I'm working on a bullet/missile class for my 3D game and I'm struggling with trying to figure out how to construct the rotation matrix to have my mesh oriented with the direction of my velocity vector (a Vector3). It seems like it should involve two rotations (since one axis will be the up-vector) and probably a little bit of Math.atan2 magic. Can anyone help me out

Orienting 3D objects along a velocity vector
erikkl2000
where's the velocity vector coming from is it constant Usually what I do is something similar to this:
Bullet CreateBullet( float radians )
{
Matrix rotation = Matrix.CreateRotationY( radians );
Bullet result = new Bullet();
result.velocity = rotation.Forward;
result.orientation = rotation;
}
alternatively, instead of keeping a seperate velocity vector, you could store a speed scalar, and move the bullet along orientation.Forward * speed;
does that help at all
( wish i could figure out how to get rid of these double spaces )
Dual Cortex
Divided by the product of their magnitudes. I'm typing this from work and don't have the XNA docs in front of me and can't remember the function names but mathematically it would look something like this.
v1=natural direction
v2=direction you want to point.
vaxis=cross_product(v1,v2)
angle=acos( dot(v1,v2)/( v1.Magnitude()*v2.Magnitude()))
you could also use the vaxis from the cross product instead
angle=asin(vaxis.Magnitude()/(v1.Magnitude()*v2.Magnitude()))
The second would have the advantage of also going to zero for small angles so might be more stable at small angles. The first would tend to degrade if the angle is small. I don't know if you need to provide a unit vector to the function which creates rotation matrices about an arbitrary axis so you might have to normalize your axis first.
I may have a sign wrong but that should be obvious the first time you try it and it would be easy to fix.
those aren't the right functions but hopefully it would be easy to plug them in with documentation in front of you. You need to understand what's going on anyway with this stuff so cut and pasting code which isn't understood is, in my opinion, a bad idea.
If the argument inside acos is over 1.0 by even a TINY amount the result becomes undefined and it will return NaN instead so put a ceiling at 1.0. Also make sure to check for the case where the model is already pointing in the direction you want it to point. You should probably treat that case seperately since your axis would become undefined.
This may be numerically unstable for very small angles. This also doesn't help with how the model is rolled along it's direction of travel.
It seems like it ought to be possible to use the function for creating the view transformation, substituting the location of the model for the location of the camera and the look at point for something along the direction you want it to point. It might be necessary to have all objects' natural direction be standard or at least put in a transform to get them all pointing in a standard direction before applying this "view" transformation. That approach would even have the advantage of letting you set the right rotation about the axis you're traveling (unless your object is a featurless cylinder or cone or somthing you'll want to do that).
Sorry for being so vague in spots. Comes from trying to post from work. Hopefully that will be helpful.
Alvin Kuiper
A single velocity vector is not enough because you could be looking down a vector and rolling, you are still aligned with the velocity vector but at different orientations. I'd suggest maintaining a heading (velocity) and an up vector (well, a right vector too to make pitching, etc. easy but this is not strictly needed for the problem you have).
Here is the algorithm I use it works a treat. It's surprisingly simple, I wont go into the math, but essentially you can plop the vector information directly into the matrix with very little alteration. The code extract is from my BaseModel classso is a property that I can call upon from any of my scene models. See below...
public Matrix WorldMatrix{
}
Hope this helps...
Kind Regards,
James
Luislcm
EDIT: oh but it appears that this is a latent effect of putting a - sign in front of the Cross product. Hmm...
patio87
If you hit ENTER....
...you get a double space....
If you hit SHIFT+ENTER...
...you get a single space.
Phil Nicholas
I seem to have gotten part of the way there with Gerix's explanation. This is how my code goes at the moment:
Matrix world = Matrix.Identity; // create an identity matrix to start with
Vector3 v1 = new Vector3(0, 1, 0); // the model's natural direction
Vector3 v2 = bullet.velocity; // the bullet's velocity
Vector3 vaxis = -Vector3.Cross(v1, v2); // not sure why, but the - sign seems to get my closer to what i'm looking for
float angle = (float)Math.Asin(vaxis.Length() / (v1.Length() * v2.Length()));
world *= Matrix.CreateRotationX(MathHelper.Pi);
// the model needs to be flipped along its local X axis for some reason.
// Simply flipping the natural direction vector doesn't produce the same effect
world *= Matrix.CreateFromAxisAngle(vaxis, angle); // rotate the model about the axis
world *= Matrix.CreateTranslation(bullet.position); // translate to the bullet's position
So with this code, the tip of the bullet model points in the direction of the velocity vector, but there is some unwanted roll (along the model's local Y axis). I'm not really sure if the vector i have specified for the model's natural direction is correct. The tip of the bullet is pointing straight up the y axis. I tried experimenting with different values for the X and Z of the natural direction vector, but the results were very funky looking. Same goes for using the inverse cosine method of getting the angle. That produced some really weird results, so I decided to pursue the inverse sine method you gave me.
Anyway, that's where I'm at for the moment. I feel like the natrual direction vector is part of my problem at the moment. Can anyone further clarify how to find this Thanks.
Dr.Virusi
If you take the cross product of the models natural direction vector, and the direction you want it to be going, that should give you a vector you can use as the axis.
I think the angle will be something like inverse cosine of the dot product of the two vectors.
ZopoStyle