Log In  

Hi,
I would like to add a basic 3d outside view to my flight sim project Tiny Sim. For this I started with the code below, which is just showing a simplified runway (essentially, a rectangle with some points). I am trying to get the projection function right and while it works for z<0 it fails miserably for z>=0: the runway is somehow mirrored in the upper half of the screen.

rwy = {{{-1,0,0}, --points
        {-1,0,30},
        {1,0,30},
        {1,0,0}},
       {{1,2}, --lines
        {2,3},
        {3,4},
        {4,1}},
         4}

cam = {0,1,-4}
mult = 64
sp = 0.01

function _update()
  if btn(0) then cam[1] -= 0.1 end
  if btn(1) then cam[1] += 0.1 end
  if btn(2) then cam[2] += 0.1 end
  if btn(3) then cam[2] -= 0.1 end
  if(cam[2]<0) cam[2]=0
  if btn(4) then cam[3] -= 0.1 end
  if btn(5) then cam[3] += 0.1 end
end

function _draw()
  cls()
  print("x="..cam[1],0,6*1)
  print("y="..cam[2],0,6*2) 
  print("z="..cam[3],0,6*3) 

  draw_shape(rwy)
  for i=1, 14 do
    draw_point({0,0,i*2},7)
  end
  draw_point({-0.5,0,2},7)
  draw_point({0.5,0,2},7)
end

function draw_shape(s,c)
  for l in all(s[2]) do
    draw_line(s[1][l[1]], s[1][l[2]], c)
  end
end

function draw_line(p1,p2,c)
  x0, y0 = project(p1)
  x1, y1 = project(p2)
  line(x0, y0, x1, y1, c or 6)
end

function draw_point(p,c)
  x, y = project(p)
  pset(x, y, c or 11)
end

function project(p)
  x = (p[1]-cam[1])*mult/(p[3]-cam[3]) + 127/2
  y = -(p[2]-cam[2])*mult/(p[3]-cam[3]) + 127/2  
  return x, y
end

--functions for roll, pitch and yaw

Runway being displayed correctly (z<0):

Runway with wrong projection (z>=0):

I split up the projection function for z<0 and z>=0 but did not find the right formula for z>=0 yet:

function project(p)
  if cam[3]<=0 then
    x = (p[1]-cam[1])*mult/(p[3]-cam[3]) + 127/2
    y = -(p[2]-cam[2])*mult/(p[3]-cam[3]) + 127/2
  else
    x = (p[1]+cam[1])*mult/(p[3]+cam[3]) + 127/2
    y = -(p[2]+cam[2])*mult/(p[3]+cam[3]) + 127/2
  end  
  return x, y
end

Any help is much appreciated!

P#59388 2018-11-27 14:46

Welcome to the wonderful world of 3d clipping!
(and I really liked your flight sim - something I always wanted to do!)

In short, your maths are correct (and certainly don’t need a special handling of negative z).
What you must do is clip the lines (usually in projected space) against the 6 planes of the view frustrum.
For wireframe 3d, that's easy: http://geomalgorithms.com/a06-_intersect-2.html
For filled polygons, a lot less: https://www.gamasutra.com/view/news/168577/Indepth_Software_rasterizer_and_triangle_clipping.php

Good luck!

P#59400 2018-11-27 19:41 ( Edited 2018-11-28 21:57)

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-04-20 11:41:24 | 0.008s | Q:14