(C++) Making a Newton Convex hull from an IMesh

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
Gothi[c]
Posts: 8
Joined: Fri Mar 17, 2006 6:40 pm
Contact:

(C++) Making a Newton Convex hull from an IMesh

Post by Gothi[c] »

This function makes a newton Convex hull from an Irrlicht mesh for collision testing.

requires nWorld global (newton world)
I was too lazy to put it as a function argument but i guess you could do that.



Code: Select all

/////////////////////////////////////////////////////////////////////////////

  struct CollisionMesh
    {
    NewtonCollision* Collision;
    NewtonBody* Body;
    };

/////////////////////////////////////////////////////////////////////////////

  CollisionMesh CreateNewtonCollisionConvex(IAnimatedMesh *Mesh)
    {

    // get a mesh from the animated mesh. (default first frame)

    IMesh* MyMesh = Mesh->getMesh(0);

    // Init stuff

    int BufferCount = MyMesh->getMeshBufferCount();
    IMeshBuffer* mb = 0;
    NewtonBody* Body;
    NewtonCollision* Collision;
    float *varray = 0;

    // Loop through all vertices and add them to an array of float that newton wants.

    for (int bi = 0 ; bi < BufferCount ; bi++)
      {
      mb = MyMesh->getMeshBuffer(bi);
      int VerticleCount = mb->getVertexCount();
      debugout << "VertexCount : " << VerticleCount;
      varray = new float[VerticleCount*3];
      switch(mb->getVertexType())
        {
        case EVT_STANDARD:
          {
          S3DVertex* Vertices = (S3DVertex*)mb->getVertices();
          for (int ii = 0 ; ii < VerticleCount ; ii++)
            {
            varray[(ii*3)] = Vertices[ii].Pos.X;
            varray[(ii*3)+1] = Vertices[ii].Pos.Y;
            varray[(ii*3)+2] = Vertices[ii].Pos.Z;
            }
            break;
          }
        case EVT_2TCOORDS:
          {
          S3DVertex2TCoords* Vertices = (S3DVertex2TCoords*)mb->getVertices();
          for (int ii = 0 ; ii < VerticleCount ; ii++)
            {
            varray[(ii*3)] = Vertices[ii].Pos.X;
            varray[(ii*3)+1] = Vertices[ii].Pos.Y;
            varray[(ii*3)+2] = Vertices[ii].Pos.Z;
            }
            break;
          }
        }
      }

    // Finalize and return result.

    Collision = NewtonCreateConvexHull(nWorld,mb->getVertexCount(),(float*)varray,(sizeof(float)*3),NULL);
    delete varray;
    Body = NewtonCreateBody(nWorld,Collision);
    CollisionMesh result;
    result.Collision = Collision;
    result.Body = Body;
    return result;
    }
Baal Cadar
Posts: 377
Joined: Fri Oct 28, 2005 10:28 am
Contact:

Post by Baal Cadar »

Useful indeed. :)
But the function doesn't work for meshes with multiple mesh buffers. You could first determine the accumulated vertex count over all mesh buffers, then create the array and then fill it. As it stands, it only creates the convex hull from the last buffer and has a gaping memory leak with varray newed all over in the for-loop, but not being deleted. And the delete itself uses the wrong operator. It has to be

Code: Select all

delete [] varray;
Also handling of EVT_TANGENTS is missing.
Gothi[c]
Posts: 8
Joined: Fri Mar 17, 2006 6:40 pm
Contact:

Post by Gothi[c] »

But the function doesn't work for meshes with multiple mesh buffers.
Right. to prevent that you have to prevent the array pointer to be overwritten. maybe add another dimension to the array or something. Though your idea sounds better :p
And the delete itself uses the wrong operator.
Nothing like submitting a snipplet for debugging ;)
Also handling of EVT_TANGENTS is missing.
Yeah i forgot to add those. But the general idea should be clear :)
Post Reply