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.
