Created
February 11, 2022 20:15
-
-
Save audinue/276f802ff50fd273bdc0858fc4fb9a73 to your computer and use it in GitHub Desktop.
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
| const renderTriangles = (triangles, options) => { | |
| options = { | |
| eye: [0, 1, 1], | |
| center: [0, 0, 0], | |
| mode: 'both', | |
| orbit: true, | |
| ...options | |
| } | |
| const wireframe = ([a, b, c]) => [a, b, b, c, c, a] | |
| const throwIfTruthy = message => { | |
| if (message) { | |
| throw new Error(message) | |
| } | |
| } | |
| const createProgram = (gl, vs, fs) => { | |
| const program = gl.createProgram() | |
| const vertex = gl.createShader(gl.VERTEX_SHADER) | |
| const fragment = gl.createShader(gl.FRAGMENT_SHADER) | |
| gl.shaderSource(vertex, vs) | |
| gl.shaderSource(fragment, fs) | |
| gl.compileShader(vertex) | |
| gl.compileShader(fragment) | |
| throwIfTruthy(gl.getShaderInfoLog(vertex)) | |
| throwIfTruthy(gl.getShaderInfoLog(fragment)) | |
| gl.attachShader(program, vertex) | |
| gl.attachShader(program, fragment) | |
| gl.linkProgram(program) | |
| return program | |
| } | |
| const main = () => { | |
| const canvas = Object.assign( | |
| document.createElement('canvas'), | |
| { width: 500, height: 500 } | |
| ) | |
| const gl = canvas.getContext('webgl') | |
| const triangleProgram = createProgram(gl, ` | |
| varying mediump vec3 interpolatedColor; | |
| attribute vec3 position; | |
| attribute vec3 color; | |
| uniform mat4 mvp; | |
| void main () { | |
| gl_Position = mvp * vec4(position, 1); | |
| interpolatedColor = color; | |
| } | |
| `, ` | |
| precision mediump float; | |
| varying vec3 interpolatedColor; | |
| void main () { | |
| // gl_FragColor = vec4(floor(interpolatedColor * 20.0) / 20.0, 1); | |
| gl_FragColor = vec4(interpolatedColor, 1); | |
| } | |
| `) | |
| const wireframeProgram = createProgram(gl, ` | |
| attribute vec3 position; | |
| uniform mat4 mvp; | |
| void main () { | |
| gl_Position = mvp * vec4(position, 1); | |
| } | |
| `, ` | |
| void main () { | |
| gl_FragColor = vec4(1, 1, 1, 1); | |
| } | |
| `) | |
| const triangleMvp = gl.getUniformLocation(triangleProgram, 'mvp') | |
| const wireframeMvp = gl.getUniformLocation(wireframeProgram, 'mvp') | |
| const triangleBuffer = gl.createBuffer() | |
| const wireframeBuffer = gl.createBuffer() | |
| const projection = glMatrix.mat4.create() | |
| const view = glMatrix.mat4.create() | |
| const mvp = glMatrix.mat4.create() | |
| gl.enableVertexAttribArray(0) | |
| gl.clearColor(0.15, 0.15, 0.15, 1) | |
| gl.enable(gl.CULL_FACE) | |
| gl.enable(gl.DEPTH_TEST) | |
| gl.bindBuffer(gl.ARRAY_BUFFER, triangleBuffer) | |
| gl.bufferData(gl.ARRAY_BUFFER, new Float32Array( | |
| triangles | |
| .flatMap(triangle => triangle | |
| .flatMap(vertex => vertex | |
| .flatMap(value => value))) | |
| ), gl.STATIC_DRAW) | |
| gl.bindBuffer(gl.ARRAY_BUFFER, wireframeBuffer) | |
| gl.bufferData(gl.ARRAY_BUFFER, new Float32Array( | |
| triangles | |
| .map(triangle => triangle | |
| .map(vertex => vertex[0])) | |
| .flatMap(wireframe) | |
| .flatMap(position => position) | |
| ), gl.STATIC_DRAW) | |
| glMatrix.mat4.perspective(projection, glMatrix.glMatrix.toRadian(90), 1, 0.001) | |
| glMatrix.mat4.lookAt(view, options.eye, options.center, [0, 1, 0]) | |
| glMatrix.mat4.multiply(mvp, projection, view) | |
| const animate = () => { | |
| if (options.orbit) { | |
| glMatrix.vec3.rotateY(options.eye, options.eye, options.center, glMatrix.glMatrix.toRadian(1)) | |
| glMatrix.mat4.lookAt(view, options.eye, options.center, [0, 1, 0]) | |
| glMatrix.mat4.multiply(mvp, projection, view) | |
| } | |
| gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) | |
| if (options.mode === 'both' || options.mode === 'triangles') { | |
| gl.useProgram(triangleProgram) | |
| gl.enableVertexAttribArray(1) | |
| gl.bindBuffer(gl.ARRAY_BUFFER, triangleBuffer) | |
| gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 6 * 4, 0 * 4) | |
| gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 6 * 4, 3 * 4) | |
| gl.uniformMatrix4fv(triangleMvp, false, mvp) | |
| gl.drawArrays(gl.TRIANGLES, 0, triangles.length * 3) | |
| } | |
| if (options.mode === 'both' || options.mode === 'wireframe') { | |
| gl.useProgram(wireframeProgram) | |
| gl.disableVertexAttribArray(1) | |
| gl.bindBuffer(gl.ARRAY_BUFFER, wireframeBuffer) | |
| gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0) | |
| gl.uniformMatrix4fv(wireframeMvp, false, mvp) | |
| gl.drawArrays(gl.LINES, 0, triangles.length * 6) | |
| } | |
| requestAnimationFrame(animate) | |
| } | |
| const info = Object.assign(document.createElement('p'), { | |
| textContent: `Triangle count: ${triangles.length}`, | |
| style: 'font: 12pt sans-serif' | |
| }) | |
| document.body.append(canvas, info) | |
| requestAnimationFrame(animate) | |
| } | |
| if (document.body) { | |
| main() | |
| } else { | |
| addEventListener('DOMContentLoaded', main) | |
| } | |
| } |
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="gl-matrix-min.js"></script> | |
| <script src="render-triangles.js"></script> | |
| <script src="voxel.js"></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
| const getBlock = ({ data, width, height, depth }, [x, y, z]) => { | |
| if (x < 0 || x >= width || y < 0 || y >= height || z < 0 || z >= depth) { | |
| return undefined | |
| } | |
| return data[x + y * width + z * width * depth] | |
| } | |
| const getColor = value => [ | |
| [0, 0, 0], | |
| [1, 0.5, 0], | |
| [0, 1, 0], | |
| [0, 0.75, 0], | |
| [1, 1, 1], | |
| ][value] | |
| const getBlockColor = (chunk, v) => getColor(getBlock(chunk, v)) | |
| const isFilled = value => value > 0 | |
| const isBlockFilled = (chunk, v) => isFilled(getBlock(chunk, v)) | |
| const getFront = ([x, y, z]) => [x, y, z + 1] | |
| const getBack = ([x, y, z]) => [x, y, z - 1] | |
| const getLeft = ([x, y, z]) => [x - 1, y, z] | |
| const getRight = ([x, y, z]) => [x + 1, y, z] | |
| const getTop = ([x, y, z]) => [x, y + 1, z] | |
| const getBottom = ([x, y, z]) => [x, y - 1, z] | |
| const getTopFront = v => getTop(getFront(v)) | |
| const getTopBack = v => getTop(getBack(v)) | |
| const getTopLeft = v => getTop(getLeft(v)) | |
| const getTopRight = v => getTop(getRight(v)) | |
| const getBottomFront = v => getBottom(getFront(v)) | |
| const getBottomBack = v => getBottom(getBack(v)) | |
| const getBottomLeft = v => getBottom(getLeft(v)) | |
| const getBottomRight = v => getBottom(getRight(v)) | |
| const getA = v => getLeft(getTopFront(v)) | |
| const getB = v => getRight(getTopFront(v)) | |
| const getC = v => getRight(getBottomFront(v)) | |
| const getD = v => getLeft(getBottomFront(v)) | |
| const getE = v => getLeft(getTopBack(v)) | |
| const getF = v => getRight(getTopBack(v)) | |
| const getG = v => getRight(getBottomBack(v)) | |
| const getH = v => getLeft(getBottomBack(v)) | |
| const getPositionA = ([x, y, z]) => [x - 0.5, y + 0.5, z + 0.5] | |
| const getPositionB = ([x, y, z]) => [x + 0.5, y + 0.5, z + 0.5] | |
| const getPositionC = ([x, y, z]) => [x + 0.5, y - 0.5, z + 0.5] | |
| const getPositionD = ([x, y, z]) => [x - 0.5, y - 0.5, z + 0.5] | |
| const getPositionE = ([x, y, z]) => [x - 0.5, y + 0.5, z - 0.5] | |
| const getPositionF = ([x, y, z]) => [x + 0.5, y + 0.5, z - 0.5] | |
| const getPositionG = ([x, y, z]) => [x + 0.5, y - 0.5, z - 0.5] | |
| const getPositionH = ([x, y, z]) => [x - 0.5, y - 0.5, z - 0.5] | |
| const applyAO = (condition, color) => condition ? darker(color) : color | |
| const isDarkFrontA = (chunk, v) => | |
| isBlockFilled(chunk, getA(v)) | |
| || isBlockFilled(chunk, getFront(getTop(v))) | |
| || isBlockFilled(chunk, getFront(getLeft(v))) | |
| const isDarkFrontB = (chunk, v) => | |
| isBlockFilled(chunk, getB(v)) | |
| || isBlockFilled(chunk, getFront(getTop(v))) | |
| || isBlockFilled(chunk, getFront(getRight(v))) | |
| const isDarkFrontC = (chunk, v) => | |
| isBlockFilled(chunk, getC(v)) | |
| || isBlockFilled(chunk, getFront(getRight(v))) | |
| || isBlockFilled(chunk, getFront(getBottom(v))) | |
| const isDarkFrontD = (chunk, v) => | |
| isBlockFilled(chunk, getD(v)) | |
| || isBlockFilled(chunk, getFront(getLeft(v))) | |
| || isBlockFilled(chunk, getFront(getBottom(v))) | |
| const isDarkBackG = (chunk, v) => | |
| isBlockFilled(chunk, getG(v)) | |
| || isBlockFilled(chunk, getBack(getBottom(v))) | |
| || isBlockFilled(chunk, getBack(getRight(v))) | |
| const isDarkBackH = (chunk, v) => | |
| isBlockFilled(chunk, getH(v)) | |
| || isBlockFilled(chunk, getBack(getBottom(v))) | |
| || isBlockFilled(chunk, getBack(getLeft(v))) | |
| const isDarkBackE = (chunk, v) => | |
| isBlockFilled(chunk, getE(v)) | |
| || isBlockFilled(chunk, getBack(getLeft(v))) | |
| || isBlockFilled(chunk, getBack(getTop(v))) | |
| const isDarkBackF = (chunk, v) => | |
| isBlockFilled(chunk, getF(v)) | |
| || isBlockFilled(chunk, getBack(getTop(v))) | |
| || isBlockFilled(chunk, getBack(getRight(v))) | |
| const isDarkLeftH = (chunk, v) => | |
| isBlockFilled(chunk, getH(v)) | |
| || isBlockFilled(chunk, getLeft(getBottom(v))) | |
| || isBlockFilled(chunk, getLeft(getBack(v))) | |
| const isDarkLeftD = (chunk, v) => | |
| isBlockFilled(chunk, getD(v)) | |
| || isBlockFilled(chunk, getLeft(getBottom(v))) | |
| || isBlockFilled(chunk, getLeft(getFront(v))) | |
| const isDarkLeftA = (chunk, v) => | |
| isBlockFilled(chunk, getA(v)) | |
| || isBlockFilled(chunk, getLeft(getTop(v))) | |
| || isBlockFilled(chunk, getLeft(getFront(v))) | |
| const isDarkLeftE = (chunk, v) => | |
| isBlockFilled(chunk, getE(v)) | |
| || isBlockFilled(chunk, getLeft(getBack(v))) | |
| || isBlockFilled(chunk, getLeft(getTop(v))) | |
| const isDarkRightC = (chunk, v) => | |
| isBlockFilled(chunk, getC(v)) | |
| || isBlockFilled(chunk, getRight(getFront(v))) | |
| || isBlockFilled(chunk, getRight(getBottom(v))) | |
| const isDarkRightG = (chunk, v) => | |
| isBlockFilled(chunk, getG(v)) | |
| || isBlockFilled(chunk, getRight(getBack(v))) | |
| || isBlockFilled(chunk, getRight(getBottom(v))) | |
| const isDarkRightF = (chunk, v) => | |
| isBlockFilled(chunk, getF(v)) | |
| || isBlockFilled(chunk, getRight(getBack(v))) | |
| || isBlockFilled(chunk, getRight(getTop(v))) | |
| const isDarkRightB = (chunk, v) => | |
| isBlockFilled(chunk, getB(v)) | |
| || isBlockFilled(chunk, getRight(getFront(v))) | |
| || isBlockFilled(chunk, getRight(getTop(v))) | |
| const isDarkTopA = (chunk, v) => | |
| isBlockFilled(chunk, getA(v)) | |
| || isBlockFilled(chunk, getTop(getFront(v))) | |
| || isBlockFilled(chunk, getTop(getLeft(v))) | |
| const isDarkTopB = (chunk, v) => | |
| isBlockFilled(chunk, getB(v)) | |
| || isBlockFilled(chunk, getTop(getFront(v))) | |
| || isBlockFilled(chunk, getTop(getRight(v))) | |
| const isDarkTopF = (chunk, v) => | |
| isBlockFilled(chunk, getF(v)) | |
| || isBlockFilled(chunk, getTop(getBack(v))) | |
| || isBlockFilled(chunk, getTop(getRight(v))) | |
| const isDarkTopE = (chunk, v) => | |
| isBlockFilled(chunk, getE(v)) | |
| || isBlockFilled(chunk, getTop(getBack(v))) | |
| || isBlockFilled(chunk, getTop(getLeft(v))) | |
| const isDarkBottomH = (chunk, v) => | |
| isBlockFilled(chunk, getH(v)) | |
| || isBlockFilled(chunk, getBottom(getBack(v))) | |
| || isBlockFilled(chunk, getBottom(getLeft(v))) | |
| const isDarkBottomG = (chunk, v) => | |
| isBlockFilled(chunk, getG(v)) | |
| || isBlockFilled(chunk, getBottom(getBack(v))) | |
| || isBlockFilled(chunk, getBottom(getRight(v))) | |
| const isDarkBottomC = (chunk, v) => | |
| isBlockFilled(chunk, getC(v)) | |
| || isBlockFilled(chunk, getBottom(getFront(v))) | |
| || isBlockFilled(chunk, getBottom(getRight(v))) | |
| const isDarkBottomD = (chunk, v) => | |
| isBlockFilled(chunk, getD(v)) | |
| || isBlockFilled(chunk, getBottom(getFront(v))) | |
| || isBlockFilled(chunk, getBottom(getLeft(v))) | |
| const getFrontPlane = (chunk, v) => [ | |
| [getPositionD(v), applyAO(isDarkFrontD(chunk, v), dark(getBlockColor(chunk, v)))], | |
| [getPositionC(v), applyAO(isDarkFrontC(chunk, v), dark(getBlockColor(chunk, v)))], | |
| [getPositionB(v), applyAO(isDarkFrontB(chunk, v), dark(getBlockColor(chunk, v)))], | |
| [getPositionA(v), applyAO(isDarkFrontA(chunk, v), dark(getBlockColor(chunk, v)))], | |
| isDarkFrontD(chunk, v) || isDarkFrontB(chunk, v) | |
| ] | |
| const getBackPlane = (chunk, v) => [ | |
| [getPositionG(v), applyAO(isDarkBackG(chunk, v), dark(getBlockColor(chunk, v)))], | |
| [getPositionH(v), applyAO(isDarkBackH(chunk, v), dark(getBlockColor(chunk, v)))], | |
| [getPositionE(v), applyAO(isDarkBackE(chunk, v), dark(getBlockColor(chunk, v)))], | |
| [getPositionF(v), applyAO(isDarkBackF(chunk, v), dark(getBlockColor(chunk, v)))], | |
| isDarkBackG(chunk, v) || isDarkBackE(chunk, v) | |
| ] | |
| const getLeftPlane = (chunk, v) => [ | |
| [getPositionH(v), applyAO(isDarkLeftH(chunk, v), dark(dark(dark(getBlockColor(chunk, v)))))], | |
| [getPositionD(v), applyAO(isDarkLeftD(chunk, v), dark(dark(dark(getBlockColor(chunk, v)))))], | |
| [getPositionA(v), applyAO(isDarkLeftA(chunk, v), dark(dark(dark(getBlockColor(chunk, v)))))], | |
| [getPositionE(v), applyAO(isDarkLeftE(chunk, v), dark(dark(dark(getBlockColor(chunk, v)))))], | |
| isDarkLeftH(chunk, v) || isDarkLeftA(chunk, v) | |
| ] | |
| const getRightPlane = (chunk, v) => [ | |
| [getPositionC(v), applyAO(isDarkRightC(chunk, v), dark(getBlockColor(chunk, v)))], | |
| [getPositionG(v), applyAO(isDarkRightG(chunk, v), dark(getBlockColor(chunk, v)))], | |
| [getPositionF(v), applyAO(isDarkRightF(chunk, v), dark(getBlockColor(chunk, v)))], | |
| [getPositionB(v), applyAO(isDarkRightB(chunk, v), dark(getBlockColor(chunk, v)))], | |
| isDarkRightC(chunk, v) || isDarkRightF(chunk, v) | |
| ] | |
| const getTopPlane = (chunk, v) => [ | |
| [getPositionA(v), applyAO(isDarkTopA(chunk, v), getBlockColor(chunk, v))], | |
| [getPositionB(v), applyAO(isDarkTopB(chunk, v), getBlockColor(chunk, v))], | |
| [getPositionF(v), applyAO(isDarkTopF(chunk, v), getBlockColor(chunk, v))], | |
| [getPositionE(v), applyAO(isDarkTopE(chunk, v), getBlockColor(chunk, v))], | |
| isDarkTopA(chunk, v) || isDarkTopF(chunk, v) | |
| ] | |
| const getBottomPlane = (chunk, v) => [ | |
| [getPositionH(v), applyAO(isDarkBottomH(chunk, v), darkest(getBlockColor(chunk, v)))], | |
| [getPositionG(v), applyAO(isDarkBottomG(chunk, v), darkest(getBlockColor(chunk, v)))], | |
| [getPositionC(v), applyAO(isDarkBottomC(chunk, v), darkest(getBlockColor(chunk, v)))], | |
| [getPositionD(v), applyAO(isDarkBottomD(chunk, v), darkest(getBlockColor(chunk, v)))], | |
| isDarkBottomH(chunk, v) || isDarkBottomC(chunk, v) | |
| ] | |
| const triangulatePlane = ([a, b, c, d, inverse]) => inverse ? [[a, b, d], [d, b, c]] : [[a, b, c], [a, c, d]] | |
| const dark = ([r, g, b]) => [r * 0.95, g * 0.95, b * 0.95] | |
| const darker = ([r, g, b]) => [r * 0.8, g * 0.8, b * 0.8] | |
| const darkest = ([r, g, b]) => [r * 0.6, g * 0.6, b * 0.6] | |
| const isFrontPlaneVisible = (chunk, v) => !isBlockFilled(chunk, getFront(v)) | |
| const isBackPlaneVisible = (chunk, v) => !isBlockFilled(chunk, getBack(v)) | |
| const isLeftPlaneVisible = (chunk, v) => !isBlockFilled(chunk, getLeft(v)) | |
| const isRightPlaneVisible = (chunk, v) => !isBlockFilled(chunk, getRight(v)) | |
| const isTopPlaneVisible = (chunk, v) => !isBlockFilled(chunk, getTop(v)) | |
| const isBottomPlaneVisible = (chunk, v) => !isBlockFilled(chunk, getBottom(v)) | |
| const getBlockV = ({ width, depth }, offset) => [ | |
| offset % width, | |
| Math.floor(offset / width) % depth, | |
| Math.floor(offset / (width * depth)) | |
| ] | |
| /* | |
| Back Bottom | |
| | | | |
| | | | |
| v V | |
| Front Top | |
| Left --> Right | |
| */ | |
| const x = 3 | |
| const sz = 20 | |
| const chunk = { | |
| data: [ | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 1, 1, 1, 1, 1, 1, 1, 0, | |
| 1, 1, 1, 1, 1, 1, 1, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 1, 1, 1, 1, 1, 0, 0, | |
| 1, 1, 1, 1, 1, 1, 1, 0, | |
| 1, 1, 1, 1, 1, 1, 1, 0, | |
| 0, 1, 1, 1, 1, 1, 0, 0, | |
| 0, 0, 1, 1, 1, 0, 0, 0, | |
| 0, 0, 0, 1, 1, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 1, 1, 1, 1, 1, 0, 0, | |
| 1, 1, 1, 1, 1, 1, 1, 0, | |
| 1, 1, 1, 1, 1, 1, 1, 0, | |
| 0, 1, 1, 1, 1, 1, 0, 0, | |
| 0, 0, 1, 1, 1, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 1, 1, 1, 1, 1, 0, 0, | |
| 1, 1, 1, 1, 1, 1, 1, 0, | |
| 1, 1, 1, 1, 1, 1, 1, 0, | |
| 0, 1, 1, 1, 1, 1, 0, 0, | |
| 0, 0, 1, 1, 1, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 1, 1, 1, 1, 1, 0, 0, | |
| 1, 1, 1, 1, 1, 1, 1, 0, | |
| 1, 1, 1, 1, 1, 1, 1, 0, | |
| 0, 1, 1, 1, 1, 1, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 1, 1, 1, 1, 1, 0, 0, | |
| 1, 1, 1, 1, 1, 1, 1, 0, | |
| 1, 1, 1, 1, 1, 1, 1, 0, | |
| 0, 1, 1, 1, 1, 1, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 1, 1, 1, 1, 1, 1, 1, 0, | |
| 1, 1, 1, 1, 1, 1, 1, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| ], | |
| width: 8, | |
| height: 8, | |
| depth: 8 | |
| } | |
| const triangles = chunk.data | |
| .map((x, i) => getBlockV(chunk, i)) | |
| .filter(v => isBlockFilled(chunk, v)) | |
| .flatMap(v => [ | |
| ...(isFrontPlaneVisible(chunk, v) ? [getFrontPlane(chunk, v)] : []), | |
| ...(isBackPlaneVisible(chunk, v) ? [getBackPlane(chunk, v)] : []), | |
| ...(isLeftPlaneVisible(chunk, v) ? [getLeftPlane(chunk, v)] : []), | |
| ...(isRightPlaneVisible(chunk, v) ? [getRightPlane(chunk, v)] : []), | |
| ...(isTopPlaneVisible(chunk, v) ? [getTopPlane(chunk, v)] : []), | |
| ...(isBottomPlaneVisible(chunk, v) ? [getBottomPlane(chunk, v)] : []), | |
| ]) | |
| .flatMap(triangulatePlane) | |
| renderTriangles(triangles, { | |
| eye: [3.5, 10, 12], | |
| center: [3.5, 3.5, 3.5], | |
| mode: 'triangles', | |
| orbit: true, | |
| }) | |
| const tree = [ | |
| 3, 3, 3, 3, 3, 3, 3, 3, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 2, 2, 2, 2, 2, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 3, 3, 3, 3, 3, 3, 3, 3, | |
| 0, 2, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 2, 2, 2, 0, 0, | |
| 0, 0, 2, 2, 2, 2, 2, 0, | |
| 0, 0, 0, 2, 2, 2, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 3, 3, 3, 3, 3, 3, 3, 3, | |
| 0, 0, 0, 0, 1, 0, 2, 0, | |
| 0, 0, 0, 0, 1, 0, 0, 0, | |
| 0, 0, 0, 0, 1, 0, 0, 0, | |
| 0, 0, 0, 2, 2, 2, 0, 0, | |
| 0, 0, 2, 2, 2, 2, 2, 0, | |
| 0, 0, 0, 2, 2, 2, 0, 0, | |
| 0, 0, 0, 0, 2, 0, 0, 0, | |
| 3, 3, 3, 3, 3, 3, 3, 3, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 2, 2, 2, 0, 0, | |
| 0, 0, 2, 2, 2, 2, 2, 0, | |
| 0, 0, 0, 2, 2, 2, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 3, 3, 3, 3, 3, 3, 3, 3, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 2, 2, 2, 2, 2, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 3, 3, 3, 3, 3, 3, 3, 3, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 3, 3, 3, 3, 3, 3, 3, 3, | |
| 4, 4, 4, 4, 4, 4, 4, 0, | |
| 4, 0, 0, 4, 0, 0, 4, 0, | |
| 4, 0, 0, 4, 0, 0, 4, 0, | |
| 4, 0, 0, 4, 4, 4, 4, 0, | |
| 4, 0, 0, 4, 0, 0, 4, 0, | |
| 4, 0, 0, 4, 0, 0, 4, 0, | |
| 4, 4, 4, 4, 4, 4, 4, 0, | |
| 3, 3, 3, 3, 3, 3, 3, 3, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| ] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment