diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-30 03:00:43 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-30 03:00:43 +0000 |
commit | bbbe8128e7ae9d816a221377dbf5ff3969bb203b (patch) | |
tree | 0283a521760b879b30e61872f14f235645745675 /graphics/asymptote/webgl | |
parent | 14ce8b68fe7df49e8a8891bb94c63b9a846da232 (diff) |
CTAN sync 201909300300
Diffstat (limited to 'graphics/asymptote/webgl')
-rw-r--r-- | graphics/asymptote/webgl/WebGLfooter.html | 17 | ||||
-rw-r--r-- | graphics/asymptote/webgl/WebGLheader.html | 172 | ||||
-rw-r--r-- | graphics/asymptote/webgl/arcball-0.01.js | 67 | ||||
-rw-r--r-- | graphics/asymptote/webgl/arcball-min-0.01.js | 1 | ||||
-rw-r--r-- | graphics/asymptote/webgl/arcball.js | 67 | ||||
-rw-r--r-- | graphics/asymptote/webgl/data.js | 47 | ||||
-rw-r--r-- | graphics/asymptote/webgl/gl-0.01.js | 738 | ||||
-rw-r--r-- | graphics/asymptote/webgl/gl-matrix-min-2.3.2.js | 29 | ||||
-rw-r--r-- | graphics/asymptote/webgl/gl.js | 2756 | ||||
-rw-r--r-- | graphics/asymptote/webgl/glm-js-min-2.2.2.js | 273 |
10 files changed, 1987 insertions, 2180 deletions
diff --git a/graphics/asymptote/webgl/WebGLfooter.html b/graphics/asymptote/webgl/WebGLfooter.html deleted file mode 100644 index 043713cd25..0000000000 --- a/graphics/asymptote/webgl/WebGLfooter.html +++ /dev/null @@ -1,17 +0,0 @@ - </script> - -</head> - - -<body onload="webGLStart();"> - <script type="text/javascript" id="eventfunc"> - // forceredraw = true; - function processloop(deltams) { - // enter arbitrary processing event here - // if one wants to modify the object per tick. - } - </script> - <canvas id="Asymptote" style="border: none;" width="800" height="800" /> -</body> - -</html> diff --git a/graphics/asymptote/webgl/WebGLheader.html b/graphics/asymptote/webgl/WebGLheader.html deleted file mode 100644 index 98fa24ec32..0000000000 --- a/graphics/asymptote/webgl/WebGLheader.html +++ /dev/null @@ -1,172 +0,0 @@ -<html> - -<head> - <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"> - - <script id="shader-fs" type="x-shader/x-fragment">#version 300 es - precision mediump float; - - in vec4 vColor; - in vec3 vNormal; - out vec4 outColor; - - flat in int vMaterialIndex; - - // can also construct an alternative shader, - // but would require more work. - // FIXME: An ad-hoc solution is to use uniforms... - uniform int useColor; - - struct Material { - vec4 baseColor, emissive, specular; - float roughness, metallic, f0; - }; - - uniform mat4 uMMatrix; // model matrix - uniform mat4 uPMatrix; // projection matrix - uniform mat4 uVMatrix; // view matrix - - uniform Material objMaterial[100]; // assuming we are doing multiple materials, - - // we can upload them one at a time per call. - // but, we can also make it an array + pass in an index, - // say uniform Material objMaterial[$nmat]; - - // or, even use Uniform Buffer Objects... - - // type, for now - #define POINT_LIGHT 1 - #define DIRECTIONAL_LIGHT 2 - - // for direction, parameter is direction - // for point light, parameter is position (in homoeg coords?) - // are these given in world coords, or view coords? - I can do both - struct Light { - int type; - vec3 color; - float brightness; - vec4 parameter; - }; - - uniform int unLights; // can be replaced by a constant, or even a fixed array in the final release. - uniform Light objLights[100]; // again, can be set at will by the asy generator. - - float NDF_TRG(vec3 halfv, vec3 normal, float roughness) { - float ndoth=max(dot(normal, halfv), 0.0); - float alpha2=roughness*roughness; - - float denom=pow(ndoth*ndoth*(alpha2-1.0)+1.0, 2.0); - return alpha2/denom; - } - - float GGX_Geom(vec3 v, vec3 normal, float roughness) { - float ndotv=max(dot(v, normal), 0.0); - float ap=pow((1.0+roughness), 2.0); - float k=ap/8.0; - - return ndotv/((ndotv*(1.0-k))+k); - } - - float Geom(vec3 v, vec3 l, vec3 normal, float roughness) { - return GGX_Geom(v,normal,roughness)*GGX_Geom(l,normal,roughness); - } - - float Fresnel(vec3 h, vec3 v, float f0) { - float hdotv=max(dot(h,v), 0.0); - return f0+(1.0-f0)*pow((1.0-hdotv),5.0); - } - - // physical based shading using UE4 model. - vec3 physBDRF(Material material, vec3 normal, vec3 lightdir, vec3 lookdir) { - vec3 lambertian=material.baseColor.rgb; - vec3 h=normalize(lightdir+lookdir); - float omegain=max(dot(lookdir, normal), 0.0); - float omegali=max(dot(lightdir, normal), 0.0); - - float D=NDF_TRG(h, normal, material.roughness*material.roughness); - float G=Geom(lookdir, lightdir, normal, material.roughness*material.roughness); - float F=Fresnel(h, lookdir, material.f0); - - float denom=4.0*omegain*omegali; - if (denom == 0.0) {return vec3(0,0,0); } - - float rawrefl=(D*G) / denom; - - vec3 dielectric=mix(lambertian, rawrefl*material.specular.rgb, F); - vec3 metal=rawrefl*material.baseColor.rgb; - - return mix(dielectric, metal, material.metallic); - } - - void main(void) - { - // change later. - - // assuming for now that the headlamp is always on. - // light dir=+Z, viewDir=+Z, - - float normalSign = gl_FrontFacing ? 1.0 : -1.0; - - vec3 normal=normalSign*normalize(vNormal); - vec3 Z=vec3(0,0,1.0); - vec3 rawCol = vec3(0.0); - - Material m=objMaterial[vMaterialIndex]; - - if (useColor == 1) { - m.baseColor = vColor; - } - - for (int i=0;i<unLights;++i) { - Light Li=objLights[i]; - float cosTheta = 0.0; - float atteunation = 1.0; - vec3 lightDirection = vec3(0.0); - if (Li.type == DIRECTIONAL_LIGHT) { - lightDirection = Li.parameter.xyz; - cosTheta = max(dot(normal, lightDirection), 0.0); - } - vec3 radiance = cosTheta * Li.color * Li.brightness; - rawCol += physBDRF(m, normal, lightDirection, Z) * radiance; - } - outColor=vec4(rawCol,1); - } - </script> - - <script id="shader-vs" type="x-shader/x-vertex">#version 300 es - precision mediump float; - in vec3 aVertexPosition; - in vec4 aVertexColor; - in vec3 aVertexNormal; - in int aVertexMaterialIndex; - - uniform mat4 uMMatrix; // model matrix - uniform mat4 uPMatrix; // projection matrix - uniform mat4 uVMatrix; // view matrix - - out vec4 vColor; - out vec3 vNormal; - flat out int vMaterialIndex; - - mat4 invdual(mat4 invec) { - return inverse(transpose(invec)); - } - void main(void) { - gl_Position=uPMatrix*uVMatrix*uMMatrix*vec4(aVertexPosition,1.0); - - mat4 invdualmat=invdual(uVMatrix*uMMatrix); - vec4 rawNormal=invdualmat*vec4(aVertexNormal, 0); - - vNormal=normalize(rawNormal.xyz); - - vColor=aVertexColor; - vMaterialIndex=aVertexMaterialIndex; - } - - </script> - - <script type="text/javascript" src="https://vectorgraphics.github.io/asymptote/webgl/gl-matrix-min-2.3.2.js"></script> - <script type="text/javascript" src="https://vectorgraphics.github.io/asymptote/webgl/glm-js-min-2.2.2.js"></script> - <script type="text/javascript" src="https://vectorgraphics.github.io/asymptote/webgl/arcball-min-0.01.js"></script> - <script type="text/javascript" src="gl.js"></script> - <script type="text/javascript"> diff --git a/graphics/asymptote/webgl/arcball-0.01.js b/graphics/asymptote/webgl/arcball-0.01.js deleted file mode 100644 index db6da0f81a..0000000000 --- a/graphics/asymptote/webgl/arcball-0.01.js +++ /dev/null @@ -1,67 +0,0 @@ -// double, double => rotation matrix -// require https://cdn.rawgit.com/humbletim/glm-js/31fd034b/build/glm-js.min.js - - -var arcballLib = { - arcball: function(oldmouse, newmouse) { - let oldMouseNew = [0, 0, 0]; - let newMouseNew = [0, 0, 0]; - - let testNorm = this.twonorm(oldmouse); - if (testNorm > 1) { - oldMouseNew[0] = oldmouse[0] / testNorm; - oldMouseNew[1] = oldmouse[1] / testNorm; - } else { - oldMouseNew[0] = oldmouse[0]; - oldMouseNew[1] = oldmouse[1]; - } - - let testNorm2 = this.twonorm(newmouse); - if (testNorm2 > 1) { - newMouseNew[0] = newmouse[0] / testNorm2; - newMouseNew[1] = newmouse[1] / testNorm2; - } else { - newMouseNew[0] = newmouse[0]; - newMouseNew[1] = newmouse[1]; - } - - var z1squared = 1 - (oldMouseNew[1] ** 2) - (oldMouseNew[0] ** 2); - if (z1squared < 0 && z1squared > -0.00001) { - z1squared = 0; - } - - var z2squared = 1 - (newMouseNew[1] ** 2) - (newMouseNew[0] ** 2); - if (z2squared < 0 && z2squared > -0.00001) { - z2squared = 0; - } - - - oldMouseNew[2] = Math.sqrt(z1squared); - newMouseNew[2] = Math.sqrt(z2squared); - - if (isNaN(oldMouseNew[2]) || isNaN(newMouseNew[2])) { - - alert('Error!'); - } - - - let oldMouseVec = glm.vec3(...oldMouseNew); - let newMouseVec = glm.vec3(...newMouseNew); - let axis = glm.normalize(glm.cross(oldMouseVec, newMouseVec)); - - // console.log(axis[0], axis[1], axis[2]); - - let angle = Math.acos(glm.dot(oldMouseVec, newMouseVec)); - - return [angle, axis] - - }, - - twonorm: function(v) { - let normSq = 0 - for (let i = 0; i < v.length; i++) { - normSq += (v[i] ** 2); - } - return Math.sqrt(normSq); - } -}
\ No newline at end of file diff --git a/graphics/asymptote/webgl/arcball-min-0.01.js b/graphics/asymptote/webgl/arcball-min-0.01.js deleted file mode 100644 index 9efc72fa4d..0000000000 --- a/graphics/asymptote/webgl/arcball-min-0.01.js +++ /dev/null @@ -1 +0,0 @@ -var arcballLib={arcball:function(oldmouse,newmouse){let oldMouseNew=[0,0,0];let newMouseNew=[0,0,0];let testNorm=this.twonorm(oldmouse);if(testNorm>1){oldMouseNew[0]=oldmouse[0]/testNorm;oldMouseNew[1]=oldmouse[1]/testNorm}else{oldMouseNew[0]=oldmouse[0];oldMouseNew[1]=oldmouse[1]}let testNorm2=this.twonorm(newmouse);if(testNorm2>1){newMouseNew[0]=newmouse[0]/testNorm2;newMouseNew[1]=newmouse[1]/testNorm2}else{newMouseNew[0]=newmouse[0];newMouseNew[1]=newmouse[1]}var z1squared=1-oldMouseNew[1]**2-oldMouseNew[0]**2;if(z1squared<0&&z1squared>-1e-5){z1squared=0}var z2squared=1-newMouseNew[1]**2-newMouseNew[0]**2;if(z2squared<0&&z2squared>-1e-5){z2squared=0}oldMouseNew[2]=Math.sqrt(z1squared);newMouseNew[2]=Math.sqrt(z2squared);if(isNaN(oldMouseNew[2])||isNaN(newMouseNew[2])){alert("Error!")}let oldMouseVec=glm.vec3(...oldMouseNew);let newMouseVec=glm.vec3(...newMouseNew);let axis=glm.normalize(glm.cross(oldMouseVec,newMouseVec));let angle=Math.acos(glm.dot(oldMouseVec,newMouseVec));return[angle,axis]},twonorm:function(v){let normSq=0;for(let i=0;i<v.length;i++){normSq+=v[i]**2}return Math.sqrt(normSq)}};
\ No newline at end of file diff --git a/graphics/asymptote/webgl/arcball.js b/graphics/asymptote/webgl/arcball.js deleted file mode 100644 index db6da0f81a..0000000000 --- a/graphics/asymptote/webgl/arcball.js +++ /dev/null @@ -1,67 +0,0 @@ -// double, double => rotation matrix -// require https://cdn.rawgit.com/humbletim/glm-js/31fd034b/build/glm-js.min.js - - -var arcballLib = { - arcball: function(oldmouse, newmouse) { - let oldMouseNew = [0, 0, 0]; - let newMouseNew = [0, 0, 0]; - - let testNorm = this.twonorm(oldmouse); - if (testNorm > 1) { - oldMouseNew[0] = oldmouse[0] / testNorm; - oldMouseNew[1] = oldmouse[1] / testNorm; - } else { - oldMouseNew[0] = oldmouse[0]; - oldMouseNew[1] = oldmouse[1]; - } - - let testNorm2 = this.twonorm(newmouse); - if (testNorm2 > 1) { - newMouseNew[0] = newmouse[0] / testNorm2; - newMouseNew[1] = newmouse[1] / testNorm2; - } else { - newMouseNew[0] = newmouse[0]; - newMouseNew[1] = newmouse[1]; - } - - var z1squared = 1 - (oldMouseNew[1] ** 2) - (oldMouseNew[0] ** 2); - if (z1squared < 0 && z1squared > -0.00001) { - z1squared = 0; - } - - var z2squared = 1 - (newMouseNew[1] ** 2) - (newMouseNew[0] ** 2); - if (z2squared < 0 && z2squared > -0.00001) { - z2squared = 0; - } - - - oldMouseNew[2] = Math.sqrt(z1squared); - newMouseNew[2] = Math.sqrt(z2squared); - - if (isNaN(oldMouseNew[2]) || isNaN(newMouseNew[2])) { - - alert('Error!'); - } - - - let oldMouseVec = glm.vec3(...oldMouseNew); - let newMouseVec = glm.vec3(...newMouseNew); - let axis = glm.normalize(glm.cross(oldMouseVec, newMouseVec)); - - // console.log(axis[0], axis[1], axis[2]); - - let angle = Math.acos(glm.dot(oldMouseVec, newMouseVec)); - - return [angle, axis] - - }, - - twonorm: function(v) { - let normSq = 0 - for (let i = 0; i < v.length; i++) { - normSq += (v[i] ** 2); - } - return Math.sqrt(normSq); - } -}
\ No newline at end of file diff --git a/graphics/asymptote/webgl/data.js b/graphics/asymptote/webgl/data.js deleted file mode 100644 index 915dc35619..0000000000 --- a/graphics/asymptote/webgl/data.js +++ /dev/null @@ -1,47 +0,0 @@ -var p = [ - [0, 0, 1.6], - [1, 1.333333333333333, 0], - [0, 0.666666666666667, 0], - [0, 1, 0], - [0.333333333333333, 0, 0], - [0.333333333333333, 0.333333333333333, 0], - [0.333333333333333, 0.666666666666667, 0], - [0.333333333333333, 1, 0], - [0.666666666666667, 0, 0], - [0.666666666666667, 0.333333333333333, 0], - [0.666666666666667, 0.666666666666667, 0], - [0.666666666666667, 1, 0], - [1, 0, 0], - [1, 0.333333333333333, 0], - [1, 0.666666666666667, 0], - [1, 1, 0.1] - ]; - - var materialIndex = 0; - - var objMaterial = new Material( - baseColor = [1, 1, 0, 1], - emissive = [0, 0, 0, 1], - specular = [1, 1, 1, 1], - roughness = 0.15, - metallic = 0, - f0 = 0.04 - ); - - // Lighting parameters - var L = [0.447735768366173, 0.497260947684137, 0.743144825477394]; - var Ambient = [0.1, 0.1, 0.1]; - var Diffuse = [0.8, 0.8, 0.8, 1]; - var Specular = [0.7, 0.7, 0.7, 1]; - var specularfactor = 3; - - // Material parameters - var emissive = [0, 0, 0, 1]; - var ambient = [0, 0, 0, 1]; - var diffuse = [1, 0, 0, 1]; - var specular = [0.75, 0.75, 0.75, 1]; - var shininess = 0.5; - - var cameraPos = vec3.fromValues(0, 0, 2); - var cameraLookAt = vec3.fromValues(0, 0, 0); - var cameraUp = vec3.fromValues(1, 0, 0); diff --git a/graphics/asymptote/webgl/gl-0.01.js b/graphics/asymptote/webgl/gl-0.01.js deleted file mode 100644 index 079b1bb70e..0000000000 --- a/graphics/asymptote/webgl/gl-0.01.js +++ /dev/null @@ -1,738 +0,0 @@ -// Contains code from http: //learningwebgl.com/blog/ ? p=28#triangle-vertex-positions -// modified to produce a subdivision algorithm for rendering Bezier -// patches with WebGL -var gl; - -function initGL(canvas) { - try { - gl=canvas.getContext("experimental-webgl"); - gl.viewportWidth=canvas.width; - gl.viewportHeight=canvas.height; - } catch(e) {} - if(!gl) { - alert("Could not initialise WebGL, sorry : -("); - } -} - -function getShader(gl, id) { - var shaderScript=document.getElementById(id); - if(!shaderScript) { - return null; - } - var str=""; - var k=shaderScript.firstChild; - while(k) { - if(k.nodeType == 3) { - str += k.textContent; - } - k=k.nextSibling; - } - var shader; - if(shaderScript.type == "x-shader/x-fragment") { - shader=gl.createShader(gl.FRAGMENT_SHADER); - } else if(shaderScript.type == "x-shader/x-vertex") { - shader=gl.createShader(gl.VERTEX_SHADER); - } else { - return null; - } - gl.shaderSource(shader,str); - gl.compileShader(shader); - if(!gl.getShaderParameter(shader,gl.COMPILE_STATUS)) { - alert(gl.getShaderInfoLog(shader)); - return null; - } - return shader; -} - -var shaderProgram; - -function initShaders() { - var fragmentShader=getShader(gl,"shader-fs"); - var vertexShader=getShader(gl,"shader-vs"); - shaderProgram=gl.createProgram(); - gl.attachShader(shaderProgram,vertexShader); - gl.attachShader(shaderProgram,fragmentShader); - gl.linkProgram(shaderProgram); - if(!gl.getProgramParameter(shaderProgram,gl.LINK_STATUS)) { - alert("Could not initialise shaders"); - } - gl.useProgram(shaderProgram); - shaderProgram.vertexPositionAttribute=gl.getAttribLocation(shaderProgram,"aVertexPosition"); - gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute); - shaderProgram.vertexColorAttribute=gl.getAttribLocation(shaderProgram,"aVertexColor"); - gl.enableVertexAttribArray(shaderProgram.vertexColorAttribute); - shaderProgram.pMatrixUniform=gl.getUniformLocation(shaderProgram,"uPMatrix"); - shaderProgram.mvMatrixUniform=gl.getUniformLocation(shaderProgram,"uMVMatrix"); -} -var mvMatrix=mat4.create(); -var pMatrix=mat4.create(); - -function setMatrixUniforms() { - gl.uniformMatrix4fv(shaderProgram.pMatrixUniform,false,pMatrix); - gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform,false,mvMatrix); -} - -var VertexBuffer; -var ColorBuffer; - -var vertices=new Array(); -var colors=new Array(); -var indices=new Array(); -var nvertices=0; - -var mvMatrix=mat4.create(); -var translOffset=[0,0,0]; -var zoomFactor=1; - -var mvMatrixStack=[] ; -var pMatrix=mat4.create(); - -var localRotation=mat4.create(); - -function mvPushMatrix() { - var copy=mat4.create(); - mat4.set(mvMatrix,copy); - mvMatrixStack.push(copy); -} - -function mvPopMatrix() { - if(mvMatrixStack.length == 0) { - throw "Invalid popMatrix!"; - } - mvMatrix=mvMatrixStack.pop(); -} - -function degToRad(degrees) { - return degrees*Math.PI/180; -} - -var redraw=true; -var mouseDownOrTouchActive=false; -var lastMouseX=null; -var lastMouseY=null; -var touchID=null; - - -var center=[0,0,1]; -var centerInv=[0,0,-1]; - -var rotationMatLocal=mat4.create(); -var rotationMatrix=mat4.create(); -mat4.identity(rotationMatrix); - -function handleMouseDown(event) { - mouseDownOrTouchActive=true; - lastMouseX=event.clientX; - lastMouseY=event.clientY; -} - -function handleTouchStart(evt) { - evt.preventDefault(); - var touches=evt.targetTouches; - - if(touches.length == 1 && !mouseDownOrTouchActive) { - touchId=touches[0].identifier; - lastMouseX=touches[0].pageX, - lastMouseY=touches[0].pageY; - } -} - -function handleMouseUpOrTouchEnd(event) { - mouseDownOrTouchActive=false; -} - -function processDrag(newX, newY, pan=false) { - let lastX=(lastMouseX-400)/400; - let lastY=(lastMouseY-400)/400; - - let rawX=(newX-400)/400; - let rawY=(newY-400)/400; - - if(!pan) { - let [angle,axis]=arcballLib.arcball([lastX,-lastY],[rawX,-rawY]); - let tmpMatrix=mat4.create() - mat4.identity(tmpMatrix) - mat4.rotate(tmpMatrix,tmpMatrix,angle,[axis[0],axis[1],axis[2]]) - mat4.multiply(rotationMatrix,tmpMatrix,rotationMatrix); - } else { - translOffset[0] +=(rawX-lastX); - translOffset[1] -=(rawY-lastY); - } - lastMouseX=newX; - lastMouseY=newY; - redraw=true; -} - -function handleKey(key) { - var keycode=key.key; - var rotate=true; - var axis=[0,0,1]; - switch(keycode) { - case "w": - axis=[-1,0,0]; - break; - case "d": - axis=[0,1,0]; - break; - case "a": - axis=[0,-1,0]; - break; - case "s": - axis=[1,0,0]; - break; - - default: - rotate=false; - break; - } - - if(rotate) { - mat4.rotate(rotationMatrix,rotationMatrix,0.1,axis); - redraw=true; - } - -} - -function handleMouseWheel(event) { - zoomFactor -= event.deltaY/100; - - if(zoomFactor < 0) { - zoomFactor=0; - } else if(zoomFactor > 100) { - zoomFactor=100; - } - - res=zoomFactor*0.001; - redraw=true; -} - -function handleMouseMove(event) { - if(!mouseDownOrTouchActive) { - return; - } - - var newX=event.clientX; - var newY=event.clientY; - - processDrag(newX,newY,event.getModifierState("Alt")); -} - -function handleTouchMove(evt) { - evt.preventDefault(); - var touches=evt.targetTouches; - - if(touches.length == 1 && touchId == touches[0].identifier) { - var newX=touches[0].pageX; - var newY=touches[0].pageY; - processDrag(newX,newY); - } -} - -// Prepare canvas for drawing -function sceneSetup() { - gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); - mat4.perspective(pMatrix,45,gl.viewportWidth/gl.viewportHeight,0.1,100.0); - mat4.identity(mvMatrix); - - mat4.translate(mvMatrix,mvMatrix,centerInv); - mat4.multiply(mvMatrix,mvMatrix,rotationMatrix); - mat4.scale(mvMatrix,mvMatrix,[zoomFactor,zoomFactor,zoomFactor]); - mat4.translate(mvMatrix,mvMatrix,center); - - mat4.translate(mvMatrix,mvMatrix,translOffset) -} - -var indexExt; - -// Create buffer data for the patch and its subdivisions to be pushed to the graphics card -//Takes as an argument the array of vertices that define the patch to be drawn -// Using the vertex position buffer of the above function,draw patch. -function setBuffer() { - VertexBuffer=gl.createBuffer(); - VertexBuffer.itemSize=3; - - ColorBuffer=gl.createBuffer(); - ColorBuffer.itemSize=4; - - indexBuffer=gl.createBuffer(); - indexBuffer.itemSize=1; -} - -function drawBuffer() { - gl.bindBuffer(gl.ARRAY_BUFFER,VertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(vertices),gl.STATIC_DRAW); - gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, - VertexBuffer.itemSize,gl.FLOAT,false,0,0); - VertexBuffer.numItems=nvertices; - - gl.bindBuffer(gl.ARRAY_BUFFER,ColorBuffer); - gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(colors),gl.STATIC_DRAW); - gl.vertexAttribPointer(shaderProgram.vertexColorAttribute, - ColorBuffer.itemSize,gl.FLOAT,false,0,0); - ColorBuffer.numItems=nvertices; - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, - indexExt ? new Uint32Array(indices) : new Uint16Array(indices), - gl.STATIC_DRAW); - indexBuffer.numItems=indices.length; - gl.drawElements(gl.TRIANGLES,indexBuffer.numItems, - indexExt ? gl.UNSIGNED_INT : gl.UNSIGNED_SHORT,0); - vertices=[]; - colors=[]; - indices=[]; - nvertices=0; -} - -var pixel=1.0; // Adaptive rendering constant. -var FillFactor=0.1; -var BezierFactor=0.4; -//var res=0.0005; // Temporary -var res=0.001; // Temporary -var res2=res*res; -var Epsilon=0.1*res; -var epsilon=0; -var Fuzz=1000*Number.EPSILON; -var Fuzz2=Fuzz*Fuzz; - -function Split3(z0, c0, c1, z1) { - this.m0=new Array(3); - this.m2=new Array(3); - this.m3=new Array(3); - this.m4=new Array(3); - this.m5=new Array(3); - for(var i=0; i < 3; ++i) { - this.m0[i]=0.5*(z0[i]+c0[i]); - var m1=0.5*(c0[i]+c1[i]); - this.m2[i]=0.5*(c1[i]+z1[i]); - this.m3[i]=0.5*(this.m0[i]+m1); - this.m4[i]=0.5*(m1+this.m2[i]); - this.m5[i]=0.5*(this.m3[i]+this.m4[i]); - } -} - -function unit(v) { - var norm=Math.sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]); - norm=(norm != 0) ? 1/norm : 1; - return [v[0]*norm,v[1]*norm,v[2]*norm]; -} - -// Store the vertex v and its color vector c in the buffer. -function vertex(v,c) { - vertices.push(v[0]); - vertices.push(v[1]); - vertices.push(v[2]); - - colors.push(c[0]); - colors.push(c[1]); - colors.push(c[2]); - colors.push(c[3]); - return nvertices++; -} - -function abs2(v) { - return v[0]*v[0]+v[1]*v[1]+v[2]*v[2]; -} - -function dot(u, v) { - return u[0]*v[0]+u[1]*v[1]+u[2]*v[2]; -} - -function cross(u, v) { - return [u[1]*v[2]-u[2]*v[1], - u[2]*v[0]-u[0]*v[2], - u[0]*v[1]-u[1]*v[0] - ]; -} - -function normal(left3, left2, left1, middle, right1, right2, right3) { - var u0=right1[0]-middle[0]; - var v0=left1[0]-middle[0]; - var u1=right1[1]-middle[1]; - var v1=left1[1]-middle[1]; - var u2=right1[2]-middle[2]; - var v2=left1[2]-middle[2]; - var n=[ - u1*v2-u2*v1, - u2*v0-u0*v2, - u0*v1-u1*v0 - ]; - if(abs2(n) > epsilon) - return unit(n); - - var lp=[v0,v1,v2]; - var rp=[u0,u1,u2]; - var lpp=[middle[0]+left2[0]-2*left1[0], - middle[1]+left2[1]-2*left1[1], - middle[2]+left2[2]-2*left1[2] - ]; - var rpp=[middle[0]+right2[0]-2*right1[0], - middle[1]+right2[1]-2*right1[1], - middle[2]+right2[2]-2*right1[2] - ]; - var a=cross(rpp,lp); - var b=cross(rp,lpp); - n=[a[0]+b[0], - a[1]+b[1], - a[2]+b[2] - ]; - if(abs2(n) > epsilon) - return unit(n); - - var lppp=[left3[0]-middle[0]+3*(left1[0]-left2[0]), - left3[1]-middle[1]+3*(left1[1]-left2[1]), - left3[2]-middle[2]+3*(left1[2]-left2[2]) - ]; - var rppp=[right3[0]-middle[0]+3*(right1[0]-right2[0]), - right3[1]-middle[1]+3*(right1[1]-right2[1]), - right3[2]-middle[2]+3*(right1[2]-right2[2]) - ]; - a=cross(rpp,lpp); - b=cross(rp,lppp); - var c=cross(rppp,lp); - var d=cross(rppp,lpp); - var e=cross(rpp,lppp); - var f=cross(rppp,lppp); - return unit([9*a[0]+3*(b[0]+c[0]+d[0]+e[0])+f[0], - 9*a[1]+3*(b[1]+c[1]+d[1]+e[1])+f[1], - 9*a[2]+3*(b[2]+c[2]+d[2]+e[2])+f[2] - ]); -} - -// return the maximum distance squared of points c0 and c1 from -// the respective internal control points of z0--z1. -function Straightness(z0,c0,c1,z1) -{ - var third=1.0/3.0; - var v=[third*(z1[0]-z0[0]),third*(z1[1]-z0[1]),third*(z1[2]-z0[2])]; - return Math.max(abs2([c0[0]-v[0]-z0[0],c0[1]-v[1]-z0[1],c0[2]-v[2]-z0[2]]), - abs2([z1[0]-v[0]-c1[0],z1[1]-v[1]-c1[1],z1[2]-v[2]-c1[2]])); -} - -// return the maximum perpendicular distance squared of points c0 and c1 -// from z0--z1. -function Distance1(z0, c0, c1, z1) { - var Z0=[c0[0]-z0[0],c0[1]-z0[1],c0[2]-z0[2]]; - var Q=unit([z1[0]-z0[0],z1[1]-z0[1],z1[2]-z0[2]]); - var Z1=[c1[0]-z0[0],c1[1]-z0[1],c1[2]-z0[2]]; - var p0=dot(Z0,Q); - var p1=dot(Z1,Q); - return Math.max(abs2([Z0[0]-p0*Q[0],Z0[1]-p0*Q[1],Z0[2]-p0*Q[2]]), - abs2([Z1[0]-p1*Q[0],Z1[1]-p1*Q[1],Z1[2]-p1*Q[2]])); -} - -// return the perpendicular distance squared of a point z from the plane -// through u with unit normal n. -function Distance2(z, u, n) { - var d=dot([z[0]-u[0],z[1]-u[1],z[2]-u[2]],n); - return d*d; -} - -function Distance(p) { - var p0=p[0]; - var p3=p[3]; - var p12=p[12]; - var p15=p[15]; - - // Check the flatness of the quad. - var d=Distance2(p15,p0,normal(p3,p[2],p[1],p0,p[4],p[8],p12)); - - // Determine how straight the edges are. - d=Math.max(d,Straightness(p0,p[1],p[2],p3)); - d=Math.max(d,Straightness(p0,p[4],p[8],p12)); - d=Math.max(d,Straightness(p3,p[7],p[11],p15)); - d=Math.max(d,Straightness(p12,p[13],p[14],p15)); - - // Determine how straight the interior control curves are. - d=Math.max(d,Straightness(p[4],p[5],p[6],p[7])); - d=Math.max(d,Straightness(p[8],p[9],p[10],p[11])); - d=Math.max(d,Straightness(p[1],p[5],p[9],p[13])); - return Math.max(d,Straightness(p[2],p[6],p[10],p[14])); -} - -var k=1; -// Return color associated with unit normal vector n. -function color(n) { - var Ldotn=L[0]*n[0]+L[1]*n[1]+L[2]*n[2]; - if(Ldotn < 0) Ldotn=0; - var p=[emissive[0]+ambient[0]*Ambient[0]+Ldotn*diffuse[0]*Diffuse[0], - emissive[1]+ambient[1]*Ambient[1]+Ldotn*diffuse[1]*Diffuse[1], - emissive[2]+ambient[2]*Ambient[2]+Ldotn*diffuse[2]*Diffuse[2] - ]; - var s=shininess*128; - var H=unit([L[0],L[1],L[2]+1]); - var f=Math.pow(H[0]*n[0]+H[1]*n[1]+H[2]*n[2],s); - - if(Ldotn > 0) // Phong-Blinn model of specular reflection - p=[p[0]+f*specular[0]*Specular[0],p[1]+f*specular[1]*Specular[1], - p[2]+f*specular[2]*Specular[2] - ]; - - return [p[0],p[1],p[2],1]; -} - -function render(p, I0, I1, I2, I3, P0, P1, P2, P3, flat0, flat1, flat2, flat3, - C0, C1, C2, C3) { - if(Distance(p) < res2) { // Patch is flat - indices.push(I0); - indices.push(I1); - indices.push(I2); - - indices.push(I0); - indices.push(I2); - indices.push(I3); - return; - } - - var p0=p[0]; - var p3=p[3]; - var p12=p[12]; - var p15=p[15]; - - var c0=new Split3(p0,p[1],p[2],p3); - var c1=new Split3(p[4],p[5],p[6],p[7]); - var c2=new Split3(p[8],p[9],p[10],p[11]); - var c3=new Split3(p12,p[13],p[14],p15); - var c4=new Split3(p0,p[4],p[8],p12); - var c5=new Split3(c0.m0,c1.m0,c2.m0,c3.m0); - var c6=new Split3(c0.m3,c1.m3,c2.m3,c3.m3); - var c7=new Split3(c0.m5,c1.m5,c2.m5,c3.m5); - var c8=new Split3(c0.m4,c1.m4,c2.m4,c3.m4); - var c9=new Split3(c0.m2,c1.m2,c2.m2,c3.m2); - var c10=new Split3(p3,p[7],p[11],p15); - - var s0=[p0,c0.m0,c0.m3,c0.m5,c4.m0,c5.m0,c6.m0,c7.m0, - c4.m3,c5.m3,c6.m3,c7.m3,c4.m5,c5.m5,c6.m5,c7.m5 - ]; - var s1=[c4.m5,c5.m5,c6.m5,c7.m5,c4.m4,c5.m4,c6.m4,c7.m4, - c4.m2,c5.m2,c6.m2,c7.m2,p12,c3.m0,c3.m3,c3.m5 - ]; - var s2=[c7.m5,c8.m5,c9.m5,c10.m5,c7.m4,c8.m4,c9.m4,c10.m4, - c7.m2,c8.m2,c9.m2,c10.m2,c3.m5,c3.m4,c3.m2,p15 - ]; - var s3=[c0.m5,c0.m4,c0.m2,p3,c7.m0,c8.m0,c9.m0,c10.m0, - c7.m3,c8.m3,c9.m3,c10.m3,c7.m5,c8.m5,c9.m5,c10.m5 - ]; - - var m4=s0[15]; - - var n0=normal(s0[0],s0[4],s0[8],s0[12],s0[13],s0[14],s0[15]); - if(n0 == 0.0) { - n0=normal(s0[0],s0[4],s0[8],s0[12],s0[11],s0[7],s0[3]); - if(n0 == 0.0) n0=normal(s0[3],s0[2],s0[1],s0[0],s0[13],s0[14],s0[15]); - } - - var n1=normal(s1[12],s1[13],s1[14],s1[15],s1[11],s1[7],s1[3]); - if(n1 == 0.0) { - n1=normal(s1[12],s1[13],s1[14],s1[15],s1[2],s1[1],s1[0]); - if(n1 == 0.0) n1=normal(s1[0],s1[4],s1[8],s1[12],s1[11],s1[7],s1[3]); - } - - var n2=normal(s2[15],s2[11],s2[7],s2[3],s2[2],s2[1],s2[0]); - if(n2 == 0.0) { - n2=normal(s2[15],s2[11],s2[7],s2[3],s2[4],s2[8],s2[12]); - if(n2 == 0.0) n2=normal(s2[12],s2[13],s2[14],s2[15],s2[2],s2[1],s2[0]); - } - - var n3=normal(s3[3],s3[2],s3[1],s3[0],s3[4],s3[8],s3[12]); - if(n3 == 0.0) { - n3=normal(s3[3],s3[2],s3[1],s3[0],s3[13],s3[14],s3[15]); - if(n3 == 0.0) n3=normal(s3[15],s3[11],s3[7],s3[3],s3[4],s3[8],s3[12]); - } - - var n4=normal(s2[3],s2[2],s2[1],m4,s2[4],s2[8],s2[12]); - - var m0,m1,m2,m3; - - // A kludge to remove subdivision cracks, only applied the first time - // an edge is found to be flat before the rest of the subpatch is. - if(flat0) - m0=[0.5*(P0[0]+P1[0]),0.5*(P0[1]+P1[1]),0.5*(P0[2]+P1[2])]; - else { - if((flat0=Distance1(p0,p[4],p[8],p12) < res2)) { - var u=s0[12]; - var v=s2[3]; - var e=unit([u[0]-v[0],u[1]-v[1],u[2]-v[2]]); - m0=[0.5*(P0[0]+P1[0])+Epsilon*e[0],0.5*(P0[1]+P1[1])+Epsilon*e[1], - 0.5*(P0[2]+P1[2])+Epsilon*e[2] - ]; - } else - m0=s0[12]; - } - - if(flat1) - m1=[0.5*(P1[0]+P2[0]),0.5*(P1[1]+P2[1]),0.5*(P1[2]+P2[2])]; - else { - if((flat1=Distance1(p12,p[13],p[14],p15) < res2)) { - var u=s1[15]; - var v=s3[0]; - var e=unit([u[0]-v[0],u[1]-v[1],u[2]-v[2]]); - m1=[0.5*(P1[0]+P2[0])+Epsilon*e[0],0.5*(P1[1]+P2[1])+Epsilon*e[1], - 0.5*(P1[2]+P2[2])+Epsilon*e[2] - ]; - } else - m1=s1[15]; - } - - if(flat2) - m2=[0.5*(P2[0]+P3[0]),0.5*(P2[1]+P3[1]),0.5*(P2[2]+P3[2])]; - else { - if((flat2=Distance1(p15,p[11],p[7],p3) < res2)) { - var u=s2[3]; - var v=s0[12]; - var e=unit([u[0]-v[0],u[1]-v[1],u[2]-v[2]]); - m2=[0.5*(P2[0]+P3[0])+Epsilon*e[0],0.5*(P2[1]+P3[1])+Epsilon*e[1], - 0.5*(P2[2]+P3[2])+Epsilon*e[2] - ]; - } else - m2=s2[3]; - } - - if(flat3) - m3=[0.5*(P3[0]+P0[0]),0.5*(P3[1]+P0[1]),0.5*(P3[2]+P0[2])]; - else { - if((flat3=Distance1(p3,p[2],p[1],p0) < res2)) { - var u=s3[0]; - var v=s1[15]; - var e=unit([u[0]-v[0],u[1]-v[1],u[2]-v[2]]); - m3=[0.5*(P3[0]+P0[0])+Epsilon*e[0], - 0.5*(P3[1]+P0[1])+Epsilon*e[1], - 0.5*(P3[2]+P0[2])+Epsilon*e[2] - ]; - } else - m3=s3[0]; - } - - // document.write(n0); - // document.write(" < br > "); - - { - /* - var c0=new Array(4); - var c1=new Array(4); - var c2=new Array(4); - var c3=new Array(4); - var c4=new Array(4); - - for(var i=0; i < 4; ++i) { - c0[i]=0.5*(C0[i]+C1[i]); - c1[i]=0.5*(C1[i]+C2[i]); - c2[i]=0.5*(C2[i]+C3[i]); - c3[i]=0.5*(C3[i]+C0[i]); - c4[i]=0.5*(c0[i]+c2[i]); - } - */ - - var c0=color(n0); - var c1=color(n1); - var c2=color(n2); - var c3=color(n3); - var c4=color(n4); - - - var i0=vertex(m0,c0); - var i1=vertex(m1,c1); - var i2=vertex(m2,c2); - var i3=vertex(m3,c3); - var i4=vertex(m4,c4); - - render(s0,I0,i0,i4,i3,P0,m0,m4,m3,flat0,false,false,flat3, - C0,c0,c4,c3); - render(s1,i0,I1,i1,i4,m0,P1,m1,m4,flat0,flat1,false,false, - c0,C1,c1,c4); - render(s2,i4,i1,I2,i2,m4,m1,P2,m2,false,flat1,flat2,false, - c4,c1,C2,c2); - render(s3,i3,i4,i2,I3,m3,m4,m2,P3,false,false,flat2,flat3, - c3,c4,c2,C3); - } -} - - -function draw(p) { - var p0=p[0]; - var p3=p[3]; - var p12=p[12]; - var p15=p[15]; - - epsilon=0; - for(var i=1; i < 16; ++i) - epsilon=Math.max(epsilon, - abs2([p[i][0]-p0[0],p[i][1]-p0[1],p[i][2]-p0[2]])); - epsilon *= Fuzz2; - - var n0=normal(p3,p[2],p[1],p0,p[4],p[8],p12); - var n1=normal(p0,p[4],p[8],p12,p[13],p[14],p15); - var n2=normal(p12,p[13],p[14],p15,p[11],p[7],p3); - var n3=normal(p15,p[11],p[7],p3,p[2],p[1],p0); - - var c0=color(n0); - var c1=color(n1); - var c2=color(n2); - var c3=color(n3); - - var i0=vertex(p0,c0); - var i1=vertex(p12,c1); - var i2=vertex(p15,c2); - var i3=vertex(p3,c3); - - render(p,i0,i1,i2,i3,p0,p12,p15,p3,false,false,false,false, - c0,c1,c2,c3); - - drawBuffer(); -} - -var p=[]; - -function tick() { - requestAnimationFrame(tick); - if(redraw) { - sceneSetup(); - mat4.translate(mvMatrix,mvMatrix,[-0.5,-0.5,-1.5]); - setMatrixUniforms(); - for(var i=0; i < p.length; ++i) - draw(p[i]); - redraw=false; - } -} - -function webGLStart() { - var canvas=document.getElementById("Asymptote"); - initGL(canvas); - initShaders(); - gl.clearColor(0.0,0.0,0.0,1.0); - gl.enable(gl.DEPTH_TEST); - - indexExt=gl.getExtension("OES_element_index_uint"); - - gl.viewport(0,0,gl.viewportWidth,gl.viewportHeight); - setBuffer(); - - canvas.onmousedown=handleMouseDown; - document.onmouseup=handleMouseUpOrTouchEnd; - document.onmousemove=handleMouseMove; - canvas.onkeydown=handleKey; - document.onwheel=handleMouseWheel; - - canvas.addEventListener("touchstart",handleTouchStart,false); - canvas.addEventListener("touchend",handleMouseUpOrTouchEnd,false); - canvas.addEventListener("touchcancel",handleMouseUpOrTouchEnd,false); - canvas.addEventListener("touchleave",handleMouseUpOrTouchEnd,false); - canvas.addEventListener("touchmove",handleTouchMove,false); - - tick(); -} - - -// Lighting parameters -var L = [0.447735768366173, 0.497260947684137, 0.743144825477394]; -var Ambient = [0.1, 0.1, 0.1]; -var Diffuse = [0.8, 0.8, 0.8, 1]; -var Specular = [0.7, 0.7, 0.7, 1]; -var specularfactor = 3; - -// Material parameters -var emissive = [0, 0, 0, 1]; -var ambient = [1, 1, 1, 1]; -var diffuse = [0, 1, 0, 1]; -var specular = [0.75, 0.75, 0.75, 1]; -var shininess = 0.5; diff --git a/graphics/asymptote/webgl/gl-matrix-min-2.3.2.js b/graphics/asymptote/webgl/gl-matrix-min-2.3.2.js deleted file mode 100644 index 84476b6061..0000000000 --- a/graphics/asymptote/webgl/gl-matrix-min-2.3.2.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * @fileoverview gl-matrix - High performance matrix and vector operations - * @author Brandon Jones - * @author Colin MacKenzie IV - * @version 2.3.2 - */ - -/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. */ - -!function(t,a){if("object"==typeof exports&&"object"==typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var n=a();for(var r in n)("object"==typeof exports?exports:t)[r]=n[r]}}(this,function(){return function(t){function a(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return t[r].call(o.exports,o,o.exports,a),o.loaded=!0,o.exports}var n={};return a.m=t,a.c=n,a.p="",a(0)}([function(t,a,n){a.glMatrix=n(1),a.mat2=n(2),a.mat2d=n(3),a.mat3=n(4),a.mat4=n(5),a.quat=n(6),a.vec2=n(9),a.vec3=n(7),a.vec4=n(8)},function(t,a){var n={};n.EPSILON=1e-6,n.ARRAY_TYPE="undefined"!=typeof Float32Array?Float32Array:Array,n.RANDOM=Math.random,n.ENABLE_SIMD=!1,n.SIMD_AVAILABLE=n.ARRAY_TYPE===Float32Array&&"SIMD"in this,n.USE_SIMD=n.ENABLE_SIMD&&n.SIMD_AVAILABLE,n.setMatrixArrayType=function(t){n.ARRAY_TYPE=t};var r=Math.PI/180;n.toRadian=function(t){return t*r},n.equals=function(t,a){return Math.abs(t-a)<=n.EPSILON*Math.max(1,Math.abs(t),Math.abs(a))},t.exports=n},function(t,a,n){var r=n(1),o={};o.create=function(){var t=new r.ARRAY_TYPE(4);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},o.clone=function(t){var a=new r.ARRAY_TYPE(4);return a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=t[3],a},o.copy=function(t,a){return t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[3],t},o.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},o.fromValues=function(t,a,n,o){var u=new r.ARRAY_TYPE(4);return u[0]=t,u[1]=a,u[2]=n,u[3]=o,u},o.set=function(t,a,n,r,o){return t[0]=a,t[1]=n,t[2]=r,t[3]=o,t},o.transpose=function(t,a){if(t===a){var n=a[1];t[1]=a[2],t[2]=n}else t[0]=a[0],t[1]=a[2],t[2]=a[1],t[3]=a[3];return t},o.invert=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=n*u-o*r;return l?(l=1/l,t[0]=u*l,t[1]=-r*l,t[2]=-o*l,t[3]=n*l,t):null},o.adjoint=function(t,a){var n=a[0];return t[0]=a[3],t[1]=-a[1],t[2]=-a[2],t[3]=n,t},o.determinant=function(t){return t[0]*t[3]-t[2]*t[1]},o.multiply=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=n[0],M=n[1],s=n[2],i=n[3];return t[0]=r*e+u*M,t[1]=o*e+l*M,t[2]=r*s+u*i,t[3]=o*s+l*i,t},o.mul=o.multiply,o.rotate=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=Math.sin(n),M=Math.cos(n);return t[0]=r*M+u*e,t[1]=o*M+l*e,t[2]=r*-e+u*M,t[3]=o*-e+l*M,t},o.scale=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=n[0],M=n[1];return t[0]=r*e,t[1]=o*e,t[2]=u*M,t[3]=l*M,t},o.fromRotation=function(t,a){var n=Math.sin(a),r=Math.cos(a);return t[0]=r,t[1]=n,t[2]=-n,t[3]=r,t},o.fromScaling=function(t,a){return t[0]=a[0],t[1]=0,t[2]=0,t[3]=a[1],t},o.str=function(t){return"mat2("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},o.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2))},o.LDU=function(t,a,n,r){return t[2]=r[2]/r[0],n[0]=r[0],n[1]=r[1],n[3]=r[3]-t[2]*n[1],[t,a,n]},o.add=function(t,a,n){return t[0]=a[0]+n[0],t[1]=a[1]+n[1],t[2]=a[2]+n[2],t[3]=a[3]+n[3],t},o.subtract=function(t,a,n){return t[0]=a[0]-n[0],t[1]=a[1]-n[1],t[2]=a[2]-n[2],t[3]=a[3]-n[3],t},o.sub=o.subtract,o.exactEquals=function(t,a){return t[0]===a[0]&&t[1]===a[1]&&t[2]===a[2]&&t[3]===a[3]},o.equals=function(t,a){var n=t[0],o=t[1],u=t[2],l=t[3],e=a[0],M=a[1],s=a[2],i=a[3];return Math.abs(n-e)<=r.EPSILON*Math.max(1,Math.abs(n),Math.abs(e))&&Math.abs(o-M)<=r.EPSILON*Math.max(1,Math.abs(o),Math.abs(M))&&Math.abs(u-s)<=r.EPSILON*Math.max(1,Math.abs(u),Math.abs(s))&&Math.abs(l-i)<=r.EPSILON*Math.max(1,Math.abs(l),Math.abs(i))},o.multiplyScalar=function(t,a,n){return t[0]=a[0]*n,t[1]=a[1]*n,t[2]=a[2]*n,t[3]=a[3]*n,t},o.multiplyScalarAndAdd=function(t,a,n,r){return t[0]=a[0]+n[0]*r,t[1]=a[1]+n[1]*r,t[2]=a[2]+n[2]*r,t[3]=a[3]+n[3]*r,t},t.exports=o},function(t,a,n){var r=n(1),o={};o.create=function(){var t=new r.ARRAY_TYPE(6);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},o.clone=function(t){var a=new r.ARRAY_TYPE(6);return a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=t[3],a[4]=t[4],a[5]=t[5],a},o.copy=function(t,a){return t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[3],t[4]=a[4],t[5]=a[5],t},o.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},o.fromValues=function(t,a,n,o,u,l){var e=new r.ARRAY_TYPE(6);return e[0]=t,e[1]=a,e[2]=n,e[3]=o,e[4]=u,e[5]=l,e},o.set=function(t,a,n,r,o,u,l){return t[0]=a,t[1]=n,t[2]=r,t[3]=o,t[4]=u,t[5]=l,t},o.invert=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=a[4],e=a[5],M=n*u-r*o;return M?(M=1/M,t[0]=u*M,t[1]=-r*M,t[2]=-o*M,t[3]=n*M,t[4]=(o*e-u*l)*M,t[5]=(r*l-n*e)*M,t):null},o.determinant=function(t){return t[0]*t[3]-t[1]*t[2]},o.multiply=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=n[0],i=n[1],c=n[2],h=n[3],S=n[4],I=n[5];return t[0]=r*s+u*i,t[1]=o*s+l*i,t[2]=r*c+u*h,t[3]=o*c+l*h,t[4]=r*S+u*I+e,t[5]=o*S+l*I+M,t},o.mul=o.multiply,o.rotate=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=Math.sin(n),i=Math.cos(n);return t[0]=r*i+u*s,t[1]=o*i+l*s,t[2]=r*-s+u*i,t[3]=o*-s+l*i,t[4]=e,t[5]=M,t},o.scale=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=n[0],i=n[1];return t[0]=r*s,t[1]=o*s,t[2]=u*i,t[3]=l*i,t[4]=e,t[5]=M,t},o.translate=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=n[0],i=n[1];return t[0]=r,t[1]=o,t[2]=u,t[3]=l,t[4]=r*s+u*i+e,t[5]=o*s+l*i+M,t},o.fromRotation=function(t,a){var n=Math.sin(a),r=Math.cos(a);return t[0]=r,t[1]=n,t[2]=-n,t[3]=r,t[4]=0,t[5]=0,t},o.fromScaling=function(t,a){return t[0]=a[0],t[1]=0,t[2]=0,t[3]=a[1],t[4]=0,t[5]=0,t},o.fromTranslation=function(t,a){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=a[0],t[5]=a[1],t},o.str=function(t){return"mat2d("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+")"},o.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+1)},o.add=function(t,a,n){return t[0]=a[0]+n[0],t[1]=a[1]+n[1],t[2]=a[2]+n[2],t[3]=a[3]+n[3],t[4]=a[4]+n[4],t[5]=a[5]+n[5],t},o.subtract=function(t,a,n){return t[0]=a[0]-n[0],t[1]=a[1]-n[1],t[2]=a[2]-n[2],t[3]=a[3]-n[3],t[4]=a[4]-n[4],t[5]=a[5]-n[5],t},o.sub=o.subtract,o.multiplyScalar=function(t,a,n){return t[0]=a[0]*n,t[1]=a[1]*n,t[2]=a[2]*n,t[3]=a[3]*n,t[4]=a[4]*n,t[5]=a[5]*n,t},o.multiplyScalarAndAdd=function(t,a,n,r){return t[0]=a[0]+n[0]*r,t[1]=a[1]+n[1]*r,t[2]=a[2]+n[2]*r,t[3]=a[3]+n[3]*r,t[4]=a[4]+n[4]*r,t[5]=a[5]+n[5]*r,t},o.exactEquals=function(t,a){return t[0]===a[0]&&t[1]===a[1]&&t[2]===a[2]&&t[3]===a[3]&&t[4]===a[4]&&t[5]===a[5]},o.equals=function(t,a){var n=t[0],o=t[1],u=t[2],l=t[3],e=t[4],M=t[5],s=a[0],i=a[1],c=a[2],h=a[3],S=a[4],I=a[5];return Math.abs(n-s)<=r.EPSILON*Math.max(1,Math.abs(n),Math.abs(s))&&Math.abs(o-i)<=r.EPSILON*Math.max(1,Math.abs(o),Math.abs(i))&&Math.abs(u-c)<=r.EPSILON*Math.max(1,Math.abs(u),Math.abs(c))&&Math.abs(l-h)<=r.EPSILON*Math.max(1,Math.abs(l),Math.abs(h))&&Math.abs(e-S)<=r.EPSILON*Math.max(1,Math.abs(e),Math.abs(S))&&Math.abs(M-I)<=r.EPSILON*Math.max(1,Math.abs(M),Math.abs(I))},t.exports=o},function(t,a,n){var r=n(1),o={};o.create=function(){var t=new r.ARRAY_TYPE(9);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},o.fromMat4=function(t,a){return t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[4],t[4]=a[5],t[5]=a[6],t[6]=a[8],t[7]=a[9],t[8]=a[10],t},o.clone=function(t){var a=new r.ARRAY_TYPE(9);return a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=t[3],a[4]=t[4],a[5]=t[5],a[6]=t[6],a[7]=t[7],a[8]=t[8],a},o.copy=function(t,a){return t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[3],t[4]=a[4],t[5]=a[5],t[6]=a[6],t[7]=a[7],t[8]=a[8],t},o.fromValues=function(t,a,n,o,u,l,e,M,s){var i=new r.ARRAY_TYPE(9);return i[0]=t,i[1]=a,i[2]=n,i[3]=o,i[4]=u,i[5]=l,i[6]=e,i[7]=M,i[8]=s,i},o.set=function(t,a,n,r,o,u,l,e,M,s){return t[0]=a,t[1]=n,t[2]=r,t[3]=o,t[4]=u,t[5]=l,t[6]=e,t[7]=M,t[8]=s,t},o.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},o.transpose=function(t,a){if(t===a){var n=a[1],r=a[2],o=a[5];t[1]=a[3],t[2]=a[6],t[3]=n,t[5]=a[7],t[6]=r,t[7]=o}else t[0]=a[0],t[1]=a[3],t[2]=a[6],t[3]=a[1],t[4]=a[4],t[5]=a[7],t[6]=a[2],t[7]=a[5],t[8]=a[8];return t},o.invert=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=a[4],e=a[5],M=a[6],s=a[7],i=a[8],c=i*l-e*s,h=-i*u+e*M,S=s*u-l*M,I=n*c+r*h+o*S;return I?(I=1/I,t[0]=c*I,t[1]=(-i*r+o*s)*I,t[2]=(e*r-o*l)*I,t[3]=h*I,t[4]=(i*n-o*M)*I,t[5]=(-e*n+o*u)*I,t[6]=S*I,t[7]=(-s*n+r*M)*I,t[8]=(l*n-r*u)*I,t):null},o.adjoint=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=a[4],e=a[5],M=a[6],s=a[7],i=a[8];return t[0]=l*i-e*s,t[1]=o*s-r*i,t[2]=r*e-o*l,t[3]=e*M-u*i,t[4]=n*i-o*M,t[5]=o*u-n*e,t[6]=u*s-l*M,t[7]=r*M-n*s,t[8]=n*l-r*u,t},o.determinant=function(t){var a=t[0],n=t[1],r=t[2],o=t[3],u=t[4],l=t[5],e=t[6],M=t[7],s=t[8];return a*(s*u-l*M)+n*(-s*o+l*e)+r*(M*o-u*e)},o.multiply=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=a[6],i=a[7],c=a[8],h=n[0],S=n[1],I=n[2],f=n[3],x=n[4],D=n[5],F=n[6],m=n[7],d=n[8];return t[0]=h*r+S*l+I*s,t[1]=h*o+S*e+I*i,t[2]=h*u+S*M+I*c,t[3]=f*r+x*l+D*s,t[4]=f*o+x*e+D*i,t[5]=f*u+x*M+D*c,t[6]=F*r+m*l+d*s,t[7]=F*o+m*e+d*i,t[8]=F*u+m*M+d*c,t},o.mul=o.multiply,o.translate=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=a[6],i=a[7],c=a[8],h=n[0],S=n[1];return t[0]=r,t[1]=o,t[2]=u,t[3]=l,t[4]=e,t[5]=M,t[6]=h*r+S*l+s,t[7]=h*o+S*e+i,t[8]=h*u+S*M+c,t},o.rotate=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=a[6],i=a[7],c=a[8],h=Math.sin(n),S=Math.cos(n);return t[0]=S*r+h*l,t[1]=S*o+h*e,t[2]=S*u+h*M,t[3]=S*l-h*r,t[4]=S*e-h*o,t[5]=S*M-h*u,t[6]=s,t[7]=i,t[8]=c,t},o.scale=function(t,a,n){var r=n[0],o=n[1];return t[0]=r*a[0],t[1]=r*a[1],t[2]=r*a[2],t[3]=o*a[3],t[4]=o*a[4],t[5]=o*a[5],t[6]=a[6],t[7]=a[7],t[8]=a[8],t},o.fromTranslation=function(t,a){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=a[0],t[7]=a[1],t[8]=1,t},o.fromRotation=function(t,a){var n=Math.sin(a),r=Math.cos(a);return t[0]=r,t[1]=n,t[2]=0,t[3]=-n,t[4]=r,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},o.fromScaling=function(t,a){return t[0]=a[0],t[1]=0,t[2]=0,t[3]=0,t[4]=a[1],t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},o.fromMat2d=function(t,a){return t[0]=a[0],t[1]=a[1],t[2]=0,t[3]=a[2],t[4]=a[3],t[5]=0,t[6]=a[4],t[7]=a[5],t[8]=1,t},o.fromQuat=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=n+n,e=r+r,M=o+o,s=n*l,i=r*l,c=r*e,h=o*l,S=o*e,I=o*M,f=u*l,x=u*e,D=u*M;return t[0]=1-c-I,t[3]=i-D,t[6]=h+x,t[1]=i+D,t[4]=1-s-I,t[7]=S-f,t[2]=h-x,t[5]=S+f,t[8]=1-s-c,t},o.normalFromMat4=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=a[4],e=a[5],M=a[6],s=a[7],i=a[8],c=a[9],h=a[10],S=a[11],I=a[12],f=a[13],x=a[14],D=a[15],F=n*e-r*l,m=n*M-o*l,d=n*s-u*l,b=r*M-o*e,v=r*s-u*e,z=o*s-u*M,p=i*f-c*I,w=i*x-h*I,E=i*D-S*I,A=c*x-h*f,P=c*D-S*f,L=h*D-S*x,q=F*L-m*P+d*A+b*E-v*w+z*p;return q?(q=1/q,t[0]=(e*L-M*P+s*A)*q,t[1]=(M*E-l*L-s*w)*q,t[2]=(l*P-e*E+s*p)*q,t[3]=(o*P-r*L-u*A)*q,t[4]=(n*L-o*E+u*w)*q,t[5]=(r*E-n*P-u*p)*q,t[6]=(f*z-x*v+D*b)*q,t[7]=(x*d-I*z-D*m)*q,t[8]=(I*v-f*d+D*F)*q,t):null},o.str=function(t){return"mat3("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+")"},o.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2))},o.add=function(t,a,n){return t[0]=a[0]+n[0],t[1]=a[1]+n[1],t[2]=a[2]+n[2],t[3]=a[3]+n[3],t[4]=a[4]+n[4],t[5]=a[5]+n[5],t[6]=a[6]+n[6],t[7]=a[7]+n[7],t[8]=a[8]+n[8],t},o.subtract=function(t,a,n){return t[0]=a[0]-n[0],t[1]=a[1]-n[1],t[2]=a[2]-n[2],t[3]=a[3]-n[3],t[4]=a[4]-n[4],t[5]=a[5]-n[5],t[6]=a[6]-n[6],t[7]=a[7]-n[7],t[8]=a[8]-n[8],t},o.sub=o.subtract,o.multiplyScalar=function(t,a,n){return t[0]=a[0]*n,t[1]=a[1]*n,t[2]=a[2]*n,t[3]=a[3]*n,t[4]=a[4]*n,t[5]=a[5]*n,t[6]=a[6]*n,t[7]=a[7]*n,t[8]=a[8]*n,t},o.multiplyScalarAndAdd=function(t,a,n,r){return t[0]=a[0]+n[0]*r,t[1]=a[1]+n[1]*r,t[2]=a[2]+n[2]*r,t[3]=a[3]+n[3]*r,t[4]=a[4]+n[4]*r,t[5]=a[5]+n[5]*r,t[6]=a[6]+n[6]*r,t[7]=a[7]+n[7]*r,t[8]=a[8]+n[8]*r,t},o.exactEquals=function(t,a){return t[0]===a[0]&&t[1]===a[1]&&t[2]===a[2]&&t[3]===a[3]&&t[4]===a[4]&&t[5]===a[5]&&t[6]===a[6]&&t[7]===a[7]&&t[8]===a[8]},o.equals=function(t,a){var n=t[0],o=t[1],u=t[2],l=t[3],e=t[4],M=t[5],s=t[6],i=t[7],c=t[8],h=a[0],S=a[1],I=a[2],f=a[3],x=a[4],D=a[5],F=t[6],m=a[7],d=a[8];return Math.abs(n-h)<=r.EPSILON*Math.max(1,Math.abs(n),Math.abs(h))&&Math.abs(o-S)<=r.EPSILON*Math.max(1,Math.abs(o),Math.abs(S))&&Math.abs(u-I)<=r.EPSILON*Math.max(1,Math.abs(u),Math.abs(I))&&Math.abs(l-f)<=r.EPSILON*Math.max(1,Math.abs(l),Math.abs(f))&&Math.abs(e-x)<=r.EPSILON*Math.max(1,Math.abs(e),Math.abs(x))&&Math.abs(M-D)<=r.EPSILON*Math.max(1,Math.abs(M),Math.abs(D))&&Math.abs(s-F)<=r.EPSILON*Math.max(1,Math.abs(s),Math.abs(F))&&Math.abs(i-m)<=r.EPSILON*Math.max(1,Math.abs(i),Math.abs(m))&&Math.abs(c-d)<=r.EPSILON*Math.max(1,Math.abs(c),Math.abs(d))},t.exports=o},function(t,a,n){var r=n(1),o={scalar:{},SIMD:{}};o.create=function(){var t=new r.ARRAY_TYPE(16);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},o.clone=function(t){var a=new r.ARRAY_TYPE(16);return a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=t[3],a[4]=t[4],a[5]=t[5],a[6]=t[6],a[7]=t[7],a[8]=t[8],a[9]=t[9],a[10]=t[10],a[11]=t[11],a[12]=t[12],a[13]=t[13],a[14]=t[14],a[15]=t[15],a},o.copy=function(t,a){return t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[3],t[4]=a[4],t[5]=a[5],t[6]=a[6],t[7]=a[7],t[8]=a[8],t[9]=a[9],t[10]=a[10],t[11]=a[11],t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15],t},o.fromValues=function(t,a,n,o,u,l,e,M,s,i,c,h,S,I,f,x){var D=new r.ARRAY_TYPE(16);return D[0]=t,D[1]=a,D[2]=n,D[3]=o,D[4]=u,D[5]=l,D[6]=e,D[7]=M,D[8]=s,D[9]=i,D[10]=c,D[11]=h,D[12]=S,D[13]=I,D[14]=f,D[15]=x,D},o.set=function(t,a,n,r,o,u,l,e,M,s,i,c,h,S,I,f,x){return t[0]=a,t[1]=n,t[2]=r,t[3]=o,t[4]=u,t[5]=l,t[6]=e,t[7]=M,t[8]=s,t[9]=i,t[10]=c,t[11]=h,t[12]=S,t[13]=I,t[14]=f,t[15]=x,t},o.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},o.scalar.transpose=function(t,a){if(t===a){var n=a[1],r=a[2],o=a[3],u=a[6],l=a[7],e=a[11];t[1]=a[4],t[2]=a[8],t[3]=a[12],t[4]=n,t[6]=a[9],t[7]=a[13],t[8]=r,t[9]=u,t[11]=a[14],t[12]=o,t[13]=l,t[14]=e}else t[0]=a[0],t[1]=a[4],t[2]=a[8],t[3]=a[12],t[4]=a[1],t[5]=a[5],t[6]=a[9],t[7]=a[13],t[8]=a[2],t[9]=a[6],t[10]=a[10],t[11]=a[14],t[12]=a[3],t[13]=a[7],t[14]=a[11],t[15]=a[15];return t},o.SIMD.transpose=function(t,a){var n,r,o,u,l,e,M,s,i,c;return n=SIMD.Float32x4.load(a,0),r=SIMD.Float32x4.load(a,4),o=SIMD.Float32x4.load(a,8),u=SIMD.Float32x4.load(a,12),l=SIMD.Float32x4.shuffle(n,r,0,1,4,5),e=SIMD.Float32x4.shuffle(o,u,0,1,4,5),M=SIMD.Float32x4.shuffle(l,e,0,2,4,6),s=SIMD.Float32x4.shuffle(l,e,1,3,5,7),SIMD.Float32x4.store(t,0,M),SIMD.Float32x4.store(t,4,s),l=SIMD.Float32x4.shuffle(n,r,2,3,6,7),e=SIMD.Float32x4.shuffle(o,u,2,3,6,7),i=SIMD.Float32x4.shuffle(l,e,0,2,4,6),c=SIMD.Float32x4.shuffle(l,e,1,3,5,7),SIMD.Float32x4.store(t,8,i),SIMD.Float32x4.store(t,12,c),t},o.transpose=r.USE_SIMD?o.SIMD.transpose:o.scalar.transpose,o.scalar.invert=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=a[4],e=a[5],M=a[6],s=a[7],i=a[8],c=a[9],h=a[10],S=a[11],I=a[12],f=a[13],x=a[14],D=a[15],F=n*e-r*l,m=n*M-o*l,d=n*s-u*l,b=r*M-o*e,v=r*s-u*e,z=o*s-u*M,p=i*f-c*I,w=i*x-h*I,E=i*D-S*I,A=c*x-h*f,P=c*D-S*f,L=h*D-S*x,q=F*L-m*P+d*A+b*E-v*w+z*p;return q?(q=1/q,t[0]=(e*L-M*P+s*A)*q,t[1]=(o*P-r*L-u*A)*q,t[2]=(f*z-x*v+D*b)*q,t[3]=(h*v-c*z-S*b)*q,t[4]=(M*E-l*L-s*w)*q,t[5]=(n*L-o*E+u*w)*q,t[6]=(x*d-I*z-D*m)*q,t[7]=(i*z-h*d+S*m)*q,t[8]=(l*P-e*E+s*p)*q,t[9]=(r*E-n*P-u*p)*q,t[10]=(I*v-f*d+D*F)*q,t[11]=(c*d-i*v-S*F)*q,t[12]=(e*w-l*A-M*p)*q,t[13]=(n*A-r*w+o*p)*q,t[14]=(f*m-I*b-x*F)*q,t[15]=(i*b-c*m+h*F)*q,t):null},o.SIMD.invert=function(t,a){var n,r,o,u,l,e,M,s,i,c,h=SIMD.Float32x4.load(a,0),S=SIMD.Float32x4.load(a,4),I=SIMD.Float32x4.load(a,8),f=SIMD.Float32x4.load(a,12);return l=SIMD.Float32x4.shuffle(h,S,0,1,4,5),r=SIMD.Float32x4.shuffle(I,f,0,1,4,5),n=SIMD.Float32x4.shuffle(l,r,0,2,4,6),r=SIMD.Float32x4.shuffle(r,l,1,3,5,7),l=SIMD.Float32x4.shuffle(h,S,2,3,6,7),u=SIMD.Float32x4.shuffle(I,f,2,3,6,7),o=SIMD.Float32x4.shuffle(l,u,0,2,4,6),u=SIMD.Float32x4.shuffle(u,l,1,3,5,7),l=SIMD.Float32x4.mul(o,u),l=SIMD.Float32x4.swizzle(l,1,0,3,2),e=SIMD.Float32x4.mul(r,l),M=SIMD.Float32x4.mul(n,l),l=SIMD.Float32x4.swizzle(l,2,3,0,1),e=SIMD.Float32x4.sub(SIMD.Float32x4.mul(r,l),e),M=SIMD.Float32x4.sub(SIMD.Float32x4.mul(n,l),M),M=SIMD.Float32x4.swizzle(M,2,3,0,1),l=SIMD.Float32x4.mul(r,o),l=SIMD.Float32x4.swizzle(l,1,0,3,2),e=SIMD.Float32x4.add(SIMD.Float32x4.mul(u,l),e),i=SIMD.Float32x4.mul(n,l),l=SIMD.Float32x4.swizzle(l,2,3,0,1),e=SIMD.Float32x4.sub(e,SIMD.Float32x4.mul(u,l)),i=SIMD.Float32x4.sub(SIMD.Float32x4.mul(n,l),i),i=SIMD.Float32x4.swizzle(i,2,3,0,1),l=SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(r,2,3,0,1),u),l=SIMD.Float32x4.swizzle(l,1,0,3,2),o=SIMD.Float32x4.swizzle(o,2,3,0,1),e=SIMD.Float32x4.add(SIMD.Float32x4.mul(o,l),e),s=SIMD.Float32x4.mul(n,l),l=SIMD.Float32x4.swizzle(l,2,3,0,1),e=SIMD.Float32x4.sub(e,SIMD.Float32x4.mul(o,l)),s=SIMD.Float32x4.sub(SIMD.Float32x4.mul(n,l),s),s=SIMD.Float32x4.swizzle(s,2,3,0,1),l=SIMD.Float32x4.mul(n,r),l=SIMD.Float32x4.swizzle(l,1,0,3,2),s=SIMD.Float32x4.add(SIMD.Float32x4.mul(u,l),s),i=SIMD.Float32x4.sub(SIMD.Float32x4.mul(o,l),i),l=SIMD.Float32x4.swizzle(l,2,3,0,1),s=SIMD.Float32x4.sub(SIMD.Float32x4.mul(u,l),s),i=SIMD.Float32x4.sub(i,SIMD.Float32x4.mul(o,l)),l=SIMD.Float32x4.mul(n,u),l=SIMD.Float32x4.swizzle(l,1,0,3,2),M=SIMD.Float32x4.sub(M,SIMD.Float32x4.mul(o,l)),s=SIMD.Float32x4.add(SIMD.Float32x4.mul(r,l),s),l=SIMD.Float32x4.swizzle(l,2,3,0,1),M=SIMD.Float32x4.add(SIMD.Float32x4.mul(o,l),M),s=SIMD.Float32x4.sub(s,SIMD.Float32x4.mul(r,l)),l=SIMD.Float32x4.mul(n,o),l=SIMD.Float32x4.swizzle(l,1,0,3,2),M=SIMD.Float32x4.add(SIMD.Float32x4.mul(u,l),M),i=SIMD.Float32x4.sub(i,SIMD.Float32x4.mul(r,l)),l=SIMD.Float32x4.swizzle(l,2,3,0,1),M=SIMD.Float32x4.sub(M,SIMD.Float32x4.mul(u,l)),i=SIMD.Float32x4.add(SIMD.Float32x4.mul(r,l),i),c=SIMD.Float32x4.mul(n,e),c=SIMD.Float32x4.add(SIMD.Float32x4.swizzle(c,2,3,0,1),c),c=SIMD.Float32x4.add(SIMD.Float32x4.swizzle(c,1,0,3,2),c),l=SIMD.Float32x4.reciprocalApproximation(c),c=SIMD.Float32x4.sub(SIMD.Float32x4.add(l,l),SIMD.Float32x4.mul(c,SIMD.Float32x4.mul(l,l))),(c=SIMD.Float32x4.swizzle(c,0,0,0,0))?(SIMD.Float32x4.store(t,0,SIMD.Float32x4.mul(c,e)),SIMD.Float32x4.store(t,4,SIMD.Float32x4.mul(c,M)),SIMD.Float32x4.store(t,8,SIMD.Float32x4.mul(c,s)),SIMD.Float32x4.store(t,12,SIMD.Float32x4.mul(c,i)),t):null},o.invert=r.USE_SIMD?o.SIMD.invert:o.scalar.invert,o.scalar.adjoint=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=a[4],e=a[5],M=a[6],s=a[7],i=a[8],c=a[9],h=a[10],S=a[11],I=a[12],f=a[13],x=a[14],D=a[15];return t[0]=e*(h*D-S*x)-c*(M*D-s*x)+f*(M*S-s*h),t[1]=-(r*(h*D-S*x)-c*(o*D-u*x)+f*(o*S-u*h)),t[2]=r*(M*D-s*x)-e*(o*D-u*x)+f*(o*s-u*M),t[3]=-(r*(M*S-s*h)-e*(o*S-u*h)+c*(o*s-u*M)),t[4]=-(l*(h*D-S*x)-i*(M*D-s*x)+I*(M*S-s*h)),t[5]=n*(h*D-S*x)-i*(o*D-u*x)+I*(o*S-u*h),t[6]=-(n*(M*D-s*x)-l*(o*D-u*x)+I*(o*s-u*M)),t[7]=n*(M*S-s*h)-l*(o*S-u*h)+i*(o*s-u*M),t[8]=l*(c*D-S*f)-i*(e*D-s*f)+I*(e*S-s*c),t[9]=-(n*(c*D-S*f)-i*(r*D-u*f)+I*(r*S-u*c)),t[10]=n*(e*D-s*f)-l*(r*D-u*f)+I*(r*s-u*e),t[11]=-(n*(e*S-s*c)-l*(r*S-u*c)+i*(r*s-u*e)),t[12]=-(l*(c*x-h*f)-i*(e*x-M*f)+I*(e*h-M*c)),t[13]=n*(c*x-h*f)-i*(r*x-o*f)+I*(r*h-o*c),t[14]=-(n*(e*x-M*f)-l*(r*x-o*f)+I*(r*M-o*e)),t[15]=n*(e*h-M*c)-l*(r*h-o*c)+i*(r*M-o*e),t},o.SIMD.adjoint=function(t,a){var n,r,o,u,l,e,M,s,i,c,h,S,I,n=SIMD.Float32x4.load(a,0),r=SIMD.Float32x4.load(a,4),o=SIMD.Float32x4.load(a,8),u=SIMD.Float32x4.load(a,12);return i=SIMD.Float32x4.shuffle(n,r,0,1,4,5),e=SIMD.Float32x4.shuffle(o,u,0,1,4,5),l=SIMD.Float32x4.shuffle(i,e,0,2,4,6),e=SIMD.Float32x4.shuffle(e,i,1,3,5,7),i=SIMD.Float32x4.shuffle(n,r,2,3,6,7),s=SIMD.Float32x4.shuffle(o,u,2,3,6,7),M=SIMD.Float32x4.shuffle(i,s,0,2,4,6),s=SIMD.Float32x4.shuffle(s,i,1,3,5,7),i=SIMD.Float32x4.mul(M,s),i=SIMD.Float32x4.swizzle(i,1,0,3,2),c=SIMD.Float32x4.mul(e,i),h=SIMD.Float32x4.mul(l,i),i=SIMD.Float32x4.swizzle(i,2,3,0,1),c=SIMD.Float32x4.sub(SIMD.Float32x4.mul(e,i),c),h=SIMD.Float32x4.sub(SIMD.Float32x4.mul(l,i),h),h=SIMD.Float32x4.swizzle(h,2,3,0,1),i=SIMD.Float32x4.mul(e,M),i=SIMD.Float32x4.swizzle(i,1,0,3,2),c=SIMD.Float32x4.add(SIMD.Float32x4.mul(s,i),c),I=SIMD.Float32x4.mul(l,i),i=SIMD.Float32x4.swizzle(i,2,3,0,1),c=SIMD.Float32x4.sub(c,SIMD.Float32x4.mul(s,i)),I=SIMD.Float32x4.sub(SIMD.Float32x4.mul(l,i),I),I=SIMD.Float32x4.swizzle(I,2,3,0,1),i=SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(e,2,3,0,1),s),i=SIMD.Float32x4.swizzle(i,1,0,3,2),M=SIMD.Float32x4.swizzle(M,2,3,0,1),c=SIMD.Float32x4.add(SIMD.Float32x4.mul(M,i),c),S=SIMD.Float32x4.mul(l,i),i=SIMD.Float32x4.swizzle(i,2,3,0,1),c=SIMD.Float32x4.sub(c,SIMD.Float32x4.mul(M,i)),S=SIMD.Float32x4.sub(SIMD.Float32x4.mul(l,i),S),S=SIMD.Float32x4.swizzle(S,2,3,0,1),i=SIMD.Float32x4.mul(l,e),i=SIMD.Float32x4.swizzle(i,1,0,3,2),S=SIMD.Float32x4.add(SIMD.Float32x4.mul(s,i),S),I=SIMD.Float32x4.sub(SIMD.Float32x4.mul(M,i),I),i=SIMD.Float32x4.swizzle(i,2,3,0,1),S=SIMD.Float32x4.sub(SIMD.Float32x4.mul(s,i),S),I=SIMD.Float32x4.sub(I,SIMD.Float32x4.mul(M,i)),i=SIMD.Float32x4.mul(l,s),i=SIMD.Float32x4.swizzle(i,1,0,3,2),h=SIMD.Float32x4.sub(h,SIMD.Float32x4.mul(M,i)),S=SIMD.Float32x4.add(SIMD.Float32x4.mul(e,i),S),i=SIMD.Float32x4.swizzle(i,2,3,0,1),h=SIMD.Float32x4.add(SIMD.Float32x4.mul(M,i),h),S=SIMD.Float32x4.sub(S,SIMD.Float32x4.mul(e,i)),i=SIMD.Float32x4.mul(l,M),i=SIMD.Float32x4.swizzle(i,1,0,3,2),h=SIMD.Float32x4.add(SIMD.Float32x4.mul(s,i),h),I=SIMD.Float32x4.sub(I,SIMD.Float32x4.mul(e,i)),i=SIMD.Float32x4.swizzle(i,2,3,0,1),h=SIMD.Float32x4.sub(h,SIMD.Float32x4.mul(s,i)),I=SIMD.Float32x4.add(SIMD.Float32x4.mul(e,i),I),SIMD.Float32x4.store(t,0,c),SIMD.Float32x4.store(t,4,h),SIMD.Float32x4.store(t,8,S),SIMD.Float32x4.store(t,12,I),t},o.adjoint=r.USE_SIMD?o.SIMD.adjoint:o.scalar.adjoint,o.determinant=function(t){var a=t[0],n=t[1],r=t[2],o=t[3],u=t[4],l=t[5],e=t[6],M=t[7],s=t[8],i=t[9],c=t[10],h=t[11],S=t[12],I=t[13],f=t[14],x=t[15],D=a*l-n*u,F=a*e-r*u,m=a*M-o*u,d=n*e-r*l,b=n*M-o*l,v=r*M-o*e,z=s*I-i*S,p=s*f-c*S,w=s*x-h*S,E=i*f-c*I,A=i*x-h*I,P=c*x-h*f;return D*P-F*A+m*E+d*w-b*p+v*z},o.SIMD.multiply=function(t,a,n){var r=SIMD.Float32x4.load(a,0),o=SIMD.Float32x4.load(a,4),u=SIMD.Float32x4.load(a,8),l=SIMD.Float32x4.load(a,12),e=SIMD.Float32x4.load(n,0),M=SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(e,0,0,0,0),r),SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(e,1,1,1,1),o),SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(e,2,2,2,2),u),SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(e,3,3,3,3),l))));SIMD.Float32x4.store(t,0,M);var s=SIMD.Float32x4.load(n,4),i=SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(s,0,0,0,0),r),SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(s,1,1,1,1),o),SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(s,2,2,2,2),u),SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(s,3,3,3,3),l))));SIMD.Float32x4.store(t,4,i);var c=SIMD.Float32x4.load(n,8),h=SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(c,0,0,0,0),r),SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(c,1,1,1,1),o),SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(c,2,2,2,2),u),SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(c,3,3,3,3),l))));SIMD.Float32x4.store(t,8,h);var S=SIMD.Float32x4.load(n,12),I=SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(S,0,0,0,0),r),SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(S,1,1,1,1),o),SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(S,2,2,2,2),u),SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(S,3,3,3,3),l))));return SIMD.Float32x4.store(t,12,I),t},o.scalar.multiply=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=a[6],i=a[7],c=a[8],h=a[9],S=a[10],I=a[11],f=a[12],x=a[13],D=a[14],F=a[15],m=n[0],d=n[1],b=n[2],v=n[3];return t[0]=m*r+d*e+b*c+v*f,t[1]=m*o+d*M+b*h+v*x,t[2]=m*u+d*s+b*S+v*D,t[3]=m*l+d*i+b*I+v*F,m=n[4],d=n[5],b=n[6],v=n[7],t[4]=m*r+d*e+b*c+v*f,t[5]=m*o+d*M+b*h+v*x,t[6]=m*u+d*s+b*S+v*D,t[7]=m*l+d*i+b*I+v*F,m=n[8],d=n[9],b=n[10],v=n[11],t[8]=m*r+d*e+b*c+v*f,t[9]=m*o+d*M+b*h+v*x,t[10]=m*u+d*s+b*S+v*D,t[11]=m*l+d*i+b*I+v*F,m=n[12],d=n[13],b=n[14],v=n[15],t[12]=m*r+d*e+b*c+v*f,t[13]=m*o+d*M+b*h+v*x,t[14]=m*u+d*s+b*S+v*D,t[15]=m*l+d*i+b*I+v*F,t},o.multiply=r.USE_SIMD?o.SIMD.multiply:o.scalar.multiply,o.mul=o.multiply,o.scalar.translate=function(t,a,n){var r,o,u,l,e,M,s,i,c,h,S,I,f=n[0],x=n[1],D=n[2];return a===t?(t[12]=a[0]*f+a[4]*x+a[8]*D+a[12],t[13]=a[1]*f+a[5]*x+a[9]*D+a[13],t[14]=a[2]*f+a[6]*x+a[10]*D+a[14],t[15]=a[3]*f+a[7]*x+a[11]*D+a[15]):(r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=a[6],i=a[7],c=a[8],h=a[9],S=a[10],I=a[11],t[0]=r,t[1]=o,t[2]=u,t[3]=l,t[4]=e,t[5]=M,t[6]=s,t[7]=i,t[8]=c,t[9]=h,t[10]=S,t[11]=I,t[12]=r*f+e*x+c*D+a[12],t[13]=o*f+M*x+h*D+a[13],t[14]=u*f+s*x+S*D+a[14],t[15]=l*f+i*x+I*D+a[15]),t},o.SIMD.translate=function(t,a,n){var r=SIMD.Float32x4.load(a,0),o=SIMD.Float32x4.load(a,4),u=SIMD.Float32x4.load(a,8),l=SIMD.Float32x4.load(a,12),e=SIMD.Float32x4(n[0],n[1],n[2],0);a!==t&&(t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[3],t[4]=a[4],t[5]=a[5],t[6]=a[6],t[7]=a[7],t[8]=a[8],t[9]=a[9],t[10]=a[10],t[11]=a[11]),r=SIMD.Float32x4.mul(r,SIMD.Float32x4.swizzle(e,0,0,0,0)),o=SIMD.Float32x4.mul(o,SIMD.Float32x4.swizzle(e,1,1,1,1)),u=SIMD.Float32x4.mul(u,SIMD.Float32x4.swizzle(e,2,2,2,2));var M=SIMD.Float32x4.add(r,SIMD.Float32x4.add(o,SIMD.Float32x4.add(u,l)));return SIMD.Float32x4.store(t,12,M),t},o.translate=r.USE_SIMD?o.SIMD.translate:o.scalar.translate,o.scalar.scale=function(t,a,n){var r=n[0],o=n[1],u=n[2];return t[0]=a[0]*r,t[1]=a[1]*r,t[2]=a[2]*r,t[3]=a[3]*r,t[4]=a[4]*o,t[5]=a[5]*o,t[6]=a[6]*o,t[7]=a[7]*o,t[8]=a[8]*u,t[9]=a[9]*u,t[10]=a[10]*u,t[11]=a[11]*u,t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15],t},o.SIMD.scale=function(t,a,n){var r,o,u,l=SIMD.Float32x4(n[0],n[1],n[2],0);return r=SIMD.Float32x4.load(a,0),SIMD.Float32x4.store(t,0,SIMD.Float32x4.mul(r,SIMD.Float32x4.swizzle(l,0,0,0,0))),o=SIMD.Float32x4.load(a,4),SIMD.Float32x4.store(t,4,SIMD.Float32x4.mul(o,SIMD.Float32x4.swizzle(l,1,1,1,1))),u=SIMD.Float32x4.load(a,8),SIMD.Float32x4.store(t,8,SIMD.Float32x4.mul(u,SIMD.Float32x4.swizzle(l,2,2,2,2))),t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15],t},o.scale=r.USE_SIMD?o.SIMD.scale:o.scalar.scale,o.rotate=function(t,a,n,o){var u,l,e,M,s,i,c,h,S,I,f,x,D,F,m,d,b,v,z,p,w,E,A,P,L=o[0],q=o[1],R=o[2],N=Math.sqrt(L*L+q*q+R*R);return Math.abs(N)<r.EPSILON?null:(N=1/N,L*=N,q*=N,R*=N,u=Math.sin(n),l=Math.cos(n),e=1-l,M=a[0],s=a[1],i=a[2],c=a[3],h=a[4],S=a[5],I=a[6],f=a[7],x=a[8],D=a[9],F=a[10],m=a[11],d=L*L*e+l,b=q*L*e+R*u,v=R*L*e-q*u,z=L*q*e-R*u,p=q*q*e+l,w=R*q*e+L*u,E=L*R*e+q*u,A=q*R*e-L*u,P=R*R*e+l,t[0]=M*d+h*b+x*v,t[1]=s*d+S*b+D*v,t[2]=i*d+I*b+F*v,t[3]=c*d+f*b+m*v,t[4]=M*z+h*p+x*w,t[5]=s*z+S*p+D*w,t[6]=i*z+I*p+F*w,t[7]=c*z+f*p+m*w,t[8]=M*E+h*A+x*P,t[9]=s*E+S*A+D*P,t[10]=i*E+I*A+F*P,t[11]=c*E+f*A+m*P,a!==t&&(t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15]),t)},o.scalar.rotateX=function(t,a,n){var r=Math.sin(n),o=Math.cos(n),u=a[4],l=a[5],e=a[6],M=a[7],s=a[8],i=a[9],c=a[10],h=a[11];return a!==t&&(t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[3],t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15]),t[4]=u*o+s*r,t[5]=l*o+i*r,t[6]=e*o+c*r,t[7]=M*o+h*r,t[8]=s*o-u*r,t[9]=i*o-l*r,t[10]=c*o-e*r,t[11]=h*o-M*r,t},o.SIMD.rotateX=function(t,a,n){var r=SIMD.Float32x4.splat(Math.sin(n)),o=SIMD.Float32x4.splat(Math.cos(n));a!==t&&(t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[3],t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15]);var u=SIMD.Float32x4.load(a,4),l=SIMD.Float32x4.load(a,8);return SIMD.Float32x4.store(t,4,SIMD.Float32x4.add(SIMD.Float32x4.mul(u,o),SIMD.Float32x4.mul(l,r))),SIMD.Float32x4.store(t,8,SIMD.Float32x4.sub(SIMD.Float32x4.mul(l,o),SIMD.Float32x4.mul(u,r))),t},o.rotateX=r.USE_SIMD?o.SIMD.rotateX:o.scalar.rotateX,o.scalar.rotateY=function(t,a,n){var r=Math.sin(n),o=Math.cos(n),u=a[0],l=a[1],e=a[2],M=a[3],s=a[8],i=a[9],c=a[10],h=a[11];return a!==t&&(t[4]=a[4],t[5]=a[5],t[6]=a[6],t[7]=a[7],t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15]),t[0]=u*o-s*r,t[1]=l*o-i*r,t[2]=e*o-c*r,t[3]=M*o-h*r,t[8]=u*r+s*o,t[9]=l*r+i*o,t[10]=e*r+c*o,t[11]=M*r+h*o,t},o.SIMD.rotateY=function(t,a,n){var r=SIMD.Float32x4.splat(Math.sin(n)),o=SIMD.Float32x4.splat(Math.cos(n));a!==t&&(t[4]=a[4],t[5]=a[5],t[6]=a[6],t[7]=a[7],t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15]);var u=SIMD.Float32x4.load(a,0),l=SIMD.Float32x4.load(a,8);return SIMD.Float32x4.store(t,0,SIMD.Float32x4.sub(SIMD.Float32x4.mul(u,o),SIMD.Float32x4.mul(l,r))),SIMD.Float32x4.store(t,8,SIMD.Float32x4.add(SIMD.Float32x4.mul(u,r),SIMD.Float32x4.mul(l,o))),t},o.rotateY=r.USE_SIMD?o.SIMD.rotateY:o.scalar.rotateY,o.scalar.rotateZ=function(t,a,n){var r=Math.sin(n),o=Math.cos(n),u=a[0],l=a[1],e=a[2],M=a[3],s=a[4],i=a[5],c=a[6],h=a[7];return a!==t&&(t[8]=a[8],t[9]=a[9],t[10]=a[10],t[11]=a[11],t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15]),t[0]=u*o+s*r,t[1]=l*o+i*r,t[2]=e*o+c*r,t[3]=M*o+h*r,t[4]=s*o-u*r,t[5]=i*o-l*r,t[6]=c*o-e*r,t[7]=h*o-M*r,t},o.SIMD.rotateZ=function(t,a,n){var r=SIMD.Float32x4.splat(Math.sin(n)),o=SIMD.Float32x4.splat(Math.cos(n));a!==t&&(t[8]=a[8],t[9]=a[9],t[10]=a[10],t[11]=a[11],t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15]);var u=SIMD.Float32x4.load(a,0),l=SIMD.Float32x4.load(a,4);return SIMD.Float32x4.store(t,0,SIMD.Float32x4.add(SIMD.Float32x4.mul(u,o),SIMD.Float32x4.mul(l,r))),SIMD.Float32x4.store(t,4,SIMD.Float32x4.sub(SIMD.Float32x4.mul(l,o),SIMD.Float32x4.mul(u,r))),t},o.rotateZ=r.USE_SIMD?o.SIMD.rotateZ:o.scalar.rotateZ,o.fromTranslation=function(t,a){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=a[0],t[13]=a[1],t[14]=a[2],t[15]=1,t},o.fromScaling=function(t,a){return t[0]=a[0],t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=a[1],t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=a[2],t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},o.fromRotation=function(t,a,n){var o,u,l,e=n[0],M=n[1],s=n[2],i=Math.sqrt(e*e+M*M+s*s);return Math.abs(i)<r.EPSILON?null:(i=1/i,e*=i,M*=i,s*=i,o=Math.sin(a),u=Math.cos(a),l=1-u,t[0]=e*e*l+u,t[1]=M*e*l+s*o,t[2]=s*e*l-M*o,t[3]=0,t[4]=e*M*l-s*o,t[5]=M*M*l+u,t[6]=s*M*l+e*o,t[7]=0,t[8]=e*s*l+M*o,t[9]=M*s*l-e*o,t[10]=s*s*l+u,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t)},o.fromXRotation=function(t,a){var n=Math.sin(a),r=Math.cos(a);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=r,t[6]=n,t[7]=0,t[8]=0,t[9]=-n,t[10]=r,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},o.fromYRotation=function(t,a){var n=Math.sin(a),r=Math.cos(a);return t[0]=r,t[1]=0,t[2]=-n,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=n,t[9]=0,t[10]=r,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},o.fromZRotation=function(t,a){var n=Math.sin(a),r=Math.cos(a);return t[0]=r,t[1]=n,t[2]=0,t[3]=0,t[4]=-n,t[5]=r,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},o.fromRotationTranslation=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=r+r,M=o+o,s=u+u,i=r*e,c=r*M,h=r*s,S=o*M,I=o*s,f=u*s,x=l*e,D=l*M,F=l*s;return t[0]=1-(S+f),t[1]=c+F,t[2]=h-D,t[3]=0,t[4]=c-F,t[5]=1-(i+f),t[6]=I+x,t[7]=0,t[8]=h+D,t[9]=I-x,t[10]=1-(i+S),t[11]=0,t[12]=n[0],t[13]=n[1],t[14]=n[2],t[15]=1,t},o.getTranslation=function(t,a){return t[0]=a[12],t[1]=a[13],t[2]=a[14],t},o.getRotation=function(t,a){var n=a[0]+a[5]+a[10],r=0;return n>0?(r=2*Math.sqrt(n+1),t[3]=.25*r,t[0]=(a[6]-a[9])/r,t[1]=(a[8]-a[2])/r,t[2]=(a[1]-a[4])/r):a[0]>a[5]&a[0]>a[10]?(r=2*Math.sqrt(1+a[0]-a[5]-a[10]),t[3]=(a[6]-a[9])/r,t[0]=.25*r,t[1]=(a[1]+a[4])/r,t[2]=(a[8]+a[2])/r):a[5]>a[10]?(r=2*Math.sqrt(1+a[5]-a[0]-a[10]),t[3]=(a[8]-a[2])/r,t[0]=(a[1]+a[4])/r,t[1]=.25*r,t[2]=(a[6]+a[9])/r):(r=2*Math.sqrt(1+a[10]-a[0]-a[5]),t[3]=(a[1]-a[4])/r,t[0]=(a[8]+a[2])/r,t[1]=(a[6]+a[9])/r,t[2]=.25*r),t},o.fromRotationTranslationScale=function(t,a,n,r){var o=a[0],u=a[1],l=a[2],e=a[3],M=o+o,s=u+u,i=l+l,c=o*M,h=o*s,S=o*i,I=u*s,f=u*i,x=l*i,D=e*M,F=e*s,m=e*i,d=r[0],b=r[1],v=r[2];return t[0]=(1-(I+x))*d,t[1]=(h+m)*d,t[2]=(S-F)*d,t[3]=0,t[4]=(h-m)*b,t[5]=(1-(c+x))*b,t[6]=(f+D)*b,t[7]=0,t[8]=(S+F)*v,t[9]=(f-D)*v,t[10]=(1-(c+I))*v,t[11]=0,t[12]=n[0],t[13]=n[1],t[14]=n[2],t[15]=1,t},o.fromRotationTranslationScaleOrigin=function(t,a,n,r,o){ -var u=a[0],l=a[1],e=a[2],M=a[3],s=u+u,i=l+l,c=e+e,h=u*s,S=u*i,I=u*c,f=l*i,x=l*c,D=e*c,F=M*s,m=M*i,d=M*c,b=r[0],v=r[1],z=r[2],p=o[0],w=o[1],E=o[2];return t[0]=(1-(f+D))*b,t[1]=(S+d)*b,t[2]=(I-m)*b,t[3]=0,t[4]=(S-d)*v,t[5]=(1-(h+D))*v,t[6]=(x+F)*v,t[7]=0,t[8]=(I+m)*z,t[9]=(x-F)*z,t[10]=(1-(h+f))*z,t[11]=0,t[12]=n[0]+p-(t[0]*p+t[4]*w+t[8]*E),t[13]=n[1]+w-(t[1]*p+t[5]*w+t[9]*E),t[14]=n[2]+E-(t[2]*p+t[6]*w+t[10]*E),t[15]=1,t},o.fromQuat=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=n+n,e=r+r,M=o+o,s=n*l,i=r*l,c=r*e,h=o*l,S=o*e,I=o*M,f=u*l,x=u*e,D=u*M;return t[0]=1-c-I,t[1]=i+D,t[2]=h-x,t[3]=0,t[4]=i-D,t[5]=1-s-I,t[6]=S+f,t[7]=0,t[8]=h+x,t[9]=S-f,t[10]=1-s-c,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},o.frustum=function(t,a,n,r,o,u,l){var e=1/(n-a),M=1/(o-r),s=1/(u-l);return t[0]=2*u*e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=2*u*M,t[6]=0,t[7]=0,t[8]=(n+a)*e,t[9]=(o+r)*M,t[10]=(l+u)*s,t[11]=-1,t[12]=0,t[13]=0,t[14]=l*u*2*s,t[15]=0,t},o.perspective=function(t,a,n,r,o){var u=1/Math.tan(a/2),l=1/(r-o);return t[0]=u/n,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=u,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=(o+r)*l,t[11]=-1,t[12]=0,t[13]=0,t[14]=2*o*r*l,t[15]=0,t},o.perspectiveFromFieldOfView=function(t,a,n,r){var o=Math.tan(a.upDegrees*Math.PI/180),u=Math.tan(a.downDegrees*Math.PI/180),l=Math.tan(a.leftDegrees*Math.PI/180),e=Math.tan(a.rightDegrees*Math.PI/180),M=2/(l+e),s=2/(o+u);return t[0]=M,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=s,t[6]=0,t[7]=0,t[8]=-((l-e)*M*.5),t[9]=(o-u)*s*.5,t[10]=r/(n-r),t[11]=-1,t[12]=0,t[13]=0,t[14]=r*n/(n-r),t[15]=0,t},o.ortho=function(t,a,n,r,o,u,l){var e=1/(a-n),M=1/(r-o),s=1/(u-l);return t[0]=-2*e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*M,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*s,t[11]=0,t[12]=(a+n)*e,t[13]=(o+r)*M,t[14]=(l+u)*s,t[15]=1,t},o.lookAt=function(t,a,n,u){var l,e,M,s,i,c,h,S,I,f,x=a[0],D=a[1],F=a[2],m=u[0],d=u[1],b=u[2],v=n[0],z=n[1],p=n[2];return Math.abs(x-v)<r.EPSILON&&Math.abs(D-z)<r.EPSILON&&Math.abs(F-p)<r.EPSILON?o.identity(t):(h=x-v,S=D-z,I=F-p,f=1/Math.sqrt(h*h+S*S+I*I),h*=f,S*=f,I*=f,l=d*I-b*S,e=b*h-m*I,M=m*S-d*h,f=Math.sqrt(l*l+e*e+M*M),f?(f=1/f,l*=f,e*=f,M*=f):(l=0,e=0,M=0),s=S*M-I*e,i=I*l-h*M,c=h*e-S*l,f=Math.sqrt(s*s+i*i+c*c),f?(f=1/f,s*=f,i*=f,c*=f):(s=0,i=0,c=0),t[0]=l,t[1]=s,t[2]=h,t[3]=0,t[4]=e,t[5]=i,t[6]=S,t[7]=0,t[8]=M,t[9]=c,t[10]=I,t[11]=0,t[12]=-(l*x+e*D+M*F),t[13]=-(s*x+i*D+c*F),t[14]=-(h*x+S*D+I*F),t[15]=1,t)},o.str=function(t){return"mat4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+", "+t[9]+", "+t[10]+", "+t[11]+", "+t[12]+", "+t[13]+", "+t[14]+", "+t[15]+")"},o.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2)+Math.pow(t[9],2)+Math.pow(t[10],2)+Math.pow(t[11],2)+Math.pow(t[12],2)+Math.pow(t[13],2)+Math.pow(t[14],2)+Math.pow(t[15],2))},o.add=function(t,a,n){return t[0]=a[0]+n[0],t[1]=a[1]+n[1],t[2]=a[2]+n[2],t[3]=a[3]+n[3],t[4]=a[4]+n[4],t[5]=a[5]+n[5],t[6]=a[6]+n[6],t[7]=a[7]+n[7],t[8]=a[8]+n[8],t[9]=a[9]+n[9],t[10]=a[10]+n[10],t[11]=a[11]+n[11],t[12]=a[12]+n[12],t[13]=a[13]+n[13],t[14]=a[14]+n[14],t[15]=a[15]+n[15],t},o.subtract=function(t,a,n){return t[0]=a[0]-n[0],t[1]=a[1]-n[1],t[2]=a[2]-n[2],t[3]=a[3]-n[3],t[4]=a[4]-n[4],t[5]=a[5]-n[5],t[6]=a[6]-n[6],t[7]=a[7]-n[7],t[8]=a[8]-n[8],t[9]=a[9]-n[9],t[10]=a[10]-n[10],t[11]=a[11]-n[11],t[12]=a[12]-n[12],t[13]=a[13]-n[13],t[14]=a[14]-n[14],t[15]=a[15]-n[15],t},o.sub=o.subtract,o.multiplyScalar=function(t,a,n){return t[0]=a[0]*n,t[1]=a[1]*n,t[2]=a[2]*n,t[3]=a[3]*n,t[4]=a[4]*n,t[5]=a[5]*n,t[6]=a[6]*n,t[7]=a[7]*n,t[8]=a[8]*n,t[9]=a[9]*n,t[10]=a[10]*n,t[11]=a[11]*n,t[12]=a[12]*n,t[13]=a[13]*n,t[14]=a[14]*n,t[15]=a[15]*n,t},o.multiplyScalarAndAdd=function(t,a,n,r){return t[0]=a[0]+n[0]*r,t[1]=a[1]+n[1]*r,t[2]=a[2]+n[2]*r,t[3]=a[3]+n[3]*r,t[4]=a[4]+n[4]*r,t[5]=a[5]+n[5]*r,t[6]=a[6]+n[6]*r,t[7]=a[7]+n[7]*r,t[8]=a[8]+n[8]*r,t[9]=a[9]+n[9]*r,t[10]=a[10]+n[10]*r,t[11]=a[11]+n[11]*r,t[12]=a[12]+n[12]*r,t[13]=a[13]+n[13]*r,t[14]=a[14]+n[14]*r,t[15]=a[15]+n[15]*r,t},o.exactEquals=function(t,a){return t[0]===a[0]&&t[1]===a[1]&&t[2]===a[2]&&t[3]===a[3]&&t[4]===a[4]&&t[5]===a[5]&&t[6]===a[6]&&t[7]===a[7]&&t[8]===a[8]&&t[9]===a[9]&&t[10]===a[10]&&t[11]===a[11]&&t[12]===a[12]&&t[13]===a[13]&&t[14]===a[14]&&t[15]===a[15]},o.equals=function(t,a){var n=t[0],o=t[1],u=t[2],l=t[3],e=t[4],M=t[5],s=t[6],i=t[7],c=t[8],h=t[9],S=t[10],I=t[11],f=t[12],x=t[13],D=t[14],F=t[15],m=a[0],d=a[1],b=a[2],v=a[3],z=a[4],p=a[5],w=a[6],E=a[7],A=a[8],P=a[9],L=a[10],q=a[11],R=a[12],N=a[13],O=a[14],Y=a[15];return Math.abs(n-m)<=r.EPSILON*Math.max(1,Math.abs(n),Math.abs(m))&&Math.abs(o-d)<=r.EPSILON*Math.max(1,Math.abs(o),Math.abs(d))&&Math.abs(u-b)<=r.EPSILON*Math.max(1,Math.abs(u),Math.abs(b))&&Math.abs(l-v)<=r.EPSILON*Math.max(1,Math.abs(l),Math.abs(v))&&Math.abs(e-z)<=r.EPSILON*Math.max(1,Math.abs(e),Math.abs(z))&&Math.abs(M-p)<=r.EPSILON*Math.max(1,Math.abs(M),Math.abs(p))&&Math.abs(s-w)<=r.EPSILON*Math.max(1,Math.abs(s),Math.abs(w))&&Math.abs(i-E)<=r.EPSILON*Math.max(1,Math.abs(i),Math.abs(E))&&Math.abs(c-A)<=r.EPSILON*Math.max(1,Math.abs(c),Math.abs(A))&&Math.abs(h-P)<=r.EPSILON*Math.max(1,Math.abs(h),Math.abs(P))&&Math.abs(S-L)<=r.EPSILON*Math.max(1,Math.abs(S),Math.abs(L))&&Math.abs(I-q)<=r.EPSILON*Math.max(1,Math.abs(I),Math.abs(q))&&Math.abs(f-R)<=r.EPSILON*Math.max(1,Math.abs(f),Math.abs(R))&&Math.abs(x-N)<=r.EPSILON*Math.max(1,Math.abs(x),Math.abs(N))&&Math.abs(D-O)<=r.EPSILON*Math.max(1,Math.abs(D),Math.abs(O))&&Math.abs(F-Y)<=r.EPSILON*Math.max(1,Math.abs(F),Math.abs(Y))},t.exports=o},function(t,a,n){var r=n(1),o=n(4),u=n(7),l=n(8),e={};e.create=function(){var t=new r.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},e.rotationTo=function(){var t=u.create(),a=u.fromValues(1,0,0),n=u.fromValues(0,1,0);return function(r,o,l){var M=u.dot(o,l);return M<-.999999?(u.cross(t,a,o),u.length(t)<1e-6&&u.cross(t,n,o),u.normalize(t,t),e.setAxisAngle(r,t,Math.PI),r):M>.999999?(r[0]=0,r[1]=0,r[2]=0,r[3]=1,r):(u.cross(t,o,l),r[0]=t[0],r[1]=t[1],r[2]=t[2],r[3]=1+M,e.normalize(r,r))}}(),e.setAxes=function(){var t=o.create();return function(a,n,r,o){return t[0]=r[0],t[3]=r[1],t[6]=r[2],t[1]=o[0],t[4]=o[1],t[7]=o[2],t[2]=-n[0],t[5]=-n[1],t[8]=-n[2],e.normalize(a,e.fromMat3(a,t))}}(),e.clone=l.clone,e.fromValues=l.fromValues,e.copy=l.copy,e.set=l.set,e.identity=function(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},e.setAxisAngle=function(t,a,n){n=.5*n;var r=Math.sin(n);return t[0]=r*a[0],t[1]=r*a[1],t[2]=r*a[2],t[3]=Math.cos(n),t},e.getAxisAngle=function(t,a){var n=2*Math.acos(a[3]),r=Math.sin(n/2);return 0!=r?(t[0]=a[0]/r,t[1]=a[1]/r,t[2]=a[2]/r):(t[0]=1,t[1]=0,t[2]=0),n},e.add=l.add,e.multiply=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=n[0],M=n[1],s=n[2],i=n[3];return t[0]=r*i+l*e+o*s-u*M,t[1]=o*i+l*M+u*e-r*s,t[2]=u*i+l*s+r*M-o*e,t[3]=l*i-r*e-o*M-u*s,t},e.mul=e.multiply,e.scale=l.scale,e.rotateX=function(t,a,n){n*=.5;var r=a[0],o=a[1],u=a[2],l=a[3],e=Math.sin(n),M=Math.cos(n);return t[0]=r*M+l*e,t[1]=o*M+u*e,t[2]=u*M-o*e,t[3]=l*M-r*e,t},e.rotateY=function(t,a,n){n*=.5;var r=a[0],o=a[1],u=a[2],l=a[3],e=Math.sin(n),M=Math.cos(n);return t[0]=r*M-u*e,t[1]=o*M+l*e,t[2]=u*M+r*e,t[3]=l*M-o*e,t},e.rotateZ=function(t,a,n){n*=.5;var r=a[0],o=a[1],u=a[2],l=a[3],e=Math.sin(n),M=Math.cos(n);return t[0]=r*M+o*e,t[1]=o*M-r*e,t[2]=u*M+l*e,t[3]=l*M-u*e,t},e.calculateW=function(t,a){var n=a[0],r=a[1],o=a[2];return t[0]=n,t[1]=r,t[2]=o,t[3]=Math.sqrt(Math.abs(1-n*n-r*r-o*o)),t},e.dot=l.dot,e.lerp=l.lerp,e.slerp=function(t,a,n,r){var o,u,l,e,M,s=a[0],i=a[1],c=a[2],h=a[3],S=n[0],I=n[1],f=n[2],x=n[3];return u=s*S+i*I+c*f+h*x,u<0&&(u=-u,S=-S,I=-I,f=-f,x=-x),1-u>1e-6?(o=Math.acos(u),l=Math.sin(o),e=Math.sin((1-r)*o)/l,M=Math.sin(r*o)/l):(e=1-r,M=r),t[0]=e*s+M*S,t[1]=e*i+M*I,t[2]=e*c+M*f,t[3]=e*h+M*x,t},e.sqlerp=function(){var t=e.create(),a=e.create();return function(n,r,o,u,l,M){return e.slerp(t,r,l,M),e.slerp(a,o,u,M),e.slerp(n,t,a,2*M*(1-M)),n}}(),e.invert=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=n*n+r*r+o*o+u*u,e=l?1/l:0;return t[0]=-n*e,t[1]=-r*e,t[2]=-o*e,t[3]=u*e,t},e.conjugate=function(t,a){return t[0]=-a[0],t[1]=-a[1],t[2]=-a[2],t[3]=a[3],t},e.length=l.length,e.len=e.length,e.squaredLength=l.squaredLength,e.sqrLen=e.squaredLength,e.normalize=l.normalize,e.fromMat3=function(t,a){var n,r=a[0]+a[4]+a[8];if(r>0)n=Math.sqrt(r+1),t[3]=.5*n,n=.5/n,t[0]=(a[5]-a[7])*n,t[1]=(a[6]-a[2])*n,t[2]=(a[1]-a[3])*n;else{var o=0;a[4]>a[0]&&(o=1),a[8]>a[3*o+o]&&(o=2);var u=(o+1)%3,l=(o+2)%3;n=Math.sqrt(a[3*o+o]-a[3*u+u]-a[3*l+l]+1),t[o]=.5*n,n=.5/n,t[3]=(a[3*u+l]-a[3*l+u])*n,t[u]=(a[3*u+o]+a[3*o+u])*n,t[l]=(a[3*l+o]+a[3*o+l])*n}return t},e.str=function(t){return"quat("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},e.exactEquals=l.exactEquals,e.equals=l.equals,t.exports=e},function(t,a,n){var r=n(1),o={};o.create=function(){var t=new r.ARRAY_TYPE(3);return t[0]=0,t[1]=0,t[2]=0,t},o.clone=function(t){var a=new r.ARRAY_TYPE(3);return a[0]=t[0],a[1]=t[1],a[2]=t[2],a},o.fromValues=function(t,a,n){var o=new r.ARRAY_TYPE(3);return o[0]=t,o[1]=a,o[2]=n,o},o.copy=function(t,a){return t[0]=a[0],t[1]=a[1],t[2]=a[2],t},o.set=function(t,a,n,r){return t[0]=a,t[1]=n,t[2]=r,t},o.add=function(t,a,n){return t[0]=a[0]+n[0],t[1]=a[1]+n[1],t[2]=a[2]+n[2],t},o.subtract=function(t,a,n){return t[0]=a[0]-n[0],t[1]=a[1]-n[1],t[2]=a[2]-n[2],t},o.sub=o.subtract,o.multiply=function(t,a,n){return t[0]=a[0]*n[0],t[1]=a[1]*n[1],t[2]=a[2]*n[2],t},o.mul=o.multiply,o.divide=function(t,a,n){return t[0]=a[0]/n[0],t[1]=a[1]/n[1],t[2]=a[2]/n[2],t},o.div=o.divide,o.ceil=function(t,a){return t[0]=Math.ceil(a[0]),t[1]=Math.ceil(a[1]),t[2]=Math.ceil(a[2]),t},o.floor=function(t,a){return t[0]=Math.floor(a[0]),t[1]=Math.floor(a[1]),t[2]=Math.floor(a[2]),t},o.min=function(t,a,n){return t[0]=Math.min(a[0],n[0]),t[1]=Math.min(a[1],n[1]),t[2]=Math.min(a[2],n[2]),t},o.max=function(t,a,n){return t[0]=Math.max(a[0],n[0]),t[1]=Math.max(a[1],n[1]),t[2]=Math.max(a[2],n[2]),t},o.round=function(t,a){return t[0]=Math.round(a[0]),t[1]=Math.round(a[1]),t[2]=Math.round(a[2]),t},o.scale=function(t,a,n){return t[0]=a[0]*n,t[1]=a[1]*n,t[2]=a[2]*n,t},o.scaleAndAdd=function(t,a,n,r){return t[0]=a[0]+n[0]*r,t[1]=a[1]+n[1]*r,t[2]=a[2]+n[2]*r,t},o.distance=function(t,a){var n=a[0]-t[0],r=a[1]-t[1],o=a[2]-t[2];return Math.sqrt(n*n+r*r+o*o)},o.dist=o.distance,o.squaredDistance=function(t,a){var n=a[0]-t[0],r=a[1]-t[1],o=a[2]-t[2];return n*n+r*r+o*o},o.sqrDist=o.squaredDistance,o.length=function(t){var a=t[0],n=t[1],r=t[2];return Math.sqrt(a*a+n*n+r*r)},o.len=o.length,o.squaredLength=function(t){var a=t[0],n=t[1],r=t[2];return a*a+n*n+r*r},o.sqrLen=o.squaredLength,o.negate=function(t,a){return t[0]=-a[0],t[1]=-a[1],t[2]=-a[2],t},o.inverse=function(t,a){return t[0]=1/a[0],t[1]=1/a[1],t[2]=1/a[2],t},o.normalize=function(t,a){var n=a[0],r=a[1],o=a[2],u=n*n+r*r+o*o;return u>0&&(u=1/Math.sqrt(u),t[0]=a[0]*u,t[1]=a[1]*u,t[2]=a[2]*u),t},o.dot=function(t,a){return t[0]*a[0]+t[1]*a[1]+t[2]*a[2]},o.cross=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=n[0],e=n[1],M=n[2];return t[0]=o*M-u*e,t[1]=u*l-r*M,t[2]=r*e-o*l,t},o.lerp=function(t,a,n,r){var o=a[0],u=a[1],l=a[2];return t[0]=o+r*(n[0]-o),t[1]=u+r*(n[1]-u),t[2]=l+r*(n[2]-l),t},o.hermite=function(t,a,n,r,o,u){var l=u*u,e=l*(2*u-3)+1,M=l*(u-2)+u,s=l*(u-1),i=l*(3-2*u);return t[0]=a[0]*e+n[0]*M+r[0]*s+o[0]*i,t[1]=a[1]*e+n[1]*M+r[1]*s+o[1]*i,t[2]=a[2]*e+n[2]*M+r[2]*s+o[2]*i,t},o.bezier=function(t,a,n,r,o,u){var l=1-u,e=l*l,M=u*u,s=e*l,i=3*u*e,c=3*M*l,h=M*u;return t[0]=a[0]*s+n[0]*i+r[0]*c+o[0]*h,t[1]=a[1]*s+n[1]*i+r[1]*c+o[1]*h,t[2]=a[2]*s+n[2]*i+r[2]*c+o[2]*h,t},o.random=function(t,a){a=a||1;var n=2*r.RANDOM()*Math.PI,o=2*r.RANDOM()-1,u=Math.sqrt(1-o*o)*a;return t[0]=Math.cos(n)*u,t[1]=Math.sin(n)*u,t[2]=o*a,t},o.transformMat4=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=n[3]*r+n[7]*o+n[11]*u+n[15];return l=l||1,t[0]=(n[0]*r+n[4]*o+n[8]*u+n[12])/l,t[1]=(n[1]*r+n[5]*o+n[9]*u+n[13])/l,t[2]=(n[2]*r+n[6]*o+n[10]*u+n[14])/l,t},o.transformMat3=function(t,a,n){var r=a[0],o=a[1],u=a[2];return t[0]=r*n[0]+o*n[3]+u*n[6],t[1]=r*n[1]+o*n[4]+u*n[7],t[2]=r*n[2]+o*n[5]+u*n[8],t},o.transformQuat=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=n[0],e=n[1],M=n[2],s=n[3],i=s*r+e*u-M*o,c=s*o+M*r-l*u,h=s*u+l*o-e*r,S=-l*r-e*o-M*u;return t[0]=i*s+S*-l+c*-M-h*-e,t[1]=c*s+S*-e+h*-l-i*-M,t[2]=h*s+S*-M+i*-e-c*-l,t},o.rotateX=function(t,a,n,r){var o=[],u=[];return o[0]=a[0]-n[0],o[1]=a[1]-n[1],o[2]=a[2]-n[2],u[0]=o[0],u[1]=o[1]*Math.cos(r)-o[2]*Math.sin(r),u[2]=o[1]*Math.sin(r)+o[2]*Math.cos(r),t[0]=u[0]+n[0],t[1]=u[1]+n[1],t[2]=u[2]+n[2],t},o.rotateY=function(t,a,n,r){var o=[],u=[];return o[0]=a[0]-n[0],o[1]=a[1]-n[1],o[2]=a[2]-n[2],u[0]=o[2]*Math.sin(r)+o[0]*Math.cos(r),u[1]=o[1],u[2]=o[2]*Math.cos(r)-o[0]*Math.sin(r),t[0]=u[0]+n[0],t[1]=u[1]+n[1],t[2]=u[2]+n[2],t},o.rotateZ=function(t,a,n,r){var o=[],u=[];return o[0]=a[0]-n[0],o[1]=a[1]-n[1],o[2]=a[2]-n[2],u[0]=o[0]*Math.cos(r)-o[1]*Math.sin(r),u[1]=o[0]*Math.sin(r)+o[1]*Math.cos(r),u[2]=o[2],t[0]=u[0]+n[0],t[1]=u[1]+n[1],t[2]=u[2]+n[2],t},o.forEach=function(){var t=o.create();return function(a,n,r,o,u,l){var e,M;for(n||(n=3),r||(r=0),M=o?Math.min(o*n+r,a.length):a.length,e=r;e<M;e+=n)t[0]=a[e],t[1]=a[e+1],t[2]=a[e+2],u(t,t,l),a[e]=t[0],a[e+1]=t[1],a[e+2]=t[2];return a}}(),o.angle=function(t,a){var n=o.fromValues(t[0],t[1],t[2]),r=o.fromValues(a[0],a[1],a[2]);o.normalize(n,n),o.normalize(r,r);var u=o.dot(n,r);return u>1?0:Math.acos(u)},o.str=function(t){return"vec3("+t[0]+", "+t[1]+", "+t[2]+")"},o.exactEquals=function(t,a){return t[0]===a[0]&&t[1]===a[1]&&t[2]===a[2]},o.equals=function(t,a){var n=t[0],o=t[1],u=t[2],l=a[0],e=a[1],M=a[2];return Math.abs(n-l)<=r.EPSILON*Math.max(1,Math.abs(n),Math.abs(l))&&Math.abs(o-e)<=r.EPSILON*Math.max(1,Math.abs(o),Math.abs(e))&&Math.abs(u-M)<=r.EPSILON*Math.max(1,Math.abs(u),Math.abs(M))},t.exports=o},function(t,a,n){var r=n(1),o={};o.create=function(){var t=new r.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=0,t},o.clone=function(t){var a=new r.ARRAY_TYPE(4);return a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=t[3],a},o.fromValues=function(t,a,n,o){var u=new r.ARRAY_TYPE(4);return u[0]=t,u[1]=a,u[2]=n,u[3]=o,u},o.copy=function(t,a){return t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[3],t},o.set=function(t,a,n,r,o){return t[0]=a,t[1]=n,t[2]=r,t[3]=o,t},o.add=function(t,a,n){return t[0]=a[0]+n[0],t[1]=a[1]+n[1],t[2]=a[2]+n[2],t[3]=a[3]+n[3],t},o.subtract=function(t,a,n){return t[0]=a[0]-n[0],t[1]=a[1]-n[1],t[2]=a[2]-n[2],t[3]=a[3]-n[3],t},o.sub=o.subtract,o.multiply=function(t,a,n){return t[0]=a[0]*n[0],t[1]=a[1]*n[1],t[2]=a[2]*n[2],t[3]=a[3]*n[3],t},o.mul=o.multiply,o.divide=function(t,a,n){return t[0]=a[0]/n[0],t[1]=a[1]/n[1],t[2]=a[2]/n[2],t[3]=a[3]/n[3],t},o.div=o.divide,o.ceil=function(t,a){return t[0]=Math.ceil(a[0]),t[1]=Math.ceil(a[1]),t[2]=Math.ceil(a[2]),t[3]=Math.ceil(a[3]),t},o.floor=function(t,a){return t[0]=Math.floor(a[0]),t[1]=Math.floor(a[1]),t[2]=Math.floor(a[2]),t[3]=Math.floor(a[3]),t},o.min=function(t,a,n){return t[0]=Math.min(a[0],n[0]),t[1]=Math.min(a[1],n[1]),t[2]=Math.min(a[2],n[2]),t[3]=Math.min(a[3],n[3]),t},o.max=function(t,a,n){return t[0]=Math.max(a[0],n[0]),t[1]=Math.max(a[1],n[1]),t[2]=Math.max(a[2],n[2]),t[3]=Math.max(a[3],n[3]),t},o.round=function(t,a){return t[0]=Math.round(a[0]),t[1]=Math.round(a[1]),t[2]=Math.round(a[2]),t[3]=Math.round(a[3]),t},o.scale=function(t,a,n){return t[0]=a[0]*n,t[1]=a[1]*n,t[2]=a[2]*n,t[3]=a[3]*n,t},o.scaleAndAdd=function(t,a,n,r){return t[0]=a[0]+n[0]*r,t[1]=a[1]+n[1]*r,t[2]=a[2]+n[2]*r,t[3]=a[3]+n[3]*r,t},o.distance=function(t,a){var n=a[0]-t[0],r=a[1]-t[1],o=a[2]-t[2],u=a[3]-t[3];return Math.sqrt(n*n+r*r+o*o+u*u)},o.dist=o.distance,o.squaredDistance=function(t,a){var n=a[0]-t[0],r=a[1]-t[1],o=a[2]-t[2],u=a[3]-t[3];return n*n+r*r+o*o+u*u},o.sqrDist=o.squaredDistance,o.length=function(t){var a=t[0],n=t[1],r=t[2],o=t[3];return Math.sqrt(a*a+n*n+r*r+o*o)},o.len=o.length,o.squaredLength=function(t){var a=t[0],n=t[1],r=t[2],o=t[3];return a*a+n*n+r*r+o*o},o.sqrLen=o.squaredLength,o.negate=function(t,a){return t[0]=-a[0],t[1]=-a[1],t[2]=-a[2],t[3]=-a[3],t},o.inverse=function(t,a){return t[0]=1/a[0],t[1]=1/a[1],t[2]=1/a[2],t[3]=1/a[3],t},o.normalize=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=n*n+r*r+o*o+u*u;return l>0&&(l=1/Math.sqrt(l),t[0]=n*l,t[1]=r*l,t[2]=o*l,t[3]=u*l),t},o.dot=function(t,a){return t[0]*a[0]+t[1]*a[1]+t[2]*a[2]+t[3]*a[3]},o.lerp=function(t,a,n,r){var o=a[0],u=a[1],l=a[2],e=a[3];return t[0]=o+r*(n[0]-o),t[1]=u+r*(n[1]-u),t[2]=l+r*(n[2]-l),t[3]=e+r*(n[3]-e),t},o.random=function(t,a){return a=a||1,t[0]=r.RANDOM(),t[1]=r.RANDOM(),t[2]=r.RANDOM(),t[3]=r.RANDOM(),o.normalize(t,t),o.scale(t,t,a),t},o.transformMat4=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3];return t[0]=n[0]*r+n[4]*o+n[8]*u+n[12]*l,t[1]=n[1]*r+n[5]*o+n[9]*u+n[13]*l,t[2]=n[2]*r+n[6]*o+n[10]*u+n[14]*l,t[3]=n[3]*r+n[7]*o+n[11]*u+n[15]*l,t},o.transformQuat=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=n[0],e=n[1],M=n[2],s=n[3],i=s*r+e*u-M*o,c=s*o+M*r-l*u,h=s*u+l*o-e*r,S=-l*r-e*o-M*u;return t[0]=i*s+S*-l+c*-M-h*-e,t[1]=c*s+S*-e+h*-l-i*-M,t[2]=h*s+S*-M+i*-e-c*-l,t[3]=a[3],t},o.forEach=function(){var t=o.create();return function(a,n,r,o,u,l){var e,M;for(n||(n=4),r||(r=0),M=o?Math.min(o*n+r,a.length):a.length,e=r;e<M;e+=n)t[0]=a[e],t[1]=a[e+1],t[2]=a[e+2],t[3]=a[e+3],u(t,t,l),a[e]=t[0],a[e+1]=t[1],a[e+2]=t[2],a[e+3]=t[3];return a}}(),o.str=function(t){return"vec4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},o.exactEquals=function(t,a){return t[0]===a[0]&&t[1]===a[1]&&t[2]===a[2]&&t[3]===a[3]},o.equals=function(t,a){var n=t[0],o=t[1],u=t[2],l=t[3],e=a[0],M=a[1],s=a[2],i=a[3];return Math.abs(n-e)<=r.EPSILON*Math.max(1,Math.abs(n),Math.abs(e))&&Math.abs(o-M)<=r.EPSILON*Math.max(1,Math.abs(o),Math.abs(M))&&Math.abs(u-s)<=r.EPSILON*Math.max(1,Math.abs(u),Math.abs(s))&&Math.abs(l-i)<=r.EPSILON*Math.max(1,Math.abs(l),Math.abs(i))},t.exports=o},function(t,a,n){var r=n(1),o={};o.create=function(){var t=new r.ARRAY_TYPE(2);return t[0]=0,t[1]=0,t},o.clone=function(t){var a=new r.ARRAY_TYPE(2);return a[0]=t[0],a[1]=t[1],a},o.fromValues=function(t,a){var n=new r.ARRAY_TYPE(2);return n[0]=t,n[1]=a,n},o.copy=function(t,a){return t[0]=a[0],t[1]=a[1],t},o.set=function(t,a,n){return t[0]=a,t[1]=n,t},o.add=function(t,a,n){return t[0]=a[0]+n[0],t[1]=a[1]+n[1],t},o.subtract=function(t,a,n){return t[0]=a[0]-n[0],t[1]=a[1]-n[1],t},o.sub=o.subtract,o.multiply=function(t,a,n){return t[0]=a[0]*n[0],t[1]=a[1]*n[1],t},o.mul=o.multiply,o.divide=function(t,a,n){return t[0]=a[0]/n[0],t[1]=a[1]/n[1],t},o.div=o.divide,o.ceil=function(t,a){return t[0]=Math.ceil(a[0]),t[1]=Math.ceil(a[1]),t},o.floor=function(t,a){return t[0]=Math.floor(a[0]),t[1]=Math.floor(a[1]),t},o.min=function(t,a,n){return t[0]=Math.min(a[0],n[0]),t[1]=Math.min(a[1],n[1]),t},o.max=function(t,a,n){return t[0]=Math.max(a[0],n[0]),t[1]=Math.max(a[1],n[1]),t},o.round=function(t,a){return t[0]=Math.round(a[0]),t[1]=Math.round(a[1]),t},o.scale=function(t,a,n){return t[0]=a[0]*n,t[1]=a[1]*n,t},o.scaleAndAdd=function(t,a,n,r){return t[0]=a[0]+n[0]*r,t[1]=a[1]+n[1]*r,t},o.distance=function(t,a){var n=a[0]-t[0],r=a[1]-t[1];return Math.sqrt(n*n+r*r)},o.dist=o.distance,o.squaredDistance=function(t,a){var n=a[0]-t[0],r=a[1]-t[1];return n*n+r*r},o.sqrDist=o.squaredDistance,o.length=function(t){var a=t[0],n=t[1];return Math.sqrt(a*a+n*n)},o.len=o.length,o.squaredLength=function(t){var a=t[0],n=t[1];return a*a+n*n},o.sqrLen=o.squaredLength,o.negate=function(t,a){return t[0]=-a[0],t[1]=-a[1],t},o.inverse=function(t,a){return t[0]=1/a[0],t[1]=1/a[1],t},o.normalize=function(t,a){var n=a[0],r=a[1],o=n*n+r*r;return o>0&&(o=1/Math.sqrt(o),t[0]=a[0]*o,t[1]=a[1]*o),t},o.dot=function(t,a){return t[0]*a[0]+t[1]*a[1]},o.cross=function(t,a,n){var r=a[0]*n[1]-a[1]*n[0];return t[0]=t[1]=0,t[2]=r,t},o.lerp=function(t,a,n,r){var o=a[0],u=a[1];return t[0]=o+r*(n[0]-o),t[1]=u+r*(n[1]-u),t},o.random=function(t,a){a=a||1;var n=2*r.RANDOM()*Math.PI;return t[0]=Math.cos(n)*a,t[1]=Math.sin(n)*a,t},o.transformMat2=function(t,a,n){var r=a[0],o=a[1];return t[0]=n[0]*r+n[2]*o,t[1]=n[1]*r+n[3]*o,t},o.transformMat2d=function(t,a,n){var r=a[0],o=a[1];return t[0]=n[0]*r+n[2]*o+n[4],t[1]=n[1]*r+n[3]*o+n[5],t},o.transformMat3=function(t,a,n){var r=a[0],o=a[1];return t[0]=n[0]*r+n[3]*o+n[6],t[1]=n[1]*r+n[4]*o+n[7],t},o.transformMat4=function(t,a,n){var r=a[0],o=a[1];return t[0]=n[0]*r+n[4]*o+n[12],t[1]=n[1]*r+n[5]*o+n[13],t},o.forEach=function(){var t=o.create();return function(a,n,r,o,u,l){var e,M;for(n||(n=2),r||(r=0),M=o?Math.min(o*n+r,a.length):a.length,e=r;e<M;e+=n)t[0]=a[e],t[1]=a[e+1],u(t,t,l),a[e]=t[0],a[e+1]=t[1];return a}}(),o.str=function(t){return"vec2("+t[0]+", "+t[1]+")"},o.exactEquals=function(t,a){return t[0]===a[0]&&t[1]===a[1]},o.equals=function(t,a){var n=t[0],o=t[1],u=a[0],l=a[1];return Math.abs(n-u)<=r.EPSILON*Math.max(1,Math.abs(n),Math.abs(u))&&Math.abs(o-l)<=r.EPSILON*Math.max(1,Math.abs(o),Math.abs(l))},t.exports=o}])});
\ No newline at end of file diff --git a/graphics/asymptote/webgl/gl.js b/graphics/asymptote/webgl/gl.js index ab2f5fa799..f3bdf5505f 100644 --- a/graphics/asymptote/webgl/gl.js +++ b/graphics/asymptote/webgl/gl.js @@ -1,922 +1,2140 @@ -// Contains code from http: //learningwebgl.com/blog/ ? p=28#triangle-vertex-positions -// modified to produce a subdivision algorithm for rendering Bezier -// patches with WebGL - -var gl; +/*@license + gl.js: Render Bezier patches via subdivision with WebGL. + Copyright 2019: John C. Bowman and Supakorn "Jamie" Rassameemasmuang + University of Alberta + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + + +let gl; + +let canvas; +let canvasWidth,canvasHeight; +let halfCanvasWidth,halfCanvasHeight; + +let pixel=0.75; // Adaptive rendering constant. +let BezierFactor=0.4; +let FillFactor=0.1; +let Zoom; +let Zoom0; + +let maxViewportWidth=window.innerWidth; +let maxViewportHeight=window.innerHeight; +let viewportmargin=0; + +const windowTrim=10; +let resizeStep=1.2; +let zoomFactor; +let zoomPinchFactor; +let zoomPinchCap; +let zoomStep; + +let shiftHoldDistance; +let shiftWaitTime; +let vibrateTime; + +let lastzoom; +let H; // maximum camera view half-height + +let Fuzz2=1000*Number.EPSILON; +let Fuzz4=Fuzz2*Fuzz2; +let third=1/3; + +let P=[]; // Array of Bezier patches, triangles, curves, and pixels +let Materials=[]; // Array of materials +let Lights=[]; // Array of lights +let Centers=[]; // Array of billboard centers + +// Don't account for device pixels when embedding in another html document +let absolute=false; + +let rotMat=mat4.create(); +let projMat=mat4.create(); // projection matrix +let viewMat=mat4.create(); // view matrix + +let projViewMat=mat4.create(); // projection view matrix +let normMat=mat3.create(); +let viewMat3=mat3.create(); // 3x3 view matrix +let rotMats=mat4.create(); +let cjMatInv=mat4.create(); +let translMat=mat4.create(); + +let zmin,zmax; +let center={x:0,y:0,z:0}; +let size2; +let ArcballFactor; +let b,B; // Scene min,max bounding box corners +let shift={ + x:0,y:0 +}; + +let viewParam = { + xmin:0,xmax:0, + ymin:0,ymax:0, + zmin:0,zmax:0 +}; + +let positionBuffer; +let materialBuffer; +let colorBuffer; +let indexBuffer; + +let redraw=true; +let remesh=true; +let mouseDownOrTouchActive=false; +let lastMouseX=null; +let lastMouseY=null; +let touchID=null; + +// Indexed triangles: +let Positions=[]; +let Normals=[]; +let Colors=[]; +let Indices=[]; class Material { - constructor(baseColor, emissive, specular, roughness, metallic, f0) { - this.baseColor = baseColor; - this.emissive = emissive; - this.specular = specular; - this.roughness = roughness; - this.metallic = metallic; - this.f0 = f0; + constructor(diffuse,emissive,specular,shininess,metallic,fresnel0) { + this.diffuse=diffuse; + this.emissive=emissive; + this.specular=specular; + this.shininess=shininess; + this.metallic=metallic; + this.fresnel0=fresnel0; + } + + setUniform(program,stringLoc,index=null) { + let getLoc; + if (index === null) + getLoc = + param => gl.getUniformLocation(program,stringLoc+"."+param); + else + getLoc = + param => gl.getUniformLocation(program,stringLoc+"["+index+"]."+param); + + gl.uniform4fv(getLoc("diffuse"),new Float32Array(this.diffuse)); + gl.uniform4fv(getLoc("emissive"),new Float32Array(this.emissive)); + gl.uniform4fv(getLoc("specular"),new Float32Array(this.specular)); + + gl.uniform1f(getLoc("shininess"),this.shininess); + gl.uniform1f(getLoc("metallic"),this.metallic); + gl.uniform1f(getLoc("fresnel0"),this.fresnel0); + } +} + +let enumPointLight=1; +let enumDirectionalLight=2; + +class Light { + constructor(direction,color) { + this.direction=direction; + this.color=color; + } + + setUniform(program,stringLoc,index) { + let getLoc= + param => gl.getUniformLocation(program,stringLoc+"["+index+"]."+param); + + gl.uniform3fv(getLoc("direction"),new Float32Array(this.direction)); + gl.uniform3fv(getLoc("color"),new Float32Array(this.color)); + } +} + +function initGL() { + try { + gl=canvas.getContext("webgl",{alpha:false}); // Don't composite background + } catch(e) {} + if (!gl) + alert("Could not initialize WebGL"); +} + +function getShader(gl,id,options=[]) { + let shaderScript=document.getElementById(id); + if(!shaderScript) + return null; + + let str=`#version 100 +#ifdef GL_FRAGMENT_PRECISION_HIGH + precision highp float; +#else + precision mediump float; +#endif + const int nLights=${Lights.length}; + const int nMaterials=${Materials.length};\n` + + if(orthographic) + str += `#define ORTHOGRAPHIC\n`; + + options.forEach(s => str += `#define `+s+`\n`); + + let k=shaderScript.firstChild; + while(k) { + if(k.nodeType == 3) + str += k.textContent; + k=k.nextSibling; + } + let shader; + if(shaderScript.type == "x-shader/x-fragment") + shader = gl.createShader(gl.FRAGMENT_SHADER); + else if (shaderScript.type == "x-shader/x-vertex") + shader = gl.createShader(gl.VERTEX_SHADER); + else + return null; + + gl.shaderSource(shader,str); + gl.compileShader(shader); + if(!gl.getShaderParameter(shader,gl.COMPILE_STATUS)) { + alert(gl.getShaderInfoLog(shader)); + return null; + } + return shader; +} + + +function drawBuffer(data,shader,indices=data.indices) +{ + if(data.indices.length == 0) return; + let pixel=shader == pixelShader; + let normal=!pixel && (shader != noNormalShader); + + setUniforms(shader); + + gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer); + gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(data.vertices), + gl.STATIC_DRAW); + gl.vertexAttribPointer(shader.vertexPositionAttribute, + 3,gl.FLOAT,false,normal ? 24 : (pixel ? 16 : 12),0); + if(normal) + gl.vertexAttribPointer(shader.vertexNormalAttribute, + 3,gl.FLOAT,false,24,12); + else if(pixel) + gl.vertexAttribPointer(shader.vertexWidthAttribute, + 1,gl.FLOAT,false,16,12); + + gl.bindBuffer(gl.ARRAY_BUFFER,materialBuffer); + gl.bufferData(gl.ARRAY_BUFFER,new Int16Array(data.materials), + gl.STATIC_DRAW); + gl.vertexAttribPointer(shader.vertexMaterialAttribute, + 1,gl.SHORT,false,2,0); + + if(shader == colorShader || shader == transparentShader) { + gl.bindBuffer(gl.ARRAY_BUFFER,colorBuffer); + gl.bufferData(gl.ARRAY_BUFFER,new Uint8Array(data.colors), + gl.STATIC_DRAW); + gl.vertexAttribPointer(shader.vertexColorAttribute, + 4,gl.UNSIGNED_BYTE,true,0,0); + } + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indexBuffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, + indexExt ? new Uint32Array(indices) : + new Uint16Array(indices),gl.STATIC_DRAW); + + gl.drawElements(normal ? gl.TRIANGLES : (pixel ? gl.POINTS : gl.LINES), + indices.length, + indexExt ? gl.UNSIGNED_INT : gl.UNSIGNED_SHORT,0); +} + +class vertexBuffer { + constructor() { + this.clear(); + } + clear() { + this.vertices=[]; + this.materials=[]; + this.colors=[]; + this.indices=[]; + this.nvertices=0; + } + + // material vertex + vertex(v,n) { + this.vertices.push(v[0]); + this.vertices.push(v[1]); + this.vertices.push(v[2]); + this.vertices.push(n[0]); + this.vertices.push(n[1]); + this.vertices.push(n[2]); + this.materials.push(materialIndex); + return this.nvertices++; + } + + // colored vertex + Vertex(v,n,c=[0,0,0,0]) { + this.vertices.push(v[0]); + this.vertices.push(v[1]); + this.vertices.push(v[2]); + this.vertices.push(n[0]); + this.vertices.push(n[1]); + this.vertices.push(n[2]); + this.materials.push(materialIndex); + this.colors.push(c[0]); + this.colors.push(c[1]); + this.colors.push(c[2]); + this.colors.push(c[3]); + return this.nvertices++; + } + + // material vertex without normal + vertex1(v) { + this.vertices.push(v[0]); + this.vertices.push(v[1]); + this.vertices.push(v[2]); + this.materials.push(materialIndex); + return this.nvertices++; + } + + // material vertex with width and without normal + vertex0(v,width) { + this.vertices.push(v[0]); + this.vertices.push(v[1]); + this.vertices.push(v[2]); + this.vertices.push(width); + this.materials.push(materialIndex); + return this.nvertices++; + } + + // indexed colored vertex + iVertex(i,v,n,c=[0,0,0,0]) { + let i6=6*i; + this.vertices[i6]=v[0]; + this.vertices[i6+1]=v[1]; + this.vertices[i6+2]=v[2]; + this.vertices[i6+3]=n[0]; + this.vertices[i6+4]=n[1]; + this.vertices[i6+5]=n[2]; + this.materials[i]=materialIndex; + let i4=4*i; + this.colors[i4]=c[0]; + this.colors[i4+1]=c[1]; + this.colors[i4+2]=c[2]; + this.colors[i4+3]=c[3]; + this.indices.push(i); + } + + append(data) { + append(this.vertices,data.vertices); + append(this.materials,data.materials); + append(this.colors,data.colors); + appendOffset(this.indices,data.indices,this.nvertices); + this.nvertices += data.nvertices; + } +} + +let material0Data=new vertexBuffer(); // pixels +let material1Data=new vertexBuffer(); // material Bezier curves +let materialData=new vertexBuffer(); // material Bezier patches & triangles +let colorData=new vertexBuffer(); // colored Bezier patches & triangles +let transparentData=new vertexBuffer(); // transparent patches & triangles +let triangleData=new vertexBuffer(); // opaque indexed triangles + + +let materialIndex; + +// efficiently append array b onto array a +function append(a,b) +{ + let n=a.length; + let m=b.length; + a.length += m; + for(let i=0; i < m; ++i) + a[n+i]=b[i]; +} + +// efficiently append array b onto array a +function appendOffset(a,b,o) +{ + let n=a.length; + let m=b.length; + a.length += b.length; + for(let i=0; i < m; ++i) + a[n+i]=b[i]+o; +} + +class Geometry { + constructor() { + this.data=new vertexBuffer(); + this.Onscreen=false; + this.m=[]; + } + + // Is 2D bounding box formed by projecting 3d points in vector v offscreen? + offscreen(v) { + let m=projViewMat; + let v0=v[0]; + let x=v0[0], y=v0[1], z=v0[2]; + let f=1/(m[3]*x+m[7]*y+m[11]*z+m[15]); + this.x=this.X=(m[0]*x+m[4]*y+m[8]*z+m[12])*f; + this.y=this.Y=(m[1]*x+m[5]*y+m[9]*z+m[13])*f; + for(let i=1, n=v.length; i < n; ++i) { + let vi=v[i]; + let x=vi[0], y=vi[1], z=vi[2]; + let f=1/(m[3]*x+m[7]*y+m[11]*z+m[15]); + let X=(m[0]*x+m[4]*y+m[8]*z+m[12])*f; + let Y=(m[1]*x+m[5]*y+m[9]*z+m[13])*f; + if(X < this.x) this.x=X; + else if(X > this.X) this.X=X; + if(Y < this.y) this.y=Y; + else if(Y > this.Y) this.Y=Y; + } + let eps=1e-2; + let min=-1-eps; + let max=1+eps; + if(this.X < min || this.x > max || this.Y < min || this.y > max) { + this.Onscreen=false; + return true; } + return false; + } - setUniform(program, stringLoc, index=null) { - var getLoc; - if (index===null) { - getLoc = - param => gl.getUniformLocation(program, stringLoc + "." + param); - } else { - getLoc = - param => gl.getUniformLocation(program, stringLoc + "[" + index + "]." + param); - } + T(v) { + let c0=this.c[0]; + let c1=this.c[1]; + let c2=this.c[2]; + let x=v[0]-c0; + let y=v[1]-c1; + let z=v[2]-c2; + return [x*normMat[0]+y*normMat[3]+z*normMat[6]+c0, + x*normMat[1]+y*normMat[4]+z*normMat[7]+c1, + x*normMat[2]+y*normMat[5]+z*normMat[8]+c2]; + } - gl.uniform4fv(getLoc("baseColor"), new Float32Array(this.baseColor)); - gl.uniform4fv(getLoc("emissive"), new Float32Array(this.emissive)); - gl.uniform4fv(getLoc("specular"), new Float32Array(this.specular)); + Tcorners(m,M) { + return [this.T(m),this.T([m[0],m[1],M[2]]),this.T([m[0],M[1],m[2]]), + this.T([m[0],M[1],M[2]]),this.T([M[0],m[1],m[2]]), + this.T([M[0],m[1],M[2]]),this.T([M[0],M[1],m[2]]),this.T(M)]; - gl.uniform1f(getLoc("roughness"), this.roughness); - gl.uniform1f(getLoc("metallic"), this.metallic); - gl.uniform1f(getLoc("f0"), this.f0); + } + + render() { + // First check if re-rendering is required + let v; + if(this.CenterIndex == 0) + v=corners(this.Min,this.Max); + else { + this.c=Centers[this.CenterIndex-1]; + v=this.Tcorners(this.Min,this.Max); + } + + if(this.offscreen(v)) { // Fully offscreen + this.data.clear(); + return; } + + let p=this.controlpoints; + let P; + + if(this.CenterIndex == 0) { + if(!remesh && this.Onscreen) { + // Fully onscreen; no need to re-render + this.append(); + return; + } + P=p; + } else { // Transform billboard labels + let n=p.length; + P=Array(n); + for(let i=0; i < n; ++i) + P[i]=this.T(p[i]); + } + + materialIndex=this.MaterialIndex; + + let s=orthographic ? 1 : this.Min[2]/B[2]; + let res=pixel*Math.hypot(s*(viewParam.xmax-viewParam.xmin), + s*(viewParam.ymax-viewParam.ymin))/size2; + this.res2=res*res; + this.Epsilon=FillFactor*res; + + this.data.clear(); + this.Onscreen=true; + this.process(P); + } } -var enumPointLight = 1; -var enumDirectionalLight = 2; +class BezierPatch extends Geometry { + /** + * Constructor for Bezier Patch + * @param {*} controlpoints array of 16 control points + * @param {*} CenterIndex center index of billboard labels (or 0) + * @param {*} MaterialIndex material index (>= 0) + * @param {*} Min bounding box corner + * @param {*} Max bounding box corner + * @param {*} colors array of 4 RGBA color arrays + */ + constructor(controlpoints,CenterIndex,MaterialIndex,Min,Max,color) { + super(); + this.controlpoints=controlpoints; + this.Min=Min; + this.Max=Max; + this.color=color; + this.CenterIndex=CenterIndex; + let n=controlpoints.length; + if(color) { + let sum=color[0][3]+color[1][3]+color[2][3]; + this.transparent=(n == 16 || n == 4) ? + sum+color[3][3] < 1020 : sum < 765; + } else + this.transparent=Materials[MaterialIndex].diffuse[3] < 1; + if(this.transparent) { + this.MaterialIndex=color ? -1-MaterialIndex : 1+MaterialIndex; + this.vertex=this.data.Vertex.bind(this.data); + } else { + this.MaterialIndex=MaterialIndex; + this.vertex=this.data.vertex.bind(this.data); + } + this.L2norm(this.controlpoints); + } -class Light { - constructor(type, lightColor, brightness, customParam) { - this.type = type; - this.lightColor = lightColor; - this.brightness = brightness; - this.customParam = customParam; +// Render a Bezier patch via subdivision. + L2norm(p) { + let p0=p[0]; + this.epsilon=0; + let n=p.length; + for(let i=1; i < n; ++i) + this.epsilon=Math.max(this.epsilon, + abs2([p[i][0]-p0[0],p[i][1]-p0[1],p[i][2]-p0[2]])); + this.epsilon *= Fuzz4; + } + + processTriangle(p) { + let p0=p[0]; + let p1=p[1]; + let p2=p[2]; + let n=unit(cross([p1[0]-p0[0],p1[1]-p0[1],p1[2]-p0[2]], + [p2[0]-p0[0],p2[1]-p0[1],p2[2]-p0[2]])); + if(!this.offscreen([p0,p1,p2])) { + if(this.color) { + this.data.indices.push(this.data.Vertex(p0,n,this.color[0])); + this.data.indices.push(this.data.Vertex(p1,n,this.color[1])); + this.data.indices.push(this.data.Vertex(p2,n,this.color[2])); + } else { + this.data.indices.push(this.vertex(p0,n)); + this.data.indices.push(this.vertex(p1,n)); + this.data.indices.push(this.vertex(p2,n)); + } + this.append(); } + } - setUniform(program, stringLoc, index) { - var getLoc = - param => gl.getUniformLocation(program, stringLoc + "[" + index + "]." + param); + processQuad(p) { + let p0=p[0]; + let p1=p[1]; + let p2=p[2]; + let p3=p[3]; + let n1=cross([p1[0]-p0[0],p1[1]-p0[1],p1[2]-p0[2]], + [p2[0]-p1[0],p2[1]-p1[1],p2[2]-p1[2]]); + let n2=cross([p2[0]-p3[0],p2[1]-p3[1],p2[2]-p3[2]], + [p3[0]-p0[0],p3[1]-p0[1],p3[2]-p0[2]]); + let n=unit([n1[0]+n2[0],n1[1]+n2[1],n1[2]+n2[2]]); + if(!this.offscreen([p0,p1,p2,p3])) { + let i0,i1,i2,i3; + if(this.color) { + i0=this.data.Vertex(p0,n,this.color[0]); + i1=this.data.Vertex(p1,n,this.color[1]); + i2=this.data.Vertex(p2,n,this.color[2]); + i3=this.data.Vertex(p3,n,this.color[3]); + } else { + i0=this.vertex(p0,n); + i1=this.vertex(p1,n); + i2=this.vertex(p2,n); + i3=this.vertex(p3,n); + } + this.data.indices.push(i0); + this.data.indices.push(i1); + this.data.indices.push(i2); + + this.data.indices.push(i0); + this.data.indices.push(i2); + this.data.indices.push(i3); + + this.append(); + } + } - gl.uniform1i(getLoc("type"), this.type); - gl.uniform3fv(getLoc("color"), new Float32Array(this.lightColor)); - gl.uniform1f(getLoc("brightness"), this.brightness); - gl.uniform4fv(getLoc("parameter"), new Float32Array(this.customParam)); + process(p) { + if(p.length == 10) return this.process3(p); + if(p.length == 3) return this.processTriangle(p); + if(p.length == 4) return this.processQuad(p); + + let p0=p[0]; + let p3=p[3]; + let p12=p[12]; + let p15=p[15]; + + let n0=this.normal(p3,p[2],p[1],p0,p[4],p[8],p12); + if(iszero(n0)) { + n0=this.normal(p3,p[2],p[1],p0,p[13],p[14],p15); + if(iszero(n0)) n0=this.normal(p15,p[11],p[7],p3,p[4],p[8],p12); } -} -function initGL(canvas) { - try { - gl = canvas.getContext("webgl2"); - gl.viewportWidth = canvas.width; - gl.viewportHeight = canvas.height; - } catch (e) {} - if (!gl) { - alert("Could not initialize WebGL"); + let n1=this.normal(p0,p[4],p[8],p12,p[13],p[14],p15); + if(iszero(n1)) { + n1=this.normal(p0,p[4],p[8],p12,p[11],p[7],p3); + if(iszero(n1)) n1=this.normal(p3,p[2],p[1],p0,p[13],p[14],p15); } -} -function getShader(gl, id) { - var shaderScript = document.getElementById(id); - if (!shaderScript) { - return null; + let n2=this.normal(p12,p[13],p[14],p15,p[11],p[7],p3); + if(iszero(n2)) { + n2=this.normal(p12,p[13],p[14],p15,p[2],p[1],p0); + if(iszero(n2)) n2=this.normal(p0,p[4],p[8],p12,p[11],p[7],p3); } - var str = ""; - var k = shaderScript.firstChild; - while (k) { - if (k.nodeType == 3) { - str += k.textContent; - } - k = k.nextSibling; + + let n3=this.normal(p15,p[11],p[7],p3,p[2],p[1],p0); + if(iszero(n3)) { + n3=this.normal(p15,p[11],p[7],p3,p[4],p[8],p12); + if(iszero(n3)) n3=this.normal(p12,p[13],p[14],p15,p[2],p[1],p0); } - var shader; - if (shaderScript.type == "x-shader/x-fragment") { - shader = gl.createShader(gl.FRAGMENT_SHADER); - } else if (shaderScript.type == "x-shader/x-vertex") { - shader = gl.createShader(gl.VERTEX_SHADER); + + if(this.color) { + let c0=this.color[0]; + let c1=this.color[1]; + let c2=this.color[2]; + let c3=this.color[3]; + + let i0=this.data.Vertex(p0,n0,c0); + let i1=this.data.Vertex(p12,n1,c1); + let i2=this.data.Vertex(p15,n2,c2); + let i3=this.data.Vertex(p3,n3,c3); + + this.Render(p,i0,i1,i2,i3,p0,p12,p15,p3,false,false,false,false, + c0,c1,c2,c3); } else { - return null; + let i0=this.vertex(p0,n0); + let i1=this.vertex(p12,n1); + let i2=this.vertex(p15,n2); + let i3=this.vertex(p3,n3); + + this.Render(p,i0,i1,i2,i3,p0,p12,p15,p3,false,false,false,false); } - gl.shaderSource(shader, str); - gl.compileShader(shader); - if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { - alert(gl.getShaderInfoLog(shader)); - return null; + if(this.data.indices.length > 0) this.append(); + } + + append() { + if(this.transparent) + transparentData.append(this.data); + else if(this.color) + colorData.append(this.data); + else + materialData.append(this.data); + } + + Render(p,I0,I1,I2,I3,P0,P1,P2,P3,flat0,flat1,flat2,flat3,C0,C1,C2,C3) { + if(this.Distance(p) < this.res2) { // Bezier patch is flat + if(!this.offscreen([P0,P1,P2])) { + this.data.indices.push(I0); + this.data.indices.push(I1); + this.data.indices.push(I2); + } + if(!this.offscreen([P0,P2,P3])) { + this.data.indices.push(I0); + this.data.indices.push(I2); + this.data.indices.push(I3); + } + } else { + // Approximate bounds by bounding box of control polyhedron. + if(this.offscreen(p)) return; + + /* Control points are indexed as follows: + + Coordinate + +----- + Index + + + 03 13 23 33 + +-----+-----+-----+ + |3 |7 |11 |15 + | | | | + |02 |12 |22 |32 + +-----+-----+-----+ + |2 |6 |10 |14 + | | | | + |01 |11 |21 |31 + +-----+-----+-----+ + |1 |5 |9 |13 + | | | | + |00 |10 |20 |30 + +-----+-----+-----+ + 0 4 8 12 + + + Subdivision: + P refers to a corner + m refers to a midpoint + s refers to a subpatch + + m2 + +--------+--------+ + |P3 | P2| + | | | + | s3 | s2 | + | | | + | |m4 | + m3+--------+--------+m1 + | | | + | | | + | s0 | s1 | + | | | + |P0 | P1| + +--------+--------+ + m0 + */ + + // Subdivide patch: + + let p0=p[0]; + let p3=p[3]; + let p12=p[12]; + let p15=p[15]; + + let c0=new Split3(p0,p[1],p[2],p3); + let c1=new Split3(p[4],p[5],p[6],p[7]); + let c2=new Split3(p[8],p[9],p[10],p[11]); + let c3=new Split3(p12,p[13],p[14],p15); + + let c4=new Split3(p0,p[4],p[8],p12); + let c5=new Split3(c0.m0,c1.m0,c2.m0,c3.m0); + let c6=new Split3(c0.m3,c1.m3,c2.m3,c3.m3); + let c7=new Split3(c0.m5,c1.m5,c2.m5,c3.m5); + let c8=new Split3(c0.m4,c1.m4,c2.m4,c3.m4); + let c9=new Split3(c0.m2,c1.m2,c2.m2,c3.m2); + let c10=new Split3(p3,p[7],p[11],p15); + + let s0=[p0,c0.m0,c0.m3,c0.m5,c4.m0,c5.m0,c6.m0,c7.m0, + c4.m3,c5.m3,c6.m3,c7.m3,c4.m5,c5.m5,c6.m5,c7.m5]; + let s1=[c4.m5,c5.m5,c6.m5,c7.m5,c4.m4,c5.m4,c6.m4,c7.m4, + c4.m2,c5.m2,c6.m2,c7.m2,p12,c3.m0,c3.m3,c3.m5]; + let s2=[c7.m5,c8.m5,c9.m5,c10.m5,c7.m4,c8.m4,c9.m4,c10.m4, + c7.m2,c8.m2,c9.m2,c10.m2,c3.m5,c3.m4,c3.m2,p15]; + let s3=[c0.m5,c0.m4,c0.m2,p3,c7.m0,c8.m0,c9.m0,c10.m0, + c7.m3,c8.m3,c9.m3,c10.m3,c7.m5,c8.m5,c9.m5,c10.m5]; + + let m4=s0[15]; + + let n0=this.normal(s0[0],s0[4],s0[8],s0[12],s0[13],s0[14],s0[15]); + if(iszero(n0)) { + n0=this.normal(s0[0],s0[4],s0[8],s0[12],s0[11],s0[7],s0[3]); + if(iszero(n0)) + n0=this.normal(s0[3],s0[2],s0[1],s0[0],s0[13],s0[14],s0[15]); + } + + let n1=this.normal(s1[12],s1[13],s1[14],s1[15],s1[11],s1[7],s1[3]); + if(iszero(n1)) { + n1=this.normal(s1[12],s1[13],s1[14],s1[15],s1[2],s1[1],s1[0]); + if(iszero(n1)) + n1=this.normal(s1[0],s1[4],s1[8],s1[12],s1[11],s1[7],s1[3]); + } + + let n2=this.normal(s2[15],s2[11],s2[7],s2[3],s2[2],s2[1],s2[0]); + if(iszero(n2)) { + n2=this.normal(s2[15],s2[11],s2[7],s2[3],s2[4],s2[8],s2[12]); + if(iszero(n2)) + n2=this.normal(s2[12],s2[13],s2[14],s2[15],s2[2],s2[1],s2[0]); + } + + let n3=this.normal(s3[3],s3[2],s3[1],s3[0],s3[4],s3[8],s3[12]); + if(iszero(n3)) { + n3=this.normal(s3[3],s3[2],s3[1],s3[0],s3[13],s3[14],s3[15]); + if(iszero(n3)) + n3=this.normal(s3[15],s3[11],s3[7],s3[3],s3[4],s3[8],s3[12]); + } + + let n4=this.normal(s2[3],s2[2],s2[1],m4,s2[4],s2[8],s2[12]); + + let e=this.Epsilon; + + // A kludge to remove subdivision cracks, only applied the first time + // an edge is found to be flat before the rest of the subpatch is. + let m0=[0.5*(P0[0]+P1[0]), + 0.5*(P0[1]+P1[1]), + 0.5*(P0[2]+P1[2])]; + if(!flat0) { + if((flat0=Straightness(p0,p[4],p[8],p12) < this.res2)) { + let r=unit(this.derivative(s1[0],s1[1],s1[2],s1[3])); + m0=[m0[0]-e*r[0],m0[1]-e*r[1],m0[2]-e*r[2]]; + } + else m0=s0[12]; + } + + let m1=[0.5*(P1[0]+P2[0]), + 0.5*(P1[1]+P2[1]), + 0.5*(P1[2]+P2[2])]; + if(!flat1) { + if((flat1=Straightness(p12,p[13],p[14],p15) < this.res2)) { + let r=unit(this.derivative(s2[12],s2[8],s2[4],s2[0])); + m1=[m1[0]-e*r[0],m1[1]-e*r[1],m1[2]-e*r[2]]; + } + else m1=s1[15]; + } + + let m2=[0.5*(P2[0]+P3[0]), + 0.5*(P2[1]+P3[1]), + 0.5*(P2[2]+P3[2])]; + if(!flat2) { + if((flat2=Straightness(p15,p[11],p[7],p3) < this.res2)) { + let r=unit(this.derivative(s3[15],s2[14],s2[13],s1[12])); + m2=[m2[0]-e*r[0],m2[1]-e*r[1],m2[2]-e*r[2]]; + } + else m2=s2[3]; + } + + let m3=[0.5*(P3[0]+P0[0]), + 0.5*(P3[1]+P0[1]), + 0.5*(P3[2]+P0[2])]; + if(!flat3) { + if((flat3=Straightness(p0,p[1],p[2],p3) < this.res2)) { + let r=unit(this.derivative(s0[3],s0[7],s0[11],s0[15])); + m3=[m3[0]-e*r[0],m3[1]-e*r[1],m3[2]-e*r[2]]; + } + else m3=s3[0]; + } + + if(C0) { + let c0=Array(4); + let c1=Array(4); + let c2=Array(4); + let c3=Array(4); + let c4=Array(4); + for(let i=0; i < 4; ++i) { + c0[i]=0.5*(C0[i]+C1[i]); + c1[i]=0.5*(C1[i]+C2[i]); + c2[i]=0.5*(C2[i]+C3[i]); + c3[i]=0.5*(C3[i]+C0[i]); + c4[i]=0.5*(c0[i]+c2[i]); + } + + let i0=this.data.Vertex(m0,n0,c0); + let i1=this.data.Vertex(m1,n1,c1); + let i2=this.data.Vertex(m2,n2,c2); + let i3=this.data.Vertex(m3,n3,c3); + let i4=this.data.Vertex(m4,n4,c4); + + this.Render(s0,I0,i0,i4,i3,P0,m0,m4,m3,flat0,false,false,flat3, + C0,c0,c4,c3); + this.Render(s1,i0,I1,i1,i4,m0,P1,m1,m4,flat0,flat1,false,false, + c0,C1,c1,c4); + this.Render(s2,i4,i1,I2,i2,m4,m1,P2,m2,false,flat1,flat2,false, + c4,c1,C2,c2); + this.Render(s3,i3,i4,i2,I3,m3,m4,m2,P3,false,false,flat2,flat3, + c3,c4,c2,C3); + } else { + let i0=this.vertex(m0,n0); + let i1=this.vertex(m1,n1); + let i2=this.vertex(m2,n2); + let i3=this.vertex(m3,n3); + let i4=this.vertex(m4,n4); + + this.Render(s0,I0,i0,i4,i3,P0,m0,m4,m3,flat0,false,false,flat3); + this.Render(s1,i0,I1,i1,i4,m0,P1,m1,m4,flat0,flat1,false,false); + this.Render(s2,i4,i1,I2,i2,m4,m1,P2,m2,false,flat1,flat2,false); + this.Render(s3,i3,i4,i2,I3,m3,m4,m2,P3,false,false,flat2,flat3); + } } - return shader; -} + } -function resetCamera() { - cameraPos = vec3.fromValues(0, 0, 2); - cameraLookAt = vec3.fromValues(0, 0, 0); - cameraUp = vec3.fromValues(1, 0, 0); - sceneSetup(); - redraw=true; -} +// Render a Bezier triangle via subdivision. + process3(p) { + this.Res2=BezierFactor*BezierFactor*this.res2; -var shaderProgram; + let p0=p[0]; + let p6=p[6]; + let p9=p[9]; -function initShaders() { - var fragmentShader = getShader(gl, "shader-fs"); - var vertexShader = getShader(gl, "shader-vs"); - shaderProgram = gl.createProgram(); - gl.attachShader(shaderProgram, vertexShader); - gl.attachShader(shaderProgram, fragmentShader); - gl.linkProgram(shaderProgram); - if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { - alert("Could not initialize shaders"); + let n0=this.normal(p9,p[5],p[2],p0,p[1],p[3],p6); + let n1=this.normal(p0,p[1],p[3],p6,p[7],p[8],p9); + let n2=this.normal(p6,p[7],p[8],p9,p[5],p[2],p0); + + if(this.color) { + let c0=this.color[0]; + let c1=this.color[1]; + let c2=this.color[2]; + + let i0=this.data.Vertex(p0,n0,c0); + let i1=this.data.Vertex(p6,n1,c1); + let i2=this.data.Vertex(p9,n2,c2); + + this.Render3(p,i0,i1,i2,p0,p6,p9,false,false,false,c0,c1,c2); + + } else { + let i0=this.vertex(p0,n0); + let i1=this.vertex(p6,n1); + let i2=this.vertex(p9,n2); + + this.Render3(p,i0,i1,i2,p0,p6,p9,false,false,false); + } + if(this.data.indices.length > 0) this.append(); + } + + Render3(p,I0,I1,I2,P0,P1,P2,flat0,flat1,flat2,C0,C1,C2) { + if(this.Distance3(p) < this.Res2) { // Bezier triangle is flat + if(!this.offscreen([P0,P1,P2])) { + this.data.indices.push(I0); + this.data.indices.push(I1); + this.data.indices.push(I2); + } + } else { + // Approximate bounds by bounding box of control polyhedron. + if(this.offscreen(p)) return; + + /* Control points are indexed as follows: + + Coordinate + Index + + 030 + 9 + /\ + / \ + / \ + / \ + / \ + 021 + + 120 + 5 / \ 8 + / \ + / \ + / \ + / \ + 012 + + + 210 + 2 / 111 \ 7 + / 4 \ + / \ + / \ + / \ + /__________________________________\ + 003 102 201 300 + 0 1 3 6 + + + Subdivision: + P2 + 030 + /\ + / \ + / \ + / \ + / \ + / up \ + / \ + / \ + p1 /________________\ p0 + /\ / \ + / \ / \ + / \ / \ + / \ center / \ + / \ / \ + / \ / \ + / left \ / right \ + / \ / \ + /________________V_________________\ + 003 p2 300 + P0 P1 + */ + + // Subdivide triangle: + + let l003=p[0]; + let p102=p[1]; + let p012=p[2]; + let p201=p[3]; + let p111=p[4]; + let p021=p[5]; + let r300=p[6]; + let p210=p[7]; + let p120=p[8]; + let u030=p[9]; + + let u021=[0.5*(u030[0]+p021[0]), + 0.5*(u030[1]+p021[1]), + 0.5*(u030[2]+p021[2])]; + let u120=[0.5*(u030[0]+p120[0]), + 0.5*(u030[1]+p120[1]), + 0.5*(u030[2]+p120[2])]; + + let p033=[0.5*(p021[0]+p012[0]), + 0.5*(p021[1]+p012[1]), + 0.5*(p021[2]+p012[2])]; + let p231=[0.5*(p120[0]+p111[0]), + 0.5*(p120[1]+p111[1]), + 0.5*(p120[2]+p111[2])]; + let p330=[0.5*(p120[0]+p210[0]), + 0.5*(p120[1]+p210[1]), + 0.5*(p120[2]+p210[2])]; + + let p123=[0.5*(p012[0]+p111[0]), + 0.5*(p012[1]+p111[1]), + 0.5*(p012[2]+p111[2])]; + + let l012=[0.5*(p012[0]+l003[0]), + 0.5*(p012[1]+l003[1]), + 0.5*(p012[2]+l003[2])]; + let p312=[0.5*(p111[0]+p201[0]), + 0.5*(p111[1]+p201[1]), + 0.5*(p111[2]+p201[2])]; + let r210=[0.5*(p210[0]+r300[0]), + 0.5*(p210[1]+r300[1]), + 0.5*(p210[2]+r300[2])]; + + let l102=[0.5*(l003[0]+p102[0]), + 0.5*(l003[1]+p102[1]), + 0.5*(l003[2]+p102[2])]; + let p303=[0.5*(p102[0]+p201[0]), + 0.5*(p102[1]+p201[1]), + 0.5*(p102[2]+p201[2])]; + let r201=[0.5*(p201[0]+r300[0]), + 0.5*(p201[1]+r300[1]), + 0.5*(p201[2]+r300[2])]; + + let u012=[0.5*(u021[0]+p033[0]), + 0.5*(u021[1]+p033[1]), + 0.5*(u021[2]+p033[2])]; + let u210=[0.5*(u120[0]+p330[0]), + 0.5*(u120[1]+p330[1]), + 0.5*(u120[2]+p330[2])]; + let l021=[0.5*(p033[0]+l012[0]), + 0.5*(p033[1]+l012[1]), + 0.5*(p033[2]+l012[2])]; + let p4xx=[0.5*p231[0]+0.25*(p111[0]+p102[0]), + 0.5*p231[1]+0.25*(p111[1]+p102[1]), + 0.5*p231[2]+0.25*(p111[2]+p102[2])]; + let r120=[0.5*(p330[0]+r210[0]), + 0.5*(p330[1]+r210[1]), + 0.5*(p330[2]+r210[2])]; + let px4x=[0.5*p123[0]+0.25*(p111[0]+p210[0]), + 0.5*p123[1]+0.25*(p111[1]+p210[1]), + 0.5*p123[2]+0.25*(p111[2]+p210[2])]; + let pxx4=[0.25*(p021[0]+p111[0])+0.5*p312[0], + 0.25*(p021[1]+p111[1])+0.5*p312[1], + 0.25*(p021[2]+p111[2])+0.5*p312[2]]; + let l201=[0.5*(l102[0]+p303[0]), + 0.5*(l102[1]+p303[1]), + 0.5*(l102[2]+p303[2])]; + let r102=[0.5*(p303[0]+r201[0]), + 0.5*(p303[1]+r201[1]), + 0.5*(p303[2]+r201[2])]; + + let l210=[0.5*(px4x[0]+l201[0]), + 0.5*(px4x[1]+l201[1]), + 0.5*(px4x[2]+l201[2])]; // =c120 + let r012=[0.5*(px4x[0]+r102[0]), + 0.5*(px4x[1]+r102[1]), + 0.5*(px4x[2]+r102[2])]; // =c021 + let l300=[0.5*(l201[0]+r102[0]), + 0.5*(l201[1]+r102[1]), + 0.5*(l201[2]+r102[2])]; // =r003=c030 + + let r021=[0.5*(pxx4[0]+r120[0]), + 0.5*(pxx4[1]+r120[1]), + 0.5*(pxx4[2]+r120[2])]; // =c012 + let u201=[0.5*(u210[0]+pxx4[0]), + 0.5*(u210[1]+pxx4[1]), + 0.5*(u210[2]+pxx4[2])]; // =c102 + let r030=[0.5*(u210[0]+r120[0]), + 0.5*(u210[1]+r120[1]), + 0.5*(u210[2]+r120[2])]; // =u300=c003 + + let u102=[0.5*(u012[0]+p4xx[0]), + 0.5*(u012[1]+p4xx[1]), + 0.5*(u012[2]+p4xx[2])]; // =c201 + let l120=[0.5*(l021[0]+p4xx[0]), + 0.5*(l021[1]+p4xx[1]), + 0.5*(l021[2]+p4xx[2])]; // =c210 + let l030=[0.5*(u012[0]+l021[0]), + 0.5*(u012[1]+l021[1]), + 0.5*(u012[2]+l021[2])]; // =u003=c300 + + let l111=[0.5*(p123[0]+l102[0]), + 0.5*(p123[1]+l102[1]), + 0.5*(p123[2]+l102[2])]; + let r111=[0.5*(p312[0]+r210[0]), + 0.5*(p312[1]+r210[1]), + 0.5*(p312[2]+r210[2])]; + let u111=[0.5*(u021[0]+p231[0]), + 0.5*(u021[1]+p231[1]), + 0.5*(u021[2]+p231[2])]; + let c111=[0.25*(p033[0]+p330[0]+p303[0]+p111[0]), + 0.25*(p033[1]+p330[1]+p303[1]+p111[1]), + 0.25*(p033[2]+p330[2]+p303[2]+p111[2])]; + + let l=[l003,l102,l012,l201,l111,l021,l300,l210,l120,l030]; // left + let r=[l300,r102,r012,r201,r111,r021,r300,r210,r120,r030]; // right + let u=[l030,u102,u012,u201,u111,u021,r030,u210,u120,u030]; // up + let c=[r030,u201,r021,u102,c111,r012,l030,l120,l210,l300]; // center + + let n0=this.normal(l300,r012,r021,r030,u201,u102,l030); + let n1=this.normal(r030,u201,u102,l030,l120,l210,l300); + let n2=this.normal(l030,l120,l210,l300,r012,r021,r030); + + let e=this.Epsilon; + + // A kludge to remove subdivision cracks, only applied the first time + // an edge is found to be flat before the rest of the subpatch is. + + let m0=[0.5*(P1[0]+P2[0]), + 0.5*(P1[1]+P2[1]), + 0.5*(P1[2]+P2[2])]; + if(!flat0) { + if((flat0=Straightness(r300,p210,p120,u030) < this.res2)) { + let r=unit(this.sumderivative(c[0],c[2],c[5],c[9],c[1],c[3],c[6])); + m0=[m0[0]-e*r[0],m0[1]-e*r[1],m0[2]-e*r[2]]; + } + else m0=r030; + } + + + let m1=[0.5*(P2[0]+P0[0]), + 0.5*(P2[1]+P0[1]), + 0.5*(P2[2]+P0[2])]; + if(!flat1) { + if((flat1=Straightness(l003,p012,p021,u030) < this.res2)) { + let r=unit(this.sumderivative(c[6],c[3],c[1],c[0],c[7],c[8],c[9])); + m1=[m1[0]-e*r[0],m1[1]-e*r[1],m1[2]-e*r[2]]; + } + else m1=l030; + } + + let m2=[0.5*(P0[0]+P1[0]), + 0.5*(P0[1]+P1[1]), + 0.5*(P0[2]+P1[2])]; + if(!flat2) { + if((flat2=Straightness(l003,p102,p201,r300) < this.res2)) { + let r=unit(this.sumderivative(c[9],c[8],c[7],c[6],c[5],c[2],c[0])); + m2=[m2[0]-e*r[0],m2[1]-e*r[1],m2[2]-e*r[2]]; + } + else m2=l300; + } + + if(C0) { + let c0=Array(4); + let c1=Array(4); + let c2=Array(4); + for(let i=0; i < 4; ++i) { + c0[i]=0.5*(C1[i]+C2[i]); + c1[i]=0.5*(C2[i]+C0[i]); + c2[i]=0.5*(C0[i]+C1[i]); + } + + let i0=this.data.Vertex(m0,n0,c0); + let i1=this.data.Vertex(m1,n1,c1); + let i2=this.data.Vertex(m2,n2,c2); + + this.Render3(l,I0,i2,i1,P0,m2,m1,false,flat1,flat2,C0,c2,c1); + this.Render3(r,i2,I1,i0,m2,P1,m0,flat0,false,flat2,c2,C1,c0); + this.Render3(u,i1,i0,I2,m1,m0,P2,flat0,flat1,false,c1,c0,C2); + this.Render3(c,i0,i1,i2,m0,m1,m2,false,false,false,c0,c1,c2); + } else { + let i0=this.vertex(m0,n0); + let i1=this.vertex(m1,n1); + let i2=this.vertex(m2,n2); + + this.Render3(l,I0,i2,i1,P0,m2,m1,false,flat1,flat2); + this.Render3(r,i2,I1,i0,m2,P1,m0,flat0,false,flat2); + this.Render3(u,i1,i0,I2,m1,m0,P2,flat0,flat1,false); + this.Render3(c,i0,i1,i2,m0,m1,m2,false,false,false); + } } - gl.useProgram(shaderProgram); + } - shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); - gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute); - shaderProgram.vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor"); - gl.enableVertexAttribArray(shaderProgram.vertexColorAttribute); - shaderProgram.vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal"); - gl.enableVertexAttribArray(shaderProgram.vertexNormalAttribute); + // Check the flatness of a Bezier patch + Distance(p) { + let p0=p[0]; + let p3=p[3]; + let p12=p[12]; + let p15=p[15]; - shaderProgram.vertexMaterialIndexAttribute = gl.getAttribLocation(shaderProgram, "aVertexMaterialIndex"); - gl.enableVertexAttribArray(shaderProgram.vertexMaterialIndexAttribute); + // Check the flatness of a patch. + let d=Distance2(p15,p0,this.normal(p3,p[2],p[1],p0,p[4],p[8],p12)); + + // Determine how straight the edges are. + d=Math.max(d,Straightness(p0,p[1],p[2],p3)); + d=Math.max(d,Straightness(p0,p[4],p[8],p12)); + d=Math.max(d,Straightness(p3,p[7],p[11],p15)); + d=Math.max(d,Straightness(p12,p[13],p[14],p15)); + // Determine how straight the interior control curves are. + d=Math.max(d,Straightness(p[4],p[5],p[6],p[7])); + d=Math.max(d,Straightness(p[8],p[9],p[10],p[11])); + d=Math.max(d,Straightness(p[1],p[5],p[9],p[13])); + return Math.max(d,Straightness(p[2],p[6],p[10],p[14])); + } - shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); - shaderProgram.mMatrixUniform = gl.getUniformLocation(shaderProgram, "uMMatrix"); - shaderProgram.vMatrixUniform = gl.getUniformLocation(shaderProgram, "uVMatrix"); - shaderProgram.nlightsUniform = gl.getUniformLocation(shaderProgram, "unLights"); - shaderProgram.useColorUniform = gl.getUniformLocation(shaderProgram, "useColor"); + // Check the flatness of a Bezier triangle + Distance3(p) { + let p0=p[0]; + let p4=p[4]; + let p6=p[6]; + let p9=p[9]; + + // Check how far the internal point is from the centroid of the vertices. + let d=abs2([(p0[0]+p6[0]+p9[0])*third-p4[0], + (p0[1]+p6[1]+p9[1])*third-p4[1], + (p0[2]+p6[2]+p9[2])*third-p4[2]]); + + // Determine how straight the edges are. + d=Math.max(d,Straightness(p0,p[1],p[3],p6)); + d=Math.max(d,Straightness(p0,p[2],p[5],p9)); + return Math.max(d,Straightness(p6,p[7],p[8],p9)); + } + + derivative(p0,p1,p2,p3) { + let lp=[p1[0]-p0[0],p1[1]-p0[1],p1[2]-p0[2]]; + if(abs2(lp) > this.epsilon) + return lp; + + let lpp=bezierPP(p0,p1,p2); + if(abs2(lpp) > this.epsilon) + return lpp; + return bezierPPP(p0,p1,p2,p3); + } + + sumderivative(p0,p1,p2,p3,p4,p5,p6) { + let d0=this.derivative(p0,p1,p2,p3); + let d1=this.derivative(p0,p4,p5,p6); + return [d0[0]+d1[0],d0[1]+d1[1],d0[2]+d1[2]]; + } + + normal(left3,left2,left1,middle,right1,right2,right3) { + let ux=right1[0]-middle[0]; + let uy=right1[1]-middle[1]; + let uz=right1[2]-middle[2]; + let vx=left1[0]-middle[0]; + let vy=left1[1]-middle[1]; + let vz=left1[2]-middle[2]; + let n=[uy*vz-uz*vy, + uz*vx-ux*vz, + ux*vy-uy*vx]; + if(abs2(n) > this.epsilon) + return unit(n); + + let lp=[vx,vy,vz]; + let rp=[ux,uy,uz]; + let lpp=bezierPP(middle,left1,left2); + let rpp=bezierPP(middle,right1,right2); + let a=cross(rpp,lp); + let b=cross(rp,lpp); + n=[a[0]+b[0], + a[1]+b[1], + a[2]+b[2]]; + if(abs2(n) > this.epsilon) + return unit(n); + + let lppp=bezierPPP(middle,left1,left2,left3); + let rppp=bezierPPP(middle,right1,right2,right3); + a=cross(rpp,lpp); + b=cross(rp,lppp); + let c=cross(rppp,lp); + let d=cross(rppp,lpp); + let e=cross(rpp,lppp); + let f=cross(rppp,lppp); + return unit([9*a[0]+3*(b[0]+c[0]+d[0]+e[0])+f[0], + 9*a[1]+3*(b[1]+c[1]+d[1]+e[1])+f[1], + 9*a[2]+3*(b[2]+c[2]+d[2]+e[2])+f[2]]); + } } +class BezierCurve extends Geometry { + constructor(controlpoints,CenterIndex,MaterialIndex,Min,Max) { + super(); + this.controlpoints=controlpoints; + this.Min=Min; + this.Max=Max; + this.CenterIndex=CenterIndex; + this.MaterialIndex=MaterialIndex; + } -// math aux functions -function degToRad(degrees) { - return degrees * Math.PI / 180; -} -function unit(v) { - var norm = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); - norm = (norm != 0) ? 1 / norm : 1; - return [v[0] * norm, v[1] * norm, v[2] * norm]; -} + processLine(p) { + let p0=p[0]; + let p1=p[1]; + if(!this.offscreen([p0,p1])) { + this.data.indices.push(this.data.vertex1(p0)); + this.data.indices.push(this.data.vertex1(p1)); + this.append(); + } + } -function abs2(v) { -return v[0] * v[0] + v[1] * v[1] + v[2] * v[2]; + process(p) { + if(p.length == 2) return this.processLine(p); + + let i0=this.data.vertex1(p[0]); + let i3=this.data.vertex1(p[3]); + + this.Render(p,i0,i3); + if(this.data.indices.length > 0) this.append(); + } + + append() { + material1Data.append(this.data); + } + + Render(p,I0,I1) { + let p0=p[0]; + let p1=p[1]; + let p2=p[2]; + let p3=p[3]; + + if(Straightness(p0,p1,p2,p3) < this.res2) { // Segment is flat + if(!this.offscreen([p0,p3])) { + this.data.indices.push(I0); + this.data.indices.push(I1); + } + } else { // Segment is not flat + if(this.offscreen(p)) return; + + let m0=[0.5*(p0[0]+p1[0]),0.5*(p0[1]+p1[1]),0.5*(p0[2]+p1[2])]; + let m1=[0.5*(p1[0]+p2[0]),0.5*(p1[1]+p2[1]),0.5*(p1[2]+p2[2])]; + let m2=[0.5*(p2[0]+p3[0]),0.5*(p2[1]+p3[1]),0.5*(p2[2]+p3[2])]; + let m3=[0.5*(m0[0]+m1[0]),0.5*(m0[1]+m1[1]),0.5*(m0[2]+m1[2])]; + let m4=[0.5*(m1[0]+m2[0]),0.5*(m1[1]+m2[1]),0.5*(m1[2]+m2[2])]; + let m5=[0.5*(m3[0]+m4[0]),0.5*(m3[1]+m4[1]),0.5*(m3[2]+m4[2])]; + + let s0=[p0,m0,m3,m5]; + let s1=[m5,m4,m2,p3]; + + let i0=this.data.vertex1(m5); + + this.Render(s0,I0,i0); + this.Render(s1,i0,I1); + } + } } -function dot(u, v) { -return u[0] * v[0] + u[1] * v[1] + u[2] * v[2]; +class Pixel extends Geometry { + constructor(controlpoint,width,MaterialIndex,Min,Max) { + super(); + this.controlpoint=controlpoint; + this.width=width; + this.CenterIndex=0; + this.MaterialIndex=MaterialIndex; + this.Min=Min; + this.Max=Max; + } + + process(p) { + this.data.indices.push(this.data.vertex0(this.controlpoint,this.width)); + this.append(); + } + + append() { + material0Data.append(this.data); + } } -function cross(u, v) { -return [u[1] * v[2] - u[2] * v[1], - u[2] * v[0] - u[0] * v[2], - u[0] * v[1] - u[1] * v[0] -]; +class Triangles extends Geometry { + constructor(MaterialIndex,Min,Max) { + super(); + this.CenterIndex=0; + this.MaterialIndex=MaterialIndex; + this.Min=Min; + this.Max=Max; + this.Positions=Positions; + this.Normals=Normals; + this.Colors=Colors; + this.Indices=Indices; + Positions=[]; + Normals=[]; + Colors=[]; + Indices=[]; + this.transparent=Materials[MaterialIndex].diffuse[3] < 1; + } + + process(p) { + for(let i=0, n=this.Indices.length; i < n; ++i) { + let index=this.Indices[i]; + let PI=index[0]; + let P0=this.Positions[PI[0]]; + let P1=this.Positions[PI[1]]; + let P2=this.Positions[PI[2]]; + if(!this.offscreen([P0,P1,P2])) { + let NI=index.length > 1 ? index[1] : PI; + if(!NI || NI.length == 0) NI=PI; + if(this.Colors.length > 0) { + let CI=index.length > 2 ? index[2] : PI; + if(!CI || CI.length == 0) CI=PI; + let C0=this.Colors[CI[0]]; + let C1=this.Colors[CI[1]]; + let C2=this.Colors[CI[2]]; + this.transparent |= C0[3]+C1[3]+C2[3] < 765; + materialIndex=-1-this.MaterialIndex; + this.data.iVertex(PI[0],P0,this.Normals[NI[0]],C0); + this.data.iVertex(PI[1],P1,this.Normals[NI[1]],C1); + this.data.iVertex(PI[2],P2,this.Normals[NI[2]],C2); + } else { + materialIndex=1+this.MaterialIndex; + this.data.iVertex(PI[0],P0,this.Normals[NI[0]]); + this.data.iVertex(PI[1],P1,this.Normals[NI[1]]); + this.data.iVertex(PI[2],P2,this.Normals[NI[2]]); + } + } + } + this.data.nvertices=this.Positions.length; + if(this.data.indices.length > 0) this.append(); + } + + append() { + if(this.transparent) + transparentData.append(this.data); + else + triangleData.append(this.data); + } } -// return the perpendicular distance squared of a point z from the plane -// through u with unit normal n. -function Distance2(z, u, n) { - var d = dot([z[0] - u[0], z[1] - u[1], z[2] - u[2]], n); - return d * d; + +function home() +{ + mat4.identity(rotMat); + initProjection(); + setProjection(); + redraw=true; } -var vMatrix = mat4.create(); -var mMatrix = mat4.create(); -var pMatrix = mat4.create(); +function initShader(options=[]) +{ + let fragmentShader=getShader(gl,"fragment",options); + let vertexShader=getShader(gl,"vertex",options); + let shader=gl.createProgram(); + + gl.attachShader(shader,vertexShader); + gl.attachShader(shader,fragmentShader); + gl.linkProgram(shader); + if (!gl.getProgramParameter(shader,gl.LINK_STATUS)) { + alert("Could not initialize shaders"); + } -var headlamp = new Light( - type = enumDirectionalLight, - lightColor = [1, 0.87, 0.745], - brightness = 1, - customParam = [0, 0, 1, 0] -); + return shader; +} -function setUniforms() { - gl.uniformMatrix4fv(shaderProgram.vMatrixUniform, false, vMatrix); - gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix); - gl.uniformMatrix4fv(shaderProgram.mMatrixUniform, false, mMatrix); +class Split3 { + constructor(z0,c0,c1,z1) { + this.m0=[0.5*(z0[0]+c0[0]),0.5*(z0[1]+c0[1]),0.5*(z0[2]+c0[2])]; + let m1_0=0.5*(c0[0]+c1[0]); + let m1_1=0.5*(c0[1]+c1[1]); + let m1_2=0.5*(c0[2]+c1[2]); + this.m2=[0.5*(c1[0]+z1[0]),0.5*(c1[1]+z1[1]),0.5*(c1[2]+z1[2])]; + this.m3=[0.5*(this.m0[0]+m1_0),0.5*(this.m0[1]+m1_1), + 0.5*(this.m0[2]+m1_2)]; + this.m4=[0.5*(m1_0+this.m2[0]),0.5*(m1_1+this.m2[1]), + 0.5*(m1_2+this.m2[2])]; + this.m5=[0.5*(this.m3[0]+this.m4[0]),0.5*(this.m3[1]+this.m4[1]), + 0.5*(this.m3[2]+this.m4[2])]; + } +} - objMaterial.setUniform(shaderProgram, "objMaterial", 0); +function iszero(v) +{ + return v[0] == 0 && v[1] == 0 && v[2] == 0; +} - // for now, if we simulate headlamp. Can also specify custom lights later on... - headlamp.setUniform(shaderProgram, "objLights", 0); - gl.uniform1i(shaderProgram.nlightsUniform, 1); - gl.uniform1i(shaderProgram.useColorUniform, 0); +function unit(v) +{ + let norm=1/(Math.sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]) || 1); + return [v[0]*norm,v[1]*norm,v[2]*norm]; +} +function abs2(v) +{ + return v[0]*v[0]+v[1]*v[1]+v[2]*v[2]; } -var VertexBuffer; -var ColorBuffer; -var NormalBuffer; +function dot(u,v) +{ + return u[0]*v[0]+u[1]*v[1]+u[2]*v[2]; +} -// base buffer arrays -var vertices = new Array(); -var colors = new Array(); -var normals = new Array(); -var indices = new Array(); -var materials = new Array(); +function cross(u,v) +{ + return [u[1]*v[2]-u[2]*v[1], + u[2]*v[0]-u[0]*v[2], + u[0]*v[1]-u[1]*v[0]]; +} -// no. of verts. -var nvertices = 0; +// Return one-sixth of the second derivative of the Bezier curve defined +// by a,b,c,d at 0. +function bezierPP(a,b,c) +{ + return [a[0]+c[0]-2*b[0], + a[1]+c[1]-2*b[1], + a[2]+c[2]-2*b[2]]; +} -var mMatrixStack = []; -var pMatrix = mat4.create(); -var viewMatrix = mat4.create(); -var localRotation = mat4.create(); +// Return one-third of the third derivative of the Bezier curve defined by +// a,b,c,d at 0. +function bezierPPP(a,b,c,d) +{ + return [d[0]-a[0]+3*(b[0]-c[0]), + d[1]-a[1]+3*(b[1]-c[1]), + d[2]-a[2]+3*(b[2]-c[2])]; +} -function mvPushMatrix() { - var copy = mat4.create(); - mat4.set(mMatrix, copy); - mMatrixStack.push(copy); +/** + * Return the maximum distance squared of points c0 and c1 from + * the respective internal control points of z0--z1. +*/ +function Straightness(z0,c0,c1,z1) +{ + let v=[third*(z1[0]-z0[0]),third*(z1[1]-z0[1]),third*(z1[2]-z0[2])]; + return Math.max(abs2([c0[0]-v[0]-z0[0],c0[1]-v[1]-z0[1],c0[2]-v[2]-z0[2]]), + abs2([z1[0]-v[0]-c1[0],z1[1]-v[1]-c1[1],z1[2]-v[2]-c1[2]])); } -function mvPopMatrix() { - if (mMatrixStack.length == 0) { - throw "Invalid popMatrix!"; - } - mMatrix = mMatrixStack.pop(); +/** + * Return the perpendicular distance squared of a point z from the plane + * through u with unit normal n. + */ +function Distance2(z,u,n) +{ + let d=dot([z[0]-u[0],z[1]-u[1],z[2]-u[2]],n); + return d*d; } -var redraw = true; -var mouseDownOrTouchActive = false; -var lastMouseX = null; -var lastMouseY = null; -var touchID = null; +// Return the vertices of the box containing 3d points m and M. +function corners(m,M) +{ + return [m,[m[0],m[1],M[2]],[m[0],M[1],m[2]],[m[0],M[1],M[2]], + [M[0],m[1],m[2]],[M[0],m[1],M[2]],[M[0],M[1],m[2]],M]; +} +/** + * Perform a change of basis + * @param {*} out Out Matrix + * @param {*} mat Matrix + * + * Compute the matrix (translMatrix) * mat * (translMatrix)^{-1} + */ + +function COBTarget(out,mat) +{ + mat4.fromTranslation(translMat,[center.x,center.y,center.z]) + mat4.invert(cjMatInv,translMat); + mat4.multiply(out,mat,cjMatInv); + mat4.multiply(out,translMat,out); +} -var center = [0, 0, 1]; -var centerInv = [0, 0, -1]; +function setUniforms(shader) +{ + let pixel=shader == pixelShader; -var rotationMatLocal = mat4.create(); -var rotationMatrix = mat4.create(); -mat4.identity(rotationMatrix); + gl.useProgram(shader); -function handleMouseDown(event) { - mouseDownOrTouchActive = true; - lastMouseX = event.clientX; - lastMouseY = event.clientY; -} + shader.vertexPositionAttribute= + gl.getAttribLocation(shader,"position"); + gl.enableVertexAttribArray(shader.vertexPositionAttribute); -function handleTouchStart(evt) { - evt.preventDefault(); - var touches = evt.targetTouches; + if(pixel) { + shader.vertexWidthAttribute= + gl.getAttribLocation(shader,"width"); + gl.enableVertexAttribArray(shader.vertexWidthAttribute); + } - if (touches.length == 1 && !mouseDownOrTouchActive) { - touchId = touches[0].identifier; - lastMouseX = touches[0].pageX, - lastMouseY = touches[0].pageY; + if(shader != noNormalShader && !pixel) { + shader.vertexNormalAttribute= + gl.getAttribLocation(shader,"normal"); + gl.enableVertexAttribArray(shader.vertexNormalAttribute); } -} -function handleMouseUpOrTouchEnd(event) { - mouseDownOrTouchActive = false; -} + shader.vertexMaterialAttribute= + gl.getAttribLocation(shader,"materialIndex"); + gl.enableVertexAttribArray(shader.vertexMaterialAttribute); -function processDrag(newX, newY, pan = false) { - let lastX = (lastMouseX - 400) / 400; - let lastY = (lastMouseY - 400) / 400; + shader.projViewMatUniform=gl.getUniformLocation(shader,"projViewMat"); + shader.viewMatUniform=gl.getUniformLocation(shader,"viewMat"); + shader.normMatUniform=gl.getUniformLocation(shader,"normMat"); - let rawX = (newX - 400) / 400; - let rawY = (newY - 400) / 400; + if(shader == colorShader || shader == transparentShader) { + shader.vertexColorAttribute= + gl.getAttribLocation(shader,"color"); + gl.enableVertexAttribArray(shader.vertexColorAttribute); + } - let viewmatInv = mat4.create(); - mat4.invert(viewmatInv, vMatrix); + for(let i=0; i < Materials.length; ++i) + Materials[i].setUniform(shader,"Materials",i); - let tmpCameraOffset = vec3.create(); - vec3.subtract(tmpCameraOffset, cameraPos, cameraLookAt); + for(let i=0; i < Lights.length; ++i) + Lights[i].setUniform(shader,"Lights",i); - if (!pan) { - let [angle, axis] = arcballLib.arcball([lastX, -lastY], [rawX, -rawY]); + gl.uniformMatrix4fv(shader.projViewMatUniform,false,projViewMat); + gl.uniformMatrix4fv(shader.viewMatUniform,false,viewMat); + gl.uniformMatrix3fv(shader.normMatUniform,false,normMat); +} - if (angle == NaN || axis == NaN) { - console.error("Angle or axis NaN!"); - return; - } +function handleMouseDown(event) +{ + mouseDownOrTouchActive=true; + lastMouseX=event.clientX; + lastMouseY=event.clientY; +} - let depthVec = vec3.clone(cameraLookAt); - vec3.transformMat4(depthVec, depthVec, vMatrix); - //vec3.transformMat4(depthVec, depthVec, pMatrix); - vec3.add(axis, axis, depthVec); +let pinch=false; +let pinchStart; - // let projMatInv=mat4.create(); - // mat4.invert(projMatInv, pMatrix); +function pinchDistance(touches) +{ + return Math.hypot( + touches[0].pageX-touches[1].pageX, + touches[0].pageY-touches[1].pageY); +} - //vec3.transformMat4(axis,axis,projMatInv); - vec3.transformMat4(axis, axis, viewmatInv); - let tmpRotMat = mat4.create(); +let touchStartTime; - mat4.fromRotation(tmpRotMat, -angle, axis); +function handleTouchStart(evt) +{ + evt.preventDefault(); + let touches=evt.targetTouches; + swipe=rotate=pinch=false; + if(zooming) return; + + if(touches.length == 1 && !mouseDownOrTouchActive) { + touchStartTime=new Date().getTime(); + touchId=touches[0].identifier; + lastMouseX=touches[0].pageX, + lastMouseY=touches[0].pageY; + } + + if(touches.length == 2 && !mouseDownOrTouchActive) { + touchId=touches[0].identifier; + pinchStart=pinchDistance(touches); + pinch=true; + } +} - vec3.transformMat4(tmpCameraOffset, tmpCameraOffset, tmpRotMat); - vec3.transformMat4(cameraUp, cameraUp, tmpRotMat); +function handleMouseUpOrTouchEnd(event) +{ + mouseDownOrTouchActive=false; +} + +function rotateScene(lastX,lastY,rawX,rawY,factor) +{ + if(lastX == rawX && lastY == rawY) return; + let [angle,axis]=arcball([lastX,-lastY],[rawX,-rawY]); - vec3.add(cameraPos, tmpCameraOffset, cameraLookAt); + mat4.fromRotation(rotMats,2*factor*ArcballFactor*angle/lastzoom,axis); + mat4.multiply(rotMat,rotMats,rotMat); +} +function shiftScene(lastX,lastY,rawX,rawY) +{ + let zoominv=1/lastzoom; + shift.x += (rawX-lastX)*zoominv*halfCanvasWidth; + shift.y -= (rawY-lastY)*zoominv*halfCanvasHeight; +} +function panScene(lastX,lastY,rawX,rawY) +{ + if (orthographic) { + shiftScene(lastX,lastY,rawX,rawY); } else { - let xTransl = (rawX - lastX); - let yTransl = (rawY - lastY); - let normCameraUp = vec3.create(); - vec3.normalize(normCameraUp, cameraUp); - vec3.scale(normCameraUp, normCameraUp, yTransl); + center.x += (rawX-lastX)*(viewParam.xmax-viewParam.xmin); + center.y -= (rawY-lastY)*(viewParam.ymax-viewParam.ymin); + } +} - let normCameraLeft = vec3.create(); - vec3.cross(normCameraLeft, tmpCameraOffset, cameraUp); - vec3.normalize(normCameraLeft, normCameraLeft); - vec3.scale(normCameraLeft, normCameraLeft, xTransl); +function updateViewMatrix() +{ + COBTarget(viewMat,rotMat); + mat4.translate(viewMat,viewMat,[center.x,center.y,0]); + mat3.fromMat4(viewMat3,viewMat); + mat3.invert(normMat,viewMat3); + mat4.multiply(projViewMat,projMat,viewMat); +} + +function capzoom() +{ + let maxzoom=Math.sqrt(Number.MAX_VALUE); + let minzoom=1/maxzoom; + if(Zoom <= minzoom) Zoom=minzoom; + if(Zoom >= maxzoom) Zoom=maxzoom; + + if(Zoom != lastzoom) remesh=true; + lastzoom=Zoom; +} - let cameraShift = vec3.create(); - vec3.add(cameraShift, normCameraUp, normCameraLeft); +function zoomImage(diff) +{ + let stepPower=zoomStep*halfCanvasHeight*diff; + const limit=Math.log(0.1*Number.MAX_VALUE)/Math.log(zoomFactor); - vec3.add(cameraLookAt, cameraLookAt, cameraShift); - vec3.add(cameraPos, cameraPos, cameraShift); + if(Math.abs(stepPower) < limit) { + Zoom *= zoomFactor**stepPower; + capzoom(); } +} - lastMouseX = newX; - lastMouseY = newY; - redraw = true; +function normMouse(v) +{ + let v0=v[0]; + let v1=v[1]; + let norm=Math.hypot(v0,v1); + if(norm > 1) { + denom=1/norm; + v0 *= denom; + v1 *= denom; + } + return [v0,v1,Math.sqrt(Math.max(1-v1*v1-v0*v0,0))]; } -function handleKey(key) { - var keycode = key.key; - var rotate = true; - var axis = [0, 0, 1]; - switch (keycode) { - case "w": - axis = [-1, 0, 0]; - break; - case "d": - axis = [0, 1, 0]; +function arcball(oldmouse,newmouse) +{ + let oldMouse=normMouse(oldmouse); + let newMouse=normMouse(newmouse); + let Dot=dot(oldMouse,newMouse); + if(Dot > 1) Dot=1; + else if(Dot < -1) Dot=-1; + return [Math.acos(Dot),unit(cross(oldMouse,newMouse))] +} + +/** + * Mouse Drag Zoom + * @param {*} lastX unused + * @param {*} lastY + * @param {*} rawX unused + * @param {*} rawY + */ +function zoomScene(lastX,lastY,rawX,rawY) +{ + zoomImage(lastY-rawY); +} + +// mode: +const DRAGMODE_ROTATE=1; +const DRAGMODE_SHIFT=2; +const DRAGMODE_ZOOM=3; +const DRAGMODE_PAN=4 +function processDrag(newX,newY,mode,factor=1) +{ + let dragFunc; + switch (mode) { + case DRAGMODE_ROTATE: + dragFunc=rotateScene; break; - case "a": - axis = [0, -1, 0]; + case DRAGMODE_SHIFT: + dragFunc=shiftScene; break; - case "s": - axis = [1, 0, 0]; + case DRAGMODE_ZOOM: + dragFunc=zoomScene; break; - case "h": - resetCamera(); + case DRAGMODE_PAN: + dragFunc=panScene; break; default: - rotate = false; + dragFunc=(_a,_b,_c,_d) => {}; break; } - if (rotate) { - mat4.rotate(rotationMatrix, rotationMatrix, 0.1, axis); - redraw = true; - } - -} - -function handleMouseWheel(event) { - let zoomFactor = event.deltaY / 50; - - // console.log(zoomFactor); + let lastX=(lastMouseX-halfCanvasWidth)/halfCanvasWidth; + let lastY=(lastMouseY-halfCanvasHeight)/halfCanvasHeight; + let rawX=(newX-halfCanvasWidth)/halfCanvasWidth; + let rawY=(newY-halfCanvasHeight)/halfCanvasHeight; - let cameraShift = vec3.create(); - vec3.subtract(cameraShift, cameraPos, cameraLookAt); + dragFunc(lastX,lastY,rawX,rawY,factor); - let cameraDir = vec3.create(); - vec3.normalize(cameraDir, cameraShift); - vec3.scale(cameraDir, cameraDir, zoomFactor); + lastMouseX=newX; + lastMouseY=newY; - let newCameraShift = vec3.create(); - vec3.add(newCameraShift, cameraShift, cameraDir); - - // not go beyond the bounds - if (vec3.length(newCameraShift) < 0.01 && zoomFactor < 0) { + setProjection(); + redraw=true; +} - } else if (vec3.length(newCameraShift) > 100 && zoomFactor > 0) { +function handleKey(event) +{ + let keycode=event.key; + let axis=[]; + switch(keycode) { + case 'x': + axis=[1,0,0]; + break; + case 'y': + axis=[0,1,0]; + break; + case 'z': + axis=[0,0,1]; + break; + case 'h': + home(); + break; + case '+': + case '=': + case '>': + expand(); + break; + case '-': + case '_': + case '<': + shrink(); + break; + default: + break; + } - } else if (vec3.dot(newCameraShift, cameraShift) >= 0) { - cameraShift = vec3.clone(newCameraShift); + if(axis.length > 0) { + mat4.rotate(rotMat,rotMat,0.1,axis); + updateViewMatrix(); + redraw=true; } +} - vec3.add(cameraPos, cameraShift, cameraLookAt); +function handleMouseWheel(event) +{ + if (event.deltaY < 0) { + Zoom *= zoomFactor; + } else { + Zoom /= zoomFactor; + } + capzoom(); + setProjection(); - res = 1 / (vec3.length(cameraShift) + 0.001) * 0.001; - redraw = true; + redraw=true; } -function handleMouseMove(event) { - if (!mouseDownOrTouchActive) { +function handleMouseMove(event) +{ + if(!mouseDownOrTouchActive) { return; } - var newX = event.clientX; - var newY = event.clientY; + let newX=event.clientX; + let newY=event.clientY; + + let mode; + if(event.getModifierState("Control")) { + mode=DRAGMODE_SHIFT; + } else if(event.getModifierState("Shift")) { + mode=DRAGMODE_ZOOM; + } else if(event.getModifierState("Alt")) { + mode=DRAGMODE_PAN; + } else { + mode=DRAGMODE_ROTATE; + } - processDrag(newX, newY, event.getModifierState("Alt")); + processDrag(newX,newY,mode); } -function handleTouchMove(evt) { +let zooming=false; +let swipe=false; +let rotate=false; + +function handleTouchMove(evt) +{ evt.preventDefault(); - var touches = evt.targetTouches; + if(zooming) return; + let touches=evt.targetTouches; + + if(!pinch && touches.length == 1 && touchId == touches[0].identifier) { + let newX=touches[0].pageX; + let newY=touches[0].pageY; + let dx=newX-lastMouseX; + let dy=newY-lastMouseY; + let stationary=dx*dx+dy*dy <= shiftHoldDistance*shiftHoldDistance; + if(stationary) { + if(!swipe && !rotate && + new Date().getTime()-touchStartTime > shiftWaitTime) { + if(navigator.vibrate) + window.navigator.vibrate(vibrateTime); + swipe=true; + } + } + if(swipe) + processDrag(newX,newY,DRAGMODE_SHIFT); + else if(!stationary) { + rotate=true; + let newX=touches[0].pageX; + let newY=touches[0].pageY; + processDrag(newX,newY,DRAGMODE_ROTATE,0.5); + } + } - if (touches.length == 1 && touchId == touches[0].identifier) { - var newX = touches[0].pageX; - var newY = touches[0].pageY; - processDrag(newX, newY); + if(pinch && !swipe && + touches.length == 2 && touchId == touches[0].identifier) { + let distance=pinchDistance(touches); + let diff=distance-pinchStart; + zooming=true; + diff *= zoomPinchFactor; + if(diff > zoomPinchCap) diff=zoomPinchCap; + if(diff < -zoomPinchCap) diff=-zoomPinchCap; + zoomImage(diff/size2); + pinchStart=distance; + swipe=rotate=zooming=false; + setProjection(); + redraw=true; } } -// Prepare canvas for drawing -function sceneSetup() { - gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight); - gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); - mat4.perspective(pMatrix, 45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0); +let indexExt; - mat4.lookAt(vMatrix, cameraPos, cameraLookAt, cameraUp); - mat4.identity(mMatrix); +// Create buffers for the patch and its subdivisions. +function setBuffer() +{ + positionBuffer=gl.createBuffer(); + materialBuffer=gl.createBuffer(); + colorBuffer=gl.createBuffer(); + indexBuffer=gl.createBuffer(); + indexExt=gl.getExtension("OES_element_index_uint"); } -var indexExt; +let zbuffer=[]; + +function transformVertices(vertices) +{ + let Tz0=viewMat[2]; + let Tz1=viewMat[6]; + let Tz2=viewMat[10]; + zbuffer.length=vertices.length; + for(let i=0; i < vertices.length; ++i) { + let i6=6*i; + zbuffer[i]=Tz0*vertices[i6]+Tz1*vertices[i6+1]+Tz2*vertices[i6+2]; + } +} -// Create buffer data for the patch and its subdivisions to be pushed to the graphics card -//Takes as an argument the array of vertices that define the patch to be drawn -// Using the vertex position buffer of the above function,draw patch. -function setBuffer() { - VertexBuffer = gl.createBuffer(); - VertexBuffer.itemSize = 3; +function draw() +{ + gl.clearColor(1,1,1,1); + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); - ColorBuffer = gl.createBuffer(); - ColorBuffer.itemSize = 4; + material0Data.clear(); + material1Data.clear(); + materialData.clear(); + colorData.clear(); + triangleData.clear(); + transparentData.clear(); + + P.forEach(function(p) { + p.render(); + }); + + drawBuffer(material0Data,pixelShader); + drawBuffer(material1Data,noNormalShader); + drawBuffer(materialData,materialShader); + drawBuffer(colorData,colorShader); + drawBuffer(triangleData,transparentShader); + + let indices=transparentData.indices; + if(indices.length > 0) { + transformVertices(transparentData.vertices); + + let n=indices.length/3; + let triangles=Array(n).fill().map((_,i)=>i); + + triangles.sort(function(a,b) { + let a3=3*a; + Ia=indices[a3]; + Ib=indices[a3+1]; + Ic=indices[a3+2]; + + let b3=3*b; + IA=indices[b3]; + IB=indices[b3+1]; + IC=indices[b3+2]; + + return zbuffer[Ia]+zbuffer[Ib]+zbuffer[Ic] < + zbuffer[IA]+zbuffer[IB]+zbuffer[IC] ? -1 : 1; + }); + + let Indices=Array(indices.length); + + for(let i=0; i < n; ++i) { + let i3=3*i; + let t=3*triangles[i]; + Indices[3*i]=indices[t]; + Indices[3*i+1]=indices[t+1]; + Indices[3*i+2]=indices[t+2]; + } - NormalBuffer = gl.createBuffer(); - NormalBuffer.itemSize = 3; + gl.depthMask(false); // Enable transparency + drawBuffer(transparentData,transparentShader,Indices); + gl.depthMask(true); // Disable transparency + } - MaterialIndexBuffer = gl.createBuffer(); - MaterialIndexBuffer.itemSize = 1; + remesh=false; +} - indexBuffer = gl.createBuffer(); - indexBuffer.itemSize = 1; +function tick() +{ + requestAnimationFrame(tick); + if(redraw) { + draw(); + redraw=false; + } +} - setUniforms(); - indexExt = gl.getExtension("OES_element_index_uint"); +function setDimensions(width,height,X,Y) +{ + let Aspect=width/height; + let zoominv=1/lastzoom; + let xshift=X/width*lastzoom + let yshift=Y/height*lastzoom + + if (orthographic) { + let xsize=B[0]-b[0]; + let ysize=B[1]-b[1]; + if (xsize < ysize*Aspect) { + let r=0.5*ysize*Aspect*zoominv; + let X0=2*r*xshift; + let Y0=ysize*zoominv*yshift; + viewParam.xmin=-r-X0; + viewParam.xmax=r-X0; + viewParam.ymin=b[1]*zoominv-Y0; + viewParam.ymax=B[1]*zoominv-Y0; + } else { + let r=0.5*xsize/(Aspect*Zoom); + let X0=xsize*zoominv*xshift; + let Y0=2*r*yshift; + viewParam.xmin=b[0]*zoominv-X0; + viewParam.xmax=B[0]*zoominv-X0; + viewParam.ymin=-r-Y0; + viewParam.ymax=r-Y0; + } + } else { + let r=H*zoominv; + let rAspect=r*Aspect; + let X0=2*rAspect*xshift; + let Y0=2*r*yshift; + viewParam.xmin=-rAspect-X0; + viewParam.xmax=rAspect-X0; + viewParam.ymin=-r-Y0; + viewParam.ymax=r-Y0; + } } -function drawBuffer() { - gl.bindBuffer(gl.ARRAY_BUFFER, VertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); - gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, - VertexBuffer.itemSize, gl.FLOAT, false, 0, 0); - VertexBuffer.numItems = nvertices; +function setProjection() +{ + setDimensions(canvasWidth,canvasHeight,shift.x,shift.y); + let f=orthographic ? mat4.ortho : mat4.frustum; + f(projMat,viewParam.xmin,viewParam.xmax, + viewParam.ymin,viewParam.ymax, + -viewParam.zmax,-viewParam.zmin); + updateViewMatrix(); +} - // FIXME: Some kind of a conditional here for colors??? - // along a flag of "useColors or something??? " - gl.bindBuffer(gl.ARRAY_BUFFER, ColorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); - gl.vertexAttribPointer(shaderProgram.vertexColorAttribute, - ColorBuffer.itemSize, gl.FLOAT, false, 0, 0); - ColorBuffer.numItems = nvertices; +function initProjection() +{ + H=-Math.tan(0.5*angle)*B[2]; - gl.bindBuffer(gl.ARRAY_BUFFER, NormalBuffer); - gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normals), gl.STATIC_DRAW); - gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute, - NormalBuffer.itemSize, gl.FLOAT, false, 0, 0); - NormalBuffer.numItems = nvertices; + center.x=center.y=0; + center.z=0.5*(b[2]+B[2]); + lastzoom=Zoom=Zoom0; - gl.bindBuffer(gl.ARRAY_BUFFER, MaterialIndexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, new Int32Array(materials), gl.STATIC_DRAW); - gl.vertexAttribIPointer(shaderProgram.vertexMaterialIndexAttribute, - MaterialIndexBuffer.itemSize, gl.INT,false,0,0); - MaterialIndexBuffer.numItems = nvertices; + viewParam.zmin=b[2]; + viewParam.zmax=B[2]; - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, - indexExt ? new Uint32Array(indices) : new Uint16Array(indices), - gl.STATIC_DRAW); - indexBuffer.numItems = indices.length; - - gl.drawElements(gl.TRIANGLES, indexBuffer.numItems, - indexExt ? gl.UNSIGNED_INT : gl.UNSIGNED_SHORT, 0); - vertices = []; - colors = []; - normals = []; - indices = []; - materials = []; - nvertices = 0; -} - -var pixel = 1.0; // Adaptive rendering constant. -var FillFactor = 0.1; -var BezierFactor = 0.4; -//var res=0.0005; // Temporary -var res = 0.001; // Temporary -var res2 = res * res; -var Epsilon = 0.1 * res; -var epsilon = 0; -var Fuzz = 1000 * Number.EPSILON; -var Fuzz2 = Fuzz * Fuzz; - -function Split3(z0, c0, c1, z1) { - this.m0 = new Array(3); - this.m2 = new Array(3); - this.m3 = new Array(3); - this.m4 = new Array(3); - this.m5 = new Array(3); - for (var i = 0; i < 3; ++i) { - this.m0[i] = 0.5 * (z0[i] + c0[i]); - var m1 = 0.5 * (c0[i] + c1[i]); - this.m2[i] = 0.5 * (c1[i] + z1[i]); - this.m3[i] = 0.5 * (this.m0[i] + m1); - this.m4[i] = 0.5 * (m1 + this.m2[i]); - this.m5[i] = 0.5 * (this.m3[i] + this.m4[i]); - } -} - - -// Store the vertex v and its color vector c in the buffer. -function vertex(v, c, n) { - vertices.push(v[0]); - vertices.push(v[1]); - vertices.push(v[2]); - - colors.push(c[0]); - colors.push(c[1]); - colors.push(c[2]); - colors.push(c[3]); - - normals.push(n[0]); - normals.push(n[1]); - normals.push(n[2]); - - // FIXME: Enable arbitrary materials? - materials.push(materialIndex); - - return nvertices++; -} - -function normal(left3, left2, left1, middle, right1, right2, right3) { - var u0 = right1[0] - middle[0]; - var v0 = left1[0] - middle[0]; - var u1 = right1[1] - middle[1]; - var v1 = left1[1] - middle[1]; - var u2 = right1[2] - middle[2]; - var v2 = left1[2] - middle[2]; - var n = [ - u1 * v2 - u2 * v1, - u2 * v0 - u0 * v2, - u0 * v1 - u1 * v0 - ]; - if (abs2(n) > epsilon) - return unit(n); - - var lp = [v0, v1, v2]; - var rp = [u0, u1, u2]; - var lpp = [middle[0] + left2[0] - 2 * left1[0], - middle[1] + left2[1] - 2 * left1[1], - middle[2] + left2[2] - 2 * left1[2] - ]; - var rpp = [middle[0] + right2[0] - 2 * right1[0], - middle[1] + right2[1] - 2 * right1[1], - middle[2] + right2[2] - 2 * right1[2] - ]; - var a = cross(rpp, lp); - var b = cross(rp, lpp); - n = [a[0] + b[0], - a[1] + b[1], - a[2] + b[2] - ]; - if (abs2(n) > epsilon) - return unit(n); - - var lppp = [left3[0] - middle[0] + 3 * (left1[0] - left2[0]), - left3[1] - middle[1] + 3 * (left1[1] - left2[1]), - left3[2] - middle[2] + 3 * (left1[2] - left2[2]) - ]; - var rppp = [right3[0] - middle[0] + 3 * (right1[0] - right2[0]), - right3[1] - middle[1] + 3 * (right1[1] - right2[1]), - right3[2] - middle[2] + 3 * (right1[2] - right2[2]) - ]; - a = cross(rpp, lpp); - b = cross(rp, lppp); - var c = cross(rppp, lp); - var d = cross(rppp, lpp); - var e = cross(rpp, lppp); - var f = cross(rppp, lppp); - return unit([9 * a[0] + 3 * (b[0] + c[0] + d[0] + e[0]) + f[0], - 9 * a[1] + 3 * (b[1] + c[1] + d[1] + e[1]) + f[1], - 9 * a[2] + 3 * (b[2] + c[2] + d[2] + e[2]) + f[2] - ]); -} - -// return the maximum distance squared of points c0 and c1 from -// the respective internal control points of z0--z1. -function Straightness(z0, c0, c1, z1) { - var third = 1.0 / 3.0; - var v = [third * (z1[0] - z0[0]), third * (z1[1] - z0[1]), third * (z1[2] - z0[2])]; - return Math.max(abs2([c0[0] - v[0] - z0[0], c0[1] - v[1] - z0[1], c0[2] - v[2] - z0[2]]), - abs2([z1[0] - v[0] - c1[0], z1[1] - v[1] - c1[1], z1[2] - v[2] - c1[2]])); -} - -// return the maximum perpendicular distance squared of points c0 and c1 -// from z0--z1. -function Distance1(z0, c0, c1, z1) { - var Z0 = [c0[0] - z0[0], c0[1] - z0[1], c0[2] - z0[2]]; - var Q = unit([z1[0] - z0[0], z1[1] - z0[1], z1[2] - z0[2]]); - var Z1 = [c1[0] - z0[0], c1[1] - z0[1], c1[2] - z0[2]]; - var p0 = dot(Z0, Q); - var p1 = dot(Z1, Q); - return Math.max(abs2([Z0[0] - p0 * Q[0], Z0[1] - p0 * Q[1], Z0[2] - p0 * Q[2]]), - abs2([Z1[0] - p1 * Q[0], Z1[1] - p1 * Q[1], Z1[2] - p1 * Q[2]])); -} - - -function Distance(p) { - var p0 = p[0]; - var p3 = p[3]; - var p12 = p[12]; - var p15 = p[15]; - - // Check the flatness of the quad. - var d = Distance2(p15, p0, normal(p3, p[2], p[1], p0, p[4], p[8], p12)); - - // Determine how straight the edges are. - d = Math.max(d, Straightness(p0, p[1], p[2], p3)); - d = Math.max(d, Straightness(p0, p[4], p[8], p12)); - d = Math.max(d, Straightness(p3, p[7], p[11], p15)); - d = Math.max(d, Straightness(p12, p[13], p[14], p15)); - - // Determine how straight the interior control curves are. - d = Math.max(d, Straightness(p[4], p[5], p[6], p[7])); - d = Math.max(d, Straightness(p[8], p[9], p[10], p[11])); - d = Math.max(d, Straightness(p[1], p[5], p[9], p[13])); - return Math.max(d, Straightness(p[2], p[6], p[10], p[14])); -} - -var k = 1; -// Return color associated with unit normal vector n. -function color(n) { - var Ldotn = Math.abs(L[0] * n[0] + L[1] * n[1] + L[2] * n[2]); - var p = [emissive[0] + ambient[0] * Ambient[0] + Ldotn * diffuse[0] * Diffuse[0], - emissive[1] + ambient[1] * Ambient[1] + Ldotn * diffuse[1] * Diffuse[1], - emissive[2] + ambient[2] * Ambient[2] + Ldotn * diffuse[2] * Diffuse[2] - ]; - var s = shininess * 128; - var H = unit([L[0], L[1], L[2] + 1]); - var f = Math.pow(H[0] * n[0] + H[1] * n[1] + H[2] * n[2], s); - - // Phong-Blinn model of specular reflection - p = [p[0] + f * specular[0] * Specular[0], p[1] + f * specular[1] * Specular[1], - p[2] + f * specular[2] * Specular[2] - ]; - - return [p[0], p[1], p[2], 1]; -} - -function render(p, I0, I1, I2, I3, P0, P1, P2, P3, flat0, flat1, flat2, flat3, - C0, C1, C2, C3) { - if (Distance(p) < res2) { // Patch is flat - indices.push(I0); - indices.push(I1); - indices.push(I2); - - indices.push(I0); - indices.push(I2); - indices.push(I3); - return; - } + shift.x=shift.y=0; +} - var p0 = p[0]; - var p3 = p[3]; - var p12 = p[12]; - var p15 = p[15]; - - var c0 = new Split3(p0, p[1], p[2], p3); - var c1 = new Split3(p[4], p[5], p[6], p[7]); - var c2 = new Split3(p[8], p[9], p[10], p[11]); - var c3 = new Split3(p12, p[13], p[14], p15); - var c4 = new Split3(p0, p[4], p[8], p12); - var c5 = new Split3(c0.m0, c1.m0, c2.m0, c3.m0); - var c6 = new Split3(c0.m3, c1.m3, c2.m3, c3.m3); - var c7 = new Split3(c0.m5, c1.m5, c2.m5, c3.m5); - var c8 = new Split3(c0.m4, c1.m4, c2.m4, c3.m4); - var c9 = new Split3(c0.m2, c1.m2, c2.m2, c3.m2); - var c10 = new Split3(p3, p[7], p[11], p15); - - var s0 = [p0, c0.m0, c0.m3, c0.m5, c4.m0, c5.m0, c6.m0, c7.m0, - c4.m3, c5.m3, c6.m3, c7.m3, c4.m5, c5.m5, c6.m5, c7.m5 - ]; - var s1 = [c4.m5, c5.m5, c6.m5, c7.m5, c4.m4, c5.m4, c6.m4, c7.m4, - c4.m2, c5.m2, c6.m2, c7.m2, p12, c3.m0, c3.m3, c3.m5 - ]; - var s2 = [c7.m5, c8.m5, c9.m5, c10.m5, c7.m4, c8.m4, c9.m4, c10.m4, - c7.m2, c8.m2, c9.m2, c10.m2, c3.m5, c3.m4, c3.m2, p15 - ]; - var s3 = [c0.m5, c0.m4, c0.m2, p3, c7.m0, c8.m0, c9.m0, c10.m0, - c7.m3, c8.m3, c9.m3, c10.m3, c7.m5, c8.m5, c9.m5, c10.m5 - ]; - - var m4 = s0[15]; - - var n0 = normal(s0[0], s0[4], s0[8], s0[12], s0[13], s0[14], s0[15]); - if (n0 == 0.0) { - n0 = normal(s0[0], s0[4], s0[8], s0[12], s0[11], s0[7], s0[3]); - if (n0 == 0.0) n0 = normal(s0[3], s0[2], s0[1], s0[0], s0[13], s0[14], s0[15]); - } - - var n1 = normal(s1[12], s1[13], s1[14], s1[15], s1[11], s1[7], s1[3]); - if (n1 == 0.0) { - n1 = normal(s1[12], s1[13], s1[14], s1[15], s1[2], s1[1], s1[0]); - if (n1 == 0.0) n1 = normal(s1[0], s1[4], s1[8], s1[12], s1[11], s1[7], s1[3]); - } - - var n2 = normal(s2[15], s2[11], s2[7], s2[3], s2[2], s2[1], s2[0]); - if (n2 == 0.0) { - n2 = normal(s2[15], s2[11], s2[7], s2[3], s2[4], s2[8], s2[12]); - if (n2 == 0.0) n2 = normal(s2[12], s2[13], s2[14], s2[15], s2[2], s2[1], s2[0]); - } - - var n3 = normal(s3[3], s3[2], s3[1], s3[0], s3[4], s3[8], s3[12]); - if (n3 == 0.0) { - n3 = normal(s3[3], s3[2], s3[1], s3[0], s3[13], s3[14], s3[15]); - if (n3 == 0.0) n3 = normal(s3[15], s3[11], s3[7], s3[3], s3[4], s3[8], s3[12]); - } - - var n4 = normal(s2[3], s2[2], s2[1], m4, s2[4], s2[8], s2[12]); - - var m0, m1, m2, m3; - - // A kludge to remove subdivision cracks, only applied the first time - // an edge is found to be flat before the rest of the subpatch is. - if (flat0) - m0 = [0.5 * (P0[0] + P1[0]), 0.5 * (P0[1] + P1[1]), 0.5 * (P0[2] + P1[2])]; - else { - if ((flat0 = Distance1(p0, p[4], p[8], p12) < res2)) { - var u = s0[12]; - var v = s2[3]; - var e = unit([u[0] - v[0], u[1] - v[1], u[2] - v[2]]); - m0 = [0.5 * (P0[0] + P1[0]) + Epsilon * e[0], 0.5 * (P0[1] + P1[1]) + Epsilon * e[1], - 0.5 * (P0[2] + P1[2]) + Epsilon * e[2] - ]; - } else - m0 = s0[12]; - } - - if (flat1) - m1 = [0.5 * (P1[0] + P2[0]), 0.5 * (P1[1] + P2[1]), 0.5 * (P1[2] + P2[2])]; - else { - if ((flat1 = Distance1(p12, p[13], p[14], p15) < res2)) { - var u = s1[15]; - var v = s3[0]; - var e = unit([u[0] - v[0], u[1] - v[1], u[2] - v[2]]); - m1 = [0.5 * (P1[0] + P2[0]) + Epsilon * e[0], 0.5 * (P1[1] + P2[1]) + Epsilon * e[1], - 0.5 * (P1[2] + P2[2]) + Epsilon * e[2] - ]; - } else - m1 = s1[15]; - } - - if (flat2) - m2 = [0.5 * (P2[0] + P3[0]), 0.5 * (P2[1] + P3[1]), 0.5 * (P2[2] + P3[2])]; - else { - if ((flat2 = Distance1(p15, p[11], p[7], p3) < res2)) { - var u = s2[3]; - var v = s0[12]; - var e = unit([u[0] - v[0], u[1] - v[1], u[2] - v[2]]); - m2 = [0.5 * (P2[0] + P3[0]) + Epsilon * e[0], 0.5 * (P2[1] + P3[1]) + Epsilon * e[1], - 0.5 * (P2[2] + P3[2]) + Epsilon * e[2] - ]; - } else - m2 = s2[3]; - } - - if (flat3) - m3 = [0.5 * (P3[0] + P0[0]), 0.5 * (P3[1] + P0[1]), 0.5 * (P3[2] + P0[2])]; - else { - if ((flat3 = Distance1(p3, p[2], p[1], p0) < res2)) { - var u = s3[0]; - var v = s1[15]; - var e = unit([u[0] - v[0], u[1] - v[1], u[2] - v[2]]); - m3 = [0.5 * (P3[0] + P0[0]) + Epsilon * e[0], - 0.5 * (P3[1] + P0[1]) + Epsilon * e[1], - 0.5 * (P3[2] + P0[2]) + Epsilon * e[2] - ]; - } else - m3 = s3[0]; - } +function setViewport() +{ + gl.viewportWidth=canvasWidth; + gl.viewportHeight=canvasHeight; + gl.viewport(0,0,gl.viewportWidth,gl.viewportHeight); + home(); +} - // document.write(n0); - // document.write(" < br > "); +function setCanvas() +{ + canvas.width=canvasWidth; + canvas.height=canvasHeight; + size2=Math.hypot(canvasWidth,canvasHeight); + halfCanvasWidth=0.5*canvasWidth; + halfCanvasHeight=0.5*canvasHeight; +} - { - /* - var c0=new Array(4); - var c1=new Array(4); - var c2=new Array(4); - var c3=new Array(4); - var c4=new Array(4); - - for(var i=0; i < 4; ++i) { - c0[i]=0.5*(C0[i]+C1[i]); - c1[i]=0.5*(C1[i]+C2[i]); - c2[i]=0.5*(C2[i]+C3[i]); - c3[i]=0.5*(C3[i]+C0[i]); - c4[i]=0.5*(c0[i]+c2[i]); - } - */ +function setsize(w,h) +{ + if(w > maxViewportWidth) + w=maxViewportWidth; - var c0 = color(n0); - var c1 = color(n1); - var c2 = color(n2); - var c3 = color(n3); - var c4 = color(n4); + if(h > maxViewportHeight) + h=maxViewportHeight; + shift.x *= w/canvasWidth; + shift.y *= h/canvasHeight; - var i0 = vertex(m0, c0, n0); - var i1 = vertex(m1, c1, n1); - var i2 = vertex(m2, c2, n2); - var i3 = vertex(m3, c3, n3); - var i4 = vertex(m4, c4, n4); + canvasWidth=w; + canvasHeight=h; + setCanvas(); + setViewport(); +} - render(s0, I0, i0, i4, i3, P0, m0, m4, m3, flat0, false, false, flat3, - C0, c0, c4, c3); - render(s1, i0, I1, i1, i4, m0, P1, m1, m4, flat0, flat1, false, false, - c0, C1, c1, c4); - render(s2, i4, i1, I2, i2, m4, m1, P2, m2, false, flat1, flat2, false, - c4, c1, C2, c2); - render(s3, i3, i4, i2, I3, m3, m4, m2, P3, false, false, flat2, flat3, - c3, c4, c2, C3); - } +function expand() +{ + setsize(canvasWidth*resizeStep+0.5,canvasHeight*resizeStep+0.5); } -var p; +function shrink() +{ + setsize(Math.max((canvasWidth/resizeStep+0.5),1), + Math.max((canvasHeight/resizeStep+0.5),1)); +} -function draw() { - sceneSetup(); - // mat4.translate(mMatrix,mMatrix,[-0.5,-0.5,-1.5]); +let pixelShader,noNormalShader,materialShader,colorShader,transparentShader; + +function webGLStart() +{ + canvas=document.getElementById("Asymptote"); + + if(absolute) { + canvasWidth *= window.devicePixelRatio; + canvasHeight *= window.devicePixelRatio; + } else { + if(canvas.width == 0) + canvas.width=Math.max(window.innerWidth-windowTrim,windowTrim); + + if(canvas.height == 0) + canvas.height=Math.max(window.innerHeight-windowTrim,windowTrim); + + let Aspect=canvasWidth/canvasHeight; + if(canvas.width > canvas.height*Aspect) + canvas.width=Math.min(canvas.height*Aspect,canvas.width); + else + canvas.height=Math.min(canvas.width/Aspect,canvas.height); + + if(canvas.width > 0) + canvasWidth=canvas.width; + + if(canvas.height > 0) + canvasHeight=canvas.height; - setBuffer(); - var p0 = p[0]; - var p3 = p[3]; - var p12 = p[12]; - var p15 = p[15]; - - epsilon = 0; - for (var i = 1; i < 16; ++i) - epsilon = Math.max(epsilon, - abs2([p[i][0] - p0[0], p[i][1] - p0[1], p[i][2] - p0[2]])); - epsilon *= Fuzz2; - - var n0 = normal(p3, p[2], p[1], p0, p[4], p[8], p12); - var n1 = normal(p0, p[4], p[8], p12, p[13], p[14], p15); - var n2 = normal(p12, p[13], p[14], p15, p[11], p[7], p3); - var n3 = normal(p15, p[11], p[7], p3, p[2], p[1], p0); - - var c0 = color(n0); - var c1 = color(n1); - var c2 = color(n2); - var c3 = color(n3); - - var i0 = vertex(p0, c0, n0); - var i1 = vertex(p12, c1, n1); - var i2 = vertex(p15, c2, n2); - var i3 = vertex(p3, c3, n3); - - render(p, i0, i1, i2, i3, p0, p12, p15, p3, false, false, false, false, - c0, c1, c2, c3); - drawBuffer(); -} - -var forceredraw = false; -var lasttime; -var newtime; - -function tick() { - requestAnimationFrame(tick); - lasttime = newtime; - newtime = performance.now(); - // invariant: every time this loop is called, lasttime stores the - // last time processloop was called. - processloop(newtime - lasttime); - draw(); -} -function tickNoRedraw() { - requestAnimationFrame(tickNoRedraw); - if (redraw) { - draw(); - redraw = false; } -} -function webGLStart() { - var canvas = document.getElementById("Asymptote"); - initGL(canvas); - initShaders(); - gl.clearColor(0.0, 0.0, 0.0, 1.0); + setCanvas(); + ArcballFactor=1+8*Math.hypot(viewportmargin[0],viewportmargin[1])/size2; + + initGL(); + + gl.enable(gl.BLEND); + gl.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA); gl.enable(gl.DEPTH_TEST); + setViewport(); - canvas.onmousedown = handleMouseDown; - document.onmouseup = handleMouseUpOrTouchEnd; - document.onmousemove = handleMouseMove; - canvas.onkeydown = handleKey; - document.onwheel = handleMouseWheel; + noNormalShader=initShader(); + pixelShader=initShader(["WIDTH"]); + materialShader=initShader(["NORMAL"]); + colorShader=initShader(["NORMAL","COLOR"]); + transparentShader=initShader(["NORMAL","COLOR","TRANSPARENT"]); - canvas.addEventListener("touchstart", handleTouchStart, false); - canvas.addEventListener("touchend", handleMouseUpOrTouchEnd, false); - canvas.addEventListener("touchcancel", handleMouseUpOrTouchEnd, false); - canvas.addEventListener("touchleave", handleMouseUpOrTouchEnd, false); - canvas.addEventListener("touchmove", handleTouchMove, false); + setBuffer(); + + canvas.onmousedown=handleMouseDown; + document.onmouseup=handleMouseUpOrTouchEnd; + document.onmousemove=handleMouseMove; + canvas.onkeydown=handleKey; + document.onwheel=handleMouseWheel; - newtime = performance.now(); + canvas.addEventListener("touchstart",handleTouchStart,false); + canvas.addEventListener("touchend",handleMouseUpOrTouchEnd,false); + canvas.addEventListener("touchcancel",handleMouseUpOrTouchEnd,false); + canvas.addEventListener("touchleave",handleMouseUpOrTouchEnd,false); + canvas.addEventListener("touchmove",handleTouchMove,false); + document.addEventListener("keydown",handleKey,false); - if (forceredraw) { tick(); - } else { - tickNoRedraw(); - } } diff --git a/graphics/asymptote/webgl/glm-js-min-2.2.2.js b/graphics/asymptote/webgl/glm-js-min-2.2.2.js deleted file mode 100644 index 3e11d90371..0000000000 --- a/graphics/asymptote/webgl/glm-js-min-2.2.2.js +++ /dev/null @@ -1,273 +0,0 @@ -/*! glm-js built 2017-03-20 16:45:23-04:00 | (c) humbletim | http://humbletim.github.io/glm-js */ -(function declare_glmjs_glmatrix(globals, $GLM_log, $GLM_console_log) { var GLM, GLMAT, GLMAT_VERSION, GLMJS_PREFIX, $GLM_console_factory, glm; ArrayBuffer.exists; -/* - - -------------------------------------------------------------------------- - glm-js | (c) humbletim | http://humbletim.github.io/glm-js - -------------------------------------------------------------------------- - - The MIT License (MIT) - - Copyright (c) 2015-2016 humbletim - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - -------------------------------------------------------------------------- - gl-matrix | (c) Brandon Jones, Colin MacKenzie IV | http://glmatrix.net/ - -------------------------------------------------------------------------- - - Copyright (c) 2013 Brandon Jones, Colin MacKenzie IV - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not - be misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source distribution. -*/ -GLMAT={};GLMAT_VERSION="2.2.2"; -(function(a){a.VERSION=GLMAT_VERSION;if(!b)var b=1E-6;if(!c)var c="undefined"!==typeof Float32Array?Float32Array:Array;if(!e)var e=Math.random;var d={setMatrixArrayType:function(y){c=y}};"undefined"!==typeof a&&(a.glMatrix=d);var h=Math.PI/180;d.toRadian=function(y){return y*h};d={create:function(){var y=new c(2);y[0]=0;y[1]=0;return y},clone:function(y){var a=new c(2);a[0]=y[0];a[1]=y[1];return a},fromValues:function(y,a){var v=new c(2);v[0]=y;v[1]=a;return v},copy:function(y,a){y[0]=a[0];y[1]=a[1]; -return y},set:function(y,a,v){y[0]=a;y[1]=v;return y},add:function(y,a,v){y[0]=a[0]+v[0];y[1]=a[1]+v[1];return y},subtract:function(y,a,v){y[0]=a[0]-v[0];y[1]=a[1]-v[1];return y}};d.sub=d.subtract;d.multiply=function(y,a,v){y[0]=a[0]*v[0];y[1]=a[1]*v[1];return y};d.mul=d.multiply;d.divide=function(y,a,v){y[0]=a[0]/v[0];y[1]=a[1]/v[1];return y};d.div=d.divide;d.min=function(y,a,v){y[0]=Math.min(a[0],v[0]);y[1]=Math.min(a[1],v[1]);return y};d.max=function(y,a,v){y[0]=Math.max(a[0],v[0]);y[1]=Math.max(a[1], -v[1]);return y};d.scale=function(y,a,v){y[0]=a[0]*v;y[1]=a[1]*v;return y};d.scaleAndAdd=function(y,a,v,b){y[0]=a[0]+v[0]*b;y[1]=a[1]+v[1]*b;return y};d.distance=function(a,f){var v=f[0]-a[0],b=f[1]-a[1];return Math.sqrt(v*v+b*b)};d.dist=d.distance;d.squaredDistance=function(a,f){var v=f[0]-a[0],b=f[1]-a[1];return v*v+b*b};d.sqrDist=d.squaredDistance;d.length=function(a){var f=a[0];a=a[1];return Math.sqrt(f*f+a*a)};d.len=d.length;d.squaredLength=function(a){var f=a[0];a=a[1];return f*f+a*a};d.sqrLen= -d.squaredLength;d.negate=function(a,f){a[0]=-f[0];a[1]=-f[1];return a};d.inverse=function(a,f){a[0]=1/f[0];a[1]=1/f[1];return a};d.normalize=function(a,f){var v=f[0],b=f[1],v=v*v+b*b;0<v&&(v=1/Math.sqrt(v),a[0]=f[0]*v,a[1]=f[1]*v);return a};d.dot=function(a,f){return a[0]*f[0]+a[1]*f[1]};d.cross=function(a,f,v){f=f[0]*v[1]-f[1]*v[0];a[0]=a[1]=0;a[2]=f;return a};d.lerp=function(a,f,v,b){var c=f[0];f=f[1];a[0]=c+b*(v[0]-c);a[1]=f+b*(v[1]-f);return a};d.random=function(a,f){f=f||1;var v=2*e()*Math.PI; -a[0]=Math.cos(v)*f;a[1]=Math.sin(v)*f;return a};d.transformMat2=function(a,f,v){var b=f[0];f=f[1];a[0]=v[0]*b+v[2]*f;a[1]=v[1]*b+v[3]*f;return a};d.transformMat2d=function(a,f,v){var b=f[0];f=f[1];a[0]=v[0]*b+v[2]*f+v[4];a[1]=v[1]*b+v[3]*f+v[5];return a};d.transformMat3=function(a,f,b){var c=f[0];f=f[1];a[0]=b[0]*c+b[3]*f+b[6];a[1]=b[1]*c+b[4]*f+b[7];return a};d.transformMat4=function(a,f,b){var c=f[0];f=f[1];a[0]=b[0]*c+b[4]*f+b[12];a[1]=b[1]*c+b[5]*f+b[13];return a};var j=d.create();d.forEach=function(a, -f,b,c,d,e){f||(f=2);b||(b=0);for(c=c?Math.min(c*f+b,a.length):a.length;b<c;b+=f)j[0]=a[b],j[1]=a[b+1],d(j,j,e),a[b]=j[0],a[b+1]=j[1];return a};d.str=function(a){return"vec2("+a[0]+", "+a[1]+")"};"undefined"!==typeof a&&(a.vec2=d);var g={create:function(){var a=new c(3);a[0]=0;a[1]=0;a[2]=0;return a},clone:function(a){var f=new c(3);f[0]=a[0];f[1]=a[1];f[2]=a[2];return f},fromValues:function(a,f,b){var P=new c(3);P[0]=a;P[1]=f;P[2]=b;return P},copy:function(a,f){a[0]=f[0];a[1]=f[1];a[2]=f[2];return a}, -set:function(a,f,b,c){a[0]=f;a[1]=b;a[2]=c;return a},add:function(a,f,b){a[0]=f[0]+b[0];a[1]=f[1]+b[1];a[2]=f[2]+b[2];return a},subtract:function(a,f,b){a[0]=f[0]-b[0];a[1]=f[1]-b[1];a[2]=f[2]-b[2];return a}};g.sub=g.subtract;g.multiply=function(a,f,b){a[0]=f[0]*b[0];a[1]=f[1]*b[1];a[2]=f[2]*b[2];return a};g.mul=g.multiply;g.divide=function(a,f,b){a[0]=f[0]/b[0];a[1]=f[1]/b[1];a[2]=f[2]/b[2];return a};g.div=g.divide;g.min=function(a,f,b){a[0]=Math.min(f[0],b[0]);a[1]=Math.min(f[1],b[1]);a[2]=Math.min(f[2], -b[2]);return a};g.max=function(a,f,b){a[0]=Math.max(f[0],b[0]);a[1]=Math.max(f[1],b[1]);a[2]=Math.max(f[2],b[2]);return a};g.scale=function(a,f,b){a[0]=f[0]*b;a[1]=f[1]*b;a[2]=f[2]*b;return a};g.scaleAndAdd=function(a,f,b,c){a[0]=f[0]+b[0]*c;a[1]=f[1]+b[1]*c;a[2]=f[2]+b[2]*c;return a};g.distance=function(a,f){var b=f[0]-a[0],c=f[1]-a[1],d=f[2]-a[2];return Math.sqrt(b*b+c*c+d*d)};g.dist=g.distance;g.squaredDistance=function(a,f){var b=f[0]-a[0],c=f[1]-a[1],d=f[2]-a[2];return b*b+c*c+d*d};g.sqrDist= -g.squaredDistance;g.length=function(a){var f=a[0],b=a[1];a=a[2];return Math.sqrt(f*f+b*b+a*a)};g.len=g.length;g.squaredLength=function(a){var f=a[0],b=a[1];a=a[2];return f*f+b*b+a*a};g.sqrLen=g.squaredLength;g.negate=function(a,f){a[0]=-f[0];a[1]=-f[1];a[2]=-f[2];return a};g.inverse=function(a,f){a[0]=1/f[0];a[1]=1/f[1];a[2]=1/f[2];return a};g.normalize=function(a,f){var b=f[0],c=f[1],d=f[2],b=b*b+c*c+d*d;0<b&&(b=1/Math.sqrt(b),a[0]=f[0]*b,a[1]=f[1]*b,a[2]=f[2]*b);return a};g.dot=function(a,f){return a[0]* -f[0]+a[1]*f[1]+a[2]*f[2]};g.cross=function(a,f,b){var c=f[0],d=f[1];f=f[2];var e=b[0],l=b[1];b=b[2];a[0]=d*b-f*l;a[1]=f*e-c*b;a[2]=c*l-d*e;return a};g.lerp=function(a,f,b,c){var d=f[0],e=f[1];f=f[2];a[0]=d+c*(b[0]-d);a[1]=e+c*(b[1]-e);a[2]=f+c*(b[2]-f);return a};g.random=function(a,f){f=f||1;var b=2*e()*Math.PI,c=2*e()-1,d=Math.sqrt(1-c*c)*f;a[0]=Math.cos(b)*d;a[1]=Math.sin(b)*d;a[2]=c*f;return a};g.transformMat4=function(a,f,b){var c=f[0],d=f[1];f=f[2];var e=b[3]*c+b[7]*d+b[11]*f+b[15],e=e||1;a[0]= -(b[0]*c+b[4]*d+b[8]*f+b[12])/e;a[1]=(b[1]*c+b[5]*d+b[9]*f+b[13])/e;a[2]=(b[2]*c+b[6]*d+b[10]*f+b[14])/e;return a};g.transformMat3=function(a,f,b){var c=f[0],d=f[1];f=f[2];a[0]=c*b[0]+d*b[3]+f*b[6];a[1]=c*b[1]+d*b[4]+f*b[7];a[2]=c*b[2]+d*b[5]+f*b[8];return a};g.transformQuat=function(a,f,b){var c=f[0],d=f[1],e=f[2];f=b[0];var l=b[1],x=b[2];b=b[3];var u=b*c+l*e-x*d,J=b*d+x*c-f*e,g=b*e+f*d-l*c,c=-f*c-l*d-x*e;a[0]=u*b+c*-f+J*-x-g*-l;a[1]=J*b+c*-l+g*-f-u*-x;a[2]=g*b+c*-x+u*-l-J*-f;return a};g.rotateX= -function(a,f,b,c){var d=[],e=[];d[0]=f[0]-b[0];d[1]=f[1]-b[1];d[2]=f[2]-b[2];e[0]=d[0];e[1]=d[1]*Math.cos(c)-d[2]*Math.sin(c);e[2]=d[1]*Math.sin(c)+d[2]*Math.cos(c);a[0]=e[0]+b[0];a[1]=e[1]+b[1];a[2]=e[2]+b[2];return a};g.rotateY=function(a,f,b,c){var d=[],e=[];d[0]=f[0]-b[0];d[1]=f[1]-b[1];d[2]=f[2]-b[2];e[0]=d[2]*Math.sin(c)+d[0]*Math.cos(c);e[1]=d[1];e[2]=d[2]*Math.cos(c)-d[0]*Math.sin(c);a[0]=e[0]+b[0];a[1]=e[1]+b[1];a[2]=e[2]+b[2];return a};g.rotateZ=function(a,f,b,c){var d=[],e=[];d[0]=f[0]- -b[0];d[1]=f[1]-b[1];d[2]=f[2]-b[2];e[0]=d[0]*Math.cos(c)-d[1]*Math.sin(c);e[1]=d[0]*Math.sin(c)+d[1]*Math.cos(c);e[2]=d[2];a[0]=e[0]+b[0];a[1]=e[1]+b[1];a[2]=e[2]+b[2];return a};var k=g.create();g.forEach=function(a,f,b,c,d,e){f||(f=3);b||(b=0);for(c=c?Math.min(c*f+b,a.length):a.length;b<c;b+=f)k[0]=a[b],k[1]=a[b+1],k[2]=a[b+2],d(k,k,e),a[b]=k[0],a[b+1]=k[1],a[b+2]=k[2];return a};g.str=function(a){return"vec3("+a[0]+", "+a[1]+", "+a[2]+")"};"undefined"!==typeof a&&(a.vec3=g);var i={create:function(){var a= -new c(4);a[0]=0;a[1]=0;a[2]=0;a[3]=0;return a},clone:function(a){var f=new c(4);f[0]=a[0];f[1]=a[1];f[2]=a[2];f[3]=a[3];return f},fromValues:function(a,f,b,d){var e=new c(4);e[0]=a;e[1]=f;e[2]=b;e[3]=d;return e},copy:function(a,f){a[0]=f[0];a[1]=f[1];a[2]=f[2];a[3]=f[3];return a},set:function(a,f,b,c,d){a[0]=f;a[1]=b;a[2]=c;a[3]=d;return a},add:function(a,f,b){a[0]=f[0]+b[0];a[1]=f[1]+b[1];a[2]=f[2]+b[2];a[3]=f[3]+b[3];return a},subtract:function(a,f,b){a[0]=f[0]-b[0];a[1]=f[1]-b[1];a[2]=f[2]-b[2]; -a[3]=f[3]-b[3];return a}};i.sub=i.subtract;i.multiply=function(a,f,b){a[0]=f[0]*b[0];a[1]=f[1]*b[1];a[2]=f[2]*b[2];a[3]=f[3]*b[3];return a};i.mul=i.multiply;i.divide=function(a,f,b){a[0]=f[0]/b[0];a[1]=f[1]/b[1];a[2]=f[2]/b[2];a[3]=f[3]/b[3];return a};i.div=i.divide;i.min=function(a,f,b){a[0]=Math.min(f[0],b[0]);a[1]=Math.min(f[1],b[1]);a[2]=Math.min(f[2],b[2]);a[3]=Math.min(f[3],b[3]);return a};i.max=function(a,f,b){a[0]=Math.max(f[0],b[0]);a[1]=Math.max(f[1],b[1]);a[2]=Math.max(f[2],b[2]);a[3]= -Math.max(f[3],b[3]);return a};i.scale=function(a,f,b){a[0]=f[0]*b;a[1]=f[1]*b;a[2]=f[2]*b;a[3]=f[3]*b;return a};i.scaleAndAdd=function(a,f,b,c){a[0]=f[0]+b[0]*c;a[1]=f[1]+b[1]*c;a[2]=f[2]+b[2]*c;a[3]=f[3]+b[3]*c;return a};i.distance=function(a,f){var b=f[0]-a[0],c=f[1]-a[1],d=f[2]-a[2],e=f[3]-a[3];return Math.sqrt(b*b+c*c+d*d+e*e)};i.dist=i.distance;i.squaredDistance=function(a,f){var b=f[0]-a[0],c=f[1]-a[1],d=f[2]-a[2],e=f[3]-a[3];return b*b+c*c+d*d+e*e};i.sqrDist=i.squaredDistance;i.length=function(a){var f= -a[0],b=a[1],c=a[2];a=a[3];return Math.sqrt(f*f+b*b+c*c+a*a)};i.len=i.length;i.squaredLength=function(a){var f=a[0],b=a[1],c=a[2];a=a[3];return f*f+b*b+c*c+a*a};i.sqrLen=i.squaredLength;i.negate=function(a,f){a[0]=-f[0];a[1]=-f[1];a[2]=-f[2];a[3]=-f[3];return a};i.inverse=function(a,f){a[0]=1/f[0];a[1]=1/f[1];a[2]=1/f[2];a[3]=1/f[3];return a};i.normalize=function(a,f){var b=f[0],c=f[1],d=f[2],e=f[3],b=b*b+c*c+d*d+e*e;0<b&&(b=1/Math.sqrt(b),a[0]=f[0]*b,a[1]=f[1]*b,a[2]=f[2]*b,a[3]=f[3]*b);return a}; -i.dot=function(a,f){return a[0]*f[0]+a[1]*f[1]+a[2]*f[2]+a[3]*f[3]};i.lerp=function(a,f,b,c){var d=f[0],e=f[1],l=f[2];f=f[3];a[0]=d+c*(b[0]-d);a[1]=e+c*(b[1]-e);a[2]=l+c*(b[2]-l);a[3]=f+c*(b[3]-f);return a};i.random=function(a,f){f=f||1;a[0]=e();a[1]=e();a[2]=e();a[3]=e();i.normalize(a,a);i.scale(a,a,f);return a};i.transformMat4=function(a,f,b){var c=f[0],d=f[1],e=f[2];f=f[3];a[0]=b[0]*c+b[4]*d+b[8]*e+b[12]*f;a[1]=b[1]*c+b[5]*d+b[9]*e+b[13]*f;a[2]=b[2]*c+b[6]*d+b[10]*e+b[14]*f;a[3]=b[3]*c+b[7]*d+ -b[11]*e+b[15]*f;return a};i.transformQuat=function(a,b,c){var d=b[0],e=b[1],n=b[2];b=c[0];var l=c[1],x=c[2];c=c[3];var u=c*d+l*n-x*e,J=c*e+x*d-b*n,g=c*n+b*e-l*d,d=-b*d-l*e-x*n;a[0]=u*c+d*-b+J*-x-g*-l;a[1]=J*c+d*-l+g*-b-u*-x;a[2]=g*c+d*-x+u*-l-J*-b;return a};var w=i.create();i.forEach=function(a,b,c,d,e,n){b||(b=4);c||(c=0);for(d=d?Math.min(d*b+c,a.length):a.length;c<d;c+=b)w[0]=a[c],w[1]=a[c+1],w[2]=a[c+2],w[3]=a[c+3],e(w,w,n),a[c]=w[0],a[c+1]=w[1],a[c+2]=w[2],a[c+3]=w[3];return a};i.str=function(a){return"vec4("+ -a[0]+", "+a[1]+", "+a[2]+", "+a[3]+")"};"undefined"!==typeof a&&(a.vec4=i);d={create:function(){var a=new c(4);a[0]=1;a[1]=0;a[2]=0;a[3]=1;return a},clone:function(a){var b=new c(4);b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];return b},copy:function(a,b){a[0]=b[0];a[1]=b[1];a[2]=b[2];a[3]=b[3];return a},identity:function(a){a[0]=1;a[1]=0;a[2]=0;a[3]=1;return a},transpose:function(a,b){if(a===b){var c=b[1];a[1]=b[2];a[2]=c}else a[0]=b[0],a[1]=b[2],a[2]=b[1],a[3]=b[3];return a},invert:function(a,b){var c= -b[0],d=b[1],e=b[2],n=b[3],l=c*n-e*d;if(!l)return null;l=1/l;a[0]=n*l;a[1]=-d*l;a[2]=-e*l;a[3]=c*l;return a},adjoint:function(a,b){var c=b[0];a[0]=b[3];a[1]=-b[1];a[2]=-b[2];a[3]=c;return a},determinant:function(a){return a[0]*a[3]-a[2]*a[1]},multiply:function(a,b,c){var d=b[0],e=b[1],n=b[2];b=b[3];var l=c[0],x=c[1],u=c[2];c=c[3];a[0]=d*l+n*x;a[1]=e*l+b*x;a[2]=d*u+n*c;a[3]=e*u+b*c;return a}};d.mul=d.multiply;d.rotate=function(a,b,c){var d=b[0],e=b[1],n=b[2];b=b[3];var l=Math.sin(c);c=Math.cos(c);a[0]= -d*c+n*l;a[1]=e*c+b*l;a[2]=d*-l+n*c;a[3]=e*-l+b*c;return a};d.scale=function(a,b,c){var d=b[1],e=b[2],n=b[3],l=c[0];c=c[1];a[0]=b[0]*l;a[1]=d*l;a[2]=e*c;a[3]=n*c;return a};d.str=function(a){return"mat2("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+")"};d.frob=function(a){return Math.sqrt(Math.pow(a[0],2)+Math.pow(a[1],2)+Math.pow(a[2],2)+Math.pow(a[3],2))};d.LDU=function(a,b,c,d){a[2]=d[2]/d[0];c[0]=d[0];c[1]=d[1];c[3]=d[3]-a[2]*c[1];return[a,b,c]};"undefined"!==typeof a&&(a.mat2=d);d={create:function(){var a= -new c(6);a[0]=1;a[1]=0;a[2]=0;a[3]=1;a[4]=0;a[5]=0;return a},clone:function(a){var b=new c(6);b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];return b},copy:function(a,b){a[0]=b[0];a[1]=b[1];a[2]=b[2];a[3]=b[3];a[4]=b[4];a[5]=b[5];return a},identity:function(a){a[0]=1;a[1]=0;a[2]=0;a[3]=1;a[4]=0;a[5]=0;return a},invert:function(a,b){var c=b[0],d=b[1],e=b[2],n=b[3],l=b[4],x=b[5],u=c*n-d*e;if(!u)return null;u=1/u;a[0]=n*u;a[1]=-d*u;a[2]=-e*u;a[3]=c*u;a[4]=(e*x-n*l)*u;a[5]=(d*l-c*x)*u;return a}, -determinant:function(a){return a[0]*a[3]-a[1]*a[2]},multiply:function(a,b,c){var d=b[0],e=b[1],n=b[2],l=b[3],x=b[4];b=b[5];var u=c[0],g=c[1],h=c[2],K=c[3],j=c[4];c=c[5];a[0]=d*u+n*g;a[1]=e*u+l*g;a[2]=d*h+n*K;a[3]=e*h+l*K;a[4]=d*j+n*c+x;a[5]=e*j+l*c+b;return a}};d.mul=d.multiply;d.rotate=function(a,b,c){var d=b[0],e=b[1],n=b[2],l=b[3],x=b[4];b=b[5];var u=Math.sin(c);c=Math.cos(c);a[0]=d*c+n*u;a[1]=e*c+l*u;a[2]=d*-u+n*c;a[3]=e*-u+l*c;a[4]=x;a[5]=b;return a};d.scale=function(a,b,c){var d=b[1],e=b[2], -n=b[3],l=b[4],x=b[5],u=c[0];c=c[1];a[0]=b[0]*u;a[1]=d*u;a[2]=e*c;a[3]=n*c;a[4]=l;a[5]=x;return a};d.translate=function(a,b,c){var d=b[0],e=b[1],n=b[2],l=b[3],x=b[4];b=b[5];var u=c[0];c=c[1];a[0]=d;a[1]=e;a[2]=n;a[3]=l;a[4]=d*u+n*c+x;a[5]=e*u+l*c+b;return a};d.str=function(a){return"mat2d("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+")"};d.frob=function(a){return Math.sqrt(Math.pow(a[0],2)+Math.pow(a[1],2)+Math.pow(a[2],2)+Math.pow(a[3],2)+Math.pow(a[4],2)+Math.pow(a[5],2)+1)};"undefined"!== -typeof a&&(a.mat2d=d);d={create:function(){var a=new c(9);a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=1;a[5]=0;a[6]=0;a[7]=0;a[8]=1;return a},fromMat4:function(a,b){a[0]=b[0];a[1]=b[1];a[2]=b[2];a[3]=b[4];a[4]=b[5];a[5]=b[6];a[6]=b[8];a[7]=b[9];a[8]=b[10];return a},clone:function(a){var b=new c(9);b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];return b},copy:function(a,b){a[0]=b[0];a[1]=b[1];a[2]=b[2];a[3]=b[3];a[4]=b[4];a[5]=b[5];a[6]=b[6];a[7]=b[7];a[8]=b[8];return a}, -identity:function(a){a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=1;a[5]=0;a[6]=0;a[7]=0;a[8]=1;return a},transpose:function(a,b){if(a===b){var c=b[1],d=b[2],e=b[5];a[1]=b[3];a[2]=b[6];a[3]=c;a[5]=b[7];a[6]=d;a[7]=e}else a[0]=b[0],a[1]=b[3],a[2]=b[6],a[3]=b[1],a[4]=b[4],a[5]=b[7],a[6]=b[2],a[7]=b[5],a[8]=b[8];return a},invert:function(a,b){var c=b[0],d=b[1],e=b[2],n=b[3],l=b[4],x=b[5],u=b[6],g=b[7],h=b[8],K=h*l-x*g,j=-h*n+x*u,m=g*n-l*u,i=c*K+d*j+e*m;if(!i)return null;i=1/i;a[0]=K*i;a[1]=(-h*d+e*g)*i;a[2]=(x* -d-e*l)*i;a[3]=j*i;a[4]=(h*c-e*u)*i;a[5]=(-x*c+e*n)*i;a[6]=m*i;a[7]=(-g*c+d*u)*i;a[8]=(l*c-d*n)*i;return a},adjoint:function(a,b){var c=b[0],d=b[1],e=b[2],n=b[3],l=b[4],x=b[5],u=b[6],g=b[7],h=b[8];a[0]=l*h-x*g;a[1]=e*g-d*h;a[2]=d*x-e*l;a[3]=x*u-n*h;a[4]=c*h-e*u;a[5]=e*n-c*x;a[6]=n*g-l*u;a[7]=d*u-c*g;a[8]=c*l-d*n;return a},determinant:function(a){var b=a[3],c=a[4],d=a[5],e=a[6],n=a[7],l=a[8];return a[0]*(l*c-d*n)+a[1]*(-l*b+d*e)+a[2]*(n*b-c*e)},multiply:function(a,b,c){var d=b[0],e=b[1],n=b[2],l=b[3], -x=b[4],u=b[5],g=b[6],h=b[7];b=b[8];var j=c[0],m=c[1],i=c[2],k=c[3],q=c[4],t=c[5],s=c[6],r=c[7];c=c[8];a[0]=j*d+m*l+i*g;a[1]=j*e+m*x+i*h;a[2]=j*n+m*u+i*b;a[3]=k*d+q*l+t*g;a[4]=k*e+q*x+t*h;a[5]=k*n+q*u+t*b;a[6]=s*d+r*l+c*g;a[7]=s*e+r*x+c*h;a[8]=s*n+r*u+c*b;return a}};d.mul=d.multiply;d.translate=function(a,b,c){var d=b[0],e=b[1],n=b[2],l=b[3],x=b[4],u=b[5],g=b[6],h=b[7];b=b[8];var j=c[0];c=c[1];a[0]=d;a[1]=e;a[2]=n;a[3]=l;a[4]=x;a[5]=u;a[6]=j*d+c*l+g;a[7]=j*e+c*x+h;a[8]=j*n+c*u+b;return a};d.rotate= -function(a,b,c){var d=b[0],e=b[1],n=b[2],l=b[3],x=b[4],u=b[5],g=b[6],h=b[7];b=b[8];var j=Math.sin(c);c=Math.cos(c);a[0]=c*d+j*l;a[1]=c*e+j*x;a[2]=c*n+j*u;a[3]=c*l-j*d;a[4]=c*x-j*e;a[5]=c*u-j*n;a[6]=g;a[7]=h;a[8]=b;return a};d.scale=function(a,b,c){var d=c[0];c=c[1];a[0]=d*b[0];a[1]=d*b[1];a[2]=d*b[2];a[3]=c*b[3];a[4]=c*b[4];a[5]=c*b[5];a[6]=b[6];a[7]=b[7];a[8]=b[8];return a};d.fromMat2d=function(a,b){a[0]=b[0];a[1]=b[1];a[2]=0;a[3]=b[2];a[4]=b[3];a[5]=0;a[6]=b[4];a[7]=b[5];a[8]=1;return a};d.fromQuat= -function(a,b){var c=b[0],d=b[1],e=b[2],n=b[3],l=c+c,x=d+d,u=e+e,c=c*l,g=d*l,d=d*x,h=e*l,j=e*x,e=e*u,l=n*l,x=n*x,n=n*u;a[0]=1-d-e;a[3]=g-n;a[6]=h+x;a[1]=g+n;a[4]=1-c-e;a[7]=j-l;a[2]=h-x;a[5]=j+l;a[8]=1-c-d;return a};d.normalFromMat4=function(a,b){var c=b[0],d=b[1],e=b[2],n=b[3],l=b[4],x=b[5],u=b[6],g=b[7],h=b[8],j=b[9],m=b[10],i=b[11],k=b[12],q=b[13],t=b[14],s=b[15],r=c*x-d*l,z=c*u-e*l,w=c*g-n*l,A=d*u-e*x,E=d*g-n*x,F=e*g-n*u,G=h*q-j*k,H=h*t-m*k,h=h*s-i*k,I=j*t-m*q,j=j*s-i*q,m=m*s-i*t,i=r*m-z*j+w*I+ -A*h-E*H+F*G;if(!i)return null;i=1/i;a[0]=(x*m-u*j+g*I)*i;a[1]=(u*h-l*m-g*H)*i;a[2]=(l*j-x*h+g*G)*i;a[3]=(e*j-d*m-n*I)*i;a[4]=(c*m-e*h+n*H)*i;a[5]=(d*h-c*j-n*G)*i;a[6]=(q*F-t*E+s*A)*i;a[7]=(t*w-k*F-s*z)*i;a[8]=(k*E-q*w+s*r)*i;return a};d.str=function(a){return"mat3("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+")"};d.frob=function(a){return Math.sqrt(Math.pow(a[0],2)+Math.pow(a[1],2)+Math.pow(a[2],2)+Math.pow(a[3],2)+Math.pow(a[4],2)+Math.pow(a[5],2)+Math.pow(a[6], -2)+Math.pow(a[7],2)+Math.pow(a[8],2))};"undefined"!==typeof a&&(a.mat3=d);var r={create:function(){var a=new c(16);a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=0;a[5]=1;a[6]=0;a[7]=0;a[8]=0;a[9]=0;a[10]=1;a[11]=0;a[12]=0;a[13]=0;a[14]=0;a[15]=1;return a},clone:function(a){var b=new c(16);b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=a[12];b[13]=a[13];b[14]=a[14];b[15]=a[15];return b},copy:function(a,b){a[0]=b[0];a[1]=b[1];a[2]= -b[2];a[3]=b[3];a[4]=b[4];a[5]=b[5];a[6]=b[6];a[7]=b[7];a[8]=b[8];a[9]=b[9];a[10]=b[10];a[11]=b[11];a[12]=b[12];a[13]=b[13];a[14]=b[14];a[15]=b[15];return a},identity:function(a){a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=0;a[5]=1;a[6]=0;a[7]=0;a[8]=0;a[9]=0;a[10]=1;a[11]=0;a[12]=0;a[13]=0;a[14]=0;a[15]=1;return a},transpose:function(a,b){if(a===b){var c=b[1],d=b[2],e=b[3],n=b[6],l=b[7],g=b[11];a[1]=b[4];a[2]=b[8];a[3]=b[12];a[4]=c;a[6]=b[9];a[7]=b[13];a[8]=d;a[9]=n;a[11]=b[14];a[12]=e;a[13]=l;a[14]=g}else a[0]= -b[0],a[1]=b[4],a[2]=b[8],a[3]=b[12],a[4]=b[1],a[5]=b[5],a[6]=b[9],a[7]=b[13],a[8]=b[2],a[9]=b[6],a[10]=b[10],a[11]=b[14],a[12]=b[3],a[13]=b[7],a[14]=b[11],a[15]=b[15];return a},invert:function(a,b){var c=b[0],d=b[1],e=b[2],n=b[3],l=b[4],g=b[5],u=b[6],h=b[7],j=b[8],m=b[9],i=b[10],k=b[11],q=b[12],t=b[13],s=b[14],r=b[15],z=c*g-d*l,w=c*u-e*l,B=c*h-n*l,A=d*u-e*g,E=d*h-n*g,F=e*h-n*u,G=j*t-m*q,H=j*s-i*q,I=j*r-k*q,L=m*s-i*t,M=m*r-k*t,O=i*r-k*s,D=z*O-w*M+B*L+A*I-E*H+F*G;if(!D)return null;D=1/D;a[0]=(g*O-u* -M+h*L)*D;a[1]=(e*M-d*O-n*L)*D;a[2]=(t*F-s*E+r*A)*D;a[3]=(i*E-m*F-k*A)*D;a[4]=(u*I-l*O-h*H)*D;a[5]=(c*O-e*I+n*H)*D;a[6]=(s*B-q*F-r*w)*D;a[7]=(j*F-i*B+k*w)*D;a[8]=(l*M-g*I+h*G)*D;a[9]=(d*I-c*M-n*G)*D;a[10]=(q*E-t*B+r*z)*D;a[11]=(m*B-j*E-k*z)*D;a[12]=(g*H-l*L-u*G)*D;a[13]=(c*L-d*H+e*G)*D;a[14]=(t*w-q*A-s*z)*D;a[15]=(j*A-m*w+i*z)*D;return a},adjoint:function(a,b){var c=b[0],d=b[1],e=b[2],n=b[3],l=b[4],g=b[5],h=b[6],j=b[7],m=b[8],i=b[9],k=b[10],q=b[11],t=b[12],s=b[13],r=b[14],z=b[15];a[0]=g*(k*z-q*r)- -i*(h*z-j*r)+s*(h*q-j*k);a[1]=-(d*(k*z-q*r)-i*(e*z-n*r)+s*(e*q-n*k));a[2]=d*(h*z-j*r)-g*(e*z-n*r)+s*(e*j-n*h);a[3]=-(d*(h*q-j*k)-g*(e*q-n*k)+i*(e*j-n*h));a[4]=-(l*(k*z-q*r)-m*(h*z-j*r)+t*(h*q-j*k));a[5]=c*(k*z-q*r)-m*(e*z-n*r)+t*(e*q-n*k);a[6]=-(c*(h*z-j*r)-l*(e*z-n*r)+t*(e*j-n*h));a[7]=c*(h*q-j*k)-l*(e*q-n*k)+m*(e*j-n*h);a[8]=l*(i*z-q*s)-m*(g*z-j*s)+t*(g*q-j*i);a[9]=-(c*(i*z-q*s)-m*(d*z-n*s)+t*(d*q-n*i));a[10]=c*(g*z-j*s)-l*(d*z-n*s)+t*(d*j-n*g);a[11]=-(c*(g*q-j*i)-l*(d*q-n*i)+m*(d*j-n*g));a[12]= --(l*(i*r-k*s)-m*(g*r-h*s)+t*(g*k-h*i));a[13]=c*(i*r-k*s)-m*(d*r-e*s)+t*(d*k-e*i);a[14]=-(c*(g*r-h*s)-l*(d*r-e*s)+t*(d*h-e*g));a[15]=c*(g*k-h*i)-l*(d*k-e*i)+m*(d*h-e*g);return a},determinant:function(a){var b=a[0],c=a[1],d=a[2],e=a[3],n=a[4],l=a[5],g=a[6],h=a[7],j=a[8],i=a[9],m=a[10],k=a[11],q=a[12],s=a[13],t=a[14];a=a[15];return(b*l-c*n)*(m*a-k*t)-(b*g-d*n)*(i*a-k*s)+(b*h-e*n)*(i*t-m*s)+(c*g-d*l)*(j*a-k*q)-(c*h-e*l)*(j*t-m*q)+(d*h-e*g)*(j*s-i*q)},multiply:function(a,b,c){var d=b[0],e=b[1],n=b[2], -l=b[3],g=b[4],h=b[5],j=b[6],i=b[7],m=b[8],k=b[9],q=b[10],s=b[11],t=b[12],r=b[13],z=b[14];b=b[15];var w=c[0],C=c[1],B=c[2],A=c[3];a[0]=w*d+C*g+B*m+A*t;a[1]=w*e+C*h+B*k+A*r;a[2]=w*n+C*j+B*q+A*z;a[3]=w*l+C*i+B*s+A*b;w=c[4];C=c[5];B=c[6];A=c[7];a[4]=w*d+C*g+B*m+A*t;a[5]=w*e+C*h+B*k+A*r;a[6]=w*n+C*j+B*q+A*z;a[7]=w*l+C*i+B*s+A*b;w=c[8];C=c[9];B=c[10];A=c[11];a[8]=w*d+C*g+B*m+A*t;a[9]=w*e+C*h+B*k+A*r;a[10]=w*n+C*j+B*q+A*z;a[11]=w*l+C*i+B*s+A*b;w=c[12];C=c[13];B=c[14];A=c[15];a[12]=w*d+C*g+B*m+A*t;a[13]= -w*e+C*h+B*k+A*r;a[14]=w*n+C*j+B*q+A*z;a[15]=w*l+C*i+B*s+A*b;return a}};r.mul=r.multiply;r.translate=function(a,b,c){var d=c[0],e=c[1];c=c[2];var n,l,g,h,j,i,m,k,q,s,t,r;b===a?(a[12]=b[0]*d+b[4]*e+b[8]*c+b[12],a[13]=b[1]*d+b[5]*e+b[9]*c+b[13],a[14]=b[2]*d+b[6]*e+b[10]*c+b[14],a[15]=b[3]*d+b[7]*e+b[11]*c+b[15]):(n=b[0],l=b[1],g=b[2],h=b[3],j=b[4],i=b[5],m=b[6],k=b[7],q=b[8],s=b[9],t=b[10],r=b[11],a[0]=n,a[1]=l,a[2]=g,a[3]=h,a[4]=j,a[5]=i,a[6]=m,a[7]=k,a[8]=q,a[9]=s,a[10]=t,a[11]=r,a[12]=n*d+j*e+q*c+ -b[12],a[13]=l*d+i*e+s*c+b[13],a[14]=g*d+m*e+t*c+b[14],a[15]=h*d+k*e+r*c+b[15]);return a};r.scale=function(a,b,c){var d=c[0],e=c[1];c=c[2];a[0]=b[0]*d;a[1]=b[1]*d;a[2]=b[2]*d;a[3]=b[3]*d;a[4]=b[4]*e;a[5]=b[5]*e;a[6]=b[6]*e;a[7]=b[7]*e;a[8]=b[8]*c;a[9]=b[9]*c;a[10]=b[10]*c;a[11]=b[11]*c;a[12]=b[12];a[13]=b[13];a[14]=b[14];a[15]=b[15];return a};r.rotate=function(a,c,d,e){var g=e[0],n=e[1];e=e[2];var l=Math.sqrt(g*g+n*n+e*e),h,j,i,m,k,q,s,t,r,z,w,Q,C,B,A,E,F,G,H,I;if(Math.abs(l)<b)return null;l=1/l;g*= -l;n*=l;e*=l;h=Math.sin(d);j=Math.cos(d);i=1-j;d=c[0];l=c[1];m=c[2];k=c[3];q=c[4];s=c[5];t=c[6];r=c[7];z=c[8];w=c[9];Q=c[10];C=c[11];B=g*g*i+j;A=n*g*i+e*h;E=e*g*i-n*h;F=g*n*i-e*h;G=n*n*i+j;H=e*n*i+g*h;I=g*e*i+n*h;g=n*e*i-g*h;n=e*e*i+j;a[0]=d*B+q*A+z*E;a[1]=l*B+s*A+w*E;a[2]=m*B+t*A+Q*E;a[3]=k*B+r*A+C*E;a[4]=d*F+q*G+z*H;a[5]=l*F+s*G+w*H;a[6]=m*F+t*G+Q*H;a[7]=k*F+r*G+C*H;a[8]=d*I+q*g+z*n;a[9]=l*I+s*g+w*n;a[10]=m*I+t*g+Q*n;a[11]=k*I+r*g+C*n;c!==a&&(a[12]=c[12],a[13]=c[13],a[14]=c[14],a[15]=c[15]);return a}; -r.rotateX=function(a,b,c){var d=Math.sin(c);c=Math.cos(c);var e=b[4],g=b[5],l=b[6],h=b[7],j=b[8],i=b[9],m=b[10],k=b[11];b!==a&&(a[0]=b[0],a[1]=b[1],a[2]=b[2],a[3]=b[3],a[12]=b[12],a[13]=b[13],a[14]=b[14],a[15]=b[15]);a[4]=e*c+j*d;a[5]=g*c+i*d;a[6]=l*c+m*d;a[7]=h*c+k*d;a[8]=j*c-e*d;a[9]=i*c-g*d;a[10]=m*c-l*d;a[11]=k*c-h*d;return a};r.rotateY=function(a,b,c){var d=Math.sin(c);c=Math.cos(c);var e=b[0],g=b[1],l=b[2],h=b[3],j=b[8],i=b[9],m=b[10],k=b[11];b!==a&&(a[4]=b[4],a[5]=b[5],a[6]=b[6],a[7]=b[7], -a[12]=b[12],a[13]=b[13],a[14]=b[14],a[15]=b[15]);a[0]=e*c-j*d;a[1]=g*c-i*d;a[2]=l*c-m*d;a[3]=h*c-k*d;a[8]=e*d+j*c;a[9]=g*d+i*c;a[10]=l*d+m*c;a[11]=h*d+k*c;return a};r.rotateZ=function(a,b,c){var d=Math.sin(c);c=Math.cos(c);var e=b[0],g=b[1],l=b[2],h=b[3],j=b[4],i=b[5],m=b[6],k=b[7];b!==a&&(a[8]=b[8],a[9]=b[9],a[10]=b[10],a[11]=b[11],a[12]=b[12],a[13]=b[13],a[14]=b[14],a[15]=b[15]);a[0]=e*c+j*d;a[1]=g*c+i*d;a[2]=l*c+m*d;a[3]=h*c+k*d;a[4]=j*c-e*d;a[5]=i*c-g*d;a[6]=m*c-l*d;a[7]=k*c-h*d;return a};r.fromRotationTranslation= -function(a,b,c){var d=b[0],e=b[1],g=b[2],h=b[3],j=d+d,i=e+e,m=g+g;b=d*j;var k=d*i,d=d*m,q=e*i,e=e*m,g=g*m,j=h*j,i=h*i,h=h*m;a[0]=1-(q+g);a[1]=k+h;a[2]=d-i;a[3]=0;a[4]=k-h;a[5]=1-(b+g);a[6]=e+j;a[7]=0;a[8]=d+i;a[9]=e-j;a[10]=1-(b+q);a[11]=0;a[12]=c[0];a[13]=c[1];a[14]=c[2];a[15]=1;return a};r.fromQuat=function(a,b){var c=b[0],d=b[1],e=b[2],g=b[3],h=c+c,j=d+d,i=e+e,c=c*h,m=d*h,d=d*j,k=e*h,q=e*j,e=e*i,h=g*h,j=g*j,g=g*i;a[0]=1-d-e;a[1]=m+g;a[2]=k-j;a[3]=0;a[4]=m-g;a[5]=1-c-e;a[6]=q+h;a[7]=0;a[8]=k+j; -a[9]=q-h;a[10]=1-c-d;a[11]=0;a[12]=0;a[13]=0;a[14]=0;a[15]=1;return a};r.frustum=function(a,b,c,d,e,g,h){var j=1/(c-b),i=1/(e-d),m=1/(g-h);a[0]=2*g*j;a[1]=0;a[2]=0;a[3]=0;a[4]=0;a[5]=2*g*i;a[6]=0;a[7]=0;a[8]=(c+b)*j;a[9]=(e+d)*i;a[10]=(h+g)*m;a[11]=-1;a[12]=0;a[13]=0;a[14]=2*(h*g)*m;a[15]=0;return a};r.perspective=function(a,b,c,d,e){b=1/Math.tan(b/2);var g=1/(d-e);a[0]=b/c;a[1]=0;a[2]=0;a[3]=0;a[4]=0;a[5]=b;a[6]=0;a[7]=0;a[8]=0;a[9]=0;a[10]=(e+d)*g;a[11]=-1;a[12]=0;a[13]=0;a[14]=2*e*d*g;a[15]=0; -return a};r.ortho=function(a,b,c,d,e,g,h){var j=1/(b-c),i=1/(d-e),m=1/(g-h);a[0]=-2*j;a[1]=0;a[2]=0;a[3]=0;a[4]=0;a[5]=-2*i;a[6]=0;a[7]=0;a[8]=0;a[9]=0;a[10]=2*m;a[11]=0;a[12]=(b+c)*j;a[13]=(e+d)*i;a[14]=(h+g)*m;a[15]=1;return a};r.lookAt=function(a,c,d,e){var g,h,j,i,m,k,q,s,t=c[0],z=c[1];c=c[2];j=e[0];i=e[1];h=e[2];q=d[0];e=d[1];g=d[2];if(Math.abs(t-q)<b&&Math.abs(z-e)<b&&Math.abs(c-g)<b)return r.identity(a);d=t-q;e=z-e;q=c-g;s=1/Math.sqrt(d*d+e*e+q*q);d*=s;e*=s;q*=s;g=i*q-h*e;h=h*d-j*q;j=j*e-i* -d;(s=Math.sqrt(g*g+h*h+j*j))?(s=1/s,g*=s,h*=s,j*=s):j=h=g=0;i=e*j-q*h;m=q*g-d*j;k=d*h-e*g;(s=Math.sqrt(i*i+m*m+k*k))?(s=1/s,i*=s,m*=s,k*=s):k=m=i=0;a[0]=g;a[1]=i;a[2]=d;a[3]=0;a[4]=h;a[5]=m;a[6]=e;a[7]=0;a[8]=j;a[9]=k;a[10]=q;a[11]=0;a[12]=-(g*t+h*z+j*c);a[13]=-(i*t+m*z+k*c);a[14]=-(d*t+e*z+q*c);a[15]=1;return a};r.str=function(a){return"mat4("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+", "+a[9]+", "+a[10]+", "+a[11]+", "+a[12]+", "+a[13]+", "+a[14]+", "+ -a[15]+")"};r.frob=function(a){return Math.sqrt(Math.pow(a[0],2)+Math.pow(a[1],2)+Math.pow(a[2],2)+Math.pow(a[3],2)+Math.pow(a[4],2)+Math.pow(a[5],2)+Math.pow(a[6],2)+Math.pow(a[7],2)+Math.pow(a[8],2)+Math.pow(a[9],2)+Math.pow(a[10],2)+Math.pow(a[11],2)+Math.pow(a[12],2)+Math.pow(a[13],2)+Math.pow(a[14],2)+Math.pow(a[15],2))};"undefined"!==typeof a&&(a.mat4=r);var m={create:function(){var a=new c(4);a[0]=0;a[1]=0;a[2]=0;a[3]=1;return a}},q=g.create(),s=g.fromValues(1,0,0),t=g.fromValues(0,1,0);m.rotationTo= -function(a,b,c){var d=g.dot(b,c);if(-0.999999>d)return g.cross(q,s,b),1E-6>g.length(q)&&g.cross(q,t,b),g.normalize(q,q),m.setAxisAngle(a,q,Math.PI),a;if(0.999999<d)return a[0]=0,a[1]=0,a[2]=0,a[3]=1,a;g.cross(q,b,c);a[0]=q[0];a[1]=q[1];a[2]=q[2];a[3]=1+d;return m.normalize(a,a)};var z=d.create();m.setAxes=function(a,b,c,d){z[0]=c[0];z[3]=c[1];z[6]=c[2];z[1]=d[0];z[4]=d[1];z[7]=d[2];z[2]=-b[0];z[5]=-b[1];z[8]=-b[2];return m.normalize(a,m.fromMat3(a,z))};m.clone=i.clone;m.fromValues=i.fromValues;m.copy= -i.copy;m.set=i.set;m.identity=function(a){a[0]=0;a[1]=0;a[2]=0;a[3]=1;return a};m.setAxisAngle=function(a,b,c){c*=0.5;var d=Math.sin(c);a[0]=d*b[0];a[1]=d*b[1];a[2]=d*b[2];a[3]=Math.cos(c);return a};m.add=i.add;m.multiply=function(a,b,c){var d=b[0],e=b[1],g=b[2];b=b[3];var h=c[0],j=c[1],i=c[2];c=c[3];a[0]=d*c+b*h+e*i-g*j;a[1]=e*c+b*j+g*h-d*i;a[2]=g*c+b*i+d*j-e*h;a[3]=b*c-d*h-e*j-g*i;return a};m.mul=m.multiply;m.scale=i.scale;m.rotateX=function(a,b,c){c*=0.5;var d=b[0],e=b[1],g=b[2];b=b[3];var h=Math.sin(c); -c=Math.cos(c);a[0]=d*c+b*h;a[1]=e*c+g*h;a[2]=g*c-e*h;a[3]=b*c-d*h;return a};m.rotateY=function(a,b,c){c*=0.5;var d=b[0],e=b[1],g=b[2];b=b[3];var h=Math.sin(c);c=Math.cos(c);a[0]=d*c-g*h;a[1]=e*c+b*h;a[2]=g*c+d*h;a[3]=b*c-e*h;return a};m.rotateZ=function(a,b,c){c*=0.5;var d=b[0],e=b[1],g=b[2];b=b[3];var h=Math.sin(c);c=Math.cos(c);a[0]=d*c+e*h;a[1]=e*c-d*h;a[2]=g*c+b*h;a[3]=b*c-g*h;return a};m.calculateW=function(a,b){var c=b[0],d=b[1],e=b[2];a[0]=c;a[1]=d;a[2]=e;a[3]=Math.sqrt(Math.abs(1-c*c-d*d- -e*e));return a};m.dot=i.dot;m.lerp=i.lerp;m.slerp=function(a,b,c,d){var e=b[0],g=b[1],h=b[2];b=b[3];var j=c[0],i=c[1],m=c[2];c=c[3];var k,q,s;q=e*j+g*i+h*m+b*c;0>q&&(q=-q,j=-j,i=-i,m=-m,c=-c);1E-6<1-q?(k=Math.acos(q),s=Math.sin(k),q=Math.sin((1-d)*k)/s,d=Math.sin(d*k)/s):q=1-d;a[0]=q*e+d*j;a[1]=q*g+d*i;a[2]=q*h+d*m;a[3]=q*b+d*c;return a};m.invert=function(a,b){var c=b[0],d=b[1],e=b[2],g=b[3],h=c*c+d*d+e*e+g*g,h=h?1/h:0;a[0]=-c*h;a[1]=-d*h;a[2]=-e*h;a[3]=g*h;return a};m.conjugate=function(a,b){a[0]= --b[0];a[1]=-b[1];a[2]=-b[2];a[3]=b[3];return a};m.length=i.length;m.len=m.length;m.squaredLength=i.squaredLength;m.sqrLen=m.squaredLength;m.normalize=i.normalize;m.fromMat3=function(a,b){var c=b[0]+b[4]+b[8];if(0<c)c=Math.sqrt(c+1),a[3]=0.5*c,c=0.5/c,a[0]=(b[5]-b[7])*c,a[1]=(b[6]-b[2])*c,a[2]=(b[1]-b[3])*c;else{var d=0;b[4]>b[0]&&(d=1);b[8]>b[3*d+d]&&(d=2);var e=(d+1)%3,g=(d+2)%3,c=Math.sqrt(b[3*d+d]-b[3*e+e]-b[3*g+g]+1);a[d]=0.5*c;c=0.5/c;a[3]=(b[3*e+g]-b[3*g+e])*c;a[e]=(b[3*e+d]+b[3*d+e])*c;a[g]= -(b[3*g+d]+b[3*d+g])*c}return a};m.str=function(a){return"quat("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+")"};"undefined"!==typeof a&&(a.quat=m)})(GLMAT);try{module.exports=GLMAT}catch(e$$10){}try{glm.exists&&alert("glm.common.js loaded over exist glm instance: "+glm)}catch(e$$11){}glm=null;GLMJS_PREFIX="glm-js: "; -GLM={$DEBUG:"undefined"!==typeof $GLM_DEBUG&&$GLM_DEBUG,version:"0.0.6b",GLM_VERSION:96,$outer:{polyfills:GLM_polyfills(),functions:{},intern:function(a,b){if(a)if(void 0===b&&"object"===typeof a)for(var c in a)GLM.$outer.intern(c,a[c]);else return GLM.$DEBUG&&GLM.$outer.console.debug("intern "+a,b&&(b.name||typeof b)),GLM.$outer[a]=b},$import:function(a){GLM.$outer.$import=function(){throw Error("glm.$outer.$import already called...");};GLM.$outer.intern(a.statics);GLM.$template.extend(GLM,GLM.$template["declare<T,V,number>"](a["declare<T,V,number>"]), -GLM.$template["declare<T,V,...>"](a["declare<T,V,...>"]),GLM.$template["declare<T,...>"](a["declare<T,...>"]),GLM.$template["declare<T>"](a["declare<T>"]));GLM.$init(a)},console:$GLM_reset_logging(),quat_array_from_xyz:function(a){var b=glm.quat(),c=glm.mat3(1);b["*="](glm.angleAxis(a.x,c[0]));b["*="](glm.angleAxis(a.y,c[1]));b["*="](glm.angleAxis(a.z,c[2]));return b.elements},Array:Array,ArrayBuffer:ArrayBuffer,Float32Array:Float32Array,Float64Array:Float64Array,Uint8Array:Uint8Array,Uint16Array:Uint16Array, -Uint32Array:Uint32Array,Int8Array:Int8Array,Int16Array:Int16Array,Int32Array:Int32Array,DataView:"undefined"!==typeof DataView&&DataView,$rebindTypedArrays:function(a){var b=Object.keys(GLM.$outer).filter(RegExp.prototype.test.bind(/.Array$|^ArrayBuffer$|^DataView$/)).map(function(b){var e=a.call(this,b,GLM.$outer[b]);e!==GLM.$outer[b]&&(GLM.$outer.console.warn("$rebindTypedArrays("+b+")... replacing"),GLM.$outer[b]=e);return e});GLM.$subarray=GLM.patch_subarray();return b}},$extern:$GLM_extern,$log:$GLM_log, -GLMJSError:$GLM_GLMJSError("GLMJSError"),_radians:function(a){return a*this.PI/180}.bind(Math),_degrees:function(a){return 180*a/this.PI}.bind(Math),normalize:$GLM_extern("normalize"),inverse:$GLM_extern("inverse"),distance:$GLM_extern("distance"),length:$GLM_extern("length"),length2:$GLM_extern("length2"),transpose:$GLM_extern("transpose"),slerp:$GLM_extern("slerp"),mix:$GLM_extern("mix"),clamp:$GLM_extern("clamp"),angleAxis:$GLM_extern("angleAxis"),rotate:$GLM_extern("rotate"),scale:$GLM_extern("scale"), -translate:$GLM_extern("translate"),lookAt:$GLM_extern("lookAt"),cross:$GLM_extern("cross"),dot:$GLM_extern("dot"),perspective:function(a,b,c,e){return GLM.$outer.mat4_perspective(a,b,c,e)},ortho:function(a,b,c,e,d,h){return GLM.$outer.mat4_ortho(a,b,c,e,d,h)},_eulerAngles:function(a){return GLM.$outer.vec3_eulerAngles(a)},angle:function(a){return 2*Math.acos(a.w)},axis:function(a){var b=1-a.w*a.w;if(0>=b)return glm.vec3(0,0,1);b=1/Math.sqrt(b);return glm.vec3(a.x*b,a.y*b,a.z*b)},$from_ptr:function(a, -b,c){if(this!==GLM)throw new GLM.GLMJSError("... use glm.make_<type>() (not new glm.make<type>())");b=new GLM.$outer.Float32Array(b.buffer||b,c||0,a.componentLength);b=new GLM.$outer.Float32Array(b);return new a(b)},make_vec2:function(a,b){return GLM.$from_ptr.call(this,GLM.vec2,a,2===arguments.length?b:a.byteOffset)},make_vec3:function(a,b){return GLM.$from_ptr.call(this,GLM.vec3,a,2===arguments.length?b:a.byteOffset)},make_vec4:function(a,b){return GLM.$from_ptr.call(this,GLM.vec4,a,2===arguments.length? -b:a.byteOffset)},make_quat:function(a,b){return GLM.$from_ptr.call(this,GLM.quat,a,2===arguments.length?b:a.byteOffset)},make_mat3:function(a,b){return GLM.$from_ptr.call(this,GLM.mat3,a,2===arguments.length?b:a.byteOffset)},make_mat4:function(a,b){return GLM.$from_ptr.call(this,GLM.mat4,a,2===arguments.length?b:a.byteOffset)},diagonal4x4:function(a){if("vec4"!==GLM.$typeof(a))throw new GLM.GLMJSError("unsupported argtype to GLM.diagonal4x4: "+["type:"+GLM.$typeof(a)]);a=a.elements;return new GLM.mat4([a[0], -0,0,0,0,a[1],0,0,0,0,a[2],0,0,0,0,a[3]])},diagonal3x3:function(a){if("vec3"!==GLM.$typeof(a))throw new GLM.GLMJSError("unsupported argtype to GLM.diagonal3x3: "+["type:"+GLM.$typeof(a)]);a=a.elements;return new GLM.mat3([a[0],0,0,0,a[1],0,0,0,a[2]])},_toMat4:function(a){return new GLM.mat4(GLM.$outer.mat4_array_from_quat(a))},FAITHFUL:!0,to_string:function(a,b){try{var c=a.$type||typeof a;if(!GLM[c])throw new GLM.GLMJSError("unsupported argtype to GLM.to_string: "+["type:"+c,a]);return GLM.FAITHFUL? -GLM.$to_string(a,b).replace(/[\t\n]/g,""):GLM.$to_string(a,b)}catch(e){return GLM.$DEBUG&&GLM.$outer.console.error("to_string error: ",c,a+"",e),e+""}},$sizeof:function(a){return a.BYTES_PER_ELEMENT},$types:[],$isGLMConstructor:function(a){return!!(a&&a.prototype instanceof GLM.$GLMBaseType)},$getGLMType:function(a){return a instanceof GLM.$GLMBaseType&&a.constructor||"string"===typeof a&&GLM[a]},$isGLMObject:function(a){return!!(a instanceof GLM.$GLMBaseType&&a.$type)},$typeof:function(a){return a instanceof -GLM.$GLMBaseType?a.$type:"undefined"},$to_array:function(a){return[].slice.call(a.elements)},$to_json:function(a,b,c){this instanceof GLM.$GLMBaseType&&(c=b,b=a,a=this);return JSON.stringify(GLM.$to_object(a),b,c)},$inspect:function(a){this instanceof GLM.$GLMBaseType&&(a=this);return GLM.$to_json(a,null,2)},_clamp:function(a,b,c){return a<b?b:a>c?c:a},_abs:function(a){return Math.abs(a)},_equal:function(a,b){return a===b},_epsilonEqual:function(a,b,c){return Math.abs(a-b)<c},_fract:function(a){return a- -Math.floor(a)},_frexp:function(){function a(b,c){var e=GLM.$outer.DataView||a._DataView;if(0==b)return c&&Array.isArray(c)?c[0]=c[1]=0:[0,0];e=new e(new GLM.$outer.ArrayBuffer(8));e.setFloat64(0,b);var d=e.getUint32(0)>>>20&2047;0===d&&(e.setFloat64(0,b*Math.pow(2,64)),d=(e.getUint32(0)>>>20&2047)-64);e=d-1022;d=GLM.ldexp(b,-e);return c&&Array.isArray(c)?(c[0]=e,c[1]=d):[d,e]}a._DataView=function(a){this.buffer=a;this.setFloat64=function(a,b){if(0!==a)throw Error("...this is a very limited DataView emulator"); -(new Uint8Array(this.buffer)).set([].reverse.call(new Uint8Array((new Float64Array([b])).buffer)),a)};this.getUint32=function(a){if(0!==a)throw Error("...this is a very limited DataView emulator");return(new Uint32Array((new Uint8Array([].slice.call(new Uint8Array(this.buffer)).reverse())).buffer))[1]}};return a}(),_ldexp:function(a,b){return 1023<b?a*Math.pow(2,1023)*Math.pow(2,b-1023):-1074>b?a*Math.pow(2,-1074)*Math.pow(2,b+1074):a*Math.pow(2,b)},_max:Math.max,_min:Math.min,sqrt:Math.sqrt,__sign:function(a){return 0< -a?1:0>a?-1:+a},$constants:{epsilon:1E-6,euler:0.5772156649015329,e:Math.E,ln_ten:Math.LN10,ln_two:Math.LN2,pi:Math.PI,half_pi:Math.PI/2,quarter_pi:Math.PI/4,one_over_pi:1/Math.PI,two_over_pi:2/Math.PI,root_pi:Math.sqrt(Math.PI),root_two:Math.sqrt(2),root_three:Math.sqrt(3),two_over_root_pi:2/Math.sqrt(Math.PI),one_over_root_two:Math.SQRT1_2,root_two:Math.SQRT2},FIXEDPRECISION:6,$toFixedString:function(a,b,c,e){void 0===e&&(e=GLM.FIXEDPRECISION);if(!c||!c.map)throw Error("unsupported argtype to $toFixedString(..,..,props="+ -typeof c+")");try{var d="";c.map(function(c){c=b[d=c];if(!c.toFixed)throw Error("!toFixed in w"+[c,a,JSON.stringify(b)]);return c.toFixed(0)})}catch(h){throw GLM.$DEBUG&&GLM.$outer.console.error("$toFixedString error",a,typeof b,Object.prototype.toString.call(b),d),GLM.$DEBUG&&glm.$log("$toFixedString error",a,typeof b,Object.prototype.toString.call(b),d),new GLM.GLMJSError(h);}c=c.map(function(a){return b[a].toFixed(e)});return a+"("+c.join(", ")+")"}};GLM._sign=Math.sign||GLM.__sign; -for(var p in GLM.$constants)(function(a,b){GLM[b]=function(){return a};GLM[b].valueOf=GLM[b]})(GLM.$constants[p],p); -GLM.$GLMBaseType=function(){function a(a,c){var e=a.$||{};this.$type=c;this.$type_name=e.name||"<"+c+">";e.components&&(this.$components=e.components[0]);this.$len=this.components=a.componentLength;this.constructor=a;this.byteLength=a.BYTES_PER_ELEMENT;GLM.$types.push(c)}a.prototype={clone:function(){return new this.constructor(new this.elements.constructor(this.elements))},toString:function(){return GLM.$to_string(this)},inspect:function(){return GLM.$inspect(this)},toJSON:function(){return GLM.$to_object(this)}}; -Object.defineProperty(a.prototype,"address",{get:function(){var a=this.elements.byteOffset.toString(16);return"0x00000000".substr(0,10-a.length)+a}});return a}(); -(function(){function a(a,b,c){return a.subarray(b,c||a.length)}function b(a,b,c){var e=a.constructor;c=c||a.length;return new e(a.buffer,a.byteOffset+b*e.BYTES_PER_ELEMENT,c-b)}function c(){var a=new GLM.$outer.Float32Array([0,0]);a.subarray(1).subarray(0)[0]=1;var b=c.result=[a[1],(new GLM.$outer.Float32Array(16)).subarray(12,16).length];return!(a[1]!==b[0]||4!==b[1])}function e(a){var b=new GLM.$outer.Float32Array([0,0]);a(a(b,1),0)[0]=1;a=e.result=[b[1],a(new GLM.$outer.Float32Array(16),12,16).length]; -return!(b[1]!==a[0]||4!==a[1])}Object.defineProperty(GLM,"patch_subarray",{configurable:!0,value:function(){var d=!c()?b:a;d.workaround_broken_spidermonkey_subarray=b;d.native_subarray=a;if(!e(d))throw Error("failed to resolve working TypedArray.subarray implementation... "+e.result);return d}})})();GLM.$subarray=GLM.patch_subarray(); -var GLM_template=GLM.$template={_genArgError:function(a,b,c,e){~e.indexOf(void 0)&&(e=e.slice(0,e.indexOf(void 0)));var d=RegExp.prototype.test.bind(/^[^$_]/);return new GLM.GLMJSError("unsupported argtype to "+b+" "+a.$sig+": [typ="+c+"] :: got arg types: "+e.map(GLM.$template.jstypes.get)+" // supported types: "+Object.keys(a).filter(d).join("||"))},jstypes:{get:function(a){return null===a?"null":void 0===a?"undefined":a.$type||GLM.$template.jstypes[typeof a]||GLM.$template.jstypes[a+""]||function(a){if("object"=== -typeof a){if(a instanceof GLM.$outer.Float32Array)return"Float32Array";if(a instanceof GLM.$outer.ArrayBuffer)return"ArrayBuffer";if(Array.isArray(a))return"array"}return"<unknown "+[typeof a,a]+">"}(a)},"0":"float","boolean":"bool",number:"float",string:"string","[object Float32Array]":"Float32Array","[object ArrayBuffer]":"ArrayBuffer","function":"function"},_add_overrides:function(a,b){for(var c in b)b[c]&&GLM[c].override(a,b[c])},_add_inline_override:function(a,b,c){this[b]=eval(GLM.$template._traceable("glm_"+ -a+"_"+b,c))();return this},_inline_helpers:function(a,b){Object.defineProperty(a,"GLM",{value:GLM});return{$type:"built-in",$type_name:b,$template:a,F:a,dbg:b,override:this._add_inline_override.bind(a,b),link:function(c){var e=a[c];e||(e=a[[c,"undefined"]]);if(!e)throw new GLM.GLMJSError("error linking direct function for "+b+"<"+c+"> or "+b+"<"+[c,void 0]+">");return/\bthis[\[.]/.test(e+"")?e.bind(a):e}}},"template<T>":function(a,b){a.$sig="template<T>";var c=GLM.$template.jstypes,e=GLM.$template._genArgError, -d=GLM.$GLMBaseType;return this.slingshot(this._inline_helpers(a,b),eval(this._traceable("Tglm_"+b,function(b){this instanceof d&&(b=this);var j=[b&&b.$type||c[typeof b]||c.get(b)||"null"];if(!a[j])throw e(a,arguments.callee.dbg,j,[b]);return a[j](b)}))())},"template<T,...>":function(a,b){a.$sig="template<T,...>";var c=GLM.$template.jstypes,e=GLM.$template._genArgError,d=GLM.$GLMBaseType;return this.slingshot(this._inline_helpers(a,b),eval(this._traceable("Tdotglm_"+b,function(b){for(var j=Array(arguments.length), -g=0;g<j.length;g++)j[g]=arguments[g];this instanceof d&&j.unshift(b=this);g=[b&&b.$type||c[typeof b]||c.get(b)||"null"];if(!a[g])throw e(a,arguments.callee.dbg,g,j);return a[g].apply(a,j)}))())},"template<T,V,number>":function(a,b){a.$sig="template<T,V,number>";var c=GLM.$template.jstypes,e=GLM.$template._genArgError,d=GLM.GLMJSError,h=GLM.$GLMBaseType;return this.slingshot(this._inline_helpers(a,b),eval(this._traceable("TVnglm_"+b,function(){for(var b=Array(arguments.length),g=0;g<b.length;g++)b[g]= -arguments[g];this instanceof h&&b.unshift(this);var g=b[0],k=b[1],b=b[2],i=[g&&g.$type||c[typeof g]||c[g+""]||"<unknown "+g+">",k&&k.$type||c[typeof k]||c[k+""]||"<unknown "+k+">"];if(!a[i])throw e(a,arguments.callee.dbg,i,[g,k,b]);if("number"!==typeof b)throw new d(arguments.callee.dbg+a.$sig+": unsupported n type: "+[typeof b,b]);return a[i](g,k,b)}))())},"template<T,V,...>":function(a,b){a.$sig="template<T,V,...>";var c=GLM.$template.jstypes,e=GLM.$GLMBaseType,d=GLM.$template._genArgError,h=GLM.$outer.Array; -return this.slingshot(this._inline_helpers(a,b),eval(this._traceable("TVglm_"+b,function(){for(var b=new h(arguments.length),g=0;g<b.length;g++)b[g]=arguments[g];this instanceof e&&b.unshift(this);var g=b[0],k=b[1],g=[g&&g.$type||c[typeof g],k&&k.$type||c[typeof k]||c[k+""]||h.isArray(k)&&"array"+k.length+""||""+k+""];if(!a[g])throw d(a,arguments.callee.dbg,g,b);return a[g].apply(a,b)}))())},override:function(a,b,c,e,d){function h(a,c){GLM.$outer.console.debug("glm.$template.override: "+b+" ... "+ -Object.keys(a.$template).filter(function(a){return!~a.indexOf("$")}).map(function(a){return!~c.indexOf(a)?"*"+a+"*":a}).join(" | "))}GLM.$DEBUG&&GLM.$outer.console.debug("glm.$template.override: ",a,b,c.$op?'$op: ["'+c.$op+'"]':"");if(!e)throw Error("unspecified target group "+e+' (expected override(<TV>, "p", {TSP}, ret={GROUP}))');var j=e[b];if(j&&j.$op!==c.$op)throw Error('glm.$template.override: mismatch merging existing override: .$op "'+[j.$op,"!=",c.$op].join(" ")+'" p='+[b,j.$op,c.$op,"||"+ -Object.keys(j.$template).join("||")]);var g=GLM.$template[a](GLM.$template.deNify(c,b),b);if(j&&j.F.$sig!==g.F.$sig)throw Error('glm.$template.override: mismatch merging existing override: .$sig "'+[j&&j.F.$sig,"!=",g.F.$sig].join(" ")+'" p='+[b,j&&j.F.$sig,g.F.$sig,"||"+Object.keys(j&&j.$template||{}).join("||")]);g.$op=c.$op;if(j){for(var k in g.$template)"$op"===k||"$sig"===k||(a=k in j.$template,!a||!0===d?(GLM.$DEBUG&&GLM.$outer.console.debug("glm.$template.override: "+b+" ... "+k+" merged"), -j.$template[k]=g.$template[k]):a&&GLM.$DEBUG&&GLM.$outer.console.debug("glm.$template.override: "+b+" ... "+k+" skipped"));if(GLM.$DEBUG){var i=[];Object.keys(j.$template).forEach(function(a){a in g.$template||(GLM.$DEBUG&&GLM.$outer.console.debug("glm.$template.override: "+b+" ... "+a+" carried-forward"),i.push(a))});h(e[b],i)}}else e[b]=g,GLM.$DEBUG&&h(e[b],[]);return e},_override:function(a,b,c){for(var e in b){if("mat4_scale"!==e&&"object"!==typeof b[e])throw new GLM.GLMJSError("expect object property overrides"+ -[e,b[e],Object.keys(c)]);"object"===typeof b[e]?this.override(a,e,b[e],c,!0):ret_scale=5}return c},slingshot:function(){return this.extend.apply(this,[].reverse.call(arguments))},extend:function(a,b){[].slice.call(arguments,1).forEach(function(b){if(b)for(var e in b)b.hasOwnProperty(e)&&(a[e]=b[e])});return a},"declare<T,V,...>":function(a){return!a?{}:this._override("template<T,V,...>",a,GLM.$outer.functions)},"declare<T>":function(a){return!a?{}:this._override("template<T>",a,GLM.$outer.functions)}, -"declare<T,...>":function(a){return!a?{}:this._override("template<T,...>",a,GLM.$outer.functions)},"declare<T,V,number>":function(a){return!a?{}:this._override("template<T,V,number>",a,GLM.$outer.functions)},_tojsname:function(a){return(a||"_").replace(/[^$a-zA-Z0-9_]/g,"_")},_traceable:function(a,b){var c=b;if("function"!==typeof c)throw new GLM.GLMJSError("_traceable expects tidy function as second arg "+c);if(!a)throw new GLM.GLMJSError("_traceable expects hint or what's the point"+[c,a]);a=this._tojsname(a|| -"_traceable");c=c.toString().replace(/^(\s*var\s*(\w+)\s*=\s*)__VA_ARGS__;/mg,function(a,b,c){return b+"new Array(arguments.length);for(var I=0;I<varname.length;I++)varname[I]=arguments[I];".replace(/I/g,"__VA_ARGS__I").replace(/varname/g,c)}).replace(/\barguments[.]callee\b/g,a);if(/^function _traceable/.test(c))throw new GLM.GLMJSError("already wrapped in a _traceable: "+[c,a]);c='function _traceable(){ "use strict"; SRC; return HINT; }'.replace("HINT",a.replace(/[$]/g,"$$$$")).replace("SRC",c.replace(/[$]/g, -"$$$$").replace(/^function\s*\(/,"function "+a+"("));c="1,"+c;if(GLM.$DEBUG)try{eval(c)}catch(e){throw console.error("_traceable error",a,c,b,e),e;}return c},deNify:function(a,b){var c={vec:[2,3,4],mat:[3,4]},e=this._tojsname.bind(this),d;for(d in a){var h=!1;d.replace(/([vV]ec|[mM]at)(?:\w*)<N>/,function(j,g){h=!0;var k=a[d];delete a[d];c[g.toLowerCase()].forEach(function(c){var g=d.replace(/<N[*]N>/g,c*c).replace(/<N>/g,c);if(!(g in a)){var h=e("glm_"+b+"_"+g);a[g]=eval("'use strict'; 1,"+(k+"").replace(/^function\s*\(/, -"function "+h+"(").replace(/N[*]N/g,c*c).replace(/N/g,c))}})}.bind(this));/^[$]/.test(d)?GLM.$DEBUG&&GLM.$outer.console.debug("@ NOT naming "+d):!h&&("function"===typeof a[d]&&!a[d].name)&&(GLM.$DEBUG&&GLM.$outer.console.debug("naming "+e(b+"_"+d)),a[d]=eval(this._traceable("glm_"+b+"_"+d,a[d]))())}return a},$_module_stamp:+new Date,_iso:"/[*][^/*]*[*]/",_get_argnames:function(a){return(a+"").replace(/\s+/g,"").replace(RegExp(this._iso,"g"),"").split("){",1)[0].replace(/^[^(]*[(]/,"").replace(/=[^,]+/g, -"").split(",").filter(Boolean)},_fix_$_names:function(a,b){Object.keys(b).filter(function(a){return"function"===typeof b[a]&&!b[a].name}).map(function(c){var e=a+"_"+c;GLM.$DEBUG&&GLM.$outer.console.debug("naming $."+c+" == "+e,this._traceable(e,b[c]));b[c]=eval(this._traceable("glm_"+e,b[c]))()}.bind(this));return b},_typedArrayMaker:function(a,b){return function(c){if(c.length===a)return new b(c);var e=new b(a);e.set(c);return e}},GLMType:function(a,b){var c=this._fix_$_names(a,b),e=c.identity.length, -d,h=Object,j=GLM.$template._get_argnames.bind(GLM.$template),g=GLM.GLMJSError,k={},i;for(i in c)"function"===typeof c[i]&&function(a){k[i]=function(b){return a.apply(c,b)}}(c[i]);d=function(b){var d=k[typeof b[0]+b.length];if(!d){var e="glm."+a;b=e+"("+b.map(function(a){return typeof a})+")";d=h.keys(c).filter(function(a){return"function"===typeof c[a]&&/^\w+\d+$/.test(a)}).map(function(a){return e+"("+j(c[a])+")"});throw new g("no constructor found for: "+b+"\nsupported signatures:\n\t"+d.join("\n\t")); -}return d};var w,r=GLM;GLM.$template._get_argnames.bind(GLM.$template);w=function(b,c){2<r.$DEBUG&&r.$outer.console.info("adopting elements...",typeof b);if(b.length!=e){if(!1===c)return c;r.$outer.console.error(a+" elements size mismatch: "+["wanted:"+e,"handed:"+b.length]);var d=r.$subarray(b,0,e);throw new r.GLMJSError(a+" elements size mismatch: "+["wanted:"+e,"handed:"+b.length,"theoreticaly-correctable?:"+(d.length===e)]);}return b};var m=this._typedArrayMaker(e,GLM.$outer.Float32Array),q,s= -GLM.$outer;q=function(a){return a instanceof s.Float32Array};var t=function(a,b,c,g,h,i,j,k){return eval(k("glm_"+h+"$class",function(c){for(var f=new a(arguments.length),g=0;g<f.length;g++)f[g]=arguments[g];var h=d(f),g=t;if(this instanceof g)f=q(c)?w(c):m(h(f)),b.defineProperty(this,"elements",{enumerable:!1,configurable:!0,value:f});else return f=q(c)&&c.length===e?m(c):h(f),new g(f)}))()}(Array,Object,GLM,c,a,GLM.$template._get_argnames.bind(GLM.$template),GLM.GLMJSError,GLM.$template._traceable.bind(GLM.$template)); -c.components=c.components?c.components.map(function(a){return"string"===typeof a?a.split(""):a}):[];t.$=c;t.componentLength=e;t.BYTES_PER_ELEMENT=e*GLM.$outer.Float32Array.BYTES_PER_ELEMENT;t.prototype=new GLM.$GLMBaseType(t,a);t.toJSON=function(){var b={glm$type:a,glm$class:t.prototype.$type_name,glm$eg:(new t).object},c;for(c in t)/function |^[$]/.test(c+t[c])||(b[c]=t[c]);return b};return t}}; -GLM.$template["declare<T,V,...>"]({cross:{"vec2,vec2":function(a,b){return this.GLM.vec3(0,0,a.x*b.y-a.y*b.x)}},distance:{"vec<N>,vec<N>":function(a,b){return this.GLM.length(b.sub(a))}}}); -GLM.$template["declare<T,V,number>"]({mix:{"float,float":function(a,b,c){return b*c+a*(1-c)},"vec<N>,vec<N>":function(a,b,c){var e=1-c,d=new this.GLM.vecN(new a.elements.constructor(N)),h=d.elements;a=a.elements;b=b.elements;for(var j=0;j<N;j++)h[j]=b[j]*c+a[j]*e;return d}},clamp:{"float,float":function(a,b,c){return GLM._clamp(a,b,c)},"vec<N>,float":function(a,b,c){return new GLM.vecN(GLM.$to_array(a).map(function(a){return GLM._clamp(a,b,c)}))}},epsilonEqual:{"float,float":GLM._epsilonEqual,"vec<N>,vec<N>":function(a, -b,c){for(var e=this["float,float"],d=glm.bvecN(),h=0;h<N;h++)d[h]=e(a[h],b[h],c);return d},"ivec<N>,ivec<N>":function(a,b,c){return this["vecN,vecN"](a,b,c)},"uvec<N>,uvec<N>":function(a,b,c){return this["vecN,vecN"](a,b,c)},"quat,quat":function(a,b,c){for(var e=this["float,float"],d=glm.bvec4(),h=0;4>h;h++)d[h]=e(a[h],b[h],c);return d},"mat<N>,mat<N>":function(){throw new GLM.GLMJSError("error: 'epsilonEqual' only accept floating-point and integer scalar or vector inputs");}}}); -GLM.$template.extend(GLM,GLM.$template["declare<T>"]({degrees:{"float":function(a){return this.GLM._degrees(a)},"vec<N>":function(a){return new this.GLM.vecN(this.GLM.$to_array(a).map(this.GLM._degrees))}},radians:{"float":function(a){return this.GLM._radians(a)},"vec<N>":function(a){return new this.GLM.vecN(this.GLM.$to_array(a).map(this.GLM._radians))}},sign:{"null":function(){return 0},undefined:function(){return NaN},string:function(){return NaN},"float":function(a){return GLM._sign(a)},"vec<N>":function(a){return new GLM.vecN(GLM.$to_array(a).map(GLM._sign))}, -"ivec<N>":function(a){return new GLM.ivecN(GLM.$to_array(a).map(GLM._sign))}},abs:{"float":function(a){return GLM._abs(a)},"vec<N>":function(a){return new GLM.vecN(GLM.$to_array(a).map(GLM._abs))}},fract:{"float":function(a){return GLM._fract(a)},"vec<N>":function(a){return new GLM.vecN(GLM.$to_array(a).map(GLM._fract))}},all:{"vec<N>":function(a){return N===GLM.$to_array(a).filter(Boolean).length},"bvec<N>":function(a){return N===GLM.$to_array(a).filter(Boolean).length},"ivec<N>":function(a){return N=== -GLM.$to_array(a).filter(Boolean).length},"uvec<N>":function(a){return N===GLM.$to_array(a).filter(Boolean).length},quat:function(a){return 4===GLM.$to_array(a).filter(Boolean).length}},$to_object:{vec2:function(a){return{x:a.x,y:a.y}},vec3:function(a){return{x:a.x,y:a.y,z:a.z}},vec4:function(a){return{x:a.x,y:a.y,z:a.z,w:a.w}},uvec2:function(a){return{x:a.x,y:a.y}},uvec3:function(a){return{x:a.x,y:a.y,z:a.z}},uvec4:function(a){return{x:a.x,y:a.y,z:a.z,w:a.w}},ivec2:function(a){return{x:a.x,y:a.y}}, -ivec3:function(a){return{x:a.x,y:a.y,z:a.z}},ivec4:function(a){return{x:a.x,y:a.y,z:a.z,w:a.w}},bvec2:function(a){return{x:!!a.x,y:!!a.y}},bvec3:function(a){return{x:!!a.x,y:!!a.y,z:!!a.z}},bvec4:function(a){return{x:!!a.x,y:!!a.y,z:!!a.z,w:!!a.w}},quat:function(a){return{w:a.w,x:a.x,y:a.y,z:a.z}},mat3:function(a){return{"0":this.vec3(a[0]),1:this.vec3(a[1]),2:this.vec3(a[2])}},mat4:function(a){return{"0":this.vec4(a[0]),1:this.vec4(a[1]),2:this.vec4(a[2]),3:this.vec4(a[3])}}},roll:{$atan2:Math.atan2, -quat:function(a){return this.$atan2(2*(a.x*a.y+a.w*a.z),a.w*a.w+a.x*a.x-a.y*a.y-a.z*a.z)}},pitch:{$atan2:Math.atan2,quat:function(a){return this.$atan2(2*(a.y*a.z+a.w*a.x),a.w*a.w-a.x*a.x-a.y*a.y+a.z*a.z)}},yaw:{$asin:Math.asin,quat:function(a){return this.$asin(this.GLM.clamp(-2*(a.x*a.z-a.w*a.y),-1,1))}},eulerAngles:{quat:function(a){return this.GLM.vec3(this.GLM.pitch(a),this.GLM.yaw(a),this.GLM.roll(a))}}}),GLM.$template["declare<T,...>"]({$from_glsl:{string:function(a,b){var c;a.replace(/^([$\w]+)\(([-.0-9ef, ]+)\)$/, -function(a,d,h){a=glm[d]||glm["$"+d];if(!a)throw new GLM.GLMJSError("glsl decoding issue: unknown type '"+d+"'");c=h.split(",").map(parseFloat);if(!b||b===a)c=a.apply(glm,c);else{if(!0===b||b===Array){for(;c.length<a.componentLength;)c.push(c[c.length-1]);return c}throw new GLM.GLMJSError("glsl decoding issue: second argument expected to be undefined|true|Array");}});return c}},$to_glsl:{"vec<N>":function(a,b){var c=GLM.$to_array(a);b&&("object"===typeof b&&"precision"in b)&&(c=c.map(function(a){return a.toFixed(b.precision)})); -for(;c.length&&c[c.length-2]===c[c.length-1];)c.pop();return a.$type+"("+c+")"},"uvec<N>":function(a,b){return this.vecN(a,b)},"ivec<N>":function(a,b){return this.vecN(a,b)},"bvec<N>":function(a,b){return this.vecN(a,b)},quat:function(a,b){var c;b&&("object"===typeof b&&"precision"in b)&&(c=b.precision);return 0===a.x+a.y+a.z?"quat("+(void 0===c?a.w:a.w.toFixed(c))+")":this.vec4(a,b)},"mat<N>":function(a,b){var c;b&&("object"===typeof b&&"precision"in b)&&(c=b.precision);var e=GLM.$to_array(a);void 0!== -c&&(e=e.map(function(a){return a.toFixed(c)}));return e.reduce(function(a,b){return a+1*b},0)===e[0]*N?"matN("+e[0]+")":"matN("+e+")"}},frexp:{"float":function(a,b){return 1===arguments.length?this["float,undefined"](a):this["float,array"](a,b)},"vec<N>":function(a,b){if(2>arguments.length)throw new GLM.GLMJSError("frexp(vecN, ivecN) expected ivecN as second parameter");return GLM.vecN(GLM.$to_array(a).map(function(a,e){var d=GLM._frexp(a);b[e]=d[1];return d[0]}))},"float,undefined":function(a){return GLM._frexp(a)}, -"float,array":function(a,b){return GLM._frexp(a,b)}},ldexp:{"float":GLM._ldexp,"vec<N>":function(a,b){return GLM.vecN(GLM.$to_array(a).map(function(a,e){return GLM._ldexp(a,b[e])}))}}})); -GLM.$template["declare<T,V,...>"]({rotate:{"float,vec3":function(a,b){return this.GLM.$outer.mat4_angleAxis(a,b)},"mat4,float":function(a,b,c){return a.mul(this.GLM.$outer.mat4_angleAxis(b,c))}},scale:{$outer:GLM.$outer,"mat4,vec3":function(a,b){return a.mul(this.$outer.mat4_scale(b))},"vec3,undefined":function(a){return this.$outer.mat4_scale(a)}},translate:{"mat4,vec3":function(a,b){return a.mul(this.GLM.$outer.mat4_translation(b))},"vec3,undefined":function(a){return this.GLM.$outer.mat4_translation(a)}}, -angleAxis:{"float,vec3":function(a,b){return this.GLM.$outer.quat_angleAxis(a,b)}},min:{"float,float":function(a,b){return this.GLM._min(a,b)},"vec<N>,float":function(a,b){return new this.GLM.vecN(this.GLM.$to_array(a).map(function(a){return this.GLM._min(a,b)}.bind(this)))}},max:{"float,float":function(a,b){return this.GLM._max(a,b)},"vec<N>,float":function(a,b){return new this.GLM.vecN(this.GLM.$to_array(a).map(function(a){return this.GLM._max(a,b)}.bind(this)))}},equal:{"float,float":GLM._equal, -"vec<N>,vec<N>":function(a,b){for(var c=this["float,float"],e=glm.bvecN(),d=0;d<N;d++)e[d]=c(a[d],b[d]);return e},"bvec<N>,bvec<N>":function(a,b){return this["vecN,vecN"](a,b)},"ivec<N>,ivec<N>":function(a,b){return this["vecN,vecN"](a,b)},"uvec<N>,uvec<N>":function(a,b){return this["vecN,vecN"](a,b)},"quat,quat":function(a,b){for(var c=this["float,float"],e=glm.bvec4(),d=0;4>d;d++)e[d]=c(a[d],b[d]);return e}},_slerp:{"quat,quat":function(a,b,c){var e=b,d=glm.dot(glm.vec4(a),glm.vec4(b));0>d&&(e= -b.mul(-1),d=-d);if(d>1-glm.epsilon())return glm.quat(glm.mix(a.w,e.w,c),glm.mix(a.x,e.x,c),glm.mix(a.y,e.y,c),glm.mix(a.z,e.z,c));b=Math.acos(d);return(a.mul(Math.sin((1-c)*b))+e.mul(Math.sin(c*b)))/Math.sin(b)}},rotation:{"vec3,vec3":function(a,b){var c=this.$dot(a,b),e=new a.constructor(new a.elements.constructor(3));if(c>=1-this.$epsilon)return this.$quat();if(c<-1+this.$epsilon)return e=this.$cross(this.$m[2],a),this.$length2(e)<this.$epsilon&&(e=this.$cross(this.$m[0],a)),e=this.$normalize(e), -this.$angleAxis(this.$pi,e);var e=this.$cross(a,b),c=this.$sqrt(2*(1+c)),d=1/c;return this.$quat(0.5*c,e.x*d,e.y*d,e.z*d)}},project:{"vec3,mat4":function(a,b,c,e){a=glm.vec4(a,1);a=b["*"](a);a=c["*"](a);a["/="](a.w);a=a["*"](0.5)["+"](0.5);a[0]=a[0]*e[2]+e[0];a[1]=a[1]*e[3]+e[1];return glm.vec3(a)}},unProject:{"vec3,mat4":function(a,b,c,e){b=glm.inverse(c["*"](b));a=glm.vec4(a,1);a.x=(a.x-e[0])/e[2];a.y=(a.y-e[1])/e[3];a=a["*"](2)["-"](glm.vec4(1));e=b["*"](a);e["/="](e.w);return glm.vec3(e)}},orientedAngle:{"vec3,vec3":function(a, -b,c){var e=Math.acos(glm.clamp(glm.dot(a,b),0,1));return glm.mix(e,-e,0>glm.dot(c,glm.cross(a,b))?1:0)}}}); -GLM.$to_string=GLM.$template["declare<T,...>"]({$to_string:{"function":function(a){return"[function "+(a.name||"anonymous")+"]"},ArrayBuffer:function(a){return"[object ArrayBuffer "+JSON.stringify({byteLength:a.byteLength})+"]"},Float32Array:function(a){return"[object Float32Array "+JSON.stringify({length:a.length,byteOffset:a.byteOffset,byteLength:a.byteLength,BPE:a.BYTES_PER_ELEMENT})+"]"},"float":function(a,b){return GLM.$toFixedString("float",{value:a},["value"],b&&b.precision)},string:function(a){return a}, -bool:function(a){return"bool("+a+")"},"vec<N>":function(a,b){return GLM.$toFixedString(a.$type_name,a,a.$components,b&&b.precision)},"uvec<N>":function(a,b){return GLM.$toFixedString(a.$type_name,a,a.$components,b&&"object"===typeof b&&b.precision||0)},"ivec<N>":function(a,b){return GLM.$toFixedString(a.$type_name,a,a.$components,b&&"object"===typeof b&&b.precision||0)},"bvec<N>":function(a){return a.$type_name+"("+GLM.$to_array(a).map(Boolean).join(", ")+")"},"mat<N>":function(a,b){var c=[0,1,2, -3].slice(0,N).map(function(b){return a[b]}).map(function(a){return GLM.$toFixedString("\t",a,a.$components,b&&b.precision)});return a.$type_name+"(\n"+c.join(", \n")+"\n)"},quat:function(a,b){a=GLM.degrees(GLM.eulerAngles(a));return GLM.$toFixedString("<quat>"+a.$type_name,a,["x","y","z"],b&&b.precision)}}}).$to_string; -GLM.$template["declare<T,V,...>"]({copy:{$op:"=","vec<N>,vec<N>":function(a,b){a.elements.set(b.elements);return a},"vec<N>,array<N>":function(a,b){a.elements.set(b);return a},"vec<N>,uvec<N>":function(a,b){a.elements.set(b.elements);return a},"vec<N>,ivec<N>":function(a,b){a.elements.set(b.elements);return a},"vec<N>,bvec<N>":function(a,b){a.elements.set(b.elements);return a},"uvec<N>,uvec<N>":function(a,b){a.elements.set(b.elements);return a},"uvec<N>,array<N>":function(a,b){a.elements.set(b);return a}, -"uvec<N>,vec<N>":function(a,b){a.elements.set(b.elements);return a},"uvec<N>,ivec<N>":function(a,b){a.elements.set(b.elements);return a},"uvec<N>,bvec<N>":function(a,b){a.elements.set(b.elements);return a},"ivec<N>,ivec<N>":function(a,b){a.elements.set(b.elements);return a},"ivec<N>,array<N>":function(a,b){a.elements.set(b);return a},"ivec<N>,vec<N>":function(a,b){a.elements.set(b.elements);return a},"ivec<N>,uvec<N>":function(a,b){a.elements.set(b.elements);return a},"ivec<N>,bvec<N>":function(a, -b){a.elements.set(b.elements);return a},"bvec<N>,ivec<N>":function(a,b){a.elements.set(b.elements);return a},"bvec<N>,array<N>":function(a,b){a.elements.set(b);return a},"bvec<N>,vec<N>":function(a,b){a.elements.set(b.elements);return a},"bvec<N>,uvec<N>":function(a,b){a.elements.set(b.elements);return a},"bvec<N>,bvec<N>":function(a,b){a.elements.set(b.elements);return a},"quat,quat":function(a,b){a.elements.set(b.elements);return a},"mat<N>,mat<N>":function(a,b){a.elements.set(b.elements);return a}, -"mat<N>,array<N>":function(a,b){b=b.reduce(function(a,b){if(!a.concat)throw new GLM.GLMJSError("matN,arrayN -- [[.length===4] x 4] expected");return a.concat(b)});if(b===N)throw new GLM.GLMJSError("matN,arrayN -- [[N],[N],[N],[N]] expected");return a["="](b)},"mat<N>,array<N*N>":function(a,b){a.elements.set(b);return a},"mat4,array9":function(a,b){a.elements.set((new GLM.mat4(b)).elements);return a}},sub:{$op:"-",_sub:function(a,b){return this.GLM.$to_array(a).map(function(a,e){return a-b[e]})},"vec<N>,vec<N>":function(a, -b){return new this.GLM.vecN(this._sub(a,b))},"vec<N>,uvec<N>":function(a,b){return new this.GLM.vecN(this._sub(a,b))},"uvec<N>,uvec<N>":function(a,b){return new this.GLM.uvecN(this._sub(a,b))},"uvec<N>,ivec<N>":function(a,b){return new this.GLM.uvecN(this._sub(a,b))},"vec<N>,ivec<N>":function(a,b){return new this.GLM.vecN(this._sub(a,b))},"ivec<N>,uvec<N>":function(a,b){return new this.GLM.ivecN(this._sub(a,b))},"ivec<N>,ivec<N>":function(a,b){return new this.GLM.ivecN(this._sub(a,b))}},sub_eq:{$op:"-=", -"vec<N>,vec<N>":function(a,b){for(var c=a.elements,e=b.elements,d=0;d<N;d++)c[d]-=e[d];return a},"vec<N>,uvec<N>":function(a,b){return this["vecN,vecN"](a,b)},"uvec<N>,uvec<N>":function(a,b){return this["vecN,vecN"](a,b)},"uvec<N>,ivec<N>":function(a,b){return this["vecN,vecN"](a,b)},"vec<N>,ivec<N>":function(a,b){return this["vecN,vecN"](a,b)},"ivec<N>,ivec<N>":function(a,b){return this["vecN,vecN"](a,b)},"ivec<N>,uvec<N>":function(a,b){return this["vecN,vecN"](a,b)}},add:{$op:"+",_add:function(a, -b){return this.GLM.$to_array(a).map(function(a,e){return a+b[e]})},"vec<N>,float":function(a,b){return new this.GLM.vecN(this._add(a,[b,b,b,b]))},"vec<N>,vec<N>":function(a,b){return new this.GLM.vecN(this._add(a,b))},"vec<N>,uvec<N>":function(a,b){return new this.GLM.vecN(this._add(a,b))},"uvec<N>,uvec<N>":function(a,b){return new this.GLM.uvecN(this._add(a,b))},"uvec<N>,ivec<N>":function(a,b){return new this.GLM.uvecN(this._add(a,b))},"vec<N>,ivec<N>":function(a,b){return new this.GLM.vecN(this._add(a, -b))},"ivec<N>,ivec<N>":function(a,b){return new this.GLM.ivecN(this._add(a,b))},"ivec<N>,uvec<N>":function(a,b){return new this.GLM.ivecN(this._add(a,b))}},add_eq:{$op:"+=","vec<N>,vec<N>":function(a,b){for(var c=a.elements,e=b.elements,d=0;d<N;d++)c[d]+=e[d];return a},"vec<N>,uvec<N>":function(a,b){return this["vecN,vecN"](a,b)},"uvec<N>,uvec<N>":function(a,b){return this["vecN,vecN"](a,b)},"uvec<N>,ivec<N>":function(a,b){return this["vecN,vecN"](a,b)},"vec<N>,ivec<N>":function(a,b){return this["vecN,vecN"](a, -b)},"ivec<N>,ivec<N>":function(a,b){return this["vecN,vecN"](a,b)},"ivec<N>,uvec<N>":function(a,b){return this["vecN,vecN"](a,b)}},div:{$op:"/","vec<N>,float":function(a,b){return new this.GLM.vecN(this.GLM.$to_array(a).map(function(a){return a/b}))}},div_eq:{$op:"/=","vec<N>,float":function(a,b){for(var c=0;c<N;c++)a.elements[c]/=b;return a}},mul:{$op:"*","vec<N>,vec<N>":function(a,b){return new this.GLM.vecN(this.GLM.$to_array(a).map(function(a,e){return a*b[e]}))}},eql_epsilon:function(a){return{$op:"~=", -"vec<N>,vec<N>":a,"mat<N>,mat<N>":a,"quat,quat":a,"uvec<N>,uvec<N>":a,"ivec<N>,ivec<N>":a}}(function(a,b){return this.GLM.all(this.GLM.epsilonEqual(a,b,this.GLM.epsilon()))}),eql:function(a){return{$op:"==","mat<N>,mat<N>":function(a,c){return c.elements.length===glm.$to_array(a).filter(function(a,b){return a===c.elements[b]}).length},"vec<N>,vec<N>":a,"quat,quat":a,"uvec<N>,uvec<N>":a,"ivec<N>,ivec<N>":a,"bvec<N>,bvec<N>":a}}(function(a,b){return GLM.all(GLM.equal(a,b))})}); -GLM.string={$type_name:"string",$:{}};GLM.number={$type_name:"float",$:{}};GLM["boolean"]={$type:"bool",$type_name:"bool",$:{}}; -GLM.vec2=GLM.$template.GLMType("vec2",{name:"fvec2",identity:[0,0],components:["xy","01"],undefined0:function(){return this.identity},number1:function(a){return[a,a]},number2:function(a,b){return[a,b]},object1:function(a){if(null!==a)switch(a.length){case 4:case 3:case 2:return[a[0],a[1]];default:if("y"in a&&"x"in a){if(typeof a.x!==typeof a.y)throw new GLM.GLMJSError("unrecognized .x-ish object passed to GLM.vec2: "+a);return"string"===typeof a.x?[1*a.x,1*a.y]:[a.x,a.y]}}throw new GLM.GLMJSError("unrecognized object passed to GLM.vec2: "+ -a);}}); -GLM.uvec2=GLM.$template.GLMType("uvec2",{name:"uvec2",identity:[0,0],components:["xy","01"],_clamp:function(a){return~~a},undefined0:function(){return this.identity},number1:function(a){a=this._clamp(a);return[a,a]},number2:function(a,b){a=this._clamp(a);b=this._clamp(b);return[a,b]},object1:function(a){switch(a.length){case 4:case 3:case 2:return[a[0],a[1]].map(this._clamp);default:if("y"in a&&"x"in a){if(typeof a.x!==typeof a.y)throw new GLM.GLMJSError("unrecognized .x-ish object passed to GLM."+this.name+ -": "+a);return[a.x,a.y].map(this._clamp)}}throw new GLM.GLMJSError("unrecognized object passed to GLM."+this.name+": "+a);}}); -GLM.vec3=GLM.$template.GLMType("vec3",{name:"fvec3",identity:[0,0,0],components:["xyz","012","rgb"],undefined0:function(){return GLM.vec3.$.identity},number1:function(a){return[a,a,a]},number2:function(a,b){return[a,b,b]},number3:function(a,b,c){return[a,b,c]},Error:GLM.GLMJSError,object1:function(a){if(a)switch(a.length){case 4:case 3:return[a[0],a[1],a[2]];case 2:return[a[0],a[1],a[1]];default:if("z"in a&&"x"in a){if(typeof a.x!==typeof a.y)throw new this.Error("unrecognized .x-ish object passed to GLM.vec3: "+ -a);return"string"===typeof a.x?[1*a.x,1*a.y,1*a.z]:[a.x,a.y,a.z]}}throw new this.Error("unrecognized object passed to GLM.vec3: "+a);},object2:function(a,b){if(a instanceof GLM.vec2||a instanceof GLM.uvec2||a instanceof GLM.ivec2||a instanceof GLM.bvec2)return[a.x,a.y,b];throw new GLM.GLMJSError("unrecognized object passed to GLM.vec3(o,z): "+[a,b]);}}); -GLM.uvec3=GLM.$template.GLMType("uvec3",{name:"uvec3",identity:[0,0,0],components:["xyz","012"],_clamp:GLM.uvec2.$._clamp,undefined0:function(){return this.identity},number1:function(a){a=this._clamp(a);return[a,a,a]},number2:function(a,b){a=this._clamp(a);b=this._clamp(b);return[a,b,b]},number3:function(a,b,c){a=this._clamp(a);b=this._clamp(b);c=this._clamp(c);return[a,b,c]},object1:function(a){if(a)switch(a.length){case 4:case 3:return[a[0],a[1],a[2]].map(this._clamp);case 2:return[a[0],a[1],a[1]].map(this._clamp); -default:if("z"in a&&"x"in a){if(typeof a.x!==typeof a.y)throw new GLM.GLMJSError("unrecognized .x-ish object passed to GLM."+this.name+": "+a);return[a.x,a.y,a.z].map(this._clamp)}}throw new GLM.GLMJSError("unrecognized object passed to GLM."+this.name+": "+a);},object2:function(a,b){if(a instanceof GLM.vec2)return[a.x,a.y,b].map(this._clamp);if(a instanceof GLM.uvec2||a instanceof GLM.ivec2||a instanceof GLM.bvec2)return[a.x,a.y,this._clamp(b)];throw new GLM.GLMJSError("unrecognized object passed to GLM."+ -this.name+"(o,z): "+[a,b]);}}); -GLM.vec4=GLM.$template.GLMType("vec4",{name:"fvec4",identity:[0,0,0,0],components:["xyzw","0123","rgba"],undefined0:function(){return this.identity},number1:function(a){return[a,a,a,a]},number2:function(a,b){return[a,b,b,b]},number3:function(a,b,c){return[a,b,c,c]},number4:function(a,b,c,e){return[a,b,c,e]},Error:GLM.GLMJSError,object1:function(a){if(a)switch(a.length){case 4:return[a[0],a[1],a[2],a[3]];case 3:return[a[0],a[1],a[2],a[2]];case 2:return[a[0],a[1],a[1],a[1]];default:if("w"in a&&"x"in -a){if(typeof a.x!==typeof a.w)throw new this.Error("unrecognized .x-ish object passed to GLM.vec4: "+a);return"string"===typeof a.x?[1*a.x,1*a.y,1*a.z,1*a.w]:[a.x,a.y,a.z,a.w]}}throw new this.Error("unrecognized object passed to GLM.vec4: "+[a,a&&a.$type]);},$GLM:GLM,object2:function(a,b){if(a instanceof this.$GLM.vec3||a instanceof this.$GLM.uvec3||a instanceof this.$GLM.ivec3||a instanceof this.$GLM.bvec3)return[a.x,a.y,a.z,b];throw new this.$GLM.GLMJSError("unrecognized object passed to GLM.vec4(o,w): "+ -[a,b]);},object3:function(a,b,c){if(a instanceof this.$GLM.vec2||a instanceof this.$GLM.uvec2||a instanceof this.$GLM.ivec2||a instanceof this.$GLM.bvec2)return[a.x,a.y,b,c];throw new this.$GLM.GLMJSError("unrecognized object passed to GLM.vec4(o,z,w): "+[a,b,c]);}}); -GLM.uvec4=GLM.$template.GLMType("uvec4",{name:"uvec4",identity:[0,0,0,0],components:["xyzw","0123"],_clamp:GLM.uvec2.$._clamp,undefined0:function(){return this.identity},number1:function(a){a=this._clamp(a);return[a,a,a,a]},number2:function(a,b){a=this._clamp(a);b=this._clamp(b);return[a,b,b,b]},number3:function(a,b,c){a=this._clamp(a);b=this._clamp(b);c=this._clamp(c);return[a,b,c,c]},number4:function(a,b,c,e){return[a,b,c,e].map(this._clamp)},Error:GLM.GLMJSError,object1:function(a){if(a)switch(a.length){case 4:return[a[0], -a[1],a[2],a[3]].map(this._clamp);case 3:return[a[0],a[1],a[2],a[2]].map(this._clamp);case 2:return[a[0],a[1],a[1],a[1]].map(this._clamp);default:if("w"in a&&"x"in a){if(typeof a.x!==typeof a.y)throw new this.Error("unrecognized .x-ish object passed to GLM."+this.name+": "+a);return[a.x,a.y,a.z,a.w].map(this._clamp)}}throw new GLM.GLMJSError("unrecognized object passed to GLM."+this.name+": "+[a,a&&a.$type]);},object2:function(a,b){if(a instanceof GLM.vec3)return[a.x,a.y,a.z,b].map(this._clamp);if(a instanceof -GLM.uvec3||a instanceof GLM.ivec3||a instanceof GLM.bvec3)return[a.x,a.y,a.z,this._clamp(b)];throw new GLM.GLMJSError("unrecognized object passed to GLM."+this.name+"(o,w): "+[a,b]);},object3:function(a,b,c){if(a instanceof GLM.vec2)return[a.x,a.y,b,c].map(this._clamp);if(a instanceof GLM.uvec2||a instanceof GLM.ivec2||a instanceof GLM.bvec2)return[a.x,a.y,this._clamp(b),this._clamp(c)];throw new GLM.GLMJSError("unrecognized object passed to GLM."+this.name+"(o,z,w): "+[a,b,c]);}}); -GLM.ivec2=GLM.$template.GLMType("ivec2",GLM.$template.extend({},GLM.uvec2.$,{name:"ivec2"}));GLM.ivec3=GLM.$template.GLMType("ivec3",GLM.$template.extend({},GLM.uvec3.$,{name:"ivec3"}));GLM.ivec4=GLM.$template.GLMType("ivec4",GLM.$template.extend({},GLM.uvec4.$,{name:"ivec4"}));GLM.bvec2=GLM.$template.GLMType("bvec2",GLM.$template.extend({},GLM.uvec2.$,{name:"bvec2",boolean1:GLM.uvec2.$.number1,boolean2:GLM.uvec2.$.number2})); -GLM.bvec3=GLM.$template.GLMType("bvec3",GLM.$template.extend({},GLM.uvec3.$,{name:"bvec3",boolean1:GLM.uvec3.$.number1,boolean2:GLM.uvec3.$.number2,boolean3:GLM.uvec3.$.number3}));GLM.bvec4=GLM.$template.GLMType("bvec4",GLM.$template.extend({},GLM.uvec4.$,{name:"bvec4",boolean1:GLM.uvec4.$.number1,boolean2:GLM.uvec4.$.number2,boolean3:GLM.uvec4.$.number3,boolean4:GLM.uvec4.$.number4}));GLM.bvec2.$._clamp=GLM.bvec3.$._clamp=GLM.bvec4.$._clamp=function(a){return!!a}; -GLM.mat3=GLM.$template.GLMType("mat3",{name:"mat3x3",identity:[1,0,0,0,1,0,0,0,1],undefined0:function(){return this.identity},number1:function(a){return 1===a?this.identity:[a,0,0,0,a,0,0,0,a]},number9:function(a,b,c,e,d,h,j,g,k){return arguments},Error:GLM.GLMJSError,$vec3:GLM.vec3,object1:function(a){if(a){var b=a.elements||a;if(16===b.length)return[b[0],b[1],b[2],b[4],b[5],b[6],b[8],b[9],b[10]];if(9===b.length)return b;if(0 in b&&1 in b&&2 in b&&!(3 in b)&&"object"===typeof b[2])return[b[0],b[1], -b[2]].map(this.$vec3.$.object1).reduce(function(a,b){return a.concat(b)})}throw new this.Error("unrecognized object passed to GLM.mat3: "+a);},object3:function(a,b,c){return[a,b,c].map(glm.$to_array).reduce(function(a,b){return a.concat(b)})}}); -GLM.mat4=GLM.$template.GLMType("mat4",{name:"mat4x4",identity:[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],undefined0:function(){return this.identity},number16:function(a,b,c,e,d,h,j,g,k,i,w,r,m,q,s,t){return arguments},number1:function(a){return 1===a?this.identity:[a,0,0,0,0,a,0,0,0,0,a,0,0,0,0,a]},Error:GLM.GLMJSError,$vec4:GLM.vec4,object1:function(a){var b;if(a){b=a.elements||a;if(9===b.length)return[b[0],b[1],b[2],0,b[3],b[4],b[5],0,b[6],b[7],b[8],0,0,0,0,1];if(4===b.length&&b[0]&&4===b[0].length)return b[0].concat(b[1], -b[2],b[3]);if(16===b.length)return b;if(0 in b&&1 in b&&2 in b&&3 in b&&!(4 in b)&&"object"===typeof b[3])return[b[0],b[1],b[2],b[3]].map(this.$vec4.$.object1).reduce(function(a,b){return a.concat(b)})}throw new this.Error("unrecognized object passed to GLM.mat4: "+[a,b&&b.length]);},object4:function(a,b,c,e){return[a,b,c,e].map(glm.$to_array).reduce(function(a,b){return a.concat(b)})}}); -GLM.quat=GLM.$template.GLMType("quat",{identity:[0,0,0,1],components:["xyzw","0123"],undefined0:function(){return this.identity},number1:function(a){if(1!==a)throw Error("only quat(1) syntax supported for quat(number1 args)...");return this.identity},number4:function(a,b,c,e){return[b,c,e,a]},$GLM:GLM,$M3:GLM.mat3(),$quat_array_from_zyx:function(a){var b=this.$M3;return this.$GLM.$outer.quat_angleAxis(a.z,b[2]).mul(this.$GLM.$outer.quat_angleAxis(a.y,b[1])).mul(this.$GLM.$outer.quat_angleAxis(a.x, -b[0])).elements},object1:function(a){if(a){if(a instanceof this.$GLM.mat4)return this.$GLM.$outer.quat_array_from_mat4(a);if(4===a.length)return[a[0],a[1],a[2],a[3]];if(a instanceof this.$GLM.quat)return[a.x,a.y,a.z,a.w];if(a instanceof this.$GLM.vec3)return this.$quat_array_from_zyx(a);if("w"in a&&"x"in a)return"string"===typeof a.x?[1*a.x,1*a.y,1*a.z,1*a.w]:[a.x,a.y,a.z,a.w]}throw new this.$GLM.GLMJSError("unrecognized object passed to GLM.quat.object1: "+[a,a&&a.$type,typeof a,a&&a.constructor]); -}}); -(function(){var a=function(a,b,c,e){var k={def:function(b,c){this[b]=c;Object.defineProperty(a.prototype,b,c)}};a.$properties=a.$properties||k;var i=a.$properties.def.bind(a.$properties),w=[0,1,2,3].map(function(a){return{enumerable:c,get:function(){return this.elements[a]},set:function(b){this.elements[a]=b}}});b.forEach(function(a,b){i(a,w[b])});if(isNaN(b[0])&&!/^_/.test(b[0])){var k=b.slice(),r=GLM.$subarray;do(function(a,b,c){"quat"===b&&(b="vec"+c);var d=GLM[b];i(a,{enumerable:!1,get:function(){return new d(r(this.elements,0* -c,1*c))},set:function(a){return(new d(r(this.elements,0*c,1*c)))["="](a)}})})(k.join(""),a.prototype.$type.replace(/[1-9]$/,k.length),k.length);while(k[1]!=k.pop());if(e)return a.$properties;k=b.slice();if(b={xyz:{yz:1},xyzw:{yzw:1,yz:1,zw:2}}[k.join("")])for(var m in b)(function(a,b,c,d){i(a,{enumerable:!1,get:function(){return new GLM[b](GLM.$subarray(this.elements,0*c+d,1*c+d))},set:function(a){return(new GLM[b](GLM.$subarray(this.elements,0*c+d,1*c+d)))["="](a)}})})(m,a.prototype.$type.replace(/[1-9]$/, -m.length),m.length,b[m])}return a.$properties};a(GLM.vec2,GLM.vec2.$.components[0],!0);a(GLM.vec2,GLM.vec2.$.components[1]);a(GLM.vec3,GLM.vec3.$.components[0],!0);a(GLM.vec3,GLM.vec3.$.components[1]);a(GLM.vec3,GLM.vec3.$.components[2]);a(GLM.vec4,GLM.vec4.$.components[0],!0);a(GLM.vec4,GLM.vec4.$.components[1]);a(GLM.vec4,GLM.vec4.$.components[2]);a(GLM.quat,GLM.quat.$.components[0],!0,"noswizzles");a(GLM.quat,GLM.quat.$.components[1]);GLM.quat.$properties.def("wxyz",{enumerable:!1,get:function(){return new GLM.vec4(this.w, -this.x,this.y,this.z)},set:function(a){a=GLM.vec4(a);return this["="](GLM.quat(a.x,a.y,a.z,a.w))}});"uvec2 uvec3 uvec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4".split(" ").forEach(function(b){a(GLM[b],GLM[b].$.components[0],!0);a(GLM[b],GLM[b].$.components[1])});Object.defineProperty(GLM.quat.prototype,"_x",{get:function(){throw Error("erroneous quat._x access");}});var b={2:{yx:{enumerable:!1,get:function(){return new GLM.vec2(this.y,this.x)},set:function(a){a=GLM.vec2(a);this.y=a[0];this.x=a[1]}}},3:{xz:{enumerable:!1, -get:function(){return new GLM.vec2(this.x,this.z)},set:function(a){a=GLM.vec2(a);this.x=a[0];this.z=a[1]}},zx:{enumerable:!1,get:function(){return new GLM.vec2(this.z,this.x)},set:function(a){a=GLM.vec2(a);this.z=a[0];this.x=a[1]}},xzy:{enumerable:!1,get:function(){return new GLM.vec3(this.x,this.z,this.y)},set:function(a){a=GLM.vec3(a);this.x=a[0];this.z=a[1];this.y=a[2]}}},4:{xw:{enumerable:!1,get:function(){return new GLM.vec2(this.x,this.w)},set:function(a){a=GLM.vec2(a);this.x=a[0];this.w=a[1]}}, -wz:{enumerable:!1,get:function(){return new GLM.vec2(this.w,this.z)},set:function(a){a=GLM.vec2(a);this.w=a[0];this.z=a[1]}},wxz:{enumerable:!1,get:function(){return new GLM.vec3(this.w,this.x,this.z)},set:function(a){a=GLM.vec3(a);this.w=a[0];this.x=a[1];this.z=a[2];return this}},xyw:{enumerable:!1,get:function(){return new GLM.vec3(this.x,this.y,this.w)},set:function(a){a=GLM.vec3(a);this.x=a[0];this.y=a[1];this.w=a[2];return this}},xzw:{enumerable:!1,get:function(){return new GLM.vec3(this.x,this.z, -this.w)},set:function(a){a=GLM.vec3(a);this.x=a[0];this.z=a[1];this.w=a[2]}},wxyz:{enumerable:!1,get:function(){return new GLM.vec4(this.w,this.x,this.y,this.z)},set:function(a){a=GLM.vec4(a);this.w=a[0];this.x=a[1];this.y=a[2];this.z=a[3];return this}}}},c;for(c in b)for(var e in b[c])2>=c&&GLM.vec2.$properties.def(e,b[c][e]),3>=c&&GLM.vec3.$properties.def(e,b[c][e]),4>=c&&GLM.vec4.$properties.def(e,b[c][e]);GLM.$partition=function(a,b,c,e){if(void 0===c)throw new GLM.GLMJSError("nrows is undefined"); -var k=b.$.identity.length;c=c||k;for(var i=function(a){3<GLM.$DEBUG&&GLM.$outer.console.debug("CACHEDBG: "+a)},w=0;w<c;w++)(function(c){var j=e&&e+c,q=c*k;Object.defineProperty(a,c,{configurable:!0,enumerable:!0,set:function(e){if(e instanceof b)this.elements.set(e.elements,q);else if(e&&e.length===k)this.elements.set(e,q);else throw new GLM.GLMJSError("unsupported argtype to "+(a&&a.$type)+"["+c+"] setter: "+[typeof e,e]);},get:function(){if(e){if(this[j])return c||i("cache hit "+j),this[j];c||i("cache miss "+ -j)}var a,d=new b(a=GLM.$subarray(this.elements,q,q+k));if(d.elements!==a)throw new GLM.GLMJSError("v.elements !== t "+[GLM.$subarray,d.elements.constructor===a.constructor,d.elements.buffer===a.buffer]);e&&Object.defineProperty(this,j,{configurable:!0,enumerable:!1,value:d});return d}})})(w)};GLM.$partition(GLM.mat4.prototype,GLM.vec4,4,"_cache_");GLM.$partition(GLM.mat3.prototype,GLM.vec3,3,"_cache_")})(); -GLM.$dumpTypes=function(a){GLM.$types.forEach(function(b){GLM[b].componentLength&&a("GLM."+b,JSON.stringify({"#type":GLM[b].prototype.$type_name,"#floats":GLM[b].componentLength,"#bytes":GLM[b].BYTES_PER_ELEMENT}))})}; -GLM.$init=function(a){a.prefix&&(GLMJS_PREFIX=a.prefix);GLM.$prefix=GLMJS_PREFIX;var b=a.log||function(){};try{b("GLM-js: ENV: "+_ENV._VERSION)}catch(c){}b("GLM-JS: initializing: "+JSON.stringify(a,0,2));b(JSON.stringify({functions:Object.keys(GLM.$outer.functions)}));var e=GLM.mat4,d=GLM.$outer;GLM.toMat4=function(a){return new e(d.mat4_array_from_quat(a))};GLM.$template.extend(GLM.rotation.$template,{$quat:GLM.quat,$dot:GLM.dot.link("vec3,vec3"),$epsilon:GLM.epsilon(),$m:GLM.mat3(),$pi:GLM.pi(), -$length2:GLM.length2.link("vec3"),$cross:GLM.cross.link("vec3,vec3"),$normalize:GLM.normalize.link("vec3"),$angleAxis:GLM.angleAxis.link("float,vec3"),$sqrt:GLM.sqrt});GLM.$symbols=[];for(var h in GLM)"function"===typeof GLM[h]&&/^[a-z]/.test(h)&&GLM.$symbols.push(h);GLM.$types.forEach(function(a){var b=GLM[a].prototype.$type,c;for(c in GLM.$outer.functions){var d=GLM.$outer.functions[c];d.$op&&(GLM.$DEBUG&&GLM.$outer.console.debug("mapping operator<"+b+"> "+c+" / "+d.$op),GLM[a].prototype[c]=d,GLM[a].prototype[d.$op]= -d)}});b("GLM-JS: "+GLM.version+" emulating GLM_VERSION="+GLM.GLM_VERSION+" vendor_name="+a.vendor_name+" vendor_version="+a.vendor_version);glm.vendor=a}; -GLM.using_namespace=function(a){GLM.$DEBUG&&GLM.$outer.console.debug("GLM.using_namespace munges globals; it should probably not be used!");GLM.using_namespace.$tmp={ret:void 0,tpl:a,names:GLM.$symbols,saved:{},evals:[],restore:[],before:[],after:[]};eval(GLM.using_namespace.$tmp.names.map(function(a,c){return"GLM.using_namespace.$tmp.saved['"+a+"'] = GLM.using_namespace.$tmp.before["+c+"] = 'undefined' !== typeof "+a+";"}).join("\n"));GLM.$DEBUG&&console.warn("GLM.using_namespace before #globals: "+ -GLM.using_namespace.$tmp.before.length);GLM.using_namespace.$tmp.names.map(function(a){GLM.using_namespace.$tmp.restore.push(a+"=GLM.using_namespace.$tmp.saved['"+a+"'];"+("GLM.using_namespace.$tmp.saved['"+a+"']=undefined;delete GLM.using_namespace.$tmp.saved['"+a+"'];"));GLM.using_namespace.$tmp.evals.push(a+"=GLM."+a+";")});eval(GLM.using_namespace.$tmp.evals.join("\n"));GLM.using_namespace.$tmp.ret=a();eval(GLM.using_namespace.$tmp.restore.join("\n"));eval(GLM.using_namespace.$tmp.names.map(function(a, -c){return"GLM.using_namespace.$tmp.after["+c+"] = 'undefined' !== typeof "+a+";"}).join("\n"));GLM.$DEBUG&&console.warn("GLM.using_namespace after #globals: "+GLM.using_namespace.$tmp.after.length);a=GLM.using_namespace.$tmp.ret;delete GLM.using_namespace.$tmp;return a}; -function $GLM_extern(a,b){b=b||a;return function(){GLM[b]=GLM.$outer.functions[a]||GLM.$outer[a];if(!GLM[b])throw new GLM.GLMJSError("$GLM_extern: unresolved external symbol: "+a);GLM.$DEBUG&&GLM.$outer.console.debug("$GLM_extern: resolved external symbol "+a+" "+typeof GLM[b]);return GLM[b].apply(this,arguments)}} -function GLM_polyfills(){var a={};"bind"in Function.prototype||(a.bind=Function.prototype.bind=function(a){function c(){}if("function"!==typeof this)throw new TypeError("not callable");var e=[].slice,d=e.call(arguments,1),h=this,j=function(){return h.apply(this instanceof c?this:a||global,d.concat(e.call(arguments)))};c.prototype=this.prototype||c.prototype;j.prototype=new c;return j});return a} -$GLM_reset_logging.current=function(){return{$GLM_log:"undefined"!==typeof $GLM_log&&$GLM_log,$GLM_console_log:"undefined"!==typeof $GLM_console_log&&$GLM_console_log,$GLM_console_prefixed:"undefined"!==typeof $GLM_console_prefixed&&$GLM_console_prefixed,console:GLM.$outer.console}}; -function $GLM_reset_logging(a){a&&"object"===typeof a&&($GLM_log=a.$GLM_log,$GLM_console_log=a.$GLM_console_log,$GLM_console_factory=a.$GLM_console_factory,GLM.$outer.console=a.console,a=!1);if(a||"undefined"===typeof $GLM_log)$GLM_log=function(a,b){GLM.$outer.console.log.apply(GLM.$outer.console,[].slice.call(arguments).map(function(a){var b=typeof a;return"xboolean"===b||"string"===b?a+"":GLM.$isGLMObject(a)||!isNaN(a)?GLM.to_string(a):a+""}))};if(a||"undefined"===typeof $GLM_console_log)$GLM_console_log= -function(a,b){(console[a]||function(){}).apply(console,[].slice.call(arguments,1))};if(a||"undefined"===typeof $GLM_console_factory)$GLM_console_factory=function(a){return $GLM_console_log.bind($GLM_console_log,a)};var b=$GLM_console_factory,c={};"debug,warn,info,error,log,write".replace(/\w+/g,function(a){c[a]=b(a)});"object"===typeof GLM&&(GLM.$outer&&(GLM.$outer.console=c),GLM.$log=$GLM_log);return c}try{window.$GLM_reset_logging=this.$GLM_reset_logging=$GLM_reset_logging}catch(e$$19){} -GLM.$reset_logging=$GLM_reset_logging;GLM.$log=GLM.$log||$GLM_log;function $GLM_GLMJSError(a,b){function c(c){this.name=a;this.stack=Error().stack;Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor);this.message=c;b&&b.apply(this,arguments)}c.prototype=Error();c.prototype.name=a;return c.prototype.constructor=c}GLMAT.mat4.exists;glm=GLM;var DLL={_version:"0.0.2",_name:"glm.gl-matrix.js",_glm_version:glm.version,prefix:"glm-js[glMatrix]: ",vendor_version:GLMAT.VERSION,vendor_name:"glMatrix"}; -DLL.statics={$outer:GLM.$outer,$typeArray:function(a){return new this.$outer.Float32Array(a)},$mat4:GLM.mat4,$quat:GLM.quat,$mat4$perspective:GLMAT.mat4.perspective,$mat4$ortho:GLMAT.mat4.ortho,mat4_perspective:function(a,b,c,e){return new this.$mat4(this.$mat4$perspective(this.$typeArray(16),a,b,c,e))},mat4_ortho:function(a,b,c,e,d,h){return new this.$mat4(this.$mat4$ortho(this.$typeArray(16),a,b,c,e,d||-1,h||1))},$quat$setAxisAngle:GLMAT.quat.setAxisAngle,$mat4$fromQuat:GLMAT.mat4.fromQuat,mat4_angleAxis:function(a, -b){var c=this.$quat$setAxisAngle(this.$typeArray(4),b,a);return new this.$mat4(this.$mat4$fromQuat(this.$typeArray(16),c))},quat_angleAxis:function(a,b){return new this.$quat(this.$quat$setAxisAngle(this.$typeArray(4),b,a))},$mat4$translate:GLMAT.mat4.translate,mat4_translation:function(a){var b=new this.$mat4;this.$mat4$translate(b.elements,b.elements,a.elements);return b},$mat4$scale:GLMAT.mat4.scale,mat4_scale:function(a){var b=new this.$mat4;this.$mat4$scale(b.elements,b.elements,a.elements); -return b},toJSON:function(){var a={},b;for(b in this)0!==b.indexOf("$")&&(a[b]=this[b]);return a},$vec3:GLM.vec3,$clamp:GLM.clamp,mat4_array_from_quat:function(a){return this.$mat4$fromQuat(this.$typeArray(16),a.elements)},$qtmp:new GLM.$outer.Float32Array(9),$quat$fromMat3:GLMAT.quat.fromMat3,$mat3$fromMat4:GLMAT.mat3.fromMat4,quat_array_from_mat4:function(a){return this.$quat$fromMat3(this.$typeArray(4),this.$mat3$fromMat4(this.$qtmp,a.elements))}}; -DLL["declare<T,V,...>"]={mul:{$op:"*",$typeArray:function(a){return new this.GLM.$outer.Float32Array(a)},$vec3$transformQuat:GLMAT.vec3.transformQuat,"quat,vec3":function(a,b){return new this.GLM.vec3(this.$vec3$transformQuat(this.$typeArray(3),b.elements,a.elements))},"vec3,quat":function(a,b){return this["quat,vec3"](this.GLM.inverse(b),a)},"quat,vec4":function(a,b){return this["mat4,vec4"](this.GLM.toMat4(a),b)},"vec4,quat":function(a,b){return this["quat,vec4"](this.GLM.inverse(b),a)},"$vec<N>$scale":"GLMAT.vecN.scale", -"vec<N>,float":function(a,b){return new this.GLM.vecN(this.$vecN$scale(this.$typeArray(N),a.elements,b))},"quat,float":function(a,b){return new a.constructor(this["vec4,float"](a,b).elements)},$vec4$transformMat4:GLMAT.vec4.transformMat4,"mat4,vec4":function(a,b){return new GLM.vec4(this.$vec4$transformMat4(this.$typeArray(4),b.elements,a.elements))},"vec4,mat4":function(a,b){return this["mat4,vec4"](GLM.inverse(b),a)},"$mat<N>mul":"GLMAT.matN.mul","mat<N>,mat<N>":function(a,b){return new a.constructor(this.$matNmul(this.$typeArray(N* -N),a.elements,b.elements))},$quat$multiply:GLMAT.quat.multiply,"quat,quat":function(a,b){return new a.constructor(this.$quat$multiply(this.$typeArray(4),a.elements,b.elements))}},mul_eq:{$op:"*=","$mat<N>$multiply":"GLMAT.matN.multiply","mat<N>,mat<N>":function(a,b){this.$matN$multiply(a.elements,a.elements,b.elements);return a},"$vec<N>$scale":"GLMAT.vecN.scale","vec<N>,float":function(a,b){this.$vecN$scale(a.elements,a.elements,b);return a},$quat$multiply:GLMAT.quat.multiply,"quat,quat":function(a, -b){this.$quat$multiply(a.elements,a.elements,b.elements);return a},$quat$invert:GLMAT.quat.invert,$vec3$transformQuat:GLMAT.vec3.transformQuat,"inplace:vec3,quat":function(a,b){var c=this.$quat$invert(new this.GLM.$outer.Float32Array(4),b.elements);this.$vec3$transformQuat(a.elements,a.elements,c);return a},$mat4$invert:GLMAT.mat4.invert,$vec4$transformMat4:GLMAT.vec4.transformMat4,"inplace:vec4,mat4":function(a,b){var c=this.$mat4$invert(new this.GLM.$outer.Float32Array(16),b.elements);this.$vec4$transformMat4(a.elements, -a.elements,c);return a}},cross:{$vec2$cross:GLMAT.vec2.cross,"vec2,vec2":function(a,b){return new this.GLM.vec3(this.$vec2$cross(new this.GLM.$outer.Float32Array(3),a,b))},$vec3$cross:GLMAT.vec3.cross,"vec3,vec3":function(a,b){return new this.GLM.vec3(this.$vec3$cross(new this.GLM.$outer.Float32Array(3),a,b))}},dot:{"$vec<N>$dot":"GLMAT.vecN.dot","vec<N>,vec<N>":function(a,b){return this.$vecN$dot(a,b)}},lookAt:{$mat4$lookAt:GLMAT.mat4.lookAt,"vec3,vec3":function(a,b,c){return new this.GLM.mat4(this.$mat4$lookAt(new this.GLM.$outer.Float32Array(16), -a.elements,b.elements,c.elements))}}};DLL["declare<T,V,number>"]={mix:{$quat$slerp:GLMAT.quat.slerp,"quat,quat":function(a,b,c){return new GLM.quat(this.$quat$slerp(new GLM.$outer.Float32Array(4),a.elements,b.elements,c))}}};DLL["declare<T,V,number>"].slerp=DLL["declare<T,V,number>"].mix; -DLL["declare<T>"]={normalize:{"$vec<N>normalize":"GLMAT.vecN.normalize",$typeArray:function(a){return new this.GLM.$outer.Float32Array(a)},"vec<N>":function(a){return new this.GLM.vecN(this.$vecNnormalize(this.$typeArray(N),a))},$quat$normalize:GLMAT.quat.normalize,quat:function(a){return new this.GLM.quat(this.$quat$normalize(new this.GLM.$outer.Float32Array(4),a.elements))}},length:{$quat$length:GLMAT.quat.length,quat:function(a){return this.$quat$length(a.elements)},"$vec<N>$length":"GLMAT.vecN.length", -"vec<N>":function(a){return this.$vecN$length(a.elements)}},length2:{$quat$squaredLength:GLMAT.quat.squaredLength,quat:function(a){return this.$quat$squaredLength(a.elements)},"$vec<N>$squaredLength":"GLMAT.vecN.squaredLength","vec<N>":function(a){return this.$vecN$squaredLength(a.elements)}},inverse:{$quatinvert:GLMAT.quat.invert,quat:function(a){return this.GLM.quat(this.$quatinvert(new this.GLM.$outer.Float32Array(4),a.elements))},$mat4invert:GLMAT.mat4.invert,mat4:function(a){a=a.clone();return null=== -this.$mat4invert(a.elements,a.elements)?a["="](this.GLM.mat4()):a}},transpose:{$mat4$transpose:GLMAT.mat4.transpose,mat4:function(a){a=a.clone();this.$mat4$transpose(a.elements,a.elements);return a}}};glm.$outer.$import(DLL);try{module.exports=glm}catch(e$$20){} -function $GLMVector(a,b,c){this.typearray=c=c||GLM.$outer.Float32Array;if(!(this instanceof $GLMVector))throw new GLM.GLMJSError("use new");if("function"!==typeof a||!GLM.$isGLMConstructor(a))throw new GLM.GLMJSError("expecting typ to be GLM.$isGLMConstructor: "+[typeof a,a?a.$type:a]+" // "+GLM.$isGLMConstructor(a));if(1===a.componentLength&&GLM[a.prototype.$type.replace("$","$$v")])throw new GLM.GLMJSError("unsupported argtype to glm.$vectorType - for single-value types use glm."+a.prototype.$type.replace("$", -"$$v")+"..."+a.prototype.$type);this.glmtype=a;if(!this.glmtype.componentLength)throw Error("need .componentLength "+[a,b,c]);this.componentLength=this.glmtype.componentLength;this.BYTES_PER_ELEMENT=this.glmtype.BYTES_PER_ELEMENT;this._set_$elements=function(a){Object.defineProperty(this,"$elements",{enumerable:!1,configurable:!0,value:a});return this.$elements};Object.defineProperty(this,"elements",{enumerable:!0,configurable:!0,get:function(){return this.$elements},set:function(a){this._kv&&!this._kv.dynamic&& -GLM.$DEBUG&&GLM.$outer.console.warn("WARNING: setting .elements on frozen (non-dynamic) GLMVector...");if(a){var b=this.length;this.length=a.length/this.componentLength;this.byteLength=a.length*this.BYTES_PER_ELEMENT;if(this.length!==Math.round(this.length))throw new GLM.GLMJSError("$vectorType.length alignment mismatch "+JSON.stringify({componentLength:this.componentLength,length:this.length,rounded_length:Math.round(this.length),elements_length:a.length,old_length:b}));}else this.length=this.byteLength= -0;return this._set_$elements(a)}});this.elements=b&&new c(b*a.componentLength)}GLM.$vectorType=$GLMVector;GLM.$vectorType.version="0.0.2"; -$GLMVector.prototype=GLM.$template.extend(new GLM.$GLMBaseType($GLMVector,"$vectorType"),{toString:function(){return"[$GLMVector .elements=#"+(this.elements&&this.elements.length)+" .elements[0]="+(this.elements&&this.elements[0])+" ->[0]"+(this["->"]&&this["->"][0])+"]"},"=":function(a){if(a instanceof this.constructor||glm.$isGLMObject(a))a=a.elements;return this._set(new this.typearray(a))},_typed_concat:function(a,b,c){var e=a.length+b.length;c=c||new a.constructor(e);c.set(a);c.set(b,a.length); -return c},"+":function(a){if(a instanceof this.constructor||glm.$isGLMObject(a))a=a.elements;return new this.constructor(this._typed_concat(this.elements,a))},"+=":function(a){if(a instanceof this.constructor||glm.$isGLMObject(a))a=a.elements;return this._set(this._typed_concat(this.elements,a))},_set:function(a){a instanceof this.constructor&&(a=new this.typearray(a.elements));if(!(a instanceof this.typearray))throw new GLM.GLMJSError("unsupported argtype to $GLMVector._set "+(a&&a.constructor)); -GLM.$DEBUG&&GLM.$outer.console.debug("$GLMVector.prototype.set...this.elements:"+[this.elements&&this.elements.constructor.name,this.elements&&this.elements.length]+"elements:"+[a.constructor.name,a.length]);var b=this._kv;this._kv=void 0;this.elements=a;if(this.elements!==a)throw new GLM.GLMJSError("err with .elements: "+[this.glmtype.prototype.$type,this.elements,a]);b&&this._setup(b);return this},arrayize:function(a,b){return this._setup({dynamic:b,setters:a},this.length)},$destroy:function(a){if(a){for(var b= -Array.isArray(a),c=function(c){Object.defineProperty(a,c,{enumerable:!0,configurable:!0,value:void 0});delete a[c];b||(a[c]=void 0,delete a[c])},e=0;e<a.length;e++)e in a&&c(e);for(;e in a;)GLM.$DEBUG&&GLM.$outer.console.debug("$destroy",this.name,e),c(e++);b&&(a.length=0)}},_arrlike_toJSON:function(){return this.slice(0)},_mixinArray:function(a){a.toJSON=this._arrlike_toJSON;"forEach map slice filter join reduce".split(" ").forEach(function(b){a[b]=Array.prototype[b]});return a},_setup:function(a, -b){var c=this.glmtype,e=this.typearray,d=this.length;this._kv=a;var h=a.stride||this.glmtype.BYTES_PER_ELEMENT,j=a.offset||this.elements.byteOffset,g=a.elements||this.elements,k=a.container||this.arr||[],i=a.setters||!1,w=a.dynamic||!1;"self"===k&&(k=this);if(!g)throw new GLMJSError("GLMVector._setup - neither kv.elements nor this.elements...");this.$destroy(this.arr,b);var r=this.arr=this["->"]=k;Array.isArray(r)||this._mixinArray(r);var m=this.componentLength;if(!m)throw new GLM.GLMJSError("no componentLength!?"+ -Object.keys(this));for(var q=g.buffer.byteLength,s=this,t=0;t<d;t++){var k=j+t*h,z=k+this.glmtype.BYTES_PER_ELEMENT,y=function(){a.i=t;a.next=z;a.last=q;a.offset=a.offset||j;a.stride=a.stride||h;return JSON.stringify(a)};if(k>q)throw Error("["+t+"] off "+k+" > last "+q+" "+y());if(z>q)throw Error("["+t+"] next "+z+" > last "+q+" "+y());r[t]=null;var f=function(a,b){var d=new c(new e(a.buffer,b,m));w&&Object.defineProperty(d,"$elements",{value:a});return d},y=f(g,k);!i&&!w?r[t]=y:function(a,b,c){Object.defineProperty(r, -b,{enumerable:!0,configurable:!0,get:w?function(){a.$elements!==s.elements&&(GLM.$log("dynoget rebinding ti",b,c,a.$elements===s.elements),a=f(s.elements,c));return a}:function(){return a},set:i&&(w?function(d){GLM.$log("dynoset",b,c,a.$elements===s.elements);a.$elements!==s.elements&&(GLM.$log("dynoset rebinding ti",b,c,a.$elements===s.elements),a=f(s.elements,c));return a.copy(d)}:function(b){return a.copy(b)})||void 0})}(y,t,k)}return this},setFromBuffers:function(a){var b=this.elements,c=0;a.forEach(function(a){var d= -a.length;if(c+d>b.length){d=Math.min(b.length-c,a.length);if(0>=d)return;a=glm.$subarray(a,0,d);d=a.length}if(c+d>b.length)throw new glm.GLMJSError("$vectorType.fromBuffers mismatch "+[c,d,b.length]);b.set(a,c);c+=a.length});return c},setFromPointer:function(a){if(!(a instanceof GLM.$outer.ArrayBuffer))throw new glm.GLMJSError("unsupported argtype "+[typeof a]+" - $GLMVector.setFromPointer");return this._set(new this.typearray(a))}});GLM.exists;GLM.$vectorType.exists; -if(GLM.$toTypedArray)throw"error: glm.experimental.js double-included"; -GLM.$toTypedArray=function(a,b,c){var e=b||0,d=typeof e;if("number"===d){if("number"!==typeof c)throw new GLM.GLMJSError("GLM.$toTypedArray: unsupported argtype for componentLength ("+typeof c+")");return new a(e*c)}if("object"!==d)throw new GLM.GLMJSError("GLM.$toTypedArray: unsupported arrayType: "+[typeof a,a]);if(e instanceof a)return e;if(e instanceof GLM.$outer.ArrayBuffer||Array.isArray(e))return new a(e);GLM.$isGLMObject(e)&&(d=e.elements,e=new a(d.length),e.set(d));if(!(e instanceof a)&& -"byteOffset"in e&&"buffer"in e)return GLM.$DEBUG&&GLM.$outer.console.warn("coercing "+e.constructor.name+".buffer into "+[a.name,e.byteOffset,e.byteLength+" bytes","~"+e.byteLength/a.BYTES_PER_ELEMENT+" coerced elements"]+"...",{byteOffset:e.byteOffset,byteLength:e.byteLength,ecount:e.byteLength/a.BYTES_PER_ELEMENT}),new a(e.buffer,e.byteOffset,e.byteLength/a.BYTES_PER_ELEMENT);if(e instanceof a)return e;throw new GLM.GLMJSError("GLM.$toTypedArray: unsupported argtype initializers: "+[a,b,c]);}; -GLM.$make_primitive=function(a,b){GLM[a]=function(c){if(!(this instanceof GLM[a]))return new GLM[a](c);"object"!==typeof c&&(c=[c]);this.elements=GLM.$toTypedArray(b,c,1)};GLM[a]=eval(GLM.$template._traceable("glm_"+a+"$class",GLM[a]))();GLM.$template._add_overrides(a,{$to_string:function(a){return a.$type.replace(/[^a-z]/g,"")+"("+a.elements[0]+")"},$to_object:function(a){return a.elements[0]},$to_glsl:function(a){return a.$type.replace(/[^a-z]/g,"")+"("+a.elements[0]+")"}});GLM.$template._add_overrides(a.substr(1), -{$to_string:!(a.substr(1)in GLM.$to_string.$template)&&function(a){return a.$type.replace(/[^a-z]/g,"")+"("+a.elements[0]+")"},$to_object:function(a){return a},$to_glsl:function(a){return a.$type.replace(/[^a-z]/g,"")+"("+a+")"}});GLM.$template.extend(GLM[a],{componentLength:1,BYTES_PER_ELEMENT:b.BYTES_PER_ELEMENT,prototype:GLM.$template.extend(new GLM.$GLMBaseType(GLM[a],a),{copy:function(a){this.elements.set(GLM.$isGLMObject(a)?a.elements:[a]);return this},valueOf:function(){return this.elements[0]}})}); -GLM[a].prototype["="]=GLM[a].prototype.copy;return GLM[a]};GLM.$make_primitive("$bool",GLM.$outer.Int32Array);GLM.$template._add_overrides("$bool",{$to_object:function(a){return!!a}});GLM.$make_primitive("$int32",GLM.$outer.Int32Array);GLM.$make_primitive("$uint32",GLM.$outer.Uint32Array);GLM.$make_primitive("$uint16",GLM.$outer.Uint16Array);GLM.$make_primitive("$uint8",GLM.$outer.Uint8Array);GLM.$float32=GLM.$make_primitive("$float",GLM.$outer.Float32Array); -GLM.$make_primitive_vector=function(a,b,c){c=c||(new b).elements.constructor;var e=function(d){if(!(this instanceof e))return new e(d);this.$type=a;this.$type_name="vector<"+a+">";(d=GLM.$toTypedArray(c,d,b.componentLength))&&this._set(d)},e=eval(GLM.$template._traceable("glm_"+a+"$class",e))();e.prototype=new GLM.$vectorType(b,0,c);GLM.$template._add_overrides(a,{$to_string:function(a){return"[GLM."+a.$type+" elements[0]="+(a.elements&&a.elements[0])+"]"},$to_object:function(a){return a.map(GLM.$to_object)}, -$to_glsl:function(a,b){var c=a.$type.substr(2).replace(/[^a-z]/g,"");b="string"===typeof b?b:"example";var e=[];b&&e.push(c+" "+b+"["+a.length+"]");return e.concat(a.map(function(a,c){return b+"["+c+"] = "+a})).join(";")+";"}});GLM.$types.push(a);GLM.$template.extend(e.prototype,{$type:a,constructor:e,_setup:function(){throw new GLM.GLMJSError("._setup not available on primitive vectors yet...");},_set:function(a){this.elements=a;this.length=!this.elements?0:this.elements.length/this.glmtype.componentLength; -this.arrayize();return this},arrayize:function(){for(var a=Object.defineProperty.bind(Object,this),b=0;b<this.length;b++)(function(b){a(b,{configurable:!0,enumerable:!0,get:function(){return this.elements[b]},set:function(a){return this.elements[b]=a}})})(b);return this._mixinArray(this)},toString:function(){return"[vector<"+a+"> {"+[].slice.call(this.elements,0,5)+(5<this.elements.length?",...":"")+"}]"}});return e};GLM.$vint32=GLM.$make_primitive_vector("$vint32",GLM.$int32); -GLM.$vfloat=GLM.$vfloat32=GLM.$make_primitive_vector("$vfloat32",GLM.$float32);GLM.$vuint8=GLM.$make_primitive_vector("$vuint8",GLM.$uint8);GLM.$vuint16=GLM.$make_primitive_vector("$vuint16",GLM.$uint16);GLM.$vuint32=GLM.$make_primitive_vector("$vuint32",GLM.$uint32); -GLM.$make_componentized_vector=function(a,b,c){c=c||(new b).elements.constructor;var e=function(a,h){if(!(this instanceof e))return new e(a,h);this._set(GLM.$toTypedArray(c,a,b.componentLength));if(!this.elements)throw new GLM.GLMJSError("!this.elements: "+[GLM.$toTypedArray(c,a,b.componentLength)]);this._setup({setters:!0,dynamic:h,container:"self"})},e=eval(GLM.$template._traceable("glm_"+a+"$class",e))();e.prototype=new GLM.$vectorType(b,0,c);GLM.$template._add_overrides(a,{$to_string:function(a){return"[GLM."+ -a.$type+" elements[0]="+(a.elements&&a.elements[0])+"]"},$to_object:function(a){return a.map(GLM.$to_object)},$to_glsl:function(a,b){var c=a.$type.substr(2);b="string"===typeof b?b:"example";var e=[];b&&e.push(c+" "+b+"["+a.length+"]");return e.concat(a.map(GLM.$to_glsl).map(function(a,c){return b+"["+c+"] = "+a})).join(";\n ")+";"}});GLM.$types.push(a);GLM.$template.extend(e.prototype,{$type:a,constructor:e});e.prototype.componentLength||alert("!cmop "+p);return e}; -(function(){var a=GLM.$template.deNify({"$vvec<N>":function(){return GLM.$make_componentized_vector("$vvecN",GLM.vecN)},"$vuvec<N>":function(){return GLM.$make_componentized_vector("$vuvecN",GLM.uvecN)},"$vmat<N>":function(){return GLM.$make_componentized_vector("$vmatN",GLM.matN)},$vquat:function(){return GLM.$make_componentized_vector("$vquat",GLM.quat)}},"$v"),b;for(b in a)GLM[b]=a[b]()})(); -(GLM._redefine_base64_helpers=function define_base64_helpers(b,c){function e(b){return(b+"").replace(/\s/g,"")}function d(b){return new k(b.split("").map(function(b){return b.charCodeAt(0)}))}function h(b){b instanceof k||(b=new k(b));return[].map.call(b,function(b){return String.fromCharCode(b)}).join("")}function j(b){b=b instanceof i?b:d(b).buffer;return GLM.$b64.encode(b,b.byteOffset,b.byteLength)}function g(b){b=new String(h(GLM.$b64.decode(b)));b.array=d(b);b.buffer=b.array.buffer;return b} -b=define_base64_helpers.atob=b||define_base64_helpers.atob||g;c=define_base64_helpers.btoa=c||define_base64_helpers.btoa||j;var k=GLM.$outer.Uint8Array,i=GLM.$outer.ArrayBuffer,w,r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf.bind("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");w={encode:function(b,c,d){b=new k(b,c,d);d=b.length;var e="";for(c=0;c<d;c+=3)e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[b[c]>>2],e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(b[c]& -3)<<4|b[c+1]>>4],e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(b[c+1]&15)<<2|b[c+2]>>6],e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[b[c+2]&63];2===d%3?e=e.substring(0,e.length-1)+"=":1===d%3&&(e=e.substring(0,e.length-2)+"==");return e},decode:function(b){b=e(b);var c=b.length,d=0.75*c,g=0,h,j,f,v;"="===b[c-1]&&(d--,"="===b[c-2]&&d--);for(var w=new i(d),R=new k(w),d=0;d<c;d+=4)h=r(b[d]),j=r(b[d+1]),f=r(b[d+2]),v=r(b[d+3]),R[g++]=h<<2|j>>4,R[g++]= -(j&15)<<4|f>>2,R[g++]=(f&3)<<6|v&63;return w}};GLM.$template.extend(w,{trim:e,atob:b,btoa:c,$atob:g,$btoa:j,toCharCodes:d,fromCharCodes:h,b64_to_utf8:function(c){return decodeURIComponent(escape(b(e(c))))},utf8_to_b64:function(b){return c(unescape(encodeURIComponent(b)))}});GLM.$template.extend(GLM,{$b64:w,$to_base64:function(b){return GLM.$b64.encode(b.elements.buffer,b.elements.byteOffset,b.elements.byteLength)},$from_base64:function(b,c){var d=GLM.$b64.decode(b);if(!0===c||c==GLM.$outer.ArrayBuffer)return d; -void 0===c&&(c=GLM.$outer.Float32Array);return new c(d);throw new GLM.GLMJSError("TODO: $from_base64 not yet supported second argument type: ("+[typeof c,c]+")");}})})("function"===typeof atob&&atob.bind(this),"function"===typeof btoa&&btoa.bind(this)); -(function(){function a(a,c){return{get:function(){return a.call(this)},set:function(a){if(this.copy)return this.copy(new this.constructor(c.call(this,a)));this.elements.set(c.call(this,a))}}}"$bool $float32 $vfloat32 $vuint8 $vuint16 $vuint32 $vvec2 $vvec3 $vvec4 $vmat3 $vmat4 $vquat vec2 vec3 vec4 mat3 mat4 uvec2 uvec3 uvec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 quat".split(" ").map(GLM.$getGLMType).forEach(function(b){Object.defineProperty(b.prototype,"array",a(function(){return GLM.$to_array(this)}, -function(a){return a}));Object.defineProperty(b.prototype,"base64",a(function(){return GLM.$to_base64(this)},function(a){return GLM.$from_base64(a,this.elements.constructor)}));Object.defineProperty(b.prototype,"buffer",a(function(){return this.elements.buffer},function(a){return new this.elements.constructor(a)}));Object.defineProperty(b.prototype,"json",a(function(){return GLM.$to_json(this)},function(a){return JSON.parse(a)}));Object.defineProperty(b.prototype,"object",a(function(){return GLM.$to_object(this)}, -function(a){return a}));Object.defineProperty(b.prototype,"glsl",a(function(){return GLM.$to_glsl(this)},function(a){return GLM.$from_glsl(a,Array)}))})})(); -glm.GLMAT = GLMAT; globals.glm = glm; try { module.exports = glm; } catch(e) { }; try { window.glm = glm; } catch(e) {} ; try { declare.amd && declare(function() { return glm; }); } catch(e) {}; return this.glm = glm; })(this, typeof $GLM_log !== "undefined" ? $GLM_log : undefined, typeof $GLM_console_log !== "undefined" ? $GLM_console_log : undefined); |