UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

146 lines (145 loc) 5.32 kB
"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); } }