Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

rotations hurt my brain, this should be trivial!

Ged Larsen
thwarted by quaternions
Join date: 4 Dec 2006
Posts: 294
12-12-2006 07:34
New to SL and scripting, and I'm sorry to post what should be a _trivial_ script, but I can not get this to work the way I want to.

Goal is to rez a number of objects arranged in a circle around the script-containing prim, keeping the rezzed objects facing outwards (which works), and with each object "flaring outwards" a constant amount (which does NOT work).

The problem seems to be with calculating the proper rotation of the rezzed object, to have it flare out. It _appears_ to work with a low angle of flaring out, but if you set the flaring out angle to 80 degrees, you can see a "twist" to each object that is not wanted.

I suppose a REALLY kludgy work-around, that avoids my understanding the rotations, would be to have each rezzed object contain a script that would have it OnRez rotate itself by the flare angle about it's own local Y-axis, but I'd rather just have the object rezzed in proper rotation to begin with.

Please help :(

CODE
// from Ariane Brodie's: http://virtualunderworld.net/arianeb/secondlife.htm

// attempts to rez a number of objects in a 1m radius circle, all facing "outwards", and flaring out a set amount
// ** doesn't work **

string object = "test object"; // object to use
integer numObjects = 12; // how many objects
float flareAngle = 80.0; // rez the object flaring outwards this number of degrees

make()
{
integer n; // step
float theta; // angle in radians
vector pos; // position
vector rotEul; // rotation in euler
rotation rot; // rotEul in quaternion rot format

for(n = 1; n <= numObjects; n++) {
theta = TWO_PI * ( (float)n / (float)numObjects );
llOwnerSay((string)n);

pos.x = llCos(theta); // 1m radius circle, 2m above rezzing object
pos.y = llSin(theta);
pos.z = 2;
pos = pos + llGetPos();

rotEul.x = flareAngle * DEG_TO_RAD * llSin(theta); // supposed to set flaring out
rotEul.y = -1*flareAngle * DEG_TO_RAD * llCos(theta); // supposed to set flaring out
rotEul.z = theta; // makes the object face "outwards"

rot = llEuler2Rot(rotEul);

llRezObject(object, pos, ZERO_VECTOR, rot, 0);
}
}
Yumi Murakami
DoIt!AttachTheEarOfACat!
Join date: 27 Sep 2005
Posts: 6,860
12-12-2006 08:54
Forgive my possible lack of geometry knowledge, but do you really mean to multiply the x and y components of the rotation by the sin and cos of theta? Multiplying an angle by a distance?
Kitsu Nico
Registered User
Join date: 2 Jul 2005
Posts: 11
12-12-2006 09:30
I hope this is what you were trying to achieve, and that I understood the question properly. If not, then time for another.

CODE


// from Ariane Brodie's: http://virtualunderworld.net/arianeb/secondlife.htm

// attempts to rez a number of objects in a 1m radius circle, all facing "outwards", and flaring out a set amount
// ** doesn't work **

string object = "test object"; // object to use
integer numObjects = 12; // how many objects
float flareAngle = 80.0; // rez the object flaring outwards this number of degrees

make()
{
integer n; // step
float theta; // angle in radians
vector pos; // position
vector rotEul; // rotation in euler
rotation rot; // rotEul in quaternion rot format

for(n = 1; n <= numObjects; n++) {
theta = TWO_PI * ( (float)n / (float)numObjects );
llOwnerSay((string)n);

pos.x = llCos(theta); // 1m radius circle, 2m above rezzing object
pos.y = llSin(theta);
pos.z = 2;
pos = pos + llGetPos();

// rotEul.x = llSin(theta); // supposed to set flaring out
// rotEul.y = -1*llCos(theta); // supposed to set flaring out
rotEul.z = theta; // makes the object face "outwards"

rot = llEuler2Rot(rotEul);

rot = llEuler2Rot(<0,flareAngle*DEG_TO_RAD,0>)*rot;

//alternate quaternion form:
// rot = <0,llSin(flareAngle*DEG_TO_RAD*/2),0,llCos(flareAngle*DEG_TO_RAD/2)>*rot

llRezObject(object, pos, ZERO_VECTOR, rot, 0);
}
}





I commented out the x and y components of rot, to leave just the z so that they just face out, and upwards. Then applied local rotation with this line:

CODE

rot = llEuler2Rot(<0,flareAngle*DEG_TO_RAD,0>)*rot;


If you multiply in that order, it is a local rotation. If you reverse the order of multiplication, like...


CODE

rot = rot*llEuler2Rot(<0,flareAngle*DEG_TO_RAD,0>);


...it will rotate on Y:80 degrees, globally.

Commented below that line, is an alternate way of doing it, using a quaternion directly. Quaternions are easy to use, if you're rotating on just a single axis.

http://www.lslwiki.com/lslwiki/wakka.php?wakka=quaternions
Ged Larsen
thwarted by quaternions
Join date: 4 Dec 2006
Posts: 294
12-12-2006 10:23
From: Kitsu Nico
I hope this is what you were trying to achieve, and that I understood the question properly. If not, then time for another.
..snip..
I commented out the x and y components of rot, to leave just the z so that they just face out, and upwards. Then applied local rotation with this line:
CODE

rot = llEuler2Rot(<0,flareAngle*DEG_TO_RAD,0>)*rot;


If you multiply in that order, it is a local rotation. If you reverse the order of multiplication, like...
CODE

rot = rot*llEuler2Rot(<0,flareAngle*DEG_TO_RAD,0>);


...it will rotate on Y:80 degrees, globally.

Commented below that line, is an alternate way of doing it, using a quaternion directly. Quaternions are easy to use, if you're rotating on just a single axis.

http://www.lslwiki.com/lslwiki/wakka.php?wakka=quaternions


Thank you, that is PERFECT.

As soon as I read your reply, it rang a bell that using quaternions and multiplying in different orders would achieve local vs. global rotations -- I should have remembered that.

Thanks again, much appreciated.