view3d-core 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/core/EventEmitter.ts","../src/core/Scene.ts","../src/core/Camera.ts","../src/core/Renderer.ts","../src/core/Engine.ts","../src/ThreeEditor.ts","../src/utils/dispose.ts"],"sourcesContent":["import type { Unsubscribe } from '../types/event.types'\r\n\r\n/**\r\n * 事件发射器\r\n * 提供类型安全的事件订阅和发布机制\r\n */\r\nexport class EventEmitter<TEventMap extends Record<string, any> = Record<string, any>> {\r\n private listeners = new Map<keyof TEventMap, Set<{ callback: Function; once: boolean }>>()\r\n\r\n /**\r\n * 订阅事件\r\n * @param event 事件名称\r\n * @param callback 回调函数\r\n * @returns 取消订阅函数\r\n */\r\n on<K extends keyof TEventMap>(event: K, callback: (data: TEventMap[K]) => void): Unsubscribe {\r\n if (!this.listeners.has(event)) {\r\n this.listeners.set(event, new Set())\r\n }\r\n const listener = { callback, once: false }\r\n this.listeners.get(event)!.add(listener)\r\n\r\n return () => {\r\n this.listeners.get(event)?.delete(listener)\r\n }\r\n }\r\n\r\n /**\r\n * 订阅一次性事件\r\n * @param event 事件名称\r\n * @param callback 回调函数\r\n * @returns 取消订阅函数\r\n */\r\n once<K extends keyof TEventMap>(event: K, callback: (data: TEventMap[K]) => void): Unsubscribe {\r\n if (!this.listeners.has(event)) {\r\n this.listeners.set(event, new Set())\r\n }\r\n const listener = { callback, once: true }\r\n this.listeners.get(event)!.add(listener)\r\n\r\n return () => {\r\n this.listeners.get(event)?.delete(listener)\r\n }\r\n }\r\n\r\n /**\r\n * 取消订阅事件\r\n * @param event 事件名称\r\n * @param callback 回调函数(可选,不传则移除该事件所有监听器)\r\n */\r\n off<K extends keyof TEventMap>(event: K, callback?: (data: TEventMap[K]) => void): void {\r\n if (!callback) {\r\n this.listeners.delete(event)\r\n return\r\n }\r\n\r\n const listeners = this.listeners.get(event)\r\n if (listeners) {\r\n for (const listener of listeners) {\r\n if (listener.callback === callback) {\r\n listeners.delete(listener)\r\n break\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 发射事件\r\n * @param event 事件名称\r\n * @param data 事件数据\r\n */\r\n emit<K extends keyof TEventMap>(event: K, data?: TEventMap[K]): void {\r\n const listeners = this.listeners.get(event)\r\n if (!listeners) return\r\n\r\n const toRemove: { callback: Function; once: boolean }[] = []\r\n\r\n for (const listener of listeners) {\r\n try {\r\n listener.callback(data)\r\n } catch (error) {\r\n console.error(`Error in event listener for \"${String(event)}\":`, error)\r\n }\r\n\r\n if (listener.once) {\r\n toRemove.push(listener)\r\n }\r\n }\r\n\r\n // 移除一次性监听器\r\n for (const listener of toRemove) {\r\n listeners.delete(listener)\r\n }\r\n }\r\n\r\n /**\r\n * 检查是否有监听器\r\n * @param event 事件名称\r\n */\r\n hasListeners<K extends keyof TEventMap>(event: K): boolean {\r\n const listeners = this.listeners.get(event)\r\n return listeners !== undefined && listeners.size > 0\r\n }\r\n\r\n /**\r\n * 获取监听器数量\r\n * @param event 事件名称\r\n */\r\n listenerCount<K extends keyof TEventMap>(event: K): number {\r\n return this.listeners.get(event)?.size ?? 0\r\n }\r\n\r\n /**\r\n * 移除所有监听器\r\n */\r\n removeAllListeners(): void {\r\n this.listeners.clear()\r\n }\r\n\r\n /**\r\n * 销毁\r\n */\r\n dispose(): void {\r\n this.removeAllListeners()\r\n }\r\n}\r\n","import * as THREE from 'three'\r\nimport type { EventEmitter } from './EventEmitter'\r\nimport type { EventMap } from '../types/event.types'\r\n\r\n/**\r\n * 场景管理器\r\n * 封装 THREE.Scene,提供扩展功能\r\n */\r\nexport class SceneManager {\r\n /** Three.js 场景实例 */\r\n readonly scene: THREE.Scene\r\n\r\n /** 环境贴图 */\r\n private _envBackground: THREE.CubeTexture | THREE.Texture | null = null\r\n\r\n /** 是否启用环境贴图 */\r\n private _environmentEnabled = false\r\n\r\n /** 环境贴图变化回调列表 */\r\n private envMapChangeCallbacks: Array<() => void> = []\r\n\r\n /** SSR 网格列表 */\r\n readonly ssrMeshList: THREE.Mesh[] = []\r\n\r\n constructor(private events: EventEmitter<EventMap>) {\r\n this.scene = new THREE.Scene()\r\n this.scene.name = 'MainScene'\r\n }\r\n\r\n /**\r\n * 获取环境贴图\r\n */\r\n get envBackground(): THREE.CubeTexture | THREE.Texture | null {\r\n return this._envBackground\r\n }\r\n\r\n /**\r\n * 设置环境贴图\r\n */\r\n set envBackground(value: THREE.CubeTexture | THREE.Texture | null) {\r\n this._envBackground = value\r\n this.updateEnvironment()\r\n this.envMapChangeCallbacks.forEach(cb => cb())\r\n }\r\n\r\n /**\r\n * 获取是否启用环境贴图\r\n */\r\n get environmentEnabled(): boolean {\r\n return this._environmentEnabled\r\n }\r\n\r\n /**\r\n * 设置是否启用环境贴图\r\n */\r\n set environmentEnabled(value: boolean) {\r\n this._environmentEnabled = value\r\n this.updateEnvironment()\r\n }\r\n\r\n /**\r\n * 更新环境贴图\r\n */\r\n private updateEnvironment(): void {\r\n this.scene.environment = this._environmentEnabled ? this._envBackground : null\r\n }\r\n\r\n /**\r\n * 注册环境贴图变化回调\r\n */\r\n onEnvMapChange(callback: () => void): () => void {\r\n this.envMapChangeCallbacks.push(callback)\r\n return () => {\r\n const index = this.envMapChangeCallbacks.indexOf(callback)\r\n if (index > -1) {\r\n this.envMapChangeCallbacks.splice(index, 1)\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 设置背景\r\n */\r\n setBackground(background: THREE.Color | THREE.Texture | THREE.CubeTexture | null): void {\r\n this.scene.background = background\r\n this.events.emit('scene:background:change', { background })\r\n }\r\n\r\n /**\r\n * 设置天空盒\r\n * @param urls 六张图片的 URL 数组 [px, nx, py, ny, pz, nz]\r\n */\r\n setSkybox(urls: string[]): Promise<THREE.CubeTexture> {\r\n return new Promise((resolve, reject) => {\r\n const loader = new THREE.CubeTextureLoader()\r\n loader.load(\r\n urls,\r\n (texture) => {\r\n this.scene.background = texture\r\n this.events.emit('scene:background:change', { background: texture })\r\n resolve(texture)\r\n },\r\n undefined,\r\n reject\r\n )\r\n })\r\n }\r\n\r\n /**\r\n * 设置环境贴图\r\n * @param urls 六张图片的 URL 数组\r\n */\r\n setEnvironmentMap(urls: string[]): Promise<THREE.CubeTexture> {\r\n return new Promise((resolve, reject) => {\r\n const loader = new THREE.CubeTextureLoader()\r\n loader.load(\r\n urls,\r\n (texture) => {\r\n this.envBackground = texture\r\n resolve(texture)\r\n },\r\n undefined,\r\n reject\r\n )\r\n })\r\n }\r\n\r\n /**\r\n * 添加物体到场景\r\n */\r\n add(...objects: THREE.Object3D[]): void {\r\n for (const object of objects) {\r\n this.scene.add(object)\r\n this.events.emit('object:added', { object, parent: this.scene })\r\n }\r\n }\r\n\r\n /**\r\n * 从场景移除物体\r\n */\r\n remove(...objects: THREE.Object3D[]): void {\r\n for (const object of objects) {\r\n this.scene.remove(object)\r\n this.events.emit('object:removed', { object, parent: this.scene })\r\n }\r\n }\r\n\r\n /**\r\n * 根据名称获取物体\r\n */\r\n getObjectByName(name: string): THREE.Object3D | undefined {\r\n return this.scene.getObjectByName(name)\r\n }\r\n\r\n /**\r\n * 根据 ID 获取物体\r\n */\r\n getObjectById(id: number): THREE.Object3D | undefined {\r\n return this.scene.getObjectById(id)\r\n }\r\n\r\n /**\r\n * 遍历场景中的所有物体\r\n */\r\n traverse(callback: (object: THREE.Object3D) => void): void {\r\n this.scene.traverse(callback)\r\n }\r\n\r\n /**\r\n * 获取场景中的所有网格\r\n */\r\n getMeshes(): THREE.Mesh[] {\r\n const meshes: THREE.Mesh[] = []\r\n this.scene.traverse((object) => {\r\n if (object instanceof THREE.Mesh) {\r\n meshes.push(object)\r\n }\r\n })\r\n return meshes\r\n }\r\n\r\n /**\r\n * 获取场景中的所有灯光\r\n */\r\n getLights(): THREE.Light[] {\r\n const lights: THREE.Light[] = []\r\n this.scene.traverse((object) => {\r\n if (object instanceof THREE.Light) {\r\n lights.push(object)\r\n }\r\n })\r\n return lights\r\n }\r\n\r\n /**\r\n * 清空场景\r\n */\r\n clear(): void {\r\n while (this.scene.children.length > 0) {\r\n const child = this.scene.children[0]\r\n this.scene.remove(child)\r\n this.events.emit('object:removed', { object: child, parent: this.scene })\r\n }\r\n }\r\n\r\n /**\r\n * 销毁场景\r\n */\r\n dispose(): void {\r\n this.scene.traverse((object) => {\r\n if (object instanceof THREE.Mesh) {\r\n object.geometry?.dispose()\r\n if (Array.isArray(object.material)) {\r\n object.material.forEach(m => {\r\n m.dispose()\r\n if ('map' in m && m.map) {\r\n (m.map as THREE.Texture).dispose()\r\n }\r\n })\r\n } else if (object.material) {\r\n object.material.dispose()\r\n if ('map' in object.material && object.material.map) {\r\n (object.material.map as THREE.Texture).dispose()\r\n }\r\n }\r\n }\r\n })\r\n\r\n this.clear()\r\n this.envMapChangeCallbacks = []\r\n this.ssrMeshList.length = 0\r\n }\r\n}\r\n","import * as THREE from 'three'\r\nimport type { CameraConfig } from '../types/config.types'\r\nimport type { EventEmitter } from './EventEmitter'\r\nimport type { EventMap } from '../types/event.types'\r\n\r\n/**\r\n * 默认相机配置\r\n */\r\nexport const DEFAULT_CAMERA_CONFIG: CameraConfig = {\r\n fov: 50,\r\n near: 0.1,\r\n far: 100000,\r\n position: { x: 10, y: 10, z: 10 }\r\n}\r\n\r\n/**\r\n * 相机管理器\r\n * 封装 THREE.PerspectiveCamera,提供扩展功能\r\n */\r\nexport class CameraManager {\r\n /** Three.js 相机实例 */\r\n readonly camera: THREE.PerspectiveCamera\r\n\r\n /** 配置 */\r\n private config: CameraConfig\r\n\r\n constructor(\r\n private container: HTMLElement,\r\n private events: EventEmitter<EventMap>,\r\n config?: Partial<CameraConfig>\r\n ) {\r\n this.config = { ...DEFAULT_CAMERA_CONFIG, ...config }\r\n\r\n const aspect = container.clientWidth / container.clientHeight\r\n\r\n this.camera = new THREE.PerspectiveCamera(\r\n this.config.fov,\r\n aspect,\r\n this.config.near,\r\n this.config.far\r\n )\r\n\r\n this.camera.name = 'MainCamera'\r\n this.camera.position.set(\r\n this.config.position.x,\r\n this.config.position.y,\r\n this.config.position.z\r\n )\r\n }\r\n\r\n /**\r\n * 获取相机位置\r\n */\r\n get position(): THREE.Vector3 {\r\n return this.camera.position\r\n }\r\n\r\n /**\r\n * 获取相机视野角度\r\n */\r\n get fov(): number {\r\n return this.camera.fov\r\n }\r\n\r\n /**\r\n * 设置相机视野角度\r\n */\r\n set fov(value: number) {\r\n this.camera.fov = value\r\n this.camera.updateProjectionMatrix()\r\n this.events.emit('camera:change', { camera: this.camera })\r\n }\r\n\r\n /**\r\n * 获取近裁剪面\r\n */\r\n get near(): number {\r\n return this.camera.near\r\n }\r\n\r\n /**\r\n * 设置近裁剪面\r\n */\r\n set near(value: number) {\r\n this.camera.near = value\r\n this.camera.updateProjectionMatrix()\r\n this.events.emit('camera:change', { camera: this.camera })\r\n }\r\n\r\n /**\r\n * 获取远裁剪面\r\n */\r\n get far(): number {\r\n return this.camera.far\r\n }\r\n\r\n /**\r\n * 设置远裁剪面\r\n */\r\n set far(value: number) {\r\n this.camera.far = value\r\n this.camera.updateProjectionMatrix()\r\n this.events.emit('camera:change', { camera: this.camera })\r\n }\r\n\r\n /**\r\n * 设置相机位置\r\n */\r\n setPosition(x: number, y: number, z: number): void {\r\n this.camera.position.set(x, y, z)\r\n this.events.emit('camera:change', { camera: this.camera })\r\n }\r\n\r\n /**\r\n * 让相机看向目标点\r\n */\r\n lookAt(target: THREE.Vector3 | { x: number; y: number; z: number }): void {\r\n if (target instanceof THREE.Vector3) {\r\n this.camera.lookAt(target)\r\n } else {\r\n this.camera.lookAt(target.x, target.y, target.z)\r\n }\r\n this.events.emit('camera:change', { camera: this.camera })\r\n }\r\n\r\n /**\r\n * 更新相机宽高比\r\n */\r\n updateAspect(): void {\r\n this.camera.aspect = this.container.clientWidth / this.container.clientHeight\r\n this.camera.updateProjectionMatrix()\r\n }\r\n\r\n /**\r\n * 获取相机世界方向\r\n */\r\n getWorldDirection(): THREE.Vector3 {\r\n const direction = new THREE.Vector3()\r\n this.camera.getWorldDirection(direction)\r\n return direction\r\n }\r\n\r\n /**\r\n * 获取相机前方指定距离的点\r\n */\r\n getTargetPoint(distance: number): THREE.Vector3 {\r\n const direction = this.getWorldDirection()\r\n return this.camera.position.clone().add(direction.multiplyScalar(distance))\r\n }\r\n\r\n /**\r\n * 获取相机配置\r\n */\r\n getConfig(): CameraConfig {\r\n return {\r\n fov: this.camera.fov,\r\n near: this.camera.near,\r\n far: this.camera.far,\r\n position: {\r\n x: this.camera.position.x,\r\n y: this.camera.position.y,\r\n z: this.camera.position.z\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 应用配置\r\n */\r\n applyConfig(config: Partial<CameraConfig>): void {\r\n if (config.fov !== undefined) {\r\n this.camera.fov = config.fov\r\n }\r\n if (config.near !== undefined) {\r\n this.camera.near = config.near\r\n }\r\n if (config.far !== undefined) {\r\n this.camera.far = config.far\r\n }\r\n if (config.position) {\r\n this.camera.position.set(\r\n config.position.x,\r\n config.position.y,\r\n config.position.z\r\n )\r\n }\r\n this.camera.updateProjectionMatrix()\r\n this.events.emit('camera:change', { camera: this.camera })\r\n }\r\n\r\n /**\r\n * 销毁\r\n */\r\n dispose(): void {\r\n // 相机本身不需要特殊清理\r\n }\r\n}\r\n","import * as THREE from 'three'\r\nimport type { RendererConfig } from '../types/config.types'\r\nimport type { EventEmitter } from './EventEmitter'\r\nimport type { EventMap } from '../types/event.types'\r\n\r\n/**\r\n * 默认渲染器配置\r\n * 注意:像素比默认限制为 2,避免高 DPI 设备性能问题\r\n */\r\nexport const DEFAULT_RENDERER_CONFIG: RendererConfig = {\r\n pixelRatio: typeof window !== 'undefined' ? Math.min(window.devicePixelRatio, 2) : 1,\r\n antialias: true,\r\n alpha: true,\r\n logarithmicDepthBuffer: true,\r\n preserveDrawingBuffer: false,\r\n powerPreference: 'high-performance',\r\n toneMapping: THREE.NoToneMapping,\r\n toneMappingExposure: 1,\r\n outputColorSpace: THREE.SRGBColorSpace,\r\n shadowMapEnabled: false,\r\n shadowMapType: THREE.PCFSoftShadowMap\r\n}\r\n\r\n/**\r\n * 渲染器管理器\r\n * 封装 THREE.WebGLRenderer,提供扩展功能\r\n */\r\nexport class RendererManager {\r\n /** Three.js 渲染器实例 */\r\n readonly renderer: THREE.WebGLRenderer\r\n\r\n /** 配置 */\r\n private config: RendererConfig\r\n\r\n constructor(\r\n private container: HTMLElement,\r\n private events: EventEmitter<EventMap>,\r\n config?: Partial<RendererConfig>\r\n ) {\r\n this.config = { ...DEFAULT_RENDERER_CONFIG, ...config }\r\n \r\n // 限制像素比最大为 2\r\n this.config.pixelRatio = Math.min(this.config.pixelRatio, 2)\r\n\r\n this.renderer = new THREE.WebGLRenderer({\r\n antialias: this.config.antialias,\r\n alpha: this.config.alpha,\r\n logarithmicDepthBuffer: this.config.logarithmicDepthBuffer,\r\n preserveDrawingBuffer: this.config.preserveDrawingBuffer,\r\n powerPreference: this.config.powerPreference\r\n })\r\n\r\n this.renderer.setSize(container.clientWidth, container.clientHeight)\r\n this.renderer.setPixelRatio(this.config.pixelRatio)\r\n this.renderer.toneMapping = this.config.toneMapping\r\n this.renderer.toneMappingExposure = this.config.toneMappingExposure\r\n this.renderer.outputColorSpace = this.config.outputColorSpace\r\n\r\n // 阴影配置\r\n this.renderer.shadowMap.enabled = this.config.shadowMapEnabled\r\n this.renderer.shadowMap.type = this.config.shadowMapType\r\n\r\n // 添加到容器\r\n container.appendChild(this.renderer.domElement)\r\n }\r\n\r\n /**\r\n * 获取 DOM 元素\r\n */\r\n get domElement(): HTMLCanvasElement {\r\n return this.renderer.domElement\r\n }\r\n\r\n /**\r\n * 获取像素比\r\n */\r\n get pixelRatio(): number {\r\n return this.renderer.getPixelRatio()\r\n }\r\n\r\n /**\r\n * 设置像素比\r\n * 限制最大值为 2,避免性能问题\r\n */\r\n set pixelRatio(value: number) {\r\n const limitedValue = Math.min(value, 2)\r\n this.renderer.setPixelRatio(limitedValue)\r\n this.config.pixelRatio = limitedValue\r\n }\r\n\r\n /**\r\n * 获取渲染器大小\r\n */\r\n getSize(): { width: number; height: number } {\r\n const size = new THREE.Vector2()\r\n this.renderer.getSize(size)\r\n return { width: size.x, height: size.y }\r\n }\r\n\r\n /**\r\n * 设置渲染器大小\r\n */\r\n setSize(width: number, height: number): void {\r\n this.renderer.setSize(width, height)\r\n this.events.emit('resize', { width, height })\r\n }\r\n\r\n /**\r\n * 更新大小以适应容器\r\n */\r\n updateSize(): void {\r\n const width = this.container.clientWidth\r\n const height = this.container.clientHeight\r\n this.setSize(width, height)\r\n }\r\n\r\n /**\r\n * 渲染场景\r\n */\r\n render(scene: THREE.Scene, camera: THREE.Camera): void {\r\n this.renderer.render(scene, camera)\r\n }\r\n\r\n /**\r\n * 获取截图\r\n */\r\n getScreenshot(type = 'image/png', quality = 0.9): string {\r\n return this.renderer.domElement.toDataURL(type, quality)\r\n }\r\n\r\n /**\r\n * 启用/禁用阴影\r\n */\r\n setShadowMapEnabled(enabled: boolean): void {\r\n this.renderer.shadowMap.enabled = enabled\r\n this.config.shadowMapEnabled = enabled\r\n }\r\n\r\n /**\r\n * 设置阴影类型\r\n */\r\n setShadowMapType(type: THREE.ShadowMapType): void {\r\n this.renderer.shadowMap.type = type\r\n this.config.shadowMapType = type\r\n }\r\n\r\n /**\r\n * 设置色调映射\r\n */\r\n setToneMapping(toneMapping: THREE.ToneMapping, exposure?: number): void {\r\n this.renderer.toneMapping = toneMapping\r\n this.config.toneMapping = toneMapping\r\n if (exposure !== undefined) {\r\n this.renderer.toneMappingExposure = exposure\r\n this.config.toneMappingExposure = exposure\r\n }\r\n }\r\n\r\n /**\r\n * 获取渲染器配置\r\n */\r\n getConfig(): RendererConfig {\r\n return { ...this.config }\r\n }\r\n\r\n /**\r\n * 应用配置\r\n */\r\n applyConfig(config: Partial<RendererConfig>): void {\r\n if (config.pixelRatio !== undefined) {\r\n this.pixelRatio = config.pixelRatio\r\n }\r\n if (config.toneMapping !== undefined) {\r\n this.renderer.toneMapping = config.toneMapping\r\n this.config.toneMapping = config.toneMapping\r\n }\r\n if (config.toneMappingExposure !== undefined) {\r\n this.renderer.toneMappingExposure = config.toneMappingExposure\r\n this.config.toneMappingExposure = config.toneMappingExposure\r\n }\r\n if (config.shadowMapEnabled !== undefined) {\r\n this.setShadowMapEnabled(config.shadowMapEnabled)\r\n }\r\n if (config.shadowMapType !== undefined) {\r\n this.setShadowMapType(config.shadowMapType)\r\n }\r\n }\r\n\r\n /**\r\n * 获取渲染信息\r\n */\r\n getInfo(): THREE.WebGLInfo {\r\n return this.renderer.info\r\n }\r\n\r\n /**\r\n * 清除渲染信息\r\n */\r\n resetInfo(): void {\r\n this.renderer.info.reset()\r\n }\r\n\r\n /**\r\n * 销毁\r\n */\r\n dispose(): void {\r\n this.renderer.dispose()\r\n this.renderer.forceContextLoss()\r\n if (this.renderer.domElement.parentNode) {\r\n this.renderer.domElement.parentNode.removeChild(this.renderer.domElement)\r\n }\r\n }\r\n}\r\n","import * as THREE from 'three'\r\nimport { EventEmitter } from './EventEmitter'\r\nimport { SceneManager } from './Scene'\r\nimport { CameraManager } from './Camera'\r\nimport { RendererManager } from './Renderer'\r\nimport type { EngineConfig } from '../types/config.types'\r\nimport type { EventMap } from '../types/event.types'\r\n\r\n/**\r\n * 默认引擎配置\r\n */\r\nexport const DEFAULT_ENGINE_CONFIG: Partial<EngineConfig> = {\r\n autoResize: true,\r\n fps: null,\r\n autoStart: true\r\n}\r\n\r\n/**\r\n * 帧回调函数类型\r\n */\r\ntype FrameCallback = (delta: number, elapsed: number) => void\r\n\r\n/**\r\n * 引擎核心\r\n * 管理场景、相机、渲染器和渲染循环\r\n */\r\nexport class Engine {\r\n /** 事件发射器 */\r\n readonly events: EventEmitter<EventMap>\r\n\r\n /** 场景管理器 */\r\n readonly sceneManager: SceneManager\r\n\r\n /** 相机管理器 */\r\n readonly cameraManager: CameraManager\r\n\r\n /** 渲染器管理器 */\r\n readonly rendererManager: RendererManager\r\n\r\n /** 时钟 */\r\n readonly clock: THREE.Clock\r\n\r\n /** 配置 */\r\n private config: EngineConfig\r\n\r\n /** 动画帧 ID */\r\n private animationId: number | null = null\r\n\r\n /** 是否正在运行 */\r\n private _isRunning = false\r\n\r\n /** 帧回调列表 */\r\n private frameCallbacks: Set<FrameCallback> = new Set()\r\n\r\n /** FPS 控制相关 */\r\n private fpsInterval: number = 0\r\n private lastFrameTime: number = 0\r\n\r\n /** 容器 */\r\n private container: HTMLElement\r\n\r\n /** 窗口大小变化处理函数 */\r\n private resizeHandler: (() => void) | null = null\r\n\r\n constructor(config: EngineConfig) {\r\n this.config = { ...DEFAULT_ENGINE_CONFIG, ...config } as EngineConfig\r\n this.container = config.container\r\n\r\n // 初始化事件系统\r\n this.events = new EventEmitter<EventMap>()\r\n\r\n // 初始化时钟\r\n this.clock = new THREE.Clock(false)\r\n\r\n // 初始化场景\r\n this.sceneManager = new SceneManager(this.events)\r\n\r\n // 初始化相机\r\n this.cameraManager = new CameraManager(\r\n this.container,\r\n this.events,\r\n config.camera\r\n )\r\n\r\n // 将相机添加到场景\r\n this.sceneManager.scene.add(this.cameraManager.camera)\r\n\r\n // 初始化渲染器\r\n this.rendererManager = new RendererManager(\r\n this.container,\r\n this.events,\r\n config.renderer\r\n )\r\n\r\n // FPS 控制\r\n if (this.config.fps !== undefined && this.config.fps !== null && this.config.fps > 0) {\r\n this.fpsInterval = 1000 / this.config.fps\r\n }\r\n\r\n // 自动调整大小\r\n if (this.config.autoResize) {\r\n this.setupAutoResize()\r\n }\r\n\r\n // 发射就绪事件\r\n this.events.emit('engine:ready', undefined)\r\n\r\n // 自动启动\r\n if (this.config.autoStart) {\r\n this.start()\r\n }\r\n }\r\n\r\n /**\r\n * 获取场景\r\n */\r\n get scene(): THREE.Scene {\r\n return this.sceneManager.scene\r\n }\r\n\r\n /**\r\n * 获取相机\r\n */\r\n get camera(): THREE.PerspectiveCamera {\r\n return this.cameraManager.camera\r\n }\r\n\r\n /**\r\n * 获取渲染器\r\n */\r\n get renderer(): THREE.WebGLRenderer {\r\n return this.rendererManager.renderer\r\n }\r\n\r\n /**\r\n * 获取 DOM 元素\r\n */\r\n get domElement(): HTMLCanvasElement {\r\n return this.rendererManager.domElement\r\n }\r\n\r\n /**\r\n * 是否正在运行\r\n */\r\n get isRunning(): boolean {\r\n return this._isRunning\r\n }\r\n\r\n /**\r\n * 设置自动调整大小\r\n */\r\n private setupAutoResize(): void {\r\n this.resizeHandler = () => this.resize()\r\n window.addEventListener('resize', this.resizeHandler)\r\n }\r\n\r\n /**\r\n * 启动渲染循环\r\n */\r\n start(): void {\r\n if (this._isRunning) return\r\n\r\n this._isRunning = true\r\n this.clock.start()\r\n this.lastFrameTime = performance.now()\r\n this.events.emit('engine:start', undefined)\r\n this.animate()\r\n }\r\n\r\n /**\r\n * 停止渲染循环\r\n */\r\n stop(): void {\r\n if (!this._isRunning) return\r\n\r\n this._isRunning = false\r\n this.clock.stop()\r\n\r\n if (this.animationId !== null) {\r\n cancelAnimationFrame(this.animationId)\r\n this.animationId = null\r\n }\r\n\r\n this.events.emit('engine:stop', undefined)\r\n }\r\n\r\n /**\r\n * 动画循环\r\n */\r\n private animate = (): void => {\r\n if (!this._isRunning) return\r\n\r\n this.animationId = requestAnimationFrame(this.animate)\r\n\r\n const now = performance.now()\r\n\r\n // FPS 控制\r\n if (this.fpsInterval > 0) {\r\n const elapsed = now - this.lastFrameTime\r\n if (elapsed < this.fpsInterval) return\r\n this.lastFrameTime = now - (elapsed % this.fpsInterval)\r\n }\r\n\r\n const delta = this.clock.getDelta()\r\n const elapsedTime = this.clock.getElapsedTime()\r\n\r\n // 发射渲染前事件\r\n this.events.emit('render:before', { delta, elapsed: elapsedTime })\r\n\r\n // 执行帧回调\r\n for (const callback of this.frameCallbacks) {\r\n try {\r\n callback(delta, elapsedTime)\r\n } catch (error) {\r\n console.error('Error in frame callback:', error)\r\n }\r\n }\r\n\r\n // 渲染\r\n this.render()\r\n\r\n // 发射渲染后事件\r\n this.events.emit('render:after', { delta, elapsed: elapsedTime })\r\n }\r\n\r\n /**\r\n * 渲染一帧\r\n */\r\n render(): void {\r\n this.rendererManager.render(this.scene, this.camera)\r\n }\r\n\r\n /**\r\n * 调整大小\r\n */\r\n resize(): void {\r\n const width = this.container.clientWidth\r\n const height = this.container.clientHeight\r\n\r\n this.cameraManager.updateAspect()\r\n this.rendererManager.setSize(width, height)\r\n\r\n this.events.emit('resize', { width, height })\r\n }\r\n\r\n /**\r\n * 注册帧回调\r\n * @param callback 每帧执行的回调函数\r\n * @returns 取消注册函数\r\n */\r\n onUpdate(callback: FrameCallback): () => void {\r\n this.frameCallbacks.add(callback)\r\n return () => {\r\n this.frameCallbacks.delete(callback)\r\n }\r\n }\r\n\r\n /**\r\n * 获取截图\r\n */\r\n screenshot(type?: string, quality?: number): string {\r\n // 确保渲染最新帧\r\n this.render()\r\n return this.rendererManager.getScreenshot(type, quality)\r\n }\r\n\r\n /**\r\n * 设置 FPS 限制\r\n */\r\n setFPS(fps: number | null): void {\r\n this.config.fps = fps\r\n if (fps !== null && fps > 0) {\r\n this.fpsInterval = 1000 / fps\r\n } else {\r\n this.fpsInterval = 0\r\n }\r\n }\r\n\r\n /**\r\n * 获取当前 FPS\r\n */\r\n getFPS(): number {\r\n return this.fpsInterval > 0 ? 1000 / this.fpsInterval : 0\r\n }\r\n\r\n /**\r\n * 销毁引擎\r\n */\r\n dispose(): void {\r\n this.events.emit('engine:dispose', undefined)\r\n\r\n // 停止渲染循环\r\n this.stop()\r\n\r\n // 移除窗口事件监听\r\n if (this.resizeHandler) {\r\n window.removeEventListener('resize', this.resizeHandler)\r\n this.resizeHandler = null\r\n }\r\n\r\n // 清空帧回调\r\n this.frameCallbacks.clear()\r\n\r\n // 销毁各管理器\r\n this.sceneManager.dispose()\r\n this.cameraManager.dispose()\r\n this.rendererManager.dispose()\r\n\r\n // 销毁事件系统\r\n this.events.dispose()\r\n }\r\n}\r\n","import * as THREE from 'three'\r\nimport gsap from 'gsap'\r\nimport { Engine } from './core/Engine'\r\nimport { EventEmitter } from './core/EventEmitter'\r\nimport { PluginManager } from './plugins/PluginManager'\r\nimport { OrbitControllerPlugin } from './plugins/controls/OrbitController'\r\nimport { TransformControllerPlugin } from './plugins/controls/TransformController'\r\nimport { LoaderPlugin } from './plugins/loaders/LoaderPlugin'\r\nimport { ComposerPlugin } from './plugins/postprocessing/ComposerPlugin'\r\nimport { CSSRendererPlugin } from './plugins/renderers/CSSRendererPlugin'\r\nimport { EditorPlugin } from './plugins/editor/EditorPlugin'\r\nimport { GUIPlugin } from './plugins/gui/GUIPlugin'\r\nimport { GizmoPlugin } from './plugins/gizmo/GizmoPlugin'\r\nimport { getDistanceScalePoint } from './utils/math'\r\nimport { getBestViewTarget, getObjectViews } from './utils/box3'\r\nimport { getRootModel } from './utils/raycast'\r\nimport type { ThreeEditorConfig, ScreenshotOptions } from './types/config.types'\r\nimport type { GsapQuery } from './types/core.types'\r\nimport type { EventMap } from './types/event.types'\r\nimport type { IPlugin } from './types/plugin.types'\r\nimport type {\r\n HandlerMode,\r\n RootInfo,\r\n LoaderService,\r\n ClickInfo,\r\n ViewAngle,\r\n CurveAnimationController,\r\n ExtendedObject3D\r\n} from './types/core.types'\r\n\r\n/**\r\n * Draco 解码器默认路径\r\n */\r\nlet dracoPath = '/draco/'\r\n\r\n/**\r\n * Three Editor 主类\r\n * 提供完整的 3D 编辑器功能\r\n */\r\nexport class ThreeEditor {\r\n /** Three.js 库引用 */\r\n static THREE = THREE\r\n\r\n /** GSAP 库引用 */\r\n static gsap = gsap\r\n\r\n /** Draco 解码器路径 */\r\n static get dracoPath(): string {\r\n return dracoPath\r\n }\r\n\r\n static set dracoPath(path: string) {\r\n dracoPath = path\r\n }\r\n\r\n /** 引擎实例 */\r\n readonly engine: Engine\r\n\r\n /** 事件发射器 */\r\n readonly events: EventEmitter<EventMap>\r\n\r\n /** 插件管理器 */\r\n readonly plugins: PluginManager\r\n\r\n /** 配置 */\r\n private config: ThreeEditorConfig\r\n\r\n /** 进度列表 */\r\n progressList: Array<{ loaderService: LoaderService; rootInfo: RootInfo; params?: any }> = []\r\n\r\n /** 公共帧动画列表 */\r\n private commonFrameList: CurveAnimationController[] = []\r\n\r\n /** 混合器列表 */\r\n private mixerList: THREE.AnimationMixer[] = []\r\n\r\n /** 着色器列表 */\r\n private shaderList: any[] = []\r\n\r\n constructor(config: ThreeEditorConfig) {\r\n this.config = config\r\n\r\n // 创建引擎\r\n this.engine = new Engine({\r\n container: config.container,\r\n ...config.engine,\r\n autoStart: false\r\n })\r\n\r\n // 使用引擎的事件发射器\r\n this.events = this.engine.events\r\n\r\n // 创建插件管理器\r\n this.plugins = new PluginManager({\r\n engine: this.engine,\r\n events: this.events\r\n })\r\n\r\n // 安装核心插件\r\n this.installCorePlugins()\r\n\r\n // 设置渲染回调\r\n this.engine.onUpdate((delta, elapsed) => {\r\n this.onUpdate(delta, elapsed)\r\n })\r\n\r\n // 恢复场景(如果有)\r\n if (config.sceneParams) {\r\n this.restoreScene(config.sceneParams)\r\n }\r\n\r\n // 加载模型(如果有)\r\n if (config.meshListParams) {\r\n config.meshListParams.forEach(item => {\r\n this.setModelFromInfo(item.rootInfo, item.group)\r\n })\r\n }\r\n\r\n // 设置天空盒(如果有)\r\n if (config.skyParams) {\r\n this.setSky(config.skyParams)\r\n this.setGlobalEnvBackground(config.skyParams)\r\n }\r\n\r\n // 启动引擎\r\n if (config.autoStart !== false) {\r\n this.engine.start()\r\n }\r\n }\r\n\r\n // ============ 便捷访问器 ============\r\n\r\n /** 获取 THREE 库 */\r\n get THREE() {\r\n return THREE\r\n }\r\n\r\n /** 获取 gsap 库 */\r\n get gsap() {\r\n return gsap\r\n }\r\n\r\n /** 获取场景 */\r\n get scene(): THREE.Scene {\r\n return this.engine.scene\r\n }\r\n\r\n /** 获取相机 */\r\n get camera(): THREE.PerspectiveCamera {\r\n return this.engine.camera\r\n }\r\n\r\n /** 获取渲染器 */\r\n get renderer(): THREE.WebGLRenderer {\r\n return this.engine.renderer\r\n }\r\n\r\n /** 获取 viewer 对象(兼容旧 API) */\r\n get viewer() {\r\n const orbitPlugin = this.plugins.get<OrbitControllerPlugin>('orbit-controller')\r\n const transformPlugin = this.plugins.get<TransformControllerPlugin>('transform-controller')\r\n const composerPlugin = this.plugins.get<ComposerPlugin>('composer')\r\n const cssPlugin = this.plugins.get<CSSRendererPlugin>('css-renderer')\r\n const editorPlugin = this.plugins.get<EditorPlugin>('editor')\r\n const loaderPlugin = this.plugins.get<LoaderPlugin>('loader')\r\n const guiPlugin = this.plugins.get<GUIPlugin>('gui')\r\n\r\n return {\r\n scene: this.scene,\r\n camera: this.camera,\r\n renderer: this.renderer,\r\n controls: orbitPlugin?.controls,\r\n transformControls: transformPlugin?.controls,\r\n Composer: composerPlugin,\r\n CSS2DObject: cssPlugin?.CSS2DObject,\r\n CSS3DObject: cssPlugin?.CSS3DObject,\r\n MixerList: this.mixerList,\r\n ShaderList: this.shaderList,\r\n CommonFrameList: this.commonFrameList,\r\n handler: editorPlugin,\r\n modelControls: loaderPlugin,\r\n currentInfo: editorPlugin?.currentInfo,\r\n GUI: guiPlugin?.gui,\r\n renderSceneResize: () => this.engine.resize(),\r\n destroySceneRender: () => this.dispose(),\r\n saveSceneEditor: () => this.saveSceneEditor()\r\n }\r\n }\r\n\r\n // ============ 核心方法 ============\r\n\r\n /**\r\n * 安装核心插件\r\n */\r\n private installCorePlugins(): void {\r\n // 轨道控制器\r\n this.plugins.use(new OrbitControllerPlugin())\r\n\r\n // 变换控制器\r\n this.plugins.use(new TransformControllerPlugin())\r\n\r\n // 加载器\r\n const loaderPlugin = new LoaderPlugin({ dracoPath: ThreeEditor.dracoPath })\r\n this.plugins.use(loaderPlugin)\r\n\r\n // 后期处理\r\n this.plugins.use(new ComposerPlugin())\r\n\r\n // CSS 渲染器\r\n this.plugins.use(new CSSRendererPlugin())\r\n\r\n // 编辑器\r\n this.plugins.use(new EditorPlugin())\r\n\r\n // 辅助工具 (网格、坐标轴、性能监控)\r\n this.plugins.use(new GizmoPlugin({\r\n grid: { enabled: true, size: 100, divisions: 100, colorCenterLine: 0x444444, colorGrid: 0x888888 },\r\n axes: { enabled: true, size: 5 },\r\n stats: { enabled: false, mode: 0 },\r\n viewHelper: { enabled: false, size: 128, position: 'bottom-right' },\r\n box3Helper: { enabled: false, color: 0xffff00 }\r\n }))\r\n\r\n // GUI 面板\r\n const guiConfig = this.config.gui\r\n if (guiConfig?.useProxy !== true) {\r\n this.plugins.use(new GUIPlugin({\r\n autoPlace: guiConfig?.autoPlace ?? true,\r\n width: guiConfig?.width ?? 300,\r\n useProxy: guiConfig?.useProxy ?? false\r\n }))\r\n }\r\n }\r\n\r\n /**\r\n * 每帧更新\r\n */\r\n private onUpdate(delta: number, elapsed: number): void {\r\n // 更新混合器\r\n this.mixerList.forEach(mixer => {\r\n (mixer as any).mixerRender?.()\r\n })\r\n\r\n // 更新着色器\r\n this.shaderList.forEach(shader => {\r\n shader.ShaderAnimateRender?.()\r\n })\r\n\r\n // 更新公共帧动画\r\n this.commonFrameList.forEach((anim: any) => {\r\n anim.frameAnimationRender?.()\r\n })\r\n\r\n // 后期处理渲染\r\n const composerPlugin = this.plugins.get<ComposerPlugin>('composer')\r\n if (composerPlugin) {\r\n composerPlugin.render()\r\n }\r\n }\r\n\r\n /**\r\n * 使用插件\r\n */\r\n use<T extends IPlugin>(plugin: T): this {\r\n this.plugins.use(plugin)\r\n return this\r\n }\r\n\r\n // ============ 模型加载 ============\r\n\r\n /**\r\n * 根据类型加载模型\r\n */\r\n setModelFromInfo(rootInfo: RootInfo, params: any = null): {\r\n loaderService: LoaderService\r\n rootInfo: RootInfo\r\n params: any\r\n } {\r\n const loaderPlugin = this.plugins.get<LoaderPlugin>('loader')\r\n if (!loaderPlugin) {\r\n throw new Error('Loader plugin not installed')\r\n }\r\n\r\n const loaderService = loaderPlugin.loadModel(rootInfo)\r\n\r\n // 加载完成后添加到场景\r\n const originalComplete = loaderService.complete\r\n loaderService.complete = (model) => {\r\n // 标记根信息\r\n (model as ExtendedObject3D).rootInfo = rootInfo\r\n\r\n // 添加到场景\r\n this.scene.add(model)\r\n\r\n // 调用原始回调\r\n originalComplete(model)\r\n }\r\n\r\n const item = { loaderService, rootInfo, params }\r\n this.progressList.push(item)\r\n\r\n return item\r\n }\r\n\r\n // ============ 天空/环境 ============\r\n\r\n /**\r\n * 设置天空盒\r\n */\r\n setSky(urls: string[]): void {\r\n this.engine.sceneManager.setSkybox(urls)\r\n }\r\n\r\n /**\r\n * 设置全局环境贴图\r\n */\r\n setGlobalEnvBackground(urls: string[]): void {\r\n this.engine.sceneManager.setEnvironmentMap(urls).then(() => {\r\n this.engine.sceneManager.environmentEnabled = true\r\n })\r\n }\r\n\r\n // ============ CSS DOM ============\r\n\r\n /**\r\n * 设置 CSS2D DOM 元素\r\n */\r\n setCss2dDOM(dom: HTMLElement, position: THREE.Vector3) {\r\n const cssPlugin = this.plugins.get<CSSRendererPlugin>('css-renderer')\r\n if (!cssPlugin) {\r\n throw new Error('CSS Renderer plugin not installed')\r\n }\r\n\r\n dom.style.pointerEvents = 'auto'\r\n const mesh = cssPlugin.addCSS2D(dom, position)\r\n return mesh\r\n }\r\n\r\n /**\r\n * 设置 CSS3D DOM 元素\r\n */\r\n setCss3dDOM(dom: HTMLElement, position: THREE.Vector3) {\r\n const cssPlugin = this.plugins.get<CSSRendererPlugin>('css-renderer')\r\n if (!cssPlugin) {\r\n throw new Error('CSS Renderer plugin not installed')\r\n }\r\n\r\n const mesh = cssPlugin.addCSS3D(dom, position)\r\n return mesh\r\n }\r\n\r\n // ============ 事件处理 ============\r\n\r\n /**\r\n * 获取场景点击事件\r\n */\r\n getSceneEvent(event: MouseEvent, callback: (info: ClickInfo) => void): void {\r\n const editorPlugin = this.plugins.get<EditorPlugin>('editor')\r\n if (!editorPlugin) return\r\n\r\n const info = editorPlugin.handleClick(event)\r\n if (info) {\r\n callback(info)\r\n }\r\n }\r\n\r\n /**\r\n * 获取原始场景事件\r\n */\r\n getRawSceneEvent(): { raycaster: THREE.Raycaster; getIntersects: (event: MouseEvent, objects: THREE.Object3D[]) => THREE.Intersection[] } {\r\n const raycaster = new THREE.Raycaster()\r\n const mouse = new THREE.Vector2()\r\n\r\n const getIntersects = (event: MouseEvent, objects: THREE.Object3D[]): THREE.Intersection[] => {\r\n const rect = this.renderer.domElement.getBoundingClientRect()\r\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1\r\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1\r\n\r\n raycaster.setFromCamera(mouse, this.camera)\r\n return raycaster.intersectObjects(objects, true)\r\n }\r\n\r\n return { raycaster, getIntersects }\r\n }\r\n\r\n // ============ 动画 ============\r\n\r\n /**\r\n * 创建 GSAP 动画\r\n */\r\n setGsapAnimation(\r\n position: THREE.Vector3 | { x: number; y: number; z: number },\r\n target: { x?: number; y?: number; z?: number },\r\n query: GsapQuery = {}\r\n ) {\r\n return gsap.to(position, {\r\n ...target,\r\n duration: 2,\r\n ease: 'none',\r\n repeat: 0,\r\n yoyo: false,\r\n yoyoEase: true,\r\n ...query\r\n })\r\n }\r\n\r\n /**\r\n * 播放模型动画\r\n */\r\n setModelAnimationPlay(group: ExtendedObject3D) {\r\n if (!group.animationPlayParams || !group.animations) return null\r\n\r\n const { speed, actionIndexs, startTime, loop } = group.animationPlayParams\r\n\r\n const clock = new THREE.Clock()\r\n const mixer = new THREE.AnimationMixer(group as unknown as THREE.Object3D)\r\n\r\n const actions = group.animations\r\n .filter((_, index) => actionIndexs[index])\r\n .map(clip => {\r\n const action = mixer.clipAction(clip)\r\n action.loop = loop ? THREE.LoopRepeat : THREE.LoopOnce\r\n action.time = startTime\r\n action.timeScale = speed\r\n action.clampWhenFinished = true\r\n action.play()\r\n return action\r\n })\r\n\r\n ;(group as any).mixerRender = () => {\r\n mixer.update(clock.getDelta())\r\n }\r\n\r\n this.mixerList.push(mixer as any)\r\n\r\n return { mixer, actions }\r\n }\r\n\r\n /**\r\n * 移除模型动画\r\n */\r\n removeModelAnimation(group: ExtendedObject3D): void {\r\n const index = this.mixerList.findIndex((m: any) => m === group || (m as any).mixerRender === (group as any).mixerRender)\r\n if (index > -1) {\r\n this.mixerList.splice(index, 1)\r\n }\r\n }\r\n\r\n /**\r\n * 设置曲线动画\r\n */\r\n setCurveAnimation(curve: THREE.Curve<THREE.Vector3>, speed: number = 1): CurveAnimationController {\r\n const commonFrameList = this.commonFrameList\r\n \r\n const controller: CurveAnimationController = {\r\n id: Date.now(),\r\n curve,\r\n time: 0,\r\n pause: false,\r\n speed,\r\n frameCallback: null,\r\n frameEndCallback: null,\r\n start: function(this: CurveAnimationController) {\r\n if (!commonFrameList.includes(this as any)) {\r\n commonFrameList.push(this as any)\r\n }\r\n this.pause = false\r\n },\r\n destroy: function(this: CurveAnimationController) {\r\n const index = commonFrameList.indexOf(this as any)\r\n if (index > -1) {\r\n commonFrameList.splice(index, 1)\r\n }\r\n }\r\n }\r\n\r\n // 帧动画渲染\r\n ;(controller as any).frameAnimationRender = () => {\r\n if (controller.pause) return\r\n\r\n controller.time += controller.speed / 1000\r\n\r\n if (controller.time > 1 || controller.time < 0) {\r\n controller.time = controller.time > 1 ? 1 : 0\r\n controller.pause = true\r\n controller.frameEndCallback?.()\r\n return\r\n }\r\n\r\n const point = curve.getPointAt(controller.time)\r\n controller.frameCallback?.(point)\r\n }\r\n\r\n return controller\r\n }\r\n\r\n // ============ 后期处理 ============\r\n\r\n /**\r\n * 设置轮廓光选中\r\n */\r\n setOutlinePass(meshList: THREE.Object3D[] = []): void {\r\n const composerPlugin = this.plugins.get<ComposerPlugin>('composer')\r\n if (composerPlugin) {\r\n composerPlugin.setOutlineObjects(meshList)\r\n }\r\n }\r\n\r\n // ============ 控制 ============\r\n\r\n /**\r\n * 设置场景控制模式\r\n */\r\n setSceneControlMode(mode: HandlerMode): void {\r\n const editorPlugin = this.plugins.get<EditorPlugin>('editor')\r\n if (editorPlugin) {\r\n editorPlugin.setMode(mode)\r\n }\r\n }\r\n\r\n /**\r\n * 设置变换控制器属性\r\n */\r\n setTransformControlsProperty(key: string, value: any): void {\r\n const transformPlugin = this.plugins.get<TransformControllerPlugin>('transform-controller')\r\n if (transformPlugin && transformPlugin.controls.hasOwnProperty(key)) {\r\n (transformPlugin.controls as any)[key] = value\r\n }\r\n }\r\n\r\n // ============ 工具方法 ============\r\n\r\n /**\r\n * 获取两点指定距离比例点\r\n */\r\n getDistanceScalePoint = getDistanceScalePoint\r\n\r\n /**\r\n * 获取最佳视角\r\n */\r\n getBestViewTarget = getBestViewTarget\r\n\r\n /**\r\n * 获取物体视图\r\n */\r\n getObjectViews(object: THREE.Object3D, fov?: number) {\r\n return getObjectViews(object, fov ?? this.camera.fov)\r\n }\r\n\r\n /**\r\n * 获取场景曲线列表\r\n */\r\n getSceneCurveList() {\r\n return this.scene.children\r\n .filter(i => (i as ExtendedObject3D).isCurveMesh)\r\n .map(i => ({\r\n path: (i as ExtendedObject3D).curvePath || ((i as THREE.Mesh).geometry as any)?.parameters?.path,\r\n mesh: i\r\n }))\r\n }\r\n\r\n // ============ 保存/恢复 ============\r\n\r\n /**\r\n * 保存场景\r\n */\r\n saveSceneEditor(): void {\r\n if (this.config.saveCallback) {\r\n // TODO: 实现完整的序列化\r\n const sceneParams = {}\r\n const meshListParams: any[] = []\r\n\r\n this.config.saveCallback(sceneParams, meshListParams)\r\n }\r\n }\r\n\r\n /**\r\n * 恢复场景\r\n */\r\n private restoreScene(params: any): void {\r\n // TODO: 实现完整的反序列化\r\n }\r\n\r\n /**\r\n * 获取场景截图\r\n */\r\n getSceneEditorImage(params?: { type?: string; quality?: number } | [string?, number?]): string {\r\n if (Array.isArray(params)) {\r\n return this.engine.screenshot(params[0], params[1])\r\n }\r\n return this.engine.screenshot(params?.type, params?.quality)\r\n }\r\n\r\n /**\r\n * 刷新 GUI\r\n */\r\n refreshGUI(): void {\r\n const guiPlugin = this.plugins.get<GUIPlugin>('gui')\r\n if (guiPlugin) {\r\n guiPlugin.updateDisplay()\r\n }\r\n }\r\n\r\n /**\r\n * 设置 GUI DOM 位置\r\n */\r\n setGUIDomPosition(dom: HTMLElement): { GUIDom: HTMLElement | null; remove: () => void } | null {\r\n const guiPlugin = this.plugins.get<GUIPlugin>('gui')\r\n if (!guiPlugin || !guiPlugin.domElement) return null\r\n\r\n const guiDom = guiPlugin.domElement\r\n dom.appendChild(guiDom)\r\n\r\n return {\r\n GUIDom: guiDom,\r\n remove: () => {\r\n if (guiDom.parentElement === dom) {\r\n dom.removeChild(guiDom)\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 设置操作选项\r\n */\r\n setOperateOption(key: string, value: boolean): void {\r\n const editorPlugin = this.plugins.get<EditorPlugin>('editor')\r\n const gizmoPlugin = this.plugins.get<any>('gizmo')\r\n\r\n switch (key) {\r\n case 'stats':\r\n if (gizmoPlugin) {\r\n gizmoPlugin.setStatsVisible(value)\r\n }\r\n break\r\n case 'axes':\r\n if (gizmoPlugin) {\r\n gizmoPlugin.setAxesVisible(value)\r\n }\r\n break\r\n case 'grid':\r\n if (gizmoPlugin) {\r\n gizmoPlugin.setGridVisible(value)\r\n }\r\n break\r\n case 'openKey':\r\n if (editorPlugin) {\r\n editorPlugin.config.enableKeyboard = value\r\n }\r\n break\r\n }\r\n }\r\n\r\n /**\r\n * 设置场景分类\r\n */\r\n setSceneFromClassify(type: string): void {\r\n // 根据类型显示/隐藏场景物体\r\n this.scene.children.forEach(child => {\r\n const extChild = child as ExtendedObject3D\r\n if (extChild.rootInfo) {\r\n // 根据分类设置可见性\r\n // TODO: 实现完整的分类逻辑\r\n }\r\n })\r\n }\r\n\r\n /**\r\n * 点位同步变换\r\n */\r\n pointSyncTransform(point: THREE.Vector3, mesh: THREE.Object3D): THREE.Vector3 {\r\n const result = point.clone()\r\n result.applyMatrix4(mesh.matrixWorld)\r\n return result\r\n }\r\n\r\n /**\r\n * 克隆材质\r\n */\r\n meshGroupCloneMaterial(object: THREE.Object3D): void {\r\n object.traverse(child => {\r\n if ((child as THREE.Mesh).isMesh) {\r\n const mesh = child as THREE.Mesh\r\n const extMesh = mesh as unknown as ExtendedObject3D\r\n \r\n if (!extMesh.isCloneMaterial) {\r\n extMesh.originMaterial = mesh.material\r\n mesh.material = Array.isArray(mesh.material)\r\n ? mesh.material.map(m => m.clone())\r\n : mesh.material.clone()\r\n extMesh.isCloneMaterial = true\r\n }\r\n }\r\n })\r\n }\r\n\r\n /**\r\n * 修改物体材质\r\n */\r\n changeMeshMaterial(object: THREE.Object3D, params: Record<string, any>): void {\r\n object.traverse(child => {\r\n if ((child as THREE.Mesh).isMesh) {\r\n const mesh = child as THREE.Mesh\r\n const materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material]\r\n \r\n materials.forEach(material => {\r\n Object.entries(params).forEach(([key, value]) => {\r\n if (key in material) {\r\n if (key === 'color' || key === 'emissive') {\r\n (material as any)[key].set(value)\r\n } else {\r\n (material as any)[key] = value\r\n }\r\n }\r\n })\r\n material.needsUpdate = true\r\n })\r\n }\r\n })\r\n }\r\n\r\n /**\r\n * 修改物体变换\r\n */\r\n changeMeshTransform(object: THREE.Object3D, params: { position?: any; rotation?: any; scale?: any }): void {\r\n const extObj = object as unknown as ExtendedObject3D\r\n \r\n // 保存原始变换\r\n if (!extObj.meshRevertTransform) {\r\n const origPos = object.position.clone()\r\n const origRot = object.rotation.clone()\r\n const origScale = object.scale.clone()\r\n \r\n extObj.meshRevertTransform = () => {\r\n object.position.copy(origPos)\r\n object.rotation.copy(origRot)\r\n object.scale.copy(origScale)\r\n }\r\n }\r\n\r\n if (params.position) {\r\n object.position.set(params.position.x ?? object.position.x, params.position.y ?? object.position.y, params.position.z ?? object.position.z)\r\n }\r\n if (params.rotation) {\r\n object.rotation.set(params.rotation.x ?? object.rotation.x, params.rotation.y ?? object.rotation.y, params.rotation.z ?? object.rotation.z)\r\n }\r\n if (params.scale) {\r\n object.scale.set(params.scale.x ?? object.scale.x, params.scale.y ?? object.scale.y, params.scale.z ?? object.scale.z)\r\n }\r\n }\r\n\r\n /**\r\n * 执行 GSAP 物体动作\r\n */\r\n setGsapMeshAction(\r\n mesh: THREE.Object3D,\r\n fromTransform: any,\r\n toTransform: any,\r\n gsapParams: { mode?: string; query: GsapQuery }\r\n ): void {\r\n const { query } = gsapParams\r\n\r\n // 位置动画\r\n if (fromTransform.position && toTransform.position) {\r\n mesh.position.set(fromTransform.position.x, fromTransform.position.y, fromTransform.position.z)\r\n gsap.to(mesh.position, {\r\n x: toTransform.position.x,\r\n y: toTransform.position.y,\r\n z: toTransform.position.z,\r\n ...query\r\n })\r\n }\r\n\r\n // 旋转动画\r\n if (fromTransform.rotation && toTransform.rotation) {\r\n mesh.rotation.set(fromTransform.rotation.x, fromTransform.rotation.y, fromTransform.rotation.z)\r\n gsap.to(mesh.rotation, {\r\n x: toTransform.rotation.x,\r\n y: toTransform.rotation.y,\r\n z: toTransform.rotation.z,\r\n ...query\r\n })\r\n }\r\n\r\n // 缩放动画\r\n if (fromTransform.scale && toTransform.scale) {\r\n mesh.scale.set(fromTransform.scale.x, fromTransform.scale.y, fromTransform.scale.z)\r\n gsap.to(mesh.scale, {\r\n x: toTransform.scale.x,\r\n y: toTransform.scale.y,\r\n z: toTransform.scale.z,\r\n ...query\r\n })\r\n }\r\n }\r\n\r\n // ============ 生命周期 ============\r\n\r\n /**\r\n * 启动\r\n */\r\n start(): void {\r\n this.engine.start()\r\n }\r\n\r\n /**\r\n * 停止\r\n */\r\n stop(): void {\r\n this.engine.stop()\r\n }\r\n\r\n /**\r\n * 销毁\r\n */\r\n dispose(): void {\r\n this.plugins.dispose()\r\n this.engine.dispose()\r\n this.progressList = []\r\n this.mixerList = []\r\n this.shaderList = []\r\n this.commonFrameList = []\r\n }\r\n}\r\n","import * as THREE from 'three'\r\n\r\n/**\r\n * 释放网格资源\r\n * @param mesh 网格\r\n */\r\nexport function disposeMesh(mesh: THREE.Mesh): void {\r\n mesh.geometry?.dispose()\r\n\r\n if (Array.isArray(mesh.material)) {\r\n mesh.material.forEach(disposeMaterial)\r\n } else if (mesh.material) {\r\n disposeMaterial(mesh.material)\r\n }\r\n}\r\n\r\n/**\r\n * 释放材质资源\r\n * @param material 材质\r\n */\r\nexport function disposeMaterial(material: THREE.Material): void {\r\n material.dispose()\r\n\r\n // 释放纹理\r\n const mat = material as any\r\n if (mat.map) mat.map.dispose()\r\n if (mat.lightMap) mat.lightMap.dispose()\r\n if (mat.bumpMap) mat.bumpMap.dispose()\r\n if (mat.normalMap) mat.normalMap.dispose()\r\n if (mat.specularMap) mat.specularMap.dispose()\r\n if (mat.envMap) mat.envMap.dispose()\r\n if (mat.alphaMap) mat.alphaMap.dispose()\r\n if (mat.aoMap) mat.aoMap.dispose()\r\n if (mat.displacementMap) mat.displacementMap.dispose()\r\n if (mat.emissiveMap) mat.emissiveMap.dispose()\r\n if (mat.gradientMap) mat.gradientMap.dispose()\r\n if (mat.metalnessMap) mat.metalnessMap.dispose()\r\n if (mat.roughnessMap) mat.roughnessMap.dispose()\r\n}\r\n\r\n/**\r\n * 释放物体及其子物体的资源\r\n * @param object 物体\r\n */\r\nexport function disposeObject(object: THREE.Object3D): void {\r\n object.traverse((child) => {\r\n if ((child as THREE.Mesh).isMesh) {\r\n disposeMesh(child as THREE.Mesh)\r\n }\r\n })\r\n}\r\n\r\n/**\r\n * 释放场景资源\r\n * @param scene 场景\r\n */\r\nexport function disposeScene(scene: THREE.Scene): void {\r\n scene.traverse((object) => {\r\n if ((object as THREE.Mesh).isMesh) {\r\n disposeMesh(object as THREE.Mesh)\r\n }\r\n })\r\n\r\n // 清空场景\r\n while (scene.children.length > 0) {\r\n scene.remove(scene.children[0])\r\n }\r\n\r\n // 释放背景和环境\r\n if (scene.background instanceof THREE.Texture) {\r\n scene.background.dispose()\r\n }\r\n if (scene.environment) {\r\n scene.environment.dispose()\r\n }\r\n}\r\n"],"names":["EventEmitter","constructor","this","listeners","Map","event","callback","has","set","Set","listener","once","get","add","delete","data","toRemove","error","push","size","removeAllListeners","clear","SceneManager","events","_envBackground","_environmentEnabled","envMapChangeCallbacks","ssrMeshList","scene","THREE","Scene","name","envBackground","value","updateEnvironment","forEach","cb","environment","index","indexOf","splice","background","emit","urls","Promise","resolve","reject","CubeTextureLoader","load","texture","objects","object","parent","remove","getObjectByName","id","getObjectById","traverse","meshes","Mesh","getLights","lights","Light","children","length","child","dispose","geometry","Array","isArray","material","m","map","DEFAULT_CAMERA_CONFIG","fov","near","far","position","x","y","z","CameraManager","container","config","aspect","clientWidth","clientHeight","camera","PerspectiveCamera","updateProjectionMatrix","target","Vector3","lookAt","getWorldDirection","direction","distance","clone","multiplyScalar","getConfig","DEFAULT_RENDERER_CONFIG","pixelRatio","window","Math","min","devicePixelRatio","antialias","alpha","logarithmicDepthBuffer","preserveDrawingBuffer","powerPreference","toneMapping","NoToneMapping","toneMappingExposure","outputColorSpace","SRGBColorSpace","shadowMapEnabled","shadowMapType","PCFSoftShadowMap","RendererManager","renderer","WebGLRenderer","setSize","setPixelRatio","shadowMap","enabled","type","appendChild","domElement","getPixelRatio","limitedValue","getSize","Vector2","width","height","updateSize","render","quality","toDataURL","exposure","setShadowMapEnabled","setShadowMapType","getInfo","info","resetInfo","reset","forceContextLoss","parentNode","removeChild","DEFAULT_ENGINE_CONFIG","autoResize","fps","autoStart","Engine","animationId","_isRunning","frameCallbacks","fpsInterval","lastFrameTime","resizeHandler","animate","requestAnimationFrame","now","performance","elapsed","delta","clock","getDelta","elapsedTime","getElapsedTime","Clock","sceneManager","cameraManager","rendererManager","setupAutoResize","start","isRunning","resize","addEventListener","stop","cancelAnimationFrame","updateAspect","getScreenshot","getFPS","removeEventListener","dracoPath","ThreeEditor","progressList","commonFrameList","mixerList","shaderList","getDistanceScalePoint","getBestViewTarget","engine","plugins","PluginManager","installCorePlugins","onUpdate","sceneParams","restoreScene","meshListParams","item","setModelFromInfo","rootInfo","group","skyParams","setSky","setGlobalEnvBackground","path","gsap","orbitPlugin","transformPlugin","composerPlugin","cssPlugin","editorPlugin","loaderPlugin","guiPlugin","controls","transformControls","Composer","CSS2DObject","CSS3DObject","MixerList","ShaderList","CommonFrameList","handler","modelControls","currentInfo","GUI","gui","renderSceneResize","destroySceneRender","saveSceneEditor","use","OrbitControllerPlugin","TransformControllerPlugin","LoaderPlugin","ComposerPlugin","CSSRendererPlugin","EditorPlugin","GizmoPlugin","grid","divisions","colorCenterLine","colorGrid","axes","stats","mode","viewHelper","box3Helper","color","guiConfig","useProxy","GUIPlugin","autoPlace","mixer","mixerRender","shader","ShaderAnimateRender","anim","frameAnimationRender","plugin","params","Error","loaderService","loadModel","originalComplete","complete","model","setSkybox","setEnvironmentMap","then","environmentEnabled","dom","style","pointerEvents","addCSS2D","addCSS3D","handleClick","getRawSceneEvent","raycaster","Raycaster","mouse","getIntersects","rect","getBoundingClientRect","clientX","left","clientY","top","setFromCamera","intersectObjects","query","to","duration","ease","repeat","yoyo","yoyoEase","animationPlayParams","animations","speed","actionIndexs","startTime","loop","AnimationMixer","actions","filter","_","clip","action","clipAction","LoopRepeat","LoopOnce","time","timeScale","clampWhenFinished","play","update","findIndex","curve","controller","Date","pause","frameCallback","frameEndCallback","includes","destroy","point","getPointAt","meshList","setOutlineObjects","setMode","key","hasOwnProperty","getObjectViews","getSceneCurveList","i","isCurveMesh","curvePath","parameters","mesh","saveCallback","screenshot","updateDisplay","guiDom","GUIDom","parentElement","gizmoPlugin","setStatsVisible","setAxesVisible","setGridVisible","enableKeyboard","result","applyMatrix4","matrixWorld","isMesh","extMesh","isCloneMaterial","originMaterial","Object","entries","needsUpdate","extObj","meshRevertTransform","origPos","origRot","rotation","origScale","scale","copy","fromTransform","toTransform","gsapParams","disposeMesh","disposeMaterial","mat","lightMap","bumpMap","normalMap","specularMap","envMap","alphaMap","aoMap","displacementMap","emissiveMap","gradientMap","metalnessMap","roughnessMap","disposeObject","disposeScene","Texture"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/core/EventEmitter.ts","../src/core/Scene.ts","../src/core/Camera.ts","../src/core/Renderer.ts","../src/core/Engine.ts","../node_modules/three-mesh-bvh/src/utils/StaticGeometryGenerator.js","../src/ThreeEditor.ts","../src/utils/dispose.ts"],"sourcesContent":["import type { Unsubscribe } from '../types/event.types'\r\n\r\n/**\r\n * 事件发射器\r\n * 提供类型安全的事件订阅和发布机制\r\n */\r\nexport class EventEmitter<TEventMap extends Record<string, any> = Record<string, any>> {\r\n private listeners = new Map<keyof TEventMap, Set<{ callback: Function; once: boolean }>>()\r\n\r\n /**\r\n * 订阅事件\r\n * @param event 事件名称\r\n * @param callback 回调函数\r\n * @returns 取消订阅函数\r\n */\r\n on<K extends keyof TEventMap>(event: K, callback: (data: TEventMap[K]) => void): Unsubscribe {\r\n if (!this.listeners.has(event)) {\r\n this.listeners.set(event, new Set())\r\n }\r\n const listener = { callback, once: false }\r\n this.listeners.get(event)!.add(listener)\r\n\r\n return () => {\r\n this.listeners.get(event)?.delete(listener)\r\n }\r\n }\r\n\r\n /**\r\n * 订阅一次性事件\r\n * @param event 事件名称\r\n * @param callback 回调函数\r\n * @returns 取消订阅函数\r\n */\r\n once<K extends keyof TEventMap>(event: K, callback: (data: TEventMap[K]) => void): Unsubscribe {\r\n if (!this.listeners.has(event)) {\r\n this.listeners.set(event, new Set())\r\n }\r\n const listener = { callback, once: true }\r\n this.listeners.get(event)!.add(listener)\r\n\r\n return () => {\r\n this.listeners.get(event)?.delete(listener)\r\n }\r\n }\r\n\r\n /**\r\n * 取消订阅事件\r\n * @param event 事件名称\r\n * @param callback 回调函数(可选,不传则移除该事件所有监听器)\r\n */\r\n off<K extends keyof TEventMap>(event: K, callback?: (data: TEventMap[K]) => void): void {\r\n if (!callback) {\r\n this.listeners.delete(event)\r\n return\r\n }\r\n\r\n const listeners = this.listeners.get(event)\r\n if (listeners) {\r\n for (const listener of listeners) {\r\n if (listener.callback === callback) {\r\n listeners.delete(listener)\r\n break\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 发射事件\r\n * @param event 事件名称\r\n * @param data 事件数据\r\n */\r\n emit<K extends keyof TEventMap>(event: K, data?: TEventMap[K]): void {\r\n const listeners = this.listeners.get(event)\r\n if (!listeners) return\r\n\r\n const toRemove: { callback: Function; once: boolean }[] = []\r\n\r\n for (const listener of listeners) {\r\n try {\r\n listener.callback(data)\r\n } catch (error) {\r\n console.error(`Error in event listener for \"${String(event)}\":`, error)\r\n }\r\n\r\n if (listener.once) {\r\n toRemove.push(listener)\r\n }\r\n }\r\n\r\n // 移除一次性监听器\r\n for (const listener of toRemove) {\r\n listeners.delete(listener)\r\n }\r\n }\r\n\r\n /**\r\n * 检查是否有监听器\r\n * @param event 事件名称\r\n */\r\n hasListeners<K extends keyof TEventMap>(event: K): boolean {\r\n const listeners = this.listeners.get(event)\r\n return listeners !== undefined && listeners.size > 0\r\n }\r\n\r\n /**\r\n * 获取监听器数量\r\n * @param event 事件名称\r\n */\r\n listenerCount<K extends keyof TEventMap>(event: K): number {\r\n return this.listeners.get(event)?.size ?? 0\r\n }\r\n\r\n /**\r\n * 移除所有监听器\r\n */\r\n removeAllListeners(): void {\r\n this.listeners.clear()\r\n }\r\n\r\n /**\r\n * 销毁\r\n */\r\n dispose(): void {\r\n this.removeAllListeners()\r\n }\r\n}\r\n","import * as THREE from 'three'\r\nimport type { EventEmitter } from './EventEmitter'\r\nimport type { EventMap } from '../types/event.types'\r\n\r\n/**\r\n * 场景管理器\r\n * 封装 THREE.Scene,提供扩展功能\r\n */\r\nexport class SceneManager {\r\n /** Three.js 场景实例 */\r\n readonly scene: THREE.Scene\r\n\r\n /** 环境贴图 */\r\n private _envBackground: THREE.CubeTexture | THREE.Texture | null = null\r\n\r\n /** 是否启用环境贴图 */\r\n private _environmentEnabled = false\r\n\r\n /** 环境贴图变化回调列表 */\r\n private envMapChangeCallbacks: Array<() => void> = []\r\n\r\n /** SSR 网格列表 */\r\n readonly ssrMeshList: THREE.Mesh[] = []\r\n\r\n constructor(private events: EventEmitter<EventMap>) {\r\n this.scene = new THREE.Scene()\r\n this.scene.name = 'MainScene'\r\n }\r\n\r\n /**\r\n * 获取环境贴图\r\n */\r\n get envBackground(): THREE.CubeTexture | THREE.Texture | null {\r\n return this._envBackground\r\n }\r\n\r\n /**\r\n * 设置环境贴图\r\n */\r\n set envBackground(value: THREE.CubeTexture | THREE.Texture | null) {\r\n this._envBackground = value\r\n this.updateEnvironment()\r\n this.envMapChangeCallbacks.forEach(cb => cb())\r\n }\r\n\r\n /**\r\n * 获取是否启用环境贴图\r\n */\r\n get environmentEnabled(): boolean {\r\n return this._environmentEnabled\r\n }\r\n\r\n /**\r\n * 设置是否启用环境贴图\r\n */\r\n set environmentEnabled(value: boolean) {\r\n this._environmentEnabled = value\r\n this.updateEnvironment()\r\n }\r\n\r\n /**\r\n * 更新环境贴图\r\n */\r\n private updateEnvironment(): void {\r\n this.scene.environment = this._environmentEnabled ? this._envBackground : null\r\n }\r\n\r\n /**\r\n * 注册环境贴图变化回调\r\n */\r\n onEnvMapChange(callback: () => void): () => void {\r\n this.envMapChangeCallbacks.push(callback)\r\n return () => {\r\n const index = this.envMapChangeCallbacks.indexOf(callback)\r\n if (index > -1) {\r\n this.envMapChangeCallbacks.splice(index, 1)\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 设置背景\r\n */\r\n setBackground(background: THREE.Color | THREE.Texture | THREE.CubeTexture | null): void {\r\n this.scene.background = background\r\n this.events.emit('scene:background:change', { background })\r\n }\r\n\r\n /**\r\n * 设置天空盒\r\n * @param urls 六张图片的 URL 数组 [px, nx, py, ny, pz, nz]\r\n */\r\n setSkybox(urls: string[]): Promise<THREE.CubeTexture> {\r\n return new Promise((resolve, reject) => {\r\n const loader = new THREE.CubeTextureLoader()\r\n loader.load(\r\n urls,\r\n (texture) => {\r\n this.scene.background = texture\r\n this.events.emit('scene:background:change', { background: texture })\r\n resolve(texture)\r\n },\r\n undefined,\r\n reject\r\n )\r\n })\r\n }\r\n\r\n /**\r\n * 设置环境贴图\r\n * @param urls 六张图片的 URL 数组\r\n */\r\n setEnvironmentMap(urls: string[]): Promise<THREE.CubeTexture> {\r\n return new Promise((resolve, reject) => {\r\n const loader = new THREE.CubeTextureLoader()\r\n loader.load(\r\n urls,\r\n (texture) => {\r\n this.envBackground = texture\r\n resolve(texture)\r\n },\r\n undefined,\r\n reject\r\n )\r\n })\r\n }\r\n\r\n /**\r\n * 添加物体到场景\r\n */\r\n add(...objects: THREE.Object3D[]): void {\r\n for (const object of objects) {\r\n this.scene.add(object)\r\n this.events.emit('object:added', { object, parent: this.scene })\r\n }\r\n }\r\n\r\n /**\r\n * 从场景移除物体\r\n */\r\n remove(...objects: THREE.Object3D[]): void {\r\n for (const object of objects) {\r\n this.scene.remove(object)\r\n this.events.emit('object:removed', { object, parent: this.scene })\r\n }\r\n }\r\n\r\n /**\r\n * 根据名称获取物体\r\n */\r\n getObjectByName(name: string): THREE.Object3D | undefined {\r\n return this.scene.getObjectByName(name)\r\n }\r\n\r\n /**\r\n * 根据 ID 获取物体\r\n */\r\n getObjectById(id: number): THREE.Object3D | undefined {\r\n return this.scene.getObjectById(id)\r\n }\r\n\r\n /**\r\n * 遍历场景中的所有物体\r\n */\r\n traverse(callback: (object: THREE.Object3D) => void): void {\r\n this.scene.traverse(callback)\r\n }\r\n\r\n /**\r\n * 获取场景中的所有网格\r\n */\r\n getMeshes(): THREE.Mesh[] {\r\n const meshes: THREE.Mesh[] = []\r\n this.scene.traverse((object) => {\r\n if (object instanceof THREE.Mesh) {\r\n meshes.push(object)\r\n }\r\n })\r\n return meshes\r\n }\r\n\r\n /**\r\n * 获取场景中的所有灯光\r\n */\r\n getLights(): THREE.Light[] {\r\n const lights: THREE.Light[] = []\r\n this.scene.traverse((object) => {\r\n if (object instanceof THREE.Light) {\r\n lights.push(object)\r\n }\r\n })\r\n return lights\r\n }\r\n\r\n /**\r\n * 清空场景\r\n */\r\n clear(): void {\r\n while (this.scene.children.length > 0) {\r\n const child = this.scene.children[0]\r\n this.scene.remove(child)\r\n this.events.emit('object:removed', { object: child, parent: this.scene })\r\n }\r\n }\r\n\r\n /**\r\n * 销毁场景\r\n */\r\n dispose(): void {\r\n this.scene.traverse((object) => {\r\n if (object instanceof THREE.Mesh) {\r\n object.geometry?.dispose()\r\n if (Array.isArray(object.material)) {\r\n object.material.forEach(m => {\r\n m.dispose()\r\n if ('map' in m && m.map) {\r\n (m.map as THREE.Texture).dispose()\r\n }\r\n })\r\n } else if (object.material) {\r\n object.material.dispose()\r\n if ('map' in object.material && object.material.map) {\r\n (object.material.map as THREE.Texture).dispose()\r\n }\r\n }\r\n }\r\n })\r\n\r\n this.clear()\r\n this.envMapChangeCallbacks = []\r\n this.ssrMeshList.length = 0\r\n }\r\n}\r\n","import * as THREE from 'three'\r\nimport type { CameraConfig } from '../types/config.types'\r\nimport type { EventEmitter } from './EventEmitter'\r\nimport type { EventMap } from '../types/event.types'\r\n\r\n/**\r\n * 默认相机配置\r\n */\r\nexport const DEFAULT_CAMERA_CONFIG: CameraConfig = {\r\n fov: 50,\r\n near: 0.1,\r\n far: 100000,\r\n position: { x: 10, y: 10, z: 10 }\r\n}\r\n\r\n/**\r\n * 相机管理器\r\n * 封装 THREE.PerspectiveCamera,提供扩展功能\r\n */\r\nexport class CameraManager {\r\n /** Three.js 相机实例 */\r\n readonly camera: THREE.PerspectiveCamera\r\n\r\n /** 配置 */\r\n private config: CameraConfig\r\n\r\n constructor(\r\n private container: HTMLElement,\r\n private events: EventEmitter<EventMap>,\r\n config?: Partial<CameraConfig>\r\n ) {\r\n this.config = { ...DEFAULT_CAMERA_CONFIG, ...config }\r\n\r\n const aspect = container.clientWidth / container.clientHeight\r\n\r\n this.camera = new THREE.PerspectiveCamera(\r\n this.config.fov,\r\n aspect,\r\n this.config.near,\r\n this.config.far\r\n )\r\n\r\n this.camera.name = 'MainCamera'\r\n this.camera.position.set(\r\n this.config.position.x,\r\n this.config.position.y,\r\n this.config.position.z\r\n )\r\n }\r\n\r\n /**\r\n * 获取相机位置\r\n */\r\n get position(): THREE.Vector3 {\r\n return this.camera.position\r\n }\r\n\r\n /**\r\n * 获取相机视野角度\r\n */\r\n get fov(): number {\r\n return this.camera.fov\r\n }\r\n\r\n /**\r\n * 设置相机视野角度\r\n */\r\n set fov(value: number) {\r\n this.camera.fov = value\r\n this.camera.updateProjectionMatrix()\r\n this.events.emit('camera:change', { camera: this.camera })\r\n }\r\n\r\n /**\r\n * 获取近裁剪面\r\n */\r\n get near(): number {\r\n return this.camera.near\r\n }\r\n\r\n /**\r\n * 设置近裁剪面\r\n */\r\n set near(value: number) {\r\n this.camera.near = value\r\n this.camera.updateProjectionMatrix()\r\n this.events.emit('camera:change', { camera: this.camera })\r\n }\r\n\r\n /**\r\n * 获取远裁剪面\r\n */\r\n get far(): number {\r\n return this.camera.far\r\n }\r\n\r\n /**\r\n * 设置远裁剪面\r\n */\r\n set far(value: number) {\r\n this.camera.far = value\r\n this.camera.updateProjectionMatrix()\r\n this.events.emit('camera:change', { camera: this.camera })\r\n }\r\n\r\n /**\r\n * 设置相机位置\r\n */\r\n setPosition(x: number, y: number, z: number): void {\r\n this.camera.position.set(x, y, z)\r\n this.events.emit('camera:change', { camera: this.camera })\r\n }\r\n\r\n /**\r\n * 让相机看向目标点\r\n */\r\n lookAt(target: THREE.Vector3 | { x: number; y: number; z: number }): void {\r\n if (target instanceof THREE.Vector3) {\r\n this.camera.lookAt(target)\r\n } else {\r\n this.camera.lookAt(target.x, target.y, target.z)\r\n }\r\n this.events.emit('camera:change', { camera: this.camera })\r\n }\r\n\r\n /**\r\n * 更新相机宽高比\r\n */\r\n updateAspect(): void {\r\n this.camera.aspect = this.container.clientWidth / this.container.clientHeight\r\n this.camera.updateProjectionMatrix()\r\n }\r\n\r\n /**\r\n * 获取相机世界方向\r\n */\r\n getWorldDirection(): THREE.Vector3 {\r\n const direction = new THREE.Vector3()\r\n this.camera.getWorldDirection(direction)\r\n return direction\r\n }\r\n\r\n /**\r\n * 获取相机前方指定距离的点\r\n */\r\n getTargetPoint(distance: number): THREE.Vector3 {\r\n const direction = this.getWorldDirection()\r\n return this.camera.position.clone().add(direction.multiplyScalar(distance))\r\n }\r\n\r\n /**\r\n * 获取相机配置\r\n */\r\n getConfig(): CameraConfig {\r\n return {\r\n fov: this.camera.fov,\r\n near: this.camera.near,\r\n far: this.camera.far,\r\n position: {\r\n x: this.camera.position.x,\r\n y: this.camera.position.y,\r\n z: this.camera.position.z\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 应用配置\r\n */\r\n applyConfig(config: Partial<CameraConfig>): void {\r\n if (config.fov !== undefined) {\r\n this.camera.fov = config.fov\r\n }\r\n if (config.near !== undefined) {\r\n this.camera.near = config.near\r\n }\r\n if (config.far !== undefined) {\r\n this.camera.far = config.far\r\n }\r\n if (config.position) {\r\n this.camera.position.set(\r\n config.position.x,\r\n config.position.y,\r\n config.position.z\r\n )\r\n }\r\n this.camera.updateProjectionMatrix()\r\n this.events.emit('camera:change', { camera: this.camera })\r\n }\r\n\r\n /**\r\n * 销毁\r\n */\r\n dispose(): void {\r\n // 相机本身不需要特殊清理\r\n }\r\n}\r\n","import * as THREE from 'three'\r\nimport type { RendererConfig } from '../types/config.types'\r\nimport type { EventEmitter } from './EventEmitter'\r\nimport type { EventMap } from '../types/event.types'\r\n\r\n/**\r\n * 默认渲染器配置\r\n * 注意:像素比默认限制为 2,避免高 DPI 设备性能问题\r\n */\r\nexport const DEFAULT_RENDERER_CONFIG: RendererConfig = {\r\n pixelRatio: typeof window !== 'undefined' ? Math.min(window.devicePixelRatio, 2) : 1,\r\n antialias: true,\r\n alpha: true,\r\n logarithmicDepthBuffer: true,\r\n preserveDrawingBuffer: false,\r\n powerPreference: 'high-performance',\r\n toneMapping: THREE.NoToneMapping,\r\n toneMappingExposure: 1,\r\n outputColorSpace: THREE.SRGBColorSpace,\r\n shadowMapEnabled: false,\r\n shadowMapType: THREE.PCFSoftShadowMap\r\n}\r\n\r\n/**\r\n * 渲染器管理器\r\n * 封装 THREE.WebGLRenderer,提供扩展功能\r\n */\r\nexport class RendererManager {\r\n /** Three.js 渲染器实例 */\r\n readonly renderer: THREE.WebGLRenderer\r\n\r\n /** 配置 */\r\n private config: RendererConfig\r\n\r\n constructor(\r\n private container: HTMLElement,\r\n private events: EventEmitter<EventMap>,\r\n config?: Partial<RendererConfig>\r\n ) {\r\n this.config = { ...DEFAULT_RENDERER_CONFIG, ...config }\r\n \r\n // 限制像素比最大为 2\r\n this.config.pixelRatio = Math.min(this.config.pixelRatio, 2)\r\n\r\n this.renderer = new THREE.WebGLRenderer({\r\n antialias: this.config.antialias,\r\n alpha: this.config.alpha,\r\n logarithmicDepthBuffer: this.config.logarithmicDepthBuffer,\r\n preserveDrawingBuffer: this.config.preserveDrawingBuffer,\r\n powerPreference: this.config.powerPreference\r\n })\r\n\r\n this.renderer.setSize(container.clientWidth, container.clientHeight)\r\n this.renderer.setPixelRatio(this.config.pixelRatio)\r\n this.renderer.toneMapping = this.config.toneMapping\r\n this.renderer.toneMappingExposure = this.config.toneMappingExposure\r\n this.renderer.outputColorSpace = this.config.outputColorSpace\r\n\r\n // 阴影配置\r\n this.renderer.shadowMap.enabled = this.config.shadowMapEnabled\r\n this.renderer.shadowMap.type = this.config.shadowMapType\r\n\r\n // 添加到容器\r\n container.appendChild(this.renderer.domElement)\r\n }\r\n\r\n /**\r\n * 获取 DOM 元素\r\n */\r\n get domElement(): HTMLCanvasElement {\r\n return this.renderer.domElement\r\n }\r\n\r\n /**\r\n * 获取像素比\r\n */\r\n get pixelRatio(): number {\r\n return this.renderer.getPixelRatio()\r\n }\r\n\r\n /**\r\n * 设置像素比\r\n * 限制最大值为 2,避免性能问题\r\n */\r\n set pixelRatio(value: number) {\r\n const limitedValue = Math.min(value, 2)\r\n this.renderer.setPixelRatio(limitedValue)\r\n this.config.pixelRatio = limitedValue\r\n }\r\n\r\n /**\r\n * 获取渲染器大小\r\n */\r\n getSize(): { width: number; height: number } {\r\n const size = new THREE.Vector2()\r\n this.renderer.getSize(size)\r\n return { width: size.x, height: size.y }\r\n }\r\n\r\n /**\r\n * 设置渲染器大小\r\n */\r\n setSize(width: number, height: number): void {\r\n this.renderer.setSize(width, height)\r\n this.events.emit('resize', { width, height })\r\n }\r\n\r\n /**\r\n * 更新大小以适应容器\r\n */\r\n updateSize(): void {\r\n const width = this.container.clientWidth\r\n const height = this.container.clientHeight\r\n this.setSize(width, height)\r\n }\r\n\r\n /**\r\n * 渲染场景\r\n */\r\n render(scene: THREE.Scene, camera: THREE.Camera): void {\r\n this.renderer.render(scene, camera)\r\n }\r\n\r\n /**\r\n * 获取截图\r\n */\r\n getScreenshot(type = 'image/png', quality = 0.9): string {\r\n return this.renderer.domElement.toDataURL(type, quality)\r\n }\r\n\r\n /**\r\n * 启用/禁用阴影\r\n */\r\n setShadowMapEnabled(enabled: boolean): void {\r\n this.renderer.shadowMap.enabled = enabled\r\n this.config.shadowMapEnabled = enabled\r\n }\r\n\r\n /**\r\n * 设置阴影类型\r\n */\r\n setShadowMapType(type: THREE.ShadowMapType): void {\r\n this.renderer.shadowMap.type = type\r\n this.config.shadowMapType = type\r\n }\r\n\r\n /**\r\n * 设置色调映射\r\n */\r\n setToneMapping(toneMapping: THREE.ToneMapping, exposure?: number): void {\r\n this.renderer.toneMapping = toneMapping\r\n this.config.toneMapping = toneMapping\r\n if (exposure !== undefined) {\r\n this.renderer.toneMappingExposure = exposure\r\n this.config.toneMappingExposure = exposure\r\n }\r\n }\r\n\r\n /**\r\n * 获取渲染器配置\r\n */\r\n getConfig(): RendererConfig {\r\n return { ...this.config }\r\n }\r\n\r\n /**\r\n * 应用配置\r\n */\r\n applyConfig(config: Partial<RendererConfig>): void {\r\n if (config.pixelRatio !== undefined) {\r\n this.pixelRatio = config.pixelRatio\r\n }\r\n if (config.toneMapping !== undefined) {\r\n this.renderer.toneMapping = config.toneMapping\r\n this.config.toneMapping = config.toneMapping\r\n }\r\n if (config.toneMappingExposure !== undefined) {\r\n this.renderer.toneMappingExposure = config.toneMappingExposure\r\n this.config.toneMappingExposure = config.toneMappingExposure\r\n }\r\n if (config.shadowMapEnabled !== undefined) {\r\n this.setShadowMapEnabled(config.shadowMapEnabled)\r\n }\r\n if (config.shadowMapType !== undefined) {\r\n this.setShadowMapType(config.shadowMapType)\r\n }\r\n }\r\n\r\n /**\r\n * 获取渲染信息\r\n */\r\n getInfo(): THREE.WebGLInfo {\r\n return this.renderer.info\r\n }\r\n\r\n /**\r\n * 清除渲染信息\r\n */\r\n resetInfo(): void {\r\n this.renderer.info.reset()\r\n }\r\n\r\n /**\r\n * 销毁\r\n */\r\n dispose(): void {\r\n this.renderer.dispose()\r\n this.renderer.forceContextLoss()\r\n if (this.renderer.domElement.parentNode) {\r\n this.renderer.domElement.parentNode.removeChild(this.renderer.domElement)\r\n }\r\n }\r\n}\r\n","import * as THREE from 'three'\r\nimport { EventEmitter } from './EventEmitter'\r\nimport { SceneManager } from './Scene'\r\nimport { CameraManager } from './Camera'\r\nimport { RendererManager } from './Renderer'\r\nimport type { EngineConfig } from '../types/config.types'\r\nimport type { EventMap } from '../types/event.types'\r\n\r\n/**\r\n * 默认引擎配置\r\n */\r\nexport const DEFAULT_ENGINE_CONFIG: Partial<EngineConfig> = {\r\n autoResize: true,\r\n fps: null,\r\n autoStart: true\r\n}\r\n\r\n/**\r\n * 帧回调函数类型\r\n */\r\ntype FrameCallback = (delta: number, elapsed: number) => void\r\n\r\n/**\r\n * 引擎核心\r\n * 管理场景、相机、渲染器和渲染循环\r\n */\r\nexport class Engine {\r\n /** 事件发射器 */\r\n readonly events: EventEmitter<EventMap>\r\n\r\n /** 场景管理器 */\r\n readonly sceneManager: SceneManager\r\n\r\n /** 相机管理器 */\r\n readonly cameraManager: CameraManager\r\n\r\n /** 渲染器管理器 */\r\n readonly rendererManager: RendererManager\r\n\r\n /** 时钟 */\r\n readonly clock: THREE.Clock\r\n\r\n /** 配置 */\r\n private config: EngineConfig\r\n\r\n /** 动画帧 ID */\r\n private animationId: number | null = null\r\n\r\n /** 是否正在运行 */\r\n private _isRunning = false\r\n\r\n /** 帧回调列表 */\r\n private frameCallbacks: Set<FrameCallback> = new Set()\r\n\r\n /** FPS 控制相关 */\r\n private fpsInterval: number = 0\r\n private lastFrameTime: number = 0\r\n\r\n /** 容器 */\r\n private container: HTMLElement\r\n\r\n /** 窗口大小变化处理函数 */\r\n private resizeHandler: (() => void) | null = null\r\n\r\n constructor(config: EngineConfig) {\r\n this.config = { ...DEFAULT_ENGINE_CONFIG, ...config } as EngineConfig\r\n this.container = config.container\r\n\r\n // 初始化事件系统\r\n this.events = new EventEmitter<EventMap>()\r\n\r\n // 初始化时钟\r\n this.clock = new THREE.Clock(false)\r\n\r\n // 初始化场景\r\n this.sceneManager = new SceneManager(this.events)\r\n\r\n // 初始化相机\r\n this.cameraManager = new CameraManager(\r\n this.container,\r\n this.events,\r\n config.camera\r\n )\r\n\r\n // 将相机添加到场景\r\n this.sceneManager.scene.add(this.cameraManager.camera)\r\n\r\n // 初始化渲染器\r\n this.rendererManager = new RendererManager(\r\n this.container,\r\n this.events,\r\n config.renderer\r\n )\r\n\r\n // FPS 控制\r\n if (this.config.fps !== undefined && this.config.fps !== null && this.config.fps > 0) {\r\n this.fpsInterval = 1000 / this.config.fps\r\n }\r\n\r\n // 自动调整大小\r\n if (this.config.autoResize) {\r\n this.setupAutoResize()\r\n }\r\n\r\n // 发射就绪事件\r\n this.events.emit('engine:ready', undefined)\r\n\r\n // 自动启动\r\n if (this.config.autoStart) {\r\n this.start()\r\n }\r\n }\r\n\r\n /**\r\n * 获取场景\r\n */\r\n get scene(): THREE.Scene {\r\n return this.sceneManager.scene\r\n }\r\n\r\n /**\r\n * 获取相机\r\n */\r\n get camera(): THREE.PerspectiveCamera {\r\n return this.cameraManager.camera\r\n }\r\n\r\n /**\r\n * 获取渲染器\r\n */\r\n get renderer(): THREE.WebGLRenderer {\r\n return this.rendererManager.renderer\r\n }\r\n\r\n /**\r\n * 获取 DOM 元素\r\n */\r\n get domElement(): HTMLCanvasElement {\r\n return this.rendererManager.domElement\r\n }\r\n\r\n /**\r\n * 是否正在运行\r\n */\r\n get isRunning(): boolean {\r\n return this._isRunning\r\n }\r\n\r\n /**\r\n * 设置自动调整大小\r\n */\r\n private setupAutoResize(): void {\r\n this.resizeHandler = () => this.resize()\r\n window.addEventListener('resize', this.resizeHandler)\r\n }\r\n\r\n /**\r\n * 启动渲染循环\r\n */\r\n start(): void {\r\n if (this._isRunning) return\r\n\r\n this._isRunning = true\r\n this.clock.start()\r\n this.lastFrameTime = performance.now()\r\n this.events.emit('engine:start', undefined)\r\n this.animate()\r\n }\r\n\r\n /**\r\n * 停止渲染循环\r\n */\r\n stop(): void {\r\n if (!this._isRunning) return\r\n\r\n this._isRunning = false\r\n this.clock.stop()\r\n\r\n if (this.animationId !== null) {\r\n cancelAnimationFrame(this.animationId)\r\n this.animationId = null\r\n }\r\n\r\n this.events.emit('engine:stop', undefined)\r\n }\r\n\r\n /**\r\n * 动画循环\r\n */\r\n private animate = (): void => {\r\n if (!this._isRunning) return\r\n\r\n this.animationId = requestAnimationFrame(this.animate)\r\n\r\n const now = performance.now()\r\n\r\n // FPS 控制\r\n if (this.fpsInterval > 0) {\r\n const elapsed = now - this.lastFrameTime\r\n if (elapsed < this.fpsInterval) return\r\n this.lastFrameTime = now - (elapsed % this.fpsInterval)\r\n }\r\n\r\n const delta = this.clock.getDelta()\r\n const elapsedTime = this.clock.getElapsedTime()\r\n\r\n // 发射渲染前事件\r\n this.events.emit('render:before', { delta, elapsed: elapsedTime })\r\n\r\n // 执行帧回调\r\n for (const callback of this.frameCallbacks) {\r\n try {\r\n callback(delta, elapsedTime)\r\n } catch (error) {\r\n console.error('Error in frame callback:', error)\r\n }\r\n }\r\n\r\n // 渲染\r\n this.render()\r\n\r\n // 发射渲染后事件\r\n this.events.emit('render:after', { delta, elapsed: elapsedTime })\r\n }\r\n\r\n /**\r\n * 渲染一帧\r\n */\r\n render(): void {\r\n this.rendererManager.render(this.scene, this.camera)\r\n }\r\n\r\n /**\r\n * 调整大小\r\n */\r\n resize(): void {\r\n const width = this.container.clientWidth\r\n const height = this.container.clientHeight\r\n\r\n this.cameraManager.updateAspect()\r\n this.rendererManager.setSize(width, height)\r\n\r\n this.events.emit('resize', { width, height })\r\n }\r\n\r\n /**\r\n * 注册帧回调\r\n * @param callback 每帧执行的回调函数\r\n * @returns 取消注册函数\r\n */\r\n onUpdate(callback: FrameCallback): () => void {\r\n this.frameCallbacks.add(callback)\r\n return () => {\r\n this.frameCallbacks.delete(callback)\r\n }\r\n }\r\n\r\n /**\r\n * 获取截图\r\n */\r\n screenshot(type?: string, quality?: number): string {\r\n // 确保渲染最新帧\r\n this.render()\r\n return this.rendererManager.getScreenshot(type, quality)\r\n }\r\n\r\n /**\r\n * 设置 FPS 限制\r\n */\r\n setFPS(fps: number | null): void {\r\n this.config.fps = fps\r\n if (fps !== null && fps > 0) {\r\n this.fpsInterval = 1000 / fps\r\n } else {\r\n this.fpsInterval = 0\r\n }\r\n }\r\n\r\n /**\r\n * 获取当前 FPS\r\n */\r\n getFPS(): number {\r\n return this.fpsInterval > 0 ? 1000 / this.fpsInterval : 0\r\n }\r\n\r\n /**\r\n * 销毁引擎\r\n */\r\n dispose(): void {\r\n this.events.emit('engine:dispose', undefined)\r\n\r\n // 停止渲染循环\r\n this.stop()\r\n\r\n // 移除窗口事件监听\r\n if (this.resizeHandler) {\r\n window.removeEventListener('resize', this.resizeHandler)\r\n this.resizeHandler = null\r\n }\r\n\r\n // 清空帧回调\r\n this.frameCallbacks.clear()\r\n\r\n // 销毁各管理器\r\n this.sceneManager.dispose()\r\n this.cameraManager.dispose()\r\n this.rendererManager.dispose()\r\n\r\n // 销毁事件系统\r\n this.events.dispose()\r\n }\r\n}\r\n","import { BufferAttribute, BufferGeometry, Vector3, Vector4, Matrix4, Matrix3 } from 'three';\n\nconst _positionVector = /*@__PURE__*/ new Vector3();\nconst _normalVector = /*@__PURE__*/ new Vector3();\nconst _tangentVector = /*@__PURE__*/ new Vector3();\nconst _tangentVector4 = /*@__PURE__*/ new Vector4();\n\nconst _morphVector = /*@__PURE__*/ new Vector3();\nconst _temp = /*@__PURE__*/ new Vector3();\n\nconst _skinIndex = /*@__PURE__*/ new Vector4();\nconst _skinWeight = /*@__PURE__*/ new Vector4();\nconst _matrix = /*@__PURE__*/ new Matrix4();\nconst _boneMatrix = /*@__PURE__*/ new Matrix4();\n\n// Confirms that the two provided attributes are compatible\nfunction validateAttributes( attr1, attr2 ) {\n\n\tif ( ! attr1 && ! attr2 ) {\n\n\t\treturn;\n\n\t}\n\n\tconst sameCount = attr1.count === attr2.count;\n\tconst sameNormalized = attr1.normalized === attr2.normalized;\n\tconst sameType = attr1.array.constructor === attr2.array.constructor;\n\tconst sameItemSize = attr1.itemSize === attr2.itemSize;\n\n\tif ( ! sameCount || ! sameNormalized || ! sameType || ! sameItemSize ) {\n\n\t\tthrow new Error();\n\n\t}\n\n}\n\n// Clones the given attribute with a new compatible buffer attribute but no data\nfunction createAttributeClone( attr, countOverride = null ) {\n\n\tconst cons = attr.array.constructor;\n\tconst normalized = attr.normalized;\n\tconst itemSize = attr.itemSize;\n\tconst count = countOverride === null ? attr.count : countOverride;\n\n\treturn new BufferAttribute( new cons( itemSize * count ), itemSize, normalized );\n\n}\n\n// target offset is the number of elements in the target buffer stride to skip before copying the\n// attributes contents in to.\nfunction copyAttributeContents( attr, target, targetOffset = 0 ) {\n\n\tif ( attr.isInterleavedBufferAttribute ) {\n\n\t\tconst itemSize = attr.itemSize;\n\t\tfor ( let i = 0, l = attr.count; i < l; i ++ ) {\n\n\t\t\tconst io = i + targetOffset;\n\t\t\ttarget.setX( io, attr.getX( i ) );\n\t\t\tif ( itemSize >= 2 ) target.setY( io, attr.getY( i ) );\n\t\t\tif ( itemSize >= 3 ) target.setZ( io, attr.getZ( i ) );\n\t\t\tif ( itemSize >= 4 ) target.setW( io, attr.getW( i ) );\n\n\t\t}\n\n\t} else {\n\n\t\tconst array = target.array;\n\t\tconst cons = array.constructor;\n\t\tconst byteOffset = array.BYTES_PER_ELEMENT * attr.itemSize * targetOffset;\n\t\tconst temp = new cons( array.buffer, byteOffset, attr.array.length );\n\t\ttemp.set( attr.array );\n\n\t}\n\n}\n\n// Adds the \"matrix\" multiplied by \"scale\" to \"target\"\nfunction addScaledMatrix( target, matrix, scale ) {\n\n\tconst targetArray = target.elements;\n\tconst matrixArray = matrix.elements;\n\tfor ( let i = 0, l = matrixArray.length; i < l; i ++ ) {\n\n\t\ttargetArray[ i ] += matrixArray[ i ] * scale;\n\n\t}\n\n}\n\n// A version of \"SkinnedMesh.boneTransform\" for normals\nfunction boneNormalTransform( mesh, index, target ) {\n\n\tconst skeleton = mesh.skeleton;\n\tconst geometry = mesh.geometry;\n\tconst bones = skeleton.bones;\n\tconst boneInverses = skeleton.boneInverses;\n\n\t_skinIndex.fromBufferAttribute( geometry.attributes.skinIndex, index );\n\t_skinWeight.fromBufferAttribute( geometry.attributes.skinWeight, index );\n\n\t_matrix.elements.fill( 0 );\n\n\tfor ( let i = 0; i < 4; i ++ ) {\n\n\t\tconst weight = _skinWeight.getComponent( i );\n\n\t\tif ( weight !== 0 ) {\n\n\t\t\tconst boneIndex = _skinIndex.getComponent( i );\n\t\t\t_boneMatrix.multiplyMatrices( bones[ boneIndex ].matrixWorld, boneInverses[ boneIndex ] );\n\n\t\t\taddScaledMatrix( _matrix, _boneMatrix, weight );\n\n\t\t}\n\n\t}\n\n\t_matrix.multiply( mesh.bindMatrix ).premultiply( mesh.bindMatrixInverse );\n\ttarget.transformDirection( _matrix );\n\n\treturn target;\n\n}\n\n// Applies the morph target data to the target vector\nfunction applyMorphTarget( morphData, morphInfluences, morphTargetsRelative, i, target ) {\n\n\t_morphVector.set( 0, 0, 0 );\n\tfor ( let j = 0, jl = morphData.length; j < jl; j ++ ) {\n\n\t\tconst influence = morphInfluences[ j ];\n\t\tconst morphAttribute = morphData[ j ];\n\n\t\tif ( influence === 0 ) continue;\n\n\t\t_temp.fromBufferAttribute( morphAttribute, i );\n\n\t\tif ( morphTargetsRelative ) {\n\n\t\t\t_morphVector.addScaledVector( _temp, influence );\n\n\t\t} else {\n\n\t\t\t_morphVector.addScaledVector( _temp.sub( target ), influence );\n\n\t\t}\n\n\t}\n\n\ttarget.add( _morphVector );\n\n}\n\n// Modified version of BufferGeometryUtils.mergeBufferGeometries that ignores morph targets and updates a attributes in place\nfunction mergeBufferGeometries( geometries, options = { useGroups: false, updateIndex: false, skipAttributes: [] }, targetGeometry = new BufferGeometry() ) {\n\n\tconst isIndexed = geometries[ 0 ].index !== null;\n\tconst { useGroups = false, updateIndex = false, skipAttributes = [] } = options;\n\n\tconst attributesUsed = new Set( Object.keys( geometries[ 0 ].attributes ) );\n\tconst attributes = {};\n\n\tlet offset = 0;\n\n\ttargetGeometry.clearGroups();\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\t\tif ( isIndexed !== ( geometry.index !== null ) ) {\n\n\t\t\tthrow new Error( 'StaticGeometryGenerator: All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them.' );\n\n\t\t}\n\n\t\t// gather attributes, exit early if they're different\n\t\tfor ( const name in geometry.attributes ) {\n\n\t\t\tif ( ! attributesUsed.has( name ) ) {\n\n\t\t\t\tthrow new Error( 'StaticGeometryGenerator: All geometries must have compatible attributes; make sure \"' + name + '\" attribute exists among all geometries, or in none of them.' );\n\n\t\t\t}\n\n\t\t\tif ( attributes[ name ] === undefined ) {\n\n\t\t\t\tattributes[ name ] = [];\n\n\t\t\t}\n\n\t\t\tattributes[ name ].push( geometry.attributes[ name ] );\n\t\t\tattributesCount ++;\n\n\t\t}\n\n\t\t// ensure geometries have the same number of attributes\n\t\tif ( attributesCount !== attributesUsed.size ) {\n\n\t\t\tthrow new Error( 'StaticGeometryGenerator: Make sure all geometries have the same number of attributes.' );\n\n\t\t}\n\n\t\tif ( useGroups ) {\n\n\t\t\tlet count;\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\tthrow new Error( 'StaticGeometryGenerator: The geometry must have either an index or a position attribute' );\n\n\t\t\t}\n\n\t\t\ttargetGeometry.addGroup( offset, count, i );\n\t\t\toffset += count;\n\n\t\t}\n\n\t}\n\n\t// merge indices\n\tif ( isIndexed ) {\n\n\t\tlet forceUpdateIndex = false;\n\t\tif ( ! targetGeometry.index ) {\n\n\t\t\tlet indexCount = 0;\n\t\t\tfor ( let i = 0; i < geometries.length; ++ i ) {\n\n\t\t\t\tindexCount += geometries[ i ].index.count;\n\n\t\t\t}\n\n\t\t\ttargetGeometry.setIndex( new BufferAttribute( new Uint32Array( indexCount ), 1, false ) );\n\t\t\tforceUpdateIndex = true;\n\n\t\t}\n\n\t\tif ( updateIndex || forceUpdateIndex ) {\n\n\t\t\tconst targetIndex = targetGeometry.index;\n\t\t\tlet targetOffset = 0;\n\t\t\tlet indexOffset = 0;\n\t\t\tfor ( let i = 0; i < geometries.length; ++ i ) {\n\n\t\t\t\tconst geometry = geometries[ i ];\n\t\t\t\tconst index = geometry.index;\n\t\t\t\tif ( skipAttributes[ i ] !== true ) {\n\n\t\t\t\t\tfor ( let j = 0; j < index.count; ++ j ) {\n\n\t\t\t\t\t\ttargetIndex.setX( targetOffset, index.getX( j ) + indexOffset );\n\t\t\t\t\t\ttargetOffset ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tindexOffset += geometry.attributes.position.count;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t// merge attributes\n\tfor ( const name in attributes ) {\n\n\t\tconst attrList = attributes[ name ];\n\t\tif ( ! ( name in targetGeometry.attributes ) ) {\n\n\t\t\tlet count = 0;\n\t\t\tfor ( const key in attrList ) {\n\n\t\t\t\tcount += attrList[ key ].count;\n\n\t\t\t}\n\n\t\t\ttargetGeometry.setAttribute( name, createAttributeClone( attributes[ name ][ 0 ], count ) );\n\n\t\t}\n\n\t\tconst targetAttribute = targetGeometry.attributes[ name ];\n\t\tlet offset = 0;\n\t\tfor ( let i = 0, l = attrList.length; i < l; i ++ ) {\n\n\t\t\tconst attr = attrList[ i ];\n\t\t\tif ( skipAttributes[ i ] !== true ) {\n\n\t\t\t\tcopyAttributeContents( attr, targetAttribute, offset );\n\n\t\t\t}\n\n\t\t\toffset += attr.count;\n\n\t\t}\n\n\t}\n\n\treturn targetGeometry;\n\n}\n\nfunction checkTypedArrayEquality( a, b ) {\n\n\tif ( a === null || b === null ) {\n\n\t\treturn a === b;\n\n\t}\n\n\tif ( a.length !== b.length ) {\n\n\t\treturn false;\n\n\t}\n\n\tfor ( let i = 0, l = a.length; i < l; i ++ ) {\n\n\t\tif ( a[ i ] !== b[ i ] ) {\n\n\t\t\treturn false;\n\n\t\t}\n\n\t}\n\n\treturn true;\n\n}\n\nfunction invertGeometry( geometry ) {\n\n\tconst { index, attributes } = geometry;\n\tif ( index ) {\n\n\t\tfor ( let i = 0, l = index.count; i < l; i += 3 ) {\n\n\t\t\tconst v0 = index.getX( i );\n\t\t\tconst v2 = index.getX( i + 2 );\n\t\t\tindex.setX( i, v2 );\n\t\t\tindex.setX( i + 2, v0 );\n\n\t\t}\n\n\t} else {\n\n\t\tfor ( const key in attributes ) {\n\n\t\t\tconst attr = attributes[ key ];\n\t\t\tconst itemSize = attr.itemSize;\n\t\t\tfor ( let i = 0, l = attr.count; i < l; i += 3 ) {\n\n\t\t\t\tfor ( let j = 0; j < itemSize; j ++ ) {\n\n\t\t\t\t\tconst v0 = attr.getComponent( i, j );\n\t\t\t\t\tconst v2 = attr.getComponent( i + 2, j );\n\t\t\t\t\tattr.setComponent( i, j, v2 );\n\t\t\t\t\tattr.setComponent( i + 2, j, v0 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\treturn geometry;\n\n\n}\n\n// Checks whether the geometry changed between this and last evaluation\nclass GeometryDiff {\n\n\tconstructor( mesh ) {\n\n\t\tthis.matrixWorld = new Matrix4();\n\t\tthis.geometryHash = null;\n\t\tthis.boneMatrices = null;\n\t\tthis.primitiveCount = - 1;\n\t\tthis.mesh = mesh;\n\n\t\tthis.update();\n\n\t}\n\n\tupdate() {\n\n\t\tconst mesh = this.mesh;\n\t\tconst geometry = mesh.geometry;\n\t\tconst skeleton = mesh.skeleton;\n\t\tconst primitiveCount = ( geometry.index ? geometry.index.count : geometry.attributes.position.count ) / 3;\n\t\tthis.matrixWorld.copy( mesh.matrixWorld );\n\t\tthis.geometryHash = geometry.attributes.position.version;\n\t\tthis.primitiveCount = primitiveCount;\n\n\t\tif ( skeleton ) {\n\n\t\t\t// ensure the bone matrix array is updated to the appropriate length\n\t\t\tif ( ! skeleton.boneTexture ) {\n\n\t\t\t\tskeleton.computeBoneTexture();\n\n\t\t\t}\n\n\t\t\tskeleton.update();\n\n\t\t\t// copy data if possible otherwise clone it\n\t\t\tconst boneMatrices = skeleton.boneMatrices;\n\t\t\tif ( ! this.boneMatrices || this.boneMatrices.length !== boneMatrices.length ) {\n\n\t\t\t\tthis.boneMatrices = boneMatrices.slice();\n\n\t\t\t} else {\n\n\t\t\t\tthis.boneMatrices.set( boneMatrices );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tthis.boneMatrices = null;\n\n\t\t}\n\n\t}\n\n\tdidChange() {\n\n\t\tconst mesh = this.mesh;\n\t\tconst geometry = mesh.geometry;\n\t\tconst primitiveCount = ( geometry.index ? geometry.index.count : geometry.attributes.position.count ) / 3;\n\t\tconst identical =\n\t\t\tthis.matrixWorld.equals( mesh.matrixWorld ) &&\n\t\t\tthis.geometryHash === geometry.attributes.position.version &&\n\t\t\tcheckTypedArrayEquality( mesh.skeleton && mesh.skeleton.boneMatrices || null, this.boneMatrices ) &&\n\t\t\tthis.primitiveCount === primitiveCount;\n\n\t\treturn ! identical;\n\n\t}\n\n}\n\nexport class StaticGeometryGenerator {\n\n\tconstructor( meshes ) {\n\n\t\tif ( ! Array.isArray( meshes ) ) {\n\n\t\t\tmeshes = [ meshes ];\n\n\t\t}\n\n\t\tconst finalMeshes = [];\n\t\tmeshes.forEach( object => {\n\n\t\t\tobject.traverseVisible( c => {\n\n\t\t\t\tif ( c.isMesh ) {\n\n\t\t\t\t\tfinalMeshes.push( c );\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t} );\n\n\t\tthis.meshes = finalMeshes;\n\t\tthis.useGroups = true;\n\t\tthis.applyWorldTransforms = true;\n\t\tthis.attributes = [ 'position', 'normal', 'color', 'tangent', 'uv', 'uv2' ];\n\t\tthis._intermediateGeometry = new Array( finalMeshes.length ).fill().map( () => new BufferGeometry() );\n\t\tthis._diffMap = new WeakMap();\n\n\t}\n\n\tgetMaterials() {\n\n\t\tconst materials = [];\n\t\tthis.meshes.forEach( mesh => {\n\n\t\t\tif ( Array.isArray( mesh.material ) ) {\n\n\t\t\t\tmaterials.push( ...mesh.material );\n\n\t\t\t} else {\n\n\t\t\t\tmaterials.push( mesh.material );\n\n\t\t\t}\n\n\t\t} );\n\t\treturn materials;\n\n\t}\n\n\tgenerate( targetGeometry = new BufferGeometry() ) {\n\n\t\t// track which attributes have been updated and which to skip to avoid unnecessary attribute copies\n\t\tlet skipAttributes = [];\n\t\tconst { meshes, useGroups, _intermediateGeometry, _diffMap } = this;\n\t\tfor ( let i = 0, l = meshes.length; i < l; i ++ ) {\n\n\t\t\tconst mesh = meshes[ i ];\n\t\t\tconst geom = _intermediateGeometry[ i ];\n\t\t\tconst diff = _diffMap.get( mesh );\n\t\t\tif ( ! diff || diff.didChange( mesh ) ) {\n\n\t\t\t\tthis._convertToStaticGeometry( mesh, geom );\n\t\t\t\tskipAttributes.push( false );\n\n\t\t\t\tif ( ! diff ) {\n\n\t\t\t\t\t_diffMap.set( mesh, new GeometryDiff( mesh ) );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tdiff.update();\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tskipAttributes.push( true );\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( _intermediateGeometry.length === 0 ) {\n\n\t\t\t// if there are no geometries then just create a fake empty geometry to provide\n\t\t\ttargetGeometry.setIndex( null );\n\n\t\t\t// remove all geometry\n\t\t\tconst attrs = targetGeometry.attributes;\n\t\t\tfor ( const key in attrs ) {\n\n\t\t\t\ttargetGeometry.deleteAttribute( key );\n\n\t\t\t}\n\n\t\t\t// create dummy attributes\n\t\t\tfor ( const key in this.attributes ) {\n\n\t\t\t\ttargetGeometry.setAttribute( this.attributes[ key ], new BufferAttribute( new Float32Array( 0 ), 4, false ) );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tmergeBufferGeometries( _intermediateGeometry, { useGroups, skipAttributes }, targetGeometry );\n\n\t\t}\n\n\t\tfor ( const key in targetGeometry.attributes ) {\n\n\t\t\ttargetGeometry.attributes[ key ].needsUpdate = true;\n\n\t\t}\n\n\t\treturn targetGeometry;\n\n\t}\n\n\t_convertToStaticGeometry( mesh, targetGeometry = new BufferGeometry() ) {\n\n\t\tconst geometry = mesh.geometry;\n\t\tconst applyWorldTransforms = this.applyWorldTransforms;\n\t\tconst includeNormal = this.attributes.includes( 'normal' );\n\t\tconst includeTangent = this.attributes.includes( 'tangent' );\n\t\tconst attributes = geometry.attributes;\n\t\tconst targetAttributes = targetGeometry.attributes;\n\n\t\t// initialize the attributes if they don't exist\n\t\tif ( ! targetGeometry.index && geometry.index ) {\n\n\t\t\ttargetGeometry.index = geometry.index.clone();\n\n\t\t}\n\n\t\tif ( ! targetAttributes.position ) {\n\n\t\t\ttargetGeometry.setAttribute( 'position', createAttributeClone( attributes.position ) );\n\n\t\t}\n\n\t\tif ( includeNormal && ! targetAttributes.normal && attributes.normal ) {\n\n\t\t\ttargetGeometry.setAttribute( 'normal', createAttributeClone( attributes.normal ) );\n\n\t\t}\n\n\t\tif ( includeTangent && ! targetAttributes.tangent && attributes.tangent ) {\n\n\t\t\ttargetGeometry.setAttribute( 'tangent', createAttributeClone( attributes.tangent ) );\n\n\t\t}\n\n\t\t// ensure the attributes are consistent\n\t\tvalidateAttributes( geometry.index, targetGeometry.index );\n\t\tvalidateAttributes( attributes.position, targetAttributes.position );\n\n\t\tif ( includeNormal ) {\n\n\t\t\tvalidateAttributes( attributes.normal, targetAttributes.normal );\n\n\t\t}\n\n\t\tif ( includeTangent ) {\n\n\t\t\tvalidateAttributes( attributes.tangent, targetAttributes.tangent );\n\n\t\t}\n\n\t\t// generate transformed vertex attribute data\n\t\tconst position = attributes.position;\n\t\tconst normal = includeNormal ? attributes.normal : null;\n\t\tconst tangent = includeTangent ? attributes.tangent : null;\n\t\tconst morphPosition = geometry.morphAttributes.position;\n\t\tconst morphNormal = geometry.morphAttributes.normal;\n\t\tconst morphTangent = geometry.morphAttributes.tangent;\n\t\tconst morphTargetsRelative = geometry.morphTargetsRelative;\n\t\tconst morphInfluences = mesh.morphTargetInfluences;\n\t\tconst normalMatrix = new Matrix3();\n\t\tnormalMatrix.getNormalMatrix( mesh.matrixWorld );\n\n\t\t// copy the index\n\t\tif ( geometry.index ) {\n\n\t\t\ttargetGeometry.index.array.set( geometry.index.array );\n\n\t\t}\n\n\t\t// copy and apply other attributes\n\t\tfor ( let i = 0, l = attributes.position.count; i < l; i ++ ) {\n\n\t\t\t_positionVector.fromBufferAttribute( position, i );\n\t\t\tif ( normal ) {\n\n\t\t\t\t_normalVector.fromBufferAttribute( normal, i );\n\n\t\t\t}\n\n\t\t\tif ( tangent ) {\n\n\t\t\t\t_tangentVector4.fromBufferAttribute( tangent, i );\n\t\t\t\t_tangentVector.fromBufferAttribute( tangent, i );\n\n\t\t\t}\n\n\t\t\t// apply morph target transform\n\t\t\tif ( morphInfluences ) {\n\n\t\t\t\tif ( morphPosition ) {\n\n\t\t\t\t\tapplyMorphTarget( morphPosition, morphInfluences, morphTargetsRelative, i, _positionVector );\n\n\t\t\t\t}\n\n\t\t\t\tif ( morphNormal ) {\n\n\t\t\t\t\tapplyMorphTarget( morphNormal, morphInfluences, morphTargetsRelative, i, _normalVector );\n\n\t\t\t\t}\n\n\t\t\t\tif ( morphTangent ) {\n\n\t\t\t\t\tapplyMorphTarget( morphTangent, morphInfluences, morphTargetsRelative, i, _tangentVector );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// apply bone transform\n\t\t\tif ( mesh.isSkinnedMesh ) {\n\n\t\t\t\tmesh.applyBoneTransform( i, _positionVector );\n\t\t\t\tif ( normal ) {\n\n\t\t\t\t\tboneNormalTransform( mesh, i, _normalVector );\n\n\t\t\t\t}\n\n\t\t\t\tif ( tangent ) {\n\n\t\t\t\t\tboneNormalTransform( mesh, i, _tangentVector );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// update the vectors of the attributes\n\t\t\tif ( applyWorldTransforms ) {\n\n\t\t\t\t_positionVector.applyMatrix4( mesh.matrixWorld );\n\n\t\t\t}\n\n\t\t\ttargetAttributes.position.setXYZ( i, _positionVector.x, _positionVector.y, _positionVector.z );\n\n\t\t\tif ( normal ) {\n\n\t\t\t\tif ( applyWorldTransforms ) {\n\n\t\t\t\t\t_normalVector.applyNormalMatrix( normalMatrix );\n\n\t\t\t\t}\n\n\t\t\t\ttargetAttributes.normal.setXYZ( i, _normalVector.x, _normalVector.y, _normalVector.z );\n\n\t\t\t}\n\n\t\t\tif ( tangent ) {\n\n\t\t\t\tif ( applyWorldTransforms ) {\n\n\t\t\t\t\t_tangentVector.transformDirection( mesh.matrixWorld );\n\n\t\t\t\t}\n\n\t\t\t\ttargetAttributes.tangent.setXYZW( i, _tangentVector.x, _tangentVector.y, _tangentVector.z, _tangentVector4.w );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// copy other attributes over\n\t\tfor ( const i in this.attributes ) {\n\n\t\t\tconst key = this.attributes[ i ];\n\t\t\tif ( key === 'position' || key === 'tangent' || key === 'normal' || ! ( key in attributes ) ) {\n\n\t\t\t\tcontinue;\n\n\t\t\t}\n\n\t\t\tif ( ! targetAttributes[ key ] ) {\n\n\t\t\t\ttargetGeometry.setAttribute( key, createAttributeClone( attributes[ key ] ) );\n\n\t\t\t}\n\n\t\t\tvalidateAttributes( attributes[ key ], targetAttributes[ key ] );\n\t\t\tcopyAttributeContents( attributes[ key ], targetAttributes[ key ] );\n\n\t\t}\n\n\t\tif ( mesh.matrixWorld.determinant() < 0 ) {\n\n\t\t\tinvertGeometry( targetGeometry );\n\n\t\t}\n\n\t\treturn targetGeometry;\n\n\t}\n\n}\n","import * as THREE from 'three'\r\nimport gsap from 'gsap'\r\nimport { Engine } from './core/Engine'\r\nimport { EventEmitter } from './core/EventEmitter'\r\nimport { PluginManager } from './plugins/PluginManager'\r\nimport { OrbitControllerPlugin } from './plugins/controls/OrbitController'\r\nimport { TransformControllerPlugin } from './plugins/controls/TransformController'\r\nimport { LoaderPlugin } from './plugins/loaders/LoaderPlugin'\r\nimport { ComposerPlugin } from './plugins/postprocessing/ComposerPlugin'\r\nimport { CSSRendererPlugin } from './plugins/renderers/CSSRendererPlugin'\r\nimport { EditorPlugin } from './plugins/editor/EditorPlugin'\r\nimport { GUIPlugin } from './plugins/gui/GUIPlugin'\r\nimport { GizmoPlugin } from './plugins/gizmo/GizmoPlugin'\r\nimport { getDistanceScalePoint } from './utils/math'\r\nimport { getBestViewTarget, getObjectViews } from './utils/box3'\r\nimport { getRootModel } from './utils/raycast'\r\nimport type { ThreeEditorConfig, ScreenshotOptions } from './types/config.types'\r\nimport type { GsapQuery } from './types/core.types'\r\nimport type { EventMap } from './types/event.types'\r\nimport type { IPlugin } from './types/plugin.types'\r\nimport type {\r\n HandlerMode,\r\n RootInfo,\r\n LoaderService,\r\n ClickInfo,\r\n ViewAngle,\r\n CurveAnimationController,\r\n ExtendedObject3D\r\n} from './types/core.types'\r\n\r\n/**\r\n * Draco 解码器默认路径\r\n */\r\nlet dracoPath = '/draco/'\r\n\r\n/**\r\n * Three Editor 主类\r\n * 提供完整的 3D 编辑器功能\r\n */\r\nexport class ThreeEditor {\r\n /** Three.js 库引用 */\r\n static THREE = THREE\r\n\r\n /** GSAP 库引用 */\r\n static gsap = gsap\r\n\r\n /** Draco 解码器路径 */\r\n static get dracoPath(): string {\r\n return dracoPath\r\n }\r\n\r\n static set dracoPath(path: string) {\r\n dracoPath = path\r\n }\r\n\r\n /** 引擎实例 */\r\n readonly engine: Engine\r\n\r\n /** 事件发射器 */\r\n readonly events: EventEmitter<EventMap>\r\n\r\n /** 插件管理器 */\r\n readonly plugins: PluginManager\r\n\r\n /** 配置 */\r\n private config: ThreeEditorConfig\r\n\r\n /** 进度列表 */\r\n progressList: Array<{ loaderService: LoaderService; rootInfo: RootInfo; params?: any }> = []\r\n\r\n /** 公共帧动画列表 */\r\n private commonFrameList: CurveAnimationController[] = []\r\n\r\n /** 混合器列表 */\r\n private mixerList: THREE.AnimationMixer[] = []\r\n\r\n /** 着色器列表 */\r\n private shaderList: any[] = []\r\n\r\n constructor(config: ThreeEditorConfig) {\r\n this.config = config\r\n\r\n // 创建引擎\r\n this.engine = new Engine({\r\n container: config.container,\r\n ...config.engine,\r\n autoStart: false\r\n })\r\n\r\n // 使用引擎的事件发射器\r\n this.events = this.engine.events\r\n\r\n // 创建插件管理器\r\n this.plugins = new PluginManager({\r\n engine: this.engine,\r\n events: this.events\r\n })\r\n\r\n // 安装核心插件\r\n this.installCorePlugins()\r\n\r\n // 设置渲染回调\r\n this.engine.onUpdate((delta, elapsed) => {\r\n this.onUpdate(delta, elapsed)\r\n })\r\n\r\n // 恢复场景(如果有)\r\n if (config.sceneParams) {\r\n this.restoreScene(config.sceneParams)\r\n }\r\n\r\n // 加载模型(如果有)\r\n if (config.meshListParams) {\r\n config.meshListParams.forEach(item => {\r\n this.setModelFromInfo(item.rootInfo, item.group)\r\n })\r\n }\r\n\r\n // 设置天空盒(如果有)\r\n if (config.skyParams) {\r\n this.setSky(config.skyParams)\r\n this.setGlobalEnvBackground(config.skyParams)\r\n }\r\n\r\n // 启动引擎\r\n if (config.autoStart !== false) {\r\n this.engine.start()\r\n }\r\n }\r\n\r\n // ============ 便捷访问器 ============\r\n\r\n /** 获取 THREE 库 */\r\n get THREE() {\r\n return THREE\r\n }\r\n\r\n /** 获取 gsap 库 */\r\n get gsap() {\r\n return gsap\r\n }\r\n\r\n /** 获取场景 */\r\n get scene(): THREE.Scene {\r\n return this.engine.scene\r\n }\r\n\r\n /** 获取相机 */\r\n get camera(): THREE.PerspectiveCamera {\r\n return this.engine.camera\r\n }\r\n\r\n /** 获取渲染器 */\r\n get renderer(): THREE.WebGLRenderer {\r\n return this.engine.renderer\r\n }\r\n\r\n /** 获取 viewer 对象(兼容旧 API) */\r\n get viewer() {\r\n const orbitPlugin = this.plugins.get<OrbitControllerPlugin>('orbit-controller')\r\n const transformPlugin = this.plugins.get<TransformControllerPlugin>('transform-controller')\r\n const composerPlugin = this.plugins.get<ComposerPlugin>('composer')\r\n const cssPlugin = this.plugins.get<CSSRendererPlugin>('css-renderer')\r\n const editorPlugin = this.plugins.get<EditorPlugin>('editor')\r\n const loaderPlugin = this.plugins.get<LoaderPlugin>('loader')\r\n const guiPlugin = this.plugins.get<GUIPlugin>('gui')\r\n\r\n return {\r\n scene: this.scene,\r\n camera: this.camera,\r\n renderer: this.renderer,\r\n controls: orbitPlugin?.controls,\r\n transformControls: transformPlugin?.controls,\r\n Composer: composerPlugin,\r\n CSS2DObject: cssPlugin?.CSS2DObject,\r\n CSS3DObject: cssPlugin?.CSS3DObject,\r\n MixerList: this.mixerList,\r\n ShaderList: this.shaderList,\r\n CommonFrameList: this.commonFrameList,\r\n handler: editorPlugin,\r\n modelControls: loaderPlugin,\r\n currentInfo: editorPlugin?.currentInfo,\r\n GUI: guiPlugin?.gui,\r\n renderSceneResize: () => this.engine.resize(),\r\n destroySceneRender: () => this.dispose(),\r\n saveSceneEditor: () => this.saveSceneEditor()\r\n }\r\n }\r\n\r\n // ============ 核心方法 ============\r\n\r\n /**\r\n * 安装核心插件\r\n */\r\n private installCorePlugins(): void {\r\n // 轨道控制器\r\n this.plugins.use(new OrbitControllerPlugin())\r\n\r\n // 变换控制器\r\n this.plugins.use(new TransformControllerPlugin())\r\n\r\n // 加载器\r\n const loaderPlugin = new LoaderPlugin({ dracoPath: ThreeEditor.dracoPath })\r\n this.plugins.use(loaderPlugin)\r\n\r\n // 后期处理\r\n this.plugins.use(new ComposerPlugin())\r\n\r\n // CSS 渲染器\r\n this.plugins.use(new CSSRendererPlugin())\r\n\r\n // 编辑器\r\n this.plugins.use(new EditorPlugin())\r\n\r\n // 辅助工具 (网格、坐标轴、性能监控)\r\n this.plugins.use(new GizmoPlugin({\r\n grid: { enabled: true, size: 100, divisions: 100, colorCenterLine: 0x444444, colorGrid: 0x888888 },\r\n axes: { enabled: true, size: 5 },\r\n stats: { enabled: false, mode: 0 },\r\n viewHelper: { enabled: false, size: 128, position: 'bottom-right' },\r\n box3Helper: { enabled: false, color: 0xffff00 }\r\n }))\r\n\r\n // GUI 面板\r\n const guiConfig = this.config.gui\r\n if (guiConfig?.useProxy !== true) {\r\n this.plugins.use(new GUIPlugin({\r\n autoPlace: guiConfig?.autoPlace ?? true,\r\n width: guiConfig?.width ?? 300,\r\n useProxy: guiConfig?.useProxy ?? false\r\n }))\r\n }\r\n }\r\n\r\n /**\r\n * 每帧更新\r\n */\r\n private onUpdate(delta: number, elapsed: number): void {\r\n // 更新混合器\r\n this.mixerList.forEach(mixer => {\r\n (mixer as any).mixerRender?.()\r\n })\r\n\r\n // 更新着色器\r\n this.shaderList.forEach(shader => {\r\n shader.ShaderAnimateRender?.()\r\n })\r\n\r\n // 更新公共帧动画\r\n this.commonFrameList.forEach((anim: any) => {\r\n anim.frameAnimationRender?.()\r\n })\r\n\r\n // 后期处理渲染\r\n const composerPlugin = this.plugins.get<ComposerPlugin>('composer')\r\n if (composerPlugin) {\r\n composerPlugin.render()\r\n }\r\n }\r\n\r\n /**\r\n * 使用插件\r\n */\r\n use<T extends IPlugin>(plugin: T): this {\r\n this.plugins.use(plugin)\r\n return this\r\n }\r\n\r\n // ============ 模型加载 ============\r\n\r\n /**\r\n * 根据类型加载模型\r\n */\r\n setModelFromInfo(rootInfo: RootInfo, params: any = null): {\r\n loaderService: LoaderService\r\n rootInfo: RootInfo\r\n params: any\r\n } {\r\n const loaderPlugin = this.plugins.get<LoaderPlugin>('loader')\r\n if (!loaderPlugin) {\r\n throw new Error('Loader plugin not installed')\r\n }\r\n\r\n const loaderService = loaderPlugin.loadModel(rootInfo)\r\n\r\n // 加载完成后添加到场景\r\n const originalComplete = loaderService.complete\r\n loaderService.complete = (model) => {\r\n // 标记根信息\r\n (model as ExtendedObject3D).rootInfo = rootInfo\r\n\r\n // 添加到场景\r\n this.scene.add(model)\r\n\r\n // 调用原始回调\r\n originalComplete(model)\r\n }\r\n\r\n const item = { loaderService, rootInfo, params }\r\n this.progressList.push(item)\r\n\r\n return item\r\n }\r\n\r\n // ============ 天空/环境 ============\r\n\r\n /**\r\n * 设置天空盒\r\n */\r\n setSky(urls: string[]): void {\r\n this.engine.sceneManager.setSkybox(urls)\r\n }\r\n\r\n /**\r\n * 设置全局环境贴图\r\n */\r\n setGlobalEnvBackground(urls: string[]): void {\r\n this.engine.sceneManager.setEnvironmentMap(urls).then(() => {\r\n this.engine.sceneManager.environmentEnabled = true\r\n })\r\n }\r\n\r\n // ============ CSS DOM ============\r\n\r\n /**\r\n * 设置 CSS2D DOM 元素\r\n */\r\n setCss2dDOM(dom: HTMLElement, position: THREE.Vector3) {\r\n const cssPlugin = this.plugins.get<CSSRendererPlugin>('css-renderer')\r\n if (!cssPlugin) {\r\n throw new Error('CSS Renderer plugin not installed')\r\n }\r\n\r\n dom.style.pointerEvents = 'auto'\r\n const mesh = cssPlugin.addCSS2D(dom, position)\r\n return mesh\r\n }\r\n\r\n /**\r\n * 设置 CSS3D DOM 元素\r\n */\r\n setCss3dDOM(dom: HTMLElement, position: THREE.Vector3) {\r\n const cssPlugin = this.plugins.get<CSSRendererPlugin>('css-renderer')\r\n if (!cssPlugin) {\r\n throw new Error('CSS Renderer plugin not installed')\r\n }\r\n\r\n const mesh = cssPlugin.addCSS3D(dom, position)\r\n return mesh\r\n }\r\n\r\n // ============ 事件处理 ============\r\n\r\n /**\r\n * 获取场景点击事件\r\n */\r\n getSceneEvent(event: MouseEvent, callback: (info: ClickInfo) => void): void {\r\n const editorPlugin = this.plugins.get<EditorPlugin>('editor')\r\n if (!editorPlugin) return\r\n\r\n const info = editorPlugin.handleClick(event)\r\n if (info) {\r\n callback(info)\r\n }\r\n }\r\n\r\n /**\r\n * 获取原始场景事件\r\n */\r\n getRawSceneEvent(): { raycaster: THREE.Raycaster; getIntersects: (event: MouseEvent, objects: THREE.Object3D[]) => THREE.Intersection[] } {\r\n const raycaster = new THREE.Raycaster()\r\n const mouse = new THREE.Vector2()\r\n\r\n const getIntersects = (event: MouseEvent, objects: THREE.Object3D[]): THREE.Intersection[] => {\r\n const rect = this.renderer.domElement.getBoundingClientRect()\r\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1\r\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1\r\n\r\n raycaster.setFromCamera(mouse, this.camera)\r\n return raycaster.intersectObjects(objects, true)\r\n }\r\n\r\n return { raycaster, getIntersects }\r\n }\r\n\r\n // ============ 动画 ============\r\n\r\n /**\r\n * 创建 GSAP 动画\r\n */\r\n setGsapAnimation(\r\n position: THREE.Vector3 | { x: number; y: number; z: number },\r\n target: { x?: number; y?: number; z?: number },\r\n query: GsapQuery = {}\r\n ) {\r\n return gsap.to(position, {\r\n ...target,\r\n duration: 2,\r\n ease: 'none',\r\n repeat: 0,\r\n yoyo: false,\r\n yoyoEase: true,\r\n ...query\r\n })\r\n }\r\n\r\n /**\r\n * 播放模型动画\r\n */\r\n setModelAnimationPlay(group: ExtendedObject3D) {\r\n if (!group.animationPlayParams || !group.animations) return null\r\n\r\n const { speed, actionIndexs, startTime, loop } = group.animationPlayParams\r\n\r\n const clock = new THREE.Clock()\r\n const mixer = new THREE.AnimationMixer(group as unknown as THREE.Object3D)\r\n\r\n const actions = group.animations\r\n .filter((_, index) => actionIndexs[index])\r\n .map(clip => {\r\n const action = mixer.clipAction(clip)\r\n action.loop = loop ? THREE.LoopRepeat : THREE.LoopOnce\r\n action.time = startTime\r\n action.timeScale = speed\r\n action.clampWhenFinished = true\r\n action.play()\r\n return action\r\n })\r\n\r\n ;(group as any).mixerRender = () => {\r\n mixer.update(clock.getDelta())\r\n }\r\n\r\n this.mixerList.push(mixer as any)\r\n\r\n return { mixer, actions }\r\n }\r\n\r\n /**\r\n * 移除模型动画\r\n */\r\n removeModelAnimation(group: ExtendedObject3D): void {\r\n const index = this.mixerList.findIndex((m: any) => m === group || (m as any).mixerRender === (group as any).mixerRender)\r\n if (index > -1) {\r\n this.mixerList.splice(index, 1)\r\n }\r\n }\r\n\r\n /**\r\n * 设置曲线动画\r\n */\r\n setCurveAnimation(curve: THREE.Curve<THREE.Vector3>, speed: number = 1): CurveAnimationController {\r\n const commonFrameList = this.commonFrameList\r\n \r\n const controller: CurveAnimationController = {\r\n id: Date.now(),\r\n curve,\r\n time: 0,\r\n pause: false,\r\n speed,\r\n frameCallback: null,\r\n frameEndCallback: null,\r\n start: function(this: CurveAnimationController) {\r\n if (!commonFrameList.includes(this as any)) {\r\n commonFrameList.push(this as any)\r\n }\r\n this.pause = false\r\n },\r\n destroy: function(this: CurveAnimationController) {\r\n const index = commonFrameList.indexOf(this as any)\r\n if (index > -1) {\r\n commonFrameList.splice(index, 1)\r\n }\r\n }\r\n }\r\n\r\n // 帧动画渲染\r\n ;(controller as any).frameAnimationRender = () => {\r\n if (controller.pause) return\r\n\r\n controller.time += controller.speed / 1000\r\n\r\n if (controller.time > 1 || controller.time < 0) {\r\n controller.time = controller.time > 1 ? 1 : 0\r\n controller.pause = true\r\n controller.frameEndCallback?.()\r\n return\r\n }\r\n\r\n const point = curve.getPointAt(controller.time)\r\n controller.frameCallback?.(point)\r\n }\r\n\r\n return controller\r\n }\r\n\r\n // ============ 后期处理 ============\r\n\r\n /**\r\n * 设置轮廓光选中\r\n */\r\n setOutlinePass(meshList: THREE.Object3D[] = []): void {\r\n const composerPlugin = this.plugins.get<ComposerPlugin>('composer')\r\n if (composerPlugin) {\r\n composerPlugin.setOutlineObjects(meshList)\r\n }\r\n }\r\n\r\n // ============ 控制 ============\r\n\r\n /**\r\n * 设置场景控制模式\r\n */\r\n setSceneControlMode(mode: HandlerMode): void {\r\n const editorPlugin = this.plugins.get<EditorPlugin>('editor')\r\n if (editorPlugin) {\r\n editorPlugin.setMode(mode)\r\n }\r\n }\r\n\r\n /**\r\n * 设置变换控制器属性\r\n */\r\n setTransformControlsProperty(key: string, value: any): void {\r\n const transformPlugin = this.plugins.get<TransformControllerPlugin>('transform-controller')\r\n if (transformPlugin && transformPlugin.controls.hasOwnProperty(key)) {\r\n (transformPlugin.controls as any)[key] = value\r\n }\r\n }\r\n\r\n // ============ 工具方法 ============\r\n\r\n /**\r\n * 获取两点指定距离比例点\r\n */\r\n getDistanceScalePoint = getDistanceScalePoint\r\n\r\n /**\r\n * 获取最佳视角\r\n */\r\n getBestViewTarget = getBestViewTarget\r\n\r\n /**\r\n * 获取物体视图\r\n */\r\n getObjectViews(object: THREE.Object3D, fov?: number) {\r\n return getObjectViews(object, fov ?? this.camera.fov)\r\n }\r\n\r\n /**\r\n * 获取场景曲线列表\r\n */\r\n getSceneCurveList() {\r\n return this.scene.children\r\n .filter(i => (i as ExtendedObject3D).isCurveMesh)\r\n .map(i => ({\r\n path: (i as ExtendedObject3D).curvePath || ((i as THREE.Mesh).geometry as any)?.parameters?.path,\r\n mesh: i\r\n }))\r\n }\r\n\r\n // ============ 保存/恢复 ============\r\n\r\n /**\r\n * 保存场景\r\n */\r\n saveSceneEditor(): void {\r\n if (this.config.saveCallback) {\r\n // TODO: 实现完整的序列化\r\n const sceneParams = {}\r\n const meshListParams: any[] = []\r\n\r\n this.config.saveCallback(sceneParams, meshListParams)\r\n }\r\n }\r\n\r\n /**\r\n * 恢复场景\r\n */\r\n private restoreScene(params: any): void {\r\n // TODO: 实现完整的反序列化\r\n }\r\n\r\n /**\r\n * 获取场景截图\r\n */\r\n getSceneEditorImage(params?: { type?: string; quality?: number } | [string?, number?]): string {\r\n if (Array.isArray(params)) {\r\n return this.engine.screenshot(params[0], params[1])\r\n }\r\n return this.engine.screenshot(params?.type, params?.quality)\r\n }\r\n\r\n /**\r\n * 刷新 GUI\r\n */\r\n refreshGUI(): void {\r\n const guiPlugin = this.plugins.get<GUIPlugin>('gui')\r\n if (guiPlugin) {\r\n guiPlugin.updateDisplay()\r\n }\r\n }\r\n\r\n /**\r\n * 设置 GUI DOM 位置\r\n */\r\n setGUIDomPosition(dom: HTMLElement): { GUIDom: HTMLElement | null; remove: () => void } | null {\r\n const guiPlugin = this.plugins.get<GUIPlugin>('gui')\r\n if (!guiPlugin || !guiPlugin.domElement) return null\r\n\r\n const guiDom = guiPlugin.domElement\r\n dom.appendChild(guiDom)\r\n\r\n return {\r\n GUIDom: guiDom,\r\n remove: () => {\r\n if (guiDom.parentElement === dom) {\r\n dom.removeChild(guiDom)\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 设置操作选项\r\n */\r\n setOperateOption(key: string, value: boolean): void {\r\n const editorPlugin = this.plugins.get<EditorPlugin>('editor')\r\n const gizmoPlugin = this.plugins.get<any>('gizmo')\r\n\r\n switch (key) {\r\n case 'stats':\r\n if (gizmoPlugin) {\r\n gizmoPlugin.setStatsVisible(value)\r\n }\r\n break\r\n case 'axes':\r\n if (gizmoPlugin) {\r\n gizmoPlugin.setAxesVisible(value)\r\n }\r\n break\r\n case 'grid':\r\n if (gizmoPlugin) {\r\n gizmoPlugin.setGridVisible(value)\r\n }\r\n break\r\n case 'openKey':\r\n if (editorPlugin) {\r\n editorPlugin.config.enableKeyboard = value\r\n }\r\n break\r\n }\r\n }\r\n\r\n /**\r\n * 设置场景分类\r\n */\r\n setSceneFromClassify(type: string): void {\r\n // 根据类型显示/隐藏场景物体\r\n this.scene.children.forEach(child => {\r\n const extChild = child as ExtendedObject3D\r\n if (extChild.rootInfo) {\r\n // 根据分类设置可见性\r\n // TODO: 实现完整的分类逻辑\r\n }\r\n })\r\n }\r\n\r\n /**\r\n * 点位同步变换\r\n */\r\n pointSyncTransform(point: THREE.Vector3, mesh: THREE.Object3D): THREE.Vector3 {\r\n const result = point.clone()\r\n result.applyMatrix4(mesh.matrixWorld)\r\n return result\r\n }\r\n\r\n /**\r\n * 克隆材质\r\n */\r\n meshGroupCloneMaterial(object: THREE.Object3D): void {\r\n object.traverse(child => {\r\n if ((child as THREE.Mesh).isMesh) {\r\n const mesh = child as THREE.Mesh\r\n const extMesh = mesh as unknown as ExtendedObject3D\r\n \r\n if (!extMesh.isCloneMaterial) {\r\n extMesh.originMaterial = mesh.material\r\n mesh.material = Array.isArray(mesh.material)\r\n ? mesh.material.map(m => m.clone())\r\n : mesh.material.clone()\r\n extMesh.isCloneMaterial = true\r\n }\r\n }\r\n })\r\n }\r\n\r\n /**\r\n * 修改物体材质\r\n */\r\n changeMeshMaterial(object: THREE.Object3D, params: Record<string, any>): void {\r\n object.traverse(child => {\r\n if ((child as THREE.Mesh).isMesh) {\r\n const mesh = child as THREE.Mesh\r\n const materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material]\r\n \r\n materials.forEach(material => {\r\n Object.entries(params).forEach(([key, value]) => {\r\n if (key in material) {\r\n if (key === 'color' || key === 'emissive') {\r\n (material as any)[key].set(value)\r\n } else {\r\n (material as any)[key] = value\r\n }\r\n }\r\n })\r\n material.needsUpdate = true\r\n })\r\n }\r\n })\r\n }\r\n\r\n /**\r\n * 修改物体变换\r\n */\r\n changeMeshTransform(object: THREE.Object3D, params: { position?: any; rotation?: any; scale?: any }): void {\r\n const extObj = object as unknown as ExtendedObject3D\r\n \r\n // 保存原始变换\r\n if (!extObj.meshRevertTransform) {\r\n const origPos = object.position.clone()\r\n const origRot = object.rotation.clone()\r\n const origScale = object.scale.clone()\r\n \r\n extObj.meshRevertTransform = () => {\r\n object.position.copy(origPos)\r\n object.rotation.copy(origRot)\r\n object.scale.copy(origScale)\r\n }\r\n }\r\n\r\n if (params.position) {\r\n object.position.set(params.position.x ?? object.position.x, params.position.y ?? object.position.y, params.position.z ?? object.position.z)\r\n }\r\n if (params.rotation) {\r\n object.rotation.set(params.rotation.x ?? object.rotation.x, params.rotation.y ?? object.rotation.y, params.rotation.z ?? object.rotation.z)\r\n }\r\n if (params.scale) {\r\n object.scale.set(params.scale.x ?? object.scale.x, params.scale.y ?? object.scale.y, params.scale.z ?? object.scale.z)\r\n }\r\n }\r\n\r\n /**\r\n * 执行 GSAP 物体动作\r\n */\r\n setGsapMeshAction(\r\n mesh: THREE.Object3D,\r\n fromTransform: any,\r\n toTransform: any,\r\n gsapParams: { mode?: string; query: GsapQuery }\r\n ): void {\r\n const { query } = gsapParams\r\n\r\n // 位置动画\r\n if (fromTransform.position && toTransform.position) {\r\n mesh.position.set(fromTransform.position.x, fromTransform.position.y, fromTransform.position.z)\r\n gsap.to(mesh.position, {\r\n x: toTransform.position.x,\r\n y: toTransform.position.y,\r\n z: toTransform.position.z,\r\n ...query\r\n })\r\n }\r\n\r\n // 旋转动画\r\n if (fromTransform.rotation && toTransform.rotation) {\r\n mesh.rotation.set(fromTransform.rotation.x, fromTransform.rotation.y, fromTransform.rotation.z)\r\n gsap.to(mesh.rotation, {\r\n x: toTransform.rotation.x,\r\n y: toTransform.rotation.y,\r\n z: toTransform.rotation.z,\r\n ...query\r\n })\r\n }\r\n\r\n // 缩放动画\r\n if (fromTransform.scale && toTransform.scale) {\r\n mesh.scale.set(fromTransform.scale.x, fromTransform.scale.y, fromTransform.scale.z)\r\n gsap.to(mesh.scale, {\r\n x: toTransform.scale.x,\r\n y: toTransform.scale.y,\r\n z: toTransform.scale.z,\r\n ...query\r\n })\r\n }\r\n }\r\n\r\n // ============ 生命周期 ============\r\n\r\n /**\r\n * 启动\r\n */\r\n start(): void {\r\n this.engine.start()\r\n }\r\n\r\n /**\r\n * 停止\r\n */\r\n stop(): void {\r\n this.engine.stop()\r\n }\r\n\r\n /**\r\n * 销毁\r\n */\r\n dispose(): void {\r\n this.plugins.dispose()\r\n this.engine.dispose()\r\n this.progressList = []\r\n this.mixerList = []\r\n this.shaderList = []\r\n this.commonFrameList = []\r\n }\r\n}\r\n","import * as THREE from 'three'\r\n\r\n/**\r\n * 释放网格资源\r\n * @param mesh 网格\r\n */\r\nexport function disposeMesh(mesh: THREE.Mesh): void {\r\n mesh.geometry?.dispose()\r\n\r\n if (Array.isArray(mesh.material)) {\r\n mesh.material.forEach(disposeMaterial)\r\n } else if (mesh.material) {\r\n disposeMaterial(mesh.material)\r\n }\r\n}\r\n\r\n/**\r\n * 释放材质资源\r\n * @param material 材质\r\n */\r\nexport function disposeMaterial(material: THREE.Material): void {\r\n material.dispose()\r\n\r\n // 释放纹理\r\n const mat = material as any\r\n if (mat.map) mat.map.dispose()\r\n if (mat.lightMap) mat.lightMap.dispose()\r\n if (mat.bumpMap) mat.bumpMap.dispose()\r\n if (mat.normalMap) mat.normalMap.dispose()\r\n if (mat.specularMap) mat.specularMap.dispose()\r\n if (mat.envMap) mat.envMap.dispose()\r\n if (mat.alphaMap) mat.alphaMap.dispose()\r\n if (mat.aoMap) mat.aoMap.dispose()\r\n if (mat.displacementMap) mat.displacementMap.dispose()\r\n if (mat.emissiveMap) mat.emissiveMap.dispose()\r\n if (mat.gradientMap) mat.gradientMap.dispose()\r\n if (mat.metalnessMap) mat.metalnessMap.dispose()\r\n if (mat.roughnessMap) mat.roughnessMap.dispose()\r\n}\r\n\r\n/**\r\n * 释放物体及其子物体的资源\r\n * @param object 物体\r\n */\r\nexport function disposeObject(object: THREE.Object3D): void {\r\n object.traverse((child) => {\r\n if ((child as THREE.Mesh).isMesh) {\r\n disposeMesh(child as THREE.Mesh)\r\n }\r\n })\r\n}\r\n\r\n/**\r\n * 释放场景资源\r\n * @param scene 场景\r\n */\r\nexport function disposeScene(scene: THREE.Scene): void {\r\n scene.traverse((object) => {\r\n if ((object as THREE.Mesh).isMesh) {\r\n disposeMesh(object as THREE.Mesh)\r\n }\r\n })\r\n\r\n // 清空场景\r\n while (scene.children.length > 0) {\r\n scene.remove(scene.children[0])\r\n }\r\n\r\n // 释放背景和环境\r\n if (scene.background instanceof THREE.Texture) {\r\n scene.background.dispose()\r\n }\r\n if (scene.environment) {\r\n scene.environment.dispose()\r\n }\r\n}\r\n"],"names":["EventEmitter","constructor","this","listeners","Map","event","callback","has","set","Set","listener","once","get","add","delete","data","toRemove","error","push","size","removeAllListeners","clear","dispose","SceneManager","events","_envBackground","_environmentEnabled","envMapChangeCallbacks","ssrMeshList","scene","THREE","Scene","name","envBackground","value","updateEnvironment","forEach","cb","environmentEnabled","environment","index","indexOf","splice","background","emit","urls","Promise","resolve","reject","CubeTextureLoader","load","texture","objects","object","parent","remove","getObjectByName","id","getObjectById","traverse","getMeshes","meshes","Mesh","getLights","lights","Light","children","length","child","geometry","Array","isArray","material","m","map","DEFAULT_CAMERA_CONFIG","fov","near","far","position","x","y","z","CameraManager","container","config","aspect","clientWidth","clientHeight","camera","PerspectiveCamera","updateProjectionMatrix","target","Vector3","lookAt","updateAspect","getWorldDirection","direction","distance","clone","multiplyScalar","getConfig","DEFAULT_RENDERER_CONFIG","pixelRatio","window","Math","min","devicePixelRatio","antialias","alpha","logarithmicDepthBuffer","preserveDrawingBuffer","powerPreference","toneMapping","NoToneMapping","toneMappingExposure","outputColorSpace","SRGBColorSpace","shadowMapEnabled","shadowMapType","PCFSoftShadowMap","RendererManager","renderer","WebGLRenderer","setSize","setPixelRatio","shadowMap","enabled","type","appendChild","domElement","getPixelRatio","limitedValue","getSize","Vector2","width","height","updateSize","render","quality","toDataURL","exposure","setShadowMapEnabled","setShadowMapType","getInfo","info","resetInfo","reset","forceContextLoss","parentNode","removeChild","DEFAULT_ENGINE_CONFIG","autoResize","fps","autoStart","Engine","animationId","_isRunning","frameCallbacks","fpsInterval","lastFrameTime","resizeHandler","animate","requestAnimationFrame","now","performance","elapsed","delta","clock","getDelta","elapsedTime","getElapsedTime","Clock","sceneManager","cameraManager","rendererManager","setupAutoResize","start","isRunning","resize","addEventListener","stop","cancelAnimationFrame","getScreenshot","removeEventListener","_positionVector","_normalVector","_tangentVector","_tangentVector4","Vector4","_morphVector","_temp","_skinIndex","_skinWeight","_matrix","Matrix4","_boneMatrix","validateAttributes","attr1","attr2","sameCount","count","sameNormalized","normalized","sameType","array","sameItemSize","itemSize","Error","createAttributeClone","attr","countOverride","cons","BufferAttribute","copyAttributeContents","targetOffset","isInterleavedBufferAttribute","i","l","io","setX","getX","setY","getY","setZ","getZ","setW","getW","byteOffset","BYTES_PER_ELEMENT","buffer","addScaledMatrix","matrix","scale","targetArray","elements","matrixArray","boneNormalTransform","mesh","skeleton","bones","boneInverses","fromBufferAttribute","attributes","skinIndex","skinWeight","fill","weight","getComponent","boneIndex","multiplyMatrices","matrixWorld","multiply","bindMatrix","premultiply","bindMatrixInverse","transformDirection","applyMorphTarget","morphData","morphInfluences","morphTargetsRelative","j","jl","influence","morphAttribute","addScaledVector","sub","GeometryDiff","geometryHash","boneMatrices","primitiveCount","update","copy","version","boneTexture","computeBoneTexture","slice","didChange","equals","a","b","StaticGeometryGenerator","finalMeshes","traverseVisible","c","isMesh","useGroups","applyWorldTransforms","_intermediateGeometry","BufferGeometry","_diffMap","WeakMap","materials","targetGeometry","skipAttributes","geom","diff","_convertToStaticGeometry","setIndex","attrs","key","deleteAttribute","setAttribute","Float32Array","geometries","options","updateIndex","isIndexed","attributesUsed","Object","keys","offset","clearGroups","attributesCount","addGroup","forceUpdateIndex","indexCount","Uint32Array","targetIndex","indexOffset","attrList","targetAttribute","needsUpdate","includeNormal","includes","includeTangent","targetAttributes","normal","tangent","morphPosition","morphAttributes","morphNormal","morphTangent","morphTargetInfluences","normalMatrix","Matrix3","getNormalMatrix","isSkinnedMesh","applyBoneTransform","applyMatrix4","setXYZ","applyNormalMatrix","setXYZW","w","determinant","v0","v2","setComponent","dracoPath","ThreeEditor","progressList","commonFrameList","mixerList","shaderList","getDistanceScalePoint","getBestViewTarget","engine","plugins","PluginManager","installCorePlugins","onUpdate","sceneParams","restoreScene","meshListParams","item","setModelFromInfo","rootInfo","group","skyParams","setSky","setGlobalEnvBackground","path","gsap","viewer","orbitPlugin","transformPlugin","composerPlugin","cssPlugin","editorPlugin","loaderPlugin","guiPlugin","controls","transformControls","Composer","CSS2DObject","CSS3DObject","MixerList","ShaderList","CommonFrameList","handler","modelControls","currentInfo","GUI","gui","renderSceneResize","destroySceneRender","saveSceneEditor","use","OrbitControllerPlugin","TransformControllerPlugin","LoaderPlugin","ComposerPlugin","CSSRendererPlugin","EditorPlugin","GizmoPlugin","grid","divisions","colorCenterLine","colorGrid","axes","stats","mode","viewHelper","box3Helper","color","guiConfig","useProxy","GUIPlugin","autoPlace","mixer","mixerRender","shader","ShaderAnimateRender","anim","frameAnimationRender","plugin","params","loaderService","loadModel","originalComplete","complete","model","setSkybox","setEnvironmentMap","then","dom","style","pointerEvents","addCSS2D","addCSS3D","handleClick","getRawSceneEvent","raycaster","Raycaster","mouse","getIntersects","rect","getBoundingClientRect","clientX","left","clientY","top","setFromCamera","intersectObjects","query","to","duration","ease","repeat","yoyo","yoyoEase","animationPlayParams","animations","speed","actionIndexs","startTime","loop","AnimationMixer","actions","filter","_","clip","action","clipAction","LoopRepeat","LoopOnce","time","timeScale","clampWhenFinished","play","findIndex","curve","controller","Date","pause","frameCallback","frameEndCallback","destroy","point","getPointAt","meshList","setOutlineObjects","setMode","hasOwnProperty","getObjectViews","isCurveMesh","curvePath","parameters","saveCallback","screenshot","refreshGUI","updateDisplay","guiDom","GUIDom","parentElement","gizmoPlugin","setStatsVisible","setAxesVisible","setGridVisible","enableKeyboard","result","extMesh","isCloneMaterial","originMaterial","entries","extObj","meshRevertTransform","origPos","origRot","rotation","origScale","fromTransform","toTransform","gsapParams","disposeMesh","disposeMaterial","mat","lightMap","bumpMap","normalMap","specularMap","envMap","alphaMap","aoMap","displacementMap","emissiveMap","gradientMap","metalnessMap","roughnessMap","disposeObject","disposeScene","Texture"],"mappings":"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","x_google_ignoreList":[5]}
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const e = require("../SerializationPlugin-DJVOx3pd.cjs");
3
+ const e = require("../SerializationPlugin-C54a1wAp.cjs");
4
4
  exports.AnimationPlugin = e.AnimationPlugin, exports.CSSRendererPlugin = e.CSSRendererPlugin, exports.ComposerPlugin = e.ComposerPlugin, exports.DEFAULT_ANIMATION_CONFIG = e.DEFAULT_ANIMATION_CONFIG, exports.DEFAULT_COMPOSER_CONFIG = e.DEFAULT_COMPOSER_CONFIG, exports.DEFAULT_DRAWING_CONFIG = e.DEFAULT_DRAWING_CONFIG, exports.DEFAULT_EDITOR_CONFIG = e.DEFAULT_EDITOR_CONFIG, exports.DEFAULT_GEOMAP_CONFIG = e.DEFAULT_GEOMAP_CONFIG, exports.DEFAULT_GEOMETRY_CONFIG = e.DEFAULT_GEOMETRY_CONFIG, exports.DEFAULT_GUI_CONFIG = e.DEFAULT_GUI_CONFIG, exports.DEFAULT_LOADER_CONFIG = e.DEFAULT_LOADER_CONFIG, exports.DEFAULT_MATERIAL_CONFIG = e.DEFAULT_MATERIAL_CONFIG, exports.DEFAULT_ORBIT_CONFIG = e.DEFAULT_ORBIT_CONFIG, exports.DEFAULT_PARTICLE_CONFIG = e.DEFAULT_PARTICLE_CONFIG, exports.DEFAULT_PHYSICS_CONFIG = e.DEFAULT_PHYSICS_CONFIG, exports.DEFAULT_SHADER_CONFIG = e.DEFAULT_SHADER_CONFIG, exports.DEFAULT_TRANSFORM_CONFIG = e.DEFAULT_TRANSFORM_CONFIG, exports.DrawingPlugin = e.DrawingPlugin, exports.EditorPlugin = e.EditorPlugin, exports.EnvironmentPlugin = e.EnvironmentPlugin, exports.GUIPlugin = e.GUIPlugin, exports.GeoMapPlugin = e.GeoMapPlugin, exports.GeometryPlugin = e.GeometryPlugin, exports.GizmoPlugin = e.GizmoPlugin, exports.LoaderPlugin = e.LoaderPlugin, exports.MaterialPlugin = e.MaterialPlugin, exports.OrbitControllerPlugin = e.OrbitControllerPlugin, exports.ParticlePlugin = e.ParticlePlugin, exports.PhysicsPlugin = e.PhysicsPlugin, exports.Plugin = e.Plugin, exports.PluginManager = e.PluginManager, exports.SerializationPlugin = e.SerializationPlugin, exports.ShaderPlugin = e.ShaderPlugin, exports.TextPlugin = e.TextPlugin, exports.TransformControllerPlugin = e.TransformControllerPlugin, exports.drawModeList = e.drawModeList, exports.geometryList = e.geometryList, exports.lightTypeList = e.lightTypeList, exports.materialList = e.materialList, exports.pointModeList = e.pointModeList;
5
5
  //# sourceMappingURL=index.cjs.map
@@ -1,4 +1,4 @@
1
- import { A, f, C, j, e, l, D, n, g, x, d, h, b, p, r, i, c, k, E, u, w, m, G, t, L, M, O, o, q, P, a, v, S, s, T, F, y, B, z, H } from "../SerializationPlugin-D418fw5V.js";
1
+ import { A, f, C, j, e, l, D, n, g, x, d, h, b, p, r, i, c, k, E, u, w, m, G, t, L, M, O, o, q, P, a, v, S, s, T, F, y, B, z, H } from "../SerializationPlugin-06oXfKib.js";
2
2
  export {
3
3
  A as AnimationPlugin,
4
4
  f as CSSRendererPlugin,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "view3d-core",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "view3d edit",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -45,12 +45,14 @@
45
45
  },
46
46
  "homepage": "https://github.com/your-username/threejs-cores#readme",
47
47
  "peerDependencies": {
48
- "three": ">=0.150.0",
48
+ "cannon-es": ">=0.20.0",
49
49
  "gsap": ">=3.0.0",
50
50
  "proj4": ">=2.9.0",
51
- "cannon-es": ">=0.20.0"
51
+ "three": ">=0.150.0"
52
+ },
53
+ "dependencies": {
54
+ "three-mesh-bvh": "^0.9.6"
52
55
  },
53
- "dependencies": {},
54
56
  "devDependencies": {
55
57
  "@rollup/plugin-terser": "^0.4.4",
56
58
  "@types/dat.gui": "^0.7.9",