What I am trying to do overall, is take mesh data from an already loaded Ogre mesh, and perform convex decomposition with that data. As a result I don't need or want anything to do with Wavefront object files, so I cut that part out, but the rest is pretty much copy pasta from the Convex Decomp Demo files.
Part of my Interface class:
Code: Select all
void PhysConvexDecomposition::ConvexDecompResult(ConvexDecomposition::ConvexResult &result)
{
btTriangleMesh* trimesh = new btTriangleMesh();
btVector3 localScaling(1.f,1.f,1.f);
//calc centroid, to shift vertices around center of mass
btVector3 centroid;
centroid.setValue(0,0,0);
btAlignedObjectArray<btVector3> vertices;
//const unsigned int *src = result.mHullIndices;
for (unsigned int i=0; i<result.mHullVcount; i++)
{
btVector3 vertex(result.mHullVertices[i*3],result.mHullVertices[i*3+1],result.mHullVertices[i*3+2]);
vertex *= localScaling;
centroid += vertex;
}
centroid *= 1.f/(float(result.mHullVcount) );
//const unsigned int *src = result.mHullIndices;
for (unsigned int i=0; i<result.mHullVcount; i++)
{
btVector3 vertex(result.mHullVertices[i*3],result.mHullVertices[i*3+1],result.mHullVertices[i*3+2]);
vertex *= localScaling;
vertex -= centroid ;
vertices.push_back(vertex);
}
const unsigned int *src = result.mHullIndices;
for (unsigned int i=0; i<result.mHullTcount; i++)
{
unsigned int index0 = *src++;
unsigned int index1 = *src++;
unsigned int index2 = *src++;
btVector3 vertex0(result.mHullVertices[index0*3], result.mHullVertices[index0*3+1],result.mHullVertices[index0*3+2]);
btVector3 vertex1(result.mHullVertices[index1*3], result.mHullVertices[index1*3+1],result.mHullVertices[index1*3+2]);
btVector3 vertex2(result.mHullVertices[index2*3], result.mHullVertices[index2*3+1],result.mHullVertices[index2*3+2]);
vertex0 *= localScaling;
vertex1 *= localScaling;
vertex2 *= localScaling;
vertex0 -= centroid;
vertex1 -= centroid;
vertex2 -= centroid;
trimesh->addTriangle(vertex0,vertex1,vertex2);
index0+=mBaseCount;
index1+=mBaseCount;
index2+=mBaseCount;
}
btConvexHullShape* convexShape = new btConvexHullShape(&(vertices[0].getX()),vertices.size());
convexShape->setMargin(0.01f);
m_convexShapes.push_back(convexShape);
m_convexCentroids.push_back(centroid);
mBaseCount+=result.mHullVcount; // advance the 'base index' counter.
}Code: Select all
void ActorRigid::PerformConvexDecomposition(unsigned int depth, float cpercent, float ppercent)
{
Ogre::MeshPtr myMesh = entity->getMesh();
Ogre::SubMesh* subMesh = myMesh->getSubMesh(0);
Ogre::IndexData* indexData = subMesh->indexData;
Ogre::VertexData* vertexData = subMesh->vertexData;
const Ogre::VertexElement* posElem = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
Ogre::HardwareVertexBufferSharedPtr vBuffer = vertexData->vertexBufferBinding->getBuffer(posElem->getSource());
Ogre::HardwareIndexBufferSharedPtr iBuffer = indexData->indexBuffer;
unsigned int triCount = indexData->indexCount/3;
Ogre::Real* vertices = new Ogre::Real[vertexData->vertexCount*3];
unsigned int* indices = new unsigned int[indexData->indexCount];
unsigned char* vertex = static_cast<unsigned char*>(vBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
int vcount=0;
float* pReal = NULL;
for (size_t j = 0; j < vertexData->vertexCount; j+=3, vertex += vBuffer->getVertexSize() )
{
posElem->baseVertexPointerToElement(vertex, &pReal);
vertices[j] = pReal[0];
vertices[j+1] = pReal[1];
vertices[j+2] = pReal[2];
vcount+=3;
}
vBuffer->unlock();
size_t index_offset = 0;
bool use32bitindexes = (iBuffer->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);
unsigned long* pLong = static_cast<unsigned long*>(iBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong);
if (use32bitindexes)
{
for (size_t k = 0; k < triCount*3; ++k)
{
indices[index_offset++] = pLong[k];
}
}
else
{
for (size_t k = 0; k < triCount*3; ++k)
{
indices[index_offset++] = static_cast<unsigned long>(pShort[k]);
}
}
iBuffer->unlock();
ConvexDecomposition::DecompDesc desc;
desc.mVcount = vcount;
desc.mTcount = triCount;
desc.mVertices = &vertices[0];
desc.mIndices = &indices[0];
unsigned int maxv = 16;
float skinWidth = 0.0;
desc.mDepth = depth;
desc.mCpercent = cpercent;
desc.mPpercent = ppercent;
desc.mMaxVertices = maxv;
desc.mSkinWidth = skinWidth;
internal::PhysConvexDecomposition decomp;
desc.mCallback = &decomp;
ConvexBuilder cb(desc.mCallback);
cb.process(desc);
btCompoundShape* compound = new btCompoundShape(false);
btTransform trans;
trans.setIdentity();
for (int i=0;i<decomp.m_convexShapes.size();i++)
{
btVector3 centroid = decomp.m_convexCentroids[i];
trans.setOrigin(centroid);
btConvexHullShape* convexShape = decomp.m_convexShapes[i];
compound->addChildShape(trans,convexShape);
}
Shape=compound;
this->physrigidbody->setCollisionShape(this->Shape);
delete[] vertices;
delete[] indices;
return;The problem right now is that in windows, this will cause an Assertion fail from line 502 of cd_hull.cpp . If I run it through with GDB (MinGW debugger) then it won't throw an assert at all, instead it'll not fill the mChulls vector and skip over most of the code in the process function, thus not actually perform any decomposition and not give the object any shape causing objects to fall through each other. In linux, the same code will cause a seg fault in btAxisSweep.h on line 1004, rather then either of the windows behaviors. This also only happens when we enable Convex decomp in our code. We have it creating regular convex hulls and gimpact shapes just fine.
If anyone can help, or post a code snippet to get me on the right track, I would greatly appreciate it.