@polarfront-lab/ionian 1.4.0 → 1.5.0
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.d.ts +3 -1
- package/dist/ionian.iife.js +1 -1
- package/dist/ionian.iife.js.map +1 -1
- package/dist/ionian.js +31 -14
- package/dist/ionian.js.map +1 -1
- package/package.json +1 -1
package/dist/ionian.iife.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ionian.iife.js","sources":["../src/lib/easing.ts","../src/lib/events/defaultEventEmitter.ts","../node_modules/.pnpm/mitt@3.0.1/node_modules/mitt/dist/mitt.mjs","../src/lib/utils.ts","../src/lib/services/assets/assetService.ts","../node_modules/.pnpm/three@0.173.0/node_modules/three/examples/jsm/math/MeshSurfaceSampler.js","../src/lib/services/dataTexture/dataTextureService.ts","../src/lib/services/instancedmesh/instancedMeshManager.ts","../src/lib/services/instancedmesh/shaders/instanceVertexShader.ts","../src/lib/services/instancedmesh/shaders/instanceFragmentShader.ts","../src/lib/services/intersection/intersectionService.ts","../node_modules/.pnpm/three@0.173.0/node_modules/three/examples/jsm/postprocessing/Pass.js","../node_modules/.pnpm/three@0.173.0/node_modules/three/examples/jsm/misc/GPUComputationRenderer.js","../src/lib/services/simulation/simulationRenderer.ts","../src/lib/services/simulation/shaders/simulationMixShader.ts","../src/lib/services/simulation/shaders/simulationVelocityShader.ts","../src/lib/services/simulation/shaders/simulationPositionShader.ts","../src/lib/services/simulation/simulationRendererService.ts","../src/lib/services/transition/transitionService.ts","../src/lib/particlesEngine.ts"],"sourcesContent":["import { EasingFunction } from '@/lib/types';\n\n/**\n * Linear easing function.\n */\nexport const linear: EasingFunction = (n: number) => n;\n","import { Events } from '@/lib/events/topics';\nimport mitt from 'mitt';\nimport { EngineEventEmitter } from './engineEventEmitter';\n\nexport class DefaultEventEmitter implements EngineEventEmitter<Events> {\n private readonly emitter = mitt<Events>();\n\n emit<Key extends keyof Events>(type: Key, payload: Events[Key]): void {\n this.emitter.emit(type, payload);\n }\n\n off<Key extends keyof Events>(type: Key, handler?: (payload: Events[Key]) => void): void {\n this.emitter.off(type, handler);\n }\n\n on<Key extends keyof Events>(type: Key, handler: (payload: Events[Key]) => void): void {\n this.emitter.on(type, handler);\n }\n\n once<Key extends keyof Events>(type: Key, handler: (payload: Events[Key]) => void): void {\n this.emitter.on(type, (payload: Events[Key]) => {\n this.emitter.off(type, handler);\n handler(payload);\n });\n }\n\n dispose(): void {\n this.emitter.all.clear();\n }\n}\n","export default function(n){return{all:n=n||new Map,on:function(t,e){var i=n.get(t);i?i.push(e):n.set(t,[e])},off:function(t,e){var i=n.get(t);i&&(e?i.splice(i.indexOf(e)>>>0,1):n.set(t,[]))},emit:function(t,e){var i=n.get(t);i&&i.slice().map(function(n){n(e)}),(i=n.get(\"*\"))&&i.slice().map(function(n){n(t,e)})}}}\n//# sourceMappingURL=mitt.mjs.map\n","import * as THREE from 'three';\n\n/**\n * Creates a new DataTexture from the given data and size.\n * @param data - The data for the texture.\n * @param size - The size of the texture.\n * @returns The created DataTexture.\n */\nexport function createDataTexture(data: Float32Array, size: number) {\n const texture = new THREE.DataTexture(data, size, size, THREE.RGBAFormat, THREE.FloatType);\n texture.needsUpdate = true;\n return texture;\n}\n\n/**\n * Creates a blank DataTexture with the given size.\n * @param size - The size of the texture.\n * @returns The created blank DataTexture.\n */\nexport function createBlankDataTexture(size: number) {\n return createDataTexture(new Float32Array(4 * size * size), size);\n}\n\n/**\n * Creates a DataTexture representing a sphere.\n * @param size - The size of the texture.\n * @returns The created DataTexture.\n */\nexport function createSpherePoints(size: number) {\n const data = new Float32Array(size * size * 4);\n for (let i = 0; i < size; i++) {\n for (let j = 0; j < size; j++) {\n const index = i * size + j;\n\n let theta = Math.random() * Math.PI * 2;\n let phi = Math.acos(Math.random() * 2 - 1);\n let x = Math.sin(phi) * Math.cos(theta);\n let y = Math.sin(phi) * Math.sin(theta);\n let z = Math.cos(phi);\n\n data[4 * index] = x;\n data[4 * index + 1] = y;\n data[4 * index + 2] = z;\n data[4 * index + 3] = (Math.random() - 0.5) * 0.01;\n }\n }\n\n return createDataTexture(data, size);\n}\n\nexport function disposeMesh(mesh: THREE.Mesh) {\n mesh.geometry.dispose();\n if (mesh.material instanceof THREE.Material) {\n mesh.material.dispose();\n } else {\n mesh.material.forEach((material) => material.dispose());\n }\n}\n\nexport function clamp(value: number, min: number, max: number): number {\n value = Math.min(value, max);\n value = Math.max(value, min);\n return value;\n}\n","import { DefaultEventEmitter } from '@/lib/events';\nimport { ServiceState } from '@/lib/types';\nimport { disposeMesh } from '@/lib/utils';\nimport * as THREE from 'three';\nimport { DRACOLoader, GLTFLoader } from 'three-stdlib';\n\nexport class AssetService {\n private serviceState: ServiceState = 'created';\n\n private readonly eventEmitter;\n private readonly meshes = new Map<string, THREE.Mesh>();\n private readonly textures = new Map<string, THREE.Texture>();\n\n private readonly gltfLoader = new GLTFLoader();\n private readonly textureLoader = new THREE.TextureLoader();\n private readonly dracoLoader = new DRACOLoader();\n\n private solidColorTexture = new THREE.DataTexture(new Uint8Array([127, 127, 127, 255]), 1, 1, THREE.RGBAFormat);\n\n constructor(eventEmitter: DefaultEventEmitter) {\n this.eventEmitter = eventEmitter;\n this.dracoLoader.setDecoderPath('https://www.gstatic.com/draco/versioned/decoders/1.5.7/');\n this.gltfLoader.setDRACOLoader(this.dracoLoader);\n this.updateServiceState('ready');\n }\n\n /**\n * Registers an asset.\n * @param id - The ID of the asset.\n * @param item - The asset to set.\n */\n register(id: string, item: THREE.Mesh | THREE.Texture) {\n item.name = id;\n\n if (item instanceof THREE.Mesh) {\n const prev = this.meshes.get(id);\n if (prev) disposeMesh(prev);\n this.meshes.set(id, item);\n } else {\n const prev = this.textures.get(id);\n if (prev) prev.dispose();\n this.textures.set(id, item);\n }\n\n this.eventEmitter.emit('assetRegistered', { id });\n }\n\n setSolidColor(color: THREE.ColorRepresentation) {\n this.changeColor(color);\n }\n\n getSolidColorTexture() {\n return this.solidColorTexture;\n }\n\n getMesh(id: string): THREE.Mesh | null {\n return this.meshes.get(id) ?? null;\n }\n\n getMatcap(id: string): THREE.Texture {\n const texture = this.textures.get(id);\n if (!texture) this.eventEmitter.emit('invalidRequest', { message: `texture with id \"${id}\" not found. using solid color texture instead...` });\n return texture ?? this.solidColorTexture;\n }\n\n getMeshIDs(): string[] {\n return Array.from(this.meshes.keys());\n }\n\n getTextureIDs(): string[] {\n return Array.from(this.textures.keys());\n }\n\n getMeshes(): THREE.Mesh[] {\n return Array.from(this.meshes.values());\n }\n\n getTextures(): THREE.Texture[] {\n return Array.from(this.textures.values());\n }\n\n hasMatcap(id: string) {\n return this.textures.has(id);\n }\n\n /**\n * Loads a mesh asynchronously.\n * @param id - The ID of the mesh.\n * @param url - The URL of the mesh.\n * @param options - Optional parameters.\n * @returns The loaded mesh or null.\n */\n async loadMeshAsync(id: string, url: string, options: { meshName?: string } = {}): Promise<THREE.Mesh | null> {\n const gltf = await this.gltfLoader.loadAsync(url);\n try {\n if (options.meshName) {\n const mesh = gltf.scene.getObjectByName(options.meshName) as THREE.Mesh;\n this.register(id, mesh);\n return mesh;\n } else {\n const mesh = gltf.scene.children[0] as THREE.Mesh;\n this.register(id, mesh);\n return mesh;\n }\n } catch (error) {\n this.eventEmitter.emit('invalidRequest', { message: `failed to load mesh: ${id}. ${error}` });\n return null;\n }\n }\n\n /**\n * Loads a texture asynchronously.\n * @param id - The ID of the texture.\n * @param url - The URL of the texture.\n * @returns The loaded texture or null.\n */\n async loadTextureAsync(id: string, url: string): Promise<THREE.Texture | null> {\n try {\n const texture = await this.textureLoader.loadAsync(url);\n this.register(id, texture);\n return texture;\n } catch (error) {\n this.eventEmitter.emit('invalidRequest', { message: `failed to load texture: ${id}. ${error}` });\n return null;\n }\n }\n\n dispose() {\n this.updateServiceState('disposed');\n this.meshes.forEach((mesh) => disposeMesh(mesh));\n this.meshes.clear();\n this.textures.forEach((texture) => texture.dispose());\n this.textures.clear();\n }\n\n private changeColor(color: THREE.ColorRepresentation) {\n const actual = new THREE.Color(color);\n this.solidColorTexture = new THREE.DataTexture(new Uint8Array([actual.r, actual.g, actual.b, 255]), 1, 1, THREE.RGBAFormat);\n this.solidColorTexture.needsUpdate = true;\n }\n\n private updateServiceState(serviceState: ServiceState) {\n this.serviceState = serviceState;\n this.eventEmitter.emit('serviceStateUpdated', { type: 'asset', state: serviceState });\n }\n}\n","import {\n\tTriangle,\n\tVector2,\n\tVector3\n} from 'three';\n\n/**\n * Utility class for sampling weighted random points on the surface of a mesh.\n *\n * Building the sampler is a one-time O(n) operation. Once built, any number of\n * random samples may be selected in O(logn) time. Memory usage is O(n).\n *\n * References:\n * - http://www.joesfer.com/?p=84\n * - https://stackoverflow.com/a/4322940/1314762\n */\n\nconst _face = new Triangle();\nconst _color = new Vector3();\nconst _uva = new Vector2(), _uvb = new Vector2(), _uvc = new Vector2();\n\nclass MeshSurfaceSampler {\n\n\tconstructor( mesh ) {\n\n\t\tthis.geometry = mesh.geometry;\n\t\tthis.randomFunction = Math.random;\n\n\t\tthis.indexAttribute = this.geometry.index;\n\t\tthis.positionAttribute = this.geometry.getAttribute( 'position' );\n\t\tthis.normalAttribute = this.geometry.getAttribute( 'normal' );\n\t\tthis.colorAttribute = this.geometry.getAttribute( 'color' );\n\t\tthis.uvAttribute = this.geometry.getAttribute( 'uv' );\n\t\tthis.weightAttribute = null;\n\n\t\tthis.distribution = null;\n\n\t}\n\n\tsetWeightAttribute( name ) {\n\n\t\tthis.weightAttribute = name ? this.geometry.getAttribute( name ) : null;\n\n\t\treturn this;\n\n\t}\n\n\tbuild() {\n\n\t\tconst indexAttribute = this.indexAttribute;\n\t\tconst positionAttribute = this.positionAttribute;\n\t\tconst weightAttribute = this.weightAttribute;\n\n\t\tconst totalFaces = indexAttribute ? ( indexAttribute.count / 3 ) : ( positionAttribute.count / 3 );\n\t\tconst faceWeights = new Float32Array( totalFaces );\n\n\t\t// Accumulate weights for each mesh face.\n\n\t\tfor ( let i = 0; i < totalFaces; i ++ ) {\n\n\t\t\tlet faceWeight = 1;\n\n\t\t\tlet i0 = 3 * i;\n\t\t\tlet i1 = 3 * i + 1;\n\t\t\tlet i2 = 3 * i + 2;\n\n\t\t\tif ( indexAttribute ) {\n\n\t\t\t\ti0 = indexAttribute.getX( i0 );\n\t\t\t\ti1 = indexAttribute.getX( i1 );\n\t\t\t\ti2 = indexAttribute.getX( i2 );\n\n\t\t\t}\n\n\t\t\tif ( weightAttribute ) {\n\n\t\t\t\tfaceWeight = weightAttribute.getX( i0 )\n\t\t\t\t\t+ weightAttribute.getX( i1 )\n\t\t\t\t\t+ weightAttribute.getX( i2 );\n\n\t\t\t}\n\n\t\t\t_face.a.fromBufferAttribute( positionAttribute, i0 );\n\t\t\t_face.b.fromBufferAttribute( positionAttribute, i1 );\n\t\t\t_face.c.fromBufferAttribute( positionAttribute, i2 );\n\t\t\tfaceWeight *= _face.getArea();\n\n\t\t\tfaceWeights[ i ] = faceWeight;\n\n\t\t}\n\n\t\t// Store cumulative total face weights in an array, where weight index\n\t\t// corresponds to face index.\n\n\t\tconst distribution = new Float32Array( totalFaces );\n\t\tlet cumulativeTotal = 0;\n\n\t\tfor ( let i = 0; i < totalFaces; i ++ ) {\n\n\t\t\tcumulativeTotal += faceWeights[ i ];\n\t\t\tdistribution[ i ] = cumulativeTotal;\n\n\t\t}\n\n\t\tthis.distribution = distribution;\n\t\treturn this;\n\n\t}\n\n\tsetRandomGenerator( randomFunction ) {\n\n\t\tthis.randomFunction = randomFunction;\n\t\treturn this;\n\n\t}\n\n\tsample( targetPosition, targetNormal, targetColor, targetUV ) {\n\n\t\tconst faceIndex = this.sampleFaceIndex();\n\t\treturn this.sampleFace( faceIndex, targetPosition, targetNormal, targetColor, targetUV );\n\n\t}\n\n\tsampleFaceIndex() {\n\n\t\tconst cumulativeTotal = this.distribution[ this.distribution.length - 1 ];\n\t\treturn this.binarySearch( this.randomFunction() * cumulativeTotal );\n\n\t}\n\n\tbinarySearch( x ) {\n\n\t\tconst dist = this.distribution;\n\t\tlet start = 0;\n\t\tlet end = dist.length - 1;\n\n\t\tlet index = - 1;\n\n\t\twhile ( start <= end ) {\n\n\t\t\tconst mid = Math.ceil( ( start + end ) / 2 );\n\n\t\t\tif ( mid === 0 || dist[ mid - 1 ] <= x && dist[ mid ] > x ) {\n\n\t\t\t\tindex = mid;\n\n\t\t\t\tbreak;\n\n\t\t\t} else if ( x < dist[ mid ] ) {\n\n\t\t\t\tend = mid - 1;\n\n\t\t\t} else {\n\n\t\t\t\tstart = mid + 1;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn index;\n\n\t}\n\n\tsampleFace( faceIndex, targetPosition, targetNormal, targetColor, targetUV ) {\n\n\t\tlet u = this.randomFunction();\n\t\tlet v = this.randomFunction();\n\n\t\tif ( u + v > 1 ) {\n\n\t\t\tu = 1 - u;\n\t\t\tv = 1 - v;\n\n\t\t}\n\n\t\t// get the vertex attribute indices\n\t\tconst indexAttribute = this.indexAttribute;\n\t\tlet i0 = faceIndex * 3;\n\t\tlet i1 = faceIndex * 3 + 1;\n\t\tlet i2 = faceIndex * 3 + 2;\n\t\tif ( indexAttribute ) {\n\n\t\t\ti0 = indexAttribute.getX( i0 );\n\t\t\ti1 = indexAttribute.getX( i1 );\n\t\t\ti2 = indexAttribute.getX( i2 );\n\n\t\t}\n\n\t\t_face.a.fromBufferAttribute( this.positionAttribute, i0 );\n\t\t_face.b.fromBufferAttribute( this.positionAttribute, i1 );\n\t\t_face.c.fromBufferAttribute( this.positionAttribute, i2 );\n\n\t\ttargetPosition\n\t\t\t.set( 0, 0, 0 )\n\t\t\t.addScaledVector( _face.a, u )\n\t\t\t.addScaledVector( _face.b, v )\n\t\t\t.addScaledVector( _face.c, 1 - ( u + v ) );\n\n\t\tif ( targetNormal !== undefined ) {\n\n\t\t\tif ( this.normalAttribute !== undefined ) {\n\n\t\t\t\t_face.a.fromBufferAttribute( this.normalAttribute, i0 );\n\t\t\t\t_face.b.fromBufferAttribute( this.normalAttribute, i1 );\n\t\t\t\t_face.c.fromBufferAttribute( this.normalAttribute, i2 );\n\t\t\t\ttargetNormal.set( 0, 0, 0 ).addScaledVector( _face.a, u ).addScaledVector( _face.b, v ).addScaledVector( _face.c, 1 - ( u + v ) ).normalize();\n\n\t\t\t} else {\n\n\t\t\t\t_face.getNormal( targetNormal );\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( targetColor !== undefined && this.colorAttribute !== undefined ) {\n\n\t\t\t_face.a.fromBufferAttribute( this.colorAttribute, i0 );\n\t\t\t_face.b.fromBufferAttribute( this.colorAttribute, i1 );\n\t\t\t_face.c.fromBufferAttribute( this.colorAttribute, i2 );\n\n\t\t\t_color\n\t\t\t\t.set( 0, 0, 0 )\n\t\t\t\t.addScaledVector( _face.a, u )\n\t\t\t\t.addScaledVector( _face.b, v )\n\t\t\t\t.addScaledVector( _face.c, 1 - ( u + v ) );\n\n\t\t\ttargetColor.r = _color.x;\n\t\t\ttargetColor.g = _color.y;\n\t\t\ttargetColor.b = _color.z;\n\n\t\t}\n\n\t\tif ( targetUV !== undefined && this.uvAttribute !== undefined ) {\n\n\t\t\t_uva.fromBufferAttribute( this.uvAttribute, i0 );\n\t\t\t_uvb.fromBufferAttribute( this.uvAttribute, i1 );\n\t\t\t_uvc.fromBufferAttribute( this.uvAttribute, i2 );\n\t\t\ttargetUV.set( 0, 0 ).addScaledVector( _uva, u ).addScaledVector( _uvb, v ).addScaledVector( _uvc, 1 - ( u + v ) );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n}\n\nexport { MeshSurfaceSampler };\n","import { DefaultEventEmitter } from '@/lib/events/defaultEventEmitter';\nimport { MeshData, ServiceState } from '@/lib/types';\nimport { createDataTexture } from '@/lib/utils';\nimport * as THREE from 'three';\nimport { MeshSurfaceSampler } from 'three/examples/jsm/math/MeshSurfaceSampler.js';\n\n/**\n * DataTextureManager is responsible for managing data textures used for mesh sampling.\n */\nexport class DataTextureService {\n private textureSize: number;\n private dataTextures: Map<string, THREE.DataTexture>;\n private eventEmitter;\n\n /**\n * Creates a new DataTextureManager instance.\n * @param eventEmitter\n * @param textureSize\n */\n constructor(eventEmitter: DefaultEventEmitter, textureSize: number) {\n this.eventEmitter = eventEmitter;\n this.textureSize = textureSize;\n this.dataTextures = new Map<string, THREE.DataTexture>();\n this.updateServiceState('ready');\n }\n\n setTextureSize(textureSize: number) {\n if (this.textureSize === textureSize) return;\n this.textureSize = textureSize;\n this.dataTextures.forEach((texture) => texture.dispose());\n this.dataTextures.clear();\n }\n\n /**\n * Prepares a mesh for sampling.\n * @returns The prepared data texture.\n * @param asset The asset to prepare.\n */\n async getDataTexture(asset: THREE.Mesh) {\n const texture = this.dataTextures.get(asset.name);\n if (texture) {\n return texture; // already prepared\n }\n\n const meshData = parseMeshData(asset);\n const array = sampleMesh(meshData, this.textureSize);\n const dataTexture = createDataTexture(array, this.textureSize);\n dataTexture.name = asset.name;\n return dataTexture;\n }\n\n async dispose() {\n this.dataTextures.clear();\n this.updateServiceState('disposed');\n }\n\n private updateServiceState(serviceState: ServiceState) {\n this.eventEmitter.emit('serviceStateUpdated', { type: 'data-texture', state: serviceState });\n }\n}\n\n/**\n * Parses mesh data into a simplified format.\n * @param mesh The mesh to parse.\n * @returns The parsed mesh data.\n */\nfunction parseMeshData(mesh: THREE.Mesh): MeshData {\n return {\n position: mesh.geometry.attributes.position.array,\n normal: (mesh.geometry.attributes.normal as THREE.BufferAttribute)?.array,\n scale: { x: mesh.scale.x, y: mesh.scale.y, z: mesh.scale.z },\n };\n}\n\nfunction sampleMesh(meshData: MeshData, size: number): Float32Array {\n const geometry = new THREE.BufferGeometry();\n geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(meshData.position), 3));\n if (meshData.normal) {\n geometry.setAttribute('normal', new THREE.BufferAttribute(new Float32Array(meshData.normal), 3));\n }\n const material = new THREE.MeshBasicMaterial();\n const mesh = new THREE.Mesh(geometry, material);\n mesh.scale.set(meshData.scale.x, meshData.scale.y, meshData.scale.z);\n\n const sampler = new MeshSurfaceSampler(mesh).build();\n const data = new Float32Array(size * size * 4);\n const position = new THREE.Vector3();\n\n for (let i = 0; i < size; i++) {\n for (let j = 0; j < size; j++) {\n const index = i * size + j;\n sampler.sample(position);\n data[4 * index] = position.x * meshData.scale.x;\n data[4 * index + 1] = position.y * meshData.scale.y;\n data[4 * index + 2] = position.z * meshData.scale.z;\n data[4 * index + 3] = (Math.random() - 0.5) * 0.01;\n }\n }\n\n return data;\n}\n","import * as THREE from 'three';\nimport { Vector3Like } from 'three';\nimport instanceFragmentShader from './shaders/instanceFragmentShader';\nimport instanceVertexShader from './shaders/instanceVertexShader';\n\ntype MaterialUniforms = {\n uTime: { value: number };\n uProgress: { value: number };\n uTexture: { value: THREE.DataTexture | null };\n uVelocity: { value: THREE.DataTexture | null };\n uOriginTexture: { value: THREE.Texture | null };\n uDestinationTexture: { value: THREE.Texture | null };\n};\n\n/**\n * InstancedMeshManager is responsible for managing instanced meshes.\n */\nexport class InstancedMeshManager {\n private size: number;\n private mesh: THREE.InstancedMesh;\n\n private readonly matcapMaterial: THREE.ShaderMaterial;\n private readonly fallbackGeometry: THREE.BufferGeometry;\n\n private readonly uniforms: MaterialUniforms;\n\n private originColor: THREE.ColorRepresentation | null;\n private destinationColor: THREE.ColorRepresentation | null;\n\n private geometries: Map<string, THREE.BufferGeometry>;\n private uvRefsCache: Map<number, THREE.InstancedBufferAttribute>;\n\n private previousScale: Vector3Like;\n\n /**\n * Creates a new InstancedMeshManager instance.\n * @param initialSize The initial size of the instanced mesh.\n */\n constructor(initialSize: number) {\n this.size = initialSize;\n this.geometries = new Map();\n this.uvRefsCache = new Map();\n\n this.previousScale = { x: 1, y: 1, z: 1 };\n this.originColor = 'grey';\n this.destinationColor = 'grey';\n\n this.uniforms = {\n uTime: { value: 0 },\n uProgress: { value: 0 },\n uTexture: { value: null },\n uVelocity: { value: null },\n uOriginTexture: { value: null },\n uDestinationTexture: { value: null },\n };\n\n this.matcapMaterial = new THREE.ShaderMaterial({\n uniforms: this.uniforms,\n vertexShader: instanceVertexShader,\n fragmentShader: instanceFragmentShader,\n });\n\n this.setOriginColor(this.originColor);\n this.setDestinationColor(this.destinationColor);\n\n this.fallbackGeometry = new THREE.BoxGeometry(0.001, 0.001, 0.001);\n this.mesh = this.createInstancedMesh(initialSize, this.fallbackGeometry, this.matcapMaterial);\n }\n\n /**\n * Gets the instanced mesh.\n * @returns The instanced mesh.\n */\n getMesh() {\n return this.mesh;\n }\n\n /**\n * Updates the instanced mesh.\n * @param elapsedTime The elapsed time.\n */\n update(elapsedTime: number) {\n const material = this.mesh.material;\n if (material instanceof THREE.ShaderMaterial || material instanceof THREE.RawShaderMaterial) {\n material.uniforms.uTime.value = elapsedTime;\n }\n }\n\n /**\n * Sets the matcap texture.\n * @param matcap The matcap texture to set.\n */\n setOriginMatcap(matcap: THREE.Texture) {\n this.disposeSolidColorOriginTexture();\n this.matcapMaterial.uniforms.uOriginTexture.value = matcap;\n }\n\n setDestinationMatcap(matcap: THREE.Texture) {\n this.disposeSolidColorDestinationTexture();\n this.matcapMaterial.uniforms.uDestinationTexture.value = matcap;\n }\n\n setProgress(float: number) {\n float = Math.max(0, float);\n float = Math.min(1, float);\n this.matcapMaterial.uniforms.uProgress.value = float;\n }\n\n setGeometrySize(size: THREE.Vector3Like) {\n this.mesh.geometry.scale(1 / this.previousScale.x, 1 / this.previousScale.y, 1 / this.previousScale.z);\n this.mesh.geometry.scale(size.x, size.y, size.z);\n this.previousScale = size;\n }\n\n /**\n * Use the matcap material for the instanced mesh.\n */\n useMatcapMaterial() {\n this.mesh.material = this.matcapMaterial;\n }\n\n /**\n * Use the specified geometry for the instanced mesh.\n * @param id The ID of the geometry to use.\n */\n useGeometry(id: string) {\n const geometry = this.geometries.get(id);\n if (geometry) {\n this.mesh.geometry = geometry;\n }\n }\n\n /**\n * Updates the velocity texture.\n * @param texture The velocity texture to update with.\n */\n updateVelocityTexture(texture: THREE.Texture) {\n this.matcapMaterial.uniforms.uVelocity.value = texture;\n }\n\n /**\n * Updates the position texture.\n * @param texture The position texture to update with.\n */\n updatePositionTexture(texture: THREE.Texture) {\n this.matcapMaterial.uniforms.uTexture.value = texture;\n }\n\n /**\n * Resizes or replaces the instanced mesh.\n * @param size The new size of the instanced mesh.\n * @returns An object containing the updated mesh, the previous mesh, and a boolean indicating whether the mesh was updated.\n */\n resize(size: number): { current: THREE.InstancedMesh; previous: THREE.InstancedMesh } {\n if (this.size === size) return { current: this.mesh, previous: this.mesh };\n\n this.size = size;\n\n // create new instances since it is greater than the last known value\n const prev = this.mesh;\n\n this.mesh = this.createInstancedMesh(size, prev.geometry, prev.material);\n\n return { current: this.mesh, previous: prev };\n }\n\n /**\n * Disposes the resources used by the InstancedMeshManager.\n */\n dispose() {\n this.mesh.dispose();\n\n this.geometries.forEach((geometry) => geometry.dispose());\n this.disposeSolidColorOriginTexture();\n this.disposeSolidColorDestinationTexture();\n this.matcapMaterial.dispose();\n\n this.uvRefsCache.clear();\n this.geometries.clear();\n }\n\n /**\n * Registers a geometry.\n * @param id The ID of the geometry to register.\n * @param geometry The geometry to register.\n */\n registerGeometry(id: string, geometry: THREE.BufferGeometry) {\n const previous = this.geometries.get(id);\n\n if (previous) {\n if (previous === geometry) {\n return;\n }\n }\n\n // finally, we are attaching uvRefs.\n const uvRefs = this.createUVRefs(this.size);\n geometry.setAttribute('uvRef', uvRefs);\n\n this.geometries.set(id, geometry);\n\n if (this.mesh.geometry === previous) {\n this.mesh.geometry = geometry;\n }\n\n previous?.dispose();\n }\n\n setOriginColor(color: THREE.ColorRepresentation) {\n this.disposeSolidColorOriginTexture();\n this.originColor = color;\n this.uniforms.uOriginTexture.value = this.createSolidColorDataTexture(color);\n }\n\n setDestinationColor(color: THREE.ColorRepresentation) {\n this.disposeSolidColorDestinationTexture();\n this.destinationColor = color;\n this.uniforms.uDestinationTexture.value = this.createSolidColorDataTexture(color);\n }\n\n /**\n * Gets the UV references for the specified size.\n * @param size The size for which to generate UV references.\n * @returns The UV references.\n */\n private createUVRefs(size: number) {\n const cached = this.uvRefsCache.get(size);\n\n if (cached) {\n return cached;\n }\n\n const uvRefs = new Float32Array(size * size * 2);\n\n for (let i = 0; i < size; i++) {\n for (let j = 0; j < size; j++) {\n const index = i * size + j;\n uvRefs[2 * index] = j / (size - 1);\n uvRefs[2 * index + 1] = i / (size - 1);\n }\n }\n\n const attr = new THREE.InstancedBufferAttribute(uvRefs, 2);\n\n this.uvRefsCache.set(size, attr);\n return attr;\n }\n\n /**\n * Creates a new instanced mesh.\n * @param size The size of the instanced mesh.\n * @param geometry The geometry to use for the instanced mesh.\n * @param material The material to use for the instanced mesh.\n * @returns The created instanced mesh.\n */\n private createInstancedMesh(size: number, geometry: THREE.BufferGeometry, material: THREE.Material | THREE.Material[]) {\n geometry = geometry || this.fallbackGeometry;\n geometry.setAttribute('uvRef', this.createUVRefs(size));\n const count = size * size;\n return new THREE.InstancedMesh(geometry, material, count);\n }\n\n private createSolidColorDataTexture(color: THREE.ColorRepresentation, size: number = 16): THREE.DataTexture {\n const col = new THREE.Color(color);\n const width = size;\n const height = size;\n const data = new Uint8Array(width * height * 4); // RGBA\n\n const r = Math.floor(col.r * 255);\n const g = Math.floor(col.g * 255);\n const b = Math.floor(col.b * 255);\n\n for (let i = 0; i < width * height; i++) {\n const index = i * 4;\n data[index] = r;\n data[index + 1] = g;\n data[index + 2] = b;\n data[index + 3] = 255; // Alpha\n }\n\n const texture = new THREE.DataTexture(data, width, height, THREE.RGBAFormat);\n texture.type = THREE.UnsignedByteType;\n texture.wrapS = THREE.RepeatWrapping; // Or ClampToEdgeWrapping\n texture.wrapT = THREE.RepeatWrapping; // Or ClampToEdgeWrapping\n texture.minFilter = THREE.NearestFilter; // Ensure sharp color\n texture.magFilter = THREE.NearestFilter;\n texture.needsUpdate = true;\n return texture;\n }\n\n private disposeSolidColorOriginTexture() {\n if (this.originColor) {\n this.originColor = null;\n if (this.uniforms.uOriginTexture.value) {\n this.uniforms.uOriginTexture.value.dispose();\n }\n }\n }\n\n private disposeSolidColorDestinationTexture() {\n if (this.destinationColor) {\n this.destinationColor = null;\n if (this.uniforms.uDestinationTexture.value) {\n this.uniforms.uDestinationTexture.value.dispose();\n }\n }\n }\n}\n","export default `\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform sampler2D uVelocity;\nuniform float uTime;\nvarying vec3 vNormal;\nattribute vec2 uvRef;\nvarying vec3 vViewPosition;\n\nvec3 rotate3D(vec3 v, vec3 vel) {\n vec3 pos = v;\n vec3 up = vec3(0, 1, 0);\n vec3 axis = normalize(cross(up, vel));\n float angle = acos(dot(up, normalize(vel)));\n pos = pos * cos(angle) + cross(axis, pos) * sin(angle) + axis * dot(axis, pos) * (1. - cos(angle));\n return pos;\n}\n\nvoid main() {\n vUv = uv;\n vNormal = normal;\n\n vec4 color = texture2D(uTexture, uvRef);\n vec4 velocity = texture2D(uVelocity, uvRef);\n vec3 pos = color.xyz;// apply the texture to the vertex distribution.\n\n vec3 localPosition = position.xyz;\n if (length (velocity.xyz) < 0.0001) {\n velocity.xyz = vec3(0.0, 0.0001, 0.0001);\n }\n localPosition.y *= max(1.0, length(velocity.xyz) * 1000.0);\n localPosition = rotate3D(localPosition, velocity.xyz);\n vNormal = rotate3D(normal, velocity.xyz);\n\n mat4 instanceMat = instanceMatrix;\n instanceMat[3].xyz = pos.xyz;\n\n // unlike the traditional mvMatrix * position, we need to additional multiplication with the instance matrix.\n vec4 modelViewPosition = modelViewMatrix * instanceMat * vec4(localPosition, 1.0);\n\n vViewPosition = - modelViewPosition.xyz;\n\n gl_Position = projectionMatrix * modelViewPosition;\n}\n`;\n","export default `\nvarying vec2 vUv;\nuniform sampler2D uTexture;\n\nuniform sampler2D uOriginTexture;\nuniform sampler2D uDestinationTexture;\n\nuniform float uProgress;\nvarying vec3 vNormal;\nvarying vec3 vViewPosition;\nvoid main() {\n vec3 viewDir = normalize( vViewPosition );\n vec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n vec3 y = cross( viewDir, x );\n vec2 uv = vec2( dot( x, vNormal ), dot( y, vNormal ) ) * 0.495 + 0.5; // 0.495 to remove artifacts caused by undersized matcap disks\n\n vec4 sourceMatcap = texture2D( uOriginTexture, uv );\n vec4 targetMatcap = texture2D( uDestinationTexture, uv );\n\n vec4 matcap = mix(sourceMatcap, targetMatcap, uProgress);\n gl_FragColor = matcap;\n}\n`;\n","import { DefaultEventEmitter, EngineEventEmitter, Events } from '@/lib/events';\nimport * as THREE from 'three';\n\n/**\n * Service for calculating intersections between a ray and a morphed geometry.\n */\nexport class IntersectionService {\n private raycaster = new THREE.Raycaster();\n private mousePosition = new THREE.Vector2();\n\n private camera?: THREE.Camera;\n private originGeometry?: THREE.BufferGeometry;\n private destinationGeometry?: THREE.BufferGeometry;\n\n private progress: number = 0;\n private intersectionMesh = new THREE.Mesh();\n\n private geometryNeedsUpdate: boolean;\n private eventEmitter: EngineEventEmitter<Events>;\n\n private blendedGeometry?: THREE.BufferGeometry;\n private intersection?: THREE.Vector4;\n\n private lastKnownOriginMeshID?: string;\n private lastKnownDestinationMeshID?: string;\n /**\n * Creates a new IntersectionService instance.\n * @param eventEmitter The event emitter used for emitting events.\n * @param camera The camera used for raycasting.\n * @param originGeometry The origin geometry.\n * @param destinationGeometry The destination geometry.\n */\n constructor(eventEmitter: DefaultEventEmitter, camera?: THREE.Camera, originGeometry?: THREE.BufferGeometry, destinationGeometry?: THREE.BufferGeometry) {\n this.camera = camera;\n this.originGeometry = originGeometry;\n this.eventEmitter = eventEmitter;\n this.destinationGeometry = destinationGeometry;\n this.geometryNeedsUpdate = true;\n }\n\n getIntersectionMesh(): THREE.Mesh {\n return this.intersectionMesh;\n }\n\n /**\n * Set the camera used for raycasting.\n * @param camera\n */\n setCamera(camera: THREE.Camera) {\n this.camera = camera;\n }\n\n /**\n * Set the origin geometry.\n * @param source\n */\n setOriginGeometry(source: THREE.Mesh) {\n if (this.lastKnownOriginMeshID === source.uuid) return;\n // dispose the previous geometry\n if (this.originGeometry) this.originGeometry.dispose();\n\n this.lastKnownOriginMeshID = source.uuid;\n // we need to clone the geometry because we are going to modify it.\n this.originGeometry = source.geometry.clone();\n this.originGeometry.applyMatrix4(source.matrixWorld);\n this.geometryNeedsUpdate = true;\n }\n\n /**\n * Set the destination geometry.\n * @param source\n */\n setDestinationGeometry(source: THREE.Mesh) {\n if (this.lastKnownDestinationMeshID === source.uuid) return;\n // dispose the previous geometry\n if (this.destinationGeometry) this.destinationGeometry.dispose();\n\n this.lastKnownDestinationMeshID = source.uuid;\n // we need to clone the geometry because we are going to modify it.\n this.destinationGeometry = source.geometry.clone();\n this.destinationGeometry.applyMatrix4(source.matrixWorld);\n\n this.geometryNeedsUpdate = true;\n }\n\n /**\n * Set the progress of the morphing animation.\n * @param progress\n */\n setProgress(progress: number) {\n this.progress = progress;\n this.geometryNeedsUpdate = true;\n }\n\n /**\n * Set the mouse position.\n * @param mousePosition\n */\n setMousePosition(mousePosition?: THREE.Vector2Like) {\n if (mousePosition) this.mousePosition.copy(mousePosition);\n }\n\n /**\n * Calculate the intersection.\n * @returns The intersection point or undefined if no intersection was found.\n */\n calculate(instancedMesh: THREE.Mesh): THREE.Vector4 | undefined {\n this.updateIntersectionMesh(instancedMesh);\n\n if (!this.camera) return;\n if (this.geometryNeedsUpdate) {\n this.geometryNeedsUpdate = false;\n this.blendedGeometry = this.getBlendedGeometry();\n }\n\n if (this.blendedGeometry) {\n this.intersection = this.getFirstIntersection(this.camera, instancedMesh);\n } else {\n this.intersection = undefined;\n }\n\n if (this.intersection) {\n this.eventEmitter.emit('interactionPositionUpdated', { position: this.intersection });\n } else {\n this.eventEmitter.emit('interactionPositionUpdated', { position: { x: 0, y: 0, z: 0, w: 0 } });\n }\n\n return this.intersection;\n }\n\n /**\n * Dispose the resources used by the IntersectionService.\n */\n dispose() {\n this.blendedGeometry?.dispose();\n this.intersectionMesh.geometry.dispose();\n }\n\n private updateIntersectionMesh(instancedMesh: THREE.Mesh) {\n if (this.blendedGeometry) {\n if (this.blendedGeometry.uuid !== this.intersectionMesh.geometry.uuid) {\n this.intersectionMesh.geometry.dispose();\n this.intersectionMesh.geometry = this.blendedGeometry;\n }\n }\n this.intersectionMesh.matrix.copy(instancedMesh.matrixWorld);\n this.intersectionMesh.matrixWorld.copy(instancedMesh.matrixWorld);\n this.intersectionMesh.matrixAutoUpdate = false;\n this.intersectionMesh.updateMatrixWorld(true);\n }\n\n private getFirstIntersection(camera: THREE.Camera, instancedMesh: THREE.Mesh) {\n this.raycaster.setFromCamera(this.mousePosition, camera);\n\n const intersection = this.raycaster.intersectObject(this.intersectionMesh, false)[0];\n if (intersection) {\n const worldPoint = intersection.point.clone();\n const localPoint = instancedMesh.worldToLocal(worldPoint);\n return new THREE.Vector4(localPoint.x, localPoint.y, localPoint.z, 1);\n }\n }\n\n private getBlendedGeometry() {\n if (this.progress === 0) {\n return this.originGeometry;\n }\n if (this.progress === 1) {\n return this.destinationGeometry;\n }\n\n if (!this.originGeometry || !this.destinationGeometry) {\n return;\n }\n\n if (this.originGeometry === this.destinationGeometry) {\n // if same, just return one of them\n return this.originGeometry;\n }\n\n return this.blendGeometry(this.originGeometry, this.destinationGeometry, this.progress);\n }\n\n private blendGeometry(from: THREE.BufferGeometry, to: THREE.BufferGeometry, progress: number): THREE.BufferGeometry {\n const blended = new THREE.BufferGeometry();\n const originPositions = from.attributes.position.array;\n const destinationPositions = to.attributes.position.array;\n const blendedPositions = new Float32Array(originPositions.length);\n\n for (let i = 0; i < originPositions.length; i += 3) {\n const originVert = new THREE.Vector3(originPositions[i], originPositions[i + 1], originPositions[i + 2]);\n const destinationVert = new THREE.Vector3(destinationPositions[i], destinationPositions[i + 1], destinationPositions[i + 2]);\n const blendedVert = new THREE.Vector3().lerpVectors(originVert, destinationVert, progress);\n\n blendedPositions[i] = blendedVert.x;\n blendedPositions[i + 1] = blendedVert.y;\n blendedPositions[i + 2] = blendedVert.z;\n }\n\n blended.setAttribute('position', new THREE.BufferAttribute(blendedPositions, 3));\n\n if (from.attributes.normal) blended.setAttribute('normal', from.attributes.normal.clone());\n if (from.attributes.uv) blended.setAttribute('uv', from.attributes.uv.clone());\n if (from.index) blended.setIndex(from.index.clone());\n\n return blended;\n }\n}\n","import {\n\tBufferGeometry,\n\tFloat32BufferAttribute,\n\tOrthographicCamera,\n\tMesh\n} from 'three';\n\nclass Pass {\n\n\tconstructor() {\n\n\t\tthis.isPass = true;\n\n\t\t// if set to true, the pass is processed by the composer\n\t\tthis.enabled = true;\n\n\t\t// if set to true, the pass indicates to swap read and write buffer after rendering\n\t\tthis.needsSwap = true;\n\n\t\t// if set to true, the pass clears its buffer before rendering\n\t\tthis.clear = false;\n\n\t\t// if set to true, the result of the pass is rendered to screen. This is set automatically by EffectComposer.\n\t\tthis.renderToScreen = false;\n\n\t}\n\n\tsetSize( /* width, height */ ) {}\n\n\trender( /* renderer, writeBuffer, readBuffer, deltaTime, maskActive */ ) {\n\n\t\tconsole.error( 'THREE.Pass: .render() must be implemented in derived pass.' );\n\n\t}\n\n\tdispose() {}\n\n}\n\n// Helper for passes that need to fill the viewport with a single quad.\n\nconst _camera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );\n\n// https://github.com/mrdoob/three.js/pull/21358\n\nclass FullscreenTriangleGeometry extends BufferGeometry {\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\tthis.setAttribute( 'position', new Float32BufferAttribute( [ - 1, 3, 0, - 1, - 1, 0, 3, - 1, 0 ], 3 ) );\n\t\tthis.setAttribute( 'uv', new Float32BufferAttribute( [ 0, 2, 0, 0, 2, 0 ], 2 ) );\n\n\t}\n\n}\n\nconst _geometry = new FullscreenTriangleGeometry();\n\nclass FullScreenQuad {\n\n\tconstructor( material ) {\n\n\t\tthis._mesh = new Mesh( _geometry, material );\n\n\t}\n\n\tdispose() {\n\n\t\tthis._mesh.geometry.dispose();\n\n\t}\n\n\trender( renderer ) {\n\n\t\trenderer.render( this._mesh, _camera );\n\n\t}\n\n\tget material() {\n\n\t\treturn this._mesh.material;\n\n\t}\n\n\tset material( value ) {\n\n\t\tthis._mesh.material = value;\n\n\t}\n\n}\n\nexport { Pass, FullScreenQuad };\n","import {\n\tClampToEdgeWrapping,\n\tDataTexture,\n\tFloatType,\n\tNearestFilter,\n\tRGBAFormat,\n\tShaderMaterial,\n\tWebGLRenderTarget\n} from 'three';\n\nimport { FullScreenQuad } from '../postprocessing/Pass.js';\n\n/**\n * GPUComputationRenderer, based on SimulationRenderer by zz85\n *\n * The GPUComputationRenderer uses the concept of variables. These variables are RGBA float textures that hold 4 floats\n * for each compute element (texel)\n *\n * Each variable has a fragment shader that defines the computation made to obtain the variable in question.\n * You can use as many variables you need, and make dependencies so you can use textures of other variables in the shader\n * (the sampler uniforms are added automatically) Most of the variables will need themselves as dependency.\n *\n * The renderer has actually two render targets per variable, to make ping-pong. Textures from the current frame are used\n * as inputs to render the textures of the next frame.\n *\n * The render targets of the variables can be used as input textures for your visualization shaders.\n *\n * Variable names should be valid identifiers and should not collide with THREE GLSL used identifiers.\n * a common approach could be to use 'texture' prefixing the variable name; i.e texturePosition, textureVelocity...\n *\n * The size of the computation (sizeX * sizeY) is defined as 'resolution' automatically in the shader. For example:\n * #DEFINE resolution vec2( 1024.0, 1024.0 )\n *\n * -------------\n *\n * Basic use:\n *\n * // Initialization...\n *\n * // Create computation renderer\n * const gpuCompute = new GPUComputationRenderer( 1024, 1024, renderer );\n *\n * // Create initial state float textures\n * const pos0 = gpuCompute.createTexture();\n * const vel0 = gpuCompute.createTexture();\n * // and fill in here the texture data...\n *\n * // Add texture variables\n * const velVar = gpuCompute.addVariable( \"textureVelocity\", fragmentShaderVel, vel0 );\n * const posVar = gpuCompute.addVariable( \"texturePosition\", fragmentShaderPos, pos0 );\n *\n * // Add variable dependencies\n * gpuCompute.setVariableDependencies( velVar, [ velVar, posVar ] );\n * gpuCompute.setVariableDependencies( posVar, [ velVar, posVar ] );\n *\n * // Add custom uniforms\n * velVar.material.uniforms.time = { value: 0.0 };\n *\n * // Check for completeness\n * const error = gpuCompute.init();\n * if ( error !== null ) {\n *\t\tconsole.error( error );\n * }\n *\n *\n * // In each frame...\n *\n * // Compute!\n * gpuCompute.compute();\n *\n * // Update texture uniforms in your visualization materials with the gpu renderer output\n * myMaterial.uniforms.myTexture.value = gpuCompute.getCurrentRenderTarget( posVar ).texture;\n *\n * // Do your rendering\n * renderer.render( myScene, myCamera );\n *\n * -------------\n *\n * Also, you can use utility functions to create ShaderMaterial and perform computations (rendering between textures)\n * Note that the shaders can have multiple input textures.\n *\n * const myFilter1 = gpuCompute.createShaderMaterial( myFilterFragmentShader1, { theTexture: { value: null } } );\n * const myFilter2 = gpuCompute.createShaderMaterial( myFilterFragmentShader2, { theTexture: { value: null } } );\n *\n * const inputTexture = gpuCompute.createTexture();\n *\n * // Fill in here inputTexture...\n *\n * myFilter1.uniforms.theTexture.value = inputTexture;\n *\n * const myRenderTarget = gpuCompute.createRenderTarget();\n * myFilter2.uniforms.theTexture.value = myRenderTarget.texture;\n *\n * const outputRenderTarget = gpuCompute.createRenderTarget();\n *\n * // Now use the output texture where you want:\n * myMaterial.uniforms.map.value = outputRenderTarget.texture;\n *\n * // And compute each frame, before rendering to screen:\n * gpuCompute.doRenderTarget( myFilter1, myRenderTarget );\n * gpuCompute.doRenderTarget( myFilter2, outputRenderTarget );\n */\n\nclass GPUComputationRenderer {\n\n\t/**\n\t * @param {Number} sizeX Computation problem size is always 2d: sizeX * sizeY elements.\n \t * @param {Number} sizeY Computation problem size is always 2d: sizeX * sizeY elements.\n \t * @param {WebGLRenderer} renderer The renderer\n\t */\n\tconstructor( sizeX, sizeY, renderer ) {\n\n\t\tthis.variables = [];\n\n\t\tthis.currentTextureIndex = 0;\n\n\t\tlet dataType = FloatType;\n\n\t\tconst passThruUniforms = {\n\t\t\tpassThruTexture: { value: null }\n\t\t};\n\n\t\tconst passThruShader = createShaderMaterial( getPassThroughFragmentShader(), passThruUniforms );\n\n\t\tconst quad = new FullScreenQuad( passThruShader );\n\n\t\tthis.setDataType = function ( type ) {\n\n\t\t\tdataType = type;\n\t\t\treturn this;\n\n\t\t};\n\n\t\tthis.addVariable = function ( variableName, computeFragmentShader, initialValueTexture ) {\n\n\t\t\tconst material = this.createShaderMaterial( computeFragmentShader );\n\n\t\t\tconst variable = {\n\t\t\t\tname: variableName,\n\t\t\t\tinitialValueTexture: initialValueTexture,\n\t\t\t\tmaterial: material,\n\t\t\t\tdependencies: null,\n\t\t\t\trenderTargets: [],\n\t\t\t\twrapS: null,\n\t\t\t\twrapT: null,\n\t\t\t\tminFilter: NearestFilter,\n\t\t\t\tmagFilter: NearestFilter\n\t\t\t};\n\n\t\t\tthis.variables.push( variable );\n\n\t\t\treturn variable;\n\n\t\t};\n\n\t\tthis.setVariableDependencies = function ( variable, dependencies ) {\n\n\t\t\tvariable.dependencies = dependencies;\n\n\t\t};\n\n\t\tthis.init = function () {\n\n\t\t\tif ( renderer.capabilities.maxVertexTextures === 0 ) {\n\n\t\t\t\treturn 'No support for vertex shader textures.';\n\n\t\t\t}\n\n\t\t\tfor ( let i = 0; i < this.variables.length; i ++ ) {\n\n\t\t\t\tconst variable = this.variables[ i ];\n\n\t\t\t\t// Creates rendertargets and initialize them with input texture\n\t\t\t\tvariable.renderTargets[ 0 ] = this.createRenderTarget( sizeX, sizeY, variable.wrapS, variable.wrapT, variable.minFilter, variable.magFilter );\n\t\t\t\tvariable.renderTargets[ 1 ] = this.createRenderTarget( sizeX, sizeY, variable.wrapS, variable.wrapT, variable.minFilter, variable.magFilter );\n\t\t\t\tthis.renderTexture( variable.initialValueTexture, variable.renderTargets[ 0 ] );\n\t\t\t\tthis.renderTexture( variable.initialValueTexture, variable.renderTargets[ 1 ] );\n\n\t\t\t\t// Adds dependencies uniforms to the ShaderMaterial\n\t\t\t\tconst material = variable.material;\n\t\t\t\tconst uniforms = material.uniforms;\n\n\t\t\t\tif ( variable.dependencies !== null ) {\n\n\t\t\t\t\tfor ( let d = 0; d < variable.dependencies.length; d ++ ) {\n\n\t\t\t\t\t\tconst depVar = variable.dependencies[ d ];\n\n\t\t\t\t\t\tif ( depVar.name !== variable.name ) {\n\n\t\t\t\t\t\t\t// Checks if variable exists\n\t\t\t\t\t\t\tlet found = false;\n\n\t\t\t\t\t\t\tfor ( let j = 0; j < this.variables.length; j ++ ) {\n\n\t\t\t\t\t\t\t\tif ( depVar.name === this.variables[ j ].name ) {\n\n\t\t\t\t\t\t\t\t\tfound = true;\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( ! found ) {\n\n\t\t\t\t\t\t\t\treturn 'Variable dependency not found. Variable=' + variable.name + ', dependency=' + depVar.name;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tuniforms[ depVar.name ] = { value: null };\n\n\t\t\t\t\t\tmaterial.fragmentShader = '\\nuniform sampler2D ' + depVar.name + ';\\n' + material.fragmentShader;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.currentTextureIndex = 0;\n\n\t\t\treturn null;\n\n\t\t};\n\n\t\tthis.compute = function () {\n\n\t\t\tconst currentTextureIndex = this.currentTextureIndex;\n\t\t\tconst nextTextureIndex = this.currentTextureIndex === 0 ? 1 : 0;\n\n\t\t\tfor ( let i = 0, il = this.variables.length; i < il; i ++ ) {\n\n\t\t\t\tconst variable = this.variables[ i ];\n\n\t\t\t\t// Sets texture dependencies uniforms\n\t\t\t\tif ( variable.dependencies !== null ) {\n\n\t\t\t\t\tconst uniforms = variable.material.uniforms;\n\n\t\t\t\t\tfor ( let d = 0, dl = variable.dependencies.length; d < dl; d ++ ) {\n\n\t\t\t\t\t\tconst depVar = variable.dependencies[ d ];\n\n\t\t\t\t\t\tuniforms[ depVar.name ].value = depVar.renderTargets[ currentTextureIndex ].texture;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// Performs the computation for this variable\n\t\t\t\tthis.doRenderTarget( variable.material, variable.renderTargets[ nextTextureIndex ] );\n\n\t\t\t}\n\n\t\t\tthis.currentTextureIndex = nextTextureIndex;\n\n\t\t};\n\n\t\tthis.getCurrentRenderTarget = function ( variable ) {\n\n\t\t\treturn variable.renderTargets[ this.currentTextureIndex ];\n\n\t\t};\n\n\t\tthis.getAlternateRenderTarget = function ( variable ) {\n\n\t\t\treturn variable.renderTargets[ this.currentTextureIndex === 0 ? 1 : 0 ];\n\n\t\t};\n\n\t\tthis.dispose = function () {\n\n\t\t\tquad.dispose();\n\n\t\t\tconst variables = this.variables;\n\n\t\t\tfor ( let i = 0; i < variables.length; i ++ ) {\n\n\t\t\t\tconst variable = variables[ i ];\n\n\t\t\t\tif ( variable.initialValueTexture ) variable.initialValueTexture.dispose();\n\n\t\t\t\tconst renderTargets = variable.renderTargets;\n\n\t\t\t\tfor ( let j = 0; j < renderTargets.length; j ++ ) {\n\n\t\t\t\t\tconst renderTarget = renderTargets[ j ];\n\t\t\t\t\trenderTarget.dispose();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\tfunction addResolutionDefine( materialShader ) {\n\n\t\t\tmaterialShader.defines.resolution = 'vec2( ' + sizeX.toFixed( 1 ) + ', ' + sizeY.toFixed( 1 ) + ' )';\n\n\t\t}\n\n\t\tthis.addResolutionDefine = addResolutionDefine;\n\n\n\t\t// The following functions can be used to compute things manually\n\n\t\tfunction createShaderMaterial( computeFragmentShader, uniforms ) {\n\n\t\t\tuniforms = uniforms || {};\n\n\t\t\tconst material = new ShaderMaterial( {\n\t\t\t\tname: 'GPUComputationShader',\n\t\t\t\tuniforms: uniforms,\n\t\t\t\tvertexShader: getPassThroughVertexShader(),\n\t\t\t\tfragmentShader: computeFragmentShader\n\t\t\t} );\n\n\t\t\taddResolutionDefine( material );\n\n\t\t\treturn material;\n\n\t\t}\n\n\t\tthis.createShaderMaterial = createShaderMaterial;\n\n\t\tthis.createRenderTarget = function ( sizeXTexture, sizeYTexture, wrapS, wrapT, minFilter, magFilter ) {\n\n\t\t\tsizeXTexture = sizeXTexture || sizeX;\n\t\t\tsizeYTexture = sizeYTexture || sizeY;\n\n\t\t\twrapS = wrapS || ClampToEdgeWrapping;\n\t\t\twrapT = wrapT || ClampToEdgeWrapping;\n\n\t\t\tminFilter = minFilter || NearestFilter;\n\t\t\tmagFilter = magFilter || NearestFilter;\n\n\t\t\tconst renderTarget = new WebGLRenderTarget( sizeXTexture, sizeYTexture, {\n\t\t\t\twrapS: wrapS,\n\t\t\t\twrapT: wrapT,\n\t\t\t\tminFilter: minFilter,\n\t\t\t\tmagFilter: magFilter,\n\t\t\t\tformat: RGBAFormat,\n\t\t\t\ttype: dataType,\n\t\t\t\tdepthBuffer: false\n\t\t\t} );\n\n\t\t\treturn renderTarget;\n\n\t\t};\n\n\t\tthis.createTexture = function () {\n\n\t\t\tconst data = new Float32Array( sizeX * sizeY * 4 );\n\t\t\tconst texture = new DataTexture( data, sizeX, sizeY, RGBAFormat, FloatType );\n\t\t\ttexture.needsUpdate = true;\n\t\t\treturn texture;\n\n\t\t};\n\n\t\tthis.renderTexture = function ( input, output ) {\n\n\t\t\t// Takes a texture, and render out in rendertarget\n\t\t\t// input = Texture\n\t\t\t// output = RenderTarget\n\n\t\t\tpassThruUniforms.passThruTexture.value = input;\n\n\t\t\tthis.doRenderTarget( passThruShader, output );\n\n\t\t\tpassThruUniforms.passThruTexture.value = null;\n\n\t\t};\n\n\t\tthis.doRenderTarget = function ( material, output ) {\n\n\t\t\tconst currentRenderTarget = renderer.getRenderTarget();\n\n\t\t\tconst currentXrEnabled = renderer.xr.enabled;\n\t\t\tconst currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;\n\n\t\t\trenderer.xr.enabled = false; // Avoid camera modification\n\t\t\trenderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows\n\t\t\tquad.material = material;\n\t\t\trenderer.setRenderTarget( output );\n\t\t\tquad.render( renderer );\n\t\t\tquad.material = passThruShader;\n\n\t\t\trenderer.xr.enabled = currentXrEnabled;\n\t\t\trenderer.shadowMap.autoUpdate = currentShadowAutoUpdate;\n\n\t\t\trenderer.setRenderTarget( currentRenderTarget );\n\n\t\t};\n\n\t\t// Shaders\n\n\t\tfunction getPassThroughVertexShader() {\n\n\t\t\treturn\t'void main()\t{\\n' +\n\t\t\t\t\t'\\n' +\n\t\t\t\t\t'\tgl_Position = vec4( position, 1.0 );\\n' +\n\t\t\t\t\t'\\n' +\n\t\t\t\t\t'}\\n';\n\n\t\t}\n\n\t\tfunction getPassThroughFragmentShader() {\n\n\t\t\treturn\t'uniform sampler2D passThruTexture;\\n' +\n\t\t\t\t\t'\\n' +\n\t\t\t\t\t'void main() {\\n' +\n\t\t\t\t\t'\\n' +\n\t\t\t\t\t'\tvec2 uv = gl_FragCoord.xy / resolution.xy;\\n' +\n\t\t\t\t\t'\\n' +\n\t\t\t\t\t'\tgl_FragColor = texture2D( passThruTexture, uv );\\n' +\n\t\t\t\t\t'\\n' +\n\t\t\t\t\t'}\\n';\n\n\t\t}\n\n\t}\n\n}\n\nexport { GPUComputationRenderer };\n","import { clamp, createBlankDataTexture, createSpherePoints } from '@/lib/utils';\nimport * as THREE from 'three';\nimport { GPUComputationRenderer, Variable } from 'three/examples/jsm/misc/GPUComputationRenderer.js';\nimport mixShader from './shaders/simulationMixShader';\nimport positionShader from './shaders/simulationPositionShader';\nimport velocityShader from './shaders/simulationVelocityShader';\n\n/**\n * SimulationRenderer is responsible for running the particle simulation using the GPU.\n */\nexport class SimulationRenderer {\n gpuComputationRenderer: GPUComputationRenderer;\n webGLRenderer: THREE.WebGLRenderer;\n\n // calculations\n private readonly positionDataTexture: THREE.DataTexture;\n private readonly velocityDataTexture: THREE.DataTexture;\n\n // GPUComputationRenderer variables\n private readonly mixPositionsVar: Variable;\n private readonly velocityVar: Variable;\n private readonly positionVar: Variable;\n\n readonly interactionPosition: THREE.Vector4;\n\n private lastKnownPositionDataTexture: THREE.Texture;\n private lastKnownVelocityDataTexture: THREE.Texture;\n private lastKnownMixProgress: number;\n\n private readonly initialDataTexture: THREE.DataTexture;\n\n /**\n * Creates a new SimulationRenderer instance.\n * @param size The size of the simulation textures.\n * @param webGLRenderer The WebGL renderer.\n * @param initialPosition The initial position data texture. If not provided, a default sphere will be used.\n */\n constructor(size: number, webGLRenderer: THREE.WebGLRenderer, initialPosition?: THREE.DataTexture) {\n this.initialDataTexture = initialPosition ?? createSpherePoints(size);\n this.positionDataTexture = this.initialDataTexture;\n\n this.webGLRenderer = webGLRenderer;\n this.gpuComputationRenderer = new GPUComputationRenderer(size, size, this.webGLRenderer);\n this.lastKnownMixProgress = 0;\n\n if (!webGLRenderer.capabilities.isWebGL2) {\n this.gpuComputationRenderer.setDataType(THREE.HalfFloatType);\n }\n\n this.velocityDataTexture = createBlankDataTexture(size);\n this.interactionPosition = new THREE.Vector4(0, 0, 0, 0);\n\n // init gpgpu render target textures.\n this.mixPositionsVar = this.gpuComputationRenderer.addVariable('uMixedPosition', mixShader, this.positionDataTexture);\n this.velocityVar = this.gpuComputationRenderer.addVariable('uCurrentVelocity', velocityShader, this.velocityDataTexture);\n this.positionVar = this.gpuComputationRenderer.addVariable('uCurrentPosition', positionShader, this.positionDataTexture);\n\n // attach uniforms\n this.mixPositionsVar.material.uniforms.uProgress = { value: 0 };\n this.mixPositionsVar.material.uniforms.uPositionA = { value: this.initialDataTexture };\n this.mixPositionsVar.material.uniforms.uPositionB = { value: this.initialDataTexture };\n\n this.velocityVar.material.uniforms.uTime = { value: 0 };\n this.velocityVar.material.uniforms.uInteractionPosition = { value: this.interactionPosition };\n this.velocityVar.material.uniforms.uCurrentPosition = { value: this.positionDataTexture };\n this.velocityVar.material.uniforms.uTractionForce = { value: 0.1 };\n this.velocityVar.material.uniforms.uMaxRepelDistance = { value: 0.3 };\n\n this.positionVar.material.uniforms.uTime = { value: 0 };\n this.positionVar.material.uniforms.uProgress = { value: 0 };\n this.positionVar.material.uniforms.uTractionForce = { value: 0.1 };\n this.positionVar.material.uniforms.uInteractionPosition = { value: this.interactionPosition };\n this.positionVar.material.uniforms.uCurrentPosition = { value: this.positionDataTexture };\n\n this.gpuComputationRenderer.setVariableDependencies(this.positionVar, [this.velocityVar, this.positionVar, this.mixPositionsVar]);\n this.gpuComputationRenderer.setVariableDependencies(this.velocityVar, [this.velocityVar, this.positionVar, this.mixPositionsVar]);\n\n const err = this.gpuComputationRenderer.init();\n if (err) {\n throw new Error('failed to initialize SimulationRenderer: ' + err);\n }\n\n this.lastKnownVelocityDataTexture = this.getVelocityTexture();\n this.lastKnownPositionDataTexture = this.getPositionTexture();\n }\n\n /**\n * Sets the source data texture for morphing.\n * @param texture The source data texture.\n */\n setMorphSourceDataTexture(texture: THREE.DataTexture) {\n this.mixPositionsVar.material.uniforms.uPositionA.value = texture;\n }\n\n /**\n * Sets the destination data texture for morphing.\n * @param texture The destination data texture.\n */\n setMorphDestinationDataTexture(texture: THREE.DataTexture) {\n this.mixPositionsVar.material.uniforms.uPositionB.value = texture;\n }\n\n setMaxRepelDistance(distance: number) {\n this.velocityVar.material.uniforms.uMaxRepelDistance.value = distance;\n }\n\n /**\n * Sets the progress of the morphing animation.\n * @param progress The progress value, between 0 and 1.\n */\n setProgress(progress: number) {\n this.lastKnownMixProgress = clamp(progress, 0, 1);\n this.mixPositionsVar.material.uniforms.uProgress.value = this.lastKnownMixProgress;\n }\n\n setVelocityTractionForce(force: number) {\n this.velocityVar.material.uniforms.uTractionForce.value = force;\n }\n\n setPositionalTractionForce(force: number) {\n this.positionVar.material.uniforms.uTractionForce.value = force;\n }\n\n setInteractionPosition(position: THREE.Vector4Like) {\n this.interactionPosition.copy(position);\n }\n\n /**\n * Disposes the resources used by the simulation renderer.\n */\n dispose() {\n this.mixPositionsVar.renderTargets.forEach((rtt) => rtt.dispose());\n this.positionVar.renderTargets.forEach((rtt) => rtt.dispose());\n this.velocityVar.renderTargets.forEach((rtt) => rtt.dispose());\n\n this.positionDataTexture.dispose();\n this.velocityDataTexture.dispose();\n\n this.gpuComputationRenderer.dispose();\n }\n\n /**\n * Computes the next step of the simulation.\n * @param elapsedTime The elapsed time since the simulation started.\n */\n compute(elapsedTime: number) {\n this.velocityVar.material.uniforms.uTime.value = elapsedTime;\n this.positionVar.material.uniforms.uTime.value = elapsedTime;\n this.gpuComputationRenderer.compute();\n }\n\n /**\n * Gets the current velocity texture.\n * @returns The current velocity texture.\n */\n getVelocityTexture(): THREE.Texture {\n this.lastKnownVelocityDataTexture = this.gpuComputationRenderer.getCurrentRenderTarget(this.velocityVar).texture;\n return this.lastKnownVelocityDataTexture;\n }\n\n /**\n * Gets the current position texture.\n * @returns The current position texture.\n */\n getPositionTexture(): THREE.Texture {\n this.lastKnownPositionDataTexture = this.gpuComputationRenderer.getCurrentRenderTarget(this.positionVar).texture;\n return this.lastKnownPositionDataTexture;\n }\n}\n","export default `\nuniform sampler2D uPositionA;\nuniform sampler2D uPositionB;\nuniform float uProgress;\n\nvoid main() {\n vec2 uv = gl_FragCoord.xy / resolution.xy;\n vec3 positionA = texture2D(uPositionA, uv).xyz;\n vec3 positionB = texture2D(uPositionB, uv).xyz;\n vec3 mixedPosition = mix(positionA, positionB, uProgress);\n gl_FragColor = vec4(mixedPosition, 1.0);\n}\n`;\n","export default `\nuniform float uProgress;\nuniform vec4 uInteractionPosition;\nuniform float uTime;\nuniform float uTractionForce;\nuniform float uMaxRepelDistance;\n\nfloat rand(vec2 co) {\n return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453);\n}\n\nvoid main() {\n vec2 uv = gl_FragCoord.xy / resolution.xy;\n float offset = rand(uv);\n\n vec3 position = texture2D(uCurrentPosition, uv).xyz;\n vec3 velocity = texture2D(uCurrentVelocity, uv).xyz;\n vec3 mixedPosition = texture2D(uMixedPosition, uv).xyz;\n\n velocity *= 0.9;\n\n // particle traction\n vec3 direction = normalize(mixedPosition - position); // direction vector\n float dist = length ( mixedPosition - position ); // distance from where it was supposed to be, and currently are.\n if (dist > 0.01) {\n position += direction * 0.1 * uTractionForce; // uTractionForce defaults to 0.1\n }\n\n // mouse repel force\n float pointerDistance = distance(position, uInteractionPosition.xyz);\n float mouseRepelModifier = clamp(uMaxRepelDistance - pointerDistance, 0.0, 1.0);\n float normalizedDistance = pointerDistance / uMaxRepelDistance;\n float repulsionStrength = (1.0 - normalizedDistance) * uInteractionPosition.w;\n direction = normalize(position - uInteractionPosition.xyz);\n velocity += (direction * 0.01 * repulsionStrength) * mouseRepelModifier;\n\n float lifespan = 20.0;\n float age = mod(uTime + lifespan * offset, lifespan);\n\n if (age < 0.1) {\n position.xyz = mixedPosition;\n }\n\n gl_FragColor = vec4(velocity, 1.0);\n}\n`;\n","export default `\nuniform float uProgress;\nuniform vec4 uInteractionPosition;\nuniform float uTime;\nuniform float uTractionForce;\n\nfloat rand(vec2 co) {\n return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453);\n}\n\nvoid main() {\n\n // in GPGPU, we calculate the uv on each fragment shader, not using the static varying passed over from the v shader.\n vec2 uv = gl_FragCoord.xy / resolution.xy;\n float offset = rand(uv);\n\n vec3 position = texture2D(uCurrentPosition, uv).xyz;\n vec3 velocity = texture2D(uCurrentVelocity, uv).xyz;\n vec3 mixedPosition = texture2D(uMixedPosition, uv).xyz;\n\n // particle attraction to original position.\n vec3 direction = normalize(mixedPosition - position); // direction vector\n float dist = length ( mixedPosition - position ); // distance from where it was supposed to be, and currently are.\n\n if (dist > 0.01) {\n position = mix(position, mixedPosition, 0.1 * uTractionForce); // 0.1 ~ 0.001 (faster, slower)\n }\n\n position += velocity;\n gl_FragColor = vec4(position, 1.0);\n}\n`;\n","import { DefaultEventEmitter } from '@/lib/events';\nimport { DataTextureEntry, ServiceState } from '@/lib/types';\nimport * as THREE from 'three';\nimport { SimulationRenderer } from './simulationRenderer';\n\nexport class SimulationRendererService {\n private state!: ServiceState;\n private textureSize: number;\n private dataTextureTransitionProgress: number;\n private velocityTractionForce: number;\n private positionalTractionForce: number;\n\n private simulationRenderer;\n private webGLRenderer;\n private eventEmitter;\n\n private lastKnownVelocityDataTexture: THREE.Texture;\n private lastKnownPositionDataTexture: THREE.Texture;\n\n constructor(eventEmitter: DefaultEventEmitter, size: number, webGLRenderer: THREE.WebGLRenderer) {\n this.eventEmitter = eventEmitter;\n this.webGLRenderer = webGLRenderer;\n this.textureSize = size;\n this.dataTextureTransitionProgress = 0;\n this.velocityTractionForce = 0.1;\n this.positionalTractionForce = 0.1;\n\n this.updateServiceState('initializing');\n\n this.simulationRenderer = new SimulationRenderer(this.textureSize, this.webGLRenderer);\n this.lastKnownVelocityDataTexture = this.simulationRenderer.getVelocityTexture();\n this.lastKnownPositionDataTexture = this.simulationRenderer.getPositionTexture();\n\n this.updateServiceState('ready');\n }\n\n setTextureSize(size: number) {\n this.updateServiceState('initializing');\n this.simulationRenderer.dispose();\n this.textureSize = size;\n this.simulationRenderer = new SimulationRenderer(size, this.webGLRenderer);\n this.updateServiceState('ready');\n }\n\n setOriginDataTexture(entry: DataTextureEntry) {\n if (this.textureSize !== entry.textureSize) {\n this.eventEmitter.emit('invalidRequest', { message: `Texture size mismatch: ${entry.textureSize} vs ${this.textureSize}` });\n } else {\n this.simulationRenderer.setMorphSourceDataTexture(entry.dataTexture);\n }\n }\n\n setDestinationDataTexture(entry: DataTextureEntry) {\n if (this.textureSize !== entry.textureSize) {\n this.eventEmitter.emit('invalidRequest', { message: `Texture size mismatch: ${entry.textureSize} vs ${this.textureSize}` });\n } else {\n this.simulationRenderer.setMorphDestinationDataTexture(entry.dataTexture);\n }\n }\n\n setDataTextureTransitionProgress(progress: number) {\n this.dataTextureTransitionProgress = progress;\n this.simulationRenderer.setProgress(this.dataTextureTransitionProgress);\n }\n\n setVelocityTractionForce(force: number) {\n this.velocityTractionForce = force;\n this.simulationRenderer.setVelocityTractionForce(this.velocityTractionForce);\n }\n\n setPositionalTractionForce(force: number) {\n this.positionalTractionForce = force;\n this.simulationRenderer.setPositionalTractionForce(this.positionalTractionForce);\n }\n\n compute(elapsedTime: number) {\n this.simulationRenderer.compute(elapsedTime);\n }\n\n getVelocityTexture(): THREE.Texture {\n if (this.state === 'ready') this.lastKnownVelocityDataTexture = this.simulationRenderer.getVelocityTexture();\n return this.lastKnownVelocityDataTexture;\n }\n\n getPositionTexture(): THREE.Texture {\n if (this.state === 'ready') this.lastKnownPositionDataTexture = this.simulationRenderer.getPositionTexture();\n return this.lastKnownPositionDataTexture;\n }\n\n dispose() {\n this.updateServiceState('disposed');\n this.simulationRenderer.dispose();\n this.lastKnownVelocityDataTexture.dispose();\n this.lastKnownPositionDataTexture.dispose();\n }\n\n private updateServiceState(serviceState: ServiceState) {\n this.state = serviceState;\n this.eventEmitter.emit('serviceStateUpdated', { type: 'simulation', state: serviceState });\n }\n\n setInteractionPosition(position: THREE.Vector4Like) {\n this.simulationRenderer.setInteractionPosition(position);\n }\n\n setMaxRepelDistance(distance: number) {\n this.simulationRenderer.setMaxRepelDistance(distance);\n }\n}\n","import { DefaultEventEmitter } from '@/lib/events';\nimport { TransitionDetail, TransitionOptions, TransitionType } from '@/lib/types';\nimport { clamp } from '@/lib/utils';\n\ntype ExecStatus = 'idle' | 'running';\n\ntype TransitionQueueItem = { cancelled: boolean; startTime?: number } & TransitionDetail & TransitionOptions;\ntype OngoingTransition = { startTime: number } & TransitionQueueItem;\n\nclass ExecutionStatusMap {\n private readonly execStatus = new Map<TransitionType, ExecStatus>();\n\n get(type: TransitionType): ExecStatus {\n const status = this.execStatus.get(type);\n if (!status) {\n this.execStatus.set(type, 'idle');\n return 'idle';\n }\n return status;\n }\n\n set(type: TransitionType, status: ExecStatus) {\n this.execStatus.set(type, status);\n }\n}\n\nexport class TransitionService {\n private readonly eventEmitter;\n private readonly transitions: Map<TransitionType, Array<TransitionQueueItem>> = new Map();\n private readonly execStatus: ExecutionStatusMap;\n private readonly ongoingTransitions: Map<TransitionType, OngoingTransition> = new Map();\n\n constructor(eventEmitter: DefaultEventEmitter) {\n this.eventEmitter = eventEmitter;\n this.execStatus = new ExecutionStatusMap();\n this.eventEmitter.on('transitionCancelled', this.handleTransitionCancelledEvent.bind(this));\n }\n\n /**\n * Enqueues a transition.\n * @param type - The type of transition.\n * @param transition - The transition details.\n * @param options - Optional transition options.\n */\n enqueue<T extends TransitionType>(type: T, transition: TransitionDetail, options: TransitionOptions = {}) {\n const transitionQueueItem: TransitionQueueItem = {\n ...transition,\n ...options,\n cancelled: false,\n duration: transition.duration * 0.001, // convert to seconds\n };\n this.getQueue(type).push(transitionQueueItem);\n }\n\n compute(elapsedTime: number) {\n this.transitions.forEach((queue, type) => {\n if (queue.length && !this.ongoingTransitions.has(type)) {\n const transition = queue.shift();\n if (transition) {\n this.ongoingTransitions.set(type, { ...transition, startTime: elapsedTime });\n transition.onTransitionBegin?.();\n }\n }\n });\n\n this.ongoingTransitions.forEach((transition, type) => {\n if (transition.cancelled) {\n transition.onTransitionCancelled?.();\n this.ongoingTransitions.delete(type);\n return;\n }\n\n const { startTime, duration, easing } = transition;\n\n const timeDistance = elapsedTime - startTime;\n const progress = clamp(easing(Math.min(1.0, timeDistance / duration)), 0.0, 1.0);\n\n this.emitTransitionProgress(type, progress);\n transition.onTransitionProgress?.(progress);\n\n if (progress >= 1) {\n this.emitTransitionFinished(type);\n transition.onTransitionFinished?.();\n this.ongoingTransitions.delete(type);\n }\n });\n }\n\n private getQueue(type: TransitionType): Array<TransitionQueueItem> {\n const queue = this.transitions.get(type);\n if (!queue) {\n this.transitions.set(type, []);\n return this.transitions.get(type) ?? [];\n }\n return queue;\n }\n\n private handleTransitionCancelledEvent({ type }: { type: TransitionType }) {\n const transitions = this.getQueue(type);\n while (transitions.length) transitions.pop();\n\n const ongoingTransition = this.ongoingTransitions.get(type);\n if (ongoingTransition) {\n ongoingTransition.cancelled = true;\n ongoingTransition.onTransitionCancelled?.();\n }\n }\n\n private emitTransitionProgress(type: TransitionType, progress: number) {\n this.eventEmitter.emit('transitionProgressed', { type, progress });\n }\n\n private emitTransitionFinished(type: TransitionType) {\n this.eventEmitter.emit('transitionFinished', { type });\n }\n}\n","import { linear } from '@/lib/easing';\nimport { DefaultEventEmitter } from '@/lib/events/defaultEventEmitter';\nimport { AssetService } from '@/lib/services/assets/assetService';\nimport { DataTextureService } from '@/lib/services/dataTexture/dataTextureService';\nimport { InstancedMeshManager } from '@/lib/services/instancedmesh/instancedMeshManager';\nimport { IntersectionService } from '@/lib/services/intersection/intersectionService';\nimport { SimulationRendererService } from '@/lib/services/simulation/simulationRendererService';\nimport { TransitionService } from '@/lib/services/transition/transitionService';\nimport { EasingFunction, ServiceState, ServiceType, TransitionType } from '@/lib/types';\nimport { EngineState } from '@/lib/types/state';\nimport * as THREE from 'three';\n\n/**\n * Parameters for creating a ParticlesEngine instance.\n */\ntype ParticlesEngineParameters = {\n textureSize: number;\n scene: THREE.Scene;\n renderer: THREE.WebGLRenderer;\n camera?: THREE.Camera;\n};\n\ntype ServiceStates = Record<ServiceType, ServiceState>;\n\n/**\n * The main class for the particle engine.\n */\nexport class ParticlesEngine {\n private simulationRendererService: SimulationRendererService;\n private eventEmitter: DefaultEventEmitter;\n private renderer: THREE.WebGLRenderer;\n\n private scene: THREE.Scene;\n private serviceStates: ServiceStates;\n\n // assets\n private assetService: AssetService;\n private dataTextureManager: DataTextureService;\n private instancedMeshManager: InstancedMeshManager;\n\n private transitionService: TransitionService;\n private engineState: EngineState;\n\n private intersectionService: IntersectionService;\n\n /**\n * Creates a new ParticlesEngine instance.\n * @param params The parameters for creating the instance.\n */\n constructor(params: ParticlesEngineParameters) {\n this.eventEmitter = new DefaultEventEmitter();\n this.serviceStates = this.initialServiceStates();\n this.eventEmitter.on('serviceStateUpdated', this.handleServiceStateUpdated.bind(this));\n\n this.scene = params.scene;\n this.renderer = params.renderer;\n this.engineState = this.initialEngineState(params.textureSize);\n\n this.assetService = new AssetService(this.eventEmitter);\n this.transitionService = new TransitionService(this.eventEmitter);\n this.dataTextureManager = new DataTextureService(this.eventEmitter, params.textureSize);\n this.simulationRendererService = new SimulationRendererService(this.eventEmitter, params.textureSize, this.renderer);\n this.instancedMeshManager = new InstancedMeshManager(params.textureSize);\n this.instancedMeshManager.useMatcapMaterial();\n this.scene.add(this.instancedMeshManager.getMesh());\n\n this.intersectionService = new IntersectionService(this.eventEmitter, params.camera);\n\n this.eventEmitter.on('transitionProgressed', this.handleTransitionProgress.bind(this));\n this.eventEmitter.on('interactionPositionUpdated', this.handleInteractionPositionUpdated.bind(this));\n }\n\n /**\n * Renders the scene.\n * @param elapsedTime The elapsed time since the last frame.\n */\n\n render(elapsedTime: number) {\n this.intersectionService.calculate(this.instancedMeshManager.getMesh());\n this.transitionService.compute(elapsedTime);\n this.simulationRendererService.compute(elapsedTime);\n this.instancedMeshManager.update(elapsedTime);\n this.instancedMeshManager.updateVelocityTexture(this.simulationRendererService.getVelocityTexture());\n this.instancedMeshManager.updatePositionTexture(this.simulationRendererService.getPositionTexture());\n }\n\n setOriginDataTexture(meshID: string, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'data-texture' });\n\n const mesh = this.assetService.getMesh(meshID);\n\n if (!mesh) {\n this.eventEmitter.emit('invalidRequest', { message: `Mesh with id \"${meshID}\" does not exist` });\n return;\n }\n\n this.dataTextureManager.getDataTexture(mesh).then((dataTexture) => {\n this.engineState.originMeshID = meshID;\n this.simulationRendererService.setOriginDataTexture({ dataTexture, textureSize: this.engineState.textureSize });\n this.intersectionService.setOriginGeometry(mesh);\n });\n }\n\n setDestinationDataTexture(meshID: string, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'data-texture' });\n\n const mesh = this.assetService.getMesh(meshID);\n\n if (!mesh) {\n this.eventEmitter.emit('invalidRequest', { message: `Mesh with id \"${meshID}\" does not exist` });\n return;\n }\n\n this.dataTextureManager.getDataTexture(mesh).then((texture) => {\n this.engineState.destinationMeshID = meshID;\n this.simulationRendererService.setDestinationDataTexture({\n dataTexture: texture,\n textureSize: this.engineState.textureSize,\n });\n this.intersectionService.setDestinationGeometry(mesh);\n });\n }\n\n setDataTextureTransitionProgress(progress: number, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'data-texture' });\n this.engineState.dataTextureTransitionProgress = progress;\n this.simulationRendererService.setDataTextureTransitionProgress(progress);\n this.intersectionService.setProgress(progress);\n }\n\n setOriginMatcap(matcapID: string, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n this.engineState.originMatcapID = matcapID;\n this.instancedMeshManager.setOriginMatcap(this.assetService.getMatcap(matcapID));\n }\n\n setDestinationMatcap(matcapID: string, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n this.engineState.destinationMatcapID = matcapID;\n this.instancedMeshManager.setDestinationMatcap(this.assetService.getMatcap(matcapID));\n }\n\n setOriginColor(color: THREE.ColorRepresentation, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n this.instancedMeshManager.setOriginColor(color);\n }\n\n setDestinationColor(color: THREE.ColorRepresentation, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n this.instancedMeshManager.setDestinationColor(color);\n }\n\n setOriginTexture(id: string | THREE.ColorRepresentation, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n\n if (typeof id === 'string' && this.assetService.hasMatcap(id)) {\n this.setOriginMatcap(id);\n } else {\n this.setOriginColor(id);\n }\n }\n\n setDestinationTexture(id: string | THREE.ColorRepresentation, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n\n if (typeof id === 'string' && this.assetService.hasMatcap(id)) {\n this.setDestinationMatcap(id);\n } else {\n this.setDestinationColor(id);\n }\n }\n\n setMatcapProgress(progress: number, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n this.engineState.matcapTransitionProgress = progress;\n this.instancedMeshManager.setProgress(progress);\n }\n\n async setTextureSize(size: number) {\n this.engineState.textureSize = size;\n this.dataTextureManager.setTextureSize(size);\n this.simulationRendererService.setTextureSize(size);\n this.instancedMeshManager.resize(size);\n\n const originMesh = this.assetService.getMesh(this.engineState.originMeshID);\n if (!originMesh) {\n this.eventEmitter.emit('invalidRequest', { message: `Mesh with id \"${this.engineState.originMeshID}\" does not exist` });\n return;\n }\n\n const destinationMesh = this.assetService.getMesh(this.engineState.destinationMeshID);\n if (!destinationMesh) {\n this.eventEmitter.emit('invalidRequest', { message: `Mesh with id \"${this.engineState.destinationMeshID}\" does not exist` });\n return;\n }\n\n this.dataTextureManager.getDataTexture(originMesh).then((texture) =>\n this.simulationRendererService.setOriginDataTexture({\n dataTexture: texture,\n textureSize: size,\n }),\n );\n\n this.dataTextureManager.getDataTexture(destinationMesh).then((texture) =>\n this.simulationRendererService.setDestinationDataTexture({\n dataTexture: texture,\n textureSize: size,\n }),\n );\n\n this.simulationRendererService.setDataTextureTransitionProgress(this.engineState.dataTextureTransitionProgress);\n this.simulationRendererService.setVelocityTractionForce(this.engineState.velocityTractionForce);\n this.simulationRendererService.setPositionalTractionForce(this.engineState.positionalTractionForce);\n\n this.instancedMeshManager.setOriginMatcap(this.assetService.getMatcap(this.engineState.originMatcapID));\n this.instancedMeshManager.setDestinationMatcap(this.assetService.getMatcap(this.engineState.destinationMatcapID));\n this.instancedMeshManager.setProgress(this.engineState.matcapTransitionProgress);\n this.instancedMeshManager.setGeometrySize(this.engineState.instanceGeometryScale);\n }\n\n registerMesh(id: string, mesh: THREE.Mesh) {\n this.assetService.register(id, mesh);\n }\n\n registerMatcap(id: string, matcap: THREE.Texture) {\n this.assetService.register(id, matcap);\n }\n\n async fetchAndRegisterMesh(id: string, url: string) {\n return await this.assetService.loadMeshAsync(id, url);\n }\n\n async fetchAndRegisterMatcap(id: string, url: string) {\n return await this.assetService.loadTextureAsync(id, url);\n }\n\n setPointerPosition(position: THREE.Vector2Like) {\n this.engineState.pointerPosition = position;\n this.intersectionService.setMousePosition(position);\n }\n\n setGeometrySize(geometrySize: THREE.Vector3Like) {\n this.engineState.instanceGeometryScale = geometrySize;\n this.instancedMeshManager.setGeometrySize(geometrySize);\n }\n\n setVelocityTractionForce(force: number) {\n this.engineState.velocityTractionForce = force;\n this.simulationRendererService.setVelocityTractionForce(force);\n }\n\n setPositionalTractionForce(force: number) {\n this.engineState.positionalTractionForce = force;\n this.simulationRendererService.setPositionalTractionForce(force);\n }\n\n setMaxRepelDistance(distance: number) {\n this.engineState.maxRepelDistance = distance;\n this.simulationRendererService.setMaxRepelDistance(distance);\n }\n\n scheduleMeshTransition(originMeshID: string, destinationMeshID: string, easing: EasingFunction = linear, duration: number = 1000, override: boolean = false) {\n this.transitionService.enqueue(\n 'data-texture',\n { easing, duration },\n {\n onTransitionBegin: () => {\n this.setOriginDataTexture(originMeshID, override);\n this.setDestinationDataTexture(destinationMeshID, override);\n this.setDataTextureTransitionProgress(0);\n },\n },\n );\n }\n\n scheduleMatcapTransition(\n originMatcapID: string,\n destinationMatcapID: string,\n easing: EasingFunction = linear,\n duration: number = 1000,\n override: boolean = false,\n ) {\n this.transitionService.enqueue(\n 'matcap',\n { easing, duration },\n {\n onTransitionBegin: () => {\n this.setOriginMatcap(originMatcapID, override);\n this.setDestinationMatcap(destinationMatcapID, override);\n this.setMatcapProgress(0);\n },\n },\n );\n }\n\n scheduleTextureTransition(\n origin: string,\n destination: string,\n options?: {\n easing?: EasingFunction;\n duration?: number;\n override?: boolean;\n },\n ) {\n const easing = options?.easing ?? linear;\n const duration = options?.duration ?? 1000;\n\n if (options?.override) {\n this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n }\n\n this.transitionService.enqueue(\n 'matcap',\n { easing, duration },\n {\n onTransitionBegin: () => {\n this.setOriginTexture(origin);\n this.setDestinationTexture(destination);\n this.setMatcapProgress(0);\n },\n },\n );\n }\n\n handleServiceStateUpdated({ type, state }: { type: ServiceType; state: ServiceState }) {\n this.serviceStates[type] = state;\n }\n\n getObject(): THREE.Mesh {\n return this.instancedMeshManager.getMesh();\n }\n\n getMeshIDs() {\n return this.assetService.getMeshIDs();\n }\n\n getMatcapIDs() {\n return this.assetService.getTextureIDs();\n }\n\n /**\n * Disposes the resources used by the engine.\n */\n dispose() {\n this.scene.remove(this.instancedMeshManager.getMesh());\n this.simulationRendererService.dispose();\n this.instancedMeshManager.dispose();\n this.intersectionService.dispose();\n this.assetService.dispose();\n this.dataTextureManager.dispose();\n }\n\n private initialEngineState(textureSize: number): EngineState {\n return {\n textureSize,\n originMeshID: '',\n destinationMeshID: '',\n dataTextureTransitionProgress: 0,\n originMatcapID: '',\n destinationMatcapID: '',\n matcapTransitionProgress: 0,\n velocityTractionForce: 0.1,\n positionalTractionForce: 0.1,\n maxRepelDistance: 0.3,\n pointerPosition: { x: 0, y: 0 },\n instanceGeometryScale: { x: 1, y: 1, z: 1 },\n };\n }\n\n private initialServiceStates(): ServiceStates {\n return {\n 'data-texture': 'created',\n 'instanced-mesh': 'created',\n matcap: 'created',\n simulation: 'created',\n asset: 'created',\n };\n }\n\n private handleTransitionProgress({ type, progress }: { type: TransitionType; progress: number }) {\n switch (type) {\n case 'data-texture':\n this.setDataTextureTransitionProgress(progress);\n break;\n case 'matcap':\n this.setMatcapProgress(progress);\n break;\n }\n }\n\n private handleInteractionPositionUpdated({ position }: { position: THREE.Vector4Like }) {\n this.simulationRendererService.setInteractionPosition(position);\n }\n}\n"],"names":["linear","n","DefaultEventEmitter","constructor","__publicField","this","all","Map","on","t","e","i","get","push","set","off","splice","indexOf","emit","slice","map","type","payload","emitter","handler","once","dispose","clear","createDataTexture","data","size","texture","THREE","DataTexture","RGBAFormat","FloatType","needsUpdate","disposeMesh","mesh","geometry","material","Material","forEach","clamp","value","min","max","Math","AssetService","eventEmitter","GLTFLoader","TextureLoader","DRACOLoader","Uint8Array","dracoLoader","setDecoderPath","gltfLoader","setDRACOLoader","updateServiceState","register","id","item","name","Mesh","prev","meshes","textures","setSolidColor","color","changeColor","getSolidColorTexture","solidColorTexture","getMesh","getMatcap","message","getMeshIDs","Array","from","keys","getTextureIDs","getMeshes","values","getTextures","hasMatcap","has","loadMeshAsync","url","options","gltf","loadAsync","meshName","scene","getObjectByName","children","error","loadTextureAsync","textureLoader","actual","Color","r","g","b","serviceState","state","_face","Triangle","_color","Vector3","_uva","Vector2","_uvb","_uvc","MeshSurfaceSampler","randomFunction","random","indexAttribute","index","positionAttribute","getAttribute","normalAttribute","colorAttribute","uvAttribute","weightAttribute","distribution","setWeightAttribute","build","totalFaces","count","faceWeights","Float32Array","faceWeight","i0","i1","i2","getX","a","fromBufferAttribute","c","getArea","cumulativeTotal","setRandomGenerator","sample","targetPosition","targetNormal","targetColor","targetUV","faceIndex","sampleFaceIndex","sampleFace","length","binarySearch","x","dist","start","end","mid","ceil","u","v","addScaledVector","normalize","getNormal","y","z","DataTextureService","textureSize","dataTextures","setTextureSize","getDataTexture","asset","array","meshData","BufferGeometry","setAttribute","BufferAttribute","position","normal","MeshBasicMaterial","scale","sampler","j","sampleMesh","attributes","_a","dataTexture","InstancedMeshManager","initialSize","geometries","uvRefsCache","previousScale","originColor","destinationColor","uniforms","uTime","uProgress","uTexture","uVelocity","uOriginTexture","uDestinationTexture","matcapMaterial","ShaderMaterial","vertexShader","fragmentShader","setOriginColor","setDestinationColor","fallbackGeometry","BoxGeometry","createInstancedMesh","update","elapsedTime","RawShaderMaterial","setOriginMatcap","matcap","disposeSolidColorOriginTexture","setDestinationMatcap","disposeSolidColorDestinationTexture","setProgress","float","setGeometrySize","useMatcapMaterial","useGeometry","updateVelocityTexture","updatePositionTexture","resize","current","previous","registerGeometry","uvRefs","createUVRefs","createSolidColorDataTexture","cached","attr","InstancedBufferAttribute","InstancedMesh","col","width","height","floor","UnsignedByteType","wrapS","RepeatWrapping","wrapT","minFilter","NearestFilter","magFilter","IntersectionService","camera","originGeometry","destinationGeometry","Raycaster","geometryNeedsUpdate","getIntersectionMesh","intersectionMesh","setCamera","setOriginGeometry","source","lastKnownOriginMeshID","uuid","clone","applyMatrix4","matrixWorld","setDestinationGeometry","lastKnownDestinationMeshID","progress","setMousePosition","mousePosition","copy","calculate","instancedMesh","updateIntersectionMesh","blendedGeometry","getBlendedGeometry","intersection","getFirstIntersection","w","matrix","matrixAutoUpdate","updateMatrixWorld","raycaster","setFromCamera","intersectObject","worldPoint","point","localPoint","worldToLocal","Vector4","blendGeometry","to","blended","originPositions","destinationPositions","blendedPositions","originVert","destinationVert","blendedVert","lerpVectors","uv","setIndex","_camera","OrthographicCamera","FullscreenTriangleGeometry","super","Float32BufferAttribute","_geometry","FullScreenQuad","_mesh","render","renderer","GPUComputationRenderer","sizeX","sizeY","variables","currentTextureIndex","dataType","passThruUniforms","passThruTexture","passThruShader","createShaderMaterial","quad","addResolutionDefine","materialShader","defines","resolution","toFixed","computeFragmentShader","setDataType","addVariable","variableName","initialValueTexture","variable","dependencies","renderTargets","setVariableDependencies","init","capabilities","maxVertexTextures","createRenderTarget","renderTexture","d","depVar","found","compute","nextTextureIndex","il","dl","doRenderTarget","getCurrentRenderTarget","getAlternateRenderTarget","sizeXTexture","sizeYTexture","ClampToEdgeWrapping","WebGLRenderTarget","format","depthBuffer","createTexture","input","output","currentRenderTarget","getRenderTarget","currentXrEnabled","xr","enabled","currentShadowAutoUpdate","shadowMap","autoUpdate","setRenderTarget","SimulationRenderer","webGLRenderer","initialPosition","initialDataTexture","theta","PI","phi","acos","sin","cos","createSpherePoints","positionDataTexture","gpuComputationRenderer","lastKnownMixProgress","isWebGL2","HalfFloatType","velocityDataTexture","createBlankDataTexture","interactionPosition","mixPositionsVar","velocityVar","positionVar","uPositionA","uPositionB","uInteractionPosition","uCurrentPosition","uTractionForce","uMaxRepelDistance","err","Error","lastKnownVelocityDataTexture","getVelocityTexture","lastKnownPositionDataTexture","getPositionTexture","setMorphSourceDataTexture","setMorphDestinationDataTexture","setMaxRepelDistance","distance","setVelocityTractionForce","force","setPositionalTractionForce","setInteractionPosition","rtt","SimulationRendererService","dataTextureTransitionProgress","velocityTractionForce","positionalTractionForce","simulationRenderer","setOriginDataTexture","entry","setDestinationDataTexture","setDataTextureTransitionProgress","ExecutionStatusMap","status","execStatus","TransitionService","handleTransitionCancelledEvent","bind","enqueue","transition","transitionQueueItem","cancelled","duration","getQueue","transitions","queue","ongoingTransitions","shift","startTime","onTransitionBegin","call","onTransitionCancelled","delete","easing","timeDistance","emitTransitionProgress","_b","onTransitionProgress","emitTransitionFinished","_c","onTransitionFinished","pop","ongoingTransition","params","serviceStates","initialServiceStates","handleServiceStateUpdated","engineState","initialEngineState","assetService","transitionService","dataTextureManager","simulationRendererService","instancedMeshManager","add","intersectionService","handleTransitionProgress","handleInteractionPositionUpdated","meshID","override","then","originMeshID","destinationMeshID","matcapID","originMatcapID","destinationMatcapID","setOriginTexture","setDestinationTexture","setMatcapProgress","matcapTransitionProgress","originMesh","destinationMesh","instanceGeometryScale","registerMesh","registerMatcap","fetchAndRegisterMesh","fetchAndRegisterMatcap","setPointerPosition","pointerPosition","geometrySize","maxRepelDistance","scheduleMeshTransition","scheduleMatcapTransition","scheduleTextureTransition","origin","destination","getObject","getMatcapIDs","remove","simulation"],"mappings":"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","x_google_ignoreList":[2,5,11,12]}
|
|
1
|
+
{"version":3,"file":"ionian.iife.js","sources":["../src/lib/easing.ts","../src/lib/events/defaultEventEmitter.ts","../node_modules/.pnpm/mitt@3.0.1/node_modules/mitt/dist/mitt.mjs","../src/lib/utils.ts","../src/lib/services/assets/assetService.ts","../node_modules/.pnpm/three@0.173.0/node_modules/three/examples/jsm/math/MeshSurfaceSampler.js","../src/lib/services/dataTexture/dataTextureService.ts","../src/lib/services/instancedmesh/instancedMeshManager.ts","../src/lib/services/instancedmesh/shaders/instanceVertexShader.ts","../src/lib/services/instancedmesh/shaders/instanceFragmentShader.ts","../src/lib/services/intersection/intersectionService.ts","../node_modules/.pnpm/three@0.173.0/node_modules/three/examples/jsm/postprocessing/Pass.js","../node_modules/.pnpm/three@0.173.0/node_modules/three/examples/jsm/misc/GPUComputationRenderer.js","../src/lib/services/simulation/simulationRenderer.ts","../src/lib/services/simulation/shaders/simulationMixShader.ts","../src/lib/services/simulation/shaders/simulationVelocityShader.ts","../src/lib/services/simulation/shaders/simulationPositionShader.ts","../src/lib/services/simulation/simulationRendererService.ts","../src/lib/services/transition/transitionService.ts","../src/lib/particlesEngine.ts"],"sourcesContent":["import { EasingFunction } from '@/lib/types';\n\n/**\n * Linear easing function.\n */\nexport const linear: EasingFunction = (n: number) => n;\n","import { Events } from '@/lib/events/topics';\nimport mitt from 'mitt';\nimport { EngineEventEmitter } from './engineEventEmitter';\n\nexport class DefaultEventEmitter implements EngineEventEmitter<Events> {\n private readonly emitter = mitt<Events>();\n\n emit<Key extends keyof Events>(type: Key, payload: Events[Key]): void {\n this.emitter.emit(type, payload);\n }\n\n off<Key extends keyof Events>(type: Key, handler?: (payload: Events[Key]) => void): void {\n this.emitter.off(type, handler);\n }\n\n on<Key extends keyof Events>(type: Key, handler: (payload: Events[Key]) => void): void {\n this.emitter.on(type, handler);\n }\n\n once<Key extends keyof Events>(type: Key, handler: (payload: Events[Key]) => void): void {\n this.emitter.on(type, (payload: Events[Key]) => {\n this.emitter.off(type, handler);\n handler(payload);\n });\n }\n\n dispose(): void {\n this.emitter.all.clear();\n }\n}\n","export default function(n){return{all:n=n||new Map,on:function(t,e){var i=n.get(t);i?i.push(e):n.set(t,[e])},off:function(t,e){var i=n.get(t);i&&(e?i.splice(i.indexOf(e)>>>0,1):n.set(t,[]))},emit:function(t,e){var i=n.get(t);i&&i.slice().map(function(n){n(e)}),(i=n.get(\"*\"))&&i.slice().map(function(n){n(t,e)})}}}\n//# sourceMappingURL=mitt.mjs.map\n","import * as THREE from 'three';\n\n/**\n * Creates a new DataTexture from the given data and size.\n * @param data - The data for the texture.\n * @param size - The size of the texture.\n * @returns The created DataTexture.\n */\nexport function createDataTexture(data: Float32Array, size: number) {\n const texture = new THREE.DataTexture(data, size, size, THREE.RGBAFormat, THREE.FloatType);\n texture.needsUpdate = true;\n return texture;\n}\n\n/**\n * Creates a blank DataTexture with the given size.\n * @param size - The size of the texture.\n * @returns The created blank DataTexture.\n */\nexport function createBlankDataTexture(size: number) {\n return createDataTexture(new Float32Array(4 * size * size), size);\n}\n\n/**\n * Creates a DataTexture representing a sphere.\n * @param size - The size of the texture.\n * @returns The created DataTexture.\n */\nexport function createSpherePoints(size: number) {\n const data = new Float32Array(size * size * 4);\n for (let i = 0; i < size; i++) {\n for (let j = 0; j < size; j++) {\n const index = i * size + j;\n\n let theta = Math.random() * Math.PI * 2;\n let phi = Math.acos(Math.random() * 2 - 1);\n let x = Math.sin(phi) * Math.cos(theta);\n let y = Math.sin(phi) * Math.sin(theta);\n let z = Math.cos(phi);\n\n data[4 * index] = x;\n data[4 * index + 1] = y;\n data[4 * index + 2] = z;\n data[4 * index + 3] = (Math.random() - 0.5) * 0.01;\n }\n }\n\n return createDataTexture(data, size);\n}\n\nexport function disposeMesh(mesh: THREE.Mesh) {\n mesh.geometry.dispose();\n if (mesh.material instanceof THREE.Material) {\n mesh.material.dispose();\n } else {\n mesh.material.forEach((material) => material.dispose());\n }\n}\n\nexport function clamp(value: number, min: number, max: number): number {\n value = Math.min(value, max);\n value = Math.max(value, min);\n return value;\n}\n","import { DefaultEventEmitter } from '@/lib/events';\nimport { ServiceState } from '@/lib/types';\nimport { disposeMesh } from '@/lib/utils';\nimport * as THREE from 'three';\nimport { DRACOLoader, GLTFLoader } from 'three-stdlib';\n\nexport class AssetService {\n private serviceState: ServiceState = 'created';\n\n private readonly eventEmitter;\n private readonly meshes = new Map<string, THREE.Mesh>();\n private readonly textures = new Map<string, THREE.Texture>();\n\n private readonly gltfLoader = new GLTFLoader();\n private readonly textureLoader = new THREE.TextureLoader();\n private readonly dracoLoader = new DRACOLoader();\n\n private solidColorTexture = new THREE.DataTexture(new Uint8Array([127, 127, 127, 255]), 1, 1, THREE.RGBAFormat);\n\n constructor(eventEmitter: DefaultEventEmitter) {\n this.eventEmitter = eventEmitter;\n this.dracoLoader.setDecoderPath('https://www.gstatic.com/draco/versioned/decoders/1.5.7/');\n this.gltfLoader.setDRACOLoader(this.dracoLoader);\n this.updateServiceState('ready');\n }\n\n /**\n * Registers an asset.\n * @param id - The ID of the asset.\n * @param item - The asset to set.\n */\n register(id: string, item: THREE.Mesh | THREE.Texture) {\n item.name = id;\n\n if (item instanceof THREE.Mesh) {\n const prev = this.meshes.get(id);\n if (prev) disposeMesh(prev);\n this.meshes.set(id, item);\n } else {\n const prev = this.textures.get(id);\n if (prev) prev.dispose();\n this.textures.set(id, item);\n }\n\n this.eventEmitter.emit('assetRegistered', { id });\n }\n\n setSolidColor(color: THREE.ColorRepresentation) {\n this.changeColor(color);\n }\n\n getSolidColorTexture() {\n return this.solidColorTexture;\n }\n\n getMesh(id: string): THREE.Mesh | null {\n return this.meshes.get(id) ?? null;\n }\n\n getMatcap(id: string): THREE.Texture {\n const texture = this.textures.get(id);\n if (!texture) this.eventEmitter.emit('invalidRequest', { message: `texture with id \"${id}\" not found. using solid color texture instead...` });\n return texture ?? this.solidColorTexture;\n }\n\n getMeshIDs(): string[] {\n return Array.from(this.meshes.keys());\n }\n\n getTextureIDs(): string[] {\n return Array.from(this.textures.keys());\n }\n\n getMeshes(): THREE.Mesh[] {\n return Array.from(this.meshes.values());\n }\n\n getTextures(): THREE.Texture[] {\n return Array.from(this.textures.values());\n }\n\n hasMatcap(id: string) {\n return this.textures.has(id);\n }\n\n /**\n * Loads a mesh asynchronously.\n * @param id - The ID of the mesh.\n * @param url - The URL of the mesh.\n * @param options - Optional parameters.\n * @returns The loaded mesh or null.\n */\n async loadMeshAsync(id: string, url: string, options: { meshName?: string } = {}): Promise<THREE.Mesh | null> {\n const gltf = await this.gltfLoader.loadAsync(url);\n try {\n if (options.meshName) {\n const mesh = gltf.scene.getObjectByName(options.meshName) as THREE.Mesh;\n this.register(id, mesh);\n return mesh;\n } else {\n const mesh = gltf.scene.children[0] as THREE.Mesh;\n this.register(id, mesh);\n return mesh;\n }\n } catch (error) {\n this.eventEmitter.emit('invalidRequest', { message: `failed to load mesh: ${id}. ${error}` });\n return null;\n }\n }\n\n /**\n * Loads a texture asynchronously.\n * @param id - The ID of the texture.\n * @param url - The URL of the texture.\n * @returns The loaded texture or null.\n */\n async loadTextureAsync(id: string, url: string): Promise<THREE.Texture | null> {\n try {\n const texture = await this.textureLoader.loadAsync(url);\n this.register(id, texture);\n return texture;\n } catch (error) {\n this.eventEmitter.emit('invalidRequest', { message: `failed to load texture: ${id}. ${error}` });\n return null;\n }\n }\n\n dispose() {\n this.updateServiceState('disposed');\n this.meshes.forEach((mesh) => disposeMesh(mesh));\n this.meshes.clear();\n this.textures.forEach((texture) => texture.dispose());\n this.textures.clear();\n }\n\n private changeColor(color: THREE.ColorRepresentation) {\n const actual = new THREE.Color(color);\n this.solidColorTexture = new THREE.DataTexture(new Uint8Array([actual.r, actual.g, actual.b, 255]), 1, 1, THREE.RGBAFormat);\n this.solidColorTexture.needsUpdate = true;\n }\n\n private updateServiceState(serviceState: ServiceState) {\n this.serviceState = serviceState;\n this.eventEmitter.emit('serviceStateUpdated', { type: 'asset', state: serviceState });\n }\n}\n","import {\n\tTriangle,\n\tVector2,\n\tVector3\n} from 'three';\n\n/**\n * Utility class for sampling weighted random points on the surface of a mesh.\n *\n * Building the sampler is a one-time O(n) operation. Once built, any number of\n * random samples may be selected in O(logn) time. Memory usage is O(n).\n *\n * References:\n * - http://www.joesfer.com/?p=84\n * - https://stackoverflow.com/a/4322940/1314762\n */\n\nconst _face = new Triangle();\nconst _color = new Vector3();\nconst _uva = new Vector2(), _uvb = new Vector2(), _uvc = new Vector2();\n\nclass MeshSurfaceSampler {\n\n\tconstructor( mesh ) {\n\n\t\tthis.geometry = mesh.geometry;\n\t\tthis.randomFunction = Math.random;\n\n\t\tthis.indexAttribute = this.geometry.index;\n\t\tthis.positionAttribute = this.geometry.getAttribute( 'position' );\n\t\tthis.normalAttribute = this.geometry.getAttribute( 'normal' );\n\t\tthis.colorAttribute = this.geometry.getAttribute( 'color' );\n\t\tthis.uvAttribute = this.geometry.getAttribute( 'uv' );\n\t\tthis.weightAttribute = null;\n\n\t\tthis.distribution = null;\n\n\t}\n\n\tsetWeightAttribute( name ) {\n\n\t\tthis.weightAttribute = name ? this.geometry.getAttribute( name ) : null;\n\n\t\treturn this;\n\n\t}\n\n\tbuild() {\n\n\t\tconst indexAttribute = this.indexAttribute;\n\t\tconst positionAttribute = this.positionAttribute;\n\t\tconst weightAttribute = this.weightAttribute;\n\n\t\tconst totalFaces = indexAttribute ? ( indexAttribute.count / 3 ) : ( positionAttribute.count / 3 );\n\t\tconst faceWeights = new Float32Array( totalFaces );\n\n\t\t// Accumulate weights for each mesh face.\n\n\t\tfor ( let i = 0; i < totalFaces; i ++ ) {\n\n\t\t\tlet faceWeight = 1;\n\n\t\t\tlet i0 = 3 * i;\n\t\t\tlet i1 = 3 * i + 1;\n\t\t\tlet i2 = 3 * i + 2;\n\n\t\t\tif ( indexAttribute ) {\n\n\t\t\t\ti0 = indexAttribute.getX( i0 );\n\t\t\t\ti1 = indexAttribute.getX( i1 );\n\t\t\t\ti2 = indexAttribute.getX( i2 );\n\n\t\t\t}\n\n\t\t\tif ( weightAttribute ) {\n\n\t\t\t\tfaceWeight = weightAttribute.getX( i0 )\n\t\t\t\t\t+ weightAttribute.getX( i1 )\n\t\t\t\t\t+ weightAttribute.getX( i2 );\n\n\t\t\t}\n\n\t\t\t_face.a.fromBufferAttribute( positionAttribute, i0 );\n\t\t\t_face.b.fromBufferAttribute( positionAttribute, i1 );\n\t\t\t_face.c.fromBufferAttribute( positionAttribute, i2 );\n\t\t\tfaceWeight *= _face.getArea();\n\n\t\t\tfaceWeights[ i ] = faceWeight;\n\n\t\t}\n\n\t\t// Store cumulative total face weights in an array, where weight index\n\t\t// corresponds to face index.\n\n\t\tconst distribution = new Float32Array( totalFaces );\n\t\tlet cumulativeTotal = 0;\n\n\t\tfor ( let i = 0; i < totalFaces; i ++ ) {\n\n\t\t\tcumulativeTotal += faceWeights[ i ];\n\t\t\tdistribution[ i ] = cumulativeTotal;\n\n\t\t}\n\n\t\tthis.distribution = distribution;\n\t\treturn this;\n\n\t}\n\n\tsetRandomGenerator( randomFunction ) {\n\n\t\tthis.randomFunction = randomFunction;\n\t\treturn this;\n\n\t}\n\n\tsample( targetPosition, targetNormal, targetColor, targetUV ) {\n\n\t\tconst faceIndex = this.sampleFaceIndex();\n\t\treturn this.sampleFace( faceIndex, targetPosition, targetNormal, targetColor, targetUV );\n\n\t}\n\n\tsampleFaceIndex() {\n\n\t\tconst cumulativeTotal = this.distribution[ this.distribution.length - 1 ];\n\t\treturn this.binarySearch( this.randomFunction() * cumulativeTotal );\n\n\t}\n\n\tbinarySearch( x ) {\n\n\t\tconst dist = this.distribution;\n\t\tlet start = 0;\n\t\tlet end = dist.length - 1;\n\n\t\tlet index = - 1;\n\n\t\twhile ( start <= end ) {\n\n\t\t\tconst mid = Math.ceil( ( start + end ) / 2 );\n\n\t\t\tif ( mid === 0 || dist[ mid - 1 ] <= x && dist[ mid ] > x ) {\n\n\t\t\t\tindex = mid;\n\n\t\t\t\tbreak;\n\n\t\t\t} else if ( x < dist[ mid ] ) {\n\n\t\t\t\tend = mid - 1;\n\n\t\t\t} else {\n\n\t\t\t\tstart = mid + 1;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn index;\n\n\t}\n\n\tsampleFace( faceIndex, targetPosition, targetNormal, targetColor, targetUV ) {\n\n\t\tlet u = this.randomFunction();\n\t\tlet v = this.randomFunction();\n\n\t\tif ( u + v > 1 ) {\n\n\t\t\tu = 1 - u;\n\t\t\tv = 1 - v;\n\n\t\t}\n\n\t\t// get the vertex attribute indices\n\t\tconst indexAttribute = this.indexAttribute;\n\t\tlet i0 = faceIndex * 3;\n\t\tlet i1 = faceIndex * 3 + 1;\n\t\tlet i2 = faceIndex * 3 + 2;\n\t\tif ( indexAttribute ) {\n\n\t\t\ti0 = indexAttribute.getX( i0 );\n\t\t\ti1 = indexAttribute.getX( i1 );\n\t\t\ti2 = indexAttribute.getX( i2 );\n\n\t\t}\n\n\t\t_face.a.fromBufferAttribute( this.positionAttribute, i0 );\n\t\t_face.b.fromBufferAttribute( this.positionAttribute, i1 );\n\t\t_face.c.fromBufferAttribute( this.positionAttribute, i2 );\n\n\t\ttargetPosition\n\t\t\t.set( 0, 0, 0 )\n\t\t\t.addScaledVector( _face.a, u )\n\t\t\t.addScaledVector( _face.b, v )\n\t\t\t.addScaledVector( _face.c, 1 - ( u + v ) );\n\n\t\tif ( targetNormal !== undefined ) {\n\n\t\t\tif ( this.normalAttribute !== undefined ) {\n\n\t\t\t\t_face.a.fromBufferAttribute( this.normalAttribute, i0 );\n\t\t\t\t_face.b.fromBufferAttribute( this.normalAttribute, i1 );\n\t\t\t\t_face.c.fromBufferAttribute( this.normalAttribute, i2 );\n\t\t\t\ttargetNormal.set( 0, 0, 0 ).addScaledVector( _face.a, u ).addScaledVector( _face.b, v ).addScaledVector( _face.c, 1 - ( u + v ) ).normalize();\n\n\t\t\t} else {\n\n\t\t\t\t_face.getNormal( targetNormal );\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( targetColor !== undefined && this.colorAttribute !== undefined ) {\n\n\t\t\t_face.a.fromBufferAttribute( this.colorAttribute, i0 );\n\t\t\t_face.b.fromBufferAttribute( this.colorAttribute, i1 );\n\t\t\t_face.c.fromBufferAttribute( this.colorAttribute, i2 );\n\n\t\t\t_color\n\t\t\t\t.set( 0, 0, 0 )\n\t\t\t\t.addScaledVector( _face.a, u )\n\t\t\t\t.addScaledVector( _face.b, v )\n\t\t\t\t.addScaledVector( _face.c, 1 - ( u + v ) );\n\n\t\t\ttargetColor.r = _color.x;\n\t\t\ttargetColor.g = _color.y;\n\t\t\ttargetColor.b = _color.z;\n\n\t\t}\n\n\t\tif ( targetUV !== undefined && this.uvAttribute !== undefined ) {\n\n\t\t\t_uva.fromBufferAttribute( this.uvAttribute, i0 );\n\t\t\t_uvb.fromBufferAttribute( this.uvAttribute, i1 );\n\t\t\t_uvc.fromBufferAttribute( this.uvAttribute, i2 );\n\t\t\ttargetUV.set( 0, 0 ).addScaledVector( _uva, u ).addScaledVector( _uvb, v ).addScaledVector( _uvc, 1 - ( u + v ) );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n}\n\nexport { MeshSurfaceSampler };\n","import { DefaultEventEmitter } from '@/lib/events/defaultEventEmitter';\nimport { MeshData, ServiceState } from '@/lib/types';\nimport { createDataTexture } from '@/lib/utils';\nimport * as THREE from 'three';\nimport { MeshSurfaceSampler } from 'three/examples/jsm/math/MeshSurfaceSampler.js';\n\n/**\n * DataTextureManager is responsible for managing data textures used for mesh sampling.\n */\nexport class DataTextureService {\n private textureSize: number;\n private dataTextures: Map<string, THREE.DataTexture>;\n private eventEmitter;\n\n /**\n * Creates a new DataTextureManager instance.\n * @param eventEmitter\n * @param textureSize\n */\n constructor(eventEmitter: DefaultEventEmitter, textureSize: number) {\n this.eventEmitter = eventEmitter;\n this.textureSize = textureSize;\n this.dataTextures = new Map<string, THREE.DataTexture>();\n this.updateServiceState('ready');\n }\n\n setTextureSize(textureSize: number) {\n if (this.textureSize === textureSize) return;\n this.textureSize = textureSize;\n this.dataTextures.forEach((texture) => texture.dispose());\n this.dataTextures.clear();\n }\n\n /**\n * Prepares a mesh for sampling.\n * @returns The prepared data texture.\n * @param asset The asset to prepare.\n */\n async getDataTexture(asset: THREE.Mesh) {\n const texture = this.dataTextures.get(asset.name);\n if (texture) {\n return texture; // already prepared\n }\n\n const meshData = parseMeshData(asset);\n const array = sampleMesh(meshData, this.textureSize);\n const dataTexture = createDataTexture(array, this.textureSize);\n dataTexture.name = asset.name;\n return dataTexture;\n }\n\n async dispose() {\n this.dataTextures.clear();\n this.updateServiceState('disposed');\n }\n\n private updateServiceState(serviceState: ServiceState) {\n this.eventEmitter.emit('serviceStateUpdated', { type: 'data-texture', state: serviceState });\n }\n}\n\n/**\n * Parses mesh data into a simplified format.\n * @param mesh The mesh to parse.\n * @returns The parsed mesh data.\n */\nfunction parseMeshData(mesh: THREE.Mesh): MeshData {\n return {\n position: mesh.geometry.attributes.position.array,\n normal: (mesh.geometry.attributes.normal as THREE.BufferAttribute)?.array,\n scale: { x: mesh.scale.x, y: mesh.scale.y, z: mesh.scale.z },\n };\n}\n\nfunction sampleMesh(meshData: MeshData, size: number): Float32Array {\n const geometry = new THREE.BufferGeometry();\n geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(meshData.position), 3));\n if (meshData.normal) {\n geometry.setAttribute('normal', new THREE.BufferAttribute(new Float32Array(meshData.normal), 3));\n }\n const material = new THREE.MeshBasicMaterial();\n const mesh = new THREE.Mesh(geometry, material);\n mesh.scale.set(meshData.scale.x, meshData.scale.y, meshData.scale.z);\n\n const sampler = new MeshSurfaceSampler(mesh).build();\n const data = new Float32Array(size * size * 4);\n const position = new THREE.Vector3();\n\n for (let i = 0; i < size; i++) {\n for (let j = 0; j < size; j++) {\n const index = i * size + j;\n sampler.sample(position);\n data[4 * index] = position.x * meshData.scale.x;\n data[4 * index + 1] = position.y * meshData.scale.y;\n data[4 * index + 2] = position.z * meshData.scale.z;\n data[4 * index + 3] = (Math.random() - 0.5) * 0.01;\n }\n }\n\n return data;\n}\n","import * as THREE from 'three';\nimport { Vector3Like } from 'three';\nimport instanceFragmentShader from './shaders/instanceFragmentShader';\nimport instanceVertexShader from './shaders/instanceVertexShader';\n\ntype MaterialUniforms = {\n uTime: { value: number };\n uProgress: { value: number };\n uTexture: { value: THREE.DataTexture | null };\n uVelocity: { value: THREE.DataTexture | null };\n uOriginTexture: { value: THREE.Texture | null };\n uDestinationTexture: { value: THREE.Texture | null };\n};\n\n/**\n * InstancedMeshManager is responsible for managing instanced meshes.\n */\nexport class InstancedMeshManager {\n private size: number;\n private mesh: THREE.InstancedMesh;\n\n private readonly matcapMaterial: THREE.ShaderMaterial;\n private readonly fallbackGeometry: THREE.BufferGeometry;\n\n private readonly uniforms: MaterialUniforms;\n\n private originColor: THREE.ColorRepresentation | null;\n private destinationColor: THREE.ColorRepresentation | null;\n\n private geometries: Map<string, THREE.BufferGeometry>;\n private uvRefsCache: Map<number, THREE.InstancedBufferAttribute>;\n\n private previousScale: Vector3Like;\n\n /**\n * Creates a new InstancedMeshManager instance.\n * @param initialSize The initial size of the instanced mesh.\n */\n constructor(initialSize: number) {\n this.size = initialSize;\n this.geometries = new Map();\n this.uvRefsCache = new Map();\n\n this.previousScale = { x: 1, y: 1, z: 1 };\n this.originColor = 'grey';\n this.destinationColor = 'grey';\n\n this.uniforms = {\n uTime: { value: 0 },\n uProgress: { value: 0 },\n uTexture: { value: null },\n uVelocity: { value: null },\n uOriginTexture: { value: null },\n uDestinationTexture: { value: null },\n };\n\n this.matcapMaterial = new THREE.ShaderMaterial({\n uniforms: this.uniforms,\n vertexShader: instanceVertexShader,\n fragmentShader: instanceFragmentShader,\n });\n\n this.setOriginColor(this.originColor);\n this.setDestinationColor(this.destinationColor);\n\n this.fallbackGeometry = new THREE.BoxGeometry(0.001, 0.001, 0.001);\n this.mesh = this.createInstancedMesh(initialSize, this.fallbackGeometry, this.matcapMaterial);\n }\n\n /**\n * Gets the instanced mesh.\n * @returns The instanced mesh.\n */\n getMesh() {\n return this.mesh;\n }\n\n /**\n * Updates the instanced mesh.\n * @param elapsedTime The elapsed time.\n */\n update(elapsedTime: number) {\n const material = this.mesh.material;\n if (material instanceof THREE.ShaderMaterial || material instanceof THREE.RawShaderMaterial) {\n material.uniforms.uTime.value = elapsedTime;\n }\n }\n\n /**\n * Sets the matcap texture.\n * @param matcap The matcap texture to set.\n */\n setOriginMatcap(matcap: THREE.Texture) {\n this.disposeSolidColorOriginTexture();\n this.matcapMaterial.uniforms.uOriginTexture.value = matcap;\n }\n\n setDestinationMatcap(matcap: THREE.Texture) {\n this.disposeSolidColorDestinationTexture();\n this.matcapMaterial.uniforms.uDestinationTexture.value = matcap;\n }\n\n setProgress(float: number) {\n float = Math.max(0, float);\n float = Math.min(1, float);\n this.matcapMaterial.uniforms.uProgress.value = float;\n }\n\n setGeometrySize(size: THREE.Vector3Like) {\n this.mesh.geometry.scale(1 / this.previousScale.x, 1 / this.previousScale.y, 1 / this.previousScale.z);\n this.mesh.geometry.scale(size.x, size.y, size.z);\n this.previousScale = size;\n }\n\n /**\n * Use the matcap material for the instanced mesh.\n */\n useMatcapMaterial() {\n this.mesh.material = this.matcapMaterial;\n }\n\n /**\n * Use the specified geometry for the instanced mesh.\n * @param id The ID of the geometry to use.\n */\n useGeometry(id: string) {\n const geometry = this.geometries.get(id);\n if (geometry) {\n this.mesh.geometry = geometry;\n }\n }\n\n /**\n * Updates the velocity texture.\n * @param texture The velocity texture to update with.\n */\n updateVelocityTexture(texture: THREE.Texture) {\n this.matcapMaterial.uniforms.uVelocity.value = texture;\n }\n\n /**\n * Updates the position texture.\n * @param texture The position texture to update with.\n */\n updatePositionTexture(texture: THREE.Texture) {\n this.matcapMaterial.uniforms.uTexture.value = texture;\n }\n\n /**\n * Resizes or replaces the instanced mesh.\n * @param size The new size of the instanced mesh.\n * @returns An object containing the updated mesh, the previous mesh, and a boolean indicating whether the mesh was updated.\n */\n resize(size: number): { current: THREE.InstancedMesh; previous: THREE.InstancedMesh } {\n if (this.size === size) return { current: this.mesh, previous: this.mesh };\n\n this.size = size;\n\n // create new instances since it is greater than the last known value\n const prev = this.mesh;\n\n this.mesh = this.createInstancedMesh(size, prev.geometry, prev.material);\n\n return { current: this.mesh, previous: prev };\n }\n\n /**\n * Disposes the resources used by the InstancedMeshManager.\n */\n dispose() {\n this.mesh.dispose();\n\n this.geometries.forEach((geometry) => geometry.dispose());\n this.disposeSolidColorOriginTexture();\n this.disposeSolidColorDestinationTexture();\n this.matcapMaterial.dispose();\n\n this.uvRefsCache.clear();\n this.geometries.clear();\n }\n\n /**\n * Registers a geometry.\n * @param id The ID of the geometry to register.\n * @param geometry The geometry to register.\n */\n registerGeometry(id: string, geometry: THREE.BufferGeometry) {\n const previous = this.geometries.get(id);\n\n if (previous) {\n if (previous === geometry) {\n return;\n }\n }\n\n // finally, we are attaching uvRefs.\n const uvRefs = this.createUVRefs(this.size);\n geometry.setAttribute('uvRef', uvRefs);\n\n this.geometries.set(id, geometry);\n\n if (this.mesh.geometry === previous) {\n this.mesh.geometry = geometry;\n }\n\n previous?.dispose();\n }\n\n setOriginColor(color: THREE.ColorRepresentation) {\n this.disposeSolidColorOriginTexture();\n this.originColor = color;\n this.uniforms.uOriginTexture.value = this.createSolidColorDataTexture(color);\n }\n\n setDestinationColor(color: THREE.ColorRepresentation) {\n this.disposeSolidColorDestinationTexture();\n this.destinationColor = color;\n this.uniforms.uDestinationTexture.value = this.createSolidColorDataTexture(color);\n }\n\n /**\n * Gets the UV references for the specified size.\n * @param size The size for which to generate UV references.\n * @returns The UV references.\n */\n private createUVRefs(size: number) {\n const cached = this.uvRefsCache.get(size);\n\n if (cached) {\n return cached;\n }\n\n const uvRefs = new Float32Array(size * size * 2);\n\n for (let i = 0; i < size; i++) {\n for (let j = 0; j < size; j++) {\n const index = i * size + j;\n uvRefs[2 * index] = j / (size - 1);\n uvRefs[2 * index + 1] = i / (size - 1);\n }\n }\n\n const attr = new THREE.InstancedBufferAttribute(uvRefs, 2);\n\n this.uvRefsCache.set(size, attr);\n return attr;\n }\n\n /**\n * Creates a new instanced mesh.\n * @param size The size of the instanced mesh.\n * @param geometry The geometry to use for the instanced mesh.\n * @param material The material to use for the instanced mesh.\n * @returns The created instanced mesh.\n */\n private createInstancedMesh(size: number, geometry: THREE.BufferGeometry, material: THREE.Material | THREE.Material[]) {\n geometry = geometry || this.fallbackGeometry;\n geometry.setAttribute('uvRef', this.createUVRefs(size));\n const count = size * size;\n return new THREE.InstancedMesh(geometry, material, count);\n }\n\n private createSolidColorDataTexture(color: THREE.ColorRepresentation, size: number = 16): THREE.DataTexture {\n const col = new THREE.Color(color);\n const width = size;\n const height = size;\n const data = new Uint8Array(width * height * 4); // RGBA\n\n const r = Math.floor(col.r * 255);\n const g = Math.floor(col.g * 255);\n const b = Math.floor(col.b * 255);\n\n for (let i = 0; i < width * height; i++) {\n const index = i * 4;\n data[index] = r;\n data[index + 1] = g;\n data[index + 2] = b;\n data[index + 3] = 255; // Alpha\n }\n\n const texture = new THREE.DataTexture(data, width, height, THREE.RGBAFormat);\n texture.type = THREE.UnsignedByteType;\n texture.wrapS = THREE.RepeatWrapping; // Or ClampToEdgeWrapping\n texture.wrapT = THREE.RepeatWrapping; // Or ClampToEdgeWrapping\n texture.minFilter = THREE.NearestFilter; // Ensure sharp color\n texture.magFilter = THREE.NearestFilter;\n texture.needsUpdate = true;\n return texture;\n }\n\n private disposeSolidColorOriginTexture() {\n if (this.originColor) {\n this.originColor = null;\n if (this.uniforms.uOriginTexture.value) {\n this.uniforms.uOriginTexture.value.dispose();\n }\n }\n }\n\n private disposeSolidColorDestinationTexture() {\n if (this.destinationColor) {\n this.destinationColor = null;\n if (this.uniforms.uDestinationTexture.value) {\n this.uniforms.uDestinationTexture.value.dispose();\n }\n }\n }\n}\n","export default `\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform sampler2D uVelocity;\nuniform float uTime;\nvarying vec3 vNormal;\nattribute vec2 uvRef;\nvarying vec3 vViewPosition;\n\nvec3 rotate3D(vec3 v, vec3 vel) {\n vec3 pos = v;\n vec3 up = vec3(0, 1, 0);\n vec3 axis = normalize(cross(up, vel));\n float angle = acos(dot(up, normalize(vel)));\n pos = pos * cos(angle) + cross(axis, pos) * sin(angle) + axis * dot(axis, pos) * (1. - cos(angle));\n return pos;\n}\n\nvoid main() {\n vUv = uv;\n vNormal = normal;\n\n vec4 color = texture2D(uTexture, uvRef);\n vec4 velocity = texture2D(uVelocity, uvRef);\n vec3 pos = color.xyz;// apply the texture to the vertex distribution.\n\n vec3 localPosition = position.xyz;\n if (length (velocity.xyz) < 0.0001) {\n velocity.xyz = vec3(0.0, 0.0001, 0.0001);\n }\n localPosition.y *= max(1.0, length(velocity.xyz) * 1000.0);\n localPosition = rotate3D(localPosition, velocity.xyz);\n vNormal = rotate3D(normal, velocity.xyz);\n\n mat4 instanceMat = instanceMatrix;\n instanceMat[3].xyz = pos.xyz;\n\n // unlike the traditional mvMatrix * position, we need to additional multiplication with the instance matrix.\n vec4 modelViewPosition = modelViewMatrix * instanceMat * vec4(localPosition, 1.0);\n\n vViewPosition = - modelViewPosition.xyz;\n\n gl_Position = projectionMatrix * modelViewPosition;\n}\n`;\n","export default `\nvarying vec2 vUv;\nuniform sampler2D uTexture;\n\nuniform sampler2D uOriginTexture;\nuniform sampler2D uDestinationTexture;\n\nuniform float uProgress;\nvarying vec3 vNormal;\nvarying vec3 vViewPosition;\nvoid main() {\n vec3 viewDir = normalize( vViewPosition );\n vec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n vec3 y = cross( viewDir, x );\n vec2 uv = vec2( dot( x, vNormal ), dot( y, vNormal ) ) * 0.495 + 0.5; // 0.495 to remove artifacts caused by undersized matcap disks\n\n vec4 sourceMatcap = texture2D( uOriginTexture, uv );\n vec4 targetMatcap = texture2D( uDestinationTexture, uv );\n\n vec4 matcap = mix(sourceMatcap, targetMatcap, uProgress);\n gl_FragColor = matcap;\n}\n`;\n","import { DefaultEventEmitter, EngineEventEmitter, Events } from '@/lib/events';\nimport * as THREE from 'three';\n\n/**\n * Service for calculating intersections between a ray and a morphed geometry.\n */\nexport class IntersectionService {\n private active: boolean = true;\n\n private raycaster = new THREE.Raycaster();\n private mousePosition = new THREE.Vector2();\n\n private camera?: THREE.Camera;\n private originGeometry?: THREE.BufferGeometry;\n private destinationGeometry?: THREE.BufferGeometry;\n\n private progress: number = 0;\n private intersectionMesh = new THREE.Mesh();\n\n private geometryNeedsUpdate: boolean;\n private eventEmitter: EngineEventEmitter<Events>;\n\n private blendedGeometry?: THREE.BufferGeometry;\n private intersection?: THREE.Vector4;\n\n private lastKnownOriginMeshID?: string;\n private lastKnownDestinationMeshID?: string;\n /**\n * Creates a new IntersectionService instance.\n * @param eventEmitter The event emitter used for emitting events.\n * @param camera The camera used for raycasting.\n * @param originGeometry The origin geometry.\n * @param destinationGeometry The destination geometry.\n */\n constructor(eventEmitter: DefaultEventEmitter, camera?: THREE.Camera, originGeometry?: THREE.BufferGeometry, destinationGeometry?: THREE.BufferGeometry) {\n this.camera = camera;\n this.originGeometry = originGeometry;\n this.eventEmitter = eventEmitter;\n this.destinationGeometry = destinationGeometry;\n this.geometryNeedsUpdate = true;\n }\n\n setActive(active: boolean) {\n this.active = active;\n }\n\n getIntersectionMesh(): THREE.Mesh {\n return this.intersectionMesh;\n }\n\n /**\n * Set the camera used for raycasting.\n * @param camera\n */\n setCamera(camera: THREE.Camera) {\n this.camera = camera;\n }\n\n /**\n * Set the origin geometry.\n * @param source\n */\n setOriginGeometry(source: THREE.Mesh) {\n if (this.lastKnownOriginMeshID === source.uuid) return;\n // dispose the previous geometry\n if (this.originGeometry) this.originGeometry.dispose();\n\n this.lastKnownOriginMeshID = source.uuid;\n // we need to clone the geometry because we are going to modify it.\n this.originGeometry = source.geometry.clone();\n this.originGeometry.applyMatrix4(source.matrixWorld);\n this.geometryNeedsUpdate = true;\n }\n\n /**\n * Set the destination geometry.\n * @param source\n */\n setDestinationGeometry(source: THREE.Mesh) {\n if (this.lastKnownDestinationMeshID === source.uuid) return;\n // dispose the previous geometry\n if (this.destinationGeometry) this.destinationGeometry.dispose();\n\n this.lastKnownDestinationMeshID = source.uuid;\n // we need to clone the geometry because we are going to modify it.\n this.destinationGeometry = source.geometry.clone();\n this.destinationGeometry.applyMatrix4(source.matrixWorld);\n\n this.geometryNeedsUpdate = true;\n }\n\n /**\n * Set the progress of the morphing animation.\n * @param progress\n */\n setProgress(progress: number) {\n this.progress = progress;\n this.geometryNeedsUpdate = true;\n }\n\n /**\n * Set the mouse position.\n * @param mousePosition\n */\n setPointerPosition(mousePosition?: THREE.Vector2Like) {\n if (mousePosition) this.mousePosition.copy(mousePosition);\n }\n\n /**\n * Calculate the intersection.\n * @returns The intersection point or undefined if no intersection was found.\n */\n calculate(instancedMesh: THREE.Mesh): THREE.Vector4 | undefined {\n if (!this.active) return;\n this.updateIntersectionMesh(instancedMesh);\n\n if (!this.camera) return;\n if (this.geometryNeedsUpdate) {\n this.geometryNeedsUpdate = false;\n this.blendedGeometry = this.getBlendedGeometry();\n }\n\n if (this.blendedGeometry) {\n this.intersection = this.getFirstIntersection(this.camera, instancedMesh);\n } else {\n this.intersection = undefined;\n }\n\n if (this.intersection) {\n this.eventEmitter.emit('interactionPositionUpdated', { position: this.intersection });\n } else {\n this.eventEmitter.emit('interactionPositionUpdated', { position: { x: 0, y: 0, z: 0, w: 0 } });\n }\n\n return this.intersection;\n }\n\n /**\n * Dispose the resources used by the IntersectionService.\n */\n dispose() {\n this.blendedGeometry?.dispose();\n this.intersectionMesh.geometry.dispose();\n }\n\n private updateIntersectionMesh(instancedMesh: THREE.Mesh) {\n if (this.blendedGeometry) {\n if (this.blendedGeometry.uuid !== this.intersectionMesh.geometry.uuid) {\n this.intersectionMesh.geometry.dispose();\n this.intersectionMesh.geometry = this.blendedGeometry;\n }\n }\n this.intersectionMesh.matrix.copy(instancedMesh.matrixWorld);\n this.intersectionMesh.matrixWorld.copy(instancedMesh.matrixWorld);\n this.intersectionMesh.matrixAutoUpdate = false;\n this.intersectionMesh.updateMatrixWorld(true);\n }\n\n private getFirstIntersection(camera: THREE.Camera, instancedMesh: THREE.Mesh) {\n this.raycaster.setFromCamera(this.mousePosition, camera);\n\n const intersection = this.raycaster.intersectObject(this.intersectionMesh, false)[0];\n if (intersection) {\n const worldPoint = intersection.point.clone();\n const localPoint = instancedMesh.worldToLocal(worldPoint);\n return new THREE.Vector4(localPoint.x, localPoint.y, localPoint.z, 1);\n }\n }\n\n private getBlendedGeometry() {\n if (this.progress === 0) {\n return this.originGeometry;\n }\n if (this.progress === 1) {\n return this.destinationGeometry;\n }\n\n if (!this.originGeometry || !this.destinationGeometry) {\n return;\n }\n\n if (this.originGeometry === this.destinationGeometry) {\n // if same, just return one of them\n return this.originGeometry;\n }\n\n return this.blendGeometry(this.originGeometry, this.destinationGeometry, this.progress);\n }\n\n private blendGeometry(from: THREE.BufferGeometry, to: THREE.BufferGeometry, progress: number): THREE.BufferGeometry {\n const blended = new THREE.BufferGeometry();\n const originPositions = from.attributes.position.array;\n const destinationPositions = to.attributes.position.array;\n const blendedPositions = new Float32Array(originPositions.length);\n\n for (let i = 0; i < originPositions.length; i += 3) {\n const originVert = new THREE.Vector3(originPositions[i], originPositions[i + 1], originPositions[i + 2]);\n const destinationVert = new THREE.Vector3(destinationPositions[i], destinationPositions[i + 1], destinationPositions[i + 2]);\n const blendedVert = new THREE.Vector3().lerpVectors(originVert, destinationVert, progress);\n\n blendedPositions[i] = blendedVert.x;\n blendedPositions[i + 1] = blendedVert.y;\n blendedPositions[i + 2] = blendedVert.z;\n }\n\n blended.setAttribute('position', new THREE.BufferAttribute(blendedPositions, 3));\n\n if (from.attributes.normal) blended.setAttribute('normal', from.attributes.normal.clone());\n if (from.attributes.uv) blended.setAttribute('uv', from.attributes.uv.clone());\n if (from.index) blended.setIndex(from.index.clone());\n\n return blended;\n }\n}\n","import {\n\tBufferGeometry,\n\tFloat32BufferAttribute,\n\tOrthographicCamera,\n\tMesh\n} from 'three';\n\nclass Pass {\n\n\tconstructor() {\n\n\t\tthis.isPass = true;\n\n\t\t// if set to true, the pass is processed by the composer\n\t\tthis.enabled = true;\n\n\t\t// if set to true, the pass indicates to swap read and write buffer after rendering\n\t\tthis.needsSwap = true;\n\n\t\t// if set to true, the pass clears its buffer before rendering\n\t\tthis.clear = false;\n\n\t\t// if set to true, the result of the pass is rendered to screen. This is set automatically by EffectComposer.\n\t\tthis.renderToScreen = false;\n\n\t}\n\n\tsetSize( /* width, height */ ) {}\n\n\trender( /* renderer, writeBuffer, readBuffer, deltaTime, maskActive */ ) {\n\n\t\tconsole.error( 'THREE.Pass: .render() must be implemented in derived pass.' );\n\n\t}\n\n\tdispose() {}\n\n}\n\n// Helper for passes that need to fill the viewport with a single quad.\n\nconst _camera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );\n\n// https://github.com/mrdoob/three.js/pull/21358\n\nclass FullscreenTriangleGeometry extends BufferGeometry {\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\tthis.setAttribute( 'position', new Float32BufferAttribute( [ - 1, 3, 0, - 1, - 1, 0, 3, - 1, 0 ], 3 ) );\n\t\tthis.setAttribute( 'uv', new Float32BufferAttribute( [ 0, 2, 0, 0, 2, 0 ], 2 ) );\n\n\t}\n\n}\n\nconst _geometry = new FullscreenTriangleGeometry();\n\nclass FullScreenQuad {\n\n\tconstructor( material ) {\n\n\t\tthis._mesh = new Mesh( _geometry, material );\n\n\t}\n\n\tdispose() {\n\n\t\tthis._mesh.geometry.dispose();\n\n\t}\n\n\trender( renderer ) {\n\n\t\trenderer.render( this._mesh, _camera );\n\n\t}\n\n\tget material() {\n\n\t\treturn this._mesh.material;\n\n\t}\n\n\tset material( value ) {\n\n\t\tthis._mesh.material = value;\n\n\t}\n\n}\n\nexport { Pass, FullScreenQuad };\n","import {\n\tClampToEdgeWrapping,\n\tDataTexture,\n\tFloatType,\n\tNearestFilter,\n\tRGBAFormat,\n\tShaderMaterial,\n\tWebGLRenderTarget\n} from 'three';\n\nimport { FullScreenQuad } from '../postprocessing/Pass.js';\n\n/**\n * GPUComputationRenderer, based on SimulationRenderer by zz85\n *\n * The GPUComputationRenderer uses the concept of variables. These variables are RGBA float textures that hold 4 floats\n * for each compute element (texel)\n *\n * Each variable has a fragment shader that defines the computation made to obtain the variable in question.\n * You can use as many variables you need, and make dependencies so you can use textures of other variables in the shader\n * (the sampler uniforms are added automatically) Most of the variables will need themselves as dependency.\n *\n * The renderer has actually two render targets per variable, to make ping-pong. Textures from the current frame are used\n * as inputs to render the textures of the next frame.\n *\n * The render targets of the variables can be used as input textures for your visualization shaders.\n *\n * Variable names should be valid identifiers and should not collide with THREE GLSL used identifiers.\n * a common approach could be to use 'texture' prefixing the variable name; i.e texturePosition, textureVelocity...\n *\n * The size of the computation (sizeX * sizeY) is defined as 'resolution' automatically in the shader. For example:\n * #DEFINE resolution vec2( 1024.0, 1024.0 )\n *\n * -------------\n *\n * Basic use:\n *\n * // Initialization...\n *\n * // Create computation renderer\n * const gpuCompute = new GPUComputationRenderer( 1024, 1024, renderer );\n *\n * // Create initial state float textures\n * const pos0 = gpuCompute.createTexture();\n * const vel0 = gpuCompute.createTexture();\n * // and fill in here the texture data...\n *\n * // Add texture variables\n * const velVar = gpuCompute.addVariable( \"textureVelocity\", fragmentShaderVel, vel0 );\n * const posVar = gpuCompute.addVariable( \"texturePosition\", fragmentShaderPos, pos0 );\n *\n * // Add variable dependencies\n * gpuCompute.setVariableDependencies( velVar, [ velVar, posVar ] );\n * gpuCompute.setVariableDependencies( posVar, [ velVar, posVar ] );\n *\n * // Add custom uniforms\n * velVar.material.uniforms.time = { value: 0.0 };\n *\n * // Check for completeness\n * const error = gpuCompute.init();\n * if ( error !== null ) {\n *\t\tconsole.error( error );\n * }\n *\n *\n * // In each frame...\n *\n * // Compute!\n * gpuCompute.compute();\n *\n * // Update texture uniforms in your visualization materials with the gpu renderer output\n * myMaterial.uniforms.myTexture.value = gpuCompute.getCurrentRenderTarget( posVar ).texture;\n *\n * // Do your rendering\n * renderer.render( myScene, myCamera );\n *\n * -------------\n *\n * Also, you can use utility functions to create ShaderMaterial and perform computations (rendering between textures)\n * Note that the shaders can have multiple input textures.\n *\n * const myFilter1 = gpuCompute.createShaderMaterial( myFilterFragmentShader1, { theTexture: { value: null } } );\n * const myFilter2 = gpuCompute.createShaderMaterial( myFilterFragmentShader2, { theTexture: { value: null } } );\n *\n * const inputTexture = gpuCompute.createTexture();\n *\n * // Fill in here inputTexture...\n *\n * myFilter1.uniforms.theTexture.value = inputTexture;\n *\n * const myRenderTarget = gpuCompute.createRenderTarget();\n * myFilter2.uniforms.theTexture.value = myRenderTarget.texture;\n *\n * const outputRenderTarget = gpuCompute.createRenderTarget();\n *\n * // Now use the output texture where you want:\n * myMaterial.uniforms.map.value = outputRenderTarget.texture;\n *\n * // And compute each frame, before rendering to screen:\n * gpuCompute.doRenderTarget( myFilter1, myRenderTarget );\n * gpuCompute.doRenderTarget( myFilter2, outputRenderTarget );\n */\n\nclass GPUComputationRenderer {\n\n\t/**\n\t * @param {Number} sizeX Computation problem size is always 2d: sizeX * sizeY elements.\n \t * @param {Number} sizeY Computation problem size is always 2d: sizeX * sizeY elements.\n \t * @param {WebGLRenderer} renderer The renderer\n\t */\n\tconstructor( sizeX, sizeY, renderer ) {\n\n\t\tthis.variables = [];\n\n\t\tthis.currentTextureIndex = 0;\n\n\t\tlet dataType = FloatType;\n\n\t\tconst passThruUniforms = {\n\t\t\tpassThruTexture: { value: null }\n\t\t};\n\n\t\tconst passThruShader = createShaderMaterial( getPassThroughFragmentShader(), passThruUniforms );\n\n\t\tconst quad = new FullScreenQuad( passThruShader );\n\n\t\tthis.setDataType = function ( type ) {\n\n\t\t\tdataType = type;\n\t\t\treturn this;\n\n\t\t};\n\n\t\tthis.addVariable = function ( variableName, computeFragmentShader, initialValueTexture ) {\n\n\t\t\tconst material = this.createShaderMaterial( computeFragmentShader );\n\n\t\t\tconst variable = {\n\t\t\t\tname: variableName,\n\t\t\t\tinitialValueTexture: initialValueTexture,\n\t\t\t\tmaterial: material,\n\t\t\t\tdependencies: null,\n\t\t\t\trenderTargets: [],\n\t\t\t\twrapS: null,\n\t\t\t\twrapT: null,\n\t\t\t\tminFilter: NearestFilter,\n\t\t\t\tmagFilter: NearestFilter\n\t\t\t};\n\n\t\t\tthis.variables.push( variable );\n\n\t\t\treturn variable;\n\n\t\t};\n\n\t\tthis.setVariableDependencies = function ( variable, dependencies ) {\n\n\t\t\tvariable.dependencies = dependencies;\n\n\t\t};\n\n\t\tthis.init = function () {\n\n\t\t\tif ( renderer.capabilities.maxVertexTextures === 0 ) {\n\n\t\t\t\treturn 'No support for vertex shader textures.';\n\n\t\t\t}\n\n\t\t\tfor ( let i = 0; i < this.variables.length; i ++ ) {\n\n\t\t\t\tconst variable = this.variables[ i ];\n\n\t\t\t\t// Creates rendertargets and initialize them with input texture\n\t\t\t\tvariable.renderTargets[ 0 ] = this.createRenderTarget( sizeX, sizeY, variable.wrapS, variable.wrapT, variable.minFilter, variable.magFilter );\n\t\t\t\tvariable.renderTargets[ 1 ] = this.createRenderTarget( sizeX, sizeY, variable.wrapS, variable.wrapT, variable.minFilter, variable.magFilter );\n\t\t\t\tthis.renderTexture( variable.initialValueTexture, variable.renderTargets[ 0 ] );\n\t\t\t\tthis.renderTexture( variable.initialValueTexture, variable.renderTargets[ 1 ] );\n\n\t\t\t\t// Adds dependencies uniforms to the ShaderMaterial\n\t\t\t\tconst material = variable.material;\n\t\t\t\tconst uniforms = material.uniforms;\n\n\t\t\t\tif ( variable.dependencies !== null ) {\n\n\t\t\t\t\tfor ( let d = 0; d < variable.dependencies.length; d ++ ) {\n\n\t\t\t\t\t\tconst depVar = variable.dependencies[ d ];\n\n\t\t\t\t\t\tif ( depVar.name !== variable.name ) {\n\n\t\t\t\t\t\t\t// Checks if variable exists\n\t\t\t\t\t\t\tlet found = false;\n\n\t\t\t\t\t\t\tfor ( let j = 0; j < this.variables.length; j ++ ) {\n\n\t\t\t\t\t\t\t\tif ( depVar.name === this.variables[ j ].name ) {\n\n\t\t\t\t\t\t\t\t\tfound = true;\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( ! found ) {\n\n\t\t\t\t\t\t\t\treturn 'Variable dependency not found. Variable=' + variable.name + ', dependency=' + depVar.name;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tuniforms[ depVar.name ] = { value: null };\n\n\t\t\t\t\t\tmaterial.fragmentShader = '\\nuniform sampler2D ' + depVar.name + ';\\n' + material.fragmentShader;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.currentTextureIndex = 0;\n\n\t\t\treturn null;\n\n\t\t};\n\n\t\tthis.compute = function () {\n\n\t\t\tconst currentTextureIndex = this.currentTextureIndex;\n\t\t\tconst nextTextureIndex = this.currentTextureIndex === 0 ? 1 : 0;\n\n\t\t\tfor ( let i = 0, il = this.variables.length; i < il; i ++ ) {\n\n\t\t\t\tconst variable = this.variables[ i ];\n\n\t\t\t\t// Sets texture dependencies uniforms\n\t\t\t\tif ( variable.dependencies !== null ) {\n\n\t\t\t\t\tconst uniforms = variable.material.uniforms;\n\n\t\t\t\t\tfor ( let d = 0, dl = variable.dependencies.length; d < dl; d ++ ) {\n\n\t\t\t\t\t\tconst depVar = variable.dependencies[ d ];\n\n\t\t\t\t\t\tuniforms[ depVar.name ].value = depVar.renderTargets[ currentTextureIndex ].texture;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// Performs the computation for this variable\n\t\t\t\tthis.doRenderTarget( variable.material, variable.renderTargets[ nextTextureIndex ] );\n\n\t\t\t}\n\n\t\t\tthis.currentTextureIndex = nextTextureIndex;\n\n\t\t};\n\n\t\tthis.getCurrentRenderTarget = function ( variable ) {\n\n\t\t\treturn variable.renderTargets[ this.currentTextureIndex ];\n\n\t\t};\n\n\t\tthis.getAlternateRenderTarget = function ( variable ) {\n\n\t\t\treturn variable.renderTargets[ this.currentTextureIndex === 0 ? 1 : 0 ];\n\n\t\t};\n\n\t\tthis.dispose = function () {\n\n\t\t\tquad.dispose();\n\n\t\t\tconst variables = this.variables;\n\n\t\t\tfor ( let i = 0; i < variables.length; i ++ ) {\n\n\t\t\t\tconst variable = variables[ i ];\n\n\t\t\t\tif ( variable.initialValueTexture ) variable.initialValueTexture.dispose();\n\n\t\t\t\tconst renderTargets = variable.renderTargets;\n\n\t\t\t\tfor ( let j = 0; j < renderTargets.length; j ++ ) {\n\n\t\t\t\t\tconst renderTarget = renderTargets[ j ];\n\t\t\t\t\trenderTarget.dispose();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\tfunction addResolutionDefine( materialShader ) {\n\n\t\t\tmaterialShader.defines.resolution = 'vec2( ' + sizeX.toFixed( 1 ) + ', ' + sizeY.toFixed( 1 ) + ' )';\n\n\t\t}\n\n\t\tthis.addResolutionDefine = addResolutionDefine;\n\n\n\t\t// The following functions can be used to compute things manually\n\n\t\tfunction createShaderMaterial( computeFragmentShader, uniforms ) {\n\n\t\t\tuniforms = uniforms || {};\n\n\t\t\tconst material = new ShaderMaterial( {\n\t\t\t\tname: 'GPUComputationShader',\n\t\t\t\tuniforms: uniforms,\n\t\t\t\tvertexShader: getPassThroughVertexShader(),\n\t\t\t\tfragmentShader: computeFragmentShader\n\t\t\t} );\n\n\t\t\taddResolutionDefine( material );\n\n\t\t\treturn material;\n\n\t\t}\n\n\t\tthis.createShaderMaterial = createShaderMaterial;\n\n\t\tthis.createRenderTarget = function ( sizeXTexture, sizeYTexture, wrapS, wrapT, minFilter, magFilter ) {\n\n\t\t\tsizeXTexture = sizeXTexture || sizeX;\n\t\t\tsizeYTexture = sizeYTexture || sizeY;\n\n\t\t\twrapS = wrapS || ClampToEdgeWrapping;\n\t\t\twrapT = wrapT || ClampToEdgeWrapping;\n\n\t\t\tminFilter = minFilter || NearestFilter;\n\t\t\tmagFilter = magFilter || NearestFilter;\n\n\t\t\tconst renderTarget = new WebGLRenderTarget( sizeXTexture, sizeYTexture, {\n\t\t\t\twrapS: wrapS,\n\t\t\t\twrapT: wrapT,\n\t\t\t\tminFilter: minFilter,\n\t\t\t\tmagFilter: magFilter,\n\t\t\t\tformat: RGBAFormat,\n\t\t\t\ttype: dataType,\n\t\t\t\tdepthBuffer: false\n\t\t\t} );\n\n\t\t\treturn renderTarget;\n\n\t\t};\n\n\t\tthis.createTexture = function () {\n\n\t\t\tconst data = new Float32Array( sizeX * sizeY * 4 );\n\t\t\tconst texture = new DataTexture( data, sizeX, sizeY, RGBAFormat, FloatType );\n\t\t\ttexture.needsUpdate = true;\n\t\t\treturn texture;\n\n\t\t};\n\n\t\tthis.renderTexture = function ( input, output ) {\n\n\t\t\t// Takes a texture, and render out in rendertarget\n\t\t\t// input = Texture\n\t\t\t// output = RenderTarget\n\n\t\t\tpassThruUniforms.passThruTexture.value = input;\n\n\t\t\tthis.doRenderTarget( passThruShader, output );\n\n\t\t\tpassThruUniforms.passThruTexture.value = null;\n\n\t\t};\n\n\t\tthis.doRenderTarget = function ( material, output ) {\n\n\t\t\tconst currentRenderTarget = renderer.getRenderTarget();\n\n\t\t\tconst currentXrEnabled = renderer.xr.enabled;\n\t\t\tconst currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;\n\n\t\t\trenderer.xr.enabled = false; // Avoid camera modification\n\t\t\trenderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows\n\t\t\tquad.material = material;\n\t\t\trenderer.setRenderTarget( output );\n\t\t\tquad.render( renderer );\n\t\t\tquad.material = passThruShader;\n\n\t\t\trenderer.xr.enabled = currentXrEnabled;\n\t\t\trenderer.shadowMap.autoUpdate = currentShadowAutoUpdate;\n\n\t\t\trenderer.setRenderTarget( currentRenderTarget );\n\n\t\t};\n\n\t\t// Shaders\n\n\t\tfunction getPassThroughVertexShader() {\n\n\t\t\treturn\t'void main()\t{\\n' +\n\t\t\t\t\t'\\n' +\n\t\t\t\t\t'\tgl_Position = vec4( position, 1.0 );\\n' +\n\t\t\t\t\t'\\n' +\n\t\t\t\t\t'}\\n';\n\n\t\t}\n\n\t\tfunction getPassThroughFragmentShader() {\n\n\t\t\treturn\t'uniform sampler2D passThruTexture;\\n' +\n\t\t\t\t\t'\\n' +\n\t\t\t\t\t'void main() {\\n' +\n\t\t\t\t\t'\\n' +\n\t\t\t\t\t'\tvec2 uv = gl_FragCoord.xy / resolution.xy;\\n' +\n\t\t\t\t\t'\\n' +\n\t\t\t\t\t'\tgl_FragColor = texture2D( passThruTexture, uv );\\n' +\n\t\t\t\t\t'\\n' +\n\t\t\t\t\t'}\\n';\n\n\t\t}\n\n\t}\n\n}\n\nexport { GPUComputationRenderer };\n","import { clamp, createBlankDataTexture, createSpherePoints } from '@/lib/utils';\nimport * as THREE from 'three';\nimport { GPUComputationRenderer, Variable } from 'three/examples/jsm/misc/GPUComputationRenderer.js';\nimport mixShader from './shaders/simulationMixShader';\nimport positionShader from './shaders/simulationPositionShader';\nimport velocityShader from './shaders/simulationVelocityShader';\n\n/**\n * SimulationRenderer is responsible for running the particle simulation using the GPU.\n */\nexport class SimulationRenderer {\n gpuComputationRenderer: GPUComputationRenderer;\n webGLRenderer: THREE.WebGLRenderer;\n\n // calculations\n private readonly positionDataTexture: THREE.DataTexture;\n private readonly velocityDataTexture: THREE.DataTexture;\n\n // GPUComputationRenderer variables\n private readonly mixPositionsVar: Variable;\n private readonly velocityVar: Variable;\n private readonly positionVar: Variable;\n\n readonly interactionPosition: THREE.Vector4;\n\n private lastKnownPositionDataTexture: THREE.Texture;\n private lastKnownVelocityDataTexture: THREE.Texture;\n private lastKnownMixProgress: number;\n\n private readonly initialDataTexture: THREE.DataTexture;\n\n /**\n * Creates a new SimulationRenderer instance.\n * @param size The size of the simulation textures.\n * @param webGLRenderer The WebGL renderer.\n * @param initialPosition The initial position data texture. If not provided, a default sphere will be used.\n */\n constructor(size: number, webGLRenderer: THREE.WebGLRenderer, initialPosition?: THREE.DataTexture) {\n this.initialDataTexture = initialPosition ?? createSpherePoints(size);\n this.positionDataTexture = this.initialDataTexture;\n\n this.webGLRenderer = webGLRenderer;\n this.gpuComputationRenderer = new GPUComputationRenderer(size, size, this.webGLRenderer);\n this.lastKnownMixProgress = 0;\n\n if (!webGLRenderer.capabilities.isWebGL2) {\n this.gpuComputationRenderer.setDataType(THREE.HalfFloatType);\n }\n\n this.velocityDataTexture = createBlankDataTexture(size);\n this.interactionPosition = new THREE.Vector4(0, 0, 0, 0);\n\n // init gpgpu render target textures.\n this.mixPositionsVar = this.gpuComputationRenderer.addVariable('uMixedPosition', mixShader, this.positionDataTexture);\n this.velocityVar = this.gpuComputationRenderer.addVariable('uCurrentVelocity', velocityShader, this.velocityDataTexture);\n this.positionVar = this.gpuComputationRenderer.addVariable('uCurrentPosition', positionShader, this.positionDataTexture);\n\n // attach uniforms\n this.mixPositionsVar.material.uniforms.uProgress = { value: 0 };\n this.mixPositionsVar.material.uniforms.uPositionA = { value: this.initialDataTexture };\n this.mixPositionsVar.material.uniforms.uPositionB = { value: this.initialDataTexture };\n\n this.velocityVar.material.uniforms.uTime = { value: 0 };\n this.velocityVar.material.uniforms.uInteractionPosition = { value: this.interactionPosition };\n this.velocityVar.material.uniforms.uCurrentPosition = { value: this.positionDataTexture };\n this.velocityVar.material.uniforms.uTractionForce = { value: 0.1 };\n this.velocityVar.material.uniforms.uMaxRepelDistance = { value: 0.3 };\n\n this.positionVar.material.uniforms.uTime = { value: 0 };\n this.positionVar.material.uniforms.uProgress = { value: 0 };\n this.positionVar.material.uniforms.uTractionForce = { value: 0.1 };\n this.positionVar.material.uniforms.uInteractionPosition = { value: this.interactionPosition };\n this.positionVar.material.uniforms.uCurrentPosition = { value: this.positionDataTexture };\n\n this.gpuComputationRenderer.setVariableDependencies(this.positionVar, [this.velocityVar, this.positionVar, this.mixPositionsVar]);\n this.gpuComputationRenderer.setVariableDependencies(this.velocityVar, [this.velocityVar, this.positionVar, this.mixPositionsVar]);\n\n const err = this.gpuComputationRenderer.init();\n if (err) {\n throw new Error('failed to initialize SimulationRenderer: ' + err);\n }\n\n this.lastKnownVelocityDataTexture = this.getVelocityTexture();\n this.lastKnownPositionDataTexture = this.getPositionTexture();\n }\n\n /**\n * Sets the source data texture for morphing.\n * @param texture The source data texture.\n */\n setMorphSourceDataTexture(texture: THREE.DataTexture) {\n this.mixPositionsVar.material.uniforms.uPositionA.value = texture;\n }\n\n /**\n * Sets the destination data texture for morphing.\n * @param texture The destination data texture.\n */\n setMorphDestinationDataTexture(texture: THREE.DataTexture) {\n this.mixPositionsVar.material.uniforms.uPositionB.value = texture;\n }\n\n setMaxRepelDistance(distance: number) {\n this.velocityVar.material.uniforms.uMaxRepelDistance.value = distance;\n }\n\n /**\n * Sets the progress of the morphing animation.\n * @param progress The progress value, between 0 and 1.\n */\n setProgress(progress: number) {\n this.lastKnownMixProgress = clamp(progress, 0, 1);\n this.mixPositionsVar.material.uniforms.uProgress.value = this.lastKnownMixProgress;\n }\n\n setVelocityTractionForce(force: number) {\n this.velocityVar.material.uniforms.uTractionForce.value = force;\n }\n\n setPositionalTractionForce(force: number) {\n this.positionVar.material.uniforms.uTractionForce.value = force;\n }\n\n setInteractionPosition(position: THREE.Vector4Like) {\n this.interactionPosition.copy(position);\n }\n\n /**\n * Disposes the resources used by the simulation renderer.\n */\n dispose() {\n this.mixPositionsVar.renderTargets.forEach((rtt) => rtt.dispose());\n this.positionVar.renderTargets.forEach((rtt) => rtt.dispose());\n this.velocityVar.renderTargets.forEach((rtt) => rtt.dispose());\n\n this.positionDataTexture.dispose();\n this.velocityDataTexture.dispose();\n\n this.gpuComputationRenderer.dispose();\n }\n\n /**\n * Computes the next step of the simulation.\n * @param elapsedTime The elapsed time since the simulation started.\n */\n compute(elapsedTime: number) {\n this.velocityVar.material.uniforms.uTime.value = elapsedTime;\n this.positionVar.material.uniforms.uTime.value = elapsedTime;\n this.gpuComputationRenderer.compute();\n }\n\n /**\n * Gets the current velocity texture.\n * @returns The current velocity texture.\n */\n getVelocityTexture(): THREE.Texture {\n this.lastKnownVelocityDataTexture = this.gpuComputationRenderer.getCurrentRenderTarget(this.velocityVar).texture;\n return this.lastKnownVelocityDataTexture;\n }\n\n /**\n * Gets the current position texture.\n * @returns The current position texture.\n */\n getPositionTexture(): THREE.Texture {\n this.lastKnownPositionDataTexture = this.gpuComputationRenderer.getCurrentRenderTarget(this.positionVar).texture;\n return this.lastKnownPositionDataTexture;\n }\n}\n","export default `\nuniform sampler2D uPositionA;\nuniform sampler2D uPositionB;\nuniform float uProgress;\n\nvoid main() {\n vec2 uv = gl_FragCoord.xy / resolution.xy;\n vec3 positionA = texture2D(uPositionA, uv).xyz;\n vec3 positionB = texture2D(uPositionB, uv).xyz;\n vec3 mixedPosition = mix(positionA, positionB, uProgress);\n gl_FragColor = vec4(mixedPosition, 1.0);\n}\n`;\n","export default `\nuniform float uProgress;\nuniform vec4 uInteractionPosition;\nuniform float uTime;\nuniform float uTractionForce;\nuniform float uMaxRepelDistance;\n\nfloat rand(vec2 co) {\n return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453);\n}\n\nvoid main() {\n vec2 uv = gl_FragCoord.xy / resolution.xy;\n float offset = rand(uv);\n\n vec3 position = texture2D(uCurrentPosition, uv).xyz;\n vec3 velocity = texture2D(uCurrentVelocity, uv).xyz;\n vec3 mixedPosition = texture2D(uMixedPosition, uv).xyz;\n\n velocity *= 0.9;\n\n // particle traction\n vec3 direction = normalize(mixedPosition - position); // direction vector\n float dist = length ( mixedPosition - position ); // distance from where it was supposed to be, and currently are.\n if (dist > 0.01) {\n position += direction * 0.1 * uTractionForce; // uTractionForce defaults to 0.1\n }\n\n // mouse repel force\n float pointerDistance = distance(position, uInteractionPosition.xyz);\n float mouseRepelModifier = clamp(uMaxRepelDistance - pointerDistance, 0.0, 1.0);\n float normalizedDistance = pointerDistance / uMaxRepelDistance;\n float repulsionStrength = (1.0 - normalizedDistance) * uInteractionPosition.w;\n direction = normalize(position - uInteractionPosition.xyz);\n velocity += (direction * 0.01 * repulsionStrength) * mouseRepelModifier;\n\n float lifespan = 20.0;\n float age = mod(uTime + lifespan * offset, lifespan);\n\n if (age < 0.1) {\n position.xyz = mixedPosition;\n }\n\n gl_FragColor = vec4(velocity, 1.0);\n}\n`;\n","export default `\nuniform float uProgress;\nuniform vec4 uInteractionPosition;\nuniform float uTime;\nuniform float uTractionForce;\n\nfloat rand(vec2 co) {\n return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453);\n}\n\nvoid main() {\n\n // in GPGPU, we calculate the uv on each fragment shader, not using the static varying passed over from the v shader.\n vec2 uv = gl_FragCoord.xy / resolution.xy;\n float offset = rand(uv);\n\n vec3 position = texture2D(uCurrentPosition, uv).xyz;\n vec3 velocity = texture2D(uCurrentVelocity, uv).xyz;\n vec3 mixedPosition = texture2D(uMixedPosition, uv).xyz;\n\n // particle attraction to original position.\n vec3 direction = normalize(mixedPosition - position); // direction vector\n float dist = length ( mixedPosition - position ); // distance from where it was supposed to be, and currently are.\n\n if (dist > 0.01) {\n position = mix(position, mixedPosition, 0.1 * uTractionForce); // 0.1 ~ 0.001 (faster, slower)\n }\n\n position += velocity;\n gl_FragColor = vec4(position, 1.0);\n}\n`;\n","import { DefaultEventEmitter } from '@/lib/events';\nimport { DataTextureEntry, ServiceState } from '@/lib/types';\nimport * as THREE from 'three';\nimport { SimulationRenderer } from './simulationRenderer';\n\nexport class SimulationRendererService {\n private state!: ServiceState;\n private textureSize: number;\n private dataTextureTransitionProgress: number;\n private velocityTractionForce: number;\n private positionalTractionForce: number;\n\n private simulationRenderer;\n private webGLRenderer;\n private eventEmitter;\n\n private lastKnownVelocityDataTexture: THREE.Texture;\n private lastKnownPositionDataTexture: THREE.Texture;\n\n constructor(eventEmitter: DefaultEventEmitter, size: number, webGLRenderer: THREE.WebGLRenderer) {\n this.eventEmitter = eventEmitter;\n this.webGLRenderer = webGLRenderer;\n this.textureSize = size;\n this.dataTextureTransitionProgress = 0;\n this.velocityTractionForce = 0.1;\n this.positionalTractionForce = 0.1;\n\n this.updateServiceState('initializing');\n\n this.simulationRenderer = new SimulationRenderer(this.textureSize, this.webGLRenderer);\n this.lastKnownVelocityDataTexture = this.simulationRenderer.getVelocityTexture();\n this.lastKnownPositionDataTexture = this.simulationRenderer.getPositionTexture();\n\n this.updateServiceState('ready');\n }\n\n setTextureSize(size: number) {\n this.updateServiceState('initializing');\n this.simulationRenderer.dispose();\n this.textureSize = size;\n this.simulationRenderer = new SimulationRenderer(size, this.webGLRenderer);\n this.updateServiceState('ready');\n }\n\n setOriginDataTexture(entry: DataTextureEntry) {\n if (this.textureSize !== entry.textureSize) {\n this.eventEmitter.emit('invalidRequest', { message: `Texture size mismatch: ${entry.textureSize} vs ${this.textureSize}` });\n } else {\n this.simulationRenderer.setMorphSourceDataTexture(entry.dataTexture);\n }\n }\n\n setDestinationDataTexture(entry: DataTextureEntry) {\n if (this.textureSize !== entry.textureSize) {\n this.eventEmitter.emit('invalidRequest', { message: `Texture size mismatch: ${entry.textureSize} vs ${this.textureSize}` });\n } else {\n this.simulationRenderer.setMorphDestinationDataTexture(entry.dataTexture);\n }\n }\n\n setDataTextureTransitionProgress(progress: number) {\n this.dataTextureTransitionProgress = progress;\n this.simulationRenderer.setProgress(this.dataTextureTransitionProgress);\n }\n\n setVelocityTractionForce(force: number) {\n this.velocityTractionForce = force;\n this.simulationRenderer.setVelocityTractionForce(this.velocityTractionForce);\n }\n\n setPositionalTractionForce(force: number) {\n this.positionalTractionForce = force;\n this.simulationRenderer.setPositionalTractionForce(this.positionalTractionForce);\n }\n\n compute(elapsedTime: number) {\n this.simulationRenderer.compute(elapsedTime);\n }\n\n getVelocityTexture(): THREE.Texture {\n if (this.state === 'ready') this.lastKnownVelocityDataTexture = this.simulationRenderer.getVelocityTexture();\n return this.lastKnownVelocityDataTexture;\n }\n\n getPositionTexture(): THREE.Texture {\n if (this.state === 'ready') this.lastKnownPositionDataTexture = this.simulationRenderer.getPositionTexture();\n return this.lastKnownPositionDataTexture;\n }\n\n dispose() {\n this.updateServiceState('disposed');\n this.simulationRenderer.dispose();\n this.lastKnownVelocityDataTexture.dispose();\n this.lastKnownPositionDataTexture.dispose();\n }\n\n private updateServiceState(serviceState: ServiceState) {\n this.state = serviceState;\n this.eventEmitter.emit('serviceStateUpdated', { type: 'simulation', state: serviceState });\n }\n\n setInteractionPosition(position: THREE.Vector4Like) {\n this.simulationRenderer.setInteractionPosition(position);\n }\n\n setMaxRepelDistance(distance: number) {\n this.simulationRenderer.setMaxRepelDistance(distance);\n }\n}\n","import { DefaultEventEmitter } from '@/lib/events';\nimport { TransitionDetail, TransitionOptions, TransitionType } from '@/lib/types';\nimport { clamp } from '@/lib/utils';\n\ntype ExecStatus = 'idle' | 'running';\n\ntype TransitionQueueItem = { cancelled: boolean; startTime?: number } & TransitionDetail & TransitionOptions;\ntype OngoingTransition = { startTime: number } & TransitionQueueItem;\n\nclass ExecutionStatusMap {\n private readonly execStatus = new Map<TransitionType, ExecStatus>();\n\n get(type: TransitionType): ExecStatus {\n const status = this.execStatus.get(type);\n if (!status) {\n this.execStatus.set(type, 'idle');\n return 'idle';\n }\n return status;\n }\n\n set(type: TransitionType, status: ExecStatus) {\n this.execStatus.set(type, status);\n }\n}\n\nexport class TransitionService {\n private readonly eventEmitter;\n private readonly transitions: Map<TransitionType, Array<TransitionQueueItem>> = new Map();\n private readonly execStatus: ExecutionStatusMap;\n private readonly ongoingTransitions: Map<TransitionType, OngoingTransition> = new Map();\n\n constructor(eventEmitter: DefaultEventEmitter) {\n this.eventEmitter = eventEmitter;\n this.execStatus = new ExecutionStatusMap();\n this.eventEmitter.on('transitionCancelled', this.handleTransitionCancelledEvent.bind(this));\n }\n\n /**\n * Enqueues a transition.\n * @param type - The type of transition.\n * @param transition - The transition details.\n * @param options - Optional transition options.\n */\n enqueue<T extends TransitionType>(type: T, transition: TransitionDetail, options: TransitionOptions = {}) {\n const transitionQueueItem: TransitionQueueItem = {\n ...transition,\n ...options,\n cancelled: false,\n duration: transition.duration * 0.001, // convert to seconds\n };\n this.getQueue(type).push(transitionQueueItem);\n }\n\n compute(elapsedTime: number) {\n this.transitions.forEach((queue, type) => {\n if (queue.length && !this.ongoingTransitions.has(type)) {\n const transition = queue.shift();\n if (transition) {\n this.ongoingTransitions.set(type, { ...transition, startTime: elapsedTime });\n transition.onTransitionBegin?.();\n }\n }\n });\n\n this.ongoingTransitions.forEach((transition, type) => {\n if (transition.cancelled) {\n transition.onTransitionCancelled?.();\n this.ongoingTransitions.delete(type);\n return;\n }\n\n const { startTime, duration, easing } = transition;\n\n const timeDistance = elapsedTime - startTime;\n const progress = clamp(easing(Math.min(1.0, timeDistance / duration)), 0.0, 1.0);\n\n this.emitTransitionProgress(type, progress);\n transition.onTransitionProgress?.(progress);\n\n if (progress >= 1) {\n this.emitTransitionFinished(type);\n transition.onTransitionFinished?.();\n this.ongoingTransitions.delete(type);\n }\n });\n }\n\n private getQueue(type: TransitionType): Array<TransitionQueueItem> {\n const queue = this.transitions.get(type);\n if (!queue) {\n this.transitions.set(type, []);\n return this.transitions.get(type) ?? [];\n }\n return queue;\n }\n\n private handleTransitionCancelledEvent({ type }: { type: TransitionType }) {\n const transitions = this.getQueue(type);\n while (transitions.length) transitions.pop();\n\n const ongoingTransition = this.ongoingTransitions.get(type);\n if (ongoingTransition) {\n ongoingTransition.cancelled = true;\n ongoingTransition.onTransitionCancelled?.();\n }\n }\n\n private emitTransitionProgress(type: TransitionType, progress: number) {\n this.eventEmitter.emit('transitionProgressed', { type, progress });\n }\n\n private emitTransitionFinished(type: TransitionType) {\n this.eventEmitter.emit('transitionFinished', { type });\n }\n}\n","import { linear } from '@/lib/easing';\nimport { DefaultEventEmitter } from '@/lib/events/defaultEventEmitter';\nimport { AssetService } from '@/lib/services/assets/assetService';\nimport { DataTextureService } from '@/lib/services/dataTexture/dataTextureService';\nimport { InstancedMeshManager } from '@/lib/services/instancedmesh/instancedMeshManager';\nimport { IntersectionService } from '@/lib/services/intersection/intersectionService';\nimport { SimulationRendererService } from '@/lib/services/simulation/simulationRendererService';\nimport { TransitionService } from '@/lib/services/transition/transitionService';\nimport { EasingFunction, ServiceState, ServiceType, TransitionType } from '@/lib/types';\nimport { EngineState } from '@/lib/types/state';\nimport * as THREE from 'three';\n\n/**\n * Parameters for creating a ParticlesEngine instance.\n */\ntype ParticlesEngineParameters = {\n textureSize: number;\n scene: THREE.Scene;\n renderer: THREE.WebGLRenderer;\n camera?: THREE.Camera;\n useIntersection?: boolean;\n};\n\ntype ServiceStates = Record<ServiceType, ServiceState>;\n\n/**\n * The main class for the particle engine.\n */\nexport class ParticlesEngine {\n private simulationRendererService: SimulationRendererService;\n private eventEmitter: DefaultEventEmitter;\n private renderer: THREE.WebGLRenderer;\n\n private scene: THREE.Scene;\n private serviceStates: ServiceStates;\n\n // assets\n private assetService: AssetService;\n private dataTextureManager: DataTextureService;\n private instancedMeshManager: InstancedMeshManager;\n\n private transitionService: TransitionService;\n private engineState: EngineState;\n\n private intersectionService: IntersectionService;\n\n /**\n * Creates a new ParticlesEngine instance.\n * @param params The parameters for creating the instance.\n */\n constructor(params: ParticlesEngineParameters) {\n const { scene, renderer, camera, textureSize, useIntersection = true } = params;\n\n this.eventEmitter = new DefaultEventEmitter();\n this.serviceStates = this.getInitialServiceStates();\n this.eventEmitter.on('serviceStateUpdated', this.handleServiceStateUpdated.bind(this));\n\n this.scene = scene;\n this.renderer = renderer;\n this.engineState = this.initialEngineState(params);\n\n this.assetService = new AssetService(this.eventEmitter);\n this.transitionService = new TransitionService(this.eventEmitter);\n this.dataTextureManager = new DataTextureService(this.eventEmitter, textureSize);\n this.simulationRendererService = new SimulationRendererService(this.eventEmitter, textureSize, this.renderer);\n this.instancedMeshManager = new InstancedMeshManager(textureSize);\n this.instancedMeshManager.useMatcapMaterial();\n this.scene.add(this.instancedMeshManager.getMesh());\n\n this.intersectionService = new IntersectionService(this.eventEmitter, camera);\n if (!useIntersection) this.intersectionService.setActive(false);\n\n this.eventEmitter.on('transitionProgressed', this.handleTransitionProgress.bind(this));\n this.eventEmitter.on('interactionPositionUpdated', this.handleInteractionPositionUpdated.bind(this));\n }\n\n /**\n * Renders the scene.\n * @param elapsedTime The elapsed time since the last frame.\n */\n\n render(elapsedTime: number) {\n this.intersectionService.calculate(this.instancedMeshManager.getMesh());\n this.transitionService.compute(elapsedTime);\n this.simulationRendererService.compute(elapsedTime);\n this.instancedMeshManager.update(elapsedTime);\n this.instancedMeshManager.updateVelocityTexture(this.simulationRendererService.getVelocityTexture());\n this.instancedMeshManager.updatePositionTexture(this.simulationRendererService.getPositionTexture());\n }\n\n setOriginDataTexture(meshID: string, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'data-texture' });\n\n const mesh = this.assetService.getMesh(meshID);\n\n if (!mesh) {\n this.eventEmitter.emit('invalidRequest', { message: `Mesh with id \"${meshID}\" does not exist` });\n return;\n }\n\n this.dataTextureManager.getDataTexture(mesh).then((dataTexture) => {\n this.engineState.originMeshID = meshID;\n this.simulationRendererService.setOriginDataTexture({ dataTexture, textureSize: this.engineState.textureSize });\n this.intersectionService.setOriginGeometry(mesh);\n });\n }\n\n setDestinationDataTexture(meshID: string, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'data-texture' });\n\n const mesh = this.assetService.getMesh(meshID);\n\n if (!mesh) {\n this.eventEmitter.emit('invalidRequest', { message: `Mesh with id \"${meshID}\" does not exist` });\n return;\n }\n\n this.dataTextureManager.getDataTexture(mesh).then((texture) => {\n this.engineState.destinationMeshID = meshID;\n this.simulationRendererService.setDestinationDataTexture({\n dataTexture: texture,\n textureSize: this.engineState.textureSize\n });\n this.intersectionService.setDestinationGeometry(mesh);\n });\n }\n\n setDataTextureTransitionProgress(progress: number, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'data-texture' });\n this.engineState.dataTextureTransitionProgress = progress;\n this.simulationRendererService.setDataTextureTransitionProgress(progress);\n this.intersectionService.setProgress(progress);\n }\n\n setOriginMatcap(matcapID: string, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n this.engineState.originMatcapID = matcapID;\n this.instancedMeshManager.setOriginMatcap(this.assetService.getMatcap(matcapID));\n }\n\n setDestinationMatcap(matcapID: string, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n this.engineState.destinationMatcapID = matcapID;\n this.instancedMeshManager.setDestinationMatcap(this.assetService.getMatcap(matcapID));\n }\n\n setOriginColor(color: THREE.ColorRepresentation, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n this.instancedMeshManager.setOriginColor(color);\n }\n\n setDestinationColor(color: THREE.ColorRepresentation, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n this.instancedMeshManager.setDestinationColor(color);\n }\n\n setOriginTexture(id: string | THREE.ColorRepresentation, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n\n if (typeof id === 'string' && this.assetService.hasMatcap(id)) {\n this.setOriginMatcap(id);\n } else {\n this.setOriginColor(id);\n }\n }\n\n setDestinationTexture(id: string | THREE.ColorRepresentation, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n\n if (typeof id === 'string' && this.assetService.hasMatcap(id)) {\n this.setDestinationMatcap(id);\n } else {\n this.setDestinationColor(id);\n }\n }\n\n setMatcapProgress(progress: number, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n this.engineState.matcapTransitionProgress = progress;\n this.instancedMeshManager.setProgress(progress);\n }\n\n async setTextureSize(size: number) {\n this.engineState.textureSize = size;\n this.dataTextureManager.setTextureSize(size);\n this.simulationRendererService.setTextureSize(size);\n this.instancedMeshManager.resize(size);\n\n const originMesh = this.assetService.getMesh(this.engineState.originMeshID);\n if (!originMesh) {\n this.eventEmitter.emit('invalidRequest', { message: `Mesh with id \"${this.engineState.originMeshID}\" does not exist` });\n return;\n }\n\n const destinationMesh = this.assetService.getMesh(this.engineState.destinationMeshID);\n if (!destinationMesh) {\n this.eventEmitter.emit('invalidRequest', { message: `Mesh with id \"${this.engineState.destinationMeshID}\" does not exist` });\n return;\n }\n\n this.dataTextureManager.getDataTexture(originMesh).then((texture) =>\n this.simulationRendererService.setOriginDataTexture({\n dataTexture: texture,\n textureSize: size\n })\n );\n\n this.dataTextureManager.getDataTexture(destinationMesh).then((texture) =>\n this.simulationRendererService.setDestinationDataTexture({\n dataTexture: texture,\n textureSize: size\n })\n );\n\n this.simulationRendererService.setDataTextureTransitionProgress(this.engineState.dataTextureTransitionProgress);\n this.simulationRendererService.setVelocityTractionForce(this.engineState.velocityTractionForce);\n this.simulationRendererService.setPositionalTractionForce(this.engineState.positionalTractionForce);\n\n this.instancedMeshManager.setOriginMatcap(this.assetService.getMatcap(this.engineState.originMatcapID));\n this.instancedMeshManager.setDestinationMatcap(this.assetService.getMatcap(this.engineState.destinationMatcapID));\n this.instancedMeshManager.setProgress(this.engineState.matcapTransitionProgress);\n this.instancedMeshManager.setGeometrySize(this.engineState.instanceGeometryScale);\n }\n\n registerMesh(id: string, mesh: THREE.Mesh) {\n this.assetService.register(id, mesh);\n }\n\n registerMatcap(id: string, matcap: THREE.Texture) {\n this.assetService.register(id, matcap);\n }\n\n async fetchAndRegisterMesh(id: string, url: string) {\n return await this.assetService.loadMeshAsync(id, url);\n }\n\n async fetchAndRegisterMatcap(id: string, url: string) {\n return await this.assetService.loadTextureAsync(id, url);\n }\n\n useIntersect(use: boolean) {\n this.intersectionService.setActive(use);\n this.engineState.useIntersect = use;\n\n if (!use) {\n this.engineState.pointerPosition = { x: -99999999, y: -99999999 };\n this.intersectionService.setPointerPosition(this.engineState.pointerPosition);\n }\n }\n\n setPointerPosition(position: THREE.Vector2Like) {\n if (!this.engineState.useIntersect) return;\n this.engineState.pointerPosition = position;\n this.intersectionService.setPointerPosition(position);\n }\n\n setGeometrySize(geometrySize: THREE.Vector3Like) {\n this.engineState.instanceGeometryScale = geometrySize;\n this.instancedMeshManager.setGeometrySize(geometrySize);\n }\n\n setVelocityTractionForce(force: number) {\n this.engineState.velocityTractionForce = force;\n this.simulationRendererService.setVelocityTractionForce(force);\n }\n\n setPositionalTractionForce(force: number) {\n this.engineState.positionalTractionForce = force;\n this.simulationRendererService.setPositionalTractionForce(force);\n }\n\n setMaxRepelDistance(distance: number) {\n this.engineState.maxRepelDistance = distance;\n this.simulationRendererService.setMaxRepelDistance(distance);\n }\n\n scheduleMeshTransition(originMeshID: string, destinationMeshID: string, easing: EasingFunction = linear, duration: number = 1000, override: boolean = false) {\n this.transitionService.enqueue(\n 'data-texture',\n { easing, duration },\n {\n onTransitionBegin: () => {\n this.setOriginDataTexture(originMeshID, override);\n this.setDestinationDataTexture(destinationMeshID, override);\n this.setDataTextureTransitionProgress(0);\n }\n }\n );\n }\n\n scheduleMatcapTransition(\n originMatcapID: string,\n destinationMatcapID: string,\n easing: EasingFunction = linear,\n duration: number = 1000,\n override: boolean = false\n ) {\n this.transitionService.enqueue(\n 'matcap',\n { easing, duration },\n {\n onTransitionBegin: () => {\n this.setOriginMatcap(originMatcapID, override);\n this.setDestinationMatcap(destinationMatcapID, override);\n this.setMatcapProgress(0);\n }\n }\n );\n }\n\n scheduleTextureTransition(\n origin: string,\n destination: string,\n options?: {\n easing?: EasingFunction;\n duration?: number;\n override?: boolean;\n }\n ) {\n const easing = options?.easing ?? linear;\n const duration = options?.duration ?? 1000;\n\n if (options?.override) {\n this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n }\n\n this.transitionService.enqueue(\n 'matcap',\n { easing, duration },\n {\n onTransitionBegin: () => {\n this.setOriginTexture(origin);\n this.setDestinationTexture(destination);\n this.setMatcapProgress(0);\n }\n }\n );\n }\n\n handleServiceStateUpdated({ type, state }: { type: ServiceType; state: ServiceState }) {\n this.serviceStates[type] = state;\n }\n\n getObject(): THREE.Mesh {\n return this.instancedMeshManager.getMesh();\n }\n\n getMeshIDs() {\n return this.assetService.getMeshIDs();\n }\n\n getMatcapIDs() {\n return this.assetService.getTextureIDs();\n }\n\n /**\n * Disposes the resources used by the engine.\n */\n dispose() {\n this.scene.remove(this.instancedMeshManager.getMesh());\n this.simulationRendererService.dispose();\n this.instancedMeshManager.dispose();\n this.intersectionService.dispose();\n this.assetService.dispose();\n this.dataTextureManager.dispose();\n }\n\n private initialEngineState(params: ParticlesEngineParameters): EngineState {\n return {\n textureSize: params.textureSize,\n originMeshID: '',\n destinationMeshID: '',\n dataTextureTransitionProgress: 0,\n originMatcapID: '',\n destinationMatcapID: '',\n matcapTransitionProgress: 0,\n velocityTractionForce: 0.1,\n positionalTractionForce: 0.1,\n maxRepelDistance: 0.3,\n pointerPosition: { x: 0, y: 0 },\n instanceGeometryScale: { x: 1, y: 1, z: 1 },\n useIntersect: params.useIntersection ?? true\n };\n }\n\n private getInitialServiceStates(): ServiceStates {\n return {\n 'data-texture': 'created',\n 'instanced-mesh': 'created',\n matcap: 'created',\n simulation: 'created',\n asset: 'created'\n };\n }\n\n private handleTransitionProgress({ type, progress }: { type: TransitionType; progress: number }) {\n switch (type) {\n case 'data-texture':\n this.setDataTextureTransitionProgress(progress);\n break;\n case 'matcap':\n this.setMatcapProgress(progress);\n break;\n }\n }\n\n private handleInteractionPositionUpdated({ position }: { position: THREE.Vector4Like }) {\n this.simulationRendererService.setInteractionPosition(position);\n }\n}\n"],"names":["linear","n","DefaultEventEmitter","constructor","__publicField","this","all","Map","on","t","e","i","get","push","set","off","splice","indexOf","emit","slice","map","type","payload","emitter","handler","once","dispose","clear","createDataTexture","data","size","texture","THREE","DataTexture","RGBAFormat","FloatType","needsUpdate","disposeMesh","mesh","geometry","material","Material","forEach","clamp","value","min","max","Math","AssetService","eventEmitter","GLTFLoader","TextureLoader","DRACOLoader","Uint8Array","dracoLoader","setDecoderPath","gltfLoader","setDRACOLoader","updateServiceState","register","id","item","name","Mesh","prev","meshes","textures","setSolidColor","color","changeColor","getSolidColorTexture","solidColorTexture","getMesh","getMatcap","message","getMeshIDs","Array","from","keys","getTextureIDs","getMeshes","values","getTextures","hasMatcap","has","loadMeshAsync","url","options","gltf","loadAsync","meshName","scene","getObjectByName","children","error","loadTextureAsync","textureLoader","actual","Color","r","g","b","serviceState","state","_face","Triangle","_color","Vector3","_uva","Vector2","_uvb","_uvc","MeshSurfaceSampler","randomFunction","random","indexAttribute","index","positionAttribute","getAttribute","normalAttribute","colorAttribute","uvAttribute","weightAttribute","distribution","setWeightAttribute","build","totalFaces","count","faceWeights","Float32Array","faceWeight","i0","i1","i2","getX","a","fromBufferAttribute","c","getArea","cumulativeTotal","setRandomGenerator","sample","targetPosition","targetNormal","targetColor","targetUV","faceIndex","sampleFaceIndex","sampleFace","length","binarySearch","x","dist","start","end","mid","ceil","u","v","addScaledVector","normalize","getNormal","y","z","DataTextureService","textureSize","dataTextures","setTextureSize","getDataTexture","asset","array","meshData","BufferGeometry","setAttribute","BufferAttribute","position","normal","MeshBasicMaterial","scale","sampler","j","sampleMesh","attributes","_a","dataTexture","InstancedMeshManager","initialSize","geometries","uvRefsCache","previousScale","originColor","destinationColor","uniforms","uTime","uProgress","uTexture","uVelocity","uOriginTexture","uDestinationTexture","matcapMaterial","ShaderMaterial","vertexShader","fragmentShader","setOriginColor","setDestinationColor","fallbackGeometry","BoxGeometry","createInstancedMesh","update","elapsedTime","RawShaderMaterial","setOriginMatcap","matcap","disposeSolidColorOriginTexture","setDestinationMatcap","disposeSolidColorDestinationTexture","setProgress","float","setGeometrySize","useMatcapMaterial","useGeometry","updateVelocityTexture","updatePositionTexture","resize","current","previous","registerGeometry","uvRefs","createUVRefs","createSolidColorDataTexture","cached","attr","InstancedBufferAttribute","InstancedMesh","col","width","height","floor","UnsignedByteType","wrapS","RepeatWrapping","wrapT","minFilter","NearestFilter","magFilter","IntersectionService","camera","originGeometry","destinationGeometry","Raycaster","geometryNeedsUpdate","setActive","active","getIntersectionMesh","intersectionMesh","setCamera","setOriginGeometry","source","lastKnownOriginMeshID","uuid","clone","applyMatrix4","matrixWorld","setDestinationGeometry","lastKnownDestinationMeshID","progress","setPointerPosition","mousePosition","copy","calculate","instancedMesh","updateIntersectionMesh","blendedGeometry","getBlendedGeometry","intersection","getFirstIntersection","w","matrix","matrixAutoUpdate","updateMatrixWorld","raycaster","setFromCamera","intersectObject","worldPoint","point","localPoint","worldToLocal","Vector4","blendGeometry","to","blended","originPositions","destinationPositions","blendedPositions","originVert","destinationVert","blendedVert","lerpVectors","uv","setIndex","_camera","OrthographicCamera","FullscreenTriangleGeometry","super","Float32BufferAttribute","_geometry","FullScreenQuad","_mesh","render","renderer","GPUComputationRenderer","sizeX","sizeY","variables","currentTextureIndex","dataType","passThruUniforms","passThruTexture","passThruShader","createShaderMaterial","quad","addResolutionDefine","materialShader","defines","resolution","toFixed","computeFragmentShader","setDataType","addVariable","variableName","initialValueTexture","variable","dependencies","renderTargets","setVariableDependencies","init","capabilities","maxVertexTextures","createRenderTarget","renderTexture","d","depVar","found","compute","nextTextureIndex","il","dl","doRenderTarget","getCurrentRenderTarget","getAlternateRenderTarget","sizeXTexture","sizeYTexture","ClampToEdgeWrapping","WebGLRenderTarget","format","depthBuffer","createTexture","input","output","currentRenderTarget","getRenderTarget","currentXrEnabled","xr","enabled","currentShadowAutoUpdate","shadowMap","autoUpdate","setRenderTarget","SimulationRenderer","webGLRenderer","initialPosition","initialDataTexture","theta","PI","phi","acos","sin","cos","createSpherePoints","positionDataTexture","gpuComputationRenderer","lastKnownMixProgress","isWebGL2","HalfFloatType","velocityDataTexture","createBlankDataTexture","interactionPosition","mixPositionsVar","velocityVar","positionVar","uPositionA","uPositionB","uInteractionPosition","uCurrentPosition","uTractionForce","uMaxRepelDistance","err","Error","lastKnownVelocityDataTexture","getVelocityTexture","lastKnownPositionDataTexture","getPositionTexture","setMorphSourceDataTexture","setMorphDestinationDataTexture","setMaxRepelDistance","distance","setVelocityTractionForce","force","setPositionalTractionForce","setInteractionPosition","rtt","SimulationRendererService","dataTextureTransitionProgress","velocityTractionForce","positionalTractionForce","simulationRenderer","setOriginDataTexture","entry","setDestinationDataTexture","setDataTextureTransitionProgress","ExecutionStatusMap","status","execStatus","TransitionService","handleTransitionCancelledEvent","bind","enqueue","transition","transitionQueueItem","cancelled","duration","getQueue","transitions","queue","ongoingTransitions","shift","startTime","onTransitionBegin","call","onTransitionCancelled","delete","easing","timeDistance","emitTransitionProgress","_b","onTransitionProgress","emitTransitionFinished","_c","onTransitionFinished","pop","ongoingTransition","params","useIntersection","serviceStates","getInitialServiceStates","handleServiceStateUpdated","engineState","initialEngineState","assetService","transitionService","dataTextureManager","simulationRendererService","instancedMeshManager","add","intersectionService","handleTransitionProgress","handleInteractionPositionUpdated","meshID","override","then","originMeshID","destinationMeshID","matcapID","originMatcapID","destinationMatcapID","setOriginTexture","setDestinationTexture","setMatcapProgress","matcapTransitionProgress","originMesh","destinationMesh","instanceGeometryScale","registerMesh","registerMatcap","fetchAndRegisterMesh","fetchAndRegisterMatcap","useIntersect","use","pointerPosition","geometrySize","maxRepelDistance","scheduleMeshTransition","scheduleMatcapTransition","scheduleTextureTransition","origin","destination","getObject","getMatcapIDs","remove","simulation"],"mappings":"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","x_google_ignoreList":[2,5,11,12]}
|