[DirectX9] Collision problem

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

[DirectX9] Collision problem

Postby Ripiz » Tue Jun 15, 2010 8:54 am

My code:
Code: Select all
//Globals
typedef D3DXVECTOR3 Vector3;
vector<Model*> newtonTest;
NewtonWorld *world;

//WinMain
   world = NewtonCreate();
   Vector3 minSize (-1000.0f, -1000.0f, -1000.0f);
   Vector3 maxSize ( 1000.0f,  1000.0f,  1000.0f);
   NewtonSetWorldSize (world, minSize, maxSize);

//Model creation
   NewtonCollision* shape;
   NewtonBody* testBody;
   newtonTest.push_back(new Model("box2.x", Vector3(0, 0, 0), Vector3(0, 0, 0), Vector3(1, 1, 1)));
   
   shape=CreateNewtonConvex (world, newtonTest[0], 0);
   testBody=CreateRigidBody (world, newtonTest[0], shape, 0.0f);
   NewtonReleaseCollision (world, shape);

   for(unsigned int i=1; i<=10; i++){
      newtonTest.push_back(new Model("sword.x", Vector3(roll(10)-5, roll(10)-5, 50), Vector3(2, 2, 2), Vector3(1, 1, 1)));
      shape=CreateNewtonConvex (world, newtonTest[i], 0);
      testBody=CreateRigidBody (world, newtonTest[i], shape, 1.0f);
      NewtonReleaseCollision (world, shape);
   }

//Functions used
inline int roll(int i){
   return rand() % i + 1;
}
void DestroyBodyCallback (const NewtonBody* body){
}
void ApplyForceAndTorqueCallback (const NewtonBody* body, float timestep, int threadIndex){
   float Ixx;
   float Iyy;
   float Izz;
   float mass;
   NewtonBodyGetMassMatrix (body, &mass, &Ixx, &Iyy, &Izz);
   D3DXVECTOR4 gravityForce  (0.0f, 0.0f, mass * -10.0f, 1.0f);
   NewtonBodySetForce(body, &gravityForce[0]);
}
void SetTransformCallback (const NewtonBody* body, const float* matrix, int threadIndex){
   Model* ent;
   Matrix mx = matrix;
   float rot[10];
   ent = (Model*)NewtonBodyGetUserData(body);
   NewtonBodyGetRotation(body, rot);
   ent->vecPos.x = matrix[12];
   ent->vecPos.y = matrix[13];
   ent->vecPos.z = matrix[14];

   ent->vecRot.x=rot[0];
   ent->vecRot.y=rot[1];
   ent->vecRot.z=rot[2];
}
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;
}
NewtonCollision* CreateNewtonConvex (NewtonWorld* world, Model *ent, int shapeId){
   NewtonCollision* collision;
   float* tmpArray = new float [ent->Mesh->GetNumVertices()*3];
   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++){
      tmpArray[i*3+0]=pVerticesW[i].p.x;
      tmpArray[i*3+1]=pVerticesW[i].p.y;
      tmpArray[i*3+2]=pVerticesW[i].p.z;
   }
   collision = NewtonCreateConvexHull(world, ent->Mesh->GetNumVertices(), (float*)tmpArray, sizeof (Vector3), 0, shapeId, NULL);
   delete tmpArray;
   return collision;
}


Seems collision doesn't happen all the time, which is pretty annoying, anyone have idea why this happens, and how to fix this? Thank you in advance.

Screenshots of bug:
http://dl.dropbox.com/u/2637453/5.jpg
http://dl.dropbox.com/u/2637453/7.jpg
Last edited by Ripiz on Tue Jun 15, 2010 9:17 am, edited 2 times in total.
Ripiz
 
Posts: 47
Joined: Sat Oct 03, 2009 12:07 pm

Re: [DirectX9] Collision problem

Postby JernejL » Tue Jun 15, 2010 9:12 am

What on the earth is in that screenshot? some akward objects from another akward upclose camera, to make it really hard to understand what is what.
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1587
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Re: [DirectX9] Collision problem

Postby Ripiz » Tue Jun 15, 2010 9:16 am

Alright here's new screenshot: http://dl.dropbox.com/u/2637453/7.jpg
It's swords, and for some reason their handles go through box, but other part(s) collide(s).
Ripiz
 
Posts: 47
Joined: Sat Oct 03, 2009 12:07 pm

Re: [DirectX9] Collision problem

Postby Julio Jerez » Tue Jun 15, 2010 11:16 am

I am gessing that eh collision does no math teh sword exacly,
implement debug display to see what is going on.

Then when you have the collision shape as it should be, the othe problem is that migh happen is that the blade may be too thin for decrete collision,
you need to enable continue collision and may sampel at a higher that fps.
but for you need to know that the collision shapes are right.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: [DirectX9] Collision problem

Postby Ripiz » Tue Jun 15, 2010 12:51 pm

And how to do that debug display? :)
Ripiz
 
Posts: 47
Joined: Sat Oct 03, 2009 12:07 pm

Re: [DirectX9] Collision problem

Postby Julio Jerez » Tue Jun 15, 2010 1:30 pm

look at the debugdisplay.cpp in the SDK demos.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: [DirectX9] Collision problem

Postby Ripiz » Tue Jun 15, 2010 3:19 pm

Code: Select all
vector<D3DVERTEX> V;
void Polygon(void * userData, int vertexCount, const float* faceVertec, int id){
   for(int i=0; i<vertexCount; i++){
      D3DVERTEX v;
      v.p = Vector4(faceVertec[i*3+0], faceVertec[i*3+1], faceVertec[i*3+2], 1);
      v.color = 0xFFFFFFFF;
      V.push_back(v);
   }
}
void Render_Login(float Time){
   NewtonBody *body = NewtonWorldGetFirstBody(world);
   NewtonCollision *coll;
   while(body){
      coll = NewtonBodyGetCollision(body);
      Matrix mx;
      NewtonBodyGetMatrix(body, mx);
      device->SetTransform(D3DTS_WORLD, &mx);
      NewtonCollisionForEachPolygonDo(coll, mx, Polygon, 0);
      body = NewtonWorldGetNextBody(world, body);
   }

   D3DVERTEX* verts = new D3DVERTEX[V.size()];
   LPDIRECT3DVERTEXBUFFER9 VB = 0;
   for(unsigned int i=0; i<V.size(); i++)
      verts[i]=V[i];
   device->CreateVertexBuffer(sizeof(D3DVERTEX)*(V.size()-1), D3DUSAGE_WRITEONLY, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, D3DPOOL_DEFAULT, &VB, NULL);
   VOID* p_Vertices;
   VB->Lock(0, 0, (void**)&p_Vertices, 0);
   memcpy(p_Vertices, verts, sizeof(D3DVERTEX)*(V.size()-1));
   VB->Unlock();

   device->SetStreamSource(0, VB, 0, sizeof(D3DVERTEX));
   device->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
   device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, (V.size()-1)/3);
   VB->Release();
   delete []verts;
   V.clear();
}


I followed few examples, I think I did everything right but I get only one retarded line in the corner: http://dl.dropbox.com/u/2637453/11.JPG
Debug Display needs a fix too :(
Ripiz
 
Posts: 47
Joined: Sat Oct 03, 2009 12:07 pm

Re: [DirectX9] Collision problem

Postby Julio Jerez » Tue Jun 15, 2010 4:14 pm

if it does no display then it is not right, luck carefully void Polygon is a poygon it is not a triangle
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: [DirectX9] Collision problem

Postby Stucuk » Tue Jun 15, 2010 7:27 pm

I think Julio means this line:
Code: Select all
device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, (V.size()-1)/3);


I don't think V.size()-1 would be right. Assuming that V.size() gives the total count of vertex's then taking 1 away would make it incorrect. Rounding may still give the correct number of primitives but its still wrong.
User avatar
Stucuk
 
Posts: 801
Joined: Sat Mar 12, 2005 3:54 pm
Location: Scotland

Re: [DirectX9] Collision problem

Postby Ripiz » Wed Jun 16, 2010 12:15 am

V.size() is 718, 718/3 = 239.33, so I did -1. Before it was without it, it was still wrong.
Ripiz
 
Posts: 47
Joined: Sat Oct 03, 2009 12:07 pm

Re: [DirectX9] Collision problem

Postby Stucuk » Wed Jun 16, 2010 12:22 am

As Julio said, your trying to draw them as Triangles but newton is sending polygons. While a triangle is a Polygon, what newton is giving you may have more than 3 points. You should change your code so that instead of building a list of everything, you only build a list of the vertex's in each polygon and render each polygon separately.
User avatar
Stucuk
 
Posts: 801
Joined: Sat Mar 12, 2005 3:54 pm
Location: Scotland

Re: [DirectX9] Collision problem

Postby Ripiz » Wed Jun 16, 2010 1:35 am

Code: Select all
void Polygon(void * userData, int vertexCount, const float* faceVertec, int id){
   D3DVERTEX* verts = new D3DVERTEX[vertexCount];
   LPDIRECT3DVERTEXBUFFER9 VB = 0;
   for(unsigned int i=0; i<vertexCount; i++){
      verts[i].p=Vector4(faceVertec[i*3+0], faceVertec[i*3+1], faceVertec[i*3+2], 1);
      verts[i].color=0xFFFFFFFF;
   }
   device->CreateVertexBuffer(sizeof(D3DVERTEX)*vertexCount, D3DUSAGE_WRITEONLY, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, D3DPOOL_DEFAULT, &VB, NULL);
   VOID* p_Vertices;
   VB->Lock(0, 0, (void**)&p_Vertices, 0);
   memcpy(p_Vertices, verts, sizeof(D3DVERTEX)*vertexCount);
   VB->Unlock();

   device->SetStreamSource(0, VB, 0, sizeof(D3DVERTEX));
   device->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
   device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
   VB->Release();
   delete []verts;
}


FPS dropped, nothing else changed. Same dumb line in the corner.
Ripiz
 
Posts: 47
Joined: Sat Oct 03, 2009 12:07 pm

Re: [DirectX9] Collision problem

Postby Julio Jerez » Wed Jun 16, 2010 8:39 am

you can not expect the code to work with wrong data.
you are building the collision mesh wrong and the debug display also wrong.

the debug display callback provide a polygon in each call, you need to Fan then into a triangle list, you cannot simple put all the vertices in a vertex list and render then as if they were triangles.
There as few functions in file debugDisplay.cpp to do just that.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: [DirectX9] Collision problem

Postby Ripiz » Wed Jun 16, 2010 8:42 am

Sorry for double post, haven't found how to delete old post.
Here's how I've done Visual Debug:
Code: Select all
vector<D3DVERTEX> V;
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.color = 0xFFFFFFFF;
      V.push_back(v);
   }
}
void Render(float Time){

   device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
   device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID );
   
   for(unsigned int i=1; i<newtonTest.size(); i++)
      newtonTest[i]->Draw();
   newtonTest[0]->Draw();

   device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME );
   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 | D3DFVF_DIFFUSE);
      device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, V.size()/3, &V[0], sizeof(D3DVERTEX));
      V.clear();
   }
}



My code for TransformCallback:
Code: Select all
void SetTransformCallback (const NewtonBody* body, const float* matrix, int threadIndex){
   Model* ent;
   ent = (Model*)NewtonBodyGetUserData(body);
   ent->vecPos.x = matrix[12];
   ent->vecPos.y = matrix[13];
   ent->vecPos.z = matrix[14];
}

It's missing rotation as I didn't knew how to make it. Anyone have any ideas/tips how to do it? Thank you in advance.

Current result without rotation:
http://dl.dropbox.com/u/2637453/rot.JPG
Ripiz
 
Posts: 47
Joined: Sat Oct 03, 2009 12:07 pm

Re: [DirectX9] Collision problem

Postby Carli » Wed Jun 16, 2010 9:25 am

Ripiz wrote:It's missing rotation as I didn't knew how to make it. Anyone have any ideas/tips how to do it? Thank you in advance.

Code: Select all
void SetTransformCallback (const NewtonBody* body, const float* matrix, int threadIndex){
   Model* ent;
   ent = (Model*)NewtonBodyGetUserData(body);
   ent->vecPos.x = matrix[12];
   ent->vecPos.y = matrix[13];
   ent->vecPos.z = matrix[14];
}



you should multiply the matrix with the vector and not just add the transformation part of the matrix to the vector.
Carli
 
Posts: 245
Joined: Fri Oct 02, 2009 5:28 am

Next

Return to General Discussion

Who is online

Users browsing this forum: No registered users and 1 guest