Created
December 9, 2013 11:52
-
-
Save dermotbalson/7871147 to your computer and use it in GitHub Desktop.
3D viewer v1.0
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 | |
--3D Model viewer | |
function setup() | |
--saveLocalData("Shuttle.mtl",nil) | |
loadState=2 -- 0=failed, 1=downloading, 2=ready for next one, 3=all loaded 4=running | |
parameter.integer("Choose",1,#Models,3) | |
parameter.action("Load",OBJ.ShowModel) | |
parameter.integer("Zoom",1,300,50) | |
parameter.boolean("AutoRotate",true) | |
parameter.integer("X",-180,180,0) | |
parameter.integer("Y",-180,180,0) | |
parameter.integer("Z",-180,180,0) | |
parameter.action("DeleteStoredData",DeleteData) | |
parameter.integer("FPS",0,60,60) | |
--rotate shuttle in all three directions | |
rot=vec3(0,0,0) | |
tween( 15, rot, { x = 360 }, { easing = tween.easing.linear, loop = tween.loop.pingpong } ) | |
tween( 27, rot, { y = 360 }, { easing = tween.easing.linear, loop = tween.loop.pingpong } ) | |
tween( 35, rot, { z = 360 }, { easing = tween.easing.linear, loop = tween.loop.pingpong } ) | |
output.clear() | |
for i=1,#Models do print(i,Models[i].name) end | |
end | |
function LoadModel(meshes) | |
m=meshes | |
for i=1,#m do --add lighting to each mesh | |
m[i]:setColors(color(255)) | |
m[i].shader=shader(diffuseShader.vertexShader,diffuseShader.fragmentShader) | |
local ca,cd,cs | |
if m[i].settings then | |
ca = m[i].settings.Ka or color(255) | |
cd = m[i].settings.Kd or color(255) | |
cs = m[i].settings.Ks or color(255) | |
sp = m[i].settings.Ns or 32 | |
if m[i].settings.map then m[i].texture="Documents:z3D"..m[i].settings.map end | |
else ca,cd=color(255),color(255) | |
end | |
local a=0.2 | |
m[i].shader.ambientColor=color(ca.r*a,ca.g*a,ca.b*a,255) | |
local d=1 | |
m[i].shader.directColor=color(cd.r*d,cd.g*d,cd.b*d) | |
m[i].shader.directDirection=vec4(-2,1,4,0):normalize() | |
m[i].shader.specularColor=cs | |
m[i].shader.specularPower=sp | |
m[i].shader.shine=1 | |
if m[i].hasNormals~=true then | |
m[i].normals=CalculateAverageNormals(m[i].vertices,0) | |
end | |
m[i].shader.reflect=1 | |
if m[i].texture then m[i].shader.hasTexture=true else m[i].shader.hasTexture=false end | |
end | |
output.clear() | |
for i=1,#Models do print(i,Models[i].name) end | |
end | |
function DeleteData() | |
saveLocalData(Models[Choose].name .. ".mtl",nil) | |
saveLocalData(Models[Choose].name .. ".obj",nil) | |
--print("Deleting "..Models[Choose].name .. ".mtl") | |
--print("Deleting "..Models[Choose].name .. ".obj") | |
if Models[Choose].images then | |
for i=2,#Models[Choose].images,2 do | |
--print("Deleting "..Models[Choose].images[i]) | |
saveImage("Documents:z3Dspstob_1",nil) | |
end | |
end | |
end | |
function draw() | |
background(116, 173, 182, 255) | |
FPS=FPS*0.9+0.1/DeltaTime | |
if dataStatus~='Ready' then return end | |
if touchPos then | |
if touchImg==nil then | |
touchImg=image(WIDTH,HEIGHT) | |
setContext(touchImg) | |
else | |
local a,b=touchImg:get(touchPos.x,touchPos.y) | |
--print("Vertex="..a*256+b) | |
touchPos=nil | |
touchImg=nil | |
end | |
end | |
perspective() | |
camera(0,0,Zoom,0,0,-Zoom) | |
pushMatrix() | |
if AutoRotate then | |
rotate(rot.x,1,0,0) | |
rotate(rot.y,0,1,0) | |
rotate(rot.z,0,0,1) | |
else | |
rotate(X,1,0,0) | |
rotate(Y,0,1,0) | |
rotate(Z,0,0,1) | |
end | |
if m then | |
for i=1,#m do | |
if touchPos then | |
m[i].shader.useIndex=true | |
m[i].colors=m[i].C2 | |
else | |
m[i].shader.useIndex=false | |
--m[i]:setColors(m[i].C1) | |
end | |
m[i].shader.mModel=modelMatrix() --part of lighting | |
m[i].shader.eyePosition=vec3(0,0,Zoom) | |
m[i]:draw() | |
end | |
end | |
popMatrix() | |
if touchPos then setContext() end | |
end | |
function GetColor(n) | |
local b=math.fmod(n,256) | |
local a=(n-b)/255 | |
return color(a,b,0) | |
end | |
function touched(t) | |
if t.state==BEGAN then | |
touchPos=vec2(t.x,t.y) | |
end | |
end | |
function CalculateNormals(vertices) | |
--this assumes flat surfaces, and hard edges between triangles | |
local norm = {} | |
for i=1, #vertices,3 do --calculate normal for each set of 3 vertices | |
local n = ((vertices[i+1] - vertices[i]):cross(vertices[i+2] - vertices[i])):normalize() | |
norm[i] = n --then apply it to all 3 | |
norm[i+1] = n | |
norm[i+2] = n | |
end | |
return norm | |
end | |
function CalculateAverageNormals(vertices,f) | |
--average normals at each vertex | |
--first get a list of unique vertices, concatenate the x,y,z values as a key | |
local norm,unique= {},{} | |
for i=1, #vertices do | |
unique[vertices[i].x ..vertices[i].y..vertices[i].z]=vec3(0,0,0) | |
end | |
--calculate normals, add them up for each vertex and keep count | |
for i=1, #vertices,3 do --calculate normal for each set of 3 vertices | |
local n = (vertices[i+1] - vertices[i]):cross(vertices[i+2] - vertices[i]) | |
for j=0,2 do | |
local v=vertices[i+j].x ..vertices[i+j].y..vertices[i+j].z | |
unique[v]=unique[v]+n | |
end | |
end | |
--calculate average for each unique vertex | |
for i=1,#unique do | |
unique[i] = unique[i]:normalize() | |
end | |
--now apply averages to list of vertices | |
for i=1, #vertices,3 do --calculate average | |
local n = (vertices[i+1] - vertices[i]):cross(vertices[i+2] - vertices[i]) | |
for j=0,2 do | |
norm[i+j] = unique[vertices[i+j].x ..vertices[i+j].y..vertices[i+j].z] | |
end | |
end | |
return norm | |
end | |
--# OBJ | |
--OBJ library | |
OBJ={} | |
function OBJ.SetupModel() | |
local s=readLocalData(OBJ.model..".mtl") | |
if s then | |
OBJ.mtl={} | |
local mname | |
for line in s:gmatch("[^\r\n]+") do | |
line=OBJ.trim(line) | |
if string.find(line,"newmtl") then | |
mname=OBJ.GetValue(line) | |
OBJ.mtl[mname]={} | |
--print(mname) | |
else | |
local code=string.sub(line,1,2) | |
if code=="Ka" then --ambient | |
OBJ.mtl[mname].Ka=OBJ.GetColor(line) | |
--print(mname,"Ka",OBJ.mtl[mname].Ka[1],OBJ.mtl[mname].Ka[2],OBJ.mtl[mname].Ka[3]) | |
elseif code=="Kd" then --diffuse | |
OBJ.mtl[mname].Kd=OBJ.GetColor(line) | |
--print(mname,"Kd",OBJ.mtl[mname].Kd[1],OBJ.mtl[mname].Kd[2],OBJ.mtl[mname].Kd[3]) | |
elseif code=="Ks" then --specular | |
OBJ.mtl[mname].Ks=OBJ.GetColor(line) | |
--print(mname,"Ks",OBJ.mtl[mname].Ks[1],OBJ.mtl[mname].Ks[2],OBJ.mtl[mname].Ks[3]) | |
elseif code=="Ns" then --specular exponent | |
OBJ.mtl[mname].Ns=OBJ.GetValue(line) | |
--print(mname,"Ns",OBJ.mtl[mname].Ns) | |
elseif code=="ill" then --illumination code | |
OBJ.mtl[mname].illum=OBJ.GetValue(line) | |
--print(mname,"illum",OBJ.mtl[mname].illum) | |
elseif code=="ma" then --texture map name | |
local u=OBJ.split(OBJ.GetValue(line),"\\") | |
--print(line,"=",string.sub(u[#u],1,string.find(u[#u],".\")-1)) | |
OBJ.mtl[mname].map=string.sub(u[#u],1,string.find(u[#u],"%.")-1) | |
--print(mname,OBJ.mtl[mname].map) | |
end | |
end | |
end | |
else | |
print("ERROR:"..OBJ.model..".mtl could not be loaded") | |
return | |
end | |
local s=readLocalData(OBJ.model..".obj") | |
if s then | |
--read in groups of data into separate meshes | |
OBJ.m={} | |
local p, v, tx, t, np, n={},{},{},{},{},{} | |
local mname | |
for line in s:gmatch("[^\r\n]+") do | |
line=OBJ.trim(line) | |
local code=string.sub(line,1,2) | |
--look for material settings, a separate mesh is used for each | |
if string.find(line,"usemtl") then | |
if mname then | |
local m=mesh() | |
m.vertices=v | |
if #t>0 then m.texCoords=t end | |
if #n>0 then m.normals=n end | |
m.settings=OBJ.mtl[mname] | |
OBJ.m[#OBJ.m+1]=m | |
--print(#p) | |
end | |
mname=OBJ.GetValue(line) | |
v,t,n={},{},{} | |
--print(mname) | |
end | |
if code=="v " then --point position | |
p[#p+1]=OBJ.GetVec3(line) | |
elseif code=="vn" then --point normal | |
np[#np+1]=OBJ.GetVec3(line) | |
elseif code=="vt" then --texture co-ord | |
tx[#tx+1]=OBJ.GetVec2(line) | |
elseif code=="f " then --vertex | |
local pts,ptex,pnorm=OBJ.GetList(line) | |
if #pts==3 then | |
for i=1,3 do v[#v+1]=p[tonumber(pts[i])] end | |
if ptex then for i=1,3 do t[#t+1]=tx[tonumber(ptex[i])] end end | |
if pnorm then for i=1,3 do n[#n+1]=np[tonumber(pnorm[i])] end end | |
elseif #pts==4 then | |
for i=1,3 do v[#v+1]=p[tonumber(pts[i])] end | |
if ptex then for i=1,3 do t[#t+1]=tx[tonumber(ptex[i])] end end | |
if pnorm then for i=1,3 do n[#n+1]=np[tonumber(pnorm[i])] end end | |
v[#v+1]=p[tonumber(pts[3])] | |
if ptex then t[#t+1]=tx[tonumber(ptex[3])] end | |
if pnorm then n[#n+1]=np[tonumber(pnorm[3])] end | |
v[#v+1]=p[tonumber(pts[4])] | |
if ptex then t[#t+1]=tx[tonumber(ptex[4])] end | |
if pnorm then n[#n+1]=np[tonumber(pnorm[4])] end | |
v[#v+1]=p[tonumber(pts[1])] | |
if ptex then t[#t+1]=tx[tonumber(ptex[1])] end | |
if pnorm then n[#n+1]=np[tonumber(pnorm[1])] end | |
elseif #pts>4 then | |
local cx,cy,cz=0,0,0 | |
local ttx,tty=0,0 | |
local nx,ny,nz=0,0,0 | |
for i=1,#pts do | |
local u=p[tonumber(pts[i])] cx,cy,cz=cx+u.x,cy+u.y,cz+u.z | |
if ptex then local u=tx[tonumber(ptex[i])] ttx,tty=ttx+u.x,tty+u.y end | |
--if pnorm then local u=p[tonumber(pnorm[i])] nx,ny,nz=nx+u.x,ny+u.y,nz+u.z end | |
end | |
local cp=vec3(cx/#pts,cy/#pts,cz/#pts) | |
if ptex then ct=vec2(ttx/#pts,tty/#pts) end | |
--if pnorm then cn=vec3(nx/#pts,ny/#pts,nz/#pts):normalize() end | |
local j | |
for i=1,#pts do | |
if i<#pts then j=i+1 else j=1 end | |
v[#v+1]=p[tonumber(pts[i])] | |
if ptex then t[#t+1]=tx[tonumber(ptex[i])] end | |
--if pnorm then n[#n+1]=np[tonumber(pnorm[i])] end | |
v[#v+1]=p[tonumber(pts[j])] | |
if ptex then t[#t+1]=tx[tonumber(ptex[j])] end | |
--if pnorm then n[#n+1]=np[tonumber(pnorm[j])] end | |
v[#v+1]=cp | |
if ptex then t[#t+1]=ct end | |
--if pnorm then n[#n+1]=np[tonumber(cn)] end | |
end | |
end | |
end | |
end | |
local m=mesh() | |
m.vertices=v | |
if #t>0 then m.texCoords=t end | |
if #n>0 then m.normals=n end | |
m.settings=OBJ.mtl[mname] | |
OBJ.m[#OBJ.m+1]=m | |
--for i=1,#OBJ.m do print(i,#OBJ.m[i].texCoords) end | |
return OBJ.m | |
else | |
print("ERROR:"..OBJ.model..".obj could not be loaded") | |
return | |
end | |
end | |
function OBJ.GetColor(s) | |
local s1=string.find(s," ") | |
local s2=string.find(s," ",s1+1) | |
local s3=string.find(s," ",s2+1) | |
return color(string.sub(s,s1+1,s2-1)*255,string.sub(s,s2+1,s3-1)*255,string.sub(s,s3+1,string.len(s))*255) | |
end | |
function OBJ.GetVec3(s) | |
local s1=string.find(s," ") | |
local s2=string.find(s," ",s1+1) | |
local s3=string.find(s," ",s2+1) | |
return vec3(math.floor(string.sub(s,s1+1,s2-1)*100)/100, | |
math.floor(string.sub(s,s2+1,s3-1)*100)/100, | |
math.floor(string.sub(s,s3+1,string.len(s))*100)/100) | |
end | |
function OBJ.GetVec2(s) | |
local s1=string.find(s," ") | |
local s2=string.find(s," ",s1+1) | |
return vec2(math.floor(string.sub(s,s1+1,s2-1)*100)/100, | |
math.floor(string.sub(s,s2+1,string.len(s))*100)/100) | |
end | |
function OBJ.GetValue(s) | |
return string.sub(s,string.find(s," ")+1,string.len(s)) | |
end | |
function OBJ.trim(s) | |
while string.find(s," ") do s = string.gsub(s," "," ") end | |
return s:match'^()%s*$' and '' or s:match'^%s*(.*%S)' | |
end | |
function OBJ.split(s,sep) | |
sep=sep or "/" | |
local p={} | |
local pattern = string.format("([^%s]+)", sep) | |
string.gsub(s,pattern, function(c) p[#p+1] = c end) | |
return p | |
end | |
function OBJ.GetList(s) | |
local p,t,n={},{},{} | |
--for word in s:gmatch("%w+") do table.insert(p, word) end | |
p=OBJ.split(s," ") | |
table.remove(p,1) | |
for i=1,#p do | |
local a=OBJ.split(p[i]) | |
if #a==1 then | |
p[i]=a[1] | |
elseif #a==2 then | |
p[i]=a[1] | |
t[i]=a[2] | |
elseif #a==3 then | |
p[i]=a[1] | |
t[i]=a[2] | |
n[i]=a[3] | |
end | |
end | |
return p,t,n | |
end | |
function setup0() | |
s="f 1000/2000 3000/4000 5000/6000" | |
p,t=OBJ.GetList(s) | |
for i=1,#p do print(i,p[i],t[i]) end | |
end | |
function draw0() end | |
--# Assets | |
--Assets | |
Models={ | |
{name="AllianceStarFighter", | |
mtl="https://gist.github.com/dermotbalson/7853224/raw/4531e3e1ef1e564dd38835926006b8a677b24c65/gistfile1.txt", | |
obj="https://gist.github.com/dermotbalson/7853222/raw/bc75e086a6fa11cc48c62ef4c3a7efc452529861/gistfile1.txt"}, | |
{name="Lunar_lander", | |
mtl="https://gist.github.com/dermotbalson/7854557/raw/a6a2e2dd687650c5b93c166e0c3ddf0e5df1dd4d/gistfile1.txt", | |
obj="https://gist.github.com/dermotbalson/7854555/raw/0f1dffb2263814cf47145418c3af41d872628576/gistfile1.txt"}, | |
{name="Me262", | |
mtl="https://gist.github.com/dermotbalson/7858260/raw/78dd90b5c6760b0a28df49ab9354091df8b34bef/gistfile1.txt", | |
obj="https://gist.github.com/dermotbalson/7858284/raw/b5b4acea32f09a6a9583088a1b307a9abdd01ae0/gistfile1.txt", | |
images={"http://i1303.photobucket.com/albums/ag142/ignatz_mouse/3D%20-%20Me262/", | |
"Material__2noCulling","Material__2noCulling_zps9ac9abf8.jpg", | |
"fusR2noCulling","fusR2noCulling_zps815a3aa9.jpg", | |
"fusR1noCulling","3D%20-%20Me262/fusR1noCulling_zps2307cad9.jpg", | |
"fusL1noCulling","3D%20-%20Me262/fusL1noCulling_zpsb2ec3384.jpg", | |
"engine_1noCulling","engine1noCulling_zpsc9e864fb.jpg", | |
"_2_1noCulling","_2_1noCulling_zps3af25934.jpg", | |
"fuselage1noCulling","fuselage1noCulling_zps5ec01367.jpg", | |
"elevlowL1_1noCulling","elevlowL1_1noCulling_zps92e9007f.jpg", | |
"elevlowR1noCulling","elevlowR1noCulling_zpsf5d3b587.jpg", | |
"engine_1noCulling","engine_1noCulling_zps84731447.jpg", | |
"_22_-_Default1noCulling","_22_-_Default1noCulling_zpsc34b8ed4.jpg", | |
"_2noCulling","_2noCulling_zpsdb6ae3da.jpg", | |
"_20_-_Default1noCulling","_20_-_Default1noCulling_zpsab9ada71.jpg", | |
"wgtopR1noCulling","wgtopR1noCulling_zps01fcba8b.jpg", | |
"Material__4noCulling","Material__4noCulling_zps57a72fa9.jpg", | |
"_1noCulling","_1noCulling_zps8d87449d.jpg", | |
"shield2noCulling","shield2noCulling_zpsd7ab3209.jpg", | |
"Material__1noCulling","Material__1noCulling_zpseb4845ed.jpg", | |
"shield1noCulling","shield1noCulling_zpsaa6f4423.jpg", | |
"Material__3noCulling","Material__3noCulling_zps4422f8d9.jpg"}}, | |
{name="Me262a", | |
obj="https://gist.github.com/dermotbalson/7866473/raw/57750a8a7a2763db3cb3871eff329a3380a41719/gistfile1.txt", | |
mtl="https://gist.github.com/dermotbalson/7866500/raw/204a07273c5e1eba1921b0d8dd050d598ae515fd/gistfile1.txt", | |
images={"http://i1303.photobucket.com/albums/ag142/ignatz_mouse/3D%20-%20Me262/", | |
"Me262Texture","Me262Texture_zps9a5c6ab4.jpg"}}, | |
{name="TIE", | |
mtl="https://gist.github.com/dermotbalson/7867711/raw/5bd1d273eb76f2ab0521019a8bf14f62dd35eabe/gistfile1.txt", | |
obj="https://gist.github.com/dermotbalson/7867714/raw/568570cb2bcc9ccc325f933f6e72609e92f80e8d/gistfile1.txt", | |
images={"http://i1303.photobucket.com/albums/ag142/ignatz_mouse/TIE2/", | |
"White_p0","White_p0_zpse833d35d.jpg", | |
"Pottery_clay","Pottery_clay_zps0dd8067f.jpg", | |
"Flat_white","Flat_white_zps90fee47d.jpg", | |
"Metallic_Varnish","Metallic_Varnish_zps9d47ede3.jpg", | |
"GRAY","GRAY_zps3b6c9a13.jpg", | |
"Pottery","Pottery__zpsf04e3b44.jpg", | |
"Flat_whi","Flat_whi_zps3db708fa.jpg", | |
"GREY_DARK","GREY_DARK_zps10890cbe.jpg", | |
"Metallic","Metallic_zps3f042630.jpg", | |
"GREY_DAR","GREY_DAR_zps93b978ef.jpg", | |
"Blue_glass","Blue_glass_zps3df479ac.jpg", | |
"Blue_gla","Blue_gla_zps85ce7ffa.jpg", | |
"BLAST_RED1","BLAST_RED1_zps955b974e.jpg", | |
"BLAST_R1","BLAST_R1_zpse6832a58.jpg", | |
"BLAST_RED0","BLAST_RED0_zpsdcb29c70.jpg", | |
"A_TIE_WI","A_TIE_WI_zps98da0a2f.jpg", | |
"White_porcelain3","White_porcelain3_zpsb19c4e77.jpg", | |
"A_TIE_WINDOW","A_TIE_WINDOW_zpscf0b2fc1.jpg", | |
"BLAST_R0","BLAST_R0_zpsdc173ba1.jpg", | |
"White_porcelain2","White_porcelain2_zps8380f151.jpg", | |
"White_p2","White_p2_zps14f2790e.jpg", | |
"White_p3","White_p3_zps05b2dde8.jpg", | |
"White_porcelain1","White_porcelain1_zpsd73396c8.jpg", | |
"White_porcelain0","White_porcelain0_zps839c6206.jpg", | |
"White_p1","White_p1_zps59e0fa3c.jpg", | |
"White_p0","White_p0_zpse833d35d.jpg"}}, | |
{name="Shuttle", | |
mtl="https://gist.github.com/dermotbalson/7868340/raw/8d9daf6171c47040deaa1aa8c8315bb8bec0d95e/gistfile1.txt", | |
obj="https://gist.github.com/dermotbalson/7868345/raw/e5c3c9b66dc6ae179ad797b8cc833f93939351da/gistfile1.txt", | |
images={"http://i1303.photobucket.com/albums/ag142/ignatz_mouse/Shuttle5/", | |
"spstob_1","spstob_1_zpsb14b8e49.jpg", | |
"spstob_2","spstob_2_zps60610a11.jpg", | |
"spstob_4","spstob_4_zps95834fee.jpg", | |
"spstob_e","spstob_e_zpsfdb1dd94.jpg", | |
"spstob_3","spstob_3_zps5b08c82c.jpg"}} | |
} | |
--# AssetLoader | |
--Asset loader | |
function OBJ.ShowModel() | |
OBJ.m=Choose | |
OBJ.model=Models[OBJ.m].name | |
OBJ.assetTable={} | |
OBJ.LoadModel() | |
end | |
function OBJ.LoadModel() | |
output.clear() | |
--pass through Codea name of file and internet url | |
--if not in Codea, will be downloaded and saved | |
OBJ.LoadAsset(OBJ.model..".mtl",Models[OBJ.m].mtl) | |
OBJ.LoadAsset(OBJ.model..".obj",Models[OBJ.m].obj) | |
if Models[OBJ.m].images then | |
local path=Models[OBJ.m].images[1] | |
for i=2,#Models[OBJ.m].images,2 do | |
OBJ.LoadAsset(Models[OBJ.m].images[i],path..Models[OBJ.m].images[i+1]) | |
end | |
--else print("No images") | |
end | |
if #OBJ.assetTable==0 then | |
dataStatus='Ready' --tells draw it's ok to draw the scene | |
local m= OBJ.SetupModel() | |
LoadModel(m) | |
end | |
end | |
--downloads assets one by one | |
function OBJ.LoadAsset(fileName,url) | |
if OBJ.IsObjFile(fileName) then | |
local i=readLocalData(fileName) | |
if i~=nil then return i end | |
else | |
local i=readImage("Documents:z3D"..fileName) | |
if i then return i end | |
end | |
--print(fileName.." not found") | |
--not found, we need to download, add to queue (ie table) | |
OBJ.assetTable[#OBJ.assetTable+1]={name=fileName,url=url} | |
print('Queueing',fileName) | |
dataStatus='Loading' | |
--if the first one, go ahead and download | |
if #OBJ.assetTable==1 then | |
http.request(OBJ.assetTable[1].url,OBJ.AssetDownloaded) | |
print('loading',OBJ.assetTable[1].name) | |
end | |
end | |
--saves downloaded images | |
function OBJ.AssetDownloaded(data) | |
--print(OBJ.assetTable[1].name,'loaded') | |
if OBJ.IsObjFile(OBJ.assetTable[1].name) then | |
saveLocalData(OBJ.assetTable[1].name,data) --save | |
local i=readLocalData(OBJ.assetTable[1].name) | |
if i~=data then print("ERROR in saving "..OBJ.assetTable[1].name) else | |
print("Saved"..OBJ.assetTable[1].name) end | |
else | |
saveImage("Documents:z3D"..OBJ.assetTable[1].name,data) --save | |
print("Saved "..OBJ.assetTable[1].name) | |
end | |
table.remove(OBJ.assetTable,1) | |
--load next one if we have any more to do | |
if #OBJ.assetTable>0 then | |
http.request(OBJ.assetTable[1].url,OBJ.AssetDownloaded) | |
print('loading',OBJ.assetTable[1].name) | |
else | |
OBJ.LoadModel() | |
end | |
end | |
function OBJ.IsObjFile(f) | |
local ff=string.upper(f) | |
if string.find(ff,".OBJ") or string.find(ff,".MTL") then return true else return false end | |
end | |
--# Shader | |
--# Shader2 | |
diffuseShader={ | |
vertexShader=[[ | |
uniform mat4 modelViewProjection; | |
uniform mat4 mModel; | |
uniform vec4 directColor; | |
uniform vec4 directDirection; | |
attribute vec4 position; | |
attribute vec4 color; | |
attribute vec2 texCoord; | |
attribute vec3 normal; | |
varying lowp vec4 vColor; | |
varying highp vec2 vTexCoord; | |
varying lowp vec4 vPosition; | |
varying lowp vec4 vNormal; | |
varying vec4 vDirectDiffuse; | |
void main() | |
{ | |
vColor = color; | |
gl_Position = modelViewProjection * position; | |
vTexCoord = texCoord; | |
vNormal = mModel * vec4( normal, 0.0 ); | |
vec4 norm = normalize(vNormal); | |
vPosition = mModel * position; | |
vDirectDiffuse = directColor * max( 0.0, dot( norm, directDirection )); | |
} | |
]], | |
fragmentShader=[[ | |
precision highp float; | |
uniform vec4 ambientColor; | |
uniform lowp sampler2D texture; | |
uniform float reflect; | |
uniform bool hasTexture; | |
uniform vec4 directColor; | |
uniform float directStrength; | |
uniform vec4 directDirection; | |
uniform vec4 eyePosition; | |
uniform vec4 specularColor; | |
uniform float specularPower; | |
uniform float shine; | |
varying lowp vec4 vColor; | |
varying highp vec2 vTexCoord; | |
varying lowp vec4 vPosition; | |
varying lowp vec4 vNormal; | |
varying vec4 vDirectDiffuse; | |
vec4 normalizedNormal = normalize(vNormal); | |
vec4 GetSpecularColor(vec4 lightPosition, vec4 lightColor, bool IsDirectional) | |
{ | |
vec4 lightDirection; | |
if (IsDirectional) lightDirection = lightPosition; | |
else lightDirection = vec4( normalize( lightPosition - vPosition )); | |
vec4 cameraDirection = normalize( eyePosition - vPosition ); | |
vec4 halfAngle = normalize( cameraDirection + lightDirection ); | |
vec4 specularColor = min(lightColor + 0.5, 1.0); | |
float spec = pow( max( 0.0, dot( normalizedNormal, halfAngle)), specularPower ); | |
return specularColor * spec * shine; | |
} | |
void main() | |
{ | |
lowp vec4 ambient=vec4(0.,0.,0.,0.); | |
lowp vec4 diffuse=vec4(0.,0.,0.,0.); | |
lowp vec4 specular=vec4(0.,0.,0.,0.); | |
lowp vec4 pixel; | |
if (hasTexture) pixel = texture2D( texture, vTexCoord); | |
else pixel = vColor; | |
ambient = pixel * ambientColor; | |
diffuse = diffuse + pixel * vDirectDiffuse; | |
specular=specular + pixel * directStrength * GetSpecularColor(directDirection, specularColor, true); | |
vec4 totalColor = clamp( reflect * (ambient + diffuse + specular),0.,1.); | |
totalColor.a=1.; | |
gl_FragColor=totalColor; | |
} | |
]] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment