Jump to content

Trying to detect avatars 2m in front of me without using a Sensor.


D4rkHax
 Share

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

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

Recommended Posts

So, im playing around with a new idea i had. I want to detect avatars that are within 2 Meters infront of me without using a Sensor. So far i have used llGetAgentList to do this and have set a condition so it only returns people within 2 Meters of me BUT it returns everyone within 2 Meteres within 360 degrees of me. So if someone is stood behind me it will stick pick them up. So what i want to do is have my script only detect other avatars that are standing infront of me, inside a 45 degree angle. So a similar shape to this \ / . And are no further away than 2 meters. My code is as follows :

list avatars=[];
integer i;

av(){
    avatars=llGetAgentList(AGENT_LIST_REGION,[]);
    i=-1;
    while(++i<llGetListLength(avatars)){
        vector pos=(vector)llList2String(llGetObjectDetails((key)llList2String(avatars,i),[OBJECT_POS]),0);
        vector pos2=llGetPos()+<0,0,0>*llGetRot();
        vector pos3=pos2-pos;
        
        
        if(llVecDist(pos,llGetPos())<2){
            if((key)llList2String(avatars,i)!=llGetOwner()){
           
                //This section is the section that needs to only detect avatars in front of me within the 2 meter / 45 degree range
                llOwnerSay(llKey2Name((key)llList2String(avatars,i))+" is within range");
                llOwnerSay("Pos3 is : "+(string)pos3);
            }
        }
    }
}
default{
    touch_start(integer x){
        av();
    }
}

As you can see i have made some attempts already with the pos, pos2, pos3 and have tried a variety of other ideas but i just can not seem to crack this. 

 

Would someone kindly be of help to me?

Link to comment
Share on other sites

Hello,

Why to not use llSensor for this?

Please check this function here:

 Function: llSensor( string name, key id, integer type, float radius, float arc );28 	Function ID0.0 	Forced Delay10.0 	EnergyPerforms a single scan for name and id with type within radius meters and arc radians of forward vector• string 	name 	– 	object or avatar name! 	• key 	id 	– 	group, avatar or object UUID that is in the same region 	• integer 	type 	– 	mask (AGENT, AGENT_BY_LEGACY_NAME, AGENT_BY_USERNAME, ACTIVE, PASSIVE, and/or SCRIPTED) 	• float 	radius 	– 	distance from center [0.0, 96.0m] 	• float 	arc 	– 	the max angle between the local x-axis of the prim and detectable objects, range 0.0 to PI

http://wiki.secondlife.com/wiki/LlSensor

 

Because when you don't use a timer and when the avatars are in range of 96m: you can use this function, it does the job already and you don't need to create a new one...

 

 

Link to comment
Share on other sites

The vector dot product is your friend

  1. Get your position and rotation ( provided your script is in the root of an attachment)
    vector mypos = llGetPos;
    rotation myrot = llGetRot();
  2. Get position of the avatar you test
    It looks like you already have the variable pos
  3. One vector is
    vector avdir = llVecNorm( pos - mypos);
  4. The other vector is
    vector lookdir = llRot2Fwd( myRot);
  5. The vector dot product is
    float dp = avdir * lookdir; // (note that the two vectors avdir and lookdir are unit vectors)

dp lays in the range -1 <= dp <= 1

When dp == 1 you are looking exactly at the avatar and when dp == -1 you look the opposite direction

The angle between avdir and lookdir is
float angle = llAcos( dp);

Use this angle to select avatar

:smileysurprised::):smileyvery-happy:

Link to comment
Share on other sites

@Luxen I am already more than aware of Sensors and how they operate. I have used them regularly in the past. However, i am exploring alternative ways to do this. 

 

@Dora That is a very interesting way to do it. I have been sat here thinking "So i must have to get my position and then my rotation and then somehow extend my field of check X meters infront of the positon of my avatar....but how do i do this exactly". Thank you for the response :)

Link to comment
Share on other sites


D4rkHax wrote:

@Luxen I am already more than aware of Sensors and how they operate. I have used them regularly in the past. However, i am exploring alternative ways to do this.

lol, ok sorry for the mistake then.

Link to comment
Share on other sites

It couldn't be more simple
first note that Acos( 1) == 0° and Acos(-1) == 180°
Acos always is a positive angle in [0,180]°

If you only want to accept avatars within ±5° you could write this code in LSL (LSL uses radians)

if ( RAD_TO_DEG * llAcos( dp) < 5.0 ){ // accept avatar}

dp is the dot product from a previous post

the very same in condensed form:

if ( dp > 0.9962 ){ // accept avatar}

0.9962 equals cos(5°)

:smileysurprised::):smileyvery-happy:

Link to comment
Share on other sites

And just a thing if i can:

vector pos=(vector)llList2String(llGetObjectDetails((key)llList2String(avatars,i),[OBJECT_POS]),0);->(key)llList2String(avatars,i) : it's a key and you take this key with llList2String 
and so llList2String cast this key to a string and after this you cast this string to a key
...After that you cast all of this into a string to cast it after to a vector....

 I say that because it's more complicate after to find an error in a script if we don't simplify our scripts.

Link to comment
Share on other sites

It is just force of habit Lux, i read a long time ago on one the wiki somewhere that whilst we do have llList2Key and llList2Vector. Due to all the data in a list being stored by default as a string it was reccomended to always cast the information back from a string into your chosen data type. So i started using the likes of (vector)llList2String and its just become something that has stuck with me 

Link to comment
Share on other sites

Well, i never saw that. I think that is recommended is to always use the good type: so if the list store a key: to use llList2Key and if it's a string to use llList2String...

But sometimes, i use the cast of these functions and don't care about the type, example: if i want a string and that is a key: so i use, in some cases (not always), llList2String. I never had bugs with that but i think that is not recommended by the wiki.

But i know a thing: more your code is simple and logical: more your code is correct and optimized...

Link to comment
Share on other sites

I agree it will be shorter to

vector pos = llList2Vector( llGetObjectDetails( llList2Key(avatars,i),[OBJECT_POS]),0);

 In this case we know for certain the list element is of type vector so there is no reason to take the detour with getting a string and then cast it. It even saves accuracy not to have a string in between

Also we can get the key directly from the llGetObjectDetails list, no need to get it as a string and then cast to key

:smileysurprised::):smileyvery-happy:

Link to comment
Share on other sites

[Trying to detect avatars 2m in front of me without using a Sensor]

If you need to be extremely precise you can always cast a few rays.

Alternatively if you want to be extremely simply you can just compare the distance of each avatars positon to a point exactly 2 meters directly in front of you.

 

OffsetTestPosition = mypos+<2,0,0>*myrot;

llVecDist(OffsetTestPos,RandomAvatarPos)  will tell you how close they are to the designated point.

Link to comment
Share on other sites

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

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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...