How to rotate an object to terrain normal

Started by
12 comments, last by soconne 16 years, 10 months ago
Once you get the angle between the terrain normal and the player's normal, you then need to find the cross product and rotate around it........not all 3 axis.

So....

float angle = Dot(...);
Vec3 cross = CrossProduct(...);
cross.normalize();

rotationMatrix.rotate(angle, cross.x, cross.y, cross.z);
Author Freeworld3Dhttp://www.freeworld3d.org
Advertisement
Thanks for the reply soconne, here is what I have but am sure its wrong...

void RotatePlayerToTerrainNormal(Player *player, Camera &camera){	Matrix4x4 rotationMatrix;	vec3 terrainNormal = gterrain->GetTerrainNormal(camera.View.x, camera.View.z);	vec3 player1Normal = vec3(player->model->Objects->Normals[3],							  player->model->Objects->Normals[4],							  player->model->Objects->Normals[5]);		float angle = Dot(terrainNormal, player1Normal);	vec3 crossProduct = Cross(terrainNormal, player1Normal);	crossProduct.Normalize();	rotationMatrix.Rotate(angle, int(crossProduct.x), int(crossProduct.y), int(crossProduct.z));		//vec4 tempRotation = rotationMatrix.VectorMatrixMultiply3x3(player1Normal);	player->model->rot.x = RADTODEG(rotationMatrix.matrix[12]);	player->model->rot.y = RADTODEG(rotationMatrix.matrix[13]);	player->model->rot.z = RADTODEG(rotationMatrix.matrix[14]);	//player->model->rot.x = RADTODEG(tempRotation.x);	//player->model->rot.z = RADTODEG(tempRotation.z);}
u have players forward direction vector (Z) + terrain normal(Y)
crossproduct will give u (X)
Quote:Original post by MARS_999
Thanks for the reply soconne, here is what I have but am sure its wrong...

*** Source Snippet Removed ***


Its wrong because you're causing the x, y, z values of the cross product to become 0!! That vector is going to have floating point values less than 1.0. Does your rotate function rotate around an arbitrary vector or the main axis?

Here is my function for doing it.

void Matrix4::setupRotate(const Vector3 &axis, float theta) {	// Quick sanity check to make sure they passed in a unit vector	// to specify the axis	assert(fabs(axis*axis - 1.0f) < .01f);	// Get sin and cosine of rotation angle	float	s, c;	sinCos(&s, &c, theta);	// Compute 1 - cos(theta) and some common subexpressions	float	a = 1.0f - c;	float	ax = a * axis.x;	float	ay = a * axis.y;	float	az = a * axis.z;	// Set the matrix elements.  There is still a little more	// opportunity for optimization due to the many common	// subexpressions.  We'll let the compiler handle that...	m[0] = ax*axis.x + c;	m[1] = ax*axis.y + axis.z*s;	m[2] = ax*axis.z - axis.y*s;	m[4] = ay*axis.x - axis.z*s;	m[5] = ay*axis.y + c;	m[6] = ay*axis.z + axis.x*s;	m[8] = az*axis.x + axis.y*s;	m[9] = az*axis.y - axis.x*s;	m[10] = az*axis.z + c;	// Reset the translation portion	m[12] = 0.0f; m[13] = 0.0f; m[14] = 0.0f; m[15] = 1.0f;}


So you're code should stay the same, except after you call the above function, you need to actually store the entire new matrix and NOT just 3 simple values like you're doing. In my application I store a 3x3 rotation matrix for each object, not just a x,y,z rotation vector. I'm not sure if you can fully represent the proper rotation that way.
Author Freeworld3Dhttp://www.freeworld3d.org

This topic is closed to new replies.

Advertisement