1165 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			1165 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | /*! \file btGImpactShape.h
 | |||
|  | \author Francisco Len N<EFBFBD>jera | |||
|  | */ | |||
|  | /*
 | |||
|  | This source file is part of GIMPACT Library. | |||
|  | 
 | |||
|  | For the latest info, see http://gimpact.sourceforge.net/
 | |||
|  | 
 | |||
|  | Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371. | |||
|  | email: projectileman@yahoo.com | |||
|  | 
 | |||
|  | 
 | |||
|  | This software is provided 'as-is', without any express or implied warranty. | |||
|  | In no event will the authors be held liable for any damages arising from the use of this software. | |||
|  | Permission is granted to anyone to use this software for any purpose, | |||
|  | including commercial applications, and to alter it and redistribute it freely, | |||
|  | subject to the following restrictions: | |||
|  | 
 | |||
|  | 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. | |||
|  | 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. | |||
|  | 3. This notice may not be removed or altered from any source distribution. | |||
|  | */ | |||
|  | 
 | |||
|  | 
 | |||
|  | #ifndef GIMPACT_SHAPE_H
 | |||
|  | #define GIMPACT_SHAPE_H
 | |||
|  | 
 | |||
|  | #include "BulletCollision/CollisionShapes/btCollisionShape.h"
 | |||
|  | #include "BulletCollision/CollisionShapes/btTriangleShape.h"
 | |||
|  | #include "BulletCollision/CollisionShapes/btStridingMeshInterface.h"
 | |||
|  | #include "BulletCollision/CollisionShapes/btCollisionMargin.h"
 | |||
|  | #include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
 | |||
|  | #include "BulletCollision/CollisionShapes/btConcaveShape.h"
 | |||
|  | #include "BulletCollision/CollisionShapes/btTetrahedronShape.h"
 | |||
|  | #include "LinearMath/btVector3.h"
 | |||
|  | #include "LinearMath/btTransform.h"
 | |||
|  | #include "LinearMath/btMatrix3x3.h"
 | |||
|  | #include "LinearMath/btAlignedObjectArray.h"
 | |||
|  | 
 | |||
|  | #include "btGImpactQuantizedBvh.h" // box tree class
 | |||
|  | 
 | |||
|  | 
 | |||
|  | //! declare Quantized trees, (you can change to float based trees)
 | |||
|  | typedef btGImpactQuantizedBvh btGImpactBoxSet; | |||
|  | 
 | |||
|  | enum eGIMPACT_SHAPE_TYPE | |||
|  | { | |||
|  | 	CONST_GIMPACT_COMPOUND_SHAPE = 0, | |||
|  | 	CONST_GIMPACT_TRIMESH_SHAPE_PART, | |||
|  | 	CONST_GIMPACT_TRIMESH_SHAPE | |||
|  | }; | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | //! Helper class for tetrahedrons
 | |||
|  | class btTetrahedronShapeEx:public btBU_Simplex1to4 | |||
|  | { | |||
|  | public: | |||
|  | 	btTetrahedronShapeEx() | |||
|  | 	{ | |||
|  | 		m_numVertices = 4; | |||
|  | 	} | |||
|  | 
 | |||
|  | 
 | |||
|  | 	SIMD_FORCE_INLINE void setVertices( | |||
|  | 		const btVector3 & v0,const btVector3 & v1, | |||
|  | 		const btVector3 & v2,const btVector3 & v3) | |||
|  | 	{ | |||
|  | 		m_vertices[0] = v0; | |||
|  | 		m_vertices[1] = v1; | |||
|  | 		m_vertices[2] = v2; | |||
|  | 		m_vertices[3] = v3; | |||
|  | 		recalcLocalAabb(); | |||
|  | 	} | |||
|  | }; | |||
|  | 
 | |||
|  | 
 | |||
|  | //! Base class for gimpact shapes
 | |||
|  | class btGImpactShapeInterface : public btConcaveShape | |||
|  | { | |||
|  | protected: | |||
|  |     btAABB m_localAABB; | |||
|  |     bool m_needs_update; | |||
|  |     btVector3  localScaling; | |||
|  |     btGImpactBoxSet m_box_set;// optionally boxset
 | |||
|  | 
 | |||
|  | 	//! use this function for perfofm refit in bounding boxes
 | |||
|  |     //! use this function for perfofm refit in bounding boxes
 | |||
|  |     virtual void calcLocalAABB() | |||
|  |     { | |||
|  | 		lockChildShapes(); | |||
|  |     	if(m_box_set.getNodeCount() == 0) | |||
|  |     	{ | |||
|  |     		m_box_set.buildSet(); | |||
|  |     	} | |||
|  |     	else | |||
|  |     	{ | |||
|  |     		m_box_set.update(); | |||
|  |     	} | |||
|  |     	unlockChildShapes(); | |||
|  | 
 | |||
|  |     	m_localAABB = m_box_set.getGlobalBox(); | |||
|  |     } | |||
|  | 
 | |||
|  | 
 | |||
|  | public: | |||
|  | 	btGImpactShapeInterface() | |||
|  | 	{ | |||
|  | 		m_shapeType=GIMPACT_SHAPE_PROXYTYPE; | |||
|  | 		m_localAABB.invalidate(); | |||
|  | 		m_needs_update = true; | |||
|  | 		localScaling.setValue(1.f,1.f,1.f); | |||
|  | 	} | |||
|  | 
 | |||
|  | 
 | |||
|  | 	//! performs refit operation
 | |||
|  | 	/*!
 | |||
|  | 	Updates the entire Box set of this shape. | |||
|  | 	\pre postUpdate() must be called for attemps to calculating the box set, else this function | |||
|  | 		will does nothing. | |||
|  | 	\post if m_needs_update == true, then it calls calcLocalAABB(); | |||
|  | 	*/ | |||
|  |     SIMD_FORCE_INLINE void updateBound() | |||
|  |     { | |||
|  |     	if(!m_needs_update) return; | |||
|  |     	calcLocalAABB(); | |||
|  |     	m_needs_update  = false; | |||
|  |     } | |||
|  | 
 | |||
|  |     //! If the Bounding box is not updated, then this class attemps to calculate it.
 | |||
|  |     /*!
 | |||
|  |     \post Calls updateBound() for update the box set. | |||
|  |     */ | |||
|  |     void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const | |||
|  |     { | |||
|  |         btAABB transformedbox = m_localAABB; | |||
|  |         transformedbox.appy_transform(t); | |||
|  |         aabbMin = transformedbox.m_min; | |||
|  |         aabbMax = transformedbox.m_max; | |||
|  |     } | |||
|  | 
 | |||
|  |     //! Tells to this object that is needed to refit the box set
 | |||
|  |     virtual void postUpdate() | |||
|  |     { | |||
|  |     	m_needs_update = true; | |||
|  |     } | |||
|  | 
 | |||
|  | 	//! Obtains the local box, which is the global calculated box of the total of subshapes
 | |||
|  | 	SIMD_FORCE_INLINE const btAABB & getLocalBox() | |||
|  | 	{ | |||
|  | 		return m_localAABB; | |||
|  | 	} | |||
|  | 
 | |||
|  | 
 | |||
|  |     virtual int	getShapeType() const | |||
|  |     { | |||
|  |         return GIMPACT_SHAPE_PROXYTYPE; | |||
|  |     } | |||
|  | 
 | |||
|  |     /*!
 | |||
|  | 	\post You must call updateBound() for update the box set. | |||
|  | 	*/ | |||
|  | 	virtual void	setLocalScaling(const btVector3& scaling) | |||
|  | 	{ | |||
|  | 		localScaling = scaling; | |||
|  | 		postUpdate(); | |||
|  | 	} | |||
|  | 
 | |||
|  | 	virtual const btVector3& getLocalScaling() const | |||
|  | 	{ | |||
|  | 		return localScaling; | |||
|  | 	} | |||
|  | 
 | |||
|  | 
 | |||
|  | 	virtual void setMargin(btScalar margin) | |||
|  |     { | |||
|  |     	m_collisionMargin = margin; | |||
|  |     	int i = getNumChildShapes(); | |||
|  |     	while(i--) | |||
|  |     	{ | |||
|  | 			btCollisionShape* child = getChildShape(i); | |||
|  | 			child->setMargin(margin); | |||
|  |     	} | |||
|  | 
 | |||
|  | 		m_needs_update = true; | |||
|  |     } | |||
|  | 
 | |||
|  | 
 | |||
|  | 	//! Subshape member functions
 | |||
|  | 	//!@{
 | |||
|  | 
 | |||
|  | 	//! Base method for determinig which kind of GIMPACT shape we get
 | |||
|  | 	virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const = 0 ; | |||
|  | 
 | |||
|  | 	//! gets boxset
 | |||
|  | 	SIMD_FORCE_INLINE const btGImpactBoxSet * getBoxSet() const | |||
|  | 	{ | |||
|  | 		return &m_box_set; | |||
|  | 	} | |||
|  | 
 | |||
|  | 	//! Determines if this class has a hierarchy structure for sorting its primitives
 | |||
|  | 	SIMD_FORCE_INLINE bool hasBoxSet()  const | |||
|  | 	{ | |||
|  | 		if(m_box_set.getNodeCount() == 0) return false; | |||
|  | 		return true; | |||
|  | 	} | |||
|  | 
 | |||
|  | 	//! Obtains the primitive manager
 | |||
|  | 	virtual const btPrimitiveManagerBase * getPrimitiveManager()  const = 0; | |||
|  | 
 | |||
|  | 
 | |||
|  | 	//! Gets the number of children
 | |||
|  | 	virtual int	getNumChildShapes() const  = 0; | |||
|  | 
 | |||
|  | 	//! if true, then its children must get transforms.
 | |||
|  | 	virtual bool childrenHasTransform() const = 0; | |||
|  | 
 | |||
|  | 	//! Determines if this shape has triangles
 | |||
|  | 	virtual bool needsRetrieveTriangles() const = 0; | |||
|  | 
 | |||
|  | 	//! Determines if this shape has tetrahedrons
 | |||
|  | 	virtual bool needsRetrieveTetrahedrons() const = 0; | |||
|  | 
 | |||
|  | 	virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const = 0; | |||
|  | 
 | |||
|  | 	virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const = 0; | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 	//! call when reading child shapes
 | |||
|  | 	virtual void lockChildShapes() const | |||
|  | 	{ | |||
|  | 	} | |||
|  | 
 | |||
|  | 	virtual void unlockChildShapes() const | |||
|  | 	{ | |||
|  | 	} | |||
|  | 
 | |||
|  | 	//! if this trimesh
 | |||
|  | 	SIMD_FORCE_INLINE void getPrimitiveTriangle(int index,btPrimitiveTriangle & triangle) const | |||
|  | 	{ | |||
|  | 		getPrimitiveManager()->get_primitive_triangle(index,triangle); | |||
|  | 	} | |||
|  | 
 | |||
|  | 
 | |||
|  | 	//! Retrieves the bound from a child
 | |||
|  |     /*!
 | |||
|  |     */ | |||
|  |     virtual void getChildAabb(int child_index,const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const | |||
|  |     { | |||
|  |         btAABB child_aabb; | |||
|  |         getPrimitiveManager()->get_primitive_box(child_index,child_aabb); | |||
|  |         child_aabb.appy_transform(t); | |||
|  |         aabbMin = child_aabb.m_min; | |||
|  |         aabbMax = child_aabb.m_max; | |||
|  |     } | |||
|  | 
 | |||
|  | 	//! Gets the children
 | |||
|  | 	virtual btCollisionShape* getChildShape(int index) = 0; | |||
|  | 
 | |||
|  | 
 | |||
|  | 	//! Gets the child
 | |||
|  | 	virtual const btCollisionShape* getChildShape(int index) const = 0; | |||
|  | 
 | |||
|  | 	//! Gets the children transform
 | |||
|  | 	virtual btTransform	getChildTransform(int index) const = 0; | |||
|  | 
 | |||
|  | 	//! Sets the children transform
 | |||
|  | 	/*!
 | |||
|  | 	\post You must call updateBound() for update the box set. | |||
|  | 	*/ | |||
|  | 	virtual void setChildTransform(int index, const btTransform & transform) = 0; | |||
|  | 
 | |||
|  | 	//!@}
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 	//! virtual method for ray collision
 | |||
|  | 	virtual void rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback)  const | |||
|  | 	{ | |||
|  |         (void) rayFrom; (void) rayTo; (void) resultCallback; | |||
|  | 	} | |||
|  | 
 | |||
|  | 	//! Function for retrieve triangles.
 | |||
|  | 	/*!
 | |||
|  | 	It gives the triangles in local space | |||
|  | 	*/ | |||
|  | 	virtual void	processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const | |||
|  | 	{ | |||
|  |         (void) callback; (void) aabbMin; (void) aabbMax; | |||
|  | 	} | |||
|  | 
 | |||
|  | 	//! Function for retrieve triangles.
 | |||
|  | 	/*!
 | |||
|  | 	It gives the triangles in local space | |||
|  | 	*/ | |||
|  | 	virtual void processAllTrianglesRay(btTriangleCallback* /*callback*/,const btVector3& /*rayFrom*/, const btVector3& /*rayTo*/) const | |||
|  | 	{ | |||
|  | 		 | |||
|  | 	} | |||
|  | 
 | |||
|  | 	//!@}
 | |||
|  | 
 | |||
|  | }; | |||
|  | 
 | |||
|  | 
 | |||
|  | //! btGImpactCompoundShape allows to handle multiple btCollisionShape objects at once
 | |||
|  | /*!
 | |||
|  | This class only can manage Convex subshapes | |||
|  | */ | |||
|  | class btGImpactCompoundShape	: public btGImpactShapeInterface | |||
|  | { | |||
|  | public: | |||
|  | 	//! compound primitive manager
 | |||
|  | 	class CompoundPrimitiveManager:public btPrimitiveManagerBase | |||
|  | 	{ | |||
|  | 	public: | |||
|  | 		virtual ~CompoundPrimitiveManager() {} | |||
|  | 		btGImpactCompoundShape * m_compoundShape; | |||
|  | 
 | |||
|  | 
 | |||
|  | 		CompoundPrimitiveManager(const CompoundPrimitiveManager& compound) | |||
|  |             : btPrimitiveManagerBase() | |||
|  | 		{ | |||
|  | 			m_compoundShape = compound.m_compoundShape; | |||
|  | 		} | |||
|  | 
 | |||
|  | 		CompoundPrimitiveManager(btGImpactCompoundShape * compoundShape) | |||
|  | 		{ | |||
|  | 			m_compoundShape = compoundShape; | |||
|  | 		} | |||
|  | 
 | |||
|  | 		CompoundPrimitiveManager() | |||
|  | 		{ | |||
|  | 			m_compoundShape = NULL; | |||
|  | 		} | |||
|  | 
 | |||
|  | 		virtual bool is_trimesh() const | |||
|  | 		{ | |||
|  | 			return false; | |||
|  | 		} | |||
|  | 
 | |||
|  | 		virtual int get_primitive_count() const | |||
|  | 		{ | |||
|  | 			return (int )m_compoundShape->getNumChildShapes(); | |||
|  | 		} | |||
|  | 
 | |||
|  | 		virtual void get_primitive_box(int prim_index ,btAABB & primbox) const | |||
|  | 		{ | |||
|  | 			btTransform prim_trans; | |||
|  | 			if(m_compoundShape->childrenHasTransform()) | |||
|  | 			{ | |||
|  | 				prim_trans = m_compoundShape->getChildTransform(prim_index); | |||
|  | 			} | |||
|  | 			else | |||
|  | 			{ | |||
|  | 				prim_trans.setIdentity(); | |||
|  | 			} | |||
|  | 			const btCollisionShape* shape = m_compoundShape->getChildShape(prim_index); | |||
|  | 			shape->getAabb(prim_trans,primbox.m_min,primbox.m_max); | |||
|  | 		} | |||
|  | 
 | |||
|  | 		virtual void get_primitive_triangle(int prim_index,btPrimitiveTriangle & triangle) const | |||
|  | 		{ | |||
|  | 			btAssert(0); | |||
|  |             (void) prim_index; (void) triangle; | |||
|  | 		} | |||
|  | 
 | |||
|  | 	}; | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | protected: | |||
|  | 	CompoundPrimitiveManager m_primitive_manager; | |||
|  | 	btAlignedObjectArray<btTransform>		m_childTransforms; | |||
|  | 	btAlignedObjectArray<btCollisionShape*>	m_childShapes; | |||
|  | 
 | |||
|  | 
 | |||
|  | public: | |||
|  | 
 | |||
|  | 	btGImpactCompoundShape(bool children_has_transform = true) | |||
|  | 	{ | |||
|  |         (void) children_has_transform; | |||
|  | 		m_primitive_manager.m_compoundShape = this; | |||
|  | 		m_box_set.setPrimitiveManager(&m_primitive_manager); | |||
|  | 	} | |||
|  | 
 | |||
|  | 	virtual ~btGImpactCompoundShape() | |||
|  | 	{ | |||
|  | 	} | |||
|  | 
 | |||
|  | 
 | |||
|  | 	//! if true, then its children must get transforms.
 | |||
|  | 	virtual bool childrenHasTransform() const | |||
|  | 	{ | |||
|  | 		if(m_childTransforms.size()==0) return false; | |||
|  | 		return true; | |||
|  | 	} | |||
|  | 
 | |||
|  | 
 | |||
|  | 	//! Obtains the primitive manager
 | |||
|  | 	virtual const btPrimitiveManagerBase * getPrimitiveManager()  const | |||
|  | 	{ | |||
|  | 		return &m_primitive_manager; | |||
|  | 	} | |||
|  | 
 | |||
|  | 	//! Obtains the compopund primitive manager
 | |||
|  | 	SIMD_FORCE_INLINE CompoundPrimitiveManager * getCompoundPrimitiveManager() | |||
|  | 	{ | |||
|  | 		return &m_primitive_manager; | |||
|  | 	} | |||
|  | 
 | |||
|  | 	//! Gets the number of children
 | |||
|  | 	virtual int	getNumChildShapes() const | |||
|  | 	{ | |||
|  | 		return m_childShapes.size(); | |||
|  | 	} | |||
|  | 
 | |||
|  | 
 | |||
|  | 	//! Use this method for adding children. Only Convex shapes are allowed.
 | |||
|  | 	void addChildShape(const btTransform& localTransform,btCollisionShape* shape) | |||
|  | 	{ | |||
|  | 		btAssert(shape->isConvex()); | |||
|  | 		m_childTransforms.push_back(localTransform); | |||
|  | 		m_childShapes.push_back(shape); | |||
|  | 	} | |||
|  | 
 | |||
|  | 	//! Use this method for adding children. Only Convex shapes are allowed.
 | |||
|  | 	void addChildShape(btCollisionShape* shape) | |||
|  | 	{ | |||
|  | 		btAssert(shape->isConvex()); | |||
|  | 		m_childShapes.push_back(shape); | |||
|  | 	} | |||
|  | 
 | |||
|  | 	//! Gets the children
 | |||
|  | 	virtual btCollisionShape* getChildShape(int index) | |||
|  | 	{ | |||
|  | 		return m_childShapes[index]; | |||
|  | 	} | |||
|  | 
 | |||
|  | 	//! Gets the children
 | |||
|  | 	virtual const btCollisionShape* getChildShape(int index) const | |||
|  | 	{ | |||
|  | 		return m_childShapes[index]; | |||
|  | 	} | |||
|  | 
 | |||
|  | 	//! Retrieves the bound from a child
 | |||
|  |     /*!
 | |||
|  |     */ | |||
|  |     virtual void getChildAabb(int child_index,const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const | |||
|  |     { | |||
|  | 
 | |||
|  |     	if(childrenHasTransform()) | |||
|  |     	{ | |||
|  |     		m_childShapes[child_index]->getAabb(t*m_childTransforms[child_index],aabbMin,aabbMax); | |||
|  |     	} | |||
|  |     	else | |||
|  |     	{ | |||
|  |     		m_childShapes[child_index]->getAabb(t,aabbMin,aabbMax); | |||
|  |     	} | |||
|  |     } | |||
|  | 
 | |||
|  | 
 | |||
|  | 	//! Gets the children transform
 | |||
|  | 	virtual btTransform	getChildTransform(int index) const | |||
|  | 	{ | |||
|  | 		btAssert(m_childTransforms.size() == m_childShapes.size()); | |||
|  | 		return m_childTransforms[index]; | |||
|  | 	} | |||
|  | 
 | |||
|  | 	//! Sets the children transform
 | |||
|  | 	/*!
 | |||
|  | 	\post You must call updateBound() for update the box set. | |||
|  | 	*/ | |||
|  | 	virtual void setChildTransform(int index, const btTransform & transform) | |||
|  | 	{ | |||
|  | 		btAssert(m_childTransforms.size() == m_childShapes.size()); | |||
|  | 		m_childTransforms[index] = transform; | |||
|  | 		postUpdate(); | |||
|  | 	} | |||
|  | 
 | |||
|  | 	//! Determines if this shape has triangles
 | |||
|  | 	virtual bool needsRetrieveTriangles() const | |||
|  | 	{ | |||
|  | 		return false; | |||
|  | 	} | |||
|  | 
 | |||
|  | 	//! Determines if this shape has tetrahedrons
 | |||
|  | 	virtual bool needsRetrieveTetrahedrons() const | |||
|  | 	{ | |||
|  | 		return false; | |||
|  | 	} | |||
|  | 
 | |||
|  | 
 | |||
|  | 	virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const | |||
|  | 	{ | |||
|  |         (void) prim_index; (void) triangle; | |||
|  | 		btAssert(0); | |||
|  | 	} | |||
|  | 
 | |||
|  | 	virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const | |||
|  | 	{ | |||
|  |         (void) prim_index; (void) tetrahedron; | |||
|  | 		btAssert(0); | |||
|  | 	} | |||
|  | 
 | |||
|  | 
 | |||
|  | 	//! Calculates the exact inertia tensor for this shape
 | |||
|  | 	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const; | |||
|  | 
 | |||
|  | 	virtual const char*	getName()const | |||
|  | 	{ | |||
|  | 		return "GImpactCompound"; | |||
|  | 	} | |||
|  | 
 | |||
|  | 	virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const | |||
|  | 	{ | |||
|  | 		return CONST_GIMPACT_COMPOUND_SHAPE; | |||
|  | 	} | |||
|  | 
 | |||
|  | }; | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | //! This class manages a sub part of a mesh supplied by the btStridingMeshInterface interface.
 | |||
|  | /*!
 | |||
|  | - Simply create this shape by passing the btStridingMeshInterface to the constructor btGImpactMeshShapePart, then you must call updateBound() after creating the mesh | |||
|  | - When making operations with this shape, you must call <b>lock</b> before accessing to the trimesh primitives, and then call <b>unlock</b> | |||
|  | - You can handle deformable meshes with this shape, by calling postUpdate() every time when changing the mesh vertices. | |||
|  | 
 | |||
|  | */ | |||
|  | class btGImpactMeshShapePart : public btGImpactShapeInterface | |||
|  | { | |||
|  | public: | |||
|  | 	//! Trimesh primitive manager
 | |||
|  | 	/*!
 | |||
|  | 	Manages the info from btStridingMeshInterface object and controls the Lock/Unlock mechanism | |||
|  | 	*/ | |||
|  | 	class TrimeshPrimitiveManager:public btPrimitiveManagerBase | |||
|  | 	{ | |||
|  | 	public: | |||
|  | 		btScalar m_margin; | |||
|  | 		btStridingMeshInterface * m_meshInterface; | |||
|  | 		btVector3 m_scale; | |||
|  | 		int m_part; | |||
|  | 		int m_lock_count; | |||
|  | 		const unsigned char *vertexbase; | |||
|  | 		int numverts; | |||
|  | 		PHY_ScalarType type; | |||
|  | 		int stride; | |||
|  | 		const unsigned char *indexbase; | |||
|  | 		int indexstride; | |||
|  | 		int  numfaces; | |||
|  | 		PHY_ScalarType indicestype; | |||
|  | 
 | |||
|  | 		TrimeshPrimitiveManager() | |||
|  | 		{ | |||
|  | 			m_meshInterface = NULL; | |||
|  | 			m_part = 0; | |||
|  | 			m_margin = 0.01f; | |||
|  | 			m_scale = btVector3(1.f,1.f,1.f); | |||
|  | 			m_lock_count = 0; | |||
|  | 			vertexbase = 0; | |||
|  | 			numverts = 0; | |||
|  | 			stride = 0; | |||
|  | 			indexbase = 0; | |||
|  | 			indexstride = 0; | |||
|  | 			numfaces = 0; | |||
|  | 		} | |||
|  | 
 | |||
|  |  		TrimeshPrimitiveManager(const TrimeshPrimitiveManager & manager) | |||
|  |             : btPrimitiveManagerBase() | |||
|  | 		{ | |||
|  | 			m_meshInterface = manager.m_meshInterface; | |||
|  | 			m_part = manager.m_part; | |||
|  | 			m_margin = manager.m_margin; | |||
|  | 			m_scale = manager.m_scale; | |||
|  | 			m_lock_count = 0; | |||
|  | 			vertexbase = 0; | |||
|  | 			numverts = 0; | |||
|  | 			stride = 0; | |||
|  | 			indexbase = 0; | |||
|  | 			indexstride = 0; | |||
|  | 			numfaces = 0; | |||
|  | 
 | |||
|  | 		} | |||
|  | 
 | |||
|  | 		TrimeshPrimitiveManager( | |||
|  | 			btStridingMeshInterface * meshInterface,	int part) | |||
|  | 		{ | |||
|  | 			m_meshInterface = meshInterface; | |||
|  | 			m_part = part; | |||
|  | 			m_scale = m_meshInterface->getScaling(); | |||
|  | 			m_margin = 0.1f; | |||
|  | 			m_lock_count = 0; | |||
|  | 			vertexbase = 0; | |||
|  | 			numverts = 0; | |||
|  | 			stride = 0; | |||
|  | 			indexbase = 0; | |||
|  | 			indexstride = 0; | |||
|  | 			numfaces = 0; | |||
|  | 
 | |||
|  | 		} | |||
|  | 
 | |||
|  | 		virtual ~TrimeshPrimitiveManager() {} | |||
|  | 
 | |||
|  | 		void lock() | |||
|  | 		{ | |||
|  | 			if(m_lock_count>0) | |||
|  | 			{ | |||
|  | 				m_lock_count++; | |||
|  | 				return; | |||
|  | 			} | |||
|  | 			m_meshInterface->getLockedReadOnlyVertexIndexBase( | |||
|  | 				&vertexbase,numverts, | |||
|  | 				type, stride,&indexbase, indexstride, numfaces,indicestype,m_part); | |||
|  | 
 | |||
|  | 			m_lock_count = 1; | |||
|  | 		} | |||
|  | 
 | |||
|  | 		void unlock() | |||
|  | 		{ | |||
|  | 			if(m_lock_count == 0) return; | |||
|  | 			if(m_lock_count>1) | |||
|  | 			{ | |||
|  | 				--m_lock_count; | |||
|  | 				return; | |||
|  | 			} | |||
|  | 			m_meshInterface->unLockReadOnlyVertexBase(m_part); | |||
|  | 			vertexbase = NULL; | |||
|  | 			m_lock_count = 0; | |||
|  | 		} | |||
|  | 
 | |||
|  | 		virtual bool is_trimesh() const | |||
|  | 		{ | |||
|  | 			return true; | |||
|  | 		} | |||
|  | 
 | |||
|  | 		virtual int get_primitive_count() const | |||
|  | 		{ | |||
|  | 			return (int )numfaces; | |||
|  | 		} | |||
|  | 
 | |||
|  | 		SIMD_FORCE_INLINE int get_vertex_count() const | |||
|  | 		{ | |||
|  | 			return (int )numverts; | |||
|  | 		} | |||
|  | 
 | |||
|  | 		SIMD_FORCE_INLINE void get_indices(int face_index,unsigned int &i0,unsigned int &i1,unsigned int &i2) const | |||
|  | 		{ | |||
|  | 			if(indicestype == PHY_SHORT) | |||
|  | 			{ | |||
|  | 				unsigned short* s_indices = (unsigned short *)(indexbase + face_index * indexstride); | |||
|  | 				i0 = s_indices[0]; | |||
|  | 				i1 = s_indices[1]; | |||
|  | 				i2 = s_indices[2]; | |||
|  | 			} | |||
|  | 			else | |||
|  | 			{ | |||
|  | 				unsigned int * i_indices = (unsigned int *)(indexbase + face_index*indexstride); | |||
|  | 				i0 = i_indices[0]; | |||
|  | 				i1 = i_indices[1]; | |||
|  | 				i2 = i_indices[2]; | |||
|  | 			} | |||
|  | 		} | |||
|  | 
 | |||
|  | 		SIMD_FORCE_INLINE void get_vertex(unsigned int vertex_index, btVector3 & vertex) const | |||
|  | 		{ | |||
|  | 			if(type == PHY_DOUBLE) | |||
|  | 			{ | |||
|  | 				double * dvertices = (double *)(vertexbase + vertex_index*stride); | |||
|  | 				vertex[0] = btScalar(dvertices[0]*m_scale[0]); | |||
|  | 				vertex[1] = btScalar(dvertices[1]*m_scale[1]); | |||
|  | 				vertex[2] = btScalar(dvertices[2]*m_scale[2]); | |||
|  | 			} | |||
|  | 			else | |||
|  | 			{ | |||
|  | 				float * svertices = (float *)(vertexbase + vertex_index*stride); | |||
|  | 				vertex[0] = svertices[0]*m_scale[0]; | |||
|  | 				vertex[1] = svertices[1]*m_scale[1]; | |||
|  | 				vertex[2] = svertices[2]*m_scale[2]; | |||
|  | 			} | |||
|  | 		} | |||
|  | 
 | |||
|  | 		virtual void get_primitive_box(int prim_index ,btAABB & primbox) const | |||
|  | 		{ | |||
|  | 			btPrimitiveTriangle  triangle; | |||
|  | 			get_primitive_triangle(prim_index,triangle); | |||
|  | 			primbox.calc_from_triangle_margin( | |||
|  | 				triangle.m_vertices[0], | |||
|  | 				triangle.m_vertices[1],triangle.m_vertices[2],triangle.m_margin); | |||
|  | 		} | |||
|  | 
 | |||
|  | 		virtual void get_primitive_triangle(int prim_index,btPrimitiveTriangle & triangle) const | |||
|  | 		{ | |||
|  | 			unsigned int indices[3]; | |||
|  | 			get_indices(prim_index,indices[0],indices[1],indices[2]); | |||
|  | 			get_vertex(indices[0],triangle.m_vertices[0]); | |||
|  | 			get_vertex(indices[1],triangle.m_vertices[1]); | |||
|  | 			get_vertex(indices[2],triangle.m_vertices[2]); | |||
|  | 			triangle.m_margin = m_margin; | |||
|  | 		} | |||
|  | 
 | |||
|  | 		SIMD_FORCE_INLINE void get_bullet_triangle(int prim_index,btTriangleShapeEx & triangle) const | |||
|  | 		{ | |||
|  | 			unsigned int indices[3]; | |||
|  | 			get_indices(prim_index,indices[0],indices[1],indices[2]); | |||
|  | 			get_vertex(indices[0],triangle.m_vertices1[0]); | |||
|  | 			get_vertex(indices[1],triangle.m_vertices1[1]); | |||
|  | 			get_vertex(indices[2],triangle.m_vertices1[2]); | |||
|  | 			triangle.setMargin(m_margin); | |||
|  | 		} | |||
|  | 
 | |||
|  | 	}; | |||
|  | 
 | |||
|  | 
 | |||
|  | protected: | |||
|  | 	TrimeshPrimitiveManager m_primitive_manager; | |||
|  | public: | |||
|  | 
 | |||
|  | 	btGImpactMeshShapePart() | |||
|  | 	{ | |||
|  | 		m_box_set.setPrimitiveManager(&m_primitive_manager); | |||
|  | 	} | |||
|  | 
 | |||
|  |     btGImpactMeshShapePart( btStridingMeshInterface * meshInterface, int part ); | |||
|  |     virtual ~btGImpactMeshShapePart(); | |||
|  | 
 | |||
|  | 	//! if true, then its children must get transforms.
 | |||
|  | 	virtual bool childrenHasTransform() const | |||
|  | 	{ | |||
|  | 		return false; | |||
|  | 	} | |||
|  | 
 | |||
|  | 
 | |||
|  | 	//! call when reading child shapes
 | |||
|  |     virtual void lockChildShapes() const; | |||
|  |     virtual void unlockChildShapes()  const; | |||
|  | 
 | |||
|  | 	//! Gets the number of children
 | |||
|  | 	virtual int	getNumChildShapes() const | |||
|  | 	{ | |||
|  | 		return m_primitive_manager.get_primitive_count(); | |||
|  | 	} | |||
|  | 
 | |||
|  | 
 | |||
|  | 	//! Gets the children
 | |||
|  | 	virtual btCollisionShape* getChildShape(int index) | |||
|  | 	{ | |||
|  |         (void) index; | |||
|  | 		btAssert(0); | |||
|  | 		return NULL; | |||
|  | 	} | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 	//! Gets the child
 | |||
|  | 	virtual const btCollisionShape* getChildShape(int index) const | |||
|  | 	{ | |||
|  |         (void) index; | |||
|  | 		btAssert(0); | |||
|  | 		return NULL; | |||
|  | 	} | |||
|  | 
 | |||
|  | 	//! Gets the children transform
 | |||
|  | 	virtual btTransform	getChildTransform(int index) const | |||
|  | 	{ | |||
|  |         (void) index; | |||
|  | 		btAssert(0); | |||
|  | 		return btTransform(); | |||
|  | 	} | |||
|  | 
 | |||
|  | 	//! Sets the children transform
 | |||
|  | 	/*!
 | |||
|  | 	\post You must call updateBound() for update the box set. | |||
|  | 	*/ | |||
|  | 	virtual void setChildTransform(int index, const btTransform & transform) | |||
|  | 	{ | |||
|  |         (void) index; | |||
|  |         (void) transform; | |||
|  | 		btAssert(0); | |||
|  | 	} | |||
|  | 
 | |||
|  | 
 | |||
|  | 	//! Obtains the primitive manager
 | |||
|  | 	virtual const btPrimitiveManagerBase * getPrimitiveManager()  const | |||
|  | 	{ | |||
|  | 		return &m_primitive_manager; | |||
|  | 	} | |||
|  | 
 | |||
|  | 	SIMD_FORCE_INLINE TrimeshPrimitiveManager * getTrimeshPrimitiveManager() | |||
|  | 	{ | |||
|  | 		return &m_primitive_manager; | |||
|  | 	} | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const; | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 	virtual const char*	getName()const | |||
|  | 	{ | |||
|  | 		return "GImpactMeshShapePart"; | |||
|  | 	} | |||
|  | 
 | |||
|  | 	virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const | |||
|  | 	{ | |||
|  | 		return CONST_GIMPACT_TRIMESH_SHAPE_PART; | |||
|  | 	} | |||
|  | 
 | |||
|  | 	//! Determines if this shape has triangles
 | |||
|  | 	virtual bool needsRetrieveTriangles() const | |||
|  | 	{ | |||
|  | 		return true; | |||
|  | 	} | |||
|  | 
 | |||
|  | 	//! Determines if this shape has tetrahedrons
 | |||
|  | 	virtual bool needsRetrieveTetrahedrons() const | |||
|  | 	{ | |||
|  | 		return false; | |||
|  | 	} | |||
|  | 
 | |||
|  | 	virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const | |||
|  | 	{ | |||
|  | 		m_primitive_manager.get_bullet_triangle(prim_index,triangle); | |||
|  | 	} | |||
|  | 
 | |||
|  | 	virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const | |||
|  | 	{ | |||
|  |         (void) prim_index; | |||
|  |         (void) tetrahedron; | |||
|  | 		btAssert(0); | |||
|  | 	} | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 	SIMD_FORCE_INLINE int getVertexCount() const | |||
|  | 	{ | |||
|  | 		return m_primitive_manager.get_vertex_count(); | |||
|  | 	} | |||
|  | 
 | |||
|  | 	SIMD_FORCE_INLINE void getVertex(int vertex_index, btVector3 & vertex) const | |||
|  | 	{ | |||
|  | 		m_primitive_manager.get_vertex(vertex_index,vertex); | |||
|  | 	} | |||
|  | 
 | |||
|  | 	SIMD_FORCE_INLINE void setMargin(btScalar margin) | |||
|  |     { | |||
|  |     	m_primitive_manager.m_margin = margin; | |||
|  |     	postUpdate(); | |||
|  |     } | |||
|  | 
 | |||
|  |     SIMD_FORCE_INLINE btScalar getMargin() const | |||
|  |     { | |||
|  |     	return m_primitive_manager.m_margin; | |||
|  |     } | |||
|  | 
 | |||
|  |     virtual void	setLocalScaling(const btVector3& scaling) | |||
|  |     { | |||
|  |     	m_primitive_manager.m_scale = scaling; | |||
|  |     	postUpdate(); | |||
|  |     } | |||
|  | 
 | |||
|  |     virtual const btVector3& getLocalScaling() const | |||
|  |     { | |||
|  |     	return m_primitive_manager.m_scale; | |||
|  |     } | |||
|  | 
 | |||
|  |     SIMD_FORCE_INLINE int getPart() const | |||
|  |     { | |||
|  |     	return (int)m_primitive_manager.m_part; | |||
|  |     } | |||
|  | 
 | |||
|  | 	virtual void	processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; | |||
|  | 	virtual void	processAllTrianglesRay(btTriangleCallback* callback,const btVector3& rayFrom,const btVector3& rayTo) const; | |||
|  | }; | |||
|  | 
 | |||
|  | 
 | |||
|  | //! This class manages a mesh supplied by the btStridingMeshInterface interface.
 | |||
|  | /*!
 | |||
|  | Set of btGImpactMeshShapePart parts | |||
|  | - Simply create this shape by passing the btStridingMeshInterface to the constructor btGImpactMeshShape, then you must call updateBound() after creating the mesh | |||
|  | 
 | |||
|  | - You can handle deformable meshes with this shape, by calling postUpdate() every time when changing the mesh vertices. | |||
|  | 
 | |||
|  | */ | |||
|  | class btGImpactMeshShape : public btGImpactShapeInterface | |||
|  | { | |||
|  | 	btStridingMeshInterface* m_meshInterface; | |||
|  | 
 | |||
|  | protected: | |||
|  | 	btAlignedObjectArray<btGImpactMeshShapePart*> m_mesh_parts; | |||
|  | 	void buildMeshParts(btStridingMeshInterface * meshInterface) | |||
|  | 	{ | |||
|  | 		for (int i=0;i<meshInterface->getNumSubParts() ;++i ) | |||
|  | 		{ | |||
|  | 			btGImpactMeshShapePart * newpart = new btGImpactMeshShapePart(meshInterface,i); | |||
|  | 			m_mesh_parts.push_back(newpart); | |||
|  | 		} | |||
|  | 	} | |||
|  | 
 | |||
|  | 	//! use this function for perfofm refit in bounding boxes
 | |||
|  |     virtual void calcLocalAABB() | |||
|  |     { | |||
|  |     	m_localAABB.invalidate(); | |||
|  |     	int i = m_mesh_parts.size(); | |||
|  |     	while(i--) | |||
|  |     	{ | |||
|  |     		m_mesh_parts[i]->updateBound(); | |||
|  |     		m_localAABB.merge(m_mesh_parts[i]->getLocalBox()); | |||
|  |     	} | |||
|  |     } | |||
|  | 
 | |||
|  | public: | |||
|  | 	btGImpactMeshShape(btStridingMeshInterface * meshInterface) | |||
|  | 	{ | |||
|  | 		m_meshInterface = meshInterface; | |||
|  | 		buildMeshParts(meshInterface); | |||
|  | 	} | |||
|  | 
 | |||
|  | 	virtual ~btGImpactMeshShape() | |||
|  | 	{ | |||
|  | 		int i = m_mesh_parts.size(); | |||
|  |     	while(i--) | |||
|  |     	{ | |||
|  | 			btGImpactMeshShapePart * part = m_mesh_parts[i]; | |||
|  | 			delete part; | |||
|  |     	} | |||
|  | 		m_mesh_parts.clear(); | |||
|  | 	} | |||
|  | 
 | |||
|  | 
 | |||
|  | 	btStridingMeshInterface* getMeshInterface() | |||
|  | 	{ | |||
|  | 		return m_meshInterface; | |||
|  | 	} | |||
|  | 
 | |||
|  | 	const btStridingMeshInterface* getMeshInterface() const | |||
|  | 	{ | |||
|  | 		return m_meshInterface; | |||
|  | 	} | |||
|  | 
 | |||
|  | 	int getMeshPartCount() const | |||
|  | 	{ | |||
|  | 		return m_mesh_parts.size(); | |||
|  | 	} | |||
|  | 
 | |||
|  | 	btGImpactMeshShapePart * getMeshPart(int index) | |||
|  | 	{ | |||
|  | 		return m_mesh_parts[index]; | |||
|  | 	} | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 	const btGImpactMeshShapePart * getMeshPart(int index) const | |||
|  | 	{ | |||
|  | 		return m_mesh_parts[index]; | |||
|  | 	} | |||
|  | 
 | |||
|  | 
 | |||
|  | 	virtual void	setLocalScaling(const btVector3& scaling) | |||
|  | 	{ | |||
|  | 		localScaling = scaling; | |||
|  | 
 | |||
|  | 		int i = m_mesh_parts.size(); | |||
|  |     	while(i--) | |||
|  |     	{ | |||
|  | 			btGImpactMeshShapePart * part = m_mesh_parts[i]; | |||
|  | 			part->setLocalScaling(scaling); | |||
|  |     	} | |||
|  | 
 | |||
|  | 		m_needs_update = true; | |||
|  | 	} | |||
|  | 
 | |||
|  | 	virtual void setMargin(btScalar margin) | |||
|  |     { | |||
|  |     	m_collisionMargin = margin; | |||
|  | 
 | |||
|  | 		int i = m_mesh_parts.size(); | |||
|  |     	while(i--) | |||
|  |     	{ | |||
|  | 			btGImpactMeshShapePart * part = m_mesh_parts[i]; | |||
|  | 			part->setMargin(margin); | |||
|  |     	} | |||
|  | 
 | |||
|  | 		m_needs_update = true; | |||
|  |     } | |||
|  | 
 | |||
|  | 	//! Tells to this object that is needed to refit all the meshes
 | |||
|  |     virtual void postUpdate() | |||
|  |     { | |||
|  | 		int i = m_mesh_parts.size(); | |||
|  |     	while(i--) | |||
|  |     	{ | |||
|  | 			btGImpactMeshShapePart * part = m_mesh_parts[i]; | |||
|  | 			part->postUpdate(); | |||
|  |     	} | |||
|  | 
 | |||
|  |     	m_needs_update = true; | |||
|  |     } | |||
|  | 
 | |||
|  | 	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const; | |||
|  | 
 | |||
|  | 
 | |||
|  | 	//! Obtains the primitive manager
 | |||
|  | 	virtual const btPrimitiveManagerBase * getPrimitiveManager()  const | |||
|  | 	{ | |||
|  | 		btAssert(0); | |||
|  | 		return NULL; | |||
|  | 	} | |||
|  | 
 | |||
|  | 
 | |||
|  | 	//! Gets the number of children
 | |||
|  | 	virtual int	getNumChildShapes() const | |||
|  | 	{ | |||
|  | 		btAssert(0); | |||
|  | 		return 0; | |||
|  | 	} | |||
|  | 
 | |||
|  | 
 | |||
|  | 	//! if true, then its children must get transforms.
 | |||
|  | 	virtual bool childrenHasTransform() const | |||
|  | 	{ | |||
|  | 		btAssert(0); | |||
|  | 		return false; | |||
|  | 	} | |||
|  | 
 | |||
|  | 	//! Determines if this shape has triangles
 | |||
|  | 	virtual bool needsRetrieveTriangles() const | |||
|  | 	{ | |||
|  | 		btAssert(0); | |||
|  | 		return false; | |||
|  | 	} | |||
|  | 
 | |||
|  | 	//! Determines if this shape has tetrahedrons
 | |||
|  | 	virtual bool needsRetrieveTetrahedrons() const | |||
|  | 	{ | |||
|  | 		btAssert(0); | |||
|  | 		return false; | |||
|  | 	} | |||
|  | 
 | |||
|  | 	virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const | |||
|  | 	{ | |||
|  |         (void) prim_index; (void) triangle; | |||
|  | 		btAssert(0); | |||
|  | 	} | |||
|  | 
 | |||
|  | 	virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const | |||
|  | 	{ | |||
|  |         (void) prim_index; (void) tetrahedron; | |||
|  | 		btAssert(0); | |||
|  | 	} | |||
|  | 
 | |||
|  | 	//! call when reading child shapes
 | |||
|  | 	virtual void lockChildShapes() const | |||
|  | 	{ | |||
|  | 		btAssert(0); | |||
|  | 	} | |||
|  | 
 | |||
|  | 	virtual void unlockChildShapes() const | |||
|  | 	{ | |||
|  | 		btAssert(0); | |||
|  | 	} | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 	//! Retrieves the bound from a child
 | |||
|  |     /*!
 | |||
|  |     */ | |||
|  |     virtual void getChildAabb(int child_index,const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const | |||
|  |     { | |||
|  |         (void) child_index; (void) t; (void) aabbMin; (void) aabbMax; | |||
|  |         btAssert(0); | |||
|  |     } | |||
|  | 
 | |||
|  | 	//! Gets the children
 | |||
|  | 	virtual btCollisionShape* getChildShape(int index) | |||
|  | 	{ | |||
|  |         (void) index; | |||
|  | 		btAssert(0); | |||
|  | 		return NULL; | |||
|  | 	} | |||
|  | 
 | |||
|  | 
 | |||
|  | 	//! Gets the child
 | |||
|  | 	virtual const btCollisionShape* getChildShape(int index) const | |||
|  | 	{ | |||
|  |         (void) index; | |||
|  | 		btAssert(0); | |||
|  | 		return NULL; | |||
|  | 	} | |||
|  | 
 | |||
|  | 	//! Gets the children transform
 | |||
|  | 	virtual btTransform	getChildTransform(int index) const | |||
|  | 	{ | |||
|  |         (void) index; | |||
|  | 		btAssert(0); | |||
|  | 		return btTransform(); | |||
|  | 	} | |||
|  | 
 | |||
|  | 	//! Sets the children transform
 | |||
|  | 	/*!
 | |||
|  | 	\post You must call updateBound() for update the box set. | |||
|  | 	*/ | |||
|  | 	virtual void setChildTransform(int index, const btTransform & transform) | |||
|  | 	{ | |||
|  |         (void) index; (void) transform; | |||
|  | 		btAssert(0); | |||
|  | 	} | |||
|  | 
 | |||
|  | 
 | |||
|  | 	virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const | |||
|  | 	{ | |||
|  | 		return CONST_GIMPACT_TRIMESH_SHAPE; | |||
|  | 	} | |||
|  | 
 | |||
|  | 
 | |||
|  | 	virtual const char*	getName()const | |||
|  | 	{ | |||
|  | 		return "GImpactMesh"; | |||
|  | 	} | |||
|  | 
 | |||
|  | 	virtual void rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback)  const; | |||
|  | 
 | |||
|  | 	//! Function for retrieve triangles.
 | |||
|  | 	/*!
 | |||
|  | 	It gives the triangles in local space | |||
|  | 	*/ | |||
|  | 	virtual void	processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; | |||
|  | 
 | |||
|  | 	virtual void	processAllTrianglesRay (btTriangleCallback* callback,const btVector3& rayFrom,const btVector3& rayTo) const; | |||
|  | 
 | |||
|  | 	virtual	int	calculateSerializeBufferSize() const; | |||
|  | 
 | |||
|  | 	///fills the dataBuffer and returns the struct name (and 0 on failure)
 | |||
|  | 	virtual	const char*	serialize(void* dataBuffer, btSerializer* serializer) const; | |||
|  | 
 | |||
|  | }; | |||
|  | 
 | |||
|  | ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
 | |||
|  | struct	btGImpactMeshShapeData | |||
|  | { | |||
|  | 	btCollisionShapeData	m_collisionShapeData; | |||
|  | 
 | |||
|  | 	btStridingMeshInterfaceData m_meshInterface; | |||
|  | 
 | |||
|  | 	btVector3FloatData	m_localScaling; | |||
|  | 
 | |||
|  | 	float	m_collisionMargin; | |||
|  | 
 | |||
|  | 	int		m_gimpactSubType; | |||
|  | }; | |||
|  | 
 | |||
|  | SIMD_FORCE_INLINE	int	btGImpactMeshShape::calculateSerializeBufferSize() const | |||
|  | { | |||
|  | 	return sizeof(btGImpactMeshShapeData); | |||
|  | } | |||
|  | 
 | |||
|  | 
 | |||
|  | #endif //GIMPACT_MESH_SHAPE_H
 |