UNPKG

polygonjs-engine

Version:

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

177 lines (176 loc) 6.38 kB
import {TypedCameraControlsEventNode} from "./_BaseCameraControls"; import {NodeParamsConfig, ParamConfig} from "../utils/params/ParamsConfig"; import {EventConnectionPoint, EventConnectionPointType} from "../utils/io/connections/Event"; import {OrbitControls as OrbitControls2} from "../../../modules/core/controls/OrbitControls"; import {CameraControlsNodeType} from "../../poly/NodeContext"; const OUTPUT_START = "start"; const OUTPUT_CHANGE = "change"; const OUTPUT_END = "end"; var KeysMode; (function(KeysMode2) { KeysMode2["PAN"] = "pan"; KeysMode2["ROTATE"] = "rotate"; })(KeysMode || (KeysMode = {})); const KEYS_MODES = [KeysMode.PAN, KeysMode.ROTATE]; class CameraOrbitEventParamsConfig extends NodeParamsConfig { constructor() { super(...arguments); this.enabled = ParamConfig.BOOLEAN(1); this.allowPan = ParamConfig.BOOLEAN(1); this.allowRotate = ParamConfig.BOOLEAN(1); this.allowZoom = ParamConfig.BOOLEAN(1); this.tdamping = ParamConfig.BOOLEAN(1); this.damping = ParamConfig.FLOAT(0.1, { visibleIf: {tdamping: true} }); this.screenSpacePanning = ParamConfig.BOOLEAN(1); this.rotateSpeed = ParamConfig.FLOAT(0.5); this.minDistance = ParamConfig.FLOAT(1, { range: [0, 100], rangeLocked: [true, false] }); this.maxDistance = ParamConfig.FLOAT(50, { range: [0, 100], rangeLocked: [true, false] }); this.limitAzimuthAngle = ParamConfig.BOOLEAN(0); this.azimuthAngleRange = ParamConfig.VECTOR2(["-2*$PI", "2*$PI"], { visibleIf: {limitAzimuthAngle: 1} }); this.polarAngleRange = ParamConfig.VECTOR2([0, "$PI"]); this.target = ParamConfig.VECTOR3([0, 0, 0], { cook: false, computeOnDirty: true, callback: (node) => { CameraOrbitControlsEventNode.PARAM_CALLBACK_update_target(node); } }); this.enableKeys = ParamConfig.BOOLEAN(0); this.keysMode = ParamConfig.INTEGER(KEYS_MODES.indexOf(KeysMode.PAN), { visibleIf: {enableKeys: 1}, menu: { entries: KEYS_MODES.map((name, value) => { return {name, value}; }) } }); this.keysPanSpeed = ParamConfig.FLOAT(7, { range: [0, 10], rangeLocked: [false, false], visibleIf: {enableKeys: 1, keysMode: KEYS_MODES.indexOf(KeysMode.PAN)} }); this.keysRotateSpeedVertical = ParamConfig.FLOAT(1, { range: [0, 1], rangeLocked: [false, false], visibleIf: {enableKeys: 1, keysMode: KEYS_MODES.indexOf(KeysMode.ROTATE)} }); this.keysRotateSpeedHorizontal = ParamConfig.FLOAT(1, { range: [0, 1], rangeLocked: [false, false], visibleIf: {enableKeys: 1, keysMode: KEYS_MODES.indexOf(KeysMode.ROTATE)} }); } } const ParamsConfig2 = new CameraOrbitEventParamsConfig(); export class CameraOrbitControlsEventNode extends TypedCameraControlsEventNode { constructor() { super(...arguments); this.params_config = ParamsConfig2; this._controls_by_element_id = new Map(); this._target_array = [0, 0, 0]; } static type() { return CameraControlsNodeType.ORBIT; } initializeNode() { this.io.outputs.setNamedOutputConnectionPoints([ new EventConnectionPoint(OUTPUT_START, EventConnectionPointType.BASE), new EventConnectionPoint(OUTPUT_CHANGE, EventConnectionPointType.BASE), new EventConnectionPoint(OUTPUT_END, EventConnectionPointType.BASE) ]); } async create_controls_instance(camera, element) { const controls = new OrbitControls2(camera, element); controls.addEventListener("end", () => { this._on_controls_end(controls); }); this._controls_by_element_id.set(element.id, controls); this._bind_listeners_to_controls_instance(controls); return controls; } _bind_listeners_to_controls_instance(controls) { controls.addEventListener("start", () => { this.dispatch_event_to_output(OUTPUT_START, {}); }); controls.addEventListener("change", () => { this.dispatch_event_to_output(OUTPUT_CHANGE, {}); }); controls.addEventListener("end", () => { this.dispatch_event_to_output(OUTPUT_END, {}); }); } setup_controls(controls) { controls.enabled = this.pv.enabled; controls.enablePan = this.pv.allowPan; controls.enableRotate = this.pv.allowRotate; controls.enableZoom = this.pv.allowZoom; controls.enableDamping = this.pv.tdamping; controls.dampingFactor = this.pv.damping; controls.rotateSpeed = this.pv.rotateSpeed; controls.screenSpacePanning = this.pv.screenSpacePanning; controls.minDistance = this.pv.minDistance; controls.maxDistance = this.pv.maxDistance; this._set_azimuth_angle(controls); controls.minPolarAngle = this.pv.polarAngleRange.x; controls.maxPolarAngle = this.pv.polarAngleRange.y; controls.target.copy(this.pv.target); if (controls.enabled) { controls.update(); } controls.enableKeys = this.pv.enableKeys; if (controls.enableKeys) { controls.keyMode = KEYS_MODES[this.pv.keysMode]; controls.keyRotateSpeedVertical = this.pv.keysRotateSpeedVertical; controls.keyRotateSpeedHorizontal = this.pv.keysRotateSpeedHorizontal; controls.keyPanSpeed = this.pv.keysPanSpeed; } } _set_azimuth_angle(controls) { if (this.pv.limitAzimuthAngle) { controls.minAzimuthAngle = this.pv.azimuthAngleRange.x; controls.maxAzimuthAngle = this.pv.azimuthAngleRange.y; } else { controls.minAzimuthAngle = Infinity; controls.maxAzimuthAngle = Infinity; } } update_required() { return this.pv.tdamping; } _on_controls_end(controls) { if (!this.pv.allowPan) { return; } controls.target.toArray(this._target_array); this.p.target.set(this._target_array); } static PARAM_CALLBACK_update_target(node) { node._update_target(); } _update_target() { const src_target = this.pv.target; this._controls_by_element_id.forEach((control, element_id) => { const dest_target = control.target; if (!dest_target.equals(src_target)) { dest_target.copy(src_target); control.update(); } }); } dispose_controls_for_html_element_id(html_element_id) { const controls = this._controls_by_element_id.get(html_element_id); if (controls) { this._controls_by_element_id.delete(html_element_id); } } }