Home   Help Search Login Register  

Author Topic: Line Of Sight Checking Script!!!  (Read 6409 times)

0 Members and 1 Guest are viewing this topic.

Grendel

  • Guest
Line Of Sight Checking Script!!!
« on: 31 May 2005, 21:35:46 »
So I was out of the OFPEC net this Memorial Day Holiday, But I was very busy working on a....secret project.

One of the things I needed was a way to see if a unit has LOS to another, regardless of the AI.  So I put on my thinking cap and found a solution that works!  

Does anyone know if someone has done this already? I couldn't find anything...

If not, I will post an appropriate Demo Mission ( I would have posted it on the beta page but wanted to see if it has been done...and I sort of forgot to put it on my thumb drive).  I am using it to further enhance one of my AI er...enhancing scripts, and it has many possible applications for the savy scripter.

For those that A) CARE and B) LIKE MATH here is how it works (feel free to ignore if A and B do not apply and go to the end):

The script first finds the distance between two units.  This becomes side A of a right triangle.

The script then gets the height above sea level for the two units. It uses the height difference to form the B side of the triangle.

Everything is shifted up .5 meters to keep the LOS above ground level (and is a compromise value  for OFP having no decent prone detection)

The direct LOS is the hypotneuse (side C) of the right triangle. Pretty  simple. Here comes the tricky part:

To check the LOS, the script uses a sine/cos projection from the low-unit in the direction of the high-unit in one meter incriments setposing an invisible 'H'.

The ratio of the heigt of the hypotneuse from any point along the side A, is B divided by A. The script checks the height ASL of the setpos'd 'H', and if it is higher than the point along the hypotneuse...Viola: NO LOS!

The End: It works!

-Grendel


Offline dmakatra

  • Members
  • *
  • Better known as Armsty
Re:Line Of Sight Checking Script!!!
« Reply #1 on: 31 May 2005, 21:40:15 »
I'm sorry, it's been done before. But it's a damn good workaround anyway. The only problem is that it doesn't work if a unit is behind a car or a house. :'(

:beat: *Gets Shot* :beat:

Grendel

  • Guest
Re:Line Of Sight Checking Script!!!
« Reply #2 on: 31 May 2005, 22:09:26 »
Do you know where I can find the one done already and/or how it works?...hopefully it is a function and works better and quicker than mine (need to learn functions but...tooo...lazy)

And yeah, the building/car thing is a problem, but if you used a nearestobject function to check for these things at the invis 'H''s location maybe...

Does the other one find this stuff already?

-Grendel

Offline General Barron

  • Former Staff
  • ****
  • Semper Fi!
Re:Line Of Sight Checking Script!!!
« Reply #3 on: 01 Jun 2005, 02:30:23 »
Lets see.... I think LCD posted a script on the forums years ago that sorta worked for finding LOS. I never checked it out myself, so I don't know how/if it worked.

Your method sounds like it would work, but only for finding if there is terrain in the way. I might suggest automatically adjusting the increments between test points depending on the distance between the two units though.

Quote
but if you used a nearestobject function to check for these things at the invis 'H''s location maybe...

This prolly would work pretty well. It would be a hassle to code, and it might make the script run pretty inefficiently, but it could work! You can take apart my find cover function here to see how to find... er, cover, with nearestobject.

Oh, and you really should learn how to do functions. They are really easy to make, and darn useful.

HANDSIGNALS COMMAND SYSTEM-- A realistic squad-control modification for OFP
kexp.org-- The best radio station in the world, right here at home! Listen to John Richards!

Grendel

  • Guest
Re:Line Of Sight Checking Script!!!
« Reply #4 on: 01 Jun 2005, 05:17:21 »
***Long winded post alert***
You have been warned!

Quote
I might suggest automatically adjusting the increments between test points depending on the distance between the two units though

Well, I set the interval as an easy to edit variable in the script and it has comments to that effect, but actually, on my 1.5ghz it only takes about 1 second per 500m or so at 1m resolution. That is using drop particles to show the LOS hypotneuse and the terrain track (for debugging/proof of principle).  it also drops a large particle  where the offending terrain is at if LOS is blocked.

Quote
You can take apart my find cover function here to see how to find... er, cover, with nearestobject.

Thanks, will do.

Quote
Oh, and you really should learn how to do functions.

grumble, grumble..yeah. LOL!

I just thought of a new method though that might work in almost all situations: terrain, buildings, etc (Jinxed myself there):

If I config'd a new ammo class 'shell', with a damage of zero and no explosion effects, and had it setposed along the LOS hypotneuse (no longer needing the ground trace), I could just check to see if it "blew up" (! alive _shell or something) anywhere other than the target unit's location (or at a farther distance than the unit-should it be prone)!

Other than foilage (which would still need the nearest object querry) it would work on anything with collision detection...buildings, terrain, the tree trunks, cars, chickens, nuns, etc

Downside: would need to download a TINY .pbo for the new ammo.

Thoughts General Barron (or anyone)?

-Grendel




Offline Morglor9

  • Members
  • *
Re:Line Of Sight Checking Script!!!
« Reply #5 on: 01 Jun 2005, 05:51:58 »
i'm looking for a script that has this, but when the player's crosshair goes over the unit it shows either red (enemy) or green (friend), using a CutRsc, to create an IFF (identify friend or foe) system. anyone know of a script that does this/care to make it?
Cymbaline

Chad

  • Guest
Re:Line Of Sight Checking Script!!!
« Reply #6 on: 01 Jun 2005, 07:21:46 »
This is my higher language code that i use to find the if a target can/cannot see the target. Only problem i find is that the speed at witch the calculations are done in ofp are abit slow, i am hopping if anyone of you guys can actualy see the bottleneck with my calculations?

Code: [Select]
// Author Chad Lion
// Version: 1.00
// Date: May 3, 2005
//
// This document is for demonstration purposes.
// Its to reflect a ongoing development of two current projects
// One the object orientated compiler and the next is the
// A.I. Heuristic
public class TanTarget{
   public int lastknown[];
   
   /**
    * Draws a virtual line from the object to the target
    * if the absolute height of the terriean is
    * higher than the target, then the object cant see
    * the target return
    */
   public boolean CanSee( object me, object target ){
      int mypos[] = getposasl me;
      int mytarget[] = getposasl target;
      int aheight;
      int tmpheight[];
      int tmp[];
      int adir = 0;  
      int dist = me distance target;
      int angle = atan((mytarget[2]-mypos[2])/dist);
      object camera = "logic" camcreate [0,0,0];
      boolean result = true;
      int sina;
      int cosa;
     
     
      adir = DirToObj( me, target );  
      sina = sin adir;
      cosa = cos adir;
      for( int i = 0; i < DistancePos( mypos, mytarget ); i = i + 5){  
         aheight = i * (tan angle);
         tmp = [((mypos[0]) + (sina*i)), ((mypos[1]) + (cosa*i)),0];

         camera setpos tmp;
         tmpheight = getposasl camera;
         
         // Calculate the terreian is in the way or not
         // plus 0.5 for guns position
         if( tmpheight[2] > ((mypos[2] + aheight)+0.5) ){
            lastknown = tmp;
            result = false;
            i = DistancePos( mypos, mytarget );
         }else{
            freeheap( tmp );
         }
         
         tmp = [((mypos[0]) + (sina*i)), ((mypos[1]) + (cosa*i)), (((mypos[2] + aheight)+0.5) -  (tmpheight[2])) ];
         dropSmoke( tmp );
      }  
     
      camdestroy camera;
      freeheap( mypos );
      freeheap( mytarget );
      freeheap( tmpheight );
      return result;
   }
   
   
   
   /**
    * Calculate the Degree from one object to another
    */
   public static int DirToObj( object me, object target ){
      int ai[] = getpos me;
      int thetarget[] = getpos target;
      int result = 0;

      result = (thetarget[0] - ai[0]) atan2 (thetarget[1] - ai[1]);
      if( result < 0 ){
         result = result + 360;
      }

      freeheap(ai);
      freeheap(thetarget);
      return result;
   }

   /**
    * Calculate the Degree from arraypos to another arraypos
    */
   public static int DirToArrayPos( int ai[] , int thetarget[] ){
      int result = 0;

      result = (thetarget[0] - ai[0]) atan2 (thetarget[1] - ai[1]);
      if( result <= 0 ){
         result = result + 360;
      }
     
      return result;
   }

   
   /**
    * Calculate the absolute height for object
    */
   public static int AslHeightObject( object person ){
      int pos[] = getpos person;
      int dist = 0;
      int ground = 0;
      object camera;
     
      camera = "logic" camcreate [0,0,0];
      dist = camera distance person;
     
      ground = (pos[0] ^ 2) + (pos[1] ^ 2);
      camdestroy camera;
     
      freeheap( pos );
      return sqrt((dist ^ 2) - ground);
   }

   /**
    * Calculate the absolute height for position
    */
   public static int AslHeightPosition( int pos[] ){
      int dist = 0;
      int ground = 0;
      object camera;
      object tmp;
     
      camera = "logic" camcreate [0,0,0];
      tmp =    "logic" camcreate [0,0,0];
      tmp setpos pos;
     
      dist = camera distance tmp;
      ground = (pos[0] ^ 2) + (pos[1] ^ 2);
     
      camdestroy camera;
      camdestroy tmp;
      return sqrt((dist ^ 2) - ground);
   }


   /**
    * Drop smoke at a location, used for debugging
    */
   public static void dropSmoke( int pos[] ){        
      drop ["cl_basic",
       "",
       "Billboard",
       0.01,
       40,
       [pos[0],pos[1],pos[2]],
       [0,0,0],
       0,
       1.1,
       0.861584,
       0,
       [0.5,1],
       [[0, 0, 0, 1],[0, 0, 0, 1],[0, 0, 0, 1],[0,0,0,1]],
       [0],
       0,
       0.01,
       "",
       "",
      ""];      
   }

   /**
    * Used to calculate the distance from one position to the next
    */
   public static int DistancePos( int pos[], int end[] ){
      return sqrt( (pos[0]-end[0])^2 + (pos[1]-end[1])^2 );
   }
}
« Last Edit: 01 Jun 2005, 07:31:45 by Chad »

Grendel

  • Guest
Re:Line Of Sight Checking Script!!!
« Reply #7 on: 01 Jun 2005, 16:34:35 »
Chad,

It looks to be a matter of streamlining....

Mine does pretty much exactly what yours does, just with less calculations methinks?


Code: [Select]
#ut
player sidechat "Checking LOS"
_orig=u1
_targ=u2

_dist=_orig distance _targ
;player sidechat format ["_dist:%1",_dist]
_aslt=[_targ] call getASLheight
_aslo=[_orig] call getASLheight

?(_aslt>_aslo):goto "targhigh"
;orighigh
_h=(_aslo-_aslt)+.5
_lowunit=_targ
_highunit=_orig
_luh=(_aslt+.5)
goto "skiptarghigh"

#targhigh
_h=(_aslt-_aslo)+.5
_lowunit=_orig
_highunit=_targ
_luh=(_aslo+.5)

#skiptarghigh
;player sidechat format ["_lowunit:%1,_highunit:%2",_lowunit,_highunit]

lup setpos getpos _lowunit
hup setpos getpos _highunit
_dir=[lup,hup] call dirtoobj

lup setdir _dir
_lupos=getpos _lowunit
_lx=_lupos select 0
_ly=_lupos select 1

_ratio=(_h/_dist)
;player sidechat format ["_h: %1, _ratio:%2",_h,_ratio]
;;;;;;;;;LOS resolution in meters (1=check los at one meter intervals);;;;;;;;
_r=1
_di=1
#chklos
.1
_di=_di+_r
_nlx=_lx+(_di*(sin(_dir)))
_nly=_ly+(_di*(cos(_dir)))

checkheight setpos [_nlx,_nly]
drop ["cl_fire", "", "Billboard", 1,3, [0,0,0], [0, 0, 0], 0, 1.275, 1, 0, [.1,.1],[[1,1,1,1],[1,1,1,0]],[0],0,0,"","",checkheight]
_chasl=[checkheight] call getASLheight
;player sidechat format ["Checkheight ASL:%1",_chasl]

_losheight=(_luh+.5)+(_di*_ratio)
drop ["cl_fire", "", "Billboard", 1,3, [0,_di,(_di*_ratio)+.5], [0, 0, 0], 0, 1.275, 1, 0, [.1,.1],[[0,1,0,1],[0,1,0,0]],[0],0,0,"","",lup]
;player sidechat format ["LOS ASL:%1, _di:%2",_losheight,_di]
?(_chasl>_losheight):goto "nolos"
_cld=checkheight distance hup
;player sidechat format ["_cld:%1",_cld]
?(_cld>_r):goto "chklos"
player sidechat "LOS is clear"
~1
goto "ut"

#nolos
player sidechat "No clear LOS"
drop ["cl_fire", "", "Billboard", 1,30, [0,0,.5], [0, 0, 0], 0, 1.275, 1, 0, [1,1],[[1,1,1,1],[1,1,1,0]],[0],0,0,"","",checkheight]
exit

It's not commented very well (I'll fix that tonight) but there you go.

Here is a demo mission, I yanked it out without setting default units, so tou need BAS ranger/Delta (for no reason other that I was in a big hurry and forgot to clean up the mission .sqm, sorry-will fix with updated code)

-Grendel

Offline dmakatra

  • Members
  • *
  • Better known as Armsty
Re:Line Of Sight Checking Script!!!
« Reply #8 on: 01 Jun 2005, 16:37:26 »
i'm looking for a script that has this, but when the player's crosshair goes over the unit it shows either red (enemy) or green (friend), using a CutRsc, to create an IFF (identify friend or foe) system. anyone know of a script that does this/care to make it?
That cannot be done.

@ Barron: LCD made such a script yes. But in that you needed to define every object in the mission area. Kinda sucks if the mission is spanning across the island. ;)

:beat: *Gets Shot* :beat:

Offline Morglor9

  • Members
  • *
Re:Line Of Sight Checking Script!!!
« Reply #9 on: 01 Jun 2005, 22:25:05 »
ok, i didn't think it would be possible, but now i know for sure. thanks.
Cymbaline

Grendel

  • Guest
Re:Line Of Sight Checking Script!!!
« Reply #10 on: 02 Jun 2005, 01:20:15 »
Chad after further review  of your script, I think I know where the 'bottleneck" is..

It appears that you are using your script to calculate the absolute height....

There is a function that does this made by TakeOffTim (found in the Ed Depot funcitons section here at OFPEC), and functoins ALWAYS run much quicker than scripts as they are preloaded into RAM at the begining of the mission.

I am working on the new script that uses a setpos'd shell along the virtual LOS, to check for any oject or terrain. This should be both more effective in finding the true LOS and be quicker.

-Grendel

Chad

  • Guest
Re:Line Of Sight Checking Script!!!
« Reply #11 on: 02 Jun 2005, 04:32:52 »
Grendal do you have msn or icq i would like to talk to you about acouple of things. Do you use team speak?

I will post my code when i get home later on tonight for you to have a look at.

My contact details are
icq: 20758380
msn: doodo477@hotmail.com

Offline Fragorl

  • Coding Team
  • Former Staff
  • ****
Re:Line Of Sight Checking Script!!!
« Reply #12 on: 02 Jun 2005, 05:26:50 »
Taking a bit of a stint from ofpec on account of exam season at the moment, but this thread reminds me....

I made a function a couple months ago now, which is pretty much the same as Chad/grendel's two versions except it uses vectors & no trig... the function (in the demo mission) is here[/url].

There is no bottleneck, the only problem with it is that there's no way of knowing the dimensions of any of the objects.... and I still don't think there is a solution to this.

My next attempt to do a los check was with a physical object..... a bullet.

Eventually, after much agonising and optimising, I came up with a decent script (not function) which could get the position of a colliding object along a line AB to within one metre. Being a script not a function, it is quite difficult to implement as it does not *instantaneously* return a value.

The lmitations:

The tracing object is subject to gravity - any traces over ~100 metres are too inaccurate
The script takes time to return a value
If multiple instances of the trace script are running, the trace position gets more and more inaccurate.

I haven't released this script yet, but if anyone wants it...

Chad

  • Guest
Re:Line Of Sight Checking Script!!!
« Reply #13 on: 02 Jun 2005, 11:19:01 »
Well its nice compairing a hand writen version of a script to my compilers emited code. Though I am re-designing the emited instructions. The reason for this is mostly because i ran both your script and mine side by side, and yours came out so far ahead its not funny. So i am just revisiting the code emmited by the compiler.

Chad.

Offline Fragorl

  • Coding Team
  • Former Staff
  • ****
Re:Line Of Sight Checking Script!!!
« Reply #14 on: 02 Jun 2005, 12:20:51 »
I'm eagerly awaiting this compiler of yours... :D

A couple of things. Firstly, I lied about there not being any trig ::) There doesn't need to be, but there actually is in that version. I use trig for checking if the projection vector is > 90* from the vector to the target, when I could just use the dot product. I wrote that series of functions, oh, nearly a year ago now, and looking at them I can see a whole bunch of ways of improving them. I will do so in the near future. They can also be made way more accessible / understandable to the layscripter ;D. One of the problems with my code has always been that it's not too easy to follow. Well, I'm mending my ways.

The advantage of doing a pure projection is that it works in 3 dimensions, in any direction, be it up, down, or side to side, there's no need to worry about angles or anything. Just the projection distance and the distance to an interfering object.

Secondly, about the bottleneck. I can't say for sure where it's coming from, but if you're constantly creating or positioning objects at regular intervals in your function, then this will constribute far more to the load than your code's structure itself. Structure-wise, you can have a whole heap of stuff, much more than you have now, before even the slightest lag shows up. I refer to mathematical calculations etc. I think the criteria for loops is way into the tens of thousands of iterations before you experience the slightest lag. Of course, with functions in ofp it's a little less :P. It more depends on what you're doing per loop.

EDIT: i see the max attachment size has gone up. Hurrah!
« Last Edit: 02 Jun 2005, 12:38:58 by Fragorl »