new standard

This commit is contained in:
Evert Prants 2020-03-31 11:15:29 +03:00
parent 9dbfb40707
commit 9db001d18f
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
23 changed files with 456 additions and 448 deletions

View File

@ -31,9 +31,9 @@ class Camera extends Node {
}
processKeyboard (direction, delta) {
let newSpeed = this.speed * delta
let velocity = vec3.fromValues(newSpeed, newSpeed, newSpeed)
let vec = vec3.create()
const newSpeed = this.speed * delta
const velocity = vec3.fromValues(newSpeed, newSpeed, newSpeed)
const vec = vec3.create()
if (direction === 0) {
vec3.multiply(vec, this.front, velocity)
@ -57,7 +57,7 @@ class Camera extends Node {
}
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[1] += glMatrix.toRadian(fst[1])
@ -81,7 +81,7 @@ class Camera extends Node {
if (!this.front || !this.worldUp) return
// 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[1] = Math.sin(this.rotation[1])
@ -91,8 +91,8 @@ class Camera extends Node {
// 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.
let rightCross = vec3.create()
let upCross = vec3.create()
const rightCross = vec3.create()
const upCross = vec3.create()
vec3.cross(rightCross, this.front, this.worldUp)
vec3.normalize(this.right, rightCross)
@ -108,8 +108,8 @@ class Camera extends Node {
// Calculate the view matrix on-the-go
// Really no advantage in storing this
get view () {
let mat = mat4.create()
let center = vec3.create()
const mat = mat4.create()
const center = vec3.create()
vec3.add(center, this.pos, this.front)
mat4.lookAt(mat, this.pos, center, this.up)
return mat

View File

@ -7,16 +7,16 @@ import { mat4, quat, vec3 } from 'gl-matrix'
* @return {vec3} out
*/
quat.getEuler = function (out, quat) {
let x = quat[0]
let y = quat[1]
let z = quat[2]
let w = quat[3]
let x2 = x * x
let y2 = y * y
let z2 = z * z
let w2 = w * w
let unit = x2 + y2 + z2 + w2
let test = x * w - y * z
const x = quat[0]
const y = quat[1]
const z = quat[2]
const w = quat[3]
const x2 = x * x
const y2 = y * y
const z2 = z * z
const w2 = w * w
const unit = x2 + y2 + z2 + w2
const test = x * w - y * z
if (test > 0.499995 * unit) {
// singularity at the north pole
out[0] = Math.PI / 2
@ -55,8 +55,8 @@ class Node {
}
updateTransform () {
let matrix = mat4.create()
let rot = quat.create()
const matrix = mat4.create()
const rot = quat.create()
// Set rotation
quat.fromEuler(rot, this.rotation[0], this.rotation[1], this.rotation[2])
@ -77,18 +77,18 @@ class Node {
this.transform = matrix
// Update children's transforms
for (let i in this.children) {
let child = this.children[i]
for (const i in this.children) {
const child = this.children[i]
if (!(child instanceof Node)) continue
child.updateTransform()
}
}
fromLocalTransform (transform) {
let quaternion = quat.create()
let translation = vec3.create()
let rotation = vec3.create()
let scale = vec3.create()
const quaternion = quat.create()
const translation = vec3.create()
const rotation = vec3.create()
const scale = vec3.create()
mat4.transpose(transform, transform)
@ -171,8 +171,8 @@ class Node {
// Draw base
draw (gl, shader) {
// Nothing to draw here, so just draw children
for (let i in this.children) {
let child = this.children[i]
for (const i in this.children) {
const child = this.children[i]
if (!(child instanceof Node)) continue
child.draw(gl, shader)
}
@ -180,8 +180,8 @@ class Node {
update (dt) {
// Update children
for (let i in this.children) {
let child = this.children[i]
for (const i in this.children) {
const child = this.children[i]
if (!(child instanceof Node)) continue
child.update(dt)
}
@ -190,7 +190,7 @@ class Node {
addChild (ch) {
// Recursive add in case of table
if (ch && typeof ch === 'object' && ch.length) {
for (let i in ch) {
for (const i in ch) {
this.addChild(ch[i])
}
}

View File

@ -31,17 +31,17 @@ class Particle {
}
_createOffset (index) {
let col = Math.floor(index % this.texture.rows)
let row = Math.floor(index / this.texture.rows)
return [ col / this.texture.rows, row / this.texture.rows ]
const col = Math.floor(index % this.texture.rows)
const row = Math.floor(index / this.texture.rows)
return [col / this.texture.rows, row / this.texture.rows]
}
_updateTexture () {
let lifeFactor = this.elapsed / this.life
let stages = this.texture.rows * this.texture.rows
let progression = lifeFactor * stages
let index1 = Math.floor(progression)
let index2 = (index1 < stages - 1) ? index1 + 1 : index1
const lifeFactor = this.elapsed / this.life
const stages = this.texture.rows * this.texture.rows
const progression = lifeFactor * stages
const index1 = Math.floor(progression)
const index2 = (index1 < stages - 1) ? index1 + 1 : index1
this.texBlend = progression % 1
this.texOffset1 = this._createOffset(index1)
this.texOffset2 = this._createOffset(index2)
@ -49,7 +49,7 @@ class Particle {
update (dt, gravity) {
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._updateTexture()
this.elapsed += dt
@ -68,10 +68,10 @@ class ParticleSystem {
}
update (dt, gravity) {
let alive = []
for (let i in this.particles) {
let particle = this.particles[i]
let stillAlive = particle.update(dt, gravity)
const alive = []
for (const i in this.particles) {
const particle = this.particles[i]
const stillAlive = particle.update(dt, gravity)
if (!stillAlive) continue
alive.push(particle)
}
@ -95,7 +95,7 @@ class ParticleRenderer {
}
createModelMatrix (shader, viewMatrix, particle) {
let modelMatrix = mat4.create()
const modelMatrix = mat4.create()
mat4.translate(modelMatrix, modelMatrix, particle.pos)
modelMatrix[0] = viewMatrix[0]
modelMatrix[1] = viewMatrix[4]
@ -112,9 +112,9 @@ class ParticleRenderer {
draw (gl, particles, cam) {
particles = (particles instanceof ParticleSystem) ? particles.particles : particles
let textures = []
for (let i in particles) {
let particle = particles[i]
const textures = []
for (const i in particles) {
const particle = particles[i]
if (textures.indexOf(particle.texture) !== -1) continue
textures.push(particle.texture)
}
@ -132,15 +132,15 @@ class ParticleRenderer {
gl.depthMask(false)
this.mesh.prepare(gl, this.shader)
for (let i in textures) {
let texture = textures[i]
for (const i in textures) {
const texture = textures[i]
gl.activeTexture(gl.TEXTURE0)
gl.bindTexture(gl.TEXTURE_2D, texture.id)
for (let j in particles) {
let particle = particles[j]
for (const j in particles) {
const particle = particles[j]
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.uniform2fv(off1Loc, particle.texOffset1)
gl.uniform2fv(off2Loc, particle.texOffset2)

View File

@ -1,5 +1,4 @@
import { Mesh } from '../../mesh'
import { BoundingBox } from '../../mesh/aabb'
import { mat4, vec3 } from 'gl-matrix'
import { subv3, mulv3, addv3, divv3, normalv3, crossv3 } from '../../utility'
import Screen from '../../screen'
@ -44,31 +43,31 @@ class CubeFace {
generate () {
if (this.generated) return
let VERTICES = this.generator.resolution
let vertices = []
let normals = []
let textureCoords = []
let indices = []
const VERTICES = this.generator.resolution
const vertices = []
const normals = []
const textureCoords = []
const indices = []
let radius = this.generator.radius
let divisionLevel = Math.pow(2, this.level)
const radius = this.generator.radius
const divisionLevel = Math.pow(2, this.level)
for (let i = 0, vertexPointer = 0; i < VERTICES; i++) {
for (let j = 0; j < VERTICES; j++, vertexPointer++) {
// Vertex index (0 - 1)
let iindex = i / (VERTICES - 1)
let jindex = j / (VERTICES - 1)
const iindex = i / (VERTICES - 1)
const jindex = j / (VERTICES - 1)
// From the left and forward vectors, we can calculate an oriented vertex
let iv = divv3(mulv3(mulv3(this.left, iindex), radius), divisionLevel)
let jv = divv3(mulv3(mulv3(this.forward, jindex), radius), divisionLevel)
const iv = divv3(mulv3(mulv3(this.left, iindex), radius), divisionLevel)
const jv = divv3(mulv3(mulv3(this.forward, jindex), radius), divisionLevel)
// 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
let normal = normalv3(vertex)
let pos = mulv3(normal, (this.generator.noise.getNoise3D(this.level + 1, normal[0], normal[1], normal[2]) + radius))
const normal = normalv3(vertex)
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 + 1] = pos[1]
@ -87,10 +86,10 @@ class CubeFace {
for (let gz = 0, pointer = 0; gz < VERTICES - 1; gz++) {
for (let gx = 0; gx < VERTICES - 1; gx++) {
let topLeft = (gz * VERTICES) + gx
let topRight = topLeft + 1
let bottomLeft = ((gz + 1) * VERTICES) + gx
let bottomRight = bottomLeft + 1
const topLeft = (gz * VERTICES) + gx
const topRight = topLeft + 1
const bottomLeft = ((gz + 1) * VERTICES) + gx
const bottomRight = bottomLeft + 1
indices[pointer++] = topLeft
indices[pointer++] = bottomLeft
indices[pointer++] = topRight
@ -100,40 +99,7 @@ class CubeFace {
}
}
// Generate normals
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]
}
}
Mesh.generateNormals(normals, indices, vertices)
this.mesh = Mesh.construct(Screen.gl, vertices, indices, textureCoords, normals)
this.generated = true
@ -150,8 +116,8 @@ class CubeFace {
merge () {
if (!this.children.length) return
for (let i in this.children) {
let ch = this.children[i]
for (const i in this.children) {
const ch = this.children[i]
ch.merge()
ch.dispose()
@ -164,14 +130,18 @@ class CubeFace {
subdivide () {
if (this.level === lodMax) return
let lv = this.level + 1
let stepLeft = mulv3(this.left, this.generator.radius / Math.pow(2, lv))
let stepForward = mulv3(this.forward, this.generator.radius / Math.pow(2, lv))
const lv = this.level + 1
const stepLeft = mulv3(this.left, this.generator.radius / Math.pow(2, lv))
const stepForward = mulv3(this.forward, this.generator.radius / Math.pow(2, lv))
this.children = [
// Bottom right corner
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),
// Bottom left corner
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)
]
@ -180,7 +150,7 @@ class CubeFace {
draw (gl, shader) {
if (!this.mesh) {
for (let i in this.children) {
for (const i in this.children) {
this.children[i].draw(gl, shader)
}
return
@ -192,9 +162,9 @@ class CubeFace {
update (camera, dt) {
if (!this.center) return
let camToOrigin = vec3.distance(camera.pos, this.center)
let divisionLevel = Math.pow(2, this.level)
let splitDistance = this.generator.radius / divisionLevel
const camToOrigin = vec3.distance(camera.pos, this.center)
const divisionLevel = Math.pow(2, this.level)
const splitDistance = this.generator.radius / divisionLevel
if (camToOrigin < splitDistance * 2 && this.children.length === 0) {
this.subdivide()
@ -205,7 +175,7 @@ class CubeFace {
}
if (this.children.length > 0) {
for (let i in this.children) {
for (const i in this.children) {
this.children[i].update(camera, dt)
}
}
@ -220,7 +190,7 @@ class CubePlanet {
this.transform = mat4.create()
mat4.fromTranslation(this.transform, origin)
let hs = generator.radius / 2
const hs = generator.radius / 2
this.faces = [
new CubeFace(this, 0, [0, 0, -hs], [0, 0, -1], generator), // front
@ -235,7 +205,7 @@ class CubePlanet {
}
update (camera, dt) {
for (let i in this.faces) {
for (const i in this.faces) {
this.faces[i].update(camera, dt)
}
}
@ -245,7 +215,7 @@ class CubePlanet {
const transformLocation = shader.getUniformLocation(gl, 'uModelMatrix')
gl.uniformMatrix4fv(transformLocation, false, this.transform)
for (let i in this.faces) {
for (const i in this.faces) {
this.faces[i].draw(gl, shader)
}
}

View File

@ -20,14 +20,14 @@ class Skybox {
}
async createTexture (gl) {
let ready = []
for (let i in FNAMES) {
let real = this.name + '/' + FNAMES[i] + '.png'
let loaded = await Resource.loadImage(real)
const ready = []
for (const i in FNAMES) {
const real = this.name + '/' + FNAMES[i] + '.png'
const loaded = await Resource.loadImage(real)
ready[i] = loaded
}
let imgCube = Texture.createTextureCubeMap(gl, ready)
const imgCube = Texture.createTextureCubeMap(gl, ready)
this.cubemap = imgCube
}
@ -83,7 +83,7 @@ class Skybox {
const viewloc = shader.getUniformLocation(gl, 'uViewMatrix')
// 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[13] = 0
view[14] = 0

View File

@ -12,12 +12,12 @@ class Terrain extends Node {
}
createMesh (gl, heightMap) {
let VERTICES = heightMap.size
let count = VERTICES * VERTICES
let vertices = new Array(count * 3)
let normals = new Array(count * 3)
let textureCoords = new Array(count * 2)
let indices = new Array(6 * (VERTICES - 1) * (VERTICES - 1))
const VERTICES = heightMap.size
const count = VERTICES * VERTICES
const vertices = new Array(count * 3)
const normals = new Array(count * 3)
const textureCoords = new Array(count * 2)
const indices = new Array(6 * (VERTICES - 1) * (VERTICES - 1))
let vertexPointer = 0
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 + 1] = heightMap.getHeight(j, i)
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 + 1] = normal[1]
normals[vertexPointer * 3 + 2] = normal[2]
@ -38,10 +38,10 @@ class Terrain extends Node {
let pointer = 0
for (let gz = 0; gz < VERTICES - 1; gz++) {
for (let gx = 0; gx < VERTICES - 1; gx++) {
let topLeft = (gz * VERTICES) + gx
let topRight = topLeft + 1
let bottomLeft = ((gz + 1) * VERTICES) + gx
let bottomRight = bottomLeft + 1
const topLeft = (gz * VERTICES) + gx
const topRight = topLeft + 1
const bottomLeft = ((gz + 1) * VERTICES) + gx
const bottomRight = bottomLeft + 1
indices[pointer++] = topLeft
indices[pointer++] = bottomLeft
indices[pointer++] = topRight

View File

@ -8,10 +8,10 @@ class HeightMap {
}
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.')
let hmap = new HeightMap(img.width)
const hmap = new HeightMap(img.width)
let sampler = Resource.imageToSampler(img)
for (let x = 0; x < img.width; x++) {
@ -32,11 +32,11 @@ class HeightMap {
}
getNormal (x, y) {
let hL = this.getHeight(x - 1, y)
let hR = this.getHeight(x + 1, y)
let hD = this.getHeight(x, y - 1)
let hU = this.getHeight(x, y + 1)
let normal = vec3.fromValues(hL - hR, 2.0, hD - hU)
const hL = this.getHeight(x - 1, y)
const hR = this.getHeight(x + 1, y)
const hD = this.getHeight(x, y - 1)
const hU = this.getHeight(x, y + 1)
const normal = vec3.fromValues(hL - hR, 2.0, hD - hU)
vec3.normalize(normal, normal)
return normal
}

View File

@ -20,9 +20,9 @@ class TerrainNode extends Node {
// If this mesh has children (we're a branch), generate their meshes instead
if (this.children.length) {
let generated = 0
for (let i in this.children) {
for (const i in this.children) {
if (generated >= this.root.genPerTick) break
let child = this.children[i]
const child = this.children[i]
if (!(child instanceof TerrainNode)) continue
generated += this.children[i].updateLODMesh(gl)
}
@ -32,31 +32,31 @@ class TerrainNode extends Node {
// If we already have a mesh, we can skip
if (this.mesh) return 0
let VERTICES = this.root.resolution
let count = VERTICES * VERTICES
let vertices = new Array(count * 3)
let normals = new Array(count * 3)
let textureCoords = new Array(count * 2)
let indices = new Array(6 * (VERTICES - 1) * (VERTICES - 1))
const VERTICES = this.root.resolution
const count = VERTICES * VERTICES
const vertices = new Array(count * 3)
const normals = new Array(count * 3)
const textureCoords = new Array(count * 2)
const indices = new Array(6 * (VERTICES - 1) * (VERTICES - 1))
let vertexPointer = 0
let divisionLevel = Math.pow(2, this.level)
const divisionLevel = Math.pow(2, this.level)
// Create vertices dynamically
for (let i = 0; i < VERTICES; i++) {
for (let j = 0; j < VERTICES; j++) {
let vertDivj = j / (VERTICES - 1)
let vertDivi = i / (VERTICES - 1)
const vertDivj = j / (VERTICES - 1)
const vertDivi = i / (VERTICES - 1)
// Calculate relative resolution
let pj = vertDivj * this.root.width / divisionLevel
let pi = vertDivi * this.root.height / divisionLevel
const pj = vertDivj * this.root.width / divisionLevel
const pi = vertDivi * this.root.height / divisionLevel
// Generator takes meshes' absolute vertex position in the world when using height values
vertices[vertexPointer * 3] = pj
vertices[vertexPointer * 3 + 1] = this.root.generator.getHeightPlaneMesh(this, pj, pi, true)
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 + 1] = normal[1]
normals[vertexPointer * 3 + 2] = normal[2]
@ -70,10 +70,10 @@ class TerrainNode extends Node {
let pointer = 0
for (let gz = 0; gz < VERTICES - 1; gz++) {
for (let gx = 0; gx < VERTICES - 1; gx++) {
let topLeft = (gz * VERTICES) + gx
let topRight = topLeft + 1
let bottomLeft = ((gz + 1) * VERTICES) + gx
let bottomRight = bottomLeft + 1
const topLeft = (gz * VERTICES) + gx
const topRight = topLeft + 1
const bottomLeft = ((gz + 1) * VERTICES) + gx
const bottomRight = bottomLeft + 1
indices[pointer++] = topLeft
indices[pointer++] = bottomLeft
indices[pointer++] = topRight
@ -123,7 +123,7 @@ class TerrainNode extends Node {
if (this.children.length === 0) return
// 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].dispose(gl)
}
@ -135,10 +135,10 @@ class TerrainNode extends Node {
subdivide () {
// Do not divide when we're already at the limit
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)
let stepForward = this.root.height / Math.pow(2, lv)
const stepLeft = this.root.width / Math.pow(2, lv)
const stepForward = this.root.height / Math.pow(2, lv)
// Child nodes take relative positions because they are parented
this.addChild(new TerrainNode(this.root, [0, 0, 0], lv))
@ -152,10 +152,10 @@ class TerrainNode extends Node {
if (!this.bounds) return false
// Get camera distance from the center of this mesh
// 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
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.children.length) {
@ -167,8 +167,8 @@ class TerrainNode extends Node {
// Update the children
let acted = false
for (let i in this.children) {
let child = this.children[i]
for (const i in this.children) {
const child = this.children[i]
acted = child.update(gl, camera)
}
return acted
@ -217,9 +217,9 @@ class LODTerrain extends Node {
updateLODMesh (gl) {
// Ensure only genPerTick mesh(es) is/are generated every tick
let generated = 0
for (let i in this.children) {
for (const i in this.children) {
if (generated >= this.genPerTick) break
let child = this.children[i]
const child = this.children[i]
if (!(child instanceof TerrainNode)) continue
generated += this.children[i].updateLODMesh(gl)
}
@ -230,9 +230,9 @@ class LODTerrain extends Node {
update (gl, camera) {
// Ensure only one mesh update per tick
let acted = false
for (let i in this.children) {
for (const i in this.children) {
if (acted) break
let child = this.children[i]
const child = this.children[i]
acted = child.update(gl, camera)
}
return acted

View File

@ -32,7 +32,7 @@ class WaterFBOs {
createFrameBuffer (gl) {
// generate frame buffer
let frameBuffer = gl.createFramebuffer()
const frameBuffer = gl.createFramebuffer()
// create the framebuffer
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer)
// indicate that we will always render to color attachment 0
@ -62,7 +62,7 @@ class WaterFBOs {
}
createTextureAttachment (gl, width, height) {
let texture = gl.createTexture()
const texture = gl.createTexture()
gl.bindTexture(gl.TEXTURE_2D, texture)
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)
@ -74,7 +74,7 @@ class WaterFBOs {
}
createDepthTextureAttachment (gl, width, height) {
let texture = gl.createTexture()
const texture = gl.createTexture()
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.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
@ -86,7 +86,7 @@ class WaterFBOs {
}
createDepthBufferAttachment (gl, width, height) {
let depthBuffer = gl.createRenderbuffer()
const depthBuffer = gl.createRenderbuffer()
gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer)
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height)
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthBuffer)
@ -124,7 +124,7 @@ class WaterRenderer {
reflect (gl, cam, render) {
this.fbos.bindReflectionFrameBuffer(gl)
let dist = 2 * cam.pos[1]
const dist = 2 * cam.pos[1]
cam.pos[1] -= dist
cam.rotation[1] *= -1
cam.updateTransform()
@ -212,7 +212,7 @@ class WaterRenderer {
// Render a mesh at every tile location
this.mesh.prepare(gl, this.shader)
for (let i in waters) {
for (const i in waters) {
const transformLoc = this.shader.getUniformLocation(gl, 'uModelMatrix')
gl.uniformMatrix4fv(transformLoc, false, waters[i].transform)

View File

@ -43,7 +43,7 @@ class Environment {
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.lights = [ this.sun ]
this.lights = [this.sun]
this.maxEnvironmentLights = ENV_MAX_LIGHTS
}
@ -82,9 +82,9 @@ class Environment {
draw (gl, shader) {
for (let i = 0; i < this.maxEnvironmentLights; i++) {
let lightColor = shader.getUniformLocation(gl, 'lightColor[' + i + ']')
let lightPosition = shader.getUniformLocation(gl, 'lightPosition[' + i + ']')
let lightAttn = shader.getUniformLocation(gl, 'attenuation[' + i + ']')
const lightColor = shader.getUniformLocation(gl, 'lightColor[' + i + ']')
const lightPosition = shader.getUniformLocation(gl, 'lightPosition[' + i + ']')
const lightAttn = shader.getUniformLocation(gl, 'attenuation[' + i + ']')
if (this.lights[i]) {
gl.uniform3fv(lightColor, this.lights[i].color)

View File

@ -82,9 +82,9 @@ class FontFile {
}
getValues (vals, key) {
let nums = vals[key].split(NUMBER_SEPARATOR)
let result = []
for (let i in nums) {
const nums = vals[key].split(NUMBER_SEPARATOR)
const result = []
for (const i in nums) {
result.push(parseInt(nums[i]))
}
return result
@ -92,14 +92,14 @@ class FontFile {
// Parse a .fnt file
readValues (data) {
let lines = data.split('\n')
for (let i in lines) {
let line = lines[i]
let lineSplit = line.split(SPLITTER)
let lineValues = {}
const lines = data.split('\n')
for (const i in lines) {
const line = lines[i]
const lineSplit = line.split(SPLITTER)
const lineValues = {}
for (let j in lineSplit) {
let valuePairs = lineSplit[j].split('=')
for (const j in lineSplit) {
const valuePairs = lineSplit[j].split('=')
if (valuePairs.length === 2) {
lineValues[valuePairs[0]] = valuePairs[1]
}
@ -110,34 +110,34 @@ class FontFile {
this.paddingWidth = this.padding[PAD_LEFT] + this.padding[PAD_RIGHT]
this.paddingHeight = this.padding[PAD_TOP] + this.padding[PAD_BOTTOM]
} 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.horizPixelSize = this.vertPerPixelSize / Screen.aspectRatio
this.scaleWidth = this.getValue(lineValues, 'scaleW')
} 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
}
}
}
loadCharacter (values, imageSize) {
let id = this.getValue(values, 'id')
const id = this.getValue(values, 'id')
if (id === SPACE_ASCII) {
this.spaceWidth = (this.getValue(values, 'xadvance') - this.paddingWidth) * this.horizPixelSize
return null
}
let 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
let width = this.getValue(values, 'width') - (this.paddingWidth - (2 * DESIRED_PADDING))
let height = this.getValue(values, 'height') - ((this.paddingHeight) - (2 * DESIRED_PADDING))
let quadWidth = width * this.horizPixelSize
let quadHeight = height * this.vertPerPixelSize
let xTexSize = width / imageSize
let yTexSize = height / imageSize
let 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
let xAdvance = (this.getValue(values, 'xadvance') - this.paddingWidth) * this.horizPixelSize
const xTex = (this.getValue(values, 'x') + (this.padding[PAD_LEFT] - DESIRED_PADDING)) / imageSize
const yTex = (this.getValue(values, 'y') + (this.padding[PAD_TOP] - DESIRED_PADDING)) / imageSize
const width = this.getValue(values, 'width') - (this.paddingWidth - (2 * DESIRED_PADDING))
const height = this.getValue(values, 'height') - ((this.paddingHeight) - (2 * DESIRED_PADDING))
const quadWidth = width * this.horizPixelSize
const quadHeight = height * this.vertPerPixelSize
const xTexSize = width / imageSize
const yTexSize = height / imageSize
const xOff = (this.getValue(values, 'xoffset') + this.padding[PAD_LEFT] - DESIRED_PADDING) * this.horizPixelSize
const yOff = (this.getValue(values, 'yoffset') + (this.padding[PAD_TOP] - DESIRED_PADDING)) * this.vertPerPixelSize
const xAdvance = (this.getValue(values, 'xadvance') - this.paddingWidth) * this.horizPixelSize
return new Character(id, xTex, yTex, xTexSize, yTexSize, xOff, yOff, quadWidth, quadHeight, xAdvance)
}
@ -146,8 +146,8 @@ class FontFile {
}
static async fromFile (fontName) {
let load = await Resource.GET('/assets/fonts/' + fontName + '.fnt')
let file = new FontFile(fontName)
const load = await Resource.GET('/assets/fonts/' + fontName + '.fnt')
const file = new FontFile(fontName)
file.readValues(load)
return file
}
@ -162,7 +162,7 @@ class Font {
// Load font data from a .fnt file and create a Font object with it
static async fromFile (name) {
let meta = await FontFile.fromFile(name)
const meta = await FontFile.fromFile(name)
return new Font(name, meta)
}
@ -173,21 +173,21 @@ class Font {
// Create a renderable mesh for a text
createTextMesh (gl, text) {
let lines = this.createStructure(text)
let data = this.createQuadVertices(text, lines)
const lines = this.createStructure(text)
const data = this.createQuadVertices(text, lines)
return Mesh.constructFromVerticesUVs(gl, data.vertices, data.textureCoords)
}
// Create a structure of lines, words and characters in order to generate the vertices properly
createStructure (text) {
let chars = text.asCharacters
let lines = []
const chars = text.asCharacters
const lines = []
let currentLine = new Line(this.metadata.spaceWidth, text.fontSize, text.lineLength)
let currentWord = new Word(text.fontSize)
for (let c in chars) {
let ascii = parseInt(chars[c])
for (const c in chars) {
const ascii = parseInt(chars[c])
if (ascii === SPACE_ASCII) {
let added = currentLine.attemptToAddWord(currentWord)
const added = currentLine.attemptToAddWord(currentWord)
if (!added) {
lines.push(currentLine)
currentLine = new Line(this.metadata.spaceWidth, text.fontSize, text.lineLength)
@ -198,7 +198,7 @@ class Font {
}
if (ascii === NL_ASCII) {
let added = currentLine.attemptToAddWord(currentWord)
const added = currentLine.attemptToAddWord(currentWord)
if (!added) {
lines.push(currentLine)
currentLine = new Line(this.metadata.spaceWidth, text.fontSize, text.lineLength)
@ -210,7 +210,7 @@ class Font {
continue
}
let character = this.metadata.getCharacter(ascii)
const character = this.metadata.getCharacter(ascii)
currentWord.addCharacter(character)
}
this.completeStructure(lines, currentLine, currentWord, text)
@ -219,7 +219,7 @@ class Font {
// Add final word
completeStructure (lines, currentLine, currentWord, text) {
let added = currentLine.attemptToAddWord(currentWord)
const added = currentLine.attemptToAddWord(currentWord)
if (!added) {
lines.push(currentLine)
currentLine = new Line(this.metadata.spaceWidth, text.fontSize, text.lineLength)
@ -234,17 +234,17 @@ class Font {
text.lines = lines.length
let cursorX = 0
let cursorY = 0
let vertices = []
let textureCoords = []
for (let i in lines) {
let line = lines[i]
const vertices = []
const textureCoords = []
for (const i in lines) {
const line = lines[i]
if (text.centered) {
cursorX = (line.maxLength - line.lineLength) / 2
}
for (let j in line.words) {
let word = line.words[j]
for (let k in word.characters) {
let letter = word.characters[k]
for (const j in line.words) {
const word = line.words[j]
for (const k in word.characters) {
const letter = word.characters[k]
this.addVerticesForCharacter(cursorX, cursorY, letter, text.fontSize, vertices)
this.addTexCoords(textureCoords, letter.xTexCoord, letter.yTexCoord, letter.xMaxTexCoord, letter.yMaxTexCoord)
cursorX += letter.xAdvance * text.fontSize
@ -259,14 +259,14 @@ class Font {
// Create text vertex coordinates for a specific character
addVerticesForCharacter (cursorX, cursorY, character, fontSize, vertices) {
let x = cursorX + (character.xOffset * fontSize)
let y = cursorY + (character.yOffset * fontSize)
let maxX = x + (character.sizeX * fontSize)
let maxY = y + (character.sizeY * fontSize)
let properX = (2 * x) - 1
let properY = (-2 * y) + 1
let properMaxX = (2 * maxX) - 1
let properMaxY = (-2 * maxY) + 1
const x = cursorX + (character.xOffset * fontSize)
const y = cursorY + (character.yOffset * fontSize)
const maxX = x + (character.sizeX * fontSize)
const maxY = y + (character.sizeY * fontSize)
const properX = (2 * x) - 1
const properY = (-2 * y) + 1
const properMaxX = (2 * maxX) - 1
const properMaxY = (-2 * maxY) + 1
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
updateTransform () {
let matrix = mat4.create()
const matrix = mat4.create()
mat4.translate(matrix, matrix, [this.pos[0], this.pos[2], 0.0])
if (this.rotation !== 0.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
// Update children's transforms
for (let i in this.children) {
let child = this.children[i]
for (const i in this.children) {
const child = this.children[i]
if (!(child instanceof Node2D)) continue
child.updateTransform()
}
@ -363,7 +363,7 @@ class GUIText extends Node2D {
// Return all characters as their ascii code
get asCharacters () {
let chars = []
const chars = []
for (let i = 0; i < this.text.length; i++) {
chars.push(this.text.charCodeAt(i))
}
@ -404,8 +404,8 @@ class GUIText extends Node2D {
class FontRenderer {
discoverTextNodes (nodes) {
let textNodes = []
for (let i in nodes) {
let node = nodes[i]
for (const i in nodes) {
const node = nodes[i]
if (!(node instanceof GUIText)) {
if (node.children.length) {
textNodes = textNodes.concat(this.discoverTextNodes(node.children))
@ -419,10 +419,10 @@ class FontRenderer {
draw (gl, cam, nodes) {
// Discover all nodes in the array that are texts
let fontPairs = {}
let textNodes = this.discoverTextNodes(nodes)
for (let i in textNodes) {
let node = textNodes[i]
const fontPairs = {}
const textNodes = this.discoverTextNodes(nodes)
for (const i in textNodes) {
const node = textNodes[i]
if (!this.fonts) {
this.fonts = {}
}
@ -443,15 +443,15 @@ class FontRenderer {
gl.enable(gl.BLEND)
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
gl.disable(gl.DEPTH_TEST)
for (let i in fontPairs) {
let texts = fontPairs[i]
let font = this.fonts[i]
for (const i in fontPairs) {
const texts = fontPairs[i]
const font = this.fonts[i]
// Set font's map as the texture
gl.activeTexture(gl.TEXTURE0)
gl.bindTexture(font.texture.type, font.texture.id)
// Draw all texts
for (let j in texts) {
let text = texts[j]
for (const j in texts) {
const text = texts[j]
text.draw(gl, this.shader)
}
}

View File

@ -36,8 +36,8 @@ class Dim4 {
let sy = 0.0
let oy = 0.0
if (tbl.length === 2) {
let x = tbl[0]
let y = tbl[1]
const x = tbl[0]
const y = tbl[1]
if (typeof x === 'object' && x.length === 2) {
sx = x[0]
@ -95,7 +95,7 @@ class Node2D {
}
updateTransform () {
let matrix = mat4.create()
const matrix = mat4.create()
mat4.translate(matrix, matrix, [this.pos[0], this.pos[2], 0.0])
mat4.scale(matrix, matrix, [this.size[0], this.size[2], 1.0])
if (this.rotation !== 0.0) {
@ -111,8 +111,8 @@ class Node2D {
this.transform = matrix
// Update children's transforms
for (let i in this.children) {
let child = this.children[i]
for (const i in this.children) {
const child = this.children[i]
if (!(child instanceof Node2D)) continue
child.updateTransform()
}
@ -130,8 +130,8 @@ class Node2D {
// Draw base
draw (gl, shader, quad) {
// Nothing to draw here, so just draw children
for (let i in this.children) {
let child = this.children[i]
for (const i in this.children) {
const child = this.children[i]
if (!(child instanceof Node2D)) continue
child.draw(gl, shader, quad)
}
@ -139,8 +139,8 @@ class Node2D {
update (dt) {
// Update children
for (let i in this.children) {
let child = this.children[i]
for (const i in this.children) {
const child = this.children[i]
if (!(child instanceof Node2D)) continue
child.update(dt)
}
@ -149,7 +149,7 @@ class Node2D {
addChild (ch) {
// Recursive add in case of table
if (ch && typeof ch === 'object' && ch.length) {
for (let i in ch) {
for (const i in ch) {
this.addChild(ch[i])
}
}
@ -204,13 +204,13 @@ class GUIRenderer {
}
draw (gl, cam, nodes) {
if (typeof nodes !== 'object') nodes = [ nodes ]
if (typeof nodes !== 'object') nodes = [nodes]
this.shader.use(gl)
this.quad.prepare(gl, this.shader)
gl.enable(gl.BLEND)
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
gl.disable(gl.DEPTH_TEST)
for (let i in nodes) {
for (const i in nodes) {
nodes[i].draw(gl, this.shader, this.quad)
}
gl.enable(gl.DEPTH_TEST)

View File

@ -52,14 +52,14 @@ class Engine {
render () {
// Render functions
for (let i in this.rst) {
for (const i in this.rst) {
this.rst[i](gl)
}
}
update (dt) {
// Updates
for (let i in this.ust) {
for (const i in this.ust) {
this.ust[i](dt)
}
@ -71,8 +71,8 @@ class Engine {
this.render(this.gl)
let ts = performance.now()
let timeDiff = ts - this.frameTime // time difference in milliseconds
const ts = performance.now()
const timeDiff = ts - this.frameTime // time difference in milliseconds
this.frameCount++
if (timeDiff > 0) {

View File

@ -1,65 +1,65 @@
const specialKeyMap = {
'backspace': 8,
'tab': 9,
'enter': 13,
'shift': 16,
'ctrl': 17,
'alt': 18,
'pausebreak': 19,
'capslock': 20,
'escape': 27,
'pgup': 33,
'pgdown': 34,
'end': 35,
'home': 36,
'left': 37,
'up': 38,
'right': 39,
'down': 40,
'insert': 45,
'delete': 46,
backspace: 8,
tab: 9,
enter: 13,
shift: 16,
ctrl: 17,
alt: 18,
pausebreak: 19,
capslock: 20,
escape: 27,
pgup: 33,
pgdown: 34,
end: 35,
home: 36,
left: 37,
up: 38,
right: 39,
down: 40,
insert: 45,
delete: 46,
'left-window': 91,
'right-window': 92,
'select': 93,
'numpad0': 96,
'numpad1': 97,
'numpad2': 98,
'numpad3': 99,
'numpad4': 100,
'numpad5': 101,
'numpad6': 102,
'numpad7': 103,
'numpad8': 104,
'numpad9': 105,
'multiply': 106,
'add': 107,
'subtract': 109,
'decimal': 110,
'divide': 111,
'f1': 112,
'f2': 113,
'f3': 114,
'f4': 115,
'f5': 116,
'f6': 117,
'f7': 118,
'f8': 119,
'f9': 120,
'f10': 121,
'f11': 122,
'f12': 123,
'numlock': 144,
'scrolllock': 145,
select: 93,
numpad0: 96,
numpad1: 97,
numpad2: 98,
numpad3: 99,
numpad4: 100,
numpad5: 101,
numpad6: 102,
numpad7: 103,
numpad8: 104,
numpad9: 105,
multiply: 106,
add: 107,
subtract: 109,
decimal: 110,
divide: 111,
f1: 112,
f2: 113,
f3: 114,
f4: 115,
f5: 116,
f6: 117,
f7: 118,
f8: 119,
f9: 120,
f10: 121,
f11: 122,
f12: 123,
numlock: 144,
scrolllock: 145,
'semi-colon': 186,
'equals': 187,
'comma': 188,
'dash': 189,
'period': 190,
'fwdslash': 191,
'grave': 192,
equals: 187,
comma: 188,
dash: 189,
period: 190,
fwdslash: 191,
grave: 192,
'open-bracket': 219,
'bkslash': 220,
bkslash: 220,
'close-braket': 221,
'single-quote': 222
}
@ -84,7 +84,7 @@ class Input {
let y
if (e.changedTouches) {
let touch = e.changedTouches[0]
const touch = e.changedTouches[0]
if (touch) {
e.pageX = touch.pageX
e.pageY = touch.pageY
@ -140,8 +140,8 @@ class Input {
toggleKey (keyCode, on) {
// Find key in special key list
let key = null
for (let k in specialKeyMap) {
let val = specialKeyMap[k]
for (const k in specialKeyMap) {
const val = specialKeyMap[k]
if (keyCode === val) {
key = k
break
@ -202,7 +202,7 @@ class Input {
update () {
this.previousKeyList = {}
for (let k in this.keyList) {
for (const k in this.keyList) {
if (this.keyList[k] === true) {
this.previousKeyList[k] = true
}

View File

@ -7,10 +7,10 @@ class BoundingBox {
}
static fromMesh (mesh) {
let min = [0, 0, 0]
let max = [0, 0, 0]
const min = [0, 0, 0]
const max = [0, 0, 0]
for (let v = 0; v < mesh.vertices.length; v += 3) {
let vertex = [mesh.vertices[v], mesh.vertices[v + 1], mesh.vertices[v + 2]]
const vertex = [mesh.vertices[v], mesh.vertices[v + 1], mesh.vertices[v + 2]]
// X
if (vertex[0] > max[0]) max[0] = vertex[0]
if (vertex[0] < min[0]) min[0] = vertex[0]

View File

@ -1,7 +1,8 @@
import { subv3, normalv3, crossv3 } from '../utility'
class Mesh {
static loadToBuffer (gl, type, data, drawtype = gl.STATIC_DRAW) {
let id = gl.createBuffer()
const id = gl.createBuffer()
gl.bindBuffer(type, id)
gl.bufferData(type, data, drawtype)
return id
@ -9,16 +10,16 @@ class Mesh {
static construct (gl, vertices, indices, uvs, normals) {
// 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
let mesh = new Mesh()
const mesh = new Mesh()
mesh.posBuffer = pos
mesh.vertices = vertices
// Indices Buffer (EBO)
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.indices = indices
} else {
@ -44,8 +45,8 @@ class Mesh {
}
static constructFromVertices (gl, vertices, dimensions = 3) {
let pos = Mesh.loadToBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(vertices))
let mesh = new Mesh()
const pos = Mesh.loadToBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(vertices))
const mesh = new Mesh()
mesh.posBuffer = pos
mesh.vertices = vertices
mesh.vertexCount = vertices.length / dimensions
@ -56,8 +57,8 @@ class Mesh {
}
static constructFromVerticesUVs (gl, vertices, uvs, dimensions = 2) {
let pos = Mesh.loadToBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(vertices))
let mesh = new Mesh()
const pos = Mesh.loadToBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(vertices))
const mesh = new Mesh()
mesh.uv = uvs
mesh.posBuffer = pos
mesh.vertices = vertices
@ -69,10 +70,47 @@ class 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) {
this._bufferCount = 1
let d = this.vertexLayout || 3
const d = this.vertexLayout || 3
gl.bindBuffer(gl.ARRAY_BUFFER, this.posBuffer)
shader.setAttribute(gl, 'aVertexPosition', d, false, d * Float32Array.BYTES_PER_ELEMENT, 0)
@ -129,7 +167,7 @@ class Mesh {
}
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
this.dispose(gl)
return msh

View File

@ -6,15 +6,15 @@ import { mat4 } from 'gl-matrix'
import Resource from '../resource'
let meshCache = {}
const meshCache = {}
// Parse an assimp2json formatted mesh file
// Supports multiple geometries
async function assimp2json (gl, file, dat) {
let cleaned = []
let materials = []
for (let mi in dat.meshes) {
let mesh = dat.meshes[mi]
const cleaned = []
const materials = []
for (const mi in dat.meshes) {
const mesh = dat.meshes[mi]
let material
if (mesh.materialindex != null && dat.materials && dat.materials.length) {
@ -24,15 +24,15 @@ async function assimp2json (gl, file, dat) {
} else {
// Load a new material
material = new Material()
let matdata = dat.materials[mesh.materialindex].properties
const matdata = dat.materials[mesh.materialindex].properties
// Parse material information
for (let pi in matdata) {
let property = matdata[pi]
for (const pi in matdata) {
const property = matdata[pi]
if (!property || !property.key) continue
if (property.key === '?mat.name') material.name = property.value
else if (property.key.indexOf('$clr.') === 0) {
let dproperty = property.key.substr(5)
const dproperty = property.key.substr(5)
switch (dproperty) {
case 'specular':
case 'diffuse':
@ -65,10 +65,10 @@ async function assimp2json (gl, file, dat) {
}
// Load everything
let loadComplete = []
for (let i in cleaned) {
let meshdata = cleaned[i]
let mesh = Mesh.construct(gl, meshdata.vertices, meshdata.indices,
const loadComplete = []
for (const i in cleaned) {
const meshdata = cleaned[i]
const mesh = Mesh.construct(gl, meshdata.vertices, meshdata.indices,
meshdata.uv, meshdata.normals)
// Initialize the material's texture if present
@ -84,12 +84,12 @@ async function assimp2json (gl, file, dat) {
loadComplete.push(mesh)
}
let finished = []
let lastTransform = dat.rootnode.transformation
const finished = []
const lastTransform = dat.rootnode.transformation
function setChildren (parent, chMeshes, last) {
if (!chMeshes.meshes) {
if (chMeshes.children) {
for (let j in chMeshes.children) {
for (const j in chMeshes.children) {
setChildren(null, chMeshes.children[j], chMeshes)
}
}
@ -97,16 +97,16 @@ async function assimp2json (gl, file, dat) {
}
// Transpose the mesh's transform
let transform = chMeshes.transformation
const transform = chMeshes.transformation
let meshIndex = chMeshes.meshes[0]
let mesh = loadComplete[meshIndex]
let meshInstance = new MeshInstance(mesh)
const meshIndex = chMeshes.meshes[0]
const mesh = loadComplete[meshIndex]
const meshInstance = new MeshInstance(mesh)
meshInstance.mesh = mesh
if (chMeshes.children) {
for (let i in chMeshes.children) {
for (const i in chMeshes.children) {
if (!chMeshes.children[i].meshes) continue
setChildren(meshInstance, chMeshes.children[i], chMeshes)
}
@ -158,15 +158,15 @@ async function loadMesh (gl, file) {
// Ensure each mesh file is loaded only once
if (meshCache[file]) {
if (meshCache[file].length <= 1) return meshCache[file][0]
let cached = new Node()
const cached = new Node()
cached.addChild(meshCache[file])
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
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)
return assimp2json(gl, file, dat)
}

View File

@ -2,12 +2,12 @@ import Resource from '../resource'
class Texture {
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)
}
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.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flip)
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)
let oTex = new Texture()
const oTex = new Texture()
oTex.type = gl.TEXTURE_2D
oTex.id = tex
@ -33,7 +33,7 @@ class Texture {
static createTextureCubeMap (gl, img) {
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.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false)
@ -50,7 +50,7 @@ class Texture {
gl.bindTexture(gl.TEXTURE_CUBE_MAP, null)
let oTex = new Texture()
const oTex = new Texture()
oTex.type = gl.TEXTURE_CUBE_MAP
oTex.id = tex
@ -65,10 +65,10 @@ class Material {
async loadTextures (gl) {
if (this.textures) {
for (let ti in this.textures) {
let tex = this.textures[ti]
for (const ti in this.textures) {
const tex = this.textures[ti]
if (!(tex instanceof Texture)) {
let result = await Texture.fromFile(gl, tex, true)
const result = await Texture.fromFile(gl, tex, true)
this.textures[ti] = result
}
}
@ -80,8 +80,8 @@ class Material {
// Load textures
if (!this.textures || !this.textures.length) return
for (let i in this.textures) {
let tex = this.textures[i]
for (const i in this.textures) {
const tex = this.textures[i]
if (tex && tex instanceof Texture) {
gl.activeTexture(gl.TEXTURE0 + parseInt(i))
gl.bindTexture(tex.type, tex.id)

View File

@ -1,13 +1,13 @@
/* global XMLHttpRequest, Image */
let imgCache = {}
const imgCache = {}
// Find the assets directory properly
function fixURI (path, a = '') {
let pn = window.location.pathname
const pn = window.location.pathname
if (path.indexOf('/assets') === -1) path = '/assets/' + a + path
if (pn === '/' || pn === '/index.html') return path
let assetsDir = pn + path
const assetsDir = pn + path
return assetsDir.replace(/\/\//g, '/')
}
@ -19,7 +19,7 @@ function GET (url, istext) {
if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
resolve(xmlHttp.responseText)
} else if (xmlHttp.readyState === 4 && xmlHttp.status >= 400) {
let err = new Error(xmlHttp.status)
const err = new Error(xmlHttp.status)
err.request = xmlHttp
reject(err)
}
@ -40,16 +40,16 @@ function smartGET (data) {
}
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 (data.type === 'json') {
return new Promise((resolve, reject) => {
GET(url).then((dtext) => {
try {
let jsonp = JSON.parse(dtext)
const jsonp = JSON.parse(dtext)
return resolve(jsonp)
} catch (e) {
reject(e)
@ -68,7 +68,7 @@ function loadImage (url) {
if (imgCache[url]) return imgCache[url]
return new Promise((resolve, reject) => {
let img = new Image()
const img = new Image()
img.onload = function () {
imgCache[url] = img
@ -84,8 +84,8 @@ function loadImage (url) {
}
function imageToSampler (img) {
let canvas = document.createElement('canvas')
let ctx = canvas.getContext('2d')
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
canvas.width = img.width
canvas.height = img.height
ctx.drawImage(img, 0, 0, img.width, img.height)

View File

@ -18,7 +18,7 @@ class Shader {
// See if it compiled successfully
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
let inf = gl.getShaderInfoLog(shader)
const inf = gl.getShaderInfoLog(shader)
gl.deleteShader(shader)
throw new Error('An error occurred compiling the shaders: ' + inf)
}
@ -43,9 +43,9 @@ class ShaderProgram {
}
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)
}
@ -79,7 +79,7 @@ class ShaderProgram {
getUniformLocation (gl, 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
this.uniforms[name] = uni
@ -88,7 +88,7 @@ class ShaderProgram {
getAttributeLocation (gl, 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}!`)
this.attribs[name] = pos
return pos
@ -104,7 +104,7 @@ class ShaderProgram {
}
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.vertexAttribPointer(
@ -129,11 +129,11 @@ class ShaderManager {
createShader (gl, name, vs, fs, gs) {
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)
let frag = new Shader(gl.FRAGMENT_SHADER, fs)
let geom = gs ? new Shader(gl.GEOMETRY_SHADER, gs) : null
const vert = new Shader(gl.VERTEX_SHADER, vs)
const frag = new Shader(gl.FRAGMENT_SHADER, fs)
const geom = gs ? new Shader(gl.GEOMETRY_SHADER, gs) : null
shader.link(gl, vert, frag, geom)
@ -144,12 +144,12 @@ class ShaderManager {
// Standard shader nomenclature: /assets/shaders/shader-name.vs|fs[|gs]
// shader-name.vs and shader-name.fs are mandatory!
createShaderFromFiles (gl, name, gs) {
let stdloc = '/assets/shaders/' + name
const stdloc = '/assets/shaders/' + name
return new Promise((resolve, reject) => {
function finishLink (vs, fs, gss) {
try {
let shader = this.createShader(gl, name, vs, fs, gss)
const shader = this.createShader(gl, name, vs, fs, gss)
resolve(shader)
} catch (e) {
reject(e)

View File

@ -57,13 +57,13 @@ export function divv3 (one, two) {
}
export function normalv3 (vec) {
let res = vec
const res = vec
vec3.normalize(res, vec)
return res
}
export function crossv3 (vec1, vec2) {
let res = []
const res = []
vec3.cross(res, vec1, vec2)
return res
}

View File

@ -145,9 +145,9 @@ class VoxelChunk extends MeshInstance {
if (!this.data[x]) this.data[x] = {}
for (let z = 0; z < this.size; 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++) {
let solid = this.pos[1] + y < columnHeight
const solid = this.pos[1] + y < columnHeight
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
createFace (points, pos, face) {
// 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][2]), addv3(pos, FACE_VERTEX[face][3])
]
// 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)
// 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
let points = []
const points = []
// Generate face quads for each voxel in the chunk
for (let x = 0; x < this.size; x++) {
for (let y = 0; y < this.size; y++) {
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 - 1, z).solid) {
@ -242,11 +242,11 @@ class VoxelChunk extends MeshInstance {
}
// Flatten the points array to three separate arrays
let vertices = []
let normals = []
let uvs = []
for (let i in points) {
let vert = points[i]
const vertices = []
const normals = []
const uvs = []
for (const i in points) {
const vert = points[i]
vertices.push(vert[0][0])
vertices.push(vert[0][1])
vertices.push(vert[0][2])
@ -304,7 +304,7 @@ class VoxelMapBlock extends Node {
if (!this.chunks[x][z]) this.chunks[x][z] = {}
for (let y = 0; y < this.size; y++) {
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.addChild(chunk)
generator.pushChunk(chunk)
@ -315,8 +315,8 @@ class VoxelMapBlock extends Node {
destroy (gl) {
this.generated = false
for (let i in this.children) {
let ch = this.children[i]
for (const i in this.children) {
const ch = this.children[i]
if (!(ch instanceof VoxelChunk)) continue
ch.destroy(gl)
}
@ -326,8 +326,8 @@ class VoxelMapBlock extends Node {
update (gl, dt) {
if (!this.generated) return false
for (let i in this.children) {
let ch = this.children[i]
for (const i in this.children) {
const ch = this.children[i]
if (!(ch instanceof VoxelChunk)) continue
if (ch.update(gl, dt)) return true
}
@ -359,19 +359,19 @@ class VoxelWorld extends Node {
update (gl, cam, dt) {
// Generate queued mapblocks before adding new ones to queue
if (this.mapblockqueue.length) {
let leftover = []
const leftover = []
let generated = false
for (let i in this.mapblockqueue) {
let pos = this.mapblockqueue[i]
let check = this.getBlock(pos[0], pos[1], pos[2])
for (const i in this.mapblockqueue) {
const pos = this.mapblockqueue[i]
const check = this.getBlock(pos[0], pos[1], pos[2])
if (generated || check) {
leftover.push(pos)
continue
}
let absPos = mulv3(pos, this.blockSize * this.chunkSize)
let block = new VoxelMapBlock(absPos, this.chunkSize, this.blockSize)
const absPos = mulv3(pos, this.blockSize * this.chunkSize)
const block = new VoxelMapBlock(absPos, this.chunkSize, this.blockSize)
block.generate(this.generator)
if (!this.blocks[pos[0]]) this.blocks[pos[0]] = {}
@ -387,8 +387,8 @@ class VoxelWorld extends Node {
}
// Calculate a fixed grid
let 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 total = this.blockSize * this.chunkSize
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 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
}
}
@ -425,8 +425,8 @@ class VoxelGenerator {
// Generate chunks in the queue
update (dt) {
for (let i in this.generateQueue) {
let chunk = this.generateQueue[i]
for (const i in this.generateQueue) {
const chunk = this.generateQueue[i]
if (chunk.generated) continue
chunk.material = this.material

View File

@ -19,16 +19,16 @@ import Atmosphere from './engine/components/planet/atmosphere'
import { CubePlanet, PlanetGenerator } from './engine/components/planet'
let game = Engine
let env = new Environment()
let gui = new GUIRenderer()
let fnt = new FontRenderer()
let prt = new ParticleRenderer()
const game = Engine
const env = new Environment()
const gui = new GUIRenderer()
const fnt = new FontRenderer()
const prt = new ParticleRenderer()
async function pipeline () {
let entity = await loadMesh(game.gl, 'test')
let terrainShader = await game.shaders.createShaderFromFiles(game.gl, 'terrain', false)
let skyboxShader = await game.shaders.createShaderFromFiles(game.gl, 'skybox', false)
const entity = await loadMesh(game.gl, 'test')
const terrainShader = await game.shaders.createShaderFromFiles(game.gl, 'terrain', false)
const skyboxShader = await game.shaders.createShaderFromFiles(game.gl, 'skybox', false)
// let atmosShader = await game.shaders.createShaderFromFiles(game.gl, 'atmosphere', false)
entity.setRotation([0.0, 0.0, -90.0])
@ -39,7 +39,7 @@ async function pipeline () {
// await waterRenderer.initialize(game)
// await waterRenderer.useDUDVMap(game.gl, 'dudv')
// await waterRenderer.useNormalMap(game.gl, 'normalmap')
let arialFont = await Font.fromFile('arial')
const arialFont = await Font.fromFile('arial')
await arialFont.loadTextures(game.gl)
// Initialize GUI
@ -48,12 +48,12 @@ async function pipeline () {
// Initialize particles
await prt.initialize(game)
let particleSystem = new ParticleSystem(prt)
const particleSystem = new ParticleSystem(prt)
// 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 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]
// 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
// let terrain = new LODTerrain([0.0, 0.0, 0.0], 1024, 1024, 850, 4)
// Terrain material
let material = new Material(['grass-plain-1024.jpg'])
const material = new Material(['grass-plain-1024.jpg'])
await material.loadTextures(game.gl)
// test code
for (let i in entity.children) {
for (const i in entity.children) {
entity.children[i].mesh.material = material
}
@ -81,11 +81,11 @@ async function pipeline () {
// terrain.setMaterial(material)
// 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)
// Create skybox
let skybox = new Skybox('skybox', cam.farPlane / 2)
const skybox = new Skybox('skybox', cam.farPlane / 2)
// Load textures and generate a mesh
await skybox.initialize(game.gl)
@ -95,7 +95,7 @@ async function pipeline () {
// let block = new VoxelWorld(voxgen)
// 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])
// Update function for camera and terrain
@ -122,11 +122,11 @@ async function pipeline () {
particleSystem.update(dt, -50)
if (game.input.isDown('y')) {
let velocity = 20
const velocity = 20
for (let i = 0; i < 360; i += 15) {
let rad1 = i * Math.PI / 180
let x1 = (Math.cos(rad1) * velocity) + randomInt(-5, 5)
let y1 = (Math.sin(rad1) * velocity) + randomInt(-5, 5)
const rad1 = i * Math.PI / 180
const x1 = (Math.cos(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)))
}
}