Luft08 27 Posted November 9, 2021 I'm writing a function that should return true or false depending on the visibility of an object by an observer. I worked out all of the vector math stuff (man, I learned that back in college and apparently have spent the last 50 years forgetting what I learned.) but am having a tough time getting meaningful information about object blocking the view. Here is what I have so far: if(!isServer) exitWith {}; params ["_observer", "_target", "_fieldOfView", "_maxDist"]; private _dist = _observer distance _target; if(_dist > _maxDist) exitWith {inView = false;}; private _dir = vectorDir _observer; private _targetPos = (position _target);// vectorAdd [0,0,5]; private _vector = vectorNormalized (_targetPos vectorDiff (position _observer)); private _dotProduct = _vector vectorDotProduct _dir; private _inView = _dotProduct > (cos _fieldOfView); if(_inView) then { intersectionsArray = lineIntersectsSurfaces [ eyePos _observer, _targetPos, _observer, _target, true, 1, "GEOM", "NONE" ]; private _data = intersectionsArray # 0; hint str _data; }; _inview I think I'm close but I don't know how to interpret the data I'm getting back from the lineIntersectsSurfaces function. Share this post Link to post Share on other sites
beno_83au 1369 Posted November 9, 2021 _data should be returning the first result that it intersects with in the format: [intersectPosASL, surfaceNormal, intersectObj, parentObject] https://community.bistudio.com/wiki/lineIntersectsSurfaces 1 Share this post Link to post Share on other sites
Luft08 27 Posted November 9, 2021 1 hour ago, beno_83au said: _data should be returning the first result that it intersects with in the format: [intersectPosASL, surfaceNormal, intersectObj, parentObject] https://community.bistudio.com/wiki/lineIntersectsSurfaces Correct but when the target is behind a building and within range the code returns: [[6755.84,712.766,118.435],[-0.000152588,-0.000210571,1],<NULL-object>,<NULL-object>] And when the target is standing directly in front of the observer the code returns: [[6755.65,712.701,118.435],[-0.000152588,-0.000210571,1],<NULL-object>,<NULL-object>] This does not seem right. Share this post Link to post Share on other sites
beno_83au 1369 Posted November 9, 2021 What object are you trying to return? Because it looks as though you're ignoring the target you're trying to intersect with (you've got _target as an ignored object). Share this post Link to post Share on other sites
Luft08 27 Posted November 9, 2021 5 minutes ago, beno_83au said: What object are you trying to return? Because it looks as though you're ignoring the target you're trying to intersect with (you've got _target as an ignored object). I do. What I would like is for the function to return a Nil or objNull when it does not see anything between the observer and the target. That way I know that the target is visible to the observer but if it returns any intersectObj other than that the view was blocked. Share this post Link to post Share on other sites
beno_83au 1369 Posted November 9, 2021 Just count your returned array. If it's greater than 0, something is blocking the view. If it returns 0 (an empty array - [ ]) then the view isn't blocked. Also, be careful that your line isn't intersecting with the ground: Quote none of the intersectXXX commands will work when initiated from under the ground To put it into perspective, I just jumped into the VR terrain and was getting a ground pos and just using 1 for the ASL height of the start and end positions, but that had the positions BELOW the ground (ground level there is actually 5m ASL). So being that the command wants ASL positions, I was giving it an ASL position with a z-axis of -4 by mistake. Just make sure you're not doing the same. Share this post Link to post Share on other sites
Luft08 27 Posted November 9, 2021 1 hour ago, beno_83au said: Just count your returned array. If it's greater than 0, something is blocking the view. If it returns 0 (an empty array - [ ]) then the view isn't blocked. Also, be careful that your line isn't intersecting with the ground: To put it into perspective, I just jumped into the VR terrain and was getting a ground pos and just using 1 for the ASL height of the start and end positions, but that had the positions BELOW the ground (ground level there is actually 5m ASL). So being that the command wants ASL positions, I was giving it an ASL position with a z-axis of -4 by mistake. Just make sure you're not doing the same. In my code I trace from the observer's eyePos to the target. (Isn't that always going to be above ground?)I also tried raising the trace above the target in case the position of the target was under the ground. i.e. private _targetPos = (position _target) vectorAdd [0,0,5]; position _target should return a Position in AGLS format shouldn't it? I'm unclear about what I should change in my code? UPDATE: I just tried raising the position of the observer and target by a vectorAdd [0,0,3] and the function returned: [[6729,669.414,119.037],[-0.0528591,-0.998602,-0],1700230d600# 38092: gm_euro_house_08_w.p3d,1700230d600# 38092: gm_euro_house_08_w.p3d] So I lowered the observer position by one meter i.e. vectorAdd [0,0,2] and got the null objects again. I obviously do not have a handle on how the position and eyePos commands work. Do I need to determine the height above sea level of the ground and add it in? I though that is what the position and eyePos commands were doing by returning AGLS positons? Update 2 My testing is inconsistent. I moved the units and now I get objNull no matter what the vectorAdd value is. I'm officially lost... Share this post Link to post Share on other sites
Alert23 215 Posted November 9, 2021 im not sure if i understand your problem right but im using this to check if a unit is visible to another unit checkVisibility BIS_fnc_inAngleSector tested like this [] spawn { while {sleep 1;true} do { if ( [getposATL spectator1, getdir spectator1, 80, getposATL player] call BIS_fnc_inAngleSector && [ObjNull, "VIEW"] checkVisibility [eyepos spectator1, eyePos player] > 0) then { hintSilent "he sees you";} else { hintSilent "he can't see you";}; }; }; ps: if not helpful please ignore 😅 Share this post Link to post Share on other sites
Larrow 2820 Posted November 9, 2021 4 hours ago, Luft08 said: position _target should return a Position in AGLS format shouldn't it? Yes but lineIntersectsSurfaces expects an ASL position. Observer is ok as you use eyePos which returns a position ASL. Just change both your position commands to getPosASL. private _targetPos = getPosASL _target; private _vector = vectorNormalized (_targetPos vectorDiff (getPosASL _observer)); 1 1 Share this post Link to post Share on other sites
Luft08 27 Posted November 9, 2021 8 hours ago, Larrow said: Yes but lineIntersectsSurfaces expects an ASL position. Observer is ok as you use eyePos which returns a position ASL. Just change both your position commands to getPosASL. private _targetPos = getPosASL _target; private _vector = vectorNormalized (_targetPos vectorDiff (getPosASL _observer)); That was it! Thanks! It's the small details that get me every time. Share this post Link to post Share on other sites
Luft08 27 Posted November 9, 2021 For anyone who might find a "inView" function useful, the final (not well tested) code is: if(!isServer) exitWith {}; params ["_observer", "_target", "_fieldOfView", "_maxDist"]; private _inView = false; private _dist = _observer distance _target; if(_dist > _maxDist) exitWith {_inView}; private _dir = vectorDir _observer; private _targetPos = (getPosASL _target); private _vector = vectorNormalized (_targetPos vectorDiff (getPosASL _observer)); private _dotProduct = _vector vectorDotProduct _dir; _inView = _dotProduct > (cos _fieldOfView); private _intersectionsArray = []; if(_inView) then { _intersectionsArray = lineIntersectsSurfaces [ eyePos _observer, _targetPos, _observer, _target, true, 1, "GEOM", "NONE" ]; private _data = _intersectionsArray # 0; if(isNil "_data") then { _inView = true; }; }; _inView To use pass in the observer object, the target object, the maximum angle (field of view) and maximum distance visible. Example: (After compiling function) : inView = compileFinal preprocessfilelinenumbers "inView.sqf"; [soldier_1, player, 90, 150] call inView; If the function returns true the observer can see the target. Share this post Link to post Share on other sites