106 lines
2.9 KiB
TypeScript
106 lines
2.9 KiB
TypeScript
import Config from "./Config";
|
|
import GUI from "./GUI";
|
|
import Renderer from "./Renderer";
|
|
import AntsComputeScene from "./scenes/AntsComputeScene";
|
|
import AntsDiscretizeScene from "./scenes/AntsDiscretizeScene";
|
|
import DrawScene from "./scenes/DrawScene";
|
|
import ScreenScene from "./scenes/ScreenScene";
|
|
import WorldBlurScene from "./scenes/WorldBlurScene";
|
|
import WorldComputeScene from "./scenes/WorldComputeScene";
|
|
|
|
export interface SceneCollection {
|
|
ants: AntsComputeScene;
|
|
world: WorldComputeScene;
|
|
worldBlur: WorldBlurScene;
|
|
discretize: AntsDiscretizeScene;
|
|
screen: ScreenScene;
|
|
draw: DrawScene;
|
|
}
|
|
|
|
export default new (class App {
|
|
private renderer: Renderer = new Renderer(
|
|
<HTMLCanvasElement>document.getElementById("canvas"),
|
|
);
|
|
private scenes!: SceneCollection;
|
|
private gui: GUI = new GUI();
|
|
private renderLoop = (time: number): void => this.render(time);
|
|
private lastTime: number = 0;
|
|
private queuedSimSteps: number = 0;
|
|
|
|
constructor() {
|
|
this.initScenes();
|
|
|
|
window.addEventListener("resize", () => this.resize());
|
|
|
|
this.resize();
|
|
|
|
this.renderLoop(0);
|
|
|
|
this.gui.on("reset", () => {
|
|
this.resetRenderer();
|
|
});
|
|
|
|
this.gui.on("zoomChange", () => {
|
|
this.scenes.screen.applyCameraZoom();
|
|
});
|
|
}
|
|
|
|
private resetRenderer() {
|
|
this.renderer.reset(this.scenes);
|
|
}
|
|
|
|
private initScenes() {
|
|
this.scenes = {
|
|
ants: new AntsComputeScene(this.renderer),
|
|
world: new WorldComputeScene(this.renderer),
|
|
worldBlur: new WorldBlurScene(this.renderer),
|
|
discretize: new AntsDiscretizeScene(this.renderer),
|
|
screen: new ScreenScene(this.renderer),
|
|
draw: new DrawScene(this.renderer),
|
|
};
|
|
}
|
|
|
|
private resize() {
|
|
const canvas = this.renderer.canvas;
|
|
const width = canvas.clientWidth * window.devicePixelRatio;
|
|
const height = canvas.clientHeight * window.devicePixelRatio;
|
|
|
|
this.renderer.resizeCanvas(width, height);
|
|
|
|
for (const scene of Object.values(this.scenes)) {
|
|
scene.resize(width, height);
|
|
}
|
|
}
|
|
|
|
private simulationStep() {
|
|
for (const scene of Object.values(this.scenes)) {
|
|
scene.update();
|
|
}
|
|
|
|
this.renderer.renderSimulation(this.scenes);
|
|
}
|
|
|
|
private render(time: number) {
|
|
requestAnimationFrame(this.renderLoop);
|
|
|
|
const deltaTime = time - this.lastTime;
|
|
const simStepsToDo =
|
|
(deltaTime / 1000) * Config.simulationStepsPerSecond;
|
|
|
|
this.queuedSimSteps += simStepsToDo;
|
|
this.queuedSimSteps = Math.min(this.queuedSimSteps, 10);
|
|
|
|
while (this.queuedSimSteps >= 1) {
|
|
this.simulationStep();
|
|
--this.queuedSimSteps;
|
|
}
|
|
|
|
if (time === 0) {
|
|
return;
|
|
}
|
|
|
|
this.renderer.renderToScreen(this.scenes);
|
|
|
|
this.lastTime = time;
|
|
}
|
|
})();
|