Skip to content

Instantly share code, notes, and snippets.

@doyousketch2
Created December 2, 2018 02:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save doyousketch2/d669a20238b7ebe93da9424c3bab4efe to your computer and use it in GitHub Desktop.
Save doyousketch2/d669a20238b7ebe93da9424c3bab4efe to your computer and use it in GitHub Desktop.
body.lua
-- title: ModelRenderer
-- author: FlamingPandas
-- desc: Shows 3D models
-- script: lua
point={x=0,y=0,z=300}
fov=100 -- Field of View
rspeed=.1 -- Rotation speed, you can change it
tspeed=10 -- Translation speed, you can change it
mesh={} -- Table that contains all the 3D points
polygon={} -- Table that contains all conections of 3D points to create triangle polygons, with their texture specified too
zorder={} -- Tabe used to know the rendering order of the triangles
function addMesh(mx,my,mz)
local m={x=mx,y=my,z=mz,u=0,v=0}
table.insert(mesh,m)
end
function addPolygon( pp1,pp2,pp3,
pu1,pv1,pu2,
pv2,pu3,pv3 )
local p={ p1=pp1,p2=pp2,p3=pp3,
u1=pu1,v1=pv1,u2=pu2,
v2=pv2,u3=pu3,v3=pv3, zOrd=0 }
table.insert(polygon,p)
end
function addZOrder(polygon,zor)
local z={poly=polygon,zo=zor}
table.insert(zorder,z)
end
function init()
-- "Loading" points and polygon data
local m=addMesh
m(5,20,5) -- 1
m(-5,20,5) -- 2
m(-5,20,-5) -- 3
m(5,20,-5) -- 4
m(5,0,5) -- 5
m(-5,0,5) -- 6
m(-5,0,-5) --7
m(5,0,-5) -- 8
local p=addPolygon
p(1,2,3, 48,8,64,8,64,14)
p(1,3,4, 48,8,64,8,64,14)
p(1,5,2, 0,7,16,7,16,16)
p(5,6,2, 0,7,16,7,16,16)
p(6,7,2, 0,7,16,7,16,16)
p(2,7,3, 0,7,16,7,16,16)
p(4,3,7, 48,8,64,8,64,14)
p(4,7,8, 48,8,64,8,64,14)
p(1,4,5, 0,7,16,7,16,16)
p(5,4,8, 0,7,16,7,16,16)
p(5,7,6, 0,7,16,7,16,16)
p(5,8,7, 0,7,16,7,16,16)
for i,p in pairs(polygon) do
addZOrder(i,0)
end
end
init()
mode=1
function TIC()
if btn(6) then
if btn(0) then translate(0,-tspeed,0) end
if btn(1) then translate(0,tspeed,0) end
if btn(2) then translate(-tspeed,0,0) end
if btn(3) then translate(tspeed,0,0) end
else
if btn(0) then rotatateX(-rspeed) end
if btn(1) then rotatateX(rspeed) end
if btn(2) then rotatateY(-rspeed) end
if btn(3) then rotatateY(rspeed) end
end
if btn(4) then if fov<800 then fov=fov+10 end end
if btn(5) then if fov>10 then fov=fov-10 end end
if btnp(7) then if mode<3 then mode=mode+1 else mode=1 end end
cls(13)
-- Shows info from the zorder table
-- for i,z in pairs(zorder) do
-- print(z.poly.." - "..z.zo,10,10*i)
-- end
calculateMeshUV()
calculateZOrder()
table.sort(zorder,function(a,b) return a.zo > b.zo end)
if mode==1 then showMesh() end
if mode==2 then showWireFrame() end
if mode==3 then showMesh() showWireFrame() end
end
--Given this 3D points calculate how they would look in a 2D screen
function calculateMeshUV()
for i,m in pairs(mesh) do
m.u=((m.x+point.x)*(fov/(m.z+point.z)))+120
m.v=((m.y+point.y)*(fov/(m.z+point.z)))+70
end
end
-- I made this up but ot works... it gives the avarage of the depth of the three points of each triangle, it works good enough to know witch triangles to draw first (the further ones)
function calculateZOrder()
m=mesh
for i,p in pairs(polygon) do
p.zord=(m[p.p1].z+m[p.p2].z+m[p.p3].z)/3
updateZOrder(i,p.zord)
end
end
-- Once calcuated the zorder you need to update the zorder table with those values
-- Why do we need this values in another table? well... lua can sort this table and now we have the order in witch to draw the triangles
function updateZOrder(polygon,zor)
for i,z in pairs(zorder) do
if z.poly==polygon then
z.zo=zor
end
end
end
-- Using the textri function you can show triangles with textures
-- This function draws all triangles that are facimg the camera with the textures defined on the init function
-- The function draws them in the zorder from further to closest so when a triangle is closer it shows "Above" othee triangles
function showMesh()
m=mesh
for i,z in pairs(zorder) do
p=polygon[z.poly]
-- If the triangle points are clockwise they are facing the camera
if isClockWise(p) then
--Draw the textured triangle textri()
tri( m[p.p1].u ,m[p.p1].v,
m[p.p2].u, m[p.p2].v,
m[p.p3].u, m[p.p3].v, 0 )
-- p.u1,p.v1,p.u2,p.v2,p.u3,p.v3)
end
end
end
-- Given a triangle return true if it's points are clockwise false if they aren't
function isClockWise(poly)
p=poly
m=mesh
return (m[p.p2].v-m[p.p1].v)*
(m[p.p3].u-m[p.p2].u)-
(m[p.p3].v-m[p.p2].v)*
(m[p.p2].u-m[p.p1].u) > 0
end
--Function that draws all lines in the three points of a triangle (it just shpws the WireFrame and also the individual points)
function showWireFrame()
m=mesh
for i,p in pairs(polygon) do
line(m[p.p1].u,m[p.p1].v,m[p.p2].u,m[p.p2].v,15)
line(m[p.p2].u,m[p.p2].v,m[p.p3].u,m[p.p3].v,15)
line(m[p.p3].u,m[p.p3].v,m[p.p1].u,m[p.p1].v,15)
end
for i,m in pairs(mesh) do
circ(m.u,m.v,1,0)
print(i,m.u,m.v+5,3)
end
end
-- Rotates all pf the points in the mesh by an angle in the x axes
function rotatateX(angle)
cos=math.cos(angle)
sin=math.sin(angle)
for i,p in pairs(mesh) do
y=p.y*cos-p.z*sin
z=p.z*cos+p.y*sin
p.y=y
p.z=z
end
end
function rotatateY(angle)
cos=math.cos(angle)
sin=math.sin(angle)
for i,p in pairs(mesh) do
x=p.x*cos-p.z*sin
z=p.z*cos+p.x*sin
p.x=x
p.z=z
end
end
function rotatateZ(angle)
cos=math.cos(angle)
sin=math.sin(angle)
for i,p in pairs(mesh) do
x=p.x*cos-p.y*sin
y=p.y*cos+p.x*sin
p.x=x
p.y=y
end
end
-- Translate all of the points an x,y and z distance
function translate(dx,dy,dz)
point.x=point.x+dx
point.y=point.y+dy
point.z=point.z+dz
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment