new standard
This commit is contained in:
parent
9dbfb40707
commit
9db001d18f
@ -31,9 +31,9 @@ class Camera extends Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
processKeyboard (direction, delta) {
|
processKeyboard (direction, delta) {
|
||||||
let newSpeed = this.speed * delta
|
const newSpeed = this.speed * delta
|
||||||
let velocity = vec3.fromValues(newSpeed, newSpeed, newSpeed)
|
const velocity = vec3.fromValues(newSpeed, newSpeed, newSpeed)
|
||||||
let vec = vec3.create()
|
const vec = vec3.create()
|
||||||
|
|
||||||
if (direction === 0) {
|
if (direction === 0) {
|
||||||
vec3.multiply(vec, this.front, velocity)
|
vec3.multiply(vec, this.front, velocity)
|
||||||
@ -57,7 +57,7 @@ class Camera extends Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
processMouseMove (offset, constrain = true) {
|
processMouseMove (offset, constrain = true) {
|
||||||
let fst = vec2.fromValues(offset.x * -this.sensitivity, offset.y * this.sensitivity)
|
const fst = vec2.fromValues(offset.x * -this.sensitivity, offset.y * this.sensitivity)
|
||||||
this.rotation[0] += glMatrix.toRadian(fst[0])
|
this.rotation[0] += glMatrix.toRadian(fst[0])
|
||||||
this.rotation[1] += glMatrix.toRadian(fst[1])
|
this.rotation[1] += glMatrix.toRadian(fst[1])
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ class Camera extends Node {
|
|||||||
if (!this.front || !this.worldUp) return
|
if (!this.front || !this.worldUp) return
|
||||||
|
|
||||||
// Calculate the new Front vector
|
// Calculate the new Front vector
|
||||||
let front = vec3.create()
|
const front = vec3.create()
|
||||||
|
|
||||||
front[0] = Math.cos(this.rotation[0]) * Math.cos(this.rotation[1])
|
front[0] = Math.cos(this.rotation[0]) * Math.cos(this.rotation[1])
|
||||||
front[1] = Math.sin(this.rotation[1])
|
front[1] = Math.sin(this.rotation[1])
|
||||||
@ -91,8 +91,8 @@ class Camera extends Node {
|
|||||||
|
|
||||||
// Also re-calculate the Right and Up vector
|
// Also re-calculate the Right and Up vector
|
||||||
// Normalize the vectors, because their length gets closer to 0 the more you look up or down which results in slower movement.
|
// Normalize the vectors, because their length gets closer to 0 the more you look up or down which results in slower movement.
|
||||||
let rightCross = vec3.create()
|
const rightCross = vec3.create()
|
||||||
let upCross = vec3.create()
|
const upCross = vec3.create()
|
||||||
|
|
||||||
vec3.cross(rightCross, this.front, this.worldUp)
|
vec3.cross(rightCross, this.front, this.worldUp)
|
||||||
vec3.normalize(this.right, rightCross)
|
vec3.normalize(this.right, rightCross)
|
||||||
@ -108,8 +108,8 @@ class Camera extends Node {
|
|||||||
// Calculate the view matrix on-the-go
|
// Calculate the view matrix on-the-go
|
||||||
// Really no advantage in storing this
|
// Really no advantage in storing this
|
||||||
get view () {
|
get view () {
|
||||||
let mat = mat4.create()
|
const mat = mat4.create()
|
||||||
let center = vec3.create()
|
const center = vec3.create()
|
||||||
vec3.add(center, this.pos, this.front)
|
vec3.add(center, this.pos, this.front)
|
||||||
mat4.lookAt(mat, this.pos, center, this.up)
|
mat4.lookAt(mat, this.pos, center, this.up)
|
||||||
return mat
|
return mat
|
||||||
|
@ -7,16 +7,16 @@ import { mat4, quat, vec3 } from 'gl-matrix'
|
|||||||
* @return {vec3} out
|
* @return {vec3} out
|
||||||
*/
|
*/
|
||||||
quat.getEuler = function (out, quat) {
|
quat.getEuler = function (out, quat) {
|
||||||
let x = quat[0]
|
const x = quat[0]
|
||||||
let y = quat[1]
|
const y = quat[1]
|
||||||
let z = quat[2]
|
const z = quat[2]
|
||||||
let w = quat[3]
|
const w = quat[3]
|
||||||
let x2 = x * x
|
const x2 = x * x
|
||||||
let y2 = y * y
|
const y2 = y * y
|
||||||
let z2 = z * z
|
const z2 = z * z
|
||||||
let w2 = w * w
|
const w2 = w * w
|
||||||
let unit = x2 + y2 + z2 + w2
|
const unit = x2 + y2 + z2 + w2
|
||||||
let test = x * w - y * z
|
const test = x * w - y * z
|
||||||
if (test > 0.499995 * unit) {
|
if (test > 0.499995 * unit) {
|
||||||
// singularity at the north pole
|
// singularity at the north pole
|
||||||
out[0] = Math.PI / 2
|
out[0] = Math.PI / 2
|
||||||
@ -55,8 +55,8 @@ class Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateTransform () {
|
updateTransform () {
|
||||||
let matrix = mat4.create()
|
const matrix = mat4.create()
|
||||||
let rot = quat.create()
|
const rot = quat.create()
|
||||||
|
|
||||||
// Set rotation
|
// Set rotation
|
||||||
quat.fromEuler(rot, this.rotation[0], this.rotation[1], this.rotation[2])
|
quat.fromEuler(rot, this.rotation[0], this.rotation[1], this.rotation[2])
|
||||||
@ -77,18 +77,18 @@ class Node {
|
|||||||
this.transform = matrix
|
this.transform = matrix
|
||||||
|
|
||||||
// Update children's transforms
|
// Update children's transforms
|
||||||
for (let i in this.children) {
|
for (const i in this.children) {
|
||||||
let child = this.children[i]
|
const child = this.children[i]
|
||||||
if (!(child instanceof Node)) continue
|
if (!(child instanceof Node)) continue
|
||||||
child.updateTransform()
|
child.updateTransform()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fromLocalTransform (transform) {
|
fromLocalTransform (transform) {
|
||||||
let quaternion = quat.create()
|
const quaternion = quat.create()
|
||||||
let translation = vec3.create()
|
const translation = vec3.create()
|
||||||
let rotation = vec3.create()
|
const rotation = vec3.create()
|
||||||
let scale = vec3.create()
|
const scale = vec3.create()
|
||||||
|
|
||||||
mat4.transpose(transform, transform)
|
mat4.transpose(transform, transform)
|
||||||
|
|
||||||
@ -171,8 +171,8 @@ class Node {
|
|||||||
// Draw base
|
// Draw base
|
||||||
draw (gl, shader) {
|
draw (gl, shader) {
|
||||||
// Nothing to draw here, so just draw children
|
// Nothing to draw here, so just draw children
|
||||||
for (let i in this.children) {
|
for (const i in this.children) {
|
||||||
let child = this.children[i]
|
const child = this.children[i]
|
||||||
if (!(child instanceof Node)) continue
|
if (!(child instanceof Node)) continue
|
||||||
child.draw(gl, shader)
|
child.draw(gl, shader)
|
||||||
}
|
}
|
||||||
@ -180,8 +180,8 @@ class Node {
|
|||||||
|
|
||||||
update (dt) {
|
update (dt) {
|
||||||
// Update children
|
// Update children
|
||||||
for (let i in this.children) {
|
for (const i in this.children) {
|
||||||
let child = this.children[i]
|
const child = this.children[i]
|
||||||
if (!(child instanceof Node)) continue
|
if (!(child instanceof Node)) continue
|
||||||
child.update(dt)
|
child.update(dt)
|
||||||
}
|
}
|
||||||
@ -190,7 +190,7 @@ class Node {
|
|||||||
addChild (ch) {
|
addChild (ch) {
|
||||||
// Recursive add in case of table
|
// Recursive add in case of table
|
||||||
if (ch && typeof ch === 'object' && ch.length) {
|
if (ch && typeof ch === 'object' && ch.length) {
|
||||||
for (let i in ch) {
|
for (const i in ch) {
|
||||||
this.addChild(ch[i])
|
this.addChild(ch[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,17 +31,17 @@ class Particle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_createOffset (index) {
|
_createOffset (index) {
|
||||||
let col = Math.floor(index % this.texture.rows)
|
const col = Math.floor(index % this.texture.rows)
|
||||||
let row = Math.floor(index / this.texture.rows)
|
const row = Math.floor(index / this.texture.rows)
|
||||||
return [ col / this.texture.rows, row / this.texture.rows ]
|
return [col / this.texture.rows, row / this.texture.rows]
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateTexture () {
|
_updateTexture () {
|
||||||
let lifeFactor = this.elapsed / this.life
|
const lifeFactor = this.elapsed / this.life
|
||||||
let stages = this.texture.rows * this.texture.rows
|
const stages = this.texture.rows * this.texture.rows
|
||||||
let progression = lifeFactor * stages
|
const progression = lifeFactor * stages
|
||||||
let index1 = Math.floor(progression)
|
const index1 = Math.floor(progression)
|
||||||
let index2 = (index1 < stages - 1) ? index1 + 1 : index1
|
const index2 = (index1 < stages - 1) ? index1 + 1 : index1
|
||||||
this.texBlend = progression % 1
|
this.texBlend = progression % 1
|
||||||
this.texOffset1 = this._createOffset(index1)
|
this.texOffset1 = this._createOffset(index1)
|
||||||
this.texOffset2 = this._createOffset(index2)
|
this.texOffset2 = this._createOffset(index2)
|
||||||
@ -49,7 +49,7 @@ class Particle {
|
|||||||
|
|
||||||
update (dt, gravity) {
|
update (dt, gravity) {
|
||||||
this.vel[1] += gravity * this.gravity * dt
|
this.vel[1] += gravity * this.gravity * dt
|
||||||
let change = [this.vel[0] * dt, this.vel[1] * dt, this.vel[2] * dt]
|
const change = [this.vel[0] * dt, this.vel[1] * dt, this.vel[2] * dt]
|
||||||
this.pos = [this.pos[0] + change[0], this.pos[1] + change[1], this.pos[2] + change[2]]
|
this.pos = [this.pos[0] + change[0], this.pos[1] + change[1], this.pos[2] + change[2]]
|
||||||
this._updateTexture()
|
this._updateTexture()
|
||||||
this.elapsed += dt
|
this.elapsed += dt
|
||||||
@ -68,10 +68,10 @@ class ParticleSystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
update (dt, gravity) {
|
update (dt, gravity) {
|
||||||
let alive = []
|
const alive = []
|
||||||
for (let i in this.particles) {
|
for (const i in this.particles) {
|
||||||
let particle = this.particles[i]
|
const particle = this.particles[i]
|
||||||
let stillAlive = particle.update(dt, gravity)
|
const stillAlive = particle.update(dt, gravity)
|
||||||
if (!stillAlive) continue
|
if (!stillAlive) continue
|
||||||
alive.push(particle)
|
alive.push(particle)
|
||||||
}
|
}
|
||||||
@ -95,7 +95,7 @@ class ParticleRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createModelMatrix (shader, viewMatrix, particle) {
|
createModelMatrix (shader, viewMatrix, particle) {
|
||||||
let modelMatrix = mat4.create()
|
const modelMatrix = mat4.create()
|
||||||
mat4.translate(modelMatrix, modelMatrix, particle.pos)
|
mat4.translate(modelMatrix, modelMatrix, particle.pos)
|
||||||
modelMatrix[0] = viewMatrix[0]
|
modelMatrix[0] = viewMatrix[0]
|
||||||
modelMatrix[1] = viewMatrix[4]
|
modelMatrix[1] = viewMatrix[4]
|
||||||
@ -112,9 +112,9 @@ class ParticleRenderer {
|
|||||||
|
|
||||||
draw (gl, particles, cam) {
|
draw (gl, particles, cam) {
|
||||||
particles = (particles instanceof ParticleSystem) ? particles.particles : particles
|
particles = (particles instanceof ParticleSystem) ? particles.particles : particles
|
||||||
let textures = []
|
const textures = []
|
||||||
for (let i in particles) {
|
for (const i in particles) {
|
||||||
let particle = particles[i]
|
const particle = particles[i]
|
||||||
if (textures.indexOf(particle.texture) !== -1) continue
|
if (textures.indexOf(particle.texture) !== -1) continue
|
||||||
textures.push(particle.texture)
|
textures.push(particle.texture)
|
||||||
}
|
}
|
||||||
@ -132,15 +132,15 @@ class ParticleRenderer {
|
|||||||
gl.depthMask(false)
|
gl.depthMask(false)
|
||||||
|
|
||||||
this.mesh.prepare(gl, this.shader)
|
this.mesh.prepare(gl, this.shader)
|
||||||
for (let i in textures) {
|
for (const i in textures) {
|
||||||
let texture = textures[i]
|
const texture = textures[i]
|
||||||
gl.activeTexture(gl.TEXTURE0)
|
gl.activeTexture(gl.TEXTURE0)
|
||||||
gl.bindTexture(gl.TEXTURE_2D, texture.id)
|
gl.bindTexture(gl.TEXTURE_2D, texture.id)
|
||||||
for (let j in particles) {
|
for (const j in particles) {
|
||||||
let particle = particles[j]
|
const particle = particles[j]
|
||||||
if (particle.texture !== texture) continue
|
if (particle.texture !== texture) continue
|
||||||
|
|
||||||
let mat = this.createModelMatrix(this.shader, cam.view, particle)
|
const mat = this.createModelMatrix(this.shader, cam.view, particle)
|
||||||
gl.uniformMatrix4fv(modelLoc, false, mat)
|
gl.uniformMatrix4fv(modelLoc, false, mat)
|
||||||
gl.uniform2fv(off1Loc, particle.texOffset1)
|
gl.uniform2fv(off1Loc, particle.texOffset1)
|
||||||
gl.uniform2fv(off2Loc, particle.texOffset2)
|
gl.uniform2fv(off2Loc, particle.texOffset2)
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { Mesh } from '../../mesh'
|
import { Mesh } from '../../mesh'
|
||||||
import { BoundingBox } from '../../mesh/aabb'
|
|
||||||
import { mat4, vec3 } from 'gl-matrix'
|
import { mat4, vec3 } from 'gl-matrix'
|
||||||
import { subv3, mulv3, addv3, divv3, normalv3, crossv3 } from '../../utility'
|
import { subv3, mulv3, addv3, divv3, normalv3, crossv3 } from '../../utility'
|
||||||
import Screen from '../../screen'
|
import Screen from '../../screen'
|
||||||
@ -44,31 +43,31 @@ class CubeFace {
|
|||||||
generate () {
|
generate () {
|
||||||
if (this.generated) return
|
if (this.generated) return
|
||||||
|
|
||||||
let VERTICES = this.generator.resolution
|
const VERTICES = this.generator.resolution
|
||||||
let vertices = []
|
const vertices = []
|
||||||
let normals = []
|
const normals = []
|
||||||
let textureCoords = []
|
const textureCoords = []
|
||||||
let indices = []
|
const indices = []
|
||||||
|
|
||||||
let radius = this.generator.radius
|
const radius = this.generator.radius
|
||||||
let divisionLevel = Math.pow(2, this.level)
|
const divisionLevel = Math.pow(2, this.level)
|
||||||
|
|
||||||
for (let i = 0, vertexPointer = 0; i < VERTICES; i++) {
|
for (let i = 0, vertexPointer = 0; i < VERTICES; i++) {
|
||||||
for (let j = 0; j < VERTICES; j++, vertexPointer++) {
|
for (let j = 0; j < VERTICES; j++, vertexPointer++) {
|
||||||
// Vertex index (0 - 1)
|
// Vertex index (0 - 1)
|
||||||
let iindex = i / (VERTICES - 1)
|
const iindex = i / (VERTICES - 1)
|
||||||
let jindex = j / (VERTICES - 1)
|
const jindex = j / (VERTICES - 1)
|
||||||
|
|
||||||
// From the left and forward vectors, we can calculate an oriented vertex
|
// From the left and forward vectors, we can calculate an oriented vertex
|
||||||
let iv = divv3(mulv3(mulv3(this.left, iindex), radius), divisionLevel)
|
const iv = divv3(mulv3(mulv3(this.left, iindex), radius), divisionLevel)
|
||||||
let jv = divv3(mulv3(mulv3(this.forward, jindex), radius), divisionLevel)
|
const jv = divv3(mulv3(mulv3(this.forward, jindex), radius), divisionLevel)
|
||||||
|
|
||||||
// Add the scaled left and forward to the centered origin
|
// Add the scaled left and forward to the centered origin
|
||||||
let vertex = addv3(this.position, addv3(iv, jv))
|
const vertex = addv3(this.position, addv3(iv, jv))
|
||||||
|
|
||||||
// Normalize and multiply by radius to create a spherical mesh
|
// Normalize and multiply by radius to create a spherical mesh
|
||||||
let normal = normalv3(vertex)
|
const normal = normalv3(vertex)
|
||||||
let pos = mulv3(normal, (this.generator.noise.getNoise3D(this.level + 1, normal[0], normal[1], normal[2]) + radius))
|
const pos = mulv3(normal, (this.generator.noise.getNoise3D(this.level + 1, normal[0], normal[1], normal[2]) * 2 + radius))
|
||||||
|
|
||||||
vertices[vertexPointer * 3] = pos[0]
|
vertices[vertexPointer * 3] = pos[0]
|
||||||
vertices[vertexPointer * 3 + 1] = pos[1]
|
vertices[vertexPointer * 3 + 1] = pos[1]
|
||||||
@ -87,10 +86,10 @@ class CubeFace {
|
|||||||
|
|
||||||
for (let gz = 0, pointer = 0; gz < VERTICES - 1; gz++) {
|
for (let gz = 0, pointer = 0; gz < VERTICES - 1; gz++) {
|
||||||
for (let gx = 0; gx < VERTICES - 1; gx++) {
|
for (let gx = 0; gx < VERTICES - 1; gx++) {
|
||||||
let topLeft = (gz * VERTICES) + gx
|
const topLeft = (gz * VERTICES) + gx
|
||||||
let topRight = topLeft + 1
|
const topRight = topLeft + 1
|
||||||
let bottomLeft = ((gz + 1) * VERTICES) + gx
|
const bottomLeft = ((gz + 1) * VERTICES) + gx
|
||||||
let bottomRight = bottomLeft + 1
|
const bottomRight = bottomLeft + 1
|
||||||
indices[pointer++] = topLeft
|
indices[pointer++] = topLeft
|
||||||
indices[pointer++] = bottomLeft
|
indices[pointer++] = bottomLeft
|
||||||
indices[pointer++] = topRight
|
indices[pointer++] = topRight
|
||||||
@ -100,40 +99,7 @@ class CubeFace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate normals
|
Mesh.generateNormals(normals, indices, vertices)
|
||||||
for (let i = 0; i < indices.length; i += 3) {
|
|
||||||
// Extract face from vertices
|
|
||||||
// First vertex position
|
|
||||||
let vertexA = [
|
|
||||||
vertices[indices[i] * 3],
|
|
||||||
vertices[indices[i] * 3 + 1],
|
|
||||||
vertices[indices[i] * 3 + 2]
|
|
||||||
]
|
|
||||||
|
|
||||||
// Second vertex position
|
|
||||||
let vertexB = [
|
|
||||||
vertices[indices[i + 1] * 3],
|
|
||||||
vertices[indices[i + 1] * 3 + 1],
|
|
||||||
vertices[indices[i + 1] * 3 + 2]
|
|
||||||
]
|
|
||||||
|
|
||||||
// Third vertex position
|
|
||||||
let vertexC = [
|
|
||||||
vertices[indices[i + 2] * 3],
|
|
||||||
vertices[indices[i + 2] * 3 + 1],
|
|
||||||
vertices[indices[i + 2] * 3 + 2]
|
|
||||||
]
|
|
||||||
|
|
||||||
// Normalize
|
|
||||||
let dir = crossv3(subv3(vertexB, vertexA), subv3(vertexC, vertexA))
|
|
||||||
let normal = normalv3(dir)
|
|
||||||
|
|
||||||
for (let k = 0; k < 3; k++) {
|
|
||||||
normals[indices[i + k] * 3] = normal[0]
|
|
||||||
normals[indices[i + k] * 3 + 1] = normal[1]
|
|
||||||
normals[indices[i + k] * 3 + 2] = normal[2]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.mesh = Mesh.construct(Screen.gl, vertices, indices, textureCoords, normals)
|
this.mesh = Mesh.construct(Screen.gl, vertices, indices, textureCoords, normals)
|
||||||
this.generated = true
|
this.generated = true
|
||||||
@ -150,8 +116,8 @@ class CubeFace {
|
|||||||
merge () {
|
merge () {
|
||||||
if (!this.children.length) return
|
if (!this.children.length) return
|
||||||
|
|
||||||
for (let i in this.children) {
|
for (const i in this.children) {
|
||||||
let ch = this.children[i]
|
const ch = this.children[i]
|
||||||
|
|
||||||
ch.merge()
|
ch.merge()
|
||||||
ch.dispose()
|
ch.dispose()
|
||||||
@ -164,14 +130,18 @@ class CubeFace {
|
|||||||
subdivide () {
|
subdivide () {
|
||||||
if (this.level === lodMax) return
|
if (this.level === lodMax) return
|
||||||
|
|
||||||
let lv = this.level + 1
|
const lv = this.level + 1
|
||||||
let stepLeft = mulv3(this.left, this.generator.radius / Math.pow(2, lv))
|
const stepLeft = mulv3(this.left, this.generator.radius / Math.pow(2, lv))
|
||||||
let stepForward = mulv3(this.forward, this.generator.radius / Math.pow(2, lv))
|
const stepForward = mulv3(this.forward, this.generator.radius / Math.pow(2, lv))
|
||||||
|
|
||||||
this.children = [
|
this.children = [
|
||||||
|
// Bottom right corner
|
||||||
new CubeFace(this, lv, this.position, this.normal, this.generator),
|
new CubeFace(this, lv, this.position, this.normal, this.generator),
|
||||||
|
// Top right corner
|
||||||
new CubeFace(this, lv, addv3(this.position, stepForward), this.normal, this.generator),
|
new CubeFace(this, lv, addv3(this.position, stepForward), this.normal, this.generator),
|
||||||
|
// Bottom left corner
|
||||||
new CubeFace(this, lv, addv3(this.position, stepLeft), this.normal, this.generator),
|
new CubeFace(this, lv, addv3(this.position, stepLeft), this.normal, this.generator),
|
||||||
|
// Top left corner
|
||||||
new CubeFace(this, lv, addv3(this.position, addv3(stepLeft, stepForward)), this.normal, this.generator)
|
new CubeFace(this, lv, addv3(this.position, addv3(stepLeft, stepForward)), this.normal, this.generator)
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -180,7 +150,7 @@ class CubeFace {
|
|||||||
|
|
||||||
draw (gl, shader) {
|
draw (gl, shader) {
|
||||||
if (!this.mesh) {
|
if (!this.mesh) {
|
||||||
for (let i in this.children) {
|
for (const i in this.children) {
|
||||||
this.children[i].draw(gl, shader)
|
this.children[i].draw(gl, shader)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -192,9 +162,9 @@ class CubeFace {
|
|||||||
|
|
||||||
update (camera, dt) {
|
update (camera, dt) {
|
||||||
if (!this.center) return
|
if (!this.center) return
|
||||||
let camToOrigin = vec3.distance(camera.pos, this.center)
|
const camToOrigin = vec3.distance(camera.pos, this.center)
|
||||||
let divisionLevel = Math.pow(2, this.level)
|
const divisionLevel = Math.pow(2, this.level)
|
||||||
let splitDistance = this.generator.radius / divisionLevel
|
const splitDistance = this.generator.radius / divisionLevel
|
||||||
|
|
||||||
if (camToOrigin < splitDistance * 2 && this.children.length === 0) {
|
if (camToOrigin < splitDistance * 2 && this.children.length === 0) {
|
||||||
this.subdivide()
|
this.subdivide()
|
||||||
@ -205,7 +175,7 @@ class CubeFace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.children.length > 0) {
|
if (this.children.length > 0) {
|
||||||
for (let i in this.children) {
|
for (const i in this.children) {
|
||||||
this.children[i].update(camera, dt)
|
this.children[i].update(camera, dt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -220,7 +190,7 @@ class CubePlanet {
|
|||||||
this.transform = mat4.create()
|
this.transform = mat4.create()
|
||||||
mat4.fromTranslation(this.transform, origin)
|
mat4.fromTranslation(this.transform, origin)
|
||||||
|
|
||||||
let hs = generator.radius / 2
|
const hs = generator.radius / 2
|
||||||
|
|
||||||
this.faces = [
|
this.faces = [
|
||||||
new CubeFace(this, 0, [0, 0, -hs], [0, 0, -1], generator), // front
|
new CubeFace(this, 0, [0, 0, -hs], [0, 0, -1], generator), // front
|
||||||
@ -235,7 +205,7 @@ class CubePlanet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
update (camera, dt) {
|
update (camera, dt) {
|
||||||
for (let i in this.faces) {
|
for (const i in this.faces) {
|
||||||
this.faces[i].update(camera, dt)
|
this.faces[i].update(camera, dt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -245,7 +215,7 @@ class CubePlanet {
|
|||||||
const transformLocation = shader.getUniformLocation(gl, 'uModelMatrix')
|
const transformLocation = shader.getUniformLocation(gl, 'uModelMatrix')
|
||||||
gl.uniformMatrix4fv(transformLocation, false, this.transform)
|
gl.uniformMatrix4fv(transformLocation, false, this.transform)
|
||||||
|
|
||||||
for (let i in this.faces) {
|
for (const i in this.faces) {
|
||||||
this.faces[i].draw(gl, shader)
|
this.faces[i].draw(gl, shader)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,14 +20,14 @@ class Skybox {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async createTexture (gl) {
|
async createTexture (gl) {
|
||||||
let ready = []
|
const ready = []
|
||||||
for (let i in FNAMES) {
|
for (const i in FNAMES) {
|
||||||
let real = this.name + '/' + FNAMES[i] + '.png'
|
const real = this.name + '/' + FNAMES[i] + '.png'
|
||||||
let loaded = await Resource.loadImage(real)
|
const loaded = await Resource.loadImage(real)
|
||||||
ready[i] = loaded
|
ready[i] = loaded
|
||||||
}
|
}
|
||||||
|
|
||||||
let imgCube = Texture.createTextureCubeMap(gl, ready)
|
const imgCube = Texture.createTextureCubeMap(gl, ready)
|
||||||
this.cubemap = imgCube
|
this.cubemap = imgCube
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ class Skybox {
|
|||||||
const viewloc = shader.getUniformLocation(gl, 'uViewMatrix')
|
const viewloc = shader.getUniformLocation(gl, 'uViewMatrix')
|
||||||
|
|
||||||
// Set translation to zero to prevent the skybox from moving in relation to the camera
|
// Set translation to zero to prevent the skybox from moving in relation to the camera
|
||||||
let view = mat4.clone(camera.view)
|
const view = mat4.clone(camera.view)
|
||||||
view[12] = 0
|
view[12] = 0
|
||||||
view[13] = 0
|
view[13] = 0
|
||||||
view[14] = 0
|
view[14] = 0
|
||||||
|
@ -12,12 +12,12 @@ class Terrain extends Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createMesh (gl, heightMap) {
|
createMesh (gl, heightMap) {
|
||||||
let VERTICES = heightMap.size
|
const VERTICES = heightMap.size
|
||||||
let count = VERTICES * VERTICES
|
const count = VERTICES * VERTICES
|
||||||
let vertices = new Array(count * 3)
|
const vertices = new Array(count * 3)
|
||||||
let normals = new Array(count * 3)
|
const normals = new Array(count * 3)
|
||||||
let textureCoords = new Array(count * 2)
|
const textureCoords = new Array(count * 2)
|
||||||
let indices = new Array(6 * (VERTICES - 1) * (VERTICES - 1))
|
const indices = new Array(6 * (VERTICES - 1) * (VERTICES - 1))
|
||||||
let vertexPointer = 0
|
let vertexPointer = 0
|
||||||
|
|
||||||
for (let i = 0; i < VERTICES; i++) {
|
for (let i = 0; i < VERTICES; i++) {
|
||||||
@ -25,7 +25,7 @@ class Terrain extends Node {
|
|||||||
vertices[vertexPointer * 3] = j / (VERTICES - 1) * this.width
|
vertices[vertexPointer * 3] = j / (VERTICES - 1) * this.width
|
||||||
vertices[vertexPointer * 3 + 1] = heightMap.getHeight(j, i)
|
vertices[vertexPointer * 3 + 1] = heightMap.getHeight(j, i)
|
||||||
vertices[vertexPointer * 3 + 2] = i / (VERTICES - 1) * this.height
|
vertices[vertexPointer * 3 + 2] = i / (VERTICES - 1) * this.height
|
||||||
let normal = heightMap.getNormal(j, i)
|
const normal = heightMap.getNormal(j, i)
|
||||||
normals[vertexPointer * 3] = normal[0]
|
normals[vertexPointer * 3] = normal[0]
|
||||||
normals[vertexPointer * 3 + 1] = normal[1]
|
normals[vertexPointer * 3 + 1] = normal[1]
|
||||||
normals[vertexPointer * 3 + 2] = normal[2]
|
normals[vertexPointer * 3 + 2] = normal[2]
|
||||||
@ -38,10 +38,10 @@ class Terrain extends Node {
|
|||||||
let pointer = 0
|
let pointer = 0
|
||||||
for (let gz = 0; gz < VERTICES - 1; gz++) {
|
for (let gz = 0; gz < VERTICES - 1; gz++) {
|
||||||
for (let gx = 0; gx < VERTICES - 1; gx++) {
|
for (let gx = 0; gx < VERTICES - 1; gx++) {
|
||||||
let topLeft = (gz * VERTICES) + gx
|
const topLeft = (gz * VERTICES) + gx
|
||||||
let topRight = topLeft + 1
|
const topRight = topLeft + 1
|
||||||
let bottomLeft = ((gz + 1) * VERTICES) + gx
|
const bottomLeft = ((gz + 1) * VERTICES) + gx
|
||||||
let bottomRight = bottomLeft + 1
|
const bottomRight = bottomLeft + 1
|
||||||
indices[pointer++] = topLeft
|
indices[pointer++] = topLeft
|
||||||
indices[pointer++] = bottomLeft
|
indices[pointer++] = bottomLeft
|
||||||
indices[pointer++] = topRight
|
indices[pointer++] = topRight
|
||||||
|
@ -8,10 +8,10 @@ class HeightMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static async fromFile (file, amplitude) {
|
static async fromFile (file, amplitude) {
|
||||||
let img = await Resource.loadImage(file)
|
const img = await Resource.loadImage(file)
|
||||||
if (img.width / img.height !== 1) throw new Error('Height Map needs to be of 1:1 aspect ratio.')
|
if (img.width / img.height !== 1) throw new Error('Height Map needs to be of 1:1 aspect ratio.')
|
||||||
|
|
||||||
let hmap = new HeightMap(img.width)
|
const hmap = new HeightMap(img.width)
|
||||||
let sampler = Resource.imageToSampler(img)
|
let sampler = Resource.imageToSampler(img)
|
||||||
|
|
||||||
for (let x = 0; x < img.width; x++) {
|
for (let x = 0; x < img.width; x++) {
|
||||||
@ -32,11 +32,11 @@ class HeightMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getNormal (x, y) {
|
getNormal (x, y) {
|
||||||
let hL = this.getHeight(x - 1, y)
|
const hL = this.getHeight(x - 1, y)
|
||||||
let hR = this.getHeight(x + 1, y)
|
const hR = this.getHeight(x + 1, y)
|
||||||
let hD = this.getHeight(x, y - 1)
|
const hD = this.getHeight(x, y - 1)
|
||||||
let hU = this.getHeight(x, y + 1)
|
const hU = this.getHeight(x, y + 1)
|
||||||
let normal = vec3.fromValues(hL - hR, 2.0, hD - hU)
|
const normal = vec3.fromValues(hL - hR, 2.0, hD - hU)
|
||||||
vec3.normalize(normal, normal)
|
vec3.normalize(normal, normal)
|
||||||
return normal
|
return normal
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,9 @@ class TerrainNode extends Node {
|
|||||||
// If this mesh has children (we're a branch), generate their meshes instead
|
// If this mesh has children (we're a branch), generate their meshes instead
|
||||||
if (this.children.length) {
|
if (this.children.length) {
|
||||||
let generated = 0
|
let generated = 0
|
||||||
for (let i in this.children) {
|
for (const i in this.children) {
|
||||||
if (generated >= this.root.genPerTick) break
|
if (generated >= this.root.genPerTick) break
|
||||||
let child = this.children[i]
|
const child = this.children[i]
|
||||||
if (!(child instanceof TerrainNode)) continue
|
if (!(child instanceof TerrainNode)) continue
|
||||||
generated += this.children[i].updateLODMesh(gl)
|
generated += this.children[i].updateLODMesh(gl)
|
||||||
}
|
}
|
||||||
@ -32,31 +32,31 @@ class TerrainNode extends Node {
|
|||||||
// If we already have a mesh, we can skip
|
// If we already have a mesh, we can skip
|
||||||
if (this.mesh) return 0
|
if (this.mesh) return 0
|
||||||
|
|
||||||
let VERTICES = this.root.resolution
|
const VERTICES = this.root.resolution
|
||||||
let count = VERTICES * VERTICES
|
const count = VERTICES * VERTICES
|
||||||
let vertices = new Array(count * 3)
|
const vertices = new Array(count * 3)
|
||||||
let normals = new Array(count * 3)
|
const normals = new Array(count * 3)
|
||||||
let textureCoords = new Array(count * 2)
|
const textureCoords = new Array(count * 2)
|
||||||
let indices = new Array(6 * (VERTICES - 1) * (VERTICES - 1))
|
const indices = new Array(6 * (VERTICES - 1) * (VERTICES - 1))
|
||||||
let vertexPointer = 0
|
let vertexPointer = 0
|
||||||
let divisionLevel = Math.pow(2, this.level)
|
const divisionLevel = Math.pow(2, this.level)
|
||||||
|
|
||||||
// Create vertices dynamically
|
// Create vertices dynamically
|
||||||
for (let i = 0; i < VERTICES; i++) {
|
for (let i = 0; i < VERTICES; i++) {
|
||||||
for (let j = 0; j < VERTICES; j++) {
|
for (let j = 0; j < VERTICES; j++) {
|
||||||
let vertDivj = j / (VERTICES - 1)
|
const vertDivj = j / (VERTICES - 1)
|
||||||
let vertDivi = i / (VERTICES - 1)
|
const vertDivi = i / (VERTICES - 1)
|
||||||
|
|
||||||
// Calculate relative resolution
|
// Calculate relative resolution
|
||||||
let pj = vertDivj * this.root.width / divisionLevel
|
const pj = vertDivj * this.root.width / divisionLevel
|
||||||
let pi = vertDivi * this.root.height / divisionLevel
|
const pi = vertDivi * this.root.height / divisionLevel
|
||||||
|
|
||||||
// Generator takes meshes' absolute vertex position in the world when using height values
|
// Generator takes meshes' absolute vertex position in the world when using height values
|
||||||
|
|
||||||
vertices[vertexPointer * 3] = pj
|
vertices[vertexPointer * 3] = pj
|
||||||
vertices[vertexPointer * 3 + 1] = this.root.generator.getHeightPlaneMesh(this, pj, pi, true)
|
vertices[vertexPointer * 3 + 1] = this.root.generator.getHeightPlaneMesh(this, pj, pi, true)
|
||||||
vertices[vertexPointer * 3 + 2] = pi
|
vertices[vertexPointer * 3 + 2] = pi
|
||||||
let normal = this.root.generator.getNormalPlaneMesh(this, pj, pi, true)
|
const normal = this.root.generator.getNormalPlaneMesh(this, pj, pi, true)
|
||||||
normals[vertexPointer * 3] = normal[0]
|
normals[vertexPointer * 3] = normal[0]
|
||||||
normals[vertexPointer * 3 + 1] = normal[1]
|
normals[vertexPointer * 3 + 1] = normal[1]
|
||||||
normals[vertexPointer * 3 + 2] = normal[2]
|
normals[vertexPointer * 3 + 2] = normal[2]
|
||||||
@ -70,10 +70,10 @@ class TerrainNode extends Node {
|
|||||||
let pointer = 0
|
let pointer = 0
|
||||||
for (let gz = 0; gz < VERTICES - 1; gz++) {
|
for (let gz = 0; gz < VERTICES - 1; gz++) {
|
||||||
for (let gx = 0; gx < VERTICES - 1; gx++) {
|
for (let gx = 0; gx < VERTICES - 1; gx++) {
|
||||||
let topLeft = (gz * VERTICES) + gx
|
const topLeft = (gz * VERTICES) + gx
|
||||||
let topRight = topLeft + 1
|
const topRight = topLeft + 1
|
||||||
let bottomLeft = ((gz + 1) * VERTICES) + gx
|
const bottomLeft = ((gz + 1) * VERTICES) + gx
|
||||||
let bottomRight = bottomLeft + 1
|
const bottomRight = bottomLeft + 1
|
||||||
indices[pointer++] = topLeft
|
indices[pointer++] = topLeft
|
||||||
indices[pointer++] = bottomLeft
|
indices[pointer++] = bottomLeft
|
||||||
indices[pointer++] = topRight
|
indices[pointer++] = topRight
|
||||||
@ -123,7 +123,7 @@ class TerrainNode extends Node {
|
|||||||
if (this.children.length === 0) return
|
if (this.children.length === 0) return
|
||||||
|
|
||||||
// Merge children and dispose their meshes
|
// Merge children and dispose their meshes
|
||||||
for (let i in this.children) {
|
for (const i in this.children) {
|
||||||
this.children[i].merge(gl)
|
this.children[i].merge(gl)
|
||||||
this.children[i].dispose(gl)
|
this.children[i].dispose(gl)
|
||||||
}
|
}
|
||||||
@ -135,10 +135,10 @@ class TerrainNode extends Node {
|
|||||||
subdivide () {
|
subdivide () {
|
||||||
// Do not divide when we're already at the limit
|
// Do not divide when we're already at the limit
|
||||||
if (this.level === this.root.maxDetail) return
|
if (this.level === this.root.maxDetail) return
|
||||||
let lv = this.level + 1
|
const lv = this.level + 1
|
||||||
|
|
||||||
let stepLeft = this.root.width / Math.pow(2, lv)
|
const stepLeft = this.root.width / Math.pow(2, lv)
|
||||||
let stepForward = this.root.height / Math.pow(2, lv)
|
const stepForward = this.root.height / Math.pow(2, lv)
|
||||||
|
|
||||||
// Child nodes take relative positions because they are parented
|
// Child nodes take relative positions because they are parented
|
||||||
this.addChild(new TerrainNode(this.root, [0, 0, 0], lv))
|
this.addChild(new TerrainNode(this.root, [0, 0, 0], lv))
|
||||||
@ -152,10 +152,10 @@ class TerrainNode extends Node {
|
|||||||
if (!this.bounds) return false
|
if (!this.bounds) return false
|
||||||
// Get camera distance from the center of this mesh
|
// Get camera distance from the center of this mesh
|
||||||
// TODO: use edges
|
// TODO: use edges
|
||||||
let distCamera = vec3.distance(camera.pos, addv3(this.bounds.center, this.absolutePosition))
|
const distCamera = vec3.distance(camera.pos, addv3(this.bounds.center, this.absolutePosition))
|
||||||
|
|
||||||
// Get LOD change distance based on current division level and a fixed distance
|
// Get LOD change distance based on current division level and a fixed distance
|
||||||
let lodDistance = this.root.lodDistance - (Math.pow(2, this.level) * LOD_SEPARATOR)
|
const lodDistance = this.root.lodDistance - (Math.pow(2, this.level) * LOD_SEPARATOR)
|
||||||
|
|
||||||
// If this node has children, either merge if too far away or update the children
|
// If this node has children, either merge if too far away or update the children
|
||||||
if (this.children.length) {
|
if (this.children.length) {
|
||||||
@ -167,8 +167,8 @@ class TerrainNode extends Node {
|
|||||||
|
|
||||||
// Update the children
|
// Update the children
|
||||||
let acted = false
|
let acted = false
|
||||||
for (let i in this.children) {
|
for (const i in this.children) {
|
||||||
let child = this.children[i]
|
const child = this.children[i]
|
||||||
acted = child.update(gl, camera)
|
acted = child.update(gl, camera)
|
||||||
}
|
}
|
||||||
return acted
|
return acted
|
||||||
@ -217,9 +217,9 @@ class LODTerrain extends Node {
|
|||||||
updateLODMesh (gl) {
|
updateLODMesh (gl) {
|
||||||
// Ensure only genPerTick mesh(es) is/are generated every tick
|
// Ensure only genPerTick mesh(es) is/are generated every tick
|
||||||
let generated = 0
|
let generated = 0
|
||||||
for (let i in this.children) {
|
for (const i in this.children) {
|
||||||
if (generated >= this.genPerTick) break
|
if (generated >= this.genPerTick) break
|
||||||
let child = this.children[i]
|
const child = this.children[i]
|
||||||
if (!(child instanceof TerrainNode)) continue
|
if (!(child instanceof TerrainNode)) continue
|
||||||
generated += this.children[i].updateLODMesh(gl)
|
generated += this.children[i].updateLODMesh(gl)
|
||||||
}
|
}
|
||||||
@ -230,9 +230,9 @@ class LODTerrain extends Node {
|
|||||||
update (gl, camera) {
|
update (gl, camera) {
|
||||||
// Ensure only one mesh update per tick
|
// Ensure only one mesh update per tick
|
||||||
let acted = false
|
let acted = false
|
||||||
for (let i in this.children) {
|
for (const i in this.children) {
|
||||||
if (acted) break
|
if (acted) break
|
||||||
let child = this.children[i]
|
const child = this.children[i]
|
||||||
acted = child.update(gl, camera)
|
acted = child.update(gl, camera)
|
||||||
}
|
}
|
||||||
return acted
|
return acted
|
||||||
|
@ -32,7 +32,7 @@ class WaterFBOs {
|
|||||||
|
|
||||||
createFrameBuffer (gl) {
|
createFrameBuffer (gl) {
|
||||||
// generate frame buffer
|
// generate frame buffer
|
||||||
let frameBuffer = gl.createFramebuffer()
|
const frameBuffer = gl.createFramebuffer()
|
||||||
// create the framebuffer
|
// create the framebuffer
|
||||||
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer)
|
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer)
|
||||||
// indicate that we will always render to color attachment 0
|
// indicate that we will always render to color attachment 0
|
||||||
@ -62,7 +62,7 @@ class WaterFBOs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createTextureAttachment (gl, width, height) {
|
createTextureAttachment (gl, width, height) {
|
||||||
let texture = gl.createTexture()
|
const texture = gl.createTexture()
|
||||||
gl.bindTexture(gl.TEXTURE_2D, texture)
|
gl.bindTexture(gl.TEXTURE_2D, texture)
|
||||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, width, height, 0, gl.RGB, gl.UNSIGNED_BYTE, null)
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, width, height, 0, gl.RGB, gl.UNSIGNED_BYTE, null)
|
||||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
|
||||||
@ -74,7 +74,7 @@ class WaterFBOs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createDepthTextureAttachment (gl, width, height) {
|
createDepthTextureAttachment (gl, width, height) {
|
||||||
let texture = gl.createTexture()
|
const texture = gl.createTexture()
|
||||||
gl.bindTexture(gl.TEXTURE_2D, texture)
|
gl.bindTexture(gl.TEXTURE_2D, texture)
|
||||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT, width, height, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_SHORT, null)
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT, width, height, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_SHORT, null)
|
||||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
|
||||||
@ -86,7 +86,7 @@ class WaterFBOs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createDepthBufferAttachment (gl, width, height) {
|
createDepthBufferAttachment (gl, width, height) {
|
||||||
let depthBuffer = gl.createRenderbuffer()
|
const depthBuffer = gl.createRenderbuffer()
|
||||||
gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer)
|
gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer)
|
||||||
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height)
|
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height)
|
||||||
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthBuffer)
|
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthBuffer)
|
||||||
@ -124,7 +124,7 @@ class WaterRenderer {
|
|||||||
|
|
||||||
reflect (gl, cam, render) {
|
reflect (gl, cam, render) {
|
||||||
this.fbos.bindReflectionFrameBuffer(gl)
|
this.fbos.bindReflectionFrameBuffer(gl)
|
||||||
let dist = 2 * cam.pos[1]
|
const dist = 2 * cam.pos[1]
|
||||||
cam.pos[1] -= dist
|
cam.pos[1] -= dist
|
||||||
cam.rotation[1] *= -1
|
cam.rotation[1] *= -1
|
||||||
cam.updateTransform()
|
cam.updateTransform()
|
||||||
@ -212,7 +212,7 @@ class WaterRenderer {
|
|||||||
|
|
||||||
// Render a mesh at every tile location
|
// Render a mesh at every tile location
|
||||||
this.mesh.prepare(gl, this.shader)
|
this.mesh.prepare(gl, this.shader)
|
||||||
for (let i in waters) {
|
for (const i in waters) {
|
||||||
const transformLoc = this.shader.getUniformLocation(gl, 'uModelMatrix')
|
const transformLoc = this.shader.getUniformLocation(gl, 'uModelMatrix')
|
||||||
gl.uniformMatrix4fv(transformLoc, false, waters[i].transform)
|
gl.uniformMatrix4fv(transformLoc, false, waters[i].transform)
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ class Environment {
|
|||||||
this.fogColor = [0.8, 0.8, 0.8]
|
this.fogColor = [0.8, 0.8, 0.8]
|
||||||
|
|
||||||
this.sun = new Light([0.0, 1000.0, -2000.0], [1.0, 1.0, 1.0])
|
this.sun = new Light([0.0, 1000.0, -2000.0], [1.0, 1.0, 1.0])
|
||||||
this.lights = [ this.sun ]
|
this.lights = [this.sun]
|
||||||
|
|
||||||
this.maxEnvironmentLights = ENV_MAX_LIGHTS
|
this.maxEnvironmentLights = ENV_MAX_LIGHTS
|
||||||
}
|
}
|
||||||
@ -82,9 +82,9 @@ class Environment {
|
|||||||
|
|
||||||
draw (gl, shader) {
|
draw (gl, shader) {
|
||||||
for (let i = 0; i < this.maxEnvironmentLights; i++) {
|
for (let i = 0; i < this.maxEnvironmentLights; i++) {
|
||||||
let lightColor = shader.getUniformLocation(gl, 'lightColor[' + i + ']')
|
const lightColor = shader.getUniformLocation(gl, 'lightColor[' + i + ']')
|
||||||
let lightPosition = shader.getUniformLocation(gl, 'lightPosition[' + i + ']')
|
const lightPosition = shader.getUniformLocation(gl, 'lightPosition[' + i + ']')
|
||||||
let lightAttn = shader.getUniformLocation(gl, 'attenuation[' + i + ']')
|
const lightAttn = shader.getUniformLocation(gl, 'attenuation[' + i + ']')
|
||||||
|
|
||||||
if (this.lights[i]) {
|
if (this.lights[i]) {
|
||||||
gl.uniform3fv(lightColor, this.lights[i].color)
|
gl.uniform3fv(lightColor, this.lights[i].color)
|
||||||
|
@ -82,9 +82,9 @@ class FontFile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getValues (vals, key) {
|
getValues (vals, key) {
|
||||||
let nums = vals[key].split(NUMBER_SEPARATOR)
|
const nums = vals[key].split(NUMBER_SEPARATOR)
|
||||||
let result = []
|
const result = []
|
||||||
for (let i in nums) {
|
for (const i in nums) {
|
||||||
result.push(parseInt(nums[i]))
|
result.push(parseInt(nums[i]))
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@ -92,14 +92,14 @@ class FontFile {
|
|||||||
|
|
||||||
// Parse a .fnt file
|
// Parse a .fnt file
|
||||||
readValues (data) {
|
readValues (data) {
|
||||||
let lines = data.split('\n')
|
const lines = data.split('\n')
|
||||||
for (let i in lines) {
|
for (const i in lines) {
|
||||||
let line = lines[i]
|
const line = lines[i]
|
||||||
let lineSplit = line.split(SPLITTER)
|
const lineSplit = line.split(SPLITTER)
|
||||||
let lineValues = {}
|
const lineValues = {}
|
||||||
|
|
||||||
for (let j in lineSplit) {
|
for (const j in lineSplit) {
|
||||||
let valuePairs = lineSplit[j].split('=')
|
const valuePairs = lineSplit[j].split('=')
|
||||||
if (valuePairs.length === 2) {
|
if (valuePairs.length === 2) {
|
||||||
lineValues[valuePairs[0]] = valuePairs[1]
|
lineValues[valuePairs[0]] = valuePairs[1]
|
||||||
}
|
}
|
||||||
@ -110,34 +110,34 @@ class FontFile {
|
|||||||
this.paddingWidth = this.padding[PAD_LEFT] + this.padding[PAD_RIGHT]
|
this.paddingWidth = this.padding[PAD_LEFT] + this.padding[PAD_RIGHT]
|
||||||
this.paddingHeight = this.padding[PAD_TOP] + this.padding[PAD_BOTTOM]
|
this.paddingHeight = this.padding[PAD_TOP] + this.padding[PAD_BOTTOM]
|
||||||
} else if (lineSplit[0] === 'common') {
|
} else if (lineSplit[0] === 'common') {
|
||||||
let lineHeightPixels = this.getValue(lineValues, 'lineHeight') - this.paddingHeight
|
const lineHeightPixels = this.getValue(lineValues, 'lineHeight') - this.paddingHeight
|
||||||
this.vertPerPixelSize = LINE_HEIGHT / lineHeightPixels
|
this.vertPerPixelSize = LINE_HEIGHT / lineHeightPixels
|
||||||
this.horizPixelSize = this.vertPerPixelSize / Screen.aspectRatio
|
this.horizPixelSize = this.vertPerPixelSize / Screen.aspectRatio
|
||||||
this.scaleWidth = this.getValue(lineValues, 'scaleW')
|
this.scaleWidth = this.getValue(lineValues, 'scaleW')
|
||||||
} else if (lineSplit[0] === 'char') {
|
} else if (lineSplit[0] === 'char') {
|
||||||
let c = this.loadCharacter(lineValues, this.scaleWidth)
|
const c = this.loadCharacter(lineValues, this.scaleWidth)
|
||||||
if (c) this.metadata[c.id] = c
|
if (c) this.metadata[c.id] = c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loadCharacter (values, imageSize) {
|
loadCharacter (values, imageSize) {
|
||||||
let id = this.getValue(values, 'id')
|
const id = this.getValue(values, 'id')
|
||||||
if (id === SPACE_ASCII) {
|
if (id === SPACE_ASCII) {
|
||||||
this.spaceWidth = (this.getValue(values, 'xadvance') - this.paddingWidth) * this.horizPixelSize
|
this.spaceWidth = (this.getValue(values, 'xadvance') - this.paddingWidth) * this.horizPixelSize
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
let xTex = (this.getValue(values, 'x') + (this.padding[PAD_LEFT] - DESIRED_PADDING)) / imageSize
|
const xTex = (this.getValue(values, 'x') + (this.padding[PAD_LEFT] - DESIRED_PADDING)) / imageSize
|
||||||
let yTex = (this.getValue(values, 'y') + (this.padding[PAD_TOP] - DESIRED_PADDING)) / imageSize
|
const yTex = (this.getValue(values, 'y') + (this.padding[PAD_TOP] - DESIRED_PADDING)) / imageSize
|
||||||
let width = this.getValue(values, 'width') - (this.paddingWidth - (2 * DESIRED_PADDING))
|
const width = this.getValue(values, 'width') - (this.paddingWidth - (2 * DESIRED_PADDING))
|
||||||
let height = this.getValue(values, 'height') - ((this.paddingHeight) - (2 * DESIRED_PADDING))
|
const height = this.getValue(values, 'height') - ((this.paddingHeight) - (2 * DESIRED_PADDING))
|
||||||
let quadWidth = width * this.horizPixelSize
|
const quadWidth = width * this.horizPixelSize
|
||||||
let quadHeight = height * this.vertPerPixelSize
|
const quadHeight = height * this.vertPerPixelSize
|
||||||
let xTexSize = width / imageSize
|
const xTexSize = width / imageSize
|
||||||
let yTexSize = height / imageSize
|
const yTexSize = height / imageSize
|
||||||
let xOff = (this.getValue(values, 'xoffset') + this.padding[PAD_LEFT] - DESIRED_PADDING) * this.horizPixelSize
|
const xOff = (this.getValue(values, 'xoffset') + this.padding[PAD_LEFT] - DESIRED_PADDING) * this.horizPixelSize
|
||||||
let yOff = (this.getValue(values, 'yoffset') + (this.padding[PAD_TOP] - DESIRED_PADDING)) * this.vertPerPixelSize
|
const yOff = (this.getValue(values, 'yoffset') + (this.padding[PAD_TOP] - DESIRED_PADDING)) * this.vertPerPixelSize
|
||||||
let xAdvance = (this.getValue(values, 'xadvance') - this.paddingWidth) * this.horizPixelSize
|
const xAdvance = (this.getValue(values, 'xadvance') - this.paddingWidth) * this.horizPixelSize
|
||||||
return new Character(id, xTex, yTex, xTexSize, yTexSize, xOff, yOff, quadWidth, quadHeight, xAdvance)
|
return new Character(id, xTex, yTex, xTexSize, yTexSize, xOff, yOff, quadWidth, quadHeight, xAdvance)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,8 +146,8 @@ class FontFile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static async fromFile (fontName) {
|
static async fromFile (fontName) {
|
||||||
let load = await Resource.GET('/assets/fonts/' + fontName + '.fnt')
|
const load = await Resource.GET('/assets/fonts/' + fontName + '.fnt')
|
||||||
let file = new FontFile(fontName)
|
const file = new FontFile(fontName)
|
||||||
file.readValues(load)
|
file.readValues(load)
|
||||||
return file
|
return file
|
||||||
}
|
}
|
||||||
@ -162,7 +162,7 @@ class Font {
|
|||||||
|
|
||||||
// Load font data from a .fnt file and create a Font object with it
|
// Load font data from a .fnt file and create a Font object with it
|
||||||
static async fromFile (name) {
|
static async fromFile (name) {
|
||||||
let meta = await FontFile.fromFile(name)
|
const meta = await FontFile.fromFile(name)
|
||||||
return new Font(name, meta)
|
return new Font(name, meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,21 +173,21 @@ class Font {
|
|||||||
|
|
||||||
// Create a renderable mesh for a text
|
// Create a renderable mesh for a text
|
||||||
createTextMesh (gl, text) {
|
createTextMesh (gl, text) {
|
||||||
let lines = this.createStructure(text)
|
const lines = this.createStructure(text)
|
||||||
let data = this.createQuadVertices(text, lines)
|
const data = this.createQuadVertices(text, lines)
|
||||||
return Mesh.constructFromVerticesUVs(gl, data.vertices, data.textureCoords)
|
return Mesh.constructFromVerticesUVs(gl, data.vertices, data.textureCoords)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a structure of lines, words and characters in order to generate the vertices properly
|
// Create a structure of lines, words and characters in order to generate the vertices properly
|
||||||
createStructure (text) {
|
createStructure (text) {
|
||||||
let chars = text.asCharacters
|
const chars = text.asCharacters
|
||||||
let lines = []
|
const lines = []
|
||||||
let currentLine = new Line(this.metadata.spaceWidth, text.fontSize, text.lineLength)
|
let currentLine = new Line(this.metadata.spaceWidth, text.fontSize, text.lineLength)
|
||||||
let currentWord = new Word(text.fontSize)
|
let currentWord = new Word(text.fontSize)
|
||||||
for (let c in chars) {
|
for (const c in chars) {
|
||||||
let ascii = parseInt(chars[c])
|
const ascii = parseInt(chars[c])
|
||||||
if (ascii === SPACE_ASCII) {
|
if (ascii === SPACE_ASCII) {
|
||||||
let added = currentLine.attemptToAddWord(currentWord)
|
const added = currentLine.attemptToAddWord(currentWord)
|
||||||
if (!added) {
|
if (!added) {
|
||||||
lines.push(currentLine)
|
lines.push(currentLine)
|
||||||
currentLine = new Line(this.metadata.spaceWidth, text.fontSize, text.lineLength)
|
currentLine = new Line(this.metadata.spaceWidth, text.fontSize, text.lineLength)
|
||||||
@ -198,7 +198,7 @@ class Font {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ascii === NL_ASCII) {
|
if (ascii === NL_ASCII) {
|
||||||
let added = currentLine.attemptToAddWord(currentWord)
|
const added = currentLine.attemptToAddWord(currentWord)
|
||||||
if (!added) {
|
if (!added) {
|
||||||
lines.push(currentLine)
|
lines.push(currentLine)
|
||||||
currentLine = new Line(this.metadata.spaceWidth, text.fontSize, text.lineLength)
|
currentLine = new Line(this.metadata.spaceWidth, text.fontSize, text.lineLength)
|
||||||
@ -210,7 +210,7 @@ class Font {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
let character = this.metadata.getCharacter(ascii)
|
const character = this.metadata.getCharacter(ascii)
|
||||||
currentWord.addCharacter(character)
|
currentWord.addCharacter(character)
|
||||||
}
|
}
|
||||||
this.completeStructure(lines, currentLine, currentWord, text)
|
this.completeStructure(lines, currentLine, currentWord, text)
|
||||||
@ -219,7 +219,7 @@ class Font {
|
|||||||
|
|
||||||
// Add final word
|
// Add final word
|
||||||
completeStructure (lines, currentLine, currentWord, text) {
|
completeStructure (lines, currentLine, currentWord, text) {
|
||||||
let added = currentLine.attemptToAddWord(currentWord)
|
const added = currentLine.attemptToAddWord(currentWord)
|
||||||
if (!added) {
|
if (!added) {
|
||||||
lines.push(currentLine)
|
lines.push(currentLine)
|
||||||
currentLine = new Line(this.metadata.spaceWidth, text.fontSize, text.lineLength)
|
currentLine = new Line(this.metadata.spaceWidth, text.fontSize, text.lineLength)
|
||||||
@ -234,17 +234,17 @@ class Font {
|
|||||||
text.lines = lines.length
|
text.lines = lines.length
|
||||||
let cursorX = 0
|
let cursorX = 0
|
||||||
let cursorY = 0
|
let cursorY = 0
|
||||||
let vertices = []
|
const vertices = []
|
||||||
let textureCoords = []
|
const textureCoords = []
|
||||||
for (let i in lines) {
|
for (const i in lines) {
|
||||||
let line = lines[i]
|
const line = lines[i]
|
||||||
if (text.centered) {
|
if (text.centered) {
|
||||||
cursorX = (line.maxLength - line.lineLength) / 2
|
cursorX = (line.maxLength - line.lineLength) / 2
|
||||||
}
|
}
|
||||||
for (let j in line.words) {
|
for (const j in line.words) {
|
||||||
let word = line.words[j]
|
const word = line.words[j]
|
||||||
for (let k in word.characters) {
|
for (const k in word.characters) {
|
||||||
let letter = word.characters[k]
|
const letter = word.characters[k]
|
||||||
this.addVerticesForCharacter(cursorX, cursorY, letter, text.fontSize, vertices)
|
this.addVerticesForCharacter(cursorX, cursorY, letter, text.fontSize, vertices)
|
||||||
this.addTexCoords(textureCoords, letter.xTexCoord, letter.yTexCoord, letter.xMaxTexCoord, letter.yMaxTexCoord)
|
this.addTexCoords(textureCoords, letter.xTexCoord, letter.yTexCoord, letter.xMaxTexCoord, letter.yMaxTexCoord)
|
||||||
cursorX += letter.xAdvance * text.fontSize
|
cursorX += letter.xAdvance * text.fontSize
|
||||||
@ -259,14 +259,14 @@ class Font {
|
|||||||
|
|
||||||
// Create text vertex coordinates for a specific character
|
// Create text vertex coordinates for a specific character
|
||||||
addVerticesForCharacter (cursorX, cursorY, character, fontSize, vertices) {
|
addVerticesForCharacter (cursorX, cursorY, character, fontSize, vertices) {
|
||||||
let x = cursorX + (character.xOffset * fontSize)
|
const x = cursorX + (character.xOffset * fontSize)
|
||||||
let y = cursorY + (character.yOffset * fontSize)
|
const y = cursorY + (character.yOffset * fontSize)
|
||||||
let maxX = x + (character.sizeX * fontSize)
|
const maxX = x + (character.sizeX * fontSize)
|
||||||
let maxY = y + (character.sizeY * fontSize)
|
const maxY = y + (character.sizeY * fontSize)
|
||||||
let properX = (2 * x) - 1
|
const properX = (2 * x) - 1
|
||||||
let properY = (-2 * y) + 1
|
const properY = (-2 * y) + 1
|
||||||
let properMaxX = (2 * maxX) - 1
|
const properMaxX = (2 * maxX) - 1
|
||||||
let properMaxY = (-2 * maxY) + 1
|
const properMaxY = (-2 * maxY) + 1
|
||||||
this.addVertices(vertices, properX, properY, properMaxX, properMaxY)
|
this.addVertices(vertices, properX, properY, properMaxX, properMaxY)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,7 +326,7 @@ class GUIText extends Node2D {
|
|||||||
|
|
||||||
// Do not scale the transform like we do with regular GUIs
|
// Do not scale the transform like we do with regular GUIs
|
||||||
updateTransform () {
|
updateTransform () {
|
||||||
let matrix = mat4.create()
|
const matrix = mat4.create()
|
||||||
mat4.translate(matrix, matrix, [this.pos[0], this.pos[2], 0.0])
|
mat4.translate(matrix, matrix, [this.pos[0], this.pos[2], 0.0])
|
||||||
if (this.rotation !== 0.0) {
|
if (this.rotation !== 0.0) {
|
||||||
mat4.rotate(matrix, matrix, this.rotation * Math.PI / 180, [0.0, 0.0, 1.0])
|
mat4.rotate(matrix, matrix, this.rotation * Math.PI / 180, [0.0, 0.0, 1.0])
|
||||||
@ -341,8 +341,8 @@ class GUIText extends Node2D {
|
|||||||
this.transform = matrix
|
this.transform = matrix
|
||||||
|
|
||||||
// Update children's transforms
|
// Update children's transforms
|
||||||
for (let i in this.children) {
|
for (const i in this.children) {
|
||||||
let child = this.children[i]
|
const child = this.children[i]
|
||||||
if (!(child instanceof Node2D)) continue
|
if (!(child instanceof Node2D)) continue
|
||||||
child.updateTransform()
|
child.updateTransform()
|
||||||
}
|
}
|
||||||
@ -363,7 +363,7 @@ class GUIText extends Node2D {
|
|||||||
|
|
||||||
// Return all characters as their ascii code
|
// Return all characters as their ascii code
|
||||||
get asCharacters () {
|
get asCharacters () {
|
||||||
let chars = []
|
const chars = []
|
||||||
for (let i = 0; i < this.text.length; i++) {
|
for (let i = 0; i < this.text.length; i++) {
|
||||||
chars.push(this.text.charCodeAt(i))
|
chars.push(this.text.charCodeAt(i))
|
||||||
}
|
}
|
||||||
@ -404,8 +404,8 @@ class GUIText extends Node2D {
|
|||||||
class FontRenderer {
|
class FontRenderer {
|
||||||
discoverTextNodes (nodes) {
|
discoverTextNodes (nodes) {
|
||||||
let textNodes = []
|
let textNodes = []
|
||||||
for (let i in nodes) {
|
for (const i in nodes) {
|
||||||
let node = nodes[i]
|
const node = nodes[i]
|
||||||
if (!(node instanceof GUIText)) {
|
if (!(node instanceof GUIText)) {
|
||||||
if (node.children.length) {
|
if (node.children.length) {
|
||||||
textNodes = textNodes.concat(this.discoverTextNodes(node.children))
|
textNodes = textNodes.concat(this.discoverTextNodes(node.children))
|
||||||
@ -419,10 +419,10 @@ class FontRenderer {
|
|||||||
|
|
||||||
draw (gl, cam, nodes) {
|
draw (gl, cam, nodes) {
|
||||||
// Discover all nodes in the array that are texts
|
// Discover all nodes in the array that are texts
|
||||||
let fontPairs = {}
|
const fontPairs = {}
|
||||||
let textNodes = this.discoverTextNodes(nodes)
|
const textNodes = this.discoverTextNodes(nodes)
|
||||||
for (let i in textNodes) {
|
for (const i in textNodes) {
|
||||||
let node = textNodes[i]
|
const node = textNodes[i]
|
||||||
if (!this.fonts) {
|
if (!this.fonts) {
|
||||||
this.fonts = {}
|
this.fonts = {}
|
||||||
}
|
}
|
||||||
@ -443,15 +443,15 @@ class FontRenderer {
|
|||||||
gl.enable(gl.BLEND)
|
gl.enable(gl.BLEND)
|
||||||
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
|
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
|
||||||
gl.disable(gl.DEPTH_TEST)
|
gl.disable(gl.DEPTH_TEST)
|
||||||
for (let i in fontPairs) {
|
for (const i in fontPairs) {
|
||||||
let texts = fontPairs[i]
|
const texts = fontPairs[i]
|
||||||
let font = this.fonts[i]
|
const font = this.fonts[i]
|
||||||
// Set font's map as the texture
|
// Set font's map as the texture
|
||||||
gl.activeTexture(gl.TEXTURE0)
|
gl.activeTexture(gl.TEXTURE0)
|
||||||
gl.bindTexture(font.texture.type, font.texture.id)
|
gl.bindTexture(font.texture.type, font.texture.id)
|
||||||
// Draw all texts
|
// Draw all texts
|
||||||
for (let j in texts) {
|
for (const j in texts) {
|
||||||
let text = texts[j]
|
const text = texts[j]
|
||||||
text.draw(gl, this.shader)
|
text.draw(gl, this.shader)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,8 +36,8 @@ class Dim4 {
|
|||||||
let sy = 0.0
|
let sy = 0.0
|
||||||
let oy = 0.0
|
let oy = 0.0
|
||||||
if (tbl.length === 2) {
|
if (tbl.length === 2) {
|
||||||
let x = tbl[0]
|
const x = tbl[0]
|
||||||
let y = tbl[1]
|
const y = tbl[1]
|
||||||
|
|
||||||
if (typeof x === 'object' && x.length === 2) {
|
if (typeof x === 'object' && x.length === 2) {
|
||||||
sx = x[0]
|
sx = x[0]
|
||||||
@ -95,7 +95,7 @@ class Node2D {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateTransform () {
|
updateTransform () {
|
||||||
let matrix = mat4.create()
|
const matrix = mat4.create()
|
||||||
mat4.translate(matrix, matrix, [this.pos[0], this.pos[2], 0.0])
|
mat4.translate(matrix, matrix, [this.pos[0], this.pos[2], 0.0])
|
||||||
mat4.scale(matrix, matrix, [this.size[0], this.size[2], 1.0])
|
mat4.scale(matrix, matrix, [this.size[0], this.size[2], 1.0])
|
||||||
if (this.rotation !== 0.0) {
|
if (this.rotation !== 0.0) {
|
||||||
@ -111,8 +111,8 @@ class Node2D {
|
|||||||
this.transform = matrix
|
this.transform = matrix
|
||||||
|
|
||||||
// Update children's transforms
|
// Update children's transforms
|
||||||
for (let i in this.children) {
|
for (const i in this.children) {
|
||||||
let child = this.children[i]
|
const child = this.children[i]
|
||||||
if (!(child instanceof Node2D)) continue
|
if (!(child instanceof Node2D)) continue
|
||||||
child.updateTransform()
|
child.updateTransform()
|
||||||
}
|
}
|
||||||
@ -130,8 +130,8 @@ class Node2D {
|
|||||||
// Draw base
|
// Draw base
|
||||||
draw (gl, shader, quad) {
|
draw (gl, shader, quad) {
|
||||||
// Nothing to draw here, so just draw children
|
// Nothing to draw here, so just draw children
|
||||||
for (let i in this.children) {
|
for (const i in this.children) {
|
||||||
let child = this.children[i]
|
const child = this.children[i]
|
||||||
if (!(child instanceof Node2D)) continue
|
if (!(child instanceof Node2D)) continue
|
||||||
child.draw(gl, shader, quad)
|
child.draw(gl, shader, quad)
|
||||||
}
|
}
|
||||||
@ -139,8 +139,8 @@ class Node2D {
|
|||||||
|
|
||||||
update (dt) {
|
update (dt) {
|
||||||
// Update children
|
// Update children
|
||||||
for (let i in this.children) {
|
for (const i in this.children) {
|
||||||
let child = this.children[i]
|
const child = this.children[i]
|
||||||
if (!(child instanceof Node2D)) continue
|
if (!(child instanceof Node2D)) continue
|
||||||
child.update(dt)
|
child.update(dt)
|
||||||
}
|
}
|
||||||
@ -149,7 +149,7 @@ class Node2D {
|
|||||||
addChild (ch) {
|
addChild (ch) {
|
||||||
// Recursive add in case of table
|
// Recursive add in case of table
|
||||||
if (ch && typeof ch === 'object' && ch.length) {
|
if (ch && typeof ch === 'object' && ch.length) {
|
||||||
for (let i in ch) {
|
for (const i in ch) {
|
||||||
this.addChild(ch[i])
|
this.addChild(ch[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -204,13 +204,13 @@ class GUIRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
draw (gl, cam, nodes) {
|
draw (gl, cam, nodes) {
|
||||||
if (typeof nodes !== 'object') nodes = [ nodes ]
|
if (typeof nodes !== 'object') nodes = [nodes]
|
||||||
this.shader.use(gl)
|
this.shader.use(gl)
|
||||||
this.quad.prepare(gl, this.shader)
|
this.quad.prepare(gl, this.shader)
|
||||||
gl.enable(gl.BLEND)
|
gl.enable(gl.BLEND)
|
||||||
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
|
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
|
||||||
gl.disable(gl.DEPTH_TEST)
|
gl.disable(gl.DEPTH_TEST)
|
||||||
for (let i in nodes) {
|
for (const i in nodes) {
|
||||||
nodes[i].draw(gl, this.shader, this.quad)
|
nodes[i].draw(gl, this.shader, this.quad)
|
||||||
}
|
}
|
||||||
gl.enable(gl.DEPTH_TEST)
|
gl.enable(gl.DEPTH_TEST)
|
||||||
|
@ -52,14 +52,14 @@ class Engine {
|
|||||||
|
|
||||||
render () {
|
render () {
|
||||||
// Render functions
|
// Render functions
|
||||||
for (let i in this.rst) {
|
for (const i in this.rst) {
|
||||||
this.rst[i](gl)
|
this.rst[i](gl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
update (dt) {
|
update (dt) {
|
||||||
// Updates
|
// Updates
|
||||||
for (let i in this.ust) {
|
for (const i in this.ust) {
|
||||||
this.ust[i](dt)
|
this.ust[i](dt)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,8 +71,8 @@ class Engine {
|
|||||||
|
|
||||||
this.render(this.gl)
|
this.render(this.gl)
|
||||||
|
|
||||||
let ts = performance.now()
|
const ts = performance.now()
|
||||||
let timeDiff = ts - this.frameTime // time difference in milliseconds
|
const timeDiff = ts - this.frameTime // time difference in milliseconds
|
||||||
this.frameCount++
|
this.frameCount++
|
||||||
|
|
||||||
if (timeDiff > 0) {
|
if (timeDiff > 0) {
|
||||||
|
@ -1,65 +1,65 @@
|
|||||||
|
|
||||||
const specialKeyMap = {
|
const specialKeyMap = {
|
||||||
'backspace': 8,
|
backspace: 8,
|
||||||
'tab': 9,
|
tab: 9,
|
||||||
'enter': 13,
|
enter: 13,
|
||||||
'shift': 16,
|
shift: 16,
|
||||||
'ctrl': 17,
|
ctrl: 17,
|
||||||
'alt': 18,
|
alt: 18,
|
||||||
'pausebreak': 19,
|
pausebreak: 19,
|
||||||
'capslock': 20,
|
capslock: 20,
|
||||||
'escape': 27,
|
escape: 27,
|
||||||
'pgup': 33,
|
pgup: 33,
|
||||||
'pgdown': 34,
|
pgdown: 34,
|
||||||
'end': 35,
|
end: 35,
|
||||||
'home': 36,
|
home: 36,
|
||||||
'left': 37,
|
left: 37,
|
||||||
'up': 38,
|
up: 38,
|
||||||
'right': 39,
|
right: 39,
|
||||||
'down': 40,
|
down: 40,
|
||||||
'insert': 45,
|
insert: 45,
|
||||||
'delete': 46,
|
delete: 46,
|
||||||
'left-window': 91,
|
'left-window': 91,
|
||||||
'right-window': 92,
|
'right-window': 92,
|
||||||
'select': 93,
|
select: 93,
|
||||||
'numpad0': 96,
|
numpad0: 96,
|
||||||
'numpad1': 97,
|
numpad1: 97,
|
||||||
'numpad2': 98,
|
numpad2: 98,
|
||||||
'numpad3': 99,
|
numpad3: 99,
|
||||||
'numpad4': 100,
|
numpad4: 100,
|
||||||
'numpad5': 101,
|
numpad5: 101,
|
||||||
'numpad6': 102,
|
numpad6: 102,
|
||||||
'numpad7': 103,
|
numpad7: 103,
|
||||||
'numpad8': 104,
|
numpad8: 104,
|
||||||
'numpad9': 105,
|
numpad9: 105,
|
||||||
'multiply': 106,
|
multiply: 106,
|
||||||
'add': 107,
|
add: 107,
|
||||||
'subtract': 109,
|
subtract: 109,
|
||||||
'decimal': 110,
|
decimal: 110,
|
||||||
'divide': 111,
|
divide: 111,
|
||||||
'f1': 112,
|
f1: 112,
|
||||||
'f2': 113,
|
f2: 113,
|
||||||
'f3': 114,
|
f3: 114,
|
||||||
'f4': 115,
|
f4: 115,
|
||||||
'f5': 116,
|
f5: 116,
|
||||||
'f6': 117,
|
f6: 117,
|
||||||
'f7': 118,
|
f7: 118,
|
||||||
'f8': 119,
|
f8: 119,
|
||||||
'f9': 120,
|
f9: 120,
|
||||||
'f10': 121,
|
f10: 121,
|
||||||
'f11': 122,
|
f11: 122,
|
||||||
'f12': 123,
|
f12: 123,
|
||||||
'numlock': 144,
|
numlock: 144,
|
||||||
'scrolllock': 145,
|
scrolllock: 145,
|
||||||
'semi-colon': 186,
|
'semi-colon': 186,
|
||||||
'equals': 187,
|
equals: 187,
|
||||||
'comma': 188,
|
comma: 188,
|
||||||
'dash': 189,
|
dash: 189,
|
||||||
'period': 190,
|
period: 190,
|
||||||
'fwdslash': 191,
|
fwdslash: 191,
|
||||||
'grave': 192,
|
grave: 192,
|
||||||
'open-bracket': 219,
|
'open-bracket': 219,
|
||||||
'bkslash': 220,
|
bkslash: 220,
|
||||||
'close-braket': 221,
|
'close-braket': 221,
|
||||||
'single-quote': 222
|
'single-quote': 222
|
||||||
}
|
}
|
||||||
@ -84,7 +84,7 @@ class Input {
|
|||||||
let y
|
let y
|
||||||
|
|
||||||
if (e.changedTouches) {
|
if (e.changedTouches) {
|
||||||
let touch = e.changedTouches[0]
|
const touch = e.changedTouches[0]
|
||||||
if (touch) {
|
if (touch) {
|
||||||
e.pageX = touch.pageX
|
e.pageX = touch.pageX
|
||||||
e.pageY = touch.pageY
|
e.pageY = touch.pageY
|
||||||
@ -140,8 +140,8 @@ class Input {
|
|||||||
toggleKey (keyCode, on) {
|
toggleKey (keyCode, on) {
|
||||||
// Find key in special key list
|
// Find key in special key list
|
||||||
let key = null
|
let key = null
|
||||||
for (let k in specialKeyMap) {
|
for (const k in specialKeyMap) {
|
||||||
let val = specialKeyMap[k]
|
const val = specialKeyMap[k]
|
||||||
if (keyCode === val) {
|
if (keyCode === val) {
|
||||||
key = k
|
key = k
|
||||||
break
|
break
|
||||||
@ -202,7 +202,7 @@ class Input {
|
|||||||
|
|
||||||
update () {
|
update () {
|
||||||
this.previousKeyList = {}
|
this.previousKeyList = {}
|
||||||
for (let k in this.keyList) {
|
for (const k in this.keyList) {
|
||||||
if (this.keyList[k] === true) {
|
if (this.keyList[k] === true) {
|
||||||
this.previousKeyList[k] = true
|
this.previousKeyList[k] = true
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,10 @@ class BoundingBox {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static fromMesh (mesh) {
|
static fromMesh (mesh) {
|
||||||
let min = [0, 0, 0]
|
const min = [0, 0, 0]
|
||||||
let max = [0, 0, 0]
|
const max = [0, 0, 0]
|
||||||
for (let v = 0; v < mesh.vertices.length; v += 3) {
|
for (let v = 0; v < mesh.vertices.length; v += 3) {
|
||||||
let vertex = [mesh.vertices[v], mesh.vertices[v + 1], mesh.vertices[v + 2]]
|
const vertex = [mesh.vertices[v], mesh.vertices[v + 1], mesh.vertices[v + 2]]
|
||||||
// X
|
// X
|
||||||
if (vertex[0] > max[0]) max[0] = vertex[0]
|
if (vertex[0] > max[0]) max[0] = vertex[0]
|
||||||
if (vertex[0] < min[0]) min[0] = vertex[0]
|
if (vertex[0] < min[0]) min[0] = vertex[0]
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
|
import { subv3, normalv3, crossv3 } from '../utility'
|
||||||
|
|
||||||
class Mesh {
|
class Mesh {
|
||||||
static loadToBuffer (gl, type, data, drawtype = gl.STATIC_DRAW) {
|
static loadToBuffer (gl, type, data, drawtype = gl.STATIC_DRAW) {
|
||||||
let id = gl.createBuffer()
|
const id = gl.createBuffer()
|
||||||
gl.bindBuffer(type, id)
|
gl.bindBuffer(type, id)
|
||||||
gl.bufferData(type, data, drawtype)
|
gl.bufferData(type, data, drawtype)
|
||||||
return id
|
return id
|
||||||
@ -9,16 +10,16 @@ class Mesh {
|
|||||||
|
|
||||||
static construct (gl, vertices, indices, uvs, normals) {
|
static construct (gl, vertices, indices, uvs, normals) {
|
||||||
// VBO for model vertices
|
// VBO for model vertices
|
||||||
let pos = Mesh.loadToBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(vertices))
|
const pos = Mesh.loadToBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(vertices))
|
||||||
|
|
||||||
// Create the mesh, as we have the most important data already buffered
|
// Create the mesh, as we have the most important data already buffered
|
||||||
let mesh = new Mesh()
|
const mesh = new Mesh()
|
||||||
mesh.posBuffer = pos
|
mesh.posBuffer = pos
|
||||||
mesh.vertices = vertices
|
mesh.vertices = vertices
|
||||||
|
|
||||||
// Indices Buffer (EBO)
|
// Indices Buffer (EBO)
|
||||||
if (indices) {
|
if (indices) {
|
||||||
let ebo = Mesh.loadToBuffer(gl, gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices))
|
const ebo = Mesh.loadToBuffer(gl, gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices))
|
||||||
mesh.ebo = ebo
|
mesh.ebo = ebo
|
||||||
mesh.indices = indices
|
mesh.indices = indices
|
||||||
} else {
|
} else {
|
||||||
@ -44,8 +45,8 @@ class Mesh {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static constructFromVertices (gl, vertices, dimensions = 3) {
|
static constructFromVertices (gl, vertices, dimensions = 3) {
|
||||||
let pos = Mesh.loadToBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(vertices))
|
const pos = Mesh.loadToBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(vertices))
|
||||||
let mesh = new Mesh()
|
const mesh = new Mesh()
|
||||||
mesh.posBuffer = pos
|
mesh.posBuffer = pos
|
||||||
mesh.vertices = vertices
|
mesh.vertices = vertices
|
||||||
mesh.vertexCount = vertices.length / dimensions
|
mesh.vertexCount = vertices.length / dimensions
|
||||||
@ -56,8 +57,8 @@ class Mesh {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static constructFromVerticesUVs (gl, vertices, uvs, dimensions = 2) {
|
static constructFromVerticesUVs (gl, vertices, uvs, dimensions = 2) {
|
||||||
let pos = Mesh.loadToBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(vertices))
|
const pos = Mesh.loadToBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(vertices))
|
||||||
let mesh = new Mesh()
|
const mesh = new Mesh()
|
||||||
mesh.uv = uvs
|
mesh.uv = uvs
|
||||||
mesh.posBuffer = pos
|
mesh.posBuffer = pos
|
||||||
mesh.vertices = vertices
|
mesh.vertices = vertices
|
||||||
@ -69,10 +70,47 @@ class Mesh {
|
|||||||
return mesh
|
return mesh
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static generateNormals (normals, indices, vertices) {
|
||||||
|
// Generate normals
|
||||||
|
for (let i = 0; i < indices.length; i += 3) {
|
||||||
|
// Extract face from vertices
|
||||||
|
// First vertex position
|
||||||
|
const vertexA = [
|
||||||
|
vertices[indices[i] * 3],
|
||||||
|
vertices[indices[i] * 3 + 1],
|
||||||
|
vertices[indices[i] * 3 + 2]
|
||||||
|
]
|
||||||
|
|
||||||
|
// Second vertex position
|
||||||
|
const vertexB = [
|
||||||
|
vertices[indices[i + 1] * 3],
|
||||||
|
vertices[indices[i + 1] * 3 + 1],
|
||||||
|
vertices[indices[i + 1] * 3 + 2]
|
||||||
|
]
|
||||||
|
|
||||||
|
// Third vertex position
|
||||||
|
const vertexC = [
|
||||||
|
vertices[indices[i + 2] * 3],
|
||||||
|
vertices[indices[i + 2] * 3 + 1],
|
||||||
|
vertices[indices[i + 2] * 3 + 2]
|
||||||
|
]
|
||||||
|
|
||||||
|
// Normalize
|
||||||
|
const dir = crossv3(subv3(vertexB, vertexA), subv3(vertexC, vertexA))
|
||||||
|
const normal = normalv3(dir)
|
||||||
|
|
||||||
|
for (let k = 0; k < 3; k++) {
|
||||||
|
normals[indices[i + k] * 3] = normal[0]
|
||||||
|
normals[indices[i + k] * 3 + 1] = normal[1]
|
||||||
|
normals[indices[i + k] * 3 + 2] = normal[2]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bindBuffers (gl, shader) {
|
bindBuffers (gl, shader) {
|
||||||
this._bufferCount = 1
|
this._bufferCount = 1
|
||||||
|
|
||||||
let d = this.vertexLayout || 3
|
const d = this.vertexLayout || 3
|
||||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.posBuffer)
|
gl.bindBuffer(gl.ARRAY_BUFFER, this.posBuffer)
|
||||||
shader.setAttribute(gl, 'aVertexPosition', d, false, d * Float32Array.BYTES_PER_ELEMENT, 0)
|
shader.setAttribute(gl, 'aVertexPosition', d, false, d * Float32Array.BYTES_PER_ELEMENT, 0)
|
||||||
|
|
||||||
@ -129,7 +167,7 @@ class Mesh {
|
|||||||
}
|
}
|
||||||
|
|
||||||
recreate (gl) {
|
recreate (gl) {
|
||||||
let msh = Mesh.construct(gl, this.vertices, this.indices, this.uv, this.normals)
|
const msh = Mesh.construct(gl, this.vertices, this.indices, this.uv, this.normals)
|
||||||
if (!msh) return null
|
if (!msh) return null
|
||||||
this.dispose(gl)
|
this.dispose(gl)
|
||||||
return msh
|
return msh
|
||||||
|
@ -6,15 +6,15 @@ import { mat4 } from 'gl-matrix'
|
|||||||
|
|
||||||
import Resource from '../resource'
|
import Resource from '../resource'
|
||||||
|
|
||||||
let meshCache = {}
|
const meshCache = {}
|
||||||
|
|
||||||
// Parse an assimp2json formatted mesh file
|
// Parse an assimp2json formatted mesh file
|
||||||
// Supports multiple geometries
|
// Supports multiple geometries
|
||||||
async function assimp2json (gl, file, dat) {
|
async function assimp2json (gl, file, dat) {
|
||||||
let cleaned = []
|
const cleaned = []
|
||||||
let materials = []
|
const materials = []
|
||||||
for (let mi in dat.meshes) {
|
for (const mi in dat.meshes) {
|
||||||
let mesh = dat.meshes[mi]
|
const mesh = dat.meshes[mi]
|
||||||
let material
|
let material
|
||||||
|
|
||||||
if (mesh.materialindex != null && dat.materials && dat.materials.length) {
|
if (mesh.materialindex != null && dat.materials && dat.materials.length) {
|
||||||
@ -24,15 +24,15 @@ async function assimp2json (gl, file, dat) {
|
|||||||
} else {
|
} else {
|
||||||
// Load a new material
|
// Load a new material
|
||||||
material = new Material()
|
material = new Material()
|
||||||
let matdata = dat.materials[mesh.materialindex].properties
|
const matdata = dat.materials[mesh.materialindex].properties
|
||||||
|
|
||||||
// Parse material information
|
// Parse material information
|
||||||
for (let pi in matdata) {
|
for (const pi in matdata) {
|
||||||
let property = matdata[pi]
|
const property = matdata[pi]
|
||||||
if (!property || !property.key) continue
|
if (!property || !property.key) continue
|
||||||
if (property.key === '?mat.name') material.name = property.value
|
if (property.key === '?mat.name') material.name = property.value
|
||||||
else if (property.key.indexOf('$clr.') === 0) {
|
else if (property.key.indexOf('$clr.') === 0) {
|
||||||
let dproperty = property.key.substr(5)
|
const dproperty = property.key.substr(5)
|
||||||
switch (dproperty) {
|
switch (dproperty) {
|
||||||
case 'specular':
|
case 'specular':
|
||||||
case 'diffuse':
|
case 'diffuse':
|
||||||
@ -65,10 +65,10 @@ async function assimp2json (gl, file, dat) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load everything
|
// Load everything
|
||||||
let loadComplete = []
|
const loadComplete = []
|
||||||
for (let i in cleaned) {
|
for (const i in cleaned) {
|
||||||
let meshdata = cleaned[i]
|
const meshdata = cleaned[i]
|
||||||
let mesh = Mesh.construct(gl, meshdata.vertices, meshdata.indices,
|
const mesh = Mesh.construct(gl, meshdata.vertices, meshdata.indices,
|
||||||
meshdata.uv, meshdata.normals)
|
meshdata.uv, meshdata.normals)
|
||||||
|
|
||||||
// Initialize the material's texture if present
|
// Initialize the material's texture if present
|
||||||
@ -84,12 +84,12 @@ async function assimp2json (gl, file, dat) {
|
|||||||
loadComplete.push(mesh)
|
loadComplete.push(mesh)
|
||||||
}
|
}
|
||||||
|
|
||||||
let finished = []
|
const finished = []
|
||||||
let lastTransform = dat.rootnode.transformation
|
const lastTransform = dat.rootnode.transformation
|
||||||
function setChildren (parent, chMeshes, last) {
|
function setChildren (parent, chMeshes, last) {
|
||||||
if (!chMeshes.meshes) {
|
if (!chMeshes.meshes) {
|
||||||
if (chMeshes.children) {
|
if (chMeshes.children) {
|
||||||
for (let j in chMeshes.children) {
|
for (const j in chMeshes.children) {
|
||||||
setChildren(null, chMeshes.children[j], chMeshes)
|
setChildren(null, chMeshes.children[j], chMeshes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,16 +97,16 @@ async function assimp2json (gl, file, dat) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Transpose the mesh's transform
|
// Transpose the mesh's transform
|
||||||
let transform = chMeshes.transformation
|
const transform = chMeshes.transformation
|
||||||
|
|
||||||
let meshIndex = chMeshes.meshes[0]
|
const meshIndex = chMeshes.meshes[0]
|
||||||
let mesh = loadComplete[meshIndex]
|
const mesh = loadComplete[meshIndex]
|
||||||
let meshInstance = new MeshInstance(mesh)
|
const meshInstance = new MeshInstance(mesh)
|
||||||
|
|
||||||
meshInstance.mesh = mesh
|
meshInstance.mesh = mesh
|
||||||
|
|
||||||
if (chMeshes.children) {
|
if (chMeshes.children) {
|
||||||
for (let i in chMeshes.children) {
|
for (const i in chMeshes.children) {
|
||||||
if (!chMeshes.children[i].meshes) continue
|
if (!chMeshes.children[i].meshes) continue
|
||||||
setChildren(meshInstance, chMeshes.children[i], chMeshes)
|
setChildren(meshInstance, chMeshes.children[i], chMeshes)
|
||||||
}
|
}
|
||||||
@ -158,15 +158,15 @@ async function loadMesh (gl, file) {
|
|||||||
// Ensure each mesh file is loaded only once
|
// Ensure each mesh file is loaded only once
|
||||||
if (meshCache[file]) {
|
if (meshCache[file]) {
|
||||||
if (meshCache[file].length <= 1) return meshCache[file][0]
|
if (meshCache[file].length <= 1) return meshCache[file][0]
|
||||||
let cached = new Node()
|
const cached = new Node()
|
||||||
cached.addChild(meshCache[file])
|
cached.addChild(meshCache[file])
|
||||||
return cached
|
return cached
|
||||||
}
|
}
|
||||||
|
|
||||||
let dat = await Resource.GET({ type: 'json', url: file })
|
const dat = await Resource.GET({ type: 'json', url: file })
|
||||||
|
|
||||||
// Recognize a assimp2json file format
|
// Recognize a assimp2json file format
|
||||||
if (dat['__metadata__'] && dat['__metadata__'].format === 'assimp2json') {
|
if (dat.__metadata__ && dat.__metadata__.format === 'assimp2json') {
|
||||||
if (!dat.meshes) throw new Error('No geometries found in file ' + file)
|
if (!dat.meshes) throw new Error('No geometries found in file ' + file)
|
||||||
return assimp2json(gl, file, dat)
|
return assimp2json(gl, file, dat)
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,12 @@ import Resource from '../resource'
|
|||||||
|
|
||||||
class Texture {
|
class Texture {
|
||||||
static async fromFile (gl, file, flip, filtering, repeat) {
|
static async fromFile (gl, file, flip, filtering, repeat) {
|
||||||
let image = await Resource.loadImage(file)
|
const image = await Resource.loadImage(file)
|
||||||
return Texture.createTexture2D(gl, image, flip, filtering, repeat)
|
return Texture.createTexture2D(gl, image, flip, filtering, repeat)
|
||||||
}
|
}
|
||||||
|
|
||||||
static createTexture2D (gl, img, flip = false, filtering, repeat = gl.REPEAT) {
|
static createTexture2D (gl, img, flip = false, filtering, repeat = gl.REPEAT) {
|
||||||
let tex = gl.createTexture()
|
const tex = gl.createTexture()
|
||||||
gl.bindTexture(gl.TEXTURE_2D, tex)
|
gl.bindTexture(gl.TEXTURE_2D, tex)
|
||||||
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flip)
|
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flip)
|
||||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img)
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img)
|
||||||
@ -24,7 +24,7 @@ class Texture {
|
|||||||
|
|
||||||
gl.bindTexture(gl.TEXTURE_2D, null)
|
gl.bindTexture(gl.TEXTURE_2D, null)
|
||||||
|
|
||||||
let oTex = new Texture()
|
const oTex = new Texture()
|
||||||
oTex.type = gl.TEXTURE_2D
|
oTex.type = gl.TEXTURE_2D
|
||||||
oTex.id = tex
|
oTex.id = tex
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ class Texture {
|
|||||||
|
|
||||||
static createTextureCubeMap (gl, img) {
|
static createTextureCubeMap (gl, img) {
|
||||||
if (!img || img.length !== 6) throw new Error('createTextureCubeMap() requires six images!')
|
if (!img || img.length !== 6) throw new Error('createTextureCubeMap() requires six images!')
|
||||||
let tex = gl.createTexture()
|
const tex = gl.createTexture()
|
||||||
gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex)
|
gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex)
|
||||||
|
|
||||||
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false)
|
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false)
|
||||||
@ -50,7 +50,7 @@ class Texture {
|
|||||||
|
|
||||||
gl.bindTexture(gl.TEXTURE_CUBE_MAP, null)
|
gl.bindTexture(gl.TEXTURE_CUBE_MAP, null)
|
||||||
|
|
||||||
let oTex = new Texture()
|
const oTex = new Texture()
|
||||||
oTex.type = gl.TEXTURE_CUBE_MAP
|
oTex.type = gl.TEXTURE_CUBE_MAP
|
||||||
oTex.id = tex
|
oTex.id = tex
|
||||||
|
|
||||||
@ -65,10 +65,10 @@ class Material {
|
|||||||
|
|
||||||
async loadTextures (gl) {
|
async loadTextures (gl) {
|
||||||
if (this.textures) {
|
if (this.textures) {
|
||||||
for (let ti in this.textures) {
|
for (const ti in this.textures) {
|
||||||
let tex = this.textures[ti]
|
const tex = this.textures[ti]
|
||||||
if (!(tex instanceof Texture)) {
|
if (!(tex instanceof Texture)) {
|
||||||
let result = await Texture.fromFile(gl, tex, true)
|
const result = await Texture.fromFile(gl, tex, true)
|
||||||
this.textures[ti] = result
|
this.textures[ti] = result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,8 +80,8 @@ class Material {
|
|||||||
|
|
||||||
// Load textures
|
// Load textures
|
||||||
if (!this.textures || !this.textures.length) return
|
if (!this.textures || !this.textures.length) return
|
||||||
for (let i in this.textures) {
|
for (const i in this.textures) {
|
||||||
let tex = this.textures[i]
|
const tex = this.textures[i]
|
||||||
if (tex && tex instanceof Texture) {
|
if (tex && tex instanceof Texture) {
|
||||||
gl.activeTexture(gl.TEXTURE0 + parseInt(i))
|
gl.activeTexture(gl.TEXTURE0 + parseInt(i))
|
||||||
gl.bindTexture(tex.type, tex.id)
|
gl.bindTexture(tex.type, tex.id)
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
/* global XMLHttpRequest, Image */
|
/* global XMLHttpRequest, Image */
|
||||||
|
|
||||||
let imgCache = {}
|
const imgCache = {}
|
||||||
|
|
||||||
// Find the assets directory properly
|
// Find the assets directory properly
|
||||||
function fixURI (path, a = '') {
|
function fixURI (path, a = '') {
|
||||||
let pn = window.location.pathname
|
const pn = window.location.pathname
|
||||||
if (path.indexOf('/assets') === -1) path = '/assets/' + a + path
|
if (path.indexOf('/assets') === -1) path = '/assets/' + a + path
|
||||||
if (pn === '/' || pn === '/index.html') return path
|
if (pn === '/' || pn === '/index.html') return path
|
||||||
let assetsDir = pn + path
|
const assetsDir = pn + path
|
||||||
return assetsDir.replace(/\/\//g, '/')
|
return assetsDir.replace(/\/\//g, '/')
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ function GET (url, istext) {
|
|||||||
if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
|
if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
|
||||||
resolve(xmlHttp.responseText)
|
resolve(xmlHttp.responseText)
|
||||||
} else if (xmlHttp.readyState === 4 && xmlHttp.status >= 400) {
|
} else if (xmlHttp.readyState === 4 && xmlHttp.status >= 400) {
|
||||||
let err = new Error(xmlHttp.status)
|
const err = new Error(xmlHttp.status)
|
||||||
err.request = xmlHttp
|
err.request = xmlHttp
|
||||||
reject(err)
|
reject(err)
|
||||||
}
|
}
|
||||||
@ -40,16 +40,16 @@ function smartGET (data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!data.type) data.type = 'text'
|
if (!data.type) data.type = 'text'
|
||||||
let istext = (data.type !== 'image' && data.type !== 'file')
|
const istext = (data.type !== 'image' && data.type !== 'file')
|
||||||
|
|
||||||
let url = data.url
|
const url = data.url
|
||||||
if (!url) throw new Error('URL is required!')
|
if (!url) throw new Error('URL is required!')
|
||||||
|
|
||||||
if (data.type === 'json') {
|
if (data.type === 'json') {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
GET(url).then((dtext) => {
|
GET(url).then((dtext) => {
|
||||||
try {
|
try {
|
||||||
let jsonp = JSON.parse(dtext)
|
const jsonp = JSON.parse(dtext)
|
||||||
return resolve(jsonp)
|
return resolve(jsonp)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
reject(e)
|
reject(e)
|
||||||
@ -68,7 +68,7 @@ function loadImage (url) {
|
|||||||
if (imgCache[url]) return imgCache[url]
|
if (imgCache[url]) return imgCache[url]
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let img = new Image()
|
const img = new Image()
|
||||||
|
|
||||||
img.onload = function () {
|
img.onload = function () {
|
||||||
imgCache[url] = img
|
imgCache[url] = img
|
||||||
@ -84,8 +84,8 @@ function loadImage (url) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function imageToSampler (img) {
|
function imageToSampler (img) {
|
||||||
let canvas = document.createElement('canvas')
|
const canvas = document.createElement('canvas')
|
||||||
let ctx = canvas.getContext('2d')
|
const ctx = canvas.getContext('2d')
|
||||||
canvas.width = img.width
|
canvas.width = img.width
|
||||||
canvas.height = img.height
|
canvas.height = img.height
|
||||||
ctx.drawImage(img, 0, 0, img.width, img.height)
|
ctx.drawImage(img, 0, 0, img.width, img.height)
|
||||||
|
@ -18,7 +18,7 @@ class Shader {
|
|||||||
|
|
||||||
// See if it compiled successfully
|
// See if it compiled successfully
|
||||||
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
||||||
let inf = gl.getShaderInfoLog(shader)
|
const inf = gl.getShaderInfoLog(shader)
|
||||||
gl.deleteShader(shader)
|
gl.deleteShader(shader)
|
||||||
throw new Error('An error occurred compiling the shaders: ' + inf)
|
throw new Error('An error occurred compiling the shaders: ' + inf)
|
||||||
}
|
}
|
||||||
@ -43,9 +43,9 @@ class ShaderProgram {
|
|||||||
}
|
}
|
||||||
|
|
||||||
link (gl, vs, fs, gs) {
|
link (gl, vs, fs, gs) {
|
||||||
let vsh = [ vs, fs, gs ]
|
const vsh = [vs, fs, gs]
|
||||||
|
|
||||||
for (let i in vsh) {
|
for (const i in vsh) {
|
||||||
vsh[i] && vsh[i].compile(gl)
|
vsh[i] && vsh[i].compile(gl)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ class ShaderProgram {
|
|||||||
|
|
||||||
getUniformLocation (gl, name) {
|
getUniformLocation (gl, name) {
|
||||||
if (this.uniforms[name]) return this.uniforms[name]
|
if (this.uniforms[name]) return this.uniforms[name]
|
||||||
let uni = gl.getUniformLocation(this.id, name)
|
const uni = gl.getUniformLocation(this.id, name)
|
||||||
if (uni < 0) return null
|
if (uni < 0) return null
|
||||||
|
|
||||||
this.uniforms[name] = uni
|
this.uniforms[name] = uni
|
||||||
@ -88,7 +88,7 @@ class ShaderProgram {
|
|||||||
|
|
||||||
getAttributeLocation (gl, name) {
|
getAttributeLocation (gl, name) {
|
||||||
if (this.attribs[name]) return this.attribs[name]
|
if (this.attribs[name]) return this.attribs[name]
|
||||||
let pos = gl.getAttribLocation(this.id, name)
|
const pos = gl.getAttribLocation(this.id, name)
|
||||||
if (pos < 0) throw new Error(`No such attribute location ${name} in shader ${this.name}!`)
|
if (pos < 0) throw new Error(`No such attribute location ${name} in shader ${this.name}!`)
|
||||||
this.attribs[name] = pos
|
this.attribs[name] = pos
|
||||||
return pos
|
return pos
|
||||||
@ -104,7 +104,7 @@ class ShaderProgram {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setAttribute (gl, name, size, normalized, stride, offset, type) {
|
setAttribute (gl, name, size, normalized, stride, offset, type) {
|
||||||
let loc = this.getAttributeLocation(gl, name) // throws an error in case the name doesn't exist in shader
|
const loc = this.getAttributeLocation(gl, name) // throws an error in case the name doesn't exist in shader
|
||||||
|
|
||||||
gl.enableVertexAttribArray(loc)
|
gl.enableVertexAttribArray(loc)
|
||||||
gl.vertexAttribPointer(
|
gl.vertexAttribPointer(
|
||||||
@ -129,11 +129,11 @@ class ShaderManager {
|
|||||||
|
|
||||||
createShader (gl, name, vs, fs, gs) {
|
createShader (gl, name, vs, fs, gs) {
|
||||||
if (this.shaders[name]) return this.shaders[name]
|
if (this.shaders[name]) return this.shaders[name]
|
||||||
let shader = new ShaderProgram(name)
|
const shader = new ShaderProgram(name)
|
||||||
|
|
||||||
let vert = new Shader(gl.VERTEX_SHADER, vs)
|
const vert = new Shader(gl.VERTEX_SHADER, vs)
|
||||||
let frag = new Shader(gl.FRAGMENT_SHADER, fs)
|
const frag = new Shader(gl.FRAGMENT_SHADER, fs)
|
||||||
let geom = gs ? new Shader(gl.GEOMETRY_SHADER, gs) : null
|
const geom = gs ? new Shader(gl.GEOMETRY_SHADER, gs) : null
|
||||||
|
|
||||||
shader.link(gl, vert, frag, geom)
|
shader.link(gl, vert, frag, geom)
|
||||||
|
|
||||||
@ -144,12 +144,12 @@ class ShaderManager {
|
|||||||
// Standard shader nomenclature: /assets/shaders/shader-name.vs|fs[|gs]
|
// Standard shader nomenclature: /assets/shaders/shader-name.vs|fs[|gs]
|
||||||
// shader-name.vs and shader-name.fs are mandatory!
|
// shader-name.vs and shader-name.fs are mandatory!
|
||||||
createShaderFromFiles (gl, name, gs) {
|
createShaderFromFiles (gl, name, gs) {
|
||||||
let stdloc = '/assets/shaders/' + name
|
const stdloc = '/assets/shaders/' + name
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
function finishLink (vs, fs, gss) {
|
function finishLink (vs, fs, gss) {
|
||||||
try {
|
try {
|
||||||
let shader = this.createShader(gl, name, vs, fs, gss)
|
const shader = this.createShader(gl, name, vs, fs, gss)
|
||||||
resolve(shader)
|
resolve(shader)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
reject(e)
|
reject(e)
|
||||||
|
@ -57,13 +57,13 @@ export function divv3 (one, two) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function normalv3 (vec) {
|
export function normalv3 (vec) {
|
||||||
let res = vec
|
const res = vec
|
||||||
vec3.normalize(res, vec)
|
vec3.normalize(res, vec)
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
export function crossv3 (vec1, vec2) {
|
export function crossv3 (vec1, vec2) {
|
||||||
let res = []
|
const res = []
|
||||||
vec3.cross(res, vec1, vec2)
|
vec3.cross(res, vec1, vec2)
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
@ -145,9 +145,9 @@ class VoxelChunk extends MeshInstance {
|
|||||||
if (!this.data[x]) this.data[x] = {}
|
if (!this.data[x]) this.data[x] = {}
|
||||||
for (let z = 0; z < this.size; z++) {
|
for (let z = 0; z < this.size; z++) {
|
||||||
if (!this.data[x][z]) this.data[x][z] = {}
|
if (!this.data[x][z]) this.data[x][z] = {}
|
||||||
let columnHeight = generator.getHeight(x + this.pos[0], z + this.pos[2])
|
const columnHeight = generator.getHeight(x + this.pos[0], z + this.pos[2])
|
||||||
for (let y = 0; y < this.size; y++) {
|
for (let y = 0; y < this.size; y++) {
|
||||||
let solid = this.pos[1] + y < columnHeight
|
const solid = this.pos[1] + y < columnHeight
|
||||||
this.data[x][z][y] = solid ? GROUND_VOXEL : AIR_VOXEL
|
this.data[x][z][y] = solid ? GROUND_VOXEL : AIR_VOXEL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -168,13 +168,13 @@ class VoxelChunk extends MeshInstance {
|
|||||||
// Returns the position, normal and texture coordinates for each vertex in this face
|
// Returns the position, normal and texture coordinates for each vertex in this face
|
||||||
createFace (points, pos, face) {
|
createFace (points, pos, face) {
|
||||||
// Add the corresponding offsets for this face to the position
|
// Add the corresponding offsets for this face to the position
|
||||||
let corners = [
|
const corners = [
|
||||||
addv3(pos, FACE_VERTEX[face][0]), addv3(pos, FACE_VERTEX[face][1]),
|
addv3(pos, FACE_VERTEX[face][0]), addv3(pos, FACE_VERTEX[face][1]),
|
||||||
addv3(pos, FACE_VERTEX[face][2]), addv3(pos, FACE_VERTEX[face][3])
|
addv3(pos, FACE_VERTEX[face][2]), addv3(pos, FACE_VERTEX[face][3])
|
||||||
]
|
]
|
||||||
|
|
||||||
// Select the normal for this face
|
// Select the normal for this face
|
||||||
let normal = FACE_VERTEX[face][4]
|
const normal = FACE_VERTEX[face][4]
|
||||||
|
|
||||||
// Return the 6 vertices that make up this face (two triangles)
|
// Return the 6 vertices that make up this face (two triangles)
|
||||||
// They're named points because this function returns not only vertices,
|
// They're named points because this function returns not only vertices,
|
||||||
@ -200,13 +200,13 @@ class VoxelChunk extends MeshInstance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Array of vertices with texture positions and normals
|
// Array of vertices with texture positions and normals
|
||||||
let points = []
|
const points = []
|
||||||
|
|
||||||
// Generate face quads for each voxel in the chunk
|
// Generate face quads for each voxel in the chunk
|
||||||
for (let x = 0; x < this.size; x++) {
|
for (let x = 0; x < this.size; x++) {
|
||||||
for (let y = 0; y < this.size; y++) {
|
for (let y = 0; y < this.size; y++) {
|
||||||
for (let z = 0; z < this.size; z++) {
|
for (let z = 0; z < this.size; z++) {
|
||||||
let cellPos = [x, y, z]
|
const cellPos = [x, y, z]
|
||||||
if (!this.getVoxel(x, y, z).solid) continue
|
if (!this.getVoxel(x, y, z).solid) continue
|
||||||
|
|
||||||
if (!this.getVoxel(x, y - 1, z).solid) {
|
if (!this.getVoxel(x, y - 1, z).solid) {
|
||||||
@ -242,11 +242,11 @@ class VoxelChunk extends MeshInstance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Flatten the points array to three separate arrays
|
// Flatten the points array to three separate arrays
|
||||||
let vertices = []
|
const vertices = []
|
||||||
let normals = []
|
const normals = []
|
||||||
let uvs = []
|
const uvs = []
|
||||||
for (let i in points) {
|
for (const i in points) {
|
||||||
let vert = points[i]
|
const vert = points[i]
|
||||||
vertices.push(vert[0][0])
|
vertices.push(vert[0][0])
|
||||||
vertices.push(vert[0][1])
|
vertices.push(vert[0][1])
|
||||||
vertices.push(vert[0][2])
|
vertices.push(vert[0][2])
|
||||||
@ -304,7 +304,7 @@ class VoxelMapBlock extends Node {
|
|||||||
if (!this.chunks[x][z]) this.chunks[x][z] = {}
|
if (!this.chunks[x][z]) this.chunks[x][z] = {}
|
||||||
for (let y = 0; y < this.size; y++) {
|
for (let y = 0; y < this.size; y++) {
|
||||||
if (this.chunks[x][z][y]) continue
|
if (this.chunks[x][z][y]) continue
|
||||||
let chunk = new VoxelChunk(this.pos, [x, y, z], this.chunkSize)
|
const chunk = new VoxelChunk(this.pos, [x, y, z], this.chunkSize)
|
||||||
this.chunks[x][z][y] = chunk
|
this.chunks[x][z][y] = chunk
|
||||||
this.addChild(chunk)
|
this.addChild(chunk)
|
||||||
generator.pushChunk(chunk)
|
generator.pushChunk(chunk)
|
||||||
@ -315,8 +315,8 @@ class VoxelMapBlock extends Node {
|
|||||||
|
|
||||||
destroy (gl) {
|
destroy (gl) {
|
||||||
this.generated = false
|
this.generated = false
|
||||||
for (let i in this.children) {
|
for (const i in this.children) {
|
||||||
let ch = this.children[i]
|
const ch = this.children[i]
|
||||||
if (!(ch instanceof VoxelChunk)) continue
|
if (!(ch instanceof VoxelChunk)) continue
|
||||||
ch.destroy(gl)
|
ch.destroy(gl)
|
||||||
}
|
}
|
||||||
@ -326,8 +326,8 @@ class VoxelMapBlock extends Node {
|
|||||||
|
|
||||||
update (gl, dt) {
|
update (gl, dt) {
|
||||||
if (!this.generated) return false
|
if (!this.generated) return false
|
||||||
for (let i in this.children) {
|
for (const i in this.children) {
|
||||||
let ch = this.children[i]
|
const ch = this.children[i]
|
||||||
if (!(ch instanceof VoxelChunk)) continue
|
if (!(ch instanceof VoxelChunk)) continue
|
||||||
if (ch.update(gl, dt)) return true
|
if (ch.update(gl, dt)) return true
|
||||||
}
|
}
|
||||||
@ -359,19 +359,19 @@ class VoxelWorld extends Node {
|
|||||||
update (gl, cam, dt) {
|
update (gl, cam, dt) {
|
||||||
// Generate queued mapblocks before adding new ones to queue
|
// Generate queued mapblocks before adding new ones to queue
|
||||||
if (this.mapblockqueue.length) {
|
if (this.mapblockqueue.length) {
|
||||||
let leftover = []
|
const leftover = []
|
||||||
let generated = false
|
let generated = false
|
||||||
for (let i in this.mapblockqueue) {
|
for (const i in this.mapblockqueue) {
|
||||||
let pos = this.mapblockqueue[i]
|
const pos = this.mapblockqueue[i]
|
||||||
let check = this.getBlock(pos[0], pos[1], pos[2])
|
const check = this.getBlock(pos[0], pos[1], pos[2])
|
||||||
|
|
||||||
if (generated || check) {
|
if (generated || check) {
|
||||||
leftover.push(pos)
|
leftover.push(pos)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
let absPos = mulv3(pos, this.blockSize * this.chunkSize)
|
const absPos = mulv3(pos, this.blockSize * this.chunkSize)
|
||||||
let block = new VoxelMapBlock(absPos, this.chunkSize, this.blockSize)
|
const block = new VoxelMapBlock(absPos, this.chunkSize, this.blockSize)
|
||||||
block.generate(this.generator)
|
block.generate(this.generator)
|
||||||
|
|
||||||
if (!this.blocks[pos[0]]) this.blocks[pos[0]] = {}
|
if (!this.blocks[pos[0]]) this.blocks[pos[0]] = {}
|
||||||
@ -387,8 +387,8 @@ class VoxelWorld extends Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calculate a fixed grid
|
// Calculate a fixed grid
|
||||||
let total = this.blockSize * this.chunkSize
|
const total = this.blockSize * this.chunkSize
|
||||||
let slgrid = [Math.floor(cam.pos[0] / total), Math.floor(cam.pos[1] / total), Math.floor(cam.pos[2] / total)]
|
const slgrid = [Math.floor(cam.pos[0] / total), Math.floor(cam.pos[1] / total), Math.floor(cam.pos[2] / total)]
|
||||||
|
|
||||||
for (let x = slgrid[0] - this.renderDistance / 2; x < slgrid[0] + this.renderDistance / 2; x++) {
|
for (let x = slgrid[0] - this.renderDistance / 2; x < slgrid[0] + this.renderDistance / 2; x++) {
|
||||||
for (let z = slgrid[2] - this.renderDistance / 2; z < slgrid[2] + this.renderDistance / 2; z++) {
|
for (let z = slgrid[2] - this.renderDistance / 2; z < slgrid[2] + this.renderDistance / 2; z++) {
|
||||||
@ -399,7 +399,7 @@ class VoxelWorld extends Node {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i in this.children) {
|
for (const i in this.children) {
|
||||||
if (this.children[i].update(gl, dt)) break
|
if (this.children[i].update(gl, dt)) break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -425,8 +425,8 @@ class VoxelGenerator {
|
|||||||
|
|
||||||
// Generate chunks in the queue
|
// Generate chunks in the queue
|
||||||
update (dt) {
|
update (dt) {
|
||||||
for (let i in this.generateQueue) {
|
for (const i in this.generateQueue) {
|
||||||
let chunk = this.generateQueue[i]
|
const chunk = this.generateQueue[i]
|
||||||
if (chunk.generated) continue
|
if (chunk.generated) continue
|
||||||
|
|
||||||
chunk.material = this.material
|
chunk.material = this.material
|
||||||
|
44
src/index.js
44
src/index.js
@ -19,16 +19,16 @@ import Atmosphere from './engine/components/planet/atmosphere'
|
|||||||
|
|
||||||
import { CubePlanet, PlanetGenerator } from './engine/components/planet'
|
import { CubePlanet, PlanetGenerator } from './engine/components/planet'
|
||||||
|
|
||||||
let game = Engine
|
const game = Engine
|
||||||
let env = new Environment()
|
const env = new Environment()
|
||||||
let gui = new GUIRenderer()
|
const gui = new GUIRenderer()
|
||||||
let fnt = new FontRenderer()
|
const fnt = new FontRenderer()
|
||||||
let prt = new ParticleRenderer()
|
const prt = new ParticleRenderer()
|
||||||
|
|
||||||
async function pipeline () {
|
async function pipeline () {
|
||||||
let entity = await loadMesh(game.gl, 'test')
|
const entity = await loadMesh(game.gl, 'test')
|
||||||
let terrainShader = await game.shaders.createShaderFromFiles(game.gl, 'terrain', false)
|
const terrainShader = await game.shaders.createShaderFromFiles(game.gl, 'terrain', false)
|
||||||
let skyboxShader = await game.shaders.createShaderFromFiles(game.gl, 'skybox', false)
|
const skyboxShader = await game.shaders.createShaderFromFiles(game.gl, 'skybox', false)
|
||||||
// let atmosShader = await game.shaders.createShaderFromFiles(game.gl, 'atmosphere', false)
|
// let atmosShader = await game.shaders.createShaderFromFiles(game.gl, 'atmosphere', false)
|
||||||
|
|
||||||
entity.setRotation([0.0, 0.0, -90.0])
|
entity.setRotation([0.0, 0.0, -90.0])
|
||||||
@ -39,7 +39,7 @@ async function pipeline () {
|
|||||||
// await waterRenderer.initialize(game)
|
// await waterRenderer.initialize(game)
|
||||||
// await waterRenderer.useDUDVMap(game.gl, 'dudv')
|
// await waterRenderer.useDUDVMap(game.gl, 'dudv')
|
||||||
// await waterRenderer.useNormalMap(game.gl, 'normalmap')
|
// await waterRenderer.useNormalMap(game.gl, 'normalmap')
|
||||||
let arialFont = await Font.fromFile('arial')
|
const arialFont = await Font.fromFile('arial')
|
||||||
await arialFont.loadTextures(game.gl)
|
await arialFont.loadTextures(game.gl)
|
||||||
|
|
||||||
// Initialize GUI
|
// Initialize GUI
|
||||||
@ -48,12 +48,12 @@ async function pipeline () {
|
|||||||
|
|
||||||
// Initialize particles
|
// Initialize particles
|
||||||
await prt.initialize(game)
|
await prt.initialize(game)
|
||||||
let particleSystem = new ParticleSystem(prt)
|
const particleSystem = new ParticleSystem(prt)
|
||||||
|
|
||||||
// Particle texture atlas
|
// Particle texture atlas
|
||||||
let particleTexture = new ParticleTexture(await Texture.fromFile(game.gl, 'particleAtlas.png'), 4)
|
const particleTexture = new ParticleTexture(await Texture.fromFile(game.gl, 'particleAtlas.png'), 4)
|
||||||
|
|
||||||
let itms = [
|
const itms = [
|
||||||
// new GUIImage(await Texture.fromFile(game.gl, 'noisy.png', false, game.gl.LINEAR),
|
// new GUIImage(await Texture.fromFile(game.gl, 'noisy.png', false, game.gl.LINEAR),
|
||||||
// new Dim4(-0.9, 0.0, 0.9, 0.0), new Dim4(0.1, 0.0, 0.1, 0.0))
|
// new Dim4(-0.9, 0.0, 0.9, 0.0), new Dim4(0.1, 0.0, 0.1, 0.0))
|
||||||
]
|
]
|
||||||
@ -62,17 +62,17 @@ async function pipeline () {
|
|||||||
itms[0].color = [0.0, 0.2, 1.0]
|
itms[0].color = [0.0, 0.2, 1.0]
|
||||||
|
|
||||||
// Create a height map based on OpenSimplex noise
|
// Create a height map based on OpenSimplex noise
|
||||||
let hmap = new SimplexHeightMap(50, 20, 128)
|
const hmap = new SimplexHeightMap(50, 64, 64, 0.2)
|
||||||
|
|
||||||
// Create a terrain instance
|
// Create a terrain instance
|
||||||
// let terrain = new LODTerrain([0.0, 0.0, 0.0], 1024, 1024, 850, 4)
|
// let terrain = new LODTerrain([0.0, 0.0, 0.0], 1024, 1024, 850, 4)
|
||||||
|
|
||||||
// Terrain material
|
// Terrain material
|
||||||
let material = new Material(['grass-plain-1024.jpg'])
|
const material = new Material(['grass-plain-1024.jpg'])
|
||||||
await material.loadTextures(game.gl)
|
await material.loadTextures(game.gl)
|
||||||
|
|
||||||
// test code
|
// test code
|
||||||
for (let i in entity.children) {
|
for (const i in entity.children) {
|
||||||
entity.children[i].mesh.material = material
|
entity.children[i].mesh.material = material
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,11 +81,11 @@ async function pipeline () {
|
|||||||
// terrain.setMaterial(material)
|
// terrain.setMaterial(material)
|
||||||
|
|
||||||
// Create and initialize the camera
|
// Create and initialize the camera
|
||||||
let cam = new Camera([-1300.0, 1325.0, -1300.0], [0.8, -0.6, 0.0])
|
const cam = new Camera([-1300.0, 1325.0, -1300.0], [0.8, -0.6, 0.0])
|
||||||
cam.updateProjection(game.gl)
|
cam.updateProjection(game.gl)
|
||||||
|
|
||||||
// Create skybox
|
// Create skybox
|
||||||
let skybox = new Skybox('skybox', cam.farPlane / 2)
|
const skybox = new Skybox('skybox', cam.farPlane / 2)
|
||||||
|
|
||||||
// Load textures and generate a mesh
|
// Load textures and generate a mesh
|
||||||
await skybox.initialize(game.gl)
|
await skybox.initialize(game.gl)
|
||||||
@ -95,7 +95,7 @@ async function pipeline () {
|
|||||||
// let block = new VoxelWorld(voxgen)
|
// let block = new VoxelWorld(voxgen)
|
||||||
|
|
||||||
// Planet test
|
// Planet test
|
||||||
let planet = new CubePlanet([0.0, 0.0, 0.0], new PlanetGenerator(16, 1000, hmap))
|
const planet = new CubePlanet([0.0, 0.0, 0.0], new PlanetGenerator(16, 1000, hmap))
|
||||||
// let atmosphere = new Atmosphere([0.0, 0.0, 0.0], 1000, 1025, 1, [0.0, 0.0, 1.0])
|
// let atmosphere = new Atmosphere([0.0, 0.0, 0.0], 1000, 1025, 1, [0.0, 0.0, 1.0])
|
||||||
|
|
||||||
// Update function for camera and terrain
|
// Update function for camera and terrain
|
||||||
@ -122,11 +122,11 @@ async function pipeline () {
|
|||||||
particleSystem.update(dt, -50)
|
particleSystem.update(dt, -50)
|
||||||
|
|
||||||
if (game.input.isDown('y')) {
|
if (game.input.isDown('y')) {
|
||||||
let velocity = 20
|
const velocity = 20
|
||||||
for (let i = 0; i < 360; i += 15) {
|
for (let i = 0; i < 360; i += 15) {
|
||||||
let rad1 = i * Math.PI / 180
|
const rad1 = i * Math.PI / 180
|
||||||
let x1 = (Math.cos(rad1) * velocity) + randomInt(-5, 5)
|
const x1 = (Math.cos(rad1) * velocity) + randomInt(-5, 5)
|
||||||
let y1 = (Math.sin(rad1) * velocity) + randomInt(-5, 5)
|
const y1 = (Math.sin(rad1) * velocity) + randomInt(-5, 5)
|
||||||
particleSystem.add(new Particle(particleTexture, [0.0, 0.0, 0.0], [x1, randomInt(-velocity, velocity), y1], 0.2, 2, randomInt(0, 360), randomInt(0.1, 1)))
|
particleSystem.add(new Particle(particleTexture, [0.0, 0.0, 0.0], [x1, randomInt(-velocity, velocity), y1], 0.2, 2, randomInt(0, 360), randomInt(0.1, 1)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user