Last active
June 5, 2016 12:52
-
-
Save dermotbalson/34d83800a16632cf5f91d8d845bac3f4 to your computer and use it in GitHub Desktop.
3D box 2
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
--# Main | |
displayMode(FULLSCREEN) | |
function setup() | |
size,radius=200,10 | |
pos=vec3(0,0,0) --assumes centre of box is (0,0,0) | |
CreateScene() | |
notStarted=true | |
end | |
function touched(t) | |
if t.state==ENDED then | |
local v=vec3(math.random()*6-3,math.random()*6-3,math.random()*6-3):normalize()*5 | |
velocity=velocity+v | |
notStarted=false | |
end | |
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) | |
ball=CreateSphere(radius,readImage("Cargo Bot:Starry Background"),color(255)) | |
velocity=vec3(0,0,0) | |
end | |
function AdjustPos() | |
local p=pos+velocity | |
--check for collisions with each axis wall | |
local f=0 | |
--x | |
if p.x-radius<-size/2 then --collided with left wall | |
f=(-size/2-p.x+radius)/velocity.x --backtrack by this fraction of the last movement | |
velocity.x=-velocity.x --reverse x velocity | |
elseif p.x+radius>size/2 then --right wall | |
f=(p.x+radius-size/2)/velocity.x | |
velocity.x=-velocity.x | |
end | |
--y | |
if p.y-radius<-size/2 then | |
f=(-size/2-p.y+radius)/velocity.y | |
velocity.y=-velocity.y | |
elseif p.y+radius>size/2 then | |
f=(p.y+radius-size/2)/velocity.y | |
velocity.y=-velocity.y | |
end | |
--z | |
if p.z-radius<-size/2 then | |
f=(-size/2-p.z+radius)/velocity.z | |
velocity.z=-velocity.z | |
elseif p.z+radius>size/2 then | |
f=(p.z+radius-size/2)/velocity.z | |
velocity.z=-velocity.z | |
end | |
pos=pos+velocity*(1-f) | |
end | |
function draw() | |
background(220) | |
perspective(90) | |
AdjustPos() print(pos) | |
camera(0,0,0,pos.x,pos.y,pos.z) | |
box:draw() | |
pushMatrix() | |
translate(pos:unpack()) | |
ball:draw() | |
popMatrix() | |
if notStarted then | |
ortho() | |
viewMatrix(matrix()) | |
text( | |
[[You are at the centre of a box with a red ball. | |
You can't see anything because the ball is around you | |
Touch the screen to push the ball in a random direction | |
and the camera will follow its movement. | |
Touch the screen to push it again.]],WIDTH/2,HEIGHT/2) | |
end | |
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