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]




