Jump to content

How to find avatar direction?


Kaos Dragoone
 Share

You are about to reply to a thread that has been inactive for 4600 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

I can't figure out how to tell the angle of an avatar in relation to an object's rotation. And not just NESW compass directions, but like "in front", "behind", "left", "right", and diagonals too. I've been trying to figure it out for the past few days but all I've gotten is a headache out of it.

Link to comment
Share on other sites

Here's one way, using a hastily modified version of the example at http://wiki.secondlife.com/wiki/LlGetCameraRot .  This solution is imperfect, because it's using a camera follower and then telling you which direction IT is facing, which may not be exactly the same direction that your av is.  Depending on how close the answer has to be, though, it could be useful.

//Camera Follower Script //llGetCameraPos & llGetCameraRot Example //By Nika Rugani //Modified by Rolig Loon by the addition of a touch event integer perm_track = 0x400;float second_check = 0.1; vector object_offset = <2,0,0>; //Offset of the cameras position where the object will set itselfinteger die_channel = 0;string die_command = "/die"; quickPosRot(vector pos, rotation rot){//This way you don't have the 0.2 second sleeps from llSetPos and llSetRot    llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_POSITION, pos, PRIM_ROTATION, rot]);} default{    on_rez(integer a)    {        llResetScript();    }    state_entry()    {        llRequestPermissions(llGetOwner(), perm_track);    }    run_time_permissions(integer permission)    {        if(permission == perm_track)        {            llSetTimerEvent(second_check);            llListen(die_channel, "", llGetOwner(), "");        }        else        {            //llResetScript(); //Remove comment to loop the process of requesting permissions if user deny's permission //llDie(); //Remove comment to kill the object if user deny's it        }    }    listen(integer channel, string name, key id, string str)    {        str = llToLower(str);        if(str == die_command)        {            llDie();        }    }    touch(integer num)    {        vector Front = llRot2Euler(llGetRot())*RAD_TO_DEG;        float Facing = Front.z;        if (Facing < 0.0)        {            Facing = (180.0 + Facing) + 180.0;        }        llSay(0, "You are facing "+ (string)Facing + " degrees from East.");    }    timer()    {        vector c_pos = llGetCameraPos(); //Get Users Camera Position        rotation c_rot = llGetCameraRot(); //Get Users Camera Rotation        c_pos = (c_pos+object_offset*c_rot); //Apply the offset to the position        quickPosRot(c_pos, c_rot); //EXECUTE ORDER!    }}

 ETA:   Hehehe... I forgot all about llGetObjectDetails, Dora.   That's MUCH less work.   (But this is fun.) :smileytongue:

 

Link to comment
Share on other sites

in relation to an object....  how many points of direction, and what arcs?

you start with av position, subtract object position, then divide by object rotation. that gives you the position of the av relative to your objects position and facing.

from there you can tackle it several different ways, but the mathematically simplest is is to grab o each element in three separate calculations, and use triange theoroms to get the angle off the major axis.

llAsin( x / llVecMag( <x, y, 0.0> ) ) = x_angle

llAsin( y / llVecMag( <0.0, y, z> ) )= y_angle

llAsin( z / llVecMag( x, 0.0, z> ) )= z_angle

from there you can divide it up any way you want

 

ETA:
slight correction

Link to comment
Share on other sites

Didn't we have a long thread about exactly this problem sometime last year?  I can't find it at the moment, but I remember two or three of us coming up with scripts that did the job.  Next time I can get in world, I'll have to poke around and see what I did with mine.

Link to comment
Share on other sites

Using the vector dot product the problem is solved smoothly and straight forward:

vector avatarPosition;rotation avatarRotation;vector primPosition;float dotp = llRot2Fwd(avatarRotation)*llVecNorm(primPosition-avatarPosition);float angleToPrim = RAD_TO_DEG*llACos(dotp); // angleToPrim == 0 deg when the avartar is pointing directly towards the prim// angleToPrim == 180 deg when the avartar is pointing away from the prim 

 You can even skip the angle calculation and use dotp as it is:

// dotp == 1 when the avartar is pointing directly towards the prim// dotp == -1 when the avartar is pointing away from the prim 

 Changed error dotp == 0 to dotp == 1



Link to comment
Share on other sites

now lets just hope my math is right =X

 

the calculations I gave are based on the diameter of a circumcircle [diameter = any_side / sin( opposite angle ) ], and the presumption that the triangle we create this way is a right tringle (meanging the long side is the diameter, which is distance in our forumla). we get the side by the distance to the major axis, and we do it in 2d by zeroing the previous element tested.

Link to comment
Share on other sites

well you reversed the terms ( OPs case was angle from prim ), but otherwise it works for single axis... but doen't give the relation to the other two.

PS you last calc is wrong, it's 1 fwd, -1 behind

 

ETA:
I was trying to avoid vector and plane normals in my example, or even the mor complex case of rotations, since the math is easier to visualize.... you can do it all in rotations and pull out all three axis, but I'd hace to do the math longhand to figure out the formula, and vector space is easier on my brain =X

most of the formula are on the "geometric library" page in the wiki though. (assuming you can interpret Nexii's shorthand descriptions)

Link to comment
Share on other sites


Void Singer wrote:

well you reversed the terms ( OPs case was angle from prim ), but otherwise it works for single axis... but doen't give the relation to the other two.

PS you last calc is wrong, it's 1 fwd, -1 behind

 

ETA:

I was trying to avoid vector and plane normals in my example, or even the mor complex case of rotations, since the math is easier to visualize.... you can do it all in rotations and pull out all three axis, but I'd hace to do the math longhand to figure out the formula, and vector space is easier on my brain =X

most of the formula are on the "geometric library" page in the wiki though. (assuming you can interpret Nexii's shorthand descriptions)

The error is corrected in my original contribution:

// dotp == 1 when the avartar is pointing directly towards the prim

// dotp == -1 when the avartar is pointing away from the prim

 

To alter direction just swap primPosition and avatarPosition

 

This approach is general for any positions and rotations you can think of

If you want the angle in the horizontal plane only all you have to do is to take the z coordinate out of the calculation:

 

primPosition.z = avatarPosition.z;

float dotp = llRot2Fwd(avatarRotation)*llVecNorm(primPosition-avatarPosition);

@Void

I don't see any plane normals in my calculations and only one rotation: where it is converted to the forward vector

llVecNorm(v) does not return a plane normal but a vector with a normal size pointing the same way as the argument vector.

The dot product is entirely "vector space" and it is easier on my brain too:smileyvery-happy:

 

 

Link to comment
Share on other sites

technically vector == plane normal, they are interchangable ...

so what I see in the  formula is "what the direction/angle is the point off the plane" sign for direction, Acos( value ) for angle. ETA: and now of course thinking on it that's backwards... since it'd be (90-angle) for the plane...

but my comment was more towards the higher math understanding, since the common reference for vectors (incorrectly) is a set of spatial points (HS geometry), rather than direction/velocity, direction/distance, or plane/velocity, plane/size, gravimetric distortion, etc.

PS
I meant the reference framewas revesed, not the direction... so you;d swap in the prim rot, and flip the other two...generalized to

llRot2Fwd( sensorRot ) * llVecNorm( targetPos - sensorPos );

and since the lindens threw them in there you can do left/right and up/down with llRot2Left [ya-xis] and llRot2Up[z-axis]

 

I'm not sure which method works out cheaper in script time/size, but I'm betting yours does.

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 4600 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...