Jump to content

Recommended Posts

What I want to know is if there is a simple command to check if point A has a line of sight to point B ?

Share this post


Link to post
Share on other sites

 

Thank you for your advice.

 

checkVisibility is work in progress and has no comments in biki it would be nice if someone could explain it.

 

 lineIntersectsSurfaces seems to be good but is it only checking for surface intersections? what about objects? do I need to check with another Intersect command?

Share this post


Link to post
Share on other sites

It checks for objects as well. I literally just whipped this up for you to have a play with; I can't guarantee that it's perfect:

/*
    Author: HallyG
    
    Parameter(s):
    0: [OBJECT] - Object who is 'looking'
    1: [OBJECT] - Object to look for
    2: [NUMBER] - Looker's FOV (OPTIONAL) DEFAULT (70)

    Returns:
    [BOOLEAN]
*/
params [
    ["_looker",objNull,[objNull]],
    ["_target",objNull,[objNull]],
    ["_FOV",70,[0]]
];
if ([position _looker, getdir _looker, _FOV, position _target] call BIS_fnc_inAngleSector) then {
    if (count (lineIntersectsSurfaces [(AGLtoASL (_looker modelToWorldVisual (_looker selectionPosition "pilot"))), getPosASL _target, _target, _looker, true, 1,"GEOM","NONE"]) > 0) exitWith {false};
    true
} else {
    false
};

Admittedly it's quite messy but hey ho - Doesn't take into account objects behind windows

  • Like 2

Share this post


Link to post
Share on other sites

hey man, you are realy nice to me ... like this :-)

 

Edit: u saved hours for me if not days. I m very happy with that. Thank you very much.

Edited by sarogahtyp

Share this post


Link to post
Share on other sites

Thank you for your advice.

 

checkVisibility is work in progress and has no comments in biki it would be nice if someone could explain it.

 

 lineIntersectsSurfaces seems to be good but is it only checking for surface intersections? what about objects? do I need to check with another Intersect command?

I don't know if the "WIP" means just the wiki page or that the command itself is subject to change.

But it works like this:

Syntax:

[ignored object, lod name] checkVisibility [begin,end]

Returns a number from 0 to 1.

Zero means not visible, 1 means clearly, and anything in between is partially visible.

The LOD names are probably the same as in lineIntersectsSurfaces; "FIRE", "VIEW", "GEOM", "IFIRE", "NONE"

Positions are in ASL.

Example:

if ( [player, "VIEW"] checkVisibility [eyepos santaClaus, eyepos player] > 0) then { hint "He sees you!"}; 

And compared to lineIntersects, it's much faster to execute.

Share this post


Link to post
Share on other sites

Example:

if ( [player, "VIEW"] checkVisibility [eyepos santaClaus, eyepos player] > 0) then { hint "He sees you!"}; 
And compared to lineIntersects, it's much faster to execute.

 

Thank u very much for your explanation. I tested both commands and measured 1000 runs via diag_tickTime and my result for my specific case was that lineIntersects runs about 2 times faster than checkVisibility.

checkVisibility had values between 0.2 - 0.25 ms as sum of 1,000 runs

lineIntersects had values between 0.08 - 0.15 ms as sum of 1,000 runs

I think playing around with checkVisibility could be interesting with smoke and such things but i ll test that.

EDIT:

I compared that line

if ( [_looker, "VIEW"] checkVisibility [(AGLtoASL (_looker modelToWorldVisual (_looker selectionPosition "gunner"))), (getPosASL _target)] < 1) exitWith {false};

with this one

if (count (lineIntersectsSurfaces [(AGLtoASL (_looker modelToWorldVisual (_looker selectionPosition "gunner"))), getPosASL _target, _target, _looker, true, 1,"GEOM","NONE"]) > 0) exitWith {false};

just in case if i made a measuring mistake with those lines just tell me, please.

EDIT again: I did a cleaner test now in VR with one man and one cargo box only with a distance of 1,000 meters.

The difference is not so much now.

I reapeated the code 10,000 times now therefore the time for both is higher.

checkVisibility took about 0.6 ms

lineIntersects took about 0.4 ms

next EDIT:

I did some tests with checkVisibility and smoke now and it seems that the return value is never reaching 0.6 even if the objects are close together and without smoke.

If u pop smoke then the return value falls rapidly near zero. I tested only the case when the objects are close together (1-20 meters).

For that distance i think 0.001 could be a good value to decide if u can see through the smoke or not. everything above 0.001 means you have a good view.

Last EDIT in this post:

After testing a lot more in a real scenario on altis i m totaly confused about the return value of checkVisibility.

I dont know how to decide if something is smoked. the only thing what I know that u have a LOS if the return value is above zero.

Edited by sarogahtyp

Share this post


Link to post
Share on other sites

Thank u very much for your explanation. I tested both commands and measured 1000 runs via diag_tickTime and my result for my specific case was that lineIntersects runs about 2 times faster than checkVisibility.

checkVisibility had values between 0.2 - 0.25 ms as sum of 1,000 runs

lineIntersects had values between 0.08 - 0.15 ms as sum of 1,000 runs

I think playing around with checkVisibility could be interesting with smoke and such things but i ll test that.

EDIT:

I compared that line

if ( [_looker, "VIEW"] checkVisibility [(AGLtoASL (_looker modelToWorldVisual (_looker selectionPosition "gunner"))), (getPosASL _target)] < 1) exitWith {false};

with this one

if (count (lineIntersectsSurfaces [(AGLtoASL (_looker modelToWorldVisual (_looker selectionPosition "gunner"))), getPosASL _target, _target, _looker, true, 1,"GEOM","NONE"]) > 0) exitWith {false};

just in case if i made a measuring mistake with those lines just tell me, please.

EDIT again: I did a cleaner test now in VR with one man and one cargo box only with a distance of 1,000 meters.

The difference is not so much now.

I reapeated the code 10,000 times now therefore the time for both is higher.

checkVisibility took about 0.6 ms

lineIntersects took about 0.4 ms

next EDIT:

I did some tests with checkVisibility and smoke now and it seems that the return value is never reaching 0.6 even if the objects are close together and without smoke.

If u pop smoke then the return value falls rapidly near zero. I tested only the case when the objects are close together (1-20 meters).

For that distance i think 0.001 could be a good value to decide if u can see through the smoke or not. everything above 0.001 means you have a good view.

Last EDIT in this post:

After testing a lot more in a real scenario on altis i m totaly confused about the return value of checkVisibility.

I dont know how to decide if something is smoked. the only thing what I know that u have a LOS if the return value is above zero.

 

I was wondering how your experiments with this went on ?

 

I myself am using the following that I found in one of Pierre's scripts

{
if ((side _x != playerSide ) and (!(lineIntersects [eyePos player, eyePos _x, player, _x]) && !(terrainIntersect [[getPosATL player select 0, getPosATL player select 1, (getPosATL player select 2)+0.5], [getPosATL _x select 0, getPosATL _x select 1, (getPosATL _x select 2)+1]]) )) then {

... do stuff ...

};
} foreach (getPosATL player) nearEntities [["CAManBase", "Air", "Car", "Motorcycle", "Tank"], _range];

However this sees straight through smokes, fog, rain, sometimes through hillsides when lying prone.  Needless to say it given hits where it shouldn't.  I was hoping I could improve this setup with checkVisibility.  I don't mind it being a little slower as long as it is accurate

Share this post


Link to post
Share on other sites

I was wondering how your experiments with this went on ?

 

I myself am using the following that I found in one of Pierre's scripts

{
if ((side _x != playerSide ) and (!(lineIntersects [eyePos player, eyePos _x, player, _x]) && !(terrainIntersect [[getPosATL player select 0, getPosATL player select 1, (getPosATL player select 2)+0.5], [getPosATL _x select 0, getPosATL _x select 1, (getPosATL _x select 2)+1]]) )) then {

... do stuff ...

};
} foreach (getPosATL player) nearEntities [["CAManBase", "Air", "Car", "Motorcycle", "Tank"], _range];
However this sees straight through smokes, fog, rain, sometimes through hillsides when lying prone.  Needless to say it given hits where it shouldn't.  I was hoping I could improve this setup with checkVisibility.  I don't mind it being a little slower as long as it is accurate

i think upto now its useless. i did not manage to detect smoke with it. even if there was no smoke and a clear LOS it went often to a value of 0. I think its WIP and has to be optimized by BI developpers

  • Like 1

Share this post


Link to post
Share on other sites

i think upto now its useless. i did not manage to detect smoke with it. even if there was no smoke and a clear LOS it went often to a value of 0. I think its WIP and has to be optimized by BI developpers

checkVisibility detects smoke just fine on my end. I tried it in dev branch though, it might be different there.

  • Like 1

Share this post


Link to post
Share on other sites

I used this code picked from some SaoK post in OFPEC long time ago, what do you think?

//Taken from SAok LOS snippet in OFPEC.
private ["_a","_b","_dirTo","_eyeD","_eyePb","_eyePa","_eyeDV","_hayLOS"];
//Player
_a = _this select 0;
//AI to see or not
_b = _this select 1;
_eyeDV = eyeDirection _b;
_eyeD = ((_eyeDV select 0) atan2 (_eyeDV select 1));
if (_eyeD < 0) then {_eyeD = 360 + _eyeD};
_dirTo = [_b, _a] call BIS_fnc_dirTo;
_eyePb = eyePos _b;
_eyePa = eyePos _a;
if ((abs(_dirTo - _eyeD) >= 90 && (abs(_dirTo - _eyeD) <= 270)) || (lineIntersects [_eyePb, _eyePa]) || (terrainIntersectASL [_eyePb, _eyePa])) then {_hayLOS = false;} else {_hayLOS = true};
_hayLOS;

Share this post


Link to post
Share on other sites

 

I used this code picked from some SaoK post in OFPEC long time ago, what do you think?

//Taken from SAok LOS snippet in OFPEC.
private ["_a","_b","_dirTo","_eyeD","_eyePb","_eyePa","_eyeDV","_hayLOS"];
//Player
_a = _this select 0;
//AI to see or not
_b = _this select 1;
_eyeDV = eyeDirection _b;
_eyeD = ((_eyeDV select 0) atan2 (_eyeDV select 1));
if (_eyeD < 0) then {_eyeD = 360 + _eyeD};
_dirTo = [_b, _a] call BIS_fnc_dirTo;
_eyePb = eyePos _b;
_eyePa = eyePos _a;
if ((abs(_dirTo - _eyeD) >= 90 && (abs(_dirTo - _eyeD) <= 270)) || (lineIntersects [_eyePb, _eyePa]) || (terrainIntersectASL [_eyePb, _eyePa])) then {_hayLOS = false;} else {_hayLOS = true};
_hayLOS;

 

I don't think this code takes in account smokes or any other fx hinderances.  But it will probably work for direct line of sight lines I guess ?

Share this post


Link to post
Share on other sites

Totally true!

 

How the hell BIS publishes a super useful LOS command and gives no line in the patch notes, sitrep oprep whatever???

Share this post


Link to post
Share on other sites

Totally true!

 

How the hell BIS publishes a super useful LOS command and gives no line in the patch notes, sitrep oprep whatever???

 

In all fairness it is still WIP, so not sure it can count as an actually publish ...

  • Like 1

Share this post


Link to post
Share on other sites
Guest

The head model object can block the eye and make checkVisibility return 0?

if ( [player, "VIEW"] checkVisibility [eyepos santaClaus, eyepos player] > 0) then { hint "He sees you!"}; 

Share this post


Link to post
Share on other sites

In that example you're telling the command to ignore the player object but then use the eyepos of the player as a reference point.  So you're checking if you can see an object you're ignoring if I understand the command properly.

 

How about trying:

if ( [objNull, "VIEW"] checkVisibility [eyepos santaClaus, eyepos player] > 0) then { hint "He sees you!"}; 

Share this post


Link to post
Share on other sites

In that example you're telling the command to ignore the player object but then use the eyepos of the player as a reference point.  So you're checking if you can see an object you're ignoring if I understand the command properly.

 

How about trying:

if ( [objNull, "VIEW"] checkVisibility [eyepos santaClaus, eyepos player] > 0) then { hint "He sees you!"}; 

nope, its correct to ignore the player model because the line of seight could be interrupted by this model with the result that the command returns 0 even if there is a clear LOS

 

what donnovan did wrong is to start the check at santaclauses position. so the check fails at santaclauses model and of course the player cant be found because its model is ignored...

so donnovan u should change the begin and end object or ignore the model of santaclaus[/size]

if ( [santaClaus, "VIEW"] checkVisibility [eyepos santaClaus, eyepos player] > 0) then { hint "He sees you!"}; 

or

if ( [player, "VIEW"] checkVisibility [eyepos player, eyepos santaClaus] > 0) then { hint "He sees you!"}; 

the above codes should work. the first runs the check from santaclaus to player and the second vice versa.

but if u really need to ignore the objects model where the check starts depend on what u r doin I think.

it maybe that if player looks in the direction of santaclaus that u dont need to ignore players model like did in 2nd code example.

Edited by sarogahtyp

Share this post


Link to post
Share on other sites
Guest

Thankyou.

 

I would like this to return 1, but it will return 0 in any combination of parameters because i can ignore just one model.

 

y2VhNZv.png

Share this post


Link to post
Share on other sites

ok, understood.

try this:

_pl_eye = eyepos player;
_sc_eye = eyepos santaClaus;

_pos_in_dir = _pl_eye vectorAdd ((_pl_eye vectorFromTo _sc_eye) vectorMultiplay 0.5);

if ( [santaClaus, "VIEW"] checkVisibility [_sc_eye, _pos_in_dir] > 0) then { hint "He sees you!"}; 
the code calculates a position 0.5 meters away from players eypos in direction to santa and stores it to _pos_in_dir.

it can be done vice versa with this code:

 

_pl_eye = eyepos player;
_sc_eye = eyepos santaClaus;

_pos_in_dir = _sc_eye vectorAdd ((_sc_eye vectorFromTo _pl_eye) vectorMultiplay 0.5);

if ( [player, "VIEW"] checkVisibility [_pl_eye, _pos_in_dir] > 0) then { hint "He sees you!"}; 
or u can do it without ignoring any object with this code:

 

_pl_eye = eyepos player;
_sc_eye = eyepos santaClaus;

_sc_in_dir = _sc_eye vectorAdd ((_sc_eye vectorFromTo _pl_eye) vectorMultiplay 0.5);
_pl_in_dir = _pl_eye vectorAdd ((_pl_eye vectorFromTo _sc_eye) vectorMultiplay 0.5);

if ( [objNull, "VIEW"] checkVisibility [_pl_in_dir, _sc_in_dir] > 0) then { hint "He sees you!"}; 
in this case it doesnt matter where the check starts so u also could do this in the last line:

if ( [objNull, "VIEW"] checkVisibility [_sc_in_dir, _pl_in_dir] > 0) then { hint "He sees you!"}; 
FYI:

the vector operations r calulating a position at the surface of a sphere around eye pos in the direction of the eyepos of the opposit unit.

better would be to have a point in the middle of the head instead of the eye position. but idk how to get the middle of the head...

Edited by sarogahtyp
  • Like 1

Share this post


Link to post
Share on other sites
Guest

Thankyou a lot!

Share this post


Link to post
Share on other sites

Thankyou.

 

I would like this to return 1, but it will return 0 in any combination of parameters because i can ignore just one model.

 

y2VhNZv.png

 

From Arma 3 v1.61.136673 you can ignore both.

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×