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;
}