@Stevon8ter, @Luismi, I have updated my code (but it was in a duplicate project, so no CC yet, but here’s a preview:
-- Page Turn
-- Use this function to perform your initial setup
function setup()
noSmooth()
parameter.watch("1/DeltaTime")
p = {} -- page
local s = 1.5 -- scale factor
p.w = 210 * s -- A4 width
p.h = 297 * s -- A4 height
p.l = math.sqrt(math.pow(p.w, 2) + math.pow(p.h, 2))
b = {} -- book
b.active = false
b.w = p.w * 2
b.h = p.h
b.c = vec2(WIDTH / 2, HEIGHT / 2)
b.b = b.c.y - b.h / 2
b.t = b.c.y + b.h / 2
b.l = b.c.x - b.w / 2
b.r = b.c.x + b.w / 2
b.bl = vec2(b.l, b.b)
b.bc = vec2(b.c.x, b.b)
b.br = vec2(b.r, b.b)
b.tl = vec2(b.l, b.t)
b.tc = vec2(b.c.x, b.t)
b.tr = vec2(b.r, b.t)
pages = {
{ { b.bl, b.tl, b.tc, b.bc }, { vec2(0, 0), vec2(0, 1), vec2(1, 1), vec2(1, 0) } },
{ { b.bc, b.tc, b.tr, b.br }, { vec2(0, 0), vec2(0, 1), vec2(1, 1), vec2(1, 0) } },
{ { }, { } }
}
flip = mesh()
flip.texture = "Dropbox:A4"
flip:setColors(255, 255, 255, 255)
b.mesh = mesh()
b.mesh.texture = "Dropbox:A4"
function b:construct()
local v = append(triangulate(pages[1][1]), triangulate(pages[2][1]))
self.mesh:resize(#v)
self.mesh.vertices = v
self.mesh.texCoords = append(triangulate(pages[1][2]), triangulate(pages[2][2]))
self.mesh:setColors(255, 255, 255, 255)
flip.vertices = triangulate(pages[3][1])
flip.texCoords = triangulate(pages[3][2])
flip:setColors(255, 255, 255, 255)
end
b:construct()
c = {} -- corner
c.selected = nil -- I know it does nothing, it is there as a reminder
c.t = vec2(b.br.x, b.br.y) -- touch
c.pos = vec2(b.br.x, b.br.y) -- position
end
-- This function gets called once every frame
function draw()
background(40, 40, 50)
if b.active then
if c.pos.y < b.b + 1 and c.selected == nil then
c.pos.x = c.t.x
c.pos.y = c.t.y
b.active = false
end
c.pos = constrain(constrain(c.pos + (c.t - c.pos) * 0.13, b.bc, p.w), b.tc, p.l)
bisect = (c.pos + b.br) / 2
tan = intersect(b.bl, vec2(1, 0), bisect, (bisect - c.pos):rotate90())
pageAngle = vec2(0, 1):angleBetween(bisect - tan)
clipAngle = vec2(0, 1):angleBetween(c.pos - tan)
rI = intersect(b.br, vec2(0, 1), tan, vec2(0, 1):rotate(pageAngle))
bI = intersect(b.br, vec2(1, 0), tan, vec2(0, 1):rotate(pageAngle))
local tl = c.pos + vec2(p.h, 0):rotate(clipAngle)
local tr = tl + vec2(p.w, 0):rotate(clipAngle)
local ti = intersect(b.tr, vec2(1, 0), tl, c.pos - tan)
if tl.x > b.r then
pages[3][1] = {
bI,
c.pos,
rI
}
pages[3][2] = {
vec2((bI - c.pos):len() / p.w, 0),
vec2(0, 0),
vec2(0, (rI - c.pos):len() / p.h),
}
--[[pages[2][1] = {
bI,
b.bc,
b.tc,
b.tr,
rI,
}
pages[2][2] = {
vec2((bI - c.pos):len() / p.w, 0),
vec2(0, 0),
vec2(0, 1),
vec2(1, 1),
vec2(1, (rI - c.pos):len() / p.h),
}]]
else
pages[3][1] = {
bI,
c.pos,
tl,
ti,
}
pages[3][2] = {
vec2((bI - c.pos):len() / p.w, 0),
vec2(0, 0),
vec2(0, 1),
vec2((ti - tl):len() / p.w, 1),
}
end
b:construct()
end
b.mesh:draw()
flip:draw()
end
function touched(t)
if t.state == BEGAN then
if not c.selected
and t.x > b.l
and t.x < b.r
and t.y > b.b
and t.y < b.t
then
c.selected = t.id
b.active = true
c.t.x, c.t.y = t.x, t.y
end
elseif c.selected == t.id then
c.t.x, c.t.y = t.x, t.y
if t.state == ENDED then
c.selected = nil
if t.deltaX < 0 or c.pos.x < b.c.x then
c.t.x, c.t.y = b.bl.x, b.bl.y
b.f = turn
else
c.t.x, c.t.y = b.br.x, b.br.y
end
end
end
end
function intersect(o1, v1, o2, v2)
local d = o2 - o1
v2 = v2:rotate90()
local t = d:dot(v2) / v1:dot(v2)
return o1 + v1 * t
end
function constrain(v, c, r)
if (v-c):len() > r then
return (v-c):normalize() * r + c
end
return v
end
function append(t1, t2)
for i, j in ipairs(t2) do
table.insert(t1, j)
end
return t1
end
-- Rewritten triangulate function to account for nil cases
local _triangulate = triangulate
function triangulate(t)
return _triangulate(t) or {}
end
function turn()
end