Falling box only updates once [SOLVED!]

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Falling box only updates once [SOLVED!]

Postby zaneski13 » Sat Aug 28, 2010 6:57 pm

So, this is my second day trying to make an app using the Newton Physics Engine 2.24

I made a simple cube class that creates a Cube Object in the Newton World and also draws it every frame. The problem is the cube only updates once. I think it has to do something with the matrices of the box. I'll explain...

I made a simple matrix class which does only what I need.

Code: Select all

#pragma once


#include "Camera.h"

class Matrix4
{
public:
   float m[16];

public:
   Matrix4(float m0, float m1, float m2, float m3, float m4, float m5, float m6, float m7, float m8,
      float m9, float m10, float m11, float m12, float m13, float m14, float m15 )
   {
      m[0] = m0;
      m[1] = m1;
      m[2] = m2;
      m[3] = m3;
      m[4] = m4;
      m[5] = m5;
      m[6] = m6;
      m[7] = m7;
      m[8] = m8;
      m[9] = m9;
      m[10] = m10;
      m[11] = m11;
      m[12] = m12;
      m[13] = m13;
      m[14] = m14;
      m[15] = m15;
   }
   
   Matrix4()
   {
      LoadIdentity();
   }

   void LoadIdentity(void)
   {
      m[0] = m[5] = m[10] = m[15] = 1.0f;
      m[1] = m[2] = m[3] = m[4] = m[6] = m[7] = m[8] = m[9] = m[11] = m[12] = m[13] = m[14] = 0.0f;
   }


   void Transpose(void)
   {
      *this = GetTranspose();
   }

   Matrix4 GetTranspose(void)
   {
      return Matrix4( m[0], m[4], m[8], m[12],
                  m[1], m[5], m[9], m[13],
                  m[2], m[6], m[10], m[14],
                  m[3], m[7], m[11], m[15] );         
   }

   void SetTranslationPart(float x, float y, float z)
   {
      m[12] = x;
      m[13] = y;
      m[14] = z;
   }
   void SetRotation(float angleX, float angleY, float angleZ)
   {
      LoadIdentity();

      double cr = cos( PI*angleX/180 );
      double sr = sin( PI*angleX/180 );
      double cp = cos( PI*angleY/180 );
      double sp = sin( PI*angleY/180 );
      double cy = cos( PI*angleZ/180 );
      double sy = sin( PI*angleZ/180 );

      m[0] = ( float )( cp*cy );
      m[1] = ( float )( cp*sy );
      m[2] = ( float )( -sp );

      double srsp = sr*sp;
      double crsp = cr*sp;

      m[4] = ( float )( srsp*cy-cr*sy );
      m[5] = ( float )( srsp*sy+cr*cy );
      m[6] = ( float )( sr*cp );

      m[8] = ( float )( crsp*cy+sr*sy );
      m[9] = ( float )( crsp*sy-sr*cy );
      m[10] = ( float )( cr*cp );
   }

   void operator=(const Matrix4 &mat)
   {
      for ( int i = 0; i < 16; i++ )
         m[i] = mat.m[i];
   }

};





The matrices store the positions in m[12] m[13] and m[14] because thats how OpenGL stores them (And I use glMultMatrixf() before I draw the box)
Well, I read somewhere that Newton stores matrices in row major order so I would have to transpose the matrix I pass to newton. so here's my code for creating the box

Code: Select all

class Cube
{
public:
   Matrix4 matrix;

   Cube(Vector3f position, Vector3f rotation, Vector3f size_, Vector3f velocity, float mass)
   {
      size = size_;

      NewtonCollision *collision;
      collision = ::NewtonCreateBox(world, size.x, size.y, size.z, 0, NULL);
      body = ::NewtonCreateBody(world, collision);
      ::NewtonReleaseCollision(world, collision);

      ::NewtonBodySetUserData(body, this);

      // Set body mass & inertia matrix
      float Ixx = 0.7f * mass * (size.y * size.y + size.z * size.z) / 12.0f;
      float Iyy = 0.7f * mass * (size.x * size.x + size.z * size.z) / 12.0f;
      float Izz = 0.7f * mass * (size.x * size.x + size.y * size.y) / 12.0f;
      NewtonBodySetMassMatrix (body, mass, Ixx, Iyy, Izz);

      // Set callback functions for the body
      NewtonBodySetTransformCallback(body, setTransformationNewtonCallback);
      NewtonBodySetForceAndTorqueCallback(body, applyForceAndTorqueNewtonCallback);

      //SETUP THE MATIX FOR THE BODY
      matrix.LoadIdentity();
      matrix.SetRotation(rotation.x, rotation.y, rotation.z);
      matrix.SetTranslationPart(position.x, position.y, position.z);

      NewtonBodySetMatrix(body, matrix.GetTranspose().m); //TRANSPOSE BECAUSE NEWTON STORES MATRICES ROW MAJOR


      float vel[3] = {velocity.x, velocity.y, velocity.z};
      NewtonBodySetVelocity(body, vel);

      float gravityForce = GRAVITY * mass;
      ::NewtonBodySetForce(body, &gravityForce);


   }

   ~Cube()
   {

   }

   void Draw(void)
   {
      glPushMatrix();


      cout << "matrix when we draw\n";
           cout << matrix.m[0] << "   " << matrix.m[1] << "   " << matrix.m[2] << "   " << matrix.m[3] << endl;
           cout << matrix.m[4] << "   " << matrix.m[5] << "   " << matrix.m[6] << "   " << matrix.m[7] << endl;
           cout << matrix.m[8] << "   " << matrix.m[9] << "   " << matrix.m[10] << "   " << matrix.m[11] << endl;
           cout << matrix.m[12] << "   " << matrix.m[13] << "   " << matrix.m[14] << "   " << matrix.m[15] << endl;
    
      glMultMatrixf(matrix.m);


      DrawBox(size.x, size.y, size.z);

      glPopMatrix();
   }

   NewtonBody* GetNewtonBody(void)
   {
      return body;
   }

private:
   Vector3f size;
   NewtonBody *body;

};



now that everytthing is set up I have the callback functions. The setTransformationNewtonCallback() is giving me most trouble. The matrix that comes in has incorrect results

Code: Select all
Cube *c = (Cube*)NewtonBodyGetUserData(body);
   if ( !c )
      return;

   Matrix4 mat;
   memcpy(mat.m, matrixFromNewton, sizeof(float)*16);

   mat.Transpose();
   c->matrix = mat;

   cout << "matrix when we look at it\n";
   cout << mat.m[0] << "   " << mat.m[1] << "   " << mat.m[2] << "   " << mat.m[3] << endl;
   cout << mat.m[4] << "   " << mat.m[5] << "   " << mat.m[6] << "   " << mat.m[7] << endl;
   cout << mat.m[8] << "   " << mat.m[9] << "   " << mat.m[10] << "   " << mat.m[11] << endl;
   cout << mat.m[12] << "   " << mat.m[13] << "   " << mat.m[14] << "   " << mat.m[15] << endl;

   


Now, the first VERY weird thing that happens is when I set the cubes matrix (IE: c->matrix = mat.) the cubes matrix doesn't change at all.
Heres the out put of my program. ( the cout << "stuff"; )

matrix when we look at it
0.219846 0.604023 -0.766044 -0.00138889
-0.682796 0.656121 0.321394 0.332637
0.696747 0.452395 0.55667 -2982.62
0 0 0 1

matrix when we draw
0.219846 0.604023 -0.766044 0
-0.682796 0.656121 0.321394 0
0.696747 0.452395 0.55667 0
0 20 -60 1

so for some reason the matrix doesn't change.

The second weird thing that happens is the setTransformationNewtonCallback function is only called ONCE! I think this has to do with the face that the cubes position.z in the matrix somehow goes to -2982.62 which is out of the world size I set. But regardless, the zpos shouldn't have changed like that!

So I have no clue whats happening in my program, and I've been debugging it almost 20 hours so I really need help on this one.
Last edited by zaneski13 on Sun Aug 29, 2010 12:35 am, edited 1 time in total.
zaneski13
 
Posts: 10
Joined: Sat Aug 28, 2010 6:12 pm

Re: Falling box only updates once

Postby Stucuk » Sat Aug 28, 2010 8:32 pm

If applyForceAndTorqueNewtonCallback is not applying a force then you won't get more than 1 Matrix Update. If your object is outside the worlds min/max size then you also won't get more than 1 Matrix Update.

P.S My Matrix's look like the following, its the same as i sent to OpenGL:
Code: Select all
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (PosX, PosY, PosZ, 1));


Thats what iv been passing to Newton anyway.
User avatar
Stucuk
 
Posts: 801
Joined: Sat Mar 12, 2005 3:54 pm
Location: Scotland

Re: Falling box only updates once

Postby zaneski13 » Sat Aug 28, 2010 10:11 pm

my applyForceAndTorqueNewtonCallback looks like this


so it is applying a force.
Code: Select all
void applyForceAndTorqueNewtonCallback(const ::NewtonBody *body, float timeStep, int threadIndex) //this func gives DEBUG Warnings
{
   float mass;
   float Ixx;
   float Iyy;
   float Izz;

   NewtonBodyGetMassMatrix (body, &mass, &Ixx, &Iyy, &Izz);

   Vector3f force (0.0f , GRAVITY * mass , 0.0f);
   Vector3f torque (0.0f, 0.0f, 0.0f);

   NewtonBodySetForce(body, &force.y);
}


But I think whats happening is the object falls out of the world in 1 frame. Because when I cout the matrix that is sent to me in setTransformationNewtonCallback the z position strangely becomes -2982.62. This is VERY starange because the starting position of the body is -60 and the velocity in the z direction is 0.0f so its impossible for it to change. I think its something wrong with the matrices but I can't figure out what.
zaneski13
 
Posts: 10
Joined: Sat Aug 28, 2010 6:12 pm

Re: Falling box only updates once

Postby zaneski13 » Sat Aug 28, 2010 11:01 pm

So, I actually ended up changing some code around and I narrowed the problem down to one little spot.

Code: Select all
void setTransformationNewtonCallback(const NewtonBody *body, const float *matrixFromNewton, int threadIndex)
{
   
   Cube *c = (Cube*)NewtonBodyGetUserData(body);
   if ( !c )
      return;


   memcpy(  c->matrix.m, matrixFromNewton, sizeof(float)*16);




   /*cout << "matrix when we set it\n";
   cout << c->matrix.m[0] << "   " << c->matrix.m[1] << "   " << c->matrix.m[2] << "   " << c->matrix.m[3] << endl;
   cout << c->matrix.m[4] << "   " << c->matrix.m[5] << "   " << c->matrix.m[6] << "   " << c->matrix.m[7] << endl;
   cout << c->matrix.m[8] << "   " << c->matrix.m[9] << "   " << c->matrix.m[10] << "   " << c->matrix.m[11] << endl;
   cout << c->matrix.m[12] << "   " << c->matrix.m[13] << "   " << c->matrix.m[14] << "   " << c->matrix.m[15] << "\n\n\n";
*/
   
}


so when I cout the matrix, the matrix looks correct. the yPos drops as it should in the presence of gravity.
However, when I draw the cube, the matrix stays the same! I don't understand how this is even possible! I set the cube's matrix when this line excecutes.

Code: Select all
memcpy(  c->matrix.m, matrixFromNewton, sizeof(float)*16);


so Its a problem with changing data around. Everything seems like it should work, yet the cube's matrix stays the same as it starts with
zaneski13
 
Posts: 10
Joined: Sat Aug 28, 2010 6:12 pm

Re: Falling box only updates once [SOLVED]

Postby zaneski13 » Sun Aug 29, 2010 12:35 am

I FIGURED IT OUT!!!

the problem was in this line.

NewtonBodySetUserData(body, this);

in c++ a this pointer can't be used to modify elements in the class. So I changed my code around and got everything working!
zaneski13
 
Posts: 10
Joined: Sat Aug 28, 2010 6:12 pm


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 161 guests

cron