Skip to content

Instantly share code, notes, and snippets.

@dermotbalson
Last active August 29, 2015 14:13
Show Gist options
  • Save dermotbalson/286f386438d427d3c721 to your computer and use it in GitHub Desktop.
Save dermotbalson/286f386438d427d3c721 to your computer and use it in GitHub Desktop.
Touch code math - plane
function setup()
p={}
p.pos=vec3(0,-200,-250)
p.size=vec3(500,800,1)
p.rotation=vec3(45,0,20)
p.picture="Cargo Bot:Starry Background"
end
function draw()
background(50)
perspective()
camera(0,0,1000,0,0,-1)
pushMatrix()
--do rotations but not translation
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
SetMatrix(p.pos,p.size)
sprite(p.picture,0,0,1,1)
popMatrix()
end
function touched(t)
if t.state==ENDED then
touchPoint=PictureIsTouchedBy(t)
print(touchPoint)
end
end
------ touch code below ----
Matrix=matrix() --to store model x view x projection matrix
function SetMatrix(p,s)
local mm = matrix()
mm = mm:translate(p.x,p.y,p.z)
mm = mm:scale(s.x,s.y,s.z)
applyMatrix(mm)
Matrix=modelMatrix() * viewMatrix() * projectionMatrix()
end
function PictureIsTouchedBy(t)
local tc = screentoplane(t, vec3(0,0,0), vec3(1,0,0), vec3(0,1,0), Matrix)
if math.abs(tc.x) > 0.5 or math.abs(tc.y) > 0.5 then return nil end
return tc +vec3(0.5,0.5,0.5)
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