Logo Search packages:      
Sourcecode: blender version File versions

btGImpactShape.h

Go to the documentation of this file.
/*! \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)
00044 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
00055 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
00078 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
00088     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();
      */
00122     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.
    */
00133     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
00142     virtual void postUpdate()
    {
      m_needs_update = true;
    }

      //! Obtains the local box, which is the global calculated box of the total of subshapes
00148       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.
      */
00162       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() = 0;

      //! gets boxset
00195       SIMD_FORCE_INLINE btGImpactBoxSet * getBoxSet()
      {
            return &m_box_set;
      }

      //! Determines if this class has a hierarchy structure for sorting its primitives
00201       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
00230       virtual void lockChildShapes() const
      {
      }

      virtual void unlockChildShapes() const
      {
      }

      //! if this trimesh
00239       SIMD_FORCE_INLINE void getPrimitiveTriangle(int index,btPrimitiveTriangle & triangle) const
      {
            getPrimitiveManager()->get_primitive_triangle(index,triangle);
      }


      //! Retrieves the bound from a child
    /*!
    */
00248     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
00277       virtual void rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback)  const
      {
      }

      //! Function for retrieve triangles.
      /*!
      It gives the triangles in local space
      */
00285       virtual void      processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
      {
      }

      //!@}

};


//! btGImpactCompoundShape allows to handle multiple btCollisionShape objects at once
/*!
This class only can manage Convex subshapes
*/
00298 class btGImpactCompoundShape  : public btGImpactShapeInterface
{
public:
      //! compound primitive manager
00302       class CompoundPrimitiveManager:public btPrimitiveManagerBase
      {
      public:
            btGImpactCompoundShape * m_compoundShape;


            CompoundPrimitiveManager(const CompoundPrimitiveManager& compound)
            {
                  m_compoundShape = compound.m_compoundShape;
            }

            CompoundPrimitiveManager(btGImpactCompoundShape * compoundShape)
            {
                  m_compoundShape = compoundShape;
            }

            CompoundPrimitiveManager()
            {
                  m_compoundShape = NULL;
            }

00323             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);
            }

00348             virtual void get_primitive_triangle(int prim_index,btPrimitiveTriangle & triangle) const
            {
                  btAssert(0);
            }

      };



protected:
      CompoundPrimitiveManager m_primitive_manager;
      btAlignedObjectArray<btTransform>         m_childTransforms;
      btAlignedObjectArray<btCollisionShape*>   m_childShapes;


public:

      btGImpactCompoundShape(bool children_has_transform = true)
      {
            m_primitive_manager.m_compoundShape = this;
            m_box_set.setPrimitiveManager(&m_primitive_manager);
      }

      virtual ~btGImpactCompoundShape()
      {
      }


      //! if true, then its children must get transforms.
00377       virtual bool childrenHasTransform() const
      {
            if(m_childTransforms.size()==0) return false;
            return true;
      }


      //! Obtains the primitive manager
00385       virtual const btPrimitiveManagerBase * getPrimitiveManager()  const
      {
            return &m_primitive_manager;
      }

      //! Obtains the compopund primitive manager
00391       SIMD_FORCE_INLINE CompoundPrimitiveManager * getCompoundPrimitiveManager()
      {
            return &m_primitive_manager;
      }

      //! Gets the number of children
00397       virtual int getNumChildShapes() const
      {
            return m_childShapes.size();
      }


      //! Use this method for adding children. Only Convex shapes are allowed.
00404       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.
00412       void addChildShape(btCollisionShape* shape)
      {
            btAssert(shape->isConvex());
            m_childShapes.push_back(shape);
      }

      //! Gets the children
00419       virtual btCollisionShape* getChildShape(int index)
      {
            return m_childShapes[index];
      }

      //! Gets the children
00425       virtual const btCollisionShape* getChildShape(int index) const
      {
            return m_childShapes[index];
      }

      //! Retrieves the bound from a child
    /*!
    */
00433     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
00448       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.
      */
00458       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
00466       virtual bool needsRetrieveTriangles() const
      {
            return false;
      }

      //! Determines if this shape has tetrahedrons
00472       virtual bool needsRetrieveTetrahedrons() const
      {
            return false;
      }


      virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const
      {
            btAssert(0);
      }

      virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const
      {
            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";
      }

00497       virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType()
      {
            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.

*/
00513 class btGImpactMeshShapePart : public btGImpactShapeInterface
{
public:
      //! Trimesh primitive manager
      /*!
      Manages the info from btStridingMeshInterface object and controls the Lock/Unlock mechanism
      */
00520       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)
            {
                  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;

            }


            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;
            }

00613             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,int &i0,int &i1,int &i2) const
            {
                  if(indicestype == PHY_SHORT)
                  {
                        short * s_indices = (short *)(indexbase + face_index*indexstride);
                        i0 = s_indices[0];
                        i1 = s_indices[1];
                        i2 = s_indices[2];
                  }
                  else
                  {
                        int * i_indices = (int *)(indexbase + face_index*indexstride);
                        i0 = i_indices[0];
                        i1 = i_indices[1];
                        i2 = i_indices[2];
                  }
            }

            SIMD_FORCE_INLINE void get_vertex(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);
            }

00673             virtual void get_primitive_triangle(int prim_index,btPrimitiveTriangle & triangle) const
            {
                  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
            {
                  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)
      {
            m_primitive_manager.m_meshInterface = meshInterface;
            m_primitive_manager.m_part = part;
            m_box_set.setPrimitiveManager(&m_primitive_manager);
      }

      virtual ~btGImpactMeshShapePart()
      {
      }

      //! if true, then its children must get transforms.
00718       virtual bool childrenHasTransform() const
      {
            return false;
      }


      //! call when reading child shapes
00725       virtual void lockChildShapes() const
      {
            void * dummy = (void*)(m_box_set.getPrimitiveManager());
            TrimeshPrimitiveManager * dummymanager = static_cast<TrimeshPrimitiveManager *>(dummy);
            dummymanager->lock();
      }

      virtual void unlockChildShapes()  const
      {
            void * dummy = (void*)(m_box_set.getPrimitiveManager());
            TrimeshPrimitiveManager * dummymanager = static_cast<TrimeshPrimitiveManager *>(dummy);
            dummymanager->unlock();
      }

      //! Gets the number of children
00740       virtual int getNumChildShapes() const
      {
            return m_primitive_manager.get_primitive_count();
      }


      //! Gets the children
00747       virtual btCollisionShape* getChildShape(int index)
      {
            btAssert(0);
            return NULL;
      }



      //! Gets the child
00756       virtual const btCollisionShape* getChildShape(int index) const
      {
            btAssert(0);
            return NULL;
      }

      //! Gets the children transform
00763       virtual btTransform     getChildTransform(int index) const
      {
            btAssert(0);
            return btTransform();
      }

      //! Sets the children transform
      /*!
      \post You must call updateBound() for update the box set.
      */
00773       virtual void setChildTransform(int index, const btTransform & transform)
      {
            btAssert(0);
      }


      //! Obtains the primitive manager
00780       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";
      }

00804       virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType()
      {
            return CONST_GIMPACT_TRIMESH_SHAPE_PART;
      }

      //! Determines if this shape has triangles
00810       virtual bool needsRetrieveTriangles() const
      {
            return true;
      }

      //! Determines if this shape has tetrahedrons
00816       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
      {
            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;
    }

00854     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;
};


//! 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.

*/
00882 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
00898     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];
      }


00956       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
00985     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
01001       virtual const btPrimitiveManagerBase * getPrimitiveManager()  const
      {
            btAssert(0);
            return NULL;
      }


      //! Gets the number of children
01009       virtual int getNumChildShapes() const
      {
            btAssert(0);
            return 0;
      }


      //! if true, then its children must get transforms.
01017       virtual bool childrenHasTransform() const
      {
            btAssert(0);
            return false;
      }

      //! Determines if this shape has triangles
01024       virtual bool needsRetrieveTriangles() const
      {
            btAssert(0);
            return false;
      }

      //! Determines if this shape has tetrahedrons
01031       virtual bool needsRetrieveTetrahedrons() const
      {
            btAssert(0);
            return false;
      }

      virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const
      {
            btAssert(0);
      }

      virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const
      {
            btAssert(0);
      }

      //! call when reading child shapes
01048       virtual void lockChildShapes() const
      {
            btAssert(0);
      }

      virtual void unlockChildShapes() const
      {
            btAssert(0);
      }




      //! Retrieves the bound from a child
    /*!
    */
01064     virtual void getChildAabb(int child_index,const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
    {
        btAssert(0);
    }

      //! Gets the children
01070       virtual btCollisionShape* getChildShape(int index)
      {
            btAssert(0);
            return NULL;
      }


      //! Gets the child
01078       virtual const btCollisionShape* getChildShape(int index) const
      {
            btAssert(0);
            return NULL;
      }

      //! Gets the children transform
01085       virtual btTransform     getChildTransform(int index) const
      {
            btAssert(0);
            return btTransform();
      }

      //! Sets the children transform
      /*!
      \post You must call updateBound() for update the box set.
      */
01095       virtual void setChildTransform(int index, const btTransform & transform)
      {
            btAssert(0);
      }


01101       virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType()
      {
            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;
};


#endif //GIMPACT_MESH_SHAPE_H

Generated by  Doxygen 1.6.0   Back to index