3d Rotations and Translations

Started by
-1 comments, last by clipmon 14 years, 8 months ago
Hello, I would like to say that I know what I'm doing, but for the life of me everything that should mathematically work doesnt and I have things working that dont make sense to me. So I'm hoping to have some one explain to me what is going on regarding some code. I'm using euler angles about an arbitrary axis to rotate in the typical first person shooter style. I'm rendering using opengl that uses column major ordering (The column ordering may be the culprit)

void rotateVector(float rad, vec3 &vec, vec3 &axis)
{
	matrix3	m;
	float	sinVal, cosVal, minusVal;

	sinVal = sin(rad);
	cosVal = cos(rad);
	minusVal = 1.0f - cosVal;

	m.m[0] = cosVal + minusVal * axis.x * axis.x;
	m.m[3] = minusVal * axis.x * axis.y - sinVal * axis.z;
	m.m[6] = minusVal * axis.x * axis.z + sinVal * axis.y;

	m.m[1] = minusVal * axis.y * axis.x + sinVal * axis.z;
	m.m[4] = cosVal + minusVal * axis.y * axis.y;
	m.m[7] = minusVal * axis.y * axis.z - sinVal * axis.x;

	m.m[2] = minusVal * axis.z * axis.x - sinVal * axis.y;
	m.m[5] = minusVal * axis.z * axis.y + sinVal * axis.x;
	m.m[8] = cosVal + minusVal * axis.z * axis.z;

	vec = m * vec;
}
I keep a frame class that has a up, forward, and position vector and the mouse input part of it follows which relies on the above.

void Frame::update(const vec2 δ)
{
	vec3		right;
	vec3		world_up(0.0f, 1.0f, 0.0f);

//"camera"
	// Left / Right
	rotateVector(-delta.x / 50.0f, forward, world_up);
	rotateVector(-delta.x / 50.0f, up, world_up);
	forward.normalize();
	up.normalize();

	// Up / Down
	right = vec3::crossproduct(up, forward);
	right.normalize();

	rotateVector(-delta.y / 50.0f, forward, right);
	rotateVector(-delta.y / 50.0f, up, right);
	forward.normalize();
	up.normalize();
}
I load these vectors into the opengl modelview matrix, notice that I have to flip the column ordering when I thought it was already in the correct format. This is the only way I can get it will work though.

void Frame::set()

{
	float	matrix[16];
	vec3	right;

	right = vec3::crossproduct(this->up, this->forward);
	right.normalize();

	// Dont ask...
	matrix[0] = right.x;
	matrix[1] = up.x;
	matrix[2] = forward.x;
	matrix[3] = 0.0f;

	matrix[4] = right.y;
	matrix[5] = up.y;
	matrix[6] = forward.y;
	matrix[7] = 0.0f;

	matrix[8] = right.z;
	matrix[9] = up.z;
	matrix[10] = forward.z;
	matrix[11] = 0.0f;

	matrix[12] = -(right * pos);
	matrix[13] = -(up * pos);
	matrix[14] = -(forward * pos);
	matrix[15] = 1.0f;
	glLoadMatrixf(matrix);
}
When I render, I call frame::set above to load my initial modelview matrix, I then render the bsp, loop through my entities and render those, (for the most part they are just boxes with 3x3 identity rotation matrices and world coordinate positions. Entities multiply their matrix ontop of the Frame matrix and render. They appear to be working correctly. (I have some of them spinning in place with an angular momentum setting, so I think the rotation matrix works fine even though I am directly placing world coordinates into this matrix, which should (at least to my mind) be dotted with the rotation matrix first. (rotate before translate right?) But, it works so I'll leave it alone. Every frame I have my first entity get a copy of the camera frame's matrix and have a button to disable this copy so I can move away from the entity and see its orientation. It appears to work fine. (I look up, press control, and the cube is looking up in my previous position. I am trying to add frustum culling by extracting the planes from the projection matrix, the planes appear oriented correctly in eye space. When I multiply them by my first entities matrix, in order to convert them to world space, they appear at the correct coordinates, but are locked straight on the Z axis. If I press control so the matrix becomes static they continue to follow the frame camera instead of staying at the entity. -- That shouldnt be possible... Anyway it could be an issue with how I am drawing the planes. But I'm not sure.

void Plane::draw_plane(Entity &ent)
{
	GLfloat fExtent = 200.0f;
	GLfloat fStep = 10.0f;
	GLint iLine;
	float matrix[16];

	vec3 forward = vec3::crossproduct(normal, vec3(0.0, 1.0, 0.0));
	forward.normalize();
	float magnitude = forward.magnitude();

	if ( magnitude < 0.001f && magnitude > -0.001f)
	{
		forward = vec3::crossproduct(normal, vec3(0.0, 0.0, 1.0));
		forward.normalize();
	}

	vec3 right = vec3::crossproduct(normal, forward);
	right.normalize();

	matrix[0] = right.x;
	matrix[1] = right.y;
	matrix[2] = right.z;
	matrix[3] = 0.0f;

	matrix[4] = normal.x;
	matrix[5] = normal.y;
	matrix[6] = normal.z;
	matrix[7] = 0.0f;

	matrix[8] = forward.x;
	matrix[9] = forward.y;
	matrix[10] = forward.z;
	matrix[11] = 0.0f;

	matrix[12] = 1.0f;
	matrix[13] = 1.0f;
	matrix[14] = 1.0f;
	matrix[15] = 1.0f;

	glPushMatrix();
	glLoadMatrixf(matrix);

	glBegin(GL_LINES);
	for(iLine = -fExtent; iLine <= fExtent; iLine += fStep)
	{
		glVertex3f(iLine, 0, fExtent);    // Draw Z lines
		glVertex3f(iLine, 0, -fExtent);
		glVertex3f(fExtent, 0, iLine);
		glVertex3f(-fExtent, 0, iLine);
	}
	glEnd();
	glPopMatrix();
}
I'll upload entire source files later if you need to see something else to help me out. I'd like to know why I have to transpose my supposedly column matrix before entering it into opengl. Why my little entities spin in place with world position coordinates. And what I need to do to get my frustum culling to work. I've spent waaaay too long aimlessly trying stuff and would like to have things make sense again. Thanks for reading! http://home.swbell.net/aw2001/engine.cpp http://home.swbell.net/aw2001/entity.cpp http://home.swbell.net/aw2001/frame.cpp [Edited by - clipmon on August 26, 2009 6:15:26 PM]

This topic is closed to new replies.

Advertisement