I try to create a simple and minimalistic touch library, which takes care of all touches and the corresponding shapes. I wrote a little prototype. It works only with polygons (e.g. mesh) and only when they are not transformed by rotation, translation or scale. To check the ‘hit / collision point’ on the shape itself, I use the pointInPoly() function…
How can I apply my concept to transformed matrices? (How can I check, if the polygon was hit by a touch, when this polygon is rotated, etc… - so, matrix has changed, but its vertices actually remained the same as before?)
Hope you do understand, what I want. Sorry for confusion.
Main
function setup()
body = {mesh = mesh()}
body.vertices = {
vec2(0,0),
vec2(60,0),
vec2(0,40),
vec2(60,0),
vec2(60,40),
vec2(0,40)
}
body.mesh.vertices = body.vertices
head = {mesh = mesh()}
head.callback = function() print("touched head") end
head.vertices = {
vec2(10,20),
vec2(50,20),
vec2(10,80),
vec2(50,20),
vec2(50,80),
vec2(10,80)
}
head.mesh.vertices = head.vertices
monitor = StatusBar()
addTouchListener(body, function(touch) --notice ordering!
if touch.state == ENDED then
print("touched body")
end
end)
addTouchListener(head)
addTouchListener(monitor, function() print("NONONO!!!") end)
end
function draw()
background(80, 86, 87, 255)
translate(WIDTH/2, HEIGHT/2)
rotate(45)
fill(174, 174, 40, 255)
body.mesh:draw()
fill(255, 72, 0, 255)
head.mesh:draw()
resetMatrix()
monitor:draw()
end
function touched(touch)
updateTouchListeners(touch)
end
Facilities
local function pointInPoly(touch, vertices)
local intersectionCount = 0
local x0 = vertices[#vertices].x - touch.x
local y0 = vertices[#vertices].y - touch.y
for i = 1, #vertices do
local x1 = vertices[i].x - touch.x
local y1 = vertices[i].y - touch.y
if y0 > 0 and y1 <= 0 and x1 * y0 > y1 * x0 then
intersectionCount = intersectionCount + 1
end
if y1 > 0 and y0 <= 0 and x0 * y1 > y0 * x1 then
intersectionCount = intersectionCount + 1
end
x0 = x1
y0 = y1
end
return (intersectionCount % 2) == 1
end
function addTouchListener(obj, callback)
if not _touchesStack then --create a stack, if needed
_touchesStack = {}
end
if callback then --bind callback to obj, if given
obj.callback = callback
end
table.insert(_touchesStack, obj)
end
function updateTouchListeners(touch)
for i=#_touchesStack, 1, -1 do --travel stack in reverse and compare touch with each obj
local obj = _touchesStack[i]
if obj.vertices and pointInPoly(touch, obj.vertices) then --check collision
if obj.callback then
obj.callback(touch)
end
return true
end
if obj.touched then --fallback to 'original' method, if any
obj:touched(touch)
end
end
return false
end