mirror of
https://github.com/storytold/spark.git
synced 2026-10-17 00:12:59 +00:00
Fix .ksplat decoding by implementing partial bucket decoding. (#68)
This commit is contained in:
committed by
GitHub
parent
521fcb6a3a
commit
af45f72a2b
+46
-4
@@ -143,7 +143,8 @@ export function decodeKsplat(
|
|||||||
(section.getUint32(24, true) ||
|
(section.getUint32(24, true) ||
|
||||||
KSPLAT_COMPRESSION[compressionLevel]?.scaleRange) ??
|
KSPLAT_COMPRESSION[compressionLevel]?.scaleRange) ??
|
||||||
1;
|
1;
|
||||||
// const fullBucketCount = section.getUint32(32, true);
|
const fullBucketCount = section.getUint32(32, true);
|
||||||
|
const fullBucketSplats = fullBucketCount * bucketSize;
|
||||||
const partiallyFilledBucketCount = section.getUint32(36, true);
|
const partiallyFilledBucketCount = section.getUint32(36, true);
|
||||||
const bucketsMetaDataSizeBytes = partiallyFilledBucketCount * 4;
|
const bucketsMetaDataSizeBytes = partiallyFilledBucketCount * 4;
|
||||||
const bucketsStorageSizeBytes =
|
const bucketsStorageSizeBytes =
|
||||||
@@ -201,6 +202,11 @@ export function decodeKsplat(
|
|||||||
bucketsBase,
|
bucketsBase,
|
||||||
bucketCount * 3,
|
bucketCount * 3,
|
||||||
);
|
);
|
||||||
|
const partiallyFilledBucketLengths = new Uint32Array(
|
||||||
|
fileBytes.buffer,
|
||||||
|
sectionBase,
|
||||||
|
partiallyFilledBucketCount,
|
||||||
|
);
|
||||||
|
|
||||||
function getSh(splatOffset: number, component: number) {
|
function getSh(splatOffset: number, component: number) {
|
||||||
if (compressionLevel === 0) {
|
if (compressionLevel === 0) {
|
||||||
@@ -226,9 +232,24 @@ export function decodeKsplat(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let partialBucketIndex = fullBucketCount;
|
||||||
|
let partialBucketBase = fullBucketSplats;
|
||||||
|
|
||||||
for (let i = 0; i < sectionSplatCount; ++i) {
|
for (let i = 0; i < sectionSplatCount; ++i) {
|
||||||
const splatOffset = i * bytesPerSplat;
|
const splatOffset = i * bytesPerSplat;
|
||||||
const bucketIndex = Math.floor(i / bucketSize);
|
|
||||||
|
let bucketIndex: number;
|
||||||
|
if (i < fullBucketSplats) {
|
||||||
|
bucketIndex = Math.floor(i / bucketSize);
|
||||||
|
} else {
|
||||||
|
const bucketLength =
|
||||||
|
partiallyFilledBucketLengths[partialBucketIndex - fullBucketCount];
|
||||||
|
if (i >= partialBucketBase + bucketLength) {
|
||||||
|
partialBucketIndex += 1;
|
||||||
|
partialBucketBase += bucketLength;
|
||||||
|
}
|
||||||
|
bucketIndex = partialBucketIndex;
|
||||||
|
}
|
||||||
|
|
||||||
const x =
|
const x =
|
||||||
compressionLevel === 0
|
compressionLevel === 0
|
||||||
@@ -372,7 +393,8 @@ export function unpackKsplat(fileBytes: Uint8Array): {
|
|||||||
(section.getUint32(24, true) ||
|
(section.getUint32(24, true) ||
|
||||||
KSPLAT_COMPRESSION[compressionLevel]?.scaleRange) ??
|
KSPLAT_COMPRESSION[compressionLevel]?.scaleRange) ??
|
||||||
1;
|
1;
|
||||||
// const fullBucketCount = section.getUint32(32, true);
|
const fullBucketCount = section.getUint32(32, true);
|
||||||
|
const fullBucketSplats = fullBucketCount * bucketSize;
|
||||||
const partiallyFilledBucketCount = section.getUint32(36, true);
|
const partiallyFilledBucketCount = section.getUint32(36, true);
|
||||||
const bucketsMetaDataSizeBytes = partiallyFilledBucketCount * 4;
|
const bucketsMetaDataSizeBytes = partiallyFilledBucketCount * 4;
|
||||||
const bucketsStorageSizeBytes =
|
const bucketsStorageSizeBytes =
|
||||||
@@ -430,6 +452,11 @@ export function unpackKsplat(fileBytes: Uint8Array): {
|
|||||||
bucketsBase,
|
bucketsBase,
|
||||||
bucketCount * 3,
|
bucketCount * 3,
|
||||||
);
|
);
|
||||||
|
const partiallyFilledBucketLengths = new Uint32Array(
|
||||||
|
fileBytes.buffer,
|
||||||
|
sectionBase,
|
||||||
|
partiallyFilledBucketCount,
|
||||||
|
);
|
||||||
|
|
||||||
function getSh(splatOffset: number, component: number) {
|
function getSh(splatOffset: number, component: number) {
|
||||||
if (compressionLevel === 0) {
|
if (compressionLevel === 0) {
|
||||||
@@ -455,9 +482,24 @@ export function unpackKsplat(fileBytes: Uint8Array): {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let partialBucketIndex = fullBucketCount;
|
||||||
|
let partialBucketBase = fullBucketSplats;
|
||||||
|
|
||||||
for (let i = 0; i < sectionSplatCount; ++i) {
|
for (let i = 0; i < sectionSplatCount; ++i) {
|
||||||
const splatOffset = i * bytesPerSplat;
|
const splatOffset = i * bytesPerSplat;
|
||||||
const bucketIndex = Math.floor(i / bucketSize);
|
|
||||||
|
let bucketIndex: number;
|
||||||
|
if (i < fullBucketSplats) {
|
||||||
|
bucketIndex = Math.floor(i / bucketSize);
|
||||||
|
} else {
|
||||||
|
const bucketLength =
|
||||||
|
partiallyFilledBucketLengths[partialBucketIndex - fullBucketCount];
|
||||||
|
if (i >= partialBucketBase + bucketLength) {
|
||||||
|
partialBucketIndex += 1;
|
||||||
|
partialBucketBase += bucketLength;
|
||||||
|
}
|
||||||
|
bucketIndex = partialBucketIndex;
|
||||||
|
}
|
||||||
|
|
||||||
const x =
|
const x =
|
||||||
compressionLevel === 0
|
compressionLevel === 0
|
||||||
|
|||||||
Reference in New Issue
Block a user