x


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.

more ▼

asked Feb 14 '10 at 10:09 PM

Jerdak gravatar image

Jerdak
166 8 9 13

(comments are locked)
10|3000 characters needed characters left

3 answers: sort voted first

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

more ▼

answered Feb 15 '10 at 03:45 PM

bruceb gravatar image

bruceb
174 6 7 12

(comments are locked)
10|3000 characters needed characters left

You could convert the absolute rotation to a relative rotation by multiplying it with the inverse of the current rotation.

more ▼

answered Feb 14 '10 at 11:16 PM

Jaap Kreijkamp gravatar image

Jaap Kreijkamp
6.4k 20 26 70

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 Max. 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.

Feb 14 '10 at 11:34 PM Jerdak
(comments are locked)
10|3000 characters needed characters left

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);
    }
}
more ▼

answered Feb 15 '10 at 12:08 AM

Jerdak gravatar image

Jerdak
166 8 9 13

(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x1273
x436
x124
x11

asked: Feb 14 '10 at 10:09 PM

Seen: 2754 times

Last Updated: Feb 14 '10 at 10:09 PM