From 651e3e913f57884d9923cb31e0f0d76fd0d85c76 Mon Sep 17 00:00:00 2001 From: Ryland Goldstein Date: Mon, 10 Dec 2018 19:10:01 -0800 Subject: [PATCH 01/14] Add local server support --- fractal-terrain-generation/fractal.js | 51 ++++++++++++------- .../localserver/package.json | 14 +++++ .../localserver/server.js | 16 ++++++ 3 files changed, 63 insertions(+), 18 deletions(-) create mode 100644 fractal-terrain-generation/localserver/package.json create mode 100644 fractal-terrain-generation/localserver/server.js diff --git a/fractal-terrain-generation/fractal.js b/fractal-terrain-generation/fractal.js index 24dc5f7..76ef837 100644 --- a/fractal-terrain-generation/fractal.js +++ b/fractal-terrain-generation/fractal.js @@ -2,9 +2,30 @@ const noiseGen = require('./function_lib/noiseGen'); const simplify = require('./function_lib/simplify'); +function makeHeaders(blockCount, maxHeight, + payloadBytes, genTime) { + const statusHeaders = { + 'X-Gen-Data-Blockcount': blockCount, + 'X-Gen-Data-Max-Height': maxHeight, + 'X-Gen-Data-Payload-Bytes': payloadBytes, + 'X-Gen-Data-Time-Running-MS': genTime, + }; + const customHeaders = { + 'Access-Control-Expose-Headers': Object.keys(statusHeaders).join(', '), + 'Content-Type': 'application/octet-stream', + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Headers': 'Origin X-Requested-With, Content-Type, Accept', + ... statusHeaders, + }; + return customHeaders; +} + exports.handler = async (body, ctx) => { const { size, xPos, zPos, downscale, heightFactor } = ctx.request.query; + let respBody; + let headers; + let statusCode = 500; const genStartTime = process.hrtime(); const { blockCount, data, maxHeight } = noiseGen( @@ -42,24 +63,18 @@ exports.handler = async (body, ctx) => { const buffer = Buffer.from(mergedData.buffer); console.log(`buffer size is ${buffer.length / 1000}`); - const genTime = process.hrtime(genStartTime); - const genDataTimeStr = (genTime[0] * 1000) + (genTime[1] / 1000000); - const customHeaders = { - 'X-Gen-Data-Blockcount': blockCount, - 'X-Gen-Data-Max-Height': maxHeight, - 'X-Gen-Data-Payload-Bytes': buffer.length, - 'X-Gen-Data-Time-Running-MS': genDataTimeStr, - }; - + const genTime = process.hrtime(genStartTime); + const genDataTimeStr = (genTime[0] * 1000) + (genTime[1] / 1000000); + headers = makeHeaders(blockCount, maxHeight, respBody.length, genDataTimeStr); + statusCode = 200; + } + if (ctx.request.query.express_server) { + ctx.set(headers); + return ctx.send(respBody); + } return new ctx.HTTPResponse({ - statusCode: 200, - headers: { - 'Access-Control-Expose-Headers': Object.keys(customHeaders).join(', '), - 'Content-Type': 'application/octet-stream', - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Headers': 'Origin X-Requested-With, Content-Type, Accept', - ...customHeaders, - }, - body: buffer, + statusCode, + headers, + body: respBody, }); }; diff --git a/fractal-terrain-generation/localserver/package.json b/fractal-terrain-generation/localserver/package.json new file mode 100644 index 0000000..e5e7485 --- /dev/null +++ b/fractal-terrain-generation/localserver/package.json @@ -0,0 +1,14 @@ +{ + "name": "local fractal server", + "version": "1.0.0", + "description": "", + "main": "server.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "express": "^4.16.4" + } +} diff --git a/fractal-terrain-generation/localserver/server.js b/fractal-terrain-generation/localserver/server.js new file mode 100644 index 0000000..a3cf83a --- /dev/null +++ b/fractal-terrain-generation/localserver/server.js @@ -0,0 +1,16 @@ +const express = require('express'); + +const fractal = require('../fractal'); +const app = express(); + +async function handleReq(req, res) { + if (req && req.query) { + req.query.express_server = true; + res.request = { query: req.query }; + } + return await fractal.handler(req.body, res); +} + +app.get('/v2/*', handleReq); + +app.listen(3000, () => console.log('Fractal server running at localhost:3000/v2/*')); From fdc7f03e60845b9724b7e1315d4dcbb0faa08efc Mon Sep 17 00:00:00 2001 From: Ryland Goldstein Date: Fri, 14 Dec 2018 14:10:14 -0800 Subject: [PATCH 02/14] support vertical chunking --- fractal-terrain-generation/fractal.js | 72 +++++++++++-------- .../function_lib/noiseGen.js | 31 +++++--- .../function_lib/simplify.js | 11 +-- fractal-terrain-generation/src/gen.worker.js | 11 ++- fractal-terrain-generation/src/main.js | 5 +- fractal-terrain-generation/src/tile.js | 12 ++-- fractal-terrain-generation/src/worldGen.js | 42 ++++++----- 7 files changed, 115 insertions(+), 69 deletions(-) diff --git a/fractal-terrain-generation/fractal.js b/fractal-terrain-generation/fractal.js index 76ef837..b27ded9 100644 --- a/fractal-terrain-generation/fractal.js +++ b/fractal-terrain-generation/fractal.js @@ -21,7 +21,14 @@ function makeHeaders(blockCount, maxHeight, } exports.handler = async (body, ctx) => { - const { size, xPos, zPos, downscale, heightFactor } = ctx.request.query; + const { + size, + xPos, + yPos, + zPos, + downscale, + heightFactor, + } = ctx.request.query; let respBody; let headers; @@ -29,39 +36,48 @@ exports.handler = async (body, ctx) => { const genStartTime = process.hrtime(); const { blockCount, data, maxHeight } = noiseGen( - parseInt(xPos, 10), parseInt(zPos, 10), size, - downscale, heightFactor - ); - const { verts, indices, normals, tex } = simplify( - data, size, maxHeight, size, - parseInt(xPos, 10), parseInt(zPos, 10) + parseInt(xPos, 10), parseInt(yPos, 10), + parseInt(zPos, 10), parseInt(size, 10), + downscale, parseInt(heightFactor, 10) ); + if (blockCount === 0) { + const failedGenTime = process.hrtime(genStartTime); + const genStr = (failedGenTime[0] * 1000) + (failedGenTime[1] / 1000000); + headers = makeHeaders(blockCount, maxHeight, 0, genStr); + respBody = new Buffer(2); + } else { + const { verts, indices, normals, tex } = simplify( + data, size, size, size, + parseInt(xPos, 10), parseInt(yPos, 10), + parseInt(zPos, 10), heightFactor + ); - // how many elements make up the lookup table - const tableElements = 4; + // how many elements make up the lookup table + const tableElements = 4; - const mergedData = new Int16Array(verts.length + indices.length - + normals.length + tex.length + tableElements); + const mergedData = new Int16Array(verts.length + indices.length + + normals.length + tex.length + tableElements); - // this is an unfortunate bit of logic required to make sure - // that our buffers length value doesn't get truncated/overflowed - // in the lookup table. - function split32BitValue(value) { - return [value & 0xFFFF, (value >> 16) & 0xFFFF]; - } - const splitVertsLength = split32BitValue(verts.length); - const splitTexLength = split32BitValue(tex.length); - mergedData[0] = splitVertsLength[0]; - mergedData[1] = splitVertsLength[1]; - mergedData[2] = splitTexLength[0]; - mergedData[3] = splitTexLength[1]; + // this is an unfortunate bit of logic required to make sure + // that our buffers length value doesn't get truncated/overflowed + // in the lookup table. + function split32BitValue(value) { + return [value & 0xFFFF, (value >> 16) & 0xFFFF]; + } + const splitVertsLength = split32BitValue(verts.length); + const splitTexLength = split32BitValue(tex.length); + mergedData[0] = splitVertsLength[0]; + mergedData[1] = splitVertsLength[1]; + mergedData[2] = splitTexLength[0]; + mergedData[3] = splitTexLength[1]; - mergedData.set(verts, tableElements); - mergedData.set(normals, tableElements + verts.length); - mergedData.set(indices, verts.length + tableElements + normals.length + tex.length); + mergedData.set(verts, tableElements); + mergedData.set(normals, tableElements + verts.length); + mergedData.set(tex, tableElements + verts.length + normals.length); + mergedData.set(indices, verts.length + tableElements + normals.length + tex.length); - const buffer = Buffer.from(mergedData.buffer); - console.log(`buffer size is ${buffer.length / 1000}`); + respBody = Buffer.from(mergedData.buffer); + console.log(`buffer size is ${respBody.length / 1000}`); const genTime = process.hrtime(genStartTime); const genDataTimeStr = (genTime[0] * 1000) + (genTime[1] / 1000000); diff --git a/fractal-terrain-generation/function_lib/noiseGen.js b/fractal-terrain-generation/function_lib/noiseGen.js index f2f007d..548e2c4 100644 --- a/fractal-terrain-generation/function_lib/noiseGen.js +++ b/fractal-terrain-generation/function_lib/noiseGen.js @@ -14,7 +14,7 @@ const simplex = new SimplexNoise('default'); * @param {number} scaleHeight - sets the defacto maxHeight of the volume * @return {object} - generated data and metadata */ -function createDensities(cX, cZ, size, downscale = 1000, scaleHeight = 50) { +function createDensities(cX, cY, cZ, size, downscale = 1000, scaleHeight = 50) { let maxHeight = -1; let minHeight = 10000; let blockCount = 0; @@ -42,19 +42,30 @@ function createDensities(cX, cZ, size, downscale = 1000, scaleHeight = 50) { } } } - // if the calculated max height isn't divisible by - // the volume size granularity, we need to modify it - // to be an increment of size. - if (maxHeight % size !== 0) { - maxHeight = Math.ceil(maxHeight / size) * size; + + if ((minHeight) > (cY + size)) { + return { + blockCount: 0, + data: [], + maxHeight, + minHeight, + }; + } + + let maxRelevantHeight = maxHeight; + if (maxHeight > (cY + size)) { + maxRelevantHeight = size; + } else { + maxRelevantHeight = maxHeight - cY; } - const densities = new Int8Array(size * size * maxHeight).fill(1); + + const densities = new Int8Array(size * size * size).fill(1); let currIdx = -1; for (let i = 0; i < size; i += 1) { - for (let j = 0; j < maxHeight; j += 1) { + for (let j = 0; j < size; j += 1) { for (let k = 0; k < size; k += 1) { - currIdx = i + (j * size) + (k * maxHeight * size); - densities[currIdx] = (j <= heights[i + (k * size)]) ? 1 : 0; + currIdx = i + (j * size) + (k * size * size); + densities[currIdx] = ((j + cY) <= heights[i + (k * size)]) ? 1 : 0; blockCount += densities[currIdx]; } } diff --git a/fractal-terrain-generation/function_lib/simplify.js b/fractal-terrain-generation/function_lib/simplify.js index a1047b1..63cae51 100644 --- a/fractal-terrain-generation/function_lib/simplify.js +++ b/fractal-terrain-generation/function_lib/simplify.js @@ -67,9 +67,10 @@ class BlockFace { * @param {number} ySize - volumes size in Y dimension * @param {number} zSize - volumes size in Z dimension * @param {number} xPos - x coordinate offset of geometry + * @param {number} yPos - y coordinate offset of geometry * @param {number} zPos - z coordinate offset of geometry */ -function simplify(volume, xSize, ySize, zSize, xPos, zPos) { +function simplify(volume, xSize, ySize, zSize, xPos, yPos, zPos, heightFactor) { const nX = [0, 0, xSize - 1, 0, 0, 0]; const nY = [0, 0, 0, 0, ySize - 1, 0]; @@ -240,19 +241,19 @@ function simplify(volume, xSize, ySize, zSize, xPos, zPos) { verts.push(x[0] + xPos); // v0 - verts.push(x[1]); + verts.push(x[1] + yPos); verts.push(x[2] + zPos); verts.push(x[0] + du[0] + xPos); // v1 - verts.push(x[1] + du[1]); + verts.push(x[1] + du[1] + yPos); verts.push(x[2] + du[2] + zPos); verts.push(x[0] + dv[0] + xPos); // v2 - verts.push(x[1] + dv[1]); + verts.push(x[1] + dv[1] + yPos); verts.push(x[2] + dv[2] + zPos); verts.push(x[0] + du[0] + dv[0] + xPos); // v3 - verts.push(x[1] + du[1] + dv[1]); + verts.push(x[1] + du[1] + dv[1] + yPos); verts.push(x[2] + du[2] + dv[2] + zPos); tex.push(g); diff --git a/fractal-terrain-generation/src/gen.worker.js b/fractal-terrain-generation/src/gen.worker.js index 0bbfc63..f5f1ffb 100644 --- a/fractal-terrain-generation/src/gen.worker.js +++ b/fractal-terrain-generation/src/gen.worker.js @@ -25,9 +25,10 @@ const timeMSBetweenRetries = 20; * @param {Number} numRetries - # of invocation attempts before failing explicitly * @param {Number} endpoint - which of the function endpoints to use (if remote gen) */ -async function genData(ID, size, xPos, zPos, downscale, - heightFactor, endpoint, numRetries = 1) { +async function genData(ID, size, xPos, yPos, zPos, + downscale, heightFactor, endpoint, numRetries = 1) { const scaledX = xPos * size; + const scaledY = yPos * size; const scaledZ = zPos * size; // TODO(Ry): add exponential backoff // For now we simply retry based on the specified number @@ -42,6 +43,7 @@ async function genData(ID, size, xPos, zPos, downscale, downscale, heightFactor, xPos: scaledX, + yPos: scaledY, zPos: scaledZ, }) .responseType('arraybuffer'); @@ -51,6 +53,7 @@ async function genData(ID, size, xPos, zPos, downscale, type: GEN_SUCCESS, size, xPos, + yPos, zPos, heightFactor, maxHeight: headers['x-gen-data-max-height'], @@ -68,6 +71,7 @@ async function genData(ID, size, xPos, zPos, downscale, type: GEN_FAILURE, size, xPos, + yPos, zPos, data: err.message, }); @@ -88,11 +92,12 @@ thisWorker.addEventListener('message', async (e) => { ID, size, xPos, + yPos, zPos, endpoint, numRetries, downscale, heightFactor, } = e.data; - genData(ID, size, xPos, zPos, downscale, heightFactor, endpoint, numRetries); + genData(ID, size, xPos, yPos, zPos, downscale, heightFactor, endpoint, numRetries); }); diff --git a/fractal-terrain-generation/src/main.js b/fractal-terrain-generation/src/main.js index 8d98d2b..381de65 100644 --- a/fractal-terrain-generation/src/main.js +++ b/fractal-terrain-generation/src/main.js @@ -191,10 +191,11 @@ function setupDemo() { // currently a hack which is used to "fake" concurrency const downScale = 80; const heightFactor = (2 ** tileSize) * 0.8; + const maxHeight = 3; const world = new TileWorld(game, pool, mats, - tileRadius, 2 ** tileSize, downScale, heightFactor, - 0, 0, rootEndpoint, 1000, numFunctions); + tileRadius, maxHeight, 2 ** tileSize, downScale, + heightFactor, 0, 0, rootEndpoint, 1000, numFunctions); // ADD GENS PER SECOND game.setBackgroundColor(new THREE.Color(skyboxColor)); diff --git a/fractal-terrain-generation/src/tile.js b/fractal-terrain-generation/src/tile.js index b9dc3ab..a114169 100644 --- a/fractal-terrain-generation/src/tile.js +++ b/fractal-terrain-generation/src/tile.js @@ -1,8 +1,9 @@ class Tile { - constructor(xPos, zPos) { + constructor(xPos, yPos, zPos) { this.xPos = xPos; + this.yPos = yPos; this.zPos = zPos; - this.key = `${this.xPos},${this.zPos}`; + this.key = `${this.xPos},${this.yPos},${this.zPos}`; this.mesh = undefined; this.stale = false; this.generated = false; @@ -22,6 +23,7 @@ class Tile { if (verbose) { const tileData = JSON.stringify({ x: this.xPos, + y: this.yPos, z: this.zPos, hasMesh: this.mesh !== undefined, generating: this.generating, @@ -29,12 +31,12 @@ class Tile { }); return `Tile info ${tileData}`; } - return `Tile @ x=${this.xPos} z=${this.zPos}`; + return `Tile @ x=${this.xPos} y=${this.yPos} z=${this.zPos}`; } } -function tileKey(x, z) { - return `${x},${z}`; +function tileKey(x, y, z) { + return `${x},${y},${z}`; } // TODO(Ry): change tileKey method of usage diff --git a/fractal-terrain-generation/src/worldGen.js b/fractal-terrain-generation/src/worldGen.js index bdc4cbe..230e758 100644 --- a/fractal-terrain-generation/src/worldGen.js +++ b/fractal-terrain-generation/src/worldGen.js @@ -10,7 +10,7 @@ import { GEN_SUCCESS } from './sharedTypes'; // Allow for buffers longer than their type can express -function createGeomFromBuffer(rawData, xPos, zPos, sizeScalar) { +function createGeomFromBuffer(rawData, xPos, yPos, zPos, sizeScalar) { log.debug(`generating geom from buffer @pos x "${xPos}" z "${zPos}"`); const buffGeom = new THREE.BufferGeometry(); // eslint-disable-next-line no-bitwise @@ -38,7 +38,7 @@ function createGeomFromBuffer(rawData, xPos, zPos, sizeScalar) { class TileWorld { constructor(game, workerPool, materials, radius, - tileSize, downScale, heightFactor, startX, + maxHeight, tileSize, downScale, heightFactor, startX, startZ, rootEndpoint, maxGeomGen = 1000, maxEndpoints = 1) { this.game = game; this.workerPool = workerPool; @@ -47,6 +47,7 @@ class TileWorld { this.tileMap = {}; this.currX = startX; this.currZ = startZ; + this.maxHeight = maxHeight; this.radius = radius; this.tileSize = tileSize; this.downScale = downScale; @@ -82,9 +83,9 @@ class TileWorld { */ this.workerPool.setWorkersMessageEvent((e) => { this.workerPool.releaseWorker(new WorkerHandle(e.data.ID)); - const currTile = this.tileMap[tileKey(e.data.xPos, e.data.zPos)]; + const currTile = this.tileMap[tileKey(e.data.xPos, e.data.yPos, e.data.zPos)]; if (!currTile) { - log.warn(`tile ${tileKey(e.data.xPos, e.data.zPos)} not valid`); + log.warn(`tile ${tileKey(e.data.xPos, e.data.yPos, e.data.zPos)} not valid`); } if (e.data.type === GEN_SUCCESS) { const timeToGen = performance.now() - currTile.genTime; @@ -94,15 +95,15 @@ class TileWorld { this.runningTime += timeToGen; this.totalGenTime += timeToGen; this.totalGens += 1; - log.trace(`finished generation for tile at x "${e.data.xPos}" z "${e.data.zPos}"`); + log.trace(`finished generation for tile at x "${e.data.xPos}" y "${e.data.yPos}" z "${e.data.zPos}"`); // now that our worker has finished its task we can pass the raw // geometry data to the GPU for rendering this.processRawGeom(currTile, e.data); } else { - const { xPos, zPos, data } = e.data; + const { xPos, yPos, zPos, data } = e.data; this.inGen -= 1; currTile.generating = false; - log.error(`Tile at x "${xPos}" z "${zPos}" failed to generate`); + log.error(`Tile at x "${xPos}" y "${yPos}" z "${zPos}" failed to generate`); log.error(data); } }); @@ -200,13 +201,15 @@ class TileWorld { let newZ; let newLoc; for (let i = -this.radius; i < this.radius; i += 1) { - for (let j = -this.radius; j < this.radius; j += 1) { - newX = i + this.currX; - newZ = j + this.currZ; - newLoc = tileKey(newX, newZ); - if (!this.tileMap[newLoc]) { - this.tileMap[newLoc] = new Tile(newX, newZ); - tilesToGen.push(this.tileMap[newLoc]); + for (let j = 0; j < this.maxHeight; j += 1) { + for (let k = -this.radius; k < this.radius; k += 1) { + newX = i + this.currX; + newZ = k + this.currZ; + newLoc = tileKey(newX, j, newZ); + if (!this.tileMap[newLoc]) { + this.tileMap[newLoc] = new Tile(newX, j, newZ); + tilesToGen.push(this.tileMap[newLoc]); + } } } } @@ -241,15 +244,22 @@ class TileWorld { ID: handle.ID, size: this.tileSize, downscale: this.downScale, - heightFactor: this.heightFactor, + heightFactor: (this.maxHeight * this.tileSize), numRetries: 5, xPos: tile.xPos, + yPos: tile.yPos, zPos: tile.zPos, endpoint, }); } async processRawGeom(tile, workerData) { + if (parseInt(workerData.blockCount, 10) === 0) { + tile.generated = true; + tile.generating = false; + this.inGen -= 1; + return; + } // since this may be one of the few operations // on the main thread, care needs to be taken // so we avoid blocking @@ -258,7 +268,7 @@ class TileWorld { } this.inGeomGen += 1; const tileGeom = createGeomFromBuffer(workerData.data, - tile.xPos, tile.zPos, this.sizeScalar); + tile.xPos, tile.yPos, tile.zPos, this.sizeScalar); if (!tile.stale) { const tileMesh = new THREE.Mesh(tileGeom, this.getCurrentMaterial()); tileMesh.name = tile.key; From 6d75f792968378117166d20cfb54678edea4e25b Mon Sep 17 00:00:00 2001 From: Ryland Goldstein Date: Thu, 13 Dec 2018 11:27:09 -0800 Subject: [PATCH 03/14] make deploying modular and fast, new npm scripts --- .../{ => dist}/binaris.yml | 4 ---- fractal-terrain-generation/dist/package.json | 15 +++++++++++++ .../{ => dist}/servePage.js | 2 +- .../fractal_backend/binaris.yml | 5 +++++ .../{ => fractal_backend}/fractal.js | 5 +++-- .../noiseGen.js | 0 .../fractal_backend/package-lock.json | 13 ++++++++++++ .../fractal_backend/package.json | 14 +++++++++++++ .../simplify.js | 0 .../{localserver/server.js => localServer.js} | 2 +- .../localserver/package.json | 14 ------------- fractal-terrain-generation/package.json | 21 +++++++++++++------ 12 files changed, 67 insertions(+), 28 deletions(-) rename fractal-terrain-generation/{ => dist}/binaris.yml (57%) create mode 100644 fractal-terrain-generation/dist/package.json rename fractal-terrain-generation/{ => dist}/servePage.js (96%) create mode 100644 fractal-terrain-generation/fractal_backend/binaris.yml rename fractal-terrain-generation/{ => fractal_backend}/fractal.js (96%) rename fractal-terrain-generation/{function_lib => fractal_backend}/noiseGen.js (100%) create mode 100644 fractal-terrain-generation/fractal_backend/package-lock.json create mode 100644 fractal-terrain-generation/fractal_backend/package.json rename fractal-terrain-generation/{function_lib => fractal_backend}/simplify.js (100%) rename fractal-terrain-generation/{localserver/server.js => localServer.js} (87%) delete mode 100644 fractal-terrain-generation/localserver/package.json diff --git a/fractal-terrain-generation/binaris.yml b/fractal-terrain-generation/dist/binaris.yml similarity index 57% rename from fractal-terrain-generation/binaris.yml rename to fractal-terrain-generation/dist/binaris.yml index 47f2aad..c6619b1 100644 --- a/fractal-terrain-generation/binaris.yml +++ b/fractal-terrain-generation/dist/binaris.yml @@ -1,8 +1,4 @@ functions: - public_fractal: - file: fractal.js - entrypoint: handler - runtime: node8 public_servePage: file: servePage.js entrypoint: handler diff --git a/fractal-terrain-generation/dist/package.json b/fractal-terrain-generation/dist/package.json new file mode 100644 index 0000000..0d8e359 --- /dev/null +++ b/fractal-terrain-generation/dist/package.json @@ -0,0 +1,15 @@ +{ + "name": "fractal-frontend", + "version": "1.0.0", + "description": "", + "main": "servePage.js", + "scripts": {}, + "keywords": [], + "author": "Ryland Goldstein", + "license": "MIT", + "dependencies": { + "mime-types": "^2.1.21", + "mz": "^2.7.0", + "path": "^0.12.7" + } +} diff --git a/fractal-terrain-generation/servePage.js b/fractal-terrain-generation/dist/servePage.js similarity index 96% rename from fractal-terrain-generation/servePage.js rename to fractal-terrain-generation/dist/servePage.js index 890aef6..bbeb807 100644 --- a/fractal-terrain-generation/servePage.js +++ b/fractal-terrain-generation/dist/servePage.js @@ -4,7 +4,7 @@ const fs = require('mz/fs'); const mime = require('mime-types'); const path = require('path'); -const prefix = './dist'; +const prefix = '.'; exports.handler = async (body, ctx) => { let resourcePath = ctx.request.path; diff --git a/fractal-terrain-generation/fractal_backend/binaris.yml b/fractal-terrain-generation/fractal_backend/binaris.yml new file mode 100644 index 0000000..ba18240 --- /dev/null +++ b/fractal-terrain-generation/fractal_backend/binaris.yml @@ -0,0 +1,5 @@ +functions: + public_fractal: + file: fractal.js + entrypoint: handler + runtime: node8 diff --git a/fractal-terrain-generation/fractal.js b/fractal-terrain-generation/fractal_backend/fractal.js similarity index 96% rename from fractal-terrain-generation/fractal.js rename to fractal-terrain-generation/fractal_backend/fractal.js index b27ded9..8ca52ec 100644 --- a/fractal-terrain-generation/fractal.js +++ b/fractal-terrain-generation/fractal_backend/fractal.js @@ -1,6 +1,6 @@ /* eslint-disable no-console,no-bitwise */ -const noiseGen = require('./function_lib/noiseGen'); -const simplify = require('./function_lib/simplify'); +const noiseGen = require('./noiseGen'); +const simplify = require('./simplify'); function makeHeaders(blockCount, maxHeight, payloadBytes, genTime) { @@ -45,6 +45,7 @@ exports.handler = async (body, ctx) => { const genStr = (failedGenTime[0] * 1000) + (failedGenTime[1] / 1000000); headers = makeHeaders(blockCount, maxHeight, 0, genStr); respBody = new Buffer(2); + statusCode = 200; } else { const { verts, indices, normals, tex } = simplify( data, size, size, size, diff --git a/fractal-terrain-generation/function_lib/noiseGen.js b/fractal-terrain-generation/fractal_backend/noiseGen.js similarity index 100% rename from fractal-terrain-generation/function_lib/noiseGen.js rename to fractal-terrain-generation/fractal_backend/noiseGen.js diff --git a/fractal-terrain-generation/fractal_backend/package-lock.json b/fractal-terrain-generation/fractal_backend/package-lock.json new file mode 100644 index 0000000..7b99ba1 --- /dev/null +++ b/fractal-terrain-generation/fractal_backend/package-lock.json @@ -0,0 +1,13 @@ +{ + "name": "fractal_backend", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "simplex-noise": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/simplex-noise/-/simplex-noise-2.4.0.tgz", + "integrity": "sha512-OjyDWm/QZjVbMrPxDVi9b2as+SeNn9EBXlrWVRlFW+TSyWMSXouDryXkQN0vf5YP+QZKobrmkvx1eQYPLtuqfw==" + } + } +} diff --git a/fractal-terrain-generation/fractal_backend/package.json b/fractal-terrain-generation/fractal_backend/package.json new file mode 100644 index 0000000..aa54513 --- /dev/null +++ b/fractal-terrain-generation/fractal_backend/package.json @@ -0,0 +1,14 @@ +{ + "name": "fractal_backend", + "version": "1.0.0", + "description": "Binaris fractal backend function", + "main": "fractal.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Ryland Goldstein", + "license": "ISC", + "dependencies": { + "simplex-noise": "^2.4.0" + } +} diff --git a/fractal-terrain-generation/function_lib/simplify.js b/fractal-terrain-generation/fractal_backend/simplify.js similarity index 100% rename from fractal-terrain-generation/function_lib/simplify.js rename to fractal-terrain-generation/fractal_backend/simplify.js diff --git a/fractal-terrain-generation/localserver/server.js b/fractal-terrain-generation/localServer.js similarity index 87% rename from fractal-terrain-generation/localserver/server.js rename to fractal-terrain-generation/localServer.js index a3cf83a..fb2924a 100644 --- a/fractal-terrain-generation/localserver/server.js +++ b/fractal-terrain-generation/localServer.js @@ -1,6 +1,6 @@ const express = require('express'); -const fractal = require('../fractal'); +const fractal = require('./fractal_backend/fractal'); const app = express(); async function handleReq(req, res) { diff --git a/fractal-terrain-generation/localserver/package.json b/fractal-terrain-generation/localserver/package.json deleted file mode 100644 index e5e7485..0000000 --- a/fractal-terrain-generation/localserver/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "local fractal server", - "version": "1.0.0", - "description": "", - "main": "server.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "ISC", - "dependencies": { - "express": "^4.16.4" - } -} diff --git a/fractal-terrain-generation/package.json b/fractal-terrain-generation/package.json index e973222..70a7c51 100644 --- a/fractal-terrain-generation/package.json +++ b/fractal-terrain-generation/package.json @@ -4,21 +4,29 @@ "description": "", "main": "webpack.config.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "start": "webpack-dev-server", "build": "webpack --config webpack.prod.config.js", - "lint": "./node_modules/.bin/eslint -c .eslintrc.js src/ function_lib/" + "deploy": "npm run deploy_backend && npm run deploy_frontend", + "deploy_backend": "cd fractal_backend && bn deploy public_fractal", + "deploy_frontend": "npm run build && cd dist && bn deploy public_servePage", + "install_deps": "npm run install_dev && npm run install_frontend && npm run install_backend", + "install_backend": "cd fractal_backend && npm install", + "install_dev": "npm install", + "install_frontend": "cd dist && npm install", + "lint": "./node_modules/.bin/eslint -c .eslintrc.js src/ function_lib/", + "local_server": "forever --watch --watchDirectory ./fractal_backend ./localServer.js", + "start": "webpack-dev-server", + "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "Ryland Goldstein", "license": "MIT", "dependencies": { "dat.gui": "^0.7.2", + "forever": "^0.15.3", "loglevel": "^1.6.1", "mime-types": "^2.1.21", "mz": "^2.7.0", "path": "^0.12.7", - "simplex-noise": "^2.4.0", "superagent": "^3.8.3", "three": "^0.94.0" }, @@ -26,15 +34,16 @@ "babel-core": "^6.24.1", "babel-loader": "^7.0.0", "babel-plugin-transform-async-to-generator": "^6.24.1", - "babel-polyfill": "^6.26.0", - "babel-preset-es2016": "^6.24.1", "babel-plugin-transform-runtime": "^6.23.0", + "babel-polyfill": "^6.26.0", "babel-preset-env": "^1.7.0", + "babel-preset-es2016": "^6.24.1", "browser-sync": "^2.18.8", "browser-sync-webpack-plugin": "^1.1.4", "eslint": "^3.14.1", "eslint-config-airbnb-base": "^11.0.1", "eslint-plugin-import": "^2.12.0", + "express": "^4.16.4", "glslify-loader": "^1.0.2", "raw-loader": "^0.5.1", "webpack": "^2.5.1", From 0b50a51fe7f60cbcbf42dd8f4e4ff4ecf27789bd Mon Sep 17 00:00:00 2001 From: Ryland Goldstein Date: Tue, 11 Dec 2018 21:22:26 -0800 Subject: [PATCH 04/14] load textures from our endpoint --- .../dist/resources/brown_red.png | Bin 0 -> 1589 bytes .../dist/resources/dark_blue.png | Bin 0 -> 1589 bytes .../dist/resources/dark_red.png | Bin 0 -> 1591 bytes .../dist/resources/light_blue.png | Bin 0 -> 1590 bytes .../dist/resources/lime_green.png | Bin 0 -> 1590 bytes .../dist/resources/orange.png | Bin 0 -> 1592 bytes .../dist/resources/yellow.png | Bin 0 -> 1590 bytes .../fractal_backend/fractal.js | 14 ++-- .../fractal_backend/simplify.js | 25 +++++-- fractal-terrain-generation/src/gen.worker.js | 16 ++-- fractal-terrain-generation/src/main.js | 4 +- .../src/shaders/internal_compute_shader.frag | 36 +++++++++ .../src/shaders/internal_compute_shader.vert | 15 ++++ .../src/shaders/shader.frag | 9 --- .../src/shaders/shader.vert | 6 -- .../src/shaders/simple_shader.frag | 31 ++++++++ .../src/shaders/simple_shader.vert | 18 +++++ fractal-terrain-generation/src/worldGen.js | 69 ++++++++++++++++-- fractal-terrain-generation/webpack.config.js | 3 +- 19 files changed, 204 insertions(+), 42 deletions(-) create mode 100644 fractal-terrain-generation/dist/resources/brown_red.png create mode 100644 fractal-terrain-generation/dist/resources/dark_blue.png create mode 100644 fractal-terrain-generation/dist/resources/dark_red.png create mode 100644 fractal-terrain-generation/dist/resources/light_blue.png create mode 100644 fractal-terrain-generation/dist/resources/lime_green.png create mode 100644 fractal-terrain-generation/dist/resources/orange.png create mode 100644 fractal-terrain-generation/dist/resources/yellow.png create mode 100644 fractal-terrain-generation/src/shaders/internal_compute_shader.frag create mode 100644 fractal-terrain-generation/src/shaders/internal_compute_shader.vert delete mode 100644 fractal-terrain-generation/src/shaders/shader.frag delete mode 100644 fractal-terrain-generation/src/shaders/shader.vert create mode 100644 fractal-terrain-generation/src/shaders/simple_shader.frag create mode 100644 fractal-terrain-generation/src/shaders/simple_shader.vert diff --git a/fractal-terrain-generation/dist/resources/brown_red.png b/fractal-terrain-generation/dist/resources/brown_red.png new file mode 100644 index 0000000000000000000000000000000000000000..47522eb19a1b1bd192b887d0b664e6437dff764d GIT binary patch literal 1589 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 literal 0 HcmV?d00001 diff --git a/fractal-terrain-generation/dist/resources/dark_red.png b/fractal-terrain-generation/dist/resources/dark_red.png new file mode 100644 index 0000000000000000000000000000000000000000..6564aba366d696697fa116d8f00d42dcacde0531 GIT binary patch literal 1591 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrV3Evpb`HpPc6ZLt$u9~nNK8(3 zPt8j$%1jP&cVb|$=t{ILD;5WQ9GiD(~bllZ9J$)!)5qmN(7Q z?3U7tlyC3O%{Y0^!g%-Jh5oJqHHNQdiyYa%y+J|aEB|e~E&5ZrRBv5T(6HO`qdDM3 z_p;YBt&L}9?%H@S^+^r*PKzr$90LQDGs zakhowfwJ1MD}9*E{JG1wM&EZnR2_fw>fL|y*KT){6;&vdPul!!1$Re3#;r^^_t zeod6Oe-$P7E$PK}Lx&^!RXZLgUq4)ISJ#`F_C)8={&3^@ZMflD z`~u&s*Q;JUU6eGt^zMR<1@9C8&CflU(fT>}@bdFB=i9ZsPmKAkZL0eGVc-$(Rg>ns z{o#0&om;z2=E3c0vnLALvrV{jZ`S%{g6~~o*4$=awQv5CwOhLs>z=omeb#xT+i~9f z`KjQ8H&(Bje00vivLo9~qdtAIW;xKgD|*()<3+!7gXevE{`8gUtkcz%E`NUQsr2|( zTQuMD?aP`MpIfHsvj15+eM+-y2g>H`DotBsQ3;w%o?k;LrAIY{lu&3AmmhR41uYU#}Jttl>zoyk}bz}WL z-p!n>8Z!*q_j370Fbk$=II!IpyOFW7nUBp#WUYu~SNy^>ap~s=Y(80SnR)i$zC%;~ zoj4KS{By^-Em|qcNr2h1+5xboFadm4$P^@{AB$~mHPVnv6{9tI{FeNyM)NOlUm(Kv1G>)&GY_2=2j@+HeZTmCy{pI#Va=kJY7 zUwr?ChK9T>n4&2gmhWq^&r!HX#W|&Cido3_9pRrBDoyo&8k8vzY#l7Ta^n?8{`Sqw z$`<4@{r)3+b!FbBpjVfY@6|FzUbf16&3jg~-22kxB&qdgTGM8|deN~$qV0rFUq*2I zt=uSS*7x_m^naOcw3}ZzTF-sXZ=M7D>_5Kwt@o&J3&S*-hQ{N{c@pPOvEO60_}p@9 z)9r(@6Fq9UA6)tV=G*>XMiq5`ue`i-qLg!!7(@et+h^eLh8xJdS<4M zb_E8;BfLjG+BPseVte#M&Viwjxv+*`p nz|t{ILD;5WQ9GiD(~bllZ9J$)!)5qmN(7Q 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 o&O#=1MKOX_`a6O87aOl*fADYk7S^xk5 literal 0 HcmV?d00001 diff --git a/fractal-terrain-generation/dist/resources/yellow.png b/fractal-terrain-generation/dist/resources/yellow.png new file mode 100644 index 0000000000000000000000000000000000000000..48dfac6b9d2d3a38b7926bd4e4a9228a2f4d8518 GIT binary patch literal 1590 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrV3Evpb`HpPc6ZLt$u9~nNK8(3 zPt8j$%1jP&cVb|$=t{ILD;5WQ9GiD(~bllZ9J$)!)5qmN(7Q z?3U7tlyC3O%{Y0^!g%-Jh5oJqHHNQdiyYa%y+J|aEB|e~E&5ZrRBv5T(6HO`qdDM3 z_p;YBt&L}9?%H@S^+^r*PKzr$90LQDGs zakhowfwJ1MD}9*E{JG1wM&EZnR2_fw>fL|y*KT){6;&vdPul!!1$Re3#;r^^_t zeod6Oe-$P7E$PK}Lx&^!RXZLgUq4)ISJ#`F_C)8={&3^@ZMflD z`~u&s*Q;JUU6eGt^zMR<1@9C8&CflU(fT>}@bdFB=i9ZsPmKAkZL0eGVc-$(Rg>ns z{o#0&om;z2=E3c0vnLALvrV{jZ`S%{g6~~o*4$=awQv5CwOhLs>z=omeb#xT+i~9f z`KjQ8H&(Bje00vivLo9~qdtAIW;xKgD|*()<3+!7gXevE{`8gUtkcz%E`NUQsr2|( zTQuMD?aP`MpIfHsvj15+eM+-y2g>H`DotBsQ3;w%o?k;LrAIY{lu&3AmmhR41uYU#}Jttl>zoyk}bz}WL z-p!n>8Z!*q_j370Fbk$=II!IpyOFW7nUBp#WUYu~SNy^>ap~s=Y(80SnR)i$zC%;~ zoj4KS{By^-Em|qcNr2h1+5xboFadm4$P^@{AB$~mHPVnv6{9tI{FeNyM)NOlUm(Kv1G>)&GY_2=2j@+HeZTmCy{pI#Va=kJY7 zUwr?ChK9T>n4&2gmhWq^&r!HX#W|&Cido3_9pRrBDoyo&8k8vzY#l7Ta^n?8{`Sqw z$`<4@{r)3+b!FbBpjVfY@6|FzUbf16&3jg~-22kxB&qdgTGM8|deN~$qV0rFUq*2I zt=uSS*7x_m^naOcw3}ZzTF-sXZ=M7D>_5Kwt@o&J3&S*-hQ{N{c@pPOvEO60_}p@9 z)9r(@6Fq9UA6)tV=G*>XMiq5`ue`i-qc82ZloC!Ww>sh8>L-``85>?l{QYXXa4IQ|Noo$Rc1aaQr(1 mQ-^fN { const { + downscale, + heightFactor, + numTex, size, xPos, yPos, zPos, - downscale, - heightFactor, } = ctx.request.query; let respBody; @@ -47,17 +48,17 @@ exports.handler = async (body, ctx) => { respBody = new Buffer(2); statusCode = 200; } else { - const { verts, indices, normals, tex } = simplify( + const { indices, mats, normals, tex, verts } = simplify( data, size, size, size, parseInt(xPos, 10), parseInt(yPos, 10), - parseInt(zPos, 10), heightFactor + parseInt(zPos, 10), heightFactor, numTex, ); // how many elements make up the lookup table const tableElements = 4; const mergedData = new Int16Array(verts.length + indices.length - + normals.length + tex.length + tableElements); + + normals.length + tex.length + mats.length + tableElements); // this is an unfortunate bit of logic required to make sure // that our buffers length value doesn't get truncated/overflowed @@ -75,7 +76,8 @@ exports.handler = async (body, ctx) => { mergedData.set(verts, tableElements); mergedData.set(normals, tableElements + verts.length); mergedData.set(tex, tableElements + verts.length + normals.length); - mergedData.set(indices, verts.length + tableElements + normals.length + tex.length); + mergedData.set(mats, tableElements + verts.length + normals.length + tex.length); + mergedData.set(indices, verts.length + tableElements + normals.length + tex.length + mats.length); respBody = Buffer.from(mergedData.buffer); console.log(`buffer size is ${respBody.length / 1000}`); diff --git a/fractal-terrain-generation/fractal_backend/simplify.js b/fractal-terrain-generation/fractal_backend/simplify.js index 63cae51..d4aaec6 100644 --- a/fractal-terrain-generation/fractal_backend/simplify.js +++ b/fractal-terrain-generation/fractal_backend/simplify.js @@ -6,9 +6,18 @@ const WEST = 3; const TOP = 4; const BOTTOM = 5; +function getMat(currHeight, maxHeight, numColors) { + const heightIncr = maxHeight / numColors; + for (let i = 0; i < numColors; i += 1) { + if (currHeight <= i * heightIncr) { + return i; + } + } + return numColors - 1; +} + // Credit to https://0fps.net/2012/06/30/meshing-in-a-minecraft-game/ for // the theory and code structure for this algorithm. - class Vector3 { constructor(x, y, z) { this.x = x; @@ -70,7 +79,7 @@ class BlockFace { * @param {number} yPos - y coordinate offset of geometry * @param {number} zPos - z coordinate offset of geometry */ -function simplify(volume, xSize, ySize, zSize, xPos, yPos, zPos, heightFactor) { +function simplify(volume, xSize, ySize, zSize, xPos, yPos, zPos, heightFactor, numColors) { const nX = [0, 0, xSize - 1, 0, 0, 0]; const nY = [0, 0, 0, 0, ySize - 1, 0]; @@ -119,6 +128,7 @@ function simplify(volume, xSize, ySize, zSize, xPos, yPos, zPos, heightFactor) { const indices = []; let normals = []; const tex = []; + const mats = []; let indexExtend = 0; const x = [0, 0, 0]; @@ -243,18 +253,22 @@ function simplify(volume, xSize, ySize, zSize, xPos, yPos, zPos, heightFactor) { verts.push(x[0] + xPos); // v0 verts.push(x[1] + yPos); verts.push(x[2] + zPos); + mats.push(parseInt(getMat(x[1], heightFactor, numColors), 10) + 0); verts.push(x[0] + du[0] + xPos); // v1 verts.push(x[1] + du[1] + yPos); verts.push(x[2] + du[2] + zPos); + mats.push(parseInt(getMat(x[1] + du[1], heightFactor, numColors), 10) + 0); verts.push(x[0] + dv[0] + xPos); // v2 verts.push(x[1] + dv[1] + yPos); verts.push(x[2] + dv[2] + zPos); + mats.push(parseInt(getMat(x[1] + dv[1], heightFactor, numColors), 10) + 0); verts.push(x[0] + du[0] + dv[0] + xPos); // v3 verts.push(x[1] + du[1] + dv[1] + yPos); verts.push(x[2] + du[2] + dv[2] + zPos); + mats.push(parseInt(getMat(x[1] + du[1] + dv[1], heightFactor, numColors), 10) + 0); tex.push(g); tex.push(0); @@ -342,10 +356,11 @@ function simplify(volume, xSize, ySize, zSize, xPos, yPos, zPos, heightFactor) { calcNormals(); return { - verts, - tex, - normals, indices, + mats, + normals, + tex, + verts, }; } diff --git a/fractal-terrain-generation/src/gen.worker.js b/fractal-terrain-generation/src/gen.worker.js index f5f1ffb..46b1f77 100644 --- a/fractal-terrain-generation/src/gen.worker.js +++ b/fractal-terrain-generation/src/gen.worker.js @@ -26,7 +26,7 @@ const timeMSBetweenRetries = 20; * @param {Number} endpoint - which of the function endpoints to use (if remote gen) */ async function genData(ID, size, xPos, yPos, zPos, - downscale, heightFactor, endpoint, numRetries = 1) { + downscale, heightFactor, numTex, endpoint, numRetries = 1) { const scaledX = xPos * size; const scaledY = yPos * size; const scaledZ = zPos * size; @@ -39,9 +39,10 @@ async function genData(ID, size, xPos, yPos, zPos, const { body, headers } = await request .get(endpoint) .query({ - size, downscale, heightFactor, + numTex, + size, xPos: scaledX, yPos: scaledY, zPos: scaledZ, @@ -89,15 +90,16 @@ async function genData(ID, size, xPos, yPos, zPos, */ thisWorker.addEventListener('message', async (e) => { const { + downscale, + endpoint, + heightFactor, ID, + numRetries, + numTex, size, xPos, yPos, zPos, - endpoint, - numRetries, - downscale, - heightFactor, } = e.data; - genData(ID, size, xPos, yPos, zPos, downscale, heightFactor, endpoint, numRetries); + genData(ID, size, xPos, yPos, zPos, downscale, heightFactor, numTex, endpoint, numRetries); }); diff --git a/fractal-terrain-generation/src/main.js b/fractal-terrain-generation/src/main.js index 381de65..7c743ff 100644 --- a/fractal-terrain-generation/src/main.js +++ b/fractal-terrain-generation/src/main.js @@ -7,7 +7,7 @@ import { Game } from './game'; import TileWorld from './worldGen'; import { WorkerPool } from './workerPool'; -const rootEndpoint = `${process.env.FRACTAL_ENDPOINT}/generate`; +const rootEndpoint = process.env.FRACTAL_ENDPOINT; const defaultTileSize = 4; const defaultTileRadius = 8; @@ -127,7 +127,7 @@ function setupGUIMenus(gui, world, game) { } }); - const numFunctionsEle = gui.add(fullOptions, 'numFunctions').min(1).max(5).step(1); + const numFunctionsEle = gui.add(fullOptions, 'numFunctions').min(1).max(7).step(1); numFunctionsEle.onChange(async (value) => { if (value === world.maxEndpoints) { log.info('value is unchanged'); diff --git a/fractal-terrain-generation/src/shaders/internal_compute_shader.frag b/fractal-terrain-generation/src/shaders/internal_compute_shader.frag new file mode 100644 index 0000000..473c8dd --- /dev/null +++ b/fractal-terrain-generation/src/shaders/internal_compute_shader.frag @@ -0,0 +1,36 @@ +precision highp float; + +varying vec2 vUv; +varying vec3 vNormal; +varying vec3 vPosition; + +uniform vec3 directionalLightColor[1]; +uniform vec3 directionalLightDirection[1]; +uniform sampler2D textures[7]; + +int whichTex() { + float heightIncr = 50.0 / 7.0; + + for (int i = 0; i < 7; i += 1) { + if (vPosition.y <= float(i) * heightIncr) { + return i; + } + } + return 6; +} + +void main() { + vec4 lights = vec4(0.0, 0.0, 0.0, 1.0); + vec4 ambient = vec4(0.4, 0.4, 0.4, 1.0); + vec3 lightVector = normalize(vPosition - vec3(0, 50, 0)); + lights.rgb += clamp(dot(-vec3(0, -1, 0), vNormal), 0.0, 1.0) * vec3(2,2,2); + + int textureIndex = whichTex(); + + for (int k = 0; k < 7; ++k) { + if (textureIndex == k) { + vec4 lerp = texture2D(textures[k], vUv); + gl_FragColor = (lerp * lights) + (lerp * ambient); + } + } +} diff --git a/fractal-terrain-generation/src/shaders/internal_compute_shader.vert b/fractal-terrain-generation/src/shaders/internal_compute_shader.vert new file mode 100644 index 0000000..256321f --- /dev/null +++ b/fractal-terrain-generation/src/shaders/internal_compute_shader.vert @@ -0,0 +1,15 @@ +varying vec3 worldPosition; + +varying vec2 vUv; +varying vec3 vNormal; +varying vec3 vPosition; +varying float vTextureIdx; + +void main() { + vUv = uv; + vNormal = (modelMatrix * vec4(normal, 0.0)).xyz; + vPosition = position; + vec4 mPosition = modelMatrix * vec4(position, 1.0 ); + gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); + worldPosition = mPosition.xyz; +} diff --git a/fractal-terrain-generation/src/shaders/shader.frag b/fractal-terrain-generation/src/shaders/shader.frag deleted file mode 100644 index bbca28c..0000000 --- a/fractal-terrain-generation/src/shaders/shader.frag +++ /dev/null @@ -1,9 +0,0 @@ -uniform vec3 topColor; -uniform vec3 bottomColor; -uniform float offset; -uniform float exponent; -varying vec3 worldPosition; -void main() { - float h = normalize( worldPosition + offset ).y; - gl_FragColor = vec4( mix( bottomColor, topColor, max( pow( h, exponent ), 0.0 ) ), 1.0 ); -} diff --git a/fractal-terrain-generation/src/shaders/shader.vert b/fractal-terrain-generation/src/shaders/shader.vert deleted file mode 100644 index b003441..0000000 --- a/fractal-terrain-generation/src/shaders/shader.vert +++ /dev/null @@ -1,6 +0,0 @@ -varying vec3 worldPosition; -void main() { - vec4 mPosition = modelMatrix * vec4( position, 1.0 ); - gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); - worldPosition = mPosition.xyz; -} diff --git a/fractal-terrain-generation/src/shaders/simple_shader.frag b/fractal-terrain-generation/src/shaders/simple_shader.frag new file mode 100644 index 0000000..99330e8 --- /dev/null +++ b/fractal-terrain-generation/src/shaders/simple_shader.frag @@ -0,0 +1,31 @@ +precision highp float; + +varying vec2 vUv; +varying vec3 vNormal; +varying vec3 vPosition; +varying float vTextureIdx; + +uniform vec3 directionalLightColor[1]; +uniform vec3 directionalLightDirection[1]; +uniform sampler2D textures[7]; + +void main() { + vec4 lights = vec4(0.0, 0.0, 0.0, 1.0); + vec4 ambient = vec4(0.4, 0.4, 0.4, 1.0); + vec3 lightVector = normalize(vPosition - vec3(0, 50, 0)); + lights.rgb += clamp(dot(-vec3(0, -1, 0), vNormal), 0.0, 1.0) * vec3(2,2,2); + + int textureIndex = int(floor(vTextureIdx)); + + for (int k = 0; k < 7; ++k) { + if (textureIndex == k) { + vec4 lowTex = texture2D(textures[k], vUv); + vec4 highTex = vec4(0, 0, 0, 1); + if (k < 6) { + highTex = texture2D(textures[k], vUv); + } + vec4 lerp = mix(lowTex, highTex, vTextureIdx - float(textureIndex)); + gl_FragColor = (lerp * lights) + (lerp * ambient); + } + } +} diff --git a/fractal-terrain-generation/src/shaders/simple_shader.vert b/fractal-terrain-generation/src/shaders/simple_shader.vert new file mode 100644 index 0000000..4268d3d --- /dev/null +++ b/fractal-terrain-generation/src/shaders/simple_shader.vert @@ -0,0 +1,18 @@ +attribute float textureIdx; + +varying vec3 worldPosition; + +varying vec2 vUv; +varying vec3 vNormal; +varying vec3 vPosition; +varying float vTextureIdx; + +void main() { + vTextureIdx = textureIdx; + vUv = uv; + vNormal = (modelMatrix * vec4(normal, 0.0)).xyz; + vPosition = position; + vec4 mPosition = modelMatrix * vec4(position, 1.0 ); + gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); + worldPosition = mPosition.xyz; +} diff --git a/fractal-terrain-generation/src/worldGen.js b/fractal-terrain-generation/src/worldGen.js index 230e758..86b6ac1 100644 --- a/fractal-terrain-generation/src/worldGen.js +++ b/fractal-terrain-generation/src/worldGen.js @@ -8,6 +8,59 @@ import msleep from './msleep'; import { GEN_SUCCESS } from './sharedTypes'; +import VertShader from './shaders/simple_shader.vert'; +import FragShader from './shaders/simple_shader.frag'; + +const loader = new THREE.TextureLoader(); + +const modifiedRemoteEndpoint = process.env.FRACTAL_ENDPOINT.replace('fractal', 'servePage'); +const resEndpoint = `${process.env.FRACTAL_RESOURCE_ENDPOINT || modifiedRemoteEndpoint}/resources`; + +/** + * Needed as of now because of our rate limiting. + */ +function keepTryLoadTex(texURL) { + let loaded = false; + while (!loaded) { + return loader.load(texURL); + } +} + +const lightBlueTex = keepTryLoadTex(`${resEndpoint}/light_blue.png`); +const redBrownTex = keepTryLoadTex(`${resEndpoint}/brown_red.png`); +const yellowTex = keepTryLoadTex(`${resEndpoint}/yellow.png`); +const darkBlueTex = keepTryLoadTex(`${resEndpoint}/dark_blue.png`); +const orangeTex = keepTryLoadTex(`${resEndpoint}/orange.png`); +const limeTex = keepTryLoadTex(`${resEndpoint}/lime_green.png`); +const redTex = keepTryLoadTex(`${resEndpoint}/dark_red.png`); + +const texArray = [ + darkBlueTex, lightBlueTex, limeTex, yellowTex, + orangeTex, redTex, redBrownTex +]; + +const numTex = texArray.length; + +texArray.forEach((tex) => { + tex.wrapS = tex.wrapT = THREE.RepeatWrapping; + tex.repeat.set(2, 2); +}); + +const uniforms = THREE.UniformsUtils.merge([ + THREE.UniformsLib['lights'], { + textures: { + type: 'tv', + value: texArray, + }, + }, +]); + +const shaderMat = new THREE.ShaderMaterial({ + uniforms, + lights: true, + vertexShader: VertShader, + fragmentShader: FragShader, +}); // Allow for buffers longer than their type can express function createGeomFromBuffer(rawData, xPos, yPos, zPos, sizeScalar) { @@ -17,6 +70,7 @@ function createGeomFromBuffer(rawData, xPos, yPos, zPos, sizeScalar) { const numVerts = rawData[0] + (rawData[1] << 16); // eslint-disable-next-line no-bitwise const numTex = rawData[2] + (rawData[3] << 16); + const numMats = numVerts / 3; log.trace(`#verts "${numVerts}" #tex "${numTex}"`); const bytesPerEle = 2; const initOffset = bytesPerEle * 4; @@ -24,13 +78,15 @@ function createGeomFromBuffer(rawData, xPos, yPos, zPos, sizeScalar) { const vertView = new Int16Array(rawData.buffer, initOffset, numVerts); const normView = new Int16Array(rawData.buffer, initOffset + vertOff, numVerts); const texView = new Int16Array(rawData.buffer, initOffset + (2 * vertOff), numTex); + const matsView = new Uint16Array(rawData.buffer, initOffset + (2 * vertOff) + (bytesPerEle * numTex), numMats); const indexView = new Uint16Array(rawData.buffer, - initOffset + (2 * vertOff) + (bytesPerEle * numTex)); + initOffset + (2 * vertOff) + (bytesPerEle * numTex) + (numMats * bytesPerEle)); buffGeom.addAttribute('position', new THREE.Int16BufferAttribute(vertView, 3)); buffGeom.addAttribute('normal', new THREE.Float32BufferAttribute(normView, 3, true)); // TODO(Ry): Get UV coordinates working and enable this buffGeom.addAttribute('uv', new THREE.Int16BufferAttribute(texView, 2)); + buffGeom.addAttribute('textureIdx', new THREE.Int16BufferAttribute(matsView, 1)); buffGeom.setIndex(new THREE.Uint32BufferAttribute(indexView, 1)); buffGeom.scale(sizeScalar, sizeScalar, sizeScalar); return buffGeom; @@ -121,7 +177,7 @@ class TileWorld { const endpoint = this.currEndpoint % this.maxEndpoints; const endpointString = endpoint > 0 ? `${endpoint - 1}` : ''; this.currEndpoint += 1; - return `${this.rootEndpoint}${endpointString}`; + return `${this.rootEndpoint}${endpointString}/generate`; } /** @@ -217,7 +273,7 @@ class TileWorld { tilesToGen.forEach(async (tile) => { this.inGen += 1; tile.generating = true; - this.workerGenTile(tile, this.getAndIncrementEndpoint()); + this.workerGenTile(tile); }); this.updating = false; } @@ -228,7 +284,7 @@ class TileWorld { * @param {object} tile - tile instance to generate data for * @param {number} endpoint - numerical endpoint to use for generation */ - async workerGenTile(tile, endpoint) { + async workerGenTile(tile) { log.trace(`Passing tile gen task to worker using endpoint ${endpoint} for ${tile.describe()}`); const handle = await this.workerPool.getAvailableWorker(); // if we weren't able to get a valid worker or the world is @@ -238,7 +294,7 @@ class TileWorld { tile.generating = false; return; } - + const endpoint = this.getAndIncrementEndpoint() tile.genTime = performance.now(); handle.worker.postMessage({ ID: handle.ID, @@ -246,6 +302,7 @@ class TileWorld { downscale: this.downScale, heightFactor: (this.maxHeight * this.tileSize), numRetries: 5, + numTex, xPos: tile.xPos, yPos: tile.yPos, zPos: tile.zPos, @@ -270,7 +327,7 @@ class TileWorld { const tileGeom = createGeomFromBuffer(workerData.data, tile.xPos, tile.yPos, tile.zPos, this.sizeScalar); if (!tile.stale) { - const tileMesh = new THREE.Mesh(tileGeom, this.getCurrentMaterial()); + const tileMesh = new THREE.Mesh(tileGeom, shaderMat); tileMesh.name = tile.key; log.trace(`adding mesh ${tileMesh.name} to scene`); this.game.addMesh(tileMesh); diff --git a/fractal-terrain-generation/webpack.config.js b/fractal-terrain-generation/webpack.config.js index ef3de68..51fcd39 100644 --- a/fractal-terrain-generation/webpack.config.js +++ b/fractal-terrain-generation/webpack.config.js @@ -71,12 +71,13 @@ module.exports = { 'process.env': { 'FRACTAL_ENDPOINT': JSON.stringify(process.env.FRACTAL_ENDPOINT), + 'FRACTAL_RESOURCE_ENDPOINT': JSON.stringify(process.env.FRACTAL_RESOURCE_ENDPOINT), } } ), ], devServer: { - contentBase: path.resolve(__dirname, 'dist'), + contentBase: [path.resolve(__dirname, 'dist'), path.resolve(__dirname, 'dist/resources')], publicPath: `/v2/run/${process.env.BINARIS_ACCOUNT_NUMBER}/public_servePage/js/`, }, watch: true, From 1c7a155f972cbe7748dbfb9e45f8b83a2b7edc20 Mon Sep 17 00:00:00 2001 From: Ryland Goldstein Date: Fri, 14 Dec 2018 15:29:13 -0800 Subject: [PATCH 05/14] rework asset loading to avoid concurrency issues --- fractal-terrain-generation/src/main.js | 55 ++++++++++--- .../src/textureLoader.js | 49 +++++++++++ fractal-terrain-generation/src/workerPool.js | 4 +- fractal-terrain-generation/src/worldGen.js | 81 ++----------------- 4 files changed, 105 insertions(+), 84 deletions(-) create mode 100644 fractal-terrain-generation/src/textureLoader.js diff --git a/fractal-terrain-generation/src/main.js b/fractal-terrain-generation/src/main.js index 7c743ff..5775c39 100644 --- a/fractal-terrain-generation/src/main.js +++ b/fractal-terrain-generation/src/main.js @@ -3,9 +3,13 @@ import * as THREE from 'three'; import * as dat from 'dat.gui'; import * as log from 'loglevel'; +import VertShader from './shaders/simple_shader.vert'; +import FragShader from './shaders/simple_shader.frag'; + import { Game } from './game'; import TileWorld from './worldGen'; import { WorkerPool } from './workerPool'; +import loadTextures from './textureLoader'; const rootEndpoint = process.env.FRACTAL_ENDPOINT; @@ -27,6 +31,16 @@ const guiOptions = { const currPos = { x: 0, z: 0 }; +const textureMap = { + lightBlueTex: 'light_blue.png', + redBrownTex: 'brown_red.png', + yellowTex: 'yellow.png', + darkBlueTex: 'dark_blue.png', + orangeTex: 'orange.png', + limeTex: 'lime_green.png', + redTex: 'dark_red.png', +}; + const mats = [ new THREE.MeshNormalMaterial({ side: THREE.FrontSide, @@ -140,7 +154,7 @@ function setupGUIMenus(gui, world, game) { // enable/disable wireframe rendering const wireframeEle = gui.add(fullOptions, 'wireframe'); wireframeEle.onChange(() => { - world.updateMaterials(); + world.updateMaterial(); }); // choose from accepted values @@ -179,7 +193,13 @@ function createGUI(gui) { * * @return {object} - the fully configured game instance */ -function setupDemo() { +async function setupDemo() { + const maxTexLoadTries = 5; + const texLoadRetryDelay = 3; + // kick start texture loading to avoid initial delay + const inLoading = loadTextures(textureMap, + maxTexLoadTries, texLoadRetryDelay); + const gui = new dat.gui.GUI(); const savedConfig = createGUI(gui); @@ -188,13 +208,30 @@ function setupDemo() { tileRadius, skyboxColor } = savedConfig; const pool = new WorkerPool(numWorkers, 1); + const texArray = await inLoading; + const uniforms = THREE.UniformsUtils.merge([ + THREE.UniformsLib['lights'], { + textures: { + type: 'tv', + value: texArray, + }, + }, + ]); + + const terrainMaterial = new THREE.ShaderMaterial({ + uniforms, + lights: true, + vertexShader: VertShader, + fragmentShader: FragShader, + }); + // currently a hack which is used to "fake" concurrency const downScale = 80; const heightFactor = (2 ** tileSize) * 0.8; - const maxHeight = 3; + const maxHeight = 1; - const world = new TileWorld(game, pool, mats, - tileRadius, maxHeight, 2 ** tileSize, downScale, + const world = new TileWorld(game, pool, terrainMaterial, + texArray.length, tileRadius, maxHeight, 2 ** tileSize, downScale, heightFactor, 0, 0, rootEndpoint, 1000, numFunctions); // ADD GENS PER SECOND @@ -225,7 +262,7 @@ function setupDemo() { function onDocumentKeyDown(event) { const keyCode = event.which; if (keyCode === 77) { - world.updateMaterials(); + world.updateMaterial(); } if (keyCode === 82) { world.drain(); @@ -238,6 +275,6 @@ function setupDemo() { return game; } -const game = setupDemo(); - -game.animate(); +Promise.resolve(setupDemo()).then((game) => { + game.animate(); +}); diff --git a/fractal-terrain-generation/src/textureLoader.js b/fractal-terrain-generation/src/textureLoader.js new file mode 100644 index 0000000..c3ea67d --- /dev/null +++ b/fractal-terrain-generation/src/textureLoader.js @@ -0,0 +1,49 @@ +import * as THREE from 'three'; +import * as log from 'loglevel'; + +import msleep from './msleep'; + +const loader = new THREE.TextureLoader(); + +const modifiedRemoteEndpoint = process.env.FRACTAL_ENDPOINT.replace('fractal', 'servePage'); +const resEndpoint = `${process.env.FRACTAL_RESOURCE_ENDPOINT || modifiedRemoteEndpoint}/resources`; + +/** + * Needed as of now because of our rate limiting. + */ +async function loadUntilSuccess(texURL, maxRetries, retryDelay) { + for (let i = 0; i < maxRetries; i += 1) { + try { + return await (new Promise((resolve, reject) => { + function onLoad(tex) { + return resolve(tex); + } + function onError(err) { + return reject(err); + } + loader.load(texURL, onLoad, undefined, onError); + })); + } catch (err) { + log.debug(`err loading texture ${texURL}, ${err}`); + await msleep(retryDelay); + } + } + throw new Error(`Unable to load texture ${texURL}`); +} + +module.exports = async function loadTextures(texMap, maxRetries, retryDelay) { + const texArray = []; + const textureKeys = Object.keys(texMap); + for (let i = 0; i < textureKeys.length; i += 1) { + const texKey = textureKeys[i]; + const texURL = `${resEndpoint}/${texMap[texKey]}`; + texArray.push(await loadUntilSuccess(texURL, maxRetries)); + } + + texArray.forEach((tex) => { + tex.wrapS = tex.wrapT = THREE.RepeatWrapping; + tex.repeat.set(2, 2); + }); + + return texArray; +} diff --git a/fractal-terrain-generation/src/workerPool.js b/fractal-terrain-generation/src/workerPool.js index 240538f..27963d8 100644 --- a/fractal-terrain-generation/src/workerPool.js +++ b/fractal-terrain-generation/src/workerPool.js @@ -94,7 +94,7 @@ class WorkerPool { this.workers.forEach(worker => (worker.onmessage = msgEventFunction)); } - changeNumWorkers(numWorkers) { + async changeNumWorkers(numWorkers) { if (this.adjusting) return false; if (numWorkers === this.numWorkers) return true; @@ -108,6 +108,8 @@ class WorkerPool { addedWorker.onmessage = this.onMessage; this.workers.push(addedWorker); this.workersAvailable.push(0); + // TODO(Ry): remove this once concurrent loading is fixed:w + await msleep(100); } this.numWorkers = numWorkers; this.adjusting = false; diff --git a/fractal-terrain-generation/src/worldGen.js b/fractal-terrain-generation/src/worldGen.js index 86b6ac1..286b89b 100644 --- a/fractal-terrain-generation/src/worldGen.js +++ b/fractal-terrain-generation/src/worldGen.js @@ -8,60 +8,6 @@ import msleep from './msleep'; import { GEN_SUCCESS } from './sharedTypes'; -import VertShader from './shaders/simple_shader.vert'; -import FragShader from './shaders/simple_shader.frag'; - -const loader = new THREE.TextureLoader(); - -const modifiedRemoteEndpoint = process.env.FRACTAL_ENDPOINT.replace('fractal', 'servePage'); -const resEndpoint = `${process.env.FRACTAL_RESOURCE_ENDPOINT || modifiedRemoteEndpoint}/resources`; - -/** - * Needed as of now because of our rate limiting. - */ -function keepTryLoadTex(texURL) { - let loaded = false; - while (!loaded) { - return loader.load(texURL); - } -} - -const lightBlueTex = keepTryLoadTex(`${resEndpoint}/light_blue.png`); -const redBrownTex = keepTryLoadTex(`${resEndpoint}/brown_red.png`); -const yellowTex = keepTryLoadTex(`${resEndpoint}/yellow.png`); -const darkBlueTex = keepTryLoadTex(`${resEndpoint}/dark_blue.png`); -const orangeTex = keepTryLoadTex(`${resEndpoint}/orange.png`); -const limeTex = keepTryLoadTex(`${resEndpoint}/lime_green.png`); -const redTex = keepTryLoadTex(`${resEndpoint}/dark_red.png`); - -const texArray = [ - darkBlueTex, lightBlueTex, limeTex, yellowTex, - orangeTex, redTex, redBrownTex -]; - -const numTex = texArray.length; - -texArray.forEach((tex) => { - tex.wrapS = tex.wrapT = THREE.RepeatWrapping; - tex.repeat.set(2, 2); -}); - -const uniforms = THREE.UniformsUtils.merge([ - THREE.UniformsLib['lights'], { - textures: { - type: 'tv', - value: texArray, - }, - }, -]); - -const shaderMat = new THREE.ShaderMaterial({ - uniforms, - lights: true, - vertexShader: VertShader, - fragmentShader: FragShader, -}); - // Allow for buffers longer than their type can express function createGeomFromBuffer(rawData, xPos, yPos, zPos, sizeScalar) { log.debug(`generating geom from buffer @pos x "${xPos}" z "${zPos}"`); @@ -93,13 +39,13 @@ function createGeomFromBuffer(rawData, xPos, yPos, zPos, sizeScalar) { } class TileWorld { - constructor(game, workerPool, materials, radius, + constructor(game, workerPool, material, numTex, radius, maxHeight, tileSize, downScale, heightFactor, startX, startZ, rootEndpoint, maxGeomGen = 1000, maxEndpoints = 1) { this.game = game; this.workerPool = workerPool; - this.materials = materials; - this.currMaterial = 0; + this.material = material; + this.numTex = numTex; this.tileMap = {}; this.currX = startX; this.currZ = startZ; @@ -302,7 +248,7 @@ class TileWorld { downscale: this.downScale, heightFactor: (this.maxHeight * this.tileSize), numRetries: 5, - numTex, + numTex: this.numTex, xPos: tile.xPos, yPos: tile.yPos, zPos: tile.zPos, @@ -327,7 +273,7 @@ class TileWorld { const tileGeom = createGeomFromBuffer(workerData.data, tile.xPos, tile.yPos, tile.zPos, this.sizeScalar); if (!tile.stale) { - const tileMesh = new THREE.Mesh(tileGeom, shaderMat); + const tileMesh = new THREE.Mesh(tileGeom, this.material); tileMesh.name = tile.key; log.trace(`adding mesh ${tileMesh.name} to scene`); this.game.addMesh(tileMesh); @@ -339,21 +285,8 @@ class TileWorld { tile.generating = false; } - getCurrentMaterial() { - const mat = this.materials[this.currMaterial % this.materials.length]; - return mat; - } - - updateMaterials() { - this.currMaterial += 1; - const mat = this.materials[this.currMaterial % this.materials.length]; - Object.keys(this.tileMap).forEach((keyForTile) => { - const tileObj = this.game.getObject(keyForTile); - if (tileObj) { - tileObj.material = mat; - tileObj.material.needsUpdate = true; - } - }); + updateMaterial() { + this.material.wireframe = !this.material.wireframe; } avgGenTime() { From 80e728bf188d13459aa803d61a89b6569cfa89e1 Mon Sep 17 00:00:00 2001 From: Ryland Goldstein Date: Sat, 15 Dec 2018 15:21:05 -0800 Subject: [PATCH 06/14] try and simplify user experience --- fractal-terrain-generation/.gitignore | 1 + fractal-terrain-generation/builder.js | 62 +++++++++++++++++++ fractal-terrain-generation/dist/servePage.js | 3 +- fractal-terrain-generation/package.json | 3 + .../{dist/index.html => template.html} | 0 fractal-terrain-generation/webpack.config.js | 19 +++--- .../webpack.prod.config.js | 12 +++- 7 files changed, 89 insertions(+), 11 deletions(-) create mode 100644 fractal-terrain-generation/builder.js rename fractal-terrain-generation/{dist/index.html => template.html} (100%) diff --git a/fractal-terrain-generation/.gitignore b/fractal-terrain-generation/.gitignore index 893afd5..9ea7034 100644 --- a/fractal-terrain-generation/.gitignore +++ b/fractal-terrain-generation/.gitignore @@ -1 +1,2 @@ dist/js +dist/index.html diff --git a/fractal-terrain-generation/builder.js b/fractal-terrain-generation/builder.js new file mode 100644 index 0000000..741c246 --- /dev/null +++ b/fractal-terrain-generation/builder.js @@ -0,0 +1,62 @@ +const replace = require('replace-in-file'); +const fse = require('fs-extra'); +const path = require('path'); + +const YMLUtil = require('binaris/lib/binarisYML'); + +const { getAccountId, getAPIKey } = require('binaris/lib/userConf'); + +const backendYAMLPath = path.join(__dirname, 'fractal_backend'); +const servingYAMLPath = path.join(__dirname, 'dist'); + +async function getServingFuncName() { + const binarisConf = await YMLUtil.loadBinarisConf(servingYAMLPath); + return YMLUtil.getFuncName(binarisConf); +} + +async function getBackendFuncName() { + const binarisConf = await YMLUtil.loadBinarisConf(backendYAMLPath); + return YMLUtil.getFuncName(binarisConf); +} + +async function getPublicPath(accountID, endpoint) { + process.env.BINARIS_INVOKE_ENDPOINT = endpoint; + const { getInvokeUrl } = require('binaris/sdk/url'); + const servingName = await getServingFuncName(); + const savedEndpoint = process.env.BINARIS_INVOKE_ENDPOINT; + const invokeURL = await getInvokeUrl(accountID, servingName); + process.env.BINARIS_INVOKE_ENDPOINT = savedEndpoint; + return invokeURL; +} + +async function getFractalURL(accountID) { + const { getInvokeUrl } = require('binaris/sdk/url'); + const backendName = await getBackendFuncName(); + return getInvokeUrl(accountID, backendName); +} + +async function replaceHTMLAccountID(accountID) { + const templatePath = path.join(__dirname, 'template.html'); + const destPath = path.join(__dirname, 'dist', 'index.html'); + await fse.copy(templatePath, destPath, { overwrite: true, errorOnExist: false }); + + const options = { + files: destPath, + from: //g, + to: accountID, + }; + await replace(options) +} + +async function prebuild() { + const accountID = await getAccountId(undefined); + await replaceHTMLAccountID(accountID); + const FRACTAL_ENDPOINT = await getFractalURL(accountID); + const PUBLIC_PATH = (await getPublicPath(accountID, ' ')).slice(8); + return { + FRACTAL_ENDPOINT, + PUBLIC_PATH, + }; +} + +module.exports = { prebuild }; diff --git a/fractal-terrain-generation/dist/servePage.js b/fractal-terrain-generation/dist/servePage.js index bbeb807..4e98ba2 100644 --- a/fractal-terrain-generation/dist/servePage.js +++ b/fractal-terrain-generation/dist/servePage.js @@ -22,7 +22,8 @@ exports.handler = async (body, ctx) => { statusCode: 200, headers: { 'Content-Type': resourceType, - 'Access-Control-Allow-Headers': 'X-Requested-With, Content-Type, Accept', + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept', }, body: webpage, }); diff --git a/fractal-terrain-generation/package.json b/fractal-terrain-generation/package.json index 70a7c51..6be83a9 100644 --- a/fractal-terrain-generation/package.json +++ b/fractal-terrain-generation/package.json @@ -21,12 +21,15 @@ "author": "Ryland Goldstein", "license": "MIT", "dependencies": { + "binaris": "binaris/binaris#feature-updated-endpoints", "dat.gui": "^0.7.2", "forever": "^0.15.3", + "fs-extra": "^7.0.1", "loglevel": "^1.6.1", "mime-types": "^2.1.21", "mz": "^2.7.0", "path": "^0.12.7", + "replace-in-file": "^3.4.2", "superagent": "^3.8.3", "three": "^0.94.0" }, diff --git a/fractal-terrain-generation/dist/index.html b/fractal-terrain-generation/template.html similarity index 100% rename from fractal-terrain-generation/dist/index.html rename to fractal-terrain-generation/template.html diff --git a/fractal-terrain-generation/webpack.config.js b/fractal-terrain-generation/webpack.config.js index 51fcd39..a9977b9 100644 --- a/fractal-terrain-generation/webpack.config.js +++ b/fractal-terrain-generation/webpack.config.js @@ -2,11 +2,16 @@ const webpack = require('webpack'); const path = require('path'); const BrowserSyncPlugin = require('browser-sync-webpack-plugin'); -module.exports = { +const { prebuild } = require('./builder'); +const localResourceEndpoint = 'http://localhost:3001'; + +module.exports = async () => { + const { FRACTAL_ENDPOINT, PUBLIC_PATH } = await prebuild(); + return { entry: [ 'babel-polyfill', './src/gen.worker.js', './src/main.js' ], output: { path: path.resolve(__dirname, 'dist/js'), - publicPath: `/v2/run/${process.env.BINARIS_ACCOUNT_NUMBER}/public_servePage/js/`, + publicPath: `${PUBLIC_PATH}/js`, filename: 'three.bundle.js' }, module: { @@ -24,8 +29,7 @@ module.exports = { options: { presets: ['env'] } - } - }, + } }, { test: /\.(glsl|frag|vert)$/, loader: 'raw-loader', @@ -70,16 +74,17 @@ module.exports = { { 'process.env': { - 'FRACTAL_ENDPOINT': JSON.stringify(process.env.FRACTAL_ENDPOINT), - 'FRACTAL_RESOURCE_ENDPOINT': JSON.stringify(process.env.FRACTAL_RESOURCE_ENDPOINT), + FRACTAL_ENDPOINT: JSON.stringify(FRACTAL_ENDPOINT), + FRACTAL_RESOURCE_ENDPOINT: JSON.stringify(localResourceEndpoint), } } ), ], devServer: { contentBase: [path.resolve(__dirname, 'dist'), path.resolve(__dirname, 'dist/resources')], - publicPath: `/v2/run/${process.env.BINARIS_ACCOUNT_NUMBER}/public_servePage/js/`, + publicPath: `${PUBLIC_PATH}/js`, }, watch: true, devtool: 'cheap-eval-source-map' + }; } diff --git a/fractal-terrain-generation/webpack.prod.config.js b/fractal-terrain-generation/webpack.prod.config.js index 8ec3d9b..89f5fc2 100644 --- a/fractal-terrain-generation/webpack.prod.config.js +++ b/fractal-terrain-generation/webpack.prod.config.js @@ -2,11 +2,15 @@ const webpack = require('webpack'); const path = require('path'); const BrowserSyncPlugin = require('browser-sync-webpack-plugin'); -module.exports = { +const { prebuild } = require('./builder'); + +module.exports = async () => { + const { FRACTAL_ENDPOINT, PUBLIC_PATH } = await prebuild(); + return { entry: [ 'babel-polyfill', './src/gen.worker.js', './src/main.js' ], output: { path: path.resolve(__dirname, 'dist/js'), - publicPath: `/v2/run/${process.env.BINARIS_ACCOUNT_NUMBER}/public_servePage/js/`, + publicPath: `${PUBLIC_PATH}/js/`, filename: 'three.bundle.js' }, module: { @@ -47,9 +51,11 @@ module.exports = { { 'process.env': { - 'FRACTAL_ENDPOINT': JSON.stringify(process.env.FRACTAL_ENDPOINT), + FRACTAL_ENDPOINT: JSON.stringify(FRACTAL_ENDPOINT), } } ), ], + }; } + From f2a2a47f65ea55ad141741e590c6508fc096a83f Mon Sep 17 00:00:00 2001 From: Ryland Goldstein Date: Sat, 15 Dec 2018 15:29:37 -0800 Subject: [PATCH 07/14] update README --- fractal-terrain-generation/README.md | 15 +++++++-------- fractal-terrain-generation/package.json | 1 - 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/fractal-terrain-generation/README.md b/fractal-terrain-generation/README.md index f37e6fb..bbea32b 100644 --- a/fractal-terrain-generation/README.md +++ b/fractal-terrain-generation/README.md @@ -2,15 +2,14 @@ Demo originally created for talk given by Ryland Goldstein at _Serverless conf 2018_ in San Francisco. -1. Replace in `dist/index.html` with your account number. -1. Export `BINARIS_ACCOUNT_NUMBER` to your environment -1. Run the following command - `export FRACTAL_ENDPOINT=https://run-sandbox.binaris.com/v2/run/${BINARIS_ACCOUNT_NUMBER}/public_fractal` -1. Run `npm install` -1. Run `bn deploy public_fractal` -1. Run `npm run build` -1. Run `bn deploy public_servePage` +1. If you haven't run `bn login` before, do so +1. Run `npm run install_deps` +1. Run `npm run deploy` 1. Navigate to the generated Binaris function URL for `servePage` in your browser For even faster generation consider upgrading to the Binaris paid tier. + +If you made changes to the frontend (anything in `src`) simply run `npm run deploy_frontend` + +For backend changes run `npm run deploy_backend` \ No newline at end of file diff --git a/fractal-terrain-generation/package.json b/fractal-terrain-generation/package.json index 6be83a9..9efc5ce 100644 --- a/fractal-terrain-generation/package.json +++ b/fractal-terrain-generation/package.json @@ -10,7 +10,6 @@ "deploy_frontend": "npm run build && cd dist && bn deploy public_servePage", "install_deps": "npm run install_dev && npm run install_frontend && npm run install_backend", "install_backend": "cd fractal_backend && npm install", - "install_dev": "npm install", "install_frontend": "cd dist && npm install", "lint": "./node_modules/.bin/eslint -c .eslintrc.js src/ function_lib/", "local_server": "forever --watch --watchDirectory ./fractal_backend ./localServer.js", From 2ef49bd86a86405062b05fadbe0c18972d741651 Mon Sep 17 00:00:00 2001 From: Ryland Goldstein Date: Sat, 15 Dec 2018 15:43:25 -0800 Subject: [PATCH 08/14] force realm in builder --- fractal-terrain-generation/builder.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fractal-terrain-generation/builder.js b/fractal-terrain-generation/builder.js index 741c246..f675441 100644 --- a/fractal-terrain-generation/builder.js +++ b/fractal-terrain-generation/builder.js @@ -4,7 +4,8 @@ const path = require('path'); const YMLUtil = require('binaris/lib/binarisYML'); -const { getAccountId, getAPIKey } = require('binaris/lib/userConf'); +const { getAccountId, getAPIKey, getRealm } = require('binaris/lib/userConf'); +const { forceRealm } = require('binaris/sdk'); const backendYAMLPath = path.join(__dirname, 'fractal_backend'); const servingYAMLPath = path.join(__dirname, 'dist'); @@ -49,6 +50,10 @@ async function replaceHTMLAccountID(accountID) { } async function prebuild() { + const realm = await getRealm(); + if (realm) { + forceRealm(realm); + } const accountID = await getAccountId(undefined); await replaceHTMLAccountID(accountID); const FRACTAL_ENDPOINT = await getFractalURL(accountID); From 942adcab70b21532b2b3d42cdd7d247ad0266e38 Mon Sep 17 00:00:00 2001 From: Ryland Goldstein Date: Sat, 15 Dec 2018 15:56:17 -0800 Subject: [PATCH 09/14] fix mistake in package.json --- fractal-terrain-generation/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fractal-terrain-generation/package.json b/fractal-terrain-generation/package.json index 9efc5ce..31f3993 100644 --- a/fractal-terrain-generation/package.json +++ b/fractal-terrain-generation/package.json @@ -8,7 +8,7 @@ "deploy": "npm run deploy_backend && npm run deploy_frontend", "deploy_backend": "cd fractal_backend && bn deploy public_fractal", "deploy_frontend": "npm run build && cd dist && bn deploy public_servePage", - "install_deps": "npm run install_dev && npm run install_frontend && npm run install_backend", + "install_deps": "npm install && npm run install_frontend && npm run install_backend", "install_backend": "cd fractal_backend && npm install", "install_frontend": "cd dist && npm install", "lint": "./node_modules/.bin/eslint -c .eslintrc.js src/ function_lib/", From 51ea0cefa7a8bbf495189e08f9fab04bb02a860a Mon Sep 17 00:00:00 2001 From: Ryland Goldstein Date: Sat, 15 Dec 2018 22:41:42 -0800 Subject: [PATCH 10/14] Fix materials on PC --- .../fractal_backend/fractal.js | 2 +- .../fractal_backend/noiseGen.js | 17 ++++++++++-- .../fractal_backend/simplify.js | 27 ++++++++----------- .../src/shaders/simple_shader.frag | 12 +++------ .../src/shaders/simple_shader.vert | 2 +- 5 files changed, 31 insertions(+), 29 deletions(-) diff --git a/fractal-terrain-generation/fractal_backend/fractal.js b/fractal-terrain-generation/fractal_backend/fractal.js index 0846588..049550e 100644 --- a/fractal-terrain-generation/fractal_backend/fractal.js +++ b/fractal-terrain-generation/fractal_backend/fractal.js @@ -39,7 +39,7 @@ exports.handler = async (body, ctx) => { const { blockCount, data, maxHeight } = noiseGen( parseInt(xPos, 10), parseInt(yPos, 10), parseInt(zPos, 10), parseInt(size, 10), - downscale, parseInt(heightFactor, 10) + numTex, downscale, parseInt(heightFactor, 10) ); if (blockCount === 0) { const failedGenTime = process.hrtime(genStartTime); diff --git a/fractal-terrain-generation/fractal_backend/noiseGen.js b/fractal-terrain-generation/fractal_backend/noiseGen.js index 548e2c4..a6e3c17 100644 --- a/fractal-terrain-generation/fractal_backend/noiseGen.js +++ b/fractal-terrain-generation/fractal_backend/noiseGen.js @@ -2,6 +2,16 @@ const SimplexNoise = require('simplex-noise'); const simplex = new SimplexNoise('default'); +function getMat(currHeight, maxHeight, numColors) { + const heightIncr = maxHeight / numColors; + for (let i = 0; i < numColors; i += 1) { + if (currHeight <= i * heightIncr) { + return i; + } + } + return numColors - 1; +} + /** * Create a volumetric density field representing the state * of a given region of terrain. @@ -14,7 +24,7 @@ const simplex = new SimplexNoise('default'); * @param {number} scaleHeight - sets the defacto maxHeight of the volume * @return {object} - generated data and metadata */ -function createDensities(cX, cY, cZ, size, downscale = 1000, scaleHeight = 50) { +function createDensities(cX, cY, cZ, size, numColors, downscale = 1000, scaleHeight = 50) { let maxHeight = -1; let minHeight = 10000; let blockCount = 0; @@ -66,7 +76,10 @@ function createDensities(cX, cY, cZ, size, downscale = 1000, scaleHeight = 50) { for (let k = 0; k < size; k += 1) { currIdx = i + (j * size) + (k * size * size); densities[currIdx] = ((j + cY) <= heights[i + (k * size)]) ? 1 : 0; - blockCount += densities[currIdx]; + if (densities[currIdx] !== 0) { + densities[currIdx] = getMat(j + cY, scaleHeight, numColors); + blockCount += 1; + } } } } diff --git a/fractal-terrain-generation/fractal_backend/simplify.js b/fractal-terrain-generation/fractal_backend/simplify.js index d4aaec6..5d8dd22 100644 --- a/fractal-terrain-generation/fractal_backend/simplify.js +++ b/fractal-terrain-generation/fractal_backend/simplify.js @@ -6,16 +6,6 @@ const WEST = 3; const TOP = 4; const BOTTOM = 5; -function getMat(currHeight, maxHeight, numColors) { - const heightIncr = maxHeight / numColors; - for (let i = 0; i < numColors; i += 1) { - if (currHeight <= i * heightIncr) { - return i; - } - } - return numColors - 1; -} - // Credit to https://0fps.net/2012/06/30/meshing-in-a-minecraft-game/ for // the theory and code structure for this algorithm. class Vector3 { @@ -89,8 +79,13 @@ function simplify(volume, xSize, ySize, zSize, xPos, yPos, zPos, heightFactor, n const cZ = [1, -1, 0, 0, 0, 0]; const faces = new Array(xSize * ySize * zSize); - for (let i = 0; i < volume.length; i += 1) { - faces[i] = new BlockFace(volume[i]); + for (let x0 = 0; x0 < xSize; x0++) { + for (let y0 = 0; y0 < ySize; y0++) { + for (let z0 = 0; z0 < zSize; z0++) { + const sharedIDX = x0 + (y0 * xSize) + (z0 * xSize * ySize); + faces[sharedIDX] = new BlockFace(volume[sharedIDX]); + } + } } function getBlockData(x, y, z) { @@ -253,22 +248,22 @@ function simplify(volume, xSize, ySize, zSize, xPos, yPos, zPos, heightFactor, n verts.push(x[0] + xPos); // v0 verts.push(x[1] + yPos); verts.push(x[2] + zPos); - mats.push(parseInt(getMat(x[1], heightFactor, numColors), 10) + 0); + mats.push(mask[n].type); verts.push(x[0] + du[0] + xPos); // v1 verts.push(x[1] + du[1] + yPos); verts.push(x[2] + du[2] + zPos); - mats.push(parseInt(getMat(x[1] + du[1], heightFactor, numColors), 10) + 0); + mats.push(mask[n].type); verts.push(x[0] + dv[0] + xPos); // v2 verts.push(x[1] + dv[1] + yPos); verts.push(x[2] + dv[2] + zPos); - mats.push(parseInt(getMat(x[1] + dv[1], heightFactor, numColors), 10) + 0); + mats.push(mask[n].type); verts.push(x[0] + du[0] + dv[0] + xPos); // v3 verts.push(x[1] + du[1] + dv[1] + yPos); verts.push(x[2] + du[2] + dv[2] + zPos); - mats.push(parseInt(getMat(x[1] + du[1] + dv[1], heightFactor, numColors), 10) + 0); + mats.push(mask[n].type); tex.push(g); tex.push(0); diff --git a/fractal-terrain-generation/src/shaders/simple_shader.frag b/fractal-terrain-generation/src/shaders/simple_shader.frag index 99330e8..6a105b0 100644 --- a/fractal-terrain-generation/src/shaders/simple_shader.frag +++ b/fractal-terrain-generation/src/shaders/simple_shader.frag @@ -15,17 +15,11 @@ void main() { vec3 lightVector = normalize(vPosition - vec3(0, 50, 0)); lights.rgb += clamp(dot(-vec3(0, -1, 0), vNormal), 0.0, 1.0) * vec3(2,2,2); - int textureIndex = int(floor(vTextureIdx)); - for (int k = 0; k < 7; ++k) { - if (textureIndex == k) { + if (vTextureIdx - float(k) <= 0.1) { vec4 lowTex = texture2D(textures[k], vUv); - vec4 highTex = vec4(0, 0, 0, 1); - if (k < 6) { - highTex = texture2D(textures[k], vUv); - } - vec4 lerp = mix(lowTex, highTex, vTextureIdx - float(textureIndex)); - gl_FragColor = (lerp * lights) + (lerp * ambient); + gl_FragColor = (lowTex * lights) + (lowTex * ambient); + break; } } } diff --git a/fractal-terrain-generation/src/shaders/simple_shader.vert b/fractal-terrain-generation/src/shaders/simple_shader.vert index 4268d3d..09c1066 100644 --- a/fractal-terrain-generation/src/shaders/simple_shader.vert +++ b/fractal-terrain-generation/src/shaders/simple_shader.vert @@ -14,5 +14,5 @@ void main() { vPosition = position; vec4 mPosition = modelMatrix * vec4(position, 1.0 ); gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); - worldPosition = mPosition.xyz; + worldPosition = position; } From 2fc4d0b2dc715607399daa47e5c4ed039a6f5f72 Mon Sep 17 00:00:00 2001 From: Ryland Goldstein Date: Sat, 15 Dec 2018 22:41:56 -0800 Subject: [PATCH 11/14] bump up time again to avoid 429 --- fractal-terrain-generation/src/workerPool.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fractal-terrain-generation/src/workerPool.js b/fractal-terrain-generation/src/workerPool.js index 27963d8..ec451c2 100644 --- a/fractal-terrain-generation/src/workerPool.js +++ b/fractal-terrain-generation/src/workerPool.js @@ -109,7 +109,7 @@ class WorkerPool { this.workers.push(addedWorker); this.workersAvailable.push(0); // TODO(Ry): remove this once concurrent loading is fixed:w - await msleep(100); + await msleep(400); } this.numWorkers = numWorkers; this.adjusting = false; From f0bad0bd818a178d252687167f97efe15898cf49 Mon Sep 17 00:00:00 2001 From: Ryland Goldstein Date: Mon, 17 Dec 2018 09:50:02 -0800 Subject: [PATCH 12/14] fix env var bug in builder --- fractal-terrain-generation/builder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fractal-terrain-generation/builder.js b/fractal-terrain-generation/builder.js index f675441..048179d 100644 --- a/fractal-terrain-generation/builder.js +++ b/fractal-terrain-generation/builder.js @@ -21,10 +21,10 @@ async function getBackendFuncName() { } async function getPublicPath(accountID, endpoint) { + const savedEndpoint = process.env.BINARIS_INVOKE_ENDPOINT; process.env.BINARIS_INVOKE_ENDPOINT = endpoint; const { getInvokeUrl } = require('binaris/sdk/url'); const servingName = await getServingFuncName(); - const savedEndpoint = process.env.BINARIS_INVOKE_ENDPOINT; const invokeURL = await getInvokeUrl(accountID, servingName); process.env.BINARIS_INVOKE_ENDPOINT = savedEndpoint; return invokeURL; From b02e3f103d3fe8a2779b8acddcbec5c3da87bf1d Mon Sep 17 00:00:00 2001 From: Ryland Goldstein Date: Mon, 17 Dec 2018 12:09:26 -0800 Subject: [PATCH 13/14] use standard version of CLI --- fractal-terrain-generation/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fractal-terrain-generation/package.json b/fractal-terrain-generation/package.json index 31f3993..418a9b2 100644 --- a/fractal-terrain-generation/package.json +++ b/fractal-terrain-generation/package.json @@ -20,7 +20,7 @@ "author": "Ryland Goldstein", "license": "MIT", "dependencies": { - "binaris": "binaris/binaris#feature-updated-endpoints", + "binaris": "^6.0.6", "dat.gui": "^0.7.2", "forever": "^0.15.3", "fs-extra": "^7.0.1", From 41feeb4a1edc0a19c4dbdcc4c4b73ffbd2dc9145 Mon Sep 17 00:00:00 2001 From: Ryland Goldstein Date: Wed, 2 Jan 2019 15:21:33 -0800 Subject: [PATCH 14/14] improvements based on review --- fractal-terrain-generation/builder.js | 16 +--------------- .../{template.html => dist/index.html.dot} | 2 +- fractal-terrain-generation/dist/package.json | 1 + fractal-terrain-generation/dist/servePage.js | 12 ++++++++++-- fractal-terrain-generation/package.json | 2 +- fractal-terrain-generation/webpack.config.js | 14 ++++++++++++-- 6 files changed, 26 insertions(+), 21 deletions(-) rename fractal-terrain-generation/{template.html => dist/index.html.dot} (98%) diff --git a/fractal-terrain-generation/builder.js b/fractal-terrain-generation/builder.js index 048179d..0fdd973 100644 --- a/fractal-terrain-generation/builder.js +++ b/fractal-terrain-generation/builder.js @@ -1,4 +1,3 @@ -const replace = require('replace-in-file'); const fse = require('fs-extra'); const path = require('path'); @@ -36,31 +35,18 @@ async function getFractalURL(accountID) { return getInvokeUrl(accountID, backendName); } -async function replaceHTMLAccountID(accountID) { - const templatePath = path.join(__dirname, 'template.html'); - const destPath = path.join(__dirname, 'dist', 'index.html'); - await fse.copy(templatePath, destPath, { overwrite: true, errorOnExist: false }); - - const options = { - files: destPath, - from: //g, - to: accountID, - }; - await replace(options) -} - async function prebuild() { const realm = await getRealm(); if (realm) { forceRealm(realm); } const accountID = await getAccountId(undefined); - await replaceHTMLAccountID(accountID); const FRACTAL_ENDPOINT = await getFractalURL(accountID); const PUBLIC_PATH = (await getPublicPath(accountID, ' ')).slice(8); return { FRACTAL_ENDPOINT, PUBLIC_PATH, + BINARIS_ACCOUNT_ID: accountID, }; } diff --git a/fractal-terrain-generation/template.html b/fractal-terrain-generation/dist/index.html.dot similarity index 98% rename from fractal-terrain-generation/template.html rename to fractal-terrain-generation/dist/index.html.dot index 58b6e79..059ba17 100644 --- a/fractal-terrain-generation/template.html +++ b/fractal-terrain-generation/dist/index.html.dot @@ -196,6 +196,6 @@
Paused
- + diff --git a/fractal-terrain-generation/dist/package.json b/fractal-terrain-generation/dist/package.json index 0d8e359..04c23d3 100644 --- a/fractal-terrain-generation/dist/package.json +++ b/fractal-terrain-generation/dist/package.json @@ -8,6 +8,7 @@ "author": "Ryland Goldstein", "license": "MIT", "dependencies": { + "dot": "^1.1.2", "mime-types": "^2.1.21", "mz": "^2.7.0", "path": "^0.12.7" diff --git a/fractal-terrain-generation/dist/servePage.js b/fractal-terrain-generation/dist/servePage.js index 4e98ba2..d1f8f25 100644 --- a/fractal-terrain-generation/dist/servePage.js +++ b/fractal-terrain-generation/dist/servePage.js @@ -1,10 +1,12 @@ /* eslint-disable no-console */ - const fs = require('mz/fs'); const mime = require('mime-types'); const path = require('path'); +const dot = require('dot'); const prefix = '.'; +const binarisAccountId = process.env.BINARIS_ACCOUNT_ID; +const dots = dot.process(prefix); exports.handler = async (body, ctx) => { let resourcePath = ctx.request.path; @@ -15,7 +17,13 @@ exports.handler = async (body, ctx) => { resourcePath = '/index.html'; } - const webpage = await fs.readFile(`${prefix}${resourcePath}`); + let webPage; + const dotName = resourcePath.substr(1, resourcePath.indexOf('.') - 1); + if (dots[dotName]) { + webpage = dots[dotName]({ binarisAccountId }); + } else { + webpage = await fs.readFile(`${prefix}${resourcePath}`); + } const resourceType = mime.contentType(path.extname(resourcePath)); return new ctx.HTTPResponse({ diff --git a/fractal-terrain-generation/package.json b/fractal-terrain-generation/package.json index 418a9b2..f10785c 100644 --- a/fractal-terrain-generation/package.json +++ b/fractal-terrain-generation/package.json @@ -22,13 +22,13 @@ "dependencies": { "binaris": "^6.0.6", "dat.gui": "^0.7.2", + "dot": "^1.1.2", "forever": "^0.15.3", "fs-extra": "^7.0.1", "loglevel": "^1.6.1", "mime-types": "^2.1.21", "mz": "^2.7.0", "path": "^0.12.7", - "replace-in-file": "^3.4.2", "superagent": "^3.8.3", "three": "^0.94.0" }, diff --git a/fractal-terrain-generation/webpack.config.js b/fractal-terrain-generation/webpack.config.js index a9977b9..616b9ab 100644 --- a/fractal-terrain-generation/webpack.config.js +++ b/fractal-terrain-generation/webpack.config.js @@ -1,12 +1,14 @@ const webpack = require('webpack'); const path = require('path'); const BrowserSyncPlugin = require('browser-sync-webpack-plugin'); +const fs = require('mz/fs'); +const dot = require('dot'); const { prebuild } = require('./builder'); const localResourceEndpoint = 'http://localhost:3001'; module.exports = async () => { - const { FRACTAL_ENDPOINT, PUBLIC_PATH } = await prebuild(); + const { FRACTAL_ENDPOINT, PUBLIC_PATH, BINARIS_ACCOUNT_ID } = await prebuild(); return { entry: [ 'babel-polyfill', './src/gen.worker.js', './src/main.js' ], output: { @@ -54,7 +56,7 @@ module.exports = async () => { proxy: 'http://localhost:8080/', files: [ { - match: ['**/*.html'], + match: ['**/*.html*'], fn: event => { if (event === 'change') { const bs = require('browser-sync').get( @@ -81,6 +83,14 @@ module.exports = async () => { ), ], devServer: { + before: function(app, server) { + app.get(['/', '/index.html'], async (req, res) => { + const file = await fs.readFile(__dirname + '/dist/index.html.dot', 'utf8'); + const template = dot.template(file); + res.set('content-type', 'text/html'); + res.send(template({ binarisAccountId: BINARIS_ACCOUNT_ID })); + }); + }, contentBase: [path.resolve(__dirname, 'dist'), path.resolve(__dirname, 'dist/resources')], publicPath: `${PUBLIC_PATH}/js`, },