Skip to content

Instantly share code, notes, and snippets.

@dermotbalson
Last active August 29, 2015 14:13
Show Gist options
  • Save dermotbalson/3b1ec6169604bf87f09b to your computer and use it in GitHub Desktop.
Save dermotbalson/3b1ec6169604bf87f09b to your computer and use it in GitHub Desktop.
Touch code math - plane Ver 2
function setup()
pics={
{name="red",pos=vec3(-100,-300,-250),size=vec3(400,600,1),rotation=vec3(45,0,20),colr=color(255,0,0)},
{name="yellow",pos=vec3(100,200,-250),size=vec3(400,600,1),rotation=vec3(-45,30,0),colr=color(255,255,0)}
}
end
function draw()
background(50)
perspective()
camera(0,0,1000,0,0,-1)
for _,p in pairs(pics) do
pushMatrix()
translate(p.pos.x,p.pos.y,p.pos.z)
if p.rotation.x~=0 then rotate(p.rotation.x,1,0,0) end
if p.rotation.y~=0 then rotate(p.rotation.y,0,1,0) end
if p.rotation.z~=0 then rotate(p.rotation.z,0,0,1) end
fill(p.colr)
rect(-p.size.x/2,-p.size.y/2,p.size.x,p.size.y)
p.matrix=SetMatrix()
popMatrix()
end
end
function touched(t)
if t.state==ENDED then
for _,p in pairs(pics) do
touchPoint=PictureIsTouchedBy(t,p.size,p.matrix)
if touchPoint then print(p.name,"=",touchPoint) end
end
end
end
------ touch code below ----
Matrix=matrix() --to store model x view x projection matrix
function SetMatrix()
Matrix=modelMatrix() * viewMatrix() * projectionMatrix()
return Matrix
end
function PictureIsTouchedBy(t,s,m)
m=m or Matrix
local tc = screentoplane(t, vec3(0,0,0), vec3(1,0,0), vec3(0,1,0), m)
tc=vec2(tc.x+0.5*s.x,tc.y+0.5*s.y)
if tc.x<0 or tc.x>s.x or tc.y<0 or tc.y>s.y then return nil end
return tc
end
-- Compute the cofactor matrix of a 3x3 matrix, entries
-- hard-coded for efficiency.
-- The cofactor differs from the inverse by a scale factor, but
-- as our matrices are only well-defined up to scale, this
-- doen't matter.
function cofactor3(m)
return {
vec3(
m[2].y * m[3].z - m[3].y * m[2].z,
m[3].y * m[1].z - m[1].y * m[3].z,
m[1].y * m[2].z - m[2].y * m[1].z
),
vec3(
m[2].z * m[3].x - m[3].z * m[2].x,
m[3].z * m[1].x - m[1].z * m[3].x,
m[1].z * m[2].x - m[2].z * m[1].x
),
vec3(
m[2].x * m[3].y - m[3].x * m[2].y,
m[3].x * m[1].y - m[1].x * m[3].y,
m[1].x * m[2].y - m[2].x * m[1].y
)
}
end
-- Given a plane in space, this computes the transformation
-- matrix from that plane to the screen
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 = A*o
uA = A*u
vA = A*v
oA = applymatrix4(o,A)
uA = applymatrix4(u,A)
vA = applymatrix4(v,A)
return { vec3(uA[1], uA[2], uA[4]),
vec3(vA[1], vA[2], vA[4]),
vec3(oA[1], oA[2], oA[4])}
end
-- Given a plane in space, this computes the transformation
-- matrix from the screen to that plane
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 = vec3((t.x/WIDTH - .5)*2,(t.y/HEIGHT - .5)*2,1)
local a
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
-- This computes a frame in which the first vector is along
-- the "touch ray" and the other two are in the orthogonal plane
-- (but the whole frame is not guaranteed to be orthogonal)
function screenframe(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),u,v
end
-- Apply a 3-matrix to a 3-vector
function applymatrix3(v,m)
return v.x * m[1] + v.y * m[2] + v.z * m[3]
end
-- Apply a 4-matrix to a 4-vector
function applymatrix4(v,m)
return vec4(
m[1]*v[1] + m[5]*v[2] + m[09]*v[3] + m[13]*v[4],
m[2]*v[1] + m[6]*v[2] + m[10]*v[3] + m[14]*v[4],
m[3]*v[1] + m[7]*v[2] + m[11]*v[3] + m[15]*v[4],
m[4]*v[1] + m[8]*v[2] + m[12]*v[3] + m[16]*v[4]
)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment