Skip to main content
GameDev.net gamedev.net
🔒 Locked

OpenGL with ODE

Started by cossie Jun 21, 2007 at 5:07 AM 5 replies 3k views
Original Post
cossie
cossie
Hi, Has anyone had any success rendering ODE scenes / simulations using OpenGL? I'm having some moderate success but I've noticed some odd behavior when drawing cuboid shapes :( In some cases they render fine but in other cases a cube will end up like this: http://img258.imageshack.us/my.php?image=wrongha0.png It's annoying me because the other cube has landed fine and has wobbled on the blues spheres before coming to rest on the ground. Because ODE sets it's coordinates in the centre of an object, I'm drawing the quads for the cube with the top left corner as the reference point. So x, y and z define the object's centre in ODE, I calculate the OpenGL x, y and z as:

	float x = GetX() - (width / 2.0f);
	float y = GetY() + (height / 2.0f);
	float z = GetZ() - (length / 2.0f);
I get the rotational matrix from ODE (which is in mathematical ordering) and convert it to a 4x4 OpenGL suitable matrix. I build a complete transformation matrix by plugging in x, y and z. When drawing a cube, I do a glMultMatrixf(convertedMatrix); before specifying the vertices. Everything is driven from ODE, the only user input is actually starting the simulation. It's annoying the hell out of me. Has anyone had any luck with using OpenGL in this case?
Pilo
Pilo
Hi!

I use ODE and OpenGL for a long time now, I think it's only a transformation problem.

First I would do thing simple, the center of the cube shape in ode = the center of the rigid body = the center of your "opengl" cube. This way there's no position offset to add :)

Then, ODE matrix are store in "reverse order" (I think you handle it already, if you can post some code it would be nice :))

Here's the code I use to convert ode transform to opengl :

m_Transform.SetIdentity();
const dReal * rot = dBodyGetRotation(m_Body);
m_Transform.m_Data[0][0] = rot[0];
m_Transform.m_Data[0][1] = rot[4];
m_Transform.m_Data[0][2] = rot[8];

m_Transform.m_Data[1][0] = rot[1];
m_Transform.m_Data[1][1] = rot[5];
m_Transform.m_Data[1][2] = rot[9];

m_Transform.m_Data[2][0] = rot[2];
m_Transform.m_Data[2][1] = rot[6];
m_Transform.m_Data[2][2] = rot[10];

m_Transform.SetPosition((Vector3)dBodyGetPosition(m_Body));

m_Transform is just a float[4][4] (but stored in the way opengl use it)
cossie
cossie
Thanks Pilo for your reply,

I convert the matrix as follows, rot is the ODE rotation matrix
and x, y, z is the cube's positional vector:

	t[0] = rot[0]; t[4] = rot[1]; t[8] = rot[2];	t[12] = x;	t[1] = rot[4]; t[5] = rot[5]; t[9] = rot[6];	t[13] = y;	t[2] = rot[8]; t[6] = rot[9]; t[10]= rot[10];   t[14] = z;	t[3] = 0;      t[7] = 0;      t[11]= 0;		t[15] = 1;	


And then my rendering function for my Cube:

	glPushMatrix();// t will contain the coverted ODE rotation matrixglMultMatrixf(t.GetElements());glBegin(GL_QUADS);		// Start Drawing The Cube	// RED	glColor3f(1.0f, 0.0f, 0.0f);		// back wall		glColor3f(0.0f, 0.0f, 1.0f);		glVertex3f(width, 0, 0);		// top right		glVertex3f(0, 0, 0);				// top left		glVertex3f(0, -height, 0);		// bottom left		glVertex3f(width, -height, 0);	// bottom right				// front wall		glColor3f(1.0f, 0.0f, 0.0f);		glVertex3f(width, 0, length);	// top right		glVertex3f(0, 0, length);	// top left		glVertex3f(0, -height, length);		// bottom left		glVertex3f(width, -height, length);	// bottom right				// "floor"		glColor3f(0.0f, 1.0f, 0.0f);		glVertex3f(width, -height, 0);		// top right 		glVertex3f(0, -height, 0);		// top left 		glVertex3f(0, -height, length);		// bottom left 		glVertex3f(width, -height, length);	// bottom right				// "roof"		glColor3f(0.0f, 1.0f, 1.0f);		glVertex3f(width, 0, 0);		// top right 		glVertex3f(0, 0, 0);			// top left		glVertex3f(0, 0, length);		// bottom left 		glVertex3f(width, 0, length);		// bottom right 				// left wall		glColor3f(1.0f, 1.0f, 0.0f);		glVertex3f(0, 0, 0);		// top right 		glVertex3f(0, 0, length);	// top left		glVertex3f(0, -height, length);	// bottom left		glVertex3f(0, -height, 0);	// bottom right				// right wall		glColor3f(0.0f, 1.0f, 0.3f);		glVertex3f(width, 0, 0);	// top right		glVertex3f(width, 0, length);	// top left		glVertex3f(width, -height, length);	// bottom left		glVertex3f(width, -height, 0);		// bottom right			glEnd();	glPopMatrix();


I'm only using a 1D array to store my Matrices because I read that OpenGL uses 1D arrays for matrices (I don't have the link right now, but I think it might have been a FAQ here on gamedev where I read that).

The reason I was doing the offset was because that when I drew a cube using the ODE coordinates cubes would be drawn half way through the ground (the plane I had created for the ground was: dCreatePlane(space, 0, 1, 0, 0);)

So I found if I based the coordinates on a corner, I didn't have that problem.

[editted to format code pasted in]
Pilo
Pilo
Ok you're ode to opengl matrix convertion seems fine.

One problem is that you don't apply the offset correctly :
Quote:

float x = GetX() - (width / 2.0f);
float y = GetY() + (height / 2.0f);
float z = GetZ() - (length / 2.0f);


let's offset = ( -width / 2.0f, height/2.0f, -width/2.0f) be your offset vector (from center to corner in object frame). Then to apply the correct translation to your OpenGL object, you translate by the vector M * offset, and not by offset.

Quote:

The reason I was doing the offset was because that when I drew a cube using the ODE coordinates cubes would be drawn half way through the ground (the plane I had created for the ground was: dCreatePlane(space, 0, 1, 0, 0);)

mmm it seems that ode cude shape was too big?
cossie
cossie
Quote:

One problem is that you don't apply the offset correctly...


Thanks Pilo, I never noticed that at all! :)


Quote:

Then to apply the correct translation to your OpenGL object, you translate by the vector M * offset, and not by offset.


What do you mean when you say "vector M * offset" - what is vector M?


Thanks for your help so far, I greatly appreciate it :)
Pilo
Pilo
Quote:
Thanks for your help so far, I greatly appreciate it :)

No problem ;) I like to be helped too when I have some trouble :)

Quote:
What do you mean when you say "vector M * offset" - what is vector M?

Oops sorry, by M I mean the transform matrix of the object.
You can add this offset just by doing :


glPushMatrix();// t will contain the coverted ODE rotation matrix (with ODE translation part)glMultMatrixf(t.GetElements());// add this to translate the origin from the center of the frame (ODE's object center) to the corner of itglTranslatef(-width / 2.0f, height/2.0f, -width/2.0f);glBegin(GL_QUADS);		// Start Drawing The Cube	// RED	glColor3f(1.0f, 0.0f, 0.0f)...
cossie
cossie
Brilliant! Thanks Pilo that solved the problem :)

I thought maybe that you did mean the transformation matrix so I tried the translation but I was foolishly doing the translate _before_ the matrix multiplication which was the wrong thing to do - oops!

Thank you very much for your help!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.