@dominicstop/utils
Version:
Yet another event emitter written in typescript.
104 lines (103 loc) • 3.42 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CirclePackingOfflineSimulation = void 0;
const PhysicsEngine_1 = require("./PhysicsEngine");
const CentralAttractionForce_1 = require("./CentralAttractionForce");
class CirclePackingOfflineSimulation {
get totalSimulatedTime() {
return this._totalSimulatedTime;
}
get iterationCount() {
return this._iterationCount;
}
;
get frameTimeMS() {
return this.minIterations * 1000;
}
;
constructor(args) {
this.isRunning = false;
this.shouldLog = false;
this._totalSimulatedTime = 0;
this._iterationCount = 0;
this.minIterations = 50;
this.maxIterations = 250;
this.onPreStep = null;
this.onPostStep = null;
this.onUpdate = null;
this.fixedDeltaTimeSeconds = args.timeStep ?? (1 / 60);
const engine = new PhysicsEngine_1.PhysicsEngine();
this.engine = engine;
const centerForce = new CentralAttractionForce_1.CentralAttractionForce(args.frame.center.asVector, args.centralAttractionStrength ?? 8, true);
engine.addForce(centerForce);
}
run() {
this.isRunning = true;
this._iterationCount = 0;
while (true) {
const didReachMaxIterations = this._iterationCount >= this.maxIterations;
if (!this.isRunning || didReachMaxIterations) {
this.isRunning = false;
break;
}
;
this.step();
this._iterationCount++;
this.onUpdate?.();
const didReachMinIterations = this._iterationCount > this.minIterations;
const shouldStop = didReachMinIterations
&& this.isStable();
if (shouldStop) {
this.isRunning = false;
}
}
}
;
step() {
this.onPreStep?.(this.fixedDeltaTimeSeconds);
this.engine.update(this.fixedDeltaTimeSeconds);
this.onPostStep?.(this.fixedDeltaTimeSeconds);
this._totalSimulatedTime += this.fixedDeltaTimeSeconds;
if (this.shouldLog) {
console.log({
'isRunning': this.isRunning,
'iterationCount': this._iterationCount,
'totalSimulatedTime': this._totalSimulatedTime,
'getTotalKineticEnergy': this.engine.getTotalKineticEnergy(),
'isKineticEnergyNegligible': this.isKineticEnergyNegligible(),
'checkIfAllParticlesAtRest': this.engine.checkIfAllParticlesAtRest(),
'this.isStable': this.isStable(),
});
this.engine.logState();
}
;
}
;
reset() {
this.isRunning = false;
this.engine.clear();
this._totalSimulatedTime = 0;
this._iterationCount = 0;
}
;
addParticle(particle) {
this.engine.addParticle(particle);
}
;
addForce(force) {
this.engine.addForce(force);
}
;
isKineticEnergyNegligible() {
const energyThreshold = 0.01;
return this.engine.getTotalKineticEnergy() < energyThreshold;
}
;
isStable() {
return (this.isKineticEnergyNegligible()
|| this.engine.checkIfAllParticlesAtRest());
}
;
}
exports.CirclePackingOfflineSimulation = CirclePackingOfflineSimulation;
;