functioninitWebGL(t){varr=document.getElementById(t);returngl=WebGLUtils.setupWebGL(r)}functionlog(t){window.console&&window.console.log&&window.console.log(t)}functionsimpleSetup(t,r,i,e,a,m){varn=loadShader(t,r),x=loadShader(t,i),s=t.createProgram();t.attachShader(s,n),t.attachShader(s,x);for(varo=0;o<e.length;++o)t.bindAttribLocation(s,o,e[o]);t.linkProgram(s);varh=t.getProgramParameter(s,t.LINK_STATUS);if(!h&&!t.isContextLost()){var$=t.getProgramInfoLog(s);returnlog("Error in program linking:"+$),t.deleteProgram(s),t.deleteProgram(x),t.deleteProgram(n),null}returnt.useProgram(s),t.clearColor(a[0],a[1],a[2],a[3]),t.clearDepth(m),t.enable(t.DEPTH_TEST),t.enable(t.BLEND),t.blendFunc(t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA),s}functionloadShader(t,r){vari=document.getElementById(r);returni?loadShaderScript(t,i.text,i.type):(log("*** Error: shader script '"+r+"' not found"),null)}functionloadShaderVertexScript(t,r){returnloadShaderScript(t,r,"x-shader/x-vertex")}functionloadShaderFragmentScript(t,r){returnloadShaderScript(t,r,"x-shader/x-fragment")}functionloadShaderScript(t,r,i){if(!r)returnlog("*** Error: shader script missing"),null;if("x-shader/x-vertex"==i)vare=t.VERTEX_SHADER;else{if("x-shader/x-fragment"!=i)returnlog("*** Error: shader script of undefined type '"+i+"'"),null;vare=t.FRAGMENT_SHADER}vara=t.createShader(e);t.shaderSource(a,r),t.compileShader(a);varm=t.getShaderParameter(a,t.COMPILE_STATUS);if(!m&&!t.isContextLost()){varn=t.getShaderInfoLog(a);returnlog("*** Error compiling shader: "+n),t.deleteShader(a),null}returna}functionclearLoadingObjects(){for(vart=0;t<g_loadingObjects.length;++t)g_loadingObjects[t].onreadystatechange=void0;g_loadingObjects=[]}functionloadObj(t,r){vari={loaded:!1};i.ctx=t;vare=newXMLHttpRequest;returne.obj=i,g_loadingObjects.push(e),e.onreadystatechange=function(){processLoadObj(e)},e.open("GET",r,!0),e.send(null),i}functionprocessLoadObj(t){log("req="+t),4==t.readyState&&(g_loadingObjects.splice(g_loadingObjects.indexOf(t),1),doLoadObj(t.obj,t.responseText))}functiondoLoadObj(t,r){vertexArray=[],normalArray=[],textureArray=[],indexArray=[];vari=[],e=[],a=[],m={},n=0,x={},s=[-1,0];x._unnamed=s;varo=r.split("\n");for(varhino){var$=o[h].replace(/[ \t]+/g," ").replace(/\s\s*$/,"");if("#"!=$[0]){varu=$.split(" ");if("g"==u[0])s=[indexArray.length,0],x[u[1]]=s;elseif("v"==u[0])i.push(parseFloat(u[1])),i.push(parseFloat(u[2])),i.push(parseFloat(u[3]));elseif("vt"==u[0])a.push(parseFloat(u[1])),a.push(parseFloat(u[2]));elseif("vn"==u[0])e.push(parseFloat(u[1])),e.push(parseFloat(u[2])),e.push(parseFloat(u[3]));elseif("f"==u[0]){if(4!=u.length){log("*** Error: face '"+$+"' not handled");continue}for(varf=1;4>f;++f){if(!(u[f]inm)){varl,c,d,g=u[f].split("/");if(1==g.length)l=parseInt(g[0])-1,c=l,d=l;else{if(!(g.length=3))returnt.ctx.console.log("*** Error: did not understand face '"+u[f]+"'"),null;l=parseInt(g[0])-1,d=parseInt(g[1])-1,c=parseInt(g[2])-1}varp=0,v=0,A=0;3*l+2<i.length&&(p=i[3*l],v=i[3*l+1],A=i[3*l+2]),vertexArray.push(p),vertexArray.push(v),vertexArray.push(A),p=0,v=0,2*d+1<a.length&&(p=a[2*d],v=a[2*d+1]),textureArray.push(p),textureArray.push(v),p=0,v=0,A=1,3*c+2<e.length&&(p=e[3*c],v=e[3*c+1],A=e[3*c+2]),normalArray.push(p),normalArray.push(v),normalArray.push(A),m[u[f]]=n++}indexArray.push(m[u[f]]),s[1]++}}}}t.normalObject=t.ctx.createBuffer(),t.ctx.bindBuffer(t.ctx.ARRAY_BUFFER,t.normalObject),t.ctx.bufferData(t.ctx.ARRAY_BUFFER,newFloat32Array(normalArray),t.ctx.STATIC_DRAW),t.texCoordObject=t.ctx.createBuffer(),t.ctx.bindBuffer(t.ctx.ARRAY_BUFFER,t.texCoordObject),t.ctx.bufferData(t.ctx.ARRAY_BUFFER,newFloat32Array(textureArray),t.ctx.STATIC_DRAW),t.vertexObject=t.ctx.createBuffer(),t.ctx.bindBuffer(t.ctx.ARRAY_BUFFER,t.vertexObject),t.ctx.bufferData(t.ctx.ARRAY_BUFFER,newFloat32Array(vertexArray),t.ctx.STATIC_DRAW),t.numIndices=indexArray.length,t.indexObject=t.ctx.createBuffer(),t.ctx.bindBuffer(t.ctx.ELEMENT_ARRAY_BUFFER,t.indexObject),t.ctx.bufferData(t.ctx.ELEMENT_ARRAY_BUFFER,newUint16Array(indexArray),t.ctx.ST