BulletMeshStrider         A subclass of btStridingMeshInterface which allows one to share the same geometry between both graphics and collision meshes
Print

Table of contents

Mesh Strider for Bullet(external link) physics engine

This is subclass of btStridingMeshInterface(external link), which allows one to share the same geometry between both graphics and collision meshes

MeshStrider.h

#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

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

Contributors to this page: jacmoe133512 points  and Spacegaier4386 points  .
Page last modified on Saturday 02 of January, 2010 22:04:42 UTC by jacmoe133512 points .


The content on this page is licensed under the terms of the Creative Commons Attribution-ShareAlike License.
As an exception, any source code contributed within the content is released into the Public Domain.