Jump to content

A question regarding llcastray


Xander Lopez
 Share

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

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

Recommended Posts

Is there anyway i can use llCastRay to detect if there is any non-phantom prim in between me and my target avatar?  For example, lets say that I am in the middle of the sim, and my target avatar is inside a house. I would like to use llCastRay to determine if there is a wall in between me and my target avatar.

Would this be possible via llCastRay? If so, how can i automatically commend llCastRay to shoot the ray toward the target avatar automatically?

Link to comment
Share on other sites

llCastRay() returns the UUID of the avatar or object it is pointing at. If an object is located between an avatar and you, then llCastRay() will return the UUID of that object.

You can use llGetAgentSize() to see if the UUID returned belongs to an avatar. See http://wiki.secondlife.com/wiki/LlGetAgentSize for how to use this function.

Link to comment
Share on other sites

Use your own and your target's positions as the start and end vectors. Maximum hits is 1 by default (which is all you need). Phantom objects are rejected by default.

vector target_pos = llList2Vector (llGetObjectDetails (target_key, [OBJECT_POS]), 0);
list raycast = llCastRay (llGetPos (), target_pos, []);
key hit = llList2Key (raycast, 0);
if (hit == target_key)
{
    // you've hit the target: there's nothing between you and them
}

This is a pretty basic snippet, but it may be an adequate starting point. Not tested in-world.

  • Confused 1
Link to comment
Share on other sites

It's always the stuff around the main library function that can pose a challenge. We don't know details of the application, and I'd assume the script already has a known valid target agent key "somehow" (maybe an element of llGetAgentList, a sensor return, a collision, whatever). Nor do we know what "automatically" means; perhaps it's triggered by the same event that revealed our target agent, or a timer, or something else. So to get on with it, I'll assume the target is the owner and "automatically" is a comfy 10 second timer:

key tgtAV;  // SOMEHOW you've got an avatar target

cast()
{
    list castResults = llCastRay
        ( llGetPos()    // between the scripted object's location
        , llList2Vector( llGetObjectDetails( tgtAV, [OBJECT_POS]), 0)   // and the avatar target
        , [ RC_REJECT_TYPES
            , RC_REJECT_AGENTS  // ignore agents in between
            | RC_REJECT_LAND    // ignore if they crouch behind terrain (?)
          ] // default to ignoring non-phantom and stopping with any one detection
        );
    integer castStatus = llList2Integer( castResults, -1);
    if (0 < castStatus) // always 1 because we didn't specify RC_MAX_HITS
        llOwnerSay("Detected "+(string)castStatus+" intervening objects");
    else
    if (0 == castStatus)
        llOwnerSay("Nothing in the way");
    else    // error
    llOwnerSay( "ERROR: " + llList2String(  
        [ "Cast time exceeded"                  // -3: RCERR_CAST_TIME_EXCEEDED
        , "Sim performance too low for cast"    // -2: RCERR_SIM_PERF_LOW
        , "Unknown cast error encountered"      // -1: RCERR_UNKNOWN
        ], castStatus + 3));
}

default
{
    state_entry()
    {
        tgtAV = llGetOwner();   // demo: use owner as avatar target
        llSetTimerEvent(10.0);
        cast();
    }
    timer()
    {
        cast();
    }
}

Incidentally, I've found llCastRay() to be crazy sensitive to sim Physics load specifically, and will throw errors long before the sim is showing any real performance problems.

  • Like 2
Link to comment
Share on other sites

Yes, you can do this with llCastRay.

A few notes:

  • Set RC_GET_ROOT_KEY in the DATA_FLAGS for llCastRay if you want to tell when the ray reached the avatar. That way, when the ray cast hit's the avatar's mesh clothing, you'll get the key of the avatar, not the key of the clothing attachment. Note that if the avatar is sitting, you'll get what they're sitting on. So you have to take that into account. When you find the avatar's key, get the root of that key, and that's "Hit the avatar or at least what they're sitting on or in". If you need to resolve avatar position inside a vehicle, where they are sitting on something that surrounds them, it's more complicated. But for most uses, comparing root keys is good enough.
  • If you get RCERR_CAST_TIME_EXCEEDED or RCERR_SIM_PERF_LOW statuses, wait 0.1 second or so and try again. After 20 tries or so, give up. My NPCs do huge numbers of ray casts as they find their way through their surroundings, and they hit the ray cast limits now and then. It slows them down but doesn't stop them.
  • If you cast a ray outwards from your own avatar, you can get a hit on your own attachments or seat. So you may have to ask for the first 2 or 3 hits, and ignore any which have the same root the caster does.
Link to comment
Share on other sites

24 minutes ago, animats said:

Yes, you can do this with llCastRay.

A few notes:

  • Set RC_GET_ROOT_KEY in the DATA_FLAGS for llCastRay if you want to tell when the ray reached the avatar. That way, when the ray cast hit's the avatar's mesh clothing, you'll get the key of the avatar, not the key of the clothing attachment. Note that if the avatar is sitting, you'll get what they're sitting on. So you have to take that into account. When you find the avatar's key, get the root of that key, and that's "Hit the avatar or at least what they're sitting on or in". If you need to resolve avatar position inside a vehicle, where they are sitting on something that surrounds them, it's more complicated. But for most uses, comparing root keys is good enough.
  • If you get RCERR_CAST_TIME_EXCEEDED or RCERR_SIM_PERF_LOW statuses, wait 0.1 second or so and try again. After 20 tries or so, give up. My NPCs do huge numbers of ray casts as they find their way through their surroundings, and they hit the ray cast limits now and then. It slows them down but doesn't stop them.
  • If you cast a ray outwards from your own avatar, you can get a hit on your own attachments or seat. So you may have to ask for the first 2 or 3 hits, and ignore any which have the same root the caster does.

I'm 99.8% sure you can't hit attachments with raycast.

  • Like 1
Link to comment
Share on other sites

Just now, Wulfie Reanimator said:

I'm 99.8% sure you can't hit attachments with raycast.

I think you're right. I see that with my NPCs, who can ray cast hit their own clothing, but animesh have a different system. When animesh wear rigged mesh, it's a child prim, not an attachment.

  • Like 1
Link to comment
Share on other sites

@Fritigern Gothly @Rachel1206 I can't see why my post caused your reactions. Fritigern writes about testing the hit returned by llCastRay to see if it's an avatar. There's no need for that, surely? If the key returned by llCastRay is that of the target avatar, then there was nothing in between the start of the ray and that avatar. If the key was anything else then that something else was between the start of the ray and the target avatar, or there was an llCastRay error.

Now, this wouldn't be the first time I've missed something bleedin' obvious, but for the life of me I still can't see where I've gone wrong here. Please enlighten me.

The shortcomings in my post that I do acknowledge are that I didn't state specifically that the variable target_key was the key of the target that had been previously acquired, that I didn't handle any of the possible errors that llCastRay may have generated, instead going for the simple options: a clear line of sight to the target/something got in the way, albeit possibly a system error (which I allude to with the phrase "pretty basic"), and I didn't address the OP's automation question which, I think needs more information before a proper answer can be given.

  • Like 1
Link to comment
Share on other sites

33 minutes ago, KT Kingsley said:

@Fritigern Gothly @Rachel1206 I can't see why my post caused your reactions. Fritigern writes about testing the hit returned by llCastRay to see if it's an avatar. There's no need for that, surely? If the key returned by llCastRay is that of the target avatar, then there was nothing in between the start of the ray and that avatar. If the key was anything else then that something else was between the start of the ray and the target avatar, or there was an llCastRay error.

Now, this wouldn't be the first time I've missed something bleedin' obvious, but for the life of me I still can't see where I've gone wrong here. Please enlighten me.

The shortcomings in my post that I do acknowledge are that I didn't state specifically that the variable target_key was the key of the target that had been previously acquired, that I didn't handle any of the possible errors that llCastRay may have generated, instead going for the simple options: a clear line of sight to the target/something got in the way, albeit possibly a system error (which I allude to with the phrase "pretty basic"), and I didn't address the OP's automation question which, I think needs more information before a proper answer can be given.

Your previous post is perfectly correct and succinct. There's nothing wrong with it.

Though, I would add that if you hit nothing at all, you should consider that a "success." Moving avatars may change position after you've gotten their position but before the cast begins. As long as you haven't hit anything else, there was no obstacle between you and the target.

Edited by Wulfie Reanimator
  • Thanks 1
Link to comment
Share on other sites

1 hour ago, KT Kingsley said:

Now, this wouldn't be the first time I've missed something bleedin' obvious, but for the life of me I still can't see where I've gone wrong here. Please enlighten me.

The OP asks if llCastRay() can detect a wall between it and its target. You start talking about positions, this made your response irrelevant to the question. 
 

Link to comment
Share on other sites

35 minutes ago, Fritigern Gothly said:

The OP asks if llCastRay() can detect a wall between it and its target. You start talking about positions, this made your response irrelevant to the question. 

So if KT hadn't said anything and only posted the code, that'd been better?

Q: "How to detect a wall between me and my target?"
A: "if (hit == target_key), you've hit the target without obstacles."

It's literally a complete answer that directly addresses the problem, especially when considering how we don't know to what degree OP has already tried to solve it and what their skills are. The foreword adds useful context to the given example.

Edited by Wulfie Reanimator
  • Thanks 2
Link to comment
Share on other sites

4 hours ago, KT Kingsley said:

@Fritigern Gothly @Rachel1206 I can't see why my post caused your reactions....

.... that I didn't state specifically that the variable target_key was the key of the target that had been previously acquired...

That, not the the code it self. I assumed, OP using cast ray firstly to search, the original question a little unclear.

I can see, my answer in hindsight looks arrogant, it was not meant to be.

  • Thanks 1
Link to comment
Share on other sites

6 hours ago, Wulfie Reanimator said:

Your previous post is perfectly correct and succinct. There's nothing wrong with it.

Though, I would add that if you hit nothing at all, you should consider that a "success." Moving avatars may change position after you've gotten their position but before the cast begins. As long as you haven't hit anything else, there was no obstacle between you and the target.

Yes. But why test for hitting the target? Why not simply cast to the target's position and count any non-phantom non-avatar stuff in the way? Nothing, one thing (default RC_MAX_HITS of 1), or an error was encountered.

Link to comment
Share on other sites

34 minutes ago, Qie Niangao said:

But why test for hitting the target?

Because you might hit it?

The one thing you hit (rather than nothing, or you encounter an error) might turn out to be the target, which isn't that unlikely given that's what you were aiming at.

Edited by KT Kingsley
  • Like 1
  • Thanks 1
Link to comment
Share on other sites

5 hours ago, KT Kingsley said:

Because you might hit it?

The one thing you hit (rather than nothing, or you encounter an error) might turn out to be the target, which isn't that unlikely given that's what you were aiming at.

I'm still not getting it. The target is an avatar, so if we specify RC_REJECT_AGENTS that target will never appear on the result list (nor any of the target avatar's attachments, if that was the thinking).

My theory of llCastRay is to minimize the cost of each call by keeping the filters as tight as possible and the RC_MAX_HITS as low as possible. In this case (at least as specified), we don't even need to compare UUIDs; an integer comparison is good enough.

The reason I obsess about cost here is that each llCastRay call eats a little Havok, which is why its probability of succeeding is ultra dependent on the sim having spare Physics capacity.

  • Like 3
Link to comment
Share on other sites

4 hours ago, Qie Niangao said:

I'm still not getting it. The target is an avatar, so if we specify RC_REJECT_AGENTS that target will never appear on the result list (nor any of the target avatar's attachments, if that was the thinking).

My theory of llCastRay is to minimize the cost of each call by keeping the filters as tight as possible and the RC_MAX_HITS as low as possible. In this case (at least as specified), we don't even need to compare UUIDs; an integer comparison is good enough.

The reason I obsess about cost here is that each llCastRay call eats a little Havok, which is why its probability of succeeding is ultra dependent on the sim having spare Physics capacity.

Qie, that's a good point, and something I hadn't thought of. I shall modify my own implementation of this accordingly.

Speaking of which, it'd be interesting to hear if the OP is concerned that some of their targets might be sitting on something, which opens a whole new can of worms as far as llCastRay is concerned.

 

  • Like 1
Link to comment
Share on other sites

10 hours ago, KT Kingsley said:

 

Speaking of which, it'd be interesting to hear if the OP is concerned that some of their targets might be sitting on something, which opens a whole new can of worms as far as llCastRay is concerned.

 

Oh i am not too concierned about whether target is sitting, or anything. I was trying to develop a game where you get to shoot particle effect at your target, and i just wanted to make sure the particle doesn't fire off when there is some non-phantom obstacles like walls or rocks on its way. 

Link to comment
Share on other sites

thanks Xander for the clarification

in this case then go with Qie's method. 

if answer NO, fire a line-of-sight projectile toward the target avatar last position

if answer YES, get height, position of wall/object. Calculate arc and lob a grenade over the wall. If grenade collides with a roof then will need to change position/angle of attack

if answer ERROR, chuck a tactical nuke at them 😸

Link to comment
Share on other sites

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