Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Rez Position / Rotations from a child prim

Celty Westwick
Registered User
Join date: 24 Jun 2006
Posts: 145
12-10-2009 09:08
I can get an object to rez an object with position and rotations relative to the child prim from which it is rezzed, even when that object is manually rotated inworld:

CODE

llRezAtRoot("Sample Object", llGetPos() + SampleOffset * llGetRot(), ZERO_VECTOR, llGetRot(), 0);


My difficulty is that when i need to specify a rotation for the rezzed object that keeps the child prims orientation, other than on one axis. This code gets there partially in that it specifies a rotation, but does not maintain the child prim's rotations when the object is rotated manually.

CODE

llRezAtRoot("Sample Object", llGetPos() + <0.036, -0.26, 0.0135> * llGetRot(), ZERO_VECTOR, llEuler2Rot( <79.0, 0.0, 180.0> * DEG_TO_RAD ), 0);


What I need is for the rezzed object to keep the location and Z rotation relative to the child prim, but specify a X and Y rotation. If it helps, think of a compass needle that rather than pointing north, points in whatever way the case is rotated. In other words it acts as if it were a linked prim.

Perhaps a better analogy is a fork rezzed by a placemat (placemat being a child prim of a table) that needs to keep a specific rotation on two axis, but rez pointing in the same direction as a placemat.
Dora Gustafson
Registered User
Join date: 13 Mar 2007
Posts: 779
12-10-2009 11:57
To rezz something with the same rotation as the child you would need the child's global rotation and that is:
rotation RR=llGetLocalRot()*llGetRootRotation(); //(computed in the child)

You want the rezzed object to have a relative rotation in the local system:
rotation myRot=llEuler2Rot( <79.0, 0.0, 180.0> * DEG_TO_RAD );

The global rotation will be:
rotation rezRot=llGetLocalRot()*myRot*llGetRootRotation(); //(computed in the child)

and finally:
llRezAtRoot("Some Object", llGetPos() + SomeOffset , ZERO_VECTOR, rezRot, 0);

The above is not tested in any way and it needs adjustments for the very purpose.
Happy scripting:)
_____________________
From Studio Dora
Celty Westwick
Registered User
Join date: 24 Jun 2006
Posts: 145
12-10-2009 15:07
Ah caught the edits, thanks so much, it does work! Now seeing how I can use most efficiently in the script for a number of different rezzed objects :)
Celty Westwick
Registered User
Join date: 24 Jun 2006
Posts: 145
12-10-2009 22:19
Followup question on this portion:

rotation myRot=llEuler2Rot( <79.0, 0.0, 180.0> * DEG_TO_RAD );

I have a heck of a time getting the correct vector numbers for an object. They are not the same as the vector numbers shown in the client for an object's rotation, and its very trial and error - the errors are a trial. Is there a way to convert the degrees from the client into the vector for this?
Dora Gustafson
Registered User
Join date: 13 Mar 2007
Posts: 779
12-11-2009 02:40
The order in which a prim is turned around the axis does matter. If you change the order you will end up with different rotations. That is one reason I avoid the Euler notation when ever I can.
The discipline of doing the turns in the same order as it is done in the viewer's editor has been discussed in the forum. I don't remember where and when, but you can search for it:)
_____________________
From Studio Dora
Celty Westwick
Registered User
Join date: 24 Jun 2006
Posts: 145
12-12-2009 11:59
OK, I'm still trying to get this one.

This does what I want in that it takes the rotation numbers from the client edit window for the object I want to rezz and replicates the orientation, but it does not "turn" if the rezzing object is turned in-world. The script is in a child prim of a linked object.

CODE

RezAnObject()
{
rotation myRot = llEuler2Rot(<354.95, 281.05, 84.90>* DEG_TO_RAD); // Rotation from inworld object i want to rez,converted to Radians,converted to a Quaternion
llRezAtRoot("SampleObject", llGetPos() + <0.036, -0.26, 0.0131> * llGetRot(), ZERO_VECTOR, myRot, 42);
}

default
{
touch_start(integer num_detected)
{
RezAnObject();
}
}


This does turn when the object is turned, however, it is next to impossible to find the original vector numbers that will orient it correctly.

CODE

RezAnObject()
{
rotation myRot=llEuler2Rot( <354.95, 281.05, 84.90> * DEG_TO_RAD );
rotation rezRot=llGetLocalRot()*myRot*llGetRootRotation();
llRezAtRoot("SampleObject", llGetPos() + <0.036, -0.26, 0.0131> * llGetRot(), ZERO_VECTOR, rezRot, 0);
}

default
{
touch_start(integer num_detected)
{
RezAnObject();
}
}


I have not been able to figure out how to both get it to take the rotation numbers from the edit window and adjust the rotation when the object is turned in-world.
Dora Gustafson
Registered User
Join date: 13 Mar 2007
Posts: 779
12-12-2009 12:48
As I said before I would avoid using Euler rotation. The outcome is not the same when you rotate around X, then around Z as if you do Z, then X. Furthermore: what you read in the editor depends on which mode you are in, global or local.

What I would do was make a small script to tell me the rotation (as a quaternion) of the prim when it is placed the way I want.

Finally: I may have misunderstood what it is that you want. Wasn't it a rezzed prim with the Z axis pointing same way as the Z axis in a child prim?
_____________________
From Studio Dora
Celty Westwick
Registered User
Join date: 24 Jun 2006
Posts: 145
12-12-2009 14:27
"As I said before I would avoid using Euler rotation. The outcome is not the same when you rotate around X, then around Z as if you do Z, then X. Furthermore: what you read in the editor depends on which mode you are in, global or local."

Apparently the issue is regarding that when "rotation rezRot=llGetLocalRot()*myRot*llGetRootRotation();" is performed though i have tried changing this sequence.

"Furthermore: what you read in the editor depends on which mode you are in, global or local."

Not quite sure what you mean on this one. I am manually rezzing the object I want the script to rez, orienting it's rotation as I want it be rezzed to, and starting from those numbers. How would that be changing between a "global or local mode"?

"What I would do was make a small script to tell me the rotation (as a quaternion) of the prim when it is placed the way I want."

Yes not knowing how to make the script itself do the calculating, I tried this as an attempt at a "calculator" script dropped into the intended rezzed object with a desired rotation:

CODE

rotation thequaternionlocal;
rotation thequaternion;

vector as_a_vector;
vector local_as_a_vector;

float component_x;
float component_y;
float component_z;

float rcomponent_x;
float rcomponent_y;
float rcomponent_z;

float lcomponent_x;
float lcomponent_y;
float lcomponent_z;

float lrcomponent_x;
float lrcomponent_y;
float lrcomponent_z;

default
{
touch_start(integer total_number)
{
//Get the rotation of the child prim
thequaternionlocal = llGetLocalRot();
thequaternion = llGetRot();
// Convert it to a vector
as_a_vector = llRot2Euler(thequaternion);
local_as_a_vector = llRot2Euler(thequaternionlocal);
//Get the x, y & z components of that vector and convert to degrees
component_x = as_a_vector.x * RAD_TO_DEG;
component_y = as_a_vector.y * RAD_TO_DEG;
component_z = as_a_vector.z * RAD_TO_DEG;

rcomponent_x = as_a_vector.x;
rcomponent_y = as_a_vector.y;
rcomponent_z = as_a_vector.z;

lcomponent_x = local_as_a_vector.x * RAD_TO_DEG;
lcomponent_y = local_as_a_vector.y * RAD_TO_DEG;
lcomponent_z = local_as_a_vector.z * RAD_TO_DEG;

lrcomponent_x = local_as_a_vector.x;
lrcomponent_y = local_as_a_vector.y;
lrcomponent_z = local_as_a_vector.z;

// Say the vector components
llOwnerSay("The rotation in degrees is <" + (string)( component_x) + ", " + (string)( component_y) + ", " +(string)( component_z) + " > ");
llOwnerSay("The rotation in radians is <" + (string)( rcomponent_x) + ", " + (string)( rcomponent_y) + ", " +(string)( rcomponent_z) + " > ");
llOwnerSay("The local rotation in degrees is <" + (string)( lcomponent_x) + ", " + (string)( lcomponent_y) + ", " +(string)( lcomponent_z) + " > ");
llOwnerSay("The local rotation in radians is <" + (string)( lrcomponent_x) + ", " + (string)( lrcomponent_y) + ", " +(string)( lrcomponent_z) + " > ");
llOwnerSay("thequaternionlocal is " + (string)thequaternionlocal);
llOwnerSay("thequaternion is " + (string)thequaternion);
}
}

An example result was:

[14:22] Fork: The rotation in degrees is <78.983185, 1.988623, -179.555481 >
[14:22] Fork: The rotation in radians is <1.378517, 0.034708, -3.133834 >
[14:22] Fork: The local rotation in degrees is <78.983185, 1.988623, -179.555481 >
[14:22] Fork: The local rotation in radians is <1.378517, 0.034708, -3.133834 >
[14:22] Fork: thequaternionlocal is <-0.01092, 0.63592, -0.77155, 0.01403>
[14:22] Fork: thequaternion is <-0.01092, 0.63592, -0.77155, 0.01403>

Perhaps I got confused in doing the calculation I need but tried these and it did not get me there. one issue being i did not undertand how to incorporate the 4 variable quaternian result into the the script.

"Finally: I may have misunderstood what it is that you want. Wasn't it a rezzed prim with the Z axis pointing same way as the Z axis in a child prim?"

Yes that's what I want to achieve, and your method does that if i had a way to figure out what rotations to feed it, either using as you said a calculation script or in the script itself using the edit window rotations.

Sorry to be such a pain, rotations just make my head spin (pun semi-intended).
Dora Gustafson
Registered User
Join date: 13 Mar 2007
Posts: 779
12-12-2009 15:18
:D you are not the first and not the last. Myself I try to think of something else not to have my head spin.
It looks to me as you make the detector script much more complicated than needed. I was thinking of a one liner like this:
llOwnerSay((string)llGetLocalRot());

But let that rest. I would like much more if you could approach the problem from another side:

You know the child's Z axis is the axis you will turn the rezzed object around. If you know the angle to rotate it, you can obtain the rotation like this:
float angle='your angle in radians';
rotation myRot=llAxisAngle2Rot(< 0.0, 0.0, 1.0 >, angle);
and:
rotation rezRot=llGetLocalRot()*myRot*llGetRootRotation(); //(computed in the child)

This way you wouldn't need Euler rotations at all:)

Look at all the handy rotation functions here:
http://www.lslwiki.net/lslwiki/wakka.php?wakka=rotation
_____________________
From Studio Dora
Celty Westwick
Registered User
Join date: 24 Jun 2006
Posts: 145
12-12-2009 18:32
I appreciate your help, just does not seem to work for me, I tried your last suggestion, I get odd results, and it moves the location the object is rezzed as well. Oh I had already read the wiki pages many times, just gets me more confused, each time, LOL.
Celty Westwick
Registered User
Join date: 24 Jun 2006
Posts: 145
12-12-2009 22:48
I did find a solution, though not elegant, I used a "cheater" prim with 0,0,0 rotation for each rezzed object, which allows everything to work fine:).