Back to Safe Sand · Material studies
SOURCE / PINNED RELEASE

Made of little things.

Safe Sand · Material studies

Release
9101a9cd9fb4…
Author-recorded commit
75d98e1b8edb…
License
LICENSE
Author’s source reference
nostr://npub182jczunncwe0jn6frpqwq3e0qjws7yqqnc3auccqv9nte2dnd63scjm4rf/wss%3A%2F%2Fgit.napplet.soy%2F/n-7682e55a791

Archive hash verified: 6c8ddabeb31100e1…. The source-to-build association is the author’s claim; it has not been independently rebuilt.

src/engine/camera.js
// A bounded orthographic orbit. World x points right, y down, height up.
export class TrayCamera {
  constructor() { this.pitch = 0; this.yaw = 0; }
  set(pitch, yaw) {
    this.pitch = Math.max(-35, Math.min(35, Number.isFinite(pitch) ? pitch : 0));
    this.yaw = Math.max(-35, Math.min(35, Number.isFinite(yaw) ? yaw : 0));
  }
  basis() {
    const p = this.pitch * Math.PI / 180, y = this.yaw * Math.PI / 180;
    return [Math.sin(p), Math.cos(p), Math.sin(y), Math.cos(y)];
  }
  scale(world) {
    const [sp, cp, sy, cy] = this.basis();
    const fit = Math.max(1, Math.abs(cy) + Math.abs(sy * sp) * world[1] / world[0], Math.abs(cp));
    return fit * (1 + 0.12 * Math.max(Math.abs(this.pitch), Math.abs(this.yaw)) / 35);
  }
  rotate([x, y, z]) {
    const [sp, cp, sy, cy] = this.basis();
    return [cy * x + sy * (sp * y + cp * z), cp * y - sp * z, -sy * x + cy * (sp * y + cp * z)];
  }
  project(x, y, z, world) {
    const p = this.rotate([x - world[0] / 2, world[1] / 2 - y, z]);
    const scale = this.scale(world);
    return [0.5 + p[0] / (world[0] * scale), 0.5 - p[1] / (world[1] * scale), p[2]];
  }
  unproject(u, v, world) {
    const [sp, cp, sy, cy] = this.basis(), scale = this.scale(world);
    const Y = (0.5 - v) * world[1] * scale / cp;
    const X = ((u - 0.5) * world[0] * scale - sy * sp * Y) / cy;
    return [X + world[0] / 2, world[1] / 2 - Y];
  }
}