update deps, add planet back
This commit is contained in:
parent
c73e705aaa
commit
cca0d2b3c3
20
package.json
20
package.json
@ -16,19 +16,19 @@
|
|||||||
"author": "Evert \"Diamond\" Prants <evert@lunasqu.ee>",
|
"author": "Evert \"Diamond\" Prants <evert@lunasqu.ee>",
|
||||||
"license": "LGPL-3.0-or-later",
|
"license": "LGPL-3.0-or-later",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.7.4",
|
"@babel/core": "^7.9.0",
|
||||||
"@babel/plugin-transform-runtime": "^7.7.4",
|
"@babel/plugin-transform-runtime": "^7.9.0",
|
||||||
"@babel/preset-env": "^7.7.4",
|
"@babel/preset-env": "^7.9.0",
|
||||||
"babel-loader": "^8.0.6",
|
"babel-loader": "^8.1.0",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"html-webpack-plugin": "^3.2.0",
|
"html-webpack-plugin": "^4.0.3",
|
||||||
"standard": "^12.0.1",
|
"standard": "^14.3.3",
|
||||||
"webpack": "^4.41.2",
|
"webpack": "^4.42.1",
|
||||||
"webpack-command": "^0.4.2"
|
"webpack-command": "^0.5.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.7.4",
|
"@babel/runtime": "^7.9.2",
|
||||||
"gl-matrix": "^2.8.1",
|
"gl-matrix": "^3.2.1",
|
||||||
"open-simplex-noise": "^1.7.0"
|
"open-simplex-noise": "^1.7.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
220
src/engine/components/planet/index.js
Normal file
220
src/engine/components/planet/index.js
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
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'
|
||||||
|
|
||||||
|
const lodMax = 8
|
||||||
|
|
||||||
|
class PlanetGenerator {
|
||||||
|
constructor (resolution, radius, noise) {
|
||||||
|
this.resolution = resolution
|
||||||
|
this.radius = radius
|
||||||
|
this.noise = noise
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CubeFace {
|
||||||
|
constructor (parent, level, pos, normal, generator) {
|
||||||
|
this.parent = parent
|
||||||
|
this.children = []
|
||||||
|
|
||||||
|
this.normal = normal
|
||||||
|
|
||||||
|
this.level = level
|
||||||
|
|
||||||
|
this.generated = false
|
||||||
|
this.generator = generator
|
||||||
|
|
||||||
|
// Calculate left (x) and forward (z) vectors from the normal (y)
|
||||||
|
this.left = [normal[1], normal[2], normal[0]]
|
||||||
|
this.forward = crossv3(normal, this.left)
|
||||||
|
|
||||||
|
this.position = pos
|
||||||
|
|
||||||
|
// Center the face
|
||||||
|
if (level === 0) {
|
||||||
|
this.position = subv3(this.position, mulv3(this.left, generator.radius / 2))
|
||||||
|
this.position = subv3(this.position, mulv3(this.forward, generator.radius / 2))
|
||||||
|
}
|
||||||
|
|
||||||
|
this.generate()
|
||||||
|
}
|
||||||
|
|
||||||
|
generate () {
|
||||||
|
if (this.generated) return
|
||||||
|
|
||||||
|
let VERTICES = this.generator.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))
|
||||||
|
|
||||||
|
let radius = this.generator.radius
|
||||||
|
let 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)
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
|
||||||
|
// Add the scaled left and forward to the centered origin
|
||||||
|
let 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, (radius))
|
||||||
|
|
||||||
|
vertices[vertexPointer * 3] = pos[0]
|
||||||
|
vertices[vertexPointer * 3 + 1] = pos[1]
|
||||||
|
vertices[vertexPointer * 3 + 2] = pos[2]
|
||||||
|
normals[vertexPointer * 3] = normal[0]
|
||||||
|
normals[vertexPointer * 3 + 1] = normal[1]
|
||||||
|
normals[vertexPointer * 3 + 2] = normal[2]
|
||||||
|
textureCoords[vertexPointer * 2] = j * (1 / VERTICES)
|
||||||
|
textureCoords[vertexPointer * 2 + 1] = i * (1 / VERTICES)
|
||||||
|
|
||||||
|
if (i === VERTICES / 2 && j === VERTICES / 2) {
|
||||||
|
this.center = pos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
indices[pointer++] = topLeft
|
||||||
|
indices[pointer++] = bottomLeft
|
||||||
|
indices[pointer++] = topRight
|
||||||
|
indices[pointer++] = topRight
|
||||||
|
indices[pointer++] = bottomLeft
|
||||||
|
indices[pointer++] = bottomRight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mesh = Mesh.construct(Screen.gl, vertices, indices, textureCoords, normals)
|
||||||
|
this.generated = true
|
||||||
|
}
|
||||||
|
|
||||||
|
dispose () {
|
||||||
|
this.generated = false
|
||||||
|
if (this.mesh) {
|
||||||
|
// this.mesh.dispose(Screen.gl)
|
||||||
|
this.mesh = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
merge () {
|
||||||
|
if (!this.children.length) return
|
||||||
|
|
||||||
|
for (let i in this.children) {
|
||||||
|
let ch = this.children[i]
|
||||||
|
|
||||||
|
ch.merge()
|
||||||
|
ch.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.children = []
|
||||||
|
this.generate()
|
||||||
|
}
|
||||||
|
|
||||||
|
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))
|
||||||
|
|
||||||
|
this.children = [
|
||||||
|
new CubeFace(this, lv, this.position, this.normal, this.generator),
|
||||||
|
new CubeFace(this, lv, addv3(this.position, stepForward), this.normal, this.generator),
|
||||||
|
new CubeFace(this, lv, addv3(this.position, stepLeft), this.normal, this.generator),
|
||||||
|
new CubeFace(this, lv, addv3(this.position, addv3(stepLeft, stepForward)), this.normal, this.generator)
|
||||||
|
]
|
||||||
|
|
||||||
|
this.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
draw (gl, shader) {
|
||||||
|
if (!this.mesh) {
|
||||||
|
for (let i in this.children) {
|
||||||
|
this.children[i].draw(gl, shader)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mesh.prepare(gl, shader)
|
||||||
|
this.mesh.draw(gl, shader)
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
if (camToOrigin < splitDistance * 1.5 && this.children.length === 0) {
|
||||||
|
this.subdivide()
|
||||||
|
return
|
||||||
|
} else if (camToOrigin > splitDistance * 2 && this.children.length > 0) {
|
||||||
|
this.merge()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.children.length > 0) {
|
||||||
|
for (let i in this.children) {
|
||||||
|
this.children[i].update(camera, dt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CubePlanet {
|
||||||
|
constructor (origin, generator) {
|
||||||
|
this.origin = origin
|
||||||
|
this.generator = generator
|
||||||
|
|
||||||
|
this.transform = mat4.create()
|
||||||
|
mat4.fromTranslation(this.transform, origin)
|
||||||
|
|
||||||
|
let hs = generator.radius / 2
|
||||||
|
|
||||||
|
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), // back
|
||||||
|
|
||||||
|
new CubeFace(this, 0, [-hs, 0, 0], [-1, 0, 0], generator), // left
|
||||||
|
new CubeFace(this, 0, [hs, 0, 0], [1, 0, 0], generator), // right
|
||||||
|
|
||||||
|
new CubeFace(this, 0, [0, hs, 0], [0, 1, 0], generator), // top
|
||||||
|
new CubeFace(this, 0, [0, -hs, 0], [0, -1, 0], generator) // bottom
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
update (camera, dt) {
|
||||||
|
for (let i in this.faces) {
|
||||||
|
this.faces[i].update(camera, dt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
draw (gl, shader) {
|
||||||
|
// Set model transform matrix uniform
|
||||||
|
const transformLocation = shader.getUniformLocation(gl, 'uModelMatrix')
|
||||||
|
gl.uniformMatrix4fv(transformLocation, false, this.transform)
|
||||||
|
|
||||||
|
for (let i in this.faces) {
|
||||||
|
this.faces[i].draw(gl, shader)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { CubePlanet, CubeFace, PlanetGenerator }
|
@ -42,7 +42,7 @@ class Environment {
|
|||||||
this.fogEnd = 0
|
this.fogEnd = 0
|
||||||
this.fogColor = [0.8, 0.8, 0.8]
|
this.fogColor = [0.8, 0.8, 0.8]
|
||||||
|
|
||||||
this.sun = new DirectionalLight([0.0, 1000.0, 2000.0], [-1.0, -1.0, 0.0], [1.0, 1.0, 1.0])
|
this.sun = new DirectionalLight([0.0, 1000.0, -2000.0], [-1.0, -1.0, 0.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
|
||||||
|
@ -325,11 +325,11 @@ class VoxelMapBlock extends Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
update (gl, dt) {
|
update (gl, dt) {
|
||||||
if (!this.generated) return
|
if (!this.generated) return false
|
||||||
for (let i in this.children) {
|
for (let i in this.children) {
|
||||||
let ch = this.children[i]
|
let ch = this.children[i]
|
||||||
if (!(ch instanceof VoxelChunk)) continue
|
if (!(ch instanceof VoxelChunk)) continue
|
||||||
if (ch.update(gl, dt)) break
|
if (ch.update(gl, dt)) return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -370,7 +370,7 @@ class VoxelWorld extends Node {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
let absPos = mulv3(pos, this.blockSize * (this.chunkSize / 2))
|
let absPos = mulv3(pos, this.blockSize * this.chunkSize)
|
||||||
let block = new VoxelMapBlock(absPos, this.chunkSize, this.blockSize)
|
let block = new VoxelMapBlock(absPos, this.chunkSize, this.blockSize)
|
||||||
block.generate(this.generator)
|
block.generate(this.generator)
|
||||||
|
|
||||||
@ -391,8 +391,8 @@ class VoxelWorld extends Node {
|
|||||||
let slgrid = [Math.floor(cam.pos[0] / total), Math.floor(cam.pos[1] / total), Math.floor(cam.pos[2] / total)]
|
let 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[1] - this.renderDistance / 2; z < slgrid[1] + this.renderDistance / 2; z++) {
|
for (let z = slgrid[2] - this.renderDistance / 2; z < slgrid[2] + this.renderDistance / 2; z++) {
|
||||||
for (let y = slgrid[2] - this.renderDistance / 2; y < slgrid[2] + this.renderDistance / 2; y++) {
|
for (let y = slgrid[1] - this.renderDistance / 2; y < slgrid[1] + this.renderDistance / 2; y++) {
|
||||||
if (this.getBlock(x, y, z)) continue
|
if (this.getBlock(x, y, z)) continue
|
||||||
this.queueMapblock([x, y, z])
|
this.queueMapblock([x, y, z])
|
||||||
}
|
}
|
||||||
@ -400,7 +400,7 @@ class VoxelWorld extends Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (let i in this.children) {
|
for (let i in this.children) {
|
||||||
this.children[i].update(gl, dt)
|
if (this.children[i].update(gl, dt)) break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
43
src/index.js
43
src/index.js
@ -15,6 +15,8 @@ import { GUIRenderer, GUIImage, Dim4 } from './engine/gui'
|
|||||||
import { FontRenderer, GUIText, Font } from './engine/gui/font'
|
import { FontRenderer, GUIText, Font } from './engine/gui/font'
|
||||||
import { VoxelWorld, VoxelGenerator } from './engine/voxel'
|
import { VoxelWorld, VoxelGenerator } from './engine/voxel'
|
||||||
|
|
||||||
|
import { CubePlanet, PlanetGenerator } from './engine/components/planet'
|
||||||
|
|
||||||
let game = Engine
|
let game = Engine
|
||||||
let env = new Environment()
|
let env = new Environment()
|
||||||
let gui = new GUIRenderer()
|
let gui = new GUIRenderer()
|
||||||
@ -29,11 +31,11 @@ async function pipeline () {
|
|||||||
entity.setRotation([0.0, 0.0, -90.0])
|
entity.setRotation([0.0, 0.0, -90.0])
|
||||||
|
|
||||||
// Initialize water
|
// Initialize water
|
||||||
let waterRenderer = new WaterRenderer()
|
// let waterRenderer = new WaterRenderer()
|
||||||
let water = new WaterTile([100.0, 0.0, 100.0], 100.0)
|
// let water = new WaterTile([100.0, 0.0, 100.0], 100.0)
|
||||||
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')
|
let arialFont = await Font.fromFile('arial')
|
||||||
await arialFont.loadTextures(game.gl)
|
await arialFont.loadTextures(game.gl)
|
||||||
|
|
||||||
@ -60,7 +62,7 @@ async function pipeline () {
|
|||||||
let hmap = new SimplexHeightMap(1, 1, 256, 50)
|
let hmap = new SimplexHeightMap(1, 1, 256, 50)
|
||||||
|
|
||||||
// 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-1024.jpg'])
|
let material = new Material(['grass-1024.jpg'])
|
||||||
@ -72,11 +74,11 @@ async function pipeline () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set generator and material for terrain
|
// Set generator and material for terrain
|
||||||
terrain.setGenerator(hmap)
|
// terrain.setGenerator(hmap)
|
||||||
terrain.setMaterial(material)
|
// terrain.setMaterial(material)
|
||||||
|
|
||||||
// Create and initialize the camera
|
// Create and initialize the camera
|
||||||
let cam = new Camera([-16.0, 25.0, -16.0], [0.8, -0.6, 0.0])
|
let 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
|
||||||
@ -89,6 +91,9 @@ async function pipeline () {
|
|||||||
// let voxgen = new VoxelGenerator(hmap, material)
|
// let voxgen = new VoxelGenerator(hmap, material)
|
||||||
// let block = new VoxelWorld(voxgen)
|
// let block = new VoxelWorld(voxgen)
|
||||||
|
|
||||||
|
// Planet test
|
||||||
|
let planet = new CubePlanet([0.0, 0.0, 0.0], new PlanetGenerator(16, 1000, hmap))
|
||||||
|
|
||||||
// Update function for camera and terrain
|
// Update function for camera and terrain
|
||||||
let fpsTimer = 0
|
let fpsTimer = 0
|
||||||
game.addUpdateFunction(function (dt) {
|
game.addUpdateFunction(function (dt) {
|
||||||
@ -123,11 +128,11 @@ async function pipeline () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update detail levels
|
// Update detail levels
|
||||||
terrain.update(game.gl, cam)
|
// terrain.update(game.gl, cam)
|
||||||
terrain.updateLODMesh(game.gl)
|
// terrain.updateLODMesh(game.gl)
|
||||||
|
|
||||||
// Ripple water
|
// Ripple water
|
||||||
waterRenderer.update(dt)
|
// waterRenderer.update(dt)
|
||||||
|
|
||||||
// Update voxel chunk
|
// Update voxel chunk
|
||||||
// voxgen.update(dt)
|
// voxgen.update(dt)
|
||||||
@ -139,6 +144,9 @@ async function pipeline () {
|
|||||||
itms[0].children[0].setText(game.fps + ' fps')
|
itms[0].children[0].setText(game.fps + ' fps')
|
||||||
fpsTimer = 0
|
fpsTimer = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update planet LOD
|
||||||
|
planet.update(cam, dt)
|
||||||
})
|
})
|
||||||
|
|
||||||
function drawEverything (gl) {
|
function drawEverything (gl) {
|
||||||
@ -155,21 +163,24 @@ async function pipeline () {
|
|||||||
// Set the viewport uniforms
|
// Set the viewport uniforms
|
||||||
cam.draw(gl, terrainShader)
|
cam.draw(gl, terrainShader)
|
||||||
// Draw terrain
|
// Draw terrain
|
||||||
terrain.draw(gl, terrainShader)
|
// terrain.draw(gl, terrainShader)
|
||||||
|
|
||||||
// entity.draw(gl, terrainShader)
|
// entity.draw(gl, terrainShader)
|
||||||
|
|
||||||
// block.draw(gl, terrainShader)
|
// block.draw(gl, terrainShader)
|
||||||
|
|
||||||
|
material.apply(gl, terrainShader)
|
||||||
|
planet.draw(gl, terrainShader)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render function for the triangle
|
// Render function for the triangle
|
||||||
game.addRenderFunction(function (gl) {
|
game.addRenderFunction(function (gl) {
|
||||||
waterRenderer.reflect(gl, cam, drawEverything)
|
// waterRenderer.reflect(gl, cam, drawEverything)
|
||||||
waterRenderer.refract(gl, cam, drawEverything)
|
// waterRenderer.refract(gl, cam, drawEverything)
|
||||||
|
|
||||||
drawEverything(gl)
|
drawEverything(gl)
|
||||||
|
|
||||||
waterRenderer.draw(gl, [water], cam, env.sun)
|
// waterRenderer.draw(gl, [water], cam, env.sun)
|
||||||
|
|
||||||
// Draw particles
|
// Draw particles
|
||||||
particleSystem.draw(gl, cam)
|
particleSystem.draw(gl, cam)
|
||||||
|
Loading…
Reference in New Issue
Block a user