diff options
Diffstat (limited to 'WebCore/manual-tests/webgl')
-rw-r--r-- | WebCore/manual-tests/webgl/Earth.html | 166 | ||||
-rw-r--r-- | WebCore/manual-tests/webgl/ManyPlanetsDeep.html | 202 | ||||
-rw-r--r-- | WebCore/manual-tests/webgl/SpinningBox.html | 149 | ||||
-rw-r--r-- | WebCore/manual-tests/webgl/TeapotPerPixel.html | 332 | ||||
-rw-r--r-- | WebCore/manual-tests/webgl/TeapotPerVertex.html | 305 | ||||
-rw-r--r-- | WebCore/manual-tests/webgl/resources/CanvasMatrix.js | 698 | ||||
-rw-r--r-- | WebCore/manual-tests/webgl/resources/earthmap1k.jpg | bin | 0 -> 344080 bytes | |||
-rw-r--r-- | WebCore/manual-tests/webgl/resources/mars500x250.png | bin | 0 -> 174308 bytes | |||
-rw-r--r-- | WebCore/manual-tests/webgl/resources/teapot.obj | 2866 | ||||
-rw-r--r-- | WebCore/manual-tests/webgl/resources/utils3d.js | 531 |
10 files changed, 5249 insertions, 0 deletions
diff --git a/WebCore/manual-tests/webgl/Earth.html b/WebCore/manual-tests/webgl/Earth.html new file mode 100644 index 0000000..fa59a20 --- /dev/null +++ b/WebCore/manual-tests/webgl/Earth.html @@ -0,0 +1,166 @@ +<!DOCTYPE html> +<html> + <head> + <title>Canvas3d example</title> + <script src="resources/CanvasMatrix.js"> </script> + <script src="resources/utils3d.js"> </script> + + <script id="vshader" type="x-shader/x-vertex"> + uniform mat4 u_modelViewMatrix; + uniform mat4 u_modelViewProjMatrix; + uniform mat4 u_normalMatrix; + uniform vec3 lightDir; + + attribute vec3 vNormal; + attribute vec4 vTexCoord; + attribute vec4 vPosition; + + varying float v_Dot; + varying vec2 v_texCoord; + + void main() + { + gl_Position = u_modelViewProjMatrix * vPosition; + v_texCoord = vTexCoord.st; + vec4 transNormal = u_normalMatrix * vec4(vNormal,1); + v_Dot = max(dot(transNormal.xyz, lightDir), 0.0); + } + </script> + + <script id="fshader" type="x-shader/x-fragment"> + uniform sampler2D sampler2d; + + varying float v_Dot; + varying vec2 v_texCoord; + + void main() + { + vec4 color = texture2D(sampler2d,v_texCoord); + color += vec4(0.1,0.1,0.1,1); + gl_FragColor = vec4(color.xyz * v_Dot, color.a); + } + </script> + + <script> + function init() + { + var gl = initWebGL("example", "vshader", "fshader", + [ "vNormal", "vTexCoord", "vPosition"], + [ 0, 0, 0, 1 ], 10000); + + gl.uniform3f(gl.getUniformLocation(gl.program, "lightDir"), 0, 0, 1); + gl.uniform1i(gl.getUniformLocation(gl.program, "sampler2d"), 0); + + gl.enable(gl.TEXTURE_2D); + + gl.sphere = makeSphere(gl, 1, 30, 30); + + // get the images + earthTexture = loadImageTexture(gl, "resources/earthmap1k.jpg"); + marsTexture = loadImageTexture(gl, "resources/mars500x250.png"); + + return gl; + } + + width = -1; + height = -1; + + function reshape(ctx) + { + var canvas = document.getElementById('example'); + if (canvas.clientWidth == width && canvas.clientHeight == height) + return; + + width = canvas.clientWidth; + height = canvas.clientHeight; + + ctx.viewport(0, 0, width, height); + + ctx.perspectiveMatrix = new CanvasMatrix4(); + ctx.perspectiveMatrix.lookat(0,0,6, 0, 0, 0, 0, 1, 0); + ctx.perspectiveMatrix.perspective(30, width/height, 1, 10000); + } + + function drawOne(ctx, angle, x, y, z, scale, texture) + { + // setup VBOs + ctx.enableVertexAttribArray(0); + ctx.enableVertexAttribArray(1); + ctx.enableVertexAttribArray(2); + + ctx.bindBuffer(ctx.ARRAY_BUFFER, ctx.sphere.vertexObject); + ctx.vertexAttribPointer(2, 3, ctx.FLOAT, false, 0, 0); + + ctx.bindBuffer(ctx.ARRAY_BUFFER, ctx.sphere.normalObject); + ctx.vertexAttribPointer(0, 3, ctx.FLOAT, false, 0, 0); + + ctx.bindBuffer(ctx.ARRAY_BUFFER, ctx.sphere.texCoordObject); + ctx.vertexAttribPointer(1, 2, ctx.FLOAT, false, 0, 0); + + ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, ctx.sphere.indexObject); + + // generate the model-view matrix + var mvMatrix = new CanvasMatrix4(); + mvMatrix.scale(scale, scale, scale); + mvMatrix.rotate(angle, 0,1,0); + mvMatrix.rotate(30, 1,0,0); + mvMatrix.translate(x,y,z); + ctx.uniformMatrix4fv(ctx.getUniformLocation(ctx.program, "u_modelViewMatrix"), false, mvMatrix.getAsCanvasFloatArray()); + + // construct the normal matrix from the model-view matrix + var normalMatrix = new CanvasMatrix4(mvMatrix); + normalMatrix.invert(); + normalMatrix.transpose(); + ctx.uniformMatrix4fv(ctx.getUniformLocation(ctx.program, "u_normalMatrix"), false, normalMatrix.getAsCanvasFloatArray()); + + // construct the model-view * projection matrix + var mvpMatrix = new CanvasMatrix4(mvMatrix); + mvpMatrix.multRight(ctx.perspectiveMatrix); + ctx.uniformMatrix4fv(ctx.getUniformLocation(ctx.program, "u_modelViewProjMatrix"), false, mvpMatrix.getAsCanvasFloatArray()); + + ctx.bindTexture(ctx.TEXTURE_2D, texture); + ctx.drawElements(ctx.TRIANGLES, ctx.sphere.numIndices, ctx.UNSIGNED_SHORT, 0); + } + + function drawPicture(ctx) + { + reshape(ctx); + ctx.clear(ctx.COLOR_BUFFER_BIT | ctx.DEPTH_BUFFER_BIT); + + drawOne(ctx, currentAngle, -1, 0, 0, 1, earthTexture); + drawOne(ctx, -currentAngle, 1, 0, 0, 0.6, marsTexture); + ctx.flush(); + + framerate.snapshot(); + + currentAngle += incAngle; + if (currentAngle > 360) + currentAngle -= 360; + } + + function start() + { + var ctx = init(); + currentAngle = 0; + incAngle = 0.2; + var f = function() { drawPicture(ctx) }; + setInterval(f, 10); + framerate = new Framerate("framerate"); + } + </script> + <style type="text/css"> + canvas { + border: 2px solid black; + width:90%; + height:90%; + } + </style> + </head> + <body onload="start()"> + <canvas id="example"> + There is supposed to be an example drawing here, but it's not important. + </canvas> + <div id="framerate"></div> + <div id="console"></div> + </body> +</html> diff --git a/WebCore/manual-tests/webgl/ManyPlanetsDeep.html b/WebCore/manual-tests/webgl/ManyPlanetsDeep.html new file mode 100644 index 0000000..e5bb773 --- /dev/null +++ b/WebCore/manual-tests/webgl/ManyPlanetsDeep.html @@ -0,0 +1,202 @@ +<!DOCTYPE html> +<html> + <head> + <title>Canvas3d example</title> + <script src="resources/CanvasMatrix.js"> </script> + <script src="resources/utils3d.js"> </script> + + <script id="vshader" type="x-shader/x-vertex"> + uniform mat4 u_modelViewMatrix; + uniform mat4 u_modelViewProjMatrix; + uniform mat4 u_normalMatrix; + uniform vec3 lightDir; + + attribute vec3 vNormal; + attribute vec4 vTexCoord; + attribute vec4 vPosition; + + varying float v_Dot; + varying vec2 v_texCoord; + + void main() + { + gl_Position = u_modelViewProjMatrix * vPosition; + v_texCoord = vTexCoord.st; + vec4 transNormal = u_normalMatrix * vec4(vNormal,1); + v_Dot = max(dot(transNormal.xyz, lightDir), 0.0); + } + </script> + + <script id="fshader" type="x-shader/x-fragment"> + uniform sampler2D sampler2d; + + varying float v_Dot; + varying vec2 v_texCoord; + + void main() + { + vec4 color = texture2D(sampler2d,v_texCoord); + color += vec4(0.1,0.1,0.1,1); + gl_FragColor = vec4(color.xyz * v_Dot, color.a); + } + </script> + + <script> + const numRowCols = 4; + const numLayers = 3; + const layoutWidth = 10; + const layoutHeight = 8; + const globeSize = 25; + const minIncAngle = 0.2; + const maxIncAngle = 2; + + function init() + { + var gl = initWebGL("example", "vshader", "fshader", + [ "vNormal", "vTexCoord", "vPosition"], + [ 0, 0, 0, 1 ], 10000); + + gl.uniform3f(gl.getUniformLocation(gl.program, "lightDir"), 0, 0, 1); + gl.uniform1i(gl.getUniformLocation(gl.program, "sampler2d"), 0); + + gl.enable(gl.TEXTURE_2D); + + gl.sphere = makeSphere(gl, 1, 30, 30); + + // get the images + earthTexture = loadImageTexture(gl, "resources/earthmap1k.jpg"); + marsTexture = loadImageTexture(gl, "resources/mars500x250.png"); + + return gl; + } + + width = -1; + height = -1; + + function reshape(ctx) + { + var canvas = document.getElementById('example'); + if (canvas.clientWidth == width && canvas.clientHeight == height) + return; + + width = canvas.clientWidth; + height = canvas.clientHeight; + + ctx.viewport(0, 0, width, height); + + ctx.perspectiveMatrix = new CanvasMatrix4(); + ctx.perspectiveMatrix.lookat(0,0,20, 0, 0, 0, 0, 1, 0); + ctx.perspectiveMatrix.perspective(30, width/height, 1, 10000); + } + + function drawOne(ctx, angle, x, y, z, scale, texture) + { + // setup VBOs + ctx.enableVertexAttribArray(0); + ctx.enableVertexAttribArray(1); + ctx.enableVertexAttribArray(2); + + ctx.bindBuffer(ctx.ARRAY_BUFFER, ctx.sphere.vertexObject); + ctx.vertexAttribPointer(2, 3, ctx.FLOAT, false, 0, 0); + + ctx.bindBuffer(ctx.ARRAY_BUFFER, ctx.sphere.normalObject); + ctx.vertexAttribPointer(0, 3, ctx.FLOAT, false, 0, 0); + + ctx.bindBuffer(ctx.ARRAY_BUFFER, ctx.sphere.texCoordObject); + ctx.vertexAttribPointer(1, 2, ctx.FLOAT, false, 0, 0); + + ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, ctx.sphere.indexObject); + + // generate the model-view matrix + var mvMatrix = new CanvasMatrix4(); + mvMatrix.scale(scale, scale, scale); + mvMatrix.rotate(angle, 0,1,0); + mvMatrix.rotate(30, 1,0,0); + mvMatrix.translate(x,y,z); + ctx.uniformMatrix4fv(ctx.getUniformLocation(ctx.program, "u_modelViewMatrix"), false, mvMatrix.getAsCanvasFloatArray()); + + // construct the normal matrix from the model-view matrix + var normalMatrix = new CanvasMatrix4(mvMatrix); + normalMatrix.invert(); + normalMatrix.transpose(); + ctx.uniformMatrix4fv(ctx.getUniformLocation(ctx.program, "u_normalMatrix"), false, normalMatrix.getAsCanvasFloatArray()); + + // construct the model-view * projection matrix + var mvpMatrix = new CanvasMatrix4(mvMatrix); + mvpMatrix.multRight(ctx.perspectiveMatrix); + ctx.uniformMatrix4fv(ctx.getUniformLocation(ctx.program, "u_modelViewProjMatrix"), false, mvpMatrix.getAsCanvasFloatArray()); + + ctx.bindTexture(ctx.TEXTURE_2D, texture); + ctx.drawElements(ctx.TRIANGLES, ctx.sphere.numIndices, ctx.UNSIGNED_SHORT, 0); + } + + function drawPicture(ctx) + { + reshape(ctx); + ctx.clear(ctx.COLOR_BUFFER_BIT | ctx.DEPTH_BUFFER_BIT); + + var startX = -layoutWidth/2; + var startY = -layoutHeight/2; + var startZ = 0; + var incX = layoutWidth / (numRowCols-1); + var incY = layoutHeight / (numRowCols-1); + var incZ = -5; + + for (i = 0; i < numLayers; ++i) { + for (j = 0; j < numRowCols; ++j) { + for (k = 0; k < numRowCols; ++k) { + var index = i * numLayers * numRowCols + j * numRowCols + k; + + drawOne(ctx, currentAngles[index], + startX + incX * k, + startY + incY * j, + startZ + incZ * i, + showEarth[index] ? 1 : 0.6, showEarth[index] ? earthTexture : marsTexture); + + currentAngles[index] += incAngles[i]; + if (currentAngles[index] > 360) + currentAngles[index] -= 360; + } + } + } + + ctx.bindTexture(ctx.TEXTURE_2D, 0); + ctx.flush(); + + framerate.snapshot(); + } + + function start() + { + var ctx = init(); + currentAngles = [ ]; + incAngles = [ ]; + showEarth = [ ]; + + for (var i = 0; i < numRowCols * numRowCols * numLayers; ++i) { + currentAngles[i] = 0; + incAngles[i] = Math.random() * (maxIncAngle - minIncAngle) + minIncAngle; + showEarth[i] = Math.random() > 0.5; + } + + framerate = new Framerate("framerate"); + + var f = function() { drawPicture(ctx) }; + setInterval(f, 10); + } + </script> + <style type="text/css"> + canvas { + border: 2px solid black; + width:90%; + height:90%; + } + </style> + </head> + <body onload="start()"> + <canvas id="example"> + There is supposed to be an example drawing here, but it's not important. + </canvas> + <div id="framerate"></div> + </body> +</html> diff --git a/WebCore/manual-tests/webgl/SpinningBox.html b/WebCore/manual-tests/webgl/SpinningBox.html new file mode 100644 index 0000000..203d7bd --- /dev/null +++ b/WebCore/manual-tests/webgl/SpinningBox.html @@ -0,0 +1,149 @@ +<!DOCTYPE html> +<html> + <head> + <title>Canvas3d example</title> + <script src="resources/CanvasMatrix.js"> </script> + <script src="resources/utils3d.js"> </script> + <script id="vshader" type="x-shader/x-vertex"> + uniform mat4 pMatrix; + uniform mat4 mvMatrix; + uniform vec3 lightDir; + + attribute vec3 vNormal; + attribute vec4 vColor; + attribute vec4 vPosition; + + varying float v_Dot; + + void main() + { + gl_FrontColor = vColor; + vec4 transNormal = mvMatrix * vec4(vNormal,1); + v_Dot = max(dot(transNormal.xyz, lightDir), 0.0); + gl_Position = pMatrix * mvMatrix * vPosition; + } + </script> + + <script id="fshader" type="x-shader/x-fragment"> + varying float v_Dot; + + void main() + { + gl_FragColor = vec4(gl_Color.xyz * v_Dot, gl_Color.a); + } + </script> + + <script> + function init() + { + var gl = initWebGL("example", "vshader", "fshader", + [ "vNormal", "vColor", "vPosition"], + [ 0, 0, 0, 1 ], 10000); + + gl.uniform3f(gl.getUniformLocation(gl.program, "lightDir"), 0, 0, 1); + + gl.box = makeBox(gl); + + // color array + var colors = new CanvasUnsignedByteArray( + [ 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, // v0-v1-v2-v3 front + 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, // v0-v3-v4-v5 right + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, // v0-v5-v6-v1 top + 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, // v1-v6-v7-v2 left + 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, // v7-v4-v3-v2 bottom + 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1 ] // v4-v7-v6-v5 back + ); + + gl.box.colorObject = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, gl.box.colorObject); + gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW); + + return gl; + } + + width = -1; + height = -1; + + function reshape(gl) + { + var canvas = document.getElementById('example'); + if (canvas.clientWidth == width && canvas.clientHeight == height) + return; + + width = canvas.clientWidth; + height = canvas.clientHeight; + + gl.viewport(0, 0, width, height); + var pMatrix = new CanvasMatrix4(); + pMatrix.lookat(0,0,10, 0, 0, 0, 0, 1, 0); + pMatrix.perspective(30, width/height, 1, 10000); + gl.uniformMatrix4fv(gl.getUniformLocation(gl.program, "pMatrix"), false, pMatrix.getAsCanvasFloatArray()); + } + + function drawPicture(gl) + { + reshape(gl); + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); + + var mvMatrix = new CanvasMatrix4(); + mvMatrix.rotate(currentAngle, 0,1,0); + mvMatrix.rotate(20, 1,0,0); + gl.uniformMatrix4fv(gl.getUniformLocation(gl.program, "mvMatrix"), false, mvMatrix.getAsCanvasFloatArray()); + + gl.enableVertexAttribArray(0); + gl.enableVertexAttribArray(1); + gl.enableVertexAttribArray(2); + + gl.bindBuffer(gl.ARRAY_BUFFER, gl.box.vertexObject); + gl.vertexAttribPointer(2, 3, gl.FLOAT, false, 0, 0); + + gl.bindBuffer(gl.ARRAY_BUFFER, gl.box.normalObject); + gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); + + gl.bindBuffer(gl.ARRAY_BUFFER, gl.box.colorObject); + gl.vertexAttribPointer(1, 4, gl.UNSIGNED_BYTE, false, 0, 0); + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.box.indexObject); + gl.drawElements(gl.TRIANGLES, gl.box.numIndices, gl.UNSIGNED_BYTE, 0); + + gl.flush(); + + framerate.snapshot(); + + currentAngle += incAngle; + if (currentAngle > 360) + currentAngle -= 360; + } + + function start() + { + var gl = init(); + currentAngle = 0; + incAngle = 0.5; + framerate = new Framerate("framerate"); + setInterval(function() { drawPicture(gl) }, 10); + } + </script> + <style type="text/css"> + canvas { + border: 2px solid black; + width:90%; + height:90%; + } + .text { + position:absolute; + top:100px; + left:20px; + font-size:2em; + color: blue; + } + </style> + </head> + <body onload="start()"> + <canvas id="example"> + There is supposed to be an example drawing here, but it's not important. + </canvas> + <div class="text">This is some text under the canvas</div> + <div id="framerate"></div> + </body> +</html> diff --git a/WebCore/manual-tests/webgl/TeapotPerPixel.html b/WebCore/manual-tests/webgl/TeapotPerPixel.html new file mode 100644 index 0000000..6274c8b --- /dev/null +++ b/WebCore/manual-tests/webgl/TeapotPerPixel.html @@ -0,0 +1,332 @@ +<!DOCTYPE html> +<html> + <head> + <title>Canvas3d example</title> + <script src="resources/CanvasMatrix.js"> </script> + <script src="resources/utils3d.js"> </script> + <script id="vshader" type="x-shader/x-vertex"> + /* + Copyright (c) 2008 Seneca College + Licenced under the MIT License (http://www.c3dl.org/index.php/mit-license/) + */ + + // We need to create our own light structure since we can't access + // the light() function in the 2.0 context. + struct Light + { + vec4 ambient; + vec4 diffuse; + vec4 specular; + vec4 position; + + vec3 halfVector; + }; + + struct Material + { + vec4 emission; + vec4 ambient; + vec4 diffuse; + vec4 specular; + float shininess; + }; + + // + // vertex attributes + // + attribute vec4 a_vertex; + attribute vec3 a_normal; + attribute vec4 a_texCoord; + + // for every model we multiply the projection, view and model matrices + // once to prevent having to do it for every vertex, however we still need + // the view matrix to calculate lighting. + uniform mat4 u_modelViewMatrix; + + // we can calculate this once per model to speed up processing done on the js side. + uniform mat4 u_modelViewProjMatrix; + + // matrix to transform the vertex normals + uniform mat4 u_normalMatrix; + + // custom light structures need to be used since we don't have access to + // light states. + uniform Light u_light; + + // material + uniform vec4 u_globalAmbientColor; + uniform Material u_frontMaterial; + uniform Material u_backMaterial; + + // passed to fragment shader + varying vec4 v_diffuse, v_ambient; + varying vec3 v_normal, v_lightDir; + varying vec2 v_texCoord; + + /* + Given a reference to the ambient and diffuse lighting variables, + this function will calculate how much each component contributes to the scene. + + Light light - the light in view space + vec3 normal - + vec4 ambient - + vec4 diffuse - + */ + vec3 directionalLight(inout vec4 ambient, inout vec4 diffuse) + { + ambient += u_light.ambient; + diffuse += u_light.diffuse; + return normalize(vec3(u_light.position)); + } + + void main() + { + v_normal = normalize(u_normalMatrix * vec4(a_normal, 1)).xyz; + + vec4 ambient = vec4(0.0, 0.0, 0.0, 1.0); + vec4 diffuse = vec4(0.0, 0.0, 0.0, 1.0); + vec4 specular = vec4(0.0, 0.0, 0.0, 1.0); + + // place the current vertex into view space + // ecPos = eye coordinate position. + vec4 ecPos4 = u_modelViewMatrix * a_vertex; + + // the current vertex in eye coordinate space + vec3 ecPos = ecPos4.xyz/ecPos4.w; + v_lightDir = directionalLight(ambient, diffuse); + + v_ambient = u_frontMaterial.ambient * ambient; + v_ambient += u_globalAmbientColor * u_frontMaterial.ambient; + v_diffuse = u_frontMaterial.diffuse * diffuse; + + gl_Position = u_modelViewProjMatrix * a_vertex; + v_texCoord = a_texCoord.st; + } + </script> + + <script id="fshader" type="x-shader/x-fragment"> + struct Light + { + vec4 ambient; + vec4 diffuse; + vec4 specular; + vec4 position; + + vec3 halfVector; + }; + + struct Material + { + vec4 emission; + vec4 ambient; + vec4 diffuse; + vec4 specular; + float shininess; + }; + + uniform sampler2D u_sampler2d; + uniform Light u_light; + uniform Material u_frontMaterial; + uniform Material u_backMaterial; + + varying vec4 v_diffuse, v_ambient; + varying vec3 v_normal, v_lightDir; + varying vec2 v_texCoord; + + void main() + { + vec4 color = v_diffuse; + + vec3 n = normalize(v_normal); + + Light light = u_light; + vec3 lightDir = v_lightDir; + float nDotL = max(dot(n, lightDir), 0.0); + if (nDotL > 0.0) { + color = vec4(color.rgb * nDotL, color.a); + float nDotHV = max(dot(n, light.halfVector), 0.0); + vec4 specular = u_frontMaterial.specular * light.specular; + color += vec4(specular.rgb * pow(nDotHV, u_frontMaterial.shininess), specular.a); + } + + gl_FragColor = color + v_ambient; + } + </script> + + <script> + console.log("Hello"); + function setDirectionalLight(ctx, program, eyeVector, direction, ambient, diffuse, specular) + { + var lightString = "u_light."; + + ctx.uniform4f(ctx.getUniformLocation(program, lightString+"ambient"), + ambient[0], ambient[1], ambient[2], ambient[3]); + ctx.uniform4f(ctx.getUniformLocation(program, lightString+"diffuse"), + diffuse[0], diffuse[1], diffuse[2], diffuse[3]); + ctx.uniform4f(ctx.getUniformLocation(program, lightString+"specular"), + specular[0], specular[1], specular[2], specular[3]); + ctx.uniform4f(ctx.getUniformLocation(program, lightString+"position"), + direction[0], direction[1], direction[2], direction[3]); + + // compute the half vector + var halfVector = [ eyeVector[0] + direction[0], eyeVector[1] + direction[1], eyeVector[2] + direction[2] ]; + var length = Math.sqrt(halfVector[0] * halfVector[0] + + halfVector[1] * halfVector[1] + + halfVector[2] * halfVector[2]); + if (length == 0) + halfVector = [ 0, 0, 1 ]; + else { + halfVector[0] /= length; + halfVector[1] /= length; + halfVector[2] /= length; + } + + ctx.uniform3f(ctx.getUniformLocation(program, lightString+"halfVector"), + halfVector[0], halfVector[1], halfVector[2]); + } + + function setMaterial(ctx, program, emission, ambient, diffuse, specular, shininess) + { + var matString = "u_frontMaterial."; + ctx.uniform4f(ctx.getUniformLocation(program, matString+"emission"), + emission[0], emission[1], emission[2], emission[3]); + ctx.uniform4f(ctx.getUniformLocation(program, matString+"ambient"), + ambient[0], ambient[1], ambient[2], ambient[3]); + ctx.uniform4f(ctx.getUniformLocation(program, matString+"diffuse"), + diffuse[0], diffuse[1], diffuse[2], diffuse[3]); + ctx.uniform4f(ctx.getUniformLocation(program, matString+"specular"), + specular[0], specular[1], specular[2], specular[3]); + ctx.uniform1f(ctx.getUniformLocation(program, matString+"shininess"), shininess); + } + + function init() + { + var gl = initWebGL("example", "vshader", "fshader", + [ "a_normal", "a_texCoord", "a_vertex"], + [ 0, 0, 0, 1 ], 10000); + + gl.uniform1i(gl.getUniformLocation(gl.program, "u_sampler2d"), 0); + gl.uniform4f(gl.getUniformLocation(gl.program, "u_globalAmbientColor"), 0.2, 0.2, 0.2, 1); + + setDirectionalLight(gl, gl.program, + [ 0, 0, 1 ], // eyeVector + [0, 0, 1, 1], // position + [0.1, 0.1, 0.1, 1], // ambient + [1, 1, 1, 1], // diffuse + [1, 1, 1, 1]); // specular + + setMaterial(gl, gl.program, + [ 0, 0, 0, 0 ], // emission + [ 0.1, 0.1, 0.1, 1 ], // ambient + [ 0.8, 0.2, 0, 1 ], // diffuse + [ 0, 0, 1, 1 ], // specular + 32); // shininess + + obj = loadObj(gl, "resources/teapot.obj"); + + mvMatrix = new CanvasMatrix4(); + normalMatrix = new CanvasMatrix4(); + + return gl; + } + + width = -1; + height = -1; + loaded = false; + + function reshape(ctx) + { + var canvas = document.getElementById('example'); + if (canvas.clientWidth == width && canvas.clientHeight == height) + return; + + width = canvas.clientWidth; + height = canvas.clientHeight; + + ctx.viewport(0, 0, width, height); + + ctx.perspectiveMatrix = new CanvasMatrix4(); + ctx.perspectiveMatrix.lookat(0,0,50, 0, 0, 0, 0, 1, 0); + ctx.perspectiveMatrix.perspective(30, width/height, 1, 10000); + } + + function drawPicture(ctx) + { + var startRenderTime = new Date().getTime(); + + reshape(ctx); + ctx.clear(ctx.COLOR_BUFFER_BIT | ctx.DEPTH_BUFFER_BIT); + + if (!loaded && obj.loaded) { + loaded = true; + + ctx.enableVertexAttribArray(0); + ctx.enableVertexAttribArray(1); + ctx.enableVertexAttribArray(2); + + ctx.bindBuffer(ctx.ARRAY_BUFFER, obj.vertexObject); + ctx.vertexAttribPointer(2, 3, ctx.FLOAT, false, 0, 0); + + ctx.bindBuffer(ctx.ARRAY_BUFFER, obj.normalObject); + ctx.vertexAttribPointer(0, 3, ctx.FLOAT, false, 0, 0); + + ctx.bindBuffer(ctx.ARRAY_BUFFER, obj.texCoordObject); + ctx.vertexAttribPointer(1, 2, ctx.FLOAT, false, 0, 0); + + ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, obj.indexObject); + } + + if (!loaded) + return; + + // generate the model-view matrix + mvMatrix.makeIdentity(); + mvMatrix.rotate(currentAngle, 0, 1, 0); + mvMatrix.rotate(10, 1,0,0); + ctx.uniformMatrix4fv(ctx.getUniformLocation(ctx.program, "u_modelViewMatrix"), false, mvMatrix.getAsCanvasFloatArray()); + + // construct the normal matrix from the model-view matrix + normalMatrix.load(mvMatrix); + normalMatrix.invert(); + normalMatrix.transpose(); + ctx.uniformMatrix4fv(ctx.getUniformLocation(ctx.program, "u_normalMatrix"), false, normalMatrix.getAsCanvasFloatArray()); + + mvMatrix.multRight(ctx.perspectiveMatrix); + ctx.uniformMatrix4fv(ctx.getUniformLocation(ctx.program, "u_modelViewProjMatrix"), false, mvMatrix.getAsCanvasFloatArray()); + + ctx.drawElements(ctx.TRIANGLES, obj.numIndices, ctx.UNSIGNED_SHORT, 0); + + ctx.flush(); + + framerate.snapshot(); + + currentAngle += incAngle; + if (currentAngle > 360) + currentAngle -= 360; + } + + function start() + { + var ctx = init(); + currentAngle = 0; + incAngle = 0.2; + framerate = new Framerate("framerate"); + var f = function() { drawPicture(ctx) }; + setInterval(f, 10); + } + </script> + <style type="text/css"> + canvas { + border: 2px solid black; + width:90%; + height:90%; + } + </style> + </head> + <body onload="start()"> + <canvas id="example"> + There is supposed to be an example drawing here, but it's not important. + </canvas> + <div id="framerate"></div> + </body> +</html> diff --git a/WebCore/manual-tests/webgl/TeapotPerVertex.html b/WebCore/manual-tests/webgl/TeapotPerVertex.html new file mode 100644 index 0000000..d2544a3 --- /dev/null +++ b/WebCore/manual-tests/webgl/TeapotPerVertex.html @@ -0,0 +1,305 @@ +<!DOCTYPE html> +<html> + <head> + <title>Canvas3d example</title> + <script src="resources/CanvasMatrix.js"> </script> + <script src="resources/utils3d.js"> </script> + <script id="vshader" type="x-shader/x-vertex"> + /* + Copyright (c) 2008 Seneca College + Licenced under the MIT License (http://www.c3dl.org/index.php/mit-license/) + */ + + // We need to create our own light structure since we can't access + // the light() function in the 2.0 context. + struct Light + { + vec4 ambient; + vec4 diffuse; + vec4 specular; + vec4 position; + + vec3 halfVector; + }; + + struct Material + { + vec4 emission; + vec4 ambient; + vec4 diffuse; + vec4 specular; + float shininess; + }; + + // + // vertex attributes + // + attribute vec3 a_normal; + attribute vec4 a_texCoord; + attribute vec4 a_vertex; + + // for every model we multiply the projection, view and model matrices + // once to prevent having to do it for every vertex, however we still need + // the view matrix to calculate lighting. + uniform mat4 u_modelViewMatrix; + + // we can calculate this once per model to speed up processing done on the js side. + uniform mat4 u_modelViewProjMatrix; + + // matrix to transform the vertex normals + uniform mat4 u_normalMatrix; + + // custom light structures need to be used since we don't have access to + // light states. + uniform Light u_light; + + // material + uniform vec4 u_globalAmbientColor; + uniform Material u_frontMaterial; + uniform Material u_backMaterial; + + // passed to fragment shader + varying vec4 v_diffuse, v_specular; + varying vec2 v_texCoord; + + /* + Given a reference to the ambient and diffuse lighting variables, + this function will calculate how much each component contributes to the scene. + + Light light - the light in view space + vec3 normal - + vec4 ambient - + vec4 diffuse - + */ + void directionalLight(in vec3 normal, inout vec4 ambient, inout vec4 diffuse, inout vec4 specular) + { + vec3 lightDir = normalize(vec3(u_light.position)); + ambient += u_light.ambient; + + float nDotL = max(dot(normal, lightDir), 0.0); + if (nDotL > 0.0) { + diffuse += u_light.diffuse * nDotL; + float nDotHV = max(dot(normal, u_light.halfVector), 0.0); + nDotHV += 0.3; + vec4 specularColor = u_frontMaterial.specular * u_light.specular; + specular += vec4(specularColor.rgb * pow(nDotHV, u_frontMaterial.shininess), specularColor.a); + } + } + + void main() + { + vec3 normal = normalize(u_normalMatrix * vec4(a_normal, 1)).xyz; + + vec4 ambient = vec4(0.0, 0.0, 0.0, 1.0); + vec4 diffuse = vec4(0.0, 0.0, 0.0, 1.0); + vec4 specular = vec4(0.0, 0.0, 0.0, 1.0); + + // place the current vertex into view space + // ecPos = eye coordinate position. + vec4 ecPos4 = u_modelViewMatrix * a_vertex; + + // the current vertex in eye coordinate space + vec3 ecPos = ecPos4.xyz/ecPos4.w; + directionalLight(normal, ambient, diffuse, specular); + + ambient = u_frontMaterial.ambient * ambient; + ambient += u_globalAmbientColor * u_frontMaterial.ambient; + diffuse = u_frontMaterial.diffuse * diffuse; + + v_diffuse = diffuse; + v_specular = specular + ambient; + gl_Position = u_modelViewProjMatrix * a_vertex; + v_texCoord = a_texCoord.st; + } + </script> + + <script id="fshader" type="x-shader/x-fragment"> + uniform sampler2D u_sampler2d; + + varying vec4 v_diffuse, v_specular; + varying vec2 v_texCoord; + + void main() + { + vec4 color = v_diffuse; + + gl_FragColor = color + v_specular; + } + </script> + + <script> + function setDirectionalLight(ctx, program, eyeVector, direction, ambient, diffuse, specular) + { + var lightString = "u_light."; + + ctx.uniform4f(ctx.getUniformLocation(program, lightString+"ambient"), + ambient[0], ambient[1], ambient[2], ambient[3]); + ctx.uniform4f(ctx.getUniformLocation(program, lightString+"diffuse"), + diffuse[0], diffuse[1], diffuse[2], diffuse[3]); + ctx.uniform4f(ctx.getUniformLocation(program, lightString+"specular"), + specular[0], specular[1], specular[2], specular[3]); + ctx.uniform4f(ctx.getUniformLocation(program, lightString+"position"), + direction[0], direction[1], direction[2], direction[3]); + + // compute the half vector + var halfVector = [ eyeVector[0] + direction[0], eyeVector[1] + direction[1], eyeVector[2] + direction[2] ]; + var length = Math.sqrt(halfVector[0] * halfVector[0] + + halfVector[1] * halfVector[1] + + halfVector[2] * halfVector[2]); + if (length == 0) + halfVector = [ 0, 0, 1 ]; + else { + halfVector[0] /= length; + halfVector[1] /= length; + halfVector[2] /= length; + } + + ctx.uniform3f(ctx.getUniformLocation(program, lightString+"halfVector"), + halfVector[0], halfVector[1], halfVector[2]); + } + + function setMaterial(ctx, program, emission, ambient, diffuse, specular, shininess) + { + var matString = "u_frontMaterial."; + ctx.uniform4f(ctx.getUniformLocation(program, matString+"emission"), + emission[0], emission[1], emission[2], emission[3]); + ctx.uniform4f(ctx.getUniformLocation(program, matString+"ambient"), + ambient[0], ambient[1], ambient[2], ambient[3]); + ctx.uniform4f(ctx.getUniformLocation(program, matString+"diffuse"), + diffuse[0], diffuse[1], diffuse[2], diffuse[3]); + ctx.uniform4f(ctx.getUniformLocation(program, matString+"specular"), + specular[0], specular[1], specular[2], specular[3]); + ctx.uniform1f(ctx.getUniformLocation(program, matString+"shininess"), shininess); + } + + function init() + { + var gl = initWebGL("example", "vshader", "fshader", + [ "a_normal", "a_texCoord", "a_vertex"], + [ 0, 0, 0, 1 ], 10000); + + gl.uniform1i(gl.getUniformLocation(gl.program, "u_sampler2d"), 0); + gl.uniform4f(gl.getUniformLocation(gl.program, "u_globalAmbientColor"), 0.2, 0.2, 0.2, 1); + + setDirectionalLight(gl, gl.program, + [ 0, 0, 1 ], // eyeVector + [0, 0, 1, 1], // position + [0.1, 0.1, 0.1, 1], // ambient + [1, 1, 1, 1], // diffuse + [1, 1, 1, 1]); // specular + + setMaterial(gl, gl.program, + [ 0, 0, 0, 0 ], // emission + [ 0.1, 0.1, 0.1, 1 ], // ambient + [ 0.8, 0.2, 0, 1 ], // diffuse + [ 0, 0, 1, 1 ], // specular + 32); // shininess + + obj = loadObj(gl, "resources/teapot.obj"); + + mvMatrix = new CanvasMatrix4(); + normalMatrix = new CanvasMatrix4(); + + return gl; + } + + width = -1; + height = -1; + loaded = false; + + function reshape(ctx) + { + var canvas = document.getElementById('example'); + if (canvas.clientWidth == width && canvas.clientHeight == height) + return; + + width = canvas.clientWidth; + height = canvas.clientHeight; + + ctx.viewport(0, 0, width, height); + + ctx.perspectiveMatrix = new CanvasMatrix4(); + ctx.perspectiveMatrix.lookat(0,0,50, 0, 0, 0, 0, 1, 0); + ctx.perspectiveMatrix.perspective(30, width/height, 1, 10000); + } + + function drawPicture(ctx) + { + var startRenderTime = new Date().getTime(); + + reshape(ctx); + ctx.clear(ctx.COLOR_BUFFER_BIT | ctx.DEPTH_BUFFER_BIT); + + if (!loaded && obj.loaded) { + loaded = true; + + ctx.enableVertexAttribArray(0); + ctx.enableVertexAttribArray(1); + ctx.enableVertexAttribArray(2); + + ctx.bindBuffer(ctx.ARRAY_BUFFER, obj.normalObject); + ctx.vertexAttribPointer(0, 3, ctx.FLOAT, false, 0, 0); + + ctx.bindBuffer(ctx.ARRAY_BUFFER, obj.texCoordObject); + ctx.vertexAttribPointer(1, 2, ctx.FLOAT, false, 0, 0); + + ctx.bindBuffer(ctx.ARRAY_BUFFER, obj.vertexObject); + ctx.vertexAttribPointer(2, 3, ctx.FLOAT, false, 0, 0); + + ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, obj.indexObject); + } + + if (!loaded) + return; + + // generate the model-view matrix + mvMatrix.makeIdentity(); + mvMatrix.rotate(currentAngle, 0, 1, 0); + mvMatrix.rotate(10, 1,0,0); + ctx.uniformMatrix4fv(ctx.getUniformLocation(ctx.program, "u_modelViewMatrix"), false, mvMatrix.getAsCanvasFloatArray()); + + // construct the normal matrix from the model-view matrix + normalMatrix.load(mvMatrix); + normalMatrix.invert(); + normalMatrix.transpose(); + ctx.uniformMatrix4fv(ctx.getUniformLocation(ctx.program, "u_normalMatrix"), false, normalMatrix.getAsCanvasFloatArray()); + + mvMatrix.multRight(ctx.perspectiveMatrix); + ctx.uniformMatrix4fv(ctx.getUniformLocation(ctx.program, "u_modelViewProjMatrix"), false, mvMatrix.getAsCanvasFloatArray()); + + ctx.drawElements(ctx.TRIANGLES, obj.numIndices, ctx.UNSIGNED_SHORT, 0); + + ctx.flush(); + + framerate.snapshot(); + + currentAngle += incAngle; + if (currentAngle > 360) + currentAngle -= 360; + } + + function start() + { + var ctx = init(); + currentAngle = 0; + incAngle = 0.2; + framerate = new Framerate("framerate"); + var f = function() { drawPicture(ctx) }; + setInterval(f, 10); + } + </script> + <style type="text/css"> + canvas { + border: 2px solid black; + width:90%; + height:90%; + } + </style> + </head> + <body onload="start()"> + <canvas id="example"> + There is supposed to be an example drawing here, but it's not important. + </canvas> + <div id="framerate"></div> + </body> +</html> diff --git a/WebCore/manual-tests/webgl/resources/CanvasMatrix.js b/WebCore/manual-tests/webgl/resources/CanvasMatrix.js new file mode 100644 index 0000000..f35727f --- /dev/null +++ b/WebCore/manual-tests/webgl/resources/CanvasMatrix.js @@ -0,0 +1,698 @@ +/* + CanvasMatrix4 class + + This class implements a 4x4 matrix. It has functions which + duplicate the functionality of the OpenGL matrix stack and + glut functions. + + IDL: + + [ + Constructor(in CanvasMatrix4 matrix), // copy passed matrix into new CanvasMatrix4 + Constructor(in sequence<float> array) // create new CanvasMatrix4 with 16 floats (row major) + Constructor() // create new CanvasMatrix4 with identity matrix + ] + interface CanvasMatrix4 { + attribute float m11; + attribute float m12; + attribute float m13; + attribute float m14; + attribute float m21; + attribute float m22; + attribute float m23; + attribute float m24; + attribute float m31; + attribute float m32; + attribute float m33; + attribute float m34; + attribute float m41; + attribute float m42; + attribute float m43; + attribute float m44; + + void load(in CanvasMatrix4 matrix); // copy the values from the passed matrix + void load(in sequence<float> array); // copy 16 floats into the matrix + sequence<float> getAsArray(); // return the matrix as an array of 16 floats + CanvasFloatArray getAsCanvasFloatArray(); // return the matrix as a CanvasFloatArray with 16 values + void makeIdentity(); // replace the matrix with identity + void transpose(); // replace the matrix with its transpose + void invert(); // replace the matrix with its inverse + + void translate(in float x, in float y, in float z); // multiply the matrix by passed translation values on the right + void scale(in float x, in float y, in float z); // multiply the matrix by passed scale values on the right + void rotate(in float angle, // multiply the matrix by passed rotation values on the right + in float x, in float y, in float z); // (angle is in degrees) + void multRight(in CanvasMatrix matrix); // multiply the matrix by the passed matrix on the right + void multLeft(in CanvasMatrix matrix); // multiply the matrix by the passed matrix on the left + void ortho(in float left, in float right, // multiply the matrix by the passed ortho values on the right + in float bottom, in float top, + in float near, in float far); + void frustum(in float left, in float right, // multiply the matrix by the passed frustum values on the right + in float bottom, in float top, + in float near, in float far); + void perspective(in float fovy, in float aspect, // multiply the matrix by the passed perspective values on the right + in float zNear, in float zFar); + void lookat(in float eyex, in float eyey, in float eyez, // multiply the matrix by the passed lookat + in float ctrx, in float ctry, in float ctrz, // values on the right + in float upx, in float upy, in float upz); + } +*/ + +CanvasMatrix4 = function(m) +{ + if (typeof m == 'object') { + if ("length" in m && m.length >= 16) { + this.load(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8], m[9], m[10], m[11], m[12], m[13], m[14], m[15]); + return; + } + else if (m instanceof CanvasMatrix4) { + this.load(m); + return; + } + } + this.makeIdentity(); +} + +CanvasMatrix4.prototype.load = function() +{ + if (arguments.length == 1 && typeof arguments[0] == 'object') { + var matrix = arguments[0]; + + if ("length" in matrix && matrix.length == 16) { + this.m11 = matrix[0]; + this.m12 = matrix[1]; + this.m13 = matrix[2]; + this.m14 = matrix[3]; + + this.m21 = matrix[4]; + this.m22 = matrix[5]; + this.m23 = matrix[6]; + this.m24 = matrix[7]; + + this.m31 = matrix[8]; + this.m32 = matrix[9]; + this.m33 = matrix[10]; + this.m34 = matrix[11]; + + this.m41 = matrix[12]; + this.m42 = matrix[13]; + this.m43 = matrix[14]; + this.m44 = matrix[15]; + return; + } + + if (arguments[0] instanceof CanvasMatrix4) { + + this.m11 = matrix.m11; + this.m12 = matrix.m12; + this.m13 = matrix.m13; + this.m14 = matrix.m14; + + this.m21 = matrix.m21; + this.m22 = matrix.m22; + this.m23 = matrix.m23; + this.m24 = matrix.m24; + + this.m31 = matrix.m31; + this.m32 = matrix.m32; + this.m33 = matrix.m33; + this.m34 = matrix.m34; + + this.m41 = matrix.m41; + this.m42 = matrix.m42; + this.m43 = matrix.m43; + this.m44 = matrix.m44; + return; + } + } + + this.makeIdentity(); +} + +CanvasMatrix4.prototype.getAsArray = function() +{ + return [ + this.m11, this.m12, this.m13, this.m14, + this.m21, this.m22, this.m23, this.m24, + this.m31, this.m32, this.m33, this.m34, + this.m41, this.m42, this.m43, this.m44 + ]; +} + +CanvasMatrix4.prototype.getAsCanvasFloatArray = function() +{ + return new CanvasFloatArray(this.getAsArray()); +} + +CanvasMatrix4.prototype.makeIdentity = function() +{ + this.m11 = 1; + this.m12 = 0; + this.m13 = 0; + this.m14 = 0; + + this.m21 = 0; + this.m22 = 1; + this.m23 = 0; + this.m24 = 0; + + this.m31 = 0; + this.m32 = 0; + this.m33 = 1; + this.m34 = 0; + + this.m41 = 0; + this.m42 = 0; + this.m43 = 0; + this.m44 = 1; +} + +CanvasMatrix4.prototype.transpose = function() +{ + var tmp = this.m12; + this.m12 = this.m21; + this.m21 = tmp; + + tmp = this.m13; + this.m13 = this.m31; + this.m31 = tmp; + + tmp = this.m14; + this.m14 = this.m41; + this.m41 = tmp; + + tmp = this.m23; + this.m23 = this.m32; + this.m32 = tmp; + + tmp = this.m24; + this.m24 = this.m42; + this.m42 = tmp; + + tmp = this.m34; + this.m34 = this.m43; + this.m43 = tmp; +} + +CanvasMatrix4.prototype.invert = function() +{ + // Calculate the 4x4 determinant + // If the determinant is zero, + // then the inverse matrix is not unique. + var det = this._determinant4x4(); + + if (Math.abs(det) < 1e-8) + return null; + + this._makeAdjoint(); + + // Scale the adjoint matrix to get the inverse + this.m11 /= det; + this.m12 /= det; + this.m13 /= det; + this.m14 /= det; + + this.m21 /= det; + this.m22 /= det; + this.m23 /= det; + this.m24 /= det; + + this.m31 /= det; + this.m32 /= det; + this.m33 /= det; + this.m34 /= det; + + this.m41 /= det; + this.m42 /= det; + this.m43 /= det; + this.m44 /= det; +} + +CanvasMatrix4.prototype.translate = function(x,y,z) +{ + if (x == undefined) + x = 0; + if (y == undefined) + y = 0; + if (z == undefined) + z = 0; + + var matrix = new CanvasMatrix4(); + matrix.m41 = x; + matrix.m42 = y; + matrix.m43 = z; + + this.multRight(matrix); +} + +CanvasMatrix4.prototype.scale = function(x,y,z) +{ + if (x == undefined) + x = 1; + if (z == undefined) { + if (y == undefined) { + y = x; + z = x; + } + else + z = 1; + } + else if (y == undefined) + y = x; + + var matrix = new CanvasMatrix4(); + matrix.m11 = x; + matrix.m22 = y; + matrix.m33 = z; + + this.multRight(matrix); +} + +CanvasMatrix4.prototype.rotate = function(angle,x,y,z) +{ + // angles are in degrees. Switch to radians + angle = angle / 180 * Math.PI; + + angle /= 2; + var sinA = Math.sin(angle); + var cosA = Math.cos(angle); + var sinA2 = sinA * sinA; + + // normalize + var length = Math.sqrt(x * x + y * y + z * z); + if (length == 0) { + // bad vector, just use something reasonable + x = 0; + y = 0; + z = 1; + } else if (length != 1) { + x /= length; + y /= length; + z /= length; + } + + var mat = new CanvasMatrix4(); + + // optimize case where axis is along major axis + if (x == 1 && y == 0 && z == 0) { + mat.m11 = 1; + mat.m12 = 0; + mat.m13 = 0; + mat.m21 = 0; + mat.m22 = 1 - 2 * sinA2; + mat.m23 = 2 * sinA * cosA; + mat.m31 = 0; + mat.m32 = -2 * sinA * cosA; + mat.m33 = 1 - 2 * sinA2; + mat.m14 = mat.m24 = mat.m34 = 0; + mat.m41 = mat.m42 = mat.m43 = 0; + mat.m44 = 1; + } else if (x == 0 && y == 1 && z == 0) { + mat.m11 = 1 - 2 * sinA2; + mat.m12 = 0; + mat.m13 = -2 * sinA * cosA; + mat.m21 = 0; + mat.m22 = 1; + mat.m23 = 0; + mat.m31 = 2 * sinA * cosA; + mat.m32 = 0; + mat.m33 = 1 - 2 * sinA2; + mat.m14 = mat.m24 = mat.m34 = 0; + mat.m41 = mat.m42 = mat.m43 = 0; + mat.m44 = 1; + } else if (x == 0 && y == 0 && z == 1) { + mat.m11 = 1 - 2 * sinA2; + mat.m12 = 2 * sinA * cosA; + mat.m13 = 0; + mat.m21 = -2 * sinA * cosA; + mat.m22 = 1 - 2 * sinA2; + mat.m23 = 0; + mat.m31 = 0; + mat.m32 = 0; + mat.m33 = 1; + mat.m14 = mat.m24 = mat.m34 = 0; + mat.m41 = mat.m42 = mat.m43 = 0; + mat.m44 = 1; + } else { + var x2 = x*x; + var y2 = y*y; + var z2 = z*z; + + mat.m11 = 1 - 2 * (y2 + z2) * sinA2; + mat.m12 = 2 * (x * y * sinA2 + z * sinA * cosA); + mat.m13 = 2 * (x * z * sinA2 - y * sinA * cosA); + mat.m21 = 2 * (y * x * sinA2 - z * sinA * cosA); + mat.m22 = 1 - 2 * (z2 + x2) * sinA2; + mat.m23 = 2 * (y * z * sinA2 + x * sinA * cosA); + mat.m31 = 2 * (z * x * sinA2 + y * sinA * cosA); + mat.m32 = 2 * (z * y * sinA2 - x * sinA * cosA); + mat.m33 = 1 - 2 * (x2 + y2) * sinA2; + mat.m14 = mat.m24 = mat.m34 = 0; + mat.m41 = mat.m42 = mat.m43 = 0; + mat.m44 = 1; + } + this.multRight(mat); +} + +CanvasMatrix4.prototype.multRight = function(mat) +{ + var m11 = (this.m11 * mat.m11 + this.m12 * mat.m21 + + this.m13 * mat.m31 + this.m14 * mat.m41); + var m12 = (this.m11 * mat.m12 + this.m12 * mat.m22 + + this.m13 * mat.m32 + this.m14 * mat.m42); + var m13 = (this.m11 * mat.m13 + this.m12 * mat.m23 + + this.m13 * mat.m33 + this.m14 * mat.m43); + var m14 = (this.m11 * mat.m14 + this.m12 * mat.m24 + + this.m13 * mat.m34 + this.m14 * mat.m44); + + var m21 = (this.m21 * mat.m11 + this.m22 * mat.m21 + + this.m23 * mat.m31 + this.m24 * mat.m41); + var m22 = (this.m21 * mat.m12 + this.m22 * mat.m22 + + this.m23 * mat.m32 + this.m24 * mat.m42); + var m23 = (this.m21 * mat.m13 + this.m22 * mat.m23 + + this.m23 * mat.m33 + this.m24 * mat.m43); + var m24 = (this.m21 * mat.m14 + this.m22 * mat.m24 + + this.m23 * mat.m34 + this.m24 * mat.m44); + + var m31 = (this.m31 * mat.m11 + this.m32 * mat.m21 + + this.m33 * mat.m31 + this.m34 * mat.m41); + var m32 = (this.m31 * mat.m12 + this.m32 * mat.m22 + + this.m33 * mat.m32 + this.m34 * mat.m42); + var m33 = (this.m31 * mat.m13 + this.m32 * mat.m23 + + this.m33 * mat.m33 + this.m34 * mat.m43); + var m34 = (this.m31 * mat.m14 + this.m32 * mat.m24 + + this.m33 * mat.m34 + this.m34 * mat.m44); + + var m41 = (this.m41 * mat.m11 + this.m42 * mat.m21 + + this.m43 * mat.m31 + this.m44 * mat.m41); + var m42 = (this.m41 * mat.m12 + this.m42 * mat.m22 + + this.m43 * mat.m32 + this.m44 * mat.m42); + var m43 = (this.m41 * mat.m13 + this.m42 * mat.m23 + + this.m43 * mat.m33 + this.m44 * mat.m43); + var m44 = (this.m41 * mat.m14 + this.m42 * mat.m24 + + this.m43 * mat.m34 + this.m44 * mat.m44); + + this.m11 = m11; + this.m12 = m12; + this.m13 = m13; + this.m14 = m14; + + this.m21 = m21; + this.m22 = m22; + this.m23 = m23; + this.m24 = m24; + + this.m31 = m31; + this.m32 = m32; + this.m33 = m33; + this.m34 = m34; + + this.m41 = m41; + this.m42 = m42; + this.m43 = m43; + this.m44 = m44; +} + +CanvasMatrix4.prototype.multLeft = function(mat) +{ + var m11 = (mat.m11 * this.m11 + mat.m12 * this.m21 + + mat.m13 * this.m31 + mat.m14 * this.m41); + var m12 = (mat.m11 * this.m12 + mat.m12 * this.m22 + + mat.m13 * this.m32 + mat.m14 * this.m42); + var m13 = (mat.m11 * this.m13 + mat.m12 * this.m23 + + mat.m13 * this.m33 + mat.m14 * this.m43); + var m14 = (mat.m11 * this.m14 + mat.m12 * this.m24 + + mat.m13 * this.m34 + mat.m14 * this.m44); + + var m21 = (mat.m21 * this.m11 + mat.m22 * this.m21 + + mat.m23 * this.m31 + mat.m24 * this.m41); + var m22 = (mat.m21 * this.m12 + mat.m22 * this.m22 + + mat.m23 * this.m32 + mat.m24 * this.m42); + var m23 = (mat.m21 * this.m13 + mat.m22 * this.m23 + + mat.m23 * this.m33 + mat.m24 * this.m43); + var m24 = (mat.m21 * this.m14 + mat.m22 * this.m24 + + mat.m23 * this.m34 + mat.m24 * this.m44); + + var m31 = (mat.m31 * this.m11 + mat.m32 * this.m21 + + mat.m33 * this.m31 + mat.m34 * this.m41); + var m32 = (mat.m31 * this.m12 + mat.m32 * this.m22 + + mat.m33 * this.m32 + mat.m34 * this.m42); + var m33 = (mat.m31 * this.m13 + mat.m32 * this.m23 + + mat.m33 * this.m33 + mat.m34 * this.m43); + var m34 = (mat.m31 * this.m14 + mat.m32 * this.m24 + + mat.m33 * this.m34 + mat.m34 * this.m44); + + var m41 = (mat.m41 * this.m11 + mat.m42 * this.m21 + + mat.m43 * this.m31 + mat.m44 * this.m41); + var m42 = (mat.m41 * this.m12 + mat.m42 * this.m22 + + mat.m43 * this.m32 + mat.m44 * this.m42); + var m43 = (mat.m41 * this.m13 + mat.m42 * this.m23 + + mat.m43 * this.m33 + mat.m44 * this.m43); + var m44 = (mat.m41 * this.m14 + mat.m42 * this.m24 + + mat.m43 * this.m34 + mat.m44 * this.m44); + + this.m11 = m11; + this.m12 = m12; + this.m13 = m13; + this.m14 = m14; + + this.m21 = m21; + this.m22 = m22; + this.m23 = m23; + this.m24 = m24; + + this.m31 = m31; + this.m32 = m32; + this.m33 = m33; + this.m34 = m34; + + this.m41 = m41; + this.m42 = m42; + this.m43 = m43; + this.m44 = m44; +} + +CanvasMatrix4.prototype.ortho = function(left, right, bottom, top, near, far) +{ + var tx = (left + right) / (left - right); + var ty = (top + bottom) / (top - bottom); + var tz = (far + near) / (far - near); + + var matrix = new CanvasMatrix4(); + matrix.m11 = 2 / (left - right); + matrix.m12 = 0; + matrix.m13 = 0; + matrix.m14 = 0; + matrix.m21 = 0; + matrix.m22 = 2 / (top - bottom); + matrix.m23 = 0; + matrix.m24 = 0; + matrix.m31 = 0; + matrix.m32 = 0; + matrix.m33 = -2 / (far - near); + matrix.m34 = 0; + matrix.m41 = tx; + matrix.m42 = ty; + matrix.m43 = tz; + matrix.m44 = 1; + + this.multRight(matrix); +} + +CanvasMatrix4.prototype.frustum = function(left, right, bottom, top, near, far) +{ + var matrix = new CanvasMatrix4(); + var A = (right + left) / (right - left); + var B = (top + bottom) / (top - bottom); + var C = -(far + near) / (far - near); + var D = -(2 * far * near) / (far - near); + + matrix.m11 = (2 * near) / (right - left); + matrix.m12 = 0; + matrix.m13 = 0; + matrix.m14 = 0; + + matrix.m21 = 0; + matrix.m22 = 2 * near / (top - bottom); + matrix.m23 = 0; + matrix.m24 = 0; + + matrix.m31 = A; + matrix.m32 = B; + matrix.m33 = C; + matrix.m34 = -1; + + matrix.m41 = 0; + matrix.m42 = 0; + matrix.m43 = D; + matrix.m44 = 0; + + this.multRight(matrix); +} + +CanvasMatrix4.prototype.perspective = function(fovy, aspect, zNear, zFar) +{ + var top = Math.tan(fovy * Math.PI / 360) * zNear; + var bottom = -top; + var left = aspect * bottom; + var right = aspect * top; + this.frustum(left, right, bottom, top, zNear, zFar); +} + +CanvasMatrix4.prototype.lookat = function(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz) +{ + var matrix = new CanvasMatrix4(); + + // Make rotation matrix + + // Z vector + var zx = eyex - centerx; + var zy = eyey - centery; + var zz = eyez - centerz; + var mag = Math.sqrt(zx * zx + zy * zy + zz * zz); + if (mag) { + zx /= mag; + zy /= mag; + zz /= mag; + } + + // Y vector + var yx = upx; + var yy = upy; + var yz = upz; + + // X vector = Y cross Z + xx = yy * zz - yz * zy; + xy = -yx * zz + yz * zx; + xz = yx * zy - yy * zx; + + // Recompute Y = Z cross X + yx = zy * xz - zz * xy; + yy = -zx * xz + zz * xx; + yx = zx * xy - zy * xx; + + // cross product gives area of parallelogram, which is < 1.0 for + // non-perpendicular unit-length vectors; so normalize x, y here + + mag = Math.sqrt(xx * xx + xy * xy + xz * xz); + if (mag) { + xx /= mag; + xy /= mag; + xz /= mag; + } + + mag = Math.sqrt(yx * yx + yy * yy + yz * yz); + if (mag) { + yx /= mag; + yy /= mag; + yz /= mag; + } + + matrix.m11 = xx; + matrix.m12 = xy; + matrix.m13 = xz; + matrix.m14 = 0; + + matrix.m21 = yx; + matrix.m22 = yy; + matrix.m23 = yz; + matrix.m24 = 0; + + matrix.m31 = zx; + matrix.m32 = zy; + matrix.m33 = zz; + matrix.m34 = 0; + + matrix.m41 = 0; + matrix.m42 = 0; + matrix.m43 = 0; + matrix.m44 = 1; + matrix.translate(-eyex, -eyey, -eyez); + + this.multRight(matrix); +} + +// Support functions +CanvasMatrix4.prototype._determinant2x2 = function(a, b, c, d) +{ + return a * d - b * c; +} + +CanvasMatrix4.prototype._determinant3x3 = function(a1, a2, a3, b1, b2, b3, c1, c2, c3) +{ + return a1 * this._determinant2x2(b2, b3, c2, c3) + - b1 * this._determinant2x2(a2, a3, c2, c3) + + c1 * this._determinant2x2(a2, a3, b2, b3); +} + +CanvasMatrix4.prototype._determinant4x4 = function() +{ + var a1 = this.m11; + var b1 = this.m12; + var c1 = this.m13; + var d1 = this.m14; + + var a2 = this.m21; + var b2 = this.m22; + var c2 = this.m23; + var d2 = this.m24; + + var a3 = this.m31; + var b3 = this.m32; + var c3 = this.m33; + var d3 = this.m34; + + var a4 = this.m41; + var b4 = this.m42; + var c4 = this.m43; + var d4 = this.m44; + + return a1 * this._determinant3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4) + - b1 * this._determinant3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4) + + c1 * this._determinant3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4) + - d1 * this._determinant3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4); +} + +CanvasMatrix4.prototype._makeAdjoint = function() +{ + var a1 = this.m11; + var b1 = this.m12; + var c1 = this.m13; + var d1 = this.m14; + + var a2 = this.m21; + var b2 = this.m22; + var c2 = this.m23; + var d2 = this.m24; + + var a3 = this.m31; + var b3 = this.m32; + var c3 = this.m33; + var d3 = this.m34; + + var a4 = this.m41; + var b4 = this.m42; + var c4 = this.m43; + var d4 = this.m44; + + // Row column labeling reversed since we transpose rows & columns + this.m11 = this._determinant3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4); + this.m21 = - this._determinant3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4); + this.m31 = this._determinant3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4); + this.m41 = - this._determinant3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4); + + this.m12 = - this._determinant3x3(b1, b3, b4, c1, c3, c4, d1, d3, d4); + this.m22 = this._determinant3x3(a1, a3, a4, c1, c3, c4, d1, d3, d4); + this.m32 = - this._determinant3x3(a1, a3, a4, b1, b3, b4, d1, d3, d4); + this.m42 = this._determinant3x3(a1, a3, a4, b1, b3, b4, c1, c3, c4); + + this.m13 = this._determinant3x3(b1, b2, b4, c1, c2, c4, d1, d2, d4); + this.m23 = - this._determinant3x3(a1, a2, a4, c1, c2, c4, d1, d2, d4); + this.m33 = this._determinant3x3(a1, a2, a4, b1, b2, b4, d1, d2, d4); + this.m43 = - this._determinant3x3(a1, a2, a4, b1, b2, b4, c1, c2, c4); + + this.m14 = - this._determinant3x3(b1, b2, b3, c1, c2, c3, d1, d2, d3); + this.m24 = this._determinant3x3(a1, a2, a3, c1, c2, c3, d1, d2, d3); + this.m34 = - this._determinant3x3(a1, a2, a3, b1, b2, b3, d1, d2, d3); + this.m44 = this._determinant3x3(a1, a2, a3, b1, b2, b3, c1, c2, c3); +} diff --git a/WebCore/manual-tests/webgl/resources/earthmap1k.jpg b/WebCore/manual-tests/webgl/resources/earthmap1k.jpg Binary files differnew file mode 100644 index 0000000..7dcab8a --- /dev/null +++ b/WebCore/manual-tests/webgl/resources/earthmap1k.jpg diff --git a/WebCore/manual-tests/webgl/resources/mars500x250.png b/WebCore/manual-tests/webgl/resources/mars500x250.png Binary files differnew file mode 100644 index 0000000..f38ef09 --- /dev/null +++ b/WebCore/manual-tests/webgl/resources/mars500x250.png diff --git a/WebCore/manual-tests/webgl/resources/teapot.obj b/WebCore/manual-tests/webgl/resources/teapot.obj new file mode 100644 index 0000000..b6c6810 --- /dev/null +++ b/WebCore/manual-tests/webgl/resources/teapot.obj @@ -0,0 +1,2866 @@ +# Max2Obj Version 4.0 Mar 10th, 2001 +# +# object Teapot01 to come ... +# +v 5.929688 4.125000 0.000000 +v 5.832031 4.494141 0.000000 +v 5.945313 4.617188 0.000000 +v 6.175781 4.494141 0.000000 +v 6.429688 4.125000 0.000000 +v 5.387188 4.125000 2.747500 +v 5.297100 4.494141 2.709170 +v 5.401602 4.617188 2.753633 +v 5.614209 4.494141 2.844092 +v 5.848437 4.125000 2.943750 +v 3.899688 4.125000 4.970000 +v 3.830352 4.494141 4.900664 +v 3.910782 4.617188 4.981094 +v 4.074414 4.494141 5.144727 +v 4.254687 4.125000 5.325000 +v 1.677188 4.125000 6.457500 +v 1.638858 4.494141 6.367412 +v 1.683320 4.617188 6.471914 +v 1.773780 4.494141 6.684522 +v 1.873438 4.125000 6.918750 +v -1.070312 4.125000 7.000000 +v -1.070312 4.494141 6.902344 +v -1.070312 4.617188 7.015625 +v -1.070312 4.494141 7.246094 +v -1.070312 4.125000 7.500000 +v -4.007656 4.125000 6.457500 +v -3.859572 4.494141 6.367412 +v -3.847676 4.617188 6.471914 +v -3.917371 4.494141 6.684522 +v -4.014062 4.125000 6.918750 +v -6.209063 4.125000 4.970000 +v -6.042168 4.494141 4.900664 +v -6.072500 4.617188 4.981094 +v -6.217675 4.494141 5.144727 +v -6.395312 4.125000 5.325000 +v -7.591093 4.125000 2.747500 +v -7.464421 4.494141 2.709170 +v -7.550137 4.617188 2.753633 +v -7.755822 4.494141 2.844092 +v -7.989062 4.125000 2.943750 +v -8.070313 4.125000 0.000000 +v -7.972656 4.494141 0.000000 +v -8.085938 4.617188 0.000000 +v -8.316406 4.494141 0.000000 +v -8.570313 4.125000 0.000000 +v -7.527812 4.125000 -2.747500 +v -7.437724 4.494141 -2.709170 +v -7.542227 4.617188 -2.753633 +v -7.754834 4.494141 -2.844092 +v -7.989062 4.125000 -2.943750 +v -6.040312 4.125000 -4.970000 +v -5.970977 4.494141 -4.900664 +v -6.051406 4.617188 -4.981094 +v -6.215039 4.494141 -5.144727 +v -6.395312 4.125000 -5.325000 +v -3.817812 4.125000 -6.457500 +v -3.779482 4.494141 -6.367412 +v -3.823945 4.617188 -6.471914 +v -3.914404 4.494141 -6.684522 +v -4.014062 4.125000 -6.918750 +v -1.070312 4.125000 -7.000000 +v -1.070312 4.494141 -6.902344 +v -1.070312 4.617188 -7.015625 +v -1.070312 4.494141 -7.246094 +v -1.070312 4.125000 -7.500000 +v 1.677188 4.125000 -6.457500 +v 1.638858 4.494141 -6.367412 +v 1.683320 4.617188 -6.471914 +v 1.773780 4.494141 -6.684522 +v 1.873438 4.125000 -6.918750 +v 3.899688 4.125000 -4.970000 +v 3.830352 4.494141 -4.900664 +v 3.910782 4.617188 -4.981094 +v 4.074414 4.494141 -5.144727 +v 4.254687 4.125000 -5.325000 +v 5.387188 4.125000 -2.747500 +v 5.297100 4.494141 -2.709170 +v 5.401602 4.617188 -2.753633 +v 5.614209 4.494141 -2.844092 +v 5.848437 4.125000 -2.943750 +v 7.347656 2.162109 0.000000 +v 8.148438 0.234375 0.000000 +v 8.714844 -1.623047 0.000000 +v 8.929688 -3.375000 0.000000 +v 6.695264 2.162109 3.304053 +v 7.433985 0.234375 3.618360 +v 7.956494 -1.623047 3.840674 +v 8.154688 -3.375000 3.925000 +v 4.906446 2.162109 5.976758 +v 5.475000 0.234375 6.545312 +v 5.877149 -1.623047 6.947461 +v 6.029688 -3.375000 7.100000 +v 2.233740 2.162109 7.765576 +v 2.548047 0.234375 8.504297 +v 2.770362 -1.623047 9.026807 +v 2.854688 -3.375000 9.225000 +v -1.070312 2.162109 8.417969 +v -1.070312 0.234375 9.218750 +v -1.070312 -1.623047 9.785156 +v -1.070312 -3.375000 10.000000 +v -4.374365 2.162109 7.765576 +v -4.688672 0.234375 8.504297 +v -4.910986 -1.623047 9.026807 +v -4.995313 -3.375000 9.225000 +v -7.047071 2.162109 5.976758 +v -7.615624 0.234375 6.545312 +v -8.017773 -1.623047 6.947461 +v -8.170312 -3.375000 7.100000 +v -8.835889 2.162109 3.304053 +v -9.574610 0.234375 3.618360 +v -10.097119 -1.623047 3.840674 +v -10.295313 -3.375000 3.925000 +v -9.488281 2.162109 0.000000 +v -10.289063 0.234375 0.000000 +v -10.855469 -1.623047 0.000000 +v -11.070313 -3.375000 0.000000 +v -8.835889 2.162109 -3.304053 +v -9.574610 0.234375 -3.618360 +v -10.097119 -1.623047 -3.840674 +v -10.295313 -3.375000 -3.925000 +v -7.047071 2.162109 -5.976758 +v -7.615624 0.234375 -6.545312 +v -8.017773 -1.623047 -6.947461 +v -8.170312 -3.375000 -7.100000 +v -4.374365 2.162109 -7.765576 +v -4.688672 0.234375 -8.504297 +v -4.910986 -1.623047 -9.026807 +v -4.995313 -3.375000 -9.225000 +v -1.070312 2.162109 -8.417969 +v -1.070312 0.234375 -9.218750 +v -1.070312 -1.623047 -9.785156 +v -1.070312 -3.375000 -10.000000 +v 2.233740 2.162109 -7.765576 +v 2.548047 0.234375 -8.504297 +v 2.770362 -1.623047 -9.026807 +v 2.854688 -3.375000 -9.225000 +v 4.906446 2.162109 -5.976758 +v 5.475000 0.234375 -6.545312 +v 5.877149 -1.623047 -6.947461 +v 6.029688 -3.375000 -7.100000 +v 6.695264 2.162109 -3.304053 +v 7.433985 0.234375 -3.618360 +v 7.956494 -1.623047 -3.840674 +v 8.154688 -3.375000 -3.925000 +v 8.539063 -4.857422 0.000000 +v 7.679688 -5.953125 0.000000 +v 6.820313 -6.697266 0.000000 +v 6.429688 -7.125000 0.000000 +v 7.794336 -4.857422 3.771680 +v 7.001562 -5.953125 3.434375 +v 6.208789 -6.697266 3.097070 +v 5.848437 -7.125000 2.943750 +v 5.752343 -4.857422 6.822656 +v 5.142187 -5.953125 6.212500 +v 4.532031 -6.697266 5.602344 +v 4.254687 -7.125000 5.325000 +v 2.701367 -4.857422 8.864649 +v 2.364063 -5.953125 8.071875 +v 2.026758 -6.697266 7.279101 +v 1.873438 -7.125000 6.918750 +v -1.070312 -4.857422 9.609375 +v -1.070312 -5.953125 8.750000 +v -1.070312 -6.697266 7.890625 +v -1.070312 -7.125000 7.500000 +v -4.841992 -4.857422 8.864649 +v -4.504687 -5.953125 8.071875 +v -4.167383 -6.697266 7.279101 +v -4.014062 -7.125000 6.918750 +v -7.892968 -4.857422 6.822656 +v -7.282812 -5.953125 6.212500 +v -6.672656 -6.697266 5.602344 +v -6.395312 -7.125000 5.325000 +v -9.934961 -4.857422 3.771680 +v -9.142187 -5.953125 3.434375 +v -8.349414 -6.697266 3.097070 +v -7.989062 -7.125000 2.943750 +v -10.679688 -4.857422 0.000000 +v -9.820313 -5.953125 0.000000 +v -8.960938 -6.697266 0.000000 +v -8.570313 -7.125000 0.000000 +v -9.934961 -4.857422 -3.771680 +v -9.142187 -5.953125 -3.434375 +v -8.349414 -6.697266 -3.097070 +v -7.989062 -7.125000 -2.943750 +v -7.892968 -4.857422 -6.822656 +v -7.282812 -5.953125 -6.212500 +v -6.672656 -6.697266 -5.602344 +v -6.395312 -7.125000 -5.325000 +v -4.841992 -4.857422 -8.864649 +v -4.504687 -5.953125 -8.071875 +v -4.167383 -6.697266 -7.279101 +v -4.014062 -7.125000 -6.918750 +v -1.070312 -4.857422 -9.609375 +v -1.070312 -5.953125 -8.750000 +v -1.070312 -6.697266 -7.890625 +v -1.070312 -7.125000 -7.500000 +v 2.701367 -4.857422 -8.864649 +v 2.364063 -5.953125 -8.071875 +v 2.026758 -6.697266 -7.279101 +v 1.873438 -7.125000 -6.918750 +v 5.752343 -4.857422 -6.822656 +v 5.142187 -5.953125 -6.212500 +v 4.532031 -6.697266 -5.602344 +v 4.254687 -7.125000 -5.325000 +v 7.794336 -4.857422 -3.771680 +v 7.001562 -5.953125 -3.434375 +v 6.208789 -6.697266 -3.097070 +v 5.848437 -7.125000 -2.943750 +v 6.259766 -7.400391 0.000000 +v 5.351563 -7.640625 0.000000 +v 3.107422 -7.810547 0.000000 +v -1.070312 -7.875000 0.000000 +v 5.691685 -7.400391 2.877056 +v 4.853868 -7.640625 2.520586 +v 2.783648 -7.810547 1.639761 +v 4.134043 -7.400391 5.204355 +v 3.489219 -7.640625 4.559531 +v 1.895879 -7.810547 2.966191 +v 1.806743 -7.400391 6.761997 +v 1.450274 -7.640625 5.924180 +v 0.569448 -7.810547 3.853960 +v -1.070312 -7.400391 7.330078 +v -1.070312 -7.640625 6.421875 +v -1.070312 -7.810547 4.177734 +v -3.947368 -7.400391 6.761997 +v -3.590898 -7.640625 5.924180 +v -2.710073 -7.810547 3.853960 +v -6.274668 -7.400391 5.204355 +v -5.629844 -7.640625 4.559531 +v -4.036504 -7.810547 2.966191 +v -7.832309 -7.400391 2.877056 +v -6.994492 -7.640625 2.520586 +v -4.924272 -7.810547 1.639761 +v -8.400391 -7.400391 0.000000 +v -7.492188 -7.640625 0.000000 +v -5.248047 -7.810547 0.000000 +v -7.832309 -7.400391 -2.877056 +v -6.994492 -7.640625 -2.520586 +v -4.924272 -7.810547 -1.639761 +v -6.274668 -7.400391 -5.204355 +v -5.629844 -7.640625 -4.559531 +v -4.036504 -7.810547 -2.966191 +v -3.947368 -7.400391 -6.761997 +v -3.590898 -7.640625 -5.924180 +v -2.710073 -7.810547 -3.853960 +v -1.070312 -7.400391 -7.330078 +v -1.070312 -7.640625 -6.421875 +v -1.070312 -7.810547 -4.177734 +v 1.806743 -7.400391 -6.761997 +v 1.450274 -7.640625 -5.924180 +v 0.569448 -7.810547 -3.853960 +v 4.134043 -7.400391 -5.204355 +v 3.489219 -7.640625 -4.559531 +v 1.895879 -7.810547 -2.966191 +v 5.691685 -7.400391 -2.877056 +v 4.853868 -7.640625 -2.520586 +v 2.783648 -7.810547 -1.639761 +v -9.070313 2.250000 0.000000 +v -11.406250 2.232422 0.000000 +v -13.132813 2.109375 0.000000 +v -14.203125 1.775391 0.000000 +v -14.570313 1.125000 0.000000 +v -8.992188 2.425781 0.843750 +v -11.475830 2.405457 0.843750 +v -13.298828 2.263184 0.843750 +v -14.421631 1.877014 0.843750 +v -14.804688 1.125000 0.843750 +v -8.820313 2.812500 1.125000 +v -11.628906 2.786134 1.125000 +v -13.664063 2.601563 1.125000 +v -14.902344 2.100586 1.125000 +v -15.320313 1.125000 1.125000 +v -8.648438 3.199219 0.843750 +v -11.781982 3.166809 0.843750 +v -14.029297 2.939941 0.843750 +v -15.383057 2.324158 0.843750 +v -15.835938 1.125000 0.843750 +v -8.570313 3.375000 0.000000 +v -11.851563 3.339844 0.000000 +v -14.195313 3.093750 0.000000 +v -15.601563 2.425781 0.000000 +v -16.070313 1.125000 0.000000 +v -8.648438 3.199219 -0.843750 +v -11.781982 3.166809 -0.843750 +v -14.029297 2.939941 -0.843750 +v -15.383057 2.324158 -0.843750 +v -15.835938 1.125000 -0.843750 +v -8.820313 2.812500 -1.125000 +v -11.628906 2.786134 -1.125000 +v -13.664063 2.601563 -1.125000 +v -14.902344 2.100586 -1.125000 +v -15.320313 1.125000 -1.125000 +v -8.992188 2.425781 -0.843750 +v -11.475830 2.405457 -0.843750 +v -13.298828 2.263184 -0.843750 +v -14.421631 1.877014 -0.843750 +v -14.804688 1.125000 -0.843750 +v -14.375000 0.105469 0.000000 +v -13.757813 -1.125000 0.000000 +v -12.671875 -2.355469 0.000000 +v -11.070313 -3.375000 0.000000 +v -14.588013 0.007050 0.843750 +v -13.909180 -1.275146 0.843750 +v -12.724976 -2.540863 0.843750 +v -10.992188 -3.609375 0.843750 +v -15.056641 -0.209473 1.125000 +v -14.242188 -1.605469 1.125000 +v -12.841797 -2.948730 1.125000 +v -10.820313 -4.125000 1.125000 +v -15.525269 -0.425995 0.843750 +v -14.575195 -1.935791 0.843750 +v -12.958618 -3.356598 0.843750 +v -10.648438 -4.640625 0.843750 +v -15.738281 -0.524414 0.000000 +v -14.726563 -2.085938 0.000000 +v -13.011719 -3.541992 0.000000 +v -10.570313 -4.875000 0.000000 +v -15.525269 -0.425995 -0.843750 +v -14.575195 -1.935791 -0.843750 +v -12.958618 -3.356598 -0.843750 +v -10.648438 -4.640625 -0.843750 +v -15.056641 -0.209473 -1.125000 +v -14.242188 -1.605469 -1.125000 +v -12.841797 -2.948730 -1.125000 +v -10.820313 -4.125000 -1.125000 +v -14.588013 0.007050 -0.843750 +v -13.909180 -1.275146 -0.843750 +v -12.724976 -2.540863 -0.843750 +v -10.992188 -3.609375 -0.843750 +v 7.429688 -0.750000 0.000000 +v 9.828125 -0.199219 0.000000 +v 10.867188 1.125000 0.000000 +v 11.437500 2.730469 0.000000 +v 12.429688 4.125000 0.000000 +v 7.429688 -1.394531 1.856250 +v 10.011230 -0.677124 1.676074 +v 11.101563 0.846680 1.279688 +v 11.723145 2.629761 0.883301 +v 12.898438 4.125000 0.703125 +v 7.429688 -2.812500 2.475000 +v 10.414063 -1.728516 2.234766 +v 11.617188 0.234375 1.706250 +v 12.351563 2.408203 1.177734 +v 13.929688 4.125000 0.937500 +v 7.429688 -4.230469 1.856250 +v 10.816895 -2.779907 1.676074 +v 12.132813 -0.377930 1.279688 +v 12.979980 2.186646 0.883301 +v 14.960938 4.125000 0.703125 +v 7.429688 -4.875000 0.000000 +v 11.000000 -3.257813 0.000000 +v 12.367188 -0.656250 0.000000 +v 13.265625 2.085938 0.000000 +v 15.429688 4.125000 0.000000 +v 7.429688 -4.230469 -1.856250 +v 10.816895 -2.779907 -1.676074 +v 12.132813 -0.377930 -1.279688 +v 12.979980 2.186646 -0.883301 +v 14.960938 4.125000 -0.703125 +v 7.429688 -2.812500 -2.475000 +v 10.414063 -1.728516 -2.234766 +v 11.617188 0.234375 -1.706250 +v 12.351563 2.408203 -1.177734 +v 13.929688 4.125000 -0.937500 +v 7.429688 -1.394531 -1.856250 +v 10.011230 -0.677124 -1.676074 +v 11.101563 0.846680 -1.279688 +v 11.723145 2.629761 -0.883301 +v 12.898438 4.125000 -0.703125 +v 12.789063 4.335938 0.000000 +v 13.054688 4.406250 0.000000 +v 13.132813 4.335938 0.000000 +v 12.929688 4.125000 0.000000 +v 13.291077 4.346237 0.659180 +v 13.525879 4.422729 0.562500 +v 13.532898 4.350357 0.465820 +v 13.242188 4.125000 0.421875 +v 14.395508 4.368896 0.878906 +v 14.562500 4.458984 0.750000 +v 14.413086 4.382080 0.621094 +v 13.929688 4.125000 0.562500 +v 15.499939 4.391556 0.659180 +v 15.599121 4.495239 0.562500 +v 15.293274 4.413804 0.465820 +v 14.617188 4.125000 0.421875 +v 16.001953 4.401855 0.000000 +v 16.070313 4.511719 0.000000 +v 15.693359 4.428224 0.000000 +v 14.929688 4.125000 0.000000 +v 15.499939 4.391556 -0.659180 +v 15.599121 4.495239 -0.562500 +v 15.293274 4.413804 -0.465820 +v 14.617188 4.125000 -0.421875 +v 14.395508 4.368896 -0.878906 +v 14.562500 4.458984 -0.750000 +v 14.413086 4.382080 -0.621094 +v 13.929688 4.125000 -0.562500 +v 13.291077 4.346237 -0.659180 +v 13.525879 4.422729 -0.562500 +v 13.532898 4.350357 -0.465820 +v 13.242188 4.125000 -0.421875 +v -1.070312 7.875000 0.000000 +v 0.632813 7.628906 0.000000 +v 0.554688 7.031250 0.000000 +v -0.085937 6.292969 0.000000 +v -0.070312 5.625000 0.000000 +v 0.501414 7.628906 0.670256 +v 0.429278 7.031250 0.639395 +v -0.162029 6.292969 0.386960 +v -0.147812 5.625000 0.392500 +v 0.140489 7.628906 1.210801 +v 0.084844 7.031250 1.155156 +v -0.370879 6.292969 0.699434 +v -0.360312 5.625000 0.710000 +v -0.400056 7.628906 1.571726 +v -0.430918 7.031250 1.499590 +v -0.683352 6.292969 0.908284 +v -0.677812 5.625000 0.922500 +v -1.070312 7.628906 1.703125 +v -1.070312 7.031250 1.625000 +v -1.070312 6.292969 0.984375 +v -1.070312 5.625000 1.000000 +v -1.740569 7.628906 1.571726 +v -1.709707 7.031250 1.499590 +v -1.457273 6.292969 0.908284 +v -1.462812 5.625000 0.922500 +v -2.281113 7.628906 1.210801 +v -2.225469 7.031250 1.155156 +v -1.769746 6.292969 0.699434 +v -1.780312 5.625000 0.710000 +v -2.642038 7.628906 0.670256 +v -2.569902 7.031250 0.639395 +v -1.978596 6.292969 0.386960 +v -1.992812 5.625000 0.392500 +v -2.773438 7.628906 0.000000 +v -2.695313 7.031250 0.000000 +v -2.054687 6.292969 0.000000 +v -2.070312 5.625000 0.000000 +v -2.642038 7.628906 -0.670256 +v -2.569902 7.031250 -0.639395 +v -1.978596 6.292969 -0.386960 +v -1.992812 5.625000 -0.392500 +v -2.281113 7.628906 -1.210801 +v -2.225469 7.031250 -1.155156 +v -1.769746 6.292969 -0.699434 +v -1.780312 5.625000 -0.710000 +v -1.740569 7.628906 -1.571726 +v -1.709707 7.031250 -1.499590 +v -1.457273 6.292969 -0.908284 +v -1.462812 5.625000 -0.922500 +v -1.070312 7.628906 -1.703125 +v -1.070312 7.031250 -1.625000 +v -1.070312 6.292969 -0.984375 +v -1.070312 5.625000 -1.000000 +v -0.400056 7.628906 -1.571726 +v -0.430918 7.031250 -1.499590 +v -0.683352 6.292969 -0.908284 +v -0.677812 5.625000 -0.922500 +v 0.140489 7.628906 -1.210801 +v 0.084844 7.031250 -1.155156 +v -0.370879 6.292969 -0.699434 +v -0.360312 5.625000 -0.710000 +v 0.501414 7.628906 -0.670256 +v 0.429278 7.031250 -0.639395 +v -0.162029 6.292969 -0.386960 +v -0.147812 5.625000 -0.392500 +v 1.210938 5.179688 0.000000 +v 3.054688 4.875000 0.000000 +v 4.710938 4.570313 0.000000 +v 5.429688 4.125000 0.000000 +v 1.034141 5.179688 0.895391 +v 2.735000 4.875000 1.619062 +v 4.262891 4.570313 2.269140 +v 4.925938 4.125000 2.551250 +v 0.549375 5.179688 1.619688 +v 1.858438 4.875000 2.928750 +v 3.034375 4.570313 4.104687 +v 3.544688 4.125000 4.615000 +v -0.174922 5.179688 2.104453 +v 0.548750 4.875000 3.805313 +v 1.198828 4.570313 5.333203 +v 1.480938 4.125000 5.996250 +v -1.070312 5.179688 2.281250 +v -1.070312 4.875000 4.125000 +v -1.070312 4.570313 5.781250 +v -1.070312 4.125000 6.500000 +v -1.965703 5.179688 2.104453 +v -2.689375 4.875000 3.805313 +v -3.339453 4.570313 5.333203 +v -3.621562 4.125000 5.996250 +v -2.690000 5.179688 1.619688 +v -3.999062 4.875000 2.928750 +v -5.174999 4.570313 4.104687 +v -5.685312 4.125000 4.615000 +v -3.174765 5.179688 0.895391 +v -4.875625 4.875000 1.619062 +v -6.403516 4.570313 2.269140 +v -7.066563 4.125000 2.551250 +v -3.351562 5.179688 0.000000 +v -5.195313 4.875000 0.000000 +v -6.851563 4.570313 0.000000 +v -7.570313 4.125000 0.000000 +v -3.174765 5.179688 -0.895391 +v -4.875625 4.875000 -1.619062 +v -6.403516 4.570313 -2.269140 +v -7.066563 4.125000 -2.551250 +v -2.690000 5.179688 -1.619688 +v -3.999062 4.875000 -2.928750 +v -5.174999 4.570313 -4.104687 +v -5.685312 4.125000 -4.615000 +v -1.965703 5.179688 -2.104453 +v -2.689375 4.875000 -3.805313 +v -3.339453 4.570313 -5.333203 +v -3.621562 4.125000 -5.996250 +v -1.070312 5.179688 -2.281250 +v -1.070312 4.875000 -4.125000 +v -1.070312 4.570313 -5.781250 +v -1.070312 4.125000 -6.500000 +v -0.174922 5.179688 -2.104453 +v 0.548750 4.875000 -3.805313 +v 1.198828 4.570313 -5.333203 +v 1.480938 4.125000 -5.996250 +v 0.549375 5.179688 -1.619688 +v 1.858438 4.875000 -2.928750 +v 3.034375 4.570313 -4.104687 +v 3.544688 4.125000 -4.615000 +v 1.034141 5.179688 -0.895391 +v 2.735000 4.875000 -1.619062 +v 4.262891 4.570313 -2.269140 +v 4.925938 4.125000 -2.551250 +# 530 vertices + +vt 2.000000 2.000000 0.000000 +vt 2.000000 1.975000 0.000000 +vt 2.000000 1.950000 0.000000 +vt 2.000000 1.925000 0.000000 +vt 2.000000 1.900000 0.000000 +vt 1.750000 2.000000 0.000000 +vt 1.750000 1.975000 0.000000 +vt 1.750000 1.950000 0.000000 +vt 1.750000 1.925000 0.000000 +vt 1.750000 1.900000 0.000000 +vt 1.500000 2.000000 0.000000 +vt 1.500000 1.975000 0.000000 +vt 1.500000 1.950000 0.000000 +vt 1.500000 1.925000 0.000000 +vt 1.500000 1.900000 0.000000 +vt 1.250000 2.000000 0.000000 +vt 1.250000 1.975000 0.000000 +vt 1.250000 1.950000 0.000000 +vt 1.250000 1.925000 0.000000 +vt 1.250000 1.900000 0.000000 +vt 1.000000 2.000000 0.000000 +vt 1.000000 1.975000 0.000000 +vt 1.000000 1.950000 0.000000 +vt 1.000000 1.925000 0.000000 +vt 1.000000 1.900000 0.000000 +vt 1.000000 2.000000 0.000000 +vt 1.000000 1.975000 0.000000 +vt 1.000000 1.950000 0.000000 +vt 1.000000 1.925000 0.000000 +vt 1.000000 1.900000 0.000000 +vt 0.750000 2.000000 0.000000 +vt 0.750000 1.975000 0.000000 +vt 0.750000 1.950000 0.000000 +vt 0.750000 1.925000 0.000000 +vt 0.750000 1.900000 0.000000 +vt 0.500000 2.000000 0.000000 +vt 0.500000 1.975000 0.000000 +vt 0.500000 1.950000 0.000000 +vt 0.500000 1.925000 0.000000 +vt 0.500000 1.900000 0.000000 +vt 0.250000 2.000000 0.000000 +vt 0.250000 1.975000 0.000000 +vt 0.250000 1.950000 0.000000 +vt 0.250000 1.925000 0.000000 +vt 0.250000 1.900000 0.000000 +vt 0.000000 2.000000 0.000000 +vt 0.000000 1.975000 0.000000 +vt 0.000000 1.950000 0.000000 +vt 0.000000 1.925000 0.000000 +vt 0.000000 1.900000 0.000000 +vt 2.000000 2.000000 0.000000 +vt 2.000000 1.975000 0.000000 +vt 2.000000 1.950000 0.000000 +vt 2.000000 1.925000 0.000000 +vt 2.000000 1.900000 0.000000 +vt 1.750000 2.000000 0.000000 +vt 1.750000 1.975000 0.000000 +vt 1.750000 1.950000 0.000000 +vt 1.750000 1.925000 0.000000 +vt 1.750000 1.900000 0.000000 +vt 1.500000 2.000000 0.000000 +vt 1.500000 1.975000 0.000000 +vt 1.500000 1.950000 0.000000 +vt 1.500000 1.925000 0.000000 +vt 1.500000 1.900000 0.000000 +vt 1.250000 2.000000 0.000000 +vt 1.250000 1.975000 0.000000 +vt 1.250000 1.950000 0.000000 +vt 1.250000 1.925000 0.000000 +vt 1.250000 1.900000 0.000000 +vt 1.000000 2.000000 0.000000 +vt 1.000000 1.975000 0.000000 +vt 1.000000 1.950000 0.000000 +vt 1.000000 1.925000 0.000000 +vt 1.000000 1.900000 0.000000 +vt 1.000000 2.000000 0.000000 +vt 1.000000 1.975000 0.000000 +vt 1.000000 1.950000 0.000000 +vt 1.000000 1.925000 0.000000 +vt 1.000000 1.900000 0.000000 +vt 0.750000 2.000000 0.000000 +vt 0.750000 1.975000 0.000000 +vt 0.750000 1.950000 0.000000 +vt 0.750000 1.925000 0.000000 +vt 0.750000 1.900000 0.000000 +vt 0.500000 2.000000 0.000000 +vt 0.500000 1.975000 0.000000 +vt 0.500000 1.950000 0.000000 +vt 0.500000 1.925000 0.000000 +vt 0.500000 1.900000 0.000000 +vt 0.250000 2.000000 0.000000 +vt 0.250000 1.975000 0.000000 +vt 0.250000 1.950000 0.000000 +vt 0.250000 1.925000 0.000000 +vt 0.250000 1.900000 0.000000 +vt 0.000000 2.000000 0.000000 +vt 0.000000 1.975000 0.000000 +vt 0.000000 1.950000 0.000000 +vt 0.000000 1.925000 0.000000 +vt 0.000000 1.900000 0.000000 +vt 2.000000 1.900000 0.000000 +vt 2.000000 1.675000 0.000000 +vt 2.000000 1.450000 0.000000 +vt 2.000000 1.225000 0.000000 +vt 2.000000 1.000000 0.000000 +vt 1.750000 1.900000 0.000000 +vt 1.750000 1.675000 0.000000 +vt 1.750000 1.450000 0.000000 +vt 1.750000 1.225000 0.000000 +vt 1.750000 1.000000 0.000000 +vt 1.500000 1.900000 0.000000 +vt 1.500000 1.675000 0.000000 +vt 1.500000 1.450000 0.000000 +vt 1.500000 1.225000 0.000000 +vt 1.500000 1.000000 0.000000 +vt 1.250000 1.900000 0.000000 +vt 1.250000 1.675000 0.000000 +vt 1.250000 1.450000 0.000000 +vt 1.250000 1.225000 0.000000 +vt 1.250000 1.000000 0.000000 +vt 1.000000 1.900000 0.000000 +vt 1.000000 1.675000 0.000000 +vt 1.000000 1.450000 0.000000 +vt 1.000000 1.225000 0.000000 +vt 1.000000 1.000000 0.000000 +vt 1.000000 1.900000 0.000000 +vt 1.000000 1.675000 0.000000 +vt 1.000000 1.450000 0.000000 +vt 1.000000 1.225000 0.000000 +vt 1.000000 1.000000 0.000000 +vt 0.750000 1.900000 0.000000 +vt 0.750000 1.675000 0.000000 +vt 0.750000 1.450000 0.000000 +vt 0.750000 1.225000 0.000000 +vt 0.750000 1.000000 0.000000 +vt 0.500000 1.900000 0.000000 +vt 0.500000 1.675000 0.000000 +vt 0.500000 1.450000 0.000000 +vt 0.500000 1.225000 0.000000 +vt 0.500000 1.000000 0.000000 +vt 0.250000 1.900000 0.000000 +vt 0.250000 1.675000 0.000000 +vt 0.250000 1.450000 0.000000 +vt 0.250000 1.225000 0.000000 +vt 0.250000 1.000000 0.000000 +vt 0.000000 1.900000 0.000000 +vt 0.000000 1.675000 0.000000 +vt 0.000000 1.450000 0.000000 +vt 0.000000 1.225000 0.000000 +vt 0.000000 1.000000 0.000000 +vt 2.000000 1.900000 0.000000 +vt 2.000000 1.675000 0.000000 +vt 2.000000 1.450000 0.000000 +vt 2.000000 1.225000 0.000000 +vt 2.000000 1.000000 0.000000 +vt 1.750000 1.900000 0.000000 +vt 1.750000 1.675000 0.000000 +vt 1.750000 1.450000 0.000000 +vt 1.750000 1.225000 0.000000 +vt 1.750000 1.000000 0.000000 +vt 1.500000 1.900000 0.000000 +vt 1.500000 1.675000 0.000000 +vt 1.500000 1.450000 0.000000 +vt 1.500000 1.225000 0.000000 +vt 1.500000 1.000000 0.000000 +vt 1.250000 1.900000 0.000000 +vt 1.250000 1.675000 0.000000 +vt 1.250000 1.450000 0.000000 +vt 1.250000 1.225000 0.000000 +vt 1.250000 1.000000 0.000000 +vt 1.000000 1.900000 0.000000 +vt 1.000000 1.675000 0.000000 +vt 1.000000 1.450000 0.000000 +vt 1.000000 1.225000 0.000000 +vt 1.000000 1.000000 0.000000 +vt 1.000000 1.900000 0.000000 +vt 1.000000 1.675000 0.000000 +vt 1.000000 1.450000 0.000000 +vt 1.000000 1.225000 0.000000 +vt 1.000000 1.000000 0.000000 +vt 0.750000 1.900000 0.000000 +vt 0.750000 1.675000 0.000000 +vt 0.750000 1.450000 0.000000 +vt 0.750000 1.225000 0.000000 +vt 0.750000 1.000000 0.000000 +vt 0.500000 1.900000 0.000000 +vt 0.500000 1.675000 0.000000 +vt 0.500000 1.450000 0.000000 +vt 0.500000 1.225000 0.000000 +vt 0.500000 1.000000 0.000000 +vt 0.250000 1.900000 0.000000 +vt 0.250000 1.675000 0.000000 +vt 0.250000 1.450000 0.000000 +vt 0.250000 1.225000 0.000000 +vt 0.250000 1.000000 0.000000 +vt 0.000000 1.900000 0.000000 +vt 0.000000 1.675000 0.000000 +vt 0.000000 1.450000 0.000000 +vt 0.000000 1.225000 0.000000 +vt 0.000000 1.000000 0.000000 +vt 2.000000 1.000000 0.000000 +vt 2.000000 0.850000 0.000000 +vt 2.000000 0.700000 0.000000 +vt 2.000000 0.550000 0.000000 +vt 2.000000 0.400000 0.000000 +vt 1.750000 1.000000 0.000000 +vt 1.750000 0.850000 0.000000 +vt 1.750000 0.700000 0.000000 +vt 1.750000 0.550000 0.000000 +vt 1.750000 0.400000 0.000000 +vt 1.500000 1.000000 0.000000 +vt 1.500000 0.850000 0.000000 +vt 1.500000 0.700000 0.000000 +vt 1.500000 0.550000 0.000000 +vt 1.500000 0.400000 0.000000 +vt 1.250000 1.000000 0.000000 +vt 1.250000 0.850000 0.000000 +vt 1.250000 0.700000 0.000000 +vt 1.250000 0.550000 0.000000 +vt 1.250000 0.400000 0.000000 +vt 1.000000 1.000000 0.000000 +vt 1.000000 0.850000 0.000000 +vt 1.000000 0.700000 0.000000 +vt 1.000000 0.550000 0.000000 +vt 1.000000 0.400000 0.000000 +vt 1.000000 1.000000 0.000000 +vt 1.000000 0.850000 0.000000 +vt 1.000000 0.700000 0.000000 +vt 1.000000 0.550000 0.000000 +vt 1.000000 0.400000 0.000000 +vt 0.750000 1.000000 0.000000 +vt 0.750000 0.850000 0.000000 +vt 0.750000 0.700000 0.000000 +vt 0.750000 0.550000 0.000000 +vt 0.750000 0.400000 0.000000 +vt 0.500000 1.000000 0.000000 +vt 0.500000 0.850000 0.000000 +vt 0.500000 0.700000 0.000000 +vt 0.500000 0.550000 0.000000 +vt 0.500000 0.400000 0.000000 +vt 0.250000 1.000000 0.000000 +vt 0.250000 0.850000 0.000000 +vt 0.250000 0.700000 0.000000 +vt 0.250000 0.550000 0.000000 +vt 0.250000 0.400000 0.000000 +vt 0.000000 1.000000 0.000000 +vt 0.000000 0.850000 0.000000 +vt 0.000000 0.700000 0.000000 +vt 0.000000 0.550000 0.000000 +vt 0.000000 0.400000 0.000000 +vt 2.000000 1.000000 0.000000 +vt 2.000000 0.850000 0.000000 +vt 2.000000 0.700000 0.000000 +vt 2.000000 0.550000 0.000000 +vt 2.000000 0.400000 0.000000 +vt 1.750000 1.000000 0.000000 +vt 1.750000 0.850000 0.000000 +vt 1.750000 0.700000 0.000000 +vt 1.750000 0.550000 0.000000 +vt 1.750000 0.400000 0.000000 +vt 1.500000 1.000000 0.000000 +vt 1.500000 0.850000 0.000000 +vt 1.500000 0.700000 0.000000 +vt 1.500000 0.550000 0.000000 +vt 1.500000 0.400000 0.000000 +vt 1.250000 1.000000 0.000000 +vt 1.250000 0.850000 0.000000 +vt 1.250000 0.700000 0.000000 +vt 1.250000 0.550000 0.000000 +vt 1.250000 0.400000 0.000000 +vt 1.000000 1.000000 0.000000 +vt 1.000000 0.850000 0.000000 +vt 1.000000 0.700000 0.000000 +vt 1.000000 0.550000 0.000000 +vt 1.000000 0.400000 0.000000 +vt 1.000000 1.000000 0.000000 +vt 1.000000 0.850000 0.000000 +vt 1.000000 0.700000 0.000000 +vt 1.000000 0.550000 0.000000 +vt 1.000000 0.400000 0.000000 +vt 0.750000 1.000000 0.000000 +vt 0.750000 0.850000 0.000000 +vt 0.750000 0.700000 0.000000 +vt 0.750000 0.550000 0.000000 +vt 0.750000 0.400000 0.000000 +vt 0.500000 1.000000 0.000000 +vt 0.500000 0.850000 0.000000 +vt 0.500000 0.700000 0.000000 +vt 0.500000 0.550000 0.000000 +vt 0.500000 0.400000 0.000000 +vt 0.250000 1.000000 0.000000 +vt 0.250000 0.850000 0.000000 +vt 0.250000 0.700000 0.000000 +vt 0.250000 0.550000 0.000000 +vt 0.250000 0.400000 0.000000 +vt 0.000000 1.000000 0.000000 +vt 0.000000 0.850000 0.000000 +vt 0.000000 0.700000 0.000000 +vt 0.000000 0.550000 0.000000 +vt 0.000000 0.400000 0.000000 +vt 2.000000 0.400000 0.000000 +vt 2.000000 0.300000 0.000000 +vt 2.000000 0.200000 0.000000 +vt 2.000000 0.100000 0.000000 +vt 2.000000 0.000000 0.000000 +vt 1.750000 0.400000 0.000000 +vt 1.750000 0.300000 0.000000 +vt 1.750000 0.200000 0.000000 +vt 1.750000 0.100000 0.000000 +vt 1.750000 0.000000 0.000000 +vt 1.500000 0.400000 0.000000 +vt 1.500000 0.300000 0.000000 +vt 1.500000 0.200000 0.000000 +vt 1.500000 0.100000 0.000000 +vt 1.500000 0.000000 0.000000 +vt 1.250000 0.400000 0.000000 +vt 1.250000 0.300000 0.000000 +vt 1.250000 0.200000 0.000000 +vt 1.250000 0.100000 0.000000 +vt 1.250000 0.000000 0.000000 +vt 1.000000 0.400000 0.000000 +vt 1.000000 0.300000 0.000000 +vt 1.000000 0.200000 0.000000 +vt 1.000000 0.100000 0.000000 +vt 1.000000 0.000000 0.000000 +vt 1.000000 0.400000 0.000000 +vt 1.000000 0.300000 0.000000 +vt 1.000000 0.200000 0.000000 +vt 1.000000 0.100000 0.000000 +vt 1.000000 0.000000 0.000000 +vt 0.750000 0.400000 0.000000 +vt 0.750000 0.300000 0.000000 +vt 0.750000 0.200000 0.000000 +vt 0.750000 0.100000 0.000000 +vt 0.750000 0.000000 0.000000 +vt 0.500000 0.400000 0.000000 +vt 0.500000 0.300000 0.000000 +vt 0.500000 0.200000 0.000000 +vt 0.500000 0.100000 0.000000 +vt 0.500000 0.000000 0.000000 +vt 0.250000 0.400000 0.000000 +vt 0.250000 0.300000 0.000000 +vt 0.250000 0.200000 0.000000 +vt 0.250000 0.100000 0.000000 +vt 0.250000 0.000000 0.000000 +vt 0.000000 0.400000 0.000000 +vt 0.000000 0.300000 0.000000 +vt 0.000000 0.200000 0.000000 +vt 0.000000 0.100000 0.000000 +vt 0.000000 0.000000 0.000000 +vt 2.000000 0.400000 0.000000 +vt 2.000000 0.300000 0.000000 +vt 2.000000 0.200000 0.000000 +vt 2.000000 0.100000 0.000000 +vt 2.000000 0.000000 0.000000 +vt 1.750000 0.400000 0.000000 +vt 1.750000 0.300000 0.000000 +vt 1.750000 0.200000 0.000000 +vt 1.750000 0.100000 0.000000 +vt 1.750000 0.000000 0.000000 +vt 1.500000 0.400000 0.000000 +vt 1.500000 0.300000 0.000000 +vt 1.500000 0.200000 0.000000 +vt 1.500000 0.100000 0.000000 +vt 1.500000 0.000000 0.000000 +vt 1.250000 0.400000 0.000000 +vt 1.250000 0.300000 0.000000 +vt 1.250000 0.200000 0.000000 +vt 1.250000 0.100000 0.000000 +vt 1.250000 0.000000 0.000000 +vt 1.000000 0.400000 0.000000 +vt 1.000000 0.300000 0.000000 +vt 1.000000 0.200000 0.000000 +vt 1.000000 0.100000 0.000000 +vt 1.000000 0.000000 0.000000 +vt 1.000000 0.400000 0.000000 +vt 1.000000 0.300000 0.000000 +vt 1.000000 0.200000 0.000000 +vt 1.000000 0.100000 0.000000 +vt 1.000000 0.000000 0.000000 +vt 0.750000 0.400000 0.000000 +vt 0.750000 0.300000 0.000000 +vt 0.750000 0.200000 0.000000 +vt 0.750000 0.100000 0.000000 +vt 0.750000 0.000000 0.000000 +vt 0.500000 0.400000 0.000000 +vt 0.500000 0.300000 0.000000 +vt 0.500000 0.200000 0.000000 +vt 0.500000 0.100000 0.000000 +vt 0.500000 0.000000 0.000000 +vt 0.250000 0.400000 0.000000 +vt 0.250000 0.300000 0.000000 +vt 0.250000 0.200000 0.000000 +vt 0.250000 0.100000 0.000000 +vt 0.250000 0.000000 0.000000 +vt 0.000000 0.400000 0.000000 +vt 0.000000 0.300000 0.000000 +vt 0.000000 0.200000 0.000000 +vt 0.000000 0.100000 0.000000 +vt 0.000000 0.000000 0.000000 +vt 1.000000 1.000000 0.000000 +vt 1.000000 0.875000 0.000000 +vt 1.000000 0.750000 0.000000 +vt 1.000000 0.625000 0.000000 +vt 1.000000 0.500000 0.000000 +vt 0.875000 1.000000 0.000000 +vt 0.875000 0.875000 0.000000 +vt 0.875000 0.750000 0.000000 +vt 0.875000 0.625000 0.000000 +vt 0.875000 0.500000 0.000000 +vt 0.750000 1.000000 0.000000 +vt 0.750000 0.875000 0.000000 +vt 0.750000 0.750000 0.000000 +vt 0.750000 0.625000 0.000000 +vt 0.750000 0.500000 0.000000 +vt 0.625000 1.000000 0.000000 +vt 0.625000 0.875000 0.000000 +vt 0.625000 0.750000 0.000000 +vt 0.625000 0.625000 0.000000 +vt 0.625000 0.500000 0.000000 +vt 0.500000 1.000000 0.000000 +vt 0.500000 0.875000 0.000000 +vt 0.500000 0.750000 0.000000 +vt 0.500000 0.625000 0.000000 +vt 0.500000 0.500000 0.000000 +vt 0.500000 1.000000 0.000000 +vt 0.500000 0.875000 0.000000 +vt 0.500000 0.750000 0.000000 +vt 0.500000 0.625000 0.000000 +vt 0.500000 0.500000 0.000000 +vt 0.375000 1.000000 0.000000 +vt 0.375000 0.875000 0.000000 +vt 0.375000 0.750000 0.000000 +vt 0.375000 0.625000 0.000000 +vt 0.375000 0.500000 0.000000 +vt 0.250000 1.000000 0.000000 +vt 0.250000 0.875000 0.000000 +vt 0.250000 0.750000 0.000000 +vt 0.250000 0.625000 0.000000 +vt 0.250000 0.500000 0.000000 +vt 0.125000 1.000000 0.000000 +vt 0.125000 0.875000 0.000000 +vt 0.125000 0.750000 0.000000 +vt 0.125000 0.625000 0.000000 +vt 0.125000 0.500000 0.000000 +vt 0.000000 1.000000 0.000000 +vt 0.000000 0.875000 0.000000 +vt 0.000000 0.750000 0.000000 +vt 0.000000 0.625000 0.000000 +vt 0.000000 0.500000 0.000000 +vt 1.000000 0.500000 0.000000 +vt 1.000000 0.375000 0.000000 +vt 1.000000 0.250000 0.000000 +vt 1.000000 0.125000 0.000000 +vt 1.000000 0.000000 0.000000 +vt 0.875000 0.500000 0.000000 +vt 0.875000 0.375000 0.000000 +vt 0.875000 0.250000 0.000000 +vt 0.875000 0.125000 0.000000 +vt 0.875000 0.000000 0.000000 +vt 0.750000 0.500000 0.000000 +vt 0.750000 0.375000 0.000000 +vt 0.750000 0.250000 0.000000 +vt 0.750000 0.125000 0.000000 +vt 0.750000 0.000000 0.000000 +vt 0.625000 0.500000 0.000000 +vt 0.625000 0.375000 0.000000 +vt 0.625000 0.250000 0.000000 +vt 0.625000 0.125000 0.000000 +vt 0.625000 0.000000 0.000000 +vt 0.500000 0.500000 0.000000 +vt 0.500000 0.375000 0.000000 +vt 0.500000 0.250000 0.000000 +vt 0.500000 0.125000 0.000000 +vt 0.500000 0.000000 0.000000 +vt 0.500000 0.500000 0.000000 +vt 0.500000 0.375000 0.000000 +vt 0.500000 0.250000 0.000000 +vt 0.500000 0.125000 0.000000 +vt 0.500000 0.000000 0.000000 +vt 0.375000 0.500000 0.000000 +vt 0.375000 0.375000 0.000000 +vt 0.375000 0.250000 0.000000 +vt 0.375000 0.125000 0.000000 +vt 0.375000 0.000000 0.000000 +vt 0.250000 0.500000 0.000000 +vt 0.250000 0.375000 0.000000 +vt 0.250000 0.250000 0.000000 +vt 0.250000 0.125000 0.000000 +vt 0.250000 0.000000 0.000000 +vt 0.125000 0.500000 0.000000 +vt 0.125000 0.375000 0.000000 +vt 0.125000 0.250000 0.000000 +vt 0.125000 0.125000 0.000000 +vt 0.125000 0.000000 0.000000 +vt 0.000000 0.500000 0.000000 +vt 0.000000 0.375000 0.000000 +vt 0.000000 0.250000 0.000000 +vt 0.000000 0.125000 0.000000 +vt 0.000000 0.000000 0.000000 +vt 0.500000 0.000000 0.000000 +vt 0.500000 0.225000 0.000000 +vt 0.500000 0.450000 0.000000 +vt 0.500000 0.675000 0.000000 +vt 0.500000 0.900000 0.000000 +vt 0.625000 0.000000 0.000000 +vt 0.625000 0.225000 0.000000 +vt 0.625000 0.450000 0.000000 +vt 0.625000 0.675000 0.000000 +vt 0.625000 0.900000 0.000000 +vt 0.750000 0.000000 0.000000 +vt 0.750000 0.225000 0.000000 +vt 0.750000 0.450000 0.000000 +vt 0.750000 0.675000 0.000000 +vt 0.750000 0.900000 0.000000 +vt 0.875000 0.000000 0.000000 +vt 0.875000 0.225000 0.000000 +vt 0.875000 0.450000 0.000000 +vt 0.875000 0.675000 0.000000 +vt 0.875000 0.900000 0.000000 +vt 1.000000 0.000000 0.000000 +vt 1.000000 0.225000 0.000000 +vt 1.000000 0.450000 0.000000 +vt 1.000000 0.675000 0.000000 +vt 1.000000 0.900000 0.000000 +vt 0.000000 0.000000 0.000000 +vt 0.000000 0.225000 0.000000 +vt 0.000000 0.450000 0.000000 +vt 0.000000 0.675000 0.000000 +vt 0.000000 0.900000 0.000000 +vt 0.125000 0.000000 0.000000 +vt 0.125000 0.225000 0.000000 +vt 0.125000 0.450000 0.000000 +vt 0.125000 0.675000 0.000000 +vt 0.125000 0.900000 0.000000 +vt 0.250000 0.000000 0.000000 +vt 0.250000 0.225000 0.000000 +vt 0.250000 0.450000 0.000000 +vt 0.250000 0.675000 0.000000 +vt 0.250000 0.900000 0.000000 +vt 0.375000 0.000000 0.000000 +vt 0.375000 0.225000 0.000000 +vt 0.375000 0.450000 0.000000 +vt 0.375000 0.675000 0.000000 +vt 0.375000 0.900000 0.000000 +vt 0.500000 0.000000 0.000000 +vt 0.500000 0.225000 0.000000 +vt 0.500000 0.450000 0.000000 +vt 0.500000 0.675000 0.000000 +vt 0.500000 0.900000 0.000000 +vt 0.500000 0.900000 0.000000 +vt 0.500000 0.925000 0.000000 +vt 0.500000 0.950000 0.000000 +vt 0.500000 0.975000 0.000000 +vt 0.500000 1.000000 0.000000 +vt 0.625000 0.900000 0.000000 +vt 0.625000 0.925000 0.000000 +vt 0.625000 0.950000 0.000000 +vt 0.625000 0.975000 0.000000 +vt 0.625000 1.000000 0.000000 +vt 0.750000 0.900000 0.000000 +vt 0.750000 0.925000 0.000000 +vt 0.750000 0.950000 0.000000 +vt 0.750000 0.975000 0.000000 +vt 0.750000 1.000000 0.000000 +vt 0.875000 0.900000 0.000000 +vt 0.875000 0.925000 0.000000 +vt 0.875000 0.950000 0.000000 +vt 0.875000 0.975000 0.000000 +vt 0.875000 1.000000 0.000000 +vt 1.000000 0.900000 0.000000 +vt 1.000000 0.925000 0.000000 +vt 1.000000 0.950000 0.000000 +vt 1.000000 0.975000 0.000000 +vt 1.000000 1.000000 0.000000 +vt 0.000000 0.900000 0.000000 +vt 0.000000 0.925000 0.000000 +vt 0.000000 0.950000 0.000000 +vt 0.000000 0.975000 0.000000 +vt 0.000000 1.000000 0.000000 +vt 0.125000 0.900000 0.000000 +vt 0.125000 0.925000 0.000000 +vt 0.125000 0.950000 0.000000 +vt 0.125000 0.975000 0.000000 +vt 0.125000 1.000000 0.000000 +vt 0.250000 0.900000 0.000000 +vt 0.250000 0.925000 0.000000 +vt 0.250000 0.950000 0.000000 +vt 0.250000 0.975000 0.000000 +vt 0.250000 1.000000 0.000000 +vt 0.375000 0.900000 0.000000 +vt 0.375000 0.925000 0.000000 +vt 0.375000 0.950000 0.000000 +vt 0.375000 0.975000 0.000000 +vt 0.375000 1.000000 0.000000 +vt 0.500000 0.900000 0.000000 +vt 0.500000 0.925000 0.000000 +vt 0.500000 0.950000 0.000000 +vt 0.500000 0.975000 0.000000 +vt 0.500000 1.000000 0.000000 +vt 1.000000 1.000000 0.000000 +vt 1.000000 0.750000 0.000000 +vt 1.000000 0.500000 0.000000 +vt 1.000000 0.250000 0.000000 +vt 1.000000 0.000000 0.000000 +vt 0.875000 1.000000 0.000000 +vt 0.875000 0.750000 0.000000 +vt 0.875000 0.500000 0.000000 +vt 0.875000 0.250000 0.000000 +vt 0.875000 0.000000 0.000000 +vt 0.750000 1.000000 0.000000 +vt 0.750000 0.750000 0.000000 +vt 0.750000 0.500000 0.000000 +vt 0.750000 0.250000 0.000000 +vt 0.750000 0.000000 0.000000 +vt 0.625000 1.000000 0.000000 +vt 0.625000 0.750000 0.000000 +vt 0.625000 0.500000 0.000000 +vt 0.625000 0.250000 0.000000 +vt 0.625000 0.000000 0.000000 +vt 0.500000 1.000000 0.000000 +vt 0.500000 0.750000 0.000000 +vt 0.500000 0.500000 0.000000 +vt 0.500000 0.250000 0.000000 +vt 0.500000 0.000000 0.000000 +vt 0.500000 1.000000 0.000000 +vt 0.500000 0.750000 0.000000 +vt 0.500000 0.500000 0.000000 +vt 0.500000 0.250000 0.000000 +vt 0.500000 0.000000 0.000000 +vt 0.375000 1.000000 0.000000 +vt 0.375000 0.750000 0.000000 +vt 0.375000 0.500000 0.000000 +vt 0.375000 0.250000 0.000000 +vt 0.375000 0.000000 0.000000 +vt 0.250000 1.000000 0.000000 +vt 0.250000 0.750000 0.000000 +vt 0.250000 0.500000 0.000000 +vt 0.250000 0.250000 0.000000 +vt 0.250000 0.000000 0.000000 +vt 0.125000 1.000000 0.000000 +vt 0.125000 0.750000 0.000000 +vt 0.125000 0.500000 0.000000 +vt 0.125000 0.250000 0.000000 +vt 0.125000 0.000000 0.000000 +vt 0.000000 1.000000 0.000000 +vt 0.000000 0.750000 0.000000 +vt 0.000000 0.500000 0.000000 +vt 0.000000 0.250000 0.000000 +vt 0.000000 0.000000 0.000000 +vt 1.000000 1.000000 0.000000 +vt 1.000000 0.750000 0.000000 +vt 1.000000 0.500000 0.000000 +vt 1.000000 0.250000 0.000000 +vt 1.000000 0.000000 0.000000 +vt 0.875000 1.000000 0.000000 +vt 0.875000 0.750000 0.000000 +vt 0.875000 0.500000 0.000000 +vt 0.875000 0.250000 0.000000 +vt 0.875000 0.000000 0.000000 +vt 0.750000 1.000000 0.000000 +vt 0.750000 0.750000 0.000000 +vt 0.750000 0.500000 0.000000 +vt 0.750000 0.250000 0.000000 +vt 0.750000 0.000000 0.000000 +vt 0.625000 1.000000 0.000000 +vt 0.625000 0.750000 0.000000 +vt 0.625000 0.500000 0.000000 +vt 0.625000 0.250000 0.000000 +vt 0.625000 0.000000 0.000000 +vt 0.500000 1.000000 0.000000 +vt 0.500000 0.750000 0.000000 +vt 0.500000 0.500000 0.000000 +vt 0.500000 0.250000 0.000000 +vt 0.500000 0.000000 0.000000 +vt 0.500000 1.000000 0.000000 +vt 0.500000 0.750000 0.000000 +vt 0.500000 0.500000 0.000000 +vt 0.500000 0.250000 0.000000 +vt 0.500000 0.000000 0.000000 +vt 0.375000 1.000000 0.000000 +vt 0.375000 0.750000 0.000000 +vt 0.375000 0.500000 0.000000 +vt 0.375000 0.250000 0.000000 +vt 0.375000 0.000000 0.000000 +vt 0.250000 1.000000 0.000000 +vt 0.250000 0.750000 0.000000 +vt 0.250000 0.500000 0.000000 +vt 0.250000 0.250000 0.000000 +vt 0.250000 0.000000 0.000000 +vt 0.125000 1.000000 0.000000 +vt 0.125000 0.750000 0.000000 +vt 0.125000 0.500000 0.000000 +vt 0.125000 0.250000 0.000000 +vt 0.125000 0.000000 0.000000 +vt 0.000000 1.000000 0.000000 +vt 0.000000 0.750000 0.000000 +vt 0.000000 0.500000 0.000000 +vt 0.000000 0.250000 0.000000 +vt 0.000000 0.000000 0.000000 +vt 1.000000 1.000000 0.000000 +vt 1.000000 0.750000 0.000000 +vt 1.000000 0.500000 0.000000 +vt 1.000000 0.250000 0.000000 +vt 1.000000 0.000000 0.000000 +vt 0.875000 1.000000 0.000000 +vt 0.875000 0.750000 0.000000 +vt 0.875000 0.500000 0.000000 +vt 0.875000 0.250000 0.000000 +vt 0.875000 0.000000 0.000000 +vt 0.750000 1.000000 0.000000 +vt 0.750000 0.750000 0.000000 +vt 0.750000 0.500000 0.000000 +vt 0.750000 0.250000 0.000000 +vt 0.750000 0.000000 0.000000 +vt 0.625000 1.000000 0.000000 +vt 0.625000 0.750000 0.000000 +vt 0.625000 0.500000 0.000000 +vt 0.625000 0.250000 0.000000 +vt 0.625000 0.000000 0.000000 +vt 0.500000 1.000000 0.000000 +vt 0.500000 0.750000 0.000000 +vt 0.500000 0.500000 0.000000 +vt 0.500000 0.250000 0.000000 +vt 0.500000 0.000000 0.000000 +vt 0.500000 1.000000 0.000000 +vt 0.500000 0.750000 0.000000 +vt 0.500000 0.500000 0.000000 +vt 0.500000 0.250000 0.000000 +vt 0.500000 0.000000 0.000000 +vt 0.375000 1.000000 0.000000 +vt 0.375000 0.750000 0.000000 +vt 0.375000 0.500000 0.000000 +vt 0.375000 0.250000 0.000000 +vt 0.375000 0.000000 0.000000 +vt 0.250000 1.000000 0.000000 +vt 0.250000 0.750000 0.000000 +vt 0.250000 0.500000 0.000000 +vt 0.250000 0.250000 0.000000 +vt 0.250000 0.000000 0.000000 +vt 0.125000 1.000000 0.000000 +vt 0.125000 0.750000 0.000000 +vt 0.125000 0.500000 0.000000 +vt 0.125000 0.250000 0.000000 +vt 0.125000 0.000000 0.000000 +vt 0.000000 1.000000 0.000000 +vt 0.000000 0.750000 0.000000 +vt 0.000000 0.500000 0.000000 +vt 0.000000 0.250000 0.000000 +vt 0.000000 0.000000 0.000000 +vt 1.000000 1.000000 0.000000 +vt 1.000000 0.750000 0.000000 +vt 1.000000 0.500000 0.000000 +vt 1.000000 0.250000 0.000000 +vt 1.000000 0.000000 0.000000 +vt 0.875000 1.000000 0.000000 +vt 0.875000 0.750000 0.000000 +vt 0.875000 0.500000 0.000000 +vt 0.875000 0.250000 0.000000 +vt 0.875000 0.000000 0.000000 +vt 0.750000 1.000000 0.000000 +vt 0.750000 0.750000 0.000000 +vt 0.750000 0.500000 0.000000 +vt 0.750000 0.250000 0.000000 +vt 0.750000 0.000000 0.000000 +vt 0.625000 1.000000 0.000000 +vt 0.625000 0.750000 0.000000 +vt 0.625000 0.500000 0.000000 +vt 0.625000 0.250000 0.000000 +vt 0.625000 0.000000 0.000000 +vt 0.500000 1.000000 0.000000 +vt 0.500000 0.750000 0.000000 +vt 0.500000 0.500000 0.000000 +vt 0.500000 0.250000 0.000000 +vt 0.500000 0.000000 0.000000 +vt 0.500000 1.000000 0.000000 +vt 0.500000 0.750000 0.000000 +vt 0.500000 0.500000 0.000000 +vt 0.500000 0.250000 0.000000 +vt 0.500000 0.000000 0.000000 +vt 0.375000 1.000000 0.000000 +vt 0.375000 0.750000 0.000000 +vt 0.375000 0.500000 0.000000 +vt 0.375000 0.250000 0.000000 +vt 0.375000 0.000000 0.000000 +vt 0.250000 1.000000 0.000000 +vt 0.250000 0.750000 0.000000 +vt 0.250000 0.500000 0.000000 +vt 0.250000 0.250000 0.000000 +vt 0.250000 0.000000 0.000000 +vt 0.125000 1.000000 0.000000 +vt 0.125000 0.750000 0.000000 +vt 0.125000 0.500000 0.000000 +vt 0.125000 0.250000 0.000000 +vt 0.125000 0.000000 0.000000 +vt 0.000000 1.000000 0.000000 +vt 0.000000 0.750000 0.000000 +vt 0.000000 0.500000 0.000000 +vt 0.000000 0.250000 0.000000 +vt 0.000000 0.000000 0.000000 +# 800 texture vertices + +vn -0.966742 -0.255752 0.000000 +vn -0.966824 0.255443 0.000000 +vn -0.092052 0.995754 0.000000 +vn 0.682050 0.731305 0.000000 +vn 0.870301 0.492521 0.000000 +vn -0.893014 -0.256345 -0.369882 +vn -0.893437 0.255996 -0.369102 +vn -0.083877 0.995843 -0.035507 +vn 0.629724 0.731860 0.260439 +vn 0.803725 0.493370 0.332584 +vn -0.683407 -0.256728 -0.683407 +vn -0.683531 0.256068 -0.683531 +vn -0.064925 0.995776 -0.064925 +vn 0.481399 0.732469 0.481399 +vn 0.614804 0.493997 0.614804 +vn -0.369882 -0.256345 -0.893014 +vn -0.369102 0.255996 -0.893437 +vn -0.035507 0.995843 -0.083877 +vn 0.260439 0.731860 0.629724 +vn 0.332584 0.493369 0.803725 +vn -0.002848 -0.257863 -0.966177 +vn -0.001923 0.254736 -0.967009 +vn -0.000266 0.995734 -0.092270 +vn 0.000024 0.731295 0.682061 +vn -0.000000 0.492521 0.870301 +vn 0.379058 -0.359300 -0.852771 +vn 0.377110 0.149085 -0.914091 +vn 0.027502 0.992081 -0.122552 +vn -0.261010 0.726762 0.635367 +vn -0.332485 0.492546 0.804271 +vn 0.663548 -0.410790 -0.625264 +vn 0.712664 0.073722 -0.697621 +vn 0.099726 0.987509 -0.121983 +vn -0.487320 0.723754 0.488569 +vn -0.615242 0.492602 0.615484 +vn 0.880028 -0.332906 -0.338709 +vn 0.917276 0.167113 -0.361493 +vn 0.113584 0.992365 -0.048070 +vn -0.634150 0.727508 0.261889 +vn -0.804126 0.492634 0.332705 +vn 0.966690 -0.255738 0.010454 +vn 0.967442 0.252962 0.008103 +vn 0.093436 0.995624 0.001281 +vn -0.682167 0.731196 -0.000343 +vn -0.870322 0.492483 -0.000054 +vn 0.893014 -0.256345 0.369882 +vn 0.893437 0.255996 0.369102 +vn 0.083877 0.995843 0.035507 +vn -0.629724 0.731860 -0.260439 +vn -0.803725 0.493370 -0.332584 +vn 0.683407 -0.256728 0.683407 +vn 0.683531 0.256068 0.683531 +vn 0.064925 0.995776 0.064925 +vn -0.481399 0.732469 -0.481399 +vn -0.614804 0.493997 -0.614804 +vn 0.369882 -0.256345 0.893014 +vn 0.369102 0.255996 0.893437 +vn 0.035507 0.995843 0.083877 +vn -0.260439 0.731860 -0.629724 +vn -0.332584 0.493369 -0.803725 +vn 0.000000 -0.255752 0.966742 +vn 0.000000 0.255443 0.966824 +vn 0.000000 0.995754 0.092052 +vn 0.000000 0.731305 -0.682050 +vn 0.000000 0.492521 -0.870301 +vn -0.369882 -0.256345 0.893014 +vn -0.369102 0.255996 0.893437 +vn -0.035507 0.995843 0.083877 +vn 0.260439 0.731860 -0.629724 +vn 0.332584 0.493370 -0.803725 +vn -0.683407 -0.256728 0.683407 +vn -0.683531 0.256068 0.683531 +vn -0.064925 0.995776 0.064925 +vn 0.481399 0.732469 -0.481399 +vn 0.614804 0.493997 -0.614804 +vn -0.893014 -0.256345 0.369882 +vn -0.893437 0.255996 0.369102 +vn -0.083877 0.995843 0.035507 +vn 0.629724 0.731860 -0.260439 +vn 0.803725 0.493369 -0.332584 +vn 0.915321 0.402725 -0.000000 +vn 0.941808 0.336151 0.000000 +vn 0.978690 0.205342 0.000000 +vn 0.997804 -0.066240 -0.000000 +vn 0.845438 0.403546 0.349835 +vn 0.869996 0.336859 0.360047 +vn 0.904193 0.205791 0.374280 +vn 0.921879 -0.066370 0.381752 +vn 0.646802 0.404096 0.646802 +vn 0.665655 0.337351 0.665655 +vn 0.691923 0.206120 0.691923 +vn 0.705543 -0.066480 0.705542 +vn 0.349835 0.403546 0.845438 +vn 0.360047 0.336859 0.869996 +vn 0.374280 0.205791 0.904193 +vn 0.381752 -0.066369 0.921879 +vn 0.000000 0.402725 0.915321 +vn -0.000000 0.336151 0.941808 +vn 0.000000 0.205342 0.978690 +vn 0.000000 -0.066240 0.997804 +vn -0.349835 0.403546 0.845438 +vn -0.360047 0.336859 0.869996 +vn -0.374280 0.205791 0.904193 +vn -0.381752 -0.066370 0.921879 +vn -0.646802 0.404096 0.646802 +vn -0.665655 0.337351 0.665655 +vn -0.691923 0.206120 0.691923 +vn -0.705542 -0.066480 0.705543 +vn -0.845438 0.403546 0.349835 +vn -0.869996 0.336859 0.360047 +vn -0.904193 0.205791 0.374280 +vn -0.921879 -0.066369 0.381752 +vn -0.915321 0.402725 0.000000 +vn -0.941808 0.336151 -0.000000 +vn -0.978690 0.205342 0.000000 +vn -0.997804 -0.066240 0.000000 +vn -0.845438 0.403546 -0.349835 +vn -0.869996 0.336859 -0.360047 +vn -0.904193 0.205791 -0.374280 +vn -0.921879 -0.066370 -0.381752 +vn -0.646802 0.404096 -0.646802 +vn -0.665655 0.337351 -0.665655 +vn -0.691923 0.206120 -0.691923 +vn -0.705543 -0.066480 -0.705542 +vn -0.349835 0.403546 -0.845438 +vn -0.360047 0.336859 -0.869996 +vn -0.374280 0.205791 -0.904193 +vn -0.381752 -0.066369 -0.921879 +vn -0.000000 0.402725 -0.915321 +vn 0.000000 0.336151 -0.941808 +vn -0.000000 0.205342 -0.978690 +vn -0.000000 -0.066240 -0.997804 +vn 0.349835 0.403546 -0.845438 +vn 0.360047 0.336859 -0.869996 +vn 0.374280 0.205791 -0.904193 +vn 0.381752 -0.066370 -0.921879 +vn 0.646802 0.404096 -0.646802 +vn 0.665655 0.337351 -0.665655 +vn 0.691923 0.206120 -0.691923 +vn 0.705542 -0.066480 -0.705543 +vn 0.845438 0.403546 -0.349835 +vn 0.869996 0.336859 -0.360047 +vn 0.904193 0.205791 -0.374280 +vn 0.921879 -0.066369 -0.381752 +vn 0.900182 -0.435513 0.000000 +vn 0.729611 -0.683863 0.000000 +vn 0.693951 -0.720022 -0.000000 +vn 0.793950 -0.607983 0.000000 +vn 0.831437 -0.436180 0.344179 +vn 0.673512 -0.684666 0.278594 +vn 0.640399 -0.720924 0.264874 +vn 0.732949 -0.608995 0.303167 +vn 0.636092 -0.436778 0.636092 +vn 0.514965 -0.685290 0.514965 +vn 0.489651 -0.721446 0.489651 +vn 0.560555 -0.609554 0.560555 +vn 0.344179 -0.436180 0.831437 +vn 0.278595 -0.684666 0.673512 +vn 0.264874 -0.720924 0.640399 +vn 0.303167 -0.608995 0.732949 +vn -0.000000 -0.435513 0.900182 +vn -0.000000 -0.683863 0.729611 +vn 0.000000 -0.720022 0.693951 +vn -0.000000 -0.607983 0.793950 +vn -0.344179 -0.436180 0.831437 +vn -0.278594 -0.684666 0.673512 +vn -0.264874 -0.720924 0.640399 +vn -0.303167 -0.608995 0.732949 +vn -0.636092 -0.436778 0.636092 +vn -0.514965 -0.685290 0.514965 +vn -0.489651 -0.721446 0.489651 +vn -0.560555 -0.609554 0.560555 +vn -0.831437 -0.436180 0.344179 +vn -0.673512 -0.684666 0.278595 +vn -0.640399 -0.720924 0.264874 +vn -0.732949 -0.608995 0.303167 +vn -0.900182 -0.435513 -0.000000 +vn -0.729611 -0.683863 -0.000000 +vn -0.693951 -0.720022 0.000000 +vn -0.793950 -0.607983 -0.000000 +vn -0.831437 -0.436180 -0.344179 +vn -0.673512 -0.684666 -0.278594 +vn -0.640399 -0.720924 -0.264874 +vn -0.732949 -0.608995 -0.303167 +vn -0.636092 -0.436778 -0.636092 +vn -0.514965 -0.685290 -0.514965 +vn -0.489651 -0.721446 -0.489651 +vn -0.560555 -0.609554 -0.560555 +vn -0.344179 -0.436180 -0.831437 +vn -0.278595 -0.684666 -0.673512 +vn -0.264874 -0.720924 -0.640399 +vn -0.303167 -0.608995 -0.732949 +vn 0.000000 -0.435513 -0.900182 +vn 0.000000 -0.683863 -0.729611 +vn -0.000000 -0.720022 -0.693951 +vn 0.000000 -0.607983 -0.793950 +vn 0.344179 -0.436180 -0.831437 +vn 0.278594 -0.684666 -0.673512 +vn 0.264874 -0.720924 -0.640399 +vn 0.303167 -0.608995 -0.732949 +vn 0.636092 -0.436778 -0.636092 +vn 0.514965 -0.685290 -0.514965 +vn 0.489651 -0.721446 -0.489651 +vn 0.560555 -0.609554 -0.560555 +vn 0.831437 -0.436180 -0.344179 +vn 0.673512 -0.684666 -0.278595 +vn 0.640399 -0.720924 -0.264874 +vn 0.732949 -0.608995 -0.303167 +vn 0.623860 -0.781536 0.000000 +vn 0.177291 -0.984159 -0.000000 +vn 0.049207 -0.998789 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.576230 -0.781801 0.238217 +vn 0.163628 -0.984208 0.067527 +vn 0.045422 -0.998792 0.018736 +vn 0.440416 -0.782348 0.440416 +vn 0.124903 -0.984276 0.124903 +vn 0.034662 -0.998798 0.034662 +vn 0.238217 -0.781801 0.576230 +vn 0.067527 -0.984208 0.163628 +vn 0.018736 -0.998792 0.045422 +vn -0.000000 -0.781536 0.623860 +vn 0.000000 -0.984159 0.177291 +vn -0.000000 -0.998789 0.049207 +vn -0.238217 -0.781801 0.576230 +vn -0.067527 -0.984208 0.163628 +vn -0.018736 -0.998792 0.045422 +vn -0.440416 -0.782348 0.440416 +vn -0.124903 -0.984276 0.124903 +vn -0.034662 -0.998798 0.034662 +vn -0.576230 -0.781801 0.238217 +vn -0.163628 -0.984208 0.067527 +vn -0.045422 -0.998792 0.018736 +vn -0.623860 -0.781536 -0.000000 +vn -0.177291 -0.984159 0.000000 +vn -0.049207 -0.998789 -0.000000 +vn -0.576230 -0.781801 -0.238217 +vn -0.163628 -0.984208 -0.067527 +vn -0.045422 -0.998792 -0.018736 +vn -0.440416 -0.782348 -0.440416 +vn -0.124903 -0.984276 -0.124903 +vn -0.034662 -0.998798 -0.034662 +vn -0.238217 -0.781801 -0.576230 +vn -0.067527 -0.984208 -0.163628 +vn -0.018736 -0.998792 -0.045422 +vn 0.000000 -0.781536 -0.623860 +vn -0.000000 -0.984159 -0.177291 +vn 0.000000 -0.998789 -0.049207 +vn 0.238217 -0.781801 -0.576230 +vn 0.067527 -0.984208 -0.163628 +vn 0.018736 -0.998792 -0.045422 +vn 0.440416 -0.782348 -0.440416 +vn 0.124903 -0.984276 -0.124903 +vn 0.034662 -0.998798 -0.034662 +vn 0.576230 -0.781801 -0.238217 +vn 0.163628 -0.984208 -0.067527 +vn 0.045422 -0.998792 -0.018736 +vn 0.007786 -0.999970 -0.000216 +vn 0.039138 -0.999233 -0.000989 +vn 0.179512 -0.983746 -0.004369 +vn 0.612299 -0.790557 -0.010460 +vn 0.986152 -0.165708 -0.006670 +vn 0.007039 -0.812495 0.582926 +vn 0.036127 -0.837257 0.545614 +vn 0.161846 -0.810421 0.563048 +vn 0.482365 -0.595148 0.642746 +vn 0.738720 -0.114594 0.664199 +vn -0.001909 0.162121 0.986769 +vn 0.002762 0.017107 0.999850 +vn 0.010533 0.073398 0.997247 +vn -0.066041 0.130070 0.989303 +vn -0.094427 0.016594 0.995393 +vn -0.009203 0.871509 0.490293 +vn -0.048606 0.840609 0.539457 +vn -0.223298 0.802880 0.552739 +vn -0.596365 0.559971 0.575135 +vn -0.803337 0.068236 0.591603 +vn -0.010561 0.999944 0.000103 +vn -0.058798 0.998270 0.000710 +vn -0.280710 0.959787 0.003269 +vn -0.749723 0.661738 0.004268 +vn -0.997351 0.072714 0.002059 +vn -0.008792 0.871493 -0.490330 +vn -0.046494 0.841178 -0.538756 +vn -0.217909 0.806807 -0.549161 +vn -0.597291 0.560026 -0.574121 +vn -0.804000 0.062913 -0.591292 +vn -0.001806 0.161691 -0.986840 +vn 0.002031 0.014555 -0.999892 +vn 0.009215 0.060069 -0.998152 +vn -0.059334 0.113865 -0.991723 +vn -0.086899 0.012290 -0.996141 +vn 0.006418 -0.812379 -0.583095 +vn 0.033783 -0.837512 -0.545373 +vn 0.157113 -0.811947 -0.562190 +vn 0.484406 -0.589366 -0.646528 +vn 0.738870 -0.101320 -0.666187 +vn 0.946512 0.322650 -0.003357 +vn 0.825830 0.563870 -0.007452 +vn 0.650011 0.759893 -0.006937 +vn 0.532429 0.846459 -0.005245 +vn 0.725608 0.259351 0.637361 +vn 0.645945 0.461988 0.607719 +vn 0.531615 0.636660 0.558614 +vn 0.424964 0.681717 0.595540 +vn -0.049562 -0.019755 0.998576 +vn -0.037816 -0.035624 0.998650 +vn -0.037914 -0.036512 0.998614 +vn -0.168854 -0.297945 0.939530 +vn -0.742342 -0.299166 0.599523 +vn -0.619602 -0.529406 0.579502 +vn -0.483708 -0.685760 0.543837 +vn -0.445293 -0.794355 0.413177 +vn -0.926513 -0.376258 0.001996 +vn -0.753920 -0.656952 0.004317 +vn -0.566224 -0.824244 0.003461 +vn -0.481804 -0.876277 0.001850 +vn -0.744675 -0.294425 -0.598977 +vn -0.621949 -0.528114 -0.578165 +vn -0.481171 -0.688340 -0.542828 +vn -0.438055 -0.797035 -0.415744 +vn -0.044337 -0.017056 -0.998871 +vn -0.026176 -0.028166 -0.999260 +vn -0.025294 -0.028332 -0.999278 +vn -0.157482 -0.289392 -0.944167 +vn 0.728244 0.252410 -0.637142 +vn 0.647055 0.459725 -0.608254 +vn 0.522994 0.640657 -0.562170 +vn 0.409978 0.682857 -0.604669 +vn -0.230787 0.972982 -0.006523 +vn -0.548936 0.835863 -0.001511 +vn -0.875671 0.482806 0.009893 +vn -0.877554 0.479097 0.019092 +vn -0.696190 0.717439 0.024497 +vn -0.152877 0.687211 0.710190 +vn -0.316721 0.637750 0.702113 +vn -0.601067 0.471452 0.645330 +vn -0.635889 0.446090 0.629801 +vn -0.435746 0.601008 0.670011 +vn 0.111113 -0.085070 0.990160 +vn 0.223310 0.006540 0.974726 +vn 0.190097 0.154964 0.969458 +vn 0.005271 0.189482 0.981870 +vn -0.011752 0.246688 0.969024 +vn 0.343906 -0.722796 0.599412 +vn 0.572489 -0.567656 0.591627 +vn 0.787436 -0.256459 0.560512 +vn 0.647097 -0.306374 0.698141 +vn 0.427528 -0.499343 0.753576 +vn 0.410926 -0.911668 0.001284 +vn 0.671520 -0.740986 -0.000899 +vn 0.922026 -0.387060 -0.007253 +vn 0.846910 -0.531556 -0.013854 +vn 0.535924 -0.844201 -0.010505 +vn 0.341188 -0.722823 -0.600931 +vn 0.578664 -0.561139 -0.591838 +vn 0.784869 -0.251020 -0.566542 +vn 0.642681 -0.302257 -0.703990 +vn 0.418589 -0.500042 -0.758117 +vn 0.115806 -0.079139 -0.990114 +vn 0.232811 0.012565 -0.972441 +vn 0.206662 0.153601 -0.966280 +vn 0.024500 0.161443 -0.986578 +vn 0.003382 0.211115 -0.977455 +vn -0.134912 0.687491 -0.713551 +vn -0.319540 0.633073 -0.705063 +vn -0.603902 0.461442 -0.649903 +vn -0.631815 0.437169 -0.640072 +vn -0.424306 0.612706 -0.666750 +vn -0.425801 0.904753 0.010805 +vn 0.022046 0.999756 0.001623 +vn 0.999598 0.025875 0.011556 +vn 0.709587 -0.704552 0.009672 +vn -0.259858 0.791937 0.552548 +vn 0.009539 0.999720 -0.021674 +vn 0.410157 0.332912 -0.849082 +vn 0.541523 -0.548619 -0.637001 +vn 0.046311 0.455223 0.889172 +vn -0.010688 0.988794 0.148900 +vn -0.044376 0.682946 -0.729120 +vn 0.122824 0.009233 -0.992385 +vn 0.481839 -0.180440 0.857480 +vn 0.455272 0.736752 0.499925 +vn -0.220542 0.907193 -0.358277 +vn -0.235919 0.657250 -0.715797 +vn 0.728094 -0.685300 -0.015585 +vn 0.888738 0.458112 -0.016679 +vn -0.260098 0.965582 0.000800 +vn -0.371611 0.928378 -0.004418 +vn 0.480165 -0.178362 -0.858853 +vn 0.488102 0.716802 -0.497947 +vn -0.222004 0.905399 0.361892 +vn -0.235405 0.663180 0.710477 +vn 0.058720 0.437702 -0.897200 +vn 0.001326 0.986459 -0.164002 +vn -0.044190 0.681675 0.730319 +vn 0.138801 -0.034188 0.989730 +vn -0.258890 0.797206 -0.545380 +vn 0.012270 0.999739 0.019287 +vn 0.398632 0.354890 0.845663 +vn 0.537564 -0.581398 0.610738 +vn 0.000000 1.000000 0.000000 +vn 0.824540 0.565804 0.000017 +vn 0.917701 -0.397272 0.000034 +vn 0.935269 -0.353939 0.000113 +vn 0.780712 0.624890 0.000075 +vn 0.762640 0.565035 0.314825 +vn 0.847982 -0.397998 0.350034 +vn 0.864141 -0.355261 0.356441 +vn 0.720992 0.625625 0.297933 +vn 0.583357 0.565165 0.583338 +vn 0.648485 -0.398726 0.648448 +vn 0.660872 -0.355894 0.660748 +vn 0.551862 0.625290 0.551780 +vn 0.314824 0.565051 0.762629 +vn 0.350045 -0.397976 0.847988 +vn 0.356474 -0.355199 0.864153 +vn 0.297983 0.625515 0.721067 +vn -0.000017 0.565804 0.824540 +vn -0.000034 -0.397272 0.917701 +vn -0.000113 -0.353939 0.935269 +vn -0.000075 0.624890 0.780712 +vn -0.314825 0.565035 0.762640 +vn -0.350034 -0.397998 0.847982 +vn -0.356441 -0.355261 0.864141 +vn -0.297933 0.625625 0.720992 +vn -0.583338 0.565165 0.583357 +vn -0.648448 -0.398726 0.648485 +vn -0.660748 -0.355894 0.660872 +vn -0.551780 0.625290 0.551862 +vn -0.762629 0.565051 0.314824 +vn -0.847988 -0.397976 0.350045 +vn -0.864153 -0.355199 0.356474 +vn -0.721067 0.625515 0.297983 +vn -0.824540 0.565804 -0.000017 +vn -0.917701 -0.397272 -0.000034 +vn -0.935269 -0.353939 -0.000113 +vn -0.780712 0.624890 -0.000075 +vn -0.762640 0.565035 -0.314825 +vn -0.847982 -0.397998 -0.350034 +vn -0.864141 -0.355261 -0.356441 +vn -0.720992 0.625625 -0.297933 +vn -0.583357 0.565165 -0.583338 +vn -0.648485 -0.398726 -0.648448 +vn -0.660872 -0.355894 -0.660748 +vn -0.551862 0.625290 -0.551780 +vn -0.314824 0.565051 -0.762629 +vn -0.350045 -0.397976 -0.847988 +vn -0.356474 -0.355199 -0.864153 +vn -0.297983 0.625515 -0.721067 +vn 0.000017 0.565804 -0.824540 +vn 0.000034 -0.397272 -0.917701 +vn 0.000113 -0.353939 -0.935269 +vn 0.000075 0.624890 -0.780712 +vn 0.314825 0.565035 -0.762640 +vn 0.350034 -0.397998 -0.847982 +vn 0.356441 -0.355261 -0.864141 +vn 0.297933 0.625625 -0.720992 +vn 0.583338 0.565165 -0.583357 +vn 0.648448 -0.398726 -0.648485 +vn 0.660748 -0.355894 -0.660872 +vn 0.551780 0.625290 -0.551862 +vn 0.762629 0.565051 -0.314824 +vn 0.847988 -0.397976 -0.350045 +vn 0.864153 -0.355199 -0.356474 +vn 0.721067 0.625515 -0.297983 +vn 0.236583 0.971611 -0.000000 +vn 0.173084 0.984907 -0.000000 +vn 0.379703 0.925108 -0.000000 +vn 0.526673 0.850068 0.000000 +vn 0.217978 0.971775 0.090216 +vn 0.159589 0.984977 0.065961 +vn 0.350498 0.925311 0.144740 +vn 0.485590 0.850653 0.201474 +vn 0.166631 0.971838 0.166631 +vn 0.121908 0.985026 0.121908 +vn 0.267668 0.925585 0.267668 +vn 0.371315 0.851029 0.371315 +vn 0.090216 0.971775 0.217978 +vn 0.065961 0.984977 0.159589 +vn 0.144740 0.925311 0.350498 +vn 0.201475 0.850653 0.485590 +vn 0.000000 0.971611 0.236583 +vn 0.000000 0.984907 0.173084 +vn 0.000000 0.925108 0.379703 +vn -0.000000 0.850068 0.526673 +vn -0.090216 0.971775 0.217978 +vn -0.065961 0.984977 0.159589 +vn -0.144740 0.925311 0.350498 +vn -0.201474 0.850653 0.485590 +vn -0.166631 0.971838 0.166631 +vn -0.121908 0.985026 0.121908 +vn -0.267668 0.925585 0.267668 +vn -0.371315 0.851029 0.371315 +vn -0.217978 0.971775 0.090216 +vn -0.159589 0.984977 0.065961 +vn -0.350498 0.925311 0.144740 +vn -0.485590 0.850653 0.201475 +vn -0.236583 0.971611 0.000000 +vn -0.173084 0.984907 0.000000 +vn -0.379703 0.925108 0.000000 +vn -0.526673 0.850068 -0.000000 +vn -0.217978 0.971775 -0.090216 +vn -0.159589 0.984977 -0.065961 +vn -0.350498 0.925311 -0.144740 +vn -0.485590 0.850653 -0.201474 +vn -0.166631 0.971838 -0.166631 +vn -0.121908 0.985026 -0.121908 +vn -0.267668 0.925585 -0.267668 +vn -0.371315 0.851029 -0.371315 +vn -0.090216 0.971775 -0.217978 +vn -0.065961 0.984977 -0.159589 +vn -0.144740 0.925311 -0.350498 +vn -0.201475 0.850653 -0.485590 +vn -0.000000 0.971611 -0.236583 +vn -0.000000 0.984907 -0.173084 +vn -0.000000 0.925108 -0.379703 +vn 0.000000 0.850068 -0.526673 +vn 0.090216 0.971775 -0.217978 +vn 0.065961 0.984977 -0.159589 +vn 0.144740 0.925311 -0.350498 +vn 0.201474 0.850653 -0.485590 +vn 0.166631 0.971838 -0.166631 +vn 0.121908 0.985026 -0.121908 +vn 0.267668 0.925585 -0.267668 +vn 0.371315 0.851029 -0.371315 +vn 0.217978 0.971775 -0.090216 +vn 0.159589 0.984977 -0.065961 +vn 0.350498 0.925311 -0.144740 +vn 0.485590 0.850653 -0.201475 +# 530 vertex normals + +g Teapot01 +f 1/1/1 6/6/6 7/7/7 +f 7/7/7 2/2/2 1/1/1 +f 2/2/2 7/7/7 8/8/8 +f 8/8/8 3/3/3 2/2/2 +f 3/3/3 8/8/8 9/9/9 +f 9/9/9 4/4/4 3/3/3 +f 4/4/4 9/9/9 10/10/10 +f 10/10/10 5/5/5 4/4/4 +f 6/6/6 11/11/11 12/12/12 +f 12/12/12 7/7/7 6/6/6 +f 7/7/7 12/12/12 13/13/13 +f 13/13/13 8/8/8 7/7/7 +f 8/8/8 13/13/13 14/14/14 +f 14/14/14 9/9/9 8/8/8 +f 9/9/9 14/14/14 15/15/15 +f 15/15/15 10/10/10 9/9/9 +f 11/11/11 16/16/16 17/17/17 +f 17/17/17 12/12/12 11/11/11 +f 12/12/12 17/17/17 18/18/18 +f 18/18/18 13/13/13 12/12/12 +f 13/13/13 18/18/18 19/19/19 +f 19/19/19 14/14/14 13/13/13 +f 14/14/14 19/19/19 20/20/20 +f 20/20/20 15/15/15 14/14/14 +f 16/16/16 21/21/21 22/22/22 +f 22/22/22 17/17/17 16/16/16 +f 17/17/17 22/22/22 23/23/23 +f 23/23/23 18/18/18 17/17/17 +f 18/18/18 23/23/23 24/24/24 +f 24/24/24 19/19/19 18/18/18 +f 19/19/19 24/24/24 25/25/25 +f 25/25/25 20/20/20 19/19/19 +f 21/26/21 26/31/26 27/32/27 +f 27/32/27 22/27/22 21/26/21 +f 22/27/22 27/32/27 28/33/28 +f 28/33/28 23/28/23 22/27/22 +f 23/28/23 28/33/28 29/34/29 +f 29/34/29 24/29/24 23/28/23 +f 24/29/24 29/34/29 30/35/30 +f 30/35/30 25/30/25 24/29/24 +f 26/31/26 31/36/31 32/37/32 +f 32/37/32 27/32/27 26/31/26 +f 27/32/27 32/37/32 33/38/33 +f 33/38/33 28/33/28 27/32/27 +f 28/33/28 33/38/33 34/39/34 +f 34/39/34 29/34/29 28/33/28 +f 29/34/29 34/39/34 35/40/35 +f 35/40/35 30/35/30 29/34/29 +f 31/36/31 36/41/36 37/42/37 +f 37/42/37 32/37/32 31/36/31 +f 32/37/32 37/42/37 38/43/38 +f 38/43/38 33/38/33 32/37/32 +f 33/38/33 38/43/38 39/44/39 +f 39/44/39 34/39/34 33/38/33 +f 34/39/34 39/44/39 40/45/40 +f 40/45/40 35/40/35 34/39/34 +f 36/41/36 41/46/41 42/47/42 +f 42/47/42 37/42/37 36/41/36 +f 37/42/37 42/47/42 43/48/43 +f 43/48/43 38/43/38 37/42/37 +f 38/43/38 43/48/43 44/49/44 +f 44/49/44 39/44/39 38/43/38 +f 39/44/39 44/49/44 45/50/45 +f 45/50/45 40/45/40 39/44/39 +f 41/51/41 46/56/46 47/57/47 +f 47/57/47 42/52/42 41/51/41 +f 42/52/42 47/57/47 48/58/48 +f 48/58/48 43/53/43 42/52/42 +f 43/53/43 48/58/48 49/59/49 +f 49/59/49 44/54/44 43/53/43 +f 44/54/44 49/59/49 50/60/50 +f 50/60/50 45/55/45 44/54/44 +f 46/56/46 51/61/51 52/62/52 +f 52/62/52 47/57/47 46/56/46 +f 47/57/47 52/62/52 53/63/53 +f 53/63/53 48/58/48 47/57/47 +f 48/58/48 53/63/53 54/64/54 +f 54/64/54 49/59/49 48/58/48 +f 49/59/49 54/64/54 55/65/55 +f 55/65/55 50/60/50 49/59/49 +f 51/61/51 56/66/56 57/67/57 +f 57/67/57 52/62/52 51/61/51 +f 52/62/52 57/67/57 58/68/58 +f 58/68/58 53/63/53 52/62/52 +f 53/63/53 58/68/58 59/69/59 +f 59/69/59 54/64/54 53/63/53 +f 54/64/54 59/69/59 60/70/60 +f 60/70/60 55/65/55 54/64/54 +f 56/66/56 61/71/61 62/72/62 +f 62/72/62 57/67/57 56/66/56 +f 57/67/57 62/72/62 63/73/63 +f 63/73/63 58/68/58 57/67/57 +f 58/68/58 63/73/63 64/74/64 +f 64/74/64 59/69/59 58/68/58 +f 59/69/59 64/74/64 65/75/65 +f 65/75/65 60/70/60 59/69/59 +f 61/76/61 66/81/66 67/82/67 +f 67/82/67 62/77/62 61/76/61 +f 62/77/62 67/82/67 68/83/68 +f 68/83/68 63/78/63 62/77/62 +f 63/78/63 68/83/68 69/84/69 +f 69/84/69 64/79/64 63/78/63 +f 64/79/64 69/84/69 70/85/70 +f 70/85/70 65/80/65 64/79/64 +f 66/81/66 71/86/71 72/87/72 +f 72/87/72 67/82/67 66/81/66 +f 67/82/67 72/87/72 73/88/73 +f 73/88/73 68/83/68 67/82/67 +f 68/83/68 73/88/73 74/89/74 +f 74/89/74 69/84/69 68/83/68 +f 69/84/69 74/89/74 75/90/75 +f 75/90/75 70/85/70 69/84/69 +f 71/86/71 76/91/76 77/92/77 +f 77/92/77 72/87/72 71/86/71 +f 72/87/72 77/92/77 78/93/78 +f 78/93/78 73/88/73 72/87/72 +f 73/88/73 78/93/78 79/94/79 +f 79/94/79 74/89/74 73/88/73 +f 74/89/74 79/94/79 80/95/80 +f 80/95/80 75/90/75 74/89/74 +f 76/91/76 1/96/1 2/97/2 +f 2/97/2 77/92/77 76/91/76 +f 77/92/77 2/97/2 3/98/3 +f 3/98/3 78/93/78 77/92/77 +f 78/93/78 3/98/3 4/99/4 +f 4/99/4 79/94/79 78/93/78 +f 79/94/79 4/99/4 5/100/5 +f 5/100/5 80/95/80 79/94/79 +f 5/101/5 10/106/10 85/107/85 +f 85/107/85 81/102/81 5/101/5 +f 81/102/81 85/107/85 86/108/86 +f 86/108/86 82/103/82 81/102/81 +f 82/103/82 86/108/86 87/109/87 +f 87/109/87 83/104/83 82/103/82 +f 83/104/83 87/109/87 88/110/88 +f 88/110/88 84/105/84 83/104/83 +f 10/106/10 15/111/15 89/112/89 +f 89/112/89 85/107/85 10/106/10 +f 85/107/85 89/112/89 90/113/90 +f 90/113/90 86/108/86 85/107/85 +f 86/108/86 90/113/90 91/114/91 +f 91/114/91 87/109/87 86/108/86 +f 87/109/87 91/114/91 92/115/92 +f 92/115/92 88/110/88 87/109/87 +f 15/111/15 20/116/20 93/117/93 +f 93/117/93 89/112/89 15/111/15 +f 89/112/89 93/117/93 94/118/94 +f 94/118/94 90/113/90 89/112/89 +f 90/113/90 94/118/94 95/119/95 +f 95/119/95 91/114/91 90/113/90 +f 91/114/91 95/119/95 96/120/96 +f 96/120/96 92/115/92 91/114/91 +f 20/116/20 25/121/25 97/122/97 +f 97/122/97 93/117/93 20/116/20 +f 93/117/93 97/122/97 98/123/98 +f 98/123/98 94/118/94 93/117/93 +f 94/118/94 98/123/98 99/124/99 +f 99/124/99 95/119/95 94/118/94 +f 95/119/95 99/124/99 100/125/100 +f 100/125/100 96/120/96 95/119/95 +f 25/126/25 30/131/30 101/132/101 +f 101/132/101 97/127/97 25/126/25 +f 97/127/97 101/132/101 102/133/102 +f 102/133/102 98/128/98 97/127/97 +f 98/128/98 102/133/102 103/134/103 +f 103/134/103 99/129/99 98/128/98 +f 99/129/99 103/134/103 104/135/104 +f 104/135/104 100/130/100 99/129/99 +f 30/131/30 35/136/35 105/137/105 +f 105/137/105 101/132/101 30/131/30 +f 101/132/101 105/137/105 106/138/106 +f 106/138/106 102/133/102 101/132/101 +f 102/133/102 106/138/106 107/139/107 +f 107/139/107 103/134/103 102/133/102 +f 103/134/103 107/139/107 108/140/108 +f 108/140/108 104/135/104 103/134/103 +f 35/136/35 40/141/40 109/142/109 +f 109/142/109 105/137/105 35/136/35 +f 105/137/105 109/142/109 110/143/110 +f 110/143/110 106/138/106 105/137/105 +f 106/138/106 110/143/110 111/144/111 +f 111/144/111 107/139/107 106/138/106 +f 107/139/107 111/144/111 112/145/112 +f 112/145/112 108/140/108 107/139/107 +f 40/141/40 45/146/45 113/147/113 +f 113/147/113 109/142/109 40/141/40 +f 109/142/109 113/147/113 114/148/114 +f 114/148/114 110/143/110 109/142/109 +f 110/143/110 114/148/114 115/149/115 +f 115/149/115 111/144/111 110/143/110 +f 111/144/111 115/149/115 116/150/116 +f 116/150/116 112/145/112 111/144/111 +f 45/151/45 50/156/50 117/157/117 +f 117/157/117 113/152/113 45/151/45 +f 113/152/113 117/157/117 118/158/118 +f 118/158/118 114/153/114 113/152/113 +f 114/153/114 118/158/118 119/159/119 +f 119/159/119 115/154/115 114/153/114 +f 115/154/115 119/159/119 120/160/120 +f 120/160/120 116/155/116 115/154/115 +f 50/156/50 55/161/55 121/162/121 +f 121/162/121 117/157/117 50/156/50 +f 117/157/117 121/162/121 122/163/122 +f 122/163/122 118/158/118 117/157/117 +f 118/158/118 122/163/122 123/164/123 +f 123/164/123 119/159/119 118/158/118 +f 119/159/119 123/164/123 124/165/124 +f 124/165/124 120/160/120 119/159/119 +f 55/161/55 60/166/60 125/167/125 +f 125/167/125 121/162/121 55/161/55 +f 121/162/121 125/167/125 126/168/126 +f 126/168/126 122/163/122 121/162/121 +f 122/163/122 126/168/126 127/169/127 +f 127/169/127 123/164/123 122/163/122 +f 123/164/123 127/169/127 128/170/128 +f 128/170/128 124/165/124 123/164/123 +f 60/166/60 65/171/65 129/172/129 +f 129/172/129 125/167/125 60/166/60 +f 125/167/125 129/172/129 130/173/130 +f 130/173/130 126/168/126 125/167/125 +f 126/168/126 130/173/130 131/174/131 +f 131/174/131 127/169/127 126/168/126 +f 127/169/127 131/174/131 132/175/132 +f 132/175/132 128/170/128 127/169/127 +f 65/176/65 70/181/70 133/182/133 +f 133/182/133 129/177/129 65/176/65 +f 129/177/129 133/182/133 134/183/134 +f 134/183/134 130/178/130 129/177/129 +f 130/178/130 134/183/134 135/184/135 +f 135/184/135 131/179/131 130/178/130 +f 131/179/131 135/184/135 136/185/136 +f 136/185/136 132/180/132 131/179/131 +f 70/181/70 75/186/75 137/187/137 +f 137/187/137 133/182/133 70/181/70 +f 133/182/133 137/187/137 138/188/138 +f 138/188/138 134/183/134 133/182/133 +f 134/183/134 138/188/138 139/189/139 +f 139/189/139 135/184/135 134/183/134 +f 135/184/135 139/189/139 140/190/140 +f 140/190/140 136/185/136 135/184/135 +f 75/186/75 80/191/80 141/192/141 +f 141/192/141 137/187/137 75/186/75 +f 137/187/137 141/192/141 142/193/142 +f 142/193/142 138/188/138 137/187/137 +f 138/188/138 142/193/142 143/194/143 +f 143/194/143 139/189/139 138/188/138 +f 139/189/139 143/194/143 144/195/144 +f 144/195/144 140/190/140 139/189/139 +f 80/191/80 5/196/5 81/197/81 +f 81/197/81 141/192/141 80/191/80 +f 141/192/141 81/197/81 82/198/82 +f 82/198/82 142/193/142 141/192/141 +f 142/193/142 82/198/82 83/199/83 +f 83/199/83 143/194/143 142/193/142 +f 143/194/143 83/199/83 84/200/84 +f 84/200/84 144/195/144 143/194/143 +f 84/201/84 88/206/88 149/207/149 +f 149/207/149 145/202/145 84/201/84 +f 145/202/145 149/207/149 150/208/150 +f 150/208/150 146/203/146 145/202/145 +f 146/203/146 150/208/150 151/209/151 +f 151/209/151 147/204/147 146/203/146 +f 147/204/147 151/209/151 152/210/152 +f 152/210/152 148/205/148 147/204/147 +f 88/206/88 92/211/92 153/212/153 +f 153/212/153 149/207/149 88/206/88 +f 149/207/149 153/212/153 154/213/154 +f 154/213/154 150/208/150 149/207/149 +f 150/208/150 154/213/154 155/214/155 +f 155/214/155 151/209/151 150/208/150 +f 151/209/151 155/214/155 156/215/156 +f 156/215/156 152/210/152 151/209/151 +f 92/211/92 96/216/96 157/217/157 +f 157/217/157 153/212/153 92/211/92 +f 153/212/153 157/217/157 158/218/158 +f 158/218/158 154/213/154 153/212/153 +f 154/213/154 158/218/158 159/219/159 +f 159/219/159 155/214/155 154/213/154 +f 155/214/155 159/219/159 160/220/160 +f 160/220/160 156/215/156 155/214/155 +f 96/216/96 100/221/100 161/222/161 +f 161/222/161 157/217/157 96/216/96 +f 157/217/157 161/222/161 162/223/162 +f 162/223/162 158/218/158 157/217/157 +f 158/218/158 162/223/162 163/224/163 +f 163/224/163 159/219/159 158/218/158 +f 159/219/159 163/224/163 164/225/164 +f 164/225/164 160/220/160 159/219/159 +f 100/226/100 104/231/104 165/232/165 +f 165/232/165 161/227/161 100/226/100 +f 161/227/161 165/232/165 166/233/166 +f 166/233/166 162/228/162 161/227/161 +f 162/228/162 166/233/166 167/234/167 +f 167/234/167 163/229/163 162/228/162 +f 163/229/163 167/234/167 168/235/168 +f 168/235/168 164/230/164 163/229/163 +f 104/231/104 108/236/108 169/237/169 +f 169/237/169 165/232/165 104/231/104 +f 165/232/165 169/237/169 170/238/170 +f 170/238/170 166/233/166 165/232/165 +f 166/233/166 170/238/170 171/239/171 +f 171/239/171 167/234/167 166/233/166 +f 167/234/167 171/239/171 172/240/172 +f 172/240/172 168/235/168 167/234/167 +f 108/236/108 112/241/112 173/242/173 +f 173/242/173 169/237/169 108/236/108 +f 169/237/169 173/242/173 174/243/174 +f 174/243/174 170/238/170 169/237/169 +f 170/238/170 174/243/174 175/244/175 +f 175/244/175 171/239/171 170/238/170 +f 171/239/171 175/244/175 176/245/176 +f 176/245/176 172/240/172 171/239/171 +f 112/241/112 116/246/116 177/247/177 +f 177/247/177 173/242/173 112/241/112 +f 173/242/173 177/247/177 178/248/178 +f 178/248/178 174/243/174 173/242/173 +f 174/243/174 178/248/178 179/249/179 +f 179/249/179 175/244/175 174/243/174 +f 175/244/175 179/249/179 180/250/180 +f 180/250/180 176/245/176 175/244/175 +f 116/251/116 120/256/120 181/257/181 +f 181/257/181 177/252/177 116/251/116 +f 177/252/177 181/257/181 182/258/182 +f 182/258/182 178/253/178 177/252/177 +f 178/253/178 182/258/182 183/259/183 +f 183/259/183 179/254/179 178/253/178 +f 179/254/179 183/259/183 184/260/184 +f 184/260/184 180/255/180 179/254/179 +f 120/256/120 124/261/124 185/262/185 +f 185/262/185 181/257/181 120/256/120 +f 181/257/181 185/262/185 186/263/186 +f 186/263/186 182/258/182 181/257/181 +f 182/258/182 186/263/186 187/264/187 +f 187/264/187 183/259/183 182/258/182 +f 183/259/183 187/264/187 188/265/188 +f 188/265/188 184/260/184 183/259/183 +f 124/261/124 128/266/128 189/267/189 +f 189/267/189 185/262/185 124/261/124 +f 185/262/185 189/267/189 190/268/190 +f 190/268/190 186/263/186 185/262/185 +f 186/263/186 190/268/190 191/269/191 +f 191/269/191 187/264/187 186/263/186 +f 187/264/187 191/269/191 192/270/192 +f 192/270/192 188/265/188 187/264/187 +f 128/266/128 132/271/132 193/272/193 +f 193/272/193 189/267/189 128/266/128 +f 189/267/189 193/272/193 194/273/194 +f 194/273/194 190/268/190 189/267/189 +f 190/268/190 194/273/194 195/274/195 +f 195/274/195 191/269/191 190/268/190 +f 191/269/191 195/274/195 196/275/196 +f 196/275/196 192/270/192 191/269/191 +f 132/276/132 136/281/136 197/282/197 +f 197/282/197 193/277/193 132/276/132 +f 193/277/193 197/282/197 198/283/198 +f 198/283/198 194/278/194 193/277/193 +f 194/278/194 198/283/198 199/284/199 +f 199/284/199 195/279/195 194/278/194 +f 195/279/195 199/284/199 200/285/200 +f 200/285/200 196/280/196 195/279/195 +f 136/281/136 140/286/140 201/287/201 +f 201/287/201 197/282/197 136/281/136 +f 197/282/197 201/287/201 202/288/202 +f 202/288/202 198/283/198 197/282/197 +f 198/283/198 202/288/202 203/289/203 +f 203/289/203 199/284/199 198/283/198 +f 199/284/199 203/289/203 204/290/204 +f 204/290/204 200/285/200 199/284/199 +f 140/286/140 144/291/144 205/292/205 +f 205/292/205 201/287/201 140/286/140 +f 201/287/201 205/292/205 206/293/206 +f 206/293/206 202/288/202 201/287/201 +f 202/288/202 206/293/206 207/294/207 +f 207/294/207 203/289/203 202/288/202 +f 203/289/203 207/294/207 208/295/208 +f 208/295/208 204/290/204 203/289/203 +f 144/291/144 84/296/84 145/297/145 +f 145/297/145 205/292/205 144/291/144 +f 205/292/205 145/297/145 146/298/146 +f 146/298/146 206/293/206 205/292/205 +f 206/293/206 146/298/146 147/299/147 +f 147/299/147 207/294/207 206/293/206 +f 207/294/207 147/299/147 148/300/148 +f 148/300/148 208/295/208 207/294/207 +f 148/301/148 152/306/152 213/307/213 +f 213/307/213 209/302/209 148/301/148 +f 209/302/209 213/307/213 214/308/214 +f 214/308/214 210/303/210 209/302/209 +f 210/303/210 214/308/214 215/309/215 +f 215/309/215 211/304/211 210/303/210 +f 211/304/211 215/309/215 212/310/212 +f 152/306/152 156/311/156 216/312/216 +f 216/312/216 213/307/213 152/306/152 +f 213/307/213 216/312/216 217/313/217 +f 217/313/217 214/308/214 213/307/213 +f 214/308/214 217/313/217 218/314/218 +f 218/314/218 215/309/215 214/308/214 +f 215/309/215 218/314/218 212/315/212 +f 156/311/156 160/316/160 219/317/219 +f 219/317/219 216/312/216 156/311/156 +f 216/312/216 219/317/219 220/318/220 +f 220/318/220 217/313/217 216/312/216 +f 217/313/217 220/318/220 221/319/221 +f 221/319/221 218/314/218 217/313/217 +f 218/314/218 221/319/221 212/320/212 +f 160/316/160 164/321/164 222/322/222 +f 222/322/222 219/317/219 160/316/160 +f 219/317/219 222/322/222 223/323/223 +f 223/323/223 220/318/220 219/317/219 +f 220/318/220 223/323/223 224/324/224 +f 224/324/224 221/319/221 220/318/220 +f 221/319/221 224/324/224 212/325/212 +f 164/326/164 168/331/168 225/332/225 +f 225/332/225 222/327/222 164/326/164 +f 222/327/222 225/332/225 226/333/226 +f 226/333/226 223/328/223 222/327/222 +f 223/328/223 226/333/226 227/334/227 +f 227/334/227 224/329/224 223/328/223 +f 224/329/224 227/334/227 212/335/212 +f 168/331/168 172/336/172 228/337/228 +f 228/337/228 225/332/225 168/331/168 +f 225/332/225 228/337/228 229/338/229 +f 229/338/229 226/333/226 225/332/225 +f 226/333/226 229/338/229 230/339/230 +f 230/339/230 227/334/227 226/333/226 +f 227/334/227 230/339/230 212/340/212 +f 172/336/172 176/341/176 231/342/231 +f 231/342/231 228/337/228 172/336/172 +f 228/337/228 231/342/231 232/343/232 +f 232/343/232 229/338/229 228/337/228 +f 229/338/229 232/343/232 233/344/233 +f 233/344/233 230/339/230 229/338/229 +f 230/339/230 233/344/233 212/345/212 +f 176/341/176 180/346/180 234/347/234 +f 234/347/234 231/342/231 176/341/176 +f 231/342/231 234/347/234 235/348/235 +f 235/348/235 232/343/232 231/342/231 +f 232/343/232 235/348/235 236/349/236 +f 236/349/236 233/344/233 232/343/232 +f 233/344/233 236/349/236 212/350/212 +f 180/351/180 184/356/184 237/357/237 +f 237/357/237 234/352/234 180/351/180 +f 234/352/234 237/357/237 238/358/238 +f 238/358/238 235/353/235 234/352/234 +f 235/353/235 238/358/238 239/359/239 +f 239/359/239 236/354/236 235/353/235 +f 236/354/236 239/359/239 212/360/212 +f 184/356/184 188/361/188 240/362/240 +f 240/362/240 237/357/237 184/356/184 +f 237/357/237 240/362/240 241/363/241 +f 241/363/241 238/358/238 237/357/237 +f 238/358/238 241/363/241 242/364/242 +f 242/364/242 239/359/239 238/358/238 +f 239/359/239 242/364/242 212/365/212 +f 188/361/188 192/366/192 243/367/243 +f 243/367/243 240/362/240 188/361/188 +f 240/362/240 243/367/243 244/368/244 +f 244/368/244 241/363/241 240/362/240 +f 241/363/241 244/368/244 245/369/245 +f 245/369/245 242/364/242 241/363/241 +f 242/364/242 245/369/245 212/370/212 +f 192/366/192 196/371/196 246/372/246 +f 246/372/246 243/367/243 192/366/192 +f 243/367/243 246/372/246 247/373/247 +f 247/373/247 244/368/244 243/367/243 +f 244/368/244 247/373/247 248/374/248 +f 248/374/248 245/369/245 244/368/244 +f 245/369/245 248/374/248 212/375/212 +f 196/376/196 200/381/200 249/382/249 +f 249/382/249 246/377/246 196/376/196 +f 246/377/246 249/382/249 250/383/250 +f 250/383/250 247/378/247 246/377/246 +f 247/378/247 250/383/250 251/384/251 +f 251/384/251 248/379/248 247/378/247 +f 248/379/248 251/384/251 212/385/212 +f 200/381/200 204/386/204 252/387/252 +f 252/387/252 249/382/249 200/381/200 +f 249/382/249 252/387/252 253/388/253 +f 253/388/253 250/383/250 249/382/249 +f 250/383/250 253/388/253 254/389/254 +f 254/389/254 251/384/251 250/383/250 +f 251/384/251 254/389/254 212/390/212 +f 204/386/204 208/391/208 255/392/255 +f 255/392/255 252/387/252 204/386/204 +f 252/387/252 255/392/255 256/393/256 +f 256/393/256 253/388/253 252/387/252 +f 253/388/253 256/393/256 257/394/257 +f 257/394/257 254/389/254 253/388/253 +f 254/389/254 257/394/257 212/395/212 +f 208/391/208 148/396/148 209/397/209 +f 209/397/209 255/392/255 208/391/208 +f 255/392/255 209/397/209 210/398/210 +f 210/398/210 256/393/256 255/392/255 +f 256/393/256 210/398/210 211/399/211 +f 211/399/211 257/394/257 256/393/256 +f 257/394/257 211/399/211 212/400/212 +f 258/401/258 263/406/263 264/407/264 +f 264/407/264 259/402/259 258/401/258 +f 259/402/259 264/407/264 265/408/265 +f 265/408/265 260/403/260 259/402/259 +f 260/403/260 265/408/265 266/409/266 +f 266/409/266 261/404/261 260/403/260 +f 261/404/261 266/409/266 267/410/267 +f 267/410/267 262/405/262 261/404/261 +f 263/406/263 268/411/268 269/412/269 +f 269/412/269 264/407/264 263/406/263 +f 264/407/264 269/412/269 270/413/270 +f 270/413/270 265/408/265 264/407/264 +f 265/408/265 270/413/270 271/414/271 +f 271/414/271 266/409/266 265/408/265 +f 266/409/266 271/414/271 272/415/272 +f 272/415/272 267/410/267 266/409/266 +f 268/411/268 273/416/273 274/417/274 +f 274/417/274 269/412/269 268/411/268 +f 269/412/269 274/417/274 275/418/275 +f 275/418/275 270/413/270 269/412/269 +f 270/413/270 275/418/275 276/419/276 +f 276/419/276 271/414/271 270/413/270 +f 271/414/271 276/419/276 277/420/277 +f 277/420/277 272/415/272 271/414/271 +f 273/416/273 278/421/278 279/422/279 +f 279/422/279 274/417/274 273/416/273 +f 274/417/274 279/422/279 280/423/280 +f 280/423/280 275/418/275 274/417/274 +f 275/418/275 280/423/280 281/424/281 +f 281/424/281 276/419/276 275/418/275 +f 276/419/276 281/424/281 282/425/282 +f 282/425/282 277/420/277 276/419/276 +f 278/426/278 283/431/283 284/432/284 +f 284/432/284 279/427/279 278/426/278 +f 279/427/279 284/432/284 285/433/285 +f 285/433/285 280/428/280 279/427/279 +f 280/428/280 285/433/285 286/434/286 +f 286/434/286 281/429/281 280/428/280 +f 281/429/281 286/434/286 287/435/287 +f 287/435/287 282/430/282 281/429/281 +f 283/431/283 288/436/288 289/437/289 +f 289/437/289 284/432/284 283/431/283 +f 284/432/284 289/437/289 290/438/290 +f 290/438/290 285/433/285 284/432/284 +f 285/433/285 290/438/290 291/439/291 +f 291/439/291 286/434/286 285/433/285 +f 286/434/286 291/439/291 292/440/292 +f 292/440/292 287/435/287 286/434/286 +f 288/436/288 293/441/293 294/442/294 +f 294/442/294 289/437/289 288/436/288 +f 289/437/289 294/442/294 295/443/295 +f 295/443/295 290/438/290 289/437/289 +f 290/438/290 295/443/295 296/444/296 +f 296/444/296 291/439/291 290/438/290 +f 291/439/291 296/444/296 297/445/297 +f 297/445/297 292/440/292 291/439/291 +f 293/441/293 258/446/258 259/447/259 +f 259/447/259 294/442/294 293/441/293 +f 294/442/294 259/447/259 260/448/260 +f 260/448/260 295/443/295 294/442/294 +f 295/443/295 260/448/260 261/449/261 +f 261/449/261 296/444/296 295/443/295 +f 296/444/296 261/449/261 262/450/262 +f 262/450/262 297/445/297 296/444/296 +f 262/451/262 267/456/267 302/457/302 +f 302/457/302 298/452/298 262/451/262 +f 298/452/298 302/457/302 303/458/303 +f 303/458/303 299/453/299 298/452/298 +f 299/453/299 303/458/303 304/459/304 +f 304/459/304 300/454/300 299/453/299 +f 300/454/300 304/459/304 305/460/305 +f 305/460/305 301/455/301 300/454/300 +f 267/456/267 272/461/272 306/462/306 +f 306/462/306 302/457/302 267/456/267 +f 302/457/302 306/462/306 307/463/307 +f 307/463/307 303/458/303 302/457/302 +f 303/458/303 307/463/307 308/464/308 +f 308/464/308 304/459/304 303/458/303 +f 304/459/304 308/464/308 309/465/309 +f 309/465/309 305/460/305 304/459/304 +f 272/461/272 277/466/277 310/467/310 +f 310/467/310 306/462/306 272/461/272 +f 306/462/306 310/467/310 311/468/311 +f 311/468/311 307/463/307 306/462/306 +f 307/463/307 311/468/311 312/469/312 +f 312/469/312 308/464/308 307/463/307 +f 308/464/308 312/469/312 313/470/313 +f 313/470/313 309/465/309 308/464/308 +f 277/466/277 282/471/282 314/472/314 +f 314/472/314 310/467/310 277/466/277 +f 310/467/310 314/472/314 315/473/315 +f 315/473/315 311/468/311 310/467/310 +f 311/468/311 315/473/315 316/474/316 +f 316/474/316 312/469/312 311/468/311 +f 312/469/312 316/474/316 317/475/317 +f 317/475/317 313/470/313 312/469/312 +f 282/476/282 287/481/287 318/482/318 +f 318/482/318 314/477/314 282/476/282 +f 314/477/314 318/482/318 319/483/319 +f 319/483/319 315/478/315 314/477/314 +f 315/478/315 319/483/319 320/484/320 +f 320/484/320 316/479/316 315/478/315 +f 316/479/316 320/484/320 321/485/321 +f 321/485/321 317/480/317 316/479/316 +f 287/481/287 292/486/292 322/487/322 +f 322/487/322 318/482/318 287/481/287 +f 318/482/318 322/487/322 323/488/323 +f 323/488/323 319/483/319 318/482/318 +f 319/483/319 323/488/323 324/489/324 +f 324/489/324 320/484/320 319/483/319 +f 320/484/320 324/489/324 325/490/325 +f 325/490/325 321/485/321 320/484/320 +f 292/486/292 297/491/297 326/492/326 +f 326/492/326 322/487/322 292/486/292 +f 322/487/322 326/492/326 327/493/327 +f 327/493/327 323/488/323 322/487/322 +f 323/488/323 327/493/327 328/494/328 +f 328/494/328 324/489/324 323/488/323 +f 324/489/324 328/494/328 329/495/329 +f 329/495/329 325/490/325 324/489/324 +f 297/491/297 262/496/262 298/497/298 +f 298/497/298 326/492/326 297/491/297 +f 326/492/326 298/497/298 299/498/299 +f 299/498/299 327/493/327 326/492/326 +f 327/493/327 299/498/299 300/499/300 +f 300/499/300 328/494/328 327/493/327 +f 328/494/328 300/499/300 301/500/301 +f 301/500/301 329/495/329 328/494/328 +f 330/501/330 335/506/335 336/507/336 +f 336/507/336 331/502/331 330/501/330 +f 331/502/331 336/507/336 337/508/337 +f 337/508/337 332/503/332 331/502/331 +f 332/503/332 337/508/337 338/509/338 +f 338/509/338 333/504/333 332/503/332 +f 333/504/333 338/509/338 339/510/339 +f 339/510/339 334/505/334 333/504/333 +f 335/506/335 340/511/340 341/512/341 +f 341/512/341 336/507/336 335/506/335 +f 336/507/336 341/512/341 342/513/342 +f 342/513/342 337/508/337 336/507/336 +f 337/508/337 342/513/342 343/514/343 +f 343/514/343 338/509/338 337/508/337 +f 338/509/338 343/514/343 344/515/344 +f 344/515/344 339/510/339 338/509/338 +f 340/511/340 345/516/345 346/517/346 +f 346/517/346 341/512/341 340/511/340 +f 341/512/341 346/517/346 347/518/347 +f 347/518/347 342/513/342 341/512/341 +f 342/513/342 347/518/347 348/519/348 +f 348/519/348 343/514/343 342/513/342 +f 343/514/343 348/519/348 349/520/349 +f 349/520/349 344/515/344 343/514/343 +f 345/516/345 350/521/350 351/522/351 +f 351/522/351 346/517/346 345/516/345 +f 346/517/346 351/522/351 352/523/352 +f 352/523/352 347/518/347 346/517/346 +f 347/518/347 352/523/352 353/524/353 +f 353/524/353 348/519/348 347/518/347 +f 348/519/348 353/524/353 354/525/354 +f 354/525/354 349/520/349 348/519/348 +f 350/526/350 355/531/355 356/532/356 +f 356/532/356 351/527/351 350/526/350 +f 351/527/351 356/532/356 357/533/357 +f 357/533/357 352/528/352 351/527/351 +f 352/528/352 357/533/357 358/534/358 +f 358/534/358 353/529/353 352/528/352 +f 353/529/353 358/534/358 359/535/359 +f 359/535/359 354/530/354 353/529/353 +f 355/531/355 360/536/360 361/537/361 +f 361/537/361 356/532/356 355/531/355 +f 356/532/356 361/537/361 362/538/362 +f 362/538/362 357/533/357 356/532/356 +f 357/533/357 362/538/362 363/539/363 +f 363/539/363 358/534/358 357/533/357 +f 358/534/358 363/539/363 364/540/364 +f 364/540/364 359/535/359 358/534/358 +f 360/536/360 365/541/365 366/542/366 +f 366/542/366 361/537/361 360/536/360 +f 361/537/361 366/542/366 367/543/367 +f 367/543/367 362/538/362 361/537/361 +f 362/538/362 367/543/367 368/544/368 +f 368/544/368 363/539/363 362/538/362 +f 363/539/363 368/544/368 369/545/369 +f 369/545/369 364/540/364 363/539/363 +f 365/541/365 330/546/330 331/547/331 +f 331/547/331 366/542/366 365/541/365 +f 366/542/366 331/547/331 332/548/332 +f 332/548/332 367/543/367 366/542/366 +f 367/543/367 332/548/332 333/549/333 +f 333/549/333 368/544/368 367/543/367 +f 368/544/368 333/549/333 334/550/334 +f 334/550/334 369/545/369 368/544/368 +f 334/551/334 339/556/339 374/557/374 +f 374/557/374 370/552/370 334/551/334 +f 370/552/370 374/557/374 375/558/375 +f 375/558/375 371/553/371 370/552/370 +f 371/553/371 375/558/375 376/559/376 +f 376/559/376 372/554/372 371/553/371 +f 372/554/372 376/559/376 377/560/377 +f 377/560/377 373/555/373 372/554/372 +f 339/556/339 344/561/344 378/562/378 +f 378/562/378 374/557/374 339/556/339 +f 374/557/374 378/562/378 379/563/379 +f 379/563/379 375/558/375 374/557/374 +f 375/558/375 379/563/379 380/564/380 +f 380/564/380 376/559/376 375/558/375 +f 376/559/376 380/564/380 381/565/381 +f 381/565/381 377/560/377 376/559/376 +f 344/561/344 349/566/349 382/567/382 +f 382/567/382 378/562/378 344/561/344 +f 378/562/378 382/567/382 383/568/383 +f 383/568/383 379/563/379 378/562/378 +f 379/563/379 383/568/383 384/569/384 +f 384/569/384 380/564/380 379/563/379 +f 380/564/380 384/569/384 385/570/385 +f 385/570/385 381/565/381 380/564/380 +f 349/566/349 354/571/354 386/572/386 +f 386/572/386 382/567/382 349/566/349 +f 382/567/382 386/572/386 387/573/387 +f 387/573/387 383/568/383 382/567/382 +f 383/568/383 387/573/387 388/574/388 +f 388/574/388 384/569/384 383/568/383 +f 384/569/384 388/574/388 389/575/389 +f 389/575/389 385/570/385 384/569/384 +f 354/576/354 359/581/359 390/582/390 +f 390/582/390 386/577/386 354/576/354 +f 386/577/386 390/582/390 391/583/391 +f 391/583/391 387/578/387 386/577/386 +f 387/578/387 391/583/391 392/584/392 +f 392/584/392 388/579/388 387/578/387 +f 388/579/388 392/584/392 393/585/393 +f 393/585/393 389/580/389 388/579/388 +f 359/581/359 364/586/364 394/587/394 +f 394/587/394 390/582/390 359/581/359 +f 390/582/390 394/587/394 395/588/395 +f 395/588/395 391/583/391 390/582/390 +f 391/583/391 395/588/395 396/589/396 +f 396/589/396 392/584/392 391/583/391 +f 392/584/392 396/589/396 397/590/397 +f 397/590/397 393/585/393 392/584/392 +f 364/586/364 369/591/369 398/592/398 +f 398/592/398 394/587/394 364/586/364 +f 394/587/394 398/592/398 399/593/399 +f 399/593/399 395/588/395 394/587/394 +f 395/588/395 399/593/399 400/594/400 +f 400/594/400 396/589/396 395/588/395 +f 396/589/396 400/594/400 401/595/401 +f 401/595/401 397/590/397 396/589/396 +f 369/591/369 334/596/334 370/597/370 +f 370/597/370 398/592/398 369/591/369 +f 398/592/398 370/597/370 371/598/371 +f 371/598/371 399/593/399 398/592/398 +f 399/593/399 371/598/371 372/599/372 +f 372/599/372 400/594/400 399/593/399 +f 400/594/400 372/599/372 373/600/373 +f 373/600/373 401/595/401 400/594/400 +f 407/607/407 403/602/403 402/601/402 +f 403/602/403 407/607/407 408/608/408 +f 408/608/408 404/603/404 403/602/403 +f 404/603/404 408/608/408 409/609/409 +f 409/609/409 405/604/405 404/603/404 +f 405/604/405 409/609/409 410/610/410 +f 410/610/410 406/605/406 405/604/405 +f 411/612/411 407/607/407 402/606/402 +f 407/607/407 411/612/411 412/613/412 +f 412/613/412 408/608/408 407/607/407 +f 408/608/408 412/613/412 413/614/413 +f 413/614/413 409/609/409 408/608/408 +f 409/609/409 413/614/413 414/615/414 +f 414/615/414 410/610/410 409/609/409 +f 415/617/415 411/612/411 402/611/402 +f 411/612/411 415/617/415 416/618/416 +f 416/618/416 412/613/412 411/612/411 +f 412/613/412 416/618/416 417/619/417 +f 417/619/417 413/614/413 412/613/412 +f 413/614/413 417/619/417 418/620/418 +f 418/620/418 414/615/414 413/614/413 +f 419/622/419 415/617/415 402/616/402 +f 415/617/415 419/622/419 420/623/420 +f 420/623/420 416/618/416 415/617/415 +f 416/618/416 420/623/420 421/624/421 +f 421/624/421 417/619/417 416/618/416 +f 417/619/417 421/624/421 422/625/422 +f 422/625/422 418/620/418 417/619/417 +f 423/632/423 419/627/419 402/626/402 +f 419/627/419 423/632/423 424/633/424 +f 424/633/424 420/628/420 419/627/419 +f 420/628/420 424/633/424 425/634/425 +f 425/634/425 421/629/421 420/628/420 +f 421/629/421 425/634/425 426/635/426 +f 426/635/426 422/630/422 421/629/421 +f 427/637/427 423/632/423 402/631/402 +f 423/632/423 427/637/427 428/638/428 +f 428/638/428 424/633/424 423/632/423 +f 424/633/424 428/638/428 429/639/429 +f 429/639/429 425/634/425 424/633/424 +f 425/634/425 429/639/429 430/640/430 +f 430/640/430 426/635/426 425/634/425 +f 431/642/431 427/637/427 402/636/402 +f 427/637/427 431/642/431 432/643/432 +f 432/643/432 428/638/428 427/637/427 +f 428/638/428 432/643/432 433/644/433 +f 433/644/433 429/639/429 428/638/428 +f 429/639/429 433/644/433 434/645/434 +f 434/645/434 430/640/430 429/639/429 +f 435/647/435 431/642/431 402/641/402 +f 431/642/431 435/647/435 436/648/436 +f 436/648/436 432/643/432 431/642/431 +f 432/643/432 436/648/436 437/649/437 +f 437/649/437 433/644/433 432/643/432 +f 433/644/433 437/649/437 438/650/438 +f 438/650/438 434/645/434 433/644/433 +f 439/657/439 435/652/435 402/651/402 +f 435/652/435 439/657/439 440/658/440 +f 440/658/440 436/653/436 435/652/435 +f 436/653/436 440/658/440 441/659/441 +f 441/659/441 437/654/437 436/653/436 +f 437/654/437 441/659/441 442/660/442 +f 442/660/442 438/655/438 437/654/437 +f 443/662/443 439/657/439 402/656/402 +f 439/657/439 443/662/443 444/663/444 +f 444/663/444 440/658/440 439/657/439 +f 440/658/440 444/663/444 445/664/445 +f 445/664/445 441/659/441 440/658/440 +f 441/659/441 445/664/445 446/665/446 +f 446/665/446 442/660/442 441/659/441 +f 447/667/447 443/662/443 402/661/402 +f 443/662/443 447/667/447 448/668/448 +f 448/668/448 444/663/444 443/662/443 +f 444/663/444 448/668/448 449/669/449 +f 449/669/449 445/664/445 444/663/444 +f 445/664/445 449/669/449 450/670/450 +f 450/670/450 446/665/446 445/664/445 +f 451/672/451 447/667/447 402/666/402 +f 447/667/447 451/672/451 452/673/452 +f 452/673/452 448/668/448 447/667/447 +f 448/668/448 452/673/452 453/674/453 +f 453/674/453 449/669/449 448/668/448 +f 449/669/449 453/674/453 454/675/454 +f 454/675/454 450/670/450 449/669/449 +f 455/682/455 451/677/451 402/676/402 +f 451/677/451 455/682/455 456/683/456 +f 456/683/456 452/678/452 451/677/451 +f 452/678/452 456/683/456 457/684/457 +f 457/684/457 453/679/453 452/678/452 +f 453/679/453 457/684/457 458/685/458 +f 458/685/458 454/680/454 453/679/453 +f 459/687/459 455/682/455 402/681/402 +f 455/682/455 459/687/459 460/688/460 +f 460/688/460 456/683/456 455/682/455 +f 456/683/456 460/688/460 461/689/461 +f 461/689/461 457/684/457 456/683/456 +f 457/684/457 461/689/461 462/690/462 +f 462/690/462 458/685/458 457/684/457 +f 463/692/463 459/687/459 402/686/402 +f 459/687/459 463/692/463 464/693/464 +f 464/693/464 460/688/460 459/687/459 +f 460/688/460 464/693/464 465/694/465 +f 465/694/465 461/689/461 460/688/460 +f 461/689/461 465/694/465 466/695/466 +f 466/695/466 462/690/462 461/689/461 +f 403/697/403 463/692/463 402/691/402 +f 463/692/463 403/697/403 404/698/404 +f 404/698/404 464/693/464 463/692/463 +f 464/693/464 404/698/404 405/699/405 +f 405/699/405 465/694/465 464/693/464 +f 465/694/465 405/699/405 406/700/406 +f 406/700/406 466/695/466 465/694/465 +f 406/701/406 410/706/410 471/707/471 +f 471/707/471 467/702/467 406/701/406 +f 467/702/467 471/707/471 472/708/472 +f 472/708/472 468/703/468 467/702/467 +f 468/703/468 472/708/472 473/709/473 +f 473/709/473 469/704/469 468/703/468 +f 469/704/469 473/709/473 474/710/474 +f 474/710/474 470/705/470 469/704/469 +f 410/706/410 414/711/414 475/712/475 +f 475/712/475 471/707/471 410/706/410 +f 471/707/471 475/712/475 476/713/476 +f 476/713/476 472/708/472 471/707/471 +f 472/708/472 476/713/476 477/714/477 +f 477/714/477 473/709/473 472/708/472 +f 473/709/473 477/714/477 478/715/478 +f 478/715/478 474/710/474 473/709/473 +f 414/711/414 418/716/418 479/717/479 +f 479/717/479 475/712/475 414/711/414 +f 475/712/475 479/717/479 480/718/480 +f 480/718/480 476/713/476 475/712/475 +f 476/713/476 480/718/480 481/719/481 +f 481/719/481 477/714/477 476/713/476 +f 477/714/477 481/719/481 482/720/482 +f 482/720/482 478/715/478 477/714/477 +f 418/716/418 422/721/422 483/722/483 +f 483/722/483 479/717/479 418/716/418 +f 479/717/479 483/722/483 484/723/484 +f 484/723/484 480/718/480 479/717/479 +f 480/718/480 484/723/484 485/724/485 +f 485/724/485 481/719/481 480/718/480 +f 481/719/481 485/724/485 486/725/486 +f 486/725/486 482/720/482 481/719/481 +f 422/726/422 426/731/426 487/732/487 +f 487/732/487 483/727/483 422/726/422 +f 483/727/483 487/732/487 488/733/488 +f 488/733/488 484/728/484 483/727/483 +f 484/728/484 488/733/488 489/734/489 +f 489/734/489 485/729/485 484/728/484 +f 485/729/485 489/734/489 490/735/490 +f 490/735/490 486/730/486 485/729/485 +f 426/731/426 430/736/430 491/737/491 +f 491/737/491 487/732/487 426/731/426 +f 487/732/487 491/737/491 492/738/492 +f 492/738/492 488/733/488 487/732/487 +f 488/733/488 492/738/492 493/739/493 +f 493/739/493 489/734/489 488/733/488 +f 489/734/489 493/739/493 494/740/494 +f 494/740/494 490/735/490 489/734/489 +f 430/736/430 434/741/434 495/742/495 +f 495/742/495 491/737/491 430/736/430 +f 491/737/491 495/742/495 496/743/496 +f 496/743/496 492/738/492 491/737/491 +f 492/738/492 496/743/496 497/744/497 +f 497/744/497 493/739/493 492/738/492 +f 493/739/493 497/744/497 498/745/498 +f 498/745/498 494/740/494 493/739/493 +f 434/741/434 438/746/438 499/747/499 +f 499/747/499 495/742/495 434/741/434 +f 495/742/495 499/747/499 500/748/500 +f 500/748/500 496/743/496 495/742/495 +f 496/743/496 500/748/500 501/749/501 +f 501/749/501 497/744/497 496/743/496 +f 497/744/497 501/749/501 502/750/502 +f 502/750/502 498/745/498 497/744/497 +f 438/751/438 442/756/442 503/757/503 +f 503/757/503 499/752/499 438/751/438 +f 499/752/499 503/757/503 504/758/504 +f 504/758/504 500/753/500 499/752/499 +f 500/753/500 504/758/504 505/759/505 +f 505/759/505 501/754/501 500/753/500 +f 501/754/501 505/759/505 506/760/506 +f 506/760/506 502/755/502 501/754/501 +f 442/756/442 446/761/446 507/762/507 +f 507/762/507 503/757/503 442/756/442 +f 503/757/503 507/762/507 508/763/508 +f 508/763/508 504/758/504 503/757/503 +f 504/758/504 508/763/508 509/764/509 +f 509/764/509 505/759/505 504/758/504 +f 505/759/505 509/764/509 510/765/510 +f 510/765/510 506/760/506 505/759/505 +f 446/761/446 450/766/450 511/767/511 +f 511/767/511 507/762/507 446/761/446 +f 507/762/507 511/767/511 512/768/512 +f 512/768/512 508/763/508 507/762/507 +f 508/763/508 512/768/512 513/769/513 +f 513/769/513 509/764/509 508/763/508 +f 509/764/509 513/769/513 514/770/514 +f 514/770/514 510/765/510 509/764/509 +f 450/766/450 454/771/454 515/772/515 +f 515/772/515 511/767/511 450/766/450 +f 511/767/511 515/772/515 516/773/516 +f 516/773/516 512/768/512 511/767/511 +f 512/768/512 516/773/516 517/774/517 +f 517/774/517 513/769/513 512/768/512 +f 513/769/513 517/774/517 518/775/518 +f 518/775/518 514/770/514 513/769/513 +f 454/776/454 458/781/458 519/782/519 +f 519/782/519 515/777/515 454/776/454 +f 515/777/515 519/782/519 520/783/520 +f 520/783/520 516/778/516 515/777/515 +f 516/778/516 520/783/520 521/784/521 +f 521/784/521 517/779/517 516/778/516 +f 517/779/517 521/784/521 522/785/522 +f 522/785/522 518/780/518 517/779/517 +f 458/781/458 462/786/462 523/787/523 +f 523/787/523 519/782/519 458/781/458 +f 519/782/519 523/787/523 524/788/524 +f 524/788/524 520/783/520 519/782/519 +f 520/783/520 524/788/524 525/789/525 +f 525/789/525 521/784/521 520/783/520 +f 521/784/521 525/789/525 526/790/526 +f 526/790/526 522/785/522 521/784/521 +f 462/786/462 466/791/466 527/792/527 +f 527/792/527 523/787/523 462/786/462 +f 523/787/523 527/792/527 528/793/528 +f 528/793/528 524/788/524 523/787/523 +f 524/788/524 528/793/528 529/794/529 +f 529/794/529 525/789/525 524/788/524 +f 525/789/525 529/794/529 530/795/530 +f 530/795/530 526/790/526 525/789/525 +f 466/791/466 406/796/406 467/797/467 +f 467/797/467 527/792/527 466/791/466 +f 527/792/527 467/797/467 468/798/468 +f 468/798/468 528/793/528 527/792/527 +f 528/793/528 468/798/468 469/799/469 +f 469/799/469 529/794/529 528/793/528 +f 529/794/529 469/799/469 470/800/470 +f 470/800/470 530/795/530 529/794/529 +# 992 faces + +g diff --git a/WebCore/manual-tests/webgl/resources/utils3d.js b/WebCore/manual-tests/webgl/resources/utils3d.js new file mode 100644 index 0000000..0ffd7c4 --- /dev/null +++ b/WebCore/manual-tests/webgl/resources/utils3d.js @@ -0,0 +1,531 @@ +// +// initWebGL +// +// Initialize the Canvas element with the passed name as a WebGL object and return the +// CanvasRenderingContext3D. +// +// Load shaders with the passed names and create a program with them. Return this program +// in the 'program' property of the returned context. +// +// For each string in the passed attribs array, bind an attrib with that name at that index. +// Once the attribs are bound, link the program and then use it. +// +// Set the clear color to the passed array (4 values) and set the clear depth to the passed value. +// Enable depth testing and blending with a blend func of (SRC_ALPHA, ONE_MINUS_SRC_ALPHA) +// +function initWebGL(canvasName, vshader, fshader, attribs, clearColor, clearDepth) +{ + var canvas = document.getElementById(canvasName); + var gl = canvas.getContext("webkit-3d"); + + // create our shaders + var vertexShader = loadShader(gl, vshader); + var fragmentShader = loadShader(gl, fshader); + + if (!vertexShader || !fragmentShader) + return null; + + // Create the program object + gl.program = gl.createProgram(); + + if (!gl.program) + return null; + + // Attach our two shaders to the program + gl.attachShader (gl.program, vertexShader); + gl.attachShader (gl.program, fragmentShader); + + // Bind attributes + for (var i in attribs) + gl.bindAttribLocation (gl.program, i, attribs[i]); + + // Link the program + gl.linkProgram(gl.program); + + // Check the link status + var linked = gl.getProgrami(gl.program, gl.LINK_STATUS); + if (!linked) { + // something went wrong with the link + var error = gl.getProgramInfoLog (gl.program); + console.log("Error in program linking:"+error); + + gl.deleteProgram(gl.program); + gl.deleteProgram(fragmentShader); + gl.deleteProgram(vertexShader); + + return null; + } + + gl.useProgram(gl.program); + + gl.clearColor (clearColor[0], clearColor[1], clearColor[2], clearColor[3]); + gl.clearDepth (clearDepth); + + gl.enable(gl.DEPTH_TEST); + gl.enable(gl.BLEND); + gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); + + return gl; +} + +// +// loadShader +// +// 'shaderId' is the id of a <script> element containing the shader source string. +// Load this shader and return the CanvasShader object corresponding to it. +// +function loadShader(ctx, shaderId) +{ + var shaderScript = document.getElementById(shaderId); + if (!shaderScript) { + console.log("*** Error: shader script '"+shaderId+"' not found"); + return null; + } + + if (shaderScript.type == "x-shader/x-vertex") + var shaderType = ctx.VERTEX_SHADER; + else if (shaderScript.type == "x-shader/x-fragment") + var shaderType = ctx.FRAGMENT_SHADER; + else { + console.log("*** Error: shader script '"+shaderId+"' of undefined type '"+shaderScript.type+"'"); + return null; + } + + // Create the shader object + var shader = ctx.createShader(shaderType); + if (shader == null) { + console.log("*** Error: unable to create shader '"+shaderId+"'"); + return null; + } + + // Load the shader source + ctx.shaderSource(shader, shaderScript.text); + + // Compile the shader + ctx.compileShader(shader); + + // Check the compile status + var compiled = ctx.getShaderi(shader, ctx.COMPILE_STATUS); + if (!compiled) { + // Something went wrong during compilation; get the error + var error = ctx.getShaderInfoLog(shader); + console.log("*** Error compiling shader '"+shaderId+"':"+error); + ctx.deleteShader(shader); + return null; + } + + return shader; +} + +// +// makeBox +// +// Create a box with vertices, normals and texCoords. Create VBOs for each as well as the index array. +// Return an object with the following properties: +// +// normalObject CanvasBuffer object for normals +// texCoordObject CanvasBuffer object for texCoords +// vertexObject CanvasBuffer object for vertices +// indexObject CanvasBuffer object for indices +// numIndices The number of indices in the indexObject +// +function makeBox(ctx) +{ + // box + // v6----- v5 + // /| /| + // v1------v0| + // | | | | + // | |v7---|-|v4 + // |/ |/ + // v2------v3 + // + // vertex coords array + var vertices = new CanvasFloatArray( + [ 1, 1, 1, -1, 1, 1, -1,-1, 1, 1,-1, 1, // v0-v1-v2-v3 front + 1, 1, 1, 1,-1, 1, 1,-1,-1, 1, 1,-1, // v0-v3-v4-v5 right + 1, 1, 1, 1, 1,-1, -1, 1,-1, -1, 1, 1, // v0-v5-v6-v1 top + -1, 1, 1, -1, 1,-1, -1,-1,-1, -1,-1, 1, // v1-v6-v7-v2 left + -1,-1,-1, 1,-1,-1, 1,-1, 1, -1,-1, 1, // v7-v4-v3-v2 bottom + 1,-1,-1, -1,-1,-1, -1, 1,-1, 1, 1,-1 ] // v4-v7-v6-v5 back + ); + + // normal array + var normals = new CanvasFloatArray( + [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, // v0-v1-v2-v3 front + 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v0-v3-v4-v5 right + 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, // v0-v5-v6-v1 top + -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, // v1-v6-v7-v2 left + 0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1, 0, // v7-v4-v3-v2 bottom + 0, 0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1 ] // v4-v7-v6-v5 back + ); + + + // texCoord array + var texCoords = new CanvasFloatArray( + [ 1, 1, 0, 1, 0, 0, 1, 0, // v0-v1-v2-v3 front + 0, 1, 0, 0, 1, 0, 1, 1, // v0-v3-v4-v5 right + 1, 0, 1, 1, 0, 1, 0, 0, // v0-v5-v6-v1 top + 1, 1, 0, 1, 0, 0, 1, 0, // v1-v6-v7-v2 left + 0, 0, 1, 0, 1, 1, 0, 1, // v7-v4-v3-v2 bottom + 0, 0, 1, 0, 1, 1, 0, 1 ] // v4-v7-v6-v5 back + ); + + // index array + var indices = new CanvasUnsignedByteArray( + [ 0, 1, 2, 0, 2, 3, // front + 4, 5, 6, 4, 6, 7, // right + 8, 9,10, 8,10,11, // top + 12,13,14, 12,14,15, // left + 16,17,18, 16,18,19, // bottom + 20,21,22, 20,22,23 ] // back + ); + + var retval = { }; + + retval.normalObject = ctx.createBuffer(); + ctx.bindBuffer(ctx.ARRAY_BUFFER, retval.normalObject); + ctx.bufferData(ctx.ARRAY_BUFFER, normals, ctx.STATIC_DRAW); + + retval.texCoordObject = ctx.createBuffer(); + ctx.bindBuffer(ctx.ARRAY_BUFFER, retval.texCoordObject); + ctx.bufferData(ctx.ARRAY_BUFFER, texCoords, ctx.STATIC_DRAW); + + retval.vertexObject = ctx.createBuffer(); + ctx.bindBuffer(ctx.ARRAY_BUFFER, retval.vertexObject); + ctx.bufferData(ctx.ARRAY_BUFFER, vertices, ctx.STATIC_DRAW); + + ctx.bindBuffer(ctx.ARRAY_BUFFER, 0); + + retval.indexObject = ctx.createBuffer(); + ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, retval.indexObject); + ctx.bufferData(ctx.ELEMENT_ARRAY_BUFFER, indices, ctx.STATIC_DRAW); + ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, 0); + + retval.numIndices = indices.length; + + return retval; +} + +// +// makeSphere +// +// Create a sphere with the passed number of latitude and longitude bands and the passed radius. +// Sphere has vertices, normals and texCoords. Create VBOs for each as well as the index array. +// Return an object with the following properties: +// +// normalObject CanvasBuffer object for normals +// texCoordObject CanvasBuffer object for texCoords +// vertexObject CanvasBuffer object for vertices +// indexObject CanvasBuffer object for indices +// numIndices The number of indices in the indexObject +// +function makeSphere(ctx, radius, lats, longs) +{ + var geometryData = [ ]; + var normalData = [ ]; + var texCoordData = [ ]; + var indexData = [ ]; + + for (var latNumber = 0; latNumber <= lats; ++latNumber) { + for (var longNumber = 0; longNumber <= longs; ++longNumber) { + var theta = latNumber * Math.PI / lats; + var phi = longNumber * 2 * Math.PI / longs; + var sinTheta = Math.sin(theta); + var sinPhi = Math.sin(phi); + var cosTheta = Math.cos(theta); + var cosPhi = Math.cos(phi); + + var x = cosPhi * sinTheta; + var y = cosTheta; + var z = sinPhi * sinTheta; + var u = 1-(longNumber/longs); + var v = latNumber/lats; + + normalData.push(x); + normalData.push(y); + normalData.push(z); + texCoordData.push(u); + texCoordData.push(v); + geometryData.push(radius * x); + geometryData.push(radius * y); + geometryData.push(radius * z); + } + } + + longs += 1; + for (var latNumber = 0; latNumber < lats; ++latNumber) { + for (var longNumber = 0; longNumber < longs; ++longNumber) { + var first = (latNumber * longs) + (longNumber % longs); + var second = first + longs; + indexData.push(first); + indexData.push(second); + indexData.push(first+1); + + indexData.push(second); + indexData.push(second+1); + indexData.push(first+1); + } + } + + var retval = { }; + + retval.normalObject = ctx.createBuffer(); + ctx.bindBuffer(ctx.ARRAY_BUFFER, retval.normalObject); + ctx.bufferData(ctx.ARRAY_BUFFER, new CanvasFloatArray(normalData), ctx.STATIC_DRAW); + + retval.texCoordObject = ctx.createBuffer(); + ctx.bindBuffer(ctx.ARRAY_BUFFER, retval.texCoordObject); + ctx.bufferData(ctx.ARRAY_BUFFER, new CanvasFloatArray(texCoordData), ctx.STATIC_DRAW); + + retval.vertexObject = ctx.createBuffer(); + ctx.bindBuffer(ctx.ARRAY_BUFFER, retval.vertexObject); + ctx.bufferData(ctx.ARRAY_BUFFER, new CanvasFloatArray(geometryData), ctx.STATIC_DRAW); + + retval.numIndices = indexData.length; + retval.indexObject = ctx.createBuffer(); + ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, retval.indexObject); + ctx.bufferData(ctx.ELEMENT_ARRAY_BUFFER, new CanvasUnsignedShortArray(indexData), ctx.STREAM_DRAW); + + return retval; +} + +// +// loadObj +// +// Load a .obj file from the passed URL. Return an object with a 'loaded' property set to false. +// When the object load is complete, the 'loaded' property becomes true and the following +// properties are set: +// +// normalObject CanvasBuffer object for normals +// texCoordObject CanvasBuffer object for texCoords +// vertexObject CanvasBuffer object for vertices +// indexObject CanvasBuffer object for indices +// numIndices The number of indices in the indexObject +// +function loadObj(ctx, url) +{ + var obj = { loaded : false }; + obj.ctx = ctx; + var req = new XMLHttpRequest(); + req.obj = obj; + req.onreadystatechange = function () { processLoadObj(req) }; + req.open("GET", url, true); + req.send(null); + return obj; +} + +function processLoadObj(req) +{ + console.log("req="+req) + // only if req shows "complete" + if (req.readyState == 4) { + doLoadObj(req.obj, req.responseText); + } +} + +function doLoadObj(obj, text) +{ + vertexArray = [ ]; + normalArray = [ ]; + textureArray = [ ]; + indexArray = [ ]; + + var vertex = [ ]; + var normal = [ ]; + var texture = [ ]; + var facemap = { }; + var index = 0; + + var lines = text.split("\n"); + for (var lineIndex in lines) { + var line = lines[lineIndex].replace(/[ \t]+/g, " ").replace(/\s\s*$/, ""); + + // ignore comments + if (line[0] == "#") + continue; + + var array = line.split(" "); + if (array[0] == "v") { + // vertex + vertex.push(parseFloat(array[1])); + vertex.push(parseFloat(array[2])); + vertex.push(parseFloat(array[3])); + } + else if (array[0] == "vt") { + // normal + texture.push(parseFloat(array[1])); + texture.push(parseFloat(array[2])); + } + else if (array[0] == "vn") { + // normal + normal.push(parseFloat(array[1])); + normal.push(parseFloat(array[2])); + normal.push(parseFloat(array[3])); + } + else if (array[0] == "f") { + // face + if (array.length != 4) { + console.log("*** Error: face '"+line+"' not handled"); + continue; + } + + for (var i = 1; i < 4; ++i) { + if (!(array[i] in facemap)) { + // add a new entry to the map and arrays + var f = array[i].split("/"); + var vtx, nor, tex; + + if (f.length == 1) { + vtx = parseInt(f[0]) - 1; + nor = vtx; + tex = vtx; + } + else if (f.length = 3) { + vtx = parseInt(f[0]) - 1; + tex = parseInt(f[1]) - 1; + nor = parseInt(f[2]) - 1; + } + else { + console.log("*** Error: did not understand face '"+array[i]+"'"); + return null; + } + + // do the vertices + var x = 0; + var y = 0; + var z = 0; + if (vtx * 3 + 2 < vertex.length) { + x = vertex[vtx*3]; + y = vertex[vtx*3+1]; + z = vertex[vtx*3+2]; + } + vertexArray.push(x); + vertexArray.push(y); + vertexArray.push(z); + + // do the textures + x = 0; + y = 0; + if (tex * 2 + 1 < texture.length) { + x = texture[tex*2]; + y = texture[tex*2+1]; + } + textureArray.push(x); + textureArray.push(y); + + // do the normals + x = 0; + y = 0; + z = 1; + if (nor * 3 + 2 < normal.length) { + x = normal[nor*3]; + y = normal[nor*3+1]; + z = normal[nor*3+2]; + } + normalArray.push(x); + normalArray.push(y); + normalArray.push(z); + + facemap[array[i]] = index++; + } + + indexArray.push(facemap[array[i]]); + } + } + } + + // set the VBOs + obj.normalObject = obj.ctx.createBuffer(); + obj.ctx.bindBuffer(obj.ctx.ARRAY_BUFFER, obj.normalObject); + obj.ctx.bufferData(obj.ctx.ARRAY_BUFFER, new CanvasFloatArray(normalArray), obj.ctx.STATIC_DRAW); + + obj.texCoordObject = obj.ctx.createBuffer(); + obj.ctx.bindBuffer(obj.ctx.ARRAY_BUFFER, obj.texCoordObject); + obj.ctx.bufferData(obj.ctx.ARRAY_BUFFER, new CanvasFloatArray(textureArray), obj.ctx.STATIC_DRAW); + + obj.vertexObject = obj.ctx.createBuffer(); + obj.ctx.bindBuffer(obj.ctx.ARRAY_BUFFER, obj.vertexObject); + obj.ctx.bufferData(obj.ctx.ARRAY_BUFFER, new CanvasFloatArray(vertexArray), obj.ctx.STATIC_DRAW); + + obj.numIndices = indexArray.length; + obj.indexObject = obj.ctx.createBuffer(); + obj.ctx.bindBuffer(obj.ctx.ELEMENT_ARRAY_BUFFER, obj.indexObject); + obj.ctx.bufferData(obj.ctx.ELEMENT_ARRAY_BUFFER, new CanvasUnsignedShortArray(indexArray), obj.ctx.STREAM_DRAW); + + obj.loaded = true; +} + +// +// loadImageTexture +// +// Load the image at the passed url, place it in a new CanvasTexture object and return the CanvasTexture. +// +function loadImageTexture(ctx, url) +{ + var texture = ctx.createTexture(); + texture.image = new Image(); + texture.image.onload = function() { doLoadImageTexture(ctx, texture.image, texture) } + texture.image.src = url; + return texture; +} + +function doLoadImageTexture(ctx, image, texture) +{ + ctx.enable(ctx.TEXTURE_2D); + ctx.bindTexture(ctx.TEXTURE_2D, texture); + ctx.texImage2D(ctx.TEXTURE_2D, 0, image); + ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MAG_FILTER, ctx.LINEAR); + ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.LINEAR_MIPMAP_LINEAR); + ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_S, ctx.CLAMP_TO_EDGE); + ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_T, ctx.CLAMP_TO_EDGE); + ctx.generateMipmap(ctx.TEXTURE_2D) + ctx.bindTexture(ctx.TEXTURE_2D, 0); +} + +// +// Framerate object +// +// This object keeps track of framerate and displays it as the innerHTML text of the +// HTML element with the passed id. Once created you call snapshot at the end +// of every rendering cycle. Every 500ms the framerate is updated in the HTML element. +// +Framerate = function(id) +{ + this.numFramerates = 10; + this.framerateUpdateInterval = 500; + this.id = id; + + this.renderTime = -1; + this.framerates = [ ]; + self = this; + var fr = function() { self.updateFramerate() } + setInterval(fr, this.framerateUpdateInterval); +} + +Framerate.prototype.updateFramerate = function() +{ + var tot = 0; + for (var i = 0; i < this.framerates.length; ++i) + tot += this.framerates[i]; + + var framerate = tot / this.framerates.length; + framerate = Math.round(framerate); + document.getElementById(this.id).innerHTML = "Framerate:"+framerate+"fps"; +} + +Framerate.prototype.snapshot = function() +{ + if (this.renderTime < 0) + this.renderTime = new Date().getTime(); + else { + var newTime = new Date().getTime(); + var t = newTime - this.renderTime; + var framerate = 1000/t; + this.framerates.push(framerate); + while (this.framerates.length > this.numFramerates) + this.framerates.shift(); + this.renderTime = newTime; + } +} + |