Phys Body.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /******************************************************************************
  2. Use 'PhysBody' as a physical body description, to create 'Actors' from it.
  3. /******************************************************************************/
  4. enum PHYS_TYPE : Byte // Physical Body Type
  5. {
  6. PHYS_NONE , // none
  7. PHYS_SHAPE , // shape
  8. PHYS_CONVEX, // convex
  9. PHYS_MESH , // mesh, actor created from this type can be only static
  10. };
  11. /******************************************************************************/
  12. #if EE_PRIVATE
  13. struct PhysMesh
  14. {
  15. PHYS_TYPE _type;
  16. Int _used_by;
  17. Box _box;
  18. MeshBase *_base;
  19. Mems<Byte> _physx_cooked_data;
  20. Ptr _bullet_cooked_data; UInt _bullet_cooked_data_size;
  21. PHYS_API(PxConvexMesh , btConvexHullShape ) *_convex;
  22. PHYS_API(PxTriangleMesh, btBvhTriangleMeshShape ) *_mesh ;
  23. PHYS_API(void , btTriangleIndexVertexArray) *_tvia ;
  24. #if !PHYSX
  25. Flt volume()C;
  26. #endif
  27. void zero();
  28. void del ();
  29. void freeHelperData();
  30. Bool adjustStorage (Bool universal, Bool physx, Bool bullet, Bool *changed=null); // adjust the type of storage for the physical body, 'universal'=can be used for both PhysX and Bullet, 'physx'=can be used for PhysX (and when used there it is faster than 'universal'), 'bullet'=can be used for Bullet (and when used there it is faster than 'universal'), each storage uses additional space, for PhysX only games it is suggested to set 'physx' to true and others to false, for Bullet only games it is suggested to set 'bullet' to true and others to false, please note if you call this method under engine compiled with Bullet library, you won't be able to use any PhysX information (which means converting from or to PhysX storage), 'changed'=pointer to custom bool which will be set to true if any change was performed on the physical body (false otherwise), false on fail
  31. Bool cookConvex(MeshBase *src, Bool mesh_is_already_convex ); // cook 'src' into 'physx_cooked_data'
  32. Bool cookMesh (MeshBase *src, Bool keep_face_indexes=false); // cook 'src' into 'physx_cooked_data'
  33. void setPhysMesh();
  34. Bool setBox();
  35. Bool createConvexTry(MeshBase &mshb, Bool mesh_is_already_convex ); // create as convex body, false on fail, if 'mesh_is_already_convex' is set to true then the mesh is assumed to be already convex which will make the creation faster, this method can sometimes fail if the mesh is too complex, in that case you can create a temporary mesh using 'MeshBase.createConvex', specify vertex limit and use that mesh for phys body creation
  36. Bool createMeshTry (MeshBase &mshb, Bool keep_face_indexes=false); // create as static mesh, false on fail
  37. void draw(C Color &color)C;
  38. ~PhysMesh() {del ();}
  39. PhysMesh() {zero();}
  40. PhysMesh(C PhysMesh &src)=delete;
  41. PhysMesh& operator=(C PhysMesh &src); // create from 'src'
  42. };
  43. #endif
  44. /******************************************************************************/
  45. struct PhysPart // Physical Body Part, contains a single Shape/Convex/Mesh, can be used to create actors from it
  46. {
  47. Flt density; // mass density multiplier, 0..Inf
  48. Shape shape ; // geometric shape
  49. // manage
  50. PhysPart& del ( ); // delete
  51. PhysPart& create(C Box &box , Flt density=1) {return create(Shape(box ), density);} // create as box with 'density'
  52. PhysPart& create(C OBox &obox , Flt density=1) {return create(Shape(obox ), density);} // create as obox with 'density'
  53. PhysPart& create(C Extent &ext , Flt density=1) {return create(Shape(ext ), density);} // create as ext with 'density'
  54. PhysPart& create(C Ball &ball , Flt density=1) {return create(Shape(ball ), density);} // create as ball with 'density'
  55. PhysPart& create(C Capsule &capsule, Flt density=1) {return create(Shape(capsule), density);} // create as capsule with 'density'
  56. PhysPart& create(C Tube &tube , Flt density=1) {return create(Shape(tube ), density);} // create as tube with 'density'
  57. PhysPart& create(C Shape &shape , Flt density=1); // create as shape with 'density'
  58. Bool createConvexTry(MeshBase &mshb, Flt density=1, Bool mesh_is_already_convex=false ); // create as convex body with 'density', false on fail, if 'mesh_is_already_convex' is set to true then the mesh is assumed to be already convex which will make the creation faster, this method can sometimes fail if the mesh is too complex, in that case you can create a temporary mesh using 'MeshBase.createConvex', specify vertex limit and use that mesh for phys body creation
  59. Bool createConvexTry(MeshLod &mshl, Flt density=1, Bool mesh_is_already_convex=false, Bool skip_hidden_parts=false); // create as convex body with 'density', false on fail, if 'mesh_is_already_convex' is set to true then the mesh is assumed to be already convex which will make the creation faster, this method can sometimes fail if the mesh is too complex, in that case you can create a temporary mesh using 'MeshBase.createConvex', specify vertex limit and use that mesh for phys body creation, 'skip_hidden_parts'=if ignore MeshPart's with MSHP_HIDDEN flag
  60. PhysPart& createConvex (MeshBase &mshb, Flt density=1, Bool mesh_is_already_convex=false ); // create as convex body with 'density', Exit on fail, if 'mesh_is_already_convex' is set to true then the mesh is assumed to be already convex which will make the creation faster, this method can sometimes fail if the mesh is too complex, in that case you can create a temporary mesh using 'MeshBase.createConvex', specify vertex limit and use that mesh for phys body creation
  61. PhysPart& createConvex (MeshLod &mshl, Flt density=1, Bool mesh_is_already_convex=false, Bool skip_hidden_parts=false); // create as convex body with 'density', Exit on fail, if 'mesh_is_already_convex' is set to true then the mesh is assumed to be already convex which will make the creation faster, this method can sometimes fail if the mesh is too complex, in that case you can create a temporary mesh using 'MeshBase.createConvex', specify vertex limit and use that mesh for phys body creation, 'skip_hidden_parts'=if ignore MeshPart's with MSHP_HIDDEN flag
  62. Bool createMeshTry(MeshBase &mshb, Bool keep_face_indexes=false ); // create as static mesh, 'keep_face_indexes'=if preserve original face indexes in the 'PhysHit.face' (when enabled this will use additional memory, when disabled the face index will point to the internal face of the physical body but not the original face of the source mesh), false on fail
  63. Bool createMeshTry(MeshLod &mshl, Bool keep_face_indexes=false, Bool skip_hidden_parts=false); // create as static mesh, 'keep_face_indexes'=if preserve original face indexes in the 'PhysHit.face' (when enabled this will use additional memory, when disabled the face index will point to the internal face of the physical body but not the original face of the source mesh), false on fail, 'skip_hidden_parts'=if ignore MeshPart's with MSHP_HIDDEN flag
  64. PhysPart& createMesh (MeshBase &mshb, Bool keep_face_indexes=false ); // create as static mesh, 'keep_face_indexes'=if preserve original face indexes in the 'PhysHit.face' (when enabled this will use additional memory, when disabled the face index will point to the internal face of the physical body but not the original face of the source mesh), Exit on fail
  65. PhysPart& createMesh (MeshLod &mshl, Bool keep_face_indexes=false, Bool skip_hidden_parts=false); // create as static mesh, 'keep_face_indexes'=if preserve original face indexes in the 'PhysHit.face' (when enabled this will use additional memory, when disabled the face index will point to the internal face of the physical body but not the original face of the source mesh), Exit on fail, 'skip_hidden_parts'=if ignore MeshPart's with MSHP_HIDDEN flag
  66. // get
  67. Bool is ( )C {return _type!=PHYS_NONE;} // if part body has any data
  68. PHYS_TYPE type ( )C {return _type ;} // get part body type
  69. Flt area ( )C; // get surface area, this method works only for PHYS_SHAPE types
  70. Flt volume( )C; // get volume , this method works only for PHYS_SHAPE types
  71. Flt mass ( )C {return density*volume();} // get mass , this method works only for PHYS_SHAPE types
  72. Bool getBox(Box &box)C; // get bounding box surrounding the body, false on fail
  73. // operations
  74. Bool adjustStorage (Bool universal, Bool physx, Bool bullet, Bool *changed=null); // adjust the type of storage for the physical body, 'universal'=can be used for both PhysX and Bullet, 'physx'=can be used for PhysX (and when used there it is faster than 'universal'), 'bullet'=can be used for Bullet (and when used there it is faster than 'universal'), each storage uses additional space, for PhysX only games it is suggested to set 'physx' to true and others to false, for Bullet only games it is suggested to set 'bullet' to true and others to false, please note if you call this method under engine compiled with Bullet library, you won't be able to create PhysX data, 'changed'=pointer to custom bool which will be set to true if any change was performed on the physical body (false otherwise), false on fail
  75. PhysPart& freeHelperData( ); // this free's up the helper data of the physical body, which increases available memory, however it disables saving the body to file, or converting it to 'MeshBase'
  76. PhysPart& transform (C Matrix3 &matrix); // transform by matrix
  77. PhysPart& transform (C Matrix &matrix); // transform by matrix
  78. PhysPart& operator*=(C Matrix3 &matrix) {return transform(matrix);} // transform by matrix
  79. PhysPart& operator*=(C Matrix &matrix) {return transform(matrix);} // transform by matrix
  80. #if EE_PRIVATE
  81. PhysPart& mirrorX(); // mirror in X axis
  82. PhysPart& mirrorY(); // mirror in Y axis
  83. PhysPart& mirrorZ(); // mirror in Z axis
  84. void setPhysMesh();
  85. #endif
  86. Bool ray(C Vec &pos, C Vec &move, C Matrix *body_matrix, PhysHitBasic *phys_hit, Bool two_sided=false)C; // if ray cuts with body, 'pos'=ray start position, 'move'=ray movement vector, 'body_matrix'=optional matrix of the physical body, 'phys_hit'=optionally pass pointer to 'PhysHitBasic' class to receive additional data about the nearest contact, 'two_sided'=if mesh faces are two sided
  87. // draw
  88. void draw(C Color &color)C; // this can be optionally called outside of Render function
  89. // io
  90. void operator=(C Str &name) ; // load, Exit on fail
  91. Bool save (C Str &name)C; // save, false on fail
  92. Bool load (C Str &name) ; // load, false on fail
  93. Bool save ( File &f )C; // save, false on fail
  94. Bool load ( File &f ) ; // load, false on fail
  95. #if EE_PRIVATE
  96. Bool saveData(File &f)C; // save, false on fail
  97. Bool loadData(File &f) ; // load, false on fail
  98. #endif
  99. PhysPart& operator=(C PhysPart &src); // create from 'src'
  100. ~PhysPart() {del();}
  101. PhysPart();
  102. explicit PhysPart(C Box &box , Flt density=1); // create box
  103. explicit PhysPart(C OBox &obox , Flt density=1); // create obox
  104. explicit PhysPart(C Extent &ext , Flt density=1); // create ext
  105. explicit PhysPart(C Ball &ball , Flt density=1); // create ball
  106. explicit PhysPart(C Capsule &capsule, Flt density=1); // create capsule
  107. explicit PhysPart(C Tube &tube , Flt density=1); // create tube
  108. explicit PhysPart(C Shape &shape , Flt density=1); // create shape
  109. #if EE_PRIVATE
  110. void zero();
  111. #endif
  112. #if !EE_PRIVATE
  113. private:
  114. #endif
  115. PHYS_TYPE _type;
  116. #if EE_PRIVATE
  117. PhysMesh *_pm;
  118. #else
  119. Ptr _pm;
  120. #endif
  121. PhysPart(C PhysPart &src)=delete;
  122. };
  123. /******************************************************************************/
  124. struct PhysBody // Physical Body (array of PhysPart's), can be used to create actors from it
  125. {
  126. Flt density ; // mass density multiplier, 0..Inf, default=1
  127. Box box ; // bounding box surrounding the body
  128. PhysMtrl *material; // physical material , default=null
  129. Mems<PhysPart> parts ; // physical body parts
  130. // manage
  131. PhysBody& del(); // delete
  132. // get
  133. Bool is ()C {return parts.elms()>0;} // if has any data
  134. Flt area ()C; // get surface area of all parts, this method works only for PHYS_SHAPE types
  135. Flt volume ()C; // get volume of all parts, this method works only for PHYS_SHAPE types
  136. Flt mass ()C; // get mass of all parts, this method works only for PHYS_SHAPE types
  137. Flt finalDensity()C; // get density of PhysBody including material -> "density * material.density"
  138. // operations
  139. Bool adjustStorage (Bool universal, Bool physx, Bool bullet, Bool *changed=null); // adjust the type of storage for the physical body, 'universal'=can be used for both PhysX and Bullet, 'physx'=can be used for PhysX (and when used there it is faster than 'universal'), 'bullet'=can be used for Bullet (and when used there it is faster than 'universal'), each storage uses additional space, for PhysX only games it is suggested to set 'physx' to true and others to false, for Bullet only games it is suggested to set 'bullet' to true and others to false, please note if you call this method under engine compiled with Bullet library, you won't be able to use any PhysX information (which means converting from or to PhysX storage), 'changed'=pointer to custom bool which will be set to true if any change was performed on the physical body (false otherwise), false on fail
  140. Bool setBox ( ); // recalculate bounding box, false on fail
  141. PhysBody& freeHelperData( ); // this free's up the helper data of the physical body, which increases available memory, however it disables saving the body to file, or converting it to 'MeshBase'
  142. PhysBody& transform (C Matrix3 &matrix); // transform by matrix
  143. PhysBody& transform (C Matrix &matrix); // transform by matrix
  144. PhysBody& operator*=(C Matrix3 &matrix) {return transform(matrix);} // transform by matrix
  145. PhysBody& operator*=(C Matrix &matrix) {return transform(matrix);} // transform by matrix
  146. #if EE_PRIVATE
  147. PhysBody& mirrorX(); // mirror in X axis
  148. PhysBody& mirrorY(); // mirror in Y axis
  149. PhysBody& mirrorZ(); // mirror in Z axis
  150. #endif
  151. // draw
  152. void draw(C Color &color)C; // this can be optionally called outside of Render function
  153. // io
  154. void operator=(C Str &name) ; // load, Exit on fail
  155. Bool save (C Str &name)C; // save, false on fail
  156. Bool load (C Str &name) ; // load, false on fail
  157. Bool save (File &f, CChar *path=null)C; // save, 'path'=path at which resource is located (this is needed so that the sub-resources can be accessed with relative path), false on fail
  158. Bool load (File &f, CChar *path=null) ; // load, 'path'=path at which resource is located (this is needed so that the sub-resources can be accessed with relative path), false on fail
  159. Bool loadAdd (File &f, CChar *path=null) ; // load, 'path'=path at which resource is located (this is needed so that the sub-resources can be accessed with relative path), false on fail, this method adds the data from file to self (not replaces it)
  160. #if EE_PRIVATE
  161. Bool saveData(File &f, CChar *path=null)C; // save, 'path'=path at which resource is located (this is needed so that the sub-resources can be accessed with relative path), false on fail
  162. Bool loadData(File &f, CChar *path=null) ; // load, 'path'=path at which resource is located (this is needed so that the sub-resources can be accessed with relative path), false on fail
  163. void zero();
  164. #endif
  165. PhysBody();
  166. };
  167. /******************************************************************************/
  168. DECLARE_CACHE(PhysBody, PhysBodies, PhysBodyPtr); // 'PhysBodies' cache storing 'PhysBody' objects which can be accessed by 'PhysBodyPtr' pointer
  169. inline Int Elms(C PhysBody &phys) {return phys.parts.elms();}
  170. #if EE_PRIVATE
  171. void IncRef(PhysMesh* &ptr);
  172. void DecRef(PhysMesh* &ptr);
  173. #if !PHYSX
  174. void IncRef(btCollisionShape* shape);
  175. void DecRef(btCollisionShape* shape);
  176. #endif
  177. #endif
  178. /******************************************************************************/