FromToRotation and it using vector3.Forward

Hi, when using Quaternion.FromToRotation(Vector3.Forward, TargetDirection) and multiplying that by an objects rotation it rotates that object so that it’s forward vector points in the TargetDirection, correct?

Why do you not feed in the transform.forward instead of Vector3.forward? as I understand it FromToRotation is the rotation that would take the from direction towards the to direction. But Vector3.Forward is just some vector in space that does not point in the forwards direction of the object.

And maybe it can’t be used in any of these ways and I have misunderstood because I can’t get it to work.

Not a math wiz, but I’m pretty sure FromToRotation gives you the difference between directions… like if you’re at 80 degrees and the target is 90 degrees, it gives you a rotation equal to 10 degrees.

If you want to have your transform face a point, use LookRotation instead.

Quaternion lookRotation = Quaternion.LookRotation(target.position - transform.position, transform.up);

// instantly set:
transform.rotation = lookRotation;

// or if you want it to smoothly rotate:
transform.rotation = Quaternion.RotateTowards(transform.rotation, lookRotation, rotation speed * Time.deltaTime);
1 Like

The first vector is the axis you want it to rotate around. If you are rotating the forward direction, you probably want the first to be up.

1 Like

Thx for the replies! yea grozzler that’s the way I think of the function too. it’s like taking the cross product of the from and the to vectors and thus getting the axis of rotation and checking the angle between the vectors and using quaternion.angleaxis i think. but Im wrong so what I think is not that important.

The other methods I know how to use but thanks anyway for a good explanation! I don’t think I can use that in this case because I don’t know the up vector I want and in fact this is a big simplification of what I want to do, but I can post my code a little later.

Hmm that seems like it would be a bad function, I mean there is only one axis to rotate around to reach a certain direction but then not telling the function which axis you want to align with the direction I don’t see how it would work. but I’ll try it.

If you further explain what you’re trying to do then we can offer potential solutions.

2 Likes

Indeed. That function is for pretty specific needs, for looking / pointing at targets there are other approaches.

1 Like

Yes, that’s how it works, but usually not important to know. The effect is that FromToRot(V3.forward, target) gives you an angle to the target, but your z-spin is whatever the angleAxis makes (I think.) Whereas LookRotation(target) has you specify the final z-spin.

Oh, no. That’s like saying x+(5-1) is equal to 4. Setting your rotation directly to FromToRotation(forward, target) makes you face that way (lookAt is a shortcut for that math.) But using currentRotation*yourFormula adds it (using local space.)

1 Like

Thx so much for all replies. Did not expect it. I’m making an inverse kinnematics system, it calculates the rotation it wants to be applied in two steps. In the first step I’m not rotating the object but store the axis i want it to have and the second step looks at these axis and rotates them again. Anyway that part works and here is that code:

r = Quaternion.FromToRotation (BoneVector[n-1, 1],BoneVector[n-1,2]);
forward [n-1, 2] = r*forward [n-1,1];
right [n-1, 2] = r *right[n-1, 1];
up [n-1, 2] = r*up [n-1, 1];
t[n].transform.rotation = Quaternion.LookRotation(forward[n,2],up[n,2]);

BoneVector[i,j] is the vector along the object “i” which could be something else than the objects forward vector. j is 0,1, or 2. a value of 0 means the direction before any rotation, a value of 1 is after tha first rotation and 2 is after the second rotation.

Again, that works but this does not. its not understandable without more code shown, but what i would need to show is like 50 lines:

r = Quaternion.FromToRotation (BoneVector[n-1, 1],BoneVector[n-2,2]);
Boneperp1 [n - 1, 1] = r * Boneperp1 [n - 1, 1];//the perpendicular axis to previous bone direction if that bone had pointed straight in the same direction as the bone before that.
Boneperp2 [n - 1, 1] = r * Boneperp2 [n - 1, 1];

What i want to do is rotate a bone to face the direction of its parent. And in doing so i want to check what my up vector became. I’m rotating the bone in various ways around the x and y axis(if z is along the bone), but never around the z axis. So if the bones bonevector started pointing along the parents bonevector but then after some rotations did not, but I rotated it back, the right and up axis would be the same as they were before the rotations. This may be my misstake though.

The thing is that i pretty much want to use the parents right and up Vectors and i have those. But I’m allowing the user to have any forward direction of the bone so it may be that its the -y and z that would point in the x and y direction of this child bone after rotating it back. And i’m allowing the bones to at start not being alligned with each other.

I’m not seeing what the perpendicular parts do – each bone works like a hinge? I assume an actual animator would understand. But this might help:

These two are pretty much the same:

Quaternion r = Quaternion.FromToRotation(bunny1.forward, bunny2.forward);
r = bunny2.rotation*Quaternion.Inverse(bunny1.rotation);

Both are applied as r*startingbunny1Rotation;, and both make bunny1 face the same way as bunny2. The difference (my test program slerps r on 0 to 1 to 0 over and over so you can see the angle) is the second matches bunny2’s local z-roll, by spinning along an axis that will do that. The first just takes the shortest spin, not even trying to match b2’s spin. This should make sense, since FromToRotation takes vectors, so never sees the z-spin.

In other words, suppose bunny1 faces forward, and bunny2 faces up and z-spun 180 so it’s feet face you. #1 will spin straight back, putting the bunny1 with feet away from you. #2 will spin sideways and up, matching the feet exactly when it arrives.

Mathwise, multiplying by the inverse rotation is like subtracting it, so #2 is like r=b2-b1; (except you have to worry about the left or right inverse. I think.) All my notes are in the Vector/Rotation part of www.taxesforcatses (actually, this may be all of them.)

1 Like

Awesome stuff Owen! I got my code to work now, your help lead me on the right track. I kept using FromToRotation but you made me realise how its more properly used.

Doing rotation1 and then rotating back to allign forward with the forward before rotation worked well before. Because rotating it back would use the “oposite” rotation of rotation1 so it lands in the same orientation like before rotation. But when doing rotation1 then rotation2 and rotating back, it lands its orientation in “rotation3, bad”. Now what i do is using… nvm it only works when the bones are all alligned at start. Back to work. But it is not to the fault of these functions anymore.

Alright. Now finally it works. Using Quaternion.Inverse is super powerfull. with it I “store” the difference in rotation of parent and child bone at start. Then when the parent has been rotated in various ways I initially rotate the child bone to have the same rotational offset from its parent and then rotate from there. That way it alligns well with the parent bone the way the dog picture shows if i rotate back to the initial rotation relative to the parent bone.

//At Start:
rotationOffsetFromParent = bonechild.transform.rotation*Quaternion.Inverse(boneparent.transform.rotation);
//

Quaternion tempChildRotation = rotationOffsetFromParent*boneparent.transform.rotation;
childforward = tempChildRotation*Vector3.forward; 
childright  = tempChildRotation*Vector3.right;
childup  = tempChildRotation*Vector3.up;

r = Quaternion.FromToRotation (childforward, targetVector);//if forward is along the bone
childforward=r*childforward;
childright  =r*childright  ;
childup  =r*childup  ;
//Pseudo code, my code actual code does some additional steps that is not relevant to the general use of these functions.