Unfortunately, you're going to see a lot of Matrix and Vector stuff when dealing with orientations and transformations just because it's far easier to correctly compute things in such a form. The 'three angle' orientation representation is limited and will almost always cause some annoying problem.
Here's the general way I would approach computing a matrix that fits something to a normal:
Code: Select all
Matrix alignToSurface;
float tiltAngle = (float)Math.Acos(normal.Y); //This is equivalent to arccos(normal dot upvector), since the up vector is (0,1,0)
if(tiltAngle > SomeSmallValue) //Don't want to normalize something that results in almost dividing by zero
{
Vector3 tiltAxis = Vector3.Normalize(Vector3.Cross(normal, Vector3.Up)); //This could also be 'simplified' since the up vector is (0,1,0), but it would take more work :)
alignToSurface = Matrix.CreateFromAxisAngle(tiltAxis, tiltAngle);
}
else
alignToSurface = Matrix.Identity;
If you want the board to tip forward and back only, then you need to compute the angle to rotate around the character's 'sideways' axis. This is similar to how you'd calculate an angle on a traditional 2d graph, using the Math.Atan2 function. The problem is, what are x and y? We need an X and Y axis to 'measure' the normal against to find out. Fortunately, we know two axes that are perpendicular to the sideways axis- the movement direction, and the up vector. We can dot against those axes to get the x and y component, plug them into the Atan2, and get the angle.
But what is the sideways axis that is being rotated around? We can get it directly from the movement direction, rotated by 90 degrees. For our movement direction (x, z), the sideways axis is (z, 0, -x). Try drawing the points on a graph and rotating it to visualize why this is, or use the fact that the dot product between the two (2d) vectors is 0, meaning they are perpendicular.
So the code would look something like this:
Code: Select all
Vector3 movementDirection3D = new Vector3(movementDirection.X, 0, movementDirection.Y);
float x = Vector3.Dot(movementDirection3D, normal);
float y = normal.Y; //Again, Vector3.Dot(normal, Vector3.up) is equivalent to just normal.Y
float pitchAngle = (float)Math.Atan2(y, x);
Vector3 sidewaysDirection = new Vector3(movementDirection.Y, 0, -movementDirection.X);
Matrix alignToSurface = Matrix.CreateFromAxisAngle(sidewaysDirection, pitchAngle);
The actual entity body of the character should never rotate during any maneuvers (it's possible to do, but you need to be prepared to deal with the consequences), so any rotation will be graphical/gameplay logic, not direct physical dynamics.
To do tricks, you could manage some sort of 'gameplay orientation' matrix or quaternion. One way to rotate it would be to use angular velocities, where the magnitude of angular velocity is the radians per second, and the normalized direction of the angular velocity is the spin axis. Each frame, you could increment the rotation using the velocity (a simple axis angle matrix multiplication for orientation matrices).
In addition, you can measure the total rotation like I mentioned in an earlier post by summing up the velocity * dt. Summing up individual velocity magnitude * dt gives you the total rotation, but you could also sum parts of the angular velocity. For example, by dotting the angular velocity with the world up vector and multiplying by dt, you get a frame's rotation around the up axis. You could also do it in the gameplay orientation's 'local space,' using the gameplay orientation's own up vector instead. The same idea would work for the other axes as well.
To see if a character successfully lands after being airborne, check the tilt angle as shown earlier. If your 'gameplay' orientation compared with the normal shows a small tilt, then you can land. If not, you wipe out.
Be aware that I wrote all of the above in notepad, so I don't guarantee that everything is error free
This might be a lot to digest, but efficiently dealing with matrices/vectors and linear algebra in general is extremely valuable. There's a lot of information out there about it; here's a fairly recent relevant link:
http://stevehazen.wordpress.com/2010/02 ... -3-angles/