Table of contents
Mesh Strider for Bullet physics engine
This is subclass of btStridingMeshInterface, which allows one to share the same geometry between both graphics and collision meshes
MeshStrider.h
Copy to clipboard
#ifndef MeshStrider_h__ #define MeshStrider_h__ #include "..\common.h" /// Shares vertices/indexes between Ogre and Bullet class MeshStrider : public btStridingMeshInterface{ public: MeshStrider( Ogre::Mesh * m = 0 ):mMesh(m){} void set( Ogre::Mesh * m ) { ASSERT(m); mMesh = m; } // inherited interface virtual int getNumSubParts() const; virtual void getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0); virtual void getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0) const; virtual void unLockVertexBase(int subpart); virtual void unLockReadOnlyVertexBase(int subpart) const; virtual void preallocateVertices(int numverts); virtual void preallocateIndices(int numindices); private: Ogre::Mesh * mMesh; }; #endif // MeshStrider_h__
MeshStrider.cpp
Copy to clipboard
#include "common.h" #include "MeshStrider.h" int MeshStrider::getNumSubParts() const { int ret = mMesh->getNumSubMeshes(); ASSERT( ret > 0 ); return ret; } void MeshStrider::getLockedReadOnlyVertexIndexBase( const unsigned char **vertexbase, int& numverts, PHY_ScalarType& type, int& stride, const unsigned char **indexbase, int & indexstride, int& numfaces, PHY_ScalarType& indicestype, int subpart/*=0*/ ) const { Ogre::SubMesh* submesh = mMesh->getSubMesh(subpart); Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mMesh->sharedVertexData : submesh->vertexData; const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource()); *vertexbase = reinterpret_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); // There is _no_ baseVertexPointerToElement() which takes an Ogre::Real or a double // as second argument. So make it float, to avoid trouble when Ogre::Real will // be comiled/typedefed as double: //Ogre::Real* pReal; float* pReal; posElem->baseVertexPointerToElement((void*) *vertexbase, &pReal); *vertexbase = (unsigned char*) pReal; stride = (int) vbuf->getVertexSize(); numverts = (int) vertex_data->vertexCount; ASSERT( numverts ); type = PHY_FLOAT; Ogre::IndexData* index_data = submesh->indexData; Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer; if (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT){ indicestype = PHY_INTEGER; } else{ ASSERT(ibuf->getType() == Ogre::HardwareIndexBuffer::IT_16BIT); indicestype = PHY_SHORT; } if ( submesh->operationType == Ogre::RenderOperation::OT_TRIANGLE_LIST ){ numfaces = (int) index_data->indexCount / 3; indexstride = (int) ibuf->getIndexSize()*3; } else if ( submesh->operationType == Ogre::RenderOperation::OT_TRIANGLE_STRIP ){ numfaces = (int) index_data->indexCount -2; indexstride = (int) ibuf->getIndexSize(); } else{ ASSERT( 0 ); // not supported } *indexbase = reinterpret_cast<unsigned char*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); } void MeshStrider::getLockedVertexIndexBase( unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart/*=0*/ ) { ASSERT( 0 ); } void MeshStrider::unLockReadOnlyVertexBase( int subpart ) const { Ogre::SubMesh* submesh = mMesh->getSubMesh(subpart); Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mMesh->sharedVertexData : submesh->vertexData; const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource()); vbuf->unlock(); Ogre::IndexData* index_data = submesh->indexData; Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer; ibuf->unlock(); } void MeshStrider::unLockVertexBase( int subpart ) { ASSERT( 0 ); } void MeshStrider::preallocateVertices( int numverts ) { ASSERT( 0 ); } void MeshStrider::preallocateIndices( int numindices ) { ASSERT( 0 ); }