endset_three_editor 0.2.7 → 0.3.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"three-editor.es.js","sources":["../node_modules/three/examples/jsm/controls/OrbitControls.js","../node_modules/three/examples/jsm/controls/TransformControls.js","../src/three/index.ts","../node_modules/three/examples/jsm/loaders/OBJLoader.js","../node_modules/three/examples/jsm/utils/BufferGeometryUtils.js","../node_modules/three/examples/jsm/utils/SkeletonUtils.js","../node_modules/three/examples/jsm/loaders/GLTFLoader.js","../src/three/addHandle.ts","../src/components/TreeItem.vue","../src/composables/useTreeExpand.ts","../src/components/PropertyPanel.vue","../src/components/TopBar.vue","../src/components/BottomBar.vue","../src/components/DrawingBoard.vue"],"sourcesContent":["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/**\n * Fires when the camera has been transformed by the controls.\n *\n * @event OrbitControls#change\n * @type {Object}\n */\nconst _changeEvent = { type: 'change' };\n\n/**\n * Fires when an interaction was initiated.\n *\n * @event OrbitControls#start\n * @type {Object}\n */\nconst _startEvent = { type: 'start' };\n\n/**\n * Fires when an interaction has finished.\n *\n * @event OrbitControls#end\n * @type {Object}\n */\nconst _endEvent = { type: 'end' };\n\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\n\n/**\n * Orbit controls allow the camera to orbit around a target.\n *\n * OrbitControls performs orbiting, dollying (zooming), and panning. Unlike {@link TrackballControls},\n * 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 *\n * ```js\n * const controls = new OrbitControls( camera, renderer.domElement );\n *\n * // controls.update() must be called after any manual changes to the camera's transform\n * camera.position.set( 0, 20, 100 );\n * controls.update();\n *\n * function animate() {\n *\n * \t// required if controls.enableDamping or controls.autoRotate are set to true\n * \tcontrols.update();\n *\n * \trenderer.render( scene, camera );\n *\n * }\n * ```\n *\n * @augments Controls\n * @three_import import { OrbitControls } from 'three/addons/controls/OrbitControls.js';\n */\nclass OrbitControls extends Controls {\n\n\t/**\n\t * Constructs a new controls instance.\n\t *\n\t * @param {Object3D} object - The object that is managed by the controls.\n\t * @param {?HTMLElement} domElement - The HTML element used for event listeners.\n\t */\n\tconstructor( object, domElement = null ) {\n\n\t\tsuper( object, domElement );\n\n\t\tthis.state = _STATE.NONE;\n\n\t\t/**\n\t\t * The focus point of the controls, the `object` orbits around this.\n\t\t * It can be updated manually at any point to change the focus of the controls.\n\t\t *\n\t\t * @type {Vector3}\n\t\t */\n\t\tthis.target = new Vector3();\n\n\t\t/**\n\t\t * The focus point of the `minTargetRadius` and `maxTargetRadius` limits.\n\t\t * It can be updated manually at any point to change the center of interest\n\t\t * for the `target`.\n\t\t *\n\t\t * @type {Vector3}\n\t\t */\n\t\tthis.cursor = new Vector3();\n\n\t\t/**\n\t\t * How far you can dolly in (perspective camera only).\n\t\t *\n\t\t * @type {number}\n\t\t * @default 0\n\t\t */\n\t\tthis.minDistance = 0;\n\n\t\t/**\n\t\t * How far you can dolly out (perspective camera only).\n\t\t *\n\t\t * @type {number}\n\t\t * @default Infinity\n\t\t */\n\t\tthis.maxDistance = Infinity;\n\n\t\t/**\n\t\t * How far you can zoom in (orthographic camera only).\n\t\t *\n\t\t * @type {number}\n\t\t * @default 0\n\t\t */\n\t\tthis.minZoom = 0;\n\n\t\t/**\n\t\t * How far you can zoom out (orthographic camera only).\n\t\t *\n\t\t * @type {number}\n\t\t * @default Infinity\n\t\t */\n\t\tthis.maxZoom = Infinity;\n\n\t\t/**\n\t\t * How close you can get the target to the 3D `cursor`.\n\t\t *\n\t\t * @type {number}\n\t\t * @default 0\n\t\t */\n\t\tthis.minTargetRadius = 0;\n\n\t\t/**\n\t\t * How far you can move the target from the 3D `cursor`.\n\t\t *\n\t\t * @type {number}\n\t\t * @default Infinity\n\t\t */\n\t\tthis.maxTargetRadius = Infinity;\n\n\t\t/**\n\t\t * How far you can orbit vertically, lower limit. Range is `[0, Math.PI]` radians.\n\t\t *\n\t\t * @type {number}\n\t\t * @default 0\n\t\t */\n\t\tthis.minPolarAngle = 0;\n\n\t\t/**\n\t\t * How far you can orbit vertically, upper limit. Range is `[0, Math.PI]` radians.\n\t\t *\n\t\t * @type {number}\n\t\t * @default Math.PI\n\t\t */\n\t\tthis.maxPolarAngle = Math.PI;\n\n\t\t/**\n\t\t * How far you can orbit horizontally, lower limit. If set, the interval `[ min, max ]`\n\t\t * must be a sub-interval of `[ - 2 PI, 2 PI ]`, with `( max - min < 2 PI )`.\n\t\t *\n\t\t * @type {number}\n\t\t * @default -Infinity\n\t\t */\n\t\tthis.minAzimuthAngle = - Infinity;\n\n\t\t/**\n\t\t * How far you can orbit horizontally, upper limit. If set, the interval `[ min, max ]`\n\t\t * must be a sub-interval of `[ - 2 PI, 2 PI ]`, with `( max - min < 2 PI )`.\n\t\t *\n\t\t * @type {number}\n\t\t * @default -Infinity\n\t\t */\n\t\tthis.maxAzimuthAngle = Infinity;\n\n\t\t/**\n\t\t * Set to `true` to enable damping (inertia), which can be used to give a sense of weight\n\t\t * to the controls. Note that if this is enabled, you must call `update()` in your animation\n\t\t * loop.\n\t\t *\n\t\t * @type {boolean}\n\t\t * @default false\n\t\t */\n\t\tthis.enableDamping = false;\n\n\t\t/**\n\t\t * The damping inertia used if `enableDamping` is set to `true`.\n\t\t *\n\t\t * Note that for this to work, you must call `update()` in your animation loop.\n\t\t *\n\t\t * @type {number}\n\t\t * @default 0.05\n\t\t */\n\t\tthis.dampingFactor = 0.05;\n\n\t\t/**\n\t\t * Enable or disable zooming (dollying) of the camera.\n\t\t *\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t */\n\t\tthis.enableZoom = true;\n\n\t\t/**\n\t\t * Speed of zooming / dollying.\n\t\t *\n\t\t * @type {number}\n\t\t * @default 1\n\t\t */\n\t\tthis.zoomSpeed = 1.0;\n\n\t\t/**\n\t\t * Enable or disable horizontal and vertical rotation of the camera.\n\t\t *\n\t\t * Note that it is possible to disable a single axis by setting the min and max of the\n\t\t * `minPolarAngle` or `minAzimuthAngle` to the same value, which will cause the vertical\n\t\t * or horizontal rotation to be fixed at that value.\n\t\t *\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t */\n\t\tthis.enableRotate = true;\n\n\t\t/**\n\t\t * Speed of rotation.\n\t\t *\n\t\t * @type {number}\n\t\t * @default 1\n\t\t */\n\t\tthis.rotateSpeed = 1.0;\n\n\t\t/**\n\t\t * How fast to rotate the camera when the keyboard is used.\n\t\t *\n\t\t * @type {number}\n\t\t * @default 1\n\t\t */\n\t\tthis.keyRotateSpeed = 1.0;\n\n\t\t/**\n\t\t * Enable or disable camera panning.\n\t\t *\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t */\n\t\tthis.enablePan = true;\n\n\t\t/**\n\t\t * Speed of panning.\n\t\t *\n\t\t * @type {number}\n\t\t * @default 1\n\t\t */\n\t\tthis.panSpeed = 1.0;\n\n\t\t/**\n\t\t * Defines how the camera's position is translated when panning. If `true`, the camera pans\n\t\t * in screen space. Otherwise, the camera pans in the plane orthogonal to the camera's up\n\t\t * direction.\n\t\t *\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t */\n\t\tthis.screenSpacePanning = true;\n\n\t\t/**\n\t\t * How fast to pan the camera when the keyboard is used in\n\t\t * pixels per keypress.\n\t\t *\n\t\t * @type {number}\n\t\t * @default 7\n\t\t */\n\t\tthis.keyPanSpeed = 7.0;\n\n\t\t/**\n\t\t * Setting this property to `true` allows to zoom to the cursor's position.\n\t\t *\n\t\t * @type {boolean}\n\t\t * @default false\n\t\t */\n\t\tthis.zoomToCursor = false;\n\n\t\t/**\n\t\t * Set to true to automatically rotate around the target\n\t\t *\n\t\t * Note that if this is enabled, you must call `update()` in your animation loop.\n\t\t * If you want the auto-rotate speed to be independent of the frame rate (the refresh\n\t\t * rate of the display), you must pass the time `deltaTime`, in seconds, to `update()`.\n\t\t *\n\t\t * @type {boolean}\n\t\t * @default false\n\t\t */\n\t\tthis.autoRotate = false;\n\n\t\t/**\n\t\t * How fast to rotate around the target if `autoRotate` is `true`. The default equates to 30 seconds\n\t\t * per orbit at 60fps.\n\t\t *\n\t\t * Note that if `autoRotate` is enabled, you must call `update()` in your animation loop.\n\t\t *\n\t\t * @type {number}\n\t\t * @default 2\n\t\t */\n\t\tthis.autoRotateSpeed = 2.0;\n\n\t\t/**\n\t\t * This object contains references to the keycodes for controlling camera panning.\n\t\t *\n\t\t * ```js\n\t\t * controls.keys = {\n\t\t * \tLEFT: 'ArrowLeft', //left arrow\n\t\t * \tUP: 'ArrowUp', // up arrow\n\t\t * \tRIGHT: 'ArrowRight', // right arrow\n\t\t * \tBOTTOM: 'ArrowDown' // down arrow\n\t\t * }\n\t\t * ```\n\t\t * @type {Object}\n\t\t */\n\t\tthis.keys = { LEFT: 'ArrowLeft', UP: 'ArrowUp', RIGHT: 'ArrowRight', BOTTOM: 'ArrowDown' };\n\n\t\t/**\n\t\t * This object contains references to the mouse actions used by the controls.\n\t\t *\n\t\t * ```js\n\t\t * controls.mouseButtons = {\n\t\t * \tLEFT: THREE.MOUSE.ROTATE,\n\t\t * \tMIDDLE: THREE.MOUSE.DOLLY,\n\t\t * \tRIGHT: THREE.MOUSE.PAN\n\t\t * }\n\t\t * ```\n\t\t * @type {Object}\n\t\t */\n\t\tthis.mouseButtons = { LEFT: MOUSE.ROTATE, MIDDLE: MOUSE.DOLLY, RIGHT: MOUSE.PAN };\n\n\t\t/**\n\t\t * This object contains references to the touch actions used by the controls.\n\t\t *\n\t\t * ```js\n\t\t * controls.mouseButtons = {\n\t\t * \tONE: THREE.TOUCH.ROTATE,\n\t\t * \tTWO: THREE.TOUCH.DOLLY_PAN\n\t\t * }\n\t\t * ```\n\t\t * @type {Object}\n\t\t */\n\t\tthis.touches = { ONE: TOUCH.ROTATE, TWO: TOUCH.DOLLY_PAN };\n\n\t\t/**\n\t\t * Used internally by `saveState()` and `reset()`.\n\t\t *\n\t\t * @type {Vector3}\n\t\t */\n\t\tthis.target0 = this.target.clone();\n\n\t\t/**\n\t\t * Used internally by `saveState()` and `reset()`.\n\t\t *\n\t\t * @type {Vector3}\n\t\t */\n\t\tthis.position0 = this.object.position.clone();\n\n\t\t/**\n\t\t * Used internally by `saveState()` and `reset()`.\n\t\t *\n\t\t * @type {number}\n\t\t */\n\t\tthis.zoom0 = this.object.zoom;\n\n\t\tthis._cursorStyle = 'auto';\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( this.domElement );\n\n\t\t}\n\n\t\tthis.update();\n\n\t}\n\n\t/**\n\t * Defines the visual representation of the cursor.\n\t *\n\t * @type {('auto'|'grab')}\n\t * @default 'auto'\n\t */\n\tset cursorStyle( type ) {\n\n\t\tthis._cursorStyle = type;\n\n\t\tif ( type === 'grab' ) {\n\n\t\t\tthis.domElement.style.cursor = 'grab';\n\n\t\t} else {\n\n\t\t\tthis.domElement.style.cursor = 'auto';\n\n\t\t}\n\n\t}\n\n\tget cursorStyle() {\n\n\t\treturn this._cursorStyle;\n\n\t}\n\n\tconnect( element ) {\n\n\t\tsuper.connect( element );\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.ownerDocument.removeEventListener( 'pointermove', this._onPointerMove );\n\t\tthis.domElement.ownerDocument.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 = ''; // Restore touch scroll\n\n\t}\n\n\tdispose() {\n\n\t\tthis.disconnect();\n\n\t}\n\n\t/**\n\t * Get the current vertical rotation, in radians.\n\t *\n\t * @return {number} The current vertical rotation, in radians.\n\t */\n\tgetPolarAngle() {\n\n\t\treturn this._spherical.phi;\n\n\t}\n\n\t/**\n\t * Get the current horizontal rotation, in radians.\n\t *\n\t * @return {number} The current horizontal rotation, in radians.\n\t */\n\tgetAzimuthalAngle() {\n\n\t\treturn this._spherical.theta;\n\n\t}\n\n\t/**\n\t * Returns the distance from the camera to the target.\n\t *\n\t * @return {number} The distance from the camera to the target.\n\t */\n\tgetDistance() {\n\n\t\treturn this.object.position.distanceTo( this.target );\n\n\t}\n\n\t/**\n\t * Adds key event listeners to the given DOM element.\n\t * `window` is a recommended argument for using this method.\n\t *\n\t * @param {HTMLElement} domElement - The DOM element\n\t */\n\tlistenToKeyEvents( domElement ) {\n\n\t\tdomElement.addEventListener( 'keydown', this._onKeyDown );\n\t\tthis._domElementKeyEvents = domElement;\n\n\t}\n\n\t/**\n\t * Removes the key event listener previously defined with `listenToKeyEvents()`.\n\t */\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\t/**\n\t * Save the current state of the controls. This can later be recovered with `reset()`.\n\t */\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\t/**\n\t * Reset the controls to their state from either the last time the `saveState()`\n\t * was called, or the initial state.\n\t */\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\t/**\n\t * Programmatically pan the camera.\n\t *\n\t * @param {number} deltaX - The horizontal pan amount in pixels.\n\t * @param {number} deltaY - The vertical pan amount in pixels.\n\t */\n\tpan( deltaX, deltaY ) {\n\n\t\tthis._pan( deltaX, deltaY );\n\t\tthis.update();\n\n\t}\n\n\t/**\n\t * Programmatically dolly in (zoom in for perspective camera).\n\t *\n\t * @param {number} dollyScale - The dolly scale factor.\n\t */\n\tdollyIn( dollyScale ) {\n\n\t\tthis._dollyIn( dollyScale );\n\t\tthis.update();\n\n\t}\n\n\t/**\n\t * Programmatically dolly out (zoom out for perspective camera).\n\t *\n\t * @param {number} dollyScale - The dolly scale factor.\n\t */\n\tdollyOut( dollyScale ) {\n\n\t\tthis._dollyOut( dollyScale );\n\t\tthis.update();\n\n\t}\n\n\t/**\n\t * Programmatically rotate the camera left (around the vertical axis).\n\t *\n\t * @param {number} angle - The rotation angle in radians.\n\t */\n\trotateLeft( angle ) {\n\n\t\tthis._rotateLeft( angle );\n\t\tthis.update();\n\n\t}\n\n\t/**\n\t * Programmatically rotate the camera up (around the horizontal axis).\n\t *\n\t * @param {number} angle - The rotation angle in radians.\n\t */\n\trotateUp( angle ) {\n\n\t\tthis._rotateUp( angle );\n\t\tthis.update();\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\tif ( this.enableRotate ) {\n\n\t\t\t\t\t\tthis._rotateUp( _twoPI * this.keyRotateSpeed / this.domElement.clientHeight );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( this.enablePan ) {\n\n\t\t\t\t\t\tthis._pan( 0, this.keyPanSpeed );\n\n\t\t\t\t\t}\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\tif ( this.enableRotate ) {\n\n\t\t\t\t\t\tthis._rotateUp( - _twoPI * this.keyRotateSpeed / this.domElement.clientHeight );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( this.enablePan ) {\n\n\t\t\t\t\t\tthis._pan( 0, - this.keyPanSpeed );\n\n\t\t\t\t\t}\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\tif ( this.enableRotate ) {\n\n\t\t\t\t\t\tthis._rotateLeft( _twoPI * this.keyRotateSpeed / this.domElement.clientHeight );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( this.enablePan ) {\n\n\t\t\t\t\t\tthis._pan( this.keyPanSpeed, 0 );\n\n\t\t\t\t\t}\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\tif ( this.enableRotate ) {\n\n\t\t\t\t\t\tthis._rotateLeft( - _twoPI * this.keyRotateSpeed / this.domElement.clientHeight );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( this.enablePan ) {\n\n\t\t\t\t\t\tthis._pan( - this.keyPanSpeed, 0 );\n\n\t\t\t\t\t}\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.ownerDocument.addEventListener( 'pointermove', this._onPointerMove );\n\t\tthis.domElement.ownerDocument.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\tif ( this._cursorStyle === 'grab' ) {\n\n\t\tthis.domElement.style.cursor = 'grabbing';\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.ownerDocument.removeEventListener( 'pointermove', this._onPointerMove );\n\t\t\tthis.domElement.ownerDocument.removeEventListener( 'pointerup', this._onPointerUp );\n\n\t\t\tthis.dispatchEvent( _endEvent );\n\n\t\t\tthis.state = _STATE.NONE;\n\n\t\t\tif ( this._cursorStyle === 'grab' ) {\n\n\t\t\t\tthis.domElement.style.cursor = 'grab';\n\n\t\t\t}\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 ) 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 {\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\n/**\n * Fires if any type of change (object or property change) is performed. Property changes\n * are separate events you can add event listeners to. The event type is \"propertyname-changed\".\n *\n * @event TransformControls#change\n * @type {Object}\n */\nconst _changeEvent = { type: 'change' };\n\n/**\n * Fires if a pointer (mouse/touch) becomes active.\n *\n * @event TransformControls#mouseDown\n * @type {Object}\n */\nconst _mouseDownEvent = { type: 'mouseDown', mode: null };\n\n/**\n * Fires if a pointer (mouse/touch) is no longer active.\n *\n * @event TransformControls#mouseUp\n * @type {Object}\n */\nconst _mouseUpEvent = { type: 'mouseUp', mode: null };\n\n/**\n * Fires if the controlled 3D object is changed.\n *\n * @event TransformControls#objectChange\n * @type {Object}\n */\nconst _objectChangeEvent = { type: 'objectChange' };\n\n/**\n * This class can be used to transform objects in 3D space by adapting a similar interaction model\n * of DCC tools like Blender. Unlike other controls, it is not intended to transform the scene's camera.\n *\n * `TransformControls` expects that its attached 3D object is part of the scene graph.\n *\n * @augments Controls\n * @three_import import { TransformControls } from 'three/addons/controls/TransformControls.js';\n */\nclass TransformControls extends Controls {\n\n\t/**\n\t * Constructs a new controls instance.\n\t *\n\t * @param {Camera} camera - The camera of the rendered scene.\n\t * @param {?HTMLElement} domElement - The HTML element used for event listeners.\n\t */\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\t/**\n\t\t * The camera of the rendered scene.\n\t\t *\n\t\t * @name TransformControls#camera\n\t\t * @type {Camera}\n\t\t */\n\t\tdefineProperty( 'camera', camera );\n\t\tdefineProperty( 'object', undefined );\n\t\tdefineProperty( 'enabled', true );\n\n\t\t/**\n\t\t * The current transformation axis.\n\t\t *\n\t\t * @name TransformControls#axis\n\t\t * @type {string}\n\t\t */\n\t\tdefineProperty( 'axis', null );\n\n\t\t/**\n\t\t * The current transformation axis.\n\t\t *\n\t\t * @name TransformControls#mode\n\t\t * @type {('translate'|'rotate'|'scale')}\n\t\t * @default 'translate'\n\t\t */\n\t\tdefineProperty( 'mode', 'translate' );\n\n\t\t/**\n\t\t * By default, 3D objects are continuously translated. If you set this property to a numeric\n\t\t * value (world units), you can define in which steps the 3D object should be translated.\n\t\t *\n\t\t * @name TransformControls#translationSnap\n\t\t * @type {?number}\n\t\t * @default null\n\t\t */\n\t\tdefineProperty( 'translationSnap', null );\n\n\t\t/**\n\t\t * By default, 3D objects are continuously rotated. If you set this property to a numeric\n\t\t * value (radians), you can define in which steps the 3D object should be rotated.\n\t\t *\n\t\t * @name TransformControls#rotationSnap\n\t\t * @type {?number}\n\t\t * @default null\n\t\t */\n\t\tdefineProperty( 'rotationSnap', null );\n\n\t\t/**\n\t\t * By default, 3D objects are continuously scaled. If you set this property to a numeric\n\t\t * value, you can define in which steps the 3D object should be scaled.\n\t\t *\n\t\t * @name TransformControls#scaleSnap\n\t\t * @type {?number}\n\t\t * @default null\n\t\t */\n\t\tdefineProperty( 'scaleSnap', null );\n\n\t\t/**\n\t\t * Defines in which coordinate space transformations should be performed.\n\t\t *\n\t\t * @name TransformControls#space\n\t\t * @type {('world'|'local')}\n\t\t * @default 'world'\n\t\t */\n\t\tdefineProperty( 'space', 'world' );\n\n\t\t/**\n\t\t * The size of the helper UI (axes/planes).\n\t\t *\n\t\t * @name TransformControls#size\n\t\t * @type {number}\n\t\t * @default 1\n\t\t */\n\t\tdefineProperty( 'size', 1 );\n\n\t\t/**\n\t\t * Whether dragging is currently performed or not.\n\t\t *\n\t\t * @name TransformControls#dragging\n\t\t * @type {boolean}\n\t\t * @readonly\n\t\t * @default false\n\t\t */\n\t\tdefineProperty( 'dragging', false );\n\n\t\t/**\n\t\t * Whether the x-axis helper should be visible or not.\n\t\t *\n\t\t * @name TransformControls#showX\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t */\n\t\tdefineProperty( 'showX', true );\n\n\t\t/**\n\t\t * Whether the y-axis helper should be visible or not.\n\t\t *\n\t\t * @name TransformControls#showY\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t */\n\t\tdefineProperty( 'showY', true );\n\n\t\t/**\n\t\t * Whether the z-axis helper should be visible or not.\n\t\t *\n\t\t * @name TransformControls#showZ\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t */\n\t\tdefineProperty( 'showZ', true );\n\n\t\t/**\n\t\t * Whether the xy-plane helper should be visible or not.\n\t\t *\n\t\t * @name TransformControls#showXY\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t */\n\t\tdefineProperty( 'showXY', true );\n\n\t\t/**\n\t\t * Whether the yz-plane helper should be visible or not.\n\t\t *\n\t\t * @name TransformControls#showYZ\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t */\n\t\tdefineProperty( 'showYZ', true );\n\n\t\t/**\n\t\t * Whether the xz-axis helper should be visible or not.\n\t\t *\n\t\t * @name TransformControls#showXZ\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t */\n\t\tdefineProperty( 'showXZ', true );\n\n\t\t/**\n\t\t * The minimum allowed X position during translation.\n\t\t *\n\t\t * @name TransformControls#minX\n\t\t * @type {number}\n\t\t * @default -Infinity\n\t\t */\n\t\tdefineProperty( 'minX', - Infinity );\n\n\t\t/**\n\t\t * The maximum allowed X position during translation.\n\t\t *\n\t\t * @name TransformControls#maxX\n\t\t * @type {number}\n\t\t * @default Infinity\n\t\t */\n\t\tdefineProperty( 'maxX', Infinity );\n\n\t\t/**\n\t\t * The minimum allowed y position during translation.\n\t\t *\n\t\t * @name TransformControls#minY\n\t\t * @type {number}\n\t\t * @default -Infinity\n\t\t */\n\t\tdefineProperty( 'minY', - Infinity );\n\n\t\t/**\n\t\t * The maximum allowed Y position during translation.\n\t\t *\n\t\t * @name TransformControls#maxY\n\t\t * @type {number}\n\t\t * @default Infinity\n\t\t */\n\t\tdefineProperty( 'maxY', Infinity );\n\n\t\t/**\n\t\t * The minimum allowed z position during translation.\n\t\t *\n\t\t * @name TransformControls#minZ\n\t\t * @type {number}\n\t\t * @default -Infinity\n\t\t */\n\t\tdefineProperty( 'minZ', - Infinity );\n\n\t\t/**\n\t\t * The maximum allowed Z position during translation.\n\t\t *\n\t\t * @name TransformControls#maxZ\n\t\t * @type {number}\n\t\t * @default Infinity\n\t\t */\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( domElement );\n\n\t\t}\n\n\t}\n\n\tconnect( element ) {\n\n\t\tsuper.connect( element );\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 = ''; // Restore touch scroll\n\n\t}\n\n\t/**\n\t * Returns the visual representation of the controls. Add the helper to your scene to\n\t * visually transform the attached 3D object.\n\t *\n\t * @return {TransformControlsRoot} The helper.\n\t */\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/**\n\t * Sets the 3D object that should be transformed and ensures the controls UI is visible.\n\t *\n\t * @param {Object3D} object - The 3D object that should be transformed.\n\t * @return {TransformControls} A reference to this controls.\n\t */\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/**\n\t * Removes the current 3D object from the controls and makes the helper UI invisible.\n\t *\n\t * @return {TransformControls} A reference to this controls.\n\t */\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\t/**\n\t * Resets the object's position, rotation and scale to when the current transform began.\n\t */\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\t/**\n\t * Returns the raycaster that is used for user interaction. This object is shared between all\n\t * instances of `TransformControls`.\n\t *\n\t * @returns {Raycaster} The internal raycaster.\n\t */\n\tgetRaycaster() {\n\n\t\treturn _raycaster;\n\n\t}\n\n\t/**\n\t * Returns the transformation mode.\n\t *\n\t * @returns {'translate'|'rotate'|'scale'} The transformation mode.\n\t */\n\tgetMode() {\n\n\t\treturn this.mode;\n\n\t}\n\n\t/**\n\t * Sets the given transformation mode.\n\t *\n\t * @param {'translate'|'rotate'|'scale'} mode - The transformation mode to set.\n\t */\n\tsetMode( mode ) {\n\n\t\tthis.mode = mode;\n\n\t}\n\n\t/**\n\t * Sets the translation snap.\n\t *\n\t * @param {?number} translationSnap - The translation snap to set.\n\t */\n\tsetTranslationSnap( translationSnap ) {\n\n\t\tthis.translationSnap = translationSnap;\n\n\t}\n\n\t/**\n\t * Sets the rotation snap.\n\t *\n\t * @param {?number} rotationSnap - The rotation snap to set.\n\t */\n\tsetRotationSnap( rotationSnap ) {\n\n\t\tthis.rotationSnap = rotationSnap;\n\n\t}\n\n\t/**\n\t * Sets the scale snap.\n\t *\n\t * @param {?number} scaleSnap - The scale snap to set.\n\t */\n\tsetScaleSnap( scaleSnap ) {\n\n\t\tthis.scaleSnap = scaleSnap;\n\n\t}\n\n\t/**\n\t * Sets the size of the helper UI.\n\t *\n\t * @param {number} size - The size to set.\n\t */\n\tsetSize( size ) {\n\n\t\tthis.size = size;\n\n\t}\n\n\t/**\n\t * Sets the coordinate space in which transformations are applied.\n\t *\n\t * @param {'world'|'local'} space - The space to set.\n\t */\n\tsetSpace( space ) {\n\n\t\tthis.space = space;\n\n\t}\n\n\t/**\n\t * Sets the colors of the control's gizmo.\n\t *\n\t * @param {number|Color|string} xAxis - The x-axis color.\n\t * @param {number|Color|string} yAxis - The y-axis color.\n\t * @param {number|Color|string} zAxis - The z-axis color.\n\t * @param {number|Color|string} active - The color for active elements.\n\t */\n\tsetColors( xAxis, yAxis, zAxis, active ) {\n\n\t\tconst materialLib = this._gizmo.materialLib;\n\n\t\tmaterialLib.xAxis.color.set( xAxis );\n\t\tmaterialLib.yAxis.color.set( yAxis );\n\t\tmaterialLib.zAxis.color.set( zAxis );\n\t\tmaterialLib.active.color.set( active );\n\t\tmaterialLib.xAxisTransparent.color.set( xAxis );\n\t\tmaterialLib.yAxisTransparent.color.set( yAxis );\n\t\tmaterialLib.zAxisTransparent.color.set( zAxis );\n\t\tmaterialLib.activeTransparent.color.set( active );\n\n\t\t// update color caches\n\n\t\tif ( materialLib.xAxis._color ) materialLib.xAxis._color.set( xAxis );\n\t\tif ( materialLib.yAxis._color ) materialLib.yAxis._color.set( yAxis );\n\t\tif ( materialLib.zAxis._color ) materialLib.zAxis._color.set( zAxis );\n\t\tif ( materialLib.active._color ) materialLib.active._color.set( active );\n\t\tif ( materialLib.xAxisTransparent._color ) materialLib.xAxisTransparent._color.set( xAxis );\n\t\tif ( materialLib.yAxisTransparent._color ) materialLib.yAxisTransparent._color.set( yAxis );\n\t\tif ( materialLib.zAxisTransparent._color ) materialLib.zAxisTransparent._color.set( zAxis );\n\t\tif ( materialLib.activeTransparent._color ) materialLib.activeTransparent._color.set( active );\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// materials in the below property are configurable via setColors()\n\n\t\tthis.materialLib = {\n\t\t\txAxis: matRed,\n\t\t\tyAxis: matGreen,\n\t\t\tzAxis: matBlue,\n\t\t\tactive: matYellow,\n\t\t\txAxisTransparent: matRedTransparent,\n\t\t\tyAxisTransparent: matGreenTransparent,\n\t\t\tzAxisTransparent: matBlueTransparent,\n\t\t\tactiveTransparent: matYellowTransparent\n\t\t};\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 ), [ 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 ), [ 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};\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 ), [ - 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 ), [ 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 ), [ 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 ), [ - 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 ) ],\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 ), [ - 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 ), [ 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 ), [ 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// Hide disabled plane helpers\n\t\t\thandle.visible = handle.visible && ( handle.name.indexOf( 'XY' ) === - 1 || this.showXY );\n\t\t\thandle.visible = handle.visible && ( handle.name.indexOf( 'YZ' ) === - 1 || this.showYZ );\n\t\t\thandle.visible = handle.visible && ( handle.name.indexOf( 'XZ' ) === - 1 || this.showXZ );\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.copy( this.materialLib.active.color );\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.copy( this.materialLib.active.color );\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","/**\r\n * 3D 模型编辑器核心模块\r\n * 提供场景管理、物体增删、选中/变换控制、树形数据同步等功能\r\n * 采用单例模式管理所有 Three.js 相关状态\r\n */\r\n\r\nimport * as THREE from \"three\";\r\nimport TWEEN from \"@tweenjs/tween.js\";\r\nimport { OrbitControls } from \"three/examples/jsm/controls/OrbitControls.js\";\r\nimport { TransformControls } from \"three/examples/jsm/controls/TransformControls.js\";\r\nimport type { Object3D } from \"three\";\r\nimport type {\r\n SelectedChangeCallback,\r\n TransformChangeCallback,\r\n SceneObjectsChangeCallback,\r\n} from \"./types\";\r\n\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n//#region 编辑器状态(单例)\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n\r\n/** 编辑器核心状态容器,所有 Three.js 核心对象均存放于此 */\r\nconst state = {\r\n mode: \"\",\r\n /** Three.js 场景 */\r\n scene: null as THREE.Scene | null,\r\n /** 透视相机 */\r\n camera: null as THREE.PerspectiveCamera | null,\r\n /** WebGL 渲染器 */\r\n renderer: null as THREE.WebGLRenderer | null,\r\n /** 轨道控制器(用于场景浏览) */\r\n orbitControls: null as OrbitControls | null,\r\n /** 变换控制器(用于平移/旋转/缩放物体) */\r\n transformControls: null as TransformControls | null,\r\n /** 编辑器挂载的 DOM 容器 */\r\n container: null as HTMLElement | null,\r\n /** 网格辅助对象(地板) */\r\n gridHelper: null as THREE.GridHelper | null,\r\n /** 当前选中的物体 */\r\n selectedObject: null as Object3D | null,\r\n};\r\n//#endregion\r\n\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n//#region 辅助标志\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n\r\n/** 轨道控制器是否发生了旋转/平移/缩放操作 */\r\nlet orbitChanged = false;\r\n/** 是否应该跳过下一次鼠标点击事件(用于防止拖拽后误触发选中) */\r\nlet skipNextClick = false;\r\n//#endregion\r\n\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n//#region 外部回调\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n\r\n/** 选中物体变化时的回调(由外部注册,用于同步 UI) */\r\nlet onSelectedChange: SelectedChangeCallback | null = null;\r\n/** 变换过程中(拖拽)的回调(由外部注册,用于实时更新属性面板) */\r\nlet onTransformChange: TransformChangeCallback | null = null;\r\n/** 场景物体列表变化时的回调(由外部注册,用于更新树形面板) */\r\nlet onSceneObjectsChange: SceneObjectsChangeCallback | null = null;\r\n//#endregion\r\n\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n//#region 树形数据(仅存储顶层可移动物体)\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n\r\n/** 场景中顶层可移动物体的列表(不包含子物体,子物体通过 parent 关系访问) */\r\nlet sceneObjects: Object3D[] = [];\r\n//#endregion\r\n\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n//#region 初始化场景数据\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n\r\n// 如果有场景数据,恢复相机参数并保存 target\r\nlet cameraTarget: number[] | undefined;\r\n//#endregion\r\n\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n//#region 辅助变量(用于销毁)\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n\r\n/** 动画帧 ID,用于取消动画循环 */\r\nlet animationId: number | null = null;\r\n/** 鼠标点击事件监听函数引用(用于移除) */\r\nlet clickHandler: ((event: MouseEvent) => void) | null = null;\r\n/** 窗口 resize 事件监听函数引用(用于移除) */\r\nlet resizeHandler: (() => void) | null = null;\r\n//#endregion\r\n\r\n// ═══════════════════════════════════════════════════════════════════\r\n//#region 初始化\r\n// ═══════════════════════════════════════════════════════════════════\r\n\r\n/**\r\n * 初始化编辑器,挂载到指定 DOM 容器\r\n * @param container - 编辑器挂载的 DOM 元素\r\n */\r\nexport function initEditor(\r\n container: HTMLElement,\r\n mode = \"edit\",\r\n sceneData?: any,\r\n) {\r\n state.container = container;\r\n state.mode = mode;\r\n initRenderer(); // 创建渲染器\r\n initScene(); // 创建场景\r\n initCamera(); // 创建相机\r\n\r\n // 如果有传入场景数据\r\n if (sceneData) {\r\n // 设置场景数据\r\n loadSceneFromJSON(sceneData.scene, mode);\r\n\r\n if (sceneData?.camera) {\r\n const camData = sceneData.camera;\r\n state.camera!.position.set(\r\n camData.position[0],\r\n camData.position[1],\r\n camData.position[2],\r\n );\r\n state.camera!.rotation.set(\r\n camData.rotation[0],\r\n camData.rotation[1],\r\n camData.rotation[2],\r\n );\r\n state.camera!.updateProjectionMatrix();\r\n cameraTarget = camData.target;\r\n }\r\n }\r\n\r\n initTransformControls(); // 初始化变换控制器(需在 OrbitControls 前,因为辅助对象要加入场景)\r\n initOrbitControls(); // 初始化轨道控制器\r\n\r\n // 如果有 target,恢复 OrbitControls 的目标并更新\r\n if (cameraTarget && state.orbitControls) {\r\n state.orbitControls.target.fromArray(cameraTarget);\r\n state.orbitControls.update();\r\n }\r\n\r\n refreshSceneObjects(); // 刷新顶层物体列表\r\n animate(); // 启动动画循环\r\n\r\n // 绑定事件(保存引用以便销毁时移除)\r\n clickHandler = (event: MouseEvent) => onMouseClick(event);\r\n resizeHandler = () => onResize();\r\n // 绑定事件\r\n if (mode === \"edit\") container.addEventListener(\"click\", clickHandler);\r\n window.addEventListener(\"resize\", resizeHandler);\r\n\r\n // 如果没有传入场景数据\r\n if (!sceneData) {\r\n addDefaultLightAndCube(); // 添加默认灯光和立方体(演示用)\r\n }\r\n\r\n if (mode === \"edit\") initGrid(); // 添加网格地板\r\n}\r\n\r\n/** 创建 WebGL 渲染器,设置尺寸和像素比 */\r\nfunction initRenderer() {\r\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\r\n renderer.setSize(state.container!.clientWidth, state.container!.clientHeight);\r\n // 限制像素比不超过 2,以平衡性能和显示效果\r\n renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));\r\n state.container!.appendChild(renderer.domElement);\r\n state.renderer = renderer;\r\n}\r\n\r\n/** 创建场景并命名(便于调试) */\r\nfunction initScene() {\r\n state.scene = new THREE.Scene();\r\n state.scene.name = \"sl_scene\";\r\n}\r\n\r\n/** 创建网格辅助对象(地板),不加入树形列表 */\r\nfunction initGrid() {\r\n const grid = new THREE.GridHelper(30, 30, 0x88aaff, 0x335588);\r\n grid.name = \"地板\";\r\n grid.userData.type = \"initFloor\";\r\n // 地板不可移动,故不设置 isMovable\r\n state.scene!.add(grid);\r\n state.gridHelper = grid;\r\n}\r\n\r\n/** 创建透视相机,设置初始位置 */\r\nfunction initCamera() {\r\n const container = state.container!;\r\n const aspect = container.clientWidth / container.clientHeight;\r\n const camera = new THREE.PerspectiveCamera(45, aspect, 0.1, 1000);\r\n camera.position.set(0, 6, 15);\r\n camera.lookAt(0, 0, 0);\r\n state.camera = camera;\r\n}\r\n\r\n/** 创建轨道控制器,允许用户旋转/平移/缩放视图 */\r\nfunction initOrbitControls() {\r\n const controls = new OrbitControls(state.camera!, state.renderer!.domElement);\r\n\r\n controls.minDistance = 0;\r\n controls.maxDistance = Infinity;\r\n // 监测操作是否改变了相机状态\r\n controls.addEventListener(\"start\", () => {\r\n orbitChanged = false;\r\n });\r\n controls.addEventListener(\"change\", () => {\r\n orbitChanged = true;\r\n });\r\n controls.addEventListener(\"end\", () => {\r\n // 如果相机发生了改变,则标记跳过下一次点击(避免拖拽后选中物体)\r\n if (orbitChanged) {\r\n skipNextClick = true;\r\n setTimeout(() => {\r\n skipNextClick = false;\r\n }, 200);\r\n }\r\n });\r\n state.orbitControls = controls;\r\n}\r\n\r\n/** 创建变换控制器,用于拖拽移动物体(平移模式) */\r\nfunction initTransformControls() {\r\n const controls = new TransformControls(\r\n state.camera!,\r\n state.renderer!.domElement,\r\n );\r\n // 拖拽变换控制器时,暂时禁用轨道控制器\r\n controls.addEventListener(\"dragging-changed\", (event: any) => {\r\n state.orbitControls!.enabled = !event.value;\r\n if (!event.value) {\r\n // 拖拽结束后,跳过下一次点击\r\n skipNextClick = true;\r\n setTimeout(() => {\r\n skipNextClick = false;\r\n }, 200);\r\n }\r\n });\r\n // 物体变换过程中(位置/旋转/缩放变化),触发外部回调以更新 UI\r\n controls.addEventListener(\"objectChange\", () => {\r\n if (onTransformChange && state.selectedObject) {\r\n onTransformChange(state.selectedObject);\r\n }\r\n });\r\n // 将变换控制器的辅助轴添加到场景\r\n state.scene!.add(controls.getHelper());\r\n state.transformControls = controls;\r\n}\r\n\r\n/** 添加默认的环境光、平行光和一个示例立方体 */\r\nfunction addDefaultLightAndCube() {\r\n // 环境光\r\n const ambient = new THREE.AmbientLight(0xffffff, 2);\r\n state.scene!.add(ambient);\r\n // 平行光\r\n const dirLight = new THREE.DirectionalLight(0xffffff, 3);\r\n dirLight.position.set(48, 104, 138);\r\n state.scene!.add(dirLight);\r\n\r\n // 默认立方体(方便演示)\r\n // const geo = new THREE.BoxGeometry(1, 1, 1);\r\n // const mat = new THREE.MeshStandardMaterial({ color: 0xffffff });\r\n // const cube = new THREE.Mesh(geo, mat);\r\n // cube.position.y = 1;\r\n // cube.userData.isMovable = true;\r\n // cube.name = \"默认立方体\";\r\n // addModel(cube, true);\r\n}\r\n//#endregion\r\n\r\n// ═══════════════════════════════════════════════════════════════════\r\n//#region 动画循环 & 窗口自适应\r\n// ═══════════════════════════════════════════════════════════════════\r\n\r\n/** 动画循环:更新 Tween 动画、轨道控制器,并渲染场景 */\r\nfunction animate() {\r\n animationId = requestAnimationFrame(animate);\r\n TWEEN.update(); // 更新补间动画(当前未使用,保留扩展)\r\n state.orbitControls?.update();\r\n state.renderer?.render(state.scene!, state.camera!);\r\n}\r\n\r\n/** 窗口大小变化时,自适应渲染尺寸和相机比例 */\r\nfunction onResize() {\r\n if (!state.container || !state.camera || !state.renderer) return;\r\n const width = state.container.clientWidth;\r\n const height = state.container.clientHeight;\r\n if (width === 0 || height === 0) return;\r\n state.camera.aspect = width / height;\r\n state.camera.updateProjectionMatrix();\r\n state.renderer.setSize(width, height);\r\n}\r\n//#endregion\r\n\r\n// ═══════════════════════════════════════════════════════════════════\r\n//#region 选中 / 取消选中\r\n// ═══════════════════════════════════════════════════════════════════\r\n\r\n/**\r\n * 选中场景中的一个物体,将其附着到变换控制器并显示平移轴\r\n * @param obj - 要选中的物体\r\n */\r\nexport function selectObject(obj: Object3D) {\r\n if (state.selectedObject === obj) return; // 已选中则忽略\r\n // 取消之前的附着\r\n if (state.selectedObject) {\r\n state.transformControls!.detach();\r\n }\r\n state.selectedObject = obj;\r\n state.transformControls!.attach(obj);\r\n state.transformControls!.setMode(\"translate\"); // 默认平移模式\r\n state.transformControls!.showX = true;\r\n state.transformControls!.showY = true;\r\n state.transformControls!.showZ = true;\r\n // 通知外部选中变化\r\n onSelectedChange?.(obj);\r\n}\r\n\r\n/** 取消选中:隐藏变换控制器,并通知外部 */\r\nfunction deselectObject() {\r\n if (state.selectedObject) {\r\n state.transformControls!.detach();\r\n state.selectedObject = null;\r\n onSelectedChange?.(null);\r\n }\r\n}\r\n//#endregion\r\n\r\n// ═══════════════════════════════════════════════════════════════════\r\n//#region 鼠标点击(射线拾取)\r\n// ═══════════════════════════════════════════════════════════════════\r\n\r\n/**\r\n * 鼠标点击事件处理:使用射线检测拾取场景中的可移动 Mesh,\r\n * 若点击到物体则选中它,否则取消选中\r\n */\r\nfunction onMouseClick(event: MouseEvent) {\r\n // 如果标记跳过本次点击(如拖拽刚结束),则忽略并重置标记\r\n if (skipNextClick) {\r\n skipNextClick = false;\r\n return;\r\n }\r\n // 计算鼠标位置归一化坐标\r\n const rect = state.renderer!.domElement.getBoundingClientRect();\r\n const mouse = new THREE.Vector2(\r\n ((event.clientX - rect.left) / rect.width) * 2 - 1,\r\n -((event.clientY - rect.top) / rect.height) * 2 + 1,\r\n );\r\n const raycaster = new THREE.Raycaster();\r\n raycaster.setFromCamera(mouse, state.camera!);\r\n\r\n // 收集场景中所有可点击的物体(isMovable 且为 Mesh)\r\n const clickables: Object3D[] = [];\r\n state.scene!.traverse((obj) => {\r\n if (obj.type === \"Mesh\" && obj.userData.isMovable) {\r\n clickables.push(obj);\r\n }\r\n });\r\n const intersects = raycaster.intersectObjects(clickables);\r\n if (intersects.length > 0) {\r\n selectObject(intersects[0].object);\r\n } else {\r\n deselectObject();\r\n }\r\n}\r\n//#endregion\r\n\r\n// ═══════════════════════════════════════════════════════════════════\r\n//#region 模型管理(增删改查)\r\n// ═══════════════════════════════════════════════════════════════════\r\n\r\n/**\r\n * 向场景添加一个模型(Object3D 及其子节点)\r\n * @param model - 要添加的模型对象\r\n * @param selected - 是否添加后立即选中\r\n */\r\nexport function addModel(model: Object3D, selected = false) {\r\n state.scene!.add(model);\r\n // 如果模型本身是可移动的,则加入顶层列表(但只有顶层对象才加入)\r\n if (model.userData.isMovable) {\r\n addObjectToTree(model);\r\n notifyChange();\r\n }\r\n if (selected && state.mode === \"edit\") selectObject(model);\r\n}\r\n\r\n/**\r\n * 从场景中移除一个模型及其子节点\r\n * @param model - 要移除的模型对象\r\n */\r\nexport function removeModel(model: Object3D) {\r\n if (state.selectedObject === model) deselectObject();\r\n // 从父节点移除(更通用),若没有父节点则从场景移除\r\n if (model.parent) {\r\n model.parent.remove(model);\r\n } else {\r\n state.scene!.remove(model);\r\n }\r\n // 如果该对象在顶层列表中,则移除\r\n removeObjectFromTree(model);\r\n notifyChange();\r\n}\r\n\r\n/**\r\n * 根据 UUID 删除场景中的物体\r\n * @param uuid - 物体的唯一标识符\r\n */\r\nexport function removeModelById(uuid: string) {\r\n const obj = state.scene!.getObjectByProperty(\"uuid\", uuid);\r\n if (obj) removeModel(obj);\r\n}\r\n\r\n// ─── 树形数据管理(仅顶层对象) ───\r\n\r\n/**\r\n * 将一个可移动物体加入顶层列表(前提是它是场景的直接子级)\r\n */\r\nfunction addObjectToTree(obj: Object3D) {\r\n if (obj.userData.isMovable && obj.parent === state.scene) {\r\n if (!sceneObjects.includes(obj)) {\r\n sceneObjects.push(obj);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * 从顶层列表中移除物体(如果存在)\r\n */\r\nfunction removeObjectFromTree(obj: Object3D) {\r\n const idx = sceneObjects.indexOf(obj);\r\n if (idx !== -1) sceneObjects.splice(idx, 1);\r\n}\r\n\r\n/** 全量刷新顶层物体列表(初始化时调用) */\r\nfunction refreshSceneObjects() {\r\n const list: Object3D[] = [];\r\n state.scene!.children.forEach((child) => {\r\n if (child.userData.isMovable) list.push(child);\r\n });\r\n sceneObjects = list;\r\n notifyChange();\r\n}\r\n\r\n/** 通知外部树形数据变化,传递列表副本以触发 shallowRef 更新 */\r\nfunction notifyChange() {\r\n onSceneObjectsChange?.([...sceneObjects]);\r\n}\r\n//#endregion\r\n\r\n// ═══════════════════════════════════════════════════════════════════\r\n//#region 回调注册\r\n// ═══════════════════════════════════════════════════════════════════\r\n\r\n/**\r\n * 注册选中物体变化的回调\r\n * @param cb - 回调函数,参数为当前选中的物体或 null\r\n */\r\nexport function setSelectedObjectCallback(cb: SelectedChangeCallback) {\r\n onSelectedChange = cb;\r\n}\r\n\r\n/**\r\n * 注册变换过程中(拖拽)的回调\r\n * @param cb - 回调函数,参数为正在变换的物体\r\n */\r\nexport function setTransformChangeCallback(cb: TransformChangeCallback) {\r\n onTransformChange = cb;\r\n}\r\n\r\n/**\r\n * 注册场景物体列表变化的回调\r\n * @param cb - 回调函数,参数为当前顶层物体列表\r\n */\r\nexport function onSceneObjectsChangeCallback(cb: SceneObjectsChangeCallback) {\r\n onSceneObjectsChange = cb;\r\n}\r\n\r\n/**\r\n * 获取当前顶层物体列表\r\n * @returns 顶层物体数组\r\n */\r\nexport function getSceneObjects() {\r\n return sceneObjects;\r\n}\r\n//#endregion\r\n\r\n// ═══════════════════════════════════════════════════════════════════\r\n//#region 场景导出导入\r\n// ═══════════════════════════════════════════════════════════════════\r\n\r\nexport function getScene() {\r\n return state.scene;\r\n}\r\nexport function getCamera() {\r\n return state.camera;\r\n}\r\nexport function getRenderer() {\r\n return state.renderer;\r\n}\r\n\r\n/**\r\n * 将当前 Three.js 场景导出为 JSON 数据(使用 Three.js 内置 toJSON)\r\n * @returns JSON 字符串\r\n */\r\nexport function exportSceneToJSON(): string {\r\n // 首先取消选中模型\r\n deselectObject();\r\n\r\n const scene = state.scene;\r\n if (!scene) return \"{}\";\r\n\r\n // 不需要初始化地板对象,创建一个临时场景副本\r\n let exportScene = scene;\r\n\r\n exportScene = scene.clone();\r\n // 移除初始化地板的对象\r\n exportScene.children = exportScene.children.filter(\r\n (child) => child.userData.type !== \"initFloor\",\r\n );\r\n\r\n // 场景 json\r\n const sceneJson = exportScene.toJSON();\r\n // 摄像机 json\r\n const cameraJson = {\r\n position: state.camera?.position.toArray(),\r\n rotation: state.camera?.rotation.toArray(),\r\n target: state.orbitControls?.target.toArray() || [0, 0, 0],\r\n };\r\n\r\n return JSON.stringify({ scene: sceneJson, camera: cameraJson });\r\n}\r\n\r\n/**\r\n * 从 JSON 数据恢复场景(使用 Three.js 内置 ObjectLoader)\r\n * @param json - JSON 字符串或对象\r\n * @returns 解析后的 Object3D 或 Scene\r\n */\r\nexport function loadSceneFromJSON(\r\n json: string | object,\r\n mode: string = \"edit\",\r\n) {\r\n const data = typeof json === \"string\" ? JSON.parse(json) : json;\r\n const loader = new THREE.ObjectLoader();\r\n const loaded = loader.parse(data);\r\n\r\n if (loaded.type === \"Scene\") {\r\n if (mode === \"run\") {\r\n }\r\n state.scene = loaded as THREE.Scene;\r\n } else {\r\n state.scene?.add(loaded);\r\n }\r\n}\r\n//#endregion\r\n\r\n// ═══════════════════════════════════════════════════════════════════\r\n//#region 销毁\r\n// ═══════════════════════════════════════════════════════════════════\r\n\r\n/**\r\n * 递归释放 Object3D 及其资源(几何体、材质、纹理)\r\n */\r\nfunction disposeObject(obj: THREE.Object3D) {\r\n if (!obj) return;\r\n\r\n // 处理 Mesh\r\n if (obj.type === \"Mesh\") {\r\n const mesh = obj as THREE.Mesh;\r\n if (mesh.geometry) {\r\n mesh.geometry.dispose();\r\n }\r\n if (mesh.material) {\r\n const materials = Array.isArray(mesh.material)\r\n ? mesh.material\r\n : [mesh.material];\r\n materials.forEach((mat: any) => {\r\n if (mat.map) mat.map = null;\r\n if (mat.lightMap) mat.lightMap = null;\r\n if (mat.aoMap) mat.aoMap = null;\r\n if (mat.emissiveMap) mat.emissiveMap = null;\r\n if (mat.bumpMap) mat.bumpMap = null;\r\n if (mat.normalMap) mat.normalMap = null;\r\n if (mat.displacementMap) mat.displacementMap = null;\r\n if (mat.roughnessMap) mat.roughnessMap = null;\r\n if (mat.metalnessMap) mat.metalnessMap = null;\r\n if (mat.alphaMap) mat.alphaMap = null;\r\n if (mat.envMap) mat.envMap = null;\r\n mat.dispose();\r\n });\r\n }\r\n }\r\n\r\n // 递归处理子对象\r\n const children = obj.children.slice();\r\n for (const child of children) {\r\n disposeObject(child);\r\n }\r\n}\r\n\r\n/**\r\n * 销毁编辑器,释放所有资源(场景、渲染器、控制器、事件监听等)\r\n * 调用后编辑器将完全卸载,可重新调用 initEditor 重新初始化\r\n */\r\nexport function destroyEditor() {\r\n // ─── 取消动画循环 ───\r\n if (animationId !== null) {\r\n cancelAnimationFrame(animationId);\r\n animationId = null;\r\n }\r\n\r\n // ─── 移除事件监听 ───\r\n if (clickHandler && state.container) {\r\n state.container.removeEventListener(\"click\", clickHandler);\r\n clickHandler = null;\r\n }\r\n if (resizeHandler) {\r\n window.removeEventListener(\"resize\", resizeHandler);\r\n resizeHandler = null;\r\n }\r\n\r\n // ─── 释放控制器 ───\r\n if (state.orbitControls) {\r\n state.orbitControls.dispose();\r\n state.orbitControls = null;\r\n }\r\n if (state.transformControls) {\r\n state.transformControls.dispose();\r\n state.transformControls = null;\r\n }\r\n\r\n // ─── 释放场景及所有物体 ───\r\n if (state.scene) {\r\n disposeObject(state.scene);\r\n state.scene = null;\r\n }\r\n\r\n // ─── 释放渲染器 ───\r\n if (state.renderer) {\r\n state.renderer.dispose();\r\n // 移除 DOM 元素\r\n if (state.renderer.domElement && state.container) {\r\n state.container.removeChild(state.renderer.domElement);\r\n }\r\n state.renderer = null;\r\n }\r\n\r\n // ─── 清空其他状态 ───\r\n state.camera = null;\r\n state.gridHelper = null;\r\n state.selectedObject = null;\r\n state.container = null;\r\n state.mode = \"\";\r\n\r\n // ─── 清空树形数据 ───\r\n sceneObjects = [];\r\n notifyChange();\r\n\r\n // ─── 重置标志 ───\r\n orbitChanged = false;\r\n skipNextClick = false;\r\n}\r\n","import {\n\tBufferGeometry,\n\tFileLoader,\n\tFloat32BufferAttribute,\n\tGroup,\n\tLineBasicMaterial,\n\tLineSegments,\n\tLoader,\n\tMaterial,\n\tMesh,\n\tMeshPhongMaterial,\n\tPoints,\n\tPointsMaterial,\n\tVector3,\n\tColor,\n\tSRGBColorSpace\n} from 'three';\n\n// o object_name | g group_name\nconst _object_pattern = /^[og]\\s*(.+)?/;\n// mtllib file_reference\nconst _material_library_pattern = /^mtllib /;\n// usemtl material_name\nconst _material_use_pattern = /^usemtl /;\n// usemap map_name\nconst _map_use_pattern = /^usemap /;\nconst _face_vertex_data_separator_pattern = /\\s+/;\n\nconst _vA = new Vector3();\nconst _vB = new Vector3();\nconst _vC = new Vector3();\n\nconst _ab = new Vector3();\nconst _cb = new Vector3();\n\nconst _color = new Color();\n\nfunction ParserState() {\n\n\tconst state = {\n\t\tobjects: [],\n\t\tobject: {},\n\n\t\tvertices: [],\n\t\tnormals: [],\n\t\tcolors: [],\n\t\tuvs: [],\n\n\t\tmaterials: {},\n\t\tmaterialLibraries: [],\n\n\t\tstartObject: function ( name, fromDeclaration ) {\n\n\t\t\t// If the current object (initial from reset) is not from a g/o declaration in the parsed\n\t\t\t// file. We need to use it for the first parsed g/o to keep things in sync.\n\t\t\tif ( this.object && this.object.fromDeclaration === false ) {\n\n\t\t\t\tthis.object.name = name;\n\t\t\t\tthis.object.fromDeclaration = ( fromDeclaration !== false );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tconst previousMaterial = ( this.object && typeof this.object.currentMaterial === 'function' ? this.object.currentMaterial() : undefined );\n\n\t\t\tif ( this.object && typeof this.object._finalize === 'function' ) {\n\n\t\t\t\tthis.object._finalize( true );\n\n\t\t\t}\n\n\t\t\tthis.object = {\n\t\t\t\tname: name || '',\n\t\t\t\tfromDeclaration: ( fromDeclaration !== false ),\n\n\t\t\t\tgeometry: {\n\t\t\t\t\tvertices: [],\n\t\t\t\t\tnormals: [],\n\t\t\t\t\tcolors: [],\n\t\t\t\t\tuvs: [],\n\t\t\t\t\thasUVIndices: false\n\t\t\t\t},\n\t\t\t\tmaterials: [],\n\t\t\t\tsmooth: true,\n\n\t\t\t\tstartMaterial: function ( name, libraries ) {\n\n\t\t\t\t\tconst previous = this._finalize( false );\n\n\t\t\t\t\t// New usemtl declaration overwrites an inherited material, except if faces were declared\n\t\t\t\t\t// after the material, then it must be preserved for proper MultiMaterial continuation.\n\t\t\t\t\tif ( previous && ( previous.inherited || previous.groupCount <= 0 ) ) {\n\n\t\t\t\t\t\tthis.materials.splice( previous.index, 1 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tconst material = {\n\t\t\t\t\t\tindex: this.materials.length,\n\t\t\t\t\t\tname: name || '',\n\t\t\t\t\t\tmtllib: ( Array.isArray( libraries ) && libraries.length > 0 ? libraries[ libraries.length - 1 ] : '' ),\n\t\t\t\t\t\tsmooth: ( previous !== undefined ? previous.smooth : this.smooth ),\n\t\t\t\t\t\tgroupStart: ( previous !== undefined ? previous.groupEnd : 0 ),\n\t\t\t\t\t\tgroupEnd: - 1,\n\t\t\t\t\t\tgroupCount: - 1,\n\t\t\t\t\t\tinherited: false,\n\n\t\t\t\t\t\tclone: function ( index ) {\n\n\t\t\t\t\t\t\tconst cloned = {\n\t\t\t\t\t\t\t\tindex: ( typeof index === 'number' ? index : this.index ),\n\t\t\t\t\t\t\t\tname: this.name,\n\t\t\t\t\t\t\t\tmtllib: this.mtllib,\n\t\t\t\t\t\t\t\tsmooth: this.smooth,\n\t\t\t\t\t\t\t\tgroupStart: 0,\n\t\t\t\t\t\t\t\tgroupEnd: - 1,\n\t\t\t\t\t\t\t\tgroupCount: - 1,\n\t\t\t\t\t\t\t\tinherited: false\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tcloned.clone = this.clone.bind( cloned );\n\t\t\t\t\t\t\treturn cloned;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\t\tthis.materials.push( material );\n\n\t\t\t\t\treturn material;\n\n\t\t\t\t},\n\n\t\t\t\tcurrentMaterial: function () {\n\n\t\t\t\t\tif ( this.materials.length > 0 ) {\n\n\t\t\t\t\t\treturn this.materials[ this.materials.length - 1 ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t},\n\n\t\t\t\t_finalize: function ( end ) {\n\n\t\t\t\t\tconst lastMultiMaterial = this.currentMaterial();\n\t\t\t\t\tif ( lastMultiMaterial && lastMultiMaterial.groupEnd === - 1 ) {\n\n\t\t\t\t\t\tlastMultiMaterial.groupEnd = this.geometry.vertices.length / 3;\n\t\t\t\t\t\tlastMultiMaterial.groupCount = lastMultiMaterial.groupEnd - lastMultiMaterial.groupStart;\n\t\t\t\t\t\tlastMultiMaterial.inherited = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Ignore objects tail materials if no face declarations followed them before a new o/g started.\n\t\t\t\t\tif ( end && this.materials.length > 1 ) {\n\n\t\t\t\t\t\tfor ( let mi = this.materials.length - 1; mi >= 0; mi -- ) {\n\n\t\t\t\t\t\t\tif ( this.materials[ mi ].groupCount <= 0 ) {\n\n\t\t\t\t\t\t\t\tthis.materials.splice( mi, 1 );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Guarantee at least one empty material, this makes the creation later more straight forward.\n\t\t\t\t\tif ( end && this.materials.length === 0 ) {\n\n\t\t\t\t\t\tthis.materials.push( {\n\t\t\t\t\t\t\tname: '',\n\t\t\t\t\t\t\tsmooth: this.smooth\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn lastMultiMaterial;\n\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// Inherit previous objects material.\n\t\t\t// Spec tells us that a declared material must be set to all objects until a new material is declared.\n\t\t\t// If a usemtl declaration is encountered while this new object is being parsed, it will\n\t\t\t// overwrite the inherited material. Exception being that there was already face declarations\n\t\t\t// to the inherited material, then it will be preserved for proper MultiMaterial continuation.\n\n\t\t\tif ( previousMaterial && previousMaterial.name && typeof previousMaterial.clone === 'function' ) {\n\n\t\t\t\tconst declared = previousMaterial.clone( 0 );\n\t\t\t\tdeclared.inherited = true;\n\t\t\t\tthis.object.materials.push( declared );\n\n\t\t\t}\n\n\t\t\tthis.objects.push( this.object );\n\n\t\t},\n\n\t\tfinalize: function () {\n\n\t\t\tif ( this.object && typeof this.object._finalize === 'function' ) {\n\n\t\t\t\tthis.object._finalize( true );\n\n\t\t\t}\n\n\t\t},\n\n\t\tparseVertexIndex: function ( value, len ) {\n\n\t\t\tconst index = parseInt( value, 10 );\n\t\t\treturn ( index >= 0 ? index - 1 : index + len / 3 ) * 3;\n\n\t\t},\n\n\t\tparseNormalIndex: function ( value, len ) {\n\n\t\t\tconst index = parseInt( value, 10 );\n\t\t\treturn ( index >= 0 ? index - 1 : index + len / 3 ) * 3;\n\n\t\t},\n\n\t\tparseUVIndex: function ( value, len ) {\n\n\t\t\tconst index = parseInt( value, 10 );\n\t\t\treturn ( index >= 0 ? index - 1 : index + len / 2 ) * 2;\n\n\t\t},\n\n\t\taddVertex: function ( a, b, c ) {\n\n\t\t\tconst src = this.vertices;\n\t\t\tconst dst = this.object.geometry.vertices;\n\n\t\t\tdst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );\n\t\t\tdst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] );\n\t\t\tdst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] );\n\n\t\t},\n\n\t\taddVertexPoint: function ( a ) {\n\n\t\t\tconst src = this.vertices;\n\t\t\tconst dst = this.object.geometry.vertices;\n\n\t\t\tdst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );\n\n\t\t},\n\n\t\taddVertexLine: function ( a ) {\n\n\t\t\tconst src = this.vertices;\n\t\t\tconst dst = this.object.geometry.vertices;\n\n\t\t\tdst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );\n\n\t\t},\n\n\t\taddNormal: function ( a, b, c ) {\n\n\t\t\tconst src = this.normals;\n\t\t\tconst dst = this.object.geometry.normals;\n\n\t\t\tdst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );\n\t\t\tdst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] );\n\t\t\tdst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] );\n\n\t\t},\n\n\t\taddFaceNormal: function ( a, b, c ) {\n\n\t\t\tconst src = this.vertices;\n\t\t\tconst dst = this.object.geometry.normals;\n\n\t\t\t_vA.fromArray( src, a );\n\t\t\t_vB.fromArray( src, b );\n\t\t\t_vC.fromArray( src, c );\n\n\t\t\t_cb.subVectors( _vC, _vB );\n\t\t\t_ab.subVectors( _vA, _vB );\n\t\t\t_cb.cross( _ab );\n\n\t\t\t_cb.normalize();\n\n\t\t\tdst.push( _cb.x, _cb.y, _cb.z );\n\t\t\tdst.push( _cb.x, _cb.y, _cb.z );\n\t\t\tdst.push( _cb.x, _cb.y, _cb.z );\n\n\t\t},\n\n\t\taddColor: function ( a, b, c ) {\n\n\t\t\tconst src = this.colors;\n\t\t\tconst dst = this.object.geometry.colors;\n\n\t\t\tif ( src[ a ] !== undefined ) dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );\n\t\t\tif ( src[ b ] !== undefined ) dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] );\n\t\t\tif ( src[ c ] !== undefined ) dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] );\n\n\t\t},\n\n\t\taddUV: function ( a, b, c ) {\n\n\t\t\tconst src = this.uvs;\n\t\t\tconst dst = this.object.geometry.uvs;\n\n\t\t\tdst.push( src[ a + 0 ], src[ a + 1 ] );\n\t\t\tdst.push( src[ b + 0 ], src[ b + 1 ] );\n\t\t\tdst.push( src[ c + 0 ], src[ c + 1 ] );\n\n\t\t},\n\n\t\taddDefaultUV: function () {\n\n\t\t\tconst dst = this.object.geometry.uvs;\n\n\t\t\tdst.push( 0, 0 );\n\t\t\tdst.push( 0, 0 );\n\t\t\tdst.push( 0, 0 );\n\n\t\t},\n\n\t\taddUVLine: function ( a ) {\n\n\t\t\tconst src = this.uvs;\n\t\t\tconst dst = this.object.geometry.uvs;\n\n\t\t\tdst.push( src[ a + 0 ], src[ a + 1 ] );\n\n\t\t},\n\n\t\taddFace: function ( a, b, c, ua, ub, uc, na, nb, nc ) {\n\n\t\t\tconst vLen = this.vertices.length;\n\n\t\t\tlet ia = this.parseVertexIndex( a, vLen );\n\t\t\tlet ib = this.parseVertexIndex( b, vLen );\n\t\t\tlet ic = this.parseVertexIndex( c, vLen );\n\n\t\t\tthis.addVertex( ia, ib, ic );\n\t\t\tthis.addColor( ia, ib, ic );\n\n\t\t\t// normals\n\n\t\t\tif ( na !== undefined && na !== '' ) {\n\n\t\t\t\tconst nLen = this.normals.length;\n\n\t\t\t\tia = this.parseNormalIndex( na, nLen );\n\t\t\t\tib = this.parseNormalIndex( nb, nLen );\n\t\t\t\tic = this.parseNormalIndex( nc, nLen );\n\n\t\t\t\tthis.addNormal( ia, ib, ic );\n\n\t\t\t} else {\n\n\t\t\t\tthis.addFaceNormal( ia, ib, ic );\n\n\t\t\t}\n\n\t\t\t// uvs\n\n\t\t\tif ( ua !== undefined && ua !== '' ) {\n\n\t\t\t\tconst uvLen = this.uvs.length;\n\n\t\t\t\tia = this.parseUVIndex( ua, uvLen );\n\t\t\t\tib = this.parseUVIndex( ub, uvLen );\n\t\t\t\tic = this.parseUVIndex( uc, uvLen );\n\n\t\t\t\tthis.addUV( ia, ib, ic );\n\n\t\t\t\tthis.object.geometry.hasUVIndices = true;\n\n\t\t\t} else {\n\n\t\t\t\t// add placeholder values (for inconsistent face definitions)\n\n\t\t\t\tthis.addDefaultUV();\n\n\t\t\t}\n\n\t\t},\n\n\t\taddPointGeometry: function ( vertices ) {\n\n\t\t\tthis.object.geometry.type = 'Points';\n\n\t\t\tconst vLen = this.vertices.length;\n\n\t\t\tfor ( let vi = 0, l = vertices.length; vi < l; vi ++ ) {\n\n\t\t\t\tconst index = this.parseVertexIndex( vertices[ vi ], vLen );\n\n\t\t\t\tthis.addVertexPoint( index );\n\t\t\t\tthis.addColor( index );\n\n\t\t\t}\n\n\t\t},\n\n\t\taddLineGeometry: function ( vertices, uvs ) {\n\n\t\t\tthis.object.geometry.type = 'Line';\n\n\t\t\tconst vLen = this.vertices.length;\n\t\t\tconst uvLen = this.uvs.length;\n\n\t\t\tfor ( let vi = 0, l = vertices.length; vi < l; vi ++ ) {\n\n\t\t\t\tthis.addVertexLine( this.parseVertexIndex( vertices[ vi ], vLen ) );\n\n\t\t\t}\n\n\t\t\tfor ( let uvi = 0, l = uvs.length; uvi < l; uvi ++ ) {\n\n\t\t\t\tthis.addUVLine( this.parseUVIndex( uvs[ uvi ], uvLen ) );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tstate.startObject( '', false );\n\n\treturn state;\n\n}\n\n\n/**\n * A loader for the OBJ format.\n *\n * The [OBJ format](https://en.wikipedia.org/wiki/Wavefront_.obj_file) is a simple data-format that\n * represents 3D geometry in a human readable format as the position of each vertex, the UV position of\n * each texture coordinate vertex, vertex normals, and the faces that make each polygon defined as a list\n * of vertices, and texture vertices.\n *\n * ```js\n * const loader = new OBJLoader();\n * const object = await loader.loadAsync( 'models/monster.obj' );\n * scene.add( object );\n * ```\n *\n * @augments Loader\n * @three_import import { OBJLoader } from 'three/addons/loaders/OBJLoader.js';\n */\nclass OBJLoader extends Loader {\n\n\t/**\n\t * Constructs a new OBJ loader.\n\t *\n\t * @param {LoadingManager} [manager] - The loading manager.\n\t */\n\tconstructor( manager ) {\n\n\t\tsuper( manager );\n\n\t\t/**\n\t\t * A reference to a material creator.\n\t\t *\n\t\t * @type {?MaterialCreator}\n\t\t * @default null\n\t\t */\n\t\tthis.materials = null;\n\n\t}\n\n\t/**\n\t * Starts loading from the given URL and passes the loaded OBJ asset\n\t * to the `onLoad()` callback.\n\t *\n\t * @param {string} url - The path/URL of the file to be loaded. This can also be a data URI.\n\t * @param {function(Group)} onLoad - Executed when the loading process has been finished.\n\t * @param {onProgressCallback} onProgress - Executed while the loading is in progress.\n\t * @param {onErrorCallback} onError - Executed when errors occur.\n\t */\n\tload( url, onLoad, onProgress, onError ) {\n\n\t\tconst scope = this;\n\n\t\tconst loader = new FileLoader( this.manager );\n\t\tloader.setPath( this.path );\n\t\tloader.setRequestHeader( this.requestHeader );\n\t\tloader.setWithCredentials( this.withCredentials );\n\t\tloader.load( url, function ( text ) {\n\n\t\t\ttry {\n\n\t\t\t\tonLoad( scope.parse( text ) );\n\n\t\t\t} catch ( e ) {\n\n\t\t\t\tif ( onError ) {\n\n\t\t\t\t\tonError( e );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.error( e );\n\n\t\t\t\t}\n\n\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t}\n\n\t\t}, onProgress, onError );\n\n\t}\n\n\t/**\n\t * Sets the material creator for this OBJ. This object is loaded via {@link MTLLoader}.\n\t *\n\t * @param {MaterialCreator} materials - An object that creates the materials for this OBJ.\n\t * @return {OBJLoader} A reference to this loader.\n\t */\n\tsetMaterials( materials ) {\n\n\t\tthis.materials = materials;\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * Parses the given OBJ data and returns the resulting group.\n\t *\n\t * @param {string} text - The raw OBJ data as a string.\n\t * @return {Group} The parsed OBJ.\n\t */\n\tparse( text ) {\n\n\t\tconst state = new ParserState();\n\n\t\tif ( text.indexOf( '\\r\\n' ) !== - 1 ) {\n\n\t\t\t// This is faster than String.split with regex that splits on both\n\t\t\ttext = text.replace( /\\r\\n/g, '\\n' );\n\n\t\t}\n\n\t\tif ( text.indexOf( '\\\\\\n' ) !== - 1 ) {\n\n\t\t\t// join lines separated by a line continuation character (\\)\n\t\t\ttext = text.replace( /\\\\\\n/g, '' );\n\n\t\t}\n\n\t\tconst lines = text.split( '\\n' );\n\t\tlet result = [];\n\n\t\tfor ( let i = 0, l = lines.length; i < l; i ++ ) {\n\n\t\t\tconst line = lines[ i ].trimStart();\n\n\t\t\tif ( line.length === 0 ) continue;\n\n\t\t\tconst lineFirstChar = line.charAt( 0 );\n\n\t\t\t// @todo invoke passed in handler if any\n\t\t\tif ( lineFirstChar === '#' ) continue; // skip comments\n\n\t\t\tif ( lineFirstChar === 'v' ) {\n\n\t\t\t\tconst data = line.split( _face_vertex_data_separator_pattern );\n\n\t\t\t\tswitch ( data[ 0 ] ) {\n\n\t\t\t\t\tcase 'v':\n\t\t\t\t\t\tstate.vertices.push(\n\t\t\t\t\t\t\tparseFloat( data[ 1 ] ),\n\t\t\t\t\t\t\tparseFloat( data[ 2 ] ),\n\t\t\t\t\t\t\tparseFloat( data[ 3 ] )\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif ( data.length >= 7 ) {\n\n\t\t\t\t\t\t\t_color.setRGB(\n\t\t\t\t\t\t\t\tparseFloat( data[ 4 ] ),\n\t\t\t\t\t\t\t\tparseFloat( data[ 5 ] ),\n\t\t\t\t\t\t\t\tparseFloat( data[ 6 ] ),\n\t\t\t\t\t\t\t\tSRGBColorSpace\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tstate.colors.push( _color.r, _color.g, _color.b );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// if no colors are defined, add placeholders so color and vertex indices match\n\n\t\t\t\t\t\t\tstate.colors.push( undefined, undefined, undefined );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'vn':\n\t\t\t\t\t\tstate.normals.push(\n\t\t\t\t\t\t\tparseFloat( data[ 1 ] ),\n\t\t\t\t\t\t\tparseFloat( data[ 2 ] ),\n\t\t\t\t\t\t\tparseFloat( data[ 3 ] )\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'vt':\n\t\t\t\t\t\tstate.uvs.push(\n\t\t\t\t\t\t\tparseFloat( data[ 1 ] ),\n\t\t\t\t\t\t\tparseFloat( data[ 2 ] )\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t} else if ( lineFirstChar === 'f' ) {\n\n\t\t\t\tconst lineData = line.slice( 1 ).trim();\n\t\t\t\tconst vertexData = lineData.split( _face_vertex_data_separator_pattern );\n\t\t\t\tconst faceVertices = [];\n\n\t\t\t\t// Parse the face vertex data into an easy to work with format\n\n\t\t\t\tfor ( let j = 0, jl = vertexData.length; j < jl; j ++ ) {\n\n\t\t\t\t\tconst vertex = vertexData[ j ];\n\n\t\t\t\t\tif ( vertex.length > 0 ) {\n\n\t\t\t\t\t\tconst vertexParts = vertex.split( '/' );\n\t\t\t\t\t\tfaceVertices.push( vertexParts );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// Draw an edge between the first vertex and all subsequent vertices to form an n-gon\n\n\t\t\t\tconst v1 = faceVertices[ 0 ];\n\n\t\t\t\tfor ( let j = 1, jl = faceVertices.length - 1; j < jl; j ++ ) {\n\n\t\t\t\t\tconst v2 = faceVertices[ j ];\n\t\t\t\t\tconst v3 = faceVertices[ j + 1 ];\n\n\t\t\t\t\tstate.addFace(\n\t\t\t\t\t\tv1[ 0 ], v2[ 0 ], v3[ 0 ],\n\t\t\t\t\t\tv1[ 1 ], v2[ 1 ], v3[ 1 ],\n\t\t\t\t\t\tv1[ 2 ], v2[ 2 ], v3[ 2 ]\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t} else if ( lineFirstChar === 'l' ) {\n\n\t\t\t\tconst lineParts = line.substring( 1 ).trim().split( ' ' );\n\t\t\t\tlet lineVertices = [];\n\t\t\t\tconst lineUVs = [];\n\n\t\t\t\tif ( line.indexOf( '/' ) === - 1 ) {\n\n\t\t\t\t\tlineVertices = lineParts;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( let li = 0, llen = lineParts.length; li < llen; li ++ ) {\n\n\t\t\t\t\t\tconst parts = lineParts[ li ].split( '/' );\n\n\t\t\t\t\t\tif ( parts[ 0 ] !== '' ) lineVertices.push( parts[ 0 ] );\n\t\t\t\t\t\tif ( parts[ 1 ] !== '' ) lineUVs.push( parts[ 1 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tstate.addLineGeometry( lineVertices, lineUVs );\n\n\t\t\t} else if ( lineFirstChar === 'p' ) {\n\n\t\t\t\tconst lineData = line.slice( 1 ).trim();\n\t\t\t\tconst pointData = lineData.split( ' ' );\n\n\t\t\t\tstate.addPointGeometry( pointData );\n\n\t\t\t} else if ( ( result = _object_pattern.exec( line ) ) !== null ) {\n\n\t\t\t\t// o object_name\n\t\t\t\t// or\n\t\t\t\t// g group_name\n\n\t\t\t\t// WORKAROUND: https://bugs.chromium.org/p/v8/issues/detail?id=2869\n\t\t\t\t// let name = result[ 0 ].slice( 1 ).trim();\n\t\t\t\tconst name = ( ' ' + result[ 0 ].slice( 1 ).trim() ).slice( 1 );\n\n\t\t\t\tstate.startObject( name );\n\n\t\t\t} else if ( _material_use_pattern.test( line ) ) {\n\n\t\t\t\t// material\n\n\t\t\t\tstate.object.startMaterial( line.substring( 7 ).trim(), state.materialLibraries );\n\n\t\t\t} else if ( _material_library_pattern.test( line ) ) {\n\n\t\t\t\t// mtl file\n\n\t\t\t\tstate.materialLibraries.push( line.substring( 7 ).trim() );\n\n\t\t\t} else if ( _map_use_pattern.test( line ) ) {\n\n\t\t\t\t// the line is parsed but ignored since the loader assumes textures are defined MTL files\n\t\t\t\t// (according to https://www.okino.com/conv/imp_wave.htm, 'usemap' is the old-style Wavefront texture reference method)\n\n\t\t\t\tconsole.warn( 'THREE.OBJLoader: Rendering identifier \"usemap\" not supported. Textures must be defined in MTL files.' );\n\n\t\t\t} else if ( lineFirstChar === 's' ) {\n\n\t\t\t\tresult = line.split( ' ' );\n\n\t\t\t\t// smooth shading\n\n\t\t\t\t// @todo Handle files that have varying smooth values for a set of faces inside one geometry,\n\t\t\t\t// but does not define a usemtl for each face set.\n\t\t\t\t// This should be detected and a dummy material created (later MultiMaterial and geometry groups).\n\t\t\t\t// This requires some care to not create extra material on each smooth value for \"normal\" obj files.\n\t\t\t\t// where explicit usemtl defines geometry groups.\n\t\t\t\t// Example asset: examples/models/obj/cerberus/Cerberus.obj\n\n\t\t\t\t/*\n\t\t\t\t\t * http://paulbourke.net/dataformats/obj/\n\t\t\t\t\t *\n\t\t\t\t\t * From chapter \"Grouping\" Syntax explanation \"s group_number\":\n\t\t\t\t\t * \"group_number is the smoothing group number. To turn off smoothing groups, use a value of 0 or off.\n\t\t\t\t\t * Polygonal elements use group numbers to put elements in different smoothing groups. For free-form\n\t\t\t\t\t * surfaces, smoothing groups are either turned on or off; there is no difference between values greater\n\t\t\t\t\t * than 0.\"\n\t\t\t\t\t */\n\t\t\t\tif ( result.length > 1 ) {\n\n\t\t\t\t\tconst value = result[ 1 ].trim().toLowerCase();\n\t\t\t\t\tstate.object.smooth = ( value !== '0' && value !== 'off' );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// ZBrush can produce \"s\" lines #11707\n\t\t\t\t\tstate.object.smooth = true;\n\n\t\t\t\t}\n\n\t\t\t\tconst material = state.object.currentMaterial();\n\t\t\t\tif ( material ) material.smooth = state.object.smooth;\n\n\t\t\t} else {\n\n\t\t\t\t// Handle null terminated files without exception\n\t\t\t\tif ( line === '\\0' ) continue;\n\n\t\t\t\tconsole.warn( 'THREE.OBJLoader: Unexpected line: \"' + line + '\"' );\n\n\t\t\t}\n\n\t\t}\n\n\t\tstate.finalize();\n\n\t\tconst container = new Group();\n\t\tcontainer.materialLibraries = [].concat( state.materialLibraries );\n\n\t\tconst hasPrimitives = ! ( state.objects.length === 1 && state.objects[ 0 ].geometry.vertices.length === 0 );\n\n\t\tif ( hasPrimitives === true ) {\n\n\t\t\tfor ( let i = 0, l = state.objects.length; i < l; i ++ ) {\n\n\t\t\t\tconst object = state.objects[ i ];\n\t\t\t\tconst geometry = object.geometry;\n\t\t\t\tconst materials = object.materials;\n\t\t\t\tconst isLine = ( geometry.type === 'Line' );\n\t\t\t\tconst isPoints = ( geometry.type === 'Points' );\n\t\t\t\tlet hasVertexColors = false;\n\n\t\t\t\t// Skip o/g line declarations that did not follow with any faces\n\t\t\t\tif ( geometry.vertices.length === 0 ) continue;\n\n\t\t\t\tconst buffergeometry = new BufferGeometry();\n\n\t\t\t\tbuffergeometry.setAttribute( 'position', new Float32BufferAttribute( geometry.vertices, 3 ) );\n\n\t\t\t\tif ( geometry.normals.length > 0 ) {\n\n\t\t\t\t\tbuffergeometry.setAttribute( 'normal', new Float32BufferAttribute( geometry.normals, 3 ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.colors.length > 0 ) {\n\n\t\t\t\t\thasVertexColors = true;\n\t\t\t\t\tbuffergeometry.setAttribute( 'color', new Float32BufferAttribute( geometry.colors, 3 ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.hasUVIndices === true ) {\n\n\t\t\t\t\tbuffergeometry.setAttribute( 'uv', new Float32BufferAttribute( geometry.uvs, 2 ) );\n\n\t\t\t\t}\n\n\t\t\t\t// Create materials\n\n\t\t\t\tconst createdMaterials = [];\n\n\t\t\t\tfor ( let mi = 0, miLen = materials.length; mi < miLen; mi ++ ) {\n\n\t\t\t\t\tconst sourceMaterial = materials[ mi ];\n\t\t\t\t\tconst materialHash = sourceMaterial.name + '_' + sourceMaterial.smooth + '_' + hasVertexColors;\n\t\t\t\t\tlet material = state.materials[ materialHash ];\n\n\t\t\t\t\tif ( this.materials !== null ) {\n\n\t\t\t\t\t\tmaterial = this.materials.create( sourceMaterial.name );\n\n\t\t\t\t\t\t// mtl etc. loaders probably can't create line materials correctly, copy properties to a line material.\n\t\t\t\t\t\tif ( isLine && material && ! ( material instanceof LineBasicMaterial ) ) {\n\n\t\t\t\t\t\t\tconst materialLine = new LineBasicMaterial();\n\t\t\t\t\t\t\tMaterial.prototype.copy.call( materialLine, material );\n\t\t\t\t\t\t\tmaterialLine.color.copy( material.color );\n\t\t\t\t\t\t\tmaterial = materialLine;\n\n\t\t\t\t\t\t} else if ( isPoints && material && ! ( material instanceof PointsMaterial ) ) {\n\n\t\t\t\t\t\t\tconst materialPoints = new PointsMaterial( { size: 10, sizeAttenuation: false } );\n\t\t\t\t\t\t\tMaterial.prototype.copy.call( materialPoints, material );\n\t\t\t\t\t\t\tmaterialPoints.color.copy( material.color );\n\t\t\t\t\t\t\tmaterialPoints.map = material.map;\n\t\t\t\t\t\t\tmaterial = materialPoints;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( material === undefined ) {\n\n\t\t\t\t\t\tif ( isLine ) {\n\n\t\t\t\t\t\t\tmaterial = new LineBasicMaterial();\n\n\t\t\t\t\t\t} else if ( isPoints ) {\n\n\t\t\t\t\t\t\tmaterial = new PointsMaterial( { size: 1, sizeAttenuation: false } );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tmaterial = new MeshPhongMaterial();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tmaterial.name = sourceMaterial.name;\n\t\t\t\t\t\tmaterial.flatShading = sourceMaterial.smooth ? false : true;\n\t\t\t\t\t\tmaterial.vertexColors = hasVertexColors;\n\n\t\t\t\t\t\tstate.materials[ materialHash ] = material;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tcreatedMaterials.push( material );\n\n\t\t\t\t}\n\n\t\t\t\t// Create mesh\n\n\t\t\t\tlet mesh;\n\n\t\t\t\tif ( createdMaterials.length > 1 ) {\n\n\t\t\t\t\tfor ( let mi = 0, miLen = materials.length; mi < miLen; mi ++ ) {\n\n\t\t\t\t\t\tconst sourceMaterial = materials[ mi ];\n\t\t\t\t\t\tbuffergeometry.addGroup( sourceMaterial.groupStart, sourceMaterial.groupCount, mi );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( isLine ) {\n\n\t\t\t\t\t\tmesh = new LineSegments( buffergeometry, createdMaterials );\n\n\t\t\t\t\t} else if ( isPoints ) {\n\n\t\t\t\t\t\tmesh = new Points( buffergeometry, createdMaterials );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tmesh = new Mesh( buffergeometry, createdMaterials );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( isLine ) {\n\n\t\t\t\t\t\tmesh = new LineSegments( buffergeometry, createdMaterials[ 0 ] );\n\n\t\t\t\t\t} else if ( isPoints ) {\n\n\t\t\t\t\t\tmesh = new Points( buffergeometry, createdMaterials[ 0 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tmesh = new Mesh( buffergeometry, createdMaterials[ 0 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tmesh.name = object.name;\n\n\t\t\t\tcontainer.add( mesh );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// if there is only the default parser state object with no geometry data, interpret data as point cloud\n\n\t\t\tif ( state.vertices.length > 0 ) {\n\n\t\t\t\tconst material = new PointsMaterial( { size: 1, sizeAttenuation: false } );\n\n\t\t\t\tconst buffergeometry = new BufferGeometry();\n\n\t\t\t\tbuffergeometry.setAttribute( 'position', new Float32BufferAttribute( state.vertices, 3 ) );\n\n\t\t\t\tif ( state.colors.length > 0 && state.colors[ 0 ] !== undefined ) {\n\n\t\t\t\t\tbuffergeometry.setAttribute( 'color', new Float32BufferAttribute( state.colors, 3 ) );\n\t\t\t\t\tmaterial.vertexColors = true;\n\n\t\t\t\t}\n\n\t\t\t\tconst points = new Points( buffergeometry, material );\n\t\t\t\tcontainer.add( points );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn container;\n\n\t}\n\n}\n\nexport { OBJLoader };\n","import {\n\tBufferAttribute,\n\tBufferGeometry,\n\tFloat32BufferAttribute,\n\tInstancedBufferAttribute,\n\tInterleavedBuffer,\n\tInterleavedBufferAttribute,\n\tTriangleFanDrawMode,\n\tTriangleStripDrawMode,\n\tTrianglesDrawMode,\n\tVector3,\n} from 'three';\n\n/**\n * @module BufferGeometryUtils\n * @three_import import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js';\n */\n\n/**\n * Computes vertex tangents using the MikkTSpace algorithm. MikkTSpace generates the same tangents consistently,\n * and is used in most modelling tools and normal map bakers. Use MikkTSpace for materials with normal maps,\n * because inconsistent tangents may lead to subtle visual issues in the normal map, particularly around mirrored\n * UV seams.\n *\n * In comparison to this method, {@link BufferGeometry#computeTangents} (a custom algorithm) generates tangents that\n * probably will not match the tangents in other software. The custom algorithm is sufficient for general use with a\n * custom material, and may be faster than MikkTSpace.\n *\n * Returns the original BufferGeometry. Indexed geometries will be de-indexed. Requires position, normal, and uv attributes.\n *\n * @param {BufferGeometry} geometry - The geometry to compute tangents for.\n * @param {Object} MikkTSpace - Instance of `examples/jsm/libs/mikktspace.module.js`, or `mikktspace` npm package.\n * Await `MikkTSpace.ready` before use.\n * @param {boolean} [negateSign=true] - Whether to negate the sign component (.w) of each tangent.\n * Required for normal map conventions in some formats, including glTF.\n * @return {BufferGeometry} The updated geometry.\n */\nfunction computeMikkTSpaceTangents( geometry, MikkTSpace, negateSign = true ) {\n\n\tif ( ! MikkTSpace || ! MikkTSpace.isReady ) {\n\n\t\tthrow new Error( 'BufferGeometryUtils: Initialized MikkTSpace library required.' );\n\n\t}\n\n\tif ( ! geometry.hasAttribute( 'position' ) || ! geometry.hasAttribute( 'normal' ) || ! geometry.hasAttribute( 'uv' ) ) {\n\n\t\tthrow new Error( 'BufferGeometryUtils: Tangents require \"position\", \"normal\", and \"uv\" attributes.' );\n\n\t}\n\n\tfunction getAttributeArray( attribute ) {\n\n\t\tif ( attribute.normalized || attribute.isInterleavedBufferAttribute ) {\n\n\t\t\tconst dstArray = new Float32Array( attribute.count * attribute.itemSize );\n\n\t\t\tfor ( let i = 0, j = 0; i < attribute.count; i ++ ) {\n\n\t\t\t\tdstArray[ j ++ ] = attribute.getX( i );\n\t\t\t\tdstArray[ j ++ ] = attribute.getY( i );\n\n\t\t\t\tif ( attribute.itemSize > 2 ) {\n\n\t\t\t\t\tdstArray[ j ++ ] = attribute.getZ( i );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn dstArray;\n\n\t\t}\n\n\t\tif ( attribute.array instanceof Float32Array ) {\n\n\t\t\treturn attribute.array;\n\n\t\t}\n\n\t\treturn new Float32Array( attribute.array );\n\n\t}\n\n\t// MikkTSpace algorithm requires non-indexed input.\n\n\tconst _geometry = geometry.index ? geometry.toNonIndexed() : geometry;\n\n\t// Compute vertex tangents.\n\n\tconst tangents = MikkTSpace.generateTangents(\n\n\t\tgetAttributeArray( _geometry.attributes.position ),\n\t\tgetAttributeArray( _geometry.attributes.normal ),\n\t\tgetAttributeArray( _geometry.attributes.uv )\n\n\t);\n\n\t// Texture coordinate convention of glTF differs from the apparent\n\t// default of the MikkTSpace library; .w component must be flipped.\n\n\tif ( negateSign ) {\n\n\t\tfor ( let i = 3; i < tangents.length; i += 4 ) {\n\n\t\t\ttangents[ i ] *= - 1;\n\n\t\t}\n\n\t}\n\n\t//\n\n\t_geometry.setAttribute( 'tangent', new BufferAttribute( tangents, 4 ) );\n\n\tif ( geometry !== _geometry ) {\n\n\t\tgeometry.copy( _geometry );\n\n\t}\n\n\treturn geometry;\n\n}\n\n/**\n * Merges a set of geometries into a single instance. All geometries must have compatible attributes.\n *\n * @param {Array<BufferGeometry>} geometries - The geometries to merge.\n * @param {boolean} [useGroups=false] - Whether to use groups or not.\n * @return {?BufferGeometry} The merged geometry. Returns `null` if the merge does not succeed.\n */\nfunction mergeGeometries( geometries, useGroups = false ) {\n\n\tconst isIndexed = geometries[ 0 ].index !== null;\n\n\tconst attributesUsed = new Set( Object.keys( geometries[ 0 ].attributes ) );\n\tconst morphAttributesUsed = new Set( Object.keys( geometries[ 0 ].morphAttributes ) );\n\n\tconst attributes = {};\n\tconst morphAttributes = {};\n\n\tconst morphTargetsRelative = geometries[ 0 ].morphTargetsRelative;\n\n\tconst mergedGeometry = new BufferGeometry();\n\n\tlet offset = 0;\n\n\tfor ( let i = 0; i < geometries.length; ++ i ) {\n\n\t\tconst geometry = geometries[ i ];\n\t\tlet attributesCount = 0;\n\n\t\t// ensure that all geometries are indexed, or none\n\n\t\tif ( isIndexed !== ( geometry.index !== null ) ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them.' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\t// gather attributes, exit early if they're different\n\n\t\tfor ( const name in geometry.attributes ) {\n\n\t\t\tif ( ! attributesUsed.has( name ) ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. All geometries must have compatible attributes; make sure \"' + name + '\" attribute exists among all geometries, or in none of them.' );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tif ( attributes[ name ] === undefined ) attributes[ name ] = [];\n\n\t\t\tattributes[ name ].push( geometry.attributes[ name ] );\n\n\t\t\tattributesCount ++;\n\n\t\t}\n\n\t\t// ensure geometries have the same number of attributes\n\n\t\tif ( attributesCount !== attributesUsed.size ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. Make sure all geometries have the same number of attributes.' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\t// gather morph attributes, exit early if they're different\n\n\t\tif ( morphTargetsRelative !== geometry.morphTargetsRelative ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. .morphTargetsRelative must be consistent throughout all geometries.' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\tfor ( const name in geometry.morphAttributes ) {\n\n\t\t\tif ( ! morphAttributesUsed.has( name ) ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. .morphAttributes must be consistent throughout all geometries.' );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tif ( morphAttributes[ name ] === undefined ) morphAttributes[ name ] = [];\n\n\t\t\tmorphAttributes[ name ].push( geometry.morphAttributes[ name ] );\n\n\t\t}\n\n\t\tif ( useGroups ) {\n\n\t\t\tlet count;\n\n\t\t\tif ( isIndexed ) {\n\n\t\t\t\tcount = geometry.index.count;\n\n\t\t\t} else if ( geometry.attributes.position !== undefined ) {\n\n\t\t\t\tcount = geometry.attributes.position.count;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. The geometry must have either an index or a position attribute' );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tmergedGeometry.addGroup( offset, count, i );\n\n\t\t\toffset += count;\n\n\t\t}\n\n\t}\n\n\t// merge indices\n\n\tif ( isIndexed ) {\n\n\t\tlet indexOffset = 0;\n\t\tconst mergedIndex = [];\n\n\t\tfor ( let i = 0; i < geometries.length; ++ i ) {\n\n\t\t\tconst index = geometries[ i ].index;\n\n\t\t\tfor ( let j = 0; j < index.count; ++ j ) {\n\n\t\t\t\tmergedIndex.push( index.getX( j ) + indexOffset );\n\n\t\t\t}\n\n\t\t\tindexOffset += geometries[ i ].attributes.position.count;\n\n\t\t}\n\n\t\tmergedGeometry.setIndex( mergedIndex );\n\n\t}\n\n\t// merge attributes\n\n\tfor ( const name in attributes ) {\n\n\t\tconst mergedAttribute = mergeAttributes( attributes[ name ] );\n\n\t\tif ( ! mergedAttribute ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the ' + name + ' attribute.' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\tmergedGeometry.setAttribute( name, mergedAttribute );\n\n\t}\n\n\t// merge morph attributes\n\n\tfor ( const name in morphAttributes ) {\n\n\t\tconst numMorphTargets = morphAttributes[ name ][ 0 ].length;\n\t\tif ( numMorphTargets === 0 ) continue;\n\n\t\tmergedGeometry.morphAttributes = mergedGeometry.morphAttributes || {};\n\t\tmergedGeometry.morphAttributes[ name ] = [];\n\n\t\tfor ( let i = 0; i < numMorphTargets; ++ i ) {\n\n\t\t\tconst morphAttributesToMerge = [];\n\n\t\t\tfor ( let j = 0; j < morphAttributes[ name ].length; ++ j ) {\n\n\t\t\t\tmorphAttributesToMerge.push( morphAttributes[ name ][ j ][ i ] );\n\n\t\t\t}\n\n\t\t\tconst mergedMorphAttribute = mergeAttributes( morphAttributesToMerge );\n\n\t\t\tif ( ! mergedMorphAttribute ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the ' + name + ' morphAttribute.' );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tmergedGeometry.morphAttributes[ name ].push( mergedMorphAttribute );\n\n\t\t}\n\n\t}\n\n\treturn mergedGeometry;\n\n}\n\n/**\n * Merges a set of attributes into a single instance. All attributes must have compatible properties and types.\n * Instances of {@link InterleavedBufferAttribute} are not supported.\n *\n * @param {Array<BufferAttribute>} attributes - The attributes to merge.\n * @return {?BufferAttribute} The merged attribute. Returns `null` if the merge does not succeed.\n */\nfunction mergeAttributes( attributes ) {\n\n\tlet TypedArray;\n\tlet itemSize;\n\tlet normalized;\n\tlet gpuType = - 1;\n\tlet arrayLength = 0;\n\n\tfor ( let i = 0; i < attributes.length; ++ i ) {\n\n\t\tconst attribute = attributes[ i ];\n\n\t\tif ( TypedArray === undefined ) TypedArray = attribute.array.constructor;\n\t\tif ( TypedArray !== attribute.array.constructor ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.array must be of consistent array types across matching attributes.' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\tif ( itemSize === undefined ) itemSize = attribute.itemSize;\n\t\tif ( itemSize !== attribute.itemSize ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.itemSize must be consistent across matching attributes.' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\tif ( normalized === undefined ) normalized = attribute.normalized;\n\t\tif ( normalized !== attribute.normalized ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.normalized must be consistent across matching attributes.' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\tif ( gpuType === - 1 ) gpuType = attribute.gpuType;\n\t\tif ( gpuType !== attribute.gpuType ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.gpuType must be consistent across matching attributes.' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\tarrayLength += attribute.count * itemSize;\n\n\t}\n\n\tconst array = new TypedArray( arrayLength );\n\tconst result = new BufferAttribute( array, itemSize, normalized );\n\tlet offset = 0;\n\n\tfor ( let i = 0; i < attributes.length; ++ i ) {\n\n\t\tconst attribute = attributes[ i ];\n\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\tconst tupleOffset = offset / itemSize;\n\t\t\tfor ( let j = 0, l = attribute.count; j < l; j ++ ) {\n\n\t\t\t\tfor ( let c = 0; c < itemSize; c ++ ) {\n\n\t\t\t\t\tconst value = attribute.getComponent( j, c );\n\t\t\t\t\tresult.setComponent( j + tupleOffset, c, value );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tarray.set( attribute.array, offset );\n\n\t\t}\n\n\t\toffset += attribute.count * itemSize;\n\n\t}\n\n\tif ( gpuType !== undefined ) {\n\n\t\tresult.gpuType = gpuType;\n\n\t}\n\n\treturn result;\n\n}\n\n/**\n * Performs a deep clone of the given buffer attribute.\n *\n * @param {BufferAttribute} attribute - The attribute to clone.\n * @return {BufferAttribute} The cloned attribute.\n */\nfunction deepCloneAttribute( attribute ) {\n\n\tif ( attribute.isInstancedInterleavedBufferAttribute || attribute.isInterleavedBufferAttribute ) {\n\n\t\treturn deinterleaveAttribute( attribute );\n\n\t}\n\n\tif ( attribute.isInstancedBufferAttribute ) {\n\n\t\treturn new InstancedBufferAttribute().copy( attribute );\n\n\t}\n\n\treturn new BufferAttribute().copy( attribute );\n\n}\n\n/**\n * Interleaves a set of attributes and returns a new array of corresponding attributes that share a\n * single {@link InterleavedBuffer} instance. All attributes must have compatible types.\n *\n * @param {Array<BufferAttribute>} attributes - The attributes to interleave.\n * @return {?Array<InterleavedBufferAttribute>} An array of interleaved attributes. If interleave does not succeed, the method returns `null`.\n */\nfunction interleaveAttributes( attributes ) {\n\n\t// Interleaves the provided attributes into an InterleavedBuffer and returns\n\t// a set of InterleavedBufferAttributes for each attribute\n\tlet TypedArray;\n\tlet arrayLength = 0;\n\tlet stride = 0;\n\n\t// calculate the length and type of the interleavedBuffer\n\tfor ( let i = 0, l = attributes.length; i < l; ++ i ) {\n\n\t\tconst attribute = attributes[ i ];\n\n\t\tif ( TypedArray === undefined ) TypedArray = attribute.array.constructor;\n\t\tif ( TypedArray !== attribute.array.constructor ) {\n\n\t\t\tconsole.error( 'AttributeBuffers of different types cannot be interleaved' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\tarrayLength += attribute.array.length;\n\t\tstride += attribute.itemSize;\n\n\t}\n\n\t// Create the set of buffer attributes\n\tconst interleavedBuffer = new InterleavedBuffer( new TypedArray( arrayLength ), stride );\n\tlet offset = 0;\n\tconst res = [];\n\tconst getters = [ 'getX', 'getY', 'getZ', 'getW' ];\n\tconst setters = [ 'setX', 'setY', 'setZ', 'setW' ];\n\n\tfor ( let j = 0, l = attributes.length; j < l; j ++ ) {\n\n\t\tconst attribute = attributes[ j ];\n\t\tconst itemSize = attribute.itemSize;\n\t\tconst count = attribute.count;\n\t\tconst iba = new InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, attribute.normalized );\n\t\tres.push( iba );\n\n\t\toffset += itemSize;\n\n\t\t// Move the data for each attribute into the new interleavedBuffer\n\t\t// at the appropriate offset\n\t\tfor ( let c = 0; c < count; c ++ ) {\n\n\t\t\tfor ( let k = 0; k < itemSize; k ++ ) {\n\n\t\t\t\tiba[ setters[ k ] ]( c, attribute[ getters[ k ] ]( c ) );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\treturn res;\n\n}\n\n/**\n * Returns a new, non-interleaved version of the given attribute.\n *\n * @param {InterleavedBufferAttribute} attribute - The interleaved attribute.\n * @return {BufferAttribute} The non-interleaved attribute.\n */\nfunction deinterleaveAttribute( attribute ) {\n\n\tconst cons = attribute.data.array.constructor;\n\tconst count = attribute.count;\n\tconst itemSize = attribute.itemSize;\n\tconst normalized = attribute.normalized;\n\n\tconst array = new cons( count * itemSize );\n\tlet newAttribute;\n\tif ( attribute.isInstancedInterleavedBufferAttribute ) {\n\n\t\tnewAttribute = new InstancedBufferAttribute( array, itemSize, normalized, attribute.meshPerAttribute );\n\n\t} else {\n\n\t\tnewAttribute = new BufferAttribute( array, itemSize, normalized );\n\n\t}\n\n\tfor ( let i = 0; i < count; i ++ ) {\n\n\t\tnewAttribute.setX( i, attribute.getX( i ) );\n\n\t\tif ( itemSize >= 2 ) {\n\n\t\t\tnewAttribute.setY( i, attribute.getY( i ) );\n\n\t\t}\n\n\t\tif ( itemSize >= 3 ) {\n\n\t\t\tnewAttribute.setZ( i, attribute.getZ( i ) );\n\n\t\t}\n\n\t\tif ( itemSize >= 4 ) {\n\n\t\t\tnewAttribute.setW( i, attribute.getW( i ) );\n\n\t\t}\n\n\t}\n\n\treturn newAttribute;\n\n}\n\n/**\n * Deinterleaves all attributes on the given geometry.\n *\n * @param {BufferGeometry} geometry - The geometry to deinterleave.\n */\nfunction deinterleaveGeometry( geometry ) {\n\n\tconst attributes = geometry.attributes;\n\tconst morphTargets = geometry.morphTargets;\n\tconst attrMap = new Map();\n\n\tfor ( const key in attributes ) {\n\n\t\tconst attr = attributes[ key ];\n\t\tif ( attr.isInterleavedBufferAttribute ) {\n\n\t\t\tif ( ! attrMap.has( attr ) ) {\n\n\t\t\t\tattrMap.set( attr, deinterleaveAttribute( attr ) );\n\n\t\t\t}\n\n\t\t\tattributes[ key ] = attrMap.get( attr );\n\n\t\t}\n\n\t}\n\n\tfor ( const key in morphTargets ) {\n\n\t\tconst attr = morphTargets[ key ];\n\t\tif ( attr.isInterleavedBufferAttribute ) {\n\n\t\t\tif ( ! attrMap.has( attr ) ) {\n\n\t\t\t\tattrMap.set( attr, deinterleaveAttribute( attr ) );\n\n\t\t\t}\n\n\t\t\tmorphTargets[ key ] = attrMap.get( attr );\n\n\t\t}\n\n\t}\n\n}\n\n/**\n * Returns the amount of bytes used by all attributes to represent the geometry.\n *\n * @param {BufferGeometry} geometry - The geometry.\n * @return {number} The estimate bytes used.\n */\nfunction estimateBytesUsed( geometry ) {\n\n\t// Return the estimated memory used by this geometry in bytes\n\t// Calculate using itemSize, count, and BYTES_PER_ELEMENT to account\n\t// for InterleavedBufferAttributes.\n\tlet mem = 0;\n\tfor ( const name in geometry.attributes ) {\n\n\t\tconst attr = geometry.getAttribute( name );\n\t\tmem += attr.count * attr.itemSize * attr.array.BYTES_PER_ELEMENT;\n\n\t}\n\n\tconst indices = geometry.getIndex();\n\tmem += indices ? indices.count * indices.itemSize * indices.array.BYTES_PER_ELEMENT : 0;\n\treturn mem;\n\n}\n\n/**\n * Returns a new geometry with vertices for which all similar vertex attributes (within tolerance) are merged.\n *\n * @param {BufferGeometry} geometry - The geometry to merge vertices for.\n * @param {number} [tolerance=1e-4] - The tolerance value.\n * @return {BufferGeometry} - The new geometry with merged vertices.\n */\nfunction mergeVertices( geometry, tolerance = 1e-4 ) {\n\n\ttolerance = Math.max( tolerance, Number.EPSILON );\n\n\t// Generate an index buffer if the geometry doesn't have one, or optimize it\n\t// if it's already available.\n\tconst hashToIndex = {};\n\tconst indices = geometry.getIndex();\n\tconst positions = geometry.getAttribute( 'position' );\n\tconst vertexCount = indices ? indices.count : positions.count;\n\n\t// next value for triangle indices\n\tlet nextIndex = 0;\n\n\t// attributes and new attribute arrays\n\tconst attributeNames = Object.keys( geometry.attributes );\n\tconst tmpAttributes = {};\n\tconst tmpMorphAttributes = {};\n\tconst newIndices = [];\n\tconst getters = [ 'getX', 'getY', 'getZ', 'getW' ];\n\tconst setters = [ 'setX', 'setY', 'setZ', 'setW' ];\n\n\t// Initialize the arrays, allocating space conservatively. Extra\n\t// space will be trimmed in the last step.\n\tfor ( let i = 0, l = attributeNames.length; i < l; i ++ ) {\n\n\t\tconst name = attributeNames[ i ];\n\t\tconst attr = geometry.attributes[ name ];\n\n\t\ttmpAttributes[ name ] = new attr.constructor(\n\t\t\tnew attr.array.constructor( attr.count * attr.itemSize ),\n\t\t\tattr.itemSize,\n\t\t\tattr.normalized\n\t\t);\n\n\t\tconst morphAttributes = geometry.morphAttributes[ name ];\n\t\tif ( morphAttributes ) {\n\n\t\t\tif ( ! tmpMorphAttributes[ name ] ) tmpMorphAttributes[ name ] = [];\n\t\t\tmorphAttributes.forEach( ( morphAttr, i ) => {\n\n\t\t\t\tconst array = new morphAttr.array.constructor( morphAttr.count * morphAttr.itemSize );\n\t\t\t\ttmpMorphAttributes[ name ][ i ] = new morphAttr.constructor( array, morphAttr.itemSize, morphAttr.normalized );\n\n\t\t\t} );\n\n\t\t}\n\n\t}\n\n\t// convert the error tolerance to an amount of decimal places to truncate to\n\tconst halfTolerance = tolerance * 0.5;\n\tconst exponent = Math.log10( 1 / tolerance );\n\tconst hashMultiplier = Math.pow( 10, exponent );\n\tconst hashAdditive = halfTolerance * hashMultiplier;\n\tfor ( let i = 0; i < vertexCount; i ++ ) {\n\n\t\tconst index = indices ? indices.getX( i ) : i;\n\n\t\t// Generate a hash for the vertex attributes at the current index 'i'\n\t\tlet hash = '';\n\t\tfor ( let j = 0, l = attributeNames.length; j < l; j ++ ) {\n\n\t\t\tconst name = attributeNames[ j ];\n\t\t\tconst attribute = geometry.getAttribute( name );\n\t\t\tconst itemSize = attribute.itemSize;\n\n\t\t\tfor ( let k = 0; k < itemSize; k ++ ) {\n\n\t\t\t\t// double tilde truncates the decimal value\n\t\t\t\thash += `${ ~ ~ ( attribute[ getters[ k ] ]( index ) * hashMultiplier + hashAdditive ) },`;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Add another reference to the vertex if it's already\n\t\t// used by another index\n\t\tif ( hash in hashToIndex ) {\n\n\t\t\tnewIndices.push( hashToIndex[ hash ] );\n\n\t\t} else {\n\n\t\t\t// copy data to the new index in the temporary attributes\n\t\t\tfor ( let j = 0, l = attributeNames.length; j < l; j ++ ) {\n\n\t\t\t\tconst name = attributeNames[ j ];\n\t\t\t\tconst attribute = geometry.getAttribute( name );\n\t\t\t\tconst morphAttributes = geometry.morphAttributes[ name ];\n\t\t\t\tconst itemSize = attribute.itemSize;\n\t\t\t\tconst newArray = tmpAttributes[ name ];\n\t\t\t\tconst newMorphArrays = tmpMorphAttributes[ name ];\n\n\t\t\t\tfor ( let k = 0; k < itemSize; k ++ ) {\n\n\t\t\t\t\tconst getterFunc = getters[ k ];\n\t\t\t\t\tconst setterFunc = setters[ k ];\n\t\t\t\t\tnewArray[ setterFunc ]( nextIndex, attribute[ getterFunc ]( index ) );\n\n\t\t\t\t\tif ( morphAttributes ) {\n\n\t\t\t\t\t\tfor ( let m = 0, ml = morphAttributes.length; m < ml; m ++ ) {\n\n\t\t\t\t\t\t\tnewMorphArrays[ m ][ setterFunc ]( nextIndex, morphAttributes[ m ][ getterFunc ]( index ) );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\thashToIndex[ hash ] = nextIndex;\n\t\t\tnewIndices.push( nextIndex );\n\t\t\tnextIndex ++;\n\n\t\t}\n\n\t}\n\n\t// generate result BufferGeometry\n\tconst result = geometry.clone();\n\tfor ( const name in geometry.attributes ) {\n\n\t\tconst tmpAttribute = tmpAttributes[ name ];\n\n\t\tresult.setAttribute( name, new tmpAttribute.constructor(\n\t\t\ttmpAttribute.array.slice( 0, nextIndex * tmpAttribute.itemSize ),\n\t\t\ttmpAttribute.itemSize,\n\t\t\ttmpAttribute.normalized,\n\t\t) );\n\n\t\tif ( ! ( name in tmpMorphAttributes ) ) continue;\n\n\t\tfor ( let j = 0; j < tmpMorphAttributes[ name ].length; j ++ ) {\n\n\t\t\tconst tmpMorphAttribute = tmpMorphAttributes[ name ][ j ];\n\n\t\t\tresult.morphAttributes[ name ][ j ] = new tmpMorphAttribute.constructor(\n\t\t\t\ttmpMorphAttribute.array.slice( 0, nextIndex * tmpMorphAttribute.itemSize ),\n\t\t\t\ttmpMorphAttribute.itemSize,\n\t\t\t\ttmpMorphAttribute.normalized,\n\t\t\t);\n\n\t\t}\n\n\t}\n\n\t// indices\n\n\tresult.setIndex( newIndices );\n\n\treturn result;\n\n}\n\n/**\n * Returns a new indexed geometry based on `TrianglesDrawMode` draw mode.\n * This mode corresponds to the `gl.TRIANGLES` primitive in WebGL.\n *\n * @param {BufferGeometry} geometry - The geometry to convert.\n * @param {number} drawMode - The current draw mode.\n * @return {BufferGeometry} The new geometry using `TrianglesDrawMode`.\n */\nfunction toTrianglesDrawMode( geometry, drawMode ) {\n\n\tif ( drawMode === TrianglesDrawMode ) {\n\n\t\tconsole.warn( 'THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles.' );\n\t\treturn geometry;\n\n\t}\n\n\tif ( drawMode === TriangleFanDrawMode || drawMode === TriangleStripDrawMode ) {\n\n\t\tlet index = geometry.getIndex();\n\n\t\t// generate index if not present\n\n\t\tif ( index === null ) {\n\n\t\t\tconst indices = [];\n\n\t\t\tconst position = geometry.getAttribute( 'position' );\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tfor ( let i = 0; i < position.count; i ++ ) {\n\n\t\t\t\t\tindices.push( i );\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.setIndex( indices );\n\t\t\t\tindex = geometry.getIndex();\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometryUtils.toTrianglesDrawMode(): Undefined position attribute. Processing not possible.' );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tconst numberOfTriangles = index.count - 2;\n\t\tconst newIndices = [];\n\n\t\tif ( drawMode === TriangleFanDrawMode ) {\n\n\t\t\t// gl.TRIANGLE_FAN\n\n\t\t\tfor ( let i = 1; i <= numberOfTriangles; i ++ ) {\n\n\t\t\t\tnewIndices.push( index.getX( 0 ) );\n\t\t\t\tnewIndices.push( index.getX( i ) );\n\t\t\t\tnewIndices.push( index.getX( i + 1 ) );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// gl.TRIANGLE_STRIP\n\n\t\t\tfor ( let i = 0; i < numberOfTriangles; i ++ ) {\n\n\t\t\t\tif ( i % 2 === 0 ) {\n\n\t\t\t\t\tnewIndices.push( index.getX( i ) );\n\t\t\t\t\tnewIndices.push( index.getX( i + 1 ) );\n\t\t\t\t\tnewIndices.push( index.getX( i + 2 ) );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tnewIndices.push( index.getX( i + 2 ) );\n\t\t\t\t\tnewIndices.push( index.getX( i + 1 ) );\n\t\t\t\t\tnewIndices.push( index.getX( i ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( ( newIndices.length / 3 ) !== numberOfTriangles ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unable to generate correct amount of triangles.' );\n\n\t\t}\n\n\t\t// build final geometry\n\n\t\tconst newGeometry = geometry.clone();\n\t\tnewGeometry.setIndex( newIndices );\n\t\tnewGeometry.clearGroups();\n\n\t\treturn newGeometry;\n\n\t} else {\n\n\t\tconsole.error( 'THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unknown draw mode:', drawMode );\n\t\treturn geometry;\n\n\t}\n\n}\n\n/**\n * Calculates the morphed attributes of a morphed/skinned BufferGeometry.\n *\n * Helpful for Raytracing or Decals (i.e. a `DecalGeometry` applied to a morphed Object with a `BufferGeometry`\n * will use the original `BufferGeometry`, not the morphed/skinned one, generating an incorrect result.\n * Using this function to create a shadow `Object3`D the `DecalGeometry` can be correctly generated).\n *\n * @param {Mesh|Line|Points} object - The 3D object to compute morph attributes for.\n * @return {Object} An object with original position/normal attributes and morphed ones.\n */\nfunction computeMorphedAttributes( object ) {\n\n\tconst _vA = new Vector3();\n\tconst _vB = new Vector3();\n\tconst _vC = new Vector3();\n\n\tconst _tempA = new Vector3();\n\tconst _tempB = new Vector3();\n\tconst _tempC = new Vector3();\n\n\tconst _morphA = new Vector3();\n\tconst _morphB = new Vector3();\n\tconst _morphC = new Vector3();\n\n\tfunction _calculateMorphedAttributeData(\n\t\tobject,\n\t\tattribute,\n\t\tmorphAttribute,\n\t\tmorphTargetsRelative,\n\t\ta,\n\t\tb,\n\t\tc,\n\t\tmodifiedAttributeArray\n\t) {\n\n\t\t_vA.fromBufferAttribute( attribute, a );\n\t\t_vB.fromBufferAttribute( attribute, b );\n\t\t_vC.fromBufferAttribute( attribute, c );\n\n\t\tconst morphInfluences = object.morphTargetInfluences;\n\n\t\tif ( morphAttribute && morphInfluences ) {\n\n\t\t\t_morphA.set( 0, 0, 0 );\n\t\t\t_morphB.set( 0, 0, 0 );\n\t\t\t_morphC.set( 0, 0, 0 );\n\n\t\t\tfor ( let i = 0, il = morphAttribute.length; i < il; i ++ ) {\n\n\t\t\t\tconst influence = morphInfluences[ i ];\n\t\t\t\tconst morph = morphAttribute[ i ];\n\n\t\t\t\tif ( influence === 0 ) continue;\n\n\t\t\t\t_tempA.fromBufferAttribute( morph, a );\n\t\t\t\t_tempB.fromBufferAttribute( morph, b );\n\t\t\t\t_tempC.fromBufferAttribute( morph, c );\n\n\t\t\t\tif ( morphTargetsRelative ) {\n\n\t\t\t\t\t_morphA.addScaledVector( _tempA, influence );\n\t\t\t\t\t_morphB.addScaledVector( _tempB, influence );\n\t\t\t\t\t_morphC.addScaledVector( _tempC, influence );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_morphA.addScaledVector( _tempA.sub( _vA ), influence );\n\t\t\t\t\t_morphB.addScaledVector( _tempB.sub( _vB ), influence );\n\t\t\t\t\t_morphC.addScaledVector( _tempC.sub( _vC ), influence );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_vA.add( _morphA );\n\t\t\t_vB.add( _morphB );\n\t\t\t_vC.add( _morphC );\n\n\t\t}\n\n\t\tif ( object.isSkinnedMesh ) {\n\n\t\t\tobject.applyBoneTransform( a, _vA );\n\t\t\tobject.applyBoneTransform( b, _vB );\n\t\t\tobject.applyBoneTransform( c, _vC );\n\n\t\t}\n\n\t\tmodifiedAttributeArray[ a * 3 + 0 ] = _vA.x;\n\t\tmodifiedAttributeArray[ a * 3 + 1 ] = _vA.y;\n\t\tmodifiedAttributeArray[ a * 3 + 2 ] = _vA.z;\n\t\tmodifiedAttributeArray[ b * 3 + 0 ] = _vB.x;\n\t\tmodifiedAttributeArray[ b * 3 + 1 ] = _vB.y;\n\t\tmodifiedAttributeArray[ b * 3 + 2 ] = _vB.z;\n\t\tmodifiedAttributeArray[ c * 3 + 0 ] = _vC.x;\n\t\tmodifiedAttributeArray[ c * 3 + 1 ] = _vC.y;\n\t\tmodifiedAttributeArray[ c * 3 + 2 ] = _vC.z;\n\n\t}\n\n\tconst geometry = object.geometry;\n\tconst material = object.material;\n\n\tlet a, b, c;\n\tconst index = geometry.index;\n\tconst positionAttribute = geometry.attributes.position;\n\tconst morphPosition = geometry.morphAttributes.position;\n\tconst morphTargetsRelative = geometry.morphTargetsRelative;\n\tconst normalAttribute = geometry.attributes.normal;\n\tconst morphNormal = geometry.morphAttributes.normal;\n\n\tconst groups = geometry.groups;\n\tconst drawRange = geometry.drawRange;\n\tlet i, j, il, jl;\n\tlet group;\n\tlet start, end;\n\n\tconst modifiedPosition = new Float32Array( positionAttribute.count * positionAttribute.itemSize );\n\tconst modifiedNormal = new Float32Array( normalAttribute.count * normalAttribute.itemSize );\n\n\tif ( index !== null ) {\n\n\t\t// indexed buffer geometry\n\n\t\tif ( Array.isArray( material ) ) {\n\n\t\t\tfor ( i = 0, il = groups.length; i < il; i ++ ) {\n\n\t\t\t\tgroup = groups[ i ];\n\n\t\t\t\tstart = Math.max( group.start, drawRange.start );\n\t\t\t\tend = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );\n\n\t\t\t\tfor ( j = start, jl = end; j < jl; j += 3 ) {\n\n\t\t\t\t\ta = index.getX( j );\n\t\t\t\t\tb = index.getX( j + 1 );\n\t\t\t\t\tc = index.getX( j + 2 );\n\n\t\t\t\t\t_calculateMorphedAttributeData(\n\t\t\t\t\t\tobject,\n\t\t\t\t\t\tpositionAttribute,\n\t\t\t\t\t\tmorphPosition,\n\t\t\t\t\t\tmorphTargetsRelative,\n\t\t\t\t\t\ta, b, c,\n\t\t\t\t\t\tmodifiedPosition\n\t\t\t\t\t);\n\n\t\t\t\t\t_calculateMorphedAttributeData(\n\t\t\t\t\t\tobject,\n\t\t\t\t\t\tnormalAttribute,\n\t\t\t\t\t\tmorphNormal,\n\t\t\t\t\t\tmorphTargetsRelative,\n\t\t\t\t\t\ta, b, c,\n\t\t\t\t\t\tmodifiedNormal\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tstart = Math.max( 0, drawRange.start );\n\t\t\tend = Math.min( index.count, ( drawRange.start + drawRange.count ) );\n\n\t\t\tfor ( i = start, il = end; i < il; i += 3 ) {\n\n\t\t\t\ta = index.getX( i );\n\t\t\t\tb = index.getX( i + 1 );\n\t\t\t\tc = index.getX( i + 2 );\n\n\t\t\t\t_calculateMorphedAttributeData(\n\t\t\t\t\tobject,\n\t\t\t\t\tpositionAttribute,\n\t\t\t\t\tmorphPosition,\n\t\t\t\t\tmorphTargetsRelative,\n\t\t\t\t\ta, b, c,\n\t\t\t\t\tmodifiedPosition\n\t\t\t\t);\n\n\t\t\t\t_calculateMorphedAttributeData(\n\t\t\t\t\tobject,\n\t\t\t\t\tnormalAttribute,\n\t\t\t\t\tmorphNormal,\n\t\t\t\t\tmorphTargetsRelative,\n\t\t\t\t\ta, b, c,\n\t\t\t\t\tmodifiedNormal\n\t\t\t\t);\n\n\t\t\t}\n\n\t\t}\n\n\t} else {\n\n\t\t// non-indexed buffer geometry\n\n\t\tif ( Array.isArray( material ) ) {\n\n\t\t\tfor ( i = 0, il = groups.length; i < il; i ++ ) {\n\n\t\t\t\tgroup = groups[ i ];\n\n\t\t\t\tstart = Math.max( group.start, drawRange.start );\n\t\t\t\tend = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );\n\n\t\t\t\tfor ( j = start, jl = end; j < jl; j += 3 ) {\n\n\t\t\t\t\ta = j;\n\t\t\t\t\tb = j + 1;\n\t\t\t\t\tc = j + 2;\n\n\t\t\t\t\t_calculateMorphedAttributeData(\n\t\t\t\t\t\tobject,\n\t\t\t\t\t\tpositionAttribute,\n\t\t\t\t\t\tmorphPosition,\n\t\t\t\t\t\tmorphTargetsRelative,\n\t\t\t\t\t\ta, b, c,\n\t\t\t\t\t\tmodifiedPosition\n\t\t\t\t\t);\n\n\t\t\t\t\t_calculateMorphedAttributeData(\n\t\t\t\t\t\tobject,\n\t\t\t\t\t\tnormalAttribute,\n\t\t\t\t\t\tmorphNormal,\n\t\t\t\t\t\tmorphTargetsRelative,\n\t\t\t\t\t\ta, b, c,\n\t\t\t\t\t\tmodifiedNormal\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tstart = Math.max( 0, drawRange.start );\n\t\t\tend = Math.min( positionAttribute.count, ( drawRange.start + drawRange.count ) );\n\n\t\t\tfor ( i = start, il = end; i < il; i += 3 ) {\n\n\t\t\t\ta = i;\n\t\t\t\tb = i + 1;\n\t\t\t\tc = i + 2;\n\n\t\t\t\t_calculateMorphedAttributeData(\n\t\t\t\t\tobject,\n\t\t\t\t\tpositionAttribute,\n\t\t\t\t\tmorphPosition,\n\t\t\t\t\tmorphTargetsRelative,\n\t\t\t\t\ta, b, c,\n\t\t\t\t\tmodifiedPosition\n\t\t\t\t);\n\n\t\t\t\t_calculateMorphedAttributeData(\n\t\t\t\t\tobject,\n\t\t\t\t\tnormalAttribute,\n\t\t\t\t\tmorphNormal,\n\t\t\t\t\tmorphTargetsRelative,\n\t\t\t\t\ta, b, c,\n\t\t\t\t\tmodifiedNormal\n\t\t\t\t);\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tconst morphedPositionAttribute = new Float32BufferAttribute( modifiedPosition, 3 );\n\tconst morphedNormalAttribute = new Float32BufferAttribute( modifiedNormal, 3 );\n\n\treturn {\n\n\t\tpositionAttribute: positionAttribute,\n\t\tnormalAttribute: normalAttribute,\n\t\tmorphedPositionAttribute: morphedPositionAttribute,\n\t\tmorphedNormalAttribute: morphedNormalAttribute\n\n\t};\n\n}\n\n/**\n * Merges the {@link BufferGeometry#groups} for the given geometry.\n *\n * @param {BufferGeometry} geometry - The geometry to modify.\n * @return {BufferGeometry} - The updated geometry\n */\nfunction mergeGroups( geometry ) {\n\n\tif ( geometry.groups.length === 0 ) {\n\n\t\tconsole.warn( 'THREE.BufferGeometryUtils.mergeGroups(): No groups are defined. Nothing to merge.' );\n\t\treturn geometry;\n\n\t}\n\n\tlet groups = geometry.groups;\n\n\t// sort groups by material index\n\n\tgroups = groups.sort( ( a, b ) => {\n\n\t\tif ( a.materialIndex !== b.materialIndex ) return a.materialIndex - b.materialIndex;\n\n\t\treturn a.start - b.start;\n\n\t} );\n\n\t// create index for non-indexed geometries\n\n\tif ( geometry.getIndex() === null ) {\n\n\t\tconst positionAttribute = geometry.getAttribute( 'position' );\n\t\tconst indices = [];\n\n\t\tfor ( let i = 0; i < positionAttribute.count; i += 3 ) {\n\n\t\t\tindices.push( i, i + 1, i + 2 );\n\n\t\t}\n\n\t\tgeometry.setIndex( indices );\n\n\t}\n\n\t// sort index\n\n\tconst index = geometry.getIndex();\n\n\tconst newIndices = [];\n\n\tfor ( let i = 0; i < groups.length; i ++ ) {\n\n\t\tconst group = groups[ i ];\n\n\t\tconst groupStart = group.start;\n\t\tconst groupLength = groupStart + group.count;\n\n\t\tfor ( let j = groupStart; j < groupLength; j ++ ) {\n\n\t\t\tnewIndices.push( index.getX( j ) );\n\n\t\t}\n\n\t}\n\n\tgeometry.dispose(); // Required to force buffer recreation\n\tgeometry.setIndex( newIndices );\n\n\t// update groups indices\n\n\tlet start = 0;\n\n\tfor ( let i = 0; i < groups.length; i ++ ) {\n\n\t\tconst group = groups[ i ];\n\n\t\tgroup.start = start;\n\t\tstart += group.count;\n\n\t}\n\n\t// merge groups\n\n\tlet currentGroup = groups[ 0 ];\n\n\tgeometry.groups = [ currentGroup ];\n\n\tfor ( let i = 1; i < groups.length; i ++ ) {\n\n\t\tconst group = groups[ i ];\n\n\t\tif ( currentGroup.materialIndex === group.materialIndex ) {\n\n\t\t\tcurrentGroup.count += group.count;\n\n\t\t} else {\n\n\t\t\tcurrentGroup = group;\n\t\t\tgeometry.groups.push( currentGroup );\n\n\t\t}\n\n\t}\n\n\treturn geometry;\n\n}\n\n/**\n * Modifies the supplied geometry if it is non-indexed, otherwise creates a new,\n * non-indexed geometry. Returns the geometry with smooth normals everywhere except\n * faces that meet at an angle greater than the crease angle.\n *\n * @param {BufferGeometry} geometry - The geometry to modify.\n * @param {number} [creaseAngle=Math.PI/3] - The crease angle in radians.\n * @return {BufferGeometry} - The updated geometry\n */\nfunction toCreasedNormals( geometry, creaseAngle = Math.PI / 3 /* 60 degrees */ ) {\n\n\tconst creaseDot = Math.cos( creaseAngle );\n\tconst hashMultiplier = ( 1 + 1e-10 ) * 1e2;\n\n\t// reusable vectors\n\tconst verts = [ new Vector3(), new Vector3(), new Vector3() ];\n\tconst tempVec1 = new Vector3();\n\tconst tempVec2 = new Vector3();\n\tconst tempNorm = new Vector3();\n\tconst tempNorm2 = new Vector3();\n\n\t// hashes a vector\n\tfunction hashVertex( v ) {\n\n\t\tconst x = ~ ~ ( v.x * hashMultiplier );\n\t\tconst y = ~ ~ ( v.y * hashMultiplier );\n\t\tconst z = ~ ~ ( v.z * hashMultiplier );\n\t\treturn `${x},${y},${z}`;\n\n\t}\n\n\t// BufferGeometry.toNonIndexed() warns if the geometry is non-indexed\n\t// and returns the original geometry\n\tconst resultGeometry = geometry.index ? geometry.toNonIndexed() : geometry;\n\tconst posAttr = resultGeometry.attributes.position;\n\tconst vertexMap = {};\n\n\t// find all the normals shared by commonly located vertices\n\tfor ( let i = 0, l = posAttr.count / 3; i < l; i ++ ) {\n\n\t\tconst i3 = 3 * i;\n\t\tconst a = verts[ 0 ].fromBufferAttribute( posAttr, i3 + 0 );\n\t\tconst b = verts[ 1 ].fromBufferAttribute( posAttr, i3 + 1 );\n\t\tconst c = verts[ 2 ].fromBufferAttribute( posAttr, i3 + 2 );\n\n\t\ttempVec1.subVectors( c, b );\n\t\ttempVec2.subVectors( a, b );\n\n\t\t// add the normal to the map for all vertices\n\t\tconst normal = new Vector3().crossVectors( tempVec1, tempVec2 ).normalize();\n\t\tfor ( let n = 0; n < 3; n ++ ) {\n\n\t\t\tconst vert = verts[ n ];\n\t\t\tconst hash = hashVertex( vert );\n\t\t\tif ( ! ( hash in vertexMap ) ) {\n\n\t\t\t\tvertexMap[ hash ] = [];\n\n\t\t\t}\n\n\t\t\tvertexMap[ hash ].push( normal );\n\n\t\t}\n\n\t}\n\n\t// average normals from all vertices that share a common location if they are within the\n\t// provided crease threshold\n\tconst normalArray = new Float32Array( posAttr.count * 3 );\n\tconst normAttr = new BufferAttribute( normalArray, 3, false );\n\tfor ( let i = 0, l = posAttr.count / 3; i < l; i ++ ) {\n\n\t\t// get the face normal for this vertex\n\t\tconst i3 = 3 * i;\n\t\tconst a = verts[ 0 ].fromBufferAttribute( posAttr, i3 + 0 );\n\t\tconst b = verts[ 1 ].fromBufferAttribute( posAttr, i3 + 1 );\n\t\tconst c = verts[ 2 ].fromBufferAttribute( posAttr, i3 + 2 );\n\n\t\ttempVec1.subVectors( c, b );\n\t\ttempVec2.subVectors( a, b );\n\n\t\ttempNorm.crossVectors( tempVec1, tempVec2 ).normalize();\n\n\t\t// average all normals that meet the threshold and set the normal value\n\t\tfor ( let n = 0; n < 3; n ++ ) {\n\n\t\t\tconst vert = verts[ n ];\n\t\t\tconst hash = hashVertex( vert );\n\t\t\tconst otherNormals = vertexMap[ hash ];\n\t\t\ttempNorm2.set( 0, 0, 0 );\n\n\t\t\tfor ( let k = 0, lk = otherNormals.length; k < lk; k ++ ) {\n\n\t\t\t\tconst otherNorm = otherNormals[ k ];\n\t\t\t\tif ( tempNorm.dot( otherNorm ) > creaseDot ) {\n\n\t\t\t\t\ttempNorm2.add( otherNorm );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\ttempNorm2.normalize();\n\t\t\tnormAttr.setXYZ( i3 + n, tempNorm2.x, tempNorm2.y, tempNorm2.z );\n\n\t\t}\n\n\t}\n\n\tresultGeometry.setAttribute( 'normal', normAttr );\n\treturn resultGeometry;\n\n}\n\nexport {\n\tcomputeMikkTSpaceTangents,\n\tmergeGeometries,\n\tmergeAttributes,\n\tdeepCloneAttribute,\n\tdeinterleaveAttribute,\n\tdeinterleaveGeometry,\n\tinterleaveAttributes,\n\testimateBytesUsed,\n\tmergeVertices,\n\ttoTrianglesDrawMode,\n\tcomputeMorphedAttributes,\n\tmergeGroups,\n\ttoCreasedNormals\n};\n","import {\n\tAnimationClip,\n\tAnimationMixer,\n\tMatrix4,\n\tQuaternion,\n\tQuaternionKeyframeTrack,\n\tSkeletonHelper,\n\tVector3,\n\tVectorKeyframeTrack\n} from 'three';\n\n/**\n * @module SkeletonUtils\n * @three_import import * as SkeletonUtils from 'three/addons/utils/SkeletonUtils.js';\n */\n\nfunction getBoneName( bone, options ) {\n\n\tif ( options.getBoneName !== undefined ) {\n\n\t\treturn options.getBoneName( bone );\n\n\t}\n\n\treturn options.names[ bone.name ];\n\n}\n\n/**\n * Retargets the skeleton from the given source to the target.\n *\n * Both `target` and `source` can be a 3D object with a skeleton property (e.g. a skinned mesh)\n * or a {@link Skeleton} directly.\n *\n * @param {Object3D|Skeleton} target - The target object.\n * @param {Object3D|Skeleton} source - The source object.\n * @param {module:SkeletonUtils~RetargetOptions} options - The options.\n */\nfunction retarget( target, source, options = {} ) {\n\n\tconst quat = new Quaternion(),\n\t\tscale = new Vector3(),\n\t\trelativeMatrix = new Matrix4(),\n\t\tglobalMatrix = new Matrix4();\n\n\toptions.preserveBoneMatrix = options.preserveBoneMatrix !== undefined ? options.preserveBoneMatrix : true;\n\toptions.preserveBonePositions = options.preserveBonePositions !== undefined ? options.preserveBonePositions : true;\n\toptions.useTargetMatrix = options.useTargetMatrix !== undefined ? options.useTargetMatrix : false;\n\toptions.hip = options.hip !== undefined ? options.hip : 'hip';\n\toptions.hipInfluence = options.hipInfluence !== undefined ? options.hipInfluence : new Vector3( 1, 1, 1 );\n\toptions.scale = options.scale !== undefined ? options.scale : 1;\n\toptions.names = options.names || {};\n\n\tconst sourceBones = source.isObject3D ? source.skeleton.bones : getBones( source ),\n\t\tbones = target.isObject3D ? target.skeleton.bones : getBones( target );\n\n\tlet bone, name, boneTo,\n\t\tbonesPosition;\n\n\t// reset bones\n\n\tif ( target.isObject3D ) {\n\n\t\ttarget.skeleton.pose();\n\n\t} else {\n\n\t\toptions.useTargetMatrix = true;\n\t\toptions.preserveBoneMatrix = false;\n\n\t}\n\n\tif ( options.preserveBonePositions ) {\n\n\t\tbonesPosition = [];\n\n\t\tfor ( let i = 0; i < bones.length; i ++ ) {\n\n\t\t\tbonesPosition.push( bones[ i ].position.clone() );\n\n\t\t}\n\n\t}\n\n\tif ( options.preserveBoneMatrix ) {\n\n\t\t// reset matrix\n\n\t\ttarget.updateMatrixWorld();\n\n\t\ttarget.matrixWorld.identity();\n\n\t\t// reset children matrix\n\n\t\tfor ( let i = 0; i < target.children.length; ++ i ) {\n\n\t\t\ttarget.children[ i ].updateMatrixWorld( true );\n\n\t\t}\n\n\t}\n\n\tfor ( let i = 0; i < bones.length; ++ i ) {\n\n\t\tbone = bones[ i ];\n\t\tname = getBoneName( bone, options );\n\n\t\tboneTo = getBoneByName( name, sourceBones );\n\n\t\tglobalMatrix.copy( bone.matrixWorld );\n\n\t\tif ( boneTo ) {\n\n\t\t\tboneTo.updateMatrixWorld();\n\n\t\t\tif ( options.useTargetMatrix ) {\n\n\t\t\t\trelativeMatrix.copy( boneTo.matrixWorld );\n\n\t\t\t} else {\n\n\t\t\t\trelativeMatrix.copy( target.matrixWorld ).invert();\n\t\t\t\trelativeMatrix.multiply( boneTo.matrixWorld );\n\n\t\t\t}\n\n\t\t\t// ignore scale to extract rotation\n\n\t\t\tscale.setFromMatrixScale( relativeMatrix );\n\t\t\trelativeMatrix.scale( scale.set( 1 / scale.x, 1 / scale.y, 1 / scale.z ) );\n\n\t\t\t// apply to global matrix\n\n\t\t\tglobalMatrix.makeRotationFromQuaternion( quat.setFromRotationMatrix( relativeMatrix ) );\n\n\t\t\tif ( target.isObject3D ) {\n\n\t\t\t\tif ( options.localOffsets ) {\n\n\t\t\t\t\tif ( options.localOffsets[ bone.name ] ) {\n\n\t\t\t\t\t\tglobalMatrix.multiply( options.localOffsets[ bone.name ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tglobalMatrix.copyPosition( relativeMatrix );\n\n\t\t}\n\n\t\tif ( name === options.hip ) {\n\n\t\t\tglobalMatrix.elements[ 12 ] *= options.scale * options.hipInfluence.x;\n\t\t\tglobalMatrix.elements[ 13 ] *= options.scale * options.hipInfluence.y;\n\t\t\tglobalMatrix.elements[ 14 ] *= options.scale * options.hipInfluence.z;\n\n\t\t\tif ( options.hipPosition !== undefined ) {\n\n\t\t\t\tglobalMatrix.elements[ 12 ] += options.hipPosition.x * options.scale;\n\t\t\t\tglobalMatrix.elements[ 13 ] += options.hipPosition.y * options.scale;\n\t\t\t\tglobalMatrix.elements[ 14 ] += options.hipPosition.z * options.scale;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( bone.parent ) {\n\n\t\t\tbone.matrix.copy( bone.parent.matrixWorld ).invert();\n\t\t\tbone.matrix.multiply( globalMatrix );\n\n\t\t} else {\n\n\t\t\tbone.matrix.copy( globalMatrix );\n\n\t\t}\n\n\t\tbone.matrix.decompose( bone.position, bone.quaternion, bone.scale );\n\n\t\tbone.updateMatrixWorld();\n\n\t}\n\n\tif ( options.preserveBonePositions ) {\n\n\t\tfor ( let i = 0; i < bones.length; ++ i ) {\n\n\t\t\tbone = bones[ i ];\n\t\t\tname = getBoneName( bone, options ) || bone.name;\n\n\t\t\tif ( name !== options.hip ) {\n\n\t\t\t\tbone.position.copy( bonesPosition[ i ] );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tif ( options.preserveBoneMatrix ) {\n\n\t\t// restore matrix\n\n\t\ttarget.updateMatrixWorld( true );\n\n\t}\n\n}\n\n/**\n * Retargets the animation clip of the source to the target 3D object.\n *\n * The `source` can be a 3D object with a skeleton property (e.g. a skinned mesh)\n * or a {@link Skeleton} directly.\n *\n * @param {Object3D} target - The target 3D object. Must have a `skeleton` property.\n * @param {Object3D|Skeleton} source - The source object.\n * @param {AnimationClip} clip - The animation clip.\n * @param {module:SkeletonUtils~RetargetOptions} options - The options.\n * @return {AnimationClip} The retargeted animation clip.\n */\nfunction retargetClip( target, source, clip, options = {} ) {\n\n\toptions.useFirstFramePosition = options.useFirstFramePosition !== undefined ? options.useFirstFramePosition : false;\n\n\t// Calculate the fps from the source clip based on the track with the most frames, unless fps is already provided.\n\toptions.fps = options.fps !== undefined ? options.fps : ( Math.max( ...clip.tracks.map( track => track.times.length ) ) / clip.duration );\n\toptions.names = options.names || [];\n\n\tif ( ! source.isObject3D ) {\n\n\t\tsource = getHelperFromSkeleton( source );\n\n\t}\n\n\tconst numFrames = Math.round( clip.duration * ( options.fps / 1000 ) * 1000 ),\n\t\tdelta = clip.duration / ( numFrames - 1 ),\n\t\tconvertedTracks = [],\n\t\tmixer = new AnimationMixer( source ),\n\t\tbones = getBones( target.skeleton ),\n\t\tboneDatas = [];\n\n\tlet positionOffset,\n\t\tbone, boneTo, boneData,\n\t\tname;\n\n\tmixer.clipAction( clip ).play();\n\n\t// trim\n\n\tlet start = 0, end = numFrames;\n\n\tif ( options.trim !== undefined ) {\n\n\t\tstart = Math.round( options.trim[ 0 ] * options.fps );\n\t\tend = Math.min( Math.round( options.trim[ 1 ] * options.fps ), numFrames ) - start;\n\n\t\tmixer.update( options.trim[ 0 ] );\n\n\t} else {\n\n\t\tmixer.update( 0 );\n\n\t}\n\n\tsource.updateMatrixWorld();\n\n\t//\n\n\tfor ( let frame = 0; frame < end; ++ frame ) {\n\n\t\tconst time = frame * delta;\n\n\t\tretarget( target, source, options );\n\n\t\tfor ( let j = 0; j < bones.length; ++ j ) {\n\n\t\t\tbone = bones[ j ];\n\t\t\tname = getBoneName( bone, options ) || bone.name;\n\t\t\tboneTo = getBoneByName( name, source.skeleton );\n\n\t\t\tif ( boneTo ) {\n\n\t\t\t\tboneData = boneDatas[ j ] = boneDatas[ j ] || { bone: bone };\n\n\t\t\t\tif ( options.hip === name ) {\n\n\t\t\t\t\tif ( ! boneData.pos ) {\n\n\t\t\t\t\t\tboneData.pos = {\n\t\t\t\t\t\t\ttimes: new Float32Array( end ),\n\t\t\t\t\t\t\tvalues: new Float32Array( end * 3 )\n\t\t\t\t\t\t};\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( options.useFirstFramePosition ) {\n\n\t\t\t\t\t\tif ( frame === 0 ) {\n\n\t\t\t\t\t\t\tpositionOffset = bone.position.clone();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbone.position.sub( positionOffset );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tboneData.pos.times[ frame ] = time;\n\n\t\t\t\t\tbone.position.toArray( boneData.pos.values, frame * 3 );\n\n\t\t\t\t}\n\n\t\t\t\tif ( ! boneData.quat ) {\n\n\t\t\t\t\tboneData.quat = {\n\t\t\t\t\t\ttimes: new Float32Array( end ),\n\t\t\t\t\t\tvalues: new Float32Array( end * 4 )\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\tboneData.quat.times[ frame ] = time;\n\n\t\t\t\tbone.quaternion.toArray( boneData.quat.values, frame * 4 );\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( frame === end - 2 ) {\n\n\t\t\t// last mixer update before final loop iteration\n\t\t\t// make sure we do not go over or equal to clip duration\n\t\t\tmixer.update( delta - 0.0000001 );\n\n\t\t} else {\n\n\t\t\tmixer.update( delta );\n\n\t\t}\n\n\t\tsource.updateMatrixWorld();\n\n\t}\n\n\tfor ( let i = 0; i < boneDatas.length; ++ i ) {\n\n\t\tboneData = boneDatas[ i ];\n\n\t\tif ( boneData ) {\n\n\t\t\tif ( boneData.pos ) {\n\n\t\t\t\tconvertedTracks.push( new VectorKeyframeTrack(\n\t\t\t\t\t'.bones[' + boneData.bone.name + '].position',\n\t\t\t\t\tboneData.pos.times,\n\t\t\t\t\tboneData.pos.values\n\t\t\t\t) );\n\n\t\t\t}\n\n\t\t\tconvertedTracks.push( new QuaternionKeyframeTrack(\n\t\t\t\t'.bones[' + boneData.bone.name + '].quaternion',\n\t\t\t\tboneData.quat.times,\n\t\t\t\tboneData.quat.values\n\t\t\t) );\n\n\t\t}\n\n\t}\n\n\tmixer.uncacheAction( clip );\n\n\treturn new AnimationClip( clip.name, - 1, convertedTracks );\n\n}\n\n/**\n * Clones the given 3D object and its descendants, ensuring that any `SkinnedMesh` instances are\n * correctly associated with their bones. Bones are also cloned, and must be descendants of the\n * object passed to this method. Other data, like geometries and materials, are reused by reference.\n *\n * @param {Object3D} source - The 3D object to clone.\n * @return {Object3D} The cloned 3D object.\n */\nfunction clone( source ) {\n\n\tconst sourceLookup = new Map();\n\tconst cloneLookup = new Map();\n\n\tconst clone = source.clone();\n\n\tparallelTraverse( source, clone, function ( sourceNode, clonedNode ) {\n\n\t\tsourceLookup.set( clonedNode, sourceNode );\n\t\tcloneLookup.set( sourceNode, clonedNode );\n\n\t} );\n\n\tclone.traverse( function ( node ) {\n\n\t\tif ( ! node.isSkinnedMesh ) return;\n\n\t\tconst clonedMesh = node;\n\t\tconst sourceMesh = sourceLookup.get( node );\n\t\tconst sourceBones = sourceMesh.skeleton.bones;\n\n\t\tclonedMesh.skeleton = sourceMesh.skeleton.clone();\n\t\tclonedMesh.bindMatrix.copy( sourceMesh.bindMatrix );\n\n\t\tclonedMesh.skeleton.bones = sourceBones.map( function ( bone ) {\n\n\t\t\treturn cloneLookup.get( bone );\n\n\t\t} );\n\n\t\tclonedMesh.bind( clonedMesh.skeleton, clonedMesh.bindMatrix );\n\n\t} );\n\n\treturn clone;\n\n}\n\n// internal helper\n\nfunction getBoneByName( name, skeleton ) {\n\n\tfor ( let i = 0, bones = getBones( skeleton ); i < bones.length; i ++ ) {\n\n\t\tif ( name === bones[ i ].name )\n\n\t\t\treturn bones[ i ];\n\n\t}\n\n}\n\nfunction getBones( skeleton ) {\n\n\treturn Array.isArray( skeleton ) ? skeleton : skeleton.bones;\n\n}\n\n\nfunction getHelperFromSkeleton( skeleton ) {\n\n\tconst source = new SkeletonHelper( skeleton.bones[ 0 ] );\n\tsource.skeleton = skeleton;\n\n\treturn source;\n\n}\n\nfunction parallelTraverse( a, b, callback ) {\n\n\tcallback( a, b );\n\n\tfor ( let i = 0; i < a.children.length; i ++ ) {\n\n\t\tparallelTraverse( a.children[ i ], b.children[ i ], callback );\n\n\t}\n\n}\n\n/**\n * Retarget options of `SkeletonUtils`.\n *\n * @typedef {Object} module:SkeletonUtils~RetargetOptions\n * @property {boolean} [useFirstFramePosition=false] - Whether to use the position of the first frame or not.\n * @property {number} [fps] - The FPS of the clip.\n * @property {Object<string,string>} [names] - A dictionary for mapping target to source bone names.\n * @property {function(string):string} [getBoneName] - A function for mapping bone names. Alternative to `names`.\n * @property {Array<number>} [trim] - Whether to trim the clip or not. If set the array should hold two values for the start and end.\n * @property {boolean} [preserveBoneMatrix=true] - Whether to preserve bone matrices or not.\n * @property {boolean} [preserveBonePositions=true] - Whether to preserve bone positions or not.\n * @property {boolean} [useTargetMatrix=false] - Whether to use the target matrix or not.\n * @property {string} [hip='hip'] - The name of the source's hip bone.\n * @property {Vector3} [hipInfluence=(1,1,1)] - The hip influence.\n * @property {number} [scale=1] - The scale.\n * @property {Object<string,Matrix4>} [localOffsets] - Per-bone local offset matrices, keyed by bone name.\n * @property {Vector3} [hipPosition] - An additional position offset applied to the hip bone.\n **/\n\nexport {\n\tretarget,\n\tretargetClip,\n\tclone,\n};\n","import {\n\tAnimationClip,\n\tBone,\n\tBox3,\n\tBufferAttribute,\n\tBufferGeometry,\n\tClampToEdgeWrapping,\n\tColor,\n\tColorManagement,\n\tDirectionalLight,\n\tDoubleSide,\n\tFileLoader,\n\tFrontSide,\n\tGroup,\n\tImageBitmapLoader,\n\tInstancedMesh,\n\tInterleavedBuffer,\n\tInterleavedBufferAttribute,\n\tInterpolant,\n\tInterpolateDiscrete,\n\tInterpolateLinear,\n\tLine,\n\tLineBasicMaterial,\n\tLineLoop,\n\tLineSegments,\n\tLinearFilter,\n\tLinearMipmapLinearFilter,\n\tLinearMipmapNearestFilter,\n\tLinearSRGBColorSpace,\n\tLoader,\n\tLoaderUtils,\n\tMaterial,\n\tMathUtils,\n\tMatrix4,\n\tMesh,\n\tMeshBasicMaterial,\n\tMeshPhysicalMaterial,\n\tMeshStandardMaterial,\n\tMirroredRepeatWrapping,\n\tNearestFilter,\n\tNearestMipmapLinearFilter,\n\tNearestMipmapNearestFilter,\n\tNumberKeyframeTrack,\n\tObject3D,\n\tOrthographicCamera,\n\tPerspectiveCamera,\n\tPointLight,\n\tPoints,\n\tPointsMaterial,\n\tPropertyBinding,\n\tQuaternion,\n\tQuaternionKeyframeTrack,\n\tRepeatWrapping,\n\tSkeleton,\n\tSkinnedMesh,\n\tSphere,\n\tSpotLight,\n\tTexture,\n\tTextureLoader,\n\tTriangleFanDrawMode,\n\tTriangleStripDrawMode,\n\tVector2,\n\tVector3,\n\tVectorKeyframeTrack,\n\tSRGBColorSpace,\n\tInstancedBufferAttribute\n} from 'three';\nimport { toTrianglesDrawMode } from '../utils/BufferGeometryUtils.js';\nimport { clone } from '../utils/SkeletonUtils.js';\n\n/**\n * A loader for the glTF 2.0 format.\n *\n * [glTF](https://www.khronos.org/gltf/) (GL Transmission Format) is an [open format specification]{@link https://github.com/KhronosGroup/glTF/tree/main/specification/2.0)\n * for efficient delivery and loading of 3D content. Assets may be provided either in JSON (.gltf) or binary (.glb)\n * format. External files store textures (.jpg, .png) and additional binary data (.bin). A glTF asset may deliver\n * one or more scenes, including meshes, materials, textures, skins, skeletons, morph targets, animations, lights,\n * and/or cameras.\n *\n * `GLTFLoader` uses {@link ImageBitmapLoader} whenever possible. Be advised that image bitmaps are not\n * automatically GC-collected when they are no longer referenced, and they require special handling during\n * the disposal process.\n *\n * `GLTFLoader` supports the following glTF 2.0 extensions:\n * - KHR_draco_mesh_compression\n * - KHR_lights_punctual\n * - KHR_materials_anisotropy\n * - KHR_materials_clearcoat\n * - KHR_materials_dispersion\n * - KHR_materials_emissive_strength\n * - KHR_materials_ior\n * - KHR_materials_specular\n * - KHR_materials_transmission\n * - KHR_materials_iridescence\n * - KHR_materials_unlit\n * - KHR_materials_volume\n * - KHR_mesh_quantization\n * - KHR_meshopt_compression\n * - KHR_texture_basisu\n * - KHR_texture_transform\n * - EXT_materials_bump\n * - EXT_meshopt_compression\n * - EXT_mesh_gpu_instancing\n * - EXT_texture_avif\n * - EXT_texture_webp\n *\n * The following glTF 2.0 extension is supported by an external user plugin:\n * - [KHR_materials_variants](https://github.com/takahirox/three-gltf-extensions)\n * - [MSFT_texture_dds](https://github.com/takahirox/three-gltf-extensions)\n * - [KHR_animation_pointer](https://github.com/needle-tools/three-animation-pointer)\n * - [NEEDLE_progressive](https://github.com/needle-tools/gltf-progressive)\n *\n * ```js\n * const loader = new GLTFLoader();\n *\n * // Optional: Provide a DRACOLoader instance to decode compressed mesh data\n * const dracoLoader = new DRACOLoader();\n * dracoLoader.setDecoderPath( '/examples/jsm/libs/draco/' );\n * loader.setDRACOLoader( dracoLoader );\n *\n * const gltf = await loader.loadAsync( 'models/gltf/duck/duck.gltf' );\n * scene.add( gltf.scene );\n * ```\n *\n * @augments Loader\n * @three_import import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';\n */\nclass GLTFLoader extends Loader {\n\n\t/**\n\t * Constructs a new glTF loader.\n\t *\n\t * @param {LoadingManager} [manager] - The loading manager.\n\t */\n\tconstructor( manager ) {\n\n\t\tsuper( manager );\n\n\t\tthis.dracoLoader = null;\n\t\tthis.ktx2Loader = null;\n\t\tthis.meshoptDecoder = null;\n\n\t\tthis.pluginCallbacks = [];\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsClearcoatExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsDispersionExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFTextureBasisUExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFTextureWebPExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFTextureAVIFExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsSheenExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsTransmissionExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsVolumeExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsIorExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsEmissiveStrengthExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsSpecularExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsIridescenceExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsAnisotropyExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsBumpExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFLightsExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMeshoptCompression( parser, EXTENSIONS.EXT_MESHOPT_COMPRESSION );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMeshoptCompression( parser, EXTENSIONS.KHR_MESHOPT_COMPRESSION );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMeshGpuInstancing( parser );\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Starts loading from the given URL and passes the loaded glTF asset\n\t * to the `onLoad()` callback.\n\t *\n\t * @param {string} url - The path/URL of the file to be loaded. This can also be a data URI.\n\t * @param {function(GLTFLoader~LoadObject)} onLoad - Executed when the loading process has been finished.\n\t * @param {onProgressCallback} onProgress - Executed while the loading is in progress.\n\t * @param {onErrorCallback} onError - Executed when errors occur.\n\t */\n\tload( url, onLoad, onProgress, onError ) {\n\n\t\tconst scope = this;\n\n\t\tlet resourcePath;\n\n\t\tif ( this.resourcePath !== '' ) {\n\n\t\t\tresourcePath = this.resourcePath;\n\n\t\t} else if ( this.path !== '' ) {\n\n\t\t\t// If a base path is set, resources will be relative paths from that plus the relative path of the gltf file\n\t\t\t// Example path = 'https://my-cnd-server.com/', url = 'assets/models/model.gltf'\n\t\t\t// resourcePath = 'https://my-cnd-server.com/assets/models/'\n\t\t\t// referenced resource 'model.bin' will be loaded from 'https://my-cnd-server.com/assets/models/model.bin'\n\t\t\t// referenced resource '../textures/texture.png' will be loaded from 'https://my-cnd-server.com/assets/textures/texture.png'\n\t\t\tconst relativeUrl = LoaderUtils.extractUrlBase( url );\n\t\t\tresourcePath = LoaderUtils.resolveURL( relativeUrl, this.path );\n\n\t\t} else {\n\n\t\t\tresourcePath = LoaderUtils.extractUrlBase( url );\n\n\t\t}\n\n\t\t// Tells the LoadingManager to track an extra item, which resolves after\n\t\t// the model is fully loaded. This means the count of items loaded will\n\t\t// be incorrect, but ensures manager.onLoad() does not fire early.\n\t\tthis.manager.itemStart( url );\n\n\t\tconst _onError = function ( e ) {\n\n\t\t\tif ( onError ) {\n\n\t\t\t\tonError( e );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( e );\n\n\t\t\t}\n\n\t\t\tscope.manager.itemError( url );\n\t\t\tscope.manager.itemEnd( url );\n\n\t\t};\n\n\t\tconst loader = new FileLoader( this.manager );\n\n\t\tloader.setPath( this.path );\n\t\tloader.setResponseType( 'arraybuffer' );\n\t\tloader.setRequestHeader( this.requestHeader );\n\t\tloader.setWithCredentials( this.withCredentials );\n\n\t\tloader.load( url, function ( data ) {\n\n\t\t\ttry {\n\n\t\t\t\tscope.parse( data, resourcePath, function ( gltf ) {\n\n\t\t\t\t\tonLoad( gltf );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, _onError );\n\n\t\t\t} catch ( e ) {\n\n\t\t\t\t_onError( e );\n\n\t\t\t}\n\n\t\t}, onProgress, _onError );\n\n\t}\n\n\t/**\n\t * Sets the given Draco loader to this loader. Required for decoding assets\n\t * compressed with the `KHR_draco_mesh_compression` extension.\n\t *\n\t * @param {DRACOLoader} dracoLoader - The Draco loader to set.\n\t * @return {GLTFLoader} A reference to this loader.\n\t */\n\tsetDRACOLoader( dracoLoader ) {\n\n\t\tthis.dracoLoader = dracoLoader;\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * Sets the given KTX2 loader to this loader. Required for loading KTX2\n\t * compressed textures.\n\t *\n\t * @param {KTX2Loader} ktx2Loader - The KTX2 loader to set.\n\t * @return {GLTFLoader} A reference to this loader.\n\t */\n\tsetKTX2Loader( ktx2Loader ) {\n\n\t\tthis.ktx2Loader = ktx2Loader;\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * Sets the given meshopt decoder. Required for decoding assets\n\t * compressed with the `EXT_meshopt_compression` extension.\n\t *\n\t * @param {Object} meshoptDecoder - The meshopt decoder to set.\n\t * @return {GLTFLoader} A reference to this loader.\n\t */\n\tsetMeshoptDecoder( meshoptDecoder ) {\n\n\t\tthis.meshoptDecoder = meshoptDecoder;\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * Registers a plugin callback. This API is internally used to implement the various\n\t * glTF extensions but can also used by third-party code to add additional logic\n\t * to the loader.\n\t *\n\t * @param {function(parser:GLTFParser)} callback - The callback function to register.\n\t * @return {GLTFLoader} A reference to this loader.\n\t */\n\tregister( callback ) {\n\n\t\tif ( this.pluginCallbacks.indexOf( callback ) === - 1 ) {\n\n\t\t\tthis.pluginCallbacks.push( callback );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * Unregisters a plugin callback.\n\t *\n\t * @param {Function} callback - The callback function to unregister.\n\t * @return {GLTFLoader} A reference to this loader.\n\t */\n\tunregister( callback ) {\n\n\t\tif ( this.pluginCallbacks.indexOf( callback ) !== - 1 ) {\n\n\t\t\tthis.pluginCallbacks.splice( this.pluginCallbacks.indexOf( callback ), 1 );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * Parses the given glTF data and returns the resulting group.\n\t *\n\t * @param {string|ArrayBuffer} data - The raw glTF data.\n\t * @param {string} path - The URL base path.\n\t * @param {function(GLTFLoader~LoadObject)} onLoad - Executed when the loading process has been finished.\n\t * @param {onErrorCallback} onError - Executed when errors occur.\n\t */\n\tparse( data, path, onLoad, onError ) {\n\n\t\tlet json;\n\t\tconst extensions = {};\n\t\tconst plugins = {};\n\t\tconst textDecoder = new TextDecoder();\n\n\t\tif ( typeof data === 'string' ) {\n\n\t\t\tjson = JSON.parse( data );\n\n\t\t} else if ( data instanceof ArrayBuffer ) {\n\n\t\t\tconst magic = textDecoder.decode( new Uint8Array( data, 0, 4 ) );\n\n\t\t\tif ( magic === BINARY_EXTENSION_HEADER_MAGIC ) {\n\n\t\t\t\ttry {\n\n\t\t\t\t\textensions[ EXTENSIONS.KHR_BINARY_GLTF ] = new GLTFBinaryExtension( data );\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\tif ( onError ) onError( error );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tjson = JSON.parse( extensions[ EXTENSIONS.KHR_BINARY_GLTF ].content );\n\n\t\t\t} else {\n\n\t\t\t\tjson = JSON.parse( textDecoder.decode( data ) );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tjson = data;\n\n\t\t}\n\n\t\tif ( json.asset === undefined || json.asset.version[ 0 ] < 2 ) {\n\n\t\t\tif ( onError ) onError( new Error( 'THREE.GLTFLoader: Unsupported asset. glTF versions >=2.0 are supported.' ) );\n\t\t\treturn;\n\n\t\t}\n\n\t\tconst parser = new GLTFParser( json, {\n\n\t\t\tpath: path || this.resourcePath || '',\n\t\t\tcrossOrigin: this.crossOrigin,\n\t\t\trequestHeader: this.requestHeader,\n\t\t\tmanager: this.manager,\n\t\t\tktx2Loader: this.ktx2Loader,\n\t\t\tmeshoptDecoder: this.meshoptDecoder\n\n\t\t} );\n\n\t\tparser.fileLoader.setRequestHeader( this.requestHeader );\n\n\t\tfor ( let i = 0; i < this.pluginCallbacks.length; i ++ ) {\n\n\t\t\tconst plugin = this.pluginCallbacks[ i ]( parser );\n\n\t\t\tif ( ! plugin.name ) console.error( 'THREE.GLTFLoader: Invalid plugin found: missing name' );\n\n\t\t\tplugins[ plugin.name ] = plugin;\n\n\t\t\t// Workaround to avoid determining as unknown extension\n\t\t\t// in addUnknownExtensionsToUserData().\n\t\t\t// Remove this workaround if we move all the existing\n\t\t\t// extension handlers to plugin system\n\t\t\textensions[ plugin.name ] = true;\n\n\t\t}\n\n\t\tif ( json.extensionsUsed ) {\n\n\t\t\tfor ( let i = 0; i < json.extensionsUsed.length; ++ i ) {\n\n\t\t\t\tconst extensionName = json.extensionsUsed[ i ];\n\t\t\t\tconst extensionsRequired = json.extensionsRequired || [];\n\n\t\t\t\tswitch ( extensionName ) {\n\n\t\t\t\t\tcase EXTENSIONS.KHR_MATERIALS_UNLIT:\n\t\t\t\t\t\textensions[ extensionName ] = new GLTFMaterialsUnlitExtension();\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase EXTENSIONS.KHR_DRACO_MESH_COMPRESSION:\n\t\t\t\t\t\textensions[ extensionName ] = new GLTFDracoMeshCompressionExtension( json, this.dracoLoader );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase EXTENSIONS.KHR_TEXTURE_TRANSFORM:\n\t\t\t\t\t\textensions[ extensionName ] = new GLTFTextureTransformExtension();\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase EXTENSIONS.KHR_MESH_QUANTIZATION:\n\t\t\t\t\t\textensions[ extensionName ] = new GLTFMeshQuantizationExtension();\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tif ( extensionsRequired.indexOf( extensionName ) >= 0 && plugins[ extensionName ] === undefined ) {\n\n\t\t\t\t\t\t\tconsole.warn( 'THREE.GLTFLoader: Unknown extension \"' + extensionName + '\".' );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tparser.setExtensions( extensions );\n\t\tparser.setPlugins( plugins );\n\t\tparser.parse( onLoad, onError );\n\n\t}\n\n\t/**\n\t * Async version of {@link GLTFLoader#parse}.\n\t *\n\t * @async\n\t * @param {string|ArrayBuffer} data - The raw glTF data.\n\t * @param {string} path - The URL base path.\n\t * @return {Promise<GLTFLoader~LoadObject>} A Promise that resolves with the loaded glTF when the parsing has been finished.\n\t */\n\tparseAsync( data, path ) {\n\n\t\tconst scope = this;\n\n\t\treturn new Promise( function ( resolve, reject ) {\n\n\t\t\tscope.parse( data, path, resolve, reject );\n\n\t\t} );\n\n\t}\n\n}\n\n/* GLTFREGISTRY */\n\nfunction GLTFRegistry() {\n\n\tlet objects = {};\n\n\treturn\t{\n\n\t\tget: function ( key ) {\n\n\t\t\treturn objects[ key ];\n\n\t\t},\n\n\t\tadd: function ( key, object ) {\n\n\t\t\tobjects[ key ] = object;\n\n\t\t},\n\n\t\tremove: function ( key ) {\n\n\t\t\tdelete objects[ key ];\n\n\t\t},\n\n\t\tremoveAll: function () {\n\n\t\t\tobjects = {};\n\n\t\t}\n\n\t};\n\n}\n\n/*********************************/\n/********** EXTENSIONS ***********/\n/*********************************/\n\nfunction getMaterialExtension( parser, materialIndex, extensionName ) {\n\n\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\tif ( materialDef.extensions && materialDef.extensions[ extensionName ] ) {\n\n\t\treturn materialDef.extensions[ extensionName ];\n\n\t}\n\n\treturn null;\n\n}\n\nconst EXTENSIONS = {\n\tKHR_BINARY_GLTF: 'KHR_binary_glTF',\n\tKHR_DRACO_MESH_COMPRESSION: 'KHR_draco_mesh_compression',\n\tKHR_LIGHTS_PUNCTUAL: 'KHR_lights_punctual',\n\tKHR_MATERIALS_CLEARCOAT: 'KHR_materials_clearcoat',\n\tKHR_MATERIALS_DISPERSION: 'KHR_materials_dispersion',\n\tKHR_MATERIALS_IOR: 'KHR_materials_ior',\n\tKHR_MATERIALS_SHEEN: 'KHR_materials_sheen',\n\tKHR_MATERIALS_SPECULAR: 'KHR_materials_specular',\n\tKHR_MATERIALS_TRANSMISSION: 'KHR_materials_transmission',\n\tKHR_MATERIALS_IRIDESCENCE: 'KHR_materials_iridescence',\n\tKHR_MATERIALS_ANISOTROPY: 'KHR_materials_anisotropy',\n\tKHR_MATERIALS_UNLIT: 'KHR_materials_unlit',\n\tKHR_MATERIALS_VOLUME: 'KHR_materials_volume',\n\tKHR_TEXTURE_BASISU: 'KHR_texture_basisu',\n\tKHR_TEXTURE_TRANSFORM: 'KHR_texture_transform',\n\tKHR_MESH_QUANTIZATION: 'KHR_mesh_quantization',\n\tKHR_MATERIALS_EMISSIVE_STRENGTH: 'KHR_materials_emissive_strength',\n\tEXT_MATERIALS_BUMP: 'EXT_materials_bump',\n\tEXT_TEXTURE_WEBP: 'EXT_texture_webp',\n\tEXT_TEXTURE_AVIF: 'EXT_texture_avif',\n\tEXT_MESHOPT_COMPRESSION: 'EXT_meshopt_compression',\n\tKHR_MESHOPT_COMPRESSION: 'KHR_meshopt_compression',\n\tEXT_MESH_GPU_INSTANCING: 'EXT_mesh_gpu_instancing'\n};\n\n/**\n * Punctual Lights Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual\n *\n * @private\n */\nclass GLTFLightsExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_LIGHTS_PUNCTUAL;\n\n\t\t// Object3D instance caches\n\t\tthis.cache = { refs: {}, uses: {} };\n\n\t}\n\n\t_markDefs() {\n\n\t\tconst parser = this.parser;\n\t\tconst nodeDefs = this.parser.json.nodes || [];\n\n\t\tfor ( let nodeIndex = 0, nodeLength = nodeDefs.length; nodeIndex < nodeLength; nodeIndex ++ ) {\n\n\t\t\tconst nodeDef = nodeDefs[ nodeIndex ];\n\n\t\t\tif ( nodeDef.extensions\n\t\t\t\t\t&& nodeDef.extensions[ this.name ]\n\t\t\t\t\t&& nodeDef.extensions[ this.name ].light !== undefined ) {\n\n\t\t\t\tparser._addNodeRef( this.cache, nodeDef.extensions[ this.name ].light );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t_loadLight( lightIndex ) {\n\n\t\tconst parser = this.parser;\n\t\tconst cacheKey = 'light:' + lightIndex;\n\t\tlet dependency = parser.cache.get( cacheKey );\n\n\t\tif ( dependency ) return dependency;\n\n\t\tconst json = parser.json;\n\t\tconst extensions = ( json.extensions && json.extensions[ this.name ] ) || {};\n\t\tconst lightDefs = extensions.lights || [];\n\t\tconst lightDef = lightDefs[ lightIndex ];\n\t\tlet lightNode;\n\n\t\tconst color = new Color( 0xffffff );\n\n\t\tif ( lightDef.color !== undefined ) color.setRGB( lightDef.color[ 0 ], lightDef.color[ 1 ], lightDef.color[ 2 ], LinearSRGBColorSpace );\n\n\t\tconst range = lightDef.range !== undefined ? lightDef.range : 0;\n\n\t\tswitch ( lightDef.type ) {\n\n\t\t\tcase 'directional':\n\t\t\t\tlightNode = new DirectionalLight( color );\n\t\t\t\tlightNode.target.position.set( 0, 0, - 1 );\n\t\t\t\tlightNode.add( lightNode.target );\n\t\t\t\tbreak;\n\n\t\t\tcase 'point':\n\t\t\t\tlightNode = new PointLight( color );\n\t\t\t\tlightNode.distance = range;\n\t\t\t\tbreak;\n\n\t\t\tcase 'spot':\n\t\t\t\tlightNode = new SpotLight( color );\n\t\t\t\tlightNode.distance = range;\n\t\t\t\t// Handle spotlight properties.\n\t\t\t\tlightDef.spot = lightDef.spot || {};\n\t\t\t\tlightDef.spot.innerConeAngle = lightDef.spot.innerConeAngle !== undefined ? lightDef.spot.innerConeAngle : 0;\n\t\t\t\tlightDef.spot.outerConeAngle = lightDef.spot.outerConeAngle !== undefined ? lightDef.spot.outerConeAngle : Math.PI / 4.0;\n\t\t\t\tlightNode.angle = lightDef.spot.outerConeAngle;\n\t\t\t\tlightNode.penumbra = 1.0 - lightDef.spot.innerConeAngle / lightDef.spot.outerConeAngle;\n\t\t\t\tlightNode.target.position.set( 0, 0, - 1 );\n\t\t\t\tlightNode.add( lightNode.target );\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'THREE.GLTFLoader: Unexpected light type: ' + lightDef.type );\n\n\t\t}\n\n\t\t// Some lights (e.g. spot) default to a position other than the origin. Reset the position\n\t\t// here, because node-level parsing will only override position if explicitly specified.\n\t\tlightNode.position.set( 0, 0, 0 );\n\n\t\tassignExtrasToUserData( lightNode, lightDef );\n\n\t\tif ( lightDef.intensity !== undefined ) lightNode.intensity = lightDef.intensity;\n\n\t\tlightNode.name = parser.createUniqueName( lightDef.name || ( 'light_' + lightIndex ) );\n\n\t\tdependency = Promise.resolve( lightNode );\n\n\t\tparser.cache.add( cacheKey, dependency );\n\n\t\treturn dependency;\n\n\t}\n\n\tgetDependency( type, index ) {\n\n\t\tif ( type !== 'light' ) return;\n\n\t\treturn this._loadLight( index );\n\n\t}\n\n\tcreateNodeAttachment( nodeIndex ) {\n\n\t\tconst self = this;\n\t\tconst parser = this.parser;\n\t\tconst json = parser.json;\n\t\tconst nodeDef = json.nodes[ nodeIndex ];\n\t\tconst lightDef = ( nodeDef.extensions && nodeDef.extensions[ this.name ] ) || {};\n\t\tconst lightIndex = lightDef.light;\n\n\t\tif ( lightIndex === undefined ) return null;\n\n\t\treturn this._loadLight( lightIndex ).then( function ( light ) {\n\n\t\t\treturn parser._getNodeRef( self.cache, lightIndex, light );\n\n\t\t} );\n\n\t}\n\n}\n\n/**\n * Unlit Materials Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit\n *\n * @private\n */\nclass GLTFMaterialsUnlitExtension {\n\n\tconstructor() {\n\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_UNLIT;\n\n\t}\n\n\tgetMaterialType() {\n\n\t\treturn MeshBasicMaterial;\n\n\t}\n\n\textendParams( materialParams, materialDef, parser ) {\n\n\t\tconst pending = [];\n\n\t\tmaterialParams.color = new Color( 1.0, 1.0, 1.0 );\n\t\tmaterialParams.opacity = 1.0;\n\n\t\tconst metallicRoughness = materialDef.pbrMetallicRoughness;\n\n\t\tif ( metallicRoughness ) {\n\n\t\t\tif ( Array.isArray( metallicRoughness.baseColorFactor ) ) {\n\n\t\t\t\tconst array = metallicRoughness.baseColorFactor;\n\n\t\t\t\tmaterialParams.color.setRGB( array[ 0 ], array[ 1 ], array[ 2 ], LinearSRGBColorSpace );\n\t\t\t\tmaterialParams.opacity = array[ 3 ];\n\n\t\t\t}\n\n\t\t\tif ( metallicRoughness.baseColorTexture !== undefined ) {\n\n\t\t\t\tpending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture, SRGBColorSpace ) );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Materials Emissive Strength Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/blob/5768b3ce0ef32bc39cdf1bef10b948586635ead3/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md\n *\n * @private\n */\nclass GLTFMaterialsEmissiveStrengthExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_EMISSIVE_STRENGTH;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\tif ( extension === null ) return Promise.resolve();\n\n\t\tif ( extension.emissiveStrength !== undefined ) {\n\n\t\t\tmaterialParams.emissiveIntensity = extension.emissiveStrength;\n\n\t\t}\n\n\t\treturn Promise.resolve();\n\n\t}\n\n}\n\n/**\n * Clearcoat Materials Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_clearcoat\n *\n * @private\n */\nclass GLTFMaterialsClearcoatExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_CLEARCOAT;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\treturn extension !== null ? MeshPhysicalMaterial : null;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\tif ( extension === null ) return Promise.resolve();\n\n\t\tconst pending = [];\n\n\t\tif ( extension.clearcoatFactor !== undefined ) {\n\n\t\t\tmaterialParams.clearcoat = extension.clearcoatFactor;\n\n\t\t}\n\n\t\tif ( extension.clearcoatTexture !== undefined ) {\n\n\t\t\tpending.push( this.parser.assignTexture( materialParams, 'clearcoatMap', extension.clearcoatTexture ) );\n\n\t\t}\n\n\t\tif ( extension.clearcoatRoughnessFactor !== undefined ) {\n\n\t\t\tmaterialParams.clearcoatRoughness = extension.clearcoatRoughnessFactor;\n\n\t\t}\n\n\t\tif ( extension.clearcoatRoughnessTexture !== undefined ) {\n\n\t\t\tpending.push( this.parser.assignTexture( materialParams, 'clearcoatRoughnessMap', extension.clearcoatRoughnessTexture ) );\n\n\t\t}\n\n\t\tif ( extension.clearcoatNormalTexture !== undefined ) {\n\n\t\t\tpending.push( this.parser.assignTexture( materialParams, 'clearcoatNormalMap', extension.clearcoatNormalTexture ) );\n\n\t\t\tif ( extension.clearcoatNormalTexture.scale !== undefined ) {\n\n\t\t\t\tconst scale = extension.clearcoatNormalTexture.scale;\n\n\t\t\t\tmaterialParams.clearcoatNormalScale = new Vector2( scale, scale );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Materials dispersion Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_dispersion\n *\n * @private\n */\nclass GLTFMaterialsDispersionExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_DISPERSION;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\treturn extension !== null ? MeshPhysicalMaterial : null;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\tif ( extension === null ) return Promise.resolve();\n\n\t\tmaterialParams.dispersion = extension.dispersion !== undefined ? extension.dispersion : 0;\n\n\t\treturn Promise.resolve();\n\n\t}\n\n}\n\n/**\n * Iridescence Materials Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_iridescence\n *\n * @private\n */\nclass GLTFMaterialsIridescenceExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_IRIDESCENCE;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\treturn extension !== null ? MeshPhysicalMaterial : null;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\tif ( extension === null ) return Promise.resolve();\n\n\t\tconst pending = [];\n\n\t\tif ( extension.iridescenceFactor !== undefined ) {\n\n\t\t\tmaterialParams.iridescence = extension.iridescenceFactor;\n\n\t\t}\n\n\t\tif ( extension.iridescenceTexture !== undefined ) {\n\n\t\t\tpending.push( this.parser.assignTexture( materialParams, 'iridescenceMap', extension.iridescenceTexture ) );\n\n\t\t}\n\n\t\tif ( extension.iridescenceIor !== undefined ) {\n\n\t\t\tmaterialParams.iridescenceIOR = extension.iridescenceIor;\n\n\t\t}\n\n\t\tif ( materialParams.iridescenceThicknessRange === undefined ) {\n\n\t\t\tmaterialParams.iridescenceThicknessRange = [ 100, 400 ];\n\n\t\t}\n\n\t\tif ( extension.iridescenceThicknessMinimum !== undefined ) {\n\n\t\t\tmaterialParams.iridescenceThicknessRange[ 0 ] = extension.iridescenceThicknessMinimum;\n\n\t\t}\n\n\t\tif ( extension.iridescenceThicknessMaximum !== undefined ) {\n\n\t\t\tmaterialParams.iridescenceThicknessRange[ 1 ] = extension.iridescenceThicknessMaximum;\n\n\t\t}\n\n\t\tif ( extension.iridescenceThicknessTexture !== undefined ) {\n\n\t\t\tpending.push( this.parser.assignTexture( materialParams, 'iridescenceThicknessMap', extension.iridescenceThicknessTexture ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Sheen Materials Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_sheen\n *\n * @private\n */\nclass GLTFMaterialsSheenExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_SHEEN;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\treturn extension !== null ? MeshPhysicalMaterial : null;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\tif ( extension === null ) return Promise.resolve();\n\n\t\tconst pending = [];\n\n\t\tmaterialParams.sheenColor = new Color( 0, 0, 0 );\n\t\tmaterialParams.sheenRoughness = 0;\n\t\tmaterialParams.sheen = 1;\n\n\t\tif ( extension.sheenColorFactor !== undefined ) {\n\n\t\t\tconst colorFactor = extension.sheenColorFactor;\n\t\t\tmaterialParams.sheenColor.setRGB( colorFactor[ 0 ], colorFactor[ 1 ], colorFactor[ 2 ], LinearSRGBColorSpace );\n\n\t\t}\n\n\t\tif ( extension.sheenRoughnessFactor !== undefined ) {\n\n\t\t\tmaterialParams.sheenRoughness = extension.sheenRoughnessFactor;\n\n\t\t}\n\n\t\tif ( extension.sheenColorTexture !== undefined ) {\n\n\t\t\tpending.push( this.parser.assignTexture( materialParams, 'sheenColorMap', extension.sheenColorTexture, SRGBColorSpace ) );\n\n\t\t}\n\n\t\tif ( extension.sheenRoughnessTexture !== undefined ) {\n\n\t\t\tpending.push( this.parser.assignTexture( materialParams, 'sheenRoughnessMap', extension.sheenRoughnessTexture ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Transmission Materials Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_transmission\n * Draft: https://github.com/KhronosGroup/glTF/pull/1698\n *\n * @private\n */\nclass GLTFMaterialsTransmissionExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_TRANSMISSION;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\treturn extension !== null ? MeshPhysicalMaterial : null;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\tif ( extension === null ) return Promise.resolve();\n\n\t\tconst pending = [];\n\n\t\tif ( extension.transmissionFactor !== undefined ) {\n\n\t\t\tmaterialParams.transmission = extension.transmissionFactor;\n\n\t\t}\n\n\t\tif ( extension.transmissionTexture !== undefined ) {\n\n\t\t\tpending.push( this.parser.assignTexture( materialParams, 'transmissionMap', extension.transmissionTexture ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Materials Volume Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_volume\n *\n * @private\n */\nclass GLTFMaterialsVolumeExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_VOLUME;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\treturn extension !== null ? MeshPhysicalMaterial : null;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\tif ( extension === null ) return Promise.resolve();\n\n\t\tconst pending = [];\n\n\t\tmaterialParams.thickness = extension.thicknessFactor !== undefined ? extension.thicknessFactor : 0;\n\n\t\tif ( extension.thicknessTexture !== undefined ) {\n\n\t\t\tpending.push( this.parser.assignTexture( materialParams, 'thicknessMap', extension.thicknessTexture ) );\n\n\t\t}\n\n\t\tmaterialParams.attenuationDistance = extension.attenuationDistance || Infinity;\n\n\t\tconst colorArray = extension.attenuationColor || [ 1, 1, 1 ];\n\t\tmaterialParams.attenuationColor = new Color().setRGB( colorArray[ 0 ], colorArray[ 1 ], colorArray[ 2 ], LinearSRGBColorSpace );\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Materials ior Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_ior\n *\n * @private\n */\nclass GLTFMaterialsIorExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_IOR;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\treturn extension !== null ? MeshPhysicalMaterial : null;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\tif ( extension === null ) return Promise.resolve();\n\n\t\tmaterialParams.ior = extension.ior !== undefined ? extension.ior : 1.5;\n\n\t\tif ( materialParams.ior === 0 ) materialParams.ior = 1000; // see #26167\n\n\t\treturn Promise.resolve();\n\n\t}\n\n}\n\n/**\n * Materials specular Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_specular\n *\n * @private\n */\nclass GLTFMaterialsSpecularExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_SPECULAR;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\treturn extension !== null ? MeshPhysicalMaterial : null;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\tif ( extension === null ) return Promise.resolve();\n\n\t\tconst pending = [];\n\n\t\tmaterialParams.specularIntensity = extension.specularFactor !== undefined ? extension.specularFactor : 1.0;\n\n\t\tif ( extension.specularTexture !== undefined ) {\n\n\t\t\tpending.push( this.parser.assignTexture( materialParams, 'specularIntensityMap', extension.specularTexture ) );\n\n\t\t}\n\n\t\tconst colorArray = extension.specularColorFactor || [ 1, 1, 1 ];\n\t\tmaterialParams.specularColor = new Color().setRGB( colorArray[ 0 ], colorArray[ 1 ], colorArray[ 2 ], LinearSRGBColorSpace );\n\n\t\tif ( extension.specularColorTexture !== undefined ) {\n\n\t\t\tpending.push( this.parser.assignTexture( materialParams, 'specularColorMap', extension.specularColorTexture, SRGBColorSpace ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n\n/**\n * Materials bump Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/EXT_materials_bump\n *\n * @private\n */\nclass GLTFMaterialsBumpExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.EXT_MATERIALS_BUMP;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\treturn extension !== null ? MeshPhysicalMaterial : null;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\tif ( extension === null ) return Promise.resolve();\n\n\t\tconst pending = [];\n\n\t\tmaterialParams.bumpScale = extension.bumpFactor !== undefined ? extension.bumpFactor : 1.0;\n\n\t\tif ( extension.bumpTexture !== undefined ) {\n\n\t\t\tpending.push( this.parser.assignTexture( materialParams, 'bumpMap', extension.bumpTexture ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Materials anisotropy Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_anisotropy\n *\n * @private\n */\nclass GLTFMaterialsAnisotropyExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_ANISOTROPY;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\treturn extension !== null ? MeshPhysicalMaterial : null;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\tif ( extension === null ) return Promise.resolve();\n\n\t\tconst pending = [];\n\n\t\tif ( extension.anisotropyStrength !== undefined ) {\n\n\t\t\tmaterialParams.anisotropy = extension.anisotropyStrength;\n\n\t\t}\n\n\t\tif ( extension.anisotropyRotation !== undefined ) {\n\n\t\t\tmaterialParams.anisotropyRotation = extension.anisotropyRotation;\n\n\t\t}\n\n\t\tif ( extension.anisotropyTexture !== undefined ) {\n\n\t\t\tpending.push( this.parser.assignTexture( materialParams, 'anisotropyMap', extension.anisotropyTexture ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * BasisU Texture Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_texture_basisu\n *\n * @private\n */\nclass GLTFTextureBasisUExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_TEXTURE_BASISU;\n\n\t}\n\n\tloadTexture( textureIndex ) {\n\n\t\tconst parser = this.parser;\n\t\tconst json = parser.json;\n\n\t\tconst textureDef = json.textures[ textureIndex ];\n\n\t\tif ( ! textureDef.extensions || ! textureDef.extensions[ this.name ] ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\tconst extension = textureDef.extensions[ this.name ];\n\t\tconst loader = parser.options.ktx2Loader;\n\n\t\tif ( ! loader ) {\n\n\t\t\tif ( json.extensionsRequired && json.extensionsRequired.indexOf( this.name ) >= 0 ) {\n\n\t\t\t\tthrow new Error( 'THREE.GLTFLoader: setKTX2Loader must be called before loading KTX2 textures' );\n\n\t\t\t} else {\n\n\t\t\t\t// Assumes that the extension is optional and that a fallback texture is present\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn parser.loadTextureImage( textureIndex, extension.source, loader );\n\n\t}\n\n}\n\n/**\n * WebP Texture Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_texture_webp\n *\n * @private\n */\nclass GLTFTextureWebPExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.EXT_TEXTURE_WEBP;\n\n\t}\n\n\tloadTexture( textureIndex ) {\n\n\t\tconst name = this.name;\n\t\tconst parser = this.parser;\n\t\tconst json = parser.json;\n\n\t\tconst textureDef = json.textures[ textureIndex ];\n\n\t\tif ( ! textureDef.extensions || ! textureDef.extensions[ name ] ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\tconst extension = textureDef.extensions[ name ];\n\t\tconst source = json.images[ extension.source ];\n\n\t\tlet loader = parser.textureLoader;\n\t\tif ( source.uri ) {\n\n\t\t\tconst handler = parser.options.manager.getHandler( source.uri );\n\t\t\tif ( handler !== null ) loader = handler;\n\n\t\t}\n\n\t\treturn parser.loadTextureImage( textureIndex, extension.source, loader );\n\n\t}\n\n}\n\n/**\n * AVIF Texture Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_texture_avif\n *\n * @private\n */\nclass GLTFTextureAVIFExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.EXT_TEXTURE_AVIF;\n\n\t}\n\n\tloadTexture( textureIndex ) {\n\n\t\tconst name = this.name;\n\t\tconst parser = this.parser;\n\t\tconst json = parser.json;\n\n\t\tconst textureDef = json.textures[ textureIndex ];\n\n\t\tif ( ! textureDef.extensions || ! textureDef.extensions[ name ] ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\tconst extension = textureDef.extensions[ name ];\n\t\tconst source = json.images[ extension.source ];\n\n\t\tlet loader = parser.textureLoader;\n\t\tif ( source.uri ) {\n\n\t\t\tconst handler = parser.options.manager.getHandler( source.uri );\n\t\t\tif ( handler !== null ) loader = handler;\n\n\t\t}\n\n\t\treturn parser.loadTextureImage( textureIndex, extension.source, loader );\n\n\t}\n\n}\n\n/**\n * meshopt BufferView Compression Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_meshopt_compression\n *\n * @private\n */\nclass GLTFMeshoptCompression {\n\n\tconstructor( parser, name ) {\n\n\t\tthis.name = name;\n\t\tthis.parser = parser;\n\n\t}\n\n\tloadBufferView( index ) {\n\n\t\tconst json = this.parser.json;\n\t\tconst bufferView = json.bufferViews[ index ];\n\n\t\tif ( bufferView.extensions && bufferView.extensions[ this.name ] ) {\n\n\t\t\tconst extensionDef = bufferView.extensions[ this.name ];\n\n\t\t\tconst buffer = this.parser.getDependency( 'buffer', extensionDef.buffer );\n\t\t\tconst decoder = this.parser.options.meshoptDecoder;\n\n\t\t\tif ( ! decoder || ! decoder.supported ) {\n\n\t\t\t\tif ( json.extensionsRequired && json.extensionsRequired.indexOf( this.name ) >= 0 ) {\n\n\t\t\t\t\tthrow new Error( 'THREE.GLTFLoader: setMeshoptDecoder must be called before loading compressed files' );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Assumes that the extension is optional and that fallback buffer data is present\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn buffer.then( function ( res ) {\n\n\t\t\t\tconst byteOffset = extensionDef.byteOffset || 0;\n\t\t\t\tconst byteLength = extensionDef.byteLength || 0;\n\n\t\t\t\tconst count = extensionDef.count;\n\t\t\t\tconst stride = extensionDef.byteStride;\n\n\t\t\t\tconst source = new Uint8Array( res, byteOffset, byteLength );\n\n\t\t\t\tif ( decoder.decodeGltfBufferAsync ) {\n\n\t\t\t\t\treturn decoder.decodeGltfBufferAsync( count, stride, source, extensionDef.mode, extensionDef.filter ).then( function ( res ) {\n\n\t\t\t\t\t\treturn res.buffer;\n\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Support for MeshoptDecoder 0.18 or earlier, without decodeGltfBufferAsync\n\t\t\t\t\treturn decoder.ready.then( function () {\n\n\t\t\t\t\t\tconst result = new ArrayBuffer( count * stride );\n\t\t\t\t\t\tdecoder.decodeGltfBuffer( new Uint8Array( result ), count, stride, source, extensionDef.mode, extensionDef.filter );\n\t\t\t\t\t\treturn result;\n\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t} else {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t}\n\n}\n\n/**\n * GPU Instancing Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_mesh_gpu_instancing\n *\n * @private\n */\nclass GLTFMeshGpuInstancing {\n\n\tconstructor( parser ) {\n\n\t\tthis.name = EXTENSIONS.EXT_MESH_GPU_INSTANCING;\n\t\tthis.parser = parser;\n\n\t}\n\n\tcreateNodeMesh( nodeIndex ) {\n\n\t\tconst json = this.parser.json;\n\t\tconst nodeDef = json.nodes[ nodeIndex ];\n\n\t\tif ( ! nodeDef.extensions || ! nodeDef.extensions[ this.name ] ||\n\t\t\tnodeDef.mesh === undefined ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\tconst meshDef = json.meshes[ nodeDef.mesh ];\n\n\t\t// No Points or Lines + Instancing support yet\n\n\t\tfor ( const primitive of meshDef.primitives ) {\n\n\t\t\tif ( primitive.mode !== WEBGL_CONSTANTS.TRIANGLES &&\n\t\t\t\t primitive.mode !== WEBGL_CONSTANTS.TRIANGLE_STRIP &&\n\t\t\t\t primitive.mode !== WEBGL_CONSTANTS.TRIANGLE_FAN &&\n\t\t\t\t primitive.mode !== undefined ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst extensionDef = nodeDef.extensions[ this.name ];\n\t\tconst attributesDef = extensionDef.attributes;\n\n\t\t// @TODO: Can we support InstancedMesh + SkinnedMesh?\n\n\t\tconst pending = [];\n\t\tconst attributes = {};\n\n\t\tfor ( const key in attributesDef ) {\n\n\t\t\tpending.push( this.parser.getDependency( 'accessor', attributesDef[ key ] ).then( accessor => {\n\n\t\t\t\tattributes[ key ] = accessor;\n\t\t\t\treturn attributes[ key ];\n\n\t\t\t} ) );\n\n\t\t}\n\n\t\tif ( pending.length < 1 ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\tpending.push( this.parser.createNodeMesh( nodeIndex ) );\n\n\t\treturn Promise.all( pending ).then( results => {\n\n\t\t\tconst nodeObject = results.pop();\n\t\t\tconst meshes = nodeObject.isGroup ? nodeObject.children : [ nodeObject ];\n\t\t\tconst count = results[ 0 ].count; // All attribute counts should be same\n\t\t\tconst instancedMeshes = [];\n\n\t\t\tfor ( const mesh of meshes ) {\n\n\t\t\t\t// Temporal variables\n\t\t\t\tconst m = new Matrix4();\n\t\t\t\tconst p = new Vector3();\n\t\t\t\tconst q = new Quaternion();\n\t\t\t\tconst s = new Vector3( 1, 1, 1 );\n\n\t\t\t\tconst instancedMesh = new InstancedMesh( mesh.geometry, mesh.material, count );\n\n\t\t\t\tfor ( let i = 0; i < count; i ++ ) {\n\n\t\t\t\t\tif ( attributes.TRANSLATION ) {\n\n\t\t\t\t\t\tp.fromBufferAttribute( attributes.TRANSLATION, i );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( attributes.ROTATION ) {\n\n\t\t\t\t\t\tq.fromBufferAttribute( attributes.ROTATION, i );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( attributes.SCALE ) {\n\n\t\t\t\t\t\ts.fromBufferAttribute( attributes.SCALE, i );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tinstancedMesh.setMatrixAt( i, m.compose( p, q, s ) );\n\n\t\t\t\t}\n\n\t\t\t\t// Add instance attributes to the geometry, excluding TRS.\n\t\t\t\tfor ( const attributeName in attributes ) {\n\n\t\t\t\t\tif ( attributeName === '_COLOR_0' ) {\n\n\t\t\t\t\t\tconst attr = attributes[ attributeName ];\n\t\t\t\t\t\tinstancedMesh.instanceColor = new InstancedBufferAttribute( attr.array, attr.itemSize, attr.normalized );\n\n\t\t\t\t\t} else if ( attributeName !== 'TRANSLATION' &&\n\t\t\t\t\t\t attributeName !== 'ROTATION' &&\n\t\t\t\t\t\t attributeName !== 'SCALE' ) {\n\n\t\t\t\t\t\tmesh.geometry.setAttribute( attributeName, attributes[ attributeName ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// Just in case\n\t\t\t\tObject3D.prototype.copy.call( instancedMesh, mesh );\n\n\t\t\t\tthis.parser.assignFinalMaterial( instancedMesh );\n\n\t\t\t\tinstancedMeshes.push( instancedMesh );\n\n\t\t\t}\n\n\t\t\tif ( nodeObject.isGroup ) {\n\n\t\t\t\tnodeObject.clear();\n\n\t\t\t\tnodeObject.add( ... instancedMeshes );\n\n\t\t\t\treturn nodeObject;\n\n\t\t\t}\n\n\t\t\treturn instancedMeshes[ 0 ];\n\n\t\t} );\n\n\t}\n\n}\n\n/* BINARY EXTENSION */\nconst BINARY_EXTENSION_HEADER_MAGIC = 'glTF';\nconst BINARY_EXTENSION_HEADER_LENGTH = 12;\nconst BINARY_EXTENSION_CHUNK_TYPES = { JSON: 0x4E4F534A, BIN: 0x004E4942 };\n\nclass GLTFBinaryExtension {\n\n\tconstructor( data ) {\n\n\t\tthis.name = EXTENSIONS.KHR_BINARY_GLTF;\n\t\tthis.content = null;\n\t\tthis.body = null;\n\n\t\tconst headerView = new DataView( data, 0, BINARY_EXTENSION_HEADER_LENGTH );\n\t\tconst textDecoder = new TextDecoder();\n\n\t\tthis.header = {\n\t\t\tmagic: textDecoder.decode( new Uint8Array( data.slice( 0, 4 ) ) ),\n\t\t\tversion: headerView.getUint32( 4, true ),\n\t\t\tlength: headerView.getUint32( 8, true )\n\t\t};\n\n\t\tif ( this.header.magic !== BINARY_EXTENSION_HEADER_MAGIC ) {\n\n\t\t\tthrow new Error( 'THREE.GLTFLoader: Unsupported glTF-Binary header.' );\n\n\t\t} else if ( this.header.version < 2.0 ) {\n\n\t\t\tthrow new Error( 'THREE.GLTFLoader: Legacy binary file detected.' );\n\n\t\t}\n\n\t\tconst chunkContentsLength = this.header.length - BINARY_EXTENSION_HEADER_LENGTH;\n\t\tconst chunkView = new DataView( data, BINARY_EXTENSION_HEADER_LENGTH );\n\t\tlet chunkIndex = 0;\n\n\t\twhile ( chunkIndex < chunkContentsLength ) {\n\n\t\t\tconst chunkLength = chunkView.getUint32( chunkIndex, true );\n\t\t\tchunkIndex += 4;\n\n\t\t\tconst chunkType = chunkView.getUint32( chunkIndex, true );\n\t\t\tchunkIndex += 4;\n\n\t\t\tif ( chunkType === BINARY_EXTENSION_CHUNK_TYPES.JSON ) {\n\n\t\t\t\tconst contentArray = new Uint8Array( data, BINARY_EXTENSION_HEADER_LENGTH + chunkIndex, chunkLength );\n\t\t\t\tthis.content = textDecoder.decode( contentArray );\n\n\t\t\t} else if ( chunkType === BINARY_EXTENSION_CHUNK_TYPES.BIN ) {\n\n\t\t\t\tconst byteOffset = BINARY_EXTENSION_HEADER_LENGTH + chunkIndex;\n\t\t\t\tthis.body = data.slice( byteOffset, byteOffset + chunkLength );\n\n\t\t\t}\n\n\t\t\t// Clients must ignore chunks with unknown types.\n\n\t\t\tchunkIndex += chunkLength;\n\n\t\t}\n\n\t\tif ( this.content === null ) {\n\n\t\t\tthrow new Error( 'THREE.GLTFLoader: JSON content not found.' );\n\n\t\t}\n\n\t}\n\n}\n\n/**\n * DRACO Mesh Compression Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_draco_mesh_compression\n *\n * @private\n */\nclass GLTFDracoMeshCompressionExtension {\n\n\tconstructor( json, dracoLoader ) {\n\n\t\tif ( ! dracoLoader ) {\n\n\t\t\tthrow new Error( 'THREE.GLTFLoader: No DRACOLoader instance provided.' );\n\n\t\t}\n\n\t\tthis.name = EXTENSIONS.KHR_DRACO_MESH_COMPRESSION;\n\t\tthis.json = json;\n\t\tthis.dracoLoader = dracoLoader;\n\t\tthis.dracoLoader.preload();\n\n\t}\n\n\tdecodePrimitive( primitive, parser ) {\n\n\t\tconst json = this.json;\n\t\tconst dracoLoader = this.dracoLoader;\n\t\tconst bufferViewIndex = primitive.extensions[ this.name ].bufferView;\n\t\tconst gltfAttributeMap = primitive.extensions[ this.name ].attributes;\n\t\tconst threeAttributeMap = {};\n\t\tconst attributeNormalizedMap = {};\n\t\tconst attributeTypeMap = {};\n\n\t\tfor ( const attributeName in gltfAttributeMap ) {\n\n\t\t\tconst threeAttributeName = ATTRIBUTES[ attributeName ] || attributeName.toLowerCase();\n\n\t\t\tthreeAttributeMap[ threeAttributeName ] = gltfAttributeMap[ attributeName ];\n\n\t\t}\n\n\t\tfor ( const attributeName in primitive.attributes ) {\n\n\t\t\tconst threeAttributeName = ATTRIBUTES[ attributeName ] || attributeName.toLowerCase();\n\n\t\t\tif ( gltfAttributeMap[ attributeName ] !== undefined ) {\n\n\t\t\t\tconst accessorDef = json.accessors[ primitive.attributes[ attributeName ] ];\n\t\t\t\tconst componentType = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ];\n\n\t\t\t\tattributeTypeMap[ threeAttributeName ] = componentType.name;\n\t\t\t\tattributeNormalizedMap[ threeAttributeName ] = accessorDef.normalized === true;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn parser.getDependency( 'bufferView', bufferViewIndex ).then( function ( bufferView ) {\n\n\t\t\treturn new Promise( function ( resolve, reject ) {\n\n\t\t\t\tdracoLoader.decodeDracoFile( bufferView, function ( geometry ) {\n\n\t\t\t\t\tfor ( const attributeName in geometry.attributes ) {\n\n\t\t\t\t\t\tconst attribute = geometry.attributes[ attributeName ];\n\t\t\t\t\t\tconst normalized = attributeNormalizedMap[ attributeName ];\n\n\t\t\t\t\t\tif ( normalized !== undefined ) attribute.normalized = normalized;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve( geometry );\n\n\t\t\t\t}, threeAttributeMap, attributeTypeMap, LinearSRGBColorSpace, reject );\n\n\t\t\t} );\n\n\t\t} );\n\n\t}\n\n}\n\n/**\n * Texture Transform Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_texture_transform\n *\n * @private\n */\nclass GLTFTextureTransformExtension {\n\n\tconstructor() {\n\n\t\tthis.name = EXTENSIONS.KHR_TEXTURE_TRANSFORM;\n\n\t}\n\n\textendTexture( texture, transform ) {\n\n\t\tif ( ( transform.texCoord === undefined || transform.texCoord === texture.channel )\n\t\t\t&& transform.offset === undefined\n\t\t\t&& transform.rotation === undefined\n\t\t\t&& transform.scale === undefined ) {\n\n\t\t\t// See https://github.com/mrdoob/three.js/issues/21819.\n\t\t\treturn texture;\n\n\t\t}\n\n\t\ttexture = texture.clone();\n\n\t\tif ( transform.texCoord !== undefined ) {\n\n\t\t\ttexture.channel = transform.texCoord;\n\n\t\t}\n\n\t\tif ( transform.offset !== undefined ) {\n\n\t\t\ttexture.offset.fromArray( transform.offset );\n\n\t\t}\n\n\t\tif ( transform.rotation !== undefined ) {\n\n\t\t\ttexture.rotation = transform.rotation;\n\n\t\t}\n\n\t\tif ( transform.scale !== undefined ) {\n\n\t\t\ttexture.repeat.fromArray( transform.scale );\n\n\t\t}\n\n\t\ttexture.needsUpdate = true;\n\n\t\treturn texture;\n\n\t}\n\n}\n\n/**\n * Mesh Quantization Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization\n *\n * @private\n */\nclass GLTFMeshQuantizationExtension {\n\n\tconstructor() {\n\n\t\tthis.name = EXTENSIONS.KHR_MESH_QUANTIZATION;\n\n\t}\n\n}\n\n/*********************************/\n/********** INTERPOLATION ********/\n/*********************************/\n\n// Spline Interpolation\n// Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#appendix-c-spline-interpolation\nclass GLTFCubicSplineInterpolant extends Interpolant {\n\n\tconstructor( parameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tsuper( parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tcopySampleValue_( index ) {\n\n\t\t// Copies a sample value to the result buffer. See description of glTF\n\t\t// CUBICSPLINE values layout in interpolate_() function below.\n\n\t\tconst result = this.resultBuffer,\n\t\t\tvalues = this.sampleValues,\n\t\t\tvalueSize = this.valueSize,\n\t\t\toffset = index * valueSize * 3 + valueSize;\n\n\t\tfor ( let i = 0; i !== valueSize; i ++ ) {\n\n\t\t\tresult[ i ] = values[ offset + i ];\n\n\t\t}\n\n\t\treturn result;\n\n\t}\n\n\tinterpolate_( i1, t0, t, t1 ) {\n\n\t\tconst result = this.resultBuffer;\n\t\tconst values = this.sampleValues;\n\t\tconst stride = this.valueSize;\n\n\t\tconst stride2 = stride * 2;\n\t\tconst stride3 = stride * 3;\n\n\t\tconst td = t1 - t0;\n\n\t\tconst p = ( t - t0 ) / td;\n\t\tconst pp = p * p;\n\t\tconst ppp = pp * p;\n\n\t\tconst offset1 = i1 * stride3;\n\t\tconst offset0 = offset1 - stride3;\n\n\t\tconst s2 = - 2 * ppp + 3 * pp;\n\t\tconst s3 = ppp - pp;\n\t\tconst s0 = 1 - s2;\n\t\tconst s1 = s3 - pp + p;\n\n\t\t// Layout of keyframe output values for CUBICSPLINE animations:\n\t\t// [ inTangent_1, splineVertex_1, outTangent_1, inTangent_2, splineVertex_2, ... ]\n\t\tfor ( let i = 0; i !== stride; i ++ ) {\n\n\t\t\tconst p0 = values[ offset0 + i + stride ]; // splineVertex_k\n\t\t\tconst m0 = values[ offset0 + i + stride2 ] * td; // outTangent_k * (t_k+1 - t_k)\n\t\t\tconst p1 = values[ offset1 + i + stride ]; // splineVertex_k+1\n\t\t\tconst m1 = values[ offset1 + i ] * td; // inTangent_k+1 * (t_k+1 - t_k)\n\n\t\t\tresult[ i ] = s0 * p0 + s1 * m0 + s2 * p1 + s3 * m1;\n\n\t\t}\n\n\t\treturn result;\n\n\t}\n\n}\n\nconst _quaternion = new Quaternion();\n\nclass GLTFCubicSplineQuaternionInterpolant extends GLTFCubicSplineInterpolant {\n\n\tinterpolate_( i1, t0, t, t1 ) {\n\n\t\tconst result = super.interpolate_( i1, t0, t, t1 );\n\n\t\t_quaternion.fromArray( result ).normalize().toArray( result );\n\n\t\treturn result;\n\n\t}\n\n}\n\n\n/*********************************/\n/********** INTERNALS ************/\n/*********************************/\n\n/* CONSTANTS */\n\nconst WEBGL_CONSTANTS = {\n\tFLOAT: 5126,\n\t//FLOAT_MAT2: 35674,\n\tFLOAT_MAT3: 35675,\n\tFLOAT_MAT4: 35676,\n\tFLOAT_VEC2: 35664,\n\tFLOAT_VEC3: 35665,\n\tFLOAT_VEC4: 35666,\n\tLINEAR: 9729,\n\tREPEAT: 10497,\n\tSAMPLER_2D: 35678,\n\tPOINTS: 0,\n\tLINES: 1,\n\tLINE_LOOP: 2,\n\tLINE_STRIP: 3,\n\tTRIANGLES: 4,\n\tTRIANGLE_STRIP: 5,\n\tTRIANGLE_FAN: 6,\n\tUNSIGNED_BYTE: 5121,\n\tUNSIGNED_SHORT: 5123\n};\n\nconst WEBGL_COMPONENT_TYPES = {\n\t5120: Int8Array,\n\t5121: Uint8Array,\n\t5122: Int16Array,\n\t5123: Uint16Array,\n\t5125: Uint32Array,\n\t5126: Float32Array\n};\n\nconst WEBGL_FILTERS = {\n\t9728: NearestFilter,\n\t9729: LinearFilter,\n\t9984: NearestMipmapNearestFilter,\n\t9985: LinearMipmapNearestFilter,\n\t9986: NearestMipmapLinearFilter,\n\t9987: LinearMipmapLinearFilter\n};\n\nconst WEBGL_WRAPPINGS = {\n\t33071: ClampToEdgeWrapping,\n\t33648: MirroredRepeatWrapping,\n\t10497: RepeatWrapping\n};\n\nconst WEBGL_TYPE_SIZES = {\n\t'SCALAR': 1,\n\t'VEC2': 2,\n\t'VEC3': 3,\n\t'VEC4': 4,\n\t'MAT2': 4,\n\t'MAT3': 9,\n\t'MAT4': 16\n};\n\nconst ATTRIBUTES = {\n\tPOSITION: 'position',\n\tNORMAL: 'normal',\n\tTANGENT: 'tangent',\n\tTEXCOORD_0: 'uv',\n\tTEXCOORD_1: 'uv1',\n\tTEXCOORD_2: 'uv2',\n\tTEXCOORD_3: 'uv3',\n\tCOLOR_0: 'color',\n\tWEIGHTS_0: 'skinWeight',\n\tJOINTS_0: 'skinIndex',\n};\n\nconst PATH_PROPERTIES = {\n\tscale: 'scale',\n\ttranslation: 'position',\n\trotation: 'quaternion',\n\tweights: 'morphTargetInfluences'\n};\n\nconst INTERPOLATION = {\n\tCUBICSPLINE: undefined, // We use a custom interpolant (GLTFCubicSplineInterpolation) for CUBICSPLINE tracks. Each\n\t\t // keyframe track will be initialized with a default interpolation type, then modified.\n\tLINEAR: InterpolateLinear,\n\tSTEP: InterpolateDiscrete\n};\n\nconst ALPHA_MODES = {\n\tOPAQUE: 'OPAQUE',\n\tMASK: 'MASK',\n\tBLEND: 'BLEND'\n};\n\n/**\n * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#default-material\n *\n * @private\n * @param {Object<string, Material>} cache\n * @return {Material}\n */\nfunction createDefaultMaterial( cache ) {\n\n\tif ( cache[ 'DefaultMaterial' ] === undefined ) {\n\n\t\tcache[ 'DefaultMaterial' ] = new MeshStandardMaterial( {\n\t\t\tcolor: 0xFFFFFF,\n\t\t\temissive: 0x000000,\n\t\t\tmetalness: 1,\n\t\t\troughness: 1,\n\t\t\ttransparent: false,\n\t\t\tdepthTest: true,\n\t\t\tside: FrontSide\n\t\t} );\n\n\t}\n\n\treturn cache[ 'DefaultMaterial' ];\n\n}\n\nfunction addUnknownExtensionsToUserData( knownExtensions, object, objectDef ) {\n\n\t// Add unknown glTF extensions to an object's userData.\n\n\tfor ( const name in objectDef.extensions ) {\n\n\t\tif ( knownExtensions[ name ] === undefined ) {\n\n\t\t\tobject.userData.gltfExtensions = object.userData.gltfExtensions || {};\n\t\t\tobject.userData.gltfExtensions[ name ] = objectDef.extensions[ name ];\n\n\t\t}\n\n\t}\n\n}\n\n/**\n *\n * @private\n * @param {Object3D|Material|BufferGeometry|Object|AnimationClip} object\n * @param {GLTF.definition} gltfDef\n */\nfunction assignExtrasToUserData( object, gltfDef ) {\n\n\tif ( gltfDef.extras !== undefined ) {\n\n\t\tif ( typeof gltfDef.extras === 'object' ) {\n\n\t\t\tObject.assign( object.userData, gltfDef.extras );\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.GLTFLoader: Ignoring primitive type .extras, ' + gltfDef.extras );\n\n\t\t}\n\n\t}\n\n}\n\n/**\n * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#morph-targets\n *\n * @private\n * @param {BufferGeometry} geometry\n * @param {Array<GLTF.Target>} targets\n * @param {GLTFParser} parser\n * @return {Promise<BufferGeometry>}\n */\nfunction addMorphTargets( geometry, targets, parser ) {\n\n\tlet hasMorphPosition = false;\n\tlet hasMorphNormal = false;\n\tlet hasMorphColor = false;\n\n\tfor ( let i = 0, il = targets.length; i < il; i ++ ) {\n\n\t\tconst target = targets[ i ];\n\n\t\tif ( target.POSITION !== undefined ) hasMorphPosition = true;\n\t\tif ( target.NORMAL !== undefined ) hasMorphNormal = true;\n\t\tif ( target.COLOR_0 !== undefined ) hasMorphColor = true;\n\n\t\tif ( hasMorphPosition && hasMorphNormal && hasMorphColor ) break;\n\n\t}\n\n\tif ( ! hasMorphPosition && ! hasMorphNormal && ! hasMorphColor ) return Promise.resolve( geometry );\n\n\tconst pendingPositionAccessors = [];\n\tconst pendingNormalAccessors = [];\n\tconst pendingColorAccessors = [];\n\n\tfor ( let i = 0, il = targets.length; i < il; i ++ ) {\n\n\t\tconst target = targets[ i ];\n\n\t\tif ( hasMorphPosition ) {\n\n\t\t\tconst pendingAccessor = target.POSITION !== undefined\n\t\t\t\t? parser.getDependency( 'accessor', target.POSITION )\n\t\t\t\t: geometry.attributes.position;\n\n\t\t\tpendingPositionAccessors.push( pendingAccessor );\n\n\t\t}\n\n\t\tif ( hasMorphNormal ) {\n\n\t\t\tconst pendingAccessor = target.NORMAL !== undefined\n\t\t\t\t? parser.getDependency( 'accessor', target.NORMAL )\n\t\t\t\t: geometry.attributes.normal;\n\n\t\t\tpendingNormalAccessors.push( pendingAccessor );\n\n\t\t}\n\n\t\tif ( hasMorphColor ) {\n\n\t\t\tconst pendingAccessor = target.COLOR_0 !== undefined\n\t\t\t\t? parser.getDependency( 'accessor', target.COLOR_0 )\n\t\t\t\t: geometry.attributes.color;\n\n\t\t\tpendingColorAccessors.push( pendingAccessor );\n\n\t\t}\n\n\t}\n\n\treturn Promise.all( [\n\t\tPromise.all( pendingPositionAccessors ),\n\t\tPromise.all( pendingNormalAccessors ),\n\t\tPromise.all( pendingColorAccessors )\n\t] ).then( function ( accessors ) {\n\n\t\tconst morphPositions = accessors[ 0 ];\n\t\tconst morphNormals = accessors[ 1 ];\n\t\tconst morphColors = accessors[ 2 ];\n\n\t\tif ( hasMorphPosition ) geometry.morphAttributes.position = morphPositions;\n\t\tif ( hasMorphNormal ) geometry.morphAttributes.normal = morphNormals;\n\t\tif ( hasMorphColor ) geometry.morphAttributes.color = morphColors;\n\t\tgeometry.morphTargetsRelative = true;\n\n\t\treturn geometry;\n\n\t} );\n\n}\n\n/**\n *\n * @private\n * @param {Mesh} mesh\n * @param {GLTF.Mesh} meshDef\n */\nfunction updateMorphTargets( mesh, meshDef ) {\n\n\tmesh.updateMorphTargets();\n\n\tif ( meshDef.weights !== undefined ) {\n\n\t\tfor ( let i = 0, il = meshDef.weights.length; i < il; i ++ ) {\n\n\t\t\tmesh.morphTargetInfluences[ i ] = meshDef.weights[ i ];\n\n\t\t}\n\n\t}\n\n\t// .extras has user-defined data, so check that .extras.targetNames is an array.\n\tif ( meshDef.extras && Array.isArray( meshDef.extras.targetNames ) ) {\n\n\t\tconst targetNames = meshDef.extras.targetNames;\n\n\t\tif ( mesh.morphTargetInfluences.length === targetNames.length ) {\n\n\t\t\tmesh.morphTargetDictionary = {};\n\n\t\t\tfor ( let i = 0, il = targetNames.length; i < il; i ++ ) {\n\n\t\t\t\tmesh.morphTargetDictionary[ targetNames[ i ] ] = i;\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.GLTFLoader: Invalid extras.targetNames length. Ignoring names.' );\n\n\t\t}\n\n\t}\n\n}\n\nfunction createPrimitiveKey( primitiveDef ) {\n\n\tlet geometryKey;\n\n\tconst dracoExtension = primitiveDef.extensions && primitiveDef.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ];\n\n\tif ( dracoExtension ) {\n\n\t\tgeometryKey = 'draco:' + dracoExtension.bufferView\n\t\t\t\t+ ':' + dracoExtension.indices\n\t\t\t\t+ ':' + createAttributesKey( dracoExtension.attributes );\n\n\t} else {\n\n\t\tgeometryKey = primitiveDef.indices + ':' + createAttributesKey( primitiveDef.attributes ) + ':' + primitiveDef.mode;\n\n\t}\n\n\tif ( primitiveDef.targets !== undefined ) {\n\n\t\tfor ( let i = 0, il = primitiveDef.targets.length; i < il; i ++ ) {\n\n\t\t\tgeometryKey += ':' + createAttributesKey( primitiveDef.targets[ i ] );\n\n\t\t}\n\n\t}\n\n\treturn geometryKey;\n\n}\n\nfunction createAttributesKey( attributes ) {\n\n\tlet attributesKey = '';\n\n\tconst keys = Object.keys( attributes ).sort();\n\n\tfor ( let i = 0, il = keys.length; i < il; i ++ ) {\n\n\t\tattributesKey += keys[ i ] + ':' + attributes[ keys[ i ] ] + ';';\n\n\t}\n\n\treturn attributesKey;\n\n}\n\nfunction getNormalizedComponentScale( constructor ) {\n\n\t// Reference:\n\t// https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization#encoding-quantized-data\n\n\tswitch ( constructor ) {\n\n\t\tcase Int8Array:\n\t\t\treturn 1 / 127;\n\n\t\tcase Uint8Array:\n\t\t\treturn 1 / 255;\n\n\t\tcase Int16Array:\n\t\t\treturn 1 / 32767;\n\n\t\tcase Uint16Array:\n\t\t\treturn 1 / 65535;\n\n\t\tdefault:\n\t\t\tthrow new Error( 'THREE.GLTFLoader: Unsupported normalized accessor component type.' );\n\n\t}\n\n}\n\nfunction getImageURIMimeType( uri ) {\n\n\tif ( uri.search( /\\.jpe?g($|\\?)/i ) > 0 || uri.search( /^data\\:image\\/jpeg/ ) === 0 ) return 'image/jpeg';\n\tif ( uri.search( /\\.webp($|\\?)/i ) > 0 || uri.search( /^data\\:image\\/webp/ ) === 0 ) return 'image/webp';\n\tif ( uri.search( /\\.ktx2($|\\?)/i ) > 0 || uri.search( /^data\\:image\\/ktx2/ ) === 0 ) return 'image/ktx2';\n\n\treturn 'image/png';\n\n}\n\nconst _identityMatrix = new Matrix4();\n\n/* GLTF PARSER */\n\nclass GLTFParser {\n\n\tconstructor( json = {}, options = {} ) {\n\n\t\tthis.json = json;\n\t\tthis.extensions = {};\n\t\tthis.plugins = {};\n\t\tthis.options = options;\n\n\t\t// loader object cache\n\t\tthis.cache = new GLTFRegistry();\n\n\t\t// associations between Three.js objects and glTF elements\n\t\tthis.associations = new Map();\n\n\t\t// BufferGeometry caching\n\t\tthis.primitiveCache = {};\n\n\t\t// Node cache\n\t\tthis.nodeCache = {};\n\n\t\t// Object3D instance caches\n\t\tthis.meshCache = { refs: {}, uses: {} };\n\t\tthis.cameraCache = { refs: {}, uses: {} };\n\t\tthis.lightCache = { refs: {}, uses: {} };\n\n\t\tthis.sourceCache = {};\n\t\tthis.textureCache = {};\n\n\t\t// Track node names, to ensure no duplicates\n\t\tthis.nodeNamesUsed = {};\n\n\t\t// Use an ImageBitmapLoader if imageBitmaps are supported. Moves much of the\n\t\t// expensive work of uploading a texture to the GPU off the main thread.\n\n\t\tlet isSafari = false;\n\t\tlet safariVersion = - 1;\n\t\tlet isFirefox = false;\n\t\tlet firefoxVersion = - 1;\n\n\t\tif ( typeof navigator !== 'undefined' && typeof navigator.userAgent !== 'undefined' ) {\n\n\t\t\tconst userAgent = navigator.userAgent;\n\n\t\t\tisSafari = /^((?!chrome|android).)*safari/i.test( userAgent ) === true;\n\t\t\tconst safariMatch = userAgent.match( /Version\\/(\\d+)/ );\n\t\t\tsafariVersion = isSafari && safariMatch ? parseInt( safariMatch[ 1 ], 10 ) : - 1;\n\n\t\t\tisFirefox = userAgent.indexOf( 'Firefox' ) > - 1;\n\t\t\tfirefoxVersion = isFirefox ? userAgent.match( /Firefox\\/([0-9]+)\\./ )[ 1 ] : - 1;\n\n\t\t}\n\n\t\tif ( typeof createImageBitmap === 'undefined' || ( isSafari && safariVersion < 17 ) || ( isFirefox && firefoxVersion < 98 ) ) {\n\n\t\t\tthis.textureLoader = new TextureLoader( this.options.manager );\n\n\t\t} else {\n\n\t\t\tthis.textureLoader = new ImageBitmapLoader( this.options.manager );\n\n\t\t}\n\n\t\tthis.textureLoader.setCrossOrigin( this.options.crossOrigin );\n\t\tthis.textureLoader.setRequestHeader( this.options.requestHeader );\n\n\t\tthis.fileLoader = new FileLoader( this.options.manager );\n\t\tthis.fileLoader.setResponseType( 'arraybuffer' );\n\n\t\tif ( this.options.crossOrigin === 'use-credentials' ) {\n\n\t\t\tthis.fileLoader.setWithCredentials( true );\n\n\t\t}\n\n\t}\n\n\tsetExtensions( extensions ) {\n\n\t\tthis.extensions = extensions;\n\n\t}\n\n\tsetPlugins( plugins ) {\n\n\t\tthis.plugins = plugins;\n\n\t}\n\n\tparse( onLoad, onError ) {\n\n\t\tconst parser = this;\n\t\tconst json = this.json;\n\t\tconst extensions = this.extensions;\n\n\t\t// Clear the loader cache\n\t\tthis.cache.removeAll();\n\t\tthis.nodeCache = {};\n\n\t\t// Mark the special nodes/meshes in json for efficient parse\n\t\tthis._invokeAll( function ( ext ) {\n\n\t\t\treturn ext._markDefs && ext._markDefs();\n\n\t\t} );\n\n\t\tPromise.all( this._invokeAll( function ( ext ) {\n\n\t\t\treturn ext.beforeRoot && ext.beforeRoot();\n\n\t\t} ) ).then( function () {\n\n\t\t\treturn Promise.all( [\n\n\t\t\t\tparser.getDependencies( 'scene' ),\n\t\t\t\tparser.getDependencies( 'animation' ),\n\t\t\t\tparser.getDependencies( 'camera' ),\n\n\t\t\t] );\n\n\t\t} ).then( function ( dependencies ) {\n\n\t\t\tconst result = {\n\t\t\t\tscene: dependencies[ 0 ][ json.scene || 0 ],\n\t\t\t\tscenes: dependencies[ 0 ],\n\t\t\t\tanimations: dependencies[ 1 ],\n\t\t\t\tcameras: dependencies[ 2 ],\n\t\t\t\tasset: json.asset,\n\t\t\t\tparser: parser,\n\t\t\t\tuserData: {}\n\t\t\t};\n\n\t\t\taddUnknownExtensionsToUserData( extensions, result, json );\n\n\t\t\tassignExtrasToUserData( result, json );\n\n\t\t\treturn Promise.all( parser._invokeAll( function ( ext ) {\n\n\t\t\t\treturn ext.afterRoot && ext.afterRoot( result );\n\n\t\t\t} ) ).then( function () {\n\n\t\t\t\tfor ( const scene of result.scenes ) {\n\n\t\t\t\t\tscene.updateMatrixWorld();\n\n\t\t\t\t}\n\n\t\t\t\tonLoad( result );\n\n\t\t\t} );\n\n\t\t} ).catch( onError );\n\n\t}\n\n\t/**\n\t * Marks the special nodes/meshes in json for efficient parse.\n\t *\n\t * @private\n\t */\n\t_markDefs() {\n\n\t\tconst nodeDefs = this.json.nodes || [];\n\t\tconst skinDefs = this.json.skins || [];\n\t\tconst meshDefs = this.json.meshes || [];\n\n\t\t// Nothing in the node definition indicates whether it is a Bone or an\n\t\t// Object3D. Use the skins' joint references to mark bones.\n\t\tfor ( let skinIndex = 0, skinLength = skinDefs.length; skinIndex < skinLength; skinIndex ++ ) {\n\n\t\t\tconst joints = skinDefs[ skinIndex ].joints;\n\n\t\t\tfor ( let i = 0, il = joints.length; i < il; i ++ ) {\n\n\t\t\t\tnodeDefs[ joints[ i ] ].isBone = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Iterate over all nodes, marking references to shared resources,\n\t\t// as well as skeleton joints.\n\t\tfor ( let nodeIndex = 0, nodeLength = nodeDefs.length; nodeIndex < nodeLength; nodeIndex ++ ) {\n\n\t\t\tconst nodeDef = nodeDefs[ nodeIndex ];\n\n\t\t\tif ( nodeDef.mesh !== undefined ) {\n\n\t\t\t\tthis._addNodeRef( this.meshCache, nodeDef.mesh );\n\n\t\t\t\t// Nothing in the mesh definition indicates whether it is\n\t\t\t\t// a SkinnedMesh or Mesh. Use the node's mesh reference\n\t\t\t\t// to mark SkinnedMesh if node has skin.\n\t\t\t\tif ( nodeDef.skin !== undefined ) {\n\n\t\t\t\t\tmeshDefs[ nodeDef.mesh ].isSkinnedMesh = true;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( nodeDef.camera !== undefined ) {\n\n\t\t\t\tthis._addNodeRef( this.cameraCache, nodeDef.camera );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Counts references to shared node / Object3D resources. These resources\n\t * can be reused, or \"instantiated\", at multiple nodes in the scene\n\t * hierarchy. Mesh, Camera, and Light instances are instantiated and must\n\t * be marked. Non-scenegraph resources (like Materials, Geometries, and\n\t * Textures) can be reused directly and are not marked here.\n\t *\n\t * Example: CesiumMilkTruck sample model reuses \"Wheel\" meshes.\n\t *\n\t * @private\n\t * @param {Object} cache\n\t * @param {Object3D} index\n\t */\n\t_addNodeRef( cache, index ) {\n\n\t\tif ( index === undefined ) return;\n\n\t\tif ( cache.refs[ index ] === undefined ) {\n\n\t\t\tcache.refs[ index ] = cache.uses[ index ] = 0;\n\n\t\t}\n\n\t\tcache.refs[ index ] ++;\n\n\t}\n\n\t/**\n\t * Returns a reference to a shared resource, cloning it if necessary.\n\t *\n\t * @private\n\t * @param {Object} cache\n\t * @param {number} index\n\t * @param {Object} object\n\t * @return {Object}\n\t */\n\t_getNodeRef( cache, index, object ) {\n\n\t\tif ( cache.refs[ index ] <= 1 ) return object;\n\n\t\tconst ref = object.clone();\n\n\t\t// Propagates mappings to the cloned object, prevents mappings on the\n\t\t// original object from being lost.\n\t\tconst updateMappings = ( original, clone ) => {\n\n\t\t\tconst mappings = this.associations.get( original );\n\t\t\tif ( mappings != null ) {\n\n\t\t\t\tthis.associations.set( clone, mappings );\n\n\t\t\t}\n\n\t\t\tfor ( const [ i, child ] of original.children.entries() ) {\n\n\t\t\t\tupdateMappings( child, clone.children[ i ] );\n\n\t\t\t}\n\n\t\t};\n\n\t\tupdateMappings( object, ref );\n\n\t\tref.name += '_instance_' + ( cache.uses[ index ] ++ );\n\n\t\treturn ref;\n\n\t}\n\n\t_invokeOne( func ) {\n\n\t\tconst extensions = Object.values( this.plugins );\n\t\textensions.push( this );\n\n\t\tfor ( let i = 0; i < extensions.length; i ++ ) {\n\n\t\t\tconst result = func( extensions[ i ] );\n\n\t\t\tif ( result ) return result;\n\n\t\t}\n\n\t\treturn null;\n\n\t}\n\n\t_invokeAll( func ) {\n\n\t\tconst extensions = Object.values( this.plugins );\n\t\textensions.unshift( this );\n\n\t\tconst pending = [];\n\n\t\tfor ( let i = 0; i < extensions.length; i ++ ) {\n\n\t\t\tconst result = func( extensions[ i ] );\n\n\t\t\tif ( result ) pending.push( result );\n\n\t\t}\n\n\t\treturn pending;\n\n\t}\n\n\t/**\n\t * Requests the specified dependency asynchronously, with caching.\n\t *\n\t * @private\n\t * @param {string} type\n\t * @param {number} index\n\t * @return {Promise<Object3D|Material|Texture|AnimationClip|ArrayBuffer|Object>}\n\t */\n\tgetDependency( type, index ) {\n\n\t\tconst cacheKey = type + ':' + index;\n\t\tlet dependency = this.cache.get( cacheKey );\n\n\t\tif ( ! dependency ) {\n\n\t\t\tswitch ( type ) {\n\n\t\t\t\tcase 'scene':\n\t\t\t\t\tdependency = this.loadScene( index );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'node':\n\t\t\t\t\tdependency = this._invokeOne( function ( ext ) {\n\n\t\t\t\t\t\treturn ext.loadNode && ext.loadNode( index );\n\n\t\t\t\t\t} );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'mesh':\n\t\t\t\t\tdependency = this._invokeOne( function ( ext ) {\n\n\t\t\t\t\t\treturn ext.loadMesh && ext.loadMesh( index );\n\n\t\t\t\t\t} );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'accessor':\n\t\t\t\t\tdependency = this.loadAccessor( index );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'bufferView':\n\t\t\t\t\tdependency = this._invokeOne( function ( ext ) {\n\n\t\t\t\t\t\treturn ext.loadBufferView && ext.loadBufferView( index );\n\n\t\t\t\t\t} );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'buffer':\n\t\t\t\t\tdependency = this.loadBuffer( index );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'material':\n\t\t\t\t\tdependency = this._invokeOne( function ( ext ) {\n\n\t\t\t\t\t\treturn ext.loadMaterial && ext.loadMaterial( index );\n\n\t\t\t\t\t} );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'texture':\n\t\t\t\t\tdependency = this._invokeOne( function ( ext ) {\n\n\t\t\t\t\t\treturn ext.loadTexture && ext.loadTexture( index );\n\n\t\t\t\t\t} );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'skin':\n\t\t\t\t\tdependency = this.loadSkin( index );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'animation':\n\t\t\t\t\tdependency = this._invokeOne( function ( ext ) {\n\n\t\t\t\t\t\treturn ext.loadAnimation && ext.loadAnimation( index );\n\n\t\t\t\t\t} );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'camera':\n\t\t\t\t\tdependency = this.loadCamera( index );\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\tdependency = this._invokeOne( function ( ext ) {\n\n\t\t\t\t\t\treturn ext != this && ext.getDependency && ext.getDependency( type, index );\n\n\t\t\t\t\t} );\n\n\t\t\t\t\tif ( ! dependency ) {\n\n\t\t\t\t\t\tthrow new Error( 'Unknown type: ' + type );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tthis.cache.add( cacheKey, dependency );\n\n\t\t}\n\n\t\treturn dependency;\n\n\t}\n\n\t/**\n\t * Requests all dependencies of the specified type asynchronously, with caching.\n\t *\n\t * @private\n\t * @param {string} type\n\t * @return {Promise<Array<Object>>}\n\t */\n\tgetDependencies( type ) {\n\n\t\tlet dependencies = this.cache.get( type );\n\n\t\tif ( ! dependencies ) {\n\n\t\t\tconst parser = this;\n\t\t\tconst defs = this.json[ type + ( type === 'mesh' ? 'es' : 's' ) ] || [];\n\n\t\t\tdependencies = Promise.all( defs.map( function ( def, index ) {\n\n\t\t\t\treturn parser.getDependency( type, index );\n\n\t\t\t} ) );\n\n\t\t\tthis.cache.add( type, dependencies );\n\n\t\t}\n\n\t\treturn dependencies;\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views\n\t *\n\t * @private\n\t * @param {number} bufferIndex\n\t * @return {Promise<ArrayBuffer>}\n\t */\n\tloadBuffer( bufferIndex ) {\n\n\t\tconst bufferDef = this.json.buffers[ bufferIndex ];\n\t\tconst loader = this.fileLoader;\n\n\t\tif ( bufferDef.type && bufferDef.type !== 'arraybuffer' ) {\n\n\t\t\tthrow new Error( 'THREE.GLTFLoader: ' + bufferDef.type + ' buffer type is not supported.' );\n\n\t\t}\n\n\t\t// If present, GLB container is required to be the first buffer.\n\t\tif ( bufferDef.uri === undefined && bufferIndex === 0 ) {\n\n\t\t\treturn Promise.resolve( this.extensions[ EXTENSIONS.KHR_BINARY_GLTF ].body );\n\n\t\t}\n\n\t\tconst options = this.options;\n\n\t\treturn new Promise( function ( resolve, reject ) {\n\n\t\t\tloader.load( LoaderUtils.resolveURL( bufferDef.uri, options.path ), resolve, undefined, function () {\n\n\t\t\t\treject( new Error( 'THREE.GLTFLoader: Failed to load buffer \"' + bufferDef.uri + '\".' ) );\n\n\t\t\t} );\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views\n\t *\n\t * @private\n\t * @param {number} bufferViewIndex\n\t * @return {Promise<ArrayBuffer>}\n\t */\n\tloadBufferView( bufferViewIndex ) {\n\n\t\tconst bufferViewDef = this.json.bufferViews[ bufferViewIndex ];\n\n\t\treturn this.getDependency( 'buffer', bufferViewDef.buffer ).then( function ( buffer ) {\n\n\t\t\tconst byteLength = bufferViewDef.byteLength || 0;\n\t\t\tconst byteOffset = bufferViewDef.byteOffset || 0;\n\t\t\treturn buffer.slice( byteOffset, byteOffset + byteLength );\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#accessors\n\t *\n\t * @private\n\t * @param {number} accessorIndex\n\t * @return {Promise<BufferAttribute|InterleavedBufferAttribute>}\n\t */\n\tloadAccessor( accessorIndex ) {\n\n\t\tconst parser = this;\n\t\tconst json = this.json;\n\n\t\tconst accessorDef = this.json.accessors[ accessorIndex ];\n\n\t\tif ( accessorDef.bufferView === undefined && accessorDef.sparse === undefined ) {\n\n\t\t\tconst itemSize = WEBGL_TYPE_SIZES[ accessorDef.type ];\n\t\t\tconst TypedArray = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ];\n\t\t\tconst normalized = accessorDef.normalized === true;\n\n\t\t\tconst array = new TypedArray( accessorDef.count * itemSize );\n\t\t\treturn Promise.resolve( new BufferAttribute( array, itemSize, normalized ) );\n\n\t\t}\n\n\t\tconst pendingBufferViews = [];\n\n\t\tif ( accessorDef.bufferView !== undefined ) {\n\n\t\t\tpendingBufferViews.push( this.getDependency( 'bufferView', accessorDef.bufferView ) );\n\n\t\t} else {\n\n\t\t\tpendingBufferViews.push( null );\n\n\t\t}\n\n\t\tif ( accessorDef.sparse !== undefined ) {\n\n\t\t\tpendingBufferViews.push( this.getDependency( 'bufferView', accessorDef.sparse.indices.bufferView ) );\n\t\t\tpendingBufferViews.push( this.getDependency( 'bufferView', accessorDef.sparse.values.bufferView ) );\n\n\t\t}\n\n\t\treturn Promise.all( pendingBufferViews ).then( function ( bufferViews ) {\n\n\t\t\tconst bufferView = bufferViews[ 0 ];\n\n\t\t\tconst itemSize = WEBGL_TYPE_SIZES[ accessorDef.type ];\n\t\t\tconst TypedArray = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ];\n\n\t\t\t// For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12.\n\t\t\tconst elementBytes = TypedArray.BYTES_PER_ELEMENT;\n\t\t\tconst itemBytes = elementBytes * itemSize;\n\t\t\tconst byteOffset = accessorDef.byteOffset || 0;\n\t\t\tconst byteStride = accessorDef.bufferView !== undefined ? json.bufferViews[ accessorDef.bufferView ].byteStride : undefined;\n\t\t\tconst normalized = accessorDef.normalized === true;\n\t\t\tlet array, bufferAttribute;\n\n\t\t\t// The buffer is not interleaved if the stride is the item size in bytes.\n\t\t\tif ( byteStride && byteStride !== itemBytes ) {\n\n\t\t\t\t// Each \"slice\" of the buffer, as defined by 'count' elements of 'byteStride' bytes, gets its own InterleavedBuffer\n\t\t\t\t// This makes sure that IBA.count reflects accessor.count properly\n\t\t\t\tconst ibSlice = Math.floor( byteOffset / byteStride );\n\t\t\t\tconst ibCacheKey = 'InterleavedBuffer:' + accessorDef.bufferView + ':' + accessorDef.componentType + ':' + ibSlice + ':' + accessorDef.count;\n\t\t\t\tlet ib = parser.cache.get( ibCacheKey );\n\n\t\t\t\tif ( ! ib ) {\n\n\t\t\t\t\tarray = new TypedArray( bufferView, ibSlice * byteStride, accessorDef.count * byteStride / elementBytes );\n\n\t\t\t\t\t// Integer parameters to IB/IBA are in array elements, not bytes.\n\t\t\t\t\tib = new InterleavedBuffer( array, byteStride / elementBytes );\n\n\t\t\t\t\tparser.cache.add( ibCacheKey, ib );\n\n\t\t\t\t}\n\n\t\t\t\tbufferAttribute = new InterleavedBufferAttribute( ib, itemSize, ( byteOffset % byteStride ) / elementBytes, normalized );\n\n\t\t\t} else {\n\n\t\t\t\tif ( bufferView === null ) {\n\n\t\t\t\t\tarray = new TypedArray( accessorDef.count * itemSize );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tarray = new TypedArray( bufferView, byteOffset, accessorDef.count * itemSize );\n\n\t\t\t\t}\n\n\t\t\t\tbufferAttribute = new BufferAttribute( array, itemSize, normalized );\n\n\t\t\t}\n\n\t\t\t// https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#sparse-accessors\n\t\t\tif ( accessorDef.sparse !== undefined ) {\n\n\t\t\t\tconst itemSizeIndices = WEBGL_TYPE_SIZES.SCALAR;\n\t\t\t\tconst TypedArrayIndices = WEBGL_COMPONENT_TYPES[ accessorDef.sparse.indices.componentType ];\n\n\t\t\t\tconst byteOffsetIndices = accessorDef.sparse.indices.byteOffset || 0;\n\t\t\t\tconst byteOffsetValues = accessorDef.sparse.values.byteOffset || 0;\n\n\t\t\t\tconst sparseIndices = new TypedArrayIndices( bufferViews[ 1 ], byteOffsetIndices, accessorDef.sparse.count * itemSizeIndices );\n\t\t\t\tconst sparseValues = new TypedArray( bufferViews[ 2 ], byteOffsetValues, accessorDef.sparse.count * itemSize );\n\n\t\t\t\tif ( bufferView !== null ) {\n\n\t\t\t\t\t// Avoid modifying the original ArrayBuffer, if the bufferView wasn't initialized with zeroes.\n\t\t\t\t\tbufferAttribute = new BufferAttribute( bufferAttribute.array.slice(), bufferAttribute.itemSize, bufferAttribute.normalized );\n\n\t\t\t\t}\n\n\t\t\t\t// Ignore normalized since we copy from sparse\n\t\t\t\tbufferAttribute.normalized = false;\n\n\t\t\t\tfor ( let i = 0, il = sparseIndices.length; i < il; i ++ ) {\n\n\t\t\t\t\tconst index = sparseIndices[ i ];\n\n\t\t\t\t\tbufferAttribute.setX( index, sparseValues[ i * itemSize ] );\n\t\t\t\t\tif ( itemSize >= 2 ) bufferAttribute.setY( index, sparseValues[ i * itemSize + 1 ] );\n\t\t\t\t\tif ( itemSize >= 3 ) bufferAttribute.setZ( index, sparseValues[ i * itemSize + 2 ] );\n\t\t\t\t\tif ( itemSize >= 4 ) bufferAttribute.setW( index, sparseValues[ i * itemSize + 3 ] );\n\t\t\t\t\tif ( itemSize >= 5 ) throw new Error( 'THREE.GLTFLoader: Unsupported itemSize in sparse BufferAttribute.' );\n\n\t\t\t\t}\n\n\t\t\t\tbufferAttribute.normalized = normalized;\n\n\t\t\t}\n\n\t\t\treturn bufferAttribute;\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#textures\n\t *\n\t * @private\n\t * @param {number} textureIndex\n\t * @return {Promise<?Texture>}\n\t */\n\tloadTexture( textureIndex ) {\n\n\t\tconst json = this.json;\n\t\tconst options = this.options;\n\t\tconst textureDef = json.textures[ textureIndex ];\n\t\tconst sourceIndex = textureDef.source;\n\t\tconst sourceDef = json.images[ sourceIndex ];\n\n\t\tlet loader = this.textureLoader;\n\n\t\tif ( sourceDef.uri ) {\n\n\t\t\tconst handler = options.manager.getHandler( sourceDef.uri );\n\t\t\tif ( handler !== null ) loader = handler;\n\n\t\t}\n\n\t\treturn this.loadTextureImage( textureIndex, sourceIndex, loader );\n\n\t}\n\n\tloadTextureImage( textureIndex, sourceIndex, loader ) {\n\n\t\tconst parser = this;\n\t\tconst json = this.json;\n\n\t\tconst textureDef = json.textures[ textureIndex ];\n\t\tconst sourceDef = json.images[ sourceIndex ];\n\n\t\tconst cacheKey = ( sourceDef.uri || sourceDef.bufferView ) + ':' + textureDef.sampler;\n\n\t\tif ( this.textureCache[ cacheKey ] ) {\n\n\t\t\t// See https://github.com/mrdoob/three.js/issues/21559.\n\t\t\treturn this.textureCache[ cacheKey ];\n\n\t\t}\n\n\t\tconst promise = this.loadImageSource( sourceIndex, loader ).then( function ( texture ) {\n\n\t\t\ttexture.flipY = false;\n\n\t\t\ttexture.name = textureDef.name || sourceDef.name || '';\n\n\t\t\tif ( texture.name === '' && typeof sourceDef.uri === 'string' && sourceDef.uri.startsWith( 'data:image/' ) === false ) {\n\n\t\t\t\ttexture.name = sourceDef.uri;\n\n\t\t\t}\n\n\t\t\tconst samplers = json.samplers || {};\n\t\t\tconst sampler = samplers[ textureDef.sampler ] || {};\n\n\t\t\ttexture.magFilter = WEBGL_FILTERS[ sampler.magFilter ] || LinearFilter;\n\t\t\ttexture.minFilter = WEBGL_FILTERS[ sampler.minFilter ] || LinearMipmapLinearFilter;\n\t\t\ttexture.wrapS = WEBGL_WRAPPINGS[ sampler.wrapS ] || RepeatWrapping;\n\t\t\ttexture.wrapT = WEBGL_WRAPPINGS[ sampler.wrapT ] || RepeatWrapping;\n\t\t\ttexture.generateMipmaps = ! texture.isCompressedTexture && texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter;\n\n\t\t\tparser.associations.set( texture, { textures: textureIndex } );\n\n\t\t\treturn texture;\n\n\t\t} ).catch( function () {\n\n\t\t\treturn null;\n\n\t\t} );\n\n\t\tthis.textureCache[ cacheKey ] = promise;\n\n\t\treturn promise;\n\n\t}\n\n\tloadImageSource( sourceIndex, loader ) {\n\n\t\tconst parser = this;\n\t\tconst json = this.json;\n\t\tconst options = this.options;\n\n\t\tif ( this.sourceCache[ sourceIndex ] !== undefined ) {\n\n\t\t\treturn this.sourceCache[ sourceIndex ].then( ( texture ) => texture.clone() );\n\n\t\t}\n\n\t\tconst sourceDef = json.images[ sourceIndex ];\n\n\t\tconst URL = self.URL || self.webkitURL;\n\n\t\tlet sourceURI = sourceDef.uri || '';\n\t\tlet isObjectURL = false;\n\n\t\tif ( sourceDef.bufferView !== undefined ) {\n\n\t\t\t// Load binary image data from bufferView, if provided.\n\n\t\t\tsourceURI = parser.getDependency( 'bufferView', sourceDef.bufferView ).then( function ( bufferView ) {\n\n\t\t\t\tisObjectURL = true;\n\t\t\t\tconst blob = new Blob( [ bufferView ], { type: sourceDef.mimeType } );\n\t\t\t\tsourceURI = URL.createObjectURL( blob );\n\t\t\t\treturn sourceURI;\n\n\t\t\t} );\n\n\t\t} else if ( sourceDef.uri === undefined ) {\n\n\t\t\tthrow new Error( 'THREE.GLTFLoader: Image ' + sourceIndex + ' is missing URI and bufferView' );\n\n\t\t}\n\n\t\tconst promise = Promise.resolve( sourceURI ).then( function ( sourceURI ) {\n\n\t\t\treturn new Promise( function ( resolve, reject ) {\n\n\t\t\t\tlet onLoad = resolve;\n\n\t\t\t\tif ( loader.isImageBitmapLoader === true ) {\n\n\t\t\t\t\tonLoad = function ( imageBitmap ) {\n\n\t\t\t\t\t\tconst texture = new Texture( imageBitmap );\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tresolve( texture );\n\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\tloader.load( LoaderUtils.resolveURL( sourceURI, options.path ), onLoad, undefined, reject );\n\n\t\t\t} );\n\n\t\t} ).then( function ( texture ) {\n\n\t\t\t// Clean up resources and configure Texture.\n\n\t\t\tif ( isObjectURL === true ) {\n\n\t\t\t\tURL.revokeObjectURL( sourceURI );\n\n\t\t\t}\n\n\t\t\tassignExtrasToUserData( texture, sourceDef );\n\n\t\t\ttexture.userData.mimeType = sourceDef.mimeType || getImageURIMimeType( sourceDef.uri );\n\n\t\t\treturn texture;\n\n\t\t} ).catch( function ( error ) {\n\n\t\t\tconsole.error( 'THREE.GLTFLoader: Couldn\\'t load texture', sourceURI );\n\t\t\tthrow error;\n\n\t\t} );\n\n\t\tthis.sourceCache[ sourceIndex ] = promise;\n\t\treturn promise;\n\n\t}\n\n\t/**\n\t * Asynchronously assigns a texture to the given material parameters.\n\t *\n\t * @private\n\t * @param {Object} materialParams\n\t * @param {string} mapName\n\t * @param {Object} mapDef\n\t * @param {string} [colorSpace]\n\t * @return {Promise<Texture>}\n\t */\n\tassignTexture( materialParams, mapName, mapDef, colorSpace ) {\n\n\t\tconst parser = this;\n\n\t\treturn this.getDependency( 'texture', mapDef.index ).then( function ( texture ) {\n\n\t\t\tif ( ! texture ) return null;\n\n\t\t\tif ( mapDef.texCoord !== undefined && mapDef.texCoord > 0 ) {\n\n\t\t\t\ttexture = texture.clone();\n\t\t\t\ttexture.channel = mapDef.texCoord;\n\n\t\t\t}\n\n\t\t\tif ( parser.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] ) {\n\n\t\t\t\tconst transform = mapDef.extensions !== undefined ? mapDef.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] : undefined;\n\n\t\t\t\tif ( transform ) {\n\n\t\t\t\t\tconst gltfReference = parser.associations.get( texture );\n\t\t\t\t\ttexture = parser.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ].extendTexture( texture, transform );\n\t\t\t\t\tparser.associations.set( texture, gltfReference );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( colorSpace !== undefined ) {\n\n\t\t\t\ttexture.colorSpace = colorSpace;\n\n\t\t\t}\n\n\t\t\tmaterialParams[ mapName ] = texture;\n\n\t\t\treturn texture;\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Assigns final material to a Mesh, Line, or Points instance. The instance\n\t * already has a material (generated from the glTF material options alone)\n\t * but reuse of the same glTF material may require multiple threejs materials\n\t * to accommodate different primitive types, defines, etc. New materials will\n\t * be created if necessary, and reused from a cache.\n\t *\n\t * @private\n\t * @param {Object3D} mesh Mesh, Line, or Points instance.\n\t */\n\tassignFinalMaterial( mesh ) {\n\n\t\tconst geometry = mesh.geometry;\n\t\tlet material = mesh.material;\n\n\t\tconst useDerivativeTangents = geometry.attributes.tangent === undefined;\n\t\tconst useVertexColors = geometry.attributes.color !== undefined;\n\t\tconst useFlatShading = geometry.attributes.normal === undefined;\n\n\t\tif ( mesh.isPoints ) {\n\n\t\t\tconst cacheKey = 'PointsMaterial:' + material.uuid;\n\n\t\t\tlet pointsMaterial = this.cache.get( cacheKey );\n\n\t\t\tif ( ! pointsMaterial ) {\n\n\t\t\t\tpointsMaterial = new PointsMaterial();\n\t\t\t\tMaterial.prototype.copy.call( pointsMaterial, material );\n\t\t\t\tpointsMaterial.color.copy( material.color );\n\t\t\t\tpointsMaterial.map = material.map;\n\t\t\t\tpointsMaterial.sizeAttenuation = false; // glTF spec says points should be 1px\n\n\t\t\t\tthis.cache.add( cacheKey, pointsMaterial );\n\n\t\t\t}\n\n\t\t\tmaterial = pointsMaterial;\n\n\t\t} else if ( mesh.isLine ) {\n\n\t\t\tconst cacheKey = 'LineBasicMaterial:' + material.uuid;\n\n\t\t\tlet lineMaterial = this.cache.get( cacheKey );\n\n\t\t\tif ( ! lineMaterial ) {\n\n\t\t\t\tlineMaterial = new LineBasicMaterial();\n\t\t\t\tMaterial.prototype.copy.call( lineMaterial, material );\n\t\t\t\tlineMaterial.color.copy( material.color );\n\t\t\t\tlineMaterial.map = material.map;\n\n\t\t\t\tthis.cache.add( cacheKey, lineMaterial );\n\n\t\t\t}\n\n\t\t\tmaterial = lineMaterial;\n\n\t\t}\n\n\t\t// Clone the material if it will be modified\n\t\tif ( useDerivativeTangents || useVertexColors || useFlatShading ) {\n\n\t\t\tlet cacheKey = 'ClonedMaterial:' + material.uuid + ':';\n\n\t\t\tif ( useDerivativeTangents ) cacheKey += 'derivative-tangents:';\n\t\t\tif ( useVertexColors ) cacheKey += 'vertex-colors:';\n\t\t\tif ( useFlatShading ) cacheKey += 'flat-shading:';\n\n\t\t\tlet cachedMaterial = this.cache.get( cacheKey );\n\n\t\t\tif ( ! cachedMaterial ) {\n\n\t\t\t\tcachedMaterial = material.clone();\n\n\t\t\t\tif ( useVertexColors ) cachedMaterial.vertexColors = true;\n\t\t\t\tif ( useFlatShading ) cachedMaterial.flatShading = true;\n\n\t\t\t\tif ( useDerivativeTangents ) {\n\n\t\t\t\t\t// https://github.com/mrdoob/three.js/issues/11438#issuecomment-507003995\n\t\t\t\t\tif ( cachedMaterial.normalScale ) cachedMaterial.normalScale.y *= - 1;\n\t\t\t\t\tif ( cachedMaterial.clearcoatNormalScale ) cachedMaterial.clearcoatNormalScale.y *= - 1;\n\n\t\t\t\t}\n\n\t\t\t\tthis.cache.add( cacheKey, cachedMaterial );\n\n\t\t\t\tthis.associations.set( cachedMaterial, this.associations.get( material ) );\n\n\t\t\t}\n\n\t\t\tmaterial = cachedMaterial;\n\n\t\t}\n\n\t\tmesh.material = material;\n\n\t}\n\n\tgetMaterialType( /* materialIndex */ ) {\n\n\t\treturn MeshStandardMaterial;\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#materials\n\t *\n\t * @private\n\t * @param {number} materialIndex\n\t * @return {Promise<Material>}\n\t */\n\tloadMaterial( materialIndex ) {\n\n\t\tconst parser = this;\n\t\tconst json = this.json;\n\t\tconst extensions = this.extensions;\n\t\tconst materialDef = json.materials[ materialIndex ];\n\n\t\tlet materialType;\n\t\tconst materialParams = {};\n\t\tconst materialExtensions = materialDef.extensions || {};\n\n\t\tconst pending = [];\n\n\t\tif ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ] ) {\n\n\t\t\tconst kmuExtension = extensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ];\n\t\t\tmaterialType = kmuExtension.getMaterialType();\n\t\t\tpending.push( kmuExtension.extendParams( materialParams, materialDef, parser ) );\n\n\t\t} else {\n\n\t\t\t// Specification:\n\t\t\t// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#metallic-roughness-material\n\n\t\t\tconst metallicRoughness = materialDef.pbrMetallicRoughness || {};\n\n\t\t\tmaterialParams.color = new Color( 1.0, 1.0, 1.0 );\n\t\t\tmaterialParams.opacity = 1.0;\n\n\t\t\tif ( Array.isArray( metallicRoughness.baseColorFactor ) ) {\n\n\t\t\t\tconst array = metallicRoughness.baseColorFactor;\n\n\t\t\t\tmaterialParams.color.setRGB( array[ 0 ], array[ 1 ], array[ 2 ], LinearSRGBColorSpace );\n\t\t\t\tmaterialParams.opacity = array[ 3 ];\n\n\t\t\t}\n\n\t\t\tif ( metallicRoughness.baseColorTexture !== undefined ) {\n\n\t\t\t\tpending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture, SRGBColorSpace ) );\n\n\t\t\t}\n\n\t\t\tmaterialParams.metalness = metallicRoughness.metallicFactor !== undefined ? metallicRoughness.metallicFactor : 1.0;\n\t\t\tmaterialParams.roughness = metallicRoughness.roughnessFactor !== undefined ? metallicRoughness.roughnessFactor : 1.0;\n\n\t\t\tif ( metallicRoughness.metallicRoughnessTexture !== undefined ) {\n\n\t\t\t\tpending.push( parser.assignTexture( materialParams, 'metalnessMap', metallicRoughness.metallicRoughnessTexture ) );\n\t\t\t\tpending.push( parser.assignTexture( materialParams, 'roughnessMap', metallicRoughness.metallicRoughnessTexture ) );\n\n\t\t\t}\n\n\t\t\tmaterialType = this._invokeOne( function ( ext ) {\n\n\t\t\t\treturn ext.getMaterialType && ext.getMaterialType( materialIndex );\n\n\t\t\t} );\n\n\t\t\tpending.push( Promise.all( this._invokeAll( function ( ext ) {\n\n\t\t\t\treturn ext.extendMaterialParams && ext.extendMaterialParams( materialIndex, materialParams );\n\n\t\t\t} ) ) );\n\n\t\t}\n\n\t\tif ( materialDef.doubleSided === true ) {\n\n\t\t\tmaterialParams.side = DoubleSide;\n\n\t\t}\n\n\t\tconst alphaMode = materialDef.alphaMode || ALPHA_MODES.OPAQUE;\n\n\t\tif ( alphaMode === ALPHA_MODES.BLEND ) {\n\n\t\t\tmaterialParams.transparent = true;\n\n\t\t\t// See: https://github.com/mrdoob/three.js/issues/17706\n\t\t\tmaterialParams.depthWrite = false;\n\n\t\t} else {\n\n\t\t\tmaterialParams.transparent = false;\n\n\t\t\tif ( alphaMode === ALPHA_MODES.MASK ) {\n\n\t\t\t\tmaterialParams.alphaTest = materialDef.alphaCutoff !== undefined ? materialDef.alphaCutoff : 0.5;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( materialDef.normalTexture !== undefined && materialType !== MeshBasicMaterial ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'normalMap', materialDef.normalTexture ) );\n\n\t\t\tmaterialParams.normalScale = new Vector2( 1, 1 );\n\n\t\t\tif ( materialDef.normalTexture.scale !== undefined ) {\n\n\t\t\t\tconst scale = materialDef.normalTexture.scale;\n\n\t\t\t\tmaterialParams.normalScale.set( scale, scale );\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( materialDef.occlusionTexture !== undefined && materialType !== MeshBasicMaterial ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'aoMap', materialDef.occlusionTexture ) );\n\n\t\t\tif ( materialDef.occlusionTexture.strength !== undefined ) {\n\n\t\t\t\tmaterialParams.aoMapIntensity = materialDef.occlusionTexture.strength;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( materialDef.emissiveFactor !== undefined && materialType !== MeshBasicMaterial ) {\n\n\t\t\tconst emissiveFactor = materialDef.emissiveFactor;\n\t\t\tmaterialParams.emissive = new Color().setRGB( emissiveFactor[ 0 ], emissiveFactor[ 1 ], emissiveFactor[ 2 ], LinearSRGBColorSpace );\n\n\t\t}\n\n\t\tif ( materialDef.emissiveTexture !== undefined && materialType !== MeshBasicMaterial ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'emissiveMap', materialDef.emissiveTexture, SRGBColorSpace ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending ).then( function () {\n\n\t\t\tconst material = new materialType( materialParams );\n\n\t\t\tif ( materialDef.name ) material.name = materialDef.name;\n\n\t\t\tassignExtrasToUserData( material, materialDef );\n\n\t\t\tparser.associations.set( material, { materials: materialIndex } );\n\n\t\t\tif ( materialDef.extensions ) addUnknownExtensionsToUserData( extensions, material, materialDef );\n\n\t\t\treturn material;\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * When Object3D instances are targeted by animation, they need unique names.\n\t *\n\t * @private\n\t * @param {string} originalName\n\t * @return {string}\n\t */\n\tcreateUniqueName( originalName ) {\n\n\t\tconst sanitizedName = PropertyBinding.sanitizeNodeName( originalName || '' );\n\n\t\tif ( sanitizedName in this.nodeNamesUsed ) {\n\n\t\t\treturn sanitizedName + '_' + ( ++ this.nodeNamesUsed[ sanitizedName ] );\n\n\t\t} else {\n\n\t\t\tthis.nodeNamesUsed[ sanitizedName ] = 0;\n\n\t\t\treturn sanitizedName;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#geometry\n\t *\n\t * Creates BufferGeometries from primitives.\n\t *\n\t * @private\n\t * @param {Array<GLTF.Primitive>} primitives\n\t * @return {Promise<Array<BufferGeometry>>}\n\t */\n\tloadGeometries( primitives ) {\n\n\t\tconst parser = this;\n\t\tconst extensions = this.extensions;\n\t\tconst cache = this.primitiveCache;\n\n\t\tfunction createDracoPrimitive( primitive ) {\n\n\t\t\treturn extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ]\n\t\t\t\t.decodePrimitive( primitive, parser )\n\t\t\t\t.then( function ( geometry ) {\n\n\t\t\t\t\treturn addPrimitiveAttributes( geometry, primitive, parser );\n\n\t\t\t\t} );\n\n\t\t}\n\n\t\tconst pending = [];\n\n\t\tfor ( let i = 0, il = primitives.length; i < il; i ++ ) {\n\n\t\t\tconst primitive = primitives[ i ];\n\t\t\tconst cacheKey = createPrimitiveKey( primitive );\n\n\t\t\t// See if we've already created this geometry\n\t\t\tconst cached = cache[ cacheKey ];\n\n\t\t\tif ( cached ) {\n\n\t\t\t\t// Use the cached geometry if it exists\n\t\t\t\tpending.push( cached.promise );\n\n\t\t\t} else {\n\n\t\t\t\tlet geometryPromise;\n\n\t\t\t\tif ( primitive.extensions && primitive.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ] ) {\n\n\t\t\t\t\t// Use DRACO geometry if available\n\t\t\t\t\tgeometryPromise = createDracoPrimitive( primitive );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Otherwise create a new geometry\n\t\t\t\t\tgeometryPromise = addPrimitiveAttributes( new BufferGeometry(), primitive, parser );\n\n\t\t\t\t}\n\n\t\t\t\t// Cache this geometry\n\t\t\t\tcache[ cacheKey ] = { primitive: primitive, promise: geometryPromise };\n\n\t\t\t\tpending.push( geometryPromise );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#meshes\n\t *\n\t * @private\n\t * @param {number} meshIndex\n\t * @return {Promise<Group|Mesh|SkinnedMesh|Line|Points>}\n\t */\n\tloadMesh( meshIndex ) {\n\n\t\tconst parser = this;\n\t\tconst json = this.json;\n\t\tconst extensions = this.extensions;\n\n\t\tconst meshDef = json.meshes[ meshIndex ];\n\t\tconst primitives = meshDef.primitives;\n\n\t\tconst pending = [];\n\n\t\tfor ( let i = 0, il = primitives.length; i < il; i ++ ) {\n\n\t\t\tconst material = primitives[ i ].material === undefined\n\t\t\t\t? createDefaultMaterial( this.cache )\n\t\t\t\t: this.getDependency( 'material', primitives[ i ].material );\n\n\t\t\tpending.push( material );\n\n\t\t}\n\n\t\tpending.push( parser.loadGeometries( primitives ) );\n\n\t\treturn Promise.all( pending ).then( function ( results ) {\n\n\t\t\tconst materials = results.slice( 0, results.length - 1 );\n\t\t\tconst geometries = results[ results.length - 1 ];\n\n\t\t\tconst meshes = [];\n\n\t\t\tfor ( let i = 0, il = geometries.length; i < il; i ++ ) {\n\n\t\t\t\tconst geometry = geometries[ i ];\n\t\t\t\tconst primitive = primitives[ i ];\n\n\t\t\t\t// 1. create Mesh\n\n\t\t\t\tlet mesh;\n\n\t\t\t\tconst material = materials[ i ];\n\n\t\t\t\tif ( primitive.mode === WEBGL_CONSTANTS.TRIANGLES ||\n\t\t\t\t\t\tprimitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ||\n\t\t\t\t\t\tprimitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN ||\n\t\t\t\t\t\tprimitive.mode === undefined ) {\n\n\t\t\t\t\t// .isSkinnedMesh isn't in glTF spec. See ._markDefs()\n\t\t\t\t\tmesh = meshDef.isSkinnedMesh === true\n\t\t\t\t\t\t? new SkinnedMesh( geometry, material )\n\t\t\t\t\t\t: new Mesh( geometry, material );\n\n\t\t\t\t\tif ( mesh.isSkinnedMesh === true ) {\n\n\t\t\t\t\t\t// normalize skin weights to fix malformed assets (see #15319)\n\t\t\t\t\t\tmesh.normalizeSkinWeights();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ) {\n\n\t\t\t\t\t\tmesh.geometry = toTrianglesDrawMode( mesh.geometry, TriangleStripDrawMode );\n\n\t\t\t\t\t} else if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN ) {\n\n\t\t\t\t\t\tmesh.geometry = toTrianglesDrawMode( mesh.geometry, TriangleFanDrawMode );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( primitive.mode === WEBGL_CONSTANTS.LINES ) {\n\n\t\t\t\t\tmesh = new LineSegments( geometry, material );\n\n\t\t\t\t} else if ( primitive.mode === WEBGL_CONSTANTS.LINE_STRIP ) {\n\n\t\t\t\t\tmesh = new Line( geometry, material );\n\n\t\t\t\t} else if ( primitive.mode === WEBGL_CONSTANTS.LINE_LOOP ) {\n\n\t\t\t\t\tmesh = new LineLoop( geometry, material );\n\n\t\t\t\t} else if ( primitive.mode === WEBGL_CONSTANTS.POINTS ) {\n\n\t\t\t\t\tmesh = new Points( geometry, material );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow new Error( 'THREE.GLTFLoader: Primitive mode unsupported: ' + primitive.mode );\n\n\t\t\t\t}\n\n\t\t\t\tif ( Object.keys( mesh.geometry.morphAttributes ).length > 0 ) {\n\n\t\t\t\t\tupdateMorphTargets( mesh, meshDef );\n\n\t\t\t\t}\n\n\t\t\t\tmesh.name = parser.createUniqueName( meshDef.name || ( 'mesh_' + meshIndex ) );\n\n\t\t\t\tassignExtrasToUserData( mesh, meshDef );\n\n\t\t\t\tif ( primitive.extensions ) addUnknownExtensionsToUserData( extensions, mesh, primitive );\n\n\t\t\t\tparser.assignFinalMaterial( mesh );\n\n\t\t\t\tmeshes.push( mesh );\n\n\t\t\t}\n\n\t\t\tfor ( let i = 0, il = meshes.length; i < il; i ++ ) {\n\n\t\t\t\tparser.associations.set( meshes[ i ], {\n\t\t\t\t\tmeshes: meshIndex,\n\t\t\t\t\tprimitives: i\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\tif ( meshes.length === 1 ) {\n\n\t\t\t\tif ( meshDef.extensions ) addUnknownExtensionsToUserData( extensions, meshes[ 0 ], meshDef );\n\n\t\t\t\treturn meshes[ 0 ];\n\n\t\t\t}\n\n\t\t\tconst group = new Group();\n\n\t\t\tif ( meshDef.extensions ) addUnknownExtensionsToUserData( extensions, group, meshDef );\n\n\t\t\tparser.associations.set( group, { meshes: meshIndex } );\n\n\t\t\tfor ( let i = 0, il = meshes.length; i < il; i ++ ) {\n\n\t\t\t\tgroup.add( meshes[ i ] );\n\n\t\t\t}\n\n\t\t\treturn group;\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#cameras\n\t *\n\t * @private\n\t * @param {number} cameraIndex\n\t * @return {Promise<Camera>|undefined}\n\t */\n\tloadCamera( cameraIndex ) {\n\n\t\tlet camera;\n\t\tconst cameraDef = this.json.cameras[ cameraIndex ];\n\t\tconst params = cameraDef[ cameraDef.type ];\n\n\t\tif ( ! params ) {\n\n\t\t\tconsole.warn( 'THREE.GLTFLoader: Missing camera parameters.' );\n\t\t\treturn;\n\n\t\t}\n\n\t\tif ( cameraDef.type === 'perspective' ) {\n\n\t\t\tcamera = new PerspectiveCamera( MathUtils.radToDeg( params.yfov ), params.aspectRatio || 1, params.znear || 1, params.zfar || 2e6 );\n\n\t\t} else if ( cameraDef.type === 'orthographic' ) {\n\n\t\t\tcamera = new OrthographicCamera( - params.xmag, params.xmag, params.ymag, - params.ymag, params.znear, params.zfar );\n\n\t\t}\n\n\t\tif ( cameraDef.name ) camera.name = this.createUniqueName( cameraDef.name );\n\n\t\tassignExtrasToUserData( camera, cameraDef );\n\n\t\treturn Promise.resolve( camera );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins\n\t *\n\t * @private\n\t * @param {number} skinIndex\n\t * @return {Promise<Skeleton>}\n\t */\n\tloadSkin( skinIndex ) {\n\n\t\tconst skinDef = this.json.skins[ skinIndex ];\n\n\t\tconst pending = [];\n\n\t\tfor ( let i = 0, il = skinDef.joints.length; i < il; i ++ ) {\n\n\t\t\tpending.push( this._loadNodeShallow( skinDef.joints[ i ] ) );\n\n\t\t}\n\n\t\tif ( skinDef.inverseBindMatrices !== undefined ) {\n\n\t\t\tpending.push( this.getDependency( 'accessor', skinDef.inverseBindMatrices ) );\n\n\t\t} else {\n\n\t\t\tpending.push( null );\n\n\t\t}\n\n\t\treturn Promise.all( pending ).then( function ( results ) {\n\n\t\t\tconst inverseBindMatrices = results.pop();\n\t\t\tconst jointNodes = results;\n\n\t\t\t// Note that bones (joint nodes) may or may not be in the\n\t\t\t// scene graph at this time.\n\n\t\t\tconst bones = [];\n\t\t\tconst boneInverses = [];\n\n\t\t\tfor ( let i = 0, il = jointNodes.length; i < il; i ++ ) {\n\n\t\t\t\tconst jointNode = jointNodes[ i ];\n\n\t\t\t\tif ( jointNode ) {\n\n\t\t\t\t\tbones.push( jointNode );\n\n\t\t\t\t\tconst mat = new Matrix4();\n\n\t\t\t\t\tif ( inverseBindMatrices !== null ) {\n\n\t\t\t\t\t\tmat.fromArray( inverseBindMatrices.array, i * 16 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tboneInverses.push( mat );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( 'THREE.GLTFLoader: Joint \"%s\" could not be found.', skinDef.joints[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn new Skeleton( bones, boneInverses );\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#animations\n\t *\n\t * @private\n\t * @param {number} animationIndex\n\t * @return {Promise<AnimationClip>}\n\t */\n\tloadAnimation( animationIndex ) {\n\n\t\tconst json = this.json;\n\t\tconst parser = this;\n\n\t\tconst animationDef = json.animations[ animationIndex ];\n\t\tconst animationName = animationDef.name ? animationDef.name : 'animation_' + animationIndex;\n\n\t\tconst pendingNodes = [];\n\t\tconst pendingInputAccessors = [];\n\t\tconst pendingOutputAccessors = [];\n\t\tconst pendingSamplers = [];\n\t\tconst pendingTargets = [];\n\n\t\tfor ( let i = 0, il = animationDef.channels.length; i < il; i ++ ) {\n\n\t\t\tconst channel = animationDef.channels[ i ];\n\t\t\tconst sampler = animationDef.samplers[ channel.sampler ];\n\t\t\tconst target = channel.target;\n\t\t\tconst name = target.node;\n\t\t\tconst input = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.input ] : sampler.input;\n\t\t\tconst output = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.output ] : sampler.output;\n\n\t\t\tif ( target.node === undefined ) continue;\n\n\t\t\tpendingNodes.push( this.getDependency( 'node', name ) );\n\t\t\tpendingInputAccessors.push( this.getDependency( 'accessor', input ) );\n\t\t\tpendingOutputAccessors.push( this.getDependency( 'accessor', output ) );\n\t\t\tpendingSamplers.push( sampler );\n\t\t\tpendingTargets.push( target );\n\n\t\t}\n\n\t\treturn Promise.all( [\n\n\t\t\tPromise.all( pendingNodes ),\n\t\t\tPromise.all( pendingInputAccessors ),\n\t\t\tPromise.all( pendingOutputAccessors ),\n\t\t\tPromise.all( pendingSamplers ),\n\t\t\tPromise.all( pendingTargets )\n\n\t\t] ).then( function ( dependencies ) {\n\n\t\t\tconst nodes = dependencies[ 0 ];\n\t\t\tconst inputAccessors = dependencies[ 1 ];\n\t\t\tconst outputAccessors = dependencies[ 2 ];\n\t\t\tconst samplers = dependencies[ 3 ];\n\t\t\tconst targets = dependencies[ 4 ];\n\n\t\t\tconst tracks = [];\n\n\t\t\tfor ( let i = 0, il = nodes.length; i < il; i ++ ) {\n\n\t\t\t\tconst node = nodes[ i ];\n\t\t\t\tconst inputAccessor = inputAccessors[ i ];\n\t\t\t\tconst outputAccessor = outputAccessors[ i ];\n\t\t\t\tconst sampler = samplers[ i ];\n\t\t\t\tconst target = targets[ i ];\n\n\t\t\t\tif ( node === undefined ) continue;\n\n\t\t\t\tif ( node.updateMatrix ) {\n\n\t\t\t\t\tnode.updateMatrix();\n\n\t\t\t\t}\n\n\t\t\t\tconst createdTracks = parser._createAnimationTracks( node, inputAccessor, outputAccessor, sampler, target );\n\n\t\t\t\tif ( createdTracks ) {\n\n\t\t\t\t\tfor ( let k = 0; k < createdTracks.length; k ++ ) {\n\n\t\t\t\t\t\ttracks.push( createdTracks[ k ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tconst animation = new AnimationClip( animationName, undefined, tracks );\n\n\t\t\tassignExtrasToUserData( animation, animationDef );\n\n\t\t\treturn animation;\n\n\t\t} );\n\n\t}\n\n\tcreateNodeMesh( nodeIndex ) {\n\n\t\tconst json = this.json;\n\t\tconst parser = this;\n\t\tconst nodeDef = json.nodes[ nodeIndex ];\n\n\t\tif ( nodeDef.mesh === undefined ) return null;\n\n\t\treturn parser.getDependency( 'mesh', nodeDef.mesh ).then( function ( mesh ) {\n\n\t\t\tconst node = parser._getNodeRef( parser.meshCache, nodeDef.mesh, mesh );\n\n\t\t\t// if weights are provided on the node, override weights on the mesh.\n\t\t\tif ( nodeDef.weights !== undefined ) {\n\n\t\t\t\tnode.traverse( function ( o ) {\n\n\t\t\t\t\tif ( ! o.isMesh ) return;\n\n\t\t\t\t\tfor ( let i = 0, il = nodeDef.weights.length; i < il; i ++ ) {\n\n\t\t\t\t\t\to.morphTargetInfluences[ i ] = nodeDef.weights[ i ];\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\treturn node;\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#nodes-and-hierarchy\n\t *\n\t * @private\n\t * @param {number} nodeIndex\n\t * @return {Promise<Object3D>}\n\t */\n\tloadNode( nodeIndex ) {\n\n\t\tconst json = this.json;\n\t\tconst parser = this;\n\n\t\tconst nodeDef = json.nodes[ nodeIndex ];\n\n\t\tconst nodePending = parser._loadNodeShallow( nodeIndex );\n\n\t\tconst childPending = [];\n\t\tconst childrenDef = nodeDef.children || [];\n\n\t\tfor ( let i = 0, il = childrenDef.length; i < il; i ++ ) {\n\n\t\t\tchildPending.push( parser.getDependency( 'node', childrenDef[ i ] ) );\n\n\t\t}\n\n\t\tconst skeletonPending = nodeDef.skin === undefined\n\t\t\t? Promise.resolve( null )\n\t\t\t: parser.getDependency( 'skin', nodeDef.skin );\n\n\t\treturn Promise.all( [\n\t\t\tnodePending,\n\t\t\tPromise.all( childPending ),\n\t\t\tskeletonPending\n\t\t] ).then( function ( results ) {\n\n\t\t\tconst node = results[ 0 ];\n\t\t\tconst children = results[ 1 ];\n\t\t\tconst skeleton = results[ 2 ];\n\n\t\t\tif ( skeleton !== null ) {\n\n\t\t\t\t// This full traverse should be fine because\n\t\t\t\t// child glTF nodes have not been added to this node yet.\n\t\t\t\tnode.traverse( function ( mesh ) {\n\n\t\t\t\t\tif ( ! mesh.isSkinnedMesh ) return;\n\n\t\t\t\t\tmesh.bind( skeleton, _identityMatrix );\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\tfor ( let i = 0, il = children.length; i < il; i ++ ) {\n\n\t\t\t\tnode.add( children[ i ] );\n\n\t\t\t}\n\n\t\t\t// Reconstruct pivot from container pattern created by GLTFExporter\n\t\t\t// The container has position+pivot, rotation, scale; child has -pivot offset and mesh\n\t\t\tif ( node.userData.pivot !== undefined && children.length > 0 ) {\n\n\t\t\t\tconst pivot = node.userData.pivot;\n\t\t\t\tconst pivotChild = children[ 0 ];\n\n\t\t\t\t// Set pivot on container and adjust transforms\n\t\t\t\tnode.pivot = new Vector3().fromArray( pivot );\n\n\t\t\t\t// Adjust container position: stored as position + pivot, so subtract pivot\n\t\t\t\tnode.position.x -= pivot[ 0 ];\n\t\t\t\tnode.position.y -= pivot[ 1 ];\n\t\t\t\tnode.position.z -= pivot[ 2 ];\n\n\t\t\t\t// Remove the child's -pivot offset since pivot now handles it\n\t\t\t\tpivotChild.position.set( 0, 0, 0 );\n\n\t\t\t\tdelete node.userData.pivot;\n\n\t\t\t}\n\n\t\t\treturn node;\n\n\t\t} );\n\n\t}\n\n\t// ._loadNodeShallow() parses a single node.\n\t// skin and child nodes are created and added in .loadNode() (no '_' prefix).\n\t_loadNodeShallow( nodeIndex ) {\n\n\t\tconst json = this.json;\n\t\tconst extensions = this.extensions;\n\t\tconst parser = this;\n\n\t\t// This method is called from .loadNode() and .loadSkin().\n\t\t// Cache a node to avoid duplication.\n\n\t\tif ( this.nodeCache[ nodeIndex ] !== undefined ) {\n\n\t\t\treturn this.nodeCache[ nodeIndex ];\n\n\t\t}\n\n\t\tconst nodeDef = json.nodes[ nodeIndex ];\n\n\t\t// reserve node's name before its dependencies, so the root has the intended name.\n\t\tconst nodeName = nodeDef.name ? parser.createUniqueName( nodeDef.name ) : '';\n\n\t\tconst pending = [];\n\n\t\tconst meshPromise = parser._invokeOne( function ( ext ) {\n\n\t\t\treturn ext.createNodeMesh && ext.createNodeMesh( nodeIndex );\n\n\t\t} );\n\n\t\tif ( meshPromise ) {\n\n\t\t\tpending.push( meshPromise );\n\n\t\t}\n\n\t\tif ( nodeDef.camera !== undefined ) {\n\n\t\t\tpending.push( parser.getDependency( 'camera', nodeDef.camera ).then( function ( camera ) {\n\n\t\t\t\treturn parser._getNodeRef( parser.cameraCache, nodeDef.camera, camera );\n\n\t\t\t} ) );\n\n\t\t}\n\n\t\tparser._invokeAll( function ( ext ) {\n\n\t\t\treturn ext.createNodeAttachment && ext.createNodeAttachment( nodeIndex );\n\n\t\t} ).forEach( function ( promise ) {\n\n\t\t\tpending.push( promise );\n\n\t\t} );\n\n\t\tthis.nodeCache[ nodeIndex ] = Promise.all( pending ).then( function ( objects ) {\n\n\t\t\tlet node;\n\n\t\t\t// .isBone isn't in glTF spec. See ._markDefs\n\t\t\tif ( nodeDef.isBone === true ) {\n\n\t\t\t\tnode = new Bone();\n\n\t\t\t} else if ( objects.length > 1 ) {\n\n\t\t\t\tnode = new Group();\n\n\t\t\t} else if ( objects.length === 1 ) {\n\n\t\t\t\tnode = objects[ 0 ];\n\n\t\t\t} else {\n\n\t\t\t\tnode = new Object3D();\n\n\t\t\t}\n\n\t\t\tif ( node !== objects[ 0 ] ) {\n\n\t\t\t\tfor ( let i = 0, il = objects.length; i < il; i ++ ) {\n\n\t\t\t\t\tnode.add( objects[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( nodeDef.name ) {\n\n\t\t\t\tnode.userData.name = nodeDef.name;\n\t\t\t\tnode.name = nodeName;\n\n\t\t\t}\n\n\t\t\tassignExtrasToUserData( node, nodeDef );\n\n\t\t\tif ( nodeDef.extensions ) addUnknownExtensionsToUserData( extensions, node, nodeDef );\n\n\t\t\tif ( nodeDef.matrix !== undefined ) {\n\n\t\t\t\tconst matrix = new Matrix4();\n\t\t\t\tmatrix.fromArray( nodeDef.matrix );\n\t\t\t\tnode.applyMatrix4( matrix );\n\n\t\t\t} else {\n\n\t\t\t\tif ( nodeDef.translation !== undefined ) {\n\n\t\t\t\t\tnode.position.fromArray( nodeDef.translation );\n\n\t\t\t\t}\n\n\t\t\t\tif ( nodeDef.rotation !== undefined ) {\n\n\t\t\t\t\tnode.quaternion.fromArray( nodeDef.rotation );\n\n\t\t\t\t}\n\n\t\t\t\tif ( nodeDef.scale !== undefined ) {\n\n\t\t\t\t\tnode.scale.fromArray( nodeDef.scale );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( ! parser.associations.has( node ) ) {\n\n\t\t\t\tparser.associations.set( node, {} );\n\n\t\t\t} else if ( nodeDef.mesh !== undefined && parser.meshCache.refs[ nodeDef.mesh ] > 1 ) {\n\n\t\t\t\tconst mapping = parser.associations.get( node );\n\t\t\t\tparser.associations.set( node, { ...mapping } );\n\n\t\t\t}\n\n\t\t\tparser.associations.get( node ).nodes = nodeIndex;\n\n\t\t\treturn node;\n\n\t\t} );\n\n\t\treturn this.nodeCache[ nodeIndex ];\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#scenes\n\t *\n\t * @private\n\t * @param {number} sceneIndex\n\t * @return {Promise<Group>}\n\t */\n\tloadScene( sceneIndex ) {\n\n\t\tconst extensions = this.extensions;\n\t\tconst sceneDef = this.json.scenes[ sceneIndex ];\n\t\tconst parser = this;\n\n\t\t// Loader returns Group, not Scene.\n\t\t// See: https://github.com/mrdoob/three.js/issues/18342#issuecomment-578981172\n\t\tconst scene = new Group();\n\t\tif ( sceneDef.name ) scene.name = parser.createUniqueName( sceneDef.name );\n\n\t\tassignExtrasToUserData( scene, sceneDef );\n\n\t\tif ( sceneDef.extensions ) addUnknownExtensionsToUserData( extensions, scene, sceneDef );\n\n\t\tconst nodeIds = sceneDef.nodes || [];\n\n\t\tconst pending = [];\n\n\t\tfor ( let i = 0, il = nodeIds.length; i < il; i ++ ) {\n\n\t\t\tpending.push( parser.getDependency( 'node', nodeIds[ i ] ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending ).then( function ( nodes ) {\n\n\t\t\tfor ( let i = 0, il = nodes.length; i < il; i ++ ) {\n\n\t\t\t\tconst node = nodes[ i ];\n\n\t\t\t\t// If the node already has a parent, it means it's being reused across multiple scenes.\n\t\t\t\t// Clone it to avoid the second scene's add() removing it from the first scene.\n\t\t\t\t// See: https://github.com/mrdoob/three.js/issues/27993\n\t\t\t\tif ( node.parent !== null ) {\n\n\t\t\t\t\tscene.add( clone( node ) );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tscene.add( node );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Removes dangling associations, associations that reference a node that\n\t\t\t// didn't make it into the scene.\n\t\t\tconst reduceAssociations = ( node ) => {\n\n\t\t\t\tconst reducedAssociations = new Map();\n\n\t\t\t\tfor ( const [ key, value ] of parser.associations ) {\n\n\t\t\t\t\tif ( key instanceof Material || key instanceof Texture ) {\n\n\t\t\t\t\t\treducedAssociations.set( key, value );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tnode.traverse( ( node ) => {\n\n\t\t\t\t\tconst mappings = parser.associations.get( node );\n\n\t\t\t\t\tif ( mappings != null ) {\n\n\t\t\t\t\t\treducedAssociations.set( node, mappings );\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t\treturn reducedAssociations;\n\n\t\t\t};\n\n\t\t\tparser.associations = reduceAssociations( scene );\n\n\t\t\treturn scene;\n\n\t\t} );\n\n\t}\n\n\t_createAnimationTracks( node, inputAccessor, outputAccessor, sampler, target ) {\n\n\t\tconst tracks = [];\n\n\t\tconst targetName = node.name ? node.name : node.uuid;\n\t\tconst targetNames = [];\n\n\t\tfunction collectMorphTargets( object ) {\n\n\t\t\tif ( object.morphTargetInfluences ) {\n\n\t\t\t\ttargetNames.push( object.name ? object.name : object.uuid );\n\n\t\t\t}\n\n\t\t}\n\n\n\t\tif ( PATH_PROPERTIES[ target.path ] === PATH_PROPERTIES.weights ) {\n\n\t\t\tcollectMorphTargets( node );\n\n\t\t\t// for multi-primitive meshes, the node is a Group containing the sub-meshes\n\n\t\t\tif ( node.isGroup ) {\n\n\t\t\t\tnode.children.forEach( collectMorphTargets );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\ttargetNames.push( targetName );\n\n\t\t}\n\n\t\tlet TypedKeyframeTrack;\n\n\t\tswitch ( PATH_PROPERTIES[ target.path ] ) {\n\n\t\t\tcase PATH_PROPERTIES.weights:\n\n\t\t\t\tTypedKeyframeTrack = NumberKeyframeTrack;\n\t\t\t\tbreak;\n\n\t\t\tcase PATH_PROPERTIES.rotation:\n\n\t\t\t\tTypedKeyframeTrack = QuaternionKeyframeTrack;\n\t\t\t\tbreak;\n\n\t\t\tcase PATH_PROPERTIES.translation:\n\t\t\tcase PATH_PROPERTIES.scale:\n\n\t\t\t\tTypedKeyframeTrack = VectorKeyframeTrack;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\n\t\t\t\tswitch ( outputAccessor.itemSize ) {\n\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tTypedKeyframeTrack = NumberKeyframeTrack;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 2:\n\t\t\t\t\tcase 3:\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tTypedKeyframeTrack = VectorKeyframeTrack;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t}\n\n\t\tconst interpolation = sampler.interpolation !== undefined ? INTERPOLATION[ sampler.interpolation ] : InterpolateLinear;\n\n\n\t\tconst outputArray = this._getArrayFromAccessor( outputAccessor );\n\n\t\tfor ( let j = 0, jl = targetNames.length; j < jl; j ++ ) {\n\n\t\t\tconst track = new TypedKeyframeTrack(\n\t\t\t\ttargetNames[ j ] + '.' + PATH_PROPERTIES[ target.path ],\n\t\t\t\tinputAccessor.array,\n\t\t\t\toutputArray,\n\t\t\t\tinterpolation\n\t\t\t);\n\n\t\t\t// Override interpolation with custom factory method.\n\t\t\tif ( sampler.interpolation === 'CUBICSPLINE' ) {\n\n\t\t\t\tthis._createCubicSplineTrackInterpolant( track );\n\n\t\t\t}\n\n\t\t\ttracks.push( track );\n\n\t\t}\n\n\t\treturn tracks;\n\n\t}\n\n\t_getArrayFromAccessor( accessor ) {\n\n\t\tlet outputArray = accessor.array;\n\n\t\tif ( accessor.normalized ) {\n\n\t\t\tconst scale = getNormalizedComponentScale( outputArray.constructor );\n\t\t\tconst scaled = new Float32Array( outputArray.length );\n\n\t\t\tfor ( let j = 0, jl = outputArray.length; j < jl; j ++ ) {\n\n\t\t\t\tscaled[ j ] = outputArray[ j ] * scale;\n\n\t\t\t}\n\n\t\t\toutputArray = scaled;\n\n\t\t}\n\n\t\treturn outputArray;\n\n\t}\n\n\t_createCubicSplineTrackInterpolant( track ) {\n\n\t\ttrack.createInterpolant = function InterpolantFactoryMethodGLTFCubicSpline( result ) {\n\n\t\t\t// A CUBICSPLINE keyframe in glTF has three output values for each input value,\n\t\t\t// representing inTangent, splineVertex, and outTangent. As a result, track.getValueSize()\n\t\t\t// must be divided by three to get the interpolant's sampleSize argument.\n\n\t\t\tconst interpolantType = ( this instanceof QuaternionKeyframeTrack ) ? GLTFCubicSplineQuaternionInterpolant : GLTFCubicSplineInterpolant;\n\n\t\t\treturn new interpolantType( this.times, this.values, this.getValueSize() / 3, result );\n\n\t\t};\n\n\t\t// Mark as CUBICSPLINE. `track.getInterpolation()` doesn't support custom interpolants.\n\t\ttrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline = true;\n\n\t}\n\n}\n\n/**\n *\n * @private\n * @param {BufferGeometry} geometry\n * @param {GLTF.Primitive} primitiveDef\n * @param {GLTFParser} parser\n */\nfunction computeBounds( geometry, primitiveDef, parser ) {\n\n\tconst attributes = primitiveDef.attributes;\n\n\tconst box = new Box3();\n\n\tif ( attributes.POSITION !== undefined ) {\n\n\t\tconst accessor = parser.json.accessors[ attributes.POSITION ];\n\n\t\tconst min = accessor.min;\n\t\tconst max = accessor.max;\n\n\t\t// glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement.\n\n\t\tif ( min !== undefined && max !== undefined ) {\n\n\t\t\tbox.set(\n\t\t\t\tnew Vector3( min[ 0 ], min[ 1 ], min[ 2 ] ),\n\t\t\t\tnew Vector3( max[ 0 ], max[ 1 ], max[ 2 ] )\n\t\t\t);\n\n\t\t\tif ( accessor.normalized ) {\n\n\t\t\t\tconst boxScale = getNormalizedComponentScale( WEBGL_COMPONENT_TYPES[ accessor.componentType ] );\n\t\t\t\tbox.min.multiplyScalar( boxScale );\n\t\t\t\tbox.max.multiplyScalar( boxScale );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.GLTFLoader: Missing min/max properties for accessor POSITION.' );\n\n\t\t\treturn;\n\n\t\t}\n\n\t} else {\n\n\t\treturn;\n\n\t}\n\n\tconst targets = primitiveDef.targets;\n\n\tif ( targets !== undefined ) {\n\n\t\tconst maxDisplacement = new Vector3();\n\t\tconst vector = new Vector3();\n\n\t\tfor ( let i = 0, il = targets.length; i < il; i ++ ) {\n\n\t\t\tconst target = targets[ i ];\n\n\t\t\tif ( target.POSITION !== undefined ) {\n\n\t\t\t\tconst accessor = parser.json.accessors[ target.POSITION ];\n\t\t\t\tconst min = accessor.min;\n\t\t\t\tconst max = accessor.max;\n\n\t\t\t\t// glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement.\n\n\t\t\t\tif ( min !== undefined && max !== undefined ) {\n\n\t\t\t\t\t// we need to get max of absolute components because target weight is [-1,1]\n\t\t\t\t\tvector.setX( Math.max( Math.abs( min[ 0 ] ), Math.abs( max[ 0 ] ) ) );\n\t\t\t\t\tvector.setY( Math.max( Math.abs( min[ 1 ] ), Math.abs( max[ 1 ] ) ) );\n\t\t\t\t\tvector.setZ( Math.max( Math.abs( min[ 2 ] ), Math.abs( max[ 2 ] ) ) );\n\n\n\t\t\t\t\tif ( accessor.normalized ) {\n\n\t\t\t\t\t\tconst boxScale = getNormalizedComponentScale( WEBGL_COMPONENT_TYPES[ accessor.componentType ] );\n\t\t\t\t\t\tvector.multiplyScalar( boxScale );\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Note: this assumes that the sum of all weights is at most 1. This isn't quite correct - it's more conservative\n\t\t\t\t\t// to assume that each target can have a max weight of 1. However, for some use cases - notably, when morph targets\n\t\t\t\t\t// are used to implement key-frame animations and as such only two are active at a time - this results in very large\n\t\t\t\t\t// boxes. So for now we make a box that's sometimes a touch too small but is hopefully mostly of reasonable size.\n\t\t\t\t\tmaxDisplacement.max( vector );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( 'THREE.GLTFLoader: Missing min/max properties for accessor POSITION.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// As per comment above this box isn't conservative, but has a reasonable size for a very large number of morph targets.\n\t\tbox.expandByVector( maxDisplacement );\n\n\t}\n\n\tgeometry.boundingBox = box;\n\n\tconst sphere = new Sphere();\n\n\tbox.getCenter( sphere.center );\n\tsphere.radius = box.min.distanceTo( box.max ) / 2;\n\n\tgeometry.boundingSphere = sphere;\n\n}\n\n/**\n *\n * @private\n * @param {BufferGeometry} geometry\n * @param {GLTF.Primitive} primitiveDef\n * @param {GLTFParser} parser\n * @return {Promise<BufferGeometry>}\n */\nfunction addPrimitiveAttributes( geometry, primitiveDef, parser ) {\n\n\tconst attributes = primitiveDef.attributes;\n\n\tconst pending = [];\n\n\tfunction assignAttributeAccessor( accessorIndex, attributeName ) {\n\n\t\treturn parser.getDependency( 'accessor', accessorIndex )\n\t\t\t.then( function ( accessor ) {\n\n\t\t\t\tgeometry.setAttribute( attributeName, accessor );\n\n\t\t\t} );\n\n\t}\n\n\tfor ( const gltfAttributeName in attributes ) {\n\n\t\tconst threeAttributeName = ATTRIBUTES[ gltfAttributeName ] || gltfAttributeName.toLowerCase();\n\n\t\t// Skip attributes already provided by e.g. Draco extension.\n\t\tif ( threeAttributeName in geometry.attributes ) continue;\n\n\t\tpending.push( assignAttributeAccessor( attributes[ gltfAttributeName ], threeAttributeName ) );\n\n\t}\n\n\tif ( primitiveDef.indices !== undefined && ! geometry.index ) {\n\n\t\tconst accessor = parser.getDependency( 'accessor', primitiveDef.indices ).then( function ( accessor ) {\n\n\t\t\tgeometry.setIndex( accessor );\n\n\t\t} );\n\n\t\tpending.push( accessor );\n\n\t}\n\n\tif ( ColorManagement.workingColorSpace !== LinearSRGBColorSpace && 'COLOR_0' in attributes ) {\n\n\t\tconsole.warn( `THREE.GLTFLoader: Converting vertex colors from \"srgb-linear\" to \"${ColorManagement.workingColorSpace}\" not supported.` );\n\n\t}\n\n\tassignExtrasToUserData( geometry, primitiveDef );\n\n\tcomputeBounds( geometry, primitiveDef, parser );\n\n\treturn Promise.all( pending ).then( function () {\n\n\t\treturn primitiveDef.targets !== undefined\n\t\t\t? addMorphTargets( geometry, primitiveDef.targets, parser )\n\t\t\t: geometry;\n\n\t} );\n\n}\n\n/**\n * Loader result of `GLTFLoader`.\n *\n * @typedef {Object} GLTFLoader~LoadObject\n * @property {Array<AnimationClip>} animations - An array of animation clips.\n * @property {Object} asset - Meta data about the loaded asset.\n * @property {Array<Camera>} cameras - An array of cameras.\n * @property {GLTFParser} parser - A reference to the internal parser.\n * @property {Group} scene - The default scene.\n * @property {Array<Group>} scenes - glTF assets might define multiple scenes.\n * @property {Object} userData - Additional data.\n **/\n\nexport { GLTFLoader };\n","/**\r\n * 提供添加基础几何体(正方体、球体)以及导入外部模型文件的功能\r\n * 所有模型均自动标记为可移动(isMovable = true)\r\n */\r\n\r\nimport * as THREE from \"three\";\r\nimport { addModel } from \"./index\";\r\nimport { OBJLoader } from \"three/examples/jsm/loaders/OBJLoader.js\";\r\nimport { GLTFLoader } from \"three/examples/jsm/loaders/GLTFLoader.js\";\r\n\r\n//#region ─── 添加基础体 ───\r\n\r\n/** 添加一个蓝色的正方体,位置在地面上方 0.5 单位 */\r\nexport function addBox() {\r\n const geo = new THREE.BoxGeometry(1, 1, 1);\r\n const mat = new THREE.MeshStandardMaterial({ color: 0x00aaff });\r\n const mesh = new THREE.Mesh(geo, mat);\r\n mesh.position.y = 0.5;\r\n mesh.userData.isMovable = true;\r\n mesh.name = \"正方体\";\r\n addModel(mesh, true);\r\n return mesh;\r\n}\r\n\r\n/** 添加一个橙色的球体,位置在地面上方 0.6 单位 */\r\nexport function addSphere() {\r\n const geo = new THREE.SphereGeometry(0.6, 32, 32);\r\n const mat = new THREE.MeshStandardMaterial({ color: 0xff8800 });\r\n const mesh = new THREE.Mesh(geo, mat);\r\n mesh.position.y = 0.6;\r\n mesh.userData.isMovable = true;\r\n mesh.name = \"球体\";\r\n addModel(mesh, true);\r\n return mesh;\r\n}\r\n//#endregion\r\n\r\n//#region ─── 导入外部模型 ───\r\n\r\n/**\r\n * 从 File 对象导入 3D 模型(支持 .obj, .gltf, .glb)\r\n * 导入后自动标记所有节点为可移动,并居中放置\r\n * @param file - 模型文件\r\n * @returns Promise 解析为模型根对象\r\n */\r\nexport function importModelFromFile(file: File): Promise<THREE.Object3D> {\r\n return new Promise((resolve, reject) => {\r\n const ext = file.name.split(\".\").pop()?.toLowerCase();\r\n const url = URL.createObjectURL(file);\r\n\r\n let loader: any;\r\n if (ext === \"obj\") loader = new OBJLoader();\r\n else if (ext === \"gltf\" || ext === \"glb\") loader = new GLTFLoader();\r\n else {\r\n reject(new Error(\"不支持的文件格式,请使用 .obj, .gltf, .glb\"));\r\n return;\r\n }\r\n\r\n loader.load(\r\n url,\r\n (result: any) => {\r\n // 获取模型根对象\r\n const model = ext === \"gltf\" || ext === \"glb\" ? result.scene : result;\r\n // 遍历所有后代,标记为可移动,设置默认名称,优化 Mesh\r\n model.traverse((child: THREE.Object3D) => {\r\n child.userData.isMovable = true;\r\n if (!child.name) child.name = child.type;\r\n if (child.type === \"Mesh\") {\r\n child.frustumCulled = true; // 启用视锥体裁剪\r\n (child as THREE.Mesh).geometry?.computeVertexNormals(); // 重新计算法线\r\n }\r\n });\r\n // 将模型包围盒中心置于原点(居中)\r\n const box = new THREE.Box3().setFromObject(model);\r\n const center = box.getCenter(new THREE.Vector3());\r\n model.position.sub(center);\r\n // 添加到场景并自动选中\r\n addModel(model, true);\r\n resolve(model);\r\n },\r\n undefined,\r\n (err: any) => reject(err),\r\n );\r\n });\r\n}\r\n\r\n/**\r\n * 根据类型字符串添加对应的基础模型\r\n * @param type - 'box' 或 'sphere'\r\n */\r\nexport function addModelByType(type: string) {\r\n switch (type) {\r\n case \"box\":\r\n addBox();\r\n break;\r\n case \"sphere\":\r\n addSphere();\r\n break;\r\n }\r\n}\r\n//#endregion\r\n","<template>\r\n <div class=\"tree-node\" ref=\"nodeRef\">\r\n <!-- 节点行 -->\r\n <div\r\n class=\"tree-item\"\r\n :class=\"{ selected: isSelected }\"\r\n @click=\"handleSelect\"\r\n >\r\n <!-- 展开/收起箭头 -->\r\n <span\r\n v-if=\"hasChildren\"\r\n class=\"toggle-icon\"\r\n @click.stop=\"toggleExpand(node.uuid)\"\r\n >\r\n {{ isExpanded ? \"▼\" : \"▶\" }}\r\n </span>\r\n <span v-else class=\"toggle-placeholder\"></span>\r\n <!-- 图标 -->\r\n <span class=\"tree-icon\">{{ getIcon(node) }}</span>\r\n <!-- 名称 -->\r\n <span class=\"tree-name\">{{ getDisplayName(node) }}</span>\r\n <!-- 删除按钮 -->\r\n <button class=\"tree-delete\" @click.stop=\"handleDelete\">×</button>\r\n </div>\r\n <!-- 子节点列表(递归) -->\r\n <div v-if=\"isExpanded && hasChildren\" class=\"tree-children\">\r\n <TreeItem\r\n v-for=\"child in childNodes\"\r\n :key=\"child.uuid\"\r\n :node=\"child\"\r\n :selected-object=\"selectedObject\"\r\n :version=\"version\"\r\n @select=\"emit('select', $event)\"\r\n @delete=\"emit('delete', $event)\"\r\n />\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\n/**\r\n * 递归树节点组件,用于展示场景物体的层级结构\r\n * 展开状态由父组件通过 provide/inject 共享\r\n * 当节点被选中时自动滚动到可视区域\r\n */\r\n\r\nimport { computed, inject, ref, watchEffect, type Ref } from \"vue\";\r\nimport type { Object3D } from \"three\";\r\n\r\nconst props = defineProps<{\r\n /** 当前节点对应的 Three.js 物体 */\r\n node: Object3D;\r\n /** 当前选中的物体(外部传入) */\r\n selectedObject: Object3D | null;\r\n /** 版本号,用于强制重新计算子节点列表 */\r\n version: number;\r\n}>();\r\n\r\nconst emit = defineEmits<{\r\n (e: \"select\", obj: Object3D): void;\r\n (e: \"delete\", obj: Object3D): void;\r\n}>();\r\n\r\n// ─── DOM 引用 ───\r\nconst nodeRef = ref<HTMLElement | null>(null);\r\n\r\n// ─── 注入展开状态管理 ───\r\nconst { expandedSet, toggleExpand } = inject<{\r\n expandedSet: Ref<Set<string>>;\r\n toggleExpand: (uuid: string) => void;\r\n}>(\"treeExpand\")!;\r\n\r\n// ─── 计算属性 ───\r\n\r\n/** 当前节点是否展开(基于展开集合) */\r\nconst isExpanded = computed(() => expandedSet.value.has(props.node.uuid));\r\n\r\n/** 是否有可移动的子节点(依赖 version) */\r\nconst hasChildren = computed(() => {\r\n const _ = props.version; // 建立依赖\r\n _\r\n return props.node.children.some((child) => child.userData.isMovable === true);\r\n});\r\n\r\n/** 可移动的子节点列表(依赖 version) */\r\nconst childNodes = computed(() => {\r\n const _ = props.version; // 建立依赖\r\n _\r\n return props.node.children.filter(\r\n (child) => child.userData.isMovable === true,\r\n );\r\n});\r\n\r\n/** 当前节点是否被选中 */\r\nconst isSelected = computed(\r\n () => props.selectedObject?.uuid === props.node.uuid,\r\n);\r\n\r\n/**\r\n * 自动滚动到选中节点(使用 watchEffect + flush: 'post' 确保 DOM 更新后执行)\r\n */\r\nwatchEffect(\r\n () => {\r\n if (isSelected.value && nodeRef.value) {\r\n nodeRef.value.scrollIntoView({\r\n block: \"nearest\", // 仅当元素不在可视区域时才滚动\r\n behavior: \"smooth\", // 平滑滚动\r\n });\r\n }\r\n },\r\n { flush: \"post\" },\r\n);\r\n\r\n// ─── 事件处理 ───\r\n\r\n/** 点击节点行:阻止冒泡并触发选中事件 */\r\nconst handleSelect = (event: MouseEvent) => {\r\n event.stopPropagation();\r\n emit(\"select\", props.node);\r\n};\r\n\r\n/** 点击删除按钮:阻止冒泡并触发删除事件 */\r\nconst handleDelete = (event: MouseEvent) => {\r\n event.stopPropagation();\r\n emit(\"delete\", props.node);\r\n};\r\n\r\n// ─── 辅助函数 ───\r\n\r\n/** 根据对象类型返回对应的图标字符 */\r\nconst getIcon = (obj: Object3D) => {\r\n if (obj.type === \"Mesh\" || obj.type === \"Sprite\") return \"🟦\";\r\n if (obj.type === \"Light\") return \"💡\";\r\n return \"📦\";\r\n};\r\n\r\n/** 获取对象的显示名称,若没有则自动生成 */\r\nconst getDisplayName = (obj: Object3D) => obj.name || `${obj.type} (${obj.id})`;\r\n</script>\r\n\r\n<style lang=\"less\" scoped>\r\n/* 节点样式 */\r\n.tree-node {\r\n .tree-item {\r\n display: flex;\r\n align-items: center;\r\n padding: 4px 10px;\r\n cursor: pointer;\r\n transition: background 0.15s;\r\n &:hover {\r\n background: #2a4050;\r\n }\r\n }\r\n .tree-item.selected {\r\n background: #3e5a6b;\r\n }\r\n\r\n .toggle-icon {\r\n cursor: pointer;\r\n width: 20px;\r\n text-align: center;\r\n font-size: 12px;\r\n user-select: none;\r\n }\r\n .toggle-placeholder {\r\n width: 20px;\r\n display: inline-block;\r\n }\r\n .tree-icon {\r\n margin-right: 6px;\r\n font-size: 14px;\r\n }\r\n .tree-name {\r\n flex: 1;\r\n font-size: 13px;\r\n user-select: none;\r\n }\r\n .tree-delete {\r\n background: transparent;\r\n border: none;\r\n color: #e74c3c;\r\n font-size: 16px;\r\n cursor: pointer;\r\n padding: 0 4px;\r\n line-height: 1;\r\n &:hover {\r\n color: #ff6b6b;\r\n }\r\n }\r\n}\r\n.tree-children {\r\n padding-left: 20px;\r\n} /* 缩进 */\r\n</style>\r\n","/**\r\n * 树形展开状态管理的组合式函数\r\n * 提供展开集合的响应式管理、切换展开、展开路径(自动展开父级)等功能\r\n * 用于 PropertyPanel 和 TreeItem 组件之间共享展开状态\r\n */\r\n\r\nimport { ref, watch, type Ref } from \"vue\";\r\nimport type { Object3D } from \"three\";\r\n\r\n/**\r\n * @param selectedObject - 响应式的当前选中物体(Ref)\r\n * @returns 包含展开集合和切换方法的对象\r\n */\r\nexport function useTreeExpand(selectedObject: Ref<Object3D | null>) {\r\n /** 存储所有展开节点的 uuid 的 Set(响应式) */\r\n const expandedSet = ref<Set<string>>(new Set());\r\n\r\n /**\r\n * 切换某个节点的展开/收起状态\r\n * @param uuid - 节点的唯一标识符\r\n */\r\n const toggleExpand = (uuid: string) => {\r\n const newSet = new Set(expandedSet.value);\r\n if (newSet.has(uuid)) newSet.delete(uuid);\r\n else newSet.add(uuid);\r\n expandedSet.value = newSet;\r\n };\r\n\r\n /**\r\n * 展开从目标节点到根节点的所有父级节点(不展开目标节点自身)\r\n * 用于点击场景物体后自动展开树形路径\r\n * @param target - 目标物体\r\n */\r\n const expandPath = (target: Object3D) => {\r\n if (!target) return;\r\n const newSet = new Set(expandedSet.value);\r\n let current = target.parent;\r\n // 逐级向上遍历,直到遇到场景根节点\r\n while (current && current.type !== \"Scene\") {\r\n newSet.add(current.uuid);\r\n current = current.parent;\r\n }\r\n expandedSet.value = newSet;\r\n };\r\n\r\n // 监听选中物体的变化,当选中新物体时自动展开其路径\r\n watch(\r\n selectedObject,\r\n (obj) => {\r\n if (obj) expandPath(obj);\r\n },\r\n { immediate: true },\r\n );\r\n\r\n return { expandedSet, toggleExpand };\r\n}\r\n","<template>\r\n <div class=\"property-panel\" v-if=\"transform\">\r\n <h3>属性面板</h3>\r\n\r\n <!-- 场景物体树 -->\r\n <div class=\"property-group tree-group\">\r\n <label>场景物体</label>\r\n <div class=\"tree-container\">\r\n <TreeItem\r\n v-for=\"obj in treeData\"\r\n :key=\"obj.uuid\"\r\n :node=\"obj\"\r\n :selected-object=\"selectedObject\"\r\n :version=\"treeVersion\"\r\n @select=\"emit('treeSelect', $event)\"\r\n @delete=\"handleTreeDelete\"\r\n />\r\n <div v-if=\"treeData.length === 0\" class=\"tree-empty\">暂无物体</div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"property-group\">\r\n <label>全局属性</label>\r\n <div class=\"row\"></div>\r\n </div>\r\n\r\n <!-- Tab 切换(仅控制变换属性) -->\r\n <div class=\"tabs\" v-if=\"selectedObject\">\r\n <button\r\n class=\"tab-btn\"\r\n :class=\"{ active: activeTab === 'transform' }\"\r\n @click=\"activeTab = 'transform'\"\r\n >\r\n 🔄 变换\r\n </button>\r\n <button\r\n class=\"tab-btn\"\r\n :class=\"{ active: activeTab === 'info' }\"\r\n @click=\"activeTab = 'info'\"\r\n >\r\n ℹ️ 信息\r\n </button>\r\n </div>\r\n\r\n <!-- Tab 内容 -->\r\n <div class=\"tab-content\" v-if=\"selectedObject\">\r\n <!-- 变换 Tab -->\r\n <div v-show=\"activeTab === 'transform'\">\r\n <!-- 位置 -->\r\n <div class=\"property-group\">\r\n <label>位置</label>\r\n <div class=\"row\">\r\n <span>X:</span>\r\n <input\r\n type=\"number\"\r\n v-model.number=\"transform.position.x\"\r\n step=\"0.01\"\r\n @input=\"emitChange\"\r\n />\r\n <span>Y:</span>\r\n <input\r\n type=\"number\"\r\n v-model.number=\"transform.position.y\"\r\n step=\"0.01\"\r\n @input=\"emitChange\"\r\n />\r\n <span>Z:</span>\r\n <input\r\n type=\"number\"\r\n v-model.number=\"transform.position.z\"\r\n step=\"0.01\"\r\n @input=\"emitChange\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- 旋转 (弧度) -->\r\n <div class=\"property-group\">\r\n <label>旋转 (弧度)</label>\r\n <div class=\"row\">\r\n <span>X:</span>\r\n <input\r\n type=\"number\"\r\n v-model.number=\"transform.rotation.x\"\r\n step=\"0.01\"\r\n @input=\"emitChange\"\r\n />\r\n <span>Y:</span>\r\n <input\r\n type=\"number\"\r\n v-model.number=\"transform.rotation.y\"\r\n step=\"0.01\"\r\n @input=\"emitChange\"\r\n />\r\n <span>Z:</span>\r\n <input\r\n type=\"number\"\r\n v-model.number=\"transform.rotation.z\"\r\n step=\"0.01\"\r\n @input=\"emitChange\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- 缩放 -->\r\n <div class=\"property-group\">\r\n <label>缩放</label>\r\n <div class=\"row\">\r\n <span>X:</span>\r\n <input\r\n type=\"number\"\r\n v-model.number=\"transform.scale.x\"\r\n step=\"0.01\"\r\n @input=\"emitChange\"\r\n />\r\n <span>Y:</span>\r\n <input\r\n type=\"number\"\r\n v-model.number=\"transform.scale.y\"\r\n step=\"0.01\"\r\n @input=\"emitChange\"\r\n />\r\n <span>Z:</span>\r\n <input\r\n type=\"number\"\r\n v-model.number=\"transform.scale.z\"\r\n step=\"0.01\"\r\n @input=\"emitChange\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- ─── 材质属性 ─── -->\r\n <div class=\"property-group material-group\" v-if=\"selectedObject\">\r\n <label>材质</label>\r\n <div class=\"slider-row\">\r\n <span class=\"slider-label\">金属度</span>\r\n <input\r\n type=\"range\"\r\n min=\"0\"\r\n max=\"1\"\r\n step=\"0.01\"\r\n v-model.number=\"materialProps.metalness\"\r\n @input=\"onMaterialChange\"\r\n />\r\n <span class=\"slider-value\">{{\r\n materialProps.metalness.toFixed(2)\r\n }}</span>\r\n </div>\r\n <div class=\"slider-row\">\r\n <span class=\"slider-label\">粗糙度</span>\r\n <input\r\n type=\"range\"\r\n min=\"0\"\r\n max=\"1\"\r\n step=\"0.01\"\r\n v-model.number=\"materialProps.roughness\"\r\n @input=\"onMaterialChange\"\r\n />\r\n <span class=\"slider-value\">{{\r\n materialProps.roughness.toFixed(2)\r\n }}</span>\r\n </div>\r\n <div class=\"slider-row\">\r\n <span class=\"slider-label\">透明度</span>\r\n <input\r\n type=\"range\"\r\n min=\"0\"\r\n max=\"1\"\r\n step=\"0.01\"\r\n v-model.number=\"materialProps.opacity\"\r\n @input=\"onMaterialChange\"\r\n />\r\n <span class=\"slider-value\">{{\r\n materialProps.opacity.toFixed(2)\r\n }}</span>\r\n </div>\r\n <div class=\"material-hint\" v-if=\"!hasStandardMaterial\">\r\n ⚠️ 当前材质不支持金属度/粗糙度(仅支持 Standard/Phong)\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"property-panel empty\" v-else>\r\n <p>未选中任何模型</p>\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\n/**\r\n * 属性面板组件\r\n * 显示当前选中物体的变换参数,并提供树形场景物体列表\r\n * 使用 provide 向子组件提供树形展开状态管理\r\n */\r\n\r\nimport type { Object3D, Mesh } from \"three\";\r\nimport TreeItem from \"./TreeItem.vue\";\r\nimport { ref, provide, toRef, watch, reactive } from \"vue\";\r\nimport { useTreeExpand } from \"../composables/useTreeExpand\";\r\n\r\nconst props = defineProps<{\r\n /** 变换数据对象,包含 position, rotation, scale */\r\n transform: {\r\n position: { x: number; y: number; z: number };\r\n rotation: { x: number; y: number; z: number };\r\n scale: { x: number; y: number; z: number };\r\n } | null;\r\n /** 顶层物体列表 */\r\n treeData: Object3D[];\r\n /** 当前选中的物体 */\r\n selectedObject: Object3D | null;\r\n}>();\r\n\r\nconst emit = defineEmits<{\r\n (e: \"propertyChange\"): void; // 变换数据变化\r\n (e: \"treeSelect\", obj: Object3D): void; // 树形选中节点\r\n (e: \"treeDelete\", obj: Object3D): void; // 树形删除节点\r\n}>();\r\n\r\n/** 触发变换变更事件(输入框 input 事件) */\r\nconst emitChange = () => emit(\"propertyChange\");\r\n\r\n// ─── Tab 状态 ───\r\nconst activeTab = ref<\"transform\" | \"info\">(\"transform\");\r\n\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n//#region 树形组件\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n\r\n// ─── 树形版本号 ───\r\n/**\r\n * 版本号用于强制刷新 TreeItem 的子节点列表(在删除节点后增加)\r\n * 因为子节点列表依赖 version 来重新计算\r\n */\r\nconst treeVersion = ref(0);\r\n\r\n// ─── 树形展开状态管理 ───\r\n/**\r\n * 使用组合式函数管理展开集合,并提供给子组件\r\n * 将 selectedObject prop 转换为 Ref,以便 useTreeExpand 监听变化\r\n */\r\nconst selectedObjectRef = toRef(props, \"selectedObject\");\r\nconst { expandedSet, toggleExpand } = useTreeExpand(selectedObjectRef);\r\n\r\n// 向子组件提供展开状态\r\nprovide(\"treeExpand\", { expandedSet, toggleExpand });\r\n\r\n// ─── 自定义删除处理 ───\r\n/**\r\n * 删除节点时递增版本号,使所有 TreeItem 重新计算 childNodes\r\n */\r\nconst handleTreeDelete = (obj: Object3D) => {\r\n treeVersion.value++;\r\n emit(\"treeDelete\", obj);\r\n};\r\n//#endregion\r\n\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n//#region 材质属性管理\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n/**\r\n * 材质属性数据(与滑块双向绑定)\r\n */\r\nconst materialProps = reactive({\r\n metalness: 0,\r\n roughness: 0.5,\r\n opacity: 1,\r\n});\r\n\r\n/** 是否包含支持 PBR 的材质 */\r\nconst hasStandardMaterial = ref(false);\r\n\r\n/**\r\n * 读取选中物体的材质属性(取第一个 Mesh 的材质作为代表)\r\n */\r\nfunction readMaterialFromObject(\r\n obj: Object3D,\r\n): { metalness: number; roughness: number; opacity: number } | null {\r\n let result: { metalness: number; roughness: number; opacity: number } | null =\r\n null;\r\n obj.traverse((child) => {\r\n if (child.type === \"Mesh\" && !result) {\r\n const mesh = child as Mesh;\r\n const materials = Array.isArray(mesh.material)\r\n ? mesh.material\r\n : [mesh.material];\r\n for (const mat of materials) {\r\n // 支持 MeshStandardMaterial 和 MeshPhongMaterial\r\n if (\r\n mat &&\r\n (mat.type === \"MeshStandardMaterial\" ||\r\n mat.type === \"MeshPhongMaterial\")\r\n ) {\r\n const stdMat = mat as any;\r\n result = {\r\n metalness: stdMat.metalness ?? 0,\r\n roughness: stdMat.roughness ?? 0.5,\r\n opacity: mat.opacity ?? 1,\r\n };\r\n break;\r\n }\r\n }\r\n }\r\n });\r\n return result;\r\n}\r\n\r\n/**\r\n * 应用材质属性到选中物体的所有 Mesh\r\n */\r\nfunction applyMaterialToObject(\r\n obj: Object3D,\r\n props: { metalness?: number; roughness?: number; opacity?: number },\r\n) {\r\n let applied = false;\r\n obj.traverse((child) => {\r\n if (child.type === \"Mesh\") {\r\n const mesh = child as Mesh;\r\n const materials = Array.isArray(mesh.material)\r\n ? mesh.material\r\n : [mesh.material];\r\n for (const mat of materials) {\r\n if (\r\n mat &&\r\n (mat.type === \"MeshStandardMaterial\" ||\r\n mat.type === \"MeshPhongMaterial\")\r\n ) {\r\n if (props.metalness !== undefined)\r\n (mat as any).metalness = props.metalness;\r\n if (props.roughness !== undefined)\r\n (mat as any).roughness = props.roughness;\r\n if (props.opacity !== undefined) {\r\n mat.opacity = props.opacity;\r\n mat.transparent = props.opacity < 1;\r\n }\r\n mat.needsUpdate = true;\r\n applied = true;\r\n }\r\n }\r\n }\r\n });\r\n return applied;\r\n}\r\n\r\n/**\r\n * 当滑块变化时应用到物体\r\n */\r\nfunction onMaterialChange() {\r\n if (props.selectedObject) {\r\n const applied = applyMaterialToObject(props.selectedObject, {\r\n metalness: materialProps.metalness,\r\n roughness: materialProps.roughness,\r\n opacity: materialProps.opacity,\r\n });\r\n hasStandardMaterial.value = applied;\r\n }\r\n}\r\n\r\n/**\r\n * 监听选中物体变化,更新滑块值和材质支持状态\r\n */\r\nwatch(\r\n () => props.selectedObject,\r\n (newObj) => {\r\n if (newObj) {\r\n const read = readMaterialFromObject(newObj);\r\n if (read) {\r\n materialProps.metalness = read.metalness;\r\n materialProps.roughness = read.roughness;\r\n materialProps.opacity = read.opacity;\r\n hasStandardMaterial.value = true;\r\n } else {\r\n // 没有材质或材质不支持,设为默认值并标记不支持\r\n materialProps.metalness = 0;\r\n materialProps.roughness = 0.5;\r\n materialProps.opacity = 1;\r\n hasStandardMaterial.value = false;\r\n }\r\n } else {\r\n // 取消选中时重置\r\n materialProps.metalness = 0;\r\n materialProps.roughness = 0.5;\r\n materialProps.opacity = 1;\r\n hasStandardMaterial.value = false;\r\n }\r\n },\r\n { immediate: true },\r\n);\r\n//#endregion\r\n</script>\r\n\r\n<style lang=\"less\" scoped>\r\n// ─── Tabs ───\r\n.tabs {\r\n display: flex;\r\n gap: 0;\r\n border-bottom: 2px solid #1a2a36;\r\n margin-bottom: 16px;\r\n\r\n .tab-btn {\r\n flex: 1;\r\n padding: 8px 12px;\r\n background: transparent;\r\n border: none;\r\n color: #95a5a6;\r\n font-size: 13px;\r\n cursor: pointer;\r\n transition:\r\n color 0.2s,\r\n border-bottom 0.2s;\r\n border-bottom: 2px solid transparent;\r\n margin-bottom: -2px;\r\n\r\n &:hover {\r\n color: #ecf0f1;\r\n }\r\n\r\n &.active {\r\n color: #f1c40f;\r\n border-bottom-color: #f1c40f;\r\n }\r\n }\r\n}\r\n\r\n.property-panel {\r\n width: 320px;\r\n height: 100%;\r\n background: #2c3e50;\r\n color: #ecf0f1;\r\n padding: 16px;\r\n box-sizing: border-box;\r\n border-left: 1px solid #1a2a36;\r\n overflow-y: auto;\r\n font-size: 14px;\r\n h3 {\r\n margin-top: 0;\r\n text-align: center;\r\n }\r\n\r\n .property-group {\r\n margin-bottom: 20px;\r\n border-bottom: 1px solid #1a2a36;\r\n padding-bottom: 12px;\r\n label {\r\n font-weight: bold;\r\n display: block;\r\n margin-bottom: 8px;\r\n color: #f1c40f;\r\n }\r\n .row {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n margin-bottom: 6px;\r\n span {\r\n width: 20px;\r\n text-align: right;\r\n }\r\n input {\r\n background: #1e2a36;\r\n border: 1px solid #3e5a6b;\r\n color: #ecf0f1;\r\n padding: 4px 8px;\r\n border-radius: 4px;\r\n width: 48px;\r\n }\r\n }\r\n }\r\n\r\n .tab-content {\r\n // ─── 材质滑块 ───\r\n .material-group {\r\n .slider-row {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n margin-bottom: 6px;\r\n\r\n .slider-label {\r\n width: 50px;\r\n font-size: 12px;\r\n color: #95a5a6;\r\n }\r\n\r\n input[type=\"range\"] {\r\n flex: 1;\r\n height: 4px;\r\n -webkit-appearance: none;\r\n background: #1e2a36;\r\n border-radius: 2px;\r\n outline: none;\r\n\r\n &::-webkit-slider-thumb {\r\n -webkit-appearance: none;\r\n width: 12px;\r\n height: 12px;\r\n border-radius: 50%;\r\n background: #f1c40f;\r\n cursor: pointer;\r\n }\r\n }\r\n\r\n .slider-value {\r\n width: 36px;\r\n font-size: 12px;\r\n text-align: center;\r\n color: #ecf0f1;\r\n }\r\n }\r\n\r\n .material-hint {\r\n margin-top: 6px;\r\n font-size: 12px;\r\n color: #e67e22;\r\n }\r\n }\r\n }\r\n}\r\n.empty {\r\n text-align: center;\r\n color: #95a5a6;\r\n}\r\n.tree-group {\r\n margin-top: 10px;\r\n .tree-container {\r\n max-height: 200px;\r\n overflow-y: auto;\r\n background: #1a2a36;\r\n border-radius: 4px;\r\n padding: 4px 0;\r\n }\r\n}\r\n.tree-empty {\r\n padding: 8px 10px;\r\n color: #95a5a6;\r\n font-style: italic;\r\n}\r\n</style>\r\n","<template>\r\n <div class=\"top-bar\">\r\n <div class=\"left-section\">\r\n <!-- 文件菜单 -->\r\n <div\r\n class=\"dropdown-wrapper\"\r\n @mouseenter=\"showFileMenu = true\"\r\n @mouseleave=\"showFileMenu = false\"\r\n >\r\n <button class=\"menu-btn\">文件</button>\r\n <div class=\"dropdown-menu\" v-show=\"showFileMenu\">\r\n <div class=\"menu-item\" @click=\"handleNew\">新建</div>\r\n <div\r\n class=\"menu-item dropdown-wrapper sub-trigger\"\r\n @mouseenter=\"showOpenSub = true\"\r\n @mouseleave=\"showOpenSub = false\"\r\n >\r\n <span>打开</span>\r\n <div class=\"dropdown-menu sub-menu\" v-show=\"showOpenSub\">\r\n <div class=\"menu-item\" @click=\"handleOpenProject\">打开项目</div>\r\n <div class=\"menu-item\" @click=\"handleOpenModel\">打开模型</div>\r\n <div class=\"menu-item\" @click=\"handleOpenScene\">打开场景</div>\r\n </div>\r\n </div>\r\n <div class=\"menu-item\" @click=\"handleSave\">保存</div>\r\n <div class=\"menu-item\" @click=\"handleExport\">导出</div>\r\n </div>\r\n </div>\r\n\r\n <!-- 添加菜单 -->\r\n <div\r\n class=\"dropdown-wrapper\"\r\n @mouseenter=\"showAddMenu = true\"\r\n @mouseleave=\"showAddMenu = false\"\r\n >\r\n <button class=\"menu-btn\">添加</button>\r\n <div class=\"dropdown-menu\" v-show=\"showAddMenu\">\r\n <div class=\"menu-item\" @click=\"handleUndo\">组</div>\r\n <div\r\n class=\"menu-item dropdown-wrapper sub-trigger\"\r\n @mouseenter=\"showOpenGrid = true\"\r\n @mouseleave=\"showOpenGrid = false\"\r\n >\r\n <span>网格</span>\r\n <div class=\"dropdown-menu sub-menu\" v-show=\"showOpenGrid\">\r\n <div class=\"menu-item\" @click=\"emit('addModel', 'box')\">\r\n 正方体\r\n </div>\r\n <div class=\"menu-item\" @click=\"emit('addModel', 'sphere')\">\r\n 球体\r\n </div>\r\n <div class=\"menu-item\" @click=\"triggerImport\">导入</div>\r\n </div>\r\n </div>\r\n <div class=\"menu-item\" @click=\"handleDuplicate\">光源</div>\r\n <div class=\"menu-item\" @click=\"handleDelete\">摄像机</div>\r\n </div>\r\n </div>\r\n\r\n <!-- 编辑菜单 -->\r\n <div\r\n class=\"dropdown-wrapper\"\r\n @mouseenter=\"showEditMenu = true\"\r\n @mouseleave=\"showEditMenu = false\"\r\n >\r\n <button class=\"menu-btn\">编辑</button>\r\n <div class=\"dropdown-menu\" v-show=\"showEditMenu\">\r\n <div class=\"menu-item\" @click=\"handleUndo\">撤销</div>\r\n <div class=\"menu-item\" @click=\"handleRedo\">重做</div>\r\n <div class=\"menu-item\" @click=\"handleDuplicate\">复制</div>\r\n <div class=\"menu-item\" @click=\"handleDelete\">删除</div>\r\n </div>\r\n </div>\r\n\r\n <!-- 视图菜单 -->\r\n <div\r\n class=\"dropdown-wrapper\"\r\n @mouseenter=\"showViewMenu = true\"\r\n @mouseleave=\"showViewMenu = false\"\r\n >\r\n <button class=\"menu-btn\">视图</button>\r\n <div class=\"dropdown-menu\" v-show=\"showViewMenu\">\r\n <div class=\"menu-item\" @click=\"handleResetCamera\">重置相机</div>\r\n <div class=\"menu-item\" @click=\"handleToggleGrid\">显示网格</div>\r\n </div>\r\n </div>\r\n\r\n <!-- 帮助菜单 -->\r\n <div\r\n class=\"dropdown-wrapper\"\r\n @mouseenter=\"showHelpMenu = true\"\r\n @mouseleave=\"showHelpMenu = false\"\r\n >\r\n <button class=\"menu-btn\">帮助</button>\r\n <div class=\"dropdown-menu\" v-show=\"showHelpMenu\">\r\n <div class=\"menu-item\" @click=\"handleHelp\">使用帮助</div>\r\n <div class=\"menu-item\" @click=\"handleAbout\">关于</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"right-section\">\r\n <span class=\"app-title\">3D 模型编辑器</span>\r\n </div>\r\n\r\n <!-- 隐藏的文件输入框,用于导入模型 -->\r\n <input\r\n type=\"file\"\r\n ref=\"fileInput\"\r\n accept=\".obj,.gltf,.glb\"\r\n style=\"display: none\"\r\n @change=\"onFileSelected\"\r\n />\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\n/**\r\n * 顶部菜单栏组件\r\n * 包含文件、添加、编辑、视图、帮助等下拉菜单\r\n * 通过 emit 向父组件传递添加模型和导入模型事件\r\n */\r\n\r\nimport { ref } from \"vue\";\r\n\r\n// 各菜单显示状态\r\nconst showFileMenu = ref(false);\r\nconst showEditMenu = ref(false);\r\nconst showViewMenu = ref(false);\r\nconst showHelpMenu = ref(false);\r\nconst showAddMenu = ref(false);\r\nconst showOpenSub = ref(false); // 文件→打开子菜单\r\nconst showOpenGrid = ref(false); // 添加→网格子菜单\r\n\r\nconst emit = defineEmits<{\r\n (e: \"addModel\", type: string): void;\r\n (e: \"importModel\", file: File): void;\r\n}>();\r\n\r\n// ─── 文件输入 ───\r\nconst fileInput = ref<HTMLInputElement | null>(null);\r\n\r\n/** 触发文件选择对话框 */\r\nconst triggerImport = () => fileInput.value?.click();\r\n\r\n/** 文件选择后,向上传递文件对象,并重置 input 以便重复选择同一文件 */\r\nconst onFileSelected = (event: Event) => {\r\n const input = event.target as HTMLInputElement;\r\n if (input.files && input.files.length > 0) {\r\n emit(\"importModel\", input.files[0]);\r\n input.value = \"\";\r\n }\r\n};\r\n\r\n// ─── 各菜单项的占位处理(后续可扩展功能) ───\r\nconst handleNew = () => console.log(\"新建项目\");\r\nconst handleSave = () => console.log(\"保存场景\");\r\nconst handleExport = () => console.log(\"导出模型\");\r\nconst handleUndo = () => console.log(\"撤销\");\r\nconst handleRedo = () => console.log(\"重做\");\r\nconst handleDuplicate = () => console.log(\"复制物体\");\r\nconst handleDelete = () => console.log(\"删除物体\");\r\nconst handleResetCamera = () => console.log(\"重置相机\");\r\nconst handleToggleGrid = () => console.log(\"切换网格\");\r\nconst handleHelp = () => console.log(\"打开帮助\");\r\nconst handleAbout = () => console.log(\"关于编辑器\");\r\nconst handleOpenProject = () => console.log(\"打开项目\");\r\nconst handleOpenModel = () => console.log(\"打开模型\");\r\nconst handleOpenScene = () => console.log(\"打开场景\");\r\n</script>\r\n\r\n<style lang=\"less\" scoped>\r\n.top-bar {\r\n height: 40px;\r\n background: #1a2a36;\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 0 16px;\r\n border-bottom: 1px solid #2a4050;\r\n flex-shrink: 0;\r\n user-select: none;\r\n\r\n .left-section {\r\n display: flex;\r\n gap: 12px;\r\n align-items: center;\r\n\r\n .dropdown-wrapper {\r\n position: relative;\r\n display: inline-block;\r\n\r\n .menu-btn {\r\n background: transparent;\r\n border: none;\r\n color: #ecf0f1;\r\n padding: 6px 12px;\r\n border-radius: 4px;\r\n cursor: pointer;\r\n font-size: 14px;\r\n transition: background 0.2s;\r\n &:hover {\r\n background: #2a4050;\r\n }\r\n }\r\n\r\n .dropdown-menu {\r\n position: absolute;\r\n top: 100%;\r\n left: 0;\r\n background: #2c3e50;\r\n border: 1px solid #3e5a6b;\r\n border-radius: 4px;\r\n min-width: 140px;\r\n padding: 4px 0;\r\n z-index: 100;\r\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);\r\n\r\n .menu-item {\r\n padding: 6px 16px;\r\n color: #ecf0f1;\r\n cursor: pointer;\r\n font-size: 13px;\r\n transition: background 0.15s;\r\n white-space: nowrap;\r\n &:hover {\r\n background: #3e5a6b;\r\n }\r\n }\r\n .menu-item.sub-trigger {\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n position: relative;\r\n }\r\n }\r\n .sub-menu {\r\n position: absolute;\r\n left: 100%;\r\n top: 0;\r\n background: #2c3e50;\r\n border: 1px solid #3e5a6b;\r\n border-radius: 4px;\r\n min-width: 140px;\r\n padding: 4px 0;\r\n z-index: 101;\r\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);\r\n }\r\n }\r\n }\r\n\r\n .right-section {\r\n display: flex;\r\n align-items: center;\r\n }\r\n .app-title {\r\n color: #88aaff;\r\n font-size: 16px;\r\n font-weight: 500;\r\n letter-spacing: 0.5px;\r\n }\r\n}\r\n</style>\r\n","<template>\r\n <div class=\"bottom-bar\">\r\n <div class=\"status-left\">\r\n <span>就绪</span>\r\n </div>\r\n <div class=\"status-right\">\r\n <span>顶点: 0 | 面: 0</span>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\n/**\r\n * 底部状态栏\r\n * 目前仅显示“就绪”和占位统计信息\r\n * 未来可扩展显示顶点/面数、坐标等\r\n */\r\n</script>\r\n\r\n<style lang=\"less\" scoped>\r\n.bottom-bar {\r\n height: 40px;\r\n background: #1a2a36;\r\n border-top: 1px solid #2a4050;\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 0 16px;\r\n flex-shrink: 0;\r\n color: #95a5a6;\r\n font-size: 13px;\r\n user-select: none;\r\n .status-left,\r\n .status-right {\r\n display: flex;\r\n gap: 16px;\r\n }\r\n}\r\n</style>\r\n","<template>\r\n <div class=\"app-layout\">\r\n <!-- 顶部菜单栏 -->\r\n <TopBar\r\n @add-model=\"handleAddModel\"\r\n @import-model=\"handleImportModel\"\r\n v-if=\"mode === 'edit'\"\r\n />\r\n <div :class=\"`editor-container editor-container-mode-${mode}`\">\r\n <!-- Three.js 画布 -->\r\n <div :class=\"`canvas canvas-mode-${mode}`\" ref=\"containerRef\"></div>\r\n <!-- 属性面板 -->\r\n <PropertyPanel\r\n :transform=\"transform\"\r\n :tree-data=\"treeData\"\r\n :selected-object=\"selectedModel\"\r\n @property-change=\"handlePropertyChange\"\r\n @tree-select=\"handleTreeSelect\"\r\n @tree-delete=\"handleTreeDelete\"\r\n v-if=\"mode === 'edit'\"\r\n />\r\n </div>\r\n <!-- 底部状态栏 -->\r\n <BottomBar v-if=\"mode === 'edit'\" />\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\n/**\r\n * 编辑器主组件,负责:\r\n * - 挂载 Three.js 编辑器\r\n * - 管理选中物体的变换数据(位置/旋转/缩放)\r\n * - 同步场景物体树形数据\r\n * - 处理添加模型、导入模型、树形选中/删除等交互\r\n */\r\n\r\nimport { onBeforeUnmount, onMounted, reactive, ref, shallowRef } from \"vue\";\r\nimport {\r\n initEditor,\r\n setSelectedObjectCallback,\r\n setTransformChangeCallback,\r\n onSceneObjectsChangeCallback,\r\n getSceneObjects,\r\n removeModelById,\r\n selectObject,\r\n destroyEditor,\r\n} from \"../three/index\";\r\nimport { addModelByType, importModelFromFile } from \"../three/addHandle\";\r\nimport PropertyPanel from \"./PropertyPanel.vue\";\r\nimport TopBar from \"./TopBar.vue\";\r\nimport BottomBar from \"./BottomBar.vue\";\r\nimport type { Object3D } from \"three\";\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n mode: string;\r\n sceneData: any;\r\n }>(),\r\n {\r\n mode: \"edit\",\r\n sceneData: null,\r\n },\r\n);\r\n\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n//#region 属性面板\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n\r\n/** 当前选中的模型对象 */\r\nconst selectedModel = ref<Object3D | null>(null);\r\n\r\n/**\r\n * 变换数据(位置/旋转/缩放),与属性面板双向绑定\r\n * 使用 reactive 使每个属性独立响应式\r\n */\r\nconst transform = reactive({\r\n position: { x: 0, y: 0, z: 0 },\r\n rotation: { x: 0, y: 0, z: 0 },\r\n scale: { x: 1, y: 1, z: 1 },\r\n});\r\n\r\n// ─── 同步函数 ───\r\n\r\n/**\r\n * 从 Three.js 物体同步变换数据到 transform 对象\r\n * 保留三位小数,避免浮点数误差\r\n */\r\nconst syncTransformFromObject = (obj: Object3D) => {\r\n transform.position.x = Number(obj.position.x.toFixed(3));\r\n transform.position.y = Number(obj.position.y.toFixed(3));\r\n transform.position.z = Number(obj.position.z.toFixed(3));\r\n transform.rotation.x = Number(obj.rotation.x.toFixed(3));\r\n transform.rotation.y = Number(obj.rotation.y.toFixed(3));\r\n transform.rotation.z = Number(obj.rotation.z.toFixed(3));\r\n transform.scale.x = Number(obj.scale.x.toFixed(3));\r\n transform.scale.y = Number(obj.scale.y.toFixed(3));\r\n transform.scale.z = Number(obj.scale.z.toFixed(3));\r\n};\r\n\r\n/**\r\n * 将 transform 数据应用到 Three.js 物体\r\n * 用于属性面板输入变化时更新物体\r\n */\r\nconst applyTransformToObject = (obj: Object3D) => {\r\n obj.position.set(\r\n transform.position.x,\r\n transform.position.y,\r\n transform.position.z,\r\n );\r\n obj.rotation.set(\r\n transform.rotation.x,\r\n transform.rotation.y,\r\n transform.rotation.z,\r\n );\r\n obj.scale.set(transform.scale.x, transform.scale.y, transform.scale.z);\r\n};\r\n\r\n// ─── 注册回调 ───\r\n\r\n// 选中物体变化时同步到本地状态\r\nsetSelectedObjectCallback((obj) => {\r\n selectedModel.value = obj;\r\n if (obj) syncTransformFromObject(obj);\r\n});\r\n\r\n// 变换过程中(拖拽)实时更新面板\r\nsetTransformChangeCallback((obj) => {\r\n syncTransformFromObject(obj);\r\n});\r\n\r\n// ─── 事件处理 ───\r\n\r\n/** 属性面板数值变化时,应用变换到物体 */\r\nconst handlePropertyChange = () => {\r\n if (selectedModel.value) applyTransformToObject(selectedModel.value);\r\n};\r\n\r\n/** 添加模型(来自顶部菜单) */\r\nconst handleAddModel = (type: string) => addModelByType(type);\r\n\r\n/** 导入模型(来自顶部菜单) */\r\nconst handleImportModel = async (file: File) => {\r\n try {\r\n await importModelFromFile(file);\r\n } catch (error) {\r\n console.error(\"导入失败:\", error);\r\n alert(\"导入失败:\" + (error as Error).message);\r\n }\r\n};\r\n//#endregion\r\n\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n//#region 树形面板\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n\r\n/** 树形数据使用 shallowRef 避免深度响应式,提高性能 */\r\nconst treeData = shallowRef<Object3D[]>([]);\r\n\r\n// 注册树形数据变化回调\r\nonSceneObjectsChangeCallback((objects) => {\r\n treeData.value = objects;\r\n});\r\n\r\n/** 初始化树形数据 */\r\nconst initTree = () => {\r\n const objects = getSceneObjects();\r\n if (objects) treeData.value = objects;\r\n};\r\n\r\n/** 树形选中节点 → 同步选中场景物体 */\r\nconst handleTreeSelect = (obj: Object3D) => selectObject(obj);\r\n\r\n/** 树形删除节点 → 删除场景物体 */\r\nconst handleTreeDelete = (obj: Object3D) => removeModelById(obj.uuid);\r\n//#endregion\r\n\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n//#region 初始化\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n\r\nconst containerRef = ref<HTMLElement | null>(null);\r\n/** 挂载 Three.js 编辑器并初始化树 */\r\nconst init = () => {\r\n if (containerRef.value)\r\n initEditor(containerRef.value, props.mode, props.sceneData);\r\n // const dom = document.getElementById(\"sl_canvas\");\r\n // if (dom) initEditor(dom);\r\n initTree();\r\n};\r\n\r\nonMounted(init);\r\n\r\nonBeforeUnmount(() => {\r\n console.log('endset_three_editor destroy');\r\n destroyEditor();\r\n});\r\n//#endregion\r\n</script>\r\n\r\n<style lang=\"less\" scoped>\r\n/* 整体布局:纵向排列,编辑器区域占剩余高度 */\r\n.app-layout {\r\n display: flex;\r\n flex-direction: column;\r\n height: 100%;\r\n width: 100%;\r\n}\r\n.editor-container {\r\n display: flex;\r\n width: 100%;\r\n}\r\n.editor-container-mode-edit {\r\n height: calc(100% - 80px); /* 顶部栏 40px + 底部栏 40px */\r\n}\r\n.editor-container-mode-run {\r\n height: 100%; /* 顶部栏 40px + 底部栏 40px */\r\n}\r\n.canvas {\r\n height: 100%;\r\n background-color: transparent;\r\n position: relative;\r\n}\r\n.canvas-mode-edit {\r\n width: calc(100% - 320px); /* 属性面板宽 320px */\r\n}\r\n.canvas-mode-run {\r\n width: 100%; /* 属性面板宽 320px */\r\n}\r\n</style>\r\n"],"names":["_changeEvent","_startEvent","_endEvent","_ray","Ray","_plane","Plane","_TILT_LIMIT","MathUtils","_v","Vector3","_twoPI","_STATE","_EPS","OrbitControls","Controls","object","domElement","MOUSE","TOUCH","Quaternion","Spherical","Vector2","onPointerMove","onPointerDown","onPointerUp","onContextMenu","onMouseWheel","onKeyDown","onTouchStart","onTouchMove","onMouseDown","onMouseMove","interceptControlDown","interceptControlUp","type","element","deltaX","deltaY","dollyScale","angle","deltaTime","position","min","max","zoomChanged","prevRadius","newRadius","radiusDelta","mouseBefore","prevZoom","mouseAfter","delta","normalizedDelta","distance","objectMatrix","targetDistance","x","y","rect","dx","dy","w","h","dist","event","needsUpdate","centerX","centerY","i","pointerId","mode","newEvent","mouseAction","_raycaster","Raycaster","_tempVector","_tempVector2","_tempQuaternion","_unit","_mouseDownEvent","_mouseUpEvent","_objectChangeEvent","TransformControls","camera","root","TransformControlsRoot","gizmo","TransformControlsGizmo","plane","TransformControlsPlane","scope","defineProperty","propName","defaultValue","propValue","value","worldPosition","worldPositionStart","worldQuaternion","worldQuaternionStart","cameraPosition","cameraQuaternion","pointStart","pointEnd","rotationAxis","rotationAngle","eye","getPointer","onPointerHover","pointer","intersect","intersectObjectWithRay","planeIntersect","axis","space","d","ROTATION_SPEED","_inPlaneRotation","translationSnap","rotationSnap","scaleSnap","size","xAxis","yAxis","zAxis","active","materialLib","raycaster","includeInvisible","allIntersections","_tempEuler","Euler","_alignVector","_zeroVector","_lookAtMatrix","Matrix4","_tempQuaternion2","_identityQuaternion","_dirVector","_tempMatrix","_unitX","_unitY","_unitZ","_v1","_v2","_v3","Object3D","controls","force","child","gizmoMaterial","MeshBasicMaterial","gizmoLineMaterial","LineBasicMaterial","matInvisible","matHelper","matRed","matGreen","matBlue","matRedTransparent","matGreenTransparent","matBlueTransparent","matWhiteTransparent","matYellowTransparent","matYellow","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","rotation","scale","tag","tempGeometry","quaternion","handles","handle","factor","a","PlaneGeometry","DoubleSide","state","orbitChanged","skipNextClick","onSelectedChange","onTransformChange","onSceneObjectsChange","sceneObjects","cameraTarget","animationId","clickHandler","resizeHandler","initEditor","container","sceneData","initRenderer","initScene","initCamera","loadSceneFromJSON","camData","initTransformControls","initOrbitControls","refreshSceneObjects","animate","onMouseClick","onResize","addDefaultLightAndCube","initGrid","renderer","THREE","grid","aspect","ambient","dirLight","TWEEN","_a","_b","width","height","selectObject","obj","deselectObject","mouse","clickables","intersects","addModel","model","selected","addObjectToTree","notifyChange","removeModel","removeObjectFromTree","removeModelById","uuid","idx","list","setSelectedObjectCallback","cb","setTransformChangeCallback","onSceneObjectsChangeCallback","getSceneObjects","getScene","getCamera","getRenderer","exportSceneToJSON","scene","exportScene","sceneJson","cameraJson","_c","json","data","loaded","disposeObject","mesh","mat","children","destroyEditor","_object_pattern","_material_library_pattern","_material_use_pattern","_map_use_pattern","_face_vertex_data_separator_pattern","_vA","_vB","_vC","_ab","_cb","_color","Color","ParserState","fromDeclaration","previousMaterial","libraries","previous","material","index","cloned","end","lastMultiMaterial","mi","declared","len","b","c","src","dst","ua","ub","uc","na","nb","nc","vLen","ia","ib","ic","nLen","uvLen","vertices","vi","l","uvs","uvi","OBJLoader","Loader","manager","url","onLoad","onProgress","onError","loader","FileLoader","text","e","materials","lines","result","line","lineFirstChar","SRGBColorSpace","vertexData","faceVertices","j","jl","vertex","vertexParts","v1","v2","v3","lineParts","lineVertices","lineUVs","li","llen","parts","pointData","Group","isLine","isPoints","hasVertexColors","buffergeometry","createdMaterials","miLen","sourceMaterial","materialHash","materialLine","Material","PointsMaterial","materialPoints","MeshPhongMaterial","LineSegments","Points","points","toTrianglesDrawMode","drawMode","TrianglesDrawMode","TriangleFanDrawMode","TriangleStripDrawMode","indices","numberOfTriangles","newIndices","newGeometry","clone","source","sourceLookup","cloneLookup","parallelTraverse","sourceNode","clonedNode","node","clonedMesh","sourceMesh","sourceBones","bone","callback","GLTFLoader","parser","GLTFMaterialsClearcoatExtension","GLTFMaterialsDispersionExtension","GLTFTextureBasisUExtension","GLTFTextureWebPExtension","GLTFTextureAVIFExtension","GLTFMaterialsSheenExtension","GLTFMaterialsTransmissionExtension","GLTFMaterialsVolumeExtension","GLTFMaterialsIorExtension","GLTFMaterialsEmissiveStrengthExtension","GLTFMaterialsSpecularExtension","GLTFMaterialsIridescenceExtension","GLTFMaterialsAnisotropyExtension","GLTFMaterialsBumpExtension","GLTFLightsExtension","GLTFMeshoptCompression","EXTENSIONS","GLTFMeshGpuInstancing","resourcePath","relativeUrl","LoaderUtils","_onError","gltf","dracoLoader","ktx2Loader","meshoptDecoder","path","extensions","plugins","textDecoder","BINARY_EXTENSION_HEADER_MAGIC","GLTFBinaryExtension","error","GLTFParser","plugin","extensionName","extensionsRequired","GLTFMaterialsUnlitExtension","GLTFDracoMeshCompressionExtension","GLTFTextureTransformExtension","GLTFMeshQuantizationExtension","resolve","reject","GLTFRegistry","objects","key","getMaterialExtension","materialIndex","materialDef","nodeDefs","nodeIndex","nodeLength","nodeDef","lightIndex","cacheKey","dependency","lightDef","lightNode","color","LinearSRGBColorSpace","range","DirectionalLight","PointLight","SpotLight","assignExtrasToUserData","self","light","materialParams","pending","metallicRoughness","array","extension","MeshPhysicalMaterial","colorFactor","colorArray","textureIndex","textureDef","handler","bufferView","extensionDef","buffer","decoder","res","byteOffset","byteLength","count","stride","meshDef","primitive","WEBGL_CONSTANTS","attributesDef","attributes","accessor","results","nodeObject","meshes","instancedMeshes","m","p","q","s","instancedMesh","InstancedMesh","attributeName","attr","InstancedBufferAttribute","BINARY_EXTENSION_HEADER_LENGTH","BINARY_EXTENSION_CHUNK_TYPES","headerView","chunkContentsLength","chunkView","chunkIndex","chunkLength","chunkType","contentArray","bufferViewIndex","gltfAttributeMap","threeAttributeMap","attributeNormalizedMap","attributeTypeMap","threeAttributeName","ATTRIBUTES","accessorDef","componentType","WEBGL_COMPONENT_TYPES","attribute","normalized","texture","transform","GLTFCubicSplineInterpolant","Interpolant","parameterPositions","sampleValues","sampleSize","resultBuffer","values","valueSize","offset","i1","t0","t","t1","stride2","stride3","td","pp","ppp","offset1","offset0","s2","s3","s0","s1","p0","m0","p1","m1","_quaternion","GLTFCubicSplineQuaternionInterpolant","WEBGL_FILTERS","NearestFilter","LinearFilter","NearestMipmapNearestFilter","LinearMipmapNearestFilter","NearestMipmapLinearFilter","LinearMipmapLinearFilter","WEBGL_WRAPPINGS","ClampToEdgeWrapping","MirroredRepeatWrapping","RepeatWrapping","WEBGL_TYPE_SIZES","PATH_PROPERTIES","INTERPOLATION","InterpolateLinear","InterpolateDiscrete","ALPHA_MODES","createDefaultMaterial","cache","MeshStandardMaterial","FrontSide","addUnknownExtensionsToUserData","knownExtensions","objectDef","gltfDef","addMorphTargets","targets","hasMorphPosition","hasMorphNormal","hasMorphColor","il","target","pendingPositionAccessors","pendingNormalAccessors","pendingColorAccessors","pendingAccessor","accessors","morphPositions","morphNormals","morphColors","updateMorphTargets","targetNames","createPrimitiveKey","primitiveDef","geometryKey","dracoExtension","createAttributesKey","attributesKey","keys","getNormalizedComponentScale","constructor","getImageURIMimeType","uri","_identityMatrix","options","isSafari","safariVersion","isFirefox","firefoxVersion","userAgent","safariMatch","TextureLoader","ImageBitmapLoader","ext","dependencies","skinDefs","meshDefs","skinIndex","skinLength","joints","ref","updateMappings","original","mappings","func","defs","def","bufferIndex","bufferDef","bufferViewDef","accessorIndex","itemSize","TypedArray","BufferAttribute","pendingBufferViews","bufferViews","elementBytes","itemBytes","byteStride","bufferAttribute","ibSlice","ibCacheKey","InterleavedBuffer","InterleavedBufferAttribute","itemSizeIndices","TypedArrayIndices","byteOffsetIndices","byteOffsetValues","sparseIndices","sparseValues","sourceIndex","sourceDef","promise","sampler","URL","sourceURI","isObjectURL","blob","imageBitmap","Texture","mapName","mapDef","colorSpace","gltfReference","useDerivativeTangents","useVertexColors","useFlatShading","pointsMaterial","lineMaterial","cachedMaterial","materialType","materialExtensions","kmuExtension","alphaMode","emissiveFactor","originalName","sanitizedName","PropertyBinding","primitives","createDracoPrimitive","addPrimitiveAttributes","cached","geometryPromise","meshIndex","geometries","SkinnedMesh","LineLoop","group","cameraIndex","cameraDef","params","PerspectiveCamera","OrthographicCamera","skinDef","inverseBindMatrices","jointNodes","bones","boneInverses","jointNode","Skeleton","animationIndex","animationDef","animationName","pendingNodes","pendingInputAccessors","pendingOutputAccessors","pendingSamplers","pendingTargets","channel","input","output","nodes","inputAccessors","outputAccessors","samplers","tracks","inputAccessor","outputAccessor","createdTracks","k","animation","AnimationClip","o","nodePending","childPending","childrenDef","skeletonPending","skeleton","pivot","pivotChild","nodeName","meshPromise","Bone","matrix","mapping","sceneIndex","sceneDef","nodeIds","reduceAssociations","reducedAssociations","targetName","collectMorphTargets","TypedKeyframeTrack","NumberKeyframeTrack","QuaternionKeyframeTrack","VectorKeyframeTrack","interpolation","outputArray","track","scaled","interpolantType","computeBounds","box","Box3","boxScale","maxDisplacement","vector","sphere","Sphere","assignAttributeAccessor","gltfAttributeName","ColorManagement","addBox","geo","addSphere","importModelFromFile","file","center","err","addModelByType","props","__props","emit","__emit","nodeRef","expandedSet","toggleExpand","inject","isExpanded","computed","hasChildren","childNodes","isSelected","watchEffect","handleSelect","handleDelete","getIcon","getDisplayName","_createElementBlock","_createElementVNode","_normalizeClass","_cache","_withModifiers","$event","_unref","_openBlock","_hoisted_1","_hoisted_2","_toDisplayString","_hoisted_3","_hoisted_4","_Fragment","_renderList","_createBlock","_component_TreeItem","useTreeExpand","selectedObject","newSet","expandPath","current","watch","emitChange","activeTab","treeVersion","selectedObjectRef","toRef","provide","handleTreeDelete","materialProps","reactive","hasStandardMaterial","readMaterialFromObject","stdMat","applyMaterialToObject","applied","onMaterialChange","newObj","read","TreeItem","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_18","_hoisted_19","_hoisted_20","_hoisted_21","showFileMenu","showEditMenu","showViewMenu","showHelpMenu","showAddMenu","showOpenSub","showOpenGrid","fileInput","triggerImport","onFileSelected","handleNew","handleSave","handleExport","handleUndo","handleRedo","handleDuplicate","handleResetCamera","handleToggleGrid","handleHelp","handleAbout","handleOpenProject","handleOpenModel","handleOpenScene","_withDirectives","selectedModel","syncTransformFromObject","applyTransformToObject","handlePropertyChange","handleAddModel","handleImportModel","treeData","shallowRef","initTree","handleTreeSelect","containerRef","onMounted","onBeforeUnmount","TopBar","PropertyPanel","BottomBar"],"mappings":"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","x_google_ignoreList":[0,1,3,4,5,6]}
1
+ {"version":3,"file":"three-editor.es.js","sources":["../node_modules/three/examples/jsm/controls/OrbitControls.js","../node_modules/three/examples/jsm/controls/TransformControls.js","../src/three/index.ts","../node_modules/three/examples/jsm/loaders/OBJLoader.js","../node_modules/three/examples/jsm/utils/BufferGeometryUtils.js","../node_modules/three/examples/jsm/utils/SkeletonUtils.js","../node_modules/three/examples/jsm/loaders/GLTFLoader.js","../node_modules/three/examples/jsm/loaders/DRACOLoader.js","../src/assets/water.webp","../src/three/addHandle.ts","../src/components/TreeItem.vue","../src/components/PropertyPanel/TransformTab.vue","../src/components/PropertyPanel/UserDataTab.vue","../src/composables/useTreeExpand.ts","../src/components/PropertyPanel/index.vue","../src/components/TopBar.vue","../src/components/BottomBar.vue","../src/components/DrawingBoard.vue"],"sourcesContent":["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/**\n * Fires when the camera has been transformed by the controls.\n *\n * @event OrbitControls#change\n * @type {Object}\n */\nconst _changeEvent = { type: 'change' };\n\n/**\n * Fires when an interaction was initiated.\n *\n * @event OrbitControls#start\n * @type {Object}\n */\nconst _startEvent = { type: 'start' };\n\n/**\n * Fires when an interaction has finished.\n *\n * @event OrbitControls#end\n * @type {Object}\n */\nconst _endEvent = { type: 'end' };\n\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\n\n/**\n * Orbit controls allow the camera to orbit around a target.\n *\n * OrbitControls performs orbiting, dollying (zooming), and panning. Unlike {@link TrackballControls},\n * 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 *\n * ```js\n * const controls = new OrbitControls( camera, renderer.domElement );\n *\n * // controls.update() must be called after any manual changes to the camera's transform\n * camera.position.set( 0, 20, 100 );\n * controls.update();\n *\n * function animate() {\n *\n * \t// required if controls.enableDamping or controls.autoRotate are set to true\n * \tcontrols.update();\n *\n * \trenderer.render( scene, camera );\n *\n * }\n * ```\n *\n * @augments Controls\n * @three_import import { OrbitControls } from 'three/addons/controls/OrbitControls.js';\n */\nclass OrbitControls extends Controls {\n\n\t/**\n\t * Constructs a new controls instance.\n\t *\n\t * @param {Object3D} object - The object that is managed by the controls.\n\t * @param {?HTMLElement} domElement - The HTML element used for event listeners.\n\t */\n\tconstructor( object, domElement = null ) {\n\n\t\tsuper( object, domElement );\n\n\t\tthis.state = _STATE.NONE;\n\n\t\t/**\n\t\t * The focus point of the controls, the `object` orbits around this.\n\t\t * It can be updated manually at any point to change the focus of the controls.\n\t\t *\n\t\t * @type {Vector3}\n\t\t */\n\t\tthis.target = new Vector3();\n\n\t\t/**\n\t\t * The focus point of the `minTargetRadius` and `maxTargetRadius` limits.\n\t\t * It can be updated manually at any point to change the center of interest\n\t\t * for the `target`.\n\t\t *\n\t\t * @type {Vector3}\n\t\t */\n\t\tthis.cursor = new Vector3();\n\n\t\t/**\n\t\t * How far you can dolly in (perspective camera only).\n\t\t *\n\t\t * @type {number}\n\t\t * @default 0\n\t\t */\n\t\tthis.minDistance = 0;\n\n\t\t/**\n\t\t * How far you can dolly out (perspective camera only).\n\t\t *\n\t\t * @type {number}\n\t\t * @default Infinity\n\t\t */\n\t\tthis.maxDistance = Infinity;\n\n\t\t/**\n\t\t * How far you can zoom in (orthographic camera only).\n\t\t *\n\t\t * @type {number}\n\t\t * @default 0\n\t\t */\n\t\tthis.minZoom = 0;\n\n\t\t/**\n\t\t * How far you can zoom out (orthographic camera only).\n\t\t *\n\t\t * @type {number}\n\t\t * @default Infinity\n\t\t */\n\t\tthis.maxZoom = Infinity;\n\n\t\t/**\n\t\t * How close you can get the target to the 3D `cursor`.\n\t\t *\n\t\t * @type {number}\n\t\t * @default 0\n\t\t */\n\t\tthis.minTargetRadius = 0;\n\n\t\t/**\n\t\t * How far you can move the target from the 3D `cursor`.\n\t\t *\n\t\t * @type {number}\n\t\t * @default Infinity\n\t\t */\n\t\tthis.maxTargetRadius = Infinity;\n\n\t\t/**\n\t\t * How far you can orbit vertically, lower limit. Range is `[0, Math.PI]` radians.\n\t\t *\n\t\t * @type {number}\n\t\t * @default 0\n\t\t */\n\t\tthis.minPolarAngle = 0;\n\n\t\t/**\n\t\t * How far you can orbit vertically, upper limit. Range is `[0, Math.PI]` radians.\n\t\t *\n\t\t * @type {number}\n\t\t * @default Math.PI\n\t\t */\n\t\tthis.maxPolarAngle = Math.PI;\n\n\t\t/**\n\t\t * How far you can orbit horizontally, lower limit. If set, the interval `[ min, max ]`\n\t\t * must be a sub-interval of `[ - 2 PI, 2 PI ]`, with `( max - min < 2 PI )`.\n\t\t *\n\t\t * @type {number}\n\t\t * @default -Infinity\n\t\t */\n\t\tthis.minAzimuthAngle = - Infinity;\n\n\t\t/**\n\t\t * How far you can orbit horizontally, upper limit. If set, the interval `[ min, max ]`\n\t\t * must be a sub-interval of `[ - 2 PI, 2 PI ]`, with `( max - min < 2 PI )`.\n\t\t *\n\t\t * @type {number}\n\t\t * @default -Infinity\n\t\t */\n\t\tthis.maxAzimuthAngle = Infinity;\n\n\t\t/**\n\t\t * Set to `true` to enable damping (inertia), which can be used to give a sense of weight\n\t\t * to the controls. Note that if this is enabled, you must call `update()` in your animation\n\t\t * loop.\n\t\t *\n\t\t * @type {boolean}\n\t\t * @default false\n\t\t */\n\t\tthis.enableDamping = false;\n\n\t\t/**\n\t\t * The damping inertia used if `enableDamping` is set to `true`.\n\t\t *\n\t\t * Note that for this to work, you must call `update()` in your animation loop.\n\t\t *\n\t\t * @type {number}\n\t\t * @default 0.05\n\t\t */\n\t\tthis.dampingFactor = 0.05;\n\n\t\t/**\n\t\t * Enable or disable zooming (dollying) of the camera.\n\t\t *\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t */\n\t\tthis.enableZoom = true;\n\n\t\t/**\n\t\t * Speed of zooming / dollying.\n\t\t *\n\t\t * @type {number}\n\t\t * @default 1\n\t\t */\n\t\tthis.zoomSpeed = 1.0;\n\n\t\t/**\n\t\t * Enable or disable horizontal and vertical rotation of the camera.\n\t\t *\n\t\t * Note that it is possible to disable a single axis by setting the min and max of the\n\t\t * `minPolarAngle` or `minAzimuthAngle` to the same value, which will cause the vertical\n\t\t * or horizontal rotation to be fixed at that value.\n\t\t *\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t */\n\t\tthis.enableRotate = true;\n\n\t\t/**\n\t\t * Speed of rotation.\n\t\t *\n\t\t * @type {number}\n\t\t * @default 1\n\t\t */\n\t\tthis.rotateSpeed = 1.0;\n\n\t\t/**\n\t\t * How fast to rotate the camera when the keyboard is used.\n\t\t *\n\t\t * @type {number}\n\t\t * @default 1\n\t\t */\n\t\tthis.keyRotateSpeed = 1.0;\n\n\t\t/**\n\t\t * Enable or disable camera panning.\n\t\t *\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t */\n\t\tthis.enablePan = true;\n\n\t\t/**\n\t\t * Speed of panning.\n\t\t *\n\t\t * @type {number}\n\t\t * @default 1\n\t\t */\n\t\tthis.panSpeed = 1.0;\n\n\t\t/**\n\t\t * Defines how the camera's position is translated when panning. If `true`, the camera pans\n\t\t * in screen space. Otherwise, the camera pans in the plane orthogonal to the camera's up\n\t\t * direction.\n\t\t *\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t */\n\t\tthis.screenSpacePanning = true;\n\n\t\t/**\n\t\t * How fast to pan the camera when the keyboard is used in\n\t\t * pixels per keypress.\n\t\t *\n\t\t * @type {number}\n\t\t * @default 7\n\t\t */\n\t\tthis.keyPanSpeed = 7.0;\n\n\t\t/**\n\t\t * Setting this property to `true` allows to zoom to the cursor's position.\n\t\t *\n\t\t * @type {boolean}\n\t\t * @default false\n\t\t */\n\t\tthis.zoomToCursor = false;\n\n\t\t/**\n\t\t * Set to true to automatically rotate around the target\n\t\t *\n\t\t * Note that if this is enabled, you must call `update()` in your animation loop.\n\t\t * If you want the auto-rotate speed to be independent of the frame rate (the refresh\n\t\t * rate of the display), you must pass the time `deltaTime`, in seconds, to `update()`.\n\t\t *\n\t\t * @type {boolean}\n\t\t * @default false\n\t\t */\n\t\tthis.autoRotate = false;\n\n\t\t/**\n\t\t * How fast to rotate around the target if `autoRotate` is `true`. The default equates to 30 seconds\n\t\t * per orbit at 60fps.\n\t\t *\n\t\t * Note that if `autoRotate` is enabled, you must call `update()` in your animation loop.\n\t\t *\n\t\t * @type {number}\n\t\t * @default 2\n\t\t */\n\t\tthis.autoRotateSpeed = 2.0;\n\n\t\t/**\n\t\t * This object contains references to the keycodes for controlling camera panning.\n\t\t *\n\t\t * ```js\n\t\t * controls.keys = {\n\t\t * \tLEFT: 'ArrowLeft', //left arrow\n\t\t * \tUP: 'ArrowUp', // up arrow\n\t\t * \tRIGHT: 'ArrowRight', // right arrow\n\t\t * \tBOTTOM: 'ArrowDown' // down arrow\n\t\t * }\n\t\t * ```\n\t\t * @type {Object}\n\t\t */\n\t\tthis.keys = { LEFT: 'ArrowLeft', UP: 'ArrowUp', RIGHT: 'ArrowRight', BOTTOM: 'ArrowDown' };\n\n\t\t/**\n\t\t * This object contains references to the mouse actions used by the controls.\n\t\t *\n\t\t * ```js\n\t\t * controls.mouseButtons = {\n\t\t * \tLEFT: THREE.MOUSE.ROTATE,\n\t\t * \tMIDDLE: THREE.MOUSE.DOLLY,\n\t\t * \tRIGHT: THREE.MOUSE.PAN\n\t\t * }\n\t\t * ```\n\t\t * @type {Object}\n\t\t */\n\t\tthis.mouseButtons = { LEFT: MOUSE.ROTATE, MIDDLE: MOUSE.DOLLY, RIGHT: MOUSE.PAN };\n\n\t\t/**\n\t\t * This object contains references to the touch actions used by the controls.\n\t\t *\n\t\t * ```js\n\t\t * controls.mouseButtons = {\n\t\t * \tONE: THREE.TOUCH.ROTATE,\n\t\t * \tTWO: THREE.TOUCH.DOLLY_PAN\n\t\t * }\n\t\t * ```\n\t\t * @type {Object}\n\t\t */\n\t\tthis.touches = { ONE: TOUCH.ROTATE, TWO: TOUCH.DOLLY_PAN };\n\n\t\t/**\n\t\t * Used internally by `saveState()` and `reset()`.\n\t\t *\n\t\t * @type {Vector3}\n\t\t */\n\t\tthis.target0 = this.target.clone();\n\n\t\t/**\n\t\t * Used internally by `saveState()` and `reset()`.\n\t\t *\n\t\t * @type {Vector3}\n\t\t */\n\t\tthis.position0 = this.object.position.clone();\n\n\t\t/**\n\t\t * Used internally by `saveState()` and `reset()`.\n\t\t *\n\t\t * @type {number}\n\t\t */\n\t\tthis.zoom0 = this.object.zoom;\n\n\t\tthis._cursorStyle = 'auto';\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( this.domElement );\n\n\t\t}\n\n\t\tthis.update();\n\n\t}\n\n\t/**\n\t * Defines the visual representation of the cursor.\n\t *\n\t * @type {('auto'|'grab')}\n\t * @default 'auto'\n\t */\n\tset cursorStyle( type ) {\n\n\t\tthis._cursorStyle = type;\n\n\t\tif ( type === 'grab' ) {\n\n\t\t\tthis.domElement.style.cursor = 'grab';\n\n\t\t} else {\n\n\t\t\tthis.domElement.style.cursor = 'auto';\n\n\t\t}\n\n\t}\n\n\tget cursorStyle() {\n\n\t\treturn this._cursorStyle;\n\n\t}\n\n\tconnect( element ) {\n\n\t\tsuper.connect( element );\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.ownerDocument.removeEventListener( 'pointermove', this._onPointerMove );\n\t\tthis.domElement.ownerDocument.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 = ''; // Restore touch scroll\n\n\t}\n\n\tdispose() {\n\n\t\tthis.disconnect();\n\n\t}\n\n\t/**\n\t * Get the current vertical rotation, in radians.\n\t *\n\t * @return {number} The current vertical rotation, in radians.\n\t */\n\tgetPolarAngle() {\n\n\t\treturn this._spherical.phi;\n\n\t}\n\n\t/**\n\t * Get the current horizontal rotation, in radians.\n\t *\n\t * @return {number} The current horizontal rotation, in radians.\n\t */\n\tgetAzimuthalAngle() {\n\n\t\treturn this._spherical.theta;\n\n\t}\n\n\t/**\n\t * Returns the distance from the camera to the target.\n\t *\n\t * @return {number} The distance from the camera to the target.\n\t */\n\tgetDistance() {\n\n\t\treturn this.object.position.distanceTo( this.target );\n\n\t}\n\n\t/**\n\t * Adds key event listeners to the given DOM element.\n\t * `window` is a recommended argument for using this method.\n\t *\n\t * @param {HTMLElement} domElement - The DOM element\n\t */\n\tlistenToKeyEvents( domElement ) {\n\n\t\tdomElement.addEventListener( 'keydown', this._onKeyDown );\n\t\tthis._domElementKeyEvents = domElement;\n\n\t}\n\n\t/**\n\t * Removes the key event listener previously defined with `listenToKeyEvents()`.\n\t */\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\t/**\n\t * Save the current state of the controls. This can later be recovered with `reset()`.\n\t */\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\t/**\n\t * Reset the controls to their state from either the last time the `saveState()`\n\t * was called, or the initial state.\n\t */\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\t/**\n\t * Programmatically pan the camera.\n\t *\n\t * @param {number} deltaX - The horizontal pan amount in pixels.\n\t * @param {number} deltaY - The vertical pan amount in pixels.\n\t */\n\tpan( deltaX, deltaY ) {\n\n\t\tthis._pan( deltaX, deltaY );\n\t\tthis.update();\n\n\t}\n\n\t/**\n\t * Programmatically dolly in (zoom in for perspective camera).\n\t *\n\t * @param {number} dollyScale - The dolly scale factor.\n\t */\n\tdollyIn( dollyScale ) {\n\n\t\tthis._dollyIn( dollyScale );\n\t\tthis.update();\n\n\t}\n\n\t/**\n\t * Programmatically dolly out (zoom out for perspective camera).\n\t *\n\t * @param {number} dollyScale - The dolly scale factor.\n\t */\n\tdollyOut( dollyScale ) {\n\n\t\tthis._dollyOut( dollyScale );\n\t\tthis.update();\n\n\t}\n\n\t/**\n\t * Programmatically rotate the camera left (around the vertical axis).\n\t *\n\t * @param {number} angle - The rotation angle in radians.\n\t */\n\trotateLeft( angle ) {\n\n\t\tthis._rotateLeft( angle );\n\t\tthis.update();\n\n\t}\n\n\t/**\n\t * Programmatically rotate the camera up (around the horizontal axis).\n\t *\n\t * @param {number} angle - The rotation angle in radians.\n\t */\n\trotateUp( angle ) {\n\n\t\tthis._rotateUp( angle );\n\t\tthis.update();\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\tif ( this.enableRotate ) {\n\n\t\t\t\t\t\tthis._rotateUp( _twoPI * this.keyRotateSpeed / this.domElement.clientHeight );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( this.enablePan ) {\n\n\t\t\t\t\t\tthis._pan( 0, this.keyPanSpeed );\n\n\t\t\t\t\t}\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\tif ( this.enableRotate ) {\n\n\t\t\t\t\t\tthis._rotateUp( - _twoPI * this.keyRotateSpeed / this.domElement.clientHeight );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( this.enablePan ) {\n\n\t\t\t\t\t\tthis._pan( 0, - this.keyPanSpeed );\n\n\t\t\t\t\t}\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\tif ( this.enableRotate ) {\n\n\t\t\t\t\t\tthis._rotateLeft( _twoPI * this.keyRotateSpeed / this.domElement.clientHeight );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( this.enablePan ) {\n\n\t\t\t\t\t\tthis._pan( this.keyPanSpeed, 0 );\n\n\t\t\t\t\t}\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\tif ( this.enableRotate ) {\n\n\t\t\t\t\t\tthis._rotateLeft( - _twoPI * this.keyRotateSpeed / this.domElement.clientHeight );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( this.enablePan ) {\n\n\t\t\t\t\t\tthis._pan( - this.keyPanSpeed, 0 );\n\n\t\t\t\t\t}\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.ownerDocument.addEventListener( 'pointermove', this._onPointerMove );\n\t\tthis.domElement.ownerDocument.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\tif ( this._cursorStyle === 'grab' ) {\n\n\t\tthis.domElement.style.cursor = 'grabbing';\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.ownerDocument.removeEventListener( 'pointermove', this._onPointerMove );\n\t\t\tthis.domElement.ownerDocument.removeEventListener( 'pointerup', this._onPointerUp );\n\n\t\t\tthis.dispatchEvent( _endEvent );\n\n\t\t\tthis.state = _STATE.NONE;\n\n\t\t\tif ( this._cursorStyle === 'grab' ) {\n\n\t\t\t\tthis.domElement.style.cursor = 'grab';\n\n\t\t\t}\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 ) 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 {\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\n/**\n * Fires if any type of change (object or property change) is performed. Property changes\n * are separate events you can add event listeners to. The event type is \"propertyname-changed\".\n *\n * @event TransformControls#change\n * @type {Object}\n */\nconst _changeEvent = { type: 'change' };\n\n/**\n * Fires if a pointer (mouse/touch) becomes active.\n *\n * @event TransformControls#mouseDown\n * @type {Object}\n */\nconst _mouseDownEvent = { type: 'mouseDown', mode: null };\n\n/**\n * Fires if a pointer (mouse/touch) is no longer active.\n *\n * @event TransformControls#mouseUp\n * @type {Object}\n */\nconst _mouseUpEvent = { type: 'mouseUp', mode: null };\n\n/**\n * Fires if the controlled 3D object is changed.\n *\n * @event TransformControls#objectChange\n * @type {Object}\n */\nconst _objectChangeEvent = { type: 'objectChange' };\n\n/**\n * This class can be used to transform objects in 3D space by adapting a similar interaction model\n * of DCC tools like Blender. Unlike other controls, it is not intended to transform the scene's camera.\n *\n * `TransformControls` expects that its attached 3D object is part of the scene graph.\n *\n * @augments Controls\n * @three_import import { TransformControls } from 'three/addons/controls/TransformControls.js';\n */\nclass TransformControls extends Controls {\n\n\t/**\n\t * Constructs a new controls instance.\n\t *\n\t * @param {Camera} camera - The camera of the rendered scene.\n\t * @param {?HTMLElement} domElement - The HTML element used for event listeners.\n\t */\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\t/**\n\t\t * The camera of the rendered scene.\n\t\t *\n\t\t * @name TransformControls#camera\n\t\t * @type {Camera}\n\t\t */\n\t\tdefineProperty( 'camera', camera );\n\t\tdefineProperty( 'object', undefined );\n\t\tdefineProperty( 'enabled', true );\n\n\t\t/**\n\t\t * The current transformation axis.\n\t\t *\n\t\t * @name TransformControls#axis\n\t\t * @type {string}\n\t\t */\n\t\tdefineProperty( 'axis', null );\n\n\t\t/**\n\t\t * The current transformation axis.\n\t\t *\n\t\t * @name TransformControls#mode\n\t\t * @type {('translate'|'rotate'|'scale')}\n\t\t * @default 'translate'\n\t\t */\n\t\tdefineProperty( 'mode', 'translate' );\n\n\t\t/**\n\t\t * By default, 3D objects are continuously translated. If you set this property to a numeric\n\t\t * value (world units), you can define in which steps the 3D object should be translated.\n\t\t *\n\t\t * @name TransformControls#translationSnap\n\t\t * @type {?number}\n\t\t * @default null\n\t\t */\n\t\tdefineProperty( 'translationSnap', null );\n\n\t\t/**\n\t\t * By default, 3D objects are continuously rotated. If you set this property to a numeric\n\t\t * value (radians), you can define in which steps the 3D object should be rotated.\n\t\t *\n\t\t * @name TransformControls#rotationSnap\n\t\t * @type {?number}\n\t\t * @default null\n\t\t */\n\t\tdefineProperty( 'rotationSnap', null );\n\n\t\t/**\n\t\t * By default, 3D objects are continuously scaled. If you set this property to a numeric\n\t\t * value, you can define in which steps the 3D object should be scaled.\n\t\t *\n\t\t * @name TransformControls#scaleSnap\n\t\t * @type {?number}\n\t\t * @default null\n\t\t */\n\t\tdefineProperty( 'scaleSnap', null );\n\n\t\t/**\n\t\t * Defines in which coordinate space transformations should be performed.\n\t\t *\n\t\t * @name TransformControls#space\n\t\t * @type {('world'|'local')}\n\t\t * @default 'world'\n\t\t */\n\t\tdefineProperty( 'space', 'world' );\n\n\t\t/**\n\t\t * The size of the helper UI (axes/planes).\n\t\t *\n\t\t * @name TransformControls#size\n\t\t * @type {number}\n\t\t * @default 1\n\t\t */\n\t\tdefineProperty( 'size', 1 );\n\n\t\t/**\n\t\t * Whether dragging is currently performed or not.\n\t\t *\n\t\t * @name TransformControls#dragging\n\t\t * @type {boolean}\n\t\t * @readonly\n\t\t * @default false\n\t\t */\n\t\tdefineProperty( 'dragging', false );\n\n\t\t/**\n\t\t * Whether the x-axis helper should be visible or not.\n\t\t *\n\t\t * @name TransformControls#showX\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t */\n\t\tdefineProperty( 'showX', true );\n\n\t\t/**\n\t\t * Whether the y-axis helper should be visible or not.\n\t\t *\n\t\t * @name TransformControls#showY\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t */\n\t\tdefineProperty( 'showY', true );\n\n\t\t/**\n\t\t * Whether the z-axis helper should be visible or not.\n\t\t *\n\t\t * @name TransformControls#showZ\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t */\n\t\tdefineProperty( 'showZ', true );\n\n\t\t/**\n\t\t * Whether the xy-plane helper should be visible or not.\n\t\t *\n\t\t * @name TransformControls#showXY\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t */\n\t\tdefineProperty( 'showXY', true );\n\n\t\t/**\n\t\t * Whether the yz-plane helper should be visible or not.\n\t\t *\n\t\t * @name TransformControls#showYZ\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t */\n\t\tdefineProperty( 'showYZ', true );\n\n\t\t/**\n\t\t * Whether the xz-axis helper should be visible or not.\n\t\t *\n\t\t * @name TransformControls#showXZ\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t */\n\t\tdefineProperty( 'showXZ', true );\n\n\t\t/**\n\t\t * The minimum allowed X position during translation.\n\t\t *\n\t\t * @name TransformControls#minX\n\t\t * @type {number}\n\t\t * @default -Infinity\n\t\t */\n\t\tdefineProperty( 'minX', - Infinity );\n\n\t\t/**\n\t\t * The maximum allowed X position during translation.\n\t\t *\n\t\t * @name TransformControls#maxX\n\t\t * @type {number}\n\t\t * @default Infinity\n\t\t */\n\t\tdefineProperty( 'maxX', Infinity );\n\n\t\t/**\n\t\t * The minimum allowed y position during translation.\n\t\t *\n\t\t * @name TransformControls#minY\n\t\t * @type {number}\n\t\t * @default -Infinity\n\t\t */\n\t\tdefineProperty( 'minY', - Infinity );\n\n\t\t/**\n\t\t * The maximum allowed Y position during translation.\n\t\t *\n\t\t * @name TransformControls#maxY\n\t\t * @type {number}\n\t\t * @default Infinity\n\t\t */\n\t\tdefineProperty( 'maxY', Infinity );\n\n\t\t/**\n\t\t * The minimum allowed z position during translation.\n\t\t *\n\t\t * @name TransformControls#minZ\n\t\t * @type {number}\n\t\t * @default -Infinity\n\t\t */\n\t\tdefineProperty( 'minZ', - Infinity );\n\n\t\t/**\n\t\t * The maximum allowed Z position during translation.\n\t\t *\n\t\t * @name TransformControls#maxZ\n\t\t * @type {number}\n\t\t * @default Infinity\n\t\t */\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( domElement );\n\n\t\t}\n\n\t}\n\n\tconnect( element ) {\n\n\t\tsuper.connect( element );\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 = ''; // Restore touch scroll\n\n\t}\n\n\t/**\n\t * Returns the visual representation of the controls. Add the helper to your scene to\n\t * visually transform the attached 3D object.\n\t *\n\t * @return {TransformControlsRoot} The helper.\n\t */\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/**\n\t * Sets the 3D object that should be transformed and ensures the controls UI is visible.\n\t *\n\t * @param {Object3D} object - The 3D object that should be transformed.\n\t * @return {TransformControls} A reference to this controls.\n\t */\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/**\n\t * Removes the current 3D object from the controls and makes the helper UI invisible.\n\t *\n\t * @return {TransformControls} A reference to this controls.\n\t */\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\t/**\n\t * Resets the object's position, rotation and scale to when the current transform began.\n\t */\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\t/**\n\t * Returns the raycaster that is used for user interaction. This object is shared between all\n\t * instances of `TransformControls`.\n\t *\n\t * @returns {Raycaster} The internal raycaster.\n\t */\n\tgetRaycaster() {\n\n\t\treturn _raycaster;\n\n\t}\n\n\t/**\n\t * Returns the transformation mode.\n\t *\n\t * @returns {'translate'|'rotate'|'scale'} The transformation mode.\n\t */\n\tgetMode() {\n\n\t\treturn this.mode;\n\n\t}\n\n\t/**\n\t * Sets the given transformation mode.\n\t *\n\t * @param {'translate'|'rotate'|'scale'} mode - The transformation mode to set.\n\t */\n\tsetMode( mode ) {\n\n\t\tthis.mode = mode;\n\n\t}\n\n\t/**\n\t * Sets the translation snap.\n\t *\n\t * @param {?number} translationSnap - The translation snap to set.\n\t */\n\tsetTranslationSnap( translationSnap ) {\n\n\t\tthis.translationSnap = translationSnap;\n\n\t}\n\n\t/**\n\t * Sets the rotation snap.\n\t *\n\t * @param {?number} rotationSnap - The rotation snap to set.\n\t */\n\tsetRotationSnap( rotationSnap ) {\n\n\t\tthis.rotationSnap = rotationSnap;\n\n\t}\n\n\t/**\n\t * Sets the scale snap.\n\t *\n\t * @param {?number} scaleSnap - The scale snap to set.\n\t */\n\tsetScaleSnap( scaleSnap ) {\n\n\t\tthis.scaleSnap = scaleSnap;\n\n\t}\n\n\t/**\n\t * Sets the size of the helper UI.\n\t *\n\t * @param {number} size - The size to set.\n\t */\n\tsetSize( size ) {\n\n\t\tthis.size = size;\n\n\t}\n\n\t/**\n\t * Sets the coordinate space in which transformations are applied.\n\t *\n\t * @param {'world'|'local'} space - The space to set.\n\t */\n\tsetSpace( space ) {\n\n\t\tthis.space = space;\n\n\t}\n\n\t/**\n\t * Sets the colors of the control's gizmo.\n\t *\n\t * @param {number|Color|string} xAxis - The x-axis color.\n\t * @param {number|Color|string} yAxis - The y-axis color.\n\t * @param {number|Color|string} zAxis - The z-axis color.\n\t * @param {number|Color|string} active - The color for active elements.\n\t */\n\tsetColors( xAxis, yAxis, zAxis, active ) {\n\n\t\tconst materialLib = this._gizmo.materialLib;\n\n\t\tmaterialLib.xAxis.color.set( xAxis );\n\t\tmaterialLib.yAxis.color.set( yAxis );\n\t\tmaterialLib.zAxis.color.set( zAxis );\n\t\tmaterialLib.active.color.set( active );\n\t\tmaterialLib.xAxisTransparent.color.set( xAxis );\n\t\tmaterialLib.yAxisTransparent.color.set( yAxis );\n\t\tmaterialLib.zAxisTransparent.color.set( zAxis );\n\t\tmaterialLib.activeTransparent.color.set( active );\n\n\t\t// update color caches\n\n\t\tif ( materialLib.xAxis._color ) materialLib.xAxis._color.set( xAxis );\n\t\tif ( materialLib.yAxis._color ) materialLib.yAxis._color.set( yAxis );\n\t\tif ( materialLib.zAxis._color ) materialLib.zAxis._color.set( zAxis );\n\t\tif ( materialLib.active._color ) materialLib.active._color.set( active );\n\t\tif ( materialLib.xAxisTransparent._color ) materialLib.xAxisTransparent._color.set( xAxis );\n\t\tif ( materialLib.yAxisTransparent._color ) materialLib.yAxisTransparent._color.set( yAxis );\n\t\tif ( materialLib.zAxisTransparent._color ) materialLib.zAxisTransparent._color.set( zAxis );\n\t\tif ( materialLib.activeTransparent._color ) materialLib.activeTransparent._color.set( active );\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// materials in the below property are configurable via setColors()\n\n\t\tthis.materialLib = {\n\t\t\txAxis: matRed,\n\t\t\tyAxis: matGreen,\n\t\t\tzAxis: matBlue,\n\t\t\tactive: matYellow,\n\t\t\txAxisTransparent: matRedTransparent,\n\t\t\tyAxisTransparent: matGreenTransparent,\n\t\t\tzAxisTransparent: matBlueTransparent,\n\t\t\tactiveTransparent: matYellowTransparent\n\t\t};\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 ), [ 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 ), [ 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};\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 ), [ - 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 ), [ 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 ), [ 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 ), [ - 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 ) ],\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 ), [ - 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 ), [ 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 ), [ 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// Hide disabled plane helpers\n\t\t\thandle.visible = handle.visible && ( handle.name.indexOf( 'XY' ) === - 1 || this.showXY );\n\t\t\thandle.visible = handle.visible && ( handle.name.indexOf( 'YZ' ) === - 1 || this.showYZ );\n\t\t\thandle.visible = handle.visible && ( handle.name.indexOf( 'XZ' ) === - 1 || this.showXZ );\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.copy( this.materialLib.active.color );\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.copy( this.materialLib.active.color );\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","/**\r\n * 3D 模型编辑器核心模块\r\n * 提供场景管理、物体增删、选中/变换控制、树形数据同步等功能\r\n * 采用单例模式管理所有 Three.js 相关状态\r\n */\r\n\r\nimport * as THREE from \"three\";\r\nimport TWEEN from \"@tweenjs/tween.js\";\r\nimport { OrbitControls } from \"three/examples/jsm/controls/OrbitControls.js\";\r\nimport { TransformControls } from \"three/examples/jsm/controls/TransformControls.js\";\r\nimport type { Object3D } from \"three\";\r\n// import bgImage from \"../assets/R-C.jpg\";\r\nimport type {\r\n SelectedChangeCallback,\r\n TransformChangeCallback,\r\n SceneObjectsChangeCallback,\r\n} from \"./types\";\r\n\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n//#region 编辑器状态(单例)\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n\r\n/** 编辑器核心状态容器,所有 Three.js 核心对象均存放于此 */\r\nconst state = {\r\n /** 场景模式 */\r\n mode: \"\",\r\n /** 控制器模式 */\r\n transformControlsMode: \"translate\" as \"translate\" | \"rotate\" | \"scale\",\r\n /** Three.js 场景 */\r\n scene: null as THREE.Scene | null,\r\n /** 透视相机 */\r\n camera: null as THREE.PerspectiveCamera | null,\r\n /** WebGL 渲染器 */\r\n renderer: null as THREE.WebGLRenderer | null,\r\n /** 轨道控制器(用于场景浏览) */\r\n orbitControls: null as OrbitControls | null,\r\n /** 变换控制器(用于平移/旋转/缩放物体) */\r\n transformControls: null as TransformControls | null,\r\n /** 编辑器挂载的 DOM 容器 */\r\n container: null as HTMLElement | null,\r\n /** 网格辅助对象(地板) */\r\n gridHelper: null as THREE.GridHelper | null,\r\n /** 当前选中的物体 */\r\n selectedObject: null as Object3D | null,\r\n};\r\n//#endregion\r\n\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n//#region 辅助标志\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n\r\n/** 轨道控制器是否发生了旋转/平移/缩放操作 */\r\nlet orbitChanged = false;\r\n/** 是否应该跳过下一次鼠标点击事件(用于防止拖拽后误触发选中) */\r\nlet skipNextClick = false;\r\n//#endregion\r\n\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n//#region 外部回调\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n\r\n/** 选中物体变化时的回调(由外部注册,用于同步 UI) */\r\nlet onSelectedChange: SelectedChangeCallback | null = null;\r\n/** 变换过程中(拖拽)的回调(由外部注册,用于实时更新属性面板) */\r\nlet onTransformChange: TransformChangeCallback | null = null;\r\n/** 场景物体列表变化时的回调(由外部注册,用于更新树形面板) */\r\nlet onSceneObjectsChange: SceneObjectsChangeCallback | null = null;\r\n//#endregion\r\n\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n//#region 树形数据(仅存储顶层可移动物体)\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n\r\n/** 场景中顶层可移动物体的列表(不包含子物体,子物体通过 parent 关系访问) */\r\nlet sceneObjects: Object3D[] = [];\r\n//#endregion\r\n\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n//#region 初始化场景数据\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n\r\n// 如果有场景数据,恢复相机参数并保存 target\r\nlet cameraTarget: number[] | undefined;\r\n//#endregion\r\n\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n//#region 辅助变量(用于销毁)\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n\r\n/** 动画帧 ID,用于取消动画循环 */\r\nlet animationId: number | null = null;\r\n/** 鼠标点击事件监听函数引用(用于移除) */\r\nlet clickHandler: ((event: MouseEvent) => void) | null = null;\r\n/** 窗口 resize 事件监听函数引用(用于移除) */\r\nlet resizeHandler: (() => void) | null = null;\r\n//#endregion\r\n\r\n// ═══════════════════════════════════════════════════════════════════\r\n//#region 初始化\r\n// ═══════════════════════════════════════════════════════════════════\r\n\r\n/**\r\n * 初始化编辑器,挂载到指定 DOM 容器\r\n * @param container - 编辑器挂载的 DOM 元素\r\n */\r\nexport function initEditor(\r\n container: HTMLElement,\r\n mode = \"edit\",\r\n sceneData?: any,\r\n) {\r\n state.container = container;\r\n state.mode = mode;\r\n initRenderer(); // 创建渲染器\r\n initScene(); // 创建场景\r\n initCamera(); // 创建相机\r\n\r\n // 如果有传入场景数据\r\n if (sceneData) {\r\n // 设置场景数据\r\n loadSceneFromJSON(sceneData.scene, mode);\r\n // 设置摄像头数据\r\n if (sceneData?.camera) {\r\n const camData = sceneData.camera;\r\n state.camera!.position.set(\r\n camData.position[0],\r\n camData.position[1],\r\n camData.position[2],\r\n );\r\n state.camera!.rotation.set(\r\n camData.rotation[0],\r\n camData.rotation[1],\r\n camData.rotation[2],\r\n );\r\n state.camera!.updateProjectionMatrix();\r\n cameraTarget = camData.target;\r\n }\r\n }\r\n\r\n initTransformControls(); // 初始化变换控制器(需在 OrbitControls 前,因为辅助对象要加入场景)\r\n initOrbitControls(); // 初始化轨道控制器\r\n\r\n // 如果有 target,恢复 OrbitControls 的目标并更新\r\n if (cameraTarget && state.orbitControls) {\r\n state.orbitControls.target.fromArray(cameraTarget);\r\n state.orbitControls.update();\r\n }\r\n\r\n refreshSceneObjects(); // 刷新顶层物体列表\r\n animate(); // 启动动画循环\r\n\r\n // 绑定事件(保存引用以便销毁时移除)\r\n clickHandler = (event: MouseEvent) => onMouseClick(event);\r\n resizeHandler = () => onResize();\r\n // 绑定事件\r\n if (mode === \"edit\") container.addEventListener(\"click\", clickHandler);\r\n window.addEventListener(\"resize\", resizeHandler);\r\n\r\n // 如果没有传入场景数据\r\n if (!sceneData) {\r\n addDefaultLightAndCube(); // 添加默认灯光和立方体(演示用)\r\n }\r\n\r\n if (mode === \"edit\") initGrid(); // 添加网格地板\r\n}\r\n\r\n/** 创建 WebGL 渲染器,设置尺寸和像素比 */\r\nfunction initRenderer() {\r\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\r\n renderer.setSize(state.container!.clientWidth, state.container!.clientHeight);\r\n // 限制像素比不超过 2,以平衡性能和显示效果\r\n renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));\r\n state.container!.appendChild(renderer.domElement);\r\n state.renderer = renderer;\r\n}\r\n\r\n/** 创建场景并命名(便于调试),加载环境贴图 */\r\nfunction initScene() {\r\n state.scene = new THREE.Scene();\r\n state.scene.name = \"sl_scene\";\r\n\r\n // 异步加载图片作为背景图和环境贴图\r\n // const textureLoader = new THREE.TextureLoader();\r\n // textureLoader.load(\r\n // bgImage,\r\n // (texture) => {\r\n // // 1. 设置场景背景(直接可见的背景图)\r\n // // state.scene!.background = texture;\r\n\r\n // // 2. 基于同一纹理生成 PMREM 环境贴图(用于 PBR 反射/折射)\r\n // const pmremGenerator = new THREE.PMREMGenerator(state.renderer!);\r\n // const envMap = pmremGenerator.fromEquirectangular(texture).texture;\r\n // state.scene!.environment = envMap; // 释放临时资源\r\n // // texture.dispose();\r\n // pmremGenerator.dispose();\r\n // },\r\n // undefined,\r\n // (err) => console.error(\"背景图加载失败:\", err),\r\n // );\r\n}\r\n\r\n/** 创建网格辅助对象(地板),不加入树形列表 */\r\nfunction initGrid() {\r\n const grid = new THREE.GridHelper(30, 30, 0x88aaff, 0x335588);\r\n grid.name = \"地板\";\r\n grid.userData.type = \"initFloor\";\r\n // 地板不可移动,故不设置 isMovable\r\n state.scene!.add(grid);\r\n state.gridHelper = grid;\r\n}\r\n\r\n/** 创建透视相机,设置初始位置 */\r\nfunction initCamera() {\r\n const container = state.container!;\r\n const aspect = container.clientWidth / container.clientHeight;\r\n const camera = new THREE.PerspectiveCamera(45, aspect, 0.1, 1000);\r\n camera.position.set(0, 6, 15);\r\n camera.lookAt(0, 0, 0);\r\n state.camera = camera;\r\n}\r\n\r\n/** 创建轨道控制器,允许用户旋转/平移/缩放视图 */\r\nfunction initOrbitControls() {\r\n const controls = new OrbitControls(state.camera!, state.renderer!.domElement);\r\n\r\n controls.minDistance = 0;\r\n controls.maxDistance = Infinity;\r\n // 监测操作是否改变了相机状态\r\n controls.addEventListener(\"start\", () => {\r\n orbitChanged = false;\r\n });\r\n controls.addEventListener(\"change\", () => {\r\n orbitChanged = true;\r\n });\r\n controls.addEventListener(\"end\", () => {\r\n // 如果相机发生了改变,则标记跳过下一次点击(避免拖拽后选中物体)\r\n if (orbitChanged) {\r\n skipNextClick = true;\r\n setTimeout(() => {\r\n skipNextClick = false;\r\n }, 200);\r\n }\r\n });\r\n state.orbitControls = controls;\r\n}\r\n\r\n/** 创建变换控制器,用于拖拽移动物体(平移模式) */\r\nfunction initTransformControls() {\r\n const controls = new TransformControls(\r\n state.camera!,\r\n state.renderer!.domElement,\r\n );\r\n // 拖拽变换控制器时,暂时禁用轨道控制器\r\n controls.addEventListener(\"dragging-changed\", (event: any) => {\r\n state.orbitControls!.enabled = !event.value;\r\n if (!event.value) {\r\n // 拖拽结束后,跳过下一次点击\r\n skipNextClick = true;\r\n setTimeout(() => {\r\n skipNextClick = false;\r\n }, 200);\r\n }\r\n });\r\n // 物体变换过程中(位置/旋转/缩放变化),触发外部回调以更新 UI\r\n controls.addEventListener(\"objectChange\", () => {\r\n const selected = state.selectedObject;\r\n\r\n if (onTransformChange && selected) {\r\n onTransformChange(selected);\r\n }\r\n\r\n // ⭐ 如果是光源,手动刷新 Helper\r\n if (selected && selected.type === \"DirectionalLight\") {\r\n const helper = selected.userData.helper as THREE.Object3D | undefined;\r\n if (helper && (helper as any).update) {\r\n (helper as any).update(); // 调用 DirectionalLightHelper 的 update 方法\r\n }\r\n }\r\n });\r\n // 将变换控制器的辅助轴添加到场景\r\n state.scene!.add(controls.getHelper());\r\n state.transformControls = controls;\r\n}\r\n\r\n/** 添加默认的环境光、平行光和一个示例立方体 */\r\nfunction addDefaultLightAndCube() {\r\n // 环境光\r\n const ambient = new THREE.AmbientLight(0xffffff, 1);\r\n state.scene!.add(ambient);\r\n}\r\n//#endregion\r\n\r\n// ═══════════════════════════════════════════════════════════════════\r\n//#region 动画循环 & 窗口自适应\r\n// ═══════════════════════════════════════════════════════════════════\r\n\r\n/** 动画循环:更新 Tween 动画、轨道控制器,并渲染场景 */\r\nfunction animate() {\r\n animationId = requestAnimationFrame(animate);\r\n TWEEN.update(); // 更新补间动画(当前未使用,保留扩展)\r\n state.orbitControls?.update();\r\n state.renderer?.render(state.scene!, state.camera!);\r\n\r\n // 循环水体效果\r\n // if (state.scene) {\r\n // // const time = performance.now() * 0.001; // 秒为单位的时间\r\n // state.scene.traverse((child:any) => {\r\n // if (child.userData.isWater) {\r\n // if (child.material.uniforms) {\r\n // child.material.uniforms['time'].value += 1.0 / 120.0; // 速度可以根据需要调整[reference:15]\r\n // }\r\n // }\r\n // });\r\n // }\r\n\r\n // 遍历查找水纹效果\r\n if (state.scene) {\r\n state.scene.traverse((child) => {\r\n if (child.userData.isWater && child.type === \"Mesh\") {\r\n const mesh = child as THREE.Mesh;\r\n const mat = mesh.material as THREE.MeshStandardMaterial;\r\n if (mat.normalMap) {\r\n // 从 userData 读取速度,若未定义则使用默认值\r\n const speed = mesh.userData.waterSpeed || { x: 0.005, y: 0.003 };\r\n mat.normalMap.offset.x += speed.x;\r\n mat.normalMap.offset.y += speed.y;\r\n }\r\n }\r\n });\r\n }\r\n}\r\n\r\n/** 窗口大小变化时,自适应渲染尺寸和相机比例 */\r\nfunction onResize() {\r\n if (!state.container || !state.camera || !state.renderer) return;\r\n const width = state.container.clientWidth;\r\n const height = state.container.clientHeight;\r\n if (width === 0 || height === 0) return;\r\n state.camera.aspect = width / height;\r\n state.camera.updateProjectionMatrix();\r\n state.renderer.setSize(width, height);\r\n}\r\n//#endregion\r\n\r\n// ═══════════════════════════════════════════════════════════════════\r\n//#region 选中 / 取消选中\r\n// ═══════════════════════════════════════════════════════════════════\r\n\r\n/**\r\n * 选中场景中的一个物体,将其附着到变换控制器并显示平移轴\r\n * @param obj - 要选中的物体\r\n */\r\nexport function selectObject(obj: Object3D) {\r\n if (state.selectedObject === obj) return; // 已选中则忽略\r\n // 取消之前的附着\r\n if (state.selectedObject) {\r\n state.transformControls!.detach();\r\n }\r\n state.selectedObject = obj;\r\n state.transformControls!.attach(obj);\r\n state.transformControls!.setMode(state.transformControlsMode); // 默认平移模式\r\n state.transformControls!.showX = true;\r\n state.transformControls!.showY = true;\r\n state.transformControls!.showZ = true;\r\n // 通知外部选中变化\r\n onSelectedChange?.(obj);\r\n}\r\n\r\n/**\r\n * 设置变换控制器的模式\r\n * @param mode - \"translate\" | \"rotate\" | \"scale\"\r\n */\r\nexport function setTransformMode(mode: \"translate\" | \"rotate\" | \"scale\") {\r\n state.transformControlsMode = mode;\r\n if (state.transformControls) {\r\n state.transformControls.setMode(state.transformControlsMode);\r\n }\r\n}\r\n\r\n/** 取消选中:隐藏变换控制器,并通知外部 */\r\nfunction deselectObject() {\r\n if (state.selectedObject) {\r\n state.transformControls!.detach();\r\n state.selectedObject = null;\r\n onSelectedChange?.(null);\r\n }\r\n}\r\n//#endregion\r\n\r\n// ═══════════════════════════════════════════════════════════════════\r\n//#region 鼠标点击(射线拾取)\r\n// ═══════════════════════════════════════════════════════════════════\r\n\r\n/**\r\n * 鼠标点击事件处理:使用射线检测拾取场景中的可移动 Mesh,\r\n * 若点击到物体则选中它,否则取消选中\r\n */\r\nfunction onMouseClick(event: MouseEvent) {\r\n // 如果标记跳过本次点击(如拖拽刚结束),则忽略并重置标记\r\n if (skipNextClick) {\r\n skipNextClick = false;\r\n return;\r\n }\r\n // 计算鼠标位置归一化坐标\r\n const rect = state.renderer!.domElement.getBoundingClientRect();\r\n const mouse = new THREE.Vector2(\r\n ((event.clientX - rect.left) / rect.width) * 2 - 1,\r\n -((event.clientY - rect.top) / rect.height) * 2 + 1,\r\n );\r\n const raycaster = new THREE.Raycaster();\r\n raycaster.setFromCamera(mouse, state.camera!);\r\n\r\n // 收集场景中所有可点击的物体(isMovable 且为 Mesh)\r\n const clickables: Object3D[] = [];\r\n state.scene!.traverse((obj) => {\r\n if (obj.userData.isMovable || obj.userData.type === \"lightHelper\") {\r\n clickables.push(obj);\r\n }\r\n });\r\n const intersects = raycaster.intersectObjects(clickables);\r\n\r\n if (intersects.length > 0) {\r\n let obj: any = getIntersectsObject(intersects[0].object);\r\n selectObject(obj);\r\n } else {\r\n deselectObject();\r\n }\r\n}\r\n\r\n/**\r\n * 获取相交对象\r\n * @param firstObject\r\n * @returns\r\n */\r\nfunction getIntersectsObject(firstObject: any) {\r\n // 如果是辅助线对象\r\n if (firstObject.type === \"Line\") {\r\n // 获取父级进行判断\r\n const parent = firstObject.parent;\r\n switch (parent.type) {\r\n case \"DirectionalLightHelper\": // 若是平行光辅助,则返回平行光对象\r\n return parent.light;\r\n\r\n default:\r\n break;\r\n }\r\n } else {\r\n return firstObject;\r\n }\r\n}\r\n//#endregion\r\n\r\n// ═══════════════════════════════════════════════════════════════════\r\n//#region 选择模型后视角拉近\r\n// ═══════════════════════════════════════════════════════════════════\r\n\r\n/**\r\n * 将相机平滑聚焦到指定物体\r\n * @param objectId - 目标物体 id\r\n * @param duration - 动画持续时间(毫秒),默认 500ms\r\n */\r\nexport function focusOnObject(objectId: string, duration: number = 500) {\r\n if (!state.camera || !state.orbitControls) return;\r\n\r\n let object: any;\r\n state.scene?.traverse((child) => {\r\n if (child.userData.id == objectId) {\r\n object = child;\r\n }\r\n });\r\n\r\n // 获取物体的世界位置\r\n const targetPos = new THREE.Vector3();\r\n object.getWorldPosition(targetPos);\r\n\r\n // 计算包围盒半径(用于确定相机距离)\r\n const box = new THREE.Box3().setFromObject(object);\r\n const size = box.getSize(new THREE.Vector3());\r\n const radius = Math.max(size.x, size.y, size.z) * 0.5;\r\n // 设置最小距离,避免太小\r\n const distance = Math.max(radius * 2.5, 3);\r\n\r\n // 计算相机新位置:从物体位置沿当前相机方向后退 distance 距离\r\n const direction = new THREE.Vector3();\r\n state.camera.position.clone().sub(targetPos).normalize();\r\n // 如果相机恰好与物体重合,则使用默认方向 (0, 0, 1)\r\n if (direction.lengthSq() < 0.001) {\r\n direction.set(0, 0, 1);\r\n }\r\n const newCamPos = targetPos.clone().add(direction.multiplyScalar(distance));\r\n\r\n // 记录当前值\r\n const startPos = state.camera.position.clone();\r\n const startTarget = state.orbitControls.target.clone();\r\n\r\n // 创建 TWEEN 动画\r\n new TWEEN.Tween({\r\n x: startPos.x,\r\n y: startPos.y,\r\n z: startPos.z,\r\n tx: startTarget.x,\r\n ty: startTarget.y,\r\n tz: startTarget.z,\r\n })\r\n .to(\r\n {\r\n x: newCamPos.x,\r\n y: newCamPos.y,\r\n z: newCamPos.z,\r\n tx: targetPos.x,\r\n ty: targetPos.y,\r\n tz: targetPos.z,\r\n },\r\n duration,\r\n )\r\n .easing(TWEEN.Easing.Quadratic.InOut)\r\n .onUpdate((obj) => {\r\n state.camera!.position.set(obj.x, obj.y, obj.z);\r\n state.orbitControls!.target.set(obj.tx, obj.ty, obj.tz);\r\n state.orbitControls!.update();\r\n })\r\n .start();\r\n}\r\n//#endregion\r\n\r\n// ═══════════════════════════════════════════════════════════════════\r\n//#region 模型管理(增删)\r\n// ═══════════════════════════════════════════════════════════════════\r\n\r\n/**\r\n * 向场景添加一个模型(Object3D 及其子节点)\r\n * @param model - 要添加的模型对象\r\n * @param selected - 是否添加后立即选中\r\n */\r\nexport function addModel(model: Object3D, selected = false) {\r\n state.scene!.add(model);\r\n // 如果模型本身是可移动的,则加入顶层列表(但只有顶层对象才加入)\r\n if (model.userData.isMovable) {\r\n addObjectToTree(model);\r\n notifyChange();\r\n }\r\n if (selected && state.mode === \"edit\") selectObject(model);\r\n}\r\n\r\n/**\r\n * 从场景中移除一个模型及其子节点\r\n * @param model - 要移除的模型对象\r\n */\r\nexport function removeModel(model: Object3D) {\r\n if (state.selectedObject === model) deselectObject();\r\n // 从父节点移除(更通用),若没有父节点则从场景移除\r\n if (model.parent) {\r\n model.parent.remove(model);\r\n } else {\r\n state.scene!.remove(model);\r\n }\r\n // 如果该对象在顶层列表中,则移除\r\n removeObjectFromTree(model);\r\n notifyChange();\r\n}\r\n\r\n/**\r\n * 根据 UUID 删除场景中的物体\r\n * @param uuid - 物体的唯一标识符\r\n */\r\nexport function removeModelById(uuid: string) {\r\n const obj = state.scene!.getObjectByProperty(\"uuid\", uuid);\r\n if (obj) removeModel(obj);\r\n}\r\n\r\n// ─── 树形数据管理(仅顶层对象) ───\r\n\r\n/**\r\n * 将一个可移动物体加入顶层列表(前提是它是场景的直接子级)\r\n */\r\nfunction addObjectToTree(obj: Object3D) {\r\n if (obj.userData.isMovable && obj.parent === state.scene) {\r\n if (!sceneObjects.includes(obj)) {\r\n sceneObjects.push(obj);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * 从顶层列表中移除物体(如果存在)\r\n */\r\nfunction removeObjectFromTree(obj: Object3D) {\r\n const idx = sceneObjects.indexOf(obj);\r\n if (idx !== -1) sceneObjects.splice(idx, 1);\r\n}\r\n\r\n/** 全量刷新顶层物体列表(初始化时调用) */\r\nfunction refreshSceneObjects() {\r\n const list: Object3D[] = [];\r\n state.scene!.children.forEach((child) => {\r\n if (child.userData.isMovable) list.push(child);\r\n });\r\n sceneObjects = list;\r\n notifyChange();\r\n}\r\n\r\n/** 通知外部树形数据变化,传递列表副本以触发 shallowRef 更新 */\r\nfunction notifyChange() {\r\n onSceneObjectsChange?.([...sceneObjects]);\r\n}\r\n//#endregion\r\n\r\n// ═══════════════════════════════════════════════════════════════════\r\n//#region 回调注册\r\n// ═══════════════════════════════════════════════════════════════════\r\n\r\n/**\r\n * 注册选中物体变化的回调\r\n * @param cb - 回调函数,参数为当前选中的物体或 null\r\n */\r\nexport function setSelectedObjectCallback(cb: SelectedChangeCallback) {\r\n onSelectedChange = cb;\r\n}\r\n\r\n/**\r\n * 注册变换过程中(拖拽)的回调\r\n * @param cb - 回调函数,参数为正在变换的物体\r\n */\r\nexport function setTransformChangeCallback(cb: TransformChangeCallback) {\r\n onTransformChange = cb;\r\n}\r\n\r\n/**\r\n * 注册场景物体列表变化的回调\r\n * @param cb - 回调函数,参数为当前顶层物体列表\r\n */\r\nexport function onSceneObjectsChangeCallback(cb: SceneObjectsChangeCallback) {\r\n onSceneObjectsChange = cb;\r\n}\r\n\r\n/**\r\n * 获取当前顶层物体列表\r\n * @returns 顶层物体数组\r\n */\r\nexport function getSceneObjects() {\r\n return sceneObjects;\r\n}\r\n//#endregion\r\n\r\n// ═══════════════════════════════════════════════════════════════════\r\n//#region 场景导出导入\r\n// ═══════════════════════════════════════════════════════════════════\r\n\r\nexport function getScene() {\r\n return state.scene;\r\n}\r\nexport function getCamera() {\r\n return state.camera;\r\n}\r\nexport function getRenderer() {\r\n return state.renderer;\r\n}\r\n\r\n/**\r\n * 将当前 Three.js 场景导出为 JSON 数据(使用 Three.js 内置 toJSON)\r\n * @returns JSON 字符串\r\n */\r\nexport function exportSceneToJSON(): string {\r\n // 首先取消选中模型\r\n deselectObject();\r\n\r\n const scene = state.scene;\r\n if (!scene) return \"{}\";\r\n\r\n // 收集所有需要临时移除的辅助对象\r\n const lightHelpers: THREE.Object3D[] = [];\r\n // 保存光源与 helper 的关联,并临时清除\r\n const lightHelperMap = new Map<THREE.Object3D, any>();\r\n\r\n scene.children.forEach((child) => {\r\n if (child.userData.type === \"lightHelper\") {\r\n lightHelpers.push(child);\r\n }\r\n if (child.type === \"DirectionalLight\" && child.userData.helper) {\r\n lightHelperMap.set(child, child.userData.helper);\r\n // 清除引用,避免克隆时序列化问题\r\n child.userData.helper = undefined;\r\n }\r\n });\r\n\r\n // 从场景中移除辅助对象\r\n lightHelpers.forEach((h) => scene.remove(h));\r\n\r\n // 克隆场景(此时不包含辅助对象)\r\n const exportScene = scene.clone();\r\n // 移除初始化地板的对象\r\n exportScene.children = exportScene.children.filter(\r\n (child) => child.userData.type !== \"initFloor\",\r\n );\r\n // 场景 json\r\n const sceneJson = exportScene.toJSON();\r\n // const sceneJson = scene.toJSON();\r\n\r\n // 将辅助对象重新添加回原始场景\r\n lightHelpers.forEach((h) => scene.add(h));\r\n\r\n // 恢复光源的 helper 引用\r\n lightHelperMap.forEach((helper, light) => {\r\n light.userData.helper = helper;\r\n });\r\n\r\n // 摄像机 json\r\n const cameraJson = {\r\n position: state.camera?.position.toArray(),\r\n rotation: state.camera?.rotation.toArray(),\r\n target: state.orbitControls?.target.toArray() || [0, 0, 0],\r\n };\r\n\r\n return JSON.stringify({\r\n scene: sceneJson,\r\n camera: cameraJson,\r\n // lightHelpers: lightHelpers,\r\n });\r\n}\r\n\r\n/**\r\n * 从 JSON 数据恢复场景(使用 Three.js 内置 ObjectLoader)\r\n * @param json - JSON 字符串或对象\r\n * @returns 解析后的 Object3D 或 Scene\r\n */\r\nexport function loadSceneFromJSON(\r\n json: string | object,\r\n mode: string = \"edit\",\r\n) {\r\n const data = typeof json === \"string\" ? JSON.parse(json) : json;\r\n const loader = new THREE.ObjectLoader();\r\n const loaded = loader.parse(data);\r\n\r\n if (loaded.type === \"Scene\") {\r\n state.scene = loaded as THREE.Scene;\r\n } else {\r\n state.scene?.add(loaded);\r\n }\r\n\r\n if (mode === \"edit\") {\r\n state.scene?.traverse((obj) => {\r\n if (obj.type === \"DirectionalLight\") {\r\n const light = obj as THREE.DirectionalLight;\r\n // 避免重复添加\r\n if (!light.userData.helper) {\r\n const helper = new THREE.DirectionalLightHelper(light, 1);\r\n helper.userData.type = \"lightHelper\";\r\n light.userData.helper = helper;\r\n state.scene?.add(helper); // 添加到场景根节点\r\n }\r\n }\r\n });\r\n }\r\n}\r\n//#endregion\r\n\r\n// ═══════════════════════════════════════════════════════════════════\r\n//#region 销毁\r\n// ═══════════════════════════════════════════════════════════════════\r\n\r\n/**\r\n * 递归释放 Object3D 及其资源(几何体、材质、纹理)\r\n */\r\nfunction disposeObject(obj: THREE.Object3D) {\r\n if (!obj) return;\r\n\r\n // 处理 Mesh\r\n if (obj.type === \"Mesh\") {\r\n const mesh = obj as THREE.Mesh;\r\n if (mesh.geometry) {\r\n mesh.geometry.dispose();\r\n }\r\n if (mesh.material) {\r\n const materials = Array.isArray(mesh.material)\r\n ? mesh.material\r\n : [mesh.material];\r\n materials.forEach((mat: any) => {\r\n if (mat.map) mat.map = null;\r\n if (mat.lightMap) mat.lightMap = null;\r\n if (mat.aoMap) mat.aoMap = null;\r\n if (mat.emissiveMap) mat.emissiveMap = null;\r\n if (mat.bumpMap) mat.bumpMap = null;\r\n if (mat.normalMap) mat.normalMap = null;\r\n if (mat.displacementMap) mat.displacementMap = null;\r\n if (mat.roughnessMap) mat.roughnessMap = null;\r\n if (mat.metalnessMap) mat.metalnessMap = null;\r\n if (mat.alphaMap) mat.alphaMap = null;\r\n if (mat.envMap) mat.envMap = null;\r\n mat.dispose();\r\n });\r\n }\r\n }\r\n\r\n // 递归处理子对象\r\n const children = obj.children.slice();\r\n for (const child of children) {\r\n disposeObject(child);\r\n }\r\n}\r\n\r\n/**\r\n * 销毁编辑器,释放所有资源(场景、渲染器、控制器、事件监听等)\r\n * 调用后编辑器将完全卸载,可重新调用 initEditor 重新初始化\r\n */\r\nexport function destroyEditor() {\r\n // ─── 取消动画循环 ───\r\n if (animationId !== null) {\r\n cancelAnimationFrame(animationId);\r\n animationId = null;\r\n }\r\n\r\n // ─── 移除事件监听 ───\r\n if (clickHandler && state.container) {\r\n state.container.removeEventListener(\"click\", clickHandler);\r\n clickHandler = null;\r\n }\r\n if (resizeHandler) {\r\n window.removeEventListener(\"resize\", resizeHandler);\r\n resizeHandler = null;\r\n }\r\n\r\n // ─── 释放控制器 ───\r\n if (state.orbitControls) {\r\n state.orbitControls.dispose();\r\n state.orbitControls = null;\r\n }\r\n if (state.transformControls) {\r\n state.transformControls.dispose();\r\n state.transformControls = null;\r\n }\r\n\r\n // ─── 释放场景及所有物体 ───\r\n if (state.scene) {\r\n disposeObject(state.scene);\r\n state.scene = null;\r\n }\r\n\r\n // ─── 释放渲染器 ───\r\n if (state.renderer) {\r\n state.renderer.dispose();\r\n // 移除 DOM 元素\r\n if (state.renderer.domElement && state.container) {\r\n state.container.removeChild(state.renderer.domElement);\r\n }\r\n state.renderer = null;\r\n }\r\n\r\n // ─── 清空其他状态 ───\r\n state.camera = null;\r\n state.gridHelper = null;\r\n state.selectedObject = null;\r\n state.container = null;\r\n state.mode = \"\";\r\n\r\n // ─── 清空树形数据 ───\r\n sceneObjects = [];\r\n notifyChange();\r\n\r\n // ─── 重置标志 ───\r\n orbitChanged = false;\r\n skipNextClick = false;\r\n}\r\n","import {\n\tBufferGeometry,\n\tFileLoader,\n\tFloat32BufferAttribute,\n\tGroup,\n\tLineBasicMaterial,\n\tLineSegments,\n\tLoader,\n\tMaterial,\n\tMesh,\n\tMeshPhongMaterial,\n\tPoints,\n\tPointsMaterial,\n\tVector3,\n\tColor,\n\tSRGBColorSpace\n} from 'three';\n\n// o object_name | g group_name\nconst _object_pattern = /^[og]\\s*(.+)?/;\n// mtllib file_reference\nconst _material_library_pattern = /^mtllib /;\n// usemtl material_name\nconst _material_use_pattern = /^usemtl /;\n// usemap map_name\nconst _map_use_pattern = /^usemap /;\nconst _face_vertex_data_separator_pattern = /\\s+/;\n\nconst _vA = new Vector3();\nconst _vB = new Vector3();\nconst _vC = new Vector3();\n\nconst _ab = new Vector3();\nconst _cb = new Vector3();\n\nconst _color = new Color();\n\nfunction ParserState() {\n\n\tconst state = {\n\t\tobjects: [],\n\t\tobject: {},\n\n\t\tvertices: [],\n\t\tnormals: [],\n\t\tcolors: [],\n\t\tuvs: [],\n\n\t\tmaterials: {},\n\t\tmaterialLibraries: [],\n\n\t\tstartObject: function ( name, fromDeclaration ) {\n\n\t\t\t// If the current object (initial from reset) is not from a g/o declaration in the parsed\n\t\t\t// file. We need to use it for the first parsed g/o to keep things in sync.\n\t\t\tif ( this.object && this.object.fromDeclaration === false ) {\n\n\t\t\t\tthis.object.name = name;\n\t\t\t\tthis.object.fromDeclaration = ( fromDeclaration !== false );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tconst previousMaterial = ( this.object && typeof this.object.currentMaterial === 'function' ? this.object.currentMaterial() : undefined );\n\n\t\t\tif ( this.object && typeof this.object._finalize === 'function' ) {\n\n\t\t\t\tthis.object._finalize( true );\n\n\t\t\t}\n\n\t\t\tthis.object = {\n\t\t\t\tname: name || '',\n\t\t\t\tfromDeclaration: ( fromDeclaration !== false ),\n\n\t\t\t\tgeometry: {\n\t\t\t\t\tvertices: [],\n\t\t\t\t\tnormals: [],\n\t\t\t\t\tcolors: [],\n\t\t\t\t\tuvs: [],\n\t\t\t\t\thasUVIndices: false\n\t\t\t\t},\n\t\t\t\tmaterials: [],\n\t\t\t\tsmooth: true,\n\n\t\t\t\tstartMaterial: function ( name, libraries ) {\n\n\t\t\t\t\tconst previous = this._finalize( false );\n\n\t\t\t\t\t// New usemtl declaration overwrites an inherited material, except if faces were declared\n\t\t\t\t\t// after the material, then it must be preserved for proper MultiMaterial continuation.\n\t\t\t\t\tif ( previous && ( previous.inherited || previous.groupCount <= 0 ) ) {\n\n\t\t\t\t\t\tthis.materials.splice( previous.index, 1 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tconst material = {\n\t\t\t\t\t\tindex: this.materials.length,\n\t\t\t\t\t\tname: name || '',\n\t\t\t\t\t\tmtllib: ( Array.isArray( libraries ) && libraries.length > 0 ? libraries[ libraries.length - 1 ] : '' ),\n\t\t\t\t\t\tsmooth: ( previous !== undefined ? previous.smooth : this.smooth ),\n\t\t\t\t\t\tgroupStart: ( previous !== undefined ? previous.groupEnd : 0 ),\n\t\t\t\t\t\tgroupEnd: - 1,\n\t\t\t\t\t\tgroupCount: - 1,\n\t\t\t\t\t\tinherited: false,\n\n\t\t\t\t\t\tclone: function ( index ) {\n\n\t\t\t\t\t\t\tconst cloned = {\n\t\t\t\t\t\t\t\tindex: ( typeof index === 'number' ? index : this.index ),\n\t\t\t\t\t\t\t\tname: this.name,\n\t\t\t\t\t\t\t\tmtllib: this.mtllib,\n\t\t\t\t\t\t\t\tsmooth: this.smooth,\n\t\t\t\t\t\t\t\tgroupStart: 0,\n\t\t\t\t\t\t\t\tgroupEnd: - 1,\n\t\t\t\t\t\t\t\tgroupCount: - 1,\n\t\t\t\t\t\t\t\tinherited: false\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tcloned.clone = this.clone.bind( cloned );\n\t\t\t\t\t\t\treturn cloned;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\t\tthis.materials.push( material );\n\n\t\t\t\t\treturn material;\n\n\t\t\t\t},\n\n\t\t\t\tcurrentMaterial: function () {\n\n\t\t\t\t\tif ( this.materials.length > 0 ) {\n\n\t\t\t\t\t\treturn this.materials[ this.materials.length - 1 ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t},\n\n\t\t\t\t_finalize: function ( end ) {\n\n\t\t\t\t\tconst lastMultiMaterial = this.currentMaterial();\n\t\t\t\t\tif ( lastMultiMaterial && lastMultiMaterial.groupEnd === - 1 ) {\n\n\t\t\t\t\t\tlastMultiMaterial.groupEnd = this.geometry.vertices.length / 3;\n\t\t\t\t\t\tlastMultiMaterial.groupCount = lastMultiMaterial.groupEnd - lastMultiMaterial.groupStart;\n\t\t\t\t\t\tlastMultiMaterial.inherited = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Ignore objects tail materials if no face declarations followed them before a new o/g started.\n\t\t\t\t\tif ( end && this.materials.length > 1 ) {\n\n\t\t\t\t\t\tfor ( let mi = this.materials.length - 1; mi >= 0; mi -- ) {\n\n\t\t\t\t\t\t\tif ( this.materials[ mi ].groupCount <= 0 ) {\n\n\t\t\t\t\t\t\t\tthis.materials.splice( mi, 1 );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Guarantee at least one empty material, this makes the creation later more straight forward.\n\t\t\t\t\tif ( end && this.materials.length === 0 ) {\n\n\t\t\t\t\t\tthis.materials.push( {\n\t\t\t\t\t\t\tname: '',\n\t\t\t\t\t\t\tsmooth: this.smooth\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn lastMultiMaterial;\n\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// Inherit previous objects material.\n\t\t\t// Spec tells us that a declared material must be set to all objects until a new material is declared.\n\t\t\t// If a usemtl declaration is encountered while this new object is being parsed, it will\n\t\t\t// overwrite the inherited material. Exception being that there was already face declarations\n\t\t\t// to the inherited material, then it will be preserved for proper MultiMaterial continuation.\n\n\t\t\tif ( previousMaterial && previousMaterial.name && typeof previousMaterial.clone === 'function' ) {\n\n\t\t\t\tconst declared = previousMaterial.clone( 0 );\n\t\t\t\tdeclared.inherited = true;\n\t\t\t\tthis.object.materials.push( declared );\n\n\t\t\t}\n\n\t\t\tthis.objects.push( this.object );\n\n\t\t},\n\n\t\tfinalize: function () {\n\n\t\t\tif ( this.object && typeof this.object._finalize === 'function' ) {\n\n\t\t\t\tthis.object._finalize( true );\n\n\t\t\t}\n\n\t\t},\n\n\t\tparseVertexIndex: function ( value, len ) {\n\n\t\t\tconst index = parseInt( value, 10 );\n\t\t\treturn ( index >= 0 ? index - 1 : index + len / 3 ) * 3;\n\n\t\t},\n\n\t\tparseNormalIndex: function ( value, len ) {\n\n\t\t\tconst index = parseInt( value, 10 );\n\t\t\treturn ( index >= 0 ? index - 1 : index + len / 3 ) * 3;\n\n\t\t},\n\n\t\tparseUVIndex: function ( value, len ) {\n\n\t\t\tconst index = parseInt( value, 10 );\n\t\t\treturn ( index >= 0 ? index - 1 : index + len / 2 ) * 2;\n\n\t\t},\n\n\t\taddVertex: function ( a, b, c ) {\n\n\t\t\tconst src = this.vertices;\n\t\t\tconst dst = this.object.geometry.vertices;\n\n\t\t\tdst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );\n\t\t\tdst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] );\n\t\t\tdst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] );\n\n\t\t},\n\n\t\taddVertexPoint: function ( a ) {\n\n\t\t\tconst src = this.vertices;\n\t\t\tconst dst = this.object.geometry.vertices;\n\n\t\t\tdst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );\n\n\t\t},\n\n\t\taddVertexLine: function ( a ) {\n\n\t\t\tconst src = this.vertices;\n\t\t\tconst dst = this.object.geometry.vertices;\n\n\t\t\tdst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );\n\n\t\t},\n\n\t\taddNormal: function ( a, b, c ) {\n\n\t\t\tconst src = this.normals;\n\t\t\tconst dst = this.object.geometry.normals;\n\n\t\t\tdst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );\n\t\t\tdst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] );\n\t\t\tdst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] );\n\n\t\t},\n\n\t\taddFaceNormal: function ( a, b, c ) {\n\n\t\t\tconst src = this.vertices;\n\t\t\tconst dst = this.object.geometry.normals;\n\n\t\t\t_vA.fromArray( src, a );\n\t\t\t_vB.fromArray( src, b );\n\t\t\t_vC.fromArray( src, c );\n\n\t\t\t_cb.subVectors( _vC, _vB );\n\t\t\t_ab.subVectors( _vA, _vB );\n\t\t\t_cb.cross( _ab );\n\n\t\t\t_cb.normalize();\n\n\t\t\tdst.push( _cb.x, _cb.y, _cb.z );\n\t\t\tdst.push( _cb.x, _cb.y, _cb.z );\n\t\t\tdst.push( _cb.x, _cb.y, _cb.z );\n\n\t\t},\n\n\t\taddColor: function ( a, b, c ) {\n\n\t\t\tconst src = this.colors;\n\t\t\tconst dst = this.object.geometry.colors;\n\n\t\t\tif ( src[ a ] !== undefined ) dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );\n\t\t\tif ( src[ b ] !== undefined ) dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] );\n\t\t\tif ( src[ c ] !== undefined ) dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] );\n\n\t\t},\n\n\t\taddUV: function ( a, b, c ) {\n\n\t\t\tconst src = this.uvs;\n\t\t\tconst dst = this.object.geometry.uvs;\n\n\t\t\tdst.push( src[ a + 0 ], src[ a + 1 ] );\n\t\t\tdst.push( src[ b + 0 ], src[ b + 1 ] );\n\t\t\tdst.push( src[ c + 0 ], src[ c + 1 ] );\n\n\t\t},\n\n\t\taddDefaultUV: function () {\n\n\t\t\tconst dst = this.object.geometry.uvs;\n\n\t\t\tdst.push( 0, 0 );\n\t\t\tdst.push( 0, 0 );\n\t\t\tdst.push( 0, 0 );\n\n\t\t},\n\n\t\taddUVLine: function ( a ) {\n\n\t\t\tconst src = this.uvs;\n\t\t\tconst dst = this.object.geometry.uvs;\n\n\t\t\tdst.push( src[ a + 0 ], src[ a + 1 ] );\n\n\t\t},\n\n\t\taddFace: function ( a, b, c, ua, ub, uc, na, nb, nc ) {\n\n\t\t\tconst vLen = this.vertices.length;\n\n\t\t\tlet ia = this.parseVertexIndex( a, vLen );\n\t\t\tlet ib = this.parseVertexIndex( b, vLen );\n\t\t\tlet ic = this.parseVertexIndex( c, vLen );\n\n\t\t\tthis.addVertex( ia, ib, ic );\n\t\t\tthis.addColor( ia, ib, ic );\n\n\t\t\t// normals\n\n\t\t\tif ( na !== undefined && na !== '' ) {\n\n\t\t\t\tconst nLen = this.normals.length;\n\n\t\t\t\tia = this.parseNormalIndex( na, nLen );\n\t\t\t\tib = this.parseNormalIndex( nb, nLen );\n\t\t\t\tic = this.parseNormalIndex( nc, nLen );\n\n\t\t\t\tthis.addNormal( ia, ib, ic );\n\n\t\t\t} else {\n\n\t\t\t\tthis.addFaceNormal( ia, ib, ic );\n\n\t\t\t}\n\n\t\t\t// uvs\n\n\t\t\tif ( ua !== undefined && ua !== '' ) {\n\n\t\t\t\tconst uvLen = this.uvs.length;\n\n\t\t\t\tia = this.parseUVIndex( ua, uvLen );\n\t\t\t\tib = this.parseUVIndex( ub, uvLen );\n\t\t\t\tic = this.parseUVIndex( uc, uvLen );\n\n\t\t\t\tthis.addUV( ia, ib, ic );\n\n\t\t\t\tthis.object.geometry.hasUVIndices = true;\n\n\t\t\t} else {\n\n\t\t\t\t// add placeholder values (for inconsistent face definitions)\n\n\t\t\t\tthis.addDefaultUV();\n\n\t\t\t}\n\n\t\t},\n\n\t\taddPointGeometry: function ( vertices ) {\n\n\t\t\tthis.object.geometry.type = 'Points';\n\n\t\t\tconst vLen = this.vertices.length;\n\n\t\t\tfor ( let vi = 0, l = vertices.length; vi < l; vi ++ ) {\n\n\t\t\t\tconst index = this.parseVertexIndex( vertices[ vi ], vLen );\n\n\t\t\t\tthis.addVertexPoint( index );\n\t\t\t\tthis.addColor( index );\n\n\t\t\t}\n\n\t\t},\n\n\t\taddLineGeometry: function ( vertices, uvs ) {\n\n\t\t\tthis.object.geometry.type = 'Line';\n\n\t\t\tconst vLen = this.vertices.length;\n\t\t\tconst uvLen = this.uvs.length;\n\n\t\t\tfor ( let vi = 0, l = vertices.length; vi < l; vi ++ ) {\n\n\t\t\t\tthis.addVertexLine( this.parseVertexIndex( vertices[ vi ], vLen ) );\n\n\t\t\t}\n\n\t\t\tfor ( let uvi = 0, l = uvs.length; uvi < l; uvi ++ ) {\n\n\t\t\t\tthis.addUVLine( this.parseUVIndex( uvs[ uvi ], uvLen ) );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tstate.startObject( '', false );\n\n\treturn state;\n\n}\n\n\n/**\n * A loader for the OBJ format.\n *\n * The [OBJ format](https://en.wikipedia.org/wiki/Wavefront_.obj_file) is a simple data-format that\n * represents 3D geometry in a human readable format as the position of each vertex, the UV position of\n * each texture coordinate vertex, vertex normals, and the faces that make each polygon defined as a list\n * of vertices, and texture vertices.\n *\n * ```js\n * const loader = new OBJLoader();\n * const object = await loader.loadAsync( 'models/monster.obj' );\n * scene.add( object );\n * ```\n *\n * @augments Loader\n * @three_import import { OBJLoader } from 'three/addons/loaders/OBJLoader.js';\n */\nclass OBJLoader extends Loader {\n\n\t/**\n\t * Constructs a new OBJ loader.\n\t *\n\t * @param {LoadingManager} [manager] - The loading manager.\n\t */\n\tconstructor( manager ) {\n\n\t\tsuper( manager );\n\n\t\t/**\n\t\t * A reference to a material creator.\n\t\t *\n\t\t * @type {?MaterialCreator}\n\t\t * @default null\n\t\t */\n\t\tthis.materials = null;\n\n\t}\n\n\t/**\n\t * Starts loading from the given URL and passes the loaded OBJ asset\n\t * to the `onLoad()` callback.\n\t *\n\t * @param {string} url - The path/URL of the file to be loaded. This can also be a data URI.\n\t * @param {function(Group)} onLoad - Executed when the loading process has been finished.\n\t * @param {onProgressCallback} onProgress - Executed while the loading is in progress.\n\t * @param {onErrorCallback} onError - Executed when errors occur.\n\t */\n\tload( url, onLoad, onProgress, onError ) {\n\n\t\tconst scope = this;\n\n\t\tconst loader = new FileLoader( this.manager );\n\t\tloader.setPath( this.path );\n\t\tloader.setRequestHeader( this.requestHeader );\n\t\tloader.setWithCredentials( this.withCredentials );\n\t\tloader.load( url, function ( text ) {\n\n\t\t\ttry {\n\n\t\t\t\tonLoad( scope.parse( text ) );\n\n\t\t\t} catch ( e ) {\n\n\t\t\t\tif ( onError ) {\n\n\t\t\t\t\tonError( e );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.error( e );\n\n\t\t\t\t}\n\n\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t}\n\n\t\t}, onProgress, onError );\n\n\t}\n\n\t/**\n\t * Sets the material creator for this OBJ. This object is loaded via {@link MTLLoader}.\n\t *\n\t * @param {MaterialCreator} materials - An object that creates the materials for this OBJ.\n\t * @return {OBJLoader} A reference to this loader.\n\t */\n\tsetMaterials( materials ) {\n\n\t\tthis.materials = materials;\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * Parses the given OBJ data and returns the resulting group.\n\t *\n\t * @param {string} text - The raw OBJ data as a string.\n\t * @return {Group} The parsed OBJ.\n\t */\n\tparse( text ) {\n\n\t\tconst state = new ParserState();\n\n\t\tif ( text.indexOf( '\\r\\n' ) !== - 1 ) {\n\n\t\t\t// This is faster than String.split with regex that splits on both\n\t\t\ttext = text.replace( /\\r\\n/g, '\\n' );\n\n\t\t}\n\n\t\tif ( text.indexOf( '\\\\\\n' ) !== - 1 ) {\n\n\t\t\t// join lines separated by a line continuation character (\\)\n\t\t\ttext = text.replace( /\\\\\\n/g, '' );\n\n\t\t}\n\n\t\tconst lines = text.split( '\\n' );\n\t\tlet result = [];\n\n\t\tfor ( let i = 0, l = lines.length; i < l; i ++ ) {\n\n\t\t\tconst line = lines[ i ].trimStart();\n\n\t\t\tif ( line.length === 0 ) continue;\n\n\t\t\tconst lineFirstChar = line.charAt( 0 );\n\n\t\t\t// @todo invoke passed in handler if any\n\t\t\tif ( lineFirstChar === '#' ) continue; // skip comments\n\n\t\t\tif ( lineFirstChar === 'v' ) {\n\n\t\t\t\tconst data = line.split( _face_vertex_data_separator_pattern );\n\n\t\t\t\tswitch ( data[ 0 ] ) {\n\n\t\t\t\t\tcase 'v':\n\t\t\t\t\t\tstate.vertices.push(\n\t\t\t\t\t\t\tparseFloat( data[ 1 ] ),\n\t\t\t\t\t\t\tparseFloat( data[ 2 ] ),\n\t\t\t\t\t\t\tparseFloat( data[ 3 ] )\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif ( data.length >= 7 ) {\n\n\t\t\t\t\t\t\t_color.setRGB(\n\t\t\t\t\t\t\t\tparseFloat( data[ 4 ] ),\n\t\t\t\t\t\t\t\tparseFloat( data[ 5 ] ),\n\t\t\t\t\t\t\t\tparseFloat( data[ 6 ] ),\n\t\t\t\t\t\t\t\tSRGBColorSpace\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tstate.colors.push( _color.r, _color.g, _color.b );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// if no colors are defined, add placeholders so color and vertex indices match\n\n\t\t\t\t\t\t\tstate.colors.push( undefined, undefined, undefined );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'vn':\n\t\t\t\t\t\tstate.normals.push(\n\t\t\t\t\t\t\tparseFloat( data[ 1 ] ),\n\t\t\t\t\t\t\tparseFloat( data[ 2 ] ),\n\t\t\t\t\t\t\tparseFloat( data[ 3 ] )\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'vt':\n\t\t\t\t\t\tstate.uvs.push(\n\t\t\t\t\t\t\tparseFloat( data[ 1 ] ),\n\t\t\t\t\t\t\tparseFloat( data[ 2 ] )\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t} else if ( lineFirstChar === 'f' ) {\n\n\t\t\t\tconst lineData = line.slice( 1 ).trim();\n\t\t\t\tconst vertexData = lineData.split( _face_vertex_data_separator_pattern );\n\t\t\t\tconst faceVertices = [];\n\n\t\t\t\t// Parse the face vertex data into an easy to work with format\n\n\t\t\t\tfor ( let j = 0, jl = vertexData.length; j < jl; j ++ ) {\n\n\t\t\t\t\tconst vertex = vertexData[ j ];\n\n\t\t\t\t\tif ( vertex.length > 0 ) {\n\n\t\t\t\t\t\tconst vertexParts = vertex.split( '/' );\n\t\t\t\t\t\tfaceVertices.push( vertexParts );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// Draw an edge between the first vertex and all subsequent vertices to form an n-gon\n\n\t\t\t\tconst v1 = faceVertices[ 0 ];\n\n\t\t\t\tfor ( let j = 1, jl = faceVertices.length - 1; j < jl; j ++ ) {\n\n\t\t\t\t\tconst v2 = faceVertices[ j ];\n\t\t\t\t\tconst v3 = faceVertices[ j + 1 ];\n\n\t\t\t\t\tstate.addFace(\n\t\t\t\t\t\tv1[ 0 ], v2[ 0 ], v3[ 0 ],\n\t\t\t\t\t\tv1[ 1 ], v2[ 1 ], v3[ 1 ],\n\t\t\t\t\t\tv1[ 2 ], v2[ 2 ], v3[ 2 ]\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t} else if ( lineFirstChar === 'l' ) {\n\n\t\t\t\tconst lineParts = line.substring( 1 ).trim().split( ' ' );\n\t\t\t\tlet lineVertices = [];\n\t\t\t\tconst lineUVs = [];\n\n\t\t\t\tif ( line.indexOf( '/' ) === - 1 ) {\n\n\t\t\t\t\tlineVertices = lineParts;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( let li = 0, llen = lineParts.length; li < llen; li ++ ) {\n\n\t\t\t\t\t\tconst parts = lineParts[ li ].split( '/' );\n\n\t\t\t\t\t\tif ( parts[ 0 ] !== '' ) lineVertices.push( parts[ 0 ] );\n\t\t\t\t\t\tif ( parts[ 1 ] !== '' ) lineUVs.push( parts[ 1 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tstate.addLineGeometry( lineVertices, lineUVs );\n\n\t\t\t} else if ( lineFirstChar === 'p' ) {\n\n\t\t\t\tconst lineData = line.slice( 1 ).trim();\n\t\t\t\tconst pointData = lineData.split( ' ' );\n\n\t\t\t\tstate.addPointGeometry( pointData );\n\n\t\t\t} else if ( ( result = _object_pattern.exec( line ) ) !== null ) {\n\n\t\t\t\t// o object_name\n\t\t\t\t// or\n\t\t\t\t// g group_name\n\n\t\t\t\t// WORKAROUND: https://bugs.chromium.org/p/v8/issues/detail?id=2869\n\t\t\t\t// let name = result[ 0 ].slice( 1 ).trim();\n\t\t\t\tconst name = ( ' ' + result[ 0 ].slice( 1 ).trim() ).slice( 1 );\n\n\t\t\t\tstate.startObject( name );\n\n\t\t\t} else if ( _material_use_pattern.test( line ) ) {\n\n\t\t\t\t// material\n\n\t\t\t\tstate.object.startMaterial( line.substring( 7 ).trim(), state.materialLibraries );\n\n\t\t\t} else if ( _material_library_pattern.test( line ) ) {\n\n\t\t\t\t// mtl file\n\n\t\t\t\tstate.materialLibraries.push( line.substring( 7 ).trim() );\n\n\t\t\t} else if ( _map_use_pattern.test( line ) ) {\n\n\t\t\t\t// the line is parsed but ignored since the loader assumes textures are defined MTL files\n\t\t\t\t// (according to https://www.okino.com/conv/imp_wave.htm, 'usemap' is the old-style Wavefront texture reference method)\n\n\t\t\t\tconsole.warn( 'THREE.OBJLoader: Rendering identifier \"usemap\" not supported. Textures must be defined in MTL files.' );\n\n\t\t\t} else if ( lineFirstChar === 's' ) {\n\n\t\t\t\tresult = line.split( ' ' );\n\n\t\t\t\t// smooth shading\n\n\t\t\t\t// @todo Handle files that have varying smooth values for a set of faces inside one geometry,\n\t\t\t\t// but does not define a usemtl for each face set.\n\t\t\t\t// This should be detected and a dummy material created (later MultiMaterial and geometry groups).\n\t\t\t\t// This requires some care to not create extra material on each smooth value for \"normal\" obj files.\n\t\t\t\t// where explicit usemtl defines geometry groups.\n\t\t\t\t// Example asset: examples/models/obj/cerberus/Cerberus.obj\n\n\t\t\t\t/*\n\t\t\t\t\t * http://paulbourke.net/dataformats/obj/\n\t\t\t\t\t *\n\t\t\t\t\t * From chapter \"Grouping\" Syntax explanation \"s group_number\":\n\t\t\t\t\t * \"group_number is the smoothing group number. To turn off smoothing groups, use a value of 0 or off.\n\t\t\t\t\t * Polygonal elements use group numbers to put elements in different smoothing groups. For free-form\n\t\t\t\t\t * surfaces, smoothing groups are either turned on or off; there is no difference between values greater\n\t\t\t\t\t * than 0.\"\n\t\t\t\t\t */\n\t\t\t\tif ( result.length > 1 ) {\n\n\t\t\t\t\tconst value = result[ 1 ].trim().toLowerCase();\n\t\t\t\t\tstate.object.smooth = ( value !== '0' && value !== 'off' );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// ZBrush can produce \"s\" lines #11707\n\t\t\t\t\tstate.object.smooth = true;\n\n\t\t\t\t}\n\n\t\t\t\tconst material = state.object.currentMaterial();\n\t\t\t\tif ( material ) material.smooth = state.object.smooth;\n\n\t\t\t} else {\n\n\t\t\t\t// Handle null terminated files without exception\n\t\t\t\tif ( line === '\\0' ) continue;\n\n\t\t\t\tconsole.warn( 'THREE.OBJLoader: Unexpected line: \"' + line + '\"' );\n\n\t\t\t}\n\n\t\t}\n\n\t\tstate.finalize();\n\n\t\tconst container = new Group();\n\t\tcontainer.materialLibraries = [].concat( state.materialLibraries );\n\n\t\tconst hasPrimitives = ! ( state.objects.length === 1 && state.objects[ 0 ].geometry.vertices.length === 0 );\n\n\t\tif ( hasPrimitives === true ) {\n\n\t\t\tfor ( let i = 0, l = state.objects.length; i < l; i ++ ) {\n\n\t\t\t\tconst object = state.objects[ i ];\n\t\t\t\tconst geometry = object.geometry;\n\t\t\t\tconst materials = object.materials;\n\t\t\t\tconst isLine = ( geometry.type === 'Line' );\n\t\t\t\tconst isPoints = ( geometry.type === 'Points' );\n\t\t\t\tlet hasVertexColors = false;\n\n\t\t\t\t// Skip o/g line declarations that did not follow with any faces\n\t\t\t\tif ( geometry.vertices.length === 0 ) continue;\n\n\t\t\t\tconst buffergeometry = new BufferGeometry();\n\n\t\t\t\tbuffergeometry.setAttribute( 'position', new Float32BufferAttribute( geometry.vertices, 3 ) );\n\n\t\t\t\tif ( geometry.normals.length > 0 ) {\n\n\t\t\t\t\tbuffergeometry.setAttribute( 'normal', new Float32BufferAttribute( geometry.normals, 3 ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.colors.length > 0 ) {\n\n\t\t\t\t\thasVertexColors = true;\n\t\t\t\t\tbuffergeometry.setAttribute( 'color', new Float32BufferAttribute( geometry.colors, 3 ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.hasUVIndices === true ) {\n\n\t\t\t\t\tbuffergeometry.setAttribute( 'uv', new Float32BufferAttribute( geometry.uvs, 2 ) );\n\n\t\t\t\t}\n\n\t\t\t\t// Create materials\n\n\t\t\t\tconst createdMaterials = [];\n\n\t\t\t\tfor ( let mi = 0, miLen = materials.length; mi < miLen; mi ++ ) {\n\n\t\t\t\t\tconst sourceMaterial = materials[ mi ];\n\t\t\t\t\tconst materialHash = sourceMaterial.name + '_' + sourceMaterial.smooth + '_' + hasVertexColors;\n\t\t\t\t\tlet material = state.materials[ materialHash ];\n\n\t\t\t\t\tif ( this.materials !== null ) {\n\n\t\t\t\t\t\tmaterial = this.materials.create( sourceMaterial.name );\n\n\t\t\t\t\t\t// mtl etc. loaders probably can't create line materials correctly, copy properties to a line material.\n\t\t\t\t\t\tif ( isLine && material && ! ( material instanceof LineBasicMaterial ) ) {\n\n\t\t\t\t\t\t\tconst materialLine = new LineBasicMaterial();\n\t\t\t\t\t\t\tMaterial.prototype.copy.call( materialLine, material );\n\t\t\t\t\t\t\tmaterialLine.color.copy( material.color );\n\t\t\t\t\t\t\tmaterial = materialLine;\n\n\t\t\t\t\t\t} else if ( isPoints && material && ! ( material instanceof PointsMaterial ) ) {\n\n\t\t\t\t\t\t\tconst materialPoints = new PointsMaterial( { size: 10, sizeAttenuation: false } );\n\t\t\t\t\t\t\tMaterial.prototype.copy.call( materialPoints, material );\n\t\t\t\t\t\t\tmaterialPoints.color.copy( material.color );\n\t\t\t\t\t\t\tmaterialPoints.map = material.map;\n\t\t\t\t\t\t\tmaterial = materialPoints;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( material === undefined ) {\n\n\t\t\t\t\t\tif ( isLine ) {\n\n\t\t\t\t\t\t\tmaterial = new LineBasicMaterial();\n\n\t\t\t\t\t\t} else if ( isPoints ) {\n\n\t\t\t\t\t\t\tmaterial = new PointsMaterial( { size: 1, sizeAttenuation: false } );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tmaterial = new MeshPhongMaterial();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tmaterial.name = sourceMaterial.name;\n\t\t\t\t\t\tmaterial.flatShading = sourceMaterial.smooth ? false : true;\n\t\t\t\t\t\tmaterial.vertexColors = hasVertexColors;\n\n\t\t\t\t\t\tstate.materials[ materialHash ] = material;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tcreatedMaterials.push( material );\n\n\t\t\t\t}\n\n\t\t\t\t// Create mesh\n\n\t\t\t\tlet mesh;\n\n\t\t\t\tif ( createdMaterials.length > 1 ) {\n\n\t\t\t\t\tfor ( let mi = 0, miLen = materials.length; mi < miLen; mi ++ ) {\n\n\t\t\t\t\t\tconst sourceMaterial = materials[ mi ];\n\t\t\t\t\t\tbuffergeometry.addGroup( sourceMaterial.groupStart, sourceMaterial.groupCount, mi );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( isLine ) {\n\n\t\t\t\t\t\tmesh = new LineSegments( buffergeometry, createdMaterials );\n\n\t\t\t\t\t} else if ( isPoints ) {\n\n\t\t\t\t\t\tmesh = new Points( buffergeometry, createdMaterials );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tmesh = new Mesh( buffergeometry, createdMaterials );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( isLine ) {\n\n\t\t\t\t\t\tmesh = new LineSegments( buffergeometry, createdMaterials[ 0 ] );\n\n\t\t\t\t\t} else if ( isPoints ) {\n\n\t\t\t\t\t\tmesh = new Points( buffergeometry, createdMaterials[ 0 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tmesh = new Mesh( buffergeometry, createdMaterials[ 0 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tmesh.name = object.name;\n\n\t\t\t\tcontainer.add( mesh );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// if there is only the default parser state object with no geometry data, interpret data as point cloud\n\n\t\t\tif ( state.vertices.length > 0 ) {\n\n\t\t\t\tconst material = new PointsMaterial( { size: 1, sizeAttenuation: false } );\n\n\t\t\t\tconst buffergeometry = new BufferGeometry();\n\n\t\t\t\tbuffergeometry.setAttribute( 'position', new Float32BufferAttribute( state.vertices, 3 ) );\n\n\t\t\t\tif ( state.colors.length > 0 && state.colors[ 0 ] !== undefined ) {\n\n\t\t\t\t\tbuffergeometry.setAttribute( 'color', new Float32BufferAttribute( state.colors, 3 ) );\n\t\t\t\t\tmaterial.vertexColors = true;\n\n\t\t\t\t}\n\n\t\t\t\tconst points = new Points( buffergeometry, material );\n\t\t\t\tcontainer.add( points );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn container;\n\n\t}\n\n}\n\nexport { OBJLoader };\n","import {\n\tBufferAttribute,\n\tBufferGeometry,\n\tFloat32BufferAttribute,\n\tInstancedBufferAttribute,\n\tInterleavedBuffer,\n\tInterleavedBufferAttribute,\n\tTriangleFanDrawMode,\n\tTriangleStripDrawMode,\n\tTrianglesDrawMode,\n\tVector3,\n} from 'three';\n\n/**\n * @module BufferGeometryUtils\n * @three_import import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js';\n */\n\n/**\n * Computes vertex tangents using the MikkTSpace algorithm. MikkTSpace generates the same tangents consistently,\n * and is used in most modelling tools and normal map bakers. Use MikkTSpace for materials with normal maps,\n * because inconsistent tangents may lead to subtle visual issues in the normal map, particularly around mirrored\n * UV seams.\n *\n * In comparison to this method, {@link BufferGeometry#computeTangents} (a custom algorithm) generates tangents that\n * probably will not match the tangents in other software. The custom algorithm is sufficient for general use with a\n * custom material, and may be faster than MikkTSpace.\n *\n * Returns the original BufferGeometry. Indexed geometries will be de-indexed. Requires position, normal, and uv attributes.\n *\n * @param {BufferGeometry} geometry - The geometry to compute tangents for.\n * @param {Object} MikkTSpace - Instance of `examples/jsm/libs/mikktspace.module.js`, or `mikktspace` npm package.\n * Await `MikkTSpace.ready` before use.\n * @param {boolean} [negateSign=true] - Whether to negate the sign component (.w) of each tangent.\n * Required for normal map conventions in some formats, including glTF.\n * @return {BufferGeometry} The updated geometry.\n */\nfunction computeMikkTSpaceTangents( geometry, MikkTSpace, negateSign = true ) {\n\n\tif ( ! MikkTSpace || ! MikkTSpace.isReady ) {\n\n\t\tthrow new Error( 'BufferGeometryUtils: Initialized MikkTSpace library required.' );\n\n\t}\n\n\tif ( ! geometry.hasAttribute( 'position' ) || ! geometry.hasAttribute( 'normal' ) || ! geometry.hasAttribute( 'uv' ) ) {\n\n\t\tthrow new Error( 'BufferGeometryUtils: Tangents require \"position\", \"normal\", and \"uv\" attributes.' );\n\n\t}\n\n\tfunction getAttributeArray( attribute ) {\n\n\t\tif ( attribute.normalized || attribute.isInterleavedBufferAttribute ) {\n\n\t\t\tconst dstArray = new Float32Array( attribute.count * attribute.itemSize );\n\n\t\t\tfor ( let i = 0, j = 0; i < attribute.count; i ++ ) {\n\n\t\t\t\tdstArray[ j ++ ] = attribute.getX( i );\n\t\t\t\tdstArray[ j ++ ] = attribute.getY( i );\n\n\t\t\t\tif ( attribute.itemSize > 2 ) {\n\n\t\t\t\t\tdstArray[ j ++ ] = attribute.getZ( i );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn dstArray;\n\n\t\t}\n\n\t\tif ( attribute.array instanceof Float32Array ) {\n\n\t\t\treturn attribute.array;\n\n\t\t}\n\n\t\treturn new Float32Array( attribute.array );\n\n\t}\n\n\t// MikkTSpace algorithm requires non-indexed input.\n\n\tconst _geometry = geometry.index ? geometry.toNonIndexed() : geometry;\n\n\t// Compute vertex tangents.\n\n\tconst tangents = MikkTSpace.generateTangents(\n\n\t\tgetAttributeArray( _geometry.attributes.position ),\n\t\tgetAttributeArray( _geometry.attributes.normal ),\n\t\tgetAttributeArray( _geometry.attributes.uv )\n\n\t);\n\n\t// Texture coordinate convention of glTF differs from the apparent\n\t// default of the MikkTSpace library; .w component must be flipped.\n\n\tif ( negateSign ) {\n\n\t\tfor ( let i = 3; i < tangents.length; i += 4 ) {\n\n\t\t\ttangents[ i ] *= - 1;\n\n\t\t}\n\n\t}\n\n\t//\n\n\t_geometry.setAttribute( 'tangent', new BufferAttribute( tangents, 4 ) );\n\n\tif ( geometry !== _geometry ) {\n\n\t\tgeometry.copy( _geometry );\n\n\t}\n\n\treturn geometry;\n\n}\n\n/**\n * Merges a set of geometries into a single instance. All geometries must have compatible attributes.\n *\n * @param {Array<BufferGeometry>} geometries - The geometries to merge.\n * @param {boolean} [useGroups=false] - Whether to use groups or not.\n * @return {?BufferGeometry} The merged geometry. Returns `null` if the merge does not succeed.\n */\nfunction mergeGeometries( geometries, useGroups = false ) {\n\n\tconst isIndexed = geometries[ 0 ].index !== null;\n\n\tconst attributesUsed = new Set( Object.keys( geometries[ 0 ].attributes ) );\n\tconst morphAttributesUsed = new Set( Object.keys( geometries[ 0 ].morphAttributes ) );\n\n\tconst attributes = {};\n\tconst morphAttributes = {};\n\n\tconst morphTargetsRelative = geometries[ 0 ].morphTargetsRelative;\n\n\tconst mergedGeometry = new BufferGeometry();\n\n\tlet offset = 0;\n\n\tfor ( let i = 0; i < geometries.length; ++ i ) {\n\n\t\tconst geometry = geometries[ i ];\n\t\tlet attributesCount = 0;\n\n\t\t// ensure that all geometries are indexed, or none\n\n\t\tif ( isIndexed !== ( geometry.index !== null ) ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them.' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\t// gather attributes, exit early if they're different\n\n\t\tfor ( const name in geometry.attributes ) {\n\n\t\t\tif ( ! attributesUsed.has( name ) ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. All geometries must have compatible attributes; make sure \"' + name + '\" attribute exists among all geometries, or in none of them.' );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tif ( attributes[ name ] === undefined ) attributes[ name ] = [];\n\n\t\t\tattributes[ name ].push( geometry.attributes[ name ] );\n\n\t\t\tattributesCount ++;\n\n\t\t}\n\n\t\t// ensure geometries have the same number of attributes\n\n\t\tif ( attributesCount !== attributesUsed.size ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. Make sure all geometries have the same number of attributes.' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\t// gather morph attributes, exit early if they're different\n\n\t\tif ( morphTargetsRelative !== geometry.morphTargetsRelative ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. .morphTargetsRelative must be consistent throughout all geometries.' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\tfor ( const name in geometry.morphAttributes ) {\n\n\t\t\tif ( ! morphAttributesUsed.has( name ) ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. .morphAttributes must be consistent throughout all geometries.' );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tif ( morphAttributes[ name ] === undefined ) morphAttributes[ name ] = [];\n\n\t\t\tmorphAttributes[ name ].push( geometry.morphAttributes[ name ] );\n\n\t\t}\n\n\t\tif ( useGroups ) {\n\n\t\t\tlet count;\n\n\t\t\tif ( isIndexed ) {\n\n\t\t\t\tcount = geometry.index.count;\n\n\t\t\t} else if ( geometry.attributes.position !== undefined ) {\n\n\t\t\t\tcount = geometry.attributes.position.count;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. The geometry must have either an index or a position attribute' );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tmergedGeometry.addGroup( offset, count, i );\n\n\t\t\toffset += count;\n\n\t\t}\n\n\t}\n\n\t// merge indices\n\n\tif ( isIndexed ) {\n\n\t\tlet indexOffset = 0;\n\t\tconst mergedIndex = [];\n\n\t\tfor ( let i = 0; i < geometries.length; ++ i ) {\n\n\t\t\tconst index = geometries[ i ].index;\n\n\t\t\tfor ( let j = 0; j < index.count; ++ j ) {\n\n\t\t\t\tmergedIndex.push( index.getX( j ) + indexOffset );\n\n\t\t\t}\n\n\t\t\tindexOffset += geometries[ i ].attributes.position.count;\n\n\t\t}\n\n\t\tmergedGeometry.setIndex( mergedIndex );\n\n\t}\n\n\t// merge attributes\n\n\tfor ( const name in attributes ) {\n\n\t\tconst mergedAttribute = mergeAttributes( attributes[ name ] );\n\n\t\tif ( ! mergedAttribute ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the ' + name + ' attribute.' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\tmergedGeometry.setAttribute( name, mergedAttribute );\n\n\t}\n\n\t// merge morph attributes\n\n\tfor ( const name in morphAttributes ) {\n\n\t\tconst numMorphTargets = morphAttributes[ name ][ 0 ].length;\n\t\tif ( numMorphTargets === 0 ) continue;\n\n\t\tmergedGeometry.morphAttributes = mergedGeometry.morphAttributes || {};\n\t\tmergedGeometry.morphAttributes[ name ] = [];\n\n\t\tfor ( let i = 0; i < numMorphTargets; ++ i ) {\n\n\t\t\tconst morphAttributesToMerge = [];\n\n\t\t\tfor ( let j = 0; j < morphAttributes[ name ].length; ++ j ) {\n\n\t\t\t\tmorphAttributesToMerge.push( morphAttributes[ name ][ j ][ i ] );\n\n\t\t\t}\n\n\t\t\tconst mergedMorphAttribute = mergeAttributes( morphAttributesToMerge );\n\n\t\t\tif ( ! mergedMorphAttribute ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the ' + name + ' morphAttribute.' );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tmergedGeometry.morphAttributes[ name ].push( mergedMorphAttribute );\n\n\t\t}\n\n\t}\n\n\treturn mergedGeometry;\n\n}\n\n/**\n * Merges a set of attributes into a single instance. All attributes must have compatible properties and types.\n * Instances of {@link InterleavedBufferAttribute} are not supported.\n *\n * @param {Array<BufferAttribute>} attributes - The attributes to merge.\n * @return {?BufferAttribute} The merged attribute. Returns `null` if the merge does not succeed.\n */\nfunction mergeAttributes( attributes ) {\n\n\tlet TypedArray;\n\tlet itemSize;\n\tlet normalized;\n\tlet gpuType = - 1;\n\tlet arrayLength = 0;\n\n\tfor ( let i = 0; i < attributes.length; ++ i ) {\n\n\t\tconst attribute = attributes[ i ];\n\n\t\tif ( TypedArray === undefined ) TypedArray = attribute.array.constructor;\n\t\tif ( TypedArray !== attribute.array.constructor ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.array must be of consistent array types across matching attributes.' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\tif ( itemSize === undefined ) itemSize = attribute.itemSize;\n\t\tif ( itemSize !== attribute.itemSize ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.itemSize must be consistent across matching attributes.' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\tif ( normalized === undefined ) normalized = attribute.normalized;\n\t\tif ( normalized !== attribute.normalized ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.normalized must be consistent across matching attributes.' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\tif ( gpuType === - 1 ) gpuType = attribute.gpuType;\n\t\tif ( gpuType !== attribute.gpuType ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.gpuType must be consistent across matching attributes.' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\tarrayLength += attribute.count * itemSize;\n\n\t}\n\n\tconst array = new TypedArray( arrayLength );\n\tconst result = new BufferAttribute( array, itemSize, normalized );\n\tlet offset = 0;\n\n\tfor ( let i = 0; i < attributes.length; ++ i ) {\n\n\t\tconst attribute = attributes[ i ];\n\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\tconst tupleOffset = offset / itemSize;\n\t\t\tfor ( let j = 0, l = attribute.count; j < l; j ++ ) {\n\n\t\t\t\tfor ( let c = 0; c < itemSize; c ++ ) {\n\n\t\t\t\t\tconst value = attribute.getComponent( j, c );\n\t\t\t\t\tresult.setComponent( j + tupleOffset, c, value );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tarray.set( attribute.array, offset );\n\n\t\t}\n\n\t\toffset += attribute.count * itemSize;\n\n\t}\n\n\tif ( gpuType !== undefined ) {\n\n\t\tresult.gpuType = gpuType;\n\n\t}\n\n\treturn result;\n\n}\n\n/**\n * Performs a deep clone of the given buffer attribute.\n *\n * @param {BufferAttribute} attribute - The attribute to clone.\n * @return {BufferAttribute} The cloned attribute.\n */\nfunction deepCloneAttribute( attribute ) {\n\n\tif ( attribute.isInstancedInterleavedBufferAttribute || attribute.isInterleavedBufferAttribute ) {\n\n\t\treturn deinterleaveAttribute( attribute );\n\n\t}\n\n\tif ( attribute.isInstancedBufferAttribute ) {\n\n\t\treturn new InstancedBufferAttribute().copy( attribute );\n\n\t}\n\n\treturn new BufferAttribute().copy( attribute );\n\n}\n\n/**\n * Interleaves a set of attributes and returns a new array of corresponding attributes that share a\n * single {@link InterleavedBuffer} instance. All attributes must have compatible types.\n *\n * @param {Array<BufferAttribute>} attributes - The attributes to interleave.\n * @return {?Array<InterleavedBufferAttribute>} An array of interleaved attributes. If interleave does not succeed, the method returns `null`.\n */\nfunction interleaveAttributes( attributes ) {\n\n\t// Interleaves the provided attributes into an InterleavedBuffer and returns\n\t// a set of InterleavedBufferAttributes for each attribute\n\tlet TypedArray;\n\tlet arrayLength = 0;\n\tlet stride = 0;\n\n\t// calculate the length and type of the interleavedBuffer\n\tfor ( let i = 0, l = attributes.length; i < l; ++ i ) {\n\n\t\tconst attribute = attributes[ i ];\n\n\t\tif ( TypedArray === undefined ) TypedArray = attribute.array.constructor;\n\t\tif ( TypedArray !== attribute.array.constructor ) {\n\n\t\t\tconsole.error( 'AttributeBuffers of different types cannot be interleaved' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\tarrayLength += attribute.array.length;\n\t\tstride += attribute.itemSize;\n\n\t}\n\n\t// Create the set of buffer attributes\n\tconst interleavedBuffer = new InterleavedBuffer( new TypedArray( arrayLength ), stride );\n\tlet offset = 0;\n\tconst res = [];\n\tconst getters = [ 'getX', 'getY', 'getZ', 'getW' ];\n\tconst setters = [ 'setX', 'setY', 'setZ', 'setW' ];\n\n\tfor ( let j = 0, l = attributes.length; j < l; j ++ ) {\n\n\t\tconst attribute = attributes[ j ];\n\t\tconst itemSize = attribute.itemSize;\n\t\tconst count = attribute.count;\n\t\tconst iba = new InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, attribute.normalized );\n\t\tres.push( iba );\n\n\t\toffset += itemSize;\n\n\t\t// Move the data for each attribute into the new interleavedBuffer\n\t\t// at the appropriate offset\n\t\tfor ( let c = 0; c < count; c ++ ) {\n\n\t\t\tfor ( let k = 0; k < itemSize; k ++ ) {\n\n\t\t\t\tiba[ setters[ k ] ]( c, attribute[ getters[ k ] ]( c ) );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\treturn res;\n\n}\n\n/**\n * Returns a new, non-interleaved version of the given attribute.\n *\n * @param {InterleavedBufferAttribute} attribute - The interleaved attribute.\n * @return {BufferAttribute} The non-interleaved attribute.\n */\nfunction deinterleaveAttribute( attribute ) {\n\n\tconst cons = attribute.data.array.constructor;\n\tconst count = attribute.count;\n\tconst itemSize = attribute.itemSize;\n\tconst normalized = attribute.normalized;\n\n\tconst array = new cons( count * itemSize );\n\tlet newAttribute;\n\tif ( attribute.isInstancedInterleavedBufferAttribute ) {\n\n\t\tnewAttribute = new InstancedBufferAttribute( array, itemSize, normalized, attribute.meshPerAttribute );\n\n\t} else {\n\n\t\tnewAttribute = new BufferAttribute( array, itemSize, normalized );\n\n\t}\n\n\tfor ( let i = 0; i < count; i ++ ) {\n\n\t\tnewAttribute.setX( i, attribute.getX( i ) );\n\n\t\tif ( itemSize >= 2 ) {\n\n\t\t\tnewAttribute.setY( i, attribute.getY( i ) );\n\n\t\t}\n\n\t\tif ( itemSize >= 3 ) {\n\n\t\t\tnewAttribute.setZ( i, attribute.getZ( i ) );\n\n\t\t}\n\n\t\tif ( itemSize >= 4 ) {\n\n\t\t\tnewAttribute.setW( i, attribute.getW( i ) );\n\n\t\t}\n\n\t}\n\n\treturn newAttribute;\n\n}\n\n/**\n * Deinterleaves all attributes on the given geometry.\n *\n * @param {BufferGeometry} geometry - The geometry to deinterleave.\n */\nfunction deinterleaveGeometry( geometry ) {\n\n\tconst attributes = geometry.attributes;\n\tconst morphTargets = geometry.morphTargets;\n\tconst attrMap = new Map();\n\n\tfor ( const key in attributes ) {\n\n\t\tconst attr = attributes[ key ];\n\t\tif ( attr.isInterleavedBufferAttribute ) {\n\n\t\t\tif ( ! attrMap.has( attr ) ) {\n\n\t\t\t\tattrMap.set( attr, deinterleaveAttribute( attr ) );\n\n\t\t\t}\n\n\t\t\tattributes[ key ] = attrMap.get( attr );\n\n\t\t}\n\n\t}\n\n\tfor ( const key in morphTargets ) {\n\n\t\tconst attr = morphTargets[ key ];\n\t\tif ( attr.isInterleavedBufferAttribute ) {\n\n\t\t\tif ( ! attrMap.has( attr ) ) {\n\n\t\t\t\tattrMap.set( attr, deinterleaveAttribute( attr ) );\n\n\t\t\t}\n\n\t\t\tmorphTargets[ key ] = attrMap.get( attr );\n\n\t\t}\n\n\t}\n\n}\n\n/**\n * Returns the amount of bytes used by all attributes to represent the geometry.\n *\n * @param {BufferGeometry} geometry - The geometry.\n * @return {number} The estimate bytes used.\n */\nfunction estimateBytesUsed( geometry ) {\n\n\t// Return the estimated memory used by this geometry in bytes\n\t// Calculate using itemSize, count, and BYTES_PER_ELEMENT to account\n\t// for InterleavedBufferAttributes.\n\tlet mem = 0;\n\tfor ( const name in geometry.attributes ) {\n\n\t\tconst attr = geometry.getAttribute( name );\n\t\tmem += attr.count * attr.itemSize * attr.array.BYTES_PER_ELEMENT;\n\n\t}\n\n\tconst indices = geometry.getIndex();\n\tmem += indices ? indices.count * indices.itemSize * indices.array.BYTES_PER_ELEMENT : 0;\n\treturn mem;\n\n}\n\n/**\n * Returns a new geometry with vertices for which all similar vertex attributes (within tolerance) are merged.\n *\n * @param {BufferGeometry} geometry - The geometry to merge vertices for.\n * @param {number} [tolerance=1e-4] - The tolerance value.\n * @return {BufferGeometry} - The new geometry with merged vertices.\n */\nfunction mergeVertices( geometry, tolerance = 1e-4 ) {\n\n\ttolerance = Math.max( tolerance, Number.EPSILON );\n\n\t// Generate an index buffer if the geometry doesn't have one, or optimize it\n\t// if it's already available.\n\tconst hashToIndex = {};\n\tconst indices = geometry.getIndex();\n\tconst positions = geometry.getAttribute( 'position' );\n\tconst vertexCount = indices ? indices.count : positions.count;\n\n\t// next value for triangle indices\n\tlet nextIndex = 0;\n\n\t// attributes and new attribute arrays\n\tconst attributeNames = Object.keys( geometry.attributes );\n\tconst tmpAttributes = {};\n\tconst tmpMorphAttributes = {};\n\tconst newIndices = [];\n\tconst getters = [ 'getX', 'getY', 'getZ', 'getW' ];\n\tconst setters = [ 'setX', 'setY', 'setZ', 'setW' ];\n\n\t// Initialize the arrays, allocating space conservatively. Extra\n\t// space will be trimmed in the last step.\n\tfor ( let i = 0, l = attributeNames.length; i < l; i ++ ) {\n\n\t\tconst name = attributeNames[ i ];\n\t\tconst attr = geometry.attributes[ name ];\n\n\t\ttmpAttributes[ name ] = new attr.constructor(\n\t\t\tnew attr.array.constructor( attr.count * attr.itemSize ),\n\t\t\tattr.itemSize,\n\t\t\tattr.normalized\n\t\t);\n\n\t\tconst morphAttributes = geometry.morphAttributes[ name ];\n\t\tif ( morphAttributes ) {\n\n\t\t\tif ( ! tmpMorphAttributes[ name ] ) tmpMorphAttributes[ name ] = [];\n\t\t\tmorphAttributes.forEach( ( morphAttr, i ) => {\n\n\t\t\t\tconst array = new morphAttr.array.constructor( morphAttr.count * morphAttr.itemSize );\n\t\t\t\ttmpMorphAttributes[ name ][ i ] = new morphAttr.constructor( array, morphAttr.itemSize, morphAttr.normalized );\n\n\t\t\t} );\n\n\t\t}\n\n\t}\n\n\t// convert the error tolerance to an amount of decimal places to truncate to\n\tconst halfTolerance = tolerance * 0.5;\n\tconst exponent = Math.log10( 1 / tolerance );\n\tconst hashMultiplier = Math.pow( 10, exponent );\n\tconst hashAdditive = halfTolerance * hashMultiplier;\n\tfor ( let i = 0; i < vertexCount; i ++ ) {\n\n\t\tconst index = indices ? indices.getX( i ) : i;\n\n\t\t// Generate a hash for the vertex attributes at the current index 'i'\n\t\tlet hash = '';\n\t\tfor ( let j = 0, l = attributeNames.length; j < l; j ++ ) {\n\n\t\t\tconst name = attributeNames[ j ];\n\t\t\tconst attribute = geometry.getAttribute( name );\n\t\t\tconst itemSize = attribute.itemSize;\n\n\t\t\tfor ( let k = 0; k < itemSize; k ++ ) {\n\n\t\t\t\t// double tilde truncates the decimal value\n\t\t\t\thash += `${ ~ ~ ( attribute[ getters[ k ] ]( index ) * hashMultiplier + hashAdditive ) },`;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Add another reference to the vertex if it's already\n\t\t// used by another index\n\t\tif ( hash in hashToIndex ) {\n\n\t\t\tnewIndices.push( hashToIndex[ hash ] );\n\n\t\t} else {\n\n\t\t\t// copy data to the new index in the temporary attributes\n\t\t\tfor ( let j = 0, l = attributeNames.length; j < l; j ++ ) {\n\n\t\t\t\tconst name = attributeNames[ j ];\n\t\t\t\tconst attribute = geometry.getAttribute( name );\n\t\t\t\tconst morphAttributes = geometry.morphAttributes[ name ];\n\t\t\t\tconst itemSize = attribute.itemSize;\n\t\t\t\tconst newArray = tmpAttributes[ name ];\n\t\t\t\tconst newMorphArrays = tmpMorphAttributes[ name ];\n\n\t\t\t\tfor ( let k = 0; k < itemSize; k ++ ) {\n\n\t\t\t\t\tconst getterFunc = getters[ k ];\n\t\t\t\t\tconst setterFunc = setters[ k ];\n\t\t\t\t\tnewArray[ setterFunc ]( nextIndex, attribute[ getterFunc ]( index ) );\n\n\t\t\t\t\tif ( morphAttributes ) {\n\n\t\t\t\t\t\tfor ( let m = 0, ml = morphAttributes.length; m < ml; m ++ ) {\n\n\t\t\t\t\t\t\tnewMorphArrays[ m ][ setterFunc ]( nextIndex, morphAttributes[ m ][ getterFunc ]( index ) );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\thashToIndex[ hash ] = nextIndex;\n\t\t\tnewIndices.push( nextIndex );\n\t\t\tnextIndex ++;\n\n\t\t}\n\n\t}\n\n\t// generate result BufferGeometry\n\tconst result = geometry.clone();\n\tfor ( const name in geometry.attributes ) {\n\n\t\tconst tmpAttribute = tmpAttributes[ name ];\n\n\t\tresult.setAttribute( name, new tmpAttribute.constructor(\n\t\t\ttmpAttribute.array.slice( 0, nextIndex * tmpAttribute.itemSize ),\n\t\t\ttmpAttribute.itemSize,\n\t\t\ttmpAttribute.normalized,\n\t\t) );\n\n\t\tif ( ! ( name in tmpMorphAttributes ) ) continue;\n\n\t\tfor ( let j = 0; j < tmpMorphAttributes[ name ].length; j ++ ) {\n\n\t\t\tconst tmpMorphAttribute = tmpMorphAttributes[ name ][ j ];\n\n\t\t\tresult.morphAttributes[ name ][ j ] = new tmpMorphAttribute.constructor(\n\t\t\t\ttmpMorphAttribute.array.slice( 0, nextIndex * tmpMorphAttribute.itemSize ),\n\t\t\t\ttmpMorphAttribute.itemSize,\n\t\t\t\ttmpMorphAttribute.normalized,\n\t\t\t);\n\n\t\t}\n\n\t}\n\n\t// indices\n\n\tresult.setIndex( newIndices );\n\n\treturn result;\n\n}\n\n/**\n * Returns a new indexed geometry based on `TrianglesDrawMode` draw mode.\n * This mode corresponds to the `gl.TRIANGLES` primitive in WebGL.\n *\n * @param {BufferGeometry} geometry - The geometry to convert.\n * @param {number} drawMode - The current draw mode.\n * @return {BufferGeometry} The new geometry using `TrianglesDrawMode`.\n */\nfunction toTrianglesDrawMode( geometry, drawMode ) {\n\n\tif ( drawMode === TrianglesDrawMode ) {\n\n\t\tconsole.warn( 'THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles.' );\n\t\treturn geometry;\n\n\t}\n\n\tif ( drawMode === TriangleFanDrawMode || drawMode === TriangleStripDrawMode ) {\n\n\t\tlet index = geometry.getIndex();\n\n\t\t// generate index if not present\n\n\t\tif ( index === null ) {\n\n\t\t\tconst indices = [];\n\n\t\t\tconst position = geometry.getAttribute( 'position' );\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tfor ( let i = 0; i < position.count; i ++ ) {\n\n\t\t\t\t\tindices.push( i );\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.setIndex( indices );\n\t\t\t\tindex = geometry.getIndex();\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometryUtils.toTrianglesDrawMode(): Undefined position attribute. Processing not possible.' );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tconst numberOfTriangles = index.count - 2;\n\t\tconst newIndices = [];\n\n\t\tif ( drawMode === TriangleFanDrawMode ) {\n\n\t\t\t// gl.TRIANGLE_FAN\n\n\t\t\tfor ( let i = 1; i <= numberOfTriangles; i ++ ) {\n\n\t\t\t\tnewIndices.push( index.getX( 0 ) );\n\t\t\t\tnewIndices.push( index.getX( i ) );\n\t\t\t\tnewIndices.push( index.getX( i + 1 ) );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// gl.TRIANGLE_STRIP\n\n\t\t\tfor ( let i = 0; i < numberOfTriangles; i ++ ) {\n\n\t\t\t\tif ( i % 2 === 0 ) {\n\n\t\t\t\t\tnewIndices.push( index.getX( i ) );\n\t\t\t\t\tnewIndices.push( index.getX( i + 1 ) );\n\t\t\t\t\tnewIndices.push( index.getX( i + 2 ) );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tnewIndices.push( index.getX( i + 2 ) );\n\t\t\t\t\tnewIndices.push( index.getX( i + 1 ) );\n\t\t\t\t\tnewIndices.push( index.getX( i ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( ( newIndices.length / 3 ) !== numberOfTriangles ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unable to generate correct amount of triangles.' );\n\n\t\t}\n\n\t\t// build final geometry\n\n\t\tconst newGeometry = geometry.clone();\n\t\tnewGeometry.setIndex( newIndices );\n\t\tnewGeometry.clearGroups();\n\n\t\treturn newGeometry;\n\n\t} else {\n\n\t\tconsole.error( 'THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unknown draw mode:', drawMode );\n\t\treturn geometry;\n\n\t}\n\n}\n\n/**\n * Calculates the morphed attributes of a morphed/skinned BufferGeometry.\n *\n * Helpful for Raytracing or Decals (i.e. a `DecalGeometry` applied to a morphed Object with a `BufferGeometry`\n * will use the original `BufferGeometry`, not the morphed/skinned one, generating an incorrect result.\n * Using this function to create a shadow `Object3`D the `DecalGeometry` can be correctly generated).\n *\n * @param {Mesh|Line|Points} object - The 3D object to compute morph attributes for.\n * @return {Object} An object with original position/normal attributes and morphed ones.\n */\nfunction computeMorphedAttributes( object ) {\n\n\tconst _vA = new Vector3();\n\tconst _vB = new Vector3();\n\tconst _vC = new Vector3();\n\n\tconst _tempA = new Vector3();\n\tconst _tempB = new Vector3();\n\tconst _tempC = new Vector3();\n\n\tconst _morphA = new Vector3();\n\tconst _morphB = new Vector3();\n\tconst _morphC = new Vector3();\n\n\tfunction _calculateMorphedAttributeData(\n\t\tobject,\n\t\tattribute,\n\t\tmorphAttribute,\n\t\tmorphTargetsRelative,\n\t\ta,\n\t\tb,\n\t\tc,\n\t\tmodifiedAttributeArray\n\t) {\n\n\t\t_vA.fromBufferAttribute( attribute, a );\n\t\t_vB.fromBufferAttribute( attribute, b );\n\t\t_vC.fromBufferAttribute( attribute, c );\n\n\t\tconst morphInfluences = object.morphTargetInfluences;\n\n\t\tif ( morphAttribute && morphInfluences ) {\n\n\t\t\t_morphA.set( 0, 0, 0 );\n\t\t\t_morphB.set( 0, 0, 0 );\n\t\t\t_morphC.set( 0, 0, 0 );\n\n\t\t\tfor ( let i = 0, il = morphAttribute.length; i < il; i ++ ) {\n\n\t\t\t\tconst influence = morphInfluences[ i ];\n\t\t\t\tconst morph = morphAttribute[ i ];\n\n\t\t\t\tif ( influence === 0 ) continue;\n\n\t\t\t\t_tempA.fromBufferAttribute( morph, a );\n\t\t\t\t_tempB.fromBufferAttribute( morph, b );\n\t\t\t\t_tempC.fromBufferAttribute( morph, c );\n\n\t\t\t\tif ( morphTargetsRelative ) {\n\n\t\t\t\t\t_morphA.addScaledVector( _tempA, influence );\n\t\t\t\t\t_morphB.addScaledVector( _tempB, influence );\n\t\t\t\t\t_morphC.addScaledVector( _tempC, influence );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_morphA.addScaledVector( _tempA.sub( _vA ), influence );\n\t\t\t\t\t_morphB.addScaledVector( _tempB.sub( _vB ), influence );\n\t\t\t\t\t_morphC.addScaledVector( _tempC.sub( _vC ), influence );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_vA.add( _morphA );\n\t\t\t_vB.add( _morphB );\n\t\t\t_vC.add( _morphC );\n\n\t\t}\n\n\t\tif ( object.isSkinnedMesh ) {\n\n\t\t\tobject.applyBoneTransform( a, _vA );\n\t\t\tobject.applyBoneTransform( b, _vB );\n\t\t\tobject.applyBoneTransform( c, _vC );\n\n\t\t}\n\n\t\tmodifiedAttributeArray[ a * 3 + 0 ] = _vA.x;\n\t\tmodifiedAttributeArray[ a * 3 + 1 ] = _vA.y;\n\t\tmodifiedAttributeArray[ a * 3 + 2 ] = _vA.z;\n\t\tmodifiedAttributeArray[ b * 3 + 0 ] = _vB.x;\n\t\tmodifiedAttributeArray[ b * 3 + 1 ] = _vB.y;\n\t\tmodifiedAttributeArray[ b * 3 + 2 ] = _vB.z;\n\t\tmodifiedAttributeArray[ c * 3 + 0 ] = _vC.x;\n\t\tmodifiedAttributeArray[ c * 3 + 1 ] = _vC.y;\n\t\tmodifiedAttributeArray[ c * 3 + 2 ] = _vC.z;\n\n\t}\n\n\tconst geometry = object.geometry;\n\tconst material = object.material;\n\n\tlet a, b, c;\n\tconst index = geometry.index;\n\tconst positionAttribute = geometry.attributes.position;\n\tconst morphPosition = geometry.morphAttributes.position;\n\tconst morphTargetsRelative = geometry.morphTargetsRelative;\n\tconst normalAttribute = geometry.attributes.normal;\n\tconst morphNormal = geometry.morphAttributes.normal;\n\n\tconst groups = geometry.groups;\n\tconst drawRange = geometry.drawRange;\n\tlet i, j, il, jl;\n\tlet group;\n\tlet start, end;\n\n\tconst modifiedPosition = new Float32Array( positionAttribute.count * positionAttribute.itemSize );\n\tconst modifiedNormal = new Float32Array( normalAttribute.count * normalAttribute.itemSize );\n\n\tif ( index !== null ) {\n\n\t\t// indexed buffer geometry\n\n\t\tif ( Array.isArray( material ) ) {\n\n\t\t\tfor ( i = 0, il = groups.length; i < il; i ++ ) {\n\n\t\t\t\tgroup = groups[ i ];\n\n\t\t\t\tstart = Math.max( group.start, drawRange.start );\n\t\t\t\tend = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );\n\n\t\t\t\tfor ( j = start, jl = end; j < jl; j += 3 ) {\n\n\t\t\t\t\ta = index.getX( j );\n\t\t\t\t\tb = index.getX( j + 1 );\n\t\t\t\t\tc = index.getX( j + 2 );\n\n\t\t\t\t\t_calculateMorphedAttributeData(\n\t\t\t\t\t\tobject,\n\t\t\t\t\t\tpositionAttribute,\n\t\t\t\t\t\tmorphPosition,\n\t\t\t\t\t\tmorphTargetsRelative,\n\t\t\t\t\t\ta, b, c,\n\t\t\t\t\t\tmodifiedPosition\n\t\t\t\t\t);\n\n\t\t\t\t\t_calculateMorphedAttributeData(\n\t\t\t\t\t\tobject,\n\t\t\t\t\t\tnormalAttribute,\n\t\t\t\t\t\tmorphNormal,\n\t\t\t\t\t\tmorphTargetsRelative,\n\t\t\t\t\t\ta, b, c,\n\t\t\t\t\t\tmodifiedNormal\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tstart = Math.max( 0, drawRange.start );\n\t\t\tend = Math.min( index.count, ( drawRange.start + drawRange.count ) );\n\n\t\t\tfor ( i = start, il = end; i < il; i += 3 ) {\n\n\t\t\t\ta = index.getX( i );\n\t\t\t\tb = index.getX( i + 1 );\n\t\t\t\tc = index.getX( i + 2 );\n\n\t\t\t\t_calculateMorphedAttributeData(\n\t\t\t\t\tobject,\n\t\t\t\t\tpositionAttribute,\n\t\t\t\t\tmorphPosition,\n\t\t\t\t\tmorphTargetsRelative,\n\t\t\t\t\ta, b, c,\n\t\t\t\t\tmodifiedPosition\n\t\t\t\t);\n\n\t\t\t\t_calculateMorphedAttributeData(\n\t\t\t\t\tobject,\n\t\t\t\t\tnormalAttribute,\n\t\t\t\t\tmorphNormal,\n\t\t\t\t\tmorphTargetsRelative,\n\t\t\t\t\ta, b, c,\n\t\t\t\t\tmodifiedNormal\n\t\t\t\t);\n\n\t\t\t}\n\n\t\t}\n\n\t} else {\n\n\t\t// non-indexed buffer geometry\n\n\t\tif ( Array.isArray( material ) ) {\n\n\t\t\tfor ( i = 0, il = groups.length; i < il; i ++ ) {\n\n\t\t\t\tgroup = groups[ i ];\n\n\t\t\t\tstart = Math.max( group.start, drawRange.start );\n\t\t\t\tend = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );\n\n\t\t\t\tfor ( j = start, jl = end; j < jl; j += 3 ) {\n\n\t\t\t\t\ta = j;\n\t\t\t\t\tb = j + 1;\n\t\t\t\t\tc = j + 2;\n\n\t\t\t\t\t_calculateMorphedAttributeData(\n\t\t\t\t\t\tobject,\n\t\t\t\t\t\tpositionAttribute,\n\t\t\t\t\t\tmorphPosition,\n\t\t\t\t\t\tmorphTargetsRelative,\n\t\t\t\t\t\ta, b, c,\n\t\t\t\t\t\tmodifiedPosition\n\t\t\t\t\t);\n\n\t\t\t\t\t_calculateMorphedAttributeData(\n\t\t\t\t\t\tobject,\n\t\t\t\t\t\tnormalAttribute,\n\t\t\t\t\t\tmorphNormal,\n\t\t\t\t\t\tmorphTargetsRelative,\n\t\t\t\t\t\ta, b, c,\n\t\t\t\t\t\tmodifiedNormal\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tstart = Math.max( 0, drawRange.start );\n\t\t\tend = Math.min( positionAttribute.count, ( drawRange.start + drawRange.count ) );\n\n\t\t\tfor ( i = start, il = end; i < il; i += 3 ) {\n\n\t\t\t\ta = i;\n\t\t\t\tb = i + 1;\n\t\t\t\tc = i + 2;\n\n\t\t\t\t_calculateMorphedAttributeData(\n\t\t\t\t\tobject,\n\t\t\t\t\tpositionAttribute,\n\t\t\t\t\tmorphPosition,\n\t\t\t\t\tmorphTargetsRelative,\n\t\t\t\t\ta, b, c,\n\t\t\t\t\tmodifiedPosition\n\t\t\t\t);\n\n\t\t\t\t_calculateMorphedAttributeData(\n\t\t\t\t\tobject,\n\t\t\t\t\tnormalAttribute,\n\t\t\t\t\tmorphNormal,\n\t\t\t\t\tmorphTargetsRelative,\n\t\t\t\t\ta, b, c,\n\t\t\t\t\tmodifiedNormal\n\t\t\t\t);\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tconst morphedPositionAttribute = new Float32BufferAttribute( modifiedPosition, 3 );\n\tconst morphedNormalAttribute = new Float32BufferAttribute( modifiedNormal, 3 );\n\n\treturn {\n\n\t\tpositionAttribute: positionAttribute,\n\t\tnormalAttribute: normalAttribute,\n\t\tmorphedPositionAttribute: morphedPositionAttribute,\n\t\tmorphedNormalAttribute: morphedNormalAttribute\n\n\t};\n\n}\n\n/**\n * Merges the {@link BufferGeometry#groups} for the given geometry.\n *\n * @param {BufferGeometry} geometry - The geometry to modify.\n * @return {BufferGeometry} - The updated geometry\n */\nfunction mergeGroups( geometry ) {\n\n\tif ( geometry.groups.length === 0 ) {\n\n\t\tconsole.warn( 'THREE.BufferGeometryUtils.mergeGroups(): No groups are defined. Nothing to merge.' );\n\t\treturn geometry;\n\n\t}\n\n\tlet groups = geometry.groups;\n\n\t// sort groups by material index\n\n\tgroups = groups.sort( ( a, b ) => {\n\n\t\tif ( a.materialIndex !== b.materialIndex ) return a.materialIndex - b.materialIndex;\n\n\t\treturn a.start - b.start;\n\n\t} );\n\n\t// create index for non-indexed geometries\n\n\tif ( geometry.getIndex() === null ) {\n\n\t\tconst positionAttribute = geometry.getAttribute( 'position' );\n\t\tconst indices = [];\n\n\t\tfor ( let i = 0; i < positionAttribute.count; i += 3 ) {\n\n\t\t\tindices.push( i, i + 1, i + 2 );\n\n\t\t}\n\n\t\tgeometry.setIndex( indices );\n\n\t}\n\n\t// sort index\n\n\tconst index = geometry.getIndex();\n\n\tconst newIndices = [];\n\n\tfor ( let i = 0; i < groups.length; i ++ ) {\n\n\t\tconst group = groups[ i ];\n\n\t\tconst groupStart = group.start;\n\t\tconst groupLength = groupStart + group.count;\n\n\t\tfor ( let j = groupStart; j < groupLength; j ++ ) {\n\n\t\t\tnewIndices.push( index.getX( j ) );\n\n\t\t}\n\n\t}\n\n\tgeometry.dispose(); // Required to force buffer recreation\n\tgeometry.setIndex( newIndices );\n\n\t// update groups indices\n\n\tlet start = 0;\n\n\tfor ( let i = 0; i < groups.length; i ++ ) {\n\n\t\tconst group = groups[ i ];\n\n\t\tgroup.start = start;\n\t\tstart += group.count;\n\n\t}\n\n\t// merge groups\n\n\tlet currentGroup = groups[ 0 ];\n\n\tgeometry.groups = [ currentGroup ];\n\n\tfor ( let i = 1; i < groups.length; i ++ ) {\n\n\t\tconst group = groups[ i ];\n\n\t\tif ( currentGroup.materialIndex === group.materialIndex ) {\n\n\t\t\tcurrentGroup.count += group.count;\n\n\t\t} else {\n\n\t\t\tcurrentGroup = group;\n\t\t\tgeometry.groups.push( currentGroup );\n\n\t\t}\n\n\t}\n\n\treturn geometry;\n\n}\n\n/**\n * Modifies the supplied geometry if it is non-indexed, otherwise creates a new,\n * non-indexed geometry. Returns the geometry with smooth normals everywhere except\n * faces that meet at an angle greater than the crease angle.\n *\n * @param {BufferGeometry} geometry - The geometry to modify.\n * @param {number} [creaseAngle=Math.PI/3] - The crease angle in radians.\n * @return {BufferGeometry} - The updated geometry\n */\nfunction toCreasedNormals( geometry, creaseAngle = Math.PI / 3 /* 60 degrees */ ) {\n\n\tconst creaseDot = Math.cos( creaseAngle );\n\tconst hashMultiplier = ( 1 + 1e-10 ) * 1e2;\n\n\t// reusable vectors\n\tconst verts = [ new Vector3(), new Vector3(), new Vector3() ];\n\tconst tempVec1 = new Vector3();\n\tconst tempVec2 = new Vector3();\n\tconst tempNorm = new Vector3();\n\tconst tempNorm2 = new Vector3();\n\n\t// hashes a vector\n\tfunction hashVertex( v ) {\n\n\t\tconst x = ~ ~ ( v.x * hashMultiplier );\n\t\tconst y = ~ ~ ( v.y * hashMultiplier );\n\t\tconst z = ~ ~ ( v.z * hashMultiplier );\n\t\treturn `${x},${y},${z}`;\n\n\t}\n\n\t// BufferGeometry.toNonIndexed() warns if the geometry is non-indexed\n\t// and returns the original geometry\n\tconst resultGeometry = geometry.index ? geometry.toNonIndexed() : geometry;\n\tconst posAttr = resultGeometry.attributes.position;\n\tconst vertexMap = {};\n\n\t// find all the normals shared by commonly located vertices\n\tfor ( let i = 0, l = posAttr.count / 3; i < l; i ++ ) {\n\n\t\tconst i3 = 3 * i;\n\t\tconst a = verts[ 0 ].fromBufferAttribute( posAttr, i3 + 0 );\n\t\tconst b = verts[ 1 ].fromBufferAttribute( posAttr, i3 + 1 );\n\t\tconst c = verts[ 2 ].fromBufferAttribute( posAttr, i3 + 2 );\n\n\t\ttempVec1.subVectors( c, b );\n\t\ttempVec2.subVectors( a, b );\n\n\t\t// add the normal to the map for all vertices\n\t\tconst normal = new Vector3().crossVectors( tempVec1, tempVec2 ).normalize();\n\t\tfor ( let n = 0; n < 3; n ++ ) {\n\n\t\t\tconst vert = verts[ n ];\n\t\t\tconst hash = hashVertex( vert );\n\t\t\tif ( ! ( hash in vertexMap ) ) {\n\n\t\t\t\tvertexMap[ hash ] = [];\n\n\t\t\t}\n\n\t\t\tvertexMap[ hash ].push( normal );\n\n\t\t}\n\n\t}\n\n\t// average normals from all vertices that share a common location if they are within the\n\t// provided crease threshold\n\tconst normalArray = new Float32Array( posAttr.count * 3 );\n\tconst normAttr = new BufferAttribute( normalArray, 3, false );\n\tfor ( let i = 0, l = posAttr.count / 3; i < l; i ++ ) {\n\n\t\t// get the face normal for this vertex\n\t\tconst i3 = 3 * i;\n\t\tconst a = verts[ 0 ].fromBufferAttribute( posAttr, i3 + 0 );\n\t\tconst b = verts[ 1 ].fromBufferAttribute( posAttr, i3 + 1 );\n\t\tconst c = verts[ 2 ].fromBufferAttribute( posAttr, i3 + 2 );\n\n\t\ttempVec1.subVectors( c, b );\n\t\ttempVec2.subVectors( a, b );\n\n\t\ttempNorm.crossVectors( tempVec1, tempVec2 ).normalize();\n\n\t\t// average all normals that meet the threshold and set the normal value\n\t\tfor ( let n = 0; n < 3; n ++ ) {\n\n\t\t\tconst vert = verts[ n ];\n\t\t\tconst hash = hashVertex( vert );\n\t\t\tconst otherNormals = vertexMap[ hash ];\n\t\t\ttempNorm2.set( 0, 0, 0 );\n\n\t\t\tfor ( let k = 0, lk = otherNormals.length; k < lk; k ++ ) {\n\n\t\t\t\tconst otherNorm = otherNormals[ k ];\n\t\t\t\tif ( tempNorm.dot( otherNorm ) > creaseDot ) {\n\n\t\t\t\t\ttempNorm2.add( otherNorm );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\ttempNorm2.normalize();\n\t\t\tnormAttr.setXYZ( i3 + n, tempNorm2.x, tempNorm2.y, tempNorm2.z );\n\n\t\t}\n\n\t}\n\n\tresultGeometry.setAttribute( 'normal', normAttr );\n\treturn resultGeometry;\n\n}\n\nexport {\n\tcomputeMikkTSpaceTangents,\n\tmergeGeometries,\n\tmergeAttributes,\n\tdeepCloneAttribute,\n\tdeinterleaveAttribute,\n\tdeinterleaveGeometry,\n\tinterleaveAttributes,\n\testimateBytesUsed,\n\tmergeVertices,\n\ttoTrianglesDrawMode,\n\tcomputeMorphedAttributes,\n\tmergeGroups,\n\ttoCreasedNormals\n};\n","import {\n\tAnimationClip,\n\tAnimationMixer,\n\tMatrix4,\n\tQuaternion,\n\tQuaternionKeyframeTrack,\n\tSkeletonHelper,\n\tVector3,\n\tVectorKeyframeTrack\n} from 'three';\n\n/**\n * @module SkeletonUtils\n * @three_import import * as SkeletonUtils from 'three/addons/utils/SkeletonUtils.js';\n */\n\nfunction getBoneName( bone, options ) {\n\n\tif ( options.getBoneName !== undefined ) {\n\n\t\treturn options.getBoneName( bone );\n\n\t}\n\n\treturn options.names[ bone.name ];\n\n}\n\n/**\n * Retargets the skeleton from the given source to the target.\n *\n * Both `target` and `source` can be a 3D object with a skeleton property (e.g. a skinned mesh)\n * or a {@link Skeleton} directly.\n *\n * @param {Object3D|Skeleton} target - The target object.\n * @param {Object3D|Skeleton} source - The source object.\n * @param {module:SkeletonUtils~RetargetOptions} options - The options.\n */\nfunction retarget( target, source, options = {} ) {\n\n\tconst quat = new Quaternion(),\n\t\tscale = new Vector3(),\n\t\trelativeMatrix = new Matrix4(),\n\t\tglobalMatrix = new Matrix4();\n\n\toptions.preserveBoneMatrix = options.preserveBoneMatrix !== undefined ? options.preserveBoneMatrix : true;\n\toptions.preserveBonePositions = options.preserveBonePositions !== undefined ? options.preserveBonePositions : true;\n\toptions.useTargetMatrix = options.useTargetMatrix !== undefined ? options.useTargetMatrix : false;\n\toptions.hip = options.hip !== undefined ? options.hip : 'hip';\n\toptions.hipInfluence = options.hipInfluence !== undefined ? options.hipInfluence : new Vector3( 1, 1, 1 );\n\toptions.scale = options.scale !== undefined ? options.scale : 1;\n\toptions.names = options.names || {};\n\n\tconst sourceBones = source.isObject3D ? source.skeleton.bones : getBones( source ),\n\t\tbones = target.isObject3D ? target.skeleton.bones : getBones( target );\n\n\tlet bone, name, boneTo,\n\t\tbonesPosition;\n\n\t// reset bones\n\n\tif ( target.isObject3D ) {\n\n\t\ttarget.skeleton.pose();\n\n\t} else {\n\n\t\toptions.useTargetMatrix = true;\n\t\toptions.preserveBoneMatrix = false;\n\n\t}\n\n\tif ( options.preserveBonePositions ) {\n\n\t\tbonesPosition = [];\n\n\t\tfor ( let i = 0; i < bones.length; i ++ ) {\n\n\t\t\tbonesPosition.push( bones[ i ].position.clone() );\n\n\t\t}\n\n\t}\n\n\tif ( options.preserveBoneMatrix ) {\n\n\t\t// reset matrix\n\n\t\ttarget.updateMatrixWorld();\n\n\t\ttarget.matrixWorld.identity();\n\n\t\t// reset children matrix\n\n\t\tfor ( let i = 0; i < target.children.length; ++ i ) {\n\n\t\t\ttarget.children[ i ].updateMatrixWorld( true );\n\n\t\t}\n\n\t}\n\n\tfor ( let i = 0; i < bones.length; ++ i ) {\n\n\t\tbone = bones[ i ];\n\t\tname = getBoneName( bone, options );\n\n\t\tboneTo = getBoneByName( name, sourceBones );\n\n\t\tglobalMatrix.copy( bone.matrixWorld );\n\n\t\tif ( boneTo ) {\n\n\t\t\tboneTo.updateMatrixWorld();\n\n\t\t\tif ( options.useTargetMatrix ) {\n\n\t\t\t\trelativeMatrix.copy( boneTo.matrixWorld );\n\n\t\t\t} else {\n\n\t\t\t\trelativeMatrix.copy( target.matrixWorld ).invert();\n\t\t\t\trelativeMatrix.multiply( boneTo.matrixWorld );\n\n\t\t\t}\n\n\t\t\t// ignore scale to extract rotation\n\n\t\t\tscale.setFromMatrixScale( relativeMatrix );\n\t\t\trelativeMatrix.scale( scale.set( 1 / scale.x, 1 / scale.y, 1 / scale.z ) );\n\n\t\t\t// apply to global matrix\n\n\t\t\tglobalMatrix.makeRotationFromQuaternion( quat.setFromRotationMatrix( relativeMatrix ) );\n\n\t\t\tif ( target.isObject3D ) {\n\n\t\t\t\tif ( options.localOffsets ) {\n\n\t\t\t\t\tif ( options.localOffsets[ bone.name ] ) {\n\n\t\t\t\t\t\tglobalMatrix.multiply( options.localOffsets[ bone.name ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tglobalMatrix.copyPosition( relativeMatrix );\n\n\t\t}\n\n\t\tif ( name === options.hip ) {\n\n\t\t\tglobalMatrix.elements[ 12 ] *= options.scale * options.hipInfluence.x;\n\t\t\tglobalMatrix.elements[ 13 ] *= options.scale * options.hipInfluence.y;\n\t\t\tglobalMatrix.elements[ 14 ] *= options.scale * options.hipInfluence.z;\n\n\t\t\tif ( options.hipPosition !== undefined ) {\n\n\t\t\t\tglobalMatrix.elements[ 12 ] += options.hipPosition.x * options.scale;\n\t\t\t\tglobalMatrix.elements[ 13 ] += options.hipPosition.y * options.scale;\n\t\t\t\tglobalMatrix.elements[ 14 ] += options.hipPosition.z * options.scale;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( bone.parent ) {\n\n\t\t\tbone.matrix.copy( bone.parent.matrixWorld ).invert();\n\t\t\tbone.matrix.multiply( globalMatrix );\n\n\t\t} else {\n\n\t\t\tbone.matrix.copy( globalMatrix );\n\n\t\t}\n\n\t\tbone.matrix.decompose( bone.position, bone.quaternion, bone.scale );\n\n\t\tbone.updateMatrixWorld();\n\n\t}\n\n\tif ( options.preserveBonePositions ) {\n\n\t\tfor ( let i = 0; i < bones.length; ++ i ) {\n\n\t\t\tbone = bones[ i ];\n\t\t\tname = getBoneName( bone, options ) || bone.name;\n\n\t\t\tif ( name !== options.hip ) {\n\n\t\t\t\tbone.position.copy( bonesPosition[ i ] );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tif ( options.preserveBoneMatrix ) {\n\n\t\t// restore matrix\n\n\t\ttarget.updateMatrixWorld( true );\n\n\t}\n\n}\n\n/**\n * Retargets the animation clip of the source to the target 3D object.\n *\n * The `source` can be a 3D object with a skeleton property (e.g. a skinned mesh)\n * or a {@link Skeleton} directly.\n *\n * @param {Object3D} target - The target 3D object. Must have a `skeleton` property.\n * @param {Object3D|Skeleton} source - The source object.\n * @param {AnimationClip} clip - The animation clip.\n * @param {module:SkeletonUtils~RetargetOptions} options - The options.\n * @return {AnimationClip} The retargeted animation clip.\n */\nfunction retargetClip( target, source, clip, options = {} ) {\n\n\toptions.useFirstFramePosition = options.useFirstFramePosition !== undefined ? options.useFirstFramePosition : false;\n\n\t// Calculate the fps from the source clip based on the track with the most frames, unless fps is already provided.\n\toptions.fps = options.fps !== undefined ? options.fps : ( Math.max( ...clip.tracks.map( track => track.times.length ) ) / clip.duration );\n\toptions.names = options.names || [];\n\n\tif ( ! source.isObject3D ) {\n\n\t\tsource = getHelperFromSkeleton( source );\n\n\t}\n\n\tconst numFrames = Math.round( clip.duration * ( options.fps / 1000 ) * 1000 ),\n\t\tdelta = clip.duration / ( numFrames - 1 ),\n\t\tconvertedTracks = [],\n\t\tmixer = new AnimationMixer( source ),\n\t\tbones = getBones( target.skeleton ),\n\t\tboneDatas = [];\n\n\tlet positionOffset,\n\t\tbone, boneTo, boneData,\n\t\tname;\n\n\tmixer.clipAction( clip ).play();\n\n\t// trim\n\n\tlet start = 0, end = numFrames;\n\n\tif ( options.trim !== undefined ) {\n\n\t\tstart = Math.round( options.trim[ 0 ] * options.fps );\n\t\tend = Math.min( Math.round( options.trim[ 1 ] * options.fps ), numFrames ) - start;\n\n\t\tmixer.update( options.trim[ 0 ] );\n\n\t} else {\n\n\t\tmixer.update( 0 );\n\n\t}\n\n\tsource.updateMatrixWorld();\n\n\t//\n\n\tfor ( let frame = 0; frame < end; ++ frame ) {\n\n\t\tconst time = frame * delta;\n\n\t\tretarget( target, source, options );\n\n\t\tfor ( let j = 0; j < bones.length; ++ j ) {\n\n\t\t\tbone = bones[ j ];\n\t\t\tname = getBoneName( bone, options ) || bone.name;\n\t\t\tboneTo = getBoneByName( name, source.skeleton );\n\n\t\t\tif ( boneTo ) {\n\n\t\t\t\tboneData = boneDatas[ j ] = boneDatas[ j ] || { bone: bone };\n\n\t\t\t\tif ( options.hip === name ) {\n\n\t\t\t\t\tif ( ! boneData.pos ) {\n\n\t\t\t\t\t\tboneData.pos = {\n\t\t\t\t\t\t\ttimes: new Float32Array( end ),\n\t\t\t\t\t\t\tvalues: new Float32Array( end * 3 )\n\t\t\t\t\t\t};\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( options.useFirstFramePosition ) {\n\n\t\t\t\t\t\tif ( frame === 0 ) {\n\n\t\t\t\t\t\t\tpositionOffset = bone.position.clone();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbone.position.sub( positionOffset );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tboneData.pos.times[ frame ] = time;\n\n\t\t\t\t\tbone.position.toArray( boneData.pos.values, frame * 3 );\n\n\t\t\t\t}\n\n\t\t\t\tif ( ! boneData.quat ) {\n\n\t\t\t\t\tboneData.quat = {\n\t\t\t\t\t\ttimes: new Float32Array( end ),\n\t\t\t\t\t\tvalues: new Float32Array( end * 4 )\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\tboneData.quat.times[ frame ] = time;\n\n\t\t\t\tbone.quaternion.toArray( boneData.quat.values, frame * 4 );\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( frame === end - 2 ) {\n\n\t\t\t// last mixer update before final loop iteration\n\t\t\t// make sure we do not go over or equal to clip duration\n\t\t\tmixer.update( delta - 0.0000001 );\n\n\t\t} else {\n\n\t\t\tmixer.update( delta );\n\n\t\t}\n\n\t\tsource.updateMatrixWorld();\n\n\t}\n\n\tfor ( let i = 0; i < boneDatas.length; ++ i ) {\n\n\t\tboneData = boneDatas[ i ];\n\n\t\tif ( boneData ) {\n\n\t\t\tif ( boneData.pos ) {\n\n\t\t\t\tconvertedTracks.push( new VectorKeyframeTrack(\n\t\t\t\t\t'.bones[' + boneData.bone.name + '].position',\n\t\t\t\t\tboneData.pos.times,\n\t\t\t\t\tboneData.pos.values\n\t\t\t\t) );\n\n\t\t\t}\n\n\t\t\tconvertedTracks.push( new QuaternionKeyframeTrack(\n\t\t\t\t'.bones[' + boneData.bone.name + '].quaternion',\n\t\t\t\tboneData.quat.times,\n\t\t\t\tboneData.quat.values\n\t\t\t) );\n\n\t\t}\n\n\t}\n\n\tmixer.uncacheAction( clip );\n\n\treturn new AnimationClip( clip.name, - 1, convertedTracks );\n\n}\n\n/**\n * Clones the given 3D object and its descendants, ensuring that any `SkinnedMesh` instances are\n * correctly associated with their bones. Bones are also cloned, and must be descendants of the\n * object passed to this method. Other data, like geometries and materials, are reused by reference.\n *\n * @param {Object3D} source - The 3D object to clone.\n * @return {Object3D} The cloned 3D object.\n */\nfunction clone( source ) {\n\n\tconst sourceLookup = new Map();\n\tconst cloneLookup = new Map();\n\n\tconst clone = source.clone();\n\n\tparallelTraverse( source, clone, function ( sourceNode, clonedNode ) {\n\n\t\tsourceLookup.set( clonedNode, sourceNode );\n\t\tcloneLookup.set( sourceNode, clonedNode );\n\n\t} );\n\n\tclone.traverse( function ( node ) {\n\n\t\tif ( ! node.isSkinnedMesh ) return;\n\n\t\tconst clonedMesh = node;\n\t\tconst sourceMesh = sourceLookup.get( node );\n\t\tconst sourceBones = sourceMesh.skeleton.bones;\n\n\t\tclonedMesh.skeleton = sourceMesh.skeleton.clone();\n\t\tclonedMesh.bindMatrix.copy( sourceMesh.bindMatrix );\n\n\t\tclonedMesh.skeleton.bones = sourceBones.map( function ( bone ) {\n\n\t\t\treturn cloneLookup.get( bone );\n\n\t\t} );\n\n\t\tclonedMesh.bind( clonedMesh.skeleton, clonedMesh.bindMatrix );\n\n\t} );\n\n\treturn clone;\n\n}\n\n// internal helper\n\nfunction getBoneByName( name, skeleton ) {\n\n\tfor ( let i = 0, bones = getBones( skeleton ); i < bones.length; i ++ ) {\n\n\t\tif ( name === bones[ i ].name )\n\n\t\t\treturn bones[ i ];\n\n\t}\n\n}\n\nfunction getBones( skeleton ) {\n\n\treturn Array.isArray( skeleton ) ? skeleton : skeleton.bones;\n\n}\n\n\nfunction getHelperFromSkeleton( skeleton ) {\n\n\tconst source = new SkeletonHelper( skeleton.bones[ 0 ] );\n\tsource.skeleton = skeleton;\n\n\treturn source;\n\n}\n\nfunction parallelTraverse( a, b, callback ) {\n\n\tcallback( a, b );\n\n\tfor ( let i = 0; i < a.children.length; i ++ ) {\n\n\t\tparallelTraverse( a.children[ i ], b.children[ i ], callback );\n\n\t}\n\n}\n\n/**\n * Retarget options of `SkeletonUtils`.\n *\n * @typedef {Object} module:SkeletonUtils~RetargetOptions\n * @property {boolean} [useFirstFramePosition=false] - Whether to use the position of the first frame or not.\n * @property {number} [fps] - The FPS of the clip.\n * @property {Object<string,string>} [names] - A dictionary for mapping target to source bone names.\n * @property {function(string):string} [getBoneName] - A function for mapping bone names. Alternative to `names`.\n * @property {Array<number>} [trim] - Whether to trim the clip or not. If set the array should hold two values for the start and end.\n * @property {boolean} [preserveBoneMatrix=true] - Whether to preserve bone matrices or not.\n * @property {boolean} [preserveBonePositions=true] - Whether to preserve bone positions or not.\n * @property {boolean} [useTargetMatrix=false] - Whether to use the target matrix or not.\n * @property {string} [hip='hip'] - The name of the source's hip bone.\n * @property {Vector3} [hipInfluence=(1,1,1)] - The hip influence.\n * @property {number} [scale=1] - The scale.\n * @property {Object<string,Matrix4>} [localOffsets] - Per-bone local offset matrices, keyed by bone name.\n * @property {Vector3} [hipPosition] - An additional position offset applied to the hip bone.\n **/\n\nexport {\n\tretarget,\n\tretargetClip,\n\tclone,\n};\n","import {\n\tAnimationClip,\n\tBone,\n\tBox3,\n\tBufferAttribute,\n\tBufferGeometry,\n\tClampToEdgeWrapping,\n\tColor,\n\tColorManagement,\n\tDirectionalLight,\n\tDoubleSide,\n\tFileLoader,\n\tFrontSide,\n\tGroup,\n\tImageBitmapLoader,\n\tInstancedMesh,\n\tInterleavedBuffer,\n\tInterleavedBufferAttribute,\n\tInterpolant,\n\tInterpolateDiscrete,\n\tInterpolateLinear,\n\tLine,\n\tLineBasicMaterial,\n\tLineLoop,\n\tLineSegments,\n\tLinearFilter,\n\tLinearMipmapLinearFilter,\n\tLinearMipmapNearestFilter,\n\tLinearSRGBColorSpace,\n\tLoader,\n\tLoaderUtils,\n\tMaterial,\n\tMathUtils,\n\tMatrix4,\n\tMesh,\n\tMeshBasicMaterial,\n\tMeshPhysicalMaterial,\n\tMeshStandardMaterial,\n\tMirroredRepeatWrapping,\n\tNearestFilter,\n\tNearestMipmapLinearFilter,\n\tNearestMipmapNearestFilter,\n\tNumberKeyframeTrack,\n\tObject3D,\n\tOrthographicCamera,\n\tPerspectiveCamera,\n\tPointLight,\n\tPoints,\n\tPointsMaterial,\n\tPropertyBinding,\n\tQuaternion,\n\tQuaternionKeyframeTrack,\n\tRepeatWrapping,\n\tSkeleton,\n\tSkinnedMesh,\n\tSphere,\n\tSpotLight,\n\tTexture,\n\tTextureLoader,\n\tTriangleFanDrawMode,\n\tTriangleStripDrawMode,\n\tVector2,\n\tVector3,\n\tVectorKeyframeTrack,\n\tSRGBColorSpace,\n\tInstancedBufferAttribute\n} from 'three';\nimport { toTrianglesDrawMode } from '../utils/BufferGeometryUtils.js';\nimport { clone } from '../utils/SkeletonUtils.js';\n\n/**\n * A loader for the glTF 2.0 format.\n *\n * [glTF](https://www.khronos.org/gltf/) (GL Transmission Format) is an [open format specification]{@link https://github.com/KhronosGroup/glTF/tree/main/specification/2.0)\n * for efficient delivery and loading of 3D content. Assets may be provided either in JSON (.gltf) or binary (.glb)\n * format. External files store textures (.jpg, .png) and additional binary data (.bin). A glTF asset may deliver\n * one or more scenes, including meshes, materials, textures, skins, skeletons, morph targets, animations, lights,\n * and/or cameras.\n *\n * `GLTFLoader` uses {@link ImageBitmapLoader} whenever possible. Be advised that image bitmaps are not\n * automatically GC-collected when they are no longer referenced, and they require special handling during\n * the disposal process.\n *\n * `GLTFLoader` supports the following glTF 2.0 extensions:\n * - KHR_draco_mesh_compression\n * - KHR_lights_punctual\n * - KHR_materials_anisotropy\n * - KHR_materials_clearcoat\n * - KHR_materials_dispersion\n * - KHR_materials_emissive_strength\n * - KHR_materials_ior\n * - KHR_materials_specular\n * - KHR_materials_transmission\n * - KHR_materials_iridescence\n * - KHR_materials_unlit\n * - KHR_materials_volume\n * - KHR_mesh_quantization\n * - KHR_meshopt_compression\n * - KHR_texture_basisu\n * - KHR_texture_transform\n * - EXT_materials_bump\n * - EXT_meshopt_compression\n * - EXT_mesh_gpu_instancing\n * - EXT_texture_avif\n * - EXT_texture_webp\n *\n * The following glTF 2.0 extension is supported by an external user plugin:\n * - [KHR_materials_variants](https://github.com/takahirox/three-gltf-extensions)\n * - [MSFT_texture_dds](https://github.com/takahirox/three-gltf-extensions)\n * - [KHR_animation_pointer](https://github.com/needle-tools/three-animation-pointer)\n * - [NEEDLE_progressive](https://github.com/needle-tools/gltf-progressive)\n *\n * ```js\n * const loader = new GLTFLoader();\n *\n * // Optional: Provide a DRACOLoader instance to decode compressed mesh data\n * const dracoLoader = new DRACOLoader();\n * dracoLoader.setDecoderPath( '/examples/jsm/libs/draco/' );\n * loader.setDRACOLoader( dracoLoader );\n *\n * const gltf = await loader.loadAsync( 'models/gltf/duck/duck.gltf' );\n * scene.add( gltf.scene );\n * ```\n *\n * @augments Loader\n * @three_import import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';\n */\nclass GLTFLoader extends Loader {\n\n\t/**\n\t * Constructs a new glTF loader.\n\t *\n\t * @param {LoadingManager} [manager] - The loading manager.\n\t */\n\tconstructor( manager ) {\n\n\t\tsuper( manager );\n\n\t\tthis.dracoLoader = null;\n\t\tthis.ktx2Loader = null;\n\t\tthis.meshoptDecoder = null;\n\n\t\tthis.pluginCallbacks = [];\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsClearcoatExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsDispersionExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFTextureBasisUExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFTextureWebPExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFTextureAVIFExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsSheenExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsTransmissionExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsVolumeExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsIorExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsEmissiveStrengthExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsSpecularExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsIridescenceExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsAnisotropyExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsBumpExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFLightsExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMeshoptCompression( parser, EXTENSIONS.EXT_MESHOPT_COMPRESSION );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMeshoptCompression( parser, EXTENSIONS.KHR_MESHOPT_COMPRESSION );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMeshGpuInstancing( parser );\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Starts loading from the given URL and passes the loaded glTF asset\n\t * to the `onLoad()` callback.\n\t *\n\t * @param {string} url - The path/URL of the file to be loaded. This can also be a data URI.\n\t * @param {function(GLTFLoader~LoadObject)} onLoad - Executed when the loading process has been finished.\n\t * @param {onProgressCallback} onProgress - Executed while the loading is in progress.\n\t * @param {onErrorCallback} onError - Executed when errors occur.\n\t */\n\tload( url, onLoad, onProgress, onError ) {\n\n\t\tconst scope = this;\n\n\t\tlet resourcePath;\n\n\t\tif ( this.resourcePath !== '' ) {\n\n\t\t\tresourcePath = this.resourcePath;\n\n\t\t} else if ( this.path !== '' ) {\n\n\t\t\t// If a base path is set, resources will be relative paths from that plus the relative path of the gltf file\n\t\t\t// Example path = 'https://my-cnd-server.com/', url = 'assets/models/model.gltf'\n\t\t\t// resourcePath = 'https://my-cnd-server.com/assets/models/'\n\t\t\t// referenced resource 'model.bin' will be loaded from 'https://my-cnd-server.com/assets/models/model.bin'\n\t\t\t// referenced resource '../textures/texture.png' will be loaded from 'https://my-cnd-server.com/assets/textures/texture.png'\n\t\t\tconst relativeUrl = LoaderUtils.extractUrlBase( url );\n\t\t\tresourcePath = LoaderUtils.resolveURL( relativeUrl, this.path );\n\n\t\t} else {\n\n\t\t\tresourcePath = LoaderUtils.extractUrlBase( url );\n\n\t\t}\n\n\t\t// Tells the LoadingManager to track an extra item, which resolves after\n\t\t// the model is fully loaded. This means the count of items loaded will\n\t\t// be incorrect, but ensures manager.onLoad() does not fire early.\n\t\tthis.manager.itemStart( url );\n\n\t\tconst _onError = function ( e ) {\n\n\t\t\tif ( onError ) {\n\n\t\t\t\tonError( e );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( e );\n\n\t\t\t}\n\n\t\t\tscope.manager.itemError( url );\n\t\t\tscope.manager.itemEnd( url );\n\n\t\t};\n\n\t\tconst loader = new FileLoader( this.manager );\n\n\t\tloader.setPath( this.path );\n\t\tloader.setResponseType( 'arraybuffer' );\n\t\tloader.setRequestHeader( this.requestHeader );\n\t\tloader.setWithCredentials( this.withCredentials );\n\n\t\tloader.load( url, function ( data ) {\n\n\t\t\ttry {\n\n\t\t\t\tscope.parse( data, resourcePath, function ( gltf ) {\n\n\t\t\t\t\tonLoad( gltf );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, _onError );\n\n\t\t\t} catch ( e ) {\n\n\t\t\t\t_onError( e );\n\n\t\t\t}\n\n\t\t}, onProgress, _onError );\n\n\t}\n\n\t/**\n\t * Sets the given Draco loader to this loader. Required for decoding assets\n\t * compressed with the `KHR_draco_mesh_compression` extension.\n\t *\n\t * @param {DRACOLoader} dracoLoader - The Draco loader to set.\n\t * @return {GLTFLoader} A reference to this loader.\n\t */\n\tsetDRACOLoader( dracoLoader ) {\n\n\t\tthis.dracoLoader = dracoLoader;\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * Sets the given KTX2 loader to this loader. Required for loading KTX2\n\t * compressed textures.\n\t *\n\t * @param {KTX2Loader} ktx2Loader - The KTX2 loader to set.\n\t * @return {GLTFLoader} A reference to this loader.\n\t */\n\tsetKTX2Loader( ktx2Loader ) {\n\n\t\tthis.ktx2Loader = ktx2Loader;\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * Sets the given meshopt decoder. Required for decoding assets\n\t * compressed with the `EXT_meshopt_compression` extension.\n\t *\n\t * @param {Object} meshoptDecoder - The meshopt decoder to set.\n\t * @return {GLTFLoader} A reference to this loader.\n\t */\n\tsetMeshoptDecoder( meshoptDecoder ) {\n\n\t\tthis.meshoptDecoder = meshoptDecoder;\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * Registers a plugin callback. This API is internally used to implement the various\n\t * glTF extensions but can also used by third-party code to add additional logic\n\t * to the loader.\n\t *\n\t * @param {function(parser:GLTFParser)} callback - The callback function to register.\n\t * @return {GLTFLoader} A reference to this loader.\n\t */\n\tregister( callback ) {\n\n\t\tif ( this.pluginCallbacks.indexOf( callback ) === - 1 ) {\n\n\t\t\tthis.pluginCallbacks.push( callback );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * Unregisters a plugin callback.\n\t *\n\t * @param {Function} callback - The callback function to unregister.\n\t * @return {GLTFLoader} A reference to this loader.\n\t */\n\tunregister( callback ) {\n\n\t\tif ( this.pluginCallbacks.indexOf( callback ) !== - 1 ) {\n\n\t\t\tthis.pluginCallbacks.splice( this.pluginCallbacks.indexOf( callback ), 1 );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * Parses the given glTF data and returns the resulting group.\n\t *\n\t * @param {string|ArrayBuffer} data - The raw glTF data.\n\t * @param {string} path - The URL base path.\n\t * @param {function(GLTFLoader~LoadObject)} onLoad - Executed when the loading process has been finished.\n\t * @param {onErrorCallback} onError - Executed when errors occur.\n\t */\n\tparse( data, path, onLoad, onError ) {\n\n\t\tlet json;\n\t\tconst extensions = {};\n\t\tconst plugins = {};\n\t\tconst textDecoder = new TextDecoder();\n\n\t\tif ( typeof data === 'string' ) {\n\n\t\t\tjson = JSON.parse( data );\n\n\t\t} else if ( data instanceof ArrayBuffer ) {\n\n\t\t\tconst magic = textDecoder.decode( new Uint8Array( data, 0, 4 ) );\n\n\t\t\tif ( magic === BINARY_EXTENSION_HEADER_MAGIC ) {\n\n\t\t\t\ttry {\n\n\t\t\t\t\textensions[ EXTENSIONS.KHR_BINARY_GLTF ] = new GLTFBinaryExtension( data );\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\tif ( onError ) onError( error );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tjson = JSON.parse( extensions[ EXTENSIONS.KHR_BINARY_GLTF ].content );\n\n\t\t\t} else {\n\n\t\t\t\tjson = JSON.parse( textDecoder.decode( data ) );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tjson = data;\n\n\t\t}\n\n\t\tif ( json.asset === undefined || json.asset.version[ 0 ] < 2 ) {\n\n\t\t\tif ( onError ) onError( new Error( 'THREE.GLTFLoader: Unsupported asset. glTF versions >=2.0 are supported.' ) );\n\t\t\treturn;\n\n\t\t}\n\n\t\tconst parser = new GLTFParser( json, {\n\n\t\t\tpath: path || this.resourcePath || '',\n\t\t\tcrossOrigin: this.crossOrigin,\n\t\t\trequestHeader: this.requestHeader,\n\t\t\tmanager: this.manager,\n\t\t\tktx2Loader: this.ktx2Loader,\n\t\t\tmeshoptDecoder: this.meshoptDecoder\n\n\t\t} );\n\n\t\tparser.fileLoader.setRequestHeader( this.requestHeader );\n\n\t\tfor ( let i = 0; i < this.pluginCallbacks.length; i ++ ) {\n\n\t\t\tconst plugin = this.pluginCallbacks[ i ]( parser );\n\n\t\t\tif ( ! plugin.name ) console.error( 'THREE.GLTFLoader: Invalid plugin found: missing name' );\n\n\t\t\tplugins[ plugin.name ] = plugin;\n\n\t\t\t// Workaround to avoid determining as unknown extension\n\t\t\t// in addUnknownExtensionsToUserData().\n\t\t\t// Remove this workaround if we move all the existing\n\t\t\t// extension handlers to plugin system\n\t\t\textensions[ plugin.name ] = true;\n\n\t\t}\n\n\t\tif ( json.extensionsUsed ) {\n\n\t\t\tfor ( let i = 0; i < json.extensionsUsed.length; ++ i ) {\n\n\t\t\t\tconst extensionName = json.extensionsUsed[ i ];\n\t\t\t\tconst extensionsRequired = json.extensionsRequired || [];\n\n\t\t\t\tswitch ( extensionName ) {\n\n\t\t\t\t\tcase EXTENSIONS.KHR_MATERIALS_UNLIT:\n\t\t\t\t\t\textensions[ extensionName ] = new GLTFMaterialsUnlitExtension();\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase EXTENSIONS.KHR_DRACO_MESH_COMPRESSION:\n\t\t\t\t\t\textensions[ extensionName ] = new GLTFDracoMeshCompressionExtension( json, this.dracoLoader );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase EXTENSIONS.KHR_TEXTURE_TRANSFORM:\n\t\t\t\t\t\textensions[ extensionName ] = new GLTFTextureTransformExtension();\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase EXTENSIONS.KHR_MESH_QUANTIZATION:\n\t\t\t\t\t\textensions[ extensionName ] = new GLTFMeshQuantizationExtension();\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tif ( extensionsRequired.indexOf( extensionName ) >= 0 && plugins[ extensionName ] === undefined ) {\n\n\t\t\t\t\t\t\tconsole.warn( 'THREE.GLTFLoader: Unknown extension \"' + extensionName + '\".' );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tparser.setExtensions( extensions );\n\t\tparser.setPlugins( plugins );\n\t\tparser.parse( onLoad, onError );\n\n\t}\n\n\t/**\n\t * Async version of {@link GLTFLoader#parse}.\n\t *\n\t * @async\n\t * @param {string|ArrayBuffer} data - The raw glTF data.\n\t * @param {string} path - The URL base path.\n\t * @return {Promise<GLTFLoader~LoadObject>} A Promise that resolves with the loaded glTF when the parsing has been finished.\n\t */\n\tparseAsync( data, path ) {\n\n\t\tconst scope = this;\n\n\t\treturn new Promise( function ( resolve, reject ) {\n\n\t\t\tscope.parse( data, path, resolve, reject );\n\n\t\t} );\n\n\t}\n\n}\n\n/* GLTFREGISTRY */\n\nfunction GLTFRegistry() {\n\n\tlet objects = {};\n\n\treturn\t{\n\n\t\tget: function ( key ) {\n\n\t\t\treturn objects[ key ];\n\n\t\t},\n\n\t\tadd: function ( key, object ) {\n\n\t\t\tobjects[ key ] = object;\n\n\t\t},\n\n\t\tremove: function ( key ) {\n\n\t\t\tdelete objects[ key ];\n\n\t\t},\n\n\t\tremoveAll: function () {\n\n\t\t\tobjects = {};\n\n\t\t}\n\n\t};\n\n}\n\n/*********************************/\n/********** EXTENSIONS ***********/\n/*********************************/\n\nfunction getMaterialExtension( parser, materialIndex, extensionName ) {\n\n\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\tif ( materialDef.extensions && materialDef.extensions[ extensionName ] ) {\n\n\t\treturn materialDef.extensions[ extensionName ];\n\n\t}\n\n\treturn null;\n\n}\n\nconst EXTENSIONS = {\n\tKHR_BINARY_GLTF: 'KHR_binary_glTF',\n\tKHR_DRACO_MESH_COMPRESSION: 'KHR_draco_mesh_compression',\n\tKHR_LIGHTS_PUNCTUAL: 'KHR_lights_punctual',\n\tKHR_MATERIALS_CLEARCOAT: 'KHR_materials_clearcoat',\n\tKHR_MATERIALS_DISPERSION: 'KHR_materials_dispersion',\n\tKHR_MATERIALS_IOR: 'KHR_materials_ior',\n\tKHR_MATERIALS_SHEEN: 'KHR_materials_sheen',\n\tKHR_MATERIALS_SPECULAR: 'KHR_materials_specular',\n\tKHR_MATERIALS_TRANSMISSION: 'KHR_materials_transmission',\n\tKHR_MATERIALS_IRIDESCENCE: 'KHR_materials_iridescence',\n\tKHR_MATERIALS_ANISOTROPY: 'KHR_materials_anisotropy',\n\tKHR_MATERIALS_UNLIT: 'KHR_materials_unlit',\n\tKHR_MATERIALS_VOLUME: 'KHR_materials_volume',\n\tKHR_TEXTURE_BASISU: 'KHR_texture_basisu',\n\tKHR_TEXTURE_TRANSFORM: 'KHR_texture_transform',\n\tKHR_MESH_QUANTIZATION: 'KHR_mesh_quantization',\n\tKHR_MATERIALS_EMISSIVE_STRENGTH: 'KHR_materials_emissive_strength',\n\tEXT_MATERIALS_BUMP: 'EXT_materials_bump',\n\tEXT_TEXTURE_WEBP: 'EXT_texture_webp',\n\tEXT_TEXTURE_AVIF: 'EXT_texture_avif',\n\tEXT_MESHOPT_COMPRESSION: 'EXT_meshopt_compression',\n\tKHR_MESHOPT_COMPRESSION: 'KHR_meshopt_compression',\n\tEXT_MESH_GPU_INSTANCING: 'EXT_mesh_gpu_instancing'\n};\n\n/**\n * Punctual Lights Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual\n *\n * @private\n */\nclass GLTFLightsExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_LIGHTS_PUNCTUAL;\n\n\t\t// Object3D instance caches\n\t\tthis.cache = { refs: {}, uses: {} };\n\n\t}\n\n\t_markDefs() {\n\n\t\tconst parser = this.parser;\n\t\tconst nodeDefs = this.parser.json.nodes || [];\n\n\t\tfor ( let nodeIndex = 0, nodeLength = nodeDefs.length; nodeIndex < nodeLength; nodeIndex ++ ) {\n\n\t\t\tconst nodeDef = nodeDefs[ nodeIndex ];\n\n\t\t\tif ( nodeDef.extensions\n\t\t\t\t\t&& nodeDef.extensions[ this.name ]\n\t\t\t\t\t&& nodeDef.extensions[ this.name ].light !== undefined ) {\n\n\t\t\t\tparser._addNodeRef( this.cache, nodeDef.extensions[ this.name ].light );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t_loadLight( lightIndex ) {\n\n\t\tconst parser = this.parser;\n\t\tconst cacheKey = 'light:' + lightIndex;\n\t\tlet dependency = parser.cache.get( cacheKey );\n\n\t\tif ( dependency ) return dependency;\n\n\t\tconst json = parser.json;\n\t\tconst extensions = ( json.extensions && json.extensions[ this.name ] ) || {};\n\t\tconst lightDefs = extensions.lights || [];\n\t\tconst lightDef = lightDefs[ lightIndex ];\n\t\tlet lightNode;\n\n\t\tconst color = new Color( 0xffffff );\n\n\t\tif ( lightDef.color !== undefined ) color.setRGB( lightDef.color[ 0 ], lightDef.color[ 1 ], lightDef.color[ 2 ], LinearSRGBColorSpace );\n\n\t\tconst range = lightDef.range !== undefined ? lightDef.range : 0;\n\n\t\tswitch ( lightDef.type ) {\n\n\t\t\tcase 'directional':\n\t\t\t\tlightNode = new DirectionalLight( color );\n\t\t\t\tlightNode.target.position.set( 0, 0, - 1 );\n\t\t\t\tlightNode.add( lightNode.target );\n\t\t\t\tbreak;\n\n\t\t\tcase 'point':\n\t\t\t\tlightNode = new PointLight( color );\n\t\t\t\tlightNode.distance = range;\n\t\t\t\tbreak;\n\n\t\t\tcase 'spot':\n\t\t\t\tlightNode = new SpotLight( color );\n\t\t\t\tlightNode.distance = range;\n\t\t\t\t// Handle spotlight properties.\n\t\t\t\tlightDef.spot = lightDef.spot || {};\n\t\t\t\tlightDef.spot.innerConeAngle = lightDef.spot.innerConeAngle !== undefined ? lightDef.spot.innerConeAngle : 0;\n\t\t\t\tlightDef.spot.outerConeAngle = lightDef.spot.outerConeAngle !== undefined ? lightDef.spot.outerConeAngle : Math.PI / 4.0;\n\t\t\t\tlightNode.angle = lightDef.spot.outerConeAngle;\n\t\t\t\tlightNode.penumbra = 1.0 - lightDef.spot.innerConeAngle / lightDef.spot.outerConeAngle;\n\t\t\t\tlightNode.target.position.set( 0, 0, - 1 );\n\t\t\t\tlightNode.add( lightNode.target );\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'THREE.GLTFLoader: Unexpected light type: ' + lightDef.type );\n\n\t\t}\n\n\t\t// Some lights (e.g. spot) default to a position other than the origin. Reset the position\n\t\t// here, because node-level parsing will only override position if explicitly specified.\n\t\tlightNode.position.set( 0, 0, 0 );\n\n\t\tassignExtrasToUserData( lightNode, lightDef );\n\n\t\tif ( lightDef.intensity !== undefined ) lightNode.intensity = lightDef.intensity;\n\n\t\tlightNode.name = parser.createUniqueName( lightDef.name || ( 'light_' + lightIndex ) );\n\n\t\tdependency = Promise.resolve( lightNode );\n\n\t\tparser.cache.add( cacheKey, dependency );\n\n\t\treturn dependency;\n\n\t}\n\n\tgetDependency( type, index ) {\n\n\t\tif ( type !== 'light' ) return;\n\n\t\treturn this._loadLight( index );\n\n\t}\n\n\tcreateNodeAttachment( nodeIndex ) {\n\n\t\tconst self = this;\n\t\tconst parser = this.parser;\n\t\tconst json = parser.json;\n\t\tconst nodeDef = json.nodes[ nodeIndex ];\n\t\tconst lightDef = ( nodeDef.extensions && nodeDef.extensions[ this.name ] ) || {};\n\t\tconst lightIndex = lightDef.light;\n\n\t\tif ( lightIndex === undefined ) return null;\n\n\t\treturn this._loadLight( lightIndex ).then( function ( light ) {\n\n\t\t\treturn parser._getNodeRef( self.cache, lightIndex, light );\n\n\t\t} );\n\n\t}\n\n}\n\n/**\n * Unlit Materials Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit\n *\n * @private\n */\nclass GLTFMaterialsUnlitExtension {\n\n\tconstructor() {\n\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_UNLIT;\n\n\t}\n\n\tgetMaterialType() {\n\n\t\treturn MeshBasicMaterial;\n\n\t}\n\n\textendParams( materialParams, materialDef, parser ) {\n\n\t\tconst pending = [];\n\n\t\tmaterialParams.color = new Color( 1.0, 1.0, 1.0 );\n\t\tmaterialParams.opacity = 1.0;\n\n\t\tconst metallicRoughness = materialDef.pbrMetallicRoughness;\n\n\t\tif ( metallicRoughness ) {\n\n\t\t\tif ( Array.isArray( metallicRoughness.baseColorFactor ) ) {\n\n\t\t\t\tconst array = metallicRoughness.baseColorFactor;\n\n\t\t\t\tmaterialParams.color.setRGB( array[ 0 ], array[ 1 ], array[ 2 ], LinearSRGBColorSpace );\n\t\t\t\tmaterialParams.opacity = array[ 3 ];\n\n\t\t\t}\n\n\t\t\tif ( metallicRoughness.baseColorTexture !== undefined ) {\n\n\t\t\t\tpending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture, SRGBColorSpace ) );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Materials Emissive Strength Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/blob/5768b3ce0ef32bc39cdf1bef10b948586635ead3/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md\n *\n * @private\n */\nclass GLTFMaterialsEmissiveStrengthExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_EMISSIVE_STRENGTH;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\tif ( extension === null ) return Promise.resolve();\n\n\t\tif ( extension.emissiveStrength !== undefined ) {\n\n\t\t\tmaterialParams.emissiveIntensity = extension.emissiveStrength;\n\n\t\t}\n\n\t\treturn Promise.resolve();\n\n\t}\n\n}\n\n/**\n * Clearcoat Materials Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_clearcoat\n *\n * @private\n */\nclass GLTFMaterialsClearcoatExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_CLEARCOAT;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\treturn extension !== null ? MeshPhysicalMaterial : null;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\tif ( extension === null ) return Promise.resolve();\n\n\t\tconst pending = [];\n\n\t\tif ( extension.clearcoatFactor !== undefined ) {\n\n\t\t\tmaterialParams.clearcoat = extension.clearcoatFactor;\n\n\t\t}\n\n\t\tif ( extension.clearcoatTexture !== undefined ) {\n\n\t\t\tpending.push( this.parser.assignTexture( materialParams, 'clearcoatMap', extension.clearcoatTexture ) );\n\n\t\t}\n\n\t\tif ( extension.clearcoatRoughnessFactor !== undefined ) {\n\n\t\t\tmaterialParams.clearcoatRoughness = extension.clearcoatRoughnessFactor;\n\n\t\t}\n\n\t\tif ( extension.clearcoatRoughnessTexture !== undefined ) {\n\n\t\t\tpending.push( this.parser.assignTexture( materialParams, 'clearcoatRoughnessMap', extension.clearcoatRoughnessTexture ) );\n\n\t\t}\n\n\t\tif ( extension.clearcoatNormalTexture !== undefined ) {\n\n\t\t\tpending.push( this.parser.assignTexture( materialParams, 'clearcoatNormalMap', extension.clearcoatNormalTexture ) );\n\n\t\t\tif ( extension.clearcoatNormalTexture.scale !== undefined ) {\n\n\t\t\t\tconst scale = extension.clearcoatNormalTexture.scale;\n\n\t\t\t\tmaterialParams.clearcoatNormalScale = new Vector2( scale, scale );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Materials dispersion Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_dispersion\n *\n * @private\n */\nclass GLTFMaterialsDispersionExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_DISPERSION;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\treturn extension !== null ? MeshPhysicalMaterial : null;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\tif ( extension === null ) return Promise.resolve();\n\n\t\tmaterialParams.dispersion = extension.dispersion !== undefined ? extension.dispersion : 0;\n\n\t\treturn Promise.resolve();\n\n\t}\n\n}\n\n/**\n * Iridescence Materials Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_iridescence\n *\n * @private\n */\nclass GLTFMaterialsIridescenceExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_IRIDESCENCE;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\treturn extension !== null ? MeshPhysicalMaterial : null;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\tif ( extension === null ) return Promise.resolve();\n\n\t\tconst pending = [];\n\n\t\tif ( extension.iridescenceFactor !== undefined ) {\n\n\t\t\tmaterialParams.iridescence = extension.iridescenceFactor;\n\n\t\t}\n\n\t\tif ( extension.iridescenceTexture !== undefined ) {\n\n\t\t\tpending.push( this.parser.assignTexture( materialParams, 'iridescenceMap', extension.iridescenceTexture ) );\n\n\t\t}\n\n\t\tif ( extension.iridescenceIor !== undefined ) {\n\n\t\t\tmaterialParams.iridescenceIOR = extension.iridescenceIor;\n\n\t\t}\n\n\t\tif ( materialParams.iridescenceThicknessRange === undefined ) {\n\n\t\t\tmaterialParams.iridescenceThicknessRange = [ 100, 400 ];\n\n\t\t}\n\n\t\tif ( extension.iridescenceThicknessMinimum !== undefined ) {\n\n\t\t\tmaterialParams.iridescenceThicknessRange[ 0 ] = extension.iridescenceThicknessMinimum;\n\n\t\t}\n\n\t\tif ( extension.iridescenceThicknessMaximum !== undefined ) {\n\n\t\t\tmaterialParams.iridescenceThicknessRange[ 1 ] = extension.iridescenceThicknessMaximum;\n\n\t\t}\n\n\t\tif ( extension.iridescenceThicknessTexture !== undefined ) {\n\n\t\t\tpending.push( this.parser.assignTexture( materialParams, 'iridescenceThicknessMap', extension.iridescenceThicknessTexture ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Sheen Materials Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_sheen\n *\n * @private\n */\nclass GLTFMaterialsSheenExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_SHEEN;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\treturn extension !== null ? MeshPhysicalMaterial : null;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\tif ( extension === null ) return Promise.resolve();\n\n\t\tconst pending = [];\n\n\t\tmaterialParams.sheenColor = new Color( 0, 0, 0 );\n\t\tmaterialParams.sheenRoughness = 0;\n\t\tmaterialParams.sheen = 1;\n\n\t\tif ( extension.sheenColorFactor !== undefined ) {\n\n\t\t\tconst colorFactor = extension.sheenColorFactor;\n\t\t\tmaterialParams.sheenColor.setRGB( colorFactor[ 0 ], colorFactor[ 1 ], colorFactor[ 2 ], LinearSRGBColorSpace );\n\n\t\t}\n\n\t\tif ( extension.sheenRoughnessFactor !== undefined ) {\n\n\t\t\tmaterialParams.sheenRoughness = extension.sheenRoughnessFactor;\n\n\t\t}\n\n\t\tif ( extension.sheenColorTexture !== undefined ) {\n\n\t\t\tpending.push( this.parser.assignTexture( materialParams, 'sheenColorMap', extension.sheenColorTexture, SRGBColorSpace ) );\n\n\t\t}\n\n\t\tif ( extension.sheenRoughnessTexture !== undefined ) {\n\n\t\t\tpending.push( this.parser.assignTexture( materialParams, 'sheenRoughnessMap', extension.sheenRoughnessTexture ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Transmission Materials Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_transmission\n * Draft: https://github.com/KhronosGroup/glTF/pull/1698\n *\n * @private\n */\nclass GLTFMaterialsTransmissionExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_TRANSMISSION;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\treturn extension !== null ? MeshPhysicalMaterial : null;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\tif ( extension === null ) return Promise.resolve();\n\n\t\tconst pending = [];\n\n\t\tif ( extension.transmissionFactor !== undefined ) {\n\n\t\t\tmaterialParams.transmission = extension.transmissionFactor;\n\n\t\t}\n\n\t\tif ( extension.transmissionTexture !== undefined ) {\n\n\t\t\tpending.push( this.parser.assignTexture( materialParams, 'transmissionMap', extension.transmissionTexture ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Materials Volume Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_volume\n *\n * @private\n */\nclass GLTFMaterialsVolumeExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_VOLUME;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\treturn extension !== null ? MeshPhysicalMaterial : null;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\tif ( extension === null ) return Promise.resolve();\n\n\t\tconst pending = [];\n\n\t\tmaterialParams.thickness = extension.thicknessFactor !== undefined ? extension.thicknessFactor : 0;\n\n\t\tif ( extension.thicknessTexture !== undefined ) {\n\n\t\t\tpending.push( this.parser.assignTexture( materialParams, 'thicknessMap', extension.thicknessTexture ) );\n\n\t\t}\n\n\t\tmaterialParams.attenuationDistance = extension.attenuationDistance || Infinity;\n\n\t\tconst colorArray = extension.attenuationColor || [ 1, 1, 1 ];\n\t\tmaterialParams.attenuationColor = new Color().setRGB( colorArray[ 0 ], colorArray[ 1 ], colorArray[ 2 ], LinearSRGBColorSpace );\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Materials ior Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_ior\n *\n * @private\n */\nclass GLTFMaterialsIorExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_IOR;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\treturn extension !== null ? MeshPhysicalMaterial : null;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\tif ( extension === null ) return Promise.resolve();\n\n\t\tmaterialParams.ior = extension.ior !== undefined ? extension.ior : 1.5;\n\n\t\tif ( materialParams.ior === 0 ) materialParams.ior = 1000; // see #26167\n\n\t\treturn Promise.resolve();\n\n\t}\n\n}\n\n/**\n * Materials specular Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_specular\n *\n * @private\n */\nclass GLTFMaterialsSpecularExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_SPECULAR;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\treturn extension !== null ? MeshPhysicalMaterial : null;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\tif ( extension === null ) return Promise.resolve();\n\n\t\tconst pending = [];\n\n\t\tmaterialParams.specularIntensity = extension.specularFactor !== undefined ? extension.specularFactor : 1.0;\n\n\t\tif ( extension.specularTexture !== undefined ) {\n\n\t\t\tpending.push( this.parser.assignTexture( materialParams, 'specularIntensityMap', extension.specularTexture ) );\n\n\t\t}\n\n\t\tconst colorArray = extension.specularColorFactor || [ 1, 1, 1 ];\n\t\tmaterialParams.specularColor = new Color().setRGB( colorArray[ 0 ], colorArray[ 1 ], colorArray[ 2 ], LinearSRGBColorSpace );\n\n\t\tif ( extension.specularColorTexture !== undefined ) {\n\n\t\t\tpending.push( this.parser.assignTexture( materialParams, 'specularColorMap', extension.specularColorTexture, SRGBColorSpace ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n\n/**\n * Materials bump Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/EXT_materials_bump\n *\n * @private\n */\nclass GLTFMaterialsBumpExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.EXT_MATERIALS_BUMP;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\treturn extension !== null ? MeshPhysicalMaterial : null;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\tif ( extension === null ) return Promise.resolve();\n\n\t\tconst pending = [];\n\n\t\tmaterialParams.bumpScale = extension.bumpFactor !== undefined ? extension.bumpFactor : 1.0;\n\n\t\tif ( extension.bumpTexture !== undefined ) {\n\n\t\t\tpending.push( this.parser.assignTexture( materialParams, 'bumpMap', extension.bumpTexture ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Materials anisotropy Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_anisotropy\n *\n * @private\n */\nclass GLTFMaterialsAnisotropyExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_ANISOTROPY;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\treturn extension !== null ? MeshPhysicalMaterial : null;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst extension = getMaterialExtension( this.parser, materialIndex, this.name );\n\n\t\tif ( extension === null ) return Promise.resolve();\n\n\t\tconst pending = [];\n\n\t\tif ( extension.anisotropyStrength !== undefined ) {\n\n\t\t\tmaterialParams.anisotropy = extension.anisotropyStrength;\n\n\t\t}\n\n\t\tif ( extension.anisotropyRotation !== undefined ) {\n\n\t\t\tmaterialParams.anisotropyRotation = extension.anisotropyRotation;\n\n\t\t}\n\n\t\tif ( extension.anisotropyTexture !== undefined ) {\n\n\t\t\tpending.push( this.parser.assignTexture( materialParams, 'anisotropyMap', extension.anisotropyTexture ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * BasisU Texture Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_texture_basisu\n *\n * @private\n */\nclass GLTFTextureBasisUExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_TEXTURE_BASISU;\n\n\t}\n\n\tloadTexture( textureIndex ) {\n\n\t\tconst parser = this.parser;\n\t\tconst json = parser.json;\n\n\t\tconst textureDef = json.textures[ textureIndex ];\n\n\t\tif ( ! textureDef.extensions || ! textureDef.extensions[ this.name ] ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\tconst extension = textureDef.extensions[ this.name ];\n\t\tconst loader = parser.options.ktx2Loader;\n\n\t\tif ( ! loader ) {\n\n\t\t\tif ( json.extensionsRequired && json.extensionsRequired.indexOf( this.name ) >= 0 ) {\n\n\t\t\t\tthrow new Error( 'THREE.GLTFLoader: setKTX2Loader must be called before loading KTX2 textures' );\n\n\t\t\t} else {\n\n\t\t\t\t// Assumes that the extension is optional and that a fallback texture is present\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn parser.loadTextureImage( textureIndex, extension.source, loader );\n\n\t}\n\n}\n\n/**\n * WebP Texture Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_texture_webp\n *\n * @private\n */\nclass GLTFTextureWebPExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.EXT_TEXTURE_WEBP;\n\n\t}\n\n\tloadTexture( textureIndex ) {\n\n\t\tconst name = this.name;\n\t\tconst parser = this.parser;\n\t\tconst json = parser.json;\n\n\t\tconst textureDef = json.textures[ textureIndex ];\n\n\t\tif ( ! textureDef.extensions || ! textureDef.extensions[ name ] ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\tconst extension = textureDef.extensions[ name ];\n\t\tconst source = json.images[ extension.source ];\n\n\t\tlet loader = parser.textureLoader;\n\t\tif ( source.uri ) {\n\n\t\t\tconst handler = parser.options.manager.getHandler( source.uri );\n\t\t\tif ( handler !== null ) loader = handler;\n\n\t\t}\n\n\t\treturn parser.loadTextureImage( textureIndex, extension.source, loader );\n\n\t}\n\n}\n\n/**\n * AVIF Texture Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_texture_avif\n *\n * @private\n */\nclass GLTFTextureAVIFExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.EXT_TEXTURE_AVIF;\n\n\t}\n\n\tloadTexture( textureIndex ) {\n\n\t\tconst name = this.name;\n\t\tconst parser = this.parser;\n\t\tconst json = parser.json;\n\n\t\tconst textureDef = json.textures[ textureIndex ];\n\n\t\tif ( ! textureDef.extensions || ! textureDef.extensions[ name ] ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\tconst extension = textureDef.extensions[ name ];\n\t\tconst source = json.images[ extension.source ];\n\n\t\tlet loader = parser.textureLoader;\n\t\tif ( source.uri ) {\n\n\t\t\tconst handler = parser.options.manager.getHandler( source.uri );\n\t\t\tif ( handler !== null ) loader = handler;\n\n\t\t}\n\n\t\treturn parser.loadTextureImage( textureIndex, extension.source, loader );\n\n\t}\n\n}\n\n/**\n * meshopt BufferView Compression Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_meshopt_compression\n *\n * @private\n */\nclass GLTFMeshoptCompression {\n\n\tconstructor( parser, name ) {\n\n\t\tthis.name = name;\n\t\tthis.parser = parser;\n\n\t}\n\n\tloadBufferView( index ) {\n\n\t\tconst json = this.parser.json;\n\t\tconst bufferView = json.bufferViews[ index ];\n\n\t\tif ( bufferView.extensions && bufferView.extensions[ this.name ] ) {\n\n\t\t\tconst extensionDef = bufferView.extensions[ this.name ];\n\n\t\t\tconst buffer = this.parser.getDependency( 'buffer', extensionDef.buffer );\n\t\t\tconst decoder = this.parser.options.meshoptDecoder;\n\n\t\t\tif ( ! decoder || ! decoder.supported ) {\n\n\t\t\t\tif ( json.extensionsRequired && json.extensionsRequired.indexOf( this.name ) >= 0 ) {\n\n\t\t\t\t\tthrow new Error( 'THREE.GLTFLoader: setMeshoptDecoder must be called before loading compressed files' );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Assumes that the extension is optional and that fallback buffer data is present\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn buffer.then( function ( res ) {\n\n\t\t\t\tconst byteOffset = extensionDef.byteOffset || 0;\n\t\t\t\tconst byteLength = extensionDef.byteLength || 0;\n\n\t\t\t\tconst count = extensionDef.count;\n\t\t\t\tconst stride = extensionDef.byteStride;\n\n\t\t\t\tconst source = new Uint8Array( res, byteOffset, byteLength );\n\n\t\t\t\tif ( decoder.decodeGltfBufferAsync ) {\n\n\t\t\t\t\treturn decoder.decodeGltfBufferAsync( count, stride, source, extensionDef.mode, extensionDef.filter ).then( function ( res ) {\n\n\t\t\t\t\t\treturn res.buffer;\n\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Support for MeshoptDecoder 0.18 or earlier, without decodeGltfBufferAsync\n\t\t\t\t\treturn decoder.ready.then( function () {\n\n\t\t\t\t\t\tconst result = new ArrayBuffer( count * stride );\n\t\t\t\t\t\tdecoder.decodeGltfBuffer( new Uint8Array( result ), count, stride, source, extensionDef.mode, extensionDef.filter );\n\t\t\t\t\t\treturn result;\n\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t} else {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t}\n\n}\n\n/**\n * GPU Instancing Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_mesh_gpu_instancing\n *\n * @private\n */\nclass GLTFMeshGpuInstancing {\n\n\tconstructor( parser ) {\n\n\t\tthis.name = EXTENSIONS.EXT_MESH_GPU_INSTANCING;\n\t\tthis.parser = parser;\n\n\t}\n\n\tcreateNodeMesh( nodeIndex ) {\n\n\t\tconst json = this.parser.json;\n\t\tconst nodeDef = json.nodes[ nodeIndex ];\n\n\t\tif ( ! nodeDef.extensions || ! nodeDef.extensions[ this.name ] ||\n\t\t\tnodeDef.mesh === undefined ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\tconst meshDef = json.meshes[ nodeDef.mesh ];\n\n\t\t// No Points or Lines + Instancing support yet\n\n\t\tfor ( const primitive of meshDef.primitives ) {\n\n\t\t\tif ( primitive.mode !== WEBGL_CONSTANTS.TRIANGLES &&\n\t\t\t\t primitive.mode !== WEBGL_CONSTANTS.TRIANGLE_STRIP &&\n\t\t\t\t primitive.mode !== WEBGL_CONSTANTS.TRIANGLE_FAN &&\n\t\t\t\t primitive.mode !== undefined ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst extensionDef = nodeDef.extensions[ this.name ];\n\t\tconst attributesDef = extensionDef.attributes;\n\n\t\t// @TODO: Can we support InstancedMesh + SkinnedMesh?\n\n\t\tconst pending = [];\n\t\tconst attributes = {};\n\n\t\tfor ( const key in attributesDef ) {\n\n\t\t\tpending.push( this.parser.getDependency( 'accessor', attributesDef[ key ] ).then( accessor => {\n\n\t\t\t\tattributes[ key ] = accessor;\n\t\t\t\treturn attributes[ key ];\n\n\t\t\t} ) );\n\n\t\t}\n\n\t\tif ( pending.length < 1 ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\tpending.push( this.parser.createNodeMesh( nodeIndex ) );\n\n\t\treturn Promise.all( pending ).then( results => {\n\n\t\t\tconst nodeObject = results.pop();\n\t\t\tconst meshes = nodeObject.isGroup ? nodeObject.children : [ nodeObject ];\n\t\t\tconst count = results[ 0 ].count; // All attribute counts should be same\n\t\t\tconst instancedMeshes = [];\n\n\t\t\tfor ( const mesh of meshes ) {\n\n\t\t\t\t// Temporal variables\n\t\t\t\tconst m = new Matrix4();\n\t\t\t\tconst p = new Vector3();\n\t\t\t\tconst q = new Quaternion();\n\t\t\t\tconst s = new Vector3( 1, 1, 1 );\n\n\t\t\t\tconst instancedMesh = new InstancedMesh( mesh.geometry, mesh.material, count );\n\n\t\t\t\tfor ( let i = 0; i < count; i ++ ) {\n\n\t\t\t\t\tif ( attributes.TRANSLATION ) {\n\n\t\t\t\t\t\tp.fromBufferAttribute( attributes.TRANSLATION, i );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( attributes.ROTATION ) {\n\n\t\t\t\t\t\tq.fromBufferAttribute( attributes.ROTATION, i );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( attributes.SCALE ) {\n\n\t\t\t\t\t\ts.fromBufferAttribute( attributes.SCALE, i );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tinstancedMesh.setMatrixAt( i, m.compose( p, q, s ) );\n\n\t\t\t\t}\n\n\t\t\t\t// Add instance attributes to the geometry, excluding TRS.\n\t\t\t\tfor ( const attributeName in attributes ) {\n\n\t\t\t\t\tif ( attributeName === '_COLOR_0' ) {\n\n\t\t\t\t\t\tconst attr = attributes[ attributeName ];\n\t\t\t\t\t\tinstancedMesh.instanceColor = new InstancedBufferAttribute( attr.array, attr.itemSize, attr.normalized );\n\n\t\t\t\t\t} else if ( attributeName !== 'TRANSLATION' &&\n\t\t\t\t\t\t attributeName !== 'ROTATION' &&\n\t\t\t\t\t\t attributeName !== 'SCALE' ) {\n\n\t\t\t\t\t\tmesh.geometry.setAttribute( attributeName, attributes[ attributeName ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// Just in case\n\t\t\t\tObject3D.prototype.copy.call( instancedMesh, mesh );\n\n\t\t\t\tthis.parser.assignFinalMaterial( instancedMesh );\n\n\t\t\t\tinstancedMeshes.push( instancedMesh );\n\n\t\t\t}\n\n\t\t\tif ( nodeObject.isGroup ) {\n\n\t\t\t\tnodeObject.clear();\n\n\t\t\t\tnodeObject.add( ... instancedMeshes );\n\n\t\t\t\treturn nodeObject;\n\n\t\t\t}\n\n\t\t\treturn instancedMeshes[ 0 ];\n\n\t\t} );\n\n\t}\n\n}\n\n/* BINARY EXTENSION */\nconst BINARY_EXTENSION_HEADER_MAGIC = 'glTF';\nconst BINARY_EXTENSION_HEADER_LENGTH = 12;\nconst BINARY_EXTENSION_CHUNK_TYPES = { JSON: 0x4E4F534A, BIN: 0x004E4942 };\n\nclass GLTFBinaryExtension {\n\n\tconstructor( data ) {\n\n\t\tthis.name = EXTENSIONS.KHR_BINARY_GLTF;\n\t\tthis.content = null;\n\t\tthis.body = null;\n\n\t\tconst headerView = new DataView( data, 0, BINARY_EXTENSION_HEADER_LENGTH );\n\t\tconst textDecoder = new TextDecoder();\n\n\t\tthis.header = {\n\t\t\tmagic: textDecoder.decode( new Uint8Array( data.slice( 0, 4 ) ) ),\n\t\t\tversion: headerView.getUint32( 4, true ),\n\t\t\tlength: headerView.getUint32( 8, true )\n\t\t};\n\n\t\tif ( this.header.magic !== BINARY_EXTENSION_HEADER_MAGIC ) {\n\n\t\t\tthrow new Error( 'THREE.GLTFLoader: Unsupported glTF-Binary header.' );\n\n\t\t} else if ( this.header.version < 2.0 ) {\n\n\t\t\tthrow new Error( 'THREE.GLTFLoader: Legacy binary file detected.' );\n\n\t\t}\n\n\t\tconst chunkContentsLength = this.header.length - BINARY_EXTENSION_HEADER_LENGTH;\n\t\tconst chunkView = new DataView( data, BINARY_EXTENSION_HEADER_LENGTH );\n\t\tlet chunkIndex = 0;\n\n\t\twhile ( chunkIndex < chunkContentsLength ) {\n\n\t\t\tconst chunkLength = chunkView.getUint32( chunkIndex, true );\n\t\t\tchunkIndex += 4;\n\n\t\t\tconst chunkType = chunkView.getUint32( chunkIndex, true );\n\t\t\tchunkIndex += 4;\n\n\t\t\tif ( chunkType === BINARY_EXTENSION_CHUNK_TYPES.JSON ) {\n\n\t\t\t\tconst contentArray = new Uint8Array( data, BINARY_EXTENSION_HEADER_LENGTH + chunkIndex, chunkLength );\n\t\t\t\tthis.content = textDecoder.decode( contentArray );\n\n\t\t\t} else if ( chunkType === BINARY_EXTENSION_CHUNK_TYPES.BIN ) {\n\n\t\t\t\tconst byteOffset = BINARY_EXTENSION_HEADER_LENGTH + chunkIndex;\n\t\t\t\tthis.body = data.slice( byteOffset, byteOffset + chunkLength );\n\n\t\t\t}\n\n\t\t\t// Clients must ignore chunks with unknown types.\n\n\t\t\tchunkIndex += chunkLength;\n\n\t\t}\n\n\t\tif ( this.content === null ) {\n\n\t\t\tthrow new Error( 'THREE.GLTFLoader: JSON content not found.' );\n\n\t\t}\n\n\t}\n\n}\n\n/**\n * DRACO Mesh Compression Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_draco_mesh_compression\n *\n * @private\n */\nclass GLTFDracoMeshCompressionExtension {\n\n\tconstructor( json, dracoLoader ) {\n\n\t\tif ( ! dracoLoader ) {\n\n\t\t\tthrow new Error( 'THREE.GLTFLoader: No DRACOLoader instance provided.' );\n\n\t\t}\n\n\t\tthis.name = EXTENSIONS.KHR_DRACO_MESH_COMPRESSION;\n\t\tthis.json = json;\n\t\tthis.dracoLoader = dracoLoader;\n\t\tthis.dracoLoader.preload();\n\n\t}\n\n\tdecodePrimitive( primitive, parser ) {\n\n\t\tconst json = this.json;\n\t\tconst dracoLoader = this.dracoLoader;\n\t\tconst bufferViewIndex = primitive.extensions[ this.name ].bufferView;\n\t\tconst gltfAttributeMap = primitive.extensions[ this.name ].attributes;\n\t\tconst threeAttributeMap = {};\n\t\tconst attributeNormalizedMap = {};\n\t\tconst attributeTypeMap = {};\n\n\t\tfor ( const attributeName in gltfAttributeMap ) {\n\n\t\t\tconst threeAttributeName = ATTRIBUTES[ attributeName ] || attributeName.toLowerCase();\n\n\t\t\tthreeAttributeMap[ threeAttributeName ] = gltfAttributeMap[ attributeName ];\n\n\t\t}\n\n\t\tfor ( const attributeName in primitive.attributes ) {\n\n\t\t\tconst threeAttributeName = ATTRIBUTES[ attributeName ] || attributeName.toLowerCase();\n\n\t\t\tif ( gltfAttributeMap[ attributeName ] !== undefined ) {\n\n\t\t\t\tconst accessorDef = json.accessors[ primitive.attributes[ attributeName ] ];\n\t\t\t\tconst componentType = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ];\n\n\t\t\t\tattributeTypeMap[ threeAttributeName ] = componentType.name;\n\t\t\t\tattributeNormalizedMap[ threeAttributeName ] = accessorDef.normalized === true;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn parser.getDependency( 'bufferView', bufferViewIndex ).then( function ( bufferView ) {\n\n\t\t\treturn new Promise( function ( resolve, reject ) {\n\n\t\t\t\tdracoLoader.decodeDracoFile( bufferView, function ( geometry ) {\n\n\t\t\t\t\tfor ( const attributeName in geometry.attributes ) {\n\n\t\t\t\t\t\tconst attribute = geometry.attributes[ attributeName ];\n\t\t\t\t\t\tconst normalized = attributeNormalizedMap[ attributeName ];\n\n\t\t\t\t\t\tif ( normalized !== undefined ) attribute.normalized = normalized;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve( geometry );\n\n\t\t\t\t}, threeAttributeMap, attributeTypeMap, LinearSRGBColorSpace, reject );\n\n\t\t\t} );\n\n\t\t} );\n\n\t}\n\n}\n\n/**\n * Texture Transform Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_texture_transform\n *\n * @private\n */\nclass GLTFTextureTransformExtension {\n\n\tconstructor() {\n\n\t\tthis.name = EXTENSIONS.KHR_TEXTURE_TRANSFORM;\n\n\t}\n\n\textendTexture( texture, transform ) {\n\n\t\tif ( ( transform.texCoord === undefined || transform.texCoord === texture.channel )\n\t\t\t&& transform.offset === undefined\n\t\t\t&& transform.rotation === undefined\n\t\t\t&& transform.scale === undefined ) {\n\n\t\t\t// See https://github.com/mrdoob/three.js/issues/21819.\n\t\t\treturn texture;\n\n\t\t}\n\n\t\ttexture = texture.clone();\n\n\t\tif ( transform.texCoord !== undefined ) {\n\n\t\t\ttexture.channel = transform.texCoord;\n\n\t\t}\n\n\t\tif ( transform.offset !== undefined ) {\n\n\t\t\ttexture.offset.fromArray( transform.offset );\n\n\t\t}\n\n\t\tif ( transform.rotation !== undefined ) {\n\n\t\t\ttexture.rotation = transform.rotation;\n\n\t\t}\n\n\t\tif ( transform.scale !== undefined ) {\n\n\t\t\ttexture.repeat.fromArray( transform.scale );\n\n\t\t}\n\n\t\ttexture.needsUpdate = true;\n\n\t\treturn texture;\n\n\t}\n\n}\n\n/**\n * Mesh Quantization Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization\n *\n * @private\n */\nclass GLTFMeshQuantizationExtension {\n\n\tconstructor() {\n\n\t\tthis.name = EXTENSIONS.KHR_MESH_QUANTIZATION;\n\n\t}\n\n}\n\n/*********************************/\n/********** INTERPOLATION ********/\n/*********************************/\n\n// Spline Interpolation\n// Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#appendix-c-spline-interpolation\nclass GLTFCubicSplineInterpolant extends Interpolant {\n\n\tconstructor( parameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tsuper( parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tcopySampleValue_( index ) {\n\n\t\t// Copies a sample value to the result buffer. See description of glTF\n\t\t// CUBICSPLINE values layout in interpolate_() function below.\n\n\t\tconst result = this.resultBuffer,\n\t\t\tvalues = this.sampleValues,\n\t\t\tvalueSize = this.valueSize,\n\t\t\toffset = index * valueSize * 3 + valueSize;\n\n\t\tfor ( let i = 0; i !== valueSize; i ++ ) {\n\n\t\t\tresult[ i ] = values[ offset + i ];\n\n\t\t}\n\n\t\treturn result;\n\n\t}\n\n\tinterpolate_( i1, t0, t, t1 ) {\n\n\t\tconst result = this.resultBuffer;\n\t\tconst values = this.sampleValues;\n\t\tconst stride = this.valueSize;\n\n\t\tconst stride2 = stride * 2;\n\t\tconst stride3 = stride * 3;\n\n\t\tconst td = t1 - t0;\n\n\t\tconst p = ( t - t0 ) / td;\n\t\tconst pp = p * p;\n\t\tconst ppp = pp * p;\n\n\t\tconst offset1 = i1 * stride3;\n\t\tconst offset0 = offset1 - stride3;\n\n\t\tconst s2 = - 2 * ppp + 3 * pp;\n\t\tconst s3 = ppp - pp;\n\t\tconst s0 = 1 - s2;\n\t\tconst s1 = s3 - pp + p;\n\n\t\t// Layout of keyframe output values for CUBICSPLINE animations:\n\t\t// [ inTangent_1, splineVertex_1, outTangent_1, inTangent_2, splineVertex_2, ... ]\n\t\tfor ( let i = 0; i !== stride; i ++ ) {\n\n\t\t\tconst p0 = values[ offset0 + i + stride ]; // splineVertex_k\n\t\t\tconst m0 = values[ offset0 + i + stride2 ] * td; // outTangent_k * (t_k+1 - t_k)\n\t\t\tconst p1 = values[ offset1 + i + stride ]; // splineVertex_k+1\n\t\t\tconst m1 = values[ offset1 + i ] * td; // inTangent_k+1 * (t_k+1 - t_k)\n\n\t\t\tresult[ i ] = s0 * p0 + s1 * m0 + s2 * p1 + s3 * m1;\n\n\t\t}\n\n\t\treturn result;\n\n\t}\n\n}\n\nconst _quaternion = new Quaternion();\n\nclass GLTFCubicSplineQuaternionInterpolant extends GLTFCubicSplineInterpolant {\n\n\tinterpolate_( i1, t0, t, t1 ) {\n\n\t\tconst result = super.interpolate_( i1, t0, t, t1 );\n\n\t\t_quaternion.fromArray( result ).normalize().toArray( result );\n\n\t\treturn result;\n\n\t}\n\n}\n\n\n/*********************************/\n/********** INTERNALS ************/\n/*********************************/\n\n/* CONSTANTS */\n\nconst WEBGL_CONSTANTS = {\n\tFLOAT: 5126,\n\t//FLOAT_MAT2: 35674,\n\tFLOAT_MAT3: 35675,\n\tFLOAT_MAT4: 35676,\n\tFLOAT_VEC2: 35664,\n\tFLOAT_VEC3: 35665,\n\tFLOAT_VEC4: 35666,\n\tLINEAR: 9729,\n\tREPEAT: 10497,\n\tSAMPLER_2D: 35678,\n\tPOINTS: 0,\n\tLINES: 1,\n\tLINE_LOOP: 2,\n\tLINE_STRIP: 3,\n\tTRIANGLES: 4,\n\tTRIANGLE_STRIP: 5,\n\tTRIANGLE_FAN: 6,\n\tUNSIGNED_BYTE: 5121,\n\tUNSIGNED_SHORT: 5123\n};\n\nconst WEBGL_COMPONENT_TYPES = {\n\t5120: Int8Array,\n\t5121: Uint8Array,\n\t5122: Int16Array,\n\t5123: Uint16Array,\n\t5125: Uint32Array,\n\t5126: Float32Array\n};\n\nconst WEBGL_FILTERS = {\n\t9728: NearestFilter,\n\t9729: LinearFilter,\n\t9984: NearestMipmapNearestFilter,\n\t9985: LinearMipmapNearestFilter,\n\t9986: NearestMipmapLinearFilter,\n\t9987: LinearMipmapLinearFilter\n};\n\nconst WEBGL_WRAPPINGS = {\n\t33071: ClampToEdgeWrapping,\n\t33648: MirroredRepeatWrapping,\n\t10497: RepeatWrapping\n};\n\nconst WEBGL_TYPE_SIZES = {\n\t'SCALAR': 1,\n\t'VEC2': 2,\n\t'VEC3': 3,\n\t'VEC4': 4,\n\t'MAT2': 4,\n\t'MAT3': 9,\n\t'MAT4': 16\n};\n\nconst ATTRIBUTES = {\n\tPOSITION: 'position',\n\tNORMAL: 'normal',\n\tTANGENT: 'tangent',\n\tTEXCOORD_0: 'uv',\n\tTEXCOORD_1: 'uv1',\n\tTEXCOORD_2: 'uv2',\n\tTEXCOORD_3: 'uv3',\n\tCOLOR_0: 'color',\n\tWEIGHTS_0: 'skinWeight',\n\tJOINTS_0: 'skinIndex',\n};\n\nconst PATH_PROPERTIES = {\n\tscale: 'scale',\n\ttranslation: 'position',\n\trotation: 'quaternion',\n\tweights: 'morphTargetInfluences'\n};\n\nconst INTERPOLATION = {\n\tCUBICSPLINE: undefined, // We use a custom interpolant (GLTFCubicSplineInterpolation) for CUBICSPLINE tracks. Each\n\t\t // keyframe track will be initialized with a default interpolation type, then modified.\n\tLINEAR: InterpolateLinear,\n\tSTEP: InterpolateDiscrete\n};\n\nconst ALPHA_MODES = {\n\tOPAQUE: 'OPAQUE',\n\tMASK: 'MASK',\n\tBLEND: 'BLEND'\n};\n\n/**\n * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#default-material\n *\n * @private\n * @param {Object<string, Material>} cache\n * @return {Material}\n */\nfunction createDefaultMaterial( cache ) {\n\n\tif ( cache[ 'DefaultMaterial' ] === undefined ) {\n\n\t\tcache[ 'DefaultMaterial' ] = new MeshStandardMaterial( {\n\t\t\tcolor: 0xFFFFFF,\n\t\t\temissive: 0x000000,\n\t\t\tmetalness: 1,\n\t\t\troughness: 1,\n\t\t\ttransparent: false,\n\t\t\tdepthTest: true,\n\t\t\tside: FrontSide\n\t\t} );\n\n\t}\n\n\treturn cache[ 'DefaultMaterial' ];\n\n}\n\nfunction addUnknownExtensionsToUserData( knownExtensions, object, objectDef ) {\n\n\t// Add unknown glTF extensions to an object's userData.\n\n\tfor ( const name in objectDef.extensions ) {\n\n\t\tif ( knownExtensions[ name ] === undefined ) {\n\n\t\t\tobject.userData.gltfExtensions = object.userData.gltfExtensions || {};\n\t\t\tobject.userData.gltfExtensions[ name ] = objectDef.extensions[ name ];\n\n\t\t}\n\n\t}\n\n}\n\n/**\n *\n * @private\n * @param {Object3D|Material|BufferGeometry|Object|AnimationClip} object\n * @param {GLTF.definition} gltfDef\n */\nfunction assignExtrasToUserData( object, gltfDef ) {\n\n\tif ( gltfDef.extras !== undefined ) {\n\n\t\tif ( typeof gltfDef.extras === 'object' ) {\n\n\t\t\tObject.assign( object.userData, gltfDef.extras );\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.GLTFLoader: Ignoring primitive type .extras, ' + gltfDef.extras );\n\n\t\t}\n\n\t}\n\n}\n\n/**\n * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#morph-targets\n *\n * @private\n * @param {BufferGeometry} geometry\n * @param {Array<GLTF.Target>} targets\n * @param {GLTFParser} parser\n * @return {Promise<BufferGeometry>}\n */\nfunction addMorphTargets( geometry, targets, parser ) {\n\n\tlet hasMorphPosition = false;\n\tlet hasMorphNormal = false;\n\tlet hasMorphColor = false;\n\n\tfor ( let i = 0, il = targets.length; i < il; i ++ ) {\n\n\t\tconst target = targets[ i ];\n\n\t\tif ( target.POSITION !== undefined ) hasMorphPosition = true;\n\t\tif ( target.NORMAL !== undefined ) hasMorphNormal = true;\n\t\tif ( target.COLOR_0 !== undefined ) hasMorphColor = true;\n\n\t\tif ( hasMorphPosition && hasMorphNormal && hasMorphColor ) break;\n\n\t}\n\n\tif ( ! hasMorphPosition && ! hasMorphNormal && ! hasMorphColor ) return Promise.resolve( geometry );\n\n\tconst pendingPositionAccessors = [];\n\tconst pendingNormalAccessors = [];\n\tconst pendingColorAccessors = [];\n\n\tfor ( let i = 0, il = targets.length; i < il; i ++ ) {\n\n\t\tconst target = targets[ i ];\n\n\t\tif ( hasMorphPosition ) {\n\n\t\t\tconst pendingAccessor = target.POSITION !== undefined\n\t\t\t\t? parser.getDependency( 'accessor', target.POSITION )\n\t\t\t\t: geometry.attributes.position;\n\n\t\t\tpendingPositionAccessors.push( pendingAccessor );\n\n\t\t}\n\n\t\tif ( hasMorphNormal ) {\n\n\t\t\tconst pendingAccessor = target.NORMAL !== undefined\n\t\t\t\t? parser.getDependency( 'accessor', target.NORMAL )\n\t\t\t\t: geometry.attributes.normal;\n\n\t\t\tpendingNormalAccessors.push( pendingAccessor );\n\n\t\t}\n\n\t\tif ( hasMorphColor ) {\n\n\t\t\tconst pendingAccessor = target.COLOR_0 !== undefined\n\t\t\t\t? parser.getDependency( 'accessor', target.COLOR_0 )\n\t\t\t\t: geometry.attributes.color;\n\n\t\t\tpendingColorAccessors.push( pendingAccessor );\n\n\t\t}\n\n\t}\n\n\treturn Promise.all( [\n\t\tPromise.all( pendingPositionAccessors ),\n\t\tPromise.all( pendingNormalAccessors ),\n\t\tPromise.all( pendingColorAccessors )\n\t] ).then( function ( accessors ) {\n\n\t\tconst morphPositions = accessors[ 0 ];\n\t\tconst morphNormals = accessors[ 1 ];\n\t\tconst morphColors = accessors[ 2 ];\n\n\t\tif ( hasMorphPosition ) geometry.morphAttributes.position = morphPositions;\n\t\tif ( hasMorphNormal ) geometry.morphAttributes.normal = morphNormals;\n\t\tif ( hasMorphColor ) geometry.morphAttributes.color = morphColors;\n\t\tgeometry.morphTargetsRelative = true;\n\n\t\treturn geometry;\n\n\t} );\n\n}\n\n/**\n *\n * @private\n * @param {Mesh} mesh\n * @param {GLTF.Mesh} meshDef\n */\nfunction updateMorphTargets( mesh, meshDef ) {\n\n\tmesh.updateMorphTargets();\n\n\tif ( meshDef.weights !== undefined ) {\n\n\t\tfor ( let i = 0, il = meshDef.weights.length; i < il; i ++ ) {\n\n\t\t\tmesh.morphTargetInfluences[ i ] = meshDef.weights[ i ];\n\n\t\t}\n\n\t}\n\n\t// .extras has user-defined data, so check that .extras.targetNames is an array.\n\tif ( meshDef.extras && Array.isArray( meshDef.extras.targetNames ) ) {\n\n\t\tconst targetNames = meshDef.extras.targetNames;\n\n\t\tif ( mesh.morphTargetInfluences.length === targetNames.length ) {\n\n\t\t\tmesh.morphTargetDictionary = {};\n\n\t\t\tfor ( let i = 0, il = targetNames.length; i < il; i ++ ) {\n\n\t\t\t\tmesh.morphTargetDictionary[ targetNames[ i ] ] = i;\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.GLTFLoader: Invalid extras.targetNames length. Ignoring names.' );\n\n\t\t}\n\n\t}\n\n}\n\nfunction createPrimitiveKey( primitiveDef ) {\n\n\tlet geometryKey;\n\n\tconst dracoExtension = primitiveDef.extensions && primitiveDef.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ];\n\n\tif ( dracoExtension ) {\n\n\t\tgeometryKey = 'draco:' + dracoExtension.bufferView\n\t\t\t\t+ ':' + dracoExtension.indices\n\t\t\t\t+ ':' + createAttributesKey( dracoExtension.attributes );\n\n\t} else {\n\n\t\tgeometryKey = primitiveDef.indices + ':' + createAttributesKey( primitiveDef.attributes ) + ':' + primitiveDef.mode;\n\n\t}\n\n\tif ( primitiveDef.targets !== undefined ) {\n\n\t\tfor ( let i = 0, il = primitiveDef.targets.length; i < il; i ++ ) {\n\n\t\t\tgeometryKey += ':' + createAttributesKey( primitiveDef.targets[ i ] );\n\n\t\t}\n\n\t}\n\n\treturn geometryKey;\n\n}\n\nfunction createAttributesKey( attributes ) {\n\n\tlet attributesKey = '';\n\n\tconst keys = Object.keys( attributes ).sort();\n\n\tfor ( let i = 0, il = keys.length; i < il; i ++ ) {\n\n\t\tattributesKey += keys[ i ] + ':' + attributes[ keys[ i ] ] + ';';\n\n\t}\n\n\treturn attributesKey;\n\n}\n\nfunction getNormalizedComponentScale( constructor ) {\n\n\t// Reference:\n\t// https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization#encoding-quantized-data\n\n\tswitch ( constructor ) {\n\n\t\tcase Int8Array:\n\t\t\treturn 1 / 127;\n\n\t\tcase Uint8Array:\n\t\t\treturn 1 / 255;\n\n\t\tcase Int16Array:\n\t\t\treturn 1 / 32767;\n\n\t\tcase Uint16Array:\n\t\t\treturn 1 / 65535;\n\n\t\tdefault:\n\t\t\tthrow new Error( 'THREE.GLTFLoader: Unsupported normalized accessor component type.' );\n\n\t}\n\n}\n\nfunction getImageURIMimeType( uri ) {\n\n\tif ( uri.search( /\\.jpe?g($|\\?)/i ) > 0 || uri.search( /^data\\:image\\/jpeg/ ) === 0 ) return 'image/jpeg';\n\tif ( uri.search( /\\.webp($|\\?)/i ) > 0 || uri.search( /^data\\:image\\/webp/ ) === 0 ) return 'image/webp';\n\tif ( uri.search( /\\.ktx2($|\\?)/i ) > 0 || uri.search( /^data\\:image\\/ktx2/ ) === 0 ) return 'image/ktx2';\n\n\treturn 'image/png';\n\n}\n\nconst _identityMatrix = new Matrix4();\n\n/* GLTF PARSER */\n\nclass GLTFParser {\n\n\tconstructor( json = {}, options = {} ) {\n\n\t\tthis.json = json;\n\t\tthis.extensions = {};\n\t\tthis.plugins = {};\n\t\tthis.options = options;\n\n\t\t// loader object cache\n\t\tthis.cache = new GLTFRegistry();\n\n\t\t// associations between Three.js objects and glTF elements\n\t\tthis.associations = new Map();\n\n\t\t// BufferGeometry caching\n\t\tthis.primitiveCache = {};\n\n\t\t// Node cache\n\t\tthis.nodeCache = {};\n\n\t\t// Object3D instance caches\n\t\tthis.meshCache = { refs: {}, uses: {} };\n\t\tthis.cameraCache = { refs: {}, uses: {} };\n\t\tthis.lightCache = { refs: {}, uses: {} };\n\n\t\tthis.sourceCache = {};\n\t\tthis.textureCache = {};\n\n\t\t// Track node names, to ensure no duplicates\n\t\tthis.nodeNamesUsed = {};\n\n\t\t// Use an ImageBitmapLoader if imageBitmaps are supported. Moves much of the\n\t\t// expensive work of uploading a texture to the GPU off the main thread.\n\n\t\tlet isSafari = false;\n\t\tlet safariVersion = - 1;\n\t\tlet isFirefox = false;\n\t\tlet firefoxVersion = - 1;\n\n\t\tif ( typeof navigator !== 'undefined' && typeof navigator.userAgent !== 'undefined' ) {\n\n\t\t\tconst userAgent = navigator.userAgent;\n\n\t\t\tisSafari = /^((?!chrome|android).)*safari/i.test( userAgent ) === true;\n\t\t\tconst safariMatch = userAgent.match( /Version\\/(\\d+)/ );\n\t\t\tsafariVersion = isSafari && safariMatch ? parseInt( safariMatch[ 1 ], 10 ) : - 1;\n\n\t\t\tisFirefox = userAgent.indexOf( 'Firefox' ) > - 1;\n\t\t\tfirefoxVersion = isFirefox ? userAgent.match( /Firefox\\/([0-9]+)\\./ )[ 1 ] : - 1;\n\n\t\t}\n\n\t\tif ( typeof createImageBitmap === 'undefined' || ( isSafari && safariVersion < 17 ) || ( isFirefox && firefoxVersion < 98 ) ) {\n\n\t\t\tthis.textureLoader = new TextureLoader( this.options.manager );\n\n\t\t} else {\n\n\t\t\tthis.textureLoader = new ImageBitmapLoader( this.options.manager );\n\n\t\t}\n\n\t\tthis.textureLoader.setCrossOrigin( this.options.crossOrigin );\n\t\tthis.textureLoader.setRequestHeader( this.options.requestHeader );\n\n\t\tthis.fileLoader = new FileLoader( this.options.manager );\n\t\tthis.fileLoader.setResponseType( 'arraybuffer' );\n\n\t\tif ( this.options.crossOrigin === 'use-credentials' ) {\n\n\t\t\tthis.fileLoader.setWithCredentials( true );\n\n\t\t}\n\n\t}\n\n\tsetExtensions( extensions ) {\n\n\t\tthis.extensions = extensions;\n\n\t}\n\n\tsetPlugins( plugins ) {\n\n\t\tthis.plugins = plugins;\n\n\t}\n\n\tparse( onLoad, onError ) {\n\n\t\tconst parser = this;\n\t\tconst json = this.json;\n\t\tconst extensions = this.extensions;\n\n\t\t// Clear the loader cache\n\t\tthis.cache.removeAll();\n\t\tthis.nodeCache = {};\n\n\t\t// Mark the special nodes/meshes in json for efficient parse\n\t\tthis._invokeAll( function ( ext ) {\n\n\t\t\treturn ext._markDefs && ext._markDefs();\n\n\t\t} );\n\n\t\tPromise.all( this._invokeAll( function ( ext ) {\n\n\t\t\treturn ext.beforeRoot && ext.beforeRoot();\n\n\t\t} ) ).then( function () {\n\n\t\t\treturn Promise.all( [\n\n\t\t\t\tparser.getDependencies( 'scene' ),\n\t\t\t\tparser.getDependencies( 'animation' ),\n\t\t\t\tparser.getDependencies( 'camera' ),\n\n\t\t\t] );\n\n\t\t} ).then( function ( dependencies ) {\n\n\t\t\tconst result = {\n\t\t\t\tscene: dependencies[ 0 ][ json.scene || 0 ],\n\t\t\t\tscenes: dependencies[ 0 ],\n\t\t\t\tanimations: dependencies[ 1 ],\n\t\t\t\tcameras: dependencies[ 2 ],\n\t\t\t\tasset: json.asset,\n\t\t\t\tparser: parser,\n\t\t\t\tuserData: {}\n\t\t\t};\n\n\t\t\taddUnknownExtensionsToUserData( extensions, result, json );\n\n\t\t\tassignExtrasToUserData( result, json );\n\n\t\t\treturn Promise.all( parser._invokeAll( function ( ext ) {\n\n\t\t\t\treturn ext.afterRoot && ext.afterRoot( result );\n\n\t\t\t} ) ).then( function () {\n\n\t\t\t\tfor ( const scene of result.scenes ) {\n\n\t\t\t\t\tscene.updateMatrixWorld();\n\n\t\t\t\t}\n\n\t\t\t\tonLoad( result );\n\n\t\t\t} );\n\n\t\t} ).catch( onError );\n\n\t}\n\n\t/**\n\t * Marks the special nodes/meshes in json for efficient parse.\n\t *\n\t * @private\n\t */\n\t_markDefs() {\n\n\t\tconst nodeDefs = this.json.nodes || [];\n\t\tconst skinDefs = this.json.skins || [];\n\t\tconst meshDefs = this.json.meshes || [];\n\n\t\t// Nothing in the node definition indicates whether it is a Bone or an\n\t\t// Object3D. Use the skins' joint references to mark bones.\n\t\tfor ( let skinIndex = 0, skinLength = skinDefs.length; skinIndex < skinLength; skinIndex ++ ) {\n\n\t\t\tconst joints = skinDefs[ skinIndex ].joints;\n\n\t\t\tfor ( let i = 0, il = joints.length; i < il; i ++ ) {\n\n\t\t\t\tnodeDefs[ joints[ i ] ].isBone = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Iterate over all nodes, marking references to shared resources,\n\t\t// as well as skeleton joints.\n\t\tfor ( let nodeIndex = 0, nodeLength = nodeDefs.length; nodeIndex < nodeLength; nodeIndex ++ ) {\n\n\t\t\tconst nodeDef = nodeDefs[ nodeIndex ];\n\n\t\t\tif ( nodeDef.mesh !== undefined ) {\n\n\t\t\t\tthis._addNodeRef( this.meshCache, nodeDef.mesh );\n\n\t\t\t\t// Nothing in the mesh definition indicates whether it is\n\t\t\t\t// a SkinnedMesh or Mesh. Use the node's mesh reference\n\t\t\t\t// to mark SkinnedMesh if node has skin.\n\t\t\t\tif ( nodeDef.skin !== undefined ) {\n\n\t\t\t\t\tmeshDefs[ nodeDef.mesh ].isSkinnedMesh = true;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( nodeDef.camera !== undefined ) {\n\n\t\t\t\tthis._addNodeRef( this.cameraCache, nodeDef.camera );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Counts references to shared node / Object3D resources. These resources\n\t * can be reused, or \"instantiated\", at multiple nodes in the scene\n\t * hierarchy. Mesh, Camera, and Light instances are instantiated and must\n\t * be marked. Non-scenegraph resources (like Materials, Geometries, and\n\t * Textures) can be reused directly and are not marked here.\n\t *\n\t * Example: CesiumMilkTruck sample model reuses \"Wheel\" meshes.\n\t *\n\t * @private\n\t * @param {Object} cache\n\t * @param {Object3D} index\n\t */\n\t_addNodeRef( cache, index ) {\n\n\t\tif ( index === undefined ) return;\n\n\t\tif ( cache.refs[ index ] === undefined ) {\n\n\t\t\tcache.refs[ index ] = cache.uses[ index ] = 0;\n\n\t\t}\n\n\t\tcache.refs[ index ] ++;\n\n\t}\n\n\t/**\n\t * Returns a reference to a shared resource, cloning it if necessary.\n\t *\n\t * @private\n\t * @param {Object} cache\n\t * @param {number} index\n\t * @param {Object} object\n\t * @return {Object}\n\t */\n\t_getNodeRef( cache, index, object ) {\n\n\t\tif ( cache.refs[ index ] <= 1 ) return object;\n\n\t\tconst ref = object.clone();\n\n\t\t// Propagates mappings to the cloned object, prevents mappings on the\n\t\t// original object from being lost.\n\t\tconst updateMappings = ( original, clone ) => {\n\n\t\t\tconst mappings = this.associations.get( original );\n\t\t\tif ( mappings != null ) {\n\n\t\t\t\tthis.associations.set( clone, mappings );\n\n\t\t\t}\n\n\t\t\tfor ( const [ i, child ] of original.children.entries() ) {\n\n\t\t\t\tupdateMappings( child, clone.children[ i ] );\n\n\t\t\t}\n\n\t\t};\n\n\t\tupdateMappings( object, ref );\n\n\t\tref.name += '_instance_' + ( cache.uses[ index ] ++ );\n\n\t\treturn ref;\n\n\t}\n\n\t_invokeOne( func ) {\n\n\t\tconst extensions = Object.values( this.plugins );\n\t\textensions.push( this );\n\n\t\tfor ( let i = 0; i < extensions.length; i ++ ) {\n\n\t\t\tconst result = func( extensions[ i ] );\n\n\t\t\tif ( result ) return result;\n\n\t\t}\n\n\t\treturn null;\n\n\t}\n\n\t_invokeAll( func ) {\n\n\t\tconst extensions = Object.values( this.plugins );\n\t\textensions.unshift( this );\n\n\t\tconst pending = [];\n\n\t\tfor ( let i = 0; i < extensions.length; i ++ ) {\n\n\t\t\tconst result = func( extensions[ i ] );\n\n\t\t\tif ( result ) pending.push( result );\n\n\t\t}\n\n\t\treturn pending;\n\n\t}\n\n\t/**\n\t * Requests the specified dependency asynchronously, with caching.\n\t *\n\t * @private\n\t * @param {string} type\n\t * @param {number} index\n\t * @return {Promise<Object3D|Material|Texture|AnimationClip|ArrayBuffer|Object>}\n\t */\n\tgetDependency( type, index ) {\n\n\t\tconst cacheKey = type + ':' + index;\n\t\tlet dependency = this.cache.get( cacheKey );\n\n\t\tif ( ! dependency ) {\n\n\t\t\tswitch ( type ) {\n\n\t\t\t\tcase 'scene':\n\t\t\t\t\tdependency = this.loadScene( index );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'node':\n\t\t\t\t\tdependency = this._invokeOne( function ( ext ) {\n\n\t\t\t\t\t\treturn ext.loadNode && ext.loadNode( index );\n\n\t\t\t\t\t} );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'mesh':\n\t\t\t\t\tdependency = this._invokeOne( function ( ext ) {\n\n\t\t\t\t\t\treturn ext.loadMesh && ext.loadMesh( index );\n\n\t\t\t\t\t} );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'accessor':\n\t\t\t\t\tdependency = this.loadAccessor( index );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'bufferView':\n\t\t\t\t\tdependency = this._invokeOne( function ( ext ) {\n\n\t\t\t\t\t\treturn ext.loadBufferView && ext.loadBufferView( index );\n\n\t\t\t\t\t} );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'buffer':\n\t\t\t\t\tdependency = this.loadBuffer( index );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'material':\n\t\t\t\t\tdependency = this._invokeOne( function ( ext ) {\n\n\t\t\t\t\t\treturn ext.loadMaterial && ext.loadMaterial( index );\n\n\t\t\t\t\t} );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'texture':\n\t\t\t\t\tdependency = this._invokeOne( function ( ext ) {\n\n\t\t\t\t\t\treturn ext.loadTexture && ext.loadTexture( index );\n\n\t\t\t\t\t} );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'skin':\n\t\t\t\t\tdependency = this.loadSkin( index );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'animation':\n\t\t\t\t\tdependency = this._invokeOne( function ( ext ) {\n\n\t\t\t\t\t\treturn ext.loadAnimation && ext.loadAnimation( index );\n\n\t\t\t\t\t} );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'camera':\n\t\t\t\t\tdependency = this.loadCamera( index );\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\tdependency = this._invokeOne( function ( ext ) {\n\n\t\t\t\t\t\treturn ext != this && ext.getDependency && ext.getDependency( type, index );\n\n\t\t\t\t\t} );\n\n\t\t\t\t\tif ( ! dependency ) {\n\n\t\t\t\t\t\tthrow new Error( 'Unknown type: ' + type );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tthis.cache.add( cacheKey, dependency );\n\n\t\t}\n\n\t\treturn dependency;\n\n\t}\n\n\t/**\n\t * Requests all dependencies of the specified type asynchronously, with caching.\n\t *\n\t * @private\n\t * @param {string} type\n\t * @return {Promise<Array<Object>>}\n\t */\n\tgetDependencies( type ) {\n\n\t\tlet dependencies = this.cache.get( type );\n\n\t\tif ( ! dependencies ) {\n\n\t\t\tconst parser = this;\n\t\t\tconst defs = this.json[ type + ( type === 'mesh' ? 'es' : 's' ) ] || [];\n\n\t\t\tdependencies = Promise.all( defs.map( function ( def, index ) {\n\n\t\t\t\treturn parser.getDependency( type, index );\n\n\t\t\t} ) );\n\n\t\t\tthis.cache.add( type, dependencies );\n\n\t\t}\n\n\t\treturn dependencies;\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views\n\t *\n\t * @private\n\t * @param {number} bufferIndex\n\t * @return {Promise<ArrayBuffer>}\n\t */\n\tloadBuffer( bufferIndex ) {\n\n\t\tconst bufferDef = this.json.buffers[ bufferIndex ];\n\t\tconst loader = this.fileLoader;\n\n\t\tif ( bufferDef.type && bufferDef.type !== 'arraybuffer' ) {\n\n\t\t\tthrow new Error( 'THREE.GLTFLoader: ' + bufferDef.type + ' buffer type is not supported.' );\n\n\t\t}\n\n\t\t// If present, GLB container is required to be the first buffer.\n\t\tif ( bufferDef.uri === undefined && bufferIndex === 0 ) {\n\n\t\t\treturn Promise.resolve( this.extensions[ EXTENSIONS.KHR_BINARY_GLTF ].body );\n\n\t\t}\n\n\t\tconst options = this.options;\n\n\t\treturn new Promise( function ( resolve, reject ) {\n\n\t\t\tloader.load( LoaderUtils.resolveURL( bufferDef.uri, options.path ), resolve, undefined, function () {\n\n\t\t\t\treject( new Error( 'THREE.GLTFLoader: Failed to load buffer \"' + bufferDef.uri + '\".' ) );\n\n\t\t\t} );\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views\n\t *\n\t * @private\n\t * @param {number} bufferViewIndex\n\t * @return {Promise<ArrayBuffer>}\n\t */\n\tloadBufferView( bufferViewIndex ) {\n\n\t\tconst bufferViewDef = this.json.bufferViews[ bufferViewIndex ];\n\n\t\treturn this.getDependency( 'buffer', bufferViewDef.buffer ).then( function ( buffer ) {\n\n\t\t\tconst byteLength = bufferViewDef.byteLength || 0;\n\t\t\tconst byteOffset = bufferViewDef.byteOffset || 0;\n\t\t\treturn buffer.slice( byteOffset, byteOffset + byteLength );\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#accessors\n\t *\n\t * @private\n\t * @param {number} accessorIndex\n\t * @return {Promise<BufferAttribute|InterleavedBufferAttribute>}\n\t */\n\tloadAccessor( accessorIndex ) {\n\n\t\tconst parser = this;\n\t\tconst json = this.json;\n\n\t\tconst accessorDef = this.json.accessors[ accessorIndex ];\n\n\t\tif ( accessorDef.bufferView === undefined && accessorDef.sparse === undefined ) {\n\n\t\t\tconst itemSize = WEBGL_TYPE_SIZES[ accessorDef.type ];\n\t\t\tconst TypedArray = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ];\n\t\t\tconst normalized = accessorDef.normalized === true;\n\n\t\t\tconst array = new TypedArray( accessorDef.count * itemSize );\n\t\t\treturn Promise.resolve( new BufferAttribute( array, itemSize, normalized ) );\n\n\t\t}\n\n\t\tconst pendingBufferViews = [];\n\n\t\tif ( accessorDef.bufferView !== undefined ) {\n\n\t\t\tpendingBufferViews.push( this.getDependency( 'bufferView', accessorDef.bufferView ) );\n\n\t\t} else {\n\n\t\t\tpendingBufferViews.push( null );\n\n\t\t}\n\n\t\tif ( accessorDef.sparse !== undefined ) {\n\n\t\t\tpendingBufferViews.push( this.getDependency( 'bufferView', accessorDef.sparse.indices.bufferView ) );\n\t\t\tpendingBufferViews.push( this.getDependency( 'bufferView', accessorDef.sparse.values.bufferView ) );\n\n\t\t}\n\n\t\treturn Promise.all( pendingBufferViews ).then( function ( bufferViews ) {\n\n\t\t\tconst bufferView = bufferViews[ 0 ];\n\n\t\t\tconst itemSize = WEBGL_TYPE_SIZES[ accessorDef.type ];\n\t\t\tconst TypedArray = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ];\n\n\t\t\t// For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12.\n\t\t\tconst elementBytes = TypedArray.BYTES_PER_ELEMENT;\n\t\t\tconst itemBytes = elementBytes * itemSize;\n\t\t\tconst byteOffset = accessorDef.byteOffset || 0;\n\t\t\tconst byteStride = accessorDef.bufferView !== undefined ? json.bufferViews[ accessorDef.bufferView ].byteStride : undefined;\n\t\t\tconst normalized = accessorDef.normalized === true;\n\t\t\tlet array, bufferAttribute;\n\n\t\t\t// The buffer is not interleaved if the stride is the item size in bytes.\n\t\t\tif ( byteStride && byteStride !== itemBytes ) {\n\n\t\t\t\t// Each \"slice\" of the buffer, as defined by 'count' elements of 'byteStride' bytes, gets its own InterleavedBuffer\n\t\t\t\t// This makes sure that IBA.count reflects accessor.count properly\n\t\t\t\tconst ibSlice = Math.floor( byteOffset / byteStride );\n\t\t\t\tconst ibCacheKey = 'InterleavedBuffer:' + accessorDef.bufferView + ':' + accessorDef.componentType + ':' + ibSlice + ':' + accessorDef.count;\n\t\t\t\tlet ib = parser.cache.get( ibCacheKey );\n\n\t\t\t\tif ( ! ib ) {\n\n\t\t\t\t\tarray = new TypedArray( bufferView, ibSlice * byteStride, accessorDef.count * byteStride / elementBytes );\n\n\t\t\t\t\t// Integer parameters to IB/IBA are in array elements, not bytes.\n\t\t\t\t\tib = new InterleavedBuffer( array, byteStride / elementBytes );\n\n\t\t\t\t\tparser.cache.add( ibCacheKey, ib );\n\n\t\t\t\t}\n\n\t\t\t\tbufferAttribute = new InterleavedBufferAttribute( ib, itemSize, ( byteOffset % byteStride ) / elementBytes, normalized );\n\n\t\t\t} else {\n\n\t\t\t\tif ( bufferView === null ) {\n\n\t\t\t\t\tarray = new TypedArray( accessorDef.count * itemSize );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tarray = new TypedArray( bufferView, byteOffset, accessorDef.count * itemSize );\n\n\t\t\t\t}\n\n\t\t\t\tbufferAttribute = new BufferAttribute( array, itemSize, normalized );\n\n\t\t\t}\n\n\t\t\t// https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#sparse-accessors\n\t\t\tif ( accessorDef.sparse !== undefined ) {\n\n\t\t\t\tconst itemSizeIndices = WEBGL_TYPE_SIZES.SCALAR;\n\t\t\t\tconst TypedArrayIndices = WEBGL_COMPONENT_TYPES[ accessorDef.sparse.indices.componentType ];\n\n\t\t\t\tconst byteOffsetIndices = accessorDef.sparse.indices.byteOffset || 0;\n\t\t\t\tconst byteOffsetValues = accessorDef.sparse.values.byteOffset || 0;\n\n\t\t\t\tconst sparseIndices = new TypedArrayIndices( bufferViews[ 1 ], byteOffsetIndices, accessorDef.sparse.count * itemSizeIndices );\n\t\t\t\tconst sparseValues = new TypedArray( bufferViews[ 2 ], byteOffsetValues, accessorDef.sparse.count * itemSize );\n\n\t\t\t\tif ( bufferView !== null ) {\n\n\t\t\t\t\t// Avoid modifying the original ArrayBuffer, if the bufferView wasn't initialized with zeroes.\n\t\t\t\t\tbufferAttribute = new BufferAttribute( bufferAttribute.array.slice(), bufferAttribute.itemSize, bufferAttribute.normalized );\n\n\t\t\t\t}\n\n\t\t\t\t// Ignore normalized since we copy from sparse\n\t\t\t\tbufferAttribute.normalized = false;\n\n\t\t\t\tfor ( let i = 0, il = sparseIndices.length; i < il; i ++ ) {\n\n\t\t\t\t\tconst index = sparseIndices[ i ];\n\n\t\t\t\t\tbufferAttribute.setX( index, sparseValues[ i * itemSize ] );\n\t\t\t\t\tif ( itemSize >= 2 ) bufferAttribute.setY( index, sparseValues[ i * itemSize + 1 ] );\n\t\t\t\t\tif ( itemSize >= 3 ) bufferAttribute.setZ( index, sparseValues[ i * itemSize + 2 ] );\n\t\t\t\t\tif ( itemSize >= 4 ) bufferAttribute.setW( index, sparseValues[ i * itemSize + 3 ] );\n\t\t\t\t\tif ( itemSize >= 5 ) throw new Error( 'THREE.GLTFLoader: Unsupported itemSize in sparse BufferAttribute.' );\n\n\t\t\t\t}\n\n\t\t\t\tbufferAttribute.normalized = normalized;\n\n\t\t\t}\n\n\t\t\treturn bufferAttribute;\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#textures\n\t *\n\t * @private\n\t * @param {number} textureIndex\n\t * @return {Promise<?Texture>}\n\t */\n\tloadTexture( textureIndex ) {\n\n\t\tconst json = this.json;\n\t\tconst options = this.options;\n\t\tconst textureDef = json.textures[ textureIndex ];\n\t\tconst sourceIndex = textureDef.source;\n\t\tconst sourceDef = json.images[ sourceIndex ];\n\n\t\tlet loader = this.textureLoader;\n\n\t\tif ( sourceDef.uri ) {\n\n\t\t\tconst handler = options.manager.getHandler( sourceDef.uri );\n\t\t\tif ( handler !== null ) loader = handler;\n\n\t\t}\n\n\t\treturn this.loadTextureImage( textureIndex, sourceIndex, loader );\n\n\t}\n\n\tloadTextureImage( textureIndex, sourceIndex, loader ) {\n\n\t\tconst parser = this;\n\t\tconst json = this.json;\n\n\t\tconst textureDef = json.textures[ textureIndex ];\n\t\tconst sourceDef = json.images[ sourceIndex ];\n\n\t\tconst cacheKey = ( sourceDef.uri || sourceDef.bufferView ) + ':' + textureDef.sampler;\n\n\t\tif ( this.textureCache[ cacheKey ] ) {\n\n\t\t\t// See https://github.com/mrdoob/three.js/issues/21559.\n\t\t\treturn this.textureCache[ cacheKey ];\n\n\t\t}\n\n\t\tconst promise = this.loadImageSource( sourceIndex, loader ).then( function ( texture ) {\n\n\t\t\ttexture.flipY = false;\n\n\t\t\ttexture.name = textureDef.name || sourceDef.name || '';\n\n\t\t\tif ( texture.name === '' && typeof sourceDef.uri === 'string' && sourceDef.uri.startsWith( 'data:image/' ) === false ) {\n\n\t\t\t\ttexture.name = sourceDef.uri;\n\n\t\t\t}\n\n\t\t\tconst samplers = json.samplers || {};\n\t\t\tconst sampler = samplers[ textureDef.sampler ] || {};\n\n\t\t\ttexture.magFilter = WEBGL_FILTERS[ sampler.magFilter ] || LinearFilter;\n\t\t\ttexture.minFilter = WEBGL_FILTERS[ sampler.minFilter ] || LinearMipmapLinearFilter;\n\t\t\ttexture.wrapS = WEBGL_WRAPPINGS[ sampler.wrapS ] || RepeatWrapping;\n\t\t\ttexture.wrapT = WEBGL_WRAPPINGS[ sampler.wrapT ] || RepeatWrapping;\n\t\t\ttexture.generateMipmaps = ! texture.isCompressedTexture && texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter;\n\n\t\t\tparser.associations.set( texture, { textures: textureIndex } );\n\n\t\t\treturn texture;\n\n\t\t} ).catch( function () {\n\n\t\t\treturn null;\n\n\t\t} );\n\n\t\tthis.textureCache[ cacheKey ] = promise;\n\n\t\treturn promise;\n\n\t}\n\n\tloadImageSource( sourceIndex, loader ) {\n\n\t\tconst parser = this;\n\t\tconst json = this.json;\n\t\tconst options = this.options;\n\n\t\tif ( this.sourceCache[ sourceIndex ] !== undefined ) {\n\n\t\t\treturn this.sourceCache[ sourceIndex ].then( ( texture ) => texture.clone() );\n\n\t\t}\n\n\t\tconst sourceDef = json.images[ sourceIndex ];\n\n\t\tconst URL = self.URL || self.webkitURL;\n\n\t\tlet sourceURI = sourceDef.uri || '';\n\t\tlet isObjectURL = false;\n\n\t\tif ( sourceDef.bufferView !== undefined ) {\n\n\t\t\t// Load binary image data from bufferView, if provided.\n\n\t\t\tsourceURI = parser.getDependency( 'bufferView', sourceDef.bufferView ).then( function ( bufferView ) {\n\n\t\t\t\tisObjectURL = true;\n\t\t\t\tconst blob = new Blob( [ bufferView ], { type: sourceDef.mimeType } );\n\t\t\t\tsourceURI = URL.createObjectURL( blob );\n\t\t\t\treturn sourceURI;\n\n\t\t\t} );\n\n\t\t} else if ( sourceDef.uri === undefined ) {\n\n\t\t\tthrow new Error( 'THREE.GLTFLoader: Image ' + sourceIndex + ' is missing URI and bufferView' );\n\n\t\t}\n\n\t\tconst promise = Promise.resolve( sourceURI ).then( function ( sourceURI ) {\n\n\t\t\treturn new Promise( function ( resolve, reject ) {\n\n\t\t\t\tlet onLoad = resolve;\n\n\t\t\t\tif ( loader.isImageBitmapLoader === true ) {\n\n\t\t\t\t\tonLoad = function ( imageBitmap ) {\n\n\t\t\t\t\t\tconst texture = new Texture( imageBitmap );\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tresolve( texture );\n\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\tloader.load( LoaderUtils.resolveURL( sourceURI, options.path ), onLoad, undefined, reject );\n\n\t\t\t} );\n\n\t\t} ).then( function ( texture ) {\n\n\t\t\t// Clean up resources and configure Texture.\n\n\t\t\tif ( isObjectURL === true ) {\n\n\t\t\t\tURL.revokeObjectURL( sourceURI );\n\n\t\t\t}\n\n\t\t\tassignExtrasToUserData( texture, sourceDef );\n\n\t\t\ttexture.userData.mimeType = sourceDef.mimeType || getImageURIMimeType( sourceDef.uri );\n\n\t\t\treturn texture;\n\n\t\t} ).catch( function ( error ) {\n\n\t\t\tconsole.error( 'THREE.GLTFLoader: Couldn\\'t load texture', sourceURI );\n\t\t\tthrow error;\n\n\t\t} );\n\n\t\tthis.sourceCache[ sourceIndex ] = promise;\n\t\treturn promise;\n\n\t}\n\n\t/**\n\t * Asynchronously assigns a texture to the given material parameters.\n\t *\n\t * @private\n\t * @param {Object} materialParams\n\t * @param {string} mapName\n\t * @param {Object} mapDef\n\t * @param {string} [colorSpace]\n\t * @return {Promise<Texture>}\n\t */\n\tassignTexture( materialParams, mapName, mapDef, colorSpace ) {\n\n\t\tconst parser = this;\n\n\t\treturn this.getDependency( 'texture', mapDef.index ).then( function ( texture ) {\n\n\t\t\tif ( ! texture ) return null;\n\n\t\t\tif ( mapDef.texCoord !== undefined && mapDef.texCoord > 0 ) {\n\n\t\t\t\ttexture = texture.clone();\n\t\t\t\ttexture.channel = mapDef.texCoord;\n\n\t\t\t}\n\n\t\t\tif ( parser.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] ) {\n\n\t\t\t\tconst transform = mapDef.extensions !== undefined ? mapDef.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] : undefined;\n\n\t\t\t\tif ( transform ) {\n\n\t\t\t\t\tconst gltfReference = parser.associations.get( texture );\n\t\t\t\t\ttexture = parser.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ].extendTexture( texture, transform );\n\t\t\t\t\tparser.associations.set( texture, gltfReference );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( colorSpace !== undefined ) {\n\n\t\t\t\ttexture.colorSpace = colorSpace;\n\n\t\t\t}\n\n\t\t\tmaterialParams[ mapName ] = texture;\n\n\t\t\treturn texture;\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Assigns final material to a Mesh, Line, or Points instance. The instance\n\t * already has a material (generated from the glTF material options alone)\n\t * but reuse of the same glTF material may require multiple threejs materials\n\t * to accommodate different primitive types, defines, etc. New materials will\n\t * be created if necessary, and reused from a cache.\n\t *\n\t * @private\n\t * @param {Object3D} mesh Mesh, Line, or Points instance.\n\t */\n\tassignFinalMaterial( mesh ) {\n\n\t\tconst geometry = mesh.geometry;\n\t\tlet material = mesh.material;\n\n\t\tconst useDerivativeTangents = geometry.attributes.tangent === undefined;\n\t\tconst useVertexColors = geometry.attributes.color !== undefined;\n\t\tconst useFlatShading = geometry.attributes.normal === undefined;\n\n\t\tif ( mesh.isPoints ) {\n\n\t\t\tconst cacheKey = 'PointsMaterial:' + material.uuid;\n\n\t\t\tlet pointsMaterial = this.cache.get( cacheKey );\n\n\t\t\tif ( ! pointsMaterial ) {\n\n\t\t\t\tpointsMaterial = new PointsMaterial();\n\t\t\t\tMaterial.prototype.copy.call( pointsMaterial, material );\n\t\t\t\tpointsMaterial.color.copy( material.color );\n\t\t\t\tpointsMaterial.map = material.map;\n\t\t\t\tpointsMaterial.sizeAttenuation = false; // glTF spec says points should be 1px\n\n\t\t\t\tthis.cache.add( cacheKey, pointsMaterial );\n\n\t\t\t}\n\n\t\t\tmaterial = pointsMaterial;\n\n\t\t} else if ( mesh.isLine ) {\n\n\t\t\tconst cacheKey = 'LineBasicMaterial:' + material.uuid;\n\n\t\t\tlet lineMaterial = this.cache.get( cacheKey );\n\n\t\t\tif ( ! lineMaterial ) {\n\n\t\t\t\tlineMaterial = new LineBasicMaterial();\n\t\t\t\tMaterial.prototype.copy.call( lineMaterial, material );\n\t\t\t\tlineMaterial.color.copy( material.color );\n\t\t\t\tlineMaterial.map = material.map;\n\n\t\t\t\tthis.cache.add( cacheKey, lineMaterial );\n\n\t\t\t}\n\n\t\t\tmaterial = lineMaterial;\n\n\t\t}\n\n\t\t// Clone the material if it will be modified\n\t\tif ( useDerivativeTangents || useVertexColors || useFlatShading ) {\n\n\t\t\tlet cacheKey = 'ClonedMaterial:' + material.uuid + ':';\n\n\t\t\tif ( useDerivativeTangents ) cacheKey += 'derivative-tangents:';\n\t\t\tif ( useVertexColors ) cacheKey += 'vertex-colors:';\n\t\t\tif ( useFlatShading ) cacheKey += 'flat-shading:';\n\n\t\t\tlet cachedMaterial = this.cache.get( cacheKey );\n\n\t\t\tif ( ! cachedMaterial ) {\n\n\t\t\t\tcachedMaterial = material.clone();\n\n\t\t\t\tif ( useVertexColors ) cachedMaterial.vertexColors = true;\n\t\t\t\tif ( useFlatShading ) cachedMaterial.flatShading = true;\n\n\t\t\t\tif ( useDerivativeTangents ) {\n\n\t\t\t\t\t// https://github.com/mrdoob/three.js/issues/11438#issuecomment-507003995\n\t\t\t\t\tif ( cachedMaterial.normalScale ) cachedMaterial.normalScale.y *= - 1;\n\t\t\t\t\tif ( cachedMaterial.clearcoatNormalScale ) cachedMaterial.clearcoatNormalScale.y *= - 1;\n\n\t\t\t\t}\n\n\t\t\t\tthis.cache.add( cacheKey, cachedMaterial );\n\n\t\t\t\tthis.associations.set( cachedMaterial, this.associations.get( material ) );\n\n\t\t\t}\n\n\t\t\tmaterial = cachedMaterial;\n\n\t\t}\n\n\t\tmesh.material = material;\n\n\t}\n\n\tgetMaterialType( /* materialIndex */ ) {\n\n\t\treturn MeshStandardMaterial;\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#materials\n\t *\n\t * @private\n\t * @param {number} materialIndex\n\t * @return {Promise<Material>}\n\t */\n\tloadMaterial( materialIndex ) {\n\n\t\tconst parser = this;\n\t\tconst json = this.json;\n\t\tconst extensions = this.extensions;\n\t\tconst materialDef = json.materials[ materialIndex ];\n\n\t\tlet materialType;\n\t\tconst materialParams = {};\n\t\tconst materialExtensions = materialDef.extensions || {};\n\n\t\tconst pending = [];\n\n\t\tif ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ] ) {\n\n\t\t\tconst kmuExtension = extensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ];\n\t\t\tmaterialType = kmuExtension.getMaterialType();\n\t\t\tpending.push( kmuExtension.extendParams( materialParams, materialDef, parser ) );\n\n\t\t} else {\n\n\t\t\t// Specification:\n\t\t\t// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#metallic-roughness-material\n\n\t\t\tconst metallicRoughness = materialDef.pbrMetallicRoughness || {};\n\n\t\t\tmaterialParams.color = new Color( 1.0, 1.0, 1.0 );\n\t\t\tmaterialParams.opacity = 1.0;\n\n\t\t\tif ( Array.isArray( metallicRoughness.baseColorFactor ) ) {\n\n\t\t\t\tconst array = metallicRoughness.baseColorFactor;\n\n\t\t\t\tmaterialParams.color.setRGB( array[ 0 ], array[ 1 ], array[ 2 ], LinearSRGBColorSpace );\n\t\t\t\tmaterialParams.opacity = array[ 3 ];\n\n\t\t\t}\n\n\t\t\tif ( metallicRoughness.baseColorTexture !== undefined ) {\n\n\t\t\t\tpending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture, SRGBColorSpace ) );\n\n\t\t\t}\n\n\t\t\tmaterialParams.metalness = metallicRoughness.metallicFactor !== undefined ? metallicRoughness.metallicFactor : 1.0;\n\t\t\tmaterialParams.roughness = metallicRoughness.roughnessFactor !== undefined ? metallicRoughness.roughnessFactor : 1.0;\n\n\t\t\tif ( metallicRoughness.metallicRoughnessTexture !== undefined ) {\n\n\t\t\t\tpending.push( parser.assignTexture( materialParams, 'metalnessMap', metallicRoughness.metallicRoughnessTexture ) );\n\t\t\t\tpending.push( parser.assignTexture( materialParams, 'roughnessMap', metallicRoughness.metallicRoughnessTexture ) );\n\n\t\t\t}\n\n\t\t\tmaterialType = this._invokeOne( function ( ext ) {\n\n\t\t\t\treturn ext.getMaterialType && ext.getMaterialType( materialIndex );\n\n\t\t\t} );\n\n\t\t\tpending.push( Promise.all( this._invokeAll( function ( ext ) {\n\n\t\t\t\treturn ext.extendMaterialParams && ext.extendMaterialParams( materialIndex, materialParams );\n\n\t\t\t} ) ) );\n\n\t\t}\n\n\t\tif ( materialDef.doubleSided === true ) {\n\n\t\t\tmaterialParams.side = DoubleSide;\n\n\t\t}\n\n\t\tconst alphaMode = materialDef.alphaMode || ALPHA_MODES.OPAQUE;\n\n\t\tif ( alphaMode === ALPHA_MODES.BLEND ) {\n\n\t\t\tmaterialParams.transparent = true;\n\n\t\t\t// See: https://github.com/mrdoob/three.js/issues/17706\n\t\t\tmaterialParams.depthWrite = false;\n\n\t\t} else {\n\n\t\t\tmaterialParams.transparent = false;\n\n\t\t\tif ( alphaMode === ALPHA_MODES.MASK ) {\n\n\t\t\t\tmaterialParams.alphaTest = materialDef.alphaCutoff !== undefined ? materialDef.alphaCutoff : 0.5;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( materialDef.normalTexture !== undefined && materialType !== MeshBasicMaterial ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'normalMap', materialDef.normalTexture ) );\n\n\t\t\tmaterialParams.normalScale = new Vector2( 1, 1 );\n\n\t\t\tif ( materialDef.normalTexture.scale !== undefined ) {\n\n\t\t\t\tconst scale = materialDef.normalTexture.scale;\n\n\t\t\t\tmaterialParams.normalScale.set( scale, scale );\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( materialDef.occlusionTexture !== undefined && materialType !== MeshBasicMaterial ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'aoMap', materialDef.occlusionTexture ) );\n\n\t\t\tif ( materialDef.occlusionTexture.strength !== undefined ) {\n\n\t\t\t\tmaterialParams.aoMapIntensity = materialDef.occlusionTexture.strength;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( materialDef.emissiveFactor !== undefined && materialType !== MeshBasicMaterial ) {\n\n\t\t\tconst emissiveFactor = materialDef.emissiveFactor;\n\t\t\tmaterialParams.emissive = new Color().setRGB( emissiveFactor[ 0 ], emissiveFactor[ 1 ], emissiveFactor[ 2 ], LinearSRGBColorSpace );\n\n\t\t}\n\n\t\tif ( materialDef.emissiveTexture !== undefined && materialType !== MeshBasicMaterial ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'emissiveMap', materialDef.emissiveTexture, SRGBColorSpace ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending ).then( function () {\n\n\t\t\tconst material = new materialType( materialParams );\n\n\t\t\tif ( materialDef.name ) material.name = materialDef.name;\n\n\t\t\tassignExtrasToUserData( material, materialDef );\n\n\t\t\tparser.associations.set( material, { materials: materialIndex } );\n\n\t\t\tif ( materialDef.extensions ) addUnknownExtensionsToUserData( extensions, material, materialDef );\n\n\t\t\treturn material;\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * When Object3D instances are targeted by animation, they need unique names.\n\t *\n\t * @private\n\t * @param {string} originalName\n\t * @return {string}\n\t */\n\tcreateUniqueName( originalName ) {\n\n\t\tconst sanitizedName = PropertyBinding.sanitizeNodeName( originalName || '' );\n\n\t\tif ( sanitizedName in this.nodeNamesUsed ) {\n\n\t\t\treturn sanitizedName + '_' + ( ++ this.nodeNamesUsed[ sanitizedName ] );\n\n\t\t} else {\n\n\t\t\tthis.nodeNamesUsed[ sanitizedName ] = 0;\n\n\t\t\treturn sanitizedName;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#geometry\n\t *\n\t * Creates BufferGeometries from primitives.\n\t *\n\t * @private\n\t * @param {Array<GLTF.Primitive>} primitives\n\t * @return {Promise<Array<BufferGeometry>>}\n\t */\n\tloadGeometries( primitives ) {\n\n\t\tconst parser = this;\n\t\tconst extensions = this.extensions;\n\t\tconst cache = this.primitiveCache;\n\n\t\tfunction createDracoPrimitive( primitive ) {\n\n\t\t\treturn extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ]\n\t\t\t\t.decodePrimitive( primitive, parser )\n\t\t\t\t.then( function ( geometry ) {\n\n\t\t\t\t\treturn addPrimitiveAttributes( geometry, primitive, parser );\n\n\t\t\t\t} );\n\n\t\t}\n\n\t\tconst pending = [];\n\n\t\tfor ( let i = 0, il = primitives.length; i < il; i ++ ) {\n\n\t\t\tconst primitive = primitives[ i ];\n\t\t\tconst cacheKey = createPrimitiveKey( primitive );\n\n\t\t\t// See if we've already created this geometry\n\t\t\tconst cached = cache[ cacheKey ];\n\n\t\t\tif ( cached ) {\n\n\t\t\t\t// Use the cached geometry if it exists\n\t\t\t\tpending.push( cached.promise );\n\n\t\t\t} else {\n\n\t\t\t\tlet geometryPromise;\n\n\t\t\t\tif ( primitive.extensions && primitive.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ] ) {\n\n\t\t\t\t\t// Use DRACO geometry if available\n\t\t\t\t\tgeometryPromise = createDracoPrimitive( primitive );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Otherwise create a new geometry\n\t\t\t\t\tgeometryPromise = addPrimitiveAttributes( new BufferGeometry(), primitive, parser );\n\n\t\t\t\t}\n\n\t\t\t\t// Cache this geometry\n\t\t\t\tcache[ cacheKey ] = { primitive: primitive, promise: geometryPromise };\n\n\t\t\t\tpending.push( geometryPromise );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#meshes\n\t *\n\t * @private\n\t * @param {number} meshIndex\n\t * @return {Promise<Group|Mesh|SkinnedMesh|Line|Points>}\n\t */\n\tloadMesh( meshIndex ) {\n\n\t\tconst parser = this;\n\t\tconst json = this.json;\n\t\tconst extensions = this.extensions;\n\n\t\tconst meshDef = json.meshes[ meshIndex ];\n\t\tconst primitives = meshDef.primitives;\n\n\t\tconst pending = [];\n\n\t\tfor ( let i = 0, il = primitives.length; i < il; i ++ ) {\n\n\t\t\tconst material = primitives[ i ].material === undefined\n\t\t\t\t? createDefaultMaterial( this.cache )\n\t\t\t\t: this.getDependency( 'material', primitives[ i ].material );\n\n\t\t\tpending.push( material );\n\n\t\t}\n\n\t\tpending.push( parser.loadGeometries( primitives ) );\n\n\t\treturn Promise.all( pending ).then( function ( results ) {\n\n\t\t\tconst materials = results.slice( 0, results.length - 1 );\n\t\t\tconst geometries = results[ results.length - 1 ];\n\n\t\t\tconst meshes = [];\n\n\t\t\tfor ( let i = 0, il = geometries.length; i < il; i ++ ) {\n\n\t\t\t\tconst geometry = geometries[ i ];\n\t\t\t\tconst primitive = primitives[ i ];\n\n\t\t\t\t// 1. create Mesh\n\n\t\t\t\tlet mesh;\n\n\t\t\t\tconst material = materials[ i ];\n\n\t\t\t\tif ( primitive.mode === WEBGL_CONSTANTS.TRIANGLES ||\n\t\t\t\t\t\tprimitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ||\n\t\t\t\t\t\tprimitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN ||\n\t\t\t\t\t\tprimitive.mode === undefined ) {\n\n\t\t\t\t\t// .isSkinnedMesh isn't in glTF spec. See ._markDefs()\n\t\t\t\t\tmesh = meshDef.isSkinnedMesh === true\n\t\t\t\t\t\t? new SkinnedMesh( geometry, material )\n\t\t\t\t\t\t: new Mesh( geometry, material );\n\n\t\t\t\t\tif ( mesh.isSkinnedMesh === true ) {\n\n\t\t\t\t\t\t// normalize skin weights to fix malformed assets (see #15319)\n\t\t\t\t\t\tmesh.normalizeSkinWeights();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ) {\n\n\t\t\t\t\t\tmesh.geometry = toTrianglesDrawMode( mesh.geometry, TriangleStripDrawMode );\n\n\t\t\t\t\t} else if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN ) {\n\n\t\t\t\t\t\tmesh.geometry = toTrianglesDrawMode( mesh.geometry, TriangleFanDrawMode );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( primitive.mode === WEBGL_CONSTANTS.LINES ) {\n\n\t\t\t\t\tmesh = new LineSegments( geometry, material );\n\n\t\t\t\t} else if ( primitive.mode === WEBGL_CONSTANTS.LINE_STRIP ) {\n\n\t\t\t\t\tmesh = new Line( geometry, material );\n\n\t\t\t\t} else if ( primitive.mode === WEBGL_CONSTANTS.LINE_LOOP ) {\n\n\t\t\t\t\tmesh = new LineLoop( geometry, material );\n\n\t\t\t\t} else if ( primitive.mode === WEBGL_CONSTANTS.POINTS ) {\n\n\t\t\t\t\tmesh = new Points( geometry, material );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow new Error( 'THREE.GLTFLoader: Primitive mode unsupported: ' + primitive.mode );\n\n\t\t\t\t}\n\n\t\t\t\tif ( Object.keys( mesh.geometry.morphAttributes ).length > 0 ) {\n\n\t\t\t\t\tupdateMorphTargets( mesh, meshDef );\n\n\t\t\t\t}\n\n\t\t\t\tmesh.name = parser.createUniqueName( meshDef.name || ( 'mesh_' + meshIndex ) );\n\n\t\t\t\tassignExtrasToUserData( mesh, meshDef );\n\n\t\t\t\tif ( primitive.extensions ) addUnknownExtensionsToUserData( extensions, mesh, primitive );\n\n\t\t\t\tparser.assignFinalMaterial( mesh );\n\n\t\t\t\tmeshes.push( mesh );\n\n\t\t\t}\n\n\t\t\tfor ( let i = 0, il = meshes.length; i < il; i ++ ) {\n\n\t\t\t\tparser.associations.set( meshes[ i ], {\n\t\t\t\t\tmeshes: meshIndex,\n\t\t\t\t\tprimitives: i\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\tif ( meshes.length === 1 ) {\n\n\t\t\t\tif ( meshDef.extensions ) addUnknownExtensionsToUserData( extensions, meshes[ 0 ], meshDef );\n\n\t\t\t\treturn meshes[ 0 ];\n\n\t\t\t}\n\n\t\t\tconst group = new Group();\n\n\t\t\tif ( meshDef.extensions ) addUnknownExtensionsToUserData( extensions, group, meshDef );\n\n\t\t\tparser.associations.set( group, { meshes: meshIndex } );\n\n\t\t\tfor ( let i = 0, il = meshes.length; i < il; i ++ ) {\n\n\t\t\t\tgroup.add( meshes[ i ] );\n\n\t\t\t}\n\n\t\t\treturn group;\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#cameras\n\t *\n\t * @private\n\t * @param {number} cameraIndex\n\t * @return {Promise<Camera>|undefined}\n\t */\n\tloadCamera( cameraIndex ) {\n\n\t\tlet camera;\n\t\tconst cameraDef = this.json.cameras[ cameraIndex ];\n\t\tconst params = cameraDef[ cameraDef.type ];\n\n\t\tif ( ! params ) {\n\n\t\t\tconsole.warn( 'THREE.GLTFLoader: Missing camera parameters.' );\n\t\t\treturn;\n\n\t\t}\n\n\t\tif ( cameraDef.type === 'perspective' ) {\n\n\t\t\tcamera = new PerspectiveCamera( MathUtils.radToDeg( params.yfov ), params.aspectRatio || 1, params.znear || 1, params.zfar || 2e6 );\n\n\t\t} else if ( cameraDef.type === 'orthographic' ) {\n\n\t\t\tcamera = new OrthographicCamera( - params.xmag, params.xmag, params.ymag, - params.ymag, params.znear, params.zfar );\n\n\t\t}\n\n\t\tif ( cameraDef.name ) camera.name = this.createUniqueName( cameraDef.name );\n\n\t\tassignExtrasToUserData( camera, cameraDef );\n\n\t\treturn Promise.resolve( camera );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins\n\t *\n\t * @private\n\t * @param {number} skinIndex\n\t * @return {Promise<Skeleton>}\n\t */\n\tloadSkin( skinIndex ) {\n\n\t\tconst skinDef = this.json.skins[ skinIndex ];\n\n\t\tconst pending = [];\n\n\t\tfor ( let i = 0, il = skinDef.joints.length; i < il; i ++ ) {\n\n\t\t\tpending.push( this._loadNodeShallow( skinDef.joints[ i ] ) );\n\n\t\t}\n\n\t\tif ( skinDef.inverseBindMatrices !== undefined ) {\n\n\t\t\tpending.push( this.getDependency( 'accessor', skinDef.inverseBindMatrices ) );\n\n\t\t} else {\n\n\t\t\tpending.push( null );\n\n\t\t}\n\n\t\treturn Promise.all( pending ).then( function ( results ) {\n\n\t\t\tconst inverseBindMatrices = results.pop();\n\t\t\tconst jointNodes = results;\n\n\t\t\t// Note that bones (joint nodes) may or may not be in the\n\t\t\t// scene graph at this time.\n\n\t\t\tconst bones = [];\n\t\t\tconst boneInverses = [];\n\n\t\t\tfor ( let i = 0, il = jointNodes.length; i < il; i ++ ) {\n\n\t\t\t\tconst jointNode = jointNodes[ i ];\n\n\t\t\t\tif ( jointNode ) {\n\n\t\t\t\t\tbones.push( jointNode );\n\n\t\t\t\t\tconst mat = new Matrix4();\n\n\t\t\t\t\tif ( inverseBindMatrices !== null ) {\n\n\t\t\t\t\t\tmat.fromArray( inverseBindMatrices.array, i * 16 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tboneInverses.push( mat );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( 'THREE.GLTFLoader: Joint \"%s\" could not be found.', skinDef.joints[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn new Skeleton( bones, boneInverses );\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#animations\n\t *\n\t * @private\n\t * @param {number} animationIndex\n\t * @return {Promise<AnimationClip>}\n\t */\n\tloadAnimation( animationIndex ) {\n\n\t\tconst json = this.json;\n\t\tconst parser = this;\n\n\t\tconst animationDef = json.animations[ animationIndex ];\n\t\tconst animationName = animationDef.name ? animationDef.name : 'animation_' + animationIndex;\n\n\t\tconst pendingNodes = [];\n\t\tconst pendingInputAccessors = [];\n\t\tconst pendingOutputAccessors = [];\n\t\tconst pendingSamplers = [];\n\t\tconst pendingTargets = [];\n\n\t\tfor ( let i = 0, il = animationDef.channels.length; i < il; i ++ ) {\n\n\t\t\tconst channel = animationDef.channels[ i ];\n\t\t\tconst sampler = animationDef.samplers[ channel.sampler ];\n\t\t\tconst target = channel.target;\n\t\t\tconst name = target.node;\n\t\t\tconst input = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.input ] : sampler.input;\n\t\t\tconst output = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.output ] : sampler.output;\n\n\t\t\tif ( target.node === undefined ) continue;\n\n\t\t\tpendingNodes.push( this.getDependency( 'node', name ) );\n\t\t\tpendingInputAccessors.push( this.getDependency( 'accessor', input ) );\n\t\t\tpendingOutputAccessors.push( this.getDependency( 'accessor', output ) );\n\t\t\tpendingSamplers.push( sampler );\n\t\t\tpendingTargets.push( target );\n\n\t\t}\n\n\t\treturn Promise.all( [\n\n\t\t\tPromise.all( pendingNodes ),\n\t\t\tPromise.all( pendingInputAccessors ),\n\t\t\tPromise.all( pendingOutputAccessors ),\n\t\t\tPromise.all( pendingSamplers ),\n\t\t\tPromise.all( pendingTargets )\n\n\t\t] ).then( function ( dependencies ) {\n\n\t\t\tconst nodes = dependencies[ 0 ];\n\t\t\tconst inputAccessors = dependencies[ 1 ];\n\t\t\tconst outputAccessors = dependencies[ 2 ];\n\t\t\tconst samplers = dependencies[ 3 ];\n\t\t\tconst targets = dependencies[ 4 ];\n\n\t\t\tconst tracks = [];\n\n\t\t\tfor ( let i = 0, il = nodes.length; i < il; i ++ ) {\n\n\t\t\t\tconst node = nodes[ i ];\n\t\t\t\tconst inputAccessor = inputAccessors[ i ];\n\t\t\t\tconst outputAccessor = outputAccessors[ i ];\n\t\t\t\tconst sampler = samplers[ i ];\n\t\t\t\tconst target = targets[ i ];\n\n\t\t\t\tif ( node === undefined ) continue;\n\n\t\t\t\tif ( node.updateMatrix ) {\n\n\t\t\t\t\tnode.updateMatrix();\n\n\t\t\t\t}\n\n\t\t\t\tconst createdTracks = parser._createAnimationTracks( node, inputAccessor, outputAccessor, sampler, target );\n\n\t\t\t\tif ( createdTracks ) {\n\n\t\t\t\t\tfor ( let k = 0; k < createdTracks.length; k ++ ) {\n\n\t\t\t\t\t\ttracks.push( createdTracks[ k ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tconst animation = new AnimationClip( animationName, undefined, tracks );\n\n\t\t\tassignExtrasToUserData( animation, animationDef );\n\n\t\t\treturn animation;\n\n\t\t} );\n\n\t}\n\n\tcreateNodeMesh( nodeIndex ) {\n\n\t\tconst json = this.json;\n\t\tconst parser = this;\n\t\tconst nodeDef = json.nodes[ nodeIndex ];\n\n\t\tif ( nodeDef.mesh === undefined ) return null;\n\n\t\treturn parser.getDependency( 'mesh', nodeDef.mesh ).then( function ( mesh ) {\n\n\t\t\tconst node = parser._getNodeRef( parser.meshCache, nodeDef.mesh, mesh );\n\n\t\t\t// if weights are provided on the node, override weights on the mesh.\n\t\t\tif ( nodeDef.weights !== undefined ) {\n\n\t\t\t\tnode.traverse( function ( o ) {\n\n\t\t\t\t\tif ( ! o.isMesh ) return;\n\n\t\t\t\t\tfor ( let i = 0, il = nodeDef.weights.length; i < il; i ++ ) {\n\n\t\t\t\t\t\to.morphTargetInfluences[ i ] = nodeDef.weights[ i ];\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\treturn node;\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#nodes-and-hierarchy\n\t *\n\t * @private\n\t * @param {number} nodeIndex\n\t * @return {Promise<Object3D>}\n\t */\n\tloadNode( nodeIndex ) {\n\n\t\tconst json = this.json;\n\t\tconst parser = this;\n\n\t\tconst nodeDef = json.nodes[ nodeIndex ];\n\n\t\tconst nodePending = parser._loadNodeShallow( nodeIndex );\n\n\t\tconst childPending = [];\n\t\tconst childrenDef = nodeDef.children || [];\n\n\t\tfor ( let i = 0, il = childrenDef.length; i < il; i ++ ) {\n\n\t\t\tchildPending.push( parser.getDependency( 'node', childrenDef[ i ] ) );\n\n\t\t}\n\n\t\tconst skeletonPending = nodeDef.skin === undefined\n\t\t\t? Promise.resolve( null )\n\t\t\t: parser.getDependency( 'skin', nodeDef.skin );\n\n\t\treturn Promise.all( [\n\t\t\tnodePending,\n\t\t\tPromise.all( childPending ),\n\t\t\tskeletonPending\n\t\t] ).then( function ( results ) {\n\n\t\t\tconst node = results[ 0 ];\n\t\t\tconst children = results[ 1 ];\n\t\t\tconst skeleton = results[ 2 ];\n\n\t\t\tif ( skeleton !== null ) {\n\n\t\t\t\t// This full traverse should be fine because\n\t\t\t\t// child glTF nodes have not been added to this node yet.\n\t\t\t\tnode.traverse( function ( mesh ) {\n\n\t\t\t\t\tif ( ! mesh.isSkinnedMesh ) return;\n\n\t\t\t\t\tmesh.bind( skeleton, _identityMatrix );\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\tfor ( let i = 0, il = children.length; i < il; i ++ ) {\n\n\t\t\t\tnode.add( children[ i ] );\n\n\t\t\t}\n\n\t\t\t// Reconstruct pivot from container pattern created by GLTFExporter\n\t\t\t// The container has position+pivot, rotation, scale; child has -pivot offset and mesh\n\t\t\tif ( node.userData.pivot !== undefined && children.length > 0 ) {\n\n\t\t\t\tconst pivot = node.userData.pivot;\n\t\t\t\tconst pivotChild = children[ 0 ];\n\n\t\t\t\t// Set pivot on container and adjust transforms\n\t\t\t\tnode.pivot = new Vector3().fromArray( pivot );\n\n\t\t\t\t// Adjust container position: stored as position + pivot, so subtract pivot\n\t\t\t\tnode.position.x -= pivot[ 0 ];\n\t\t\t\tnode.position.y -= pivot[ 1 ];\n\t\t\t\tnode.position.z -= pivot[ 2 ];\n\n\t\t\t\t// Remove the child's -pivot offset since pivot now handles it\n\t\t\t\tpivotChild.position.set( 0, 0, 0 );\n\n\t\t\t\tdelete node.userData.pivot;\n\n\t\t\t}\n\n\t\t\treturn node;\n\n\t\t} );\n\n\t}\n\n\t// ._loadNodeShallow() parses a single node.\n\t// skin and child nodes are created and added in .loadNode() (no '_' prefix).\n\t_loadNodeShallow( nodeIndex ) {\n\n\t\tconst json = this.json;\n\t\tconst extensions = this.extensions;\n\t\tconst parser = this;\n\n\t\t// This method is called from .loadNode() and .loadSkin().\n\t\t// Cache a node to avoid duplication.\n\n\t\tif ( this.nodeCache[ nodeIndex ] !== undefined ) {\n\n\t\t\treturn this.nodeCache[ nodeIndex ];\n\n\t\t}\n\n\t\tconst nodeDef = json.nodes[ nodeIndex ];\n\n\t\t// reserve node's name before its dependencies, so the root has the intended name.\n\t\tconst nodeName = nodeDef.name ? parser.createUniqueName( nodeDef.name ) : '';\n\n\t\tconst pending = [];\n\n\t\tconst meshPromise = parser._invokeOne( function ( ext ) {\n\n\t\t\treturn ext.createNodeMesh && ext.createNodeMesh( nodeIndex );\n\n\t\t} );\n\n\t\tif ( meshPromise ) {\n\n\t\t\tpending.push( meshPromise );\n\n\t\t}\n\n\t\tif ( nodeDef.camera !== undefined ) {\n\n\t\t\tpending.push( parser.getDependency( 'camera', nodeDef.camera ).then( function ( camera ) {\n\n\t\t\t\treturn parser._getNodeRef( parser.cameraCache, nodeDef.camera, camera );\n\n\t\t\t} ) );\n\n\t\t}\n\n\t\tparser._invokeAll( function ( ext ) {\n\n\t\t\treturn ext.createNodeAttachment && ext.createNodeAttachment( nodeIndex );\n\n\t\t} ).forEach( function ( promise ) {\n\n\t\t\tpending.push( promise );\n\n\t\t} );\n\n\t\tthis.nodeCache[ nodeIndex ] = Promise.all( pending ).then( function ( objects ) {\n\n\t\t\tlet node;\n\n\t\t\t// .isBone isn't in glTF spec. See ._markDefs\n\t\t\tif ( nodeDef.isBone === true ) {\n\n\t\t\t\tnode = new Bone();\n\n\t\t\t} else if ( objects.length > 1 ) {\n\n\t\t\t\tnode = new Group();\n\n\t\t\t} else if ( objects.length === 1 ) {\n\n\t\t\t\tnode = objects[ 0 ];\n\n\t\t\t} else {\n\n\t\t\t\tnode = new Object3D();\n\n\t\t\t}\n\n\t\t\tif ( node !== objects[ 0 ] ) {\n\n\t\t\t\tfor ( let i = 0, il = objects.length; i < il; i ++ ) {\n\n\t\t\t\t\tnode.add( objects[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( nodeDef.name ) {\n\n\t\t\t\tnode.userData.name = nodeDef.name;\n\t\t\t\tnode.name = nodeName;\n\n\t\t\t}\n\n\t\t\tassignExtrasToUserData( node, nodeDef );\n\n\t\t\tif ( nodeDef.extensions ) addUnknownExtensionsToUserData( extensions, node, nodeDef );\n\n\t\t\tif ( nodeDef.matrix !== undefined ) {\n\n\t\t\t\tconst matrix = new Matrix4();\n\t\t\t\tmatrix.fromArray( nodeDef.matrix );\n\t\t\t\tnode.applyMatrix4( matrix );\n\n\t\t\t} else {\n\n\t\t\t\tif ( nodeDef.translation !== undefined ) {\n\n\t\t\t\t\tnode.position.fromArray( nodeDef.translation );\n\n\t\t\t\t}\n\n\t\t\t\tif ( nodeDef.rotation !== undefined ) {\n\n\t\t\t\t\tnode.quaternion.fromArray( nodeDef.rotation );\n\n\t\t\t\t}\n\n\t\t\t\tif ( nodeDef.scale !== undefined ) {\n\n\t\t\t\t\tnode.scale.fromArray( nodeDef.scale );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( ! parser.associations.has( node ) ) {\n\n\t\t\t\tparser.associations.set( node, {} );\n\n\t\t\t} else if ( nodeDef.mesh !== undefined && parser.meshCache.refs[ nodeDef.mesh ] > 1 ) {\n\n\t\t\t\tconst mapping = parser.associations.get( node );\n\t\t\t\tparser.associations.set( node, { ...mapping } );\n\n\t\t\t}\n\n\t\t\tparser.associations.get( node ).nodes = nodeIndex;\n\n\t\t\treturn node;\n\n\t\t} );\n\n\t\treturn this.nodeCache[ nodeIndex ];\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#scenes\n\t *\n\t * @private\n\t * @param {number} sceneIndex\n\t * @return {Promise<Group>}\n\t */\n\tloadScene( sceneIndex ) {\n\n\t\tconst extensions = this.extensions;\n\t\tconst sceneDef = this.json.scenes[ sceneIndex ];\n\t\tconst parser = this;\n\n\t\t// Loader returns Group, not Scene.\n\t\t// See: https://github.com/mrdoob/three.js/issues/18342#issuecomment-578981172\n\t\tconst scene = new Group();\n\t\tif ( sceneDef.name ) scene.name = parser.createUniqueName( sceneDef.name );\n\n\t\tassignExtrasToUserData( scene, sceneDef );\n\n\t\tif ( sceneDef.extensions ) addUnknownExtensionsToUserData( extensions, scene, sceneDef );\n\n\t\tconst nodeIds = sceneDef.nodes || [];\n\n\t\tconst pending = [];\n\n\t\tfor ( let i = 0, il = nodeIds.length; i < il; i ++ ) {\n\n\t\t\tpending.push( parser.getDependency( 'node', nodeIds[ i ] ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending ).then( function ( nodes ) {\n\n\t\t\tfor ( let i = 0, il = nodes.length; i < il; i ++ ) {\n\n\t\t\t\tconst node = nodes[ i ];\n\n\t\t\t\t// If the node already has a parent, it means it's being reused across multiple scenes.\n\t\t\t\t// Clone it to avoid the second scene's add() removing it from the first scene.\n\t\t\t\t// See: https://github.com/mrdoob/three.js/issues/27993\n\t\t\t\tif ( node.parent !== null ) {\n\n\t\t\t\t\tscene.add( clone( node ) );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tscene.add( node );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Removes dangling associations, associations that reference a node that\n\t\t\t// didn't make it into the scene.\n\t\t\tconst reduceAssociations = ( node ) => {\n\n\t\t\t\tconst reducedAssociations = new Map();\n\n\t\t\t\tfor ( const [ key, value ] of parser.associations ) {\n\n\t\t\t\t\tif ( key instanceof Material || key instanceof Texture ) {\n\n\t\t\t\t\t\treducedAssociations.set( key, value );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tnode.traverse( ( node ) => {\n\n\t\t\t\t\tconst mappings = parser.associations.get( node );\n\n\t\t\t\t\tif ( mappings != null ) {\n\n\t\t\t\t\t\treducedAssociations.set( node, mappings );\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t\treturn reducedAssociations;\n\n\t\t\t};\n\n\t\t\tparser.associations = reduceAssociations( scene );\n\n\t\t\treturn scene;\n\n\t\t} );\n\n\t}\n\n\t_createAnimationTracks( node, inputAccessor, outputAccessor, sampler, target ) {\n\n\t\tconst tracks = [];\n\n\t\tconst targetName = node.name ? node.name : node.uuid;\n\t\tconst targetNames = [];\n\n\t\tfunction collectMorphTargets( object ) {\n\n\t\t\tif ( object.morphTargetInfluences ) {\n\n\t\t\t\ttargetNames.push( object.name ? object.name : object.uuid );\n\n\t\t\t}\n\n\t\t}\n\n\n\t\tif ( PATH_PROPERTIES[ target.path ] === PATH_PROPERTIES.weights ) {\n\n\t\t\tcollectMorphTargets( node );\n\n\t\t\t// for multi-primitive meshes, the node is a Group containing the sub-meshes\n\n\t\t\tif ( node.isGroup ) {\n\n\t\t\t\tnode.children.forEach( collectMorphTargets );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\ttargetNames.push( targetName );\n\n\t\t}\n\n\t\tlet TypedKeyframeTrack;\n\n\t\tswitch ( PATH_PROPERTIES[ target.path ] ) {\n\n\t\t\tcase PATH_PROPERTIES.weights:\n\n\t\t\t\tTypedKeyframeTrack = NumberKeyframeTrack;\n\t\t\t\tbreak;\n\n\t\t\tcase PATH_PROPERTIES.rotation:\n\n\t\t\t\tTypedKeyframeTrack = QuaternionKeyframeTrack;\n\t\t\t\tbreak;\n\n\t\t\tcase PATH_PROPERTIES.translation:\n\t\t\tcase PATH_PROPERTIES.scale:\n\n\t\t\t\tTypedKeyframeTrack = VectorKeyframeTrack;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\n\t\t\t\tswitch ( outputAccessor.itemSize ) {\n\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tTypedKeyframeTrack = NumberKeyframeTrack;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 2:\n\t\t\t\t\tcase 3:\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tTypedKeyframeTrack = VectorKeyframeTrack;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t}\n\n\t\tconst interpolation = sampler.interpolation !== undefined ? INTERPOLATION[ sampler.interpolation ] : InterpolateLinear;\n\n\n\t\tconst outputArray = this._getArrayFromAccessor( outputAccessor );\n\n\t\tfor ( let j = 0, jl = targetNames.length; j < jl; j ++ ) {\n\n\t\t\tconst track = new TypedKeyframeTrack(\n\t\t\t\ttargetNames[ j ] + '.' + PATH_PROPERTIES[ target.path ],\n\t\t\t\tinputAccessor.array,\n\t\t\t\toutputArray,\n\t\t\t\tinterpolation\n\t\t\t);\n\n\t\t\t// Override interpolation with custom factory method.\n\t\t\tif ( sampler.interpolation === 'CUBICSPLINE' ) {\n\n\t\t\t\tthis._createCubicSplineTrackInterpolant( track );\n\n\t\t\t}\n\n\t\t\ttracks.push( track );\n\n\t\t}\n\n\t\treturn tracks;\n\n\t}\n\n\t_getArrayFromAccessor( accessor ) {\n\n\t\tlet outputArray = accessor.array;\n\n\t\tif ( accessor.normalized ) {\n\n\t\t\tconst scale = getNormalizedComponentScale( outputArray.constructor );\n\t\t\tconst scaled = new Float32Array( outputArray.length );\n\n\t\t\tfor ( let j = 0, jl = outputArray.length; j < jl; j ++ ) {\n\n\t\t\t\tscaled[ j ] = outputArray[ j ] * scale;\n\n\t\t\t}\n\n\t\t\toutputArray = scaled;\n\n\t\t}\n\n\t\treturn outputArray;\n\n\t}\n\n\t_createCubicSplineTrackInterpolant( track ) {\n\n\t\ttrack.createInterpolant = function InterpolantFactoryMethodGLTFCubicSpline( result ) {\n\n\t\t\t// A CUBICSPLINE keyframe in glTF has three output values for each input value,\n\t\t\t// representing inTangent, splineVertex, and outTangent. As a result, track.getValueSize()\n\t\t\t// must be divided by three to get the interpolant's sampleSize argument.\n\n\t\t\tconst interpolantType = ( this instanceof QuaternionKeyframeTrack ) ? GLTFCubicSplineQuaternionInterpolant : GLTFCubicSplineInterpolant;\n\n\t\t\treturn new interpolantType( this.times, this.values, this.getValueSize() / 3, result );\n\n\t\t};\n\n\t\t// Mark as CUBICSPLINE. `track.getInterpolation()` doesn't support custom interpolants.\n\t\ttrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline = true;\n\n\t}\n\n}\n\n/**\n *\n * @private\n * @param {BufferGeometry} geometry\n * @param {GLTF.Primitive} primitiveDef\n * @param {GLTFParser} parser\n */\nfunction computeBounds( geometry, primitiveDef, parser ) {\n\n\tconst attributes = primitiveDef.attributes;\n\n\tconst box = new Box3();\n\n\tif ( attributes.POSITION !== undefined ) {\n\n\t\tconst accessor = parser.json.accessors[ attributes.POSITION ];\n\n\t\tconst min = accessor.min;\n\t\tconst max = accessor.max;\n\n\t\t// glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement.\n\n\t\tif ( min !== undefined && max !== undefined ) {\n\n\t\t\tbox.set(\n\t\t\t\tnew Vector3( min[ 0 ], min[ 1 ], min[ 2 ] ),\n\t\t\t\tnew Vector3( max[ 0 ], max[ 1 ], max[ 2 ] )\n\t\t\t);\n\n\t\t\tif ( accessor.normalized ) {\n\n\t\t\t\tconst boxScale = getNormalizedComponentScale( WEBGL_COMPONENT_TYPES[ accessor.componentType ] );\n\t\t\t\tbox.min.multiplyScalar( boxScale );\n\t\t\t\tbox.max.multiplyScalar( boxScale );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.GLTFLoader: Missing min/max properties for accessor POSITION.' );\n\n\t\t\treturn;\n\n\t\t}\n\n\t} else {\n\n\t\treturn;\n\n\t}\n\n\tconst targets = primitiveDef.targets;\n\n\tif ( targets !== undefined ) {\n\n\t\tconst maxDisplacement = new Vector3();\n\t\tconst vector = new Vector3();\n\n\t\tfor ( let i = 0, il = targets.length; i < il; i ++ ) {\n\n\t\t\tconst target = targets[ i ];\n\n\t\t\tif ( target.POSITION !== undefined ) {\n\n\t\t\t\tconst accessor = parser.json.accessors[ target.POSITION ];\n\t\t\t\tconst min = accessor.min;\n\t\t\t\tconst max = accessor.max;\n\n\t\t\t\t// glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement.\n\n\t\t\t\tif ( min !== undefined && max !== undefined ) {\n\n\t\t\t\t\t// we need to get max of absolute components because target weight is [-1,1]\n\t\t\t\t\tvector.setX( Math.max( Math.abs( min[ 0 ] ), Math.abs( max[ 0 ] ) ) );\n\t\t\t\t\tvector.setY( Math.max( Math.abs( min[ 1 ] ), Math.abs( max[ 1 ] ) ) );\n\t\t\t\t\tvector.setZ( Math.max( Math.abs( min[ 2 ] ), Math.abs( max[ 2 ] ) ) );\n\n\n\t\t\t\t\tif ( accessor.normalized ) {\n\n\t\t\t\t\t\tconst boxScale = getNormalizedComponentScale( WEBGL_COMPONENT_TYPES[ accessor.componentType ] );\n\t\t\t\t\t\tvector.multiplyScalar( boxScale );\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Note: this assumes that the sum of all weights is at most 1. This isn't quite correct - it's more conservative\n\t\t\t\t\t// to assume that each target can have a max weight of 1. However, for some use cases - notably, when morph targets\n\t\t\t\t\t// are used to implement key-frame animations and as such only two are active at a time - this results in very large\n\t\t\t\t\t// boxes. So for now we make a box that's sometimes a touch too small but is hopefully mostly of reasonable size.\n\t\t\t\t\tmaxDisplacement.max( vector );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( 'THREE.GLTFLoader: Missing min/max properties for accessor POSITION.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// As per comment above this box isn't conservative, but has a reasonable size for a very large number of morph targets.\n\t\tbox.expandByVector( maxDisplacement );\n\n\t}\n\n\tgeometry.boundingBox = box;\n\n\tconst sphere = new Sphere();\n\n\tbox.getCenter( sphere.center );\n\tsphere.radius = box.min.distanceTo( box.max ) / 2;\n\n\tgeometry.boundingSphere = sphere;\n\n}\n\n/**\n *\n * @private\n * @param {BufferGeometry} geometry\n * @param {GLTF.Primitive} primitiveDef\n * @param {GLTFParser} parser\n * @return {Promise<BufferGeometry>}\n */\nfunction addPrimitiveAttributes( geometry, primitiveDef, parser ) {\n\n\tconst attributes = primitiveDef.attributes;\n\n\tconst pending = [];\n\n\tfunction assignAttributeAccessor( accessorIndex, attributeName ) {\n\n\t\treturn parser.getDependency( 'accessor', accessorIndex )\n\t\t\t.then( function ( accessor ) {\n\n\t\t\t\tgeometry.setAttribute( attributeName, accessor );\n\n\t\t\t} );\n\n\t}\n\n\tfor ( const gltfAttributeName in attributes ) {\n\n\t\tconst threeAttributeName = ATTRIBUTES[ gltfAttributeName ] || gltfAttributeName.toLowerCase();\n\n\t\t// Skip attributes already provided by e.g. Draco extension.\n\t\tif ( threeAttributeName in geometry.attributes ) continue;\n\n\t\tpending.push( assignAttributeAccessor( attributes[ gltfAttributeName ], threeAttributeName ) );\n\n\t}\n\n\tif ( primitiveDef.indices !== undefined && ! geometry.index ) {\n\n\t\tconst accessor = parser.getDependency( 'accessor', primitiveDef.indices ).then( function ( accessor ) {\n\n\t\t\tgeometry.setIndex( accessor );\n\n\t\t} );\n\n\t\tpending.push( accessor );\n\n\t}\n\n\tif ( ColorManagement.workingColorSpace !== LinearSRGBColorSpace && 'COLOR_0' in attributes ) {\n\n\t\tconsole.warn( `THREE.GLTFLoader: Converting vertex colors from \"srgb-linear\" to \"${ColorManagement.workingColorSpace}\" not supported.` );\n\n\t}\n\n\tassignExtrasToUserData( geometry, primitiveDef );\n\n\tcomputeBounds( geometry, primitiveDef, parser );\n\n\treturn Promise.all( pending ).then( function () {\n\n\t\treturn primitiveDef.targets !== undefined\n\t\t\t? addMorphTargets( geometry, primitiveDef.targets, parser )\n\t\t\t: geometry;\n\n\t} );\n\n}\n\n/**\n * Loader result of `GLTFLoader`.\n *\n * @typedef {Object} GLTFLoader~LoadObject\n * @property {Array<AnimationClip>} animations - An array of animation clips.\n * @property {Object} asset - Meta data about the loaded asset.\n * @property {Array<Camera>} cameras - An array of cameras.\n * @property {GLTFParser} parser - A reference to the internal parser.\n * @property {Group} scene - The default scene.\n * @property {Array<Group>} scenes - glTF assets might define multiple scenes.\n * @property {Object} userData - Additional data.\n **/\n\nexport { GLTFLoader };\n","import {\n\tBufferAttribute,\n\tBufferGeometry,\n\tColor,\n\tColorManagement,\n\tFileLoader,\n\tLoader,\n\tLinearSRGBColorSpace,\n\tSRGBColorSpace,\n\tInterleavedBuffer,\n\tInterleavedBufferAttribute\n} from 'three';\n\nconst _taskCache = new WeakMap();\n\n/**\n * A loader for the Draco format.\n *\n * [Draco](https://google.github.io/draco/) is an open source library for compressing\n * and decompressing 3D meshes and point clouds. Compressed geometry can be significantly smaller,\n * at the cost of additional decoding time on the client device.\n *\n * Standalone Draco files have a `.drc` extension, and contain vertex positions, normals, colors,\n * and other attributes. Draco files do not contain materials, textures, animation, or node hierarchies –\n * to use these features, embed Draco geometry inside of a glTF file. A normal glTF file can be converted\n * to a Draco-compressed glTF file using [glTF-Pipeline](https://github.com/CesiumGS/gltf-pipeline).\n * When using Draco with glTF, an instance of `DRACOLoader` will be used internally by {@link GLTFLoader}.\n *\n * It is recommended to create one DRACOLoader instance and reuse it to avoid loading and creating\n * multiple decoder instances.\n *\n * `DRACOLoader` will automatically use either the JS or the WASM decoding library, based on\n * browser capabilities.\n *\n * ```js\n * const loader = new DRACOLoader();\n * loader.setDecoderPath( '/examples/jsm/libs/draco/' );\n *\n * const geometry = await dracoLoader.loadAsync( 'models/draco/bunny.drc' );\n * geometry.computeVertexNormals(); // optional\n *\n * dracoLoader.dispose();\n * ```\n *\n * @augments Loader\n * @three_import import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';\n */\nclass DRACOLoader extends Loader {\n\n\t/**\n\t * Constructs a new Draco loader.\n\t *\n\t * @param {LoadingManager} [manager] - The loading manager.\n\t */\n\tconstructor( manager ) {\n\n\t\tsuper( manager );\n\n\t\tthis.decoderPath = '';\n\t\tthis.decoderConfig = {};\n\t\tthis.decoderBinary = null;\n\t\tthis.decoderPending = null;\n\n\t\tthis.workerLimit = 4;\n\t\tthis.workerPool = [];\n\t\tthis.workerNextTaskID = 1;\n\t\tthis.workerSourceURL = '';\n\n\t\tthis.defaultAttributeIDs = {\n\t\t\tposition: 'POSITION',\n\t\t\tnormal: 'NORMAL',\n\t\t\tcolor: 'COLOR',\n\t\t\tuv: 'TEX_COORD'\n\t\t};\n\t\tthis.defaultAttributeTypes = {\n\t\t\tposition: 'Float32Array',\n\t\t\tnormal: 'Float32Array',\n\t\t\tcolor: 'Float32Array',\n\t\t\tuv: 'Float32Array'\n\t\t};\n\n\t}\n\n\t/**\n\t * Provides configuration for the decoder libraries. Configuration cannot be changed after decoding begins.\n\t *\n\t * @param {string} path - The decoder path.\n\t * @return {DRACOLoader} A reference to this loader.\n\t */\n\tsetDecoderPath( path ) {\n\n\t\tthis.decoderPath = path;\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * Provides configuration for the decoder libraries. Configuration cannot be changed after decoding begins.\n\t *\n\t * @param {{type:('js'|'wasm')}} config - The decoder config.\n\t * @return {DRACOLoader} A reference to this loader.\n\t */\n\tsetDecoderConfig( config ) {\n\n\t\tthis.decoderConfig = config;\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * Sets the maximum number of Web Workers to be used during decoding.\n\t * A lower limit may be preferable if workers are also for other tasks in the application.\n\t *\n\t * @param {number} workerLimit - The worker limit.\n\t * @return {DRACOLoader} A reference to this loader.\n\t */\n\tsetWorkerLimit( workerLimit ) {\n\n\t\tthis.workerLimit = workerLimit;\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * Starts loading from the given URL and passes the loaded Draco asset\n\t * to the `onLoad()` callback.\n\t *\n\t * @param {string} url - The path/URL of the file to be loaded. This can also be a data URI.\n\t * @param {function(BufferGeometry)} onLoad - Executed when the loading process has been finished.\n\t * @param {onProgressCallback} onProgress - Executed while the loading is in progress.\n\t * @param {onErrorCallback} onError - Executed when errors occur.\n\t */\n\tload( url, onLoad, onProgress, onError ) {\n\n\t\tconst loader = new FileLoader( this.manager );\n\n\t\tloader.setPath( this.path );\n\t\tloader.setResponseType( 'arraybuffer' );\n\t\tloader.setRequestHeader( this.requestHeader );\n\t\tloader.setWithCredentials( this.withCredentials );\n\n\t\tloader.load( url, ( buffer ) => {\n\n\t\t\tthis.parse( buffer, onLoad, onError );\n\n\t\t}, onProgress, onError );\n\n\t}\n\n\t/**\n\t * Parses the given Draco data.\n\t *\n\t * @param {ArrayBuffer} buffer - The raw Draco data as an array buffer.\n\t * @param {function(BufferGeometry)} onLoad - Executed when the loading/parsing process has been finished.\n\t * @param {onErrorCallback} onError - Executed when errors occur.\n\t */\n\tparse( buffer, onLoad, onError = ()=>{} ) {\n\n\t\tthis.decodeDracoFile( buffer, onLoad, null, null, SRGBColorSpace, onError ).catch( onError );\n\n\t}\n\n\t//\n\n\tdecodeDracoFile( buffer, callback, attributeIDs, attributeTypes, vertexColorSpace = LinearSRGBColorSpace, onError = () => {} ) {\n\n\t\tconst taskConfig = {\n\t\t\tattributeIDs: attributeIDs || this.defaultAttributeIDs,\n\t\t\tattributeTypes: attributeTypes || this.defaultAttributeTypes,\n\t\t\tuseUniqueIDs: !! attributeIDs,\n\t\t\tvertexColorSpace: vertexColorSpace,\n\t\t};\n\n\t\treturn this.decodeGeometry( buffer, taskConfig ).then( callback ).catch( onError );\n\n\t}\n\n\tdecodeGeometry( buffer, taskConfig ) {\n\n\t\tconst taskKey = JSON.stringify( taskConfig );\n\n\t\t// Check for an existing task using this buffer. A transferred buffer cannot be transferred\n\t\t// again from this thread.\n\t\tif ( _taskCache.has( buffer ) ) {\n\n\t\t\tconst cachedTask = _taskCache.get( buffer );\n\n\t\t\tif ( cachedTask.key === taskKey ) {\n\n\t\t\t\treturn cachedTask.promise;\n\n\t\t\t} else if ( buffer.byteLength === 0 ) {\n\n\t\t\t\t// Technically, it would be possible to wait for the previous task to complete,\n\t\t\t\t// transfer the buffer back, and decode again with the second configuration. That\n\t\t\t\t// is complex, and I don't know of any reason to decode a Draco buffer twice in\n\t\t\t\t// different ways, so this is left unimplemented.\n\t\t\t\tthrow new Error(\n\n\t\t\t\t\t'THREE.DRACOLoader: Unable to re-decode a buffer with different ' +\n\t\t\t\t\t'settings. Buffer has already been transferred.'\n\n\t\t\t\t);\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tlet worker;\n\t\tconst taskID = this.workerNextTaskID ++;\n\t\tconst taskCost = buffer.byteLength;\n\n\t\t// Obtain a worker and assign a task, and construct a geometry instance\n\t\t// when the task completes.\n\t\tconst geometryPending = this._getWorker( taskID, taskCost )\n\t\t\t.then( ( _worker ) => {\n\n\t\t\t\tworker = _worker;\n\n\t\t\t\treturn new Promise( ( resolve, reject ) => {\n\n\t\t\t\t\tworker._callbacks[ taskID ] = { resolve, reject };\n\n\t\t\t\t\tworker.postMessage( { type: 'decode', id: taskID, taskConfig, buffer }, [ buffer ] );\n\n\t\t\t\t\t// this.debug();\n\n\t\t\t\t} );\n\n\t\t\t} )\n\t\t\t.then( ( message ) => this._createGeometry( message.geometry ) );\n\n\t\t// Remove task from the task list.\n\t\t// Note: replaced '.finally()' with '.catch().then()' block - iOS 11 support (#19416)\n\t\tgeometryPending\n\t\t\t.catch( () => true )\n\t\t\t.then( () => {\n\n\t\t\t\tif ( worker && taskID ) {\n\n\t\t\t\t\tthis._releaseTask( worker, taskID );\n\n\t\t\t\t\t// this.debug();\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t// Cache the task result.\n\t\t_taskCache.set( buffer, {\n\n\t\t\tkey: taskKey,\n\t\t\tpromise: geometryPending\n\n\t\t} );\n\n\t\treturn geometryPending;\n\n\t}\n\n\t_createGeometry( geometryData ) {\n\n\t\tconst geometry = new BufferGeometry();\n\n\t\tif ( geometryData.index ) {\n\n\t\t\tgeometry.setIndex( new BufferAttribute( geometryData.index.array, 1 ) );\n\n\t\t}\n\n\t\tfor ( let i = 0; i < geometryData.attributes.length; i ++ ) {\n\n\t\t\tconst { name, array, itemSize, stride, vertexColorSpace } = geometryData.attributes[ i ];\n\n\t\t\tlet attribute;\n\n\t\t\tif ( itemSize === stride ) {\n\n\t\t\t\tattribute = new BufferAttribute( array, itemSize );\n\n\t\t\t} else {\n\n\t\t\t\tconst buffer = new InterleavedBuffer( array, stride );\n\n\t\t\t\tattribute = new InterleavedBufferAttribute( buffer, itemSize, 0 );\n\n\t\t\t}\n\n\t\t\tif ( name === 'color' ) {\n\n\t\t\t\tthis._assignVertexColorSpace( attribute, vertexColorSpace );\n\n\t\t\t\tattribute.normalized = ( array instanceof Float32Array ) === false;\n\n\t\t\t}\n\n\t\t\tgeometry.setAttribute( name, attribute );\n\n\t\t}\n\n\t\treturn geometry;\n\n\t}\n\n\t_assignVertexColorSpace( attribute, inputColorSpace ) {\n\n\t\t// While .drc files do not specify colorspace, the only 'official' tooling\n\t\t// is PLY and OBJ converters, which use sRGB. We'll assume sRGB when a .drc\n\t\t// file is passed into .load() or .parse(). GLTFLoader uses internal APIs\n\t\t// to decode geometry, and vertex colors are already Linear-sRGB in there.\n\n\t\tif ( inputColorSpace !== SRGBColorSpace ) return;\n\n\t\tconst _color = new Color();\n\n\t\tfor ( let i = 0, il = attribute.count; i < il; i ++ ) {\n\n\t\t\t_color.fromBufferAttribute( attribute, i );\n\t\t\tColorManagement.colorSpaceToWorking( _color, SRGBColorSpace );\n\t\t\tattribute.setXYZ( i, _color.r, _color.g, _color.b );\n\n\t\t}\n\n\t}\n\n\t_loadLibrary( url, responseType ) {\n\n\t\tconst loader = new FileLoader( this.manager );\n\t\tloader.setPath( this.decoderPath );\n\t\tloader.setResponseType( responseType );\n\t\tloader.setWithCredentials( this.withCredentials );\n\n\t\treturn new Promise( ( resolve, reject ) => {\n\n\t\t\tloader.load( url, resolve, undefined, reject );\n\n\t\t} );\n\n\t}\n\n\tpreload() {\n\n\t\tthis._initDecoder();\n\n\t\treturn this;\n\n\t}\n\n\t_initDecoder() {\n\n\t\tif ( this.decoderPending ) return this.decoderPending;\n\n\t\tconst useJS = typeof WebAssembly !== 'object' || this.decoderConfig.type === 'js';\n\t\tconst librariesPending = [];\n\n\t\tif ( useJS ) {\n\n\t\t\tlibrariesPending.push( this._loadLibrary( 'draco_decoder.js', 'text' ) );\n\n\t\t} else {\n\n\t\t\tlibrariesPending.push( this._loadLibrary( 'draco_wasm_wrapper.js', 'text' ) );\n\t\t\tlibrariesPending.push( this._loadLibrary( 'draco_decoder.wasm', 'arraybuffer' ) );\n\n\t\t}\n\n\t\tthis.decoderPending = Promise.all( librariesPending )\n\t\t\t.then( ( libraries ) => {\n\n\t\t\t\tconst jsContent = libraries[ 0 ];\n\n\t\t\t\tif ( ! useJS ) {\n\n\t\t\t\t\tthis.decoderConfig.wasmBinary = libraries[ 1 ];\n\n\t\t\t\t}\n\n\t\t\t\tconst fn = DRACOWorker.toString();\n\n\t\t\t\tconst body = [\n\t\t\t\t\t'/* draco decoder */',\n\t\t\t\t\tjsContent,\n\t\t\t\t\t'',\n\t\t\t\t\t'/* worker */',\n\t\t\t\t\tfn.substring( fn.indexOf( '{' ) + 1, fn.lastIndexOf( '}' ) )\n\t\t\t\t].join( '\\n' );\n\n\t\t\t\tthis.workerSourceURL = URL.createObjectURL( new Blob( [ body ] ) );\n\n\t\t\t} );\n\n\t\treturn this.decoderPending;\n\n\t}\n\n\t_getWorker( taskID, taskCost ) {\n\n\t\treturn this._initDecoder().then( () => {\n\n\t\t\tif ( this.workerPool.length < this.workerLimit ) {\n\n\t\t\t\tconst worker = new Worker( this.workerSourceURL );\n\n\t\t\t\tworker._callbacks = {};\n\t\t\t\tworker._taskCosts = {};\n\t\t\t\tworker._taskLoad = 0;\n\n\t\t\t\tworker.postMessage( { type: 'init', decoderConfig: this.decoderConfig } );\n\n\t\t\t\tworker.onmessage = function ( e ) {\n\n\t\t\t\t\tconst message = e.data;\n\n\t\t\t\t\tswitch ( message.type ) {\n\n\t\t\t\t\t\tcase 'decode':\n\t\t\t\t\t\t\tworker._callbacks[ message.id ].resolve( message );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'error':\n\t\t\t\t\t\t\tworker._callbacks[ message.id ].reject( message );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tconsole.error( 'THREE.DRACOLoader: Unexpected message, \"' + message.type + '\"' );\n\n\t\t\t\t\t}\n\n\t\t\t\t};\n\n\t\t\t\tthis.workerPool.push( worker );\n\n\t\t\t} else {\n\n\t\t\t\tthis.workerPool.sort( function ( a, b ) {\n\n\t\t\t\t\treturn a._taskLoad > b._taskLoad ? - 1 : 1;\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\tconst worker = this.workerPool[ this.workerPool.length - 1 ];\n\t\t\tworker._taskCosts[ taskID ] = taskCost;\n\t\t\tworker._taskLoad += taskCost;\n\t\t\treturn worker;\n\n\t\t} );\n\n\t}\n\n\t_releaseTask( worker, taskID ) {\n\n\t\tworker._taskLoad -= worker._taskCosts[ taskID ];\n\t\tdelete worker._callbacks[ taskID ];\n\t\tdelete worker._taskCosts[ taskID ];\n\n\t}\n\n\tdebug() {\n\n\t\tconsole.log( 'Task load: ', this.workerPool.map( ( worker ) => worker._taskLoad ) );\n\n\t}\n\n\tdispose() {\n\n\t\tfor ( let i = 0; i < this.workerPool.length; ++ i ) {\n\n\t\t\tthis.workerPool[ i ].terminate();\n\n\t\t}\n\n\t\tthis.workerPool.length = 0;\n\n\t\tif ( this.workerSourceURL !== '' ) {\n\n\t\t\tURL.revokeObjectURL( this.workerSourceURL );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n}\n\n/* WEB WORKER */\n\nfunction DRACOWorker() {\n\n\tlet decoderConfig;\n\tlet decoderPending;\n\n\tonmessage = function ( e ) {\n\n\t\tconst message = e.data;\n\n\t\tswitch ( message.type ) {\n\n\t\t\tcase 'init':\n\t\t\t\tdecoderConfig = message.decoderConfig;\n\t\t\t\tdecoderPending = new Promise( function ( resolve/*, reject*/ ) {\n\n\t\t\t\t\tdecoderConfig.onModuleLoaded = function ( draco ) {\n\n\t\t\t\t\t\t// Module is Promise-like. Wrap before resolving to avoid loop.\n\t\t\t\t\t\tresolve( { draco: draco } );\n\n\t\t\t\t\t};\n\n\t\t\t\t\tDracoDecoderModule( decoderConfig ); // eslint-disable-line no-undef\n\n\t\t\t\t} );\n\t\t\t\tbreak;\n\n\t\t\tcase 'decode':\n\t\t\t\tconst buffer = message.buffer;\n\t\t\t\tconst taskConfig = message.taskConfig;\n\t\t\t\tdecoderPending.then( ( module ) => {\n\n\t\t\t\t\tconst draco = module.draco;\n\t\t\t\t\tconst decoder = new draco.Decoder();\n\n\t\t\t\t\ttry {\n\n\t\t\t\t\t\tconst geometry = decodeGeometry( draco, decoder, new Int8Array( buffer ), taskConfig );\n\n\t\t\t\t\t\tconst buffers = geometry.attributes.map( ( attr ) => attr.array.buffer );\n\n\t\t\t\t\t\tif ( geometry.index ) buffers.push( geometry.index.array.buffer );\n\n\t\t\t\t\t\tself.postMessage( { type: 'decode', id: message.id, geometry }, buffers );\n\n\t\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\t\tconsole.error( error );\n\n\t\t\t\t\t\tself.postMessage( { type: 'error', id: message.id, error: error.message } );\n\n\t\t\t\t\t} finally {\n\n\t\t\t\t\t\tdraco.destroy( decoder );\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\t\t\t\tbreak;\n\n\t\t}\n\n\t};\n\n\tfunction decodeGeometry( draco, decoder, array, taskConfig ) {\n\n\t\tconst attributeIDs = taskConfig.attributeIDs;\n\t\tconst attributeTypes = taskConfig.attributeTypes;\n\n\t\tlet dracoGeometry;\n\t\tlet decodingStatus;\n\n\t\tconst geometryType = decoder.GetEncodedGeometryType( array );\n\n\t\tif ( geometryType === draco.TRIANGULAR_MESH ) {\n\n\t\t\tdracoGeometry = new draco.Mesh();\n\t\t\tdecodingStatus = decoder.DecodeArrayToMesh( array, array.byteLength, dracoGeometry );\n\n\t\t} else if ( geometryType === draco.POINT_CLOUD ) {\n\n\t\t\tdracoGeometry = new draco.PointCloud();\n\t\t\tdecodingStatus = decoder.DecodeArrayToPointCloud( array, array.byteLength, dracoGeometry );\n\n\t\t} else {\n\n\t\t\tthrow new Error( 'THREE.DRACOLoader: Unexpected geometry type.' );\n\n\t\t}\n\n\t\tif ( ! decodingStatus.ok() || dracoGeometry.ptr === 0 ) {\n\n\t\t\tthrow new Error( 'THREE.DRACOLoader: Decoding failed: ' + decodingStatus.error_msg() );\n\n\t\t}\n\n\t\tconst geometry = { index: null, attributes: [] };\n\n\t\t// Gather all vertex attributes.\n\t\tfor ( const attributeName in attributeIDs ) {\n\n\t\t\tconst attributeType = self[ attributeTypes[ attributeName ] ];\n\n\t\t\tlet attribute;\n\t\t\tlet attributeID;\n\n\t\t\t// A Draco file may be created with default vertex attributes, whose attribute IDs\n\t\t\t// are mapped 1:1 from their semantic name (POSITION, NORMAL, ...). Alternatively,\n\t\t\t// a Draco file may contain a custom set of attributes, identified by known unique\n\t\t\t// IDs. glTF files always do the latter, and `.drc` files typically do the former.\n\t\t\tif ( taskConfig.useUniqueIDs ) {\n\n\t\t\t\tattributeID = attributeIDs[ attributeName ];\n\t\t\t\tattribute = decoder.GetAttributeByUniqueId( dracoGeometry, attributeID );\n\n\t\t\t} else {\n\n\t\t\t\tattributeID = decoder.GetAttributeId( dracoGeometry, draco[ attributeIDs[ attributeName ] ] );\n\n\t\t\t\tif ( attributeID === - 1 ) continue;\n\n\t\t\t\tattribute = decoder.GetAttribute( dracoGeometry, attributeID );\n\n\t\t\t}\n\n\t\t\tconst attributeResult = decodeAttribute( draco, decoder, dracoGeometry, attributeName, attributeType, attribute );\n\n\t\t\tif ( attributeName === 'color' ) {\n\n\t\t\t\tattributeResult.vertexColorSpace = taskConfig.vertexColorSpace;\n\n\t\t\t}\n\n\t\t\tgeometry.attributes.push( attributeResult );\n\n\t\t}\n\n\t\t// Add index.\n\t\tif ( geometryType === draco.TRIANGULAR_MESH ) {\n\n\t\t\tgeometry.index = decodeIndex( draco, decoder, dracoGeometry );\n\n\t\t}\n\n\t\tdraco.destroy( dracoGeometry );\n\n\t\treturn geometry;\n\n\t}\n\n\tfunction decodeIndex( draco, decoder, dracoGeometry ) {\n\n\t\tconst numFaces = dracoGeometry.num_faces();\n\t\tconst numIndices = numFaces * 3;\n\t\tconst byteLength = numIndices * 4;\n\n\t\tconst ptr = draco._malloc( byteLength );\n\t\tdecoder.GetTrianglesUInt32Array( dracoGeometry, byteLength, ptr );\n\t\tconst index = new Uint32Array( draco.HEAPF32.buffer, ptr, numIndices ).slice();\n\t\tdraco._free( ptr );\n\n\t\treturn { array: index, itemSize: 1 };\n\n\t}\n\n\tfunction decodeAttribute( draco, decoder, dracoGeometry, attributeName, TypedArray, attribute ) {\n\n\t\tconst count = dracoGeometry.num_points();\n\t\tconst itemSize = attribute.num_components();\n\t\tconst dracoDataType = getDracoDataType( draco, TypedArray );\n\n\t\t// Reference: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#data-alignment\n\t\tconst srcByteStride = itemSize * TypedArray.BYTES_PER_ELEMENT;\n\t\tconst dstByteStride = Math.ceil( srcByteStride / 4 ) * 4;\n\n\t\tconst dstStride = dstByteStride / TypedArray.BYTES_PER_ELEMENT;\n\n\t\tconst srcByteLength = count * srcByteStride;\n\t\tconst dstByteLength = count * dstByteStride;\n\n\t\tconst ptr = draco._malloc( srcByteLength );\n\t\tdecoder.GetAttributeDataArrayForAllPoints( dracoGeometry, attribute, dracoDataType, srcByteLength, ptr );\n\n\t\tconst srcArray = new TypedArray( draco.HEAPF32.buffer, ptr, srcByteLength / TypedArray.BYTES_PER_ELEMENT );\n\t\tlet dstArray;\n\n\t\tif ( srcByteStride === dstByteStride ) {\n\n\t\t\t// THREE.BufferAttribute\n\n\t\t\tdstArray = srcArray.slice();\n\n\t\t} else {\n\n\t\t\t// THREE.InterleavedBufferAttribute\n\n\t\t\tdstArray = new TypedArray( dstByteLength / TypedArray.BYTES_PER_ELEMENT );\n\n\t\t\tlet dstOffset = 0;\n\n\t\t\tfor ( let i = 0, il = srcArray.length; i < il; i ++ ) {\n\n\t\t\t\tfor ( let j = 0; j < itemSize; j ++ ) {\n\n\t\t\t\t\tdstArray[ dstOffset + j ] = srcArray[ i * itemSize + j ];\n\n\t\t\t\t}\n\n\t\t\t\tdstOffset += dstStride;\n\n\t\t\t}\n\n\t\t}\n\n\t\tdraco._free( ptr );\n\n\t\treturn {\n\t\t\tname: attributeName,\n\t\t\tcount: count,\n\t\t\titemSize: itemSize,\n\t\t\tarray: dstArray,\n\t\t\tstride: dstStride\n\t\t};\n\n\t}\n\n\tfunction getDracoDataType( draco, TypedArray ) {\n\n\t\tswitch ( TypedArray ) {\n\n\t\t\tcase Float32Array: return draco.DT_FLOAT32;\n\t\t\tcase Int8Array: return draco.DT_INT8;\n\t\t\tcase Int16Array: return draco.DT_INT16;\n\t\t\tcase Int32Array: return draco.DT_INT32;\n\t\t\tcase Uint8Array: return draco.DT_UINT8;\n\t\t\tcase Uint16Array: return draco.DT_UINT16;\n\t\t\tcase Uint32Array: return draco.DT_UINT32;\n\n\t\t}\n\n\t}\n\n}\n\nexport { DRACOLoader };\n","export default \"data:image/webp;base64,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L3NUeXBlL1Jlc291cmNlRXZlbnQjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzYgKFdpbmRvd3MpIiB4bXA6Q3JlYXRlRGF0ZT0iMjAxOS0wNi0wNVQwOToyODozNyswODowMCIgeG1wOk1vZGlmeURhdGU9IjIwMTktMDctMjNUMTE6MTQ6MDQrMDg6MDAiIHhtcDpNZXRhZGF0YURhdGU9IjIwMTktMDctMjNUMTE6MTQ6MDQrMDg6MDAiIGRjOmZvcm1hdD0iaW1hZ2UvanBlZyIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgcGhvdG9zaG9wOklDQ1Byb2ZpbGU9InNSR0IgSUVDNjE5NjYtMi4xIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkY1Q0RGRUVDRjdBQ0U5MTE4MEU2REUwMkQyMkQ4NThCIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjA1QkM5REU5RjdBQ0U5MTE4MEU2REUwMkQyMkQ4NThCIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6MDVCQzlERTlGN0FDRTkxMTgwRTZERTAyRDIyRDg1OEIiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjA1QkM5REU5RjdBQ0U5MTE4MEU2REUwMkQyMkQ4NThCIiBzdEV2dDp3aGVuPSIyMDE5LTA2LTA1VDA5OjI4OjM3KzA4OjAwIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ1M2IChXaW5kb3dzKSIvPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY29udmVydGVkIiBzdEV2dDpwYXJhbWV0ZXJzPSJmcm9tIGltYWdlL3BuZyB0byBpbWFnZS9qcGVnIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDpGNUNERkVFQ0Y3QUNFOTExODBFNkRFMDJEMjJEODU4QiIgc3RFdnQ6d2hlbj0iMjAxOS0wNy0yM1QxMToxNDowNCswODowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHN0RXZ0OmNoYW5nZWQ9Ii8iLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw/eHBhY2tldCBlbmQ9InciPz4=\"","/**\r\n * 提供添加基础几何体(正方体、球体)以及导入外部模型文件的功能\r\n * 所有模型均自动标记为可移动(isMovable = true)\r\n */\r\n\r\nimport * as THREE from \"three\";\r\nimport { addModel } from \"./index\";\r\nimport { OBJLoader } from \"three/examples/jsm/loaders/OBJLoader.js\";\r\nimport { GLTFLoader } from \"three/examples/jsm/loaders/GLTFLoader.js\";\r\nimport { DRACOLoader } from \"three/examples/jsm/loaders/DRACOLoader.js\";\r\n// import { Water } from \"three/examples/jsm/objects/Water.js\";\r\nimport image from \"../assets/water.webp\";\r\n//#region ─── 添加基础体 ───\r\n\r\n/**\r\n * 添加一个蓝色的正方体,位置在地面上方 0.5 单位\r\n */\r\nexport function addBox() {\r\n const geo = new THREE.BoxGeometry(1, 1, 1);\r\n const mat = new THREE.MeshStandardMaterial({ color: 0x00aaff });\r\n const mesh = new THREE.Mesh(geo, mat);\r\n mesh.position.y = 0.5;\r\n mesh.userData.isMovable = true;\r\n mesh.name = \"正方体\";\r\n addModel(mesh, true);\r\n return mesh;\r\n}\r\n\r\n/**\r\n * 添加一个橙色的球体,位置在地面上方 0.6 单位\r\n */\r\nexport function addSphere() {\r\n const geo = new THREE.SphereGeometry(0.6, 32, 32);\r\n const mat = new THREE.MeshStandardMaterial({ color: 0xff8800 });\r\n const mesh = new THREE.Mesh(geo, mat);\r\n mesh.position.y = 0.6;\r\n mesh.userData.isMovable = true;\r\n mesh.name = \"球体\";\r\n addModel(mesh, true);\r\n return mesh;\r\n}\r\n\r\n/**\r\n * 添加一个平行光\r\n */\r\nexport function addDirectionalLight() {\r\n const light = new THREE.DirectionalLight(0xffffff);\r\n light.position.set(5, 5, 5);\r\n light.name = \"平行光\";\r\n light.userData.isMovable = true;\r\n // 光源朝向原点\r\n light.target.position.set(0, 0, 0);\r\n const helper = new THREE.DirectionalLightHelper(light, 1);\r\n helper.lightPlane.userData.name = \"平行光辅助\";\r\n helper.userData.type = \"lightHelper\";\r\n\r\n light.userData.helper = helper;\r\n // 将 helper 作为 light 的子节点,实现跟随移动\r\n // light.add(helper);\r\n addModel(helper);\r\n addModel(light, true);\r\n}\r\n\r\n/**\r\n * 添加水面效果\r\n */\r\n// export function addWater(width = 10, height = 10) {\r\n // const waterGeometry = new THREE.BoxGeometry(10, 10, 10);;\r\n // const textureLoader = new THREE.TextureLoader();\r\n\r\n // // 根据几何体大小计算法线贴图重复次数,保持法线细节密度一致(每单位约 2 次重复)\r\n // const repeatX = Math.max(1, Math.round(width * 2));\r\n // const repeatY = Math.max(1, Math.round(height * 2));\r\n\r\n // const waterNormals = textureLoader.load(image, (texture) => {\r\n // texture.wrapS = texture.wrapT = THREE.RepeatWrapping;\r\n // texture.repeat.set(repeatX, repeatY);\r\n // texture.generateMipmaps = true;\r\n // texture.minFilter = THREE.LinearMipmapLinearFilter;\r\n // texture.magFilter = THREE.LinearFilter;\r\n // });\r\n\r\n // // 计算合理的反射纹理分辨率(基于面积,设置上限避免性能问题)\r\n // const texSize = Math.min(1024, Math.max(256, Math.round(Math.sqrt(width * height) * 64)));\r\n\r\n // const water = new Water(waterGeometry, {\r\n // textureWidth: texSize,\r\n // textureHeight: texSize,\r\n // waterNormals: waterNormals,\r\n // alpha: 0.2,\r\n // sunDirection: new THREE.Vector3(10, 50, 50).normalize(),\r\n // sunColor: \"#aa1a1a\",\r\n // waterColor: \"#1a6daa\",\r\n // distortionScale: 3.7,\r\n // fog: false,\r\n // });\r\n\r\n // water.rotation.x = -Math.PI / 2;\r\n // water.material.side = THREE.DoubleSide;\r\n // water.userData.isMovable = true;\r\n // water.userData.isWater = true;\r\n // water.name = \"水面\";\r\n \r\n // addModel(water, true);\r\n// }\r\n\r\n/**\r\n * 添加水纹法线贴图\r\n */\r\nexport function addWaterPlane(options?: {\r\n width?: number;\r\n height?: number;\r\n color?: string | number;\r\n roughness?: number;\r\n metalness?: number;\r\n normalScale?: number;\r\n repeatX?: number;\r\n repeatY?: number;\r\n speedX?: number;\r\n speedY?: number;\r\n}) {\r\n const {\r\n width = 10,\r\n height = 10,\r\n color = 0x0077be,\r\n roughness = 0.3,\r\n metalness = 0.1,\r\n normalScale = 0.5,\r\n repeatX = 4,\r\n repeatY = 4,\r\n speedX = 0.003,\r\n speedY = 0.002,\r\n } = options || {};\r\n\r\n // 1. 创建几何体(平面)\r\n const geometry = new THREE.PlaneGeometry(width, height);\r\n\r\n // 2. 加载法线贴图\r\n const textureLoader = new THREE.TextureLoader();\r\n // 请将 'path/to/water_normal.jpg' 替换为你的法线贴图路径\r\n const normalMap = textureLoader.load(image, (texture) => {\r\n // 纹理加载完成后设置包裹和重复\r\n texture.wrapS = texture.wrapT = THREE.RepeatWrapping;\r\n texture.repeat.set(repeatX, repeatY);\r\n // 对非2的幂纹理,关闭mipmap生成(可选)\r\n texture.generateMipmaps = false;\r\n texture.minFilter = THREE.LinearFilter;\r\n texture.magFilter = THREE.LinearFilter;\r\n });\r\n\r\n // 3. 创建材质\r\n const material = new THREE.MeshStandardMaterial({\r\n color: color,\r\n roughness: roughness,\r\n metalness: metalness,\r\n normalMap: normalMap,\r\n normalScale: new THREE.Vector2(normalScale, normalScale),\r\n side: THREE.DoubleSide, // 双面渲染,避免从侧面或底部看到黑色\r\n transparent: true,\r\n opacity: 0.8,\r\n });\r\n\r\n // 4. 创建网格\r\n const mesh = new THREE.Mesh(geometry, material);\r\n mesh.rotation.x = -Math.PI / 2; // 水平放置\r\n mesh.position.y = 0;\r\n mesh.name = '水面(标准材质)';\r\n\r\n // 5. 保存必要的元数据,用于动画更新\r\n mesh.userData.isWater = true; // 标记为水面\r\n mesh.userData.isMovable = true; // 允许在编辑器中选中和移动\r\n mesh.userData.waterSpeed = { x: speedX, y: speedY }; // 偏移速度\r\n\r\n // 6. 添加到场景\r\n addModel(mesh);\r\n}\r\n//#endregion\r\n\r\n//#region ─── 导入外部模型 ───\r\n\r\n/**\r\n * 从 File 对象导入 3D 模型(支持 .obj, .gltf, .glb)\r\n * 导入后自动标记所有节点为可移动,并居中放置\r\n * @param file - 模型文件\r\n * @returns Promise 解析为模型根对象\r\n */\r\nexport function importModelFromFile(file: File): Promise<THREE.Object3D> {\r\n return new Promise((resolve, reject) => {\r\n const ext = file.name.split(\".\").pop()?.toLowerCase();\r\n const url = URL.createObjectURL(file);\r\n\r\n let loader: any;\r\n if (ext === \"obj\") {\r\n loader = new OBJLoader();\r\n } else if (ext === \"gltf\" || ext === \"glb\") {\r\n // 为 GLTFLoader 配置 DRACOLoader 以支持 Draco 压缩的模型\r\n const dracoLoader = new DRACOLoader();\r\n dracoLoader.setDecoderPath(\r\n \"https://www.gstatic.com/draco/versioned/decoders/1.5.7/\",\r\n );\r\n const gltfLoader = new GLTFLoader();\r\n gltfLoader.setDRACOLoader(dracoLoader);\r\n loader = gltfLoader;\r\n } else {\r\n reject(new Error(\"不支持的文件格式,请使用 .obj, .gltf, .glb\"));\r\n return;\r\n }\r\n\r\n loader.load(\r\n url,\r\n (result: any) => {\r\n // 获取模型根对象\r\n const model = ext === \"gltf\" || ext === \"glb\" ? result.scene : result;\r\n // 遍历所有后代,标记为可移动,设置默认名称,优化 Mesh\r\n model.traverse((child: THREE.Object3D) => {\r\n child.userData.isMovable = true;\r\n if (!child.name) child.name = child.type;\r\n if (child.type === \"Mesh\") {\r\n child.frustumCulled = true; // 启用视锥体裁剪\r\n (child as THREE.Mesh).geometry?.computeVertexNormals(); // 重新计算法线\r\n }\r\n });\r\n // 将模型包围盒中心置于原点(居中)\r\n const box = new THREE.Box3().setFromObject(model);\r\n const center = box.getCenter(new THREE.Vector3());\r\n model.position.sub(center);\r\n // 添加到场景并自动选中\r\n addModel(model, true);\r\n resolve(model);\r\n },\r\n undefined,\r\n (err: any) => reject(err),\r\n );\r\n });\r\n}\r\n\r\n/**\r\n * 根据类型字符串添加对应的基础模型\r\n * @param type - 'box' 或 'sphere'\r\n */\r\nexport function addModelByType(type: string) {\r\n switch (type) {\r\n case \"box\":\r\n addBox();\r\n break;\r\n case \"sphere\":\r\n addSphere();\r\n break;\r\n case \"directionalLight\":\r\n addDirectionalLight();\r\n break;\r\n case \"waterPlane\":\r\n addWaterPlane();\r\n break;\r\n }\r\n}\r\n//#endregion\r\n","<template>\r\n <div class=\"tree-node\" ref=\"nodeRef\">\r\n <!-- 节点行 -->\r\n <div\r\n class=\"tree-item\"\r\n :class=\"{ selected: isSelected }\"\r\n @click=\"handleSelect\"\r\n >\r\n <!-- 展开/收起箭头 -->\r\n <span\r\n v-if=\"hasChildren\"\r\n class=\"toggle-icon\"\r\n @click.stop=\"toggleExpand(node.uuid)\"\r\n >\r\n {{ isExpanded ? \"▼\" : \"▶\" }}\r\n </span>\r\n <span v-else class=\"toggle-placeholder\"></span>\r\n <!-- 图标 -->\r\n <span class=\"tree-icon\">{{ getIcon(node) }}</span>\r\n <!-- 名称 -->\r\n <span class=\"tree-name\">{{ getDisplayName(node) }}</span>\r\n <!-- 删除按钮 -->\r\n <button class=\"tree-delete\" @click.stop=\"handleDelete\">×</button>\r\n </div>\r\n <!-- 子节点列表(递归) -->\r\n <div v-if=\"isExpanded && hasChildren\" class=\"tree-children\">\r\n <TreeItem\r\n v-for=\"child in childNodes\"\r\n :key=\"child.uuid\"\r\n :node=\"child\"\r\n :selected-object=\"selectedObject\"\r\n :version=\"version\"\r\n @select=\"emit('select', $event)\"\r\n @delete=\"emit('delete', $event)\"\r\n />\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\n/**\r\n * 递归树节点组件,用于展示场景物体的层级结构\r\n * 展开状态由父组件通过 provide/inject 共享\r\n * 当节点被选中时自动滚动到可视区域\r\n */\r\n\r\nimport { computed, inject, ref, watchEffect, type Ref } from \"vue\";\r\nimport type { Object3D } from \"three\";\r\n\r\nconst props = defineProps<{\r\n /** 当前节点对应的 Three.js 物体 */\r\n node: Object3D;\r\n /** 当前选中的物体(外部传入) */\r\n selectedObject: Object3D | null;\r\n /** 版本号,用于强制重新计算子节点列表 */\r\n version: number;\r\n}>();\r\n\r\nconst emit = defineEmits<{\r\n (e: \"select\", obj: Object3D): void;\r\n (e: \"delete\", obj: Object3D): void;\r\n}>();\r\n\r\n// ─── DOM 引用 ───\r\nconst nodeRef = ref<HTMLElement | null>(null);\r\n\r\n// ─── 注入展开状态管理 ───\r\nconst { expandedSet, toggleExpand } = inject<{\r\n expandedSet: Ref<Set<string>>;\r\n toggleExpand: (uuid: string) => void;\r\n}>(\"treeExpand\")!;\r\n\r\n// ─── 计算属性 ───\r\n\r\n/** 当前节点是否展开(基于展开集合) */\r\nconst isExpanded = computed(() => expandedSet.value.has(props.node.uuid));\r\n\r\n/** 是否有可移动的子节点(依赖 version) */\r\nconst hasChildren = computed(() => {\r\n const _ = props.version; // 建立依赖\r\n _\r\n return props.node.children.some((child) => child.userData.isMovable === true);\r\n});\r\n\r\n/** 可移动的子节点列表(依赖 version) */\r\nconst childNodes = computed(() => {\r\n const _ = props.version; // 建立依赖\r\n _\r\n return props.node.children.filter(\r\n (child) => child.userData.isMovable === true,\r\n );\r\n});\r\n\r\n/** 当前节点是否被选中 */\r\nconst isSelected = computed(\r\n () => props.selectedObject?.uuid === props.node.uuid,\r\n);\r\n\r\n/**\r\n * 自动滚动到选中节点(使用 watchEffect + flush: 'post' 确保 DOM 更新后执行)\r\n */\r\nwatchEffect(\r\n () => {\r\n if (isSelected.value && nodeRef.value) {\r\n nodeRef.value.scrollIntoView({\r\n block: \"nearest\", // 仅当元素不在可视区域时才滚动\r\n behavior: \"smooth\", // 平滑滚动\r\n });\r\n }\r\n },\r\n { flush: \"post\" },\r\n);\r\n\r\n// ─── 事件处理 ───\r\n\r\n/** 点击节点行:阻止冒泡并触发选中事件 */\r\nconst handleSelect = (event: MouseEvent) => {\r\n event.stopPropagation();\r\n emit(\"select\", props.node);\r\n};\r\n\r\n/** 点击删除按钮:阻止冒泡并触发删除事件 */\r\nconst handleDelete = (event: MouseEvent) => {\r\n event.stopPropagation();\r\n emit(\"delete\", props.node);\r\n};\r\n\r\n// ─── 辅助函数 ───\r\n\r\n/** 根据对象类型返回对应的图标字符 */\r\nconst getIcon = (obj: Object3D) => {\r\n if (obj.type === \"Mesh\" || obj.type === \"Sprite\") return \"🟦\";\r\n if (obj.type === \"Light\") return \"💡\";\r\n return \"📦\";\r\n};\r\n\r\n/** 获取对象的显示名称,若没有则自动生成 */\r\nconst getDisplayName = (obj: Object3D) => obj.name || `${obj.type} (${obj.id})`;\r\n</script>\r\n\r\n<style lang=\"less\" scoped>\r\n/* 节点样式 */\r\n.tree-node {\r\n .tree-item {\r\n display: flex;\r\n align-items: center;\r\n padding: 4px 10px;\r\n cursor: pointer;\r\n transition: background 0.15s;\r\n &:hover {\r\n background: #2a4050;\r\n }\r\n }\r\n .tree-item.selected {\r\n background: #3e5a6b;\r\n }\r\n\r\n .toggle-icon {\r\n cursor: pointer;\r\n width: 20px;\r\n text-align: center;\r\n font-size: 12px;\r\n user-select: none;\r\n }\r\n .toggle-placeholder {\r\n width: 20px;\r\n display: inline-block;\r\n }\r\n .tree-icon {\r\n margin-right: 6px;\r\n font-size: 14px;\r\n }\r\n .tree-name {\r\n flex: 1;\r\n font-size: 13px;\r\n user-select: none;\r\n }\r\n .tree-delete {\r\n background: transparent;\r\n border: none;\r\n color: #e74c3c;\r\n font-size: 16px;\r\n cursor: pointer;\r\n padding: 0 4px;\r\n line-height: 1;\r\n &:hover {\r\n color: #ff6b6b;\r\n }\r\n }\r\n}\r\n.tree-children {\r\n padding-left: 20px;\r\n} /* 缩进 */\r\n</style>\r\n","<template>\r\n <div>\r\n <!-- 位置 -->\r\n <div class=\"property-group\">\r\n <label>位置</label>\r\n <div class=\"row\">\r\n <span>X:</span>\r\n <input\r\n type=\"number\"\r\n v-model.number=\"transform.position.x\"\r\n step=\"0.01\"\r\n @input=\"emitChange\"\r\n />\r\n <span>Y:</span>\r\n <input\r\n type=\"number\"\r\n v-model.number=\"transform.position.y\"\r\n step=\"0.01\"\r\n @input=\"emitChange\"\r\n />\r\n <span>Z:</span>\r\n <input\r\n type=\"number\"\r\n v-model.number=\"transform.position.z\"\r\n step=\"0.01\"\r\n @input=\"emitChange\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- 旋转 (弧度) -->\r\n <div class=\"property-group\">\r\n <label>旋转 (弧度)</label>\r\n <div class=\"row\">\r\n <span>X:</span>\r\n <input\r\n type=\"number\"\r\n v-model.number=\"transform.rotation.x\"\r\n step=\"0.01\"\r\n @input=\"emitChange\"\r\n />\r\n <span>Y:</span>\r\n <input\r\n type=\"number\"\r\n v-model.number=\"transform.rotation.y\"\r\n step=\"0.01\"\r\n @input=\"emitChange\"\r\n />\r\n <span>Z:</span>\r\n <input\r\n type=\"number\"\r\n v-model.number=\"transform.rotation.z\"\r\n step=\"0.01\"\r\n @input=\"emitChange\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- 缩放 -->\r\n <div class=\"property-group\">\r\n <label>缩放</label>\r\n <div class=\"row\">\r\n <span>X:</span>\r\n <input\r\n type=\"number\"\r\n v-model.number=\"transform.scale.x\"\r\n step=\"0.01\"\r\n @input=\"emitChange\"\r\n />\r\n <span>Y:</span>\r\n <input\r\n type=\"number\"\r\n v-model.number=\"transform.scale.y\"\r\n step=\"0.01\"\r\n @input=\"emitChange\"\r\n />\r\n <span>Z:</span>\r\n <input\r\n type=\"number\"\r\n v-model.number=\"transform.scale.z\"\r\n step=\"0.01\"\r\n @input=\"emitChange\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- ─── 光源属性 ─── -->\r\n <div class=\"property-group light-group\" v-if=\"selectedObject && selectedObject.type === 'DirectionalLight'\">\r\n <label>光源属性</label>\r\n <div class=\"slider-row\">\r\n <span class=\"slider-label\">强度</span>\r\n <input\r\n type=\"range\"\r\n min=\"0\"\r\n max=\"10\"\r\n step=\"0.1\"\r\n v-model.number=\"lightProps.intensity\"\r\n @input=\"onLightIntensityChange\"\r\n />\r\n <input\r\n type=\"number\"\r\n min=\"0\"\r\n max=\"100\"\r\n step=\"0.1\"\r\n v-model.number=\"lightProps.intensity\"\r\n class=\"intensity-input\"\r\n @input=\"onLightIntensityChange\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- ─── 材质属性 ─── -->\r\n <div class=\"property-group material-group\" v-if=\"selectedObject\">\r\n <label>材质</label>\r\n <div class=\"slider-row\">\r\n <span class=\"slider-label\">金属度</span>\r\n <input\r\n type=\"range\"\r\n min=\"0\"\r\n max=\"1\"\r\n step=\"0.01\"\r\n v-model.number=\"materialProps.metalness\"\r\n @input=\"onMaterialChange\"\r\n />\r\n <span class=\"slider-value\">{{\r\n materialProps.metalness.toFixed(2)\r\n }}</span>\r\n </div>\r\n <div class=\"slider-row\">\r\n <span class=\"slider-label\">粗糙度</span>\r\n <input\r\n type=\"range\"\r\n min=\"0\"\r\n max=\"1\"\r\n step=\"0.01\"\r\n v-model.number=\"materialProps.roughness\"\r\n @input=\"onMaterialChange\"\r\n />\r\n <span class=\"slider-value\">{{\r\n materialProps.roughness.toFixed(2)\r\n }}</span>\r\n </div>\r\n <div class=\"slider-row\">\r\n <span class=\"slider-label\">透明度</span>\r\n <input\r\n type=\"range\"\r\n min=\"0\"\r\n max=\"1\"\r\n step=\"0.01\"\r\n v-model.number=\"materialProps.opacity\"\r\n @input=\"onMaterialChange\"\r\n />\r\n <span class=\"slider-value\">{{\r\n materialProps.opacity.toFixed(2)\r\n }}</span>\r\n </div>\r\n <div class=\"material-hint\" v-if=\"!hasStandardMaterial\">\r\n ⚠️ 当前材质不支持金属度/粗糙度(仅支持 Standard/Phong)\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\nimport type { Object3D, Mesh } from \"three\";\r\nimport { ref, watch, reactive } from \"vue\";\r\n\r\nconst props = defineProps<{\r\n transform: {\r\n position: { x: number; y: number; z: number };\r\n rotation: { x: number; y: number; z: number };\r\n scale: { x: number; y: number; z: number };\r\n };\r\n selectedObject: Object3D | null;\r\n}>();\r\n\r\nconst emit = defineEmits<{\r\n (e: \"propertyChange\"): void;\r\n}>();\r\n\r\nconst emitChange = () => emit(\"propertyChange\");\r\n\r\n// ━━━━━ 材质属性管理 ━━━━━\r\n\r\nconst materialProps = reactive({\r\n metalness: 0,\r\n roughness: 0.5,\r\n opacity: 1,\r\n});\r\n\r\nconst hasStandardMaterial = ref(false);\r\n\r\n// ━━━━━ 光源属性管理 ━━━━━\r\n\r\nconst lightProps = reactive({\r\n intensity: 1,\r\n});\r\n\r\nfunction onLightIntensityChange() {\r\n if (props.selectedObject && props.selectedObject.type === \"DirectionalLight\") {\r\n (props.selectedObject as any).intensity = lightProps.intensity;\r\n }\r\n}\r\n\r\nfunction readMaterialFromObject(\r\n obj: Object3D,\r\n): { metalness: number; roughness: number; opacity: number } | null {\r\n let result: { metalness: number; roughness: number; opacity: number } | null = null;\r\n obj.traverse((child) => {\r\n if (child.type === \"Mesh\" && !result) {\r\n const mesh = child as Mesh;\r\n const materials = Array.isArray(mesh.material)\r\n ? mesh.material\r\n : [mesh.material];\r\n for (const mat of materials) {\r\n if (\r\n mat &&\r\n (mat.type === \"MeshStandardMaterial\" ||\r\n mat.type === \"MeshPhongMaterial\")\r\n ) {\r\n const stdMat = mat as any;\r\n result = {\r\n metalness: stdMat.metalness ?? 0,\r\n roughness: stdMat.roughness ?? 0.5,\r\n opacity: mat.opacity ?? 1,\r\n };\r\n break;\r\n }\r\n }\r\n }\r\n });\r\n return result;\r\n}\r\n\r\nfunction applyMaterialToObject(\r\n obj: Object3D,\r\n propsToApply: { metalness?: number; roughness?: number; opacity?: number },\r\n) {\r\n let applied = false;\r\n obj.traverse((child) => {\r\n if (child.type === \"Mesh\") {\r\n const mesh = child as Mesh;\r\n const materials = Array.isArray(mesh.material)\r\n ? mesh.material\r\n : [mesh.material];\r\n for (const mat of materials) {\r\n if (\r\n mat &&\r\n (mat.type === \"MeshStandardMaterial\" ||\r\n mat.type === \"MeshPhongMaterial\")\r\n ) {\r\n if (propsToApply.metalness !== undefined)\r\n (mat as any).metalness = propsToApply.metalness;\r\n if (propsToApply.roughness !== undefined)\r\n (mat as any).roughness = propsToApply.roughness;\r\n if (propsToApply.opacity !== undefined) {\r\n mat.opacity = propsToApply.opacity;\r\n mat.transparent = propsToApply.opacity < 1;\r\n }\r\n mat.needsUpdate = true;\r\n applied = true;\r\n }\r\n }\r\n }\r\n });\r\n return applied;\r\n}\r\n\r\nfunction onMaterialChange() {\r\n if (props.selectedObject) {\r\n const applied = applyMaterialToObject(props.selectedObject, {\r\n metalness: materialProps.metalness,\r\n roughness: materialProps.roughness,\r\n opacity: materialProps.opacity,\r\n });\r\n hasStandardMaterial.value = applied;\r\n }\r\n}\r\n\r\nwatch(\r\n () => props.selectedObject,\r\n (newObj) => {\r\n if (newObj) {\r\n const read = readMaterialFromObject(newObj);\r\n if (read) {\r\n materialProps.metalness = read.metalness;\r\n materialProps.roughness = read.roughness;\r\n materialProps.opacity = read.opacity;\r\n hasStandardMaterial.value = true;\r\n } else {\r\n materialProps.metalness = 0;\r\n materialProps.roughness = 0.5;\r\n materialProps.opacity = 1;\r\n hasStandardMaterial.value = false;\r\n }\r\n if (newObj.type === \"DirectionalLight\") {\r\n lightProps.intensity = (newObj as any).intensity ?? 1;\r\n }\r\n } else {\r\n materialProps.metalness = 0;\r\n materialProps.roughness = 0.5;\r\n materialProps.opacity = 1;\r\n hasStandardMaterial.value = false;\r\n }\r\n },\r\n { immediate: true },\r\n);\r\n\r\n</script>\r\n\r\n<style lang=\"less\" scoped>\r\n.property-group {\r\n margin-bottom: 20px;\r\n border-bottom: 1px solid #1a2a36;\r\n padding-bottom: 12px;\r\n\r\n label {\r\n font-weight: bold;\r\n display: block;\r\n margin-bottom: 8px;\r\n color: #f1c40f;\r\n }\r\n\r\n .row {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n margin-bottom: 6px;\r\n\r\n span {\r\n width: 20px;\r\n text-align: right;\r\n }\r\n\r\n input {\r\n background: #1e2a36;\r\n border: 1px solid #3e5a6b;\r\n color: #ecf0f1;\r\n padding: 4px 8px;\r\n border-radius: 4px;\r\n width: 48px;\r\n }\r\n }\r\n}\r\n\r\n.light-group {\r\n .intensity-input {\r\n width: 48px;\r\n background: #1e2a36;\r\n border: 1px solid #3e5a6b;\r\n color: #ecf0f1;\r\n padding: 2px 6px;\r\n border-radius: 4px;\r\n text-align: center;\r\n flex: 0 0 auto;\r\n }\r\n}\r\n\r\n.material-group {\r\n .slider-row {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n margin-bottom: 6px;\r\n\r\n .slider-label {\r\n width: 50px;\r\n font-size: 12px;\r\n color: #95a5a6;\r\n }\r\n\r\n input[type=\"range\"] {\r\n flex: 1;\r\n height: 4px;\r\n -webkit-appearance: none;\r\n background: #1e2a36;\r\n border-radius: 2px;\r\n outline: none;\r\n\r\n &::-webkit-slider-thumb {\r\n -webkit-appearance: none;\r\n width: 12px;\r\n height: 12px;\r\n border-radius: 50%;\r\n background: #f1c40f;\r\n cursor: pointer;\r\n }\r\n }\r\n\r\n .slider-value {\r\n width: 36px;\r\n font-size: 12px;\r\n text-align: center;\r\n color: #ecf0f1;\r\n }\r\n }\r\n\r\n .material-hint {\r\n margin-top: 6px;\r\n font-size: 12px;\r\n color: #e67e22;\r\n }\r\n}\r\n</style>","<template>\r\n <div class=\"userdata-tab\">\r\n <div class=\"property-group userdata-group\">\r\n <label>userData 属性</label>\r\n\r\n <!-- 添加新属性 -->\r\n <div class=\"userdata-add-row\">\r\n <input\r\n type=\"text\"\r\n v-model=\"newKey\"\r\n placeholder=\"属性名\"\r\n class=\"ud-input\"\r\n @keyup.enter=\"addUserDataEntry\"\r\n />\r\n <textarea\r\n v-model=\"newValue\"\r\n placeholder=\"值\"\r\n class=\"ud-input ud-textarea\"\r\n @keyup.enter.prevent=\"addUserDataEntry\"\r\n ></textarea>\r\n <button class=\"ud-btn add-btn\" title=\"添加\" @click=\"addUserDataEntry\">+</button>\r\n </div>\r\n\r\n <!-- 已有属性列表 -->\r\n <div class=\"userdata-list\" v-if=\"userDataEntries.length > 0\">\r\n <div\r\n v-for=\"(entry, index) in userDataEntries\"\r\n :key=\"entry.key\"\r\n class=\"userdata-item\"\r\n :class=\"{ readonly: entry.key === 'isMovable', 'editing-json': editingJsonKey === entry.key }\"\r\n >\r\n <span class=\"ud-key\">{{ entry.key }}</span>\r\n\r\n <!-- isMovable 只读 -->\r\n <span v-if=\"entry.key === 'isMovable'\" class=\"ud-value-readonly\" :title=\"'isMovable 为系统属性,不可修改'\">\r\n {{ String(entry.value) }} 🔒\r\n </span>\r\n\r\n <!-- 对象/数组类型:可展开编辑 -->\r\n <template v-else-if=\"entry.key !== 'isMovable'\">\r\n <!-- 未展开:显示 JSON 预览 + 编辑按钮 -->\r\n <template v-if=\"editingJsonKey !== entry.key\">\r\n <span class=\"ud-value-json-preview\">{{ truncateJson(entry.value) }}</span>\r\n <button\r\n class=\"ud-btn edit-json-btn\"\r\n title=\"编辑对象\"\r\n @click=\"startEditingJson(entry.key)\"\r\n >\r\n ✎\r\n </button>\r\n </template>\r\n\r\n <!-- 展开编辑:显示 textarea + 应用/取消按钮 -->\r\n <template v-else>\r\n <div class=\"ud-json-error\" v-if=\"jsonError\">⚠ {{ jsonError }}</div>\r\n <textarea\r\n v-model=\"jsonEditText\"\r\n class=\"ud-json-textarea\"\r\n :class=\"{ 'has-error': jsonError }\"\r\n rows=\"3\"\r\n @input=\"validateJsonInput\"\r\n ></textarea>\r\n <div class=\"ud-json-actions\">\r\n <button class=\"ud-btn apply-btn\" title=\"应用修改\" @click=\"applyJsonEdit(entry.key)\">\r\n ✓\r\n </button>\r\n <button class=\"ud-btn cancel-btn\" title=\"取消编辑\" @click=\"cancelJsonEdit\">\r\n ✕\r\n </button>\r\n </div>\r\n </template>\r\n\r\n <!-- 删除按钮 -->\r\n <button\r\n v-if=\"editingJsonKey !== entry.key\"\r\n class=\"ud-btn del-btn\"\r\n title=\"删除\"\r\n @click=\"deleteUserDataEntry(entry.key, index)\"\r\n >\r\n ✕\r\n </button>\r\n </template>\r\n </div>\r\n </div>\r\n <div v-else class=\"userdata-empty\">暂无自定义数据</div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\n/**\r\n * 自定义数据 Tab 组件\r\n * 管理物体的 userData 属性:添加、编辑、删除\r\n */\r\nimport type { Object3D } from \"three\";\r\nimport { ref, watch } from \"vue\";\r\n\r\nconst props = defineProps<{\r\n selectedObject: Object3D | null;\r\n}>();\r\n\r\n// ━━━━━ 状态 ━━━━━\r\n\r\n/** 新增属性名 */\r\nconst newKey = ref(\"\");\r\n/** 新增属性值 */\r\nconst newValue = ref(\"\");\r\n\r\n/** 当前正在编辑 JSON 的属性键名(null 表示没有展开编辑) */\r\nconst editingJsonKey = ref<string | null>(null);\r\n/** JSON 编辑区的文本 */\r\nconst jsonEditText = ref(\"\");\r\n/** JSON 实时校验错误信息(null 表示无错误) */\r\nconst jsonError = ref<string | null>(null);\r\n\r\ninterface UserDataEntry {\r\n key: string;\r\n value: string;\r\n rawType: \"string\" | \"number\" | \"boolean\" | \"object\" | \"array\" | \"null\" | \"undefined\";\r\n}\r\n\r\n/** 当前物体的 userData 条目列表 */\r\nconst userDataEntries = ref<UserDataEntry[]>([]);\r\n\r\n// ━━━━━ 方法 ━━━━━\r\n\r\n/** 获取值的显示类型 */\r\nfunction getRawType(val: any): UserDataEntry[\"rawType\"] {\r\n if (val === null) return \"null\";\r\n if (val === undefined) return \"undefined\";\r\n if (Array.isArray(val)) return \"array\";\r\n const t = typeof val;\r\n if (t === \"object\") return \"object\";\r\n if (t === \"number\") return \"number\";\r\n if (t === \"boolean\") return \"boolean\";\r\n return \"string\";\r\n}\r\n\r\n/** 从选中物体加载 userData 到列表 */\r\nfunction loadUserDataFromObject(obj: Object3D) {\r\n const entries: UserDataEntry[] = [];\r\n if (obj.userData) {\r\n for (const [key, val] of Object.entries(obj.userData)) {\r\n if (typeof key === \"string\" && !key.startsWith(\"_\")) {\r\n entries.push({\r\n key,\r\n value: typeof val === \"object\" ? JSON.stringify(val) : String(val),\r\n rawType: getRawType(val),\r\n });\r\n }\r\n }\r\n }\r\n userDataEntries.value = entries;\r\n}\r\n\r\n/** 尝试将字符串解析为原始类型 */\r\nfunction parseValue(raw: string): any {\r\n const trimmed = raw.trim();\r\n if (trimmed === \"true\") return true;\r\n if (trimmed === \"false\") return false;\r\n if (trimmed === \"null\") return null;\r\n if (trimmed === \"undefined\") return undefined;\r\n const num = Number(trimmed);\r\n if (trimmed !== \"\" && !isNaN(num)) return num;\r\n if (\r\n (trimmed.startsWith(\"{\") && trimmed.endsWith(\"}\")) ||\r\n (trimmed.startsWith(\"[\") && trimmed.endsWith(\"]\"))\r\n ) {\r\n try {\r\n return JSON.parse(trimmed);\r\n } catch {\r\n // 解析失败则当作普通字符串\r\n }\r\n }\r\n return trimmed;\r\n}\r\n\r\n/** 添加新的 userData 条目 */\r\nfunction addUserDataEntry() {\r\n if (!props.selectedObject || !newKey.value.trim()) return;\r\n const key = newKey.value.trim();\r\n if (key === \"isMovable\") {\r\n newKey.value = \"\";\r\n return;\r\n }\r\n const parsed = parseValue(newValue.value);\r\n (props.selectedObject.userData as any)[key] = parsed;\r\n loadUserDataFromObject(props.selectedObject);\r\n newKey.value = \"\";\r\n newValue.value = \"\";\r\n}\r\n\r\n/** 删除 userData 条目 */\r\nfunction deleteUserDataEntry(key: string, _index: number) {\r\n if (!props.selectedObject) return;\r\n delete (props.selectedObject.userData as any)[key];\r\n loadUserDataFromObject(props.selectedObject);\r\n}\r\n\r\n/** 截断 JSON 字符串用于预览展示 */\r\nfunction truncateJson(raw: string): string {\r\n const maxLen = 28;\r\n if (raw.length <= maxLen) return raw;\r\n return raw.substring(0, maxLen) + \"…\";\r\n}\r\n\r\n/** 开始编辑某个属性的 JSON */\r\nfunction startEditingJson(key: string) {\r\n editingJsonKey.value = key;\r\n const obj = props.selectedObject;\r\n if (!obj) return;\r\n const actualValue = (obj.userData as any)[key];\r\n try {\r\n jsonEditText.value = JSON.stringify(actualValue, null, 2);\r\n } catch {\r\n jsonEditText.value = String(actualValue);\r\n }\r\n validateJsonInput();\r\n}\r\n\r\n/** 实时校验 JSON 输入 */\r\nfunction validateJsonInput() {\r\n const text = jsonEditText.value.trim();\r\n if (!text) {\r\n jsonError.value = null;\r\n return;\r\n }\r\n if (!text.startsWith(\"{\") && !text.startsWith(\"[\")) {\r\n jsonError.value = \"提示:当前输入不是 JSON 格式,将作为普通字符串保存\";\r\n return;\r\n }\r\n try {\r\n JSON.parse(text);\r\n jsonError.value = null;\r\n } catch (e) {\r\n jsonError.value = \"JSON 格式错误:\" + (e as Error).message;\r\n }\r\n}\r\n\r\n/** 应用 JSON 编辑 */\r\nfunction applyJsonEdit(key: string) {\r\n const obj = props.selectedObject;\r\n if (!obj) return;\r\n const text = jsonEditText.value.trim();\r\n try {\r\n const parsed = JSON.parse(text);\r\n (obj.userData as any)[key] = parsed;\r\n loadUserDataFromObject(obj);\r\n editingJsonKey.value = null;\r\n jsonEditText.value = \"\";\r\n } catch {\r\n (obj.userData as any)[key] = text;\r\n loadUserDataFromObject(obj);\r\n editingJsonKey.value = null;\r\n jsonEditText.value = \"\";\r\n }\r\n}\r\n\r\n/** 取消 JSON 编辑 */\r\nfunction cancelJsonEdit() {\r\n editingJsonKey.value = null;\r\n jsonEditText.value = \"\";\r\n}\r\n\r\n/** 监听选中物体变化,同步 userData */\r\nwatch(\r\n () => props.selectedObject,\r\n (newObj) => {\r\n if (newObj) {\r\n loadUserDataFromObject(newObj);\r\n } else {\r\n userDataEntries.value = [];\r\n }\r\n editingJsonKey.value = null;\r\n jsonEditText.value = \"\";\r\n },\r\n { immediate: true },\r\n);\r\n</script>\r\n\r\n<style lang=\"less\" scoped>\r\n.userdata-group {\r\n .userdata-add-row {\r\n display: flex;\r\n gap: 4px;\r\n margin-bottom: 10px;\r\n\r\n .ud-input {\r\n flex: 1;\r\n background: #1e2a36;\r\n border: 1px solid #3e5a6b;\r\n color: #ecf0f1;\r\n padding: 4px 6px;\r\n border-radius: 4px;\r\n font-size: 12px;\r\n min-width: 0;\r\n\r\n &::placeholder {\r\n color: #5a7a8a;\r\n }\r\n }\r\n\r\n .ud-textarea {\r\n resize: none;\r\n min-height: 28px;\r\n max-height: 28px;\r\n line-height: 1.4;\r\n font-family: inherit;\r\n }\r\n\r\n .ud-btn {\r\n flex: 0 0 28px;\r\n height: 28px;\r\n border: none;\r\n border-radius: 4px;\r\n cursor: pointer;\r\n font-size: 14px;\r\n line-height: 1;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transition: background 0.2s;\r\n\r\n &.add-btn {\r\n background: #27ae60;\r\n color: #fff;\r\n &:hover { background: #2ecc71; }\r\n }\r\n }\r\n }\r\n\r\n .userdata-list {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 4px;\r\n\r\n .userdata-item {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n padding: 3px 4px;\r\n background: #1a2a36;\r\n border-radius: 4px;\r\n border: 1px solid transparent;\r\n\r\n &.readonly {\r\n background: #1a1f2a;\r\n border-color: #3e5a6b;\r\n }\r\n\r\n .ud-key {\r\n flex: 0 0 auto;\r\n min-width: 60px;\r\n max-width: 90px;\r\n font-size: 11px;\r\n color: #f1c40f;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n }\r\n\r\n .ud-value-input {\r\n flex: 1;\r\n min-width: 0;\r\n background: #1e2a36;\r\n border: 1px solid #3e5a6b;\r\n color: #ecf0f1;\r\n padding: 2px 4px;\r\n border-radius: 3px;\r\n font-size: 12px;\r\n }\r\n\r\n .ud-value-readonly {\r\n flex: 1;\r\n font-size: 11px;\r\n color: #95a5a6;\r\n padding: 2px 4px;\r\n cursor: not-allowed;\r\n }\r\n\r\n .ud-value-json-preview {\r\n flex: 1;\r\n min-width: 0;\r\n font-size: 11px;\r\n color: #bdc3c7;\r\n padding: 2px 4px;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n font-family: \"Courier New\", Courier, monospace;\r\n }\r\n\r\n &.editing-json {\r\n flex-direction: column;\r\n align-items: stretch;\r\n gap: 4px;\r\n padding: 6px;\r\n }\r\n\r\n .ud-json-error {\r\n font-size: 10px;\r\n color: #e6b32a;\r\n padding: 2px 4px;\r\n line-height: 1.4;\r\n word-break: break-all;\r\n }\r\n\r\n .ud-json-textarea {\r\n width: 100%;\r\n min-height: 50px;\r\n background: #1e2a36;\r\n border: 1px solid #3e5a6b;\r\n color: #ecf0f1;\r\n padding: 4px 6px;\r\n border-radius: 4px;\r\n font-size: 11px;\r\n font-family: \"Courier New\", Courier, monospace;\r\n resize: vertical;\r\n box-sizing: border-box;\r\n\r\n &:focus {\r\n outline: none;\r\n border-color: #f1c40f;\r\n }\r\n\r\n &.has-error {\r\n border-color: #e6b32a;\r\n }\r\n }\r\n\r\n .ud-json-actions {\r\n display: flex;\r\n gap: 4px;\r\n justify-content: flex-end;\r\n }\r\n\r\n .ud-btn {\r\n flex: 0 0 22px;\r\n height: 22px;\r\n border: none;\r\n border-radius: 3px;\r\n cursor: pointer;\r\n font-size: 11px;\r\n line-height: 1;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transition: background 0.2s;\r\n\r\n &.del-btn {\r\n background: #c0392b;\r\n color: #fff;\r\n &:hover { background: #e74c3c; }\r\n }\r\n\r\n &.apply-btn {\r\n background: #27ae60;\r\n color: #fff;\r\n &:hover { background: #2ecc71; }\r\n }\r\n\r\n &.cancel-btn {\r\n background: #7f8c8d;\r\n color: #fff;\r\n &:hover { background: #95a5a6; }\r\n }\r\n\r\n &.edit-json-btn {\r\n flex: 0 0 22px;\r\n height: 22px;\r\n background: #2980b9;\r\n color: #fff;\r\n &:hover { background: #3498db; }\r\n }\r\n }\r\n }\r\n }\r\n\r\n .userdata-empty {\r\n font-size: 12px;\r\n color: #5a7a8a;\r\n text-align: center;\r\n padding: 8px 0;\r\n font-style: italic;\r\n }\r\n}\r\n</style>","/**\r\n * 树形展开状态管理的组合式函数\r\n * 提供展开集合的响应式管理、切换展开、展开路径(自动展开父级)等功能\r\n * 用于 PropertyPanel 和 TreeItem 组件之间共享展开状态\r\n */\r\n\r\nimport { ref, watch, type Ref } from \"vue\";\r\nimport type { Object3D } from \"three\";\r\n\r\n/**\r\n * @param selectedObject - 响应式的当前选中物体(Ref)\r\n * @returns 包含展开集合和切换方法的对象\r\n */\r\nexport function useTreeExpand(selectedObject: Ref<Object3D | null>) {\r\n /** 存储所有展开节点的 uuid 的 Set(响应式) */\r\n const expandedSet = ref<Set<string>>(new Set());\r\n\r\n /**\r\n * 切换某个节点的展开/收起状态\r\n * @param uuid - 节点的唯一标识符\r\n */\r\n const toggleExpand = (uuid: string) => {\r\n const newSet = new Set(expandedSet.value);\r\n if (newSet.has(uuid)) newSet.delete(uuid);\r\n else newSet.add(uuid);\r\n expandedSet.value = newSet;\r\n };\r\n\r\n /**\r\n * 展开从目标节点到根节点的所有父级节点(不展开目标节点自身)\r\n * 用于点击场景物体后自动展开树形路径\r\n * @param target - 目标物体\r\n */\r\n const expandPath = (target: Object3D) => {\r\n if (!target) return;\r\n const newSet = new Set(expandedSet.value);\r\n let current = target.parent;\r\n // 逐级向上遍历,直到遇到场景根节点\r\n while (current && current.type !== \"Scene\") {\r\n newSet.add(current.uuid);\r\n current = current.parent;\r\n }\r\n expandedSet.value = newSet;\r\n };\r\n\r\n // 监听选中物体的变化,当选中新物体时自动展开其路径\r\n watch(\r\n selectedObject,\r\n (obj) => {\r\n if (obj) expandPath(obj);\r\n },\r\n { immediate: true },\r\n );\r\n\r\n return { expandedSet, toggleExpand };\r\n}\r\n","<template>\r\n <div class=\"property-panel\" v-if=\"transform\">\r\n <!-- 场景物体树 -->\r\n <div class=\"property-group tree-group\">\r\n <label>场景物体</label>\r\n <div class=\"tree-container\">\r\n <TreeItem\r\n v-for=\"obj in treeData\"\r\n :key=\"obj.uuid\"\r\n :node=\"obj\"\r\n :selected-object=\"selectedObject\"\r\n :version=\"treeVersion\"\r\n @select=\"emit('treeSelect', $event)\"\r\n @delete=\"handleTreeDelete\"\r\n />\r\n <div v-if=\"treeData.length === 0\" class=\"tree-empty\">暂无物体</div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"property-group\">\r\n <label>全局属性</label>\r\n <div class=\"transform-mode-row\">\r\n <button\r\n class=\"mode-btn\"\r\n :class=\"{ active: transformMode === 'translate' }\"\r\n title=\"移动 (W)\"\r\n @click=\"setMode('translate')\"\r\n >\r\n ↕ 移动\r\n </button>\r\n <button\r\n class=\"mode-btn\"\r\n :class=\"{ active: transformMode === 'rotate' }\"\r\n title=\"旋转 (E)\"\r\n @click=\"setMode('rotate')\"\r\n >\r\n ↻ 旋转\r\n </button>\r\n <button\r\n class=\"mode-btn\"\r\n :class=\"{ active: transformMode === 'scale' }\"\r\n title=\"缩放 (R)\"\r\n @click=\"setMode('scale')\"\r\n >\r\n ⤡ 缩放\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- Tab 切换 -->\r\n <div class=\"tabs\" v-if=\"selectedObject\">\r\n <button\r\n class=\"tab-btn\"\r\n :class=\"{ active: activeTab === 'transform' }\"\r\n @click=\"activeTab = 'transform'\"\r\n >\r\n 🔄 变换\r\n </button>\r\n <button\r\n class=\"tab-btn\"\r\n :class=\"{ active: activeTab === 'userdata' }\"\r\n @click=\"activeTab = 'userdata'\"\r\n >\r\n 📋 自定义数据\r\n </button>\r\n </div>\r\n\r\n <!-- Tab 内容 -->\r\n <div class=\"tab-content\" v-if=\"selectedObject\">\r\n <TransformTab\r\n v-show=\"activeTab === 'transform'\"\r\n :transform=\"transform\"\r\n :selected-object=\"selectedObject\"\r\n @property-change=\"emitChange\"\r\n />\r\n <UserDataTab\r\n v-show=\"activeTab === 'userdata'\"\r\n :selected-object=\"selectedObject\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"property-panel empty\" v-else>\r\n <p>未选中任何模型</p>\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\n/**\r\n * 属性面板组件(主文件)\r\n * 负责:场景物体树、全局变换模式、Tab 导航\r\n * 子组件:TransformTab(变换/材质/光源)、UserDataTab(自定义数据)\r\n */\r\nimport type { Object3D } from \"three\";\r\nimport TreeItem from \"../TreeItem.vue\";\r\nimport TransformTab from \"./TransformTab.vue\";\r\nimport UserDataTab from \"./UserDataTab.vue\";\r\nimport { ref, provide, toRef } from \"vue\";\r\nimport { useTreeExpand } from \"../../composables/useTreeExpand\";\r\n\r\nconst props = defineProps<{\r\n transform: {\r\n position: { x: number; y: number; z: number };\r\n rotation: { x: number; y: number; z: number };\r\n scale: { x: number; y: number; z: number };\r\n } | null;\r\n treeData: Object3D[];\r\n selectedObject: Object3D | null;\r\n}>();\r\n\r\nconst emit = defineEmits<{\r\n (e: \"propertyChange\"): void;\r\n (e: \"treeSelect\", obj: Object3D): void;\r\n (e: \"treeDelete\", obj: Object3D): void;\r\n (e: \"transformModeChange\", mode: \"translate\" | \"rotate\" | \"scale\"): void;\r\n}>();\r\n\r\n// ─── 变换模式 ───\r\nconst transformMode = ref<\"translate\" | \"rotate\" | \"scale\">(\"translate\");\r\n\r\nfunction setMode(mode: \"translate\" | \"rotate\" | \"scale\") {\r\n transformMode.value = mode;\r\n emit(\"transformModeChange\", mode);\r\n}\r\n\r\nconst emitChange = () => emit(\"propertyChange\");\r\n\r\n// ─── Tab 状态 ───\r\nconst activeTab = ref<\"transform\" | \"userdata\">(\"transform\");\r\n\r\n// ─── 树形组件 ───\r\nconst treeVersion = ref(0);\r\n\r\nconst selectedObjectRef = toRef(props, \"selectedObject\");\r\nconst { expandedSet, toggleExpand } = useTreeExpand(selectedObjectRef);\r\n\r\nprovide(\"treeExpand\", { expandedSet, toggleExpand });\r\n\r\nconst handleTreeDelete = (obj: Object3D) => {\r\n treeVersion.value++;\r\n emit(\"treeDelete\", obj);\r\n};\r\n</script>\r\n\r\n<style lang=\"less\" scoped>\r\n.property-panel {\r\n width: 320px;\r\n height: 100%;\r\n background: #2c3e50;\r\n color: #ecf0f1;\r\n padding: 16px;\r\n box-sizing: border-box;\r\n border-left: 1px solid #1a2a36;\r\n overflow-y: auto;\r\n font-size: 14px;\r\n\r\n h3 {\r\n margin-top: 0;\r\n text-align: center;\r\n }\r\n\r\n .property-group {\r\n margin-bottom: 20px;\r\n border-bottom: 1px solid #1a2a36;\r\n padding-bottom: 12px;\r\n\r\n label {\r\n font-weight: bold;\r\n display: block;\r\n margin-bottom: 8px;\r\n color: #f1c40f;\r\n }\r\n }\r\n}\r\n\r\n.empty {\r\n text-align: center;\r\n color: #95a5a6;\r\n}\r\n\r\n// ─── 场景物体树 ───\r\n.tree-group {\r\n .tree-container {\r\n height: 200px;\r\n overflow-y: auto;\r\n background: #1a2a36;\r\n border-radius: 4px;\r\n padding: 4px 0;\r\n }\r\n}\r\n\r\n.tree-empty {\r\n padding: 8px 10px;\r\n color: #95a5a6;\r\n font-style: italic;\r\n}\r\n\r\n// ─── Tabs ───\r\n.tabs {\r\n display: flex;\r\n gap: 0;\r\n border-bottom: 2px solid #1a2a36;\r\n margin-bottom: 16px;\r\n\r\n .tab-btn {\r\n flex: 1;\r\n padding: 8px 12px;\r\n background: transparent;\r\n border: none;\r\n color: #95a5a6;\r\n font-size: 13px;\r\n cursor: pointer;\r\n transition:\r\n color 0.2s,\r\n border-bottom 0.2s;\r\n border-bottom: 2px solid transparent;\r\n margin-bottom: -2px;\r\n\r\n &:hover {\r\n color: #ecf0f1;\r\n }\r\n\r\n &.active {\r\n color: #f1c40f;\r\n border-bottom-color: #f1c40f;\r\n }\r\n }\r\n}\r\n\r\n// ─── Tab 内容容器 ───\r\n.tab-content {\r\n height: calc(100% - 430px);\r\n overflow-y: auto;\r\n overflow-x: hidden;\r\n}\r\n\r\n// ─── 变换模式按钮 ───\r\n.transform-mode-row {\r\n display: flex;\r\n gap: 4px;\r\n\r\n .mode-btn {\r\n flex: 1;\r\n padding: 6px 8px;\r\n background: #1e2a36;\r\n border: 1px solid #3e5a6b;\r\n color: #95a5a6;\r\n font-size: 12px;\r\n border-radius: 4px;\r\n cursor: pointer;\r\n transition:\r\n background 0.2s,\r\n color 0.2s,\r\n border-color 0.2s;\r\n\r\n &:hover {\r\n background: #2c3e50;\r\n color: #ecf0f1;\r\n }\r\n\r\n &.active {\r\n background: #3e5a6b;\r\n color: #f1c40f;\r\n border-color: #f1c40f;\r\n }\r\n }\r\n}\r\n\r\n// 滚动条样式\r\n.property-panel,\r\n.tree-container {\r\n &::-webkit-scrollbar { /* ... */ }\r\n scrollbar-width: thin;\r\n scrollbar-color: rgba(255, 255, 255, 0.25) transparent;\r\n}\r\n</style>","<template>\r\n <div class=\"top-bar\">\r\n <div class=\"left-section\">\r\n <!-- 文件菜单 -->\r\n <div\r\n class=\"dropdown-wrapper\"\r\n @mouseenter=\"showFileMenu = true\"\r\n @mouseleave=\"showFileMenu = false\"\r\n >\r\n <button class=\"menu-btn\">文件</button>\r\n <div class=\"dropdown-menu\" v-show=\"showFileMenu\">\r\n <div class=\"menu-item\" @click=\"handleNew\">新建</div>\r\n <div\r\n class=\"menu-item dropdown-wrapper sub-trigger\"\r\n @mouseenter=\"showOpenSub = true\"\r\n @mouseleave=\"showOpenSub = false\"\r\n >\r\n <span>打开</span>\r\n <div class=\"dropdown-menu sub-menu\" v-show=\"showOpenSub\">\r\n <div class=\"menu-item\" @click=\"handleOpenProject\">打开项目</div>\r\n <div class=\"menu-item\" @click=\"handleOpenModel\">打开模型</div>\r\n <div class=\"menu-item\" @click=\"handleOpenScene\">打开场景</div>\r\n </div>\r\n </div>\r\n <div class=\"menu-item\" @click=\"handleSave\">保存</div>\r\n <div class=\"menu-item\" @click=\"handleExport\">导出</div>\r\n </div>\r\n </div>\r\n\r\n <!-- 添加菜单 -->\r\n <div\r\n class=\"dropdown-wrapper\"\r\n @mouseenter=\"showAddMenu = true\"\r\n @mouseleave=\"showAddMenu = false\"\r\n >\r\n <button class=\"menu-btn\">添加</button>\r\n <div class=\"dropdown-menu\" v-show=\"showAddMenu\">\r\n <div class=\"menu-item\" @click=\"handleUndo\">组</div>\r\n <div\r\n class=\"menu-item dropdown-wrapper sub-trigger\"\r\n @mouseenter=\"showOpenGrid = true\"\r\n @mouseleave=\"showOpenGrid = false\"\r\n >\r\n <span>网格</span>\r\n <div class=\"dropdown-menu sub-menu\" v-show=\"showOpenGrid\">\r\n <div class=\"menu-item\" @click=\"emit('addModel', 'box')\">\r\n 正方体\r\n </div>\r\n <div class=\"menu-item\" @click=\"emit('addModel', 'sphere')\">\r\n 球体\r\n </div>\r\n <div class=\"menu-item\" @click=\"emit('addModel', 'waterPlane')\">\r\n 水面\r\n </div>\r\n <div class=\"menu-item\" @click=\"triggerImport\">导入</div>\r\n </div>\r\n </div>\r\n <div\r\n class=\"menu-item dropdown-wrapper sub-trigger\"\r\n @mouseenter=\"showLightSub = true\"\r\n @mouseleave=\"showLightSub = false\"\r\n >\r\n <span>光源</span>\r\n <div class=\"dropdown-menu sub-menu\" v-show=\"showLightSub\">\r\n <div\r\n class=\"menu-item\"\r\n @click=\"emit('addModel', 'directionalLight')\"\r\n >\r\n 平行光\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"menu-item\" @click=\"handleDelete\">摄像机</div>\r\n </div>\r\n </div>\r\n\r\n <!-- 编辑菜单 -->\r\n <div\r\n class=\"dropdown-wrapper\"\r\n @mouseenter=\"showEditMenu = true\"\r\n @mouseleave=\"showEditMenu = false\"\r\n >\r\n <button class=\"menu-btn\">编辑</button>\r\n <div class=\"dropdown-menu\" v-show=\"showEditMenu\">\r\n <div class=\"menu-item\" @click=\"handleUndo\">撤销</div>\r\n <div class=\"menu-item\" @click=\"handleRedo\">重做</div>\r\n <div class=\"menu-item\" @click=\"handleDuplicate\">复制</div>\r\n <div class=\"menu-item\" @click=\"handleDelete\">删除</div>\r\n </div>\r\n </div>\r\n\r\n <!-- 视图菜单 -->\r\n <div\r\n class=\"dropdown-wrapper\"\r\n @mouseenter=\"showViewMenu = true\"\r\n @mouseleave=\"showViewMenu = false\"\r\n >\r\n <button class=\"menu-btn\">视图</button>\r\n <div class=\"dropdown-menu\" v-show=\"showViewMenu\">\r\n <div class=\"menu-item\" @click=\"handleResetCamera\">重置相机</div>\r\n <div class=\"menu-item\" @click=\"handleToggleGrid\">显示网格</div>\r\n </div>\r\n </div>\r\n\r\n <!-- 帮助菜单 -->\r\n <div\r\n class=\"dropdown-wrapper\"\r\n @mouseenter=\"showHelpMenu = true\"\r\n @mouseleave=\"showHelpMenu = false\"\r\n >\r\n <button class=\"menu-btn\">帮助</button>\r\n <div class=\"dropdown-menu\" v-show=\"showHelpMenu\">\r\n <div class=\"menu-item\" @click=\"handleHelp\">使用帮助</div>\r\n <div class=\"menu-item\" @click=\"handleAbout\">关于</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"right-section\">\r\n <span class=\"app-title\">3D 模型编辑器</span>\r\n </div>\r\n\r\n <!-- 隐藏的文件输入框,用于导入模型 -->\r\n <input\r\n type=\"file\"\r\n ref=\"fileInput\"\r\n accept=\".obj,.gltf,.glb\"\r\n style=\"display: none\"\r\n @change=\"onFileSelected\"\r\n />\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\n/**\r\n * 顶部菜单栏组件\r\n * 包含文件、添加、编辑、视图、帮助等下拉菜单\r\n * 通过 emit 向父组件传递添加模型和导入模型事件\r\n */\r\n\r\nimport { ref } from \"vue\";\r\n\r\n// 各菜单显示状态\r\nconst showFileMenu = ref(false);\r\nconst showEditMenu = ref(false);\r\nconst showViewMenu = ref(false);\r\nconst showHelpMenu = ref(false);\r\nconst showAddMenu = ref(false);\r\nconst showOpenSub = ref(false); // 文件→打开子菜单\r\nconst showOpenGrid = ref(false); // 添加→网格子菜单\r\nconst showLightSub = ref(false); // 添加→光源子菜单\r\n\r\nconst emit = defineEmits<{\r\n (e: \"addModel\", type: string): void;\r\n (e: \"importModel\", file: File): void;\r\n}>();\r\n\r\n// ─── 文件输入 ───\r\nconst fileInput = ref<HTMLInputElement | null>(null);\r\n\r\n/** 触发文件选择对话框 */\r\nconst triggerImport = () => fileInput.value?.click();\r\n\r\n/** 文件选择后,向上传递文件对象,并重置 input 以便重复选择同一文件 */\r\nconst onFileSelected = (event: Event) => {\r\n const input = event.target as HTMLInputElement;\r\n if (input.files && input.files.length > 0) {\r\n emit(\"importModel\", input.files[0]);\r\n input.value = \"\";\r\n }\r\n};\r\n\r\n// ─── 各菜单项的占位处理(后续可扩展功能) ───\r\nconst handleNew = () => console.log(\"新建项目\");\r\nconst handleSave = () => console.log(\"保存场景\");\r\nconst handleExport = () => console.log(\"导出模型\");\r\nconst handleUndo = () => console.log(\"撤销\");\r\nconst handleRedo = () => console.log(\"重做\");\r\nconst handleDuplicate = () => console.log(\"复制物体\");\r\nconst handleDelete = () => console.log(\"删除物体\");\r\nconst handleResetCamera = () => console.log(\"重置相机\");\r\nconst handleToggleGrid = () => console.log(\"切换网格\");\r\nconst handleHelp = () => console.log(\"打开帮助\");\r\nconst handleAbout = () => console.log(\"关于编辑器\");\r\nconst handleOpenProject = () => console.log(\"打开项目\");\r\nconst handleOpenModel = () => console.log(\"打开模型\");\r\nconst handleOpenScene = () => console.log(\"打开场景\");\r\n</script>\r\n\r\n<style lang=\"less\" scoped>\r\n.top-bar {\r\n height: 40px;\r\n background: #1a2a36;\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 0 16px;\r\n border-bottom: 1px solid #2a4050;\r\n flex-shrink: 0;\r\n user-select: none;\r\n\r\n .left-section {\r\n display: flex;\r\n gap: 12px;\r\n align-items: center;\r\n\r\n .dropdown-wrapper {\r\n position: relative;\r\n display: inline-block;\r\n\r\n .menu-btn {\r\n background: transparent;\r\n border: none;\r\n color: #ecf0f1;\r\n padding: 6px 12px;\r\n border-radius: 4px;\r\n cursor: pointer;\r\n font-size: 14px;\r\n transition: background 0.2s;\r\n &:hover {\r\n background: #2a4050;\r\n }\r\n }\r\n\r\n .dropdown-menu {\r\n position: absolute;\r\n top: 100%;\r\n left: 0;\r\n background: #2c3e50;\r\n border: 1px solid #3e5a6b;\r\n border-radius: 4px;\r\n min-width: 140px;\r\n padding: 4px 0;\r\n z-index: 100;\r\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);\r\n\r\n .menu-item {\r\n padding: 6px 16px;\r\n color: #ecf0f1;\r\n cursor: pointer;\r\n font-size: 13px;\r\n transition: background 0.15s;\r\n white-space: nowrap;\r\n &:hover {\r\n background: #3e5a6b;\r\n }\r\n }\r\n .menu-item.sub-trigger {\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n position: relative;\r\n }\r\n }\r\n .sub-menu {\r\n position: absolute;\r\n left: 100%;\r\n top: 0;\r\n background: #2c3e50;\r\n border: 1px solid #3e5a6b;\r\n border-radius: 4px;\r\n min-width: 140px;\r\n padding: 4px 0;\r\n z-index: 101;\r\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);\r\n }\r\n }\r\n }\r\n\r\n .right-section {\r\n display: flex;\r\n align-items: center;\r\n }\r\n .app-title {\r\n color: #88aaff;\r\n font-size: 16px;\r\n font-weight: 500;\r\n letter-spacing: 0.5px;\r\n }\r\n}\r\n</style>\r\n","<template>\r\n <div class=\"bottom-bar\">\r\n <div class=\"status-left\">\r\n <span>就绪</span>\r\n </div>\r\n <div class=\"status-right\">\r\n <span>顶点: 0 | 面: 0</span>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\n/**\r\n * 底部状态栏\r\n * 目前仅显示“就绪”和占位统计信息\r\n * 未来可扩展显示顶点/面数、坐标等\r\n */\r\n</script>\r\n\r\n<style lang=\"less\" scoped>\r\n.bottom-bar {\r\n height: 40px;\r\n background: #1a2a36;\r\n border-top: 1px solid #2a4050;\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 0 16px;\r\n flex-shrink: 0;\r\n color: #95a5a6;\r\n font-size: 13px;\r\n user-select: none;\r\n .status-left,\r\n .status-right {\r\n display: flex;\r\n gap: 16px;\r\n }\r\n}\r\n</style>\r\n","<template>\r\n <div class=\"app-layout\">\r\n <!-- 顶部菜单栏 -->\r\n <TopBar\r\n @add-model=\"handleAddModel\"\r\n @import-model=\"handleImportModel\"\r\n v-if=\"mode === 'edit'\"\r\n />\r\n <div :class=\"`editor-container editor-container-mode-${mode}`\">\r\n <!-- Three.js 画布 -->\r\n <div :class=\"`canvas canvas-mode-${mode}`\" ref=\"containerRef\"></div>\r\n <!-- 属性面板 -->\r\n <PropertyPanel\r\n :transform=\"transform\"\r\n :tree-data=\"treeData\"\r\n :selected-object=\"selectedModel\"\r\n @property-change=\"handlePropertyChange\"\r\n @tree-select=\"handleTreeSelect\"\r\n @tree-delete=\"handleTreeDelete\"\r\n @transform-mode-change=\"handleTransformModeChange\"\r\n v-if=\"mode === 'edit'\"\r\n />\r\n </div>\r\n <!-- 底部状态栏 -->\r\n <BottomBar v-if=\"mode === 'edit'\" />\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\n/**\r\n * 编辑器主组件,负责:\r\n * - 挂载 Three.js 编辑器\r\n * - 管理选中物体的变换数据(位置/旋转/缩放)\r\n * - 同步场景物体树形数据\r\n * - 处理添加模型、导入模型、树形选中/删除等交互\r\n */\r\n\r\nimport { onBeforeUnmount, onMounted, reactive, ref, shallowRef } from \"vue\";\r\nimport {\r\n initEditor,\r\n setSelectedObjectCallback,\r\n setTransformChangeCallback,\r\n onSceneObjectsChangeCallback,\r\n getSceneObjects,\r\n removeModelById,\r\n selectObject,\r\n destroyEditor,\r\n setTransformMode,\r\n} from \"../three/index\";\r\nimport { addModelByType, importModelFromFile } from \"../three/addHandle\";\r\nimport PropertyPanel from \"./PropertyPanel/index.vue\";\r\nimport TopBar from \"./TopBar.vue\";\r\nimport BottomBar from \"./BottomBar.vue\";\r\nimport type { Object3D } from \"three\";\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n mode: string;\r\n sceneData: any;\r\n }>(),\r\n {\r\n mode: \"edit\",\r\n sceneData: null,\r\n },\r\n);\r\n\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n//#region 属性面板\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n\r\n/** 当前选中的模型对象 */\r\nconst selectedModel = ref<Object3D | null>(null);\r\n\r\n/**\r\n * 变换数据(位置/旋转/缩放),与属性面板双向绑定\r\n * 使用 reactive 使每个属性独立响应式\r\n */\r\nconst transform = reactive({\r\n position: { x: 0, y: 0, z: 0 },\r\n rotation: { x: 0, y: 0, z: 0 },\r\n scale: { x: 1, y: 1, z: 1 },\r\n});\r\n\r\n// ─── 同步函数 ───\r\n\r\n/**\r\n * 从 Three.js 物体同步变换数据到 transform 对象\r\n * 保留三位小数,避免浮点数误差\r\n */\r\nconst syncTransformFromObject = (obj: Object3D) => {\r\n transform.position.x = Number(obj.position.x.toFixed(3));\r\n transform.position.y = Number(obj.position.y.toFixed(3));\r\n transform.position.z = Number(obj.position.z.toFixed(3));\r\n transform.rotation.x = Number(obj.rotation.x.toFixed(3));\r\n transform.rotation.y = Number(obj.rotation.y.toFixed(3));\r\n transform.rotation.z = Number(obj.rotation.z.toFixed(3));\r\n transform.scale.x = Number(obj.scale.x.toFixed(3));\r\n transform.scale.y = Number(obj.scale.y.toFixed(3));\r\n transform.scale.z = Number(obj.scale.z.toFixed(3));\r\n};\r\n\r\n/**\r\n * 将 transform 数据应用到 Three.js 物体\r\n * 用于属性面板输入变化时更新物体\r\n */\r\nconst applyTransformToObject = (obj: Object3D) => {\r\n obj.position.set(\r\n transform.position.x,\r\n transform.position.y,\r\n transform.position.z,\r\n );\r\n obj.rotation.set(\r\n transform.rotation.x,\r\n transform.rotation.y,\r\n transform.rotation.z,\r\n );\r\n obj.scale.set(transform.scale.x, transform.scale.y, transform.scale.z);\r\n};\r\n\r\n// ─── 注册回调 ───\r\n\r\n// 选中物体变化时同步到本地状态\r\nsetSelectedObjectCallback((obj) => {\r\n selectedModel.value = obj;\r\n if (obj) syncTransformFromObject(obj);\r\n});\r\n\r\n// 变换过程中(拖拽)实时更新面板\r\nsetTransformChangeCallback((obj) => {\r\n syncTransformFromObject(obj);\r\n});\r\n\r\n// ─── 事件处理 ───\r\n\r\n/** 属性面板数值变化时,应用变换到物体 */\r\nconst handlePropertyChange = () => {\r\n if (selectedModel.value) {\r\n applyTransformToObject(selectedModel.value);\r\n\r\n // ⭐ 如果是光源,手动刷新 Helper\r\n if (selectedModel.value.type === \"DirectionalLight\") {\r\n const helper = selectedModel.value.userData.helper;\r\n if (helper && helper.update) helper.update();\r\n }\r\n }\r\n};\r\n\r\n/** 添加模型(来自顶部菜单) */\r\nconst handleAddModel = (type: string) => addModelByType(type);\r\n\r\n/** 导入模型(来自顶部菜单) */\r\nconst handleImportModel = async (file: File) => {\r\n try {\r\n await importModelFromFile(file);\r\n } catch (error) {\r\n console.error(\"导入失败:\", error);\r\n alert(\"导入失败:\" + (error as Error).message);\r\n }\r\n};\r\n//#endregion\r\n\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n//#region 树形面板\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n\r\n/** 树形数据使用 shallowRef 避免深度响应式,提高性能 */\r\nconst treeData = shallowRef<Object3D[]>([]);\r\n\r\n// 注册树形数据变化回调\r\nonSceneObjectsChangeCallback((objects) => {\r\n treeData.value = objects;\r\n});\r\n\r\n/** 初始化树形数据 */\r\nconst initTree = () => {\r\n const objects = getSceneObjects();\r\n if (objects) treeData.value = objects;\r\n};\r\n\r\n/** 树形选中节点 → 同步选中场景物体 */\r\nconst handleTreeSelect = (obj: Object3D) => selectObject(obj);\r\n\r\n/** 树形删除节点 → 删除场景物体 */\r\nconst handleTreeDelete = (obj: Object3D) => removeModelById(obj.uuid);\r\n\r\n/** 变换模式切换 → 设置 TransformControls 模式 */\r\nconst handleTransformModeChange = (mode: \"translate\" | \"rotate\" | \"scale\") => {\r\n setTransformMode(mode);\r\n};\r\n//#endregion\r\n\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n//#region 初始化\r\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n\r\nconst containerRef = ref<HTMLElement | null>(null);\r\n/** 挂载 Three.js 编辑器并初始化树 */\r\nconst init = () => {\r\n if (containerRef.value)\r\n initEditor(containerRef.value, props.mode, props.sceneData);\r\n // const dom = document.getElementById(\"sl_canvas\");\r\n // if (dom) initEditor(dom);\r\n initTree();\r\n};\r\n\r\nonMounted(init);\r\n\r\nonBeforeUnmount(() => {\r\n console.log(\"endset_three_editor destroy\");\r\n destroyEditor();\r\n});\r\n//#endregion\r\n</script>\r\n\r\n<style lang=\"less\" scoped>\r\n/* 整体布局:纵向排列,编辑器区域占剩余高度 */\r\n.app-layout {\r\n display: flex;\r\n flex-direction: column;\r\n height: 100%;\r\n width: 100%;\r\n background-color: #333;\r\n}\r\n.editor-container {\r\n display: flex;\r\n width: 100%;\r\n}\r\n.editor-container-mode-edit {\r\n height: calc(100% - 80px); /* 顶部栏 40px + 底部栏 40px */\r\n}\r\n.editor-container-mode-run {\r\n height: 100%; /* 顶部栏 40px + 底部栏 40px */\r\n}\r\n.canvas {\r\n height: 100%;\r\n background-color: transparent;\r\n position: relative;\r\n}\r\n.canvas-mode-edit {\r\n width: calc(100% - 320px); /* 属性面板宽 320px */\r\n}\r\n.canvas-mode-run {\r\n width: 100%; /* 属性面板宽 320px */\r\n}\r\n</style>\r\n"],"names":["_changeEvent","_startEvent","_endEvent","_ray","Ray","_plane","Plane","_TILT_LIMIT","MathUtils","_v","Vector3","_twoPI","_STATE","_EPS","OrbitControls","Controls","object","domElement","MOUSE","TOUCH","Quaternion","Spherical","Vector2","onPointerMove","onPointerDown","onPointerUp","onContextMenu","onMouseWheel","onKeyDown","onTouchStart","onTouchMove","onMouseDown","onMouseMove","interceptControlDown","interceptControlUp","type","element","deltaX","deltaY","dollyScale","angle","deltaTime","position","min","max","zoomChanged","prevRadius","newRadius","radiusDelta","mouseBefore","prevZoom","mouseAfter","delta","normalizedDelta","distance","objectMatrix","targetDistance","x","y","rect","dx","dy","w","h","dist","event","needsUpdate","centerX","centerY","i","pointerId","mode","newEvent","mouseAction","_raycaster","Raycaster","_tempVector","_tempVector2","_tempQuaternion","_unit","_mouseDownEvent","_mouseUpEvent","_objectChangeEvent","TransformControls","camera","root","TransformControlsRoot","gizmo","TransformControlsGizmo","plane","TransformControlsPlane","scope","defineProperty","propName","defaultValue","propValue","value","worldPosition","worldPositionStart","worldQuaternion","worldQuaternionStart","cameraPosition","cameraQuaternion","pointStart","pointEnd","rotationAxis","rotationAngle","eye","getPointer","onPointerHover","pointer","intersect","intersectObjectWithRay","planeIntersect","axis","space","d","ROTATION_SPEED","_inPlaneRotation","translationSnap","rotationSnap","scaleSnap","size","xAxis","yAxis","zAxis","active","materialLib","raycaster","includeInvisible","allIntersections","_tempEuler","Euler","_alignVector","_zeroVector","_lookAtMatrix","Matrix4","_tempQuaternion2","_identityQuaternion","_dirVector","_tempMatrix","_unitX","_unitY","_unitZ","_v1","_v2","_v3","Object3D","controls","force","child","gizmoMaterial","MeshBasicMaterial","gizmoLineMaterial","LineBasicMaterial","matInvisible","matHelper","matRed","matGreen","matBlue","matRedTransparent","matGreenTransparent","matBlueTransparent","matWhiteTransparent","matYellowTransparent","matYellow","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","rotation","scale","tag","tempGeometry","quaternion","handles","handle","factor","a","PlaneGeometry","DoubleSide","state","orbitChanged","skipNextClick","onSelectedChange","onTransformChange","onSceneObjectsChange","sceneObjects","cameraTarget","animationId","clickHandler","resizeHandler","initEditor","container","sceneData","initRenderer","initScene","initCamera","loadSceneFromJSON","camData","initTransformControls","initOrbitControls","refreshSceneObjects","animate","onMouseClick","onResize","addDefaultLightAndCube","initGrid","renderer","THREE","grid","aspect","selected","helper","ambient","TWEEN","_a","_b","mesh","mat","speed","width","height","selectObject","obj","setTransformMode","deselectObject","mouse","clickables","intersects","getIntersectsObject","firstObject","parent","focusOnObject","objectId","duration","targetPos","direction","newCamPos","startPos","startTarget","addModel","model","addObjectToTree","notifyChange","removeModel","removeObjectFromTree","removeModelById","uuid","idx","list","setSelectedObjectCallback","cb","setTransformChangeCallback","onSceneObjectsChangeCallback","getSceneObjects","getScene","getCamera","getRenderer","exportSceneToJSON","scene","lightHelpers","lightHelperMap","exportScene","sceneJson","light","cameraJson","_c","json","data","loaded","disposeObject","children","destroyEditor","_object_pattern","_material_library_pattern","_material_use_pattern","_map_use_pattern","_face_vertex_data_separator_pattern","_vA","_vB","_vC","_ab","_cb","_color","Color","ParserState","fromDeclaration","previousMaterial","libraries","previous","material","index","cloned","end","lastMultiMaterial","mi","declared","len","b","c","src","dst","ua","ub","uc","na","nb","nc","vLen","ia","ib","ic","nLen","uvLen","vertices","vi","l","uvs","uvi","OBJLoader","Loader","manager","url","onLoad","onProgress","onError","loader","FileLoader","text","e","materials","lines","result","line","lineFirstChar","SRGBColorSpace","vertexData","faceVertices","j","jl","vertex","vertexParts","v1","v2","v3","lineParts","lineVertices","lineUVs","li","llen","parts","pointData","Group","isLine","isPoints","hasVertexColors","buffergeometry","createdMaterials","miLen","sourceMaterial","materialHash","materialLine","Material","PointsMaterial","materialPoints","MeshPhongMaterial","LineSegments","Points","points","toTrianglesDrawMode","drawMode","TrianglesDrawMode","TriangleFanDrawMode","TriangleStripDrawMode","indices","numberOfTriangles","newIndices","newGeometry","clone","source","sourceLookup","cloneLookup","parallelTraverse","sourceNode","clonedNode","node","clonedMesh","sourceMesh","sourceBones","bone","callback","GLTFLoader","parser","GLTFMaterialsClearcoatExtension","GLTFMaterialsDispersionExtension","GLTFTextureBasisUExtension","GLTFTextureWebPExtension","GLTFTextureAVIFExtension","GLTFMaterialsSheenExtension","GLTFMaterialsTransmissionExtension","GLTFMaterialsVolumeExtension","GLTFMaterialsIorExtension","GLTFMaterialsEmissiveStrengthExtension","GLTFMaterialsSpecularExtension","GLTFMaterialsIridescenceExtension","GLTFMaterialsAnisotropyExtension","GLTFMaterialsBumpExtension","GLTFLightsExtension","GLTFMeshoptCompression","EXTENSIONS","GLTFMeshGpuInstancing","resourcePath","relativeUrl","LoaderUtils","_onError","gltf","dracoLoader","ktx2Loader","meshoptDecoder","path","extensions","plugins","textDecoder","BINARY_EXTENSION_HEADER_MAGIC","GLTFBinaryExtension","error","GLTFParser","plugin","extensionName","extensionsRequired","GLTFMaterialsUnlitExtension","GLTFDracoMeshCompressionExtension","GLTFTextureTransformExtension","GLTFMeshQuantizationExtension","resolve","reject","GLTFRegistry","objects","key","getMaterialExtension","materialIndex","materialDef","nodeDefs","nodeIndex","nodeLength","nodeDef","lightIndex","cacheKey","dependency","lightDef","lightNode","color","LinearSRGBColorSpace","range","DirectionalLight","PointLight","SpotLight","assignExtrasToUserData","self","materialParams","pending","metallicRoughness","array","extension","MeshPhysicalMaterial","colorFactor","colorArray","textureIndex","textureDef","handler","bufferView","extensionDef","buffer","decoder","res","byteOffset","byteLength","count","stride","meshDef","primitive","WEBGL_CONSTANTS","attributesDef","attributes","accessor","results","nodeObject","meshes","instancedMeshes","m","p","q","s","instancedMesh","InstancedMesh","attributeName","attr","InstancedBufferAttribute","BINARY_EXTENSION_HEADER_LENGTH","BINARY_EXTENSION_CHUNK_TYPES","headerView","chunkContentsLength","chunkView","chunkIndex","chunkLength","chunkType","contentArray","bufferViewIndex","gltfAttributeMap","threeAttributeMap","attributeNormalizedMap","attributeTypeMap","threeAttributeName","ATTRIBUTES","accessorDef","componentType","WEBGL_COMPONENT_TYPES","attribute","normalized","texture","transform","GLTFCubicSplineInterpolant","Interpolant","parameterPositions","sampleValues","sampleSize","resultBuffer","values","valueSize","offset","i1","t0","t","t1","stride2","stride3","td","pp","ppp","offset1","offset0","s2","s3","s0","s1","p0","m0","p1","m1","_quaternion","GLTFCubicSplineQuaternionInterpolant","WEBGL_FILTERS","NearestFilter","LinearFilter","NearestMipmapNearestFilter","LinearMipmapNearestFilter","NearestMipmapLinearFilter","LinearMipmapLinearFilter","WEBGL_WRAPPINGS","ClampToEdgeWrapping","MirroredRepeatWrapping","RepeatWrapping","WEBGL_TYPE_SIZES","PATH_PROPERTIES","INTERPOLATION","InterpolateLinear","InterpolateDiscrete","ALPHA_MODES","createDefaultMaterial","cache","MeshStandardMaterial","FrontSide","addUnknownExtensionsToUserData","knownExtensions","objectDef","gltfDef","addMorphTargets","targets","hasMorphPosition","hasMorphNormal","hasMorphColor","il","target","pendingPositionAccessors","pendingNormalAccessors","pendingColorAccessors","pendingAccessor","accessors","morphPositions","morphNormals","morphColors","updateMorphTargets","targetNames","createPrimitiveKey","primitiveDef","geometryKey","dracoExtension","createAttributesKey","attributesKey","keys","getNormalizedComponentScale","constructor","getImageURIMimeType","uri","_identityMatrix","options","isSafari","safariVersion","isFirefox","firefoxVersion","userAgent","safariMatch","TextureLoader","ImageBitmapLoader","ext","dependencies","skinDefs","meshDefs","skinIndex","skinLength","joints","ref","updateMappings","original","mappings","func","defs","def","bufferIndex","bufferDef","bufferViewDef","accessorIndex","itemSize","TypedArray","BufferAttribute","pendingBufferViews","bufferViews","elementBytes","itemBytes","byteStride","bufferAttribute","ibSlice","ibCacheKey","InterleavedBuffer","InterleavedBufferAttribute","itemSizeIndices","TypedArrayIndices","byteOffsetIndices","byteOffsetValues","sparseIndices","sparseValues","sourceIndex","sourceDef","promise","sampler","URL","sourceURI","isObjectURL","blob","imageBitmap","Texture","mapName","mapDef","colorSpace","gltfReference","useDerivativeTangents","useVertexColors","useFlatShading","pointsMaterial","lineMaterial","cachedMaterial","materialType","materialExtensions","kmuExtension","alphaMode","emissiveFactor","originalName","sanitizedName","PropertyBinding","primitives","createDracoPrimitive","addPrimitiveAttributes","cached","geometryPromise","meshIndex","geometries","SkinnedMesh","LineLoop","group","cameraIndex","cameraDef","params","PerspectiveCamera","OrthographicCamera","skinDef","inverseBindMatrices","jointNodes","bones","boneInverses","jointNode","Skeleton","animationIndex","animationDef","animationName","pendingNodes","pendingInputAccessors","pendingOutputAccessors","pendingSamplers","pendingTargets","channel","input","output","nodes","inputAccessors","outputAccessors","samplers","tracks","inputAccessor","outputAccessor","createdTracks","k","animation","AnimationClip","o","nodePending","childPending","childrenDef","skeletonPending","skeleton","pivot","pivotChild","nodeName","meshPromise","Bone","matrix","mapping","sceneIndex","sceneDef","nodeIds","reduceAssociations","reducedAssociations","targetName","collectMorphTargets","TypedKeyframeTrack","NumberKeyframeTrack","QuaternionKeyframeTrack","VectorKeyframeTrack","interpolation","outputArray","track","scaled","interpolantType","computeBounds","box","Box3","boxScale","maxDisplacement","vector","sphere","Sphere","assignAttributeAccessor","gltfAttributeName","ColorManagement","_taskCache","DRACOLoader","config","workerLimit","attributeIDs","attributeTypes","vertexColorSpace","taskConfig","taskKey","cachedTask","worker","taskID","taskCost","geometryPending","_worker","message","geometryData","inputColorSpace","responseType","useJS","librariesPending","jsContent","fn","DRACOWorker","body","decoderConfig","decoderPending","draco","module","decodeGeometry","buffers","dracoGeometry","decodingStatus","geometryType","attributeType","attributeID","attributeResult","decodeAttribute","decodeIndex","numIndices","ptr","dracoDataType","getDracoDataType","srcByteStride","dstByteStride","dstStride","srcByteLength","dstByteLength","srcArray","dstArray","dstOffset","image","addBox","geo","addSphere","addDirectionalLight","addWaterPlane","roughness","metalness","normalScale","repeatX","repeatY","speedX","speedY","normalMap","importModelFromFile","file","gltfLoader","center","err","addModelByType","props","__props","emit","__emit","nodeRef","expandedSet","toggleExpand","inject","isExpanded","computed","hasChildren","childNodes","isSelected","watchEffect","handleSelect","handleDelete","getIcon","getDisplayName","_createElementBlock","_createElementVNode","_normalizeClass","_cache","_withModifiers","$event","_unref","_openBlock","_hoisted_1","_hoisted_2","_toDisplayString","_hoisted_3","_hoisted_4","_Fragment","_renderList","_createBlock","_component_TreeItem","emitChange","materialProps","reactive","hasStandardMaterial","lightProps","onLightIntensityChange","readMaterialFromObject","stdMat","applyMaterialToObject","propsToApply","applied","onMaterialChange","watch","newObj","read","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_16","newKey","newValue","editingJsonKey","jsonEditText","jsonError","userDataEntries","getRawType","val","loadUserDataFromObject","entries","parseValue","raw","trimmed","num","addUserDataEntry","parsed","deleteUserDataEntry","_index","truncateJson","startEditingJson","actualValue","validateJsonInput","applyJsonEdit","cancelJsonEdit","entry","useTreeExpand","selectedObject","newSet","expandPath","current","transformMode","setMode","activeTab","treeVersion","selectedObjectRef","toRef","provide","handleTreeDelete","TreeItem","_createVNode","TransformTab","UserDataTab","showFileMenu","showEditMenu","showViewMenu","showHelpMenu","showAddMenu","showOpenSub","showOpenGrid","showLightSub","fileInput","triggerImport","onFileSelected","handleNew","handleSave","handleExport","handleUndo","handleRedo","handleDuplicate","handleResetCamera","handleToggleGrid","handleHelp","handleAbout","handleOpenProject","handleOpenModel","handleOpenScene","_withDirectives","selectedModel","syncTransformFromObject","applyTransformToObject","handlePropertyChange","handleAddModel","handleImportModel","treeData","shallowRef","initTree","handleTreeSelect","handleTransformModeChange","containerRef","onMounted","onBeforeUnmount","TopBar","PropertyPanel","BottomBar"],"mappings":"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","x_google_ignoreList":[0,1,3,4,5,6,7]}