History: BulletMeshStrider
Source of version: 3 (current)
Copy to clipboard
{maketoc}
!Mesh Strider for [http://www.bulletphysics.com/|Bullet] physics engine
This is subclass of [http://www.continuousphysics.com/Bullet/BulletFull/classbtStridingMeshInterface.html|btStridingMeshInterface], which allows one to share the same geometry between both graphics and collision meshes
!!MeshStrider.h
{CODE(wrap="1", colors="c++")}#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__{CODE}
!!MeshStrider.cpp
{CODE(wrap="1", colors="c++")}#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 );
}
{CODE}