rotation in local mode - clarified
|
|
Christof Babenco
Registered User
Join date: 2 Apr 2007
Posts: 2
|
03-16-2008 08:55
My thanks to everyone who has replied to this question. However, I am going to rewrite this as it is obvious that I have not made the question clear enough - my apologies.
Let's say I rez 4 cubes in front of me (the actual number is immaterial and they are not linked) and I want to send them all a message to rotate 25 degrees in the world x-axis, but at the same time keeping their relative positions.
I can do this in a similar fashion to the answer give by Void Singer.
1) I find the centre of the 4 objects and calculate each object's offset from that centre.
2) I add the 25 degrees rotation to each object (their rotation + 25 degrees)
3) Their new position will have changed by their offset multiplied by the added rotation.
4) I add this to their original position.
So far so good - they will rotate 25 degrees and keep their relative positions. But of course, when I originally rezzed them they had zero rotation and lie firmly in the world axes.
Now let's say I turn 45 degrees and move the cubes in front of me as before (ie. rotating them 45 degrees). If I now send them a message they will rotate and keep their relative postions but their rotation will be a mixture of x-axis and y-axis because they are now longer aligned with the world axes.
To remedy this I can reverse the rotation in 2) above: instead of rotation + 25 degrees I can put 25 degrees + rotation. They will rotate on their local axes (which is what I want) but their relative positions will be compromised.
The question is: how do you calulate the new positions so that they remain relative to their original positions?
|
|
Haplo Voss
Registered User
Join date: 18 Nov 2006
Posts: 137
|
03-16-2008 09:52
I don't know for sure because I'm not looking at your script... but it sounds like you are rezzing the objects, then using local rotations (GetLocalRot, etc...) to achieve your rotation changes in world. If you were to just stick with standard rotations (GetRot, SetRot, etc) then you shouldn't have any drifting or changes in rotation related to the world. so... something like this maybe? vector initialPos; vector nextPos; //in case you need this for some position changes you want to make rotation initialRotation; rotation nextRotation;
default { on_rez(integer rez) { initialPos = llGetPos(); initialRotation = llGetRot(); nextRotation = initialRotation; } state_entry() //So we can edit the script without having to re-rez cubes { initialPos = llGetPos(); initialRotation = llGetRot(); nextRotation = initialRotation; } touch_start(integer num) //assuming you want to do this on click { llSetPos(initialPos); rotation step = llEuler2Rot( <0, 0, 45 * DEG_TO_RAD> ); // change 45 to however many degrees you want to step
nextRotation = llGetRot() * step; llSetRot(nextRotation); } }
Hopefully that helps a little - Hap EDIT: forgot about perfect incriments... sorry. Updated the script after in-world test 
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
03-16-2008 18:58
if I understand, you've locally rotated them individually, physically moved and rotated them globally, and now want to again locally rotate them individually yes?
the same formula you used for the first individual local rotation applies to the next one, namely llSetRot( localAmount2rotate * llGetRot() ); //keeps position, rotates relative to object axis
the second move/rot you are doing manually? it can be achieved with hewee's or my example of rotating around a fixed point either by averaging the prim positions or knowing the ofset for each prim. offset = llGetPos() - [average prim position or known global point] pos = llGetPos() + (offset - offset * localArc) * llGetRot(); rot = localArc * llGetRot() llSetPrimitiveParams( [PRIM_POSITION, pos, PRIM_ROTATION, rot] ); //-- for each prim
I made a non-phys ferris wheel similar to this method by tracking buut not applying the rot for the seats.
_____________________
| | . "Cat-Like Typing Detected" | . This post may contain errors in logic, spelling, and | . grammar known to the SL populace to cause confusion | | - Please Use PHP tags when posting scripts/code, Thanks. | - Can't See PHP or URL Tags Correctly? Check Out This Link... | - 
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
03-16-2008 19:21
Hmm. If you are intending to reverse a rotation before applying a new one, I suggest doing just that: remember the original rotation and modify it from there, instead of going from the current llGetPos() and llGetRot() every time.
No, you can't reverse a rotation after applying another one. It doesn't quite work that way. Take a rubix cube, rotate it +90 about the x-axis, +90 about the y-axis, then -90 about the x-axis. You'll find it doesn't return to its original orientation. You have to reverse rotations in the opposite order they were done, THEN apply new ones if that's what you want to do.
|
|
Ollj Oh
Registered User
Join date: 28 Aug 2007
Posts: 522
|
03-16-2008 19:29
The GOOD sls script wiki has a 4 lines of code for offset rotation: http://wiki.secondlife.com/wiki/Rotation#Rotating_Vectorsrotation rot6X = llEuler2Rot(<30, 0, 0> * DEG_TO_RAD ); // create a rotation constant, 30 degrees around the local X axis vector offset = <0, 1, 0>; // create an offset one meter in the global positive Y direction vector rotatedOffset = offset * rot6X; // rotate the offset to get the motion caused by the rotations vector newPos = llGetPos() + (offset - rotatedOffset) * llGetRot(); // move the prim position by the rotated offset amount rotation newRot = rot6X * llGetRot(); // change rot to continue facing offset point //-- same as: llSetPrimitiveParams( [PRIM_POSITION, llGetPos() + (gPosOffset - gPosOffset * gRotArc) * llGetRot(), PRIM_ROTATION, gRotArc * llGetRot() );
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
03-16-2008 19:39
hehe I just fixed and updated that entry a week or so ago ollj =) if anyone knows french or japanese it needs translated and applied to those pages.
_____________________
| | . "Cat-Like Typing Detected" | . This post may contain errors in logic, spelling, and | . grammar known to the SL populace to cause confusion | | - Please Use PHP tags when posting scripts/code, Thanks. | - Can't See PHP or URL Tags Correctly? Check Out This Link... | - 
|
|
Lyndzay Meili
Registered User
Join date: 2 Sep 2007
Posts: 28
|
03-21-2008 21:52
From: Ollj Oh //-- same as: llSetPrimitiveParams( [PRIM_POSITION, llGetPos() + (gPosOffset - gPosOffset * gRotArc) * llGetRot(), PRIM_ROTATION, gRotArc * llGetRot() );
This line is missing a closing straight bracket "]" does it go after the last llGetRot() ? I've been following this thread because I've been working on a project where I need to rotate an attachment (3 linked prims) from behind my back to over my head and back again. I've been cobbling together a script with that goal but all I manage to do is consistently gt the objects to shoot off to my left side about 2 meters and rotate in that position.
vector initialPos; rotation initialRotation; vector gPosOffset; rotation gRotArc;
default {
attach(key id) { initialPos = llGetPos(); initialRotation = llGetRot(); llListen(772,"",NULL_KEY,""); }
listen(integer channel, string name, key id, string message) { llSetPrimitiveParams( [PRIM_POSITION, llGetPos() + (gPosOffset - gPosOffset * gRotArc) * llGetRot(),PRIM_ROTATION, gRotArc * llGetRot()] ); //is this the right place for this line? if (message == "open") { llSetPos(initialPos); rotation step = llEuler2Rot( <0, 5, 0 * DEG_TO_RAD> ); //real ## not set just for testing } else if (message == "close") { //move it back to original position //well that's the goal } else { llOwnerSay("say open or close only"); } }
}
Also is it better to create a 4th prim to serve as the rotation point since the 3 other prims are just floating in a semi circle? Any help is greatly appreciated, even a kick in the right direction hahaha  thx Lyndz
_____________________
"Be who you are and say what you feel, because those who matter don't mind, and those that mind, don't matter." —Dr. Seuss
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
03-22-2008 00:18
From: Lyndzay Meili This line is missing a closing straight bracket "]" does it go after the last llGetRot() ? yes, good catch, will fix that now.
_____________________
| | . "Cat-Like Typing Detected" | . This post may contain errors in logic, spelling, and | . grammar known to the SL populace to cause confusion | | - Please Use PHP tags when posting scripts/code, Thanks. | - Can't See PHP or URL Tags Correctly? Check Out This Link... | - 
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
03-22-2008 11:43
From: Lyndzay Meili I need to rotate an attachment (3 linked prims) from behind my back to over my head and back again. I've been cobbling together a script with that goal but all I manage to do is consistently gt the objects to shoot off to my left side about 2 meters and rotate in that position. I believe there is a bad bug that affects attachments in this regard. You may want to simply record the positions after the prims have been positioned using the editor, then have the script rotate/toggle between the saved positions/rotations.
|