Skip to content

Instantly share code, notes, and snippets.

@dermotbalson
Created April 9, 2013 14:40
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save dermotbalson/5346211 to your computer and use it in GitHub Desktop.
16. Cube
--# Main
--[[
In this demo, I've added a texture from the internet to make the dice more interesting
I've also added a fake highlight to the dice spots to give them some depth
--]]
function setup()
FieldOfView=45
CamHeight=300
Angle=0
local s=75
--create the covering for the block, get a picture from the internet
--only create the dice once we have the image
http.request("http://fc03.deviantart.net/fs47/i/2009/204/4/b/Blue_Venetian_Glass_Texture_by_powerpuffjazz.jpg",
function(img,a,b)
glass=img
local img2,imgData=createDice(s)
blk=Block3(s,s,s,img2,imgData)
end
)
end
function draw()
background(152, 182, 196, 255)
while glass==nil do --wait for internet image before drawing
output:clear()
print("Please wait while I load the texture from the internet..")
return
end
-- First arg is FOV, second is aspect
perspective(FieldOfView, WIDTH/HEIGHT)
-- Position the camera up and back, look at origin
camera(0,CamHeight,-300, 0,0,0, 0,1,0)
pushMatrix()
rotate(Angle,0,1,0)
blk:draw()
-- Restore orthographic projection
ortho()
-- Restore the view matrix to the identity
viewMatrix(matrix())
output.clear()
print("We create our own dice")
popMatrix()
end
function touched(touch)
local xx,yy=math.floor(touch.x*3/WIDTH),math.floor(touch.y*3/HEIGHT)
if xx==0 then Angle=Angle-15 elseif xx==2 then Angle=Angle+15 end
if yy==0 then CamHeight=CamHeight-50 elseif yy==2 then CamHeight=CamHeight+50 end
end
function createDice(s)
local d=s/5
local img=glass:copy(1,1,s,s*6) --create a new image with a slice of the texture, the size we need
--local img=image(s,s*6) --so we don't need this line any more
--I'm going to create a dot with a whte spot, to give it depth
--I'll do this with another little image, which I'll create now
local dot=image(d,d) -- CHANGED next few lines are new
pushStyle()
setContext(dot) --draw on my dot
fill(0, 0, 0, 255)
ellipse(d/2,d/2,d)
fill(232, 231, 231, 150) -- add whiteish dot off centre
ellipse(d/2-d/4,d/2,d/4,d/3)
setContext(img)
--add a light blue filter over the texture to make it lighter in color
fill(200, 208, 211, 85)
rect(0,0,img.width,img.height)
fill(192, 184, 156, 255)
--rect(0,0,s,s*6) --no need to add a background now
rectMode(CENTER)
fill(0, 0, 0, 255)
-- Insert numbers in this sequence - Front, Right, Back, Left, Top, Bottom to tie in with Block class
--one
sprite(dot,s/2,s/2) --CHANGED secdot image instead of drawing ellipses
--two
local h=s
sprite(dot,s/3,h+s/2)
sprite(dot,s*2/3,h+s/2)
--six
h=h+s
sprite(dot,s/4,h+s/3)
sprite(dot,s/4,h+s*2/3)
sprite(dot,s/2,h+s/3)
sprite(dot,s/2,h+s*2/3)
sprite(dot,s*3/4,h+s/3)
sprite(dot,s*3/4,h+s*2/3)
--five
h = h + s
sprite(dot,s/4,h+s/4)
sprite(dot,s*3/4,h+s/4)
sprite(dot,s/4,h+s*3/4)
sprite(dot,s*3/4,h+s*3/4)
sprite(dot,s/2,h+s/2)
--three
h = h + s
sprite(dot,s/4,h+s/2)
sprite(dot,s/2,h+s/2)
sprite(dot,s*3/4,h+s/2)
--four
h = h + s
sprite(dot,s/3,h+s/3,d)
sprite(dot,s*2/3,h+s/3,d)
sprite(dot,s/3,h+s*2/3,d)
sprite(dot,s*2/3,h+s*2/3,d)
--add a border for effect
local clr=color(188, 206, 215, 255)
fill(clr)
stroke(clr)
strokeWidth(1)
for i=1,6 do
local y=(i-1)*s
line(1,y+1,s,y+1)
line(1,y+1,1,y+s)
line(1,y+s,s,y+s)
line(s,y+1,s,y+s)
end
popStyle()
setContext()
saveImage("Documents:test1",img)
local imgData={0,0,1,1/6, 0,1/6,1,2/6, 0,2/6,1,3/6, 0,3/6,1,4/6, 0,4/6,1,5/6, 0,5/6,1,1}
return img,imgData
end
--# Block3
Block3 = class() --taken from 3D lab project
--t=either string name of image, or an array of 6 colors, one per block face
function Block3:init(w,h,d,t,r) --width,height,depth,texture/colors, (optional) texture range (see above)
self.width=w
self.height=h
self.depth=d
if type(t)=="string" or type(t)=="userdata" then --CHANGED to trap cases where we provide an actual image
self.type="Image" --CHANGED
self.tex=t --string name of an image in the library, or the image itself
--if no limits specified on which part of image to draw, set to 0,1
if r~=nil then self.texR=r else self.texR={0,0,1,1} end
else --we are given a table of colors, one per face
self.type="Colors" --CHANGED
self.colrs=t
end
self.blk=self:createBlock()
end
function Block3:createBlock()
-- all the unique vertices that make up a block
--There are only 8 corners in a cube - we define them as vertices
--all measurements are taken from the centre of the block
--so bottom left front has x of -1/2 width, y of -1/2 height, and z of 1/2 depth
local w,h,d=self.width,self.height,self.depth
local v = {
vec3(-0.5*w, -0.5*h, 0.5*d), -- Left bottom front
vec3( 0.5*w, -0.5*h, 0.5*d), -- Right bottom front
vec3( 0.5*w, 0.5*h, 0.5*d), -- Right top front
vec3(-0.5*w, 0.5*h, 0.5*d), -- Left top front
vec3(-0.5*w, -0.5*h, -0.5*d), -- Left bottom back
vec3( 0.5*w, -0.5*h, -0.5*d), -- Right bottom back
vec3( 0.5*w, 0.5*h, -0.5*d), -- Right top back
vec3(-0.5*w, 0.5*h, -0.5*d), -- Left top back
}
-- now construct a block out of the vertices above
--there are 6 sides, each made up of 2 triangles, each with 3 vertices
--so we need to assign 36 vertices in total
--the 8 vectors are assigned to the 8 corners as follows
--1,2,3,4 anticlockwise round front starting bottom left
--5,6,7,8 clockwise round back starting bottom right (assuming you are looking at the back)
--the first three vectors below use vectors 1,2 and 3. If you look above, you'll
--see those are for left and right of bottom front, plus right top of front
--so this is the right hand triangle for the front side
local cubeverts = {
-- Front, Right, Back, Left, Top, Bottom
v[1], v[2], v[3], v[1], v[3], v[4],
v[2], v[6], v[7], v[2], v[7], v[3],
v[6], v[5], v[8], v[6], v[8], v[7],
v[5], v[1], v[4], v[5], v[4], v[8],
v[4], v[3], v[7], v[4], v[7], v[8],
v[5], v[6], v[2], v[5], v[2], v[1],
}
-- add texture or colors
if self.type=="Image" then --texture --CHANGED
if #self.texR==4 then
--create vectors to be assigned to four corners of each face
local BL=vec2(self.texR[1],self.texR[2]) --bottom left
local BR=vec2(self.texR[3],self.texR[2]) --bottom right
local TR=vec2(self.texR[3],self.texR[4]) --top right
local TL=vec2(self.texR[1],self.texR[4]) --top left
-- apply the texture coordinates to each triangle
--we need to add them to each of the vertexes in the same order as above
--that means on each face we need to add them in the order BL, BR, TR, BL, TR, TL
self.texCoords = {}
for i=1,6 do
table.insert(self.texCoords,BL)
table.insert(self.texCoords,BR)
table.insert(self.texCoords,TR)
table.insert(self.texCoords,BL)
table.insert(self.texCoords,TR)
table.insert(self.texCoords,TL)
end
else --user has specified image fractions for each face
self.texCoords = {}
local u=0
for i=1,6 do
local BL=vec2(self.texR[u+1],self.texR[u+2]) --bottom left
local BR=vec2(self.texR[u+3],self.texR[u+2]) --bottom right
local TR=vec2(self.texR[u+3],self.texR[u+4]) --top right
local TL=vec2(self.texR[u+1],self.texR[u+4]) --top left
u = u + 4
table.insert(self.texCoords,BL)
table.insert(self.texCoords,BR)
table.insert(self.texCoords,TR)
table.insert(self.texCoords,BL)
table.insert(self.texCoords,TR)
table.insert(self.texCoords,TL)
end
end
else --colors, one per face
self.texColrs={}
for i=1,6 do
for j=1,6 do
table.insert(self.texColrs,self.colrs[i])
end
end
end
--put it all together
local ms = mesh()
ms.vertices = cubeverts
ms.texture = self.tex
if self.texCoords~=nil then ms.texCoords = self.texCoords end
ms:setColors(255,255,255,255)
if self.texColrs~=nil then ms.colors=self.texColrs end
return ms
end
function Block3:draw()
self.blk:draw()
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment