Loading...
You are not logged-in Login/Register





  • Posts   Search Threads
  • mindcalamityFebruary 3, 2012 1:26 PM PST   
    Havok Collision Shapes from Custom Vertex and Index Data ?

    Hi, because I'm using Blender, and have no way of obtaining and using 3DS Max/Maya/XSI, I'm stuck with converting the meshes on my own.

    Do the vertices/indices need to be ordered in a specific way or what ?

    I'm using OGRE as my rendering engine, and I would like to convert a simple 14-vertex level into a Havok collision shape, the code which I currently have and produces an incorrect shape is the following:
    		static hkpRigidBody* createTriangleMesh(hkpWorld* pWorld, Ogre::Mesh* mesh, const Vector3& scale)
    		{
    			hkpExtendedMeshShape* meshShape = new hkpExtendedMeshShape(0.0f);
    
    			Vector3* vertices;
    			size_t vertex_count,index_count;
    			unsigned int* indices;
    			getMeshInformation(mesh, vertex_count, vertices, index_count, indices);
    
    			hkVector4* hkVertices;
    
    			for (int j = 0; j < vertex_count; j+=1 )
    			{
    				hkVertices[j] = hkVector4(vertices[j].x, vertices[j].y, vertices[j].z, 0);
    			}
    
    			hkpExtendedMeshShape::TrianglesSubpart part;
    
    			part.m_vertexBase = (float*)hkVertices;
    			part.m_vertexStriding = sizeof(float);
    			part.m_numVertices = vertex_count;
    
    			part.m_indexBase = indices;
    			part.m_indexStriding = sizeof(unsigned int);
    			part.m_numTriangleShapes = index_count/3;
    			part.m_stridingType = hkpExtendedMeshShape::INDICES_INT16;
    
    			meshShape->addTrianglesSubpart(part);
    
    			hkpMoppCompilerInput* cmi = new hkpMoppCompilerInput();
    			hkpMoppCode* code = hkpMoppUtility::buildCode(meshShape, *cmi);
    
    			hkpMoppBvTreeShape* moppBvShape = new hkpMoppBvTreeShape(meshShape, code);
    
    			hkpRigidBodyCinfo info;
    
    			info.m_shape = moppBvShape;
    			info.m_motionType = hkpMotion::MOTION_FIXED;
    
    			hkpRigidBody* r = new hkpRigidBody(info);
    
    			pWorld->addEntity(r);
    
    			return r;
    		}

    BTW - I want to make an exporter for Blender, if possible. Where would I find what I need to read in order to acomplish that ?
    Here's the post on the OGRE3D Forums: http://www.ogre3d.org/forums/viewtopic.php?f=1&t=68747


    nashoustonFebruary 5, 2012 6:30 AM PST
    Rate
     
    Havok Collision Shapes from Custom Vertex and Index Data ?

    Hi mindcalamity
    I don't look deeply in your code
    But are you sure that this is correct :
    part.m_stridingType = hkpExtendedMeshShape::INDICES_INT16;
    Since your original index are stored as unsigned int (32 bytes) maybe change the enum to
    hkpExtendedMeshShape::INDICES_INT32
    can resolve yout problem !!! :)


    mindcalamityFebruary 6, 2012 2:12 AM PST
    Rate
     
    Havok Collision Shapes from Custom Vertex and Index Data ?

    Nah, that's not it, I already tried that.
    The real problem is probably in the way I pass my indices, or vertices.
    In any case something is very wrong.
    I looked at the exporter's XML format, and with all the meta data it was a mess, it cleaned up after disabling it, but I still don't get how a cube can have 72 vertex definitions...
    I think that an example of converting a publicly known, and well-used format into hkx/hkt would benefit the whole Havok community. (Or at least those of us who don't have the means to use 3DS Max or other commercial programs, and other potential users who are pushed away from this simple setback.)
    Here's the code I currently have:
    		static hkpRigidBody* createTriangleMesh(hkpWorld* pWorld, Ogre::Mesh* mesh, const Vector3& scale)
    		{
    			hkpExtendedMeshShape* meshShape = new hkpExtendedMeshShape(0.0f);
    
    			Vector3* vertices;
    			size_t vertex_count,index_count;
    			unsigned int* indices;
    			getMeshInformation(mesh, vertex_count, vertices, index_count, indices);
    
    			hkVector4* hkVertices;
    			hkReal* vertexBuffer;
    			int tmpCounter = 0;
    			for (int j = 0; j < vertex_count; j+=1 )
    			{
    				vertexBuffer[tmpCounter]   = vertices[j].x * scale.x;
    				vertexBuffer[tmpCounter+1]   = vertices[j].y * scale.y;
    				vertexBuffer[tmpCounter+2]   = vertices[j].z * scale.z;
    
    				tmpCounter += 3;
    			}
    
    			for (int i = 0; i < index_count; i++)
    			{
    				//indices[i] = i;
    				std::cout << indices[i] << "\n";
    			}
    			hkpExtendedMeshShape::TrianglesSubpart part;
    
    			part.m_vertexBase = vertexBuffer;
    			part.m_vertexStriding = sizeof(float) * 3;
    			part.m_numVertices = vertex_count;
    
    			part.m_indexBase = indices;
    			part.m_indexStriding = sizeof(unsigned int);
    			part.m_numTriangleShapes = index_count;
    			part.m_stridingType = hkpExtendedMeshShape::INDICES_INT16;
    
    			meshShape->addTrianglesSubpart(part);
    
    			hkpMoppCompilerInput* cmi = new hkpMoppCompilerInput();
    			hkpMoppCode* code = hkpMoppUtility::buildCode(meshShape, *cmi);
    
    			hkpMoppBvTreeShape* moppBvShape = new hkpMoppBvTreeShape(meshShape, code);
    
    			hkpRigidBodyCinfo info;
    
    			info.m_shape = moppBvShape;
    			info.m_motionType = hkpMotion::MOTION_FIXED;
    
    			hkpRigidBody* r = new hkpRigidBody(info);
    
    			pWorld->addEntity(r);
    
    			return r;
    		}
    And the result:


    mindcalamityFebruary 6, 2012 10:43 AM PST
    Rate
     
    Havok Collision Shapes from Custom Vertex and Index Data ?

    OK, progress, now at least Havok is spouting some info:
    Collide\Mopp\Builder\Splitter\hkpMoppDefaultSplitter.cpp(773): [0xABBA2344] Warning : Could not find splitting plane for child
    I also tried using Irrlicht and it's data (with intent to serialize it later), but that seems to result in this exact same thing - the error message above.
    Any ideas ?
    I searched but, amazingly Google doesn't give any results related to Havok (or in any way remotely related to programming in general) at all.
    Thanks to KungFooMasta for the code.

    Thanks to KungFooMasta for the code.
    Current code:
    		static hkpRigidBody* createTriangleMesh(hkpWorld* pWorld, Ogre::Entity* ent, const Vector3& scale)
    		{
    			size_t vertex_count;
    			size_t index_count;
    			Ogre::Vector3 pos;
    			Ogre::Quaternion ori;
    			Ogre::Vector3 rScale;
    			Ogre::Vector3* vertices;
    			unsigned long* indices;
    			_getMeshInformation(ent, vertex_count, vertices, index_count, indices, pos, ori, rScale);
    			// Create Extended Mesh Shape
    			hkpExtendedMeshShape* shape = new hkpExtendedMeshShape();
    			{
    				hkpExtendedMeshShape::TrianglesSubpart part;
    				part.m_numTriangleShapes	= index_count;
    				part.m_numVertices			= vertex_count;
    				part.m_vertexBase			= (float*)vertices;
    				part.m_stridingType         = hkpExtendedMeshShape::INDICES_INT32;
    				part.m_vertexStriding		= sizeof(float) * 3;
    				part.m_indexBase			= indices;
    				part.m_indexStriding		= sizeof(unsigned long) * 3;
    				part.m_numTriangleShapes	= index_count/3;
    
    				shape->addTrianglesSubpart( part );
    			}
    
    			hkpMoppCompilerInput* cmi = new hkpMoppCompilerInput();
    			hkpMoppCode* code = hkpMoppUtility::buildCode(shape, *cmi);
    
    			hkpMoppBvTreeShape* moppBvShape = new hkpMoppBvTreeShape(shape, code);
    
    			hkpRigidBodyCinfo info;
    
    			info.m_shape = moppBvShape;
    			info.m_motionType = hkpMotion::MOTION_FIXED;
    
    			hkpRigidBody* r = new hkpRigidBody(info);
    
    			pWorld->addEntity(r);
    
    			return r;
    		}
    http://www.ogre3d.org/forums/viewtopic.php?f=1&t=68747
    ^^^ Thread on the OGRE Forums ^^^


    havokTylerFebruary 6, 2012 3:37 PM PST
    Rate
     
    Havok Collision Shapes from Custom Vertex and Index Data ?

    Hey, there's a couple minor things here:
    part.m_numTriangleShapes    = index_count; // wrong
    //...
    part.m_numTriangleShapes    = index_count/3; // but then fixed
    part.m_vertexStriding       = sizeof(float) * 3; // best to use sizeof(Ogre::Vector3) just to be safe
    hkpMoppCompilerInput* cmi = new hkpMoppCompilerInput(); // This is an unnecessary new. Just create hkpMoppCompilerInput on the stack so you don't leak.
    That said, I don't see anything particularly wrong with your mesh building code. From that warning either _getMeshInformation() has bugs, or there could be something funky about your asset. I would recommend double checking the output from _getMeshInformation() - does it give the expected number of indices, vertices? Are they all present and valid? Have you tried debugging with simple assets (a box)? Does _getMeshInformation() return temporary buffers that get destroyed later? hkpExtendedMeshShape does not own it's triangle/index information so be sure not to destroy it.

    Just in case your mesh is huge, by default hkpExtendedMeshShape only supports "2^20 triangles = 1048576" (see comments in hkpExtendedMeshShape.h).

    Keep in mind you don't have to create a MOPP from your shape. hkpExtendedMeshShape should handle degenerate triangles. Does the mesh work without creating a mopp from it?

    If you don't mind posting or PMing me your mesh asset after building the hkpExtendedMeshShape I could take a look at it. This will write out an hkpExtendedMeshShape to a file:
    hkOstream os( "mesh.hkt" );
    hkpHavokSnapshot::save( myExtendedMesh, hkpExtendedMeshShapeClass, os.getStreamWriter() );

    Cheers,
    Tyler

    dark_sylincMarch 14, 2012 8:04 PM PDT
    Rate
     
    Havok Collision Shapes from Custom Vertex and Index Data ?

    A month late. Fully working code in the Ogre forums. I paste here just in case:
        std::vector<std::vector<float>>            *verticesOut;
        std::vector<std::vector<unsigned short>>   *indicesOut;
        MeshPtr mesh = MeshManager::getSingleton().load( "MyMeshName",
                                            ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME );
    
        Mesh::SubMe****erator subMe**** = mesh->getSubMe****erator();
        while( subMe****.hasMoreElements() )
        {
           SubMesh *subMesh = subMe****.getNext();
    
           //Reserve enough memory for our vertex buffer
           verticesOut->push_back( std::vector<float>() );
           std::vector<float> &vertices = verticesOut->back();
           vertices.reserve( subMesh->vertexData->vertexCount * 3 );
    
           //Copy vertices
           const VertexElement *vertElement = subMesh->vertexData->vertexDeclaration->
                                               findElementBySemantic( VES_POSITION );
           const size_t vertexSize =
                    subMesh->vertexData->vertexDeclaration->getVertexSize(vertElement->getSource());
           const HardwareVertexBufferSharedPtr &vertexBuf = subMesh->vertexData->vertexBufferBinding->
                                                     getBuffer( vertElement->getSource() );
    
           unsigned char const *pBuffer = static_cast<unsigned char*>
                                      (vertexBuf->lock( HardwareBuffer::HBL_READ_ONLY ));
           for( size_t i=0; i<subMesh->vertexData->vertexCount; ++i )
           {
              float const *pPos = reinterpret_cast<float const*>(pBuffer + vertElement->getOffset());
              vertices.push_back( *pPos++ );
              vertices.push_back( *pPos++ );
              vertices.push_back( *pPos++ );
              pBuffer += vertexSize;
           }
    
           vertexBuf->unlock();
    
           //Reserve enough memory for our index buffer
           indicesOut->push_back( std::vector<unsigned short>() );
           std::vector<unsigned short> &indices = indicesOut->back();
           indices.reserve( subMesh->indexData->indexCount );
    
           //Copy indices
           const HardwareIndexBufferSharedPtr indexBuffer = subMesh->indexData->indexBuffer;
           unsigned short const *pIndices = static_cast<unsigned short*>
                                         (indexBuffer->lock( HardwareBuffer::HBL_READ_ONLY ));
           for( size_t i=0; i<subMesh->indexData->indexCount; ++i )
              indices.push_back( *pIndices++ );
    
           indexBuffer->unlock();
        }
    
        hkpExtendedMeshShape *meshShape = new hkpExtendedMeshShape();
    
        for( size_t i=0; i<verticesOut.size(); ++i )
        {
           hkpExtendedMeshShape::TrianglesSubpart part;
           part.m_vertexBase      = &verticesOut[i][0];
           part.m_vertexStriding   = sizeof( float ) * 3;
           part.m_numVertices      = verticesOut[i].size() / 3;
    
           part.m_indexBase      = &indicesOut[i][0];
           part.m_indexStriding   = sizeof( unsigned short ) * 3;
           part.m_numTriangleShapes= indicesOut[i].size() / 3;
           part.m_stridingType      = hkpExtendedMeshShape::INDICES_INT16;
    
           meshShape->addTrianglesSubpart( part );
        }
    
        hkpMoppCode* moppCode = hkpMoppUtility::buildCode( meshShape, hkpMoppCompilerInput() );
    
        hkpMoppBvTreeShape *retVal = new hkpMoppBvTreeShape( meshShape, moppCode );
        hkpMeshWeldingUtility::computeWeldingInfo( meshShape, retVal,
                                         hkpWeldingUtility::WELDING_TYPE_ANTICLOCKWISE );
        moppCode->removeReference();
        meshShape->removeReference();

    Hope it helps anyone else looking for it.

    Matias N. Goldberg
    Intel Havok Physics Innovation Contest Winner
    * Most Innovative Use of Physics in a Game (2nd Place)
    * Best Physics Knowledge Base Entry (2nd Place)

Forum jump:  

Intel Software Network Forums Statistics

17,025 users have contributed to 48,321 threads and 172,762 posts to date.

In the past 24 hours, we have 11 new thread(s) 45 new posts(s), and 38 new user(s).

In the past 3 days, the most popular thread for everyone has been Optimalization of sine function\'s taylor expansion The most posts were made to Most likely, the issue is that The post with the most views is Optimalization of sine function\'s taylor expansion

Please welcome our newest member mehakchehal52


For more complete information about compiler optimizations, see our Optimization Notice.