Skip to content

Commit

Permalink
3d rivers
Browse files Browse the repository at this point in the history
  • Loading branch information
jmdejong committed Mar 20, 2024
1 parent 36a6d19 commit 639fb1b
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 27 deletions.
18 changes: 18 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,24 @@
</label>
<br />

</label>
minimum water in river
<input type="number" name="riverMin" value="1.1" step="0.01" />
</label>
</label>
river width scale
<input type="number" name="riverScale" value="0.2" step="0.01" />
</label>
</label>
river width min
<input type="number" name="riverMinWidth" value="0.1" step="0.01" />
</label>
</label>
river width max
<input type="number" name="riverMaxWidth" value="5" step="0.01" />
</label>
<br />

<label>
flat faces
<input type="checkbox" name="flatFaces" />
Expand Down
5 changes: 1 addition & 4 deletions style.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@
.settings {
border: 1px solid black;
padding: 5px;
}
.subsettings {
border: 1px solid gray;
padding: 2px;
margin: 1px;
}

input[type=number] {
Expand Down
87 changes: 64 additions & 23 deletions view3d.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@ class Input {
}
}

let THREE = null;
let view = null;

let THREE; // no, we've got a cork
let view;

class ThreeView {

Expand Down Expand Up @@ -75,26 +74,15 @@ class ThreeView {
this.camera.rotation.y = -Math.PI * 3 / 4;

const directionalLight = new THREE.DirectionalLight(0xffffff, 2.0);
directionalLight.position.set(0.1, 1, 0.4);
directionalLight.position.set(0.1, 1, 1.4);
this.scene.add(directionalLight);
const ambientLight = new THREE.AmbientLight(0x88888888);
this.scene.add(ambientLight);
this.terrain = null;
this.visible = false;
}


drawWorldGraph(graph) {
console.log("drawing graph 3d");
let settings = readSettings(document.getElementById("draw3dsettings"));
console.log(settings);
this.camera.fov = settings.fov
this.camera.updateProjectionMatrix();
this.movementSpeed = settings.movementSpeed;
this.boostSpeed = settings.boostSpeed;

let terrain = new THREE.Group()

drawGround(graph, terrain, settings) {
let vertices = [];
let colors = [];
let waterVertices = [];
Expand All @@ -104,9 +92,9 @@ class ThreeView {
let nodeIndex = new Map();
let i = 0;
for (let node of nodes) {
vertices.push(node.pos.x * settings.horizontalScale, node.baseHeight * settings.heightScale, node.pos.y * settings.horizontalScale);
vertices.push(node.pos.x, node.baseHeight, node.pos.y);
colors.push(...settings.colorScale.rgbFloats(node.baseHeight / settings.colorMax));
waterVertices.push(node.pos.x * settings.horizontalScale, node.waterHeight * settings.heightScale, node.pos.y * settings.horizontalScale);
waterVertices.push(node.pos.x, node.waterHeight, node.pos.y);
waterNormals.push(0, 1, 0);
nodeIndex.set(node.id.hash(), i++);
}
Expand All @@ -123,24 +111,77 @@ class ThreeView {
if (!settings.flatFaces) {
waterGeometry.setIndex(indices);
}
waterGeometry.scale(settings.horizontalScale, settings.heightScale, settings.horizontalScale);
waterGeometry.computeBoundingBox();
let water = new THREE.Mesh(waterGeometry, new THREE.MeshStandardMaterial({color: 0x0000ff}));
water.position.y -= 1e-6;
terrain.add(water);
terrain.add(new THREE.Mesh(waterGeometry, new THREE.MeshStandardMaterial({color: 0x0000ff})));

const geometry = new THREE.BufferGeometry();
geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(vertices), 3));
geometry.setAttribute('color', new THREE.BufferAttribute(new Float32Array(colors), 3));
if (!settings.flatFaces) {
geometry.setIndex(indices);
}
geometry.scale(settings.horizontalScale, settings.heightScale, settings.horizontalScale);
geometry.computeBoundingBox();
geometry.computeVertexNormals();

let ground = new THREE.Mesh(geometry, new THREE.MeshStandardMaterial({vertexColors: true}));
terrain.add(ground);
terrain.add(new THREE.Mesh(geometry, new THREE.MeshStandardMaterial({vertexColors: true})));
}

drawRivers(graph, terrain, settings) {
let waterMaterial = new THREE.MeshStandardMaterial({color: 0x7f7fff});
for (let node of graph.all()) {
if (node.isSink() || !settings.drawUnderwaterStreams && node.isWaterBody()) {
continue;
}
for (let [drain, o] of node.outflow) {
let water = node.water * o
if (water < settings.riverMin) {
continue;
}
// let start = new THREE.Vector3(node.pos.x, node.height(), node.pos.y);
// let end = new THREE.Vector3(drain.pos.x, drain.height(), drain.pos.y)
// let width = clamp(
// Math.sqrt(water)*settings.riverScale,
// settings.riverMinWidth,
// settings.riverMaxWidth
// );

let line = new THREE.LineCurve3(
new THREE.Vector3(node.pos.x * settings.horizontalScale, node.height() * settings.heightScale, node.pos.y * settings.horizontalScale),
new THREE.Vector3(drain.pos.x * settings.horizontalScale, drain.height() * settings.heightScale, drain.pos.y * settings.horizontalScale)
);
let tube = new THREE.TubeGeometry(
line,
8,
clamp(
Math.sqrt(water)*settings.riverScale,
settings.riverMinWidth,
settings.riverMaxWidth
) * settings.horizontalScale,
8,
false
);
terrain.add(new THREE.Mesh(tube, waterMaterial));
}
}
}

drawWorldGraph(graph) {
console.log("drawing graph 3d");
let settings = readSettings(document.getElementById("draw3dsettings"));
console.log(settings);
this.camera.fov = settings.fov
this.camera.updateProjectionMatrix();
this.movementSpeed = settings.movementSpeed;
this.boostSpeed = settings.boostSpeed;

let terrain = new THREE.Group()

this.drawGround(graph, terrain, settings);
this.drawRivers(graph, terrain, settings);

// terrain.scale.set(settings.horizontalScale, settings.heightScale, settings.horizontalScale);
if (settings.centerMesh) {
terrain.position.x -= graph.size.x * settings.horizontalScale / 2;
terrain.position.z -= graph.size.y * settings.horizontalScale / 2;
Expand Down

0 comments on commit 639fb1b

Please sign in to comment.