u-space 0.0.2 → 0.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/interactions/InteractionEvent.ts","../src/interactions/InteractionManager.ts","../src/managers/ObjectManager.ts","../src/viewers/RenderPipeline.ts","../src/viewers/CameraControls.ts","../src/viewers/RoomEnvironment.ts","../src/viewers/ViewerHelper.ts","../src/viewers/Info.ts","../src/viewers/Viewer.ts","../src/loaders/SBMXLoader.ts","../src/loaders/SBMUtils.ts","../src/loaders/SBMLoader.ts","../src/loaders/ModelLoaderManager.ts","../src/loaders/TextureLoaderManager.ts","../src/objects/BaseMesh.ts","../src/objects/BaseGroup.ts","../src/objects/BaseSprite.ts","../src/objects/Model.ts","../src/objects/SphereMesh.ts","../src/objects/TubeMesh.ts","../src/objects/Topology.ts","../src/objects/Poi.ts","../src/objects/ShapeMesh.ts","../src/objects/ExtrudeMesh.ts","../src/objects/PlaneMesh.ts","../src/objects/CircleMesh.ts","../src/objects/ObjectUtils.ts","../src/effects/TSLEffects.ts","../src/types.ts","../src/effects/MaterialEffects.ts","../src/animations/Tween.ts"],"sourcesContent":["import type { Object3D, Intersection, Object3DEventMap } from 'three/webgpu';\n\nexport type InteractionEventType =\n | 'click'\n | 'dblclick'\n | 'rightclick'\n | 'pointerdown'\n | 'pointerup'\n | 'pointermove'\n | 'pointerenter'\n | 'pointerleave'\n\nexport interface InteractionEventParameters {\n type: InteractionEventType;\n target: Object3D<InteractionEventMap>;\n intersect: Intersection<Object3D<InteractionEventMap>> | null;\n originalEvent: PointerEvent | MouseEvent;\n}\n\nexport type InteractionEventMap = Object3DEventMap & {\n [K in InteractionEventType]: { event: InteractionEvent };\n};\n\n/**\n * Custom event class for 3D object interactions.\n * Supports event bubbling via `stopPropagation()`.\n */\nexport class InteractionEvent {\n /** The type of event (e.g., 'click', 'pointerdown'). */\n readonly type: InteractionEventType;\n\n /** The original 3D object that triggered the event. */\n readonly target: Object3D<InteractionEventMap>;\n\n /** The current 3D object during the bubbling phase. */\n currentTarget: Object3D<InteractionEventMap>;\n\n /** The intersection data from raycasting, or null if not applicable. */\n readonly intersect: Intersection | null;\n\n /** The original DOM event, or undefined if not applicable. */\n readonly originalEvent: PointerEvent | MouseEvent;\n\n private _propagationStopped = false;\n\n constructor(init: InteractionEventParameters) {\n this.type = init.type;\n this.target = init.target;\n this.currentTarget = init.target;\n this.intersect = init.intersect;\n this.originalEvent = init.originalEvent;\n }\n\n /**\n * Stops the event from bubbling up the parent chain.\n */\n stopPropagation() {\n this._propagationStopped = true;\n }\n\n /**\n * Returns true if `stopPropagation()` has been called.\n */\n get propagationStopped() {\n return this._propagationStopped;\n }\n}\n","import { Raycaster, Vector2, type Object3D, type Scene, type Camera, type Intersection } from 'three/webgpu';\nimport { InteractionEvent, type InteractionEventMap, type InteractionEventType } from './InteractionEvent';\n\n/**\n * Manages pointer interactions with 3D objects in the scene.\n * Handles raycasting and event dispatching with bubbling support.\n */\nexport class InteractionManager {\n private domElement: HTMLElement;\n private scene: Scene;\n private camera: Camera;\n private raycaster = new Raycaster();\n private pointer = new Vector2();\n private hoveredObject: Object3D<InteractionEventMap> | null = null;\n private pointerDownTime = 0;\n private pointerDownPos = new Vector2();\n private clickTimer: ReturnType<typeof setTimeout> | null = null;\n private longPressThreshold = 500;\n private moveThreshold = 0.01;\n\n /**\n * The objects to check for intersections. default to all children of the scene (including nested).\n */\n targetObjects: Object3D<InteractionEventMap>[];\n\n /**\n * Whether to enable pointer move events (pointermove, pointerenter, pointerleave).\n * Disabled by default for performance optimization.\n */\n pointerMoveEventsEnabled = false;\n\n constructor(domElement: HTMLElement, scene: Scene, camera: Camera) {\n this.domElement = domElement;\n this.scene = scene;\n this.camera = camera;\n this.raycaster.params.Points.threshold = 0.1;\n this.raycaster.params.Line.threshold = 0.1;\n this.targetObjects = this.scene.children as Object3D<InteractionEventMap>[];\n this._bindEvents();\n }\n\n /**\n * Updates the camera reference (useful when switching cameras).\n */\n setCamera(camera: Camera) {\n this.camera = camera;\n }\n\n private _bindEvents() {\n this.domElement.addEventListener('click', this._onClick);\n this.domElement.addEventListener('dblclick', this._onDblClick);\n this.domElement.addEventListener('contextmenu', this._onContextMenu);\n this.domElement.addEventListener('pointerdown', this._onPointerDown);\n this.domElement.addEventListener('pointerup', this._onPointerUp);\n this.domElement.addEventListener('pointermove', this._onPointerMove);\n }\n\n private _updatePointer(event: PointerEvent | MouseEvent) {\n const rect = this.domElement.getBoundingClientRect();\n this.pointer.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n this.pointer.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n }\n\n private _getIntersects(): Intersection<Object3D<InteractionEventMap>>[] {\n this.raycaster.setFromCamera(this.pointer, this.camera);\n return this.raycaster.intersectObjects<Object3D<InteractionEventMap>>(this.targetObjects, true);\n }\n\n /**\n * Dispatches an event to the target object and bubbles up the parent chain.\n */\n private _dispatchToTarget(\n type: InteractionEventType,\n target: Object3D<InteractionEventMap>,\n intersect: Intersection<Object3D<InteractionEventMap>> | null,\n originalEvent: PointerEvent | MouseEvent\n ) {\n const event3d = new InteractionEvent({\n type,\n target,\n intersect,\n originalEvent,\n });\n\n // Bubbling phase: dispatch to target and all ancestors\n let current: Object3D<InteractionEventMap> | null = target;\n while (current && !event3d.propagationStopped) {\n event3d.currentTarget = current;\n // Three.js EventDispatcher expects { type: string, ... }\n current.dispatchEvent({ type, event: event3d });\n current = current.parent as Object3D<InteractionEventMap> | null;\n }\n }\n\n /**\n * Handles a DOM event by raycasting and dispatching to the first intersected object.\n */\n private _handleEvent(type: InteractionEventType, originalEvent: PointerEvent | MouseEvent) {\n this._updatePointer(originalEvent);\n const intersects = this._getIntersects();\n\n if (intersects.length === 0) return;\n\n const hit = intersects[0];\n this._dispatchToTarget(type, hit.object, hit, originalEvent);\n }\n\n private _onClick = (e: MouseEvent) => {\n const duration = Date.now() - this.pointerDownTime;\n const moveDistance = this.pointer.distanceTo(this.pointerDownPos);\n\n if (duration > this.longPressThreshold || moveDistance > this.moveThreshold) {\n return;\n }\n\n if (this.clickTimer) {\n clearTimeout(this.clickTimer);\n this.clickTimer = null;\n return;\n }\n\n this.clickTimer = setTimeout(() => {\n this._handleEvent('click', e);\n this.clickTimer = null;\n }, 200);\n };\n\n private _onDblClick = (e: MouseEvent) => {\n if (this.clickTimer) {\n clearTimeout(this.clickTimer);\n this.clickTimer = null;\n }\n this._handleEvent('dblclick', e);\n };\n\n private _onContextMenu = (e: MouseEvent) => {\n // Suppress the browser context menu; actual 'contextmenu' interaction events\n // are dispatched from _onPointerUp (button === 2) after validating duration/movement.\n e.preventDefault();\n };\n\n private _onPointerDown = (e: PointerEvent) => {\n this.pointerDownTime = Date.now();\n this._updatePointer(e);\n this.pointerDownPos.copy(this.pointer);\n this._handleEvent('pointerdown', e);\n };\n\n private _onPointerUp = (e: PointerEvent) => {\n this._updatePointer(e);\n // Synthesize contextmenu from right-button pointerup so that long-press /\n // drag is excluded (contextmenu fires on mousedown on macOS, making it\n // impossible to filter by duration otherwise).\n if (e.button === 2) {\n const duration = Date.now() - this.pointerDownTime;\n const moveDistance = this.pointer.distanceTo(this.pointerDownPos);\n if (duration <= this.longPressThreshold && moveDistance <= this.moveThreshold) {\n this._handleEvent('rightclick', e);\n }\n }\n this._handleEvent('pointerup', e);\n };\n\n private _onPointerMove = (e: PointerEvent) => {\n if (!this.pointerMoveEventsEnabled) return;\n\n this._updatePointer(e);\n const intersects = this._getIntersects();\n\n const hitObject = intersects.length > 0 ? intersects[0].object : null;\n const intersect = intersects.length > 0 ? intersects[0] : null;\n\n // Handle pointerenter / pointerleave\n if (this.hoveredObject !== hitObject) {\n // Dispatch pointerleave to the old hovered object\n if (this.hoveredObject) {\n this._dispatchToTarget('pointerleave', this.hoveredObject, null, e);\n }\n\n this.hoveredObject = hitObject;\n\n // Dispatch pointerenter to the new hovered object\n if (hitObject && intersect) {\n this._dispatchToTarget('pointerenter', hitObject, intersect, e);\n }\n }\n\n // Dispatch pointermove if over an object\n if (hitObject && intersect) {\n this._dispatchToTarget('pointermove', hitObject, intersect, e);\n }\n };\n\n /**\n * Cleans up event listeners.\n */\n dispose() {\n this.domElement.removeEventListener('click', this._onClick);\n this.domElement.removeEventListener('dblclick', this._onDblClick);\n this.domElement.removeEventListener('contextmenu', this._onContextMenu);\n this.domElement.removeEventListener('pointerdown', this._onPointerDown);\n this.domElement.removeEventListener('pointerup', this._onPointerUp);\n this.domElement.removeEventListener('pointermove', this._onPointerMove);\n this.hoveredObject = null;\n }\n}\n","import type { Object3D } from 'three/webgpu';\n\n/**\n * Manages 3D objects with custom id and name caching for quick retrieval.\n */\nexport class ObjectManager {\n private idMap = new Map<string, Object3D>();\n private nameMap = new Map<string, Set<Object3D>>();\n private typeMap = new Map<string, Set<Object3D>>();\n private objectIds = new Map<Object3D, Set<string>>();\n private allObjects = new Set<Object3D>();\n\n /**\n * Add an object with a custom id.\n * One object can have multiple ids.\n */\n add(id: string, object: Object3D) {\n if (this.idMap.has(id)) {\n console.warn(`ObjectManager: Object with id ${id} already exists.`);\n return;\n }\n\n this.idMap.set(id, object);\n this.allObjects.add(object);\n\n // Track all ids for this object\n if (!this.objectIds.has(object)) {\n this.objectIds.set(object, new Set());\n }\n this.objectIds.get(object)!.add(id);\n\n // Add to name map (Set)\n if (object.name) {\n if (!this.nameMap.has(object.name)) {\n this.nameMap.set(object.name, new Set());\n }\n this.nameMap.get(object.name)!.add(object);\n }\n\n // Add to type map (Set)\n if (object.type) {\n if (!this.typeMap.has(object.type)) {\n this.typeMap.set(object.type, new Set());\n }\n this.typeMap.get(object.type)!.add(object);\n }\n }\n\n /**\n * Get an object by its custom id.\n */\n getById<T extends Object3D>(id: string): T | undefined {\n return this.idMap.get(id) as T | undefined;\n }\n\n /**\n * Get all objects with a given name.\n */\n getByName<T extends Object3D>(name: string): Set<T> {\n return (this.nameMap.get(name) as Set<T>) || new Set();\n }\n\n /**\n * Get all objects with a given type.\n */\n getByType<T extends Object3D>(type: string): Set<T> {\n return (this.typeMap.get(type) as Set<T>) || new Set();\n }\n\n /**\n * Get all ids associated with an object.\n */\n getObjectIds(object: Object3D): Set<string> {\n return this.objectIds.get(object) || new Set();\n }\n\n /**\n * Remove an object and all its associated ids.\n */\n remove(object: Object3D) {\n // Remove all ids associated with this object\n const ids = this.objectIds.get(object);\n if (ids) {\n for (const id of ids) {\n this.idMap.delete(id);\n }\n this.objectIds.delete(object);\n }\n\n // Remove from name map\n if (object.name && this.nameMap.has(object.name)) {\n const set = this.nameMap.get(object.name)!;\n set.delete(object);\n if (set.size === 0) {\n this.nameMap.delete(object.name);\n }\n }\n\n // Remove from type map\n if (object.type && this.typeMap.has(object.type)) {\n const set = this.typeMap.get(object.type)!;\n set.delete(object);\n if (set.size === 0) {\n this.typeMap.delete(object.type);\n }\n }\n\n this.allObjects.delete(object);\n }\n\n /**\n * Remove an object by its id.\n */\n removeById(id: string) {\n const object = this.idMap.get(id);\n if (object) {\n this.remove(object);\n }\n }\n\n /**\n * Remove all objects with a given name.\n */\n removeByName(name: string) {\n const objects = this.getByName(name);\n for (const object of objects) {\n this.remove(object);\n }\n }\n\n /**\n * Remove all objects with a given type.\n */\n removeByType(type: string) {\n const objects = this.getByType(type);\n for (const object of objects) {\n this.remove(object);\n }\n }\n\n /**\n * Clear all cached objects.\n */\n clear() {\n this.idMap.clear();\n this.nameMap.clear();\n this.typeMap.clear();\n this.objectIds.clear();\n this.allObjects.clear();\n }\n\n /**\n * Get all cached objects as a Set.\n */\n getAll<T extends Object3D>(): Set<T> {\n return this.allObjects as Set<T>;\n }\n\n /**\n * Get the number of unique cached objects.\n */\n get size(): number {\n return this.allObjects.size;\n }\n}\n","import { type Scene, type Camera, RenderPipeline as RenderPipelineBase, type Node } from 'three/webgpu';\nimport { blendColor, pass } from 'three/tsl';\n\ntype Args = [ConstructorParameters<typeof RenderPipelineBase>[0], Scene, Camera];\n\nexport class RenderPipeline extends RenderPipelineBase {\n scene: Scene;\n camera: Camera;\n currentOutputNode: Node;\n needsUpdateOutputNode: boolean;\n\n #overlayPasses: Set<Node>;\n\n constructor(...args: Args) {\n const [renderer, scene, camera] = args;\n\n super(renderer);\n\n this.scene = scene;\n this.camera = camera;\n this.currentOutputNode = pass(scene, camera);\n this.needsUpdateOutputNode = true;\n\n this.#overlayPasses = new Set();\n }\n\n addOverlayPass(pass: Node) {\n this.#overlayPasses.add(pass);\n\n this.needsUpdateOutputNode = true;\n }\n\n removeOverlayPass(pass: Node) {\n this.#overlayPasses.delete(pass);\n\n this.needsUpdateOutputNode = true;\n }\n\n setCamera(camera: Camera): void {\n this.camera = camera;\n\n this.needsUpdateOutputNode = true;\n }\n\n setCurrentOutputNode(node: Node) {\n this.currentOutputNode.dispose();\n this.currentOutputNode = node;\n\n this.needsUpdateOutputNode = true;\n }\n\n resetCurrentOutputNode() {\n this.currentOutputNode.dispose();\n this.currentOutputNode = pass(this.scene, this.camera);\n\n this.needsUpdateOutputNode = true;\n }\n\n #updateOutputNode() {\n let currentNode: Node = this.currentOutputNode;\n\n if (this.#overlayPasses.size > 0) {\n this.#overlayPasses.forEach((overlayPass) => {\n currentNode = blendColor(currentNode, overlayPass);\n });\n }\n\n this.outputNode = currentNode;\n this.needsUpdate = true;\n }\n\n render(): void {\n if (this.needsUpdateOutputNode) {\n this.#updateOutputNode();\n this.needsUpdateOutputNode = false;\n }\n\n super.render();\n }\n}\n","import CameraControlsBase from 'camera-controls';\nimport {\n Box3,\n MathUtils,\n Matrix4,\n Quaternion,\n Raycaster,\n Sphere,\n Spherical,\n Vector2,\n Vector3,\n Vector4,\n type Object3D,\n} from 'three/webgpu';\n\nconst subsetOfTHREE = {\n Vector2: Vector2,\n Vector3: Vector3,\n Vector4: Vector4,\n Quaternion: Quaternion,\n Matrix4: Matrix4,\n Spherical: Spherical,\n Box3: Box3,\n Sphere: Sphere,\n Raycaster: Raycaster,\n};\n\nCameraControlsBase.install({ THREE: subsetOfTHREE });\n\nexport interface FlyToBoxOptions {\n viewpoint?:\n | 'current'\n | 'top'\n | 'bottom'\n | 'front'\n | 'back'\n | 'left'\n | 'right'\n | 'frontTop'\n | 'backTop'\n | 'leftTop'\n | 'rightTop'\n | 'leftFrontTop'\n | 'rightFrontTop'\n | 'leftBackTop'\n | 'rightBackTop';\n enableTransition?: boolean;\n padding?: number;\n cover?: boolean;\n}\n\nexport interface FlyToObjectOptions extends FlyToBoxOptions {}\n\nexport class CameraControls extends CameraControlsBase {\n constructor(...args: ConstructorParameters<typeof CameraControlsBase>) {\n super(...args);\n\n this.minDistance = 0.2;\n this.smoothTime = 0.2;\n this.dollySpeed = 0.2;\n }\n\n /**\n * Set absolute angle for azimuth to avoid spinning\n */\n absoluteRotations() {\n this.azimuthAngle = absoluteAngle(this.azimuthAngle, 0);\n }\n\n async flyToBox(box: Box3, options: FlyToBoxOptions = {}) {\n if (box.isEmpty()) {\n console.warn('CameraControls.flyToBox: The provided Box3 is empty.');\n return false;\n }\n\n this.absoluteRotations();\n\n const { viewpoint = 'frontTop', enableTransition = true, padding = 0.1, cover = false } = options;\n\n const promises: Promise<any>[] = [];\n\n if (viewpoint !== 'current') {\n const spherical = viewpointsSpherical[viewpoint.toUpperCase()] ?? viewpointsSpherical.FRONTTOP;\n const azimuthAngle = spherical.theta,\n polarAngle = spherical.phi;\n promises.push(\n this.fitToBox(box, enableTransition, {\n paddingLeft: padding,\n paddingRight: padding,\n paddingTop: padding,\n paddingBottom: padding,\n cover,\n }),\n );\n promises.push(this.rotateTo(azimuthAngle, polarAngle, enableTransition));\n } else {\n const sphere = new Sphere();\n box.getBoundingSphere(sphere);\n sphere.radius += padding;\n promises.push(this.fitToSphere(sphere, enableTransition));\n }\n\n await Promise.all(promises);\n\n return true;\n }\n\n async flyToObject(object: Object3D, options: FlyToObjectOptions = {}) {\n const box = new Box3().setFromObject(object);\n return this.flyToBox(box, options);\n }\n}\n\nconst viewpointsSpherical: { [viewpoint: string]: Spherical } = {\n LEFT: new Spherical(0, Math.PI / 2, -Math.PI / 2),\n RIGHT: new Spherical(0, Math.PI / 2, Math.PI / 2),\n FRONT: new Spherical(0, Math.PI / 2, 0),\n BACK: new Spherical(0, Math.PI / 2, Math.PI),\n TOP: new Spherical(0, 0, 0),\n BOTTOM: new Spherical(0, Math.PI, 0),\n\n FRONTTOP: new Spherical(0, Math.PI / 4, 0),\n BACKTOP: new Spherical(0, Math.PI / 4, Math.PI),\n\n LEFTTOP: new Spherical(0, Math.PI / 4, -Math.PI / 2),\n RIGHTTOP: new Spherical(0, Math.PI / 4, Math.PI / 2),\n\n LEFTFRONTTOP: new Spherical(0, Math.PI / 4, -Math.PI / 4),\n RIGHTFRONTTOP: new Spherical(0, Math.PI / 4, Math.PI / 4),\n\n LEFTBACKTOP: new Spherical(0, Math.PI / 4, (-Math.PI / 4) * 3),\n RIGHTBACKTOP: new Spherical(0, Math.PI / 4, (Math.PI / 4) * 3),\n};\n\nfunction absoluteAngle(targetAngle: number, sourceAngle: number): number {\n const angle = targetAngle - sourceAngle;\n\n return MathUtils.euclideanModulo(angle + Math.PI, Math.PI * 2) - Math.PI;\n}\n","import { PMREMGenerator, type Texture, type WebGPURenderer } from 'three/webgpu';\nimport { RoomEnvironment as RoomEnvironmentClass } from 'three/addons/environments/RoomEnvironment.js';\n\nexport class RoomEnvironment {\n environment = new RoomEnvironmentClass();\n\n renderer: WebGPURenderer;\n pmremGenerator: PMREMGenerator;\n envMap: Texture | null = null;\n\n constructor(renderer: WebGPURenderer) {\n this.renderer = renderer;\n this.pmremGenerator = new PMREMGenerator(renderer);\n }\n\n update() {\n if (!this.envMap) {\n this.envMap = this.pmremGenerator.fromScene(this.environment).texture;\n }\n }\n\n dispose() {\n this.pmremGenerator.dispose();\n this.envMap?.dispose();\n }\n}\n","import { type PassNode, OrthographicCamera } from 'three/webgpu';\nimport { pass } from 'three/tsl';\nimport { ViewHelper as ViewHelperBase } from 'three/addons/helpers/ViewHelper.js';\n\nimport type { Viewer } from './Viewer';\n\nconst dim = 128;\n\nclass ViewerHelper extends ViewHelperBase {\n viewer: Viewer;\n overlayPass: PassNode;\n\n constructor(viewer: Viewer) {\n super(viewer.camera, viewer.el);\n\n this.viewer = viewer;\n\n const orthoCamera = new OrthographicCamera(-2, 2, 2, -2, 0, 4);\n orthoCamera.position.set(0, 0, 2);\n\n this.overlayPass = pass(this, orthoCamera);\n\n this.setLabels('x', 'y', 'z');\n }\n\n _update = () => {\n this.quaternion.copy(this.viewer.camera.quaternion).invert();\n\n const location = this.location;\n\n let x, y;\n\n if (location.left !== null) {\n x = location.left;\n } else {\n x = this.viewer.el.offsetWidth - dim - location.right;\n }\n\n if (location.top !== null) {\n // Position from top\n y = location.top;\n } else {\n // Position from bottom\n y = this.viewer.el.offsetHeight - dim - location.bottom;\n }\n\n this.overlayPass.setViewport(x, y, dim, dim);\n };\n\n enable() {\n this.viewer.renderPipeline.addOverlayPass(this.overlayPass);\n this.viewer.addEventListener('beforeRender', this._update);\n this.viewer.render()\n return this;\n }\n\n disable() {\n this.viewer.renderPipeline.removeOverlayPass(this.overlayPass);\n this.viewer.removeEventListener('beforeRender', this._update);\n this.viewer.render()\n return this;\n }\n}\n\nexport { ViewerHelper };\n","import { TimestampQuery, type WebGPURenderer } from 'three/webgpu';\n\nexport class Info {\n el: HTMLElement;\n renderer: WebGPURenderer;\n\n container: HTMLElement;\n drawCallsText: HTMLElement;\n frameCallsText: HTMLElement;\n trianglesText: HTMLElement;\n pointsText: HTMLElement;\n linesText: HTMLElement;\n timestampText: HTMLElement;\n\n _enabled = false;\n\n constructor(el: HTMLElement, renderer: WebGPURenderer) {\n this.el = el;\n this.renderer = renderer;\n\n const container = document.createElement('div');\n\n container.style.position = 'absolute';\n container.style.left = '12px';\n container.style.bottom = '12px';\n container.style.fontSize = '12px';\n container.style.color = '#fff';\n container.style.pointerEvents = 'none';\n\n this.container = container;\n\n function createTextEl(text: string, isMarginLeft = true): HTMLElement {\n const el = document.createElement('span');\n if (isMarginLeft) el.style.marginLeft = '6px';\n el.innerText = text;\n return el;\n }\n\n function createBr() {\n return document.createElement('br');\n }\n\n this.drawCallsText = createTextEl('0');\n this.frameCallsText = createTextEl('0');\n this.trianglesText = createTextEl('0');\n this.linesText = createTextEl('0');\n this.pointsText = createTextEl('0');\n this.timestampText = createTextEl('0');\n\n // draw calls\n this.container.appendChild(createTextEl('draw calls', false));\n this.container.appendChild(this.drawCallsText);\n this.container.appendChild(createBr());\n\n // frame calls\n this.container.appendChild(createTextEl('frame calls', false));\n this.container.appendChild(this.frameCallsText);\n this.container.appendChild(createBr());\n\n // triangles\n this.container.appendChild(createTextEl('triangles', false));\n this.container.appendChild(this.trianglesText);\n this.container.appendChild(createBr());\n\n // points\n this.container.appendChild(createTextEl('points', false));\n this.container.appendChild(this.pointsText);\n this.container.appendChild(createBr());\n\n // lines\n this.container.appendChild(createTextEl('lines', false));\n this.container.appendChild(this.linesText);\n this.container.appendChild(createBr());\n\n // timestamp\n this.container.appendChild(createTextEl('timestamp', false));\n this.container.appendChild(this.timestampText);\n this.container.appendChild(createBr());\n }\n\n update() {\n if (this._enabled) {\n const { render } = this.renderer.info;\n\n this.drawCallsText.innerText = render.drawCalls.toString();\n this.frameCallsText.innerText = render.frameCalls.toString();\n this.trianglesText.innerText = render.triangles.toString();\n this.pointsText.innerText = render.points.toString();\n this.linesText.innerText = render.lines.toString();\n\n this.renderer.resolveTimestampsAsync(TimestampQuery.RENDER).then((timestamps) => {\n this.timestampText.innerText = timestamps?.toFixed(2) ?? '0';\n });\n }\n }\n\n enable() {\n this._enabled = true;\n this.el.appendChild(this.container);\n }\n\n disable() {\n this._enabled = false;\n this.container.remove();\n }\n\n dispose() {\n this.disable();\n }\n}\n","import {\n EventDispatcher,\n WebGPURenderer,\n Scene,\n PerspectiveCamera,\n Timer,\n AgXToneMapping,\n PCFShadowMap,\n Color,\n OrthographicCamera,\n Cache,\n} from 'three/webgpu';\n// import { Inspector } from 'three/addons/inspector/Inspector.js';\n\nimport { InteractionManager } from '../interactions';\nimport { ObjectManager } from '../managers';\nimport { RenderPipeline } from './RenderPipeline';\nimport { CameraControls } from './CameraControls';\nimport { RoomEnvironment } from './RoomEnvironment';\nimport { ViewerHelper } from './ViewerHelper';\nimport { Info } from './Info';\n\n// Default enable cache\nCache.enabled = true;\n\ntype ViewerRendererOptions = ConstructorParameters<typeof WebGPURenderer>['0'];\n\nexport interface ViewerOptions {\n el: HTMLElement;\n rendererOptions?: ViewerRendererOptions;\n}\n\nexport interface ViewerEventMap {\n beforeControlsUpdate: { time: number };\n afterControlsUpdate: { time: number };\n beforeRender: { time: number };\n afterRender: { time: number };\n cameraChange: { camera: PerspectiveCamera | OrthographicCamera };\n}\n\nclass Viewer extends EventDispatcher<ViewerEventMap> {\n el: HTMLElement;\n renderer: WebGPURenderer;\n scene: Scene;\n camera: PerspectiveCamera | OrthographicCamera;\n info: Info;\n controls: CameraControls;\n renderPipeline: RenderPipeline;\n timer: Timer;\n roomEnvironment: RoomEnvironment;\n interactionManager: InteractionManager;\n objectManager: ObjectManager;\n viewerHelper: ViewerHelper;\n frameCount = 1;\n frameloop: 'always' | 'demand' = 'demand';\n\n constructor({ el, rendererOptions }: ViewerOptions) {\n super();\n\n this.el = el;\n this.renderer = this._initRenderer(rendererOptions);\n this.scene = this.createScene();\n this.camera = this.createPerspectiveCamera();\n this.info = new Info(this.el, this.renderer);\n this.controls = new CameraControls(this.camera, this.renderer.domElement);\n this.renderPipeline = new RenderPipeline(this.renderer, this.scene, this.camera);\n this.timer = new Timer();\n this.roomEnvironment = new RoomEnvironment(this.renderer);\n this.interactionManager = new InteractionManager(this.renderer.domElement, this.scene, this.camera);\n this.objectManager = new ObjectManager();\n this.viewerHelper = new ViewerHelper(this);\n window.addEventListener('resize', this.onWindowResize);\n }\n\n onWindowResize = () => {\n const width = this.el.clientWidth;\n const height = this.el.clientHeight;\n\n if (this.camera instanceof PerspectiveCamera) {\n this.camera.aspect = width / height;\n this.camera.updateProjectionMatrix();\n } else if (this.camera instanceof OrthographicCamera) {\n this.camera.left = -width / 2;\n this.camera.right = width / 2;\n this.camera.top = height / 2;\n this.camera.bottom = -height / 2;\n this.camera.updateProjectionMatrix();\n }\n\n this.renderer.setSize(width, height);\n this.render();\n };\n\n async init() {\n await this.renderer.init();\n\n // Initialize environment\n this.roomEnvironment.update();\n this.scene.environment = this.roomEnvironment.envMap;\n }\n\n setCamera(camera: PerspectiveCamera | OrthographicCamera) {\n this.camera = camera;\n this.controls.camera = camera;\n this.interactionManager.setCamera(camera);\n this.renderPipeline.setCamera(camera);\n this.onWindowResize();\n this.dispatchEvent({ type: 'cameraChange', camera });\n }\n\n setCameraByType(type: 'perspective' | 'orthographic') {\n if (type === 'perspective' && !(this.camera instanceof PerspectiveCamera)) {\n this.setCamera(this.createPerspectiveCamera());\n } else if (type === 'orthographic' && !(this.camera instanceof OrthographicCamera)) {\n this.setCamera(this.createOrthographicCamera());\n }\n }\n\n render(frame = 1) {\n this.frameCount += frame;\n return new Promise<void>((resolve) => {\n const fn = () => {\n this.removeEventListener('afterRender', fn);\n resolve();\n };\n this.addEventListener('afterRender', fn);\n });\n }\n\n private animate = (time: number) => {\n this.timer.update(time);\n\n this.dispatchEvent({ type: 'beforeControlsUpdate', time });\n let needsRender = this.controls.update(this.timer.getDelta());\n this.dispatchEvent({ type: 'afterControlsUpdate', time });\n\n if (this.frameCount > 0) {\n this.frameCount--;\n needsRender = true;\n }\n\n if (this.frameloop === 'always') {\n needsRender = true;\n }\n\n if (needsRender) {\n this.dispatchEvent({ type: 'beforeRender', time });\n this.renderer.info.reset();\n this.renderPipeline.render();\n this.info.update();\n this.dispatchEvent({ type: 'afterRender', time });\n }\n };\n\n private _initRenderer(rendererOptions?: ViewerRendererOptions) {\n const renderer = new WebGPURenderer({\n logarithmicDepthBuffer: true,\n antialias: false,\n depth: false,\n trackTimestamp: true,\n ...rendererOptions,\n });\n renderer.setSize(this.el.clientWidth, this.el.clientHeight);\n renderer.shadowMap.enabled = true;\n renderer.shadowMap.type = PCFShadowMap;\n renderer.toneMapping = AgXToneMapping;\n renderer.toneMappingExposure = 1;\n renderer.info.autoReset = false;\n renderer.setPixelRatio(window.devicePixelRatio);\n renderer.setAnimationLoop(this.animate);\n // renderer.inspector = new Inspector();\n this.el.appendChild(renderer.domElement);\n return renderer;\n }\n\n createScene() {\n const scene = new Scene();\n scene.background = new Color(0x000000);\n return scene;\n }\n\n createPerspectiveCamera() {\n const camera = new PerspectiveCamera(50, this.el.clientWidth / this.el.clientHeight, 0.1, 1e5);\n camera.position.setScalar(5);\n return camera;\n }\n\n createOrthographicCamera() {\n const camera = new OrthographicCamera(\n -this.el.clientWidth / 2,\n this.el.clientWidth / 2,\n this.el.clientHeight / 2,\n -this.el.clientHeight / 2,\n 0.1,\n 1e5,\n );\n camera.position.setScalar(5);\n return camera;\n }\n\n dispose() {\n this.el.removeChild(this.renderer.domElement);\n window.removeEventListener('resize', this.onWindowResize);\n this.info.dispose();\n this.interactionManager.dispose();\n this.roomEnvironment.dispose();\n this.renderPipeline.dispose();\n this.renderer.dispose();\n }\n}\n\nexport { Viewer };\n","import type { LoadingManager } from 'three/webgpu';\nimport { GLTFLoader, type GLTF } from 'three/addons/loaders/GLTFLoader.js';\n\nexport class SBMXLoader extends GLTFLoader {\n constructor(manager?: LoadingManager) {\n super(manager);\n }\n\n parse(data: ArrayBuffer, path: string, onLoad: (gltf: GLTF) => void, onError?: (event: ErrorEvent) => void) {\n const formatName = getAsciiString(data.slice(0, 8));\n switch (formatName) {\n case 'SBMG----': {\n const swappedBuffer = swapBytes(data.slice(8));\n return super.parse(swappedBuffer, path, onLoad, onError);\n }\n default: {\n return super.parse(data, path, onLoad, onError);\n }\n }\n }\n}\n\nfunction getAsciiString(buf: ArrayBuffer): string {\n const decoder = new TextDecoder();\n return decoder.decode(new Uint8Array(buf));\n}\n\nfunction swapBytes(buffer: ArrayBuffer): ArrayBuffer {\n const view = new DataView(buffer);\n for (let i = 0; i < view.byteLength; i++) {\n const byte = view.getUint8(i);\n const swappedByte = ((byte >> 4) & 0x0f) + ((byte << 4) & 0xf0);\n view.setUint8(i, swappedByte);\n }\n return view.buffer;\n}\n","import { Color, MeshStandardNodeMaterial, type Side } from 'three/webgpu';\n\nconst BYTE_LENGTH_MAGIC = 8;\nconst BYTE_LENGTH_HEAD = 130;\nconst BYTE_LENGTH_ATTACH = 66;\n\nconst MAGIC_SBK = 'SBK-----';\nconst MAGIC_SBM = 'SBM-----';\n\nconst textDecoder = new TextDecoder();\nconst textEncoder = new TextEncoder();\n\nexport function decodeSbk(buffer: ArrayBuffer) {\n let read = BYTE_LENGTH_MAGIC;\n\n const magicBytes = new Uint8Array(buffer, 0, read);\n\n const magic = textDecoder.decode(magicBytes);\n\n if (magic !== MAGIC_SBK) {\n return buffer;\n }\n\n read += BYTE_LENGTH_HEAD;\n const headBytes = new Uint8Array(buffer, 0, read);\n const version = headBytes[40];\n\n if (version === 1) {\n const magicBuf = textEncoder.encode(MAGIC_SBM);\n const versionBuf = new Uint8Array([headBytes[41]]);\n\n const sbmKey = getSbmKey(headBytes);\n const encodeKey = getLeftKey(sbmKey);\n\n let j = BYTE_LENGTH_ATTACH % encodeKey.length;\n\n const offset = read + BYTE_LENGTH_ATTACH;\n const bodyBytes = new Uint8Array(buffer, offset);\n const bodyBuf = new Uint8Array(bodyBytes.length);\n\n for (let i = 0; i < bodyBytes.length; i++) {\n bodyBuf[i] = bodyBytes[i] ^ encodeKey[j];\n j = (j + 1) % encodeKey.length;\n }\n\n const buf = new Uint8Array(magicBuf.length + versionBuf.length + bodyBuf.length);\n\n buf.set(magicBuf);\n buf.set(versionBuf, magicBuf.length);\n buf.set(bodyBuf, magicBuf.length + versionBuf.length);\n\n return buf.buffer;\n }\n}\n\nfunction getSbmKey(headBuffer: Uint8Array) {\n const bytes = new Uint8Array(128);\n\n bytes.set(headBuffer.slice(42, 42 + 32), 0);\n bytes.set(headBuffer.slice(74, 74 + 64), 32);\n bytes.set(headBuffer.slice(8, 8 + 32), 96);\n\n return bytes;\n}\n\nfunction getLeftKey(sbmKey: Uint8Array) {\n const bytes = new Uint8Array(64);\n\n bytes.set(sbmKey.slice(0, 8), 0);\n bytes.set(sbmKey.slice(24, 24 + 8), 8);\n bytes.set(sbmKey.slice(40, 40 + 16), 16);\n bytes.set(sbmKey.slice(64, 64 + 24), 32);\n bytes.set(sbmKey.slice(96, 96 + 8), 56);\n\n return bytes;\n}\n\nexport const getTextureName = (dataView: DataView, texnamelen: number, offset: number): string => {\n const temp = dataView.buffer.slice(offset, offset + texnamelen);\n let textureName = textDecoder.decode(temp);\n textureName = textureName.replace('\\\\', '/');\n if (!textureName.startsWith('Maps/')) {\n textureName = `Maps/${textureName}`;\n }\n return textureName;\n};\n\nexport const generateSbmMaterial = (materialId: string, arr: number[], png: boolean) => {\n const [d0, d1, d2, d3, side] = arr;\n\n const trans = png || d3 < 1;\n\n const material = new MeshStandardNodeMaterial({\n name: materialId,\n color: new Color(d0, d1, d2),\n opacity: d3,\n transparent: trans,\n alphaTest: 0.01,\n side: side as Side,\n });\n\n return material;\n};\n\nexport const isPNG = (textureUrl?: string): boolean => {\n return textureUrl?.toLowerCase().endsWith('.png') ?? false;\n};\n","import {\n BackSide,\n BufferAttribute,\n BufferGeometry,\n DoubleSide,\n FileLoader,\n FrontSide,\n Group,\n Loader,\n LoaderUtils,\n Mesh,\n MeshStandardNodeMaterial,\n RepeatWrapping,\n SRGBColorSpace,\n TextureLoader,\n Vector2,\n Vector3,\n type LoadingManager,\n} from 'three/webgpu';\nimport { decodeSbk, generateSbmMaterial, getTextureName, isPNG } from './SBMUtils';\n\ninterface SBMParserOptions {\n path: string;\n crossOrigin: string;\n requestHeader: Record<string, string>;\n manager: LoadingManager;\n}\n\nclass SBMParser {\n data: ArrayBuffer;\n options: SBMParserOptions;\n textureLoader: TextureLoader;\n\n littleEndian = true;\n materials = new Map<string, MeshStandardNodeMaterial>();\n\n constructor(data: ArrayBuffer, options: SBMParserOptions) {\n this.data = data;\n this.options = options;\n\n this.textureLoader = new TextureLoader(options.manager);\n this.textureLoader.setCrossOrigin(options.crossOrigin);\n this.textureLoader.setRequestHeader(options.requestHeader);\n }\n\n parse(onLoad: (sbm: Group) => void, onError?: (err: unknown) => void): void {\n let buffer = this.data;\n\n const decodeBuffer = decodeSbk(this.data);\n if (decodeBuffer) {\n buffer = decodeBuffer;\n }\n\n const dataView = new DataView(buffer);\n let offset = 8;\n const version = dataView.getUint8(offset);\n offset += 1;\n\n if (version === 1) {\n this._parseV2(dataView, offset, onLoad);\n } else if (version === 2) {\n this._parseV2(dataView, offset, onLoad);\n } else if (version === 3) {\n this._parseV3(dataView, offset, onLoad);\n } else {\n onError?.(new Error(`SBMLoader: Unsupported SBM version: ${version}`));\n }\n }\n\n _parseV2(dataView: DataView, offset: number, onLoad: (sbm: Group) => void): void {\n const sbm = new Group();\n\n // 材质数量\n const materialCount = dataView.getUint16(offset, this.littleEndian);\n offset += 2;\n\n // Mesh 数量\n const meshCount = dataView.getUint16(offset, this.littleEndian);\n offset += 2;\n\n // 准备材质\n for (let i = 0; i < materialCount; ++i) {\n // 材质ID\n const materialId = dataView.getUint16(offset, this.littleEndian).toString();\n\n offset += 2;\n\n // a\n\n offset += 4;\n\n offset += 4;\n\n offset += 4;\n\n offset += 4;\n\n //d\n const d0 = dataView.getFloat32(offset, this.littleEndian);\n offset += 4;\n const d1 = dataView.getFloat32(offset, this.littleEndian);\n offset += 4;\n const d2 = dataView.getFloat32(offset, this.littleEndian);\n offset += 4;\n const d3 = dataView.getFloat32(offset, this.littleEndian);\n offset += 4;\n\n // s\n\n offset += 4;\n\n offset += 4;\n\n offset += 4;\n\n offset += 4;\n\n // side\n let side: number = dataView.getUint8(offset);\n\n offset += 1;\n\n // sync threejs side\n if (side === 0) side = FrontSide;\n else if (side === 1) side = BackSide;\n else if (side === 2) side = DoubleSide;\n\n // 纹理名称长度\n const textureNameLength: number = dataView.getUint16(offset, this.littleEndian);\n\n offset += 2;\n\n // 纹理名称\n const textureName = textureNameLength > 0 ? getTextureName(dataView, textureNameLength, offset) : '';\n\n offset += textureNameLength;\n\n if (!this.materials.has(materialId)) {\n const materialInfo = [d0, d1, d2, d3, side];\n\n const material = generateSbmMaterial(materialId, materialInfo, isPNG(textureName));\n\n this.materials.set(materialId, material);\n\n if (textureName && this.options.path) {\n this.textureLoader.load(LoaderUtils.resolveURL(textureName, this.options.path), (texture) => {\n texture.colorSpace = SRGBColorSpace;\n texture.wrapS = RepeatWrapping;\n texture.wrapT = RepeatWrapping;\n texture.flipY = false;\n texture.anisotropy = 16;\n material.map = texture;\n });\n }\n }\n }\n\n // 准备结构\n for (let i = 0; i < meshCount; ++i) {\n // 网格ID\n const meshId = dataView.getUint16(offset, this.littleEndian).toString();\n\n offset += 2;\n\n // 对应材质ID\n const materialId = dataView.getUint16(offset, this.littleEndian).toString();\n\n offset += 2;\n\n const vertices = [];\n const texcoords = [];\n const faces = [];\n const faceVertexUvs = [];\n\n // verticesCount\n const verticesCount = dataView.getUint16(offset, this.littleEndian);\n\n offset += 2;\n\n if (verticesCount > 0) {\n for (let j = 0; j < verticesCount; j++) {\n const vector3 = new Vector3();\n\n // x\n vector3.setX(dataView.getFloat32(offset, this.littleEndian));\n offset += 4;\n\n // y\n vector3.setY(dataView.getFloat32(offset, this.littleEndian));\n offset += 4;\n\n // z\n vector3.setZ(dataView.getFloat32(offset, this.littleEndian));\n offset += 4;\n\n vertices.push(vector3);\n }\n }\n\n // normalsCount\n const normalsCount = dataView.getUint16(offset, this.littleEndian);\n\n offset += 2;\n\n if (normalsCount > 0) {\n for (let j = 0; j < normalsCount; j++) {\n // x\n offset += 4;\n\n // y\n offset += 4;\n\n // z\n offset += 4;\n }\n }\n\n // texcoordCount\n const texcoordCount = dataView.getUint16(offset, this.littleEndian);\n\n offset += 2;\n\n if (texcoordCount > 0) {\n for (let j = 0; j < texcoordCount; j++) {\n const texcoord = new Vector2();\n\n // x\n texcoord.setX(dataView.getFloat32(offset, this.littleEndian));\n offset += 4;\n\n // y\n texcoord.setY(dataView.getFloat32(offset, this.littleEndian));\n offset += 4;\n\n texcoords.push(texcoord);\n }\n }\n\n // idxCount\n const idxCount = dataView.getUint16(offset, this.littleEndian);\n\n offset += 2;\n\n if (idxCount > 0) {\n for (let j = 0; j < idxCount; j++) {\n // a\n const a = dataView.getUint16(offset, this.littleEndian);\n\n offset += 2;\n\n // b\n const b = dataView.getUint16(offset, this.littleEndian);\n\n offset += 2;\n\n // c\n const c = dataView.getUint16(offset, this.littleEndian);\n\n offset += 2;\n\n const face = [a, b, c];\n\n faces.push(face);\n\n if (texcoords.length > 0) {\n faceVertexUvs.push([texcoords[face[0]], texcoords[face[1]], texcoords[face[2]]]);\n }\n }\n }\n\n const positions = [],\n uvs = [];\n\n for (let i = 0; i < faces.length; i++) {\n const face = faces[i];\n\n // 顶点\n const vertex = vertices[face[0]],\n vertex2 = vertices[face[1]],\n vertex3 = vertices[face[2]];\n\n // 缓存顶点\n positions.push(...vertex.toArray(), ...vertex2.toArray(), ...vertex3.toArray());\n\n let uv = new Vector2(),\n uv2 = new Vector2(),\n uv3 = new Vector2();\n\n const vertexUvs = faceVertexUvs[i];\n\n if (vertexUvs !== undefined) {\n uv = vertexUvs[0];\n uv2 = vertexUvs[1];\n uv3 = vertexUvs[2];\n }\n\n // 缓存 uv\n uvs.push(...uv.toArray(), ...uv2.toArray(), ...uv3.toArray());\n }\n\n const positionArray = new Float32Array(positions),\n uvArray = new Float32Array(uvs);\n\n // 准备几何体\n const bufferGeometry = new BufferGeometry();\n\n // position\n if (positionArray.length > 0) {\n bufferGeometry.setAttribute('position', new BufferAttribute(positionArray, 3));\n }\n // uv\n if (uvArray.length > 0) {\n bufferGeometry.setAttribute('uv', new BufferAttribute(uvArray, 2));\n }\n\n bufferGeometry.computeVertexNormals();\n\n if (this.materials.has(materialId)) {\n const sbmChild = new Mesh(bufferGeometry, this.materials.get(materialId));\n\n sbmChild.name = meshId;\n sbmChild.castShadow = true;\n sbmChild.receiveShadow = true;\n\n sbm.add(sbmChild);\n }\n }\n\n onLoad(sbm);\n }\n\n _parseV3(_dataView: DataView, _offset: number, onLoad: (sbm: Group) => void): void {\n const sbm = new Group();\n\n /// TODO: Implement SBM version 3 parsing logic here\n console.warn('SBMLoader: SBM version 3 is not supported yet.');\n\n onLoad(sbm);\n }\n}\n\nexport class SBMLoader extends Loader<Group, string> {\n load(\n url: string,\n onLoad: (sbm: Group) => void,\n onProgress?: (event: ProgressEvent) => void,\n onError?: (err: unknown) => void\n ): void {\n let resourcePath;\n\n if (this.resourcePath !== '') {\n resourcePath = this.resourcePath;\n } else if (this.path !== '') {\n const relativeUrl = LoaderUtils.extractUrlBase(url);\n resourcePath = LoaderUtils.resolveURL(relativeUrl, this.path);\n } else {\n resourcePath = LoaderUtils.extractUrlBase(url);\n }\n\n this.manager.itemStart(url);\n\n const _onError = (e: unknown) => {\n if (onError) {\n onError(e);\n } else {\n console.error(e);\n }\n this.manager.itemError(url);\n this.manager.itemEnd(url);\n };\n\n const loader = new FileLoader(this.manager);\n\n loader.setPath(this.path);\n loader.setResponseType('arraybuffer');\n loader.setRequestHeader(this.requestHeader);\n loader.setWithCredentials(this.withCredentials);\n\n loader.load(\n url,\n (data) => {\n try {\n this.parse(\n data as ArrayBuffer,\n resourcePath,\n (sbm) => {\n onLoad(sbm);\n this.manager.itemEnd(url);\n },\n _onError\n );\n } catch (e) {\n _onError(e);\n }\n },\n onProgress,\n _onError\n );\n }\n\n parse(data: ArrayBuffer, path: string, onLoad: (sbm: Group) => void, onError?: (err: unknown) => void): void {\n const formatName = new TextDecoder().decode(data.slice(0, 8));\n\n if (formatName !== 'SBK-----' && formatName !== 'SBM-----') {\n onError?.(new Error(`SBMLoader: Invalid SBM format: ${formatName}`));\n return;\n }\n\n const parser = new SBMParser(data, {\n path,\n crossOrigin: this.crossOrigin,\n requestHeader: this.requestHeader,\n manager: this.manager,\n });\n\n parser.parse(onLoad, onError);\n }\n\n parseAsync(data: ArrayBuffer | string, path: string): Promise<Group> {\n return new Promise((resolve, reject) => {\n this.parse(\n data as ArrayBuffer,\n path,\n (sbm) => {\n resolve(sbm);\n },\n (err) => {\n reject(err);\n }\n );\n });\n }\n}\n","import {\n REVISION,\n Mesh,\n MeshStandardNodeMaterial,\n LoaderUtils,\n FileLoader,\n type Object3D,\n type WebGPURenderer,\n type LoadingManager,\n} from 'three/webgpu';\nimport { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';\nimport { FBXLoader } from 'three/addons/loaders/FBXLoader.js';\nimport { OBJLoader } from 'three/addons/loaders/OBJLoader.js';\nimport { STLLoader } from 'three/addons/loaders/STLLoader.js';\nimport { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';\nimport { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js';\nimport { MeshoptDecoder } from 'three/addons/libs/meshopt_decoder.module.js';\n\nimport { SBMXLoader } from './SBMXLoader';\nimport { SBMLoader } from './SBMLoader';\n\nimport type { InteractionEventMap } from '../interactions';\n\nexport interface LoadParameters {\n persistent?: boolean;\n}\n\nexport class ModelLoaderManager {\n private static CACHE_NAME = 'u-space-model-loader-cache';\n\n static fileLoader = new FileLoader().setResponseType('arraybuffer');\n static dracoLoader = new DRACOLoader().setDecoderPath(\n `https://cdn.jsdelivr.net/npm/three@0.${REVISION}.0/examples/jsm/libs/draco/`,\n );\n static ktx2Loader = new KTX2Loader().setTranscoderPath(\n `https://cdn.jsdelivr.net/npm/three@0.${REVISION}.0/examples/jsm/libs/basis/`,\n );\n static gltfLoader = new GLTFLoader()\n .setDRACOLoader(ModelLoaderManager.dracoLoader)\n .setKTX2Loader(ModelLoaderManager.ktx2Loader)\n .setMeshoptDecoder(MeshoptDecoder);\n static sbmxLoader = new SBMXLoader()\n .setDRACOLoader(ModelLoaderManager.dracoLoader)\n .setKTX2Loader(ModelLoaderManager.ktx2Loader)\n .setMeshoptDecoder(MeshoptDecoder);\n static sbmLoader = new SBMLoader();\n static fbxLoader = new FBXLoader();\n static objLoader = new OBJLoader();\n static stlLoader = new STLLoader();\n\n static setLoadingManager(loadingManager: LoadingManager) {\n this.fileLoader.manager = loadingManager;\n this.dracoLoader.manager = loadingManager;\n this.ktx2Loader.manager = loadingManager;\n this.gltfLoader.manager = loadingManager;\n this.sbmxLoader.manager = loadingManager;\n this.sbmLoader.manager = loadingManager;\n this.fbxLoader.manager = loadingManager;\n this.objLoader.manager = loadingManager;\n this.stlLoader.manager = loadingManager;\n }\n\n /**\n * Set the renderer to enable KTX2 support and other renderer-dependent features.\n */\n static async setRenderer(renderer: WebGPURenderer) {\n await renderer.init();\n this.ktx2Loader.detectSupport(renderer);\n }\n\n /**\n * Configure Draco decoder path.\n */\n static setDracoPath(path: string) {\n this.dracoLoader.setDecoderPath(path);\n }\n\n /**\n * Configure KTX2 transcoder path.\n */\n static setKTX2Path(path: string) {\n this.ktx2Loader.setTranscoderPath(path);\n }\n\n static async loadAsync(\n url: string,\n parameters: LoadParameters = { persistent: true },\n ): Promise<Object3D<InteractionEventMap>> {\n const extension = url.split('.').pop()?.split('?')[0].toLowerCase();\n\n let buffer: ArrayBuffer;\n\n if (parameters.persistent && typeof caches !== 'undefined') {\n buffer = await this.getPersistentData(url);\n } else {\n buffer = (await this.fileLoader.loadAsync(url)) as ArrayBuffer;\n }\n\n switch (extension) {\n case 'gltf':\n case 'glb':\n const gltf = await this.gltfLoader.parseAsync(buffer, LoaderUtils.extractUrlBase(url));\n return gltf.scene;\n case 'sbmx':\n const sbmx = await this.sbmxLoader.parseAsync(buffer, LoaderUtils.extractUrlBase(url));\n return sbmx.scene;\n case 'sbm':\n const sbm = await this.sbmLoader.parseAsync(buffer, LoaderUtils.extractUrlBase(url));\n return sbm;\n case 'fbx':\n const fbx = this.fbxLoader.parse(buffer, LoaderUtils.extractUrlBase(url));\n return fbx;\n case 'obj':\n const text = new TextDecoder().decode(buffer);\n const obj = this.objLoader.parse(text);\n return obj;\n case 'stl':\n const geometry = this.stlLoader.parse(buffer);\n const mesh = new Mesh(geometry, new MeshStandardNodeMaterial());\n return mesh;\n default:\n throw new Error(`Unsupported model format: ${extension}`);\n }\n }\n\n private static async getPersistentData(url: string): Promise<ArrayBuffer> {\n try {\n const cache = await caches.open(this.CACHE_NAME);\n const cachedResponse = await cache.match(url);\n\n if (cachedResponse) {\n return await cachedResponse.arrayBuffer();\n }\n\n const buffer = (await this.fileLoader.loadAsync(url)) as ArrayBuffer;\n const response = new Response(buffer);\n await cache.put(url, response);\n return buffer;\n } catch (error) {\n console.warn(`[LoaderManager] Failed to use Cache API for ${url}:`, error);\n return (await this.fileLoader.loadAsync(url)) as ArrayBuffer;\n }\n }\n}\n","import { TextureLoader, CubeTextureLoader, EquirectangularReflectionMapping, type LoadingManager } from 'three/webgpu';\nimport { HDRLoader } from 'three/addons/loaders/HDRLoader.js';\n\nexport class TextureLoaderManager {\n static textureLoader = new TextureLoader();\n static hdrLoader = new HDRLoader();\n static cubeTextureLoader = new CubeTextureLoader();\n\n static setLoadingManager(loadingManager: LoadingManager) {\n this.textureLoader.manager = loadingManager;\n this.hdrLoader.manager = loadingManager;\n this.cubeTextureLoader.manager = loadingManager;\n }\n\n static async loadAsyncTexture(url: string) {\n const texture = await this.textureLoader.loadAsync(url);\n return texture;\n }\n\n static async loadAsyncHDR(url: string) {\n const dataTexture = await this.hdrLoader.loadAsync(url);\n dataTexture.mapping = EquirectangularReflectionMapping;\n return dataTexture;\n }\n\n static async loadAsyncCubeTexture(path: string, urls: string[]) {\n this.cubeTextureLoader.setPath(path);\n const cubeTexture = await this.cubeTextureLoader.loadAsync(urls);\n return cubeTexture;\n }\n}\n","import {\n type BufferGeometry,\n type Intersection,\n type Material,\n type Object3DEventMap,\n type Raycaster,\n Mesh,\n} from 'three/webgpu';\n\nexport class BaseMesh<\n TGeometry extends BufferGeometry = BufferGeometry,\n TMaterial extends Material | Material[] = Material | Material[],\n TEventMap extends Object3DEventMap = Object3DEventMap\n> extends Mesh<TGeometry, TMaterial, TEventMap> {\n readonly isBaseMesh = true;\n type = 'BaseMesh';\n\n ignoreInvisibleWhenRaycast = true;\n\n constructor(...args: ConstructorParameters<typeof Mesh<TGeometry, TMaterial, TEventMap>>) {\n super(...args);\n }\n\n raycast(raycaster: Raycaster, intersects: Intersection[]): boolean | void {\n if (this.visible === false && this.ignoreInvisibleWhenRaycast === true) {\n // Stop propagation if the mesh is not visible\n return false;\n }\n return super.raycast(raycaster, intersects);\n }\n}\n","import { type Raycaster, type Intersection, type Object3DEventMap, Group } from 'three/webgpu';\n\nexport class BaseGroup<TEventMap extends Object3DEventMap = Object3DEventMap> extends Group<TEventMap> {\n readonly isBaseGroup = true;\n type = 'BaseGroup';\n\n ignoreInvisibleWhenRaycast = true;\n\n constructor(...args: ConstructorParameters<typeof Group<TEventMap>>) {\n super(...args);\n }\n\n raycast(raycaster: Raycaster, intersects: Intersection[]): boolean | void {\n if (this.visible === false && this.ignoreInvisibleWhenRaycast === true) {\n // Stop propagation if the group is not visible\n return false;\n }\n return super.raycast(raycaster, intersects);\n }\n}\n","import { type Raycaster, type Intersection, type Object3DEventMap, Sprite } from 'three/webgpu';\n\nexport class BaseSprite<TEventMap extends Object3DEventMap = Object3DEventMap> extends Sprite<TEventMap> {\n readonly isBaseSprite = true;\n type = 'BaseSprite';\n\n ignoreInvisibleWhenRaycast = true;\n\n constructor(...args: ConstructorParameters<typeof Sprite<TEventMap>>) {\n super(...args);\n }\n\n raycast(raycaster: Raycaster, intersects: Intersection[]): boolean | void {\n if (this.visible === false && this.ignoreInvisibleWhenRaycast === true) {\n // Stop propagation if the sprite is not visible\n return false;\n }\n return super.raycast(raycaster, intersects);\n }\n}\n","import { type Object3D } from 'three/webgpu';\nimport { clone } from 'three/addons/utils/SkeletonUtils.js';\n\nimport { ModelLoaderManager } from '../loaders';\nimport { type InteractionEventMap } from '../interactions';\nimport { BaseGroup } from './BaseGroup';\n\nexport interface ModelParameters {\n url: string;\n cache?: boolean; // Layer 1: Memory cache (Object-level)\n persistent?: boolean; // Layer 2: Browser Cache API (File-level)\n}\n\nexport class Model extends BaseGroup<InteractionEventMap> {\n readonly isModel = true;\n type = 'Model';\n\n private static memoryCache = new Map<string, Promise<Object3D<InteractionEventMap>>>();\n\n constructor() {\n super();\n }\n\n async loadAsync(parameters: ModelParameters) {\n const { url, cache = true, persistent = true } = parameters;\n\n try {\n let objectPromise: Promise<Object3D<InteractionEventMap>>;\n\n if (cache) {\n if (Model.memoryCache.has(url)) {\n objectPromise = Model.memoryCache.get(url)!;\n } else {\n objectPromise = ModelLoaderManager.loadAsync(url, { persistent });\n Model.memoryCache.set(url, objectPromise);\n }\n } else {\n objectPromise = ModelLoaderManager.loadAsync(url, { persistent });\n }\n\n const object = await objectPromise;\n\n // Clone the object to ensure multiple Model instances don't share the same Object3D state\n // especially if it's from cache.\n const clonedObject = clone(object);\n this.add(clonedObject);\n\n return clonedObject;\n } catch (error) {\n console.error(`[Model] Failed to load model from ${url}:`, error);\n return null;\n }\n }\n\n static clearMemoryCache() {\n this.memoryCache.clear();\n }\n\n static async clearPersistentCache() {\n if (typeof caches !== 'undefined') {\n await caches.delete('u-space-loader-cache');\n }\n }\n}\n","import { SphereGeometry, MeshStandardNodeMaterial, type MeshStandardNodeMaterialParameters } from 'three/webgpu';\n\nimport type { InteractionEventMap } from '../interactions';\nimport { BaseMesh } from './BaseMesh';\n\nexport interface SphereMeshParameters {\n geometryParameters?: {\n radius?: number;\n widthSegments?: number;\n heightSegments?: number;\n phiStart?: number;\n phiLength?: number;\n thetaStart?: number;\n thetaLength?: number;\n };\n materialParameters?: MeshStandardNodeMaterialParameters;\n}\n\nexport class SphereMesh extends BaseMesh<SphereGeometry, MeshStandardNodeMaterial, InteractionEventMap> {\n readonly isSphereMesh = true;\n type = 'SphereMesh';\n\n constructor({ geometryParameters, materialParameters }: SphereMeshParameters = {}) {\n super();\n\n this.geometry = new SphereGeometry(\n geometryParameters?.radius,\n geometryParameters?.widthSegments,\n geometryParameters?.heightSegments,\n geometryParameters?.phiStart,\n geometryParameters?.phiLength,\n geometryParameters?.thetaStart,\n geometryParameters?.thetaLength\n );\n this.material = new MeshStandardNodeMaterial(materialParameters);\n }\n}\n","import {\n TubeGeometry,\n MeshStandardNodeMaterial,\n type Vector3,\n type Curve,\n type MeshStandardNodeMaterialParameters,\n} from 'three/webgpu';\n\nimport type { InteractionEventMap } from '../interactions';\nimport { BaseMesh } from './BaseMesh';\n\nexport interface TubeMeshParameters {\n geometryParameters?: {\n path?: Curve<Vector3>;\n tubularSegments?: number;\n radius?: number;\n radialSegments?: number;\n closed?: boolean;\n };\n materialParameters?: MeshStandardNodeMaterialParameters;\n}\n\nexport class TubeMesh extends BaseMesh<TubeGeometry, MeshStandardNodeMaterial, InteractionEventMap> {\n readonly isTubeMesh = true;\n type = 'TubeMesh';\n\n constructor({ geometryParameters, materialParameters }: TubeMeshParameters = {}) {\n super();\n\n this.geometry = new TubeGeometry(\n geometryParameters?.path,\n geometryParameters?.tubularSegments,\n geometryParameters?.radius,\n geometryParameters?.radialSegments,\n geometryParameters?.closed\n );\n this.material = new MeshStandardNodeMaterial(materialParameters);\n }\n}\n","import { Vector3, Mesh, Group, LineCurve3, CatmullRomCurve3, type ColorRepresentation } from 'three/webgpu';\n\nimport type { InteractionEventMap } from '../interactions';\nimport { SphereMesh } from './SphereMesh';\nimport { TubeMesh } from './TubeMesh';\nimport { BaseGroup } from './BaseGroup';\n\nexport type TopologyData = {\n nodes: Record<string, { x: number; y: number; z: number }>;\n edges: Array<{ from: string; to: string; weight: number }>;\n};\n\nexport interface TopologyParameters {\n nodeColor?: ColorRepresentation;\n nodeRadius?: number;\n edgeColor?: ColorRepresentation;\n edgeRadius?: number; // Renamed or mapped from width\n pathColor?: ColorRepresentation;\n pathRadius?: number; // Renamed or mapped from width\n}\n\nexport class Topology extends BaseGroup<InteractionEventMap> {\n readonly isTopology = true;\n type = 'Topology';\n\n // Visuals\n parameters: Required<TopologyParameters> = {\n nodeColor: 0x0000ff,\n nodeRadius: 0.5,\n edgeColor: 0x00ff00,\n edgeRadius: 0.1,\n pathColor: 0xff00ff,\n pathRadius: 0.2,\n };\n\n nodes = new Map<string, Vector3>();\n adjacencyMap = new Map<string, Map<string, number>>();\n\n graphGroup: Group<InteractionEventMap> | null = null;\n pathMeshes: TubeMesh[] = [];\n\n constructor(parameters?: TopologyParameters) {\n super();\n if (parameters) {\n Object.assign(this.parameters, parameters);\n }\n }\n\n /**\n * Add a node to the topology graph.\n * @param id Unique identifier for the node\n * @param position 3D position of the node\n */\n addNode(id: string, position: Vector3) {\n if (this.nodes.has(id)) {\n console.warn(`[Topology] Node ${id} already exists. Overwriting.`);\n }\n this.nodes.set(id, position);\n if (!this.adjacencyMap.has(id)) {\n this.adjacencyMap.set(id, new Map());\n }\n }\n\n /**\n * Remove a node from the topology graph.\n * @param id Unique identifier for the node\n */\n removeNode(id: string) {\n if (!this.nodes.has(id)) {\n console.warn(`[Topology] Node ${id} does not exist.`);\n return;\n }\n this.nodes.delete(id);\n this.adjacencyMap.delete(id);\n }\n\n /**\n * Add an edge between two nodes.\n * @param from Node ID\n * @param to Node ID\n * @param weight Cost of the edge. Defaults to Euclidean distance.\n * @param bidirectional If true, adds the reverse edge as well. Default true.\n */\n addEdge(from: string, to: string, weight?: number, bidirectional = true) {\n const fromPos = this.nodes.get(from);\n const toPos = this.nodes.get(to);\n\n if (!fromPos || !toPos) {\n console.error(`[Topology] Cannot add edge. One or both nodes not found: ${from}, ${to}`);\n return;\n }\n\n const dist = weight ?? fromPos.distanceTo(toPos);\n\n this.getNeighbors(from)?.set(to, dist);\n if (bidirectional) {\n this.getNeighbors(to)?.set(from, dist);\n }\n }\n\n /**\n * Remove an edge between two nodes.\n * @param from Node ID\n * @param to Node ID\n * @param bidirectional If true, removes the reverse edge as well. Default true.\n */\n removeEdge(from: string, to: string, bidirectional = true) {\n const fromNeighbors = this.getNeighbors(from);\n fromNeighbors?.delete(to);\n\n if (bidirectional) {\n const toNeighbors = this.getNeighbors(to);\n toNeighbors?.delete(from);\n }\n }\n\n /**\n * Find the shortest path between start and end nodes using Dijkstra's algorithm.\n */\n getShortestPath(startId: string, endId: string): Vector3[] {\n if (!this.nodes.has(startId) || !this.nodes.has(endId)) {\n console.warn(`[Topology] Start or End node not found.`);\n return [];\n }\n\n const distances = new Map<string, number>();\n const previous = new Map<string, string | null>();\n const unvisited = new Set<string>();\n\n for (const [id] of this.nodes) {\n distances.set(id, Infinity);\n previous.set(id, null);\n unvisited.add(id);\n }\n distances.set(startId, 0);\n\n while (unvisited.size > 0) {\n // Find node with min distance\n let currentId: string | null = null;\n let minDist = Infinity;\n\n for (const id of unvisited) {\n const d = distances.get(id)!;\n if (d < minDist) {\n minDist = d;\n currentId = id;\n }\n }\n\n if (currentId === null || currentId === endId) {\n break;\n }\n if (minDist === Infinity) {\n break; // No reachable path\n }\n\n unvisited.delete(currentId);\n\n const neighbors = this.adjacencyMap?.get(currentId);\n\n if (!neighbors) {\n continue;\n }\n\n for (const [to, weight] of neighbors) {\n if (!unvisited.has(to)) continue;\n\n const alt = distances.get(currentId)! + weight;\n if (alt < distances.get(to)!) {\n distances.set(to, alt);\n previous.set(to, currentId);\n }\n }\n }\n\n // Reconstruct path\n const path: Vector3[] = [];\n let curr: string | null = endId;\n\n // Check if reachable\n if (previous.get(endId) === null && startId !== endId) {\n return [];\n }\n\n while (curr !== null) {\n const pos = this.nodes.get(curr);\n if (pos) path.unshift(pos);\n curr = previous.get(curr) || null;\n }\n\n return path;\n }\n\n /**\n * Renders the entire topology graph structure using TubeGeometry and Spheres.\n */\n renderGraph() {\n this.clearGraph();\n\n this.graphGroup = new Group();\n\n // 1. Render Nodes (Spheres)\n const _dummySphere = new SphereMesh({\n geometryParameters: {\n radius: this.parameters.nodeRadius,\n widthSegments: 16,\n heightSegments: 16,\n },\n materialParameters: {\n color: this.parameters.nodeColor,\n },\n });\n\n this.nodes.forEach((pos, id) => {\n const nodeMesh = _dummySphere.clone();\n nodeMesh.position.copy(pos);\n Object.assign(nodeMesh.userData, { id, type: 'node' });\n this.graphGroup!.add(nodeMesh);\n });\n\n // 2. Render Edges (TubeGeometry)\n const processedEdges = new Set<string>();\n\n this.adjacencyMap.forEach((edges, from) => {\n edges.forEach((weight, to) => {\n const key = [from, to].sort().join('-');\n if (processedEdges.has(key)) return;\n processedEdges.add(key);\n\n const p1 = this.nodes.get(from);\n const p2 = this.nodes.get(to);\n if (p1 && p2) {\n const path = new LineCurve3(p1, p2);\n const tubeMesh = new TubeMesh({\n geometryParameters: {\n path,\n tubularSegments: 1,\n radius: this.parameters.edgeRadius,\n radialSegments: 8,\n closed: false,\n },\n materialParameters: {\n color: this.parameters.edgeColor,\n },\n });\n Object.assign(tubeMesh.userData, { from, to, weight, type: 'edge' });\n this.graphGroup!.add(tubeMesh);\n }\n });\n });\n\n this.add(this.graphGroup);\n }\n\n clearGraph() {\n if (this.graphGroup) {\n this.remove(this.graphGroup);\n // Helper to traverse and dispose\n this.graphGroup.traverse((child) => {\n if (child instanceof Mesh) {\n child.geometry.dispose();\n child.material.dispose();\n }\n });\n\n this.graphGroup = null;\n }\n }\n\n /**\n * Visualizes a path using TubeGeometry (CatmullRomCurve3).\n */\n renderPath(points: Vector3[], color: ColorRepresentation = this.parameters.pathColor) {\n if (points.length < 2) return;\n\n // Check if points are enough for curve\n const curve = new CatmullRomCurve3(points, false, 'catmullrom', 0);\n\n const mesh = new TubeMesh({\n geometryParameters: {\n path: curve,\n tubularSegments: points.length * 10,\n radius: this.parameters.pathRadius,\n closed: false,\n },\n materialParameters: {\n color,\n },\n });\n this.add(mesh);\n this.pathMeshes.push(mesh);\n return mesh;\n }\n\n clearPaths() {\n this.pathMeshes.forEach((m) => {\n this.remove(m);\n m.geometry.dispose();\n m.material.dispose();\n });\n this.pathMeshes = [];\n }\n\n /** Export nodes and edges as a JSON-serializable object. */\n exportData(): TopologyData {\n const nodes: TopologyData['nodes'] = {};\n this.nodes.forEach((pos, id) => {\n nodes[id] = { x: pos.x, y: pos.y, z: pos.z };\n });\n\n const edges: TopologyData['edges'] = [];\n const processed = new Set<string>();\n this.adjacencyMap.forEach((neighbors, from) => {\n neighbors.forEach((weight, to) => {\n const key = [from, to].sort().join('-');\n if (!processed.has(key)) {\n processed.add(key);\n edges.push({ from, to, weight });\n }\n });\n });\n\n return { nodes, edges };\n }\n\n /**\n * Load topology from a previously exported data object.\n * Replaces all current nodes, edges, and path meshes, then re-renders the graph.\n */\n importData(data: TopologyData) {\n this.clearGraph();\n this.clearPaths();\n this.nodes.clear();\n this.adjacencyMap.clear();\n\n Object.entries(data.nodes).forEach(([id, pos]) => {\n this.addNode(id, new Vector3(pos.x, pos.y, pos.z));\n });\n data.edges.forEach(({ from, to, weight }) => {\n this.addEdge(from, to, weight); // bidirectional by default, matching how edges are originally added\n });\n\n this.renderGraph();\n }\n\n dispose() {\n this.clearGraph();\n this.clearPaths();\n }\n\n getNeighbors(id: string) {\n return this.adjacencyMap.get(id);\n }\n}\n","import { SpriteNodeMaterial, CanvasTexture, SRGBColorSpace } from 'three/webgpu';\n\nimport type { InteractionEventMap } from '../interactions';\nimport { BaseSprite } from './BaseSprite';\n\nexport interface PoiParameters {\n /** Image URL or HTMLImageElement */\n img?: string | CanvasImageSource;\n /** Text content */\n text?: string;\n /** Font size in pixels */\n fontSize?: number;\n /** Font family */\n fontFamily?: string;\n /** Text color */\n color?: string;\n /** Icon size in pixels (applied to the image if present) */\n iconSize?: number;\n /** Padding between icon and text, and around the container */\n padding?: number;\n /** Background color of the POI (optional) */\n backgroundColor?: string;\n /** Border radius for the background (optional) */\n borderRadius?: number;\n /** Text position relative to the icon */\n textPosition?: 'top' | 'bottom' | 'left' | 'right';\n /** Scale factor for mapping canvas pixels to world units */\n scaleFactor?: number;\n}\n\nexport class Poi extends BaseSprite<InteractionEventMap> {\n readonly isPoi = true;\n type = 'Poi';\n\n parameters: Required<PoiParameters> = {\n img: '',\n text: '',\n fontSize: 32,\n fontFamily: 'Arial',\n color: '#ffffff',\n iconSize: 64,\n padding: 10,\n backgroundColor: 'rgba(0, 0, 0, 0)',\n borderRadius: 8,\n textPosition: 'right',\n scaleFactor: 0.01,\n };\n\n private _canvas: HTMLCanvasElement = document.createElement('canvas');\n private _lastParametersJSON = '';\n\n constructor(parameters: PoiParameters = {}) {\n super(new SpriteNodeMaterial());\n\n Object.assign(this.parameters, parameters);\n\n this.updateAsync();\n }\n\n /**\n * Update the POI with new parameters\n * @param parameters Partial POI parameters\n */\n async updateAsync(parameters: Partial<PoiParameters> = {}) {\n Object.assign(this.parameters, parameters);\n\n // Dirty check — skip if nothing changed\n const json = JSON.stringify(this.parameters);\n if (json === this._lastParametersJSON) return;\n this._lastParametersJSON = json;\n\n const canvas = this._canvas;\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n\n // Define font for measurement\n ctx.font = `${this.parameters.fontSize}px ${this.parameters.fontFamily}`;\n\n let image: CanvasImageSource | null = null;\n if (this.parameters.img) {\n image = await this._loadImage(this.parameters.img);\n }\n\n const { text, fontSize, color, iconSize, padding, backgroundColor, borderRadius, textPosition, scaleFactor } =\n this.parameters;\n\n // Measure text\n const textMetrics = ctx.measureText(text);\n const textWidth = text ? textMetrics.width : 0;\n const textHeight = text ? fontSize : 0;\n\n // Calculate canvas size and positions\n let contentWidth = 0;\n let contentHeight = 0;\n\n // Default positions (assuming single item centered)\n let iconX = 0,\n iconY = 0;\n let textX = 0,\n textY = 0;\n\n const hasImage = !!image;\n const hasText = !!text;\n\n if (hasImage && hasText) {\n switch (textPosition) {\n case 'top':\n contentWidth = Math.max(iconSize, textWidth);\n contentHeight = iconSize + padding + textHeight;\n\n textX = (contentWidth - textWidth) / 2;\n textY = textHeight / 2;\n iconX = (contentWidth - iconSize) / 2;\n iconY = textHeight + padding;\n break;\n case 'bottom':\n contentWidth = Math.max(iconSize, textWidth);\n contentHeight = iconSize + padding + textHeight;\n\n iconX = (contentWidth - iconSize) / 2;\n iconY = 0;\n textX = (contentWidth - textWidth) / 2;\n textY = iconSize + padding + textHeight / 2;\n break;\n case 'left':\n contentWidth = iconSize + padding + textWidth;\n contentHeight = Math.max(iconSize, textHeight);\n\n textX = 0;\n textY = contentHeight / 2;\n iconX = textWidth + padding;\n iconY = (contentHeight - iconSize) / 2;\n break;\n case 'right':\n default:\n contentWidth = iconSize + padding + textWidth;\n contentHeight = Math.max(iconSize, textHeight);\n\n iconX = 0;\n iconY = (contentHeight - iconSize) / 2;\n textX = iconSize + padding;\n textY = contentHeight / 2;\n break;\n }\n } else if (hasImage) {\n contentWidth = iconSize;\n contentHeight = iconSize;\n iconX = 0;\n iconY = 0;\n } else if (hasText) {\n contentWidth = textWidth;\n contentHeight = textHeight;\n textX = 0;\n textY = textHeight / 2;\n }\n\n const canvasWidth = contentWidth + padding * 2;\n const canvasHeight = contentHeight + padding * 2;\n\n canvas.width = canvasWidth;\n canvas.height = canvasHeight;\n\n // Redraw font after canvas resize (reset by resize)\n ctx.font = `${fontSize}px ${this.parameters.fontFamily}`;\n\n // Draw background\n if (backgroundColor) {\n ctx.fillStyle = backgroundColor;\n this._drawRoundedRect(ctx, 0, 0, canvasWidth, canvasHeight, borderRadius);\n ctx.fill();\n }\n\n // Offset positions by padding\n if (hasImage) {\n ctx.drawImage(image!, iconX + padding, iconY + padding, iconSize, iconSize);\n }\n\n if (hasText) {\n ctx.fillStyle = color;\n // Use actualBoundingBoxAscent/Descent for precise vertical centering\n const metrics = ctx.measureText(text);\n const actualTextHeight = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent;\n const baselineOffset = metrics.actualBoundingBoxAscent - actualTextHeight / 2;\n ctx.textBaseline = 'alphabetic';\n ctx.fillText(text, textX + padding, textY + padding + baselineOffset);\n }\n\n // Update texture — dispose old AFTER new one is set\n const oldTexture = this.material.map;\n\n const texture = new CanvasTexture(canvas);\n texture.colorSpace = SRGBColorSpace;\n this.material.map = texture;\n\n oldTexture?.dispose();\n\n // Adjust sprite scale based on aspect ratio to maintain proportions\n this.scale.set(canvasWidth * scaleFactor, canvasHeight * scaleFactor, 1);\n }\n\n private _loadImage(img: NonNullable<PoiParameters['img']>): Promise<CanvasImageSource> {\n return new Promise((resolve, reject) => {\n if (typeof img === 'string') {\n const _img = new Image();\n _img.crossOrigin = 'Anonymous';\n _img.onload = () => resolve(_img);\n _img.onerror = () => reject(new Error(`Failed to load image: ${img}`));\n _img.src = img;\n } else {\n resolve(img);\n }\n });\n }\n\n private _drawRoundedRect(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n width: number,\n height: number,\n radius: number,\n ) {\n ctx.beginPath();\n ctx.moveTo(x + radius, y);\n ctx.lineTo(x + width - radius, y);\n ctx.quadraticCurveTo(x + width, y, x + width, y + radius);\n ctx.lineTo(x + width, y + height - radius);\n ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);\n ctx.lineTo(x + radius, y + height);\n ctx.quadraticCurveTo(x, y + height, x, y + height - radius);\n ctx.lineTo(x, y + radius);\n ctx.quadraticCurveTo(x, y, x + radius, y);\n ctx.closePath();\n }\n\n dispose() {\n this.material.map?.dispose();\n this.material.dispose();\n }\n}\n","import {\n MeshStandardNodeMaterial,\n ShapeGeometry,\n Shape,\n Vector2,\n type MeshStandardNodeMaterialParameters,\n} from 'three/webgpu';\n\nimport type { InteractionEventMap } from '../interactions';\nimport type { IPlaneVector2 } from '../interfaces';\nimport { BaseMesh } from './BaseMesh';\n\nexport interface ShapeMeshParameters {\n geometryParameters?: {\n shape?: Shape | Shape[];\n curveSegments?: number;\n };\n materialParameters?: MeshStandardNodeMaterialParameters;\n}\n\nexport class ShapeMesh extends BaseMesh<ShapeGeometry, MeshStandardNodeMaterial, InteractionEventMap> {\n readonly isShapeMesh = true;\n type = 'ShapeMesh';\n\n constructor({ geometryParameters, materialParameters }: ShapeMeshParameters = {}) {\n super();\n\n this.geometry = new ShapeGeometry(geometryParameters?.shape, geometryParameters?.curveSegments);\n this.material = new MeshStandardNodeMaterial(materialParameters);\n\n this.geometry.rotateX(-Math.PI / 2);\n }\n\n static createFromPoints(points: IPlaneVector2[], parameters: ShapeMeshParameters = {}): ShapeMesh {\n return new ShapeMesh({\n ...parameters,\n geometryParameters: {\n ...parameters.geometryParameters,\n shape: new Shape(points.map((point) => new Vector2(point.x, -point.z))),\n },\n });\n }\n}\n","import {\n ExtrudeGeometry,\n MeshStandardNodeMaterial,\n Shape,\n Vector2,\n type ExtrudeGeometryOptions,\n type MeshStandardNodeMaterialParameters,\n} from 'three/webgpu';\n\nimport type { InteractionEventMap } from '../interactions';\nimport type { IPlaneVector2 } from '../interfaces';\nimport { BaseMesh } from './BaseMesh';\n\nexport interface ExtrudeMeshParameters {\n geometryParameters?: {\n shape?: Shape | Shape[];\n options?: ExtrudeGeometryOptions;\n };\n materialParameters?: MeshStandardNodeMaterialParameters;\n}\n\nexport class ExtrudeMesh extends BaseMesh<ExtrudeGeometry, MeshStandardNodeMaterial, InteractionEventMap> {\n readonly isExtrudeMesh = true;\n type = 'ExtrudeMesh';\n\n constructor({ geometryParameters, materialParameters }: ExtrudeMeshParameters = {}) {\n super();\n\n this.geometry = new ExtrudeGeometry(geometryParameters?.shape, geometryParameters?.options);\n this.material = new MeshStandardNodeMaterial(materialParameters);\n\n this.geometry.rotateX(-Math.PI / 2);\n }\n\n static createFromPoints(points: IPlaneVector2[], parameters: ExtrudeMeshParameters = {}): ExtrudeMesh {\n return new ExtrudeMesh({\n ...parameters,\n geometryParameters: {\n ...parameters.geometryParameters,\n shape: new Shape(points.map((point) => new Vector2(point.x, -point.z))),\n },\n });\n }\n}\n","import { MeshStandardNodeMaterial, PlaneGeometry, type MeshStandardNodeMaterialParameters } from 'three/webgpu';\n\nimport type { InteractionEventMap } from '../interactions';\nimport { BaseMesh } from './BaseMesh';\n\nexport interface PlaneMeshParameters {\n geometryParameters?: {\n width?: number;\n height?: number;\n widthSegments?: number;\n heightSegments?: number;\n };\n materialParameters?: MeshStandardNodeMaterialParameters;\n}\n\nexport class PlaneMesh extends BaseMesh<PlaneGeometry, MeshStandardNodeMaterial, InteractionEventMap> {\n readonly isPlaneMesh = true;\n type = 'PlaneMesh';\n\n constructor({ geometryParameters, materialParameters }: PlaneMeshParameters = {}) {\n super();\n\n this.geometry = new PlaneGeometry(\n geometryParameters?.width,\n geometryParameters?.height,\n geometryParameters?.widthSegments,\n geometryParameters?.heightSegments\n );\n this.material = new MeshStandardNodeMaterial(materialParameters);\n }\n}\n","import { CircleGeometry, MeshStandardNodeMaterial, type MeshStandardNodeMaterialParameters } from 'three/webgpu';\nimport type { InteractionEventMap } from '../interactions';\nimport { BaseMesh } from './BaseMesh';\n\nexport interface CircleMeshParameters {\n geometryParameters?: {\n radius?: number;\n segments?: number;\n thetaStart?: number;\n thetaLength?: number;\n };\n materialParameters?: MeshStandardNodeMaterialParameters;\n}\n\nexport class CircleMesh extends BaseMesh<CircleGeometry, MeshStandardNodeMaterial, InteractionEventMap> {\n readonly isCircleMesh = true;\n type = 'CircleMesh';\n\n constructor({ geometryParameters, materialParameters }: CircleMeshParameters = {}) {\n super(\n new CircleGeometry(\n geometryParameters?.radius,\n geometryParameters?.segments,\n geometryParameters?.thetaStart,\n geometryParameters?.thetaLength\n ),\n new MeshStandardNodeMaterial(materialParameters)\n );\n\n this.geometry.rotateX(-Math.PI / 2);\n }\n}\n","import { type Object3D, type Object3DEventMap, type Material, type BufferGeometry, Mesh } from 'three/webgpu';\n\nexport class ObjectUtils {\n static traverseMeshes<\n TGeometry extends BufferGeometry,\n TMaterial extends Material,\n TEventMap extends Object3DEventMap\n >(object: Object3D, callback: (object: Mesh<TGeometry, TMaterial, TEventMap>) => void) {\n object.traverse((child) => {\n if (child instanceof Mesh) {\n callback(child);\n }\n });\n }\n}\n","import { Color, type ColorRepresentation } from 'three';\nimport { color, mix, pow, sin, time, uv, mx_noise_float } from 'three/tsl';\n\nexport class TSLEffects {\n static flow(\n parameters: {\n baseColor?: ColorRepresentation;\n flowColor?: ColorRepresentation;\n speed?: number;\n scale?: number;\n intensity?: number;\n } = {},\n ) {\n const { baseColor = 0xffffff, flowColor = 0x00ff00, speed = 1.0, scale = 3.0, intensity = 4.0 } = parameters;\n\n const baseColorNode = color(new Color(baseColor));\n const flowColorNode = color(new Color(flowColor));\n\n // Assume the mesh is regular\n // uv().x runs along the length of the mesh\n const flow = uv().x.mul(scale).sub(time.mul(speed));\n\n // Create a smooth wave pattern: slightly sharper peaks\n // sin(x) -> [-1, 1]\n // (sin(x) + 1) / 2 -> [0, 1]\n // pow(..., intensity) -> narrow the highlight\n const pattern = pow(sin(flow).add(1).mul(0.5), intensity);\n\n return mix(baseColorNode, flowColorNode, pattern);\n }\n\n static breathe(\n parameters: {\n baseColor?: ColorRepresentation;\n breathColor?: ColorRepresentation;\n speed?: number;\n intensity?: number;\n } = {},\n ) {\n const { baseColor = 0xffffff, breathColor = 0x00ff00, speed = 1.0, intensity = 2.0 } = parameters;\n\n const baseColorNode = color(new Color(baseColor));\n const breathColorNode = color(new Color(breathColor));\n\n // sin(x) -> [-1, 1]\n // (sin(x) + 1) / 2 -> [0, 1]\n const osc = sin(time.mul(speed)).add(1).mul(0.5);\n\n // Apply intensity to make the \"breath\" more or less sharp\n const pattern = pow(osc, intensity);\n\n return mix(baseColorNode, breathColorNode, pattern);\n }\n\n static fluid(\n parameters: {\n baseColor?: ColorRepresentation;\n flowColor?: ColorRepresentation;\n speed?: number;\n scale?: number;\n intensity?: number;\n distortion?: number;\n } = {},\n ) {\n const {\n baseColor = 0xffffff,\n flowColor = 0x0000ff,\n speed = 1.0,\n scale = 1.0,\n intensity = 1.0,\n distortion = 0.5,\n } = parameters;\n\n const baseColorNode = color(new Color(baseColor));\n const flowColorNode = color(new Color(flowColor));\n\n // UV coordinates scaled\n const uvNode = uv().mul(scale);\n\n // Animate the noise with time\n const timeNode = time.mul(speed);\n\n // Distort UVs using noise\n const noiseNode = mx_noise_float(uvNode.add(timeNode), 1.0, 0.0);\n const distortedUV = uvNode.add(noiseNode.mul(distortion));\n\n // Create a pattern based on the distorted UVs\n const pattern = mx_noise_float(distortedUV, 1.0, 0.0).add(1.0).mul(0.5); // 0..1\n\n // Sharpen the pattern\n const fluidPattern = pow(pattern, intensity);\n\n return mix(baseColorNode, flowColorNode, fluidPattern);\n }\n}\n","export function reinterpretType<T>(_value: unknown): asserts _value is T {}\n","import { type NodeMaterial, type Object3D, type ColorRepresentation, Color, type Node } from 'three/webgpu';\nimport { userData, select, materialColor, vec3, Fn, materialOpacity } from 'three/tsl';\nimport { ObjectUtils } from '../objects';\nimport { reinterpretType } from '../types';\n\nexport interface HighlightOptions {\n enabled?: boolean;\n opacity?: number;\n color?: ColorRepresentation;\n overwrite?: boolean;\n}\n\nconst _highlightKey = 'uSpaceHighlight';\nconst _highlightEnabledKey = `${_highlightKey}/enabled`;\nconst _highlightOpacityKey = `${_highlightKey}/opacity`;\nconst _highlightColorKey = `${_highlightKey}/color`;\nconst _highlightOverwriteKey = `${_highlightKey}/overwrite`;\nconst _highlightColorNode = Fn<Node<'vec3'>>(() => {\n // Build TSL node graph with fallback support\n const enabled = userData(_highlightEnabledKey, 'uint');\n const colorUint = userData(_highlightColorKey, 'uint');\n const overwrite = userData(_highlightOverwriteKey, 'uint');\n reinterpretType<Node<'uint'>>(enabled);\n reinterpretType<Node<'uint'>>(colorUint);\n reinterpretType<Node<'uint'>>(overwrite);\n reinterpretType<Node<'vec3'>>(materialColor);\n // Convert uint to vec3 color\n const hlColorRaw = uintToColor(colorUint);\n // overwrite: 直接替换颜色\n // !overwrite: 与原色相乘(着色/染色效果)\n const tintedColor = materialColor.mul(hlColorRaw);\n const finalHlColor = select(overwrite.greaterThan(0), hlColorRaw, tintedColor);\n\n // Apply highlight or fallback to original\n const hlColor = select(enabled.greaterThan(0), finalHlColor, materialColor);\n return hlColor;\n})();\nconst _highlightOpacityNode = Fn<Node<'float'>>(() => {\n const enabled = userData(_highlightEnabledKey, 'uint');\n const opacity = userData(_highlightOpacityKey, 'float');\n reinterpretType<Node<'uint'>>(enabled);\n reinterpretType<Node<'float'>>(opacity);\n reinterpretType<Node<'float'>>(materialOpacity);\n const hlOpacity = select(enabled.greaterThan(0), opacity, materialOpacity);\n return hlOpacity;\n})();\n\nexport class MaterialEffects {\n static highlight(object: Object3D, options: HighlightOptions = {}) {\n const highlightOptions: Required<HighlightOptions> = Object.assign(\n {\n enabled: true,\n opacity: 0.5,\n color: 0xff0000,\n overwrite: false,\n },\n options,\n );\n\n // Ensure color is a hex number for TSL uint compatibility\n highlightOptions.color = new Color(highlightOptions.color).getHex();\n\n ObjectUtils.traverseMeshes(object, (mesh) => {\n // 1. Set userData on THIS specific object\n mesh.userData[_highlightEnabledKey] = highlightOptions.enabled ? 1 : 0; // Enable flag\n mesh.userData[_highlightOpacityKey] = highlightOptions.opacity;\n mesh.userData[_highlightColorKey] = highlightOptions.color;\n mesh.userData[_highlightOverwriteKey] = highlightOptions.overwrite ? 1 : 0;\n\n const material = mesh.material;\n // Currently only support single material\n if (material && !Array.isArray(material)) {\n reinterpretType<NodeMaterial>(material);\n // TODO: Revert material transparent\n material.transparent = true;\n material.colorNode = _highlightColorNode;\n material.opacityNode = _highlightOpacityNode;\n material.needsUpdate = true;\n }\n });\n }\n}\n\n/**\n * Convert a uint hex color node (e.g., 0xff0000) to a vec3 RGB node (0-1 range)\n */\nconst uintToColor = (colorUint: Node<'uint'>) => {\n const r = colorUint.shiftRight(16).bitAnd(0xff).toFloat().div(255);\n const g = colorUint.shiftRight(8).bitAnd(0xff).toFloat().div(255);\n const b = colorUint.bitAnd(0xff).toFloat().div(255);\n return vec3(r, g, b);\n};\n","import { Tween as TweenBase, Easing } from 'three/addons/libs/tween.module.js';\nimport type { Viewer, ViewerEventMap } from '../viewers';\n\nclass Tween<PropType extends Record<string, any>> extends TweenBase<PropType> {\n viewer: Viewer;\n\n constructor(viewer: Viewer, source: PropType) {\n super(source);\n\n this.viewer = viewer;\n }\n\n _update = ({ time }: ViewerEventMap['afterControlsUpdate']) => {\n const needsRender = this.update(time);\n\n if (needsRender) {\n this.viewer.render();\n }\n };\n\n easingByMode(mode: AnimationModeType): this {\n const tweenModeFunc = animationModeEnum[mode];\n return super.easing(tweenModeFunc);\n }\n\n start(time?: number, overrideStartingValues?: boolean): this {\n this.viewer.addEventListener('afterControlsUpdate', this._update);\n return super.start(time, overrideStartingValues);\n }\n\n stop(): this {\n this.viewer.removeEventListener('afterControlsUpdate', this._update);\n return super.stop();\n }\n}\n\nfunction tweenAnimation<PropType extends Record<string, any>>(\n viewer: Viewer,\n source: PropType,\n target: PropType,\n options: AnimationOptions = {},\n onUpdate?: (source: PropType, tween: Tween<PropType>) => void,\n onStart?: (tween: Tween<PropType>) => void,\n) {\n return new Promise<void>((resolve, reject) => {\n const { duration = 1000, delay = 0, repeat = false, mode = 'Linear.None', yoyo = false } = options;\n\n const tween: Tween<PropType> = new Tween<PropType>(viewer, source)\n .to(target, duration)\n .easingByMode(mode)\n .delay(delay)\n .onUpdate((e: PropType) => {\n // Euler\n onUpdate?.(e, tween);\n })\n .onComplete(() => {\n resolve();\n })\n .onStop(() => {\n reject('animation stop');\n })\n .onStart(() => {\n onStart?.(tween);\n });\n\n if (typeof repeat === 'number') tween.repeat(repeat);\n else if (typeof repeat === 'boolean' && repeat) tween.repeat(Infinity);\n\n // fix: https://github.com/tweenjs/tween.js/issues/677\n if (yoyo) tween.repeatDelay(20);\n tween.yoyo(yoyo);\n tween.start();\n });\n}\n\nexport { Tween, tweenAnimation };\n\nconst animationModeEnum: Record<AnimationModeType, (amount: number) => number> = {\n 'Linear.None': Easing.Linear.None,\n 'Quadratic.In': Easing.Quadratic.In,\n 'Quadratic.Out': Easing.Quadratic.Out,\n 'Quadratic.InOut': Easing.Quadratic.InOut,\n 'Cubic.In': Easing.Cubic.In,\n 'Cubic.Out': Easing.Cubic.Out,\n 'Cubic.InOut': Easing.Cubic.InOut,\n 'Quartic.In': Easing.Quartic.In,\n 'Quartic.Out': Easing.Quartic.Out,\n 'Quartic.InOut': Easing.Quartic.InOut,\n 'Quintic.In': Easing.Quintic.In,\n 'Quintic.Out': Easing.Quintic.Out,\n 'Quintic.InOut': Easing.Quintic.InOut,\n 'Sinusoidal.In': Easing.Sinusoidal.In,\n 'Sinusoidal.Out': Easing.Sinusoidal.Out,\n 'Sinusoidal.InOut': Easing.Sinusoidal.InOut,\n 'Exponential.In': Easing.Exponential.In,\n 'Exponential.Out': Easing.Exponential.Out,\n 'Exponential.InOut': Easing.Exponential.InOut,\n 'Circular.In': Easing.Circular.In,\n 'Circular.Out': Easing.Circular.Out,\n 'Circular.InOut': Easing.Circular.InOut,\n 'Elastic.In': Easing.Elastic.In,\n 'Elastic.Out': Easing.Elastic.Out,\n 'Elastic.InOut': Easing.Elastic.InOut,\n 'Back.In': Easing.Back.In,\n 'Back.Out': Easing.Back.Out,\n 'Back.InOut': Easing.Back.InOut,\n 'Bounce.In': Easing.Bounce.In,\n 'Bounce.Out': Easing.Bounce.Out,\n 'Bounce.InOut': Easing.Bounce.InOut,\n};\n\nexport type AnimationModeType =\n | 'Linear.None'\n | 'Quadratic.In'\n | 'Quadratic.Out'\n | 'Quadratic.InOut'\n | 'Cubic.In'\n | 'Cubic.Out'\n | 'Cubic.InOut'\n | 'Quartic.In'\n | 'Quartic.Out'\n | 'Quartic.InOut'\n | 'Quintic.In'\n | 'Quintic.Out'\n | 'Quintic.InOut'\n | 'Sinusoidal.In'\n | 'Sinusoidal.Out'\n | 'Sinusoidal.InOut'\n | 'Exponential.In'\n | 'Exponential.Out'\n | 'Exponential.InOut'\n | 'Circular.In'\n | 'Circular.Out'\n | 'Circular.InOut'\n | 'Elastic.In'\n | 'Elastic.Out'\n | 'Elastic.InOut'\n | 'Back.In'\n | 'Back.Out'\n | 'Back.InOut'\n | 'Bounce.In'\n | 'Bounce.Out'\n | 'Bounce.InOut';\n\nexport interface AnimationOptions {\n duration?: number;\n delay?: number;\n repeat?: number | boolean;\n mode?: AnimationModeType;\n yoyo?: boolean;\n}\n"],"names":["RenderPipelineBase","pass","RoomEnvironmentClass","ViewHelperBase","el","time","i","uv","uv2","color","Color","TweenBase"],"mappings":"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"}
@@ -186,7 +186,9 @@ const poi = new Poi({
186
186
  backgroundColor: 'rgba(0,0,0,0.6)',
187
187
  textPosition: 'right',
188
188
  });
189
- await poi.updateAsync(); // 渲染 canvas 纹理
189
+ // 构造时会自动调用 updateAsync(),无需手动调用
190
+ // 如需更新参数,可再次调用:
191
+ // await poi.updateAsync({ text: '新文字' });
190
192
 
191
193
  poi.position.set(10, 5, 10);
192
194
  viewer.scene.add(poi);
@@ -203,15 +205,16 @@ viewer.scene.add(poi);
203
205
  | `color` | `string` | `'#ffffff'` | 文字颜色。 |
204
206
  | `iconSize` | `number` | `64` | 图标大小(像素)。 |
205
207
  | `padding` | `number` | `10` | 内容四周的内边距。 |
206
- | `backgroundColor` | `string` | `'rgba(0, 0, 0, 0.5)'` | 背景填充颜色。 |
208
+ | `backgroundColor` | `string` | `'rgba(0, 0, 0, 0)'` | 背景填充颜色。 |
207
209
  | `borderRadius` | `number` | `8` | 背景圆角半径。 |
208
210
  | `textPosition` | `'top' \| 'bottom' \| 'left' \| 'right'` | `'right'` | 文字相对图标的位置。 |
211
+ | `scaleFactor` | `number` | `0.01` | canvas 像素到世界单位的缩放系数。 |
209
212
 
210
213
  ### 方法
211
214
 
212
215
  #### `updateAsync(parameters?)`
213
216
 
214
- 使用可选的参数覆盖重新渲染 canvas 纹理。
217
+ 使用可选的参数覆盖重新渲染 canvas 纹理。构造时会自动调用一次,后续参数未变化时会跳过重绘。
215
218
 
216
219
  ```typescript
217
220
  await poi.updateAsync({ text: '更新后的标签', color: '#ffff00' });
@@ -306,6 +309,25 @@ viewer.render();
306
309
 
307
310
  返回节点的邻接表(邻居 ID → 边权重)。
308
311
 
312
+ #### `exportData(): TopologyData`
313
+
314
+ 将当前拓扑图(节点和边)导出为 JSON 可序列化对象。
315
+
316
+ ```typescript
317
+ const data = topo.exportData();
318
+ // { nodes: Record<string, {x,y,z}>, edges: Array<{from,to,weight}> }
319
+ ```
320
+
321
+ 双向边在导出时会去重,只保留一条记录。
322
+
323
+ #### `importData(data: TopologyData)`
324
+
325
+ 从 `exportData()` 返回的数据中还原拓扑图,替换当前所有节点、边和路径网格,并重新渲染。
326
+
327
+ ```typescript
328
+ topo.importData(data);
329
+ ```
330
+
309
331
  #### `dispose()`
310
332
 
311
333
  清除图和路径网格。
@@ -2,9 +2,7 @@
2
2
 
3
3
  `u-space` 架构包含一套丰富的插件,提供从 GIS 瓦片加载到键盘控制和场景管理等高级功能。所有插件从 `u-space/plugins/*` 命名空间导入。
4
4
 
5
- ## 可用插件
6
-
7
- ### `keyboard-controls`
5
+ ## `keyboard-controls`
8
6
 
9
7
  为激活相机提供 WASD 或方向键的平移和旋转控制。
10
8
 
@@ -45,7 +43,7 @@ import { ACTION } from 'u-space/plugins/keyboard-controls';
45
43
  keyboardControls.keys['Space'] = ACTION.MOVE_UP;
46
44
  ```
47
45
 
48
- ### `minimap`
46
+ ## `minimap`
49
47
 
50
48
  生成一个 2D 小地图叠加层,在 3D 场景中跟踪目标对象。渲染到注入 `viewer.el` 的 `<canvas>` 元素中。
51
49
 
@@ -82,7 +80,7 @@ minimap.dispose();
82
80
  - `disable()` — 移除画布并停止渲染。
83
81
  - `dispose()` — 禁用并清理所有资源。
84
82
 
85
- ### `tiles`
83
+ ## `tiles`
86
84
 
87
85
  提供与 `3d-tiles-renderer` 和地理空间数据的集成。主要导出 `ArcgisTilesRenderer`,可流式加载 ArcGIS Online 3D 瓦片并将地球重新定向到指定地理位置。
88
86
 
@@ -109,7 +107,7 @@ arcgisTilesRenderer.enable();
109
107
  | `disable()` | 从场景中移除瓦片并暂停更新循环。 |
110
108
  | `dispose()` | 禁用并完全释放瓦片渲染器。 |
111
109
 
112
- ### `u-manager`
110
+ ## `u-manager`
113
111
 
114
112
  `u-manager` 是一套全面的加载器和解析器,用于从服务器路径流式传输、解密并显示结构化场景数据。支持场景、拓扑、动画、属性和相机视点。
115
113
 
@@ -233,7 +231,7 @@ const modelProps = properties.filter(p => p.modelId === myModel.userData.id);
233
231
  | `value` | `string \| null` | 属性值。 |
234
232
  | `label` | `string \| null` | 属性的显示标签。 |
235
233
 
236
- ### `curve-movement`
234
+ ## `curve-movement`
237
235
 
238
236
  沿样条路径对相机或对象进行动画。提供两个具体子类:`CurveMovementCamera` 和 `CurveMovementObject`。
239
237
 
@@ -272,7 +270,7 @@ movement.addEventListener('complete', () => console.log('完成'));
272
270
  | `positionOffset`| `Vector3` | `(0,0,0)` | 叠加到每个位置上的世界坐标偏移量。 |
273
271
  | `direction` | `1 \| -1` | `1` | 当前行进方向。 |
274
272
 
275
- ### `tracking-controls`
273
+ ## `tracking-controls`
276
274
 
277
275
  使相机平滑跟随移动的 `Object3D` 目标。
278
276
 
@@ -296,7 +294,7 @@ tracking.enable();
296
294
  | `type` | `'position' \| 'box3'` | `'position'` | 跟踪世界位置还是包围盒中心。 |
297
295
  | `offset` | `Vector3` | `(0,0,0)` | 在移动相机前叠加到跟踪位置上的偏移量。 |
298
296
 
299
- ### `atmosphere`
297
+ ## `atmosphere`
300
298
 
301
299
  天空和大气渲染插件。目前为占位实现,`enable()` / `disable()` / `dispose()` 方法可用,但尚未实现具体功能。
302
300
 
@@ -307,7 +305,7 @@ const atmosphere = new Atmosphere(viewer);
307
305
  atmosphere.enable();
308
306
  ```
309
307
 
310
- ### `object-controls`
308
+ ## `object-controls`
311
309
 
312
310
  对场景中的 3D 对象进行交互式移动、旋转、缩放操作。继承自 Three.js `TransformControls`,集成了 u-space `Viewer` 生命周期管理。
313
311
 
@@ -375,7 +373,7 @@ controls.addEventListener('dragging-changed', ({ value }) => {
375
373
 
376
374
  > 由于 `ObjectControls` 直接继承 `TransformControls`,所有原生属性(`translationSnap`、`rotationSnap`、`scaleSnap`、`showX/Y/Z` 等)和事件均可直接使用,参考 [Three.js TransformControls 文档](https://threejs.org/docs/#examples/en/controls/TransformControls)。
377
375
 
378
- ### `topology-drawer`
376
+ ## `topology-drawer`
379
377
 
380
378
  在 3D 场景中交互式绘制拓扑路径图。点击场景中的任意对象表面放置节点,自动连接成路径;点击空白处则落回不可见的地面平面。事件检测通过 `viewer.interactionManager` 实现(`scene.addEventListener` 冒泡)。
381
379
 
@@ -100,6 +100,52 @@ const camera = viewer.createOrthographicCamera();
100
100
  viewer.setCamera(camera);
101
101
  ```
102
102
 
103
+ ## 调试工具
104
+
105
+ ### Info
106
+
107
+ `viewer.info` 是一个轻量的渲染统计叠加层,显示当前帧的 GPU 诊断数据,适合开发调试阶段使用。
108
+
109
+ ```typescript
110
+ viewer.info.enable(); // 在画面左下角显示统计信息
111
+ viewer.info.disable(); // 隐藏统计信息
112
+ ```
113
+
114
+ 启用后将在 `viewer.el` 左下角叠加以下数据:
115
+
116
+ | 指标 | 说明 |
117
+ | :------------- | :---------------------------- |
118
+ | `draw calls` | 当前帧的绘制调用次数 |
119
+ | `frame calls` | 当前帧的帧调用次数 |
120
+ | `triangles` | 当前帧渲染的三角面数量 |
121
+ | `points` | 当前帧渲染的点数量 |
122
+ | `lines` | 当前帧渲染的线段数量 |
123
+ | `timestamp` | GPU 渲染耗时(ms,WebGPU 专属)|
124
+
125
+ > `timestamp` 指标仅在 WebGPU 后端可用,WebGL 回退模式下显示 `0`。
126
+
127
+ ### ViewerHelper
128
+
129
+ `viewer.viewerHelper` 是一个方向指示器 gizmo(基于 Three.js `ViewHelper`),显示当前相机朝向的 XYZ 轴,渲染为画面角落的叠加层。
130
+
131
+ ```typescript
132
+ viewer.viewerHelper.enable(); // 显示方向 gizmo
133
+ viewer.viewerHelper.disable(); // 隐藏方向 gizmo
134
+ ```
135
+
136
+ **属性:**
137
+
138
+ | 属性 | 类型 | 说明 |
139
+ | :------------- | :---------- | :---------------------------------------- |
140
+ | `location` | `object` | gizmo 在画面中的位置,支持 `top`、`bottom`、`left`、`right` 偏移(像素)。默认右下角。 |
141
+
142
+ ```typescript
143
+ // 调整位置到左下角
144
+ viewer.viewerHelper.location.left = 12;
145
+ viewer.viewerHelper.location.bottom = 12;
146
+ viewer.viewerHelper.location.right = null;
147
+ ```
148
+
103
149
  ### `dispose()`
104
150
 
105
151
  清理查看器,从 DOM 中移除 canvas,移除事件监听,并释放渲染器和环境贴图,以防止内存泄漏。
@@ -93,8 +93,7 @@ pnpm install three camera-controls
93
93
  `u-space` 内置了 `InteractionManager`,可以轻松为 3D 对象添加事件监听。
94
94
 
95
95
  ```javascript
96
- // 启用指针移动事件
97
- viewer.interactionManager.targetObjects = [];
96
+ // 启用指针移动事件(pointerenter / pointerleave 需要此开关)
98
97
  viewer.interactionManager.pointerMoveEventsEnabled = true;
99
98
 
100
99
  // 添加点击事件
package/docs/index.md CHANGED
@@ -48,3 +48,5 @@ features:
48
48
  | [curve-movement](./api-plugins#curve-movement) | 沿样条曲线移动相机或对象 |
49
49
  | [tracking-controls](./api-plugins#tracking-controls) | 相机跟随移动目标 |
50
50
  | [atmosphere](./api-plugins#atmosphere) | 天空/大气渲染(开发中) |
51
+ | [object-controls](./api-plugins#object-controls) | 交互式移动、旋转、缩放 3D 对象 |
52
+ | [topology-drawer](./api-plugins#topology-drawer) | 在场景任意表面交互式绘制拓扑路径图 |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "u-space",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "type": "module",
5
5
  "types": "dist/src/index.d.ts",
6
6
  "module": "dist/index.js",
@@ -29,7 +29,7 @@
29
29
  "docs:build": "vitepress build docs",
30
30
  "docs:preview": "vitepress preview docs",
31
31
  "docs:deploy": "pnpm docs:build && vercel --prod",
32
- "release": "npm publish --access=public"
32
+ "release": "npm version patch && npm publish --access=public"
33
33
  },
34
34
  "files": [
35
35
  "dist",