Actor.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /******************************************************************************
  2. Use 'Actor' to create Physical Objects.
  3. /******************************************************************************/
  4. enum ACTOR_GROUP : Byte // Actor Group (Actor::group)
  5. {
  6. AG_DEFAULT=0, // default group for all actors
  7. // user defined groups should be in the range of 1..15
  8. AG_CONTROLLER=30, // Controller
  9. AG_TERRAIN =31, // World Terrain
  10. AG_NUM =32, // number of actor groups
  11. };
  12. /******************************************************************************/
  13. #if EE_PRIVATE
  14. #if PHYSX
  15. struct _ActorShapes
  16. {
  17. struct Shape
  18. {
  19. Flt density;
  20. EE::Shape shape ;
  21. void set(Flt density, C EE::Shape &shape) {T.density=density; T.shape=shape;}
  22. };
  23. struct Convex
  24. {
  25. Flt density;
  26. Vec scale;
  27. PxConvexMesh *convex;
  28. void set(Flt density, C Vec &scale, PxConvexMesh *convex) {T.density=density; T.scale=scale; T.convex=convex;}
  29. };
  30. struct Mesh
  31. {
  32. Flt density;
  33. Vec scale;
  34. PxTriangleMesh *mesh;
  35. void set(Flt density, C Vec &scale, PxTriangleMesh *mesh) {T.density=density; T.scale=scale; T.mesh=mesh;}
  36. };
  37. Memc<Shape > shape ;
  38. Memc<Convex > convex;
  39. Memc<Mesh > mesh ;
  40. Memc<PhysMesh*> pm ;
  41. ~_ActorShapes();
  42. };
  43. #else
  44. struct _ActorShapes
  45. {
  46. struct Shape
  47. {
  48. Flt density;
  49. EE::Shape shape ;
  50. void set(Flt density, C EE::Shape &shape) {T.density=density; T.shape=shape;}
  51. };
  52. struct Convex
  53. {
  54. Flt density, volume;
  55. Vec scale;
  56. btConvexHullShape *convex;
  57. void set(Flt density, Flt volume, C Vec &scale, btConvexHullShape *convex) {T.density=density; T.volume=volume; T.scale=scale; T.convex=convex;}
  58. };
  59. struct Mesh
  60. {
  61. Flt density;
  62. Vec scale;
  63. btBvhTriangleMeshShape *mesh;
  64. void set(Flt density, C Vec &scale, btBvhTriangleMeshShape *mesh) {T.density=density; T.scale=scale; T.mesh=mesh;}
  65. };
  66. Memc<Shape > shape ;
  67. Memc<Convex > convex;
  68. Memc<Mesh > mesh ;
  69. Memc<PhysMesh*> pm ;
  70. ~_ActorShapes();
  71. };
  72. STRUCT(RigidBody , btRigidBody)
  73. //{
  74. PhysMtrl *material ; // material index
  75. Ptr user, obj ; // user and obj pointers
  76. Vec offset_com; // offset applied only to Center of Mass
  77. Matrix offset ; // offset Bullet<->EE space
  78. Memc<btCollisionObject*> ignore ; // list of pair-coliision ignore
  79. void materialApply();
  80. ~RigidBody();
  81. RigidBody(btRigidBody::btRigidBodyConstructionInfo &info);
  82. };
  83. #endif
  84. #endif
  85. /******************************************************************************/
  86. struct ActorShapes // Actor Shapes used for creating Actors made out of multiple shapes
  87. {
  88. ActorShapes& add(C Plane &plane ); // add plane
  89. ActorShapes& add(C Box &box , Flt density=1); // add box
  90. ActorShapes& add(C OBox &obox , Flt density=1); // add obox
  91. ActorShapes& add(C Extent &ext , Flt density=1); // add extent
  92. ActorShapes& add(C Ball &ball , Flt density=1); // add ball
  93. ActorShapes& add(C Capsule &capsule, Flt density=1); // add capsule
  94. ActorShapes& add(C Tube &tube , Flt density=1); // add tube
  95. ActorShapes& add(C Shape &shape , Flt density=1); // add shape
  96. ActorShapes& add(C PhysPart &part , C Vec &scale =1); // add PhysPart
  97. ActorShapes& add(C PhysBody &phys , C Vec &scale =1); // add PhysBody
  98. ~ActorShapes();
  99. ActorShapes();
  100. private:
  101. #if EE_PRIVATE
  102. ActorShapes& add(C PhysPart &part, Flt density, C Vec &scale);
  103. _ActorShapes *_as;
  104. friend struct Actor;
  105. #else
  106. Ptr _as;
  107. #endif
  108. PhysMtrl *_mtrl;
  109. NO_COPY_CONSTRUCTOR(ActorShapes);
  110. };
  111. /******************************************************************************/
  112. struct Actor // Physical Object
  113. {
  114. // manage
  115. Actor& del(); // delete manually
  116. Actor& create (C ActorShapes &shapes , Flt density=1, Bool kinematic=false); // create from actor shapes, Exit on fail, 'density'=density multiplier, 'kinematic'=if create actor as kinematic
  117. Actor& create (C Plane &plane ); // create from plane , Exit on fail
  118. Actor& create (C Box &box , Flt density=1, C Vec *anchor=null, Bool kinematic=false); // create from box , Exit on fail, 'density'=density , 'anchor'=custom actor position, 'kinematic'=if create actor as kinematic
  119. Actor& create (C OBox &obox , Flt density=1, C Vec *anchor=null, Bool kinematic=false); // create from oriented box, Exit on fail, 'density'=density , 'anchor'=custom actor position, 'kinematic'=if create actor as kinematic
  120. Actor& create (C Extent &ext , Flt density=1, C Vec *anchor=null, Bool kinematic=false); // create from extent , Exit on fail, 'density'=density , 'anchor'=custom actor position, 'kinematic'=if create actor as kinematic
  121. Actor& create (C Ball &ball , Flt density=1, C Vec *anchor=null, Bool kinematic=false); // create from ball , Exit on fail, 'density'=density , 'anchor'=custom actor position, 'kinematic'=if create actor as kinematic
  122. Actor& create (C Capsule &capsule, Flt density=1, C Vec *anchor=null, Bool kinematic=false); // create from capsule , Exit on fail, 'density'=density , 'anchor'=custom actor position, 'kinematic'=if create actor as kinematic
  123. Actor& create (C Tube &tube , Flt density=1, C Vec *anchor=null, Bool kinematic=false); // create from tube , Exit on fail, 'density'=density , 'anchor'=custom actor position, 'kinematic'=if create actor as kinematic
  124. Actor& create (C Shape &shape , Flt density=1, C Vec *anchor=null, Bool kinematic=false); // create from shape , Exit on fail, 'density'=density , 'anchor'=custom actor position, 'kinematic'=if create actor as kinematic
  125. Actor& create (C PhysPart &part , Flt density=1, C Vec &scale =1 , Bool kinematic=false); // create from PhysPart , Exit on fail, 'density'=density multiplier, 'scale '=custom body scale , 'kinematic'=if create actor as kinematic
  126. Actor& create (C PhysBody &phys , Flt density=1, C Vec &scale =1 , Bool kinematic=false); // create from PhysBody , Exit on fail, 'density'=density multiplier, 'scale '=custom body scale , 'kinematic'=if create actor as kinematic
  127. Bool createTry(C ActorShapes &shapes , Flt density=1, Bool kinematic=false); // create from actor shapes, false on fail, 'density'=density multiplier, 'kinematic'=if create actor as kinematic
  128. Bool createTry(C Plane &plane ); // create from plane , false on fail
  129. Bool createTry(C Box &box , Flt density=1, C Vec *anchor=null, Bool kinematic=false); // create from box , false on fail, 'density'=density , 'anchor'=custom actor position, 'kinematic'=if create actor as kinematic
  130. Bool createTry(C OBox &obox , Flt density=1, C Vec *anchor=null, Bool kinematic=false); // create from oriented box, false on fail, 'density'=density , 'anchor'=custom actor position, 'kinematic'=if create actor as kinematic
  131. Bool createTry(C Extent &ext , Flt density=1, C Vec *anchor=null, Bool kinematic=false); // create from extent , false on fail, 'density'=density , 'anchor'=custom actor position, 'kinematic'=if create actor as kinematic
  132. Bool createTry(C Ball &ball , Flt density=1, C Vec *anchor=null, Bool kinematic=false); // create from ball , false on fail, 'density'=density , 'anchor'=custom actor position, 'kinematic'=if create actor as kinematic
  133. Bool createTry(C Capsule &capsule, Flt density=1, C Vec *anchor=null, Bool kinematic=false); // create from capsule , false on fail, 'density'=density , 'anchor'=custom actor position, 'kinematic'=if create actor as kinematic
  134. Bool createTry(C Tube &tube , Flt density=1, C Vec *anchor=null, Bool kinematic=false); // create from tube , false on fail, 'density'=density , 'anchor'=custom actor position, 'kinematic'=if create actor as kinematic
  135. Bool createTry(C Shape &shape , Flt density=1, C Vec *anchor=null, Bool kinematic=false); // create from shape , false on fail, 'density'=density , 'anchor'=custom actor position, 'kinematic'=if create actor as kinematic
  136. Bool createTry(C PhysPart &part , Flt density=1, C Vec &scale =1 , Bool kinematic=false); // create from PhysPart , false on fail, 'density'=density multiplier, 'scale '=custom body scale , 'kinematic'=if create actor as kinematic
  137. Bool createTry(C PhysBody &phys , Flt density=1, C Vec &scale =1 , Bool kinematic=false); // create from PhysBody , false on fail, 'density'=density multiplier, 'scale '=custom body scale , 'kinematic'=if create actor as kinematic
  138. // get / set
  139. Bool is ( )C {return _actor!=null;} // if created
  140. Flt energy ( )C; // get kinetic energy , 0..Inf
  141. Flt damping ( )C; Actor& damping ( Flt damping); // get/set linear damping , 0..Inf, default=0.05
  142. Flt adamping ( )C; Actor& adamping ( Flt damping); // get/set angular damping , 0..Inf, default=0.05
  143. Flt maxAngVel ( )C; Actor& maxAngVel ( Flt vel ); // get/set max angular velocity, 0..Inf
  144. Flt mass ( )C; Actor& mass ( Flt mass ); // get/set mass , 0..Inf
  145. Vec massCenterL( )C; Actor& massCenterL(C Vec &center ); // get/set mass center in actor local space
  146. Vec massCenterW( )C; Actor& massCenterW(C Vec &center ); // get/set mass center in world space
  147. Vec inertia ( )C; Actor& inertia (C Vec &inertia); // get/set inertia tensor
  148. Vec pos ( )C; Actor& pos (C Vec &pos ); // get/set position
  149. Matrix3 orn ( )C; Actor& orn (C Matrix3 &orn ); // get/set orientation, 'orn' must be normalized
  150. Matrix matrix ( )C; Actor& matrix (C Matrix &matrix ); // get/set matrix , 'matrix' must be normalized
  151. Vec vel ( )C; Actor& vel (C Vec &vel ); // get/set velocity
  152. Vec angVel ( )C; Actor& angVel (C Vec &vel ); // get/set angular velocity
  153. Vec pointVelL (C Vec &pos)C; // get point velocity ('pos' is in actor local space)
  154. Vec pointVelW (C Vec &pos)C; // get point velocity ('pos' is in world space)
  155. Box box ( )C; // get bounding box in world space
  156. Shape shape (Bool local)C; // get shape, 'local'=if in actor local space or world space !! only first actor's shape is used !!
  157. Actor& kinematicMoveTo(C Vec &pos ); // move kinematic actor to position , this is slightly different than 'pos' method, 'pos' method works more like "teleport to position" while 'kinematicMoveTo' works by linearly moving from source to target position , the position isn't changed immediately - change occurs during the next physics simulation call, this method can be used only on kinematic actors
  158. Actor& kinematicMoveTo(C Matrix3 &orn ); // move kinematic actor to orientation, this is slightly different than 'orn' method, 'orn' method works more like "teleport to orientation" while 'kinematicMoveTo' works by linearly moving from source to target orientation, the orientation isn't changed immediately - change occurs during the next physics simulation call, this method can be used only on kinematic actors, 'orn' must be normalized
  159. Actor& kinematicMoveTo(C Matrix &matrix); // move kinematic actor to matrix , this is slightly different than 'matrix' method, 'matrix' method works more like "teleport to matrix" while 'kinematicMoveTo' works by linearly moving from source to target matrix , the matrix isn't changed immediately - change occurs during the next physics simulation call, this method can be used only on kinematic actors, 'matrix' must be normalized
  160. Actor& addTorque (C Vec &torque ); // add torque , unit = mass * rotation / time**2
  161. Actor& addAngVel (C Vec &ang_vel ); // add angular velocity , unit = rotation / time
  162. Actor& addForce (C Vec &force ); // add force , unit = mass * distance / time**2
  163. Actor& addForce (C Vec &force , C Vec &pos); // add force at world 'pos' position, unit = mass * distance / time**2
  164. Actor& addImpulse(C Vec &impulse ); // add impulse , unit = mass * distance / time
  165. Actor& addImpulse(C Vec &impulse, C Vec &pos); // add impulse at world 'pos' position, unit = mass * distance / time
  166. Actor& addVel (C Vec &vel ); // add velocity , unit = distance / time
  167. Actor& addAccel (C Vec &accel ); // add acceleration , unit = distance / time**2
  168. Bool freezePosX ()C; Actor& freezePosX (Bool freeze ); // get/set freeze position (x component )
  169. Bool freezePosY ()C; Actor& freezePosY (Bool freeze ); // get/set freeze position (y component )
  170. Bool freezePosZ ()C; Actor& freezePosZ (Bool freeze ); // get/set freeze position (z component )
  171. Bool freezePos ()C; Actor& freezePos (Bool freeze ); // get/set freeze position (all components)
  172. Bool freezeRotX ()C; Actor& freezeRotX (Bool freeze ); // get/set freeze rotation (x axis )
  173. Bool freezeRotY ()C; Actor& freezeRotY (Bool freeze ); // get/set freeze rotation (y axis )
  174. Bool freezeRotZ ()C; Actor& freezeRotZ (Bool freeze ); // get/set freeze rotation (z axis )
  175. Bool freezeRot ()C; Actor& freezeRot (Bool freeze ); // get/set freeze rotation (all components)
  176. Bool kinematic ()C; Actor& kinematic (Bool on ); // get/set if kinematic, only dynamic actors (with mass!=0) can be changed into kinematic actors
  177. Bool gravity ()C; Actor& gravity (Bool on ); // get/set if gravity is enabled for this actor
  178. Bool ray ()C; Actor& ray (Bool on ); // get/set if this actor should be included when performing ray tests
  179. Bool collision ()C; Actor& collision (Bool on ); // get/set if this actor should collide with other actors in the world
  180. Bool trigger ()C; Actor& trigger (Bool on ); // get/set if this actor should be treated as trigger, if actor is marked as trigger then it will make physics simulation call trigger callback functions specified using 'Physics.reportTrigger' method when the actor will collide with other actors, enabling trigger also disables all collision responses (just like disabling 'collision' method)
  181. Bool sleep ()C; Actor& sleep (Bool sleep ); // get/set sleeping
  182. Flt sleepEnergy()C; Actor& sleepEnergy(Flt energy ); // get/set the amount of energy below the actor is put to sleep, default=0.005
  183. Bool ccd ()C; Actor& ccd (Bool on ); // get/set continuous collision detection
  184. Ptr user ()C; Actor& user (Ptr user ); // get/set custom user data
  185. Ptr obj ()C; Actor& obj (Ptr obj ); // get/set pointer to object containing the actor
  186. Byte group ()C; Actor& group (Byte group ); // get/set collision group (0..31, default value is taken according to ACTOR_GROUP)
  187. Byte dominance ()C; Actor& dominance (Byte dominance); // get/set dominance index (0..31, default=0), for more information about dominance please check comments on 'Physics.dominance' method
  188. PhysMtrl* material ()C; Actor& material (PhysMtrl *material ); // get/set physics material (use 'null' for default material)
  189. Actor& ignore ( Actor &actor, Bool ignore=true) ; // ignore collisions with 'actor' actor
  190. Bool ignored(C Actor &actor )C; // if this actor should ignore collisions with 'actor' actor, this does not test for ACTOR_GROUP collisions (specified using 'Physics.ignore') but only 'Actor::ignore' method
  191. Bool ignored(C ActorInfo &actor )C; // if this actor should ignore collisions with 'actor' actor, this does not test for ACTOR_GROUP collisions (specified using 'Physics.ignore') but only 'Actor::ignore' method
  192. Actor& active(Bool on) {collision(on).ray(on).kinematic(!on).sleep(!on); return T;} // set if active, adjusts "collision, ray, kinematic, sleep" to either include or exclude actor in physics simulation
  193. // test
  194. Bool cuts ( UInt groups=~0)C; // if cuts some other actor on the scene , 'groups'=group flag (ACTOR_GROUP) bit combination specifying which groups should be included in testing - use 'IndexToFlag' function
  195. void cuts ( PhysCutsCallback &callback , UInt groups=~0)C; // if cuts some other actor on the scene , 'callback' will be used for every contact check , 'groups'=group flag (ACTOR_GROUP) bit combination specifying which groups should be included in testing - use 'IndexToFlag' function
  196. Bool sweep(C Vec &move, PhysHit *phys_hit=null, UInt groups=~0)C; // if hits some other actor on 'move' way, 'phys_hit'=optionally pass pointer to PhysHit object to receive additional data, 'groups'=group flag (ACTOR_GROUP) bit combination specifying which groups should be included in testing - use 'IndexToFlag' function
  197. void sweep(C Vec &move, PhysHitCallback &callback , UInt groups=~0)C; // if hits some other actor on 'move' way, 'callback' will be used for every contact check , 'groups'=group flag (ACTOR_GROUP) bit combination specifying which groups should be included in testing - use 'IndexToFlag' function
  198. // draw
  199. void draw(C Color &color=WHITE, Bool fill=false)C; // this can be optionally called outside of Render function
  200. // io
  201. Bool saveState(File &f)C; // save actor state ('user' is saved only as 'UInt' and not 'UIntPtr', following data is not saved: physical body, mass, density, scale, damping, max ang vel, mass center, inertia, material, object, sleepEnergy), false on fail
  202. Bool loadState(File &f) ; // load actor state ('user' is loaded only as 'UInt' and not 'UIntPtr', following data is not loaded: physical body, mass, density, scale, damping, max ang vel, mass center, inertia, material, object, sleepEnergy), false on fail, typically you should first create an actor from a physical body and then call this method to set its state according to data from the file
  203. ~Actor() {del();}
  204. Actor() {_actor=null; _dynamic=null; _ignore_id=0;}
  205. #if EE_PRIVATE
  206. Bool materialForce(PhysMtrl *material);
  207. #if PHYSX
  208. Bool isDynamic()C {return _dynamic!=null;}
  209. Bool isStatic ()C {return _actor && !_dynamic ;}
  210. #else
  211. Bool init(btRigidBody::btRigidBodyConstructionInfo &info, C Vec *anchor, Bool kinematic, PhysMesh *pm, PhysMtrl *material);
  212. Bool createTry(btConvexHullShape *convex, C Vec &scale, Flt density, Bool kinematic, PhysMesh *pm, PhysMtrl *material);
  213. Bool createTry(btBvhTriangleMeshShape *mesh , C Vec &scale , PhysMesh *pm, PhysMtrl *material);
  214. Matrix massCenterMatrix()C;
  215. #endif
  216. #endif
  217. #if !EE_PRIVATE
  218. private:
  219. #endif
  220. #if EE_PRIVATE
  221. PHYS_API(PxRigidActor , RigidBody) *_actor;
  222. PHYS_API(PxRigidDynamic, void ) *_dynamic;
  223. Mems<PhysMesh*> _pm;
  224. #else
  225. Ptr _actor, _dynamic;
  226. Mems<Ptr> _pm;
  227. #endif
  228. UInt _ignore_id;
  229. NO_COPY_CONSTRUCTOR(Actor);
  230. };
  231. /******************************************************************************/
  232. #if EE_PRIVATE
  233. enum ACTOR_FLAG
  234. {
  235. ACTOR_FREEZE_POS_X=1<< 0,
  236. ACTOR_FREEZE_POS_Y=1<< 1,
  237. ACTOR_FREEZE_POS_Z=1<< 2,
  238. ACTOR_FREEZE_ROT_X=1<< 3,
  239. ACTOR_FREEZE_ROT_Y=1<< 4,
  240. ACTOR_FREEZE_ROT_Z=1<< 5,
  241. ACTOR_KINEMATIC =1<< 6,
  242. ACTOR_GRAVITY =1<< 7,
  243. ACTOR_RAY =1<< 8,
  244. ACTOR_COLLISION =1<< 9,
  245. ACTOR_TRIGGER =1<<10,
  246. ACTOR_SLEEP =1<<11,
  247. ACTOR_CCD =1<<12,
  248. };
  249. #endif
  250. /******************************************************************************/