Hi all,

I'd just thought I'd post this here, so that anyone could find it easily (until it's added into contrib or wherever suitable).

It's an implementation of Bullet's (the physics engine) btStridingMeshInterface that allows one to use OSG::Geometry:s as source data for collision meshes.

It places some restrictions on the OSG::Geometry (only triangles and triangle strips and only floats) but it works well for VRML-loaded meshes so I hope it'll be useful.

Enjoy. :)

Cheers,
/Marcus
// simple implementation of runtime asserts 
#define ORZ_RUNTIME_ASSERT(e) if(e) throw std::runtime_error(#e);
#define ORZ_THROW_ASSERT(e) throw std::runtime_error(#e);

/** Exposes an OpenSG Geometry to the Bullet btStridingMeshInterface

    Asserts if not Pnt3f for vertices and GLuint/GLushort for indices. 
    Bullet only supports triangles or tri-strips, so only those are allowed as 
well.
*/
class OpenSGStridingMeshInterface : public btStridingMeshInterface
{
public:
    static bool s_writeInfo;

    OpenSGStridingMeshInterface(OSG::Geometry* geo);

    virtual void getLockedVertexIndexBase(unsigned char **vertexbase, int& 
numverts,
        PHY_ScalarType& type, int& vertexStride, unsigned char **indexbase, int 
& indexstride,
        int& numfaces, PHY_ScalarType& indicestype, int subpart = 0);

    virtual void getLockedReadOnlyVertexIndexBase(const unsigned char 
**vertex_base, 
        int& vertex_count, PHY_ScalarType& vertex_type, int& vertex_stride, 
const unsigned char **index_base,
        int& index_stride, int& triangle_count, PHY_ScalarType& index_type, int 
subpart = 0) const;

    virtual void unLockVertexBase(int subpart);
    virtual void unLockReadOnlyVertexBase(int subpart) const;
    virtual int  getNumSubParts() const;
    virtual void preallocateVertices(int numverts);
    virtual void preallocateIndices(int numindices);

private:
    OSG::GeometryRefPtr m_geo;
};

OpenSGStridingMeshInterface::OpenSGStridingMeshInterface(OSG::Geometry* geo) : 
m_geo(geo)
{  
    // check geo formats and data validity
    ORZ_RUNTIME_ASSERT(m_geo->getTypes()->size() == 
m_geo->getLengths()->size());
    ORZ_RUNTIME_ASSERT(m_geo->getPositions()->getFormat() == GL_FLOAT);
    ORZ_RUNTIME_ASSERT(m_geo->getPositions()->getDimension() == 3);
    GLenum format = m_geo->getIndices()->getFormat();
    ORZ_RUNTIME_ASSERT(format == GL_UNSIGNED_SHORT || format == 
GL_UNSIGNED_INT);

    if (s_writeInfo) {
        std::cout << m_geo << " " << m_geo->getLengths()->size() << " subparts" 
<< std::endl;
    }
}

void OpenSGStridingMeshInterface::getLockedVertexIndexBase(unsigned char 
**vertexbase, int& numverts,
    PHY_ScalarType& type, int& vertexStride, unsigned char **indexbase, int & 
indexstride,
    int& numfaces, PHY_ScalarType& indicestype, int subpart)
{
    ORZ_THROW_ASSERT("No writing of OpenSG data allowed");
}

void OpenSGStridingMeshInterface::getLockedReadOnlyVertexIndexBase(const 
unsigned char **vertex_base, 
    int& vertex_count, PHY_ScalarType& vertex_type, int& vertex_stride, const 
unsigned char **index_base,
    int& index_stride, int& triangle_count, PHY_ScalarType& index_type, int 
subpart) const
{
    // setup vertices and assert format
    *vertex_base = reinterpret_cast<const unsigned char 
*>(m_geo->getPositions()->getData());
    vertex_count = m_geo->getPositions()->size();
    vertex_type = PHY_FLOAT;
    vertex_stride = sizeof(GLfloat) * 3;

    // setup indices and assert format
    GLenum index_format = m_geo->getIndices()->getFormat();
    index_type = index_format == GL_UNSIGNED_SHORT ? PHY_SHORT : PHY_INTEGER;   
         
    size_t index_size = index_format == GL_UNSIGNED_SHORT ? sizeof(GLushort) : 
sizeof(GLuint);
    *index_base = reinterpret_cast<const unsigned char 
*>(m_geo->getIndices()->getData());

    // adjust indexbase to current part 
    for (int i = 0; i < subpart; ++i) {
        // using std::accumulate would've been nice, but we don't have enough 
type info here
        *index_base += m_geo->getLengths()->getValue(i) * index_size;
    }

    GLenum triangle_type = m_geo->getTypes()->getValue(subpart);
    ORZ_RUNTIME_ASSERT(triangle_type == GL_TRIANGLES || triangle_type == 
GL_TRIANGLE_STRIP);

    // compute # of triangles
    if (triangle_type == GL_TRIANGLE_STRIP) {
        triangle_count = m_geo->getLengths()->getValue(subpart) -  2;
    } else {
        triangle_count = m_geo->getLengths()->getValue(subpart) / 3;
    }

    // set stride
    index_stride = (triangle_type == GL_TRIANGLE_STRIP ? 1 : 3) * index_size;

    // write mesh part info
    if (s_writeInfo) {
        std::cout << m_geo << " # " << subpart << ": " <<
            triangle_count << " " << (triangle_type == GL_TRIANGLE_STRIP ? 
"striped " : "discrete") <<
            " triangles from " << m_geo->getLengths()->getValue(subpart) << " 
indices" << std::endl;
    }
}

void OpenSGStridingMeshInterface::unLockVertexBase(int subpart) { /* no locking 
*/  }
void OpenSGStridingMeshInterface::unLockReadOnlyVertexBase(int subpart) const { 
/* no locking */ }
int  OpenSGStridingMeshInterface::getNumSubParts() const { return 
m_geo->getLengths()->size(); }
void OpenSGStridingMeshInterface::preallocateVertices(int numverts) { /* no 
prealloc */ }
void OpenSGStridingMeshInterface::preallocateIndices(int numindices) { /* no 
prealloc */ }

bool OpenSGStridingMeshInterface::s_writeInfo = false;
------------------------------------------------------------------------------
Throughout its 18-year history, RSA Conference consistently attracts the
world's best and brightest in the field, creating opportunities for Conference
attendees to learn about information security's most important issues through
interactions with peers, luminaries and emerging and established companies.
http://p.sf.net/sfu/rsaconf-dev2dev
_______________________________________________
Opensg-users mailing list
Opensg-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensg-users

Reply via email to