From Second Life Wiki
Jump to: navigation, search

Default Rotation etc

It's a good script but the rotation code leaves much to be desired. If the user specifies in the objects description that it should have a zero rotation, the script currently ignores it. Additionally it forces the user to use Euler notation. You need something like the following, it allows the user to supply either a quaternion on Euler. <lsl> //Creator: Strife Onizuka //

rotation AngleString2Rot(string in, rotation bad){

   //we test if it is an angle type we can use by:
   //1) parse input and see if it has a value
   //2) flip the sign of an element and test again.
   rotation r = (rotation)in;
   if(r)//it's a rotation (or something greater)
       return r;//by greater it might be <x,y,z,s,...>
   vector v = (vector)in;
   if(v)// it's not a rotation but it is a vector
       return llEuler2Rot(v * DEG_TO_RAD);
   //now it's either default or invalid
   //to determine which, we modify the input string and test agian
   //if it passes, we know the result should be ZERO_ROTATION
   integer index = llSubStringIndex(in, "<");
   if(~index) {
       //we insert a negative sign 
       //but we have to remove spaces or they will cause problems
       //we don't care about negative negative zero because
       //breaking the parse is an indication that it did parse.
       in = llGetSubString(in, 0, index) + "-" + 
           llStringTrim(llDeleteSubString(in, 0, index), STRING_TRIM_HEAD);
       if((string)((vector)in) != (string)v)
           return r; 
       //r is Identity but could have negative zero's, waste not want not.
       //the user specified them, we should preserve them.
   return bad;

}//Strife Onizuka 2009, cc-by-sa 3.0

//Less verbose rotation AngleString2Rot(string in, rotation bad){

   rotation r = (rotation)in;
   if(r)//it's a rotation!
       return r;
   vector v = (vector)in;
   if(v)// it's not a rotation but it is a vector
       return llEuler2Rot(v * DEG_TO_RAD);
   integer index = llSubStringIndex(in, "<");
   if(~index) {//"<" was found, now insert "-"
       in = llGetSubString(in, 0, index) + "-" + 
           llStringTrim(llDeleteSubString(in, 0, index), STRING_TRIM_HEAD);
       if((string)((vector)in) != (string)v)
           return r; //it did parse, not an error
   return bad;

}//Strife Onizuka 2009, cc-by-sa 3.0 </lsl> -- Strife (talk|contribs) 20:46, 6 May 2009 (UTC)

Wow! Thanks Strife! Nexii Malthus 23:30, 6 May 2009 (UTC)

I took some time to review the code I previously posted, it should be noted that in the event that the user supplied a zero vector the code will always return ZERO_ROTATION; regardless of how llEuler2Rot might parse it if it were to contain negative zeros. This is of course at odds with the rotation parsing which does support negative zeros. However supporting negative zero was a side effect of an optimization; it is cheaper to recycle the value in r than inline ZERO_ROTATION. While it would only take the addition of two lines of code, it doesn't seem worth it to cover this obscure edge case. -- Strife (talk|contribs) 18:12, 10 January 2010 (UTC)


Over the last couple hours I've made a bunch of changes. None should change how the script functions except for where I removed the CheckValidity functionality.

  • Add: Ref now supports quaternions
  • Fix: Ref does not support <0,0,0>
  • Fix: Collision between Link_HierarchicsGet and Link_HierarchicsEdit
  • Add: Re-enabled Link_HierarchicsGet
  • Fix: In edit mode the (ChangedRot && ChangedPos) code is dead due to preceding logic... and inconsistent with preceding code.
  • Removed: CheckValidity

I removed CheckValidity because it wasn't necessary to the core functionality and it required configuration. In addition to that, maintaining inventory integrity may or may not be a priority of the scripter. The biggest problem was that CheckValidity in it's default configuration would delete the script and if it could the entire objec, upon object rerez or change in inventory. It was my conclusion that CheckValidity should be a separate library/example script. -- Strife (talk|contribs) 23:49, 6 May 2009 (UTC)


llGetRootRotation is going to be a problem with attachments. I'll see if I can come up with a solution. -- Strife (talk|contribs) 00:38, 7 May 2009 (UTC)

Hmm, in my prim animations code previously, I used to send llGetRootRotation along with the individual commands, perhaps we should do the same here with the Values List as an extra unreferenced value at the end. It seems the most realistic fix to me. llMessageLinked( LINK_SET, 660333, "Rot1;Rot2;Rot3"+";RootRot", "Link1;Link2;Link3" ); Nexii Malthus 12:32, 7 May 2009 (UTC)
I was wondering what llGetObjectDetails returned for attachment prims. -- Strife (talk|contribs) 15:21, 7 May 2009 (UTC)


Before you get ahead of yourself Strife, we should try fix up the script so it works. It doesn't work anymore when I sent it through the example code. The code in Update() seems okay to me, I think it may be the initialisation routine changes you introduced. Nexii Malthus 12:29, 7 May 2009 (UTC)

Well, nevermind hm. Odd! Just the first time I tried the script it behaved very strangely. Nexii Malthus 13:55, 7 May 2009 (UTC)

Okay right. An issue I had a long with this script is trying to come up with a plan so that the current structure of a hierarchy was correctly loaded up on initialisation instead of having all rotations at a default zero rotation. The current script is nearly there, just an issue with the current reference I think. Imagine using the example given, and then intermittently just randomly resetting all scripts. The script needs to be truly self-aware, so that a reset can't destroy the coordinated hierarchy, be the reset on purpose or on accident. Nexii Malthus 14:21, 7 May 2009 (UTC)

I was wondering about that, it should be pretty easy to have it determine the rot instead of zero'ing it on reset when there is a reference angle. I honestly was wondering why you did it that way. -- Strife (talk|contribs) 15:08, 7 May 2009 (UTC)
I realize it's not easy, you have to do the reverse of Update to get the starting rot. Very unfun. I shall ponder. -- Strife (talk|contribs) 15:23, 7 May 2009 (UTC)
That is what must have stopped me in my tracks then when I originally wrote it, quite messy indeed. So from what I understand is to take a copy of the hierarchy once everything is initialised (reintroducing the reference list again locally), then going through the original list, making amendments by following each piece in reverse to grab the correct rotation for each piece yet again, while making sure to consider the reference rotation as well of each piece. I'm not sure I expressed myself so well, but its basically a loop-in-a-loop thing. Nexii Malthus 01:42, 9 May 2009 (UTC)

Modify Hierarchy Structure

I realised I forgot to implement a vital feature into the system. The ability to modify the hierarchy structure at run-time. Imagine being able to move nodes in a 3D mind map, from parent to parent. Nexii Malthus 15:50, 29 May 2009 (UTC)

That's going to be fun to implement. -- Strife (talk|contribs) 00:01, 30 May 2009 (UTC)