53 lines
1.6 KiB
JavaScript
53 lines
1.6 KiB
JavaScript
// diorama.js
|
|
import { Camera } from './camera.js';
|
|
import { World } from './world.js';
|
|
|
|
export class Diorama {
|
|
constructor(elementId, engine) {
|
|
this.element = document.getElementById(elementId);
|
|
this.engine = engine;
|
|
this.world = new World();
|
|
|
|
// Pass the engine's render request function to the camera
|
|
this.camera = new Camera(this.element, () => this.engine.requestRender());
|
|
|
|
this.camera.target = [0.5, 0.5, 0.5];
|
|
this.meshes = [];
|
|
}
|
|
|
|
centerView() {
|
|
if (this.world.blocks.size === 0) {
|
|
this.camera.target = [0.5, 0.5, 0.5]; // Default to origin
|
|
return;
|
|
}
|
|
|
|
let minX = Infinity, minY = Infinity, minZ = Infinity;
|
|
let maxX = -Infinity, maxY = -Infinity, maxZ = -Infinity;
|
|
|
|
for (const block of this.world.blocks.values()) {
|
|
minX = Math.min(minX, block.x);
|
|
minY = Math.min(minY, block.y);
|
|
minZ = Math.min(minZ, block.z);
|
|
|
|
// Add 1 to max to account for the block's 1x1x1 volume
|
|
maxX = Math.max(maxX, block.x + 1);
|
|
maxY = Math.max(maxY, block.y + 1);
|
|
maxZ = Math.max(maxZ, block.z + 1);
|
|
}
|
|
|
|
this.camera.target = [
|
|
(minX + maxX) / 2,
|
|
(minY + maxY) / 2,
|
|
(minZ + maxZ) / 2
|
|
];
|
|
|
|
// Wake up the renderer so the view snaps immediately
|
|
this.engine.requestRender();
|
|
}
|
|
|
|
async update() {
|
|
this.meshes = await this.engine.buildMeshes(this.world);
|
|
// Ensure the scene draws immediately after meshes are built
|
|
this.engine.requestRender();
|
|
}
|
|
} |