Skip to content

Instantly share code, notes, and snippets.

@dermotbalson
Created July 2, 2013 05:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dermotbalson/5906898 to your computer and use it in GitHub Desktop.
Save dermotbalson/5906898 to your computer and use it in GitHub Desktop.
3D touch
function setup()
size=50 --size of circles
n=30 --number of circle
counter=0 --for showing text on screen when we have a hit
CreateImages() --create images
parameter.integer("FPS",0,60,60) --show running speed on screen
img=image(WIDTH,HEIGHT)
end
function draw()
FPS=FPS*.9+.1/DeltaTime
if T~=nil then --draw on hidden image if we've had a hit
setContext(img)
else
background(80)
end
--if we've had a touch, draw to an image instead of the screen, just this one time
perspective()
camera(0,0,-200,0,0,-1000,0,1,0)
--draw all circle meshes
for i,p in pairs(b) do
pushMatrix()
translate(p.x,p.y,p.z)
--if we've had a touch, set the shader, and id number
--the shader will put this id number in all the pixels of the circle image
--(transparent pixels will be discarded)
if T~=nil then
p.m.shader.id=p.id/255
end
p.m:draw()
if T~=nil then p.m.shader.id=0 end
popMatrix()
end
--if we've had a touch, stop drawing on the image, and test for a hit on the image
if T~=nil then
setContext()
message=testHit() --message showing what we hit
counter=120
d=vec2(T.x,T.y)
T=nil
end
--all the code below does is to draw the message on the screen if we had a touch
if counter>0 then --show for as long as counter>0, currently 2 seconds
ortho() --this and next statement required to allow us to draw text on a 3D screen
viewMatrix(matrix())
pushStyle()
fill(255)
ellipse(d.x,d.y,20)
textMode(CORNER)
fontSize(36)
text(message,50,HEIGHT-50) --message
popStyle()
counter=counter-1 --decrement counter
end
end
function touched(touch)
--if we have a touch, store the x,y details
if touch.state==ENDED then
T=vec2(touch.x,touch.y)
end
end
--test pixel that was touched
--if it was a circle, it will have a colour of r,0,0 where r = id of circle
function testHit()
local r,g,b=img:get(T.x,T.y)
if g+b==0 and r>0 then
return "You touched "..r
else return "You missed!"
end
end
idShader = {
vertexShader = [[
uniform mat4 modelViewProjection;
attribute vec4 position;
attribute vec4 color;
attribute vec2 texCoord;
varying lowp vec4 vColor;
varying highp vec2 vTexCoord;
void main()
{
vColor = color;
vTexCoord = texCoord;
gl_Position = modelViewProjection * position;
}
]],
fragmentShader = [[
precision highp float;
uniform lowp sampler2D texture;
uniform float id;
varying lowp vec4 vColor;
varying highp vec2 vTexCoord;
void main()
{
lowp vec4 col=texture2D(texture, vTexCoord);
if (id==0. || col.a<0.2) gl_FragColor=col;
else gl_FragColor = vec4(id,0.,0.,1.);
}
]]}
function CreateImages()
b={} --table of circles
for i=1,n do --create circles
p={} --table to hold details for each circle
p.id=i --id number of circle
p.m=mesh() --create mesh for circle, one per circle
local img=image(size,size) --create drawing on an image
setContext(img)
fill(math.random(0,255),math.random(0,255),math.random(0,255))
ellipse(size/2,size/2,size)
fill(0)
fontSize(24)
text(i,size/2,size/2) --draw id number on circle
setContext() --done drawing our image
p.m:addRect(0,0,size,size) --add circle to mesh
p.m:setRectTex(1,0,0,1,1)
p.m.texture=img
p.m.shader=shader(idShader.vertexShader,idShader.fragmentShader)
p.m.shader.id=0
--random position
p.x,p.y,p.z=math.random(-100,100),math.random(-200,200),-math.random(300,1000)
table.insert(b,p) --add to table of circles
end
--insert an ordinary image that can't be touched
local img=readImage("Planet Cute:Character Princess Girl")
p={}
p.id=0
p.m=mesh()
p.m:addRect(0,0,img.width,img.height) --add circle to mesh
p.m:setRectTex(1,0,0,1,1)
p.m.texture=img
p.m.shader=shader(idShader.vertexShader,idShader.fragmentShader)
p.m.shader.id=0
--random position
p.x,p.y,p.z=math.random(-100,100),math.random(-200,200),-math.random(300,1000)
table.insert(b,p) --add to table of circles
table.sort(b,function(i,j) return i.z<j.z end) --sort by distance
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment