@tonybfox/threejs-tools 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +321 -0
- package/dist/asset-loader/index.cjs +376 -0
- package/dist/asset-loader/index.cjs.map +1 -0
- package/dist/asset-loader/index.d.mts +101 -0
- package/dist/asset-loader/index.d.ts +101 -0
- package/dist/asset-loader/index.mjs +7 -0
- package/dist/asset-loader/index.mjs.map +1 -0
- package/dist/camera/index.cjs +313 -0
- package/dist/camera/index.cjs.map +1 -0
- package/dist/camera/index.d.mts +82 -0
- package/dist/camera/index.d.ts +82 -0
- package/dist/camera/index.mjs +7 -0
- package/dist/camera/index.mjs.map +1 -0
- package/dist/chunk-5DP6WDB3.mjs +1161 -0
- package/dist/chunk-5DP6WDB3.mjs.map +1 -0
- package/dist/chunk-BJKSICFA.mjs +1579 -0
- package/dist/chunk-BJKSICFA.mjs.map +1 -0
- package/dist/chunk-BYRZCHE7.mjs +277 -0
- package/dist/chunk-BYRZCHE7.mjs.map +1 -0
- package/dist/chunk-EIROAPF7.mjs +387 -0
- package/dist/chunk-EIROAPF7.mjs.map +1 -0
- package/dist/chunk-EQDOX34V.mjs +164 -0
- package/dist/chunk-EQDOX34V.mjs.map +1 -0
- package/dist/chunk-IIAZ2WJJ.mjs +405 -0
- package/dist/chunk-IIAZ2WJJ.mjs.map +1 -0
- package/dist/chunk-L4VIIJZD.mjs +340 -0
- package/dist/chunk-L4VIIJZD.mjs.map +1 -0
- package/dist/chunk-P35QJCOG.mjs +339 -0
- package/dist/chunk-P35QJCOG.mjs.map +1 -0
- package/dist/chunk-R64RVBRM.mjs +394 -0
- package/dist/chunk-R64RVBRM.mjs.map +1 -0
- package/dist/compass/index.cjs +375 -0
- package/dist/compass/index.cjs.map +1 -0
- package/dist/compass/index.d.mts +58 -0
- package/dist/compass/index.d.ts +58 -0
- package/dist/compass/index.mjs +7 -0
- package/dist/compass/index.mjs.map +1 -0
- package/dist/grid/index.cjs +200 -0
- package/dist/grid/index.cjs.map +1 -0
- package/dist/grid/index.d.mts +43 -0
- package/dist/grid/index.d.ts +43 -0
- package/dist/grid/index.mjs +7 -0
- package/dist/grid/index.mjs.map +1 -0
- package/dist/index.cjs +5049 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.mts +13 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.mjs +47 -0
- package/dist/index.mjs.map +1 -0
- package/dist/measurements/index.cjs +1198 -0
- package/dist/measurements/index.cjs.map +1 -0
- package/dist/measurements/index.d.mts +449 -0
- package/dist/measurements/index.d.ts +449 -0
- package/dist/measurements/index.mjs +9 -0
- package/dist/measurements/index.mjs.map +1 -0
- package/dist/sunlight/index.cjs +441 -0
- package/dist/sunlight/index.cjs.map +1 -0
- package/dist/sunlight/index.d.mts +92 -0
- package/dist/sunlight/index.d.ts +92 -0
- package/dist/sunlight/index.mjs +7 -0
- package/dist/sunlight/index.mjs.map +1 -0
- package/dist/terrain/index.cjs +423 -0
- package/dist/terrain/index.cjs.map +1 -0
- package/dist/terrain/index.d.mts +219 -0
- package/dist/terrain/index.d.ts +219 -0
- package/dist/terrain/index.mjs +7 -0
- package/dist/terrain/index.mjs.map +1 -0
- package/dist/transform-controls/index.cjs +1587 -0
- package/dist/transform-controls/index.cjs.map +1 -0
- package/dist/transform-controls/index.d.mts +162 -0
- package/dist/transform-controls/index.d.ts +162 -0
- package/dist/transform-controls/index.mjs +13 -0
- package/dist/transform-controls/index.mjs.map +1 -0
- package/dist/view-helper/index.cjs +430 -0
- package/dist/view-helper/index.cjs.map +1 -0
- package/dist/view-helper/index.d.mts +75 -0
- package/dist/view-helper/index.d.ts +75 -0
- package/dist/view-helper/index.mjs +7 -0
- package/dist/view-helper/index.mjs.map +1 -0
- package/package.json +124 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../packages/transform-controls/src/TransformControls.ts"],"sourcesContent":["// @ts-nocheck\nimport {\n BoxGeometry,\n BufferGeometry,\n Camera,\n Controls,\n CylinderGeometry,\n DoubleSide,\n Euler,\n Float32BufferAttribute,\n Line,\n LineBasicMaterial,\n Matrix4,\n Mesh,\n MeshBasicMaterial,\n Object3D,\n OctahedronGeometry,\n PlaneGeometry,\n Quaternion,\n Raycaster,\n SphereGeometry,\n TorusGeometry,\n Vector3,\n Box3,\n} from 'three'\nimport { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer.js'\n\nconst _raycaster = new Raycaster()\n\nconst _tempVector = new Vector3()\nconst _tempVector2 = new Vector3()\nconst _tempQuaternion = new Quaternion()\nconst _unit = {\n X: new Vector3(1, 0, 0),\n Y: new Vector3(0, 1, 0),\n Z: new Vector3(0, 0, 1),\n}\n\n/**\n * Fires if any type of change (object or property change) is performed. Property changes\n * are separate events you can add event listeners to. The event type is \"propertyname-changed\".\n *\n * @event TransformControls#change\n * @type {Object}\n */\nconst _changeEvent = { type: 'change' }\n\n/**\n * Fires if a pointer (mouse/touch) becomes active.\n *\n * @event TransformControls#mouseDown\n * @type {Object}\n */\nconst _mouseDownEvent = { type: 'mouseDown', mode: null }\n\n/**\n * Fires if a pointer (mouse/touch) is no longer active.\n *\n * @event TransformControls#mouseUp\n * @type {Object}\n */\nconst _mouseUpEvent = { type: 'mouseUp', mode: null }\n\n/**\n * Fires if the controlled 3D object is changed.\n *\n * @event TransformControls#objectChange\n * @type {Object}\n */\nconst _objectChangeEvent = { type: 'objectChange' }\n\n/**\n * This class can be used to transform objects in 3D space by adapting a similar interaction model\n * of DCC tools like Blender. Unlike other controls, it is not intended to transform the scene's camera.\n *\n * `TransformControls` expects that its attached 3D object is part of the scene graph.\n *\n * @augments Controls\n */\nclass TransformControls extends Controls<{}> {\n // @ts-ignore - dynamic properties\n [key: string]: any\n\n _root: TransformControlsRoot\n _gizmo: TransformControlsGizmo\n _plane: TransformControlsPlane\n _overlay: HTMLDivElement\n _distanceLabel: CSS2DObject\n _activeMode: string // Tracks which mode is active during drag in 'all' mode\n _rotationArc: Line | null // Arc showing rotation angle\n _rotationAngleLabel: CSS2DObject // Label showing rotation angle\n\n _offset: Vector3\n _startNorm: Vector3\n _endNorm: Vector3\n _cameraScale: Vector3\n\n _parentPosition: Vector3\n _parentQuaternion: Quaternion\n _parentQuaternionInv: Quaternion\n _parentScale: Vector3\n\n _worldScaleStart: Vector3\n _worldQuaternionInv: Quaternion\n _worldScale: Vector3\n _tempPosition: Vector3\n\n _positionStart: Vector3\n _quaternionStart: Quaternion\n _scaleStart: Vector3\n\n _getPointer: (event: PointerEvent) => { x: number; y: number; button: number }\n _onPointerDown: (event: PointerEvent) => void\n _onPointerHover: (event: PointerEvent) => void\n _onPointerMove: (event: PointerEvent) => void\n _onPointerUp: (event: PointerEvent) => void\n\n /**\n * Constructs a new controls instance.\n *\n * @param {Camera} camera - The camera of the rendered scene.\n * @param {?HTMLDOMElement} domElement - The HTML element used for event listeners.\n */\n constructor(camera: Camera, domElement: HTMLElement | null = null) {\n super(undefined, domElement)\n\n const root = new TransformControlsRoot(this)\n this._root = root\n\n const gizmo = new TransformControlsGizmo()\n this._gizmo = gizmo\n root.add(gizmo)\n\n const plane = new TransformControlsPlane()\n this._plane = plane\n root.add(plane)\n\n const scope = this\n\n // Create overlay element\n this._overlay = document.createElement('div')\n this._overlay.classList.add('absolute')\n this._overlay.classList.add('bottom-2')\n this._overlay.classList.add('left-80')\n this._overlay.classList.add('z-50')\n this._overlay.classList.add('bg-gray-700')\n this._overlay.classList.add('bg-opacity-70')\n this._overlay.classList.add('text-white')\n this._overlay.classList.add('p-2')\n this._overlay.classList.add('rounded-md')\n this._overlay.classList.add('border')\n this._overlay.classList.add('border-gray-500')\n this._overlay.classList.add('hidden')\n\n if (domElement) {\n domElement.appendChild(this._overlay)\n }\n\n // Create CSS2D distance label\n const labelDiv = document.createElement('div')\n labelDiv.className = 'distance-label'\n labelDiv.style.padding = '4px 8px'\n labelDiv.style.background = 'rgba(0, 0, 0, 0.8)'\n labelDiv.style.border = '1px solid rgba(255, 255, 255, 0.3)'\n labelDiv.style.borderRadius = '4px'\n labelDiv.style.color = '#fff'\n labelDiv.style.fontSize = '12px'\n labelDiv.style.fontFamily = 'monospace'\n labelDiv.style.whiteSpace = 'nowrap'\n labelDiv.style.pointerEvents = 'none'\n labelDiv.style.userSelect = 'none'\n labelDiv.textContent = '0.00'\n\n this._distanceLabel = new CSS2DObject(labelDiv)\n this._distanceLabel.visible = false\n root.add(this._distanceLabel)\n\n // Create CSS2D rotation angle label\n const angleLabelDiv = document.createElement('div')\n angleLabelDiv.className = 'rotation-angle-label'\n angleLabelDiv.style.padding = '4px 8px'\n angleLabelDiv.style.background = 'rgba(0, 0, 0, 0.8)'\n angleLabelDiv.style.border = '1px solid rgba(255, 255, 255, 0.3)'\n angleLabelDiv.style.borderRadius = '4px'\n angleLabelDiv.style.color = '#fff'\n angleLabelDiv.style.fontSize = '12px'\n angleLabelDiv.style.fontFamily = 'monospace'\n angleLabelDiv.style.whiteSpace = 'nowrap'\n angleLabelDiv.style.pointerEvents = 'none'\n angleLabelDiv.style.userSelect = 'none'\n angleLabelDiv.textContent = '0°'\n\n this._rotationAngleLabel = new CSS2DObject(angleLabelDiv)\n this._rotationAngleLabel.visible = false\n root.add(this._rotationAngleLabel)\n\n // Initialize rotation arc (will be created dynamically)\n this._rotationArc = null\n\n // Defined getter, setter and store for a property\n function defineProperty(propName: string, defaultValue: any) {\n let propValue = defaultValue\n\n Object.defineProperty(scope, propName, {\n get: function () {\n return propValue !== undefined ? propValue : defaultValue\n },\n\n set: function (value: any) {\n if (propValue !== value) {\n propValue = value\n ;(plane as any)[propName] = value\n ;(gizmo as any)[propName] = value\n\n scope.dispatchEvent({\n type: propName + '-changed',\n value: value,\n } as any)\n scope.dispatchEvent(_changeEvent as any)\n }\n },\n })\n ;(scope as any)[propName] = defaultValue\n ;(plane as any)[propName] = defaultValue\n ;(gizmo as any)[propName] = defaultValue\n }\n\n // Define properties with getters/setter\n // Setting the defined property will automatically trigger change event\n // Defined properties are passed down to gizmo and plane\n\n /**\n * The camera of the rendered scene.\n *\n * @name TransformControls#camera\n * @type {Camera}\n */\n defineProperty('camera', camera)\n defineProperty('object', undefined)\n defineProperty('enabled', true)\n\n /**\n * The current transformation axis.\n *\n * @name TransformControls#axis\n * @type {string}\n */\n defineProperty('axis', null)\n\n /**\n * The current transformation axis.\n *\n * @name TransformControls#mode\n * @type {('translate'|'rotate'|'scale'|'all')}\n * @default 'all'\n */\n defineProperty('mode', 'all')\n\n /**\n * By default, 3D objects are continuously translated. If you set this property to a numeric\n * value (world units), you can define in which steps the 3D object should be translated.\n *\n * @name TransformControls#translationSnap\n * @type {?number}\n * @default null\n */\n defineProperty('translationSnap', null)\n\n /**\n * By default, 3D objects are continuously rotated. If you set this property to a numeric\n * value (radians), you can define in which steps the 3D object should be rotated.\n *\n * @name TransformControls#rotationSnap\n * @type {?number}\n * @default null\n */\n defineProperty('rotationSnap', null)\n\n /**\n * By default, 3D objects are continuously scaled. If you set this property to a numeric\n * value, you can define in which steps the 3D object should be scaled.\n *\n * @name TransformControls#scaleSnap\n * @type {?number}\n * @default null\n */\n defineProperty('scaleSnap', null)\n\n /**\n * Defines in which coordinate space transformations should be performed.\n *\n * @name TransformControls#space\n * @type {('world'|'local')}\n * @default 'world'\n */\n defineProperty('space', 'world')\n\n /**\n * The size of the helper UI (axes/planes).\n *\n * @name TransformControls#size\n * @type {number}\n * @default 1\n */\n defineProperty('size', 0.75)\n\n /**\n * Whether dragging is currently performed or not.\n *\n * @name TransformControls#dragging\n * @type {boolean}\n * @readonly\n * @default false\n */\n defineProperty('dragging', false)\n\n /**\n * The active transformation mode when in 'all' mode.\n *\n * @name TransformControls#activeMode\n * @type {('translate'|'rotate'|'scale')}\n * @readonly\n * @default 'translate'\n */\n defineProperty('activeMode', 'translate')\n\n /**\n * Whether the x-axis helper should be visible or not.\n *\n * @name TransformControls#showX\n * @type {boolean}\n * @default true\n */\n defineProperty('showX', true)\n\n /**\n * Whether the y-axis helper should be visible or not.\n *\n * @name TransformControls#showY\n * @type {boolean}\n * @default true\n */\n defineProperty('showY', true)\n\n /**\n * Whether the z-axis helper should be visible or not.\n *\n * @name TransformControls#showZ\n * @type {boolean}\n * @default true\n */\n defineProperty('showZ', true)\n\n /**\n * The minimum allowed X position during translation.\n *\n * @name TransformControls#minX\n * @type {number}\n * @default -Infinity\n */\n defineProperty('minX', -Infinity)\n\n /**\n * The maximum allowed X position during translation.\n *\n * @name TransformControls#maxX\n * @type {number}\n * @default Infinity\n */\n defineProperty('maxX', Infinity)\n\n /**\n * The minimum allowed y position during translation.\n *\n * @name TransformControls#minY\n * @type {number}\n * @default -Infinity\n */\n defineProperty('minY', -Infinity)\n\n /**\n * The maximum allowed Y position during translation.\n *\n * @name TransformControls#maxY\n * @type {number}\n * @default Infinity\n */\n defineProperty('maxY', Infinity)\n\n /**\n * The minimum allowed z position during translation.\n *\n * @name TransformControls#minZ\n * @type {number}\n * @default -Infinity\n */\n defineProperty('minZ', -Infinity)\n\n /**\n * The maximum allowed Z position during translation.\n *\n * @name TransformControls#maxZ\n * @type {number}\n * @default Infinity\n */\n defineProperty('maxZ', Infinity)\n\n /**\n * The minimum allowed rotation angle during rotation (in radians).\n *\n * @name TransformControls#minRotation\n * @type {number}\n * @default -2 * Math.PI (-360 degrees)\n */\n defineProperty('minRotation', -2 * Math.PI)\n\n /**\n * The maximum allowed rotation angle during rotation (in radians).\n *\n * @name TransformControls#maxRotation\n * @type {number}\n * @default 2 * Math.PI (360 degrees)\n */\n defineProperty('maxRotation', 2 * Math.PI)\n\n // Reusable utility variables\n\n const worldPosition = new Vector3()\n const worldPositionStart = new Vector3()\n const worldQuaternion = new Quaternion()\n const worldQuaternionStart = new Quaternion()\n const cameraPosition = new Vector3()\n const cameraQuaternion = new Quaternion()\n const pointStart = new Vector3()\n const pointEnd = new Vector3()\n const rotationAxis = new Vector3()\n const rotationAngle = 0\n const eye = new Vector3()\n\n // TODO: remove properties unused in plane and gizmo\n\n defineProperty('worldPosition', worldPosition)\n defineProperty('worldPositionStart', worldPositionStart)\n defineProperty('worldQuaternion', worldQuaternion)\n defineProperty('worldQuaternionStart', worldQuaternionStart)\n defineProperty('cameraPosition', cameraPosition)\n defineProperty('cameraQuaternion', cameraQuaternion)\n defineProperty('pointStart', pointStart)\n defineProperty('pointEnd', pointEnd)\n defineProperty('rotationAxis', rotationAxis)\n defineProperty('rotationAngle', rotationAngle)\n defineProperty('eye', eye)\n\n this._offset = new Vector3()\n this._startNorm = new Vector3()\n this._endNorm = new Vector3()\n this._cameraScale = new Vector3()\n\n this._parentPosition = new Vector3()\n this._parentQuaternion = new Quaternion()\n this._parentQuaternionInv = new Quaternion()\n this._parentScale = new Vector3()\n\n this._worldScaleStart = new Vector3()\n this._worldQuaternionInv = new Quaternion()\n this._worldScale = new Vector3()\n this._tempPosition = new Vector3()\n\n this._positionStart = new Vector3()\n this._quaternionStart = new Quaternion()\n this._scaleStart = new Vector3()\n\n this._getPointer = getPointer.bind(this)\n this._onPointerDown = onPointerDown.bind(this)\n this._onPointerHover = onPointerHover.bind(this)\n this._onPointerMove = onPointerMove.bind(this)\n this._onPointerUp = onPointerUp.bind(this)\n\n if (domElement !== null) {\n this.connect(domElement)\n }\n }\n\n connect(element: HTMLElement) {\n super.connect(element)\n\n if (this.domElement?.parentNode) {\n this.domElement.parentNode.appendChild(this._overlay)\n }\n\n this.domElement?.addEventListener('pointerdown', this._onPointerDown)\n this.domElement?.addEventListener('pointermove', this._onPointerHover)\n this.domElement?.addEventListener('pointerup', this._onPointerUp)\n\n if (this.domElement) {\n this.domElement.style.touchAction = 'none' // disable touch scroll\n }\n }\n\n disconnect() {\n if (this._overlay.parentNode) {\n this._overlay.parentNode.removeChild(this._overlay)\n }\n this.domElement?.removeEventListener('pointerdown', this._onPointerDown)\n this.domElement?.removeEventListener('pointermove', this._onPointerHover)\n this.domElement?.removeEventListener('pointermove', this._onPointerMove)\n this.domElement?.removeEventListener('pointerup', this._onPointerUp)\n\n if (this.domElement) {\n this.domElement.style.touchAction = 'auto'\n }\n }\n\n /**\n * Returns the visual representation of the controls. Add the helper to your scene to\n * visually transform the attached 3D object.\n *\n * @return {TransformControlsRoot} The helper.\n */\n getHelper() {\n return this._root\n }\n\n pointerHover(pointer) {\n if (this.object === undefined || this.dragging === true) return\n\n if (pointer !== null) _raycaster.setFromCamera(pointer, this.camera)\n\n let intersect = null\n\n if (this.mode === 'all') {\n // Check all pickers in order: scale, rotate, translate\n // This order ensures smaller handles (scale cubes) are prioritized\n intersect = intersectObjectWithRay(\n this._gizmo.picker['scale'],\n _raycaster\n )\n if (!intersect) {\n intersect = intersectObjectWithRay(\n this._gizmo.picker['rotate'],\n _raycaster\n )\n }\n if (!intersect) {\n intersect = intersectObjectWithRay(\n this._gizmo.picker['translate'],\n _raycaster\n )\n }\n } else {\n intersect = intersectObjectWithRay(\n this._gizmo.picker[this.mode],\n _raycaster\n )\n }\n\n if (intersect) {\n this.axis = intersect.object.name\n } else {\n this.axis = null\n }\n }\n\n pointerDown(pointer) {\n if (\n this.object === undefined ||\n this.dragging === true ||\n (pointer != null && pointer.button !== 0)\n )\n return\n\n if (this.axis !== null) {\n if (pointer !== null) _raycaster.setFromCamera(pointer, this.camera)\n\n // Determine which mode is active when in 'all' mode\n if (this.mode === 'all') {\n // Check which picker was intersected to determine the active mode\n let intersect = intersectObjectWithRay(\n this._gizmo.picker['scale'],\n _raycaster\n )\n if (intersect && intersect.object.name === this.axis) {\n this.activeMode = 'scale'\n } else {\n intersect = intersectObjectWithRay(\n this._gizmo.picker['rotate'],\n _raycaster\n )\n if (intersect && intersect.object.name === this.axis) {\n this.activeMode = 'rotate'\n } else {\n this.activeMode = 'translate'\n }\n }\n } else {\n this.activeMode = this.mode\n }\n\n const planeIntersect = intersectObjectWithRay(\n this._plane,\n _raycaster,\n true\n )\n\n if (planeIntersect) {\n this.object.updateMatrixWorld()\n this.object.parent.updateMatrixWorld()\n\n this._positionStart.copy(this.object.position)\n this._quaternionStart.copy(this.object.quaternion)\n this._scaleStart.copy(this.object.scale)\n\n // Use bounding box center for worldPositionStart\n const boundingBoxCenter = calculateBoundingBoxCenter(this.object)\n this.worldPositionStart.copy(boundingBoxCenter)\n\n // Still need to get rotation and scale from the object's matrix\n this.object.matrixWorld.decompose(\n this._tempPosition, // Use temporary variable for position\n this.worldQuaternionStart,\n this._worldScaleStart\n )\n\n this.pointStart.copy(planeIntersect.point).sub(this.worldPositionStart)\n }\n\n this.dragging = true\n _mouseDownEvent.mode = this.mode === 'all' ? this.activeMode : this.mode\n this.dispatchEvent(_mouseDownEvent)\n }\n }\n\n pointerMove(pointer) {\n const axis = this.axis\n // Use active mode when in 'all' mode, otherwise use the current mode\n const mode = this.mode === 'all' ? this.activeMode : this.mode\n const object = this.object\n let space = this.space\n\n if (mode === 'scale') {\n space = 'local'\n } else if (axis === 'E' || axis === 'XYZE' || axis === 'XYZ') {\n space = 'world'\n }\n\n if (\n object === undefined ||\n axis === null ||\n this.dragging === false ||\n (pointer !== null && pointer.button !== -1)\n ) {\n this._updateDistanceOverlay()\n return\n }\n\n if (pointer !== null) _raycaster.setFromCamera(pointer, this.camera)\n\n const planeIntersect = intersectObjectWithRay(this._plane, _raycaster, true)\n\n if (!planeIntersect) return\n\n this.pointEnd.copy(planeIntersect.point).sub(this.worldPositionStart)\n\n if (mode === 'translate') {\n // Apply translate\n\n this._offset.copy(this.pointEnd).sub(this.pointStart)\n\n if (space === 'local' && axis !== 'XYZ') {\n this._offset.applyQuaternion(this._worldQuaternionInv)\n }\n\n if (axis.indexOf('X') === -1) this._offset.x = 0\n if (axis.indexOf('Y') === -1) this._offset.y = 0\n if (axis.indexOf('Z') === -1) this._offset.z = 0\n\n if (space === 'local' && axis !== 'XYZ') {\n this._offset\n .applyQuaternion(this._quaternionStart)\n .divide(this._parentScale)\n } else {\n this._offset\n .applyQuaternion(this._parentQuaternionInv)\n .divide(this._parentScale)\n }\n\n object.position.copy(this._offset).add(this._positionStart)\n\n // Apply translation snap\n\n if (this.translationSnap) {\n if (space === 'local') {\n object.position.applyQuaternion(\n _tempQuaternion.copy(this._quaternionStart).invert()\n )\n\n if (axis.search('X') !== -1) {\n object.position.x =\n Math.round(object.position.x / this.translationSnap) *\n this.translationSnap\n }\n\n if (axis.search('Y') !== -1) {\n object.position.y =\n Math.round(object.position.y / this.translationSnap) *\n this.translationSnap\n }\n\n if (axis.search('Z') !== -1) {\n object.position.z =\n Math.round(object.position.z / this.translationSnap) *\n this.translationSnap\n }\n\n object.position.applyQuaternion(this._quaternionStart)\n }\n\n if (space === 'world') {\n if (object.parent) {\n object.position.add(\n _tempVector.setFromMatrixPosition(object.parent.matrixWorld)\n )\n }\n\n if (axis.search('X') !== -1) {\n object.position.x =\n Math.round(object.position.x / this.translationSnap) *\n this.translationSnap\n }\n\n if (axis.search('Y') !== -1) {\n object.position.y =\n Math.round(object.position.y / this.translationSnap) *\n this.translationSnap\n }\n\n if (axis.search('Z') !== -1) {\n object.position.z =\n Math.round(object.position.z / this.translationSnap) *\n this.translationSnap\n }\n\n if (object.parent) {\n object.position.sub(\n _tempVector.setFromMatrixPosition(object.parent.matrixWorld)\n )\n }\n }\n }\n\n object.position.x = Math.max(\n this.minX,\n Math.min(this.maxX, object.position.x)\n )\n object.position.y = Math.max(\n this.minY,\n Math.min(this.maxY, object.position.y)\n )\n object.position.z = Math.max(\n this.minZ,\n Math.min(this.maxZ, object.position.z)\n )\n } else if (mode === 'scale') {\n if (axis.search('XYZ') !== -1) {\n let d = this.pointEnd.length() / this.pointStart.length()\n\n if (this.pointEnd.dot(this.pointStart) < 0) d *= -1\n\n _tempVector2.set(d, d, d)\n } else {\n _tempVector.copy(this.pointStart)\n _tempVector2.copy(this.pointEnd)\n\n _tempVector.applyQuaternion(this._worldQuaternionInv)\n _tempVector2.applyQuaternion(this._worldQuaternionInv)\n\n _tempVector2.divide(_tempVector)\n\n if (axis.search('X') === -1) {\n _tempVector2.x = 1\n }\n\n if (axis.search('Y') === -1) {\n _tempVector2.y = 1\n }\n\n if (axis.search('Z') === -1) {\n _tempVector2.z = 1\n }\n }\n\n // Apply scale\n\n object.scale.copy(this._scaleStart).multiply(_tempVector2)\n\n if (this.scaleSnap) {\n if (axis.search('X') !== -1) {\n object.scale.x =\n Math.round(object.scale.x / this.scaleSnap) * this.scaleSnap ||\n this.scaleSnap\n }\n\n if (axis.search('Y') !== -1) {\n object.scale.y =\n Math.round(object.scale.y / this.scaleSnap) * this.scaleSnap ||\n this.scaleSnap\n }\n\n if (axis.search('Z') !== -1) {\n object.scale.z =\n Math.round(object.scale.z / this.scaleSnap) * this.scaleSnap ||\n this.scaleSnap\n }\n }\n } else if (mode === 'rotate') {\n this._offset.copy(this.pointEnd).sub(this.pointStart)\n\n const ROTATION_SPEED =\n 20 /\n this.worldPosition.distanceTo(\n _tempVector.setFromMatrixPosition(this.camera.matrixWorld)\n )\n\n let _inPlaneRotation = false\n\n if (axis === 'XYZE') {\n this.rotationAxis.copy(this._offset).cross(this.eye).normalize()\n this.rotationAngle =\n this._offset.dot(\n _tempVector.copy(this.rotationAxis).cross(this.eye)\n ) * ROTATION_SPEED\n } else if (axis === 'X' || axis === 'Y' || axis === 'Z') {\n this.rotationAxis.copy(_unit[axis])\n\n _tempVector.copy(_unit[axis])\n\n if (space === 'local') {\n _tempVector.applyQuaternion(this.worldQuaternion)\n }\n\n _tempVector.cross(this.eye)\n\n // When _tempVector is 0 after cross with this.eye the vectors are parallel and should use in-plane rotation logic.\n if (_tempVector.length() === 0) {\n _inPlaneRotation = true\n } else {\n this.rotationAngle =\n this._offset.dot(_tempVector.normalize()) * ROTATION_SPEED\n }\n }\n\n if (axis === 'E' || _inPlaneRotation) {\n this.rotationAxis.copy(this.eye)\n this.rotationAngle = this.pointEnd.angleTo(this.pointStart)\n\n this._startNorm.copy(this.pointStart).normalize()\n this._endNorm.copy(this.pointEnd).normalize()\n\n this.rotationAngle *=\n this._endNorm.cross(this._startNorm).dot(this.eye) < 0 ? 1 : -1\n }\n\n // Apply rotation snap\n\n if (this.rotationSnap)\n this.rotationAngle =\n Math.round(this.rotationAngle / this.rotationSnap) * this.rotationSnap\n\n // Clamp rotation angle to min/max limits\n this.rotationAngle = Math.max(\n this.minRotation,\n Math.min(this.maxRotation, this.rotationAngle)\n )\n\n // Apply rotate\n if (space === 'local' && axis !== 'E' && axis !== 'XYZE') {\n object.quaternion.copy(this._quaternionStart)\n object.quaternion\n .multiply(\n _tempQuaternion.setFromAxisAngle(\n this.rotationAxis,\n this.rotationAngle\n )\n )\n .normalize()\n } else {\n this.rotationAxis.applyQuaternion(this._parentQuaternionInv)\n object.quaternion.copy(\n _tempQuaternion.setFromAxisAngle(\n this.rotationAxis,\n this.rotationAngle\n )\n )\n object.quaternion.multiply(this._quaternionStart).normalize()\n }\n }\n\n this.dispatchEvent(_changeEvent)\n this.dispatchEvent(_objectChangeEvent)\n this._updateDistanceOverlay()\n }\n\n pointerUp(pointer) {\n if (pointer !== null && pointer.button !== 0) return\n\n if (this.dragging && this.axis !== null) {\n _mouseUpEvent.mode = this.mode\n this.dispatchEvent(_mouseUpEvent)\n }\n\n this.dragging = false\n this.axis = null\n this._updateDistanceOverlay()\n }\n\n dispose() {\n this.disconnect()\n\n this._root.dispose()\n }\n\n /**\n * Sets the 3D object that should be transformed and ensures the controls UI is visible.\n *\n * @param {Object3D} object - The 3D object that should be transformed.\n * @return {TransformControls} A reference to this controls.\n */\n attach(object) {\n this.object = object\n this._root.visible = true\n\n return this\n }\n\n /**\n * Removes the current 3D object from the controls and makes the helper UI invisible.\n *\n * @return {TransformControls} A reference to this controls.\n */\n detach() {\n this.object = undefined\n this.axis = null\n\n this._root.visible = false\n\n return this\n }\n\n /**\n * Resets the object's position, rotation and scale to when the current transform began.\n */\n reset() {\n if (!this.enabled) return\n\n if (this.dragging) {\n this.object.position.copy(this._positionStart)\n this.object.quaternion.copy(this._quaternionStart)\n this.object.scale.copy(this._scaleStart)\n\n this.dispatchEvent(_changeEvent)\n this.dispatchEvent(_objectChangeEvent)\n\n this.pointStart.copy(this.pointEnd)\n }\n }\n\n /**\n * Returns the raycaster that is used for user interaction. This object is shared between all\n * instances of `TransformControls`.\n *\n * @returns {Raycaster} The internal raycaster.\n */\n getRaycaster() {\n return _raycaster\n }\n\n /**\n * Returns the transformation mode.\n *\n * @returns {'translate'|'rotate'|'scale'} The transformation mode.\n */\n getMode() {\n return this.mode\n }\n\n /**\n * Sets the given transformation mode.\n *\n * @param {'translate'|'rotate'|'scale'|'all'} mode - The transformation mode to set.\n */\n setMode(mode) {\n // this.mode = mode\n }\n\n /**\n * Sets the translation snap.\n *\n * @param {?number} translationSnap - The translation snap to set.\n */\n setTranslationSnap(translationSnap) {\n this.translationSnap = translationSnap\n }\n\n /**\n * Sets the rotation snap.\n *\n * @param {?number} rotationSnap - The rotation snap to set.\n */\n setRotationSnap(rotationSnap) {\n this.rotationSnap = rotationSnap\n }\n\n /**\n * Sets the minimum rotation angle limit (in radians).\n *\n * @param {number} minRotation - The minimum rotation angle to set (in radians).\n */\n setMinRotation(minRotation) {\n this.minRotation = minRotation\n }\n\n /**\n * Sets the maximum rotation angle limit (in radians).\n *\n * @param {number} maxRotation - The maximum rotation angle to set (in radians).\n */\n setMaxRotation(maxRotation) {\n this.maxRotation = maxRotation\n }\n\n /**\n * Sets the scale snap.\n *\n * @param {?number} scaleSnap - The scale snap to set.\n */\n setScaleSnap(scaleSnap) {\n this.scaleSnap = scaleSnap\n }\n\n /**\n * Sets the size of the helper UI.\n *\n * @param {number} size - The size to set.\n */\n setSize(size) {\n this.size = size\n }\n\n /**\n * Sets the coordinate space in which transformations are applied.\n *\n * @param {'world'|'local'} space - The space to set.\n */\n setSpace(space) {\n this.space = space\n }\n\n _updateDistanceOverlay() {\n if (!this.object || !this.dragging) {\n this._overlay.classList.add('hidden')\n this._distanceLabel.visible = false\n this._rotationAngleLabel.visible = false\n return\n }\n\n if (\n this.mode === 'translate' ||\n (this.mode === 'all' && this.activeMode === 'translate')\n ) {\n // Calculate the distance moved along each axis from the start position\n const xDistance = this.object.position.x - this._positionStart.x\n const yDistance = this.object.position.y - this._positionStart.y\n const zDistance = this.object.position.z - this._positionStart.z\n\n // Calculate total distance\n const totalDistance = Math.sqrt(\n xDistance * xDistance + yDistance * yDistance + zDistance * zDistance\n )\n\n // Position the label at the midpoint between start and current position\n const midPoint = new Vector3(\n (this._positionStart.x + this.object.position.x) / 2,\n (this._positionStart.y + this.object.position.y) / 2,\n (this._positionStart.z + this.object.position.z) / 2\n )\n\n this._distanceLabel.position.copy(midPoint)\n this._distanceLabel.visible = true\n this._rotationAngleLabel.visible = false\n\n // Update label text with total distance\n this._distanceLabel.element.textContent = `${totalDistance.toFixed(3)}`\n\n this._overlay.textContent = `X: ${xDistance.toFixed(2)} Y: ${yDistance.toFixed(2)} Z: ${zDistance.toFixed(2)}`\n } else if (\n this.mode === 'rotate' ||\n (this.mode === 'all' && this.activeMode === 'rotate')\n ) {\n this._distanceLabel.visible = false\n\n // Calculate angle in degrees\n const angleDegrees = (this.rotationAngle * 180) / Math.PI\n\n // Position the label along the rotation arc\n // Use a radius slightly larger than the gizmo radius\n const labelRadius = 0.55\n const labelAngle = this.rotationAngle / 2 // Position at midpoint of arc\n\n // Calculate label position based on rotation axis\n const labelPos = new Vector3()\n\n if (this.axis === 'X' || this.axis === 'Y' || this.axis === 'Z') {\n // For axis-aligned rotations, position the label on the arc\n const axisvec = _unit[this.axis]\n const perpVector = new Vector3()\n\n // Get a perpendicular vector to the rotation axis\n if (Math.abs(axisvec.dot(this.pointStart.clone().normalize())) > 0.99) {\n // If pointStart is parallel to axis, use a different reference\n perpVector.copy(this.eye).cross(axisvec).normalize()\n } else {\n perpVector.copy(this.pointStart).normalize()\n }\n\n // Rotate the perpendicular vector by half the rotation angle\n const rotQuat = new Quaternion().setFromAxisAngle(axisvec, labelAngle)\n perpVector.applyQuaternion(rotQuat)\n\n // Apply local/world orientation\n if (this.space === 'local') {\n perpVector.applyQuaternion(this.worldQuaternion)\n }\n\n perpVector.multiplyScalar(labelRadius)\n labelPos.copy(this.worldPosition).add(perpVector)\n } else {\n // For E or XYZE mode, position near the arc center\n labelPos.copy(this.worldPosition)\n const offsetDir = this.pointStart.clone().normalize()\n\n // Apply local/world orientation\n if (this.space === 'local') {\n offsetDir.applyQuaternion(this.worldQuaternion)\n }\n\n offsetDir.multiplyScalar(labelRadius)\n labelPos.add(offsetDir)\n }\n\n this._rotationAngleLabel.position.copy(labelPos)\n this._rotationAngleLabel.visible = true\n this._rotationAngleLabel.element.textContent = `${Math.abs(angleDegrees).toFixed(1)}°`\n\n this._overlay.textContent = `X: ${(this.object.rotation.x * (180 / Math.PI)).toFixed(2)}° Y: ${(this.object.rotation.y * (180 / Math.PI)).toFixed(2)}° Z: ${(this.object.rotation.z * (180 / Math.PI)).toFixed(2)}°`\n } else if (this.mode === 'scale') {\n this._distanceLabel.visible = false\n this._rotationAngleLabel.visible = false\n this._overlay.textContent = `X: ${this.object.scale.x.toFixed(2)} Y: ${this.object.scale.y.toFixed(2)} Z: ${this.object.scale.z.toFixed(2)}`\n }\n this._overlay.classList.remove('hidden')\n }\n}\n\n// mouse / touch event handlers\n\nfunction getPointer(event) {\n if (this.domElement.ownerDocument.pointerLockElement) {\n return {\n x: 0,\n y: 0,\n button: event.button,\n }\n } else {\n const rect = this.domElement.getBoundingClientRect()\n\n return {\n x: ((event.clientX - rect.left) / rect.width) * 2 - 1,\n y: (-(event.clientY - rect.top) / rect.height) * 2 + 1,\n button: event.button,\n }\n }\n}\n\nfunction onPointerHover(event) {\n if (!this.enabled) return\n\n switch (event.pointerType) {\n case 'mouse':\n case 'pen':\n this.pointerHover(this._getPointer(event))\n break\n }\n}\n\nfunction onPointerDown(event) {\n if (!this.enabled) return\n\n if (!document.pointerLockElement) {\n this.domElement.setPointerCapture(event.pointerId)\n }\n\n this.domElement.addEventListener('pointermove', this._onPointerMove)\n\n this.pointerHover(this._getPointer(event))\n this.pointerDown(this._getPointer(event))\n}\n\nfunction onPointerMove(event) {\n if (!this.enabled) return\n\n this.pointerMove(this._getPointer(event))\n}\n\nfunction onPointerUp(event) {\n if (!this.enabled) return\n\n this.domElement.releasePointerCapture(event.pointerId)\n\n this.domElement.removeEventListener('pointermove', this._onPointerMove)\n\n this.pointerUp(this._getPointer(event))\n}\n\nfunction intersectObjectWithRay(object, raycaster, includeInvisible) {\n const allIntersections = raycaster.intersectObject(object, true)\n\n for (let i = 0; i < allIntersections.length; i++) {\n if (allIntersections[i].object.visible || includeInvisible) {\n return allIntersections[i]\n }\n }\n\n return false\n}\n\n//\n\n// Reusable utility variables\n\nconst _tempEuler = new Euler()\nconst _alignVector = new Vector3(0, 1, 0)\nconst _zeroVector = new Vector3(0, 0, 0)\nconst _lookAtMatrix = new Matrix4()\nconst _tempQuaternion2 = new Quaternion()\nconst _identityQuaternion = new Quaternion()\nconst _dirVector = new Vector3()\nconst _tempMatrix = new Matrix4()\n\nconst _unitX = new Vector3(1, 0, 0)\nconst _unitY = new Vector3(0, 1, 0)\nconst _unitZ = new Vector3(0, 0, 1)\n\nconst _v1 = new Vector3()\nconst _v2 = new Vector3()\nconst _v3 = new Vector3()\n\n// Utility function to calculate the bounding box center of an object\nexport function calculateBoundingBoxCenter(object) {\n const box = new Box3()\n\n // Compute bounding box of the object and all its children\n object.traverse((child) => {\n if (child.isMesh && child.geometry) {\n child.geometry.computeBoundingBox()\n box.expandByObject(child)\n }\n })\n\n // If no geometry found, fall back to object's world position\n if (box.isEmpty()) {\n return object.getWorldPosition(new Vector3())\n }\n\n // Calculate center of bounding box\n const center = new Vector3()\n box.getCenter(center)\n\n return center\n}\n\nclass TransformControlsRoot extends Object3D {\n constructor(controls) {\n super()\n\n this.isTransformControlsRoot = true\n\n this.controls = controls\n this.visible = false\n }\n\n // updateMatrixWorld updates key transformation variables\n updateMatrixWorld(force) {\n const controls = this.controls\n\n if (controls.object !== undefined) {\n controls.object.updateMatrixWorld()\n\n if (controls.object.parent === null) {\n console.error(\n 'TransformControls: The attached 3D object must be a part of the scene graph.'\n )\n } else {\n controls.object.parent.matrixWorld.decompose(\n controls._parentPosition,\n controls._parentQuaternion,\n controls._parentScale\n )\n }\n\n // Calculate the bounding box center instead of using object's world position\n const boundingBoxCenter = calculateBoundingBoxCenter(controls.object)\n controls.worldPosition.copy(boundingBoxCenter)\n\n // Still need to get rotation and scale from the object's matrix\n controls.object.matrixWorld.decompose(\n controls._tempPosition, // Use temporary variable for position\n controls.worldQuaternion,\n controls._worldScale\n )\n\n controls._parentQuaternionInv.copy(controls._parentQuaternion).invert()\n controls._worldQuaternionInv.copy(controls.worldQuaternion).invert()\n }\n\n controls.camera.updateMatrixWorld()\n controls.camera.matrixWorld.decompose(\n controls.cameraPosition,\n controls.cameraQuaternion,\n controls._cameraScale\n )\n\n if (controls.camera.isOrthographicCamera) {\n controls.eye\n .copy(controls.cameraPosition)\n .sub(controls.worldPosition)\n .normalize()\n } else {\n controls.eye\n .copy(controls.cameraPosition)\n .sub(controls.worldPosition)\n .normalize()\n }\n\n super.updateMatrixWorld(force)\n }\n\n dispose() {\n this.traverse(function (child) {\n if (child.geometry) child.geometry.dispose()\n if (child.material) child.material.dispose()\n })\n }\n}\n\nclass TransformControlsGizmo extends Object3D {\n constructor() {\n super()\n\n this.isTransformControlsGizmo = true\n\n this.type = 'TransformControlsGizmo'\n\n // shared materials\n\n const gizmoMaterial = new MeshBasicMaterial({\n depthTest: false,\n depthWrite: false,\n fog: false,\n toneMapped: false,\n transparent: true,\n })\n\n const gizmoLineMaterial = new LineBasicMaterial({\n depthTest: false,\n depthWrite: false,\n fog: false,\n toneMapped: false,\n transparent: true,\n })\n\n // Make unique material for each axis/color\n\n const matInvisible = gizmoMaterial.clone()\n matInvisible.opacity = 0.15\n\n const matHelper = gizmoLineMaterial.clone()\n matHelper.opacity = 0.5\n\n const matRed = gizmoMaterial.clone()\n matRed.color.setHex(0xed4358)\n\n const matGreen = gizmoMaterial.clone()\n matGreen.color.setHex(0x82cc19)\n\n const matBlue = gizmoMaterial.clone()\n matBlue.color.setHex(0x3185eb)\n\n const matRedTransparent = gizmoMaterial.clone()\n matRedTransparent.color.setHex(0xed4358)\n matRedTransparent.opacity = 0.5\n\n const matGreenTransparent = gizmoMaterial.clone()\n matGreenTransparent.color.setHex(0x82cc19)\n matGreenTransparent.opacity = 0.5\n\n const matBlueTransparent = gizmoMaterial.clone()\n matBlueTransparent.color.setHex(0x3185eb)\n matBlueTransparent.opacity = 0.5\n\n const matWhiteTransparent = gizmoMaterial.clone()\n matWhiteTransparent.opacity = 0.25\n\n const matYellowTransparent = gizmoMaterial.clone()\n matYellowTransparent.color.setHex(0xffff00)\n matYellowTransparent.opacity = 0.25\n\n const matYellow = gizmoMaterial.clone()\n matYellow.color.setHex(0xffff00)\n\n const matGray = gizmoMaterial.clone()\n matGray.color.setHex(0x787878)\n\n // reusable geometry\n\n const arrowGeometry = new CylinderGeometry(0, 0.04, 0.1, 12)\n arrowGeometry.translate(0, 0.05, 0)\n\n const scaleHandleGeometry = new BoxGeometry(0.08, 0.08, 0.08)\n scaleHandleGeometry.translate(0, 0.04, 0)\n\n const lineGeometry = new BufferGeometry()\n lineGeometry.setAttribute(\n 'position',\n new Float32BufferAttribute([0, 0, 0, 1, 0, 0], 3)\n )\n\n const lineGeometry2 = new CylinderGeometry(0.02, 0.02, 0.5, 3)\n lineGeometry2.translate(0, 0.25, 0)\n\n function CircleGeometry(radius, arc) {\n const geometry = new TorusGeometry(radius, 0.02, 3, 64, arc * Math.PI * 2)\n geometry.rotateY(Math.PI / 2)\n geometry.rotateX(Math.PI / 2)\n return geometry\n }\n\n // Special geometry for transform helper. If scaled with position vector it spans from [0,0,0] to position\n\n function TranslateHelperGeometry() {\n const geometry = new BufferGeometry()\n\n geometry.setAttribute(\n 'position',\n new Float32BufferAttribute([0, 0, 0, 1, 1, 1], 3)\n )\n\n return geometry\n }\n\n // Gizmo definitions - custom hierarchy definitions for setupGizmo() function\n\n const gizmoTranslate = {\n X: [\n [new Mesh(arrowGeometry, matRed), [0.5, 0, 0], [0, 0, -Math.PI / 2]],\n [new Mesh(lineGeometry2, matRed), [0, 0, 0], [0, 0, -Math.PI / 2]],\n ],\n Y: [\n [new Mesh(arrowGeometry, matGreen), [0, 0.5, 0]],\n [new Mesh(lineGeometry2, matGreen)],\n ],\n Z: [\n [new Mesh(arrowGeometry, matBlue), [0, 0, 0.5], [Math.PI / 2, 0, 0]],\n [new Mesh(lineGeometry2, matBlue), null, [Math.PI / 2, 0, 0]],\n ],\n }\n\n const pickerTranslate = {\n X: [\n [\n new Mesh(new CylinderGeometry(0.2, 0, 0.6, 4), matInvisible),\n [0.3, 0, 0],\n [0, 0, -Math.PI / 2],\n ],\n [\n new Mesh(new CylinderGeometry(0.2, 0, 0.6, 4), matInvisible),\n [-0.3, 0, 0],\n [0, 0, Math.PI / 2],\n ],\n ],\n Y: [\n [\n new Mesh(new CylinderGeometry(0.2, 0, 0.6, 4), matInvisible),\n [0, 0.3, 0],\n ],\n [\n new Mesh(new CylinderGeometry(0.2, 0, 0.6, 4), matInvisible),\n [0, -0.3, 0],\n [0, 0, Math.PI],\n ],\n ],\n Z: [\n [\n new Mesh(new CylinderGeometry(0.2, 0, 0.6, 4), matInvisible),\n [0, 0, 0.3],\n [Math.PI / 2, 0, 0],\n ],\n [\n new Mesh(new CylinderGeometry(0.2, 0, 0.6, 4), matInvisible),\n [0, 0, -0.3],\n [-Math.PI / 2, 0, 0],\n ],\n ],\n }\n\n const helperTranslate = {\n START: [\n [\n new Mesh(new OctahedronGeometry(0.01, 2), matHelper),\n null,\n null,\n null,\n 'helper',\n ],\n ],\n END: [\n [\n new Mesh(new OctahedronGeometry(0.01, 2), matHelper),\n null,\n null,\n null,\n 'helper',\n ],\n ],\n DELTA: [\n [\n new Line(TranslateHelperGeometry(), matHelper),\n null,\n null,\n null,\n 'helper',\n ],\n ],\n }\n\n const gizmoRotate = {\n X: [[new Mesh(CircleGeometry(0.45, 0.25), matRed)]],\n Y: [\n [\n new Mesh(CircleGeometry(0.45, 0.25), matGreen),\n null,\n [0, 0, -Math.PI / 2],\n ],\n ],\n Z: [\n [\n new Mesh(CircleGeometry(0.45, 0.25), matBlue),\n null,\n [0, Math.PI / 2, 0],\n ],\n ],\n }\n\n const helperRotate = {\n AXIS: [],\n START: [\n [new Line(lineGeometry.clone(), matHelper), null, null, null, 'helper'],\n ],\n END: [\n [new Line(lineGeometry.clone(), matHelper), null, null, null, 'helper'],\n ],\n ARC: [\n [new Line(new BufferGeometry(), matHelper), null, null, null, 'helper'],\n ],\n }\n\n const pickerRotate = {\n X: [[new Mesh(CircleGeometry(0.45, 0.25), matRed)]],\n Y: [\n [\n new Mesh(CircleGeometry(0.45, 0.25), matGreen),\n null,\n [0, 0, -Math.PI / 2],\n ],\n ],\n Z: [\n [\n new Mesh(CircleGeometry(0.45, 0.25), matBlue),\n null,\n [0, Math.PI / 2, 0],\n ],\n ],\n }\n\n const gizmoScale = {\n X: [\n [\n new Mesh(scaleHandleGeometry, matRed),\n [0.7, 0, 0],\n [0, 0, -Math.PI / 2],\n ],\n ],\n Y: [[new Mesh(scaleHandleGeometry, matGreen), [0, 0.7, 0]]],\n Z: [\n [\n new Mesh(scaleHandleGeometry, matBlue),\n [0, 0, 0.7],\n [Math.PI / 2, 0, 0],\n ],\n ],\n }\n\n const pickerScale = {\n X: [\n [\n new Mesh(new BoxGeometry(0.2, 0.2, 0.2), matInvisible),\n [0.7, 0, 0],\n [0, 0, -Math.PI / 2],\n ],\n ],\n Y: [\n [new Mesh(new BoxGeometry(0.2, 0.2, 0.2), matInvisible), [0, 0.7, 0]],\n ],\n Z: [\n [\n new Mesh(new BoxGeometry(0.2, 0.2, 0.2), matInvisible),\n [0, 0, 0.7],\n [Math.PI / 2, 0, 0],\n ],\n ],\n }\n\n const helperScale = {\n X: [],\n Y: [],\n Z: [],\n }\n\n // Creates an Object3D with gizmos described in custom hierarchy definition.\n\n function setupGizmo(gizmoMap) {\n const gizmo = new Object3D()\n\n for (const name in gizmoMap) {\n for (let i = gizmoMap[name].length; i--; ) {\n const object = gizmoMap[name][i][0].clone()\n object.userData.type = 'gizmo'\n const position = gizmoMap[name][i][1]\n const rotation = gizmoMap[name][i][2]\n const scale = gizmoMap[name][i][3]\n const tag = gizmoMap[name][i][4]\n\n // name and tag properties are essential for picking and updating logic.\n object.name = name\n object.tag = tag\n\n if (position) {\n object.position.set(position[0], position[1], position[2])\n }\n\n if (rotation) {\n object.rotation.set(rotation[0], rotation[1], rotation[2])\n }\n\n if (scale) {\n object.scale.set(scale[0], scale[1], scale[2])\n }\n\n object.updateMatrix()\n\n const tempGeometry = object.geometry.clone()\n tempGeometry.applyMatrix4(object.matrix)\n object.geometry = tempGeometry\n object.renderOrder = Infinity\n\n object.position.set(0, 0, 0)\n object.rotation.set(0, 0, 0)\n object.scale.set(1, 1, 1)\n\n gizmo.add(object)\n }\n }\n\n return gizmo\n }\n\n // Gizmo creation\n\n this.gizmo = {}\n this.picker = {}\n this.helper = {}\n\n this.add((this.gizmo['translate'] = setupGizmo(gizmoTranslate)))\n this.add((this.gizmo['rotate'] = setupGizmo(gizmoRotate)))\n this.add((this.gizmo['scale'] = setupGizmo(gizmoScale)))\n this.add((this.picker['translate'] = setupGizmo(pickerTranslate)))\n this.add((this.picker['rotate'] = setupGizmo(pickerRotate)))\n this.add((this.picker['scale'] = setupGizmo(pickerScale)))\n this.add((this.helper['translate'] = setupGizmo(helperTranslate)))\n this.add((this.helper['rotate'] = setupGizmo(helperRotate)))\n this.add((this.helper['scale'] = setupGizmo(helperScale)))\n\n // Pickers should be hidden always\n\n this.picker['translate'].visible = false\n this.picker['rotate'].visible = false\n this.picker['scale'].visible = false\n }\n\n // updateMatrixWorld will update transformations and appearance of individual handles\n\n updateMatrixWorld(force) {\n const space = this.mode === 'scale' ? 'local' : this.space // scale always oriented to local rotation\n\n const quaternion =\n space === 'local' ? this.worldQuaternion : _identityQuaternion\n\n // Show gizmos based on mode\n if (this.mode === 'all') {\n // Show all gizmos simultaneously\n this.gizmo['translate'].visible = true\n this.gizmo['rotate'].visible = true\n this.gizmo['scale'].visible = true\n\n this.helper['translate'].visible = true\n this.helper['rotate'].visible = true\n this.helper['scale'].visible = false\n } else {\n // Show only gizmos for current transform mode\n this.gizmo['translate'].visible = this.mode === 'translate'\n this.gizmo['rotate'].visible = this.mode === 'rotate'\n this.gizmo['scale'].visible = this.mode === 'scale'\n\n this.helper['translate'].visible = this.mode === 'translate'\n this.helper['rotate'].visible = this.mode === 'rotate'\n this.helper['scale'].visible = this.mode === 'scale'\n }\n\n let handles = []\n if (this.mode === 'all') {\n // Include all pickers and gizmos\n handles = handles.concat(this.picker['translate'].children)\n handles = handles.concat(this.picker['rotate'].children)\n handles = handles.concat(this.picker['scale'].children)\n handles = handles.concat(this.gizmo['translate'].children)\n handles = handles.concat(this.gizmo['rotate'].children)\n handles = handles.concat(this.gizmo['scale'].children)\n handles = handles.concat(this.helper['translate'].children)\n handles = handles.concat(this.helper['rotate'].children)\n } else {\n handles = handles.concat(this.picker[this.mode].children)\n handles = handles.concat(this.gizmo[this.mode].children)\n handles = handles.concat(this.helper[this.mode].children)\n }\n\n for (let i = 0; i < handles.length; i++) {\n const handle = handles[i]\n\n // hide aligned to camera\n\n handle.visible = true\n handle.rotation.set(0, 0, 0)\n handle.position.copy(this.worldPosition)\n\n let factor\n\n if (this.camera.isOrthographicCamera) {\n factor = (this.camera.top - this.camera.bottom) / this.camera.zoom\n } else {\n factor =\n this.worldPosition.distanceTo(this.cameraPosition) *\n Math.min(\n (1.9 * Math.tan((Math.PI * this.camera.fov) / 360)) /\n this.camera.zoom,\n 7\n )\n }\n\n handle.scale.set(1, 1, 1).multiplyScalar((factor * this.size) / 4)\n\n // TODO: simplify helpers and consider decoupling from gizmo\n\n if (handle.tag === 'helper') {\n handle.visible = false\n\n if (handle.name === 'AXIS') {\n handle.visible = !!this.axis\n\n if (this.axis === 'X') {\n _tempQuaternion.setFromEuler(_tempEuler.set(0, 0, 0))\n handle.quaternion.copy(quaternion).multiply(_tempQuaternion)\n\n if (\n Math.abs(\n _alignVector\n .copy(_unitX)\n .applyQuaternion(quaternion)\n .dot(this.eye)\n ) > 0.9\n ) {\n handle.visible = false\n }\n }\n\n if (this.axis === 'Y') {\n _tempQuaternion.setFromEuler(_tempEuler.set(0, 0, Math.PI / 2))\n handle.quaternion.copy(quaternion).multiply(_tempQuaternion)\n\n if (\n Math.abs(\n _alignVector\n .copy(_unitY)\n .applyQuaternion(quaternion)\n .dot(this.eye)\n ) > 0.9\n ) {\n handle.visible = false\n }\n }\n\n if (this.axis === 'Z') {\n _tempQuaternion.setFromEuler(_tempEuler.set(0, Math.PI / 2, 0))\n handle.quaternion.copy(quaternion).multiply(_tempQuaternion)\n\n if (\n Math.abs(\n _alignVector\n .copy(_unitZ)\n .applyQuaternion(quaternion)\n .dot(this.eye)\n ) > 0.9\n ) {\n handle.visible = false\n }\n }\n\n if (this.axis === 'XYZE') {\n _tempQuaternion.setFromEuler(_tempEuler.set(0, Math.PI / 2, 0))\n _alignVector.copy(this.rotationAxis)\n handle.quaternion.setFromRotationMatrix(\n _lookAtMatrix.lookAt(_zeroVector, _alignVector, _unitY)\n )\n handle.quaternion.multiply(_tempQuaternion)\n handle.visible = this.dragging\n }\n\n if (this.axis === 'E') {\n handle.visible = false\n }\n } else if (handle.name === 'START') {\n // For rotation mode, show a line from center to start point\n if (this.mode === 'rotate' || this.mode === 'all') {\n handle.position.copy(this.worldPosition)\n // Only show when dragging rotation\n const isRotating =\n this.mode === 'rotate' ||\n (this.mode === 'all' && this.activeMode === 'rotate')\n handle.visible = this.dragging && isRotating\n\n if (handle.visible) {\n // Respect space setting (local vs world)\n const rotSpace = this.space\n\n // Apply quaternion based on space - use START quaternion to keep line fixed\n if (rotSpace === 'local') {\n handle.quaternion.copy(this.worldQuaternionStart)\n } else {\n handle.quaternion.copy(_identityQuaternion)\n }\n\n // Get the rotation axis\n let rotAxis = new Vector3()\n if (this.axis === 'X' || this.axis === 'Y' || this.axis === 'Z') {\n rotAxis.copy(_unit[this.axis])\n } else if (this.axis === 'E' || this.axis === 'XYZE') {\n rotAxis.copy(this.rotationAxis)\n if (rotSpace === 'local') {\n rotAxis.applyQuaternion(\n this.worldQuaternionStart.clone().invert()\n )\n }\n }\n\n // Transform pointStart to handle's local space\n let startPoint = this.pointStart.clone()\n if (rotSpace === 'local') {\n startPoint.applyQuaternion(\n this.worldQuaternionStart.clone().invert()\n )\n }\n\n // Project onto the plane perpendicular to the rotation axis\n // Remove the component along the rotation axis\n const dotProduct = startPoint.dot(rotAxis)\n startPoint.sub(rotAxis.clone().multiplyScalar(dotProduct))\n startPoint.normalize()\n startPoint.multiplyScalar(0.45)\n\n // Update the line geometry to point from center to pointStart\n const startLineGeometry = new BufferGeometry()\n startLineGeometry.setAttribute(\n 'position',\n new Float32BufferAttribute(\n [0, 0, 0, startPoint.x, startPoint.y, startPoint.z],\n 3\n )\n )\n handle.geometry.dispose()\n handle.geometry = startLineGeometry\n }\n } else {\n handle.position.copy(this.worldPositionStart)\n handle.visible = this.dragging && this.mode === 'translate'\n }\n } else if (handle.name === 'ARC') {\n // Draw arc showing rotation angle\n const isRotating =\n this.mode === 'rotate' ||\n (this.mode === 'all' && this.activeMode === 'rotate')\n handle.visible = this.dragging && isRotating\n\n if (handle.visible && this.rotationAngle !== 0) {\n handle.position.copy(this.worldPosition)\n\n // Respect space setting (local vs world)\n const rotSpace = this.space\n\n // Apply quaternion based on space - use START quaternion to keep arc fixed\n if (rotSpace === 'local') {\n handle.quaternion.copy(this.worldQuaternionStart)\n } else {\n handle.quaternion.copy(_identityQuaternion)\n }\n\n // Create arc geometry\n const arcRadius = 0.45\n const segments = Math.max(\n 8,\n Math.floor(Math.abs(this.rotationAngle) * 50)\n )\n const arcPoints = []\n\n // Get the rotation axis in local space\n let rotAxis = new Vector3()\n if (this.axis === 'X' || this.axis === 'Y' || this.axis === 'Z') {\n rotAxis.copy(_unit[this.axis])\n // In local mode, axis is already in local space, no transformation needed\n // In world mode, we need to transform from world to handle space\n if (rotSpace !== 'local') {\n // Axis stays as is in world mode\n }\n } else if (this.axis === 'E' || this.axis === 'XYZE') {\n rotAxis.copy(this.rotationAxis)\n // Transform rotation axis to handle's local space\n if (rotSpace === 'local') {\n rotAxis.applyQuaternion(\n this.worldQuaternionStart.clone().invert()\n )\n }\n }\n\n // Transform pointStart to handle's local space\n let startDir = this.pointStart.clone()\n if (rotSpace === 'local') {\n // Transform from world space to local space\n startDir.applyQuaternion(\n this.worldQuaternionStart.clone().invert()\n )\n }\n\n // Project onto the plane perpendicular to the rotation axis\n const dotProduct = startDir.dot(rotAxis)\n startDir.sub(rotAxis.clone().multiplyScalar(dotProduct))\n startDir.normalize()\n\n // Create the arc by rotating the start point around the axis\n for (let j = 0; j <= segments; j++) {\n const angle = (this.rotationAngle * j) / segments\n const point = startDir.clone()\n const arcQuat = new Quaternion().setFromAxisAngle(rotAxis, angle)\n point.applyQuaternion(arcQuat)\n point.multiplyScalar(arcRadius)\n arcPoints.push(point.x, point.y, point.z)\n }\n\n const arcGeometry = new BufferGeometry()\n arcGeometry.setAttribute(\n 'position',\n new Float32BufferAttribute(arcPoints, 3)\n )\n handle.geometry.dispose()\n handle.geometry = arcGeometry\n }\n } else if (handle.name === 'END') {\n // For rotation mode, show a line from center to current rotation point\n if (this.mode === 'rotate' || this.mode === 'all') {\n handle.position.copy(this.worldPosition)\n // Only show when dragging rotation\n const isRotating =\n this.mode === 'rotate' ||\n (this.mode === 'all' && this.activeMode === 'rotate')\n handle.visible = this.dragging && isRotating\n\n if (handle.visible) {\n // Respect space setting (local vs world)\n const rotSpace = this.space\n\n // Use START quaternion to match the arc's coordinate space\n if (rotSpace === 'local') {\n handle.quaternion.copy(this.worldQuaternionStart)\n } else {\n handle.quaternion.copy(_identityQuaternion)\n }\n\n // Calculate end point by rotating start point (same as arc)\n const endLineGeometry = new BufferGeometry()\n\n // Get the rotation axis in local space\n let rotAxis = new Vector3()\n if (this.axis === 'X' || this.axis === 'Y' || this.axis === 'Z') {\n rotAxis.copy(_unit[this.axis])\n } else if (this.axis === 'E' || this.axis === 'XYZE') {\n rotAxis.copy(this.rotationAxis)\n if (rotSpace === 'local') {\n rotAxis.applyQuaternion(\n this.worldQuaternionStart.clone().invert()\n )\n }\n }\n\n // Transform pointStart to handle's local space\n let startDir = this.pointStart.clone()\n if (rotSpace === 'local') {\n startDir.applyQuaternion(\n this.worldQuaternionStart.clone().invert()\n )\n }\n\n // Project onto the plane perpendicular to the rotation axis\n const dotProduct = startDir.dot(rotAxis)\n startDir.sub(rotAxis.clone().multiplyScalar(dotProduct))\n startDir.normalize()\n\n // Rotate by the full rotation angle to get end point\n const endPoint = startDir.clone()\n const arcQuat = new Quaternion().setFromAxisAngle(\n rotAxis,\n this.rotationAngle\n )\n endPoint.applyQuaternion(arcQuat)\n endPoint.multiplyScalar(0.45)\n\n endLineGeometry.setAttribute(\n 'position',\n new Float32BufferAttribute(\n [0, 0, 0, endPoint.x, endPoint.y, endPoint.z],\n 3\n )\n )\n handle.geometry.dispose()\n handle.geometry = endLineGeometry\n }\n } else {\n handle.position.copy(this.worldPosition)\n handle.visible = false\n }\n } else if (handle.name === 'DELTA') {\n handle.position.copy(this.worldPositionStart)\n handle.quaternion.copy(this.worldQuaternionStart)\n _tempVector\n .set(1e-10, 1e-10, 1e-10)\n .add(this.worldPositionStart)\n .sub(this.worldPosition)\n .multiplyScalar(-1)\n _tempVector.applyQuaternion(\n this.worldQuaternionStart.clone().invert()\n )\n handle.scale.copy(_tempVector)\n handle.visible = this.dragging\n } else {\n handle.quaternion.copy(quaternion)\n\n if (this.dragging) {\n handle.position.copy(this.worldPositionStart)\n } else {\n handle.position.copy(this.worldPosition)\n }\n\n if (this.axis) {\n handle.visible = this.axis.search(handle.name) !== -1\n }\n }\n\n // If updating helper, skip rest of the loop\n continue\n }\n\n // Align handles to current local or world rotation\n\n handle.quaternion.copy(quaternion)\n\n if (this.mode === 'translate' || this.mode === 'scale') {\n // Hide translate and scale axis facing the camera\n\n const AXIS_HIDE_THRESHOLD = 0.99\n const PLANE_HIDE_THRESHOLD = 0.2\n\n if (handle.name === 'X') {\n if (\n Math.abs(\n _alignVector\n .copy(_unitX)\n .applyQuaternion(quaternion)\n .dot(this.eye)\n ) > AXIS_HIDE_THRESHOLD\n ) {\n handle.scale.set(1e-10, 1e-10, 1e-10)\n handle.visible = false\n }\n }\n\n if (handle.name === 'Y') {\n if (\n Math.abs(\n _alignVector\n .copy(_unitY)\n .applyQuaternion(quaternion)\n .dot(this.eye)\n ) > AXIS_HIDE_THRESHOLD\n ) {\n handle.scale.set(1e-10, 1e-10, 1e-10)\n handle.visible = false\n }\n }\n\n if (handle.name === 'Z') {\n if (\n Math.abs(\n _alignVector\n .copy(_unitZ)\n .applyQuaternion(quaternion)\n .dot(this.eye)\n ) > AXIS_HIDE_THRESHOLD\n ) {\n handle.scale.set(1e-10, 1e-10, 1e-10)\n handle.visible = false\n }\n }\n\n if (handle.name === 'XY') {\n if (\n Math.abs(\n _alignVector\n .copy(_unitZ)\n .applyQuaternion(quaternion)\n .dot(this.eye)\n ) < PLANE_HIDE_THRESHOLD\n ) {\n handle.scale.set(1e-10, 1e-10, 1e-10)\n handle.visible = false\n }\n }\n\n if (handle.name === 'YZ') {\n if (\n Math.abs(\n _alignVector\n .copy(_unitX)\n .applyQuaternion(quaternion)\n .dot(this.eye)\n ) < PLANE_HIDE_THRESHOLD\n ) {\n handle.scale.set(1e-10, 1e-10, 1e-10)\n handle.visible = false\n }\n }\n\n if (handle.name === 'XZ') {\n if (\n Math.abs(\n _alignVector\n .copy(_unitY)\n .applyQuaternion(quaternion)\n .dot(this.eye)\n ) < PLANE_HIDE_THRESHOLD\n ) {\n handle.scale.set(1e-10, 1e-10, 1e-10)\n handle.visible = false\n }\n }\n } else if (this.mode === 'rotate') {\n // Align handles to current local or world rotation\n\n _tempQuaternion2.copy(quaternion)\n _alignVector\n .copy(this.eye)\n .applyQuaternion(_tempQuaternion.copy(quaternion).invert())\n\n if (handle.name.search('E') !== -1) {\n handle.quaternion.setFromRotationMatrix(\n _lookAtMatrix.lookAt(this.eye, _zeroVector, _unitY)\n )\n }\n\n if (handle.name === 'X') {\n _tempQuaternion.setFromAxisAngle(\n _unitX,\n Math.atan2(-_alignVector.y, _alignVector.z)\n )\n _tempQuaternion.multiplyQuaternions(_tempQuaternion2, _tempQuaternion)\n handle.quaternion.copy(_tempQuaternion)\n }\n\n if (handle.name === 'Y') {\n _tempQuaternion.setFromAxisAngle(\n _unitY,\n Math.atan2(_alignVector.x, _alignVector.z)\n )\n _tempQuaternion.multiplyQuaternions(_tempQuaternion2, _tempQuaternion)\n handle.quaternion.copy(_tempQuaternion)\n }\n\n if (handle.name === 'Z') {\n _tempQuaternion.setFromAxisAngle(\n _unitZ,\n Math.atan2(_alignVector.y, _alignVector.x)\n )\n _tempQuaternion.multiplyQuaternions(_tempQuaternion2, _tempQuaternion)\n handle.quaternion.copy(_tempQuaternion)\n }\n }\n\n // Hide disabled axes\n handle.visible =\n handle.visible && (handle.name.indexOf('X') === -1 || this.showX)\n handle.visible =\n handle.visible && (handle.name.indexOf('Y') === -1 || this.showY)\n handle.visible =\n handle.visible && (handle.name.indexOf('Z') === -1 || this.showZ)\n handle.visible =\n handle.visible &&\n (handle.name.indexOf('E') === -1 ||\n (this.showX && this.showY && this.showZ))\n\n // highlight selected axis\n\n handle.material._color =\n handle.material._color || handle.material.color.clone()\n handle.material._opacity =\n handle.material._opacity || handle.material.opacity\n\n handle.material.color.copy(handle.material._color)\n handle.material.opacity = handle.material._opacity\n\n // Apply transparency to all materials when dragging\n if (this.dragging) {\n handle.material.opacity = 0.2\n }\n\n if (this.enabled && this.axis) {\n if (handle.name === this.axis) {\n handle.material.color.setHex(0xffff00)\n if (!this.dragging) {\n handle.material.opacity = 1.0\n }\n } else if (\n this.axis.split('').some(function (a) {\n return handle.name === a\n })\n ) {\n handle.material.color.setHex(0xffff00)\n if (!this.dragging) {\n handle.material.opacity = 1.0\n }\n }\n }\n }\n\n super.updateMatrixWorld(force)\n }\n}\n\n//\n\nclass TransformControlsPlane extends Mesh {\n constructor() {\n super(\n new PlaneGeometry(100000, 100000, 2, 2),\n new MeshBasicMaterial({\n visible: false,\n wireframe: true,\n side: DoubleSide,\n transparent: true,\n opacity: 0.1,\n toneMapped: false,\n })\n )\n\n this.isTransformControlsPlane = true\n\n this.type = 'TransformControlsPlane'\n }\n\n updateMatrixWorld(force) {\n let space = this.space\n\n this.position.copy(this.worldPosition)\n\n if (this.mode === 'scale') space = 'local' // scale always oriented to local rotation\n\n _v1\n .copy(_unitX)\n .applyQuaternion(\n space === 'local' ? this.worldQuaternion : _identityQuaternion\n )\n _v2\n .copy(_unitY)\n .applyQuaternion(\n space === 'local' ? this.worldQuaternion : _identityQuaternion\n )\n _v3\n .copy(_unitZ)\n .applyQuaternion(\n space === 'local' ? this.worldQuaternion : _identityQuaternion\n )\n\n // Align the plane for current transform mode, axis and space.\n\n _alignVector.copy(_v2)\n\n switch (this.mode) {\n case 'translate':\n case 'scale':\n switch (this.axis) {\n case 'X':\n _alignVector.copy(this.eye).cross(_v1)\n _dirVector.copy(_v1).cross(_alignVector)\n break\n case 'Y':\n _alignVector.copy(this.eye).cross(_v2)\n _dirVector.copy(_v2).cross(_alignVector)\n break\n case 'Z':\n _alignVector.copy(this.eye).cross(_v3)\n _dirVector.copy(_v3).cross(_alignVector)\n break\n case 'XY':\n _dirVector.copy(_v3)\n break\n case 'YZ':\n _dirVector.copy(_v1)\n break\n case 'XZ':\n _alignVector.copy(_v3)\n _dirVector.copy(_v2)\n break\n case 'XYZ':\n case 'E':\n _dirVector.set(0, 0, 0)\n break\n }\n\n break\n case 'rotate':\n default:\n // special case for rotate\n _dirVector.set(0, 0, 0)\n }\n\n if (_dirVector.length() === 0) {\n // If in rotate mode, make the plane parallel to camera\n this.quaternion.copy(this.cameraQuaternion)\n } else {\n _tempMatrix.lookAt(_tempVector.set(0, 0, 0), _dirVector, _alignVector)\n\n this.quaternion.setFromRotationMatrix(_tempMatrix)\n }\n\n super.updateMatrixWorld(force)\n }\n}\n\nexport { TransformControls, TransformControlsGizmo, TransformControlsPlane }\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
// packages/camera/src/DualCameraControls.ts
|
|
2
|
+
import * as THREE from "three";
|
|
3
|
+
import CameraControls from "camera-controls";
|
|
4
|
+
var controlsInstalled = false;
|
|
5
|
+
var tempVec3A = new THREE.Vector3();
|
|
6
|
+
var tempVec3B = new THREE.Vector3();
|
|
7
|
+
var tempVec2 = new THREE.Vector2();
|
|
8
|
+
function ensureCameraControlsInstalled() {
|
|
9
|
+
if (!controlsInstalled) {
|
|
10
|
+
CameraControls.install({ THREE });
|
|
11
|
+
controlsInstalled = true;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function toVector3(value, fallback, target) {
|
|
15
|
+
if (!value) {
|
|
16
|
+
target.set(fallback[0], fallback[1], fallback[2]);
|
|
17
|
+
return target;
|
|
18
|
+
}
|
|
19
|
+
if (Array.isArray(value)) {
|
|
20
|
+
target.set(value[0], value[1], value[2]);
|
|
21
|
+
return target;
|
|
22
|
+
}
|
|
23
|
+
target.copy(value);
|
|
24
|
+
return target;
|
|
25
|
+
}
|
|
26
|
+
var DualCameraControls = class extends CameraControls {
|
|
27
|
+
constructor(renderer, options = {}) {
|
|
28
|
+
ensureCameraControlsInstalled();
|
|
29
|
+
const { domElement = renderer.domElement } = options;
|
|
30
|
+
const aspect = resolveAspect(renderer, domElement);
|
|
31
|
+
const perspectiveConfig = options.perspective ?? {};
|
|
32
|
+
const orthographicConfig = options.orthographic ?? {};
|
|
33
|
+
const perspectiveCamera = new THREE.PerspectiveCamera(
|
|
34
|
+
perspectiveConfig.fov ?? 60,
|
|
35
|
+
aspect,
|
|
36
|
+
perspectiveConfig.near ?? 0.1,
|
|
37
|
+
perspectiveConfig.far ?? 2e3
|
|
38
|
+
);
|
|
39
|
+
perspectiveCamera.position.copy(
|
|
40
|
+
toVector3(
|
|
41
|
+
perspectiveConfig.position,
|
|
42
|
+
[12, 12, 12],
|
|
43
|
+
new THREE.Vector3()
|
|
44
|
+
)
|
|
45
|
+
);
|
|
46
|
+
if (perspectiveConfig.zoom !== void 0) {
|
|
47
|
+
perspectiveCamera.zoom = perspectiveConfig.zoom;
|
|
48
|
+
perspectiveCamera.updateProjectionMatrix();
|
|
49
|
+
}
|
|
50
|
+
const orthoHalfHeight = Math.max(orthographicConfig.size ?? 20, 1e-3) * 0.5;
|
|
51
|
+
const orthoHalfWidth = orthoHalfHeight * aspect;
|
|
52
|
+
const orthographicCamera = new THREE.OrthographicCamera(
|
|
53
|
+
-orthoHalfWidth,
|
|
54
|
+
orthoHalfWidth,
|
|
55
|
+
orthoHalfHeight,
|
|
56
|
+
-orthoHalfHeight,
|
|
57
|
+
orthographicConfig.near ?? 0.1,
|
|
58
|
+
orthographicConfig.far ?? 2e3
|
|
59
|
+
);
|
|
60
|
+
orthographicCamera.position.copy(
|
|
61
|
+
toVector3(
|
|
62
|
+
orthographicConfig.position,
|
|
63
|
+
[12, 12, 12],
|
|
64
|
+
new THREE.Vector3()
|
|
65
|
+
)
|
|
66
|
+
);
|
|
67
|
+
if (orthographicConfig.zoom !== void 0) {
|
|
68
|
+
orthographicCamera.zoom = orthographicConfig.zoom;
|
|
69
|
+
orthographicCamera.updateProjectionMatrix();
|
|
70
|
+
}
|
|
71
|
+
const initialMode = options.initialMode ?? "perspective";
|
|
72
|
+
const initialCamera = initialMode === "orthographic" ? orthographicCamera : perspectiveCamera;
|
|
73
|
+
super(initialCamera, domElement);
|
|
74
|
+
this.updateClock = new THREE.Clock();
|
|
75
|
+
const initialTarget = toVector3(
|
|
76
|
+
options.initialTarget,
|
|
77
|
+
[0, 0, 0],
|
|
78
|
+
new THREE.Vector3()
|
|
79
|
+
);
|
|
80
|
+
void this.setLookAt(
|
|
81
|
+
initialCamera.position.x,
|
|
82
|
+
initialCamera.position.y,
|
|
83
|
+
initialCamera.position.z,
|
|
84
|
+
initialTarget.x,
|
|
85
|
+
initialTarget.y,
|
|
86
|
+
initialTarget.z,
|
|
87
|
+
false
|
|
88
|
+
);
|
|
89
|
+
this.renderer = renderer;
|
|
90
|
+
this.domElementRef = domElement;
|
|
91
|
+
this.perspectiveCamera = perspectiveCamera;
|
|
92
|
+
this.orthographicCamera = orthographicCamera;
|
|
93
|
+
this.activeMode = initialMode;
|
|
94
|
+
this.minOrthoHalfHeight = orthoHalfHeight;
|
|
95
|
+
this.updateInputBindingsForMode(initialMode);
|
|
96
|
+
}
|
|
97
|
+
get mode() {
|
|
98
|
+
return this.activeMode;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Returns the currently active camera instance.
|
|
102
|
+
*/
|
|
103
|
+
get activeCamera() {
|
|
104
|
+
return this.camera;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Switch to the perspective camera while keeping the current framing.
|
|
108
|
+
*/
|
|
109
|
+
switchToPerspective(enableTransition = false) {
|
|
110
|
+
if (this.activeMode === "perspective") {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const target = this.getTarget(tempVec3A);
|
|
114
|
+
const position = this.getPosition(tempVec3B);
|
|
115
|
+
const aspect = resolveAspect(this.renderer, this.domElementRef);
|
|
116
|
+
this.perspectiveCamera.aspect = aspect;
|
|
117
|
+
this.perspectiveCamera.position.copy(position);
|
|
118
|
+
this.perspectiveCamera.quaternion.copy(this.camera.quaternion);
|
|
119
|
+
this.perspectiveCamera.up.copy(this.camera.up);
|
|
120
|
+
this.perspectiveCamera.updateProjectionMatrix();
|
|
121
|
+
this.camera = this.perspectiveCamera;
|
|
122
|
+
this.activeMode = "perspective";
|
|
123
|
+
this.updateInputBindingsForMode("perspective");
|
|
124
|
+
void this.setLookAt(
|
|
125
|
+
position.x,
|
|
126
|
+
position.y,
|
|
127
|
+
position.z,
|
|
128
|
+
target.x,
|
|
129
|
+
target.y,
|
|
130
|
+
target.z,
|
|
131
|
+
enableTransition
|
|
132
|
+
);
|
|
133
|
+
this.dispatchEvent({
|
|
134
|
+
type: "modechange",
|
|
135
|
+
mode: this.activeMode,
|
|
136
|
+
previousMode: "orthographic",
|
|
137
|
+
camera: this.perspectiveCamera
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Switch to the orthographic camera while keeping the current framing.
|
|
142
|
+
*/
|
|
143
|
+
switchToOrthographic(enableTransition = false) {
|
|
144
|
+
if (this.activeMode === "orthographic") {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const target = this.getTarget(tempVec3A);
|
|
148
|
+
const position = this.getPosition(tempVec3B);
|
|
149
|
+
const aspect = resolveAspect(this.renderer, this.domElementRef);
|
|
150
|
+
this.updateOrthographicFrustum(position, target, aspect);
|
|
151
|
+
this.orthographicCamera.position.copy(position);
|
|
152
|
+
this.orthographicCamera.quaternion.copy(this.camera.quaternion);
|
|
153
|
+
this.orthographicCamera.up.copy(this.camera.up);
|
|
154
|
+
this.orthographicCamera.updateProjectionMatrix();
|
|
155
|
+
this.camera = this.orthographicCamera;
|
|
156
|
+
this.activeMode = "orthographic";
|
|
157
|
+
this.updateInputBindingsForMode("orthographic");
|
|
158
|
+
void this.setLookAt(
|
|
159
|
+
position.x,
|
|
160
|
+
position.y,
|
|
161
|
+
position.z,
|
|
162
|
+
target.x,
|
|
163
|
+
target.y,
|
|
164
|
+
target.z,
|
|
165
|
+
enableTransition
|
|
166
|
+
);
|
|
167
|
+
this.dispatchEvent({
|
|
168
|
+
type: "modechange",
|
|
169
|
+
mode: this.activeMode,
|
|
170
|
+
previousMode: "perspective",
|
|
171
|
+
camera: this.orthographicCamera
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Toggles between perspective and orthographic camera modes.
|
|
176
|
+
*/
|
|
177
|
+
toggleCameraMode(enableTransition = false) {
|
|
178
|
+
if (this.activeMode === "perspective") {
|
|
179
|
+
this.switchToOrthographic(enableTransition);
|
|
180
|
+
} else {
|
|
181
|
+
this.switchToPerspective(enableTransition);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Update camera projection parameters when the viewport size changes.
|
|
186
|
+
*/
|
|
187
|
+
handleResize(width, height) {
|
|
188
|
+
const aspect = height === 0 ? 1 : width / height;
|
|
189
|
+
this.perspectiveCamera.aspect = aspect;
|
|
190
|
+
this.perspectiveCamera.updateProjectionMatrix();
|
|
191
|
+
const target = this.getTarget(tempVec3A);
|
|
192
|
+
const position = this.getPosition(tempVec3B);
|
|
193
|
+
this.updateOrthographicFrustum(position, target, aspect);
|
|
194
|
+
if (this.activeMode === "orthographic") {
|
|
195
|
+
this.camera = this.orthographicCamera;
|
|
196
|
+
void this.setLookAt(
|
|
197
|
+
position.x,
|
|
198
|
+
position.y,
|
|
199
|
+
position.z,
|
|
200
|
+
target.x,
|
|
201
|
+
target.y,
|
|
202
|
+
target.z,
|
|
203
|
+
false
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Moves the camera to a new position and target.
|
|
209
|
+
*/
|
|
210
|
+
moveCamera(position, target, enableTransition = true) {
|
|
211
|
+
toVector3(position, [0, 0, 0], tempVec3A);
|
|
212
|
+
toVector3(target, [0, 0, 0], tempVec3B);
|
|
213
|
+
return this.setLookAt(
|
|
214
|
+
tempVec3A.x,
|
|
215
|
+
tempVec3A.y,
|
|
216
|
+
tempVec3A.z,
|
|
217
|
+
tempVec3B.x,
|
|
218
|
+
tempVec3B.y,
|
|
219
|
+
tempVec3B.z,
|
|
220
|
+
enableTransition
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Updates the controls using an internally managed clock.
|
|
225
|
+
* Useful when you don't want to pass delta time each frame.
|
|
226
|
+
*/
|
|
227
|
+
updateDelta() {
|
|
228
|
+
const delta = this.updateClock.getDelta();
|
|
229
|
+
return super.update(delta);
|
|
230
|
+
}
|
|
231
|
+
updateInputBindingsForMode(mode) {
|
|
232
|
+
const { ACTION } = CameraControls;
|
|
233
|
+
if (mode === "orthographic") {
|
|
234
|
+
this.mouseButtons.left = ACTION.TRUCK;
|
|
235
|
+
this.mouseButtons.right = ACTION.ROTATE;
|
|
236
|
+
this.mouseButtons.wheel = ACTION.ZOOM;
|
|
237
|
+
this.touches.one = ACTION.TOUCH_TRUCK;
|
|
238
|
+
this.touches.two = ACTION.TOUCH_ZOOM_TRUCK;
|
|
239
|
+
} else {
|
|
240
|
+
this.mouseButtons.left = ACTION.ROTATE;
|
|
241
|
+
this.mouseButtons.right = ACTION.TRUCK;
|
|
242
|
+
this.mouseButtons.wheel = ACTION.DOLLY;
|
|
243
|
+
this.touches.one = ACTION.TOUCH_ROTATE;
|
|
244
|
+
this.touches.two = ACTION.TOUCH_DOLLY_TRUCK;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
updateOrthographicFrustum(position, target, aspect) {
|
|
248
|
+
const distance = Math.max(position.distanceTo(target), 1e-3);
|
|
249
|
+
const fov = this.perspectiveCamera.fov;
|
|
250
|
+
const halfHeight = Math.max(
|
|
251
|
+
distance * Math.tan(THREE.MathUtils.degToRad(fov * 0.5)),
|
|
252
|
+
this.minOrthoHalfHeight
|
|
253
|
+
);
|
|
254
|
+
const halfWidth = halfHeight * aspect;
|
|
255
|
+
this.orthographicCamera.left = -halfWidth;
|
|
256
|
+
this.orthographicCamera.right = halfWidth;
|
|
257
|
+
this.orthographicCamera.top = halfHeight;
|
|
258
|
+
this.orthographicCamera.bottom = -halfHeight;
|
|
259
|
+
this.orthographicCamera.updateProjectionMatrix();
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
function resolveAspect(renderer, domElement) {
|
|
263
|
+
const size = renderer.getSize(tempVec2);
|
|
264
|
+
if (size.y > 0) {
|
|
265
|
+
return size.x / size.y;
|
|
266
|
+
}
|
|
267
|
+
const { clientWidth, clientHeight } = domElement;
|
|
268
|
+
if (clientHeight > 0) {
|
|
269
|
+
return clientWidth / clientHeight;
|
|
270
|
+
}
|
|
271
|
+
return 1;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
export {
|
|
275
|
+
DualCameraControls
|
|
276
|
+
};
|
|
277
|
+
//# sourceMappingURL=chunk-BYRZCHE7.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../packages/camera/src/DualCameraControls.ts"],"sourcesContent":["import * as THREE from 'three'\nimport CameraControls from 'camera-controls'\n\ntype Vector3Tuple = [number, number, number]\ntype Vector3Like = THREE.Vector3 | Vector3Tuple\n\nexport type CameraMode = 'perspective' | 'orthographic'\n\nexport interface PerspectiveCameraConfig {\n fov?: number\n near?: number\n far?: number\n position?: Vector3Like\n zoom?: number\n}\n\nexport interface OrthographicCameraConfig {\n size?: number\n near?: number\n far?: number\n position?: Vector3Like\n zoom?: number\n}\n\nexport interface DualCameraControlsOptions {\n domElement?: HTMLElement\n initialMode?: CameraMode\n initialTarget?: Vector3Like\n perspective?: PerspectiveCameraConfig\n orthographic?: OrthographicCameraConfig\n}\n\nexport interface ModeChangedEvent {\n type: 'modechange'\n mode: CameraMode\n previousMode: CameraMode\n camera: THREE.PerspectiveCamera | THREE.OrthographicCamera\n}\n\nlet controlsInstalled = false\n\nconst tempVec3A = new THREE.Vector3()\nconst tempVec3B = new THREE.Vector3()\nconst tempVec2 = new THREE.Vector2()\n\nfunction ensureCameraControlsInstalled() {\n if (!controlsInstalled) {\n CameraControls.install({ THREE })\n controlsInstalled = true\n }\n}\n\nfunction toVector3(\n value: Vector3Like | undefined,\n fallback: Vector3Tuple,\n target: THREE.Vector3\n) {\n if (!value) {\n target.set(fallback[0], fallback[1], fallback[2])\n return target\n }\n\n if (Array.isArray(value)) {\n target.set(value[0], value[1], value[2])\n return target\n }\n\n target.copy(value)\n return target\n}\n\n/**\n * Camera controls that manage both perspective and orthographic cameras while\n * extending {@link CameraControls}. Provides helpers to toggle between the\n * camera types and keep the framing consistent.\n */\nexport class DualCameraControls extends CameraControls {\n readonly perspectiveCamera: THREE.PerspectiveCamera\n readonly orthographicCamera: THREE.OrthographicCamera\n\n private readonly renderer: THREE.WebGLRenderer\n private readonly domElementRef: HTMLElement\n private activeMode: CameraMode\n private readonly minOrthoHalfHeight: number\n private readonly updateClock = new THREE.Clock()\n\n constructor(\n renderer: THREE.WebGLRenderer,\n options: DualCameraControlsOptions = {}\n ) {\n ensureCameraControlsInstalled()\n\n const { domElement = renderer.domElement } = options\n const aspect = resolveAspect(renderer, domElement)\n\n const perspectiveConfig = options.perspective ?? {}\n const orthographicConfig = options.orthographic ?? {}\n\n const perspectiveCamera = new THREE.PerspectiveCamera(\n perspectiveConfig.fov ?? 60,\n aspect,\n perspectiveConfig.near ?? 0.1,\n perspectiveConfig.far ?? 2000\n )\n\n perspectiveCamera.position.copy(\n toVector3(\n perspectiveConfig.position,\n [12, 12, 12],\n new THREE.Vector3()\n )\n )\n\n if (perspectiveConfig.zoom !== undefined) {\n perspectiveCamera.zoom = perspectiveConfig.zoom\n perspectiveCamera.updateProjectionMatrix()\n }\n\n const orthoHalfHeight = Math.max(orthographicConfig.size ?? 20, 0.001) * 0.5\n const orthoHalfWidth = orthoHalfHeight * aspect\n\n const orthographicCamera = new THREE.OrthographicCamera(\n -orthoHalfWidth,\n orthoHalfWidth,\n orthoHalfHeight,\n -orthoHalfHeight,\n orthographicConfig.near ?? 0.1,\n orthographicConfig.far ?? 2000\n )\n\n orthographicCamera.position.copy(\n toVector3(\n orthographicConfig.position,\n [12, 12, 12],\n new THREE.Vector3()\n )\n )\n\n if (orthographicConfig.zoom !== undefined) {\n orthographicCamera.zoom = orthographicConfig.zoom\n orthographicCamera.updateProjectionMatrix()\n }\n\n const initialMode = options.initialMode ?? 'perspective'\n const initialCamera =\n initialMode === 'orthographic' ? orthographicCamera : perspectiveCamera\n\n super(initialCamera, domElement)\n\n const initialTarget = toVector3(\n options.initialTarget,\n [0, 0, 0],\n new THREE.Vector3()\n )\n void this.setLookAt(\n initialCamera.position.x,\n initialCamera.position.y,\n initialCamera.position.z,\n initialTarget.x,\n initialTarget.y,\n initialTarget.z,\n false\n )\n\n this.renderer = renderer\n this.domElementRef = domElement\n this.perspectiveCamera = perspectiveCamera\n this.orthographicCamera = orthographicCamera\n this.activeMode = initialMode\n this.minOrthoHalfHeight = orthoHalfHeight\n\n this.updateInputBindingsForMode(initialMode)\n }\n\n get mode(): CameraMode {\n return this.activeMode\n }\n\n /**\n * Returns the currently active camera instance.\n */\n get activeCamera(): THREE.PerspectiveCamera | THREE.OrthographicCamera {\n return this.camera\n }\n\n /**\n * Switch to the perspective camera while keeping the current framing.\n */\n switchToPerspective(enableTransition = false) {\n if (this.activeMode === 'perspective') {\n return\n }\n\n const target = this.getTarget(tempVec3A)\n const position = this.getPosition(tempVec3B)\n\n const aspect = resolveAspect(this.renderer, this.domElementRef)\n this.perspectiveCamera.aspect = aspect\n this.perspectiveCamera.position.copy(position)\n this.perspectiveCamera.quaternion.copy(this.camera.quaternion)\n this.perspectiveCamera.up.copy(this.camera.up)\n this.perspectiveCamera.updateProjectionMatrix()\n\n this.camera = this.perspectiveCamera\n this.activeMode = 'perspective'\n this.updateInputBindingsForMode('perspective')\n\n void this.setLookAt(\n position.x,\n position.y,\n position.z,\n target.x,\n target.y,\n target.z,\n enableTransition\n )\n\n this.dispatchEvent({\n type: 'modechange',\n mode: this.activeMode,\n previousMode: 'orthographic',\n camera: this.perspectiveCamera,\n } satisfies ModeChangedEvent)\n }\n\n /**\n * Switch to the orthographic camera while keeping the current framing.\n */\n switchToOrthographic(enableTransition = false) {\n if (this.activeMode === 'orthographic') {\n return\n }\n\n const target = this.getTarget(tempVec3A)\n const position = this.getPosition(tempVec3B)\n\n const aspect = resolveAspect(this.renderer, this.domElementRef)\n this.updateOrthographicFrustum(position, target, aspect)\n\n this.orthographicCamera.position.copy(position)\n this.orthographicCamera.quaternion.copy(this.camera.quaternion)\n this.orthographicCamera.up.copy(this.camera.up)\n this.orthographicCamera.updateProjectionMatrix()\n\n this.camera = this.orthographicCamera\n this.activeMode = 'orthographic'\n this.updateInputBindingsForMode('orthographic')\n\n void this.setLookAt(\n position.x,\n position.y,\n position.z,\n target.x,\n target.y,\n target.z,\n enableTransition\n )\n\n this.dispatchEvent({\n type: 'modechange',\n mode: this.activeMode,\n previousMode: 'perspective',\n camera: this.orthographicCamera,\n } satisfies ModeChangedEvent)\n }\n\n /**\n * Toggles between perspective and orthographic camera modes.\n */\n toggleCameraMode(enableTransition = false) {\n if (this.activeMode === 'perspective') {\n this.switchToOrthographic(enableTransition)\n } else {\n this.switchToPerspective(enableTransition)\n }\n }\n\n /**\n * Update camera projection parameters when the viewport size changes.\n */\n handleResize(width: number, height: number) {\n const aspect = height === 0 ? 1 : width / height\n\n this.perspectiveCamera.aspect = aspect\n this.perspectiveCamera.updateProjectionMatrix()\n\n const target = this.getTarget(tempVec3A)\n const position = this.getPosition(tempVec3B)\n this.updateOrthographicFrustum(position, target, aspect)\n\n if (this.activeMode === 'orthographic') {\n this.camera = this.orthographicCamera\n void this.setLookAt(\n position.x,\n position.y,\n position.z,\n target.x,\n target.y,\n target.z,\n false\n )\n }\n }\n\n /**\n * Moves the camera to a new position and target.\n */\n moveCamera(\n position: Vector3Like,\n target: Vector3Like,\n enableTransition = true\n ) {\n toVector3(position, [0, 0, 0], tempVec3A)\n toVector3(target, [0, 0, 0], tempVec3B)\n\n return this.setLookAt(\n tempVec3A.x,\n tempVec3A.y,\n tempVec3A.z,\n tempVec3B.x,\n tempVec3B.y,\n tempVec3B.z,\n enableTransition\n )\n }\n\n /**\n * Updates the controls using an internally managed clock.\n * Useful when you don't want to pass delta time each frame.\n */\n updateDelta(): ReturnType<CameraControls['update']> {\n const delta = this.updateClock.getDelta()\n return super.update(delta)\n }\n\n private updateInputBindingsForMode(mode: CameraMode) {\n const { ACTION } = CameraControls\n\n if (mode === 'orthographic') {\n this.mouseButtons.left = ACTION.TRUCK\n this.mouseButtons.right = ACTION.ROTATE\n this.mouseButtons.wheel = ACTION.ZOOM\n this.touches.one = ACTION.TOUCH_TRUCK\n this.touches.two = ACTION.TOUCH_ZOOM_TRUCK\n } else {\n this.mouseButtons.left = ACTION.ROTATE\n this.mouseButtons.right = ACTION.TRUCK\n this.mouseButtons.wheel = ACTION.DOLLY\n this.touches.one = ACTION.TOUCH_ROTATE\n this.touches.two = ACTION.TOUCH_DOLLY_TRUCK\n }\n }\n\n private updateOrthographicFrustum(\n position: THREE.Vector3,\n target: THREE.Vector3,\n aspect: number\n ) {\n const distance = Math.max(position.distanceTo(target), 0.001)\n const fov = this.perspectiveCamera.fov\n const halfHeight = Math.max(\n distance * Math.tan(THREE.MathUtils.degToRad(fov * 0.5)),\n this.minOrthoHalfHeight\n )\n const halfWidth = halfHeight * aspect\n\n this.orthographicCamera.left = -halfWidth\n this.orthographicCamera.right = halfWidth\n this.orthographicCamera.top = halfHeight\n this.orthographicCamera.bottom = -halfHeight\n this.orthographicCamera.updateProjectionMatrix()\n }\n}\n\nfunction resolveAspect(\n renderer: THREE.WebGLRenderer,\n domElement: HTMLElement\n): number {\n const size = renderer.getSize(tempVec2)\n if (size.y > 0) {\n return size.x / size.y\n }\n\n const { clientWidth, clientHeight } = domElement\n if (clientHeight > 0) {\n return clientWidth / clientHeight\n }\n\n return 1\n}\n"],"mappings":"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","names":[]}
|