|
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  // 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.
// 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: 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... 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: 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... 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=quaternionsThank 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.
|