diff --git a/src/engine/components/planet/index.js b/src/engine/components/planet/index.js index 0111222..f149668 100644 --- a/src/engine/components/planet/index.js +++ b/src/engine/components/planet/index.js @@ -2,6 +2,8 @@ import { Mesh } from '../../mesh' import { mat4 } from 'gl-matrix' import { subv3, mulv3, addv3, normalv3, crossv3 } from '../../utility' +const lodMax = 8 + class CubeFace { constructor (parent, level, pos, normal, resolution, radius, generator) { this.parent = parent @@ -14,6 +16,7 @@ class CubeFace { this.level = level this.generated = false + this.generator = generator // Calculate left (x) and forward (z) vectors from the normal (y) this.left = [normal[1], normal[2], normal[0]] @@ -25,6 +28,10 @@ class CubeFace { this.position = subv3(this.position, mulv3(this.left, this.radius / 2)) this.position = subv3(this.position, mulv3(this.forward, this.radius / 2)) + if (this.parent) { + this.transform = this.parent.transform + } + this.generate() } @@ -84,7 +91,54 @@ class CubeFace { this.generated = true } + dispose () { + this.mesh = null + this.generated = false + } + + merge () { + if (!this.children.length) return + + for (let i in this.children) { + let ch = this.children[i] + + ch.merge() + ch.dispose() + } + + this.children = [] + } + + subdivide () { + if (this.level === lodMax) return + + let subPos = this.position + subPos = addv3(subPos, mulv3(this.left, this.radius / 2)) + subPos = addv3(subPos, mulv3(this.forward, this.radius / 2)) + + let stepLeft = mulv3(this.left, this.radius / 4) + let stepForward = mulv3(this.forward, this.radius / 4) + let hs = this.radius / 2 + let lv = this.level + 1 + + this.children = [ + new CubeFace(this, lv, addv3(subv3(subPos, stepLeft), stepForward), this.normal, this.resolution, hs, this.generator), + new CubeFace(this, lv, addv3(addv3(subPos, stepLeft), stepForward), this.normal, this.resolution, hs, this.generator), + new CubeFace(this, lv, subv3(subv3(subPos, stepLeft), stepForward), this.normal, this.resolution, hs, this.generator), + new CubeFace(this, lv, subv3(addv3(subPos, stepLeft), stepForward), this.normal, this.resolution, hs, this.generator) + ] + + this.dispose() + } + draw (gl, shader) { + if (!this.mesh) { + for (let i in this.children) { + this.children[i].draw(gl, shader) + } + return + } + // Set model transform matrix uniform const transformLocation = shader.getUniformLocation(gl, 'uModelMatrix') gl.uniformMatrix4fv(transformLocation, false, this.transform) @@ -116,9 +170,8 @@ class CubePlanet { new CubeFace(this, 0, [0, -hs, 0], [0, -1, 0], resolution, radius, generator) // bottom ] - for (let i in this.faces) { - this.faces[i].transform = this.transform - } + this.faces[0].subdivide() + this.faces[0].children[0].subdivide() } draw (gl, shader) { diff --git a/src/index.js b/src/index.js index 5663d26..d5ebd28 100644 --- a/src/index.js +++ b/src/index.js @@ -34,7 +34,7 @@ async function pipeline () { terrain.setMaterial(material) // Create and initialize the camera - let cam = new Camera([-60.0, 1.0, 0.0]) + let cam = new Camera([-200.0, 1.0, 0.0]) cam.updateProjection(game.gl) // Planet test