This is demo compo posted on Tokyo Demo Fest 2018. https://github.com/r21nomi/TokyoDemoFest2018
Last active
January 12, 2020 23:01
-
-
Save lostintangent/9ac5753b8abf8776ba7a7e40635d9592 to your computer and use it in GitHub Desktop.
Deep Sea Trench
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!-- Vertex Shader --> | |
| <script id="vertexShader" type="x-shader/x-vertex"> | |
| varying vec2 vUv; | |
| varying vec3 vNormal; | |
| void main() { | |
| vUv = uv; | |
| vec4 mvPosition = modelViewMatrix * vec4(position, 1.0); | |
| gl_Position = projectionMatrix * mvPosition; | |
| vNormal = normalize(normalMatrix * normal); | |
| } | |
| </script> | |
| <!-- Fragment Shader --> | |
| <script id="obliqueLineFragmentShader" type="x-shader/x-fragment"> | |
| #ifdef GL_ES | |
| precision mediump float; | |
| #endif | |
| #define PI 3.14159265359 | |
| uniform float time; | |
| uniform vec2 resolution; | |
| uniform vec3 dirLightPos; | |
| uniform vec3 dirLightColor; | |
| uniform vec3 ambientLightColor; | |
| varying vec2 vUv; | |
| varying vec3 vNormal; | |
| float map(float value, float beforeMin, float beforeMax, float afterMin, float afterMax) { | |
| return afterMin + (afterMax - afterMin) * ((value - beforeMin) / (beforeMax - beforeMin)); | |
| } | |
| mat2 rotate2d(float angle){ | |
| return mat2(cos(angle), -sin(angle), sin(angle), cos(angle)); | |
| } | |
| float obliqueLine(vec2 uv){ | |
| return step(0.6, fract((uv.x + uv.y + time * 0.8) * 2.0)); | |
| } | |
| void main( void ) { | |
| vec2 uv = 2.0 * vUv - 1.0; | |
| float directionalLightWeighting = max(dot(normalize(vNormal), dirLightPos), 0.0); | |
| vec3 lightWeighting = ambientLightColor + dirLightColor * directionalLightWeighting; | |
| vec3 ballColor = vec3(0.139,0.000,0.426); | |
| vec3 shadowColor = vec3(0.0, 1.0, 1.0); | |
| vec3 color = mix(ballColor, shadowColor, directionalLightWeighting); | |
| color += obliqueLine(uv * 4.0); | |
| gl_FragColor = vec4(color, 1.0); | |
| } | |
| </script> | |
| <script id="particleVertexShader" type="x-shader/x-vertex"> | |
| attribute vec3 color; | |
| uniform float time; | |
| uniform float size; | |
| varying vec4 vMvPosition; | |
| varying vec3 vColor; | |
| float map(float value, float beforeMin, float beforeMax, float afterMin, float afterMax) { | |
| return afterMin + (afterMax - afterMin) * ((value - beforeMin) / (beforeMax - beforeMin)); | |
| } | |
| void main() { | |
| vec4 mvPosition = modelViewMatrix * vec4(position, 1.0); | |
| vMvPosition = mvPosition; | |
| vColor = color; | |
| gl_PointSize = (size + map(sin(time * 0.05), -1.0, 1.0, 0.0, 100.0)) * (100.0 / length(mvPosition.xyz)); | |
| gl_Position = projectionMatrix * mvPosition; | |
| } | |
| </script> | |
| <script id="particleFragmentShader" type="x-shader/x-fragment"> | |
| uniform sampler2D texture; | |
| uniform float time; | |
| varying vec4 vMvPosition; | |
| varying vec3 vColor; | |
| void main() { | |
| float opacity = 200.0 / length(vMvPosition.xyz); | |
| vec2 uv = gl_PointCoord.xy * 2.0 - 1.0; | |
| float orb = 0.1 / length(vec2(0.0) - uv) * step(0.5, 1.0 - length(uv)); | |
| orb = smoothstep(0.0, 1.0, orb); | |
| vec3 color = vec3(orb) * vColor; | |
| gl_FragColor = vec4(color, 1.0); | |
| } | |
| </script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| initMarchingCube(); | |
| const vertexShader = document.getElementById('vertexShader').textContent; | |
| const obliqueLineFragmentShader = document.getElementById('obliqueLineFragmentShader').textContent; | |
| const particleVertexShader = document.getElementById('particleVertexShader').textContent; | |
| const particleFragmentShader = document.getElementById('particleFragmentShader').textContent; | |
| let windowWidth = window.innerWidth; | |
| let windowHeight = window.innerHeight; | |
| let scene, camera, clock, marchingCubes, renderer, light, pointLight, ambientLight; | |
| let groundGeometry, groundMesh; | |
| let blobsCount = 30; | |
| let updatingCubeSpeedOffset = 1.6; | |
| let groundVertexOffset = 3; | |
| let particlePoints; | |
| let icosahedronGroup = new THREE.Group(); | |
| const uniform = { | |
| time: { | |
| type: 'f', | |
| value: 1.0 | |
| }, | |
| resolution: { | |
| type: "v2", | |
| value: new THREE.Vector2() | |
| }, | |
| dirLightPos: { | |
| type: "v3", | |
| value: new THREE.Vector3() | |
| }, | |
| dirLightColor: { | |
| type: "v3", | |
| value: new THREE.Color(0xeeeeee) | |
| }, | |
| ambientLightColor: { | |
| type: "v3", | |
| value: new THREE.Color(0x050505) | |
| }, | |
| size: { | |
| type: 'f', | |
| value: 32.0 | |
| }, | |
| }; | |
| const init = () => { | |
| scene = new THREE.Scene(); | |
| scene.background = new THREE.Color(0xff0099); | |
| scene.fog = new THREE.FogExp2(0xff0099, 0.0003); | |
| clock = new THREE.Clock(); | |
| // Camera | |
| camera = new THREE.PerspectiveCamera(45, windowWidth / windowHeight, 1, 10000); | |
| camera.position.set(0, 100, 300); | |
| // Light | |
| light = new THREE.DirectionalLight(0xffffff); | |
| light.position.set(0.0, 0.0, 0.0); | |
| scene.add(light); | |
| pointLight = new THREE.PointLight(0x00E4BB, 30, 150); | |
| pointLight.position.set(0, -150, 0); | |
| scene.add(pointLight); | |
| ambientLight = new THREE.AmbientLight(0x00E4BB); | |
| ambientLight.position.set(0, -1.0, 0); | |
| scene.add(ambientLight); | |
| // Ground | |
| groundGeometry = new THREE.PlaneBufferGeometry(20000, 20000, 128, 128); | |
| groundGeometry.rotateX(-Math.PI / 2); | |
| const textureLoader = new THREE.TextureLoader(); | |
| const texture = textureLoader.load('https://s3-us-west-2.amazonaws.com/s.cdpn.io/64807/plastic.jpg'); // Refer to remote URL to access locally. | |
| texture.wrapS = texture.wrapT = THREE.RepeatWrapping; | |
| texture.repeat.set(5, 5); | |
| const groundMaterial = new THREE.MeshBasicMaterial({ | |
| color: 0x00E4BB, | |
| map: texture, | |
| }); | |
| groundMesh = new THREE.Mesh(groundGeometry, groundMaterial); | |
| groundMesh.position.set(0, -500, 0); | |
| scene.add(groundMesh); | |
| // Blobs | |
| uniform.resolution = new THREE.Vector2(windowWidth, windowHeight); | |
| uniform.dirLightPos.value = light.position; | |
| uniform.dirLightColor.value = light.color; | |
| uniform.ambientLightColor.value = ambientLight.color; | |
| const material = new THREE.ShaderMaterial({ | |
| uniforms: uniform, | |
| vertexShader: vertexShader, | |
| fragmentShader: obliqueLineFragmentShader, | |
| }); | |
| const resolution = 48; | |
| marchingCubes = new THREE.MarchingCubes(resolution, material, true, true); | |
| marchingCubes.position.set(0, 0, 0); | |
| marchingCubes.scale.set(100, 100, 100); | |
| scene.add(marchingCubes); | |
| renderer = new THREE.WebGLRenderer(); | |
| renderer.setPixelRatio(window.devicePixelRatio); | |
| renderer.setSize(windowWidth, windowHeight); | |
| document.body.appendChild(renderer.domElement); | |
| renderer.gammaInput = true; | |
| renderer.gammaOutput = true; | |
| renderer.autoClear = false; | |
| addParticles(); | |
| addIcosahedrons(); | |
| }; | |
| const updateCubes = (object, time) => { | |
| object.reset(); | |
| let i, ballx, bally, ballz, subtract, strength; | |
| subtract = 18; | |
| strength = 1.2 / ((Math.sqrt(blobsCount) - 1) / 4 + 1); | |
| for (i = 0; i < blobsCount; i++) { | |
| ballx = Math.sin(i + 1.26 * time * (1.03 + 0.5 * Math.cos(0.21 * i))) * 0.27 + 0.5; | |
| bally = Math.cos(i + 1.12 * time * Math.cos(1.22 + 0.1424 * i)) * 0.27 + 0.5; | |
| ballz = Math.cos(i + 1.32 * time * 0.1 * Math.sin((0.92 + 0.53 * i))) * 0.27 + 0.5; | |
| object.addBall(ballx, bally, ballz, strength, subtract); | |
| } | |
| }; | |
| const updateGround = (time) => { | |
| const position = groundGeometry.attributes.position; | |
| for (let i = 0, len = position.count; i < len; i++) { | |
| let y = 30 * Math.sin(i / 2 + (time * 5 + i)); | |
| if (i % 14 === 0) { | |
| y *= groundVertexOffset; | |
| } | |
| position.setY(i, y); | |
| } | |
| position.needsUpdate = true; | |
| }; | |
| const render = (t) => { | |
| TWEEN.update(t); | |
| clock.getDelta(); | |
| const time = clock.elapsedTime; | |
| updateGround(time); | |
| updateCubes(marchingCubes, time * updatingCubeSpeedOffset); | |
| const cubesRotationSpeed = time * 0.5; | |
| marchingCubes.rotation.x = cubesRotationSpeed; | |
| marchingCubes.rotation.y = cubesRotationSpeed; | |
| marchingCubes.rotation.z = cubesRotationSpeed; | |
| const speed = time * 30 * (Math.PI / 180); | |
| const cameraX = 300 * Math.sin(speed); | |
| const cameraZ = 300 * Math.cos(speed); | |
| camera.position.x = cameraX; | |
| camera.position.z = cameraZ; | |
| camera.position.y = cameraX * 0.3; | |
| camera.lookAt(new THREE.Vector3(0, 0, 0)); | |
| uniform.time.value = time; | |
| let len = icosahedronGroup.children.length; | |
| if (len > 0) { | |
| for (let i = 0; i < len; i++) { | |
| let object = icosahedronGroup.children[i]; | |
| let geometry = object.geometry; | |
| geometry.verticesNeedUpdate = true; | |
| let originalVertices = icosahedronOriginalVerticesArray[i]; | |
| for (let i = 0, len = geometry.vertices.length; i < len; i++) { | |
| let t = time * 8 + i * 300; | |
| let offset = 5; | |
| geometry.vertices[i].x = originalVertices[i].x + Math.sin(t) * offset; | |
| geometry.vertices[i].y = originalVertices[i].y + Math.sin(t * 0.8) * offset; | |
| } | |
| const t = time * 5 + (i % 4) * 80; | |
| object.scale.x = 1.0 + Math.abs(Math.sin(t)); | |
| object.scale.y = 1.0 + Math.abs(Math.sin(t)); | |
| object.scale.z = 1.0 + Math.abs(Math.sin(t)); | |
| } | |
| } | |
| renderer.render(scene, camera); | |
| requestAnimationFrame(render); | |
| }; | |
| const addParticles = () => { | |
| scene.remove(marchingCubes); | |
| const material1 = new THREE.ShaderMaterial({ | |
| uniforms: uniform, | |
| vertexShader: vertexShader, | |
| fragmentShader: obliqueLineFragmentShader, | |
| }); | |
| const resolution = 48; | |
| marchingCubes = new THREE.MarchingCubes(resolution, material1, true, true); | |
| marchingCubes.position.set(0, 0, 0); | |
| marchingCubes.scale.set(100, 100, 100); | |
| scene.add(marchingCubes); | |
| scene.background = new THREE.Color(0x4623DE); | |
| scene.fog = new THREE.FogExp2(0x4623DE, 0.0003); | |
| let colorsPerFace = [ | |
| "#7BFFEF", "#6FE8B8", "#7FFFAC", "#6FE873", "#FFDEAA" | |
| ]; | |
| const hexToRgb = (hex) => { | |
| let result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); | |
| return { | |
| r: parseInt(result[1], 16) / 255, | |
| g: parseInt(result[2], 16) / 255, | |
| b: parseInt(result[3], 16) / 255 | |
| }; | |
| }; | |
| const vertices = []; | |
| const colors = []; | |
| const particleCount = 20000; | |
| const geometry = new THREE.BufferGeometry(); | |
| const dist = window.innerWidth * 0.8; | |
| for (let i = 0; i < particleCount; i++) { | |
| const x = Math.floor(Math.random() * dist - dist / 2); | |
| const y = Math.floor(Math.random() * dist - dist / 2); | |
| const z = Math.floor(Math.random() * dist - dist / 2); | |
| vertices.push(x, y, z); | |
| const rgbColor = hexToRgb(colorsPerFace[Math.floor(Math.random() * colorsPerFace.length)]); | |
| colors.push(rgbColor.r, rgbColor.g, rgbColor.b); | |
| } | |
| const verticesArray = new Float32Array(vertices); | |
| geometry.addAttribute('position', new THREE.BufferAttribute(verticesArray, 3)); | |
| const colorsArray = new Float32Array(colors); | |
| geometry.addAttribute('color', new THREE.BufferAttribute(colorsArray, 3)); | |
| const material2 = new THREE.ShaderMaterial({ | |
| uniforms: uniform, | |
| vertexShader: particleVertexShader, | |
| fragmentShader: particleFragmentShader, | |
| transparent: true, | |
| depthWrite: false, | |
| blending: THREE.AdditiveBlending | |
| }); | |
| particlePoints = new THREE.Points(geometry, material2); | |
| scene.add(particlePoints); | |
| }; | |
| /** | |
| * Show icosahedron. | |
| */ | |
| const addIcosahedrons = () => { | |
| const objectRadius = 30; | |
| const count = 18; | |
| const dist = 600; | |
| for (let i = 0; i < count; i++) { | |
| const angle = 360 / count * Math.PI / 180 * i; | |
| icosahedronGroup.add(createIcosahedron(objectRadius, { | |
| x: Math.cos(angle) * dist, | |
| y: 0, | |
| z: Math.sin(angle) * dist | |
| })); | |
| } | |
| scene.add(icosahedronGroup); | |
| }; | |
| let colorsPerFace = [ | |
| 0x20D8D6, 0x31A3A2, 0x53B9B8, 0x71BCBB, 0xA3DAD9 | |
| ]; | |
| const icosahedronOriginalVerticesArray = []; | |
| const createIcosahedron = (radius, position) => { | |
| let originalVertices = []; | |
| let geometry = new THREE.IcosahedronGeometry(radius); | |
| for (let i = 0, len = geometry.faces.length; i < len; i++) { | |
| let face = geometry.faces[i]; | |
| face.color.setHex(colorsPerFace[Math.floor(Math.random() * colorsPerFace.length)]); | |
| } | |
| for (let i = 0, len = geometry.vertices.length; i < len; i++) { | |
| let vertex = geometry.vertices[i]; | |
| originalVertices.push({ | |
| x: vertex.x, | |
| y: vertex.y | |
| }); | |
| } | |
| let material = new THREE.MeshBasicMaterial({ | |
| vertexColors: THREE.FaceColors | |
| }); | |
| let obj = new THREE.Mesh(geometry, material); | |
| obj.position.x = position.x; | |
| obj.position.y = position.y; | |
| obj.position.z = position.z; | |
| obj.castShadow = true; | |
| icosahedronOriginalVerticesArray.push(originalVertices); | |
| return obj; | |
| }; | |
| const onResize = () => { | |
| windowWidth = window.innerWidth; | |
| windowHeight = window.innerHeight; | |
| camera.aspect = windowWidth / windowHeight; | |
| camera.updateProjectionMatrix(); | |
| renderer.setPixelRatio(window.devicePixelRatio); | |
| renderer.setSize(windowWidth, windowHeight); | |
| }; | |
| window.addEventListener("resize", onResize); | |
| init(); | |
| onResize(); | |
| render(); | |
| function initMarchingCube() { | |
| /** | |
| * @author alteredq / http://alteredqualia.com/ | |
| * @author mrdoob / http://mrdoob.com | |
| * Port of http://webglsamples.org/blob/blob.html | |
| */ | |
| THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors ) { | |
| THREE.ImmediateRenderObject.call( this, material ); | |
| var scope = this; | |
| // temp buffers used in polygonize | |
| var vlist = new Float32Array( 12 * 3 ); | |
| var nlist = new Float32Array( 12 * 3 ); | |
| this.enableUvs = enableUvs !== undefined ? enableUvs : false; | |
| this.enableColors = enableColors !== undefined ? enableColors : false; | |
| // functions have to be object properties | |
| // prototype functions kill performance | |
| // (tested and it was 4x slower !!!) | |
| this.init = function ( resolution ) { | |
| this.resolution = resolution; | |
| // parameters | |
| this.isolation = 80.0; | |
| // size of field, 32 is pushing it in Javascript :) | |
| this.size = resolution; | |
| this.size2 = this.size * this.size; | |
| this.size3 = this.size2 * this.size; | |
| this.halfsize = this.size / 2.0; | |
| // deltas | |
| this.delta = 2.0 / this.size; | |
| this.yd = this.size; | |
| this.zd = this.size2; | |
| this.field = new Float32Array( this.size3 ); | |
| this.normal_cache = new Float32Array( this.size3 * 3 ); | |
| // immediate render mode simulator | |
| this.maxCount = 4096; // TODO: find the fastest size for this buffer | |
| this.count = 0; | |
| this.hasPositions = false; | |
| this.hasNormals = false; | |
| this.hasColors = false; | |
| this.hasUvs = false; | |
| this.positionArray = new Float32Array( this.maxCount * 3 ); | |
| this.normalArray = new Float32Array( this.maxCount * 3 ); | |
| if ( this.enableUvs ) { | |
| this.uvArray = new Float32Array( this.maxCount * 2 ); | |
| } | |
| if ( this.enableColors ) { | |
| this.colorArray = new Float32Array( this.maxCount * 3 ); | |
| } | |
| }; | |
| /////////////////////// | |
| // Polygonization | |
| /////////////////////// | |
| function lerp( a, b, t ) { | |
| return a + ( b - a ) * t; | |
| } | |
| function VIntX( q, offset, isol, x, y, z, valp1, valp2 ) { | |
| var mu = ( isol - valp1 ) / ( valp2 - valp1 ), | |
| nc = scope.normal_cache; | |
| vlist[ offset + 0 ] = x + mu * scope.delta; | |
| vlist[ offset + 1 ] = y; | |
| vlist[ offset + 2 ] = z; | |
| nlist[ offset + 0 ] = lerp( nc[ q + 0 ], nc[ q + 3 ], mu ); | |
| nlist[ offset + 1 ] = lerp( nc[ q + 1 ], nc[ q + 4 ], mu ); | |
| nlist[ offset + 2 ] = lerp( nc[ q + 2 ], nc[ q + 5 ], mu ); | |
| } | |
| function VIntY( q, offset, isol, x, y, z, valp1, valp2 ) { | |
| var mu = ( isol - valp1 ) / ( valp2 - valp1 ), | |
| nc = scope.normal_cache; | |
| vlist[ offset + 0 ] = x; | |
| vlist[ offset + 1 ] = y + mu * scope.delta; | |
| vlist[ offset + 2 ] = z; | |
| var q2 = q + scope.yd * 3; | |
| nlist[ offset + 0 ] = lerp( nc[ q + 0 ], nc[ q2 + 0 ], mu ); | |
| nlist[ offset + 1 ] = lerp( nc[ q + 1 ], nc[ q2 + 1 ], mu ); | |
| nlist[ offset + 2 ] = lerp( nc[ q + 2 ], nc[ q2 + 2 ], mu ); | |
| } | |
| function VIntZ( q, offset, isol, x, y, z, valp1, valp2 ) { | |
| var mu = ( isol - valp1 ) / ( valp2 - valp1 ), | |
| nc = scope.normal_cache; | |
| vlist[ offset + 0 ] = x; | |
| vlist[ offset + 1 ] = y; | |
| vlist[ offset + 2 ] = z + mu * scope.delta; | |
| var q2 = q + scope.zd * 3; | |
| nlist[ offset + 0 ] = lerp( nc[ q + 0 ], nc[ q2 + 0 ], mu ); | |
| nlist[ offset + 1 ] = lerp( nc[ q + 1 ], nc[ q2 + 1 ], mu ); | |
| nlist[ offset + 2 ] = lerp( nc[ q + 2 ], nc[ q2 + 2 ], mu ); | |
| } | |
| function compNorm( q ) { | |
| var q3 = q * 3; | |
| if ( scope.normal_cache[ q3 ] === 0.0 ) { | |
| scope.normal_cache[ q3 + 0 ] = scope.field[ q - 1 ] - scope.field[ q + 1 ]; | |
| scope.normal_cache[ q3 + 1 ] = scope.field[ q - scope.yd ] - scope.field[ q + scope.yd ]; | |
| scope.normal_cache[ q3 + 2 ] = scope.field[ q - scope.zd ] - scope.field[ q + scope.zd ]; | |
| } | |
| } | |
| // Returns total number of triangles. Fills triangles. | |
| // (this is where most of time is spent - it's inner work of O(n3) loop ) | |
| function polygonize( fx, fy, fz, q, isol, renderCallback ) { | |
| // cache indices | |
| var q1 = q + 1, | |
| qy = q + scope.yd, | |
| qz = q + scope.zd, | |
| q1y = q1 + scope.yd, | |
| q1z = q1 + scope.zd, | |
| qyz = q + scope.yd + scope.zd, | |
| q1yz = q1 + scope.yd + scope.zd; | |
| var cubeindex = 0, | |
| field0 = scope.field[ q ], | |
| field1 = scope.field[ q1 ], | |
| field2 = scope.field[ qy ], | |
| field3 = scope.field[ q1y ], | |
| field4 = scope.field[ qz ], | |
| field5 = scope.field[ q1z ], | |
| field6 = scope.field[ qyz ], | |
| field7 = scope.field[ q1yz ]; | |
| if ( field0 < isol ) cubeindex |= 1; | |
| if ( field1 < isol ) cubeindex |= 2; | |
| if ( field2 < isol ) cubeindex |= 8; | |
| if ( field3 < isol ) cubeindex |= 4; | |
| if ( field4 < isol ) cubeindex |= 16; | |
| if ( field5 < isol ) cubeindex |= 32; | |
| if ( field6 < isol ) cubeindex |= 128; | |
| if ( field7 < isol ) cubeindex |= 64; | |
| // if cube is entirely in/out of the surface - bail, nothing to draw | |
| var bits = THREE.edgeTable[ cubeindex ]; | |
| if ( bits === 0 ) return 0; | |
| var d = scope.delta, | |
| fx2 = fx + d, | |
| fy2 = fy + d, | |
| fz2 = fz + d; | |
| // top of the cube | |
| if ( bits & 1 ) { | |
| compNorm( q ); | |
| compNorm( q1 ); | |
| VIntX( q * 3, 0, isol, fx, fy, fz, field0, field1 ); | |
| } | |
| if ( bits & 2 ) { | |
| compNorm( q1 ); | |
| compNorm( q1y ); | |
| VIntY( q1 * 3, 3, isol, fx2, fy, fz, field1, field3 ); | |
| } | |
| if ( bits & 4 ) { | |
| compNorm( qy ); | |
| compNorm( q1y ); | |
| VIntX( qy * 3, 6, isol, fx, fy2, fz, field2, field3 ); | |
| } | |
| if ( bits & 8 ) { | |
| compNorm( q ); | |
| compNorm( qy ); | |
| VIntY( q * 3, 9, isol, fx, fy, fz, field0, field2 ); | |
| } | |
| // bottom of the cube | |
| if ( bits & 16 ) { | |
| compNorm( qz ); | |
| compNorm( q1z ); | |
| VIntX( qz * 3, 12, isol, fx, fy, fz2, field4, field5 ); | |
| } | |
| if ( bits & 32 ) { | |
| compNorm( q1z ); | |
| compNorm( q1yz ); | |
| VIntY( q1z * 3, 15, isol, fx2, fy, fz2, field5, field7 ); | |
| } | |
| if ( bits & 64 ) { | |
| compNorm( qyz ); | |
| compNorm( q1yz ); | |
| VIntX( qyz * 3, 18, isol, fx, fy2, fz2, field6, field7 ); | |
| } | |
| if ( bits & 128 ) { | |
| compNorm( qz ); | |
| compNorm( qyz ); | |
| VIntY( qz * 3, 21, isol, fx, fy, fz2, field4, field6 ); | |
| } | |
| // vertical lines of the cube | |
| if ( bits & 256 ) { | |
| compNorm( q ); | |
| compNorm( qz ); | |
| VIntZ( q * 3, 24, isol, fx, fy, fz, field0, field4 ); | |
| } | |
| if ( bits & 512 ) { | |
| compNorm( q1 ); | |
| compNorm( q1z ); | |
| VIntZ( q1 * 3, 27, isol, fx2, fy, fz, field1, field5 ); | |
| } | |
| if ( bits & 1024 ) { | |
| compNorm( q1y ); | |
| compNorm( q1yz ); | |
| VIntZ( q1y * 3, 30, isol, fx2, fy2, fz, field3, field7 ); | |
| } | |
| if ( bits & 2048 ) { | |
| compNorm( qy ); | |
| compNorm( qyz ); | |
| VIntZ( qy * 3, 33, isol, fx, fy2, fz, field2, field6 ); | |
| } | |
| cubeindex <<= 4; // re-purpose cubeindex into an offset into triTable | |
| var o1, o2, o3, numtris = 0, i = 0; | |
| // here is where triangles are created | |
| while ( THREE.triTable[ cubeindex + i ] != - 1 ) { | |
| o1 = cubeindex + i; | |
| o2 = o1 + 1; | |
| o3 = o1 + 2; | |
| posnormtriv( vlist, nlist, | |
| 3 * THREE.triTable[ o1 ], | |
| 3 * THREE.triTable[ o2 ], | |
| 3 * THREE.triTable[ o3 ], | |
| renderCallback ); | |
| i += 3; | |
| numtris ++; | |
| } | |
| return numtris; | |
| } | |
| ///////////////////////////////////// | |
| // Immediate render mode simulator | |
| ///////////////////////////////////// | |
| function posnormtriv( pos, norm, o1, o2, o3, renderCallback ) { | |
| var c = scope.count * 3; | |
| // positions | |
| scope.positionArray[ c + 0 ] = pos[ o1 ]; | |
| scope.positionArray[ c + 1 ] = pos[ o1 + 1 ]; | |
| scope.positionArray[ c + 2 ] = pos[ o1 + 2 ]; | |
| scope.positionArray[ c + 3 ] = pos[ o2 ]; | |
| scope.positionArray[ c + 4 ] = pos[ o2 + 1 ]; | |
| scope.positionArray[ c + 5 ] = pos[ o2 + 2 ]; | |
| scope.positionArray[ c + 6 ] = pos[ o3 ]; | |
| scope.positionArray[ c + 7 ] = pos[ o3 + 1 ]; | |
| scope.positionArray[ c + 8 ] = pos[ o3 + 2 ]; | |
| // normals | |
| if ( scope.material.flatShading === true ) { | |
| var nx = ( norm[ o1 + 0 ] + norm[ o2 + 0 ] + norm[ o3 + 0 ] ) / 3; | |
| var ny = ( norm[ o1 + 1 ] + norm[ o2 + 1 ] + norm[ o3 + 1 ] ) / 3; | |
| var nz = ( norm[ o1 + 2 ] + norm[ o2 + 2 ] + norm[ o3 + 2 ] ) / 3; | |
| scope.normalArray[ c + 0 ] = nx; | |
| scope.normalArray[ c + 1 ] = ny; | |
| scope.normalArray[ c + 2 ] = nz; | |
| scope.normalArray[ c + 3 ] = nx; | |
| scope.normalArray[ c + 4 ] = ny; | |
| scope.normalArray[ c + 5 ] = nz; | |
| scope.normalArray[ c + 6 ] = nx; | |
| scope.normalArray[ c + 7 ] = ny; | |
| scope.normalArray[ c + 8 ] = nz; | |
| } else { | |
| scope.normalArray[ c + 0 ] = norm[ o1 + 0 ]; | |
| scope.normalArray[ c + 1 ] = norm[ o1 + 1 ]; | |
| scope.normalArray[ c + 2 ] = norm[ o1 + 2 ]; | |
| scope.normalArray[ c + 3 ] = norm[ o2 + 0 ]; | |
| scope.normalArray[ c + 4 ] = norm[ o2 + 1 ]; | |
| scope.normalArray[ c + 5 ] = norm[ o2 + 2 ]; | |
| scope.normalArray[ c + 6 ] = norm[ o3 + 0 ]; | |
| scope.normalArray[ c + 7 ] = norm[ o3 + 1 ]; | |
| scope.normalArray[ c + 8 ] = norm[ o3 + 2 ]; | |
| } | |
| // uvs | |
| if ( scope.enableUvs ) { | |
| var d = scope.count * 2; | |
| scope.uvArray[ d + 0 ] = pos[ o1 + 0 ]; | |
| scope.uvArray[ d + 1 ] = pos[ o1 + 2 ]; | |
| scope.uvArray[ d + 2 ] = pos[ o2 + 0 ]; | |
| scope.uvArray[ d + 3 ] = pos[ o2 + 2 ]; | |
| scope.uvArray[ d + 4 ] = pos[ o3 + 0 ]; | |
| scope.uvArray[ d + 5 ] = pos[ o3 + 2 ]; | |
| } | |
| // colors | |
| if ( scope.enableColors ) { | |
| scope.colorArray[ c + 0 ] = pos[ o1 + 0 ]; | |
| scope.colorArray[ c + 1 ] = pos[ o1 + 1 ]; | |
| scope.colorArray[ c + 2 ] = pos[ o1 + 2 ]; | |
| scope.colorArray[ c + 3 ] = pos[ o2 + 0 ]; | |
| scope.colorArray[ c + 4 ] = pos[ o2 + 1 ]; | |
| scope.colorArray[ c + 5 ] = pos[ o2 + 2 ]; | |
| scope.colorArray[ c + 6 ] = pos[ o3 + 0 ]; | |
| scope.colorArray[ c + 7 ] = pos[ o3 + 1 ]; | |
| scope.colorArray[ c + 8 ] = pos[ o3 + 2 ]; | |
| } | |
| scope.count += 3; | |
| if ( scope.count >= scope.maxCount - 3 ) { | |
| scope.hasPositions = true; | |
| scope.hasNormals = true; | |
| if ( scope.enableUvs ) { | |
| scope.hasUvs = true; | |
| } | |
| if ( scope.enableColors ) { | |
| scope.hasColors = true; | |
| } | |
| renderCallback( scope ); | |
| } | |
| } | |
| this.begin = function () { | |
| this.count = 0; | |
| this.hasPositions = false; | |
| this.hasNormals = false; | |
| this.hasUvs = false; | |
| this.hasColors = false; | |
| }; | |
| this.end = function ( renderCallback ) { | |
| if ( this.count === 0 ) return; | |
| for ( var i = this.count * 3; i < this.positionArray.length; i ++ ) { | |
| this.positionArray[ i ] = 0.0; | |
| } | |
| this.hasPositions = true; | |
| this.hasNormals = true; | |
| if ( this.enableUvs && this.material.map ) { | |
| this.hasUvs = true; | |
| } | |
| if ( this.enableColors && this.material.vertexColors !== THREE.NoColors ) { | |
| this.hasColors = true; | |
| } | |
| renderCallback( this ); | |
| }; | |
| ///////////////////////////////////// | |
| // Metaballs | |
| ///////////////////////////////////// | |
| // Adds a reciprocal ball (nice and blobby) that, to be fast, fades to zero after | |
| // a fixed distance, determined by strength and subtract. | |
| this.addBall = function ( ballx, bally, ballz, strength, subtract ) { | |
| var sign = Math.sign( strength ); | |
| strength = Math.abs( strength ); | |
| // Let's solve the equation to find the radius: | |
| // 1.0 / (0.000001 + radius^2) * strength - subtract = 0 | |
| // strength / (radius^2) = subtract | |
| // strength = subtract * radius^2 | |
| // radius^2 = strength / subtract | |
| // radius = sqrt(strength / subtract) | |
| var radius = this.size * Math.sqrt( strength / subtract ), | |
| zs = ballz * this.size, | |
| ys = bally * this.size, | |
| xs = ballx * this.size; | |
| var min_z = Math.floor( zs - radius ); if ( min_z < 1 ) min_z = 1; | |
| var max_z = Math.floor( zs + radius ); if ( max_z > this.size - 1 ) max_z = this.size - 1; | |
| var min_y = Math.floor( ys - radius ); if ( min_y < 1 ) min_y = 1; | |
| var max_y = Math.floor( ys + radius ); if ( max_y > this.size - 1 ) max_y = this.size - 1; | |
| var min_x = Math.floor( xs - radius ); if ( min_x < 1 ) min_x = 1; | |
| var max_x = Math.floor( xs + radius ); if ( max_x > this.size - 1 ) max_x = this.size - 1; | |
| // Don't polygonize in the outer layer because normals aren't | |
| // well-defined there. | |
| var x, y, z, y_offset, z_offset, fx, fy, fz, fz2, fy2, val; | |
| for ( z = min_z; z < max_z; z ++ ) { | |
| z_offset = this.size2 * z; | |
| fz = z / this.size - ballz; | |
| fz2 = fz * fz; | |
| for ( y = min_y; y < max_y; y ++ ) { | |
| y_offset = z_offset + this.size * y; | |
| fy = y / this.size - bally; | |
| fy2 = fy * fy; | |
| for ( x = min_x; x < max_x; x ++ ) { | |
| fx = x / this.size - ballx; | |
| val = strength / ( 0.000001 + fx * fx + fy2 + fz2 ) - subtract; | |
| if ( val > 0.0 ) this.field[ y_offset + x ] += val * sign; | |
| } | |
| } | |
| } | |
| }; | |
| this.addPlaneX = function ( strength, subtract ) { | |
| var x, y, z, xx, val, xdiv, cxy, | |
| // cache attribute lookups | |
| size = this.size, | |
| yd = this.yd, | |
| zd = this.zd, | |
| field = this.field, | |
| dist = size * Math.sqrt( strength / subtract ); | |
| if ( dist > size ) dist = size; | |
| for ( x = 0; x < dist; x ++ ) { | |
| xdiv = x / size; | |
| xx = xdiv * xdiv; | |
| val = strength / ( 0.0001 + xx ) - subtract; | |
| if ( val > 0.0 ) { | |
| for ( y = 0; y < size; y ++ ) { | |
| cxy = x + y * yd; | |
| for ( z = 0; z < size; z ++ ) { | |
| field[ zd * z + cxy ] += val; | |
| } | |
| } | |
| } | |
| } | |
| }; | |
| this.addPlaneY = function ( strength, subtract ) { | |
| var x, y, z, yy, val, ydiv, cy, cxy, | |
| // cache attribute lookups | |
| size = this.size, | |
| yd = this.yd, | |
| zd = this.zd, | |
| field = this.field, | |
| dist = size * Math.sqrt( strength / subtract ); | |
| if ( dist > size ) dist = size; | |
| for ( y = 0; y < dist; y ++ ) { | |
| ydiv = y / size; | |
| yy = ydiv * ydiv; | |
| val = strength / ( 0.0001 + yy ) - subtract; | |
| if ( val > 0.0 ) { | |
| cy = y * yd; | |
| for ( x = 0; x < size; x ++ ) { | |
| cxy = cy + x; | |
| for ( z = 0; z < size; z ++ ) | |
| field[ zd * z + cxy ] += val; | |
| } | |
| } | |
| } | |
| }; | |
| this.addPlaneZ = function ( strength, subtract ) { | |
| var x, y, z, zz, val, zdiv, cz, cyz, | |
| // cache attribute lookups | |
| size = this.size, | |
| yd = this.yd, | |
| zd = this.zd, | |
| field = this.field, | |
| dist = size * Math.sqrt( strength / subtract ); | |
| if ( dist > size ) dist = size; | |
| for ( z = 0; z < dist; z ++ ) { | |
| zdiv = z / size; | |
| zz = zdiv * zdiv; | |
| val = strength / ( 0.0001 + zz ) - subtract; | |
| if ( val > 0.0 ) { | |
| cz = zd * z; | |
| for ( y = 0; y < size; y ++ ) { | |
| cyz = cz + y * yd; | |
| for ( x = 0; x < size; x ++ ) | |
| field[ cyz + x ] += val; | |
| } | |
| } | |
| } | |
| }; | |
| ///////////////////////////////////// | |
| // Updates | |
| ///////////////////////////////////// | |
| this.reset = function () { | |
| var i; | |
| // wipe the normal cache | |
| for ( i = 0; i < this.size3; i ++ ) { | |
| this.normal_cache[ i * 3 ] = 0.0; | |
| this.field[ i ] = 0.0; | |
| } | |
| }; | |
| this.render = function ( renderCallback ) { | |
| this.begin(); | |
| // Triangulate. Yeah, this is slow. | |
| var smin2 = this.size - 2; | |
| for ( var z = 1; z < smin2; z ++ ) { | |
| var z_offset = this.size2 * z; | |
| var fz = ( z - this.halfsize ) / this.halfsize; //+ 1 | |
| for ( var y = 1; y < smin2; y ++ ) { | |
| var y_offset = z_offset + this.size * y; | |
| var fy = ( y - this.halfsize ) / this.halfsize; //+ 1 | |
| for ( var x = 1; x < smin2; x ++ ) { | |
| var fx = ( x - this.halfsize ) / this.halfsize; //+ 1 | |
| var q = y_offset + x; | |
| polygonize( fx, fy, fz, q, this.isolation, renderCallback ); | |
| } | |
| } | |
| } | |
| this.end( renderCallback ); | |
| }; | |
| this.generateGeometry = function () { | |
| console.warn( 'THREE.MarchingCubes: generateGeometry() now returns THREE.BufferGeometry' ); | |
| return this.generateBufferGeometry(); | |
| }; | |
| function concatenate( a, b, length ) { | |
| var result = new Float32Array( a.length + length ); | |
| result.set( a, 0 ); | |
| result.set( b.slice( 0, length ), a.length ); | |
| return result; | |
| } | |
| this.generateBufferGeometry = function () { | |
| var geo = new THREE.BufferGeometry(); | |
| var posArray = new Float32Array(); | |
| var normArray = new Float32Array(); | |
| var colorArray = new Float32Array(); | |
| var uvArray = new Float32Array(); | |
| var scope = this; | |
| var geo_callback = function ( object ) { | |
| if ( scope.hasPositions ) posArray = concatenate( posArray, object.positionArray, object.count * 3 ); | |
| if ( scope.hasNormals ) normArray = concatenate( normArray, object.normalArray, object.count * 3 ); | |
| if ( scope.hasColors ) colorArray = concatenate( colorArray, object.colorArray, object.count * 3 ); | |
| if ( scope.hasUvs ) uvArray = concatenate( uvArray, object.uvArray, object.count * 2 ); | |
| object.count = 0; | |
| }; | |
| this.render( geo_callback ); | |
| if ( this.hasPositions ) geo.addAttribute( 'position', new THREE.BufferAttribute( posArray, 3 ) ); | |
| if ( this.hasNormals ) geo.addAttribute( 'normal', new THREE.BufferAttribute( normArray, 3 ) ); | |
| if ( this.hasColors ) geo.addAttribute( 'color', new THREE.BufferAttribute( colorArray, 3 ) ); | |
| if ( this.hasUvs ) geo.addAttribute( 'uv', new THREE.BufferAttribute( uvArray, 2 ) ); | |
| return geo; | |
| }; | |
| this.init( resolution ); | |
| }; | |
| THREE.MarchingCubes.prototype = Object.create( THREE.ImmediateRenderObject.prototype ); | |
| THREE.MarchingCubes.prototype.constructor = THREE.MarchingCubes; | |
| ///////////////////////////////////// | |
| // Marching cubes lookup tables | |
| ///////////////////////////////////// | |
| // These tables are straight from Paul Bourke's page: | |
| // http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise/ | |
| // who in turn got them from Cory Gene Bloyd. | |
| THREE.edgeTable = new Int32Array( [ | |
| 0x0, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, | |
| 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00, | |
| 0x190, 0x99, 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, | |
| 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90, | |
| 0x230, 0x339, 0x33, 0x13a, 0x636, 0x73f, 0x435, 0x53c, | |
| 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30, | |
| 0x3a0, 0x2a9, 0x1a3, 0xaa, 0x7a6, 0x6af, 0x5a5, 0x4ac, | |
| 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0, | |
| 0x460, 0x569, 0x663, 0x76a, 0x66, 0x16f, 0x265, 0x36c, | |
| 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60, | |
| 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff, 0x3f5, 0x2fc, | |
| 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0, | |
| 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55, 0x15c, | |
| 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950, | |
| 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc, | |
| 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0, | |
| 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, | |
| 0xcc, 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0, | |
| 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, | |
| 0x15c, 0x55, 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650, | |
| 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, | |
| 0x2fc, 0x3f5, 0xff, 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0, | |
| 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, | |
| 0x36c, 0x265, 0x16f, 0x66, 0x76a, 0x663, 0x569, 0x460, | |
| 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, | |
| 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa, 0x1a3, 0x2a9, 0x3a0, | |
| 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, | |
| 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33, 0x339, 0x230, | |
| 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, | |
| 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99, 0x190, | |
| 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, | |
| 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0 ] ); | |
| THREE.triTable = new Int32Array( [ | |
| - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 0, 8, 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 0, 1, 9, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 1, 8, 3, 9, 8, 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 1, 2, 10, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 0, 8, 3, 1, 2, 10, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 9, 2, 10, 0, 2, 9, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 2, 8, 3, 2, 10, 8, 10, 9, 8, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 3, 11, 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 0, 11, 2, 8, 11, 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 1, 9, 0, 2, 3, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 1, 11, 2, 1, 9, 11, 9, 8, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 3, 10, 1, 11, 10, 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 0, 10, 1, 0, 8, 10, 8, 11, 10, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 3, 9, 0, 3, 11, 9, 11, 10, 9, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 9, 8, 10, 10, 8, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 4, 7, 8, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 4, 3, 0, 7, 3, 4, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 0, 1, 9, 8, 4, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 4, 1, 9, 4, 7, 1, 7, 3, 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 1, 2, 10, 8, 4, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 3, 4, 7, 3, 0, 4, 1, 2, 10, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 9, 2, 10, 9, 0, 2, 8, 4, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, - 1, - 1, - 1, - 1, | |
| 8, 4, 7, 3, 11, 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 11, 4, 7, 11, 2, 4, 2, 0, 4, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 9, 0, 1, 8, 4, 7, 2, 3, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, - 1, - 1, - 1, - 1, | |
| 3, 10, 1, 3, 11, 10, 7, 8, 4, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, - 1, - 1, - 1, - 1, | |
| 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, - 1, - 1, - 1, - 1, | |
| 4, 7, 11, 4, 11, 9, 9, 11, 10, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 9, 5, 4, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 9, 5, 4, 0, 8, 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 0, 5, 4, 1, 5, 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 8, 5, 4, 8, 3, 5, 3, 1, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 1, 2, 10, 9, 5, 4, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 3, 0, 8, 1, 2, 10, 4, 9, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 5, 2, 10, 5, 4, 2, 4, 0, 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, - 1, - 1, - 1, - 1, | |
| 9, 5, 4, 2, 3, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 0, 11, 2, 0, 8, 11, 4, 9, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 0, 5, 4, 0, 1, 5, 2, 3, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, - 1, - 1, - 1, - 1, | |
| 10, 3, 11, 10, 1, 3, 9, 5, 4, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, - 1, - 1, - 1, - 1, | |
| 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, - 1, - 1, - 1, - 1, | |
| 5, 4, 8, 5, 8, 10, 10, 8, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 9, 7, 8, 5, 7, 9, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 9, 3, 0, 9, 5, 3, 5, 7, 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 0, 7, 8, 0, 1, 7, 1, 5, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 1, 5, 3, 3, 5, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 9, 7, 8, 9, 5, 7, 10, 1, 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, - 1, - 1, - 1, - 1, | |
| 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, - 1, - 1, - 1, - 1, | |
| 2, 10, 5, 2, 5, 3, 3, 5, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 7, 9, 5, 7, 8, 9, 3, 11, 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, - 1, - 1, - 1, - 1, | |
| 2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, - 1, - 1, - 1, - 1, | |
| 11, 2, 1, 11, 1, 7, 7, 1, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, - 1, - 1, - 1, - 1, | |
| 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, - 1, | |
| 11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, - 1, | |
| 11, 10, 5, 7, 11, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 10, 6, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 0, 8, 3, 5, 10, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 9, 0, 1, 5, 10, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 1, 8, 3, 1, 9, 8, 5, 10, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 1, 6, 5, 2, 6, 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 1, 6, 5, 1, 2, 6, 3, 0, 8, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 9, 6, 5, 9, 0, 6, 0, 2, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, - 1, - 1, - 1, - 1, | |
| 2, 3, 11, 10, 6, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 11, 0, 8, 11, 2, 0, 10, 6, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 0, 1, 9, 2, 3, 11, 5, 10, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, - 1, - 1, - 1, - 1, | |
| 6, 3, 11, 6, 5, 3, 5, 1, 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, - 1, - 1, - 1, - 1, | |
| 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, - 1, - 1, - 1, - 1, | |
| 6, 5, 9, 6, 9, 11, 11, 9, 8, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 5, 10, 6, 4, 7, 8, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 4, 3, 0, 4, 7, 3, 6, 5, 10, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 1, 9, 0, 5, 10, 6, 8, 4, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, - 1, - 1, - 1, - 1, | |
| 6, 1, 2, 6, 5, 1, 4, 7, 8, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, - 1, - 1, - 1, - 1, | |
| 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, - 1, - 1, - 1, - 1, | |
| 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, - 1, | |
| 3, 11, 2, 7, 8, 4, 10, 6, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, - 1, - 1, - 1, - 1, | |
| 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, - 1, - 1, - 1, - 1, | |
| 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, - 1, | |
| 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, - 1, - 1, - 1, - 1, | |
| 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, - 1, | |
| 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, - 1, | |
| 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, - 1, - 1, - 1, - 1, | |
| 10, 4, 9, 6, 4, 10, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 4, 10, 6, 4, 9, 10, 0, 8, 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 10, 0, 1, 10, 6, 0, 6, 4, 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, - 1, - 1, - 1, - 1, | |
| 1, 4, 9, 1, 2, 4, 2, 6, 4, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, - 1, - 1, - 1, - 1, | |
| 0, 2, 4, 4, 2, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 8, 3, 2, 8, 2, 4, 4, 2, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 10, 4, 9, 10, 6, 4, 11, 2, 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, - 1, - 1, - 1, - 1, | |
| 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, - 1, - 1, - 1, - 1, | |
| 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, - 1, | |
| 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, - 1, - 1, - 1, - 1, | |
| 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, - 1, | |
| 3, 11, 6, 3, 6, 0, 0, 6, 4, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 6, 4, 8, 11, 6, 8, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 7, 10, 6, 7, 8, 10, 8, 9, 10, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, - 1, - 1, - 1, - 1, | |
| 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, - 1, - 1, - 1, - 1, | |
| 10, 6, 7, 10, 7, 1, 1, 7, 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, - 1, - 1, - 1, - 1, | |
| 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, - 1, | |
| 7, 8, 0, 7, 0, 6, 6, 0, 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 7, 3, 2, 6, 7, 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, - 1, - 1, - 1, - 1, | |
| 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, - 1, | |
| 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, - 1, | |
| 11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, - 1, - 1, - 1, - 1, | |
| 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, - 1, | |
| 0, 9, 1, 11, 6, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, - 1, - 1, - 1, - 1, | |
| 7, 11, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 7, 6, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 3, 0, 8, 11, 7, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 0, 1, 9, 11, 7, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 8, 1, 9, 8, 3, 1, 11, 7, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 10, 1, 2, 6, 11, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 1, 2, 10, 3, 0, 8, 6, 11, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 2, 9, 0, 2, 10, 9, 6, 11, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, - 1, - 1, - 1, - 1, | |
| 7, 2, 3, 6, 2, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 7, 0, 8, 7, 6, 0, 6, 2, 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 2, 7, 6, 2, 3, 7, 0, 1, 9, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, - 1, - 1, - 1, - 1, | |
| 10, 7, 6, 10, 1, 7, 1, 3, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, - 1, - 1, - 1, - 1, | |
| 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, - 1, - 1, - 1, - 1, | |
| 7, 6, 10, 7, 10, 8, 8, 10, 9, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 6, 8, 4, 11, 8, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 3, 6, 11, 3, 0, 6, 0, 4, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 8, 6, 11, 8, 4, 6, 9, 0, 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, - 1, - 1, - 1, - 1, | |
| 6, 8, 4, 6, 11, 8, 2, 10, 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, - 1, - 1, - 1, - 1, | |
| 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, - 1, - 1, - 1, - 1, | |
| 10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, - 1, | |
| 8, 2, 3, 8, 4, 2, 4, 6, 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 0, 4, 2, 4, 6, 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, - 1, - 1, - 1, - 1, | |
| 1, 9, 4, 1, 4, 2, 2, 4, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, - 1, - 1, - 1, - 1, | |
| 10, 1, 0, 10, 0, 6, 6, 0, 4, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, - 1, | |
| 10, 9, 4, 6, 10, 4, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 4, 9, 5, 7, 6, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 0, 8, 3, 4, 9, 5, 11, 7, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 5, 0, 1, 5, 4, 0, 7, 6, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, - 1, - 1, - 1, - 1, | |
| 9, 5, 4, 10, 1, 2, 7, 6, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, - 1, - 1, - 1, - 1, | |
| 7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, - 1, - 1, - 1, - 1, | |
| 3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, - 1, | |
| 7, 2, 3, 7, 6, 2, 5, 4, 9, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, - 1, - 1, - 1, - 1, | |
| 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, - 1, - 1, - 1, - 1, | |
| 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, - 1, | |
| 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, - 1, - 1, - 1, - 1, | |
| 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, - 1, | |
| 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, - 1, | |
| 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, - 1, - 1, - 1, - 1, | |
| 6, 9, 5, 6, 11, 9, 11, 8, 9, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, - 1, - 1, - 1, - 1, | |
| 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, - 1, - 1, - 1, - 1, | |
| 6, 11, 3, 6, 3, 5, 5, 3, 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, - 1, - 1, - 1, - 1, | |
| 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, - 1, | |
| 11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, - 1, | |
| 6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, - 1, - 1, - 1, - 1, | |
| 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, - 1, - 1, - 1, - 1, | |
| 9, 5, 6, 9, 6, 0, 0, 6, 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, - 1, | |
| 1, 5, 6, 2, 1, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, - 1, | |
| 10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, - 1, - 1, - 1, - 1, | |
| 0, 3, 8, 5, 6, 10, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 10, 5, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 11, 5, 10, 7, 5, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 11, 5, 10, 11, 7, 5, 8, 3, 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 5, 11, 7, 5, 10, 11, 1, 9, 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, - 1, - 1, - 1, - 1, | |
| 11, 1, 2, 11, 7, 1, 7, 5, 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, - 1, - 1, - 1, - 1, | |
| 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, - 1, - 1, - 1, - 1, | |
| 7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, - 1, | |
| 2, 5, 10, 2, 3, 5, 3, 7, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, - 1, - 1, - 1, - 1, | |
| 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, - 1, - 1, - 1, - 1, | |
| 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, - 1, | |
| 1, 3, 5, 3, 7, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 0, 8, 7, 0, 7, 1, 1, 7, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 9, 0, 3, 9, 3, 5, 5, 3, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 9, 8, 7, 5, 9, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 5, 8, 4, 5, 10, 8, 10, 11, 8, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, - 1, - 1, - 1, - 1, | |
| 0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, - 1, - 1, - 1, - 1, | |
| 10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, - 1, | |
| 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, - 1, - 1, - 1, - 1, | |
| 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, - 1, | |
| 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, - 1, | |
| 9, 4, 5, 2, 11, 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, - 1, - 1, - 1, - 1, | |
| 5, 10, 2, 5, 2, 4, 4, 2, 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, - 1, | |
| 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, - 1, - 1, - 1, - 1, | |
| 8, 4, 5, 8, 5, 3, 3, 5, 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 0, 4, 5, 1, 0, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, - 1, - 1, - 1, - 1, | |
| 9, 4, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 4, 11, 7, 4, 9, 11, 9, 10, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, - 1, - 1, - 1, - 1, | |
| 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, - 1, - 1, - 1, - 1, | |
| 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, - 1, | |
| 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, - 1, - 1, - 1, - 1, | |
| 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, - 1, | |
| 11, 7, 4, 11, 4, 2, 2, 4, 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, - 1, - 1, - 1, - 1, | |
| 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, - 1, - 1, - 1, - 1, | |
| 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, - 1, | |
| 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, - 1, | |
| 1, 10, 2, 8, 7, 4, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 4, 9, 1, 4, 1, 7, 7, 1, 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, - 1, - 1, - 1, - 1, | |
| 4, 0, 3, 7, 4, 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 4, 8, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 9, 10, 8, 10, 11, 8, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 3, 0, 9, 3, 9, 11, 11, 9, 10, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 0, 1, 10, 0, 10, 8, 8, 10, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 3, 1, 10, 11, 3, 10, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 1, 2, 11, 1, 11, 9, 9, 11, 8, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, - 1, - 1, - 1, - 1, | |
| 0, 2, 11, 8, 0, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 3, 2, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 2, 3, 8, 2, 8, 10, 10, 8, 9, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 9, 10, 2, 0, 9, 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, - 1, - 1, - 1, - 1, | |
| 1, 10, 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 1, 3, 8, 9, 1, 8, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 0, 9, 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| 0, 3, 8, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, | |
| - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1 ] ); | |
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/96/three.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/17.2.0/Tween.min.js"></script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment