Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Relative Rotations

Foxglove Fizz
Registered User
Join date: 6 May 2005
Posts: 6
06-05-2005 16:31
Hi ho,

I'm new to this whole evil rotation (quaternions) thing.

What I want to do is fairly simple, I want to rotatate non-linked prims in relation to an single anchor refrece prim. When I adjust the roation of the anchor, I need everthing else to turn the same amount.

seems like I could do something simple like
delta=anchorOldRotation-anchorNewRotation
would work, but I cant figure out the trick.


I'm building a mini verison of a primative animator, ala-poser, but all tools are in game.
So for each keyframe I need to store a relative rotation to the anchor. At playback I playbak a rotation for each prim based upon the current anchors rotation.

Anyone got any words of wizdom to help me out with this?

Thanks much for any help you can give.
Jeffrey Gomez
Cubed™
Join date: 11 Jun 2004
Posts: 3,522
06-05-2005 17:46
Sure! This is simple enough.

CODE
vector anchor = <1,1,1>; // Say your anchor position is <1,1,1>
rotation anchor_rot = <1,0,0,0>; // And it's rotated at 180 degrees on the X axis

// Now, let's say you want your child object to go three meters forward on the Z axis
// of the anchor. You would do something like this:
llMoveToTarget(anchor + (<0,0,3> * anchor_rot),0.3);

// Multiplying a quaternion times a vector gives you the vector
// in the relative frame of reference!
//
// Dividing out the quaternion will do the reverse; it'll take you
// out of that frame of reference.

// For movement, let's say you want to rotate this 30 degrees on the Z axis now.
anchor_rot = llEuler2Rot(<0,0,30> * DEG_TO_RAD) * anchor_rot;

// Multiplying quaternions is useful because it gives you the new rotation
// Be careful though! Always place the reference rotation second, because
// the order of operations matters!

// Here's your new relative position:
llMoveToTarget(anchor + (<0,0,3> * anchor_rot),0.3);

// Huzzah!


For a more complex example, I did my own prim animator several months back. You can find it here:

/15/da/37403/1.html
_____________________
---
Foxglove Fizz
Registered User
Join date: 6 May 2005
Posts: 6
Relative Rotations (simple ???)
06-06-2005 20:07
Ignore all below I got it working based on your post, thanks much J... at some point I'll have to dig up the math on why it works but for now the fact that it does is good enought

here is the working playback code for one of the child objects.

last_rot = llList2Rot(movementrot,playindex); //recorded keyframe new rot
last_pos = llList2Rot(movementpos,playindex); //recorded keyframe new pos
anchorpos = (vector)llList2String(inputlist,2); //current anchor pos
anchorrot = (rotation)llList2String(inputlist,3); //not using yet...

currentpos= last_pos+anchorpos;
diff = currentpos - anchorpos; not needed // i dont need these steps last_pos
llMoveToTarget(anchorpos+(diff*anchorrot),strength);
llRotLookAt(last_rot,strength,strength); // need to fix this still --- Move to last rotation

J your fix on the llmovetotarget works cuz I assure that the orientation of the anchor is <0,0,0> during the recording. Now they are in the correct postion in 3d space, I still need to fix the llRotlookat line to refect their new rotation bassed upon their original rotation in the recording but I think I can do that.

Thanks for your help.

Foxglove...


Ignore all below I got it working based on the last post...

Thank for your quick response Jeffrey. I'm not worthy... but since your here :)

FYI: This idea was actually sparked by your BVH importer script. I've studied it much and used the %1 I understood to get this far. Im a decient .asp/java programmer but this 3d math is killing the few brain cels i have left. I just thought it would be cool to have something simple that was all in-game so that people could it use to build their own lightweight prim animations. No skeletal structure or anything, just the ability to record keyframes and play 'em back.

Back to the problem...
Your example uses hard numbers and I'm foggy on getting from the recorded values I have to plug into it.

I also realized that based on your answer I didnt undertand the problem, and now I am not even sure I can get where I want to go... take a look at this.

1st off my design premise may not be correct in reguard to the data I am recording.
My though was simple, build a bit of code that can listen and record the position and current roations of all prims im animating, store those in an array. Playback the positions(vector) and rotations in order and boom, you have duplicated the motion and have animation.

My proof of concept worked perfectly, it recorded each node(I call each animatable prim a node) both vector llGetPos() and rotation llGetRot() a stored it. On playback they all followed the recorded pattern down to the rotations and all. No problem.
Then I modified it to use the anchor as the zero point for determining the vector. On playback I can grab the anchor and move it x,y,z and the animation follows while still playing. However I have no way of rotating the anchor and effecting all the vector postion and relative rotations.

So I have this info recorded:
anchor pos = llGetPos
anchor rot = llGetRot

And for every frame of animation I have recorded the llGetPos and llGetRot for each node.

So can I get done what I want with what I have recorded or do I need to be capturing diffrent data.
What SHOULD I capture for each node per frame, and what should playback to orient things properly based on the anchor.

Honestly I figured that the bulk of coding for this animator would be the tools around the animation cotrol and editing panel, you know adding and removing frames etc... I would think that this should be the easy part, little did I know.


------------- Below are bits of the record and playback code.
RECORD:
This code runs in the anchor object, which acts as the recorder for each keyframe:
It listens for the nodes to say what their postions are. When it hears that command it records it from a list called input
centerpos =llGetPos();
centerrot =llGetRot();
adjustedpos=(vector)llList2String(input,2)-centerpos;
adjustedrot=(rotation)llList2String(input,3); //this will never be tweakable to work :(
movementframe += (integer)frame;
movementobject += (string)llList2String(input,1);
movementpos += adjustedpos;
movementrot += (rotation)llList2String(input,3);


PLAYBACK:
Upon playback, each node in the animation runs this code to play back the frame, I simply reverse the operation bassed upon the anchors current location. I pass this to the node with a shout on a private chanel and place it into inputlist prior to this point.
newpos = llList2Vector(movementpos,playindex); // the recorded value for this frame
newrot = llList2Rot(movementrot,playindex); // the recorded value for this frame
anchorpos = (vector)llList2String(inputlist,2);
// anchorrot = (rotation)llList2String(inputlist,3); //not using yet...
llMoveToTarget(newpos+anchorpos,strength); // Move to last location
llRotLookAt(newrot,strength,strength); // Move to last rotation