Creating physX convex from ogre mesh 1.7?

icaromotta

11-03-2010 15:28:01

Hi

I was using this code to create a convex meshes. But as the ogre mesh of 1.7 is updated, the code is no longer working.

Worked perfectly with ogre mesh 1.4 .What has changed in that ogre mesh 1.7? Could anyone help me figure out what I should change to work with the current mesh?


void Physics::generateConvexMesh(Entity* pEntity, NxConvexShapeDesc* pOutDesc, NxVec3 vScale, std::string name)
{

Ogre::String sMeshName = pEntity->getOgreEntity()->getMesh()->getName();


pOutDesc->setToDefault();

unsigned int mVertexCount = 0;
unsigned int mIndexCount = 0;
size_t vertex_count;
Ogre::Vector3* vertices;
size_t index_count;
unsigned long* indices;

bool added_shared = false;
bool hasWarning = false;
vertex_count = 0;
index_count = 0;
size_t current_offset = 0;
size_t shared_offset = 0;
size_t next_offset = 0;
size_t index_offset = 0;

const Ogre::MeshPtr mesh = pEntity->getOgreEntity()->getMesh();

Ogre::ushort j = mesh->getNumSubMeshes();
for ( unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
{
Ogre::SubMesh* submesh = mesh->getSubMesh( i );

if(submesh->useSharedVertices)
{
if( !added_shared )
{
mVertexCount += (Ogre::uint)mesh->sharedVertexData->vertexCount;
added_shared = true;
}
}
else
{
mVertexCount += (Ogre::uint)submesh->vertexData->vertexCount;
}

mIndexCount += (Ogre::uint)submesh->indexData->indexCount;
}


vertices = new Ogre::Vector3[mVertexCount];
indices = new unsigned long[mIndexCount];

NxVec3* mMeshVertices = new NxVec3[mVertexCount];
NxU32* mMeshFaces = new NxU32[mIndexCount];
NxMaterialIndex* mMaterials = new NxMaterialIndex[mIndexCount];

NxMaterialIndex currentMaterialIndex = 0;
added_shared = false;

for ( unsigned short i = 0; i < mesh->getNumSubMeshes();i++)
{


Ogre::SubMesh* submesh = mesh->getSubMesh(i);
Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;


// Material Aliases..

//currentMaterialIndex = _scene->findMaterialIndex(submesh->getMaterialName());

if((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared))
{
if(submesh->useSharedVertices)
{
added_shared = true;
shared_offset = current_offset;
}

const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));

Ogre::Real* pReal;

for( size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize()) {
posElem->baseVertexPointerToElement(vertex, &pReal);
mMeshVertices[current_offset + j] = NxVec3(pReal[0] * vScale.x ,pReal[1] * vScale.y, pReal[2] * vScale.z);
}

vbuf->unlock();
next_offset += vertex_data->vertexCount;
}

Ogre::IndexData* index_data = submesh->indexData;

size_t numTris = index_data->indexCount / 3;
Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer;

bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);


if ( use32bitindexes ) {

unsigned int* pInt = static_cast<unsigned int*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));

size_t offset = (submesh->useSharedVertices)? shared_offset : current_offset;


for ( size_t k = 0; k < numTris*3; ++k) {
mMeshFaces[index_offset] = pInt[k] + static_cast<unsigned int>(offset);
mMaterials[index_offset++] = currentMaterialIndex;
}
}
else {
unsigned short* pShort = reinterpret_cast<unsigned short*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
size_t offset = (submesh->useSharedVertices)? shared_offset : current_offset;

for ( size_t k = 0; k < numTris*3; ++k) {
mMeshFaces[index_offset] = static_cast<unsigned int>(pShort[k]) + static_cast<unsigned int>(offset);
mMaterials[index_offset++] = currentMaterialIndex;

}

}

ibuf->unlock();
current_offset = next_offset;
}


NxConvexMeshDesc mTriangleMeshDescription;
mTriangleMeshDescription.numVertices = mVertexCount;
mTriangleMeshDescription.numTriangles = mIndexCount / 3;
mTriangleMeshDescription.pointStrideBytes = sizeof(NxVec3);
mTriangleMeshDescription.triangleStrideBytes = 3 * sizeof(NxU32);
Ogre::LogManager::getSingleton().logMessage("5");
//if (smooth)
mTriangleMeshDescription.points = mMeshVertices;
//else
// mTriangleMeshDescription.points = mMeshVertices_Smoothed;
mTriangleMeshDescription.triangles = mMeshFaces;
mTriangleMeshDescription.flags = NX_MF_HARDWARE_MESH;





MemoryWriteBuffer buf;


if(1)
{
Ogre::String fn;


if (1) {
fn = name; //mesh->getName();
/* if (Ogre::StringUtil::endsWith(fn, ".mesh")) {
fn = fn.substr(0, fn.length() - 5) + ".nxs";
}
else {
fn += ".nxs";
}*/
}
else {
fn = "cooked.nxs";
}

//Initialise the cooker
NxInitCooking();

if (NxCookConvexMesh(mTriangleMeshDescription, UserStream(fn.c_str(), false))) {
pOutDesc->meshData = gPhysicsSDK->createConvexMesh(UserStream(fn.c_str(), true));
}
else {
hasWarning = true;
#ifdef _DEBUG
//error::getSingleton().Throw("Failed meshShape cooking for Mesh '" + mesh->getName() + "'", error::WARNING, mesh->getName(), "meshShape");
#endif
}

}
else {
if (NxCookConvexMesh(mTriangleMeshDescription, buf)) {
pOutDesc->meshData = gPhysicsSDK->createConvexMesh(MemoryReadBuffer(buf.data));
}
else {
hasWarning = true;
#ifdef _DEBUG
#endif
}
}

//Release the cooker
NxCloseCooking();

delete []vertices;
delete []indices;

delete []mMeshVertices;
delete []mMeshFaces;
delete []mMaterials;
}



NxActor * Physics::createConvexMesh(char * name, NxVec3 pos, Entity* ent, bool Static, float densidade, NxVec3 scale, bool forceNewFile)
{
FILE *arquivo;
if(!(arquivo = fopen(name, "r")))
{
NxConvexShapeDesc shapeDesc;
shapeDesc.shapeFlags |= NX_SF_FLUID_TWOWAY;
this->generateConvexMesh(ent, &shapeDesc, scale, std::string(name));
}
else if( forceNewFile)
{
fclose(arquivo);
NxConvexShapeDesc shapeDesc;
shapeDesc.shapeFlags |= NX_SF_FLUID_TWOWAY;
this->generateConvexMesh(ent, &shapeDesc, scale, std::string(name));
}
else
fclose(arquivo);

NxActorDesc actorDesc;
actorDesc.setToDefault();
NxBodyDesc bodyDesc;

NxConvexShapeDesc shapeDesc;

shapeDesc.meshData = gPhysicsSDK->createConvexMesh(UserStream(name, true));

actorDesc.shapes.pushBack(&shapeDesc);

if (!Static)
{
actorDesc.body = &bodyDesc;
actorDesc.density = densidade;

}
actorDesc.globalPose.t = pos;
return gScene->createActor(actorDesc);
}

betajaen

11-03-2010 16:01:35

PhysX or NxOgre?

icaromotta

11-03-2010 17:29:09

whatever. NxOgre is just a wrapper for the PhysX engine in the Ogre. Either way, you will be helping me. :D

betajaen

11-03-2010 17:54:55

It's a bit more than that now.

Anyway, NxOgre you'd use the ManualMesh, and the code from this wiki page. You only need the vertices with Convex meshes, so don't worry about the triangle bits. In fact you could probably omit that part from your code.

icaromotta

11-03-2010 18:07:01

Thank you, I will study this wiki page.

Just do not understand why the code no longer works for the Ogre mesh 1.7

betajaen

11-03-2010 18:14:15

Why do you need to convert it from an Ogre Mesh? Can't you convert it from the original using Flour?

icaromotta

11-03-2010 18:18:53

Because my function works at runtime. So I have more freedom.

but what is the difference between ogre mesh 1.4 and 1.7?

icaromotta

15-03-2010 19:21:22

I made a mistake, the error only happens with the ogrehead.mesh. This code works perfectly.


:D :D :D :D :D :D :D :) :)