btGImpactShape.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107
  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: [email protected]
  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;
  218. (void)rayTo;
  219. (void)resultCallback;
  220. }
  221. //! Function for retrieve triangles.
  222. /*!
  223. It gives the triangles in local space
  224. */
  225. virtual void processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const
  226. {
  227. (void)callback;
  228. (void)aabbMin;
  229. (void)aabbMax;
  230. }
  231. //! Function for retrieve triangles.
  232. /*!
  233. It gives the triangles in local space
  234. */
  235. virtual void processAllTrianglesRay(btTriangleCallback* /*callback*/, const btVector3& /*rayFrom*/, const btVector3& /*rayTo*/) const
  236. {
  237. }
  238. //!@}
  239. };
  240. //! btGImpactCompoundShape allows to handle multiple btCollisionShape objects at once
  241. /*!
  242. This class only can manage Convex subshapes
  243. */
  244. class btGImpactCompoundShape : public btGImpactShapeInterface
  245. {
  246. public:
  247. //! compound primitive manager
  248. class CompoundPrimitiveManager : public btPrimitiveManagerBase
  249. {
  250. public:
  251. virtual ~CompoundPrimitiveManager() {}
  252. btGImpactCompoundShape* m_compoundShape;
  253. CompoundPrimitiveManager(const CompoundPrimitiveManager& compound)
  254. : btPrimitiveManagerBase()
  255. {
  256. m_compoundShape = compound.m_compoundShape;
  257. }
  258. CompoundPrimitiveManager(btGImpactCompoundShape* compoundShape)
  259. {
  260. m_compoundShape = compoundShape;
  261. }
  262. CompoundPrimitiveManager()
  263. {
  264. m_compoundShape = NULL;
  265. }
  266. virtual bool is_trimesh() const
  267. {
  268. return false;
  269. }
  270. virtual int get_primitive_count() const
  271. {
  272. return (int)m_compoundShape->getNumChildShapes();
  273. }
  274. virtual void get_primitive_box(int prim_index, btAABB& primbox) const
  275. {
  276. btTransform prim_trans;
  277. if (m_compoundShape->childrenHasTransform())
  278. {
  279. prim_trans = m_compoundShape->getChildTransform(prim_index);
  280. }
  281. else
  282. {
  283. prim_trans.setIdentity();
  284. }
  285. const btCollisionShape* shape = m_compoundShape->getChildShape(prim_index);
  286. shape->getAabb(prim_trans, primbox.m_min, primbox.m_max);
  287. }
  288. virtual void get_primitive_triangle(int prim_index, btPrimitiveTriangle& triangle) const
  289. {
  290. btAssert(0);
  291. (void)prim_index;
  292. (void)triangle;
  293. }
  294. };
  295. protected:
  296. CompoundPrimitiveManager m_primitive_manager;
  297. btAlignedObjectArray<btTransform> m_childTransforms;
  298. btAlignedObjectArray<btCollisionShape*> m_childShapes;
  299. public:
  300. btGImpactCompoundShape(bool children_has_transform = true)
  301. {
  302. (void)children_has_transform;
  303. m_primitive_manager.m_compoundShape = this;
  304. m_box_set.setPrimitiveManager(&m_primitive_manager);
  305. }
  306. virtual ~btGImpactCompoundShape()
  307. {
  308. }
  309. //! if true, then its children must get transforms.
  310. virtual bool childrenHasTransform() const
  311. {
  312. if (m_childTransforms.size() == 0) return false;
  313. return true;
  314. }
  315. //! Obtains the primitive manager
  316. virtual const btPrimitiveManagerBase* getPrimitiveManager() const
  317. {
  318. return &m_primitive_manager;
  319. }
  320. //! Obtains the compopund primitive manager
  321. SIMD_FORCE_INLINE CompoundPrimitiveManager* getCompoundPrimitiveManager()
  322. {
  323. return &m_primitive_manager;
  324. }
  325. //! Gets the number of children
  326. virtual int getNumChildShapes() const
  327. {
  328. return m_childShapes.size();
  329. }
  330. //! Use this method for adding children. Only Convex shapes are allowed.
  331. void addChildShape(const btTransform& localTransform, btCollisionShape* shape)
  332. {
  333. btAssert(shape->isConvex());
  334. m_childTransforms.push_back(localTransform);
  335. m_childShapes.push_back(shape);
  336. }
  337. //! Use this method for adding children. Only Convex shapes are allowed.
  338. void addChildShape(btCollisionShape* shape)
  339. {
  340. btAssert(shape->isConvex());
  341. m_childShapes.push_back(shape);
  342. }
  343. //! Gets the children
  344. virtual btCollisionShape* getChildShape(int index)
  345. {
  346. return m_childShapes[index];
  347. }
  348. //! Gets the children
  349. virtual const btCollisionShape* getChildShape(int index) const
  350. {
  351. return m_childShapes[index];
  352. }
  353. //! Retrieves the bound from a child
  354. /*!
  355. */
  356. virtual void getChildAabb(int child_index, const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
  357. {
  358. if (childrenHasTransform())
  359. {
  360. m_childShapes[child_index]->getAabb(t * m_childTransforms[child_index], aabbMin, aabbMax);
  361. }
  362. else
  363. {
  364. m_childShapes[child_index]->getAabb(t, aabbMin, aabbMax);
  365. }
  366. }
  367. //! Gets the children transform
  368. virtual btTransform getChildTransform(int index) const
  369. {
  370. btAssert(m_childTransforms.size() == m_childShapes.size());
  371. return m_childTransforms[index];
  372. }
  373. //! Sets the children transform
  374. /*!
  375. \post You must call updateBound() for update the box set.
  376. */
  377. virtual void setChildTransform(int index, const btTransform& transform)
  378. {
  379. btAssert(m_childTransforms.size() == m_childShapes.size());
  380. m_childTransforms[index] = transform;
  381. postUpdate();
  382. }
  383. //! Determines if this shape has triangles
  384. virtual bool needsRetrieveTriangles() const
  385. {
  386. return false;
  387. }
  388. //! Determines if this shape has tetrahedrons
  389. virtual bool needsRetrieveTetrahedrons() const
  390. {
  391. return false;
  392. }
  393. virtual void getBulletTriangle(int prim_index, btTriangleShapeEx& triangle) const
  394. {
  395. (void)prim_index;
  396. (void)triangle;
  397. btAssert(0);
  398. }
  399. virtual void getBulletTetrahedron(int prim_index, btTetrahedronShapeEx& tetrahedron) const
  400. {
  401. (void)prim_index;
  402. (void)tetrahedron;
  403. btAssert(0);
  404. }
  405. //! Calculates the exact inertia tensor for this shape
  406. virtual void calculateLocalInertia(btScalar mass, btVector3& inertia) const;
  407. virtual const char* getName() const
  408. {
  409. return "GImpactCompound";
  410. }
  411. virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const
  412. {
  413. return CONST_GIMPACT_COMPOUND_SHAPE;
  414. }
  415. };
  416. //! This class manages a sub part of a mesh supplied by the btStridingMeshInterface interface.
  417. /*!
  418. - Simply create this shape by passing the btStridingMeshInterface to the constructor btGImpactMeshShapePart, then you must call updateBound() after creating the mesh
  419. - When making operations with this shape, you must call <b>lock</b> before accessing to the trimesh primitives, and then call <b>unlock</b>
  420. - You can handle deformable meshes with this shape, by calling postUpdate() every time when changing the mesh vertices.
  421. */
  422. class btGImpactMeshShapePart : public btGImpactShapeInterface
  423. {
  424. public:
  425. //! Trimesh primitive manager
  426. /*!
  427. Manages the info from btStridingMeshInterface object and controls the Lock/Unlock mechanism
  428. */
  429. class TrimeshPrimitiveManager : public btPrimitiveManagerBase
  430. {
  431. public:
  432. btScalar m_margin;
  433. btStridingMeshInterface* m_meshInterface;
  434. btVector3 m_scale;
  435. int m_part;
  436. int m_lock_count;
  437. const unsigned char* vertexbase;
  438. int numverts;
  439. PHY_ScalarType type;
  440. int stride;
  441. const unsigned char* indexbase;
  442. int indexstride;
  443. int numfaces;
  444. PHY_ScalarType indicestype;
  445. TrimeshPrimitiveManager()
  446. {
  447. m_meshInterface = NULL;
  448. m_part = 0;
  449. m_margin = 0.01f;
  450. m_scale = btVector3(1.f, 1.f, 1.f);
  451. m_lock_count = 0;
  452. vertexbase = 0;
  453. numverts = 0;
  454. stride = 0;
  455. indexbase = 0;
  456. indexstride = 0;
  457. numfaces = 0;
  458. }
  459. TrimeshPrimitiveManager(const TrimeshPrimitiveManager& manager)
  460. : btPrimitiveManagerBase()
  461. {
  462. m_meshInterface = manager.m_meshInterface;
  463. m_part = manager.m_part;
  464. m_margin = manager.m_margin;
  465. m_scale = manager.m_scale;
  466. m_lock_count = 0;
  467. vertexbase = 0;
  468. numverts = 0;
  469. stride = 0;
  470. indexbase = 0;
  471. indexstride = 0;
  472. numfaces = 0;
  473. }
  474. TrimeshPrimitiveManager(
  475. btStridingMeshInterface* meshInterface, int part)
  476. {
  477. m_meshInterface = meshInterface;
  478. m_part = part;
  479. m_scale = m_meshInterface->getScaling();
  480. m_margin = 0.1f;
  481. m_lock_count = 0;
  482. vertexbase = 0;
  483. numverts = 0;
  484. stride = 0;
  485. indexbase = 0;
  486. indexstride = 0;
  487. numfaces = 0;
  488. }
  489. virtual ~TrimeshPrimitiveManager() {}
  490. void lock()
  491. {
  492. if (m_lock_count > 0)
  493. {
  494. m_lock_count++;
  495. return;
  496. }
  497. m_meshInterface->getLockedReadOnlyVertexIndexBase(
  498. &vertexbase, numverts,
  499. type, stride, &indexbase, indexstride, numfaces, indicestype, m_part);
  500. m_lock_count = 1;
  501. }
  502. void unlock()
  503. {
  504. if (m_lock_count == 0) return;
  505. if (m_lock_count > 1)
  506. {
  507. --m_lock_count;
  508. return;
  509. }
  510. m_meshInterface->unLockReadOnlyVertexBase(m_part);
  511. vertexbase = NULL;
  512. m_lock_count = 0;
  513. }
  514. virtual bool is_trimesh() const
  515. {
  516. return true;
  517. }
  518. virtual int get_primitive_count() const
  519. {
  520. return (int)numfaces;
  521. }
  522. SIMD_FORCE_INLINE int get_vertex_count() const
  523. {
  524. return (int)numverts;
  525. }
  526. SIMD_FORCE_INLINE void get_indices(int face_index, unsigned int& i0, unsigned int& i1, unsigned int& i2) const
  527. {
  528. if (indicestype == PHY_SHORT)
  529. {
  530. unsigned short* s_indices = (unsigned short*)(indexbase + face_index * indexstride);
  531. i0 = s_indices[0];
  532. i1 = s_indices[1];
  533. i2 = s_indices[2];
  534. }
  535. else
  536. {
  537. unsigned int* i_indices = (unsigned int*)(indexbase + face_index * indexstride);
  538. i0 = i_indices[0];
  539. i1 = i_indices[1];
  540. i2 = i_indices[2];
  541. }
  542. }
  543. SIMD_FORCE_INLINE void get_vertex(unsigned int vertex_index, btVector3& vertex) const
  544. {
  545. if (type == PHY_DOUBLE)
  546. {
  547. double* dvertices = (double*)(vertexbase + vertex_index * stride);
  548. vertex[0] = btScalar(dvertices[0] * m_scale[0]);
  549. vertex[1] = btScalar(dvertices[1] * m_scale[1]);
  550. vertex[2] = btScalar(dvertices[2] * m_scale[2]);
  551. }
  552. else
  553. {
  554. float* svertices = (float*)(vertexbase + vertex_index * stride);
  555. vertex[0] = svertices[0] * m_scale[0];
  556. vertex[1] = svertices[1] * m_scale[1];
  557. vertex[2] = svertices[2] * m_scale[2];
  558. }
  559. }
  560. virtual void get_primitive_box(int prim_index, btAABB& primbox) const
  561. {
  562. btPrimitiveTriangle triangle;
  563. get_primitive_triangle(prim_index, triangle);
  564. primbox.calc_from_triangle_margin(
  565. triangle.m_vertices[0],
  566. triangle.m_vertices[1], triangle.m_vertices[2], triangle.m_margin);
  567. }
  568. virtual void get_primitive_triangle(int prim_index, btPrimitiveTriangle& triangle) const
  569. {
  570. unsigned int indices[3];
  571. get_indices(prim_index, indices[0], indices[1], indices[2]);
  572. get_vertex(indices[0], triangle.m_vertices[0]);
  573. get_vertex(indices[1], triangle.m_vertices[1]);
  574. get_vertex(indices[2], triangle.m_vertices[2]);
  575. triangle.m_margin = m_margin;
  576. }
  577. SIMD_FORCE_INLINE void get_bullet_triangle(int prim_index, btTriangleShapeEx& triangle) const
  578. {
  579. unsigned int indices[3];
  580. get_indices(prim_index, indices[0], indices[1], indices[2]);
  581. get_vertex(indices[0], triangle.m_vertices1[0]);
  582. get_vertex(indices[1], triangle.m_vertices1[1]);
  583. get_vertex(indices[2], triangle.m_vertices1[2]);
  584. triangle.setMargin(m_margin);
  585. }
  586. };
  587. protected:
  588. TrimeshPrimitiveManager m_primitive_manager;
  589. public:
  590. btGImpactMeshShapePart()
  591. {
  592. m_box_set.setPrimitiveManager(&m_primitive_manager);
  593. }
  594. btGImpactMeshShapePart(btStridingMeshInterface* meshInterface, int part);
  595. virtual ~btGImpactMeshShapePart();
  596. //! if true, then its children must get transforms.
  597. virtual bool childrenHasTransform() const
  598. {
  599. return false;
  600. }
  601. //! call when reading child shapes
  602. virtual void lockChildShapes() const;
  603. virtual void unlockChildShapes() const;
  604. //! Gets the number of children
  605. virtual int getNumChildShapes() const
  606. {
  607. return m_primitive_manager.get_primitive_count();
  608. }
  609. //! Gets the children
  610. virtual btCollisionShape* getChildShape(int index)
  611. {
  612. (void)index;
  613. btAssert(0);
  614. return NULL;
  615. }
  616. //! Gets the child
  617. virtual const btCollisionShape* getChildShape(int index) const
  618. {
  619. (void)index;
  620. btAssert(0);
  621. return NULL;
  622. }
  623. //! Gets the children transform
  624. virtual btTransform getChildTransform(int index) const
  625. {
  626. (void)index;
  627. btAssert(0);
  628. return btTransform();
  629. }
  630. //! Sets the children transform
  631. /*!
  632. \post You must call updateBound() for update the box set.
  633. */
  634. virtual void setChildTransform(int index, const btTransform& transform)
  635. {
  636. (void)index;
  637. (void)transform;
  638. btAssert(0);
  639. }
  640. //! Obtains the primitive manager
  641. virtual const btPrimitiveManagerBase* getPrimitiveManager() const
  642. {
  643. return &m_primitive_manager;
  644. }
  645. SIMD_FORCE_INLINE TrimeshPrimitiveManager* getTrimeshPrimitiveManager()
  646. {
  647. return &m_primitive_manager;
  648. }
  649. virtual void calculateLocalInertia(btScalar mass, btVector3& inertia) const;
  650. virtual const char* getName() const
  651. {
  652. return "GImpactMeshShapePart";
  653. }
  654. virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const
  655. {
  656. return CONST_GIMPACT_TRIMESH_SHAPE_PART;
  657. }
  658. //! Determines if this shape has triangles
  659. virtual bool needsRetrieveTriangles() const
  660. {
  661. return true;
  662. }
  663. //! Determines if this shape has tetrahedrons
  664. virtual bool needsRetrieveTetrahedrons() const
  665. {
  666. return false;
  667. }
  668. virtual void getBulletTriangle(int prim_index, btTriangleShapeEx& triangle) const
  669. {
  670. m_primitive_manager.get_bullet_triangle(prim_index, triangle);
  671. }
  672. virtual void getBulletTetrahedron(int prim_index, btTetrahedronShapeEx& tetrahedron) const
  673. {
  674. (void)prim_index;
  675. (void)tetrahedron;
  676. btAssert(0);
  677. }
  678. SIMD_FORCE_INLINE int getVertexCount() const
  679. {
  680. return m_primitive_manager.get_vertex_count();
  681. }
  682. SIMD_FORCE_INLINE void getVertex(int vertex_index, btVector3& vertex) const
  683. {
  684. m_primitive_manager.get_vertex(vertex_index, vertex);
  685. }
  686. SIMD_FORCE_INLINE void setMargin(btScalar margin)
  687. {
  688. m_primitive_manager.m_margin = margin;
  689. postUpdate();
  690. }
  691. SIMD_FORCE_INLINE btScalar getMargin() const
  692. {
  693. return m_primitive_manager.m_margin;
  694. }
  695. virtual void setLocalScaling(const btVector3& scaling)
  696. {
  697. m_primitive_manager.m_scale = scaling;
  698. postUpdate();
  699. }
  700. virtual const btVector3& getLocalScaling() const
  701. {
  702. return m_primitive_manager.m_scale;
  703. }
  704. SIMD_FORCE_INLINE int getPart() const
  705. {
  706. return (int)m_primitive_manager.m_part;
  707. }
  708. virtual void processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const;
  709. virtual void processAllTrianglesRay(btTriangleCallback* callback, const btVector3& rayFrom, const btVector3& rayTo) const;
  710. };
  711. //! This class manages a mesh supplied by the btStridingMeshInterface interface.
  712. /*!
  713. Set of btGImpactMeshShapePart parts
  714. - Simply create this shape by passing the btStridingMeshInterface to the constructor btGImpactMeshShape, then you must call updateBound() after creating the mesh
  715. - You can handle deformable meshes with this shape, by calling postUpdate() every time when changing the mesh vertices.
  716. */
  717. class btGImpactMeshShape : public btGImpactShapeInterface
  718. {
  719. btStridingMeshInterface* m_meshInterface;
  720. protected:
  721. btAlignedObjectArray<btGImpactMeshShapePart*> m_mesh_parts;
  722. void buildMeshParts(btStridingMeshInterface* meshInterface)
  723. {
  724. for (int i = 0; i < meshInterface->getNumSubParts(); ++i)
  725. {
  726. btGImpactMeshShapePart* newpart = new btGImpactMeshShapePart(meshInterface, i);
  727. m_mesh_parts.push_back(newpart);
  728. }
  729. }
  730. //! use this function for perfofm refit in bounding boxes
  731. virtual void calcLocalAABB()
  732. {
  733. m_localAABB.invalidate();
  734. int i = m_mesh_parts.size();
  735. while (i--)
  736. {
  737. m_mesh_parts[i]->updateBound();
  738. m_localAABB.merge(m_mesh_parts[i]->getLocalBox());
  739. }
  740. }
  741. public:
  742. btGImpactMeshShape(btStridingMeshInterface* meshInterface)
  743. {
  744. m_meshInterface = meshInterface;
  745. buildMeshParts(meshInterface);
  746. }
  747. virtual ~btGImpactMeshShape()
  748. {
  749. int i = m_mesh_parts.size();
  750. while (i--)
  751. {
  752. btGImpactMeshShapePart* part = m_mesh_parts[i];
  753. delete part;
  754. }
  755. m_mesh_parts.clear();
  756. }
  757. btStridingMeshInterface* getMeshInterface()
  758. {
  759. return m_meshInterface;
  760. }
  761. const btStridingMeshInterface* getMeshInterface() const
  762. {
  763. return m_meshInterface;
  764. }
  765. int getMeshPartCount() const
  766. {
  767. return m_mesh_parts.size();
  768. }
  769. btGImpactMeshShapePart* getMeshPart(int index)
  770. {
  771. return m_mesh_parts[index];
  772. }
  773. const btGImpactMeshShapePart* getMeshPart(int index) const
  774. {
  775. return m_mesh_parts[index];
  776. }
  777. virtual void setLocalScaling(const btVector3& scaling)
  778. {
  779. localScaling = scaling;
  780. int i = m_mesh_parts.size();
  781. while (i--)
  782. {
  783. btGImpactMeshShapePart* part = m_mesh_parts[i];
  784. part->setLocalScaling(scaling);
  785. }
  786. m_needs_update = true;
  787. }
  788. virtual void setMargin(btScalar margin)
  789. {
  790. m_collisionMargin = margin;
  791. int i = m_mesh_parts.size();
  792. while (i--)
  793. {
  794. btGImpactMeshShapePart* part = m_mesh_parts[i];
  795. part->setMargin(margin);
  796. }
  797. m_needs_update = true;
  798. }
  799. //! Tells to this object that is needed to refit all the meshes
  800. virtual void postUpdate()
  801. {
  802. int i = m_mesh_parts.size();
  803. while (i--)
  804. {
  805. btGImpactMeshShapePart* part = m_mesh_parts[i];
  806. part->postUpdate();
  807. }
  808. m_needs_update = true;
  809. }
  810. virtual void calculateLocalInertia(btScalar mass, btVector3& inertia) const;
  811. //! Obtains the primitive manager
  812. virtual const btPrimitiveManagerBase* getPrimitiveManager() const
  813. {
  814. btAssert(0);
  815. return NULL;
  816. }
  817. //! Gets the number of children
  818. virtual int getNumChildShapes() const
  819. {
  820. btAssert(0);
  821. return 0;
  822. }
  823. //! if true, then its children must get transforms.
  824. virtual bool childrenHasTransform() const
  825. {
  826. btAssert(0);
  827. return false;
  828. }
  829. //! Determines if this shape has triangles
  830. virtual bool needsRetrieveTriangles() const
  831. {
  832. btAssert(0);
  833. return false;
  834. }
  835. //! Determines if this shape has tetrahedrons
  836. virtual bool needsRetrieveTetrahedrons() const
  837. {
  838. btAssert(0);
  839. return false;
  840. }
  841. virtual void getBulletTriangle(int prim_index, btTriangleShapeEx& triangle) const
  842. {
  843. (void)prim_index;
  844. (void)triangle;
  845. btAssert(0);
  846. }
  847. virtual void getBulletTetrahedron(int prim_index, btTetrahedronShapeEx& tetrahedron) const
  848. {
  849. (void)prim_index;
  850. (void)tetrahedron;
  851. btAssert(0);
  852. }
  853. //! call when reading child shapes
  854. virtual void lockChildShapes() const
  855. {
  856. btAssert(0);
  857. }
  858. virtual void unlockChildShapes() const
  859. {
  860. btAssert(0);
  861. }
  862. //! Retrieves the bound from a child
  863. /*!
  864. */
  865. virtual void getChildAabb(int child_index, const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
  866. {
  867. (void)child_index;
  868. (void)t;
  869. (void)aabbMin;
  870. (void)aabbMax;
  871. btAssert(0);
  872. }
  873. //! Gets the children
  874. virtual btCollisionShape* getChildShape(int index)
  875. {
  876. (void)index;
  877. btAssert(0);
  878. return NULL;
  879. }
  880. //! Gets the child
  881. virtual const btCollisionShape* getChildShape(int index) const
  882. {
  883. (void)index;
  884. btAssert(0);
  885. return NULL;
  886. }
  887. //! Gets the children transform
  888. virtual btTransform getChildTransform(int index) const
  889. {
  890. (void)index;
  891. btAssert(0);
  892. return btTransform();
  893. }
  894. //! Sets the children transform
  895. /*!
  896. \post You must call updateBound() for update the box set.
  897. */
  898. virtual void setChildTransform(int index, const btTransform& transform)
  899. {
  900. (void)index;
  901. (void)transform;
  902. btAssert(0);
  903. }
  904. virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const
  905. {
  906. return CONST_GIMPACT_TRIMESH_SHAPE;
  907. }
  908. virtual const char* getName() const
  909. {
  910. return "GImpactMesh";
  911. }
  912. virtual void rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback) const;
  913. //! Function for retrieve triangles.
  914. /*!
  915. It gives the triangles in local space
  916. */
  917. virtual void processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const;
  918. virtual void processAllTrianglesRay(btTriangleCallback* callback, const btVector3& rayFrom, const btVector3& rayTo) const;
  919. virtual int calculateSerializeBufferSize() const;
  920. ///fills the dataBuffer and returns the struct name (and 0 on failure)
  921. virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
  922. };
  923. ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
  924. struct btGImpactMeshShapeData
  925. {
  926. btCollisionShapeData m_collisionShapeData;
  927. btStridingMeshInterfaceData m_meshInterface;
  928. btVector3FloatData m_localScaling;
  929. float m_collisionMargin;
  930. int m_gimpactSubType;
  931. };
  932. SIMD_FORCE_INLINE int btGImpactMeshShape::calculateSerializeBufferSize() const
  933. {
  934. return sizeof(btGImpactMeshShapeData);
  935. }
  936. #endif //GIMPACT_MESH_SHAPE_H