@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
146 lines (145 loc) • 5.32 kB
JavaScript
"use strict";
import { TypedObjNode } from "./_Base";
import { Group } from "three";
import { FlagsControllerD } from "../utils/FlagsController";
import { AxesHelper } from "three";
import { HierarchyController } from "./utils/HierarchyController";
import { Matrix4 } from "three";
import { Vector3 } from "three";
import { MathUtils } from "three";
import { Quaternion } from "three";
import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig";
import { PolarGridHelper } from "three";
class PolarTransformObjParamConfig extends NodeParamsConfig {
constructor() {
super(...arguments);
/** @param center of the transform */
this.center = ParamConfig.VECTOR3([0, 0, 0]);
/** @param moves the objects along the longitude, which is equivalent to a rotation on the y axis */
this.longitude = ParamConfig.FLOAT(0, {
range: [-360, 360]
});
/** @param moves the objects along the latitude, which is equivalent to a rotation on the z or x axis */
this.latitude = ParamConfig.FLOAT(0, {
range: [-180, 180]
});
/** @param moves the point aways from the center */
this.depth = ParamConfig.FLOAT(1, {
range: [0, 10]
});
}
}
const ParamsConfig = new PolarTransformObjParamConfig();
const HOOK_NAME = "_cook_main_without_inputs_when_dirty";
const AXIS_VERTICAL = new Vector3(0, 1, 0);
const AXIS_HORIZONTAL = new Vector3(-1, 0, 0);
export class PolarTransformObjNode extends TypedObjNode {
constructor() {
super(...arguments);
this.paramsConfig = ParamsConfig;
this.hierarchyController = new HierarchyController(this);
this.flags = new FlagsControllerD(this);
this._helper = this._createHelper();
// TODO: this will have to be checked via the parent, when I will have obj managers at lower levels than root
this._cook_main_without_inputs_when_dirty_bound = this._cook_main_without_inputs_when_dirty.bind(this);
this._centerMatrix = new Matrix4();
this._longitudeMatrix = new Matrix4();
this._latitudeMatrix = new Matrix4();
this._depthMatrix = new Matrix4();
this._fullMatrix = new Matrix4();
this._decomposed = {
t: new Vector3(),
q: new Quaternion(),
s: new Vector3()
};
}
static type() {
return "polarTransform";
}
createObject() {
const group = new Group();
group.matrixAutoUpdate = false;
return group;
}
initializeNode() {
this.hierarchyController.initializeNode();
if (!this.dirtyController.hasHook(HOOK_NAME)) {
this.dirtyController.addPostDirtyHook(HOOK_NAME, this._cook_main_without_inputs_when_dirty_bound);
}
this._updateHelperHierarchy();
this._helper.matrixAutoUpdate = false;
this.flags.display.onUpdate(() => {
this._updateHelperHierarchy();
});
}
_updateHelperHierarchy() {
if (this._displayedHelper()) {
this.object.add(this._helper);
this._updateHelper();
} else {
this.object.remove(this._helper);
}
}
_displayedHelper() {
return this.flags.display.active();
}
_axisHelper() {
return this.__axisHelper__ = this.__axisHelper__ || this._createAxisHelper();
}
_createAxisHelper() {
const axisHelper = new AxesHelper(1);
axisHelper.matrixAutoUpdate = false;
return axisHelper;
}
_polarGridHelper() {
return this.__polarGridHelper__ = this.__polarGridHelper__ || this._createPolarGridHelper();
}
_createPolarGridHelper() {
const radius = this.pv.depth;
const radials = 16;
const circles = 8;
const divisions = 64;
const polarGridHelper = new PolarGridHelper(radius, radials, circles, divisions);
polarGridHelper.matrixAutoUpdate = false;
return polarGridHelper;
}
_createHelper() {
const group = new Group();
group.name = "PolarTransformHelper";
group.matrixAutoUpdate = false;
group.add(this._axisHelper());
group.add(this._polarGridHelper());
return group;
}
async _cook_main_without_inputs_when_dirty() {
await this.cookController.cookMainWithoutInputs();
}
cook() {
const object = this.object;
this._centerMatrix.identity();
this._longitudeMatrix.identity();
this._latitudeMatrix.identity();
this._depthMatrix.identity();
this._centerMatrix.makeTranslation(this.pv.center.x, this.pv.center.y, this.pv.center.z);
this._longitudeMatrix.makeRotationAxis(AXIS_VERTICAL, MathUtils.degToRad(this.pv.longitude));
this._latitudeMatrix.makeRotationAxis(AXIS_HORIZONTAL, MathUtils.degToRad(this.pv.latitude));
this._depthMatrix.makeTranslation(0, 0, this.pv.depth);
this._fullMatrix.copy(this._centerMatrix).multiply(this._longitudeMatrix).multiply(this._latitudeMatrix).multiply(this._depthMatrix);
this._fullMatrix.decompose(this._decomposed.t, this._decomposed.q, this._decomposed.s);
object.position.copy(this._decomposed.t);
object.quaternion.copy(this._decomposed.q);
object.scale.copy(this._decomposed.s);
object.updateMatrix();
this._updateHelper();
this.cookController.endCook();
}
_updateHelper() {
if (!this._displayedHelper()) {
return;
}
this._helper.updateMatrix();
this._polarGridHelper().matrix.copy(this.object.matrix);
this._polarGridHelper().matrix.invert();
this._polarGridHelper().matrix.multiply(this._centerMatrix);
}
}