## Newton Integration

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

### Newton Integration

Me again. Finally had time to work on integration in Quake2. So, I've been messing with it, and I think I finally got the code right. It loads the BSP in and everything, but for some reason, when I spawn a "cube" (no model right now, I just made the Newton body and made it print every time the origin changes), Newton doesn't recognize it. Here's the gist of the code:

Code: Select all
`void NDE_SetMeshTransformEvent(const NewtonBody* body, const float* matrix){   mat4x4_t mat;   memcpy(mat, matrix, sizeof(float)*16);   if (body)   {      vec3_t origin;      // Position the node      //tmp->setPosition(mat.getTranslation());      // set position      //tmp->setRotation(mat.getRotationDegrees());   // and rotation      mat3x3_t mat3;      Matrix4_Matrix3 (mat, mat3);      Matrix3_TransformVector (mat3, vec3Origin, origin);      Com_Printf (0, "%f %f %f\n", origin[0], origin[1], origin[2]);   }}void NDE_ApplyForceAndTorqueEvent (const NewtonBody* body) {    float mass;    float Ixx;    float Iyy;    float Izz;    float force[3];    float torque[3];    NewtonBodyGetMassMatrix (body, &mass, &Ixx, &Iyy, &Izz);    force[0] = 0.0f;    force[1] = NEWTON_GRAVITY * mass;    force[2] = 0.0f;    torque[0] = 0.0f;    torque[1] = 0.0f;    torque[2] = 0.0f;    NewtonBodyAddForce (body, force);    NewtonBodyAddTorque (body, torque); }void TestPhysics (void){   NewtonCollision *collision;   NewtonBody *body;   mat4x4_t mat = {0,0,0,0,0,0,0,0,0,0,0,0,0,0};   // Create a box primitive.    collision = NewtonCreateBox(mWorld, 38, 38, 38, NULL);   body = NewtonCreateBody(mWorld,collision);   // Set user data pointer to the scene node   NewtonBodySetUserData(body, NULL);   // Set body mass & inertia matrix   NewtonBodySetMassMatrix (body, 10.0f, 150.0f, 150.0f, 150.0f);   // Set the freeze threshhold to 1 unit (default is 0.01 but irrlight uses a large unit scale)   NewtonBodySetFreezeTreshold(body, 1.0, 1.0, 1.0);    // Set callback functions for the body   NewtonBodySetTransformCallback(body, NDE_SetMeshTransformEvent);   NewtonBodySetForceAndTorqueCallback(body, NDE_ApplyForceAndTorqueEvent);   // Set the position of the body   Matrix4_Translate (mat, 0, 0, 0);   NewtonBodySetMatrix(body, &mat[0]);}static void *cmdtest;void NDE_CGInit (){   cmdtest = cgi.Cmd_AddCommand("testphysics", TestPhysics, "OMG");}void NDE_Init (){   int i;   Com_Printf (0, "====== Initializing Newdon Dynamics Engine ======\n");   // Init newton   mWorld = NewtonCreate(NULL, NULL);   // Set up default material properties for newton   i = NewtonMaterialGetDefaultGroupID(mWorld);   NewtonMaterialSetDefaultFriction   (mWorld, i, i, 0.8f, 0.4f);   NewtonMaterialSetDefaultElasticity (mWorld, i, i, 0.3f);   NewtonMaterialSetDefaultSoftness   (mWorld, i, i, 0.05f);   NewtonMaterialSetCollisionCallback (mWorld, i, i, NULL, NULL, NULL, NULL);   Com_Printf (0, "====== Done Initializing NDE =====\n");}void NDE_Shutdown (){   Com_Printf (0, "Shutting down NDE...\n");   if (g_newtonMap)      // release the collision tree      NewtonReleaseCollision(mWorld, g_newtonMap);   // destory the newton world object   if (mWorld)      NewtonDestroy(mWorld);   else   {      Com_Printf (0, "Nothing to shutdown..\n");      return;   }   Com_Printf (0, "Done\n");}void NDE_Update (){   if (!mWorld)      return;   NewtonUpdate(mWorld, 0.01f);}`

The update function does get called. Any ideas, help? I'm using the lib_mt library, no DLL, with _NEWTON_USE_LIB defined in Newton.h (it didn't seem to recognize that I chose the library).

EDIT: here's the BSP load code in case maybe it's the problem:

Code: Select all
`void R_CreateLevelBody (){   int i;   mBspModel_t *BspModel = &ri.scn.worldModel->bspModel;   mesh_t *curSurf;   int j;   int v1i, v2i, v3i;   float vArray[9]; // vertex array (3*3 floats)   int tmpCount = 0;   vec3_t *mb_vertices;   index_t *mb_indices;   // set the newton world size based on the bsp size   float boxP0[3];    float boxP1[3];    float matrix[4][4];    if (!BspModel)      return;   CL_NewtonCreateTreeCollision();   CL_NewtonTreeCollisionBeginBuild();   for (i=0; i < BspModel->numSurfaces; i++)   {         curSurf = BspModel->surfaces[i].mesh;      mb_vertices = curSurf->vertexArray;      mb_indices  = curSurf->indexArray;      // add each triangle from the mesh      for (j=0; j < curSurf->numIndexes; j+=3)      {         v1i = mb_indices[j];         v2i = mb_indices[j+1];         v3i = mb_indices[j+2];            vArray[0] = mb_vertices[v1i][0];         vArray[1] = mb_vertices[v1i][1];         vArray[2] = mb_vertices[v1i][2];         vArray[3] = mb_vertices[v2i][0];         vArray[4] = mb_vertices[v2i][1];         vArray[5] = mb_vertices[v2i][2];         vArray[6] = mb_vertices[v3i][0];         vArray[7] = mb_vertices[v3i][1];         vArray[8] = mb_vertices[v3i][2];         CL_NewtonTreeCollisionAddFace(3, (float*)vArray, 12, 1);      }   }   CL_NewtonTreeCollisionEndBuild();   CL_NewtonCreateBody();   CL_NewtonBodyGetMatrix (&matrix[0][0]);    CL_NewtonCollisionCalculateAABB (&matrix[0][0],  &boxP0[0], &boxP1[0]);    // you can pad the box here if you wish   //boxP0.y -= somevalue;    //boxP1.y += somevaluef;    CL_NewtonSetWorldSize ((float*)boxP0, (float*)boxP1);}`

The boxP0 and boxP1 are this, on q2dm1 "The Edge":

- boxP1 0x0012ee94 float [3]
[0] 2064.0000 float
[1] 1792.0000 float
[2] 1216.0000 float
- boxP0 0x0012eea8 float [3]
[0] -192.00000 float
[1] -448.00000 float
[2] 192.00000 float

EDIT: Second question, I don't know how to work with matrices, and the engine I use only comes with functions for copying and translating between matrices, but the entities themselves use vectors.. is there any way to convert between the two?

-Paril
Paril

Posts: 13
Joined: Mon Jul 14, 2008 12:48 am

### Re: Newton Integration

What does Matrix4_Translate do?
Aphex

Posts: 144
Joined: Fri Jun 18, 2004 6:08 am
Location: UK

### Re: Newton Integration

Paril wrote:EDIT: Second question, I don't know how to work with matrices, and the engine I use only comes with functions for copying and translating between matrices, but the entities themselves use vectors.. is there any way to convert between the two?

It would proberly be best to replace the code which sets the transform in opengl with glmultimatrix and use the Matrix newton gives you when you are rendering objects.

Stucuk

Posts: 801
Joined: Sat Mar 12, 2005 3:54 pm
Location: Scotland

### Re: Newton Integration

Matrix4_Translate is, from what I see (I have _no_ experience with matrices), translates a 4x4 matrix by x,y,z position.

The engine I use uses a mesh buffer, which is accumulated by type and all rendered at the end. With my experience with matrices being none, and having not want to re-write tons and tons of math that revolves around the entities in the game, it would be simpler to have library functions to 'get' the rotation/position of a matrix and work from there. I'm sure there are some around, Irrlicht has them from the tutorials that I saw for Newton, but I'm not sure where to look.

I also found that it was the callback causing the issue, it wasn't being called back. I put a print out after the update and a global body/collision instead of a local one, and it seems to recognize that the object is valid, but I can't get any non-NAN numbers from the matrices because matrices are rarely used in the engine and I have nothing to look on for examples.

Does Newton work on a 3x3 matrix or a 4x4 matrix?

-Paril
Paril

Posts: 13
Joined: Mon Jul 14, 2008 12:48 am

### Re: Newton Integration

Might want to try setting 'mat' to the identity matrix, not all zeroes?
i.e. {1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1}
Aphex

Posts: 144
Joined: Fri Jun 18, 2004 6:08 am
Location: UK

### Re: Newton Integration

newton works with 4*4 matrices, and if you use those matrices for rendering each entity directly it should work just fine.
Help improving the Newton Game Dynamics WIKI

JernejL

Posts: 1531
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

### Re: Newton Integration

I understand that, but it's the fact that everything in the mesh buffer is rendered via vectors and euler angles, it would be simpler to convert between the matrix to origin/rotation from Newton and set directly to the entity, rather than having to re-write the entire handlers for the mesh buffer, and I have no experience with matrixes, so that really isn't an option.

I found dMatrix in dMatrix.h, this might be helpful, I will go through this and see what I can find.

-Paril
Paril

Posts: 13
Joined: Mon Jul 14, 2008 12:48 am

### Re: Newton Integration

The problem with converting is that whats rendered may not be an accurate representation of the actual physics, so the mesh and physics may be a bit out of sync.

Stucuk

Posts: 801
Joined: Sat Mar 12, 2005 3:54 pm
Location: Scotland

### Re: Newton Integration

Understood, but I don't have any other option. Are there any similar physics engines that use vectors/euler angles for this sort of thing? I was hoping to use Newton but I have a feeling it's more trouble than it's worth...

EDIT: Thanks from some help by a friend I have found what I can do with the matrix for Quake2. However, a new problem: the body I created never moves.. any ideas?

-Paril
Paril

Posts: 13
Joined: Mon Jul 14, 2008 12:48 am

### Re: Newton Integration

You're going to need to know about matrices to make proper use of any physics engine, unfortunately.
Aphex

Posts: 144
Joined: Fri Jun 18, 2004 6:08 am
Location: UK

### Re: Newton Integration

My friend, the creator of the engine coincidentally, has come to my aid in that term. He's wanted to scrap the origin/angles for matrixes anyway, so maybe this can come to fruition.

He gave me some temp stuff I can use for this. But my problem now is the body never moves, the GetMatrix always returns the same matrix, any ideas?

-Paril
Paril

Posts: 13
Joined: Mon Jul 14, 2008 12:48 am