Author Topic: RayCast and it's precision  (Read 1033 times)

0 Members and 1 Guest are viewing this topic.

Offline dnmr

  • Camper
  • ***
  • Posts: 315
  • emotionally handicapped
RayCast and it's precision
« on: November 19, 2009, 04:40:31 am »
How are you gentlemen!

Well i just registered a new account since apparently it's not possible to change account names here, and thought about posting something different.

I'll try to post stuff like this from time to time - mostly just results of messing with the scriptcore, but some might find them useful.

I was going through some old code that uses RayCast and thought about recoding a pretty complex piece of a script. So i made this little test script to check some details.

Code: (pascal) [Select]
var
  d: single;
  c: array[1..4] of single;


function xsplit(const source: string; const delimiter: string):TStringArray; // by KeYDoN, fixed according to forums.soldat.pl
var i,x,d: integer;
    s: string;
begin
  d := length(delimiter);
  x := 0;
  i := 1;
  SetArrayLength(Result,0);
  SetArrayLength(Result,1);
 
  while(i <= length(source)) do begin
    s := Copy(source,i,d);
    if(s = delimiter) then begin
      inc(i,d);
      inc(x,1);
      SetArrayLength(result,x+1);
    end else begin
      result[x] := result[x]+Copy(s,1,1);
      inc(i,1);
    end;
  end;
end;

procedure rayit(x1,y1,x2,y2: single);
var i: integer;
    win: boolean;
begin
  writeln('');

  writeln(inttostr(round(x1))+':'+inttostr(round(y1)));
  writeln(inttostr(round(x2))+':'+inttostr(round(y2)));
 
//  CreateBullet(x1,y1,0,-1,0,5,32);
//  CreateBullet(x2,y2,0,1,0,5,32);
  WorldImage(0,1,28,x1,y1,1.0);
  WorldText(0,2,'1: '+inttostr(round(x1))+','+inttostr(round(y1)),x1+20,y1,$FFFFFF,1,1);
 
  WorldImage(0,3,28,x2,y2,1.0);
  WorldText(0,4,'2: '+inttostr(round(x2))+','+inttostr(round(y2)),x2+20,y2,$FFFFFF,1,1);
 
  win := RayCast(x1,y1,x2,y2,d,9001);
 
  if win then
    writeln(inttostr(round(d)))
  else
    writeln(inttostr(round(-d)));
 
  WorldText(0,5,inttostr(round(d))+#13#10+inttostr(round(distance(x1,y1,x2,y2))),x1+(x2-x1)/2,y1+(y2-y1)/2,iif(win,$00FF00,$FF0000),5,1);
 
end;

 
function OnCommand(ID: Byte; Text: string): boolean;
var a: tstringarray;
begin
  a := xsplit(text,' ');
 
  case a[0] of
    '/t': WorldText(1,6,'bahoonas',0,0,$FFFFFF,strtoint(a[1]),strtofloat(a[2]));
   
    '/ray','/r': rayit(strtofloat(a[1]),strtofloat(a[2]),strtofloat(a[3]),strtofloat(a[4]));
    '/use','/revive': rayit(c[1],c[2],c[3],c[4]);
   
    '/r1': begin
      c[1] := strtofloat(a[1]);
      c[2] := strtofloat(a[2]);
      rayit(c[1],c[2],c[3],c[4]);
    end;
 
    '/r2': begin
      c[3] := strtofloat(a[1]);
      c[4] := strtofloat(a[2]);
      rayit(c[1],c[2],c[3],c[4]);
    end;
 
    '/ray1','/heal','/cc1','/cmmd1','/def','/cc2','/cmmd2': begin
      c[1] := getplayerstat(id,'x');
      c[2] := getplayerstat(id,'y');
      rayit(c[1],c[2],c[3],c[4]);
    end;
 
    '/ray2','/ofs','/cc3','/cmmd3','/smn','/summon','/cc4','/cmmd4': begin
      c[3] := getplayerstat(id,'x');
      c[4] := getplayerstat(id,'y');
      rayit(c[1],c[2],c[3],c[4]);
    end;
 
  end;
 
end;

(made for scriptcore v3, ie dedi 2.7.0, soldat 1.5.1)
Yes i know i shouldnt use xsplit etc etc, but this is just a test script, so i didnt put much effort in performance and such <.<



These commands set the first point at your current location: '/ray1','/heal','/cc1','/cmmd1','/def','/cc2','/cmmd2'
These set the second point: '/ray2','/ofs','/cc3','/cmmd3','/smn','/summon','/cc4','/cmmd4'

You can also set the coordinates of the first and second point by hand ("/r1 X1 Y1" and "/r2 X2 Y2" respectively), or set all four coordinates at the same time ("/r X1 Y1 X2 Y2")

The awful lot of command aliases is because i have hexer mod commands taunted, and some people have the other common sets, so i just threw them in so it's easier to set the points on the fly.

So what this does is it marks both points with menu cursor images (easily visualised since the tip of the arrow is at 0;0 coordinates of the sprite), writes their coordinates next to them and raycasts between the two points. The two numbers between the points mark the actual distance between the points and the value of the Distance variable used by RayCast. The two numbers are green if the result was true, and red if it's false (ie if there are polygons between the two points)

Now apart from the fact that this is fun to play with, i found that the Distance var (d in this script) does return the distance, but can vary by 20px (both ways). Which i guess is because of it's mechanics, but w/e.
So if you're raycasting and need the distance between the points anyway, you could leave distance() out and just use the var used by RayCast =P If you don't care about the +/- 20px, that is.

I also figured the scale parameter of worldtext is broked, reported it already

Offline DorkeyDear

  • Veteran
  • *****
  • Posts: 1507
  • I also go by Curt or menturi
Re: RayCast and it's precision
« Reply #1 on: November 19, 2009, 11:11:06 am »
Distance thing is kind of funny xD - ty for posting, i gots some inspiration to do something now :)

Offline dnmr

  • Camper
  • ***
  • Posts: 315
  • emotionally handicapped
Re: RayCast and it's precision
« Reply #2 on: November 20, 2009, 07:52:37 am »
Oh, i forgot to mention that i mostly did this because i thought (and hoped) that the Distance variable would contain the distance to the closest polygon on the way. That would make some things way easier. But my dreams got crashed :( WHY MUST I CRYYYYYYYYYYY

Offline DorkeyDear

  • Veteran
  • *****
  • Posts: 1507
  • I also go by Curt or menturi
Re: RayCast and it's precision
« Reply #3 on: November 20, 2009, 01:42:59 pm »
It may be slow, but you could approximate it by a loopy loop of RayCast. :P

Offline dnmr

  • Camper
  • ***
  • Posts: 315
  • emotionally handicapped
Re: RayCast and it's precision
« Reply #4 on: November 20, 2009, 02:20:09 pm »
It may be slow, but you could approximate it by a loopy loop of RayCast. :P
yeah seems like the only way (and that's how Avarax coded the part i wanted to improve)