@thi.ng/timestep
Version:
Deterministic fixed timestep simulation updates with state interpolation
82 lines (81 loc) • 2.05 kB
JavaScript
import { mix } from "@thi.ng/math/mix";
import { mixN2, mixN3, mixN4 } from "@thi.ng/vectors/mixn";
import { set2, set3, set4 } from "@thi.ng/vectors/set";
class NumericState {
constructor(value, update) {
this.value = value;
this.update = update;
this.reset(value);
}
curr;
prev;
deref() {
return this.value;
}
/**
* Sets {@link NumericState.prev}, {@link NumericState.curr} and
* {@link NumericState.value} to given new value.
*
* @param value
*/
reset(value) {
this.prev = this.curr = this.value = value;
}
integrate(dt, ctx) {
this.prev = this.curr;
this.curr = this.update(this.curr, dt, ctx);
}
interpolate(alpha, _) {
this.value = mix(this.prev, this.curr, alpha);
}
}
class VectorState {
constructor(api, value, update) {
this.value = value;
this.update = update;
this.setFn = api.set;
this.mixFn = api.mixN;
this.prev = this.setFn([], value);
this.curr = this.setFn([], value);
}
prev;
curr;
setFn;
mixFn;
deref() {
return this.value;
}
/**
* Copies given vector to {@link VectorState.prev}, {@link VectorState.curr}
* and {@link VectorState.value}.
*
* @param value
*/
reset(value) {
const set = this.setFn;
set(this.prev, value);
set(this.curr, value);
set(this.value, value);
}
integrate(dt, ctx) {
this.setFn(this.prev, this.curr);
this.update(this.curr, dt, ctx);
}
interpolate(alpha) {
this.mixFn(this.value, this.prev, this.curr, alpha);
}
}
const defNumeric = (x, update) => new NumericState(x, update);
const defVector = (api, v, update) => new VectorState(api, v, update);
const defVector2 = (v, update) => new VectorState({ set: set2, mixN: mixN2 }, v, update);
const defVector3 = (v, update) => new VectorState({ set: set3, mixN: mixN3 }, v, update);
const defVector4 = (v, update) => new VectorState({ set: set4, mixN: mixN4 }, v, update);
export {
NumericState,
VectorState,
defNumeric,
defVector,
defVector2,
defVector3,
defVector4
};