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