diff --git a/colors.js b/colors.js index 410b332..84a4b2f 100644 --- a/colors.js +++ b/colors.js @@ -2,8 +2,7 @@ class ColorScale { - static fromColorNames(colorNames, canvasId) { - let canvas = document.getElementById(canvasId); + static fromColorNames(colorNames, canvas) { let ctx = canvas.getContext("2d"); let gradient = ctx.createLinearGradient(0, 0, canvas.width, 0); for (let i=0; i
-
+
+ +
+ +
- -
minimum water in river @@ -217,14 +219,56 @@
color scale - + +
+
- + + + +
+ + +
#nodes:
Current settings: diff --git a/index3d.html b/index3d.html deleted file mode 100644 index 04bc123..0000000 --- a/index3d.html +++ /dev/null @@ -1,227 +0,0 @@ - - - - - - Elaborate - - - - - - - - - - - - - - - - - diff --git a/main.js b/main.js index 2bf8b82..f71395c 100644 --- a/main.js +++ b/main.js @@ -2,7 +2,9 @@ class CanvasView { - drawGraph(graph, settings, displayId) { + drawGraph(graph, displayId) { + let settings = readSettings(document.getElementById("drawsettings")); + let canvas = document.getElementById(displayId); canvas.hidden = false; let display = new Display(canvas); @@ -56,12 +58,12 @@ class CanvasView { } } - drawWorldGraph(graph, settings) { - this.drawGraph(graph, settings, "worldlevel") + drawWorldGraph(graph) { + this.drawGraph(graph, "worldlevel") } - drawPartialGraph(graph, settings) { - this.drawGraph(graph, settings, "partial") + drawPartialGraph(graph) { + this.drawGraph(graph, "partial") } hidePartialDisplay() { @@ -95,8 +97,8 @@ class CanvasView { function readSettings(form) { function n(input) { - if (input.id === "colorscale") { - return ColorScale.fromInput(input, "colorpreview"); + if (input.classList.contains("colorscale")) { + return ColorScale.fromInput(input, input.parentElement.getElementsByTagName("canvas")[0]); } else if (input.type === "number") { return +(input.value || input.defaultValue); } else if (input.type === "checkbox") { @@ -110,7 +112,7 @@ function readSettings(form) { } } let settings = {}; - for (let input of form) { + for (let input of form.elements) { if (input.name) { settings[input.name] = n(input); } @@ -122,18 +124,22 @@ function readSettings(form) { } function main() { - let colorInput = document.getElementById("colorscale") - colorInput.addEventListener("input", e => ColorScale.fromInput(e.target, "colorpreview")); - ColorScale.fromInput(colorInput, "colorpreview"); + for (let colorInput of document.getElementsByClassName("colorscale")) { + let preview = colorInput.parentElement.getElementsByClassName("colorpreview")[0]; + colorInput.addEventListener("input", e => ColorScale.fromInput(e.target, preview)); + ColorScale.fromInput(colorInput, preview); + } let view = new CanvasView(); - let form = document.getElementById("settings"); - form.addEventListener("submit", e => generate(readSettings(e.target.elements), view)); - generate(readSettings(form.elements), view); + let form = document.getElementById("worldsettings"); + form.addEventListener("submit", e => { + generate(readSettings(e.target), view) + }); + generate(readSettings(form), view); - document.getElementById("redraw").addEventListener("click", e => { - view.drawWorldGraph(world.graph, readSettings(form.elements)); + document.getElementById("drawsettings").addEventListener("submit", e => { + view.drawWorldGraph(world.graph); }); } diff --git a/main3d.js b/main3d.js deleted file mode 100644 index 147c018..0000000 --- a/main3d.js +++ /dev/null @@ -1,216 +0,0 @@ - -import * as THREE from '/three.module.min.js'; - -const movementSpeed = 2; -const boostSpeed = 100; -const UP = new THREE.Vector3(0, 1, 0); - -class ThreeView { - - constructor() { - - this.scene = new THREE.Scene(); - this.camera = new THREE.PerspectiveCamera( 85, window.innerWidth / window.innerHeight, 0.1, 1000 ); - - this.renderer = new THREE.WebGLRenderer(); - this.renderer.setSize( window.innerWidth, window.innerHeight ); - document.body.appendChild( this.renderer.domElement ); - this.renderer.domElement.addEventListener("click", async () => { - await this.renderer.domElement.requestPointerLock(); - }); - addEventListener("keydown", async e => { - if (e.code === "KeyE") { - await document.exitPointerLock(); - } - }); - - let lookAround = e => { - this.camera.rotation.y -= e.movementX / window.innerWidth * 5; - this.camera.rotation.x = clamp(this.camera.rotation.x - e.movementY / window.innerWidth * 5, -Math.PI/2, Math.PI/2); - }; - - document.addEventListener("pointerlockchange", () => { - if (document.pointerLockElement === this.renderer.domElement) { - console.log("The pointer lock status is now locked"); - document.addEventListener("mousemove", lookAround); - } else { - console.log("The pointer lock status is now unlocked"); - document.removeEventListener("mousemove", lookAround); - } - }); - - this.input = new Input({ - KeyW: "forward", - KeyS: "back", - KeyA: "left", - KeyD: "right", - ShiftLeft: "boost", - KeyC: "down", - Space: "up" - }); - this.input.initialize(); - - this.camera.position.z = 5; - this.camera.position.y = 50; - this.camera.rotation.order = "YXZ"; - - const directionalLight = new THREE.DirectionalLight(0xffffff, 1.0); - directionalLight.position.set(0.1, 1, 0.8); - this.scene.add(directionalLight); - const ambientLight = new THREE.AmbientLight( 0x404040 ); // soft white light - this.scene.add(ambientLight); - } - - - drawWorldGraph(graph, settings) { - console.log("drawing graph 3d"); - let v = []; - let c = [] - for (let triangle of graph.triangles()) { - for (let node of triangle) { - v.push(node.pos.x, node.height() * 64, node.pos.y); - if (node.isSea()) { - c.push(0, 0, 225); - } else if (node.isWaterBody()) { - c.push(76, 76, 255); - } else { - c.push(...settings.colorScale.rgbFloats(node.height() / settings.colorMax)); - } - } - } - let vertices = new Float32Array(v); - let colors = new Float32Array(c); - console.log(colors); - - const geometry = new THREE.BufferGeometry(); - - geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3)); - geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3)); - geometry.computeBoundingBox(); - geometry.computeVertexNormals() - - let ground = new THREE.Mesh(geometry, new THREE.MeshPhongMaterial({vertexColors: true})); - ground.position.x -= settings.size / 2; - ground.position.z -= settings.size / 2; - this.scene.add(ground); - - console.log("graph 3d drawn"); - } - - drawPartialGraph(graph, settings) { } - - hidePartialDisplay() { } - - showNodeCount(nodeCount) { - document.getElementById("nodecount").textContent = nodeCount; - } - - showSettings(settings) { - document.getElementById("currentsettings").textContent = - Object.entries(settings) - .map(([k, v]) => `${k}: ${v}`) - .join("\n"); - } - - status(s) { - document.getElementById("status").textContent = s; - } - - async time(description, fn) { - document.getElementById("status").textContent = "generating: " + description; - return await time(description, fn); - } - - setWorld(world) { - window.world = world; - } - - update(elapsed) { - let movement = new THREE.Vector3( - this.input.inputs.right - this.input.inputs.left, - this.input.inputs.up - this.input.inputs.down, - this.input.inputs.back - this.input.inputs.forward, - ) - .multiplyScalar(elapsed * (this.input.inputs.boost ? boostSpeed : movementSpeed)) - .applyAxisAngle(UP, this.camera.rotation.y); - - this.camera.position.add(movement); - - this.renderer.render(this.scene, this.camera); - } -} - -function readSettings(form) { - function n(input) { - if (input.id === "colorscale") { - return ColorScale.fromInput(input, "colorpreview"); - } else if (input.type === "number") { - return +(input.value || input.defaultValue); - } else if (input.type === "checkbox") { - return input.checked; - } else if (input.type === "select-one") { - return input.value; - } else if (input.type === "text") { - return input.value; - } else { - console.error(`unknown input type '${input.type}'`, input); - } - } - let settings = {}; - for (let input of form) { - if (input.name) { - settings[input.name] = n(input); - } - } - if (!settings.seed) { - settings.seed = Math.random() * 1e7 | 0; - } - return settings; -} - -function main() { - // let colorInput = document.getElementById("colorscale") - // colorInput.addEventListener("input", e => ColorScale.fromInput(e.target, "colorpreview")); - // ColorScale.fromInput(colorInput, "colorpreview"); - - let view = new ThreeView(); - - let form = document.getElementById("settings"); - // form.addEventListener("submit", e => generate(readSettings(e.target.elements), view)); - generate(readSettings(form.elements), view); - - // document.getElementById("redraw").addEventListener("click", e => { - // view.drawWorldGraph(world.graph, readSettings(form.elements)); - // }); - - - - let previousTimestamp = null; - - function update(timeStamp) { - requestAnimationFrame(update); - let elapsed = (previousTimestamp ? timeStamp - previousTimestamp : 1) / 1000 ; - view.update(elapsed); - previousTimestamp = timeStamp; - } - - requestAnimationFrame(update); -} - -class Input { - - constructor(mapping) { - this.mapping = mapping; - this.inputs = {}; - for (let key in mapping) { - this.inputs[mapping[key]] = false; - } - } - - initialize() { - addEventListener("keydown", e => this.inputs[this.mapping[e.code]] = true); - addEventListener("keyup", e => this.inputs[this.mapping[e.code]] = false); - } -} - -window.addEventListener("load", main); diff --git a/style.css b/style.css index e07621b..fc5f2a5 100644 --- a/style.css +++ b/style.css @@ -10,6 +10,10 @@ border: 1px solid black; padding: 5px; } +.subsettings { + border: 1px solid gray; + padding: 2px; +} input[type=number] { width: 6em; diff --git a/view3d.js b/view3d.js index 5f06174..8f74ede 100644 --- a/view3d.js +++ b/view3d.js @@ -1,11 +1,5 @@ - - -const movementSpeed = 2; -const boostSpeed = 20; - - class Input { constructor(mapping) { @@ -30,6 +24,8 @@ class ThreeView { constructor() { + this.movementSpeed = 1; + this.boostSpeed = 10; let canvas = document.getElementById("world3d"); this.scene = new THREE.Scene(); this.camera = new THREE.PerspectiveCamera( 85, window.innerWidth / window.innerHeight, 0.1, 1000 ); @@ -73,11 +69,13 @@ class ThreeView { this.input.initialize(); this.camera.position.z = 5; - this.camera.position.y = 50; + this.camera.position.y = 200; this.camera.rotation.order = "YXZ"; + this.camera.rotation.x = -Math.PI / 3; + this.camera.rotation.y = -Math.PI * 3 / 4; const directionalLight = new THREE.DirectionalLight(0xffffff, 1.0); - directionalLight.position.set(0.1, 1, 0.8); + directionalLight.position.set(0.1, 1, 0.4); this.scene.add(directionalLight); const ambientLight = new THREE.AmbientLight( 0x404040 ); // soft white light this.scene.add(ambientLight); @@ -86,36 +84,38 @@ class ThreeView { } - drawWorldGraph(graph, settings) { + drawWorldGraph(graph) { console.log("drawing graph 3d"); - let v = []; - let c = [] + let settings = readSettings(document.getElementById("draw3dsettings")); + console.log(settings); + this.movementSpeed = settings.movementSpeed; + this.boostSpeed = settings.boostSpeed; + let vertices = []; + let colors = [] for (let triangle of graph.triangles()) { for (let node of triangle) { - v.push(node.pos.x, node.height() * 64, node.pos.y); + vertices.push(node.pos.x * settings.horizontalScale, node.height() * settings.heightScale, node.pos.y * settings.horizontalScale); if (node.isSea()) { - c.push(0, 0, 225); + colors.push(0, 0, 225); } else if (node.isWaterBody()) { - c.push(76, 76, 255); + colors.push(76, 76, 255); } else { - c.push(...settings.colorScale.rgbFloats(node.height() / settings.colorMax)); + colors.push(...settings.colorScale.rgbFloats(node.height() / settings.colorMax)); } } } - let vertices = new Float32Array(v); - let colors = new Float32Array(c); - console.log(colors); const geometry = new THREE.BufferGeometry(); - - geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3)); - geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3)); + geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(vertices), 3)); + geometry.setAttribute('color', new THREE.BufferAttribute(new Float32Array(colors), 3)); geometry.computeBoundingBox(); geometry.computeVertexNormals() - let ground = new THREE.Mesh(geometry, new THREE.MeshPhongMaterial({vertexColors: true})); - ground.position.x -= settings.size / 2; - ground.position.z -= settings.size / 2; + let ground = new THREE.Mesh(geometry, new THREE.MeshStandardMaterial({vertexColors: true})); + if (settings.centerMesh) { + ground.position.x -= graph.size.x * settings.horizontalScale / 2; + ground.position.z -= graph.size.y * settings.horizontalScale / 2; + } this.scene.remove(this.currentGround); this.scene.add(ground); this.currentGround = ground; @@ -140,7 +140,7 @@ class ThreeView { this.input.inputs.up - this.input.inputs.down, this.input.inputs.back - this.input.inputs.forward, ) - .multiplyScalar(elapsed * (this.input.inputs.boost ? boostSpeed : movementSpeed)) + .multiplyScalar(elapsed * (this.input.inputs.boost ? this.boostSpeed : this.movementSpeed)) .applyAxisAngle(new THREE.Vector3(0, 1, 0), this.camera.rotation.y); this.camera.position.add(movement); @@ -159,7 +159,7 @@ async function render3d() { view = new ThreeView(); } view.show(); - view.drawWorldGraph(world.graph, readSettings(document.getElementById("settings").elements)); + view.drawWorldGraph(world.graph); let previousTimestamp = null; @@ -179,9 +179,9 @@ function close3d() { view.hide(); } -let button = document.getElementById("draw3d") -button.addEventListener("click", render3d) -button.hidden = false; +let settingsForm = document.getElementById("draw3dsettings"); +settingsForm.addEventListener("submit", render3d); +settingsForm.hidden = false; document.getElementById("close3d").addEventListener("click", close3d);