Created
June 7, 2016 15:10
-
-
Save dermotbalson/c6002726de6c6d55bc979b1ab924f5f3 to your computer and use it in GitHub Desktop.
3D box 3
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
--# Main | |
--# Main | |
displayMode(FULLSCREEN) | |
function setup() | |
size,radius=200,10 | |
CreateScene() | |
end | |
function CreateScene() --size is size of 3D box | |
local img=readImage("SpaceCute:Background")--:copy(4,4,62,62) | |
box=CreateBlock(size,size,size,color(255),vec3(0,0,0),img) | |
balls={} | |
for i=1,12 do | |
local b=CreateSphere(radius,readImage("Cargo Bot:Starry Background"),color(255)) | |
--create random position but check they dont overlap | |
local p | |
while true do | |
p=(vec3(.2,.2,.2)+0.5*vec3(math.random()-0.5,math.random()-0.5,math.random()-0.5))*size | |
local overlap=false | |
for j=1,i-1 do | |
if p:dist(balls[j].pos)<radius*2 then overlap=true end | |
end | |
if not overlap then break end | |
end | |
local v=vec3(math.random()-0.5,math.random()-0.5,math.random()-0.5)*5 | |
balls[i]={ball=b,pos=p,vel=v} | |
end | |
end | |
function DrawBalls() | |
NewVals={} | |
for i,b in pairs(balls) do | |
AdjustPos(i) | |
end | |
for i,b in pairs(balls) do | |
b.pos=NewVals[i][1] | |
b.vel=NewVals[i][2] | |
pushMatrix() | |
translate(b.pos:unpack()) | |
b.ball:draw() | |
popMatrix() | |
end | |
end | |
function AdjustPos(i) | |
local b=balls[i] | |
local p=b.pos+b.vel | |
local v1=vec3(b.vel.x,b.vel.y,b.vel.z) | |
--check for collisions with each axis wall | |
local f=0 | |
local d=size/2-radius | |
--x | |
local xd=math.abs(p.x) | |
if xd>d then --collided with x wall | |
f=(xd-d)/math.abs(b.vel.x) --backtrack by this fraction of the last movement | |
v1.x=-b.vel.x --reverse x velocity | |
end | |
--y | |
local yd=math.abs(p.y) | |
if yd>d then --collided with y wall | |
f=(yd-d)/math.abs(b.vel.y) --backtrack by this fraction of the last movement | |
v1.y=-b.vel.y --reverse y velocity | |
end | |
--z | |
local zd=math.abs(p.z) | |
if zd>d then --collided with z wall | |
f=(zd-d)/math.abs(b.vel.z) --backtrack by this fraction of the last movement | |
v1.z=-b.vel.z --reverse z velocity | |
end | |
--check for collisions with other balls | |
if f==0 then | |
for j=1,#balls do | |
if j~=i then | |
local b2=balls[j] | |
local d=p:dist(b2.pos)-radius*2 --distance between centres | |
if d<0 then | |
--calculate normal vector from b2 to b | |
local n=(b.pos-b2.pos):normalize() | |
local g=n*(b.vel:dot(n)*2) | |
v1=vec3(b.vel.x-g.x,b.vel.y-g.y,b.vel.z-g.z) | |
--reflect to reverse embedding | |
local d0=b.pos:dist(b2.pos)-radius*2 | |
f=d/(d-d0) --fraction of distance to reverse | |
end | |
end | |
end | |
end | |
NewVals[i]={b.pos+b.vel*(1-f)+v1*f,v1} | |
end | |
function draw() | |
background(220) | |
perspective(90) | |
camera(0,0,size/2-1,0,-size/3,0) | |
box:draw() | |
DrawBalls() | |
end | |
--# Utility | |
function CreateBlock(w,h,d,col,pos,tex) --width,height,depth,colour,position,texture | |
local x,X,y,Y,z,Z=pos.x-w/2,pos.x+w/2,pos.y-h/2,pos.y+h/2,pos.z-d/2,pos.z+d/2 | |
local v={vec3(x,y,Z),vec3(X,y,Z),vec3(X,Y,Z),vec3(x,Y,Z),vec3(x,y,z),vec3(X,y,z),vec3(X,Y,z),vec3(x,Y,z)} | |
local vert={v[1],v[2],v[3],v[1],v[3],v[4],v[2],v[6],v[7],v[2],v[7],v[3],v[6],v[5],v[8],v[6],v[8],v[7], | |
v[5],v[1],v[4],v[5],v[4],v[8],v[4],v[3],v[7],v[4],v[7],v[8],v[5],v[6],v[2],v[5],v[2],v[1]} | |
local texCoords | |
if tex then | |
local t={vec2(0,0),vec2(1,0),vec2(0,1),vec2(1,1)} | |
texCoords={t[1],t[2],t[4],t[1],t[4],t[3],t[1],t[2],t[4],t[1],t[4],t[3],t[1],t[2],t[4],t[1],t[4],t[3], | |
t[1],t[2],t[4],t[1],t[4],t[3],t[1],t[2],t[4],t[1],t[4],t[3],t[1],t[2],t[4],t[1],t[4],t[3]} | |
end | |
local n={vec3(0,0,1),vec3(1,0,0),vec3(0,0,-1),vec3(-1,0,0),vec3(1,0,0),vec3(-1,0,0)} | |
local norm={} | |
for i=1,6 do for j=1,6 do norm[#norm+1]=n[i] end end | |
local ms = mesh() | |
ms.vertices = vert | |
ms.normals=norm | |
if tex then ms.texture,ms.texCoords = tex,texCoords end | |
ms:setColors(col or color(255)) | |
return ms | |
end | |
function CreateSphere(r,tex,col,nx,ny) | |
local vertices,tc = Sphere_OptimMesh(nx or 40,ny or 20) | |
vertices = Sphere_WarpVertices(vertices) | |
for i=1,#vertices do vertices[i]=vertices[i]*r end | |
local ms = mesh() | |
ms.vertices=vertices | |
if tex then ms.texture,ms.texCoords=tex,tc end | |
ms:setColors(col or color(255)) | |
return ms | |
end | |
function Sphere_OptimMesh(nx,ny) | |
local v,t={},{} | |
local k,s,x,y,x1,x2,i1,i2,sx,sy=0,1,0,0,{},{},0,0,nx/ny,1/ny | |
local c = vec3(1,0.5,0) | |
local m1,m2 | |
for y=0,ny-1 do | |
local nx1 = math.floor( nx * math.abs(math.cos(( y*sy-0.5)*2 * math.pi/2)) ) | |
if nx1<6 then nx1=6 end | |
local nx2 = math.floor( nx * math.abs(math.cos(((y+1)*sy-0.5)*2 * math.pi/2)) ) | |
if nx2<6 then nx2=6 end | |
x1,x2 = {},{} | |
for i1 = 1,nx1 do x1[i1] = (i1-1)/(nx1-1)*sx end x1[nx1+1] = x1[nx1] | |
for i2 = 1,nx2 do x2[i2] = (i2-1)/(nx2-1)*sx end x2[nx2+1] = x2[nx2] | |
local i1,i2,n,nMax,continue=1,1,0,0,true | |
nMax = nx*2+1 | |
while continue do | |
m1,m2=(x1[i1]+x1[i1+1])/2,(x2[i2]+x2[i2+1])/2 | |
if m1<=m2 then | |
v[k+1],v[k+2],v[k+3]=vec3(x1[i1],sy*y,1)-c,vec3(x1[i1+1],sy*y,1)-c,vec3(x2[i2],sy*(y+1),1)-c | |
t[k+1],t[k+2],t[k+3]=vec2(-x1[i1]/2,sy*y) ,vec2(-x1[i1+1]/2,sy*y),vec2(-x2[i2]/2,sy*(y+1)) | |
if i1<nx1 then i1 = i1 +1 end | |
else | |
v[k+1],v[k+2],v[k+3]=vec3(x1[i1],sy*y,1)-c,vec3(x2[i2],sy*(y+1),1)-c,vec3(x2[i2+1],sy*(y+1),1)-c | |
t[k+1],t[k+2],t[k+3]=vec2(-x1[i1]/2,sy*y),vec2(-x2[i2]/2,sy*(y+1)),vec2(-x2[i2+1]/2,sy*(y+1)) | |
if i2<nx2 then i2 = i2 +1 end | |
end | |
if i1==nx1 and i2==nx2 then continue=false end | |
k,n=k+3,n+1 | |
if n>nMax then continue=false end | |
end | |
end | |
return v,t | |
end | |
function Sphere_WarpVertices(verts) | |
local m = matrix(0,0,0,0, 0,0,0,0, 1,0,0,0, 0,0,0,0) | |
local vx,vy,vz,vm | |
for i,v in ipairs(verts) do | |
vx,vy = v[1], v[2] | |
vm = m:rotate(180*vy,1,0,0):rotate(180*vx,0,1,0) | |
vx,vy,vz = vm[1],vm[5],vm[9] | |
verts[i] = vec3(vx,vy,vz) | |
end | |
return verts | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment