Camera-based subdivision
This commit is contained in:
parent
1acddf4074
commit
7502888d03
@ -1,5 +1,6 @@
|
|||||||
import { Mesh } from '../../mesh'
|
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'
|
import { subv3, mulv3, addv3, normalv3, crossv3 } from '../../utility'
|
||||||
|
|
||||||
const lodMax = 8
|
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.left, this.radius / 2))
|
||||||
this.position = subv3(this.position, mulv3(this.forward, this.radius / 2))
|
this.position = subv3(this.position, mulv3(this.forward, this.radius / 2))
|
||||||
|
|
||||||
if (this.parent) {
|
|
||||||
this.transform = this.parent.transform
|
|
||||||
}
|
|
||||||
|
|
||||||
this.generate()
|
this.generate()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,6 +85,7 @@ class CubeFace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.mesh = Mesh.construct(window.gl, vertices, indices, textureCoords)
|
this.mesh = Mesh.construct(window.gl, vertices, indices, textureCoords)
|
||||||
|
this.bounds = BoundingBox.fromMesh(this.mesh)
|
||||||
this.generated = true
|
this.generated = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,10 +137,6 @@ class CubeFace {
|
|||||||
return
|
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.prepare(gl, shader)
|
||||||
this.mesh.draw(gl, shader)
|
this.mesh.draw(gl, shader)
|
||||||
}
|
}
|
||||||
@ -174,7 +168,43 @@ class CubePlanet {
|
|||||||
this.faces[0].children[0].subdivide()
|
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) {
|
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) {
|
for (let i in this.faces) {
|
||||||
this.faces[i].draw(gl, shader)
|
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)
|
cam.updateProjection(game.gl)
|
||||||
|
|
||||||
// Planet test
|
// 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
|
// Update function for camera
|
||||||
|
let face = 0
|
||||||
game.addUpdateFunction(function (dt) {
|
game.addUpdateFunction(function (dt) {
|
||||||
if (game.input.isDown('w')) {
|
if (game.input.isDown('w')) {
|
||||||
cam.processKeyboard(0, dt)
|
cam.processKeyboard(0, dt)
|
||||||
@ -61,6 +62,8 @@ async function pipeline () {
|
|||||||
// TESTING: Move model forward
|
// TESTING: Move model forward
|
||||||
// t = t + 0.1
|
// t = t + 0.1
|
||||||
// entity.setPosition([t, 0.0, 0.0])
|
// entity.setPosition([t, 0.0, 0.0])
|
||||||
|
planet.update(face++, cam)
|
||||||
|
if (face > 5) face = 0
|
||||||
})
|
})
|
||||||
|
|
||||||
// Render function for the triangle
|
// Render function for the triangle
|
||||||
@ -69,7 +72,7 @@ async function pipeline () {
|
|||||||
cam.draw(gl, shader)
|
cam.draw(gl, shader)
|
||||||
entity.draw(gl, shader)
|
entity.draw(gl, shader)
|
||||||
planet.draw(gl, shader)
|
planet.draw(gl, shader)
|
||||||
|
/*
|
||||||
// Use terrain shader
|
// Use terrain shader
|
||||||
terrainShader.use(gl)
|
terrainShader.use(gl)
|
||||||
|
|
||||||
@ -81,6 +84,7 @@ async function pipeline () {
|
|||||||
|
|
||||||
// Draw terrain
|
// Draw terrain
|
||||||
terrain.draw(gl, terrainShader)
|
terrain.draw(gl, terrainShader)
|
||||||
|
*/
|
||||||
})
|
})
|
||||||
|
|
||||||
game.startGameLoop()
|
game.startGameLoop()
|
||||||
|
Loading…
Reference in New Issue
Block a user