Last active
July 5, 2020 03:53
-
-
Save lucatronica/55dc19dc4c2a7b9b456dd5d5cf241f6d to your computer and use it in GitHub Desktop.
This file contains hidden or 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
-- gumtree.lua | |
-- coordinates: x,y = ground; z = vertical | |
-- camera | |
local gt_cam={ | |
x=0, | |
y=0, | |
z=0, | |
-- spin angle | |
s=0, | |
-- tilt angle | |
t=1/8, | |
-- scale (1 means 1:1) | |
k=8, | |
-- perspective (number > 0, or nil for orthographic) | |
p=80, | |
} | |
-- buckets | |
local gt_mind=nil | |
local gt_maxd=nil | |
local gt_buckets={} | |
-- voxels | |
-- create a voxel object | |
function gt_voxel(x,y,z,w,c) | |
return {x=x,y=y,z=z,w=w,c=c} | |
end | |
-- create a voxel object and draw it | |
function gt_draw_new_voxel(x,y,z,w,c) | |
gt_draw_voxel({x=x,y=y,z=z,w=w,c=c}) | |
end | |
-- draw a voxel object | |
function gt_draw_voxel(v) | |
-- transform | |
local cs=gt_cam.cs | |
local ss=gt_cam.ss | |
local ct=gt_cam.ct | |
local st=gt_cam.st | |
local k=gt_cam.k | |
local x=v.x-gt_cam.x | |
local y=v.y-gt_cam.y | |
local z=v.z-gt_cam.z | |
x,y=x*cs-y*ss,x*ss+y*cs | |
-- depth | |
local dz=(z*ct-y*st)*k | |
-- perspective | |
local p=gt_cam.p | |
if p then | |
if dz>=p then | |
v.r=false | |
return | |
else | |
k/=(1-dz/p) | |
end | |
end | |
v.r=true | |
-- save render position to object | |
v.rx=x*k+64 | |
v.ry=(y*ct+z*st)*k+64 | |
v.rw=v.w*k | |
-- save to bucket | |
-- depth resolution is int, can multiply | |
-- before flr() to increase resolution | |
-- (more buckets, but may perform worse) | |
local d=flr(dz) | |
if gt_mind==nil then | |
gt_mind=d | |
gt_maxd=d | |
else | |
gt_mind=min(gt_mind,d) | |
gt_maxd=max(gt_maxd,d) | |
end | |
local b=gt_buckets[d] | |
if not b then | |
b={} | |
gt_buckets[d]=b | |
end | |
add(b,v) | |
end | |
-- main functions | |
-- call at the start of _update, after camera parameters have been set | |
function gt_start() | |
gt_buckets={} | |
gt_mind=nil | |
gt_maxd=nil | |
gt_cam.cs=cos(gt_cam.s) | |
gt_cam.ss=sin(gt_cam.s) | |
gt_cam.ct=cos(gt_cam.t) | |
gt_cam.st=sin(gt_cam.t) | |
end | |
-- call at the end of _draw, after all draw calls have been made | |
function gt_end() | |
if gt_mind then | |
for d=gt_mind,gt_maxd do | |
local b=gt_buckets[d] | |
if b then | |
for i=1,#b do | |
local o=b[i] | |
local x=o.rx | |
local y=o.ry | |
local w=o.rw | |
rectfill(x-w,y-w,x+w,y+w,o.c) | |
-- debug stuff | |
-- draw voxel outline | |
--rect(x-w,y-w,x+w,y+w,0) | |
-- put a flip in it: | |
--if n%20==0 then flip() end | |
end | |
end | |
end | |
end | |
end | |
-- gumtree_test.lua | |
-- create input handler to move camera | |
-- call in update (before gt_start) | |
function gt_test_cam() | |
local ix,iy=0,0 | |
if(btn(0))ix-=1 | |
if(btn(1))ix+=1 | |
if(btn(2))iy-=1 | |
if(btn(3))iy+=1 | |
local s=-gt_cam.s | |
local cs=cos(s) | |
local ss=sin(s) | |
local rix,riy=ix*cs-iy*ss,ix*ss+iy*cs | |
if btn(4) and btn(5) then | |
gt_cam.p+=ix | |
elseif btn(4) then | |
gt_cam.s-=ix/130 | |
gt_cam.t+=iy/130 | |
--cam.t=mid(0,cam.q,1/4) | |
elseif btn(5) then | |
gt_cam.k+=ix/4 | |
gt_cam.z-=iy/8 | |
else | |
gt_cam.x+=rix/8 | |
gt_cam.y+=riy/8 | |
end | |
end | |
-- kirby.p8 | |
function lerp(t,a,b) | |
return a+(b-a)*t | |
end | |
function rot(x,y,a) | |
return x*cos(a)-y*sin(a),x*sin(a)+y*cos(a) | |
end | |
function _draw() | |
cls(7) | |
--gt_test_cam() | |
gt_cam.t=0.23 | |
gt_cam.s=0.75+sin(t()/8)*0.09 | |
gt_cam.k=6 | |
gt_cam.p=100 | |
gt_start() | |
kirby() | |
gt_end() | |
--?stat(1),1,1,8 | |
end | |
function rnd2(a,b) | |
return a+rnd(b-a) | |
end | |
function sphc(r,a,b) | |
return | |
r*cos(a)*cos(b), | |
r*sin(a)*cos(b), | |
-r*sin(b) | |
end | |
function sph(r,a,b,w,c) | |
gt_draw_new_voxel( | |
r*cos(a)*cos(b), | |
r*sin(a)*cos(b), | |
-r*sin(b), | |
w, | |
c | |
) | |
end | |
dusts={} | |
frame=0 | |
fillp(0x5a5a) | |
--debug: slow animation rate | |
--function t() return frame/200 end | |
function kirby() | |
--body radius | |
local r=4 | |
--twist amount | |
local ta=sin(t()*3+0.25)*0.012 | |
--vertical bobbing offset | |
local dz=sin(t()*6+0.6)*0.19 | |
--dust | |
if frame%2==0 then | |
local dust=gt_voxel( | |
-2.5, | |
rnd2(-3.2,3.2), | |
-5, | |
0.7, | |
6+7*16 | |
) | |
add(dusts,dust) | |
end | |
for dust in all(dusts) do | |
gt_draw_voxel(dust) | |
dust.w*=0.9 | |
dust.x-=1.4 | |
if dust.w<0.05 then | |
del(dusts,dust) | |
end | |
end | |
--body | |
for v=-0.98,0.98,0.1 do | |
local s=sqrt(1-v*v) | |
for a=0,1,0.1-s*0.05 do | |
a-=ta/3 | |
local x2=v*r | |
local y2=s*cos(a)*r | |
local z2=s*sin(a)*r+dz | |
gt_draw_new_voxel( | |
x2, | |
y2, | |
z2, | |
0.55, | |
14*17 | |
) | |
end | |
end | |
for i=-1,1,2 do | |
local ra=sin(t()*3+i/4)*0.13 | |
local rb=i*ra*0.6 | |
--eyes and blush | |
function face(r,a,b,w,c) | |
local x,y,z=sphc(r,a,b) | |
x,y=rot(x,y,ta) | |
z+=dz | |
gt_draw_new_voxel(x,y,z,w,c) | |
end | |
a=i/28 | |
for j=0,1,0.1 do | |
--local j2=(1+j)/2 | |
--local r1=sqrt(1.2-j*j) | |
--local r2=sqrt(max(0.33-(j-0.27)^2))*1.6 | |
--local lr=sqrt(2-((j-.75)*7)^2) | |
--local kp=sqrt(1.1-(j*2-1)^2)*0.01 | |
--for p=-1,1,.25 do | |
-- if abs(p)<r1 then | |
-- face(r+.6,a+p*0.01,lerp(j2,0.02,0.08),0.04,abs(p)<r2 and 7*17 or 17) | |
-- end | |
--end | |
--eye dark | |
face(r+.6,a,lerp(j,0.02,0.08),0.37-abs(j-0.5)*0.4,17) | |
--eye light | |
face(r+.85,a,lerp(j,0.047,0.073),0.22-abs(j-0.5)*0.3,7*17) | |
--blush | |
face(r+.4,a+i*lerp(j,0.03,0.07),0.01,0.3-abs(j-0.5)*0.3,14+8*16) | |
end | |
--arm | |
local y=i*4.5 | |
for v=-1,1,0.25 do | |
local s=sqrt(1-v*v) | |
for a=0,0.9,0.1 do | |
local x2=1+s*cos(a)*0.6 | |
local y2=y+v*1.2 | |
local z2=s*sin(a) | |
y2,z2=rot(y2,z2,-i*0.08) | |
x2,y2=rot(x2,y2,rb*0.5-i*0.06) | |
gt_draw_new_voxel( | |
x2, | |
y2, | |
z2+dz, | |
0.3, | |
14*17 | |
) | |
end | |
end | |
--feet | |
y=i*1.7 | |
for v=-1,1,0.25 do | |
local s=sqrt(1-v*v) | |
for a=0,0.8,0.2 do | |
local x2=v*1.5 | |
local y2=y+s*cos(a)*1 | |
local z2=-5+s*sin(a)*0.4 | |
x2,z2=rot(x2,z2,ra*1.2) | |
gt_draw_new_voxel( | |
x2, | |
y2, | |
z2+dz, | |
0.4, | |
8*17 | |
) | |
end | |
end | |
end | |
--mouth | |
local x,y,z=sphc(r+0.5,0,0) | |
x,y=rot(x,y,ta) | |
gt_draw_new_voxel(x,y,z+dz,0.08,0) | |
frame+=1 | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment