@manycore/aholo-splat-transform 1.2.7 → 1.2.9

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.
Files changed (98) hide show
  1. package/CHANGELOG.md +120 -106
  2. package/COPYRIGHT.md +17 -0
  3. package/README.md +39 -39
  4. package/THIRD_PARTY_LICENSES.txt +1373 -0
  5. package/bin/cli.js +125 -118
  6. package/dist/SplatData.d.ts +67 -67
  7. package/dist/SplatData.js +167 -156
  8. package/dist/constant.d.ts +3 -3
  9. package/dist/constant.js +13 -13
  10. package/dist/file/IFile.d.ts +5 -5
  11. package/dist/file/IFile.js +1 -1
  12. package/dist/file/esz.d.ts +11 -0
  13. package/dist/file/esz.js +337 -0
  14. package/dist/file/index.d.ts +8 -7
  15. package/dist/file/index.js +7 -6
  16. package/dist/file/ksplat.d.ts +12 -12
  17. package/dist/file/ksplat.js +293 -232
  18. package/dist/file/lcc.d.ts +11 -11
  19. package/dist/file/lcc.js +161 -157
  20. package/dist/file/ply.d.ts +13 -13
  21. package/dist/file/ply.js +439 -388
  22. package/dist/file/sog.d.ts +80 -80
  23. package/dist/file/sog.js +525 -504
  24. package/dist/file/splat.d.ts +6 -6
  25. package/dist/file/splat.js +119 -99
  26. package/dist/file/spz.d.ts +11 -8
  27. package/dist/file/spz.js +597 -400
  28. package/dist/file/voxel.d.ts +43 -37
  29. package/dist/file/voxel.js +411 -280
  30. package/dist/index.d.ts +33 -33
  31. package/dist/index.js +54 -54
  32. package/dist/native/index.d.ts +54 -54
  33. package/dist/native/index.js +122 -128
  34. package/dist/native/utils.d.ts +1 -0
  35. package/dist/native/utils.js +54 -0
  36. package/dist/tasks/AutoChunkLodTask.d.ts +13 -13
  37. package/dist/tasks/AutoChunkLodTask.js +117 -117
  38. package/dist/tasks/AutoLodTask.d.ts +10 -10
  39. package/dist/tasks/AutoLodTask.js +20 -20
  40. package/dist/tasks/BaseTask.d.ts +15 -15
  41. package/dist/tasks/BaseTask.js +5 -5
  42. package/dist/tasks/FlexLodTask.d.ts +12 -12
  43. package/dist/tasks/FlexLodTask.js +54 -44
  44. package/dist/tasks/ModifyTask.d.ts +9 -9
  45. package/dist/tasks/ModifyTask.js +166 -156
  46. package/dist/tasks/ReadTask.d.ts +9 -9
  47. package/dist/tasks/ReadTask.js +29 -29
  48. package/dist/tasks/SkeletonLodTask.d.ts +10 -10
  49. package/dist/tasks/SkeletonLodTask.js +176 -156
  50. package/dist/tasks/VoxelTask.d.ts +35 -30
  51. package/dist/tasks/VoxelTask.js +40 -37
  52. package/dist/tasks/WriteTask.d.ts +12 -11
  53. package/dist/tasks/WriteTask.js +70 -70
  54. package/dist/utils/BufferReader.d.ts +12 -12
  55. package/dist/utils/BufferReader.js +45 -47
  56. package/dist/utils/Logger.d.ts +11 -11
  57. package/dist/utils/Logger.js +40 -38
  58. package/dist/utils/StreamChunkDecoder.d.ts +16 -16
  59. package/dist/utils/StreamChunkDecoder.js +31 -36
  60. package/dist/utils/index.d.ts +27 -27
  61. package/dist/utils/index.js +101 -101
  62. package/dist/utils/k-means.d.ts +4 -4
  63. package/dist/utils/k-means.js +340 -350
  64. package/dist/utils/math.d.ts +46 -46
  65. package/dist/utils/math.js +350 -351
  66. package/dist/utils/quantize-1d.d.ts +4 -4
  67. package/dist/utils/quantize-1d.js +164 -164
  68. package/dist/utils/sh-rotate.d.ts +2 -2
  69. package/dist/utils/sh-rotate.js +236 -175
  70. package/dist/utils/splat.d.ts +21 -20
  71. package/dist/utils/splat.js +397 -378
  72. package/dist/utils/voxel/binary.d.ts +8 -0
  73. package/dist/utils/voxel/binary.js +176 -0
  74. package/dist/utils/voxel/common.d.ts +178 -162
  75. package/dist/utils/voxel/common.js +1752 -1700
  76. package/dist/utils/voxel/coplanar-merge.d.ts +63 -63
  77. package/dist/utils/voxel/coplanar-merge.js +818 -819
  78. package/dist/utils/voxel/filter-cluster.d.ts +20 -0
  79. package/dist/utils/voxel/filter-cluster.js +628 -0
  80. package/dist/utils/voxel/gpu-dilation.d.ts +2 -2
  81. package/dist/utils/voxel/gpu-dilation.js +677 -665
  82. package/dist/utils/voxel/marching-cubes.d.ts +42 -42
  83. package/dist/utils/voxel/marching-cubes.js +1645 -1657
  84. package/dist/utils/voxel/mesh.d.ts +3 -3
  85. package/dist/utils/voxel/mesh.js +130 -130
  86. package/dist/utils/voxel/nav.d.ts +29 -29
  87. package/dist/utils/voxel/nav.js +1068 -1043
  88. package/dist/utils/voxel/postprocess.d.ts +23 -23
  89. package/dist/utils/voxel/postprocess.js +408 -375
  90. package/dist/utils/voxel/voxel-faces.d.ts +18 -18
  91. package/dist/utils/voxel/voxel-faces.js +662 -663
  92. package/dist/utils/voxel/voxelize.d.ts +34 -33
  93. package/dist/utils/voxel/voxelize.js +1208 -1193
  94. package/dist/utils/webgpu.d.ts +8 -8
  95. package/dist/utils/webgpu.js +122 -122
  96. package/package.json +37 -30
  97. package/dist/native/cpp/bin/linux/binding.node +0 -0
  98. package/dist/native/cpp/bin/windows/binding.node +0 -0
@@ -1,232 +1,293 @@
1
- import { SH_MAPS } from '../constant.js';
2
- import { fromHalf } from '../utils/index.js';
3
- const KSPLAT_COMPRESSION = {
4
- 0: {
5
- bytesPerCenter: 12,
6
- bytesPerScale: 12,
7
- bytesPerRotation: 16,
8
- bytesPerColor: 4,
9
- bytesPerSphericalHarmonicsComponent: 4,
10
- scaleOffsetBytes: 12,
11
- rotationOffsetBytes: 24,
12
- colorOffsetBytes: 40,
13
- sphericalHarmonicsOffsetBytes: 44,
14
- scaleRange: 1,
15
- },
16
- 1: {
17
- bytesPerCenter: 6,
18
- bytesPerScale: 6,
19
- bytesPerRotation: 8,
20
- bytesPerColor: 4,
21
- bytesPerSphericalHarmonicsComponent: 2,
22
- scaleOffsetBytes: 6,
23
- rotationOffsetBytes: 12,
24
- colorOffsetBytes: 20,
25
- sphericalHarmonicsOffsetBytes: 24,
26
- scaleRange: 32767,
27
- },
28
- 2: {
29
- bytesPerCenter: 6,
30
- bytesPerScale: 6,
31
- bytesPerRotation: 8,
32
- bytesPerColor: 4,
33
- bytesPerSphericalHarmonicsComponent: 1,
34
- scaleOffsetBytes: 6,
35
- rotationOffsetBytes: 12,
36
- colorOffsetBytes: 20,
37
- sphericalHarmonicsOffsetBytes: 24,
38
- scaleRange: 32767,
39
- },
40
- };
41
- const SHIndex = [
42
- 0, 3, 6, 1, 4, 7, 2, 5, 8, // sh1
43
- 9, 14, 19, 10, 15, 20, 11, 16, 21, 12, 17, 22, 13, 18, 23, // sh2
44
- 24, 31, 38, 25, 32, 39, 26, 33, 40, 27, 34, 41, 28, 35, 42, 29, 36, 43, 30, 37, 44, // sh3
45
- ];
46
- const HEADER_BYTES = 4096;
47
- const SECTION_BYTES = 1024;
48
- export class KsplatFile {
49
- counts = 0;
50
- shDegree = 0;
51
- header;
52
- sections;
53
- buffer;
54
- load(buffer) {
55
- this.buffer = buffer;
56
- const header = new DataView(buffer.buffer, 0, HEADER_BYTES);
57
- const versionMajor = header.getUint8(0);
58
- const versionMinor = header.getUint8(1);
59
- if (versionMajor !== 0 || versionMinor < 1) {
60
- throw new Error(`Unsupported .ksplat version: ${versionMajor}.${versionMinor}`);
61
- }
62
- const maxSectionCount = header.getUint32(4, true);
63
- const sectionCount = header.getUint32(8, true);
64
- const maxSplatCount = header.getUint32(12, true);
65
- const splatCount = header.getUint32(16, true);
66
- const compressionLevel = header.getUint16(20, true);
67
- if (compressionLevel < 0 || compressionLevel > 2) {
68
- throw new Error(`Invalid .ksplat compression level: ${compressionLevel}`);
69
- }
70
- const sceneCenterX = header.getFloat32(24, true);
71
- const sceneCenterY = header.getFloat32(28, true);
72
- const sceneCenterZ = header.getFloat32(32, true);
73
- const minSH = header.getFloat32(36, true) || -1.5;
74
- const maxSH = header.getFloat32(40, true) || 1.5;
75
- let maxSHDegree = 0;
76
- const sections = [];
77
- for (let i = 0; i < maxSectionCount; i++) {
78
- const section = new DataView(buffer.buffer, HEADER_BYTES + i * SECTION_BYTES, SECTION_BYTES);
79
- const sectionSplatCount = section.getUint32(0, true);
80
- const sectionMaxSplatCount = section.getUint32(4, true);
81
- const bucketSize = section.getUint32(8, true);
82
- const bucketCount = section.getUint32(12, true);
83
- const bucketBlockSize = section.getFloat32(16, true);
84
- const bucketStorageSizeBytes = section.getUint16(20, true);
85
- const compressionScaleRange = section.getUint32(24, true);
86
- const fullBucketCount = section.getUint32(32, true);
87
- const partiallyFilledBucketCount = section.getUint32(36, true);
88
- const shDegree = section.getUint16(40, true);
89
- maxSHDegree = Math.max(maxSHDegree, shDegree);
90
- sections.push({
91
- sectionSplatCount,
92
- sectionMaxSplatCount,
93
- bucketSize,
94
- bucketCount,
95
- bucketBlockSize,
96
- bucketStorageSizeBytes,
97
- compressionScaleRange: compressionScaleRange || KSPLAT_COMPRESSION[compressionLevel].scaleRange,
98
- fullBucketCount,
99
- partiallyFilledBucketCount,
100
- shDegree,
101
- });
102
- }
103
- this.header = {
104
- versionMajor,
105
- versionMinor,
106
- maxSectionCount,
107
- sectionCount,
108
- maxSplatCount,
109
- splatCount,
110
- compressionLevel,
111
- sceneCenter: [sceneCenterX, sceneCenterY, sceneCenterZ],
112
- shRange: [minSH, maxSH],
113
- };
114
- this.sections = sections;
115
- this.counts = splatCount;
116
- this.shDegree = maxSHDegree;
117
- }
118
- async read(stream, contentLength, data) {
119
- let BlockOffset = 0;
120
- {
121
- const buffer = new Uint8Array(contentLength);
122
- const reader = stream.getReader();
123
- let offset = 0;
124
- while (true) {
125
- const { done, value } = await reader.read();
126
- if (done) {
127
- break;
128
- }
129
- buffer.set(value, offset);
130
- offset += value.length;
131
- }
132
- this.load(buffer);
133
- BlockOffset = await data.initBlock(this.counts, this.shDegree);
134
- }
135
- const setFn = data.set.bind(data);
136
- const setShFn = data.setShN.bind(data);
137
- const { buffer, header, sections, shDegree: maxSHDegree } = this;
138
- const { maxSectionCount, compressionLevel, shRange: [minSH, maxSH] } = header;
139
- const isHighQualitySplatData = compressionLevel === 0;
140
- const single = {
141
- x: 0, y: 0, z: 0,
142
- sx: 0, sy: 0, sz: 0,
143
- qx: 0, qy: 0, qz: 0, qw: 0,
144
- r: 0, g: 0, b: 0, a: 0,
145
- shN: [],
146
- };
147
- const maxSHSize = SH_MAPS[maxSHDegree];
148
- const shData = new Array(maxSHSize);
149
- let sectionBase = HEADER_BYTES + maxSectionCount * SECTION_BYTES;
150
- for (let i = 0; i < maxSectionCount; i++) {
151
- const { sectionSplatCount, sectionMaxSplatCount, bucketSize, bucketCount, bucketBlockSize, bucketStorageSizeBytes, fullBucketCount, partiallyFilledBucketCount, compressionScaleRange, shDegree, } = sections[i];
152
- const fullBucketSplats = fullBucketCount * bucketSize;
153
- const bucketsMetaDataSizeBytes = partiallyFilledBucketCount * 4;
154
- const bucketsStorageSizeBytes = bucketStorageSizeBytes * bucketCount + bucketsMetaDataSizeBytes;
155
- const shComponents = SH_MAPS[shDegree];
156
- const { bytesPerCenter, bytesPerScale, bytesPerRotation, bytesPerColor, bytesPerSphericalHarmonicsComponent, scaleOffsetBytes, rotationOffsetBytes, colorOffsetBytes, sphericalHarmonicsOffsetBytes, } = KSPLAT_COMPRESSION[compressionLevel];
157
- const bytesPerSplat = bytesPerCenter + bytesPerScale + bytesPerRotation + bytesPerColor +
158
- shComponents * bytesPerSphericalHarmonicsComponent;
159
- const splatDataStorageSizeBytes = bytesPerSplat * sectionMaxSplatCount;
160
- const storageSizeBytes = splatDataStorageSizeBytes + bucketsStorageSizeBytes;
161
- const compressionScaleFactor = bucketBlockSize / 2 / compressionScaleRange;
162
- const bucketsBase = sectionBase + bucketsMetaDataSizeBytes;
163
- const dataBase = sectionBase + bucketsStorageSizeBytes;
164
- const data = new DataView(buffer.buffer, dataBase, splatDataStorageSizeBytes);
165
- const bucketArray = new Float32Array(buffer.buffer, bucketsBase, bucketCount * 3);
166
- const partiallyFilledBucketLengths = new Uint32Array(buffer.buffer, sectionBase, partiallyFilledBucketCount);
167
- let partialBucketIndex = fullBucketCount;
168
- let partialBucketBase = fullBucketSplats;
169
- for (let j = 0; j < sectionSplatCount; j++) {
170
- const splatOffset = j * bytesPerSplat;
171
- let bucketIndex;
172
- if (j < fullBucketSplats) {
173
- bucketIndex = Math.floor(j / bucketSize);
174
- }
175
- else {
176
- const bucketLength = partiallyFilledBucketLengths[partialBucketIndex - fullBucketCount];
177
- if (j >= partialBucketBase + bucketLength) {
178
- partialBucketIndex += 1;
179
- partialBucketBase += bucketLength;
180
- }
181
- bucketIndex = partialBucketIndex;
182
- }
183
- if (isHighQualitySplatData) {
184
- single.x = data.getFloat32(splatOffset + 0, true);
185
- single.y = data.getFloat32(splatOffset + 4, true);
186
- single.z = data.getFloat32(splatOffset + 8, true);
187
- single.sx = data.getFloat32(splatOffset + scaleOffsetBytes + 0, true);
188
- single.sy = data.getFloat32(splatOffset + scaleOffsetBytes + 4, true);
189
- single.sz = data.getFloat32(splatOffset + scaleOffsetBytes + 8, true);
190
- single.qw = data.getFloat32(splatOffset + rotationOffsetBytes + 0, true);
191
- single.qx = data.getFloat32(splatOffset + rotationOffsetBytes + 4, true);
192
- single.qy = data.getFloat32(splatOffset + rotationOffsetBytes + 8, true);
193
- single.qz = data.getFloat32(splatOffset + rotationOffsetBytes + 12, true);
194
- }
195
- else {
196
- single.x = (data.getUint16(splatOffset + 0, true) - compressionScaleRange) * compressionScaleFactor + bucketArray[3 * bucketIndex + 0];
197
- single.y = (data.getUint16(splatOffset + 2, true) - compressionScaleRange) * compressionScaleFactor + bucketArray[3 * bucketIndex + 1];
198
- single.z = (data.getUint16(splatOffset + 4, true) - compressionScaleRange) * compressionScaleFactor + bucketArray[3 * bucketIndex + 2];
199
- single.sx = fromHalf(data.getUint16(splatOffset + scaleOffsetBytes + 0, true));
200
- single.sy = fromHalf(data.getUint16(splatOffset + scaleOffsetBytes + 2, true));
201
- single.sz = fromHalf(data.getUint16(splatOffset + scaleOffsetBytes + 4, true));
202
- single.qw = fromHalf(data.getUint16(splatOffset + rotationOffsetBytes + 0, true));
203
- single.qx = fromHalf(data.getUint16(splatOffset + rotationOffsetBytes + 2, true));
204
- single.qy = fromHalf(data.getUint16(splatOffset + rotationOffsetBytes + 4, true));
205
- single.qz = fromHalf(data.getUint16(splatOffset + rotationOffsetBytes + 6, true));
206
- }
207
- single.r = data.getUint8(splatOffset + colorOffsetBytes + 0) / 255;
208
- single.g = data.getUint8(splatOffset + colorOffsetBytes + 1) / 255;
209
- single.b = data.getUint8(splatOffset + colorOffsetBytes + 2) / 255;
210
- single.a = data.getUint8(splatOffset + colorOffsetBytes + 3) / 255;
211
- setFn(j + BlockOffset, single);
212
- const shOffsetBytes = splatOffset + sphericalHarmonicsOffsetBytes;
213
- for (let k = 0; k < shComponents; k++) {
214
- shData[k] = compressionLevel === 0 ?
215
- data.getFloat32(shOffsetBytes + SHIndex[k] * 4, true) :
216
- compressionLevel === 1 ?
217
- fromHalf(data.getUint16(shOffsetBytes + SHIndex[k] * 2, true)) :
218
- (minSH + data.getUint8(shOffsetBytes + SHIndex[k]) / 255 * (maxSH - minSH));
219
- }
220
- for (let k = maxSHSize - 1; k >= shComponents; k--) {
221
- shData[k] = 0;
222
- }
223
- setShFn(j + BlockOffset, shData);
224
- }
225
- sectionBase += storageSizeBytes;
226
- }
227
- data.finishBlock();
228
- }
229
- async write(_stream, _data) {
230
- throw new Error('Method not implemented.');
231
- }
232
- }
1
+ import { SH_MAPS } from '../constant.js';
2
+ import { fromHalf } from '../utils/index.js';
3
+ const KSPLAT_COMPRESSION = {
4
+ 0: {
5
+ bytesPerCenter: 12,
6
+ bytesPerScale: 12,
7
+ bytesPerRotation: 16,
8
+ bytesPerColor: 4,
9
+ bytesPerSphericalHarmonicsComponent: 4,
10
+ scaleOffsetBytes: 12,
11
+ rotationOffsetBytes: 24,
12
+ colorOffsetBytes: 40,
13
+ sphericalHarmonicsOffsetBytes: 44,
14
+ scaleRange: 1,
15
+ },
16
+ 1: {
17
+ bytesPerCenter: 6,
18
+ bytesPerScale: 6,
19
+ bytesPerRotation: 8,
20
+ bytesPerColor: 4,
21
+ bytesPerSphericalHarmonicsComponent: 2,
22
+ scaleOffsetBytes: 6,
23
+ rotationOffsetBytes: 12,
24
+ colorOffsetBytes: 20,
25
+ sphericalHarmonicsOffsetBytes: 24,
26
+ scaleRange: 32767,
27
+ },
28
+ 2: {
29
+ bytesPerCenter: 6,
30
+ bytesPerScale: 6,
31
+ bytesPerRotation: 8,
32
+ bytesPerColor: 4,
33
+ bytesPerSphericalHarmonicsComponent: 1,
34
+ scaleOffsetBytes: 6,
35
+ rotationOffsetBytes: 12,
36
+ colorOffsetBytes: 20,
37
+ sphericalHarmonicsOffsetBytes: 24,
38
+ scaleRange: 32767,
39
+ },
40
+ };
41
+ const SHIndex = [
42
+ 0,
43
+ 3,
44
+ 6,
45
+ 1,
46
+ 4,
47
+ 7,
48
+ 2,
49
+ 5,
50
+ 8, // sh1
51
+ 9,
52
+ 14,
53
+ 19,
54
+ 10,
55
+ 15,
56
+ 20,
57
+ 11,
58
+ 16,
59
+ 21,
60
+ 12,
61
+ 17,
62
+ 22,
63
+ 13,
64
+ 18,
65
+ 23, // sh2
66
+ 24,
67
+ 31,
68
+ 38,
69
+ 25,
70
+ 32,
71
+ 39,
72
+ 26,
73
+ 33,
74
+ 40,
75
+ 27,
76
+ 34,
77
+ 41,
78
+ 28,
79
+ 35,
80
+ 42,
81
+ 29,
82
+ 36,
83
+ 43,
84
+ 30,
85
+ 37,
86
+ 44, // sh3
87
+ ];
88
+ const HEADER_BYTES = 4096;
89
+ const SECTION_BYTES = 1024;
90
+ export class KsplatFile {
91
+ constructor() {
92
+ this.counts = 0;
93
+ this.shDegree = 0;
94
+ }
95
+ load(buffer) {
96
+ this.buffer = buffer;
97
+ const header = new DataView(buffer.buffer, 0, HEADER_BYTES);
98
+ const versionMajor = header.getUint8(0);
99
+ const versionMinor = header.getUint8(1);
100
+ if (versionMajor !== 0 || versionMinor < 1) {
101
+ throw new Error(`Unsupported .ksplat version: ${versionMajor}.${versionMinor}`);
102
+ }
103
+ const maxSectionCount = header.getUint32(4, true);
104
+ const sectionCount = header.getUint32(8, true);
105
+ const maxSplatCount = header.getUint32(12, true);
106
+ const splatCount = header.getUint32(16, true);
107
+ const compressionLevel = header.getUint16(20, true);
108
+ if (compressionLevel < 0 || compressionLevel > 2) {
109
+ throw new Error(`Invalid .ksplat compression level: ${compressionLevel}`);
110
+ }
111
+ const sceneCenterX = header.getFloat32(24, true);
112
+ const sceneCenterY = header.getFloat32(28, true);
113
+ const sceneCenterZ = header.getFloat32(32, true);
114
+ const minSH = header.getFloat32(36, true) || -1.5;
115
+ const maxSH = header.getFloat32(40, true) || 1.5;
116
+ let maxSHDegree = 0;
117
+ const sections = [];
118
+ for (let i = 0; i < maxSectionCount; i++) {
119
+ const section = new DataView(buffer.buffer, HEADER_BYTES + i * SECTION_BYTES, SECTION_BYTES);
120
+ const sectionSplatCount = section.getUint32(0, true);
121
+ const sectionMaxSplatCount = section.getUint32(4, true);
122
+ const bucketSize = section.getUint32(8, true);
123
+ const bucketCount = section.getUint32(12, true);
124
+ const bucketBlockSize = section.getFloat32(16, true);
125
+ const bucketStorageSizeBytes = section.getUint16(20, true);
126
+ const compressionScaleRange = section.getUint32(24, true);
127
+ const fullBucketCount = section.getUint32(32, true);
128
+ const partiallyFilledBucketCount = section.getUint32(36, true);
129
+ const shDegree = section.getUint16(40, true);
130
+ maxSHDegree = Math.max(maxSHDegree, shDegree);
131
+ sections.push({
132
+ sectionSplatCount,
133
+ sectionMaxSplatCount,
134
+ bucketSize,
135
+ bucketCount,
136
+ bucketBlockSize,
137
+ bucketStorageSizeBytes,
138
+ compressionScaleRange: compressionScaleRange || KSPLAT_COMPRESSION[compressionLevel].scaleRange,
139
+ fullBucketCount,
140
+ partiallyFilledBucketCount,
141
+ shDegree,
142
+ });
143
+ }
144
+ this.header = {
145
+ versionMajor,
146
+ versionMinor,
147
+ maxSectionCount,
148
+ sectionCount,
149
+ maxSplatCount,
150
+ splatCount,
151
+ compressionLevel,
152
+ sceneCenter: [sceneCenterX, sceneCenterY, sceneCenterZ],
153
+ shRange: [minSH, maxSH],
154
+ };
155
+ this.sections = sections;
156
+ this.counts = splatCount;
157
+ this.shDegree = maxSHDegree;
158
+ }
159
+ async read(stream, contentLength, data) {
160
+ let BlockOffset = 0;
161
+ {
162
+ const buffer = new Uint8Array(contentLength);
163
+ const reader = stream.getReader();
164
+ let offset = 0;
165
+ while (true) {
166
+ const { done, value } = await reader.read();
167
+ if (done) {
168
+ break;
169
+ }
170
+ buffer.set(value, offset);
171
+ offset += value.length;
172
+ }
173
+ this.load(buffer);
174
+ BlockOffset = await data.initBlock(this.counts, this.shDegree);
175
+ }
176
+ const setFn = data.set.bind(data);
177
+ const setShFn = data.setShN.bind(data);
178
+ const { buffer, header, sections, shDegree: maxSHDegree } = this;
179
+ const { maxSectionCount, compressionLevel, shRange: [minSH, maxSH], } = header;
180
+ const isHighQualitySplatData = compressionLevel === 0;
181
+ const single = {
182
+ x: 0,
183
+ y: 0,
184
+ z: 0,
185
+ sx: 0,
186
+ sy: 0,
187
+ sz: 0,
188
+ qx: 0,
189
+ qy: 0,
190
+ qz: 0,
191
+ qw: 0,
192
+ r: 0,
193
+ g: 0,
194
+ b: 0,
195
+ a: 0,
196
+ shN: [],
197
+ };
198
+ const maxSHSize = SH_MAPS[maxSHDegree];
199
+ const shData = new Array(maxSHSize);
200
+ let sectionBase = HEADER_BYTES + maxSectionCount * SECTION_BYTES;
201
+ for (let i = 0; i < maxSectionCount; i++) {
202
+ const { sectionSplatCount, sectionMaxSplatCount, bucketSize, bucketCount, bucketBlockSize, bucketStorageSizeBytes, fullBucketCount, partiallyFilledBucketCount, compressionScaleRange, shDegree, } = sections[i];
203
+ const fullBucketSplats = fullBucketCount * bucketSize;
204
+ const bucketsMetaDataSizeBytes = partiallyFilledBucketCount * 4;
205
+ const bucketsStorageSizeBytes = bucketStorageSizeBytes * bucketCount + bucketsMetaDataSizeBytes;
206
+ const shComponents = SH_MAPS[shDegree];
207
+ const { bytesPerCenter, bytesPerScale, bytesPerRotation, bytesPerColor, bytesPerSphericalHarmonicsComponent, scaleOffsetBytes, rotationOffsetBytes, colorOffsetBytes, sphericalHarmonicsOffsetBytes, } = KSPLAT_COMPRESSION[compressionLevel];
208
+ const bytesPerSplat = bytesPerCenter +
209
+ bytesPerScale +
210
+ bytesPerRotation +
211
+ bytesPerColor +
212
+ shComponents * bytesPerSphericalHarmonicsComponent;
213
+ const splatDataStorageSizeBytes = bytesPerSplat * sectionMaxSplatCount;
214
+ const storageSizeBytes = splatDataStorageSizeBytes + bucketsStorageSizeBytes;
215
+ const compressionScaleFactor = bucketBlockSize / 2 / compressionScaleRange;
216
+ const bucketsBase = sectionBase + bucketsMetaDataSizeBytes;
217
+ const dataBase = sectionBase + bucketsStorageSizeBytes;
218
+ const data = new DataView(buffer.buffer, dataBase, splatDataStorageSizeBytes);
219
+ const bucketArray = new Float32Array(buffer.buffer, bucketsBase, bucketCount * 3);
220
+ const partiallyFilledBucketLengths = new Uint32Array(buffer.buffer, sectionBase, partiallyFilledBucketCount);
221
+ let partialBucketIndex = fullBucketCount;
222
+ let partialBucketBase = fullBucketSplats;
223
+ for (let j = 0; j < sectionSplatCount; j++) {
224
+ const splatOffset = j * bytesPerSplat;
225
+ let bucketIndex;
226
+ if (j < fullBucketSplats) {
227
+ bucketIndex = Math.floor(j / bucketSize);
228
+ }
229
+ else {
230
+ const bucketLength = partiallyFilledBucketLengths[partialBucketIndex - fullBucketCount];
231
+ if (j >= partialBucketBase + bucketLength) {
232
+ partialBucketIndex += 1;
233
+ partialBucketBase += bucketLength;
234
+ }
235
+ bucketIndex = partialBucketIndex;
236
+ }
237
+ if (isHighQualitySplatData) {
238
+ single.x = data.getFloat32(splatOffset + 0, true);
239
+ single.y = data.getFloat32(splatOffset + 4, true);
240
+ single.z = data.getFloat32(splatOffset + 8, true);
241
+ single.sx = data.getFloat32(splatOffset + scaleOffsetBytes + 0, true);
242
+ single.sy = data.getFloat32(splatOffset + scaleOffsetBytes + 4, true);
243
+ single.sz = data.getFloat32(splatOffset + scaleOffsetBytes + 8, true);
244
+ single.qw = data.getFloat32(splatOffset + rotationOffsetBytes + 0, true);
245
+ single.qx = data.getFloat32(splatOffset + rotationOffsetBytes + 4, true);
246
+ single.qy = data.getFloat32(splatOffset + rotationOffsetBytes + 8, true);
247
+ single.qz = data.getFloat32(splatOffset + rotationOffsetBytes + 12, true);
248
+ }
249
+ else {
250
+ single.x =
251
+ (data.getUint16(splatOffset + 0, true) - compressionScaleRange) * compressionScaleFactor +
252
+ bucketArray[3 * bucketIndex + 0];
253
+ single.y =
254
+ (data.getUint16(splatOffset + 2, true) - compressionScaleRange) * compressionScaleFactor +
255
+ bucketArray[3 * bucketIndex + 1];
256
+ single.z =
257
+ (data.getUint16(splatOffset + 4, true) - compressionScaleRange) * compressionScaleFactor +
258
+ bucketArray[3 * bucketIndex + 2];
259
+ single.sx = fromHalf(data.getUint16(splatOffset + scaleOffsetBytes + 0, true));
260
+ single.sy = fromHalf(data.getUint16(splatOffset + scaleOffsetBytes + 2, true));
261
+ single.sz = fromHalf(data.getUint16(splatOffset + scaleOffsetBytes + 4, true));
262
+ single.qw = fromHalf(data.getUint16(splatOffset + rotationOffsetBytes + 0, true));
263
+ single.qx = fromHalf(data.getUint16(splatOffset + rotationOffsetBytes + 2, true));
264
+ single.qy = fromHalf(data.getUint16(splatOffset + rotationOffsetBytes + 4, true));
265
+ single.qz = fromHalf(data.getUint16(splatOffset + rotationOffsetBytes + 6, true));
266
+ }
267
+ single.r = data.getUint8(splatOffset + colorOffsetBytes + 0) / 255;
268
+ single.g = data.getUint8(splatOffset + colorOffsetBytes + 1) / 255;
269
+ single.b = data.getUint8(splatOffset + colorOffsetBytes + 2) / 255;
270
+ single.a = data.getUint8(splatOffset + colorOffsetBytes + 3) / 255;
271
+ setFn(j + BlockOffset, single);
272
+ const shOffsetBytes = splatOffset + sphericalHarmonicsOffsetBytes;
273
+ for (let k = 0; k < shComponents; k++) {
274
+ shData[k] =
275
+ compressionLevel === 0
276
+ ? data.getFloat32(shOffsetBytes + SHIndex[k] * 4, true)
277
+ : compressionLevel === 1
278
+ ? fromHalf(data.getUint16(shOffsetBytes + SHIndex[k] * 2, true))
279
+ : minSH + (data.getUint8(shOffsetBytes + SHIndex[k]) / 255) * (maxSH - minSH);
280
+ }
281
+ for (let k = maxSHSize - 1; k >= shComponents; k--) {
282
+ shData[k] = 0;
283
+ }
284
+ setShFn(j + BlockOffset, shData);
285
+ }
286
+ sectionBase += storageSizeBytes;
287
+ }
288
+ data.finishBlock();
289
+ }
290
+ async write(_stream, _data) {
291
+ throw new Error('Method not implemented.');
292
+ }
293
+ }
@@ -1,11 +1,11 @@
1
- import { SplatData } from '../SplatData.js';
2
- import { IFile } from './IFile.js';
3
- export declare class LccFile implements IFile {
4
- private counts;
5
- private shDegree;
6
- private meta;
7
- private refs;
8
- private load;
9
- read(stream: ReadableStream<Uint8Array>, contentLength: number, data: SplatData): Promise<void>;
10
- write(_stream: WritableStream<Uint8Array>, _data: SplatData): Promise<void>;
11
- }
1
+ import type { SplatData } from '../SplatData.js';
2
+ import type { IFile } from './IFile.js';
3
+ export declare class LccFile implements IFile {
4
+ private counts;
5
+ private shDegree;
6
+ private meta;
7
+ private refs;
8
+ private load;
9
+ read(stream: ReadableStream<Uint8Array>, contentLength: number, data: SplatData): Promise<void>;
10
+ write(_stream: WritableStream<Uint8Array>, _data: SplatData): Promise<void>;
11
+ }