Skip to content

Instantly share code, notes, and snippets.

@JMV38
Created February 7, 2014 06:57
Show Gist options
  • Select an option

  • Save JMV38/8858365 to your computer and use it in GitHub Desktop.

Select an option

Save JMV38/8858365 to your computer and use it in GitHub Desktop.
Codea Project Gist Created with AutoGist
AutoGist Tab Order Version: 2.2.8
------------------------------
This file should not be included in the Codea project.
#Main
#Convert
#ObjectClassForTest
Convert = class()
-- this class exposes save() and load() function to
-- > convert a table to an image on the disk
-- > read an image from disk and add its elements to a table object
-- Only the table elements of following types can be saved or read (others are ignored)
-- "{color}" means "a table of 'color' elements with integer indexation"
function Convert:supported(typ)
local ans = false
if typ=="string" then ans = true
elseif typ=="number" then ans = true
elseif typ=="image" then ans = true
elseif typ=="{color}"then ans = true
elseif typ=="{vec3}" then ans = true
elseif typ=="{vec2}" then ans = true
elseif typ=="matrix" then ans = true
elseif typ=="{matrix}" then ans = true
elseif typ=="mesh" then ans = true
end
return ans
end
function Convert:init()
end
-- local functions to be faster
local insert = table.insert
local floor = math.floor
-- print txt..t if debug is true
function debugPrint(debug,txt,t)
if debug then
local str = ""
if type(t)=="table" then str ="{"..tostring(t[1])..",... }"
elseif t~=nil then str = tostring(t)
end
print(txt..str)
end
end
-- **********************************************
-- object <=> image on disk
-- **********************************************
-- table obj is saved to image 'name'
function Convert:save(obj,name,debug)
local img = self:pushObject01(obj,debug)
local size = floor(img.width * img.height /2048 /2048 /2 *100)
debugPrint(debug,"object size = "..size.."% of max size")
self:saveImage(name, img)
return size
end
-- image 'name' is interpreted as a table and its tags forced to obj
function Convert:load(obj,name,debug)
local img = self:readImage(name)
local obj1 = self:popObject01(img)
local txt1,txt2
for tag,v in pairs(obj1) do
debugPrint(debug,"initial : obj."..tag.." = ",obj[tag])
obj[tag] = v
debugPrint(debug,"final : obj."..tag.." = ",v)
end
end
-- these function have been introduced because IOS can save only pre-multiplied images,
-- so to have no problems alpha must be 255
-- => i've split (r.g.b.a) in (r.g.0.255) and (b.a.0.255)
function Convert:saveImage(name,img)
local w,h = img.width, img.height
local x,y,r,g,b,a
local out = image(w,h*2)
for x=1,w do for y=1,h do
r,g,b,a = img:get(x,y)
out:set(x,y*2-1,r,g,0,255)
out:set(x,y*2 ,b,a,0,255)
end end
saveImage("Documents:"..name,out)
end
function Convert:readImage(name)
local img = readImage("Documents:"..name)
local w,h = img.width, img.height
local x,y,r,g,b,a,_
local out = image(w,h/2)
for x=1,w do for y=1,h/2 do
r,g,_,_ = img:get(x,y*2-1)
b,a,_,_ = img:get(x,y*2)
out:set(x,y,r,g,b,a)
end end
return out
end
-- **********************************************
-- object <=> image
-- **********************************************
function Convert:pushObject01(obj,debug)
debugPrint(debug,".....Start of pushObject01.....")
local header = {}
header.id = "JMV38-3d-object"
header.version = 1
-- put everything in a table
local t ={}
self:pushTag("id",header,t)
debugPrint(debug,"pushed : header.".."id".." = ",header.id)
self:pushTag("version",header,t)
debugPrint(debug,"pushed : header.".."version".." = ",header.version)
local i,v
for i,v in pairs(obj) do
self:pushTag(i,obj,t)
debugPrint(debug,"pushed : obj."..i.." = ",tostring(v))
end
-- 1 more pixel at 0 to indicate it is finished (and avoid image overflow)
insert(t, self:intToColor(0) )
-- convert to an image and return it
return self:tableToImage(t)
end
function Convert:popObject01(img,debug)
debugPrint(debug,".....Start of popObject01.....")
local n,tag
local t,out,header = {},{},{}
-- read verification information
n = 1
local nmax = self:colorToInt( color(img:get(self:xy(n))) )
t,n = self:imageToTable(n,img)
tag = self:popTag(1,t,header)
debugPrint(debug,"pop01 : header."..tag.." = "..tostring(header[tag]))
t,n = self:imageToTable(n,img)
tag = self:popTag(1,t,header)
debugPrint(debug,"pop01 : header."..tag.." = "..tostring(header[tag]))
if header.id~="JMV38-3d-object"
then error("this image is not a 3d object saved to an image")
elseif header.version ~= 1
then error("the object version ("..tostring(header.version)
..") is not compatible with this reader")
end
-- get other elements
t,n = self:imageToTable(n,img)
local tag,v,txt
while t do
tag = self:popTag(1,t,out)
v = out[tag]
if type(v)=="table" then
txt = self:type(v).." = {"..tostring(v[1])..",...}"
else
txt = tostring(v)
end
debugPrint(debug,"pop01 : obj."..tag.." = "..txt)
t,n = self:imageToTable(n,img)
end
return out
end
-- **********************************************
-- color table <=> image
-- **********************************************
function Convert:xy(i)
local x,y
y = floor((i-1)/2048)
x = i-1 - y*2048
return x+1,y+1
end
function Convert:tableToImage(t)
-- write table in an image
local n = #t
local h = floor(n/2048)+1
local w
if n>2048 then w=2048 else w=n end
local img = image(w,h)
local x,y,i
for i=1,n do
x,y = self:xy(i)
img:set(x,y,t[i])
-- if self:type(t[i])~="color" then
-- error(i.." : "..tostring(t[i]).." : "..self:type(t[i])) end
end
return img
end
function Convert:imageToTable(n,img)
-- read a table from an image: start at index n, where the number of colors
-- to read is stored, read these colors, return the table and new index n value
local w,h = img.width, img.height
local x,y,i,c,k
local t = {}
local nmax = self:colorToInt( color(img:get(self:xy(n))) )
-- print("imageToTable : nmax = "..tostring(nmax))
if nmax==0 then t=nil
else
for i=0,nmax do
c = color(img:get( self:xy(i+n) ))
k = i+1
-- print("imageToTable : img["..(k).."] = "..tostring(c))
t[k] = c
end
end
return t,(n+nmax+1)
end
-- **********************************************
-- object.tag <=> color table
-- **********************************************
-- push an pop principles
-- push(data,t) writes at the end of table t:
-- the number of data words
-- the data words themselves
-- pop(n,t)
-- reads n data words from table t
-- converts these words to the data object 'out'
-- returns 'out' and 'next_n' (for next pop start)
-- **********************************************
function Convert:pushTag(tag,obj,out)
local x = obj[tag]
local typ = self:type(x)
if self:supported(typ) then
local n = #out -- record the position before the starting point of this data
self:pushString(tag,out) -- write tag string
self:pushString(typ,out) -- write tag type
if typ=="string" then self:pushString(x,out)
elseif typ=="number" then self:pushNumber(x,out)
elseif typ=="image" then self:pushImage(x,out)
elseif typ=="{color}" then self:pushColors(x,out)
elseif typ=="{vec3}" then self:pushVec3(x,out)
elseif typ=="{vec2}" then self:pushVec2(x,out)
elseif typ=="{matrix}" then self:pushMatTable(x,out)
elseif typ=="matrix" then self:pushMat(x,out)
elseif typ=="mesh" then self:pushMesh(x,out)
end
local n1 = #out - n
insert(out, n+1, self:intToColor(n1) )
else
print("the type of '"..tag.."' is not supported for saving: "..typ)
end
end
function Convert:popTag(n,t,obj)
local input,nmax = self:getSubTable(n,t)
local tag,typ,out
local n1 = 1
tag,n1 = self:popString(n1,input)
typ,n1 = self:popString(n1,input)
if typ=="string" then out,n1 = self:popString(n1,input)
elseif typ=="number" then out,n1 = self:popNumber(n1,input)
elseif typ=="image" then out,n1 = self:popImage(n1,input)
elseif typ=="{color}" then out,n1 = self:popColors(n1,input)
elseif typ=="{vec3}" then out,n1 = self:popVec3(n1,input)
elseif typ=="{vec2}" then out,n1 = self:popVec2(n1,input)
elseif typ=="matrix" then out,n1 = self:popMat(n1,input)
elseif typ=="{matrix}"then out,n1 = self:popMatTable(n1,input)
elseif typ=="mesh" then out,n1 = self:popMesh(n1,input)
end
obj[tag]=out
local next_n = n + nmax + 1
return tag, next_n
end
-- **********************************************
-- data structure <=> color table
-- **********************************************
-- mesh
function Convert:pushMesh(ms,t)
local n = #t -- record the position before the starting point of this data
local myTable = {}
local texCoords,colors = {},{}
myTable.vertices = ms.vertices
myTable.texture = ms.texture
if ms.texCoords then
-- read texCoords to correct for mesh bug : y = 1-y
for i=1,#ms.texCoords do texCoords[i] = ms:texCoord(i) end
myTable.texCoords = texCoords
end
if ms.colors then
-- read texCoords to correct for mesh bug : color = 0.0 to 1.0, instead of 0 to 255
for i=1,#ms.colors do colors[i] = ms:color(i) end
myTable.colors = colors
end
if myTable.vertices then self:pushTag("vertices", myTable,t) end
if myTable.texture then self:pushTag("texture", myTable,t) end
if myTable.texCoords then self:pushTag("texCoords",myTable,t) end
if myTable.colors then self:pushTag("colors", myTable,t) end
local n1 = #t - n -- n1 is the number of data
insert(t, n+1, self:intToColor(n1) )
end
function Convert:popMesh(n,t)
local input,nmax = self:getSubTable(n,t)
local i,tag
local ms = mesh()
local n1 = 1
while n1<nmax do
tag,n1 = self:popTag(n1,input,ms)
end
local next_n = n + nmax + 1
return ms, next_n
end
-- matrix
function Convert:pushMat(m,t)
local n = #t -- record the position before the starting point of this data
local i
for i=1,16 do
insert(t,self:floatToColor(m[i]))
end
local n1 = #t - n -- n1 is the number of data
insert(t, n+1, self:intToColor(n1) )
end
function Convert:popMat(n,t)
local input,nmax = self:getSubTable(n,t)
local i
local out = matrix()
for i=1,16 do
out[i] = self:colorToFloat( input[i] )
end
local next_n = n + nmax + 1
return out, next_n
end
-- {matrix}
function Convert:pushMatTable(matTable,t)
local n = #t -- record the position before the starting point of this data
local i
local j,m
for j=1,#matTable do
m = matTable[j]
for i=1,16 do
insert(t,self:floatToColor(m[i]))
end
end
local n1 = #t - n -- n1 is the number of data
insert(t, n+1, self:intToColor(n1) )
end
function Convert:popMatTable(n,t)
local input,nmax = self:getSubTable(n,t)
local i=1
local out = {}
while i<nmax do
local m = matrix()
for j=1,16 do
m[j] = self:colorToFloat( input[i+j-1] )
end
out[(i+15)/16] = m
i = i + 16
end
local next_n = n + nmax + 1
return out, next_n
end
--{vec2}
function Convert:pushVec2(verts,t)
local n = #t -- record the position before the starting point of this data
local i,v
for i=1,#verts do
v = verts[i]
insert(t,self:floatToColor(v.x))
insert(t,self:floatToColor(v.y))
end
local n1 = #t - n -- n1 is the number of data
insert(t, n+1, self:intToColor(n1) )
end
function Convert:popVec2(n,t)
local input,nmax = self:getSubTable(n,t)
local i=1
local out = {}
while i<nmax do
local v = vec2()
v.x = self:colorToFloat( input[i] )
v.y = self:colorToFloat( input[i+1] )
out[(i+1)/2] = v
i = i + 2
end
local next_n = n + nmax + 1
return out, next_n
end
--{vec3}
function Convert:pushVec3(vertices,t)
local n = #t -- record the position before the starting point of this data
local i,v
for i=1,#vertices do
v = vertices[i]
insert(t,self:floatToColor(v.x))
insert(t,self:floatToColor(v.y))
insert(t,self:floatToColor(v.z))
end
local n1 = #t - n -- n1 is the number of data
insert(t, n+1, self:intToColor(n1) )
end
function Convert:popVec3(n,t)
local input,nmax = self:getSubTable(n,t)
local i=1
local out = {}
while i<nmax do
local v = vec3()
v.x = self:colorToFloat( input[i] )
v.y = self:colorToFloat( input[i+1] )
v.z = self:colorToFloat( input[i+2] )
out[(i+2)/3] = v
i = i + 3
end
local next_n = n + nmax + 1
return out, next_n
end
-- {color}
function Convert:pushColors(colors,t)
local n = #t -- record the position before the starting point of this data
local i,v,r,g,b,a
for i=1,#colors do
v = colors[i]
insert(t,v)
end
local n1 = #t - n -- n1 is the number of data
insert(t, n+1, self:intToColor(n1) )
end
function Convert:popColors(n,t)
local input,nmax = self:getSubTable(n,t)
local i
local out = {}
for i=1,nmax do out[i] = input[i] end
local next_n = n + nmax + 1
return out, next_n
end
-- image
function Convert:pushImage(img,t)
local n = #t -- record the position before the starting point of this data
local w,h,x,y
w,h = img.width, img.height
insert(t,self:intToColor(w))
insert(t,self:intToColor(h))
for x=1,w do
for y=1,h do
insert(t,color(img:get(x,y)))
end
end
local n1 = #t - n -- n1 is the number of data
insert(t, n+1, self:intToColor(n1) )
end
function Convert:popImage(n,t)
local input,nmax = self:getSubTable(n,t)
local w,h,x,y
w = self:colorToInt(input[1]) --n+1
h = self:colorToInt(input[2])
local out = image(w,h)
local i = 3 -- n+3
for x=1,w do
for y=1,h do
out:set(x,y,input[i])
i = i + 1
end
end
local next_n = n + nmax + 1
return out, next_n
end
-- number
function Convert:pushNumber(x,t)
local n = #t -- record the position before the starting point of this data
insert(t,self:floatToColor(x))
local n1 = #t - n -- n1 is the number of data
insert(t, n+1, self:intToColor(n1) )
end
function Convert:popNumber(n,t)
local input,nmax = self:getSubTable(n,t)
local out = self:colorToFloat( input[1] )
local next_n = n + nmax + 1
return out, next_n
end
-- string
function Convert:pushString(txt,t,subCall)
local n = #t -- record the position before the starting point of this data
local t1,t2
if txt:len()>4 then
t1 = txt:sub(1,4)
t2 = txt:sub(5)
else
t1 = txt
end
insert(t,self:stringToColor(t1))
if t2 then self:pushString(t2,t,true) end
if not subCall then
local n1 = #t - n -- n1 is the number of data
insert(t, n+1, self:intToColor(n1) )
end
end
function Convert:popString(n,t)
local input,nmax = self:getSubTable(n,t)
local out = {}
local i
for i=1,nmax do out[i] = self:colorToString(input[i]) end
out = table.concat(out,"")
local next_n = n + nmax + 1
return out, next_n
end
-- get table part
function Convert:getSubTable(n,t)
local out = {}
local nmax = self:colorToInt( t[n] )
for i=1,nmax do out[i] = t[i+n] end
return out,nmax
end
-- **********************************************
-- basic function to convert to and from colors
-- **********************************************
local abs = math.abs
local log10 = math.log10
local pow = math.pow
-- type(v):"nil", "number", "string", "boolean", "table", "function", "thread", "userdata".
function Convert:type(x)
local txt = type(x)
function typeCompare(x,ref)
-- nb: returns an error if x or ref have no metatable!
local i = getmetatable(x).__index
local j = getmetatable(ref).__index
return (i==j)
end
if txt == "userdata" then
if typeCompare(x,vec2()) then txt ="vec2"
elseif typeCompare(x,vec3()) then txt ="vec3"
elseif typeCompare(x,color()) then txt ="color"
elseif typeCompare(x,image(1,1)) then txt ="image"
elseif typeCompare(x,matrix()) then txt ="matrix"
elseif typeCompare(x,mesh()) then txt ="mesh"
end
end
if txt == "table" then
txt = "{"..self:type(x[1]).."}"
end
return txt
end
function Convert:intToColor(dat)
-- abs value coded on 4 octets uint (r,g,b,a)
local r,g,b,a = 0,0,0,0
local x
-- chech no sign
x = abs(dat)
if x~=dat then error("only uint supported : "..dat) end
-- convert in octet basis
r = x % 256
x = floor(x/256)
g = x % 256
x = floor(x/256)
b = x % 256
x = floor(x/256)
a = x
if a>255 then error("this integer is too big to save : "..dat) end
return color(r,g,b,a)
end
function Convert:colorToInt(c)
local r,g,b,a = c.r, c.g, c.b, c.a
local i = r +256*(g + 256*(b +256*a))
return i
end
function Convert:floatToColor(dat)
-- abs value coded on 3 octets (r,g,b)
-- a is coding the power of 10, from -64 to +63
-- the sign is coded by 1 bit (+128) in a
-- accuracy limit: about less than 10/(256*256*256) relative error
local r,g,b,a = 0,0,0,0
local x,sgn,p,c
-- remove the sign and save it
x = abs(dat)
if x==dat then sgn = 0 else sgn = 128 end
-- get the exponent
if x==0 then p=0 else
p = log10(x)
p = floor(p)
end
if (p<-64) or (63<p) then -- overflow
-- in case of overflow clip the data
if p<-64 then p=-64 else p=63 end
r,g,b,a =255,255,255,127
else
-- convert to int
x = x / pow(10,p)/10 -- number x is now : 0.abcdefg with a from 1 to 9
x = floor( x *255 * 256 * 256 )
-- convert to octet basis
c = self:intToColor(x)
r,g,b,a = c.r, c.g, c.b, c.a
if a>0 then error("bug: a should be 0") end
end
-- a saves sign and exponent
a = (p + 64) + sgn
return color(r,g,b,a)
end
function Convert:colorToFloat(c)
local r,g,b,a = c.r, c.g, c.b, c.a
local sgn
if a >127 then sgn =-1 ; a=a-128 else sgn =1 end
local p = a - 64
local x = ((r/256 + g)/256 +b)/255 * pow(10,p) * 10 * sgn
return x
end
function Convert:stringToColor(t)
local r,g,b,a = 0,0,0,0
local l = t:len()
if l>0 then r = t:byte(1) end
if l>1 then g = t:byte(2) end
if l>2 then b = t:byte(3) end
if l>3 then a = t:byte(4) end
if l>4 then error("the text: "..t.." is too long (4 chars max).") end
return color(r,g,b,a)
end
function Convert:colorToString(c)
local r,g,b,a = c.r, c.g, c.b, c.a
local txt = ""
if a>0 then txt = string.char(r,g,b,a)
elseif b>0 then txt = string.char(r,g,b)
elseif g>0 then txt = string.char(r,g)
elseif r>0 then txt = string.char(r)
end
return txt
end
-- 0 conversion
-- unit test of variuos fonctions
function setup()
convert = Convert()
-- types
typeUnitTests()
-- integer
intUnitTests()
-- float
floatUnitTests()
-- string
stringUnitTests()
-- tables
myobj = ObjectClassForTest()
testPushString0()
testPushTag("name",myobj)
testPushTag("version",myobj)
img1 = testPushTag("texture",myobj.ms)
listTypes(myobj)
print("vertices : "..convert:type(myobj.ms.vertices))
print("texCoords : "..convert:type(myobj.ms.texCoords))
print("colors : "..convert:type(myobj.ms.colors))
testPushColors("colors",myobj.ms)
testPushVec3("vertices",myobj.ms)
testPushVec2("texCoords",myobj.ms)
testPushMatrixTable("mt",myobj)
testPushMatrix("m",myobj)
testPushMesh("ms",myobj)
testPushObject(myobj)
testSaveLoadImage(myobj)
testSaveLoad(myobj)
-- sprite()
end
function testSaveLoad(obj)
local debug = true
print(" ------------- ")
print(" ----- push -------- ")
convert:save(obj,"titi",debug)
print(" ----- pop -------- ")
local obj2 = {}
convert:load(obj2,"titi",debug)
end
function testSaveLoadImage(obj)
print(" ------------- ")
print("Have the images been generated?")
convert:saveImage("titi",obj.ms.texture)
img2 = readImage("Documents:titi")
print(img2)
img3 = convert:readImage("titi")
print(img3)
end
function testPushObject(obj)
print(" ------------- ")
print(" push and pop object")
local debug=true
local img = convert:pushObject01(obj,debug)
print("result image:"..tostring(img))
local obj2 = convert:popObject01(img,debug)
end
function listTypes(a)
print(" ------------- ")
for t,v in pairs(a) do
print(t.." : "..convert:type(v))
end
end
function typeUnitTests()
local t
print(" ------------- ")
print("Type unit tests")
t = 5
print("this data: \n",tostring(t),"\n is a : "..convert:type(t))
t = vec2(1,2)
print("this data: \n",tostring(t),"\n is a : "..convert:type(t))
t = vec3(1,2,3)
print("this data: \n",tostring(t),"\n is a : "..convert:type(t))
t = color(146, 45, 45, 255)
print("this data: \n",tostring(t),"\n is a : "..convert:type(t))
t = matrix()
print("this data: \n",tostring(t),"\n is a : "..convert:type(t))
t = image(10,10)
print("this data: \n",tostring(t),"\n is a : "..convert:type(t))
t = mesh()
print("this data: \n",tostring(t),"\n is a : "..convert:type(t))
end
local clock = os.clock
local floor = math.floor
function testPushMesh(tag,obj)
print(" ------------- ")
print("object.mesh to color table, and back")
local t,p = {},{}
print(tostring(obj[tag]))
local i,v,ob
ob = obj[tag]
i="vertices" ; print(i.." : "..tostring(ob[i]))
i="texCoords" ; print(i.." : "..tostring(ob[i]))
i="texture" ; print(i.." : "..tostring(ob[i]))
i="colors" ; print(i.." : "..tostring(ob[i]))
local t0 = clock()
convert:pushTag(tag,obj,t)
local t1 = clock()
print("tag => table "..floor((t1-t0)*1000).." ms")
print("intermediate table has "..#t.." elements")
local t2 = clock()
convert:popTag(1,t,p)
local t3 = clock()
print("table => tag "..floor((t3-t2)*1000).." ms")
print(tostring(p[tag]))
ob = p[tag]
i="vertices" ; print(i.." : "..tostring(ob[i]))
i="texCoords" ; print(i.." : "..tostring(ob[i]))
i="texture" ; print(i.." : "..tostring(ob[i]))
i="colors" ; print(i.." : "..tostring(ob[i]))
end
function testPushMatrix(tag,obj)
print(" ------------- ")
print("object.matrix to color table, and back")
local t,p = {},{}
print(tostring(obj[tag]))
local i,v,ob
convert:pushTag(tag,obj,t)
print("intermediate table has "..#t.." elements")
convert:popTag(1,t,p)
print(tostring(p[tag]))
end
function testPushMatrixTable(tag,obj)
print(" ------------- ")
print("object.{matrix} to color table, and back")
local t,p = {},{}
print(obj[tag])
print("initial table has "..#obj[tag].." elements")
local i,v,ob
ob = obj[tag]
for i,v in ipairs(ob) do print(tostring(ob[i])) end
convert:pushTag(tag,obj,t)
print("intermediate table has "..#t.." elements")
convert:popTag(1,t,p)
print("final table has "..#p[tag].." elements")
ob = p[tag]
for i,v in ipairs(ob) do print(tostring(ob[i])) end
end
function testPushVec2(tag,obj)
print(" ------------- ")
print("object.{Vec2} to color table, and back")
local t,p = {},{}
print(obj[tag])
print("initial table has "..#obj[tag].." elements")
local i,v,ob
ob = obj[tag]
for i,v in ipairs(ob) do print(tostring(ob[i])) end
convert:pushTag(tag,obj,t)
print("intermediate table has "..#t.." elements")
convert:popTag(1,t,p)
print("final table has "..#p[tag].." elements")
ob = p[tag]
for i,v in ipairs(ob) do print(tostring(ob[i])) end
end
function testPushVec3(tag,obj)
print(" ------------- ")
print("object.{Vec3} to color table, and back")
local t,p = {},{}
print(obj[tag])
print("initial table has "..#obj[tag].." elements")
local i,v,ob
ob = obj[tag]
for i,v in ipairs(ob) do print(tostring(ob[i])) end
convert:pushTag(tag,obj,t)
print("intermediate table has "..#t.." elements")
convert:popTag(1,t,p)
print("final table has "..#p[tag].." elements")
ob = p[tag]
for i,v in ipairs(ob) do print(tostring(ob[i])) end
end
function testPushColors(tag,obj)
print(" ------------- ")
print("object.{color} to color table, and back")
local t,p = {},{}
print(obj[tag])
print("initial table has "..#obj[tag].." elements")
local i,v,ob
ob = obj[tag]
for i,v in ipairs(ob) do print(tostring(ob[i])) end
convert:pushTag(tag,obj,t)
print("intermediate table has "..#t.." elements")
convert:popTag(1,t,p)
print("final table has "..#p[tag].." elements")
ob = p[tag]
for i,v in ipairs(ob) do print(tostring(ob[i])) end
end
function testPushTag(tag,obj)
local t = {}
print(" ------------- ")
print("tag <=> table")
print(tag.." : "..tostring(obj[tag]))
local t0 = clock()
convert:pushTag(tag,obj,t)
local t1 = clock()
print("tag => table "..floor((t1-t0)*1000).." ms")
local p = {}
local t2 = clock()
local tag = convert:popTag(1,t,p)
local t3 = clock()
print("table => tag "..floor((t3-t2)*1000).." ms")
print(tag.." : "..tostring(p[tag]))
return p[tag]
end
function testPushString0()
print(" ------------- ")
local str1 ="tag=name"
local str2 ="type=string"
local str3 ="hello world"
print(str1)
print(str2)
print(str3)
local n,t = 1,{}
convert:pushString(str1,t)
convert:pushString(str2,t)
convert:pushString(str3,t)
print("intermediate table has "..#t.." elements")
local str
str,n = convert:popString(n,t) print(str)
str,n = convert:popString(n,t) print(str)
str,n = convert:popString(n,t) print(str)
end
function stringUnitTests()
print(" ------------- ")
print("string unit test")
testString()
testString("")
testString("h")
testString("he")
testString("hel")
testString("hell")
testString("=")
testError(testString,"[{()}]")
end
function testError(f,arg)
local status,err = pcall(f,arg)
if status==false
then print("ok : "..tostring(arg).." has generated an error : "..err)
else print("FALSE : this should generate an error : "..tostring(arg))
end
end
function testString(i)
local c,t,txt
if i then
c=convert:stringToColor(i)
t=convert:colorToString(c)
if (i==t) then txt="ok" else txt="FALSE" end
print(txt.." : '"..i.."'".." = "..tostring(c).." = ".."'"..t.."'")
else
print("")
print("string to color and back to string")
end
end
function intUnitTests()
print(" ------------- ")
print("test of conversion functions")
print("")
print("intToColor")
testUInt(1)
testUInt(1000)
testUInt(1000000)
testUInt(100000000)
testError(testUInt,-1)
testError(testUInt,256*256*256*256+10)
end
function testUInt(i)
local c,i1,txt
c=convert:intToColor(i)
i1=convert:colorToInt(c)
if (i==i1) then txt="ok" else txt="FALSE" end
print(txt.." : "..i.." = "..tostring(c).." = "..i1)
end
function floatUnitTests()
print(" ------------- ")
print("Float unit tests")
test2()
test2(0)
test2(2)
test2(1003)
test2(1000003)
test2(-19)
test2(-8000)
test2(-1000003)
test2(0.2)
test2(0.00003)
test2(0.00000000003)
test2(-0.5)
test2(-0.00003)
test2(-0.000008888888)
test2(math.random())
test2(math.pi)
test2(math.pi*math.pow(10,22))
test2(-math.pi*math.pow(10,22))
end
function test2(i)
local precision = 10/256/256/255
if i then
local c,i1,t,txt
c=convert:floatToColor(i)
i1=convert:colorToFloat(c)
local err = (i-i1)/i
if math.abs(err)<precision then txt="ok" else txt="FALSE" end
print(txt.." : "..i.." = "..tostring(c).." = "..i1)
else
print("")
print("floatToColor and back to float")
print("precision required : "..precision)
end
end
-- This function gets called once every frame
function draw()
-- This sets a dark background color
background(40, 40, 50)
-- This sets the line thickness
strokeWidth(5)
-- Do your drawing here
sprite( myobj.ms.texture,WIDTH/4,HEIGHT/2)
sprite(img1,WIDTH/2,HEIGHT/2)
sprite(img2,WIDTH/2,HEIGHT/4*3)
sprite(img3,WIDTH/4,HEIGHT/4*3)
end
ObjectClassForTest = class()
function ObjectClassForTest:init(x)
self.name ="object_name" -- a string
self.version = 1 -- version of couple: object + save method
self.m = matrix() -- position of the object copies
self.mt = {matrix(),matrix():translate(100,0,0)} -- position of the object copies
self.sv = { {1},{2},{3} } -- summit vectors: for each summit a table of vertice indexes
self.sf = { {1},{1},{1} } -- summit faces: for each summit a table of face indexes
self.fs = { {1,2,3} } -- face summits: each face has 3 summit index in a table
-- nota: if 1,2,3 is a face, 12:cross(13) is oriented to the outside of the object
local z = vec3(0,0,1)
-- normals: at least one of those is needed to draw shadows:
self.sn = { z, z, z} -- summit normals: for each summit a vec3 (optionnal)
self.fn = {z} -- face normals: for each face a vec3 (optionnal)
self.vn = { z, z, z} -- vertices normals: for each vertice a vec3 (optionnal)
self.ms = mesh() -- mesh
-- vertices: a table of vec3, by group of 3, corresponding to faces index*3+0,1,2
self.ms.vertices = {vec3(-50,-50,0),vec3(50,-50,0),vec3(-50,50,0)}
-- texture coords: a table of vec2, by group of 3, corresponding to faces index*3+0,1,2
-- self.ms.texCoords = {vec2(0,0),vec2(1,0),vec2(0,1)}
self.ms.texCoords = {vec2(3/32,3/32),vec2(29/32,3/32),vec2(3/32,29/32)}
local img = readImage("Documents:mechanics")
--setContext(img) background(255, 255, 255, 255) setContext()
self.ms.texture = img
-- colors: a table of colors, by group of 3, corresponding to faces index*3+0,1,2
-- self.ms.colors = {color(255, 0, 0, 255),color(0, 255, 2, 255),color(0, 19, 255, 255)}
local white = color(255, 255,255, 255)
self.ms.colors = {white,white,white}
self.img = img -- an image for various usages
self.icon = image(101,101) -- an image used to save a small view of the object
self.visible = true
-- functions to convert object <=> image
self.converter = Convert()
end
function ObjectClassForTest:draw()
-- Codea does not automatically call this method
end
function ObjectClassForTest:touched(touch)
-- Codea does not automatically call this method
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment