summaryrefslogtreecommitdiff
path: root/thirdparty/bullet/BulletCollision/Gimpact/btGImpactShape.h
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/bullet/BulletCollision/Gimpact/btGImpactShape.h')
-rw-r--r--thirdparty/bullet/BulletCollision/Gimpact/btGImpactShape.h1164
1 files changed, 1164 insertions, 0 deletions
diff --git a/thirdparty/bullet/BulletCollision/Gimpact/btGImpactShape.h b/thirdparty/bullet/BulletCollision/Gimpact/btGImpactShape.h
new file mode 100644
index 0000000000..9d7e40562c
--- /dev/null
+++ b/thirdparty/bullet/BulletCollision/Gimpact/btGImpactShape.h
@@ -0,0 +1,1164 @@
+/*! \file btGImpactShape.h
+\author Francisco Len Nß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