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!

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!

[Please log in to post a comment]