scripts/path-controller/curve/curve1d.js
"use strict";
/*FIXME: not sure this works anymore*/
import nstructjs from "../util/struct.js";
import * as util from '../util/util.js';
//import * as ui_base from './ui_base.js';
import * as vectormath from '../util/vectormath.js';
import {EventDispatcher} from "../util/events.js";
export {getCurve} from './curve1d_base.js';
export {SplineTemplates, SplineTemplateIcons} from './curve1d_bspline.js';
var Vector2 = vectormath.Vector2;
import './curve1d_basic.js';
import './curve1d_bspline.js';
import './curve1d_anim.js';
export function mySafeJSONStringify(obj) {
return JSON.stringify(obj.toJSON(), function (key) {
let v = this[key];
if (typeof v === "number") {
if (v !== Math.floor(v)) {
v = parseFloat(v.toFixed(5));
} else {
v = v;
}
}
return v;
});
}
export function mySafeJSONParse(buf) {
return JSON.parse(buf, (key, val) => {
});
};
window.mySafeJSONStringify = mySafeJSONStringify;
export {CurveConstructors, CURVE_VERSION, CurveTypeData} from './curve1d_base.js';
import {CurveConstructors, CURVE_VERSION, CurveTypeData} from './curve1d_base.js';
let _udigest = new util.HashDigest();
export class Curve1D extends EventDispatcher {
constructor() {
super();
this.uiZoom = 1.0;
this.generators = [];
this.VERSION = CURVE_VERSION;
for (let gen of CurveConstructors) {
gen = new gen();
gen.parent = this;
this.generators.push(gen);
}
//this.generators.active = this.generators[0];
this.setGenerator("bspline");
}
get generatorType() {
return this.generators.active ? this.generators.active.type : undefined;
}
get fastmode() {
return this._fastmode;
}
set fastmode(val) {
this._fastmode = val;
for (let gen of this.generators) {
gen.fastmode = val;
}
}
calcHashKey(digest = _udigest.reset()) {
let d = digest;
for (let g of this.generators) {
g.calcHashKey(d);
}
return d.get();
}
equals(b) {
let gen1 = this.generators.active;
let gen2 = b.generators.active;
if (!gen1 || !gen2 || gen1.constructor !== gen2.constructor) {
return false;
}
return gen1.equals(gen2);
}
load(b) {
if (b === undefined) {
return;
}
let buf1 = mySafeJSONStringify(b);
let buf2 = mySafeJSONStringify(this);
if (buf1 === buf2) {
return;
}
this.loadJSON(JSON.parse(buf1));
this._on_change();
this.redraw();
return this;
}
copy() {
let ret = new Curve1D();
ret.loadJSON(JSON.parse(mySafeJSONStringify(this)));
return ret;
}
_on_change() {
}
redraw() {
this._fireEvent("draw", this);
}
setGenerator(type) {
for (let gen of this.generators) {
if (gen.constructor.define().name === type
|| gen.type === type
|| gen.constructor.define().typeName === type
|| gen.constructor === type) {
if (this.generators.active) {
this.generators.active.onInactive();
}
this.generators.active = gen;
gen.onActive();
return;
}
}
throw new Error("unknown curve type " + type);
}
toJSON() {
let ret = {
generators : [],
uiZoom : this.uiZoom,
VERSION : this.VERSION,
active_generator: this.generatorType
};
for (let gen of this.generators) {
ret.generators.push(gen.toJSON());
}
ret.generators.sort((a, b) => a.type.localeCompare(b.type));
return ret;
}
getGenerator(type, throw_on_error = true) {
for (let gen of this.generators) {
if (gen.type === type) {
return gen;
}
}
//was a new generator registerd?
for (let cls of CurveConstructors) {
if (cls.define().typeName === type) {
let gen = new cls();
gen.type = type;
this.generators.push(gen);
return gen;
}
}
if (throw_on_error) {
throw new Error("Unknown generator " + type + ".");
} else {
return undefined;
}
}
switchGenerator(type) {
let gen = this.getGenerator(type);
if (gen !== this.generators.active) {
let old = this.generators.active;
this.generators.active = gen;
old.onInactive(this);
gen.onActive(this);
}
return gen;
}
destroy() {
return this;
}
loadJSON(obj) {
this.VERSION = obj.VERSION;
this.uiZoom = parseFloat(obj.uiZoom) || this.uiZoom;
//this.generators = [];
for (let gen of obj.generators) {
let gen2 = this.getGenerator(gen.type, false);
if (!gen2 || !(gen2 instanceof CurveTypeData)) {
//old curve class?
console.warn("Bad curve generator class:", gen2);
if (gen2) {
this.generators.remove(gen2);
}
continue;
}
gen2.parent = undefined;
gen2.reset();
gen2.loadJSON(gen);
gen2.parent = this;
if (gen.type === obj.active_generator) {
this.generators.active = gen2;
}
//this.generators.push(gen2);
}
return this;
}
evaluate(s) {
return this.generators.active.evaluate(s);
}
integrate(s, quadSteps) {
return this.generators.active.integrate(s, quadSteps);
}
derivative(s) {
return this.generators.active.derivative(s);
}
derivative2(s) {
return this.generators.active.derivative2(s);
}
inverse(s) {
return this.generators.active.inverse(s);
}
reset() {
this.generators.active.reset();
}
update() {
return this.generators.active.update();
}
draw(canvas, g, draw_transform) {
let w = canvas.width, h = canvas.height;
g.save();
let sz = draw_transform[0], pan = draw_transform[1];
g.beginPath();
g.moveTo(-1, 0);
g.lineTo(1, 0);
g.strokeStyle = "red";
g.stroke();
g.beginPath();
g.moveTo(0, -1);
g.lineTo(0, 1);
g.strokeStyle = "green";
g.stroke();
//g.rect(0, 0, 1, 1);
//g.fillStyle = "rgb(50, 50, 50)";
//g.fill();
let f = 0, steps = 64;
let df = 1/(steps - 1);
w = 6.0/sz;
let curve = this.generators.active;
g.beginPath();
for (let i = 0; i < steps; i++, f += df) {
let val = curve.evaluate(f);
(i === 0 ? g.moveTo : g.lineTo).call(g, f, val, w, w);
}
g.strokeStyle = "grey";
g.stroke();
if (this.overlay_curvefunc !== undefined) {
g.beginPath();
f = 0.0;
for (let i = 0; i < steps; i++, f += df) {
let val = this.overlay_curvefunc(f);
(i === 0 ? g.moveTo : g.lineTo).call(g, f, val, w, w);
}
g.strokeStyle = "green";
g.stroke();
}
this.generators.active.draw(canvas, g, draw_transform);
g.restore();
return this;
}
loadSTRUCT(reader) {
this.generators = [];
reader(this);
//console.log("VERSION", this.VERSION);
if (this.VERSION <= 0.75) {
this.generators = [];
for (let cls of CurveConstructors) {
this.generators.push(new cls());
}
this.generators.active = this.getGenerator("BSplineCurve");
}
for (let gen of this.generators.concat([])) {
if (!(gen instanceof CurveTypeData)) {
console.warn("Bad generator data found:", gen);
this.generators.remove(gen);
continue;
}
if (gen.type === this._active) {
this.generators.active = gen;
}
}
delete this._active;
}
}
Curve1D.STRUCT = `
Curve1D {
generators : array(abstract(CurveTypeData));
_active : string | obj.generators.active.type;
VERSION : float;
uiZoom : float;
}
`;
nstructjs.register(Curve1D);