- Home /
Manual Quaternions
For some reason I can't seem to wrap my head around this problem. Basically I have a series of quaternion orientations being supplied to Unity3D from an external program. The orientations are being pulled from a mocap system I'm using.
The orientations I get from the system are relative to a single global coordinate system. So they aren't related to any sort of parent transform.
The problem that I'm having is that I can't figure out where to supply my transformations. Because they aren't cumulative (IE, each orientation I get is the actual orientation and not the change since the last one) I can't use the update methods supplied.
Answer by bruceb · Feb 15, 2010 at 03:45 PM
Here is the snippet of code that will give the localRotation of a child relative to its parent if you have the 2 world rotations.
childObj.transform.localRotation = Quaternion.Inverse(childObj.transform.parent.rotation) * theChild.transform.rotation
Answer by Jaap Kreijkamp · Feb 14, 2010 at 11:16 PM
You could convert the absolute rotation to a relative rotation by multiplying it with the inverse of the current rotation.
Hmm, I'm a touch confused. Doesn't that just subtract out the current rotation from the absolute rotation? So if I've already rotated 45 degrees about X and I tell it to rotate 90 about X it will only rotate another 45?
This is fine except for 2 things: 1.) The current rotation of my object's limb was set in 3DS $$anonymous$$ax. So the base rotation for the arm, for example, is already at Euler(5,5,0). When I rotate that by 90 around X it should be 90 + what I already have. 2.) This doesn't seem take in to account if I rotate my person in the scene.
Answer by Jerdak · Feb 15, 2010 at 12:08 AM
I'll be the first to admit my understanding of all of this is tenuous at best.
The following is my solution. Visually it seems to work as I want. The part I find slightly off is the conversion of the quaternion axis by the current base orientation. I did this on a whim to see what would happen. Oh and for some reason it won't rotate about the x-axis unless I update the z value of my quaternion?
public class Keyboard : MonoBehaviour { public GameObject objArm; public GameObject pivot; private Vector3 objPosition; private Quaternion objRot; private Quaternion lastRot = Quaternion.identity;
private float rot = 0.0f;
private int rotDir = 1;
public float rotationIncr = 0.1f;
private bool updateFromParent = false;
///Called from MouseLook.cs to tell player controller it's base orientation is in need of update
void UpdateRotationFromParent(){
objArm.transform.rotation = pivot.transform.rotation;
objRot = objArm.transform.rotation;
updateFromParent = true;
RotateArm(lastRot);
}
// Use this for initialization
void Start () {
Screen.showCursor = false;
Screen.lockCursor = true;
UpdateRotationFromParent();
}
// Update is called once per frame
void Update () {
if (Input.GetKey ("escape")) {
Application.Quit();
}
UpdateArm();
}
void RotateArm(Quaternion q){
float angle = 0.0f;
Vector3 axis = Vector3.zero;
q.ToAngleAxis(out angle, out axis);
///Reorient axis of rotation to current object rotation
axis = objRot * new Vector3(axis.x,axis.y,axis.z);
//print("Rot: " + rot + " Axis: " + axis + " Angle: " + angle + " objRot: " + objRot);
objArm.transform.rotation = objRot;
objArm.transform.RotateAround(pivot.transform.position,axis,angle);
}
void UpdateArm () {
{ ///Update rotation to simulate movement about Z axis from 0-90
rot += rotationIncr * (float)rotDir;
if(rot > 90.0f || rot < 0.0f){
rotDir *= -1;
}
}
///
Quaternion q = Quaternion.Euler(rot,0.0f,0.0f);
lastRot = q;
RotateArm(q);
}
}
Your answer
Follow this Question
Related Questions
Quaternion rotation with normals bug: Only works into one direction? 1 Answer
Quaternion.LookRotation() doesn't look down 2 Answers
Transform global quaternion from local quaternion 2 Answers
How to instantiate on custom rotation? 1 Answer
How to smoothly rotate to certain directions using input axis 1 Answer