blockymodel-web 0.1.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/LICENSE +21 -0
- package/dist/blockymodel-web.js +2717 -0
- package/dist/blockymodel-web.js.map +1 -0
- package/dist/blockymodel-web.umd.cjs +122 -0
- package/dist/blockymodel-web.umd.cjs.map +1 -0
- package/dist/editor/Editor.d.ts +94 -0
- package/dist/editor/Editor.d.ts.map +1 -0
- package/dist/editor/History.d.ts +52 -0
- package/dist/editor/History.d.ts.map +1 -0
- package/dist/editor/SelectionManager.d.ts +57 -0
- package/dist/editor/SelectionManager.d.ts.map +1 -0
- package/dist/editor/Serializer.d.ts +44 -0
- package/dist/editor/Serializer.d.ts.map +1 -0
- package/dist/editor/TransformManager.d.ts +73 -0
- package/dist/editor/TransformManager.d.ts.map +1 -0
- package/dist/editor/commands/AddNodeCommand.d.ts +24 -0
- package/dist/editor/commands/AddNodeCommand.d.ts.map +1 -0
- package/dist/editor/commands/Command.d.ts +50 -0
- package/dist/editor/commands/Command.d.ts.map +1 -0
- package/dist/editor/commands/RemoveNodeCommand.d.ts +28 -0
- package/dist/editor/commands/RemoveNodeCommand.d.ts.map +1 -0
- package/dist/editor/commands/SetPositionCommand.d.ts +24 -0
- package/dist/editor/commands/SetPositionCommand.d.ts.map +1 -0
- package/dist/editor/commands/SetPropertyCommand.d.ts +41 -0
- package/dist/editor/commands/SetPropertyCommand.d.ts.map +1 -0
- package/dist/editor/commands/SetRotationCommand.d.ts +24 -0
- package/dist/editor/commands/SetRotationCommand.d.ts.map +1 -0
- package/dist/editor/commands/SetScaleCommand.d.ts +24 -0
- package/dist/editor/commands/SetScaleCommand.d.ts.map +1 -0
- package/dist/editor/index.d.ts +15 -0
- package/dist/editor/index.d.ts.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/loaders/BlockyModelLoader.d.ts +48 -0
- package/dist/loaders/BlockyModelLoader.d.ts.map +1 -0
- package/dist/types/blockymodel.d.ts +72 -0
- package/dist/types/blockymodel.d.ts.map +1 -0
- package/dist/ui/HierarchyPanel.d.ts +73 -0
- package/dist/ui/HierarchyPanel.d.ts.map +1 -0
- package/dist/ui/PropertyPanel.d.ts +59 -0
- package/dist/ui/PropertyPanel.d.ts.map +1 -0
- package/dist/ui/UVEditor.d.ts +56 -0
- package/dist/ui/UVEditor.d.ts.map +1 -0
- package/dist/ui/index.d.ts +4 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/viewer/ViewerController.d.ts +71 -0
- package/dist/viewer/ViewerController.d.ts.map +1 -0
- package/package.json +63 -0
- package/src/editor/Editor.ts +196 -0
- package/src/editor/History.ts +123 -0
- package/src/editor/SelectionManager.ts +183 -0
- package/src/editor/Serializer.ts +212 -0
- package/src/editor/TransformManager.ts +270 -0
- package/src/editor/commands/AddNodeCommand.ts +53 -0
- package/src/editor/commands/Command.ts +63 -0
- package/src/editor/commands/RemoveNodeCommand.ts +59 -0
- package/src/editor/commands/SetPositionCommand.ts +51 -0
- package/src/editor/commands/SetPropertyCommand.ts +100 -0
- package/src/editor/commands/SetRotationCommand.ts +51 -0
- package/src/editor/commands/SetScaleCommand.ts +51 -0
- package/src/editor/index.ts +19 -0
- package/src/index.ts +49 -0
- package/src/loaders/BlockyModelLoader.ts +281 -0
- package/src/main.ts +290 -0
- package/src/styles.css +597 -0
- package/src/types/blockymodel.ts +82 -0
- package/src/ui/HierarchyPanel.ts +343 -0
- package/src/ui/PropertyPanel.ts +434 -0
- package/src/ui/UVEditor.ts +336 -0
- package/src/ui/index.ts +4 -0
- package/src/viewer/ViewerController.ts +295 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blockymodel-web.js","sources":["../src/editor/SelectionManager.ts","../node_modules/three/examples/jsm/controls/TransformControls.js","../src/editor/commands/Command.ts","../src/editor/commands/SetPositionCommand.ts","../src/editor/commands/SetRotationCommand.ts","../src/editor/commands/SetScaleCommand.ts","../src/editor/TransformManager.ts","../src/editor/History.ts","../src/editor/Editor.ts","../src/editor/Serializer.ts","../src/editor/commands/SetPropertyCommand.ts","../src/editor/commands/AddNodeCommand.ts","../src/editor/commands/RemoveNodeCommand.ts","../src/ui/PropertyPanel.ts","../src/ui/HierarchyPanel.ts","../src/ui/UVEditor.ts","../src/types/blockymodel.ts","../src/loaders/BlockyModelLoader.ts","../node_modules/three/examples/jsm/controls/OrbitControls.js","../src/viewer/ViewerController.ts"],"sourcesContent":["import * as THREE from \"three\";\nimport type { Editor } from \"./Editor\";\n\ntype SelectionCallback = (object: THREE.Object3D | null) => void;\n\nconst HIGHLIGHT_EMISSIVE = 0x4488ff;\nconst HIGHLIGHT_INTENSITY = 0.3;\n\n/**\n * Manages object selection via raycasting\n */\nexport class SelectionManager {\n private editor: Editor;\n private raycaster: THREE.Raycaster;\n private mouse: THREE.Vector2;\n private selected: THREE.Object3D | null = null;\n private highlightedMaterials: Map<THREE.Mesh, { emissive: THREE.Color; emissiveIntensity: number }> = new Map();\n private eventListeners: Map<string, Set<SelectionCallback>> = new Map();\n\n constructor(editor: Editor) {\n this.editor = editor;\n this.raycaster = new THREE.Raycaster();\n this.mouse = new THREE.Vector2();\n\n // Bind event handlers\n this.handleClick = this.handleClick.bind(this);\n this.editor.domElement.addEventListener(\"click\", this.handleClick);\n }\n\n /**\n * Handle click events for selection\n */\n private handleClick(event: MouseEvent): void {\n // Ignore if clicking on UI elements or during transform\n if (event.target !== this.editor.renderer.domElement) {\n return;\n }\n\n const rect = this.editor.domElement.getBoundingClientRect();\n this.mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n this.mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n this.raycaster.setFromCamera(this.mouse, this.editor.camera);\n\n // Get pickable objects (meshes from current model)\n const model = this.editor.getModel();\n if (!model) {\n this.deselect();\n return;\n }\n\n const pickables: THREE.Object3D[] = [];\n model.traverse((object) => {\n if (object instanceof THREE.Mesh && object.visible) {\n // Skip TransformControls gizmo objects\n if (!this.isTransformControlPart(object)) {\n pickables.push(object);\n }\n }\n });\n\n const intersects = this.raycaster.intersectObjects(pickables, false);\n\n if (intersects.length > 0) {\n // Find the most relevant parent (node with name/id)\n let target = intersects[0].object;\n while (target.parent && !target.userData.id && target.parent !== model) {\n target = target.parent;\n }\n this.select(target);\n } else {\n this.deselect();\n }\n }\n\n /**\n * Check if object is part of TransformControls\n */\n private isTransformControlPart(object: THREE.Object3D): boolean {\n let current: THREE.Object3D | null = object;\n while (current) {\n if (current.type === \"TransformControlsGizmo\" || current.type === \"TransformControlsPlane\") {\n return true;\n }\n current = current.parent;\n }\n return false;\n }\n\n /**\n * Select an object\n */\n select(object: THREE.Object3D | null): void {\n if (object === this.selected) return;\n\n // Remove highlight from previous selection\n this.removeHighlight();\n\n this.selected = object;\n\n // Add highlight to new selection\n if (object) {\n this.applyHighlight(object);\n }\n\n this.emit(\"selectionChanged\", object);\n }\n\n /**\n * Deselect current object\n */\n deselect(): void {\n this.select(null);\n }\n\n /**\n * Get currently selected object\n */\n getSelected(): THREE.Object3D | null {\n return this.selected;\n }\n\n /**\n * Apply highlight effect to object\n */\n private applyHighlight(object: THREE.Object3D): void {\n object.traverse((child) => {\n if (child instanceof THREE.Mesh) {\n const material = child.material as THREE.MeshStandardMaterial;\n if (material.emissive) {\n // Store original values\n this.highlightedMaterials.set(child, {\n emissive: material.emissive.clone(),\n emissiveIntensity: material.emissiveIntensity,\n });\n // Apply highlight\n material.emissive.setHex(HIGHLIGHT_EMISSIVE);\n material.emissiveIntensity = HIGHLIGHT_INTENSITY;\n }\n }\n });\n }\n\n /**\n * Remove highlight effect\n */\n private removeHighlight(): void {\n this.highlightedMaterials.forEach((original, mesh) => {\n const material = mesh.material as THREE.MeshStandardMaterial;\n if (material.emissive) {\n material.emissive.copy(original.emissive);\n material.emissiveIntensity = original.emissiveIntensity;\n }\n });\n this.highlightedMaterials.clear();\n }\n\n /**\n * Add event listener\n */\n on(event: string, callback: SelectionCallback): void {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, new Set());\n }\n this.eventListeners.get(event)!.add(callback);\n }\n\n /**\n * Emit event\n */\n private emit(event: string, ...args: unknown[]): void {\n this.eventListeners.get(event)?.forEach((callback) => callback(args[0] as THREE.Object3D | null));\n }\n\n /**\n * Clean up\n */\n dispose(): void {\n this.editor.domElement.removeEventListener(\"click\", this.handleClick);\n this.removeHighlight();\n this.eventListeners.clear();\n }\n}\n","import {\n\tBoxGeometry,\n\tBufferGeometry,\n\tControls,\n\tCylinderGeometry,\n\tDoubleSide,\n\tEuler,\n\tFloat32BufferAttribute,\n\tLine,\n\tLineBasicMaterial,\n\tMatrix4,\n\tMesh,\n\tMeshBasicMaterial,\n\tObject3D,\n\tOctahedronGeometry,\n\tPlaneGeometry,\n\tQuaternion,\n\tRaycaster,\n\tSphereGeometry,\n\tTorusGeometry,\n\tVector3\n} from 'three';\n\nconst _raycaster = new Raycaster();\n\nconst _tempVector = new Vector3();\nconst _tempVector2 = new Vector3();\nconst _tempQuaternion = new Quaternion();\nconst _unit = {\n\tX: new Vector3( 1, 0, 0 ),\n\tY: new Vector3( 0, 1, 0 ),\n\tZ: new Vector3( 0, 0, 1 )\n};\n\nconst _changeEvent = { type: 'change' };\nconst _mouseDownEvent = { type: 'mouseDown', mode: null };\nconst _mouseUpEvent = { type: 'mouseUp', mode: null };\nconst _objectChangeEvent = { type: 'objectChange' };\n\nclass TransformControls extends Controls {\n\n\tconstructor( camera, domElement = null ) {\n\n\t\tsuper( undefined, domElement );\n\n\t\tconst root = new TransformControlsRoot( this );\n\t\tthis._root = root;\n\n\t\tconst gizmo = new TransformControlsGizmo();\n\t\tthis._gizmo = gizmo;\n\t\troot.add( gizmo );\n\n\t\tconst plane = new TransformControlsPlane();\n\t\tthis._plane = plane;\n\t\troot.add( plane );\n\n\t\tconst scope = this;\n\n\t\t// Defined getter, setter and store for a property\n\t\tfunction defineProperty( propName, defaultValue ) {\n\n\t\t\tlet propValue = defaultValue;\n\n\t\t\tObject.defineProperty( scope, propName, {\n\n\t\t\t\tget: function () {\n\n\t\t\t\t\treturn propValue !== undefined ? propValue : defaultValue;\n\n\t\t\t\t},\n\n\t\t\t\tset: function ( value ) {\n\n\t\t\t\t\tif ( propValue !== value ) {\n\n\t\t\t\t\t\tpropValue = value;\n\t\t\t\t\t\tplane[ propName ] = value;\n\t\t\t\t\t\tgizmo[ propName ] = value;\n\n\t\t\t\t\t\tscope.dispatchEvent( { type: propName + '-changed', value: value } );\n\t\t\t\t\t\tscope.dispatchEvent( _changeEvent );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t\tscope[ propName ] = defaultValue;\n\t\t\tplane[ propName ] = defaultValue;\n\t\t\tgizmo[ propName ] = defaultValue;\n\n\t\t}\n\n\t\t// Define properties with getters/setter\n\t\t// Setting the defined property will automatically trigger change event\n\t\t// Defined properties are passed down to gizmo and plane\n\n\t\tdefineProperty( 'camera', camera );\n\t\tdefineProperty( 'object', undefined );\n\t\tdefineProperty( 'enabled', true );\n\t\tdefineProperty( 'axis', null );\n\t\tdefineProperty( 'mode', 'translate' );\n\t\tdefineProperty( 'translationSnap', null );\n\t\tdefineProperty( 'rotationSnap', null );\n\t\tdefineProperty( 'scaleSnap', null );\n\t\tdefineProperty( 'space', 'world' );\n\t\tdefineProperty( 'size', 1 );\n\t\tdefineProperty( 'dragging', false );\n\t\tdefineProperty( 'showX', true );\n\t\tdefineProperty( 'showY', true );\n\t\tdefineProperty( 'showZ', true );\n\t\tdefineProperty( 'minX', - Infinity );\n\t\tdefineProperty( 'maxX', Infinity );\n\t\tdefineProperty( 'minY', - Infinity );\n\t\tdefineProperty( 'maxY', Infinity );\n\t\tdefineProperty( 'minZ', - Infinity );\n\t\tdefineProperty( 'maxZ', Infinity );\n\n\t\t// Reusable utility variables\n\n\t\tconst worldPosition = new Vector3();\n\t\tconst worldPositionStart = new Vector3();\n\t\tconst worldQuaternion = new Quaternion();\n\t\tconst worldQuaternionStart = new Quaternion();\n\t\tconst cameraPosition = new Vector3();\n\t\tconst cameraQuaternion = new Quaternion();\n\t\tconst pointStart = new Vector3();\n\t\tconst pointEnd = new Vector3();\n\t\tconst rotationAxis = new Vector3();\n\t\tconst rotationAngle = 0;\n\t\tconst eye = new Vector3();\n\n\t\t// TODO: remove properties unused in plane and gizmo\n\n\t\tdefineProperty( 'worldPosition', worldPosition );\n\t\tdefineProperty( 'worldPositionStart', worldPositionStart );\n\t\tdefineProperty( 'worldQuaternion', worldQuaternion );\n\t\tdefineProperty( 'worldQuaternionStart', worldQuaternionStart );\n\t\tdefineProperty( 'cameraPosition', cameraPosition );\n\t\tdefineProperty( 'cameraQuaternion', cameraQuaternion );\n\t\tdefineProperty( 'pointStart', pointStart );\n\t\tdefineProperty( 'pointEnd', pointEnd );\n\t\tdefineProperty( 'rotationAxis', rotationAxis );\n\t\tdefineProperty( 'rotationAngle', rotationAngle );\n\t\tdefineProperty( 'eye', eye );\n\n\t\tthis._offset = new Vector3();\n\t\tthis._startNorm = new Vector3();\n\t\tthis._endNorm = new Vector3();\n\t\tthis._cameraScale = new Vector3();\n\n\t\tthis._parentPosition = new Vector3();\n\t\tthis._parentQuaternion = new Quaternion();\n\t\tthis._parentQuaternionInv = new Quaternion();\n\t\tthis._parentScale = new Vector3();\n\n\t\tthis._worldScaleStart = new Vector3();\n\t\tthis._worldQuaternionInv = new Quaternion();\n\t\tthis._worldScale = new Vector3();\n\n\t\tthis._positionStart = new Vector3();\n\t\tthis._quaternionStart = new Quaternion();\n\t\tthis._scaleStart = new Vector3();\n\n\t\tthis._getPointer = getPointer.bind( this );\n\t\tthis._onPointerDown = onPointerDown.bind( this );\n\t\tthis._onPointerHover = onPointerHover.bind( this );\n\t\tthis._onPointerMove = onPointerMove.bind( this );\n\t\tthis._onPointerUp = onPointerUp.bind( this );\n\n\t\tif ( domElement !== null ) {\n\n\t\t\tthis.connect();\n\n\t\t}\n\n\t}\n\n\tconnect() {\n\n\t\tthis.domElement.addEventListener( 'pointerdown', this._onPointerDown );\n\t\tthis.domElement.addEventListener( 'pointermove', this._onPointerHover );\n\t\tthis.domElement.addEventListener( 'pointerup', this._onPointerUp );\n\n\t\tthis.domElement.style.touchAction = 'none'; // disable touch scroll\n\n\t}\n\n\tdisconnect() {\n\n\t\tthis.domElement.removeEventListener( 'pointerdown', this._onPointerDown );\n\t\tthis.domElement.removeEventListener( 'pointermove', this._onPointerHover );\n\t\tthis.domElement.removeEventListener( 'pointermove', this._onPointerMove );\n\t\tthis.domElement.removeEventListener( 'pointerup', this._onPointerUp );\n\n\t\tthis.domElement.style.touchAction = 'auto';\n\n\t}\n\n\tgetHelper() {\n\n\t\treturn this._root;\n\n\t}\n\n\tpointerHover( pointer ) {\n\n\t\tif ( this.object === undefined || this.dragging === true ) return;\n\n\t\tif ( pointer !== null ) _raycaster.setFromCamera( pointer, this.camera );\n\n\t\tconst intersect = intersectObjectWithRay( this._gizmo.picker[ this.mode ], _raycaster );\n\n\t\tif ( intersect ) {\n\n\t\t\tthis.axis = intersect.object.name;\n\n\t\t} else {\n\n\t\t\tthis.axis = null;\n\n\t\t}\n\n\t}\n\n\tpointerDown( pointer ) {\n\n\t\tif ( this.object === undefined || this.dragging === true || ( pointer != null && pointer.button !== 0 ) ) return;\n\n\t\tif ( this.axis !== null ) {\n\n\t\t\tif ( pointer !== null ) _raycaster.setFromCamera( pointer, this.camera );\n\n\t\t\tconst planeIntersect = intersectObjectWithRay( this._plane, _raycaster, true );\n\n\t\t\tif ( planeIntersect ) {\n\n\t\t\t\tthis.object.updateMatrixWorld();\n\t\t\t\tthis.object.parent.updateMatrixWorld();\n\n\t\t\t\tthis._positionStart.copy( this.object.position );\n\t\t\t\tthis._quaternionStart.copy( this.object.quaternion );\n\t\t\t\tthis._scaleStart.copy( this.object.scale );\n\n\t\t\t\tthis.object.matrixWorld.decompose( this.worldPositionStart, this.worldQuaternionStart, this._worldScaleStart );\n\n\t\t\t\tthis.pointStart.copy( planeIntersect.point ).sub( this.worldPositionStart );\n\n\t\t\t}\n\n\t\t\tthis.dragging = true;\n\t\t\t_mouseDownEvent.mode = this.mode;\n\t\t\tthis.dispatchEvent( _mouseDownEvent );\n\n\t\t}\n\n\t}\n\n\tpointerMove( pointer ) {\n\n\t\tconst axis = this.axis;\n\t\tconst mode = this.mode;\n\t\tconst object = this.object;\n\t\tlet space = this.space;\n\n\t\tif ( mode === 'scale' ) {\n\n\t\t\tspace = 'local';\n\n\t\t} else if ( axis === 'E' || axis === 'XYZE' || axis === 'XYZ' ) {\n\n\t\t\tspace = 'world';\n\n\t\t}\n\n\t\tif ( object === undefined || axis === null || this.dragging === false || ( pointer !== null && pointer.button !== - 1 ) ) return;\n\n\t\tif ( pointer !== null ) _raycaster.setFromCamera( pointer, this.camera );\n\n\t\tconst planeIntersect = intersectObjectWithRay( this._plane, _raycaster, true );\n\n\t\tif ( ! planeIntersect ) return;\n\n\t\tthis.pointEnd.copy( planeIntersect.point ).sub( this.worldPositionStart );\n\n\t\tif ( mode === 'translate' ) {\n\n\t\t\t// Apply translate\n\n\t\t\tthis._offset.copy( this.pointEnd ).sub( this.pointStart );\n\n\t\t\tif ( space === 'local' && axis !== 'XYZ' ) {\n\n\t\t\t\tthis._offset.applyQuaternion( this._worldQuaternionInv );\n\n\t\t\t}\n\n\t\t\tif ( axis.indexOf( 'X' ) === - 1 ) this._offset.x = 0;\n\t\t\tif ( axis.indexOf( 'Y' ) === - 1 ) this._offset.y = 0;\n\t\t\tif ( axis.indexOf( 'Z' ) === - 1 ) this._offset.z = 0;\n\n\t\t\tif ( space === 'local' && axis !== 'XYZ' ) {\n\n\t\t\t\tthis._offset.applyQuaternion( this._quaternionStart ).divide( this._parentScale );\n\n\t\t\t} else {\n\n\t\t\t\tthis._offset.applyQuaternion( this._parentQuaternionInv ).divide( this._parentScale );\n\n\t\t\t}\n\n\t\t\tobject.position.copy( this._offset ).add( this._positionStart );\n\n\t\t\t// Apply translation snap\n\n\t\t\tif ( this.translationSnap ) {\n\n\t\t\t\tif ( space === 'local' ) {\n\n\t\t\t\t\tobject.position.applyQuaternion( _tempQuaternion.copy( this._quaternionStart ).invert() );\n\n\t\t\t\t\tif ( axis.search( 'X' ) !== - 1 ) {\n\n\t\t\t\t\t\tobject.position.x = Math.round( object.position.x / this.translationSnap ) * this.translationSnap;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( axis.search( 'Y' ) !== - 1 ) {\n\n\t\t\t\t\t\tobject.position.y = Math.round( object.position.y / this.translationSnap ) * this.translationSnap;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( axis.search( 'Z' ) !== - 1 ) {\n\n\t\t\t\t\t\tobject.position.z = Math.round( object.position.z / this.translationSnap ) * this.translationSnap;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tobject.position.applyQuaternion( this._quaternionStart );\n\n\t\t\t\t}\n\n\t\t\t\tif ( space === 'world' ) {\n\n\t\t\t\t\tif ( object.parent ) {\n\n\t\t\t\t\t\tobject.position.add( _tempVector.setFromMatrixPosition( object.parent.matrixWorld ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( axis.search( 'X' ) !== - 1 ) {\n\n\t\t\t\t\t\tobject.position.x = Math.round( object.position.x / this.translationSnap ) * this.translationSnap;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( axis.search( 'Y' ) !== - 1 ) {\n\n\t\t\t\t\t\tobject.position.y = Math.round( object.position.y / this.translationSnap ) * this.translationSnap;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( axis.search( 'Z' ) !== - 1 ) {\n\n\t\t\t\t\t\tobject.position.z = Math.round( object.position.z / this.translationSnap ) * this.translationSnap;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( object.parent ) {\n\n\t\t\t\t\t\tobject.position.sub( _tempVector.setFromMatrixPosition( object.parent.matrixWorld ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tobject.position.x = Math.max( this.minX, Math.min( this.maxX, object.position.x ) );\n\t\t\tobject.position.y = Math.max( this.minY, Math.min( this.maxY, object.position.y ) );\n\t\t\tobject.position.z = Math.max( this.minZ, Math.min( this.maxZ, object.position.z ) );\n\n\t\t} else if ( mode === 'scale' ) {\n\n\t\t\tif ( axis.search( 'XYZ' ) !== - 1 ) {\n\n\t\t\t\tlet d = this.pointEnd.length() / this.pointStart.length();\n\n\t\t\t\tif ( this.pointEnd.dot( this.pointStart ) < 0 ) d *= - 1;\n\n\t\t\t\t_tempVector2.set( d, d, d );\n\n\t\t\t} else {\n\n\t\t\t\t_tempVector.copy( this.pointStart );\n\t\t\t\t_tempVector2.copy( this.pointEnd );\n\n\t\t\t\t_tempVector.applyQuaternion( this._worldQuaternionInv );\n\t\t\t\t_tempVector2.applyQuaternion( this._worldQuaternionInv );\n\n\t\t\t\t_tempVector2.divide( _tempVector );\n\n\t\t\t\tif ( axis.search( 'X' ) === - 1 ) {\n\n\t\t\t\t\t_tempVector2.x = 1;\n\n\t\t\t\t}\n\n\t\t\t\tif ( axis.search( 'Y' ) === - 1 ) {\n\n\t\t\t\t\t_tempVector2.y = 1;\n\n\t\t\t\t}\n\n\t\t\t\tif ( axis.search( 'Z' ) === - 1 ) {\n\n\t\t\t\t\t_tempVector2.z = 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Apply scale\n\n\t\t\tobject.scale.copy( this._scaleStart ).multiply( _tempVector2 );\n\n\t\t\tif ( this.scaleSnap ) {\n\n\t\t\t\tif ( axis.search( 'X' ) !== - 1 ) {\n\n\t\t\t\t\tobject.scale.x = Math.round( object.scale.x / this.scaleSnap ) * this.scaleSnap || this.scaleSnap;\n\n\t\t\t\t}\n\n\t\t\t\tif ( axis.search( 'Y' ) !== - 1 ) {\n\n\t\t\t\t\tobject.scale.y = Math.round( object.scale.y / this.scaleSnap ) * this.scaleSnap || this.scaleSnap;\n\n\t\t\t\t}\n\n\t\t\t\tif ( axis.search( 'Z' ) !== - 1 ) {\n\n\t\t\t\t\tobject.scale.z = Math.round( object.scale.z / this.scaleSnap ) * this.scaleSnap || this.scaleSnap;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} else if ( mode === 'rotate' ) {\n\n\t\t\tthis._offset.copy( this.pointEnd ).sub( this.pointStart );\n\n\t\t\tconst ROTATION_SPEED = 20 / this.worldPosition.distanceTo( _tempVector.setFromMatrixPosition( this.camera.matrixWorld ) );\n\n\t\t\tlet _inPlaneRotation = false;\n\n\t\t\tif ( axis === 'XYZE' ) {\n\n\t\t\t\tthis.rotationAxis.copy( this._offset ).cross( this.eye ).normalize();\n\t\t\t\tthis.rotationAngle = this._offset.dot( _tempVector.copy( this.rotationAxis ).cross( this.eye ) ) * ROTATION_SPEED;\n\n\t\t\t} else if ( axis === 'X' || axis === 'Y' || axis === 'Z' ) {\n\n\t\t\t\tthis.rotationAxis.copy( _unit[ axis ] );\n\n\t\t\t\t_tempVector.copy( _unit[ axis ] );\n\n\t\t\t\tif ( space === 'local' ) {\n\n\t\t\t\t\t_tempVector.applyQuaternion( this.worldQuaternion );\n\n\t\t\t\t}\n\n\t\t\t\t_tempVector.cross( this.eye );\n\n\t\t\t\t// When _tempVector is 0 after cross with this.eye the vectors are parallel and should use in-plane rotation logic.\n\t\t\t\tif ( _tempVector.length() === 0 ) {\n\n\t\t\t\t\t_inPlaneRotation = true;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.rotationAngle = this._offset.dot( _tempVector.normalize() ) * ROTATION_SPEED;\n\n\t\t\t\t}\n\n\n\t\t\t}\n\n\t\t\tif ( axis === 'E' || _inPlaneRotation ) {\n\n\t\t\t\tthis.rotationAxis.copy( this.eye );\n\t\t\t\tthis.rotationAngle = this.pointEnd.angleTo( this.pointStart );\n\n\t\t\t\tthis._startNorm.copy( this.pointStart ).normalize();\n\t\t\t\tthis._endNorm.copy( this.pointEnd ).normalize();\n\n\t\t\t\tthis.rotationAngle *= ( this._endNorm.cross( this._startNorm ).dot( this.eye ) < 0 ? 1 : - 1 );\n\n\t\t\t}\n\n\t\t\t// Apply rotation snap\n\n\t\t\tif ( this.rotationSnap ) this.rotationAngle = Math.round( this.rotationAngle / this.rotationSnap ) * this.rotationSnap;\n\n\t\t\t// Apply rotate\n\t\t\tif ( space === 'local' && axis !== 'E' && axis !== 'XYZE' ) {\n\n\t\t\t\tobject.quaternion.copy( this._quaternionStart );\n\t\t\t\tobject.quaternion.multiply( _tempQuaternion.setFromAxisAngle( this.rotationAxis, this.rotationAngle ) ).normalize();\n\n\t\t\t} else {\n\n\t\t\t\tthis.rotationAxis.applyQuaternion( this._parentQuaternionInv );\n\t\t\t\tobject.quaternion.copy( _tempQuaternion.setFromAxisAngle( this.rotationAxis, this.rotationAngle ) );\n\t\t\t\tobject.quaternion.multiply( this._quaternionStart ).normalize();\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.dispatchEvent( _changeEvent );\n\t\tthis.dispatchEvent( _objectChangeEvent );\n\n\t}\n\n\tpointerUp( pointer ) {\n\n\t\tif ( pointer !== null && pointer.button !== 0 ) return;\n\n\t\tif ( this.dragging && ( this.axis !== null ) ) {\n\n\t\t\t_mouseUpEvent.mode = this.mode;\n\t\t\tthis.dispatchEvent( _mouseUpEvent );\n\n\t\t}\n\n\t\tthis.dragging = false;\n\t\tthis.axis = null;\n\n\t}\n\n\tdispose() {\n\n\t\tthis.disconnect();\n\n\t\tthis._root.dispose();\n\n\t}\n\n\t// Set current object\n\tattach( object ) {\n\n\t\tthis.object = object;\n\t\tthis._root.visible = true;\n\n\t\treturn this;\n\n\t}\n\n\t// Detach from object\n\tdetach() {\n\n\t\tthis.object = undefined;\n\t\tthis.axis = null;\n\n\t\tthis._root.visible = false;\n\n\t\treturn this;\n\n\t}\n\n\treset() {\n\n\t\tif ( ! this.enabled ) return;\n\n\t\tif ( this.dragging ) {\n\n\t\t\tthis.object.position.copy( this._positionStart );\n\t\t\tthis.object.quaternion.copy( this._quaternionStart );\n\t\t\tthis.object.scale.copy( this._scaleStart );\n\n\t\t\tthis.dispatchEvent( _changeEvent );\n\t\t\tthis.dispatchEvent( _objectChangeEvent );\n\n\t\t\tthis.pointStart.copy( this.pointEnd );\n\n\t\t}\n\n\t}\n\n\tgetRaycaster() {\n\n\t\treturn _raycaster;\n\n\t}\n\n\t// TODO: deprecate\n\n\tgetMode() {\n\n\t\treturn this.mode;\n\n\t}\n\n\tsetMode( mode ) {\n\n\t\tthis.mode = mode;\n\n\t}\n\n\tsetTranslationSnap( translationSnap ) {\n\n\t\tthis.translationSnap = translationSnap;\n\n\t}\n\n\tsetRotationSnap( rotationSnap ) {\n\n\t\tthis.rotationSnap = rotationSnap;\n\n\t}\n\n\tsetScaleSnap( scaleSnap ) {\n\n\t\tthis.scaleSnap = scaleSnap;\n\n\t}\n\n\tsetSize( size ) {\n\n\t\tthis.size = size;\n\n\t}\n\n\tsetSpace( space ) {\n\n\t\tthis.space = space;\n\n\t}\n\n}\n\n// mouse / touch event handlers\n\nfunction getPointer( event ) {\n\n\tif ( this.domElement.ownerDocument.pointerLockElement ) {\n\n\t\treturn {\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t\tbutton: event.button\n\t\t};\n\n\t} else {\n\n\t\tconst rect = this.domElement.getBoundingClientRect();\n\n\t\treturn {\n\t\t\tx: ( event.clientX - rect.left ) / rect.width * 2 - 1,\n\t\t\ty: - ( event.clientY - rect.top ) / rect.height * 2 + 1,\n\t\t\tbutton: event.button\n\t\t};\n\n\t}\n\n}\n\nfunction onPointerHover( event ) {\n\n\tif ( ! this.enabled ) return;\n\n\tswitch ( event.pointerType ) {\n\n\t\tcase 'mouse':\n\t\tcase 'pen':\n\t\t\tthis.pointerHover( this._getPointer( event ) );\n\t\t\tbreak;\n\n\t}\n\n}\n\nfunction onPointerDown( event ) {\n\n\tif ( ! this.enabled ) return;\n\n\tif ( ! document.pointerLockElement ) {\n\n\t\tthis.domElement.setPointerCapture( event.pointerId );\n\n\t}\n\n\tthis.domElement.addEventListener( 'pointermove', this._onPointerMove );\n\n\tthis.pointerHover( this._getPointer( event ) );\n\tthis.pointerDown( this._getPointer( event ) );\n\n}\n\nfunction onPointerMove( event ) {\n\n\tif ( ! this.enabled ) return;\n\n\tthis.pointerMove( this._getPointer( event ) );\n\n}\n\nfunction onPointerUp( event ) {\n\n\tif ( ! this.enabled ) return;\n\n\tthis.domElement.releasePointerCapture( event.pointerId );\n\n\tthis.domElement.removeEventListener( 'pointermove', this._onPointerMove );\n\n\tthis.pointerUp( this._getPointer( event ) );\n\n}\n\nfunction intersectObjectWithRay( object, raycaster, includeInvisible ) {\n\n\tconst allIntersections = raycaster.intersectObject( object, true );\n\n\tfor ( let i = 0; i < allIntersections.length; i ++ ) {\n\n\t\tif ( allIntersections[ i ].object.visible || includeInvisible ) {\n\n\t\t\treturn allIntersections[ i ];\n\n\t\t}\n\n\t}\n\n\treturn false;\n\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\nclass TransformControlsRoot extends Object3D {\n\n\tconstructor( controls ) {\n\n\t\tsuper();\n\n\t\tthis.isTransformControlsRoot = true;\n\n\t\tthis.controls = controls;\n\t\tthis.visible = false;\n\n\t}\n\n\t// updateMatrixWorld updates key transformation variables\n\tupdateMatrixWorld( force ) {\n\n\t\tconst controls = this.controls;\n\n\t\tif ( controls.object !== undefined ) {\n\n\t\t\tcontrols.object.updateMatrixWorld();\n\n\t\t\tif ( controls.object.parent === null ) {\n\n\t\t\t\tconsole.error( 'TransformControls: The attached 3D object must be a part of the scene graph.' );\n\n\t\t\t} else {\n\n\t\t\t\tcontrols.object.parent.matrixWorld.decompose( controls._parentPosition, controls._parentQuaternion, controls._parentScale );\n\n\t\t\t}\n\n\t\t\tcontrols.object.matrixWorld.decompose( controls.worldPosition, controls.worldQuaternion, controls._worldScale );\n\n\t\t\tcontrols._parentQuaternionInv.copy( controls._parentQuaternion ).invert();\n\t\t\tcontrols._worldQuaternionInv.copy( controls.worldQuaternion ).invert();\n\n\t\t}\n\n\t\tcontrols.camera.updateMatrixWorld();\n\t\tcontrols.camera.matrixWorld.decompose( controls.cameraPosition, controls.cameraQuaternion, controls._cameraScale );\n\n\t\tif ( controls.camera.isOrthographicCamera ) {\n\n\t\t\tcontrols.camera.getWorldDirection( controls.eye ).negate();\n\n\t\t} else {\n\n\t\t\tcontrols.eye.copy( controls.cameraPosition ).sub( controls.worldPosition ).normalize();\n\n\t\t}\n\n\t\tsuper.updateMatrixWorld( force );\n\n\t}\n\n\tdispose() {\n\n\t\tthis.traverse( function ( child ) {\n\n\t\t\tif ( child.geometry ) child.geometry.dispose();\n\t\t\tif ( child.material ) child.material.dispose();\n\n\t\t} );\n\n\t}\n\n}\n\nclass TransformControlsGizmo extends Object3D {\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\tthis.isTransformControlsGizmo = true;\n\n\t\tthis.type = 'TransformControlsGizmo';\n\n\t\t// shared materials\n\n\t\tconst gizmoMaterial = new MeshBasicMaterial( {\n\t\t\tdepthTest: false,\n\t\t\tdepthWrite: false,\n\t\t\tfog: false,\n\t\t\ttoneMapped: false,\n\t\t\ttransparent: true\n\t\t} );\n\n\t\tconst gizmoLineMaterial = new LineBasicMaterial( {\n\t\t\tdepthTest: false,\n\t\t\tdepthWrite: false,\n\t\t\tfog: false,\n\t\t\ttoneMapped: false,\n\t\t\ttransparent: true\n\t\t} );\n\n\t\t// Make unique material for each axis/color\n\n\t\tconst matInvisible = gizmoMaterial.clone();\n\t\tmatInvisible.opacity = 0.15;\n\n\t\tconst matHelper = gizmoLineMaterial.clone();\n\t\tmatHelper.opacity = 0.5;\n\n\t\tconst matRed = gizmoMaterial.clone();\n\t\tmatRed.color.setHex( 0xff0000 );\n\n\t\tconst matGreen = gizmoMaterial.clone();\n\t\tmatGreen.color.setHex( 0x00ff00 );\n\n\t\tconst matBlue = gizmoMaterial.clone();\n\t\tmatBlue.color.setHex( 0x0000ff );\n\n\t\tconst matRedTransparent = gizmoMaterial.clone();\n\t\tmatRedTransparent.color.setHex( 0xff0000 );\n\t\tmatRedTransparent.opacity = 0.5;\n\n\t\tconst matGreenTransparent = gizmoMaterial.clone();\n\t\tmatGreenTransparent.color.setHex( 0x00ff00 );\n\t\tmatGreenTransparent.opacity = 0.5;\n\n\t\tconst matBlueTransparent = gizmoMaterial.clone();\n\t\tmatBlueTransparent.color.setHex( 0x0000ff );\n\t\tmatBlueTransparent.opacity = 0.5;\n\n\t\tconst matWhiteTransparent = gizmoMaterial.clone();\n\t\tmatWhiteTransparent.opacity = 0.25;\n\n\t\tconst matYellowTransparent = gizmoMaterial.clone();\n\t\tmatYellowTransparent.color.setHex( 0xffff00 );\n\t\tmatYellowTransparent.opacity = 0.25;\n\n\t\tconst matYellow = gizmoMaterial.clone();\n\t\tmatYellow.color.setHex( 0xffff00 );\n\n\t\tconst matGray = gizmoMaterial.clone();\n\t\tmatGray.color.setHex( 0x787878 );\n\n\t\t// reusable geometry\n\n\t\tconst arrowGeometry = new CylinderGeometry( 0, 0.04, 0.1, 12 );\n\t\tarrowGeometry.translate( 0, 0.05, 0 );\n\n\t\tconst scaleHandleGeometry = new BoxGeometry( 0.08, 0.08, 0.08 );\n\t\tscaleHandleGeometry.translate( 0, 0.04, 0 );\n\n\t\tconst lineGeometry = new BufferGeometry();\n\t\tlineGeometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0,\t1, 0, 0 ], 3 ) );\n\n\t\tconst lineGeometry2 = new CylinderGeometry( 0.0075, 0.0075, 0.5, 3 );\n\t\tlineGeometry2.translate( 0, 0.25, 0 );\n\n\t\tfunction CircleGeometry( radius, arc ) {\n\n\t\t\tconst geometry = new TorusGeometry( radius, 0.0075, 3, 64, arc * Math.PI * 2 );\n\t\t\tgeometry.rotateY( Math.PI / 2 );\n\t\t\tgeometry.rotateX( Math.PI / 2 );\n\t\t\treturn geometry;\n\n\t\t}\n\n\t\t// Special geometry for transform helper. If scaled with position vector it spans from [0,0,0] to position\n\n\t\tfunction TranslateHelperGeometry() {\n\n\t\t\tconst geometry = new BufferGeometry();\n\n\t\t\tgeometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 1, 1, 1 ], 3 ) );\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t\t// Gizmo definitions - custom hierarchy definitions for setupGizmo() function\n\n\t\tconst gizmoTranslate = {\n\t\t\tX: [\n\t\t\t\t[ new Mesh( arrowGeometry, matRed ), [ 0.5, 0, 0 ], [ 0, 0, - Math.PI / 2 ]],\n\t\t\t\t[ new Mesh( arrowGeometry, matRed ), [ - 0.5, 0, 0 ], [ 0, 0, Math.PI / 2 ]],\n\t\t\t\t[ new Mesh( lineGeometry2, matRed ), [ 0, 0, 0 ], [ 0, 0, - Math.PI / 2 ]]\n\t\t\t],\n\t\t\tY: [\n\t\t\t\t[ new Mesh( arrowGeometry, matGreen ), [ 0, 0.5, 0 ]],\n\t\t\t\t[ new Mesh( arrowGeometry, matGreen ), [ 0, - 0.5, 0 ], [ Math.PI, 0, 0 ]],\n\t\t\t\t[ new Mesh( lineGeometry2, matGreen ) ]\n\t\t\t],\n\t\t\tZ: [\n\t\t\t\t[ new Mesh( arrowGeometry, matBlue ), [ 0, 0, 0.5 ], [ Math.PI / 2, 0, 0 ]],\n\t\t\t\t[ new Mesh( arrowGeometry, matBlue ), [ 0, 0, - 0.5 ], [ - Math.PI / 2, 0, 0 ]],\n\t\t\t\t[ new Mesh( lineGeometry2, matBlue ), null, [ Math.PI / 2, 0, 0 ]]\n\t\t\t],\n\t\t\tXYZ: [\n\t\t\t\t[ new Mesh( new OctahedronGeometry( 0.1, 0 ), matWhiteTransparent.clone() ), [ 0, 0, 0 ]]\n\t\t\t],\n\t\t\tXY: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.15, 0.15, 0.01 ), matBlueTransparent.clone() ), [ 0.15, 0.15, 0 ]]\n\t\t\t],\n\t\t\tYZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.15, 0.15, 0.01 ), matRedTransparent.clone() ), [ 0, 0.15, 0.15 ], [ 0, Math.PI / 2, 0 ]]\n\t\t\t],\n\t\t\tXZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.15, 0.15, 0.01 ), matGreenTransparent.clone() ), [ 0.15, 0, 0.15 ], [ - Math.PI / 2, 0, 0 ]]\n\t\t\t]\n\t\t};\n\n\t\tconst pickerTranslate = {\n\t\t\tX: [\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0.3, 0, 0 ], [ 0, 0, - Math.PI / 2 ]],\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ - 0.3, 0, 0 ], [ 0, 0, Math.PI / 2 ]]\n\t\t\t],\n\t\t\tY: [\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0.3, 0 ]],\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, - 0.3, 0 ], [ 0, 0, Math.PI ]]\n\t\t\t],\n\t\t\tZ: [\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0, 0.3 ], [ Math.PI / 2, 0, 0 ]],\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0, - 0.3 ], [ - Math.PI / 2, 0, 0 ]]\n\t\t\t],\n\t\t\tXYZ: [\n\t\t\t\t[ new Mesh( new OctahedronGeometry( 0.2, 0 ), matInvisible ) ]\n\t\t\t],\n\t\t\tXY: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0.15, 0.15, 0 ]]\n\t\t\t],\n\t\t\tYZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0, 0.15, 0.15 ], [ 0, Math.PI / 2, 0 ]]\n\t\t\t],\n\t\t\tXZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0.15, 0, 0.15 ], [ - Math.PI / 2, 0, 0 ]]\n\t\t\t]\n\t\t};\n\n\t\tconst helperTranslate = {\n\t\t\tSTART: [\n\t\t\t\t[ new Mesh( new OctahedronGeometry( 0.01, 2 ), matHelper ), null, null, null, 'helper' ]\n\t\t\t],\n\t\t\tEND: [\n\t\t\t\t[ new Mesh( new OctahedronGeometry( 0.01, 2 ), matHelper ), null, null, null, 'helper' ]\n\t\t\t],\n\t\t\tDELTA: [\n\t\t\t\t[ new Line( TranslateHelperGeometry(), matHelper ), null, null, null, 'helper' ]\n\t\t\t],\n\t\t\tX: [\n\t\t\t\t[ new Line( lineGeometry, matHelper.clone() ), [ - 1e3, 0, 0 ], null, [ 1e6, 1, 1 ], 'helper' ]\n\t\t\t],\n\t\t\tY: [\n\t\t\t\t[ new Line( lineGeometry, matHelper.clone() ), [ 0, - 1e3, 0 ], [ 0, 0, Math.PI / 2 ], [ 1e6, 1, 1 ], 'helper' ]\n\t\t\t],\n\t\t\tZ: [\n\t\t\t\t[ new Line( lineGeometry, matHelper.clone() ), [ 0, 0, - 1e3 ], [ 0, - Math.PI / 2, 0 ], [ 1e6, 1, 1 ], 'helper' ]\n\t\t\t]\n\t\t};\n\n\t\tconst gizmoRotate = {\n\t\t\tXYZE: [\n\t\t\t\t[ new Mesh( CircleGeometry( 0.5, 1 ), matGray ), null, [ 0, Math.PI / 2, 0 ]]\n\t\t\t],\n\t\t\tX: [\n\t\t\t\t[ new Mesh( CircleGeometry( 0.5, 0.5 ), matRed ) ]\n\t\t\t],\n\t\t\tY: [\n\t\t\t\t[ new Mesh( CircleGeometry( 0.5, 0.5 ), matGreen ), null, [ 0, 0, - Math.PI / 2 ]]\n\t\t\t],\n\t\t\tZ: [\n\t\t\t\t[ new Mesh( CircleGeometry( 0.5, 0.5 ), matBlue ), null, [ 0, Math.PI / 2, 0 ]]\n\t\t\t],\n\t\t\tE: [\n\t\t\t\t[ new Mesh( CircleGeometry( 0.75, 1 ), matYellowTransparent ), null, [ 0, Math.PI / 2, 0 ]]\n\t\t\t]\n\t\t};\n\n\t\tconst helperRotate = {\n\t\t\tAXIS: [\n\t\t\t\t[ new Line( lineGeometry, matHelper.clone() ), [ - 1e3, 0, 0 ], null, [ 1e6, 1, 1 ], 'helper' ]\n\t\t\t]\n\t\t};\n\n\t\tconst pickerRotate = {\n\t\t\tXYZE: [\n\t\t\t\t[ new Mesh( new SphereGeometry( 0.25, 10, 8 ), matInvisible ) ]\n\t\t\t],\n\t\t\tX: [\n\t\t\t\t[ new Mesh( new TorusGeometry( 0.5, 0.1, 4, 24 ), matInvisible ), [ 0, 0, 0 ], [ 0, - Math.PI / 2, - Math.PI / 2 ]],\n\t\t\t],\n\t\t\tY: [\n\t\t\t\t[ new Mesh( new TorusGeometry( 0.5, 0.1, 4, 24 ), matInvisible ), [ 0, 0, 0 ], [ Math.PI / 2, 0, 0 ]],\n\t\t\t],\n\t\t\tZ: [\n\t\t\t\t[ new Mesh( new TorusGeometry( 0.5, 0.1, 4, 24 ), matInvisible ), [ 0, 0, 0 ], [ 0, 0, - Math.PI / 2 ]],\n\t\t\t],\n\t\t\tE: [\n\t\t\t\t[ new Mesh( new TorusGeometry( 0.75, 0.1, 2, 24 ), matInvisible ) ]\n\t\t\t]\n\t\t};\n\n\t\tconst gizmoScale = {\n\t\t\tX: [\n\t\t\t\t[ new Mesh( scaleHandleGeometry, matRed ), [ 0.5, 0, 0 ], [ 0, 0, - Math.PI / 2 ]],\n\t\t\t\t[ new Mesh( lineGeometry2, matRed ), [ 0, 0, 0 ], [ 0, 0, - Math.PI / 2 ]],\n\t\t\t\t[ new Mesh( scaleHandleGeometry, matRed ), [ - 0.5, 0, 0 ], [ 0, 0, Math.PI / 2 ]],\n\t\t\t],\n\t\t\tY: [\n\t\t\t\t[ new Mesh( scaleHandleGeometry, matGreen ), [ 0, 0.5, 0 ]],\n\t\t\t\t[ new Mesh( lineGeometry2, matGreen ) ],\n\t\t\t\t[ new Mesh( scaleHandleGeometry, matGreen ), [ 0, - 0.5, 0 ], [ 0, 0, Math.PI ]],\n\t\t\t],\n\t\t\tZ: [\n\t\t\t\t[ new Mesh( scaleHandleGeometry, matBlue ), [ 0, 0, 0.5 ], [ Math.PI / 2, 0, 0 ]],\n\t\t\t\t[ new Mesh( lineGeometry2, matBlue ), [ 0, 0, 0 ], [ Math.PI / 2, 0, 0 ]],\n\t\t\t\t[ new Mesh( scaleHandleGeometry, matBlue ), [ 0, 0, - 0.5 ], [ - Math.PI / 2, 0, 0 ]]\n\t\t\t],\n\t\t\tXY: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.15, 0.15, 0.01 ), matBlueTransparent ), [ 0.15, 0.15, 0 ]]\n\t\t\t],\n\t\t\tYZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.15, 0.15, 0.01 ), matRedTransparent ), [ 0, 0.15, 0.15 ], [ 0, Math.PI / 2, 0 ]]\n\t\t\t],\n\t\t\tXZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.15, 0.15, 0.01 ), matGreenTransparent ), [ 0.15, 0, 0.15 ], [ - Math.PI / 2, 0, 0 ]]\n\t\t\t],\n\t\t\tXYZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.1, 0.1, 0.1 ), matWhiteTransparent.clone() ) ],\n\t\t\t]\n\t\t};\n\n\t\tconst pickerScale = {\n\t\t\tX: [\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0.3, 0, 0 ], [ 0, 0, - Math.PI / 2 ]],\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ - 0.3, 0, 0 ], [ 0, 0, Math.PI / 2 ]]\n\t\t\t],\n\t\t\tY: [\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0.3, 0 ]],\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, - 0.3, 0 ], [ 0, 0, Math.PI ]]\n\t\t\t],\n\t\t\tZ: [\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0, 0.3 ], [ Math.PI / 2, 0, 0 ]],\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0, - 0.3 ], [ - Math.PI / 2, 0, 0 ]]\n\t\t\t],\n\t\t\tXY: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0.15, 0.15, 0 ]],\n\t\t\t],\n\t\t\tYZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0, 0.15, 0.15 ], [ 0, Math.PI / 2, 0 ]],\n\t\t\t],\n\t\t\tXZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0.15, 0, 0.15 ], [ - Math.PI / 2, 0, 0 ]],\n\t\t\t],\n\t\t\tXYZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.2 ), matInvisible ), [ 0, 0, 0 ]],\n\t\t\t]\n\t\t};\n\n\t\tconst helperScale = {\n\t\t\tX: [\n\t\t\t\t[ new Line( lineGeometry, matHelper.clone() ), [ - 1e3, 0, 0 ], null, [ 1e6, 1, 1 ], 'helper' ]\n\t\t\t],\n\t\t\tY: [\n\t\t\t\t[ new Line( lineGeometry, matHelper.clone() ), [ 0, - 1e3, 0 ], [ 0, 0, Math.PI / 2 ], [ 1e6, 1, 1 ], 'helper' ]\n\t\t\t],\n\t\t\tZ: [\n\t\t\t\t[ new Line( lineGeometry, matHelper.clone() ), [ 0, 0, - 1e3 ], [ 0, - Math.PI / 2, 0 ], [ 1e6, 1, 1 ], 'helper' ]\n\t\t\t]\n\t\t};\n\n\t\t// Creates an Object3D with gizmos described in custom hierarchy definition.\n\n\t\tfunction setupGizmo( gizmoMap ) {\n\n\t\t\tconst gizmo = new Object3D();\n\n\t\t\tfor ( const name in gizmoMap ) {\n\n\t\t\t\tfor ( let i = gizmoMap[ name ].length; i --; ) {\n\n\t\t\t\t\tconst object = gizmoMap[ name ][ i ][ 0 ].clone();\n\t\t\t\t\tconst position = gizmoMap[ name ][ i ][ 1 ];\n\t\t\t\t\tconst rotation = gizmoMap[ name ][ i ][ 2 ];\n\t\t\t\t\tconst scale = gizmoMap[ name ][ i ][ 3 ];\n\t\t\t\t\tconst tag = gizmoMap[ name ][ i ][ 4 ];\n\n\t\t\t\t\t// name and tag properties are essential for picking and updating logic.\n\t\t\t\t\tobject.name = name;\n\t\t\t\t\tobject.tag = tag;\n\n\t\t\t\t\tif ( position ) {\n\n\t\t\t\t\t\tobject.position.set( position[ 0 ], position[ 1 ], position[ 2 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( rotation ) {\n\n\t\t\t\t\t\tobject.rotation.set( rotation[ 0 ], rotation[ 1 ], rotation[ 2 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( scale ) {\n\n\t\t\t\t\t\tobject.scale.set( scale[ 0 ], scale[ 1 ], scale[ 2 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tobject.updateMatrix();\n\n\t\t\t\t\tconst tempGeometry = object.geometry.clone();\n\t\t\t\t\ttempGeometry.applyMatrix4( object.matrix );\n\t\t\t\t\tobject.geometry = tempGeometry;\n\t\t\t\t\tobject.renderOrder = Infinity;\n\n\t\t\t\t\tobject.position.set( 0, 0, 0 );\n\t\t\t\t\tobject.rotation.set( 0, 0, 0 );\n\t\t\t\t\tobject.scale.set( 1, 1, 1 );\n\n\t\t\t\t\tgizmo.add( object );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn gizmo;\n\n\t\t}\n\n\t\t// Gizmo creation\n\n\t\tthis.gizmo = {};\n\t\tthis.picker = {};\n\t\tthis.helper = {};\n\n\t\tthis.add( this.gizmo[ 'translate' ] = setupGizmo( gizmoTranslate ) );\n\t\tthis.add( this.gizmo[ 'rotate' ] = setupGizmo( gizmoRotate ) );\n\t\tthis.add( this.gizmo[ 'scale' ] = setupGizmo( gizmoScale ) );\n\t\tthis.add( this.picker[ 'translate' ] = setupGizmo( pickerTranslate ) );\n\t\tthis.add( this.picker[ 'rotate' ] = setupGizmo( pickerRotate ) );\n\t\tthis.add( this.picker[ 'scale' ] = setupGizmo( pickerScale ) );\n\t\tthis.add( this.helper[ 'translate' ] = setupGizmo( helperTranslate ) );\n\t\tthis.add( this.helper[ 'rotate' ] = setupGizmo( helperRotate ) );\n\t\tthis.add( this.helper[ 'scale' ] = setupGizmo( helperScale ) );\n\n\t\t// Pickers should be hidden always\n\n\t\tthis.picker[ 'translate' ].visible = false;\n\t\tthis.picker[ 'rotate' ].visible = false;\n\t\tthis.picker[ 'scale' ].visible = false;\n\n\t}\n\n\t// updateMatrixWorld will update transformations and appearance of individual handles\n\n\tupdateMatrixWorld( force ) {\n\n\t\tconst space = ( this.mode === 'scale' ) ? 'local' : this.space; // scale always oriented to local rotation\n\n\t\tconst quaternion = ( space === 'local' ) ? this.worldQuaternion : _identityQuaternion;\n\n\t\t// Show only gizmos for current transform mode\n\n\t\tthis.gizmo[ 'translate' ].visible = this.mode === 'translate';\n\t\tthis.gizmo[ 'rotate' ].visible = this.mode === 'rotate';\n\t\tthis.gizmo[ 'scale' ].visible = this.mode === 'scale';\n\n\t\tthis.helper[ 'translate' ].visible = this.mode === 'translate';\n\t\tthis.helper[ 'rotate' ].visible = this.mode === 'rotate';\n\t\tthis.helper[ 'scale' ].visible = this.mode === 'scale';\n\n\n\t\tlet handles = [];\n\t\thandles = handles.concat( this.picker[ this.mode ].children );\n\t\thandles = handles.concat( this.gizmo[ this.mode ].children );\n\t\thandles = handles.concat( this.helper[ this.mode ].children );\n\n\t\tfor ( let i = 0; i < handles.length; i ++ ) {\n\n\t\t\tconst handle = handles[ i ];\n\n\t\t\t// hide aligned to camera\n\n\t\t\thandle.visible = true;\n\t\t\thandle.rotation.set( 0, 0, 0 );\n\t\t\thandle.position.copy( this.worldPosition );\n\n\t\t\tlet factor;\n\n\t\t\tif ( this.camera.isOrthographicCamera ) {\n\n\t\t\t\tfactor = ( this.camera.top - this.camera.bottom ) / this.camera.zoom;\n\n\t\t\t} else {\n\n\t\t\t\tfactor = this.worldPosition.distanceTo( this.cameraPosition ) * Math.min( 1.9 * Math.tan( Math.PI * this.camera.fov / 360 ) / this.camera.zoom, 7 );\n\n\t\t\t}\n\n\t\t\thandle.scale.set( 1, 1, 1 ).multiplyScalar( factor * this.size / 4 );\n\n\t\t\t// TODO: simplify helpers and consider decoupling from gizmo\n\n\t\t\tif ( handle.tag === 'helper' ) {\n\n\t\t\t\thandle.visible = false;\n\n\t\t\t\tif ( handle.name === 'AXIS' ) {\n\n\t\t\t\t\thandle.visible = !! this.axis;\n\n\t\t\t\t\tif ( this.axis === 'X' ) {\n\n\t\t\t\t\t\t_tempQuaternion.setFromEuler( _tempEuler.set( 0, 0, 0 ) );\n\t\t\t\t\t\thandle.quaternion.copy( quaternion ).multiply( _tempQuaternion );\n\n\t\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) ) > 0.9 ) {\n\n\t\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( this.axis === 'Y' ) {\n\n\t\t\t\t\t\t_tempQuaternion.setFromEuler( _tempEuler.set( 0, 0, Math.PI / 2 ) );\n\t\t\t\t\t\thandle.quaternion.copy( quaternion ).multiply( _tempQuaternion );\n\n\t\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitY ).applyQuaternion( quaternion ).dot( this.eye ) ) > 0.9 ) {\n\n\t\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( this.axis === 'Z' ) {\n\n\t\t\t\t\t\t_tempQuaternion.setFromEuler( _tempEuler.set( 0, Math.PI / 2, 0 ) );\n\t\t\t\t\t\thandle.quaternion.copy( quaternion ).multiply( _tempQuaternion );\n\n\t\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitZ ).applyQuaternion( quaternion ).dot( this.eye ) ) > 0.9 ) {\n\n\t\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( this.axis === 'XYZE' ) {\n\n\t\t\t\t\t\t_tempQuaternion.setFromEuler( _tempEuler.set( 0, Math.PI / 2, 0 ) );\n\t\t\t\t\t\t_alignVector.copy( this.rotationAxis );\n\t\t\t\t\t\thandle.quaternion.setFromRotationMatrix( _lookAtMatrix.lookAt( _zeroVector, _alignVector, _unitY ) );\n\t\t\t\t\t\thandle.quaternion.multiply( _tempQuaternion );\n\t\t\t\t\t\thandle.visible = this.dragging;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( this.axis === 'E' ) {\n\n\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t}\n\n\n\t\t\t\t} else if ( handle.name === 'START' ) {\n\n\t\t\t\t\thandle.position.copy( this.worldPositionStart );\n\t\t\t\t\thandle.visible = this.dragging;\n\n\t\t\t\t} else if ( handle.name === 'END' ) {\n\n\t\t\t\t\thandle.position.copy( this.worldPosition );\n\t\t\t\t\thandle.visible = this.dragging;\n\n\t\t\t\t} else if ( handle.name === 'DELTA' ) {\n\n\t\t\t\t\thandle.position.copy( this.worldPositionStart );\n\t\t\t\t\thandle.quaternion.copy( this.worldQuaternionStart );\n\t\t\t\t\t_tempVector.set( 1e-10, 1e-10, 1e-10 ).add( this.worldPositionStart ).sub( this.worldPosition ).multiplyScalar( - 1 );\n\t\t\t\t\t_tempVector.applyQuaternion( this.worldQuaternionStart.clone().invert() );\n\t\t\t\t\thandle.scale.copy( _tempVector );\n\t\t\t\t\thandle.visible = this.dragging;\n\n\t\t\t\t} else {\n\n\t\t\t\t\thandle.quaternion.copy( quaternion );\n\n\t\t\t\t\tif ( this.dragging ) {\n\n\t\t\t\t\t\thandle.position.copy( this.worldPositionStart );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\thandle.position.copy( this.worldPosition );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( this.axis ) {\n\n\t\t\t\t\t\thandle.visible = this.axis.search( handle.name ) !== - 1;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// If updating helper, skip rest of the loop\n\t\t\t\tcontinue;\n\n\t\t\t}\n\n\t\t\t// Align handles to current local or world rotation\n\n\t\t\thandle.quaternion.copy( quaternion );\n\n\t\t\tif ( this.mode === 'translate' || this.mode === 'scale' ) {\n\n\t\t\t\t// Hide translate and scale axis facing the camera\n\n\t\t\t\tconst AXIS_HIDE_THRESHOLD = 0.99;\n\t\t\t\tconst PLANE_HIDE_THRESHOLD = 0.2;\n\n\t\t\t\tif ( handle.name === 'X' ) {\n\n\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) ) > AXIS_HIDE_THRESHOLD ) {\n\n\t\t\t\t\t\thandle.scale.set( 1e-10, 1e-10, 1e-10 );\n\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( handle.name === 'Y' ) {\n\n\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitY ).applyQuaternion( quaternion ).dot( this.eye ) ) > AXIS_HIDE_THRESHOLD ) {\n\n\t\t\t\t\t\thandle.scale.set( 1e-10, 1e-10, 1e-10 );\n\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( handle.name === 'Z' ) {\n\n\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitZ ).applyQuaternion( quaternion ).dot( this.eye ) ) > AXIS_HIDE_THRESHOLD ) {\n\n\t\t\t\t\t\thandle.scale.set( 1e-10, 1e-10, 1e-10 );\n\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( handle.name === 'XY' ) {\n\n\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitZ ).applyQuaternion( quaternion ).dot( this.eye ) ) < PLANE_HIDE_THRESHOLD ) {\n\n\t\t\t\t\t\thandle.scale.set( 1e-10, 1e-10, 1e-10 );\n\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( handle.name === 'YZ' ) {\n\n\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) ) < PLANE_HIDE_THRESHOLD ) {\n\n\t\t\t\t\t\thandle.scale.set( 1e-10, 1e-10, 1e-10 );\n\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( handle.name === 'XZ' ) {\n\n\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitY ).applyQuaternion( quaternion ).dot( this.eye ) ) < PLANE_HIDE_THRESHOLD ) {\n\n\t\t\t\t\t\thandle.scale.set( 1e-10, 1e-10, 1e-10 );\n\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( this.mode === 'rotate' ) {\n\n\t\t\t\t// Align handles to current local or world rotation\n\n\t\t\t\t_tempQuaternion2.copy( quaternion );\n\t\t\t\t_alignVector.copy( this.eye ).applyQuaternion( _tempQuaternion.copy( quaternion ).invert() );\n\n\t\t\t\tif ( handle.name.search( 'E' ) !== - 1 ) {\n\n\t\t\t\t\thandle.quaternion.setFromRotationMatrix( _lookAtMatrix.lookAt( this.eye, _zeroVector, _unitY ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( handle.name === 'X' ) {\n\n\t\t\t\t\t_tempQuaternion.setFromAxisAngle( _unitX, Math.atan2( - _alignVector.y, _alignVector.z ) );\n\t\t\t\t\t_tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion );\n\t\t\t\t\thandle.quaternion.copy( _tempQuaternion );\n\n\t\t\t\t}\n\n\t\t\t\tif ( handle.name === 'Y' ) {\n\n\t\t\t\t\t_tempQuaternion.setFromAxisAngle( _unitY, Math.atan2( _alignVector.x, _alignVector.z ) );\n\t\t\t\t\t_tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion );\n\t\t\t\t\thandle.quaternion.copy( _tempQuaternion );\n\n\t\t\t\t}\n\n\t\t\t\tif ( handle.name === 'Z' ) {\n\n\t\t\t\t\t_tempQuaternion.setFromAxisAngle( _unitZ, Math.atan2( _alignVector.y, _alignVector.x ) );\n\t\t\t\t\t_tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion );\n\t\t\t\t\thandle.quaternion.copy( _tempQuaternion );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Hide disabled axes\n\t\t\thandle.visible = handle.visible && ( handle.name.indexOf( 'X' ) === - 1 || this.showX );\n\t\t\thandle.visible = handle.visible && ( handle.name.indexOf( 'Y' ) === - 1 || this.showY );\n\t\t\thandle.visible = handle.visible && ( handle.name.indexOf( 'Z' ) === - 1 || this.showZ );\n\t\t\thandle.visible = handle.visible && ( handle.name.indexOf( 'E' ) === - 1 || ( this.showX && this.showY && this.showZ ) );\n\n\t\t\t// highlight selected axis\n\n\t\t\thandle.material._color = handle.material._color || handle.material.color.clone();\n\t\t\thandle.material._opacity = handle.material._opacity || handle.material.opacity;\n\n\t\t\thandle.material.color.copy( handle.material._color );\n\t\t\thandle.material.opacity = handle.material._opacity;\n\n\t\t\tif ( this.enabled && this.axis ) {\n\n\t\t\t\tif ( handle.name === this.axis ) {\n\n\t\t\t\t\thandle.material.color.setHex( 0xffff00 );\n\t\t\t\t\thandle.material.opacity = 1.0;\n\n\t\t\t\t} else if ( this.axis.split( '' ).some( function ( a ) {\n\n\t\t\t\t\treturn handle.name === a;\n\n\t\t\t\t} ) ) {\n\n\t\t\t\t\thandle.material.color.setHex( 0xffff00 );\n\t\t\t\t\thandle.material.opacity = 1.0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tsuper.updateMatrixWorld( force );\n\n\t}\n\n}\n\n//\n\nclass TransformControlsPlane extends Mesh {\n\n\tconstructor() {\n\n\t\tsuper(\n\t\t\tnew PlaneGeometry( 100000, 100000, 2, 2 ),\n\t\t\tnew MeshBasicMaterial( { visible: false, wireframe: true, side: DoubleSide, transparent: true, opacity: 0.1, toneMapped: false } )\n\t\t);\n\n\t\tthis.isTransformControlsPlane = true;\n\n\t\tthis.type = 'TransformControlsPlane';\n\n\t}\n\n\tupdateMatrixWorld( force ) {\n\n\t\tlet space = this.space;\n\n\t\tthis.position.copy( this.worldPosition );\n\n\t\tif ( this.mode === 'scale' ) space = 'local'; // scale always oriented to local rotation\n\n\t\t_v1.copy( _unitX ).applyQuaternion( space === 'local' ? this.worldQuaternion : _identityQuaternion );\n\t\t_v2.copy( _unitY ).applyQuaternion( space === 'local' ? this.worldQuaternion : _identityQuaternion );\n\t\t_v3.copy( _unitZ ).applyQuaternion( space === 'local' ? this.worldQuaternion : _identityQuaternion );\n\n\t\t// Align the plane for current transform mode, axis and space.\n\n\t\t_alignVector.copy( _v2 );\n\n\t\tswitch ( this.mode ) {\n\n\t\t\tcase 'translate':\n\t\t\tcase 'scale':\n\t\t\t\tswitch ( this.axis ) {\n\n\t\t\t\t\tcase 'X':\n\t\t\t\t\t\t_alignVector.copy( this.eye ).cross( _v1 );\n\t\t\t\t\t\t_dirVector.copy( _v1 ).cross( _alignVector );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'Y':\n\t\t\t\t\t\t_alignVector.copy( this.eye ).cross( _v2 );\n\t\t\t\t\t\t_dirVector.copy( _v2 ).cross( _alignVector );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'Z':\n\t\t\t\t\t\t_alignVector.copy( this.eye ).cross( _v3 );\n\t\t\t\t\t\t_dirVector.copy( _v3 ).cross( _alignVector );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'XY':\n\t\t\t\t\t\t_dirVector.copy( _v3 );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'YZ':\n\t\t\t\t\t\t_dirVector.copy( _v1 );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'XZ':\n\t\t\t\t\t\t_alignVector.copy( _v3 );\n\t\t\t\t\t\t_dirVector.copy( _v2 );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'XYZ':\n\t\t\t\t\tcase 'E':\n\t\t\t\t\t\t_dirVector.set( 0, 0, 0 );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\tcase 'rotate':\n\t\t\tdefault:\n\t\t\t\t// special case for rotate\n\t\t\t\t_dirVector.set( 0, 0, 0 );\n\n\t\t}\n\n\t\tif ( _dirVector.length() === 0 ) {\n\n\t\t\t// If in rotate mode, make the plane parallel to camera\n\t\t\tthis.quaternion.copy( this.cameraQuaternion );\n\n\t\t} else {\n\n\t\t\t_tempMatrix.lookAt( _tempVector.set( 0, 0, 0 ), _dirVector, _alignVector );\n\n\t\t\tthis.quaternion.setFromRotationMatrix( _tempMatrix );\n\n\t\t}\n\n\t\tsuper.updateMatrixWorld( force );\n\n\t}\n\n}\n\nexport { TransformControls, TransformControlsGizmo, TransformControlsPlane };\n","import * as THREE from \"three\";\n\n/**\n * Base interface for all editor commands\n * Commands implement the command pattern for undo/redo support\n */\nexport interface Command {\n /**\n * Unique identifier for this command type\n */\n readonly type: string;\n\n /**\n * The object this command operates on\n */\n readonly object: THREE.Object3D;\n\n /**\n * Execute the command (apply the new state)\n */\n execute(): void;\n\n /**\n * Undo the command (restore the previous state)\n */\n undo(): void;\n\n /**\n * Whether this command can be merged with subsequent commands of the same type\n * Used for rapid updates (e.g., continuous dragging)\n */\n readonly updatable: boolean;\n\n /**\n * Update this command with a new end state\n * Only called if updatable is true and commands are of same type on same object\n */\n update?(command: Command): void;\n\n /**\n * Timestamp when this command was created\n */\n readonly timestamp: number;\n}\n\n/**\n * Base class providing common functionality for commands\n */\nexport abstract class BaseCommand implements Command {\n abstract readonly type: string;\n readonly object: THREE.Object3D;\n readonly updatable: boolean;\n readonly timestamp: number;\n\n constructor(object: THREE.Object3D, updatable: boolean = false) {\n this.object = object;\n this.updatable = updatable;\n this.timestamp = Date.now();\n }\n\n abstract execute(): void;\n abstract undo(): void;\n}\n","import * as THREE from \"three\";\nimport { BaseCommand, type Command } from \"./Command\";\n\n/**\n * Command to set an object's position\n */\nexport class SetPositionCommand extends BaseCommand {\n readonly type = \"SetPosition\";\n readonly updatable = true;\n\n private newPosition: THREE.Vector3;\n private oldPosition: THREE.Vector3;\n\n constructor(\n object: THREE.Object3D,\n newPosition: THREE.Vector3,\n oldPosition: THREE.Vector3\n ) {\n super(object, true);\n this.newPosition = newPosition.clone();\n this.oldPosition = oldPosition.clone();\n }\n\n execute(): void {\n this.object.position.copy(this.newPosition);\n }\n\n undo(): void {\n this.object.position.copy(this.oldPosition);\n }\n\n update(command: Command): void {\n if (command instanceof SetPositionCommand) {\n this.newPosition.copy(command.newPosition);\n }\n }\n\n /**\n * Get the new position\n */\n getNewPosition(): THREE.Vector3 {\n return this.newPosition.clone();\n }\n\n /**\n * Get the old position\n */\n getOldPosition(): THREE.Vector3 {\n return this.oldPosition.clone();\n }\n}\n","import * as THREE from \"three\";\nimport { BaseCommand, type Command } from \"./Command\";\n\n/**\n * Command to set an object's rotation\n */\nexport class SetRotationCommand extends BaseCommand {\n readonly type = \"SetRotation\";\n readonly updatable = true;\n\n private newRotation: THREE.Euler;\n private oldRotation: THREE.Euler;\n\n constructor(\n object: THREE.Object3D,\n newRotation: THREE.Euler,\n oldRotation: THREE.Euler\n ) {\n super(object, true);\n this.newRotation = newRotation.clone();\n this.oldRotation = oldRotation.clone();\n }\n\n execute(): void {\n this.object.rotation.copy(this.newRotation);\n }\n\n undo(): void {\n this.object.rotation.copy(this.oldRotation);\n }\n\n update(command: Command): void {\n if (command instanceof SetRotationCommand) {\n this.newRotation.copy(command.newRotation);\n }\n }\n\n /**\n * Get the new rotation\n */\n getNewRotation(): THREE.Euler {\n return this.newRotation.clone();\n }\n\n /**\n * Get the old rotation\n */\n getOldRotation(): THREE.Euler {\n return this.oldRotation.clone();\n }\n}\n","import * as THREE from \"three\";\nimport { BaseCommand, type Command } from \"./Command\";\n\n/**\n * Command to set an object's scale\n */\nexport class SetScaleCommand extends BaseCommand {\n readonly type = \"SetScale\";\n readonly updatable = true;\n\n private newScale: THREE.Vector3;\n private oldScale: THREE.Vector3;\n\n constructor(\n object: THREE.Object3D,\n newScale: THREE.Vector3,\n oldScale: THREE.Vector3\n ) {\n super(object, true);\n this.newScale = newScale.clone();\n this.oldScale = oldScale.clone();\n }\n\n execute(): void {\n this.object.scale.copy(this.newScale);\n }\n\n undo(): void {\n this.object.scale.copy(this.oldScale);\n }\n\n update(command: Command): void {\n if (command instanceof SetScaleCommand) {\n this.newScale.copy(command.newScale);\n }\n }\n\n /**\n * Get the new scale\n */\n getNewScale(): THREE.Vector3 {\n return this.newScale.clone();\n }\n\n /**\n * Get the old scale\n */\n getOldScale(): THREE.Vector3 {\n return this.oldScale.clone();\n }\n}\n","import * as THREE from \"three\";\nimport { TransformControls } from \"three/examples/jsm/controls/TransformControls.js\";\nimport type { Editor } from \"./Editor\";\nimport { SetPositionCommand } from \"./commands/SetPositionCommand\";\nimport { SetRotationCommand } from \"./commands/SetRotationCommand\";\nimport { SetScaleCommand } from \"./commands/SetScaleCommand\";\nimport type { Command } from \"./commands/Command\";\n\ntype TransformMode = \"translate\" | \"rotate\" | \"scale\";\ntype TransformCallback = (...args: unknown[]) => void;\n\n/**\n * Manages transform controls for selected objects\n */\nexport class TransformManager {\n private editor: Editor;\n private controls: TransformControls;\n private mode: TransformMode = \"translate\";\n private eventListeners: Map<string, Set<TransformCallback>> = new Map();\n\n // Track transform start state for undo\n private transformStartPosition: THREE.Vector3 | null = null;\n private transformStartRotation: THREE.Euler | null = null;\n private transformStartScale: THREE.Vector3 | null = null;\n private isTransforming: boolean = false;\n\n constructor(editor: Editor) {\n this.editor = editor;\n\n // Create TransformControls\n this.controls = new TransformControls(\n this.editor.camera,\n this.editor.renderer.domElement\n );\n this.controls.setSize(0.75);\n this.editor.scene.add(this.controls.getHelper());\n\n // Bind event handlers\n this.handleDraggingChanged = this.handleDraggingChanged.bind(this);\n this.handleObjectChange = this.handleObjectChange.bind(this);\n\n this.controls.addEventListener(\"dragging-changed\", this.handleDraggingChanged);\n this.controls.addEventListener(\"objectChange\", this.handleObjectChange);\n\n // Setup keyboard shortcuts\n this.handleKeyDown = this.handleKeyDown.bind(this);\n document.addEventListener(\"keydown\", this.handleKeyDown);\n }\n\n /**\n * Handle dragging state changes\n */\n private handleDraggingChanged(event: { value: unknown }): void {\n const isDragging = event.value as boolean;\n // Disable orbit controls while transforming\n this.editor.controls.enabled = !isDragging;\n\n if (isDragging) {\n // Starting transform - capture initial state\n this.captureStartState();\n this.isTransforming = true;\n } else if (this.isTransforming) {\n // Ending transform - create command\n this.createCommand();\n this.isTransforming = false;\n }\n }\n\n /**\n * Capture the start state before transform\n */\n private captureStartState(): void {\n const object = this.controls.object;\n if (!object) return;\n\n this.transformStartPosition = object.position.clone();\n this.transformStartRotation = object.rotation.clone();\n this.transformStartScale = object.scale.clone();\n }\n\n /**\n * Create a command after transform completes\n */\n private createCommand(): void {\n const object = this.controls.object;\n if (!object) return;\n\n let command: Command | null = null;\n\n switch (this.mode) {\n case \"translate\":\n if (this.transformStartPosition && !object.position.equals(this.transformStartPosition)) {\n command = new SetPositionCommand(\n object,\n object.position.clone(),\n this.transformStartPosition.clone()\n );\n }\n break;\n\n case \"rotate\":\n if (this.transformStartRotation) {\n const changed =\n object.rotation.x !== this.transformStartRotation.x ||\n object.rotation.y !== this.transformStartRotation.y ||\n object.rotation.z !== this.transformStartRotation.z;\n if (changed) {\n command = new SetRotationCommand(\n object,\n object.rotation.clone(),\n this.transformStartRotation.clone()\n );\n }\n }\n break;\n\n case \"scale\":\n if (this.transformStartScale && !object.scale.equals(this.transformStartScale)) {\n command = new SetScaleCommand(\n object,\n object.scale.clone(),\n this.transformStartScale.clone()\n );\n }\n break;\n }\n\n if (command) {\n this.emit(\"objectChanged\", object, command);\n }\n\n // Clear start state\n this.transformStartPosition = null;\n this.transformStartRotation = null;\n this.transformStartScale = null;\n }\n\n /**\n * Handle object change during transform (live updates)\n */\n private handleObjectChange(): void {\n // This fires continuously during drag - can be used for live UI updates\n const object = this.controls.object;\n if (object) {\n // Emit a lightweight change event for UI updates without creating commands\n this.emit(\"objectChanging\", object);\n }\n }\n\n /**\n * Handle keyboard shortcuts\n */\n private handleKeyDown(event: KeyboardEvent): void {\n // Ignore if in input field\n if (event.target instanceof HTMLInputElement || event.target instanceof HTMLTextAreaElement) {\n return;\n }\n\n switch (event.key.toLowerCase()) {\n case \"g\":\n this.setMode(\"translate\");\n break;\n case \"r\":\n if (!event.ctrlKey && !event.metaKey) {\n this.setMode(\"rotate\");\n }\n break;\n case \"s\":\n if (!event.ctrlKey && !event.metaKey) {\n this.setMode(\"scale\");\n }\n break;\n case \"escape\":\n if (this.isTransforming) {\n // Cancel transform - restore start state\n this.cancelTransform();\n }\n break;\n }\n }\n\n /**\n * Cancel current transform and restore original state\n */\n private cancelTransform(): void {\n const object = this.controls.object;\n if (!object) return;\n\n if (this.transformStartPosition) {\n object.position.copy(this.transformStartPosition);\n }\n if (this.transformStartRotation) {\n object.rotation.copy(this.transformStartRotation);\n }\n if (this.transformStartScale) {\n object.scale.copy(this.transformStartScale);\n }\n\n this.isTransforming = false;\n this.transformStartPosition = null;\n this.transformStartRotation = null;\n this.transformStartScale = null;\n }\n\n /**\n * Attach controls to an object\n */\n attach(object: THREE.Object3D | null): void {\n const helper = this.controls.getHelper();\n if (object) {\n this.controls.attach(object);\n helper.visible = true;\n } else {\n this.controls.detach();\n helper.visible = false;\n }\n }\n\n /**\n * Set transform mode\n */\n setMode(mode: TransformMode): void {\n this.mode = mode;\n this.controls.setMode(mode);\n this.emit(\"modeChanged\", mode);\n }\n\n /**\n * Get current transform mode\n */\n getMode(): TransformMode {\n return this.mode;\n }\n\n /**\n * Get TransformControls instance\n */\n getControls(): TransformControls {\n return this.controls;\n }\n\n /**\n * Add event listener\n */\n on(event: string, callback: TransformCallback): void {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, new Set());\n }\n this.eventListeners.get(event)!.add(callback);\n }\n\n /**\n * Emit event\n */\n private emit(event: string, ...args: unknown[]): void {\n this.eventListeners.get(event)?.forEach((callback) => callback(...args));\n }\n\n /**\n * Clean up\n */\n dispose(): void {\n document.removeEventListener(\"keydown\", this.handleKeyDown);\n this.controls.removeEventListener(\"dragging-changed\", this.handleDraggingChanged);\n this.controls.removeEventListener(\"objectChange\", this.handleObjectChange);\n this.controls.dispose();\n this.editor.scene.remove(this.controls.getHelper());\n this.eventListeners.clear();\n }\n}\n","import type { Command } from \"./commands/Command\";\n\ntype HistoryCallback = () => void;\n\nconst MERGE_WINDOW_MS = 500; // Commands within this window can be merged\n\n/**\n * Manages undo/redo history for editor commands\n */\nexport class History {\n private undoStack: Command[] = [];\n private redoStack: Command[] = [];\n private eventListeners: Map<string, Set<HistoryCallback>> = new Map();\n\n /**\n * Execute a command and add it to history\n */\n execute(command: Command): void {\n command.execute();\n\n // Try to merge with last command if within time window and updatable\n const lastCommand = this.undoStack[this.undoStack.length - 1];\n if (\n lastCommand &&\n lastCommand.updatable &&\n command.updatable &&\n lastCommand.type === command.type &&\n lastCommand.object === command.object &&\n command.timestamp - lastCommand.timestamp < MERGE_WINDOW_MS\n ) {\n // Merge into existing command\n if (lastCommand.update) {\n lastCommand.update(command);\n }\n } else {\n // Add as new command\n this.undoStack.push(command);\n }\n\n // Clear redo stack on new action\n this.redoStack = [];\n\n this.emit(\"historyChanged\");\n }\n\n /**\n * Undo the last command\n */\n undo(): void {\n const command = this.undoStack.pop();\n if (command) {\n command.undo();\n this.redoStack.push(command);\n this.emit(\"historyChanged\");\n }\n }\n\n /**\n * Redo the last undone command\n */\n redo(): void {\n const command = this.redoStack.pop();\n if (command) {\n command.execute();\n this.undoStack.push(command);\n this.emit(\"historyChanged\");\n }\n }\n\n /**\n * Check if undo is available\n */\n canUndo(): boolean {\n return this.undoStack.length > 0;\n }\n\n /**\n * Check if redo is available\n */\n canRedo(): boolean {\n return this.redoStack.length > 0;\n }\n\n /**\n * Clear all history\n */\n clear(): void {\n this.undoStack = [];\n this.redoStack = [];\n this.emit(\"historyChanged\");\n }\n\n /**\n * Get the number of items in undo stack\n */\n getUndoCount(): number {\n return this.undoStack.length;\n }\n\n /**\n * Get the number of items in redo stack\n */\n getRedoCount(): number {\n return this.redoStack.length;\n }\n\n /**\n * Add event listener\n */\n on(event: string, callback: HistoryCallback): void {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, new Set());\n }\n this.eventListeners.get(event)!.add(callback);\n }\n\n /**\n * Emit event\n */\n private emit(event: string): void {\n this.eventListeners.get(event)?.forEach((callback) => callback());\n }\n}\n","import * as THREE from \"three\";\nimport { SelectionManager } from \"./SelectionManager\";\nimport { TransformManager } from \"./TransformManager\";\nimport { History } from \"./History\";\nimport type { Command } from \"./commands/Command\";\nimport type { OrbitControls } from \"three/examples/jsm/controls/OrbitControls.js\";\n\nexport type EditorEvent =\n | \"selectionChanged\"\n | \"objectChanged\"\n | \"historyChanged\"\n | \"modeChanged\"\n | \"modelLoaded\";\n\nexport interface EditorOptions {\n scene: THREE.Scene;\n camera: THREE.Camera;\n renderer: THREE.WebGLRenderer;\n controls: OrbitControls;\n domElement: HTMLElement;\n}\n\ntype EventCallback = (...args: unknown[]) => void;\n\n/**\n * Central editor state manager\n * Coordinates selection, transforms, history, and emits events for UI updates\n */\nexport class Editor {\n public readonly scene: THREE.Scene;\n public readonly camera: THREE.Camera;\n public readonly renderer: THREE.WebGLRenderer;\n public readonly controls: OrbitControls;\n public readonly domElement: HTMLElement;\n\n public readonly selection: SelectionManager;\n public readonly transform: TransformManager;\n public readonly history: History;\n\n private currentModel: THREE.Group | null = null;\n private eventListeners: Map<EditorEvent, Set<EventCallback>> = new Map();\n\n constructor(options: EditorOptions) {\n this.scene = options.scene;\n this.camera = options.camera;\n this.renderer = options.renderer;\n this.controls = options.controls;\n this.domElement = options.domElement;\n\n // Initialize subsystems\n this.history = new History();\n this.selection = new SelectionManager(this);\n this.transform = new TransformManager(this);\n\n // Forward selection events\n this.selection.on(\"selectionChanged\", (object: THREE.Object3D | null) => {\n this.emit(\"selectionChanged\", object);\n this.transform.attach(object);\n });\n\n // Forward transform events\n this.transform.on(\"objectChanged\", (...args: unknown[]) => {\n const object = args[0] as THREE.Object3D;\n const command = args[1] as Command;\n this.history.execute(command);\n this.emit(\"objectChanged\", object);\n });\n\n // Forward history events\n this.history.on(\"historyChanged\", () => {\n this.emit(\"historyChanged\");\n });\n\n // Listen for mode changes\n this.transform.on(\"modeChanged\", (...args: unknown[]) => {\n const mode = args[0] as string;\n this.emit(\"modeChanged\", mode);\n });\n }\n\n /**\n * Set the current model being edited\n */\n setModel(model: THREE.Group | null): void {\n this.currentModel = model;\n this.selection.deselect();\n this.history.clear();\n this.emit(\"modelLoaded\", model);\n }\n\n /**\n * Get the current model\n */\n getModel(): THREE.Group | null {\n return this.currentModel;\n }\n\n /**\n * Get the currently selected object\n */\n getSelected(): THREE.Object3D | null {\n return this.selection.getSelected();\n }\n\n /**\n * Select an object\n */\n select(object: THREE.Object3D | null): void {\n this.selection.select(object);\n }\n\n /**\n * Execute a command (adds to history)\n */\n execute(command: Command): void {\n this.history.execute(command);\n this.emit(\"objectChanged\", this.getSelected());\n }\n\n /**\n * Undo the last command\n */\n undo(): void {\n this.history.undo();\n this.emit(\"objectChanged\", this.getSelected());\n }\n\n /**\n * Redo the last undone command\n */\n redo(): void {\n this.history.redo();\n this.emit(\"objectChanged\", this.getSelected());\n }\n\n /**\n * Check if undo is available\n */\n canUndo(): boolean {\n return this.history.canUndo();\n }\n\n /**\n * Check if redo is available\n */\n canRedo(): boolean {\n return this.history.canRedo();\n }\n\n /**\n * Set transform mode\n */\n setTransformMode(mode: \"translate\" | \"rotate\" | \"scale\"): void {\n this.transform.setMode(mode);\n }\n\n /**\n * Get current transform mode\n */\n getTransformMode(): \"translate\" | \"rotate\" | \"scale\" {\n return this.transform.getMode();\n }\n\n /**\n * Add event listener\n */\n on(event: EditorEvent, callback: EventCallback): void {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, new Set());\n }\n this.eventListeners.get(event)!.add(callback);\n }\n\n /**\n * Remove event listener\n */\n off(event: EditorEvent, callback: EventCallback): void {\n this.eventListeners.get(event)?.delete(callback);\n }\n\n /**\n * Emit an event\n */\n emit(event: EditorEvent, ...args: unknown[]): void {\n this.eventListeners.get(event)?.forEach((callback) => callback(...args));\n }\n\n /**\n * Clean up resources\n */\n dispose(): void {\n this.selection.dispose();\n this.transform.dispose();\n this.eventListeners.clear();\n }\n}\n","import * as THREE from \"three\";\nimport type {\n BlockyModel,\n BlockyNode,\n BlockyShape,\n Vec3,\n Quaternion,\n TextureLayout,\n ShadingMode,\n ShapeType,\n} from \"../types/blockymodel\";\n\n/**\n * Generate a unique ID\n */\nfunction generateId(): string {\n return `node_${Date.now().toString(36)}_${Math.random().toString(36).substring(2, 8)}`;\n}\n\n/**\n * Serializer for exporting Three.js scene to BlockyModel format\n */\nexport class Serializer {\n /**\n * Serialize a Three.js model group to BlockyModel JSON\n */\n serialize(model: THREE.Group): BlockyModel {\n const blockyModel: BlockyModel = {\n format: model.userData.format || \"prop\",\n lod: model.userData.lod || \"auto\",\n nodes: [],\n };\n\n // Serialize root-level children (skip helpers)\n for (const child of model.children) {\n if (this.shouldSerialize(child)) {\n blockyModel.nodes.push(this.serializeNode(child));\n }\n }\n\n return blockyModel;\n }\n\n /**\n * Check if an object should be serialized\n */\n private shouldSerialize(object: THREE.Object3D): boolean {\n // Skip transform controls and other helpers\n if (\n object.type === \"TransformControlsGizmo\" ||\n object.type === \"TransformControlsPlane\" ||\n object.type === \"GridHelper\" ||\n object.type === \"AxesHelper\"\n ) {\n return false;\n }\n return true;\n }\n\n /**\n * Serialize a single node\n */\n private serializeNode(object: THREE.Object3D): BlockyNode {\n const node: BlockyNode = {\n id: object.userData.id || object.name || generateId(),\n name: object.name || \"Unnamed\",\n position: this.serializePosition(object.position),\n orientation: this.serializeQuaternion(object.quaternion),\n shape: this.serializeShape(object),\n children: [],\n };\n\n // Serialize children\n for (const child of object.children) {\n if (this.shouldSerialize(child)) {\n node.children.push(this.serializeNode(child));\n }\n }\n\n return node;\n }\n\n /**\n * Serialize position\n */\n private serializePosition(position: THREE.Vector3): Vec3 {\n return {\n x: parseFloat(position.x.toFixed(4)),\n y: parseFloat(position.y.toFixed(4)),\n z: parseFloat(position.z.toFixed(4)),\n };\n }\n\n /**\n * Serialize quaternion\n */\n private serializeQuaternion(quaternion: THREE.Quaternion): Quaternion {\n return {\n w: parseFloat(quaternion.w.toFixed(6)),\n x: parseFloat(quaternion.x.toFixed(6)),\n y: parseFloat(quaternion.y.toFixed(6)),\n z: parseFloat(quaternion.z.toFixed(6)),\n };\n }\n\n /**\n * Serialize shape\n */\n private serializeShape(object: THREE.Object3D): BlockyShape {\n const shapeType = (object.userData.shapeType || \"none\") as ShapeType;\n\n // Base shape with defaults\n const shape: BlockyShape = {\n type: shapeType,\n offset: object.userData.offset || { x: 0, y: 0, z: 0 },\n stretch: object.userData.stretch || { x: 1, y: 1, z: 1 },\n settings: {\n size: object.userData.originalSize || { x: 1, y: 1, z: 1 },\n isPiece: object.userData.isPiece || false,\n isStaticBox: object.userData.isStaticBox || false,\n },\n textureLayout: object.userData.textureLayout || this.getDefaultTextureLayout(),\n unwrapMode: object.userData.unwrapMode || \"custom\",\n visible: object.visible !== false,\n doubleSided: object.userData.doubleSided || false,\n shadingMode: (object.userData.shadingMode || \"standard\") as ShadingMode,\n };\n\n // For mesh objects, try to extract geometry info\n if (object instanceof THREE.Mesh) {\n const geometry = object.geometry;\n\n // Extract size from BoxGeometry if available\n if (geometry instanceof THREE.BoxGeometry) {\n const params = geometry.parameters;\n if (!object.userData.originalSize) {\n shape.settings.size = {\n x: params.width,\n y: params.height,\n z: params.depth,\n };\n }\n }\n\n // Extract material properties\n const material = object.material as THREE.MeshStandardMaterial;\n if (material) {\n shape.doubleSided = material.side === THREE.DoubleSide;\n\n // Infer shading mode from material properties\n if (material.emissiveIntensity > 0.5) {\n shape.shadingMode = \"fullbright\";\n } else if (material.flatShading) {\n shape.shadingMode = \"flat\";\n } else if (material.metalness > 0.5) {\n shape.shadingMode = \"reflective\";\n }\n }\n }\n\n // For quads, include normal direction\n if (shapeType === \"quad\" && object.userData.normal) {\n shape.settings.normal = object.userData.normal;\n }\n\n return shape;\n }\n\n /**\n * Get default texture layout\n */\n private getDefaultTextureLayout(): TextureLayout {\n const defaultFace = {\n offset: { x: 0, y: 0 },\n mirror: { x: false, y: false },\n angle: 0 as const,\n };\n\n return {\n front: { ...defaultFace },\n back: { ...defaultFace },\n left: { ...defaultFace },\n right: { ...defaultFace },\n top: { ...defaultFace },\n bottom: { ...defaultFace },\n };\n }\n\n /**\n * Export model to JSON string\n */\n toJSON(model: THREE.Group): string {\n const blockyModel = this.serialize(model);\n return JSON.stringify(blockyModel, null, 2);\n }\n\n /**\n * Download model as .blockymodel file\n */\n download(model: THREE.Group, filename: string = \"model.blockymodel\"): void {\n const json = this.toJSON(model);\n const blob = new Blob([json], { type: \"application/json\" });\n const url = URL.createObjectURL(blob);\n\n const link = document.createElement(\"a\");\n link.href = url;\n link.download = filename.endsWith(\".blockymodel\") ? filename : `${filename}.blockymodel`;\n link.click();\n\n URL.revokeObjectURL(url);\n }\n}\n","import * as THREE from \"three\";\nimport { BaseCommand, type Command } from \"./Command\";\n\n/**\n * Command to set a property on an object\n */\nexport class SetPropertyCommand extends BaseCommand {\n readonly type = \"SetProperty\";\n readonly updatable = true;\n\n private propertyPath: string;\n private newValue: unknown;\n private oldValue: unknown;\n\n constructor(\n object: THREE.Object3D,\n propertyPath: string,\n newValue: unknown,\n oldValue: unknown\n ) {\n super(object, true);\n this.propertyPath = propertyPath;\n this.newValue = this.cloneValue(newValue);\n this.oldValue = this.cloneValue(oldValue);\n }\n\n /**\n * Clone a value if it's an object/array\n */\n private cloneValue(value: unknown): unknown {\n if (value === null || value === undefined) return value;\n if (typeof value === \"object\") {\n return JSON.parse(JSON.stringify(value));\n }\n return value;\n }\n\n /**\n * Get a nested property by path (e.g., \"userData.size.x\")\n */\n private getProperty(obj: unknown, path: string): unknown {\n const parts = path.split(\".\");\n let current = obj as Record<string, unknown>;\n for (const part of parts) {\n if (current === null || current === undefined) return undefined;\n current = current[part] as Record<string, unknown>;\n }\n return current;\n }\n\n /**\n * Set a nested property by path\n */\n private setProperty(obj: unknown, path: string, value: unknown): void {\n const parts = path.split(\".\");\n let current = obj as Record<string, unknown>;\n for (let i = 0; i < parts.length - 1; i++) {\n if (current[parts[i]] === undefined) {\n current[parts[i]] = {};\n }\n current = current[parts[i]] as Record<string, unknown>;\n }\n current[parts[parts.length - 1]] = value;\n }\n\n execute(): void {\n this.setProperty(this.object, this.propertyPath, this.cloneValue(this.newValue));\n }\n\n undo(): void {\n this.setProperty(this.object, this.propertyPath, this.cloneValue(this.oldValue));\n }\n\n update(command: Command): void {\n if (command instanceof SetPropertyCommand && command.propertyPath === this.propertyPath) {\n this.newValue = command.newValue;\n }\n }\n\n /**\n * Get the property path\n */\n getPropertyPath(): string {\n return this.propertyPath;\n }\n\n /**\n * Get the new value\n */\n getNewValue(): unknown {\n return this.cloneValue(this.newValue);\n }\n\n /**\n * Get the old value\n */\n getOldValue(): unknown {\n return this.cloneValue(this.oldValue);\n }\n}\n","import * as THREE from \"three\";\nimport { BaseCommand } from \"./Command\";\n\n/**\n * Command to add a child node to a parent\n */\nexport class AddNodeCommand extends BaseCommand {\n readonly type = \"AddNode\";\n readonly updatable = false;\n\n private parent: THREE.Object3D;\n private child: THREE.Object3D;\n private index: number;\n\n constructor(\n parent: THREE.Object3D,\n child: THREE.Object3D,\n index?: number\n ) {\n super(parent, false);\n this.parent = parent;\n this.child = child;\n this.index = index ?? parent.children.length;\n }\n\n execute(): void {\n this.parent.add(this.child);\n // Reorder to correct index if needed\n if (this.index < this.parent.children.length - 1) {\n const children = this.parent.children;\n children.splice(children.indexOf(this.child), 1);\n children.splice(this.index, 0, this.child);\n }\n }\n\n undo(): void {\n this.parent.remove(this.child);\n }\n\n /**\n * Get the added child\n */\n getChild(): THREE.Object3D {\n return this.child;\n }\n\n /**\n * Get the parent\n */\n getParent(): THREE.Object3D {\n return this.parent;\n }\n}\n","import * as THREE from \"three\";\nimport { BaseCommand } from \"./Command\";\n\n/**\n * Command to remove a node from its parent\n */\nexport class RemoveNodeCommand extends BaseCommand {\n readonly type = \"RemoveNode\";\n readonly updatable = false;\n\n private parent: THREE.Object3D;\n private child: THREE.Object3D;\n private index: number;\n\n constructor(child: THREE.Object3D) {\n super(child, false);\n if (!child.parent) {\n throw new Error(\"Cannot remove node without parent\");\n }\n this.parent = child.parent;\n this.child = child;\n this.index = this.parent.children.indexOf(child);\n }\n\n execute(): void {\n this.parent.remove(this.child);\n }\n\n undo(): void {\n this.parent.add(this.child);\n // Restore to original index\n if (this.index < this.parent.children.length) {\n const children = this.parent.children;\n children.splice(children.indexOf(this.child), 1);\n children.splice(this.index, 0, this.child);\n }\n }\n\n /**\n * Get the removed child\n */\n getChild(): THREE.Object3D {\n return this.child;\n }\n\n /**\n * Get the parent\n */\n getParent(): THREE.Object3D {\n return this.parent;\n }\n\n /**\n * Get the original index\n */\n getIndex(): number {\n return this.index;\n }\n}\n","import * as THREE from \"three\";\nimport type { Editor } from \"../editor/Editor\";\nimport { SetPositionCommand } from \"../editor/commands/SetPositionCommand\";\nimport { SetRotationCommand } from \"../editor/commands/SetRotationCommand\";\nimport { SetScaleCommand } from \"../editor/commands/SetScaleCommand\";\nimport { SetPropertyCommand } from \"../editor/commands/SetPropertyCommand\";\nimport type { ShadingMode } from \"../types/blockymodel\";\n\n/**\n * Property panel for editing selected object properties\n */\nexport class PropertyPanel {\n private editor: Editor;\n private container: HTMLElement;\n private currentObject: THREE.Object3D | null = null;\n private isUpdating: boolean = false;\n\n // Input elements\n private nameInput!: HTMLInputElement;\n private posInputs!: { x: HTMLInputElement; y: HTMLInputElement; z: HTMLInputElement };\n private rotInputs!: { x: HTMLInputElement; y: HTMLInputElement; z: HTMLInputElement };\n private scaleInputs!: { x: HTMLInputElement; y: HTMLInputElement; z: HTMLInputElement };\n private sizeInputs!: { x: HTMLInputElement; y: HTMLInputElement; z: HTMLInputElement };\n private offsetInputs!: { x: HTMLInputElement; y: HTMLInputElement; z: HTMLInputElement };\n private visibleCheckbox!: HTMLInputElement;\n private doubleSidedCheckbox!: HTMLInputElement;\n private shadingModeSelect!: HTMLSelectElement;\n private shapeTypeSpan!: HTMLElement;\n\n constructor(editor: Editor, containerId: string) {\n this.editor = editor;\n const container = document.getElementById(containerId);\n if (!container) {\n throw new Error(`Property panel container not found: ${containerId}`);\n }\n this.container = container;\n\n this.buildUI();\n this.setupEventListeners();\n }\n\n /**\n * Build the property panel UI\n */\n private buildUI(): void {\n this.container.innerHTML = `\n <div class=\"property-section\" id=\"properties-transform\">\n <div class=\"section-header\">Transform</div>\n <div class=\"property-row\">\n <label>Name</label>\n <input type=\"text\" id=\"prop-name\" class=\"prop-input prop-text\" />\n </div>\n <div class=\"property-row\">\n <label>Position</label>\n <div class=\"vec3-inputs\">\n <input type=\"number\" id=\"prop-pos-x\" class=\"prop-input\" step=\"0.1\" />\n <input type=\"number\" id=\"prop-pos-y\" class=\"prop-input\" step=\"0.1\" />\n <input type=\"number\" id=\"prop-pos-z\" class=\"prop-input\" step=\"0.1\" />\n </div>\n </div>\n <div class=\"property-row\">\n <label>Rotation</label>\n <div class=\"vec3-inputs\">\n <input type=\"number\" id=\"prop-rot-x\" class=\"prop-input\" step=\"1\" />\n <input type=\"number\" id=\"prop-rot-y\" class=\"prop-input\" step=\"1\" />\n <input type=\"number\" id=\"prop-rot-z\" class=\"prop-input\" step=\"1\" />\n </div>\n </div>\n <div class=\"property-row\">\n <label>Scale</label>\n <div class=\"vec3-inputs\">\n <input type=\"number\" id=\"prop-scale-x\" class=\"prop-input\" step=\"0.1\" min=\"0.01\" />\n <input type=\"number\" id=\"prop-scale-y\" class=\"prop-input\" step=\"0.1\" min=\"0.01\" />\n <input type=\"number\" id=\"prop-scale-z\" class=\"prop-input\" step=\"0.1\" min=\"0.01\" />\n </div>\n </div>\n </div>\n\n <div class=\"property-section\" id=\"properties-shape\">\n <div class=\"section-header\">Shape</div>\n <div class=\"property-row\">\n <label>Type</label>\n <span id=\"prop-shape-type\" class=\"prop-readonly\">-</span>\n </div>\n <div class=\"property-row\">\n <label>Size</label>\n <div class=\"vec3-inputs\">\n <input type=\"number\" id=\"prop-size-x\" class=\"prop-input\" step=\"1\" min=\"0\" />\n <input type=\"number\" id=\"prop-size-y\" class=\"prop-input\" step=\"1\" min=\"0\" />\n <input type=\"number\" id=\"prop-size-z\" class=\"prop-input\" step=\"1\" min=\"0\" />\n </div>\n </div>\n <div class=\"property-row\">\n <label>Offset</label>\n <div class=\"vec3-inputs\">\n <input type=\"number\" id=\"prop-offset-x\" class=\"prop-input\" step=\"0.5\" />\n <input type=\"number\" id=\"prop-offset-y\" class=\"prop-input\" step=\"0.5\" />\n <input type=\"number\" id=\"prop-offset-z\" class=\"prop-input\" step=\"0.5\" />\n </div>\n </div>\n <div class=\"property-row\">\n <label>Visible</label>\n <input type=\"checkbox\" id=\"prop-visible\" class=\"prop-checkbox\" />\n </div>\n <div class=\"property-row\">\n <label>Double Sided</label>\n <input type=\"checkbox\" id=\"prop-doublesided\" class=\"prop-checkbox\" />\n </div>\n <div class=\"property-row\">\n <label>Shading</label>\n <select id=\"prop-shading\" class=\"prop-select\">\n <option value=\"standard\">Standard</option>\n <option value=\"flat\">Flat</option>\n <option value=\"fullbright\">Fullbright</option>\n <option value=\"reflective\">Reflective</option>\n </select>\n </div>\n </div>\n\n <div class=\"property-empty\" id=\"properties-empty\">\n <p>Select an object to view properties</p>\n </div>\n `;\n\n // Cache input references\n this.nameInput = document.getElementById(\"prop-name\") as HTMLInputElement;\n this.posInputs = {\n x: document.getElementById(\"prop-pos-x\") as HTMLInputElement,\n y: document.getElementById(\"prop-pos-y\") as HTMLInputElement,\n z: document.getElementById(\"prop-pos-z\") as HTMLInputElement,\n };\n this.rotInputs = {\n x: document.getElementById(\"prop-rot-x\") as HTMLInputElement,\n y: document.getElementById(\"prop-rot-y\") as HTMLInputElement,\n z: document.getElementById(\"prop-rot-z\") as HTMLInputElement,\n };\n this.scaleInputs = {\n x: document.getElementById(\"prop-scale-x\") as HTMLInputElement,\n y: document.getElementById(\"prop-scale-y\") as HTMLInputElement,\n z: document.getElementById(\"prop-scale-z\") as HTMLInputElement,\n };\n this.sizeInputs = {\n x: document.getElementById(\"prop-size-x\") as HTMLInputElement,\n y: document.getElementById(\"prop-size-y\") as HTMLInputElement,\n z: document.getElementById(\"prop-size-z\") as HTMLInputElement,\n };\n this.offsetInputs = {\n x: document.getElementById(\"prop-offset-x\") as HTMLInputElement,\n y: document.getElementById(\"prop-offset-y\") as HTMLInputElement,\n z: document.getElementById(\"prop-offset-z\") as HTMLInputElement,\n };\n this.visibleCheckbox = document.getElementById(\"prop-visible\") as HTMLInputElement;\n this.doubleSidedCheckbox = document.getElementById(\"prop-doublesided\") as HTMLInputElement;\n this.shadingModeSelect = document.getElementById(\"prop-shading\") as HTMLSelectElement;\n this.shapeTypeSpan = document.getElementById(\"prop-shape-type\") as HTMLElement;\n\n // Initially hide property sections\n this.showEmpty();\n }\n\n /**\n * Setup event listeners\n */\n private setupEventListeners(): void {\n // Editor events\n this.editor.on(\"selectionChanged\", (object) => {\n this.setObject(object as THREE.Object3D | null);\n });\n\n this.editor.on(\"objectChanged\", () => {\n if (this.currentObject) {\n this.updateFromObject();\n }\n });\n\n // Listen for live transform updates\n this.editor.transform.on(\"objectChanging\", () => {\n if (this.currentObject) {\n this.updateFromObject();\n }\n });\n\n // Name input\n this.nameInput.addEventListener(\"change\", () => {\n if (this.currentObject && !this.isUpdating) {\n const oldName = this.currentObject.name;\n const newName = this.nameInput.value;\n this.editor.execute(new SetPropertyCommand(this.currentObject, \"name\", newName, oldName));\n }\n });\n\n // Position inputs\n this.setupVec3Input(this.posInputs, (value) => {\n if (this.currentObject && !this.isUpdating) {\n const oldPos = this.currentObject.position.clone();\n this.editor.execute(new SetPositionCommand(this.currentObject, value, oldPos));\n }\n });\n\n // Rotation inputs (degrees to radians)\n this.setupVec3Input(this.rotInputs, (value) => {\n if (this.currentObject && !this.isUpdating) {\n const oldRot = this.currentObject.rotation.clone();\n const newRot = new THREE.Euler(\n THREE.MathUtils.degToRad(value.x),\n THREE.MathUtils.degToRad(value.y),\n THREE.MathUtils.degToRad(value.z)\n );\n this.editor.execute(new SetRotationCommand(this.currentObject, newRot, oldRot));\n }\n });\n\n // Scale inputs\n this.setupVec3Input(this.scaleInputs, (value) => {\n if (this.currentObject && !this.isUpdating) {\n const oldScale = this.currentObject.scale.clone();\n this.editor.execute(new SetScaleCommand(this.currentObject, value, oldScale));\n }\n });\n\n // Size inputs\n this.setupVec3Input(this.sizeInputs, (value) => {\n if (this.currentObject && !this.isUpdating) {\n const oldSize = this.currentObject.userData.originalSize || { x: 1, y: 1, z: 1 };\n this.editor.execute(\n new SetPropertyCommand(this.currentObject, \"userData.originalSize\", { x: value.x, y: value.y, z: value.z }, oldSize)\n );\n this.rebuildGeometry();\n }\n });\n\n // Offset inputs\n this.setupVec3Input(this.offsetInputs, (value) => {\n if (this.currentObject && !this.isUpdating) {\n const oldOffset = this.currentObject.userData.offset || { x: 0, y: 0, z: 0 };\n this.editor.execute(\n new SetPropertyCommand(this.currentObject, \"userData.offset\", { x: value.x, y: value.y, z: value.z }, oldOffset)\n );\n this.rebuildGeometry();\n }\n });\n\n // Visible checkbox\n this.visibleCheckbox.addEventListener(\"change\", () => {\n if (this.currentObject && !this.isUpdating) {\n const oldValue = this.currentObject.visible;\n const newValue = this.visibleCheckbox.checked;\n this.editor.execute(new SetPropertyCommand(this.currentObject, \"visible\", newValue, oldValue));\n }\n });\n\n // Double sided checkbox\n this.doubleSidedCheckbox.addEventListener(\"change\", () => {\n if (this.currentObject && !this.isUpdating && this.currentObject instanceof THREE.Mesh) {\n const material = this.currentObject.material as THREE.MeshStandardMaterial;\n const oldValue = material.side === THREE.DoubleSide;\n const newValue = this.doubleSidedCheckbox.checked;\n material.side = newValue ? THREE.DoubleSide : THREE.FrontSide;\n this.currentObject.userData.doubleSided = newValue;\n this.editor.execute(\n new SetPropertyCommand(this.currentObject, \"userData.doubleSided\", newValue, oldValue)\n );\n }\n });\n\n // Shading mode select\n this.shadingModeSelect.addEventListener(\"change\", () => {\n if (this.currentObject && !this.isUpdating) {\n const oldValue = this.currentObject.userData.shadingMode || \"standard\";\n const newValue = this.shadingModeSelect.value as ShadingMode;\n this.currentObject.userData.shadingMode = newValue;\n this.editor.execute(\n new SetPropertyCommand(this.currentObject, \"userData.shadingMode\", newValue, oldValue)\n );\n }\n });\n }\n\n /**\n * Setup Vec3 input handlers\n */\n private setupVec3Input(\n inputs: { x: HTMLInputElement; y: HTMLInputElement; z: HTMLInputElement },\n onChange: (value: THREE.Vector3) => void\n ): void {\n const handler = () => {\n const value = new THREE.Vector3(\n parseFloat(inputs.x.value) || 0,\n parseFloat(inputs.y.value) || 0,\n parseFloat(inputs.z.value) || 0\n );\n onChange(value);\n };\n\n inputs.x.addEventListener(\"change\", handler);\n inputs.y.addEventListener(\"change\", handler);\n inputs.z.addEventListener(\"change\", handler);\n }\n\n /**\n * Set the object to display properties for\n */\n setObject(object: THREE.Object3D | null): void {\n this.currentObject = object;\n\n if (object) {\n this.showProperties();\n this.updateFromObject();\n } else {\n this.showEmpty();\n }\n }\n\n /**\n * Update UI from current object\n */\n private updateFromObject(): void {\n if (!this.currentObject) return;\n\n this.isUpdating = true;\n\n const obj = this.currentObject;\n\n // Name\n this.nameInput.value = obj.name || \"\";\n\n // Position\n this.posInputs.x.value = obj.position.x.toFixed(2);\n this.posInputs.y.value = obj.position.y.toFixed(2);\n this.posInputs.z.value = obj.position.z.toFixed(2);\n\n // Rotation (radians to degrees)\n this.rotInputs.x.value = THREE.MathUtils.radToDeg(obj.rotation.x).toFixed(1);\n this.rotInputs.y.value = THREE.MathUtils.radToDeg(obj.rotation.y).toFixed(1);\n this.rotInputs.z.value = THREE.MathUtils.radToDeg(obj.rotation.z).toFixed(1);\n\n // Scale\n this.scaleInputs.x.value = obj.scale.x.toFixed(2);\n this.scaleInputs.y.value = obj.scale.y.toFixed(2);\n this.scaleInputs.z.value = obj.scale.z.toFixed(2);\n\n // Shape properties\n const shapeType = obj.userData.shapeType || \"none\";\n this.shapeTypeSpan.textContent = shapeType;\n\n // Size\n const size = obj.userData.originalSize || { x: 1, y: 1, z: 1 };\n this.sizeInputs.x.value = size.x?.toString() || \"1\";\n this.sizeInputs.y.value = size.y?.toString() || \"1\";\n this.sizeInputs.z.value = size.z?.toString() || \"1\";\n\n // Offset\n const offset = obj.userData.offset || { x: 0, y: 0, z: 0 };\n this.offsetInputs.x.value = offset.x?.toString() || \"0\";\n this.offsetInputs.y.value = offset.y?.toString() || \"0\";\n this.offsetInputs.z.value = offset.z?.toString() || \"0\";\n\n // Visible\n this.visibleCheckbox.checked = obj.visible;\n\n // Double sided\n if (obj instanceof THREE.Mesh) {\n const material = obj.material as THREE.MeshStandardMaterial;\n this.doubleSidedCheckbox.checked = material.side === THREE.DoubleSide;\n } else {\n this.doubleSidedCheckbox.checked = false;\n }\n\n // Shading mode\n this.shadingModeSelect.value = obj.userData.shadingMode || \"standard\";\n\n this.isUpdating = false;\n }\n\n /**\n * Rebuild geometry after size/offset changes\n */\n private rebuildGeometry(): void {\n if (!this.currentObject || !(this.currentObject instanceof THREE.Mesh)) return;\n\n const mesh = this.currentObject;\n const size = mesh.userData.originalSize || { x: 1, y: 1, z: 1 };\n const offset = mesh.userData.offset || { x: 0, y: 0, z: 0 };\n const stretch = mesh.userData.stretch || { x: 1, y: 1, z: 1 };\n\n const finalSize = {\n x: size.x * stretch.x,\n y: size.y * stretch.y,\n z: size.z * stretch.z,\n };\n\n // Dispose old geometry\n mesh.geometry.dispose();\n\n // Create new geometry based on shape type\n if (mesh.userData.shapeType === \"box\") {\n mesh.geometry = new THREE.BoxGeometry(finalSize.x, finalSize.y, finalSize.z);\n mesh.geometry.translate(offset.x, offset.y, offset.z);\n }\n }\n\n /**\n * Show property sections\n */\n private showProperties(): void {\n const transform = document.getElementById(\"properties-transform\");\n const shape = document.getElementById(\"properties-shape\");\n const empty = document.getElementById(\"properties-empty\");\n\n if (transform) transform.style.display = \"block\";\n if (shape) shape.style.display = \"block\";\n if (empty) empty.style.display = \"none\";\n }\n\n /**\n * Show empty state\n */\n private showEmpty(): void {\n const transform = document.getElementById(\"properties-transform\");\n const shape = document.getElementById(\"properties-shape\");\n const empty = document.getElementById(\"properties-empty\");\n\n if (transform) transform.style.display = \"none\";\n if (shape) shape.style.display = \"none\";\n if (empty) empty.style.display = \"block\";\n }\n\n /**\n * Cleanup\n */\n dispose(): void {\n this.container.innerHTML = \"\";\n }\n}\n","import * as THREE from \"three\";\nimport type { Editor } from \"../editor/Editor\";\nimport { AddNodeCommand } from \"../editor/commands/AddNodeCommand\";\nimport { RemoveNodeCommand } from \"../editor/commands/RemoveNodeCommand\";\n\n/**\n * Hierarchy panel showing the model tree structure\n */\nexport class HierarchyPanel {\n private editor: Editor;\n private container: HTMLElement;\n private treeContainer!: HTMLElement;\n private contextMenu: HTMLElement | null = null;\n private contextTarget: THREE.Object3D | null = null;\n\n constructor(editor: Editor, containerId: string) {\n this.editor = editor;\n const container = document.getElementById(containerId);\n if (!container) {\n throw new Error(`Hierarchy panel container not found: ${containerId}`);\n }\n this.container = container;\n\n this.buildUI();\n this.setupEventListeners();\n }\n\n /**\n * Build the hierarchy panel UI\n */\n private buildUI(): void {\n this.container.innerHTML = `\n <div class=\"hierarchy-tree\" id=\"hierarchy-tree\"></div>\n `;\n\n this.treeContainer = document.getElementById(\"hierarchy-tree\") as HTMLElement;\n\n // Create context menu (hidden by default)\n this.contextMenu = document.createElement(\"div\");\n this.contextMenu.className = \"context-menu\";\n this.contextMenu.innerHTML = `\n <div class=\"context-menu-item\" data-action=\"add-box\">Add Child Box</div>\n <div class=\"context-menu-item\" data-action=\"add-group\">Add Child Group</div>\n <div class=\"context-menu-separator\"></div>\n <div class=\"context-menu-item\" data-action=\"duplicate\">Duplicate</div>\n <div class=\"context-menu-separator\"></div>\n <div class=\"context-menu-item context-menu-danger\" data-action=\"delete\">Delete</div>\n `;\n this.contextMenu.style.display = \"none\";\n document.body.appendChild(this.contextMenu);\n }\n\n /**\n * Setup event listeners\n */\n private setupEventListeners(): void {\n // Editor events\n this.editor.on(\"modelLoaded\", () => {\n this.refresh();\n });\n\n this.editor.on(\"selectionChanged\", () => {\n this.updateSelection();\n });\n\n this.editor.on(\"objectChanged\", () => {\n this.refresh();\n });\n\n // Context menu handlers\n this.contextMenu?.addEventListener(\"click\", (e) => {\n const target = e.target as HTMLElement;\n const action = target.dataset.action;\n if (action && this.contextTarget) {\n this.handleContextAction(action, this.contextTarget);\n }\n this.hideContextMenu();\n });\n\n // Hide context menu on click outside\n document.addEventListener(\"click\", (e) => {\n if (this.contextMenu && !this.contextMenu.contains(e.target as Node)) {\n this.hideContextMenu();\n }\n });\n\n // Keyboard shortcuts\n document.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Delete\" || e.key === \"Backspace\") {\n const selected = this.editor.getSelected();\n if (selected && selected.parent && !(e.target instanceof HTMLInputElement)) {\n this.deleteNode(selected);\n }\n }\n });\n }\n\n /**\n * Refresh the hierarchy tree\n */\n refresh(): void {\n const model = this.editor.getModel();\n if (!model) {\n this.treeContainer.innerHTML = `<p class=\"hierarchy-empty\">No model loaded</p>`;\n return;\n }\n\n this.treeContainer.innerHTML = \"\";\n this.buildTree(model, this.treeContainer, 0);\n }\n\n /**\n * Build tree recursively\n */\n private buildTree(object: THREE.Object3D, parent: HTMLElement, depth: number): void {\n const item = document.createElement(\"div\");\n item.className = \"hierarchy-item\";\n item.dataset.objectId = object.uuid;\n\n const indent = document.createElement(\"span\");\n indent.className = \"hierarchy-indent\";\n indent.style.width = `${depth * 16}px`;\n\n const expander = document.createElement(\"span\");\n expander.className = \"hierarchy-expander\";\n if (object.children.length > 0) {\n expander.textContent = \"▼\";\n expander.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.toggleExpand(item);\n });\n }\n\n const icon = document.createElement(\"span\");\n icon.className = \"hierarchy-icon\";\n icon.textContent = this.getIcon(object);\n\n const label = document.createElement(\"span\");\n label.className = \"hierarchy-label\";\n label.textContent = object.name || `(${object.type})`;\n\n item.appendChild(indent);\n item.appendChild(expander);\n item.appendChild(icon);\n item.appendChild(label);\n\n // Click to select\n item.addEventListener(\"click\", () => {\n this.editor.select(object);\n });\n\n // Right-click for context menu\n item.addEventListener(\"contextmenu\", (e) => {\n e.preventDefault();\n this.showContextMenu(e, object);\n });\n\n parent.appendChild(item);\n\n // Children container\n if (object.children.length > 0) {\n const children = document.createElement(\"div\");\n children.className = \"hierarchy-children\";\n for (const child of object.children) {\n // Skip helper objects\n if (child.type === \"TransformControlsGizmo\" || child.type === \"TransformControlsPlane\") {\n continue;\n }\n this.buildTree(child, children, depth + 1);\n }\n parent.appendChild(children);\n }\n }\n\n /**\n * Get icon for object type\n */\n private getIcon(object: THREE.Object3D): string {\n if (object instanceof THREE.Mesh) {\n const shapeType = object.userData.shapeType;\n if (shapeType === \"box\") return \"📦\";\n if (shapeType === \"quad\") return \"▫️\";\n return \"🔷\";\n }\n if (object instanceof THREE.Group) return \"📁\";\n return \"◯\";\n }\n\n /**\n * Toggle expand/collapse\n */\n private toggleExpand(item: HTMLElement): void {\n const children = item.nextElementSibling;\n if (children?.classList.contains(\"hierarchy-children\")) {\n const isCollapsed = children.classList.toggle(\"collapsed\");\n const expander = item.querySelector(\".hierarchy-expander\");\n if (expander) {\n expander.textContent = isCollapsed ? \"▶\" : \"▼\";\n }\n }\n }\n\n /**\n * Update selection highlight\n */\n private updateSelection(): void {\n // Remove all selection highlights\n this.treeContainer.querySelectorAll(\".hierarchy-item.selected\").forEach((el) => {\n el.classList.remove(\"selected\");\n });\n\n // Highlight selected object\n const selected = this.editor.getSelected();\n if (selected) {\n const item = this.treeContainer.querySelector(`[data-object-id=\"${selected.uuid}\"]`);\n if (item) {\n item.classList.add(\"selected\");\n // Scroll into view\n item.scrollIntoView({ behavior: \"smooth\", block: \"nearest\" });\n }\n }\n }\n\n /**\n * Show context menu\n */\n private showContextMenu(event: MouseEvent, object: THREE.Object3D): void {\n if (!this.contextMenu) return;\n\n this.contextTarget = object;\n this.contextMenu.style.display = \"block\";\n this.contextMenu.style.left = `${event.clientX}px`;\n this.contextMenu.style.top = `${event.clientY}px`;\n\n // Ensure menu stays within viewport\n const rect = this.contextMenu.getBoundingClientRect();\n if (rect.right > window.innerWidth) {\n this.contextMenu.style.left = `${window.innerWidth - rect.width - 10}px`;\n }\n if (rect.bottom > window.innerHeight) {\n this.contextMenu.style.top = `${window.innerHeight - rect.height - 10}px`;\n }\n }\n\n /**\n * Hide context menu\n */\n private hideContextMenu(): void {\n if (this.contextMenu) {\n this.contextMenu.style.display = \"none\";\n }\n this.contextTarget = null;\n }\n\n /**\n * Handle context menu action\n */\n private handleContextAction(action: string, target: THREE.Object3D): void {\n switch (action) {\n case \"add-box\":\n this.addChildBox(target);\n break;\n case \"add-group\":\n this.addChildGroup(target);\n break;\n case \"duplicate\":\n this.duplicateNode(target);\n break;\n case \"delete\":\n this.deleteNode(target);\n break;\n }\n }\n\n /**\n * Add a child box\n */\n private addChildBox(parent: THREE.Object3D): void {\n const geometry = new THREE.BoxGeometry(10, 10, 10);\n const material = new THREE.MeshStandardMaterial({ color: 0x888888, roughness: 0.7 });\n const mesh = new THREE.Mesh(geometry, material);\n\n mesh.name = `Box_${Date.now().toString(36)}`;\n mesh.userData.id = mesh.name;\n mesh.userData.shapeType = \"box\";\n mesh.userData.originalSize = { x: 10, y: 10, z: 10 };\n\n this.editor.execute(new AddNodeCommand(parent, mesh));\n this.editor.select(mesh);\n }\n\n /**\n * Add a child group\n */\n private addChildGroup(parent: THREE.Object3D): void {\n const group = new THREE.Group();\n group.name = `Group_${Date.now().toString(36)}`;\n group.userData.id = group.name;\n group.userData.shapeType = \"none\";\n\n this.editor.execute(new AddNodeCommand(parent, group));\n this.editor.select(group);\n }\n\n /**\n * Duplicate a node\n */\n private duplicateNode(node: THREE.Object3D): void {\n if (!node.parent) return;\n\n const clone = node.clone(true);\n clone.name = `${node.name}_copy`;\n clone.userData.id = clone.name;\n clone.position.x += 10; // Offset to make it visible\n\n this.editor.execute(new AddNodeCommand(node.parent, clone));\n this.editor.select(clone);\n }\n\n /**\n * Delete a node\n */\n private deleteNode(node: THREE.Object3D): void {\n if (!node.parent) return;\n\n // Don't delete root model\n const model = this.editor.getModel();\n if (node === model) return;\n\n this.editor.execute(new RemoveNodeCommand(node));\n this.editor.select(null);\n }\n\n /**\n * Cleanup\n */\n dispose(): void {\n if (this.contextMenu) {\n document.body.removeChild(this.contextMenu);\n }\n this.container.innerHTML = \"\";\n }\n}\n","import * as THREE from \"three\";\nimport type { Editor } from \"../editor/Editor\";\nimport { SetPropertyCommand } from \"../editor/commands/SetPropertyCommand\";\nimport type { FaceUV, TextureLayout } from \"../types/blockymodel\";\n\ntype FaceName = \"front\" | \"back\" | \"left\" | \"right\" | \"top\" | \"bottom\";\n\nconst FACE_NAMES: FaceName[] = [\"front\", \"back\", \"left\", \"right\", \"top\", \"bottom\"];\nconst FACE_LABELS: Record<FaceName, string> = {\n front: \"Front (+Z)\",\n back: \"Back (-Z)\",\n left: \"Left (-X)\",\n right: \"Right (+X)\",\n top: \"Top (+Y)\",\n bottom: \"Bottom (-Y)\",\n};\n\nconst DEFAULT_FACE_UV: FaceUV = {\n offset: { x: 0, y: 0 },\n mirror: { x: false, y: false },\n angle: 0,\n};\n\n/**\n * UV Editor panel for per-face texture UV editing\n */\nexport class UVEditor {\n private editor: Editor;\n private container: HTMLElement;\n private currentObject: THREE.Object3D | null = null;\n private isUpdating: boolean = false;\n private faceInputs: Map<FaceName, {\n offsetX: HTMLInputElement;\n offsetY: HTMLInputElement;\n mirrorX: HTMLInputElement;\n mirrorY: HTMLInputElement;\n angle: HTMLSelectElement;\n }> = new Map();\n\n constructor(editor: Editor, containerId: string) {\n this.editor = editor;\n const container = document.getElementById(containerId);\n if (!container) {\n throw new Error(`UV Editor container not found: ${containerId}`);\n }\n this.container = container;\n\n this.buildUI();\n this.setupEventListeners();\n }\n\n /**\n * Build the UV editor UI\n */\n private buildUI(): void {\n let facesHtml = \"\";\n\n for (const face of FACE_NAMES) {\n facesHtml += `\n <div class=\"uv-face\">\n <div class=\"uv-face-header\">${FACE_LABELS[face]}</div>\n <div class=\"uv-face-row\">\n <label>Offset</label>\n <input type=\"number\" id=\"uv-${face}-offset-x\" class=\"uv-input\" step=\"1\" placeholder=\"X\" />\n <input type=\"number\" id=\"uv-${face}-offset-y\" class=\"uv-input\" step=\"1\" placeholder=\"Y\" />\n </div>\n <div class=\"uv-face-row\">\n <label>Mirror</label>\n <label class=\"uv-checkbox-label\">\n <input type=\"checkbox\" id=\"uv-${face}-mirror-x\" class=\"uv-checkbox\" /> X\n </label>\n <label class=\"uv-checkbox-label\">\n <input type=\"checkbox\" id=\"uv-${face}-mirror-y\" class=\"uv-checkbox\" /> Y\n </label>\n </div>\n <div class=\"uv-face-row\">\n <label>Rotation</label>\n <select id=\"uv-${face}-angle\" class=\"uv-select\">\n <option value=\"0\">0°</option>\n <option value=\"90\">90°</option>\n <option value=\"180\">180°</option>\n <option value=\"270\">270°</option>\n </select>\n </div>\n </div>\n `;\n }\n\n this.container.innerHTML = `\n <div class=\"uv-editor-content\" id=\"uv-editor-content\">\n ${facesHtml}\n </div>\n <div class=\"uv-editor-empty\" id=\"uv-editor-empty\">\n <p>Select a box to edit UVs</p>\n </div>\n `;\n\n // Cache input references\n for (const face of FACE_NAMES) {\n this.faceInputs.set(face, {\n offsetX: document.getElementById(`uv-${face}-offset-x`) as HTMLInputElement,\n offsetY: document.getElementById(`uv-${face}-offset-y`) as HTMLInputElement,\n mirrorX: document.getElementById(`uv-${face}-mirror-x`) as HTMLInputElement,\n mirrorY: document.getElementById(`uv-${face}-mirror-y`) as HTMLInputElement,\n angle: document.getElementById(`uv-${face}-angle`) as HTMLSelectElement,\n });\n }\n\n // Initially show empty state\n this.showEmpty();\n }\n\n /**\n * Setup event listeners\n */\n private setupEventListeners(): void {\n // Editor events\n this.editor.on(\"selectionChanged\", (object) => {\n this.setObject(object as THREE.Object3D | null);\n });\n\n this.editor.on(\"objectChanged\", () => {\n if (this.currentObject) {\n this.updateFromObject();\n }\n });\n\n // Setup input handlers for each face\n for (const face of FACE_NAMES) {\n const inputs = this.faceInputs.get(face)!;\n\n // Offset X\n inputs.offsetX.addEventListener(\"change\", () => {\n this.handleFaceChange(face);\n });\n\n // Offset Y\n inputs.offsetY.addEventListener(\"change\", () => {\n this.handleFaceChange(face);\n });\n\n // Mirror X\n inputs.mirrorX.addEventListener(\"change\", () => {\n this.handleFaceChange(face);\n });\n\n // Mirror Y\n inputs.mirrorY.addEventListener(\"change\", () => {\n this.handleFaceChange(face);\n });\n\n // Angle\n inputs.angle.addEventListener(\"change\", () => {\n this.handleFaceChange(face);\n });\n }\n }\n\n /**\n * Handle face UV change\n */\n private handleFaceChange(face: FaceName): void {\n if (!this.currentObject || this.isUpdating) return;\n\n const inputs = this.faceInputs.get(face)!;\n const textureLayout = this.getTextureLayout();\n const oldFaceUV = textureLayout[face] || { ...DEFAULT_FACE_UV };\n\n const newFaceUV: FaceUV = {\n offset: {\n x: parseInt(inputs.offsetX.value) || 0,\n y: parseInt(inputs.offsetY.value) || 0,\n },\n mirror: {\n x: inputs.mirrorX.checked,\n y: inputs.mirrorY.checked,\n },\n angle: parseInt(inputs.angle.value) as 0 | 90 | 180 | 270,\n };\n\n const newTextureLayout = { ...textureLayout, [face]: newFaceUV };\n\n this.editor.execute(\n new SetPropertyCommand(\n this.currentObject,\n \"userData.textureLayout\",\n newTextureLayout,\n textureLayout\n )\n );\n\n // Apply UV changes to the geometry\n this.applyTextureLayout(newTextureLayout);\n }\n\n /**\n * Get texture layout from current object\n */\n private getTextureLayout(): TextureLayout {\n return this.currentObject?.userData.textureLayout || {};\n }\n\n /**\n * Set the object to edit UVs for\n */\n setObject(object: THREE.Object3D | null): void {\n // Only show UV editor for box meshes\n if (object && object instanceof THREE.Mesh && object.userData.shapeType === \"box\") {\n this.currentObject = object;\n this.showContent();\n this.updateFromObject();\n } else {\n this.currentObject = null;\n this.showEmpty();\n }\n }\n\n /**\n * Update UI from current object\n */\n private updateFromObject(): void {\n if (!this.currentObject) return;\n\n this.isUpdating = true;\n\n const textureLayout = this.getTextureLayout();\n\n for (const face of FACE_NAMES) {\n const inputs = this.faceInputs.get(face)!;\n const faceUV = textureLayout[face] || DEFAULT_FACE_UV;\n\n inputs.offsetX.value = faceUV.offset?.x?.toString() || \"0\";\n inputs.offsetY.value = faceUV.offset?.y?.toString() || \"0\";\n inputs.mirrorX.checked = faceUV.mirror?.x || false;\n inputs.mirrorY.checked = faceUV.mirror?.y || false;\n inputs.angle.value = faceUV.angle?.toString() || \"0\";\n }\n\n this.isUpdating = false;\n }\n\n /**\n * Apply texture layout to geometry UVs\n * Note: This is a simplified implementation - full UV mapping would require\n * knowing the texture atlas dimensions\n */\n private applyTextureLayout(layout: TextureLayout): void {\n if (!this.currentObject || !(this.currentObject instanceof THREE.Mesh)) return;\n\n const mesh = this.currentObject;\n const geometry = mesh.geometry as THREE.BufferGeometry;\n const uvAttribute = geometry.getAttribute(\"uv\");\n\n if (!uvAttribute) return;\n\n // BoxGeometry has 6 faces, 2 triangles each, 3 vertices each = 36 vertices\n // Face order: +x, -x, +y, -y, +z, -z\n // For each face: 6 vertices (2 triangles)\n const faceIndexMap: Record<FaceName, number> = {\n right: 0,\n left: 1,\n top: 2,\n bottom: 3,\n front: 4,\n back: 5,\n };\n\n const uvs = uvAttribute.array as Float32Array;\n\n for (const face of FACE_NAMES) {\n const faceUV = layout[face] || DEFAULT_FACE_UV;\n const faceIndex = faceIndexMap[face];\n const startVertex = faceIndex * 6;\n\n // Offset (in texture units, normalized to 0-1 assuming 64px texture)\n const offsetX = (faceUV.offset?.x || 0) / 64;\n const offsetY = (faceUV.offset?.y || 0) / 64;\n\n // Apply offset to each vertex's UV\n for (let i = 0; i < 6; i++) {\n const idx = (startVertex + i) * 2;\n let u = uvs[idx];\n let v = uvs[idx + 1];\n\n // Mirror\n if (faceUV.mirror?.x) u = 1 - u;\n if (faceUV.mirror?.y) v = 1 - v;\n\n // Rotation around center\n if (faceUV.angle) {\n const rad = (faceUV.angle * Math.PI) / 180;\n const cu = u - 0.5;\n const cv = v - 0.5;\n u = cu * Math.cos(rad) - cv * Math.sin(rad) + 0.5;\n v = cu * Math.sin(rad) + cv * Math.cos(rad) + 0.5;\n }\n\n // Apply offset\n uvs[idx] = u + offsetX;\n uvs[idx + 1] = v + offsetY;\n }\n }\n\n uvAttribute.needsUpdate = true;\n }\n\n /**\n * Show content\n */\n private showContent(): void {\n const content = document.getElementById(\"uv-editor-content\");\n const empty = document.getElementById(\"uv-editor-empty\");\n\n if (content) content.style.display = \"block\";\n if (empty) empty.style.display = \"none\";\n }\n\n /**\n * Show empty state\n */\n private showEmpty(): void {\n const content = document.getElementById(\"uv-editor-content\");\n const empty = document.getElementById(\"uv-editor-empty\");\n\n if (content) content.style.display = \"none\";\n if (empty) empty.style.display = \"block\";\n }\n\n /**\n * Cleanup\n */\n dispose(): void {\n this.container.innerHTML = \"\";\n this.faceInputs.clear();\n }\n}\n","/**\n * BlockyModel format type definitions\n * Based on Hytale's native 3D model format\n */\n\nexport interface Vec3 {\n x: number;\n y: number;\n z: number;\n}\n\nexport interface Vec2 {\n x: number;\n y: number;\n}\n\nexport interface Quaternion {\n w: number;\n x: number;\n y: number;\n z: number;\n}\n\nexport interface FaceUV {\n offset: Vec2;\n mirror: { x: boolean; y: boolean };\n angle: 0 | 90 | 180 | 270;\n}\n\nexport interface TextureLayout {\n front?: FaceUV;\n back?: FaceUV;\n left?: FaceUV;\n right?: FaceUV;\n top?: FaceUV;\n bottom?: FaceUV;\n}\n\nexport type ShapeType = \"box\" | \"quad\" | \"none\";\n\nexport type ShadingMode = \"standard\" | \"flat\" | \"fullbright\" | \"reflective\";\n\nexport type NormalDirection = \"+X\" | \"-X\" | \"+Y\" | \"-Y\" | \"+Z\" | \"-Z\";\n\nexport interface ShapeSettings {\n size?: Vec3;\n normal?: NormalDirection;\n isPiece?: boolean;\n isStaticBox?: boolean;\n}\n\nexport interface BlockyShape {\n type: ShapeType;\n offset: Vec3;\n stretch: Vec3;\n settings: ShapeSettings;\n textureLayout: TextureLayout;\n unwrapMode: \"custom\" | \"auto\";\n visible: boolean;\n doubleSided: boolean;\n shadingMode: ShadingMode;\n}\n\nexport interface BlockyNode {\n id: string;\n name: string;\n position?: Vec3;\n orientation?: Quaternion;\n shape: BlockyShape;\n children: BlockyNode[];\n}\n\nexport interface BlockyModel {\n lod?: \"auto\" | string;\n format?: \"character\" | \"prop\";\n nodes: BlockyNode[];\n}\n\n// Default values for optional fields\nexport const DEFAULT_POSITION: Vec3 = { x: 0, y: 0, z: 0 };\nexport const DEFAULT_ORIENTATION: Quaternion = { w: 1, x: 0, y: 0, z: 0 };\nexport const DEFAULT_STRETCH: Vec3 = { x: 1, y: 1, z: 1 };\n","import * as THREE from \"three\";\nimport type {\n BlockyModel,\n BlockyNode,\n BlockyShape,\n Vec3,\n} from \"../types/blockymodel\";\nimport {\n DEFAULT_POSITION,\n DEFAULT_ORIENTATION,\n DEFAULT_STRETCH,\n} from \"../types/blockymodel\";\n\n/**\n * Loader for .blockymodel files\n * Parses JSON and builds Three.js Object3D hierarchy\n */\nexport class BlockyModelLoader extends THREE.Loader {\n constructor(manager?: THREE.LoadingManager) {\n super(manager);\n }\n\n /**\n * Load a .blockymodel file from URL\n */\n async load(url: string): Promise<THREE.Group> {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to load model: ${response.statusText}`);\n }\n const json = await response.json();\n return this.parse(json);\n }\n\n /**\n * Load from File object (for drag-drop / file input)\n */\n async loadFromFile(file: File): Promise<THREE.Group> {\n const text = await file.text();\n const json = JSON.parse(text);\n return this.parse(json);\n }\n\n /**\n * Parse BlockyModel JSON into Three.js scene graph\n */\n parse(json: BlockyModel): THREE.Group {\n const root = new THREE.Group();\n root.name = \"BlockyModel\";\n root.userData.format = json.format;\n root.userData.lod = json.lod;\n\n for (const node of json.nodes) {\n const object = this.parseNode(node);\n root.add(object);\n }\n\n return root;\n }\n\n /**\n * Recursively parse a BlockyNode into Three.js Object3D\n */\n private parseNode(node: BlockyNode): THREE.Object3D {\n const object = this.createNodeObject(node);\n\n // Set name and metadata\n object.name = node.name;\n object.userData.id = node.id;\n object.userData.isPiece = node.shape?.settings?.isPiece ?? false;\n\n // Apply position\n const pos = node.position ?? DEFAULT_POSITION;\n object.position.set(pos.x, pos.y, pos.z);\n\n // Apply orientation (quaternion)\n const orient = node.orientation ?? DEFAULT_ORIENTATION;\n object.quaternion.set(orient.x, orient.y, orient.z, orient.w);\n\n // Recursively add children\n for (const child of node.children ?? []) {\n const childObject = this.parseNode(child);\n object.add(childObject);\n }\n\n return object;\n }\n\n /**\n * Create the appropriate Object3D based on shape type\n */\n private createNodeObject(node: BlockyNode): THREE.Object3D {\n const shape = node.shape;\n\n // No shape or invisible - return empty group\n if (!shape || shape.type === \"none\" || !shape.visible) {\n const group = new THREE.Group();\n group.userData.shapeType = shape?.type ?? \"none\";\n return group;\n }\n\n if (shape.type === \"box\") {\n return this.createBox(shape);\n }\n\n if (shape.type === \"quad\") {\n return this.createQuad(shape);\n }\n\n // Fallback to empty group for unknown types\n return new THREE.Group();\n }\n\n /**\n * Create a box mesh from shape data\n */\n private createBox(shape: BlockyShape): THREE.Mesh {\n const size = shape.settings.size ?? { x: 1, y: 1, z: 1 };\n const stretch = shape.stretch ?? DEFAULT_STRETCH;\n const offset = shape.offset ?? DEFAULT_POSITION;\n\n // Apply stretch to size\n const finalSize: Vec3 = {\n x: size.x * stretch.x,\n y: size.y * stretch.y,\n z: size.z * stretch.z,\n };\n\n // Create geometry\n const geometry = new THREE.BoxGeometry(finalSize.x, finalSize.y, finalSize.z);\n\n // Apply offset by translating geometry vertices\n geometry.translate(offset.x, offset.y, offset.z);\n\n // Create material based on shading mode\n const material = this.createMaterial(shape);\n\n const mesh = new THREE.Mesh(geometry, material);\n mesh.userData.shapeType = \"box\";\n mesh.userData.originalSize = size;\n mesh.userData.shadingMode = shape.shadingMode;\n\n // Handle double-sided\n if (shape.doubleSided) {\n material.side = THREE.DoubleSide;\n }\n\n return mesh;\n }\n\n /**\n * Create a quad (plane) mesh from shape data\n */\n private createQuad(shape: BlockyShape): THREE.Mesh {\n const size = shape.settings.size ?? { x: 1, y: 1, z: 0 };\n const stretch = shape.stretch ?? DEFAULT_STRETCH;\n const offset = shape.offset ?? DEFAULT_POSITION;\n const normal = shape.settings.normal ?? \"+Z\";\n\n // Determine plane dimensions based on normal direction\n let width: number, height: number;\n switch (normal) {\n case \"+X\":\n case \"-X\":\n width = size.z * stretch.z;\n height = size.y * stretch.y;\n break;\n case \"+Y\":\n case \"-Y\":\n width = size.x * stretch.x;\n height = size.z * stretch.z;\n break;\n case \"+Z\":\n case \"-Z\":\n default:\n width = size.x * stretch.x;\n height = size.y * stretch.y;\n break;\n }\n\n const geometry = new THREE.PlaneGeometry(width, height);\n\n // Rotate plane based on normal direction\n switch (normal) {\n case \"+X\":\n geometry.rotateY(Math.PI / 2);\n break;\n case \"-X\":\n geometry.rotateY(-Math.PI / 2);\n break;\n case \"+Y\":\n geometry.rotateX(-Math.PI / 2);\n break;\n case \"-Y\":\n geometry.rotateX(Math.PI / 2);\n break;\n case \"-Z\":\n geometry.rotateY(Math.PI);\n break;\n // +Z is default orientation\n }\n\n geometry.translate(offset.x, offset.y, offset.z);\n\n const material = this.createMaterial(shape);\n material.side = shape.doubleSided ? THREE.DoubleSide : THREE.FrontSide;\n\n const mesh = new THREE.Mesh(geometry, material);\n mesh.userData.shapeType = \"quad\";\n mesh.userData.shadingMode = shape.shadingMode;\n\n return mesh;\n }\n\n /**\n * Create material based on shading mode\n * Phase 1: Basic color material, texture mapping in Phase 2\n */\n private createMaterial(shape: BlockyShape): THREE.MeshStandardMaterial {\n const baseColor = 0x888888; // Gray placeholder until texture is applied\n\n switch (shape.shadingMode) {\n case \"fullbright\":\n return new THREE.MeshStandardMaterial({\n color: baseColor,\n emissive: baseColor,\n emissiveIntensity: 1,\n roughness: 1,\n metalness: 0,\n });\n\n case \"flat\":\n return new THREE.MeshStandardMaterial({\n color: baseColor,\n flatShading: true,\n roughness: 0.9,\n metalness: 0,\n });\n\n case \"reflective\":\n return new THREE.MeshStandardMaterial({\n color: baseColor,\n roughness: 0.1,\n metalness: 0.8,\n });\n\n case \"standard\":\n default:\n return new THREE.MeshStandardMaterial({\n color: baseColor,\n roughness: 0.7,\n metalness: 0,\n });\n }\n }\n}\n\n/**\n * Helper to apply a texture to all meshes in a loaded model\n * Phase 1: Simple texture application without UV mapping\n */\nexport function applyTextureToModel(\n model: THREE.Group,\n texture: THREE.Texture\n): void {\n // Configure texture for pixel art (no filtering)\n texture.magFilter = THREE.NearestFilter;\n texture.minFilter = THREE.NearestFilter;\n texture.colorSpace = THREE.SRGBColorSpace;\n\n model.traverse((object) => {\n if (object instanceof THREE.Mesh) {\n const material = object.material as THREE.MeshStandardMaterial;\n if (material.isMeshStandardMaterial) {\n material.map = texture;\n material.color.setHex(0xffffff); // Reset color to white when texture applied\n material.needsUpdate = true;\n }\n }\n });\n}\n","import {\n\tControls,\n\tMOUSE,\n\tQuaternion,\n\tSpherical,\n\tTOUCH,\n\tVector2,\n\tVector3,\n\tPlane,\n\tRay,\n\tMathUtils\n} from 'three';\n\n// OrbitControls performs orbiting, dollying (zooming), and panning.\n// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n//\n// Orbit - left mouse / touch: one-finger move\n// Zoom - middle mouse, or mousewheel / touch: two-finger spread or squish\n// Pan - right mouse, or left mouse + ctrl/meta/shiftKey, or arrow keys / touch: two-finger move\n\nconst _changeEvent = { type: 'change' };\nconst _startEvent = { type: 'start' };\nconst _endEvent = { type: 'end' };\nconst _ray = new Ray();\nconst _plane = new Plane();\nconst _TILT_LIMIT = Math.cos( 70 * MathUtils.DEG2RAD );\n\nconst _v = new Vector3();\nconst _twoPI = 2 * Math.PI;\n\nconst _STATE = {\n\tNONE: - 1,\n\tROTATE: 0,\n\tDOLLY: 1,\n\tPAN: 2,\n\tTOUCH_ROTATE: 3,\n\tTOUCH_PAN: 4,\n\tTOUCH_DOLLY_PAN: 5,\n\tTOUCH_DOLLY_ROTATE: 6\n};\nconst _EPS = 0.000001;\n\nclass OrbitControls extends Controls {\n\n\tconstructor( object, domElement = null ) {\n\n\t\tsuper( object, domElement );\n\n\t\tthis.state = _STATE.NONE;\n\n\t\t// Set to false to disable this control\n\t\tthis.enabled = true;\n\n\t\t// \"target\" sets the location of focus, where the object orbits around\n\t\tthis.target = new Vector3();\n\n\t\t// Sets the 3D cursor (similar to Blender), from which the maxTargetRadius takes effect\n\t\tthis.cursor = new Vector3();\n\n\t\t// How far you can dolly in and out ( PerspectiveCamera only )\n\t\tthis.minDistance = 0;\n\t\tthis.maxDistance = Infinity;\n\n\t\t// How far you can zoom in and out ( OrthographicCamera only )\n\t\tthis.minZoom = 0;\n\t\tthis.maxZoom = Infinity;\n\n\t\t// Limit camera target within a spherical area around the cursor\n\t\tthis.minTargetRadius = 0;\n\t\tthis.maxTargetRadius = Infinity;\n\n\t\t// How far you can orbit vertically, upper and lower limits.\n\t\t// Range is 0 to Math.PI radians.\n\t\tthis.minPolarAngle = 0; // radians\n\t\tthis.maxPolarAngle = Math.PI; // radians\n\n\t\t// How far you can orbit horizontally, upper and lower limits.\n\t\t// If set, the interval [ min, max ] must be a sub-interval of [ - 2 PI, 2 PI ], with ( max - min < 2 PI )\n\t\tthis.minAzimuthAngle = - Infinity; // radians\n\t\tthis.maxAzimuthAngle = Infinity; // radians\n\n\t\t// Set to true to enable damping (inertia)\n\t\t// If damping is enabled, you must call controls.update() in your animation loop\n\t\tthis.enableDamping = false;\n\t\tthis.dampingFactor = 0.05;\n\n\t\t// This option actually enables dollying in and out; left as \"zoom\" for backwards compatibility.\n\t\t// Set to false to disable zooming\n\t\tthis.enableZoom = true;\n\t\tthis.zoomSpeed = 1.0;\n\n\t\t// Set to false to disable rotating\n\t\tthis.enableRotate = true;\n\t\tthis.rotateSpeed = 1.0;\n\n\t\t// Set to false to disable panning\n\t\tthis.enablePan = true;\n\t\tthis.panSpeed = 1.0;\n\t\tthis.screenSpacePanning = true; // if false, pan orthogonal to world-space direction camera.up\n\t\tthis.keyPanSpeed = 7.0;\t// pixels moved per arrow key push\n\t\tthis.zoomToCursor = false;\n\n\t\t// Set to true to automatically rotate around the target\n\t\t// If auto-rotate is enabled, you must call controls.update() in your animation loop\n\t\tthis.autoRotate = false;\n\t\tthis.autoRotateSpeed = 2.0; // 30 seconds per orbit when fps is 60\n\n\t\t// The four arrow keys\n\t\tthis.keys = { LEFT: 'ArrowLeft', UP: 'ArrowUp', RIGHT: 'ArrowRight', BOTTOM: 'ArrowDown' };\n\n\t\t// Mouse buttons\n\t\tthis.mouseButtons = { LEFT: MOUSE.ROTATE, MIDDLE: MOUSE.DOLLY, RIGHT: MOUSE.PAN };\n\n\t\t// Touch fingers\n\t\tthis.touches = { ONE: TOUCH.ROTATE, TWO: TOUCH.DOLLY_PAN };\n\n\t\t// for reset\n\t\tthis.target0 = this.target.clone();\n\t\tthis.position0 = this.object.position.clone();\n\t\tthis.zoom0 = this.object.zoom;\n\n\t\t// the target DOM element for key events\n\t\tthis._domElementKeyEvents = null;\n\n\t\t// internals\n\n\t\tthis._lastPosition = new Vector3();\n\t\tthis._lastQuaternion = new Quaternion();\n\t\tthis._lastTargetPosition = new Vector3();\n\n\t\t// so camera.up is the orbit axis\n\t\tthis._quat = new Quaternion().setFromUnitVectors( object.up, new Vector3( 0, 1, 0 ) );\n\t\tthis._quatInverse = this._quat.clone().invert();\n\n\t\t// current position in spherical coordinates\n\t\tthis._spherical = new Spherical();\n\t\tthis._sphericalDelta = new Spherical();\n\n\t\tthis._scale = 1;\n\t\tthis._panOffset = new Vector3();\n\n\t\tthis._rotateStart = new Vector2();\n\t\tthis._rotateEnd = new Vector2();\n\t\tthis._rotateDelta = new Vector2();\n\n\t\tthis._panStart = new Vector2();\n\t\tthis._panEnd = new Vector2();\n\t\tthis._panDelta = new Vector2();\n\n\t\tthis._dollyStart = new Vector2();\n\t\tthis._dollyEnd = new Vector2();\n\t\tthis._dollyDelta = new Vector2();\n\n\t\tthis._dollyDirection = new Vector3();\n\t\tthis._mouse = new Vector2();\n\t\tthis._performCursorZoom = false;\n\n\t\tthis._pointers = [];\n\t\tthis._pointerPositions = {};\n\n\t\tthis._controlActive = false;\n\n\t\t// event listeners\n\n\t\tthis._onPointerMove = onPointerMove.bind( this );\n\t\tthis._onPointerDown = onPointerDown.bind( this );\n\t\tthis._onPointerUp = onPointerUp.bind( this );\n\t\tthis._onContextMenu = onContextMenu.bind( this );\n\t\tthis._onMouseWheel = onMouseWheel.bind( this );\n\t\tthis._onKeyDown = onKeyDown.bind( this );\n\n\t\tthis._onTouchStart = onTouchStart.bind( this );\n\t\tthis._onTouchMove = onTouchMove.bind( this );\n\n\t\tthis._onMouseDown = onMouseDown.bind( this );\n\t\tthis._onMouseMove = onMouseMove.bind( this );\n\n\t\tthis._interceptControlDown = interceptControlDown.bind( this );\n\t\tthis._interceptControlUp = interceptControlUp.bind( this );\n\n\t\t//\n\n\t\tif ( this.domElement !== null ) {\n\n\t\t\tthis.connect();\n\n\t\t}\n\n\t\tthis.update();\n\n\t}\n\n\tconnect() {\n\n\t\tthis.domElement.addEventListener( 'pointerdown', this._onPointerDown );\n\t\tthis.domElement.addEventListener( 'pointercancel', this._onPointerUp );\n\n\t\tthis.domElement.addEventListener( 'contextmenu', this._onContextMenu );\n\t\tthis.domElement.addEventListener( 'wheel', this._onMouseWheel, { passive: false } );\n\n\t\tconst document = this.domElement.getRootNode(); // offscreen canvas compatibility\n\t\tdocument.addEventListener( 'keydown', this._interceptControlDown, { passive: true, capture: true } );\n\n\t\tthis.domElement.style.touchAction = 'none'; // disable touch scroll\n\n\t}\n\n\tdisconnect() {\n\n\t\tthis.domElement.removeEventListener( 'pointerdown', this._onPointerDown );\n\t\tthis.domElement.removeEventListener( 'pointermove', this._onPointerMove );\n\t\tthis.domElement.removeEventListener( 'pointerup', this._onPointerUp );\n\t\tthis.domElement.removeEventListener( 'pointercancel', this._onPointerUp );\n\n\t\tthis.domElement.removeEventListener( 'wheel', this._onMouseWheel );\n\t\tthis.domElement.removeEventListener( 'contextmenu', this._onContextMenu );\n\n\t\tthis.stopListenToKeyEvents();\n\n\t\tconst document = this.domElement.getRootNode(); // offscreen canvas compatibility\n\t\tdocument.removeEventListener( 'keydown', this._interceptControlDown, { capture: true } );\n\n\t\tthis.domElement.style.touchAction = 'auto';\n\n\t}\n\n\tdispose() {\n\n\t\tthis.disconnect();\n\n\t}\n\n\tgetPolarAngle() {\n\n\t\treturn this._spherical.phi;\n\n\t}\n\n\tgetAzimuthalAngle() {\n\n\t\treturn this._spherical.theta;\n\n\t}\n\n\tgetDistance() {\n\n\t\treturn this.object.position.distanceTo( this.target );\n\n\t}\n\n\tlistenToKeyEvents( domElement ) {\n\n\t\tdomElement.addEventListener( 'keydown', this._onKeyDown );\n\t\tthis._domElementKeyEvents = domElement;\n\n\t}\n\n\tstopListenToKeyEvents() {\n\n\t\tif ( this._domElementKeyEvents !== null ) {\n\n\t\t\tthis._domElementKeyEvents.removeEventListener( 'keydown', this._onKeyDown );\n\t\t\tthis._domElementKeyEvents = null;\n\n\t\t}\n\n\t}\n\n\tsaveState() {\n\n\t\tthis.target0.copy( this.target );\n\t\tthis.position0.copy( this.object.position );\n\t\tthis.zoom0 = this.object.zoom;\n\n\t}\n\n\treset() {\n\n\t\tthis.target.copy( this.target0 );\n\t\tthis.object.position.copy( this.position0 );\n\t\tthis.object.zoom = this.zoom0;\n\n\t\tthis.object.updateProjectionMatrix();\n\t\tthis.dispatchEvent( _changeEvent );\n\n\t\tthis.update();\n\n\t\tthis.state = _STATE.NONE;\n\n\t}\n\n\tupdate( deltaTime = null ) {\n\n\t\tconst position = this.object.position;\n\n\t\t_v.copy( position ).sub( this.target );\n\n\t\t// rotate offset to \"y-axis-is-up\" space\n\t\t_v.applyQuaternion( this._quat );\n\n\t\t// angle from z-axis around y-axis\n\t\tthis._spherical.setFromVector3( _v );\n\n\t\tif ( this.autoRotate && this.state === _STATE.NONE ) {\n\n\t\t\tthis._rotateLeft( this._getAutoRotationAngle( deltaTime ) );\n\n\t\t}\n\n\t\tif ( this.enableDamping ) {\n\n\t\t\tthis._spherical.theta += this._sphericalDelta.theta * this.dampingFactor;\n\t\t\tthis._spherical.phi += this._sphericalDelta.phi * this.dampingFactor;\n\n\t\t} else {\n\n\t\t\tthis._spherical.theta += this._sphericalDelta.theta;\n\t\t\tthis._spherical.phi += this._sphericalDelta.phi;\n\n\t\t}\n\n\t\t// restrict theta to be between desired limits\n\n\t\tlet min = this.minAzimuthAngle;\n\t\tlet max = this.maxAzimuthAngle;\n\n\t\tif ( isFinite( min ) && isFinite( max ) ) {\n\n\t\t\tif ( min < - Math.PI ) min += _twoPI; else if ( min > Math.PI ) min -= _twoPI;\n\n\t\t\tif ( max < - Math.PI ) max += _twoPI; else if ( max > Math.PI ) max -= _twoPI;\n\n\t\t\tif ( min <= max ) {\n\n\t\t\t\tthis._spherical.theta = Math.max( min, Math.min( max, this._spherical.theta ) );\n\n\t\t\t} else {\n\n\t\t\t\tthis._spherical.theta = ( this._spherical.theta > ( min + max ) / 2 ) ?\n\t\t\t\t\tMath.max( min, this._spherical.theta ) :\n\t\t\t\t\tMath.min( max, this._spherical.theta );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// restrict phi to be between desired limits\n\t\tthis._spherical.phi = Math.max( this.minPolarAngle, Math.min( this.maxPolarAngle, this._spherical.phi ) );\n\n\t\tthis._spherical.makeSafe();\n\n\n\t\t// move target to panned location\n\n\t\tif ( this.enableDamping === true ) {\n\n\t\t\tthis.target.addScaledVector( this._panOffset, this.dampingFactor );\n\n\t\t} else {\n\n\t\t\tthis.target.add( this._panOffset );\n\n\t\t}\n\n\t\t// Limit the target distance from the cursor to create a sphere around the center of interest\n\t\tthis.target.sub( this.cursor );\n\t\tthis.target.clampLength( this.minTargetRadius, this.maxTargetRadius );\n\t\tthis.target.add( this.cursor );\n\n\t\tlet zoomChanged = false;\n\t\t// adjust the camera position based on zoom only if we're not zooming to the cursor or if it's an ortho camera\n\t\t// we adjust zoom later in these cases\n\t\tif ( this.zoomToCursor && this._performCursorZoom || this.object.isOrthographicCamera ) {\n\n\t\t\tthis._spherical.radius = this._clampDistance( this._spherical.radius );\n\n\t\t} else {\n\n\t\t\tconst prevRadius = this._spherical.radius;\n\t\t\tthis._spherical.radius = this._clampDistance( this._spherical.radius * this._scale );\n\t\t\tzoomChanged = prevRadius != this._spherical.radius;\n\n\t\t}\n\n\t\t_v.setFromSpherical( this._spherical );\n\n\t\t// rotate offset back to \"camera-up-vector-is-up\" space\n\t\t_v.applyQuaternion( this._quatInverse );\n\n\t\tposition.copy( this.target ).add( _v );\n\n\t\tthis.object.lookAt( this.target );\n\n\t\tif ( this.enableDamping === true ) {\n\n\t\t\tthis._sphericalDelta.theta *= ( 1 - this.dampingFactor );\n\t\t\tthis._sphericalDelta.phi *= ( 1 - this.dampingFactor );\n\n\t\t\tthis._panOffset.multiplyScalar( 1 - this.dampingFactor );\n\n\t\t} else {\n\n\t\t\tthis._sphericalDelta.set( 0, 0, 0 );\n\n\t\t\tthis._panOffset.set( 0, 0, 0 );\n\n\t\t}\n\n\t\t// adjust camera position\n\t\tif ( this.zoomToCursor && this._performCursorZoom ) {\n\n\t\t\tlet newRadius = null;\n\t\t\tif ( this.object.isPerspectiveCamera ) {\n\n\t\t\t\t// move the camera down the pointer ray\n\t\t\t\t// this method avoids floating point error\n\t\t\t\tconst prevRadius = _v.length();\n\t\t\t\tnewRadius = this._clampDistance( prevRadius * this._scale );\n\n\t\t\t\tconst radiusDelta = prevRadius - newRadius;\n\t\t\t\tthis.object.position.addScaledVector( this._dollyDirection, radiusDelta );\n\t\t\t\tthis.object.updateMatrixWorld();\n\n\t\t\t\tzoomChanged = !! radiusDelta;\n\n\t\t\t} else if ( this.object.isOrthographicCamera ) {\n\n\t\t\t\t// adjust the ortho camera position based on zoom changes\n\t\t\t\tconst mouseBefore = new Vector3( this._mouse.x, this._mouse.y, 0 );\n\t\t\t\tmouseBefore.unproject( this.object );\n\n\t\t\t\tconst prevZoom = this.object.zoom;\n\t\t\t\tthis.object.zoom = Math.max( this.minZoom, Math.min( this.maxZoom, this.object.zoom / this._scale ) );\n\t\t\t\tthis.object.updateProjectionMatrix();\n\n\t\t\t\tzoomChanged = prevZoom !== this.object.zoom;\n\n\t\t\t\tconst mouseAfter = new Vector3( this._mouse.x, this._mouse.y, 0 );\n\t\t\t\tmouseAfter.unproject( this.object );\n\n\t\t\t\tthis.object.position.sub( mouseAfter ).add( mouseBefore );\n\t\t\t\tthis.object.updateMatrixWorld();\n\n\t\t\t\tnewRadius = _v.length();\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - zoom to cursor disabled.' );\n\t\t\t\tthis.zoomToCursor = false;\n\n\t\t\t}\n\n\t\t\t// handle the placement of the target\n\t\t\tif ( newRadius !== null ) {\n\n\t\t\t\tif ( this.screenSpacePanning ) {\n\n\t\t\t\t\t// position the orbit target in front of the new camera position\n\t\t\t\t\tthis.target.set( 0, 0, - 1 )\n\t\t\t\t\t\t.transformDirection( this.object.matrix )\n\t\t\t\t\t\t.multiplyScalar( newRadius )\n\t\t\t\t\t\t.add( this.object.position );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// get the ray and translation plane to compute target\n\t\t\t\t\t_ray.origin.copy( this.object.position );\n\t\t\t\t\t_ray.direction.set( 0, 0, - 1 ).transformDirection( this.object.matrix );\n\n\t\t\t\t\t// if the camera is 20 degrees above the horizon then don't adjust the focus target to avoid\n\t\t\t\t\t// extremely large values\n\t\t\t\t\tif ( Math.abs( this.object.up.dot( _ray.direction ) ) < _TILT_LIMIT ) {\n\n\t\t\t\t\t\tthis.object.lookAt( this.target );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t_plane.setFromNormalAndCoplanarPoint( this.object.up, this.target );\n\t\t\t\t\t\t_ray.intersectPlane( _plane, this.target );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} else if ( this.object.isOrthographicCamera ) {\n\n\t\t\tconst prevZoom = this.object.zoom;\n\t\t\tthis.object.zoom = Math.max( this.minZoom, Math.min( this.maxZoom, this.object.zoom / this._scale ) );\n\n\t\t\tif ( prevZoom !== this.object.zoom ) {\n\n\t\t\t\tthis.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis._scale = 1;\n\t\tthis._performCursorZoom = false;\n\n\t\t// update condition is:\n\t\t// min(camera displacement, camera rotation in radians)^2 > EPS\n\t\t// using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\n\t\tif ( zoomChanged ||\n\t\t\tthis._lastPosition.distanceToSquared( this.object.position ) > _EPS ||\n\t\t\t8 * ( 1 - this._lastQuaternion.dot( this.object.quaternion ) ) > _EPS ||\n\t\t\tthis._lastTargetPosition.distanceToSquared( this.target ) > _EPS ) {\n\n\t\t\tthis.dispatchEvent( _changeEvent );\n\n\t\t\tthis._lastPosition.copy( this.object.position );\n\t\t\tthis._lastQuaternion.copy( this.object.quaternion );\n\t\t\tthis._lastTargetPosition.copy( this.target );\n\n\t\t\treturn true;\n\n\t\t}\n\n\t\treturn false;\n\n\t}\n\n\t_getAutoRotationAngle( deltaTime ) {\n\n\t\tif ( deltaTime !== null ) {\n\n\t\t\treturn ( _twoPI / 60 * this.autoRotateSpeed ) * deltaTime;\n\n\t\t} else {\n\n\t\t\treturn _twoPI / 60 / 60 * this.autoRotateSpeed;\n\n\t\t}\n\n\t}\n\n\t_getZoomScale( delta ) {\n\n\t\tconst normalizedDelta = Math.abs( delta * 0.01 );\n\t\treturn Math.pow( 0.95, this.zoomSpeed * normalizedDelta );\n\n\t}\n\n\t_rotateLeft( angle ) {\n\n\t\tthis._sphericalDelta.theta -= angle;\n\n\t}\n\n\t_rotateUp( angle ) {\n\n\t\tthis._sphericalDelta.phi -= angle;\n\n\t}\n\n\t_panLeft( distance, objectMatrix ) {\n\n\t\t_v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix\n\t\t_v.multiplyScalar( - distance );\n\n\t\tthis._panOffset.add( _v );\n\n\t}\n\n\t_panUp( distance, objectMatrix ) {\n\n\t\tif ( this.screenSpacePanning === true ) {\n\n\t\t\t_v.setFromMatrixColumn( objectMatrix, 1 );\n\n\t\t} else {\n\n\t\t\t_v.setFromMatrixColumn( objectMatrix, 0 );\n\t\t\t_v.crossVectors( this.object.up, _v );\n\n\t\t}\n\n\t\t_v.multiplyScalar( distance );\n\n\t\tthis._panOffset.add( _v );\n\n\t}\n\n\t// deltaX and deltaY are in pixels; right and down are positive\n\t_pan( deltaX, deltaY ) {\n\n\t\tconst element = this.domElement;\n\n\t\tif ( this.object.isPerspectiveCamera ) {\n\n\t\t\t// perspective\n\t\t\tconst position = this.object.position;\n\t\t\t_v.copy( position ).sub( this.target );\n\t\t\tlet targetDistance = _v.length();\n\n\t\t\t// half of the fov is center to top of screen\n\t\t\ttargetDistance *= Math.tan( ( this.object.fov / 2 ) * Math.PI / 180.0 );\n\n\t\t\t// we use only clientHeight here so aspect ratio does not distort speed\n\t\t\tthis._panLeft( 2 * deltaX * targetDistance / element.clientHeight, this.object.matrix );\n\t\t\tthis._panUp( 2 * deltaY * targetDistance / element.clientHeight, this.object.matrix );\n\n\t\t} else if ( this.object.isOrthographicCamera ) {\n\n\t\t\t// orthographic\n\t\t\tthis._panLeft( deltaX * ( this.object.right - this.object.left ) / this.object.zoom / element.clientWidth, this.object.matrix );\n\t\t\tthis._panUp( deltaY * ( this.object.top - this.object.bottom ) / this.object.zoom / element.clientHeight, this.object.matrix );\n\n\t\t} else {\n\n\t\t\t// camera neither orthographic nor perspective\n\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );\n\t\t\tthis.enablePan = false;\n\n\t\t}\n\n\t}\n\n\t_dollyOut( dollyScale ) {\n\n\t\tif ( this.object.isPerspectiveCamera || this.object.isOrthographicCamera ) {\n\n\t\t\tthis._scale /= dollyScale;\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\tthis.enableZoom = false;\n\n\t\t}\n\n\t}\n\n\t_dollyIn( dollyScale ) {\n\n\t\tif ( this.object.isPerspectiveCamera || this.object.isOrthographicCamera ) {\n\n\t\t\tthis._scale *= dollyScale;\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\tthis.enableZoom = false;\n\n\t\t}\n\n\t}\n\n\t_updateZoomParameters( x, y ) {\n\n\t\tif ( ! this.zoomToCursor ) {\n\n\t\t\treturn;\n\n\t\t}\n\n\t\tthis._performCursorZoom = true;\n\n\t\tconst rect = this.domElement.getBoundingClientRect();\n\t\tconst dx = x - rect.left;\n\t\tconst dy = y - rect.top;\n\t\tconst w = rect.width;\n\t\tconst h = rect.height;\n\n\t\tthis._mouse.x = ( dx / w ) * 2 - 1;\n\t\tthis._mouse.y = - ( dy / h ) * 2 + 1;\n\n\t\tthis._dollyDirection.set( this._mouse.x, this._mouse.y, 1 ).unproject( this.object ).sub( this.object.position ).normalize();\n\n\t}\n\n\t_clampDistance( dist ) {\n\n\t\treturn Math.max( this.minDistance, Math.min( this.maxDistance, dist ) );\n\n\t}\n\n\t//\n\t// event callbacks - update the object state\n\t//\n\n\t_handleMouseDownRotate( event ) {\n\n\t\tthis._rotateStart.set( event.clientX, event.clientY );\n\n\t}\n\n\t_handleMouseDownDolly( event ) {\n\n\t\tthis._updateZoomParameters( event.clientX, event.clientX );\n\t\tthis._dollyStart.set( event.clientX, event.clientY );\n\n\t}\n\n\t_handleMouseDownPan( event ) {\n\n\t\tthis._panStart.set( event.clientX, event.clientY );\n\n\t}\n\n\t_handleMouseMoveRotate( event ) {\n\n\t\tthis._rotateEnd.set( event.clientX, event.clientY );\n\n\t\tthis._rotateDelta.subVectors( this._rotateEnd, this._rotateStart ).multiplyScalar( this.rotateSpeed );\n\n\t\tconst element = this.domElement;\n\n\t\tthis._rotateLeft( _twoPI * this._rotateDelta.x / element.clientHeight ); // yes, height\n\n\t\tthis._rotateUp( _twoPI * this._rotateDelta.y / element.clientHeight );\n\n\t\tthis._rotateStart.copy( this._rotateEnd );\n\n\t\tthis.update();\n\n\t}\n\n\t_handleMouseMoveDolly( event ) {\n\n\t\tthis._dollyEnd.set( event.clientX, event.clientY );\n\n\t\tthis._dollyDelta.subVectors( this._dollyEnd, this._dollyStart );\n\n\t\tif ( this._dollyDelta.y > 0 ) {\n\n\t\t\tthis._dollyOut( this._getZoomScale( this._dollyDelta.y ) );\n\n\t\t} else if ( this._dollyDelta.y < 0 ) {\n\n\t\t\tthis._dollyIn( this._getZoomScale( this._dollyDelta.y ) );\n\n\t\t}\n\n\t\tthis._dollyStart.copy( this._dollyEnd );\n\n\t\tthis.update();\n\n\t}\n\n\t_handleMouseMovePan( event ) {\n\n\t\tthis._panEnd.set( event.clientX, event.clientY );\n\n\t\tthis._panDelta.subVectors( this._panEnd, this._panStart ).multiplyScalar( this.panSpeed );\n\n\t\tthis._pan( this._panDelta.x, this._panDelta.y );\n\n\t\tthis._panStart.copy( this._panEnd );\n\n\t\tthis.update();\n\n\t}\n\n\t_handleMouseWheel( event ) {\n\n\t\tthis._updateZoomParameters( event.clientX, event.clientY );\n\n\t\tif ( event.deltaY < 0 ) {\n\n\t\t\tthis._dollyIn( this._getZoomScale( event.deltaY ) );\n\n\t\t} else if ( event.deltaY > 0 ) {\n\n\t\t\tthis._dollyOut( this._getZoomScale( event.deltaY ) );\n\n\t\t}\n\n\t\tthis.update();\n\n\t}\n\n\t_handleKeyDown( event ) {\n\n\t\tlet needsUpdate = false;\n\n\t\tswitch ( event.code ) {\n\n\t\t\tcase this.keys.UP:\n\n\t\t\t\tif ( event.ctrlKey || event.metaKey || event.shiftKey ) {\n\n\t\t\t\t\tthis._rotateUp( _twoPI * this.rotateSpeed / this.domElement.clientHeight );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._pan( 0, this.keyPanSpeed );\n\n\t\t\t\t}\n\n\t\t\t\tneedsUpdate = true;\n\t\t\t\tbreak;\n\n\t\t\tcase this.keys.BOTTOM:\n\n\t\t\t\tif ( event.ctrlKey || event.metaKey || event.shiftKey ) {\n\n\t\t\t\t\tthis._rotateUp( - _twoPI * this.rotateSpeed / this.domElement.clientHeight );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._pan( 0, - this.keyPanSpeed );\n\n\t\t\t\t}\n\n\t\t\t\tneedsUpdate = true;\n\t\t\t\tbreak;\n\n\t\t\tcase this.keys.LEFT:\n\n\t\t\t\tif ( event.ctrlKey || event.metaKey || event.shiftKey ) {\n\n\t\t\t\t\tthis._rotateLeft( _twoPI * this.rotateSpeed / this.domElement.clientHeight );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._pan( this.keyPanSpeed, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tneedsUpdate = true;\n\t\t\t\tbreak;\n\n\t\t\tcase this.keys.RIGHT:\n\n\t\t\t\tif ( event.ctrlKey || event.metaKey || event.shiftKey ) {\n\n\t\t\t\t\tthis._rotateLeft( - _twoPI * this.rotateSpeed / this.domElement.clientHeight );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._pan( - this.keyPanSpeed, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tneedsUpdate = true;\n\t\t\t\tbreak;\n\n\t\t}\n\n\t\tif ( needsUpdate ) {\n\n\t\t\t// prevent the browser from scrolling on cursor keys\n\t\t\tevent.preventDefault();\n\n\t\t\tthis.update();\n\n\t\t}\n\n\n\t}\n\n\t_handleTouchStartRotate( event ) {\n\n\t\tif ( this._pointers.length === 1 ) {\n\n\t\t\tthis._rotateStart.set( event.pageX, event.pageY );\n\n\t\t} else {\n\n\t\t\tconst position = this._getSecondPointerPosition( event );\n\n\t\t\tconst x = 0.5 * ( event.pageX + position.x );\n\t\t\tconst y = 0.5 * ( event.pageY + position.y );\n\n\t\t\tthis._rotateStart.set( x, y );\n\n\t\t}\n\n\t}\n\n\t_handleTouchStartPan( event ) {\n\n\t\tif ( this._pointers.length === 1 ) {\n\n\t\t\tthis._panStart.set( event.pageX, event.pageY );\n\n\t\t} else {\n\n\t\t\tconst position = this._getSecondPointerPosition( event );\n\n\t\t\tconst x = 0.5 * ( event.pageX + position.x );\n\t\t\tconst y = 0.5 * ( event.pageY + position.y );\n\n\t\t\tthis._panStart.set( x, y );\n\n\t\t}\n\n\t}\n\n\t_handleTouchStartDolly( event ) {\n\n\t\tconst position = this._getSecondPointerPosition( event );\n\n\t\tconst dx = event.pageX - position.x;\n\t\tconst dy = event.pageY - position.y;\n\n\t\tconst distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\tthis._dollyStart.set( 0, distance );\n\n\t}\n\n\t_handleTouchStartDollyPan( event ) {\n\n\t\tif ( this.enableZoom ) this._handleTouchStartDolly( event );\n\n\t\tif ( this.enablePan ) this._handleTouchStartPan( event );\n\n\t}\n\n\t_handleTouchStartDollyRotate( event ) {\n\n\t\tif ( this.enableZoom ) this._handleTouchStartDolly( event );\n\n\t\tif ( this.enableRotate ) this._handleTouchStartRotate( event );\n\n\t}\n\n\t_handleTouchMoveRotate( event ) {\n\n\t\tif ( this._pointers.length == 1 ) {\n\n\t\t\tthis._rotateEnd.set( event.pageX, event.pageY );\n\n\t\t} else {\n\n\t\t\tconst position = this._getSecondPointerPosition( event );\n\n\t\t\tconst x = 0.5 * ( event.pageX + position.x );\n\t\t\tconst y = 0.5 * ( event.pageY + position.y );\n\n\t\t\tthis._rotateEnd.set( x, y );\n\n\t\t}\n\n\t\tthis._rotateDelta.subVectors( this._rotateEnd, this._rotateStart ).multiplyScalar( this.rotateSpeed );\n\n\t\tconst element = this.domElement;\n\n\t\tthis._rotateLeft( _twoPI * this._rotateDelta.x / element.clientHeight ); // yes, height\n\n\t\tthis._rotateUp( _twoPI * this._rotateDelta.y / element.clientHeight );\n\n\t\tthis._rotateStart.copy( this._rotateEnd );\n\n\t}\n\n\t_handleTouchMovePan( event ) {\n\n\t\tif ( this._pointers.length === 1 ) {\n\n\t\t\tthis._panEnd.set( event.pageX, event.pageY );\n\n\t\t} else {\n\n\t\t\tconst position = this._getSecondPointerPosition( event );\n\n\t\t\tconst x = 0.5 * ( event.pageX + position.x );\n\t\t\tconst y = 0.5 * ( event.pageY + position.y );\n\n\t\t\tthis._panEnd.set( x, y );\n\n\t\t}\n\n\t\tthis._panDelta.subVectors( this._panEnd, this._panStart ).multiplyScalar( this.panSpeed );\n\n\t\tthis._pan( this._panDelta.x, this._panDelta.y );\n\n\t\tthis._panStart.copy( this._panEnd );\n\n\t}\n\n\t_handleTouchMoveDolly( event ) {\n\n\t\tconst position = this._getSecondPointerPosition( event );\n\n\t\tconst dx = event.pageX - position.x;\n\t\tconst dy = event.pageY - position.y;\n\n\t\tconst distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\tthis._dollyEnd.set( 0, distance );\n\n\t\tthis._dollyDelta.set( 0, Math.pow( this._dollyEnd.y / this._dollyStart.y, this.zoomSpeed ) );\n\n\t\tthis._dollyOut( this._dollyDelta.y );\n\n\t\tthis._dollyStart.copy( this._dollyEnd );\n\n\t\tconst centerX = ( event.pageX + position.x ) * 0.5;\n\t\tconst centerY = ( event.pageY + position.y ) * 0.5;\n\n\t\tthis._updateZoomParameters( centerX, centerY );\n\n\t}\n\n\t_handleTouchMoveDollyPan( event ) {\n\n\t\tif ( this.enableZoom ) this._handleTouchMoveDolly( event );\n\n\t\tif ( this.enablePan ) this._handleTouchMovePan( event );\n\n\t}\n\n\t_handleTouchMoveDollyRotate( event ) {\n\n\t\tif ( this.enableZoom ) this._handleTouchMoveDolly( event );\n\n\t\tif ( this.enableRotate ) this._handleTouchMoveRotate( event );\n\n\t}\n\n\t// pointers\n\n\t_addPointer( event ) {\n\n\t\tthis._pointers.push( event.pointerId );\n\n\t}\n\n\t_removePointer( event ) {\n\n\t\tdelete this._pointerPositions[ event.pointerId ];\n\n\t\tfor ( let i = 0; i < this._pointers.length; i ++ ) {\n\n\t\t\tif ( this._pointers[ i ] == event.pointerId ) {\n\n\t\t\t\tthis._pointers.splice( i, 1 );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t_isTrackingPointer( event ) {\n\n\t\tfor ( let i = 0; i < this._pointers.length; i ++ ) {\n\n\t\t\tif ( this._pointers[ i ] == event.pointerId ) return true;\n\n\t\t}\n\n\t\treturn false;\n\n\t}\n\n\t_trackPointer( event ) {\n\n\t\tlet position = this._pointerPositions[ event.pointerId ];\n\n\t\tif ( position === undefined ) {\n\n\t\t\tposition = new Vector2();\n\t\t\tthis._pointerPositions[ event.pointerId ] = position;\n\n\t\t}\n\n\t\tposition.set( event.pageX, event.pageY );\n\n\t}\n\n\t_getSecondPointerPosition( event ) {\n\n\t\tconst pointerId = ( event.pointerId === this._pointers[ 0 ] ) ? this._pointers[ 1 ] : this._pointers[ 0 ];\n\n\t\treturn this._pointerPositions[ pointerId ];\n\n\t}\n\n\t//\n\n\t_customWheelEvent( event ) {\n\n\t\tconst mode = event.deltaMode;\n\n\t\t// minimal wheel event altered to meet delta-zoom demand\n\t\tconst newEvent = {\n\t\t\tclientX: event.clientX,\n\t\t\tclientY: event.clientY,\n\t\t\tdeltaY: event.deltaY,\n\t\t};\n\n\t\tswitch ( mode ) {\n\n\t\t\tcase 1: // LINE_MODE\n\t\t\t\tnewEvent.deltaY *= 16;\n\t\t\t\tbreak;\n\n\t\t\tcase 2: // PAGE_MODE\n\t\t\t\tnewEvent.deltaY *= 100;\n\t\t\t\tbreak;\n\n\t\t}\n\n\t\t// detect if event was triggered by pinching\n\t\tif ( event.ctrlKey && ! this._controlActive ) {\n\n\t\t\tnewEvent.deltaY *= 10;\n\n\t\t}\n\n\t\treturn newEvent;\n\n\t}\n\n}\n\nfunction onPointerDown( event ) {\n\n\tif ( this.enabled === false ) return;\n\n\tif ( this._pointers.length === 0 ) {\n\n\t\tthis.domElement.setPointerCapture( event.pointerId );\n\n\t\tthis.domElement.addEventListener( 'pointermove', this._onPointerMove );\n\t\tthis.domElement.addEventListener( 'pointerup', this._onPointerUp );\n\n\t}\n\n\t//\n\n\tif ( this._isTrackingPointer( event ) ) return;\n\n\t//\n\n\tthis._addPointer( event );\n\n\tif ( event.pointerType === 'touch' ) {\n\n\t\tthis._onTouchStart( event );\n\n\t} else {\n\n\t\tthis._onMouseDown( event );\n\n\t}\n\n}\n\nfunction onPointerMove( event ) {\n\n\tif ( this.enabled === false ) return;\n\n\tif ( event.pointerType === 'touch' ) {\n\n\t\tthis._onTouchMove( event );\n\n\t} else {\n\n\t\tthis._onMouseMove( event );\n\n\t}\n\n}\n\nfunction onPointerUp( event ) {\n\n\tthis._removePointer( event );\n\n\tswitch ( this._pointers.length ) {\n\n\t\tcase 0:\n\n\t\t\tthis.domElement.releasePointerCapture( event.pointerId );\n\n\t\t\tthis.domElement.removeEventListener( 'pointermove', this._onPointerMove );\n\t\t\tthis.domElement.removeEventListener( 'pointerup', this._onPointerUp );\n\n\t\t\tthis.dispatchEvent( _endEvent );\n\n\t\t\tthis.state = _STATE.NONE;\n\n\t\t\tbreak;\n\n\t\tcase 1:\n\n\t\t\tconst pointerId = this._pointers[ 0 ];\n\t\t\tconst position = this._pointerPositions[ pointerId ];\n\n\t\t\t// minimal placeholder event - allows state correction on pointer-up\n\t\t\tthis._onTouchStart( { pointerId: pointerId, pageX: position.x, pageY: position.y } );\n\n\t\t\tbreak;\n\n\t}\n\n}\n\nfunction onMouseDown( event ) {\n\n\tlet mouseAction;\n\n\tswitch ( event.button ) {\n\n\t\tcase 0:\n\n\t\t\tmouseAction = this.mouseButtons.LEFT;\n\t\t\tbreak;\n\n\t\tcase 1:\n\n\t\t\tmouseAction = this.mouseButtons.MIDDLE;\n\t\t\tbreak;\n\n\t\tcase 2:\n\n\t\t\tmouseAction = this.mouseButtons.RIGHT;\n\t\t\tbreak;\n\n\t\tdefault:\n\n\t\t\tmouseAction = - 1;\n\n\t}\n\n\tswitch ( mouseAction ) {\n\n\t\tcase MOUSE.DOLLY:\n\n\t\t\tif ( this.enableZoom === false ) return;\n\n\t\t\tthis._handleMouseDownDolly( event );\n\n\t\t\tthis.state = _STATE.DOLLY;\n\n\t\t\tbreak;\n\n\t\tcase MOUSE.ROTATE:\n\n\t\t\tif ( event.ctrlKey || event.metaKey || event.shiftKey ) {\n\n\t\t\t\tif ( this.enablePan === false ) return;\n\n\t\t\t\tthis._handleMouseDownPan( event );\n\n\t\t\t\tthis.state = _STATE.PAN;\n\n\t\t\t} else {\n\n\t\t\t\tif ( this.enableRotate === false ) return;\n\n\t\t\t\tthis._handleMouseDownRotate( event );\n\n\t\t\t\tthis.state = _STATE.ROTATE;\n\n\t\t\t}\n\n\t\t\tbreak;\n\n\t\tcase MOUSE.PAN:\n\n\t\t\tif ( event.ctrlKey || event.metaKey || event.shiftKey ) {\n\n\t\t\t\tif ( this.enableRotate === false ) return;\n\n\t\t\t\tthis._handleMouseDownRotate( event );\n\n\t\t\t\tthis.state = _STATE.ROTATE;\n\n\t\t\t} else {\n\n\t\t\t\tif ( this.enablePan === false ) return;\n\n\t\t\t\tthis._handleMouseDownPan( event );\n\n\t\t\t\tthis.state = _STATE.PAN;\n\n\t\t\t}\n\n\t\t\tbreak;\n\n\t\tdefault:\n\n\t\t\tthis.state = _STATE.NONE;\n\n\t}\n\n\tif ( this.state !== _STATE.NONE ) {\n\n\t\tthis.dispatchEvent( _startEvent );\n\n\t}\n\n}\n\nfunction onMouseMove( event ) {\n\n\tswitch ( this.state ) {\n\n\t\tcase _STATE.ROTATE:\n\n\t\t\tif ( this.enableRotate === false ) return;\n\n\t\t\tthis._handleMouseMoveRotate( event );\n\n\t\t\tbreak;\n\n\t\tcase _STATE.DOLLY:\n\n\t\t\tif ( this.enableZoom === false ) return;\n\n\t\t\tthis._handleMouseMoveDolly( event );\n\n\t\t\tbreak;\n\n\t\tcase _STATE.PAN:\n\n\t\t\tif ( this.enablePan === false ) return;\n\n\t\t\tthis._handleMouseMovePan( event );\n\n\t\t\tbreak;\n\n\t}\n\n}\n\nfunction onMouseWheel( event ) {\n\n\tif ( this.enabled === false || this.enableZoom === false || this.state !== _STATE.NONE ) return;\n\n\tevent.preventDefault();\n\n\tthis.dispatchEvent( _startEvent );\n\n\tthis._handleMouseWheel( this._customWheelEvent( event ) );\n\n\tthis.dispatchEvent( _endEvent );\n\n}\n\nfunction onKeyDown( event ) {\n\n\tif ( this.enabled === false || this.enablePan === false ) return;\n\n\tthis._handleKeyDown( event );\n\n}\n\nfunction onTouchStart( event ) {\n\n\tthis._trackPointer( event );\n\n\tswitch ( this._pointers.length ) {\n\n\t\tcase 1:\n\n\t\t\tswitch ( this.touches.ONE ) {\n\n\t\t\t\tcase TOUCH.ROTATE:\n\n\t\t\t\t\tif ( this.enableRotate === false ) return;\n\n\t\t\t\t\tthis._handleTouchStartRotate( event );\n\n\t\t\t\t\tthis.state = _STATE.TOUCH_ROTATE;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase TOUCH.PAN:\n\n\t\t\t\t\tif ( this.enablePan === false ) return;\n\n\t\t\t\t\tthis._handleTouchStartPan( event );\n\n\t\t\t\t\tthis.state = _STATE.TOUCH_PAN;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tthis.state = _STATE.NONE;\n\n\t\t\t}\n\n\t\t\tbreak;\n\n\t\tcase 2:\n\n\t\t\tswitch ( this.touches.TWO ) {\n\n\t\t\t\tcase TOUCH.DOLLY_PAN:\n\n\t\t\t\t\tif ( this.enableZoom === false && this.enablePan === false ) return;\n\n\t\t\t\t\tthis._handleTouchStartDollyPan( event );\n\n\t\t\t\t\tthis.state = _STATE.TOUCH_DOLLY_PAN;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase TOUCH.DOLLY_ROTATE:\n\n\t\t\t\t\tif ( this.enableZoom === false && this.enableRotate === false ) return;\n\n\t\t\t\t\tthis._handleTouchStartDollyRotate( event );\n\n\t\t\t\t\tthis.state = _STATE.TOUCH_DOLLY_ROTATE;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tthis.state = _STATE.NONE;\n\n\t\t\t}\n\n\t\t\tbreak;\n\n\t\tdefault:\n\n\t\t\tthis.state = _STATE.NONE;\n\n\t}\n\n\tif ( this.state !== _STATE.NONE ) {\n\n\t\tthis.dispatchEvent( _startEvent );\n\n\t}\n\n}\n\nfunction onTouchMove( event ) {\n\n\tthis._trackPointer( event );\n\n\tswitch ( this.state ) {\n\n\t\tcase _STATE.TOUCH_ROTATE:\n\n\t\t\tif ( this.enableRotate === false ) return;\n\n\t\t\tthis._handleTouchMoveRotate( event );\n\n\t\t\tthis.update();\n\n\t\t\tbreak;\n\n\t\tcase _STATE.TOUCH_PAN:\n\n\t\t\tif ( this.enablePan === false ) return;\n\n\t\t\tthis._handleTouchMovePan( event );\n\n\t\t\tthis.update();\n\n\t\t\tbreak;\n\n\t\tcase _STATE.TOUCH_DOLLY_PAN:\n\n\t\t\tif ( this.enableZoom === false && this.enablePan === false ) return;\n\n\t\t\tthis._handleTouchMoveDollyPan( event );\n\n\t\t\tthis.update();\n\n\t\t\tbreak;\n\n\t\tcase _STATE.TOUCH_DOLLY_ROTATE:\n\n\t\t\tif ( this.enableZoom === false && this.enableRotate === false ) return;\n\n\t\t\tthis._handleTouchMoveDollyRotate( event );\n\n\t\t\tthis.update();\n\n\t\t\tbreak;\n\n\t\tdefault:\n\n\t\t\tthis.state = _STATE.NONE;\n\n\t}\n\n}\n\nfunction onContextMenu( event ) {\n\n\tif ( this.enabled === false ) return;\n\n\tevent.preventDefault();\n\n}\n\nfunction interceptControlDown( event ) {\n\n\tif ( event.key === 'Control' ) {\n\n\t\tthis._controlActive = true;\n\n\t\tconst document = this.domElement.getRootNode(); // offscreen canvas compatibility\n\n\t\tdocument.addEventListener( 'keyup', this._interceptControlUp, { passive: true, capture: true } );\n\n\t}\n\n}\n\nfunction interceptControlUp( event ) {\n\n\tif ( event.key === 'Control' ) {\n\n\t\tthis._controlActive = false;\n\n\t\tconst document = this.domElement.getRootNode(); // offscreen canvas compatibility\n\n\t\tdocument.removeEventListener( 'keyup', this._interceptControlUp, { passive: true, capture: true } );\n\n\t}\n\n}\n\nexport { OrbitControls };\n","import * as THREE from \"three\";\nimport { OrbitControls } from \"three/examples/jsm/controls/OrbitControls.js\";\nimport { BlockyModelLoader, applyTextureToModel } from \"../loaders/BlockyModelLoader\";\n\nexport interface ViewerOptions {\n container: HTMLElement;\n backgroundColor?: number;\n}\n\n/**\n * Main viewer controller\n * Manages Three.js scene, camera, controls, and model loading\n */\nexport class ViewerController {\n public readonly scene: THREE.Scene;\n public readonly camera: THREE.PerspectiveCamera;\n public readonly renderer: THREE.WebGLRenderer;\n public readonly controls: OrbitControls;\n public readonly domElement: HTMLElement;\n\n private loader: BlockyModelLoader;\n private textureLoader: THREE.TextureLoader;\n private currentModel: THREE.Group | null = null;\n private animationId: number | null = null;\n\n constructor(options: ViewerOptions) {\n const { container, backgroundColor = 0x1a1a2e } = options;\n\n this.domElement = container;\n\n // Scene setup\n this.scene = new THREE.Scene();\n this.scene.background = new THREE.Color(backgroundColor);\n\n // Camera setup\n const aspect = container.clientWidth / container.clientHeight;\n this.camera = new THREE.PerspectiveCamera(50, aspect, 0.1, 1000);\n this.camera.position.set(50, 50, 100);\n\n // Renderer setup\n this.renderer = new THREE.WebGLRenderer({\n antialias: true,\n alpha: true,\n });\n this.renderer.setSize(container.clientWidth, container.clientHeight);\n this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));\n this.renderer.shadowMap.enabled = true;\n this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;\n container.appendChild(this.renderer.domElement);\n\n // Controls setup\n this.controls = new OrbitControls(this.camera, this.renderer.domElement);\n this.controls.enableDamping = true;\n this.controls.dampingFactor = 0.1;\n this.controls.minDistance = 10;\n this.controls.maxDistance = 500;\n\n // Loaders\n this.loader = new BlockyModelLoader();\n this.textureLoader = new THREE.TextureLoader();\n\n // Lighting\n this.setupLighting();\n\n // Grid helper\n this.setupHelpers();\n\n // Handle resize\n window.addEventListener(\"resize\", () => this.handleResize(container));\n\n // Start render loop\n this.animate();\n }\n\n private setupLighting(): void {\n // Ambient light for base illumination\n const ambient = new THREE.AmbientLight(0xffffff, 0.4);\n this.scene.add(ambient);\n\n // Main directional light\n const mainLight = new THREE.DirectionalLight(0xffffff, 0.8);\n mainLight.position.set(50, 100, 50);\n mainLight.castShadow = true;\n mainLight.shadow.mapSize.width = 2048;\n mainLight.shadow.mapSize.height = 2048;\n this.scene.add(mainLight);\n\n // Fill light from opposite side\n const fillLight = new THREE.DirectionalLight(0xffffff, 0.3);\n fillLight.position.set(-50, 50, -50);\n this.scene.add(fillLight);\n\n // Rim light for edge definition\n const rimLight = new THREE.DirectionalLight(0x88ccff, 0.2);\n rimLight.position.set(0, -50, -100);\n this.scene.add(rimLight);\n }\n\n private setupHelpers(): void {\n // Grid on XZ plane\n const grid = new THREE.GridHelper(200, 20, 0x444444, 0x333333);\n grid.position.y = -0.1;\n this.scene.add(grid);\n\n // Axes helper\n const axes = new THREE.AxesHelper(20);\n this.scene.add(axes);\n }\n\n private handleResize(container: HTMLElement): void {\n const width = container.clientWidth;\n const height = container.clientHeight;\n\n this.camera.aspect = width / height;\n this.camera.updateProjectionMatrix();\n this.renderer.setSize(width, height);\n }\n\n private animate = (): void => {\n this.animationId = requestAnimationFrame(this.animate);\n this.controls.update();\n this.renderer.render(this.scene, this.camera);\n };\n\n /**\n * Load a .blockymodel file\n */\n async loadModel(file: File): Promise<THREE.Group> {\n // Remove existing model\n if (this.currentModel) {\n this.scene.remove(this.currentModel);\n this.disposeModel(this.currentModel);\n this.currentModel = null;\n }\n\n try {\n this.currentModel = await this.loader.loadFromFile(file);\n this.scene.add(this.currentModel);\n\n // Center and fit camera to model\n this.fitCameraToModel();\n\n console.log(`Loaded model with ${this.countMeshes(this.currentModel)} meshes`);\n return this.currentModel;\n } catch (error) {\n console.error(\"Failed to load model:\", error);\n throw error;\n }\n }\n\n /**\n * Get the currently loaded model\n */\n getModel(): THREE.Group | null {\n return this.currentModel;\n }\n\n /**\n * Load a texture and apply to current model\n */\n async loadTexture(file: File): Promise<void> {\n if (!this.currentModel) {\n console.warn(\"No model loaded to apply texture to\");\n return;\n }\n\n const url = URL.createObjectURL(file);\n\n try {\n const texture = await new Promise<THREE.Texture>((resolve, reject) => {\n this.textureLoader.load(url, resolve, undefined, reject);\n });\n\n applyTextureToModel(this.currentModel, texture);\n console.log(\"Texture applied\");\n } finally {\n URL.revokeObjectURL(url);\n }\n }\n\n /**\n * Fit camera to view the entire model\n */\n fitCameraToModel(): void {\n if (!this.currentModel) return;\n\n const box = new THREE.Box3().setFromObject(this.currentModel);\n const center = box.getCenter(new THREE.Vector3());\n const size = box.getSize(new THREE.Vector3());\n\n const maxDim = Math.max(size.x, size.y, size.z);\n const fov = this.camera.fov * (Math.PI / 180);\n const cameraDistance = maxDim / (2 * Math.tan(fov / 2)) * 1.5;\n\n this.camera.position.set(\n center.x + cameraDistance * 0.5,\n center.y + cameraDistance * 0.5,\n center.z + cameraDistance\n );\n\n this.controls.target.copy(center);\n this.controls.update();\n }\n\n /**\n * Reset camera to default position\n */\n resetCamera(): void {\n if (this.currentModel) {\n this.fitCameraToModel();\n } else {\n this.camera.position.set(50, 50, 100);\n this.controls.target.set(0, 0, 0);\n this.controls.update();\n }\n }\n\n /**\n * Set background color\n */\n setBackgroundColor(color: number | string): void {\n this.scene.background = new THREE.Color(color);\n }\n\n /**\n * Toggle wireframe mode on all meshes\n */\n toggleWireframe(enabled: boolean): void {\n this.currentModel?.traverse((object) => {\n if (object instanceof THREE.Mesh) {\n const material = object.material as THREE.MeshStandardMaterial;\n material.wireframe = enabled;\n }\n });\n }\n\n /**\n * Get model hierarchy for debugging\n */\n getModelHierarchy(): object | null {\n if (!this.currentModel) return null;\n\n const buildHierarchy = (object: THREE.Object3D): object => ({\n name: object.name,\n type: object.type,\n userData: object.userData,\n children: object.children.map(buildHierarchy),\n });\n\n return buildHierarchy(this.currentModel);\n }\n\n /**\n * Count meshes in model\n */\n private countMeshes(object: THREE.Object3D): number {\n let count = 0;\n object.traverse((child) => {\n if (child instanceof THREE.Mesh) count++;\n });\n return count;\n }\n\n /**\n * Dispose of model resources\n */\n private disposeModel(model: THREE.Group): void {\n model.traverse((object) => {\n if (object instanceof THREE.Mesh) {\n object.geometry.dispose();\n if (Array.isArray(object.material)) {\n object.material.forEach((m) => m.dispose());\n } else {\n object.material.dispose();\n }\n }\n });\n }\n\n /**\n * Clean up all resources\n */\n dispose(): void {\n if (this.animationId !== null) {\n cancelAnimationFrame(this.animationId);\n }\n\n if (this.currentModel) {\n this.disposeModel(this.currentModel);\n }\n\n this.controls.dispose();\n this.renderer.dispose();\n }\n}\n"],"names":["HIGHLIGHT_EMISSIVE","HIGHLIGHT_INTENSITY","SelectionManager","editor","__publicField","THREE","event","rect","model","pickables","object","intersects","target","current","child","material","original","mesh","callback","args","_a","_raycaster","Raycaster","_tempVector","Vector3","_tempVector2","_tempQuaternion","Quaternion","_unit","_changeEvent","_mouseDownEvent","_mouseUpEvent","_objectChangeEvent","TransformControls","Controls","camera","domElement","root","TransformControlsRoot","gizmo","TransformControlsGizmo","plane","TransformControlsPlane","scope","defineProperty","propName","defaultValue","propValue","value","worldPosition","worldPositionStart","worldQuaternion","worldQuaternionStart","cameraPosition","cameraQuaternion","pointStart","pointEnd","rotationAxis","rotationAngle","eye","getPointer","onPointerDown","onPointerHover","onPointerMove","onPointerUp","pointer","intersect","intersectObjectWithRay","planeIntersect","axis","mode","space","d","ROTATION_SPEED","_inPlaneRotation","translationSnap","rotationSnap","scaleSnap","size","raycaster","includeInvisible","allIntersections","i","_tempEuler","Euler","_alignVector","_zeroVector","_lookAtMatrix","Matrix4","_tempQuaternion2","_identityQuaternion","_dirVector","_tempMatrix","_unitX","_unitY","_unitZ","_v1","_v2","_v3","Object3D","controls","force","gizmoMaterial","MeshBasicMaterial","gizmoLineMaterial","LineBasicMaterial","matInvisible","matHelper","matRed","matGreen","matBlue","matRedTransparent","matGreenTransparent","matBlueTransparent","matWhiteTransparent","matYellowTransparent","matGray","arrowGeometry","CylinderGeometry","scaleHandleGeometry","BoxGeometry","lineGeometry","BufferGeometry","Float32BufferAttribute","lineGeometry2","CircleGeometry","radius","arc","geometry","TorusGeometry","TranslateHelperGeometry","gizmoTranslate","Mesh","OctahedronGeometry","pickerTranslate","helperTranslate","Line","gizmoRotate","helperRotate","pickerRotate","SphereGeometry","gizmoScale","pickerScale","helperScale","setupGizmo","gizmoMap","name","position","rotation","scale","tag","tempGeometry","quaternion","handles","handle","factor","a","PlaneGeometry","DoubleSide","BaseCommand","updatable","SetPositionCommand","newPosition","oldPosition","command","SetRotationCommand","newRotation","oldRotation","SetScaleCommand","newScale","oldScale","TransformManager","isDragging","helper","MERGE_WINDOW_MS","History","lastCommand","Editor","options","generateId","Serializer","blockyModel","node","shapeType","shape","params","defaultFace","filename","json","blob","url","link","SetPropertyCommand","propertyPath","newValue","oldValue","obj","path","parts","part","AddNodeCommand","parent","index","children","RemoveNodeCommand","PropertyPanel","containerId","container","oldName","newName","oldPos","oldRot","newRot","oldSize","oldOffset","inputs","onChange","handler","_b","_c","offset","_d","_e","_f","stretch","finalSize","transform","empty","HierarchyPanel","action","selected","depth","item","indent","expander","e","icon","label","isCollapsed","el","group","clone","FACE_NAMES","FACE_LABELS","DEFAULT_FACE_UV","UVEditor","facesHtml","face","textureLayout","newFaceUV","newTextureLayout","faceUV","_g","layout","uvAttribute","faceIndexMap","uvs","startVertex","offsetX","offsetY","idx","u","v","rad","cu","cv","content","DEFAULT_POSITION","DEFAULT_ORIENTATION","DEFAULT_STRETCH","BlockyModelLoader","manager","response","file","text","pos","orient","childObject","normal","width","height","applyTextureToModel","texture","_startEvent","_endEvent","_ray","Ray","_plane","Plane","_TILT_LIMIT","MathUtils","_v","_twoPI","_STATE","_EPS","OrbitControls","MOUSE","TOUCH","Spherical","Vector2","onContextMenu","onMouseWheel","onKeyDown","onTouchStart","onTouchMove","onMouseDown","onMouseMove","interceptControlDown","interceptControlUp","deltaTime","min","max","zoomChanged","prevRadius","newRadius","radiusDelta","mouseBefore","prevZoom","mouseAfter","delta","normalizedDelta","angle","distance","objectMatrix","deltaX","deltaY","element","targetDistance","dollyScale","x","y","dx","dy","w","dist","needsUpdate","centerX","centerY","pointerId","newEvent","mouseAction","ViewerController","backgroundColor","aspect","ambient","mainLight","fillLight","rimLight","grid","axes","error","resolve","reject","box","center","maxDim","fov","cameraDistance","color","enabled","buildHierarchy","count","m"],"mappings":"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","x_google_ignoreList":[1,18]}
|