UNPKG

@polygonjs/polygonjs

Version:

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

278 lines (277 loc) 10.4 kB
"use strict"; import { MOUSE, TOUCH } from "three"; import { TypedCameraControlsEventNode } from "./_BaseCameraControls"; import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig"; import { EventConnectionPoint, EventConnectionPointType } from "../utils/io/connections/Event"; import { CameraControlsNodeType } from "../../poly/NodeContext"; import { isBooleanTrue } from "../../../core/BooleanValue"; import { PanZoomControls } from "../../../modules/core/controls/PanZoomControls"; const OUTPUT_START = "start"; const OUTPUT_CHANGE = "change"; const OUTPUT_END = "end"; export var MouseControl = /* @__PURE__ */ ((MouseControl2) => { MouseControl2["PAN"] = "pan"; MouseControl2["DOLLY"] = "dolly"; MouseControl2["NO_ACTION"] = "no action"; return MouseControl2; })(MouseControl || {}); export const MOUSE_CONTROLS = ["dolly" /* DOLLY */, "pan" /* PAN */, "no action" /* NO_ACTION */]; var TouchControl = /* @__PURE__ */ ((TouchControl2) => { TouchControl2["PAN"] = "pan"; TouchControl2["DOLLY_PAN"] = "dolly + pan"; TouchControl2["NO_ACTION"] = "no action"; return TouchControl2; })(TouchControl || {}); const TOUCH_CONTROLS = ["pan" /* PAN */, "dolly + pan" /* DOLLY_PAN */, "no action" /* NO_ACTION */]; const THREE_MOUSE_BY_MOUSE_CONTROL = { ["dolly" /* DOLLY */]: MOUSE.DOLLY, ["pan" /* PAN */]: MOUSE.PAN, ["no action" /* NO_ACTION */]: null }; const THREE_TOUCH_BY_TOUCH_CONTROL = { ["pan" /* PAN */]: TOUCH.PAN, ["dolly + pan" /* DOLLY_PAN */]: TOUCH.DOLLY_PAN, ["no action" /* NO_ACTION */]: null }; class CameraPanZoomEventParamsConfig extends NodeParamsConfig { constructor() { super(...arguments); this.main = ParamConfig.FOLDER(); /** @param enable/disable */ this.enabled = ParamConfig.BOOLEAN(1); /** @param toggle on to allow pan */ this.allowPan = ParamConfig.BOOLEAN(1); /** @param minimum distance the cursor must travel before the camera is actually moved */ this.panThreshold = ParamConfig.FLOAT(0, { range: [0, 10], rangeLocked: [true, false], visibleIf: { allowPan: 1 } }); /** @param toggle on to allow zoom */ this.allowZoom = ParamConfig.BOOLEAN(1); /** @param zoom speed */ this.zoomSpeed = ParamConfig.FLOAT(1, { range: [0, 2], rangeLocked: [true, false], visibleIf: { allowZoom: 1 } }); /** @param zoom to cursor */ this.zoomToCursor = ParamConfig.BOOLEAN(1, { visibleIf: { allowZoom: 1 } }); /** @param minimum distance the cursor must travel before the camera starts zooming */ this.zoomThreshold = ParamConfig.FLOAT(0, { range: [0, 10], rangeLocked: [true, false], visibleIf: { allowZoom: 1 } }); /** @param toggle on to have damping */ this.tdamping = ParamConfig.BOOLEAN(1); /** @param damping value */ this.damping = ParamConfig.FLOAT(0.1, { visibleIf: { tdamping: true } }); /** @param toggle on to have the pan in screen space */ this.screenSpacePanning = ParamConfig.BOOLEAN(1); this.limits = ParamConfig.FOLDER(); /** @param smallest distance the camera can go to the target (perspective cameras only) */ // minDistance = ParamConfig.FLOAT(0.1, { // range: [0.1, 100], // rangeLocked: [true, false], // }); // /** @param max distance the camera can go away the target (perspective cameras only) */ // maxDistance = ParamConfig.FLOAT(50, { // range: [0, 100], // rangeLocked: [true, false], // }); /** @param min zoom (orthographic cameras only) */ this.minZoom = ParamConfig.FLOAT(0.01, { range: [0.01, 100], rangeLocked: [true, false] }); /** @param max zoom (orthographic cameras only) */ this.maxZoom = ParamConfig.FLOAT(50, { range: [0, 100], rangeLocked: [true, false] }); /** @param clamp position */ this.clampPosition = ParamConfig.BOOLEAN(false); /** @param min position */ this.positionMin = ParamConfig.VECTOR3([-10, -10, -10], { visibleIf: { clampPosition: 1 } }); /** @param max position */ this.positionMax = ParamConfig.VECTOR3([10, 10, 10], { visibleIf: { clampPosition: 1 } }); this.controls = ParamConfig.FOLDER(); /** @param leftMouseButton */ this.leftMouseButton = ParamConfig.INTEGER(MOUSE_CONTROLS.indexOf("pan" /* PAN */), { menu: { entries: MOUSE_CONTROLS.map((name, value) => ({ name, value })) } }); /** @param leftMouseButton */ this.middleMouseButton = ParamConfig.INTEGER(MOUSE_CONTROLS.indexOf("dolly" /* DOLLY */), { menu: { entries: MOUSE_CONTROLS.map((name, value) => ({ name, value })) } }); /** @param leftMouseButton */ this.rightMouseButton = ParamConfig.INTEGER(MOUSE_CONTROLS.indexOf("pan" /* PAN */), { menu: { entries: MOUSE_CONTROLS.map((name, value) => ({ name, value })) } }); /** @param 1 finger touch */ this.oneFingerTouch = ParamConfig.INTEGER(TOUCH_CONTROLS.indexOf("pan" /* PAN */), { menu: { entries: TOUCH_CONTROLS.map((name, value) => ({ name, value })) }, separatorBefore: true }); /** @param 2 fingers touch */ this.twoFingersTouch = ParamConfig.INTEGER(TOUCH_CONTROLS.indexOf("dolly + pan" /* DOLLY_PAN */), { menu: { entries: TOUCH_CONTROLS.map((name, value) => ({ name, value })) } }); } } const ParamsConfig = new CameraPanZoomEventParamsConfig(); export class CameraPanZoomControlsEventNode extends TypedCameraControlsEventNode { constructor() { super(...arguments); this.paramsConfig = ParamsConfig; this._controlsByElementId = /* @__PURE__ */ new Map(); } static type() { return CameraControlsNodeType.PAN_ZOOM; } endEventName() { return "end"; } initializeNode() { this.io.outputs.setNamedOutputConnectionPoints([ new EventConnectionPoint(OUTPUT_START, EventConnectionPointType.BASE), new EventConnectionPoint(OUTPUT_CHANGE, EventConnectionPointType.BASE), new EventConnectionPoint(OUTPUT_END, EventConnectionPointType.BASE) ]); } _createControls(camera, element) { return new PanZoomControls(camera, element); } async createControlsInstance(camera, element) { const controls = this._createControls(camera, element); this._controlsByElementId.set(element.id, controls); this._updateCache(); this._bind_listeners_to_controls_instance(controls); return controls; } _bind_listeners_to_controls_instance(controls) { controls.addEventListener("start", () => { this.dispatchEventToOutput(OUTPUT_START, {}); }); controls.addEventListener("change", () => { this.dispatchEventToOutput(OUTPUT_CHANGE, {}); }); controls.addEventListener("end", () => { this.dispatchEventToOutput(OUTPUT_END, {}); }); } setupControls(controls) { controls.enabled = isBooleanTrue(this.pv.enabled); controls.enablePan = isBooleanTrue(this.pv.allowPan); controls.panThreshold = this.pv.panThreshold; controls.enableZoom = isBooleanTrue(this.pv.allowZoom); controls.zoomSpeed = this.pv.zoomSpeed; controls.zoomToCursor = isBooleanTrue(this.pv.zoomToCursor); controls.dollyThreshold = this.pv.zoomThreshold; controls.enableDamping = isBooleanTrue(this.pv.tdamping); controls.dampingFactor = this.pv.damping; controls.screenSpacePanning = isBooleanTrue(this.pv.screenSpacePanning); controls.minZoom = this.pv.minZoom; controls.maxZoom = this.pv.maxZoom; controls.clampPosition = this.pv.clampPosition; controls.positionBounds.min.copy(this.pv.positionMin); controls.positionBounds.max.copy(this.pv.positionMax); if (controls.enabled) { controls.update(null); } controls.mouseButtons.LEFT = THREE_MOUSE_BY_MOUSE_CONTROL[MOUSE_CONTROLS[this.pv.leftMouseButton]]; controls.mouseButtons.MIDDLE = THREE_MOUSE_BY_MOUSE_CONTROL[MOUSE_CONTROLS[this.pv.middleMouseButton]]; controls.mouseButtons.RIGHT = THREE_MOUSE_BY_MOUSE_CONTROL[MOUSE_CONTROLS[this.pv.rightMouseButton]]; controls.touches.ONE = THREE_TOUCH_BY_TOUCH_CONTROL[TOUCH_CONTROLS[this.pv.oneFingerTouch]]; controls.touches.TWO = THREE_TOUCH_BY_TOUCH_CONTROL[TOUCH_CONTROLS[this.pv.twoFingersTouch]]; } // private _set_azimuth_angle(controls: OrbitControls) { // if (isBooleanTrue(this.pv.limitAzimuthAngle)) { // controls.minAzimuthAngle = this.pv.azimuthAngleRange.x; // controls.maxAzimuthAngle = this.pv.azimuthAngleRange.y; // } else { // controls.minAzimuthAngle = Infinity; // controls.maxAzimuthAngle = Infinity; // } // } updateRequired() { return false; } // set_from_camera_node(controls: CameraControls, camera_node: BaseCameraObjNodeType): void { // const target = camera_node.params.vector3('target'); // controls.target.copy(target); // console.warn('set from camera node'); // } // private _on_controls_end(controls: OrbitControls) { // if (!isBooleanTrue(this.pv.updateTargetEndMoveEnd)) { // return; // } // if (!isBooleanTrue(this.pv.allowPan)) { // // target should not be updated if pan is not allowed // return; // } // controls.target.toArray(_targetArray); // this.p.target.set(_targetArray); // } // static PARAM_CALLBACK_updateTarget(node: CameraPanZoomControlsEventNode) { // node._updateTarget(); // } // private _updateTarget() { // this.setTarget(this.pv.target); // } // target(target: Vector3) { // if (!this._firstControls) { // return; // } // target.copy(this._firstControls.target); // } // setTarget(newTarget: Vector3) { // this._controlsByElementId.forEach((control, element_id) => { // const destTarget = control.target; // if (!destTarget.equals(newTarget)) { // destTarget.copy(newTarget); // control.update(); // } // }); // } disposeControlsForHtmlElementId(html_element_id) { const controls = this._controlsByElementId.get(html_element_id); if (controls) { this._controlsByElementId.delete(html_element_id); } this._updateCache(); } _updateCache() { this._firstControls = void 0; this._controlsByElementId.forEach((controls) => { this._firstControls = this._firstControls || controls; }); } }