Jump to content
Sign in to follow this  
[frl]myke

Script/function request: Line-of-sight check

Recommended Posts

Hello lads,

although i'm fairly good at scripting, i really suck on any form of math. Thats why i have this request:

I need a script/function that checks if object A has a free line-of-sight to object B.

I'm not pitty about how it's done and i would be happy with a simple script that only checks terrain and wont take objects into account. Although i would surely also take such a solution. :D

I do not need a ready-to-use solution if someone just could take my hand and lead me through the mathematics (and please, regarding math, talk/explain it to me as you would to a 3 year old), i guess i could wrap it myself into scripting synthax.

Any help on this would be much appreciated.

Myke out

Share this post


Link to post
Share on other sites

I also suck at maths so cannot help but I wonder if object A is a player? If he were you could possibly use WorldToScreen and then ScreenToWorld the result to find where the line of sight intersects with terrain. Apart from that I have no idea, odd that there is no built in function.

Share this post


Link to post
Share on other sites

Sadly this isn't the case. The final result should be some kind of AA radar assigning known targets to attached AA units. This is completely AI related so i have to check if the AA-radar can actually see a air vehicle or not.

Since these info's will never be seen by a player, accuracy is less of a topic as functionality and performance. Air vehicles possibly hidden by foliage i can probably fake by ignoring objects flying below a certain height. The final result is subject of tweaking but one of the most imminent problems is the general line-of-sight.

I want it that players can avoid radar detection by using terrain.

Share this post


Link to post
Share on other sites

Right, well at the risk of embarrassing myself (the blind leading the blind here) I would consider:

1. Imagine the triangle formed by the radar, the aircraft and the right angle between them. You know the length of two sides (2d coordinates, difference in altitude) from which you can determine the vertical angle of the aircraft as seen from the radar. No idea what the formula is off the top of my head but it'll be easy to find.

2. Sample at intervals from radar to aircraft (say 100m) the same angle for the terrain height at each interval (no idea how you can read this without actually placing an object). If at any stage the angle is larger than the angle to the plane it is concealed.

Share this post


Link to post
Share on other sites

The intersect command is an exercise in frustration for me. The description of the command is written EXTREMELY poorly. It is a confusing run on sentence that means NOTHING. The example code provided is next to worthless. There are no working examples of how it really works in the entire forum. I just searched and its mentioned in this thread and a few others as "interesting" but no one has stepped up and really presented a working plain language example of how its implemented. It seems like its supposed to draw a line between two pos arrays and returns an array if anything intersects the line but as I test it it just returns an empty array no matter how I position things. Maybe Im not understanding or my knowledge of LOD's and things is not good enough to figure it out. But if the command was presented properly by BIS then I wouldnt have to figure anything out. I guess we need to solve our problems with enhancing ARMA2 with a blindfold on and one hand and foot tied behind our backs.

I am extremely annoyed and frustrated with the silence over this command and I think someone from BIS should come into this thread and give us a well presented, plain language explanation of intersect and also provide a working example that actually makes sense instead of the worthless wiki entry.

I know why people want LOS code, its a powerful thing to be able to tell if clear LOS is present because thats half the battle to getting AI to dive behind cover quickly, probably a thousand other great reasons. Sure you can do a topagraphic check to see if the ground is higher than the sight line at any point between shooter and target ( I made a script for it). But that solution is cumbersome and seems geared towards rolling terrain and might get screwed up on buildings and other terrain elements that are different from rolling hills. So its good way but not dynamic enough for various island sections.

If you look at the laser designator you can shoot the laser between two points and if anything is in the way the laser object stops exactly there. Seems a simpler system to check LOS to me. We just need a proper "ray" object that exists in other games allready.

I also notice we have canstand canfire canmove checks but no CANSEE check? No isvisible check? Major ball drop on the part of BIS there. Simple ray check command and all this ridiculous monkey head/belly scratching we have to do to solve LOS would not occur.

If we had a invisible/silent bullet addon that could shoot a test bullet between two objects then the final position of the bullet can also check LOS, if the bullet stops short then no LOS and that is a position of cover.

Since I cant use intersect which seems like it might be perfect for this the "invisible bullet" method is the best I can think of.

What I will try when I have time is this:

Spawn a "bullet" object and deletecollection the object

-this can be a barrel or other small plain object that has physics in its config (cant be an object that doesnt fall after you setpos it up in the air). Deletecollection is cosmetic to remove the visible geometry. Bullet objects seem to fire when createvehicled unless Im doing something wrong there.

Then get the vector between the shooter and target objects. Not only azimut but also vector up/down which is allready possible with some trig code. Bank vector is not needed.

Place the invisible bullet object at shooter position and setdir and vector its direction to the target position and then setvelocity the object accross the LOS distance. If any objects are in the way then the bullet object will stop there and a check can be run if the bullet made the distance between objects. So if the distance was made then LOS = TRUE. If distance was short then LOS=FALSE.

Thats as clean as I can work the logic of it but maybe someone else can show us all a better way. I would love to learn something about this problem because I have been thinking about it since OFP!

So now a target unit can try to search for cover positions with LOS check. He can run the LOS position in a circle radius around his position and find the nearest position that fails LOS check between target and shooter. The result for player would be a target starts moving behind buildings as soon as the shooting begins. Once the target has reached cover, more code should be run to do additional things like, firing from cover position. The target can run LOS check back to shooter and increment out to find the nearest clear LOS position. Then they can move between a cover position and shooting position. This could even be done with crouch and stand for building tops. And can use terrain where units pop up from behind a ridge and then dissapear as they receive return fire.

Edited by TJ72
Typo

Share this post


Link to post
Share on other sites

@Dr_Eyeball

thanks for the idea. However, i think the intersect command doesn't fit here. From what i understand, it returns a named selection of an object standing in a imaginary line between point A and point B.

Looking at the example code in the BIWIKI:

[_tank, "VIEW"] intersect [[1500, 1500, 2], [1550, 1500, 2]]

Ok, the position arrays may represent the LOS between the radar and a Helo (as example). The var _tank is the object that has to be checked if the LOS hits a selection of this particular object.

So i have to know previously that object _tank is in the LOS and therefor a intersect check is pointless since the simple fact that i know it is there, answers the question.

The other way around, taking the Helo as _tank object is rather pointless since the intersect will not check if any other objects are in the LOS between Radar and Helo.

So intersect will not help here although it was worth to think about it.

There is a LOS routine already in the game. Just look at vehicles radar. It does exactly what i want. It shows contacts if there is a clear LOS to it. Whats missing is a way to access this routine by a simple scripting command, like:

_bool = _obj1 hasLOS _obj2;

This would be enough to work with.

@TJ72

This bullet method sounds interesting. Will do some investigations with it, maybe there is a way to fake LOS with this system. Will report back as soon i get some results. Do you know just from the top of the head if there is a bullet class which isn't "affected" by ballistics? Right now i think this is a point where this method could fall short.

Share this post


Link to post
Share on other sites

Myke!

Thank you for the info you have on intersect. My understanding of how it works is greatly increased!

Now that you have explained it better I get an idea:

A suppressed target unit can somehow get direction of shooter. Then check for nearestbuilding or nearestobject(s) somehow and then check to see if that nearest object(s) relative cover position to the shooter intersects in any way. So if the appropriate object can be "grabbed" with some clever scripting then that object can be checked with intersect to see if any positions the target unit can reach can be designated as cover postition. We don't care what part is intersecting with the line, just if anything is intersecting at all and we have a LOS check of sorts. So its not a strict LOS idea but a directly related idea that will involve LOS and can specifically handle buildings. Also this could be used for an area filled with editor placed objects like wrecks and sandbag walls. More testing will be done on this idea by me when I have time.

After all the better cover finding by AI the longer the battle lasts!

Well I was testing my invisible bullet idea (all day) yesterday and it was semi successful.

Some Testing Notes for my idea for a Scripted "LOS" or Line of Sight system for Arma2:

I used a createvehicled Red Barrel Object to test and create a scripted LOS system and that object is called barrel in the below text. Don't confuse with gun barrel. Please see above post by my for summary of "Invisible Bullet Idea".

A neat thing I found was that if you can get a unit to simply aim his rifle at the target you can pull weapondirection array and then plug that into the setvectorup of the spawned barrel object (first I setpos it in front of shooter then setdir the barrel to the shooters direction) then input the weapondir array into a setvelocity on the barrel object multiplied by a certain factor and it was a quick and dirty object launcher.

In the below code the _projectile is the spawned barrel object.

The factor variable is the speed float that is the "throttle" for the effect.

_shooter is a unit that the script is run on.

_target is target object, not position array.

_shooter lookat _target
~1
_shooter dotarget _target
~3
_weapon = currentweapon _shooter
_weapondir = _shooter weapondirection _weapon
_cam2="Camera" camcreate [0,0,0]
_cam2 camsettarget _shooter
_cam2 camsetrelpos [0,2,1]
_cam2 camcommit .1
~.2
_startpos = getpos _cam2
camdestroy _cam2
_dir11 = direction _shooter
_projectile setdir _dir11
_projectile setpos _startpos
[b]_projectile setvectorup _weapondir
_factor = 200
_vel1 = (_weapondir select 0)*_factor
_vel2 = (_weapondir select 1)*_factor
_vel3 = (_weapondir select 2)*_factor
_projectile setvelocity [_vel1,_vel2,_vel3][/b]

So it got the angle vector and velocity parts done by passing through just commands and not any raw math was needed. I never knew that was possible. Nothing against the math but this seems simpler. So it was an interesting byproduct of the testing that may come in handy in general.

I had a formula to aim the vectors from position to position and it is still needed because if the target is too far away the AI unit switches to binoculars and screws up the weapondirection check as his rifle is pointed straight down. But I had trouble plugging the vector positions into a clean setvelocity array and the barrel flew the wrong way from intended. I just am screwing up here somehow.

I had to fast loop the setvelocity part later in the script to keep the object on a straight line to target as gravity pulls it down. Also If I ran the barrel script on multiple units and the performance of the script degraded. The barrels all started dropping early when there was too many units using them. So its resource hungry method I come to find. It cant be run on every unit in a large group without performance hit.

The result was a flying barrel starting from shooter to his target that seemed to verify LOS in a medium to long range, terrain based "fuzzy" way. If there is ground between shooter and target this performs very well. Trees seem to have mixed effect which I liked. Bushes will not collide with the object as far as I can tell. I was somewhat pleased with this result but it wasnt nearly as "sharp" and dynamic as I wanted for close range urban areas.

When I sent the barrel through towns to a target object I knew was behind hard building type cover, the collision detection of the game failed and the barrel would not bounce off anything except certain buildings from certain angles. I tried to adjust my velocity factor and loop speed to try to optimize the collision detection, I even tried a hit EH on the barrel but it didnt work as expected. I didnt test this on editor placed objects so they may collide properly or do the same thing. I had to resort to a nearestbuilding check on the barrel in flight to see if it was getting near buildings, if near 3 meters then "hit". The effect was that towns and buildings created a soft sense of cover where if you were blocks deep in a town then the LOS check would fail but if you were behind a single building or wall or fence the barrel would not detect a hit and that position would pass LOS when there really is none. Sometimes it worked, sometimes not so I cant call that reliable or acceptable performance in this type of area.

The results were only a bit better than my topographic test I did last year. But it does seem slightly more reliable and dynamic so I will keep working on it and if I can get it into a presentable state I will release something that uses it. It could be useful tool for general LOS check between various unit types and should be an optimized and heavy stress tested thing since it will most likely run scripts on multiple units/and groups at the same time.

So another way from my idea seems to be needed for "Sharp" LOS functionality and I can try some intersect ideas and see if I can proove any concepts that are useful and post them here. We need a way to tell if a line intersects with any piece of hard geometry at all. It doesnt matter if its hard or soft cover because its for LOS and any kind of geometry that holds a texture will block view. If we can at least find if anything is blocking a perfectly straight line between two points and then later decide if it should be fired on based on later checks, we will have a razer sharp LOS check system that will greatly enhance ARMA2 for a variety of allready discussed reasons.

Share this post


Link to post
Share on other sites

@TJ72

Impressing stuff you're testing there mate. However, what you do actually isn't of any help for the opening problem. Your way is based on a unit which you may control as in "look there" and "target this". What i need is an independent script/function which works with any type of object on both sides.

The thing i'm working on, where i need this functionality, is open and dynamic from missionmakers view. Anything could be the radar emitting object, even a road cone (pointless but nonetheless possible). Also thougt about to go the other way around, testing from target position but also there your way would fall short since it requires the target to watch in direction of the radar which is rarely enough give.

I really appreciate your efforts and i'm pretty sure if you were able to create something working based on your way, people will love it and praise you. However, for what i need, it isn't usable this way.

Share this post


Link to post
Share on other sites

Myke,

Understood, but the concept is still sound.

There is code to get an objects vectordir and up to another position and if I can get it to work I will post that code. That code is lengthy and so the trick method I found was a workaround.

I just couldnt get my "bullet" object to setvelocity from zero properly because of my scripting limits but not the ideas.

Even still an invisible unit or object can be spawned and setpos'd and used for the check and removed when done, all within the script and will still be "open and dynamic from missionmakers view". It doesn't have to involve the missionmakers placed AI units at all, except to reference their positions.

Im just sharing my methods and I'm interested in peoples alternative methods to your question and hope to get you a solution at some point.

If the thread gets packed with enough info about the subject around your question it becomes very useful for searching later and so others can learn and research. After a while everyone can use LOS function in their missions and we all get improved gameplay down the road. Thats my motivation over love and praise of other users.....

For the radar method, unless there's commands and methods I dont know, It seems like a special vehicle or config may be needed which moves us out of this board into A/M sections. I don't know addon authoring but I know it adds more flexibility to a given modification idea as you can create special vehicles that run scripts automatically and use special configs. So a special radar-using vehicle addon combined with a basic script to get LOS from point A to B is the thought I get from your idea.

Anyway if I can think of more ideas that will help solve the LOS problem I intend to add them to your thread for reasons stated above.

Share this post


Link to post
Share on other sites

@TJ72

No problem mate, you're doin fabulous things there. And also no problem with posting stuff here that covers the topic, even if it doesn't help (no offense, mate) to my actual problem.

However, your last post put an idea in my head: as the stuff i'm actually working will result in an addon (but the problem right now is still pure scripting so it fits better here) i have no problem with including something addon-based. And yet i have something in mind that i want to try out. If i create a invisible "vehicle" with a AI gunner and a LaserDesignator as weapon...

I'm not good at professional explaining so let me put it in simple words. Vehicle is invisible and indestructible (will be then finally). I command gunner (which is also invisible since i wont put a proxy, see UAV's, same idea) to target and fire the laserdesignator. This weapon creates a laserpoint which is actually detectable by nearestObjects command and similar. And it also get's blocked by any obstacle in the way.

So, finally i have to check if laserpoint object is closer to radar than the targetted Helo. If so, i can assume that there is no LOS between radar and Helo.

Will check that out, for me this sounds promising. If it works, i may even create a standalone addon for it.

Just go ahead with posting ideas and stuff that comes to your mind. Without it i wouldn't had this idea. Thanks mate, really much appreciated.

Share this post


Link to post
Share on other sites

I'm sorry, i don't bump my threads usually but this one has some importance to me and i've waited unless it was more than 2 pages behind.

So if a kind soul could come up with a solution (or a developer will jump in and say there will be a scripting command in the next betapatch) i would be really happy.

Share this post


Link to post
Share on other sites

This is what is use inside Mando Missile:

/*
  mando_check_los.sqf v1.0
  Sep 2006 Mandoble (Mando Missile Suite)

  Parameters:
     Generic los created outside
     Origin object
     Destination object
     jump for each iteration in meters
     Delta Z over origin

     Done inside mando_missileinit.sqf at mando missile initialization
     mando_check_los = compile (preprocessFileLineNumbers (mando_missile_path+"mando_check_los.sqf"));

     Usage (_loglos already created with _loglos = "logic" createVehicleLocal [0,0,0];):
     _los_ok = [_loglos, _firer, _target, 20, 2] call mando_check_los;
*/


private["_log", "_orig", "_dest", "_poso", "_posd", "_vdir", "_dist", "_los_ok", "_delta", "_deltaz"];
_log    = _this select 0;
_orig   = _this select 1;
_dest   = _this select 2;
_delta  = _this select 3;
_deltaz = _this select 4;


_poso = getPosASL _orig;
_poso set [2, (_poso select 2)+_deltaz];
_posd = getPos _dest;
_log setPosASL _poso;
_log setDir 0;
_dist = _log distance _dest;
_posd = _log worldToModel [_posd select 0, _posd select 1, (_posd select 2)+_deltaz];
_vdir = [(_posd select 0)/_dist, (_posd select 1)/_dist,(_posd select 2)/_dist];


_los_ok = true;
for [{_j = 20},{(_j < (_dist - 10)) && _los_ok},{_j=_j + _delta}] do
{
  _log setPosASL [(_poso select 0)+(_vdir select 0)*_j,(_poso select 1)+(_vdir select 1)*_j,(_poso select 2)+

(_vdir select 2)*_j];

  if ((getPos _log select 2) < -0.5) then
  {
     _los_ok = false;     
  };
  Sleep 0;
};
_los_ok;

I'm also working on a better way which might be ready soon, anyway that code above should work for you.

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
Sign in to follow this  

×