Skip to content

Instantly share code, notes, and snippets.

@dermotbalson
Created July 3, 2013 02:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dermotbalson/5914883 to your computer and use it in GitHub Desktop.
Save dermotbalson/5914883 to your computer and use it in GitHub Desktop.
cubez2
--code by Andrew Stacey
function setup()
--displayMode(FULLSCREEN_NO_BUTTONS)
cubez={}
for i=1,5 do
cubez[i]=Cube(vec3(math.random(-2,2),
math.random(-2,2),
math.random(-50,0)))
end
table.sort(cubez,function(a,b) return a.pos.z<b.pos.z end)
parameter.integer("azimuth",-180,180,0)
parameter.integer("zenith",-90,90,0)
end
function draw()
background(40, 40, 50)
noSmooth()
noStroke()
fill(0, 255, 238, 255)
ellipse(CurrentTouch.x,CurrentTouch.y,15)
resetMatrix()
perspective(40, WIDTH/HEIGHT)
camera(0,0,10, 0,0,0, 0,1,0)
rotate(zenith,0,1,0)
rotate(azimuth,0,0,1)
for i,c in pairs(cubez) do
c:draw()
end
end
function touched(touch)
if touch.state == BEGAN then
cube = nil
for i,c in pairs(cubez) do
if c:isTouchedBy(t) then
cube = c
print("Touched cube " .. i)
break
end
end
else
if cube then
cube:processTouch(touch)
end
end
end
Cube = class()
__cube = mesh()
local corners = {}
for l=0,7 do
i,j,k=l%2,math.floor(l/2)%2,math.floor(l/4)%2
table.insert(corners,{vec3(i,j,k),color(255*i,255*j,255*k)})
end
local vertices = {}
local colours = {}
local u
for l=0,2 do
for i=0,1 do
for k=0,1 do
for j=0,2 do
u = (i*2^l + ((j+k)%2)*2^((l+1)%3)
+ (math.floor((j+k)/2)%2)*2^((l+2)%3)) + 1
table.insert(vertices,corners[u][1])
table.insert(colours,corners[u][2])
end
end
end
end
__cube.vertices = vertices
__cube.colors = colours
function Cube:init(v)
self.pos = v
end
function Cube:draw()
pushMatrix()
translate(self.pos.x,self.pos.y,self.pos.z)
self.matrix = modelMatrix() * viewMatrix() * projectionMatrix()
__cube:draw()
popMatrix()
end
function Cube:isTouchedBy(t)
local n = screennormal(t,self.matrix)
if math.abs(n.z) > math.abs(n.y)
and math.abs(n.z) > math.abs(n.x)
then
if n.z > 0 then
self.plane = {vec3(0,0,1),vec3(1,0,0),vec3(0,1,0)}
else
self.plane = {vec3(0,0,0),vec3(1,0,0),vec3(0,1,0)}
end
elseif math.abs(n.y) > math.abs(n.x) then
if n.y > 0 then
self.plane = {vec3(0,1,0),vec3(1,0,0),vec3(0,0,1)}
else
self.plane = {vec3(0,0,0),vec3(1,0,0),vec3(0,0,1)}
end
else
if n.x > 0 then
self.plane = {vec3(1,0,0),vec3(0,1,0),vec3(0,0,1)}
else
self.plane = {vec3(0,0,0),vec3(0,1,0),vec3(0,0,1)}
end
end
local tc = screentoplane(t,
self.plane[1],
self.plane[2],
self.plane[3],
self.matrix)
if tc:dot(self.plane[2]) > 0 and tc:dot(self.plane[2]) < 1 and
tc:dot(self.plane[3]) > 0 and tc:dot(self.plane[3]) < 1 then
self.smatrix = self.matrix
self.starttouch = tc - self.pos
return true
end
return false
end
function Cube:processTouch(t)
local tc = screentoplane(t,
self.plane[1],
self.plane[2],
self.plane[3],
self.smatrix)
self.pos = tc - self.starttouch
end
--NO MORE NEW CODE FROM HERE
function converttouch(z,t,A)
A = A or modelMatrix() * viewMatrix() * projectionMatrix()
t = t or CurrentTouch or vec2(0,0)
z = z or 0
local m = cofactor4(A)
local ndc = {}
local a
ndc[1] = (t.x/WIDTH - .5)*2
ndc[2] = (t.y/HEIGHT - .5)*2
ndc[3] = z
ndc[4] = 1
a = applymatrix4(ndc,m)
if (a[4] == 0) then return end
a = vec3(a[1], a[2], a[3])/a[4]
return a
end
function getzlevel(v,A)
A = A or modelMatrix() * viewMatrix() * projectionMatrix()
v = v or vec3(0,0,0)
local u = applymatrix4(vec4(v.x,v.y,v.z,1),A)
if u[4] == 0 then return end
return u[3]/u[4]
end
function applymatrix4(v,m)
local u = {}
u[1] = m[1]*v[1] + m[5]*v[2] + m[09]*v[3] + m[13]*v[4]
u[2] = m[2]*v[1] + m[6]*v[2] + m[10]*v[3] + m[14]*v[4]
u[3] = m[3]*v[1] + m[7]*v[2] + m[11]*v[3] + m[15]*v[4]
u[4] = m[4]*v[1] + m[8]*v[2] + m[12]*v[3] + m[16]*v[4]
return u
end
function cofactor4(m)
local rm = matrix()
local sgn,l
local fm = {}
for k=1,16 do
fm = {}
l = math.floor((k-1)/4) + 1 + 4*((k-1)%4)
sgn = (-1)^(math.floor((k-1)/4))*(-1)^((k-1)%4)
for j=1,16 do
if j%4 ~= k%4
and math.floor((j-1)/4) ~= math.floor((k-1)/4)
then
table.insert(fm,m[j])
end
end
rm[l] = sgn*Det3(fm)
end
return rm
end
function Det3(t)
return t[1]*t[5]*t[9]
+ t[2]*t[6]*t[7]
+ t[3]*t[4]*t[8]
- t[3]*t[5]*t[7]
- t[2]*t[4]*t[9]
- t[1]*t[6]*t[8]
end
function applymatrix3(v,m)
local u = {}
u[1] = m[1]*v[1] + m[4]*v[2] + m[7]*v[3]
u[2] = m[2]*v[1] + m[5]*v[2] + m[8]*v[3]
u[3] = m[3]*v[1] + m[6]*v[2] + m[9]*v[3]
return u
end
function cofactor3(m)
local rm = {}
local sgn,l
local fm = {}
for k=1,9 do
fm = {}
l = math.floor((k-1)/3) + 1 + 3*((k-1)%3)
sgn = (-1)^(math.floor((k-1)/3))*(-1)^((k-1)%3)
for j=1,9 do
if j%3 ~= k%3
and math.floor((j-1)/3) ~= math.floor((k-1)/3)
then
table.insert(fm,m[j])
end
end
rm[l] = sgn*Det2(fm)
end
return rm
end
function Det2(t)
return t[1]*t[4] - t[2]*t[3]
end
function __planetoscreen(o,u,v,A)
A = A or modelMatrix() * viewMatrix() * projectionMatrix()
o = o or vec3(0,0,0)
u = u or vec3(1,0,0)
v = v or vec3(0,1,0)
-- promote to 4-vectors
o = vec4(o.x,o.y,o.z,1)
u = vec4(u.x,u.y,u.z,0)
v = vec4(v.x,v.y,v.z,0)
local oA, uA, vA
oA = applymatrix4(o,A)
uA = applymatrix4(u,A)
vA = applymatrix4(v,A)
return { uA[1], uA[2], uA[4],
vA[1], vA[2], vA[4],
oA[1], oA[2], oA[4]}
end
function screentoplane(t,o,u,v,A)
A = A or modelMatrix() * viewMatrix() * projectionMatrix()
o = o or vec3(0,0,0)
u = u or vec3(1,0,0)
v = v or vec3(0,1,0)
t = t or CurrentTouch
local m = __planetoscreen(o,u,v,A)
m = cofactor3(m)
local ndc = {}
local a
ndc[1] = (t.x/WIDTH - .5)*2
ndc[2] = (t.y/HEIGHT - .5)*2
ndc[3] = 1
a = applymatrix3(ndc,m)
if (a[3] == 0) then return end
a = vec2(a[1], a[2])/a[3]
return o + a.x*u + a.y*v
end
function screennormal(t,A)
A = A or modelMatrix() * viewMatrix() * projectionMatrix()
t = t or CurrentTouch
local u,v,w,x,y
u = vec3(A[1],A[5],A[9])
v = vec3(A[2],A[6],A[10])
w = vec3(A[4],A[8],A[12])
x = (t.x/WIDTH - .5)*2
y = (t.y/HEIGHT - .5)*2
u = u - x*w
v = v - y*w
return u:cross(v)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment