@voluma/vlam 0.2.4 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -4
- package/dist/chunk-loader-DlNwggfG.js +1859 -0
- package/dist/chunk-loader-DlNwggfG.js.map +1 -0
- package/dist/{compute-sorter.d.ts → core/compute-sorter.d.ts} +1 -1
- package/dist/core/index.d.ts +45 -0
- package/dist/{splat-scene.d.ts → core/merged-splat-mesh.d.ts} +14 -15
- package/dist/{orientation.d.ts → core/orientation.d.ts} +7 -7
- package/dist/{relighting.d.ts → core/relighting.d.ts} +1 -1
- package/dist/{source-transform.d.ts → core/source-transform.d.ts} +4 -4
- package/dist/{splat-budget.d.ts → core/splat-budget.d.ts} +2 -2
- package/dist/{splat-data.d.ts → core/splat-data.d.ts} +4 -4
- package/dist/{splat-mesh-material.d.ts → core/splat-mesh-material.d.ts} +2 -2
- package/dist/{splat-mesh-types.d.ts → core/splat-mesh-types.d.ts} +19 -10
- package/dist/{splat-mesh.d.ts → core/splat-mesh.d.ts} +4 -4
- package/dist/{splat-modifier.d.ts → core/splat-modifier.d.ts} +5 -5
- package/dist/{webgpu-limits.d.ts → core/webgpu-limits.d.ts} +0 -59
- package/dist/{effects.d.ts → effects/index.d.ts} +14 -13
- package/dist/effects.js.map +1 -1
- package/dist/formats/ksplat/index.d.ts +1 -1
- package/dist/formats/ksplat/parse-ksplat.d.ts +1 -1
- package/dist/formats/ksplat.js.map +1 -1
- package/dist/formats/lcc/collision-mesh.d.ts +3 -3
- package/dist/formats/lcc/collision-partition.d.ts +1 -1
- package/dist/formats/lcc/lcc.d.ts +3 -3
- package/dist/formats/lcc/lcc2.d.ts +2 -2
- package/dist/formats/lcc/parse-lcc.d.ts +1 -1
- package/dist/formats/lcc.js +17 -16
- package/dist/formats/lcc.js.map +1 -1
- package/dist/formats/ply/index.d.ts +1 -1
- package/dist/formats/ply/parse-compressed-ply.d.ts +2 -2
- package/dist/formats/ply/parse-splat-ply.d.ts +4 -4
- package/dist/formats/ply.js +1 -1
- package/dist/formats/ply.js.map +1 -1
- package/dist/formats/rad/frontier-worker-protocol.d.ts +8 -1
- package/dist/formats/rad/index.d.ts +2 -2
- package/dist/formats/rad/parse-rad.d.ts +2 -2
- package/dist/formats/rad/rad-foveated-source.d.ts +3 -3
- package/dist/formats/rad/rad.d.ts +7 -7
- package/dist/formats/rad.js +3 -3
- package/dist/formats/rad.js.map +1 -1
- package/dist/formats/sog/index.d.ts +1 -1
- package/dist/formats/sog/parse-sog.d.ts +6 -6
- package/dist/formats/sog.js.map +1 -1
- package/dist/formats/splat/index.d.ts +1 -1
- package/dist/formats/splat/parse-splat.d.ts +1 -1
- package/dist/formats/splat.js.map +1 -1
- package/dist/formats/spz/index.d.ts +1 -1
- package/dist/formats/spz/parse-spz.d.ts +1 -1
- package/dist/formats/spz.js.map +1 -1
- package/dist/half-float-Cs4FDq8Q.js.map +1 -1
- package/dist/index.js +253 -9047
- package/dist/index.js.map +1 -1
- package/dist/{chunk-loader.d.ts → loaders/chunk-loader.d.ts} +4 -4
- package/dist/loaders/index.d.ts +15 -0
- package/dist/{load-scene.d.ts → loaders/load-splat-data.d.ts} +16 -14
- package/dist/{load-worker-protocol.d.ts → loaders/load-worker-protocol.d.ts} +2 -2
- package/dist/{loading.d.ts → loaders/loading.d.ts} +8 -8
- package/dist/loaders.js +26 -0
- package/dist/loaders.js.map +1 -0
- package/dist/loading-wLo8vRbA.js.map +1 -1
- package/dist/{splat-mesh-types-CTN_duw2.js → lod-scheduler-B0a_uBlv.js} +133 -140
- package/dist/lod-scheduler-B0a_uBlv.js.map +1 -0
- package/dist/logging-BfPdd7NJ.js.map +1 -1
- package/dist/{ply-header-BwgExCn-.js → ply-header-B9WllbPg.js} +3 -3
- package/dist/ply-header-B9WllbPg.js.map +1 -0
- package/dist/radix-sorter-BrbUg_CV.js +178 -0
- package/dist/radix-sorter-BrbUg_CV.js.map +1 -0
- package/dist/relighting-Tiwep8yd.js +977 -0
- package/dist/relighting-Tiwep8yd.js.map +1 -0
- package/dist/selection/index.d.ts +13 -0
- package/dist/{selection-volume.d.ts → selection/selection-volume.d.ts} +1 -1
- package/dist/{splat-partition.d.ts → selection/splat-partition.d.ts} +2 -2
- package/dist/selection.js +137 -0
- package/dist/selection.js.map +1 -0
- package/dist/sh-pack-D5wAe5gg.js.map +1 -1
- package/dist/{splat-budget-DXew_86c.js → splat-budget-DuVZspPQ.js} +7 -7
- package/dist/splat-budget-DuVZspPQ.js.map +1 -0
- package/dist/splat-data-BZM5dhhx.js.map +1 -1
- package/dist/splat-mesh-CsLOQb08.js +1942 -0
- package/dist/splat-mesh-CsLOQb08.js.map +1 -0
- package/dist/splat-mesh-types-BZIko-_9.js +18 -0
- package/dist/splat-mesh-types-BZIko-_9.js.map +1 -0
- package/dist/static-lod/index.d.ts +12 -0
- package/dist/{static-lod-splat-mesh.d.ts → static-lod/static-lod-splat-mesh.d.ts} +3 -3
- package/dist/{static-lod-worker-protocol.d.ts → static-lod/static-lod-worker-protocol.d.ts} +1 -1
- package/dist/{static-lod.d.ts → static-lod/static-lod.d.ts} +1 -1
- package/dist/{static-lod-worker-D2fyqQZO.js → static-lod-worker-DktKnJkR.js} +46 -46
- package/dist/{static-lod-worker-D2fyqQZO.js.map → static-lod-worker-DktKnJkR.js.map} +1 -1
- package/dist/static-lod.js +148 -0
- package/dist/static-lod.js.map +1 -0
- package/dist/{budget-governor.d.ts → streaming/budget-governor.d.ts} +4 -4
- package/dist/{camera-budget-governor.d.ts → streaming/camera-budget-governor.d.ts} +11 -11
- package/dist/{chunk-cache-budget.d.ts → streaming/chunk-cache-budget.d.ts} +5 -5
- package/dist/{chunk-fetch-scheduler.d.ts → streaming/chunk-fetch-scheduler.d.ts} +4 -4
- package/dist/{dataset-source.d.ts → streaming/dataset-source.d.ts} +1 -1
- package/dist/streaming/index.d.ts +23 -0
- package/dist/{lod-scheduler.d.ts → streaming/lod-scheduler.d.ts} +1 -1
- package/dist/{lod-source.d.ts → streaming/lod-source.d.ts} +9 -9
- package/dist/{streamed-splat-mesh-utils.d.ts → streaming/streamed-splat-mesh-utils.d.ts} +2 -2
- package/dist/{streamed-splat-mesh.d.ts → streaming/streamed-splat-mesh.d.ts} +66 -32
- package/dist/streaming.js +2911 -0
- package/dist/streaming.js.map +1 -0
- package/dist/unified/index.d.ts +11 -0
- package/dist/{unified-splat-renderer.d.ts → unified/unified-splat-mesh.d.ts} +23 -16
- package/dist/unified/unified-work-buffer.d.ts +66 -0
- package/dist/{work-buffer-gather.d.ts → unified/work-buffer-gather.d.ts} +6 -6
- package/dist/{work-buffer-material.d.ts → unified/work-buffer-material.d.ts} +1 -1
- package/dist/unified.js +746 -0
- package/dist/unified.js.map +1 -0
- package/dist/webgpu-limits-Y3CI_6_6.js +43 -0
- package/dist/webgpu-limits-Y3CI_6_6.js.map +1 -0
- package/package.json +27 -7
- package/dist/index.d.ts +0 -54
- package/dist/ply-header-BwgExCn-.js.map +0 -1
- package/dist/splat-budget-DXew_86c.js.map +0 -1
- package/dist/splat-mesh-types-CTN_duw2.js.map +0 -1
- /package/dist/{create-splat-renderer.d.ts → core/create-splat-renderer.d.ts} +0 -0
- /package/dist/{depth-of-field.d.ts → core/depth-of-field.d.ts} +0 -0
- /package/dist/{half-float.d.ts → core/half-float.d.ts} +0 -0
- /package/dist/{logging.d.ts → core/logging.d.ts} +0 -0
- /package/dist/{radix-sort.d.ts → core/radix-sort.d.ts} +0 -0
- /package/dist/{radix-sorter.d.ts → core/radix-sorter.d.ts} +0 -0
- /package/dist/{relighting-pass.d.ts → core/relighting-pass.d.ts} +0 -0
- /package/dist/{sh-pack.d.ts → core/sh-pack.d.ts} +0 -0
- /package/dist/{sort-scheduler.d.ts → core/sort-scheduler.d.ts} +0 -0
- /package/dist/{sort-worker-protocol.d.ts → core/sort-worker-protocol.d.ts} +0 -0
- /package/dist/{sorter.d.ts → core/sorter.d.ts} +0 -0
- /package/dist/{splat-depth-pack.d.ts → core/splat-depth-pack.d.ts} +0 -0
- /package/dist/{splat-mesh-picking.d.ts → core/splat-mesh-picking.d.ts} +0 -0
- /package/dist/{splat-mesh-pool.d.ts → core/splat-mesh-pool.d.ts} +0 -0
- /package/dist/{splat-modifier-stack.d.ts → core/splat-modifier-stack.d.ts} +0 -0
- /package/dist/{splat-query.d.ts → core/splat-query.d.ts} +0 -0
- /package/dist/{splat-sort-bounds.d.ts → core/splat-sort-bounds.d.ts} +0 -0
- /package/dist/{storage-attribute-mirror.d.ts → core/storage-attribute-mirror.d.ts} +0 -0
- /package/dist/{worker-sorter.d.ts → core/worker-sorter.d.ts} +0 -0
- /package/dist/{xr-view.d.ts → core/xr-view.d.ts} +0 -0
- /package/dist/{ply-header.d.ts → loaders/ply-header.d.ts} +0 -0
- /package/dist/{lod-manifest.d.ts → streaming/lod-manifest.d.ts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ksplat.js","sources":["../../src/lib/formats/ksplat/parse-ksplat.ts"],"sourcesContent":["import { halfToFloat } from '../../half-float';\nimport { packShCoefficients } from '../../sh-pack';\nimport { writeCovariance, type SplatData } from '../../splat-data';\n\nconst HEADER_BYTES = 4096;\nconst SECTION_HEADER_BYTES = 1024;\nconst BUCKET_CENTER_BYTES = 12;\n/** Default 8-bit SH dequant range half-width (GaussianSplats3D `Constants`). */\nconst DEFAULT_SH_RANGE_HALF = 1.5;\n\ninterface KsplatHeader {\n versionMajor: number;\n versionMinor: number;\n sectionCount: number;\n splatCount: number;\n compressionLevel: number;\n shCoeffMin: number;\n shCoeffMax: number;\n}\n\ninterface KsplatSection {\n count: number;\n maxCount: number;\n bucketSize: number;\n bucketCount: number;\n bucketBlockSize: number;\n bucketStorageBytes: number;\n compressionRange: number;\n fullBucketCount: number;\n partialBucketCount: number;\n shDegree: number;\n bytesPerSplat: number;\n base: number;\n bucketsBase: number;\n dataBase: number;\n}\n\n/**\n * Parses a GaussianSplats3D `.ksplat` file, including compression levels 0–2.\n * Base color, opacity, position, scale, rotation and optional higher-order\n * spherical harmonics (degrees 1–2) are retained.\n *\n * @throws {Error} if the header, section layout or record data is invalid.\n */\nexport function parseKsplat(buffer: ArrayBuffer): SplatData {\n const view = new DataView(buffer);\n const header = parseHeader(view);\n const sections = parseSections(view, header);\n const totalSectionSplats = sections.reduce((sum, section) => sum + section.count, 0);\n if (totalSectionSplats !== header.splatCount) {\n throw new Error(\n `Invalid KSPLAT counts: header declares ${header.splatCount}, sections contain ${totalSectionSplats}.`,\n );\n }\n\n const positions = new Float32Array(header.splatCount * 3);\n const colors = new Uint8Array(header.splatCount * 4);\n const covariances = new Float32Array(header.splatCount * 6);\n const maxShDegree = sections.reduce((max, section) => Math.max(max, section.shDegree), 0);\n const shComponents = shComponentsForDegree(maxShDegree);\n const coefficients = shComponents > 0 ? new Float32Array(header.splatCount * shComponents) : null;\n let outputIndex = 0;\n\n for (const section of sections) {\n const partialLengths = readPartialBucketLengths(view, section);\n const sectionShComponents = shComponentsForDegree(section.shDegree);\n const shOffset = header.compressionLevel === 0 ? 44 : 24;\n for (let localIndex = 0; localIndex < section.count; localIndex++, outputIndex++) {\n const source = section.dataBase + localIndex * section.bytesPerSplat;\n const position = outputIndex * 3;\n const color = outputIndex * 4;\n const scaleOffset = header.compressionLevel === 0 ? 12 : 6;\n const rotationOffset = header.compressionLevel === 0 ? 24 : 12;\n const colorOffset = header.compressionLevel === 0 ? 40 : 20;\n\n if (header.compressionLevel === 0) {\n positions[position + 0] = view.getFloat32(source + 0, true);\n positions[position + 1] = view.getFloat32(source + 4, true);\n positions[position + 2] = view.getFloat32(source + 8, true);\n } else {\n const bucket = bucketIndexForSplat(localIndex, section, partialLengths);\n const bucketBase = section.bucketsBase + bucket * section.bucketStorageBytes;\n const factor = (section.bucketBlockSize * 0.5) / section.compressionRange;\n positions[position + 0] =\n (view.getUint16(source + 0, true) - section.compressionRange) * factor +\n view.getFloat32(bucketBase + 0, true);\n positions[position + 1] =\n (view.getUint16(source + 2, true) - section.compressionRange) * factor +\n view.getFloat32(bucketBase + 4, true);\n positions[position + 2] =\n (view.getUint16(source + 4, true) - section.compressionRange) * factor +\n view.getFloat32(bucketBase + 8, true);\n }\n\n colors[color + 0] = view.getUint8(source + colorOffset + 0);\n colors[color + 1] = view.getUint8(source + colorOffset + 1);\n colors[color + 2] = view.getUint8(source + colorOffset + 2);\n colors[color + 3] = view.getUint8(source + colorOffset + 3);\n\n const readScalar = (offset: number): number =>\n header.compressionLevel === 0\n ? view.getFloat32(source + offset, true)\n : halfToFloat(view.getUint16(source + offset, true));\n const scalarBytes = header.compressionLevel === 0 ? 4 : 2;\n writeCovariance(\n covariances,\n outputIndex,\n readScalar(scaleOffset + 0 * scalarBytes),\n readScalar(scaleOffset + 1 * scalarBytes),\n readScalar(scaleOffset + 2 * scalarBytes),\n readScalar(rotationOffset + 0 * scalarBytes),\n readScalar(rotationOffset + 1 * scalarBytes),\n readScalar(rotationOffset + 2 * scalarBytes),\n readScalar(rotationOffset + 3 * scalarBytes),\n );\n\n if (coefficients && sectionShComponents > 0) {\n const dest = outputIndex * shComponents;\n for (let c = 0; c < sectionShComponents; c++) {\n const byteOffset = shOffset + c * shScalarBytes(header.compressionLevel);\n coefficients[dest + c] = readShScalar(\n view,\n source + byteOffset,\n header.compressionLevel,\n header.shCoeffMin,\n header.shCoeffMax,\n );\n }\n }\n }\n }\n\n const shPacked =\n coefficients && maxShDegree > 0\n ? packShCoefficients(coefficients, header.splatCount, maxShDegree as 1 | 2)\n : undefined;\n\n return {\n count: header.splatCount,\n positions,\n colors,\n covariances,\n ...(shPacked ? { shPacked } : {}),\n };\n}\n\nfunction shScalarBytes(compressionLevel: number): number {\n return compressionLevel === 0 ? 4 : compressionLevel === 1 ? 2 : 1;\n}\n\nfunction readShScalar(\n view: DataView,\n offset: number,\n compressionLevel: number,\n rangeMin: number,\n rangeMax: number,\n): number {\n if (compressionLevel === 0) return view.getFloat32(offset, true);\n if (compressionLevel === 1) return halfToFloat(view.getUint16(offset, true));\n const encoded = view.getUint8(offset);\n return (encoded / 255) * (rangeMax - rangeMin) + rangeMin;\n}\n\nfunction shComponentsForDegree(shDegree: number): number {\n if (shDegree === 0) return 0;\n if (shDegree === 1) return 9;\n if (shDegree === 2) return 24;\n throw new Error(`Unsupported KSPLAT SH degree ${shDegree}.`);\n}\n\nfunction parseHeader(view: DataView): KsplatHeader {\n if (view.byteLength < HEADER_BYTES) throw new Error('Truncated KSPLAT header.');\n const versionMajor = view.getUint8(0);\n const versionMinor = view.getUint8(1);\n const maxSectionCount = view.getUint32(4, true);\n const sectionCount = view.getUint32(8, true);\n const maxSplatCount = view.getUint32(12, true);\n const splatCount = view.getUint32(16, true);\n const compressionLevel = view.getUint16(20, true);\n const shCoeffMin = view.getFloat32(36, true) || -DEFAULT_SH_RANGE_HALF;\n const shCoeffMax = view.getFloat32(40, true) || DEFAULT_SH_RANGE_HALF;\n\n if (versionMajor !== 0 || versionMinor < 1) {\n throw new Error(\n `Unsupported KSPLAT version ${versionMajor}.${versionMinor}; expected 0.1 or newer.`,\n );\n }\n if (compressionLevel < 0 || compressionLevel > 2) {\n throw new Error(`Unsupported KSPLAT compression level ${compressionLevel}.`);\n }\n if (\n !Number.isSafeInteger(maxSectionCount) ||\n sectionCount > maxSectionCount ||\n sectionCount === 0\n ) {\n throw new Error(`Invalid KSPLAT section count ${sectionCount}/${maxSectionCount}.`);\n }\n if (splatCount > maxSplatCount) {\n throw new Error(`Invalid KSPLAT splat count ${splatCount}/${maxSplatCount}.`);\n }\n const headersEnd = HEADER_BYTES + maxSectionCount * SECTION_HEADER_BYTES;\n if (!Number.isSafeInteger(headersEnd) || headersEnd > view.byteLength) {\n throw new Error('Truncated KSPLAT section headers.');\n }\n\n return {\n versionMajor,\n versionMinor,\n sectionCount,\n splatCount,\n compressionLevel,\n shCoeffMin,\n shCoeffMax,\n };\n}\n\nfunction parseSections(view: DataView, header: KsplatHeader): KsplatSection[] {\n const maxSectionCount = view.getUint32(4, true);\n let sectionBase = HEADER_BYTES + maxSectionCount * SECTION_HEADER_BYTES;\n const sections: KsplatSection[] = [];\n\n for (let index = 0; index < maxSectionCount; index++) {\n const offset = HEADER_BYTES + index * SECTION_HEADER_BYTES;\n const count = view.getUint32(offset + 0, true);\n const maxCount = view.getUint32(offset + 4, true);\n const bucketSize = view.getUint32(offset + 8, true);\n const bucketCount = view.getUint32(offset + 12, true);\n const bucketBlockSize = view.getFloat32(offset + 16, true);\n const bucketStorageBytes = view.getUint16(offset + 20, true);\n const compressionRange = view.getUint32(offset + 24, true) || 32767;\n const fullBucketCount = view.getUint32(offset + 32, true);\n const partialBucketCount = view.getUint32(offset + 36, true);\n const shDegree = view.getUint16(offset + 40, true);\n const bytesPerSplat = bytesPerKsplat(header.compressionLevel, shDegree);\n const bucketMetadataBytes = partialBucketCount * 4;\n const bucketBytes = bucketCount * bucketStorageBytes;\n const storageBytes = bucketMetadataBytes + bucketBytes + maxCount * bytesPerSplat;\n\n if (index < header.sectionCount) {\n if (count > maxCount)\n throw new Error(`Invalid KSPLAT section ${index} count ${count}/${maxCount}.`);\n if (header.compressionLevel > 0) {\n if (bucketSize === 0 || bucketCount === 0 || bucketStorageBytes < BUCKET_CENTER_BYTES) {\n throw new Error(`Invalid KSPLAT bucket layout in section ${index}.`);\n }\n if (!Number.isFinite(bucketBlockSize) || bucketBlockSize <= 0 || compressionRange === 0) {\n throw new Error(`Invalid KSPLAT compression parameters in section ${index}.`);\n }\n if (fullBucketCount + partialBucketCount > bucketCount) {\n throw new Error(\n `Invalid KSPLAT section ${index}: ${fullBucketCount} full + ` +\n `${partialBucketCount} partial buckets exceed the ${bucketCount} declared.`,\n );\n }\n }\n if (sectionBase + storageBytes > view.byteLength) {\n throw new Error(`Truncated KSPLAT data in section ${index}.`);\n }\n sections.push({\n count,\n maxCount,\n bucketSize,\n bucketCount,\n bucketBlockSize,\n bucketStorageBytes,\n compressionRange,\n fullBucketCount,\n partialBucketCount,\n shDegree,\n bytesPerSplat,\n base: sectionBase,\n bucketsBase: sectionBase + bucketMetadataBytes,\n dataBase: sectionBase + bucketMetadataBytes + bucketBytes,\n });\n }\n sectionBase += storageBytes;\n }\n return sections;\n}\n\nfunction bytesPerKsplat(compressionLevel: number, shDegree: number): number {\n if (shDegree < 0 || shDegree > 2) throw new Error(`Unsupported KSPLAT SH degree ${shDegree}.`);\n const shComponents = shComponentsForDegree(shDegree);\n if (compressionLevel === 0) return 44 + shComponents * 4;\n return 24 + shComponents * shScalarBytes(compressionLevel);\n}\n\nfunction readPartialBucketLengths(view: DataView, section: KsplatSection): Uint32Array {\n const lengths = new Uint32Array(section.partialBucketCount);\n for (let i = 0; i < lengths.length; i++) lengths[i] = view.getUint32(section.base + i * 4, true);\n return lengths;\n}\n\nfunction bucketIndexForSplat(\n localIndex: number,\n section: KsplatSection,\n partialLengths: Uint32Array,\n): number {\n const fullSplats = section.fullBucketCount * section.bucketSize;\n const checked = (bucket: number): number => {\n // Belt-and-braces: a bucket index at or past bucketCount would read\n // bucket centers out of the section's storage (OOB DataView reads or\n // garbage positions from a hostile file).\n if (bucket >= section.bucketCount) {\n throw new Error(`KSPLAT splat ${localIndex} maps to out-of-range bucket ${bucket}.`);\n }\n return bucket;\n };\n if (localIndex < fullSplats) return checked(Math.floor(localIndex / section.bucketSize));\n let first = fullSplats;\n for (let i = 0; i < partialLengths.length; i++) {\n const length = partialLengths[i] as number;\n if (localIndex < first + length) return checked(section.fullBucketCount + i);\n first += length;\n }\n throw new Error(`KSPLAT splat ${localIndex} does not belong to a bucket.`);\n}\n"],"names":["HEADER_BYTES","SECTION_HEADER_BYTES","BUCKET_CENTER_BYTES","DEFAULT_SH_RANGE_HALF","parseKsplat","buffer","view","header","parseHeader","sections","parseSections","totalSectionSplats","sum","section","positions","colors","covariances","maxShDegree","max","shComponents","shComponentsForDegree","coefficients","outputIndex","partialLengths","readPartialBucketLengths","sectionShComponents","shOffset","localIndex","source","position","color","scaleOffset","rotationOffset","colorOffset","bucket","bucketIndexForSplat","bucketBase","factor","readScalar","offset","halfToFloat","scalarBytes","writeCovariance","dest","c","byteOffset","shScalarBytes","readShScalar","shPacked","packShCoefficients","compressionLevel","rangeMin","rangeMax","shDegree","versionMajor","versionMinor","maxSectionCount","sectionCount","maxSplatCount","splatCount","shCoeffMin","shCoeffMax","headersEnd","sectionBase","index","count","maxCount","bucketSize","bucketCount","bucketBlockSize","bucketStorageBytes","compressionRange","fullBucketCount","partialBucketCount","bytesPerSplat","bytesPerKsplat","bucketMetadataBytes","bucketBytes","storageBytes","lengths","i","fullSplats","checked","first","length"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ksplat.js","sources":["../../src/lib/formats/ksplat/parse-ksplat.ts"],"sourcesContent":["import { halfToFloat } from '../../core/half-float';\nimport { packShCoefficients } from '../../core/sh-pack';\nimport { writeCovariance, type SplatData } from '../../core/splat-data';\n\nconst HEADER_BYTES = 4096;\nconst SECTION_HEADER_BYTES = 1024;\nconst BUCKET_CENTER_BYTES = 12;\n/** Default 8-bit SH dequant range half-width (GaussianSplats3D `Constants`). */\nconst DEFAULT_SH_RANGE_HALF = 1.5;\n\ninterface KsplatHeader {\n versionMajor: number;\n versionMinor: number;\n sectionCount: number;\n splatCount: number;\n compressionLevel: number;\n shCoeffMin: number;\n shCoeffMax: number;\n}\n\ninterface KsplatSection {\n count: number;\n maxCount: number;\n bucketSize: number;\n bucketCount: number;\n bucketBlockSize: number;\n bucketStorageBytes: number;\n compressionRange: number;\n fullBucketCount: number;\n partialBucketCount: number;\n shDegree: number;\n bytesPerSplat: number;\n base: number;\n bucketsBase: number;\n dataBase: number;\n}\n\n/**\n * Parses a GaussianSplats3D `.ksplat` file, including compression levels 0–2.\n * Base color, opacity, position, scale, rotation and optional higher-order\n * spherical harmonics (degrees 1–2) are retained.\n *\n * @throws {Error} if the header, section layout or record data is invalid.\n */\nexport function parseKsplat(buffer: ArrayBuffer): SplatData {\n const view = new DataView(buffer);\n const header = parseHeader(view);\n const sections = parseSections(view, header);\n const totalSectionSplats = sections.reduce((sum, section) => sum + section.count, 0);\n if (totalSectionSplats !== header.splatCount) {\n throw new Error(\n `Invalid KSPLAT counts: header declares ${header.splatCount}, sections contain ${totalSectionSplats}.`,\n );\n }\n\n const positions = new Float32Array(header.splatCount * 3);\n const colors = new Uint8Array(header.splatCount * 4);\n const covariances = new Float32Array(header.splatCount * 6);\n const maxShDegree = sections.reduce((max, section) => Math.max(max, section.shDegree), 0);\n const shComponents = shComponentsForDegree(maxShDegree);\n const coefficients = shComponents > 0 ? new Float32Array(header.splatCount * shComponents) : null;\n let outputIndex = 0;\n\n for (const section of sections) {\n const partialLengths = readPartialBucketLengths(view, section);\n const sectionShComponents = shComponentsForDegree(section.shDegree);\n const shOffset = header.compressionLevel === 0 ? 44 : 24;\n for (let localIndex = 0; localIndex < section.count; localIndex++, outputIndex++) {\n const source = section.dataBase + localIndex * section.bytesPerSplat;\n const position = outputIndex * 3;\n const color = outputIndex * 4;\n const scaleOffset = header.compressionLevel === 0 ? 12 : 6;\n const rotationOffset = header.compressionLevel === 0 ? 24 : 12;\n const colorOffset = header.compressionLevel === 0 ? 40 : 20;\n\n if (header.compressionLevel === 0) {\n positions[position + 0] = view.getFloat32(source + 0, true);\n positions[position + 1] = view.getFloat32(source + 4, true);\n positions[position + 2] = view.getFloat32(source + 8, true);\n } else {\n const bucket = bucketIndexForSplat(localIndex, section, partialLengths);\n const bucketBase = section.bucketsBase + bucket * section.bucketStorageBytes;\n const factor = (section.bucketBlockSize * 0.5) / section.compressionRange;\n positions[position + 0] =\n (view.getUint16(source + 0, true) - section.compressionRange) * factor +\n view.getFloat32(bucketBase + 0, true);\n positions[position + 1] =\n (view.getUint16(source + 2, true) - section.compressionRange) * factor +\n view.getFloat32(bucketBase + 4, true);\n positions[position + 2] =\n (view.getUint16(source + 4, true) - section.compressionRange) * factor +\n view.getFloat32(bucketBase + 8, true);\n }\n\n colors[color + 0] = view.getUint8(source + colorOffset + 0);\n colors[color + 1] = view.getUint8(source + colorOffset + 1);\n colors[color + 2] = view.getUint8(source + colorOffset + 2);\n colors[color + 3] = view.getUint8(source + colorOffset + 3);\n\n const readScalar = (offset: number): number =>\n header.compressionLevel === 0\n ? view.getFloat32(source + offset, true)\n : halfToFloat(view.getUint16(source + offset, true));\n const scalarBytes = header.compressionLevel === 0 ? 4 : 2;\n writeCovariance(\n covariances,\n outputIndex,\n readScalar(scaleOffset + 0 * scalarBytes),\n readScalar(scaleOffset + 1 * scalarBytes),\n readScalar(scaleOffset + 2 * scalarBytes),\n readScalar(rotationOffset + 0 * scalarBytes),\n readScalar(rotationOffset + 1 * scalarBytes),\n readScalar(rotationOffset + 2 * scalarBytes),\n readScalar(rotationOffset + 3 * scalarBytes),\n );\n\n if (coefficients && sectionShComponents > 0) {\n const dest = outputIndex * shComponents;\n for (let c = 0; c < sectionShComponents; c++) {\n const byteOffset = shOffset + c * shScalarBytes(header.compressionLevel);\n coefficients[dest + c] = readShScalar(\n view,\n source + byteOffset,\n header.compressionLevel,\n header.shCoeffMin,\n header.shCoeffMax,\n );\n }\n }\n }\n }\n\n const shPacked =\n coefficients && maxShDegree > 0\n ? packShCoefficients(coefficients, header.splatCount, maxShDegree as 1 | 2)\n : undefined;\n\n return {\n count: header.splatCount,\n positions,\n colors,\n covariances,\n ...(shPacked ? { shPacked } : {}),\n };\n}\n\nfunction shScalarBytes(compressionLevel: number): number {\n return compressionLevel === 0 ? 4 : compressionLevel === 1 ? 2 : 1;\n}\n\nfunction readShScalar(\n view: DataView,\n offset: number,\n compressionLevel: number,\n rangeMin: number,\n rangeMax: number,\n): number {\n if (compressionLevel === 0) return view.getFloat32(offset, true);\n if (compressionLevel === 1) return halfToFloat(view.getUint16(offset, true));\n const encoded = view.getUint8(offset);\n return (encoded / 255) * (rangeMax - rangeMin) + rangeMin;\n}\n\nfunction shComponentsForDegree(shDegree: number): number {\n if (shDegree === 0) return 0;\n if (shDegree === 1) return 9;\n if (shDegree === 2) return 24;\n throw new Error(`Unsupported KSPLAT SH degree ${shDegree}.`);\n}\n\nfunction parseHeader(view: DataView): KsplatHeader {\n if (view.byteLength < HEADER_BYTES) throw new Error('Truncated KSPLAT header.');\n const versionMajor = view.getUint8(0);\n const versionMinor = view.getUint8(1);\n const maxSectionCount = view.getUint32(4, true);\n const sectionCount = view.getUint32(8, true);\n const maxSplatCount = view.getUint32(12, true);\n const splatCount = view.getUint32(16, true);\n const compressionLevel = view.getUint16(20, true);\n const shCoeffMin = view.getFloat32(36, true) || -DEFAULT_SH_RANGE_HALF;\n const shCoeffMax = view.getFloat32(40, true) || DEFAULT_SH_RANGE_HALF;\n\n if (versionMajor !== 0 || versionMinor < 1) {\n throw new Error(\n `Unsupported KSPLAT version ${versionMajor}.${versionMinor}; expected 0.1 or newer.`,\n );\n }\n if (compressionLevel < 0 || compressionLevel > 2) {\n throw new Error(`Unsupported KSPLAT compression level ${compressionLevel}.`);\n }\n if (\n !Number.isSafeInteger(maxSectionCount) ||\n sectionCount > maxSectionCount ||\n sectionCount === 0\n ) {\n throw new Error(`Invalid KSPLAT section count ${sectionCount}/${maxSectionCount}.`);\n }\n if (splatCount > maxSplatCount) {\n throw new Error(`Invalid KSPLAT splat count ${splatCount}/${maxSplatCount}.`);\n }\n const headersEnd = HEADER_BYTES + maxSectionCount * SECTION_HEADER_BYTES;\n if (!Number.isSafeInteger(headersEnd) || headersEnd > view.byteLength) {\n throw new Error('Truncated KSPLAT section headers.');\n }\n\n return {\n versionMajor,\n versionMinor,\n sectionCount,\n splatCount,\n compressionLevel,\n shCoeffMin,\n shCoeffMax,\n };\n}\n\nfunction parseSections(view: DataView, header: KsplatHeader): KsplatSection[] {\n const maxSectionCount = view.getUint32(4, true);\n let sectionBase = HEADER_BYTES + maxSectionCount * SECTION_HEADER_BYTES;\n const sections: KsplatSection[] = [];\n\n for (let index = 0; index < maxSectionCount; index++) {\n const offset = HEADER_BYTES + index * SECTION_HEADER_BYTES;\n const count = view.getUint32(offset + 0, true);\n const maxCount = view.getUint32(offset + 4, true);\n const bucketSize = view.getUint32(offset + 8, true);\n const bucketCount = view.getUint32(offset + 12, true);\n const bucketBlockSize = view.getFloat32(offset + 16, true);\n const bucketStorageBytes = view.getUint16(offset + 20, true);\n const compressionRange = view.getUint32(offset + 24, true) || 32767;\n const fullBucketCount = view.getUint32(offset + 32, true);\n const partialBucketCount = view.getUint32(offset + 36, true);\n const shDegree = view.getUint16(offset + 40, true);\n const bytesPerSplat = bytesPerKsplat(header.compressionLevel, shDegree);\n const bucketMetadataBytes = partialBucketCount * 4;\n const bucketBytes = bucketCount * bucketStorageBytes;\n const storageBytes = bucketMetadataBytes + bucketBytes + maxCount * bytesPerSplat;\n\n if (index < header.sectionCount) {\n if (count > maxCount)\n throw new Error(`Invalid KSPLAT section ${index} count ${count}/${maxCount}.`);\n if (header.compressionLevel > 0) {\n if (bucketSize === 0 || bucketCount === 0 || bucketStorageBytes < BUCKET_CENTER_BYTES) {\n throw new Error(`Invalid KSPLAT bucket layout in section ${index}.`);\n }\n if (!Number.isFinite(bucketBlockSize) || bucketBlockSize <= 0 || compressionRange === 0) {\n throw new Error(`Invalid KSPLAT compression parameters in section ${index}.`);\n }\n if (fullBucketCount + partialBucketCount > bucketCount) {\n throw new Error(\n `Invalid KSPLAT section ${index}: ${fullBucketCount} full + ` +\n `${partialBucketCount} partial buckets exceed the ${bucketCount} declared.`,\n );\n }\n }\n if (sectionBase + storageBytes > view.byteLength) {\n throw new Error(`Truncated KSPLAT data in section ${index}.`);\n }\n sections.push({\n count,\n maxCount,\n bucketSize,\n bucketCount,\n bucketBlockSize,\n bucketStorageBytes,\n compressionRange,\n fullBucketCount,\n partialBucketCount,\n shDegree,\n bytesPerSplat,\n base: sectionBase,\n bucketsBase: sectionBase + bucketMetadataBytes,\n dataBase: sectionBase + bucketMetadataBytes + bucketBytes,\n });\n }\n sectionBase += storageBytes;\n }\n return sections;\n}\n\nfunction bytesPerKsplat(compressionLevel: number, shDegree: number): number {\n if (shDegree < 0 || shDegree > 2) throw new Error(`Unsupported KSPLAT SH degree ${shDegree}.`);\n const shComponents = shComponentsForDegree(shDegree);\n if (compressionLevel === 0) return 44 + shComponents * 4;\n return 24 + shComponents * shScalarBytes(compressionLevel);\n}\n\nfunction readPartialBucketLengths(view: DataView, section: KsplatSection): Uint32Array {\n const lengths = new Uint32Array(section.partialBucketCount);\n for (let i = 0; i < lengths.length; i++) lengths[i] = view.getUint32(section.base + i * 4, true);\n return lengths;\n}\n\nfunction bucketIndexForSplat(\n localIndex: number,\n section: KsplatSection,\n partialLengths: Uint32Array,\n): number {\n const fullSplats = section.fullBucketCount * section.bucketSize;\n const checked = (bucket: number): number => {\n // Belt-and-braces: a bucket index at or past bucketCount would read\n // bucket centers out of the section's storage (OOB DataView reads or\n // garbage positions from a hostile file).\n if (bucket >= section.bucketCount) {\n throw new Error(`KSPLAT splat ${localIndex} maps to out-of-range bucket ${bucket}.`);\n }\n return bucket;\n };\n if (localIndex < fullSplats) return checked(Math.floor(localIndex / section.bucketSize));\n let first = fullSplats;\n for (let i = 0; i < partialLengths.length; i++) {\n const length = partialLengths[i] as number;\n if (localIndex < first + length) return checked(section.fullBucketCount + i);\n first += length;\n }\n throw new Error(`KSPLAT splat ${localIndex} does not belong to a bucket.`);\n}\n"],"names":["HEADER_BYTES","SECTION_HEADER_BYTES","BUCKET_CENTER_BYTES","DEFAULT_SH_RANGE_HALF","parseKsplat","buffer","view","header","parseHeader","sections","parseSections","totalSectionSplats","sum","section","positions","colors","covariances","maxShDegree","max","shComponents","shComponentsForDegree","coefficients","outputIndex","partialLengths","readPartialBucketLengths","sectionShComponents","shOffset","localIndex","source","position","color","scaleOffset","rotationOffset","colorOffset","bucket","bucketIndexForSplat","bucketBase","factor","readScalar","offset","halfToFloat","scalarBytes","writeCovariance","dest","c","byteOffset","shScalarBytes","readShScalar","shPacked","packShCoefficients","compressionLevel","rangeMin","rangeMax","shDegree","versionMajor","versionMinor","maxSectionCount","sectionCount","maxSplatCount","splatCount","shCoeffMin","shCoeffMax","headersEnd","sectionBase","index","count","maxCount","bucketSize","bucketCount","bucketBlockSize","bucketStorageBytes","compressionRange","fullBucketCount","partialBucketCount","bytesPerSplat","bytesPerKsplat","bucketMetadataBytes","bucketBytes","storageBytes","lengths","i","fullSplats","checked","first","length"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type * as THREE from 'three/webgpu';
|
|
2
|
-
import { type SplatRequestOptions } from '../../loading';
|
|
2
|
+
import { type SplatRequestOptions } from '../../loaders/loading';
|
|
3
3
|
import { type TriangleMeshData } from './parse-mesh-ply';
|
|
4
|
-
import type {
|
|
4
|
+
import type { SplatCollisionData } from '../../streaming/lod-source';
|
|
5
5
|
/**
|
|
6
6
|
* Fetches the collision-mesh tiles a streamed scene declares.
|
|
7
7
|
*
|
|
@@ -31,7 +31,7 @@ export interface CollisionMeshTile {
|
|
|
31
31
|
*
|
|
32
32
|
* @throws a `DOMException` named `AbortError` when cancelled.
|
|
33
33
|
*/
|
|
34
|
-
export declare function loadCollisionMeshTiles(collision:
|
|
34
|
+
export declare function loadCollisionMeshTiles(collision: SplatCollisionData, options?: {
|
|
35
35
|
request?: SplatRequestOptions;
|
|
36
36
|
signal?: AbortSignal;
|
|
37
37
|
}): Promise<CollisionMeshTile[]>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TriangleMeshData } from './parse-mesh-ply';
|
|
2
|
-
import type { SelectionVolume } from '../../selection-volume';
|
|
2
|
+
import type { SelectionVolume } from '../../selection/selection-volume';
|
|
3
3
|
/**
|
|
4
4
|
* Splits a collision triangle mesh by the same {@link SelectionVolume} used to
|
|
5
5
|
* separate a splat region, so the separated object keeps its collision
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { LodSourceOptions, StreamedScene } from '../../lod-source';
|
|
1
|
+
import type { LodSourceOptions, StreamedScene } from '../../streaming/lod-source';
|
|
2
2
|
import { type LccManifest } from './parse-lcc';
|
|
3
|
-
import { type SplatRequestOptions } from '../../loading';
|
|
4
|
-
import type { SplatDatasetSource } from '../../dataset-source';
|
|
3
|
+
import { type SplatRequestOptions } from '../../loaders/loading';
|
|
4
|
+
import type { SplatDatasetSource } from '../../streaming/dataset-source';
|
|
5
5
|
/** Options for {@link buildLccScene} beyond the shared LOD knobs. */
|
|
6
6
|
export interface LccSceneOptions extends LodSourceOptions {
|
|
7
7
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { LodSourceOptions, StreamedScene } from '../../lod-source';
|
|
2
|
-
import type { SplatDatasetSource } from '../../dataset-source';
|
|
1
|
+
import type { LodSourceOptions, StreamedScene } from '../../streaming/lod-source';
|
|
2
|
+
import type { SplatDatasetSource } from '../../streaming/dataset-source';
|
|
3
3
|
/** Builds a scene from a parsed `.lcc2` manifest (JSON already fetched). */
|
|
4
4
|
export declare function buildLcc2Scene(json: unknown, dataset: SplatDatasetSource, options: LodSourceOptions, shBands?: 0 | 1 | 2 | 3): StreamedScene;
|
package/dist/formats/lcc.js
CHANGED
|
@@ -4,10 +4,11 @@ var A = (e, t, n) => gt(e, typeof t != "symbol" ? t + "" : t, n);
|
|
|
4
4
|
import { w as wt } from "../splat-data-BZM5dhhx.js";
|
|
5
5
|
import { a as mt, r as pt } from "../sh-pack-D5wAe5gg.js";
|
|
6
6
|
import * as E from "three/webgpu";
|
|
7
|
-
import {
|
|
7
|
+
import { L as Ct } from "../lod-scheduler-B0a_uBlv.js";
|
|
8
8
|
import { t as ct, a as W } from "../loading-wLo8vRbA.js";
|
|
9
|
+
import { M as yt } from "../splat-mesh-types-BZIko-_9.js";
|
|
9
10
|
import { w as z } from "../logging-BfPdd7NJ.js";
|
|
10
|
-
import {
|
|
11
|
+
import { c as xt, a as vt, b as bt, p as k, d as j } from "../ply-header-B9WllbPg.js";
|
|
11
12
|
const F = 32, O = 64, K = 1 << 24;
|
|
12
13
|
function Lt(e) {
|
|
13
14
|
return e === 1 ? 3 : e === 2 ? 8 : 15;
|
|
@@ -144,7 +145,7 @@ function Ft(e) {
|
|
|
144
145
|
return n[t] = Math.sqrt(Math.max(0, 1 - s)), [n[3], n[0], n[1], n[2]];
|
|
145
146
|
}
|
|
146
147
|
const Tt = 1 / (511 * Math.SQRT2);
|
|
147
|
-
async function
|
|
148
|
+
async function le(e, t, n, o) {
|
|
148
149
|
var v;
|
|
149
150
|
const s = t.stride;
|
|
150
151
|
if (s !== F && s !== F + O)
|
|
@@ -239,11 +240,11 @@ function P(e, t) {
|
|
|
239
240
|
function H() {
|
|
240
241
|
return new E.Matrix4().set(-1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1);
|
|
241
242
|
}
|
|
242
|
-
function
|
|
243
|
+
function ce(e) {
|
|
243
244
|
e.matrix.copy(H()), e.matrix.decompose(e.position, e.quaternion, e.scale), e.matrixWorldNeedsUpdate = !0;
|
|
244
245
|
}
|
|
245
246
|
const Bt = 128e3;
|
|
246
|
-
async function
|
|
247
|
+
async function ae(e, t, n) {
|
|
247
248
|
const o = Et(e), s = (g) => {
|
|
248
249
|
const x = t.resolve(g);
|
|
249
250
|
if (x === null) throw new Error(`LCC dataset is missing "${g}".`);
|
|
@@ -253,7 +254,7 @@ async function ce(e, t, n) {
|
|
|
253
254
|
o
|
|
254
255
|
);
|
|
255
256
|
Pt(c, o);
|
|
256
|
-
const a = o.fileType === "Quality" ?
|
|
257
|
+
const a = o.fileType === "Quality" ? yt : 0, r = n.shBands ?? a, u = Math.min(r, a), f = u === 0 ? void 0 : u, h = f === void 0 ? null : s("shcoef.bin"), d = [], m = [], p = (g, x) => (d.push(g), m.push(x), d.length - 1), $ = [], b = /* @__PURE__ */ new Set();
|
|
257
258
|
let w = 0;
|
|
258
259
|
const C = o.totalLevel;
|
|
259
260
|
for (let g = 0; g < c.length; g++) {
|
|
@@ -346,7 +347,7 @@ async function ce(e, t, n) {
|
|
|
346
347
|
// Classic LCC cells are broad XY tiles. Keep their priority independent of
|
|
347
348
|
// frustum crossings so an orbit does not demote a sharp tile as it leaves
|
|
348
349
|
// one edge, then rebuild it when the same tile re-enters the other edge.
|
|
349
|
-
source: new
|
|
350
|
+
source: new Ct(y, {
|
|
350
351
|
...n,
|
|
351
352
|
// Classic LCC cells are broad XY tiles. Keep their priority independent of
|
|
352
353
|
// frustum crossings so an orbit does not demote a sharp tile as it leaves
|
|
@@ -451,7 +452,7 @@ async function _t(e, t, n) {
|
|
|
451
452
|
return o.arrayBuffer();
|
|
452
453
|
}
|
|
453
454
|
const Dt = 3, zt = 0.1, tt = 0.1, Ot = 500;
|
|
454
|
-
function
|
|
455
|
+
function ue(e, t, n, o = 0) {
|
|
455
456
|
var $, b;
|
|
456
457
|
const s = e, i = s.root.splatFiles.map((w) => {
|
|
457
458
|
const C = t.resolve(w);
|
|
@@ -889,7 +890,7 @@ function Wt(e, t, n, o, s) {
|
|
|
889
890
|
)
|
|
890
891
|
);
|
|
891
892
|
}
|
|
892
|
-
async function
|
|
893
|
+
async function he(e, t = {}) {
|
|
893
894
|
var s;
|
|
894
895
|
const n = await Promise.allSettled(
|
|
895
896
|
e.meshes.map((i) => jt(i, t))
|
|
@@ -927,7 +928,7 @@ function Kt(e) {
|
|
|
927
928
|
return e.toLowerCase().includes(".lci");
|
|
928
929
|
}
|
|
929
930
|
}
|
|
930
|
-
function
|
|
931
|
+
function fe(e, t) {
|
|
931
932
|
Zt(e);
|
|
932
933
|
const { positions: n, indices: o, vertexCount: s, triangleCount: i } = e, l = new Uint8Array(s);
|
|
933
934
|
for (let r = 0; r < s; r++)
|
|
@@ -982,16 +983,16 @@ function lt(e, t, n, o) {
|
|
|
982
983
|
return { vertexCount: l, triangleCount: o, positions: a, indices: i };
|
|
983
984
|
}
|
|
984
985
|
export {
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
986
|
+
ce as applyLcc2ToThreeTransform,
|
|
987
|
+
ue as buildLcc2Scene,
|
|
988
|
+
ae as buildLccScene,
|
|
988
989
|
H as createLcc2ToThreeMatrix,
|
|
989
|
-
|
|
990
|
+
he as loadCollisionMeshTiles,
|
|
990
991
|
Qt as parseCollisionLci,
|
|
991
|
-
|
|
992
|
+
le as parseLccChunk,
|
|
992
993
|
Mt as parseLccIndex,
|
|
993
994
|
Et as parseLccManifest,
|
|
994
995
|
Vt as parseMeshPly,
|
|
995
|
-
|
|
996
|
+
fe as partitionTriangleMesh
|
|
996
997
|
};
|
|
997
998
|
//# sourceMappingURL=lcc.js.map
|