btGImpactShape.h 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165
  1. /*! \file btGImpactShape.h
  2. \author Francisco Len Nßjera
  3. */
  4. /*
  5. This source file is part of GIMPACT Library.
  6. For the latest info, see http://gimpact.sourceforge.net/
  7. Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
  8. email: projectileman@yahoo.com
  9. This software is provided 'as-is', without any express or implied warranty.
  10. In no event will the authors be held liable for any damages arising from the use of this software.
  11. Permission is granted to anyone to use this software for any purpose,
  12. including commercial applications, and to alter it and redistribute it freely,
  13. subject to the following restrictions:
  14. 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
  15. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
  16. 3. This notice may not be removed or altered from any source distribution.
  17. */
  18. #ifndef GIMPACT_SHAPE_H
  19. #define GIMPACT_SHAPE_H
  20. #include "BulletCollision/CollisionShapes/btCollisionShape.h"
  21. #include "BulletCollision/CollisionShapes/btTriangleShape.h"
  22. #include "BulletCollision/CollisionShapes/btStridingMeshInterface.h"
  23. #include "BulletCollision/CollisionShapes/btCollisionMargin.h"
  24. #include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
  25. #include "BulletCollision/CollisionShapes/btConcaveShape.h"
  26. #include "BulletCollision/CollisionShapes/btTetrahedronShape.h"
  27. #include "LinearMath/btVector3.h"
  28. #include "LinearMath/btTransform.h"
  29. #include "LinearMath/btMatrix3x3.h"
  30. #include "LinearMath/btAlignedObjectArray.h"
  31. #include "btGImpactQuantizedBvh.h" // box tree class
  32. //! declare Quantized trees, (you can change to float based trees)
  33. typedef btGImpactQuantizedBvh btGImpactBoxSet;
  34. enum eGIMPACT_SHAPE_TYPE
  35. {
  36. CONST_GIMPACT_COMPOUND_SHAPE = 0,
  37. CONST_GIMPACT_TRIMESH_SHAPE_PART,
  38. CONST_GIMPACT_TRIMESH_SHAPE
  39. };
  40. //! Helper class for tetrahedrons
  41. class btTetrahedronShapeEx:public btBU_Simplex1to4
  42. {
  43. public:
  44. btTetrahedronShapeEx()
  45. {
  46. m_numVertices = 4;
  47. }
  48. SIMD_FORCE_INLINE void setVertices(
  49. const btVector3 & v0,const btVector3 & v1,
  50. const btVector3 & v2,const btVector3 & v3)
  51. {
  52. m_vertices[0] = v0;
  53. m_vertices[1] = v1;
  54. m_vertices[2] = v2;
  55. m_vertices[3] = v3;
  56. recalcLocalAabb();
  57. }
  58. };
  59. //! Base class for gimpact shapes
  60. class btGImpactShapeInterface : public btConcaveShape
  61. {
  62. protected:
  63. btAABB m_localAABB;
  64. bool m_needs_update;
  65. btVector3 localScaling;
  66. btGImpactBoxSet m_box_set;// optionally boxset
  67. //! use this function for perfofm refit in bounding boxes
  68. //! use this function for perfofm refit in bounding boxes
  69. virtual void calcLocalAABB()
  70. {
  71. lockChildShapes();
  72. if(m_box_set.getNodeCount() == 0)
  73. {
  74. m_box_set.buildSet();
  75. }
  76. else
  77. {
  78. m_box_set.update();
  79. }
  80. unlockChildShapes();
  81. m_localAABB = m_box_set.getGlobalBox();
  82. }
  83. public:
  84. btGImpactShapeInterface()
  85. {
  86. m_shapeType=GIMPACT_SHAPE_PROXYTYPE;
  87. m_localAABB.invalidate();
  88. m_needs_update = true;
  89. localScaling.setValue(1.f,1.f,1.f);
  90. }
  91. //! performs refit operation
  92. /*!
  93. Updates the entire Box set of this shape.
  94. \pre postUpdate() must be called for attemps to calculating the box set, else this function
  95. will does nothing.
  96. \post if m_needs_update == true, then it calls calcLocalAABB();
  97. */
  98. SIMD_FORCE_INLINE void updateBound()
  99. {
  100. if(!m_needs_update) return;
  101. calcLocalAABB();
  102. m_needs_update = false;
  103. }
  104. //! If the Bounding box is not updated, then this class attemps to calculate it.
  105. /*!
  106. \post Calls updateBound() for update the box set.
  107. */
  108. void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
  109. {
  110. btAABB transformedbox = m_localAABB;
  111. transformedbox.appy_transform(t);
  112. aabbMin = transformedbox.m_min;
  113. aabbMax = transformedbox.m_max;
  114. }
  115. //! Tells to this object that is needed to refit the box set
  116. virtual void postUpdate()
  117. {
  118. m_needs_update = true;
  119. }
  120. //! Obtains the local box, which is the global calculated box of the total of subshapes
  121. SIMD_FORCE_INLINE const btAABB & getLocalBox()
  122. {
  123. return m_localAABB;
  124. }
  125. virtual int getShapeType() const
  126. {
  127. return GIMPACT_SHAPE_PROXYTYPE;
  128. }
  129. /*!
  130. \post You must call updateBound() for update the box set.
  131. */
  132. virtual void setLocalScaling(const btVector3& scaling)
  133. {
  134. localScaling = scaling;
  135. postUpdate();
  136. }
  137. virtual const btVector3& getLocalScaling() const
  138. {
  139. return localScaling;
  140. }
  141. virtual void setMargin(btScalar margin)
  142. {
  143. m_collisionMargin = margin;
  144. int i = getNumChildShapes();
  145. while(i--)
  146. {
  147. btCollisionShape* child = getChildShape(i);
  148. child->setMargin(margin);
  149. }
  150. m_needs_update = true;
  151. }
  152. //! Subshape member functions
  153. //!@{
  154. //! Base method for determinig which kind of GIMPACT shape we get
  155. virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const = 0 ;
  156. //! gets boxset
  157. SIMD_FORCE_INLINE const btGImpactBoxSet * getBoxSet() const
  158. {
  159. return &m_box_set;
  160. }
  161. //! Determines if this class has a hierarchy structure for sorting its primitives
  162. SIMD_FORCE_INLINE bool hasBoxSet() const
  163. {
  164. if(m_box_set.getNodeCount() == 0) return false;
  165. return true;
  166. }
  167. //! Obtains the primitive manager
  168. virtual const btPrimitiveManagerBase * getPrimitiveManager() const = 0;
  169. //! Gets the number of children
  170. virtual int getNumChildShapes() const = 0;
  171. //! if true, then its children must get transforms.
  172. virtual bool childrenHasTransform() const = 0;
  173. //! Determines if this shape has triangles
  174. virtual bool needsRetrieveTriangles() const = 0;
  175. //! Determines if this shape has tetrahedrons
  176. virtual bool needsRetrieveTetrahedrons() const = 0;
  177. virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const = 0;
  178. virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const = 0;
  179. //! call when reading child shapes
  180. virtual void lockChildShapes() const
  181. {
  182. }
  183. virtual void unlockChildShapes() const
  184. {
  185. }
  186. //! if this trimesh
  187. SIMD_FORCE_INLINE void getPrimitiveTriangle(int index,btPrimitiveTriangle & triangle) const
  188. {
  189. getPrimitiveManager()->get_primitive_triangle(index,triangle);
  190. }
  191. //! Retrieves the bound from a child
  192. /*!
  193. */
  194. virtual void getChildAabb(int child_index,const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
  195. {
  196. btAABB child_aabb;
  197. getPrimitiveManager()->get_primitive_box(child_index,child_aabb);
  198. child_aabb.appy_transform(t);
  199. aabbMin = child_aabb.m_min;
  200. aabbMax = child_aabb.m_max;
  201. }
  202. //! Gets the children
  203. virtual btCollisionShape* getChildShape(int index) = 0;
  204. //! Gets the child
  205. virtual const btCollisionShape* getChildShape(int index) const = 0;
  206. //! Gets the children transform
  207. virtual btTransform getChildTransform(int index) const = 0;
  208. //! Sets the children transform
  209. /*!
  210. \post You must call updateBound() for update the box set.
  211. */
  212. virtual void setChildTransform(int index, const btTransform & transform) = 0;
  213. //!@}
  214. //! virtual method for ray collision
  215. virtual void rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback) const
  216. {
  217. (void) rayFrom; (void) rayTo; (void) resultCallback;
  218. }
  219. //! Function for retrieve triangles.
  220. /*!
  221. It gives the triangles in local space
  222. */
  223. virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
  224. {
  225. (void) callback; (void) aabbMin; (void) aabbMax;
  226. }
  227. //! Function for retrieve triangles.
  228. /*!
  229. It gives the triangles in local space
  230. */
  231. virtual void processAllTrianglesRay(btTriangleCallback* /*callback*/,const btVector3& /*rayFrom*/, const btVector3& /*rayTo*/) const
  232. {
  233. }
  234. //!@}
  235. };
  236. //! btGImpactCompoundShape allows to handle multiple btCollisionShape objects at once
  237. /*!
  238. This class only can manage Convex subshapes
  239. */
  240. class btGImpactCompoundShape : public btGImpactShapeInterface
  241. {
  242. public:
  243. //! compound primitive manager
  244. class CompoundPrimitiveManager:public btPrimitiveManagerBase
  245. {
  246. public:
  247. virtual ~CompoundPrimitiveManager() {}
  248. btGImpactCompoundShape * m_compoundShape;
  249. CompoundPrimitiveManager(const CompoundPrimitiveManager& compound)
  250. : btPrimitiveManagerBase()
  251. {
  252. m_compoundShape = compound.m_compoundShape;
  253. }
  254. CompoundPrimitiveManager(btGImpactCompoundShape * compoundShape)
  255. {
  256. m_compoundShape = compoundShape;
  257. }
  258. CompoundPrimitiveManager()
  259. {
  260. m_compoundShape = NULL;
  261. }
  262. virtual bool is_trimesh() const
  263. {
  264. return false;
  265. }
  266. virtual int get_primitive_count() const
  267. {
  268. return (int )m_compoundShape->getNumChildShapes();
  269. }
  270. virtual void get_primitive_box(int prim_index ,btAABB & primbox) const
  271. {
  272. btTransform prim_trans;
  273. if(m_compoundShape->childrenHasTransform())
  274. {
  275. prim_trans = m_compoundShape->getChildTransform(prim_index);
  276. }
  277. else
  278. {
  279. prim_trans.setIdentity();
  280. }
  281. const btCollisionShape* shape = m_compoundShape->getChildShape(prim_index);
  282. shape->getAabb(prim_trans,primbox.m_min,primbox.m_max);
  283. }
  284. virtual void get_primitive_triangle(int prim_index,btPrimitiveTriangle & triangle) const
  285. {
  286. btAssert(0);
  287. (void) prim_index; (void) triangle;
  288. }
  289. };
  290. protected:
  291. CompoundPrimitiveManager m_primitive_manager;
  292. btAlignedObjectArray<btTransform> m_childTransforms;
  293. btAlignedObjectArray<btCollisionShape*> m_childShapes;
  294. public:
  295. btGImpactCompoundShape(bool children_has_transform = true)
  296. {
  297. (void) children_has_transform;
  298. m_primitive_manager.m_compoundShape = this;
  299. m_box_set.setPrimitiveManager(&m_primitive_manager);
  300. }
  301. virtual ~btGImpactCompoundShape()
  302. {
  303. }
  304. //! if true, then its children must get transforms.
  305. virtual bool childrenHasTransform() const
  306. {
  307. if(m_childTransforms.size()==0) return false;
  308. return true;
  309. }
  310. //! Obtains the primitive manager
  311. virtual const btPrimitiveManagerBase * getPrimitiveManager() const
  312. {
  313. return &m_primitive_manager;
  314. }
  315. //! Obtains the compopund primitive manager
  316. SIMD_FORCE_INLINE CompoundPrimitiveManager * getCompoundPrimitiveManager()
  317. {
  318. return &m_primitive_manager;
  319. }
  320. //! Gets the number of children
  321. virtual int getNumChildShapes() const
  322. {
  323. return m_childShapes.size();
  324. }
  325. //! Use this method for adding children. Only Convex shapes are allowed.
  326. void addChildShape(const btTransform& localTransform,btCollisionShape* shape)
  327. {
  328. btAssert(shape->isConvex());
  329. m_childTransforms.push_back(localTransform);
  330. m_childShapes.push_back(shape);
  331. }
  332. //! Use this method for adding children. Only Convex shapes are allowed.
  333. void addChildShape(btCollisionShape* shape)
  334. {
  335. btAssert(shape->isConvex());
  336. m_childShapes.push_back(shape);
  337. }
  338. //! Gets the children
  339. virtual btCollisionShape* getChildShape(int index)
  340. {
  341. return m_childShapes[index];
  342. }
  343. //! Gets the children
  344. virtual const btCollisionShape* getChildShape(int index) const
  345. {
  346. return m_childShapes[index];
  347. }
  348. //! Retrieves the bound from a child
  349. /*!
  350. */
  351. virtual void getChildAabb(int child_index,const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
  352. {
  353. if(childrenHasTransform())
  354. {
  355. m_childShapes[child_index]->getAabb(t*m_childTransforms[child_index],aabbMin,aabbMax);
  356. }
  357. else
  358. {
  359. m_childShapes[child_index]->getAabb(t,aabbMin,aabbMax);
  360. }
  361. }
  362. //! Gets the children transform
  363. virtual btTransform getChildTransform(int index) const
  364. {
  365. btAssert(m_childTransforms.size() == m_childShapes.size());
  366. return m_childTransforms[index];
  367. }
  368. //! Sets the children transform
  369. /*!
  370. \post You must call updateBound() for update the box set.
  371. */
  372. virtual void setChildTransform(int index, const btTransform & transform)
  373. {
  374. btAssert(m_childTransforms.size() == m_childShapes.size());
  375. m_childTransforms[index] = transform;
  376. postUpdate();
  377. }
  378. //! Determines if this shape has triangles
  379. virtual bool needsRetrieveTriangles() const
  380. {
  381. return false;
  382. }
  383. //! Determines if this shape has tetrahedrons
  384. virtual bool needsRetrieveTetrahedrons() const
  385. {
  386. return false;
  387. }
  388. virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const
  389. {
  390. (void) prim_index; (void) triangle;
  391. btAssert(0);
  392. }
  393. virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const
  394. {
  395. (void) prim_index; (void) tetrahedron;
  396. btAssert(0);
  397. }
  398. //! Calculates the exact inertia tensor for this shape
  399. virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const;
  400. virtual const char* getName()const
  401. {
  402. return "GImpactCompound";
  403. }
  404. virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const
  405. {
  406. return CONST_GIMPACT_COMPOUND_SHAPE;
  407. }
  408. };
  409. //! This class manages a sub part of a mesh supplied by the btStridingMeshInterface interface.
  410. /*!
  411. - Simply create this shape by passing the btStridingMeshInterface to the constructor btGImpactMeshShapePart, then you must call updateBound() after creating the mesh
  412. - When making operations with this shape, you must call <b>lock</b> before accessing to the trimesh primitives, and then call <b>unlock</b>
  413. - You can handle deformable meshes with this shape, by calling postUpdate() every time when changing the mesh vertices.
  414. */
  415. class btGImpactMeshShapePart : public btGImpactShapeInterface
  416. {
  417. public:
  418. //! Trimesh primitive manager
  419. /*!
  420. Manages the info from btStridingMeshInterface object and controls the Lock/Unlock mechanism
  421. */
  422. class TrimeshPrimitiveManager:public btPrimitiveManagerBase
  423. {
  424. public:
  425. btScalar m_margin;
  426. btStridingMeshInterface * m_meshInterface;
  427. btVector3 m_scale;
  428. int m_part;
  429. int m_lock_count;
  430. const unsigned char *vertexbase;
  431. int numverts;
  432. PHY_ScalarType type;
  433. int stride;
  434. const unsigned char *indexbase;
  435. int indexstride;
  436. int numfaces;
  437. PHY_ScalarType indicestype;
  438. TrimeshPrimitiveManager()
  439. {
  440. m_meshInterface = NULL;
  441. m_part = 0;
  442. m_margin = 0.01f;
  443. m_scale = btVector3(1.f,1.f,1.f);
  444. m_lock_count = 0;
  445. vertexbase = 0;
  446. numverts = 0;
  447. stride = 0;
  448. indexbase = 0;
  449. indexstride = 0;
  450. numfaces = 0;
  451. }
  452. TrimeshPrimitiveManager(const TrimeshPrimitiveManager & manager)
  453. : btPrimitiveManagerBase()
  454. {
  455. m_meshInterface = manager.m_meshInterface;
  456. m_part = manager.m_part;
  457. m_margin = manager.m_margin;
  458. m_scale = manager.m_scale;
  459. m_lock_count = 0;
  460. vertexbase = 0;
  461. numverts = 0;
  462. stride = 0;
  463. indexbase = 0;
  464. indexstride = 0;
  465. numfaces = 0;
  466. }
  467. TrimeshPrimitiveManager(
  468. btStridingMeshInterface * meshInterface, int part)
  469. {
  470. m_meshInterface = meshInterface;
  471. m_part = part;
  472. m_scale = m_meshInterface->getScaling();
  473. m_margin = 0.1f;
  474. m_lock_count = 0;
  475. vertexbase = 0;
  476. numverts = 0;
  477. stride = 0;
  478. indexbase = 0;
  479. indexstride = 0;
  480. numfaces = 0;
  481. }
  482. virtual ~TrimeshPrimitiveManager() {}
  483. void lock()
  484. {
  485. if(m_lock_count>0)
  486. {
  487. m_lock_count++;
  488. return;
  489. }
  490. m_meshInterface->getLockedReadOnlyVertexIndexBase(
  491. &vertexbase,numverts,
  492. type, stride,&indexbase, indexstride, numfaces,indicestype,m_part);
  493. m_lock_count = 1;
  494. }
  495. void unlock()
  496. {
  497. if(m_lock_count == 0) return;
  498. if(m_lock_count>1)
  499. {
  500. --m_lock_count;
  501. return;
  502. }
  503. m_meshInterface->unLockReadOnlyVertexBase(m_part);
  504. vertexbase = NULL;
  505. m_lock_count = 0;
  506. }
  507. virtual bool is_trimesh() const
  508. {
  509. return true;
  510. }
  511. virtual int get_primitive_count() const
  512. {
  513. return (int )numfaces;
  514. }
  515. SIMD_FORCE_INLINE int get_vertex_count() const
  516. {
  517. return (int )numverts;
  518. }
  519. SIMD_FORCE_INLINE void get_indices(int face_index,unsigned int &i0,unsigned int &i1,unsigned int &i2) const
  520. {
  521. if(indicestype == PHY_SHORT)
  522. {
  523. unsigned short* s_indices = (unsigned short *)(indexbase + face_index * indexstride);
  524. i0 = s_indices[0];
  525. i1 = s_indices[1];
  526. i2 = s_indices[2];
  527. }
  528. else
  529. {
  530. unsigned int * i_indices = (unsigned int *)(indexbase + face_index*indexstride);
  531. i0 = i_indices[0];
  532. i1 = i_indices[1];
  533. i2 = i_indices[2];
  534. }
  535. }
  536. SIMD_FORCE_INLINE void get_vertex(unsigned int vertex_index, btVector3 & vertex) const
  537. {
  538. if(type == PHY_DOUBLE)
  539. {
  540. double * dvertices = (double *)(vertexbase + vertex_index*stride);
  541. vertex[0] = btScalar(dvertices[0]*m_scale[0]);
  542. vertex[1] = btScalar(dvertices[1]*m_scale[1]);
  543. vertex[2] = btScalar(dvertices[2]*m_scale[2]);
  544. }
  545. else
  546. {
  547. float * svertices = (float *)(vertexbase + vertex_index*stride);
  548. vertex[0] = svertices[0]*m_scale[0];
  549. vertex[1] = svertices[1]*m_scale[1];
  550. vertex[2] = svertices[2]*m_scale[2];
  551. }
  552. }
  553. virtual void get_primitive_box(int prim_index ,btAABB & primbox) const
  554. {
  555. btPrimitiveTriangle triangle;
  556. get_primitive_triangle(prim_index,triangle);
  557. primbox.calc_from_triangle_margin(
  558. triangle.m_vertices[0],
  559. triangle.m_vertices[1],triangle.m_vertices[2],triangle.m_margin);
  560. }
  561. virtual void get_primitive_triangle(int prim_index,btPrimitiveTriangle & triangle) const
  562. {
  563. unsigned int indices[3];
  564. get_indices(prim_index,indices[0],indices[1],indices[2]);
  565. get_vertex(indices[0],triangle.m_vertices[0]);
  566. get_vertex(indices[1],triangle.m_vertices[1]);
  567. get_vertex(indices[2],triangle.m_vertices[2]);
  568. triangle.m_margin = m_margin;
  569. }
  570. SIMD_FORCE_INLINE void get_bullet_triangle(int prim_index,btTriangleShapeEx & triangle) const
  571. {
  572. unsigned int indices[3];
  573. get_indices(prim_index,indices[0],indices[1],indices[2]);
  574. get_vertex(indices[0],triangle.m_vertices1[0]);
  575. get_vertex(indices[1],triangle.m_vertices1[1]);
  576. get_vertex(indices[2],triangle.m_vertices1[2]);
  577. triangle.setMargin(m_margin);
  578. }
  579. };
  580. protected:
  581. TrimeshPrimitiveManager m_primitive_manager;
  582. public:
  583. btGImpactMeshShapePart()
  584. {
  585. m_box_set.setPrimitiveManager(&m_primitive_manager);
  586. }
  587. btGImpactMeshShapePart( btStridingMeshInterface * meshInterface, int part );
  588. virtual ~btGImpactMeshShapePart();
  589. //! if true, then its children must get transforms.
  590. virtual bool childrenHasTransform() const
  591. {
  592. return false;
  593. }
  594. //! call when reading child shapes
  595. virtual void lockChildShapes() const;
  596. virtual void unlockChildShapes() const;
  597. //! Gets the number of children
  598. virtual int getNumChildShapes() const
  599. {
  600. return m_primitive_manager.get_primitive_count();
  601. }
  602. //! Gets the children
  603. virtual btCollisionShape* getChildShape(int index)
  604. {
  605. (void) index;
  606. btAssert(0);
  607. return NULL;
  608. }
  609. //! Gets the child
  610. virtual const btCollisionShape* getChildShape(int index) const
  611. {
  612. (void) index;
  613. btAssert(0);
  614. return NULL;
  615. }
  616. //! Gets the children transform
  617. virtual btTransform getChildTransform(int index) const
  618. {
  619. (void) index;
  620. btAssert(0);
  621. return btTransform();
  622. }
  623. //! Sets the children transform
  624. /*!
  625. \post You must call updateBound() for update the box set.
  626. */
  627. virtual void setChildTransform(int index, const btTransform & transform)
  628. {
  629. (void) index;
  630. (void) transform;
  631. btAssert(0);
  632. }
  633. //! Obtains the primitive manager
  634. virtual const btPrimitiveManagerBase * getPrimitiveManager() const
  635. {
  636. return &m_primitive_manager;
  637. }
  638. SIMD_FORCE_INLINE TrimeshPrimitiveManager * getTrimeshPrimitiveManager()
  639. {
  640. return &m_primitive_manager;
  641. }
  642. virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const;
  643. virtual const char* getName()const
  644. {
  645. return "GImpactMeshShapePart";
  646. }
  647. virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const
  648. {
  649. return CONST_GIMPACT_TRIMESH_SHAPE_PART;
  650. }
  651. //! Determines if this shape has triangles
  652. virtual bool needsRetrieveTriangles() const
  653. {
  654. return true;
  655. }
  656. //! Determines if this shape has tetrahedrons
  657. virtual bool needsRetrieveTetrahedrons() const
  658. {
  659. return false;
  660. }
  661. virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const
  662. {
  663. m_primitive_manager.get_bullet_triangle(prim_index,triangle);
  664. }
  665. virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const
  666. {
  667. (void) prim_index;
  668. (void) tetrahedron;
  669. btAssert(0);
  670. }
  671. SIMD_FORCE_INLINE int getVertexCount() const
  672. {
  673. return m_primitive_manager.get_vertex_count();
  674. }
  675. SIMD_FORCE_INLINE void getVertex(int vertex_index, btVector3 & vertex) const
  676. {
  677. m_primitive_manager.get_vertex(vertex_index,vertex);
  678. }
  679. SIMD_FORCE_INLINE void setMargin(btScalar margin)
  680. {
  681. m_primitive_manager.m_margin = margin;
  682. postUpdate();
  683. }
  684. SIMD_FORCE_INLINE btScalar getMargin() const
  685. {
  686. return m_primitive_manager.m_margin;
  687. }
  688. virtual void setLocalScaling(const btVector3& scaling)
  689. {
  690. m_primitive_manager.m_scale = scaling;
  691. postUpdate();
  692. }
  693. virtual const btVector3& getLocalScaling() const
  694. {
  695. return m_primitive_manager.m_scale;
  696. }
  697. SIMD_FORCE_INLINE int getPart() const
  698. {
  699. return (int)m_primitive_manager.m_part;
  700. }
  701. virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
  702. virtual void processAllTrianglesRay(btTriangleCallback* callback,const btVector3& rayFrom,const btVector3& rayTo) const;
  703. };
  704. //! This class manages a mesh supplied by the btStridingMeshInterface interface.
  705. /*!
  706. Set of btGImpactMeshShapePart parts
  707. - Simply create this shape by passing the btStridingMeshInterface to the constructor btGImpactMeshShape, then you must call updateBound() after creating the mesh
  708. - You can handle deformable meshes with this shape, by calling postUpdate() every time when changing the mesh vertices.
  709. */
  710. class btGImpactMeshShape : public btGImpactShapeInterface
  711. {
  712. btStridingMeshInterface* m_meshInterface;
  713. protected:
  714. btAlignedObjectArray<btGImpactMeshShapePart*> m_mesh_parts;
  715. void buildMeshParts(btStridingMeshInterface * meshInterface)
  716. {
  717. for (int i=0;i<meshInterface->getNumSubParts() ;++i )
  718. {
  719. btGImpactMeshShapePart * newpart = new btGImpactMeshShapePart(meshInterface,i);
  720. m_mesh_parts.push_back(newpart);
  721. }
  722. }
  723. //! use this function for perfofm refit in bounding boxes
  724. virtual void calcLocalAABB()
  725. {
  726. m_localAABB.invalidate();
  727. int i = m_mesh_parts.size();
  728. while(i--)
  729. {
  730. m_mesh_parts[i]->updateBound();
  731. m_localAABB.merge(m_mesh_parts[i]->getLocalBox());
  732. }
  733. }
  734. public:
  735. btGImpactMeshShape(btStridingMeshInterface * meshInterface)
  736. {
  737. m_meshInterface = meshInterface;
  738. buildMeshParts(meshInterface);
  739. }
  740. virtual ~btGImpactMeshShape()
  741. {
  742. int i = m_mesh_parts.size();
  743. while(i--)
  744. {
  745. btGImpactMeshShapePart * part = m_mesh_parts[i];
  746. delete part;
  747. }
  748. m_mesh_parts.clear();
  749. }
  750. btStridingMeshInterface* getMeshInterface()
  751. {
  752. return m_meshInterface;
  753. }
  754. const btStridingMeshInterface* getMeshInterface() const
  755. {
  756. return m_meshInterface;
  757. }
  758. int getMeshPartCount() const
  759. {
  760. return m_mesh_parts.size();
  761. }
  762. btGImpactMeshShapePart * getMeshPart(int index)
  763. {
  764. return m_mesh_parts[index];
  765. }
  766. const btGImpactMeshShapePart * getMeshPart(int index) const
  767. {
  768. return m_mesh_parts[index];
  769. }
  770. virtual void setLocalScaling(const btVector3& scaling)
  771. {
  772. localScaling = scaling;
  773. int i = m_mesh_parts.size();
  774. while(i--)
  775. {
  776. btGImpactMeshShapePart * part = m_mesh_parts[i];
  777. part->setLocalScaling(scaling);
  778. }
  779. m_needs_update = true;
  780. }
  781. virtual void setMargin(btScalar margin)
  782. {
  783. m_collisionMargin = margin;
  784. int i = m_mesh_parts.size();
  785. while(i--)
  786. {
  787. btGImpactMeshShapePart * part = m_mesh_parts[i];
  788. part->setMargin(margin);
  789. }
  790. m_needs_update = true;
  791. }
  792. //! Tells to this object that is needed to refit all the meshes
  793. virtual void postUpdate()
  794. {
  795. int i = m_mesh_parts.size();
  796. while(i--)
  797. {
  798. btGImpactMeshShapePart * part = m_mesh_parts[i];
  799. part->postUpdate();
  800. }
  801. m_needs_update = true;
  802. }
  803. virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const;
  804. //! Obtains the primitive manager
  805. virtual const btPrimitiveManagerBase * getPrimitiveManager() const
  806. {
  807. btAssert(0);
  808. return NULL;
  809. }
  810. //! Gets the number of children
  811. virtual int getNumChildShapes() const
  812. {
  813. btAssert(0);
  814. return 0;
  815. }
  816. //! if true, then its children must get transforms.
  817. virtual bool childrenHasTransform() const
  818. {
  819. btAssert(0);
  820. return false;
  821. }
  822. //! Determines if this shape has triangles
  823. virtual bool needsRetrieveTriangles() const
  824. {
  825. btAssert(0);
  826. return false;
  827. }
  828. //! Determines if this shape has tetrahedrons
  829. virtual bool needsRetrieveTetrahedrons() const
  830. {
  831. btAssert(0);
  832. return false;
  833. }
  834. virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const
  835. {
  836. (void) prim_index; (void) triangle;
  837. btAssert(0);
  838. }
  839. virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const
  840. {
  841. (void) prim_index; (void) tetrahedron;
  842. btAssert(0);
  843. }
  844. //! call when reading child shapes
  845. virtual void lockChildShapes() const
  846. {
  847. btAssert(0);
  848. }
  849. virtual void unlockChildShapes() const
  850. {
  851. btAssert(0);
  852. }
  853. //! Retrieves the bound from a child
  854. /*!
  855. */
  856. virtual void getChildAabb(int child_index,const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
  857. {
  858. (void) child_index; (void) t; (void) aabbMin; (void) aabbMax;
  859. btAssert(0);
  860. }
  861. //! Gets the children
  862. virtual btCollisionShape* getChildShape(int index)
  863. {
  864. (void) index;
  865. btAssert(0);
  866. return NULL;
  867. }
  868. //! Gets the child
  869. virtual const btCollisionShape* getChildShape(int index) const
  870. {
  871. (void) index;
  872. btAssert(0);
  873. return NULL;
  874. }
  875. //! Gets the children transform
  876. virtual btTransform getChildTransform(int index) const
  877. {
  878. (void) index;
  879. btAssert(0);
  880. return btTransform();
  881. }
  882. //! Sets the children transform
  883. /*!
  884. \post You must call updateBound() for update the box set.
  885. */
  886. virtual void setChildTransform(int index, const btTransform & transform)
  887. {
  888. (void) index; (void) transform;
  889. btAssert(0);
  890. }
  891. virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const
  892. {
  893. return CONST_GIMPACT_TRIMESH_SHAPE;
  894. }
  895. virtual const char* getName()const
  896. {
  897. return "GImpactMesh";
  898. }
  899. virtual void rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback) const;
  900. //! Function for retrieve triangles.
  901. /*!
  902. It gives the triangles in local space
  903. */
  904. virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
  905. virtual void processAllTrianglesRay (btTriangleCallback* callback,const btVector3& rayFrom,const btVector3& rayTo) const;
  906. virtual int calculateSerializeBufferSize() const;
  907. ///fills the dataBuffer and returns the struct name (and 0 on failure)
  908. virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
  909. };
  910. ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
  911. struct btGImpactMeshShapeData
  912. {
  913. btCollisionShapeData m_collisionShapeData;
  914. btStridingMeshInterfaceData m_meshInterface;
  915. btVector3FloatData m_localScaling;
  916. float m_collisionMargin;
  917. int m_gimpactSubType;
  918. };
  919. SIMD_FORCE_INLINE int btGImpactMeshShape::calculateSerializeBufferSize() const
  920. {
  921. return sizeof(btGImpactMeshShapeData);
  922. }
  923. #endif //GIMPACT_MESH_SHAPE_H