Created
June 11, 2021 14:44
-
-
Save Powersaurus/e8c2e07b0e9c5f3c0863a38c6f87db55 to your computer and use it in GitHub Desktop.
Slowly working my way towards perspective correct 3D dots - references https://lodev.org/cgtutor/raycasting3.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function init_palette() | |
--pal() | |
pal(2,141,1) | |
pal(7,135,1) | |
pal(8,137,1) | |
pal(10,140,1) | |
pal(11,138,1) | |
pal(12,134,1) | |
pal(14,131,1) | |
pal(15,133,1) | |
poke(0x5f2e,1) | |
end | |
function _init() | |
init_palette() | |
a=0.25 | |
pt={} | |
-- starting dir | |
-- -1 0 1 | |
-- -1 * o * g | |
-- 0 /\ | |
-- 1 * r * b | |
-- add(pt,point(-1,0,1,8))--red | |
-- add(pt,point(1,0,-1,3))--green | |
-- add(pt,point(1,0,1,10))--blue | |
add(pt,point(-1,0,-1,9))--orange | |
--[[for x=-1,1,1/3 do | |
for y=-1,1,1/3 do | |
for z=-1,1,1/3 do | |
add(pt,point(x,y,z)) | |
end | |
end | |
end--]] | |
cam={} | |
cam.x,cam.z, | |
cam.drx,cam.drz, | |
cam.cx,cam.cz= | |
0,0, | |
0,-1, | |
0,1 | |
mode=0 | |
end | |
function point(x,y,z,c) | |
local p={} | |
p.x,p.y,p.z=x,y,z | |
p.col=c or 8+(x*3+y*2)%8 | |
return p | |
end | |
function _update() | |
local da=0 | |
if(btn(0))da+=0.009 | |
if(btn(1))da-=0.009 | |
a+=da | |
local old_camcx,old_plane_x= | |
0,cam.cx | |
cam.drx,cam.drz= | |
cos(a),sin(a) | |
cam.cx,cam.cz= | |
old_plane_x*cos(da) | |
+cam.cz*sin(da), | |
old_plane_x*sin(da) | |
+cam.cz*cos(da) | |
printh(cam.drx..","..cam.drz.." "..cam.cx..","..cam.cz) | |
if btn(2) then | |
cam.z+=cam.drz/8 | |
cam.x+=cam.drx/8 | |
end | |
if btn(3) then | |
cam.z-=cam.drz/8 | |
cam.x-=cam.drx/8 | |
end | |
if btnp(4) then | |
mode=(mode+1)%4 | |
end | |
if(a>1)a-=1 | |
if(a<0)a+=1 | |
end | |
modes={ | |
[0]="2d, no rotation", | |
"2d with rotation", | |
"3d projected", | |
"perspective correct" | |
} | |
function _draw() | |
cls(0) | |
--a=0.3622 | |
if mode==0 then | |
draw_2d_no_rot() | |
elseif mode==1 then | |
draw_2d() | |
else | |
draw_3d() | |
end | |
print("x= cos("..a.. | |
")="..cos(a),0,0,7) | |
print("y= sin("..a..")="..-sin(a),0,6,7) | |
print("mode: "..modes[mode],0,122) | |
end | |
function draw_2d_no_rot() | |
local lxe,lye= | |
64+cos(a)*8, | |
64+sin(a)*8 | |
line(64,64,lxe,lye,13) | |
local nxe,nye= | |
64-sin(a)*8, | |
64+cos(a)*8 | |
line(64,64,nxe,nye,9) | |
pset(64,64,7) | |
for p in all(pt) do | |
pset( | |
64+(p.x+cam.x)*8, | |
64+(p.z+cam.z)*8,p.col) | |
end | |
end | |
function draw_2d() | |
line(64,64,64,56,13) | |
line(64,64,72,64,9) | |
pset(64,64,7) | |
local yaw=a | |
for p in all(pt) do | |
local wx=(p.x-cam.x)*8 | |
local wz=(p.z-cam.z)*8 | |
local tr_x,tr_z= | |
rot(wx,wz,a) | |
pset(64-tr_x,64-tr_z,p.col) | |
end | |
end | |
function draw_3d() | |
project(pt) | |
end | |
function rot(x,y,a) | |
local xd=x | |
x=sin(a)*xd-cos(a)*y | |
y=cos(a)*xd+sin(a)*y | |
return x,y | |
end | |
function project(pt) | |
-->cam space | |
for p in all(pt) do | |
p.cx,p.cz=rot( | |
p.x-cam.x, | |
p.z-cam.z,a) | |
-- p.cy,p.cz=rot(p.y,p.cz,t()/7) | |
p.cy=p.y | |
-- p.cz+=2 +cos(t()/6) | |
end | |
-- sort | |
for pass=1,3 do | |
for i=1,#pt-1 do | |
if pt[i].cz<pt[i+1].cz then | |
pt[i],pt[i+1]= | |
pt[i+1],pt[i] | |
end | |
end | |
for i=#pt-1,1,-1 do | |
if pt[i].cz<pt[i+1].cz then | |
pt[i],pt[i+1]= | |
pt[i+1],pt[i] | |
end | |
end | |
end | |
--]] | |
-->screen space | |
for p in all(pt) do | |
-- screen coordinates | |
-- derived only from | |
-- the cam coordinates | |
-- cz means "further | |
-- from the camera" | |
-- goes 3d -> 2d | |
if mode==2 then | |
sx=64-p.cx*64/p.cz | |
sy=64+p.cy*64/p.cz | |
rad=8/p.cz | |
else | |
local invdet=1/ | |
(cam.cx*cam.drz- | |
cam.drx*cam.cz) | |
local trx=invdet*( | |
cam.drz*p.x-cam.drx*p.y | |
) | |
local try=invdet*( | |
-cam.cz*p.x+cam.cx*p.y | |
) | |
sx=64*(1+trx/try) | |
-- local sx_pcnt= | |
-- (sx-64)/128 | |
rad=abs(8/try) | |
--rad=6 | |
local s_height=abs(128/try) | |
sy=-s_height/2+64 | |
printh(try) | |
end | |
if p.cz>0.1 then | |
circfill(sx,sy,rad,p.col) | |
circfill(sx+rad/3,sy-rad/3, | |
rad/3,7) | |
end | |
end | |
print(stat(1)) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment