diff --git a/src/compile.glsl.coffee b/src/compile.glsl.coffee index bd36ec8..5b88df9 100644 --- a/src/compile.glsl.coffee +++ b/src/compile.glsl.coffee @@ -69,7 +69,7 @@ compileGLSL = (abstractSolidModel) -> result += "}\n\n" result - main = + fragmentShaderMain = ''' void main(void) { const int steps = 64; @@ -100,35 +100,45 @@ compileGLSL = (abstractSolidModel) -> ''' - # TEMPORARY + vertexShaderMain = (bounds) -> + # TODO: Possibly change these to uniforms later to avoid recompilation + "const vec3 sceneScale = vec3(#{bounds[1][0] - bounds[0][0]}, #{bounds[1][1] - bounds[0][1]}, #{bounds[1][2] - bounds[0][2]});\n" + + "const vec3 sceneTranslation = vec3(#{bounds[0][0] + bounds[1][0]}, #{bounds[0][1] + bounds[1][1]}, #{bounds[0][2] + bounds[1][2]});\n" + + ''' + uniform mat4 projection; + uniform mat4 modelView; + attribute vec3 position; + + void main(void) { + gl_Position = projection * modelView * vec4(position, 1.0); + } + + ''' + + ## TEMPORARY console.log "ASM:" console.log abstractSolidModel + ## # Generate the fragment shader distanceResult = glslSceneDistance abstractSolidModel + if distanceResult.nodes.length != 1 + mecha.logInternalError 'GLSL Compiler: Expected exactly one result node from the distance compiler.' - # TEMPORARY + ## TEMPORARY console.log "Distance Result:" console.log distanceResult - - if distanceResult.nodes.length == 1 - distanceResult.nodes[0].code - else - mecha.logInternalError 'GLSL Compiler: Expected exactly one result node from distance compiler.' - return "" + ## idResult = glslSceneId abstractSolidModel + if idResult.nodes.length != 1 + mecha.logInternalError 'GLSL Compiler: Expected exactly one result node from the material id compiler.' - # TEMPORARY + ## TEMPORARY console.log "Id Result:" console.log idResult - - if idResult.nodes.length == 1 - idResult.nodes[0].code - else - mecha.logInternalError 'GLSL Compiler: Expected exactly one result node from id compiler.' - return "" + ## fragmentShader = prefix + (glslLibrary.compile distanceResult.flags.glslFunctions) + @@ -136,18 +146,28 @@ compileGLSL = (abstractSolidModel) -> sceneNormal + (sceneId idResult.flags.glslPrelude.code, idResult.nodes[0].code) + (sceneMaterial idResult.flags.materials) + - main + fragmentShaderMain + + ## TEMPORARY console.log fragmentShader + ## # Generate the vertex shader boundsResult = compileASMBounds abstractSolidModel + if boundsResult.nodes.length != 1 + mecha.logInternalError 'GLSL Compiler: Expected exactly one result node from the bounding box compiler.' - # TEMPORARY + ## TEMPORARY console.log "Bounds Result:" console.log boundsResult + ## + + vertexShader = vertexShaderMain boundsResult.nodes[0].bounds - # TODO: vertexShader = ... + ## TEMPORARY + console.log vertexShader + ## return fragmentShader diff --git a/static/lib/app.js b/static/lib/app.js index 0a90842..f0b2ff6 100644 --- a/static/lib/app.js +++ b/static/lib/app.js @@ -1060,7 +1060,7 @@ return result; })); compileGLSL = function(abstractSolidModel) { - var boundsResult, distanceResult, fragmentShader, idResult, main, prefix, rayDirection, rayOrigin, sceneDist, sceneId, sceneMaterial, sceneNormal, sceneRayDist, uniforms; + var boundsResult, distanceResult, fragmentShader, fragmentShaderMain, idResult, prefix, rayDirection, rayOrigin, sceneDist, sceneId, sceneMaterial, sceneNormal, sceneRayDist, uniforms, vertexShader, vertexShaderMain; rayOrigin = 'ro'; rayDirection = 'rd'; prefix = '#ifdef GL_ES\n precision highp float;\n#endif\nuniform vec3 SCENEJS_uEye; // World-space eye position\nvarying vec3 SCENEJS_vEyeVec; // Output world-space eye vector\nvarying vec4 SCENEJS_vWorldVertex; // Varying for fragment clip or world pos hook\n'; @@ -1096,32 +1096,34 @@ result += "}\n\n"; return result; }; - main = 'void main(void) {\n const int steps = 64;\n const float threshold = 0.01;\n vec3 rayDir = /*normalize*/(/*SCENEJS_uMMatrix * */ -SCENEJS_vEyeVec);\n vec3 rayOrigin = SCENEJS_vWorldVertex.xyz;\n bool hit = false;\n float dist = 0.0;\n for(int i = 0; i < steps; i++) {\n //dist = sceneRayDist(rayOrigin, rayDir);\n dist = sceneDist(rayOrigin);\n if (dist < threshold) {\n hit = true;\n break;\n }\n rayOrigin += dist * rayDir;\n }\n if(!hit) { discard; }\n //if(!hit) { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); return; }\n //const vec3 diffuseColor = vec3(0.1, 0.2, 0.8);\n vec3 diffuseColor = sceneMaterial(rayOrigin);\n //const vec3 specularColor = vec3(1.0, 1.0, 1.0);\n const vec3 lightPos = vec3(1.5,1.5, 4.0);\n vec3 ldir = normalize(lightPos - rayOrigin);\n vec3 diffuse = diffuseColor * dot(sceneNormal(rayOrigin), ldir);\n gl_FragColor = vec4(diffuse, 1.0);\n}\n'; + fragmentShaderMain = 'void main(void) {\n const int steps = 64;\n const float threshold = 0.01;\n vec3 rayDir = /*normalize*/(/*SCENEJS_uMMatrix * */ -SCENEJS_vEyeVec);\n vec3 rayOrigin = SCENEJS_vWorldVertex.xyz;\n bool hit = false;\n float dist = 0.0;\n for(int i = 0; i < steps; i++) {\n //dist = sceneRayDist(rayOrigin, rayDir);\n dist = sceneDist(rayOrigin);\n if (dist < threshold) {\n hit = true;\n break;\n }\n rayOrigin += dist * rayDir;\n }\n if(!hit) { discard; }\n //if(!hit) { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); return; }\n //const vec3 diffuseColor = vec3(0.1, 0.2, 0.8);\n vec3 diffuseColor = sceneMaterial(rayOrigin);\n //const vec3 specularColor = vec3(1.0, 1.0, 1.0);\n const vec3 lightPos = vec3(1.5,1.5, 4.0);\n vec3 ldir = normalize(lightPos - rayOrigin);\n vec3 diffuse = diffuseColor * dot(sceneNormal(rayOrigin), ldir);\n gl_FragColor = vec4(diffuse, 1.0);\n}\n'; + vertexShaderMain = function(bounds) { + return ("const vec3 sceneScale = vec3(" + (bounds[1][0] - bounds[0][0]) + ", " + (bounds[1][1] - bounds[0][1]) + ", " + (bounds[1][2] - bounds[0][2]) + ");\n") + ("const vec3 sceneTranslation = vec3(" + (bounds[0][0] + bounds[1][0]) + ", " + (bounds[0][1] + bounds[1][1]) + ", " + (bounds[0][2] + bounds[1][2]) + ");\n") + 'uniform mat4 projection;\nuniform mat4 modelView;\nattribute vec3 position;\n\nvoid main(void) {\n gl_Position = projection * modelView * vec4(position, 1.0);\n}\n'; + }; console.log("ASM:"); console.log(abstractSolidModel); distanceResult = glslSceneDistance(abstractSolidModel); + if (distanceResult.nodes.length !== 1) { + mecha.logInternalError('GLSL Compiler: Expected exactly one result node from the distance compiler.'); + } console.log("Distance Result:"); console.log(distanceResult); - if (distanceResult.nodes.length === 1) { - distanceResult.nodes[0].code; - } else { - mecha.logInternalError('GLSL Compiler: Expected exactly one result node from distance compiler.'); - return ""; - } idResult = glslSceneId(abstractSolidModel); + if (idResult.nodes.length !== 1) { + mecha.logInternalError('GLSL Compiler: Expected exactly one result node from the material id compiler.'); + } console.log("Id Result:"); console.log(idResult); - if (idResult.nodes.length === 1) { - idResult.nodes[0].code; - } else { - mecha.logInternalError('GLSL Compiler: Expected exactly one result node from id compiler.'); - return ""; - } - fragmentShader = prefix + (glslLibrary.compile(distanceResult.flags.glslFunctions)) + (sceneDist(distanceResult.flags.glslPrelude.code, distanceResult.nodes[0].code)) + sceneNormal + (sceneId(idResult.flags.glslPrelude.code, idResult.nodes[0].code)) + (sceneMaterial(idResult.flags.materials)) + main; + fragmentShader = prefix + (glslLibrary.compile(distanceResult.flags.glslFunctions)) + (sceneDist(distanceResult.flags.glslPrelude.code, distanceResult.nodes[0].code)) + sceneNormal + (sceneId(idResult.flags.glslPrelude.code, idResult.nodes[0].code)) + (sceneMaterial(idResult.flags.materials)) + fragmentShaderMain; console.log(fragmentShader); boundsResult = compileASMBounds(abstractSolidModel); + if (boundsResult.nodes.length !== 1) { + mecha.logInternalError('GLSL Compiler: Expected exactly one result node from the bounding box compiler.'); + } console.log("Bounds Result:"); console.log(boundsResult); + vertexShader = vertexShaderMain(boundsResult.nodes[0].bounds); + console.log(vertexShader); return fragmentShader; }; constants = { diff --git a/static/lib/app.min.js b/static/lib/app.min.js index a72e160..09674cc 100644 --- a/static/lib/app.min.js +++ b/static/lib/app.min.js @@ -1,3 +1,3 @@ /* * Copyright 2011, CircuitHub.com - */"use strict",function(){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P=Array.prototype.slice;t=function(a,b,c,d){var e;return e=a.get(b),e[c]=d,a.set(b,e)},C=function(a){return[a.x,a.y,a.z]},D=function(a){return[a.x,a.y,a.z,a.w]},K=function(a){return{x:a[0],y:a[1],z:a[2]}},L=function(a){return{x:a[0],y:a[1],z:a[2],w:a[3]}},q=function(a){var b,c,d,e,f,g;return b=C(a.eye),c=C(a.look),d=C(a.up),e=[0,0,0],f=[0,0,0],g=[0,0,0],SceneJS_math_subVec3(c,b,g),SceneJS_math_cross3Vec3(d,g,e),SceneJS_math_cross3Vec3(g,e,f),SceneJS_math_normalizeVec3(e),SceneJS_math_normalizeVec3(f),SceneJS_math_normalizeVec3(g),SceneJS_math_newQuaternionFromMat3(e.concat(f,g))},A=function(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;return a[0]===0&&a[1]===0?{eye:c.eye,up:c.up}:(f=C(c.eye),q=C(c.up),j=C(c.look),g=SceneJS_math_lenVec3(f),h=[0,0,0],SceneJS_math_mulVec3Scalar(f,1/g,h),m=[0,0,0],SceneJS_math_cross3Vec3(q,f,m),n=SceneJS_math_normalizeVec3(m),r=[0,0,0],SceneJS_math_cross3Vec3(h,n,r),d=[n[0]*-a[1]+r[0]*-a[0],n[1]*-a[1]+r[1]*-a[0],n[2]*-a[1]+r[2]*-a[0]],e=SceneJS_math_lenVec2(a),l=SceneJS_math_rotationMat4v(e,d),i=SceneJS_math_transformVector3(l,f),o=SceneJS_math_transformVector3(l,m),p=[0,0,0],SceneJS_math_mulVec3(o,b,p),SceneJS_math_subVec3(o,p),s=[0,0,0],SceneJS_math_cross3Vec3(i,o,s),k={eye:K(i),look:c.look,up:K(s)})},B=function(a,b,c){return a.set(A(b,c,{eye:a.get("eye"),look:a.get("look"),up:a.get("up")}))},N=function(a,b,c){var d,e,f,g,h,i;return d=C(c.eye),h=C(c.look),e=SceneJS_math_lenVec3(d),b!=null?g=Math.clamp(e+a,b[0],b[1]):g=e+a,f=[0,0,0],SceneJS_math_mulVec3Scalar(d,g/e,f),i={eye:K(f),look:c.look,up:c.up}},O=function(a,b,c){return a.set(N(b,c,{eye:a.get("eye"),look:a.get("look"),up:a.get("up")}))},s={},s.log=typeof console!="undefined"&&console!==null&&console.log!=null?function(){return console.log.apply(console,arguments)}:function(){},s.logInternalError=typeof console!="undefined"&&console!==null&&console.log!=null?function(){return console.log.apply(console,arguments)}:function(){},s.logApiError=typeof console!="undefined"&&console!==null&&console.log!=null?function(){return console.log.apply(console,arguments)}:function(){},Array.prototype.flatten=function(){var a,b;return(b=[]).concat.apply(b,function(){var b,c,d;d=[];for(b=0,c=this.length;b0&&s.logInternalError("ASM Optimize: Unexpected child nodes found in halfspace node.");for(f=0,h=a.length;fb.attr.val&&!c.invert)d.attr=b.attr;return}}}break}return a[0].nodes.push(b)},"default":function(a,b,c){return a[0].nodes.push(b)}},r(d,c,[{type:"union",nodes:[]}],a,b)},e=function(a){var b,c,d,e,f,g,h,i,j;return c=0,b=1,h={invert:function(a,b,c){return c.invert=!c.invert},union:function(a,b,d){return d.composition.push(c)},intersect:function(a,c,d){return d.composition.push(b)},"default":function(a,b,c){}},j=function(a){var b,c,d,e,f;b=[[Infinity,Infinity,Infinity],[-Infinity,-Infinity,-Infinity]];for(e=0,f=a.length;e1?b.union.apply(b,function(){var b,e,f,g;f=a.nodes,g=[];for(b=0,e=f.length;b0?b.intersect(c(a.nodes[0],b.invert.apply(b,function(){var b,e,f,g;f=a.nodes.slice(1,a.nodes.length+1||9e9),g=[];for(b=0,e=f.length;bm;0<=m?i++:i--)b=e+i,c=String.fromCharCode(b),f+="in "+g.arguments[i]+" "+c,i2?""+b+"["+(i-3)+"] - "+d.hs[i]:"-"+b+"["+i+"] + "+d.hs[i],c)),d.hs[i]=null;break}j-=1}else if(j>1){e=[d.hs[0]!==null?d.hs[0]:d.hs[3]!==null?d.hs[3]:0,d.hs[1]!==null?d.hs[1]:d.hs[4]!==null?d.hs[4]:0,d.hs[2]!==null?d.hs[2]:d.hs[5]!==null?d.hs[5]:0],m=[d.hs[0]!==null,d.hs[1]!==null,d.hs[2]!==null],l=m[0]||m[1]||m[2]?!m[0]&&d.hs[3]!==null||!m[1]&&d.hs[4]!==null||!m[2]&&d.hs[5]!==null?"vec3("+(m[0]?"-":"")+b+".x, "+(m[1]?"-":"")+b+".y, "+(m[2]?"-":"")+b+".z":"-"+b:""+b,f="vec3("+(m[0]?-e[0]:e[0])+", "+(m[1]?-e[1]:e[1])+", "+(m[2]?-e[2]:e[2])+")",k.preludePush(c.glslPrelude,""+l+" - "+f),g=k.preludePop(c.glslPrelude);if(d.hs[0]!==null||d.hs[3]!==null)d.codes.push(a(""+g+".x",c)),d.hs[0]!==null?d.hs[0]=null:d.hs[3]=null,j-=1;if(d.hs[1]!==null||d.hs[4]!==null)d.codes.push(a(""+g+".y",c)),d.hs[1]!==null?d.hs[1]=null:d.hs[4]=null,j-=1;if(d.hs[2]!==null||d.hs[5]!==null)d.codes.push(a(""+g+".z",c)),d.hs[2]!==null?d.hs[2]=null:d.hs[5]=null,j-=1}},e={invert:function(a,b,c){return c.invert=!c.invert},union:function(a,c,e){var f,g,h,i,j,k,l,m,n,o,p;if(c.nodes.length===0){s.logInternalError("GLSL Compiler: Union node is empty.");return}g=[],h=function(a,b){var c,d,e,f;f=[];for(d=0,e=b.length;dg.halfSpaces[e]||e>2&&i2&&i>g.halfSpaces[e])g.halfSpaces[e]=i;break;case"translate":h+=g.attr.offset[c.attr.axis];continue;case"invert":case"mirror":continue;default:f=d.glslPrelude[d.glslPrelude.length-1][0],c.code=a(""+c.attr.val+" - "+f+"["+c.attr.axis+"]",d)}break}return b[0].nodes.push(c)},cylinder:function(b,c,d){var e,f;return f=d.glslPrelude[d.glslPrelude.length-1][0],e=["yz","xz","xy"][c.attr.axis],c.code=a("length("+f+"."+e+") - "+c.attr.radius,d),b[0].nodes.push(c)},sphere:function(b,c,d){var e;return e=d.glslPrelude[d.glslPrelude.length-1][0],c.code=a("length("+e+") - "+c.attr.radius,d),b[0].nodes.push(c)},material:function(a,b,c){return c.materialIdStack.pop(),a[0].nodes.push(b)},"default":function(a,b,c){return a[0].nodes.push(b)}},function(a){return k(a,f,e)}},n=l(function(a){return a},function(a,b){return"min("+a+", "+b+")"},function(a,b){return"max("+a+", "+b+")"}),o=l(function(a,b){var c;return c=new J(a),c.materialId=b.materialIdStack[b.materialIdStack.length-1],c},function(a,b,c){var d,e,f;return k.preludePush(c.glslPrelude,String(a),"float"),d=k.preludePop(c.glslPrelude),k.preludePush(c.glslPrelude,String(b),"float"),e=k.preludePop(c.glslPrelude),f=new J(""+d+" < "+e+"? (id = "+a.materialId+", "+d+") : (id = "+b.materialId+", "+e+")"),f.materialId=c.materialIdStack[c.materialIdStack.length-1],f},function(a,b,c){var d,e,f;return k.preludePush(c.glslPrelude,String(a),"float"),d=k.preludePop(c.glslPrelude),k.preludePush(c.glslPrelude,String(b),"float"),e=k.preludePop(c.glslPrelude),f=new J(""+d+" > "+e+"? (id = "+a.materialId+", "+d+") : (id = "+b.materialId+", "+e+")"),f.materialId=c.materialIdStack[c.materialIdStack.length-1],f}),g=function(a){var b,c,d,f,g,h,i,j,k,l,p,q,r,t;j="ro",i="rd",h="#ifdef GL_ES\n precision highp float;\n#endif\nuniform vec3 SCENEJS_uEye; // World-space eye position\nvarying vec3 SCENEJS_vEyeVec; // Output world-space eye vector\nvarying vec4 SCENEJS_vWorldVertex; // Varying for fragment clip or world pos hook\n",t="",k=function(a,b){return"\nfloat sceneDist(in vec3 "+j+"){\n"+a+" return max(0.0,"+b+");\n}\n\n"},r="float sceneRayDist(in vec3 ro, in vec3 rd) {\n return 0.0;\n}\n",q="vec3 sceneNormal(in vec3 p) {\n const float eps = 0.0001;\n vec3 n;\n n.x = sceneDist( vec3(p.x+eps, p.yz) ) - sceneDist( vec3(p.x-eps, p.yz) );\n n.y = sceneDist( vec3(p.x, p.y+eps, p.z) ) - sceneDist( vec3(p.x, p.y-eps, p.z) );\n n.z = sceneDist( vec3(p.xy, p.z+eps) ) - sceneDist( vec3(p.xy, p.z-eps) );\n return normalize(n);\n}\n",l=function(a,b){return"\nint sceneId(in vec3 "+j+") {\n int id = -1;\n"+a+" "+b+";\n return id;\n}\n\n"},p=function(a){var b,c,d,e,f;b=function(a,c){var d,e;return d=c-a,d===1?"m"+a:(e=Math.floor(d*.5),"(id < "+e+"? "+b(a,e)+" : "+b(e,c)+")")},e="\nvec3 sceneMaterial(in vec3 ro) {\n int id = sceneId(ro);\n";if(a.length>0)for(c=0,f=a.length;0<=f?cf;0<=f?c++:c--)d=a[c],e+=" vec3 m"+c+" = "+d+";\n";return e+=" return id >= 0? "+b(0,a.length)+" : vec3(0.5);\n",e+="}\n\n",e},g="void main(void) {\n const int steps = 64;\n const float threshold = 0.01;\n vec3 rayDir = /*normalize*/(/*SCENEJS_uMMatrix * */ -SCENEJS_vEyeVec);\n vec3 rayOrigin = SCENEJS_vWorldVertex.xyz;\n bool hit = false;\n float dist = 0.0;\n for(int i = 0; i < steps; i++) {\n //dist = sceneRayDist(rayOrigin, rayDir);\n dist = sceneDist(rayOrigin);\n if (dist < threshold) {\n hit = true;\n break;\n }\n rayOrigin += dist * rayDir;\n }\n if(!hit) { discard; }\n //if(!hit) { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); return; }\n //const vec3 diffuseColor = vec3(0.1, 0.2, 0.8);\n vec3 diffuseColor = sceneMaterial(rayOrigin);\n //const vec3 specularColor = vec3(1.0, 1.0, 1.0);\n const vec3 lightPos = vec3(1.5,1.5, 4.0);\n vec3 ldir = normalize(lightPos - rayOrigin);\n vec3 diffuse = diffuseColor * dot(sceneNormal(rayOrigin), ldir);\n gl_FragColor = vec4(diffuse, 1.0);\n}\n",console.log("ASM:"),console.log(a),c=n(a),console.log("Distance Result:"),console.log(c);if(c.nodes.length===1)c.nodes[0].code;else return s.logInternalError("GLSL Compiler: Expected exactly one result node from distance compiler."),"";f=o(a),console.log("Id Result:"),console.log(f);if(f.nodes.length===1)f.nodes[0].code;else return s.logInternalError("GLSL Compiler: Expected exactly one result node from id compiler."),"";return d=h+m.compile(c.flags.glslFunctions)+k(c.flags.glslPrelude.code,c.nodes[0].code)+q+l(f.flags.glslPrelude.code,f.nodes[0].code)+p(f.flags.materials)+g,console.log(d),b=e(a),console.log("Bounds Result:"),console.log(b),d},h={canvas:{defaultSize:[512,512]},camera:{maxOrbitSpeed:Math.PI*.1,orbitSpeedFactor:.02,zoomSpeedFactor:.5}},I={scene:SceneJS.scene("Scene"),canvas:document.getElementById("scenejsCanvas"),viewport:{domElement:document.getElementById("viewport"),mouse:{last:[0,0],leftDragging:!1,middleDragging:!1}},api:{url:null,sourceCode:null},application:{initialized:!1}},u=function(a){var b,c,d,e;b=[0,0];if(!a)a=window.event,b=[a.x,a.y];else{c=a.target,d=0,e=0;while(c.offsetParent)d+=c.offsetLeft,e+=c.offsetTop,c=c.offsetParent;b=[a.pageX-d,a.pageY-e]}return b},M=function(){},v=function(a){switch(a.which){case 1:return I.viewport.mouse.leftDragging=!0}},x=function(a){return I.viewport.mouse.leftDragging=!1},w=function(a){var b,c,d;return I.viewport.mouse.leftDragging&&(b=[a.clientX-I.viewport.mouse.last[0],a.clientY-I.viewport.mouse.last[1]],c=SceneJS_math_lenVec2(b),d=[0,0],SceneJS_math_mulVec2Scalar(b,h.camera.orbitSpeedFactor/c,d),d=[Math.clamp(d[0],-h.camera.maxOrbitSpeed,h.camera.maxOrbitSpeed),Math.clamp(d[1],-h.camera.maxOrbitSpeed,h.camera.maxOrbitSpeed)],B(I.scene.findNode("main-lookAt"),d,[0,0,1])),I.viewport.mouse.last=[a.clientX,a.clientY]},y=function(a){var b,c;return b=a.wheelDelta!=null?a.wheelDelta/-120:Math.clamp(a.detail,-1,1),c=b*h.camera.zoomSpeedFactor,O(I.scene.findNode("main-lookAt"),c)},p=function(a){},j=function(){H();try{return f($("#source-code").val(),function(a){return I.scene.findNode("main-shader").set("shaders",[{stage:"fragment",code:g(d(a))}])})}catch(a){return s.log(a)}},F=function(){return I.viewport.domElement.addEventListener("mousedown",v,!0),I.viewport.domElement.addEventListener("mouseup",x,!0),I.viewport.domElement.addEventListener("mousemove",w,!0),I.viewport.domElement.addEventListener("mousewheel",y,!0),I.viewport.domElement.addEventListener("DOMMouseScroll",y,!0),document.addEventListener("keydown",p,!0),window.addEventListener("resize",M,!0)},E=function(){return $("#source-compile").click(j)},G=function(){},c=function(){return M()},H=function(){return f($("#source-code").val(),function(a){var b;return b={type:"shader",id:"main-shader",shaders:[{stage:"fragment",code:g(d(a))}],vars:{}},I.scene.findNode("cube-mat").insert("node",b)})},i=function(){},a=function(){return I.api.url=$("link[rel='api']").attr("href"),$.get(encodeURIComponent(I.api.url,void 0,void 0,"text")).success(function(a,b,c){return I.api.sourceCode=a,s.log("Loaded "+I.api.url)}).error(function(){return s.log("Error loading API script")})},c(),I.scene.start({idleFunc:G}),$(function(){return a(),i(),F(),E(),I.application.initialized=!0})}.call(this); \ No newline at end of file + */"use strict",function(){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P=Array.prototype.slice;t=function(a,b,c,d){var e;return e=a.get(b),e[c]=d,a.set(b,e)},C=function(a){return[a.x,a.y,a.z]},D=function(a){return[a.x,a.y,a.z,a.w]},K=function(a){return{x:a[0],y:a[1],z:a[2]}},L=function(a){return{x:a[0],y:a[1],z:a[2],w:a[3]}},q=function(a){var b,c,d,e,f,g;return b=C(a.eye),c=C(a.look),d=C(a.up),e=[0,0,0],f=[0,0,0],g=[0,0,0],SceneJS_math_subVec3(c,b,g),SceneJS_math_cross3Vec3(d,g,e),SceneJS_math_cross3Vec3(g,e,f),SceneJS_math_normalizeVec3(e),SceneJS_math_normalizeVec3(f),SceneJS_math_normalizeVec3(g),SceneJS_math_newQuaternionFromMat3(e.concat(f,g))},A=function(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;return a[0]===0&&a[1]===0?{eye:c.eye,up:c.up}:(f=C(c.eye),q=C(c.up),j=C(c.look),g=SceneJS_math_lenVec3(f),h=[0,0,0],SceneJS_math_mulVec3Scalar(f,1/g,h),m=[0,0,0],SceneJS_math_cross3Vec3(q,f,m),n=SceneJS_math_normalizeVec3(m),r=[0,0,0],SceneJS_math_cross3Vec3(h,n,r),d=[n[0]*-a[1]+r[0]*-a[0],n[1]*-a[1]+r[1]*-a[0],n[2]*-a[1]+r[2]*-a[0]],e=SceneJS_math_lenVec2(a),l=SceneJS_math_rotationMat4v(e,d),i=SceneJS_math_transformVector3(l,f),o=SceneJS_math_transformVector3(l,m),p=[0,0,0],SceneJS_math_mulVec3(o,b,p),SceneJS_math_subVec3(o,p),s=[0,0,0],SceneJS_math_cross3Vec3(i,o,s),k={eye:K(i),look:c.look,up:K(s)})},B=function(a,b,c){return a.set(A(b,c,{eye:a.get("eye"),look:a.get("look"),up:a.get("up")}))},N=function(a,b,c){var d,e,f,g,h,i;return d=C(c.eye),h=C(c.look),e=SceneJS_math_lenVec3(d),b!=null?g=Math.clamp(e+a,b[0],b[1]):g=e+a,f=[0,0,0],SceneJS_math_mulVec3Scalar(d,g/e,f),i={eye:K(f),look:c.look,up:c.up}},O=function(a,b,c){return a.set(N(b,c,{eye:a.get("eye"),look:a.get("look"),up:a.get("up")}))},s={},s.log=typeof console!="undefined"&&console!==null&&console.log!=null?function(){return console.log.apply(console,arguments)}:function(){},s.logInternalError=typeof console!="undefined"&&console!==null&&console.log!=null?function(){return console.log.apply(console,arguments)}:function(){},s.logApiError=typeof console!="undefined"&&console!==null&&console.log!=null?function(){return console.log.apply(console,arguments)}:function(){},Array.prototype.flatten=function(){var a,b;return(b=[]).concat.apply(b,function(){var b,c,d;d=[];for(b=0,c=this.length;b0&&s.logInternalError("ASM Optimize: Unexpected child nodes found in halfspace node.");for(f=0,h=a.length;fb.attr.val&&!c.invert)d.attr=b.attr;return}}}break}return a[0].nodes.push(b)},"default":function(a,b,c){return a[0].nodes.push(b)}},r(d,c,[{type:"union",nodes:[]}],a,b)},e=function(a){var b,c,d,e,f,g,h,i,j;return c=0,b=1,h={invert:function(a,b,c){return c.invert=!c.invert},union:function(a,b,d){return d.composition.push(c)},intersect:function(a,c,d){return d.composition.push(b)},"default":function(a,b,c){}},j=function(a){var b,c,d,e,f;b=[[Infinity,Infinity,Infinity],[-Infinity,-Infinity,-Infinity]];for(e=0,f=a.length;e1?b.union.apply(b,function(){var b,e,f,g;f=a.nodes,g=[];for(b=0,e=f.length;b0?b.intersect(c(a.nodes[0],b.invert.apply(b,function(){var b,e,f,g;f=a.nodes.slice(1,a.nodes.length+1||9e9),g=[];for(b=0,e=f.length;bm;0<=m?i++:i--)b=e+i,c=String.fromCharCode(b),f+="in "+g.arguments[i]+" "+c,i2?""+b+"["+(i-3)+"] - "+d.hs[i]:"-"+b+"["+i+"] + "+d.hs[i],c)),d.hs[i]=null;break}j-=1}else if(j>1){e=[d.hs[0]!==null?d.hs[0]:d.hs[3]!==null?d.hs[3]:0,d.hs[1]!==null?d.hs[1]:d.hs[4]!==null?d.hs[4]:0,d.hs[2]!==null?d.hs[2]:d.hs[5]!==null?d.hs[5]:0],m=[d.hs[0]!==null,d.hs[1]!==null,d.hs[2]!==null],l=m[0]||m[1]||m[2]?!m[0]&&d.hs[3]!==null||!m[1]&&d.hs[4]!==null||!m[2]&&d.hs[5]!==null?"vec3("+(m[0]?"-":"")+b+".x, "+(m[1]?"-":"")+b+".y, "+(m[2]?"-":"")+b+".z":"-"+b:""+b,f="vec3("+(m[0]?-e[0]:e[0])+", "+(m[1]?-e[1]:e[1])+", "+(m[2]?-e[2]:e[2])+")",k.preludePush(c.glslPrelude,""+l+" - "+f),g=k.preludePop(c.glslPrelude);if(d.hs[0]!==null||d.hs[3]!==null)d.codes.push(a(""+g+".x",c)),d.hs[0]!==null?d.hs[0]=null:d.hs[3]=null,j-=1;if(d.hs[1]!==null||d.hs[4]!==null)d.codes.push(a(""+g+".y",c)),d.hs[1]!==null?d.hs[1]=null:d.hs[4]=null,j-=1;if(d.hs[2]!==null||d.hs[5]!==null)d.codes.push(a(""+g+".z",c)),d.hs[2]!==null?d.hs[2]=null:d.hs[5]=null,j-=1}},e={invert:function(a,b,c){return c.invert=!c.invert},union:function(a,c,e){var f,g,h,i,j,k,l,m,n,o,p;if(c.nodes.length===0){s.logInternalError("GLSL Compiler: Union node is empty.");return}g=[],h=function(a,b){var c,d,e,f;f=[];for(d=0,e=b.length;dg.halfSpaces[e]||e>2&&i2&&i>g.halfSpaces[e])g.halfSpaces[e]=i;break;case"translate":h+=g.attr.offset[c.attr.axis];continue;case"invert":case"mirror":continue;default:f=d.glslPrelude[d.glslPrelude.length-1][0],c.code=a(""+c.attr.val+" - "+f+"["+c.attr.axis+"]",d)}break}return b[0].nodes.push(c)},cylinder:function(b,c,d){var e,f;return f=d.glslPrelude[d.glslPrelude.length-1][0],e=["yz","xz","xy"][c.attr.axis],c.code=a("length("+f+"."+e+") - "+c.attr.radius,d),b[0].nodes.push(c)},sphere:function(b,c,d){var e;return e=d.glslPrelude[d.glslPrelude.length-1][0],c.code=a("length("+e+") - "+c.attr.radius,d),b[0].nodes.push(c)},material:function(a,b,c){return c.materialIdStack.pop(),a[0].nodes.push(b)},"default":function(a,b,c){return a[0].nodes.push(b)}},function(a){return k(a,f,e)}},n=l(function(a){return a},function(a,b){return"min("+a+", "+b+")"},function(a,b){return"max("+a+", "+b+")"}),o=l(function(a,b){var c;return c=new J(a),c.materialId=b.materialIdStack[b.materialIdStack.length-1],c},function(a,b,c){var d,e,f;return k.preludePush(c.glslPrelude,String(a),"float"),d=k.preludePop(c.glslPrelude),k.preludePush(c.glslPrelude,String(b),"float"),e=k.preludePop(c.glslPrelude),f=new J(""+d+" < "+e+"? (id = "+a.materialId+", "+d+") : (id = "+b.materialId+", "+e+")"),f.materialId=c.materialIdStack[c.materialIdStack.length-1],f},function(a,b,c){var d,e,f;return k.preludePush(c.glslPrelude,String(a),"float"),d=k.preludePop(c.glslPrelude),k.preludePush(c.glslPrelude,String(b),"float"),e=k.preludePop(c.glslPrelude),f=new J(""+d+" > "+e+"? (id = "+a.materialId+", "+d+") : (id = "+b.materialId+", "+e+")"),f.materialId=c.materialIdStack[c.materialIdStack.length-1],f}),g=function(a){var b,c,d,f,g,h,i,j,k,l,p,q,r,t,u,v;return j="ro",i="rd",h="#ifdef GL_ES\n precision highp float;\n#endif\nuniform vec3 SCENEJS_uEye; // World-space eye position\nvarying vec3 SCENEJS_vEyeVec; // Output world-space eye vector\nvarying vec4 SCENEJS_vWorldVertex; // Varying for fragment clip or world pos hook\n",t="",k=function(a,b){return"\nfloat sceneDist(in vec3 "+j+"){\n"+a+" return max(0.0,"+b+");\n}\n\n"},r="float sceneRayDist(in vec3 ro, in vec3 rd) {\n return 0.0;\n}\n",q="vec3 sceneNormal(in vec3 p) {\n const float eps = 0.0001;\n vec3 n;\n n.x = sceneDist( vec3(p.x+eps, p.yz) ) - sceneDist( vec3(p.x-eps, p.yz) );\n n.y = sceneDist( vec3(p.x, p.y+eps, p.z) ) - sceneDist( vec3(p.x, p.y-eps, p.z) );\n n.z = sceneDist( vec3(p.xy, p.z+eps) ) - sceneDist( vec3(p.xy, p.z-eps) );\n return normalize(n);\n}\n",l=function(a,b){return"\nint sceneId(in vec3 "+j+") {\n int id = -1;\n"+a+" "+b+";\n return id;\n}\n\n"},p=function(a){var b,c,d,e,f;b=function(a,c){var d,e;return d=c-a,d===1?"m"+a:(e=Math.floor(d*.5),"(id < "+e+"? "+b(a,e)+" : "+b(e,c)+")")},e="\nvec3 sceneMaterial(in vec3 ro) {\n int id = sceneId(ro);\n";if(a.length>0)for(c=0,f=a.length;0<=f?cf;0<=f?c++:c--)d=a[c],e+=" vec3 m"+c+" = "+d+";\n";return e+=" return id >= 0? "+b(0,a.length)+" : vec3(0.5);\n",e+="}\n\n",e},f="void main(void) {\n const int steps = 64;\n const float threshold = 0.01;\n vec3 rayDir = /*normalize*/(/*SCENEJS_uMMatrix * */ -SCENEJS_vEyeVec);\n vec3 rayOrigin = SCENEJS_vWorldVertex.xyz;\n bool hit = false;\n float dist = 0.0;\n for(int i = 0; i < steps; i++) {\n //dist = sceneRayDist(rayOrigin, rayDir);\n dist = sceneDist(rayOrigin);\n if (dist < threshold) {\n hit = true;\n break;\n }\n rayOrigin += dist * rayDir;\n }\n if(!hit) { discard; }\n //if(!hit) { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); return; }\n //const vec3 diffuseColor = vec3(0.1, 0.2, 0.8);\n vec3 diffuseColor = sceneMaterial(rayOrigin);\n //const vec3 specularColor = vec3(1.0, 1.0, 1.0);\n const vec3 lightPos = vec3(1.5,1.5, 4.0);\n vec3 ldir = normalize(lightPos - rayOrigin);\n vec3 diffuse = diffuseColor * dot(sceneNormal(rayOrigin), ldir);\n gl_FragColor = vec4(diffuse, 1.0);\n}\n",v=function(a){return"const vec3 sceneScale = vec3("+(a[1][0]-a[0][0])+", "+(a[1][1]-a[0][1])+", "+(a[1][2]-a[0][2])+");\n"+("const vec3 sceneTranslation = vec3("+(a[0][0]+a[1][0])+", "+(a[0][1]+a[1][1])+", "+(a[0][2]+a[1][2])+");\n")+"uniform mat4 projection;\nuniform mat4 modelView;\nattribute vec3 position;\n\nvoid main(void) {\n gl_Position = projection * modelView * vec4(position, 1.0);\n}\n"},console.log("ASM:"),console.log(a),c=n(a),c.nodes.length!==1&&s.logInternalError("GLSL Compiler: Expected exactly one result node from the distance compiler."),console.log("Distance Result:"),console.log(c),g=o(a),g.nodes.length!==1&&s.logInternalError("GLSL Compiler: Expected exactly one result node from the material id compiler."),console.log("Id Result:"),console.log(g),d=h+m.compile(c.flags.glslFunctions)+k(c.flags.glslPrelude.code,c.nodes[0].code)+q+l(g.flags.glslPrelude.code,g.nodes[0].code)+p(g.flags.materials)+f,console.log(d),b=e(a),b.nodes.length!==1&&s.logInternalError("GLSL Compiler: Expected exactly one result node from the bounding box compiler."),console.log("Bounds Result:"),console.log(b),u=v(b.nodes[0].bounds),console.log(u),d},h={canvas:{defaultSize:[512,512]},camera:{maxOrbitSpeed:Math.PI*.1,orbitSpeedFactor:.02,zoomSpeedFactor:.5}},I={scene:SceneJS.scene("Scene"),canvas:document.getElementById("scenejsCanvas"),viewport:{domElement:document.getElementById("viewport"),mouse:{last:[0,0],leftDragging:!1,middleDragging:!1}},api:{url:null,sourceCode:null},application:{initialized:!1}},u=function(a){var b,c,d,e;b=[0,0];if(!a)a=window.event,b=[a.x,a.y];else{c=a.target,d=0,e=0;while(c.offsetParent)d+=c.offsetLeft,e+=c.offsetTop,c=c.offsetParent;b=[a.pageX-d,a.pageY-e]}return b},M=function(){},v=function(a){switch(a.which){case 1:return I.viewport.mouse.leftDragging=!0}},x=function(a){return I.viewport.mouse.leftDragging=!1},w=function(a){var b,c,d;return I.viewport.mouse.leftDragging&&(b=[a.clientX-I.viewport.mouse.last[0],a.clientY-I.viewport.mouse.last[1]],c=SceneJS_math_lenVec2(b),d=[0,0],SceneJS_math_mulVec2Scalar(b,h.camera.orbitSpeedFactor/c,d),d=[Math.clamp(d[0],-h.camera.maxOrbitSpeed,h.camera.maxOrbitSpeed),Math.clamp(d[1],-h.camera.maxOrbitSpeed,h.camera.maxOrbitSpeed)],B(I.scene.findNode("main-lookAt"),d,[0,0,1])),I.viewport.mouse.last=[a.clientX,a.clientY]},y=function(a){var b,c;return b=a.wheelDelta!=null?a.wheelDelta/-120:Math.clamp(a.detail,-1,1),c=b*h.camera.zoomSpeedFactor,O(I.scene.findNode("main-lookAt"),c)},p=function(a){},j=function(){H();try{return f($("#source-code").val(),function(a){return I.scene.findNode("main-shader").set("shaders",[{stage:"fragment",code:g(d(a))}])})}catch(a){return s.log(a)}},F=function(){return I.viewport.domElement.addEventListener("mousedown",v,!0),I.viewport.domElement.addEventListener("mouseup",x,!0),I.viewport.domElement.addEventListener("mousemove",w,!0),I.viewport.domElement.addEventListener("mousewheel",y,!0),I.viewport.domElement.addEventListener("DOMMouseScroll",y,!0),document.addEventListener("keydown",p,!0),window.addEventListener("resize",M,!0)},E=function(){return $("#source-compile").click(j)},G=function(){},c=function(){return M()},H=function(){return f($("#source-code").val(),function(a){var b;return b={type:"shader",id:"main-shader",shaders:[{stage:"fragment",code:g(d(a))}],vars:{}},I.scene.findNode("cube-mat").insert("node",b)})},i=function(){},a=function(){return I.api.url=$("link[rel='api']").attr("href"),$.get(encodeURIComponent(I.api.url,void 0,void 0,"text")).success(function(a,b,c){return I.api.sourceCode=a,s.log("Loaded "+I.api.url)}).error(function(){return s.log("Error loading API script")})},c(),I.scene.start({idleFunc:G}),$(function(){return a(),i(),F(),E(),I.application.initialized=!0})}.call(this); \ No newline at end of file