Created
July 3, 2013 02:01
-
-
Save dermotbalson/5914883 to your computer and use it in GitHub Desktop.
cubez2
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
--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