Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

quick Q: how to "normalize" a rot?

Chrysala Desideri
Scarlet Scriptrix
Join date: 4 Mar 2007
Posts: 65
08-30-2007 12:18
Do you even call it normalizing?

My problem is this: I want a script to llGetRot() and compare it to the cardinal and semicardinal point rotations and :

if(llGetRot()==<insert rotation here>;)
{llSay(0,"East or whatever";);}

the problem arises from the fact that llGetRot(); returns null elements of the quat as positive or negative zeroes depending on i'm-not-sure-what.

llRot2Euler doesn't help, as the null vectors are returned in the same manner.

I'm probably getting terms all wrong here, but to show you what I mean:

<0.0000, 0.0000, 0.0000, 1.0000> or <-0.0000, 0.0000, 0.0000, 1.0000>

used in an llSetRot() wil bring me same results, but if llGetRot() returns one and I compare to the other, it figures != in my if statement comparison, and I don't get my heading string.


As usual, I'm probably overlooking something bloody obvious... what's the method for getting a rot reading I can compare to a "normalized" rot? (once again, i suspect normalizing means something different..... script noob here)
Tiarnalalon Sismondi
Registered User
Join date: 1 Jun 2006
Posts: 402
08-30-2007 12:56
Those rotations you posted look like the results from a child prim when you do llGetLocalRot. Using what you posted, that rotation would be a prim that should be rotated the exact same as the root prim.
Chrysala Desideri
Scarlet Scriptrix
Join date: 4 Mar 2007
Posts: 65
08-30-2007 13:10
mmm i must have explained it wrong, better if i post the whole event (now baddly fragged by me editing in 5000 different tries at conversion)

it's a GetRot, not local, script is in root prim at that. its to set up a TP then touch it so it spits out your notecard line. a cardinal string looks better than a quat, aesthetically more user friendly, though no fundamental use or significance but more work for the code, i know.

anyway been eulering to rots back and forth and it seems to be creative with what will be made negative values from one moment to the next, and this makes my comaprisons all fail. here's the current state of the code:

Many vaues will be wrong now as i've changed them back and forth a bunch of times and lost count... and the conversion spazzing at the top was an attempt to crunch the minuses out, i read in another thread that converting back and forth would do it. no joy.

[[EDIT - changed code to get the ZERO_ROTATION*llGetRot() as variable to compare. However my comparisons are still failing!! it's llSaying and Textsetting the string-typecast quat, not my heading string. Earlier today i had it working on the rare occasions that llGetRot() returned the same values as my prefixed comparison... what am I missing?]]

This give me debug where boss and rotStr have same rot value, but the heading string is not being used... it goes straight to the final if :-(


CODE


touch_start(integer t)
{



rotation boss= ZERO_ROTATION*llGetRot();

llSay(0,(string)boss);

if(boss == ZERO_ROTATION*<0.00000, 0.00000, 0.00000, 1.00000>)
{
rotStr="E";

}

if(boss == ZERO_ROTATION*<0.00000, 0.00000, 0.70711, 0.70711>)
{
rotStr="N";

}

if(boss == ZERO_ROTATION*<0.00000, 0.00000, -1.00000, 0.00000>)
{
rotStr="W";

}

if(boss == ZERO_ROTATION*<0.00000, 0.00000, -0.70711, 0.70711>)
{
rotStr="S";

}

if(boss == ZERO_ROTATION*<0.00000, 0.00000, 0.92388, 0.38268>)
{
rotStr="NW";

}

if(boss == ZERO_ROTATION*<0.00000, 0.00000, -0.92388, 0.38268>)
{
rotStr="SW";

}

if(boss == ZERO_ROTATION*<0.00000, 0.00000, -0.38268, 0.92388>)
{
rotStr="SE";

}

if(boss == ZERO_ROTATION*<0.00000, 0.00000, 0.38268, 0.92388>)
{
rotStr="NE";

}

if(rotStr!="E"&&rotStr!="N"&&rotStr!="S"&&rotStr!="W"&&rotStr!="SE"&&rotStr!="NE"&&rotStr!="SW"&&rotStr!="NW")
{
rotStr=(string)boss;
}



llSetText(llGetObjectName()+";"+(string) (llGetPos()+<0,0,1.781> )+";"+rotStr,<1,1,1>,1);

//llSay(0,(string)llGetRot());

llSay(0,llGetObjectName()+";"+(string) (llGetPos()+<0,0,2>)+";"+rotStr);

rotStr = "";

// llResetScript();

}
Chrysala Desideri
Scarlet Scriptrix
Join date: 4 Mar 2007
Posts: 65
this doesn't work either....
08-30-2007 14:26
touch_start(integer t)
{

rotStr = "";

vector boss= llRot2Euler(llGetRot());

llSay(0,(string)boss);

if(boss == ZERO_VECTOR)
{
rotStr="E";

}

if(boss == <0,0,PI/2>;)
{
rotStr="N";

}

if(boss == <0,0,PI>;)
{
rotStr="W";

}

if(boss == <0,0,PI+PI/2>;)
{
rotStr="S";

}

if(boss == <0,0,PI/2+PI/4>;)
{
rotStr="NW";

}

if(boss == <0,0,PI+PI/4>;)
{
rotStr="SW";

}

if(boss == <0,0,PI+PI/2+PI/4>;)
{
rotStr="SE";

}

if(boss == <0,0,PI/4>;)
{
rotStr="NE";

}

if(rotStr!="E"&&rotStr!="N"&&rotStr!="S"&&rotStr!="W"&&rotStr!="SE"&&rotStr!="NE"&&rotStr!="SW"&&rotStr!="NW";)
{
rotStr=(string)boss;
}



llSetText(llGetObjectName()+";"+(string) (llGetPos()+<0,0,1.781> )+";"+rotStr,<1,1,1>,1);

//llSay(0,(string)llGetRot());

llSay(0,llGetObjectName()+";"+(string) (llGetPos()+<0,0,2>;)+";"+rotStr);



// llResetScript();

}
Chrysala Desideri
Scarlet Scriptrix
Join date: 4 Mar 2007
Posts: 65
this works for west always, east 1 try out of 3, nothing else
08-30-2007 14:53
touch_start(integer t)
{

rotStr = "";

vector boss= llRot2Euler(llGetRot());
if (boss.x == -0.00000)
{boss.x = 0.00000;}
if (boss.y == -0.00000)
{boss.y = 0.00000;}
if (boss.z == -0.00000)
{boss.z = 0.00000;}
llSay(0,(string)boss);

if(boss == <0.00000,0.00000,PI*0>||boss==<0.00000,0.00000,-PI*0>;)
{
rotStr="E";

}

if(boss == <0.00000, 0.00000, PI/2>;)
{
rotStr="N";

}

if(boss == <0.00000,0.00000,-PI>||boss == <0.00000,0.00000,PI>;)
{
rotStr="W";

}

if(boss == <0.00000, 0.00000, -PI/2>;)
{
rotStr="S";

}

if(boss == <0.00000,0.00000,PI/2+PI/4>;)
{
rotStr="NW";

}

if(boss == <0.00000,0.00000,-(PI/2+PI/4)>;)
{
rotStr="SW";

}

if(boss == <0.00000,0.00000,-(PI+PI/2+PI/4)>;)
{
rotStr="SE";

}

if(boss == <0.00000,0.00000,PI+PI/2+PI/4>;)
{
rotStr="NE";

}

if(rotStr!="E"&&rotStr!="N"&&rotStr!="S"&&rotStr!="W"&&rotStr!="SE"&&rotStr!="NE"&&rotStr!="SW"&&rotStr!="NW";)
{
rotStr=(string)boss;
}



llSetText(llGetObjectName()+";"+(string) (llGetPos()+<0,0,1.781> )+";"+rotStr,<1,1,1>,1);

//llSay(0,(string)llGetRot());

llSay(0,llGetObjectName()+";"+(string) (llGetPos()+<0,0,2>;)+";"+rotStr);



// llResetScript();

}
Masakazu Kojima
ケロ
Join date: 23 Apr 2004
Posts: 232
08-30-2007 14:57
The numbers are rounded when you convert them to a string. So while they look equivalent when you have the object say them, they aren't really.

Try this:
rotation r = llGetRot();
llOwnerSay( (string) (r.x*100) );
llOwnerSay( (string) (r.y*100) );
llOwnerSay( (string) (r.z*100) );
llOwnerSay( (string) (r.s*100) );

Facing south, I got:
[14:49] Object: 0.000000
[14:49] Object: 0.000000
[14:49] Object: -70.710686
[14:49] Object: 70.710670

Generally, if you are using == on rotations, vectors, or even floats, you're probably doing something wrong. They are not meant to be exact. With vectors you can use llVecDist, so you might try something like this:
CODE


list DIRECTIONS = ["E", "NE", "N", "NW", "W", "SW", "S", "SE"];
list OFFSETS = [<1.,0.,0.>, <.70711,.70711,0.>, <0.,1.,0.>, <-.70711,.70711,0.>, <-1.,0.,0.>, <-.70711,-.70711,0.>, <0.,-1.,0.>, <.70711,-.70711,0.> ];
float THRESHOLD = 0.0001;

default {
touch_start(integer t) {
rotation r = llGetRot();
string rotStr = (string)r;
vector v = llRot2Fwd(r);
integer i = llGetListLength(DIRECTIONS);

while (i--) {
if ( llVecDist(v, llList2Vector(OFFSETS, i)) < THRESHOLD ) {
rotStr = llList2String(DIRECTIONS, i);
i = 0; // break
}
}

llSetText(llGetObjectName()+";"+(string) (llGetPos()+<0,0,1.781> )+";"+rotStr,<1,1,1>,1);
llOwnerSay(llGetObjectName()+";"+(string) (llGetPos()+<0,0,2>)+";"+rotStr);
}
}

Chrysala Desideri
Scarlet Scriptrix
Join date: 4 Mar 2007
Posts: 65
JoyJoy! Thank you so much!!
08-30-2007 15:17
That is precisely what i needed, and i'll be studying that thoruoghly, because i don't quite understand how it's working.

like 1/4 of the code i was writing!

Let's see if i understand the concept, if not the code.... with rot2fwd this makes a virtual projected point forward from the rot and compares it to where the relative offset for compass point would be? and as long as the list item it's looking at is > threshold away from v it keeps gong through list?

this is the kind of thing i need to understand to avoid writing a forest of if trees. i keep using the computer like a damn abacus....
Talarus Luan
Ancient Archaean Dragon
Join date: 18 Mar 2006
Posts: 4,831
08-30-2007 15:24
Here's an example of a script you can put into a HUD attachment which will do what you want. Free free to cannibalize it for your needs. :)

CODE

list gaAxialDirections = ["S","","N"];
list gaRadialDirections = ["W","","E"];

default {
state_entry() {
llSetTimerEvent(1.0);
}
timer() {
vector lvFacing;
integer liAxialDirection;
integer liRadialDirection;
string lsDirection;

lvFacing = llRot2Fwd(llGetRootRotation());
liRadialDirection = llRound(lvFacing.x) + 1;
liAxialDirection = llRound(lvFacing.y) + 1;
lsDirection = llList2String(gaAxialDirections,liAxialDirection) +
llList2String(gaRadialDirections,liRadialDirection);
llSetText(lsDirection,<1.0,1.0,1.0>,1.0);
}
}