25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 

1172 satır
27 KiB

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