@zephyr3d/scene 0.9.24 → 0.9.25

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.
@@ -1 +1 @@
1
- {"version":3,"file":"grass.js","sources":["../../../src/scene/terrain-cm/grass.ts"],"sourcesContent":["import type { IndexBuffer, StructuredBuffer, Texture2D } from '@zephyr3d/device';\r\nimport type { Nullable, Vector4 } from '@zephyr3d/base';\r\nimport { AABB, ClipState, nextPowerOf2, DRef, DWeakRef, Disposable } from '@zephyr3d/base';\r\nimport type { DrawContext } from '../../render';\r\nimport { Primitive } from '../../render';\r\nimport { ClipmapGrassMaterial } from './grassmaterial';\r\nimport type { ClipmapTerrain } from './terrain-cm';\r\nimport type { Camera } from '../../camera';\r\nimport { getDevice } from '../../app/api';\r\n\r\nconst MAX_INSTANCES_PER_NODE = 2048;\r\n\r\n/**\r\n * Grass blade instance information\r\n * @public\r\n */\r\nexport type GrassInstanceInfo = {\r\n /** x position of the blade */\r\n x: number;\r\n /** y position of the blade */\r\n y: number;\r\n /** Rotation angle of the blade */\r\n angle: number;\r\n};\r\nconst INSTANCE_BYTES = 4 * 4;\r\n\r\n/**\r\n * Grass glade instance manager class\r\n * @internal\r\n */\r\nexport class GrassInstances extends Disposable {\r\n private readonly _instances: GrassInstanceInfo[];\r\n private readonly _baseVertexBuffer: DRef<StructuredBuffer>;\r\n private readonly _indexBuffer: DRef<IndexBuffer>;\r\n private readonly _instanceBuffer: DRef<StructuredBuffer>;\r\n private readonly _primitive: DRef<Primitive>;\r\n constructor(baseVertexBuffer: StructuredBuffer, indexBuffer: IndexBuffer) {\r\n super();\r\n this._instances = [];\r\n this._baseVertexBuffer = new DRef(baseVertexBuffer);\r\n this._indexBuffer = new DRef(indexBuffer);\r\n this._instanceBuffer = new DRef();\r\n this._primitive = new DRef();\r\n }\r\n get numInstances() {\r\n return this._instances.length;\r\n }\r\n get instanceBuffer() {\r\n return this._instanceBuffer.get()!;\r\n }\r\n setBaseVertexBuffer(baseVertexBuffer: StructuredBuffer) {\r\n if (baseVertexBuffer !== this._baseVertexBuffer.get()) {\r\n this._baseVertexBuffer.set(baseVertexBuffer);\r\n this._primitive.dispose();\r\n }\r\n }\r\n draw() {\r\n if (this._instances.length > 0) {\r\n if (!this._primitive.get()) {\r\n const primitive = new Primitive();\r\n primitive.setVertexBuffer(this._baseVertexBuffer.get()!);\r\n primitive.setVertexBuffer(this._instanceBuffer.get()!, 'instance');\r\n primitive.setIndexBuffer(this._indexBuffer.get());\r\n primitive.primitiveType = 'triangle-list';\r\n primitive.indexStart = 0;\r\n primitive.indexCount = this._indexBuffer.get()!.length;\r\n this._primitive.set(primitive);\r\n }\r\n this._primitive.get()!.drawInstanced(this._instances.length);\r\n }\r\n }\r\n updateBuffers() {\r\n const device = getDevice();\r\n if (this._instances.length === 0) {\r\n this._instanceBuffer.set(null);\r\n return;\r\n }\r\n if (this._instances.length > 0 && !this._instanceBuffer.get()) {\r\n this._instanceBuffer.set(\r\n device.createVertexBuffer('tex1_f32x4', new Uint8Array(this._instances.length * INSTANCE_BYTES))\r\n );\r\n }\r\n let buffer = this._instanceBuffer.get()!;\r\n const currentBytes = buffer.byteLength;\r\n const bytesRequired = this._instances.length * INSTANCE_BYTES;\r\n if (currentBytes < bytesRequired) {\r\n buffer = device.createVertexBuffer('tex1_f32x4', new Uint8Array(nextPowerOf2(bytesRequired)))!;\r\n this._instanceBuffer.set(buffer);\r\n this._primitive.dispose();\r\n }\r\n const data = new Float32Array(4 * this._instances.length);\r\n for (let i = 0; i < this._instances.length; i++) {\r\n data[i * 4 + 0] = this._instances[i].x;\r\n data[i * 4 + 1] = this._instances[i].y;\r\n data[i * 4 + 2] = Math.sin(this._instances[i].angle);\r\n data[i * 4 + 3] = Math.cos(this._instances[i].angle);\r\n }\r\n buffer.bufferSubData(0, data);\r\n }\r\n removeInstances(minX: number, minZ: number, maxX: number, maxZ: number, num: number) {\r\n if (num <= 0) {\r\n return 0;\r\n }\r\n let removed = 0;\r\n for (let i = this._instances.length - 1; i >= 0; i--) {\r\n const instance = this._instances[i];\r\n if (instance.x >= minX && instance.x <= maxX && instance.y >= minZ && instance.y <= maxZ) {\r\n this._instances.splice(i, 1);\r\n removed++;\r\n if (removed === num) {\r\n break;\r\n }\r\n }\r\n }\r\n if (removed > 0) {\r\n this.updateBuffers();\r\n }\r\n return removed;\r\n }\r\n addInstances(instances: GrassInstanceInfo[]) {\r\n this._instances.push(...instances);\r\n this.updateBuffers();\r\n }\r\n protected onDispose() {\r\n super.onDispose();\r\n this._baseVertexBuffer.dispose();\r\n this._indexBuffer.dispose();\r\n this._instanceBuffer.dispose();\r\n this._primitive.dispose();\r\n }\r\n}\r\n\r\n/**\r\n * Grass layer class\r\n * @public\r\n */\r\nexport class GrassLayer extends Disposable {\r\n private static readonly _indexBuffer: DRef<IndexBuffer> = new DRef();\r\n private readonly _material: DRef<ClipmapGrassMaterial>;\r\n private readonly _quadtree: DRef<GrassQuadtreeNode>;\r\n private _bladeWidth: number;\r\n private _bladeHeight: number;\r\n private readonly _baseVertexBuffer: DRef<StructuredBuffer>;\r\n /**\r\n * Creates an instance of GrassLayer\r\n * @param terrain - Clipmap terrain object\r\n * @param bladeWidth - Grass blade width\r\n * @param bladeHeight - Grass blade height\r\n * @param albedoMap - Albedo texture for the blade\r\n */\r\n constructor(terrain: ClipmapTerrain, bladeWidth: number, bladeHeight: number, albedoMap?: Texture2D) {\r\n super();\r\n this._material = new DRef(new ClipmapGrassMaterial(terrain));\r\n this._material.get()!.albedoTexture = albedoMap ?? null;\r\n if (albedoMap) {\r\n this._material.get()!.setTextureSize(albedoMap.width, albedoMap.height);\r\n }\r\n this._bladeWidth = bladeWidth;\r\n this._bladeHeight = bladeHeight;\r\n this._baseVertexBuffer = new DRef(this.createBaseVertexBuffer(this._bladeWidth, this._bladeHeight));\r\n this._quadtree = new DRef(\r\n new GrassQuadtreeNode(this._baseVertexBuffer.get()!, GrassLayer._getIndexBuffer()!)\r\n );\r\n }\r\n /** @internal */\r\n get quadtree() {\r\n return this._quadtree.get();\r\n }\r\n /** @internal */\r\n updateMaterial() {\r\n this._material.get()!.uniformChanged();\r\n }\r\n /**\r\n * Sets the albedo texture of grass blades in this layer\r\n * @param albedoMap - Albedo texture to set\r\n */\r\n setAlbedoMap(albedoMap: Texture2D) {\r\n this._material.get()!.albedoTexture = albedoMap;\r\n if (albedoMap) {\r\n this._material.get()!.setTextureSize(albedoMap.width, albedoMap.height);\r\n }\r\n }\r\n /**\r\n * Gets the albedo texture of grass blades in this layer\r\n * @returns - Albedo texture of grass blades in this layer\r\n */\r\n getAlbedoMap() {\r\n return this._material.get()!.albedoTexture;\r\n }\r\n /**\r\n * Add grass blades to this layer in a region\r\n * @param instances - Grass blade instances to add\r\n */\r\n addInstances(instances: GrassInstanceInfo[]) {\r\n return this._quadtree.get()!.addInstances(instances);\r\n }\r\n /**\r\n * Remove grass blades to this layer in a region\r\n * @param minX - Minimum x position of the region\r\n * @param minZ - Minimum z position of the region\r\n * @param maxX - Maximum x position of the region\r\n * @param maxZ - Maximum z position of the region\r\n * @param numInstances - How many grass blades to add\r\n */\r\n removeInstances(minX: number, minZ: number, maxX: number, maxZ: number, numInstances: number) {\r\n this._quadtree.get()!.removeInstances(minX, minZ, maxX, maxZ, numInstances);\r\n }\r\n /** Grass blade width in this layer */\r\n get bladeWidth() {\r\n return this._bladeWidth;\r\n }\r\n set bladeWidth(val: number) {\r\n this.setBladeSize(val, this._bladeHeight);\r\n }\r\n /** Grass blade height in this layer */\r\n get bladeHeight() {\r\n return this._bladeHeight;\r\n }\r\n set bladeHeight(val: number) {\r\n this.setBladeSize(this._bladeWidth, val);\r\n }\r\n /**\r\n * Sets the size of grass blades in this layer\r\n * @param width - Grass blade width\r\n * @param height - Grass blade height\r\n */\r\n setBladeSize(width: number, height: number) {\r\n if (width !== this._bladeWidth || height !== this._bladeHeight) {\r\n this._bladeWidth = width;\r\n this._bladeHeight = height;\r\n this._baseVertexBuffer.set(this.createBaseVertexBuffer(this._bladeWidth, this._bladeHeight));\r\n this._quadtree.get()!.setBaseVertexBuffer(this._baseVertexBuffer.get()!);\r\n }\r\n }\r\n /** @internal */\r\n private static _getIndexBuffer() {\r\n if (!this._indexBuffer.get()) {\r\n this._indexBuffer.set(\r\n getDevice().createIndexBuffer(\r\n new Uint16Array([0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11])\r\n )\r\n );\r\n }\r\n return this._indexBuffer.get();\r\n }\r\n /** @internal */\r\n private createBaseVertexBuffer(bladeWidth: number, bladeHeight: number) {\r\n const device = getDevice();\r\n const r = bladeWidth * 0.5;\r\n const t = bladeHeight;\r\n const c = r * Math.cos(Math.PI / 3);\r\n const s = r * Math.sin(Math.PI / 3);\r\n const vertices = new Float32Array([\r\n r,\r\n 0,\r\n 0,\r\n 0,\r\n 1,\r\n r,\r\n t,\r\n 0,\r\n 0,\r\n 0,\r\n -r,\r\n t,\r\n 0,\r\n 1,\r\n 0,\r\n -r,\r\n 0,\r\n 0,\r\n 1,\r\n 1,\r\n\r\n c,\r\n 0,\r\n s,\r\n 0,\r\n 1,\r\n -c,\r\n 0,\r\n -s,\r\n 1,\r\n 1,\r\n -c,\r\n t,\r\n -s,\r\n 1,\r\n 0,\r\n c,\r\n t,\r\n s,\r\n 0,\r\n 0,\r\n\r\n -c,\r\n 0,\r\n s,\r\n 0,\r\n 1,\r\n c,\r\n 0,\r\n -s,\r\n 1,\r\n 1,\r\n c,\r\n t,\r\n -s,\r\n 1,\r\n 0,\r\n -c,\r\n t,\r\n s,\r\n 0,\r\n 0\r\n ]);\r\n return device.createInterleavedVertexBuffer(['position_f32x3', 'tex0_f32x2'], vertices);\r\n }\r\n /** @internal */\r\n draw(ctx: DrawContext, region: Vector4, minY: number, maxY: number) {\r\n this._material.get()!.apply(ctx);\r\n for (let pass = 0; pass < this._material.get()!.numPasses; pass++) {\r\n this._material.get()!.bind(ctx.device, pass);\r\n this._quadtree.get()!.draw(ctx.camera, region, minY, maxY, false);\r\n }\r\n }\r\n /** @internal */\r\n protected onDispose() {\r\n super.onDispose();\r\n this._material.dispose();\r\n this._quadtree.dispose();\r\n this._baseVertexBuffer.dispose();\r\n }\r\n}\r\n/**\r\n * Grass renderer for clipmap terrain\r\n * @public\r\n */\r\nexport class GrassRenderer extends Disposable {\r\n private readonly _terrain: DWeakRef<ClipmapTerrain>;\r\n private _numGrassBlades: number;\r\n private _layers: GrassLayer[];\r\n /**\r\n * Creates an instance of GrassRenderer\r\n * @param terrain - Clipmap terrain object\r\n */\r\n constructor(terrain: ClipmapTerrain) {\r\n super();\r\n this._terrain = new DWeakRef(terrain);\r\n this._numGrassBlades = 0;\r\n this._layers = [];\r\n }\r\n /** @internal */\r\n updateMaterial() {\r\n for (const layer of this._layers) {\r\n layer.updateMaterial();\r\n }\r\n }\r\n /** How many grass blades */\r\n get numGrassBlades() {\r\n return this._numGrassBlades;\r\n }\r\n /** How many grass layers */\r\n get numLayers() {\r\n return this._layers.length;\r\n }\r\n /**\r\n * Gets the grass layer at given index\r\n * @param index - Index of the grass layer\r\n * @returns The grass layer at the index\r\n */\r\n getLayer(index: number) {\r\n return this._layers[index];\r\n }\r\n /**\r\n * Adds a grass layer\r\n * @param bladeWidth - Width of grass blades in this layer\r\n * @param bladeHeight - Height of grass blades in this layer\r\n * @param albedoMap - Albedo texture of grass blades in this layer\r\n * @returns Index of the added grass layer\r\n */\r\n addLayer(bladeWidth: number, bladeHeight: number, albedoMap?: Texture2D) {\r\n const layer = new GrassLayer(this._terrain.get()!, bladeWidth, bladeHeight, albedoMap);\r\n this._layers.push(layer);\r\n return this._layers.length - 1;\r\n }\r\n /**\r\n * Gets the albedo texture of grass blades in the grass layer at given index\r\n * @param layer - Index of the grass layer to get\r\n * @returns Albedo texture of grass blades in the grass layer\r\n */\r\n getGrassTexture(layer: number) {\r\n return this._layers[layer]?.getAlbedoMap() ?? null;\r\n }\r\n /**\r\n * Sets the albedo texture of grass blades in the grass layer at given index\r\n * @param layer - Index of the grass layer to set\r\n * @param texture - Albedo texture to set\r\n */\r\n setGrassTexture(layer: number, texture: Texture2D) {\r\n const grassLayer = this._layers[layer];\r\n if (grassLayer) {\r\n grassLayer.setAlbedoMap(texture);\r\n } else {\r\n console.error(`Invalid grass layer: ${layer}`);\r\n }\r\n }\r\n /**\r\n * Gets width of the grass blades in the grass layer at given index\r\n * @param layer - Index of the grass layer\r\n * @returns Width of the grass blades in the layer\r\n */\r\n getBladeWidth(layer: number) {\r\n return this._layers[layer]?.bladeWidth ?? 0;\r\n }\r\n /**\r\n * Gets height of the grass blades in the grass layer at given index\r\n * @param layer - Index of the grass layer\r\n * @returns Height of the grass blades in the layer\r\n */\r\n getBladeHeight(layer: number) {\r\n return this._layers[layer]?.bladeHeight ?? 0;\r\n }\r\n /**\r\n * Sets size of the grass blades in the grass layer at given index\r\n * @param layer - Index of the grass layer\r\n * @param width - Width to set\r\n * @param height - Height to set\r\n */\r\n setBladeSize(layer: number, width: number, height: number) {\r\n const grassLayer = this._layers[layer];\r\n if (grassLayer) {\r\n grassLayer.setBladeSize(width, height);\r\n } else {\r\n console.error(`Invalid grass layer: ${layer}`);\r\n }\r\n }\r\n /**\r\n * Add grass instances to the grass layer at given index\r\n * @param layer - Index of the grass layer\r\n * @param instances - Grass blade instances to add\r\n */\r\n addInstances(layer: number, instances: GrassInstanceInfo[]) {\r\n const grassLayer = this._layers[layer];\r\n if (!grassLayer) {\r\n console.error(`Invalid grass layer: ${layer}`);\r\n } else {\r\n this._numGrassBlades += grassLayer.addInstances(instances);\r\n }\r\n }\r\n /**\r\n * Remove grass instances from the grass layer at given index within a region\r\n * @param layer - Index of the grass layer\r\n * @param minX - Minimum x of the region\r\n * @param minZ - Minimum z of the region\r\n * @param maxX - Maximum x of the region\r\n * @param maxZ - Maximum z of the region\r\n * @param num - How many grass blades to remove\r\n */\r\n removeInstances(layer: number, minX: number, minZ: number, maxX: number, maxZ: number, num: number) {\r\n const grassLayer = this._layers[layer];\r\n if (!grassLayer) {\r\n console.error(`Invalid grass layer: ${layer}`);\r\n } else {\r\n grassLayer.removeInstances(minX, minZ, maxX, maxZ, num);\r\n }\r\n }\r\n /** @internal */\r\n draw(ctx: DrawContext) {\r\n const bv = this._terrain.get()!.getWorldBoundingVolume()!.toAABB();\r\n const minY = bv.minPoint.y;\r\n const maxY = bv.maxPoint.y;\r\n for (const layer of this._layers) {\r\n layer.draw(ctx, this._terrain.get()!.worldRegion, minY - layer.bladeHeight, maxY + layer.bladeHeight);\r\n }\r\n }\r\n protected onDispose() {\r\n super.onDispose();\r\n this._terrain.dispose();\r\n for (const layer of this._layers) {\r\n layer.dispose();\r\n }\r\n }\r\n}\r\n\r\n/** @internal */\r\nexport class GrassQuadtreeNode extends Disposable {\r\n private static readonly _cullAABB = new AABB();\r\n private readonly _grassInstances: DRef<GrassInstances>;\r\n private _children: Nullable<GrassQuadtreeNode[]>;\r\n private readonly _baseVertexBuffer: DRef<StructuredBuffer>;\r\n private readonly _indexBuffer: DRef<IndexBuffer>;\r\n private _minX: number;\r\n private _minZ: number;\r\n private _maxX: number;\r\n private _maxZ: number;\r\n constructor(baseVertexBuffer: StructuredBuffer, indexBuffer: IndexBuffer) {\r\n super();\r\n this._baseVertexBuffer = new DRef(baseVertexBuffer);\r\n this._indexBuffer = new DRef(indexBuffer);\r\n this._grassInstances = new DRef(new GrassInstances(baseVertexBuffer, indexBuffer));\r\n this._children = null;\r\n this._minX = 0;\r\n this._minZ = 0;\r\n this._maxX = 1;\r\n this._maxZ = 1;\r\n }\r\n get grassInstances() {\r\n return this._grassInstances.get();\r\n }\r\n get children() {\r\n return this._children;\r\n }\r\n draw(camera: Camera, region: Vector4, minY: number, maxY: number, skipClipTest: boolean) {\r\n if (!skipClipTest) {\r\n const cullAABB = GrassQuadtreeNode._cullAABB;\r\n const x = region.x;\r\n const z = region.y;\r\n const dx = region.z - x;\r\n const dz = region.w - z;\r\n cullAABB.minPoint.setXYZ(x + this._minX * dx, minY, z + this._minZ * dz);\r\n cullAABB.maxPoint.setXYZ(x + this._maxX * dx, maxY, z + this._maxZ * dz);\r\n const clipState = camera.clipMask\r\n ? cullAABB.getClipStateWithFrustumMask(camera.frustum, camera.clipMask)\r\n : cullAABB.getClipStateWithFrustum(camera.frustum);\r\n if (clipState === ClipState.NOT_CLIPPED) {\r\n return;\r\n }\r\n skipClipTest = clipState === ClipState.A_INSIDE_B;\r\n }\r\n if (this._grassInstances.get()!.numInstances > 0) {\r\n this._grassInstances.get()!.draw();\r\n }\r\n if (this._children) {\r\n for (const child of this._children) {\r\n child.draw(camera, region, minY, maxY, skipClipTest);\r\n }\r\n }\r\n }\r\n setBaseVertexBuffer(baseVertexBuffer: StructuredBuffer) {\r\n if (baseVertexBuffer !== this._baseVertexBuffer.get()) {\r\n this._baseVertexBuffer.set(baseVertexBuffer);\r\n this._grassInstances.get()!.setBaseVertexBuffer(baseVertexBuffer);\r\n if (this._children) {\r\n for (const child of this._children) {\r\n child.setBaseVertexBuffer(baseVertexBuffer);\r\n }\r\n }\r\n }\r\n }\r\n removeInstances(minX: number, minZ: number, maxX: number, maxZ: number, numInstances: number) {\r\n let n = Math.min(this._grassInstances.get()!.numInstances, numInstances);\r\n if (n <= 0) {\r\n return 0;\r\n }\r\n let removed = 0;\r\n if (this._children) {\r\n for (const child of this._children) {\r\n if (child._minX < maxX && child._minZ < maxZ && child._maxX > minX && child._maxZ > minZ) {\r\n removed += child.removeInstances(minX, minZ, maxX, maxZ, n);\r\n n -= removed;\r\n }\r\n }\r\n }\r\n if (n > 0) {\r\n removed += this._grassInstances.get()!.removeInstances(minX, minZ, maxX, maxZ, n);\r\n }\r\n return removed;\r\n }\r\n addInstances(instances: GrassInstanceInfo[]) {\r\n if (instances.length === 0) {\r\n return 0;\r\n }\r\n let n = Math.min(instances.length, MAX_INSTANCES_PER_NODE - this._grassInstances.get()!.numInstances);\r\n this._grassInstances.get()!.addInstances(instances.slice(0, n));\r\n if (n < instances.length) {\r\n if (!this._children) {\r\n this._children = [\r\n new GrassQuadtreeNode(this._baseVertexBuffer.get()!, this._indexBuffer.get()!),\r\n new GrassQuadtreeNode(this._baseVertexBuffer.get()!, this._indexBuffer.get()!),\r\n new GrassQuadtreeNode(this._baseVertexBuffer.get()!, this._indexBuffer.get()!),\r\n new GrassQuadtreeNode(this._baseVertexBuffer.get()!, this._indexBuffer.get()!)\r\n ];\r\n this._children[0]._minX = this._minX;\r\n this._children[0]._minZ = this._minZ;\r\n this._children[0]._maxX = (this._minX + this._maxX) * 0.5;\r\n this._children[0]._maxZ = (this._minZ + this._maxZ) * 0.5;\r\n this._children[1]._minX = this._children[0]._maxX;\r\n this._children[1]._minZ = this._minZ;\r\n this._children[1]._maxX = this._maxX;\r\n this._children[1]._maxZ = this._children[0]._maxZ;\r\n this._children[2]._minX = this._minX;\r\n this._children[2]._minZ = this._children[0]._maxZ;\r\n this._children[2]._maxX = this._children[0]._maxX;\r\n this._children[2]._maxZ = this._maxZ;\r\n this._children[3]._minX = this._children[0]._maxX;\r\n this._children[3]._minZ = this._children[0]._maxZ;\r\n this._children[3]._maxX = this._maxX;\r\n this._children[3]._maxZ = this._maxZ;\r\n }\r\n instances = instances.slice(n);\r\n for (const child of this._children) {\r\n if (instances.length > 0) {\r\n const childInstances = instances.filter(\r\n (val) =>\r\n val.x >= child._minX && val.y >= child._minZ && val.x < child._maxX && val.y < child._maxZ\r\n );\r\n n += child.addInstances(childInstances);\r\n instances = instances.filter(\r\n (val) =>\r\n !(val.x >= child._minX && val.y >= child._minZ && val.x < child._maxX && val.y < child._maxZ)\r\n );\r\n }\r\n }\r\n }\r\n return n;\r\n }\r\n protected onDispose() {\r\n super.onDispose();\r\n this._baseVertexBuffer.dispose();\r\n this._indexBuffer.dispose();\r\n this._grassInstances.dispose();\r\n if (this._children) {\r\n for (const child of this._children) {\r\n child.dispose();\r\n }\r\n }\r\n }\r\n}\r\n"],"names":["MAX_INSTANCES_PER_NODE","INSTANCE_BYTES","GrassInstances","Disposable","_instances","_baseVertexBuffer","_indexBuffer","_instanceBuffer","_primitive","baseVertexBuffer","indexBuffer","DRef","numInstances","length","instanceBuffer","get","setBaseVertexBuffer","set","dispose","draw","primitive","Primitive","setVertexBuffer","setIndexBuffer","primitiveType","indexStart","indexCount","drawInstanced","updateBuffers","device","getDevice","createVertexBuffer","Uint8Array","buffer","currentBytes","byteLength","bytesRequired","nextPowerOf2","data","Float32Array","i","x","y","Math","sin","angle","cos","bufferSubData","removeInstances","minX","minZ","maxX","maxZ","num","removed","instance","splice","addInstances","instances","push","onDispose","GrassLayer","_material","_quadtree","_bladeWidth","_bladeHeight","terrain","bladeWidth","bladeHeight","albedoMap","ClipmapGrassMaterial","albedoTexture","setTextureSize","width","height","createBaseVertexBuffer","GrassQuadtreeNode","_getIndexBuffer","quadtree","updateMaterial","uniformChanged","setAlbedoMap","getAlbedoMap","val","setBladeSize","createIndexBuffer","Uint16Array","r","t","c","PI","s","vertices","createInterleavedVertexBuffer","ctx","region","minY","maxY","apply","pass","numPasses","bind","camera","GrassRenderer","_terrain","_numGrassBlades","_layers","DWeakRef","layer","numGrassBlades","numLayers","getLayer","index","addLayer","getGrassTexture","setGrassTexture","texture","grassLayer","console","error","getBladeWidth","getBladeHeight","bv","getWorldBoundingVolume","toAABB","minPoint","maxPoint","worldRegion","_cullAABB","AABB","_grassInstances","_children","_minX","_minZ","_maxX","_maxZ","grassInstances","children","skipClipTest","cullAABB","z","dx","dz","w","setXYZ","clipState","clipMask","getClipStateWithFrustumMask","frustum","getClipStateWithFrustum","ClipState","NOT_CLIPPED","A_INSIDE_B","child","n","min","slice","childInstances","filter"],"mappings":"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"}
1
+ {"version":3,"file":"grass.js","sources":["../../../src/scene/terrain-cm/grass.ts"],"sourcesContent":["import type { IndexBuffer, StructuredBuffer, Texture2D } from '@zephyr3d/device';\r\nimport type { Vector4 } from '@zephyr3d/base';\r\nimport { AABB, ClipState, nextPowerOf2, DRef, DWeakRef, Disposable } from '@zephyr3d/base';\r\nimport type { DrawContext } from '../../render';\r\nimport { Primitive } from '../../render';\r\nimport { ClipmapGrassMaterial } from './grassmaterial';\r\nimport type { ClipmapTerrain } from './terrain-cm';\r\nimport { getDevice } from '../../app/api';\r\n\r\nconst INSTANCE_BYTES = 4 * 4;\r\n/** Number of placement cells along each axis of a grass tile */\r\nconst TILE_CELLS = 64;\r\n/** Default number of placement cells per density map texel along each axis */\r\nconst DEFAULT_CELLS_PER_TEXEL = 2;\r\nconst MAX_CELLS_PER_TEXEL = 8;\r\n\r\n/**\r\n * Deterministic 2D integer hash, returns a value in [0, 1).\r\n * Grass placement derives everything (jitter, survival threshold, rotation)\r\n * from this hash so that blade positions are stable across edits and reloads.\r\n */\r\nfunction hashCell(x: number, z: number, seed: number): number {\r\n let h = (Math.imul(x, 0x27d4eb2d) ^ Math.imul(z, 0x165667b1) ^ Math.imul(seed, 0x9e3779b9)) | 0;\r\n h = Math.imul(h ^ (h >>> 15), 0x85ebca6b);\r\n h = Math.imul(h ^ (h >>> 13), 0xc2b2ae35);\r\n h ^= h >>> 16;\r\n return (h >>> 0) / 4294967296;\r\n}\r\n\r\n/**\r\n * Grass blade instance buffer for a single tile\r\n * @internal\r\n */\r\nexport class GrassInstances extends Disposable {\r\n private _numInstances: number;\r\n private readonly _baseVertexBuffer: DRef<StructuredBuffer>;\r\n private readonly _indexBuffer: DRef<IndexBuffer>;\r\n private readonly _instanceBuffer: DRef<StructuredBuffer>;\r\n private readonly _primitive: DRef<Primitive>;\r\n constructor(baseVertexBuffer: StructuredBuffer, indexBuffer: IndexBuffer) {\r\n super();\r\n this._numInstances = 0;\r\n this._baseVertexBuffer = new DRef(baseVertexBuffer);\r\n this._indexBuffer = new DRef(indexBuffer);\r\n this._instanceBuffer = new DRef();\r\n this._primitive = new DRef();\r\n }\r\n get numInstances() {\r\n return this._numInstances;\r\n }\r\n setBaseVertexBuffer(baseVertexBuffer: StructuredBuffer) {\r\n if (baseVertexBuffer !== this._baseVertexBuffer.get()) {\r\n this._baseVertexBuffer.set(baseVertexBuffer);\r\n this._primitive.dispose();\r\n }\r\n }\r\n /**\r\n * Sets the packed instance data (x, y, sin, cos per instance)\r\n */\r\n setData(data: Float32Array<ArrayBuffer>, count: number) {\r\n this._numInstances = count;\r\n if (count === 0) {\r\n return;\r\n }\r\n const device = getDevice();\r\n const bytesRequired = count * INSTANCE_BYTES;\r\n let buffer = this._instanceBuffer.get();\r\n if (!buffer || buffer.byteLength < bytesRequired) {\r\n buffer = device.createVertexBuffer('tex1_f32x4', new Uint8Array(nextPowerOf2(bytesRequired)))!;\r\n this._instanceBuffer.set(buffer);\r\n this._primitive.dispose();\r\n }\r\n buffer.bufferSubData(0, data.subarray(0, count * 4));\r\n }\r\n draw() {\r\n if (this._numInstances > 0) {\r\n if (!this._primitive.get()) {\r\n const primitive = new Primitive();\r\n primitive.setVertexBuffer(this._baseVertexBuffer.get()!);\r\n primitive.setVertexBuffer(this._instanceBuffer.get()!, 'instance');\r\n primitive.setIndexBuffer(this._indexBuffer.get());\r\n primitive.primitiveType = 'triangle-list';\r\n primitive.indexStart = 0;\r\n primitive.indexCount = this._indexBuffer.get()!.length;\r\n this._primitive.set(primitive);\r\n }\r\n this._primitive.get()!.drawInstanced(this._numInstances);\r\n }\r\n }\r\n protected onDispose() {\r\n super.onDispose();\r\n this._baseVertexBuffer.dispose();\r\n this._indexBuffer.dispose();\r\n this._instanceBuffer.dispose();\r\n this._primitive.dispose();\r\n }\r\n}\r\n\r\n/**\r\n * Grass layer class\r\n *\r\n * @public\r\n */\r\nexport class GrassLayer extends Disposable {\r\n private static readonly _indexBuffer: DRef<IndexBuffer> = new DRef();\r\n private static readonly _cullAABB = new AABB();\r\n private static readonly _visibleTiles: GrassInstances[] = [];\r\n private static readonly _instanceData = new Float32Array(TILE_CELLS * TILE_CELLS * 4);\r\n private readonly _material: DRef<ClipmapGrassMaterial>;\r\n private readonly _seed: number;\r\n private _bladeWidth: number;\r\n private _bladeHeight: number;\r\n private readonly _baseVertexBuffer: DRef<StructuredBuffer>;\r\n private _densityWidth: number;\r\n private _densityHeight: number;\r\n private _cellsPerTexel: number;\r\n private _densityMap: Uint8Array;\r\n private readonly _tiles: Map<number, GrassInstances>;\r\n private _tilesX: number;\r\n private _tilesZ: number;\r\n private _numBlades: number;\r\n /**\r\n * Creates an instance of GrassLayer\r\n * @param terrain - Clipmap terrain object\r\n * @param seed - Seed for deterministic blade placement, usually the layer index\r\n * @param bladeWidth - Grass blade width\r\n * @param bladeHeight - Grass blade height\r\n * @param albedoMap - Albedo texture for the blade\r\n */\r\n constructor(\r\n terrain: ClipmapTerrain,\r\n seed: number,\r\n bladeWidth: number,\r\n bladeHeight: number,\r\n albedoMap?: Texture2D\r\n ) {\r\n super();\r\n this._material = new DRef(new ClipmapGrassMaterial(terrain));\r\n this._material.get()!.albedoTexture = albedoMap ?? null;\r\n if (albedoMap) {\r\n this._material.get()!.setTextureSize(albedoMap.width, albedoMap.height);\r\n }\r\n this._seed = seed;\r\n this._bladeWidth = bladeWidth;\r\n this._bladeHeight = bladeHeight;\r\n this._baseVertexBuffer = new DRef(this.createBaseVertexBuffer(this._bladeWidth, this._bladeHeight));\r\n this._densityWidth = Math.max(1, terrain.sizeX);\r\n this._densityHeight = Math.max(1, terrain.sizeZ);\r\n this._cellsPerTexel = DEFAULT_CELLS_PER_TEXEL;\r\n this._densityMap = new Uint8Array(this._densityWidth * this._densityHeight);\r\n this._tiles = new Map();\r\n this._tilesX = 0;\r\n this._tilesZ = 0;\r\n this._numBlades = 0;\r\n this.updateTileGrid();\r\n }\r\n /** @internal */\r\n updateMaterial() {\r\n this._material.get()!.uniformChanged();\r\n }\r\n /**\r\n * Sets the albedo texture of grass blades in this layer\r\n * @param albedoMap - Albedo texture to set\r\n */\r\n setAlbedoMap(albedoMap: Texture2D) {\r\n this._material.get()!.albedoTexture = albedoMap;\r\n if (albedoMap) {\r\n this._material.get()!.setTextureSize(albedoMap.width, albedoMap.height);\r\n }\r\n }\r\n /**\r\n * Gets the albedo texture of grass blades in this layer\r\n * @returns - Albedo texture of grass blades in this layer\r\n */\r\n getAlbedoMap() {\r\n return this._material.get()!.albedoTexture;\r\n }\r\n /** How many grass blades are currently generated in this layer */\r\n get numBlades() {\r\n return this._numBlades;\r\n }\r\n /**\r\n * Density map of this layer, one byte per texel (0 = no grass, 255 = full density).\r\n * Texel (x, z) covers the normalized terrain region [x/w..(x+1)/w, z/h..(z+1)/h].\r\n * After modifying the data, call {@link GrassLayer.updateDensityRegion} to\r\n * regenerate the affected blade instances.\r\n */\r\n get densityMap() {\r\n return this._densityMap;\r\n }\r\n /** Width of the density map in texels */\r\n get densityMapWidth() {\r\n return this._densityWidth;\r\n }\r\n /** Height of the density map in texels */\r\n get densityMapHeight() {\r\n return this._densityHeight;\r\n }\r\n /**\r\n * Number of placement cells per density map texel along each axis.\r\n * The maximum blade count per texel is the square of this value.\r\n */\r\n get cellsPerTexel() {\r\n return this._cellsPerTexel;\r\n }\r\n set cellsPerTexel(val: number) {\r\n val = Math.max(1, Math.min(MAX_CELLS_PER_TEXEL, val | 0));\r\n if (val !== this._cellsPerTexel) {\r\n this._cellsPerTexel = val;\r\n this.rebuild();\r\n }\r\n }\r\n /**\r\n * Replaces the density map and regenerates all blade instances\r\n * @param width - Density map width in texels\r\n * @param height - Density map height in texels\r\n * @param cellsPerTexel - Placement cells per texel along each axis\r\n * @param data - Density data, one byte per texel\r\n */\r\n setDensityData(width: number, height: number, cellsPerTexel: number, data: Uint8Array) {\r\n if (width < 1 || height < 1 || width * height !== data.length) {\r\n console.error('Invalid grass density data');\r\n return;\r\n }\r\n this._densityWidth = width;\r\n this._densityHeight = height;\r\n this._cellsPerTexel = Math.max(1, Math.min(MAX_CELLS_PER_TEXEL, cellsPerTexel | 0));\r\n this._densityMap = data;\r\n this.rebuild();\r\n }\r\n /**\r\n * Regenerates blade instances for all tiles overlapping a density map region\r\n * @param minTexelX - Minimum x texel of the region (inclusive)\r\n * @param minTexelZ - Minimum z texel of the region (inclusive)\r\n * @param maxTexelX - Maximum x texel of the region (exclusive)\r\n * @param maxTexelZ - Maximum z texel of the region (exclusive)\r\n */\r\n updateDensityRegion(minTexelX: number, minTexelZ: number, maxTexelX: number, maxTexelZ: number) {\r\n const k = this._cellsPerTexel;\r\n // expand by one texel to cover the bilinear sampling footprint\r\n const cx0 = Math.max(0, (minTexelX - 1) * k);\r\n const cz0 = Math.max(0, (minTexelZ - 1) * k);\r\n const cx1 = Math.min(this._densityWidth * k, (maxTexelX + 1) * k);\r\n const cz1 = Math.min(this._densityHeight * k, (maxTexelZ + 1) * k);\r\n if (cx1 <= cx0 || cz1 <= cz0) {\r\n return;\r\n }\r\n const tx0 = Math.floor(cx0 / TILE_CELLS);\r\n const tz0 = Math.floor(cz0 / TILE_CELLS);\r\n const tx1 = Math.min(this._tilesX, Math.ceil(cx1 / TILE_CELLS));\r\n const tz1 = Math.min(this._tilesZ, Math.ceil(cz1 / TILE_CELLS));\r\n for (let tz = tz0; tz < tz1; tz++) {\r\n for (let tx = tx0; tx < tx1; tx++) {\r\n this.generateTile(tx, tz);\r\n }\r\n }\r\n }\r\n /**\r\n * Regenerates blade instances for the entire layer\r\n */\r\n rebuild() {\r\n for (const tile of this._tiles.values()) {\r\n tile.dispose();\r\n }\r\n this._tiles.clear();\r\n this._numBlades = 0;\r\n this.updateTileGrid();\r\n for (let tz = 0; tz < this._tilesZ; tz++) {\r\n for (let tx = 0; tx < this._tilesX; tx++) {\r\n this.generateTile(tx, tz);\r\n }\r\n }\r\n }\r\n /** Grass blade width in this layer */\r\n get bladeWidth() {\r\n return this._bladeWidth;\r\n }\r\n set bladeWidth(val: number) {\r\n this.setBladeSize(val, this._bladeHeight);\r\n }\r\n /** Grass blade height in this layer */\r\n get bladeHeight() {\r\n return this._bladeHeight;\r\n }\r\n set bladeHeight(val: number) {\r\n this.setBladeSize(this._bladeWidth, val);\r\n }\r\n /**\r\n * Sets the size of grass blades in this layer\r\n * @param width - Grass blade width\r\n * @param height - Grass blade height\r\n */\r\n setBladeSize(width: number, height: number) {\r\n if (width !== this._bladeWidth || height !== this._bladeHeight) {\r\n this._bladeWidth = width;\r\n this._bladeHeight = height;\r\n this._baseVertexBuffer.set(this.createBaseVertexBuffer(this._bladeWidth, this._bladeHeight));\r\n for (const tile of this._tiles.values()) {\r\n tile.setBaseVertexBuffer(this._baseVertexBuffer.get()!);\r\n }\r\n }\r\n }\r\n /** @internal */\r\n private updateTileGrid() {\r\n this._tilesX = Math.ceil((this._densityWidth * this._cellsPerTexel) / TILE_CELLS);\r\n this._tilesZ = Math.ceil((this._densityHeight * this._cellsPerTexel) / TILE_CELLS);\r\n }\r\n /** @internal */\r\n private sampleDensity(u: number, v: number): number {\r\n const w = this._densityWidth;\r\n const h = this._densityHeight;\r\n const x = u * w - 0.5;\r\n const z = v * h - 0.5;\r\n const ix = Math.floor(x);\r\n const iz = Math.floor(z);\r\n const fx = x - ix;\r\n const fz = z - iz;\r\n const x0 = Math.min(Math.max(ix, 0), w - 1);\r\n const x1 = Math.min(Math.max(ix + 1, 0), w - 1);\r\n const z0 = Math.min(Math.max(iz, 0), h - 1);\r\n const z1 = Math.min(Math.max(iz + 1, 0), h - 1);\r\n const d = this._densityMap;\r\n const a = d[z0 * w + x0] + (d[z0 * w + x1] - d[z0 * w + x0]) * fx;\r\n const b = d[z1 * w + x0] + (d[z1 * w + x1] - d[z1 * w + x0]) * fx;\r\n return (a + (b - a) * fz) * (1 / 255);\r\n }\r\n /** @internal */\r\n private regionIsEmpty(cx0: number, cz0: number, cx1: number, cz1: number): boolean {\r\n const k = this._cellsPerTexel;\r\n const x0 = Math.max(0, Math.floor(cx0 / k) - 1);\r\n const z0 = Math.max(0, Math.floor(cz0 / k) - 1);\r\n const x1 = Math.min(this._densityWidth, Math.ceil(cx1 / k) + 1);\r\n const z1 = Math.min(this._densityHeight, Math.ceil(cz1 / k) + 1);\r\n for (let z = z0; z < z1; z++) {\r\n const rowBase = z * this._densityWidth;\r\n for (let x = x0; x < x1; x++) {\r\n if (this._densityMap[rowBase + x] !== 0) {\r\n return false;\r\n }\r\n }\r\n }\r\n return true;\r\n }\r\n /** @internal */\r\n private generateTile(tx: number, tz: number) {\r\n const k = this._cellsPerTexel;\r\n const cw = this._densityWidth * k;\r\n const ch = this._densityHeight * k;\r\n const cx0 = tx * TILE_CELLS;\r\n const cz0 = tz * TILE_CELLS;\r\n const cx1 = Math.min(cx0 + TILE_CELLS, cw);\r\n const cz1 = Math.min(cz0 + TILE_CELLS, ch);\r\n const key = tz * this._tilesX + tx;\r\n let tile = this._tiles.get(key);\r\n // fast path: nothing to generate if there is no tile yet and no density\r\n if (!tile && this.regionIsEmpty(cx0, cz0, cx1, cz1)) {\r\n return;\r\n }\r\n const data = GrassLayer._instanceData;\r\n const seed = this._seed * 4;\r\n let count = 0;\r\n for (let cz = cz0; cz < cz1; cz++) {\r\n for (let cx = cx0; cx < cx1; cx++) {\r\n const u = (cx + hashCell(cx, cz, seed)) / cw;\r\n const v = (cz + hashCell(cx, cz, seed + 1)) / ch;\r\n if (this.sampleDensity(u, v) > hashCell(cx, cz, seed + 2)) {\r\n const angle = hashCell(cx, cz, seed + 3) * Math.PI * 2;\r\n data[count * 4 + 0] = u;\r\n data[count * 4 + 1] = v;\r\n data[count * 4 + 2] = Math.sin(angle);\r\n data[count * 4 + 3] = Math.cos(angle);\r\n count++;\r\n }\r\n }\r\n }\r\n this._numBlades += count - (tile?.numInstances ?? 0);\r\n if (count === 0) {\r\n if (tile) {\r\n tile.dispose();\r\n this._tiles.delete(key);\r\n }\r\n } else {\r\n if (!tile) {\r\n tile = new GrassInstances(this._baseVertexBuffer.get()!, GrassLayer._getIndexBuffer()!);\r\n this._tiles.set(key, tile);\r\n }\r\n tile.setData(data, count);\r\n }\r\n }\r\n /** @internal */\r\n private static _getIndexBuffer() {\r\n if (!this._indexBuffer.get()) {\r\n this._indexBuffer.set(\r\n getDevice().createIndexBuffer(\r\n new Uint16Array([0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11])\r\n )\r\n );\r\n }\r\n return this._indexBuffer.get();\r\n }\r\n /** @internal */\r\n private createBaseVertexBuffer(bladeWidth: number, bladeHeight: number) {\r\n const device = getDevice();\r\n const r = bladeWidth * 0.5;\r\n const t = bladeHeight;\r\n const c = r * Math.cos(Math.PI / 3);\r\n const s = r * Math.sin(Math.PI / 3);\r\n const vertices = new Float32Array([\r\n r,\r\n 0,\r\n 0,\r\n 0,\r\n 1,\r\n r,\r\n t,\r\n 0,\r\n 0,\r\n 0,\r\n -r,\r\n t,\r\n 0,\r\n 1,\r\n 0,\r\n -r,\r\n 0,\r\n 0,\r\n 1,\r\n 1,\r\n\r\n c,\r\n 0,\r\n s,\r\n 0,\r\n 1,\r\n -c,\r\n 0,\r\n -s,\r\n 1,\r\n 1,\r\n -c,\r\n t,\r\n -s,\r\n 1,\r\n 0,\r\n c,\r\n t,\r\n s,\r\n 0,\r\n 0,\r\n\r\n -c,\r\n 0,\r\n s,\r\n 0,\r\n 1,\r\n c,\r\n 0,\r\n -s,\r\n 1,\r\n 1,\r\n c,\r\n t,\r\n -s,\r\n 1,\r\n 0,\r\n -c,\r\n t,\r\n s,\r\n 0,\r\n 0\r\n ]);\r\n return device.createInterleavedVertexBuffer(['position_f32x3', 'tex0_f32x2'], vertices);\r\n }\r\n /** @internal */\r\n draw(ctx: DrawContext, region: Vector4, minY: number, maxY: number) {\r\n const visible = GrassLayer._visibleTiles;\r\n visible.length = 0;\r\n const camera = ctx.camera;\r\n const cullAABB = GrassLayer._cullAABB;\r\n const cellsW = this._densityWidth * this._cellsPerTexel;\r\n const cellsH = this._densityHeight * this._cellsPerTexel;\r\n const rx = region.x;\r\n const rz = region.y;\r\n const rw = region.z - region.x;\r\n const rh = region.w - region.y;\r\n for (const [key, tile] of this._tiles) {\r\n const tx = key % this._tilesX;\r\n const tz = (key - tx) / this._tilesX;\r\n const u0 = (tx * TILE_CELLS) / cellsW;\r\n const v0 = (tz * TILE_CELLS) / cellsH;\r\n const u1 = Math.min(1, ((tx + 1) * TILE_CELLS) / cellsW);\r\n const v1 = Math.min(1, ((tz + 1) * TILE_CELLS) / cellsH);\r\n cullAABB.minPoint.setXYZ(rx + u0 * rw, minY, rz + v0 * rh);\r\n cullAABB.maxPoint.setXYZ(rx + u1 * rw, maxY, rz + v1 * rh);\r\n const clipState = camera.clipMask\r\n ? cullAABB.getClipStateWithFrustumMask(camera.frustum, camera.clipMask)\r\n : cullAABB.getClipStateWithFrustum(camera.frustum);\r\n if (clipState !== ClipState.NOT_CLIPPED) {\r\n visible.push(tile);\r\n }\r\n }\r\n if (visible.length === 0) {\r\n return;\r\n }\r\n this._material.get()!.apply(ctx);\r\n for (let pass = 0; pass < this._material.get()!.numPasses; pass++) {\r\n this._material.get()!.bind(ctx.device, pass);\r\n for (const tile of visible) {\r\n tile.draw();\r\n }\r\n }\r\n visible.length = 0;\r\n }\r\n /** @internal */\r\n protected onDispose() {\r\n super.onDispose();\r\n this._material.dispose();\r\n for (const tile of this._tiles.values()) {\r\n tile.dispose();\r\n }\r\n this._tiles.clear();\r\n this._baseVertexBuffer.dispose();\r\n }\r\n}\r\n/**\r\n * Grass renderer for clipmap terrain\r\n * @public\r\n */\r\nexport class GrassRenderer extends Disposable {\r\n private readonly _terrain: DWeakRef<ClipmapTerrain>;\r\n private _layers: GrassLayer[];\r\n /**\r\n * Creates an instance of GrassRenderer\r\n * @param terrain - Clipmap terrain object\r\n */\r\n constructor(terrain: ClipmapTerrain) {\r\n super();\r\n this._terrain = new DWeakRef(terrain);\r\n this._layers = [];\r\n }\r\n /** @internal */\r\n updateMaterial() {\r\n for (const layer of this._layers) {\r\n layer.updateMaterial();\r\n }\r\n }\r\n /** How many grass blades */\r\n get numGrassBlades() {\r\n return this._layers.reduce((sum, layer) => sum + layer.numBlades, 0);\r\n }\r\n /** How many grass layers */\r\n get numLayers() {\r\n return this._layers.length;\r\n }\r\n /**\r\n * Gets the grass layer at given index\r\n * @param index - Index of the grass layer\r\n * @returns The grass layer at the index\r\n */\r\n getLayer(index: number) {\r\n return this._layers[index];\r\n }\r\n /**\r\n * Adds a grass layer\r\n * @param bladeWidth - Width of grass blades in this layer\r\n * @param bladeHeight - Height of grass blades in this layer\r\n * @param albedoMap - Albedo texture of grass blades in this layer\r\n * @returns Index of the added grass layer\r\n */\r\n addLayer(bladeWidth: number, bladeHeight: number, albedoMap?: Texture2D) {\r\n const layer = new GrassLayer(\r\n this._terrain.get()!,\r\n this._layers.length,\r\n bladeWidth,\r\n bladeHeight,\r\n albedoMap\r\n );\r\n this._layers.push(layer);\r\n return this._layers.length - 1;\r\n }\r\n /**\r\n * Gets the albedo texture of grass blades in the grass layer at given index\r\n * @param layer - Index of the grass layer to get\r\n * @returns Albedo texture of grass blades in the grass layer\r\n */\r\n getGrassTexture(layer: number) {\r\n return this._layers[layer]?.getAlbedoMap() ?? null;\r\n }\r\n /**\r\n * Sets the albedo texture of grass blades in the grass layer at given index\r\n * @param layer - Index of the grass layer to set\r\n * @param texture - Albedo texture to set\r\n */\r\n setGrassTexture(layer: number, texture: Texture2D) {\r\n const grassLayer = this._layers[layer];\r\n if (grassLayer) {\r\n grassLayer.setAlbedoMap(texture);\r\n } else {\r\n console.error(`Invalid grass layer: ${layer}`);\r\n }\r\n }\r\n /**\r\n * Gets width of the grass blades in the grass layer at given index\r\n * @param layer - Index of the grass layer\r\n * @returns Width of the grass blades in the layer\r\n */\r\n getBladeWidth(layer: number) {\r\n return this._layers[layer]?.bladeWidth ?? 0;\r\n }\r\n /**\r\n * Gets height of the grass blades in the grass layer at given index\r\n * @param layer - Index of the grass layer\r\n * @returns Height of the grass blades in the layer\r\n */\r\n getBladeHeight(layer: number) {\r\n return this._layers[layer]?.bladeHeight ?? 0;\r\n }\r\n /**\r\n * Sets size of the grass blades in the grass layer at given index\r\n * @param layer - Index of the grass layer\r\n * @param width - Width to set\r\n * @param height - Height to set\r\n */\r\n setBladeSize(layer: number, width: number, height: number) {\r\n const grassLayer = this._layers[layer];\r\n if (grassLayer) {\r\n grassLayer.setBladeSize(width, height);\r\n } else {\r\n console.error(`Invalid grass layer: ${layer}`);\r\n }\r\n }\r\n /** @internal */\r\n draw(ctx: DrawContext) {\r\n const bv = this._terrain.get()!.getWorldBoundingVolume()!.toAABB();\r\n const minY = bv.minPoint.y;\r\n const maxY = bv.maxPoint.y;\r\n for (const layer of this._layers) {\r\n layer.draw(ctx, this._terrain.get()!.worldRegion, minY - layer.bladeHeight, maxY + layer.bladeHeight);\r\n }\r\n }\r\n protected onDispose() {\r\n super.onDispose();\r\n this._terrain.dispose();\r\n for (const layer of this._layers) {\r\n layer.dispose();\r\n }\r\n }\r\n}\r\n"],"names":["INSTANCE_BYTES","TILE_CELLS","DEFAULT_CELLS_PER_TEXEL","MAX_CELLS_PER_TEXEL","hashCell","x","z","seed","h","Math","imul","GrassInstances","Disposable","_numInstances","_baseVertexBuffer","_indexBuffer","_instanceBuffer","_primitive","baseVertexBuffer","indexBuffer","DRef","numInstances","setBaseVertexBuffer","get","set","dispose","setData","data","count","device","getDevice","bytesRequired","buffer","byteLength","createVertexBuffer","Uint8Array","nextPowerOf2","bufferSubData","subarray","draw","primitive","Primitive","setVertexBuffer","setIndexBuffer","primitiveType","indexStart","indexCount","length","drawInstanced","onDispose","GrassLayer","_cullAABB","AABB","_visibleTiles","_instanceData","Float32Array","_material","_seed","_bladeWidth","_bladeHeight","_densityWidth","_densityHeight","_cellsPerTexel","_densityMap","_tiles","_tilesX","_tilesZ","_numBlades","terrain","bladeWidth","bladeHeight","albedoMap","ClipmapGrassMaterial","albedoTexture","setTextureSize","width","height","createBaseVertexBuffer","max","sizeX","sizeZ","Map","updateTileGrid","updateMaterial","uniformChanged","setAlbedoMap","getAlbedoMap","numBlades","densityMap","densityMapWidth","densityMapHeight","cellsPerTexel","val","min","rebuild","setDensityData","console","error","updateDensityRegion","minTexelX","minTexelZ","maxTexelX","maxTexelZ","k","cx0","cz0","cx1","cz1","tx0","floor","tz0","tx1","ceil","tz1","tz","tx","generateTile","tile","values","clear","setBladeSize","sampleDensity","u","v","w","ix","iz","fx","fz","x0","x1","z0","z1","d","a","b","regionIsEmpty","rowBase","cw","ch","key","cz","cx","angle","PI","sin","cos","delete","_getIndexBuffer","createIndexBuffer","Uint16Array","r","t","c","s","vertices","createInterleavedVertexBuffer","ctx","region","minY","maxY","visible","camera","cullAABB","cellsW","cellsH","rx","rz","y","rw","rh","u0","v0","u1","v1","minPoint","setXYZ","maxPoint","clipState","clipMask","getClipStateWithFrustumMask","frustum","getClipStateWithFrustum","ClipState","NOT_CLIPPED","push","apply","pass","numPasses","bind","GrassRenderer","_terrain","_layers","DWeakRef","layer","numGrassBlades","reduce","sum","numLayers","getLayer","index","addLayer","getGrassTexture","setGrassTexture","texture","grassLayer","getBladeWidth","getBladeHeight","bv","getWorldBoundingVolume","toAABB","worldRegion"],"mappings":"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"}
@@ -46,60 +46,83 @@ import '../../../scene/terrain-cm/grass.js';
46
46
  import '../../../scene/raycast_visitor.js';
47
47
  import { JSONArray } from '../json.js';
48
48
 
49
- function mergeTypedArrays(ctor, arrays) {
50
- const totalLength = arrays.reduce((acc, arr)=>acc + arr.length, 0);
51
- const result = new ctor(totalLength);
52
- let offset = 0;
53
- for (const array of arrays){
54
- result.set(array, offset);
55
- offset += array.length;
56
- }
57
- return result;
58
- }
59
- async function getTerrainGrassContent(terrain) {
49
+ // 'GRAS' in little endian. The legacy per-instance format starts with the
50
+ // layer count, so any realistic legacy file can not collide with this magic.
51
+ const GRASS_DATA_MAGIC = 0x53415247;
52
+ const GRASS_DATA_VERSION = 1;
53
+ function getTerrainGrassContent(terrain) {
60
54
  const grassRenderer = terrain.grassRenderer;
61
- const layerDatas = [];
62
- let dataSize = 4 + 4 * grassRenderer.numLayers;
63
- for(let i = 0; i < grassRenderer.numLayers; i++){
64
- const promises = [];
65
- const layer = grassRenderer.getLayer(i);
66
- const queue = [
67
- layer.quadtree
68
- ];
69
- while(queue.length > 0){
70
- const quadtreeNode = queue.shift();
71
- if (quadtreeNode.children) {
72
- queue.push(...quadtreeNode.children);
73
- }
74
- const grassInstances = quadtreeNode.grassInstances;
75
- if (grassInstances.numInstances > 0) {
76
- const instanceBuffer = grassInstances.instanceBuffer;
77
- const P = instanceBuffer.getBufferSubData(null, 0, grassInstances.numInstances * 4 * 4);
78
- promises.push(P);
79
- }
80
- }
81
- if (promises.length > 0) {
82
- const data = await Promise.all(promises);
83
- const merged = mergeTypedArrays(Uint8Array, data);
84
- dataSize += merged.length;
85
- layerDatas.push(merged);
86
- } else {
87
- layerDatas.push(new Uint8Array());
88
- }
55
+ const numLayers = grassRenderer.numLayers;
56
+ let dataSize = 3 * 4;
57
+ for(let i = 0; i < numLayers; i++){
58
+ dataSize += 4 * 4 + grassRenderer.getLayer(i).densityMap.length;
89
59
  }
90
60
  const data = new DataView(new ArrayBuffer(dataSize));
91
- const view = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
61
+ const view = new Uint8Array(data.buffer);
92
62
  let offset = 0;
93
- data.setUint32(offset, grassRenderer.numLayers, true);
63
+ data.setUint32(offset, GRASS_DATA_MAGIC, true);
94
64
  offset += 4;
95
- for(let i = 0; i < grassRenderer.numLayers; i++){
96
- data.setUint32(offset, layerDatas[i].length, true);
65
+ data.setUint32(offset, GRASS_DATA_VERSION, true);
66
+ offset += 4;
67
+ data.setUint32(offset, numLayers, true);
68
+ offset += 4;
69
+ for(let i = 0; i < numLayers; i++){
70
+ const layer = grassRenderer.getLayer(i);
71
+ data.setUint32(offset, layer.densityMapWidth, true);
97
72
  offset += 4;
98
- view.set(layerDatas[i], offset);
99
- offset += layerDatas[i].length;
73
+ data.setUint32(offset, layer.densityMapHeight, true);
74
+ offset += 4;
75
+ data.setUint32(offset, layer.cellsPerTexel, true);
76
+ offset += 4;
77
+ data.setUint32(offset, layer.densityMap.length, true);
78
+ offset += 4;
79
+ view.set(layer.densityMap, offset);
80
+ offset += layer.densityMap.length;
100
81
  }
101
82
  return data.buffer;
102
83
  }
84
+ /**
85
+ * Imports grass data saved by the legacy per-instance format by baking the
86
+ * blade instances into the per-layer density maps. Blade positions will be
87
+ * re-derived from the density, so they will not match the original ones
88
+ * exactly, but the local density is preserved.
89
+ */ function importLegacyGrassInstances(terrain, dataView) {
90
+ const grassRenderer = terrain.grassRenderer;
91
+ const numLayers = dataView.getUint32(0, true);
92
+ if (numLayers !== grassRenderer.numLayers) {
93
+ console.error('Number of grass layers mismatch');
94
+ return false;
95
+ }
96
+ let offset = 4;
97
+ for(let i = 0; i < numLayers; i++){
98
+ const dataSize = dataView.getUint32(offset, true);
99
+ offset += 4;
100
+ if (dataSize > 0) {
101
+ const layer = grassRenderer.getLayer(i);
102
+ const w = layer.densityMapWidth;
103
+ const h = layer.densityMapHeight;
104
+ const counts = new Uint32Array(w * h);
105
+ // legacy instance layout: x, y, sin(angle), cos(angle) as floats
106
+ const floats = new Float32Array(dataView.buffer, dataView.byteOffset + offset, dataSize >> 2);
107
+ const numInstances = floats.length >> 2;
108
+ for(let j = 0; j < numInstances; j++){
109
+ const x = Math.min(Math.max(Math.floor(floats[j * 4 + 0] * w), 0), w - 1);
110
+ const z = Math.min(Math.max(Math.floor(floats[j * 4 + 1] * h), 0), h - 1);
111
+ counts[z * w + x]++;
112
+ }
113
+ const density = layer.densityMap;
114
+ const maxPerTexel = layer.cellsPerTexel * layer.cellsPerTexel;
115
+ for(let t = 0; t < counts.length; t++){
116
+ if (counts[t] > 0) {
117
+ density[t] = Math.min(255, Math.round(counts[t] / maxPerTexel * 255));
118
+ }
119
+ }
120
+ layer.updateDensityRegion(0, 0, w, h);
121
+ offset += dataSize;
122
+ }
123
+ }
124
+ return true;
125
+ }
103
126
  async function getTerrainHeightMapContent(terrain) {
104
127
  const heightmap = terrain.heightMap;
105
128
  const buffer = new ArrayBuffer(2 * 4 + heightmap.width * heightmap.height * 2);
@@ -427,35 +450,31 @@ async function getTerrainSplatMapContent(terrain) {
427
450
  const data = await manager.VFS.readFile(path, {
428
451
  encoding: 'binary'
429
452
  });
430
- if (!data) {
453
+ if (!data || data.byteLength < 4) {
431
454
  console.error('Load grass data failed');
432
455
  return;
433
456
  }
434
457
  const dataView = new DataView(data);
435
- let offset = 0;
436
- const numLayers = dataView.getUint32(offset, true);
437
- if (numLayers !== this.grassRenderer.numLayers) {
438
- console.error('Number of grass layers mismatch');
439
- return;
440
- }
441
- offset += 4;
442
- for(let i = 0; i < numLayers; i++){
443
- const dataSize = dataView.getUint32(offset, true);
444
- offset += 4;
445
- if (dataSize > 0) {
446
- const data = new Float32Array(dataView.buffer, dataView.byteOffset + offset, dataSize >> 2);
447
- const numInstances = data.length >> 2;
448
- const instances = [];
449
- for(let i = 0; i < numInstances; i++){
450
- instances.push({
451
- x: data[i * 4 + 0],
452
- y: data[i * 4 + 1],
453
- angle: Math.atan2(data[i * 4 + 2], data[i * 4 + 3])
454
- });
455
- }
456
- this.grassRenderer.addInstances(i, instances);
457
- offset += dataSize;
458
+ if (dataView.getUint32(0, true) === GRASS_DATA_MAGIC) {
459
+ // density map format, version at offset 4 is currently always 1
460
+ const numLayers = dataView.getUint32(8, true);
461
+ if (numLayers !== this.grassRenderer.numLayers) {
462
+ console.error('Number of grass layers mismatch');
463
+ return;
458
464
  }
465
+ let offset = 12;
466
+ for(let i = 0; i < numLayers; i++){
467
+ const width = dataView.getUint32(offset, true);
468
+ const height = dataView.getUint32(offset + 4, true);
469
+ const cellsPerTexel = dataView.getUint32(offset + 8, true);
470
+ const byteLength = dataView.getUint32(offset + 12, true);
471
+ offset += 16;
472
+ const densityData = new Uint8Array(data, offset, byteLength).slice();
473
+ offset += byteLength;
474
+ this.grassRenderer.getLayer(i).setDensityData(width, height, cellsPerTexel, densityData);
475
+ }
476
+ } else if (!importLegacyGrassInstances(this, dataView)) {
477
+ return;
459
478
  }
460
479
  this.grassAssetId = value.str[0];
461
480
  }
@@ -1 +1 @@
1
- {"version":3,"file":"terrain.js","sources":["../../../../src/utility/serialization/scene/terrain.ts"],"sourcesContent":["import type { GrassInstanceInfo } from '../../../scene';\r\nimport { GraphNode, type SceneNode } from '../../../scene';\r\nimport { defineProps, type SerializableClass } from '../types';\r\nimport { ClipmapTerrain } from '../../../scene/terrain-cm/terrain-cm';\r\nimport type { TerrainDebugMode } from '../../../material';\r\nimport type { Texture2D } from '@zephyr3d/device';\r\nimport type { Nullable, TypedArray, TypedArrayConstructor } from '@zephyr3d/base';\r\nimport type { ResourceManager } from '../manager';\r\nimport { JSONArray } from '../json';\r\nimport { getDevice } from '../../../app/api';\r\n\r\nfunction mergeTypedArrays<T extends TypedArray>(ctor: TypedArrayConstructor<T>, arrays: T[]): T {\r\n const totalLength = arrays.reduce((acc, arr) => acc + arr.length, 0);\r\n const result = new ctor(totalLength);\r\n let offset = 0;\r\n for (const array of arrays) {\r\n result.set(array, offset);\r\n offset += array.length;\r\n }\r\n return result;\r\n}\r\n\r\nasync function getTerrainGrassContent(terrain: ClipmapTerrain): Promise<ArrayBuffer> {\r\n const grassRenderer = terrain.grassRenderer;\r\n const layerDatas: Uint8Array<ArrayBuffer>[] = [];\r\n let dataSize = 4 + 4 * grassRenderer.numLayers;\r\n for (let i = 0; i < grassRenderer.numLayers; i++) {\r\n const promises: Promise<Uint8Array<ArrayBuffer>>[] = [];\r\n const layer = grassRenderer.getLayer(i);\r\n const queue = [layer.quadtree];\r\n while (queue.length > 0) {\r\n const quadtreeNode = queue.shift()!;\r\n if (quadtreeNode.children) {\r\n queue.push(...quadtreeNode.children);\r\n }\r\n const grassInstances = quadtreeNode.grassInstances!;\r\n if (grassInstances.numInstances > 0) {\r\n const instanceBuffer = grassInstances.instanceBuffer;\r\n const P = instanceBuffer.getBufferSubData(null, 0, grassInstances.numInstances * 4 * 4);\r\n promises.push(P);\r\n }\r\n }\r\n if (promises.length > 0) {\r\n const data = await Promise.all(promises);\r\n const merged = mergeTypedArrays(Uint8Array, data) as Uint8Array<ArrayBuffer>;\r\n dataSize += merged.length;\r\n layerDatas.push(merged);\r\n } else {\r\n layerDatas.push(new Uint8Array());\r\n }\r\n }\r\n const data = new DataView(new ArrayBuffer(dataSize));\r\n const view = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\r\n let offset = 0;\r\n data.setUint32(offset, grassRenderer.numLayers, true);\r\n offset += 4;\r\n for (let i = 0; i < grassRenderer.numLayers; i++) {\r\n data.setUint32(offset, layerDatas[i].length, true);\r\n offset += 4;\r\n view.set(layerDatas[i], offset);\r\n offset += layerDatas[i].length;\r\n }\r\n return data.buffer;\r\n}\r\n\r\nasync function getTerrainHeightMapContent(terrain: ClipmapTerrain): Promise<ArrayBuffer> {\r\n const heightmap = terrain.heightMap!;\r\n const buffer = new ArrayBuffer(2 * 4 + heightmap.width * heightmap.height * 2);\r\n const head = new DataView(buffer);\r\n head.setUint32(0, heightmap.width, true);\r\n head.setUint32(4, heightmap.height, true);\r\n const data = new Uint16Array(buffer, 2 * 4);\r\n if (heightmap.format === 'r16f') {\r\n await heightmap.readPixels(0, 0, heightmap.width, heightmap.height, 0, 0, data);\r\n } else if (heightmap.format === 'rgba16f') {\r\n // WebGL1 uses rgba16f for height map, so we need to convert\r\n const tmpData = new Uint16Array(heightmap.width * heightmap.height * 4);\r\n await heightmap.readPixels(0, 0, heightmap.width, heightmap.height, 0, 0, tmpData);\r\n for (let i = 0; i < heightmap.width * heightmap.height; i++) {\r\n data[i] = tmpData[i * 4 + 0]; // Use the red channel as height\r\n }\r\n }\r\n return buffer;\r\n}\r\n\r\nasync function getTerrainSplatMapContent(terrain: ClipmapTerrain): Promise<ArrayBuffer> {\r\n const device = getDevice();\r\n const splatMap = terrain.splatMap!;\r\n const numLayers = (terrain.material!.numDetailMaps + 3) >> 2;\r\n const info = device.getDeviceCaps().textureCaps.getTextureFormatInfo(splatMap.format);\r\n const buffer = new ArrayBuffer(\r\n 3 * 4 + numLayers * splatMap.width * splatMap.height * info.blockWidth * info.blockHeight * info.size\r\n );\r\n const head = new DataView(buffer);\r\n head.setUint32(0, splatMap.width, true);\r\n head.setUint32(4, splatMap.height, true);\r\n head.setUint32(8, numLayers, true);\r\n for (let i = 0; i < numLayers; i++) {\r\n const layerData = new Uint8Array(\r\n buffer,\r\n 3 * 4 + i * splatMap.width * splatMap.height * info.blockWidth * info.blockHeight * info.size\r\n );\r\n await splatMap.readPixels(0, 0, splatMap.width, splatMap.height, 0, 0, layerData);\r\n }\r\n return buffer;\r\n}\r\n\r\n/** @internal */\r\nexport function getTerrainClass(manager: ResourceManager): SerializableClass {\r\n return {\r\n ctor: ClipmapTerrain,\r\n name: 'ClipmapTerrain',\r\n parent: GraphNode,\r\n createFunc(ctx: SceneNode, init: number) {\r\n const node = new ClipmapTerrain(ctx.scene!);\r\n node.numDetailMaps = init;\r\n node.parent = ctx;\r\n return { obj: node };\r\n },\r\n getInitParams(obj: ClipmapTerrain) {\r\n return obj.numDetailMaps;\r\n },\r\n getProps() {\r\n return defineProps([\r\n {\r\n name: 'Resolution',\r\n description: 'Terrain resolution',\r\n type: 'int2',\r\n default: [256, 256],\r\n options: { minValue: 1, maxValue: 4096 },\r\n get(this: ClipmapTerrain, value) {\r\n value.num[0] = this.sizeX;\r\n value.num[1] = this.sizeZ;\r\n },\r\n set(this: ClipmapTerrain, value) {\r\n this.setSize(value.num[0], value.num[1]);\r\n }\r\n },\r\n {\r\n name: 'CastShadow',\r\n description: 'If true, the terrain can cast shadows',\r\n type: 'bool',\r\n default: true,\r\n get(this: ClipmapTerrain, value) {\r\n value.bool[0] = this.castShadow;\r\n },\r\n set(this: ClipmapTerrain, value) {\r\n this.castShadow = value.bool[0];\r\n }\r\n },\r\n {\r\n name: 'Wireframe',\r\n description: 'If true, the terrain will be rendered as wireframe',\r\n type: 'bool',\r\n default: false,\r\n isPersistent() {\r\n return false;\r\n },\r\n get(this: ClipmapTerrain, value) {\r\n value.bool[0] = this.wireframe;\r\n },\r\n set(this: ClipmapTerrain, value) {\r\n this.wireframe = value.bool[0];\r\n }\r\n },\r\n {\r\n name: 'Debug',\r\n description: 'Debug visualization mode for the terrain material',\r\n type: 'string',\r\n options: {\r\n enum: {\r\n labels: ['None', 'UV', 'VertexNormal', 'DetailNormal', 'Tangent', 'Binormal', 'Albedo'],\r\n values: ['none', 'uv', 'vertex_normal', 'detail_normal', 'tangent', 'bitangent', 'albedo']\r\n }\r\n },\r\n default: 'none',\r\n isPersistent() {\r\n return false;\r\n },\r\n get(this: ClipmapTerrain, value) {\r\n value.str[0] = this.material!.debugMode;\r\n },\r\n set(this: ClipmapTerrain, value) {\r\n this.material!.debugMode = value.str[0] as TerrainDebugMode;\r\n }\r\n },\r\n {\r\n name: 'GrassMaps',\r\n description: 'Serialized grass texture layers and blade settings',\r\n type: 'object',\r\n default: null,\r\n options: { objectTypes: [JSONArray] },\r\n phase: 0,\r\n isNullable() {\r\n return true;\r\n },\r\n isHidden() {\r\n return false;\r\n },\r\n get(this: ClipmapTerrain, value) {\r\n const data: { texture: string; bladeWidth: number; bladeHeight: number }[] = [];\r\n const numLayers = this.grassRenderer.numLayers;\r\n for (let i = 0; i < numLayers; i++) {\r\n const grassTexture = this.grassRenderer.getGrassTexture(i);\r\n const assetId = grassTexture ? (manager.getAssetId(grassTexture) ?? '') : '';\r\n data.push({\r\n texture: assetId,\r\n bladeWidth: this.grassRenderer.getBladeWidth(i),\r\n bladeHeight: this.grassRenderer.getBladeHeight(i)\r\n });\r\n }\r\n value.object[0] = new JSONArray(null, data);\r\n },\r\n async set(this: ClipmapTerrain, value) {\r\n const json = value.object[0] as JSONArray;\r\n const data =\r\n (json?.data as {\r\n texture: string;\r\n bladeWidth: number;\r\n bladeHeight: number;\r\n }[]) ?? [];\r\n for (let i = 0; i < data.length; i++) {\r\n const info = data[i];\r\n const assetId = info.texture;\r\n let texture: Nullable<Texture2D> = null;\r\n if (assetId) {\r\n try {\r\n texture = await manager.fetchTexture<Texture2D>(assetId);\r\n } catch (err) {\r\n console.error(`Load asset failed: ${value.str[0]}: ${err}`);\r\n texture = null;\r\n }\r\n if (!texture?.isTexture2D()) {\r\n console.error('Invalid texture type');\r\n texture?.dispose();\r\n texture = null;\r\n }\r\n }\r\n this.grassRenderer.addLayer(info.bladeWidth ?? 1, info.bladeHeight ?? 1, texture!);\r\n }\r\n }\r\n },\r\n {\r\n name: 'DetailMaps',\r\n description: 'Serialized terrain detail texture layers',\r\n type: 'object',\r\n default: null,\r\n options: { objectTypes: [JSONArray] },\r\n isNullable() {\r\n return true;\r\n },\r\n isHidden() {\r\n return false;\r\n },\r\n get(this: ClipmapTerrain, value) {\r\n const data: { albedo: string; normal: string; roughness: number; uvscale: number }[] = [];\r\n const material = this.material!;\r\n for (let i = 0; i < material.numDetailMaps; i++) {\r\n data.push({\r\n albedo: manager.getAssetId(material.getDetailMap(i)) ?? '',\r\n normal: manager.getAssetId(material.getDetailNormalMap(i)) ?? '',\r\n roughness: material.getDetailMapRoughness(i),\r\n uvscale: material.getDetailMapUVScale(i)\r\n });\r\n }\r\n value.object[0] = new JSONArray(null, data);\r\n },\r\n async set(this: ClipmapTerrain, value) {\r\n const json = value.object[0] as JSONArray;\r\n if (!json) {\r\n this.material!.numDetailMaps = 0;\r\n return;\r\n }\r\n const data =\r\n (json.data as {\r\n albedo: string;\r\n normal: string;\r\n roughness: number;\r\n uvscale: number;\r\n }[]) ?? [];\r\n const material = this.material!;\r\n material.numDetailMaps = data.length;\r\n for (let i = 0; i < this.numDetailMaps; i++) {\r\n const info = data[i];\r\n if (!info?.albedo) {\r\n material.setDetailMap(i, null);\r\n } else {\r\n let tex: Nullable<Texture2D>;\r\n try {\r\n tex = await manager.fetchTexture<Texture2D>(info.albedo);\r\n } catch (err) {\r\n console.error(`Load asset failed: ${value.str[0]}: ${err}`);\r\n tex = null;\r\n }\r\n if (tex?.isTexture2D()) {\r\n material.setDetailMap(i, tex);\r\n } else {\r\n console.error('Invalid texture type');\r\n }\r\n }\r\n if (!info?.normal) {\r\n material.setDetailNormalMap(i, null);\r\n } else {\r\n let tex: Nullable<Texture2D>;\r\n try {\r\n tex = await manager.fetchTexture<Texture2D>(info.normal);\r\n } catch (err) {\r\n console.error(`Load asset failed: ${value.str[0]}: ${err}`);\r\n tex = null;\r\n }\r\n if (tex?.isTexture2D()) {\r\n material.setDetailMap(i, tex);\r\n } else {\r\n console.error('Invalid texture type');\r\n }\r\n }\r\n material.setDetailMapRoughness(i, info.roughness ?? 1);\r\n material.setDetailMapUVScale(i, info.uvscale ?? 100);\r\n }\r\n }\r\n },\r\n {\r\n name: 'SplatMap',\r\n description: 'Serialized splat-map texture data for terrain layers',\r\n type: 'embedded',\r\n default: null,\r\n isHidden() {\r\n return true;\r\n },\r\n get(this: ClipmapTerrain, value) {\r\n value.str[0] = this.splatMapAssetId;\r\n value.object[0] = getTerrainSplatMapContent(this);\r\n },\r\n async set(this: ClipmapTerrain, value) {\r\n if (value.str[0]) {\r\n const path = value.str[0];\r\n const data = (await manager.VFS.readFile(path, { encoding: 'binary' })) as ArrayBuffer;\r\n if (!data) {\r\n console.error('Load height map failed');\r\n return;\r\n }\r\n const dataView = new DataView(data);\r\n const width = dataView.getUint32(0, true);\r\n const height = dataView.getUint32(4, true);\r\n const numLayers = dataView.getUint32(8, true);\r\n const splatMap = this.splatMap!;\r\n if (splatMap.width !== width || splatMap.height !== height) {\r\n console.error('Invalid splatmap data');\r\n return;\r\n }\r\n for (let i = 0; i < numLayers; i++) {\r\n const content = new Uint8Array(data, 3 * 4 + i * width * height * 4, width * height * 4);\r\n splatMap.update(content, 0, 0, i, width, height, 1);\r\n }\r\n this.splatMapAssetId = value.str[0];\r\n }\r\n }\r\n },\r\n {\r\n name: 'Grass',\r\n description: 'Serialized grass instance data for the terrain',\r\n type: 'embedded',\r\n default: null,\r\n phase: 1,\r\n isHidden() {\r\n return true;\r\n },\r\n get(this: ClipmapTerrain, value) {\r\n value.str[0] = this.grassAssetId;\r\n value.object[0] = getTerrainGrassContent(this);\r\n },\r\n async set(this: ClipmapTerrain, value) {\r\n if (value.str[0]) {\r\n const path = value.str[0];\r\n const data = (await manager.VFS.readFile(path, { encoding: 'binary' })) as ArrayBuffer;\r\n if (!data) {\r\n console.error('Load grass data failed');\r\n return;\r\n }\r\n const dataView = new DataView(data);\r\n let offset = 0;\r\n const numLayers = dataView.getUint32(offset, true);\r\n if (numLayers !== this.grassRenderer.numLayers) {\r\n console.error('Number of grass layers mismatch');\r\n return;\r\n }\r\n offset += 4;\r\n for (let i = 0; i < numLayers; i++) {\r\n const dataSize = dataView.getUint32(offset, true);\r\n offset += 4;\r\n if (dataSize > 0) {\r\n const data = new Float32Array(dataView.buffer, dataView.byteOffset + offset, dataSize >> 2);\r\n const numInstances = data.length >> 2;\r\n const instances: GrassInstanceInfo[] = [];\r\n for (let i = 0; i < numInstances; i++) {\r\n instances.push({\r\n x: data[i * 4 + 0],\r\n y: data[i * 4 + 1],\r\n angle: Math.atan2(data[i * 4 + 2], data[i * 4 + 3])\r\n });\r\n }\r\n this.grassRenderer.addInstances(i, instances);\r\n offset += dataSize;\r\n }\r\n }\r\n this.grassAssetId = value.str[0];\r\n }\r\n }\r\n },\r\n {\r\n name: 'HeightMap',\r\n description: 'Serialized terrain height map data',\r\n type: 'embedded',\r\n default: null,\r\n isHidden() {\r\n return true;\r\n },\r\n get(this: ClipmapTerrain, value) {\r\n value.str[0] = this.heightMapAssetId;\r\n value.object[0] = getTerrainHeightMapContent(this);\r\n },\r\n async set(this: ClipmapTerrain, value) {\r\n if (value.str[0]) {\r\n const path = value.str[0];\r\n const data = (await manager.VFS.readFile(path, { encoding: 'binary' })) as ArrayBuffer;\r\n if (!data) {\r\n console.error('Load height map failed');\r\n return;\r\n }\r\n const dataView = new DataView(data);\r\n const width = dataView.getUint32(0, true);\r\n const height = dataView.getUint32(4, true);\r\n const heightMap = this.createHeightMapTexture(width, height)!;\r\n if (heightMap.format !== 'r16f') {\r\n if (heightMap.format === 'rgba16f') {\r\n // WebGL1 uses rgba16f for height map, so we need to convert\r\n const rgbaData = new Uint16Array(width * height * 4);\r\n const rData = new Uint16Array(data, 8);\r\n for (let i = 0; i < width * height; i++) {\r\n rgbaData[i * 4 + 0] = rData[i];\r\n }\r\n heightMap.update(rgbaData, 0, 0, width, height);\r\n } else {\r\n throw new Error(`Unsupported height map format: ${heightMap.format}`);\r\n }\r\n } else {\r\n heightMap.update(new Uint16Array(data, 8), 0, 0, width, height);\r\n }\r\n this.heightMap = heightMap;\r\n this.heightMapAssetId = value.str[0];\r\n this.updateBoundingBox();\r\n }\r\n }\r\n }\r\n ]);\r\n }\r\n };\r\n}\r\n"],"names":["mergeTypedArrays","ctor","arrays","totalLength","reduce","acc","arr","length","result","offset","array","set","getTerrainGrassContent","terrain","grassRenderer","layerDatas","dataSize","numLayers","i","promises","layer","getLayer","queue","quadtree","quadtreeNode","shift","children","push","grassInstances","numInstances","instanceBuffer","P","getBufferSubData","data","Promise","all","merged","Uint8Array","DataView","ArrayBuffer","view","buffer","byteOffset","byteLength","setUint32","getTerrainHeightMapContent","heightmap","heightMap","width","height","head","Uint16Array","format","readPixels","tmpData","getTerrainSplatMapContent","device","getDevice","splatMap","material","numDetailMaps","info","getDeviceCaps","textureCaps","getTextureFormatInfo","blockWidth","blockHeight","size","layerData","getTerrainClass","manager","ClipmapTerrain","name","parent","GraphNode","createFunc","ctx","init","node","scene","obj","getInitParams","getProps","defineProps","description","type","default","options","minValue","maxValue","get","value","num","sizeX","sizeZ","setSize","bool","castShadow","isPersistent","wireframe","enum","labels","values","str","debugMode","objectTypes","JSONArray","phase","isNullable","isHidden","grassTexture","getGrassTexture","assetId","getAssetId","texture","bladeWidth","getBladeWidth","bladeHeight","getBladeHeight","object","json","fetchTexture","err","console","error","isTexture2D","dispose","addLayer","albedo","getDetailMap","normal","getDetailNormalMap","roughness","getDetailMapRoughness","uvscale","getDetailMapUVScale","setDetailMap","tex","setDetailNormalMap","setDetailMapRoughness","setDetailMapUVScale","splatMapAssetId","path","VFS","readFile","encoding","dataView","getUint32","content","update","grassAssetId","Float32Array","instances","x","y","angle","Math","atan2","addInstances","heightMapAssetId","createHeightMapTexture","rgbaData","rData","Error","updateBoundingBox"],"mappings":"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"}
1
+ {"version":3,"file":"terrain.js","sources":["../../../../src/utility/serialization/scene/terrain.ts"],"sourcesContent":["import { GraphNode, type SceneNode } from '../../../scene';\r\nimport { defineProps, type SerializableClass } from '../types';\r\nimport { ClipmapTerrain } from '../../../scene/terrain-cm/terrain-cm';\r\nimport type { TerrainDebugMode } from '../../../material';\r\nimport type { Texture2D } from '@zephyr3d/device';\r\nimport type { Nullable } from '@zephyr3d/base';\r\nimport type { ResourceManager } from '../manager';\r\nimport { JSONArray } from '../json';\r\nimport { getDevice } from '../../../app/api';\r\n\r\n// 'GRAS' in little endian. The legacy per-instance format starts with the\r\n// layer count, so any realistic legacy file can not collide with this magic.\r\nconst GRASS_DATA_MAGIC = 0x53415247;\r\nconst GRASS_DATA_VERSION = 1;\r\n\r\nfunction getTerrainGrassContent(terrain: ClipmapTerrain): ArrayBuffer {\r\n const grassRenderer = terrain.grassRenderer;\r\n const numLayers = grassRenderer.numLayers;\r\n let dataSize = 3 * 4;\r\n for (let i = 0; i < numLayers; i++) {\r\n dataSize += 4 * 4 + grassRenderer.getLayer(i).densityMap.length;\r\n }\r\n const data = new DataView(new ArrayBuffer(dataSize));\r\n const view = new Uint8Array(data.buffer);\r\n let offset = 0;\r\n data.setUint32(offset, GRASS_DATA_MAGIC, true);\r\n offset += 4;\r\n data.setUint32(offset, GRASS_DATA_VERSION, true);\r\n offset += 4;\r\n data.setUint32(offset, numLayers, true);\r\n offset += 4;\r\n for (let i = 0; i < numLayers; i++) {\r\n const layer = grassRenderer.getLayer(i);\r\n data.setUint32(offset, layer.densityMapWidth, true);\r\n offset += 4;\r\n data.setUint32(offset, layer.densityMapHeight, true);\r\n offset += 4;\r\n data.setUint32(offset, layer.cellsPerTexel, true);\r\n offset += 4;\r\n data.setUint32(offset, layer.densityMap.length, true);\r\n offset += 4;\r\n view.set(layer.densityMap, offset);\r\n offset += layer.densityMap.length;\r\n }\r\n return data.buffer;\r\n}\r\n\r\n/**\r\n * Imports grass data saved by the legacy per-instance format by baking the\r\n * blade instances into the per-layer density maps. Blade positions will be\r\n * re-derived from the density, so they will not match the original ones\r\n * exactly, but the local density is preserved.\r\n */\r\nfunction importLegacyGrassInstances(terrain: ClipmapTerrain, dataView: DataView): boolean {\r\n const grassRenderer = terrain.grassRenderer;\r\n const numLayers = dataView.getUint32(0, true);\r\n if (numLayers !== grassRenderer.numLayers) {\r\n console.error('Number of grass layers mismatch');\r\n return false;\r\n }\r\n let offset = 4;\r\n for (let i = 0; i < numLayers; i++) {\r\n const dataSize = dataView.getUint32(offset, true);\r\n offset += 4;\r\n if (dataSize > 0) {\r\n const layer = grassRenderer.getLayer(i);\r\n const w = layer.densityMapWidth;\r\n const h = layer.densityMapHeight;\r\n const counts = new Uint32Array(w * h);\r\n // legacy instance layout: x, y, sin(angle), cos(angle) as floats\r\n const floats = new Float32Array(dataView.buffer, dataView.byteOffset + offset, dataSize >> 2);\r\n const numInstances = floats.length >> 2;\r\n for (let j = 0; j < numInstances; j++) {\r\n const x = Math.min(Math.max(Math.floor(floats[j * 4 + 0] * w), 0), w - 1);\r\n const z = Math.min(Math.max(Math.floor(floats[j * 4 + 1] * h), 0), h - 1);\r\n counts[z * w + x]++;\r\n }\r\n const density = layer.densityMap;\r\n const maxPerTexel = layer.cellsPerTexel * layer.cellsPerTexel;\r\n for (let t = 0; t < counts.length; t++) {\r\n if (counts[t] > 0) {\r\n density[t] = Math.min(255, Math.round((counts[t] / maxPerTexel) * 255));\r\n }\r\n }\r\n layer.updateDensityRegion(0, 0, w, h);\r\n offset += dataSize;\r\n }\r\n }\r\n return true;\r\n}\r\n\r\nasync function getTerrainHeightMapContent(terrain: ClipmapTerrain): Promise<ArrayBuffer> {\r\n const heightmap = terrain.heightMap!;\r\n const buffer = new ArrayBuffer(2 * 4 + heightmap.width * heightmap.height * 2);\r\n const head = new DataView(buffer);\r\n head.setUint32(0, heightmap.width, true);\r\n head.setUint32(4, heightmap.height, true);\r\n const data = new Uint16Array(buffer, 2 * 4);\r\n if (heightmap.format === 'r16f') {\r\n await heightmap.readPixels(0, 0, heightmap.width, heightmap.height, 0, 0, data);\r\n } else if (heightmap.format === 'rgba16f') {\r\n // WebGL1 uses rgba16f for height map, so we need to convert\r\n const tmpData = new Uint16Array(heightmap.width * heightmap.height * 4);\r\n await heightmap.readPixels(0, 0, heightmap.width, heightmap.height, 0, 0, tmpData);\r\n for (let i = 0; i < heightmap.width * heightmap.height; i++) {\r\n data[i] = tmpData[i * 4 + 0]; // Use the red channel as height\r\n }\r\n }\r\n return buffer;\r\n}\r\n\r\nasync function getTerrainSplatMapContent(terrain: ClipmapTerrain): Promise<ArrayBuffer> {\r\n const device = getDevice();\r\n const splatMap = terrain.splatMap!;\r\n const numLayers = (terrain.material!.numDetailMaps + 3) >> 2;\r\n const info = device.getDeviceCaps().textureCaps.getTextureFormatInfo(splatMap.format);\r\n const buffer = new ArrayBuffer(\r\n 3 * 4 + numLayers * splatMap.width * splatMap.height * info.blockWidth * info.blockHeight * info.size\r\n );\r\n const head = new DataView(buffer);\r\n head.setUint32(0, splatMap.width, true);\r\n head.setUint32(4, splatMap.height, true);\r\n head.setUint32(8, numLayers, true);\r\n for (let i = 0; i < numLayers; i++) {\r\n const layerData = new Uint8Array(\r\n buffer,\r\n 3 * 4 + i * splatMap.width * splatMap.height * info.blockWidth * info.blockHeight * info.size\r\n );\r\n await splatMap.readPixels(0, 0, splatMap.width, splatMap.height, 0, 0, layerData);\r\n }\r\n return buffer;\r\n}\r\n\r\n/** @internal */\r\nexport function getTerrainClass(manager: ResourceManager): SerializableClass {\r\n return {\r\n ctor: ClipmapTerrain,\r\n name: 'ClipmapTerrain',\r\n parent: GraphNode,\r\n createFunc(ctx: SceneNode, init: number) {\r\n const node = new ClipmapTerrain(ctx.scene!);\r\n node.numDetailMaps = init;\r\n node.parent = ctx;\r\n return { obj: node };\r\n },\r\n getInitParams(obj: ClipmapTerrain) {\r\n return obj.numDetailMaps;\r\n },\r\n getProps() {\r\n return defineProps([\r\n {\r\n name: 'Resolution',\r\n description: 'Terrain resolution',\r\n type: 'int2',\r\n default: [256, 256],\r\n options: { minValue: 1, maxValue: 4096 },\r\n get(this: ClipmapTerrain, value) {\r\n value.num[0] = this.sizeX;\r\n value.num[1] = this.sizeZ;\r\n },\r\n set(this: ClipmapTerrain, value) {\r\n this.setSize(value.num[0], value.num[1]);\r\n }\r\n },\r\n {\r\n name: 'CastShadow',\r\n description: 'If true, the terrain can cast shadows',\r\n type: 'bool',\r\n default: true,\r\n get(this: ClipmapTerrain, value) {\r\n value.bool[0] = this.castShadow;\r\n },\r\n set(this: ClipmapTerrain, value) {\r\n this.castShadow = value.bool[0];\r\n }\r\n },\r\n {\r\n name: 'Wireframe',\r\n description: 'If true, the terrain will be rendered as wireframe',\r\n type: 'bool',\r\n default: false,\r\n isPersistent() {\r\n return false;\r\n },\r\n get(this: ClipmapTerrain, value) {\r\n value.bool[0] = this.wireframe;\r\n },\r\n set(this: ClipmapTerrain, value) {\r\n this.wireframe = value.bool[0];\r\n }\r\n },\r\n {\r\n name: 'Debug',\r\n description: 'Debug visualization mode for the terrain material',\r\n type: 'string',\r\n options: {\r\n enum: {\r\n labels: ['None', 'UV', 'VertexNormal', 'DetailNormal', 'Tangent', 'Binormal', 'Albedo'],\r\n values: ['none', 'uv', 'vertex_normal', 'detail_normal', 'tangent', 'bitangent', 'albedo']\r\n }\r\n },\r\n default: 'none',\r\n isPersistent() {\r\n return false;\r\n },\r\n get(this: ClipmapTerrain, value) {\r\n value.str[0] = this.material!.debugMode;\r\n },\r\n set(this: ClipmapTerrain, value) {\r\n this.material!.debugMode = value.str[0] as TerrainDebugMode;\r\n }\r\n },\r\n {\r\n name: 'GrassMaps',\r\n description: 'Serialized grass texture layers and blade settings',\r\n type: 'object',\r\n default: null,\r\n options: { objectTypes: [JSONArray] },\r\n phase: 0,\r\n isNullable() {\r\n return true;\r\n },\r\n isHidden() {\r\n return false;\r\n },\r\n get(this: ClipmapTerrain, value) {\r\n const data: { texture: string; bladeWidth: number; bladeHeight: number }[] = [];\r\n const numLayers = this.grassRenderer.numLayers;\r\n for (let i = 0; i < numLayers; i++) {\r\n const grassTexture = this.grassRenderer.getGrassTexture(i);\r\n const assetId = grassTexture ? (manager.getAssetId(grassTexture) ?? '') : '';\r\n data.push({\r\n texture: assetId,\r\n bladeWidth: this.grassRenderer.getBladeWidth(i),\r\n bladeHeight: this.grassRenderer.getBladeHeight(i)\r\n });\r\n }\r\n value.object[0] = new JSONArray(null, data);\r\n },\r\n async set(this: ClipmapTerrain, value) {\r\n const json = value.object[0] as JSONArray;\r\n const data =\r\n (json?.data as {\r\n texture: string;\r\n bladeWidth: number;\r\n bladeHeight: number;\r\n }[]) ?? [];\r\n for (let i = 0; i < data.length; i++) {\r\n const info = data[i];\r\n const assetId = info.texture;\r\n let texture: Nullable<Texture2D> = null;\r\n if (assetId) {\r\n try {\r\n texture = await manager.fetchTexture<Texture2D>(assetId);\r\n } catch (err) {\r\n console.error(`Load asset failed: ${value.str[0]}: ${err}`);\r\n texture = null;\r\n }\r\n if (!texture?.isTexture2D()) {\r\n console.error('Invalid texture type');\r\n texture?.dispose();\r\n texture = null;\r\n }\r\n }\r\n this.grassRenderer.addLayer(info.bladeWidth ?? 1, info.bladeHeight ?? 1, texture!);\r\n }\r\n }\r\n },\r\n {\r\n name: 'DetailMaps',\r\n description: 'Serialized terrain detail texture layers',\r\n type: 'object',\r\n default: null,\r\n options: { objectTypes: [JSONArray] },\r\n isNullable() {\r\n return true;\r\n },\r\n isHidden() {\r\n return false;\r\n },\r\n get(this: ClipmapTerrain, value) {\r\n const data: { albedo: string; normal: string; roughness: number; uvscale: number }[] = [];\r\n const material = this.material!;\r\n for (let i = 0; i < material.numDetailMaps; i++) {\r\n data.push({\r\n albedo: manager.getAssetId(material.getDetailMap(i)) ?? '',\r\n normal: manager.getAssetId(material.getDetailNormalMap(i)) ?? '',\r\n roughness: material.getDetailMapRoughness(i),\r\n uvscale: material.getDetailMapUVScale(i)\r\n });\r\n }\r\n value.object[0] = new JSONArray(null, data);\r\n },\r\n async set(this: ClipmapTerrain, value) {\r\n const json = value.object[0] as JSONArray;\r\n if (!json) {\r\n this.material!.numDetailMaps = 0;\r\n return;\r\n }\r\n const data =\r\n (json.data as {\r\n albedo: string;\r\n normal: string;\r\n roughness: number;\r\n uvscale: number;\r\n }[]) ?? [];\r\n const material = this.material!;\r\n material.numDetailMaps = data.length;\r\n for (let i = 0; i < this.numDetailMaps; i++) {\r\n const info = data[i];\r\n if (!info?.albedo) {\r\n material.setDetailMap(i, null);\r\n } else {\r\n let tex: Nullable<Texture2D>;\r\n try {\r\n tex = await manager.fetchTexture<Texture2D>(info.albedo);\r\n } catch (err) {\r\n console.error(`Load asset failed: ${value.str[0]}: ${err}`);\r\n tex = null;\r\n }\r\n if (tex?.isTexture2D()) {\r\n material.setDetailMap(i, tex);\r\n } else {\r\n console.error('Invalid texture type');\r\n }\r\n }\r\n if (!info?.normal) {\r\n material.setDetailNormalMap(i, null);\r\n } else {\r\n let tex: Nullable<Texture2D>;\r\n try {\r\n tex = await manager.fetchTexture<Texture2D>(info.normal);\r\n } catch (err) {\r\n console.error(`Load asset failed: ${value.str[0]}: ${err}`);\r\n tex = null;\r\n }\r\n if (tex?.isTexture2D()) {\r\n material.setDetailMap(i, tex);\r\n } else {\r\n console.error('Invalid texture type');\r\n }\r\n }\r\n material.setDetailMapRoughness(i, info.roughness ?? 1);\r\n material.setDetailMapUVScale(i, info.uvscale ?? 100);\r\n }\r\n }\r\n },\r\n {\r\n name: 'SplatMap',\r\n description: 'Serialized splat-map texture data for terrain layers',\r\n type: 'embedded',\r\n default: null,\r\n isHidden() {\r\n return true;\r\n },\r\n get(this: ClipmapTerrain, value) {\r\n value.str[0] = this.splatMapAssetId;\r\n value.object[0] = getTerrainSplatMapContent(this);\r\n },\r\n async set(this: ClipmapTerrain, value) {\r\n if (value.str[0]) {\r\n const path = value.str[0];\r\n const data = (await manager.VFS.readFile(path, { encoding: 'binary' })) as ArrayBuffer;\r\n if (!data) {\r\n console.error('Load height map failed');\r\n return;\r\n }\r\n const dataView = new DataView(data);\r\n const width = dataView.getUint32(0, true);\r\n const height = dataView.getUint32(4, true);\r\n const numLayers = dataView.getUint32(8, true);\r\n const splatMap = this.splatMap!;\r\n if (splatMap.width !== width || splatMap.height !== height) {\r\n console.error('Invalid splatmap data');\r\n return;\r\n }\r\n for (let i = 0; i < numLayers; i++) {\r\n const content = new Uint8Array(data, 3 * 4 + i * width * height * 4, width * height * 4);\r\n splatMap.update(content, 0, 0, i, width, height, 1);\r\n }\r\n this.splatMapAssetId = value.str[0];\r\n }\r\n }\r\n },\r\n {\r\n name: 'Grass',\r\n description: 'Serialized grass instance data for the terrain',\r\n type: 'embedded',\r\n default: null,\r\n phase: 1,\r\n isHidden() {\r\n return true;\r\n },\r\n get(this: ClipmapTerrain, value) {\r\n value.str[0] = this.grassAssetId;\r\n value.object[0] = getTerrainGrassContent(this);\r\n },\r\n async set(this: ClipmapTerrain, value) {\r\n if (value.str[0]) {\r\n const path = value.str[0];\r\n const data = (await manager.VFS.readFile(path, { encoding: 'binary' })) as ArrayBuffer;\r\n if (!data || data.byteLength < 4) {\r\n console.error('Load grass data failed');\r\n return;\r\n }\r\n const dataView = new DataView(data);\r\n if (dataView.getUint32(0, true) === GRASS_DATA_MAGIC) {\r\n // density map format, version at offset 4 is currently always 1\r\n const numLayers = dataView.getUint32(8, true);\r\n if (numLayers !== this.grassRenderer.numLayers) {\r\n console.error('Number of grass layers mismatch');\r\n return;\r\n }\r\n let offset = 12;\r\n for (let i = 0; i < numLayers; i++) {\r\n const width = dataView.getUint32(offset, true);\r\n const height = dataView.getUint32(offset + 4, true);\r\n const cellsPerTexel = dataView.getUint32(offset + 8, true);\r\n const byteLength = dataView.getUint32(offset + 12, true);\r\n offset += 16;\r\n const densityData = new Uint8Array(data, offset, byteLength).slice();\r\n offset += byteLength;\r\n this.grassRenderer.getLayer(i).setDensityData(width, height, cellsPerTexel, densityData);\r\n }\r\n } else if (!importLegacyGrassInstances(this, dataView)) {\r\n return;\r\n }\r\n this.grassAssetId = value.str[0];\r\n }\r\n }\r\n },\r\n {\r\n name: 'HeightMap',\r\n description: 'Serialized terrain height map data',\r\n type: 'embedded',\r\n default: null,\r\n isHidden() {\r\n return true;\r\n },\r\n get(this: ClipmapTerrain, value) {\r\n value.str[0] = this.heightMapAssetId;\r\n value.object[0] = getTerrainHeightMapContent(this);\r\n },\r\n async set(this: ClipmapTerrain, value) {\r\n if (value.str[0]) {\r\n const path = value.str[0];\r\n const data = (await manager.VFS.readFile(path, { encoding: 'binary' })) as ArrayBuffer;\r\n if (!data) {\r\n console.error('Load height map failed');\r\n return;\r\n }\r\n const dataView = new DataView(data);\r\n const width = dataView.getUint32(0, true);\r\n const height = dataView.getUint32(4, true);\r\n const heightMap = this.createHeightMapTexture(width, height)!;\r\n if (heightMap.format !== 'r16f') {\r\n if (heightMap.format === 'rgba16f') {\r\n // WebGL1 uses rgba16f for height map, so we need to convert\r\n const rgbaData = new Uint16Array(width * height * 4);\r\n const rData = new Uint16Array(data, 8);\r\n for (let i = 0; i < width * height; i++) {\r\n rgbaData[i * 4 + 0] = rData[i];\r\n }\r\n heightMap.update(rgbaData, 0, 0, width, height);\r\n } else {\r\n throw new Error(`Unsupported height map format: ${heightMap.format}`);\r\n }\r\n } else {\r\n heightMap.update(new Uint16Array(data, 8), 0, 0, width, height);\r\n }\r\n this.heightMap = heightMap;\r\n this.heightMapAssetId = value.str[0];\r\n this.updateBoundingBox();\r\n }\r\n }\r\n }\r\n ]);\r\n }\r\n };\r\n}\r\n"],"names":["GRASS_DATA_MAGIC","GRASS_DATA_VERSION","getTerrainGrassContent","terrain","grassRenderer","numLayers","dataSize","i","getLayer","densityMap","length","data","DataView","ArrayBuffer","view","Uint8Array","buffer","offset","setUint32","layer","densityMapWidth","densityMapHeight","cellsPerTexel","set","importLegacyGrassInstances","dataView","getUint32","console","error","w","h","counts","Uint32Array","floats","Float32Array","byteOffset","numInstances","j","x","Math","min","max","floor","z","density","maxPerTexel","t","round","updateDensityRegion","getTerrainHeightMapContent","heightmap","heightMap","width","height","head","Uint16Array","format","readPixels","tmpData","getTerrainSplatMapContent","device","getDevice","splatMap","material","numDetailMaps","info","getDeviceCaps","textureCaps","getTextureFormatInfo","blockWidth","blockHeight","size","layerData","getTerrainClass","manager","ctor","ClipmapTerrain","name","parent","GraphNode","createFunc","ctx","init","node","scene","obj","getInitParams","getProps","defineProps","description","type","default","options","minValue","maxValue","get","value","num","sizeX","sizeZ","setSize","bool","castShadow","isPersistent","wireframe","enum","labels","values","str","debugMode","objectTypes","JSONArray","phase","isNullable","isHidden","grassTexture","getGrassTexture","assetId","getAssetId","push","texture","bladeWidth","getBladeWidth","bladeHeight","getBladeHeight","object","json","fetchTexture","err","isTexture2D","dispose","addLayer","albedo","getDetailMap","normal","getDetailNormalMap","roughness","getDetailMapRoughness","uvscale","getDetailMapUVScale","setDetailMap","tex","setDetailNormalMap","setDetailMapRoughness","setDetailMapUVScale","splatMapAssetId","path","VFS","readFile","encoding","content","update","grassAssetId","byteLength","densityData","slice","setDensityData","heightMapAssetId","createHeightMapTexture","rgbaData","rData","Error","updateBoundingBox"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUA;AACA;AACA,MAAMA,gBAAmB,GAAA,UAAA;AACzB,MAAMC,kBAAqB,GAAA,CAAA;AAE3B,SAASC,uBAAuBC,OAAuB,EAAA;IACrD,MAAMC,aAAAA,GAAgBD,QAAQC,aAAa;IAC3C,MAAMC,SAAAA,GAAYD,cAAcC,SAAS;AACzC,IAAA,IAAIC,WAAW,CAAI,GAAA,CAAA;AACnB,IAAA,IAAK,IAAIC,CAAAA,GAAI,CAAGA,EAAAA,CAAAA,GAAIF,WAAWE,CAAK,EAAA,CAAA;QAClCD,QAAY,IAAA,CAAA,GAAI,IAAIF,aAAcI,CAAAA,QAAQ,CAACD,CAAGE,CAAAA,CAAAA,UAAU,CAACC,MAAM;AACjE;AACA,IAAA,MAAMC,IAAO,GAAA,IAAIC,QAAS,CAAA,IAAIC,WAAYP,CAAAA,QAAAA,CAAAA,CAAAA;AAC1C,IAAA,MAAMQ,IAAO,GAAA,IAAIC,UAAWJ,CAAAA,IAAAA,CAAKK,MAAM,CAAA;AACvC,IAAA,IAAIC,MAAS,GAAA,CAAA;IACbN,IAAKO,CAAAA,SAAS,CAACD,MAAAA,EAAQjB,gBAAkB,EAAA,IAAA,CAAA;IACzCiB,MAAU,IAAA,CAAA;IACVN,IAAKO,CAAAA,SAAS,CAACD,MAAAA,EAAQhB,kBAAoB,EAAA,IAAA,CAAA;IAC3CgB,MAAU,IAAA,CAAA;IACVN,IAAKO,CAAAA,SAAS,CAACD,MAAAA,EAAQZ,SAAW,EAAA,IAAA,CAAA;IAClCY,MAAU,IAAA,CAAA;AACV,IAAA,IAAK,IAAIV,CAAAA,GAAI,CAAGA,EAAAA,CAAAA,GAAIF,WAAWE,CAAK,EAAA,CAAA;QAClC,MAAMY,KAAAA,GAAQf,aAAcI,CAAAA,QAAQ,CAACD,CAAAA,CAAAA;AACrCI,QAAAA,IAAAA,CAAKO,SAAS,CAACD,MAAQE,EAAAA,KAAAA,CAAMC,eAAe,EAAE,IAAA,CAAA;QAC9CH,MAAU,IAAA,CAAA;AACVN,QAAAA,IAAAA,CAAKO,SAAS,CAACD,MAAQE,EAAAA,KAAAA,CAAME,gBAAgB,EAAE,IAAA,CAAA;QAC/CJ,MAAU,IAAA,CAAA;AACVN,QAAAA,IAAAA,CAAKO,SAAS,CAACD,MAAQE,EAAAA,KAAAA,CAAMG,aAAa,EAAE,IAAA,CAAA;QAC5CL,MAAU,IAAA,CAAA;AACVN,QAAAA,IAAAA,CAAKO,SAAS,CAACD,MAAAA,EAAQE,MAAMV,UAAU,CAACC,MAAM,EAAE,IAAA,CAAA;QAChDO,MAAU,IAAA,CAAA;AACVH,QAAAA,IAAAA,CAAKS,GAAG,CAACJ,KAAMV,CAAAA,UAAU,EAAEQ,MAAAA,CAAAA;QAC3BA,MAAUE,IAAAA,KAAAA,CAAMV,UAAU,CAACC,MAAM;AACnC;AACA,IAAA,OAAOC,KAAKK,MAAM;AACpB;AAEA;;;;;AAKC,IACD,SAASQ,0BAAAA,CAA2BrB,OAAuB,EAAEsB,QAAkB,EAAA;IAC7E,MAAMrB,aAAAA,GAAgBD,QAAQC,aAAa;AAC3C,IAAA,MAAMC,SAAYoB,GAAAA,QAAAA,CAASC,SAAS,CAAC,CAAG,EAAA,IAAA,CAAA;IACxC,IAAIrB,SAAAA,KAAcD,aAAcC,CAAAA,SAAS,EAAE;AACzCsB,QAAAA,OAAAA,CAAQC,KAAK,CAAC,iCAAA,CAAA;QACd,OAAO,KAAA;AACT;AACA,IAAA,IAAIX,MAAS,GAAA,CAAA;AACb,IAAA,IAAK,IAAIV,CAAAA,GAAI,CAAGA,EAAAA,CAAAA,GAAIF,WAAWE,CAAK,EAAA,CAAA;AAClC,QAAA,MAAMD,QAAWmB,GAAAA,QAAAA,CAASC,SAAS,CAACT,MAAQ,EAAA,IAAA,CAAA;QAC5CA,MAAU,IAAA,CAAA;AACV,QAAA,IAAIX,WAAW,CAAG,EAAA;YAChB,MAAMa,KAAAA,GAAQf,aAAcI,CAAAA,QAAQ,CAACD,CAAAA,CAAAA;YACrC,MAAMsB,CAAAA,GAAIV,MAAMC,eAAe;YAC/B,MAAMU,CAAAA,GAAIX,MAAME,gBAAgB;YAChC,MAAMU,MAAAA,GAAS,IAAIC,WAAAA,CAAYH,CAAIC,GAAAA,CAAAA,CAAAA;;YAEnC,MAAMG,MAAAA,GAAS,IAAIC,YAAAA,CAAaT,QAAST,CAAAA,MAAM,EAAES,QAASU,CAAAA,UAAU,GAAGlB,MAAAA,EAAQX,QAAY,IAAA,CAAA,CAAA;YAC3F,MAAM8B,YAAAA,GAAeH,MAAOvB,CAAAA,MAAM,IAAI,CAAA;AACtC,YAAA,IAAK,IAAI2B,CAAAA,GAAI,CAAGA,EAAAA,CAAAA,GAAID,cAAcC,CAAK,EAAA,CAAA;AACrC,gBAAA,MAAMC,IAAIC,IAAKC,CAAAA,GAAG,CAACD,IAAKE,CAAAA,GAAG,CAACF,IAAKG,CAAAA,KAAK,CAACT,MAAM,CAACI,CAAI,GAAA,CAAA,GAAI,EAAE,GAAGR,CAAAA,CAAAA,EAAI,IAAIA,CAAI,GAAA,CAAA,CAAA;AACvE,gBAAA,MAAMc,IAAIJ,IAAKC,CAAAA,GAAG,CAACD,IAAKE,CAAAA,GAAG,CAACF,IAAKG,CAAAA,KAAK,CAACT,MAAM,CAACI,CAAI,GAAA,CAAA,GAAI,EAAE,GAAGP,CAAAA,CAAAA,EAAI,IAAIA,CAAI,GAAA,CAAA,CAAA;gBACvEC,MAAM,CAACY,CAAId,GAAAA,CAAAA,GAAIS,CAAE,CAAA,EAAA;AACnB;YACA,MAAMM,OAAAA,GAAUzB,MAAMV,UAAU;AAChC,YAAA,MAAMoC,WAAc1B,GAAAA,KAAAA,CAAMG,aAAa,GAAGH,MAAMG,aAAa;AAC7D,YAAA,IAAK,IAAIwB,CAAI,GAAA,CAAA,EAAGA,IAAIf,MAAOrB,CAAAA,MAAM,EAAEoC,CAAK,EAAA,CAAA;AACtC,gBAAA,IAAIf,MAAM,CAACe,CAAE,CAAA,GAAG,CAAG,EAAA;AACjBF,oBAAAA,OAAO,CAACE,CAAAA,CAAE,GAAGP,IAAAA,CAAKC,GAAG,CAAC,GAAA,EAAKD,IAAKQ,CAAAA,KAAK,CAAC,MAAO,CAACD,CAAAA,CAAE,GAAGD,WAAe,GAAA,GAAA,CAAA,CAAA;AACpE;AACF;AACA1B,YAAAA,KAAAA,CAAM6B,mBAAmB,CAAC,CAAG,EAAA,CAAA,EAAGnB,CAAGC,EAAAA,CAAAA,CAAAA;YACnCb,MAAUX,IAAAA,QAAAA;AACZ;AACF;IACA,OAAO,IAAA;AACT;AAEA,eAAe2C,2BAA2B9C,OAAuB,EAAA;IAC/D,MAAM+C,SAAAA,GAAY/C,QAAQgD,SAAS;IACnC,MAAMnC,MAAAA,GAAS,IAAIH,WAAAA,CAAY,CAAI,GAAA,CAAA,GAAIqC,UAAUE,KAAK,GAAGF,SAAUG,CAAAA,MAAM,GAAG,CAAA,CAAA;IAC5E,MAAMC,IAAAA,GAAO,IAAI1C,QAASI,CAAAA,MAAAA,CAAAA;AAC1BsC,IAAAA,IAAAA,CAAKpC,SAAS,CAAC,CAAGgC,EAAAA,SAAAA,CAAUE,KAAK,EAAE,IAAA,CAAA;AACnCE,IAAAA,IAAAA,CAAKpC,SAAS,CAAC,CAAGgC,EAAAA,SAAAA,CAAUG,MAAM,EAAE,IAAA,CAAA;AACpC,IAAA,MAAM1C,IAAO,GAAA,IAAI4C,WAAYvC,CAAAA,MAAAA,EAAQ,CAAI,GAAA,CAAA,CAAA;IACzC,IAAIkC,SAAAA,CAAUM,MAAM,KAAK,MAAQ,EAAA;AAC/B,QAAA,MAAMN,SAAUO,CAAAA,UAAU,CAAC,CAAA,EAAG,CAAGP,EAAAA,SAAAA,CAAUE,KAAK,EAAEF,SAAUG,CAAAA,MAAM,EAAE,CAAA,EAAG,CAAG1C,EAAAA,IAAAA,CAAAA;AAC5E,KAAA,MAAO,IAAIuC,SAAAA,CAAUM,MAAM,KAAK,SAAW,EAAA;;QAEzC,MAAME,OAAAA,GAAU,IAAIH,WAAYL,CAAAA,SAAAA,CAAUE,KAAK,GAAGF,SAAAA,CAAUG,MAAM,GAAG,CAAA,CAAA;AACrE,QAAA,MAAMH,SAAUO,CAAAA,UAAU,CAAC,CAAA,EAAG,CAAGP,EAAAA,SAAAA,CAAUE,KAAK,EAAEF,SAAUG,CAAAA,MAAM,EAAE,CAAA,EAAG,CAAGK,EAAAA,OAAAA,CAAAA;QAC1E,IAAK,IAAInD,CAAI,GAAA,CAAA,EAAGA,CAAI2C,GAAAA,SAAAA,CAAUE,KAAK,GAAGF,SAAAA,CAAUG,MAAM,EAAE9C,CAAK,EAAA,CAAA;YAC3DI,IAAI,CAACJ,EAAE,GAAGmD,OAAO,CAACnD,CAAI,GAAA,CAAA,GAAI,CAAE,CAAA,CAAA;AAC9B;AACF;IACA,OAAOS,MAAAA;AACT;AAEA,eAAe2C,0BAA0BxD,OAAuB,EAAA;AAC9D,IAAA,MAAMyD,MAASC,GAAAA,SAAAA,EAAAA;IACf,MAAMC,QAAAA,GAAW3D,QAAQ2D,QAAQ;AACjC,IAAA,MAAMzD,YAAY,OAACF,CAAQ4D,QAAQ,CAAEC,aAAa,GAAG,CAAM,IAAA,CAAA;IAC3D,MAAMC,IAAAA,GAAOL,OAAOM,aAAa,EAAA,CAAGC,WAAW,CAACC,oBAAoB,CAACN,QAAAA,CAASN,MAAM,CAAA;AACpF,IAAA,MAAMxC,SAAS,IAAIH,WAAAA,CACjB,IAAI,CAAIR,GAAAA,SAAAA,GAAYyD,SAASV,KAAK,GAAGU,SAAST,MAAM,GAAGY,KAAKI,UAAU,GAAGJ,KAAKK,WAAW,GAAGL,KAAKM,IAAI,CAAA;IAEvG,MAAMjB,IAAAA,GAAO,IAAI1C,QAASI,CAAAA,MAAAA,CAAAA;AAC1BsC,IAAAA,IAAAA,CAAKpC,SAAS,CAAC,CAAG4C,EAAAA,QAAAA,CAASV,KAAK,EAAE,IAAA,CAAA;AAClCE,IAAAA,IAAAA,CAAKpC,SAAS,CAAC,CAAG4C,EAAAA,QAAAA,CAAST,MAAM,EAAE,IAAA,CAAA;IACnCC,IAAKpC,CAAAA,SAAS,CAAC,CAAA,EAAGb,SAAW,EAAA,IAAA,CAAA;AAC7B,IAAA,IAAK,IAAIE,CAAAA,GAAI,CAAGA,EAAAA,CAAAA,GAAIF,WAAWE,CAAK,EAAA,CAAA;QAClC,MAAMiE,SAAAA,GAAY,IAAIzD,UACpBC,CAAAA,MAAAA,EACA,IAAI,CAAIT,GAAAA,CAAAA,GAAIuD,SAASV,KAAK,GAAGU,SAAST,MAAM,GAAGY,KAAKI,UAAU,GAAGJ,KAAKK,WAAW,GAAGL,KAAKM,IAAI,CAAA;AAE/F,QAAA,MAAMT,QAASL,CAAAA,UAAU,CAAC,CAAA,EAAG,CAAGK,EAAAA,QAAAA,CAASV,KAAK,EAAEU,QAAST,CAAAA,MAAM,EAAE,CAAA,EAAG,CAAGmB,EAAAA,SAAAA,CAAAA;AACzE;IACA,OAAOxD,MAAAA;AACT;AAEA,iBACO,SAASyD,eAAAA,CAAgBC,OAAwB,EAAA;IACtD,OAAO;QACLC,IAAMC,EAAAA,cAAAA;QACNC,IAAM,EAAA,gBAAA;QACNC,MAAQC,EAAAA,SAAAA;QACRC,UAAWC,CAAAA,CAAAA,GAAc,EAAEC,IAAY,EAAA;AACrC,YAAA,MAAMC,IAAO,GAAA,IAAIP,cAAeK,CAAAA,GAAAA,CAAIG,KAAK,CAAA;AACzCD,YAAAA,IAAAA,CAAKnB,aAAa,GAAGkB,IAAAA;AACrBC,YAAAA,IAAAA,CAAKL,MAAM,GAAGG,GAAAA;YACd,OAAO;gBAAEI,GAAKF,EAAAA;AAAK,aAAA;AACrB,SAAA;AACAG,QAAAA,aAAAA,CAAAA,CAAcD,GAAmB,EAAA;AAC/B,YAAA,OAAOA,IAAIrB,aAAa;AAC1B,SAAA;AACAuB,QAAAA,QAAAA,CAAAA,GAAAA;AACE,YAAA,OAAOC,WAAY,CAAA;AACjB,gBAAA;oBACEX,IAAM,EAAA,YAAA;oBACNY,WAAa,EAAA,oBAAA;oBACbC,IAAM,EAAA,MAAA;oBACNC,OAAS,EAAA;AAAC,wBAAA,GAAA;AAAK,wBAAA;AAAI,qBAAA;oBACnBC,OAAS,EAAA;wBAAEC,QAAU,EAAA,CAAA;wBAAGC,QAAU,EAAA;AAAK,qBAAA;AACvCC,oBAAAA,GAAAA,CAAAA,CAA0BC,KAAK,EAAA;AAC7BA,wBAAAA,KAAAA,CAAMC,GAAG,CAAC,CAAA,CAAE,GAAG,IAAI,CAACC,KAAK;AACzBF,wBAAAA,KAAAA,CAAMC,GAAG,CAAC,CAAA,CAAE,GAAG,IAAI,CAACE,KAAK;AAC3B,qBAAA;AACA5E,oBAAAA,GAAAA,CAAAA,CAA0ByE,KAAK,EAAA;wBAC7B,IAAI,CAACI,OAAO,CAACJ,KAAMC,CAAAA,GAAG,CAAC,CAAA,CAAE,EAAED,KAAAA,CAAMC,GAAG,CAAC,CAAE,CAAA,CAAA;AACzC;AACF,iBAAA;AACA,gBAAA;oBACEpB,IAAM,EAAA,YAAA;oBACNY,WAAa,EAAA,uCAAA;oBACbC,IAAM,EAAA,MAAA;oBACNC,OAAS,EAAA,IAAA;AACTI,oBAAAA,GAAAA,CAAAA,CAA0BC,KAAK,EAAA;AAC7BA,wBAAAA,KAAAA,CAAMK,IAAI,CAAC,CAAA,CAAE,GAAG,IAAI,CAACC,UAAU;AACjC,qBAAA;AACA/E,oBAAAA,GAAAA,CAAAA,CAA0ByE,KAAK,EAAA;AAC7B,wBAAA,IAAI,CAACM,UAAU,GAAGN,KAAMK,CAAAA,IAAI,CAAC,CAAE,CAAA;AACjC;AACF,iBAAA;AACA,gBAAA;oBACExB,IAAM,EAAA,WAAA;oBACNY,WAAa,EAAA,oDAAA;oBACbC,IAAM,EAAA,MAAA;oBACNC,OAAS,EAAA,KAAA;AACTY,oBAAAA,YAAAA,CAAAA,GAAAA;wBACE,OAAO,KAAA;AACT,qBAAA;AACAR,oBAAAA,GAAAA,CAAAA,CAA0BC,KAAK,EAAA;AAC7BA,wBAAAA,KAAAA,CAAMK,IAAI,CAAC,CAAA,CAAE,GAAG,IAAI,CAACG,SAAS;AAChC,qBAAA;AACAjF,oBAAAA,GAAAA,CAAAA,CAA0ByE,KAAK,EAAA;AAC7B,wBAAA,IAAI,CAACQ,SAAS,GAAGR,KAAMK,CAAAA,IAAI,CAAC,CAAE,CAAA;AAChC;AACF,iBAAA;AACA,gBAAA;oBACExB,IAAM,EAAA,OAAA;oBACNY,WAAa,EAAA,mDAAA;oBACbC,IAAM,EAAA,QAAA;oBACNE,OAAS,EAAA;wBACPa,IAAM,EAAA;4BACJC,MAAQ,EAAA;AAAC,gCAAA,MAAA;AAAQ,gCAAA,IAAA;AAAM,gCAAA,cAAA;AAAgB,gCAAA,cAAA;AAAgB,gCAAA,SAAA;AAAW,gCAAA,UAAA;AAAY,gCAAA;AAAS,6BAAA;4BACvFC,MAAQ,EAAA;AAAC,gCAAA,MAAA;AAAQ,gCAAA,IAAA;AAAM,gCAAA,eAAA;AAAiB,gCAAA,eAAA;AAAiB,gCAAA,SAAA;AAAW,gCAAA,WAAA;AAAa,gCAAA;AAAS;AAC5F;AACF,qBAAA;oBACAhB,OAAS,EAAA,MAAA;AACTY,oBAAAA,YAAAA,CAAAA,GAAAA;wBACE,OAAO,KAAA;AACT,qBAAA;AACAR,oBAAAA,GAAAA,CAAAA,CAA0BC,KAAK,EAAA;wBAC7BA,KAAMY,CAAAA,GAAG,CAAC,CAAE,CAAA,GAAG,IAAI,CAAC7C,QAAQ,CAAE8C,SAAS;AACzC,qBAAA;AACAtF,oBAAAA,GAAAA,CAAAA,CAA0ByE,KAAK,EAAA;wBAC7B,IAAI,CAACjC,QAAQ,CAAE8C,SAAS,GAAGb,KAAMY,CAAAA,GAAG,CAAC,CAAE,CAAA;AACzC;AACF,iBAAA;AACA,gBAAA;oBACE/B,IAAM,EAAA,WAAA;oBACNY,WAAa,EAAA,oDAAA;oBACbC,IAAM,EAAA,QAAA;oBACNC,OAAS,EAAA,IAAA;oBACTC,OAAS,EAAA;wBAAEkB,WAAa,EAAA;AAACC,4BAAAA;AAAU;AAAC,qBAAA;oBACpCC,KAAO,EAAA,CAAA;AACPC,oBAAAA,UAAAA,CAAAA,GAAAA;wBACE,OAAO,IAAA;AACT,qBAAA;AACAC,oBAAAA,QAAAA,CAAAA,GAAAA;wBACE,OAAO,KAAA;AACT,qBAAA;AACAnB,oBAAAA,GAAAA,CAAAA,CAA0BC,KAAK,EAAA;AAC7B,wBAAA,MAAMrF,OAAuE,EAAE;AAC/E,wBAAA,MAAMN,SAAY,GAAA,IAAI,CAACD,aAAa,CAACC,SAAS;AAC9C,wBAAA,IAAK,IAAIE,CAAAA,GAAI,CAAGA,EAAAA,CAAAA,GAAIF,WAAWE,CAAK,EAAA,CAAA;AAClC,4BAAA,MAAM4G,eAAe,IAAI,CAAC/G,aAAa,CAACgH,eAAe,CAAC7G,CAAAA,CAAAA;AACxD,4BAAA,MAAM8G,UAAUF,YAAgBzC,GAAAA,OAAAA,CAAQ4C,UAAU,CAACH,iBAAiB,EAAM,GAAA,EAAA;AAC1ExG,4BAAAA,IAAAA,CAAK4G,IAAI,CAAC;gCACRC,OAASH,EAAAA,OAAAA;AACTI,gCAAAA,UAAAA,EAAY,IAAI,CAACrH,aAAa,CAACsH,aAAa,CAACnH,CAAAA,CAAAA;AAC7CoH,gCAAAA,WAAAA,EAAa,IAAI,CAACvH,aAAa,CAACwH,cAAc,CAACrH,CAAAA;AACjD,6BAAA,CAAA;AACF;AACAyF,wBAAAA,KAAAA,CAAM6B,MAAM,CAAC,CAAA,CAAE,GAAG,IAAId,UAAU,IAAMpG,EAAAA,IAAAA,CAAAA;AACxC,qBAAA;AACA,oBAAA,MAAMY,KAA0ByE,KAAK,EAAA;AACnC,wBAAA,MAAM8B,IAAO9B,GAAAA,KAAAA,CAAM6B,MAAM,CAAC,CAAE,CAAA;AAC5B,wBAAA,MAAMlH,IACJ,GAACmH,IAAMnH,EAAAA,IAAAA,IAIC,EAAE;AACZ,wBAAA,IAAK,IAAIJ,CAAI,GAAA,CAAA,EAAGA,IAAII,IAAKD,CAAAA,MAAM,EAAEH,CAAK,EAAA,CAAA;4BACpC,MAAM0D,IAAAA,GAAOtD,IAAI,CAACJ,CAAE,CAAA;4BACpB,MAAM8G,OAAAA,GAAUpD,KAAKuD,OAAO;AAC5B,4BAAA,IAAIA,OAA+B,GAAA,IAAA;AACnC,4BAAA,IAAIH,OAAS,EAAA;gCACX,IAAI;oCACFG,OAAU,GAAA,MAAM9C,OAAQqD,CAAAA,YAAY,CAAYV,OAAAA,CAAAA;AAClD,iCAAA,CAAE,OAAOW,GAAK,EAAA;AACZrG,oCAAAA,OAAAA,CAAQC,KAAK,CAAC,CAAC,mBAAmB,EAAEoE,KAAAA,CAAMY,GAAG,CAAC,CAAE,CAAA,CAAC,EAAE,EAAEoB,GAAK,CAAA,CAAA,CAAA;oCAC1DR,OAAU,GAAA,IAAA;AACZ;gCACA,IAAI,CAACA,SAASS,WAAe,EAAA,EAAA;AAC3BtG,oCAAAA,OAAAA,CAAQC,KAAK,CAAC,sBAAA,CAAA;oCACd4F,OAASU,EAAAA,OAAAA,EAAAA;oCACTV,OAAU,GAAA,IAAA;AACZ;AACF;AACA,4BAAA,IAAI,CAACpH,aAAa,CAAC+H,QAAQ,CAAClE,IAAAA,CAAKwD,UAAU,IAAI,CAAGxD,EAAAA,IAAAA,CAAK0D,WAAW,IAAI,CAAGH,EAAAA,OAAAA,CAAAA;AAC3E;AACF;AACF,iBAAA;AACA,gBAAA;oBACE3C,IAAM,EAAA,YAAA;oBACNY,WAAa,EAAA,0CAAA;oBACbC,IAAM,EAAA,QAAA;oBACNC,OAAS,EAAA,IAAA;oBACTC,OAAS,EAAA;wBAAEkB,WAAa,EAAA;AAACC,4BAAAA;AAAU;AAAC,qBAAA;AACpCE,oBAAAA,UAAAA,CAAAA,GAAAA;wBACE,OAAO,IAAA;AACT,qBAAA;AACAC,oBAAAA,QAAAA,CAAAA,GAAAA;wBACE,OAAO,KAAA;AACT,qBAAA;AACAnB,oBAAAA,GAAAA,CAAAA,CAA0BC,KAAK,EAAA;AAC7B,wBAAA,MAAMrF,OAAiF,EAAE;wBACzF,MAAMoD,QAAAA,GAAW,IAAI,CAACA,QAAQ;AAC9B,wBAAA,IAAK,IAAIxD,CAAI,GAAA,CAAA,EAAGA,IAAIwD,QAASC,CAAAA,aAAa,EAAEzD,CAAK,EAAA,CAAA;AAC/CI,4BAAAA,IAAAA,CAAK4G,IAAI,CAAC;AACRa,gCAAAA,MAAAA,EAAQ1D,QAAQ4C,UAAU,CAACvD,QAASsE,CAAAA,YAAY,CAAC9H,CAAO,CAAA,CAAA,IAAA,EAAA;AACxD+H,gCAAAA,MAAAA,EAAQ5D,QAAQ4C,UAAU,CAACvD,QAASwE,CAAAA,kBAAkB,CAAChI,CAAO,CAAA,CAAA,IAAA,EAAA;gCAC9DiI,SAAWzE,EAAAA,QAAAA,CAAS0E,qBAAqB,CAAClI,CAAAA,CAAAA;gCAC1CmI,OAAS3E,EAAAA,QAAAA,CAAS4E,mBAAmB,CAACpI,CAAAA;AACxC,6BAAA,CAAA;AACF;AACAyF,wBAAAA,KAAAA,CAAM6B,MAAM,CAAC,CAAA,CAAE,GAAG,IAAId,UAAU,IAAMpG,EAAAA,IAAAA,CAAAA;AACxC,qBAAA;AACA,oBAAA,MAAMY,KAA0ByE,KAAK,EAAA;AACnC,wBAAA,MAAM8B,IAAO9B,GAAAA,KAAAA,CAAM6B,MAAM,CAAC,CAAE,CAAA;AAC5B,wBAAA,IAAI,CAACC,IAAM,EAAA;AACT,4BAAA,IAAI,CAAC/D,QAAQ,CAAEC,aAAa,GAAG,CAAA;AAC/B,4BAAA;AACF;AACA,wBAAA,MAAMrD,IACJ,GAACmH,IAAKnH,CAAAA,IAAI,IAKF,EAAE;wBACZ,MAAMoD,QAAAA,GAAW,IAAI,CAACA,QAAQ;wBAC9BA,QAASC,CAAAA,aAAa,GAAGrD,IAAAA,CAAKD,MAAM;wBACpC,IAAK,IAAIH,IAAI,CAAGA,EAAAA,CAAAA,GAAI,IAAI,CAACyD,aAAa,EAAEzD,CAAK,EAAA,CAAA;4BAC3C,MAAM0D,IAAAA,GAAOtD,IAAI,CAACJ,CAAE,CAAA;4BACpB,IAAI,CAAC0D,MAAMmE,MAAQ,EAAA;gCACjBrE,QAAS6E,CAAAA,YAAY,CAACrI,CAAG,EAAA,IAAA,CAAA;6BACpB,MAAA;gCACL,IAAIsI,GAAAA;gCACJ,IAAI;AACFA,oCAAAA,GAAAA,GAAM,MAAMnE,OAAAA,CAAQqD,YAAY,CAAY9D,KAAKmE,MAAM,CAAA;AACzD,iCAAA,CAAE,OAAOJ,GAAK,EAAA;AACZrG,oCAAAA,OAAAA,CAAQC,KAAK,CAAC,CAAC,mBAAmB,EAAEoE,KAAAA,CAAMY,GAAG,CAAC,CAAE,CAAA,CAAC,EAAE,EAAEoB,GAAK,CAAA,CAAA,CAAA;oCAC1Da,GAAM,GAAA,IAAA;AACR;AACA,gCAAA,IAAIA,KAAKZ,WAAe,EAAA,EAAA;oCACtBlE,QAAS6E,CAAAA,YAAY,CAACrI,CAAGsI,EAAAA,GAAAA,CAAAA;iCACpB,MAAA;AACLlH,oCAAAA,OAAAA,CAAQC,KAAK,CAAC,sBAAA,CAAA;AAChB;AACF;4BACA,IAAI,CAACqC,MAAMqE,MAAQ,EAAA;gCACjBvE,QAAS+E,CAAAA,kBAAkB,CAACvI,CAAG,EAAA,IAAA,CAAA;6BAC1B,MAAA;gCACL,IAAIsI,GAAAA;gCACJ,IAAI;AACFA,oCAAAA,GAAAA,GAAM,MAAMnE,OAAAA,CAAQqD,YAAY,CAAY9D,KAAKqE,MAAM,CAAA;AACzD,iCAAA,CAAE,OAAON,GAAK,EAAA;AACZrG,oCAAAA,OAAAA,CAAQC,KAAK,CAAC,CAAC,mBAAmB,EAAEoE,KAAAA,CAAMY,GAAG,CAAC,CAAE,CAAA,CAAC,EAAE,EAAEoB,GAAK,CAAA,CAAA,CAAA;oCAC1Da,GAAM,GAAA,IAAA;AACR;AACA,gCAAA,IAAIA,KAAKZ,WAAe,EAAA,EAAA;oCACtBlE,QAAS6E,CAAAA,YAAY,CAACrI,CAAGsI,EAAAA,GAAAA,CAAAA;iCACpB,MAAA;AACLlH,oCAAAA,OAAAA,CAAQC,KAAK,CAAC,sBAAA,CAAA;AAChB;AACF;AACAmC,4BAAAA,QAAAA,CAASgF,qBAAqB,CAACxI,CAAG0D,EAAAA,IAAAA,CAAKuE,SAAS,IAAI,CAAA,CAAA;AACpDzE,4BAAAA,QAAAA,CAASiF,mBAAmB,CAACzI,CAAG0D,EAAAA,IAAAA,CAAKyE,OAAO,IAAI,GAAA,CAAA;AAClD;AACF;AACF,iBAAA;AACA,gBAAA;oBACE7D,IAAM,EAAA,UAAA;oBACNY,WAAa,EAAA,sDAAA;oBACbC,IAAM,EAAA,UAAA;oBACNC,OAAS,EAAA,IAAA;AACTuB,oBAAAA,QAAAA,CAAAA,GAAAA;wBACE,OAAO,IAAA;AACT,qBAAA;AACAnB,oBAAAA,GAAAA,CAAAA,CAA0BC,KAAK,EAAA;AAC7BA,wBAAAA,KAAAA,CAAMY,GAAG,CAAC,CAAA,CAAE,GAAG,IAAI,CAACqC,eAAe;AACnCjD,wBAAAA,KAAAA,CAAM6B,MAAM,CAAC,CAAE,CAAA,GAAGlE,0BAA0B,IAAI,CAAA;AAClD,qBAAA;AACA,oBAAA,MAAMpC,KAA0ByE,KAAK,EAAA;AACnC,wBAAA,IAAIA,KAAMY,CAAAA,GAAG,CAAC,CAAA,CAAE,EAAE;AAChB,4BAAA,MAAMsC,IAAOlD,GAAAA,KAAAA,CAAMY,GAAG,CAAC,CAAE,CAAA;AACzB,4BAAA,MAAMjG,OAAQ,MAAM+D,OAAAA,CAAQyE,GAAG,CAACC,QAAQ,CAACF,IAAM,EAAA;gCAAEG,QAAU,EAAA;AAAS,6BAAA,CAAA;AACpE,4BAAA,IAAI,CAAC1I,IAAM,EAAA;AACTgB,gCAAAA,OAAAA,CAAQC,KAAK,CAAC,wBAAA,CAAA;AACd,gCAAA;AACF;4BACA,MAAMH,QAAAA,GAAW,IAAIb,QAASD,CAAAA,IAAAA,CAAAA;AAC9B,4BAAA,MAAMyC,KAAQ3B,GAAAA,QAAAA,CAASC,SAAS,CAAC,CAAG,EAAA,IAAA,CAAA;AACpC,4BAAA,MAAM2B,MAAS5B,GAAAA,QAAAA,CAASC,SAAS,CAAC,CAAG,EAAA,IAAA,CAAA;AACrC,4BAAA,MAAMrB,SAAYoB,GAAAA,QAAAA,CAASC,SAAS,CAAC,CAAG,EAAA,IAAA,CAAA;4BACxC,MAAMoC,QAAAA,GAAW,IAAI,CAACA,QAAQ;AAC9B,4BAAA,IAAIA,SAASV,KAAK,KAAKA,SAASU,QAAST,CAAAA,MAAM,KAAKA,MAAQ,EAAA;AAC1D1B,gCAAAA,OAAAA,CAAQC,KAAK,CAAC,uBAAA,CAAA;AACd,gCAAA;AACF;AACA,4BAAA,IAAK,IAAIrB,CAAAA,GAAI,CAAGA,EAAAA,CAAAA,GAAIF,WAAWE,CAAK,EAAA,CAAA;gCAClC,MAAM+I,OAAAA,GAAU,IAAIvI,UAAAA,CAAWJ,IAAM,EAAA,CAAA,GAAI,CAAIJ,GAAAA,CAAAA,GAAI6C,KAAQC,GAAAA,MAAAA,GAAS,CAAGD,EAAAA,KAAAA,GAAQC,MAAS,GAAA,CAAA,CAAA;AACtFS,gCAAAA,QAAAA,CAASyF,MAAM,CAACD,OAAAA,EAAS,GAAG,CAAG/I,EAAAA,CAAAA,EAAG6C,OAAOC,MAAQ,EAAA,CAAA,CAAA;AACnD;AACA,4BAAA,IAAI,CAAC4F,eAAe,GAAGjD,KAAMY,CAAAA,GAAG,CAAC,CAAE,CAAA;AACrC;AACF;AACF,iBAAA;AACA,gBAAA;oBACE/B,IAAM,EAAA,OAAA;oBACNY,WAAa,EAAA,gDAAA;oBACbC,IAAM,EAAA,UAAA;oBACNC,OAAS,EAAA,IAAA;oBACTqB,KAAO,EAAA,CAAA;AACPE,oBAAAA,QAAAA,CAAAA,GAAAA;wBACE,OAAO,IAAA;AACT,qBAAA;AACAnB,oBAAAA,GAAAA,CAAAA,CAA0BC,KAAK,EAAA;AAC7BA,wBAAAA,KAAAA,CAAMY,GAAG,CAAC,CAAA,CAAE,GAAG,IAAI,CAAC4C,YAAY;AAChCxD,wBAAAA,KAAAA,CAAM6B,MAAM,CAAC,CAAE,CAAA,GAAG3H,uBAAuB,IAAI,CAAA;AAC/C,qBAAA;AACA,oBAAA,MAAMqB,KAA0ByE,KAAK,EAAA;AACnC,wBAAA,IAAIA,KAAMY,CAAAA,GAAG,CAAC,CAAA,CAAE,EAAE;AAChB,4BAAA,MAAMsC,IAAOlD,GAAAA,KAAAA,CAAMY,GAAG,CAAC,CAAE,CAAA;AACzB,4BAAA,MAAMjG,OAAQ,MAAM+D,OAAAA,CAAQyE,GAAG,CAACC,QAAQ,CAACF,IAAM,EAAA;gCAAEG,QAAU,EAAA;AAAS,6BAAA,CAAA;AACpE,4BAAA,IAAI,CAAC1I,IAAAA,IAAQA,IAAK8I,CAAAA,UAAU,GAAG,CAAG,EAAA;AAChC9H,gCAAAA,OAAAA,CAAQC,KAAK,CAAC,wBAAA,CAAA;AACd,gCAAA;AACF;4BACA,MAAMH,QAAAA,GAAW,IAAIb,QAASD,CAAAA,IAAAA,CAAAA;AAC9B,4BAAA,IAAIc,QAASC,CAAAA,SAAS,CAAC,CAAA,EAAG,UAAU1B,gBAAkB,EAAA;;AAEpD,gCAAA,MAAMK,SAAYoB,GAAAA,QAAAA,CAASC,SAAS,CAAC,CAAG,EAAA,IAAA,CAAA;AACxC,gCAAA,IAAIrB,cAAc,IAAI,CAACD,aAAa,CAACC,SAAS,EAAE;AAC9CsB,oCAAAA,OAAAA,CAAQC,KAAK,CAAC,iCAAA,CAAA;AACd,oCAAA;AACF;AACA,gCAAA,IAAIX,MAAS,GAAA,EAAA;AACb,gCAAA,IAAK,IAAIV,CAAAA,GAAI,CAAGA,EAAAA,CAAAA,GAAIF,WAAWE,CAAK,EAAA,CAAA;AAClC,oCAAA,MAAM6C,KAAQ3B,GAAAA,QAAAA,CAASC,SAAS,CAACT,MAAQ,EAAA,IAAA,CAAA;AACzC,oCAAA,MAAMoC,MAAS5B,GAAAA,QAAAA,CAASC,SAAS,CAACT,SAAS,CAAG,EAAA,IAAA,CAAA;AAC9C,oCAAA,MAAMK,aAAgBG,GAAAA,QAAAA,CAASC,SAAS,CAACT,SAAS,CAAG,EAAA,IAAA,CAAA;AACrD,oCAAA,MAAMwI,UAAahI,GAAAA,QAAAA,CAASC,SAAS,CAACT,SAAS,EAAI,EAAA,IAAA,CAAA;oCACnDA,MAAU,IAAA,EAAA;AACV,oCAAA,MAAMyI,cAAc,IAAI3I,UAAAA,CAAWJ,IAAMM,EAAAA,MAAAA,EAAQwI,YAAYE,KAAK,EAAA;oCAClE1I,MAAUwI,IAAAA,UAAAA;oCACV,IAAI,CAACrJ,aAAa,CAACI,QAAQ,CAACD,GAAGqJ,cAAc,CAACxG,KAAOC,EAAAA,MAAAA,EAAQ/B,aAAeoI,EAAAA,WAAAA,CAAAA;AAC9E;AACF,6BAAA,MAAO,IAAI,CAAClI,0BAA2B,CAAA,IAAI,EAAEC,QAAW,CAAA,EAAA;AACtD,gCAAA;AACF;AACA,4BAAA,IAAI,CAAC+H,YAAY,GAAGxD,KAAMY,CAAAA,GAAG,CAAC,CAAE,CAAA;AAClC;AACF;AACF,iBAAA;AACA,gBAAA;oBACE/B,IAAM,EAAA,WAAA;oBACNY,WAAa,EAAA,oCAAA;oBACbC,IAAM,EAAA,UAAA;oBACNC,OAAS,EAAA,IAAA;AACTuB,oBAAAA,QAAAA,CAAAA,GAAAA;wBACE,OAAO,IAAA;AACT,qBAAA;AACAnB,oBAAAA,GAAAA,CAAAA,CAA0BC,KAAK,EAAA;AAC7BA,wBAAAA,KAAAA,CAAMY,GAAG,CAAC,CAAA,CAAE,GAAG,IAAI,CAACiD,gBAAgB;AACpC7D,wBAAAA,KAAAA,CAAM6B,MAAM,CAAC,CAAE,CAAA,GAAG5E,2BAA2B,IAAI,CAAA;AACnD,qBAAA;AACA,oBAAA,MAAM1B,KAA0ByE,KAAK,EAAA;AACnC,wBAAA,IAAIA,KAAMY,CAAAA,GAAG,CAAC,CAAA,CAAE,EAAE;AAChB,4BAAA,MAAMsC,IAAOlD,GAAAA,KAAAA,CAAMY,GAAG,CAAC,CAAE,CAAA;AACzB,4BAAA,MAAMjG,OAAQ,MAAM+D,OAAAA,CAAQyE,GAAG,CAACC,QAAQ,CAACF,IAAM,EAAA;gCAAEG,QAAU,EAAA;AAAS,6BAAA,CAAA;AACpE,4BAAA,IAAI,CAAC1I,IAAM,EAAA;AACTgB,gCAAAA,OAAAA,CAAQC,KAAK,CAAC,wBAAA,CAAA;AACd,gCAAA;AACF;4BACA,MAAMH,QAAAA,GAAW,IAAIb,QAASD,CAAAA,IAAAA,CAAAA;AAC9B,4BAAA,MAAMyC,KAAQ3B,GAAAA,QAAAA,CAASC,SAAS,CAAC,CAAG,EAAA,IAAA,CAAA;AACpC,4BAAA,MAAM2B,MAAS5B,GAAAA,QAAAA,CAASC,SAAS,CAAC,CAAG,EAAA,IAAA,CAAA;AACrC,4BAAA,MAAMyB,SAAY,GAAA,IAAI,CAAC2G,sBAAsB,CAAC1G,KAAOC,EAAAA,MAAAA,CAAAA;4BACrD,IAAIF,SAAAA,CAAUK,MAAM,KAAK,MAAQ,EAAA;gCAC/B,IAAIL,SAAAA,CAAUK,MAAM,KAAK,SAAW,EAAA;;AAElC,oCAAA,MAAMuG,QAAW,GAAA,IAAIxG,WAAYH,CAAAA,KAAAA,GAAQC,MAAS,GAAA,CAAA,CAAA;oCAClD,MAAM2G,KAAAA,GAAQ,IAAIzG,WAAAA,CAAY5C,IAAM,EAAA,CAAA,CAAA;AACpC,oCAAA,IAAK,IAAIJ,CAAI,GAAA,CAAA,EAAGA,CAAI6C,GAAAA,KAAAA,GAAQC,QAAQ9C,CAAK,EAAA,CAAA;AACvCwJ,wCAAAA,QAAQ,CAACxJ,CAAI,GAAA,CAAA,GAAI,EAAE,GAAGyJ,KAAK,CAACzJ,CAAE,CAAA;AAChC;AACA4C,oCAAAA,SAAAA,CAAUoG,MAAM,CAACQ,QAAU,EAAA,CAAA,EAAG,GAAG3G,KAAOC,EAAAA,MAAAA,CAAAA;iCACnC,MAAA;AACL,oCAAA,MAAM,IAAI4G,KAAM,CAAA,CAAC,+BAA+B,EAAE9G,SAAAA,CAAUK,MAAM,CAAE,CAAA,CAAA;AACtE;6BACK,MAAA;gCACLL,SAAUoG,CAAAA,MAAM,CAAC,IAAIhG,WAAAA,CAAY5C,MAAM,CAAI,CAAA,EAAA,CAAA,EAAG,GAAGyC,KAAOC,EAAAA,MAAAA,CAAAA;AAC1D;4BACA,IAAI,CAACF,SAAS,GAAGA,SAAAA;AACjB,4BAAA,IAAI,CAAC0G,gBAAgB,GAAG7D,KAAMY,CAAAA,GAAG,CAAC,CAAE,CAAA;AACpC,4BAAA,IAAI,CAACsD,iBAAiB,EAAA;AACxB;AACF;AACF;AACD,aAAA,CAAA;AACH;AACF,KAAA;AACF;;;;"}