Door.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. namespace Game{
  5. /******************************************************************************/
  6. Door::~Door()
  7. {
  8. }
  9. Door::Door()
  10. {
  11. scale=0;
  12. mesh_variation=0;
  13. _open =false;
  14. _state=0;
  15. _angle=PI;
  16. _actor_to_hinge_dist=0;
  17. Zero(_hinge_matrix);
  18. }
  19. /******************************************************************************/
  20. // MANAGE
  21. /******************************************************************************/
  22. void Door::setUnsavedParams()
  23. {
  24. mesh=(base ? base->mesh() : MeshPtr());
  25. if(base && base->phys())actor.create(*base->phys(), 1, scale).obj(this);
  26. }
  27. void Door::create(Object &obj)
  28. {
  29. scale =obj.scale ();
  30. base =obj.firstStored ();
  31. mesh_variation=obj.meshVariationIndex();
  32. setUnsavedParams();
  33. _hinge_matrix=obj.matrixFinal().normalize();
  34. if(C PhysBodyPtr &phys=obj.phys())
  35. {
  36. actor.matrix (_hinge_matrix)
  37. .kinematic(true);
  38. _actor_to_hinge_dist=scale*phys->box.max.x;
  39. _hinge_matrix.pos+=_hinge_matrix.x*_actor_to_hinge_dist;
  40. joint.createHinge(actor, null, _hinge_matrix.pos, _hinge_matrix.y, -PI_2, PI_2);
  41. }
  42. setObstacle();
  43. }
  44. /******************************************************************************/
  45. // GET / SET
  46. /******************************************************************************/
  47. Vec Door::pos () {return actor.pos ();}
  48. Matrix Door::matrix() {return actor.matrix();}
  49. /******************************************************************************/
  50. // CALLBACKS
  51. /******************************************************************************/
  52. void Door::memoryAddressChanged()
  53. {
  54. actor.obj(this);
  55. }
  56. /******************************************************************************/
  57. // UPDATE
  58. /******************************************************************************/
  59. Bool Door::update()
  60. {
  61. if(_state==STATE_UNKNOWN)
  62. {
  63. Flt angle =AngleNormalize(PI-AngleXZ(actor.pos(), _hinge_matrix)), // get angle of the actor position relative to the hinge position
  64. angle_delta=actor.angVel().y*Time.d(); // current frame angle delta
  65. if(_open) // if want to open
  66. {
  67. if(angle+angle_delta<=-PI_2) // if angle exceeded opening limit value
  68. {
  69. _state=STATE_OPENED;
  70. Matrix temp=_hinge_matrix; temp.orn().rotateY(-PI_2); temp.pos-=temp.x*_actor_to_hinge_dist;
  71. actor.kinematic(true).kinematicMoveTo(temp); // freeze the actors and set its final opened position
  72. setObstacle();
  73. }else
  74. if(angle+angle_delta>=PI_2) // if angle exceeded opening limit value
  75. {
  76. _state=STATE_OPENED;
  77. Matrix temp=_hinge_matrix; temp.orn().rotateY(PI_2); temp.pos-=temp.x*_actor_to_hinge_dist;
  78. actor.kinematic(true).kinematicMoveTo(temp); // freeze the actors and set its final opened position
  79. setObstacle();
  80. }else
  81. {
  82. actor.addTorque(_hinge_matrix.y*SignBool(angle>0));
  83. }
  84. }else // want to close
  85. {
  86. if(Sign(T._angle)!=Sign(angle+angle_delta)) // angle=0 means door in closed position, so check if the new angle has a different sign than the old angle, which means that 0 was crossed
  87. {
  88. _state=STATE_CLOSED;
  89. actor.kinematic(true).kinematicMoveTo(Matrix(_hinge_matrix).move(_hinge_matrix.x*-_actor_to_hinge_dist));
  90. setObstacle();
  91. }else
  92. {
  93. actor.addTorque(_hinge_matrix.y*SignBool(angle<0));
  94. }
  95. }
  96. T._angle=angle; // store new angle
  97. }
  98. return true;
  99. }
  100. /******************************************************************************/
  101. // DRAW
  102. /******************************************************************************/
  103. UInt Door::drawPrepare()
  104. {
  105. if(mesh && actor.is())
  106. {
  107. Matrix matrix=actor.matrix().scaleOrn(scale);
  108. if(Frustum(*mesh, matrix))
  109. {
  110. SetVariation(mesh_variation); mesh->draw(matrix, actor.vel(), actor.angVel());
  111. SetVariation();
  112. }
  113. }
  114. return 0; // no additional render modes required
  115. }
  116. void Door::drawShadow()
  117. {
  118. if(mesh && actor.is())
  119. {
  120. Matrix matrix=actor.matrix().scaleOrn(scale);
  121. if(Frustum(*mesh, matrix))
  122. {
  123. SetVariation(mesh_variation); mesh->drawShadow(matrix);
  124. SetVariation();
  125. }
  126. }
  127. }
  128. /******************************************************************************/
  129. // ENABLE / DISABLE
  130. /******************************************************************************/
  131. void Door::disable() {super::disable(); actor.kinematic(true );}
  132. void Door:: enable() {super:: enable(); actor.kinematic(_state!=STATE_UNKNOWN);}
  133. /******************************************************************************/
  134. // OPERATIONS
  135. /******************************************************************************/
  136. void Door::open()
  137. {
  138. if(!_open)
  139. {
  140. _open =true;
  141. _state=STATE_UNKNOWN;
  142. actor.kinematic(false);
  143. }
  144. }
  145. /******************************************************************************/
  146. void Door::close()
  147. {
  148. if(_open)
  149. {
  150. _open =false;
  151. _state=STATE_UNKNOWN;
  152. actor.kinematic(false);
  153. }
  154. }
  155. /******************************************************************************/
  156. void Door::toggle()
  157. {
  158. if(_open)close();
  159. else open ();
  160. }
  161. /******************************************************************************/
  162. void Door::setObstacle()
  163. {
  164. if(mesh && actor.is())
  165. {
  166. Matrix matrix=actor.matrix().scaleOrn(scale);
  167. obstacle.create(OBox(mesh->ext, matrix), World.path());
  168. }
  169. }
  170. /******************************************************************************/
  171. // IO
  172. /******************************************************************************/
  173. Bool Door::save(File &f)
  174. {
  175. if(super::save(f))
  176. {
  177. f.cmpUIntV(0); // version
  178. f<<scale<<_open<<_state<<_angle<<_actor_to_hinge_dist<<_hinge_matrix;
  179. f.putAsset(base.id());
  180. f.putUInt (mesh ? mesh->variationID(mesh_variation) : 0);
  181. if(!actor.saveState(f))return false;
  182. if(!joint.save (f))return false;
  183. return f.ok();
  184. }
  185. return false;
  186. }
  187. /******************************************************************************/
  188. Bool Door::load(File &f)
  189. {
  190. if(super::load(f))switch(f.decUIntV()) // version
  191. {
  192. case 0:
  193. {
  194. f>>scale>>_open>>_state>>_angle>>_actor_to_hinge_dist>>_hinge_matrix;
  195. base=f.getAssetID();
  196. setUnsavedParams();
  197. UInt mesh_variation_id=f.getUInt(); mesh_variation=(mesh ? mesh->variationFind(mesh_variation_id) : 0);
  198. if(!actor.loadState(f))return false;
  199. if(!joint.load (f, actor, null))return false;
  200. setObstacle();
  201. if(f.ok())return true;
  202. }break;
  203. }
  204. return false;
  205. }
  206. /******************************************************************************/
  207. }}
  208. /******************************************************************************/