[C++, DirectX9] Weird collision meshes

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

[C++, DirectX9] Weird collision meshes

Postby Ripiz » Sun Jun 20, 2010 1:08 pm

Code goes first! :twisted:



Newton World creation:
Code: Select all
world = NewtonCreate();
Vector3 minSize (-1000.0f, -1000.0f, -1000.0f);
Vector3 maxSize ( 1000.0f,  1000.0f,  1000.0f);
NewtonSetWorldSize (world, minSize, maxSize);
NewtonSetSolverModel (world, 1);
NewtonSetPlatformArchitecture (world, 2);


Model creation:
Code: Select all
Model *test; //Model is class to handle ID3DXMesh loading, unloading and rendering
test = new Model("rifle.x",Vector3(0,0,-10), Vector3(0,0,0), Vector3(1,1,1))
//header: Model(string filename,Vector3 position, Vector3 rotation, Vector3 scaling);
//I'm using z coordinate as height.

NewtonCollision* shape;
NewtonBody* testBody;
shape=CreateNewtonConvex (world, test, 0);
testBody=CreateRigidBody (world, test, shape, 0.0f);
NewtonReleaseCollision (world, shape);


Model loading (incase there's something wrong, but doubt as it's getting rendered fine):
Code: Select all
void Model::Load(){
   ID3DXBuffer *mtrlBuf=0;
   ID3DXBuffer *adjBuf=0;
   DWORD NumMtrls=0;
   D3DXLoadMeshFromX(m_filename.c_str(), NULL, device, &adjBuf, &mtrlBuf, 0, &NumMtrls, &Mesh);
   if(mtrlBuf!=0&&NumMtrls!=0){
      D3DXMATERIAL *mtrls=(D3DXMATERIAL*)mtrlBuf->GetBufferPointer();
      for(DWORD i=0;i<NumMtrls;i++){
         D3DXMATERIAL M=mtrls[i];
         Material mat;

         mat.Ambient.a=1.0f;
         mat.Ambient.r=1.0f;
         mat.Ambient.g=1.0f;
         mat.Ambient.b=1.0f;

         mat.Diffuse.a=1.0f;
         mat.Diffuse.r=1.0f;
         mat.Diffuse.g=1.0f;
         mat.Diffuse.b=1.0f;

         mat.Emissive.a=0.5f;
         mat.Emissive.r=0.5f;
         mat.Emissive.g=0.5f;
         mat.Emissive.b=0.5f;

         mat.Specular = mtrls[i].MatD3D.Specular;

         mat.Power=1.0f;

         if(mtrls[i].pTextureFilename!=NULL)
            mat.texture=Textures->GetTexture(mtrls[i].pTextureFilename);
         else
            mat.texture=NULL;
         Mtrls.push_back(mat);
      }
   }
   mtrlBuf->Release();
   DWORD* rgdwAdjacency = NULL;
   rgdwAdjacency = new DWORD[ Mesh->GetNumFaces() * 3 ];
   Mesh->GenerateAdjacency( 5.0f, rgdwAdjacency );
   Mesh->OptimizeInplace( D3DXMESHOPT_VERTEXCACHE, rgdwAdjacency, NULL, NULL, NULL );
   delete[] rgdwAdjacency;
   if(adjBuf) adjBuf->Release();
}


Functions used in model collision creation:
Code: Select all
NewtonCollision* CreateNewtonConvex (NewtonWorld* world, Model *ent, int shapeId){
   NewtonCollision* collision;
   vector<Vector3> vertices;
   LPDIRECT3DVERTEXBUFFER9 pVertices;
   ent->Mesh->GetVertexBuffer( &pVertices );
   D3DVERTEX *pVerticesW;
   pVertices->Lock( 0, 0, ( void** )&pVerticesW, 0 );
   for(unsigned int i=0; i<ent->Mesh->GetNumVertices(); i++)
      vertices.push_back(Vector3(pVerticesW[i].p.x, pVerticesW[i].p.y, pVerticesW[i].p.z));
   pVertices->Unlock();
   collision = NewtonCreateConvexHull(world, ent->Mesh->GetNumVertices(), vertices[0], sizeof (Vector3), 0, shapeId, NULL);
   return collision;
}

Code: Select all
NewtonBody* CreateRigidBody (NewtonWorld* world, Model* ent, NewtonCollision* collision, float mass){
   Vector3 minBox;
   Vector3 maxBox;
   Vector3 origin;
   Vector3 inertia;
   NewtonBody* body;

   D3DXMATRIX World,Scale, pos, Rx, Ry, Rz;
   D3DXMatrixRotationX(&Rx, ent->vecRot.x);
   D3DXMatrixRotationY(&Ry, ent->vecRot.y);
   D3DXMatrixRotationZ(&Rz, ent->vecRot.z);
   D3DXMatrixTranslation(&pos, ent->vecPos.x, ent->vecPos.y, ent->vecPos.z);
   D3DXMatrixScaling(&Scale,ent->vecScale.x,ent->vecScale.y,ent->vecScale.z);
   World=Rx*Ry*Rz*pos*Scale;

   body = NewtonCreateBody (world, collision);
   NewtonBodySetDestructorCallback (body, DestroyBodyCallback);
   NewtonBodySetUserData (body, ent);
   NewtonConvexCollisionCalculateInertialMatrix (collision, &inertia[0], &origin[0]);
   NewtonBodySetMatrix (body,World);
   NewtonBodySetMassMatrix (body, mass, mass * inertia.x, mass * inertia.y, mass * inertia.z);
   NewtonBodySetCentreOfMass (body, &origin[0]);
   NewtonBodySetForceAndTorqueCallback (body, ApplyForceAndTorqueCallback);
   NewtonBodySetTransformCallback (body, SetTransformCallback);
   return body;
}


Vertex structure:
Code: Select all
struct D3DVERTEX {
    Vector3 p;
};



Visual debug:
Code: Select all
vector<D3DVERTEX> V; // global

//inside drawing loop
   NewtonBody *body = NewtonWorldGetFirstBody(world);
   NewtonCollision *coll;
   while(body){
      coll = NewtonBodyGetCollision(body);
      Matrix mx;
      NewtonBodyGetMatrix(body, mx);
      NewtonCollisionForEachPolygonDo(coll, mx, Polygon, 0);
      body = NewtonWorldGetNextBody(world, body);
      device->SetFVF(D3DFVF_XYZ);
      device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, V.size()/3, &V[0], sizeof(D3DVERTEX));
      V.clear();
   }


void Polygon(void * userData, int vertexCount, const float* faceVertec, int id){
   for(int i=0; i<vertexCount; i++){
      D3DVERTEX v;
      v.p = Vector3(faceVertec[i*3+0], faceVertec[i*3+1], faceVertec[i*3+2]);
      V.push_back(v);
   }
}


Visual debug is tested and it draws correctly.


And now the problem...
Well basically Convex Hull which gets generated is VERY wrong. I have totally no idea what's wrong.
Dark yellow is Convex Hull, light/bright yellow is my model.
Screenshot:
Image
Ripiz
 
Posts: 47
Joined: Sat Oct 03, 2009 12:07 pm

Return to General Discussion

Who is online

Users browsing this forum: No registered users and 22 guests