string-tune-3d 0.0.6 → 0.0.8
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 +161 -136
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +257 -51
- package/dist/index.d.ts +257 -51
- package/dist/index.js +161 -136
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +161 -136
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -4
- package/readme.md +191 -107
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../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/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":["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 { frameDOM } from \"@fiddle-digital/string-tune\";\r\nimport { MeshSynchronizer } from \"../core/synchronizer/MeshSynchronizer\";\r\nimport { String3DObject } from \"../core/String3DObject\";\r\nimport type {\r\n String3DFilterChain,\r\n String3DFilterTarget,\r\n String3DFilterEffect,\r\n} from \"../core/filters/String3DFilterTypes\";\r\nimport { String3DCustomFilterRegistry } from \"../core/filters/String3DCustomFilter\";\r\nimport {\r\n TransformWorkerClient,\r\n TransformWorkerInput,\r\n TransformWorkerCamera,\r\n TransformWorkerResult,\r\n} from \"../core/transform/TransformWorkerClient\";\r\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 useTransformWorker?: boolean;\r\n transformWorkerWasmUrl?: string;\r\n}\r\n\r\ntype FilterTransitionState = {\n raw: string;\n effects: String3DFilterChain;\n animating: boolean;\n from: String3DFilterChain;\n to: String3DFilterChain;\n startTime: number;\n duration: number;\n easing: (t: number) => number;\n clearOnComplete: boolean;\n lastDuration: number;\n lastDelay: number;\n lastEasing: (t: number) => number;\n pendingRaw?: string;\n pendingEffects?: String3DFilterChain;\n effectsKey?: string;\n};\n\r\nexport class String3D extends StringModule {\r\n private static provider: I3DEngineProvider | null = null;\r\n\r\n private renderer: String3DRenderer | null = null;\r\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 dirtyElements: Set<HTMLElement> = new Set();\r\n private observedElements: Set<HTMLElement> = new Set();\r\n private resizeObserver: ResizeObserver | null = null;\r\n private mutationObserver: MutationObserver | null = null;\r\n private lastSyncData: WeakMap<String3DObject, { scale: number }> = new WeakMap();\r\n private transformWorker: TransformWorkerClient | null = null;\r\n private workerHasResult = false;\r\n private workerObjectMap: Map<string, { object: String3DObject; el: HTMLElement }> = new Map();\r\n private domVersion = 0;\r\n private lastSubmittedVersion = 0;\r\n private scrollTicking = false;\r\n private onScrollBound = () => this.handleScroll();\r\n private filterStates: WeakMap<HTMLElement, FilterTransitionState> = new WeakMap();\r\n private filterWarnings: WeakMap<HTMLElement, string> = new WeakMap();\r\n\r\n public static setProvider(provider: I3DEngineProvider): void {\r\n String3D.provider = provider;\r\n }\r\n\r\n constructor(context: StringContext) {\r\n super(context);\r\n this.htmlKey = \"3d\";\r\n this.options = this.buildOptionsFromSettings();\r\n\r\n this.attributesToMap = [\r\n ...this.attributesToMap,\r\n { key: \"3d\", type: \"string\", fallback: \"box\" },\r\n { key: \"3d-material\", type: \"string\", fallback: \"basic[#ffffff]\" },\r\n { key: \"3d-color\", type: \"string\", fallback: \"#ffffff\" },\r\n { key: \"3d-opacity\", type: \"number\", fallback: 1 },\r\n { key: \"3d-intensity\", type: \"number\", fallback: 1 },\r\n { key: \"3d-distance\", type: \"number\", fallback: 1000 },\r\n { key: \"3d-decay\", type: \"number\", fallback: 0 },\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 { key: \"3d-metalness\", type: \"number\", fallback: 0 },\r\n { key: \"3d-roughness\", type: \"number\", fallback: 1 },\r\n { key: \"3d-texture-flipY\", type: \"boolean\", fallback: true },\r\n { key: \"3d-colorSpace\", type: \"string\", fallback: \"\" },\r\n { key: \"3d-cast-shadow\", type: \"boolean\", fallback: false },\r\n { key: \"3d-receive-shadow\", type: \"boolean\", fallback: false },\r\n { key: \"3d-shadow-bias\", type: \"number\", fallback: 0 },\r\n { key: \"3d-shadow-map-size\", type: \"number\", fallback: 512 },\r\n { key: \"3d-angle\", type: \"number\", fallback: Math.PI / 3 },\r\n { key: \"3d-penumbra\", type: \"number\", fallback: 0 },\r\n { key: \"3d-ground-color\", type: \"string\", fallback: \"#ffffff\" },\r\n { key: \"3d-target\", type: \"string\", fallback: \"\" },\r\n ];\r\n }\r\n\r\n override canConnect(object: StringObject): boolean {\r\n const result = super.canConnect(object);\r\n console.log(\r\n \"[String3D] canConnect:\",\r\n object.id,\r\n \"keys:\",\r\n object.keys,\r\n \"htmlKey:\",\r\n this.htmlKey,\r\n \"result:\",\r\n result\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.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.setupObservers();\r\n this.setupScrollListeners();\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\r\n if (this.options.useTransformWorker) {\r\n this.transformWorker = new TransformWorkerClient({\r\n wasmUrl: this.options.transformWorkerWasmUrl,\r\n });\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.setupObservers();\r\n this.setupScrollListeners();\r\n this.observeSceneElements();\r\n this.markAllDirty();\r\n } else if (!shouldUseDirtySync && this.useDirtySync) {\r\n this.useDirtySync = false;\r\n this.removeScrollListeners();\r\n this.resizeObserver?.disconnect();\r\n this.mutationObserver?.disconnect();\r\n this.dirtyElements.clear();\r\n }\r\n\r\n const shouldUseWorker = !!this.options.useTransformWorker;\r\n if (shouldUseWorker && !this.transformWorker) {\r\n this.transformWorker = new TransformWorkerClient({\r\n wasmUrl: this.options.transformWorkerWasmUrl,\r\n });\r\n this.workerHasResult = false;\r\n } else if (!shouldUseWorker && this.transformWorker) {\r\n this.transformWorker.destroy();\r\n this.transformWorker = null;\r\n this.workerHasResult = false;\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 useTransformWorker: this.getSettingValue(\"useTransformWorker\", false),\r\n transformWorkerWasmUrl: this.getSettingValue(\"transformWorkerWasmUrl\", undefined),\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.observeElement(object.htmlElement);\r\n this.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 workerResults = this.transformWorker?.takeLastResult();\r\n if (\r\n workerResults &&\r\n workerResults.frameId === this.lastSubmittedVersion &&\r\n workerResults.frameId >= this.domVersion\r\n ) {\r\n this.workerHasResult = true;\r\n this.applyWorkerResults(workerResults.results);\r\n }\r\n\r\n const dirtySet = this.useDirtySync ? this.dirtyElements : null;\r\n // If dirty sync is enabled but nothing is marked dirty, we still sync everything to keep CSS-driven effects (hover/animations) fluid.\r\n const forceSync = !dirtySet || dirtySet.size === 0;\r\n const worker = this.transformWorker;\r\n\r\n // Collect and submit worker inputs only when the worker is free\r\n if (worker?.isReady() && !worker.isPending()) {\r\n const inputs: TransformWorkerInput[] = [];\r\n this.workerObjectMap.clear();\r\n this.scene!.rootObjects.forEach((obj) => {\r\n this.collectWorkerInputs(obj, { scale: 1 }, forceSync, dirtySet, inputs);\r\n });\r\n if (inputs.length > 0) {\r\n const frameId = this.domVersion;\r\n this.lastSubmittedVersion = frameId;\r\n worker.submit(inputs, this.buildWorkerCameraData(), frameId);\r\n }\r\n }\r\n\r\n // Always do immediate CPU sync to avoid frame lag while worker is pending\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.collectFilterTargets(performance.now(), forceSync, dirtySet);\r\n this.renderer!.render(this.scene!, this.camera!, filterTargets);\r\n\r\n if (this.useDirtySync) {\r\n this.dirtyElements.clear();\r\n }\r\n }\r\n\r\n private syncRecursive(\r\n el: HTMLElement | undefined,\r\n object: String3DObject,\r\n parentData: any,\r\n forceSync: boolean,\r\n dirtySet: Set<HTMLElement> | null\r\n ): void {\r\n if (!this.synchronizer || !el) return;\r\n const shouldSync = forceSync || !dirtySet || dirtySet.has(el);\r\n let nextParentData = parentData;\r\n\r\n if (shouldSync) {\r\n const data = this.synchronizer.syncElement(el, object, parentData);\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\r\n [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 transform-style: preserve-3d;\r\n }\r\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 ];\r\n\r\n props.forEach(({ name, initialValue }) => {\r\n try {\r\n css.registerProperty({\r\n name,\r\n syntax: name === \"--filter\" ? \"*\" : \"<number>\",\r\n inherits: false,\r\n initialValue,\r\n });\r\n } catch {\r\n // Property may already be registered; ignore.\r\n }\r\n });\r\n }\r\n\r\n private setupObservers(): void {\r\n if (typeof ResizeObserver !== \"undefined\") {\r\n this.resizeObserver = new ResizeObserver((entries) => {\r\n entries.forEach((entry) => {\r\n if (entry.target instanceof HTMLElement) {\r\n this.markDirty(entry.target);\r\n }\r\n });\r\n });\r\n }\r\n\r\n if (typeof MutationObserver !== \"undefined\") {\r\n this.mutationObserver = new MutationObserver((mutations) => {\r\n mutations.forEach((mutation) => {\r\n if (mutation.target instanceof HTMLElement) {\r\n this.markDirty(mutation.target);\r\n }\r\n });\r\n });\r\n }\r\n }\r\n\r\n private setupScrollListeners(): void {\r\n window.addEventListener(\"scroll\", this.onScrollBound, { passive: true });\r\n window.addEventListener(\"resize\", this.onScrollBound, { passive: true });\r\n if (window.visualViewport) {\r\n window.visualViewport.addEventListener(\"scroll\", this.onScrollBound, { passive: true });\r\n window.visualViewport.addEventListener(\"resize\", this.onScrollBound, { passive: true });\r\n }\r\n }\r\n\r\n private removeScrollListeners(): void {\r\n window.removeEventListener(\"scroll\", this.onScrollBound);\r\n window.removeEventListener(\"resize\", this.onScrollBound);\r\n if (window.visualViewport) {\r\n window.visualViewport.removeEventListener(\"scroll\", this.onScrollBound);\r\n window.visualViewport.removeEventListener(\"resize\", this.onScrollBound);\r\n }\r\n }\r\n\r\n private handleScroll(): void {\r\n if (!this.useDirtySync) return;\r\n this.markAllDirty();\r\n }\r\n\r\n private observeElement(el: HTMLElement): void {\r\n if (this.observedElements.has(el)) return;\r\n this.observedElements.add(el);\r\n\r\n this.resizeObserver?.observe(el);\r\n this.mutationObserver?.observe(el, {\r\n attributes: true,\r\n attributeFilter: [\r\n \"style\",\r\n \"class\",\r\n \"string-3d\",\r\n \"string-3d-model-fit\",\r\n \"string-3d-model-scale\",\r\n \"string-3d-cast-shadow\",\r\n \"string-3d-receive-shadow\",\r\n \"string-3d-opacity\",\r\n \"string-3d-target\",\r\n ],\r\n });\r\n }\r\n\r\n private observeSceneElements(): void {\r\n if (!this.scene) return;\r\n this.scene.rootObjects.forEach((obj) => {\r\n this.observeRecursive(obj);\r\n });\r\n }\r\n\r\n private observeRecursive(object: String3DObject): void {\r\n if (object.el instanceof HTMLElement) {\r\n this.observeElement(object.el);\r\n }\r\n object.children.forEach((child) => this.observeRecursive(child));\r\n }\r\n\r\n private markDirty(el: HTMLElement): void {\r\n this.dirtyElements.add(el);\r\n this.domVersion += 1;\r\n }\r\n\r\n private markAllDirty(): void {\r\n this.observedElements.forEach((el) => this.dirtyElements.add(el));\r\n this.domVersion += 1;\r\n }\r\n\r\n private readNumberStyle(el: HTMLElement, prop: string, fallback: number): number {\r\n const styleMap = (el as any).computedStyleMap?.();\r\n const mapValue = styleMap?.get?.(prop);\r\n if (mapValue !== undefined) {\r\n if (typeof mapValue === \"number\") return mapValue;\r\n if (typeof mapValue === \"string\") {\r\n const parsed = Number.parseFloat(mapValue);\r\n if (!Number.isNaN(parsed)) return parsed;\r\n }\r\n if (mapValue && typeof mapValue === \"object\") {\r\n const value = (mapValue as any).value;\r\n if (typeof value === \"number\") return value;\r\n if (typeof value === \"string\") {\r\n const parsed = Number.parseFloat(value);\r\n if (!Number.isNaN(parsed)) return parsed;\r\n }\r\n }\r\n }\r\n\r\n const style = getComputedStyle(el);\r\n const raw = style.getPropertyValue(prop);\r\n const parsed = Number.parseFloat(raw);\r\n return Number.isNaN(parsed) ? fallback : parsed;\r\n }\r\n\r\n private readFilterRaw(el: HTMLElement): string {\r\n const styleMap = (el as any).computedStyleMap?.();\r\n let raw = \"\";\r\n const mapValue = styleMap?.get?.(\"--filter\");\r\n if (mapValue !== undefined) {\r\n if (typeof mapValue === \"string\") {\r\n raw = mapValue;\r\n } else if (mapValue && typeof mapValue === \"object\") {\r\n const value = (mapValue as any).value;\r\n if (typeof value === \"string\") raw = value;\r\n }\r\n }\r\n if (!raw) {\r\n raw = getComputedStyle(el).getPropertyValue(\"--filter\") || \"\";\r\n }\r\n raw = raw.trim();\r\n return 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 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 readFilterChain(\n el: HTMLElement,\n now: number,\n shouldReadStyle: boolean\n ): String3DFilterChain | null {\n const existing = this.filterStates.get(el);\n if (!shouldReadStyle && existing) {\n if (existing.animating) {\n return this.sampleTransition(existing, now);\n }\n return existing.effects;\n }\n\n const raw = this.readFilterRaw(el);\n if (!raw || raw === \"none\") {\n if (existing) {\n if (existing.animating && existing.clearOnComplete) {\n const current = this.sampleTransition(existing, now);\n if (!existing.animating) {\n this.filterStates.delete(el);\n return null;\n }\n return current;\n }\n let { duration, delay, easing } = this.getFilterTransition(el);\n if (duration <= 0 && existing.lastDuration > 0) {\n duration = existing.lastDuration;\n delay = existing.lastDelay;\n easing = existing.lastEasing;\n }\n if (duration > 0) {\n const zero = this.makeZeroChain(existing.effects);\n existing.from = existing.effects;\n existing.to = zero;\n existing.startTime = now + delay;\n existing.duration = duration;\n existing.easing = easing;\n existing.animating = true;\n existing.clearOnComplete = true;\n existing.lastDuration = duration;\n existing.lastDelay = delay;\n existing.lastEasing = easing;\n return this.sampleTransition(existing, now);\n }\n }\n this.filterStates.delete(el);\n return null;\n }\n\r\n const { effects, warnings } = this.parseFilterChain(raw);\n this.warnFilterIssues(el, raw, warnings);\n if (effects.length === 0) return null;\n\r\n const state = this.filterStates.get(el);\r\n if (!state) {\n const { duration, delay, easing } = this.getFilterTransition(el);\n if (duration > 0) {\n const zero = this.makeZeroChain(effects);\n const newState: FilterTransitionState = {\n raw,\n effects,\n animating: true,\n from: zero,\n to: effects,\n startTime: now + delay,\n duration,\n easing,\n clearOnComplete: false,\n lastDuration: duration,\n lastDelay: delay,\n lastEasing: easing,\n };\n newState.effectsKey = this.stringifyFilterChain(effects);\n this.filterStates.set(el, newState);\n return this.sampleTransition(newState, now);\n }\n this.filterStates.set(el, {\n raw,\n effects,\n animating: false,\n from: effects,\n to: effects,\n startTime: 0,\n duration: 0,\n easing: (t) => t,\n clearOnComplete: false,\n lastDuration: 0,\n lastDelay: 0,\n lastEasing: (t) => t,\n effectsKey: this.stringifyFilterChain(effects),\n });\n return effects;\n }\n\r\n if (state.raw === raw) {\n if (state.animating) {\n const current = this.sampleTransition(state, now);\n if (!state.animating && state.clearOnComplete) {\n this.filterStates.delete(el);\n return null;\n }\n return current;\n }\n return state.effects;\n }\n\n state.pendingEffects = undefined;\n state.pendingRaw = undefined;\n\n let { duration, delay, easing } = this.getFilterTransition(el);\n if (duration <= 0 && state.lastDuration > 0) {\n duration = state.lastDuration;\n delay = state.lastDelay;\n easing = state.lastEasing;\n }\n if (duration > 0) {\n const canTween = this.canInterpolate(state.effects, effects);\n const current = state.animating ? this.getCurrentChain(state, now) : state.effects;\n if (!canTween && this.isZeroChain(effects)) {\n state.pendingRaw = raw;\n state.pendingEffects = effects;\n state.raw = raw;\n state.effects = current;\n state.from = current;\n state.to = this.makeZeroChain(current);\n state.startTime = now + delay;\n state.duration = duration;\n state.easing = easing;\n state.animating = true;\n state.clearOnComplete = false;\n state.lastDuration = duration;\n state.lastDelay = delay;\n state.lastEasing = easing;\n state.effectsKey = this.stringifyFilterChain(effects);\n return this.sampleTransition(state, now);\n }\n\n const fromChain = canTween ? current : this.makeZeroChain(effects);\n state.raw = raw;\n state.effects = effects;\n state.from = fromChain;\n state.to = effects;\n state.startTime = now + delay;\n state.duration = duration;\n state.easing = easing;\n state.animating = true;\n state.clearOnComplete = false;\n state.lastDuration = duration;\n state.lastDelay = delay;\n state.lastEasing = easing;\n state.effectsKey = this.stringifyFilterChain(effects);\n return this.sampleTransition(state, now);\n }\n\n state.raw = raw;\n state.effects = effects;\n state.animating = false;\n state.clearOnComplete = false;\n state.effectsKey = this.stringifyFilterChain(effects);\n return effects;\n }\n\r\n private collectFilterTargets(\n now: number,\n forceSync: boolean,\n dirtySet: Set<HTMLElement> | null\n ): String3DFilterTarget[] {\n if (!this.scene) return [];\n const targets: String3DFilterTarget[] = [];\n const walk = (obj: String3DObject): void => {\n const el = obj.el as HTMLElement | undefined;\n if (el) {\n const shouldReadStyle =\n !this.useDirtySync ||\n !dirtySet ||\n dirtySet.has(el) ||\n this.filterStates.get(el)?.animating === true;\n const chain = this.readFilterChain(el, now, shouldReadStyle);\n if (chain && chain.length > 0) {\n const dirty =\n !this.useDirtySync ||\n !dirtySet ||\n dirtySet.has(el) ||\n this.filterStates.get(el)?.animating === true;\n const effectsKey =\n this.filterStates.get(el)?.effectsKey || this.stringifyFilterChain(chain);\n targets.push({\n object: obj,\n effects: chain,\n effectsKey,\n dirty,\n });\n return;\n }\n }\n obj.children.forEach((child) => walk(child));\r\n };\r\n this.scene.rootObjects.forEach((obj) => walk(obj));\r\n return targets;\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[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 getFilterTransition(el: HTMLElement): {\n duration: number;\n delay: number;\n easing: (t: number) => number;\n } {\n const style = getComputedStyle(el);\n const properties = this.splitTransitionList(style.transitionProperty);\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\");\n if (index === -1) {\n const shorthand = this.parseTransitionShorthand(style.transition);\n const fallback = shorthand.get(\"--filter\") || shorthand.get(\"all\");\n if (fallback) {\n return fallback;\n }\n return { duration: 0, delay: 0, easing: (t) => t };\n }\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\";\n return { duration, delay, easing: this.parseEasing(easingRaw) };\n }\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 {\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;\n }\n\n private parseTransitionShorthand(\n value: string\n ): Map<string, { duration: number; delay: number; easing: (t: number) => number }> {\n const map = new Map<\n string,\n { duration: number; delay: number; easing: (t: number) => number }\n >();\n const parts = this.splitTransitionList(value);\n parts.forEach((part) => {\n if (!part) return;\n const tokens = part.trim().split(/\\s+(?![^()]*\\))/g);\n let prop = \"\";\n let duration = \"\";\n let delay = \"\";\n let easing = \"\";\n tokens.forEach((token) => {\n const lower = token.toLowerCase();\n if (\n lower.endsWith(\"ms\") ||\n lower.endsWith(\"s\") ||\n /^[0-9.]+$/.test(lower)\n ) {\n if (!duration) duration = lower;\n else if (!delay) delay = lower;\n } else if (\n lower.startsWith(\"cubic-bezier\") ||\n lower.startsWith(\"steps\") ||\n lower === \"linear\" ||\n lower === \"ease\" ||\n lower === \"ease-in\" ||\n lower === \"ease-out\" ||\n lower === \"ease-in-out\"\n ) {\n easing = token;\n } else if (!prop) {\n prop = token;\n }\n });\n if (!prop) return;\n map.set(prop.trim().toLowerCase(), {\n duration: this.parseTime(duration || \"0s\"),\n delay: this.parseTime(delay || \"0s\"),\n easing: this.parseEasing(easing || \"linear\"),\n });\n });\n return map;\n }\n\r\n private parseEasing(value: string): (t: number) => number {\r\n const raw = value.trim().toLowerCase();\r\n if (raw === \"linear\") return (t) => t;\r\n if (raw === \"ease\") return this.cubicBezier(0.25, 0.1, 0.25, 1);\r\n if (raw === \"ease-in\") return this.cubicBezier(0.42, 0, 1, 1);\r\n if (raw === \"ease-out\") return this.cubicBezier(0, 0, 0.58, 1);\r\n if (raw === \"ease-in-out\") return this.cubicBezier(0.42, 0, 0.58, 1);\r\n if (raw.startsWith(\"cubic-bezier\")) {\r\n const match = raw.match(/cubic-bezier\\(([^)]+)\\)/);\r\n if (match) {\r\n const parts = match[1].split(\",\").map((p) => Number.parseFloat(p.trim()));\r\n if (parts.length === 4 && parts.every((n) => Number.isFinite(n))) {\r\n return this.cubicBezier(parts[0], parts[1], parts[2], parts[3]);\r\n }\r\n }\r\n }\r\n return (t) => t;\r\n }\r\n\r\n private cubicBezier(p1x: number, p1y: number, p2x: number, p2y: number): (t: number) => number {\r\n const sampleCurveX = (t: number) => {\r\n const inv = 1 - t;\r\n return 3 * inv * inv * t * p1x + 3 * inv * t * t * p2x + t * t * t;\r\n };\r\n const sampleCurveY = (t: number) => {\r\n const inv = 1 - t;\r\n return 3 * inv * inv * t * p1y + 3 * inv * t * t * p2y + t * t * t;\r\n };\r\n const solveCurveX = (x: number) => {\r\n let t = x;\r\n for (let i = 0; i < 5; i += 1) {\r\n const x2 = sampleCurveX(t) - x;\r\n const d2 =\r\n 3 * (1 - t) * (1 - t) * p1x + 6 * (1 - t) * t * (p2x - p1x) + 3 * t * t * (1 - p2x);\r\n if (Math.abs(x2) < 1e-5 || d2 === 0) break;\r\n t -= x2 / d2;\r\n }\r\n return t;\r\n };\r\n return (t: number) => {\r\n const x = Math.min(1, Math.max(0, t));\r\n const solved = solveCurveX(x);\r\n return Math.min(1, Math.max(0, sampleCurveY(solved)));\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((key) => key in other.uniforms && this.isNumeric(effect.uniforms[key]));\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 {\n if (!state.animating) return state.effects;\n if (now < state.startTime) {\n return state.from;\n }\n const elapsed = now - state.startTime;\n const duration = Math.max(1, state.duration);\n const t = Math.min(1, Math.max(0, elapsed / duration));\n const eased = state.easing(t);\n const interpolated = this.interpolateChain(state.from, state.to, eased);\n if (t >= 1) {\n state.animating = false;\n state.from = state.to;\n if (state.pendingEffects && state.pendingRaw === state.raw) {\n state.effects = state.pendingEffects;\n state.raw = state.pendingRaw || state.raw;\n state.pendingEffects = undefined;\n state.pendingRaw = undefined;\n } else if (state.pendingEffects) {\n state.pendingEffects = undefined;\n state.pendingRaw = undefined;\n }\n }\n return interpolated;\n }\n\n private getCurrentChain(state: FilterTransitionState, now: number): String3DFilterChain {\n if (!state.animating) return state.effects;\n if (now < state.startTime) return state.from;\n const elapsed = now - state.startTime;\n const duration = Math.max(1, state.duration);\n const t = Math.min(1, Math.max(0, elapsed / duration));\n const eased = state.easing(t);\n return this.interpolateChain(state.from, state.to, eased);\n }\n\r\n private interpolateChain(\n from: String3DFilterChain,\n to: String3DFilterChain,\n t: number\n ): String3DFilterChain {\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(\n from: String3DFilterEffect,\n to: String3DFilterEffect,\n t: number\n ): String3DFilterEffect {\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;\n }\n\n private isNumeric(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value);\n }\n\n private isZeroChain(chain: String3DFilterChain): boolean {\n return chain.every((effect) => {\n switch (effect.type) {\n case \"blur\":\n return effect.amount <= 0;\n case \"pixel\":\n return effect.size <= 0;\n case \"bloom\":\n return effect.intensity <= 0;\n case \"brightness\":\n return effect.amount === 1;\n case \"contrast\":\n return effect.amount === 1;\n case \"saturate\":\n return effect.amount === 1;\n case \"grayscale\":\n return effect.amount === 0;\n case \"sepia\":\n return effect.amount === 0;\n case \"invert\":\n return effect.amount === 0;\n case \"hue-rotate\":\n return effect.angle === 0;\n case \"custom\":\n return false;\n default:\n return false;\n }\n });\n }\n\r\n private buildWorkerCameraData(): TransformWorkerCamera {\r\n return {\r\n mode: this.camera!.getMode(),\r\n width: this.renderer!.width,\r\n height: this.renderer!.height,\r\n cameraZ: this.camera!.getPositionZ(),\r\n fov: this.camera!.getPerspectiveFov(),\r\n aspect: this.renderer!.width / this.renderer!.height,\r\n };\r\n }\r\n\r\n private collectWorkerInputs(\r\n object: String3DObject,\r\n parentData: { scale: number },\r\n forceSync: boolean,\r\n dirtySet: Set<HTMLElement> | null,\r\n inputs: TransformWorkerInput[]\r\n ): void {\r\n if (!this.synchronizer || !object.el) return;\r\n const el = object.el as HTMLElement;\r\n const shouldSync = forceSync || !dirtySet || dirtySet.has(el);\r\n let nextParentData = parentData;\r\n\r\n if (object.type.endsWith(\"Light\")) {\r\n if (shouldSync) {\r\n this.synchronizer.syncElement(el, object, parentData);\r\n }\r\n return;\r\n }\r\n\r\n if (shouldSync) {\r\n const rect = el.getBoundingClientRect();\r\n const layoutWidth = el.offsetWidth || rect.width;\r\n const layoutHeight = el.offsetHeight || rect.height;\r\n const translateZ = this.readNumberStyle(el, \"--translate-z\", 0);\r\n const scale = this.readNumberStyle(el, \"--scale\", 1);\r\n const scaleZ = this.readNumberStyle(el, \"--scale-z\", 1);\r\n const rotateX = this.readNumberStyle(el, \"--rotate-x\", 0);\r\n const rotateY = this.readNumberStyle(el, \"--rotate-y\", 0);\r\n const rotateZ = this.readNumberStyle(el, \"--rotate-z\", 0);\r\n const opacity = this.readNumberStyle(el, \"--opacity\", NaN);\r\n\r\n if (object.type !== \"group\") {\r\n MeshSynchronizer.applyVisualProps(el, object, opacity);\r\n }\r\n\r\n let modelSizeX: number | undefined;\r\n let modelSizeY: number | undefined;\r\n let modelScale: number | undefined;\r\n let fitMode: string | undefined;\r\n\r\n if (object.type === \"model\") {\r\n const bbox = object.getOriginalBoundingBox();\r\n const size = bbox.getSize(this.engine!.createVector3());\r\n modelSizeX = size.x;\r\n modelSizeY = size.y;\r\n const modelScaleAttr = parseFloat(el.getAttribute(\"string-3d-model-scale\") || \"1\");\r\n modelScale = Number.isFinite(modelScaleAttr) ? modelScaleAttr : 1;\r\n fitMode = (el.getAttribute(\"string-3d-model-fit\") || \"contain\").toLowerCase().trim();\r\n }\r\n\r\n const returnScale = object.type === \"group\" ? scale : scale * parentData.scale;\r\n this.lastSyncData.set(object, { scale: returnScale });\r\n nextParentData = { scale: returnScale };\r\n\r\n this.workerObjectMap.set(object.id, { object, el });\r\n inputs.push({\r\n id: object.id,\r\n type: object.type,\r\n rectLeft: rect.left,\r\n rectTop: rect.top,\r\n rectWidth: layoutWidth,\r\n rectHeight: layoutHeight,\r\n translateZ,\r\n scale,\r\n scaleZ,\r\n rotateX,\r\n rotateY,\r\n rotateZ,\r\n parentScale: parentData.scale,\r\n modelSizeX,\r\n modelSizeY,\r\n modelScale,\r\n fitMode,\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.collectWorkerInputs(child, nextParentData, forceChildren, dirtySet, inputs);\r\n });\r\n }\r\n\r\n private applyWorkerResults(results: TransformWorkerResult[]): void {\r\n if (!this.engine) return;\r\n results.forEach((result) => {\r\n const entry = this.workerObjectMap.get(result.id);\r\n if (!entry) return;\r\n const object = entry.object;\r\n object.position = this.engine!.createVector3(result.posX, result.posY, result.posZ);\r\n object.rotation = this.engine!.createEuler(result.rotX, result.rotY, result.rotZ, \"XYZ\");\r\n object.scale = this.engine!.createVector3(result.scaleX, result.scaleY, result.scaleZ);\r\n if (object.type === \"group\") {\r\n object.object.updateMatrixWorld(true);\r\n }\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.transformWorker?.destroy();\r\n this.transformWorker = null;\r\n this.removeScrollListeners();\r\n this.resizeObserver?.disconnect();\r\n this.mutationObserver?.disconnect();\r\n this.observedElements.clear();\r\n this.dirtyElements.clear();\r\n this.workerObjectMap.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 = \"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","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 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(target.object.el as HTMLElement | undefined, target.effects);\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 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","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 getAllObjects(): String3DObject[] {\n const result: String3DObject[] = [];\n const walk = (obj: String3DObject): void => {\n result.push(obj);\n obj.children.forEach((child) => walk(child));\n };\n this._rootObjects.forEach((obj) => walk(obj));\n return result;\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,\n I3DRenderTarget,\n I3DLight,\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 {\n return new this.THREE.MeshStandardMaterial(params);\n }\n\n createShaderMaterial(params?: any): I3DMaterial {\n return new this.THREE.ShaderMaterial(params);\n }\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 {\n const LoaderClass = this.loaders[type];\n if (!LoaderClass) {\n throw new Error(`[ThreeJSEngine] Model loader \"${type}\" not registered`);\n }\n return new LoaderClass();\n }\n\n createRenderTarget(width: number, height: number, options: any = {}): I3DRenderTarget {\n const defaults = {\n minFilter: this.THREE.LinearFilter,\n magFilter: this.THREE.LinearFilter,\n format: this.THREE.RGBAFormat,\n depthBuffer: true,\n stencilBuffer: false,\n };\n return new this.THREE.WebGLRenderTarget(width, height, { ...defaults, ...options });\n }\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":["StringModule","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","scene","camera","filterTargets","pipeline","allObjects","visibility","obj","anyObj","filteredSet","target","rendererAny","prevAutoClear","originalVisible","lights","supportsLayers","cache","effects","allowed","restoreLayers","restoreCameraMask","subtree","input","output","entry","existing","String3DFilterPipeline","object","set","child","visible","el","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","String3DScene","engine","options","id","result","walk","obj","child","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","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","StringModule","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","filterTargets","parentData","shouldSync","nextParentData","cached","forceChildren","child","style","css","name","initialValue","entries","entry","mutations","mutation","prop","mapValue","parsed","value","raw","styleMap","warnings","effects","parseNumber","match","num","parseRatio","cleaned","parseAngle","stripped","parseBloom","parts","part","intensity","threshold","parseAmount","allowZero","amount","parseRatioAmount","re","args","size","bloom","angle","custom","String3DCustomFilterRegistry","warning","now","shouldReadStyle","current","duration","delay","easing","zero","state","newState","t","canTween","fromChain","targets","walk","chain","dirty","effectsKey","effect","uniforms","properties","durations","delays","timings","index","shorthand","easingRaw","depth","i","ch","normalized","map","tokens","token","lower","p","n","p1x","p1y","p2x","p2y","sampleCurveX","inv","sampleCurveY","solveCurveX","x","x2","d2","solved","from","to","other","keys","otherKeys","elapsed","eased","interpolated","lerp","b","fromValue","rect","layoutWidth","layoutHeight","translateZ","scale","scaleZ","rotateX","rotateY","rotateZ","opacity","MeshSynchronizer","modelSizeX","modelSizeY","modelScale","fitMode","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","defaults","degrees","radians","object","boundingBox","hasBox","child","box","childBox","ThreeJSProvider"]}
|
|
1
|
+
{"version":3,"sources":["../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":["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\";\r\nimport { FilterController } from \"./string3d/FilterController\";\r\nimport { StyleReader } from \"./string3d/styleUtils\";\r\nimport { String3DFontRegistry } from \"../core/text\";\r\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 {\r\n private static provider: I3DEngineProvider | null = null;\r\n\r\n private renderer: String3DRenderer | null = null;\r\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 {\r\n String3D.provider = provider;\r\n }\r\n\r\n public static registerFont(name: string, url: string, options: { default?: boolean } = {}): void {\r\n String3DFontRegistry.register(name, url);\r\n if (options.default) {\r\n String3DFontRegistry.setDefault(name);\r\n }\r\n }\r\n\r\n public static setDefaultFont(name: string): void {\r\n String3DFontRegistry.setDefault(name);\r\n }\r\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 return super.canConnect(object);\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 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 }\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(\r\n el: HTMLElement | undefined,\r\n object: String3DObject,\r\n parentData: any,\r\n forceSync: boolean,\r\n dirtySet: Set<HTMLElement> | null\r\n ): void {\r\n if (!this.synchronizer || !el) return;\r\n const shouldSync =\r\n object.type === \"particles\" ||\r\n object.type === \"text\" ||\r\n forceSync ||\r\n !dirtySet ||\r\n dirtySet.has(el);\r\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; }\r\n @property --texture-flip-y { syntax: \"<number>\"; inherits: false; initial-value: 1; }\r\n @property --texture-color-space { syntax: \"*\"; inherits: false; initial-value: none; }\r\n @property --particles-mode { syntax: \"*\"; inherits: false; initial-value: emitter; }\r\n @property --particles-count { syntax: \"<number>\"; inherits: false; initial-value: 300; }\r\n @property --particles-size { syntax: \"<number>\"; inherits: false; initial-value: 2; }\r\n @property --particles-color { syntax: \"<color>\"; inherits: false; initial-value: #ffffff; }\r\n @property --particles-opacity { syntax: \"<number>\"; inherits: false; initial-value: 1; }\r\n @property --particles-spread { syntax: \"<number>\"; inherits: false; initial-value: 120; }\r\n @property --particles-seed { syntax: \"<number>\"; inherits: false; initial-value: 1; }\r\n @property --particles-shape { syntax: \"*\"; inherits: false; initial-value: sphere; }\r\n @property --particles-fit { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --particles-model { syntax: \"*\"; inherits: false; initial-value: none; }\r\n @property --particles-model-loader { syntax: \"*\"; inherits: false; initial-value: none; }\r\n @property --particles-model-node { syntax: \"*\"; inherits: false; initial-value: none; }\r\n @property --instance-model { syntax: \"*\"; inherits: false; initial-value: none; }\r\n @property --instance-model-loader { syntax: \"*\"; inherits: false; initial-value: none; }\r\n @property --instance-model-node { syntax: \"*\"; inherits: false; initial-value: none; }\r\n @property --emit-rate { syntax: \"<number>\"; inherits: false; initial-value: 30; }\r\n @property --emit-burst { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --particle-life { syntax: \"<number>\"; inherits: false; initial-value: 2.5; }\r\n @property --particle-speed { syntax: \"<number>\"; inherits: false; initial-value: 40; }\r\n @property --particle-direction { syntax: \"*\"; inherits: false; initial-value: 0 1 0; }\r\n @property --particle-gravity { syntax: \"*\"; inherits: false; initial-value: 0 -30 0; }\r\n @property --particle-drag { syntax: \"<number>\"; inherits: false; initial-value: 0.1; }\r\n @property --particle-size-variation { syntax: \"<number>\"; inherits: false; initial-value: 0.6; }\r\n @property --particle-color-variation { syntax: \"<number>\"; inherits: false; initial-value: 0.2; }\r\n @property --instance-shape { syntax: \"*\"; inherits: false; initial-value: sphere; }\r\n @property --instance-scale { syntax: \"<number>\"; inherits: false; initial-value: 1; }\r\n @property --instance-scale-variation { syntax: \"<number>\"; inherits: false; initial-value: 0.5; }\r\n @property --instance-rotation-speed { syntax: \"<number>\"; inherits: false; initial-value: 0.4; }\r\n @property --instance-jitter { syntax: \"<number>\"; inherits: false; initial-value: 0.2; }\r\n @property --instance-flow { syntax: \"<number>\"; inherits: false; initial-value: 0.3; }\r\n @property --instance-disperse { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --instance-scatter { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --instance-scatter-x { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --instance-scatter-y { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --instance-scatter-z { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --text-depth { syntax: \"<number>\"; inherits: false; initial-value: 8; }\r\n @property --text-curve-segments { syntax: \"<number>\"; inherits: false; initial-value: 8; }\r\n @property --text-bevel-size { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --text-bevel-thickness { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --text-bevel-offset { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --text-bevel-steps { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --text-fit { syntax: \"*\"; inherits: false; initial-value: contain; }\r\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;\r\n --texture-flip-y: 1; --texture-color-space: none;\r\n --particles-mode: emitter; --particles-count: 300; --particles-size: 2; --particles-color: #ffffff;\r\n --particles-opacity: 1; --particles-spread: 120; --particles-seed: 1; --particles-shape: sphere;\r\n --particles-fit: 0;\r\n --particles-model: none; --particles-model-loader: none; --particles-model-node: none;\r\n --instance-model: none; --instance-model-loader: none; --instance-model-node: none;\r\n --emit-rate: 30; --emit-burst: 0; --particle-life: 2.5; --particle-speed: 40;\r\n --particle-direction: 0 1 0; --particle-gravity: 0 -30 0; --particle-drag: 0.1;\r\n --particle-size-variation: 0.6; --particle-color-variation: 0.2;\r\n --instance-shape: sphere; --instance-scale: 1; --instance-scale-variation: 0.5;\r\n --instance-rotation-speed: 0.4; --instance-jitter: 0.2; --instance-flow: 0.3;\r\n --instance-disperse: 0;\r\n --instance-scatter: 0;\r\n --instance-scatter-x: 0; --instance-scatter-y: 0; --instance-scatter-z: 0;\r\n --text-depth: 8; --text-curve-segments: 8; --text-bevel-size: 0; --text-bevel-thickness: 0;\r\n --text-bevel-offset: 0; --text-bevel-steps: 0; --text-fit: contain;\r\n transform-style: preserve-3d;\r\n }\r\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\" },\r\n { name: \"--texture-color-space\", initialValue: \"none\" },\r\n { name: \"--particles-mode\", initialValue: \"emitter\" },\r\n { name: \"--particles-count\", initialValue: \"300\" },\r\n { name: \"--particles-size\", initialValue: \"2\" },\r\n { name: \"--particles-color\", initialValue: \"#ffffff\" },\r\n { name: \"--particles-opacity\", initialValue: \"1\" },\r\n { name: \"--particles-spread\", initialValue: \"120\" },\r\n { name: \"--particles-seed\", initialValue: \"1\" },\r\n { name: \"--particles-shape\", initialValue: \"sphere\" },\r\n { name: \"--particles-fit\", initialValue: \"0\" },\r\n { name: \"--particles-model\", initialValue: \"none\" },\r\n { name: \"--particles-model-loader\", initialValue: \"none\" },\r\n { name: \"--particles-model-node\", initialValue: \"none\" },\r\n { name: \"--instance-model\", initialValue: \"none\" },\r\n { name: \"--instance-model-loader\", initialValue: \"none\" },\r\n { name: \"--instance-model-node\", initialValue: \"none\" },\r\n { name: \"--emit-rate\", initialValue: \"30\" },\r\n { name: \"--emit-burst\", initialValue: \"0\" },\r\n { name: \"--particle-life\", initialValue: \"2.5\" },\r\n { name: \"--particle-speed\", initialValue: \"40\" },\r\n { name: \"--particle-direction\", initialValue: \"0 1 0\" },\r\n { name: \"--particle-gravity\", initialValue: \"0 -30 0\" },\r\n { name: \"--particle-drag\", initialValue: \"0.1\" },\r\n { name: \"--particle-size-variation\", initialValue: \"0.6\" },\r\n { name: \"--particle-color-variation\", initialValue: \"0.2\" },\r\n { name: \"--instance-shape\", initialValue: \"sphere\" },\r\n { name: \"--instance-scale\", initialValue: \"1\" },\r\n { name: \"--instance-scale-variation\", initialValue: \"0.5\" },\r\n { name: \"--instance-rotation-speed\", initialValue: \"0.4\" },\r\n { name: \"--instance-jitter\", initialValue: \"0.2\" },\r\n { name: \"--instance-flow\", initialValue: \"0.3\" },\r\n { name: \"--instance-disperse\", initialValue: \"0\" },\r\n { name: \"--instance-scatter\", initialValue: \"0\" },\r\n { name: \"--instance-scatter-x\", initialValue: \"0\" },\r\n { name: \"--instance-scatter-y\", initialValue: \"0\" },\r\n { name: \"--instance-scatter-z\", initialValue: \"0\" },\r\n { name: \"--text-depth\", initialValue: \"8\" },\r\n { name: \"--text-curve-segments\", initialValue: \"8\" },\r\n { name: \"--text-bevel-size\", initialValue: \"0\" },\r\n { name: \"--text-bevel-thickness\", initialValue: \"0\" },\r\n { name: \"--text-bevel-offset\", initialValue: \"0\" },\r\n { name: \"--text-bevel-steps\", initialValue: \"0\" },\r\n { name: \"--text-fit\", initialValue: \"contain\" },\r\n ];\r\n\r\n props.forEach(({ name, initialValue }) => {\r\n try {\r\n css.registerProperty({\r\n name,\r\n syntax:\r\n name === \"--filter\" ||\r\n name === \"--light-target\" ||\r\n name.startsWith(\"--texture-\") ||\r\n name === \"--material-type\" ||\r\n name === \"--particles-mode\" ||\r\n name === \"--particles-shape\" ||\r\n name === \"--particles-model\" ||\r\n name === \"--particles-model-loader\" ||\r\n name === \"--particles-model-node\" ||\r\n name === \"--instance-model\" ||\r\n name === \"--instance-model-loader\" ||\r\n name === \"--instance-model-node\" ||\r\n name === \"--particle-direction\" ||\r\n name === \"--particle-gravity\" ||\r\n name === \"--instance-shape\" ||\r\n name === \"--text-fit\"\r\n ? \"*\"\r\n : name.includes(\"color\") || name.includes(\"emissive\")\r\n ? \"<color>\"\r\n : \"<number>\",\r\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 {\r\n private styleMap: any;\r\n private style: CSSStyleDeclaration;\r\n\r\n constructor(el: HTMLElement) {\r\n this.styleMap = (el as any).computedStyleMap?.();\r\n this.style = getComputedStyle(el);\r\n }\r\n\r\n readNumber(prop: string, fallback: number): number {\r\n const mapValue = this.styleMap?.get?.(prop);\r\n if (mapValue !== undefined && mapValue !== null) {\r\n const val = typeof mapValue === \"object\" ? (mapValue as any).value : mapValue;\r\n const num = typeof val === \"number\" ? val : Number.parseFloat(val);\r\n if (!Number.isNaN(num)) return num;\r\n }\r\n const num = Number.parseFloat(this.style.getPropertyValue(prop));\r\n return Number.isNaN(num) ? fallback : num;\r\n }\r\n\r\n readString(prop: string, fallback = \"\"): string {\r\n const mapValue = this.styleMap?.get?.(prop);\r\n const val = mapValue && typeof mapValue === \"object\" ? (mapValue as any).value : mapValue;\r\n if (typeof val === \"string\") return this.stripQuotes(val.trim()) || fallback;\r\n const raw = this.style.getPropertyValue(prop).trim();\r\n return this.stripQuotes(raw) || fallback;\r\n }\r\n\r\n private stripQuotes(value: string): string {\r\n if (\r\n (value.startsWith(\"'\") && value.endsWith(\"'\")) ||\r\n (value.startsWith('\"') && value.endsWith('\"'))\r\n ) {\r\n return value.slice(1, -1);\r\n }\r\n return value;\r\n }\r\n\r\n readBoolean(prop: string, fallback = false): boolean {\r\n const raw = this.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\r\nexport function readNumberStyle(el: HTMLElement, prop: string, fallback: number): number {\r\n const styleMap = (el as any).computedStyleMap?.();\r\n const mapValue = styleMap?.get?.(prop);\r\n if (mapValue !== undefined) {\r\n if (typeof mapValue === \"number\") return mapValue;\r\n if (typeof mapValue === \"string\") {\r\n const parsed = Number.parseFloat(mapValue);\r\n if (!Number.isNaN(parsed)) return parsed;\r\n }\r\n if (mapValue && typeof mapValue === \"object\") {\r\n const value = (mapValue as any).value;\r\n if (typeof value === \"number\") return value;\r\n if (typeof value === \"string\") {\r\n const parsed = Number.parseFloat(value);\r\n if (!Number.isNaN(parsed)) return parsed;\r\n }\r\n }\r\n }\r\n\r\n const style = getComputedStyle(el);\r\n const raw = style.getPropertyValue(prop);\r\n const parsed = Number.parseFloat(raw);\r\n return Number.isNaN(parsed) ? fallback : parsed;\r\n}\r\n\r\nfunction stripQuotes(value: string): string {\r\n if (\r\n (value.startsWith(\"'\") && value.endsWith(\"'\")) ||\r\n (value.startsWith('\"') && value.endsWith('\"'))\r\n ) {\r\n return value.slice(1, -1);\r\n }\r\n return value;\r\n}\r\n\r\nexport function readStringStyle(el: HTMLElement, prop: string, fallback = \"\"): string {\r\n const styleMap = (el as any).computedStyleMap?.();\r\n const mapValue = styleMap?.get?.(prop);\r\n if (typeof mapValue === \"string\") {\r\n return stripQuotes(mapValue.trim());\r\n }\r\n if (mapValue && typeof mapValue === \"object\") {\r\n const value = (mapValue as any).value;\r\n if (typeof value === \"string\") {\r\n return stripQuotes(value.trim());\r\n }\r\n }\r\n const style = getComputedStyle(el).getPropertyValue(prop);\r\n const result = style ? stripQuotes(style.trim()) : \"\";\r\n return result || fallback;\r\n}\r\n\r\nexport function readBooleanStyle(el: HTMLElement, prop: string, fallback = false): boolean {\r\n const raw = readStringStyle(el, prop, \"\");\r\n if (!raw) return fallback;\r\n const normalized = raw.toLowerCase().trim();\r\n if (normalized === \"true\" || normalized === \"1\" || normalized === \"yes\") return true;\r\n if (normalized === \"false\" || normalized === \"0\" || normalized === \"no\") return false;\r\n return fallback;\r\n}\r\n\r\nexport function readFilterRaw(el: HTMLElement): string {\r\n const styleMap = (el as any).computedStyleMap?.();\r\n let raw = \"\";\r\n const mapValue = styleMap?.get?.(\"--filter\");\r\n if (mapValue !== undefined) {\r\n if (typeof mapValue === \"string\") {\r\n raw = mapValue;\r\n } else if (mapValue && typeof mapValue === \"object\") {\r\n const value = (mapValue as any).value;\r\n if (typeof value === \"string\") raw = value;\r\n }\r\n }\r\n if (!raw) {\r\n raw = getComputedStyle(el).getPropertyValue(\"--filter\") || \"\";\r\n }\r\n raw = raw.trim();\r\n return raw;\r\n}\r\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 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 }\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 {\r\n const obj = this._objects.get(id);\r\n if (obj) {\r\n this._scene.remove(obj.object);\r\n this._objects.delete(id);\r\n this._elementMap.delete(id);\r\n this._rootObjects = this._rootObjects.filter((root) => root !== obj);\r\n obj.destroy();\r\n return true;\r\n }\r\n return false;\r\n }\r\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\":\r\n this.createCylinder(object, onAdd);\r\n break;\r\n case \"particles\":\r\n this.createParticles(object, onAdd);\r\n break;\r\n case \"text\":\r\n this.createText(object, onAdd);\r\n break;\r\n }\r\n }\r\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 {\r\n const quality = this.getGeometryQuality(object.htmlElement);\r\n const widthSegments = Math.max(3, Math.round(32 * quality));\r\n const heightSegments = Math.max(2, Math.round(32 * quality));\r\n const geometry = this.engine.createSphereGeometry(0.5, widthSegments, heightSegments);\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, \"sphere\", 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 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(\r\n object: StringObject,\r\n onAdd: (obj: String3DObject) => void\r\n ): String3DObject {\r\n const quality = this.getGeometryQuality(object.htmlElement);\r\n const segments = Math.max(3, Math.round(32 * quality));\r\n const geometry = this.engine.createCylinderGeometry(0.5, 0.5, 1, segments);\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, \"cylinder\", 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 createModel(object: StringObject, onAdd: (obj: String3DObject) => void): void {\r\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 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 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 undefined,\r\n undefined\r\n );\r\n }\r\n\r\n private createParticles(object: StringObject, onAdd: (obj: String3DObject) => void): void {\r\n if (!this.engine.createParticleSystem) {\r\n return;\r\n }\r\n\r\n const element = object.htmlElement;\r\n const config: import(\"./abstractions/I3DEngine\").ParticleSystemConfig = {\r\n mode: \"emitter\",\r\n count: 300,\r\n size: 2,\r\n color: \"#ffffff\",\r\n opacity: 1,\r\n spread: 120,\r\n spreadX: 0,\r\n spreadY: 0,\r\n seed: 1,\r\n emitRate: 30,\r\n emitBurst: 0,\r\n particleLife: 2.5,\r\n particleSpeed: 40,\r\n particleDirection: [0, 1, 0] as [number, number, number],\r\n particleGravity: [0, -30, 0] as [number, number, number],\r\n particleDrag: 0.1,\r\n particleSizeVariation: 0.6,\r\n particleColorVariation: 0.2,\r\n particleShape: \"sphere\",\r\n particleModelUrl: \"\",\r\n particleModelLoader: \"\",\r\n particleModelNode: \"\",\r\n instanceShape: \"sphere\",\r\n instanceModelUrl: \"\",\r\n instanceModelLoader: \"\",\r\n instanceModelNode: \"\",\r\n instanceScale: 1,\r\n instanceScaleVariation: 0.5,\r\n instanceRotationSpeed: 0.4,\r\n instanceJitter: 0.2,\r\n instanceFlow: 0.3,\r\n instanceDisperse: 0,\r\n instanceDisperseScatter: 0,\r\n instanceDisperseScatterX: 0,\r\n instanceDisperseScatterY: 0,\r\n instanceDisperseScatterZ: 0,\r\n modelTransitionDuration: 0,\r\n };\r\n\r\n const system = this.engine.createParticleSystem(config);\r\n const obj = new String3DObject(object.id, \"particles\", system, this.engine);\r\n onAdd(obj);\r\n }\r\n\r\n private createText(object: StringObject, onAdd: (obj: String3DObject) => void): void {\r\n if (!this.engine.createTextGeometry) {\r\n return;\r\n }\r\n\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\r\n const group = this.engine.createGroup();\r\n (group as any).__textMesh = mesh;\r\n group.add(mesh);\r\n\r\n const obj = new String3DObject(object.id, \"text\", group, this.engine, {\r\n geometry,\r\n material,\r\n });\r\n onAdd(obj);\r\n }\r\n\r\n private getGeometryQuality(element?: HTMLElement | null): number {\r\n if (!element) return 1;\r\n const quality = readNumberStyle(element, \"--geometry-quality\", 1);\r\n if (!Number.isFinite(quality) || quality <= 0) return 1;\r\n return quality;\r\n }\r\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 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?.();\r\n if (!factory) {\r\n return null;\r\n }\r\n if (!factory.supports(definition)) {\r\n return null;\r\n }\r\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 }\r\n\r\n const manager = loader?.manager;\r\n if (!manager || typeof manager.setURLModifier !== \"function\") {\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\";\r\nimport type { String3DObjectSyncStrategy } from \"./String3DObjectSyncStrategy\";\r\nimport type { SyncContext } from \"./SyncContext\";\r\nimport { StyleReader } from \"../../modules/string3d/styleUtils\";\r\nimport { StyleBundleCache } from \"./StyleBundleCache\";\r\nimport type { ParticleSystemConfig } from \"../abstractions/I3DEngine\";\r\nimport { String3DCustomMaterialRegistry } from \"../materials\";\r\nimport type { IMaterialInstance } from \"../materials\";\r\n\r\ntype ParticleStyleBundle = ParticleSystemConfig & {\r\n translateZ: number;\r\n scale: number;\r\n rotateX: number;\r\n rotateY: number;\r\n rotateZ: number;\r\n particlesFit: boolean;\r\n materialType: string;\r\n};\r\n\r\nconst DEG_TO_RAD = Math.PI / 180;\r\n\r\nconst DEFAULT_CONFIG: ParticleSystemConfig = {\r\n mode: \"emitter\",\r\n count: 300,\r\n size: 2,\r\n color: \"#ffffff\",\r\n opacity: 1,\r\n spread: 120,\r\n spreadX: 120,\r\n spreadY: 120,\r\n seed: 1,\r\n emitRate: 30,\r\n emitBurst: 0,\r\n particleLife: 2.5,\r\n particleSpeed: 40,\r\n particleDirection: [0, 1, 0],\r\n particleGravity: [0, -30, 0],\r\n particleDrag: 0.1,\r\n particleSizeVariation: 0.6,\r\n particleColorVariation: 0.2,\r\n particleShape: \"sphere\",\r\n particleModelUrl: \"\",\r\n particleModelLoader: \"\",\r\n particleModelNode: \"\",\r\n instanceShape: \"sphere\",\r\n instanceModelUrl: \"\",\r\n instanceModelLoader: \"\",\r\n instanceModelNode: \"\",\r\n instanceScale: 1,\r\n instanceScaleVariation: 0.5,\r\n instanceRotationSpeed: 0.4,\r\n instanceJitter: 0.2,\r\n instanceFlow: 0.3,\r\n instanceDisperse: 0,\r\n instanceDisperseScatter: 0,\r\n instanceDisperseScatterX: 0,\r\n instanceDisperseScatterY: 0,\r\n instanceDisperseScatterZ: 0,\r\n modelTransitionDuration: 0,\r\n};\r\n\r\nexport class ParticlesSynchronizer implements String3DObjectSyncStrategy {\r\n private static styleCache = new StyleBundleCache<ParticleStyleBundle>();\r\n private static lastConfig: WeakMap<String3DObject, ParticleSystemConfig> = new WeakMap();\r\n private static lastTime: WeakMap<String3DObject, number> = new WeakMap();\r\n private static lastMaterialType: WeakMap<String3DObject, string> = new WeakMap();\r\n private static materialInstances: WeakMap<String3DObject, IMaterialInstance> = new WeakMap();\r\n\r\n sync(el: HTMLElement, object: String3DObject, ctx: SyncContext, parentData: any): any {\r\n const cached = (el as any).__layoutCache;\r\n const rect = cached ? cached.rect : el.getBoundingClientRect();\r\n const bundle = this.readStyleBundle(el, ctx);\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 bundle.translateZ\r\n );\r\n } else {\r\n const frustum = ctx.camera.getFrustumSizeAt(bundle.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 bundle.translateZ\r\n );\r\n }\r\n\r\n const parentScale = parentData?.scale ?? 1;\r\n const scale = bundle.scale * parentScale;\r\n object.object.scale.set(scale, scale, scale);\r\n\r\n object.object.rotation.x = -bundle.rotateX * DEG_TO_RAD;\r\n object.object.rotation.y = bundle.rotateY * DEG_TO_RAD;\r\n object.object.rotation.z = -bundle.rotateZ * DEG_TO_RAD;\r\n object.object.rotation.order = \"XYZ\";\r\n\r\n const config = this.buildConfig(bundle, rect, ctx, parentData);\r\n const prev = ParticlesSynchronizer.lastConfig.get(object);\r\n if (!prev || !this.isSameConfig(prev, config)) {\r\n ParticlesSynchronizer.lastConfig.set(object, config);\r\n (object.object as any).setConfig?.(config);\r\n }\r\n\r\n this.updateMaterialOverrides(el, object, ctx, bundle);\r\n this.updateCustomUniforms(el, object, ctx);\r\n\r\n const now = performance.now();\r\n const last = ParticlesSynchronizer.lastTime.get(object) ?? now;\r\n const dt = Math.max(0, (now - last) / 1000);\r\n ParticlesSynchronizer.lastTime.set(object, now);\r\n (object.object as any).update?.(dt);\r\n\r\n return { scale: parentData?.scale ?? 1 };\r\n }\r\n\r\n private readStyleBundle(el: HTMLElement, ctx: SyncContext): ParticleStyleBundle {\r\n return ParticlesSynchronizer.styleCache.get(el, ctx, (el) => {\r\n const styles = new StyleReader(el);\r\n const modeRaw = styles.readString(\"--particles-mode\", DEFAULT_CONFIG.mode).toLowerCase();\r\n const mode = modeRaw === \"instanced\" ? \"instanced\" : \"emitter\";\r\n return {\r\n ...DEFAULT_CONFIG,\r\n translateZ: styles.readNumber(\"--translate-z\", 0),\r\n scale: styles.readNumber(\"--scale\", 1),\r\n rotateX: styles.readNumber(\"--rotate-x\", 0),\r\n rotateY: styles.readNumber(\"--rotate-y\", 0),\r\n rotateZ: styles.readNumber(\"--rotate-z\", 0),\r\n particlesFit: styles.readNumber(\"--particles-fit\", 0) > 0.5,\r\n materialType: styles.readString(\"--material-type\", \"basic\"),\r\n mode,\r\n count: styles.readNumber(\"--particles-count\", DEFAULT_CONFIG.count),\r\n size: styles.readNumber(\"--particles-size\", DEFAULT_CONFIG.size),\r\n color: styles.readString(\"--particles-color\", DEFAULT_CONFIG.color),\r\n opacity: styles.readNumber(\"--particles-opacity\", DEFAULT_CONFIG.opacity),\r\n spread: styles.readNumber(\"--particles-spread\", DEFAULT_CONFIG.spread),\r\n seed: styles.readNumber(\"--particles-seed\", DEFAULT_CONFIG.seed),\r\n emitRate: styles.readNumber(\"--emit-rate\", DEFAULT_CONFIG.emitRate),\r\n emitBurst: styles.readNumber(\"--emit-burst\", DEFAULT_CONFIG.emitBurst),\r\n particleLife: styles.readNumber(\"--particle-life\", DEFAULT_CONFIG.particleLife),\r\n particleSpeed: styles.readNumber(\"--particle-speed\", DEFAULT_CONFIG.particleSpeed),\r\n particleDirection: this.parseVec3(\r\n styles.readString(\"--particle-direction\", \"0 1 0\"),\r\n DEFAULT_CONFIG.particleDirection\r\n ),\r\n particleGravity: this.parseVec3(\r\n styles.readString(\"--particle-gravity\", \"0 -30 0\"),\r\n DEFAULT_CONFIG.particleGravity\r\n ),\r\n particleDrag: styles.readNumber(\"--particle-drag\", DEFAULT_CONFIG.particleDrag),\r\n particleSizeVariation: styles.readNumber(\r\n \"--particle-size-variation\",\r\n DEFAULT_CONFIG.particleSizeVariation\r\n ),\r\n particleColorVariation: styles.readNumber(\r\n \"--particle-color-variation\",\r\n DEFAULT_CONFIG.particleColorVariation\r\n ),\r\n particleShape: this.parseShape(\r\n styles.readString(\"--particles-shape\", DEFAULT_CONFIG.particleShape)\r\n ),\r\n particleModelUrl: styles.readString(\"--particles-model\", DEFAULT_CONFIG.particleModelUrl),\r\n particleModelLoader: styles.readString(\r\n \"--particles-model-loader\",\r\n DEFAULT_CONFIG.particleModelLoader\r\n ),\r\n particleModelNode: styles.readString(\r\n \"--particles-model-node\",\r\n DEFAULT_CONFIG.particleModelNode\r\n ),\r\n instanceShape: this.parseDistribution(\r\n styles.readString(\"--instance-shape\", DEFAULT_CONFIG.instanceShape)\r\n ),\r\n instanceModelUrl: styles.readString(\"--instance-model\", DEFAULT_CONFIG.instanceModelUrl),\r\n instanceModelLoader: styles.readString(\r\n \"--instance-model-loader\",\r\n DEFAULT_CONFIG.instanceModelLoader\r\n ),\r\n instanceModelNode: styles.readString(\r\n \"--instance-model-node\",\r\n DEFAULT_CONFIG.instanceModelNode\r\n ),\r\n instanceScale: styles.readNumber(\"--instance-scale\", DEFAULT_CONFIG.instanceScale),\r\n instanceScaleVariation: styles.readNumber(\r\n \"--instance-scale-variation\",\r\n DEFAULT_CONFIG.instanceScaleVariation\r\n ),\r\n instanceRotationSpeed: styles.readNumber(\r\n \"--instance-rotation-speed\",\r\n DEFAULT_CONFIG.instanceRotationSpeed\r\n ),\r\n instanceJitter: styles.readNumber(\"--instance-jitter\", DEFAULT_CONFIG.instanceJitter),\r\n instanceFlow: styles.readNumber(\"--instance-flow\", DEFAULT_CONFIG.instanceFlow),\r\n instanceDisperse: styles.readNumber(\"--instance-disperse\", DEFAULT_CONFIG.instanceDisperse),\r\n instanceDisperseScatter: styles.readNumber(\r\n \"--instance-scatter\",\r\n DEFAULT_CONFIG.instanceDisperseScatter\r\n ),\r\n instanceDisperseScatterX: styles.readNumber(\r\n \"--instance-scatter-x\",\r\n DEFAULT_CONFIG.instanceDisperseScatterX\r\n ),\r\n instanceDisperseScatterY: styles.readNumber(\r\n \"--instance-scatter-y\",\r\n DEFAULT_CONFIG.instanceDisperseScatterY\r\n ),\r\n instanceDisperseScatterZ: styles.readNumber(\r\n \"--instance-scatter-z\",\r\n DEFAULT_CONFIG.instanceDisperseScatterZ\r\n ),\r\n modelTransitionDuration: this.getTransitionDuration(el, \"--instance-model\"),\r\n };\r\n });\r\n }\r\n\r\n private getTransitionDuration(el: HTMLElement, property: string): number {\r\n const style = getComputedStyle(el);\r\n const properties = this.splitTransitionList(style.transitionProperty);\r\n const durations = this.splitTransitionList(style.transitionDuration);\r\n\r\n const index = this.findTransitionIndex(properties, property);\r\n if (index === -1) {\r\n const shorthand = this.parseTransitionShorthand(style.transition);\r\n const match = shorthand.get(property) || shorthand.get(\"all\");\r\n return match ? match.duration : 0;\r\n }\r\n\r\n return this.parseTime(durations[index] || durations[durations.length - 1] || \"0s\");\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 / 1000 : 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 : 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(value: string): Map<string, { duration: number }> {\r\n const map = new Map<string, { duration: number }>();\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 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 (\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 } 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 });\r\n });\r\n return map;\r\n }\r\n\r\n private parseVec3(value: string, fallback: [number, number, number]): [number, number, number] {\r\n const parts = value\r\n .split(/[\\s,]+/)\r\n .map((part) => Number.parseFloat(part))\r\n .filter((num) => !Number.isNaN(num));\r\n if (parts.length >= 3) {\r\n return [parts[0], parts[1], parts[2]];\r\n }\r\n return fallback;\r\n }\r\n\r\n private parseShape(value: string): \"box\" | \"sphere\" | \"model\" {\r\n const normalized = value.trim().toLowerCase();\r\n if (normalized === \"box\") return \"box\";\r\n if (normalized === \"model\") return \"model\";\r\n return \"sphere\";\r\n }\r\n\r\n private parseDistribution(value: string): \"box\" | \"sphere\" | \"model\" {\r\n return this.parseShape(value);\r\n }\r\n\r\n private buildConfig(\r\n bundle: ParticleStyleBundle,\r\n rect: DOMRect,\r\n ctx: SyncContext,\r\n parentData: any\r\n ): ParticleSystemConfig {\r\n const parentScale = parentData?.scale ?? 1;\r\n const scale = parentScale;\r\n const fitMultiplier = 0.5;\r\n let spread: number;\r\n let spreadX: number;\r\n let spreadY: number;\r\n if (bundle.particlesFit) {\r\n spreadX = this.toWorld(rect.width * fitMultiplier, bundle.translateZ, ctx);\r\n spreadY = this.toWorld(rect.height * fitMultiplier, bundle.translateZ, ctx);\r\n spread = Math.max(spreadX, spreadY);\r\n } else {\r\n spread = this.toWorld(bundle.spread, bundle.translateZ, ctx);\r\n spreadX = spread;\r\n spreadY = spread;\r\n }\r\n return {\r\n ...bundle,\r\n count: Math.max(0, Math.floor(bundle.count)),\r\n size: Math.max(0.1, bundle.size),\r\n opacity: Math.max(0, Math.min(1, bundle.opacity)),\r\n spread: Math.max(0, spread * scale),\r\n spreadX: Math.max(0, spreadX * scale),\r\n spreadY: Math.max(0, spreadY * scale),\r\n seed: Math.max(0, Math.floor(bundle.seed)),\r\n emitRate: Math.max(0, bundle.emitRate),\r\n emitBurst: Math.max(0, bundle.emitBurst),\r\n particleLife: Math.max(0.1, bundle.particleLife),\r\n particleSpeed: Math.max(0, bundle.particleSpeed),\r\n particleDrag: Math.max(0, Math.min(1, bundle.particleDrag)),\r\n particleSizeVariation: Math.max(0, bundle.particleSizeVariation),\r\n particleColorVariation: Math.max(0, bundle.particleColorVariation),\r\n instanceScale: Math.max(0.1, bundle.instanceScale),\r\n instanceScaleVariation: Math.max(0, bundle.instanceScaleVariation),\r\n instanceRotationSpeed: Math.max(0, bundle.instanceRotationSpeed),\r\n instanceJitter: Math.max(0, bundle.instanceJitter),\r\n instanceFlow: Math.max(0, bundle.instanceFlow),\r\n instanceDisperse: Math.max(0, bundle.instanceDisperse),\r\n instanceDisperseScatter: Math.max(0, bundle.instanceDisperseScatter),\r\n instanceDisperseScatterX: Math.max(0, bundle.instanceDisperseScatterX),\r\n instanceDisperseScatterY: Math.max(0, bundle.instanceDisperseScatterY),\r\n instanceDisperseScatterZ: Math.max(0, bundle.instanceDisperseScatterZ),\r\n };\r\n }\r\n\r\n private toWorld(value: number, z: number, ctx: SyncContext): number {\r\n if (ctx.camera.getMode() === \"orthographic\") {\r\n return value;\r\n }\r\n const frustum = ctx.camera.getFrustumSizeAt(z);\r\n const perPixel = frustum.width / Math.max(1, ctx.viewportWidth);\r\n return value * perPixel;\r\n }\r\n\r\n private isSameConfig(a: ParticleSystemConfig, b: ParticleSystemConfig): boolean {\r\n return JSON.stringify(a) === JSON.stringify(b);\r\n }\r\n\r\n private updateMaterialOverrides(\r\n el: HTMLElement,\r\n object: String3DObject,\r\n ctx: SyncContext,\r\n bundle: ParticleStyleBundle\r\n ): void {\r\n const typeRaw = bundle.materialType || \"basic\";\r\n const type = typeRaw.split(\"[\")[0].trim().toLowerCase();\r\n const definition = String3DCustomMaterialRegistry.get(type);\r\n const factory = ctx.engine.getMaterialFactory?.();\r\n\r\n if (!definition || !factory || !factory.supports(definition)) {\r\n const hasExisting =\r\n ParticlesSynchronizer.materialInstances.has(object) ||\r\n ParticlesSynchronizer.lastMaterialType.has(object);\r\n if (!hasExisting) return;\r\n\r\n const existing = ParticlesSynchronizer.materialInstances.get(object);\r\n if (existing) {\r\n existing.dispose();\r\n ParticlesSynchronizer.materialInstances.delete(object);\r\n }\r\n ParticlesSynchronizer.lastMaterialType.delete(object);\r\n (object.object as any).setMaterial?.(null, { points: true, meshes: true });\r\n return;\r\n }\r\n\r\n const lastType = ParticlesSynchronizer.lastMaterialType.get(object);\r\n if (lastType !== type) {\r\n const existing = ParticlesSynchronizer.materialInstances.get(object);\r\n if (existing) existing.dispose();\r\n\r\n const style = getComputedStyle(el);\r\n const initialUniforms = factory.parseUniformsFromCSS(definition, el, style);\r\n const instance = factory.create(definition, initialUniforms);\r\n ParticlesSynchronizer.materialInstances.set(object, instance);\r\n ParticlesSynchronizer.lastMaterialType.set(object, type);\r\n\r\n const material = instance.material;\r\n const isShader = !!material?.isShaderMaterial;\r\n const system: any = object.object as any;\r\n system.setMaterial?.(material, { meshes: true, points: false });\r\n system.setMaterial?.(isShader ? material : null, { meshes: false, points: true });\r\n }\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\r\n for (const [key, value] of Object.entries(values)) {\r\n const def = definition.uniforms?.[key];\r\n if (!def) continue;\r\n\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 || child.isPoints) {\r\n const materials = Array.isArray(child.material) ? child.material : [child.material];\r\n materials.forEach(apply);\r\n }\r\n });\r\n }\r\n }\r\n}\r\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 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 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\nconst PSEUDO_ELEMENT_CSS = `\r\n[data-string3d-text] {\r\n -webkit-text-fill-color: transparent;\r\n}\r\n\r\n[data-string3d-text]::before {\r\n content: attr(data-string3d-text);\r\n position: absolute;\r\n left: 0;\r\n top: 0;\r\n width: 100%;\r\n height: 100%;\r\n pointer-events: none;\r\n \r\n color: inherit;\r\n -webkit-text-fill-color: initial;\r\n font: inherit;\r\n text-transform: inherit;\r\n letter-spacing: inherit;\r\n line-height: inherit;\r\n text-align: inherit;\r\n white-space: inherit;\r\n word-spacing: inherit;\r\n \r\n transform: var(--string3d-transform, none);\r\n transform-style: preserve-3d;\r\n transform-origin: center center;\r\n}\r\n`;\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 private static pseudoStyleInjected = false;\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 private static injectPseudoElementStyles(): void {\r\n if (this.pseudoStyleInjected || typeof document === \"undefined\") return;\r\n\r\n const style = document.createElement(\"style\");\r\n style.setAttribute(\"data-string3d\", \"pseudo-text\");\r\n style.textContent = PSEUDO_ELEMENT_CSS;\r\n document.head.appendChild(style);\r\n this.pseudoStyleInjected = true;\r\n }\r\n\r\n private static setupSelectableText(el: HTMLElement): void {\r\n const textContent = el.textContent || \"\";\r\n\r\n if (el.dataset.string3dText !== textContent) {\r\n el.dataset.string3dText = textContent;\r\n }\r\n\r\n const computed = getComputedStyle(el);\r\n if (computed.position === \"static\") {\r\n el.style.position = \"relative\";\r\n }\r\n\r\n const rx = computed.getPropertyValue(\"--rotate-x\").trim() || \"0\";\r\n const ry = computed.getPropertyValue(\"--rotate-y\").trim() || \"0\";\r\n const rz = computed.getPropertyValue(\"--rotate-z\").trim() || \"0\";\r\n const tx = computed.getPropertyValue(\"--translate-x\").trim() || \"0px\";\r\n const ty = computed.getPropertyValue(\"--translate-y\").trim() || \"0px\";\r\n const tz = computed.getPropertyValue(\"--translate-z\").trim() || \"0px\";\r\n const s = computed.getPropertyValue(\"--scale\").trim() || \"1\";\r\n\r\n const transform = [\r\n tx !== \"0px\" && tx !== \"0\" ? `translateX(${tx})` : \"\",\r\n ty !== \"0px\" && ty !== \"0\" ? `translateY(${ty})` : \"\",\r\n tz !== \"0px\" && tz !== \"0\" ? `translateZ(${tz})` : \"\",\r\n rx !== \"0\" ? `rotateX(${rx}deg)` : \"\",\r\n ry !== \"0\" ? `rotateY(${ry}deg)` : \"\",\r\n rz !== \"0\" ? `rotateZ(${rz}deg)` : \"\",\r\n s !== \"1\" ? `scale(${s})` : \"\",\r\n ]\r\n .filter(Boolean)\r\n .join(\" \");\r\n\r\n el.style.setProperty(\"--string3d-transform\", transform || \"none\");\r\n }\r\n\r\n sync(el: HTMLElement, object: String3DObject, ctx: SyncContext, parentData: any): any {\r\n TextSynchronizer.injectPseudoElementStyles();\r\n TextSynchronizer.setupSelectableText(el);\r\n\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 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 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 metrics = TextSynchronizer.getFontMetrics(font, fontSize);\r\n const ascent = metrics ? metrics.ascent : fontSize * 0.8;\r\n\r\n const adjustedLayout = layout.map((item) => ({\r\n ...item,\r\n y: item.y + ascent,\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 });\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\";\nimport { String3DObject } from \"../String3DObject\";\nimport { I3DEngine } from \"../abstractions/I3DEngine\";\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\nexport class String3DSynchronizer {\n private strategies: Map<string, String3DObjectSyncStrategy> = new Map();\n private styleReadIntervalMs = 0;\n private layoutReadIntervalMs = 0;\n\n constructor(\n public camera: String3DCamera,\n public viewportWidth: number,\n public viewportHeight: number,\n public engine: I3DEngine\n ) {\n this.strategies.set(\"box\", new MeshSynchronizer());\n this.strategies.set(\"sphere\", new MeshSynchronizer());\n this.strategies.set(\"plane\", new MeshSynchronizer());\n this.strategies.set(\"cylinder\", new MeshSynchronizer());\n this.strategies.set(\"model\", new MeshSynchronizer());\n this.strategies.set(\"group\", new GroupSynchronizer());\n this.strategies.set(\"pointLight\", new LightSynchronizer());\n this.strategies.set(\"ambientLight\", new LightSynchronizer());\n this.strategies.set(\"directionalLight\", new LightSynchronizer());\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\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 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: {\n styleReadIntervalMs?: number;\n layoutReadIntervalMs?: number;\n }): void {\n this.styleReadIntervalMs = Math.max(0, options.styleReadIntervalMs ?? 0);\n this.layoutReadIntervalMs = Math.max(0, options.layoutReadIntervalMs ?? 0);\n }\n\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 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 const isFontFile = FontConverter.isFontFile(normalized);\r\n\r\n let promise: Promise<any>;\r\n\r\n if (isFontFile) {\r\n promise = this.loadFontWithConverter(normalized);\r\n } else {\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 const font = this.createFontFromData(fontData);\r\n this.fontCache.set(url, font);\r\n return font;\r\n } catch (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 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 () => {\r\n resolve(null);\r\n }\r\n );\r\n });\r\n }\r\n\r\n private createFontFromData(fontData: any): any {\r\n const font = {\r\n data: fontData,\r\n generateShapes: (text: string, size: number) => {\r\n return this.generateShapesFromFontData(fontData, text, size, false);\r\n },\r\n generateNormalizedShapes: (text: string, size: number) => {\r\n return this.generateShapesFromFontData(fontData, text, size, true);\r\n },\r\n };\r\n return font;\r\n }\r\n\r\n private generateShapesFromFontData(\r\n fontData: any,\r\n text: string,\r\n size: number,\r\n normalizePosition: boolean = false\r\n ): any[] {\r\n const shapes: any[] = [];\r\n const scale = size / fontData.resolution;\r\n\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 let xOffset = 0;\r\n if (normalizePosition) {\r\n const xMin = this.getOutlineXMin(glyph.o);\r\n xOffset = -xMin * scale;\r\n }\r\n\r\n const charShapes = this.parseOutlineToShapes(glyph.o, scale, xOffset);\r\n shapes.push(...charShapes);\r\n\r\n return shapes;\r\n }\r\n\r\n private getOutlineXMin(outline: string): number {\r\n const commands = outline.split(\" \");\r\n let minX = Infinity;\r\n let i = 0;\r\n\r\n while (i < commands.length) {\r\n const cmd = commands[i];\r\n switch (cmd) {\r\n case \"m\":\r\n case \"l\":\r\n minX = Math.min(minX, parseFloat(commands[i + 1]) || 0);\r\n i += 3;\r\n break;\r\n case \"q\":\r\n minX = Math.min(minX, parseFloat(commands[i + 1]) || 0);\r\n minX = Math.min(minX, parseFloat(commands[i + 3]) || 0);\r\n i += 5;\r\n break;\r\n case \"b\":\r\n minX = Math.min(minX, parseFloat(commands[i + 1]) || 0);\r\n minX = Math.min(minX, parseFloat(commands[i + 3]) || 0);\r\n minX = Math.min(minX, parseFloat(commands[i + 5]) || 0);\r\n i += 7;\r\n break;\r\n default:\r\n i++;\r\n break;\r\n }\r\n }\r\n\r\n return minX === Infinity ? 0 : minX;\r\n }\r\n\r\n private getOutlineXMax(outline: string): number {\r\n const commands = outline.split(\" \");\r\n let maxX = -Infinity;\r\n let i = 0;\r\n\r\n while (i < commands.length) {\r\n const cmd = commands[i];\r\n switch (cmd) {\r\n case \"m\":\r\n case \"l\":\r\n maxX = Math.max(maxX, parseFloat(commands[i + 1]) || 0);\r\n i += 3;\r\n break;\r\n case \"q\":\r\n maxX = Math.max(maxX, parseFloat(commands[i + 1]) || 0);\r\n maxX = Math.max(maxX, parseFloat(commands[i + 3]) || 0);\r\n i += 5;\r\n break;\r\n case \"b\":\r\n maxX = Math.max(maxX, parseFloat(commands[i + 1]) || 0);\r\n maxX = Math.max(maxX, parseFloat(commands[i + 3]) || 0);\r\n maxX = Math.max(maxX, parseFloat(commands[i + 5]) || 0);\r\n i += 7;\r\n break;\r\n default:\r\n i++;\r\n break;\r\n }\r\n }\r\n\r\n return maxX === -Infinity ? 0 : maxX;\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 (\r\n shapePath.currentPath &&\r\n typeof shapePath.currentPath.closePath === \"function\"\r\n ) {\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(false);\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 const lastCurve = path.curves[path.curves.length - 1];\r\n const endPoint =\r\n 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 for (let i = path.curves.length - 1; i >= 0; i--) {\r\n const curve = path.curves[i];\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 (\r\n curve.isQuadraticBezierCurve ||\r\n curve.type === \"QuadraticBezierCurve\" ||\r\n curve.type === \"QuadraticBezierCurve3\"\r\n ) {\r\n newPath.quadraticCurveTo(curve.v1.x, curve.v1.y, curve.v0.x, curve.v0.y);\r\n } else if (\r\n curve.isCubicBezierCurve ||\r\n curve.type === \"CubicBezierCurve\" ||\r\n curve.type === \"CubicBezierCurve3\"\r\n ) {\r\n newPath.bezierCurveTo(\r\n curve.v2.x,\r\n curve.v2.y,\r\n curve.v1.x,\r\n curve.v1.y,\r\n curve.v0.x,\r\n curve.v0.y\r\n );\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\r\n const lines = String(text).split(/\\r?\\n/);\r\n const shapes: any[] = [];\r\n\r\n const fontData = font?.data;\r\n const resolution = fontData?.resolution || 1000;\r\n const ascender = fontData?.ascender || 800;\r\n const descender = fontData?.descender || -200;\r\n const fontScale = size / resolution;\r\n const fontAscent = ascender * fontScale;\r\n\r\n if (options.layout && options.layout.length > 0) {\r\n options.layout.forEach((item: any) => {\r\n const charShapes = font.generateShapes(item.char, size);\r\n const offsetX = item.x;\r\n const offsetY = -item.y;\r\n\r\n charShapes.forEach((shape: any) => {\r\n let finalShape = this.translateShape(shape, offsetX, offsetY);\r\n if (item.scale && item.scale !== 1) {\r\n finalShape = this.scaleShape(finalShape, item.scale);\r\n }\r\n shapes.push(finalShape);\r\n });\r\n });\r\n } else {\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 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 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 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 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 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 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 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 () => {\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 private transitionStartTime = 0;\r\n private transitionDuration = 0;\r\n private isTransitioning = false;\r\n private transitionFromPositions: Float32Array = new Float32Array(0);\r\n private transitionToPositions: Float32Array = new Float32Array(0);\r\n private pendingTransition = false;\r\n private pendingTransitionKey = \"\";\r\n private pendingDistributionLoad = false;\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 const isParticleModelChange =\r\n this.cfg.mode === \"instanced\" &&\r\n this.instanced &&\r\n this.cfg.modelTransitionDuration > 0 &&\r\n (prev.particleModelUrl !== this.cfg.particleModelUrl ||\r\n prev.particleModelLoader !== this.cfg.particleModelLoader ||\r\n prev.particleModelNode !== this.cfg.particleModelNode ||\r\n prev.particleShape !== this.cfg.particleShape);\r\n\r\n const isInstanceModelChange =\r\n this.cfg.mode === \"instanced\" &&\r\n this.instanced &&\r\n this.cfg.modelTransitionDuration > 0 &&\r\n (prev.instanceModelUrl !== this.cfg.instanceModelUrl ||\r\n prev.instanceModelLoader !== this.cfg.instanceModelLoader ||\r\n prev.instanceModelNode !== this.cfg.instanceModelNode ||\r\n prev.instanceShape !== this.cfg.instanceShape);\r\n\r\n if (isParticleModelChange || isInstanceModelChange) {\r\n this.startModelTransition();\r\n } else {\r\n this.refreshModelGeometry();\r\n this.refreshDistributionGeometry();\r\n this.rebuild();\r\n }\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 private startModelTransition(): void {\r\n this.transitionFromPositions = new Float32Array(this.basePositions);\r\n this.transitionDuration = this.cfg.modelTransitionDuration;\r\n\r\n const url = this.cfg.instanceModelUrl?.trim();\r\n const key = `${this.cfg.instanceModelLoader}|${url}|${this.cfg.instanceModelNode}`;\r\n this.pendingTransition = true;\r\n this.pendingTransitionKey = key;\r\n\r\n this.refreshModelGeometry();\r\n this.refreshDistributionGeometryForTransition();\r\n }\r\n\r\n private refreshDistributionGeometryForTransition(): void {\r\n if (this.cfg.instanceShape !== \"model\") {\r\n this.startMorphTransition();\r\n return;\r\n }\r\n const url = this.cfg.instanceModelUrl?.trim();\r\n if (!url || url === \"none\") {\r\n this.startMorphTransition();\r\n return;\r\n }\r\n const key = `${this.cfg.instanceModelLoader}|${url}|${this.cfg.instanceModelNode}`;\r\n\r\n if (this.distributionKey === key && this.distributionGeometry) {\r\n this.startMorphTransition();\r\n return;\r\n }\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 if (!this.pendingTransition || this.pendingTransitionKey !== key) return;\r\n\r\n this.distributionGeometry = geometry;\r\n this.startMorphTransition();\r\n });\r\n }\r\n\r\n private startMorphTransition(): void {\r\n this.pendingTransition = false;\r\n this.pendingTransitionKey = \"\";\r\n\r\n const count = Math.max(1, this.cfg.count);\r\n this.transitionToPositions = new Float32Array(count * 3);\r\n\r\n const useModel = this.cfg.instanceShape === \"model\" && this.distributionGeometry;\r\n if (useModel) {\r\n this.fillFromModelToArray(count, this.distributionGeometry, this.transitionToPositions);\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.transitionToPositions.set(pos, i * 3);\r\n }\r\n }\r\n\r\n this.transitionStartTime = this.elapsed;\r\n this.isTransitioning = true;\r\n }\r\n\r\n private cleanupOutgoing(): void {\r\n this.isTransitioning = false;\r\n this.pendingTransition = false;\r\n this.pendingTransitionKey = \"\";\r\n this.transitionFromPositions = new Float32Array(0);\r\n this.transitionToPositions = new Float32Array(0);\r\n }\r\n\r\n private updateTransition(): void {\r\n if (!this.isTransitioning) return;\r\n\r\n const elapsed = this.elapsed - this.transitionStartTime;\r\n const progress = Math.min(1, elapsed / this.transitionDuration);\r\n\r\n const eased =\r\n progress < 0.5 ? 2 * progress * progress : 1 - Math.pow(-2 * progress + 2, 2) / 2;\r\n\r\n const count = Math.min(\r\n this.transitionFromPositions.length / 3,\r\n this.transitionToPositions.length / 3,\r\n this.basePositions.length / 3\r\n );\r\n\r\n for (let i = 0; i < count; i += 1) {\r\n const i3 = i * 3;\r\n this.basePositions[i3] =\r\n this.transitionFromPositions[i3] +\r\n (this.transitionToPositions[i3] - this.transitionFromPositions[i3]) * eased;\r\n this.basePositions[i3 + 1] =\r\n this.transitionFromPositions[i3 + 1] +\r\n (this.transitionToPositions[i3 + 1] - this.transitionFromPositions[i3 + 1]) * eased;\r\n this.basePositions[i3 + 2] =\r\n this.transitionFromPositions[i3 + 2] +\r\n (this.transitionToPositions[i3 + 2] - this.transitionFromPositions[i3 + 2]) * eased;\r\n }\r\n\r\n if (progress >= 1) {\r\n for (let i = 0; i < count * 3; i += 1) {\r\n this.basePositions[i] = this.transitionToPositions[i];\r\n }\r\n this.cleanupOutgoing();\r\n }\r\n }\r\n\r\n private fillFromModelToArray(count: number, geometry: any, targetArray: Float32Array): 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 targetArray.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 targetX = (this.cfg.spreadX > 0 ? this.cfg.spreadX : this.cfg.spread) * 2;\r\n const targetY = (this.cfg.spreadY > 0 ? this.cfg.spreadY : this.cfg.spread) * 2;\r\n const scaleX = targetX > 0 ? targetX / sizeX : 1;\r\n const scaleY = targetY > 0 ? targetY / sizeY : 1;\r\n const scale = Math.min(scaleX, scaleY);\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 targetArray.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 targetArray[i * 3] = x;\r\n targetArray[i * 3 + 1] = y;\r\n targetArray[i * 3 + 2] = z;\r\n }\r\n }\r\n\r\n update(dt: number): void {\r\n if (dt <= 0) return;\r\n this.elapsed += dt;\r\n\r\n this.updateTransition();\r\n\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 this.cleanupOutgoing();\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 const needsModel = this.cfg.instanceShape === \"model\";\r\n const hasModel = this.distributionGeometry !== null;\r\n if (needsModel && !hasModel) {\r\n this.pendingDistributionLoad = true;\r\n this.refreshDistributionGeometry();\r\n return;\r\n }\r\n this.pendingDistributionLoad = false;\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 if (this.pendingDistributionLoad) {\r\n this.pendingDistributionLoad = false;\r\n this.buildInstanced();\r\n this.applyMaterialOverrides();\r\n } else {\r\n this.rebuild();\r\n }\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 targetX = (this.cfg.spreadX > 0 ? this.cfg.spreadX : this.cfg.spread) * 2;\r\n const targetY = (this.cfg.spreadY > 0 ? this.cfg.spreadY : this.cfg.spread) * 2;\r\n const scaleX = targetX > 0 ? targetX / sizeX : 1;\r\n const scaleY = targetY > 0 ? targetY / sizeY : 1;\r\n const scale = Math.min(scaleX, scaleY);\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":["StringModule","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","type","parseUniformValue","def","cssValue","trimmed","num","parts","s","n","parseColorValue","match","value","hex","r","g","b","rgbMatch","collectUniformsFromCSS","definition","element","style","result","parsed","key","mergeInjections","injections","grouped","injection","list","point","sorted","a","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","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","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","property","style","properties","durations","index","shorthand","match","value","result","current","depth","i","ch","name","normalized","prop","raw","num","map","part","tokens","duration","token","lower","fallback","parts","fitMultiplier","spread","spreadX","spreadY","z","perPixel","a","b","type","definition","String3DCustomMaterialRegistry","factory","existing","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","i","glyph","char","path","outline","advanceWidth","spaceGlyph","commands","cmd","value","url","lower","DEG_TO_RAD","PSEUDO_ELEMENT_CSS","_TextSynchronizer","fontUrl","object","set","obj","style","el","textContent","computed","rx","ry","rz","tx","ty","tz","s","transform","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","DEG_TO_RAD","layout","l","useCanvasText","mesh","fontEntry","String3DFontRegistry","font","promise","loaded","layoutSig","key","metrics","ascent","adjustedLayout","item","geometry","parentScale","perPixel","scaleFactor","scaleZ","localOffsetX","localOffsetY","MeshSynchronizer","range","elRect","walker","node","text","i","char","rects","r","x","y","visibleChar","anyObj","found","child","factory","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","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","b","fromValue","_String3D","StringModule","context","DirtySyncManager","FilterController","value","provider","name","url","options","String3DFontRegistry","object","globalId","element","attributes","parentElement","parentId","String3DRenderer","String3DCamera","modelLoader","modelLoaderFactory","String3DScene","String3DSynchronizer","shouldUseDirtySync","key","fallback","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","loader","resolve","text","size","normalizePosition","shapes","scale","char","glyph","xOffset","charShapes","outline","commands","minX","i","maxX","offsetX","shapePath","mx","my","lx","ly","qx","qy","bx","by","path","newPath","lastCurve","endPoint","curve","lineHeight","letterSpacing","align","bevelEnabled","bevelThickness","bevelSize","bevelOffset","bevelSegments","curveSegments","lines","resolution","ascender","descender","fontScale","fontAscent","item","offsetY","shape","finalShape","line","index","lineShapes","chars","translated","advance","data","glyphs","ha","matrix","points","holes","toVec2","pt","newShape","hole","holePath","s","modelUrl","loaderType","nodeName","normalizedLoader","nodeKey","cacheKey","gltf","root","mesh","found","child","config","engine","makeRng","seed","ParticleSystem","cfg","prev","emitterReset","isParticleModelChange","isInstanceModelChange","uniforms","key","count","pos","elapsed","progress","eased","i3","targetArray","attr","array","itemSize","vertexCount","indexArray","triangleCount","minY","minZ","maxY","maxZ","idx","sizeX","sizeY","sizeZ","targetX","targetY","scaleX","scaleY","centerX","centerY","centerZ","cumulativeAreas","totalArea","base","ia","ib","ic","a","b","c","ax","ay","az","bz","cx","cy","cz","abx","aby","abz","acx","acy","acz","crossX","crossY","crossZ","area","r","lo","hi","mid","u","v","su","w1","w2","w3","dt","needsModel","hasModel","hide","useSharedGeometry","setPoints","dir","gravity","drag","totalToEmit","emitCount","colorDirty","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","next","vec","len","theta","phi","half","quality","Modifier","anyGeom","clamped","target","degrees","radians","object","boundingBox","hasBox","box","childBox","ThreeJSProvider"]}
|