Jump to content

How can I add NE, NW, SE, and SW to this avatar scanner function?


Life Camino
 Share

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

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

Recommended Posts

I'm working on an avatar scanner HUD and I figured out how to decide whether an avatar is N, S, E, or W of me but I'm having trouble deciding when I should combine directions, like NE, NW, SE, and SW.   Any suggestions would be greatly appreciated.  Here's what I have, so far...

avatar_scan()
{
    vector avi_pos;
    list avatar_info = [];
    list avatar_keys = llGetAgentList(scope, []);
    if (~llListFindList(avatar_keys, [llGetOwner()]))
    {
        integer idx = llListFindList(avatar_keys, [llGetOwner()]);
        avatar_keys = llDeleteSubList(avatar_keys, idx, idx);//We don't want the owner information displayed in hovtext
    }
    integer n = llGetListLength(avatar_keys);
    integer i = 0;
    for (; i< n; i++)//This is where we build our avatar_info list.  It has only the avi distance and keys in it
    {
        list temp_list = llGetObjectDetails(llList2Key(avatar_keys, i), [OBJECT_POS]);
        avi_pos = llList2Vector(temp_list, 0);
        integer distance = (integer)llVecDist(llGetPos(),avi_pos);
        avatar_info += [distance];
        avatar_info += [llList2Key(avatar_keys, i)];
    }
   
    if (sort_flag)avatar_info = llListSort(avatar_info, 2, TRUE);//sort our strided list in ascending distance order
    if (!sort_flag)avatar_info = llListSort(avatar_info, 2, FALSE);
   // llOwnerSay("avatar_info = " + llDumpList2String(avatar_info, "::"));
    n = llGetListLength(avatar_info);
    i = -n;
    for (; i < -1; i = i + 2)
    {
        avatar_info = llDeleteSubList(avatar_info, i, i);
    }
   // llOwnerSay("avatar_info = " + llDumpList2String(avatar_info, "::"));
    avatar_keys = avatar_info;
    integer number_of_display_prims = llGetListLength(radar_links);
    integer current_link_number;
    integer idx;
    i = 0;
    n = llGetListLength(radar_links);
    for (;i < n; i++)//We must set prim text in every radar prim, even if it is an empty string
    {               
        key current_avi = llList2Key(avatar_keys, idx);
        ++idx;
        list temp_list = llGetObjectDetails(current_avi, [OBJECT_POS]);
        vector avi_pos = llList2Vector(temp_list, 0); 
        vector pos = llGetPos();
        integer distance = (integer)llVecDist(pos, avi_pos);
        string dist = (string)distance;
        string display_name = llGetDisplayName(current_avi);
        string user_name = llGetUsername(current_avi);
        string direction;
        string up_dn;               
        if (avi_pos.x > pos.x && llFabs(avi_pos.x-pos.x)/llFabs(avi_pos.y-pos.y) > llFabs(avi_pos.y-pos.y)/llFabs(avi_pos.x-pos.x))direction = "E";
        if (avi_pos.x < pos.x && llFabs(avi_pos.x-pos.x)/llFabs(avi_pos.y-pos.y) > llFabs(avi_pos.y-pos.y)/llFabs(avi_pos.x-pos.x))direction = "W";
        if (avi_pos.y > pos.y && llFabs(avi_pos.y-pos.y)/llFabs(avi_pos.x-pos.x) > llFabs(avi_pos.x-pos.x)/llFabs(avi_pos.y-pos.y))direction = "N";
        if (avi_pos.y < pos.y && llFabs(avi_pos.y-pos.y)/llFabs(avi_pos.x-pos.x) > llFabs(avi_pos.x-pos.x)/llFabs(avi_pos.y-pos.y))direction = "S";
        if (llFabs(avi_pos.z-pos.z) > 5 && avi_pos.z > pos.z)up_dn = Chr(0X25b2);//up_dn = "^";
        if (llFabs(avi_pos.z-pos.z) > 5 && avi_pos.z < pos.z)up_dn = Chr(0X25bc);//up_dn = "V";
        integer agent_action = llGetAgentInfo(llList2Key(avatar_keys, i));
        string action = "";
        if (agent_action & AGENT_SITTING)action = "S";
        if (agent_action & AGENT_MOUSELOOK)action = action + "M";
        if (agent_action & AGENT_AWAY)action = "AWAY";
        if (agent_action & AGENT_BUSY)action = "BUSY";
        if (agent_action & AGENT_TYPING)action = action + "T";
        if (agent_action & AGENT_CROUCHING)action = action + "C";
        if (agent_action & AGENT_IN_AIR)action = action + "F";//Flying or falling
        if (agent_action & AGENT_WALKING)action = action + "W";
        vector hov_text_color;
        if ((integer)dist >= 96)hov_text_color = <0.000, 1.0, 1.0>;//Cyan
        if ((integer)dist < 96 && (integer)dist >= 20)hov_text_color = <1.000, 1.0, 0.000>;//Yellow
        if ((integer)dist < 20 && (integer)dist >= 10)hov_text_color = <0.180, 1.0, 0.251>;//Green
        if ((integer)dist < 10)hov_text_color = <1,1,1>;
        if (~llSubStringIndex(action, "M"))hov_text_color = <1,0.2,0.0>;
            
        string prim_text = display_name + " (" + user_name + ") [" + dist + "m " + direction + " " + up_dn + "] " + action;
        if (display_name == "")prim_text = "";
        integer x = (integer)i;
        current_link_number = llList2Integer(radar_links, x);
        integer y;
        for (; y <= x; y++)
        {
            prim_text = prim_text + "\n ";
        }
        string agents_text = ("[ " + (string)llGetListLength(avatar_keys) + " Agents in Range (" + (string)(llGetListLength(avatar_keys) + 1) + " in sim) ]");
        llSetLinkPrimitiveParamsFast(agents_link, [PRIM_TEXT, agents_text, <0.0, 0.35, 1.00>, 1.0]);
        llSetLinkPrimitiveParamsFast(current_link_number, [PRIM_TEXT, prim_text, hov_text_color, 1.0]);
    }                     
}

 

Link to comment
Share on other sites

there is a circle which is centred on your avatar. 360 degrees

divide the circle into 8 even slices of 45 degrees. Conceptualise them as numbered 0.. 7

North slice is 0. NorthEast slice is 1. East slice is 2 ... etc

True North (conceptualised) is 0 degrees. The True for each slice then being +45 degrees from the preceding

when target avatar falls with the slice + or - 22.5 from True then N, NE, E ... etc

+

something else to maybe consider

can also conceptualise True North as True Forward (the rotation of the avatar wearing the radar - straight ahead) Like a clock dial. 12 slices of 30 degrees

can be more informative when the avatar is moving. Like on a combat arena or a plane. Example: there is a bandit on my 6

Link to comment
Share on other sites

Try llRot2Angle( llRotBetween(<1.0,0.0,0.0>,llVecNorm(av_pos - llGetPos()) ) )  or a variation on that theme.

ETA:  The angle you get from that will be in radians, of course, and will be the angle relative to global EAST, since that's where ZERO_ROTATION points.  You'll need to rotate that by PI/2 to get the angle relative to global NORTH.  Also, the angle won't be signed, so you won't tell from that alone whether your target is, say, NE or NW. You'll have to get that information independently.

  • Like 1
Link to comment
Share on other sites

Not that easy. You need to remove the height for a display on a 2D scanner and if you want to use the numeric value of the angle you will notice that LL obviously has no clue that N is at 0° and not E.

 

vector avi_pos = llList2Vector(llGetObjectDetails(current_avi,[OBJECT_POS]),0);avi_pos.z = 0;vector pos = llGetPos();pos.z = 0;vector rot = llRot2Euler(llRotBetween(<1,0,0>, llVecNorm(avi_pos-pos)));float angle = rot.z * RAD_TO_DEG + 270.0;if (angle>360.0) angle-=360.0;

 

That will give a positive angle between 0 and 359 and 0 is north.
Now a transformation into a string. Requires a division into 8 quadrants of 45°

 

integer quadrant = llFloor( (angle + 22.5) / 45.0 );string direction = llList2String(["N","NW","W","SW","S","SE","E","NE","N"], quadrant);

 

"direction" contains the string now. It's no typo that there are 2 "N" - think about it.

For the clock display ("boogey at 6 o'clock high") we use this code:

 

integer clock = 12 - llFloor( (angle + 15.0) / 30.0 );if (clock==0) clock = 12;

 

  • Like 1
Link to comment
Share on other sites

Thank you, Nova.  That looks like it would work great.  But, I was directed privately to the llAtan2 function and in the SL Wiki entry for the function, they included this example, which worked perfectly and was less involved than the method you described.  Here is what I ended up using to determine compass heading to the target avi:

 

string compass (vector target) {   vector source = llGetPos();   list DIRS =["W","NW","N","NE","E","SE","S","SW","W"];   integer index = llCeil(3.5 - (4 * llAtan2(target.y - source.y, target.x - source.x) / PI));   return llList2String(DIRS, index);}

 

 

  • Like 1
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 3473 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...