Page 2 of 2

Posted: Wed Nov 05, 2008 8:42 pm
by Acki
I'm not sure about your code though, but for Newton I get the collision for a mesh like this:

Code: Select all

NewtonCollision* makeCollisionFromMesh(NewtonWorld* nWorld, IMesh* mesh, ISceneNode* node){
  NewtonCollision* collision = NewtonCreateTreeCollision(nWorld, NULL);
  NewtonTreeCollisionBeginBuild(collision);
  int cMeshBuffer, j;
  int v1i, v2i, v3i;
  IMeshBuffer* mb;
  vector3df vArray[3]; // Vertex Array (3*3 Floats)
  for(cMeshBuffer = 0; cMeshBuffer < (s32)mesh->getMeshBufferCount(); cMeshBuffer++){
    mb = mesh->getMeshBuffer(cMeshBuffer);
    void* mb_vertices = (void*)mb->getVertices();
    u16* mb_indices  = mb->getIndices();
    // jedes Dreieck hinzufügen
    for(j = 0; j < (s32)mb->getIndexCount(); j += 3){
      v1i = mb_indices[j];
      v2i = mb_indices[j + 1];
      v3i = mb_indices[j + 2];
      // die drei Vertexe des Dreiecks ermitteln
      switch(mb->getVertexType()){
        case EVT_STANDARD:{
          vArray[0] =  ((S3DVertex*)mb_vertices)[v1i].Pos * node->getScale();
          vArray[1] = ((S3DVertex*)mb_vertices)[v2i].Pos * node->getScale();
          vArray[2] = ((S3DVertex*)mb_vertices)[v3i].Pos * node->getScale();
        }break;
        case EVT_2TCOORDS:{
          vArray[0] =  ((S3DVertex2TCoords*)mb_vertices)[v1i].Pos * node->getScale();
          vArray[1] = ((S3DVertex2TCoords*)mb_vertices)[v2i].Pos * node->getScale();
          vArray[2] = ((S3DVertex2TCoords*)mb_vertices)[v3i].Pos * node->getScale();
        }break;
        case EVT_TANGENTS:{
          vArray[0] =  ((S3DVertexTangents*)mb_vertices)[v1i].Pos * node->getScale();
          vArray[1] = ((S3DVertexTangents*)mb_vertices)[v2i].Pos * node->getScale();
          vArray[2] = ((S3DVertexTangents*)mb_vertices)[v3i].Pos * node->getScale();
        }break;
      }
      // sicher stellen, dass keine Fehlerhaften Flächen hinzugefügt werden
      vector3df e0 (vArray[1] - vArray[0]);
      vector3df e1 (vArray[2] - vArray[0]);
      // der Platz der Fläche ist die Quersumme
      vector3df area(e0.crossProduct(e1));
      // Flächen mit sehr kleiner Größe überspringen
      float mag = area.dotProduct(area);
      if(mag > 1.0e-16f) NewtonTreeCollisionAddFace(collision, 3, &vArray[0].X, sizeof (vector3df), 1);
    }
  }
  // wir optimieren das Mesh (erhöht die Performance enorm)
  NewtonTreeCollisionEndBuild(collision, 1);
  return collision;
}
except from the Newton stuff this should also work for ODE... ;)

Posted: Tue Nov 11, 2008 5:14 am
by cheesehound
Thanks, I failed to notice there was a second page on this :P.

That does seem to be the standard way to do it with Newton. What I'm doing, (so far as I can tell) matches what is normally done to get meshes into ODE/Physx, or any other physics engine's mesh creation function via vertex and indices arrays. I'm assuming I'm doing something wrong in my code, but if I can't fish that out I may well try some other physics solution.

[edit, problem solved:]

Ouch. So far as I can tell the main thing I botched is just making my test objects too large. For some reason ODE is perfectly happy letting large physics objects puncture and eventually fall through physics meshes (not boxes or spheres, though :P).

Also, somewhat confusingly, the float* array was causing problems for me so I reverted to the dVector3 array. I must have read that typedef wrong.

The moral of the story is: Irrlicht rad, ODE sad. I do like its 2D joint, but if behavior like this is the norm then I can see myself migrating to another physics engine in time.