Created
February 8, 2016 12:29
-
-
Save tnlogy/c66775e8473efe2ddb39 to your computer and use it in GitHub Desktop.
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
--# Main | |
-- Picker | |
-- Use this function to perform your initial setup | |
function setup() | |
p = Picker() | |
end | |
-- This function gets called once every frame | |
function draw() | |
-- This sets a dark background color | |
background(p.color or color()) | |
-- This sets the line thickness | |
strokeWidth(5) | |
-- Do your drawing here | |
translate(WIDTH/2,HEIGHT/2) | |
p:draw() | |
end | |
function touched(touch) | |
-- if touch.state == BEGAN then | |
local t = vec2(touch.x-WIDTH/2,touch.y-HEIGHT/2) | |
p:touched(t) | |
-- end | |
end | |
--# Picker | |
Picker = class() | |
function Picker:init(size) | |
self.colors = { | |
color(255, 255, 255, 255), | |
color(255, 0, 0, 255), | |
color(255, 255, 0, 255), | |
color(0, 255, 0, 255), | |
color(0, 255, 255, 255), | |
color(0, 0, 255, 255), | |
color(255, 0, 255, 255) | |
} | |
self.size = size or 200 | |
self:createCircle() | |
self:createHexagon() | |
self:touched(vec2(0,0)) | |
end | |
function Picker:createHexagon() | |
local vs, cs, cl = {}, {}, self.colors | |
for i=1,6 do | |
local a = i/6 * math.pi * 2 | |
local b = (i+1)/6 * math.pi * 2 | |
table.insert(vs, vec2(0,0)) | |
table.insert(cs, cl[1]) | |
table.insert(vs, vec2(math.cos(a), math.sin(a)) * self.size) | |
table.insert(cs, cl[i+1]) | |
table.insert(vs, vec2(math.cos(b), math.sin(b)) * self.size) | |
table.insert(cs, cl[i+2] or cl[2]) | |
end | |
self.hexagon = mesh() | |
self.hexagon.vertices = vs | |
self.hexagon.colors = cs | |
self.hexagon.shader = circleShader() | |
end | |
function Picker:createCircle() | |
local vs,n,s = {},16,self.size*.15 | |
for i=1,n do | |
local a = i/n * math.pi * 2 | |
table.insert(vs, vec2(math.cos(a), math.sin(a)) * s) | |
end | |
self.circle = mesh() | |
self.circle.vertices = triangulate(vs) | |
vs = {} | |
for i=1,n do | |
local a = i/n * math.pi * 2 | |
table.insert(vs, vec2(math.cos(a), math.sin(a)) * (s+1)) | |
end | |
self.bcircle = mesh() | |
self.bcircle.vertices = triangulate(vs) | |
self.bcircle:setColors(0,0,0) | |
end | |
function Picker:draw() | |
self.hexagon.shader.p = self.pos | |
self.hexagon.shader.c = self.color | |
self.hexagon:draw() | |
if false then | |
pushMatrix() | |
translate(self.pos.x, self.pos.y) | |
self.circle:setColors(self.color) | |
self.bcircle:draw() | |
self.circle:draw() | |
popMatrix() | |
end | |
end | |
function Picker:touched(p) | |
p = vec3(p.x,p.y,0) -- vec3 in mesh | |
local h = self.hexagon | |
for i=1,#h.vertices,3 do | |
local a,b,c = h.vertices[i], h.vertices[i+1], h.vertices[i+2] | |
local inside, u, v = insideTriangle(a,b,c,p) | |
if inside then | |
local d,e,f = h.colors[i]*255, h.colors[i+1]*255, h.colors[i+2]*255 | |
self.color = (1-u-v)*d + u*f + v*e | |
self.pos = vec2(p.x, p.y) | |
return | |
end | |
end | |
end | |
function circleShader() | |
return shader([[ | |
uniform mat4 modelViewProjection; | |
attribute vec4 position; | |
varying highp vec2 vTexCoord; | |
attribute vec4 color; | |
varying lowp vec4 vColor; | |
void main() { | |
vTexCoord = position.xy; | |
vColor = color; | |
gl_Position = modelViewProjection * position; | |
} | |
]],[[ | |
precision highp float; | |
varying lowp vec4 vColor; | |
varying highp vec2 vTexCoord; | |
uniform vec2 p; | |
uniform vec4 c; | |
void main() { | |
lowp vec4 col = vColor; | |
float l = length(vTexCoord-p.xy); | |
if(l<20.) { | |
col = c; | |
} else if(l<22.) { | |
col = vec4(0.,0.,0.,1.); | |
} | |
gl_FragColor = col; | |
} | |
]]) | |
end | |
--# Utils | |
function uv(a,b,c,p) | |
local v0 = c - a | |
local v1 = b - a | |
local v2 = p - a | |
local dot00 = v0:dot(v0) | |
local dot01 = v0:dot(v1) | |
local dot02 = v0:dot(v2) | |
local dot11 = v1:dot(v1) | |
local dot12 = v1:dot(v2) | |
-- Compute barycentric coordinates | |
local invDenom = 1 / (dot00 * dot11 - dot01 * dot01) | |
local u = (dot11 * dot02 - dot01 * dot12) * invDenom | |
local v = (dot00 * dot12 - dot01 * dot02) * invDenom | |
return u,v | |
end | |
function insideTriangle(a,b,c,p) | |
local u,v = uv(a,b,c,p) | |
return (u >= 0) and (v >= 0) and (u + v < 1), u, v | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment