string-tune-3d 0.0.5 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +243 -132
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +369 -29
- package/dist/index.d.ts +369 -29
- package/dist/index.js +243 -132
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +243 -132
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -2
- package/readme.md +191 -107
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/modules/String3D.ts","../src/core/String3DCamera.ts","../src/core/String3DRenderer.ts","../src/core/String3DObject.ts","../src/core/String3DScene.ts","../src/core/synchronizer/GroupSynchronizer.ts","../src/core/synchronizer/LightSynchronizer.ts","../src/core/synchronizer/MeshSynchronizer.ts","../src/core/synchronizer/String3DSynchronizer.ts","../src/core/transform/TransformWorkerClient.ts","../src/adapters/ThreeJSProvider.ts"],"sourcesContent":["export { String3D } from \"./modules/String3D\";\r\nexport type { String3DOptions } from \"./modules/String3D\";\r\n\r\nexport type {\r\n I3DEngine,\r\n I3DVector3,\r\n I3DVector2,\r\n I3DQuaternion,\r\n I3DEuler,\r\n I3DMatrix4,\r\n I3DBox3,\r\n I3DObject,\r\n I3DMesh,\r\n I3DGeometry,\r\n I3DMaterial,\r\n I3DLight,\r\n I3DCamera,\r\n I3DPerspectiveCamera,\r\n I3DOrthographicCamera,\r\n I3DScene,\r\n I3DRenderer,\r\n I3DTextureLoader,\r\n I3DModelLoader,\r\n} from \"./core/abstractions/I3DEngine\";\r\n\r\nexport type { CameraMode } from \"./core/String3DCamera\";\r\nexport type { I3DEngineProvider } from \"./core/abstractions/I3DEngineProvider\";\r\n\r\nexport { String3DCamera } from \"./core/String3DCamera\";\r\nexport { String3DRenderer } from \"./core/String3DRenderer\";\r\nexport { String3DScene } from \"./core/String3DScene\";\r\nexport { String3DObject } from \"./core/String3DObject\";\r\nexport { String3DSynchronizer } from \"./core/synchronizer/String3DSynchronizer\";\r\n\r\nexport { ThreeJSProvider, ThreeJSEngine } from \"./adapters/ThreeJSProvider\";\r\n","import { StringModule } from \"@fiddle-digital/string-tune\";\nimport { StringObject } from \"@fiddle-digital/string-tune\";\nimport { StringData } from \"@fiddle-digital/string-tune\";\nimport { StringContext } from \"@fiddle-digital/string-tune\";\nimport { String3DCamera } from \"../core/String3DCamera\";\nimport { String3DRenderer } from \"../core/String3DRenderer\";\nimport { String3DScene } from \"../core/String3DScene\";\nimport { String3DSynchronizer } from \"../core/synchronizer/String3DSynchronizer\";\nimport { I3DEngineProvider } from \"../core/abstractions/I3DEngineProvider\";\nimport { I3DEngine, I3DModelLoader } from \"../core/abstractions/I3DEngine\";\nimport { frameDOM } from \"@fiddle-digital/string-tune\";\nimport { MeshSynchronizer } from \"../core/synchronizer/MeshSynchronizer\";\nimport { String3DObject } from \"../core/String3DObject\";\nimport {\n TransformWorkerClient,\n TransformWorkerInput,\n TransformWorkerCamera,\n TransformWorkerResult,\n} from \"../core/transform/TransformWorkerClient\";\n\nexport interface String3DOptions {\n hideHTML?: boolean;\n container?: string | HTMLElement;\n zIndex?: number;\n modelLoaderType?: string;\n modelLoader?: I3DModelLoader;\n modelLoaderFactory?: (engine: I3DEngine, type?: string) => I3DModelLoader;\n useDirtySync?: boolean;\n useTransformWorker?: boolean;\n transformWorkerWasmUrl?: string;\n}\n\nexport class String3D extends StringModule {\n private static provider: I3DEngineProvider | null = null;\n\n private renderer: String3DRenderer | null = null;\n private camera: String3DCamera | null = null;\n private scene: String3DScene | null = null;\n private synchronizer: String3DSynchronizer | null = null;\n private engine: I3DEngine | null = null;\n private canvasContainer: HTMLElement | null = null;\n private isLoading: Map<string, boolean> = new Map();\n private options: String3DOptions;\n private useDirtySync = false;\n private dirtyElements: Set<HTMLElement> = new Set();\n private observedElements: Set<HTMLElement> = new Set();\n private resizeObserver: ResizeObserver | null = null;\n private mutationObserver: MutationObserver | null = null;\n private lastSyncData: WeakMap<String3DObject, { scale: number }> = new WeakMap();\n private transformWorker: TransformWorkerClient | null = null;\n private workerHasResult = false;\n private workerObjectMap: Map<string, { object: String3DObject; el: HTMLElement }> = new Map();\n private domVersion = 0;\n private lastSubmittedVersion = 0;\n private scrollTicking = false;\n private onScrollBound = () => this.handleScroll();\n\n public static setProvider(provider: I3DEngineProvider): void {\n String3D.provider = provider;\n }\n\n constructor(context: StringContext) {\n super(context);\n this.htmlKey = \"3d\";\n this.options = this.buildOptionsFromSettings();\n\n this.attributesToMap = [\n ...this.attributesToMap,\n { key: \"3d\", type: \"string\", fallback: \"box\" },\n { key: \"3d-material\", type: \"string\", fallback: \"basic[#ffffff]\" },\n { key: \"3d-color\", type: \"string\", fallback: \"#ffffff\" },\n { key: \"3d-opacity\", type: \"number\", fallback: 1 },\n { key: \"3d-intensity\", type: \"number\", fallback: 1 },\n { key: \"3d-distance\", type: \"number\", fallback: 1000 },\n { key: \"3d-decay\", type: \"number\", fallback: 0 },\n { key: \"3d-model\", type: \"string\", fallback: \"\" },\n { key: \"3d-segments\", type: \"number\", fallback: 32 },\n { key: \"3d-segments-width\", type: \"number\", fallback: 32 },\n { key: \"3d-segments-height\", type: \"number\", fallback: 32 },\n { key: \"3d-model-loader\", type: \"string\", fallback: \"\" },\n { key: \"3d-model-scale\", type: \"number\", fallback: 1 },\n { key: \"3d-model-center\", type: \"boolean\", fallback: false },\n { key: \"3d-model-fit\", type: \"string\", fallback: \"contain\" },\n { key: \"3d-metalness\", type: \"number\", fallback: 0 },\n { key: \"3d-roughness\", type: \"number\", fallback: 1 },\n { key: \"3d-texture-flipY\", type: \"boolean\", fallback: true },\n { key: \"3d-colorSpace\", type: \"string\", fallback: \"\" },\n { key: \"3d-cast-shadow\", type: \"boolean\", fallback: false },\n { key: \"3d-receive-shadow\", type: \"boolean\", fallback: false },\n { key: \"3d-shadow-bias\", type: \"number\", fallback: 0 },\n { key: \"3d-shadow-map-size\", type: \"number\", fallback: 512 },\n { key: \"3d-angle\", type: \"number\", fallback: Math.PI / 3 },\n { key: \"3d-penumbra\", type: \"number\", fallback: 0 },\n { key: \"3d-ground-color\", type: \"string\", fallback: \"#ffffff\" },\n { key: \"3d-target\", type: \"string\", fallback: \"\" },\n ];\n }\n\n override canConnect(object: StringObject): boolean {\n const result = super.canConnect(object);\n console.log(\n \"[String3D] canConnect:\",\n object.id,\n \"keys:\",\n object.keys,\n \"htmlKey:\",\n this.htmlKey,\n \"result:\",\n result\n );\n return result;\n }\n\n override initializeObject(\n globalId: number,\n object: StringObject,\n element: HTMLElement,\n attributes: Record<string, any>\n ): void {\n super.initializeObject(globalId, object, element, attributes);\n\n object.setProperty(\"parentId\", null);\n const parentElement = element.parentElement?.closest(\n '[string-3d=\"group\"]'\n ) as HTMLElement | null;\n if (parentElement) {\n const parentId = parentElement.getAttribute(\"string-id\");\n if (parentId) {\n object.setProperty(\"parentId\", parentId);\n object.setProperty(\"parent\", parentElement);\n }\n }\n }\n\n override onResize(): void {\n if (this.renderer && this.camera && this.synchronizer) {\n this.renderer.resize(this.camera);\n this.synchronizer.updateViewportSize(this.renderer.width, this.renderer.height);\n this.camera.clearScaleCache();\n if (this.useDirtySync) {\n this.markAllDirty();\n }\n }\n }\n\n override onInit(): void {\n this.options = this.buildOptionsFromSettings();\n if (!String3D.provider) {\n console.error(\"[String3D] No provider set. Call String3D.setProvider() before use.\");\n return;\n }\n\n this.engine = String3D.provider.getEngine();\n this.canvasContainer = this.createOrGetContainer();\n this.registerTypedProperties();\n this.injectCSS();\n this.useDirtySync = !!this.options.useDirtySync;\n if (this.useDirtySync) {\n this.setupObservers();\n this.setupScrollListeners();\n }\n\n this.renderer = new String3DRenderer(this.canvasContainer, this.engine);\n this.renderer.attach();\n\n this.camera = new String3DCamera(this.engine, \"orthographic\");\n this.camera.setPosition(0, 0, 1000);\n this.camera.resize(this.renderer.width, this.renderer.height);\n\n const modelLoader = this.resolveModelLoader();\n const modelLoaderFactory = this.resolveModelLoaderFactory();\n this.scene = new String3DScene(this.engine, {\n modelLoader,\n modelLoaderFactory,\n });\n this.scene.getScene().add(this.camera.camera);\n\n this.synchronizer = new String3DSynchronizer(\n this.camera,\n this.renderer.width,\n this.renderer.height,\n this.engine\n );\n\n if (this.options.useTransformWorker) {\n this.transformWorker = new TransformWorkerClient({\n wasmUrl: this.options.transformWorkerWasmUrl,\n });\n }\n\n console.info(`[String3D] Initialized with: ${String3D.provider.getName()}`);\n }\n\n override onSettingsChange(): void {\n this.options = this.buildOptionsFromSettings();\n const shouldUseDirtySync = !!this.options.useDirtySync;\n if (shouldUseDirtySync && !this.useDirtySync) {\n this.useDirtySync = true;\n this.setupObservers();\n this.setupScrollListeners();\n this.observeSceneElements();\n this.markAllDirty();\n } else if (!shouldUseDirtySync && this.useDirtySync) {\n this.useDirtySync = false;\n this.removeScrollListeners();\n this.resizeObserver?.disconnect();\n this.mutationObserver?.disconnect();\n this.dirtyElements.clear();\n }\n\n const shouldUseWorker = !!this.options.useTransformWorker;\n if (shouldUseWorker && !this.transformWorker) {\n this.transformWorker = new TransformWorkerClient({\n wasmUrl: this.options.transformWorkerWasmUrl,\n });\n this.workerHasResult = false;\n } else if (!shouldUseWorker && this.transformWorker) {\n this.transformWorker.destroy();\n this.transformWorker = null;\n this.workerHasResult = false;\n }\n }\n\n private buildOptionsFromSettings(): String3DOptions {\n return {\n hideHTML: this.getSettingValue(\"hideHTML\", false),\n container: this.getSettingValue(\"container\", undefined),\n zIndex: this.getSettingValue(\"zIndex\", 1),\n modelLoaderType: this.getSettingValue(\"modelLoaderType\", undefined),\n modelLoader: this.getSettingValue(\"modelLoader\", undefined),\n modelLoaderFactory: this.getSettingValue(\"modelLoaderFactory\", undefined),\n useDirtySync: this.getSettingValue(\"useDirtySync\", false),\n useTransformWorker: this.getSettingValue(\"useTransformWorker\", false),\n transformWorkerWasmUrl: this.getSettingValue(\"transformWorkerWasmUrl\", undefined),\n };\n }\n\n private getSettingValue<T>(key: string, fallback: T): T {\n if (!this.settings || !(key in this.settings)) return fallback;\n return this.settings[key] as T;\n }\n\n private resolveModelLoader(): I3DModelLoader | undefined {\n if (!this.engine) return undefined;\n if (this.options.modelLoader) return this.options.modelLoader;\n if (this.options.modelLoaderFactory) return undefined;\n if (this.options.modelLoaderType) {\n try {\n return this.engine.createModelLoader(this.options.modelLoaderType);\n } catch (error) {\n console.warn(\"[String3D] Failed to create model loader:\", error);\n }\n }\n return undefined;\n }\n\n private resolveModelLoaderFactory():\n | ((engine: I3DEngine, type?: string) => I3DModelLoader)\n | undefined {\n if (!this.engine) return undefined;\n if (this.options.modelLoaderFactory) return this.options.modelLoaderFactory;\n if (this.options.modelLoaderType) {\n return (engine: I3DEngine, type?: string) => {\n const loaderType = type || this.options.modelLoaderType;\n if (!loaderType) {\n throw new Error(\"[String3D] Model loader type not provided\");\n }\n return engine.createModelLoader(loaderType);\n };\n }\n return undefined;\n }\n\n private createOrGetContainer(): HTMLElement {\n if (this.options.container instanceof HTMLElement) {\n this.applyContainerStyles(this.options.container);\n return this.options.container;\n }\n\n if (typeof this.options.container === \"string\") {\n const existing = document.getElementById(this.options.container);\n if (existing) {\n this.applyContainerStyles(existing);\n return existing;\n }\n }\n\n const container = document.createElement(\"div\");\n container.id = \"string-3d-canvas\";\n this.applyContainerStyles(container);\n document.body.insertBefore(container, document.body.firstChild);\n return container;\n }\n\n private applyContainerStyles(el: HTMLElement): void {\n Object.assign(el.style, {\n position: \"fixed\",\n left: \"0\",\n top: \"0\",\n width: \"100vw\",\n height: \"100lvh\",\n zIndex: String(this.options.zIndex),\n pointerEvents: \"none\",\n });\n }\n\n override onObjectConnected(object: StringObject): void {\n if (this.isLoading.has(object.id) || !this.scene) return;\n this.isLoading.set(object.id, true);\n\n this.scene.createFromElement(object);\n\n if (this.useDirtySync && object.htmlElement) {\n this.observeElement(object.htmlElement);\n this.markDirty(object.htmlElement);\n }\n\n if (this.options.hideHTML && object.htmlElement) {\n object.htmlElement.style.opacity = \"0\";\n object.htmlElement.style.pointerEvents = \"none\";\n }\n }\n\n override onFrame(data: StringData): void {\n if (!this.renderer || !this.scene || !this.camera || !this.synchronizer) return;\n\n const workerResults = this.transformWorker?.takeLastResult();\n if (\n workerResults &&\n workerResults.frameId === this.lastSubmittedVersion &&\n workerResults.frameId >= this.domVersion\n ) {\n this.workerHasResult = true;\n this.applyWorkerResults(workerResults.results);\n }\n\n const dirtySet = this.useDirtySync ? this.dirtyElements : null;\n // If dirty sync is enabled but nothing is marked dirty, we still sync everything to keep CSS-driven effects (hover/animations) fluid.\n const forceSync = !dirtySet || dirtySet.size === 0;\n const worker = this.transformWorker;\n\n // Collect and submit worker inputs only when the worker is free\n if (worker?.isReady() && !worker.isPending()) {\n const inputs: TransformWorkerInput[] = [];\n this.workerObjectMap.clear();\n this.scene!.rootObjects.forEach((obj) => {\n this.collectWorkerInputs(obj, { scale: 1 }, forceSync, dirtySet, inputs);\n });\n if (inputs.length > 0) {\n const frameId = this.domVersion;\n this.lastSubmittedVersion = frameId;\n worker.submit(inputs, this.buildWorkerCameraData(), frameId);\n }\n }\n\n // Always do immediate CPU sync to avoid frame lag while worker is pending\n this.scene!.rootObjects.forEach((obj) => {\n this.syncRecursive(obj.el, obj, { scale: 1 }, forceSync, dirtySet);\n });\n\n if (this.useDirtySync) {\n this.dirtyElements.clear();\n }\n\n this.renderer!.render(this.scene!, this.camera!);\n }\n\n private syncRecursive(\n el: HTMLElement | undefined,\n object: String3DObject,\n parentData: any,\n forceSync: boolean,\n dirtySet: Set<HTMLElement> | null\n ): void {\n if (!this.synchronizer || !el) return;\n const shouldSync = forceSync || !dirtySet || dirtySet.has(el);\n let nextParentData = parentData;\n\n if (shouldSync) {\n const data = this.synchronizer.syncElement(el, object, parentData);\n if (data && typeof data.scale === \"number\") {\n this.lastSyncData.set(object, data);\n nextParentData = data;\n }\n } else {\n const cached = this.lastSyncData.get(object);\n if (cached) {\n nextParentData = cached;\n }\n }\n\n const forceChildren = forceSync || shouldSync;\n object.children.forEach((child) =>\n this.syncRecursive(child.el, child, nextParentData, forceChildren, dirtySet)\n );\n }\n\n private injectCSS(): void {\n if (document.getElementById(\"string-3d-styles\")) return;\n\n const style = document.createElement(\"style\");\n style.id = \"string-3d-styles\";\n style.textContent = `\n @property --translate-x { syntax: \"<number>\"; inherits: false; initial-value: 0; }\n @property --translate-y { syntax: \"<number>\"; inherits: false; initial-value: 0; }\n @property --translate-z { syntax: \"<number>\"; inherits: false; initial-value: 0; }\n @property --rotate-x { syntax: \"<number>\"; inherits: false; initial-value: 0; }\n @property --rotate-y { syntax: \"<number>\"; inherits: false; initial-value: 0; }\n @property --rotate-z { syntax: \"<number>\"; inherits: false; initial-value: 0; }\n @property --scale { syntax: \"<number>\"; inherits: false; initial-value: 1; }\n @property --scale-x { syntax: \"<number>\"; inherits: false; initial-value: 1; }\n @property --scale-y { syntax: \"<number>\"; inherits: false; initial-value: 1; }\n @property --scale-z { syntax: \"<number>\"; inherits: false; initial-value: 1; }\n @property --opacity { syntax: \"<number>\"; inherits: false; initial-value: 1; }\n\n [string-3d] {\n --translate-x: 0; --translate-y: 0; --translate-z: 0;\n --rotate-x: 0; --rotate-y: 0; --rotate-z: 0;\n --scale: 1; --scale-x: 1; --scale-y: 1; --scale-z: 1;--opacity: 1;\n transform-style: preserve-3d;\n }\n\n [string-3d-visual=\"true\"] {\n transform:\n translate3d(calc(var(--translate-x) * 1px), calc(var(--translate-y) * 1px), calc(var(--translate-z) * 1px))\n rotateX(calc(var(--rotate-x) * 1deg))\n rotateY(calc(var(--rotate-y) * 1deg))\n rotateZ(calc(var(--rotate-z) * 1deg))\n scale3d(calc(var(--scale) * var(--scale-x)), calc(var(--scale) * var(--scale-y)), calc(var(--scale) * var(--scale-z)));\n }\n `;\n document.head.appendChild(style);\n }\n\n private registerTypedProperties(): void {\n const css = (globalThis as any).CSS;\n if (!css?.registerProperty) return;\n\n const props: Array<{ name: string; initialValue: string }> = [\n { name: \"--translate-x\", initialValue: \"0\" },\n { name: \"--translate-y\", initialValue: \"0\" },\n { name: \"--translate-z\", initialValue: \"0\" },\n { name: \"--rotate-x\", initialValue: \"0\" },\n { name: \"--rotate-y\", initialValue: \"0\" },\n { name: \"--rotate-z\", initialValue: \"0\" },\n { name: \"--scale\", initialValue: \"1\" },\n { name: \"--scale-x\", initialValue: \"1\" },\n { name: \"--scale-y\", initialValue: \"1\" },\n { name: \"--scale-z\", initialValue: \"1\" },\n { name: \"--opacity\", initialValue: \"1\" },\n ];\n\n props.forEach(({ name, initialValue }) => {\n try {\n css.registerProperty({\n name,\n syntax: \"<number>\",\n inherits: false,\n initialValue,\n });\n } catch {\n // Property may already be registered; ignore.\n }\n });\n }\n\n private setupObservers(): void {\n if (typeof ResizeObserver !== \"undefined\") {\n this.resizeObserver = new ResizeObserver((entries) => {\n entries.forEach((entry) => {\n if (entry.target instanceof HTMLElement) {\n this.markDirty(entry.target);\n }\n });\n });\n }\n\n if (typeof MutationObserver !== \"undefined\") {\n this.mutationObserver = new MutationObserver((mutations) => {\n mutations.forEach((mutation) => {\n if (mutation.target instanceof HTMLElement) {\n this.markDirty(mutation.target);\n }\n });\n });\n }\n }\n\n private setupScrollListeners(): void {\n window.addEventListener(\"scroll\", this.onScrollBound, { passive: true });\n window.addEventListener(\"resize\", this.onScrollBound, { passive: true });\n if (window.visualViewport) {\n window.visualViewport.addEventListener(\"scroll\", this.onScrollBound, { passive: true });\n window.visualViewport.addEventListener(\"resize\", this.onScrollBound, { passive: true });\n }\n }\n\n private removeScrollListeners(): void {\n window.removeEventListener(\"scroll\", this.onScrollBound);\n window.removeEventListener(\"resize\", this.onScrollBound);\n if (window.visualViewport) {\n window.visualViewport.removeEventListener(\"scroll\", this.onScrollBound);\n window.visualViewport.removeEventListener(\"resize\", this.onScrollBound);\n }\n }\n\n private handleScroll(): void {\n if (!this.useDirtySync) return;\n this.markAllDirty();\n }\n\n private observeElement(el: HTMLElement): void {\n if (this.observedElements.has(el)) return;\n this.observedElements.add(el);\n\n this.resizeObserver?.observe(el);\n this.mutationObserver?.observe(el, {\n attributes: true,\n attributeFilter: [\n \"style\",\n \"class\",\n \"string-3d\",\n \"string-3d-model-fit\",\n \"string-3d-model-scale\",\n \"string-3d-cast-shadow\",\n \"string-3d-receive-shadow\",\n \"string-3d-opacity\",\n \"string-3d-target\",\n ],\n });\n }\n\n private observeSceneElements(): void {\n if (!this.scene) return;\n this.scene.rootObjects.forEach((obj) => {\n this.observeRecursive(obj);\n });\n }\n\n private observeRecursive(object: String3DObject): void {\n if (object.el instanceof HTMLElement) {\n this.observeElement(object.el);\n }\n object.children.forEach((child) => this.observeRecursive(child));\n }\n\n private markDirty(el: HTMLElement): void {\n this.dirtyElements.add(el);\n this.domVersion += 1;\n }\n\n private markAllDirty(): void {\n this.observedElements.forEach((el) => this.dirtyElements.add(el));\n this.domVersion += 1;\n }\n\n private readNumberStyle(el: HTMLElement, prop: string, fallback: number): number {\n const styleMap = (el as any).computedStyleMap?.();\n const mapValue = styleMap?.get?.(prop);\n if (mapValue !== undefined) {\n if (typeof mapValue === \"number\") return mapValue;\n if (typeof mapValue === \"string\") {\n const parsed = Number.parseFloat(mapValue);\n if (!Number.isNaN(parsed)) return parsed;\n }\n if (mapValue && typeof mapValue === \"object\") {\n const value = (mapValue as any).value;\n if (typeof value === \"number\") return value;\n if (typeof value === \"string\") {\n const parsed = Number.parseFloat(value);\n if (!Number.isNaN(parsed)) return parsed;\n }\n }\n }\n\n const style = getComputedStyle(el);\n const raw = style.getPropertyValue(prop);\n const parsed = Number.parseFloat(raw);\n return Number.isNaN(parsed) ? fallback : parsed;\n }\n\n private buildWorkerCameraData(): TransformWorkerCamera {\n return {\n mode: this.camera!.getMode(),\n width: this.renderer!.width,\n height: this.renderer!.height,\n cameraZ: this.camera!.getPositionZ(),\n fov: this.camera!.getPerspectiveFov(),\n aspect: this.renderer!.width / this.renderer!.height,\n };\n }\n\n private collectWorkerInputs(\n object: String3DObject,\n parentData: { scale: number },\n forceSync: boolean,\n dirtySet: Set<HTMLElement> | null,\n inputs: TransformWorkerInput[]\n ): void {\n if (!this.synchronizer || !object.el) return;\n const el = object.el as HTMLElement;\n const shouldSync = forceSync || !dirtySet || dirtySet.has(el);\n let nextParentData = parentData;\n\n if (object.type.endsWith(\"Light\")) {\n if (shouldSync) {\n this.synchronizer.syncElement(el, object, parentData);\n }\n return;\n }\n\n if (shouldSync) {\n const rect = el.getBoundingClientRect();\n const layoutWidth = el.offsetWidth || rect.width;\n const layoutHeight = el.offsetHeight || rect.height;\n const translateZ = this.readNumberStyle(el, \"--translate-z\", 0);\n const scale = this.readNumberStyle(el, \"--scale\", 1);\n const scaleZ = this.readNumberStyle(el, \"--scale-z\", 1);\n const rotateX = this.readNumberStyle(el, \"--rotate-x\", 0);\n const rotateY = this.readNumberStyle(el, \"--rotate-y\", 0);\n const rotateZ = this.readNumberStyle(el, \"--rotate-z\", 0);\n const opacity = this.readNumberStyle(el, \"--opacity\", NaN);\n\n if (object.type !== \"group\") {\n MeshSynchronizer.applyVisualProps(el, object, opacity);\n }\n\n let modelSizeX: number | undefined;\n let modelSizeY: number | undefined;\n let modelScale: number | undefined;\n let fitMode: string | undefined;\n\n if (object.type === \"model\") {\n const bbox = object.getOriginalBoundingBox();\n const size = bbox.getSize(this.engine!.createVector3());\n modelSizeX = size.x;\n modelSizeY = size.y;\n const modelScaleAttr = parseFloat(el.getAttribute(\"string-3d-model-scale\") || \"1\");\n modelScale = Number.isFinite(modelScaleAttr) ? modelScaleAttr : 1;\n fitMode = (el.getAttribute(\"string-3d-model-fit\") || \"contain\").toLowerCase().trim();\n }\n\n const returnScale = object.type === \"group\" ? scale : scale * parentData.scale;\n this.lastSyncData.set(object, { scale: returnScale });\n nextParentData = { scale: returnScale };\n\n this.workerObjectMap.set(object.id, { object, el });\n inputs.push({\n id: object.id,\n type: object.type,\n rectLeft: rect.left,\n rectTop: rect.top,\n rectWidth: layoutWidth,\n rectHeight: layoutHeight,\n translateZ,\n scale,\n scaleZ,\n rotateX,\n rotateY,\n rotateZ,\n parentScale: parentData.scale,\n modelSizeX,\n modelSizeY,\n modelScale,\n fitMode,\n });\n } else {\n const cached = this.lastSyncData.get(object);\n if (cached) {\n nextParentData = cached;\n }\n }\n\n const forceChildren = forceSync || shouldSync;\n object.children.forEach((child) => {\n this.collectWorkerInputs(child, nextParentData, forceChildren, dirtySet, inputs);\n });\n }\n\n private applyWorkerResults(results: TransformWorkerResult[]): void {\n if (!this.engine) return;\n results.forEach((result) => {\n const entry = this.workerObjectMap.get(result.id);\n if (!entry) return;\n const object = entry.object;\n object.position = this.engine!.createVector3(result.posX, result.posY, result.posZ);\n object.rotation = this.engine!.createEuler(result.rotX, result.rotY, result.rotZ, \"XYZ\");\n object.scale = this.engine!.createVector3(result.scaleX, result.scaleY, result.scaleZ);\n if (object.type === \"group\") {\n object.object.updateMatrixWorld(true);\n }\n });\n }\n\n override destroy(): void {\n this.renderer?.destroy();\n this.scene?.destroy();\n this.isLoading.clear();\n this.transformWorker?.destroy();\n this.transformWorker = null;\n this.removeScrollListeners();\n this.resizeObserver?.disconnect();\n this.mutationObserver?.disconnect();\n this.observedElements.clear();\n this.dirtyElements.clear();\n this.workerObjectMap.clear();\n this.lastSyncData = new WeakMap();\n\n const styleEl = document.getElementById(\"string-3d-styles\");\n styleEl?.remove();\n\n if (this.canvasContainer?.id === \"string-3d-canvas\") {\n this.canvasContainer.remove();\n }\n\n super.destroy();\n }\n}\n","import { I3DEngine, I3DVector3, I3DCamera } from \"./abstractions/I3DEngine\";\r\n\r\nexport type CameraMode = \"orthographic\" | \"perspective\";\r\n\r\nexport class String3DCamera {\r\n private scaleCache = new Map<number, number>();\r\n private _camera: I3DCamera;\r\n private _position: I3DVector3;\r\n private _width = 1;\r\n private _height = 1;\r\n private engine: I3DEngine;\r\n private mode: CameraMode;\r\n private perspectiveFov: number;\r\n\r\n constructor(\r\n engine: I3DEngine,\r\n mode: CameraMode = \"orthographic\",\r\n fov = 50,\r\n near = 0.1,\r\n far = 10000\r\n ) {\r\n this.engine = engine;\r\n this.mode = mode;\r\n this.perspectiveFov = fov;\r\n\r\n if (mode === \"orthographic\") {\r\n this._camera = engine.createOrthographicCamera(-1, 1, 1, -1, near, far);\r\n } else {\r\n this._camera = engine.createPerspectiveCamera(fov, 1, near, far);\r\n }\r\n\r\n this._position = engine.createVector3(0, 0, 1000);\r\n this.update();\r\n }\r\n\r\n public get camera(): I3DCamera {\r\n return this._camera;\r\n }\r\n\r\n public resize(width: number, height: number): void {\r\n this._width = width;\r\n this._height = height;\r\n\r\n if (this.mode === \"orthographic\") {\r\n const ortho = this._camera as any;\r\n ortho.left = -width / 2;\r\n ortho.right = width / 2;\r\n ortho.top = height / 2;\r\n ortho.bottom = -height / 2;\r\n } else {\r\n this._camera.aspect = width / height;\r\n }\r\n\r\n this.update();\r\n }\r\n\r\n public setPosition(x: number, y: number, z: number): void {\r\n this._position.set(x, y, z);\r\n this._camera.position.copy(this._position);\r\n this.update();\r\n }\r\n\r\n public lookAt(x: number, y: number, z: number): void {\r\n this._camera.lookAt(x, y, z);\r\n this.update();\r\n }\r\n\r\n public update(): void {\r\n this._camera.updateProjectionMatrix();\r\n (this._camera as any).updateMatrixWorld?.();\r\n }\r\n\r\n public screenToWorld(screenX: number, screenY: number, z = 0): I3DVector3 {\r\n if (this.mode === \"orthographic\") {\r\n const x = screenX - this._width / 2;\r\n const y = -(screenY - this._height / 2);\r\n return this.engine.createVector3(x, y, z);\r\n } else {\r\n const { width, height } = this.getFrustumSizeAt(z);\r\n const normalizedX = screenX / this._width;\r\n const normalizedY = screenY / this._height;\r\n const x = (normalizedX - 0.5) * width;\r\n const y = -(normalizedY - 0.5) * height;\r\n return this.engine.createVector3(x, y, z);\r\n }\r\n }\r\n\r\n public getFrustumSizeAt(z: number): { width: number; height: number } {\r\n if (this.mode === \"orthographic\") {\r\n return { width: this._width, height: this._height };\r\n }\r\n\r\n const fov = this.engine.degToRad(this.perspectiveFov);\r\n const distance = Math.abs(z - this._camera.position.z);\r\n const height = 2 * Math.tan(fov / 2) * distance;\r\n const width = height * this._camera.aspect;\r\n return { width, height };\r\n }\r\n\r\n public getScaleAtZ(z: number, viewportHeight: number): number {\r\n if (this.mode === \"orthographic\") {\r\n return 1;\r\n }\r\n\r\n const roundedZ = Math.round(z * 1000) / 1000;\r\n if (this.scaleCache.has(roundedZ)) {\r\n return this.scaleCache.get(roundedZ)!;\r\n }\r\n\r\n const { height } = this.getFrustumSizeAt(z);\r\n const scale = height / viewportHeight;\r\n this.scaleCache.set(roundedZ, scale);\r\n return scale;\r\n }\r\n\r\n public clearScaleCache(): void {\r\n this.scaleCache.clear();\r\n }\r\n\r\n public getMode(): CameraMode {\n return this.mode;\n }\n\n public getPerspectiveFov(): number {\n return this.perspectiveFov;\n }\n\n public getPositionZ(): number {\n return this._position.z;\n }\n}\n","import { I3DEngine, I3DRenderer } from \"./abstractions/I3DEngine\";\r\nimport { String3DCamera } from \"./String3DCamera\";\r\nimport { String3DScene } from \"./String3DScene\";\r\n\r\nexport class String3DRenderer {\r\n private _container: HTMLElement;\r\n private _renderer: I3DRenderer;\r\n private _width: number;\r\n private _height: number;\r\n private engine: I3DEngine;\r\n\r\n constructor(container: HTMLElement, engine: I3DEngine) {\r\n this.engine = engine;\r\n this._container = container;\r\n const { width, height } = container.getBoundingClientRect();\r\n this._width = width;\r\n this._height = height;\r\n\r\n this._renderer = engine.createRenderer({\r\n antialias: true,\r\n alpha: true,\r\n logarithmicDepthBuffer: true,\r\n });\r\n this._renderer.setPixelRatio(window.devicePixelRatio);\r\n this._renderer.setSize(width, height);\r\n\r\n if (this._renderer.shadowMap) {\r\n this._renderer.shadowMap.enabled = true;\r\n }\r\n }\r\n\r\n public attach(): void {\r\n this._container.appendChild(this._renderer.domElement);\r\n }\r\n\r\n public render(scene: String3DScene, camera: String3DCamera): void {\r\n this._renderer.render(scene.getScene(), camera.camera);\r\n }\r\n\r\n public resize(camera: String3DCamera): void {\r\n const { width, height } = this._container.getBoundingClientRect();\r\n this._width = width;\r\n this._height = height;\r\n this._renderer.setSize(width, height);\r\n camera.resize(width, height);\r\n }\r\n\r\n public get width(): number {\r\n return this._width;\r\n }\r\n\r\n public get height(): number {\r\n return this._height;\r\n }\r\n\r\n public get renderer(): I3DRenderer {\r\n return this._renderer;\r\n }\r\n\r\n public destroy(): void {\r\n this._renderer.dispose();\r\n }\r\n}\r\n","import {\r\n I3DEngine,\r\n I3DObject,\r\n I3DMaterial,\r\n I3DGeometry,\r\n I3DQuaternion,\r\n I3DVector3,\r\n I3DEuler,\r\n I3DMatrix4,\r\n I3DBox3,\r\n} from \"./abstractions/I3DEngine\";\r\n\r\nexport class String3DObject {\n public id: string;\n public type: string;\n private _object: I3DObject;\n private _material?: I3DMaterial;\n private _geometry?: I3DGeometry;\n private _texture?: any;\n private _uniforms: Record<string, { value: any }> = {};\r\n private _originalBoundingBox?: I3DBox3 | null;\r\n private _quaternion: I3DQuaternion;\r\n private _originalSize: I3DVector3;\r\n private _bbox: I3DBox3;\r\n public el: any;\r\n private _children: String3DObject[] = [];\r\n private engine: I3DEngine;\r\n\r\n public get children(): String3DObject[] {\r\n return this._children;\r\n }\r\n\r\n constructor(\n id: string,\n type: string,\n object: I3DObject,\n engine: I3DEngine,\n options: { material?: I3DMaterial; geometry?: I3DGeometry; texture?: any } = {}\n ) {\n this.id = id;\n this.type = type;\n this._object = object;\n this.engine = engine;\n this._material = options.material;\n this._geometry = options.geometry;\n this._texture = options.texture;\n this._quaternion = engine.createQuaternion();\n this._originalSize = engine.createVector3();\n this._bbox = engine.createBox3();\n this.updateBoundingBox();\n }\n\r\n public get object(): I3DObject {\r\n return this._object;\r\n }\r\n\r\n public get material(): I3DMaterial | undefined {\r\n return this._material;\r\n }\r\n\r\n public get originalSize(): I3DVector3 {\r\n return this._originalSize.clone();\r\n }\r\n\r\n public get boundingBox(): I3DBox3 {\r\n return this._bbox.clone();\r\n }\r\n\r\n public addChild(child: String3DObject): void {\r\n this._children.push(child);\r\n this.object.add(child.object);\r\n }\r\n\r\n public getWorldMatrix(): I3DMatrix4 {\r\n return this._object.matrixWorld.clone();\r\n }\r\n\r\n public getWorldPosition(): I3DVector3 {\r\n return this.engine.createVector3().setFromMatrixPosition(this._object.matrixWorld);\r\n }\r\n\r\n public getOriginalBoundingBox(): I3DBox3 {\r\n if (!this._originalBoundingBox) {\r\n const originalScale = this.object.scale.clone();\r\n this.object.scale.set(1, 1, 1);\r\n this.object.updateMatrixWorld(true);\r\n this._originalBoundingBox = this.engine.computeBoundingBoxRecursively(this.object);\r\n this.object.scale.copy(originalScale);\r\n this.object.updateMatrixWorld(true);\r\n }\r\n return this._originalBoundingBox!.clone();\r\n }\r\n\r\n public syncTransformFromMatrix(matrix: I3DMatrix4): void {\r\n const pos = this.engine.createVector3();\r\n const quat = this.engine.createQuaternion();\r\n const scale = this.engine.createVector3();\r\n matrix.decompose(pos, quat, scale);\r\n this._object.position.copy(pos);\r\n this._object.quaternion.copy(quat);\r\n this._object.scale.copy(scale);\r\n this._object.updateMatrix();\r\n this._object.updateMatrixWorld();\r\n }\r\n\r\n public applyWorldTransform(\r\n position: I3DVector3,\r\n quaternion: I3DQuaternion,\r\n scale: I3DVector3\r\n ): void {\r\n this._object.position.copy(position);\r\n this._object.quaternion.copy(quaternion);\r\n this._object.scale.copy(scale);\r\n this._object.updateMatrix();\r\n this._object.updateMatrixWorld();\r\n }\r\n\r\n public set quaternion(quaternion: I3DQuaternion) {\r\n this._quaternion.copy(quaternion);\r\n this._object.quaternion.copy(this._quaternion);\r\n this._object.updateMatrixWorld();\r\n }\r\n\r\n public set position(position: I3DVector3) {\r\n this._object.position.copy(position);\r\n }\r\n\r\n public set scale(scale: I3DVector3) {\r\n this._object.scale.copy(scale);\r\n }\r\n\r\n public set rotation(euler: I3DEuler) {\r\n this._object.rotation.copy(euler);\r\n }\r\n\r\n public set opacity(value: number) {\r\n const mat = this._object as any;\r\n if (mat.material && \"opacity\" in mat.material) {\r\n mat.material.opacity = value;\r\n }\r\n }\r\n\r\n public set metalness(value: number) {\r\n const mat = this._object as any;\r\n if (mat.material && \"metalness\" in mat.material) {\r\n mat.material.metalness = value;\r\n }\r\n }\r\n\r\n public set roughness(value: number) {\r\n const mat = this._object as any;\r\n if (mat.material && \"roughness\" in mat.material) {\r\n mat.material.roughness = value;\r\n }\r\n }\r\n\r\n public set texture(texture: any) {\n this._texture = texture;\n if ((this._object as any).isMesh && texture?.applyTexture) {\n texture.applyTexture(this._object);\n }\n }\n\n public set material(material: I3DMaterial | undefined) {\n this._material = material;\n }\n\n public set geometry(geometry: I3DGeometry | undefined) {\n this._geometry = geometry;\n }\n\n public updateBoundingBox(): void {\n this._bbox.setFromObject(this._object);\n this._bbox.getSize(this._originalSize);\n }\n\n public destroy(): void {\n this.disposeObjectResources(this._object);\n this._texture?.dispose?.();\n this._material?.dispose();\n this._geometry?.dispose();\n }\n\n private disposeObjectResources(object: I3DObject): void {\n const anyObj = object as any;\n if (anyObj?.geometry?.dispose) {\n anyObj.geometry.dispose();\n }\n const material = anyObj?.material;\n if (Array.isArray(material)) {\n material.forEach((mat) => mat?.dispose?.());\n } else if (material?.dispose) {\n material.dispose();\n }\n if (typeof anyObj?.traverse === \"function\") {\n anyObj.traverse((child: any) => {\n if (child?.geometry?.dispose) {\n child.geometry.dispose();\n }\n const childMat = child?.material;\n if (Array.isArray(childMat)) {\n childMat.forEach((mat: any) => mat?.dispose?.());\n } else if (childMat?.dispose) {\n childMat.dispose();\n }\n });\n }\n }\n}\n","import {\n I3DEngine,\n I3DScene,\n I3DLight,\n I3DMaterial,\n I3DModelLoader,\n I3DVector3,\n} from \"./abstractions/I3DEngine\";\nimport { String3DObject } from \"./String3DObject\";\nimport { StringObject } from \"@fiddle-digital/string-tune\";\n\nexport interface String3DSceneOptions {\n modelLoader?: I3DModelLoader;\n modelLoaderFactory?: (engine: I3DEngine, type?: string) => I3DModelLoader;\n}\n\nexport class String3DScene {\n private _scene: I3DScene;\n private _objects: Map<string, String3DObject> = new Map();\n private _rootObjects: String3DObject[] = [];\n private _elementMap: Map<string, HTMLElement> = new Map();\n private engine: I3DEngine;\n private _modelLoader?: I3DModelLoader;\n private _modelLoaderFactory?: (engine: I3DEngine, type?: string) => I3DModelLoader;\n private _modelLoaderCache: Map<string, I3DModelLoader> = new Map();\n\n public get rootObjects(): String3DObject[] {\n return this._rootObjects;\n }\n\n constructor(engine: I3DEngine, options: String3DSceneOptions = {}) {\n this.engine = engine;\n this._modelLoader = options.modelLoader;\n this._modelLoaderFactory = options.modelLoaderFactory;\n this._scene = engine.createScene();\n }\n\n public getScene(): I3DScene {\n return this._scene;\n }\n\n public getObject(id: string): String3DObject | undefined {\n return this._objects.get(id);\n }\n\n public hasObject(id: string): boolean {\n return this._objects.has(id);\n }\n\n public deleteObject(id: string): boolean {\n const obj = this._objects.get(id);\n if (obj) {\n this._scene.remove(obj.object);\n this._objects.delete(id);\n obj.destroy();\n return true;\n }\n return false;\n }\n\n public createFromElement(object: StringObject): void {\n const type = object.getProperty<string>(\"3d\");\n if (!type) return;\n\n const element = object.htmlElement;\n if (!element) return;\n\n const onAdd = (added3DObject: String3DObject) => {\n if (added3DObject) {\n const parentId = object.getProperty<string>(\"parentId\");\n if (parentId == null) {\n this._scene.add(added3DObject.object);\n this._rootObjects.push(added3DObject);\n } else {\n this._objects.get(parentId)?.addChild(added3DObject);\n }\n this._objects.set(object.id, added3DObject);\n this._elementMap.set(object.id, element);\n added3DObject.el = element;\n }\n };\n\n switch (type) {\n case \"group\":\n this.createGroup(object, onAdd);\n break;\n case \"pointLight\":\n this.createLight(object, \"point\", onAdd);\n break;\n case \"ambientLight\":\n this.createLight(object, \"ambient\", onAdd);\n break;\n case \"directionalLight\":\n this.createLight(object, \"directional\", onAdd);\n break;\n case \"spotLight\":\n this.createLight(object, \"spot\", onAdd);\n break;\n case \"hemisphereLight\":\n this.createLight(object, \"hemisphere\", onAdd);\n break;\n case \"model\":\n this.createModel(object, onAdd);\n break;\n case \"box\":\n this.createBox(object, onAdd);\n break;\n case \"sphere\":\n this.createSphere(object, onAdd);\n break;\n case \"plane\":\n this.createPlane(object, onAdd);\n break;\n case \"cylinder\":\n this.createCylinder(object, onAdd);\n break;\n }\n }\n\n private createGroup(object: StringObject, onAdd: (obj: String3DObject) => void): String3DObject {\n const group = this.engine.createGroup();\n const obj = new String3DObject(object.id, \"group\", group, this.engine);\n onAdd(obj);\n return obj;\n }\n\n private createLight(\n object: StringObject,\n kind: \"point\" | \"ambient\" | \"directional\" | \"spot\" | \"hemisphere\",\n onAdd: (obj: String3DObject) => void\n ): String3DObject {\n const color = object.getProperty<string>(\"3d-color\") || \"#ffffff\";\n const intensity = object.getProperty<number>(\"3d-intensity\") ?? 1;\n\n let light: I3DLight;\n if (kind === \"point\") {\n const distance = object.getProperty<number>(\"3d-distance\") ?? 1000;\n const decay = object.getProperty<number>(\"3d-decay\") ?? 0;\n light = this.engine.createPointLight(color, intensity, distance, decay);\n } else if (kind === \"directional\") {\n light = this.engine.createDirectionalLight(color, intensity);\n } else if (kind === \"spot\") {\n const distance = object.getProperty<number>(\"3d-distance\") ?? 0;\n const angle = object.getProperty<number>(\"3d-angle\") ?? Math.PI / 3;\n const penumbra = object.getProperty<number>(\"3d-penumbra\") ?? 0;\n const decay = object.getProperty<number>(\"3d-decay\") ?? 1;\n light = this.engine.createSpotLight(color, intensity, distance, angle, penumbra, decay);\n } else if (kind === \"hemisphere\") {\n const groundColor = object.getProperty<string>(\"3d-ground-color\") || \"#ffffff\";\n light = this.engine.createHemisphereLight(color, groundColor, intensity);\n } else {\n light = this.engine.createAmbientLight(color, intensity);\n }\n\n const castShadow = object.getProperty<boolean>(\"3d-cast-shadow\") ?? false;\n if (castShadow && light.shadow) {\n light.castShadow = true;\n const bias = object.getProperty<number>(\"3d-shadow-bias\") ?? 0;\n const mapSize = object.getProperty<number>(\"3d-shadow-map-size\") ?? 512;\n light.shadow.bias = bias;\n light.shadow.mapSize.width = mapSize;\n light.shadow.mapSize.height = mapSize;\n }\n\n const obj = new String3DObject(object.id, kind + \"Light\", light, this.engine);\n onAdd(obj);\n return obj;\n }\n\n private applyShadowProps(object: StringObject, mesh: any): void {\n const castShadow = object.getProperty<boolean>(\"3d-cast-shadow\") ?? false;\n const receiveShadow = object.getProperty<boolean>(\"3d-receive-shadow\") ?? false;\n mesh.castShadow = castShadow;\n mesh.receiveShadow = receiveShadow;\n }\n\n private createBox(object: StringObject, onAdd: (obj: String3DObject) => void): String3DObject {\n const geometry = this.engine.createBoxGeometry(1, 1, 1);\n const material = this.createMaterialFromObject(object);\n const mesh = this.engine.createMesh(geometry, material);\n this.applyShadowProps(object, mesh);\n const obj = new String3DObject(object.id, \"box\", mesh, this.engine, {\n geometry,\n material,\n });\n onAdd(obj);\n return obj;\n }\n\n private createSphere(object: StringObject, onAdd: (obj: String3DObject) => void): String3DObject {\n const widthSegments = object.getProperty<number>(\"3d-segments-width\") ?? 32;\n const heightSegments = object.getProperty<number>(\"3d-segments-height\") ?? 32;\n const geometry = this.engine.createSphereGeometry(0.5, widthSegments, heightSegments);\n const material = this.createMaterialFromObject(object);\n const mesh = this.engine.createMesh(geometry, material);\n this.applyShadowProps(object, mesh);\n const obj = new String3DObject(object.id, \"sphere\", mesh, this.engine, {\n geometry,\n material,\n });\n onAdd(obj);\n return obj;\n }\n\n private createPlane(object: StringObject, onAdd: (obj: String3DObject) => void): String3DObject {\n const geometry = this.engine.createPlaneGeometry(1, 1);\n const material = this.createMaterialFromObject(object);\n const mesh = this.engine.createMesh(geometry, material);\n this.applyShadowProps(object, mesh);\n const obj = new String3DObject(object.id, \"plane\", mesh, this.engine, {\n geometry,\n material,\n });\n onAdd(obj);\n return obj;\n }\n\n private createCylinder(\n object: StringObject,\n onAdd: (obj: String3DObject) => void\n ): String3DObject {\n const segments = object.getProperty<number>(\"3d-segments\") ?? 32;\n const geometry = this.engine.createCylinderGeometry(0.5, 0.5, 1, segments);\n const material = this.createMaterialFromObject(object);\n const mesh = this.engine.createMesh(geometry, material);\n this.applyShadowProps(object, mesh);\n const obj = new String3DObject(object.id, \"cylinder\", mesh, this.engine, {\n geometry,\n material,\n });\n onAdd(obj);\n return obj;\n }\n\n private createModel(object: StringObject, onAdd: (obj: String3DObject) => void): void {\n const modelPath = object.getProperty<string>(\"3d-model\");\n if (!modelPath) return;\n\n const loaderType = object.getProperty<string>(\"3d-model-loader\") || undefined;\n const loader = this.resolveModelLoader(loaderType);\n if (!loader) {\n console.warn(\"[String3D] Model loader not configured\");\n return;\n }\n\n const element = object.htmlElement;\n if (element) {\n this.applyModelTextureRemap(loader, element);\n }\n const shouldCenter = object.getProperty<boolean>(\"3d-model-center\") ?? false;\n\n loader.load(\n modelPath,\n (gltf: any) => {\n const root = gltf?.scene || gltf?.object || gltf;\n if (!root) {\n console.warn(\"[String3D] Model loader returned empty result\");\n return;\n }\n\n const overrideMaterial =\n element && this.shouldOverrideModelMaterial(element)\n ? this.createMaterialFromElement(element, object)\n : null;\n\n if (typeof root.traverse === \"function\") {\n root.traverse((child: any) => {\n if (child.isMesh) {\n if (overrideMaterial) {\n child.material = overrideMaterial;\n }\n this.applyShadowProps(object, child);\n }\n });\n }\n\n if (shouldCenter) {\n this.centerObject(root);\n }\n const obj = new String3DObject(object.id, \"model\", root, this.engine);\n onAdd(obj);\n },\n (xhr: any) => {\n console.log((xhr.loaded / xhr.total) * 100 + \"% loaded\");\n },\n (error: any) => {\n console.error(\"[String3D] Model loading error:\", error);\n }\n );\n }\n\n private resolveModelLoader(type?: string): I3DModelLoader | undefined {\n if (type) {\n if (this._modelLoaderCache.has(type)) {\n return this._modelLoaderCache.get(type);\n }\n if (!this._modelLoaderFactory) {\n console.warn(`[String3D] No model loader factory for type \"${type}\"`);\n return undefined;\n }\n const loader = this._modelLoaderFactory(this.engine, type);\n this._modelLoaderCache.set(type, loader);\n return loader;\n }\n\n if (this._modelLoader) {\n return this._modelLoader;\n }\n\n if (this._modelLoaderFactory) {\n return this._modelLoaderFactory(this.engine);\n }\n\n return undefined;\n }\n\n private centerObject(object: any): void {\n if (!object) return;\n const bbox = this.engine.computeBoundingBoxRecursively(object);\n const center = this.getBoxCenter(bbox);\n if (object.position?.set) {\n object.position.set(-center.x, -center.y, -center.z);\n }\n object.updateMatrixWorld(true);\n }\n\n private getBoxCenter(box: any): I3DVector3 {\n const center = this.engine.createVector3();\n center.x = (box.min.x + box.max.x) / 2;\n center.y = (box.min.y + box.max.y) / 2;\n center.z = (box.min.z + box.max.z) / 2;\n return center;\n }\n\n private createMaterialFromObject(object: StringObject): I3DMaterial {\n return this.createMaterialFromElement(object.htmlElement, object);\n }\n\n private createMaterialFromElement(\n element: HTMLElement | null,\n object?: StringObject\n ): I3DMaterial {\n const attr = object?.getProperty<string>(\"3d-material\") || \"basic[#ffffff]\";\n let [type, colorRaw] = attr.split(/\\[|\\]/);\n const color = colorRaw || \"#ffffff\";\n const opacity = object?.getProperty<number>(\"3d-opacity\") ?? 1;\n const metalness = object?.getProperty<number>(\"3d-metalness\");\n const roughness = object?.getProperty<number>(\"3d-roughness\");\n const params: any = {\n color,\n transparent: opacity < 1,\n opacity: opacity,\n };\n\n const mapSrc = element?.getAttribute(\"string-3d-map\");\n const normalMapSrc = element?.getAttribute(\"string-3d-normalMap\");\n const roughnessMapSrc = element?.getAttribute(\"string-3d-roughnessMap\");\n const metalnessMapSrc = element?.getAttribute(\"string-3d-metalnessMap\");\n const aoMapSrc = element?.getAttribute(\"string-3d-aoMap\");\n const flipY = this.parseFlipY(object, element);\n const colorSpace =\n object?.getProperty<string>(\"3d-colorSpace\") ||\n element?.getAttribute(\"string-3d-colorSpace\") ||\n \"\";\n\n const hasMaps = !!(mapSrc || normalMapSrc || roughnessMapSrc || metalnessMapSrc || aoMapSrc);\n if (type !== \"standard\" && hasMaps) {\n type = \"standard\";\n }\n\n if (type === \"standard\") {\n if (mapSrc) {\n params.map = this.loadTexture(mapSrc, { flipY, colorSpace });\n }\n if (normalMapSrc) params.normalMap = this.loadTexture(normalMapSrc, { flipY });\n if (roughnessMapSrc) params.roughnessMap = this.loadTexture(roughnessMapSrc, { flipY });\n if (metalnessMapSrc) params.metalnessMap = this.loadTexture(metalnessMapSrc, { flipY });\n if (aoMapSrc) params.aoMap = this.loadTexture(aoMapSrc, { flipY });\n if (typeof metalness === \"number\") params.metalness = metalness;\n if (typeof roughness === \"number\") params.roughness = roughness;\n return this.engine.createMeshStandardMaterial(params);\n }\n\n return this.engine.createMeshBasicMaterial(params);\n }\n\n private loadTexture(src: string, options: { flipY?: boolean; colorSpace?: string } = {}): any {\n const textureLoader = this.engine.createTextureLoader();\n const texture = textureLoader.load(src);\n if (typeof options.flipY === \"boolean\") {\n texture.flipY = options.flipY;\n }\n const colorSpace = (options.colorSpace || \"\").toLowerCase().trim();\n if (colorSpace && \"colorSpace\" in texture) {\n texture.colorSpace = colorSpace === \"srgb\" ? \"srgb\" : \"linear\";\n }\n texture.needsUpdate = true;\n return texture;\n }\n\n private parseFlipY(object?: StringObject, element?: HTMLElement | null): boolean | undefined {\n const value =\n object?.getProperty<boolean>(\"3d-texture-flipY\") ??\n element?.getAttribute(\"string-3d-texture-flipY\");\n if (value === undefined || value === null || value === \"\") return undefined;\n if (typeof value === \"boolean\") return value;\n const normalized = String(value).toLowerCase().trim();\n if (normalized === \"false\" || normalized === \"0\" || normalized === \"no\") return false;\n if (normalized === \"true\" || normalized === \"1\" || normalized === \"yes\") return true;\n return undefined;\n }\n\n private shouldOverrideModelMaterial(element: HTMLElement): boolean {\n const attrs = [\n \"string-3d-material\",\n \"string-3d-color\",\n \"string-3d-opacity\",\n \"string-3d-map\",\n \"string-3d-normalMap\",\n \"string-3d-roughnessMap\",\n \"string-3d-metalnessMap\",\n \"string-3d-aoMap\",\n \"string-3d-metalness\",\n \"string-3d-roughness\",\n ];\n return attrs.some((attr) => element.hasAttribute(attr));\n }\n\n private applyModelTextureRemap(loader: any, element: HTMLElement): void {\n const baseRaw = (element.getAttribute(\"string-3d-model-texture-base\") || \"\").trim();\n const base = baseRaw ? baseRaw.replace(/\\/?$/, \"/\") : \"\";\n const mappingRaw = element.getAttribute(\"string-3d-model-textures\");\n let mapping: Record<string, string> | null = null;\n\n if (mappingRaw) {\n try {\n mapping = JSON.parse(mappingRaw);\n } catch (error) {\n console.warn(\"[String3D] Invalid model texture mapping JSON:\", error);\n }\n }\n\n const manager = loader?.manager;\n if (!manager || typeof manager.setURLModifier !== \"function\") {\n if (mapping || base) {\n console.warn(\"[String3D] Model loader does not support URL remap.\");\n }\n return;\n }\n\n manager.setURLModifier((url: string) => {\n const mapped = mapping && url in mapping ? mapping[url] : url;\n if (!base) return mapped;\n if (/^(blob:|data:|https?:|file:|\\/)/i.test(mapped)) return mapped;\n return base + mapped.replace(/^\\.?\\//, \"\");\n });\n }\n\n public destroy(): void {\n this._objects.forEach((obj) => obj.destroy());\n this._objects.clear();\n this._rootObjects = [];\n }\n}\n","import { String3DObject } from \"../String3DObject\";\nimport type { String3DObjectSyncStrategy } from \"./String3DObjectSyncStrategy\";\nimport type { SyncContext } from \"./SyncContext\";\n\ntype StyleMap = {\n get?: (prop: string) => any;\n};\n\nexport class GroupSynchronizer implements String3DObjectSyncStrategy {\n sync(el: HTMLElement, object: String3DObject, ctx: SyncContext, parentData: any): any {\n const rect = el.getBoundingClientRect();\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n\n const styleMap = (el as any).computedStyleMap?.() as StyleMap | undefined;\n let style: CSSStyleDeclaration | null = null;\n const getStyle = () => {\n if (!style) style = getComputedStyle(el);\n return style;\n };\n\n const readNumberStyle = (prop: string, fallback: number): number => {\n const mapValue = styleMap?.get?.(prop);\n if (mapValue !== undefined) {\n if (typeof mapValue === \"number\") return mapValue;\n if (typeof mapValue === \"string\") {\n const parsed = Number.parseFloat(mapValue);\n if (!Number.isNaN(parsed)) return parsed;\n }\n if (mapValue && typeof mapValue === \"object\") {\n const value = (mapValue as any).value;\n if (typeof value === \"number\") return value;\n if (typeof value === \"string\") {\n const parsed = Number.parseFloat(value);\n if (!Number.isNaN(parsed)) return parsed;\n }\n }\n }\n\n const raw = getStyle().getPropertyValue(prop);\n const parsed = Number.parseFloat(raw);\n return Number.isNaN(parsed) ? fallback : parsed;\n };\n\n const translateZ = readNumberStyle(\"--translate-z\", 0);\n const position = ctx.camera.screenToWorld(centerX, centerY, translateZ);\n object.position = position;\n\n const scale = readNumberStyle(\"--scale\", 1);\n object.scale = ctx.engine.createVector3(scale, scale, scale);\n\n const rotateX = -ctx.engine.degToRad(readNumberStyle(\"--rotate-x\", 0));\n const rotateY = ctx.engine.degToRad(readNumberStyle(\"--rotate-y\", 0));\n const rotateZ = -ctx.engine.degToRad(readNumberStyle(\"--rotate-z\", 0));\n object.rotation = ctx.engine.createEuler(rotateX, rotateY, rotateZ, \"XYZ\");\n\r\n object.object.updateMatrixWorld(true);\r\n\r\n return { scale };\r\n }\r\n}\r\n","import { String3DObject } from \"../String3DObject\";\r\nimport type { String3DObjectSyncStrategy } from \"./String3DObjectSyncStrategy\";\r\nimport type { SyncContext } from \"./SyncContext\";\r\nimport { I3DLight } from \"../abstractions/I3DEngine\";\r\n\r\nexport class LightSynchronizer implements String3DObjectSyncStrategy {\r\n sync(el: HTMLElement, object: String3DObject, ctx: SyncContext, parentData: any): any {\r\n const rect = el.getBoundingClientRect();\r\n const centerX = rect.left + rect.width / 2;\r\n const centerY = rect.top + rect.height / 2;\r\n\r\n const translateZ = parseFloat(getComputedStyle(el).getPropertyValue(\"--translate-z\") || \"0\");\r\n const position = ctx.camera.screenToWorld(centerX, centerY, translateZ);\r\n object.position = position;\r\n\r\n const light = object.object as I3DLight;\r\n\r\n // Color\r\n const color = el.getAttribute(\"string-3d-color\");\r\n if (color && light.color && typeof light.color.set === \"function\") {\r\n light.color.set(color);\r\n }\r\n\r\n // Intensity\r\n const intensity = el.getAttribute(\"string-3d-intensity\");\r\n if (intensity) {\r\n light.intensity = parseFloat(intensity);\r\n }\r\n\r\n // Distance & Decay\r\n const distance = el.getAttribute(\"string-3d-distance\");\r\n if (distance && typeof light.distance !== \"undefined\") {\r\n light.distance = parseFloat(distance);\r\n }\r\n const decay = el.getAttribute(\"string-3d-decay\");\r\n if (decay && typeof light.decay !== \"undefined\") {\r\n light.decay = parseFloat(decay);\r\n }\r\n\r\n // SpotLight specific\r\n const angle = el.getAttribute(\"string-3d-angle\");\r\n if (angle && typeof light.angle !== \"undefined\") {\r\n light.angle = parseFloat(angle);\r\n }\r\n const penumbra = el.getAttribute(\"string-3d-penumbra\");\r\n if (penumbra && typeof light.penumbra !== \"undefined\") {\r\n light.penumbra = parseFloat(penumbra);\r\n }\r\n\r\n // Hemisphere specific\r\n const groundColor = el.getAttribute(\"string-3d-ground-color\");\r\n if (\r\n groundColor &&\r\n (light as any).groundColor &&\r\n typeof (light as any).groundColor.set === \"function\"\r\n ) {\r\n (light as any).groundColor.set(groundColor);\r\n }\r\n\r\n // Shadows\r\n const castShadow = el.getAttribute(\"string-3d-cast-shadow\") === \"true\";\r\n if (light.castShadow !== castShadow) {\r\n light.castShadow = castShadow;\r\n }\r\n if (castShadow && light.shadow) {\r\n const bias = el.getAttribute(\"string-3d-shadow-bias\");\r\n if (bias) light.shadow.bias = parseFloat(bias);\r\n\r\n const mapSize = el.getAttribute(\"string-3d-shadow-map-size\");\r\n if (mapSize) {\r\n const size = parseFloat(mapSize);\r\n if (light.shadow.mapSize.width !== size) {\r\n light.shadow.mapSize.width = size;\r\n light.shadow.mapSize.height = size;\r\n }\r\n }\r\n }\r\n\r\n // Target (Directional, Spot)\r\n const targetId = el.getAttribute(\"string-3d-target\");\r\n if (targetId && light.target) {\r\n const targetEl = document.querySelector(`[string-id=\"${targetId}\"]`);\r\n if (targetEl) {\r\n const tRect = targetEl.getBoundingClientRect();\r\n const tCenterX = tRect.left + tRect.width / 2;\r\n const tCenterY = tRect.top + tRect.height / 2;\r\n const tTranslateZ = parseFloat(\r\n getComputedStyle(targetEl).getPropertyValue(\"--translate-z\") || \"0\"\r\n );\r\n const tPos = ctx.camera.screenToWorld(tCenterX, tCenterY, tTranslateZ);\r\n\r\n light.target.position.copy(tPos);\r\n light.target.updateMatrixWorld(true);\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n}\r\n","import { String3DObject } from \"../String3DObject\";\nimport type { SyncContext } from \"./SyncContext\";\nimport type { String3DObjectSyncStrategy } from \"./String3DObjectSyncStrategy\";\n\ntype StyleMap = {\n get?: (prop: string) => any;\n};\n\nexport class MeshSynchronizer implements String3DObjectSyncStrategy {\n static applyVisualProps(el: HTMLElement, object: String3DObject, opacityValue?: number): void {\n const castShadow = el.getAttribute(\"string-3d-cast-shadow\") === \"true\";\n const receiveShadow = el.getAttribute(\"string-3d-receive-shadow\") === \"true\";\n\n const opacity = typeof opacityValue === \"number\" ? opacityValue : NaN;\n\n if (object.object.traverse) {\n object.object.traverse((child: any) => {\n if (child.isMesh) {\n if (child.castShadow !== castShadow) child.castShadow = castShadow;\n if (child.receiveShadow !== receiveShadow) child.receiveShadow = receiveShadow;\n\n if (!isNaN(opacity)) {\n const materials = Array.isArray(child.material) ? child.material : [child.material];\n materials.forEach((mat: any) => {\n if (mat) {\n mat.opacity = opacity;\n mat.transparent = opacity < 1;\n }\n });\n }\n }\n });\n } else if ((object.object as any).isMesh) {\n const mesh = object.object as any;\n if (mesh.castShadow !== castShadow) mesh.castShadow = castShadow;\n if (mesh.receiveShadow !== receiveShadow) mesh.receiveShadow = receiveShadow;\n\n if (!isNaN(opacity)) {\n const materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material];\n materials.forEach((mat: any) => {\n if (mat) {\n mat.opacity = opacity;\n mat.transparent = opacity < 1;\n }\n });\n }\n }\n }\n\n sync(el: HTMLElement, object: String3DObject, ctx: SyncContext, parentData: any): any {\n const styleMap = (el as any).computedStyleMap?.() as StyleMap | undefined;\n let style: CSSStyleDeclaration | null = null;\n const getStyle = () => {\n if (!style) style = getComputedStyle(el);\n return style;\n };\n\n const rect = el.getBoundingClientRect();\n const originalWidth = el.offsetWidth || rect.width;\n const originalHeight = el.offsetHeight || rect.height;\n\n const readNumberStyle = (prop: string, fallback: number): number => {\n const mapValue = styleMap?.get?.(prop);\n if (mapValue !== undefined) {\n if (typeof mapValue === \"number\") return mapValue;\n if (typeof mapValue === \"string\") {\n const parsed = Number.parseFloat(mapValue);\n if (!Number.isNaN(parsed)) return parsed;\n }\n if (mapValue && typeof mapValue === \"object\") {\n const value = (mapValue as any).value;\n if (typeof value === \"number\") return value;\n if (typeof value === \"string\") {\n const parsed = Number.parseFloat(value);\n if (!Number.isNaN(parsed)) return parsed;\n }\n }\n }\n\n const raw = getStyle().getPropertyValue(prop);\n const parsed = Number.parseFloat(raw);\n return Number.isNaN(parsed) ? fallback : parsed;\n };\n\n const translateZ = readNumberStyle(\"--translate-z\", 0);\n const cssScale = readNumberStyle(\"--scale\", 1);\n\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n\n const worldPos = ctx.camera.screenToWorld(centerX, centerY, translateZ);\n object.position = worldPos;\n\n const rotateX = -ctx.engine.degToRad(readNumberStyle(\"--rotate-x\", 0));\n const rotateY = ctx.engine.degToRad(readNumberStyle(\"--rotate-y\", 0));\n const rotateZ = -ctx.engine.degToRad(readNumberStyle(\"--rotate-z\", 0));\n object.rotation = ctx.engine.createEuler(rotateX, rotateY, rotateZ, \"XYZ\");\n\n const targetWidth = originalWidth * cssScale;\n const targetHeight = originalHeight * cssScale;\n const cssScaleZ = readNumberStyle(\"--scale-z\", 1);\n const parentScale = parentData?.scale || 1;\n\n const objectType = object.type;\n let scaleX: number, scaleY: number, scaleZ: number;\n\n switch (objectType) {\n case \"box\":\n case \"sphere\": {\n const uniformSize = Math.min(targetWidth, targetHeight);\n scaleX = uniformSize * parentScale;\n scaleY = uniformSize * parentScale;\n scaleZ = uniformSize * cssScaleZ * parentScale;\n break;\n }\n case \"model\": {\n const bbox = object.getOriginalBoundingBox();\n const size = bbox.getSize(ctx.engine.createVector3());\n const fitMode = (el.getAttribute(\"string-3d-model-fit\") || \"contain\").toLowerCase().trim();\n const modelScaleAttr = parseFloat(el.getAttribute(\"string-3d-model-scale\") || \"1\");\n const modelScale = Number.isFinite(modelScaleAttr) ? modelScaleAttr : 1;\n\n if (size.x > 0 && size.y > 0) {\n const scaleToWidth = targetWidth / size.x;\n const scaleToHeight = targetHeight / size.y;\n const uniformScale =\n fitMode === \"cover\"\n ? Math.max(scaleToWidth, scaleToHeight)\n : Math.min(scaleToWidth, scaleToHeight);\n\n scaleX = uniformScale * modelScale * parentScale;\n scaleY = uniformScale * modelScale * parentScale;\n scaleZ = uniformScale * modelScale * cssScaleZ * parentScale;\n } else {\n const fallbackSize = Math.min(targetWidth, targetHeight);\n scaleX = fallbackSize * modelScale * parentScale;\n scaleY = fallbackSize * modelScale * parentScale;\n scaleZ = fallbackSize * modelScale * cssScaleZ * parentScale;\n }\n break;\n }\n case \"cylinder\": {\n const cylRadius = targetWidth;\n scaleX = cylRadius * parentScale;\n scaleY = targetHeight * parentScale;\n scaleZ = cylRadius * cssScaleZ * parentScale;\n break;\n }\n case \"plane\":\n default:\n scaleX = targetWidth * parentScale;\n scaleY = targetHeight * parentScale;\n scaleZ = Math.min(targetWidth, targetHeight) * 0.5 * cssScaleZ * parentScale;\n break;\n }\n\n object.scale = ctx.engine.createVector3(scaleX, scaleY, scaleZ);\n\n const opacity = readNumberStyle(\"--opacity\", NaN);\n MeshSynchronizer.applyVisualProps(el, object, opacity);\n\n return { scale: cssScale * parentScale };\n }\n}\n","import { String3DCamera } from \"../String3DCamera\";\r\nimport { String3DObject } from \"../String3DObject\";\r\nimport { I3DEngine } from \"../abstractions/I3DEngine\";\r\nimport { GroupSynchronizer } from \"./GroupSynchronizer\";\r\nimport { LightSynchronizer } from \"./LightSynchronizer\";\r\nimport { MeshSynchronizer } from \"./MeshSynchronizer\";\r\nimport type { String3DObjectSyncStrategy } from \"./String3DObjectSyncStrategy\";\r\n\r\nexport class String3DSynchronizer {\r\n private strategies: Map<string, String3DObjectSyncStrategy> = new Map();\r\n\r\n constructor(\r\n public camera: String3DCamera,\r\n public viewportWidth: number,\r\n public viewportHeight: number,\r\n public engine: I3DEngine\r\n ) {\r\n this.strategies.set(\"box\", new MeshSynchronizer());\r\n this.strategies.set(\"sphere\", new MeshSynchronizer());\r\n this.strategies.set(\"plane\", new MeshSynchronizer());\r\n this.strategies.set(\"cylinder\", new MeshSynchronizer());\r\n this.strategies.set(\"model\", new MeshSynchronizer());\r\n this.strategies.set(\"group\", new GroupSynchronizer());\r\n this.strategies.set(\"pointLight\", new LightSynchronizer());\r\n this.strategies.set(\"ambientLight\", new LightSynchronizer());\r\n this.strategies.set(\"directionalLight\", new LightSynchronizer());\r\n this.strategies.set(\"spotLight\", new LightSynchronizer());\r\n this.strategies.set(\"hemisphereLight\", new LightSynchronizer());\r\n }\r\n\r\n public syncElement(el: HTMLElement, object: String3DObject, parentData: any): any {\r\n const strategy = this.strategies.get(object.type);\r\n if (!strategy) {\r\n console.warn(`[String3D Sync] No strategy for type \"${object.type}\"`);\r\n return null;\r\n }\r\n\r\n return strategy.sync(\r\n el,\r\n object,\r\n {\r\n camera: this.camera,\r\n viewportWidth: this.viewportWidth,\r\n viewportHeight: this.viewportHeight,\r\n engine: this.engine,\r\n },\r\n parentData\r\n );\r\n }\r\n\r\n public updateViewportSize(width: number, height: number): void {\r\n this.viewportWidth = width;\r\n this.viewportHeight = height;\r\n }\r\n}\r\n","export type TransformWorkerInput = {\n id: string;\n type: string;\n rectLeft: number;\n rectTop: number;\n rectWidth: number;\n rectHeight: number;\n translateZ: number;\n scale: number;\n scaleZ: number;\n rotateX: number;\n rotateY: number;\n rotateZ: number;\n parentScale: number;\n modelSizeX?: number;\n modelSizeY?: number;\n modelScale?: number;\n fitMode?: string;\n};\n\nexport type TransformWorkerCamera = {\n mode: \"orthographic\" | \"perspective\";\n width: number;\n height: number;\n cameraZ: number;\n fov: number;\n aspect: number;\n};\n\nexport type TransformWorkerResult = {\n id: string;\n posX: number;\n posY: number;\n posZ: number;\n rotX: number;\n rotY: number;\n rotZ: number;\n scaleX: number;\n scaleY: number;\n scaleZ: number;\n};\n\nexport type TransformWorkerJobResult = {\n frameId: number;\n results: TransformWorkerResult[];\n};\n\nexport type TransformWorkerOptions = {\n wasmUrl?: string;\n};\n\nconst WORKER_SOURCE = `\nlet wasm = null;\nlet wasmReady = false;\n\nfunction degToRad(deg) {\n return (deg * Math.PI) / 180;\n}\n\nfunction computeTransform(item, camera) {\n const centerX = item.rectLeft + item.rectWidth / 2;\n const centerY = item.rectTop + item.rectHeight / 2;\n\n let posX = 0;\n let posY = 0;\n let posZ = item.translateZ;\n\n if (camera.mode === \"orthographic\") {\n posX = centerX - camera.width / 2;\n posY = -(centerY - camera.height / 2);\n } else {\n const fov = degToRad(camera.fov);\n const distance = Math.abs(item.translateZ - camera.cameraZ);\n const height = 2 * Math.tan(fov / 2) * distance;\n const width = height * camera.aspect;\n const normalizedX = centerX / camera.width;\n const normalizedY = centerY / camera.height;\n posX = (normalizedX - 0.5) * width;\n posY = -(normalizedY - 0.5) * height;\n }\n\n const rotX = -degToRad(item.rotateX);\n const rotY = degToRad(item.rotateY);\n const rotZ = -degToRad(item.rotateZ);\n\n let scaleX = 1;\n let scaleY = 1;\n let scaleZ = 1;\n\n if (item.type === \"group\") {\n scaleX = item.scale;\n scaleY = item.scale;\n scaleZ = item.scale;\n } else {\n const targetWidth = item.rectWidth * item.scale;\n const targetHeight = item.rectHeight * item.scale;\n const parentScale = item.parentScale || 1;\n const cssScaleZ = item.scaleZ || 1;\n\n if (item.type === \"box\" || item.type === \"sphere\") {\n const uniformSize = Math.min(targetWidth, targetHeight);\n scaleX = uniformSize * parentScale;\n scaleY = uniformSize * parentScale;\n scaleZ = uniformSize * cssScaleZ * parentScale;\n } else if (item.type === \"model\") {\n const sizeX = item.modelSizeX || 0;\n const sizeY = item.modelSizeY || 0;\n const fitMode = (item.fitMode || \"contain\").toLowerCase().trim();\n const modelScale = Number.isFinite(item.modelScale) ? item.modelScale : 1;\n\n if (sizeX > 0 && sizeY > 0) {\n const scaleToWidth = targetWidth / sizeX;\n const scaleToHeight = targetHeight / sizeY;\n const uniformScale = fitMode === \"cover\"\n ? Math.max(scaleToWidth, scaleToHeight)\n : Math.min(scaleToWidth, scaleToHeight);\n scaleX = uniformScale * modelScale * parentScale;\n scaleY = uniformScale * modelScale * parentScale;\n scaleZ = uniformScale * modelScale * cssScaleZ * parentScale;\n } else {\n const fallbackSize = Math.min(targetWidth, targetHeight);\n scaleX = fallbackSize * modelScale * parentScale;\n scaleY = fallbackSize * modelScale * parentScale;\n scaleZ = fallbackSize * modelScale * cssScaleZ * parentScale;\n }\n } else if (item.type === \"cylinder\") {\n const cylRadius = targetWidth;\n scaleX = cylRadius * parentScale;\n scaleY = targetHeight * parentScale;\n scaleZ = cylRadius * cssScaleZ * parentScale;\n } else {\n scaleX = targetWidth * parentScale;\n scaleY = targetHeight * parentScale;\n scaleZ = Math.min(targetWidth, targetHeight) * 0.5 * cssScaleZ * parentScale;\n }\n }\n\n return {\n id: item.id,\n posX,\n posY,\n posZ,\n rotX,\n rotY,\n rotZ,\n scaleX,\n scaleY,\n scaleZ,\n };\n}\n\nasync function initWasm(url) {\n try {\n const res = await fetch(url);\n const bytes = await res.arrayBuffer();\n const mod = await WebAssembly.instantiate(bytes, {});\n wasm = mod.instance;\n wasmReady = true;\n } catch (error) {\n wasm = null;\n wasmReady = false;\n }\n}\n\nself.onmessage = async (event) => {\n const data = event.data || {};\n if (data.type === \"init\") {\n if (data.wasmUrl) {\n await initWasm(data.wasmUrl);\n }\n self.postMessage({ type: \"ready\", wasmReady });\n return;\n }\n\n if (data.type === \"compute\") {\n const items = data.items || [];\n const camera = data.camera || {};\n const results = new Array(items.length);\n for (let i = 0; i < items.length; i += 1) {\n results[i] = computeTransform(items[i], camera);\n }\n self.postMessage({ type: \"result\", frameId: data.frameId, results });\n }\n};\n`;\n\nexport class TransformWorkerClient {\n private worker: Worker | null = null;\n private ready = false;\n private lastResult: TransformWorkerJobResult | null = null;\n private pending = false;\n\n constructor(options: TransformWorkerOptions = {}) {\n if (typeof Worker === \"undefined\") return;\n const blob = new Blob([WORKER_SOURCE], { type: \"text/javascript\" });\n this.worker = new Worker(URL.createObjectURL(blob));\n this.worker.onmessage = (event) => {\n const data = event.data || {};\n if (data.type === \"ready\") {\n this.ready = true;\n return;\n }\n if (data.type === \"result\") {\n this.lastResult = {\n frameId: typeof data.frameId === \"number\" ? data.frameId : 0,\n results: data.results || [],\n };\n this.pending = false;\n }\n };\n this.worker.postMessage({ type: \"init\", wasmUrl: options.wasmUrl });\n }\n\n public isReady(): boolean {\n return this.ready;\n }\n\n public isPending(): boolean {\n return this.pending;\n }\n\n public submit(\n items: TransformWorkerInput[],\n camera: TransformWorkerCamera,\n frameId: number\n ): void {\n if (!this.worker || !this.ready || this.pending) return;\n this.pending = true;\n this.worker.postMessage({\n type: \"compute\",\n frameId,\n items,\n camera,\n });\n }\n\n public takeLastResult(): TransformWorkerJobResult | null {\n const result = this.lastResult;\n this.lastResult = null;\n return result;\n }\n\n public destroy(): void {\n this.worker?.terminate();\n this.worker = null;\n this.ready = false;\n this.pending = false;\n this.lastResult = null;\n }\n}\n","import {\r\n I3DEngine,\r\n I3DVector3,\r\n I3DVector2,\r\n I3DQuaternion,\r\n I3DEuler,\r\n I3DMatrix4,\r\n I3DBox3,\r\n I3DScene,\r\n I3DRenderer,\r\n I3DPerspectiveCamera,\r\n I3DOrthographicCamera,\r\n I3DObject,\r\n I3DMesh,\r\n I3DGeometry,\r\n I3DMaterial,\r\n I3DLight,\r\n I3DTextureLoader,\r\n I3DModelLoader,\r\n} from \"../core/abstractions/I3DEngine\";\r\nimport { I3DEngineProvider } from \"../core/abstractions/I3DEngineProvider\";\r\n\r\nexport class ThreeJSEngine implements I3DEngine {\r\n private THREE: any;\r\n private loaders: Record<string, any>;\r\n\r\n constructor(THREE: any, loaders: Record<string, any> = {}) {\r\n this.THREE = THREE;\r\n this.loaders = loaders;\r\n }\r\n\r\n createVector3(x = 0, y = 0, z = 0): I3DVector3 {\r\n return new this.THREE.Vector3(x, y, z);\r\n }\r\n\r\n createVector2(x = 0, y = 0): I3DVector2 {\r\n return new this.THREE.Vector2(x, y);\r\n }\r\n\r\n createQuaternion(x = 0, y = 0, z = 0, w = 1): I3DQuaternion {\r\n return new this.THREE.Quaternion(x, y, z, w);\r\n }\r\n\r\n createEuler(x = 0, y = 0, z = 0, order = \"XYZ\"): I3DEuler {\r\n return new this.THREE.Euler(x, y, z, order);\r\n }\r\n\r\n createMatrix4(): I3DMatrix4 {\r\n return new this.THREE.Matrix4();\r\n }\r\n\r\n createBox3(min?: I3DVector3, max?: I3DVector3): I3DBox3 {\r\n return new this.THREE.Box3(min, max);\r\n }\r\n\r\n createScene(): I3DScene {\r\n return new this.THREE.Scene();\r\n }\r\n\r\n createRenderer(options?: {\r\n antialias?: boolean;\r\n alpha?: boolean;\r\n logarithmicDepthBuffer?: boolean;\r\n }): I3DRenderer {\r\n const renderer = new this.THREE.WebGLRenderer(options);\r\n renderer.outputEncoding = this.THREE.sRGBEncoding;\r\n return renderer;\r\n }\r\n\r\n createPerspectiveCamera(fov = 45, aspect = 1, near = 0.1, far = 2000): I3DPerspectiveCamera {\r\n return new this.THREE.PerspectiveCamera(fov, aspect, near, far);\r\n }\r\n\r\n createOrthographicCamera(\r\n left: number,\r\n right: number,\r\n top: number,\r\n bottom: number,\r\n near = 0.1,\r\n far = 10000\r\n ): I3DOrthographicCamera {\r\n return new this.THREE.OrthographicCamera(left, right, top, bottom, near, far);\r\n }\r\n\r\n createGroup(): I3DObject {\r\n return new this.THREE.Group();\r\n }\r\n\r\n createMesh(geometry: I3DGeometry, material: I3DMaterial): I3DMesh {\r\n return new this.THREE.Mesh(geometry, material);\r\n }\r\n\r\n createBoxGeometry(width: number, height: number, depth: number): I3DGeometry {\r\n return new this.THREE.BoxGeometry(width, height, depth);\r\n }\r\n\r\n createSphereGeometry(radius: number, widthSegments = 32, heightSegments = 32): I3DGeometry {\r\n return new this.THREE.SphereGeometry(radius, widthSegments, heightSegments);\r\n }\r\n\r\n createPlaneGeometry(width: number, height: number): I3DGeometry {\r\n return new this.THREE.PlaneGeometry(width, height);\r\n }\r\n\r\n createCylinderGeometry(\r\n radiusTop: number,\r\n radiusBottom: number,\r\n height: number,\r\n segments = 32\r\n ): I3DGeometry {\r\n return new this.THREE.CylinderGeometry(radiusTop, radiusBottom, height, segments);\r\n }\r\n\r\n createMeshBasicMaterial(params?: any): I3DMaterial {\r\n return new this.THREE.MeshBasicMaterial(params);\r\n }\r\n\r\n createMeshStandardMaterial(params?: any): I3DMaterial {\r\n return new this.THREE.MeshStandardMaterial(params);\r\n }\r\n\r\n createPointLight(color?: string | number, intensity = 1, distance = 0, decay = 2): I3DLight {\r\n return new this.THREE.PointLight(color, intensity, distance, decay);\r\n }\r\n\r\n createSpotLight(\r\n color?: string | number,\r\n intensity = 1,\r\n distance = 0,\r\n angle = Math.PI / 3,\r\n penumbra = 0,\r\n decay = 1\r\n ): I3DLight {\r\n return new this.THREE.SpotLight(color, intensity, distance, angle, penumbra, decay);\r\n }\r\n\r\n createHemisphereLight(\r\n skyColor?: string | number,\r\n groundColor?: string | number,\r\n intensity = 1\r\n ): I3DLight {\r\n return new this.THREE.HemisphereLight(skyColor, groundColor, intensity);\r\n }\r\n\r\n createAmbientLight(color?: string | number, intensity = 1): I3DLight {\r\n return new this.THREE.AmbientLight(color, intensity);\r\n }\r\n\r\n createDirectionalLight(color?: string | number, intensity = 1): I3DLight {\r\n return new this.THREE.DirectionalLight(color, intensity);\r\n }\r\n\r\n createTextureLoader(): I3DTextureLoader {\r\n return new this.THREE.TextureLoader();\r\n }\r\n\r\n createModelLoader(type: string): I3DModelLoader {\r\n const LoaderClass = this.loaders[type];\r\n if (!LoaderClass) {\r\n throw new Error(`[ThreeJSEngine] Model loader \"${type}\" not registered`);\r\n }\r\n return new LoaderClass();\r\n }\r\n\r\n degToRad(degrees: number): number {\r\n return this.THREE.MathUtils.degToRad(degrees);\r\n }\r\n\r\n radToDeg(radians: number): number {\r\n return this.THREE.MathUtils.radToDeg(radians);\r\n }\r\n\r\n computeBoundingBoxRecursively(object: I3DObject): I3DBox3 {\r\n const boundingBox = new this.THREE.Box3();\r\n let hasBox = false;\r\n\r\n if (object.traverse) {\r\n object.traverse((child: any) => {\r\n if (!child.visible) return;\r\n if (child.geometry) {\r\n if (typeof child.geometry.computeBoundingBox === \"function\") {\r\n child.geometry.computeBoundingBox();\r\n }\r\n const box = child.geometry.boundingBox;\r\n if (box) {\r\n const childBox = box.clone().applyMatrix4(child.matrixWorld);\r\n boundingBox.union(childBox);\r\n hasBox = true;\r\n }\r\n }\r\n });\r\n }\r\n\r\n return hasBox ? boundingBox : new this.THREE.Box3();\r\n }\r\n}\r\n\r\nexport class ThreeJSProvider implements I3DEngineProvider {\r\n private engine: ThreeJSEngine;\r\n\r\n constructor(THREE: any, loaders: Record<string, any> = {}) {\r\n this.engine = new ThreeJSEngine(THREE, loaders);\r\n }\r\n\r\n getEngine(): I3DEngine {\r\n return this.engine;\r\n }\r\n\r\n getName(): string {\r\n return \"Three.js\";\r\n }\r\n}\r\n"],"mappings":"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","names":["index_exports","__export","String3D","String3DCamera","String3DObject","String3DRenderer","String3DScene","String3DSynchronizer","ThreeJSEngine","ThreeJSProvider","__toCommonJS","import_string_tune","String3DCamera","engine","mode","fov","near","far","width","height","ortho","x","y","z","screenX","screenY","normalizedX","normalizedY","distance","viewportHeight","roundedZ","scale","String3DRenderer","container","engine","width","height","scene","camera","String3DObject","id","type","object","engine","options","child","originalScale","matrix","pos","quat","scale","position","quaternion","euler","value","mat","texture","material","geometry","anyObj","childMat","String3DScene","engine","options","id","obj","object","type","element","onAdd","added3DObject","parentId","group","String3DObject","kind","color","intensity","light","distance","decay","angle","penumbra","groundColor","bias","mapSize","mesh","castShadow","receiveShadow","geometry","material","widthSegments","heightSegments","segments","modelPath","loaderType","loader","shouldCenter","gltf","root","overrideMaterial","child","xhr","error","bbox","center","box","attr","colorRaw","opacity","metalness","roughness","params","mapSrc","normalMapSrc","roughnessMapSrc","metalnessMapSrc","aoMapSrc","flipY","colorSpace","src","texture","value","normalized","baseRaw","base","mappingRaw","mapping","manager","url","mapped","GroupSynchronizer","el","object","ctx","parentData","rect","centerX","centerY","styleMap","style","getStyle","readNumberStyle","prop","fallback","mapValue","parsed","value","raw","translateZ","position","scale","rotateX","rotateY","rotateZ","LightSynchronizer","el","object","ctx","parentData","rect","centerX","centerY","translateZ","position","light","color","intensity","distance","decay","angle","penumbra","groundColor","castShadow","bias","mapSize","size","targetId","targetEl","tRect","tCenterX","tCenterY","tTranslateZ","tPos","MeshSynchronizer","_MeshSynchronizer","el","object","opacityValue","castShadow","receiveShadow","opacity","child","mat","mesh","ctx","parentData","styleMap","style","getStyle","rect","originalWidth","originalHeight","readNumberStyle","prop","fallback","mapValue","parsed","value","raw","translateZ","cssScale","centerX","centerY","worldPos","rotateX","rotateY","rotateZ","targetWidth","targetHeight","cssScaleZ","parentScale","objectType","scaleX","scaleY","scaleZ","uniformSize","size","fitMode","modelScaleAttr","modelScale","scaleToWidth","scaleToHeight","uniformScale","fallbackSize","cylRadius","String3DSynchronizer","camera","viewportWidth","viewportHeight","engine","MeshSynchronizer","GroupSynchronizer","LightSynchronizer","el","object","parentData","strategy","width","height","WORKER_SOURCE","TransformWorkerClient","options","blob","event","data","items","camera","frameId","result","_String3D","context","provider","object","result","globalId","element","attributes","parentElement","parentId","String3DRenderer","String3DCamera","modelLoader","modelLoaderFactory","String3DScene","String3DSynchronizer","TransformWorkerClient","shouldUseDirtySync","shouldUseWorker","key","fallback","error","engine","type","loaderType","existing","container","el","data","workerResults","dirtySet","forceSync","worker","inputs","obj","frameId","parentData","shouldSync","nextParentData","cached","forceChildren","child","style","css","name","initialValue","entries","entry","mutations","mutation","prop","mapValue","parsed","value","raw","rect","layoutWidth","layoutHeight","translateZ","scale","scaleZ","rotateX","rotateY","rotateZ","opacity","MeshSynchronizer","modelSizeX","modelSizeY","modelScale","fitMode","size","modelScaleAttr","returnScale","results","String3D","ThreeJSEngine","THREE","loaders","x","y","z","w","order","min","max","options","renderer","fov","aspect","near","far","left","right","top","bottom","geometry","material","width","height","depth","radius","widthSegments","heightSegments","radiusTop","radiusBottom","segments","params","color","intensity","distance","decay","angle","penumbra","skyColor","groundColor","type","LoaderClass","degrees","radians","object","boundingBox","hasBox","child","box","childBox","ThreeJSProvider"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/modules/String3D.ts","../src/core/String3DCamera.ts","../src/core/filters/String3DCustomFilter.ts","../src/core/filters/String3DFilterPipeline.ts","../src/core/String3DRenderer.ts","../src/core/String3DObject.ts","../src/modules/string3d/styleUtils.ts","../src/core/materials/String3DCustomMaterial.ts","../src/core/materials/MaterialFactory.ts","../src/core/String3DScene.ts","../src/core/synchronizer/StyleBundleCache.ts","../src/core/synchronizer/GroupSynchronizer.ts","../src/core/synchronizer/LightSynchronizer.ts","../src/core/synchronizer/MeshSynchronizer.ts","../src/core/synchronizer/ParticlesSynchronizer.ts","../src/core/text/String3DFontRegistry.ts","../src/core/text/FontConverter.ts","../src/core/synchronizer/TextSynchronizer.ts","../src/core/synchronizer/String3DSynchronizer.ts","../src/modules/string3d/DirtySyncManager.ts","../src/modules/string3d/FilterController.ts","../src/adapters/ThreeJSMaterialFactory.ts","../src/adapters/ThreeJSProvider.ts"],"sourcesContent":["export { String3D } from \"./modules/String3D\";\r\nexport type { String3DOptions } from \"./modules/String3D\";\r\n\r\nexport type {\r\n I3DEngine,\r\n I3DVector3,\r\n I3DVector2,\r\n I3DQuaternion,\r\n I3DEuler,\r\n I3DMatrix4,\r\n I3DBox3,\r\n I3DObject,\r\n I3DMesh,\r\n I3DGeometry,\r\n I3DMaterial,\r\n I3DRenderTarget,\r\n I3DLight,\r\n I3DParticleSystem,\r\n ParticleSystemConfig,\r\n ParticleMode,\r\n I3DCamera,\r\n I3DPerspectiveCamera,\r\n I3DOrthographicCamera,\r\n I3DScene,\r\n I3DRenderer,\r\n I3DTextureLoader,\r\n I3DModelLoader,\r\n} from \"./core/abstractions/I3DEngine\";\r\n\r\nexport type { CameraMode } from \"./core/String3DCamera\";\r\nexport type { I3DEngineProvider } from \"./core/abstractions/I3DEngineProvider\";\r\n\r\nexport { String3DCamera } from \"./core/String3DCamera\";\r\nexport { String3DRenderer } from \"./core/String3DRenderer\";\r\nexport { String3DScene } from \"./core/String3DScene\";\r\nexport { String3DObject } from \"./core/String3DObject\";\r\nexport { String3DSynchronizer } from \"./core/synchronizer/String3DSynchronizer\";\r\nexport {\r\n String3DCustomFilterRegistry,\r\n type String3DCustomFilterDefinition,\r\n} from \"./core/filters/String3DCustomFilter\";\r\n\r\nexport {\r\n String3DCustomMaterialRegistry,\r\n type String3DCustomMaterialDefinition,\r\n type UniformType,\r\n type UniformDefinition,\r\n type ShaderInjection,\r\n type ShaderInjectionPoint,\r\n type MaterialBlendMode,\r\n type MaterialSide,\r\n type IMaterialInstance,\r\n type IMaterialFactory,\r\n} from \"./core/materials\";\r\nexport {\r\n String3DFontRegistry,\r\n type String3DFontEntry,\r\n FontConverter,\r\n type FontData,\r\n type FontSource,\r\n} from \"./core/text\";\r\n\r\nexport { ThreeJSProvider, ThreeJSEngine } from \"./adapters/ThreeJSProvider\";\r\nexport { ThreeJSMaterialFactory } from \"./adapters/ThreeJSMaterialFactory\";\r\n","import { StringModule } from \"@fiddle-digital/string-tune\";\r\nimport { StringObject } from \"@fiddle-digital/string-tune\";\r\nimport { StringData } from \"@fiddle-digital/string-tune\";\r\nimport { StringContext } from \"@fiddle-digital/string-tune\";\r\nimport { String3DCamera } from \"../core/String3DCamera\";\r\nimport { String3DRenderer } from \"../core/String3DRenderer\";\r\nimport { String3DScene } from \"../core/String3DScene\";\r\nimport { String3DSynchronizer } from \"../core/synchronizer/String3DSynchronizer\";\r\nimport { I3DEngineProvider } from \"../core/abstractions/I3DEngineProvider\";\r\nimport { I3DEngine, I3DModelLoader } from \"../core/abstractions/I3DEngine\";\r\nimport { String3DObject } from \"../core/String3DObject\";\r\nimport { DirtySyncManager } from \"./string3d/DirtySyncManager\";\nimport { FilterController } from \"./string3d/FilterController\";\nimport { StyleReader } from \"./string3d/styleUtils\";\nimport { String3DFontRegistry } from \"../core/text\";\n\r\nexport interface String3DOptions {\r\n hideHTML?: boolean;\r\n container?: string | HTMLElement;\r\n zIndex?: number;\r\n modelLoaderType?: string;\r\n modelLoader?: I3DModelLoader;\r\n modelLoaderFactory?: (engine: I3DEngine, type?: string) => I3DModelLoader;\r\n useDirtySync?: boolean;\r\n styleReadIntervalMs?: number;\r\n layoutReadIntervalMs?: number;\r\n}\r\n\r\nexport class String3D extends StringModule {\n private static provider: I3DEngineProvider | null = null;\n\n private renderer: String3DRenderer | null = null;\n private camera: String3DCamera | null = null;\r\n private scene: String3DScene | null = null;\r\n private synchronizer: String3DSynchronizer | null = null;\r\n private engine: I3DEngine | null = null;\r\n private canvasContainer: HTMLElement | null = null;\r\n private isLoading: Map<string, boolean> = new Map();\r\n private options: String3DOptions;\r\n private useDirtySync = false;\r\n private dirtySyncManager: DirtySyncManager;\r\n private lastSyncData: WeakMap<String3DObject, { scale: number }> = new WeakMap();\r\n private filterController: FilterController;\r\n\r\n public static setProvider(provider: I3DEngineProvider): void {\n String3D.provider = provider;\n }\n\n public static registerFont(\n name: string,\n url: string,\n options: { default?: boolean } = {}\n ): void {\n String3DFontRegistry.register(name, url);\n if (options.default) {\n String3DFontRegistry.setDefault(name);\n }\n }\n\n public static setDefaultFont(name: string): void {\n String3DFontRegistry.setDefault(name);\n }\n\r\n constructor(context: StringContext) {\r\n super(context);\r\n this.htmlKey = \"3d\";\r\n this.options = this.buildOptionsFromSettings();\r\n this.dirtySyncManager = new DirtySyncManager([\r\n \"style\",\r\n \"class\",\r\n \"string-3d\",\r\n \"string-3d-model-fit\",\r\n \"string-3d-model-scale\",\r\n ]);\r\n this.filterController = new FilterController((value) =>\r\n this.tools.easingFunction.process({ easing: value })\r\n );\r\n\r\n this.attributesToMap = [\r\n ...this.attributesToMap,\r\n { key: \"3d\", type: \"string\", fallback: \"box\" },\r\n { key: \"3d-model\", type: \"string\", fallback: \"\" },\r\n { key: \"3d-segments\", type: \"number\", fallback: 32 },\r\n { key: \"3d-segments-width\", type: \"number\", fallback: 32 },\r\n { key: \"3d-segments-height\", type: \"number\", fallback: 32 },\r\n { key: \"3d-model-loader\", type: \"string\", fallback: \"\" },\r\n { key: \"3d-model-scale\", type: \"number\", fallback: 1 },\r\n { key: \"3d-model-center\", type: \"boolean\", fallback: false },\r\n { key: \"3d-model-fit\", type: \"string\", fallback: \"contain\" },\r\n ];\r\n }\r\n\r\n override canConnect(object: StringObject): boolean {\r\n const result = super.canConnect(object);\r\n\r\n return result;\r\n }\r\n\r\n override initializeObject(\r\n globalId: number,\r\n object: StringObject,\r\n element: HTMLElement,\r\n attributes: Record<string, any>\r\n ): void {\r\n super.initializeObject(globalId, object, element, attributes);\r\n\r\n object.setProperty(\"parentId\", null);\r\n const parentElement = element.parentElement?.closest(\r\n '[string-3d=\"group\"]'\r\n ) as HTMLElement | null;\r\n if (parentElement) {\r\n const parentId = parentElement.getAttribute(\"string-id\");\r\n if (parentId) {\r\n object.setProperty(\"parentId\", parentId);\r\n object.setProperty(\"parent\", parentElement);\r\n }\r\n }\r\n }\r\n\r\n override onResize(): void {\r\n if (this.renderer && this.camera && this.synchronizer) {\r\n this.renderer.resize(this.camera);\r\n this.synchronizer.updateViewportSize(this.renderer.width, this.renderer.height);\r\n this.camera.clearScaleCache();\r\n if (this.useDirtySync) {\r\n this.dirtySyncManager.markAllDirty();\r\n }\r\n }\r\n }\r\n\r\n override onInit(): void {\r\n this.options = this.buildOptionsFromSettings();\r\n if (!String3D.provider) {\r\n console.error(\"[String3D] No provider set. Call String3D.setProvider() before use.\");\r\n return;\r\n }\r\n\r\n this.engine = String3D.provider.getEngine();\r\n this.canvasContainer = this.createOrGetContainer();\r\n this.registerTypedProperties();\r\n this.injectCSS();\r\n this.useDirtySync = !!this.options.useDirtySync;\r\n if (this.useDirtySync) {\r\n this.dirtySyncManager.enable();\r\n }\r\n\r\n this.renderer = new String3DRenderer(this.canvasContainer, this.engine);\r\n this.renderer.attach();\r\n\r\n this.camera = new String3DCamera(this.engine, \"orthographic\");\r\n this.camera.setPosition(0, 0, 1000);\r\n this.camera.resize(this.renderer.width, this.renderer.height);\r\n\r\n const modelLoader = this.resolveModelLoader();\r\n const modelLoaderFactory = this.resolveModelLoaderFactory();\r\n this.scene = new String3DScene(this.engine, {\r\n modelLoader,\r\n modelLoaderFactory,\r\n });\r\n this.scene.getScene().add(this.camera.camera);\r\n\r\n this.synchronizer = new String3DSynchronizer(\r\n this.camera,\r\n this.renderer.width,\r\n this.renderer.height,\r\n this.engine\r\n );\r\n this.synchronizer.setSyncOptions({\r\n styleReadIntervalMs: this.options.styleReadIntervalMs,\r\n layoutReadIntervalMs: this.options.layoutReadIntervalMs,\r\n });\r\n\r\n console.info(`[String3D] Initialized with: ${String3D.provider.getName()}`);\r\n }\r\n\r\n override onSettingsChange(): void {\r\n this.options = this.buildOptionsFromSettings();\r\n const shouldUseDirtySync = !!this.options.useDirtySync;\r\n if (shouldUseDirtySync && !this.useDirtySync) {\r\n this.useDirtySync = true;\r\n this.dirtySyncManager.enable();\r\n if (this.scene) {\r\n this.dirtySyncManager.observeScene(this.scene.rootObjects);\r\n }\r\n this.dirtySyncManager.markAllDirty();\r\n } else if (!shouldUseDirtySync && this.useDirtySync) {\r\n this.useDirtySync = false;\r\n this.dirtySyncManager.disable();\r\n }\r\n\r\n this.synchronizer?.setSyncOptions({\r\n styleReadIntervalMs: this.options.styleReadIntervalMs,\r\n layoutReadIntervalMs: this.options.layoutReadIntervalMs,\r\n });\r\n }\r\n\r\n private buildOptionsFromSettings(): String3DOptions {\r\n return {\r\n hideHTML: this.getSettingValue(\"hideHTML\", false),\r\n container: this.getSettingValue(\"container\", undefined),\r\n zIndex: this.getSettingValue(\"zIndex\", 1),\r\n modelLoaderType: this.getSettingValue(\"modelLoaderType\", undefined),\r\n modelLoader: this.getSettingValue(\"modelLoader\", undefined),\r\n modelLoaderFactory: this.getSettingValue(\"modelLoaderFactory\", undefined),\r\n useDirtySync: this.getSettingValue(\"useDirtySync\", false),\r\n styleReadIntervalMs: this.getSettingValue(\"styleReadIntervalMs\", 0),\r\n layoutReadIntervalMs: this.getSettingValue(\"layoutReadIntervalMs\", 0),\r\n };\r\n }\r\n\r\n private getSettingValue<T>(key: string, fallback: T): T {\r\n if (!this.settings || !(key in this.settings)) return fallback;\r\n return this.settings[key] as T;\r\n }\r\n\r\n private resolveModelLoader(): I3DModelLoader | undefined {\r\n if (!this.engine) return undefined;\r\n if (this.options.modelLoader) return this.options.modelLoader;\r\n if (this.options.modelLoaderFactory) return undefined;\r\n if (this.options.modelLoaderType) {\r\n try {\r\n return this.engine.createModelLoader(this.options.modelLoaderType);\r\n } catch (error) {\r\n console.warn(\"[String3D] Failed to create model loader:\", error);\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n private resolveModelLoaderFactory():\r\n | ((engine: I3DEngine, type?: string) => I3DModelLoader)\r\n | undefined {\r\n if (!this.engine) return undefined;\r\n if (this.options.modelLoaderFactory) return this.options.modelLoaderFactory;\r\n if (this.options.modelLoaderType) {\r\n return (engine: I3DEngine, type?: string) => {\r\n const loaderType = type || this.options.modelLoaderType;\r\n if (!loaderType) {\r\n throw new Error(\"[String3D] Model loader type not provided\");\r\n }\r\n return engine.createModelLoader(loaderType);\r\n };\r\n }\r\n return undefined;\r\n }\r\n\r\n private createOrGetContainer(): HTMLElement {\r\n if (this.options.container instanceof HTMLElement) {\r\n this.applyContainerStyles(this.options.container);\r\n return this.options.container;\r\n }\r\n\r\n if (typeof this.options.container === \"string\") {\r\n const existing = document.getElementById(this.options.container);\r\n if (existing) {\r\n this.applyContainerStyles(existing);\r\n return existing;\r\n }\r\n }\r\n\r\n const container = document.createElement(\"div\");\r\n container.id = \"string-3d-canvas\";\r\n this.applyContainerStyles(container);\r\n document.body.insertBefore(container, document.body.firstChild);\r\n return container;\r\n }\r\n\r\n private applyContainerStyles(el: HTMLElement): void {\r\n Object.assign(el.style, {\r\n position: \"fixed\",\r\n left: \"0\",\r\n top: \"0\",\r\n width: \"100vw\",\r\n height: \"100lvh\",\r\n zIndex: String(this.options.zIndex),\r\n pointerEvents: \"none\",\r\n });\r\n }\r\n\r\n override onObjectConnected(object: StringObject): void {\r\n if (this.isLoading.has(object.id) || !this.scene) return;\r\n this.isLoading.set(object.id, true);\r\n\r\n this.scene.createFromElement(object);\r\n\r\n if (this.useDirtySync && object.htmlElement) {\r\n this.dirtySyncManager.observeElement(object.htmlElement);\r\n this.dirtySyncManager.markDirty(object.htmlElement);\r\n }\r\n\r\n if (this.options.hideHTML && object.htmlElement) {\r\n object.htmlElement.style.opacity = \"0\";\r\n object.htmlElement.style.pointerEvents = \"none\";\r\n }\r\n }\r\n\r\n override onFrame(data: StringData): void {\r\n if (!this.renderer || !this.scene || !this.camera || !this.synchronizer) return;\r\n\r\n const dirtySet = this.useDirtySync ? this.dirtySyncManager.getDirtySet() : null;\r\n const forceSync = !dirtySet || dirtySet.size === 0;\r\n\r\n this.batchReadLayouts(this.scene.rootObjects, forceSync, dirtySet);\r\n\r\n this.scene.rootObjects.forEach((obj) => {\r\n this.syncRecursive(obj.el, obj, { scale: 1 }, forceSync, dirtySet);\r\n });\r\n\r\n const filterTargets = this.filterController.collectTargets(\r\n this.scene.rootObjects,\r\n performance.now(),\r\n this.useDirtySync,\r\n dirtySet\r\n );\r\n this.renderer!.render(this.scene!, this.camera!, filterTargets);\r\n\r\n if (this.useDirtySync) {\r\n this.dirtySyncManager.clearDirty();\r\n }\r\n }\r\n\r\n private batchReadLayouts(\r\n rootObjects: String3DObject[],\r\n forceSync: boolean,\r\n dirtySet: Set<HTMLElement> | null\r\n ): void {\r\n const walk = (obj: String3DObject): void => {\r\n if (obj.el) {\r\n const shouldSync = forceSync || !dirtySet || dirtySet.has(obj.el);\r\n if (shouldSync) {\r\n const rect = obj.el.getBoundingClientRect();\r\n const width = obj.el.offsetWidth || rect.width;\r\n const height = obj.el.offsetHeight || rect.height;\r\n (obj.el as any).__layoutCache = { rect, width, height };\r\n }\r\n }\r\n obj.children.forEach(walk);\r\n };\r\n rootObjects.forEach(walk);\r\n }\r\n\r\n private syncRecursive(\n el: HTMLElement | undefined,\n object: String3DObject,\n parentData: any,\n forceSync: boolean,\n dirtySet: Set<HTMLElement> | null\n ): void {\n if (!this.synchronizer || !el) return;\n const shouldSync =\n object.type === \"particles\" || object.type === \"text\" || forceSync || !dirtySet || dirtySet.has(el);\n let nextParentData = parentData;\r\n\r\n if (shouldSync) {\r\n const data = this.synchronizer.syncElement(el, object, parentData, {\r\n dirtySet,\r\n forceSync,\r\n });\r\n if (data && typeof data.scale === \"number\") {\r\n this.lastSyncData.set(object, data);\r\n nextParentData = data;\r\n }\r\n } else {\r\n const cached = this.lastSyncData.get(object);\r\n if (cached) {\r\n nextParentData = cached;\r\n }\r\n }\r\n\r\n const forceChildren = forceSync || shouldSync;\r\n object.children.forEach((child) =>\r\n this.syncRecursive(child.el, child, nextParentData, forceChildren, dirtySet)\r\n );\r\n }\r\n\r\n private injectCSS(): void {\r\n if (document.getElementById(\"string-3d-styles\")) return;\r\n\r\n const style = document.createElement(\"style\");\r\n style.id = \"string-3d-styles\";\r\n style.textContent = `\r\n @property --translate-x { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --translate-y { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --translate-z { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --rotate-x { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --rotate-y { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --rotate-z { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --scale { syntax: \"<number>\"; inherits: false; initial-value: 1; }\r\n @property --scale-x { syntax: \"<number>\"; inherits: false; initial-value: 1; }\r\n @property --scale-y { syntax: \"<number>\"; inherits: false; initial-value: 1; }\r\n @property --scale-z { syntax: \"<number>\"; inherits: false; initial-value: 1; }\r\n @property --opacity { syntax: \"<number>\"; inherits: false; initial-value: 1; }\r\n @property --filter { syntax: \"*\"; inherits: false; initial-value: none; }\r\n @property --light-color { syntax: \"<color>\"; inherits: false; initial-value: #ffffff; }\r\n @property --light-intensity { syntax: \"<number>\"; inherits: false; initial-value: 1; }\r\n @property --light-distance { syntax: \"<number>\"; inherits: false; initial-value: 1000; }\r\n @property --light-decay { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --light-angle { syntax: \"<number>\"; inherits: false; initial-value: 1.0472; }\r\n @property --light-penumbra { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --light-ground-color { syntax: \"<color>\"; inherits: false; initial-value: #ffffff; }\r\n @property --light-target { syntax: \"*\"; inherits: false; initial-value: none; }\r\n @property --shadow-cast { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --shadow-receive { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --shadow-bias { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --shadow-map-size { syntax: \"<number>\"; inherits: false; initial-value: 512; }\n @property --texture-flip-y { syntax: \"<number>\"; inherits: false; initial-value: 1; }\n @property --texture-color-space { syntax: \"*\"; inherits: false; initial-value: none; }\n @property --particles-mode { syntax: \"*\"; inherits: false; initial-value: emitter; }\n @property --particles-count { syntax: \"<number>\"; inherits: false; initial-value: 300; }\n @property --particles-size { syntax: \"<number>\"; inherits: false; initial-value: 2; }\n @property --particles-color { syntax: \"<color>\"; inherits: false; initial-value: #ffffff; }\n @property --particles-opacity { syntax: \"<number>\"; inherits: false; initial-value: 1; }\n @property --particles-spread { syntax: \"<number>\"; inherits: false; initial-value: 120; }\n @property --particles-seed { syntax: \"<number>\"; inherits: false; initial-value: 1; }\n @property --particles-shape { syntax: \"*\"; inherits: false; initial-value: sphere; }\n @property --particles-fit { syntax: \"<number>\"; inherits: false; initial-value: 0; }\n @property --particles-model { syntax: \"*\"; inherits: false; initial-value: none; }\n @property --particles-model-loader { syntax: \"*\"; inherits: false; initial-value: none; }\n @property --particles-model-node { syntax: \"*\"; inherits: false; initial-value: none; }\n @property --instance-model { syntax: \"*\"; inherits: false; initial-value: none; }\n @property --instance-model-loader { syntax: \"*\"; inherits: false; initial-value: none; }\n @property --instance-model-node { syntax: \"*\"; inherits: false; initial-value: none; }\n @property --emit-rate { syntax: \"<number>\"; inherits: false; initial-value: 30; }\n @property --emit-burst { syntax: \"<number>\"; inherits: false; initial-value: 0; }\n @property --particle-life { syntax: \"<number>\"; inherits: false; initial-value: 2.5; }\n @property --particle-speed { syntax: \"<number>\"; inherits: false; initial-value: 40; }\n @property --particle-direction { syntax: \"*\"; inherits: false; initial-value: 0 1 0; }\n @property --particle-gravity { syntax: \"*\"; inherits: false; initial-value: 0 -30 0; }\n @property --particle-drag { syntax: \"<number>\"; inherits: false; initial-value: 0.1; }\n @property --particle-size-variation { syntax: \"<number>\"; inherits: false; initial-value: 0.6; }\n @property --particle-color-variation { syntax: \"<number>\"; inherits: false; initial-value: 0.2; }\n @property --instance-shape { syntax: \"*\"; inherits: false; initial-value: sphere; }\n @property --instance-scale { syntax: \"<number>\"; inherits: false; initial-value: 1; }\n @property --instance-scale-variation { syntax: \"<number>\"; inherits: false; initial-value: 0.5; }\n @property --instance-rotation-speed { syntax: \"<number>\"; inherits: false; initial-value: 0.4; }\n @property --instance-jitter { syntax: \"<number>\"; inherits: false; initial-value: 0.2; }\n @property --instance-flow { syntax: \"<number>\"; inherits: false; initial-value: 0.3; }\n @property --instance-disperse { syntax: \"<number>\"; inherits: false; initial-value: 0; }\n @property --instance-scatter { syntax: \"<number>\"; inherits: false; initial-value: 0; }\n @property --instance-scatter-x { syntax: \"<number>\"; inherits: false; initial-value: 0; }\n @property --instance-scatter-y { syntax: \"<number>\"; inherits: false; initial-value: 0; }\n @property --instance-scatter-z { syntax: \"<number>\"; inherits: false; initial-value: 0; }\n @property --text-depth { syntax: \"<number>\"; inherits: false; initial-value: 8; }\n @property --text-curve-segments { syntax: \"<number>\"; inherits: false; initial-value: 8; }\n @property --text-bevel-size { syntax: \"<number>\"; inherits: false; initial-value: 0; }\n @property --text-bevel-thickness { syntax: \"<number>\"; inherits: false; initial-value: 0; }\n @property --text-bevel-offset { syntax: \"<number>\"; inherits: false; initial-value: 0; }\n @property --text-bevel-steps { syntax: \"<number>\"; inherits: false; initial-value: 0; }\n @property --text-fit { syntax: \"*\"; inherits: false; initial-value: contain; }\n\r\n :where([string-3d]) {\r\n --translate-x: 0; --translate-y: 0; --translate-z: 0;\r\n --rotate-x: 0; --rotate-y: 0; --rotate-z: 0;\r\n --scale: 1; --scale-x: 1; --scale-y: 1; --scale-z: 1; --opacity: 1; --filter: none;\r\n --light-color: #ffffff; --light-intensity: 1; --light-distance: 1000; --light-decay: 0;\r\n --light-angle: 1.0472; --light-penumbra: 0; --light-ground-color: #ffffff; --light-target: none;\r\n --shadow-cast: 0; --shadow-receive: 0; --shadow-bias: 0; --shadow-map-size: 512;\n --texture-flip-y: 1; --texture-color-space: none;\n --particles-mode: emitter; --particles-count: 300; --particles-size: 2; --particles-color: #ffffff;\n --particles-opacity: 1; --particles-spread: 120; --particles-seed: 1; --particles-shape: sphere;\n --particles-fit: 0;\n --particles-model: none; --particles-model-loader: none; --particles-model-node: none;\n --instance-model: none; --instance-model-loader: none; --instance-model-node: none;\n --emit-rate: 30; --emit-burst: 0; --particle-life: 2.5; --particle-speed: 40;\n --particle-direction: 0 1 0; --particle-gravity: 0 -30 0; --particle-drag: 0.1;\n --particle-size-variation: 0.6; --particle-color-variation: 0.2;\n --instance-shape: sphere; --instance-scale: 1; --instance-scale-variation: 0.5;\n --instance-rotation-speed: 0.4; --instance-jitter: 0.2; --instance-flow: 0.3;\n --instance-disperse: 0;\n --instance-scatter: 0;\n --instance-scatter-x: 0; --instance-scatter-y: 0; --instance-scatter-z: 0;\n --text-depth: 8; --text-curve-segments: 8; --text-bevel-size: 0; --text-bevel-thickness: 0;\n --text-bevel-offset: 0; --text-bevel-steps: 0; --text-fit: contain;\n transform-style: preserve-3d;\n }\n\r\n [string-3d-visual=\"true\"] {\r\n transform:\r\n translate3d(calc(var(--translate-x) * 1px), calc(var(--translate-y) * 1px), calc(var(--translate-z) * 1px))\r\n rotateX(calc(var(--rotate-x) * 1deg))\r\n rotateY(calc(var(--rotate-y) * 1deg))\r\n rotateZ(calc(var(--rotate-z) * 1deg))\r\n scale3d(calc(var(--scale) * var(--scale-x)), calc(var(--scale) * var(--scale-y)), calc(var(--scale) * var(--scale-z)));\r\n }\r\n `;\r\n document.head.appendChild(style);\r\n }\r\n\r\n private registerTypedProperties(): void {\r\n const css = (globalThis as any).CSS;\r\n if (!css?.registerProperty) return;\r\n\r\n const props: Array<{ name: string; initialValue: string }> = [\r\n { name: \"--translate-x\", initialValue: \"0\" },\r\n { name: \"--translate-y\", initialValue: \"0\" },\r\n { name: \"--translate-z\", initialValue: \"0\" },\r\n { name: \"--rotate-x\", initialValue: \"0\" },\r\n { name: \"--rotate-y\", initialValue: \"0\" },\r\n { name: \"--rotate-z\", initialValue: \"0\" },\r\n { name: \"--scale\", initialValue: \"1\" },\r\n { name: \"--scale-x\", initialValue: \"1\" },\r\n { name: \"--scale-y\", initialValue: \"1\" },\r\n { name: \"--scale-z\", initialValue: \"1\" },\r\n { name: \"--opacity\", initialValue: \"1\" },\r\n { name: \"--filter\", initialValue: \"none\" },\r\n { name: \"--material-type\", initialValue: \"basic\" },\r\n { name: \"--material-color\", initialValue: \"#ffffff\" },\r\n { name: \"--material-metalness\", initialValue: \"0\" },\r\n { name: \"--material-roughness\", initialValue: \"1\" },\r\n { name: \"--material-emissive\", initialValue: \"#000000\" },\r\n { name: \"--rim-color\", initialValue: \"#00c8ff\" },\r\n { name: \"--rim-power\", initialValue: \"1.5\" },\r\n { name: \"--rim-strength\", initialValue: \"1\" },\r\n { name: \"--uv-strength\", initialValue: \"0.7\" },\r\n { name: \"--texture-map\", initialValue: \"none\" },\r\n { name: \"--texture-normal\", initialValue: \"none\" },\r\n { name: \"--texture-roughness\", initialValue: \"none\" },\r\n { name: \"--texture-metalness\", initialValue: \"none\" },\r\n { name: \"--texture-ao\", initialValue: \"none\" },\r\n { name: \"--light-color\", initialValue: \"#ffffff\" },\r\n { name: \"--light-intensity\", initialValue: \"1\" },\r\n { name: \"--light-distance\", initialValue: \"1000\" },\r\n { name: \"--light-decay\", initialValue: \"0\" },\r\n { name: \"--light-angle\", initialValue: \"1.0472\" },\r\n { name: \"--light-penumbra\", initialValue: \"0\" },\r\n { name: \"--light-ground-color\", initialValue: \"#ffffff\" },\r\n { name: \"--light-target\", initialValue: \"none\" },\r\n { name: \"--shadow-cast\", initialValue: \"0\" },\r\n { name: \"--shadow-receive\", initialValue: \"0\" },\r\n { name: \"--shadow-bias\", initialValue: \"0\" },\r\n { name: \"--shadow-map-size\", initialValue: \"512\" },\r\n { name: \"--texture-flip-y\", initialValue: \"1\" },\n { name: \"--texture-color-space\", initialValue: \"none\" },\n { name: \"--particles-mode\", initialValue: \"emitter\" },\n { name: \"--particles-count\", initialValue: \"300\" },\n { name: \"--particles-size\", initialValue: \"2\" },\n { name: \"--particles-color\", initialValue: \"#ffffff\" },\n { name: \"--particles-opacity\", initialValue: \"1\" },\n { name: \"--particles-spread\", initialValue: \"120\" },\n { name: \"--particles-seed\", initialValue: \"1\" },\n { name: \"--particles-shape\", initialValue: \"sphere\" },\n { name: \"--particles-fit\", initialValue: \"0\" },\n { name: \"--particles-model\", initialValue: \"none\" },\n { name: \"--particles-model-loader\", initialValue: \"none\" },\n { name: \"--particles-model-node\", initialValue: \"none\" },\n { name: \"--instance-model\", initialValue: \"none\" },\n { name: \"--instance-model-loader\", initialValue: \"none\" },\n { name: \"--instance-model-node\", initialValue: \"none\" },\n { name: \"--emit-rate\", initialValue: \"30\" },\n { name: \"--emit-burst\", initialValue: \"0\" },\n { name: \"--particle-life\", initialValue: \"2.5\" },\n { name: \"--particle-speed\", initialValue: \"40\" },\n { name: \"--particle-direction\", initialValue: \"0 1 0\" },\n { name: \"--particle-gravity\", initialValue: \"0 -30 0\" },\n { name: \"--particle-drag\", initialValue: \"0.1\" },\n { name: \"--particle-size-variation\", initialValue: \"0.6\" },\n { name: \"--particle-color-variation\", initialValue: \"0.2\" },\n { name: \"--instance-shape\", initialValue: \"sphere\" },\n { name: \"--instance-scale\", initialValue: \"1\" },\n { name: \"--instance-scale-variation\", initialValue: \"0.5\" },\n { name: \"--instance-rotation-speed\", initialValue: \"0.4\" },\n { name: \"--instance-jitter\", initialValue: \"0.2\" },\n { name: \"--instance-flow\", initialValue: \"0.3\" },\n { name: \"--instance-disperse\", initialValue: \"0\" },\n { name: \"--instance-scatter\", initialValue: \"0\" },\n { name: \"--instance-scatter-x\", initialValue: \"0\" },\n { name: \"--instance-scatter-y\", initialValue: \"0\" },\n { name: \"--instance-scatter-z\", initialValue: \"0\" },\n { name: \"--text-depth\", initialValue: \"8\" },\n { name: \"--text-curve-segments\", initialValue: \"8\" },\n { name: \"--text-bevel-size\", initialValue: \"0\" },\n { name: \"--text-bevel-thickness\", initialValue: \"0\" },\n { name: \"--text-bevel-offset\", initialValue: \"0\" },\n { name: \"--text-bevel-steps\", initialValue: \"0\" },\n { name: \"--text-fit\", initialValue: \"contain\" },\n ];\n\r\n props.forEach(({ name, initialValue }) => {\r\n try {\r\n css.registerProperty({\r\n name,\r\n syntax:\n name === \"--filter\" ||\n name === \"--light-target\" ||\n name.startsWith(\"--texture-\") ||\n name === \"--material-type\" ||\n name === \"--particles-mode\" ||\n name === \"--particles-shape\" ||\n name === \"--particles-model\" ||\n name === \"--particles-model-loader\" ||\n name === \"--particles-model-node\" ||\n name === \"--instance-model\" ||\n name === \"--instance-model-loader\" ||\n name === \"--instance-model-node\" ||\n name === \"--particle-direction\" ||\n name === \"--particle-gravity\" ||\n name === \"--instance-shape\" ||\n name === \"--text-fit\"\n ? \"*\"\n : name.includes(\"color\") || name.includes(\"emissive\")\n ? \"<color>\"\n : \"<number>\",\n inherits: false,\r\n initialValue,\r\n });\r\n } catch {}\r\n });\r\n }\r\n\r\n override destroy(): void {\r\n this.renderer?.destroy();\r\n this.scene?.destroy();\r\n this.isLoading.clear();\r\n this.dirtySyncManager.disable();\r\n this.filterController.clear();\r\n this.lastSyncData = new WeakMap();\r\n\r\n const styleEl = document.getElementById(\"string-3d-styles\");\r\n styleEl?.remove();\r\n\r\n if (this.canvasContainer?.id === \"string-3d-canvas\") {\r\n this.canvasContainer.remove();\r\n }\r\n\r\n super.destroy();\r\n }\r\n}\r\n","import { I3DEngine, I3DVector3, I3DCamera } from \"./abstractions/I3DEngine\";\r\n\r\nexport type CameraMode = \"orthographic\" | \"perspective\";\r\n\r\nexport class String3DCamera {\r\n private scaleCache = new Map<number, number>();\r\n private _camera: I3DCamera;\r\n private _position: I3DVector3;\r\n private _width = 1;\r\n private _height = 1;\r\n private engine: I3DEngine;\r\n private mode: CameraMode;\r\n private perspectiveFov: number;\r\n\r\n constructor(\r\n engine: I3DEngine,\r\n mode: CameraMode = \"perspective\",\r\n fov = 50,\r\n near = 0.1,\r\n far = 10000\r\n ) {\r\n this.engine = engine;\r\n this.mode = mode;\r\n this.perspectiveFov = fov;\r\n\r\n if (mode === \"orthographic\") {\r\n this._camera = engine.createOrthographicCamera(-1, 1, 1, -1, near, far);\r\n } else {\r\n this._camera = engine.createPerspectiveCamera(fov, 1, near, far);\r\n }\r\n\r\n this._position = engine.createVector3(0, 0, 1000);\r\n this.update();\r\n }\r\n\r\n public get camera(): I3DCamera {\r\n return this._camera;\r\n }\r\n\r\n public resize(width: number, height: number): void {\r\n this._width = width;\r\n this._height = height;\r\n\r\n if (this.mode === \"orthographic\") {\r\n const ortho = this._camera as any;\r\n ortho.left = -width / 2;\r\n ortho.right = width / 2;\r\n ortho.top = height / 2;\r\n ortho.bottom = -height / 2;\r\n } else {\r\n this._camera.aspect = width / height;\r\n }\r\n\r\n this.update();\r\n }\r\n\r\n public setPosition(x: number, y: number, z: number): void {\r\n this._position.set(x, y, z);\r\n this._camera.position.copy(this._position);\r\n this.update();\r\n }\r\n\r\n public lookAt(x: number, y: number, z: number): void {\r\n this._camera.lookAt(x, y, z);\r\n this.update();\r\n }\r\n\r\n public update(): void {\r\n this._camera.updateProjectionMatrix();\r\n (this._camera as any).updateMatrixWorld?.();\r\n }\r\n\r\n public screenToWorld(screenX: number, screenY: number, z = 0): I3DVector3 {\r\n if (this.mode === \"orthographic\") {\r\n const x = screenX - this._width / 2;\r\n const y = -(screenY - this._height / 2);\r\n return this.engine.createVector3(x, y, z);\r\n } else {\r\n const { width, height } = this.getFrustumSizeAt(z);\r\n const normalizedX = screenX / this._width;\r\n const normalizedY = screenY / this._height;\r\n const x = (normalizedX - 0.5) * width;\r\n const y = -(normalizedY - 0.5) * height;\r\n return this.engine.createVector3(x, y, z);\r\n }\r\n }\r\n\r\n public getFrustumSizeAt(z: number): { width: number; height: number } {\r\n if (this.mode === \"orthographic\") {\r\n return { width: this._width, height: this._height };\r\n }\r\n\r\n const fov = this.engine.degToRad(this.perspectiveFov);\r\n const distance = Math.abs(z - this._camera.position.z);\r\n const height = 2 * Math.tan(fov / 2) * distance;\r\n const width = height * this._camera.aspect;\r\n return { width, height };\r\n }\r\n\r\n public getScaleAtZ(z: number, viewportHeight: number): number {\r\n if (this.mode === \"orthographic\") {\r\n return 1;\r\n }\r\n\r\n const roundedZ = Math.round(z * 1000) / 1000;\r\n if (this.scaleCache.has(roundedZ)) {\r\n return this.scaleCache.get(roundedZ)!;\r\n }\r\n\r\n const { height } = this.getFrustumSizeAt(z);\r\n const scale = height / viewportHeight;\r\n this.scaleCache.set(roundedZ, scale);\r\n return scale;\r\n }\r\n\r\n public clearScaleCache(): void {\r\n this.scaleCache.clear();\r\n }\r\n\r\n public getMode(): CameraMode {\r\n return this.mode;\r\n }\r\n\r\n public getPerspectiveFov(): number {\r\n return this.perspectiveFov;\r\n }\r\n\r\n public getPositionZ(): number {\r\n return this._position.z;\r\n }\r\n}\r\n","export type String3DCustomFilterDefinition = {\n name: string;\n fragmentShader: string;\n uniforms?: Record<string, any>;\n parse?: (args: string) => Record<string, any> | null;\n};\n\nexport class String3DCustomFilterRegistry {\n private static filters: Map<string, String3DCustomFilterDefinition> = new Map();\n\n static register(definition: String3DCustomFilterDefinition): void {\n const name = definition.name.trim().toLowerCase();\n if (!name) {\n throw new Error(\"[String3D] Custom filter name is required.\");\n }\n this.filters.set(name, { ...definition, name });\n }\n\n static get(name: string): String3DCustomFilterDefinition | undefined {\n return this.filters.get(name.trim().toLowerCase());\n }\n\n static has(name: string): boolean {\n return this.filters.has(name.trim().toLowerCase());\n }\n\n static list(): String3DCustomFilterDefinition[] {\n return Array.from(this.filters.values());\n }\n}\n","import {\n I3DEngine,\n I3DRenderer,\n I3DRenderTarget,\n I3DScene,\n I3DCamera,\n I3DMaterial,\n I3DObject,\n} from \"../abstractions/I3DEngine\";\nimport type { String3DFilterChain } from \"./String3DFilterTypes\";\nimport { String3DCustomFilterRegistry } from \"./String3DCustomFilter\";\n\ntype RenderTargetFactory = (width: number, height: number) => I3DRenderTarget;\n\nclass RenderTargetPool {\n private pool: I3DRenderTarget[] = [];\n private create: RenderTargetFactory;\n\n constructor(create: RenderTargetFactory) {\n this.create = create;\n }\n\n acquire(width: number, height: number): I3DRenderTarget {\n const target = this.pool.pop() || this.create(width, height);\n if (target.width !== width || target.height !== height) {\n target.setSize(width, height);\n }\n return target;\n }\n\n release(target: I3DRenderTarget): void {\n this.pool.push(target);\n }\n\n dispose(): void {\n this.pool.forEach((target) => target.dispose());\n this.pool = [];\n }\n}\n\nexport class String3DFilterPipeline {\n private engine: I3DEngine;\n private renderer: I3DRenderer;\n private width: number;\n private height: number;\n private scale = 1;\n private scene: I3DScene;\n private camera: I3DCamera;\n private quad: I3DObject;\n private copyMaterial: I3DMaterial;\n private blurMaterial: I3DMaterial;\n private pixelMaterial: I3DMaterial;\n private bloomExtractMaterial: I3DMaterial;\n private bloomAddMaterial: I3DMaterial;\n private colorMaterial: I3DMaterial;\n private customMaterials: Map<string, I3DMaterial> = new Map();\n private pool: RenderTargetPool;\n\n constructor(engine: I3DEngine, renderer: I3DRenderer, width: number, height: number) {\n this.engine = engine;\n this.renderer = renderer;\n this.width = width;\n this.height = height;\n\n this.scene = engine.createScene();\n this.camera = engine.createOrthographicCamera(-1, 1, 1, -1, 0, 1);\n\n const geometry = engine.createPlaneGeometry(2, 2);\n this.copyMaterial = this.createCopyMaterial();\n this.blurMaterial = this.createBlurMaterial();\n this.pixelMaterial = this.createPixelMaterial();\n this.bloomExtractMaterial = this.createBloomExtractMaterial();\n this.bloomAddMaterial = this.createBloomAddMaterial();\n this.colorMaterial = this.createColorMaterial();\n\n this.quad = engine.createMesh(geometry, this.copyMaterial);\n this.scene.add(this.quad);\n\n const create = (w: number, h: number) => {\n if (!this.engine.createRenderTarget) {\n throw new Error(\"[String3DFilterPipeline] Render target support missing.\");\n }\n return this.engine.createRenderTarget(w, h);\n };\n this.pool = new RenderTargetPool(create);\n }\n\n public isSupported(): boolean {\n return (\n !!this.engine.createRenderTarget &&\n !!this.engine.createShaderMaterial &&\n !!this.renderer.setRenderTarget\n );\n }\n\n public resize(width: number, height: number): void {\n this.width = width;\n this.height = height;\n }\n\n public setScale(scale: number): void {\n const next = Math.max(0.75, Math.min(1, scale));\n this.scale = next;\n }\n\n public applyFilters(\n input: I3DRenderTarget,\n effects: String3DFilterChain,\n quality = 1\n ): I3DRenderTarget {\n let current = input;\n const locals: I3DRenderTarget[] = [];\n\n const releaseLocal = (target: I3DRenderTarget): void => {\n const idx = locals.indexOf(target);\n if (idx >= 0) {\n locals.splice(idx, 1);\n this.pool.release(target);\n }\n };\n\n const acquire = (): I3DRenderTarget => {\n const { width, height } = this.getScaledSize();\n const target = this.pool.acquire(width, height);\n locals.push(target);\n return target;\n };\n\n effects.forEach((effect) => {\n if (effect.type === \"blur\") {\n const radius = effect.amount * quality;\n if (radius <= 0.0001) return;\n const first = acquire();\n this.renderPass(this.blurMaterial, current, first, {\n uDirection: [1, 0],\n uRadius: radius,\n });\n const second = acquire();\n this.renderPass(this.blurMaterial, first, second, {\n uDirection: [0, 1],\n uRadius: radius,\n });\n releaseLocal(first);\n if (current !== input) {\n releaseLocal(current);\n }\n current = second;\n } else if (effect.type === \"pixel\") {\n if (effect.size <= 0.5) return;\n const output = acquire();\n this.renderPass(this.pixelMaterial, current, output, {\n uPixelSize: effect.size,\n });\n if (current !== input) {\n releaseLocal(current);\n }\n current = output;\n } else if (effect.type === \"bloom\") {\n const intensity = effect.intensity;\n if (intensity <= 0.0001) return;\n if (effect.threshold >= 0.99) return;\n const blurRadius = Math.max(1, 4 * quality);\n const extracted = acquire();\n this.renderPass(this.bloomExtractMaterial, current, extracted, {\n uThreshold: effect.threshold,\n });\n\n const blur1 = acquire();\n this.renderPass(this.blurMaterial, extracted, blur1, {\n uDirection: [1, 0],\n uRadius: blurRadius,\n });\n const blur2 = acquire();\n this.renderPass(this.blurMaterial, blur1, blur2, {\n uDirection: [0, 1],\n uRadius: blurRadius,\n });\n\n releaseLocal(extracted);\n releaseLocal(blur1);\n\n const combined = acquire();\n this.renderAddPass(current, blur2, combined, intensity);\n releaseLocal(blur2);\n\n if (current !== input) {\n releaseLocal(current);\n }\n current = combined;\n } else if (\n effect.type === \"brightness\" ||\n effect.type === \"contrast\" ||\n effect.type === \"saturate\" ||\n effect.type === \"grayscale\" ||\n effect.type === \"sepia\" ||\n effect.type === \"invert\" ||\n effect.type === \"hue-rotate\"\n ) {\n const output = acquire();\n const mode = this.getColorMode(effect.type);\n const amount = effect.type === \"hue-rotate\" ? effect.angle : effect.amount;\n this.renderPass(this.colorMaterial, current, output, {\n uMode: mode,\n uAmount: amount,\n });\n if (current !== input) {\n releaseLocal(current);\n }\n current = output;\n } else if (effect.type === \"custom\") {\n const output = acquire();\n const material = this.getCustomMaterial(effect.name);\n if (material) {\n this.renderPass(material, current, output, effect.uniforms);\n if (current !== input) {\n releaseLocal(current);\n }\n current = output;\n } else {\n releaseLocal(output);\n }\n }\n });\n\n locals.forEach((target) => {\n if (target !== current) {\n this.pool.release(target);\n }\n });\n\n return current;\n }\n\n public acquireTarget(): I3DRenderTarget {\n const { width, height } = this.getScaledSize();\n return this.pool.acquire(width, height);\n }\n\n public releaseTarget(target: I3DRenderTarget): void {\n this.pool.release(target);\n }\n\n public renderToScreen(input: I3DRenderTarget): void {\n this.renderPass(this.copyMaterial, input, null, {}, false);\n }\n\n public dispose(): void {\n this.pool.dispose();\n this.customMaterials.forEach((material) => material.dispose());\n this.customMaterials.clear();\n }\n\n private renderPass(\n material: I3DMaterial,\n input: I3DRenderTarget,\n output: I3DRenderTarget | null,\n uniforms: Record<string, any> = {},\n clear = true\n ): void {\n const renderer = this.renderer as any;\n if (renderer.setRenderTarget) {\n renderer.setRenderTarget(output);\n }\n\n this.setMaterial(this.quad, material);\n this.setUniform(material, \"tDiffuse\", input.texture);\n const { width, height } = this.getScaledSize();\n this.setUniform(material, \"uResolution\", [width, height]);\n this.setUniform(material, \"uTexel\", [1 / width, 1 / height]);\n Object.entries(uniforms).forEach(([key, value]) => this.setUniform(material, key, value));\n\n if (clear && renderer.clear) {\n renderer.clear(true, true, true);\n }\n this.renderer.render(this.scene, this.camera);\n }\n\n private renderAddPass(\n base: I3DRenderTarget,\n bloom: I3DRenderTarget,\n output: I3DRenderTarget,\n intensity: number\n ): void {\n const renderer = this.renderer as any;\n if (renderer.setRenderTarget) {\n renderer.setRenderTarget(output);\n }\n\n this.setMaterial(this.quad, this.bloomAddMaterial);\n this.setUniform(this.bloomAddMaterial, \"tBase\", base.texture);\n this.setUniform(this.bloomAddMaterial, \"tBloom\", bloom.texture);\n this.setUniform(this.bloomAddMaterial, \"uIntensity\", intensity);\n const { width, height } = this.getScaledSize();\n this.setUniform(this.bloomAddMaterial, \"uResolution\", [width, height]);\n\n if (renderer.clear) {\n renderer.clear(true, true, true);\n }\n this.renderer.render(this.scene, this.camera);\n }\n\n private setMaterial(object: I3DObject, material: I3DMaterial): void {\n const anyObj = object as any;\n if (anyObj.material !== material) {\n anyObj.material = material as any;\n }\n }\n\n private setUniform(material: I3DMaterial, name: string, value: any): void {\n const uniforms = (material as any).uniforms;\n if (!uniforms) return;\n if (!uniforms[name]) {\n uniforms[name] = { value };\n } else {\n uniforms[name].value = value;\n }\n }\n\n private createCopyMaterial(): I3DMaterial {\n return this.createShaderMaterial({\n uniforms: { tDiffuse: { value: null } },\n vertexShader: this.getVertexShader(),\n fragmentShader: `\n varying vec2 vUv;\n uniform sampler2D tDiffuse;\n void main() {\n gl_FragColor = texture2D(tDiffuse, vUv);\n }\n `,\n transparent: true,\n depthTest: false,\n depthWrite: false,\n });\n }\n\n private createPixelMaterial(): I3DMaterial {\n return this.createShaderMaterial({\n uniforms: {\n tDiffuse: { value: null },\n uResolution: { value: [this.width, this.height] },\n uPixelSize: { value: 1 },\n },\n vertexShader: this.getVertexShader(),\n fragmentShader: `\n varying vec2 vUv;\n uniform sampler2D tDiffuse;\n uniform vec2 uResolution;\n uniform float uPixelSize;\n void main() {\n vec2 pixel = uPixelSize / uResolution;\n vec2 coord = floor(vUv / pixel) * pixel + pixel * 0.5;\n gl_FragColor = texture2D(tDiffuse, coord);\n }\n `,\n transparent: true,\n depthTest: false,\n depthWrite: false,\n });\n }\n\n private createBlurMaterial(): I3DMaterial {\n return this.createShaderMaterial({\n uniforms: {\n tDiffuse: { value: null },\n uTexel: { value: [1 / this.width, 1 / this.height] },\n uDirection: { value: [1, 0] },\n uRadius: { value: 2 },\n },\n vertexShader: this.getVertexShader(),\n fragmentShader: `\n varying vec2 vUv;\n uniform sampler2D tDiffuse;\n uniform vec2 uTexel;\n uniform vec2 uDirection;\n uniform float uRadius;\n void main() {\n vec2 off1 = uDirection * uTexel * uRadius;\n vec2 off2 = uDirection * uTexel * uRadius * 2.0;\n vec2 off3 = uDirection * uTexel * uRadius * 3.0;\n vec2 off4 = uDirection * uTexel * uRadius * 4.0;\n vec4 color = texture2D(tDiffuse, vUv) * 0.227027;\n color += texture2D(tDiffuse, vUv + off1) * 0.1945946;\n color += texture2D(tDiffuse, vUv - off1) * 0.1945946;\n color += texture2D(tDiffuse, vUv + off2) * 0.1216216;\n color += texture2D(tDiffuse, vUv - off2) * 0.1216216;\n color += texture2D(tDiffuse, vUv + off3) * 0.054054;\n color += texture2D(tDiffuse, vUv - off3) * 0.054054;\n color += texture2D(tDiffuse, vUv + off4) * 0.016216;\n color += texture2D(tDiffuse, vUv - off4) * 0.016216;\n gl_FragColor = color;\n }\n `,\n transparent: true,\n depthTest: false,\n depthWrite: false,\n });\n }\n\n private createBloomExtractMaterial(): I3DMaterial {\n return this.createShaderMaterial({\n uniforms: {\n tDiffuse: { value: null },\n uThreshold: { value: 0.8 },\n },\n vertexShader: this.getVertexShader(),\n fragmentShader: `\n varying vec2 vUv;\n uniform sampler2D tDiffuse;\n uniform float uThreshold;\n void main() {\n vec4 color = texture2D(tDiffuse, vUv);\n float brightness = max(max(color.r, color.g), color.b);\n gl_FragColor = brightness > uThreshold ? color : vec4(0.0);\n }\n `,\n transparent: true,\n depthTest: false,\n depthWrite: false,\n });\n }\n\n private createBloomAddMaterial(): I3DMaterial {\n return this.createShaderMaterial({\n uniforms: {\n tBase: { value: null },\n tBloom: { value: null },\n uIntensity: { value: 1 },\n uResolution: { value: [this.width, this.height] },\n },\n vertexShader: this.getVertexShader(),\n fragmentShader: `\n varying vec2 vUv;\n uniform sampler2D tBase;\n uniform sampler2D tBloom;\n uniform float uIntensity;\n void main() {\n vec4 base = texture2D(tBase, vUv);\n vec4 bloom = texture2D(tBloom, vUv);\n gl_FragColor = vec4(base.rgb + bloom.rgb * uIntensity, base.a);\n }\n `,\n transparent: true,\n depthTest: false,\n depthWrite: false,\n });\n }\n\n private createColorMaterial(): I3DMaterial {\n return this.createShaderMaterial({\n uniforms: {\n tDiffuse: { value: null },\n uMode: { value: 0 },\n uAmount: { value: 1 },\n },\n vertexShader: this.getVertexShader(),\n fragmentShader: `\n varying vec2 vUv;\n uniform sampler2D tDiffuse;\n uniform int uMode;\n uniform float uAmount;\n\n vec3 applyHueRotate(vec3 color, float angle) {\n float cosA = cos(angle);\n float sinA = sin(angle);\n mat3 m = mat3(\n 0.213 + cosA * 0.787 - sinA * 0.213,\n 0.715 - cosA * 0.715 - sinA * 0.715,\n 0.072 - cosA * 0.072 + sinA * 0.928,\n 0.213 - cosA * 0.213 + sinA * 0.143,\n 0.715 + cosA * 0.285 + sinA * 0.140,\n 0.072 - cosA * 0.072 - sinA * 0.283,\n 0.213 - cosA * 0.213 - sinA * 0.787,\n 0.715 - cosA * 0.715 + sinA * 0.715,\n 0.072 + cosA * 0.928 + sinA * 0.072\n );\n return clamp(m * color, 0.0, 1.0);\n }\n\n void main() {\n vec4 color = texture2D(tDiffuse, vUv);\n float luma = dot(color.rgb, vec3(0.299, 0.587, 0.114));\n\n if (uMode == 1) {\n color.rgb *= uAmount;\n } else if (uMode == 2) {\n color.rgb = (color.rgb - 0.5) * uAmount + 0.5;\n } else if (uMode == 3) {\n color.rgb = mix(vec3(luma), color.rgb, uAmount);\n } else if (uMode == 4) {\n color.rgb = mix(color.rgb, vec3(luma), uAmount);\n } else if (uMode == 5) {\n vec3 sepia = vec3(\n dot(color.rgb, vec3(0.393, 0.769, 0.189)),\n dot(color.rgb, vec3(0.349, 0.686, 0.168)),\n dot(color.rgb, vec3(0.272, 0.534, 0.131))\n );\n color.rgb = mix(color.rgb, sepia, uAmount);\n } else if (uMode == 6) {\n color.rgb = mix(color.rgb, vec3(1.0) - color.rgb, uAmount);\n } else if (uMode == 7) {\n color.rgb = applyHueRotate(color.rgb, uAmount);\n }\n\n gl_FragColor = color;\n }\n `,\n transparent: true,\n depthTest: false,\n depthWrite: false,\n });\n }\n\n private getColorMode(type: string): number {\n switch (type) {\n case \"brightness\":\n return 1;\n case \"contrast\":\n return 2;\n case \"saturate\":\n return 3;\n case \"grayscale\":\n return 4;\n case \"sepia\":\n return 5;\n case \"invert\":\n return 6;\n case \"hue-rotate\":\n return 7;\n default:\n return 0;\n }\n }\n\n private createShaderMaterial(params: any): I3DMaterial {\n if (!this.engine.createShaderMaterial) {\n throw new Error(\"[String3DFilterPipeline] Shader material support missing.\");\n }\n return this.engine.createShaderMaterial(params);\n }\n\n private getCustomMaterial(name: string): I3DMaterial | null {\n const normalized = name.trim().toLowerCase();\n if (!normalized) return null;\n if (this.customMaterials.has(normalized)) {\n return this.customMaterials.get(normalized)!;\n }\n const def = String3DCustomFilterRegistry.get(normalized);\n if (!def) return null;\n\n const uniforms: Record<string, any> = { tDiffuse: { value: null } };\n const { width, height } = this.getScaledSize();\n uniforms.uResolution = { value: [width, height] };\n uniforms.uTexel = { value: [1 / width, 1 / height] };\n Object.entries(def.uniforms || {}).forEach(([key, value]) => {\n uniforms[key] = { value };\n });\n\n const material = this.createShaderMaterial({\n uniforms,\n vertexShader: this.getVertexShader(),\n fragmentShader: def.fragmentShader,\n transparent: true,\n depthTest: false,\n depthWrite: false,\n });\n\n this.customMaterials.set(normalized, material);\n return material;\n }\n\n private getScaledSize(): { width: number; height: number } {\n const width = Math.max(1, Math.round(this.width * this.scale));\n const height = Math.max(1, Math.round(this.height * this.scale));\n return { width, height };\n }\n\n private getVertexShader(): string {\n return `\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n `;\n }\n}\n","import { I3DEngine, I3DRenderer, I3DObject, I3DRenderTarget } from \"./abstractions/I3DEngine\";\nimport { String3DCamera } from \"./String3DCamera\";\nimport { String3DScene } from \"./String3DScene\";\nimport { String3DFilterPipeline } from \"./filters/String3DFilterPipeline\";\nimport type { String3DFilterTarget } from \"./filters/String3DFilterTypes\";\nimport type { String3DFilterEffect } from \"./filters/String3DFilterTypes\";\n\ntype FilterCacheEntry = {\n target: I3DRenderTarget;\n effectsKey: string;\n lastUsedFrame: number;\n qualityScale: number;\n};\n\nexport class String3DRenderer {\n private _container: HTMLElement;\n private _renderer: I3DRenderer;\n private _width: number;\n private _height: number;\n private engine: I3DEngine;\n private filterPipeline: String3DFilterPipeline | null = null;\n private filterCache: Map<string, FilterCacheEntry> = new Map();\n private frameId = 0;\n private lastFrameTime = performance.now();\n private avgFrameMs = 16.7;\n private qualityScale = 1;\n private lastQualityChange = 0;\n private filterLayer = 1;\n\n constructor(container: HTMLElement, engine: I3DEngine) {\n this.engine = engine;\n this._container = container;\n const { width, height } = container.getBoundingClientRect();\n this._width = width;\n this._height = height;\n\n this._renderer = engine.createRenderer({\n antialias: true,\n alpha: true,\n logarithmicDepthBuffer: true,\n });\n const rendererAny = this._renderer as any;\n if (typeof rendererAny.setClearColor === \"function\") {\n rendererAny.setClearColor(0x000000, 0);\n }\n this._renderer.setPixelRatio(window.devicePixelRatio);\n this._renderer.setSize(width, height);\n\n if (this._renderer.shadowMap) {\n this._renderer.shadowMap.enabled = true;\n }\n }\n\n public attach(): void {\n this._container.appendChild(this._renderer.domElement);\n }\n\n public render(\n scene: String3DScene,\n camera: String3DCamera,\n filterTargets: String3DFilterTarget[] = []\n ): void {\n if (filterTargets.length === 0) {\n this._renderer.render(scene.getScene(), camera.camera);\n return;\n }\n\n const pipeline = this.ensureFilterPipeline();\n if (!pipeline?.isSupported()) {\n this._renderer.render(scene.getScene(), camera.camera);\n return;\n }\n\n this.frameId += 1;\n this.updateQuality(filterTargets.length, pipeline);\n\n const allObjects = scene.getAllObjects();\n const visibility = new Map<I3DObject, boolean | undefined>();\n allObjects.forEach((obj) => {\n const anyObj = obj.object as any;\n if (\"visible\" in anyObj) {\n visibility.set(obj.object, anyObj.visible);\n }\n });\n\n const filteredSet = new Set<I3DObject>();\n filterTargets.forEach((target) => {\n this.collectSubtreeObjects(target.object, filteredSet);\n });\n\n allObjects.forEach((obj) => {\n if (filteredSet.has(obj.object)) {\n this.setVisible(obj.object, false);\n }\n });\n\n const rendererAny = this._renderer as any;\n const prevAutoClear = rendererAny.autoClear;\n rendererAny.autoClear = true;\n if (rendererAny.setRenderTarget) {\n rendererAny.setRenderTarget(null);\n }\n if (rendererAny.clear) {\n rendererAny.clear(true, true, true);\n }\n this._renderer.render(scene.getScene(), camera.camera);\n\n rendererAny.autoClear = false;\n\n allObjects.forEach((obj) => {\n const originalVisible = visibility.get(obj.object);\n if (typeof originalVisible !== \"undefined\") {\n this.setVisible(obj.object, originalVisible);\n }\n });\n\n const lights = allObjects.filter((obj) => obj.type.endsWith(\"Light\"));\n const supportsLayers = this.supportsLayers(camera.camera, allObjects);\n\n filterTargets.forEach((target) => {\n const cache = this.filterCache.get(target.object.id);\n const canUseCache =\n !target.dirty &&\n cache &&\n cache.effectsKey === target.effectsKey &&\n cache.qualityScale === this.qualityScale;\n\n if (canUseCache) {\n cache.lastUsedFrame = this.frameId;\n pipeline.renderToScreen(cache.target);\n return;\n }\n\n const effects = this.injectEffectContext(\n target.object.el as HTMLElement | undefined,\n target.effects\n );\n\n const allowed = new Set<I3DObject>();\n this.collectSubtreeObjects(target.object, allowed);\n\n let restoreLayers: Array<{ object: I3DObject; mask: number }> = [];\n let restoreCameraMask: number | null = null;\n\n if (supportsLayers) {\n const subtree = target.object.getSubtreeObjects();\n restoreLayers = this.applyLayerMask(subtree, lights, this.filterLayer);\n restoreCameraMask = this.setCameraLayer(camera.camera, this.filterLayer);\n } else {\n allObjects.forEach((obj) => {\n const originalVisible = visibility.get(obj.object);\n if (originalVisible === false) {\n this.setVisible(obj.object, false);\n return;\n }\n\n if (obj.type.endsWith(\"Light\")) {\n this.setVisible(obj.object, true);\n return;\n }\n\n this.setVisible(obj.object, allowed.has(obj.object));\n });\n }\n\n const input = pipeline.acquireTarget();\n if (rendererAny.setRenderTarget) {\n rendererAny.setRenderTarget(input);\n }\n if (rendererAny.clear) {\n rendererAny.clear(true, true, true);\n }\n this._renderer.render(scene.getScene(), camera.camera);\n\n const output = pipeline.applyFilters(input, effects, this.qualityScale);\n if (rendererAny.setRenderTarget) {\n rendererAny.setRenderTarget(null);\n }\n pipeline.renderToScreen(output);\n\n if (supportsLayers) {\n this.restoreLayerMask(restoreLayers);\n if (restoreCameraMask !== null) {\n this.restoreCameraLayer(camera.camera, restoreCameraMask);\n }\n }\n\n if (output !== input) {\n pipeline.releaseTarget(input);\n }\n\n const entry: FilterCacheEntry = {\n target: output,\n effectsKey: target.effectsKey,\n lastUsedFrame: this.frameId,\n qualityScale: this.qualityScale,\n };\n const existing = this.filterCache.get(target.object.id);\n if (existing && existing.target !== output) {\n pipeline.releaseTarget(existing.target);\n }\n this.filterCache.set(target.object.id, entry);\n });\n\n if (!supportsLayers) {\n allObjects.forEach((obj) => {\n const originalVisible = visibility.get(obj.object);\n if (typeof originalVisible !== \"undefined\") {\n this.setVisible(obj.object, originalVisible);\n }\n });\n }\n\n rendererAny.autoClear = prevAutoClear;\n\n this.evictCache();\n }\n\n public resize(camera: String3DCamera): void {\n const { width, height } = this._container.getBoundingClientRect();\n this._width = width;\n this._height = height;\n this._renderer.setSize(width, height);\n camera.resize(width, height);\n this.filterPipeline?.resize(width, height);\n this.invalidateFilterCache();\n }\n\n public get width(): number {\n return this._width;\n }\n\n public get height(): number {\n return this._height;\n }\n\n public get renderer(): I3DRenderer {\n return this._renderer;\n }\n\n public destroy(): void {\n this._renderer.dispose();\n this.filterPipeline?.dispose();\n this.filterCache.clear();\n }\n\n private ensureFilterPipeline(): String3DFilterPipeline | null {\n if (!this.canCreateFilterPipeline()) {\n return null;\n }\n if (!this.filterPipeline) {\n this.filterPipeline = new String3DFilterPipeline(\n this.engine,\n this._renderer,\n this._width,\n this._height\n );\n this.filterPipeline.setScale(this.qualityScale);\n }\n return this.filterPipeline;\n }\n\n private canCreateFilterPipeline(): boolean {\n return (\n typeof this.engine.createRenderTarget === \"function\" &&\n typeof this.engine.createShaderMaterial === \"function\" &&\n typeof (this._renderer as any).setRenderTarget === \"function\"\n );\n }\n\n private collectSubtreeObjects(\n object: import(\"./String3DObject\").String3DObject,\n set: Set<I3DObject>\n ): void {\n set.add(object.object);\n object.children.forEach((child) => this.collectSubtreeObjects(child, set));\n }\n\n private setVisible(object: I3DObject, visible: boolean): void {\n const anyObj = object as any;\n if (\"visible\" in anyObj) {\n anyObj.visible = visible;\n }\n }\n\n private getFilterCenter(el: HTMLElement | undefined): [number, number] {\n if (!el || !this._width || !this._height) return [0.5, 0.5];\n const cached = (el as any).__layoutCache;\n const rect = cached ? cached.rect : el.getBoundingClientRect();\n const cx = (rect.left + rect.width / 2) / this._width;\n const cy = 1 - (rect.top + rect.height / 2) / this._height;\n const clamp = (value: number) => Math.max(0, Math.min(1, value));\n return [clamp(cx), clamp(cy)];\n }\n\n private injectEffectContext(\n el: HTMLElement | undefined,\n effects: String3DFilterEffect[]\n ): String3DFilterEffect[] {\n if (!effects.some((effect) => effect.type === \"custom\")) {\n return effects;\n }\n const center = this.getFilterCenter(el);\n let changed = false;\n const next = effects.map((effect) => {\n if (effect.type !== \"custom\") return effect;\n if (effect.uniforms && \"uCenter\" in effect.uniforms) return effect;\n const uniforms = { ...(effect.uniforms || {}), uCenter: center };\n changed = true;\n return { ...effect, uniforms };\n });\n return changed ? next : effects;\n }\n\n private updateQuality(filterCount: number, pipeline: String3DFilterPipeline): void {\n const now = performance.now();\n const dt = Math.max(0.1, now - this.lastFrameTime);\n this.lastFrameTime = now;\n this.avgFrameMs = this.avgFrameMs * 0.9 + dt * 0.1;\n\n const fps = 1000 / this.avgFrameMs;\n const countScale = Math.max(0.75, 1 - Math.min(0.4, filterCount * 0.03));\n let targetScale = countScale;\n\n if (fps < 48) targetScale = Math.max(0.75, countScale - 0.1);\n if (fps < 40) targetScale = Math.max(0.75, countScale - 0.2);\n if (fps > 58) targetScale = Math.min(1, countScale + 0.05);\n\n if (Math.abs(targetScale - this.qualityScale) >= 0.05 && now - this.lastQualityChange > 300) {\n this.qualityScale = targetScale;\n this.lastQualityChange = now;\n pipeline.setScale(this.qualityScale);\n this.invalidateFilterCache();\n }\n }\n\n private invalidateFilterCache(): void {\n if (!this.filterPipeline) return;\n this.filterCache.forEach((entry) => {\n this.filterPipeline?.releaseTarget(entry.target);\n });\n this.filterCache.clear();\n }\n\n private evictCache(): void {\n if (!this.filterPipeline) return;\n const maxAge = 120;\n this.filterCache.forEach((entry, key) => {\n if (this.frameId - entry.lastUsedFrame > maxAge) {\n this.filterPipeline?.releaseTarget(entry.target);\n this.filterCache.delete(key);\n }\n });\n }\n\n private supportsLayers(camera: any, objects: Array<{ object: I3DObject }>): boolean {\n if (!camera?.layers || typeof camera.layers.set !== \"function\") return false;\n return objects.some((obj) => this.hasLayers(obj.object));\n }\n\n private hasLayers(object: any): boolean {\n return object?.layers && typeof object.layers.set === \"function\";\n }\n\n private applyLayerMask(\n objects: I3DObject[],\n lights: Array<{ object: I3DObject }>,\n layer: number\n ): Array<{ object: I3DObject; mask: number }> {\n const restoredMap = new Map<I3DObject, number>();\n const apply = (obj: I3DObject, setMode: \"set\" | \"enable\") => {\n const anyObj = obj as any;\n if (!this.hasLayers(anyObj)) return;\n if (!restoredMap.has(obj)) {\n restoredMap.set(obj, anyObj.layers.mask);\n }\n if (setMode === \"set\") {\n anyObj.layers.set(layer);\n } else {\n anyObj.layers.enable(layer);\n }\n };\n\n objects.forEach((obj) => apply(obj, \"set\"));\n lights.forEach((light) => apply(light.object, \"enable\"));\n\n return Array.from(restoredMap.entries()).map(([object, mask]) => ({ object, mask }));\n }\n\n private restoreLayerMask(entries: Array<{ object: I3DObject; mask: number }>): void {\n entries.forEach((entry) => {\n const anyObj = entry.object as any;\n if (this.hasLayers(anyObj)) {\n anyObj.layers.mask = entry.mask;\n }\n });\n }\n\n private setCameraLayer(camera: any, layer: number): number | null {\n if (!camera?.layers || typeof camera.layers.set !== \"function\") return null;\n const prev = camera.layers.mask;\n camera.layers.set(layer);\n return prev;\n }\n\n private restoreCameraLayer(camera: any, mask: number): void {\n if (camera?.layers) {\n camera.layers.mask = mask;\n }\n }\n}\n","import {\r\n I3DEngine,\r\n I3DObject,\r\n I3DMaterial,\r\n I3DGeometry,\r\n I3DQuaternion,\r\n I3DVector3,\r\n I3DEuler,\r\n I3DMatrix4,\r\n I3DBox3,\r\n} from \"./abstractions/I3DEngine\";\r\n\r\nexport class String3DObject {\n public id: string;\n public type: string;\n private _object: I3DObject;\n private _material?: I3DMaterial;\n private _geometry?: I3DGeometry;\n private _texture?: any;\n private _uniforms: Record<string, { value: any }> = {};\r\n private _originalBoundingBox?: I3DBox3 | null;\r\n private _quaternion: I3DQuaternion;\r\n private _originalSize: I3DVector3;\r\n private _bbox: I3DBox3;\r\n public el: any;\r\n private _children: String3DObject[] = [];\n private _flatObjectsCache: I3DObject[] | null = null;\n private _subtreeCache: I3DObject[] | null = null;\n private engine: I3DEngine;\r\n\r\n public get children(): String3DObject[] {\r\n return this._children;\r\n }\r\n\r\n constructor(\n id: string,\n type: string,\n object: I3DObject,\n engine: I3DEngine,\n options: { material?: I3DMaterial; geometry?: I3DGeometry; texture?: any } = {}\n ) {\n this.id = id;\n this.type = type;\n this._object = object;\n this.engine = engine;\n this._material = options.material;\n this._geometry = options.geometry;\n this._texture = options.texture;\n this._quaternion = engine.createQuaternion();\n this._originalSize = engine.createVector3();\n this._bbox = engine.createBox3();\n this.updateBoundingBox();\n }\n\r\n public get object(): I3DObject {\r\n return this._object;\r\n }\r\n\r\n public get material(): I3DMaterial | undefined {\r\n return this._material;\r\n }\r\n\r\n public get originalSize(): I3DVector3 {\r\n return this._originalSize.clone();\r\n }\r\n\r\n public get boundingBox(): I3DBox3 {\r\n return this._bbox.clone();\r\n }\r\n\r\n public addChild(child: String3DObject): void {\n this._children.push(child);\n this.object.add(child.object);\n this.invalidateFlatCache();\n this.invalidateSubtreeCache();\n }\n\r\n public getWorldMatrix(): I3DMatrix4 {\r\n return this._object.matrixWorld.clone();\r\n }\r\n\r\n public getWorldPosition(): I3DVector3 {\r\n return this.engine.createVector3().setFromMatrixPosition(this._object.matrixWorld);\r\n }\r\n\r\n public getOriginalBoundingBox(): I3DBox3 {\r\n if (!this._originalBoundingBox) {\r\n const originalScale = this.object.scale.clone();\r\n this.object.scale.set(1, 1, 1);\r\n this.object.updateMatrixWorld(true);\r\n this._originalBoundingBox = this.engine.computeBoundingBoxRecursively(this.object);\r\n this.object.scale.copy(originalScale);\r\n this.object.updateMatrixWorld(true);\r\n }\r\n return this._originalBoundingBox!.clone();\r\n }\r\n\r\n public syncTransformFromMatrix(matrix: I3DMatrix4): void {\r\n const pos = this.engine.createVector3();\r\n const quat = this.engine.createQuaternion();\r\n const scale = this.engine.createVector3();\r\n matrix.decompose(pos, quat, scale);\r\n this._object.position.copy(pos);\r\n this._object.quaternion.copy(quat);\r\n this._object.scale.copy(scale);\r\n this._object.updateMatrix();\r\n this._object.updateMatrixWorld();\r\n }\r\n\r\n public applyWorldTransform(\r\n position: I3DVector3,\r\n quaternion: I3DQuaternion,\r\n scale: I3DVector3\r\n ): void {\r\n this._object.position.copy(position);\r\n this._object.quaternion.copy(quaternion);\r\n this._object.scale.copy(scale);\r\n this._object.updateMatrix();\r\n this._object.updateMatrixWorld();\r\n }\r\n\r\n public set quaternion(quaternion: I3DQuaternion) {\r\n this._quaternion.copy(quaternion);\r\n this._object.quaternion.copy(this._quaternion);\r\n this._object.updateMatrixWorld();\r\n }\r\n\r\n public set position(position: I3DVector3) {\r\n this._object.position.copy(position);\r\n }\r\n\r\n public set scale(scale: I3DVector3) {\r\n this._object.scale.copy(scale);\r\n }\r\n\r\n public set rotation(euler: I3DEuler) {\r\n this._object.rotation.copy(euler);\r\n }\r\n\r\n public set opacity(value: number) {\r\n const mat = this._object as any;\r\n if (mat.material && \"opacity\" in mat.material) {\r\n mat.material.opacity = value;\r\n }\r\n }\r\n\r\n public set metalness(value: number) {\r\n const mat = this._object as any;\r\n if (mat.material && \"metalness\" in mat.material) {\r\n mat.material.metalness = value;\r\n }\r\n }\r\n\r\n public set roughness(value: number) {\r\n const mat = this._object as any;\r\n if (mat.material && \"roughness\" in mat.material) {\r\n mat.material.roughness = value;\r\n }\r\n }\r\n\r\n public set texture(texture: any) {\n this._texture = texture;\n if ((this._object as any).isMesh && texture?.applyTexture) {\n texture.applyTexture(this._object);\n }\n }\n\n public set material(material: I3DMaterial | undefined) {\n this._material = material;\n }\n\n public set geometry(geometry: I3DGeometry | undefined) {\n this._geometry = geometry;\n }\n\n public updateBoundingBox(): void {\n this._bbox.setFromObject(this._object);\n this._bbox.getSize(this._originalSize);\n }\n\n public destroy(): void {\n this.disposeObjectResources(this._object);\n this._texture?.dispose?.();\n this._material?.dispose();\n this._geometry?.dispose();\n this._subtreeCache = null;\n }\n\n public getFlatObjects(): I3DObject[] {\n if (this._flatObjectsCache) return this._flatObjectsCache;\n const result: I3DObject[] = [];\n const walk = (obj: String3DObject): void => {\n result.push(obj.object);\n obj.children.forEach((child) => walk(child));\n };\n walk(this);\n this._flatObjectsCache = result;\n return result;\n }\n\n public getSubtreeObjects(): I3DObject[] {\n if (this._subtreeCache) return this._subtreeCache;\n const result: I3DObject[] = [];\n const anyObj = this._object as any;\n result.push(this._object);\n if (typeof anyObj.traverse === \"function\") {\n anyObj.traverse((child: any) => {\n if (child && child !== this._object) {\n result.push(child as I3DObject);\n }\n });\n }\n this._subtreeCache = result;\n return result;\n }\n\n private invalidateFlatCache(): void {\n this._flatObjectsCache = null;\n }\n\n private invalidateSubtreeCache(): void {\n this._subtreeCache = null;\n }\n\n private disposeObjectResources(object: I3DObject): void {\n const anyObj = object as any;\n if (anyObj?.geometry?.dispose) {\n anyObj.geometry.dispose();\n }\n const material = anyObj?.material;\n if (Array.isArray(material)) {\n material.forEach((mat) => mat?.dispose?.());\n } else if (material?.dispose) {\n material.dispose();\n }\n if (typeof anyObj?.traverse === \"function\") {\n anyObj.traverse((child: any) => {\n if (child?.geometry?.dispose) {\n child.geometry.dispose();\n }\n const childMat = child?.material;\n if (Array.isArray(childMat)) {\n childMat.forEach((mat: any) => mat?.dispose?.());\n } else if (childMat?.dispose) {\n childMat.dispose();\n }\n });\n }\n }\n}\n","export class StyleReader {\n private styleMap: any;\n private style: CSSStyleDeclaration;\n\n constructor(el: HTMLElement) {\n this.styleMap = (el as any).computedStyleMap?.();\n this.style = getComputedStyle(el);\n }\n\n readNumber(prop: string, fallback: number): number {\n const mapValue = this.styleMap?.get?.(prop);\n if (mapValue !== undefined && mapValue !== null) {\n const val = typeof mapValue === \"object\" ? (mapValue as any).value : mapValue;\n const num = typeof val === \"number\" ? val : Number.parseFloat(val);\n if (!Number.isNaN(num)) return num;\n }\n const num = Number.parseFloat(this.style.getPropertyValue(prop));\n return Number.isNaN(num) ? fallback : num;\n }\n\n readString(prop: string, fallback = \"\"): string {\n const mapValue = this.styleMap?.get?.(prop);\n const val = mapValue && typeof mapValue === \"object\" ? (mapValue as any).value : mapValue;\n if (typeof val === \"string\") return this.stripQuotes(val.trim()) || fallback;\n const raw = this.style.getPropertyValue(prop).trim();\n return this.stripQuotes(raw) || fallback;\n }\n\n private stripQuotes(value: string): string {\n if (\n (value.startsWith(\"'\") && value.endsWith(\"'\")) ||\n (value.startsWith('\"') && value.endsWith('\"'))\n ) {\n return value.slice(1, -1);\n }\n return value;\n }\n\n readBoolean(prop: string, fallback = false): boolean {\n const raw = this.readString(prop, \"\");\n if (!raw) return fallback;\n const norm = raw.toLowerCase();\n return norm === \"true\" || norm === \"1\" || norm === \"yes\"\n ? true\n : norm === \"false\" || norm === \"0\" || norm === \"no\"\n ? false\n : fallback;\n }\n}\n\nexport function readNumberStyle(el: HTMLElement, prop: string, fallback: number): number {\n const styleMap = (el as any).computedStyleMap?.();\n const mapValue = styleMap?.get?.(prop);\n if (mapValue !== undefined) {\n if (typeof mapValue === \"number\") return mapValue;\n if (typeof mapValue === \"string\") {\n const parsed = Number.parseFloat(mapValue);\n if (!Number.isNaN(parsed)) return parsed;\n }\n if (mapValue && typeof mapValue === \"object\") {\n const value = (mapValue as any).value;\n if (typeof value === \"number\") return value;\n if (typeof value === \"string\") {\n const parsed = Number.parseFloat(value);\n if (!Number.isNaN(parsed)) return parsed;\n }\n }\n }\n\n const style = getComputedStyle(el);\n const raw = style.getPropertyValue(prop);\n const parsed = Number.parseFloat(raw);\n return Number.isNaN(parsed) ? fallback : parsed;\n}\n\nfunction stripQuotes(value: string): string {\n if (\n (value.startsWith(\"'\") && value.endsWith(\"'\")) ||\n (value.startsWith('\"') && value.endsWith('\"'))\n ) {\n return value.slice(1, -1);\n }\n return value;\n}\n\nexport function readStringStyle(el: HTMLElement, prop: string, fallback = \"\"): string {\n const styleMap = (el as any).computedStyleMap?.();\n const mapValue = styleMap?.get?.(prop);\n if (typeof mapValue === \"string\") {\n return stripQuotes(mapValue.trim());\n }\n if (mapValue && typeof mapValue === \"object\") {\n const value = (mapValue as any).value;\n if (typeof value === \"string\") {\n return stripQuotes(value.trim());\n }\n }\n const style = getComputedStyle(el).getPropertyValue(prop);\n const result = style ? stripQuotes(style.trim()) : \"\";\n return result || fallback;\n}\n\nexport function readBooleanStyle(el: HTMLElement, prop: string, fallback = false): boolean {\n const raw = readStringStyle(el, prop, \"\");\n if (!raw) return fallback;\n const normalized = raw.toLowerCase().trim();\n if (normalized === \"true\" || normalized === \"1\" || normalized === \"yes\") return true;\n if (normalized === \"false\" || normalized === \"0\" || normalized === \"no\") return false;\n return fallback;\n}\n\nexport function readFilterRaw(el: HTMLElement): string {\n const styleMap = (el as any).computedStyleMap?.();\n let raw = \"\";\n const mapValue = styleMap?.get?.(\"--filter\");\n if (mapValue !== undefined) {\n if (typeof mapValue === \"string\") {\n raw = mapValue;\n } else if (mapValue && typeof mapValue === \"object\") {\n const value = (mapValue as any).value;\n if (typeof value === \"string\") raw = value;\n }\n }\n if (!raw) {\n raw = getComputedStyle(el).getPropertyValue(\"--filter\") || \"\";\n }\n raw = raw.trim();\n return raw;\n}\n","export type UniformType =\n | \"float\"\n | \"int\"\n | \"vec2\"\n | \"vec3\"\n | \"vec4\"\n | \"color\"\n | \"texture\"\n | \"mat3\"\n | \"mat4\";\n\nexport type UniformDefinition = {\n type: UniformType;\n value: any;\n css?: string;\n};\n\nexport type ShaderInjectionPoint =\n | \"vertex_pars\"\n | \"vertex_header\"\n | \"vertex_transform\"\n | \"vertex_output\"\n | \"fragment_pars\"\n | \"fragment_header\"\n | \"fragment_color\"\n | \"fragment_normal\"\n | \"fragment_emissive\"\n | \"fragment_output\";\n\nexport type ShaderInjection = {\n point: ShaderInjectionPoint;\n code: string;\n order?: number;\n};\n\nexport type MaterialBlendMode = \"normal\" | \"additive\" | \"subtractive\" | \"multiply\";\nexport type MaterialSide = \"front\" | \"back\" | \"double\";\n\nexport type String3DCustomMaterialDefinition = {\n name: string;\n\n extends?: \"basic\" | \"standard\" | \"physical\" | \"shader\";\n\n vertexShader?: string;\n fragmentShader?: string;\n\n injections?: ShaderInjection[];\n\n uniforms?: Record<string, UniformDefinition>;\n\n properties?: {\n transparent?: boolean;\n side?: MaterialSide;\n depthWrite?: boolean;\n depthTest?: boolean;\n blending?: MaterialBlendMode;\n wireframe?: boolean;\n };\n\n lights?: boolean;\n\n parse?: (element: HTMLElement, style: CSSStyleDeclaration) => Record<string, any>;\n};\n\nexport class String3DCustomMaterialRegistry {\n private static materials: Map<string, String3DCustomMaterialDefinition> = new Map();\n private static registeredCssVars: Set<string> = new Set();\n\n static register(definition: String3DCustomMaterialDefinition): void {\n const name = definition.name.trim().toLowerCase();\n if (!name) {\n throw new Error(\"[String3D] Custom material name is required.\");\n }\n if (this.materials.has(name)) {\n console.warn(`[String3D] Material \"${name}\" already registered. Overwriting.`);\n }\n this.materials.set(name, { ...definition, name });\n this.registerCssVarsForMaterial(definition);\n }\n\n private static registerCssVarsForMaterial(definition: String3DCustomMaterialDefinition): void {\n const css = (globalThis as any).CSS;\n if (!css?.registerProperty) return;\n\n const uniforms = definition.uniforms || {};\n for (const def of Object.values(uniforms)) {\n const cssVar = def.css?.trim();\n if (!cssVar || !cssVar.startsWith(\"--\")) continue;\n if (this.registeredCssVars.has(cssVar)) continue;\n\n const syntax = this.resolveCssSyntax(def.type);\n\n try {\n css.registerProperty({\n name: cssVar,\n syntax,\n inherits: false,\n initialValue: this.defaultCssInitialValue(def),\n });\n this.registeredCssVars.add(cssVar);\n } catch (err) {\n console.warn(`[String3D] Failed to register CSS property ${cssVar}:`, err);\n }\n }\n }\n\n private static resolveCssSyntax(type: UniformType): string {\n switch (type) {\n case \"color\":\n return \"<color>\";\n case \"float\":\n case \"int\":\n return \"<number>\";\n default:\n return \"*\";\n }\n }\n\n private static defaultCssInitialValue(def: UniformDefinition): string {\n if (def.type === \"color\") {\n if (typeof def.value === \"string\") return def.value;\n return \"#000000\";\n }\n if (def.type === \"float\" || def.type === \"int\") {\n return typeof def.value === \"number\" ? String(def.value) : \"0\";\n }\n return \"initial\";\n }\n\n static get(name: string): String3DCustomMaterialDefinition | undefined {\n return this.materials.get(name.trim().toLowerCase());\n }\n\n static has(name: string): boolean {\n return this.materials.has(name.trim().toLowerCase());\n }\n\n static list(): String3DCustomMaterialDefinition[] {\n return Array.from(this.materials.values());\n }\n\n static unregister(name: string): boolean {\n return this.materials.delete(name.trim().toLowerCase());\n }\n}\n","import type {\n String3DCustomMaterialDefinition,\n UniformDefinition,\n ShaderInjection,\n} from \"./String3DCustomMaterial\";\n\nexport type MaterialUpdateCallback = (uniforms: Record<string, any>) => void;\n\nexport interface IMaterialInstance {\n material: any;\n definition: String3DCustomMaterialDefinition;\n update: MaterialUpdateCallback;\n dispose: () => void;\n}\n\nexport interface IMaterialFactory {\n supports(definition: String3DCustomMaterialDefinition): boolean;\n\n create(\n definition: String3DCustomMaterialDefinition,\n initialUniforms?: Record<string, any>\n ): IMaterialInstance;\n\n parseUniformsFromCSS(\n definition: String3DCustomMaterialDefinition,\n element: HTMLElement,\n style: CSSStyleDeclaration\n ): Record<string, any>;\n}\n\nexport function parseUniformValue(\n def: UniformDefinition,\n cssValue: string | null | undefined\n): any {\n if (cssValue === null || cssValue === undefined || cssValue === \"\" || cssValue === \"none\") {\n return def.value;\n }\n\n const trimmed = cssValue.trim();\n\n switch (def.type) {\n case \"float\":\n case \"int\": {\n const num = parseFloat(trimmed);\n return isNaN(num) ? def.value : num;\n }\n case \"vec2\": {\n const parts = trimmed.split(/[\\s,]+/).map((s) => parseFloat(s.trim()));\n if (parts.length >= 2 && parts.every((n) => !isNaN(n))) {\n return [parts[0], parts[1]];\n }\n return def.value;\n }\n case \"vec3\": {\n const parts = trimmed.split(/[\\s,]+/).map((s) => parseFloat(s.trim()));\n if (parts.length >= 3 && parts.every((n) => !isNaN(n))) {\n return [parts[0], parts[1], parts[2]];\n }\n return def.value;\n }\n case \"vec4\": {\n const parts = trimmed.split(/[\\s,]+/).map((s) => parseFloat(s.trim()));\n if (parts.length >= 4 && parts.every((n) => !isNaN(n))) {\n return [parts[0], parts[1], parts[2], parts[3]];\n }\n return def.value;\n }\n case \"color\": {\n return parseColorValue(trimmed) ?? def.value;\n }\n case \"texture\": {\n const match = trimmed.match(/url\\(['\"]?(.*?)['\"]?\\)/);\n return match ? match[1] : trimmed || def.value;\n }\n default:\n return def.value;\n }\n}\n\nfunction parseColorValue(value: string): [number, number, number] | null {\n if (value.startsWith(\"#\")) {\n const hex = value.slice(1);\n if (hex.length === 3) {\n const r = parseInt(hex[0] + hex[0], 16) / 255;\n const g = parseInt(hex[1] + hex[1], 16) / 255;\n const b = parseInt(hex[2] + hex[2], 16) / 255;\n return [r, g, b];\n }\n if (hex.length === 6) {\n const r = parseInt(hex.slice(0, 2), 16) / 255;\n const g = parseInt(hex.slice(2, 4), 16) / 255;\n const b = parseInt(hex.slice(4, 6), 16) / 255;\n return [r, g, b];\n }\n }\n\n const rgbMatch = value.match(/rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)/);\n if (rgbMatch) {\n return [parseInt(rgbMatch[1]) / 255, parseInt(rgbMatch[2]) / 255, parseInt(rgbMatch[3]) / 255];\n }\n\n return null;\n}\n\nexport function collectUniformsFromCSS(\n definition: String3DCustomMaterialDefinition,\n element: HTMLElement,\n style: CSSStyleDeclaration\n): Record<string, any> {\n const result: Record<string, any> = {};\n\n if (definition.parse) {\n const parsed = definition.parse(element, style);\n Object.assign(result, parsed);\n }\n\n if (definition.uniforms) {\n for (const [key, def] of Object.entries(definition.uniforms)) {\n if (def.css) {\n const cssValue = style.getPropertyValue(def.css).trim();\n result[key] = parseUniformValue(def, cssValue);\n } else if (!(key in result)) {\n result[key] = def.value;\n }\n }\n }\n\n return result;\n}\n\nexport function mergeInjections(injections: ShaderInjection[]): Map<string, string> {\n const grouped = new Map<string, ShaderInjection[]>();\n\n for (const injection of injections) {\n const list = grouped.get(injection.point) || [];\n list.push(injection);\n grouped.set(injection.point, list);\n }\n\n const result = new Map<string, string>();\n\n for (const [point, list] of grouped) {\n const sorted = list.sort((a, b) => (a.order ?? 0) - (b.order ?? 0));\n result.set(point, sorted.map((i) => i.code).join(\"\\n\"));\n }\n\n return result;\n}\n","import {\r\n I3DEngine,\r\n I3DScene,\r\n I3DLight,\r\n I3DMaterial,\r\n I3DModelLoader,\r\n I3DVector3,\r\n} from \"./abstractions/I3DEngine\";\r\nimport { String3DObject } from \"./String3DObject\";\r\nimport { StringObject } from \"@fiddle-digital/string-tune\";\r\nimport { readBooleanStyle, readNumberStyle, readStringStyle } from \"../modules/string3d/styleUtils\";\r\nimport { String3DCustomMaterialRegistry, IMaterialInstance } from \"./materials\";\r\n\r\nexport interface String3DSceneOptions {\r\n modelLoader?: I3DModelLoader;\r\n modelLoaderFactory?: (engine: I3DEngine, type?: string) => I3DModelLoader;\r\n}\r\n\r\nexport class String3DScene {\r\n private _scene: I3DScene;\r\n private _objects: Map<string, String3DObject> = new Map();\r\n private _rootObjects: String3DObject[] = [];\r\n private _elementMap: Map<string, HTMLElement> = new Map();\r\n private _materialInstances: Map<string, IMaterialInstance> = new Map();\r\n private engine: I3DEngine;\r\n private _modelLoader?: I3DModelLoader;\r\n private _modelLoaderFactory?: (engine: I3DEngine, type?: string) => I3DModelLoader;\r\n private _modelLoaderCache: Map<string, I3DModelLoader> = new Map();\r\n\r\n public get rootObjects(): String3DObject[] {\r\n return this._rootObjects;\r\n }\r\n\r\n constructor(engine: I3DEngine, options: String3DSceneOptions = {}) {\r\n this.engine = engine;\r\n this._modelLoader = options.modelLoader;\r\n this._modelLoaderFactory = options.modelLoaderFactory;\r\n this._scene = engine.createScene();\r\n }\r\n\r\n public getScene(): I3DScene {\r\n return this._scene;\r\n }\r\n\r\n public getObject(id: string): String3DObject | undefined {\r\n return this._objects.get(id);\r\n }\r\n\r\n public getAllObjects(): String3DObject[] {\r\n const result: String3DObject[] = [];\r\n const walk = (obj: String3DObject): void => {\r\n result.push(obj);\r\n obj.children.forEach((child) => walk(child));\r\n };\r\n this._rootObjects.forEach((obj) => walk(obj));\r\n return result;\r\n }\r\n\r\n public hasObject(id: string): boolean {\r\n return this._objects.has(id);\r\n }\r\n\r\n public deleteObject(id: string): boolean {\n const obj = this._objects.get(id);\n if (obj) {\n this._scene.remove(obj.object);\n this._objects.delete(id);\n this._elementMap.delete(id);\n this._rootObjects = this._rootObjects.filter((root) => root !== obj);\n obj.destroy();\n return true;\n }\n return false;\n }\n\r\n public createFromElement(object: StringObject): void {\r\n const type = object.getProperty<string>(\"3d\");\r\n if (!type) return;\r\n\r\n const element = object.htmlElement;\r\n if (!element) return;\r\n\r\n const onAdd = (added3DObject: String3DObject) => {\r\n if (added3DObject) {\r\n const parentId = object.getProperty<string>(\"parentId\");\r\n if (parentId == null) {\r\n this._scene.add(added3DObject.object);\r\n this._rootObjects.push(added3DObject);\r\n } else {\r\n this._objects.get(parentId)?.addChild(added3DObject);\r\n }\r\n this._objects.set(object.id, added3DObject);\r\n this._elementMap.set(object.id, element);\r\n added3DObject.el = element;\r\n }\r\n };\r\n\r\n switch (type) {\r\n case \"group\":\r\n this.createGroup(object, onAdd);\r\n break;\r\n case \"pointLight\":\r\n this.createLight(object, \"point\", onAdd);\r\n break;\r\n case \"ambientLight\":\r\n this.createLight(object, \"ambient\", onAdd);\r\n break;\r\n case \"directionalLight\":\r\n this.createLight(object, \"directional\", onAdd);\r\n break;\r\n case \"spotLight\":\r\n this.createLight(object, \"spot\", onAdd);\r\n break;\r\n case \"hemisphereLight\":\r\n this.createLight(object, \"hemisphere\", onAdd);\r\n break;\r\n case \"model\":\r\n this.createModel(object, onAdd);\r\n break;\r\n case \"box\":\r\n this.createBox(object, onAdd);\r\n break;\r\n case \"sphere\":\r\n this.createSphere(object, onAdd);\r\n break;\r\n case \"plane\":\r\n this.createPlane(object, onAdd);\r\n break;\r\n case \"cylinder\":\n this.createCylinder(object, onAdd);\n break;\n case \"particles\":\n this.createParticles(object, onAdd);\n break;\n case \"text\":\n this.createText(object, onAdd);\n break;\n }\n }\n\r\n private createGroup(object: StringObject, onAdd: (obj: String3DObject) => void): String3DObject {\r\n const group = this.engine.createGroup();\r\n const obj = new String3DObject(object.id, \"group\", group, this.engine);\r\n onAdd(obj);\r\n return obj;\r\n }\r\n\r\n private createLight(\r\n object: StringObject,\r\n kind: \"point\" | \"ambient\" | \"directional\" | \"spot\" | \"hemisphere\",\r\n onAdd: (obj: String3DObject) => void\r\n ): String3DObject {\r\n const element = object.htmlElement;\r\n const colorRaw = element ? readStringStyle(element, \"--light-color\", \"#ffffff\") : \"#ffffff\";\r\n const color = colorRaw && colorRaw !== \"none\" ? colorRaw : \"#ffffff\";\r\n const intensity = element ? readNumberStyle(element, \"--light-intensity\", 1) : 1;\r\n\r\n let light: I3DLight;\r\n if (kind === \"point\") {\r\n const distance = element ? readNumberStyle(element, \"--light-distance\", 1000) : 1000;\r\n const decay = element ? readNumberStyle(element, \"--light-decay\", 0) : 0;\r\n light = this.engine.createPointLight(color, intensity, distance, decay);\r\n } else if (kind === \"directional\") {\r\n light = this.engine.createDirectionalLight(color, intensity);\r\n } else if (kind === \"spot\") {\r\n const distance = element ? readNumberStyle(element, \"--light-distance\", 0) : 0;\r\n const angle = element ? readNumberStyle(element, \"--light-angle\", Math.PI / 3) : Math.PI / 3;\r\n const penumbra = element ? readNumberStyle(element, \"--light-penumbra\", 0) : 0;\r\n const decay = element ? readNumberStyle(element, \"--light-decay\", 1) : 1;\r\n light = this.engine.createSpotLight(color, intensity, distance, angle, penumbra, decay);\r\n } else if (kind === \"hemisphere\") {\r\n const groundRaw = element\r\n ? readStringStyle(element, \"--light-ground-color\", \"#ffffff\")\r\n : \"#ffffff\";\r\n const groundColor = groundRaw && groundRaw !== \"none\" ? groundRaw : \"#ffffff\";\r\n light = this.engine.createHemisphereLight(color, groundColor, intensity);\r\n } else {\r\n light = this.engine.createAmbientLight(color, intensity);\r\n }\r\n\r\n const castShadow = element ? readBooleanStyle(element, \"--shadow-cast\", false) : false;\r\n if (castShadow && light.shadow) {\r\n light.castShadow = true;\r\n const bias = element ? readNumberStyle(element, \"--shadow-bias\", 0) : 0;\r\n const mapSize = element ? readNumberStyle(element, \"--shadow-map-size\", 512) : 512;\r\n light.shadow.bias = bias;\r\n light.shadow.mapSize.width = mapSize;\r\n light.shadow.mapSize.height = mapSize;\r\n }\r\n\r\n const obj = new String3DObject(object.id, kind + \"Light\", light, this.engine);\r\n onAdd(obj);\r\n return obj;\r\n }\r\n\r\n private applyShadowProps(object: StringObject, mesh: any): void {\r\n const element = object.htmlElement;\r\n const castShadow = element ? readBooleanStyle(element, \"--shadow-cast\", false) : false;\r\n const receiveShadow = element ? readBooleanStyle(element, \"--shadow-receive\", false) : false;\r\n mesh.castShadow = castShadow;\r\n mesh.receiveShadow = receiveShadow;\r\n }\r\n\r\n private createBox(object: StringObject, onAdd: (obj: String3DObject) => void): String3DObject {\r\n const geometry = this.engine.createBoxGeometry(1, 1, 1);\r\n const material = this.createMaterialFromObject(object);\r\n const mesh = this.engine.createMesh(geometry, material);\r\n this.applyShadowProps(object, mesh);\r\n const obj = new String3DObject(object.id, \"box\", mesh, this.engine, {\r\n geometry,\r\n material,\r\n });\r\n onAdd(obj);\r\n return obj;\r\n }\r\n\r\n private createSphere(object: StringObject, onAdd: (obj: String3DObject) => void): String3DObject {\n const quality = this.getGeometryQuality(object.htmlElement);\n const widthSegments = Math.max(3, Math.round(32 * quality));\n const heightSegments = Math.max(2, Math.round(32 * quality));\n const geometry = this.engine.createSphereGeometry(0.5, widthSegments, heightSegments);\n const material = this.createMaterialFromObject(object);\n const mesh = this.engine.createMesh(geometry, material);\n this.applyShadowProps(object, mesh);\n const obj = new String3DObject(object.id, \"sphere\", mesh, this.engine, {\n geometry,\r\n material,\r\n });\r\n onAdd(obj);\r\n return obj;\r\n }\r\n\r\n private createPlane(object: StringObject, onAdd: (obj: String3DObject) => void): String3DObject {\r\n const geometry = this.engine.createPlaneGeometry(1, 1);\r\n const material = this.createMaterialFromObject(object);\r\n const mesh = this.engine.createMesh(geometry, material);\r\n this.applyShadowProps(object, mesh);\r\n const obj = new String3DObject(object.id, \"plane\", mesh, this.engine, {\r\n geometry,\r\n material,\r\n });\r\n onAdd(obj);\r\n return obj;\r\n }\r\n\r\n private createCylinder(\n object: StringObject,\n onAdd: (obj: String3DObject) => void\n ): String3DObject {\n const quality = this.getGeometryQuality(object.htmlElement);\n const segments = Math.max(3, Math.round(32 * quality));\n const geometry = this.engine.createCylinderGeometry(0.5, 0.5, 1, segments);\n const material = this.createMaterialFromObject(object);\n const mesh = this.engine.createMesh(geometry, material);\n this.applyShadowProps(object, mesh);\n const obj = new String3DObject(object.id, \"cylinder\", mesh, this.engine, {\n geometry,\r\n material,\r\n });\r\n onAdd(obj);\r\n return obj;\r\n }\r\n\r\n private createModel(object: StringObject, onAdd: (obj: String3DObject) => void): void {\n const modelPath = object.getProperty<string>(\"3d-model\");\r\n if (!modelPath) return;\r\n\r\n const loaderType = object.getProperty<string>(\"3d-model-loader\") || undefined;\r\n const loader = this.resolveModelLoader(loaderType);\r\n if (!loader) {\r\n console.warn(\"[String3D] Model loader not configured\");\r\n return;\r\n }\r\n\r\n const element = object.htmlElement;\r\n if (element) {\r\n this.applyModelTextureRemap(loader, element);\r\n }\r\n const shouldCenter = object.getProperty<boolean>(\"3d-model-center\") ?? false;\r\n\r\n loader.load(\r\n modelPath,\r\n (gltf: any) => {\r\n const root = gltf?.scene || gltf?.object || gltf;\r\n if (!root) {\r\n console.warn(\"[String3D] Model loader returned empty result\");\r\n return;\r\n }\r\n\r\n const overrideMaterial =\r\n element && this.shouldOverrideModelMaterial(element)\r\n ? this.createMaterialFromElement(element, object)\r\n : null;\r\n\r\n if (typeof root.traverse === \"function\") {\r\n root.traverse((child: any) => {\r\n if (child.isMesh) {\r\n if (overrideMaterial) {\r\n child.material = overrideMaterial;\r\n }\r\n this.applyShadowProps(object, child);\r\n }\r\n });\r\n }\r\n\r\n if (shouldCenter) {\r\n this.centerObject(root);\r\n }\r\n const obj = new String3DObject(object.id, \"model\", root, this.engine);\r\n onAdd(obj);\r\n },\r\n (xhr: any) => {\r\n console.log((xhr.loaded / xhr.total) * 100 + \"% loaded\");\r\n },\r\n (error: any) => {\r\n console.error(\"[String3D] Model loading error:\", error);\r\n }\r\n );\r\n }\n\n private createParticles(object: StringObject, onAdd: (obj: String3DObject) => void): void {\n if (!this.engine.createParticleSystem) {\n console.warn(\"[String3D] Particle system not supported by engine.\");\n return;\n }\n\n const element = object.htmlElement;\n const config: import(\"./abstractions/I3DEngine\").ParticleSystemConfig = {\n mode: \"emitter\",\n count: 300,\n size: 2,\n color: \"#ffffff\",\n opacity: 1,\n spread: 120,\n seed: 1,\n emitRate: 30,\n emitBurst: 0,\n particleLife: 2.5,\n particleSpeed: 40,\n particleDirection: [0, 1, 0] as [number, number, number],\n particleGravity: [0, -30, 0] as [number, number, number],\n particleDrag: 0.1,\n particleSizeVariation: 0.6,\n particleColorVariation: 0.2,\n particleShape: \"sphere\",\n particleModelUrl: \"\",\n particleModelLoader: \"\",\n particleModelNode: \"\",\n instanceShape: \"sphere\",\n instanceModelUrl: \"\",\n instanceModelLoader: \"\",\n instanceModelNode: \"\",\n instanceScale: 1,\n instanceScaleVariation: 0.5,\n instanceRotationSpeed: 0.4,\n instanceJitter: 0.2,\n instanceFlow: 0.3,\n instanceDisperse: 0,\n instanceDisperseScatter: 0,\n instanceDisperseScatterX: 0,\n instanceDisperseScatterY: 0,\n instanceDisperseScatterZ: 0,\n };\n\n const system = this.engine.createParticleSystem(config);\n const obj = new String3DObject(object.id, \"particles\", system, this.engine);\n onAdd(obj);\n }\n\n private createText(object: StringObject, onAdd: (obj: String3DObject) => void): void {\n if (!this.engine.createTextGeometry) {\n console.warn(\"[String3D] Text geometry not supported by engine.\");\n return;\n }\n\n const geometry = this.engine.createBoxGeometry(1, 1, 1);\n const material = this.createMaterialFromObject(object);\n const mesh = this.engine.createMesh(geometry, material);\n this.applyShadowProps(object, mesh);\n\n const group = this.engine.createGroup();\n (group as any).__textMesh = mesh;\n group.add(mesh);\n\n const obj = new String3DObject(object.id, \"text\", group, this.engine, {\n geometry,\n material,\n });\n onAdd(obj);\n }\n\n private getGeometryQuality(element?: HTMLElement | null): number {\n if (!element) return 1;\n const quality = readNumberStyle(element, \"--geometry-quality\", 1);\n if (!Number.isFinite(quality) || quality <= 0) return 1;\n return quality;\n }\n\r\n private resolveModelLoader(type?: string): I3DModelLoader | undefined {\r\n if (type) {\r\n if (this._modelLoaderCache.has(type)) {\r\n return this._modelLoaderCache.get(type);\r\n }\r\n if (!this._modelLoaderFactory) {\r\n console.warn(`[String3D] No model loader factory for type \"${type}\"`);\r\n return undefined;\r\n }\r\n const loader = this._modelLoaderFactory(this.engine, type);\r\n this._modelLoaderCache.set(type, loader);\r\n return loader;\r\n }\r\n\r\n if (this._modelLoader) {\r\n return this._modelLoader;\r\n }\r\n\r\n if (this._modelLoaderFactory) {\r\n return this._modelLoaderFactory(this.engine);\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n private centerObject(object: any): void {\r\n if (!object) return;\r\n const bbox = this.engine.computeBoundingBoxRecursively(object);\r\n const center = this.getBoxCenter(bbox);\r\n if (object.position?.set) {\r\n object.position.set(-center.x, -center.y, -center.z);\r\n }\r\n object.updateMatrixWorld(true);\r\n }\r\n\r\n private getBoxCenter(box: any): I3DVector3 {\r\n const center = this.engine.createVector3();\r\n center.x = (box.min.x + box.max.x) / 2;\r\n center.y = (box.min.y + box.max.y) / 2;\r\n center.z = (box.min.z + box.max.z) / 2;\r\n return center;\r\n }\r\n\r\n private createMaterialFromObject(object: StringObject): I3DMaterial {\r\n return this.createMaterialFromElement(object.htmlElement, object);\r\n }\r\n\r\n private createMaterialFromElement(\r\n element: HTMLElement | null,\r\n object?: StringObject\r\n ): I3DMaterial {\r\n const style = element ? getComputedStyle(element) : null;\r\n const getCSS = (prop: string) => (style ? style.getPropertyValue(prop).trim() : \"\");\r\n\r\n const resolve = <T>(cssProp: string, parser: (v: string) => T, defaultValue: T): T => {\r\n const cssVal = getCSS(cssProp);\r\n if (cssVal && cssVal !== \"none\" && cssVal !== \"\") return parser(cssVal);\r\n return defaultValue;\r\n };\r\n\r\n const parseNumber = (v: string) => parseFloat(v);\r\n const parseColor = (v: string) => v;\r\n const parseUrl = (v: string) => {\r\n const match = v.match(/url\\(['\"]?(.*?)['\"]?\\)/);\r\n return match ? match[1] : v;\r\n };\r\n\r\n const type = resolve(\"--material-type\", (v) => v.split(\"[\")[0] || \"basic\", \"basic\");\r\n\r\n const customMaterial = this.tryCreateCustomMaterial(type, element, style, object);\r\n if (customMaterial) {\r\n return customMaterial;\r\n }\r\n\r\n const color = resolve(\"--material-color\", parseColor, \"#ffffff\");\r\n\r\n const opacity = resolve(\"--opacity\", parseNumber, 1);\r\n const metalness = resolve(\"--material-metalness\", parseNumber, 0);\r\n const roughness = resolve(\"--material-roughness\", parseNumber, 1);\r\n const emissive = resolve(\"--material-emissive\", parseColor, \"#000000\");\r\n\r\n const params: any = {\r\n color,\r\n transparent: opacity < 1,\r\n opacity: opacity,\r\n };\r\n\r\n const mapSrc = resolve(\"--texture-map\", parseUrl, \"\");\r\n const normalMapSrc = resolve(\"--texture-normal\", parseUrl, \"\");\r\n const roughnessMapSrc = resolve(\"--texture-roughness\", parseUrl, \"\");\r\n const metalnessMapSrc = resolve(\"--texture-metalness\", parseUrl, \"\");\r\n const aoMapSrc = resolve(\"--texture-ao\", parseUrl, \"\");\r\n\r\n const flipY = this.parseFlipY(element);\r\n const colorSpace = element ? readStringStyle(element, \"--texture-color-space\", \"\") : \"\";\r\n\r\n const hasMaps = !!(mapSrc || normalMapSrc || roughnessMapSrc || metalnessMapSrc || aoMapSrc);\r\n let finalType = type;\r\n if (finalType !== \"standard\" && hasMaps) {\r\n finalType = \"standard\";\r\n }\r\n\r\n if (finalType === \"standard\") {\r\n if (mapSrc) params.map = this.loadTexture(mapSrc, { flipY, colorSpace });\r\n if (normalMapSrc) params.normalMap = this.loadTexture(normalMapSrc, { flipY });\r\n if (roughnessMapSrc) params.roughnessMap = this.loadTexture(roughnessMapSrc, { flipY });\r\n if (metalnessMapSrc) params.metalnessMap = this.loadTexture(metalnessMapSrc, { flipY });\r\n if (aoMapSrc) params.aoMap = this.loadTexture(aoMapSrc, { flipY });\r\n\r\n params.metalness = metalness;\r\n params.roughness = roughness;\r\n params.emissive = emissive;\r\n\r\n return this.engine.createMeshStandardMaterial(params);\r\n }\r\n\r\n return this.engine.createMeshBasicMaterial(params);\r\n }\r\n\r\n private tryCreateCustomMaterial(\r\n type: string,\r\n element: HTMLElement | null,\r\n style: CSSStyleDeclaration | null,\r\n object?: StringObject\r\n ): I3DMaterial | null {\r\n const definition = String3DCustomMaterialRegistry.get(type);\r\n if (!definition) {\r\n return null;\r\n }\r\n\r\n const factory = this.engine.getMaterialFactory?.();\n if (!factory) {\n console.warn(`[String3D] Material factory not available for custom material \"${type}\"`);\n return null;\n }\n if (!factory.supports(definition)) {\n console.warn(`[String3D] Material factory does not support \"${type}\".`);\n return null;\n }\n\r\n let initialUniforms: Record<string, any> = {};\r\n if (element && style) {\r\n initialUniforms = factory.parseUniformsFromCSS(definition, element, style);\r\n }\r\n\r\n const instance = factory.create(definition, initialUniforms);\r\n\r\n if (object) {\r\n this._materialInstances.set(object.id, instance);\r\n }\r\n\r\n return instance.material;\r\n }\r\n\r\n public updateMaterialUniforms(objectId: string, uniforms: Record<string, any>): void {\r\n const instance = this._materialInstances.get(objectId);\r\n if (instance) {\r\n instance.update(uniforms);\r\n }\r\n }\r\n\r\n public getMaterialInstance(objectId: string): IMaterialInstance | undefined {\r\n return this._materialInstances.get(objectId);\r\n }\r\n\r\n private loadTexture(src: string, options: { flipY?: boolean; colorSpace?: string } = {}): any {\r\n const textureLoader = this.engine.createTextureLoader();\r\n const texture = textureLoader.load(src);\r\n if (typeof options.flipY === \"boolean\") {\r\n texture.flipY = options.flipY;\r\n }\r\n const colorSpace = (options.colorSpace || \"\").toLowerCase().trim();\r\n if (colorSpace && \"colorSpace\" in texture) {\r\n texture.colorSpace = colorSpace === \"srgb\" ? \"srgb\" : \"linear\";\r\n }\r\n texture.needsUpdate = true;\r\n return texture;\r\n }\r\n\r\n private parseFlipY(element?: HTMLElement | null): boolean | undefined {\r\n const value = element ? readStringStyle(element, \"--texture-flip-y\", \"\") : \"\";\r\n if (value === undefined || value === null || value === \"\") return undefined;\r\n if (typeof value === \"boolean\") return value;\r\n const normalized = String(value).toLowerCase().trim();\r\n if (normalized === \"false\" || normalized === \"0\" || normalized === \"no\") return false;\r\n if (normalized === \"true\" || normalized === \"1\" || normalized === \"yes\") return true;\r\n return undefined;\r\n }\r\n\r\n private shouldOverrideModelMaterial(element: HTMLElement): boolean {\r\n const style = getComputedStyle(element);\r\n const hasStyle = (prop: string) => {\r\n const val = style.getPropertyValue(prop);\r\n return val && val !== \"0\" && val !== \"none\" && val !== \"\";\r\n };\r\n\r\n if (hasStyle(\"--material-color\") || hasStyle(\"--texture-map\")) return true;\r\n\r\n const cssVars = [\r\n \"--material-type\",\r\n \"--material-metalness\",\r\n \"--material-roughness\",\r\n \"--material-emissive\",\r\n \"--opacity\",\r\n \"--texture-normal\",\r\n \"--texture-roughness\",\r\n \"--texture-metalness\",\r\n \"--texture-ao\",\r\n ];\r\n return cssVars.some((prop) => hasStyle(prop));\r\n }\r\n\r\n private applyModelTextureRemap(loader: any, element: HTMLElement): void {\r\n const baseRaw = (element.getAttribute(\"string-3d-model-texture-base\") || \"\").trim();\r\n const base = baseRaw ? baseRaw.replace(/\\/?$/, \"/\") : \"\";\r\n const mappingRaw = element.getAttribute(\"string-3d-model-textures\");\r\n let mapping: Record<string, string> | null = null;\r\n\r\n if (mappingRaw) {\r\n try {\r\n mapping = JSON.parse(mappingRaw);\r\n } catch (error) {\r\n console.warn(\"[String3D] Invalid model texture mapping JSON:\", error);\r\n }\r\n }\r\n\r\n const manager = loader?.manager;\r\n if (!manager || typeof manager.setURLModifier !== \"function\") {\r\n if (mapping || base) {\r\n console.warn(\"[String3D] Model loader does not support URL remap.\");\r\n }\r\n return;\r\n }\r\n\r\n manager.setURLModifier((url: string) => {\r\n const mapped = mapping && url in mapping ? mapping[url] : url;\r\n if (!base) return mapped;\r\n if (/^(blob:|data:|https?:|file:|\\/)/i.test(mapped)) return mapped;\r\n return base + mapped.replace(/^\\.?\\//, \"\");\r\n });\r\n }\r\n\r\n public destroy(): void {\r\n this._materialInstances.forEach((instance) => instance.dispose());\r\n this._materialInstances.clear();\r\n this._objects.forEach((obj) => obj.destroy());\r\n this._objects.clear();\r\n this._rootObjects = [];\r\n }\r\n}\r\n","import type { SyncContext } from \"./SyncContext\";\n\nexport class StyleBundleCache<T> {\n private cache: WeakMap<HTMLElement, T> = new WeakMap();\n private meta: WeakMap<HTMLElement, { time: number }> = new WeakMap();\n\n get(el: HTMLElement, ctx: SyncContext, reader: (el: HTMLElement) => T): T {\n const canUseCache = !!ctx.dirtySet && ctx.forceSync === false && !ctx.dirtySet.has(el);\n if (canUseCache) {\n const cached = this.cache.get(el);\n if (cached) return cached;\n }\n\n const now = performance.now();\n const interval = Math.max(0, ctx.styleReadIntervalMs ?? 0);\n if (interval > 0) {\n const metaData = this.meta.get(el);\n const cached = this.cache.get(el);\n if (metaData && cached && now - metaData.time < interval) {\n return cached;\n }\n }\n\n const bundle = reader(el);\n this.cache.set(el, bundle);\n this.meta.set(el, { time: now });\n return bundle;\n }\n\n clear(): void {\n this.cache = new WeakMap();\n this.meta = new WeakMap();\n }\n}\n","import { String3DObject } from \"../String3DObject\";\nimport type { String3DObjectSyncStrategy } from \"./String3DObjectSyncStrategy\";\nimport type { SyncContext } from \"./SyncContext\";\nimport { StyleReader } from \"../../modules/string3d/styleUtils\";\nimport { StyleBundleCache } from \"./StyleBundleCache\";\n\nconst DEG_TO_RAD = Math.PI / 180;\n\ntype GroupStyleBundle = {\n translateZ: number;\n scale: number;\n rotateX: number;\n rotateY: number;\n rotateZ: number;\n};\n\nexport class GroupSynchronizer implements String3DObjectSyncStrategy {\n private static styleCache = new StyleBundleCache<GroupStyleBundle>();\n\n sync(el: HTMLElement, object: String3DObject, ctx: SyncContext, parentData: any): any {\n const cached = (el as any).__layoutCache;\n const rect = cached ? cached.rect : el.getBoundingClientRect();\n const bundle = this.readStyleBundle(el, ctx);\n\n const screenCenterX = rect.left + rect.width * 0.5;\n const screenCenterY = rect.top + rect.height * 0.5;\n\n if (ctx.camera.getMode() === \"orthographic\") {\n object.object.position.set(\n screenCenterX - ctx.viewportWidth / 2,\n -(screenCenterY - ctx.viewportHeight / 2),\n bundle.translateZ\n );\n } else {\n const frustum = ctx.camera.getFrustumSizeAt(bundle.translateZ);\n const normalizedX = screenCenterX / ctx.viewportWidth;\n const normalizedY = screenCenterY / ctx.viewportHeight;\n object.object.position.set(\n (normalizedX - 0.5) * frustum.width,\n -(normalizedY - 0.5) * frustum.height,\n bundle.translateZ\n );\n }\n\n object.object.scale.set(bundle.scale, bundle.scale, bundle.scale);\n\n object.object.rotation.x = -bundle.rotateX * DEG_TO_RAD;\n object.object.rotation.y = bundle.rotateY * DEG_TO_RAD;\n object.object.rotation.z = -bundle.rotateZ * DEG_TO_RAD;\n object.object.rotation.order = \"XYZ\";\n\n object.object.updateMatrixWorld(true);\n\n return { scale: bundle.scale };\n }\n\n private readStyleBundle(el: HTMLElement, ctx: SyncContext): GroupStyleBundle {\n return GroupSynchronizer.styleCache.get(el, ctx, (el) => {\n const styles = new StyleReader(el);\n return {\n translateZ: styles.readNumber(\"--translate-z\", 0),\n scale: styles.readNumber(\"--scale\", 1),\n rotateX: styles.readNumber(\"--rotate-x\", 0),\n rotateY: styles.readNumber(\"--rotate-y\", 0),\n rotateZ: styles.readNumber(\"--rotate-z\", 0),\n };\n });\n }\n}\n","import { String3DObject } from \"../String3DObject\";\nimport type { String3DObjectSyncStrategy } from \"./String3DObjectSyncStrategy\";\nimport type { SyncContext } from \"./SyncContext\";\nimport { I3DLight } from \"../abstractions/I3DEngine\";\nimport { StyleReader } from \"../../modules/string3d/styleUtils\";\nimport { StyleBundleCache } from \"./StyleBundleCache\";\n\ntype LightStyleBundle = {\n translateZ: number;\n translateX: number;\n translateY: number;\n color?: string;\n intensity: number;\n distance?: number;\n decay?: number;\n angle?: number;\n penumbra?: number;\n groundColor?: string;\n castShadow: boolean;\n shadowBias?: number;\n shadowMapSize?: number;\n targetId?: string;\n targetOffset?: { x: number; y: number; z: number };\n};\n\nexport class LightSynchronizer implements String3DObjectSyncStrategy {\n private static styleCache = new StyleBundleCache<LightStyleBundle>();\n\n sync(el: HTMLElement, object: String3DObject, ctx: SyncContext, parentData: any): any {\n const cached = (el as any).__layoutCache;\n const rect = cached ? cached.rect : el.getBoundingClientRect();\n const bundle = this.readStyleBundle(el, ctx, object);\n\n const screenCenterX = rect.left + rect.width * 0.5;\n const screenCenterY = rect.top + rect.height * 0.5;\n\n if (ctx.camera.getMode() === \"orthographic\") {\n object.object.position.set(\n screenCenterX - ctx.viewportWidth / 2 + bundle.translateX,\n -(screenCenterY - ctx.viewportHeight / 2) + bundle.translateY,\n bundle.translateZ\n );\n } else {\n const frustum = ctx.camera.getFrustumSizeAt(bundle.translateZ);\n const normalizedX = screenCenterX / ctx.viewportWidth;\n const normalizedY = screenCenterY / ctx.viewportHeight;\n object.object.position.set(\n (normalizedX - 0.5) * frustum.width + bundle.translateX,\n -(normalizedY - 0.5) * frustum.height + bundle.translateY,\n bundle.translateZ\n );\n }\n\n const light = object.object as I3DLight;\n\n if (\n bundle.color &&\n bundle.color !== \"none\" &&\n light.color &&\n typeof light.color.set === \"function\"\n ) {\n light.color.set(bundle.color);\n }\n\n light.intensity = bundle.intensity;\n\n if (typeof light.distance !== \"undefined\" && bundle.distance !== undefined) {\n light.distance = bundle.distance;\n }\n if (typeof light.decay !== \"undefined\" && bundle.decay !== undefined) {\n light.decay = bundle.decay;\n }\n\n if (typeof light.angle !== \"undefined\" && bundle.angle !== undefined) {\n light.angle = bundle.angle;\n }\n if (typeof light.penumbra !== \"undefined\" && bundle.penumbra !== undefined) {\n light.penumbra = bundle.penumbra;\n }\n\n if (\n bundle.groundColor &&\n bundle.groundColor !== \"none\" &&\n (light as any).groundColor &&\n typeof (light as any).groundColor.set === \"function\"\n ) {\n (light as any).groundColor.set(bundle.groundColor);\n }\n\n if (light.castShadow !== bundle.castShadow) {\n light.castShadow = bundle.castShadow;\n }\n if (bundle.castShadow && light.shadow) {\n if (bundle.shadowBias !== undefined) {\n light.shadow.bias = bundle.shadowBias;\n }\n if (\n bundle.shadowMapSize !== undefined &&\n light.shadow.mapSize.width !== bundle.shadowMapSize\n ) {\n light.shadow.mapSize.width = bundle.shadowMapSize;\n light.shadow.mapSize.height = bundle.shadowMapSize;\n }\n }\n\n if (bundle.targetId && bundle.targetId !== \"none\" && light.target) {\n const targetEl = document.querySelector(`[string-id=\"${bundle.targetId}\"]`);\n if (targetEl) {\n const tCached = (targetEl as any).__layoutCache;\n const tRect = tCached ? tCached.rect : targetEl.getBoundingClientRect();\n const tStyles = new StyleReader(targetEl as HTMLElement);\n const tTranslateZ = tStyles.readNumber(\"--translate-z\", 0);\n\n const tScreenCenterX = tRect.left + tRect.width * 0.5;\n const tScreenCenterY = tRect.top + tRect.height * 0.5;\n\n let x: number;\n let y: number;\n let z: number;\n if (ctx.camera.getMode() === \"orthographic\") {\n x = tScreenCenterX - ctx.viewportWidth / 2;\n y = -(tScreenCenterY - ctx.viewportHeight / 2);\n z = tTranslateZ;\n } else {\n const frustum = ctx.camera.getFrustumSizeAt(tTranslateZ);\n const normalizedX = tScreenCenterX / ctx.viewportWidth;\n const normalizedY = tScreenCenterY / ctx.viewportHeight;\n x = (normalizedX - 0.5) * frustum.width;\n y = -(normalizedY - 0.5) * frustum.height;\n z = tTranslateZ;\n }\n\n if (bundle.targetOffset) {\n x += bundle.targetOffset.x;\n y += bundle.targetOffset.y;\n z += bundle.targetOffset.z;\n }\n\n light.target.position.set(x, y, z);\n\n light.target.updateMatrixWorld(true);\n }\n }\n\n return null;\n }\n\n private readStyleBundle(\n el: HTMLElement,\n ctx: SyncContext,\n object: String3DObject\n ): LightStyleBundle {\n return LightSynchronizer.styleCache.get(el, ctx, (el) => {\n const styles = new StyleReader(el);\n const light = object.object as I3DLight;\n\n const bundle: LightStyleBundle = {\n translateZ: styles.readNumber(\"--translate-z\", 0),\n translateX: styles.readNumber(\"--translate-x\", 0),\n translateY: styles.readNumber(\"--translate-y\", 0),\n color: styles.readString(\"--light-color\", \"\") || undefined,\n intensity: styles.readNumber(\"--light-intensity\", light.intensity ?? 1),\n castShadow: styles.readBoolean(\"--shadow-cast\", false),\n };\n\n if (typeof light.distance !== \"undefined\") {\n bundle.distance = styles.readNumber(\"--light-distance\", light.distance ?? 0);\n }\n if (typeof light.decay !== \"undefined\") {\n bundle.decay = styles.readNumber(\"--light-decay\", light.decay ?? 1);\n }\n if (typeof light.angle !== \"undefined\") {\n bundle.angle = styles.readNumber(\"--light-angle\", light.angle ?? Math.PI / 3);\n }\n if (typeof light.penumbra !== \"undefined\") {\n bundle.penumbra = styles.readNumber(\"--light-penumbra\", light.penumbra ?? 0);\n }\n\n const groundColor = styles.readString(\"--light-ground-color\", \"\");\n if (groundColor) bundle.groundColor = groundColor;\n\n if (bundle.castShadow && light.shadow) {\n bundle.shadowBias = styles.readNumber(\"--shadow-bias\", light.shadow.bias ?? 0);\n bundle.shadowMapSize = styles.readNumber(\n \"--shadow-map-size\",\n light.shadow.mapSize.width ?? 512\n );\n }\n\n const targetId = styles.readString(\"--light-target\", \"\").trim();\n if (targetId) bundle.targetId = targetId;\n const offsetRaw = styles.readString(\"--light-target-offset\", \"\").trim();\n if (offsetRaw) {\n const offset = this.parseTargetOffset(offsetRaw);\n if (offset) bundle.targetOffset = offset;\n }\n\n return bundle;\n });\n }\n\n private parseTargetOffset(value: string): { x: number; y: number; z: number } | null {\n const parts = value\n .split(/[\\s,]+/)\n .map((part) => part.trim())\n .filter(Boolean)\n .map((part) => Number.parseFloat(part));\n if (parts.length < 3 || parts.some((num) => Number.isNaN(num))) return null;\n return { x: parts[0], y: parts[1], z: parts[2] };\n }\n}\n","import { String3DObject } from \"../String3DObject\";\nimport type { SyncContext } from \"./SyncContext\";\nimport type { String3DObjectSyncStrategy } from \"./String3DObjectSyncStrategy\";\nimport { StyleBundleCache } from \"./StyleBundleCache\";\n\nconst DEG_TO_RAD = Math.PI / 180;\n\nexport class MeshSynchronizer implements String3DObjectSyncStrategy {\n private static styleCache = new StyleBundleCache<StyleBundle>();\n private static layoutCache = new StyleBundleCache<LayoutBundle>();\n private static tempVector3: any = null;\n private static lastVisualProps: WeakMap<\n String3DObject,\n {\n opacity?: number;\n color?: string;\n metalness?: number;\n roughness?: number;\n emissive?: string;\n castShadow?: boolean;\n receiveShadow?: boolean;\n }\n > = new WeakMap();\n private static lastGeometryQuality: WeakMap<String3DObject, number> = new WeakMap();\n\n static applyVisualProps(\n el: HTMLElement,\n object: String3DObject,\n props: {\n opacity?: number;\n color?: string;\n metalness?: number;\n roughness?: number;\n emissive?: string;\n castShadow?: boolean;\n receiveShadow?: boolean;\n }\n ): void {\n const prev = MeshSynchronizer.lastVisualProps.get(object);\n if (prev) {\n if (\n prev.opacity === props.opacity &&\n prev.color === props.color &&\n prev.metalness === props.metalness &&\n prev.roughness === props.roughness &&\n prev.emissive === props.emissive &&\n prev.castShadow === props.castShadow &&\n prev.receiveShadow === props.receiveShadow\n )\n return;\n prev.opacity = props.opacity;\n prev.color = props.color;\n prev.metalness = props.metalness;\n prev.roughness = props.roughness;\n prev.emissive = props.emissive;\n prev.castShadow = props.castShadow;\n prev.receiveShadow = props.receiveShadow;\n } else {\n MeshSynchronizer.lastVisualProps.set(object, {\n opacity: props.opacity,\n color: props.color,\n metalness: props.metalness,\n roughness: props.roughness,\n emissive: props.emissive,\n castShadow: props.castShadow,\n receiveShadow: props.receiveShadow,\n });\n }\n\n const castShadow = props.castShadow ?? false;\n const receiveShadow = props.receiveShadow ?? false;\n\n const opacity = typeof props.opacity === \"number\" ? props.opacity : NaN;\n\n const applyMaterialProps = (mat: any) => {\n if (!mat) return;\n\n if (!isNaN(opacity)) {\n mat.opacity = opacity;\n mat.transparent = opacity < 1;\n }\n\n if (props.color && mat.color && mat.color.set) {\n mat.color.set(props.color);\n }\n\n if (typeof props.metalness === \"number\" && \"metalness\" in mat) {\n mat.metalness = props.metalness;\n }\n\n if (typeof props.roughness === \"number\" && \"roughness\" in mat) {\n mat.roughness = props.roughness;\n }\n\n if (props.emissive && mat.emissive && mat.emissive.set) {\n mat.emissive.set(props.emissive);\n }\n };\n\n if (object.object.traverse) {\n object.object.traverse((child: any) => {\n if (child.isMesh) {\n if (child.castShadow !== castShadow) child.castShadow = castShadow;\n if (child.receiveShadow !== receiveShadow) child.receiveShadow = receiveShadow;\n\n const materials = Array.isArray(child.material) ? child.material : [child.material];\n materials.forEach(applyMaterialProps);\n }\n });\n } else if ((object.object as any).isMesh) {\n const mesh = object.object as any;\n if (mesh.castShadow !== castShadow) mesh.castShadow = castShadow;\n if (mesh.receiveShadow !== receiveShadow) mesh.receiveShadow = receiveShadow;\n\n const materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material];\n materials.forEach(applyMaterialProps);\n }\n }\n\n sync(el: HTMLElement, object: String3DObject, ctx: SyncContext, parentData: any): any {\n const { rect, width: originalWidth, height: originalHeight } = this.readLayout(el, ctx);\n const bundle = this.readStyleBundle(el, ctx);\n const {\n translateZ,\n cssScale,\n rotateX,\n rotateY,\n rotateZ,\n cssScaleZ,\n opacity,\n color,\n metalness,\n roughness,\n emissive,\n castShadow,\n receiveShadow,\n geometryQuality,\n } = bundle;\n\n const screenCenterX = rect.left + rect.width * 0.5;\n const screenCenterY = rect.top + rect.height * 0.5;\n\n if (ctx.camera.getMode() === \"orthographic\") {\n object.object.position.set(\n screenCenterX - ctx.viewportWidth / 2,\n -(screenCenterY - ctx.viewportHeight / 2),\n translateZ\n );\n } else {\n const frustum = ctx.camera.getFrustumSizeAt(translateZ);\n const normalizedX = screenCenterX / ctx.viewportWidth;\n const normalizedY = screenCenterY / ctx.viewportHeight;\n object.object.position.set(\n (normalizedX - 0.5) * frustum.width,\n -(normalizedY - 0.5) * frustum.height,\n translateZ\n );\n }\n\n object.object.rotation.x = -rotateX * DEG_TO_RAD;\n object.object.rotation.y = rotateY * DEG_TO_RAD;\n object.object.rotation.z = -rotateZ * DEG_TO_RAD;\n object.object.rotation.order = \"XYZ\";\n\n const targetWidth = originalWidth * cssScale;\n const targetHeight = originalHeight * cssScale;\n const parentScale = parentData?.scale || 1;\n const baseScaleZ = cssScaleZ * parentScale;\n const minTargetSize = targetWidth < targetHeight ? targetWidth : targetHeight;\n let scaleX: number, scaleY: number, scaleZ: number;\n\n switch (object.type) {\n case \"box\":\n case \"sphere\": {\n const uniformSize = minTargetSize * parentScale;\n scaleX = scaleY = uniformSize;\n scaleZ = uniformSize * cssScaleZ;\n break;\n }\n case \"model\": {\n const bbox = object.getOriginalBoundingBox();\n if (!MeshSynchronizer.tempVector3) {\n MeshSynchronizer.tempVector3 = ctx.engine.createVector3();\n }\n const size = bbox.getSize(MeshSynchronizer.tempVector3);\n const fitMode = el.getAttribute(\"string-3d-model-fit\");\n const modelScale = parseFloat(el.getAttribute(\"string-3d-model-scale\") || \"1\");\n const finalModelScale = Number.isFinite(modelScale)\n ? modelScale * parentScale\n : parentScale;\n\n if (size.x > 0 && size.y > 0) {\n const scaleW = targetWidth / size.x;\n const scaleH = targetHeight / size.y;\n const uniformScale =\n (fitMode === \"cover\"\n ? scaleW > scaleH\n ? scaleW\n : scaleH\n : scaleW < scaleH\n ? scaleW\n : scaleH) * finalModelScale;\n scaleX = scaleY = uniformScale;\n scaleZ = uniformScale * cssScaleZ;\n } else {\n const fallbackSize = minTargetSize * finalModelScale;\n scaleX = scaleY = fallbackSize;\n scaleZ = fallbackSize * cssScaleZ;\n }\n break;\n }\n case \"cylinder\":\n scaleX = targetWidth * parentScale;\n scaleY = targetHeight * parentScale;\n scaleZ = targetWidth * baseScaleZ;\n break;\n default:\n scaleX = targetWidth * parentScale;\n scaleY = targetHeight * parentScale;\n scaleZ = minTargetSize * 0.5 * baseScaleZ;\n break;\n }\n\n object.object.scale.set(scaleX, scaleY, scaleZ);\n\n MeshSynchronizer.applyVisualProps(el, object, {\n opacity,\n color: color && color !== \"none\" ? color : undefined,\n metalness: isNaN(metalness) ? undefined : metalness,\n roughness: isNaN(roughness) ? undefined : roughness,\n emissive: emissive && emissive !== \"none\" ? emissive : undefined,\n castShadow,\n receiveShadow,\n });\n\n this.applyGeometryQuality(object, geometryQuality, ctx);\n\n this.updateCustomUniforms(el, object, ctx);\n\n return { scale: cssScale * parentScale };\n }\n\n private applyGeometryQuality(object: String3DObject, quality: number, ctx: SyncContext): void {\n const engine: any = ctx.engine as any;\n const simplify = engine?.simplifyGeometry?.bind(engine);\n if (typeof simplify !== \"function\") return;\n\n const normalized = Number.isFinite(quality) && quality > 0 ? quality : 1;\n const prev = MeshSynchronizer.lastGeometryQuality.get(object);\n if (typeof prev === \"number\" && Math.abs(prev - normalized) < 0.001) return;\n MeshSynchronizer.lastGeometryQuality.set(object, normalized);\n\n const applyToMesh = (mesh: any) => {\n if (!mesh?.geometry) return;\n const userData = mesh.userData || (mesh.userData = {});\n if (!userData.__originalGeometry) {\n userData.__originalGeometry = mesh.geometry;\n }\n const original = userData.__originalGeometry;\n if (normalized >= 0.999) {\n mesh.geometry = original;\n return;\n }\n if (!userData.__lodCache) {\n userData.__lodCache = new Map<string, any>();\n }\n const key = normalized.toFixed(3);\n if (userData.__lodCache.has(key)) {\n mesh.geometry = userData.__lodCache.get(key);\n return;\n }\n const simplified = simplify(original, normalized);\n if (simplified) {\n userData.__lodCache.set(key, simplified);\n mesh.geometry = simplified;\n }\n };\n\n if (object.object.traverse) {\n object.object.traverse((child: any) => {\n if (child?.isMesh) applyToMesh(child);\n });\n } else if ((object.object as any).isMesh) {\n applyToMesh(object.object as any);\n }\n }\n\n private updateCustomUniforms(el: HTMLElement, object: String3DObject, ctx: SyncContext): void {\n const factory = ctx.engine.getMaterialFactory?.();\n if (!factory) return;\n\n const style = getComputedStyle(el);\n\n const apply = (mat: any) => {\n const definition = mat?.userData?.definition;\n if (!definition?.uniforms) return;\n\n const values = factory.parseUniformsFromCSS(definition, el, style);\n\n for (const [key, value] of Object.entries(values)) {\n const def = definition.uniforms?.[key];\n if (!def) continue;\n\n const converter = (factory as any).convertUniformValue?.bind(factory);\n const converted = converter ? converter(def.type, value) : value;\n\n if (mat.userData?.shader?.uniforms?.[key]) {\n mat.userData.shader.uniforms[key].value = converted;\n } else if (mat.userData?.customUniforms?.[key]) {\n mat.userData.customUniforms[key].value = converted;\n } else if (mat.uniforms?.[key]) {\n mat.uniforms[key].value = converted;\n }\n }\n };\n\n if (object.object.traverse) {\n object.object.traverse((child: any) => {\n if (child.isMesh) {\n const materials = Array.isArray(child.material) ? child.material : [child.material];\n materials.forEach(apply);\n }\n });\n } else if ((object.object as any).isMesh) {\n const mesh = object.object as any;\n const materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material];\n materials.forEach(apply);\n }\n }\n\n private readStyleBundle(el: HTMLElement, ctx: SyncContext): StyleBundle {\n return MeshSynchronizer.styleCache.get(el, ctx, (el) => {\n const styleMap = (el as any).computedStyleMap?.();\n const style = getComputedStyle(el);\n\n const readNumber = (prop: string, fallback: number): number => {\n const mapValue = styleMap?.get?.(prop);\n if (mapValue !== undefined && mapValue !== null) {\n const val =\n typeof mapValue === \"object\" && \"value\" in (mapValue as any)\n ? (mapValue as any).value\n : mapValue;\n const num = typeof val === \"number\" ? val : Number.parseFloat(String(val));\n if (!Number.isNaN(num)) return num;\n }\n const num = Number.parseFloat(style.getPropertyValue(prop));\n return Number.isNaN(num) ? fallback : num;\n };\n\n const readString = (prop: string): string | undefined => {\n const mapValue = styleMap?.get?.(prop);\n const val =\n mapValue && typeof mapValue === \"object\" && \"value\" in (mapValue as any)\n ? (mapValue as any).value\n : mapValue;\n if (typeof val === \"string\") return val.trim() || undefined;\n const raw = style.getPropertyValue(prop).trim();\n return raw || undefined;\n };\n\n const readBool = (prop: string, fallback = false): boolean => {\n const raw = readString(prop);\n if (!raw) return fallback;\n const norm = raw.toLowerCase();\n return norm === \"true\" || norm === \"1\" || norm === \"yes\"\n ? true\n : norm === \"false\" || norm === \"0\" || norm === \"no\"\n ? false\n : fallback;\n };\n\n return {\n translateZ: readNumber(\"--translate-z\", 0),\n cssScale: readNumber(\"--scale\", 1),\n rotateX: readNumber(\"--rotate-x\", 0),\n rotateY: readNumber(\"--rotate-y\", 0),\n rotateZ: readNumber(\"--rotate-z\", 0),\n cssScaleZ: readNumber(\"--scale-z\", 1),\n opacity: readNumber(\"--opacity\", NaN),\n color: readString(\"--material-color\"),\n metalness: readNumber(\"--material-metalness\", NaN),\n roughness: readNumber(\"--material-roughness\", NaN),\n emissive: readString(\"--material-emissive\"),\n castShadow: readBool(\"--shadow-cast\", false),\n receiveShadow: readBool(\"--shadow-receive\", false),\n geometryQuality: readNumber(\"--geometry-quality\", 1),\n };\n });\n }\n\n private readLayout(el: HTMLElement, ctx: SyncContext): LayoutBundle {\n const cached = (el as any).__layoutCache;\n if (cached) {\n return cached;\n }\n\n return MeshSynchronizer.layoutCache.get(el, ctx, (el) => {\n const rect = el.getBoundingClientRect();\n const width = el.offsetWidth || rect.width;\n const height = el.offsetHeight || rect.height;\n return { rect, width, height };\n });\n }\n}\n\ntype StyleBundle = {\n translateZ: number;\n cssScale: number;\n rotateX: number;\n rotateY: number;\n rotateZ: number;\n cssScaleZ: number;\n opacity: number;\n color?: string;\n metalness: number;\n roughness: number;\n emissive?: string;\n castShadow: boolean;\n receiveShadow: boolean;\n geometryQuality: number;\n};\n\ntype LayoutBundle = {\n rect: DOMRect;\n width: number;\n height: number;\n};\n","import { String3DObject } from \"../String3DObject\";\nimport type { String3DObjectSyncStrategy } from \"./String3DObjectSyncStrategy\";\nimport type { SyncContext } from \"./SyncContext\";\nimport { StyleReader } from \"../../modules/string3d/styleUtils\";\nimport { StyleBundleCache } from \"./StyleBundleCache\";\nimport type { ParticleSystemConfig } from \"../abstractions/I3DEngine\";\nimport { String3DCustomMaterialRegistry } from \"../materials\";\nimport type { IMaterialInstance } from \"../materials\";\n\ntype ParticleStyleBundle = ParticleSystemConfig & {\n translateZ: number;\n scale: number;\n rotateX: number;\n rotateY: number;\n rotateZ: number;\n particlesFit: boolean;\n materialType: string;\n};\n\nconst DEG_TO_RAD = Math.PI / 180;\n\nconst DEFAULT_CONFIG: ParticleSystemConfig = {\n mode: \"emitter\",\n count: 300,\n size: 2,\n color: \"#ffffff\",\n opacity: 1,\n spread: 120,\n seed: 1,\n emitRate: 30,\n emitBurst: 0,\n particleLife: 2.5,\n particleSpeed: 40,\n particleDirection: [0, 1, 0],\n particleGravity: [0, -30, 0],\n particleDrag: 0.1,\n particleSizeVariation: 0.6,\n particleColorVariation: 0.2,\n particleShape: \"sphere\",\n particleModelUrl: \"\",\n particleModelLoader: \"\",\n particleModelNode: \"\",\n instanceShape: \"sphere\",\n instanceModelUrl: \"\",\n instanceModelLoader: \"\",\n instanceModelNode: \"\",\n instanceScale: 1,\n instanceScaleVariation: 0.5,\n instanceRotationSpeed: 0.4,\n instanceJitter: 0.2,\n instanceFlow: 0.3,\n instanceDisperse: 0,\n instanceDisperseScatter: 0,\n instanceDisperseScatterX: 0,\n instanceDisperseScatterY: 0,\n instanceDisperseScatterZ: 0,\n};\n\nexport class ParticlesSynchronizer implements String3DObjectSyncStrategy {\n private static styleCache = new StyleBundleCache<ParticleStyleBundle>();\n private static lastConfig: WeakMap<String3DObject, ParticleSystemConfig> = new WeakMap();\n private static lastTime: WeakMap<String3DObject, number> = new WeakMap();\n private static lastMaterialType: WeakMap<String3DObject, string> = new WeakMap();\n private static materialInstances: WeakMap<String3DObject, IMaterialInstance> = new WeakMap();\n\n sync(el: HTMLElement, object: String3DObject, ctx: SyncContext, parentData: any): any {\n const cached = (el as any).__layoutCache;\n const rect = cached ? cached.rect : el.getBoundingClientRect();\n const bundle = this.readStyleBundle(el, ctx);\n\n const screenCenterX = rect.left + rect.width * 0.5;\n const screenCenterY = rect.top + rect.height * 0.5;\n\n if (ctx.camera.getMode() === \"orthographic\") {\n object.object.position.set(\n screenCenterX - ctx.viewportWidth / 2,\n -(screenCenterY - ctx.viewportHeight / 2),\n bundle.translateZ\n );\n } else {\n const frustum = ctx.camera.getFrustumSizeAt(bundle.translateZ);\n const normalizedX = screenCenterX / ctx.viewportWidth;\n const normalizedY = screenCenterY / ctx.viewportHeight;\n object.object.position.set(\n (normalizedX - 0.5) * frustum.width,\n -(normalizedY - 0.5) * frustum.height,\n bundle.translateZ\n );\n }\n\n const parentScale = parentData?.scale ?? 1;\n const scale = bundle.scale * parentScale;\n object.object.scale.set(scale, scale, scale);\n\n object.object.rotation.x = -bundle.rotateX * DEG_TO_RAD;\n object.object.rotation.y = bundle.rotateY * DEG_TO_RAD;\n object.object.rotation.z = -bundle.rotateZ * DEG_TO_RAD;\n object.object.rotation.order = \"XYZ\";\n\n const config = this.buildConfig(bundle, rect, ctx, parentData);\n const prev = ParticlesSynchronizer.lastConfig.get(object);\n if (!prev || !this.isSameConfig(prev, config)) {\n ParticlesSynchronizer.lastConfig.set(object, config);\n (object.object as any).setConfig?.(config);\n }\n\n this.updateMaterialOverrides(el, object, ctx, bundle);\n this.updateCustomUniforms(el, object, ctx);\n\n const now = performance.now();\n const last = ParticlesSynchronizer.lastTime.get(object) ?? now;\n const dt = Math.max(0, (now - last) / 1000);\n ParticlesSynchronizer.lastTime.set(object, now);\n (object.object as any).update?.(dt);\n\n return { scale: parentData?.scale ?? 1 };\n }\n\n private readStyleBundle(el: HTMLElement, ctx: SyncContext): ParticleStyleBundle {\n return ParticlesSynchronizer.styleCache.get(el, ctx, (el) => {\n const styles = new StyleReader(el);\n const modeRaw = styles.readString(\"--particles-mode\", DEFAULT_CONFIG.mode).toLowerCase();\n const mode = modeRaw === \"instanced\" ? \"instanced\" : \"emitter\";\n return {\n ...DEFAULT_CONFIG,\n translateZ: styles.readNumber(\"--translate-z\", 0),\n scale: styles.readNumber(\"--scale\", 1),\n rotateX: styles.readNumber(\"--rotate-x\", 0),\n rotateY: styles.readNumber(\"--rotate-y\", 0),\n rotateZ: styles.readNumber(\"--rotate-z\", 0),\n particlesFit: styles.readNumber(\"--particles-fit\", 0) > 0.5,\n materialType: styles.readString(\"--material-type\", \"basic\"),\n mode,\n count: styles.readNumber(\"--particles-count\", DEFAULT_CONFIG.count),\n size: styles.readNumber(\"--particles-size\", DEFAULT_CONFIG.size),\n color: styles.readString(\"--particles-color\", DEFAULT_CONFIG.color),\n opacity: styles.readNumber(\"--particles-opacity\", DEFAULT_CONFIG.opacity),\n spread: styles.readNumber(\"--particles-spread\", DEFAULT_CONFIG.spread),\n seed: styles.readNumber(\"--particles-seed\", DEFAULT_CONFIG.seed),\n emitRate: styles.readNumber(\"--emit-rate\", DEFAULT_CONFIG.emitRate),\n emitBurst: styles.readNumber(\"--emit-burst\", DEFAULT_CONFIG.emitBurst),\n particleLife: styles.readNumber(\"--particle-life\", DEFAULT_CONFIG.particleLife),\n particleSpeed: styles.readNumber(\"--particle-speed\", DEFAULT_CONFIG.particleSpeed),\n particleDirection: this.parseVec3(\n styles.readString(\"--particle-direction\", \"0 1 0\"),\n DEFAULT_CONFIG.particleDirection\n ),\n particleGravity: this.parseVec3(\n styles.readString(\"--particle-gravity\", \"0 -30 0\"),\n DEFAULT_CONFIG.particleGravity\n ),\n particleDrag: styles.readNumber(\"--particle-drag\", DEFAULT_CONFIG.particleDrag),\n particleSizeVariation: styles.readNumber(\n \"--particle-size-variation\",\n DEFAULT_CONFIG.particleSizeVariation\n ),\n particleColorVariation: styles.readNumber(\n \"--particle-color-variation\",\n DEFAULT_CONFIG.particleColorVariation\n ),\n particleShape: this.parseShape(\n styles.readString(\"--particles-shape\", DEFAULT_CONFIG.particleShape)\n ),\n particleModelUrl: styles.readString(\"--particles-model\", DEFAULT_CONFIG.particleModelUrl),\n particleModelLoader: styles.readString(\n \"--particles-model-loader\",\n DEFAULT_CONFIG.particleModelLoader\n ),\n particleModelNode: styles.readString(\n \"--particles-model-node\",\n DEFAULT_CONFIG.particleModelNode\n ),\n instanceShape: this.parseDistribution(\n styles.readString(\"--instance-shape\", DEFAULT_CONFIG.instanceShape)\n ),\n instanceModelUrl: styles.readString(\"--instance-model\", DEFAULT_CONFIG.instanceModelUrl),\n instanceModelLoader: styles.readString(\n \"--instance-model-loader\",\n DEFAULT_CONFIG.instanceModelLoader\n ),\n instanceModelNode: styles.readString(\n \"--instance-model-node\",\n DEFAULT_CONFIG.instanceModelNode\n ),\n instanceScale: styles.readNumber(\"--instance-scale\", DEFAULT_CONFIG.instanceScale),\n instanceScaleVariation: styles.readNumber(\n \"--instance-scale-variation\",\n DEFAULT_CONFIG.instanceScaleVariation\n ),\n instanceRotationSpeed: styles.readNumber(\n \"--instance-rotation-speed\",\n DEFAULT_CONFIG.instanceRotationSpeed\n ),\n instanceJitter: styles.readNumber(\"--instance-jitter\", DEFAULT_CONFIG.instanceJitter),\n instanceFlow: styles.readNumber(\"--instance-flow\", DEFAULT_CONFIG.instanceFlow),\n instanceDisperse: styles.readNumber(\"--instance-disperse\", DEFAULT_CONFIG.instanceDisperse),\n instanceDisperseScatter: styles.readNumber(\n \"--instance-scatter\",\n DEFAULT_CONFIG.instanceDisperseScatter\n ),\n instanceDisperseScatterX: styles.readNumber(\n \"--instance-scatter-x\",\n DEFAULT_CONFIG.instanceDisperseScatterX\n ),\n instanceDisperseScatterY: styles.readNumber(\n \"--instance-scatter-y\",\n DEFAULT_CONFIG.instanceDisperseScatterY\n ),\n instanceDisperseScatterZ: styles.readNumber(\n \"--instance-scatter-z\",\n DEFAULT_CONFIG.instanceDisperseScatterZ\n ),\n };\n });\n }\n\n private parseVec3(value: string, fallback: [number, number, number]): [number, number, number] {\n const parts = value\n .split(/[\\s,]+/)\n .map((part) => Number.parseFloat(part))\n .filter((num) => !Number.isNaN(num));\n if (parts.length >= 3) {\n return [parts[0], parts[1], parts[2]];\n }\n return fallback;\n }\n\n private parseShape(value: string): \"box\" | \"sphere\" | \"model\" {\n const normalized = value.trim().toLowerCase();\n if (normalized === \"box\") return \"box\";\n if (normalized === \"model\") return \"model\";\n return \"sphere\";\n }\n\n private parseDistribution(value: string): \"box\" | \"sphere\" | \"model\" {\n return this.parseShape(value);\n }\n\n private buildConfig(\n bundle: ParticleStyleBundle,\n rect: DOMRect,\n ctx: SyncContext,\n parentData: any\n ): ParticleSystemConfig {\n const parentScale = parentData?.scale ?? 1;\n const scale = parentScale;\n const fitBase = Math.min(rect.width, rect.height);\n const fitMultiplier =\n bundle.instanceShape === \"box\" || bundle.instanceShape === \"model\" ? 1 : 0.5;\n const spreadPixels = bundle.particlesFit ? fitBase * fitMultiplier : bundle.spread;\n const spread = this.toWorld(spreadPixels, bundle.translateZ, ctx);\n return {\n ...bundle,\n count: Math.max(0, Math.floor(bundle.count)),\n size: Math.max(0.1, bundle.size),\n opacity: Math.max(0, Math.min(1, bundle.opacity)),\n spread: Math.max(0, spread * scale),\n seed: Math.max(0, Math.floor(bundle.seed)),\n emitRate: Math.max(0, bundle.emitRate),\n emitBurst: Math.max(0, bundle.emitBurst),\n particleLife: Math.max(0.1, bundle.particleLife),\n particleSpeed: Math.max(0, bundle.particleSpeed),\n particleDrag: Math.max(0, Math.min(1, bundle.particleDrag)),\n particleSizeVariation: Math.max(0, bundle.particleSizeVariation),\n particleColorVariation: Math.max(0, bundle.particleColorVariation),\n instanceScale: Math.max(0.1, bundle.instanceScale),\n instanceScaleVariation: Math.max(0, bundle.instanceScaleVariation),\n instanceRotationSpeed: Math.max(0, bundle.instanceRotationSpeed),\n instanceJitter: Math.max(0, bundle.instanceJitter),\n instanceFlow: Math.max(0, bundle.instanceFlow),\n instanceDisperse: Math.max(0, bundle.instanceDisperse),\n instanceDisperseScatter: Math.max(0, bundle.instanceDisperseScatter),\n instanceDisperseScatterX: Math.max(0, bundle.instanceDisperseScatterX),\n instanceDisperseScatterY: Math.max(0, bundle.instanceDisperseScatterY),\n instanceDisperseScatterZ: Math.max(0, bundle.instanceDisperseScatterZ),\n };\n }\n\n private toWorld(value: number, z: number, ctx: SyncContext): number {\n if (ctx.camera.getMode() === \"orthographic\") {\n return value;\n }\n const frustum = ctx.camera.getFrustumSizeAt(z);\n const perPixel = frustum.width / Math.max(1, ctx.viewportWidth);\n return value * perPixel;\n }\n\n private isSameConfig(a: ParticleSystemConfig, b: ParticleSystemConfig): boolean {\n return JSON.stringify(a) === JSON.stringify(b);\n }\n\n private updateMaterialOverrides(\n el: HTMLElement,\n object: String3DObject,\n ctx: SyncContext,\n bundle: ParticleStyleBundle\n ): void {\n const typeRaw = bundle.materialType || \"basic\";\n const type = typeRaw.split(\"[\")[0].trim().toLowerCase();\n const definition = String3DCustomMaterialRegistry.get(type);\n const factory = ctx.engine.getMaterialFactory?.();\n\n if (!definition || !factory || !factory.supports(definition)) {\n const hasExisting =\n ParticlesSynchronizer.materialInstances.has(object) ||\n ParticlesSynchronizer.lastMaterialType.has(object);\n if (!hasExisting) return;\n\n const existing = ParticlesSynchronizer.materialInstances.get(object);\n if (existing) {\n existing.dispose();\n ParticlesSynchronizer.materialInstances.delete(object);\n }\n ParticlesSynchronizer.lastMaterialType.delete(object);\n (object.object as any).setMaterial?.(null, { points: true, meshes: true });\n return;\n }\n\n const lastType = ParticlesSynchronizer.lastMaterialType.get(object);\n if (lastType !== type) {\n const existing = ParticlesSynchronizer.materialInstances.get(object);\n if (existing) existing.dispose();\n\n const style = getComputedStyle(el);\n const initialUniforms = factory.parseUniformsFromCSS(definition, el, style);\n const instance = factory.create(definition, initialUniforms);\n ParticlesSynchronizer.materialInstances.set(object, instance);\n ParticlesSynchronizer.lastMaterialType.set(object, type);\n\n const material = instance.material;\n const isShader = !!material?.isShaderMaterial;\n const system: any = object.object as any;\n system.setMaterial?.(material, { meshes: true, points: false });\n system.setMaterial?.(isShader ? material : null, { meshes: false, points: true });\n }\n }\n\n private updateCustomUniforms(el: HTMLElement, object: String3DObject, ctx: SyncContext): void {\n const factory = ctx.engine.getMaterialFactory?.();\n if (!factory) return;\n\n const style = getComputedStyle(el);\n\n const apply = (mat: any) => {\n const definition = mat?.userData?.definition;\n if (!definition?.uniforms) return;\n\n const values = factory.parseUniformsFromCSS(definition, el, style);\n\n for (const [key, value] of Object.entries(values)) {\n const def = definition.uniforms?.[key];\n if (!def) continue;\n\n const converter = (factory as any).convertUniformValue?.bind(factory);\n const converted = converter ? converter(def.type, value) : value;\n\n if (mat.userData?.shader?.uniforms?.[key]) {\n mat.userData.shader.uniforms[key].value = converted;\n } else if (mat.userData?.customUniforms?.[key]) {\n mat.userData.customUniforms[key].value = converted;\n } else if (mat.uniforms?.[key]) {\n mat.uniforms[key].value = converted;\n }\n }\n };\n\n if (object.object.traverse) {\n object.object.traverse((child: any) => {\n if (child.isMesh || child.isPoints) {\n const materials = Array.isArray(child.material) ? child.material : [child.material];\n materials.forEach(apply);\n }\n });\n }\n }\n}\n","export type String3DFontEntry = {\n name: string;\n url: string;\n};\n\nexport class String3DFontRegistry {\n private static fonts: Map<string, String3DFontEntry> = new Map();\n private static defaultFont: string | null = null;\n\n static register(name: string, url: string): void {\n const normalized = name.trim();\n if (!normalized) return;\n if (this.fonts.has(normalized)) {\n console.warn(`[String3D] Font \"${normalized}\" already registered. Overwriting.`);\n }\n this.fonts.set(normalized, { name: normalized, url });\n }\n\n static setDefault(name: string): void {\n const normalized = name.trim();\n if (!normalized) return;\n if (!this.fonts.has(normalized)) {\n console.warn(`[String3D] Default font \"${normalized}\" is not registered yet.`);\n }\n this.defaultFont = normalized;\n }\n\n static get(name: string): String3DFontEntry | undefined {\n return this.fonts.get(name.trim());\n }\n\n static list(): String3DFontEntry[] {\n return Array.from(this.fonts.values());\n }\n\n static resolveFontFamily(fontFamily: string): String3DFontEntry | null {\n if (!fontFamily) {\n return this.getDefault();\n }\n\n const families = fontFamily\n .split(\",\")\n .map((value) => value.trim().replace(/^[\"']|[\"']$/g, \"\"))\n .filter(Boolean);\n\n for (const family of families) {\n const entry = this.fonts.get(family);\n if (entry) return entry;\n }\n\n return this.getDefault();\n }\n\n private static getDefault(): String3DFontEntry | null {\n if (!this.defaultFont) return null;\n return this.fonts.get(this.defaultFont) || null;\n }\n}\n","export interface FontData {\r\n glyphs: Record<string, GlyphData>;\r\n familyName: string;\r\n ascender: number;\r\n descender: number;\r\n underlinePosition: number;\r\n underlineThickness: number;\r\n boundingBox: { xMin: number; xMax: number; yMin: number; yMax: number };\r\n resolution: number;\r\n original_font_information: Record<string, any>;\r\n}\r\n\r\nexport interface GlyphData {\r\n ha: number;\r\n x_min: number;\r\n x_max: number;\r\n o: string;\r\n}\r\n\r\nexport type FontSource = string | ArrayBuffer | Uint8Array;\r\n\r\nlet opentypePromise: Promise<any> | null = null;\r\nlet opentypeModule: any = null;\r\n\r\nlet woff2Promise: Promise<any> | null = null;\r\nlet woff2Module: any = null;\r\n\r\nasync function loadOpentype(): Promise<any> {\r\n if (opentypeModule) {\r\n return opentypeModule;\r\n }\r\n\r\n if (!opentypePromise) {\r\n opentypePromise = (async () => {\r\n if (typeof window !== \"undefined\" && (window as any).opentype) {\r\n opentypeModule = (window as any).opentype;\r\n return opentypeModule;\r\n }\r\n\r\n return new Promise((resolve, reject) => {\r\n if (typeof document === \"undefined\") {\r\n reject(new Error(\"[FontConverter] Cannot load opentype.js in non-browser environment\"));\r\n return;\r\n }\r\n const script = document.createElement(\"script\");\r\n script.src = \"https://cdn.jsdelivr.net/npm/opentype.js@1.3.4/dist/opentype.min.js\";\r\n script.onload = () => {\r\n opentypeModule = (window as any).opentype;\r\n resolve(opentypeModule);\r\n };\r\n script.onerror = () => reject(new Error(\"[FontConverter] Failed to load opentype.js\"));\r\n document.head.appendChild(script);\r\n });\r\n })();\r\n }\r\n return opentypePromise;\r\n}\r\n\r\nasync function loadWoff2Decoder(): Promise<any> {\r\n if (woff2Module) {\r\n return woff2Module;\r\n }\r\n\r\n if (!woff2Promise) {\r\n woff2Promise = (async () => {\r\n if (typeof window !== \"undefined\" && (window as any).Module?.decompress) {\r\n woff2Module = (window as any).Module;\r\n return woff2Module;\r\n }\r\n\r\n return new Promise((resolve, reject) => {\r\n if (typeof document === \"undefined\") {\r\n reject(new Error(\"[FontConverter] Cannot load woff2 decoder in non-browser environment\"));\r\n return;\r\n }\r\n const script = document.createElement(\"script\");\r\n script.src = \"https://cdn.jsdelivr.net/npm/wawoff2@2.0.1/build/decompress_binding.js\";\r\n script.onload = () => {\r\n let attempts = 0;\r\n const maxAttempts = 500;\r\n const checkReady = () => {\r\n attempts++;\r\n const win = window as any;\r\n if (win.Module?.decompress) {\r\n woff2Module = win.Module;\r\n resolve(woff2Module);\r\n } else if (attempts >= maxAttempts) {\r\n reject(new Error(\"[FontConverter] woff2 decoder initialization timeout\"));\r\n } else {\r\n setTimeout(checkReady, 10);\r\n }\r\n };\r\n checkReady();\r\n };\r\n script.onerror = () => {\r\n reject(new Error(\"[FontConverter] Failed to load woff2 decoder\"));\r\n };\r\n document.head.appendChild(script);\r\n });\r\n })();\r\n }\r\n return woff2Promise;\r\n}\r\n\r\nasync function decompressWoff2(buffer: ArrayBuffer): Promise<ArrayBuffer> {\r\n const woff2 = await loadWoff2Decoder();\r\n const inputArray = new Uint8Array(buffer);\r\n const outputArray = woff2.decompress(inputArray);\r\n\r\n if (outputArray instanceof Uint8Array) {\r\n const newBuffer = new ArrayBuffer(outputArray.length);\r\n const newArray = new Uint8Array(newBuffer);\r\n newArray.set(outputArray);\r\n return newBuffer;\r\n }\r\n\r\n return outputArray.buffer;\r\n}\r\n\r\nfunction isWoff2(buffer: ArrayBuffer): boolean {\r\n const view = new DataView(buffer);\r\n return view.getUint32(0, false) === 0x774f4632;\r\n}\r\n\r\nfunction isWoff(buffer: ArrayBuffer): boolean {\r\n const view = new DataView(buffer);\r\n return view.getUint32(0, false) === 0x774f4646;\r\n}\r\n\r\nexport class FontConverter {\r\n private static cache: Map<string, FontData> = new Map();\r\n private static loadingPromises: Map<string, Promise<FontData>> = new Map();\r\n\r\n static async load(source: FontSource): Promise<FontData> {\r\n const cacheKey = typeof source === \"string\" ? source : \"buffer-\" + Date.now();\r\n\r\n const cached = this.cache.get(cacheKey);\r\n if (cached) return cached;\r\n\r\n const loading = this.loadingPromises.get(cacheKey);\r\n if (loading) return loading;\r\n\r\n const promise = this.doLoad(source, cacheKey);\r\n this.loadingPromises.set(cacheKey, promise);\r\n\r\n try {\r\n const result = await promise;\r\n this.cache.set(cacheKey, result);\r\n return result;\r\n } finally {\r\n this.loadingPromises.delete(cacheKey);\r\n }\r\n }\r\n\r\n private static async doLoad(source: FontSource, cacheKey: string): Promise<FontData> {\r\n const opentype = await loadOpentype();\r\n\r\n let buffer: ArrayBuffer;\r\n\r\n if (typeof source === \"string\") {\r\n const response = await fetch(source);\r\n buffer = await response.arrayBuffer();\r\n } else if (source instanceof ArrayBuffer) {\r\n buffer = source;\r\n } else if (source instanceof Uint8Array) {\r\n buffer = source.buffer as ArrayBuffer;\r\n } else {\r\n throw new Error(\"[FontConverter] Invalid font source\");\r\n }\r\n\r\n if (isWoff2(buffer)) {\r\n buffer = await decompressWoff2(buffer);\r\n }\r\n\r\n const font = opentype.parse(buffer);\r\n\r\n if (!font) {\r\n throw new Error(\"[FontConverter] Failed to parse font\");\r\n }\r\n\r\n return this.convertToTypeFace(font);\r\n }\r\n\r\n private static convertToTypeFace(font: any): FontData {\r\n const scale = 1000 / font.unitsPerEm;\r\n\r\n const glyphs: Record<string, GlyphData> = {};\r\n\r\n for (let i = 0; i < font.glyphs.length; i++) {\r\n const glyph = font.glyphs.get(i);\r\n if (!glyph.unicode) continue;\r\n\r\n const char = String.fromCharCode(glyph.unicode);\r\n const path = glyph.getPath(0, 0, font.unitsPerEm);\r\n const outline = this.pathToOutline(path, scale);\r\n\r\n const advanceWidth = glyph.advanceWidth ?? glyph.xMax ?? font.unitsPerEm * 0.5;\r\n\r\n glyphs[char] = {\r\n ha: Math.round(advanceWidth * scale),\r\n x_min: glyph.xMin !== undefined ? Math.round(glyph.xMin * scale) : 0,\r\n x_max: glyph.xMax !== undefined ? Math.round(glyph.xMax * scale) : 0,\r\n o: outline,\r\n };\r\n }\r\n\r\n if (!glyphs[\" \"]) {\r\n const spaceGlyph = font.charToGlyph(\" \");\r\n glyphs[\" \"] = {\r\n ha: Math.round((spaceGlyph?.advanceWidth || font.unitsPerEm * 0.25) * scale),\r\n x_min: 0,\r\n x_max: 0,\r\n o: \"\",\r\n };\r\n }\r\n\r\n return {\r\n glyphs,\r\n familyName: font.names.fontFamily?.en || font.names.fullName?.en || \"Unknown\",\r\n ascender: Math.round(font.ascender * scale),\r\n descender: Math.round(font.descender * scale),\r\n underlinePosition: Math.round((font.tables.post?.underlinePosition || -100) * scale),\r\n underlineThickness: Math.round((font.tables.post?.underlineThickness || 50) * scale),\r\n boundingBox: {\r\n xMin: Math.round((font.tables.head?.xMin || 0) * scale),\r\n xMax: Math.round((font.tables.head?.xMax || 1000) * scale),\r\n yMin: Math.round((font.tables.head?.yMin || -200) * scale),\r\n yMax: Math.round((font.tables.head?.yMax || 800) * scale),\r\n },\r\n resolution: 1000,\r\n original_font_information: {\r\n format: 0,\r\n copyright: font.names.copyright?.en || \"\",\r\n fontFamily: font.names.fontFamily?.en || \"\",\r\n fontSubfamily: font.names.fontSubfamily?.en || \"\",\r\n uniqueID: font.names.uniqueID?.en || \"\",\r\n fullName: font.names.fullName?.en || \"\",\r\n version: font.names.version?.en || \"\",\r\n postScriptName: font.names.postScriptName?.en || \"\",\r\n },\r\n };\r\n }\r\n\r\n private static pathToOutline(path: any, scale: number): string {\r\n const commands: string[] = [];\r\n\r\n for (const cmd of path.commands) {\r\n switch (cmd.type) {\r\n case \"M\":\r\n commands.push(`m ${this.round(cmd.x * scale)} ${this.round(cmd.y * scale)}`);\r\n break;\r\n case \"L\":\r\n commands.push(`l ${this.round(cmd.x * scale)} ${this.round(cmd.y * scale)}`);\r\n break;\r\n case \"Q\":\r\n commands.push(\r\n `q ${this.round(cmd.x1 * scale)} ${this.round(cmd.y1 * scale)} ${this.round(\r\n cmd.x * scale\r\n )} ${this.round(cmd.y * scale)}`\r\n );\r\n break;\r\n case \"C\":\r\n commands.push(\r\n `b ${this.round(cmd.x1 * scale)} ${this.round(cmd.y1 * scale)} ${this.round(\r\n cmd.x2 * scale\r\n )} ${this.round(cmd.y2 * scale)} ${this.round(cmd.x * scale)} ${this.round(\r\n cmd.y * scale\r\n )}`\r\n );\r\n break;\r\n case \"Z\":\r\n commands.push(\"z\");\r\n break;\r\n }\r\n }\r\n\r\n return commands.join(\" \");\r\n }\r\n\r\n private static round(value: number): number {\r\n return Math.round(value * 100) / 100;\r\n }\r\n\r\n static isTypefaceJson(url: string): boolean {\r\n const lower = url.toLowerCase();\r\n return lower.endsWith(\".json\") || lower.includes(\"typeface\");\r\n }\r\n\r\n static isFontFile(url: string): boolean {\r\n const lower = url.toLowerCase();\r\n return (\r\n lower.endsWith(\".ttf\") ||\r\n lower.endsWith(\".otf\") ||\r\n lower.endsWith(\".woff\") ||\r\n lower.endsWith(\".woff2\")\r\n );\r\n }\r\n\r\n static clearCache(): void {\r\n this.cache.clear();\r\n }\r\n}\r\n","import { String3DObject } from \"../String3DObject\";\r\nimport type { SyncContext } from \"./SyncContext\";\r\nimport type { String3DObjectSyncStrategy } from \"./String3DObjectSyncStrategy\";\r\nimport { StyleBundleCache } from \"./StyleBundleCache\";\r\nimport { String3DFontRegistry } from \"../text\";\r\nimport { MeshSynchronizer } from \"./MeshSynchronizer\";\r\n\r\nconst DEG_TO_RAD = Math.PI / 180;\r\n\r\nconst DEBUG_TEXT_SYNC = false;\r\n\r\nexport class TextSynchronizer implements String3DObjectSyncStrategy {\r\n private static styleCache = new StyleBundleCache<StyleBundle>();\r\n private static layoutCache = new StyleBundleCache<LayoutBundle>();\r\n private static geometryKeys: WeakMap<String3DObject, string> = new WeakMap();\r\n private static fontCache: Map<string, any> = new Map();\r\n private static fontPromises: Map<string, Promise<any>> = new Map();\r\n private static pendingFontObjects: Map<string, Set<String3DObject>> = new Map();\r\n private static warnedMissingFont = false;\r\n private static warnedMissingLoader = false;\r\n\r\n private static log(...args: any[]): void {\r\n if (DEBUG_TEXT_SYNC) {\r\n console.log(\"[TextSync]\", ...args);\r\n }\r\n }\r\n\r\n private static markObjectPendingFont(fontUrl: string, object: String3DObject): void {\r\n let set = this.pendingFontObjects.get(fontUrl);\r\n if (!set) {\r\n set = new Set();\r\n this.pendingFontObjects.set(fontUrl, set);\r\n }\r\n set.add(object);\r\n this.log(`Marked object ${object.id} as pending font: ${fontUrl}`);\r\n }\r\n\r\n private static clearObjectPendingFont(fontUrl: string, object: String3DObject): void {\r\n const set = this.pendingFontObjects.get(fontUrl);\r\n if (set) {\r\n set.delete(object);\r\n }\r\n }\r\n\r\n private static invalidatePendingObjects(fontUrl: string): void {\r\n const set = this.pendingFontObjects.get(fontUrl);\r\n if (set) {\r\n this.log(`Font loaded: ${fontUrl}, invalidating ${set.size} pending objects`);\r\n set.forEach((obj) => {\r\n this.geometryKeys.delete(obj);\r\n });\r\n set.clear();\r\n }\r\n }\r\n\r\n sync(el: HTMLElement, object: String3DObject, ctx: SyncContext, parentData: any): any {\r\n const { rect, width: originalWidth, height: originalHeight } = this.readLayout(el, ctx);\r\n const bundle = this.readStyleBundle(el, ctx);\r\n\r\n const {\r\n translateZ,\r\n cssScale,\r\n rotateX,\r\n rotateY,\r\n rotateZ,\r\n cssScaleZ,\r\n opacity,\r\n color,\r\n metalness,\r\n roughness,\r\n emissive,\r\n castShadow,\r\n receiveShadow,\r\n fontFamily,\r\n fontSize,\r\n textTransform,\r\n textDepth,\r\n textCurveSegments,\r\n bevelEnabled,\r\n bevelSize,\r\n bevelThickness,\r\n bevelOffset,\r\n bevelSegments,\r\n fontCss,\r\n } = bundle;\r\n\r\n const screenCenterX = rect.left + rect.width * 0.5;\r\n const screenCenterY = rect.top + rect.height * 0.5;\r\n\r\n if (ctx.camera.getMode() === \"orthographic\") {\r\n object.object.position.set(\r\n screenCenterX - ctx.viewportWidth / 2,\r\n -(screenCenterY - ctx.viewportHeight / 2),\r\n translateZ\r\n );\r\n } else {\r\n const frustum = ctx.camera.getFrustumSizeAt(translateZ);\r\n const normalizedX = screenCenterX / ctx.viewportWidth;\r\n const normalizedY = screenCenterY / ctx.viewportHeight;\r\n object.object.position.set(\r\n (normalizedX - 0.5) * frustum.width,\r\n -(normalizedY - 0.5) * frustum.height,\r\n translateZ\r\n );\r\n }\r\n\r\n object.object.rotation.x = -rotateX * DEG_TO_RAD;\r\n object.object.rotation.y = rotateY * DEG_TO_RAD;\r\n object.object.rotation.z = -rotateZ * DEG_TO_RAD;\r\n object.object.rotation.order = \"XYZ\";\r\n\r\n object.object.rotation.z = -rotateZ * DEG_TO_RAD;\r\n object.object.rotation.order = \"XYZ\";\r\n\r\n const layout = this.extractCharacterLayout(el, textTransform);\r\n const textContent = layout.map((l) => l.char).join(\"\");\r\n const useCanvasText = Boolean(fontCss);\r\n\r\n const mesh = this.getTextMesh(object);\r\n if (!mesh) {\r\n TextSynchronizer.log(\"No mesh found for text object\");\r\n return { scale: cssScale * (parentData?.scale || 1) };\r\n }\r\n\r\n if (layout.length === 0) {\r\n TextSynchronizer.log(\"Empty text content, hiding mesh\");\r\n mesh.visible = false;\r\n return { scale: cssScale * (parentData?.scale || 1) };\r\n }\r\n mesh.visible = true;\r\n\r\n const fontEntry = String3DFontRegistry.resolveFontFamily(fontFamily || \"\");\r\n if (!fontEntry) {\r\n if (!TextSynchronizer.warnedMissingFont) {\r\n console.warn(\"[String3D] No registered font found for 3D text. Font family:\", fontFamily);\r\n TextSynchronizer.warnedMissingFont = true;\r\n }\r\n return { scale: cssScale * (parentData?.scale || 1) };\r\n return { scale: cssScale * (parentData?.scale || 1) };\r\n }\r\n\r\n if (!ctx.engine.loadFont || !ctx.engine.createTextGeometry) {\r\n if (!TextSynchronizer.warnedMissingLoader) {\r\n console.warn(\"[String3D] Engine does not support text geometry.\");\r\n TextSynchronizer.warnedMissingLoader = true;\r\n }\r\n return { scale: cssScale * (parentData?.scale || 1) };\r\n }\r\n\r\n const fontUrl = fontEntry.url;\r\n let font = TextSynchronizer.fontCache.get(fontUrl);\r\n if (!font) {\r\n TextSynchronizer.markObjectPendingFont(fontUrl, object);\r\n if (!TextSynchronizer.fontPromises.has(fontUrl)) {\r\n const promise = ctx.engine.loadFont(fontUrl).then((loaded) => {\r\n if (loaded) {\r\n TextSynchronizer.fontCache.set(fontUrl, loaded);\r\n TextSynchronizer.invalidatePendingObjects(fontUrl);\r\n }\r\n return loaded;\r\n });\r\n TextSynchronizer.fontPromises.set(fontUrl, promise);\r\n }\r\n mesh.visible = false;\r\n return { scale: cssScale * (parentData?.scale || 1) };\r\n }\r\n\r\n TextSynchronizer.clearObjectPendingFont(fontUrl, object);\r\n\r\n const layoutSig =\r\n layout.length > 0\r\n ? `${layout.length}:${layout[0].x.toFixed(1)},${layout[0].y.toFixed(1)}:${layout[\r\n layout.length - 1\r\n ].x.toFixed(1)},${layout[layout.length - 1].y.toFixed(1)}`\r\n : \"empty\";\r\n\r\n const key = [\r\n textContent,\r\n fontSize.toFixed(3),\r\n fontCss || \"\",\r\n rect.width.toFixed(1),\r\n rect.height.toFixed(1),\r\n layoutSig,\r\n textDepth.toFixed(3),\r\n textCurveSegments.toFixed(3),\r\n bevelEnabled ? \"1\" : \"0\",\r\n bevelSize.toFixed(3),\r\n bevelThickness.toFixed(3),\r\n bevelOffset.toFixed(3),\r\n bevelSegments.toFixed(3),\r\n ].join(\"|\");\r\n\r\n const prevKey = TextSynchronizer.geometryKeys.get(object);\r\n if (prevKey !== key) {\r\n TextSynchronizer.log(\r\n \"Creating new geometry for\",\r\n textContent.substring(0, 20),\r\n \"Layout:\",\r\n layoutSig\r\n );\r\n\r\n const adjustedLayout = useCanvasText\r\n ? layout\r\n : (() => {\r\n const metrics = TextSynchronizer.getFontMetrics(font, fontSize);\r\n const ascent = metrics ? metrics.ascent : fontSize * 0.8;\r\n return layout.map((item) => ({\r\n ...item,\r\n y: item.y + ascent,\r\n }));\r\n })();\r\n\r\n const geometry = ctx.engine.createTextGeometry(textContent, font, {\r\n size: fontSize,\r\n height: textDepth,\r\n curveSegments: Math.max(1, Math.round(textCurveSegments)),\r\n bevelEnabled,\r\n bevelThickness,\r\n bevelSize,\r\n bevelOffset,\r\n bevelSegments: Math.max(0, Math.round(bevelSegments)),\r\n lineHeight: 0,\r\n letterSpacing: 0,\r\n align: \"left\",\r\n layout: adjustedLayout,\r\n fontCss,\r\n useCanvasText: true,\r\n });\r\n\r\n if (geometry) {\r\n geometry.computeBoundingBox();\r\n if (mesh.geometry) {\r\n mesh.geometry.dispose?.();\r\n }\r\n mesh.geometry = geometry;\r\n object.geometry = geometry;\r\n TextSynchronizer.geometryKeys.set(object, key);\r\n }\r\n }\r\n\r\n const parentScale = parentData?.scale || 1;\r\n const perPixel =\r\n ctx.camera.getMode() === \"orthographic\"\r\n ? 1\r\n : ctx.camera.getScaleAtZ(translateZ, ctx.viewportHeight);\r\n\r\n const scaleFactor = cssScale * parentScale * perPixel;\r\n\r\n const scaleZ = scaleFactor * cssScaleZ;\r\n object.object.scale.set(scaleFactor, scaleFactor, scaleZ);\r\n\r\n const localOffsetX = -originalWidth * 0.5;\r\n const localOffsetY = originalHeight * 0.5;\r\n\r\n mesh.position.set(localOffsetX, localOffsetY, 0);\r\n\r\n MeshSynchronizer.applyVisualProps(el, object, {\r\n opacity,\r\n color: color && color !== \"none\" ? color : undefined,\r\n metalness: Number.isFinite(metalness) ? metalness : undefined,\r\n roughness: Number.isFinite(roughness) ? roughness : undefined,\r\n emissive: emissive && emissive !== \"none\" ? emissive : undefined,\r\n castShadow,\r\n receiveShadow,\r\n });\r\n\r\n this.updateCustomUniforms(el, object, ctx);\r\n\r\n return { scale: scaleFactor };\r\n }\r\n\r\n private extractCharacterLayout(\r\n el: HTMLElement,\r\n transform: string\r\n ): Array<{\r\n char: string;\r\n x: number;\r\n y: number;\r\n width?: number;\r\n height?: number;\r\n scale?: number;\r\n }> {\r\n const layout: Array<{\r\n char: string;\r\n x: number;\r\n y: number;\r\n width?: number;\r\n height?: number;\r\n scale?: number;\r\n }> = [];\r\n if (typeof document === \"undefined\" || !document.createRange) return layout;\r\n\r\n const range = document.createRange();\r\n const elRect = el.getBoundingClientRect();\r\n const walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT);\r\n let node: Node | null;\r\n\r\n while ((node = walker.nextNode())) {\r\n const text = node.textContent || \"\";\r\n if (!text.trim() && text !== \" \") continue;\r\n\r\n for (let i = 0; i < text.length; i++) {\r\n const char = text[i];\r\n if (char === \"\\n\" || char === \"\\r\") continue;\r\n\r\n if (!char.trim()) continue;\r\n\r\n range.setStart(node, i);\r\n range.setEnd(node, i + 1);\r\n const rects = range.getClientRects();\r\n\r\n if (rects.length > 0) {\r\n const r = rects[0];\r\n const x = r.left - elRect.left;\r\n const y = r.top - elRect.top;\r\n\r\n const visibleChar = this.applyTextTransform(char, transform);\r\n\r\n layout.push({\r\n char: visibleChar,\r\n x,\r\n y,\r\n width: r.width,\r\n height: r.height,\r\n });\r\n }\r\n }\r\n }\r\n return layout;\r\n }\r\n\r\n private getTextMesh(object: String3DObject): any | null {\r\n const anyObj = object.object as any;\r\n if (anyObj?.__textMesh) return anyObj.__textMesh;\r\n if (anyObj?.isMesh) return anyObj;\r\n if (Array.isArray(anyObj?.children)) {\r\n const found = anyObj.children.find((child: any) => child?.isMesh);\r\n if (found) {\r\n anyObj.__textMesh = found;\r\n return found;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n private updateCustomUniforms(el: HTMLElement, object: String3DObject, ctx: SyncContext): void {\r\n const factory = ctx.engine.getMaterialFactory?.();\r\n if (!factory) return;\r\n\r\n const style = getComputedStyle(el);\r\n\r\n const apply = (mat: any) => {\r\n const definition = mat?.userData?.definition;\r\n if (!definition?.uniforms) return;\r\n\r\n const values = factory.parseUniformsFromCSS(definition, el, style);\r\n for (const [key, value] of Object.entries(values)) {\r\n const def = definition.uniforms?.[key];\r\n if (!def) continue;\r\n const converter = (factory as any).convertUniformValue?.bind(factory);\r\n const converted = converter ? converter(def.type, value) : value;\r\n\r\n if (mat.userData?.shader?.uniforms?.[key]) {\r\n mat.userData.shader.uniforms[key].value = converted;\r\n } else if (mat.userData?.customUniforms?.[key]) {\r\n mat.userData.customUniforms[key].value = converted;\r\n } else if (mat.uniforms?.[key]) {\r\n mat.uniforms[key].value = converted;\r\n }\r\n }\r\n };\r\n\r\n if (object.object.traverse) {\r\n object.object.traverse((child: any) => {\r\n if (child.isMesh) {\r\n const materials = Array.isArray(child.material) ? child.material : [child.material];\r\n materials.forEach(apply);\r\n }\r\n });\r\n } else {\r\n const mesh = this.getTextMesh(object);\r\n if (!mesh) return;\r\n const materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material];\r\n materials.forEach(apply);\r\n }\r\n }\r\n\r\n private readStyleBundle(el: HTMLElement, ctx: SyncContext): StyleBundle {\r\n return TextSynchronizer.styleCache.get(el, ctx, (el) => {\r\n const styleMap = (el as any).computedStyleMap?.();\r\n const style = getComputedStyle(el);\r\n\r\n const readNumber = (prop: string, fallback: number): number => {\r\n const mapValue = styleMap?.get?.(prop);\r\n if (mapValue !== undefined && mapValue !== null) {\r\n const val =\r\n typeof mapValue === \"object\" && \"value\" in (mapValue as any)\r\n ? (mapValue as any).value\r\n : mapValue;\r\n const num = typeof val === \"number\" ? val : Number.parseFloat(String(val));\r\n if (!Number.isNaN(num)) return num;\r\n }\r\n const raw = style.getPropertyValue(prop);\r\n const num = Number.parseFloat(raw);\r\n return Number.isNaN(num) ? fallback : num;\r\n };\r\n\r\n const readString = (prop: string): string => {\r\n const mapValue = styleMap?.get?.(prop);\r\n const val =\r\n mapValue && typeof mapValue === \"object\" && \"value\" in (mapValue as any)\r\n ? (mapValue as any).value\r\n : mapValue;\r\n if (typeof val === \"string\") return val.trim();\r\n return style.getPropertyValue(prop).trim();\r\n };\r\n\r\n const readBool = (prop: string, fallback = false): boolean => {\r\n const raw = readString(prop);\r\n if (!raw) return fallback;\r\n const norm = raw.toLowerCase();\r\n return norm === \"true\" || norm === \"1\" || norm === \"yes\"\r\n ? true\r\n : norm === \"false\" || norm === \"0\" || norm === \"no\"\r\n ? false\r\n : fallback;\r\n };\r\n\r\n const colorVar = readString(\"--material-color\");\r\n const color = colorVar && colorVar !== \"none\" ? colorVar : style.color.trim();\r\n\r\n const fontSize = (() => {\r\n const raw = style.fontSize || \"\";\r\n const parsed = Number.parseFloat(raw);\r\n return Number.isFinite(parsed) ? parsed : 16;\r\n })();\r\n\r\n const lineHeight = (() => {\r\n const raw = style.lineHeight || \"\";\r\n if (!raw || raw === \"normal\") return fontSize * 1.2;\r\n const parsed = Number.parseFloat(raw);\r\n if (!Number.isFinite(parsed)) return fontSize * 1.2;\r\n return raw.endsWith(\"px\") ? parsed : parsed * fontSize;\r\n })();\r\n\r\n const letterSpacing = (() => {\r\n const raw = style.letterSpacing || \"\";\r\n if (!raw || raw === \"normal\") return 0;\r\n const parsed = Number.parseFloat(raw);\r\n return Number.isFinite(parsed) ? parsed : 0;\r\n })();\r\n\r\n const fit = readString(\"--text-fit\") || \"none\";\r\n\r\n const depthRaw = readNumber(\"--text-depth\", NaN);\r\n const depth = Number.isFinite(depthRaw) ? depthRaw : Math.max(1, fontSize * 0.2);\r\n\r\n const bevelSize = readNumber(\"--text-bevel-size\", 0);\r\n const bevelThickness = readNumber(\"--text-bevel-thickness\", 0);\r\n const bevelOffset = readNumber(\"--text-bevel-offset\", 0);\r\n const bevelSegments = readNumber(\"--text-bevel-steps\", 0);\r\n\r\n const alignRaw = (style.textAlign || \"left\").toLowerCase();\r\n const align =\r\n alignRaw === \"center\"\r\n ? \"center\"\r\n : alignRaw === \"right\" || alignRaw === \"end\"\r\n ? \"right\"\r\n : \"left\";\r\n\r\n const fontCss = style.font?.trim();\r\n const computedFont =\r\n fontCss && fontCss.length > 0\r\n ? fontCss\r\n : [\r\n style.fontStyle || \"normal\",\r\n style.fontWeight || \"normal\",\r\n `${style.fontSize || \"16px\"}/${style.lineHeight || \"normal\"}`,\r\n style.fontFamily || \"sans-serif\",\r\n ].join(\" \");\r\n\r\n return {\r\n translateZ: readNumber(\"--translate-z\", 0),\r\n cssScale: readNumber(\"--scale\", 1),\r\n rotateX: readNumber(\"--rotate-x\", 0),\r\n rotateY: readNumber(\"--rotate-y\", 0),\r\n rotateZ: readNumber(\"--rotate-z\", 0),\r\n cssScaleZ: readNumber(\"--scale-z\", 1),\r\n opacity: readNumber(\"--opacity\", NaN),\r\n color,\r\n metalness: readNumber(\"--material-metalness\", NaN),\r\n roughness: readNumber(\"--material-roughness\", NaN),\r\n emissive: readString(\"--material-emissive\"),\r\n castShadow: readBool(\"--shadow-cast\", false),\r\n receiveShadow: readBool(\"--shadow-receive\", false),\r\n fontFamily: style.fontFamily || \"\",\r\n fontCss: computedFont,\r\n fontSize,\r\n lineHeight,\r\n letterSpacing,\r\n textAlign: align,\r\n textTransform: (style.textTransform || \"\").toLowerCase(),\r\n textDepth: depth,\r\n textCurveSegments: readNumber(\"--text-curve-segments\", 8),\r\n bevelEnabled: bevelSize > 0 || bevelThickness > 0,\r\n bevelSize,\r\n bevelThickness,\r\n bevelOffset,\r\n bevelSegments,\r\n textFit: fit === \"cover\" || fit === \"none\" ? fit : \"contain\",\r\n };\r\n });\r\n }\r\n\r\n private applyTextTransform(text: string, transform: string): string {\r\n if (!transform || transform === \"none\") return text;\r\n if (transform === \"uppercase\") return text.toUpperCase();\r\n if (transform === \"lowercase\") return text.toLowerCase();\r\n if (transform === \"capitalize\") {\r\n return text.replace(/\\b(\\p{L})/gu, (match) => match.toUpperCase());\r\n }\r\n return text;\r\n }\r\n\r\n private static getFontMetrics(\r\n font: any,\r\n fontSize: number\r\n ): { ascent: number; descent: number } | null {\r\n const data = font?.data;\r\n const resolution = Number(data?.resolution);\r\n const ascender = Number(data?.ascender);\r\n const descender = Number(data?.descender);\r\n if (!Number.isFinite(resolution) || resolution <= 0) return null;\r\n if (!Number.isFinite(ascender) || !Number.isFinite(descender)) return null;\r\n const ascent = (ascender / resolution) * fontSize;\r\n const descent = (Math.abs(descender) / resolution) * fontSize;\r\n if (!Number.isFinite(ascent) || !Number.isFinite(descent)) return null;\r\n return { ascent, descent };\r\n }\r\n\r\n private readLayout(el: HTMLElement, ctx: SyncContext): LayoutBundle {\r\n const cached = (el as any).__layoutCache;\r\n if (cached) {\r\n return cached;\r\n }\r\n\r\n return TextSynchronizer.layoutCache.get(el, ctx, (el) => {\r\n const rect = el.getBoundingClientRect();\r\n return { rect, width: rect.width, height: rect.height };\r\n });\r\n }\r\n}\r\n\r\ntype StyleBundle = {\r\n translateZ: number;\r\n cssScale: number;\r\n rotateX: number;\r\n rotateY: number;\r\n rotateZ: number;\r\n cssScaleZ: number;\r\n opacity: number;\r\n color: string;\r\n metalness: number;\r\n roughness: number;\r\n emissive: string;\r\n castShadow: boolean;\r\n receiveShadow: boolean;\r\n fontFamily: string;\r\n fontCss: string;\r\n fontSize: number;\r\n lineHeight: number;\r\n letterSpacing: number;\r\n textAlign: \"left\" | \"center\" | \"right\";\r\n textTransform: string;\r\n textDepth: number;\r\n textCurveSegments: number;\r\n bevelEnabled: boolean;\r\n bevelSize: number;\r\n bevelThickness: number;\r\n bevelOffset: number;\r\n bevelSegments: number;\r\n textFit: \"contain\" | \"cover\" | \"none\";\r\n};\r\n\r\ntype LayoutBundle = {\r\n rect: DOMRect;\r\n width: number;\r\n height: number;\r\n};\r\n","import { String3DCamera } from \"../String3DCamera\";\r\nimport { String3DObject } from \"../String3DObject\";\r\nimport { I3DEngine } from \"../abstractions/I3DEngine\";\r\nimport { GroupSynchronizer } from \"./GroupSynchronizer\";\nimport { LightSynchronizer } from \"./LightSynchronizer\";\nimport { MeshSynchronizer } from \"./MeshSynchronizer\";\nimport { ParticlesSynchronizer } from \"./ParticlesSynchronizer\";\nimport { TextSynchronizer } from \"./TextSynchronizer\";\nimport type { String3DObjectSyncStrategy } from \"./String3DObjectSyncStrategy\";\n\r\nexport class String3DSynchronizer {\n private strategies: Map<string, String3DObjectSyncStrategy> = new Map();\n private styleReadIntervalMs = 0;\n private layoutReadIntervalMs = 0;\n\r\n constructor(\r\n public camera: String3DCamera,\r\n public viewportWidth: number,\r\n public viewportHeight: number,\r\n public engine: I3DEngine\r\n ) {\r\n this.strategies.set(\"box\", new MeshSynchronizer());\r\n this.strategies.set(\"sphere\", new MeshSynchronizer());\r\n this.strategies.set(\"plane\", new MeshSynchronizer());\r\n this.strategies.set(\"cylinder\", new MeshSynchronizer());\r\n this.strategies.set(\"model\", new MeshSynchronizer());\r\n this.strategies.set(\"group\", new GroupSynchronizer());\r\n this.strategies.set(\"pointLight\", new LightSynchronizer());\r\n this.strategies.set(\"ambientLight\", new LightSynchronizer());\r\n this.strategies.set(\"directionalLight\", new LightSynchronizer());\r\n this.strategies.set(\"spotLight\", new LightSynchronizer());\n this.strategies.set(\"hemisphereLight\", new LightSynchronizer());\n this.strategies.set(\"particles\", new ParticlesSynchronizer());\n this.strategies.set(\"text\", new TextSynchronizer());\n }\n\r\n public syncElement(\n el: HTMLElement,\n object: String3DObject,\n parentData: any,\n hints?: { dirtySet?: Set<HTMLElement> | null; forceSync?: boolean }\n ): any {\n const strategy = this.strategies.get(object.type);\n if (!strategy) {\n console.warn(`[String3D Sync] No strategy for type \"${object.type}\"`);\n return null;\n }\n\n return strategy.sync(\n el,\n object,\n {\n camera: this.camera,\n viewportWidth: this.viewportWidth,\n viewportHeight: this.viewportHeight,\n engine: this.engine,\n dirtySet: hints?.dirtySet,\n forceSync: hints?.forceSync,\n styleReadIntervalMs: this.styleReadIntervalMs,\n layoutReadIntervalMs: this.layoutReadIntervalMs,\n },\n parentData\n );\n }\n\n public setSyncOptions(options: { styleReadIntervalMs?: number; layoutReadIntervalMs?: number }): void {\n this.styleReadIntervalMs = Math.max(0, options.styleReadIntervalMs ?? 0);\n this.layoutReadIntervalMs = Math.max(0, options.layoutReadIntervalMs ?? 0);\n }\n\r\n public updateViewportSize(width: number, height: number): void {\n this.viewportWidth = width;\n this.viewportHeight = height;\n }\n}\n","import { String3DObject } from \"../../core/String3DObject\";\n\nexport class DirtySyncManager {\n private readonly attributeFilter: string[];\n private readonly handleScrollBound = () => this.handleScroll();\n private dirtyElements: Set<HTMLElement> = new Set();\n private observedElements: Set<HTMLElement> = new Set();\n private resizeObserver: ResizeObserver | null = null;\n private mutationObserver: MutationObserver | null = null;\n private enabled = false;\n private domVersion = 0;\n\n constructor(attributeFilter: string[]) {\n this.attributeFilter = attributeFilter;\n }\n\n enable(): void {\n if (this.enabled) return;\n this.enabled = true;\n this.setupObservers();\n this.setupScrollListeners();\n }\n\n disable(): void {\n if (!this.enabled) return;\n this.enabled = false;\n this.removeScrollListeners();\n this.resizeObserver?.disconnect();\n this.mutationObserver?.disconnect();\n this.dirtyElements.clear();\n this.observedElements.clear();\n }\n\n observeElement(el: HTMLElement): void {\n if (!this.enabled || this.observedElements.has(el)) return;\n this.observedElements.add(el);\n this.resizeObserver?.observe(el);\n this.mutationObserver?.observe(el, {\n attributes: true,\n attributeFilter: this.attributeFilter,\n });\n }\n\n observeScene(rootObjects: String3DObject[]): void {\n if (!this.enabled) return;\n rootObjects.forEach((obj) => this.observeRecursive(obj));\n }\n\n markDirty(el: HTMLElement): void {\n if (!this.enabled) return;\n this.dirtyElements.add(el);\n this.bumpVersion();\n }\n\n markAllDirty(): void {\n if (!this.enabled) return;\n this.observedElements.forEach((el) => this.dirtyElements.add(el));\n this.bumpVersion();\n }\n\n getDirtySet(): Set<HTMLElement> | null {\n return this.enabled ? this.dirtyElements : null;\n }\n\n clearDirty(): void {\n this.dirtyElements.clear();\n }\n\n getVersion(): number {\n return this.domVersion;\n }\n\n isEnabled(): boolean {\n return this.enabled;\n }\n\n private observeRecursive(object: String3DObject): void {\n if (object.el instanceof HTMLElement) {\n this.observeElement(object.el);\n }\n object.children.forEach((child) => this.observeRecursive(child));\n }\n\n private handleScroll(): void {\n this.markAllDirty();\n }\n\n private setupObservers(): void {\n if (typeof ResizeObserver !== \"undefined\") {\n this.resizeObserver = new ResizeObserver((entries) => {\n entries.forEach((entry) => {\n if (entry.target instanceof HTMLElement) {\n this.markDirty(entry.target);\n }\n });\n });\n }\n\n if (typeof MutationObserver !== \"undefined\") {\n this.mutationObserver = new MutationObserver((mutations) => {\n mutations.forEach((mutation) => {\n if (mutation.target instanceof HTMLElement) {\n this.markDirty(mutation.target);\n }\n });\n });\n }\n }\n\n private setupScrollListeners(): void {\n window.addEventListener(\"scroll\", this.handleScrollBound, { passive: true });\n window.addEventListener(\"resize\", this.handleScrollBound, { passive: true });\n if (window.visualViewport) {\n window.visualViewport.addEventListener(\"scroll\", this.handleScrollBound, { passive: true });\n window.visualViewport.addEventListener(\"resize\", this.handleScrollBound, { passive: true });\n }\n }\n\n private removeScrollListeners(): void {\n window.removeEventListener(\"scroll\", this.handleScrollBound);\n window.removeEventListener(\"resize\", this.handleScrollBound);\n if (window.visualViewport) {\n window.visualViewport.removeEventListener(\"scroll\", this.handleScrollBound);\n window.visualViewport.removeEventListener(\"resize\", this.handleScrollBound);\n }\n }\n\n private bumpVersion(): void {\n this.domVersion += 1;\n }\n}\n","import { String3DObject } from \"../../core/String3DObject\";\r\nimport { String3DCustomFilterRegistry } from \"../../core/filters/String3DCustomFilter\";\r\nimport {\r\n String3DFilterChain,\r\n String3DFilterEffect,\r\n String3DFilterTarget,\r\n} from \"../../core/filters/String3DFilterTypes\";\r\nimport { readFilterRaw } from \"./styleUtils\";\r\n\r\ntype FilterTransitionState = {\r\n raw: string;\r\n effects: String3DFilterChain;\r\n animating: boolean;\r\n from: String3DFilterChain;\r\n to: String3DFilterChain;\r\n startTime: number;\r\n duration: number;\r\n easing: (t: number) => number;\r\n clearOnComplete: boolean;\r\n lastDuration: number;\r\n lastDelay: number;\r\n lastEasing: (t: number) => number;\r\n pendingRaw?: string;\r\n pendingEffects?: String3DFilterChain;\r\n effectsKey?: string;\r\n};\r\n\r\nexport class FilterController {\r\n private filterStates: WeakMap<HTMLElement, FilterTransitionState> = new WeakMap();\r\n private filterWarnings: WeakMap<HTMLElement, string> = new WeakMap();\r\n\r\n constructor(private easingParser?: (value: string) => (t: number) => number) {}\r\n\r\n collectTargets(\r\n rootObjects: String3DObject[],\r\n now: number,\r\n useDirtySync: boolean,\r\n dirtySet: Set<HTMLElement> | null\r\n ): String3DFilterTarget[] {\r\n const targets: String3DFilterTarget[] = [];\r\n const walk = (obj: String3DObject): void => {\r\n const el = obj.el as HTMLElement | undefined;\r\n if (el) {\r\n const animating = this.filterStates.get(el)?.animating === true;\r\n const shouldReadStyle = !useDirtySync || !dirtySet || dirtySet.has(el) || animating;\r\n const chain = this.readFilterChain(el, now, shouldReadStyle);\r\n if (chain && chain.length > 0) {\r\n const dirty = !useDirtySync || !dirtySet || dirtySet.has(el) || animating;\r\n const effectsKey =\r\n this.filterStates.get(el)?.effectsKey || this.stringifyFilterChain(chain);\r\n targets.push({\r\n object: obj,\r\n effects: chain,\r\n effectsKey,\r\n dirty,\r\n });\r\n return;\r\n }\r\n }\r\n obj.children.forEach((child) => walk(child));\r\n };\r\n rootObjects.forEach((obj) => walk(obj));\r\n return targets;\r\n }\r\n\r\n clear(): void {\r\n this.filterStates = new WeakMap();\r\n this.filterWarnings = new WeakMap();\r\n }\r\n\r\n private readFilterChain(\r\n el: HTMLElement,\r\n now: number,\r\n shouldReadStyle: boolean\r\n ): String3DFilterChain | null {\r\n const existing = this.filterStates.get(el);\r\n if (!shouldReadStyle && existing) {\r\n if (existing.animating) {\r\n return this.sampleTransition(existing, now);\r\n }\r\n return existing.effects;\r\n }\r\n\r\n const raw = readFilterRaw(el);\r\n if (!raw || raw === \"none\") {\r\n if (existing) {\r\n if (existing.animating && existing.clearOnComplete) {\r\n const current = this.sampleTransition(existing, now);\r\n if (!existing.animating) {\r\n this.filterStates.delete(el);\r\n return null;\r\n }\r\n return current;\r\n }\r\n let { duration, delay, easing } = this.getFilterTransition(el);\r\n if (duration <= 0 && existing.lastDuration > 0) {\r\n duration = existing.lastDuration;\r\n delay = existing.lastDelay;\r\n easing = existing.lastEasing;\r\n }\r\n if (duration > 0) {\r\n const zero = this.makeZeroChain(existing.effects);\r\n existing.from = existing.effects;\r\n existing.to = zero;\r\n existing.startTime = now + delay;\r\n existing.duration = duration;\r\n existing.easing = easing;\r\n existing.animating = true;\r\n existing.clearOnComplete = true;\r\n existing.lastDuration = duration;\r\n existing.lastDelay = delay;\r\n existing.lastEasing = easing;\r\n return this.sampleTransition(existing, now);\r\n }\r\n }\r\n this.filterStates.delete(el);\r\n return null;\r\n }\r\n\r\n const { effects, warnings } = this.parseFilterChain(raw);\r\n this.warnFilterIssues(el, raw, warnings);\r\n if (effects.length === 0) return null;\r\n\r\n const state = this.filterStates.get(el);\r\n if (!state) {\r\n const { duration, delay, easing } = this.getFilterTransition(el);\r\n if (duration > 0) {\r\n const zero = this.makeZeroChain(effects);\r\n const newState: FilterTransitionState = {\r\n raw,\r\n effects,\r\n animating: true,\r\n from: zero,\r\n to: effects,\r\n startTime: now + delay,\r\n duration,\r\n easing,\r\n clearOnComplete: false,\r\n lastDuration: duration,\r\n lastDelay: delay,\r\n lastEasing: easing,\r\n };\r\n newState.effectsKey = this.stringifyFilterChain(effects);\r\n this.filterStates.set(el, newState);\r\n return this.sampleTransition(newState, now);\r\n }\r\n this.filterStates.set(el, {\r\n raw,\r\n effects,\r\n animating: false,\r\n from: effects,\r\n to: effects,\r\n startTime: 0,\r\n duration: 0,\r\n easing: (t) => t,\r\n clearOnComplete: false,\r\n lastDuration: 0,\r\n lastDelay: 0,\r\n lastEasing: (t) => t,\r\n effectsKey: this.stringifyFilterChain(effects),\r\n });\r\n return effects;\r\n }\r\n\r\n if (state.raw === raw) {\r\n if (state.animating) {\r\n const current = this.sampleTransition(state, now);\r\n if (!state.animating && state.clearOnComplete) {\r\n this.filterStates.delete(el);\r\n return null;\r\n }\r\n return current;\r\n }\r\n return state.effects;\r\n }\r\n\r\n state.pendingEffects = undefined;\r\n state.pendingRaw = undefined;\r\n\r\n let { duration, delay, easing } = this.getFilterTransition(el);\r\n if (duration <= 0 && state.lastDuration > 0) {\r\n duration = state.lastDuration;\r\n delay = state.lastDelay;\r\n easing = state.lastEasing;\r\n }\r\n if (duration > 0) {\r\n const canTween = this.canInterpolate(state.effects, effects);\r\n const current = state.animating ? this.getCurrentChain(state, now) : state.effects;\r\n if (!canTween && this.isZeroChain(effects)) {\r\n state.pendingRaw = raw;\r\n state.pendingEffects = effects;\r\n state.raw = raw;\r\n state.effects = current;\r\n state.from = current;\r\n state.to = this.makeZeroChain(current);\r\n state.startTime = now + delay;\r\n state.duration = duration;\r\n state.easing = easing;\r\n state.animating = true;\r\n state.clearOnComplete = false;\r\n state.lastDuration = duration;\r\n state.lastDelay = delay;\r\n state.lastEasing = easing;\r\n state.effectsKey = this.stringifyFilterChain(effects);\r\n return this.sampleTransition(state, now);\r\n }\r\n\r\n const fromChain = canTween ? current : this.makeZeroChain(effects);\r\n state.raw = raw;\r\n state.effects = effects;\r\n state.from = fromChain;\r\n state.to = effects;\r\n state.startTime = now + delay;\r\n state.duration = duration;\r\n state.easing = easing;\r\n state.animating = true;\r\n state.clearOnComplete = false;\r\n state.lastDuration = duration;\r\n state.lastDelay = delay;\r\n state.lastEasing = easing;\r\n state.effectsKey = this.stringifyFilterChain(effects);\r\n return this.sampleTransition(state, now);\r\n }\r\n\r\n state.raw = raw;\r\n state.effects = effects;\r\n state.animating = false;\r\n state.clearOnComplete = false;\r\n state.effectsKey = this.stringifyFilterChain(effects);\r\n return effects;\r\n }\r\n\r\n private warnFilterIssues(el: HTMLElement, raw: string, warnings: string[]): void {\r\n if (warnings.length === 0) return;\r\n const lastRaw = this.filterWarnings.get(el);\r\n if (lastRaw === raw) return;\r\n warnings.forEach((warning) => console.warn(warning, el));\r\n this.filterWarnings.set(el, raw);\r\n }\r\n\r\n private parseFilterChain(raw: string): { effects: String3DFilterChain; warnings: string[] } {\r\n const warnings: string[] = [];\r\n const effects: String3DFilterChain = [];\r\n\r\n const parseNumber = (value: string): number | null => {\r\n const cleaned = value.trim().toLowerCase();\r\n const match = cleaned.match(/^(-?\\d*\\.?\\d+)(px)?$/);\r\n if (!match) return null;\r\n const num = Number.parseFloat(match[1]);\r\n return Number.isFinite(num) ? num : null;\r\n };\r\n\r\n const parseRatio = (value: string): number | null => {\r\n const cleaned = value.trim().toLowerCase();\r\n if (!cleaned) return null;\r\n if (cleaned.endsWith(\"%\")) {\r\n const num = Number.parseFloat(cleaned.slice(0, -1));\r\n return Number.isFinite(num) ? num / 100 : null;\r\n }\r\n const num = Number.parseFloat(cleaned);\r\n return Number.isFinite(num) ? num : null;\r\n };\r\n\r\n const parseAngle = (value: string): number | null => {\r\n const cleaned = value.trim().toLowerCase();\r\n if (!cleaned) return null;\r\n if (cleaned.endsWith(\"rad\")) {\r\n const num = Number.parseFloat(cleaned.slice(0, -3));\r\n return Number.isFinite(num) ? num : null;\r\n }\r\n const stripped = cleaned.endsWith(\"deg\") ? cleaned.slice(0, -3) : cleaned;\r\n const num = Number.parseFloat(stripped);\r\n return Number.isFinite(num) ? (num * Math.PI) / 180 : null;\r\n };\r\n\r\n const parseBloom = (value: string): { intensity: number; threshold: number } | null => {\r\n const parts = value.split(\",\").map((part) => part.trim());\r\n const intensity = parseNumber(parts[0] || \"\");\r\n if (intensity === null) return null;\r\n const threshold = parts[1] ? parseRatio(parts[1]) : null;\r\n return {\r\n intensity: Math.max(0, intensity),\r\n threshold: threshold === null ? 0.8 : Math.max(0, Math.min(1, threshold)),\r\n };\r\n };\r\n\r\n const parseAmount = (value: string, name: string, allowZero = false): number | null => {\r\n const amount = parseNumber(value);\r\n if (amount === null) {\r\n warnings.push(`[String3D] Invalid ${name} value \"${value}\".`);\r\n return null;\r\n }\r\n if (!allowZero && amount <= 0) {\r\n warnings.push(`[String3D] ${name} must be > 0.`);\r\n return null;\r\n }\r\n return amount;\r\n };\r\n\r\n const parseRatioAmount = (value: string, name: string): number | null => {\r\n const amount = parseRatio(value);\r\n if (amount === null) {\r\n warnings.push(`[String3D] Invalid ${name} value \"${value}\".`);\r\n return null;\r\n }\r\n return amount;\r\n };\r\n\r\n const re = /([a-zA-Z-]+)\\(([^)]*)\\)/g;\r\n let match: RegExpExecArray | null;\r\n while ((match = re.exec(raw))) {\r\n const name = match[1].toLowerCase();\r\n const args = (match[2] || \"\").trim();\r\n\r\n if (name === \"blur\") {\r\n const amount = parseAmount(args, \"blur\", true);\r\n if (amount !== null) effects.push({ type: \"blur\", amount });\r\n } else if (name === \"pixel\" || name === \"pixelate\") {\r\n const size = parseAmount(args, \"pixel\", true);\r\n if (size !== null) effects.push({ type: \"pixel\", size });\r\n } else if (name === \"bloom\") {\r\n const bloom = parseBloom(args);\r\n if (bloom) effects.push({ type: \"bloom\", ...bloom });\r\n else warnings.push(`[String3D] Invalid bloom value \"${args}\".`);\r\n } else if (name === \"brightness\") {\r\n const amount = parseRatioAmount(args, \"brightness\");\r\n if (amount !== null) effects.push({ type: \"brightness\", amount: Math.max(0, amount) });\r\n } else if (name === \"contrast\") {\r\n const amount = parseRatioAmount(args, \"contrast\");\r\n if (amount !== null) effects.push({ type: \"contrast\", amount: Math.max(0, amount) });\r\n } else if (name === \"saturate\") {\r\n const amount = parseRatioAmount(args, \"saturate\");\r\n if (amount !== null) effects.push({ type: \"saturate\", amount: Math.max(0, amount) });\r\n } else if (name === \"grayscale\") {\r\n const amount = parseRatioAmount(args, \"grayscale\");\r\n if (amount !== null)\r\n effects.push({ type: \"grayscale\", amount: Math.max(0, Math.min(1, amount)) });\r\n } else if (name === \"sepia\") {\r\n const amount = parseRatioAmount(args, \"sepia\");\r\n if (amount !== null)\r\n effects.push({ type: \"sepia\", amount: Math.max(0, Math.min(1, amount)) });\r\n } else if (name === \"invert\") {\r\n const amount = parseRatioAmount(args, \"invert\");\r\n if (amount !== null)\r\n effects.push({ type: \"invert\", amount: Math.max(0, Math.min(1, amount)) });\r\n } else if (name === \"hue-rotate\") {\r\n const angle = parseAngle(args);\r\n if (angle !== null) effects.push({ type: \"hue-rotate\", angle });\r\n else warnings.push(`[String3D] Invalid hue-rotate value \"${args}\".`);\r\n } else if (name) {\r\n const custom = String3DCustomFilterRegistry.get(name);\r\n if (custom) {\r\n const parsed = custom.parse ? custom.parse(args) : {};\r\n if (parsed === null) {\r\n warnings.push(`[String3D] Invalid custom filter \"${name}\" args \"${args}\".`);\r\n } else {\r\n effects.push({ type: \"custom\", name, uniforms: parsed });\r\n }\r\n } else {\r\n warnings.push(`[String3D] Unknown filter \"${name}\".`);\r\n }\r\n }\r\n }\r\n\r\n if (effects.length === 0) {\r\n warnings.push(\"[String3D] No valid filters parsed from --filter.\");\r\n }\r\n\r\n return { effects, warnings };\r\n }\r\n\r\n private getFilterTransition(el: HTMLElement): {\r\n duration: number;\r\n delay: number;\r\n easing: (t: number) => number;\r\n } {\r\n const style = getComputedStyle(el);\r\n const properties = this.splitTransitionList(style.transitionProperty);\r\n const durations = this.splitTransitionList(style.transitionDuration);\r\n const delays = this.splitTransitionList(style.transitionDelay);\r\n const timings = this.splitTransitionList(style.transitionTimingFunction);\r\n\r\n const index = this.findTransitionIndex(properties, \"--filter\");\r\n if (index === -1) {\r\n const shorthand = this.parseTransitionShorthand(style.transition);\r\n const fallback = shorthand.get(\"--filter\") || shorthand.get(\"all\");\r\n if (fallback) {\r\n return fallback;\r\n }\r\n return { duration: 0, delay: 0, easing: (t) => t };\r\n }\r\n\r\n const duration = this.parseTime(durations[index] || durations[durations.length - 1] || \"0s\");\r\n const delay = this.parseTime(delays[index] || delays[delays.length - 1] || \"0s\");\r\n const easingRaw = timings[index] || timings[timings.length - 1] || \"linear\";\r\n return { duration, delay, easing: this.parseEasing(easingRaw) };\r\n }\r\n\r\n private splitTransitionList(value: string): string[] {\r\n const result: string[] = [];\r\n let current = \"\";\r\n let depth = 0;\r\n for (let i = 0; i < value.length; i += 1) {\r\n const ch = value[i];\r\n if (ch === \"(\") depth += 1;\r\n if (ch === \")\") depth = Math.max(0, depth - 1);\r\n if (ch === \",\" && depth === 0) {\r\n result.push(current.trim());\r\n current = \"\";\r\n } else {\r\n current += ch;\r\n }\r\n }\r\n if (current.trim()) result.push(current.trim());\r\n return result.length > 0 ? result : [\"all\"];\r\n }\r\n\r\n private findTransitionIndex(properties: string[], name: string): number {\r\n const normalized = properties.map((prop) => prop.trim().toLowerCase());\r\n let index = normalized.indexOf(name);\r\n if (index === -1) {\r\n index = normalized.indexOf(\"all\");\r\n }\r\n return index;\r\n }\r\n\r\n private parseTime(value: string): number {\r\n const raw = value.trim().toLowerCase();\r\n if (raw.endsWith(\"ms\")) {\r\n const num = Number.parseFloat(raw.slice(0, -2));\r\n return Number.isFinite(num) ? num : 0;\r\n }\r\n if (raw.endsWith(\"s\")) {\r\n const num = Number.parseFloat(raw.slice(0, -1));\r\n return Number.isFinite(num) ? num * 1000 : 0;\r\n }\r\n const num = Number.parseFloat(raw);\r\n return Number.isFinite(num) ? num : 0;\r\n }\r\n\r\n private parseTransitionShorthand(\r\n value: string\r\n ): Map<string, { duration: number; delay: number; easing: (t: number) => number }> {\r\n const map = new Map<\r\n string,\r\n { duration: number; delay: number; easing: (t: number) => number }\r\n >();\r\n const parts = this.splitTransitionList(value);\r\n parts.forEach((part) => {\r\n if (!part) return;\r\n const tokens = part.trim().split(/\\s+(?![^()]*\\))/g);\r\n let prop = \"\";\r\n let duration = \"\";\r\n let delay = \"\";\r\n let easing = \"\";\r\n tokens.forEach((token) => {\r\n const lower = token.toLowerCase();\r\n if (lower.endsWith(\"ms\") || lower.endsWith(\"s\") || /^[0-9.]+$/.test(lower)) {\r\n if (!duration) duration = lower;\r\n else if (!delay) delay = lower;\r\n } else if (\r\n lower.startsWith(\"cubic-bezier\") ||\r\n lower.startsWith(\"steps\") ||\r\n lower === \"linear\" ||\r\n lower === \"ease\" ||\r\n lower === \"ease-in\" ||\r\n lower === \"ease-out\" ||\r\n lower === \"ease-in-out\"\r\n ) {\r\n easing = token;\r\n } else if (!prop) {\r\n prop = token;\r\n }\r\n });\r\n if (!prop) return;\r\n map.set(prop.trim().toLowerCase(), {\r\n duration: this.parseTime(duration || \"0s\"),\r\n delay: this.parseTime(delay || \"0s\"),\r\n easing: this.parseEasing(easing || \"linear\"),\r\n });\r\n });\r\n return map;\r\n }\r\n\r\n private parseEasing(value: string): (t: number) => number {\r\n const raw = value.trim();\r\n if (!raw) return (t) => t;\r\n if (!this.easingParser) return (t) => t;\r\n try {\r\n const fn = this.easingParser(raw);\r\n return typeof fn === \"function\" ? fn : (t) => t;\r\n } catch {\r\n return (t) => t;\r\n }\r\n }\r\n\r\n private canInterpolate(from: String3DFilterChain, to: String3DFilterChain): boolean {\r\n if (from.length !== to.length) return false;\r\n return from.every((effect, index) => {\r\n const other = to[index];\r\n if (effect.type !== other.type) return false;\r\n if (effect.type === \"custom\" && other.type === \"custom\") {\r\n if (effect.name !== other.name) return false;\r\n const keys = Object.keys(effect.uniforms || {});\r\n const otherKeys = Object.keys(other.uniforms || {});\r\n if (keys.length !== otherKeys.length) return false;\r\n return keys.every(\r\n (key) => key in (other.uniforms || {}) && this.isNumeric(effect.uniforms?.[key])\r\n );\r\n }\r\n return true;\r\n });\r\n }\r\n\r\n private makeZeroChain(chain: String3DFilterChain): String3DFilterChain {\r\n return chain.map((effect) => {\r\n switch (effect.type) {\r\n case \"blur\":\r\n return { type: \"blur\", amount: 0 };\r\n case \"pixel\":\r\n return { type: \"pixel\", size: 0 };\r\n case \"bloom\":\r\n return { type: \"bloom\", intensity: 0, threshold: effect.threshold };\r\n case \"brightness\":\r\n return { type: \"brightness\", amount: 1 };\r\n case \"contrast\":\r\n return { type: \"contrast\", amount: 1 };\r\n case \"saturate\":\r\n return { type: \"saturate\", amount: 1 };\r\n case \"grayscale\":\r\n return { type: \"grayscale\", amount: 0 };\r\n case \"sepia\":\r\n return { type: \"sepia\", amount: 0 };\r\n case \"invert\":\r\n return { type: \"invert\", amount: 0 };\r\n case \"hue-rotate\":\r\n return { type: \"hue-rotate\", angle: 0 };\r\n case \"custom\": {\r\n const uniforms: Record<string, any> = {};\r\n Object.entries(effect.uniforms || {}).forEach(([key, value]) => {\r\n uniforms[key] = this.isNumeric(value) ? 0 : value;\r\n });\r\n return { type: \"custom\", name: effect.name, uniforms };\r\n }\r\n default:\r\n return effect;\r\n }\r\n });\r\n }\r\n\r\n private sampleTransition(state: FilterTransitionState, now: number): String3DFilterChain {\r\n if (!state.animating) return state.effects;\r\n if (now < state.startTime) {\r\n return state.from;\r\n }\r\n const elapsed = now - state.startTime;\r\n const duration = Math.max(1, state.duration);\r\n const t = Math.min(1, Math.max(0, elapsed / duration));\r\n const eased = state.easing(t);\r\n const interpolated = this.interpolateChain(state.from, state.to, eased);\r\n if (t >= 1) {\r\n state.animating = false;\r\n state.from = state.to;\r\n if (state.pendingEffects && state.pendingRaw === state.raw) {\r\n state.effects = state.pendingEffects;\r\n state.raw = state.pendingRaw || state.raw;\r\n state.pendingEffects = undefined;\r\n state.pendingRaw = undefined;\r\n } else if (state.pendingEffects) {\r\n state.pendingEffects = undefined;\r\n state.pendingRaw = undefined;\r\n }\r\n }\r\n return interpolated;\r\n }\r\n\r\n private getCurrentChain(state: FilterTransitionState, now: number): String3DFilterChain {\r\n if (!state.animating) return state.effects;\r\n if (now < state.startTime) return state.from;\r\n const elapsed = now - state.startTime;\r\n const duration = Math.max(1, state.duration);\r\n const t = Math.min(1, Math.max(0, elapsed / duration));\r\n const eased = state.easing(t);\r\n return this.interpolateChain(state.from, state.to, eased);\r\n }\r\n\r\n private interpolateChain(\r\n from: String3DFilterChain,\r\n to: String3DFilterChain,\r\n t: number\r\n ): String3DFilterChain {\r\n if (!this.canInterpolate(from, to)) return to;\r\n return from.map((effect, index) => this.interpolateEffect(effect, to[index], t));\r\n }\r\n\r\n private interpolateEffect(\r\n from: String3DFilterEffect,\r\n to: String3DFilterEffect,\r\n t: number\r\n ): String3DFilterEffect {\r\n const lerp = (a: number, b: number) => a + (b - a) * t;\r\n if (from.type === \"blur\" && to.type === \"blur\") {\r\n return { type: \"blur\", amount: lerp(from.amount, to.amount) };\r\n }\r\n if (from.type === \"pixel\" && to.type === \"pixel\") {\r\n return { type: \"pixel\", size: lerp(from.size, to.size) };\r\n }\r\n if (from.type === \"bloom\" && to.type === \"bloom\") {\r\n return {\r\n type: \"bloom\",\r\n intensity: lerp(from.intensity, to.intensity),\r\n threshold: lerp(from.threshold, to.threshold),\r\n };\r\n }\r\n if (from.type === \"brightness\" && to.type === \"brightness\") {\r\n return { type: \"brightness\", amount: lerp(from.amount, to.amount) };\r\n }\r\n if (from.type === \"contrast\" && to.type === \"contrast\") {\r\n return { type: \"contrast\", amount: lerp(from.amount, to.amount) };\r\n }\r\n if (from.type === \"saturate\" && to.type === \"saturate\") {\r\n return { type: \"saturate\", amount: lerp(from.amount, to.amount) };\r\n }\r\n if (from.type === \"grayscale\" && to.type === \"grayscale\") {\r\n return { type: \"grayscale\", amount: lerp(from.amount, to.amount) };\r\n }\r\n if (from.type === \"sepia\" && to.type === \"sepia\") {\r\n return { type: \"sepia\", amount: lerp(from.amount, to.amount) };\r\n }\r\n if (from.type === \"invert\" && to.type === \"invert\") {\r\n return { type: \"invert\", amount: lerp(from.amount, to.amount) };\r\n }\r\n if (from.type === \"hue-rotate\" && to.type === \"hue-rotate\") {\r\n return { type: \"hue-rotate\", angle: lerp(from.angle, to.angle) };\r\n }\r\n if (from.type === \"custom\" && to.type === \"custom\" && from.name === to.name) {\r\n const uniforms: Record<string, any> = {};\r\n Object.entries(to.uniforms || {}).forEach(([key, value]) => {\r\n const fromValue = from.uniforms?.[key];\r\n if (this.isNumeric(fromValue) && this.isNumeric(value)) {\r\n uniforms[key] = lerp(fromValue, value);\r\n } else {\r\n uniforms[key] = value;\r\n }\r\n });\r\n return { type: \"custom\", name: to.name, uniforms };\r\n }\r\n return to;\r\n }\r\n\r\n private stringifyFilterChain(chain: String3DFilterChain): string {\r\n const parts = chain.map((effect) => {\r\n if (effect.type === \"blur\") return `blur:${effect.amount}`;\r\n if (effect.type === \"pixel\") return `pixel:${effect.size}`;\r\n if (effect.type === \"bloom\") return `bloom:${effect.intensity},${effect.threshold}`;\r\n if (effect.type === \"brightness\") return `brightness:${effect.amount}`;\r\n if (effect.type === \"contrast\") return `contrast:${effect.amount}`;\r\n if (effect.type === \"saturate\") return `saturate:${effect.amount}`;\r\n if (effect.type === \"grayscale\") return `grayscale:${effect.amount}`;\r\n if (effect.type === \"sepia\") return `sepia:${effect.amount}`;\r\n if (effect.type === \"invert\") return `invert:${effect.amount}`;\r\n if (effect.type === \"hue-rotate\") return `hue-rotate:${effect.angle}`;\r\n if (effect.type === \"custom\") {\r\n const uniforms = Object.keys(effect.uniforms || {})\r\n .sort()\r\n .map((key) => `${key}=${(effect.uniforms as any)[key]}`)\r\n .join(\",\");\r\n return `custom:${effect.name}:${uniforms}`;\r\n }\r\n return \"unknown\";\r\n });\r\n return parts.join(\"|\");\r\n }\r\n\r\n private isNumeric(value: unknown): value is number {\r\n return typeof value === \"number\" && Number.isFinite(value);\r\n }\r\n\r\n private isZeroChain(chain: String3DFilterChain): boolean {\r\n return chain.every((effect) => {\r\n switch (effect.type) {\r\n case \"blur\":\r\n return effect.amount <= 0;\r\n case \"pixel\":\r\n return effect.size <= 0;\r\n case \"bloom\":\r\n return effect.intensity <= 0;\r\n case \"brightness\":\r\n return effect.amount === 1;\r\n case \"contrast\":\r\n return effect.amount === 1;\r\n case \"saturate\":\r\n return effect.amount === 1;\r\n case \"grayscale\":\r\n return effect.amount === 0;\r\n case \"sepia\":\r\n return effect.amount === 0;\r\n case \"invert\":\r\n return effect.amount === 0;\r\n case \"hue-rotate\":\r\n return effect.angle === 0;\r\n case \"custom\":\r\n return false;\r\n default:\r\n return false;\r\n }\r\n });\r\n }\r\n}\r\n","import type {\n String3DCustomMaterialDefinition,\n IMaterialInstance,\n IMaterialFactory,\n} from \"../core/materials\";\nimport { collectUniformsFromCSS, mergeInjections } from \"../core/materials\";\n\nexport class ThreeJSMaterialFactory implements IMaterialFactory {\n private THREE: any;\n private textureLoader: any;\n private textureCache: Map<string, any> = new Map();\n\n constructor(THREE: any) {\n this.THREE = THREE;\n this.textureLoader = new THREE.TextureLoader();\n }\n\n supports(definition: String3DCustomMaterialDefinition): boolean {\n return true;\n }\n\n create(\n definition: String3DCustomMaterialDefinition,\n initialUniforms?: Record<string, any>\n ): IMaterialInstance {\n const uniforms = this.buildUniforms(definition, initialUniforms);\n\n let material: any;\n\n if (definition.extends === \"shader\" || (!definition.extends && definition.vertexShader)) {\n material = this.createShaderMaterial(definition, uniforms);\n } else {\n material = this.createExtendedMaterial(definition, uniforms);\n }\n\n this.applyMaterialProperties(material, definition);\n\n const update = (newUniforms: Record<string, any>) => {\n this.updateUniforms(material, definition, newUniforms);\n };\n\n const dispose = () => {\n material.dispose();\n };\n\n return { material, definition, update, dispose };\n }\n\n parseUniformsFromCSS(\n definition: String3DCustomMaterialDefinition,\n element: HTMLElement,\n style: CSSStyleDeclaration\n ): Record<string, any> {\n return collectUniformsFromCSS(definition, element, style);\n }\n\n private buildUniforms(\n definition: String3DCustomMaterialDefinition,\n initialValues?: Record<string, any>\n ): Record<string, { value: any }> {\n const result: Record<string, { value: any }> = {};\n\n if (definition.uniforms) {\n for (const [key, def] of Object.entries(definition.uniforms)) {\n let value = initialValues?.[key] ?? def.value;\n value = this.convertUniformValue(def.type, value);\n result[key] = { value };\n }\n }\n\n return result;\n }\n\n private convertUniformValue(type: string, value: any): any {\n switch (type) {\n case \"vec2\":\n if (Array.isArray(value)) {\n return new this.THREE.Vector2(value[0], value[1]);\n }\n return value;\n case \"vec3\":\n if (Array.isArray(value)) {\n return new this.THREE.Vector3(value[0], value[1], value[2]);\n }\n return value;\n case \"vec4\":\n if (Array.isArray(value)) {\n return new this.THREE.Vector4(value[0], value[1], value[2], value[3]);\n }\n return value;\n case \"color\":\n if (Array.isArray(value)) {\n return new this.THREE.Color(value[0], value[1], value[2]);\n }\n if (typeof value === \"string\") {\n return new this.THREE.Color(value);\n }\n return value;\n case \"texture\":\n if (typeof value === \"string\" && value) {\n return this.loadTexture(value);\n }\n return value;\n default:\n return value;\n }\n }\n\n private loadTexture(url: string): any {\n if (this.textureCache.has(url)) {\n return this.textureCache.get(url);\n }\n const texture = this.textureLoader.load(url);\n this.textureCache.set(url, texture);\n return texture;\n }\n\n private createShaderMaterial(\n definition: String3DCustomMaterialDefinition,\n uniforms: Record<string, { value: any }>\n ): any {\n const material = new this.THREE.ShaderMaterial({\n uniforms,\n vertexShader: definition.vertexShader || this.getDefaultVertexShader(),\n fragmentShader: definition.fragmentShader || this.getDefaultFragmentShader(),\n lights: definition.lights ?? false,\n transparent: definition.properties?.transparent ?? false,\n });\n material.userData.customUniforms = uniforms;\n material.userData.definition = definition;\n return material;\n }\n\n private createExtendedMaterial(\n definition: String3DCustomMaterialDefinition,\n uniforms: Record<string, { value: any }>\n ): any {\n const baseType = definition.extends || \"standard\";\n let BaseMaterial: any;\n\n switch (baseType) {\n case \"basic\":\n BaseMaterial = this.THREE.MeshBasicMaterial;\n break;\n case \"physical\":\n BaseMaterial = this.THREE.MeshPhysicalMaterial;\n break;\n case \"standard\":\n default:\n BaseMaterial = this.THREE.MeshStandardMaterial;\n break;\n }\n\n const material = new BaseMaterial({\n transparent: definition.properties?.transparent ?? false,\n });\n\n if (definition.injections && definition.injections.length > 0) {\n const injectionMap = mergeInjections(definition.injections);\n\n material.onBeforeCompile = (shader: any) => {\n Object.assign(shader.uniforms, uniforms);\n\n shader.vertexShader = this.injectVertexShader(shader.vertexShader, injectionMap, uniforms);\n shader.fragmentShader = this.injectFragmentShader(\n shader.fragmentShader,\n injectionMap,\n uniforms\n );\n\n material.userData.shader = shader;\n };\n }\n\n material.userData.customUniforms = uniforms;\n material.userData.definition = definition;\n\n return material;\n }\n\n private injectVertexShader(\n shader: string,\n injections: Map<string, string>,\n uniforms: Record<string, { value: any }>\n ): string {\n let result = shader;\n\n const pars = injections.get(\"vertex_pars\");\n if (pars) {\n result = result.replace(\"#include <common>\", `#include <common>\\n${pars}`);\n }\n\n const header = injections.get(\"vertex_header\");\n if (header) {\n const uniformDeclarations = this.generateUniformDeclarations(uniforms);\n result = result.replace(\"void main() {\", `${uniformDeclarations}\\n${header}\\nvoid main() {`);\n }\n\n const transform = injections.get(\"vertex_transform\");\n if (transform) {\n result = result.replace(\"#include <begin_vertex>\", `#include <begin_vertex>\\n${transform}`);\n }\n\n const output = injections.get(\"vertex_output\");\n if (output) {\n result = result.replace(\"#include <project_vertex>\", `${output}\\n#include <project_vertex>`);\n }\n\n return result;\n }\n\n private injectFragmentShader(\n shader: string,\n injections: Map<string, string>,\n uniforms: Record<string, { value: any }>\n ): string {\n let result = shader;\n\n const pars = injections.get(\"fragment_pars\");\n if (pars) {\n result = result.replace(\"#include <common>\", `#include <common>\\n${pars}`);\n }\n\n const header = injections.get(\"fragment_header\");\n if (header) {\n const uniformDeclarations = this.generateUniformDeclarations(uniforms);\n result = result.replace(\"void main() {\", `${uniformDeclarations}\\n${header}\\nvoid main() {`);\n }\n\n const color = injections.get(\"fragment_color\");\n if (color) {\n result = result.replace(\"#include <color_fragment>\", `#include <color_fragment>\\n${color}`);\n }\n\n const normal = injections.get(\"fragment_normal\");\n if (normal) {\n result = result.replace(\n \"#include <normal_fragment_maps>\",\n `#include <normal_fragment_maps>\\n${normal}`\n );\n }\n\n const emissive = injections.get(\"fragment_emissive\");\n if (emissive) {\n result = result.replace(\n \"#include <emissivemap_fragment>\",\n `#include <emissivemap_fragment>\\n${emissive}`\n );\n }\n\n const output = injections.get(\"fragment_output\");\n if (output) {\n result = result.replace(\n \"#include <dithering_fragment>\",\n `${output}\\n#include <dithering_fragment>`\n );\n }\n\n return result;\n }\n\n private generateUniformDeclarations(uniforms: Record<string, { value: any }>): string {\n const lines: string[] = [];\n\n for (const [name, uniform] of Object.entries(uniforms)) {\n const type = this.inferGLSLType(uniform.value);\n lines.push(`uniform ${type} ${name};`);\n }\n\n return lines.join(\"\\n\");\n }\n\n private inferGLSLType(value: any): string {\n if (typeof value === \"number\") return \"float\";\n if (typeof value === \"boolean\") return \"bool\";\n if (value instanceof this.THREE.Vector2) return \"vec2\";\n if (value instanceof this.THREE.Vector3) return \"vec3\";\n if (value instanceof this.THREE.Vector4) return \"vec4\";\n if (value instanceof this.THREE.Color) return \"vec3\";\n if (value instanceof this.THREE.Matrix3) return \"mat3\";\n if (value instanceof this.THREE.Matrix4) return \"mat4\";\n if (value?.isTexture) return \"sampler2D\";\n return \"float\";\n }\n\n private applyMaterialProperties(\n material: any,\n definition: String3DCustomMaterialDefinition\n ): void {\n const props = definition.properties;\n if (!props) return;\n\n if (props.transparent !== undefined) {\n material.transparent = props.transparent;\n }\n\n if (props.side !== undefined) {\n switch (props.side) {\n case \"front\":\n material.side = this.THREE.FrontSide;\n break;\n case \"back\":\n material.side = this.THREE.BackSide;\n break;\n case \"double\":\n material.side = this.THREE.DoubleSide;\n break;\n }\n }\n\n if (props.depthWrite !== undefined) {\n material.depthWrite = props.depthWrite;\n }\n\n if (props.depthTest !== undefined) {\n material.depthTest = props.depthTest;\n }\n\n if (props.blending !== undefined) {\n switch (props.blending) {\n case \"additive\":\n material.blending = this.THREE.AdditiveBlending;\n break;\n case \"subtractive\":\n material.blending = this.THREE.SubtractiveBlending;\n break;\n case \"multiply\":\n material.blending = this.THREE.MultiplyBlending;\n break;\n default:\n material.blending = this.THREE.NormalBlending;\n }\n }\n\n if (props.wireframe !== undefined) {\n material.wireframe = props.wireframe;\n }\n }\n\n private updateUniforms(\n material: any,\n definition: String3DCustomMaterialDefinition,\n newValues: Record<string, any>\n ): void {\n const shader = material.userData?.shader;\n const customUniforms = material.userData?.customUniforms;\n\n if (shader?.uniforms) {\n for (const [key, value] of Object.entries(newValues)) {\n const uniformDef = definition.uniforms?.[key];\n if (uniformDef && shader.uniforms[key]) {\n shader.uniforms[key].value = this.convertUniformValue(uniformDef.type, value);\n }\n }\n } else if (customUniforms) {\n for (const [key, value] of Object.entries(newValues)) {\n const uniformDef = definition.uniforms?.[key];\n if (uniformDef && customUniforms[key]) {\n customUniforms[key].value = this.convertUniformValue(uniformDef.type, value);\n }\n }\n }\n\n if (material.uniforms) {\n for (const [key, value] of Object.entries(newValues)) {\n const uniformDef = definition.uniforms?.[key];\n if (uniformDef && material.uniforms[key]) {\n material.uniforms[key].value = this.convertUniformValue(uniformDef.type, value);\n }\n }\n }\n }\n\n private getDefaultVertexShader(): string {\n return `\n varying vec2 vUv;\n varying vec3 vNormal;\n varying vec3 vPosition;\n\n void main() {\n vUv = uv;\n vNormal = normalize(normalMatrix * normal);\n vPosition = (modelMatrix * vec4(position, 1.0)).xyz;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n `;\n }\n\n private getDefaultFragmentShader(): string {\n return `\n varying vec2 vUv;\n varying vec3 vNormal;\n varying vec3 vPosition;\n\n void main() {\n gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n }\n `;\n }\n\n dispose(): void {\n this.textureCache.forEach((texture) => texture.dispose());\n this.textureCache.clear();\n }\n}\n","import {\r\n I3DEngine,\r\n I3DVector3,\r\n I3DVector2,\r\n I3DQuaternion,\r\n I3DEuler,\r\n I3DMatrix4,\r\n I3DBox3,\r\n I3DScene,\r\n I3DRenderer,\r\n I3DPerspectiveCamera,\r\n I3DOrthographicCamera,\r\n I3DObject,\r\n I3DMesh,\r\n I3DGeometry,\r\n I3DMaterial,\r\n I3DRenderTarget,\r\n I3DLight,\r\n I3DTextureLoader,\r\n I3DModelLoader,\r\n ParticleSystemConfig,\r\n I3DParticleSystem,\r\n} from \"../core/abstractions/I3DEngine\";\r\nimport { I3DEngineProvider } from \"../core/abstractions/I3DEngineProvider\";\r\nimport { IMaterialFactory } from \"../core/materials\";\r\nimport { ThreeJSMaterialFactory } from \"./ThreeJSMaterialFactory\";\r\nimport { FontConverter } from \"../core/text\";\r\n\r\nexport class ThreeJSEngine implements I3DEngine {\r\n private THREE: any;\r\n private loaders: Record<string, any>;\r\n private materialFactory: ThreeJSMaterialFactory | null = null;\r\n private particleModelCache: Map<string, any> = new Map();\r\n private particleModelPromiseCache: Map<string, Promise<any>> = new Map();\r\n private fontCache: Map<string, any> = new Map();\r\n private fontPromiseCache: Map<string, Promise<any>> = new Map();\r\n private fontMetricsCache: Map<string, { ascent: number; descent: number }> = new Map();\r\n\r\n constructor(THREE: any, loaders: Record<string, any> = {}) {\r\n this.THREE = THREE;\r\n this.loaders = loaders;\r\n this.materialFactory = new ThreeJSMaterialFactory(THREE);\r\n }\r\n\r\n getMaterialFactory(): IMaterialFactory | null {\r\n return this.materialFactory;\r\n }\r\n\r\n createVector3(x = 0, y = 0, z = 0): I3DVector3 {\r\n return new this.THREE.Vector3(x, y, z);\r\n }\r\n\r\n createVector2(x = 0, y = 0): I3DVector2 {\r\n return new this.THREE.Vector2(x, y);\r\n }\r\n\r\n createQuaternion(x = 0, y = 0, z = 0, w = 1): I3DQuaternion {\r\n return new this.THREE.Quaternion(x, y, z, w);\r\n }\r\n\r\n createEuler(x = 0, y = 0, z = 0, order = \"XYZ\"): I3DEuler {\r\n return new this.THREE.Euler(x, y, z, order);\r\n }\r\n\r\n createMatrix4(): I3DMatrix4 {\r\n return new this.THREE.Matrix4();\r\n }\r\n\r\n createBox3(min?: I3DVector3, max?: I3DVector3): I3DBox3 {\r\n return new this.THREE.Box3(min, max);\r\n }\r\n\r\n createScene(): I3DScene {\r\n return new this.THREE.Scene();\r\n }\r\n\r\n createRenderer(options?: {\r\n antialias?: boolean;\r\n alpha?: boolean;\r\n logarithmicDepthBuffer?: boolean;\r\n }): I3DRenderer {\r\n const renderer = new this.THREE.WebGLRenderer(options);\r\n renderer.outputEncoding = this.THREE.sRGBEncoding;\r\n return renderer;\r\n }\r\n\r\n createPerspectiveCamera(fov = 45, aspect = 1, near = 0.1, far = 2000): I3DPerspectiveCamera {\r\n return new this.THREE.PerspectiveCamera(fov, aspect, near, far);\r\n }\r\n\r\n createOrthographicCamera(\r\n left: number,\r\n right: number,\r\n top: number,\r\n bottom: number,\r\n near = 0.1,\r\n far = 10000\r\n ): I3DOrthographicCamera {\r\n return new this.THREE.OrthographicCamera(left, right, top, bottom, near, far);\r\n }\r\n\r\n createGroup(): I3DObject {\r\n return new this.THREE.Group();\r\n }\r\n\r\n createMesh(geometry: I3DGeometry, material: I3DMaterial): I3DMesh {\r\n return new this.THREE.Mesh(geometry, material);\r\n }\r\n\r\n createBoxGeometry(width: number, height: number, depth: number): I3DGeometry {\r\n return new this.THREE.BoxGeometry(width, height, depth);\r\n }\r\n\r\n createSphereGeometry(radius: number, widthSegments = 32, heightSegments = 32): I3DGeometry {\r\n return new this.THREE.SphereGeometry(radius, widthSegments, heightSegments);\r\n }\r\n\r\n createPlaneGeometry(width: number, height: number): I3DGeometry {\r\n return new this.THREE.PlaneGeometry(width, height);\r\n }\r\n\r\n createCylinderGeometry(\r\n radiusTop: number,\r\n radiusBottom: number,\r\n height: number,\r\n segments = 32\r\n ): I3DGeometry {\r\n return new this.THREE.CylinderGeometry(radiusTop, radiusBottom, height, segments);\r\n }\r\n\r\n createMeshBasicMaterial(params?: any): I3DMaterial {\r\n return new this.THREE.MeshBasicMaterial(params);\r\n }\r\n\r\n createMeshStandardMaterial(params?: any): I3DMaterial {\r\n return new this.THREE.MeshStandardMaterial(params);\r\n }\r\n\r\n createShaderMaterial(params?: any): I3DMaterial {\r\n return new this.THREE.ShaderMaterial(params);\r\n }\r\n createPointLight(color?: string | number, intensity = 1, distance = 0, decay = 2): I3DLight {\r\n return new this.THREE.PointLight(color, intensity, distance, decay);\r\n }\r\n\r\n createSpotLight(\r\n color?: string | number,\r\n intensity = 1,\r\n distance = 0,\r\n angle = Math.PI / 3,\r\n penumbra = 0,\r\n decay = 1\r\n ): I3DLight {\r\n return new this.THREE.SpotLight(color, intensity, distance, angle, penumbra, decay);\r\n }\r\n\r\n createHemisphereLight(\r\n skyColor?: string | number,\r\n groundColor?: string | number,\r\n intensity = 1\r\n ): I3DLight {\r\n return new this.THREE.HemisphereLight(skyColor, groundColor, intensity);\r\n }\r\n\r\n createAmbientLight(color?: string | number, intensity = 1): I3DLight {\r\n return new this.THREE.AmbientLight(color, intensity);\r\n }\r\n\r\n createDirectionalLight(color?: string | number, intensity = 1): I3DLight {\r\n return new this.THREE.DirectionalLight(color, intensity);\r\n }\r\n\r\n createTextureLoader(): I3DTextureLoader {\r\n return new this.THREE.TextureLoader();\r\n }\r\n\r\n createModelLoader(type: string): I3DModelLoader {\r\n const LoaderClass = this.loaders[type];\r\n if (!LoaderClass) {\r\n throw new Error(`[ThreeJSEngine] Model loader \"${type}\" not registered`);\r\n }\r\n return new LoaderClass();\r\n }\r\n\r\n createRenderTarget(width: number, height: number, options: any = {}): I3DRenderTarget {\r\n const defaults = {\r\n minFilter: this.THREE.LinearFilter,\r\n magFilter: this.THREE.LinearFilter,\r\n format: this.THREE.RGBAFormat,\r\n depthBuffer: true,\r\n stencilBuffer: false,\r\n };\r\n return new this.THREE.WebGLRenderTarget(width, height, { ...defaults, ...options });\r\n }\r\n\r\n loadFont(url: string): Promise<any> {\r\n const normalized = url.trim();\r\n if (!normalized || normalized === \"none\") {\r\n return Promise.resolve(null);\r\n }\r\n if (this.fontCache.has(normalized)) {\r\n return Promise.resolve(this.fontCache.get(normalized));\r\n }\r\n const cachedPromise = this.fontPromiseCache.get(normalized);\r\n if (cachedPromise) return cachedPromise;\r\n\r\n // Determine if this is a font file (TTF/OTF/WOFF) or typeface.json\r\n const isFontFile = FontConverter.isFontFile(normalized);\r\n\r\n let promise: Promise<any>;\r\n\r\n if (isFontFile) {\r\n // Use FontConverter for TTF/OTF/WOFF/WOFF2 files\r\n promise = this.loadFontWithConverter(normalized);\r\n } else {\r\n // Use FontLoader for typeface.json files\r\n promise = this.loadFontWithLoader(normalized);\r\n }\r\n\r\n this.fontPromiseCache.set(normalized, promise);\r\n return promise;\r\n }\r\n\r\n private async loadFontWithConverter(url: string): Promise<any> {\r\n try {\r\n const fontData = await FontConverter.load(url);\r\n // Convert FontData to Three.js Font format\r\n const font = this.createFontFromData(fontData);\r\n this.fontCache.set(url, font);\r\n return font;\r\n } catch (error) {\r\n console.warn(\"[String3D] Font conversion error:\", error);\r\n return null;\r\n }\r\n }\r\n\r\n private loadFontWithLoader(url: string): Promise<any> {\r\n const LoaderClass = this.loaders.font || this.loaders.FontLoader;\r\n if (!LoaderClass) {\r\n console.warn(\"[String3D] No FontLoader registered.\");\r\n return Promise.resolve(null);\r\n }\r\n\r\n const loader = new LoaderClass();\r\n return new Promise<any>((resolve) => {\r\n loader.load(\r\n url,\r\n (font: any) => {\r\n this.fontCache.set(url, font);\r\n resolve(font);\r\n },\r\n undefined,\r\n (error: any) => {\r\n console.warn(\"[String3D] Font loading error:\", error);\r\n resolve(null);\r\n }\r\n );\r\n });\r\n }\r\n\r\n /**\r\n * Create a Three.js-compatible Font object from FontData\r\n */\r\n private createFontFromData(fontData: any): any {\r\n // Create a font object compatible with Three.js Font class\r\n // Three.js Font expects a specific structure with generateShapes method\r\n const font = {\r\n data: fontData,\r\n generateShapes: (text: string, size: number) => {\r\n return this.generateShapesFromFontData(fontData, text, size);\r\n },\r\n };\r\n return font;\r\n }\r\n\r\n /**\r\n * Generate Three.js Shapes from FontData for given text\r\n * This generates shapes for a SINGLE character only (used by buildLineShapes)\r\n */\r\n private generateShapesFromFontData(fontData: any, text: string, size: number): any[] {\r\n const shapes: any[] = [];\r\n const scale = size / fontData.resolution;\r\n\r\n // Only process first character - buildLineShapes handles positioning\r\n const char = text[0];\r\n if (!char) return shapes;\r\n\r\n const glyph = fontData.glyphs[char];\r\n if (!glyph || !glyph.o) return shapes;\r\n\r\n const charShapes = this.parseOutlineToShapes(glyph.o, scale, 0);\r\n shapes.push(...charShapes);\r\n\r\n return shapes;\r\n }\r\n\r\n private parseOutlineToShapes(outline: string, scale: number, offsetX: number = 0): any[] {\r\n if (!outline) return [];\r\n\r\n const shapePath = new this.THREE.ShapePath();\r\n\r\n const commands = outline.split(\" \");\r\n let i = 0;\r\n\r\n while (i < commands.length) {\r\n const cmd = commands[i];\r\n\r\n switch (cmd) {\r\n case \"m\": \r\n {\r\n const mx = parseFloat(commands[i + 1]) * scale + offsetX;\r\n const my = -parseFloat(commands[i + 2]) * scale;\r\n shapePath.moveTo(mx, my);\r\n i += 3;\r\n }\r\n break;\r\n\r\n case \"l\": \r\n {\r\n const lx = parseFloat(commands[i + 1]) * scale + offsetX;\r\n const ly = -parseFloat(commands[i + 2]) * scale;\r\n shapePath.lineTo(lx, ly);\r\n i += 3;\r\n }\r\n break;\r\n\r\n case \"q\": \r\n {\r\n const qx = parseFloat(commands[i + 3]) * scale + offsetX;\r\n const qy = -parseFloat(commands[i + 4]) * scale;\r\n shapePath.quadraticCurveTo(\r\n parseFloat(commands[i + 1]) * scale + offsetX,\r\n -parseFloat(commands[i + 2]) * scale,\r\n qx,\r\n qy\r\n );\r\n i += 5;\r\n }\r\n break;\r\n\r\n case \"b\": \r\n {\r\n const bx = parseFloat(commands[i + 5]) * scale + offsetX;\r\n const by = -parseFloat(commands[i + 6]) * scale;\r\n shapePath.bezierCurveTo(\r\n parseFloat(commands[i + 1]) * scale + offsetX,\r\n -parseFloat(commands[i + 2]) * scale,\r\n parseFloat(commands[i + 3]) * scale + offsetX,\r\n -parseFloat(commands[i + 4]) * scale,\r\n bx,\r\n by\r\n );\r\n i += 7;\r\n }\r\n break;\r\n case \"z\":\r\n {\r\n if (typeof shapePath.closePath === \"function\") {\r\n shapePath.closePath();\r\n } else if (shapePath.currentPath && typeof shapePath.currentPath.closePath === \"function\") {\r\n shapePath.currentPath.closePath();\r\n }\r\n i += 1;\r\n }\r\n break;\r\n\r\n default:\r\n i++;\r\n break;\r\n }\r\n }\r\n\r\n const shapes = shapePath.toShapes(true);\r\n return shapes;\r\n }\r\n \r\n private reversePath(path: any): any {\r\n const newPath = new this.THREE.Path();\r\n if (!path.curves || path.curves.length === 0) return newPath;\r\n \r\n // Start at the END of the last curve\r\n const lastCurve = path.curves[path.curves.length - 1];\r\n const endPoint = lastCurve.v2 || lastCurve.v3 || (lastCurve.getPoint ? lastCurve.getPoint(1) : null);\r\n if (endPoint) {\r\n newPath.moveTo(endPoint.x, endPoint.y);\r\n }\r\n \r\n // Iterate backwards\r\n for (let i = path.curves.length - 1; i >= 0; i--) {\r\n const curve = path.curves[i];\r\n // Check type\r\n if (curve.isLineCurve || curve.type === 'LineCurve' || curve.type === 'LineCurve3') {\r\n newPath.lineTo(curve.v1.x, curve.v1.y);\r\n } else if (curve.isQuadraticBezierCurve || curve.type === 'QuadraticBezierCurve' || curve.type === 'QuadraticBezierCurve3') {\r\n newPath.quadraticCurveTo(curve.v1.x, curve.v1.y, curve.v0.x, curve.v0.y);\r\n } else if (curve.isCubicBezierCurve || curve.type === 'CubicBezierCurve' || curve.type === 'CubicBezierCurve3') {\r\n newPath.bezierCurveTo(curve.v2.x, curve.v2.y, curve.v1.x, curve.v1.y, curve.v0.x, curve.v0.y);\r\n }\r\n }\r\n \r\n return newPath;\r\n }\r\n\r\n createTextGeometry(text: string, font: any, options: any): I3DGeometry | null {\r\n if (!text || !font) return null;\r\n\r\n const size = Math.max(0.001, options.size || 16);\r\n const height = Math.max(0, options.height || 0);\r\n const lineHeight = Math.max(0.001, options.lineHeight || size * 1.2);\r\n const letterSpacing = Number.isFinite(options.letterSpacing) ? options.letterSpacing : 0;\r\n const align = options.align || \"left\";\r\n const bevelEnabled = !!options.bevelEnabled;\r\n const bevelThickness = Math.max(0, options.bevelThickness || 0);\r\n const bevelSize = Math.max(0, options.bevelSize || 0);\r\n const bevelOffset = options.bevelOffset || 0;\r\n const bevelSegments = Math.max(0, options.bevelSegments || 0);\r\n const curveSegments = Math.max(1, Math.round(options.curveSegments || 8));\r\n const useCanvasText =\r\n options.useCanvasText && typeof options.fontCss === \"string\" && options.fontCss.length > 0;\r\n\r\n if (useCanvasText && typeof document !== \"undefined\" && document.fonts) {\r\n const fontCss = options.fontCss as string;\r\n if (!document.fonts.check(fontCss, text)) {\r\n document.fonts.load(fontCss, text).catch(() => null);\r\n return null;\r\n }\r\n }\r\n\r\n const lines = String(text).split(/\\r?\\n/);\r\n const shapes: any[] = [];\r\n lines.forEach((line, index) => {\r\n // If explicit layout is provided, use it instead of line-based logic for this line?\r\n // Actually, if layout is provided, we should probably ignore the `text` splitting logic or apply it differently.\r\n // But let's look at how we want to use it.\r\n // If options.layout is provided, we should probably skip the line splitting and just use the layout items.\r\n });\r\n\r\n const fontMetrics = useCanvasText ? this.measureFontMetrics(options.fontCss) : null;\r\n\r\n if (options.layout) {\r\n options.layout.forEach((item: any) => {\r\n const charShapes = useCanvasText\r\n ? this.buildGlyphShapesFromCanvas(item.char, options.fontCss, options.pixelRatio)\r\n : [];\r\n const resolvedShapes = useCanvasText\r\n ? charShapes\r\n : this.buildLineShapes(\r\n item.char,\r\n font,\r\n size,\r\n 0 // No spacing needed as we position manually\r\n ).shapes;\r\n // Layout coordinates are typically top-left relative.\r\n // In 3D:\r\n // x = item.x\r\n // y = -item.y (inverted)\r\n const offsetX = item.x;\r\n const baselineOffset = useCanvasText\r\n ? Number.isFinite(item.height) && fontMetrics\r\n ? Math.max(0, item.height - fontMetrics.descent)\r\n : fontMetrics?.ascent || 0\r\n : 0;\r\n const offsetY = useCanvasText ? -(item.y + baselineOffset) : -item.y;\r\n\r\n resolvedShapes.forEach((shape) => {\r\n let finalShape = this.translateShape(shape, offsetX, offsetY);\r\n if (item.scale && item.scale !== 1) {\r\n // We need to scale the shape.\r\n // Shape manipulation for scale is harder.\r\n // Easier to scale the geometry later? No, we needed a single geometry.\r\n // We can scale the points of the shape.\r\n finalShape = this.scaleShape(finalShape, item.scale);\r\n }\r\n shapes.push(finalShape);\r\n });\r\n });\r\n } else {\r\n // Fallback to legacy line-based logic\r\n lines.forEach((line, index) => {\r\n const { shapes: lineShapes, width } = this.buildLineShapes(line, font, size, letterSpacing);\r\n let offsetX = 0;\r\n if (align === \"center\") {\r\n offsetX = -width * 0.5;\r\n } else if (align === \"right\") {\r\n offsetX = -width;\r\n }\r\n const offsetY = -index * lineHeight;\r\n lineShapes.forEach((shape) => {\r\n shapes.push(this.translateShape(shape, offsetX, offsetY));\r\n });\r\n });\r\n }\r\n\r\n if (!shapes.length) {\r\n return null;\r\n }\r\n\r\n const geometry = new this.THREE.ExtrudeGeometry(shapes, {\r\n depth: height,\r\n curveSegments,\r\n bevelEnabled,\r\n bevelThickness,\r\n bevelSize,\r\n bevelOffset,\r\n bevelSegments,\r\n });\r\n geometry.computeBoundingBox();\r\n return geometry;\r\n }\r\n\r\n private buildLineShapes(\r\n line: string,\r\n font: any,\r\n size: number,\r\n letterSpacing: number\r\n ): { shapes: any[]; width: number } {\r\n const shapes: any[] = [];\r\n let x = 0;\r\n const chars = Array.from(line);\r\n\r\n // Debug first call only\r\n const debugAdvances: { char: string; advance: number }[] = [];\r\n\r\n chars.forEach((char, index) => {\r\n const charShapes = font.generateShapes(char, size);\r\n charShapes.forEach((shape: any) => {\r\n const translated = this.translateShape(shape, x, 0);\r\n shapes.push(translated);\r\n });\r\n const advance = this.getGlyphAdvance(font, char, size);\r\n\r\n if (debugAdvances.length < 10) {\r\n debugAdvances.push({ char, advance });\r\n }\r\n\r\n x += advance;\r\n if (letterSpacing !== 0 && index < chars.length - 1) {\r\n x += letterSpacing;\r\n }\r\n });\r\n\r\n return { shapes, width: x };\r\n }\r\n\r\n private getGlyphAdvance(font: any, char: string, size: number): number {\r\n const data = font?.data;\r\n const glyphs = data?.glyphs || {};\r\n const glyph = glyphs[char] || glyphs[char.charCodeAt(0)] || glyphs[\"?\"];\r\n const ha = glyph?.ha ?? data?.ha;\r\n const resolution = data?.resolution || 1000;\r\n if (typeof ha === \"number\") {\r\n return (ha / resolution) * size;\r\n }\r\n return size * 0.5;\r\n }\r\n\r\n private translateShape(shape: any, x: number, y: number): any {\r\n if (!shape || (!x && !y)) return shape;\r\n if (typeof shape.translate === \"function\") {\r\n shape.translate(x, y);\r\n return shape;\r\n }\r\n if (typeof shape.applyMatrix4 === \"function\") {\r\n const matrix = new this.THREE.Matrix4().makeTranslation(x, y, 0);\r\n shape.applyMatrix4(matrix);\r\n return shape;\r\n }\r\n if (typeof shape.extractPoints === \"function\") {\r\n const { shape: points, holes } = shape.extractPoints(12);\r\n const toVec2 = (pt: any) => new this.THREE.Vector2((pt.x || 0) + x, (pt.y || 0) + y);\r\n const newShape = new this.THREE.Shape(points.map(toVec2));\r\n if (Array.isArray(holes)) {\r\n holes.forEach((hole: any[]) => {\r\n const holePath = new this.THREE.Path();\r\n holePath.setFromPoints(hole.map(toVec2));\r\n newShape.holes.push(holePath);\r\n });\r\n }\r\n return newShape;\r\n }\r\n return shape;\r\n }\r\n\r\n private scaleShape(shape: any, s: number): any {\r\n if (s === 1) return shape;\r\n if (typeof shape.scale === \"function\") {\r\n shape.scale(s, s);\r\n return shape;\r\n }\r\n // Fallback if shape object doesn't have scale (THREE.Shape doesn't usually have .scale())\r\n // applying matrix\r\n if (typeof shape.applyMatrix4 === \"function\") {\r\n const matrix = new this.THREE.Matrix4().makeScale(s, s, 1);\r\n shape.applyMatrix4(matrix);\r\n return shape;\r\n }\r\n\r\n // Manual point scaling\r\n if (typeof shape.extractPoints === \"function\") {\r\n const { shape: points, holes } = shape.extractPoints(12);\r\n const toVec2 = (pt: any) => new this.THREE.Vector2((pt.x || 0) * s, (pt.y || 0) * s);\r\n const newShape = new this.THREE.Shape(points.map(toVec2));\r\n if (Array.isArray(holes)) {\r\n holes.forEach((hole: any[]) => {\r\n const holePath = new this.THREE.Path();\r\n holePath.setFromPoints(hole.map(toVec2));\r\n newShape.holes.push(holePath);\r\n });\r\n }\r\n return newShape;\r\n }\r\n return shape;\r\n }\r\n\r\n private buildGlyphShapesFromCanvas(\r\n char: string,\r\n fontCss: string,\r\n pixelRatio?: number\r\n ): any[] {\r\n if (!char || !fontCss) return [];\r\n if (!char.trim()) return [];\r\n if (typeof document === \"undefined\") return [];\r\n\r\n const ratio =\r\n typeof pixelRatio === \"number\"\r\n ? Math.max(1, Math.min(3, pixelRatio))\r\n : typeof window !== \"undefined\"\r\n ? Math.max(1, Math.min(3, window.devicePixelRatio || 1))\r\n : 1;\r\n\r\n const canvas = document.createElement(\"canvas\");\r\n const ctx = canvas.getContext(\"2d\", { willReadFrequently: true });\r\n if (!ctx) return [];\r\n\r\n ctx.font = fontCss;\r\n ctx.textBaseline = \"alphabetic\";\r\n ctx.textAlign = \"left\";\r\n\r\n const metrics = ctx.measureText(char);\r\n const leftBearingPx = Number.isFinite(metrics.actualBoundingBoxLeft)\r\n ? metrics.actualBoundingBoxLeft * ratio\r\n : 0;\r\n const ascentPx = Number.isFinite(metrics.actualBoundingBoxAscent)\r\n ? metrics.actualBoundingBoxAscent * ratio\r\n : 0;\r\n\r\n const glyphWidth = Math.max(\r\n 1,\r\n Math.ceil(((metrics.actualBoundingBoxLeft || 0) + (metrics.actualBoundingBoxRight || 0)) * ratio)\r\n );\r\n const glyphHeight = Math.max(\r\n 1,\r\n Math.ceil(((metrics.actualBoundingBoxAscent || 0) + (metrics.actualBoundingBoxDescent || 0)) * ratio)\r\n );\r\n\r\n const pad = Math.ceil(2 * ratio);\r\n canvas.width = glyphWidth + pad * 2;\r\n canvas.height = glyphHeight + pad * 2;\r\n\r\n ctx.clearRect(0, 0, canvas.width, canvas.height);\r\n ctx.font = fontCss;\r\n ctx.textBaseline = \"alphabetic\";\r\n ctx.textAlign = \"left\";\r\n ctx.fillStyle = \"#000\";\r\n\r\n const drawX = pad + leftBearingPx;\r\n const drawY = pad + ascentPx;\r\n ctx.fillText(char, drawX, drawY);\r\n\r\n const image = ctx.getImageData(0, 0, canvas.width, canvas.height);\r\n const contours = this.traceContoursFromAlpha(image.data, canvas.width, canvas.height, 16);\r\n if (!contours.length) return [];\r\n\r\n const scale = 1 / ratio;\r\n return this.contoursToShapes(contours, scale, pad + leftBearingPx, pad + ascentPx);\r\n }\r\n\r\n private measureFontMetrics(fontCss: string): { ascent: number; descent: number } {\r\n if (!fontCss) return { ascent: 0, descent: 0 };\r\n const cached = this.fontMetricsCache.get(fontCss);\r\n if (cached) return cached;\r\n if (typeof document === \"undefined\") {\r\n const fallback = { ascent: 0, descent: 0 };\r\n this.fontMetricsCache.set(fontCss, fallback);\r\n return fallback;\r\n }\r\n const canvas = document.createElement(\"canvas\");\r\n const ctx = canvas.getContext(\"2d\");\r\n if (!ctx) {\r\n const fallback = { ascent: 0, descent: 0 };\r\n this.fontMetricsCache.set(fontCss, fallback);\r\n return fallback;\r\n }\r\n ctx.font = fontCss;\r\n ctx.textBaseline = \"alphabetic\";\r\n const metrics = ctx.measureText(\"Mg\");\r\n const ascent = Number.isFinite(metrics.actualBoundingBoxAscent)\r\n ? metrics.actualBoundingBoxAscent\r\n : 0;\r\n const descent = Number.isFinite(metrics.actualBoundingBoxDescent)\r\n ? metrics.actualBoundingBoxDescent\r\n : 0;\r\n const result = { ascent, descent };\r\n this.fontMetricsCache.set(fontCss, result);\r\n return result;\r\n }\r\n\r\n private traceContoursFromAlpha(\r\n data: Uint8ClampedArray,\r\n width: number,\r\n height: number,\r\n threshold: number\r\n ): Array<Array<{ x: number; y: number }>> {\r\n const inside = (x: number, y: number): boolean => {\r\n if (x < 0 || y < 0 || x >= width || y >= height) return false;\r\n const idx = (y * width + x) * 4 + 3;\r\n return data[idx] >= threshold;\r\n };\r\n\r\n const edgesFrom = new Map<string, string[]>();\r\n const edgeKeys: string[] = [];\r\n const addEdge = (x1: number, y1: number, x2: number, y2: number): void => {\r\n const k1 = `${x1},${y1}`;\r\n const k2 = `${x2},${y2}`;\r\n let list = edgesFrom.get(k1);\r\n if (!list) {\r\n list = [];\r\n edgesFrom.set(k1, list);\r\n }\r\n list.push(k2);\r\n edgeKeys.push(`${k1}|${k2}`);\r\n };\r\n\r\n for (let y = 0; y < height; y += 1) {\r\n for (let x = 0; x < width; x += 1) {\r\n if (!inside(x, y)) continue;\r\n if (!inside(x, y - 1)) {\r\n addEdge(x + 1, y, x, y);\r\n }\r\n if (!inside(x + 1, y)) {\r\n addEdge(x + 1, y + 1, x + 1, y);\r\n }\r\n if (!inside(x, y + 1)) {\r\n addEdge(x, y + 1, x + 1, y + 1);\r\n }\r\n if (!inside(x - 1, y)) {\r\n addEdge(x, y, x, y + 1);\r\n }\r\n }\r\n }\r\n\r\n const used = new Set<string>();\r\n const contours: Array<Array<{ x: number; y: number }>> = [];\r\n const parsePoint = (key: string): { x: number; y: number } => {\r\n const [sx, sy] = key.split(\",\");\r\n return { x: Number(sx), y: Number(sy) };\r\n };\r\n\r\n for (const edgeKey of edgeKeys) {\r\n if (used.has(edgeKey)) continue;\r\n const [startKey, endKey] = edgeKey.split(\"|\");\r\n const loop: Array<{ x: number; y: number }> = [];\r\n used.add(edgeKey);\r\n loop.push(parsePoint(startKey));\r\n let currentKey = endKey;\r\n let guard = 0;\r\n\r\n while (currentKey !== startKey && guard < width * height * 4) {\r\n loop.push(parsePoint(currentKey));\r\n const nextList = edgesFrom.get(currentKey);\r\n if (!nextList || nextList.length === 0) break;\r\n let nextKey: string | null = null;\r\n for (const candidate of nextList) {\r\n const candEdge = `${currentKey}|${candidate}`;\r\n if (!used.has(candEdge)) {\r\n nextKey = candidate;\r\n used.add(candEdge);\r\n break;\r\n }\r\n }\r\n if (!nextKey) break;\r\n currentKey = nextKey;\r\n guard += 1;\r\n }\r\n\r\n if (loop.length >= 3) {\r\n const cleaned = this.simplifyCollinear(loop);\r\n const simplified = this.simplifyRdp(cleaned, 0.75);\r\n if (simplified.length >= 3) {\r\n contours.push(simplified);\r\n }\r\n }\r\n }\r\n\r\n return contours;\r\n }\r\n\r\n private simplifyCollinear(points: Array<{ x: number; y: number }>): Array<{ x: number; y: number }> {\r\n if (points.length < 4) return points;\r\n const result: Array<{ x: number; y: number }> = [];\r\n const len = points.length;\r\n for (let i = 0; i < len; i += 1) {\r\n const prev = points[(i - 1 + len) % len];\r\n const curr = points[i];\r\n const next = points[(i + 1) % len];\r\n const dx1 = curr.x - prev.x;\r\n const dy1 = curr.y - prev.y;\r\n const dx2 = next.x - curr.x;\r\n const dy2 = next.y - curr.y;\r\n const cross = dx1 * dy2 - dy1 * dx2;\r\n if (Math.abs(cross) > 0) {\r\n result.push(curr);\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n private simplifyRdp(\r\n points: Array<{ x: number; y: number }>,\r\n epsilon: number\r\n ): Array<{ x: number; y: number }> {\r\n if (points.length < 3) return points;\r\n const last = points.length - 1;\r\n let maxDist = 0;\r\n let index = 0;\r\n const start = points[0];\r\n const end = points[last];\r\n for (let i = 1; i < last; i += 1) {\r\n const d = this.pointLineDistance(points[i], start, end);\r\n if (d > maxDist) {\r\n maxDist = d;\r\n index = i;\r\n }\r\n }\r\n if (maxDist <= epsilon) {\r\n return [start, end];\r\n }\r\n const left = this.simplifyRdp(points.slice(0, index + 1), epsilon);\r\n const right = this.simplifyRdp(points.slice(index), epsilon);\r\n return left.slice(0, -1).concat(right);\r\n }\r\n\r\n private pointLineDistance(\r\n point: { x: number; y: number },\r\n start: { x: number; y: number },\r\n end: { x: number; y: number }\r\n ): number {\r\n const dx = end.x - start.x;\r\n const dy = end.y - start.y;\r\n if (dx === 0 && dy === 0) {\r\n const px = point.x - start.x;\r\n const py = point.y - start.y;\r\n return Math.sqrt(px * px + py * py);\r\n }\r\n const t = ((point.x - start.x) * dx + (point.y - start.y) * dy) / (dx * dx + dy * dy);\r\n const clamped = Math.max(0, Math.min(1, t));\r\n const projX = start.x + clamped * dx;\r\n const projY = start.y + clamped * dy;\r\n const ox = point.x - projX;\r\n const oy = point.y - projY;\r\n return Math.sqrt(ox * ox + oy * oy);\r\n }\r\n\r\n private contoursToShapes(\r\n contours: Array<Array<{ x: number; y: number }>>,\r\n scale: number,\r\n offsetX: number = 0,\r\n offsetY: number = 0\r\n ): any[] {\r\n if (!contours.length) return [];\r\n const solids: Array<{ shape: any; points: Array<{ x: number; y: number }> }> = [];\r\n const holes: Array<{ path: any; point: { x: number; y: number } }> = [];\r\n\r\n const signedArea = (pts: Array<{ x: number; y: number }>): number => {\r\n let area = 0;\r\n for (let i = 0; i < pts.length; i += 1) {\r\n const a = pts[i];\r\n const b = pts[(i + 1) % pts.length];\r\n area += a.x * b.y - b.x * a.y;\r\n }\r\n return area * 0.5;\r\n };\r\n\r\n const toScaled = (pts: Array<{ x: number; y: number }>) =>\r\n pts.map((p) => ({ x: (p.x - offsetX) * scale, y: -(p.y - offsetY) * scale }));\r\n\r\n for (const contour of contours) {\r\n if (contour.length < 3) continue;\r\n const pts = toScaled(contour);\r\n const area = signedArea(pts);\r\n\r\n if (area >= 0) {\r\n const shape = new this.THREE.Shape();\r\n shape.moveTo(pts[0].x, pts[0].y);\r\n for (let i = 1; i < pts.length; i += 1) {\r\n shape.lineTo(pts[i].x, pts[i].y);\r\n }\r\n if (typeof shape.closePath === \"function\") {\r\n shape.closePath();\r\n }\r\n solids.push({ shape, points: pts });\r\n } else {\r\n const path = new this.THREE.Path();\r\n path.moveTo(pts[0].x, pts[0].y);\r\n for (let i = 1; i < pts.length; i += 1) {\r\n path.lineTo(pts[i].x, pts[i].y);\r\n }\r\n if (typeof path.closePath === \"function\") {\r\n path.closePath();\r\n }\r\n holes.push({ path, point: pts[0] });\r\n }\r\n }\r\n\r\n const pointInPoly = (pt: { x: number; y: number }, poly: Array<{ x: number; y: number }>) => {\r\n let inside = false;\r\n for (let i = 0, j = poly.length - 1; i < poly.length; j = i++) {\r\n const xi = poly[i].x;\r\n const yi = poly[i].y;\r\n const xj = poly[j].x;\r\n const yj = poly[j].y;\r\n const intersect =\r\n yi > pt.y !== yj > pt.y &&\r\n pt.x < ((xj - xi) * (pt.y - yi)) / (yj - yi + Number.EPSILON) + xi;\r\n if (intersect) inside = !inside;\r\n }\r\n return inside;\r\n };\r\n\r\n for (const hole of holes) {\r\n let assigned = false;\r\n for (const solid of solids) {\r\n if (pointInPoly(hole.point, solid.points)) {\r\n solid.shape.holes.push(hole.path);\r\n assigned = true;\r\n break;\r\n }\r\n }\r\n if (!assigned && solids.length > 0) {\r\n solids[0].shape.holes.push(hole.path);\r\n }\r\n }\r\n\r\n return solids.map((s) => s.shape);\r\n }\r\n\r\n private resolveParticleModelGeometry(\r\n modelUrl: string,\r\n loaderType?: string,\r\n nodeName?: string\r\n ): Promise<any | null> {\r\n const url = modelUrl.trim();\r\n if (!url || url === \"none\") {\r\n return Promise.resolve(null);\r\n }\r\n\r\n const normalizedLoader =\r\n loaderType && loaderType !== \"none\"\r\n ? loaderType\r\n : this.loaders.gltf\r\n ? \"gltf\"\r\n : Object.keys(this.loaders)[0];\r\n if (!normalizedLoader) {\r\n console.warn(\"[String3D] No model loader registered for particle models.\");\r\n return Promise.resolve(null);\r\n }\r\n\r\n const nodeKey = (nodeName || \"\").trim();\r\n const cacheKey = `${normalizedLoader}|${url}|${nodeKey}`;\r\n if (this.particleModelCache.has(cacheKey)) {\r\n return Promise.resolve(this.particleModelCache.get(cacheKey));\r\n }\r\n const cachedPromise = this.particleModelPromiseCache.get(cacheKey);\r\n if (cachedPromise) {\r\n return cachedPromise;\r\n }\r\n\r\n const promise = new Promise<any | null>((resolve) => {\r\n let loader: I3DModelLoader | null = null;\r\n try {\r\n loader = this.createModelLoader(normalizedLoader);\r\n } catch (error) {\r\n console.warn(\"[String3D] Failed to create model loader:\", error);\r\n resolve(null);\r\n return;\r\n }\r\n\r\n loader.load(\r\n url,\r\n (gltf: any) => {\r\n const root = gltf?.scene || gltf?.object || gltf;\r\n if (!root) {\r\n resolve(null);\r\n return;\r\n }\r\n let mesh: any = null;\r\n if (nodeKey) {\r\n if (root.getObjectByName) {\r\n const found = root.getObjectByName(nodeKey);\r\n if (found?.isMesh) mesh = found;\r\n }\r\n if (!mesh && root.traverse) {\r\n root.traverse((child: any) => {\r\n if (mesh) return;\r\n if (child?.isMesh && child?.name === nodeKey) {\r\n mesh = child;\r\n }\r\n });\r\n }\r\n }\r\n if (!mesh) {\r\n if (root.isMesh) {\r\n mesh = root;\r\n } else if (root.traverse) {\r\n root.traverse((child: any) => {\r\n if (!mesh && child?.isMesh) {\r\n mesh = child;\r\n }\r\n });\r\n }\r\n }\r\n\r\n const geometry = mesh?.geometry || null;\r\n if (!geometry) {\r\n resolve(null);\r\n return;\r\n }\r\n this.particleModelCache.set(cacheKey, geometry);\r\n resolve(geometry);\r\n },\r\n undefined,\r\n (error: any) => {\r\n console.warn(\"[String3D] Particle model loading error:\", error);\r\n resolve(null);\r\n }\r\n );\r\n });\r\n\r\n this.particleModelPromiseCache.set(cacheKey, promise);\r\n return promise;\r\n }\r\n\r\n createParticleSystem(config: ParticleSystemConfig): I3DParticleSystem {\r\n const THREE = this.THREE;\r\n const engine = this;\r\n\r\n const makeRng = (seed: number) => {\r\n let s = Math.max(1, seed | 0);\r\n return () => {\r\n s ^= s << 13;\r\n s ^= s >> 17;\r\n s ^= s << 5;\r\n return ((s >>> 0) % 100000) / 100000;\r\n };\r\n };\r\n\r\n class ParticleSystem extends THREE.Object3D {\r\n private cfg: ParticleSystemConfig;\r\n private rng = makeRng(config.seed);\r\n private points: any = null;\r\n private instanced: any = null;\r\n private positions: Float32Array = new Float32Array(0);\r\n private velocities: Float32Array = new Float32Array(0);\r\n private life: Float32Array = new Float32Array(0);\r\n private colors: Float32Array = new Float32Array(0);\r\n private sizeFactors: Float32Array = new Float32Array(0);\r\n private alive = 0;\r\n private emitRemainder = 0;\r\n private pendingBurst = 0;\r\n private basePositions: Float32Array = new Float32Array(0);\r\n private baseScales: Float32Array = new Float32Array(0);\r\n private baseJitter: Float32Array = new Float32Array(0);\r\n private basePhase: Float32Array = new Float32Array(0);\r\n private elapsed = 0;\r\n private modelGeometry: any = null;\r\n private modelKey = \"\";\r\n private instancedUsesSharedGeometry = false;\r\n private distributionGeometry: any = null;\r\n private distributionKey = \"\";\r\n private materialOverride: any = null;\r\n private materialOverrideForPoints: any = null;\r\n private defaultEmitterMaterial: any = null;\r\n private defaultInstancedMaterial: any = null;\r\n\r\n constructor(cfg: ParticleSystemConfig) {\r\n super();\r\n this.cfg = { ...cfg };\r\n this.refreshModelGeometry();\r\n this.rebuild();\r\n }\r\n\r\n setConfig(config: ParticleSystemConfig): void {\r\n const prev = this.cfg;\r\n this.cfg = { ...config };\r\n const emitterReset =\r\n this.cfg.mode === \"emitter\" &&\r\n (prev.emitRate !== this.cfg.emitRate ||\r\n prev.emitBurst !== this.cfg.emitBurst ||\r\n prev.particleLife !== this.cfg.particleLife ||\r\n prev.particleSpeed !== this.cfg.particleSpeed ||\r\n !this.isVec3Equal(prev.particleDirection, this.cfg.particleDirection) ||\r\n !this.isVec3Equal(prev.particleGravity, this.cfg.particleGravity) ||\r\n prev.particleDrag !== this.cfg.particleDrag ||\r\n prev.particleSizeVariation !== this.cfg.particleSizeVariation ||\r\n prev.particleColorVariation !== this.cfg.particleColorVariation ||\r\n prev.color !== this.cfg.color);\r\n const needsRebuild =\r\n prev.mode !== this.cfg.mode ||\r\n prev.count !== this.cfg.count ||\r\n prev.seed !== this.cfg.seed ||\r\n prev.spread !== this.cfg.spread ||\r\n prev.particleShape !== this.cfg.particleShape ||\r\n prev.particleModelUrl !== this.cfg.particleModelUrl ||\r\n prev.particleModelLoader !== this.cfg.particleModelLoader ||\r\n prev.particleModelNode !== this.cfg.particleModelNode ||\r\n prev.instanceShape !== this.cfg.instanceShape ||\r\n prev.instanceModelUrl !== this.cfg.instanceModelUrl ||\r\n prev.instanceModelLoader !== this.cfg.instanceModelLoader ||\r\n prev.instanceModelNode !== this.cfg.instanceModelNode ||\r\n prev.instanceScale !== this.cfg.instanceScale ||\r\n prev.instanceScaleVariation !== this.cfg.instanceScaleVariation;\r\n if (needsRebuild) {\r\n this.refreshModelGeometry();\r\n this.refreshDistributionGeometry();\r\n this.rebuild();\r\n return;\r\n }\r\n if (emitterReset) {\r\n this.resetEmitter();\r\n }\r\n if (this.points) {\r\n const uniforms = this.points.material.uniforms;\r\n if (uniforms) {\r\n if (uniforms.uOpacity) {\r\n uniforms.uOpacity.value = this.cfg.opacity;\r\n }\r\n if (uniforms.uSize) {\r\n uniforms.uSize.value = this.cfg.size;\r\n }\r\n if (uniforms.uSizeVar) {\r\n uniforms.uSizeVar.value = this.cfg.particleSizeVariation;\r\n }\r\n if (uniforms.uPointSize) {\r\n uniforms.uPointSize.value = this.cfg.size;\r\n }\r\n }\r\n }\r\n if (this.instanced) {\r\n this.instanced.material.opacity = this.cfg.opacity;\r\n this.instanced.material.color = new THREE.Color(this.cfg.color);\r\n }\r\n this.pendingBurst = this.cfg.emitBurst;\r\n }\r\n\r\n update(dt: number): void {\r\n if (dt <= 0) return;\r\n this.elapsed += dt;\r\n if (this.cfg.mode === \"emitter\") {\r\n this.updateEmitter(dt);\r\n } else {\r\n this.updateInstanced(this.elapsed);\r\n }\r\n }\r\n\r\n dispose(): void {\r\n if (this.points) {\r\n this.points.geometry.dispose();\r\n this.points.material.dispose();\r\n }\r\n if (this.instanced) {\r\n if (!this.instancedUsesSharedGeometry) {\r\n this.instanced.geometry.dispose();\r\n }\r\n this.instanced.material.dispose();\r\n }\r\n }\r\n\r\n private rebuild(): void {\r\n if (this.points) {\r\n this.remove(this.points);\r\n this.points.geometry.dispose();\r\n this.points.material.dispose();\r\n this.points = null;\r\n }\r\n if (this.instanced) {\r\n this.remove(this.instanced);\r\n if (!this.instancedUsesSharedGeometry) {\r\n this.instanced.geometry.dispose();\r\n }\r\n this.instanced.material.dispose();\r\n this.instanced = null;\r\n }\r\n this.elapsed = 0;\r\n\r\n if (this.cfg.mode === \"emitter\") {\r\n this.buildEmitter();\r\n } else {\r\n this.refreshDistributionGeometry();\r\n this.buildInstanced();\r\n }\r\n this.applyMaterialOverrides();\r\n }\r\n\r\n private buildEmitter(): void {\r\n const count = Math.max(1, this.cfg.count);\r\n this.positions = new Float32Array(count * 3);\r\n this.velocities = new Float32Array(count * 3);\r\n this.life = new Float32Array(count);\r\n this.colors = new Float32Array(count * 3);\r\n this.sizeFactors = new Float32Array(count);\r\n const hide = 1e6;\r\n for (let i = 0; i < count; i += 1) {\r\n const i3 = i * 3;\r\n this.positions[i3] = hide;\r\n this.positions[i3 + 1] = hide;\r\n this.positions[i3 + 2] = hide;\r\n }\r\n this.alive = 0;\r\n this.emitRemainder = 0;\r\n this.pendingBurst = this.cfg.emitBurst;\r\n\r\n const geometry = new THREE.BufferGeometry();\r\n geometry.setAttribute(\"position\", new THREE.BufferAttribute(this.positions, 3));\r\n geometry.setAttribute(\"color\", new THREE.BufferAttribute(this.colors, 3));\r\n geometry.setAttribute(\"sizeFactor\", new THREE.BufferAttribute(this.sizeFactors, 1));\r\n const material = new THREE.ShaderMaterial({\r\n transparent: this.cfg.opacity < 1,\r\n depthWrite: false,\r\n uniforms: {\r\n uOpacity: { value: this.cfg.opacity },\r\n uSize: { value: this.cfg.size },\r\n uSizeVar: { value: this.cfg.particleSizeVariation },\r\n },\r\n vertexShader: `\r\n attribute vec3 color;\r\n attribute float sizeFactor;\r\n varying vec3 vColor;\r\n uniform float uSize;\r\n uniform float uSizeVar;\r\n void main() {\r\n vColor = color;\r\n float size = uSize * mix(1.0 - uSizeVar, 1.0, sizeFactor);\r\n gl_PointSize = size;\r\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\r\n }\r\n `,\r\n fragmentShader: `\r\n varying vec3 vColor;\r\n uniform float uOpacity;\r\n void main() {\r\n float dist = length(gl_PointCoord - vec2(0.5));\r\n if (dist > 0.5) discard;\r\n gl_FragColor = vec4(vColor, uOpacity);\r\n }\r\n `,\r\n });\r\n this.points = new THREE.Points(geometry, material);\r\n this.defaultEmitterMaterial = material;\r\n this.add(this.points);\r\n }\r\n\r\n private buildInstanced(): void {\r\n const count = Math.max(1, this.cfg.count);\r\n const useSharedGeometry = this.cfg.particleShape === \"model\" && this.modelGeometry;\r\n const geometry =\r\n this.cfg.particleShape === \"model\" && this.modelGeometry\r\n ? this.modelGeometry\r\n : this.cfg.particleShape === \"box\"\r\n ? new THREE.BoxGeometry(1, 1, 1)\r\n : new THREE.SphereGeometry(0.5, 8, 8);\r\n this.instancedUsesSharedGeometry = useSharedGeometry;\r\n const material = new THREE.MeshStandardMaterial({\r\n color: new THREE.Color(this.cfg.color),\r\n transparent: this.cfg.opacity < 1,\r\n opacity: this.cfg.opacity,\r\n });\r\n this.defaultInstancedMaterial = material;\r\n this.instanced = new THREE.InstancedMesh(geometry, material, count);\r\n this.basePositions = new Float32Array(count * 3);\r\n this.baseScales = new Float32Array(count);\r\n this.baseJitter = new Float32Array(count * 3);\r\n this.basePhase = new Float32Array(count);\r\n this.fillBasePositions(count);\r\n this.applyInstancedTransforms(0);\r\n this.add(this.instanced);\r\n }\r\n\r\n setMaterial(\r\n material: any | null,\r\n options: { points?: boolean; meshes?: boolean } = {}\r\n ): void {\r\n const setPoints = options.points ?? true;\r\n const setMeshes = options.meshes ?? true;\r\n if (setMeshes) {\r\n this.materialOverride = material;\r\n }\r\n if (setPoints) {\r\n this.materialOverrideForPoints = material;\r\n }\r\n this.applyMaterialOverrides();\r\n }\r\n\r\n private updateEmitter(dt: number): void {\r\n const count = this.cfg.count;\r\n const dir = this.normalize(this.cfg.particleDirection);\r\n const gravity = this.cfg.particleGravity;\r\n const drag = Math.max(0, Math.min(1, this.cfg.particleDrag));\r\n const emitRate = this.cfg.emitRate;\r\n const totalToEmit = emitRate * dt + this.emitRemainder;\r\n const emitCount = Math.floor(totalToEmit);\r\n this.emitRemainder = totalToEmit - emitCount;\r\n let colorDirty = false;\r\n const hide = 1e6;\r\n\r\n for (let i = 0; i < emitCount; i += 1) {\r\n this.spawnParticle(dir);\r\n }\r\n while (this.pendingBurst > 0) {\r\n this.spawnParticle(dir);\r\n this.pendingBurst -= 1;\r\n }\r\n\r\n for (let i = 0; i < count; i += 1) {\r\n if (this.life[i] <= 0) continue;\r\n this.life[i] -= dt;\r\n if (this.life[i] <= 0) {\r\n this.life[i] = 0;\r\n const i3 = i * 3;\r\n this.positions[i3] = hide;\r\n this.positions[i3 + 1] = hide;\r\n this.positions[i3 + 2] = hide;\r\n this.colors[i3] = 0;\r\n this.colors[i3 + 1] = 0;\r\n this.colors[i3 + 2] = 0;\r\n colorDirty = true;\r\n continue;\r\n }\r\n const idx = i * 3;\r\n this.velocities[idx] += gravity[0] * dt;\r\n this.velocities[idx + 1] += gravity[1] * dt;\r\n this.velocities[idx + 2] += gravity[2] * dt;\r\n this.velocities[idx] *= 1 - drag * dt;\r\n this.velocities[idx + 1] *= 1 - drag * dt;\r\n this.velocities[idx + 2] *= 1 - drag * dt;\r\n this.positions[idx] += this.velocities[idx] * dt;\r\n this.positions[idx + 1] += this.velocities[idx + 1] * dt;\r\n this.positions[idx + 2] += this.velocities[idx + 2] * dt;\r\n }\r\n\r\n if (this.points) {\r\n this.points.geometry.attributes.position.needsUpdate = true;\r\n if (colorDirty) {\r\n this.points.geometry.attributes.color.needsUpdate = true;\r\n }\r\n }\r\n }\r\n\r\n private spawnParticle(dir: [number, number, number]): void {\r\n const count = this.cfg.count;\r\n let idx = -1;\r\n for (let i = 0; i < count; i += 1) {\r\n if (this.life[i] <= 0) {\r\n idx = i;\r\n break;\r\n }\r\n }\r\n if (idx === -1) return;\r\n\r\n const pos = this.randomInSphere(this.cfg.spread);\r\n const speed =\r\n this.cfg.particleSpeed *\r\n (1 - this.cfg.particleSizeVariation + this.rng() * this.cfg.particleSizeVariation);\r\n const vel = [\r\n dir[0] * speed + (this.rng() - 0.5) * speed * 0.2,\r\n dir[1] * speed + (this.rng() - 0.5) * speed * 0.2,\r\n dir[2] * speed + (this.rng() - 0.5) * speed * 0.2,\r\n ];\r\n\r\n const i3 = idx * 3;\r\n this.positions.set(pos, i3);\r\n this.velocities.set(vel, i3);\r\n this.life[idx] = this.cfg.particleLife;\r\n this.sizeFactors[idx] = this.rng();\r\n\r\n const color = new THREE.Color(this.cfg.color);\r\n if (this.cfg.particleColorVariation > 0) {\r\n color.offsetHSL((this.rng() - 0.5) * this.cfg.particleColorVariation, 0, 0);\r\n }\r\n this.colors[i3] = color.r;\r\n this.colors[i3 + 1] = color.g;\r\n this.colors[i3 + 2] = color.b;\r\n if (this.points) {\r\n this.points.geometry.attributes.color.needsUpdate = true;\r\n this.points.geometry.attributes.sizeFactor.needsUpdate = true;\r\n }\r\n }\r\n\r\n private updateInstanced(time: number): void {\r\n this.applyInstancedTransforms(time);\r\n if (this.instanced) {\r\n this.instanced.instanceMatrix.needsUpdate = true;\r\n }\r\n }\r\n\r\n private applyInstancedTransforms(time: number): void {\r\n if (!this.instanced) return;\r\n const count = this.cfg.count;\r\n const jitter = this.cfg.instanceJitter;\r\n const flow = this.cfg.instanceFlow;\r\n const disperse = Math.max(0, this.cfg.instanceDisperse);\r\n const scatter = Math.max(0, this.cfg.instanceDisperseScatter);\r\n const scatterX =\r\n this.cfg.instanceDisperseScatterX > 0 ? this.cfg.instanceDisperseScatterX : scatter;\r\n const scatterY =\r\n this.cfg.instanceDisperseScatterY > 0 ? this.cfg.instanceDisperseScatterY : scatter;\r\n const scatterZ =\r\n this.cfg.instanceDisperseScatterZ > 0 ? this.cfg.instanceDisperseScatterZ : scatter;\r\n const rotSpeed = this.cfg.instanceRotationSpeed;\r\n const temp = new THREE.Object3D();\r\n for (let i = 0; i < count; i += 1) {\r\n const i3 = i * 3;\r\n const baseX = this.basePositions[i3];\r\n const baseY = this.basePositions[i3 + 1];\r\n const baseZ = this.basePositions[i3 + 2];\r\n const phase = this.basePhase[i];\r\n const driftX = Math.sin((baseY + time * 1.4) * 0.7 + phase) * flow * this.cfg.spread;\r\n const driftY = Math.cos((baseX - time * 1.1) * 0.6 + phase) * flow * this.cfg.spread;\r\n const driftZ = Math.sin((baseZ + time * 1.2) * 0.8 + phase) * flow * this.cfg.spread;\r\n const jitterX = Math.sin(time * 2.1 + phase + this.baseJitter[i3] * 2.5) * jitter;\r\n const jitterY = Math.cos(time * 1.7 + phase + this.baseJitter[i3 + 1] * 2.5) * jitter;\r\n const jitterZ = Math.sin(time * 1.9 + phase + this.baseJitter[i3 + 2] * 2.5) * jitter;\r\n const dispersal = 1 + disperse;\r\n const dirX = this.baseJitter[i3];\r\n const dirY = this.baseJitter[i3 + 1];\r\n const dirZ = this.baseJitter[i3 + 2];\r\n const dirLen = Math.sqrt(dirX * dirX + dirY * dirY + dirZ * dirZ) || 1;\r\n const scatterScale = disperse * this.cfg.spread;\r\n const scatterOffsetX = (dirX / dirLen) * scatterX * scatterScale;\r\n const scatterOffsetY = (dirY / dirLen) * scatterY * scatterScale;\r\n const scatterOffsetZ = (dirZ / dirLen) * scatterZ * scatterScale;\r\n temp.position.set(\r\n baseX * dispersal + scatterOffsetX + driftX + jitterX,\r\n baseY * dispersal + scatterOffsetY + driftY + jitterY,\r\n baseZ * dispersal + scatterOffsetZ + driftZ + jitterZ\r\n );\r\n temp.rotation.set(\r\n this.baseJitter[i3] * 0.5,\r\n time * rotSpeed + i * 0.1,\r\n this.baseJitter[i3 + 2] * 0.5\r\n );\r\n const scale = this.baseScales[i] * this.cfg.size;\r\n temp.scale.set(scale, scale, scale);\r\n temp.updateMatrix();\r\n this.instanced.setMatrixAt(i, temp.matrix);\r\n }\r\n }\r\n\r\n private applyMaterialOverrides(): void {\r\n if (this.points) {\r\n const next = this.materialOverrideForPoints || this.defaultEmitterMaterial;\r\n if (next && this.points.material !== next) {\r\n this.points.material = next;\r\n this.ensurePointMaterial(next);\r\n }\r\n }\r\n if (this.instanced) {\r\n const next = this.materialOverride || this.defaultInstancedMaterial;\r\n if (next && this.instanced.material !== next) {\r\n this.instanced.material = next;\r\n }\r\n }\r\n }\r\n\r\n private ensurePointMaterial(material: any): void {\r\n if (!material?.isShaderMaterial) return;\r\n if (!material.uniforms) {\r\n material.uniforms = {};\r\n }\r\n if (!material.uniforms.uPointSize) {\r\n material.uniforms.uPointSize = { value: this.cfg.size };\r\n }\r\n if (!material.uniforms.uOpacity) {\r\n material.uniforms.uOpacity = { value: this.cfg.opacity };\r\n }\r\n if (!material.vertexShader.includes(\"gl_PointSize\")) {\r\n if (!material.vertexShader.includes(\"uPointSize\")) {\r\n material.vertexShader = `uniform float uPointSize;\\n${material.vertexShader}`;\r\n }\r\n material.vertexShader = material.vertexShader.replace(\r\n /void\\\\s+main\\\\s*\\\\(\\\\)\\\\s*\\\\{/,\r\n \"void main() {\\\\n gl_PointSize = uPointSize;\"\r\n );\r\n material.needsUpdate = true;\r\n }\r\n }\r\n\r\n private refreshModelGeometry(): void {\r\n if (this.cfg.particleShape !== \"model\") {\r\n this.modelGeometry = null;\r\n this.modelKey = \"\";\r\n return;\r\n }\r\n const url = this.cfg.particleModelUrl?.trim();\r\n if (!url || url === \"none\") {\r\n this.modelGeometry = null;\r\n this.modelKey = \"\";\r\n return;\r\n }\r\n const key = `${this.cfg.particleModelLoader}|${url}|${this.cfg.particleModelNode}`;\r\n if (this.modelKey === key && this.modelGeometry) {\r\n return;\r\n }\r\n this.modelKey = key;\r\n engine\r\n .resolveParticleModelGeometry(\r\n url,\r\n this.cfg.particleModelLoader,\r\n this.cfg.particleModelNode\r\n )\r\n .then((geometry) => {\r\n if (!geometry) return;\r\n if (this.modelKey !== key) return;\r\n this.modelGeometry = geometry;\r\n if (this.cfg.mode === \"instanced\" && this.cfg.particleShape === \"model\") {\r\n this.rebuild();\r\n }\r\n });\r\n }\r\n\r\n private refreshDistributionGeometry(): void {\r\n if (this.cfg.instanceShape !== \"model\") {\r\n this.distributionGeometry = null;\r\n this.distributionKey = \"\";\r\n return;\r\n }\r\n const url = this.cfg.instanceModelUrl?.trim();\r\n if (!url || url === \"none\") {\r\n this.distributionGeometry = null;\r\n this.distributionKey = \"\";\r\n return;\r\n }\r\n const key = `${this.cfg.instanceModelLoader}|${url}|${this.cfg.instanceModelNode}`;\r\n if (this.distributionKey === key && this.distributionGeometry) {\r\n return;\r\n }\r\n this.distributionKey = key;\r\n engine\r\n .resolveParticleModelGeometry(\r\n url,\r\n this.cfg.instanceModelLoader,\r\n this.cfg.instanceModelNode\r\n )\r\n .then((geometry) => {\r\n if (!geometry) return;\r\n if (this.distributionKey !== key) return;\r\n this.distributionGeometry = geometry;\r\n if (this.cfg.mode === \"instanced\" && this.cfg.instanceShape === \"model\") {\r\n this.rebuild();\r\n }\r\n });\r\n }\r\n\r\n private fillBasePositions(count: number): void {\r\n const useModel = this.cfg.instanceShape === \"model\" && this.distributionGeometry;\r\n if (useModel) {\r\n this.fillFromModel(count, this.distributionGeometry);\r\n } else {\r\n for (let i = 0; i < count; i += 1) {\r\n const pos =\r\n this.cfg.instanceShape === \"box\"\r\n ? this.randomInBox(this.cfg.spread)\r\n : this.randomInSphere(this.cfg.spread);\r\n this.basePositions.set(pos, i * 3);\r\n }\r\n }\r\n\r\n for (let i = 0; i < count; i += 1) {\r\n const i3 = i * 3;\r\n this.baseJitter[i3] = this.rng() * 2 - 1;\r\n this.baseJitter[i3 + 1] = this.rng() * 2 - 1;\r\n this.baseJitter[i3 + 2] = this.rng() * 2 - 1;\r\n this.basePhase[i] = this.rng() * Math.PI * 2;\r\n const scale =\r\n this.cfg.instanceScale *\r\n (1 - this.cfg.instanceScaleVariation + this.rng() * this.cfg.instanceScaleVariation);\r\n this.baseScales[i] = scale;\r\n }\r\n }\r\n\r\n private fillFromModel(count: number, geometry: any): void {\r\n const attr = geometry?.attributes?.position;\r\n if (!attr?.array || attr.itemSize < 3) {\r\n for (let i = 0; i < count; i += 1) {\r\n const pos = this.randomInSphere(this.cfg.spread);\r\n this.basePositions.set(pos, i * 3);\r\n }\r\n return;\r\n }\r\n\r\n const array = attr.array as ArrayLike<number>;\r\n const itemSize = attr.itemSize;\r\n const vertexCount = Math.floor(array.length / itemSize);\r\n if (vertexCount <= 0) {\r\n return;\r\n }\r\n\r\n const indexArray = geometry?.index?.array as ArrayLike<number> | undefined;\r\n const triangleCount = indexArray\r\n ? Math.floor(indexArray.length / 3)\r\n : Math.floor(vertexCount / 3);\r\n if (triangleCount <= 0) {\r\n return;\r\n }\r\n\r\n let minX = Infinity;\r\n let minY = Infinity;\r\n let minZ = Infinity;\r\n let maxX = -Infinity;\r\n let maxY = -Infinity;\r\n let maxZ = -Infinity;\r\n for (let i = 0; i < vertexCount; i += 1) {\r\n const idx = i * itemSize;\r\n const x = array[idx];\r\n const y = array[idx + 1];\r\n const z = array[idx + 2];\r\n minX = Math.min(minX, x);\r\n minY = Math.min(minY, y);\r\n minZ = Math.min(minZ, z);\r\n maxX = Math.max(maxX, x);\r\n maxY = Math.max(maxY, y);\r\n maxZ = Math.max(maxZ, z);\r\n }\r\n const sizeX = Math.max(1e-6, maxX - minX);\r\n const sizeY = Math.max(1e-6, maxY - minY);\r\n const sizeZ = Math.max(1e-6, maxZ - minZ);\r\n const maxSize = Math.max(sizeX, sizeY, sizeZ);\r\n const targetSize = this.cfg.spread * 2;\r\n const scale = targetSize > 0 ? targetSize / maxSize : 1;\r\n const centerX = (minX + maxX) * 0.5;\r\n const centerY = (minY + maxY) * 0.5;\r\n const centerZ = (minZ + maxZ) * 0.5;\r\n\r\n const cumulativeAreas = new Float32Array(triangleCount);\r\n let totalArea = 0;\r\n for (let i = 0; i < triangleCount; i += 1) {\r\n const base = i * 3;\r\n const ia = indexArray ? indexArray[base] : base;\r\n const ib = indexArray ? indexArray[base + 1] : base + 1;\r\n const ic = indexArray ? indexArray[base + 2] : base + 2;\r\n const a = ia * itemSize;\r\n const b = ib * itemSize;\r\n const c = ic * itemSize;\r\n const ax = array[a];\r\n const ay = array[a + 1];\r\n const az = array[a + 2];\r\n const bx = array[b];\r\n const by = array[b + 1];\r\n const bz = array[b + 2];\r\n const cx = array[c];\r\n const cy = array[c + 1];\r\n const cz = array[c + 2];\r\n const abx = bx - ax;\r\n const aby = by - ay;\r\n const abz = bz - az;\r\n const acx = cx - ax;\r\n const acy = cy - ay;\r\n const acz = cz - az;\r\n const crossX = aby * acz - abz * acy;\r\n const crossY = abz * acx - abx * acz;\r\n const crossZ = abx * acy - aby * acx;\r\n const area = Math.sqrt(crossX * crossX + crossY * crossY + crossZ * crossZ) * 0.5;\r\n totalArea += area;\r\n cumulativeAreas[i] = totalArea;\r\n }\r\n if (totalArea <= 0) {\r\n for (let i = 0; i < count; i += 1) {\r\n const pos = this.randomInSphere(this.cfg.spread);\r\n this.basePositions.set(pos, i * 3);\r\n }\r\n return;\r\n }\r\n\r\n for (let i = 0; i < count; i += 1) {\r\n const r = this.rng() * totalArea;\r\n let lo = 0;\r\n let hi = triangleCount - 1;\r\n while (lo < hi) {\r\n const mid = Math.floor((lo + hi) / 2);\r\n if (r <= cumulativeAreas[mid]) {\r\n hi = mid;\r\n } else {\r\n lo = mid + 1;\r\n }\r\n }\r\n const base = lo * 3;\r\n const ia = indexArray ? indexArray[base] : base;\r\n const ib = indexArray ? indexArray[base + 1] : base + 1;\r\n const ic = indexArray ? indexArray[base + 2] : base + 2;\r\n const a = ia * itemSize;\r\n const b = ib * itemSize;\r\n const c = ic * itemSize;\r\n const ax = array[a];\r\n const ay = array[a + 1];\r\n const az = array[a + 2];\r\n const bx = array[b];\r\n const by = array[b + 1];\r\n const bz = array[b + 2];\r\n const cx = array[c];\r\n const cy = array[c + 1];\r\n const cz = array[c + 2];\r\n const u = this.rng();\r\n const v = this.rng();\r\n const su = Math.sqrt(u);\r\n const w1 = 1 - su;\r\n const w2 = su * (1 - v);\r\n const w3 = su * v;\r\n const x = (ax * w1 + bx * w2 + cx * w3 - centerX) * scale;\r\n const y = (ay * w1 + by * w2 + cy * w3 - centerY) * scale;\r\n const z = (az * w1 + bz * w2 + cz * w3 - centerZ) * scale;\r\n this.basePositions[i * 3] = x;\r\n this.basePositions[i * 3 + 1] = y;\r\n this.basePositions[i * 3 + 2] = z;\r\n }\r\n }\r\n\r\n private resetEmitter(): void {\r\n if (!this.points) return;\r\n const hide = 1e6;\r\n for (let i = 0; i < this.positions.length; i += 3) {\r\n this.positions[i] = hide;\r\n this.positions[i + 1] = hide;\r\n this.positions[i + 2] = hide;\r\n }\r\n this.velocities.fill(0);\r\n this.life.fill(0);\r\n this.colors.fill(0);\r\n this.sizeFactors.fill(0);\r\n this.alive = 0;\r\n this.emitRemainder = 0;\r\n this.pendingBurst = this.cfg.emitBurst;\r\n this.points.geometry.attributes.position.needsUpdate = true;\r\n this.points.geometry.attributes.color.needsUpdate = true;\r\n this.points.geometry.attributes.sizeFactor.needsUpdate = true;\r\n }\r\n\r\n private normalize(vec: [number, number, number]): [number, number, number] {\r\n const len = Math.sqrt(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]) || 1;\r\n return [vec[0] / len, vec[1] / len, vec[2] / len];\r\n }\r\n\r\n private isVec3Equal(a: [number, number, number], b: [number, number, number]): boolean {\r\n return a[0] === b[0] && a[1] === b[1] && a[2] === b[2];\r\n }\r\n\r\n private randomInSphere(radius: number): [number, number, number] {\r\n const u = this.rng();\r\n const v = this.rng();\r\n const theta = u * Math.PI * 2;\r\n const phi = Math.acos(2 * v - 1);\r\n const r = Math.cbrt(this.rng()) * radius;\r\n return [\r\n r * Math.sin(phi) * Math.cos(theta),\r\n r * Math.sin(phi) * Math.sin(theta),\r\n r * Math.cos(phi),\r\n ];\r\n }\r\n\r\n private randomInBox(size: number): [number, number, number] {\r\n const half = size * 0.5;\r\n return [\r\n (this.rng() * 2 - 1) * half,\r\n (this.rng() * 2 - 1) * half,\r\n (this.rng() * 2 - 1) * half,\r\n ];\r\n }\r\n }\r\n\r\n return new ParticleSystem(config) as unknown as I3DParticleSystem;\r\n }\r\n\r\n simplifyGeometry(geometry: I3DGeometry, quality: number): I3DGeometry | null {\r\n const Modifier = (this.THREE as any)?.SimplifyModifier;\r\n if (!Modifier) return null;\r\n const anyGeom: any = geometry as any;\r\n const count = anyGeom?.attributes?.position?.count;\r\n if (!Number.isFinite(count)) return null;\r\n const clamped = Math.max(0.05, Math.min(1, quality));\r\n const target = Math.max(3, Math.floor(count * clamped));\r\n if (target >= count) return geometry;\r\n try {\r\n const modifier = new Modifier();\r\n return modifier.modify(anyGeom, target);\r\n } catch {\r\n return null;\r\n }\r\n }\r\n\r\n degToRad(degrees: number): number {\r\n return this.THREE.MathUtils.degToRad(degrees);\r\n }\r\n\r\n radToDeg(radians: number): number {\r\n return this.THREE.MathUtils.radToDeg(radians);\r\n }\r\n\r\n computeBoundingBoxRecursively(object: I3DObject): I3DBox3 {\r\n const boundingBox = new this.THREE.Box3();\r\n let hasBox = false;\r\n\r\n if (object.traverse) {\r\n object.traverse((child: any) => {\r\n if (!child.visible) return;\r\n if (child.geometry) {\r\n if (typeof child.geometry.computeBoundingBox === \"function\") {\r\n child.geometry.computeBoundingBox();\r\n }\r\n const box = child.geometry.boundingBox;\r\n if (box) {\r\n const childBox = box.clone().applyMatrix4(child.matrixWorld);\r\n boundingBox.union(childBox);\r\n hasBox = true;\r\n }\r\n }\r\n });\r\n }\r\n\r\n return hasBox ? boundingBox : new this.THREE.Box3();\r\n }\r\n}\r\n\r\nexport class ThreeJSProvider implements I3DEngineProvider {\r\n private engine: ThreeJSEngine;\r\n\r\n constructor(THREE: any, loaders: Record<string, any> = {}) {\r\n this.engine = new ThreeJSEngine(THREE, loaders);\r\n }\r\n\r\n getEngine(): I3DEngine {\r\n return this.engine;\r\n }\r\n\r\n getName(): string {\r\n return \"Three.js\";\r\n }\r\n}\r\n"],"mappings":"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","names":["index_exports","__export","FontConverter","String3D","String3DCamera","String3DCustomFilterRegistry","String3DCustomMaterialRegistry","String3DFontRegistry","String3DObject","String3DRenderer","String3DScene","String3DSynchronizer","ThreeJSEngine","ThreeJSMaterialFactory","ThreeJSProvider","__toCommonJS","import_string_tune","String3DCamera","engine","mode","fov","near","far","width","height","ortho","x","y","z","screenX","screenY","normalizedX","normalizedY","distance","viewportHeight","roundedZ","scale","String3DCustomFilterRegistry","definition","name","RenderTargetPool","create","width","height","target","String3DFilterPipeline","engine","renderer","geometry","w","h","scale","next","input","effects","quality","current","locals","releaseLocal","idx","acquire","effect","radius","first","second","output","intensity","blurRadius","extracted","blur1","blur2","combined","mode","amount","material","uniforms","clear","key","value","base","bloom","object","anyObj","name","type","params","normalized","def","String3DCustomFilterRegistry","String3DRenderer","container","engine","width","height","rendererAny","scene","camera","filterTargets","pipeline","allObjects","visibility","obj","anyObj","filteredSet","target","prevAutoClear","originalVisible","lights","supportsLayers","cache","effects","allowed","restoreLayers","restoreCameraMask","subtree","input","output","entry","existing","String3DFilterPipeline","object","set","child","visible","el","cached","rect","cx","cy","clamp","value","effect","center","changed","next","uniforms","filterCount","now","dt","fps","countScale","targetScale","maxAge","key","objects","layer","restoredMap","apply","setMode","light","mask","entries","prev","String3DObject","id","type","object","engine","options","child","originalScale","matrix","pos","quat","scale","position","quaternion","euler","value","mat","texture","material","geometry","result","walk","obj","anyObj","childMat","StyleReader","el","prop","fallback","mapValue","val","num","raw","value","norm","readNumberStyle","parsed","stripQuotes","readStringStyle","style","readBooleanStyle","normalized","readFilterRaw","styleMap","String3DCustomMaterialRegistry","definition","name","css","uniforms","def","cssVar","syntax","err","type","parseUniformValue","def","cssValue","trimmed","num","parts","s","n","parseColorValue","match","value","hex","g","b","rgbMatch","collectUniformsFromCSS","definition","element","style","result","parsed","key","mergeInjections","injections","grouped","injection","list","point","sorted","i","String3DScene","engine","options","id","result","walk","obj","child","root","object","type","element","onAdd","added3DObject","parentId","group","String3DObject","kind","colorRaw","readStringStyle","color","intensity","readNumberStyle","light","distance","decay","angle","penumbra","groundRaw","groundColor","readBooleanStyle","bias","mapSize","mesh","castShadow","receiveShadow","geometry","material","quality","widthSegments","heightSegments","segments","modelPath","loaderType","loader","shouldCenter","gltf","overrideMaterial","xhr","error","config","system","bbox","center","box","style","getCSS","prop","resolve","cssProp","parser","defaultValue","cssVal","parseNumber","v","parseColor","parseUrl","match","customMaterial","opacity","metalness","roughness","emissive","params","mapSrc","normalMapSrc","roughnessMapSrc","metalnessMapSrc","aoMapSrc","flipY","colorSpace","hasMaps","finalType","definition","String3DCustomMaterialRegistry","factory","initialUniforms","instance","objectId","uniforms","src","texture","value","normalized","hasStyle","val","baseRaw","base","mappingRaw","mapping","manager","url","mapped","StyleBundleCache","el","ctx","reader","cached","now","interval","metaData","bundle","DEG_TO_RAD","_GroupSynchronizer","el","object","ctx","parentData","cached","rect","bundle","screenCenterX","screenCenterY","frustum","normalizedX","normalizedY","styles","StyleReader","StyleBundleCache","GroupSynchronizer","_LightSynchronizer","el","object","ctx","parentData","cached","rect","bundle","screenCenterX","screenCenterY","frustum","normalizedX","normalizedY","light","targetEl","tCached","tRect","tTranslateZ","StyleReader","tScreenCenterX","tScreenCenterY","x","y","z","styles","groundColor","targetId","offsetRaw","offset","value","parts","part","num","StyleBundleCache","LightSynchronizer","DEG_TO_RAD","_MeshSynchronizer","el","object","props","prev","castShadow","receiveShadow","opacity","applyMaterialProps","mat","child","mesh","ctx","parentData","rect","originalWidth","originalHeight","bundle","translateZ","cssScale","rotateX","rotateY","rotateZ","cssScaleZ","color","metalness","roughness","emissive","geometryQuality","screenCenterX","screenCenterY","frustum","normalizedX","normalizedY","targetWidth","targetHeight","parentScale","baseScaleZ","minTargetSize","scaleX","scaleY","scaleZ","uniformSize","bbox","size","fitMode","modelScale","finalModelScale","scaleW","scaleH","uniformScale","fallbackSize","quality","engine","simplify","normalized","applyToMesh","userData","original","key","simplified","factory","style","apply","definition","values","value","def","converter","converted","styleMap","readNumber","prop","fallback","mapValue","val","num","readString","readBool","raw","norm","cached","width","height","StyleBundleCache","MeshSynchronizer","DEG_TO_RAD","DEFAULT_CONFIG","_ParticlesSynchronizer","el","object","ctx","parentData","cached","rect","bundle","screenCenterX","screenCenterY","frustum","normalizedX","normalizedY","parentScale","scale","config","prev","now","last","dt","styles","StyleReader","mode","value","fallback","parts","part","num","normalized","fitBase","fitMultiplier","spreadPixels","spread","z","perPixel","a","b","type","definition","String3DCustomMaterialRegistry","factory","existing","style","initialUniforms","instance","material","isShader","system","apply","mat","values","key","def","converter","converted","child","StyleBundleCache","ParticlesSynchronizer","String3DFontRegistry","name","url","normalized","fontFamily","families","value","family","entry","opentypePromise","opentypeModule","woff2Promise","woff2Module","loadOpentype","resolve","reject","script","loadWoff2Decoder","attempts","maxAttempts","checkReady","win","decompressWoff2","buffer","woff2","inputArray","outputArray","newBuffer","isWoff2","FontConverter","source","cacheKey","cached","loading","promise","result","opentype","loadOpentype","buffer","isWoff2","decompressWoff2","font","scale","glyphs","glyph","char","path","outline","advanceWidth","spaceGlyph","commands","cmd","value","url","lower","DEG_TO_RAD","DEBUG_TEXT_SYNC","_TextSynchronizer","args","fontUrl","object","set","obj","el","ctx","parentData","rect","originalWidth","originalHeight","bundle","translateZ","cssScale","rotateX","rotateY","rotateZ","cssScaleZ","opacity","color","metalness","roughness","emissive","castShadow","receiveShadow","fontFamily","fontSize","textTransform","textDepth","textCurveSegments","bevelEnabled","bevelSize","bevelThickness","bevelOffset","bevelSegments","fontCss","screenCenterX","screenCenterY","frustum","normalizedX","normalizedY","layout","textContent","l","useCanvasText","mesh","fontEntry","String3DFontRegistry","font","promise","loaded","layoutSig","key","adjustedLayout","metrics","ascent","item","geometry","parentScale","perPixel","scaleFactor","scaleZ","localOffsetX","localOffsetY","MeshSynchronizer","transform","range","elRect","walker","node","text","i","char","rects","r","x","y","visibleChar","anyObj","found","child","factory","style","apply","mat","definition","values","value","def","converter","converted","styleMap","readNumber","prop","fallback","mapValue","val","num","raw","readString","readBool","norm","colorVar","parsed","lineHeight","letterSpacing","fit","depthRaw","depth","alignRaw","align","computedFont","match","data","resolution","ascender","descender","descent","cached","StyleBundleCache","TextSynchronizer","String3DSynchronizer","camera","viewportWidth","viewportHeight","engine","MeshSynchronizer","GroupSynchronizer","LightSynchronizer","ParticlesSynchronizer","TextSynchronizer","el","object","parentData","hints","strategy","options","width","height","DirtySyncManager","attributeFilter","el","rootObjects","obj","object","child","entries","entry","mutations","mutation","FilterController","easingParser","rootObjects","now","useDirtySync","dirtySet","targets","walk","obj","el","animating","shouldReadStyle","chain","dirty","effectsKey","child","existing","raw","readFilterRaw","current","duration","delay","easing","zero","effects","warnings","state","newState","t","canTween","fromChain","warning","parseNumber","value","match","num","parseRatio","cleaned","parseAngle","stripped","parseBloom","parts","part","intensity","threshold","parseAmount","name","allowZero","amount","parseRatioAmount","re","args","size","bloom","angle","custom","String3DCustomFilterRegistry","parsed","style","properties","durations","delays","timings","index","shorthand","fallback","easingRaw","result","depth","i","ch","normalized","prop","map","tokens","token","lower","fn","from","to","effect","other","keys","otherKeys","key","uniforms","elapsed","eased","interpolated","lerp","a","b","fromValue","_String3D","context","DirtySyncManager","FilterController","value","provider","name","url","options","String3DFontRegistry","object","globalId","element","attributes","parentElement","parentId","String3DRenderer","String3DCamera","modelLoader","modelLoaderFactory","String3DScene","String3DSynchronizer","shouldUseDirtySync","key","fallback","error","engine","type","loaderType","existing","container","el","data","dirtySet","forceSync","obj","filterTargets","rootObjects","walk","rect","width","height","parentData","shouldSync","nextParentData","cached","forceChildren","child","style","css","initialValue","String3D","ThreeJSMaterialFactory","THREE","definition","initialUniforms","uniforms","material","newUniforms","element","style","collectUniformsFromCSS","initialValues","result","key","def","value","type","url","texture","baseType","BaseMaterial","injectionMap","mergeInjections","shader","injections","pars","header","uniformDeclarations","transform","output","color","normal","emissive","lines","name","uniform","props","newValues","customUniforms","uniformDef","ThreeJSEngine","THREE","loaders","ThreeJSMaterialFactory","x","y","z","w","order","min","max","options","renderer","fov","aspect","near","far","left","right","top","bottom","geometry","material","width","height","depth","radius","widthSegments","heightSegments","radiusTop","radiusBottom","segments","params","color","intensity","distance","decay","angle","penumbra","skyColor","groundColor","type","LoaderClass","defaults","url","normalized","cachedPromise","isFontFile","FontConverter","promise","fontData","font","error","loader","resolve","text","size","shapes","scale","char","glyph","charShapes","outline","offsetX","shapePath","commands","i","mx","my","lx","ly","qx","qy","bx","by","path","newPath","lastCurve","endPoint","curve","lineHeight","letterSpacing","align","bevelEnabled","bevelThickness","bevelSize","bevelOffset","bevelSegments","curveSegments","useCanvasText","fontCss","lines","line","index","fontMetrics","item","resolvedShapes","baselineOffset","offsetY","shape","finalShape","lineShapes","chars","debugAdvances","translated","advance","data","glyphs","ha","resolution","matrix","points","holes","toVec2","pt","newShape","hole","holePath","s","pixelRatio","ratio","canvas","ctx","metrics","leftBearingPx","ascentPx","glyphWidth","glyphHeight","pad","drawX","drawY","image","contours","cached","fallback","ascent","descent","result","threshold","inside","idx","edgesFrom","edgeKeys","addEdge","x1","y1","x2","y2","k1","k2","list","used","parsePoint","key","sx","sy","edgeKey","startKey","endKey","loop","currentKey","guard","nextList","nextKey","candidate","candEdge","cleaned","simplified","len","prev","curr","next","dx1","dy1","dx2","dy2","cross","epsilon","last","maxDist","start","end","d","point","dx","dy","px","py","t","clamped","projX","projY","ox","oy","solids","signedArea","pts","area","a","b","toScaled","p","contour","pointInPoly","poly","j","xi","yi","xj","yj","assigned","solid","modelUrl","loaderType","nodeName","normalizedLoader","nodeKey","cacheKey","gltf","root","mesh","found","child","config","engine","makeRng","seed","ParticleSystem","cfg","emitterReset","uniforms","dt","count","hide","i3","useSharedGeometry","setPoints","dir","gravity","drag","totalToEmit","emitCount","colorDirty","pos","speed","vel","time","jitter","flow","disperse","scatter","scatterX","scatterY","scatterZ","rotSpeed","temp","baseX","baseY","baseZ","phase","driftX","driftY","driftZ","jitterX","jitterY","jitterZ","dispersal","dirX","dirY","dirZ","dirLen","scatterScale","scatterOffsetX","scatterOffsetY","scatterOffsetZ","attr","array","itemSize","vertexCount","indexArray","triangleCount","minX","minY","minZ","maxX","maxY","maxZ","sizeX","sizeY","sizeZ","maxSize","targetSize","centerX","centerY","centerZ","cumulativeAreas","totalArea","base","ia","ib","ic","c","ax","ay","az","bz","cx","cy","cz","abx","aby","abz","acx","acy","acz","crossX","crossY","crossZ","r","lo","hi","mid","u","v","su","w1","w2","w3","vec","theta","phi","half","quality","Modifier","anyGeom","target","degrees","radians","object","boundingBox","hasBox","box","childBox","ThreeJSProvider"]}
|