Camera-based subdivision
This commit is contained in:
parent
1acddf4074
commit
7502888d03
@ -1,5 +1,6 @@
|
||||
import { Mesh } from '../../mesh'
|
||||
import { mat4 } from 'gl-matrix'
|
||||
import { BoundingBox } from '../../mesh/aabb'
|
||||
import { mat4, vec3 } from 'gl-matrix'
|
||||
import { subv3, mulv3, addv3, normalv3, crossv3 } from '../../utility'
|
||||
|
||||
const lodMax = 8
|
||||
@ -28,10 +29,6 @@ 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()
|
||||
}
|
||||
|
||||
@ -88,6 +85,7 @@ class CubeFace {
|
||||
}
|
||||
|
||||
this.mesh = Mesh.construct(window.gl, vertices, indices, textureCoords)
|
||||
this.bounds = BoundingBox.fromMesh(this.mesh)
|
||||
this.generated = true
|
||||
}
|
||||
|
||||
@ -139,10 +137,6 @@ class CubeFace {
|
||||
return
|
||||
}
|
||||
|
||||
// Set model transform matrix uniform
|
||||
const transformLocation = shader.getUniformLocation(gl, 'uModelMatrix')
|
||||
gl.uniformMatrix4fv(transformLocation, false, this.transform)
|
||||
|
||||
this.mesh.prepare(gl, shader)
|
||||
this.mesh.draw(gl, shader)
|
||||
}
|
||||
@ -174,7 +168,43 @@ class CubePlanet {
|
||||
this.faces[0].children[0].subdivide()
|
||||
}
|
||||
|
||||
getActiveQuadTreeFaces (face, active) {
|
||||
if (!face.children.length) {
|
||||
active.push(face)
|
||||
} else {
|
||||
for (let f = 0; f < face.children.length; f++) {
|
||||
this.getActiveQuadTreeFaces(face.children[f], active)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update (f, camera) {
|
||||
let activeTree = []
|
||||
this.getActiveQuadTreeFaces(this.faces[f], activeTree)
|
||||
|
||||
for (let a = 0; a < activeTree.length; a++) {
|
||||
let dist = vec3.distance(camera.pos, activeTree[a].bounds.center)
|
||||
|
||||
if (dist > activeTree[a].radius) {
|
||||
if (dist <= this.radius * 2.0 || activeTree[a].parent === this) {
|
||||
activeTree[a].merge()
|
||||
activeTree[a].generate()
|
||||
} else {
|
||||
activeTree[a].merge()
|
||||
activeTree[a].parent.merge()
|
||||
activeTree[a].parent.generate()
|
||||
}
|
||||
} else if (activeTree[a].radius > this.resolution && activeTree[a].level < lodMax) {
|
||||
activeTree[a].subdivide()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
draw (gl, shader) {
|
||||
// Set model transform matrix uniform
|
||||
const transformLocation = shader.getUniformLocation(gl, 'uModelMatrix')
|
||||
gl.uniformMatrix4fv(transformLocation, false, this.transform)
|
||||
|
||||
for (let i in this.faces) {
|
||||
this.faces[i].draw(gl, shader)
|
||||
}
|
||||
|
37
src/engine/mesh/aabb.js
Normal file
37
src/engine/mesh/aabb.js
Normal file
@ -0,0 +1,37 @@
|
||||
|
||||
class BoundingBox {
|
||||
constructor (min, max) {
|
||||
this.min = min
|
||||
this.max = max
|
||||
this.calculateSphere()
|
||||
}
|
||||
|
||||
static fromMesh (mesh) {
|
||||
let min = [0, 0, 0]
|
||||
let max = [0, 0, 0]
|
||||
for (let v = 0; v < mesh.vertices.length; v += 3) {
|
||||
let vertex = [mesh.vertices[v], mesh.vertices[v + 1], mesh.vertices[v + 2]]
|
||||
// X
|
||||
if (vertex[0] > max[0]) max[0] = vertex[0]
|
||||
if (vertex[0] < min[0]) min[0] = vertex[0]
|
||||
// Y
|
||||
if (vertex[1] > max[1]) max[1] = vertex[1]
|
||||
if (vertex[1] < min[1]) min[1] = vertex[1]
|
||||
// Z
|
||||
if (vertex[2] > max[2]) max[2] = vertex[2]
|
||||
if (vertex[2] < min[2]) min[2] = vertex[2]
|
||||
}
|
||||
return new BoundingBox(min, max)
|
||||
}
|
||||
|
||||
calculateSphere () {
|
||||
this.center = [
|
||||
this.min[0] + (this.max[0] - this.min[0]) / 2,
|
||||
this.min[1] + (this.max[1] - this.min[1]) / 2,
|
||||
this.min[2] + (this.max[2] - this.min[2]) / 2
|
||||
]
|
||||
this.radius = Math.max((this.max[0] - this.min[0]) / 2, (this.max[1] - this.min[1]) / 2, (this.max[2] - this.min[2]) / 2)
|
||||
}
|
||||
}
|
||||
|
||||
export { BoundingBox }
|
@ -38,9 +38,10 @@ async function pipeline () {
|
||||
cam.updateProjection(game.gl)
|
||||
|
||||
// Planet test
|
||||
let planet = new CubePlanet([0.0, 0.0, 0.0], 16, 128)
|
||||
let planet = new CubePlanet([0.0, 0.0, 0.0], 16, 512)
|
||||
|
||||
// Update function for camera
|
||||
let face = 0
|
||||
game.addUpdateFunction(function (dt) {
|
||||
if (game.input.isDown('w')) {
|
||||
cam.processKeyboard(0, dt)
|
||||
@ -61,6 +62,8 @@ async function pipeline () {
|
||||
// TESTING: Move model forward
|
||||
// t = t + 0.1
|
||||
// entity.setPosition([t, 0.0, 0.0])
|
||||
planet.update(face++, cam)
|
||||
if (face > 5) face = 0
|
||||
})
|
||||
|
||||
// Render function for the triangle
|
||||
@ -69,7 +72,7 @@ async function pipeline () {
|
||||
cam.draw(gl, shader)
|
||||
entity.draw(gl, shader)
|
||||
planet.draw(gl, shader)
|
||||
|
||||
/*
|
||||
// Use terrain shader
|
||||
terrainShader.use(gl)
|
||||
|
||||
@ -81,6 +84,7 @@ async function pipeline () {
|
||||
|
||||
// Draw terrain
|
||||
terrain.draw(gl, terrainShader)
|
||||
*/
|
||||
})
|
||||
|
||||
game.startGameLoop()
|
||||
|
Loading…
Reference in New Issue
Block a user