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