xxxxxxxxxx
/*
Ground interaction
A box is able to interact with a procedural ground.
Controls:
- Use the mouse to move the box around.
- Click to toggle wireframes.
Author:
Jason Labbe
Site:
jasonlabbe3d.com
*/
var steps = 16;
var res = 400;
var maxHeight = 250;
var edges = false;
var boxSize = 30;
function setup() {
createCanvas(windowWidth, windowHeight, WEBGL);
}
function draw() {
background(0);
pointLight(255, 255, 255, 150, -350, 150);
ambientLight(150);
// Setup camera.
translate(-res / 2, 0, 0);
rotateX(radians(50));
rotateZ(radians(-20));
// Determine box's position.
let px = constrain(map(mouseX, width / 4, width - width / 4, 0, res), 0, res);
let py = constrain(map(mouseY, height / 4, height - height / 4, 0, res), 0, res);
let pz = getDepth(px, py);
// Get box's rotation.
// Sort of a hack instead of getting the polygon's proper normal vector.
let rotX = radians((pz - getDepth(px, py - steps)) * 2);
let rotY = radians((pz - getDepth(px + steps, py)) * 2);
fill(100, 200, 100);
strokeWeight(1);
if (edges) {
stroke(20, 60);
} else {
stroke(20, 10);
}
// Draw ground.
for (let x = 0; x < res; x += steps) {
for (let y = 0; y < res; y += steps) {
beginShape();
vertex(x, y, getDepth(x, y));
vertex(x + steps, y, getDepth(x + steps, y));
vertex(x + steps, y + steps, getDepth(x + steps, y + steps));
vertex(x, y + steps, getDepth(x, y + steps));
endShape(CLOSE);
}
}
// Draw box.
push();
translate(px, py, pz + boxSize / 2);
rotateY(rotY);
rotateX(rotX);
fill(200);
box(boxSize);
pop();
}
function mousePressed() {
edges = !edges;
}
// Get ground's height by passing position values.
function getDepth(x, y) {
let frequency = 0.003;
return noise((frameCount + x) * frequency, (frameCount + y) * frequency) * maxHeight;
}