PicoPicoGameEngine

Quick Links

Source Code

g=ppgraph

sqrt=math.sqrt
tan=math.tan
sin=math.sin
cos=math.cos
rand=math.random

function v3print(s)
 print(
   s.x..","..s.y..","..s.z)
end

function v3(x,y,z)
local q={}
q.x=x
q.y=y
q.z=z
q.print=v3print
return q
end

function nml(p)
local q={}
local l
l=p.x*p.x+p.y*p.y+p.z*p.z
l=sqrt(l)
q.x=p.x/l
q.y=p.y/l
q.z=p.z/l
q.print=v3print
return q
end

function abs(a)
 if a<0 then
   a=-a
 end
 return a
end

function add(a,b,r)
 local v
 v=v3(0,0,0)
 v.x=a.x+b.x*r
 v.y=a.y+b.y*r
 v.z=a.z+b.z*r
 return v
end

function sub(a,b)
return add(a,b,-1)
end

function cross(a,b)
local q={}
q.x=a.x*b.x
q.y=a.y*b.y
q.z=a.z*b.z
q.print=v3print
return q
end

function dot(a,b)
local q={}
q.x=a.x*b.x
q.y=a.y*b.y
q.z=a.z*b.z
local r
r=q.x+q.y+q.z
return r
end

function plane(p,n)
local t={}
t.p=p
t.n=n
t.cross=function(s,a,b)
local p,n
p=s.p
n=s.n
local ad=dot(n,sub(a,p))
local bd=dot(n,sub(b,p))
if abs(ad)<0.00001
then ad=0 end
if abs(bd)<0.00001
then bd=0 end
local r={}
r.ad=ad
r.bd=bd
if ad==0 and bd==0 then
 return r
end
if (ad>=0 and bd<=0)
or (ad<=0 and bd>=0) then
ad=abs(ad)
bd=abs(bd)
local d=ad/(ad+bd)
b=add(b,a,-1)
b.x=b.x*d
b.y=b.y*d
b.z=b.z*d
r.p=add(a,b,1)
end
return r
end
return t
end

function
pmap(fov_h,fov_v,near,far)
local t={}
t.w=1/tan(fov_h*0.5)
t.h=1/tan(fov_v*0.5)
t.q=far/(far-near)
t.u=-t.q*near
t.mul=function(s,p)
local t={}
t.x=s.w*p.x
t.y=s.h*p.y
t.z=s.q*p.z+s.u
t.print=v3print
return t
end
return t
end

function rad(r)
r=math.pi*r/180
return r
end

function trans(v,p)
 local a={}
 a.x=v.x+p.x
 a.y=v.y+p.y
 a.z=v.z+p.z
 return a
end

function rotx(v,r)
 local a={}
 a.x= v.x
 a.y= v.y*cos(r)
     +v.z*sin(r)
 a.z=-v.y*sin(r)
     +v.z*cos(r)
 return a
end

function roty(v,r)
 local a={}
 a.x= v.x*cos(r)
     -v.z*sin(r)
 a.y= v.y
 a.z= v.x*sin(r)
     +v.z*cos(r)
 return a
end

function rotz(v,r)
 local a={}
 a.x= v.x*cos(r)
     +v.y*sin(r)
 a.y=-v.x*sin(r)
     +v.y*cos(r)
 a.z= v.z
 return a
end

proj=pmap(
  rad(120),rad(120),
  100,1000)

cube={
 v={
  v3(100,100,100),
  v3(-100,100,100),
  v3(100,-100,100),
  v3(-100,-100,100),
  v3(100,100,-100),
  v3(-100,100,-100),
  v3(100,-100,-100),
  v3(-100,-100,-100)
 },
 p={
 {1,2},
 {2,4},
 {4,3},
 {3,1},
 {5,6},
 {6,8},
 {8,7},
 {7,5},
 {1,5},
 {2,6},
 {3,7},
 {4,8}}
}

star={
 v={
  v3(0,0,0)
 }
}

grid={
 v={
  v3(-200,0, 200),
  v3( 200,0, 200),
  v3( 200,0,-200),
  v3(-200,0,-200),
 },
 p={
  {1,2},
  {2,3},
  {3,4},
  {4,1}
 }
}

c=ppoffscreen.new()
c:create(1,1)

s={}
s.x=500
s.y=500

function scr(v)
local t={}
t.x=(v.x/v.z)*s.x+160
t.y=(v.y/v.z)*s.y+240
return t
end

function drawpos(v)
 g:fill(v.p.x,
        v.p.y,2,2)
end

function drawshape(p,v)
for i=1,#p do
local q=p[i]
local a,b,c
a=v[q[1]].w
b=v[q[2]].w
c=pln:cross(a,b)
if c.ad>0 and c.bd>0 then
else
if c.p~=nil then
 if c.ad>=0 then
   a=c.p
 else
   b=c.p
 end
end
g:line(scr(a),scr(b))
end
end
end

function obj(shape,x,y,z)
local t={}
t.mv=v3(x,y,z)
t.r=v3(0,0,0)
t.shape=shape
t.idle=function(s)
local r=s.r
r.x=r.x+0.02/2
r.y=r.y+0.03/2
r.z=r.z+0.01/2
s.r=r
end
t.draw=function(s)
local v=s.shape.v
local q=s.shape.p
local rx=s.r.x
local ry=s.r.y
local rz=s.r.z
local mv=s.mv
for i=1,#v do
local p
p=rotx(v[i],rx)
p=roty(p,ry)
p=rotz(p,rz)
p=trans(p,mv)
v[i].w=p
p=proj:mul(p)
v[i].p=scr(p)
if not q then
drawpos(v[i])
end
end
if q then
drawshape(q,v)
end
end
return t
end

prim={}
for i=1,1 do
local t
local x,y,z
x=0
y=0
z=500
t=obj(cube,x,y,z)
prim[#prim+1]=t
end

pln=plane(
  v3(0,0,0),
  v3(0,1,0))
pln.draw=function(s)
local t
t=obj(
 grid,s.p.x,s.p.y,
 500+s.p.z)
t:draw()
end

function start()
 c:drag(pptouch())
 pln.p.y=c.y
 for i=1,#prim do
 local c
 c=prim[i]
 c:idle()
 c:draw()
 end
 pln:draw()
end