From c73e705aaaa282c83e08d0badd206f70df9ba9d9 Mon Sep 17 00:00:00 2001 From: Evert Prants Date: Mon, 6 Jan 2020 15:27:18 +0200 Subject: [PATCH] i dont know how to do this --- src/engine/voxel/index.js | 75 +++++++++++++++++++++++++++++++++++++-- src/index.js | 40 ++++++++++----------- 2 files changed, 92 insertions(+), 23 deletions(-) diff --git a/src/engine/voxel/index.js b/src/engine/voxel/index.js index 9b47a5b..09dedd8 100644 --- a/src/engine/voxel/index.js +++ b/src/engine/voxel/index.js @@ -1,6 +1,6 @@ import { Mesh } from '../mesh' import { Node, MeshInstance } from '../components' -import { addv3 } from '../utility' +import { addv3, mulv3 } from '../utility' const FACE_VERTEX = [ // Bottom @@ -334,6 +334,77 @@ class VoxelMapBlock extends Node { } } +class VoxelWorld extends Node { + constructor (generator, renderDistance = 2, worldSize = 64, blockSize = 8, chunkSize = 16) { + super([0.0, 0.0, 0.0]) + this.generator = generator + this.renderDistance = renderDistance + this.generator = generator + this.worldSize = worldSize + this.blockSize = blockSize + this.chunkSize = chunkSize + this.blocks = {} + this.mapblockqueue = [] + } + + queueMapblock (pos) { + this.mapblockqueue.push(pos) + } + + getBlock (x, y, z) { + if (!this.blocks[x] || !this.blocks[x][z] || !this.blocks[x][z][y]) return null + return this.blocks[x][z][y] + } + + update (gl, cam, dt) { + // Generate queued mapblocks before adding new ones to queue + if (this.mapblockqueue.length) { + let 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]) + + if (generated || check) { + leftover.push(pos) + continue + } + + let absPos = mulv3(pos, this.blockSize * (this.chunkSize / 2)) + let block = new VoxelMapBlock(absPos, this.chunkSize, this.blockSize) + block.generate(this.generator) + + if (!this.blocks[pos[0]]) this.blocks[pos[0]] = {} + if (!this.blocks[pos[0]][pos[2]]) this.blocks[pos[0]][pos[2]] = {} + if (!this.blocks[pos[0]][pos[2]][pos[1]]) this.blocks[pos[0]][pos[2]][pos[1]] = {} + + this.blocks[pos[0]][pos[2]][pos[1]] = block + this.addChild(block) + generated = true + } + this.mapblockqueue = leftover + return + } + + // 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)] + + 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 y = slgrid[2] - this.renderDistance / 2; y < slgrid[2] + this.renderDistance / 2; y++) { + if (this.getBlock(x, y, z)) continue + this.queueMapblock([x, y, z]) + } + } + } + + for (let i in this.children) { + this.children[i].update(gl, dt) + } + } +} + class VoxelGenerator { constructor (noise, material, groundHeight = 64) { this.material = material @@ -364,4 +435,4 @@ class VoxelGenerator { } } -export { VoxelGenerator, Voxel, VoxelChunk, VoxelMapBlock } +export { VoxelGenerator, Voxel, VoxelChunk, VoxelMapBlock, VoxelWorld } diff --git a/src/index.js b/src/index.js index 62141e6..cb88405 100644 --- a/src/index.js +++ b/src/index.js @@ -13,7 +13,7 @@ import { SimplexHeightMap } from './engine/components/terrain/heightmap' import { Material, Texture } from './engine/mesh/material' import { GUIRenderer, GUIImage, Dim4 } from './engine/gui' import { FontRenderer, GUIText, Font } from './engine/gui/font' -import { VoxelMapBlock, VoxelGenerator } from './engine/voxel' +import { VoxelWorld, VoxelGenerator } from './engine/voxel' let game = Engine let env = new Environment() @@ -22,10 +22,10 @@ let fnt = new FontRenderer() let prt = new ParticleRenderer() async function pipeline () { -// let entity = await loadMesh(game.gl, 'test') + 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) -/* + entity.setRotation([0.0, 0.0, -90.0]) // Initialize water @@ -34,7 +34,6 @@ 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') await arialFont.loadTextures(game.gl) @@ -59,14 +58,14 @@ async function pipeline () { // Create a height map based on OpenSimplex noise let hmap = new SimplexHeightMap(1, 1, 256, 50) -/* + // 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-1024.jpg']) await material.loadTextures(game.gl) -/* + // test code for (let i in entity.children) { entity.children[i].mesh.material = material @@ -75,7 +74,7 @@ async function pipeline () { // Set generator and material for terrain terrain.setGenerator(hmap) terrain.setMaterial(material) -*/ + // Create and initialize the camera let cam = new Camera([-16.0, 25.0, -16.0], [0.8, -0.6, 0.0]) cam.updateProjection(game.gl) @@ -87,9 +86,8 @@ async function pipeline () { await skybox.initialize(game.gl) // Voxel test - let voxgen = new VoxelGenerator(hmap, material) - let block = new VoxelMapBlock([0.0, 0.0, 0.0]) - block.generate(voxgen) + // let voxgen = new VoxelGenerator(hmap, material) + // let block = new VoxelWorld(voxgen) // Update function for camera and terrain let fpsTimer = 0 @@ -125,15 +123,15 @@ async function pipeline () { } // Update detail levels - // terrain.update(game.gl, cam) - // terrain.updateLODMesh(game.gl) + terrain.update(game.gl, cam) + terrain.updateLODMesh(game.gl) // Ripple water - // waterRenderer.update(dt) + waterRenderer.update(dt) // Update voxel chunk - voxgen.update(dt) - block.update(game.gl, dt) + // voxgen.update(dt) + // block.update(game.gl, cam, dt) // Set text to FPS fpsTimer++ @@ -157,21 +155,21 @@ async function pipeline () { // Set the viewport uniforms cam.draw(gl, terrainShader) // Draw terrain - // terrain.draw(gl, terrainShader) + terrain.draw(gl, terrainShader) // entity.draw(gl, terrainShader) - block.draw(gl, terrainShader) + // block.draw(gl, terrainShader) } // Render function for the triangle game.addRenderFunction(function (gl) { - // waterRenderer.reflect(gl, cam, drawEverything) - // waterRenderer.refract(gl, cam, drawEverything) + waterRenderer.reflect(gl, cam, drawEverything) + waterRenderer.refract(gl, cam, drawEverything) drawEverything(gl) - // waterRenderer.draw(gl, [water], cam, env.sun) + waterRenderer.draw(gl, [water], cam, env.sun) // Draw particles particleSystem.draw(gl, cam)