@loaders.gl/splats 4.5.0-alpha.1
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/LICENSE +41 -0
- package/README.md +3 -0
- package/dist/bundled.d.ts +2 -0
- package/dist/bundled.d.ts.map +1 -0
- package/dist/bundled.js +5 -0
- package/dist/bundled.js.map +1 -0
- package/dist/dist.dev.js +33741 -0
- package/dist/dist.min.js +82 -0
- package/dist/index.cjs +1786 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/ksplat-loader-types.d.ts +19 -0
- package/dist/ksplat-loader-types.d.ts.map +1 -0
- package/dist/ksplat-loader-types.js +20 -0
- package/dist/ksplat-loader-types.js.map +1 -0
- package/dist/ksplat-loader.d.ts +21 -0
- package/dist/ksplat-loader.d.ts.map +1 -0
- package/dist/ksplat-loader.js +12 -0
- package/dist/ksplat-loader.js.map +1 -0
- package/dist/lib/parse-ksplat.d.ts +7 -0
- package/dist/lib/parse-ksplat.d.ts.map +1 -0
- package/dist/lib/parse-ksplat.js +312 -0
- package/dist/lib/parse-ksplat.js.map +1 -0
- package/dist/lib/parse-rad-chunk.d.ts +19 -0
- package/dist/lib/parse-rad-chunk.d.ts.map +1 -0
- package/dist/lib/parse-rad-chunk.js +514 -0
- package/dist/lib/parse-rad-chunk.js.map +1 -0
- package/dist/lib/parse-rad.d.ts +136 -0
- package/dist/lib/parse-rad.d.ts.map +1 -0
- package/dist/lib/parse-rad.js +110 -0
- package/dist/lib/parse-rad.js.map +1 -0
- package/dist/lib/parse-splat.d.ts +7 -0
- package/dist/lib/parse-splat.d.ts.map +1 -0
- package/dist/lib/parse-splat.js +58 -0
- package/dist/lib/parse-splat.js.map +1 -0
- package/dist/lib/parse-spz.d.ts +7 -0
- package/dist/lib/parse-spz.d.ts.map +1 -0
- package/dist/lib/parse-spz.js +268 -0
- package/dist/lib/parse-spz.js.map +1 -0
- package/dist/lib/splat-utils.d.ts +12 -0
- package/dist/lib/splat-utils.d.ts.map +1 -0
- package/dist/lib/splat-utils.js +38 -0
- package/dist/lib/splat-utils.js.map +1 -0
- package/dist/lib/splats-arrow-table.d.ts +5 -0
- package/dist/lib/splats-arrow-table.d.ts.map +1 -0
- package/dist/lib/splats-arrow-table.js +133 -0
- package/dist/lib/splats-arrow-table.js.map +1 -0
- package/dist/rad-loader-types.d.ts +16 -0
- package/dist/rad-loader-types.d.ts.map +1 -0
- package/dist/rad-loader-types.js +16 -0
- package/dist/rad-loader-types.js.map +1 -0
- package/dist/rad-loader.d.ts +20 -0
- package/dist/rad-loader.d.ts.map +1 -0
- package/dist/rad-loader.js +14 -0
- package/dist/rad-loader.js.map +1 -0
- package/dist/rad-metadata.schema.json +133 -0
- package/dist/rad-source-loader.d.ts +112 -0
- package/dist/rad-source-loader.d.ts.map +1 -0
- package/dist/rad-source-loader.js +329 -0
- package/dist/rad-source-loader.js.map +1 -0
- package/dist/rad-zod-schema.cjs +81 -0
- package/dist/rad-zod-schema.cjs.map +7 -0
- package/dist/rad-zod-schema.d.ts +88 -0
- package/dist/rad-zod-schema.d.ts.map +1 -0
- package/dist/rad-zod-schema.js +70 -0
- package/dist/rad-zod-schema.js.map +1 -0
- package/dist/radc-metadata.schema.json +112 -0
- package/dist/splat-loader-types.d.ts +19 -0
- package/dist/splat-loader-types.d.ts.map +1 -0
- package/dist/splat-loader-types.js +20 -0
- package/dist/splat-loader-types.js.map +1 -0
- package/dist/splat-loader.d.ts +21 -0
- package/dist/splat-loader.d.ts.map +1 -0
- package/dist/splat-loader.js +12 -0
- package/dist/splat-loader.js.map +1 -0
- package/dist/splats-format.d.ts +39 -0
- package/dist/splats-format.d.ts.map +1 -0
- package/dist/splats-format.js +42 -0
- package/dist/splats-format.js.map +1 -0
- package/dist/spz-loader-types.d.ts +20 -0
- package/dist/spz-loader-types.d.ts.map +1 -0
- package/dist/spz-loader-types.js +20 -0
- package/dist/spz-loader-types.js.map +1 -0
- package/dist/spz-loader.d.ts +22 -0
- package/dist/spz-loader.d.ts.map +1 -0
- package/dist/spz-loader.js +11 -0
- package/dist/spz-loader.js.map +1 -0
- package/dist/types.d.ts +34 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/unbundled.d.ts +2 -0
- package/dist/unbundled.d.ts.map +1 -0
- package/dist/unbundled.js +5 -0
- package/dist/unbundled.js.map +1 -0
- package/package.json +94 -0
- package/src/bundled.ts +5 -0
- package/src/index.ts +28 -0
- package/src/ksplat-loader-types.ts +25 -0
- package/src/ksplat-loader.ts +16 -0
- package/src/lib/parse-ksplat.ts +540 -0
- package/src/lib/parse-rad-chunk.ts +721 -0
- package/src/lib/parse-rad.ts +318 -0
- package/src/lib/parse-splat.ts +77 -0
- package/src/lib/parse-spz.ts +368 -0
- package/src/lib/splat-utils.ts +49 -0
- package/src/lib/splats-arrow-table.ts +190 -0
- package/src/rad-loader-types.ts +20 -0
- package/src/rad-loader.ts +22 -0
- package/src/rad-source-loader.ts +491 -0
- package/src/rad-zod-schema.ts +83 -0
- package/src/splat-loader-types.ts +25 -0
- package/src/splat-loader.ts +16 -0
- package/src/splats-format.ts +47 -0
- package/src/spz-loader-types.ts +25 -0
- package/src/spz-loader.ts +16 -0
- package/src/types.ts +39 -0
- package/src/unbundled.ts +5 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/** Spark RAD splat quantization and shader decode range metadata. */
|
|
2
|
+
export type RADSplatEncoding = {
|
|
3
|
+
/** Minimum RGB value encoded into quantized color properties. */
|
|
4
|
+
rgbMin?: number;
|
|
5
|
+
/** Maximum RGB value encoded into quantized color properties. */
|
|
6
|
+
rgbMax?: number;
|
|
7
|
+
/** Minimum natural log scale encoded into quantized scale properties. */
|
|
8
|
+
lnScaleMin?: number;
|
|
9
|
+
/** Maximum natural log scale encoded into quantized scale properties. */
|
|
10
|
+
lnScaleMax?: number;
|
|
11
|
+
/** Maximum absolute SH degree-1 coefficient value. */
|
|
12
|
+
sh1Max?: number;
|
|
13
|
+
/** Maximum absolute SH degree-2 coefficient value. */
|
|
14
|
+
sh2Max?: number;
|
|
15
|
+
/** Maximum absolute SH degree-3 coefficient value. */
|
|
16
|
+
sh3Max?: number;
|
|
17
|
+
/** Whether opacity is encoded for LoD blending. */
|
|
18
|
+
lodOpacity?: boolean;
|
|
19
|
+
/** Additional splat-encoding properties are preserved verbatim. */
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
};
|
|
22
|
+
/** One RAD chunk location in the top-level RAD chunk table. */
|
|
23
|
+
export type RADChunkRange = {
|
|
24
|
+
/** Chunk byte offset relative to the top-level RAD chunk payload area. */
|
|
25
|
+
offset: number;
|
|
26
|
+
/** Chunk byte length. */
|
|
27
|
+
bytes: number;
|
|
28
|
+
/** Optional first splat index represented by this chunk. */
|
|
29
|
+
base?: number;
|
|
30
|
+
/** Optional number of splats represented by this chunk. */
|
|
31
|
+
count?: number;
|
|
32
|
+
/** Optional sidecar `.radc` filename relative to the RAD file URL. */
|
|
33
|
+
filename?: string;
|
|
34
|
+
/** Additional chunk-range properties are preserved verbatim. */
|
|
35
|
+
[key: string]: unknown;
|
|
36
|
+
};
|
|
37
|
+
/** Handwritten type for the JSON metadata stored in a Spark RAD header. */
|
|
38
|
+
export type RADMetadataJSON = {
|
|
39
|
+
/** RAD container version. Version 1 is currently supported. */
|
|
40
|
+
version: 1;
|
|
41
|
+
/** RAD payload type. Spark currently writes `gsplat`. */
|
|
42
|
+
type: 'gsplat';
|
|
43
|
+
/** Total splat count represented by the RAD source. */
|
|
44
|
+
count: number;
|
|
45
|
+
/** Maximum spherical harmonics degree present in the chunks. */
|
|
46
|
+
maxSh?: number;
|
|
47
|
+
/** Whether the source includes LoD tree child-count and child-start properties. */
|
|
48
|
+
lodTree?: boolean;
|
|
49
|
+
/** Nominal number of splats per chunk. */
|
|
50
|
+
chunkSize?: number;
|
|
51
|
+
/** Total inline chunk byte length when present in the RAD metadata. */
|
|
52
|
+
allChunkBytes?: number;
|
|
53
|
+
/** RAD chunk table. */
|
|
54
|
+
chunks: RADChunkRange[];
|
|
55
|
+
/** Optional shared splat encoding metadata for chunk decoding. */
|
|
56
|
+
splatEncoding?: RADSplatEncoding;
|
|
57
|
+
/** Optional spherical harmonics codebook count. */
|
|
58
|
+
shCodeCount?: number;
|
|
59
|
+
/** Optional RAD writer comment. */
|
|
60
|
+
comment?: string;
|
|
61
|
+
/** Additional RAD metadata properties are preserved verbatim. */
|
|
62
|
+
[key: string]: unknown;
|
|
63
|
+
};
|
|
64
|
+
/** Parsed Spark RAD top-level metadata with loader-derived byte offsets. */
|
|
65
|
+
export type RADMetadata = RADMetadataJSON & {
|
|
66
|
+
/** Byte length of the JSON metadata block. */
|
|
67
|
+
headerJsonByteLength: number;
|
|
68
|
+
/** Byte offset where inline RAD chunks begin. */
|
|
69
|
+
chunksByteOffset: number;
|
|
70
|
+
};
|
|
71
|
+
/** Known RAD chunk property names. */
|
|
72
|
+
export type RADChunkPropertyName = 'center' | 'alpha' | 'rgb' | 'scales' | 'orientation' | 'sh1' | 'sh2' | 'sh3' | 'child_count' | 'child_start' | 'sh1_code' | 'sh2_code' | 'sh3_code' | 'sh_label';
|
|
73
|
+
/** Known RAD chunk property encodings. */
|
|
74
|
+
export type RADChunkPropertyEncoding = 'f32' | 'f16' | 'f32_lebytes' | 'f16_lebytes' | 'r8' | 'r8_delta' | 's8' | 's8_delta' | 'ln_0r8' | 'ln_f16' | 'oct88r8' | 'u16' | 'u32';
|
|
75
|
+
/** Known RAD chunk property compression modes. */
|
|
76
|
+
export type RADChunkPropertyCompression = 'gz';
|
|
77
|
+
/** One property payload entry inside a RAD chunk. */
|
|
78
|
+
export type RADChunkProperty = {
|
|
79
|
+
/** Property byte offset relative to the chunk payload area. */
|
|
80
|
+
offset: number;
|
|
81
|
+
/** Property byte length before 8-byte payload padding. */
|
|
82
|
+
bytes: number;
|
|
83
|
+
/** Property semantic name. */
|
|
84
|
+
property: RADChunkPropertyName | string;
|
|
85
|
+
/** Property encoding name. */
|
|
86
|
+
encoding: RADChunkPropertyEncoding | string;
|
|
87
|
+
/** Optional property compression mode. */
|
|
88
|
+
compression?: RADChunkPropertyCompression | string;
|
|
89
|
+
/** Optional decode minimum for quantized properties. */
|
|
90
|
+
min?: number;
|
|
91
|
+
/** Optional decode maximum for quantized properties. */
|
|
92
|
+
max?: number;
|
|
93
|
+
/** Additional chunk-property metadata is preserved verbatim. */
|
|
94
|
+
[key: string]: unknown;
|
|
95
|
+
};
|
|
96
|
+
/** Handwritten type for the JSON metadata stored in a Spark RADC chunk header. */
|
|
97
|
+
export type RADChunkMetadataJSON = {
|
|
98
|
+
/** RAD chunk version. Version 1 is currently supported. */
|
|
99
|
+
version: 1;
|
|
100
|
+
/** First global splat index represented by this chunk. */
|
|
101
|
+
base: number;
|
|
102
|
+
/** Number of splats represented by this chunk. */
|
|
103
|
+
count: number;
|
|
104
|
+
/** Byte length of the padded property payload. */
|
|
105
|
+
payloadBytes: number;
|
|
106
|
+
/** Maximum spherical harmonics degree present in this chunk. */
|
|
107
|
+
maxSh?: number;
|
|
108
|
+
/** Whether this chunk contains LoD tree properties. */
|
|
109
|
+
lodTree?: boolean;
|
|
110
|
+
/** Optional chunk-local splat encoding metadata. */
|
|
111
|
+
splatEncoding?: RADSplatEncoding;
|
|
112
|
+
/** Property table for the chunk payload. */
|
|
113
|
+
properties: RADChunkProperty[];
|
|
114
|
+
/** Additional RADC metadata properties are preserved verbatim. */
|
|
115
|
+
[key: string]: unknown;
|
|
116
|
+
};
|
|
117
|
+
/** Parsed Spark RADC chunk metadata with loader-derived byte offsets. */
|
|
118
|
+
export type RADChunkMetadata = RADChunkMetadataJSON & {
|
|
119
|
+
/** Byte length of the chunk JSON metadata block. */
|
|
120
|
+
headerJsonByteLength: number;
|
|
121
|
+
/** Byte offset where the chunk payload begins. */
|
|
122
|
+
payloadByteOffset: number;
|
|
123
|
+
/** Byte length of the RADC header and payload. */
|
|
124
|
+
chunkByteLength: number;
|
|
125
|
+
};
|
|
126
|
+
/** Returns true when the input begins with the Spark RAD magic bytes. */
|
|
127
|
+
export declare function isRAD(data: ArrayBuffer | ArrayBufferView): boolean;
|
|
128
|
+
/** Parses a complete or header-prefix Spark `.rad` buffer. */
|
|
129
|
+
export declare function parseRADHeader(data: ArrayBuffer | ArrayBufferView): RADMetadata;
|
|
130
|
+
/** Parses a Spark `.rad` header when enough bytes are available. */
|
|
131
|
+
export declare function tryParseRADHeader(data: ArrayBuffer | ArrayBufferView): RADMetadata | null;
|
|
132
|
+
/** Parses the metadata header from one Spark `.radc` chunk buffer. */
|
|
133
|
+
export declare function parseRADChunkHeader(data: ArrayBuffer | ArrayBufferView): RADChunkMetadata;
|
|
134
|
+
/** Rounds a byte length to Spark RAD's 8-byte alignment. */
|
|
135
|
+
export declare function roundUpToEight(byteLength: number): number;
|
|
136
|
+
//# sourceMappingURL=parse-rad.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-rad.d.ts","sourceRoot":"","sources":["../../src/lib/parse-rad.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
import { RADChunkMetadataJSONSchema, RADMetadataJSONSchema } from "../rad-zod-schema.js";
|
|
5
|
+
const RAD_MAGIC = 0x30444152;
|
|
6
|
+
const RAD_CHUNK_MAGIC = 0x43444152;
|
|
7
|
+
const RAD_HEADER_BYTE_LENGTH = 8;
|
|
8
|
+
const RAD_CHUNK_PAYLOAD_LENGTH_BYTE_LENGTH = 8;
|
|
9
|
+
const TEXT_DECODER = new TextDecoder();
|
|
10
|
+
/** Returns true when the input begins with the Spark RAD magic bytes. */
|
|
11
|
+
export function isRAD(data) {
|
|
12
|
+
const bytes = getUint8Array(data);
|
|
13
|
+
if (bytes.byteLength < 4) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
return (new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(0, true) === RAD_MAGIC);
|
|
17
|
+
}
|
|
18
|
+
/** Parses a complete or header-prefix Spark `.rad` buffer. */
|
|
19
|
+
export function parseRADHeader(data) {
|
|
20
|
+
const metadata = tryParseRADHeader(data);
|
|
21
|
+
if (!metadata) {
|
|
22
|
+
throw new Error('RADLoader: file must contain a complete RAD metadata header.');
|
|
23
|
+
}
|
|
24
|
+
return metadata;
|
|
25
|
+
}
|
|
26
|
+
/** Parses a Spark `.rad` header when enough bytes are available. */
|
|
27
|
+
export function tryParseRADHeader(data) {
|
|
28
|
+
const bytes = getUint8Array(data);
|
|
29
|
+
if (bytes.byteLength < RAD_HEADER_BYTE_LENGTH) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
const dataView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
33
|
+
const magic = dataView.getUint32(0, true);
|
|
34
|
+
if (magic !== RAD_MAGIC) {
|
|
35
|
+
throw new Error(`RADLoader: RAD0 magic header not found, received 0x${magic.toString(16)}.`);
|
|
36
|
+
}
|
|
37
|
+
const headerJsonByteLength = dataView.getUint32(4, true);
|
|
38
|
+
const headerJsonEnd = RAD_HEADER_BYTE_LENGTH + headerJsonByteLength;
|
|
39
|
+
if (bytes.byteLength < headerJsonEnd) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
const rawMetadata = RADMetadataJSONSchema.parse(parseJSON(bytes.subarray(RAD_HEADER_BYTE_LENGTH, headerJsonEnd), 'RADLoader: failed to parse RAD metadata JSON.'));
|
|
43
|
+
return normalizeRADMetadata(rawMetadata, headerJsonByteLength);
|
|
44
|
+
}
|
|
45
|
+
/** Parses the metadata header from one Spark `.radc` chunk buffer. */
|
|
46
|
+
export function parseRADChunkHeader(data) {
|
|
47
|
+
const bytes = getUint8Array(data);
|
|
48
|
+
if (bytes.byteLength < RAD_HEADER_BYTE_LENGTH) {
|
|
49
|
+
throw new Error('RADLoader: RADC chunk must contain an 8-byte metadata header.');
|
|
50
|
+
}
|
|
51
|
+
const dataView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
52
|
+
const magic = dataView.getUint32(0, true);
|
|
53
|
+
if (magic !== RAD_CHUNK_MAGIC) {
|
|
54
|
+
throw new Error(`RADLoader: RADC magic header not found, received 0x${magic.toString(16)}.`);
|
|
55
|
+
}
|
|
56
|
+
const headerJsonByteLength = dataView.getUint32(4, true);
|
|
57
|
+
const headerJsonEnd = RAD_HEADER_BYTE_LENGTH + headerJsonByteLength;
|
|
58
|
+
const payloadByteLengthOffset = RAD_HEADER_BYTE_LENGTH + roundUpToEight(headerJsonByteLength);
|
|
59
|
+
const payloadByteOffset = payloadByteLengthOffset + RAD_CHUNK_PAYLOAD_LENGTH_BYTE_LENGTH;
|
|
60
|
+
if (bytes.byteLength < payloadByteOffset) {
|
|
61
|
+
throw new Error('RADLoader: RADC chunk must contain a complete metadata header.');
|
|
62
|
+
}
|
|
63
|
+
const rawMetadata = RADChunkMetadataJSONSchema.parse(parseJSON(bytes.subarray(RAD_HEADER_BYTE_LENGTH, headerJsonEnd), 'RADLoader: failed to parse RADC metadata JSON.'));
|
|
64
|
+
const payloadBytes = readSafeUint64(dataView, payloadByteLengthOffset, 'RADC payload byte length');
|
|
65
|
+
return normalizeRADChunkMetadata(rawMetadata, headerJsonByteLength, payloadByteOffset, payloadBytes);
|
|
66
|
+
}
|
|
67
|
+
/** Rounds a byte length to Spark RAD's 8-byte alignment. */
|
|
68
|
+
export function roundUpToEight(byteLength) {
|
|
69
|
+
return (byteLength + 7) & ~7;
|
|
70
|
+
}
|
|
71
|
+
function normalizeRADMetadata(rawMetadata, headerJsonByteLength) {
|
|
72
|
+
return {
|
|
73
|
+
...rawMetadata,
|
|
74
|
+
headerJsonByteLength,
|
|
75
|
+
chunksByteOffset: RAD_HEADER_BYTE_LENGTH + roundUpToEight(headerJsonByteLength)
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function normalizeRADChunkMetadata(rawMetadata, headerJsonByteLength, payloadByteOffset, payloadBytes) {
|
|
79
|
+
if (rawMetadata.payloadBytes !== payloadBytes) {
|
|
80
|
+
throw new Error('RADLoader: RADC metadata payload byte length does not match binary header.');
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
...rawMetadata,
|
|
84
|
+
payloadBytes,
|
|
85
|
+
headerJsonByteLength,
|
|
86
|
+
payloadByteOffset,
|
|
87
|
+
chunkByteLength: payloadByteOffset + payloadBytes
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function parseJSON(bytes, message) {
|
|
91
|
+
try {
|
|
92
|
+
return JSON.parse(TEXT_DECODER.decode(bytes));
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
throw new Error(message);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function readSafeUint64(dataView, byteOffset, fieldName) {
|
|
99
|
+
const value = dataView.getBigUint64(byteOffset, true);
|
|
100
|
+
if (value > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
101
|
+
throw new Error(`RADLoader: ${fieldName} exceeds Number.MAX_SAFE_INTEGER.`);
|
|
102
|
+
}
|
|
103
|
+
return Number(value);
|
|
104
|
+
}
|
|
105
|
+
function getUint8Array(data) {
|
|
106
|
+
return data instanceof ArrayBuffer
|
|
107
|
+
? new Uint8Array(data)
|
|
108
|
+
: new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=parse-rad.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-rad.js","sourceRoot":"","sources":["../../src/lib/parse-rad.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { MeshArrowTable } from '@loaders.gl/schema';
|
|
2
|
+
import type { GaussianSplats } from "../types.js";
|
|
3
|
+
/** Parses a raw `.splat` ArrayBuffer into a Mesh Arrow table. */
|
|
4
|
+
export declare function parseSPLAT(data: ArrayBuffer): MeshArrowTable;
|
|
5
|
+
/** Parses a raw `.splat` ArrayBuffer into decoded Gaussian splat values. */
|
|
6
|
+
export declare function parseSPLATToGaussianSplats(data: ArrayBuffer): GaussianSplats;
|
|
7
|
+
//# sourceMappingURL=parse-splat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-splat.d.ts","sourceRoot":"","sources":["../../src/lib/parse-splat.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAC,cAAc,EAAC,oBAAiB;AAU7C,iEAAiE;AACjE,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,cAAc,CAE5D;AAED,4EAA4E;AAC5E,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,WAAW,GAAG,cAAc,CAuD5E"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
import { makeGaussianSplatsArrowTable } from "./splats-arrow-table.js";
|
|
5
|
+
import { convertAlphaByteToLinearOpacity, decodeQuaternionByte, normalizeQuaternion } from "./splat-utils.js";
|
|
6
|
+
const SPLAT_ROW_BYTE_LENGTH = 32;
|
|
7
|
+
/** Parses a raw `.splat` ArrayBuffer into a Mesh Arrow table. */
|
|
8
|
+
export function parseSPLAT(data) {
|
|
9
|
+
return makeGaussianSplatsArrowTable(parseSPLATToGaussianSplats(data));
|
|
10
|
+
}
|
|
11
|
+
/** Parses a raw `.splat` ArrayBuffer into decoded Gaussian splat values. */
|
|
12
|
+
export function parseSPLATToGaussianSplats(data) {
|
|
13
|
+
if (data.byteLength % SPLAT_ROW_BYTE_LENGTH !== 0) {
|
|
14
|
+
throw new Error(`SPLATLoader: byte length must be a multiple of ${SPLAT_ROW_BYTE_LENGTH}.`);
|
|
15
|
+
}
|
|
16
|
+
const splatCount = data.byteLength / SPLAT_ROW_BYTE_LENGTH;
|
|
17
|
+
const dataView = new DataView(data);
|
|
18
|
+
const positions = new Float32Array(splatCount * 3);
|
|
19
|
+
const scales = new Float32Array(splatCount * 3);
|
|
20
|
+
const rotations = new Float32Array(splatCount * 4);
|
|
21
|
+
const colors = new Uint8Array(splatCount * 3);
|
|
22
|
+
const opacities = new Float32Array(splatCount);
|
|
23
|
+
for (let splatIndex = 0; splatIndex < splatCount; splatIndex++) {
|
|
24
|
+
const byteOffset = splatIndex * SPLAT_ROW_BYTE_LENGTH;
|
|
25
|
+
const positionOffset = splatIndex * 3;
|
|
26
|
+
const rotationOffset = splatIndex * 4;
|
|
27
|
+
positions[positionOffset + 0] = dataView.getFloat32(byteOffset + 0, true);
|
|
28
|
+
positions[positionOffset + 1] = dataView.getFloat32(byteOffset + 4, true);
|
|
29
|
+
positions[positionOffset + 2] = dataView.getFloat32(byteOffset + 8, true);
|
|
30
|
+
scales[positionOffset + 0] = dataView.getFloat32(byteOffset + 12, true);
|
|
31
|
+
scales[positionOffset + 1] = dataView.getFloat32(byteOffset + 16, true);
|
|
32
|
+
scales[positionOffset + 2] = dataView.getFloat32(byteOffset + 20, true);
|
|
33
|
+
colors[positionOffset + 0] = dataView.getUint8(byteOffset + 24);
|
|
34
|
+
colors[positionOffset + 1] = dataView.getUint8(byteOffset + 25);
|
|
35
|
+
colors[positionOffset + 2] = dataView.getUint8(byteOffset + 26);
|
|
36
|
+
opacities[splatIndex] = convertAlphaByteToLinearOpacity(dataView.getUint8(byteOffset + 27));
|
|
37
|
+
const [w, x, y, z] = normalizeQuaternion(decodeQuaternionByte(dataView.getUint8(byteOffset + 28)), decodeQuaternionByte(dataView.getUint8(byteOffset + 29)), decodeQuaternionByte(dataView.getUint8(byteOffset + 30)), decodeQuaternionByte(dataView.getUint8(byteOffset + 31)));
|
|
38
|
+
rotations[rotationOffset + 0] = w;
|
|
39
|
+
rotations[rotationOffset + 1] = x;
|
|
40
|
+
rotations[rotationOffset + 2] = y;
|
|
41
|
+
rotations[rotationOffset + 3] = z;
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
format: 'splat',
|
|
45
|
+
splatCount,
|
|
46
|
+
positions,
|
|
47
|
+
scales,
|
|
48
|
+
rotations,
|
|
49
|
+
colors,
|
|
50
|
+
opacities,
|
|
51
|
+
loaderData: {
|
|
52
|
+
format: 'splat',
|
|
53
|
+
splatCount,
|
|
54
|
+
rowByteLength: SPLAT_ROW_BYTE_LENGTH
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=parse-splat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-splat.js","sourceRoot":"","sources":["../../src/lib/parse-splat.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { MeshArrowTable } from '@loaders.gl/schema';
|
|
2
|
+
import type { GaussianSplats, SplatsLoaderOptions } from "../types.js";
|
|
3
|
+
/** Parses a Niantic Spatial `.spz` ArrayBuffer into a Mesh Arrow table. */
|
|
4
|
+
export declare function parseSPZ(data: ArrayBuffer, options?: SplatsLoaderOptions): Promise<MeshArrowTable>;
|
|
5
|
+
/** Parses a Niantic Spatial `.spz` ArrayBuffer into decoded Gaussian splat values. */
|
|
6
|
+
export declare function parseSPZToGaussianSplats(data: ArrayBuffer, options?: SplatsLoaderOptions): Promise<GaussianSplats>;
|
|
7
|
+
//# sourceMappingURL=parse-spz.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-spz.d.ts","sourceRoot":"","sources":["../../src/lib/parse-spz.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAC,cAAc,EAAE,mBAAmB,EAAC,oBAAiB;AA6BlE,2EAA2E;AAC3E,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,WAAW,EACjB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,cAAc,CAAC,CAEzB;AAED,sFAAsF;AACtF,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,WAAW,EACjB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,cAAc,CAAC,CAezB"}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
import { ZstdCompression } from '@loaders.gl/compression';
|
|
5
|
+
import { makeGaussianSplatsArrowTable } from "./splats-arrow-table.js";
|
|
6
|
+
import { normalizeQuaternion } from "./splat-utils.js";
|
|
7
|
+
const SPZ_HEADER_BYTE_LENGTH = 32;
|
|
8
|
+
const SPZ_MAGIC = 0x5053474e;
|
|
9
|
+
const SPZ_VERSION = 4;
|
|
10
|
+
const SPZ_EXTENSION_FLAG = 0x2;
|
|
11
|
+
const SPZ_COLOR_SCALE = 0.15;
|
|
12
|
+
const SPZ_ROTATION_COMPONENT_SCALE = Math.SQRT1_2;
|
|
13
|
+
const SPZ_ROTATION_COMPONENT_MASK = (1 << 9) - 1;
|
|
14
|
+
/** Parses a Niantic Spatial `.spz` ArrayBuffer into a Mesh Arrow table. */
|
|
15
|
+
export async function parseSPZ(data, options) {
|
|
16
|
+
return makeGaussianSplatsArrowTable(await parseSPZToGaussianSplats(data, options));
|
|
17
|
+
}
|
|
18
|
+
/** Parses a Niantic Spatial `.spz` ArrayBuffer into decoded Gaussian splat values. */
|
|
19
|
+
export async function parseSPZToGaussianSplats(data, options) {
|
|
20
|
+
const header = parseSPZHeader(data);
|
|
21
|
+
const streamInfos = parseSPZStreamInfos(data, header, getSPZStreamByteLengths(header));
|
|
22
|
+
const compressedStreams = streamInfos.map((streamInfo) => data.slice(streamInfo.compressedOffset, streamInfo.compressedOffset + streamInfo.compressedSize));
|
|
23
|
+
const compression = new ZstdCompression({ modules: options?.modules });
|
|
24
|
+
const streams = await Promise.all(compressedStreams.map((compressedStream, streamIndex) => compression.decompress(compressedStream, streamInfos[streamIndex].uncompressedSize)));
|
|
25
|
+
validateSPZStreamLengths(streams, streamInfos);
|
|
26
|
+
return decodeSPZStreams(header, streams, data);
|
|
27
|
+
}
|
|
28
|
+
/** Parses and validates the SPZ v4 plaintext header. */
|
|
29
|
+
function parseSPZHeader(data) {
|
|
30
|
+
if (data.byteLength < SPZ_HEADER_BYTE_LENGTH) {
|
|
31
|
+
throw new Error(`SPZLoader: file must contain a ${SPZ_HEADER_BYTE_LENGTH}-byte header.`);
|
|
32
|
+
}
|
|
33
|
+
const dataView = new DataView(data);
|
|
34
|
+
const header = {
|
|
35
|
+
magic: dataView.getUint32(0, true),
|
|
36
|
+
version: dataView.getUint32(4, true),
|
|
37
|
+
numPoints: dataView.getUint32(8, true),
|
|
38
|
+
shDegree: dataView.getUint8(12),
|
|
39
|
+
fractionalBits: dataView.getUint8(13),
|
|
40
|
+
flags: dataView.getUint8(14),
|
|
41
|
+
numStreams: dataView.getUint8(15),
|
|
42
|
+
tocByteOffset: dataView.getUint32(16, true)
|
|
43
|
+
};
|
|
44
|
+
if (header.magic !== SPZ_MAGIC) {
|
|
45
|
+
throw new Error('SPZLoader: NGSP magic header not found.');
|
|
46
|
+
}
|
|
47
|
+
if (header.version !== SPZ_VERSION) {
|
|
48
|
+
throw new Error(`SPZLoader: version ${header.version} is not supported.`);
|
|
49
|
+
}
|
|
50
|
+
if (header.shDegree > 4) {
|
|
51
|
+
throw new Error(`SPZLoader: spherical harmonics degree ${header.shDegree} is not supported.`);
|
|
52
|
+
}
|
|
53
|
+
if (header.tocByteOffset < SPZ_HEADER_BYTE_LENGTH || header.tocByteOffset > data.byteLength) {
|
|
54
|
+
throw new Error('SPZLoader: invalid table of contents byte offset.');
|
|
55
|
+
}
|
|
56
|
+
return header;
|
|
57
|
+
}
|
|
58
|
+
/** Parses the SPZ stream table of contents and validates expected stream sizes. */
|
|
59
|
+
function parseSPZStreamInfos(data, header, expectedUncompressedSizes) {
|
|
60
|
+
if (header.numStreams !== expectedUncompressedSizes.length) {
|
|
61
|
+
throw new Error(`SPZLoader: expected ${expectedUncompressedSizes.length} streams, found ${header.numStreams}.`);
|
|
62
|
+
}
|
|
63
|
+
const tocByteLength = header.numStreams * 16;
|
|
64
|
+
const tocEnd = header.tocByteOffset + tocByteLength;
|
|
65
|
+
if (tocEnd > data.byteLength) {
|
|
66
|
+
throw new Error('SPZLoader: table of contents exceeds file byte length.');
|
|
67
|
+
}
|
|
68
|
+
const dataView = new DataView(data);
|
|
69
|
+
let compressedOffset = tocEnd;
|
|
70
|
+
const streamInfos = [];
|
|
71
|
+
for (let streamIndex = 0; streamIndex < header.numStreams; streamIndex++) {
|
|
72
|
+
const tocOffset = header.tocByteOffset + streamIndex * 16;
|
|
73
|
+
const compressedSize = readSafeUint64(dataView, tocOffset);
|
|
74
|
+
const uncompressedSize = readSafeUint64(dataView, tocOffset + 8);
|
|
75
|
+
const expectedUncompressedSize = expectedUncompressedSizes[streamIndex];
|
|
76
|
+
if (uncompressedSize !== expectedUncompressedSize) {
|
|
77
|
+
throw new Error(`SPZLoader: stream ${streamIndex} has ${uncompressedSize} uncompressed bytes, expected ${expectedUncompressedSize}.`);
|
|
78
|
+
}
|
|
79
|
+
if (compressedOffset + compressedSize > data.byteLength) {
|
|
80
|
+
throw new Error(`SPZLoader: stream ${streamIndex} exceeds file byte length.`);
|
|
81
|
+
}
|
|
82
|
+
streamInfos.push({ compressedSize, uncompressedSize, compressedOffset });
|
|
83
|
+
compressedOffset += compressedSize;
|
|
84
|
+
}
|
|
85
|
+
if (compressedOffset !== data.byteLength) {
|
|
86
|
+
throw new Error('SPZLoader: compressed stream byte lengths do not match file byte length.');
|
|
87
|
+
}
|
|
88
|
+
return streamInfos;
|
|
89
|
+
}
|
|
90
|
+
/** Converts a little-endian uint64 to a safe JavaScript number. */
|
|
91
|
+
function readSafeUint64(dataView, byteOffset) {
|
|
92
|
+
const value = dataView.getBigUint64(byteOffset, true);
|
|
93
|
+
if (value > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
94
|
+
throw new Error('SPZLoader: stream byte length exceeds Number.MAX_SAFE_INTEGER.');
|
|
95
|
+
}
|
|
96
|
+
return Number(value);
|
|
97
|
+
}
|
|
98
|
+
/** Returns expected SPZ v4 stream byte lengths, skipping zero-length SH data. */
|
|
99
|
+
function getSPZStreamByteLengths(header) {
|
|
100
|
+
return [
|
|
101
|
+
header.numPoints * 9,
|
|
102
|
+
header.numPoints,
|
|
103
|
+
header.numPoints * 3,
|
|
104
|
+
header.numPoints * 3,
|
|
105
|
+
header.numPoints * 4,
|
|
106
|
+
header.numPoints * getSphericalHarmonicsComponentCount(header.shDegree)
|
|
107
|
+
].filter((byteLength) => byteLength > 0);
|
|
108
|
+
}
|
|
109
|
+
/** Validates that decompressed stream lengths match the TOC. */
|
|
110
|
+
function validateSPZStreamLengths(streams, streamInfos) {
|
|
111
|
+
for (let streamIndex = 0; streamIndex < streams.length; streamIndex++) {
|
|
112
|
+
if (streams[streamIndex].byteLength !== streamInfos[streamIndex].uncompressedSize) {
|
|
113
|
+
throw new Error(`SPZLoader: decompressed stream ${streamIndex} has unexpected byte length.`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/** Decodes decompressed SPZ streams into shared Gaussian splat arrays. */
|
|
118
|
+
function decodeSPZStreams(header, streams, sourceData) {
|
|
119
|
+
const splatCount = header.numPoints;
|
|
120
|
+
const positions = new Float32Array(splatCount * 3);
|
|
121
|
+
const scales = new Float32Array(splatCount * 3);
|
|
122
|
+
const rotations = new Float32Array(splatCount * 4);
|
|
123
|
+
const colors = new Uint8Array(splatCount * 3);
|
|
124
|
+
const sphericalHarmonicDcs = new Float32Array(splatCount * 3);
|
|
125
|
+
const opacities = new Float32Array(splatCount);
|
|
126
|
+
const sphericalHarmonicsComponentCount = getSphericalHarmonicsComponentCount(header.shDegree);
|
|
127
|
+
const sphericalHarmonics = sphericalHarmonicsComponentCount
|
|
128
|
+
? new Float32Array(splatCount * sphericalHarmonicsComponentCount)
|
|
129
|
+
: undefined;
|
|
130
|
+
const [positionStream, alphaStream, colorStream, scaleStream, rotationStream, sphericalHarmonicsStream] = streams.map((stream) => new Uint8Array(stream));
|
|
131
|
+
decodeSPZPositions(positionStream, positions, header.fractionalBits);
|
|
132
|
+
decodeSPZScales(scaleStream, scales);
|
|
133
|
+
decodeSPZRotations(rotationStream, rotations);
|
|
134
|
+
decodeSPZColors(colorStream, colors, sphericalHarmonicDcs);
|
|
135
|
+
decodeSPZOpacities(alphaStream, opacities);
|
|
136
|
+
if (sphericalHarmonics && sphericalHarmonicsStream) {
|
|
137
|
+
decodeSPZSphericalHarmonics(sphericalHarmonicsStream, sphericalHarmonics);
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
format: 'spz',
|
|
141
|
+
splatCount,
|
|
142
|
+
positions,
|
|
143
|
+
scales,
|
|
144
|
+
rotations,
|
|
145
|
+
colors,
|
|
146
|
+
sphericalHarmonicDcs,
|
|
147
|
+
opacities,
|
|
148
|
+
sphericalHarmonics,
|
|
149
|
+
sphericalHarmonicsComponentCount,
|
|
150
|
+
loaderData: {
|
|
151
|
+
format: 'spz',
|
|
152
|
+
...header,
|
|
153
|
+
antialiased: Boolean(header.flags & 0x1),
|
|
154
|
+
extensionByteLength: getSPZExtensionByteLength(header),
|
|
155
|
+
extensionBytes: getSPZExtensionBytes(sourceData, header)
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/** Decodes 24-bit signed fixed-point SPZ positions. */
|
|
160
|
+
function decodeSPZPositions(positionStream, positions, fractionalBits) {
|
|
161
|
+
const scale = 1 / 2 ** fractionalBits;
|
|
162
|
+
for (let componentIndex = 0; componentIndex < positions.length; componentIndex++) {
|
|
163
|
+
const byteOffset = componentIndex * 3;
|
|
164
|
+
let fixed32 = positionStream[byteOffset] |
|
|
165
|
+
(positionStream[byteOffset + 1] << 8) |
|
|
166
|
+
(positionStream[byteOffset + 2] << 16);
|
|
167
|
+
fixed32 |= fixed32 & 0x800000 ? 0xff000000 : 0;
|
|
168
|
+
positions[componentIndex] = fixed32 * scale;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/** Decodes SPZ log-encoded scales to linear standard deviations. */
|
|
172
|
+
function decodeSPZScales(scaleStream, scales) {
|
|
173
|
+
for (let componentIndex = 0; componentIndex < scales.length; componentIndex++) {
|
|
174
|
+
scales[componentIndex] = Math.exp(scaleStream[componentIndex] / 16 - 10);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/** Decodes SPZ smallest-three quaternion rotations into `[w, x, y, z]` order. */
|
|
178
|
+
function decodeSPZRotations(rotationStream, rotations) {
|
|
179
|
+
for (let splatIndex = 0; splatIndex < rotations.length / 4; splatIndex++) {
|
|
180
|
+
const byteOffset = splatIndex * 4;
|
|
181
|
+
const component = rotationStream[byteOffset] |
|
|
182
|
+
(rotationStream[byteOffset + 1] << 8) |
|
|
183
|
+
(rotationStream[byteOffset + 2] << 16) |
|
|
184
|
+
(rotationStream[byteOffset + 3] << 24);
|
|
185
|
+
const xyzw = decodeSPZQuaternion(component >>> 0);
|
|
186
|
+
const [w, x, y, z] = normalizeQuaternion(xyzw[3], xyzw[0], xyzw[1], xyzw[2]);
|
|
187
|
+
const rotationOffset = splatIndex * 4;
|
|
188
|
+
rotations[rotationOffset + 0] = w;
|
|
189
|
+
rotations[rotationOffset + 1] = x;
|
|
190
|
+
rotations[rotationOffset + 2] = y;
|
|
191
|
+
rotations[rotationOffset + 3] = z;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/** Decodes one SPZ smallest-three quaternion into `[x, y, z, w]` order. */
|
|
195
|
+
function decodeSPZQuaternion(component) {
|
|
196
|
+
const rotation = [0, 0, 0, 0];
|
|
197
|
+
const largestComponent = component >>> 30;
|
|
198
|
+
let remainingBits = component;
|
|
199
|
+
let sumSquares = 0;
|
|
200
|
+
for (let componentIndex = 3; componentIndex >= 0; componentIndex--) {
|
|
201
|
+
if (componentIndex !== largestComponent) {
|
|
202
|
+
const magnitude = remainingBits & SPZ_ROTATION_COMPONENT_MASK;
|
|
203
|
+
const isNegative = (remainingBits >>> 9) & 0x1;
|
|
204
|
+
remainingBits >>>= 10;
|
|
205
|
+
let value = (SPZ_ROTATION_COMPONENT_SCALE * magnitude) / SPZ_ROTATION_COMPONENT_MASK;
|
|
206
|
+
if (isNegative) {
|
|
207
|
+
value = -value;
|
|
208
|
+
}
|
|
209
|
+
rotation[componentIndex] = value;
|
|
210
|
+
sumSquares += value * value;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
rotation[largestComponent] = Math.sqrt(Math.max(0, 1 - sumSquares));
|
|
214
|
+
return rotation;
|
|
215
|
+
}
|
|
216
|
+
/** Decodes SPZ color bytes into display RGB bytes and direct SH DC coefficients. */
|
|
217
|
+
function decodeSPZColors(colorStream, colors, sphericalHarmonicDcs) {
|
|
218
|
+
for (let componentIndex = 0; componentIndex < colors.length; componentIndex++) {
|
|
219
|
+
sphericalHarmonicDcs[componentIndex] =
|
|
220
|
+
(colorStream[componentIndex] / 255 - 0.5) / SPZ_COLOR_SCALE;
|
|
221
|
+
colors[componentIndex] = normalizeColorByte(sphericalHarmonicDcs[componentIndex]);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
/** Decodes SPZ alpha bytes into linear opacity. */
|
|
225
|
+
function decodeSPZOpacities(alphaStream, opacities) {
|
|
226
|
+
for (let splatIndex = 0; splatIndex < opacities.length; splatIndex++) {
|
|
227
|
+
opacities[splatIndex] = alphaStream[splatIndex] / 255;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/** Decodes SPZ quantized SH rest coefficients. */
|
|
231
|
+
function decodeSPZSphericalHarmonics(sphericalHarmonicsStream, sphericalHarmonics) {
|
|
232
|
+
for (let componentIndex = 0; componentIndex < sphericalHarmonics.length; componentIndex++) {
|
|
233
|
+
sphericalHarmonics[componentIndex] = (sphericalHarmonicsStream[componentIndex] - 128) / 128;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
/** Converts an SH DC coefficient to a fallback RGB byte for preview paths. */
|
|
237
|
+
function normalizeColorByte(sphericalHarmonicDc) {
|
|
238
|
+
return Math.min(Math.max(Math.round((sphericalHarmonicDc * SPZ_COLOR_SCALE + 0.5) * 255), 0), 255);
|
|
239
|
+
}
|
|
240
|
+
/** Returns the number of SH rest coefficients per splat for an SPZ degree. */
|
|
241
|
+
function getSphericalHarmonicsComponentCount(shDegree) {
|
|
242
|
+
switch (shDegree) {
|
|
243
|
+
case 0:
|
|
244
|
+
return 0;
|
|
245
|
+
case 1:
|
|
246
|
+
return 9;
|
|
247
|
+
case 2:
|
|
248
|
+
return 24;
|
|
249
|
+
case 3:
|
|
250
|
+
return 45;
|
|
251
|
+
case 4:
|
|
252
|
+
return 72;
|
|
253
|
+
default:
|
|
254
|
+
throw new Error(`SPZLoader: spherical harmonics degree ${shDegree} is not supported.`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
/** Returns the plaintext SPZ extension byte count. */
|
|
258
|
+
function getSPZExtensionByteLength(header) {
|
|
259
|
+
return header.flags & SPZ_EXTENSION_FLAG ? header.tocByteOffset - SPZ_HEADER_BYTE_LENGTH : 0;
|
|
260
|
+
}
|
|
261
|
+
/** Returns a copy of plaintext SPZ extension bytes when extension records are present. */
|
|
262
|
+
function getSPZExtensionBytes(data, header) {
|
|
263
|
+
const extensionByteLength = getSPZExtensionByteLength(header);
|
|
264
|
+
return extensionByteLength
|
|
265
|
+
? new Uint8Array(data.slice(SPZ_HEADER_BYTE_LENGTH, header.tocByteOffset))
|
|
266
|
+
: undefined;
|
|
267
|
+
}
|
|
268
|
+
//# sourceMappingURL=parse-spz.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-spz.js","sourceRoot":"","sources":["../../src/lib/parse-spz.ts"],"names":[],"mappings":"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"}
|