0]'],±>Sļ}W’Ķu§šp8·d%qy)6o;]ÉA¦ösļ÷ōōō”°ĀVl†31 or q.w<-1 then q:normalize()end;local s=sqrt(1-q.w*q.w);s=s.99999 then q.x,q.y,q.z,q.w=0,0,0,1;return q;elseif dot<-.99999 then vtmp1.x,vtmp1.y,vtmp1.z=1,0,0;vtmp1:cross(u);if #vtmp115 then --new_t[4] is the color of the tri. --If it is above 15, the triangle has UV coordinates --This assigns the UVs for the --renderer. for i=4,9 do new_t[i]=peek(addr+i) end addr=addr+10-4 end new_model.tris[j]=new_t addr=addr+4 end new_model.byte_size=addr-start_addr mdls[i]=new_model end end function firstToUpper(str)return (str:gsub("^%l",string.upper))end function sepThou(value) local formatted=value while true do formatted,k=string.gsub(formatted,"^(-?%d+)(%d%d%d)",'%1 %2') if (k==0) then break end end return formatted end function distanceXY(p1,p2)local x,y=p1.x-p2.x,p1.y-p2.y;return sqrt(x*x+y*y)end function lerp(a,b,t)return a+(b-a)*t;end -- Game functions function init() loadModels() music(0) end function TIC() camera.rotation.y=camera.rotation.y+0.02 camera.rotation.x=0.6 camera.zoom=6 drawModel() t=t+1 end function drawModel() cls(8) local q=maf.quat local m=mdls[1] m.pos.z=camera.zoom m.pos.y=-0.3 m.rot = q():angleAxis(camera.rotation.x,1,0,0)*q():angleAxis(camera.rotation.y,0,1,0) renderModel(m) drawRenderBuffer(0,0) end function bgCol(r,g,b,t) local addr=0x03FC0 poke(addr,floor(lerp(peek(addr),r,t))) poke(addr+1,floor(lerp(peek(addr+1),g,t))) poke(addr+2,floor(lerp(peek(addr+2),b,t))) end --Camera function rotateCam(angle,axis) local q=maf.quat:angleAxis(angle,axis) camera.q=(q*camera.q):normalize() end --3D transforms function avgTriZ(Tri, scale) local s=scale or 1 return (Tri[1].z*s + Tri[2].z*s + Tri[3].z*s)/3 end function getFurthPoint(m) if m.fp==nil then m.fp=0 for k,v in pairs(m.verts) do m.fp=max(m.fp,#v*m.scale) end end return m.fp end function rotX90(verts) for i,v in pairs(verts) do v.y,v.z=-v.z,v.y end end function rotVerts(verts,rot) local nvs={} for i,v in ipairs(verts) do local nv=maf.vec3(v.x,v.y,v.z) nvs[i]=rot*nv end return nvs end --3D rendering function renderModel(m) if m.anim_size~=nil then m.anim_pos=(m.anim_pos+1/m.anim_speed)%m.anim_size end if m.is_part then m.rot=camera.q:inverse() m.hp=m.hp-1 if m.hp<=0 then for i,_m in pairs(model_list) do if _m==m then table.remove(model_list,i) end end end end if (camera.q*m.pos).z<=0 then return end for i,Tri in pairs(m.tris) do drawTri3d(Tri,m) end end function toScreenSpace(point,model) local cv=camera.q*model.rot*point local pos=camera.q*model.pos local z=pos.z+cv.z*model.scale if z<=.5 then z=.5 end local x,y= fov*(pos.x+cv.x*model.scale)/z, fov*(pos.y+cv.y*model.scale)/z return {x=x+sw2,y=y+sh2,z=z} end function drawTri3d(Tri,model) local pos,scale,v=camera.q*model.pos,model.scale,{a=Tri.a,z=0} for i=1,3 do v[i]=toScreenSpace(model.verts[Tri[i]],model) end if (isClockwise(v)and (camera.flicker==false or t%2==0))or(not triOnScreen(v)) then return end if #Tri==4 and Tri[4]>15 then Tri[4],Tri[5],Tri[6],Tri[7],Tri[8],Tri[9]=getTex(Tri[4]) end if #Tri==9 then --textured local uv_off=model.uv_off or {0,0} local uv_x=floor(model.anim_pos or 0)*8 + uv_off[1] local uv_y=uv_off[2] table.insert(render_buffer, #render_buffer+1, {v[1].x,v[1].y,v[2].x,v[2].y,v[3].x,v[3].y, Tri[4]+uv_x,Tri[5]+uv_y, Tri[6]+uv_x,Tri[7]+uv_y, Tri[8]+uv_x,Tri[9]+uv_y, z=v[1].z+v[2].z+v[3].z } ) else -- 1-color table.insert(render_buffer, #render_buffer+1, {v[1].x,v[1].y,v[2].x,v[2].y,v[3].x,v[3].y,Tri[4], z=v[1].z+v[2].z+v[3].z } ) end end function drawRenderBuffer(x,y) if #render_buffer<1 then return end table.sort(render_buffer,function(a,b)return a.z>b.z end) if x==nil then x=0;y=0 end for i=1,#render_buffer do local Tri=render_buffer[i] if #Tri==7 then --untex tri(Tri[1]+x,Tri[2]+y,Tri[3]+x,Tri[4]+y,Tri[5]+x,Tri[6]+y,Tri[7]) elseif #Tri==12 then --tex ttri(Tri[1]+x,Tri[2]+y,Tri[3]+x,Tri[4]+y,Tri[5]+x,Tri[6]+y,Tri[7],Tri[8],Tri[9],Tri[10],Tri[11],Tri[12],false,0) end end render_buffer={} end function isClockwise(Tri) if Tri.a or (Tri[2].y-Tri[1].y)* (Tri[3].x-Tri[2].x)- (Tri[3].y-Tri[2].y)* (Tri[2].x-Tri[1].x)>0 then return false else return true end end --Collisions function pointInTriangle(x1,y1,x2,y2,x3,y3,x,y) local denominator=((y2-y3)*(x1-x3)+(x3-x2)*(y1-y3)) local a=((y2-y3)*(x-x3)+(x3-x2)*(y-y3)) / denominator local b=((y3-y1)*(x-x3)+(x1-x3)*(y-y3)) / denominator local c=1-a-b return 0 <= a and a <= 1 and 0 <= b and b <= 1 and 0 <= c and c <= 1 end function triOnScreen(Tri) local avg={x=0,y=0} for i=1,3 do if Tri[i].x0 and Tri[i].y0 then return true end avg.x=avg.x+Tri[i].x/3 avg.y=avg.y+Tri[i].y/3 end if avg.x0 and avg.y0 then return true end local s={{x=0,y=0},{x=sw,y=0},{x=sw,y=sh},{x=0,y=sh},{x=sw2,y=sh2}} for i=1,5 do if pointInTriangle( Tri[1].x,Tri[1].y, Tri[2].x,Tri[2].y, Tri[3].x,Tri[3].y, s[i].x,s[i].y)then return true end end return false end init()