minidraco 0.6.0 → 0.7.0
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 +11 -25
- package/dist/index.d.ts +13 -11
- package/dist/index.js +1223 -1456
- package/dist/pool.js +36 -36
- package/dist/three.d.ts +13 -11
- package/dist/three.js +1253 -1487
- package/dist/worker.js +1234 -1458
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,35 +1,20 @@
|
|
|
1
1
|
// src/decoder/core/DracoTypes.ts
|
|
2
|
-
var DataType = {
|
|
3
|
-
INVALID: 0,
|
|
4
|
-
INT8: 1,
|
|
5
|
-
UINT8: 2,
|
|
6
|
-
INT16: 3,
|
|
7
|
-
UINT16: 4,
|
|
8
|
-
INT32: 5,
|
|
9
|
-
UINT32: 6,
|
|
10
|
-
INT64: 7,
|
|
11
|
-
UINT64: 8,
|
|
12
|
-
FLOAT32: 9,
|
|
13
|
-
FLOAT64: 10,
|
|
14
|
-
BOOL: 11,
|
|
15
|
-
TYPES_COUNT: 12
|
|
16
|
-
};
|
|
17
2
|
function dataTypeLength(dt) {
|
|
18
3
|
switch (dt) {
|
|
19
|
-
case
|
|
20
|
-
case
|
|
21
|
-
case
|
|
4
|
+
case 1 /* INT8 */:
|
|
5
|
+
case 2 /* UINT8 */:
|
|
6
|
+
case 11 /* BOOL */:
|
|
22
7
|
return 1;
|
|
23
|
-
case
|
|
24
|
-
case
|
|
8
|
+
case 3 /* INT16 */:
|
|
9
|
+
case 4 /* UINT16 */:
|
|
25
10
|
return 2;
|
|
26
|
-
case
|
|
27
|
-
case
|
|
28
|
-
case
|
|
11
|
+
case 5 /* INT32 */:
|
|
12
|
+
case 6 /* UINT32 */:
|
|
13
|
+
case 9 /* FLOAT32 */:
|
|
29
14
|
return 4;
|
|
30
|
-
case
|
|
31
|
-
case
|
|
32
|
-
case
|
|
15
|
+
case 7 /* INT64 */:
|
|
16
|
+
case 8 /* UINT64 */:
|
|
17
|
+
case 10 /* FLOAT64 */:
|
|
33
18
|
return 8;
|
|
34
19
|
default:
|
|
35
20
|
return -1;
|
|
@@ -47,73 +32,73 @@ var Type = {
|
|
|
47
32
|
NAMED_ATTRIBUTES_COUNT: 5
|
|
48
33
|
};
|
|
49
34
|
var GeometryAttribute = class {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
35
|
+
c = null;
|
|
36
|
+
w = 1;
|
|
37
|
+
L = 9 /* FLOAT32 */;
|
|
38
|
+
Qa = false;
|
|
39
|
+
M = 0;
|
|
40
|
+
N = 0;
|
|
41
|
+
Aa = Type.INVALID;
|
|
42
|
+
Ba = 0;
|
|
58
43
|
init(attributeType, buffer, numComponents, dataType, normalized, byteStride, byteOffset) {
|
|
59
|
-
this.
|
|
60
|
-
this.
|
|
61
|
-
this.
|
|
62
|
-
this.
|
|
63
|
-
this.
|
|
64
|
-
this.
|
|
65
|
-
this.
|
|
44
|
+
this.c = buffer;
|
|
45
|
+
this.w = numComponents;
|
|
46
|
+
this.L = dataType;
|
|
47
|
+
this.Qa = normalized;
|
|
48
|
+
this.M = byteStride;
|
|
49
|
+
this.N = byteOffset;
|
|
50
|
+
this.Aa = attributeType;
|
|
66
51
|
}
|
|
67
52
|
resetBuffer(buffer, byteStride, byteOffset) {
|
|
68
|
-
this.
|
|
69
|
-
this.
|
|
70
|
-
this.
|
|
53
|
+
this.c = buffer;
|
|
54
|
+
this.M = byteStride;
|
|
55
|
+
this.N = byteOffset;
|
|
71
56
|
}
|
|
72
57
|
get attributeType() {
|
|
73
|
-
return this.
|
|
58
|
+
return this.Aa;
|
|
74
59
|
}
|
|
75
60
|
get dataType() {
|
|
76
|
-
return this.
|
|
61
|
+
return this.L;
|
|
77
62
|
}
|
|
78
63
|
get numComponents() {
|
|
79
|
-
return this.
|
|
64
|
+
return this.w;
|
|
80
65
|
}
|
|
81
66
|
get buffer() {
|
|
82
|
-
return this.
|
|
67
|
+
return this.c;
|
|
83
68
|
}
|
|
84
69
|
get byteStride() {
|
|
85
|
-
return this.
|
|
70
|
+
return this.M;
|
|
86
71
|
}
|
|
87
72
|
get byteOffset() {
|
|
88
|
-
return this.
|
|
73
|
+
return this.N;
|
|
89
74
|
}
|
|
90
75
|
get uniqueId() {
|
|
91
|
-
return this.
|
|
76
|
+
return this.Ba;
|
|
92
77
|
}
|
|
93
78
|
set uniqueId(id) {
|
|
94
|
-
this.
|
|
79
|
+
this.Ba = id;
|
|
95
80
|
}
|
|
96
81
|
};
|
|
97
82
|
|
|
98
83
|
// src/decoder/point_cloud/PointCloud.ts
|
|
99
84
|
var NAMED_ATTRIBUTES_COUNT = 8;
|
|
100
85
|
var PointCloud = class {
|
|
101
|
-
|
|
86
|
+
kb = 0;
|
|
102
87
|
attributes_ = [];
|
|
103
88
|
// named_attribute_index_[type] = [att_id, ...], one list per named type.
|
|
104
|
-
|
|
89
|
+
Ra = [[], [], [], [], [], [], [], []];
|
|
105
90
|
numNamedAttributes(type) {
|
|
106
91
|
if (type < 0 || type >= NAMED_ATTRIBUTES_COUNT) {
|
|
107
92
|
return 0;
|
|
108
93
|
}
|
|
109
|
-
return this.
|
|
94
|
+
return this.Ra[type].length;
|
|
110
95
|
}
|
|
111
96
|
getNamedAttributeId(type, i) {
|
|
112
97
|
if (i === void 0) i = 0;
|
|
113
98
|
if (this.numNamedAttributes(type) <= i) {
|
|
114
99
|
return -1;
|
|
115
100
|
}
|
|
116
|
-
return this.
|
|
101
|
+
return this.Ra[type][i];
|
|
117
102
|
}
|
|
118
103
|
getNamedAttribute(type, i) {
|
|
119
104
|
if (i === void 0) i = 0;
|
|
@@ -153,31 +138,26 @@ var PointCloud = class {
|
|
|
153
138
|
this.attributes_.push(null);
|
|
154
139
|
}
|
|
155
140
|
if (pa.attributeType < NAMED_ATTRIBUTES_COUNT) {
|
|
156
|
-
this.
|
|
141
|
+
this.Ra[pa.attributeType].push(attId);
|
|
157
142
|
}
|
|
158
143
|
pa.uniqueId = attId;
|
|
159
144
|
this.attributes_[attId] = pa;
|
|
160
145
|
}
|
|
161
146
|
numPoints() {
|
|
162
|
-
return this.
|
|
147
|
+
return this.kb;
|
|
163
148
|
}
|
|
164
149
|
setNumPoints(num) {
|
|
165
|
-
this.
|
|
150
|
+
this.kb = num;
|
|
166
151
|
}
|
|
167
152
|
};
|
|
168
153
|
|
|
169
154
|
// src/decoder/mesh/Mesh.ts
|
|
170
|
-
var MeshAttributeElementType = {
|
|
171
|
-
MESH_VERTEX_ATTRIBUTE: 0,
|
|
172
|
-
MESH_CORNER_ATTRIBUTE: 1,
|
|
173
|
-
MESH_FACE_ATTRIBUTE: 2
|
|
174
|
-
};
|
|
175
155
|
var Mesh = class extends PointCloud {
|
|
176
156
|
// Flat Int32Array, 3 point indices per face, for cache locality and to avoid
|
|
177
157
|
// a per-face allocation. faces_[3*f + c] is corner c of face f; corner index
|
|
178
158
|
// ci maps directly to faces_[ci].
|
|
179
159
|
faces_ = new Int32Array(0);
|
|
180
|
-
|
|
160
|
+
lb = 0;
|
|
181
161
|
// Sizes faces_ to hold numFaces faces. Called once per decode, before any
|
|
182
162
|
// face index is written (edgebreaker: _assignPointsToCorners; sequential:
|
|
183
163
|
// decodeConnectivity), so the buffer is allocated exactly here — the
|
|
@@ -189,10 +169,42 @@ var Mesh = class extends PointCloud {
|
|
|
189
169
|
grown.set(this.faces_);
|
|
190
170
|
this.faces_ = grown;
|
|
191
171
|
}
|
|
192
|
-
this.
|
|
172
|
+
this.lb = numFaces;
|
|
193
173
|
}
|
|
194
174
|
numFaces() {
|
|
195
|
-
return this.
|
|
175
|
+
return this.lb;
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
// src/decoder/core/DataBuffer.ts
|
|
180
|
+
var DataBuffer = class {
|
|
181
|
+
n = new Uint8Array(0);
|
|
182
|
+
// Resizes to `size` bytes (contents preserved); when `data` is given, grows
|
|
183
|
+
// as needed and copies its first `size` bytes in.
|
|
184
|
+
update(data, size) {
|
|
185
|
+
if (data === null) {
|
|
186
|
+
this.mb(size);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
if (size > this.n.length) {
|
|
190
|
+
this.mb(size);
|
|
191
|
+
}
|
|
192
|
+
this.n.set(data.length === size ? data : data.subarray(0, size));
|
|
193
|
+
}
|
|
194
|
+
// The caller passes a Uint8Array of exactly dataSize bytes in the common
|
|
195
|
+
// case; avoid allocating a wrapper view per value (dominates storage time /
|
|
196
|
+
// GC pressure).
|
|
197
|
+
write(bytePos, inArray, dataSize) {
|
|
198
|
+
this.n.set(inArray.length === dataSize ? inArray : inArray.subarray(0, dataSize), bytePos);
|
|
199
|
+
}
|
|
200
|
+
get data() {
|
|
201
|
+
return this.n;
|
|
202
|
+
}
|
|
203
|
+
mb(newSize) {
|
|
204
|
+
if (newSize === this.n.length) return;
|
|
205
|
+
const newData = new Uint8Array(newSize);
|
|
206
|
+
newData.set(this.n.subarray(0, Math.min(this.n.length, newSize)));
|
|
207
|
+
this.n = newData;
|
|
196
208
|
}
|
|
197
209
|
};
|
|
198
210
|
|
|
@@ -277,155 +289,140 @@ var releaseScratch = () => {
|
|
|
277
289
|
borrowedUint8.length = 0;
|
|
278
290
|
};
|
|
279
291
|
|
|
280
|
-
// src/decoder/core/DataBuffer.ts
|
|
281
|
-
var DataBuffer = class {
|
|
282
|
-
l = new Uint8Array(0);
|
|
283
|
-
// Resizes to `size` bytes (contents preserved); when `data` is given, grows
|
|
284
|
-
// as needed and copies its first `size` bytes in.
|
|
285
|
-
update(data, size) {
|
|
286
|
-
if (data === null) {
|
|
287
|
-
this.$a(size);
|
|
288
|
-
return;
|
|
289
|
-
}
|
|
290
|
-
if (size > this.l.length) {
|
|
291
|
-
this.$a(size);
|
|
292
|
-
}
|
|
293
|
-
this.l.set(data.length === size ? data : data.subarray(0, size));
|
|
294
|
-
}
|
|
295
|
-
// Replaces the contents with a decode-scoped scratch buffer of exactly
|
|
296
|
-
// `size` bytes; the previous contents are dropped and the new ones are
|
|
297
|
-
// arbitrary, so every byte must be written before it is read. Only for
|
|
298
|
-
// buffers that never outlive the decode (see ScratchArena) — the portable
|
|
299
|
-
// attributes the integer decoders build and discard per attribute are the
|
|
300
|
-
// one caller, and their per-primitive allocation showed up in profiles.
|
|
301
|
-
adoptScratch(size) {
|
|
302
|
-
this.l = scratchUint8(size);
|
|
303
|
-
}
|
|
304
|
-
// The caller passes a Uint8Array of exactly dataSize bytes in the common
|
|
305
|
-
// case; avoid allocating a wrapper view per value (dominates storage time /
|
|
306
|
-
// GC pressure).
|
|
307
|
-
write(bytePos, inArray, dataSize) {
|
|
308
|
-
this.l.set(inArray.length === dataSize ? inArray : inArray.subarray(0, dataSize), bytePos);
|
|
309
|
-
}
|
|
310
|
-
get data() {
|
|
311
|
-
return this.l;
|
|
312
|
-
}
|
|
313
|
-
$a(newSize) {
|
|
314
|
-
if (newSize === this.l.length) return;
|
|
315
|
-
const newData = new Uint8Array(newSize);
|
|
316
|
-
newData.set(this.l.subarray(0, Math.min(this.l.length, newSize)));
|
|
317
|
-
this.l = newData;
|
|
318
|
-
}
|
|
319
|
-
};
|
|
320
|
-
|
|
321
292
|
// src/decoder/attributes/PointAttribute.ts
|
|
322
293
|
function viewCtorFor(dt) {
|
|
323
294
|
switch (dt) {
|
|
324
|
-
case
|
|
295
|
+
case 1 /* INT8 */:
|
|
325
296
|
return Int8Array;
|
|
326
|
-
case
|
|
297
|
+
case 2 /* UINT8 */:
|
|
327
298
|
return Uint8Array;
|
|
328
|
-
case
|
|
299
|
+
case 3 /* INT16 */:
|
|
329
300
|
return Int16Array;
|
|
330
|
-
case
|
|
301
|
+
case 4 /* UINT16 */:
|
|
331
302
|
return Uint16Array;
|
|
332
|
-
case
|
|
303
|
+
case 5 /* INT32 */:
|
|
333
304
|
return Int32Array;
|
|
334
|
-
case
|
|
305
|
+
case 6 /* UINT32 */:
|
|
335
306
|
return Uint32Array;
|
|
336
|
-
case
|
|
307
|
+
case 9 /* FLOAT32 */:
|
|
337
308
|
return Float32Array;
|
|
338
|
-
case
|
|
309
|
+
case 10 /* FLOAT64 */:
|
|
339
310
|
return Float64Array;
|
|
340
311
|
default:
|
|
341
312
|
return null;
|
|
342
313
|
}
|
|
343
314
|
}
|
|
315
|
+
var LAZY_NONE = 0;
|
|
316
|
+
var LAZY_INTEGER = 1;
|
|
317
|
+
var LAZY_QUANTIZED = 2;
|
|
318
|
+
var LAZY_OCTAHEDRON = 3;
|
|
344
319
|
var PointAttribute = class extends GeometryAttribute {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
zb = null;
|
|
320
|
+
A = false;
|
|
321
|
+
Sa = 0;
|
|
322
|
+
B = [];
|
|
323
|
+
W = null;
|
|
350
324
|
// Lazily-created cached typed-array view over the attribute buffer, keyed
|
|
351
325
|
// on (constructor, underlying ArrayBuffer). An attribute only ever reads
|
|
352
326
|
// through the one view type its data type dictates.
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
327
|
+
nb = null;
|
|
328
|
+
ob = null;
|
|
329
|
+
pb = null;
|
|
330
|
+
// Deferred inverse transform. The integer attribute decoders leave their
|
|
331
|
+
// decoded values here as int32 -- quantized floats, octahedral normals or
|
|
332
|
+
// plain integers -- with the transform's parameters, and extractTo applies
|
|
333
|
+
// the transform while gathering the values into point order: one pass over
|
|
334
|
+
// the points instead of an inverse-transform pass into a per-value buffer
|
|
335
|
+
// followed by a gather from it, and no such buffer at all.
|
|
336
|
+
Ca = LAZY_NONE;
|
|
337
|
+
X = null;
|
|
338
|
+
qb = [];
|
|
339
|
+
Da = 0;
|
|
356
340
|
constructor(geometryAttribute) {
|
|
357
341
|
super();
|
|
358
342
|
if (geometryAttribute instanceof GeometryAttribute) {
|
|
359
|
-
this.
|
|
360
|
-
this.
|
|
361
|
-
this.T = geometryAttribute.T;
|
|
362
|
-
this.Ga = geometryAttribute.Ga;
|
|
363
|
-
this.K = geometryAttribute.K;
|
|
343
|
+
this.c = geometryAttribute.c;
|
|
344
|
+
this.w = geometryAttribute.w;
|
|
364
345
|
this.L = geometryAttribute.L;
|
|
365
|
-
this.
|
|
366
|
-
this.
|
|
346
|
+
this.Qa = geometryAttribute.Qa;
|
|
347
|
+
this.M = geometryAttribute.M;
|
|
348
|
+
this.N = geometryAttribute.N;
|
|
349
|
+
this.Aa = geometryAttribute.Aa;
|
|
350
|
+
this.Ba = geometryAttribute.Ba;
|
|
367
351
|
}
|
|
368
352
|
}
|
|
369
353
|
// Intentionally shadows GeometryAttribute.init with a different signature (matches draco.js / C++ source).
|
|
370
354
|
// @ts-expect-error -- signature intentionally differs from the base class, as in the source.
|
|
371
355
|
init(attributeType, numComponents, dataType, normalized, numAttributeValues) {
|
|
372
|
-
this.
|
|
356
|
+
this.W = new DataBuffer();
|
|
373
357
|
const byteStride = dataTypeLength(dataType) * numComponents;
|
|
374
|
-
super.init(attributeType, this.
|
|
358
|
+
super.init(attributeType, this.W, numComponents, dataType, normalized, byteStride, 0);
|
|
375
359
|
this.reset(numAttributeValues);
|
|
376
360
|
this.setIdentityMapping();
|
|
377
361
|
}
|
|
378
362
|
reset(numAttributeValues) {
|
|
379
|
-
if (this.
|
|
380
|
-
this.
|
|
363
|
+
if (this.W === null) {
|
|
364
|
+
this.W = new DataBuffer();
|
|
381
365
|
}
|
|
382
366
|
const entrySize = dataTypeLength(this.dataType) * this.numComponents;
|
|
383
|
-
this.
|
|
384
|
-
this.resetBuffer(this.
|
|
385
|
-
this.
|
|
367
|
+
this.W.update(null, numAttributeValues * entrySize);
|
|
368
|
+
this.resetBuffer(this.W, entrySize, 0);
|
|
369
|
+
this.Sa = numAttributeValues;
|
|
386
370
|
return true;
|
|
387
371
|
}
|
|
388
|
-
//
|
|
389
|
-
//
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
this.
|
|
397
|
-
this.
|
|
398
|
-
|
|
399
|
-
|
|
372
|
+
// Sizes the attribute without allocating storage, for the deferred
|
|
373
|
+
// transforms below (the values live in the decoder's portable attribute).
|
|
374
|
+
resetLazy(numAttributeValues) {
|
|
375
|
+
this.Sa = numAttributeValues;
|
|
376
|
+
}
|
|
377
|
+
// numValues decoded integers of the attribute's own integer type, stored as
|
|
378
|
+
// int32; extractTo converts them to the requested output type.
|
|
379
|
+
setLazyInteger(values) {
|
|
380
|
+
this.Ca = LAZY_INTEGER;
|
|
381
|
+
this.X = values;
|
|
382
|
+
}
|
|
383
|
+
// Quantized float values: value * delta + min per component (float32
|
|
384
|
+
// arithmetic, see _extractQuantized), as the C++ Dequantizer computes them.
|
|
385
|
+
setLazyQuantized(values, minValues, delta) {
|
|
386
|
+
this.Ca = LAZY_QUANTIZED;
|
|
387
|
+
this.X = values;
|
|
388
|
+
this.qb = minValues;
|
|
389
|
+
this.Da = delta;
|
|
390
|
+
}
|
|
391
|
+
// Octahedral normals: two quantized coordinates per value, dequantized by
|
|
392
|
+
// `scale` and turned into unit vectors (see _extractOctahedron).
|
|
393
|
+
setLazyOctahedron(values, scale) {
|
|
394
|
+
this.Ca = LAZY_OCTAHEDRON;
|
|
395
|
+
this.X = values;
|
|
396
|
+
this.Da = scale;
|
|
400
397
|
}
|
|
401
398
|
get size() {
|
|
402
|
-
return this.
|
|
399
|
+
return this.Sa;
|
|
403
400
|
}
|
|
404
401
|
mappedIndex(pointIndex) {
|
|
405
|
-
if (this.
|
|
402
|
+
if (this.A) {
|
|
406
403
|
return pointIndex;
|
|
407
404
|
}
|
|
408
|
-
return this.
|
|
405
|
+
return this.B[pointIndex];
|
|
409
406
|
}
|
|
410
407
|
get isMappingIdentity() {
|
|
411
|
-
return this.
|
|
408
|
+
return this.A;
|
|
412
409
|
}
|
|
413
410
|
get indicesMapSize() {
|
|
414
|
-
if (this.
|
|
411
|
+
if (this.A) {
|
|
415
412
|
return 0;
|
|
416
413
|
}
|
|
417
|
-
return this.
|
|
414
|
+
return this.B.length;
|
|
418
415
|
}
|
|
419
416
|
// Direct access to the explicit point->value index map (a Uint32Array after
|
|
420
417
|
// any of the setExplicitMapping* calls). Lets hot mapping loops write
|
|
421
418
|
// entries without a per-entry dispatch.
|
|
422
419
|
get indicesMap() {
|
|
423
|
-
return this.
|
|
420
|
+
return this.B;
|
|
424
421
|
}
|
|
425
422
|
// Implicit mapping: point index equals attribute entry index.
|
|
426
423
|
setIdentityMapping() {
|
|
427
|
-
this.
|
|
428
|
-
this.
|
|
424
|
+
this.A = true;
|
|
425
|
+
this.B = [];
|
|
429
426
|
}
|
|
430
427
|
// Explicit mapping without an invalid-index fill. Only for callers that
|
|
431
428
|
// provably write every entry right away (the fill was ~4% of decode time on
|
|
@@ -435,80 +432,76 @@ var PointAttribute = class extends GeometryAttribute {
|
|
|
435
432
|
// and avoids boxed-number storage; it is read once per point per attribute.
|
|
436
433
|
// Must be UNSIGNED so the 0xFFFFFFFF invalid sentinel round-trips intact.
|
|
437
434
|
setExplicitMappingUnfilled(numPoints) {
|
|
438
|
-
this.
|
|
439
|
-
this.
|
|
435
|
+
this.A = false;
|
|
436
|
+
this.B = new Uint32Array(numPoints);
|
|
440
437
|
}
|
|
441
438
|
// Adopts an already-computed map, shared with other attributes of the same
|
|
442
439
|
// mesh. The map must be treated as read-only from here on (reads go through
|
|
443
440
|
// mappedIndex/extractTo).
|
|
444
441
|
setExplicitMappingShared(map) {
|
|
445
|
-
this.
|
|
446
|
-
this.
|
|
442
|
+
this.A = false;
|
|
443
|
+
this.B = map;
|
|
447
444
|
}
|
|
448
445
|
// Like setExplicitMappingUnfilled, but from decode-scoped scratch. Only for
|
|
449
446
|
// attributes that never escape the decode (see ScratchArena) -- the portable
|
|
450
447
|
// attributes the sequential decoders build and discard.
|
|
451
448
|
setExplicitMappingScratch(numPoints) {
|
|
452
|
-
this.
|
|
453
|
-
this.
|
|
454
|
-
}
|
|
455
|
-
setAttributeTransformData(transformData) {
|
|
456
|
-
this.zb = transformData;
|
|
449
|
+
this.A = false;
|
|
450
|
+
this.B = scratchUint32(numPoints);
|
|
457
451
|
}
|
|
458
452
|
// Cached typed-array view of the given type over the attribute buffer.
|
|
459
|
-
|
|
460
|
-
if (this.
|
|
461
|
-
this.
|
|
462
|
-
this.
|
|
463
|
-
this.
|
|
464
|
-
}
|
|
465
|
-
return this.
|
|
466
|
-
}
|
|
467
|
-
// Mirrors C++ PointAttribute::ConvertValue<T>()
|
|
468
|
-
// byteOffset 0 and entries are
|
|
469
|
-
// through a typed-array view instead
|
|
453
|
+
rb(Ctor, bufData) {
|
|
454
|
+
if (this.nb !== Ctor || this.ob !== bufData.buffer) {
|
|
455
|
+
this.nb = Ctor;
|
|
456
|
+
this.ob = bufData.buffer;
|
|
457
|
+
this.pb = new Ctor(bufData.buffer);
|
|
458
|
+
}
|
|
459
|
+
return this.pb;
|
|
460
|
+
}
|
|
461
|
+
// Mirrors C++ PointAttribute::ConvertValue<T>() for buffer-backed
|
|
462
|
+
// attributes. Attribute buffers start at byteOffset 0 and entries are
|
|
463
|
+
// naturally aligned, so every type reads through a typed-array view instead
|
|
464
|
+
// of a per-component DataView dispatch.
|
|
470
465
|
convertValue(attIndex, outVal) {
|
|
471
|
-
const
|
|
472
|
-
const
|
|
473
|
-
const
|
|
474
|
-
const nc = this.A;
|
|
475
|
-
if (dt === DataType.INT32) {
|
|
476
|
-
const view2 = this.Ia(Int32Array, bufData);
|
|
477
|
-
const baseIndex2 = bufData.byteOffset + bytePos >> 2;
|
|
478
|
-
for (let i = 0; i < nc; ++i) {
|
|
479
|
-
outVal[i] = view2[baseIndex2 + i];
|
|
480
|
-
}
|
|
481
|
-
return;
|
|
482
|
-
}
|
|
483
|
-
const Ctor = viewCtorFor(dt);
|
|
466
|
+
const bufData = this.c.data;
|
|
467
|
+
const nc = this.w;
|
|
468
|
+
const Ctor = viewCtorFor(this.L);
|
|
484
469
|
if (Ctor === null) {
|
|
485
|
-
for (let i = 0; i < nc; ++i)
|
|
486
|
-
outVal[i] = 0;
|
|
487
|
-
}
|
|
470
|
+
for (let i = 0; i < nc; ++i) outVal[i] = 0;
|
|
488
471
|
return;
|
|
489
472
|
}
|
|
490
|
-
const view = this.
|
|
491
|
-
const baseIndex = (bufData.byteOffset +
|
|
492
|
-
for (let i = 0; i < nc; ++i)
|
|
493
|
-
outVal[i] = view[baseIndex + i];
|
|
494
|
-
}
|
|
473
|
+
const view = this.rb(Ctor, bufData);
|
|
474
|
+
const baseIndex = (bufData.byteOffset + this.N + this.M * attIndex) / Ctor.BYTES_PER_ELEMENT;
|
|
475
|
+
for (let i = 0; i < nc; ++i) outVal[i] = view[baseIndex + i];
|
|
495
476
|
}
|
|
496
|
-
// Flat-array extraction of all values into one output typed array
|
|
497
|
-
//
|
|
477
|
+
// Flat-array extraction of all values into one output typed array, in point
|
|
478
|
+
// order (applying the deferred transform, if any, on the way).
|
|
498
479
|
extractTo(OutputTypedArray, numPoints) {
|
|
499
|
-
const numComponents = this.
|
|
480
|
+
const numComponents = this.w;
|
|
500
481
|
const array = new OutputTypedArray(numPoints * numComponents);
|
|
501
|
-
|
|
502
|
-
|
|
482
|
+
if (numPoints === 0) {
|
|
483
|
+
return array;
|
|
484
|
+
}
|
|
485
|
+
const kind = this.Ca;
|
|
486
|
+
if (kind !== LAZY_NONE) {
|
|
487
|
+
if (this.X !== null) {
|
|
488
|
+
if (kind === LAZY_QUANTIZED) this.Sb(array, numPoints);
|
|
489
|
+
else if (kind === LAZY_OCTAHEDRON) this.Tb(array, numPoints);
|
|
490
|
+
else this.Ub(array, numPoints);
|
|
491
|
+
}
|
|
492
|
+
return array;
|
|
493
|
+
}
|
|
494
|
+
const Ctor = viewCtorFor(this.L);
|
|
495
|
+
if (this.c === null || Ctor === null) {
|
|
503
496
|
return array;
|
|
504
497
|
}
|
|
505
|
-
const bufData = this.
|
|
506
|
-
const isIdentity = this.
|
|
507
|
-
const indicesMap = this.
|
|
508
|
-
const srcView = this.
|
|
498
|
+
const bufData = this.c.data;
|
|
499
|
+
const isIdentity = this.A;
|
|
500
|
+
const indicesMap = this.B;
|
|
501
|
+
const srcView = this.rb(Ctor, bufData);
|
|
509
502
|
const shift = 31 - Math.clz32(Ctor.BYTES_PER_ELEMENT);
|
|
510
|
-
const srcStart = bufData.byteOffset + this.
|
|
511
|
-
const strideElements = this.
|
|
503
|
+
const srcStart = bufData.byteOffset + this.N >> shift;
|
|
504
|
+
const strideElements = this.M >> shift;
|
|
512
505
|
if (isIdentity && strideElements === numComponents) {
|
|
513
506
|
const srcEnd = srcStart + numPoints * numComponents;
|
|
514
507
|
if (srcView.constructor === OutputTypedArray) {
|
|
@@ -516,59 +509,130 @@ var PointAttribute = class extends GeometryAttribute {
|
|
|
516
509
|
return array;
|
|
517
510
|
}
|
|
518
511
|
}
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
array[dst + j] = srcView[srcOffset + j];
|
|
525
|
-
}
|
|
526
|
-
dst += numComponents;
|
|
527
|
-
}
|
|
528
|
-
} else if (numComponents === 3) {
|
|
529
|
-
let dst = 0;
|
|
530
|
-
for (let i = 0; i < numPoints; i++) {
|
|
531
|
-
const srcOffset = srcStart + indicesMap[i] * strideElements;
|
|
532
|
-
array[dst] = srcView[srcOffset];
|
|
533
|
-
array[dst + 1] = srcView[srcOffset + 1];
|
|
534
|
-
array[dst + 2] = srcView[srcOffset + 2];
|
|
535
|
-
dst += 3;
|
|
536
|
-
}
|
|
537
|
-
} else if (numComponents === 2) {
|
|
538
|
-
let dst = 0;
|
|
539
|
-
for (let i = 0; i < numPoints; i++) {
|
|
540
|
-
const srcOffset = srcStart + indicesMap[i] * strideElements;
|
|
541
|
-
array[dst] = srcView[srcOffset];
|
|
542
|
-
array[dst + 1] = srcView[srcOffset + 1];
|
|
543
|
-
dst += 2;
|
|
544
|
-
}
|
|
545
|
-
} else if (numComponents === 4) {
|
|
546
|
-
let dst = 0;
|
|
547
|
-
for (let i = 0; i < numPoints; i++) {
|
|
548
|
-
const srcOffset = srcStart + indicesMap[i] * strideElements;
|
|
549
|
-
array[dst] = srcView[srcOffset];
|
|
550
|
-
array[dst + 1] = srcView[srcOffset + 1];
|
|
551
|
-
array[dst + 2] = srcView[srcOffset + 2];
|
|
552
|
-
array[dst + 3] = srcView[srcOffset + 3];
|
|
553
|
-
dst += 4;
|
|
554
|
-
}
|
|
555
|
-
} else if (numComponents === 1) {
|
|
556
|
-
let dst = 0;
|
|
557
|
-
for (let i = 0; i < numPoints; i++) {
|
|
558
|
-
array[dst++] = srcView[srcStart + indicesMap[i] * strideElements];
|
|
559
|
-
}
|
|
560
|
-
} else {
|
|
561
|
-
let dst = 0;
|
|
562
|
-
for (let i = 0; i < numPoints; i++) {
|
|
563
|
-
const srcOffset = srcStart + indicesMap[i] * strideElements;
|
|
564
|
-
for (let j = 0; j < numComponents; j++) {
|
|
565
|
-
array[dst + j] = srcView[srcOffset + j];
|
|
566
|
-
}
|
|
567
|
-
dst += numComponents;
|
|
512
|
+
let dst = 0;
|
|
513
|
+
for (let i = 0; i < numPoints; i++) {
|
|
514
|
+
const srcOffset = srcStart + (isIdentity ? i : indicesMap[i]) * strideElements;
|
|
515
|
+
for (let j = 0; j < numComponents; j++) {
|
|
516
|
+
array[dst + j] = srcView[srcOffset + j];
|
|
568
517
|
}
|
|
518
|
+
dst += numComponents;
|
|
569
519
|
}
|
|
570
520
|
return array;
|
|
571
521
|
}
|
|
522
|
+
// The deferred transforms, each fused with the point-order gather. One
|
|
523
|
+
// function per transform so the engine tiers each up on its own complete
|
|
524
|
+
// type feedback (a single body for all three deoptimized once per newly
|
|
525
|
+
// seen kind, which made the first decodes of a session measurably slower).
|
|
526
|
+
// Every float step is rounded to float32 exactly where the C++ decoder's
|
|
527
|
+
// float arithmetic rounds (Dequantizer, OctahedronToolBox), so the values
|
|
528
|
+
// are bit-identical to the reference decoder whatever the output array type.
|
|
529
|
+
// Point -> value index; the identity mapping (sequential meshes) gets a
|
|
530
|
+
// plain iota so the loops carry no per-point branch.
|
|
531
|
+
Ta(numPoints) {
|
|
532
|
+
if (!this.A) return this.B;
|
|
533
|
+
const map = new Uint32Array(numPoints);
|
|
534
|
+
for (let p = 0; p < numPoints; ++p) map[p] = p;
|
|
535
|
+
return map;
|
|
536
|
+
}
|
|
537
|
+
// The C++ starts from static_cast<float>(value). An integer below 2^24 is
|
|
538
|
+
// exact as a float32 and its product with a float32 is exact as a double,
|
|
539
|
+
// so for such values `fround(value * scale)` is that float32 product
|
|
540
|
+
// without the (measurably costly) int-to-float32-to-double round trip per
|
|
541
|
+
// component. Larger values (quantization above 24 bits, never seen in
|
|
542
|
+
// practice) are rounded in place once here, after which the same holds.
|
|
543
|
+
sb() {
|
|
544
|
+
const values = this.X;
|
|
545
|
+
for (let i = 0; i < values.length; ++i) {
|
|
546
|
+
if (values[i] >= 16777216 || values[i] <= -16777216) {
|
|
547
|
+
for (let j = 0; j < values.length; ++j) values[j] = Math.fround(values[j]);
|
|
548
|
+
break;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
return values;
|
|
552
|
+
}
|
|
553
|
+
// C++ Dequantizer: float(value) * delta + min, all in float32.
|
|
554
|
+
Sb(out, numPoints) {
|
|
555
|
+
const values = this.sb();
|
|
556
|
+
const map = this.Ta(numPoints);
|
|
557
|
+
const numComponents = this.w;
|
|
558
|
+
const fround = Math.fround;
|
|
559
|
+
const delta = this.Da;
|
|
560
|
+
const min = this.qb;
|
|
561
|
+
if (numComponents === 3) {
|
|
562
|
+
const m0 = min[0];
|
|
563
|
+
const m1 = min[1];
|
|
564
|
+
const m2 = min[2];
|
|
565
|
+
for (let p = 0, d = 0; p < numPoints; ++p, d += 3) {
|
|
566
|
+
const s = map[p] * 3;
|
|
567
|
+
out[d] = fround(fround(values[s] * delta) + m0);
|
|
568
|
+
out[d + 1] = fround(fround(values[s + 1] * delta) + m1);
|
|
569
|
+
out[d + 2] = fround(fround(values[s + 2] * delta) + m2);
|
|
570
|
+
}
|
|
571
|
+
return;
|
|
572
|
+
}
|
|
573
|
+
if (numComponents === 2) {
|
|
574
|
+
const m0 = min[0];
|
|
575
|
+
const m1 = min[1];
|
|
576
|
+
for (let p = 0, d = 0; p < numPoints; ++p, d += 2) {
|
|
577
|
+
const s = map[p] * 2;
|
|
578
|
+
out[d] = fround(fround(values[s] * delta) + m0);
|
|
579
|
+
out[d + 1] = fround(fround(values[s + 1] * delta) + m1);
|
|
580
|
+
}
|
|
581
|
+
return;
|
|
582
|
+
}
|
|
583
|
+
for (let p = 0, d = 0; p < numPoints; ++p) {
|
|
584
|
+
const s = map[p] * numComponents;
|
|
585
|
+
for (let c = 0; c < numComponents; ++c) {
|
|
586
|
+
out[d++] = fround(fround(values[s + c] * delta) + min[c]);
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
// OctahedronToolBox.QuantizedOctahedralCoordsToUnitVector, two quantized
|
|
591
|
+
// coordinates per value to one unit vector per point.
|
|
592
|
+
Tb(out, numPoints) {
|
|
593
|
+
const values = this.sb();
|
|
594
|
+
const map = this.Ta(numPoints);
|
|
595
|
+
const fround = Math.fround;
|
|
596
|
+
const scale = this.Da;
|
|
597
|
+
for (let p = 0, d = 0; p < numPoints; ++p, d += 3) {
|
|
598
|
+
const s = map[p] * 2;
|
|
599
|
+
let y = fround(fround(values[s] * scale) - 1);
|
|
600
|
+
let z = fround(fround(values[s + 1] * scale) - 1);
|
|
601
|
+
const x = fround(fround(1 - Math.abs(y)) - Math.abs(z));
|
|
602
|
+
let xOffset = -x;
|
|
603
|
+
if (xOffset < 0) xOffset = 0;
|
|
604
|
+
y = fround(y + (y < 0 ? xOffset : -xOffset));
|
|
605
|
+
z = fround(z + (z < 0 ? xOffset : -xOffset));
|
|
606
|
+
const normSquared = fround(fround(fround(x * x) + fround(y * y)) + fround(z * z));
|
|
607
|
+
if (normSquared < 1e-6) {
|
|
608
|
+
out[d] = 0;
|
|
609
|
+
out[d + 1] = 0;
|
|
610
|
+
out[d + 2] = 0;
|
|
611
|
+
} else {
|
|
612
|
+
const k = fround(1 / fround(Math.sqrt(normSquared)));
|
|
613
|
+
out[d] = fround(x * k);
|
|
614
|
+
out[d + 1] = fround(y * k);
|
|
615
|
+
out[d + 2] = fround(z * k);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
// The int32 values wrap to the attribute's own integer type (as storing
|
|
620
|
+
// them into it would) before the output store converts them.
|
|
621
|
+
Ub(out, numPoints) {
|
|
622
|
+
const values = this.X;
|
|
623
|
+
const map = this.Ta(numPoints);
|
|
624
|
+
const numComponents = this.w;
|
|
625
|
+
const dt = this.L;
|
|
626
|
+
const shift = 32 - 8 * dataTypeLength(dt);
|
|
627
|
+
const signed = dt === 1 /* INT8 */ || dt === 3 /* INT16 */ || dt === 5 /* INT32 */;
|
|
628
|
+
for (let p = 0, d = 0; p < numPoints; ++p) {
|
|
629
|
+
const s = map[p] * numComponents;
|
|
630
|
+
for (let c = 0; c < numComponents; ++c) {
|
|
631
|
+
const v = values[s + c] << shift;
|
|
632
|
+
out[d++] = signed ? v >> shift : v >>> shift;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
}
|
|
572
636
|
};
|
|
573
637
|
|
|
574
638
|
// src/decoder/core/VarintDecoding.ts
|
|
@@ -590,21 +654,21 @@ function decodeVarint(buffer) {
|
|
|
590
654
|
|
|
591
655
|
// src/decoder/core/DecoderBuffer.ts
|
|
592
656
|
var BitDecoder = class {
|
|
593
|
-
|
|
657
|
+
Ea = null;
|
|
594
658
|
o = 0;
|
|
595
|
-
|
|
659
|
+
ka = 0;
|
|
596
660
|
reset(uint8Array, byteLength) {
|
|
597
|
-
this.
|
|
598
|
-
this.
|
|
661
|
+
this.Ea = uint8Array;
|
|
662
|
+
this.ka = byteLength;
|
|
599
663
|
this.o = 0;
|
|
600
664
|
}
|
|
601
665
|
getBits(nbits) {
|
|
602
666
|
if (nbits > 32) return void 0;
|
|
603
|
-
const buf = this.
|
|
667
|
+
const buf = this.Ea;
|
|
604
668
|
let off = this.o;
|
|
605
669
|
const byteOffset = off >> 3;
|
|
606
670
|
const bitShift = off & 7;
|
|
607
|
-
if (byteOffset + 4 < this.
|
|
671
|
+
if (byteOffset + 4 < this.ka) {
|
|
608
672
|
const val = (buf[byteOffset] | buf[byteOffset + 1] << 8 | buf[byteOffset + 2] << 16 | buf[byteOffset + 3] << 24) >>> 0;
|
|
609
673
|
let result;
|
|
610
674
|
if (nbits > 32 - bitShift) {
|
|
@@ -623,7 +687,7 @@ var BitDecoder = class {
|
|
|
623
687
|
let currOff = off;
|
|
624
688
|
while (bitsRead < nbits) {
|
|
625
689
|
const bOff = currOff >> 3;
|
|
626
|
-
if (bOff >= this.
|
|
690
|
+
if (bOff >= this.ka) return void 0;
|
|
627
691
|
const bShift = currOff & 7;
|
|
628
692
|
const bitsAvail = 8 - bShift;
|
|
629
693
|
const bitsNeeded = nbits - bitsRead;
|
|
@@ -638,61 +702,49 @@ var BitDecoder = class {
|
|
|
638
702
|
}
|
|
639
703
|
};
|
|
640
704
|
var DecoderBuffer = class {
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
705
|
+
n = null;
|
|
706
|
+
Fa = null;
|
|
707
|
+
I = 0;
|
|
708
|
+
d = 0;
|
|
709
|
+
la = new BitDecoder();
|
|
710
|
+
Ga = false;
|
|
647
711
|
init(data, dataSize = data.length) {
|
|
648
|
-
this.
|
|
649
|
-
this.
|
|
650
|
-
this.
|
|
651
|
-
this.
|
|
712
|
+
this.n = data;
|
|
713
|
+
this.Fa = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
714
|
+
this.I = dataSize;
|
|
715
|
+
this.d = 0;
|
|
652
716
|
}
|
|
653
717
|
// Typed little-endian reads.
|
|
654
718
|
decodeUint8() {
|
|
655
|
-
if (this.
|
|
656
|
-
const val = this.
|
|
657
|
-
this.
|
|
658
|
-
return val;
|
|
659
|
-
}
|
|
660
|
-
decodeInt8() {
|
|
661
|
-
if (this.c + 1 > this.w) return void 0;
|
|
662
|
-
const val = this.ea.getInt8(this.c);
|
|
663
|
-
this.c += 1;
|
|
719
|
+
if (this.d + 1 > this.I) return void 0;
|
|
720
|
+
const val = this.n[this.d];
|
|
721
|
+
this.d += 1;
|
|
664
722
|
return val;
|
|
665
723
|
}
|
|
666
724
|
decodeUint16() {
|
|
667
|
-
if (this.
|
|
668
|
-
const val = this.
|
|
669
|
-
this.
|
|
725
|
+
if (this.d + 2 > this.I) return void 0;
|
|
726
|
+
const val = this.Fa.getUint16(this.d, true);
|
|
727
|
+
this.d += 2;
|
|
670
728
|
return val;
|
|
671
729
|
}
|
|
672
730
|
decodeInt32() {
|
|
673
|
-
if (this.
|
|
674
|
-
const val = this.
|
|
675
|
-
this.
|
|
731
|
+
if (this.d + 4 > this.I) return void 0;
|
|
732
|
+
const val = this.Fa.getInt32(this.d, true);
|
|
733
|
+
this.d += 4;
|
|
676
734
|
return val;
|
|
677
735
|
}
|
|
678
736
|
decodeFloat32() {
|
|
679
|
-
if (this.
|
|
680
|
-
const val = this.
|
|
681
|
-
this.
|
|
737
|
+
if (this.d + 4 > this.I) return void 0;
|
|
738
|
+
const val = this.Fa.getFloat32(this.d, true);
|
|
739
|
+
this.d += 4;
|
|
682
740
|
return val;
|
|
683
741
|
}
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
const result = this.l.slice(this.c, this.c + size);
|
|
687
|
-
this.c += size;
|
|
688
|
-
return result;
|
|
689
|
-
}
|
|
690
|
-
// Zero-copy variant of decodeBytes: a view into the stream, only valid until
|
|
691
|
-
// the caller's next chance to mutate the buffer — copy out before keeping it.
|
|
742
|
+
// A view into the stream (no copy), only valid until the caller's next
|
|
743
|
+
// chance to mutate the buffer — copy out before keeping it.
|
|
692
744
|
decodeBytesView(size) {
|
|
693
|
-
if (this.
|
|
694
|
-
const result = this.
|
|
695
|
-
this.
|
|
745
|
+
if (this.d + size > this.I) return void 0;
|
|
746
|
+
const result = this.n.subarray(this.d, this.d + size);
|
|
747
|
+
this.d += size;
|
|
696
748
|
return result;
|
|
697
749
|
}
|
|
698
750
|
// Only the 2.2+ layout (varint size prefix): older bitstreams are rejected
|
|
@@ -704,80 +756,39 @@ var DecoderBuffer = class {
|
|
|
704
756
|
if (size === void 0) return void 0;
|
|
705
757
|
outSize = size;
|
|
706
758
|
}
|
|
707
|
-
this.
|
|
708
|
-
this.
|
|
759
|
+
this.Ga = true;
|
|
760
|
+
this.la.reset(this.n.subarray(this.d), this.I - this.d);
|
|
709
761
|
return outSize;
|
|
710
762
|
}
|
|
711
763
|
endBitDecoding() {
|
|
712
|
-
this.
|
|
713
|
-
this.
|
|
764
|
+
this.Ga = false;
|
|
765
|
+
this.d += Math.ceil(this.la.o / 8);
|
|
714
766
|
}
|
|
715
767
|
decodeLeastSignificantBits32(nbits) {
|
|
716
|
-
if (!this.
|
|
717
|
-
return this.
|
|
768
|
+
if (!this.Ga) return void 0;
|
|
769
|
+
return this.la.getBits(nbits);
|
|
718
770
|
}
|
|
719
771
|
advance(bytes) {
|
|
720
|
-
this.
|
|
772
|
+
this.d += bytes;
|
|
721
773
|
}
|
|
722
774
|
get data() {
|
|
723
|
-
return this.
|
|
775
|
+
return this.n;
|
|
724
776
|
}
|
|
725
777
|
get dataHead() {
|
|
726
|
-
return this.
|
|
778
|
+
return this.n.subarray(this.d);
|
|
727
779
|
}
|
|
728
780
|
get remainingSize() {
|
|
729
|
-
return this.
|
|
781
|
+
return this.I - this.d;
|
|
730
782
|
}
|
|
731
783
|
get decodedSize() {
|
|
732
|
-
return this.
|
|
784
|
+
return this.d;
|
|
733
785
|
}
|
|
734
786
|
get bitDecoderActive() {
|
|
735
|
-
return this.
|
|
787
|
+
return this.Ga;
|
|
736
788
|
}
|
|
737
789
|
};
|
|
738
790
|
|
|
739
791
|
// src/decoder/compression/config/CompressionShared.ts
|
|
740
|
-
var EncodedGeometryType = {
|
|
741
|
-
POINT_CLOUD: 0,
|
|
742
|
-
TRIANGULAR_MESH: 1
|
|
743
|
-
};
|
|
744
|
-
var MeshEncoderMethod = {
|
|
745
|
-
MESH_SEQUENTIAL_ENCODING: 0,
|
|
746
|
-
MESH_EDGEBREAKER_ENCODING: 1
|
|
747
|
-
};
|
|
748
|
-
var SequentialAttributeEncoderType = {
|
|
749
|
-
SEQUENTIAL_ATTRIBUTE_ENCODER_GENERIC: 0,
|
|
750
|
-
SEQUENTIAL_ATTRIBUTE_ENCODER_INTEGER: 1,
|
|
751
|
-
SEQUENTIAL_ATTRIBUTE_ENCODER_QUANTIZATION: 2,
|
|
752
|
-
SEQUENTIAL_ATTRIBUTE_ENCODER_NORMALS: 3
|
|
753
|
-
};
|
|
754
|
-
var PredictionSchemeMethod = {
|
|
755
|
-
PREDICTION_NONE: -2,
|
|
756
|
-
MESH_PREDICTION_PARALLELOGRAM: 1,
|
|
757
|
-
MESH_PREDICTION_MULTI_PARALLELOGRAM: 2,
|
|
758
|
-
MESH_PREDICTION_CONSTRAINED_MULTI_PARALLELOGRAM: 4,
|
|
759
|
-
MESH_PREDICTION_TEX_COORDS_PORTABLE: 5,
|
|
760
|
-
MESH_PREDICTION_GEOMETRIC_NORMAL: 6,
|
|
761
|
-
NUM_PREDICTION_SCHEMES: 7
|
|
762
|
-
};
|
|
763
|
-
var PredictionSchemeTransformType = {
|
|
764
|
-
PREDICTION_TRANSFORM_NONE: -1,
|
|
765
|
-
PREDICTION_TRANSFORM_WRAP: 1,
|
|
766
|
-
PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON: 2,
|
|
767
|
-
PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON_CANONICALIZED: 3,
|
|
768
|
-
NUM_PREDICTION_SCHEME_TRANSFORM_TYPES: 4
|
|
769
|
-
};
|
|
770
|
-
var MeshTraversalMethod = {
|
|
771
|
-
MESH_TRAVERSAL_DEPTH_FIRST: 0,
|
|
772
|
-
MESH_TRAVERSAL_PREDICTION_DEGREE: 1,
|
|
773
|
-
NUM_TRAVERSAL_METHODS: 2
|
|
774
|
-
};
|
|
775
|
-
var MeshEdgebreakerConnectivityEncodingMethod = {
|
|
776
|
-
MESH_EDGEBREAKER_STANDARD_ENCODING: 0,
|
|
777
|
-
MESH_EDGEBREAKER_PREDICTIVE_ENCODING: 1,
|
|
778
|
-
// Deprecated.
|
|
779
|
-
MESH_EDGEBREAKER_VALENCE_ENCODING: 2
|
|
780
|
-
};
|
|
781
792
|
var DracoHeader = class {
|
|
782
793
|
versionMajor = 0;
|
|
783
794
|
versionMinor = 0;
|
|
@@ -785,76 +796,72 @@ var DracoHeader = class {
|
|
|
785
796
|
encoderMethod = 0;
|
|
786
797
|
flags = 0;
|
|
787
798
|
};
|
|
788
|
-
var SymbolCodingMethod = {
|
|
789
|
-
SYMBOL_CODING_TAGGED: 0,
|
|
790
|
-
SYMBOL_CODING_RAW: 1
|
|
791
|
-
};
|
|
792
799
|
var METADATA_FLAG_MASK = 32768;
|
|
793
800
|
|
|
794
801
|
// src/decoder/metadata/MetadataDecoder.ts
|
|
795
802
|
var kMaxSubmetadataLevel = 1e3;
|
|
796
803
|
var MetadataDecoder = class {
|
|
797
804
|
constructor(buffer_) {
|
|
798
|
-
this.
|
|
805
|
+
this.C = buffer_;
|
|
799
806
|
}
|
|
800
807
|
buffer_;
|
|
801
808
|
// Skips per-attribute metadata followed by the geometry-level metadata.
|
|
802
809
|
skipGeometryMetadata() {
|
|
803
|
-
const numAttMetadata = decodeVarint(this.
|
|
810
|
+
const numAttMetadata = decodeVarint(this.C);
|
|
804
811
|
if (numAttMetadata === void 0) {
|
|
805
812
|
return false;
|
|
806
813
|
}
|
|
807
814
|
for (let i = 0; i < numAttMetadata; ++i) {
|
|
808
|
-
if (decodeVarint(this.
|
|
815
|
+
if (decodeVarint(this.C) === void 0) {
|
|
809
816
|
return false;
|
|
810
817
|
}
|
|
811
|
-
if (!this.
|
|
818
|
+
if (!this.Ua(0)) {
|
|
812
819
|
return false;
|
|
813
820
|
}
|
|
814
821
|
}
|
|
815
|
-
return this.
|
|
822
|
+
return this.Ua(0);
|
|
816
823
|
}
|
|
817
824
|
// Discards one metadata block (key-value entries plus nested sub-metadata).
|
|
818
825
|
// Sub-blocks read depth-first in stream order, matching the C++ stack traversal.
|
|
819
|
-
|
|
826
|
+
Ua(level) {
|
|
820
827
|
if (level > kMaxSubmetadataLevel) {
|
|
821
828
|
return false;
|
|
822
829
|
}
|
|
823
|
-
const numEntries = decodeVarint(this.
|
|
830
|
+
const numEntries = decodeVarint(this.C);
|
|
824
831
|
if (numEntries === void 0) {
|
|
825
832
|
return false;
|
|
826
833
|
}
|
|
827
834
|
for (let i = 0; i < numEntries; ++i) {
|
|
828
|
-
const nameSkipped = this.
|
|
829
|
-
const dataSize = nameSkipped ? decodeVarint(this.
|
|
830
|
-
if (dataSize === void 0 || dataSize === 0 || !this.
|
|
835
|
+
const nameSkipped = this.tb();
|
|
836
|
+
const dataSize = nameSkipped ? decodeVarint(this.C) : void 0;
|
|
837
|
+
if (dataSize === void 0 || dataSize === 0 || !this.ub(dataSize)) {
|
|
831
838
|
return false;
|
|
832
839
|
}
|
|
833
840
|
}
|
|
834
|
-
const numSubMetadata = decodeVarint(this.
|
|
835
|
-
if (numSubMetadata === void 0 || numSubMetadata > this.
|
|
841
|
+
const numSubMetadata = decodeVarint(this.C);
|
|
842
|
+
if (numSubMetadata === void 0 || numSubMetadata > this.C.remainingSize) {
|
|
836
843
|
return false;
|
|
837
844
|
}
|
|
838
845
|
for (let i = 0; i < numSubMetadata; ++i) {
|
|
839
|
-
if (!this.
|
|
846
|
+
if (!this.tb() || !this.Ua(level + 1)) {
|
|
840
847
|
return false;
|
|
841
848
|
}
|
|
842
849
|
}
|
|
843
850
|
return true;
|
|
844
851
|
}
|
|
845
852
|
// Skips a name (uint8 length prefix followed by that many bytes).
|
|
846
|
-
|
|
847
|
-
const nameLen = this.
|
|
853
|
+
tb() {
|
|
854
|
+
const nameLen = this.C.decodeUint8();
|
|
848
855
|
if (nameLen === void 0) {
|
|
849
856
|
return false;
|
|
850
857
|
}
|
|
851
|
-
return this.
|
|
858
|
+
return this.ub(nameLen);
|
|
852
859
|
}
|
|
853
|
-
|
|
854
|
-
if (size > this.
|
|
860
|
+
ub(size) {
|
|
861
|
+
if (size > this.C.remainingSize) {
|
|
855
862
|
return false;
|
|
856
863
|
}
|
|
857
|
-
this.
|
|
864
|
+
this.C.advance(size);
|
|
858
865
|
return true;
|
|
859
866
|
}
|
|
860
867
|
};
|
|
@@ -924,12 +931,13 @@ var RAnsDecoder = class {
|
|
|
924
931
|
// flat
|
|
925
932
|
cumProbTable = null;
|
|
926
933
|
// flat
|
|
927
|
-
//
|
|
934
|
+
// Coarse mode (see ransBuildLookUpTable): no full-precision lut; a
|
|
928
935
|
// 256-entry bucket table narrows each lookup to a symbol range that a short
|
|
929
936
|
// cumProb scan finishes. cumProbTable then carries one extra trailing entry
|
|
930
937
|
// (== ransPrecision) so the scan needs no bounds check.
|
|
931
938
|
coarse = false;
|
|
932
939
|
bucketShift = 0;
|
|
940
|
+
// Uint16 unless the alphabet needs wider ids, so real streams keep one table type.
|
|
933
941
|
bucketTable = null;
|
|
934
942
|
// Stream state inlined (not a nested AnsDecoder) so the ransRead() hot loop
|
|
935
943
|
// touches own props; initialized by ansReadInit.
|
|
@@ -989,47 +997,14 @@ var RAnsDecoder = class {
|
|
|
989
997
|
}
|
|
990
998
|
// Batch ransRead() into out[0..count): all fields hoisted to locals, state
|
|
991
999
|
// written back once. Removes per-symbol property reads and call indirection.
|
|
992
|
-
// lutTable's element type varies per decoder (Uint8/16/32 by symbol count),
|
|
993
|
-
// which would make the hot lutTable[rem] access site polymorphic — dispatch
|
|
994
|
-
// once here so each loop body stays monomorphic on its concrete type. The
|
|
995
|
-
// three bodies are intentionally identical copies.
|
|
996
1000
|
decodeSymbols(out, count) {
|
|
997
1001
|
if (this.coarse) {
|
|
998
|
-
this.
|
|
1002
|
+
this.Vb(out, count);
|
|
999
1003
|
return;
|
|
1000
1004
|
}
|
|
1001
|
-
|
|
1002
|
-
if (lutTable instanceof Uint8Array) {
|
|
1003
|
-
this.Bb(out, count, lutTable);
|
|
1004
|
-
} else if (lutTable instanceof Uint16Array) {
|
|
1005
|
-
this.Cb(out, count, lutTable);
|
|
1006
|
-
} else {
|
|
1007
|
-
this.Db(out, count, lutTable);
|
|
1008
|
-
}
|
|
1009
|
-
}
|
|
1010
|
-
Bb(out, count, lutTable) {
|
|
1011
|
-
const buf = this.buf;
|
|
1012
|
-
const lRansBase = this.lRansBase;
|
|
1013
|
-
const ransPrecisionBits = this.ransPrecisionBits;
|
|
1014
|
-
const ransPrecisionMask = this.ransPrecisionMask;
|
|
1015
|
-
const probTable = this.probTable;
|
|
1016
|
-
const cumProbTable = this.cumProbTable;
|
|
1017
|
-
let state = this.state;
|
|
1018
|
-
let bufOffset = this.bufOffset;
|
|
1019
|
-
const bufStart = this.bufStart;
|
|
1020
|
-
for (let i = 0; i < count; ++i) {
|
|
1021
|
-
while (state < lRansBase && bufOffset > bufStart) {
|
|
1022
|
-
state = state << 8 | buf[--bufOffset];
|
|
1023
|
-
}
|
|
1024
|
-
const rem = state & ransPrecisionMask;
|
|
1025
|
-
const symbol = lutTable[rem];
|
|
1026
|
-
out[i] = symbol;
|
|
1027
|
-
state = (state >>> ransPrecisionBits) * probTable[symbol] + rem - cumProbTable[symbol];
|
|
1028
|
-
}
|
|
1029
|
-
this.state = state;
|
|
1030
|
-
this.bufOffset = bufOffset;
|
|
1005
|
+
this.Wb(out, count, this.lutTable);
|
|
1031
1006
|
}
|
|
1032
|
-
|
|
1007
|
+
Wb(out, count, lutTable) {
|
|
1033
1008
|
const buf = this.buf;
|
|
1034
1009
|
const lRansBase = this.lRansBase;
|
|
1035
1010
|
const ransPrecisionBits = this.ransPrecisionBits;
|
|
@@ -1053,7 +1028,7 @@ var RAnsDecoder = class {
|
|
|
1053
1028
|
}
|
|
1054
1029
|
// Short-stream loop: bucket table + cumProb scan instead of the full lut.
|
|
1055
1030
|
// Same state arithmetic as the lut loops, so the output is identical.
|
|
1056
|
-
|
|
1031
|
+
Vb(out, count) {
|
|
1057
1032
|
const buf = this.buf;
|
|
1058
1033
|
const lRansBase = this.lRansBase;
|
|
1059
1034
|
const ransPrecisionBits = this.ransPrecisionBits;
|
|
@@ -1078,28 +1053,6 @@ var RAnsDecoder = class {
|
|
|
1078
1053
|
this.state = state;
|
|
1079
1054
|
this.bufOffset = bufOffset;
|
|
1080
1055
|
}
|
|
1081
|
-
Db(out, count, lutTable) {
|
|
1082
|
-
const buf = this.buf;
|
|
1083
|
-
const lRansBase = this.lRansBase;
|
|
1084
|
-
const ransPrecisionBits = this.ransPrecisionBits;
|
|
1085
|
-
const ransPrecisionMask = this.ransPrecisionMask;
|
|
1086
|
-
const probTable = this.probTable;
|
|
1087
|
-
const cumProbTable = this.cumProbTable;
|
|
1088
|
-
let state = this.state;
|
|
1089
|
-
let bufOffset = this.bufOffset;
|
|
1090
|
-
const bufStart = this.bufStart;
|
|
1091
|
-
for (let i = 0; i < count; ++i) {
|
|
1092
|
-
while (state < lRansBase && bufOffset > bufStart) {
|
|
1093
|
-
state = state << 8 | buf[--bufOffset];
|
|
1094
|
-
}
|
|
1095
|
-
const rem = state & ransPrecisionMask;
|
|
1096
|
-
const symbol = lutTable[rem];
|
|
1097
|
-
out[i] = symbol;
|
|
1098
|
-
state = (state >>> ransPrecisionBits) * probTable[symbol] + rem - cumProbTable[symbol];
|
|
1099
|
-
}
|
|
1100
|
-
this.state = state;
|
|
1101
|
-
this.bufOffset = bufOffset;
|
|
1102
|
-
}
|
|
1103
1056
|
// Builds the decoding tables. Returns false on bad input data.
|
|
1104
1057
|
//
|
|
1105
1058
|
// expectedCount is how many symbols the caller will decode from this stream.
|
|
@@ -1109,10 +1062,13 @@ var RAnsDecoder = class {
|
|
|
1109
1062
|
// get a coarse 256-entry bucket table (symbol at the start of each
|
|
1110
1063
|
// precision/256-wide bucket) and finish each lookup with a scan of the
|
|
1111
1064
|
// cumulative probabilities; long streams keep the exact lut, whose per-symbol
|
|
1112
|
-
// cost is lower.
|
|
1065
|
+
// cost is lower. The coarse tables also serve an alphabet wider than a
|
|
1066
|
+
// Uint16 lut entry (raw symbol coding allows 2^18 symbols; no real file
|
|
1067
|
+
// has been seen past 2^14), rather than keeping a Uint32 copy of every
|
|
1068
|
+
// lut loop for it.
|
|
1113
1069
|
ransBuildLookUpTable(tokenProbs, numSymbols, expectedCount = 2147483647) {
|
|
1114
1070
|
const ransPrecision = this.ransPrecision;
|
|
1115
|
-
const coarse = numSymbols
|
|
1071
|
+
const coarse = numSymbols > 65536 || expectedCount * COARSE_STREAM_FACTOR < ransPrecision;
|
|
1116
1072
|
this.coarse = coarse;
|
|
1117
1073
|
const probTable = acquirePooled(Uint32Array, numSymbols);
|
|
1118
1074
|
const cumProbTable = acquirePooled(Uint32Array, numSymbols + 1);
|
|
@@ -1135,7 +1091,7 @@ var RAnsDecoder = class {
|
|
|
1135
1091
|
}
|
|
1136
1092
|
cumProbTable[numSymbols] = ransPrecision;
|
|
1137
1093
|
const bucketShift = this.ransPrecisionBits - COARSE_BUCKET_BITS;
|
|
1138
|
-
const bucketTable = acquirePooled(Uint16Array, 1 << COARSE_BUCKET_BITS);
|
|
1094
|
+
const bucketTable = numSymbols > 65536 ? acquirePooled(Uint32Array, 1 << COARSE_BUCKET_BITS) : acquirePooled(Uint16Array, 1 << COARSE_BUCKET_BITS);
|
|
1139
1095
|
this.bucketShift = bucketShift;
|
|
1140
1096
|
this.bucketTable = bucketTable;
|
|
1141
1097
|
let symbol = 0;
|
|
@@ -1146,8 +1102,7 @@ var RAnsDecoder = class {
|
|
|
1146
1102
|
}
|
|
1147
1103
|
return true;
|
|
1148
1104
|
}
|
|
1149
|
-
const
|
|
1150
|
-
const lutTable = acquirePooled(LutArray, ransPrecision);
|
|
1105
|
+
const lutTable = acquirePooled(Uint16Array, ransPrecision);
|
|
1151
1106
|
this.lutTable = lutTable;
|
|
1152
1107
|
let actProb = 0;
|
|
1153
1108
|
for (let i = 0; i < numSymbols; ++i) {
|
|
@@ -1174,66 +1129,9 @@ var RAnsDecoder = class {
|
|
|
1174
1129
|
return true;
|
|
1175
1130
|
}
|
|
1176
1131
|
};
|
|
1177
|
-
function ransDecodeSymbolsPairU8(a, outA, countA, b, outB, countB) {
|
|
1178
|
-
const lutA = a.lutTable;
|
|
1179
|
-
const lutB = b.lutTable;
|
|
1180
|
-
const bufA = a.buf;
|
|
1181
|
-
const bufB = b.buf;
|
|
1182
|
-
const probA = a.probTable;
|
|
1183
|
-
const probB = b.probTable;
|
|
1184
|
-
const cumA = a.cumProbTable;
|
|
1185
|
-
const cumB = b.cumProbTable;
|
|
1186
|
-
const lBaseA = a.lRansBase;
|
|
1187
|
-
const lBaseB = b.lRansBase;
|
|
1188
|
-
const bitsA = a.ransPrecisionBits;
|
|
1189
|
-
const bitsB = b.ransPrecisionBits;
|
|
1190
|
-
const maskA = a.ransPrecisionMask;
|
|
1191
|
-
const maskB = b.ransPrecisionMask;
|
|
1192
|
-
const startA = a.bufStart;
|
|
1193
|
-
const startB = b.bufStart;
|
|
1194
|
-
let stateA = a.state;
|
|
1195
|
-
let stateB = b.state;
|
|
1196
|
-
let offA = a.bufOffset;
|
|
1197
|
-
let offB = b.bufOffset;
|
|
1198
|
-
const shared = countA < countB ? countA : countB;
|
|
1199
|
-
for (let i = 0; i < shared; ++i) {
|
|
1200
|
-
while (stateA < lBaseA && offA > startA) {
|
|
1201
|
-
stateA = stateA << 8 | bufA[--offA];
|
|
1202
|
-
}
|
|
1203
|
-
while (stateB < lBaseB && offB > startB) {
|
|
1204
|
-
stateB = stateB << 8 | bufB[--offB];
|
|
1205
|
-
}
|
|
1206
|
-
const remA = stateA & maskA;
|
|
1207
|
-
const remB = stateB & maskB;
|
|
1208
|
-
const symA = lutA[remA];
|
|
1209
|
-
const symB = lutB[remB];
|
|
1210
|
-
outA[i] = symA;
|
|
1211
|
-
outB[i] = symB;
|
|
1212
|
-
stateA = (stateA >>> bitsA) * probA[symA] + remA - cumA[symA];
|
|
1213
|
-
stateB = (stateB >>> bitsB) * probB[symB] + remB - cumB[symB];
|
|
1214
|
-
}
|
|
1215
|
-
a.state = stateA;
|
|
1216
|
-
a.bufOffset = offA;
|
|
1217
|
-
b.state = stateB;
|
|
1218
|
-
b.bufOffset = offB;
|
|
1219
|
-
if (shared < countA) {
|
|
1220
|
-
a.decodeSymbols(outA.subarray(shared), countA - shared);
|
|
1221
|
-
}
|
|
1222
|
-
if (shared < countB) {
|
|
1223
|
-
b.decodeSymbols(outB.subarray(shared), countB - shared);
|
|
1224
|
-
}
|
|
1225
|
-
}
|
|
1226
1132
|
function ransDecodeSymbolsPair(a, outA, countA, b, outB, countB) {
|
|
1227
|
-
|
|
1228
|
-
const lutB = b.lutTable;
|
|
1229
|
-
if (lutA instanceof Uint8Array && lutB instanceof Uint8Array) {
|
|
1230
|
-
ransDecodeSymbolsPairU8(a, outA, countA, b, outB, countB);
|
|
1231
|
-
} else if (lutA instanceof Uint16Array && lutB instanceof Uint16Array) {
|
|
1133
|
+
if (!a.coarse && !b.coarse) {
|
|
1232
1134
|
ransDecodeSymbolsPairU16(a, outA, countA, b, outB, countB);
|
|
1233
|
-
} else if (lutA instanceof Uint8Array && lutB instanceof Uint16Array) {
|
|
1234
|
-
ransDecodeSymbolsPairU8U16(a, outA, countA, b, outB, countB);
|
|
1235
|
-
} else if (lutA instanceof Uint16Array && lutB instanceof Uint8Array) {
|
|
1236
|
-
ransDecodeSymbolsPairU8U16(b, outB, countB, a, outA, countA);
|
|
1237
1135
|
} else {
|
|
1238
1136
|
a.decodeSymbols(outA, countA);
|
|
1239
1137
|
b.decodeSymbols(outB, countB);
|
|
@@ -1288,56 +1186,7 @@ function ransDecodeSymbolsPairU16(a, outA, countA, b, outB, countB) {
|
|
|
1288
1186
|
b.decodeSymbols(outB.subarray(shared), countB - shared);
|
|
1289
1187
|
}
|
|
1290
1188
|
}
|
|
1291
|
-
function
|
|
1292
|
-
const lutA = a.lutTable;
|
|
1293
|
-
const lutB = b.lutTable;
|
|
1294
|
-
const bufA = a.buf;
|
|
1295
|
-
const bufB = b.buf;
|
|
1296
|
-
const probA = a.probTable;
|
|
1297
|
-
const probB = b.probTable;
|
|
1298
|
-
const cumA = a.cumProbTable;
|
|
1299
|
-
const cumB = b.cumProbTable;
|
|
1300
|
-
const lBaseA = a.lRansBase;
|
|
1301
|
-
const lBaseB = b.lRansBase;
|
|
1302
|
-
const bitsA = a.ransPrecisionBits;
|
|
1303
|
-
const bitsB = b.ransPrecisionBits;
|
|
1304
|
-
const maskA = a.ransPrecisionMask;
|
|
1305
|
-
const maskB = b.ransPrecisionMask;
|
|
1306
|
-
const startA = a.bufStart;
|
|
1307
|
-
const startB = b.bufStart;
|
|
1308
|
-
let stateA = a.state;
|
|
1309
|
-
let stateB = b.state;
|
|
1310
|
-
let offA = a.bufOffset;
|
|
1311
|
-
let offB = b.bufOffset;
|
|
1312
|
-
const shared = countA < countB ? countA : countB;
|
|
1313
|
-
for (let i = 0; i < shared; ++i) {
|
|
1314
|
-
while (stateA < lBaseA && offA > startA) {
|
|
1315
|
-
stateA = stateA << 8 | bufA[--offA];
|
|
1316
|
-
}
|
|
1317
|
-
while (stateB < lBaseB && offB > startB) {
|
|
1318
|
-
stateB = stateB << 8 | bufB[--offB];
|
|
1319
|
-
}
|
|
1320
|
-
const remA = stateA & maskA;
|
|
1321
|
-
const remB = stateB & maskB;
|
|
1322
|
-
const symA = lutA[remA];
|
|
1323
|
-
const symB = lutB[remB];
|
|
1324
|
-
outA[i] = symA;
|
|
1325
|
-
outB[i] = symB;
|
|
1326
|
-
stateA = (stateA >>> bitsA) * probA[symA] + remA - cumA[symA];
|
|
1327
|
-
stateB = (stateB >>> bitsB) * probB[symB] + remB - cumB[symB];
|
|
1328
|
-
}
|
|
1329
|
-
a.state = stateA;
|
|
1330
|
-
a.bufOffset = offA;
|
|
1331
|
-
b.state = stateB;
|
|
1332
|
-
b.bufOffset = offB;
|
|
1333
|
-
if (shared < countA) {
|
|
1334
|
-
a.decodeSymbols(outA.subarray(shared), countA - shared);
|
|
1335
|
-
}
|
|
1336
|
-
if (shared < countB) {
|
|
1337
|
-
b.decodeSymbols(outB.subarray(shared), countB - shared);
|
|
1338
|
-
}
|
|
1339
|
-
}
|
|
1340
|
-
function ransDecodeSymbolsTrioU8(a, outA, countA, b, outB, countB, c, outC, countC) {
|
|
1189
|
+
function ransDecodeSymbolsTrioU16(a, outA, countA, b, outB, countB, c, outC, countC) {
|
|
1341
1190
|
const lutA = a.lutTable;
|
|
1342
1191
|
const lutB = b.lutTable;
|
|
1343
1192
|
const lutC = c.lutTable;
|
|
@@ -1407,7 +1256,7 @@ function ransDecodeSymbolsTrioU8(a, outA, countA, b, outB, countB, c, outC, coun
|
|
|
1407
1256
|
if (restB > 0) tails.push([b, outB.subarray(shared), restB]);
|
|
1408
1257
|
if (restC > 0) tails.push([c, outC.subarray(shared), restC]);
|
|
1409
1258
|
if (tails.length === 2) {
|
|
1410
|
-
|
|
1259
|
+
ransDecodeSymbolsPairU16(tails[0][0], tails[0][1], tails[0][2], tails[1][0], tails[1][1], tails[1][2]);
|
|
1411
1260
|
} else {
|
|
1412
1261
|
for (const [decoder, out, count] of tails) {
|
|
1413
1262
|
decoder.decodeSymbols(out, count);
|
|
@@ -1417,14 +1266,14 @@ function ransDecodeSymbolsTrioU8(a, outA, countA, b, outB, countB, c, outC, coun
|
|
|
1417
1266
|
|
|
1418
1267
|
// src/decoder/compression/point_cloud/PointCloudDecoder.ts
|
|
1419
1268
|
var PointCloudDecoder = class {
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1269
|
+
O = null;
|
|
1270
|
+
c = null;
|
|
1271
|
+
s = [];
|
|
1272
|
+
Ha = [];
|
|
1424
1273
|
// Returns an error message, or '' on success (outHeader is then populated).
|
|
1425
1274
|
static decodeHeader(buffer, outHeader) {
|
|
1426
1275
|
const kIoErrorMsg = "Failed to parse Draco header.";
|
|
1427
|
-
const bytes = buffer.
|
|
1276
|
+
const bytes = buffer.decodeBytesView(5);
|
|
1428
1277
|
if (bytes === void 0) {
|
|
1429
1278
|
return kIoErrorMsg;
|
|
1430
1279
|
}
|
|
@@ -1449,12 +1298,12 @@ var PointCloudDecoder = class {
|
|
|
1449
1298
|
}
|
|
1450
1299
|
// Main entry point, given the already-parsed header (see Decode.ts).
|
|
1451
1300
|
decode(header, inBuffer, outPointCloud) {
|
|
1452
|
-
this.
|
|
1453
|
-
this.
|
|
1301
|
+
this.c = inBuffer;
|
|
1302
|
+
this.O = outPointCloud;
|
|
1454
1303
|
if (header.versionMajor !== 2 || header.versionMinor !== 2) {
|
|
1455
1304
|
return "Unsupported bitstream version (Draco 2.2 meshes only).";
|
|
1456
1305
|
}
|
|
1457
|
-
if (header.flags & METADATA_FLAG_MASK && !new MetadataDecoder(this.
|
|
1306
|
+
if (header.flags & METADATA_FLAG_MASK && !new MetadataDecoder(this.c).skipGeometryMetadata()) {
|
|
1458
1307
|
return "Failed to decode metadata.";
|
|
1459
1308
|
}
|
|
1460
1309
|
if (!this.initializeDecoder()) {
|
|
@@ -1472,30 +1321,30 @@ var PointCloudDecoder = class {
|
|
|
1472
1321
|
if (attDecoderId < 0) {
|
|
1473
1322
|
return false;
|
|
1474
1323
|
}
|
|
1475
|
-
while (this.
|
|
1476
|
-
this.
|
|
1324
|
+
while (this.s.length <= attDecoderId) {
|
|
1325
|
+
this.s.push(null);
|
|
1477
1326
|
}
|
|
1478
|
-
this.
|
|
1327
|
+
this.s[attDecoderId] = decoder;
|
|
1479
1328
|
return true;
|
|
1480
1329
|
}
|
|
1481
1330
|
getPortableAttribute(parentAttId) {
|
|
1482
|
-
if (parentAttId < 0 || parentAttId >= this.
|
|
1331
|
+
if (parentAttId < 0 || parentAttId >= this.O.numAttributes()) {
|
|
1483
1332
|
return null;
|
|
1484
1333
|
}
|
|
1485
|
-
const parentAttDecoderId = this.
|
|
1486
|
-
return this.
|
|
1334
|
+
const parentAttDecoderId = this.Ha[parentAttId];
|
|
1335
|
+
return this.s[parentAttDecoderId].getPortableAttribute(parentAttId);
|
|
1487
1336
|
}
|
|
1488
1337
|
attributesDecoder(decId) {
|
|
1489
|
-
return this.
|
|
1338
|
+
return this.s[decId];
|
|
1490
1339
|
}
|
|
1491
1340
|
numAttributesDecoders() {
|
|
1492
|
-
return this.
|
|
1341
|
+
return this.s.length;
|
|
1493
1342
|
}
|
|
1494
1343
|
pointCloud() {
|
|
1495
|
-
return this.
|
|
1344
|
+
return this.O;
|
|
1496
1345
|
}
|
|
1497
1346
|
buffer() {
|
|
1498
|
-
return this.
|
|
1347
|
+
return this.c;
|
|
1499
1348
|
}
|
|
1500
1349
|
// -- Protected virtual methods (override in subclasses) --
|
|
1501
1350
|
initializeDecoder() {
|
|
@@ -1509,7 +1358,7 @@ var PointCloudDecoder = class {
|
|
|
1509
1358
|
return true;
|
|
1510
1359
|
}
|
|
1511
1360
|
decodePointAttributes() {
|
|
1512
|
-
const numAttributesDecoders = this.
|
|
1361
|
+
const numAttributesDecoders = this.c.decodeUint8();
|
|
1513
1362
|
if (numAttributesDecoders === void 0) {
|
|
1514
1363
|
return false;
|
|
1515
1364
|
}
|
|
@@ -1518,32 +1367,32 @@ var PointCloudDecoder = class {
|
|
|
1518
1367
|
return false;
|
|
1519
1368
|
}
|
|
1520
1369
|
}
|
|
1521
|
-
for (let i = 0; i < this.
|
|
1522
|
-
if (!this.
|
|
1370
|
+
for (let i = 0; i < this.s.length; ++i) {
|
|
1371
|
+
if (!this.s[i].init(this, this.O)) {
|
|
1523
1372
|
return false;
|
|
1524
1373
|
}
|
|
1525
1374
|
}
|
|
1526
1375
|
for (let i = 0; i < numAttributesDecoders; ++i) {
|
|
1527
|
-
if (!this.
|
|
1376
|
+
if (!this.s[i].decodeAttributesDecoderData(this.c)) {
|
|
1528
1377
|
return false;
|
|
1529
1378
|
}
|
|
1530
1379
|
}
|
|
1531
1380
|
for (let i = 0; i < numAttributesDecoders; ++i) {
|
|
1532
|
-
const numAttributes = this.
|
|
1381
|
+
const numAttributes = this.s[i].getNumAttributes();
|
|
1533
1382
|
for (let j = 0; j < numAttributes; ++j) {
|
|
1534
|
-
const attId = this.
|
|
1535
|
-
while (this.
|
|
1536
|
-
this.
|
|
1383
|
+
const attId = this.s[i].getAttributeId(j);
|
|
1384
|
+
while (this.Ha.length <= attId) {
|
|
1385
|
+
this.Ha.push(0);
|
|
1537
1386
|
}
|
|
1538
|
-
this.
|
|
1387
|
+
this.Ha[attId] = i;
|
|
1539
1388
|
}
|
|
1540
1389
|
}
|
|
1541
1390
|
return this.decodeAllAttributes();
|
|
1542
1391
|
}
|
|
1543
1392
|
decodeAllAttributes() {
|
|
1544
|
-
const decoders = this.
|
|
1393
|
+
const decoders = this.s;
|
|
1545
1394
|
for (let i2 = 0; i2 < decoders.length; i2++) {
|
|
1546
|
-
if (!decoders[i2].decodeAttributesParse(this.
|
|
1395
|
+
if (!decoders[i2].decodeAttributesParse(this.c)) {
|
|
1547
1396
|
return false;
|
|
1548
1397
|
}
|
|
1549
1398
|
}
|
|
@@ -1575,10 +1424,10 @@ var PointCloudDecoder = class {
|
|
|
1575
1424
|
|
|
1576
1425
|
// src/decoder/compression/mesh/MeshDecoder.ts
|
|
1577
1426
|
var MeshDecoder = class extends PointCloudDecoder {
|
|
1578
|
-
|
|
1427
|
+
D = null;
|
|
1579
1428
|
// Returns an error message, or '' on success.
|
|
1580
1429
|
decodeMesh(header, inBuffer, outMesh) {
|
|
1581
|
-
this.
|
|
1430
|
+
this.D = outMesh;
|
|
1582
1431
|
return this.decode(header, inBuffer, outMesh);
|
|
1583
1432
|
}
|
|
1584
1433
|
// Connectivity accessors used by the mesh prediction schemes; the sequential
|
|
@@ -1593,7 +1442,7 @@ var MeshDecoder = class extends PointCloudDecoder {
|
|
|
1593
1442
|
return null;
|
|
1594
1443
|
}
|
|
1595
1444
|
mesh() {
|
|
1596
|
-
return this.
|
|
1445
|
+
return this.D;
|
|
1597
1446
|
}
|
|
1598
1447
|
decodeGeometryData() {
|
|
1599
1448
|
return this.decodeConnectivity() && super.decodeGeometryData();
|
|
@@ -1604,60 +1453,60 @@ var MeshDecoder = class extends PointCloudDecoder {
|
|
|
1604
1453
|
var kInvalidCornerIndex = -1;
|
|
1605
1454
|
var kInvalidVertexIndex = -1;
|
|
1606
1455
|
var MeshAttributeCornerTable = class {
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1456
|
+
Y = [];
|
|
1457
|
+
ma = [];
|
|
1458
|
+
Z = [];
|
|
1459
|
+
na = [];
|
|
1611
1460
|
// Attribute-vertex count. C++ keeps a vertex -> attribute-entry map here, but
|
|
1612
1461
|
// the decoder only ever reads its size, so track the count directly instead
|
|
1613
1462
|
// of allocating an Int32Array per attribute corner table.
|
|
1614
|
-
|
|
1615
|
-
|
|
1463
|
+
oa = 0;
|
|
1464
|
+
t = null;
|
|
1616
1465
|
// Lazily built; see oppositeCornerArray.
|
|
1617
|
-
|
|
1466
|
+
P = null;
|
|
1618
1467
|
// Every corner passed to addSeamEdge (may contain duplicates); lets
|
|
1619
1468
|
// oppositeCornerArray patch seams without scanning every corner's flag.
|
|
1620
1469
|
// Preallocated to its exact upper bound (2 per seam edge) by the caller via
|
|
1621
1470
|
// reserveSeamEdges -- a plain array grown by push() was measurable on
|
|
1622
1471
|
// seam-heavy files.
|
|
1623
|
-
|
|
1624
|
-
|
|
1472
|
+
_ = [];
|
|
1473
|
+
Q = 0;
|
|
1625
1474
|
initEmpty(table) {
|
|
1626
1475
|
if (table === null) {
|
|
1627
1476
|
return false;
|
|
1628
1477
|
}
|
|
1629
|
-
this.
|
|
1630
|
-
this.
|
|
1631
|
-
this.
|
|
1632
|
-
this.
|
|
1633
|
-
this.
|
|
1634
|
-
this.
|
|
1635
|
-
this.
|
|
1636
|
-
this.
|
|
1637
|
-
this.
|
|
1478
|
+
this.Y = scratchUint8Zeroed(table.numCorners());
|
|
1479
|
+
this.ma = scratchUint8Zeroed(table.numVertices());
|
|
1480
|
+
this.Z = scratchInt32Filled(table.numCorners(), kInvalidVertexIndex);
|
|
1481
|
+
this.oa = 0;
|
|
1482
|
+
this.na = [];
|
|
1483
|
+
this.P = null;
|
|
1484
|
+
this._ = [];
|
|
1485
|
+
this.Q = 0;
|
|
1486
|
+
this.t = table;
|
|
1638
1487
|
return true;
|
|
1639
1488
|
}
|
|
1640
1489
|
// Sizes the seam-corner list for numSeamEdges upcoming addSeamEdge calls
|
|
1641
1490
|
// (each adds at most two corners). Decode-scoped scratch.
|
|
1642
1491
|
reserveSeamEdges(numSeamEdges) {
|
|
1643
|
-
this.
|
|
1644
|
-
this.
|
|
1492
|
+
this._ = scratchInt32(numSeamEdges * 2);
|
|
1493
|
+
this.Q = 0;
|
|
1645
1494
|
}
|
|
1646
1495
|
addSeamEdge(c) {
|
|
1647
|
-
const cornerToVertex = this.
|
|
1648
|
-
const oppositeCorners = this.
|
|
1649
|
-
const isEdge = this.
|
|
1650
|
-
const isVert = this.
|
|
1651
|
-
const seamCorners = this.
|
|
1496
|
+
const cornerToVertex = this.t.cornerToVertexArray();
|
|
1497
|
+
const oppositeCorners = this.t.oppositeCornerArray();
|
|
1498
|
+
const isEdge = this.Y;
|
|
1499
|
+
const isVert = this.ma;
|
|
1500
|
+
const seamCorners = this._;
|
|
1652
1501
|
isEdge[c] = 1;
|
|
1653
|
-
seamCorners[this.
|
|
1502
|
+
seamCorners[this.Q++] = c;
|
|
1654
1503
|
let rem = c - (c / 3 | 0) * 3;
|
|
1655
1504
|
isVert[cornerToVertex[rem === 2 ? c - 2 : c + 1]] = 1;
|
|
1656
1505
|
isVert[cornerToVertex[rem === 0 ? c + 2 : c - 1]] = 1;
|
|
1657
1506
|
const oppCorner = oppositeCorners[c];
|
|
1658
1507
|
if (oppCorner !== kInvalidCornerIndex) {
|
|
1659
1508
|
isEdge[oppCorner] = 1;
|
|
1660
|
-
seamCorners[this.
|
|
1509
|
+
seamCorners[this.Q++] = oppCorner;
|
|
1661
1510
|
rem = oppCorner - (oppCorner / 3 | 0) * 3;
|
|
1662
1511
|
isVert[cornerToVertex[rem === 2 ? oppCorner - 2 : oppCorner + 1]] = 1;
|
|
1663
1512
|
isVert[cornerToVertex[rem === 0 ? oppCorner + 2 : oppCorner - 1]] = 1;
|
|
@@ -1668,23 +1517,23 @@ var MeshAttributeCornerTable = class {
|
|
|
1668
1517
|
// over the per-vertex left-most corners here). leftMostMap is decode-scoped
|
|
1669
1518
|
// scratch sized for at least numNewVertices entries.
|
|
1670
1519
|
setRecomputedVertices(leftMostMap, numNewVertices) {
|
|
1671
|
-
this.
|
|
1672
|
-
this.
|
|
1520
|
+
this.oa = numNewVertices;
|
|
1521
|
+
this.na = leftMostMap.length === numNewVertices ? leftMostMap : leftMostMap.subarray(0, numNewVertices);
|
|
1673
1522
|
}
|
|
1674
1523
|
isCornerOppositeToSeamEdge(corner) {
|
|
1675
|
-
return this.
|
|
1524
|
+
return this.Y[corner];
|
|
1676
1525
|
}
|
|
1677
1526
|
opposite(corner) {
|
|
1678
1527
|
if (corner === kInvalidCornerIndex || this.isCornerOppositeToSeamEdge(corner)) {
|
|
1679
1528
|
return kInvalidCornerIndex;
|
|
1680
1529
|
}
|
|
1681
|
-
return this.
|
|
1530
|
+
return this.t.opposite(corner);
|
|
1682
1531
|
}
|
|
1683
1532
|
next(corner) {
|
|
1684
|
-
return this.
|
|
1533
|
+
return this.t.next(corner);
|
|
1685
1534
|
}
|
|
1686
1535
|
previous(corner) {
|
|
1687
|
-
return this.
|
|
1536
|
+
return this.t.previous(corner);
|
|
1688
1537
|
}
|
|
1689
1538
|
swingRight(corner) {
|
|
1690
1539
|
return this.previous(this.opposite(this.previous(corner)));
|
|
@@ -1693,68 +1542,68 @@ var MeshAttributeCornerTable = class {
|
|
|
1693
1542
|
return this.next(this.opposite(this.next(corner)));
|
|
1694
1543
|
}
|
|
1695
1544
|
numVertices() {
|
|
1696
|
-
return this.
|
|
1545
|
+
return this.oa;
|
|
1697
1546
|
}
|
|
1698
1547
|
numFaces() {
|
|
1699
|
-
return this.
|
|
1548
|
+
return this.t.numFaces();
|
|
1700
1549
|
}
|
|
1701
1550
|
numCorners() {
|
|
1702
|
-
return this.
|
|
1551
|
+
return this.t.numCorners();
|
|
1703
1552
|
}
|
|
1704
1553
|
// --- Flat-array accessors: let DepthFirstTraverser avoid per-corner dispatch. ---
|
|
1705
1554
|
cornerToVertexArray() {
|
|
1706
|
-
return this.
|
|
1555
|
+
return this.Z;
|
|
1707
1556
|
}
|
|
1708
1557
|
// Seam-aware opposite corners (seam edges -> -1), matching opposite(). Cached on
|
|
1709
1558
|
// first use; seams and connectivity are finalized before traversal, so it's stable.
|
|
1710
1559
|
oppositeCornerArray() {
|
|
1711
|
-
if (this.
|
|
1712
|
-
const nc = this.
|
|
1713
|
-
const base = this.
|
|
1714
|
-
const seamCorners = this.
|
|
1715
|
-
const numSeamCorners = this.
|
|
1560
|
+
if (this.P === null) {
|
|
1561
|
+
const nc = this.t.numCorners();
|
|
1562
|
+
const base = this.t.oppositeCornerArray();
|
|
1563
|
+
const seamCorners = this._;
|
|
1564
|
+
const numSeamCorners = this.Q;
|
|
1716
1565
|
if (numSeamCorners === 0) {
|
|
1717
|
-
this.
|
|
1566
|
+
this.P = base;
|
|
1718
1567
|
} else {
|
|
1719
1568
|
const eff = scratchInt32(nc);
|
|
1720
1569
|
eff.set(base.length === nc ? base : base.subarray(0, nc));
|
|
1721
1570
|
for (let i = 0; i < numSeamCorners; ++i) {
|
|
1722
1571
|
eff[seamCorners[i]] = kInvalidCornerIndex;
|
|
1723
1572
|
}
|
|
1724
|
-
this.
|
|
1573
|
+
this.P = eff;
|
|
1725
1574
|
}
|
|
1726
1575
|
}
|
|
1727
|
-
return this.
|
|
1576
|
+
return this.P;
|
|
1728
1577
|
}
|
|
1729
1578
|
vertexLeftmostCornerArray() {
|
|
1730
|
-
return this.
|
|
1579
|
+
return this.na;
|
|
1731
1580
|
}
|
|
1732
1581
|
// Takes over another table's state wholesale. Only valid when both tables
|
|
1733
1582
|
// were built from the same corner table and the same seam edges, in which
|
|
1734
1583
|
// case every one of these is identical and read-only from here on.
|
|
1735
1584
|
adoptFrom(other) {
|
|
1736
|
-
this.
|
|
1737
|
-
this.
|
|
1738
|
-
this.
|
|
1739
|
-
this.
|
|
1740
|
-
this.
|
|
1741
|
-
this.
|
|
1742
|
-
this.
|
|
1743
|
-
this.
|
|
1744
|
-
this.
|
|
1585
|
+
this.t = other.t;
|
|
1586
|
+
this.Y = other.Y;
|
|
1587
|
+
this.ma = other.ma;
|
|
1588
|
+
this.Z = other.Z;
|
|
1589
|
+
this.oa = other.oa;
|
|
1590
|
+
this.na = other.na;
|
|
1591
|
+
this.P = other.P;
|
|
1592
|
+
this._ = other._;
|
|
1593
|
+
this.Q = other.Q;
|
|
1745
1594
|
}
|
|
1746
1595
|
};
|
|
1747
1596
|
|
|
1748
1597
|
// src/decoder/compression/attributes/AttributesDecoder.ts
|
|
1749
1598
|
var AttributesDecoder = class {
|
|
1750
|
-
|
|
1599
|
+
Ia = [];
|
|
1751
1600
|
// Inverse of _pointAttributeIds: point attribute id -> local id.
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1601
|
+
pa = [];
|
|
1602
|
+
vb = null;
|
|
1603
|
+
O = null;
|
|
1755
1604
|
init(decoder, pointCloud) {
|
|
1756
|
-
this.
|
|
1757
|
-
this.
|
|
1605
|
+
this.vb = decoder;
|
|
1606
|
+
this.O = pointCloud;
|
|
1758
1607
|
return true;
|
|
1759
1608
|
}
|
|
1760
1609
|
decodeAttributesDecoderData(buffer) {
|
|
@@ -1762,8 +1611,8 @@ var AttributesDecoder = class {
|
|
|
1762
1611
|
if (numAttributes === void 0 || numAttributes === 0 || numAttributes > 5 * buffer.remainingSize) {
|
|
1763
1612
|
return false;
|
|
1764
1613
|
}
|
|
1765
|
-
this.
|
|
1766
|
-
const pc = this.
|
|
1614
|
+
this.Ia.length = numAttributes;
|
|
1615
|
+
const pc = this.O;
|
|
1767
1616
|
for (let i = 0; i < numAttributes; i++) {
|
|
1768
1617
|
const attType = buffer.decodeUint8();
|
|
1769
1618
|
if (attType === void 0) return false;
|
|
@@ -1776,7 +1625,7 @@ var AttributesDecoder = class {
|
|
|
1776
1625
|
if (attType >= Type.NAMED_ATTRIBUTES_COUNT) {
|
|
1777
1626
|
return false;
|
|
1778
1627
|
}
|
|
1779
|
-
if (dataType ===
|
|
1628
|
+
if (dataType === 0 /* INVALID */ || dataType >= 12 /* TYPES_COUNT */) {
|
|
1780
1629
|
return false;
|
|
1781
1630
|
}
|
|
1782
1631
|
if (numComponents === 0) {
|
|
@@ -1789,42 +1638,42 @@ var AttributesDecoder = class {
|
|
|
1789
1638
|
ga.uniqueId = uniqueId;
|
|
1790
1639
|
const attId = pc.addAttribute(new PointAttribute(ga));
|
|
1791
1640
|
pc.attribute(attId).uniqueId = uniqueId;
|
|
1792
|
-
this.
|
|
1793
|
-
while (this.
|
|
1794
|
-
this.
|
|
1641
|
+
this.Ia[i] = attId;
|
|
1642
|
+
while (this.pa.length <= attId) {
|
|
1643
|
+
this.pa.push(-1);
|
|
1795
1644
|
}
|
|
1796
|
-
this.
|
|
1645
|
+
this.pa[attId] = i;
|
|
1797
1646
|
}
|
|
1798
1647
|
return true;
|
|
1799
1648
|
}
|
|
1800
1649
|
getAttributeId(i) {
|
|
1801
|
-
return this.
|
|
1650
|
+
return this.Ia[i];
|
|
1802
1651
|
}
|
|
1803
1652
|
getNumAttributes() {
|
|
1804
|
-
return this.
|
|
1653
|
+
return this.Ia.length;
|
|
1805
1654
|
}
|
|
1806
1655
|
getDecoder() {
|
|
1807
|
-
return this.
|
|
1656
|
+
return this.vb;
|
|
1808
1657
|
}
|
|
1809
1658
|
getLocalIdForPointAttribute(pointAttributeId) {
|
|
1810
|
-
if (pointAttributeId >= this.
|
|
1659
|
+
if (pointAttributeId >= this.pa.length) {
|
|
1811
1660
|
return -1;
|
|
1812
1661
|
}
|
|
1813
|
-
return this.
|
|
1662
|
+
return this.pa[pointAttributeId];
|
|
1814
1663
|
}
|
|
1815
1664
|
};
|
|
1816
1665
|
|
|
1817
1666
|
// src/decoder/compression/attributes/SequentialAttributeDecoder.ts
|
|
1818
1667
|
var SequentialAttributeDecoder = class {
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1668
|
+
l = null;
|
|
1669
|
+
E = null;
|
|
1670
|
+
wb = -1;
|
|
1822
1671
|
// Decoded portable attribute (after lossless decoding).
|
|
1823
|
-
|
|
1672
|
+
$ = null;
|
|
1824
1673
|
init(decoder, attributeId) {
|
|
1825
|
-
this.
|
|
1826
|
-
this.
|
|
1827
|
-
this.
|
|
1674
|
+
this.l = decoder;
|
|
1675
|
+
this.E = decoder.pointCloud().attribute(attributeId);
|
|
1676
|
+
this.wb = attributeId;
|
|
1828
1677
|
return true;
|
|
1829
1678
|
}
|
|
1830
1679
|
// --- Two-phase decode ---
|
|
@@ -1835,14 +1684,20 @@ var SequentialAttributeDecoder = class {
|
|
|
1835
1684
|
// stream simply do the whole decode in Parse (decodeValues); the defaults
|
|
1836
1685
|
// below are theirs.
|
|
1837
1686
|
decodePortableAttributeParse(pointIds, buffer) {
|
|
1838
|
-
if (this.
|
|
1687
|
+
if (this.E.numComponents <= 0) {
|
|
1839
1688
|
return false;
|
|
1840
1689
|
}
|
|
1841
|
-
if (!this.
|
|
1690
|
+
if (!this.xb(pointIds.length)) {
|
|
1842
1691
|
return false;
|
|
1843
1692
|
}
|
|
1844
1693
|
return this.decodeValues(pointIds, buffer);
|
|
1845
1694
|
}
|
|
1695
|
+
// Sizes (and here allocates) the attribute's storage for numValues values;
|
|
1696
|
+
// the integer decoders override it to skip the allocation, their values
|
|
1697
|
+
// staying in the portable attribute (see PointAttribute.setLazyInteger).
|
|
1698
|
+
xb(numValues) {
|
|
1699
|
+
return this.E.reset(numValues);
|
|
1700
|
+
}
|
|
1846
1701
|
pendingSymbolStream() {
|
|
1847
1702
|
return null;
|
|
1848
1703
|
}
|
|
@@ -1858,35 +1713,35 @@ var SequentialAttributeDecoder = class {
|
|
|
1858
1713
|
return true;
|
|
1859
1714
|
}
|
|
1860
1715
|
getPortableAttribute() {
|
|
1861
|
-
if (!this.
|
|
1862
|
-
const size = this.
|
|
1863
|
-
this
|
|
1864
|
-
const src = this.
|
|
1865
|
-
const dst = this
|
|
1716
|
+
if (!this.E.isMappingIdentity && this.$ && this.$.isMappingIdentity) {
|
|
1717
|
+
const size = this.E.indicesMapSize;
|
|
1718
|
+
this.$.setExplicitMappingScratch(size);
|
|
1719
|
+
const src = this.E.indicesMap;
|
|
1720
|
+
const dst = this.$.indicesMap;
|
|
1866
1721
|
if (src.length === size) {
|
|
1867
1722
|
dst.set(src);
|
|
1868
1723
|
} else {
|
|
1869
1724
|
dst.set(src.subarray(0, size));
|
|
1870
1725
|
}
|
|
1871
1726
|
}
|
|
1872
|
-
return this
|
|
1727
|
+
return this.$;
|
|
1873
1728
|
}
|
|
1874
1729
|
get attribute() {
|
|
1875
|
-
return this.
|
|
1730
|
+
return this.E;
|
|
1876
1731
|
}
|
|
1877
1732
|
get attributeId() {
|
|
1878
|
-
return this.
|
|
1733
|
+
return this.wb;
|
|
1879
1734
|
}
|
|
1880
1735
|
get decoder() {
|
|
1881
|
-
return this.
|
|
1736
|
+
return this.l;
|
|
1882
1737
|
}
|
|
1883
1738
|
initPredictionScheme(ps) {
|
|
1884
1739
|
for (let i = 0; i < ps.getNumParentAttributes(); i++) {
|
|
1885
|
-
const attId = this.
|
|
1740
|
+
const attId = this.l.pointCloud().getNamedAttributeId(ps.getParentAttributeType(i));
|
|
1886
1741
|
if (attId === -1) {
|
|
1887
1742
|
return false;
|
|
1888
1743
|
}
|
|
1889
|
-
const pa = this.
|
|
1744
|
+
const pa = this.l.getPortableAttribute(attId);
|
|
1890
1745
|
if (pa === null || !ps.setParentAttribute(pa)) {
|
|
1891
1746
|
return false;
|
|
1892
1747
|
}
|
|
@@ -1896,13 +1751,13 @@ var SequentialAttributeDecoder = class {
|
|
|
1896
1751
|
// Decodes raw attribute values in their original format.
|
|
1897
1752
|
decodeValues(pointIds, buffer) {
|
|
1898
1753
|
const numValues = pointIds.length;
|
|
1899
|
-
const entrySize = this.
|
|
1754
|
+
const entrySize = this.E.byteStride;
|
|
1900
1755
|
const totalSize = numValues * entrySize;
|
|
1901
1756
|
const valueData = buffer.decodeBytesView(totalSize);
|
|
1902
1757
|
if (valueData === void 0) {
|
|
1903
1758
|
return false;
|
|
1904
1759
|
}
|
|
1905
|
-
this.
|
|
1760
|
+
this.E.buffer.write(0, valueData, totalSize);
|
|
1906
1761
|
return true;
|
|
1907
1762
|
}
|
|
1908
1763
|
};
|
|
@@ -1917,14 +1772,14 @@ function convertSymbolsToSignedInts(input, count, output) {
|
|
|
1917
1772
|
|
|
1918
1773
|
// src/decoder/compression/entropy/RAnsSymbolDecoder.ts
|
|
1919
1774
|
var RAnsSymbolDecoder = class {
|
|
1920
|
-
|
|
1921
|
-
|
|
1775
|
+
yb = 0;
|
|
1776
|
+
m;
|
|
1922
1777
|
constructor(uniqueSymbolsBitLength) {
|
|
1923
1778
|
const unclamped = Math.trunc(3 * uniqueSymbolsBitLength / 2);
|
|
1924
|
-
this.
|
|
1779
|
+
this.m = new RAnsDecoder(unclamped < 12 ? 12 : unclamped > 20 ? 20 : unclamped);
|
|
1925
1780
|
}
|
|
1926
1781
|
get numSymbols() {
|
|
1927
|
-
return this.
|
|
1782
|
+
return this.yb;
|
|
1928
1783
|
}
|
|
1929
1784
|
// Initialize the decoder and decode the probability table. expectedCount is
|
|
1930
1785
|
// the number of symbols the caller will decode (lets short streams skip the
|
|
@@ -1932,7 +1787,7 @@ var RAnsSymbolDecoder = class {
|
|
|
1932
1787
|
create(buffer, expectedCount = 2147483647) {
|
|
1933
1788
|
const numSymbols = decodeVarint(buffer);
|
|
1934
1789
|
if (numSymbols === void 0) return false;
|
|
1935
|
-
this.
|
|
1790
|
+
this.yb = numSymbols;
|
|
1936
1791
|
if (Math.trunc(numSymbols / 64) > buffer.remainingSize) {
|
|
1937
1792
|
return false;
|
|
1938
1793
|
}
|
|
@@ -1965,7 +1820,7 @@ var RAnsSymbolDecoder = class {
|
|
|
1965
1820
|
}
|
|
1966
1821
|
}
|
|
1967
1822
|
buffer.advance(pos - startPos);
|
|
1968
|
-
return this.
|
|
1823
|
+
return this.m.ransBuildLookUpTable(probabilityTable, numSymbols, expectedCount);
|
|
1969
1824
|
}
|
|
1970
1825
|
// Starts decoding, advancing buffer past the encoded data.
|
|
1971
1826
|
startDecoding(buffer) {
|
|
@@ -1976,10 +1831,10 @@ var RAnsSymbolDecoder = class {
|
|
|
1976
1831
|
}
|
|
1977
1832
|
const base = buffer.decodedSize;
|
|
1978
1833
|
buffer.advance(Number(bytesEncoded));
|
|
1979
|
-
return ansReadInit(this.
|
|
1834
|
+
return ansReadInit(this.m, buffer.data, base + Number(bytesEncoded), base, this.m.lRansBase, 4);
|
|
1980
1835
|
}
|
|
1981
1836
|
endDecoding() {
|
|
1982
|
-
this.
|
|
1837
|
+
this.m.readEnd();
|
|
1983
1838
|
}
|
|
1984
1839
|
};
|
|
1985
1840
|
|
|
@@ -1989,9 +1844,9 @@ function decodeSymbols(numValues, numComponents, srcBuffer, outValues) {
|
|
|
1989
1844
|
return true;
|
|
1990
1845
|
}
|
|
1991
1846
|
const scheme = srcBuffer.decodeUint8();
|
|
1992
|
-
if (scheme ===
|
|
1847
|
+
if (scheme === 0 /* SYMBOL_CODING_TAGGED */) {
|
|
1993
1848
|
return decodeTaggedSymbols(numValues, numComponents, srcBuffer, outValues);
|
|
1994
|
-
} else if (scheme ===
|
|
1849
|
+
} else if (scheme === 1 /* SYMBOL_CODING_RAW */) {
|
|
1995
1850
|
return decodeRawSymbols(numValues, srcBuffer, outValues);
|
|
1996
1851
|
}
|
|
1997
1852
|
return false;
|
|
@@ -2007,11 +1862,11 @@ function decodeTaggedSymbols(numValues, numComponents, srcBuffer, outValues) {
|
|
|
2007
1862
|
if (numValues > 0 && tagDecoder.numSymbols === 0) {
|
|
2008
1863
|
return false;
|
|
2009
1864
|
}
|
|
2010
|
-
const tagAns = tagDecoder.
|
|
1865
|
+
const tagAns = tagDecoder.m;
|
|
2011
1866
|
srcBuffer.startBitDecoding(false);
|
|
2012
|
-
const bd = srcBuffer.
|
|
2013
|
-
const buf = bd.
|
|
2014
|
-
const byteLength = bd.
|
|
1867
|
+
const bd = srcBuffer.la;
|
|
1868
|
+
const buf = bd.Ea;
|
|
1869
|
+
const byteLength = bd.ka;
|
|
2015
1870
|
let bitOffset = bd.o;
|
|
2016
1871
|
let valueId = 0;
|
|
2017
1872
|
for (let i = 0; i < numValues; i += numComponents) {
|
|
@@ -2079,15 +1934,15 @@ function decodeRawSymbols(numValues, srcBuffer, outValues) {
|
|
|
2079
1934
|
if (decoder === null) {
|
|
2080
1935
|
return false;
|
|
2081
1936
|
}
|
|
2082
|
-
decoder.
|
|
1937
|
+
decoder.m.decodeSymbols(outValues, numValues);
|
|
2083
1938
|
decoder.endDecoding();
|
|
2084
1939
|
return true;
|
|
2085
1940
|
}
|
|
2086
1941
|
|
|
2087
1942
|
// src/decoder/compression/bit_coders/RAnsBitDecoder.ts
|
|
2088
1943
|
var RAnsBitDecoder = class {
|
|
2089
|
-
|
|
2090
|
-
|
|
1944
|
+
Va = new AnsDecoder();
|
|
1945
|
+
Wa = 0;
|
|
2091
1946
|
// ANS_P8_PRECISION - probZero, precomputed
|
|
2092
1947
|
// Returns false when the data is invalid.
|
|
2093
1948
|
startDecoding(sourceBuffer) {
|
|
@@ -2095,21 +1950,21 @@ var RAnsBitDecoder = class {
|
|
|
2095
1950
|
if (probZero === void 0) {
|
|
2096
1951
|
return false;
|
|
2097
1952
|
}
|
|
2098
|
-
this.
|
|
1953
|
+
this.Wa = ANS_P8_PRECISION - probZero;
|
|
2099
1954
|
const sizeInBytes = decodeVarint(sourceBuffer);
|
|
2100
1955
|
if (sizeInBytes === void 0 || sizeInBytes > sourceBuffer.remainingSize) {
|
|
2101
1956
|
return false;
|
|
2102
1957
|
}
|
|
2103
1958
|
const base = sourceBuffer.decodedSize;
|
|
2104
|
-
if (!ansReadInit(this.
|
|
1959
|
+
if (!ansReadInit(this.Va, sourceBuffer.data, base + sizeInBytes, base, ANS_L_BASE, 3)) {
|
|
2105
1960
|
return false;
|
|
2106
1961
|
}
|
|
2107
1962
|
sourceBuffer.advance(sizeInBytes);
|
|
2108
1963
|
return true;
|
|
2109
1964
|
}
|
|
2110
1965
|
decodeNextBit() {
|
|
2111
|
-
const ans = this.
|
|
2112
|
-
const p = this.
|
|
1966
|
+
const ans = this.Va;
|
|
1967
|
+
const p = this.Wa;
|
|
2113
1968
|
if (ans.state < ANS_L_BASE && ans.bufOffset > ans.bufStart) {
|
|
2114
1969
|
ans.state = ans.state << 8 | ans.buf[--ans.bufOffset];
|
|
2115
1970
|
}
|
|
@@ -2205,18 +2060,18 @@ var MAX_NUM_PARALLELOGRAMS = 4;
|
|
|
2205
2060
|
var MeshPredictionSchemeConstrainedMultiParallelogramDecoder = class extends MeshPredictionSchemeDecoder {
|
|
2206
2061
|
// Crease edges stored per context (number of available parallelograms),
|
|
2207
2062
|
// one list per context up to MAX_NUM_PARALLELOGRAMS.
|
|
2208
|
-
|
|
2063
|
+
Ja = [[], [], [], []];
|
|
2209
2064
|
decodePredictionData(buffer) {
|
|
2210
2065
|
for (let i = 0; i < MAX_NUM_PARALLELOGRAMS; ++i) {
|
|
2211
2066
|
const numFlags = decodeVarint(buffer);
|
|
2212
2067
|
if (numFlags === void 0) return false;
|
|
2213
2068
|
if (numFlags > this.b.cornerTable.numCorners()) return false;
|
|
2214
2069
|
if (numFlags > 0) {
|
|
2215
|
-
this.
|
|
2070
|
+
this.Ja[i] = new Array(numFlags);
|
|
2216
2071
|
const decoder = new RAnsBitDecoder();
|
|
2217
2072
|
if (!decoder.startDecoding(buffer)) return false;
|
|
2218
2073
|
for (let j = 0; j < numFlags; ++j) {
|
|
2219
|
-
this.
|
|
2074
|
+
this.Ja[i][j] = decoder.decodeNextBit();
|
|
2220
2075
|
}
|
|
2221
2076
|
decoder.endDecoding();
|
|
2222
2077
|
}
|
|
@@ -2275,8 +2130,8 @@ var MeshPredictionSchemeConstrainedMultiParallelogramDecoder = class extends Mes
|
|
|
2275
2130
|
for (let i = 0; i < numParallelograms; ++i) {
|
|
2276
2131
|
const context = numParallelograms - 1;
|
|
2277
2132
|
const pos = isCreaseEdgePos[context]++;
|
|
2278
|
-
if (this.
|
|
2279
|
-
const isCrease = this.
|
|
2133
|
+
if (this.Ja[context].length <= pos) return false;
|
|
2134
|
+
const isCrease = this.Ja[context][pos];
|
|
2280
2135
|
if (!isCrease) {
|
|
2281
2136
|
++numUsedParallelograms;
|
|
2282
2137
|
for (let j = 0; j < numComponents; ++j) {
|
|
@@ -2314,23 +2169,23 @@ var MeshPredictionSchemeData = class {
|
|
|
2314
2169
|
|
|
2315
2170
|
// src/decoder/compression/attributes/NormalCompressionUtils.ts
|
|
2316
2171
|
var OctahedronToolBox = class {
|
|
2317
|
-
|
|
2318
|
-
|
|
2172
|
+
J = -1;
|
|
2173
|
+
qa = -1;
|
|
2319
2174
|
k = -1;
|
|
2320
|
-
|
|
2175
|
+
Xb = 1;
|
|
2321
2176
|
e = -1;
|
|
2322
2177
|
// q: quantization bits, valid range 2..30.
|
|
2323
2178
|
setQuantizationBits(q) {
|
|
2324
2179
|
if (q < 2 || q > 30) return false;
|
|
2325
|
-
this.
|
|
2326
|
-
this.
|
|
2327
|
-
this.k = this.
|
|
2328
|
-
this.
|
|
2180
|
+
this.J = q;
|
|
2181
|
+
this.qa = (1 << q) - 1;
|
|
2182
|
+
this.k = this.qa - 1;
|
|
2183
|
+
this.Xb = Math.fround(2 / Math.fround(this.k));
|
|
2329
2184
|
this.e = this.k / 2 | 0;
|
|
2330
2185
|
return true;
|
|
2331
2186
|
}
|
|
2332
2187
|
quantizationBits() {
|
|
2333
|
-
return this.
|
|
2188
|
+
return this.J;
|
|
2334
2189
|
}
|
|
2335
2190
|
// Canonicalizes edge points into consistent quadrants. Writes result into
|
|
2336
2191
|
// out[0], out[1] (caller-owned reusable 2-element array).
|
|
@@ -2387,14 +2242,14 @@ var OctahedronToolBox = class {
|
|
|
2387
2242
|
}
|
|
2388
2243
|
}
|
|
2389
2244
|
// The octahedral -> unit vector direction (quantizedOctahedralCoordsToUnitVector
|
|
2390
|
-
// in the source) lives inlined in
|
|
2245
|
+
// in the source) lives inlined in PointAttribute._extractOctahedron.
|
|
2391
2246
|
};
|
|
2392
2247
|
|
|
2393
2248
|
// src/decoder/compression/attributes/prediction_schemes/MeshPredictionSchemeGeometricNormalPredictorArea.ts
|
|
2394
2249
|
var UPPER_BOUND = 1 << 29;
|
|
2395
2250
|
function fillInt32PositionCache(cache, att, map, numEntries, tempPos) {
|
|
2396
2251
|
const bufData = att.buffer && att.buffer.data;
|
|
2397
|
-
if (att.dataType ===
|
|
2252
|
+
if (att.dataType === 5 /* INT32 */ && att.numComponents === 3 && bufData) {
|
|
2398
2253
|
const src = new Int32Array(bufData.buffer);
|
|
2399
2254
|
const srcStart = bufData.byteOffset + att.byteOffset >> 2;
|
|
2400
2255
|
const stride = att.byteStride >> 2;
|
|
@@ -2428,31 +2283,31 @@ function fillInt32PositionCache(cache, att, map, numEntries, tempPos) {
|
|
|
2428
2283
|
}
|
|
2429
2284
|
}
|
|
2430
2285
|
var MeshPredictionSchemeGeometricNormalPredictorArea = class {
|
|
2431
|
-
|
|
2432
|
-
|
|
2286
|
+
ra = null;
|
|
2287
|
+
sa = null;
|
|
2433
2288
|
b;
|
|
2434
|
-
|
|
2435
|
-
|
|
2289
|
+
Xa = new Array(3);
|
|
2290
|
+
ta = null;
|
|
2436
2291
|
// flat Int32 positions, indexed by data id
|
|
2437
|
-
|
|
2438
|
-
|
|
2292
|
+
p = null;
|
|
2293
|
+
zb = null;
|
|
2439
2294
|
// corner -> posCache offset, precomputed
|
|
2440
2295
|
constructor(meshData) {
|
|
2441
2296
|
this.b = meshData;
|
|
2442
2297
|
}
|
|
2443
2298
|
setPositionAttribute(positionAttribute) {
|
|
2444
|
-
this.
|
|
2299
|
+
this.ra = positionAttribute;
|
|
2445
2300
|
}
|
|
2446
2301
|
setEntryToPointIdMap(map) {
|
|
2447
|
-
this.
|
|
2302
|
+
this.sa = map;
|
|
2448
2303
|
}
|
|
2449
2304
|
buildPositionCache(numEntries) {
|
|
2450
2305
|
const posCache = scratchInt32(numEntries * 3);
|
|
2451
|
-
fillInt32PositionCache(posCache, this.
|
|
2452
|
-
this.
|
|
2306
|
+
fillInt32PositionCache(posCache, this.ra, this.sa, numEntries, this.Xa);
|
|
2307
|
+
this.ta = posCache;
|
|
2453
2308
|
const table = this.b.cornerTable;
|
|
2454
2309
|
const cornerToVertex = table.cornerToVertexArray();
|
|
2455
|
-
this.
|
|
2310
|
+
this.p = table.oppositeCornerArray();
|
|
2456
2311
|
const vertexToDataMap = this.b.vertexToDataMap;
|
|
2457
2312
|
const nc = cornerToVertex.length;
|
|
2458
2313
|
const c2o = scratchInt32(nc);
|
|
@@ -2460,12 +2315,12 @@ var MeshPredictionSchemeGeometricNormalPredictorArea = class {
|
|
|
2460
2315
|
const v = cornerToVertex[c];
|
|
2461
2316
|
c2o[c] = v < 0 ? -1 : vertexToDataMap[v] * 3;
|
|
2462
2317
|
}
|
|
2463
|
-
this.
|
|
2318
|
+
this.zb = c2o;
|
|
2464
2319
|
}
|
|
2465
2320
|
computePredictedValue(cornerId, prediction) {
|
|
2466
|
-
const oppositeCorners = this.
|
|
2467
|
-
const cornerToOffset = this.
|
|
2468
|
-
const posCache = this.
|
|
2321
|
+
const oppositeCorners = this.p;
|
|
2322
|
+
const cornerToOffset = this.zb;
|
|
2323
|
+
const posCache = this.ta;
|
|
2469
2324
|
const centerOffset = cornerToOffset[cornerId];
|
|
2470
2325
|
const centX = posCache[centerOffset];
|
|
2471
2326
|
const centY = posCache[centerOffset + 1];
|
|
@@ -2542,12 +2397,12 @@ var MeshPredictionSchemeGeometricNormalPredictorArea = class {
|
|
|
2542
2397
|
// src/decoder/compression/attributes/prediction_schemes/MeshPredictionSchemeGeometricNormalDecoder.ts
|
|
2543
2398
|
var GEOMETRY_ATTRIBUTE_POSITION = 0;
|
|
2544
2399
|
var MeshPredictionSchemeGeometricNormalDecoder = class extends MeshPredictionSchemeDecoder {
|
|
2545
|
-
|
|
2400
|
+
q;
|
|
2546
2401
|
y = new OctahedronToolBox();
|
|
2547
|
-
|
|
2402
|
+
Ya = new RAnsBitDecoder();
|
|
2548
2403
|
constructor(transform, meshData) {
|
|
2549
2404
|
super(transform, meshData);
|
|
2550
|
-
this.
|
|
2405
|
+
this.q = new MeshPredictionSchemeGeometricNormalPredictorArea(meshData);
|
|
2551
2406
|
}
|
|
2552
2407
|
getNumParentAttributes() {
|
|
2553
2408
|
return 1;
|
|
@@ -2558,25 +2413,25 @@ var MeshPredictionSchemeGeometricNormalDecoder = class extends MeshPredictionSch
|
|
|
2558
2413
|
setParentAttribute(att) {
|
|
2559
2414
|
if (att.attributeType !== GEOMETRY_ATTRIBUTE_POSITION) return false;
|
|
2560
2415
|
if (att.numComponents !== 3) return false;
|
|
2561
|
-
this.
|
|
2416
|
+
this.q.setPositionAttribute(att);
|
|
2562
2417
|
return true;
|
|
2563
2418
|
}
|
|
2564
2419
|
decodePredictionData(buffer) {
|
|
2565
2420
|
if (!this.f.decodeTransformData(buffer)) return false;
|
|
2566
|
-
return this.
|
|
2421
|
+
return this.Ya.startDecoding(buffer);
|
|
2567
2422
|
}
|
|
2568
2423
|
computeOriginalValues(inCorr, outData, _size, _numComponents, entryToPointIdMap) {
|
|
2569
2424
|
this.y.setQuantizationBits(this.f.quantizationBits());
|
|
2570
|
-
this.
|
|
2425
|
+
this.q.setEntryToPointIdMap(entryToPointIdMap);
|
|
2571
2426
|
const cornerMapSize = this.b.dataToCornerMap.length;
|
|
2572
|
-
this.
|
|
2427
|
+
this.q.buildPositionCache(cornerMapSize);
|
|
2573
2428
|
const predNormal3D = new Int32Array(3);
|
|
2574
2429
|
const predNormalOct = new Int32Array(2);
|
|
2575
2430
|
for (let dataId = 0; dataId < cornerMapSize; ++dataId) {
|
|
2576
2431
|
const cornerId = this.b.dataToCornerMap[dataId];
|
|
2577
|
-
this.
|
|
2432
|
+
this.q.computePredictedValue(cornerId, predNormal3D);
|
|
2578
2433
|
this.y.canonicalizeIntegerVector(predNormal3D);
|
|
2579
|
-
if (this.
|
|
2434
|
+
if (this.Ya.decodeNextBit()) {
|
|
2580
2435
|
predNormal3D[0] = -predNormal3D[0];
|
|
2581
2436
|
predNormal3D[1] = -predNormal3D[1];
|
|
2582
2437
|
predNormal3D[2] = -predNormal3D[2];
|
|
@@ -2585,7 +2440,7 @@ var MeshPredictionSchemeGeometricNormalDecoder = class extends MeshPredictionSch
|
|
|
2585
2440
|
const dataOffset = dataId * 2;
|
|
2586
2441
|
this.f.computeOriginalValue(predNormalOct, 0, inCorr, dataOffset, outData, dataOffset);
|
|
2587
2442
|
}
|
|
2588
|
-
this.
|
|
2443
|
+
this.Ya.endDecoding();
|
|
2589
2444
|
return true;
|
|
2590
2445
|
}
|
|
2591
2446
|
};
|
|
@@ -2652,7 +2507,7 @@ var MeshPredictionSchemeParallelogramDecoder = class extends MeshPredictionSchem
|
|
|
2652
2507
|
// zigzag form, unpacking each one inline.
|
|
2653
2508
|
computeOriginalValuesZigzag(inCorr, outData, _size, numComponents, _entryToPointIdMap) {
|
|
2654
2509
|
this.f.init(numComponents);
|
|
2655
|
-
return this.
|
|
2510
|
+
return this.Yb(inCorr, outData, numComponents, true);
|
|
2656
2511
|
}
|
|
2657
2512
|
// The wrap transform's corrections are zigzag-coded; with `zigzag` set the
|
|
2658
2513
|
// decode folds the (val >>> 1) ^ -(val & 1) unpacking into each correction
|
|
@@ -2660,15 +2515,15 @@ var MeshPredictionSchemeParallelogramDecoder = class extends MeshPredictionSchem
|
|
|
2660
2515
|
// whole array (see computeOriginalValuesZigzag). Every correction is read
|
|
2661
2516
|
// exactly once before its slot is overwritten, so the in-place aliasing of
|
|
2662
2517
|
// inCorr and outData is preserved.
|
|
2663
|
-
|
|
2518
|
+
Yb(inCorr, outData, numComponents, zigzag) {
|
|
2664
2519
|
if (numComponents === 2) {
|
|
2665
|
-
return this.
|
|
2520
|
+
return this.Zb(inCorr, outData, zigzag);
|
|
2666
2521
|
}
|
|
2667
2522
|
if (numComponents === 3) {
|
|
2668
|
-
return this.
|
|
2523
|
+
return this._b(inCorr, outData, zigzag);
|
|
2669
2524
|
}
|
|
2670
2525
|
if (numComponents === 4) {
|
|
2671
|
-
return this
|
|
2526
|
+
return this.$b(inCorr, outData, zigzag);
|
|
2672
2527
|
}
|
|
2673
2528
|
const table = this.b.cornerTable;
|
|
2674
2529
|
const vertexToDataMap = this.b.vertexToDataMap;
|
|
@@ -2676,9 +2531,9 @@ var MeshPredictionSchemeParallelogramDecoder = class extends MeshPredictionSchem
|
|
|
2676
2531
|
const cornerToVertex = table.cornerToVertexArray();
|
|
2677
2532
|
const dataToCornerMap = this.b.dataToCornerMap;
|
|
2678
2533
|
const transform = this.f;
|
|
2679
|
-
const minValue = transform.
|
|
2534
|
+
const minValue = transform.aa;
|
|
2680
2535
|
const maxValue = transform.k;
|
|
2681
|
-
const maxDif = transform.
|
|
2536
|
+
const maxDif = transform.ba;
|
|
2682
2537
|
for (let c = 0; c < numComponents; ++c) {
|
|
2683
2538
|
let pred = 0;
|
|
2684
2539
|
if (pred > maxValue) {
|
|
@@ -2757,16 +2612,16 @@ var MeshPredictionSchemeParallelogramDecoder = class extends MeshPredictionSchem
|
|
|
2757
2612
|
}
|
|
2758
2613
|
return true;
|
|
2759
2614
|
}
|
|
2760
|
-
|
|
2615
|
+
Zb(inCorr, outData, zigzag) {
|
|
2761
2616
|
const table = this.b.cornerTable;
|
|
2762
2617
|
const vertexToDataMap = this.b.vertexToDataMap;
|
|
2763
2618
|
const oppositeCorners = table.oppositeCornerArray();
|
|
2764
2619
|
const cornerToVertex = table.cornerToVertexArray();
|
|
2765
2620
|
const dataToCornerMap = this.b.dataToCornerMap;
|
|
2766
2621
|
const transform = this.f;
|
|
2767
|
-
const minValue = transform.
|
|
2622
|
+
const minValue = transform.aa;
|
|
2768
2623
|
const maxValue = transform.k;
|
|
2769
|
-
const maxDif = transform.
|
|
2624
|
+
const maxDif = transform.ba;
|
|
2770
2625
|
let pred0 = 0;
|
|
2771
2626
|
let pred1 = 0;
|
|
2772
2627
|
if (pred0 > maxValue) {
|
|
@@ -2855,16 +2710,16 @@ var MeshPredictionSchemeParallelogramDecoder = class extends MeshPredictionSchem
|
|
|
2855
2710
|
}
|
|
2856
2711
|
return true;
|
|
2857
2712
|
}
|
|
2858
|
-
|
|
2713
|
+
_b(inCorr, outData, zigzag) {
|
|
2859
2714
|
const table = this.b.cornerTable;
|
|
2860
2715
|
const vertexToDataMap = this.b.vertexToDataMap;
|
|
2861
2716
|
const oppositeCorners = table.oppositeCornerArray();
|
|
2862
2717
|
const cornerToVertex = table.cornerToVertexArray();
|
|
2863
2718
|
const dataToCornerMap = this.b.dataToCornerMap;
|
|
2864
2719
|
const transform = this.f;
|
|
2865
|
-
const minValue = transform.
|
|
2720
|
+
const minValue = transform.aa;
|
|
2866
2721
|
const maxValue = transform.k;
|
|
2867
|
-
const maxDif = transform.
|
|
2722
|
+
const maxDif = transform.ba;
|
|
2868
2723
|
let pred0 = 0;
|
|
2869
2724
|
let pred1 = 0;
|
|
2870
2725
|
let pred2 = 0;
|
|
@@ -2984,16 +2839,16 @@ var MeshPredictionSchemeParallelogramDecoder = class extends MeshPredictionSchem
|
|
|
2984
2839
|
}
|
|
2985
2840
|
// Four components: tangents, RGBA colors, skin joints/weights. Same
|
|
2986
2841
|
// structure as the 2/3-component loops.
|
|
2987
|
-
|
|
2842
|
+
$b(inCorr, outData, zigzag) {
|
|
2988
2843
|
const table = this.b.cornerTable;
|
|
2989
2844
|
const vertexToDataMap = this.b.vertexToDataMap;
|
|
2990
2845
|
const oppositeCorners = table.oppositeCornerArray();
|
|
2991
2846
|
const cornerToVertex = table.cornerToVertexArray();
|
|
2992
2847
|
const dataToCornerMap = this.b.dataToCornerMap;
|
|
2993
2848
|
const transform = this.f;
|
|
2994
|
-
const minValue = transform.
|
|
2849
|
+
const minValue = transform.aa;
|
|
2995
2850
|
const maxValue = transform.k;
|
|
2996
|
-
const maxDif = transform.
|
|
2851
|
+
const maxDif = transform.ba;
|
|
2997
2852
|
let pred0 = 0;
|
|
2998
2853
|
if (pred0 > maxValue) {
|
|
2999
2854
|
pred0 = maxValue;
|
|
@@ -3112,39 +2967,39 @@ function bigIntSqrt(value) {
|
|
|
3112
2967
|
return x;
|
|
3113
2968
|
}
|
|
3114
2969
|
var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
2970
|
+
ra = null;
|
|
2971
|
+
sa = null;
|
|
2972
|
+
r = new Int32Array(2);
|
|
2973
|
+
Ka = new Uint8Array(0);
|
|
2974
|
+
ua = 0;
|
|
3120
2975
|
b;
|
|
3121
|
-
|
|
2976
|
+
Xa = new Array(3);
|
|
3122
2977
|
// Flat Int32 position cache so fetches are array reads, not convertValue calls.
|
|
3123
|
-
|
|
2978
|
+
ta = null;
|
|
3124
2979
|
h = null;
|
|
3125
2980
|
constructor(meshData) {
|
|
3126
2981
|
this.b = meshData;
|
|
3127
2982
|
}
|
|
3128
2983
|
setPositionAttribute(positionAttribute) {
|
|
3129
|
-
this.
|
|
2984
|
+
this.ra = positionAttribute;
|
|
3130
2985
|
}
|
|
3131
2986
|
setEntryToPointIdMap(map) {
|
|
3132
|
-
this.
|
|
2987
|
+
this.sa = map;
|
|
3133
2988
|
}
|
|
3134
2989
|
get predictedValue() {
|
|
3135
|
-
return this.
|
|
2990
|
+
return this.r;
|
|
3136
2991
|
}
|
|
3137
2992
|
resizeOrientations(numOrientations) {
|
|
3138
|
-
this.
|
|
3139
|
-
this.
|
|
2993
|
+
this.Ka = new Uint8Array(numOrientations);
|
|
2994
|
+
this.ua = numOrientations;
|
|
3140
2995
|
}
|
|
3141
2996
|
setOrientation(i, v) {
|
|
3142
|
-
this.
|
|
2997
|
+
this.Ka[i] = v ? 1 : 0;
|
|
3143
2998
|
}
|
|
3144
2999
|
buildPositionCache(numEntries) {
|
|
3145
3000
|
const posCache = new Int32Array(numEntries * 3);
|
|
3146
|
-
fillInt32PositionCache(posCache, this.
|
|
3147
|
-
this.
|
|
3001
|
+
fillInt32PositionCache(posCache, this.ra, this.sa, numEntries, this.Xa);
|
|
3002
|
+
this.ta = posCache;
|
|
3148
3003
|
this.h = this.b.cornerTable.cornerToVertexArray();
|
|
3149
3004
|
}
|
|
3150
3005
|
computePredictedValue(cornerId, data, dataId) {
|
|
@@ -3163,11 +3018,11 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
3163
3018
|
const nUV0 = data[nDataOff], nUV1 = data[nDataOff + 1];
|
|
3164
3019
|
const pUV0 = data[pDataOff], pUV1 = data[pDataOff + 1];
|
|
3165
3020
|
if (pUV0 === nUV0 && pUV1 === nUV1) {
|
|
3166
|
-
this.
|
|
3167
|
-
this.
|
|
3021
|
+
this.r[0] = pUV0;
|
|
3022
|
+
this.r[1] = pUV1;
|
|
3168
3023
|
return true;
|
|
3169
3024
|
}
|
|
3170
|
-
const posCache = this.
|
|
3025
|
+
const posCache = this.ta;
|
|
3171
3026
|
let posOffset = dataId * 3;
|
|
3172
3027
|
const tip0 = posCache[posOffset];
|
|
3173
3028
|
const tip1 = posCache[posOffset + 1];
|
|
@@ -3204,7 +3059,7 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
3204
3059
|
const pnAbsMaxG = Math.max(Math.abs(pn0), Math.abs(pn1), Math.abs(pn2));
|
|
3205
3060
|
const cnDotPnAbs = Math.abs(cnDotPn);
|
|
3206
3061
|
if (cnNorm2 > SAFE_PRODUCT / pnNorm2Squared || nUVAbsMax > SAFE_PRODUCT / pnNorm2Squared || pnUVAbsMax > 0 && cnDotPnAbs > SAFE_PRODUCT / pnUVAbsMax || pnAbsMaxG > 0 && cnDotPnAbs > SAFE_PRODUCT / pnAbsMaxG) {
|
|
3207
|
-
return this.
|
|
3062
|
+
return this.ac(
|
|
3208
3063
|
tip0,
|
|
3209
3064
|
tip1,
|
|
3210
3065
|
tip2,
|
|
@@ -3236,16 +3091,16 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
3236
3091
|
const normSquared = Math.floor(Math.sqrt(cxNorm2Squared * pnNorm2Squared));
|
|
3237
3092
|
const cxUV0 = pnUV1 * normSquared;
|
|
3238
3093
|
const cxUV1 = -pnUV0 * normSquared;
|
|
3239
|
-
if (this.
|
|
3094
|
+
if (this.ua === 0) {
|
|
3240
3095
|
return false;
|
|
3241
3096
|
}
|
|
3242
|
-
const orientation = this.
|
|
3097
|
+
const orientation = this.Ka[--this.ua];
|
|
3243
3098
|
if (orientation) {
|
|
3244
|
-
this.
|
|
3245
|
-
this.
|
|
3099
|
+
this.r[0] = Math.trunc((xUV0 + cxUV0) / pnNorm2Squared);
|
|
3100
|
+
this.r[1] = Math.trunc((xUV1 + cxUV1) / pnNorm2Squared);
|
|
3246
3101
|
} else {
|
|
3247
|
-
this.
|
|
3248
|
-
this.
|
|
3102
|
+
this.r[0] = Math.trunc((xUV0 - cxUV0) / pnNorm2Squared);
|
|
3103
|
+
this.r[1] = Math.trunc((xUV1 - cxUV1) / pnNorm2Squared);
|
|
3249
3104
|
}
|
|
3250
3105
|
return true;
|
|
3251
3106
|
}
|
|
@@ -3260,13 +3115,13 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
3260
3115
|
if (dataId > 0) {
|
|
3261
3116
|
dataOffset = (dataId - 1) * 2;
|
|
3262
3117
|
} else {
|
|
3263
|
-
this.
|
|
3264
|
-
this.
|
|
3118
|
+
this.r[0] = 0;
|
|
3119
|
+
this.r[1] = 0;
|
|
3265
3120
|
return true;
|
|
3266
3121
|
}
|
|
3267
3122
|
}
|
|
3268
|
-
this.
|
|
3269
|
-
this.
|
|
3123
|
+
this.r[0] = data[dataOffset];
|
|
3124
|
+
this.r[1] = data[dataOffset + 1];
|
|
3270
3125
|
return true;
|
|
3271
3126
|
}
|
|
3272
3127
|
// 64-bit-exact projection prediction, used when the double path would lose
|
|
@@ -3274,7 +3129,7 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
3274
3129
|
// <uint64_t>, including the uint64 wraparound in IntSqrt(cxNorm2*pnNorm2) and
|
|
3275
3130
|
// the unsigned add/sub forming the final UV. Returns false in the same
|
|
3276
3131
|
// overflow cases as the double path so encoder and decoder agree on fallback.
|
|
3277
|
-
|
|
3132
|
+
ac(tip0, tip1, tip2, next0, next1, next2, pn0, pn1, pn2, nUV0, nUV1, pUV0, pUV1, pnNorm2SquaredNum) {
|
|
3278
3133
|
const B = BigInt;
|
|
3279
3134
|
const tip = [B(tip0), B(tip1), B(tip2)];
|
|
3280
3135
|
const nxt = [B(next0), B(next1), B(next2)];
|
|
@@ -3308,8 +3163,8 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
3308
3163
|
const normSquared = bigIntSqrt(cxNorm2 * pnN2 & MASK64);
|
|
3309
3164
|
const cxUV0 = B.asIntN(64, pnUV1 * normSquared);
|
|
3310
3165
|
const cxUV1 = B.asIntN(64, -pnUV0 * normSquared);
|
|
3311
|
-
if (this.
|
|
3312
|
-
const orientation = this.
|
|
3166
|
+
if (this.ua === 0) return false;
|
|
3167
|
+
const orientation = this.Ka[--this.ua];
|
|
3313
3168
|
let s0, s1;
|
|
3314
3169
|
if (orientation) {
|
|
3315
3170
|
s0 = B.asUintN(64, B.asUintN(64, xUV0) + B.asUintN(64, cxUV0));
|
|
@@ -3318,8 +3173,8 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
3318
3173
|
s0 = B.asUintN(64, B.asUintN(64, xUV0) - B.asUintN(64, cxUV0));
|
|
3319
3174
|
s1 = B.asUintN(64, B.asUintN(64, xUV1) - B.asUintN(64, cxUV1));
|
|
3320
3175
|
}
|
|
3321
|
-
this.
|
|
3322
|
-
this.
|
|
3176
|
+
this.r[0] = Number(B.asIntN(32, B.asIntN(64, s0) / pnN2));
|
|
3177
|
+
this.r[1] = Number(B.asIntN(32, B.asIntN(64, s1) / pnN2));
|
|
3323
3178
|
return true;
|
|
3324
3179
|
}
|
|
3325
3180
|
};
|
|
@@ -3327,10 +3182,10 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
3327
3182
|
// src/decoder/compression/attributes/prediction_schemes/MeshPredictionSchemeTexCoordsPortableDecoder.ts
|
|
3328
3183
|
var GEOMETRY_ATTRIBUTE_POSITION2 = 0;
|
|
3329
3184
|
var MeshPredictionSchemeTexCoordsPortableDecoder = class extends MeshPredictionSchemeDecoder {
|
|
3330
|
-
|
|
3185
|
+
q;
|
|
3331
3186
|
constructor(transform, meshData) {
|
|
3332
3187
|
super(transform, meshData);
|
|
3333
|
-
this.
|
|
3188
|
+
this.q = new MeshPredictionSchemeTexCoordsPortablePredictor(meshData);
|
|
3334
3189
|
}
|
|
3335
3190
|
getNumParentAttributes() {
|
|
3336
3191
|
return 1;
|
|
@@ -3341,13 +3196,13 @@ var MeshPredictionSchemeTexCoordsPortableDecoder = class extends MeshPredictionS
|
|
|
3341
3196
|
setParentAttribute(att) {
|
|
3342
3197
|
if (att.attributeType !== GEOMETRY_ATTRIBUTE_POSITION2) return false;
|
|
3343
3198
|
if (att.numComponents !== 3) return false;
|
|
3344
|
-
this.
|
|
3199
|
+
this.q.setPositionAttribute(att);
|
|
3345
3200
|
return true;
|
|
3346
3201
|
}
|
|
3347
3202
|
decodePredictionData(buffer) {
|
|
3348
3203
|
const numOrientations = buffer.decodeInt32();
|
|
3349
3204
|
if (numOrientations === void 0 || numOrientations < 0) return false;
|
|
3350
|
-
this.
|
|
3205
|
+
this.q.resizeOrientations(numOrientations);
|
|
3351
3206
|
let lastOrientation = true;
|
|
3352
3207
|
const decoder = new RAnsBitDecoder();
|
|
3353
3208
|
if (!decoder.startDecoding(buffer)) return false;
|
|
@@ -3355,7 +3210,7 @@ var MeshPredictionSchemeTexCoordsPortableDecoder = class extends MeshPredictionS
|
|
|
3355
3210
|
if (!decoder.decodeNextBit()) {
|
|
3356
3211
|
lastOrientation = !lastOrientation;
|
|
3357
3212
|
}
|
|
3358
|
-
this.
|
|
3213
|
+
this.q.setOrientation(i, lastOrientation);
|
|
3359
3214
|
}
|
|
3360
3215
|
decoder.endDecoding();
|
|
3361
3216
|
return super.decodePredictionData(buffer);
|
|
@@ -3364,17 +3219,17 @@ var MeshPredictionSchemeTexCoordsPortableDecoder = class extends MeshPredictionS
|
|
|
3364
3219
|
if (numComponents !== 2) {
|
|
3365
3220
|
return false;
|
|
3366
3221
|
}
|
|
3367
|
-
this.
|
|
3222
|
+
this.q.setEntryToPointIdMap(entryToPointIdMap);
|
|
3368
3223
|
this.f.init(numComponents);
|
|
3369
3224
|
const cornerMapSize = this.b.dataToCornerMap.length;
|
|
3370
|
-
this.
|
|
3225
|
+
this.q.buildPositionCache(cornerMapSize);
|
|
3371
3226
|
for (let p = 0; p < cornerMapSize; ++p) {
|
|
3372
3227
|
const cornerId = this.b.dataToCornerMap[p];
|
|
3373
|
-
if (!this.
|
|
3228
|
+
if (!this.q.computePredictedValue(cornerId, outData, p)) {
|
|
3374
3229
|
return false;
|
|
3375
3230
|
}
|
|
3376
3231
|
const dstOffset = p * numComponents;
|
|
3377
|
-
this.f.computeOriginalValue(this.
|
|
3232
|
+
this.f.computeOriginalValue(this.q.predictedValue, 0, inCorr, dstOffset, outData, dstOffset);
|
|
3378
3233
|
}
|
|
3379
3234
|
return true;
|
|
3380
3235
|
}
|
|
@@ -3401,27 +3256,27 @@ var PredictionSchemeDeltaDecoder = class extends PredictionSchemeDecoder {
|
|
|
3401
3256
|
// src/decoder/compression/attributes/prediction_schemes/PredictionSchemeDecoderFactory.ts
|
|
3402
3257
|
function createMeshPredictionSchemeDecoder(method, transform, meshData) {
|
|
3403
3258
|
const transformType = transform.getType();
|
|
3404
|
-
if (transformType ===
|
|
3405
|
-
if (method ===
|
|
3259
|
+
if (transformType === 3 /* PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON_CANONICALIZED */ || transformType === 2 /* PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON */) {
|
|
3260
|
+
if (method === 6 /* MESH_PREDICTION_GEOMETRIC_NORMAL */) {
|
|
3406
3261
|
return new MeshPredictionSchemeGeometricNormalDecoder(transform, meshData);
|
|
3407
3262
|
}
|
|
3408
3263
|
return null;
|
|
3409
3264
|
}
|
|
3410
3265
|
switch (method) {
|
|
3411
|
-
case
|
|
3266
|
+
case 1 /* MESH_PREDICTION_PARALLELOGRAM */:
|
|
3412
3267
|
return new MeshPredictionSchemeParallelogramDecoder(transform, meshData);
|
|
3413
|
-
case
|
|
3268
|
+
case 2 /* MESH_PREDICTION_MULTI_PARALLELOGRAM */:
|
|
3414
3269
|
return new MeshPredictionSchemeMultiParallelogramDecoder(transform, meshData);
|
|
3415
|
-
case
|
|
3270
|
+
case 4 /* MESH_PREDICTION_CONSTRAINED_MULTI_PARALLELOGRAM */:
|
|
3416
3271
|
return new MeshPredictionSchemeConstrainedMultiParallelogramDecoder(transform, meshData);
|
|
3417
|
-
case
|
|
3272
|
+
case 5 /* MESH_PREDICTION_TEX_COORDS_PORTABLE */:
|
|
3418
3273
|
return new MeshPredictionSchemeTexCoordsPortableDecoder(transform, meshData);
|
|
3419
3274
|
default:
|
|
3420
3275
|
return null;
|
|
3421
3276
|
}
|
|
3422
3277
|
}
|
|
3423
3278
|
function createPredictionSchemeForDecoder(method, attId, decoder, transform) {
|
|
3424
|
-
if (method ===
|
|
3279
|
+
if (method === -2 /* PREDICTION_NONE */) {
|
|
3425
3280
|
return null;
|
|
3426
3281
|
}
|
|
3427
3282
|
const meshDecoder = decoder;
|
|
@@ -3442,24 +3297,24 @@ function createPredictionSchemeForDecoder(method, attId, decoder, transform) {
|
|
|
3442
3297
|
|
|
3443
3298
|
// src/decoder/compression/attributes/prediction_schemes/PredictionSchemeWrapDecodingTransform.ts
|
|
3444
3299
|
var PredictionSchemeWrapDecodingTransform = class {
|
|
3445
|
-
|
|
3446
|
-
|
|
3300
|
+
w = 0;
|
|
3301
|
+
aa = 0;
|
|
3447
3302
|
k = 0;
|
|
3448
|
-
|
|
3303
|
+
ba = 0;
|
|
3449
3304
|
getType() {
|
|
3450
|
-
return
|
|
3305
|
+
return 1 /* PREDICTION_TRANSFORM_WRAP */;
|
|
3451
3306
|
}
|
|
3452
3307
|
init(numComponents) {
|
|
3453
|
-
this.
|
|
3308
|
+
this.w = numComponents;
|
|
3454
3309
|
}
|
|
3455
3310
|
areCorrectionsPositive() {
|
|
3456
3311
|
return false;
|
|
3457
3312
|
}
|
|
3458
3313
|
computeOriginalValue(predictedVals, predictedOffset, corrVals, corrOffset, outOriginalVals, outOffset) {
|
|
3459
|
-
const nc = this.
|
|
3460
|
-
const minValue = this.
|
|
3314
|
+
const nc = this.w;
|
|
3315
|
+
const minValue = this.aa;
|
|
3461
3316
|
const maxValue = this.k;
|
|
3462
|
-
const maxDif = this.
|
|
3317
|
+
const maxDif = this.ba;
|
|
3463
3318
|
for (let i = 0; i < nc; ++i) {
|
|
3464
3319
|
let pred = predictedVals[predictedOffset + i];
|
|
3465
3320
|
if (pred > maxValue) {
|
|
@@ -3483,63 +3338,65 @@ var PredictionSchemeWrapDecodingTransform = class {
|
|
|
3483
3338
|
if (maxValue === void 0) return false;
|
|
3484
3339
|
const dif = maxValue - minValue;
|
|
3485
3340
|
if (dif < 0 || dif >= 2147483647) return false;
|
|
3486
|
-
this.
|
|
3341
|
+
this.aa = minValue;
|
|
3487
3342
|
this.k = maxValue;
|
|
3488
|
-
this.
|
|
3343
|
+
this.ba = 1 + dif;
|
|
3489
3344
|
return true;
|
|
3490
3345
|
}
|
|
3491
3346
|
};
|
|
3492
3347
|
|
|
3493
3348
|
// src/decoder/compression/attributes/SequentialIntegerAttributeDecoder.ts
|
|
3494
3349
|
var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder {
|
|
3495
|
-
|
|
3350
|
+
ca = null;
|
|
3496
3351
|
// Two-phase decode state (see SequentialAttributeDecoder): the parse phase
|
|
3497
3352
|
// stashes the primed raw-symbol stream here so the controller can batch and
|
|
3498
3353
|
// pair several attributes' decodes; the finish phase consumes it.
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3354
|
+
da = null;
|
|
3355
|
+
Za = 0;
|
|
3356
|
+
Ab = null;
|
|
3502
3357
|
// Int32 view over the portable attribute's storage (see preparePortableAttribute).
|
|
3503
|
-
|
|
3358
|
+
R = null;
|
|
3504
3359
|
// --- Two-phase decode (parse headers / batch symbol decode / finish) ---
|
|
3505
3360
|
pendingSymbolStream() {
|
|
3506
|
-
if (this.
|
|
3361
|
+
if (this.da === null) {
|
|
3507
3362
|
return null;
|
|
3508
3363
|
}
|
|
3509
|
-
const portableData = this.
|
|
3364
|
+
const portableData = this.R;
|
|
3510
3365
|
return {
|
|
3511
|
-
ans: this.
|
|
3512
|
-
out: new Uint32Array(portableData.buffer, portableData.byteOffset, this.
|
|
3513
|
-
count: this.
|
|
3366
|
+
ans: this.da.m,
|
|
3367
|
+
out: new Uint32Array(portableData.buffer, portableData.byteOffset, this.Za),
|
|
3368
|
+
count: this.Za
|
|
3514
3369
|
};
|
|
3515
3370
|
}
|
|
3516
3371
|
decodePortableAttributeFinish() {
|
|
3517
|
-
if (this.
|
|
3518
|
-
this.
|
|
3519
|
-
this.
|
|
3372
|
+
if (this.da !== null) {
|
|
3373
|
+
this.da.endDecoding();
|
|
3374
|
+
this.da = null;
|
|
3520
3375
|
}
|
|
3521
|
-
return this.
|
|
3376
|
+
return this.bc(this.Ab);
|
|
3522
3377
|
}
|
|
3523
3378
|
// The parse phase of the integer decode: prediction scheme, portable
|
|
3524
3379
|
// attribute, the symbol stream (raw streams are deferred to the finish
|
|
3525
3380
|
// phase) and the prediction data.
|
|
3526
3381
|
decodeValues(pointIds, buffer) {
|
|
3527
|
-
this.
|
|
3528
|
-
|
|
3382
|
+
this.Ab = pointIds;
|
|
3383
|
+
let predictionSchemeMethod = buffer.decodeUint8();
|
|
3384
|
+
if (predictionSchemeMethod !== void 0) predictionSchemeMethod = predictionSchemeMethod << 24 >> 24;
|
|
3529
3385
|
if (predictionSchemeMethod === void 0) return false;
|
|
3530
|
-
if (predictionSchemeMethod <
|
|
3386
|
+
if (predictionSchemeMethod < -2 /* PREDICTION_NONE */ || predictionSchemeMethod >= 7 /* NUM_PREDICTION_SCHEMES */) {
|
|
3531
3387
|
return false;
|
|
3532
3388
|
}
|
|
3533
|
-
if (predictionSchemeMethod !==
|
|
3534
|
-
|
|
3389
|
+
if (predictionSchemeMethod !== -2 /* PREDICTION_NONE */) {
|
|
3390
|
+
let predictionTransformType = buffer.decodeUint8();
|
|
3391
|
+
if (predictionTransformType !== void 0) predictionTransformType = predictionTransformType << 24 >> 24;
|
|
3535
3392
|
if (predictionTransformType === void 0) return false;
|
|
3536
|
-
if (predictionTransformType <
|
|
3393
|
+
if (predictionTransformType < -1 /* PREDICTION_TRANSFORM_NONE */ || predictionTransformType >= 4 /* NUM_PREDICTION_SCHEME_TRANSFORM_TYPES */) {
|
|
3537
3394
|
return false;
|
|
3538
3395
|
}
|
|
3539
|
-
this.
|
|
3396
|
+
this.ca = this.createIntPredictionScheme(predictionSchemeMethod, predictionTransformType);
|
|
3540
3397
|
}
|
|
3541
|
-
if (this.
|
|
3542
|
-
if (!this.initPredictionScheme(this.
|
|
3398
|
+
if (this.ca) {
|
|
3399
|
+
if (!this.initPredictionScheme(this.ca)) {
|
|
3543
3400
|
return false;
|
|
3544
3401
|
}
|
|
3545
3402
|
}
|
|
@@ -3550,7 +3407,7 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
|
|
|
3550
3407
|
const numEntries = pointIds.length;
|
|
3551
3408
|
const numValues = numEntries * numComponents;
|
|
3552
3409
|
this.preparePortableAttribute(numEntries, numComponents);
|
|
3553
|
-
const portableAttributeData = this.
|
|
3410
|
+
const portableAttributeData = this.R;
|
|
3554
3411
|
if (portableAttributeData === null) {
|
|
3555
3412
|
return false;
|
|
3556
3413
|
}
|
|
@@ -3559,14 +3416,14 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
|
|
|
3559
3416
|
if (compressed > 0) {
|
|
3560
3417
|
if (numValues > 0) {
|
|
3561
3418
|
const scheme = buffer.decodeUint8();
|
|
3562
|
-
if (scheme ===
|
|
3419
|
+
if (scheme === 1 /* SYMBOL_CODING_RAW */) {
|
|
3563
3420
|
const decoder = parseRawSymbolStream(numValues, buffer);
|
|
3564
3421
|
if (decoder === null) {
|
|
3565
3422
|
return false;
|
|
3566
3423
|
}
|
|
3567
|
-
this.
|
|
3568
|
-
this.
|
|
3569
|
-
} else if (scheme ===
|
|
3424
|
+
this.da = decoder;
|
|
3425
|
+
this.Za = numValues;
|
|
3426
|
+
} else if (scheme === 0 /* SYMBOL_CODING_TAGGED */) {
|
|
3570
3427
|
const outUint32 = new Uint32Array(portableAttributeData.buffer, portableAttributeData.byteOffset, numValues);
|
|
3571
3428
|
if (!decodeTaggedSymbols(numValues, numComponents, buffer, outUint32)) {
|
|
3572
3429
|
return false;
|
|
@@ -3589,25 +3446,25 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
|
|
|
3589
3446
|
portableAttributeData[i] = val;
|
|
3590
3447
|
}
|
|
3591
3448
|
}
|
|
3592
|
-
if (this.
|
|
3593
|
-
if (!this.
|
|
3449
|
+
if (this.ca) {
|
|
3450
|
+
if (!this.ca.decodePredictionData(buffer)) {
|
|
3594
3451
|
return false;
|
|
3595
3452
|
}
|
|
3596
3453
|
}
|
|
3597
3454
|
return true;
|
|
3598
3455
|
}
|
|
3599
3456
|
// The post-symbol tail of the decode: zigzag unpacking and prediction.
|
|
3600
|
-
|
|
3457
|
+
bc(pointIds) {
|
|
3601
3458
|
const numComponents = this.getNumValueComponents();
|
|
3602
3459
|
const numValues = pointIds.length * numComponents;
|
|
3603
|
-
const data = this.
|
|
3460
|
+
const data = this.R;
|
|
3604
3461
|
if (data === null) {
|
|
3605
3462
|
return false;
|
|
3606
3463
|
}
|
|
3607
3464
|
if (numValues === 0) {
|
|
3608
3465
|
return true;
|
|
3609
3466
|
}
|
|
3610
|
-
const ps = this.
|
|
3467
|
+
const ps = this.ca;
|
|
3611
3468
|
if (ps === null) {
|
|
3612
3469
|
convertSymbolsToSignedInts(new Uint32Array(data.buffer, data.byteOffset, numValues), numValues, data);
|
|
3613
3470
|
return true;
|
|
@@ -3622,11 +3479,11 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
|
|
|
3622
3479
|
return ps.computeOriginalValues(data, data, numValues, numComponents, pointIds);
|
|
3623
3480
|
}
|
|
3624
3481
|
transformAttributeToOriginalFormat(pointIds) {
|
|
3625
|
-
return this.
|
|
3482
|
+
return this._a(pointIds.length);
|
|
3626
3483
|
}
|
|
3627
3484
|
// Prediction scheme for decoding integer values; subclasses override for others.
|
|
3628
3485
|
createIntPredictionScheme(method, transformType) {
|
|
3629
|
-
if (transformType !==
|
|
3486
|
+
if (transformType !== 1 /* PREDICTION_TRANSFORM_WRAP */) {
|
|
3630
3487
|
return null;
|
|
3631
3488
|
}
|
|
3632
3489
|
const transform = new PredictionSchemeWrapDecodingTransform();
|
|
@@ -3635,19 +3492,21 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
|
|
|
3635
3492
|
getNumValueComponents() {
|
|
3636
3493
|
return this.attribute.numComponents;
|
|
3637
3494
|
}
|
|
3638
|
-
//
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3495
|
+
// The decoded values stay in the portable attribute; the final attribute
|
|
3496
|
+
// only takes its size (see PointAttribute.setLazyInteger and the overrides
|
|
3497
|
+
// in the quantization / normal decoders).
|
|
3498
|
+
xb(numValues) {
|
|
3499
|
+
this.attribute.resetLazy(numValues);
|
|
3500
|
+
return true;
|
|
3501
|
+
}
|
|
3502
|
+
// Hands the decoded integer values to the attribute, converted to its
|
|
3503
|
+
// integer type on extraction.
|
|
3504
|
+
_a(_numValues) {
|
|
3505
|
+
const dt = this.attribute.dataType;
|
|
3506
|
+
if (dt < 1 /* INT8 */ || dt > 6 /* UINT32 */) {
|
|
3644
3507
|
return false;
|
|
3645
3508
|
}
|
|
3646
|
-
|
|
3647
|
-
if (total > 0) {
|
|
3648
|
-
const dstData = attribute.buffer.data;
|
|
3649
|
-
new IntArray(dstData.buffer, dstData.byteOffset + attribute.byteOffset, total).set(this.ma);
|
|
3650
|
-
}
|
|
3509
|
+
this.attribute.setLazyInteger(this.R);
|
|
3651
3510
|
return true;
|
|
3652
3511
|
}
|
|
3653
3512
|
preparePortableAttribute(numEntries, numComponents) {
|
|
@@ -3656,107 +3515,18 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
|
|
|
3656
3515
|
this.attribute.attributeType,
|
|
3657
3516
|
null,
|
|
3658
3517
|
numComponents,
|
|
3659
|
-
|
|
3518
|
+
5 /* INT32 */,
|
|
3660
3519
|
false,
|
|
3661
|
-
numComponents * dataTypeLength(
|
|
3520
|
+
numComponents * dataTypeLength(5 /* INT32 */),
|
|
3662
3521
|
0
|
|
3663
3522
|
);
|
|
3664
3523
|
const portAtt = new PointAttribute(ga);
|
|
3665
3524
|
portAtt.setIdentityMapping();
|
|
3666
|
-
portAtt.
|
|
3525
|
+
portAtt.reset(numEntries);
|
|
3667
3526
|
portAtt.uniqueId = this.attribute.uniqueId;
|
|
3668
|
-
this
|
|
3527
|
+
this.$ = portAtt;
|
|
3669
3528
|
const data = portAtt.buffer.data;
|
|
3670
|
-
this.
|
|
3671
|
-
}
|
|
3672
|
-
};
|
|
3673
|
-
|
|
3674
|
-
// src/decoder/attributes/AttributeTransformType.ts
|
|
3675
|
-
var AttributeTransformType = {
|
|
3676
|
-
INVALID: -1,
|
|
3677
|
-
NO_TRANSFORM: 0,
|
|
3678
|
-
QUANTIZATION_TRANSFORM: 1,
|
|
3679
|
-
OCTAHEDRON_TRANSFORM: 2
|
|
3680
|
-
};
|
|
3681
|
-
|
|
3682
|
-
// src/decoder/attributes/AttributeTransformData.ts
|
|
3683
|
-
var AttributeTransformData = class {
|
|
3684
|
-
transformType = AttributeTransformType.INVALID;
|
|
3685
|
-
Kb = [];
|
|
3686
|
-
Lb = [];
|
|
3687
|
-
appendParameterValue(value, type) {
|
|
3688
|
-
this.Kb.push(value);
|
|
3689
|
-
this.Lb.push(type);
|
|
3690
|
-
}
|
|
3691
|
-
};
|
|
3692
|
-
|
|
3693
|
-
// src/decoder/attributes/AttributeTransform.ts
|
|
3694
|
-
var AttributeTransform = class {
|
|
3695
|
-
transferToAttribute(attribute) {
|
|
3696
|
-
const transformData = new AttributeTransformData();
|
|
3697
|
-
this.copyToAttributeTransformData(transformData);
|
|
3698
|
-
attribute.setAttributeTransformData(transformData);
|
|
3699
|
-
return true;
|
|
3700
|
-
}
|
|
3701
|
-
};
|
|
3702
|
-
|
|
3703
|
-
// src/decoder/attributes/AttributeOctahedronTransform.ts
|
|
3704
|
-
var AttributeOctahedronTransform = class extends AttributeTransform {
|
|
3705
|
-
x = -1;
|
|
3706
|
-
copyToAttributeTransformData(outData) {
|
|
3707
|
-
outData.transformType = AttributeTransformType.OCTAHEDRON_TRANSFORM;
|
|
3708
|
-
outData.appendParameterValue(this.x, "int32");
|
|
3709
|
-
}
|
|
3710
|
-
decodeParameters(attribute, decoderBuffer) {
|
|
3711
|
-
const qBits = decoderBuffer.decodeUint8();
|
|
3712
|
-
if (qBits === void 0) return false;
|
|
3713
|
-
this.x = qBits;
|
|
3714
|
-
return true;
|
|
3715
|
-
}
|
|
3716
|
-
inverseTransformAttribute(attribute, targetAttribute) {
|
|
3717
|
-
if (targetAttribute.dataType !== DataType.FLOAT32) {
|
|
3718
|
-
return false;
|
|
3719
|
-
}
|
|
3720
|
-
const numPoints = targetAttribute.size;
|
|
3721
|
-
const numComponents = targetAttribute.numComponents;
|
|
3722
|
-
if (numComponents !== 3) {
|
|
3723
|
-
return false;
|
|
3724
|
-
}
|
|
3725
|
-
const toolBox = new OctahedronToolBox();
|
|
3726
|
-
if (!toolBox.setQuantizationBits(this.x)) {
|
|
3727
|
-
return false;
|
|
3728
|
-
}
|
|
3729
|
-
const srcData = attribute.buffer.data;
|
|
3730
|
-
const srcI32 = new Int32Array(srcData.buffer, srcData.byteOffset + attribute.byteOffset, numPoints * 2);
|
|
3731
|
-
const dstData = targetAttribute.buffer.data;
|
|
3732
|
-
const dstF32 = new Float32Array(dstData.buffer, dstData.byteOffset + targetAttribute.byteOffset, numPoints * 3);
|
|
3733
|
-
const fround = Math.fround;
|
|
3734
|
-
const scale = toolBox.hb;
|
|
3735
|
-
let si = 0;
|
|
3736
|
-
let di = 0;
|
|
3737
|
-
for (let i = 0; i < numPoints; i++) {
|
|
3738
|
-
let y = fround(fround(fround(srcI32[si]) * scale) - 1);
|
|
3739
|
-
let z = fround(fround(fround(srcI32[si + 1]) * scale) - 1);
|
|
3740
|
-
si += 2;
|
|
3741
|
-
const x = fround(fround(1 - Math.abs(y)) - Math.abs(z));
|
|
3742
|
-
let xOffset = -x;
|
|
3743
|
-
if (xOffset < 0) xOffset = 0;
|
|
3744
|
-
y = fround(y + (y < 0 ? xOffset : -xOffset));
|
|
3745
|
-
z = fround(z + (z < 0 ? xOffset : -xOffset));
|
|
3746
|
-
const normSquared = fround(fround(fround(x * x) + fround(y * y)) + fround(z * z));
|
|
3747
|
-
if (normSquared < 1e-6) {
|
|
3748
|
-
dstF32[di] = 0;
|
|
3749
|
-
dstF32[di + 1] = 0;
|
|
3750
|
-
dstF32[di + 2] = 0;
|
|
3751
|
-
} else {
|
|
3752
|
-
const d = fround(1 / fround(Math.sqrt(normSquared)));
|
|
3753
|
-
dstF32[di] = fround(x * d);
|
|
3754
|
-
dstF32[di + 1] = fround(y * d);
|
|
3755
|
-
dstF32[di + 2] = fround(z * d);
|
|
3756
|
-
}
|
|
3757
|
-
di += 3;
|
|
3758
|
-
}
|
|
3759
|
-
return true;
|
|
3529
|
+
this.R = numEntries === 0 ? null : new Int32Array(data.buffer, data.byteOffset + portAtt.byteOffset, numEntries * numComponents);
|
|
3760
3530
|
}
|
|
3761
3531
|
};
|
|
3762
3532
|
|
|
@@ -3772,7 +3542,7 @@ var PredictionSchemeNormalOctahedronTransformBase = class {
|
|
|
3772
3542
|
quantizationBits() {
|
|
3773
3543
|
return this.y.quantizationBits();
|
|
3774
3544
|
}
|
|
3775
|
-
|
|
3545
|
+
Bb(maxQuantizedValue) {
|
|
3776
3546
|
if (maxQuantizedValue % 2 === 0) return false;
|
|
3777
3547
|
let q = 0;
|
|
3778
3548
|
let v = maxQuantizedValue;
|
|
@@ -3787,21 +3557,21 @@ var PredictionSchemeNormalOctahedronTransformBase = class {
|
|
|
3787
3557
|
// src/decoder/compression/attributes/prediction_schemes/PredictionSchemeNormalOctahedronCanonicalizedDecodingTransform.ts
|
|
3788
3558
|
var PredictionSchemeNormalOctahedronCanonicalizedDecodingTransform = class extends PredictionSchemeNormalOctahedronTransformBase {
|
|
3789
3559
|
getType() {
|
|
3790
|
-
return
|
|
3560
|
+
return 3 /* PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON_CANONICALIZED */;
|
|
3791
3561
|
}
|
|
3792
3562
|
decodeTransformData(buffer) {
|
|
3793
3563
|
const maxQuantizedValue = buffer.decodeInt32();
|
|
3794
3564
|
if (maxQuantizedValue === void 0) return false;
|
|
3795
3565
|
const centerValue = buffer.decodeInt32();
|
|
3796
3566
|
if (centerValue === void 0) return false;
|
|
3797
|
-
if (!this.
|
|
3567
|
+
if (!this.Bb(maxQuantizedValue)) return false;
|
|
3798
3568
|
const q = this.y.quantizationBits();
|
|
3799
3569
|
return q >= 2 && q <= 30;
|
|
3800
3570
|
}
|
|
3801
3571
|
computeOriginalValue(predVals, predOffset, corrVals, corrOffset, outOrigVals, outOffset) {
|
|
3802
3572
|
const toolBox = this.y;
|
|
3803
3573
|
const center = toolBox.e;
|
|
3804
|
-
const maxQuantizedValue = toolBox.
|
|
3574
|
+
const maxQuantizedValue = toolBox.qa;
|
|
3805
3575
|
const corrS = corrVals[corrOffset];
|
|
3806
3576
|
const corrT = corrVals[corrOffset + 1];
|
|
3807
3577
|
let predS = predVals[predOffset] - center;
|
|
@@ -3929,7 +3699,7 @@ var PredictionSchemeNormalOctahedronCanonicalizedDecodingTransform = class exten
|
|
|
3929
3699
|
computeOriginalValuesDelta(inCorr, outData, size, numComponents) {
|
|
3930
3700
|
const toolBox = this.y;
|
|
3931
3701
|
const center = toolBox.e;
|
|
3932
|
-
const maxQuantizedValue = toolBox.
|
|
3702
|
+
const maxQuantizedValue = toolBox.qa;
|
|
3933
3703
|
let prevS = 0;
|
|
3934
3704
|
let prevT = 0;
|
|
3935
3705
|
for (let i = 0; i < size; i += numComponents) {
|
|
@@ -4058,17 +3828,17 @@ var PredictionSchemeNormalOctahedronCanonicalizedDecodingTransform = class exten
|
|
|
4058
3828
|
// src/decoder/compression/attributes/prediction_schemes/PredictionSchemeNormalOctahedronDecodingTransform.ts
|
|
4059
3829
|
var PredictionSchemeNormalOctahedronDecodingTransform = class extends PredictionSchemeNormalOctahedronTransformBase {
|
|
4060
3830
|
getType() {
|
|
4061
|
-
return
|
|
3831
|
+
return 2 /* PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON */;
|
|
4062
3832
|
}
|
|
4063
3833
|
decodeTransformData(buffer) {
|
|
4064
3834
|
const maxQuantizedValue = buffer.decodeInt32();
|
|
4065
3835
|
if (maxQuantizedValue === void 0) return false;
|
|
4066
|
-
return this.
|
|
3836
|
+
return this.Bb(maxQuantizedValue);
|
|
4067
3837
|
}
|
|
4068
3838
|
computeOriginalValue(predVals, predOffset, corrVals, corrOffset, outOrigVals, outOffset) {
|
|
4069
3839
|
const toolBox = this.y;
|
|
4070
3840
|
const center = toolBox.e;
|
|
4071
|
-
const maxQuantizedValue = toolBox.
|
|
3841
|
+
const maxQuantizedValue = toolBox.qa;
|
|
4072
3842
|
const predS = predVals[predOffset] - center;
|
|
4073
3843
|
const predT = predVals[predOffset + 1] - center;
|
|
4074
3844
|
const corrS = corrVals[corrOffset];
|
|
@@ -4147,28 +3917,34 @@ var PredictionSchemeNormalOctahedronDecodingTransform = class extends Prediction
|
|
|
4147
3917
|
|
|
4148
3918
|
// src/decoder/compression/attributes/SequentialNormalAttributeDecoder.ts
|
|
4149
3919
|
var SequentialNormalAttributeDecoder = class extends SequentialIntegerAttributeDecoder {
|
|
4150
|
-
|
|
3920
|
+
J = -1;
|
|
4151
3921
|
init(decoder, attributeId) {
|
|
4152
3922
|
if (!super.init(decoder, attributeId)) {
|
|
4153
3923
|
return false;
|
|
4154
3924
|
}
|
|
4155
|
-
return this.attribute.numComponents === 3 && this.attribute.dataType ===
|
|
3925
|
+
return this.attribute.numComponents === 3 && this.attribute.dataType === 9 /* FLOAT32 */;
|
|
4156
3926
|
}
|
|
4157
3927
|
// Normals quantize into two octahedral components.
|
|
4158
3928
|
getNumValueComponents() {
|
|
4159
3929
|
return 2;
|
|
4160
3930
|
}
|
|
3931
|
+
// The octahedral quantization bits (AttributeOctahedronTransform::DecodeParameters).
|
|
4161
3932
|
decodeDataNeededByPortableTransform(_pointIds, buffer) {
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
return
|
|
3933
|
+
const qBits = buffer.decodeUint8();
|
|
3934
|
+
if (qBits === void 0) return false;
|
|
3935
|
+
this.J = qBits;
|
|
3936
|
+
return true;
|
|
4166
3937
|
}
|
|
4167
|
-
|
|
4168
|
-
|
|
3938
|
+
// The octahedral-to-unit-vector transform is deferred to extractTo (see
|
|
3939
|
+
// PointAttribute.setLazyOctahedron).
|
|
3940
|
+
_a(_numPoints) {
|
|
3941
|
+
const q = this.J;
|
|
3942
|
+
if (q < 2 || q > 30) return false;
|
|
3943
|
+
this.attribute.setLazyOctahedron(this.R, Math.fround(2 / Math.fround((1 << q) - 2)));
|
|
3944
|
+
return true;
|
|
4169
3945
|
}
|
|
4170
3946
|
createIntPredictionScheme(method, transformType) {
|
|
4171
|
-
const transform = transformType ===
|
|
3947
|
+
const transform = transformType === 2 /* PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON */ ? new PredictionSchemeNormalOctahedronDecodingTransform() : transformType === 3 /* PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON_CANONICALIZED */ ? new PredictionSchemeNormalOctahedronCanonicalizedDecodingTransform() : null;
|
|
4172
3948
|
if (transform === null) {
|
|
4173
3949
|
return null;
|
|
4174
3950
|
}
|
|
@@ -4176,110 +3952,53 @@ var SequentialNormalAttributeDecoder = class extends SequentialIntegerAttributeD
|
|
|
4176
3952
|
}
|
|
4177
3953
|
};
|
|
4178
3954
|
|
|
4179
|
-
// src/decoder/attributes/AttributeQuantizationTransform.ts
|
|
4180
|
-
var AttributeQuantizationTransform = class extends AttributeTransform {
|
|
4181
|
-
x = -1;
|
|
4182
|
-
na = [];
|
|
4183
|
-
Pa = 0;
|
|
4184
|
-
copyToAttributeTransformData(outData) {
|
|
4185
|
-
outData.transformType = AttributeTransformType.QUANTIZATION_TRANSFORM;
|
|
4186
|
-
outData.appendParameterValue(this.x, "int32");
|
|
4187
|
-
for (let i = 0; i < this.na.length; i++) {
|
|
4188
|
-
outData.appendParameterValue(this.na[i], "float32");
|
|
4189
|
-
}
|
|
4190
|
-
outData.appendParameterValue(this.Pa, "float32");
|
|
4191
|
-
}
|
|
4192
|
-
decodeParameters(attribute, decoderBuffer) {
|
|
4193
|
-
const numComponents = attribute.numComponents;
|
|
4194
|
-
this.na = new Array(numComponents);
|
|
4195
|
-
for (let i = 0; i < numComponents; i++) {
|
|
4196
|
-
const val = decoderBuffer.decodeFloat32();
|
|
4197
|
-
if (val === void 0) return false;
|
|
4198
|
-
this.na[i] = val;
|
|
4199
|
-
}
|
|
4200
|
-
const range = decoderBuffer.decodeFloat32();
|
|
4201
|
-
if (range === void 0) return false;
|
|
4202
|
-
this.Pa = range;
|
|
4203
|
-
const qBits = decoderBuffer.decodeUint8();
|
|
4204
|
-
if (qBits === void 0 || qBits < 1 || qBits > 30) return false;
|
|
4205
|
-
this.x = qBits;
|
|
4206
|
-
return true;
|
|
4207
|
-
}
|
|
4208
|
-
inverseTransformAttribute(attribute, targetAttribute) {
|
|
4209
|
-
if (targetAttribute.dataType !== DataType.FLOAT32) {
|
|
4210
|
-
return false;
|
|
4211
|
-
}
|
|
4212
|
-
const maxQuantizedValue = (1 << this.x >>> 0) - 1;
|
|
4213
|
-
if (maxQuantizedValue <= 0) return false;
|
|
4214
|
-
const delta = Math.fround(this.Pa / Math.fround(maxQuantizedValue));
|
|
4215
|
-
const numComponents = targetAttribute.numComponents;
|
|
4216
|
-
const numValues = targetAttribute.size;
|
|
4217
|
-
const total = numValues * numComponents;
|
|
4218
|
-
const minValues = this.na;
|
|
4219
|
-
const srcData = attribute.buffer.data;
|
|
4220
|
-
const srcI32 = new Int32Array(srcData.buffer, srcData.byteOffset + attribute.byteOffset, total);
|
|
4221
|
-
const dstData = targetAttribute.buffer.data;
|
|
4222
|
-
const dstF32 = new Float32Array(dstData.buffer, dstData.byteOffset + targetAttribute.byteOffset, total);
|
|
4223
|
-
const fround = Math.fround;
|
|
4224
|
-
if (numComponents === 3) {
|
|
4225
|
-
const m0 = minValues[0], m1 = minValues[1], m2 = minValues[2];
|
|
4226
|
-
for (let o2 = 0; o2 < total; o2 += 3) {
|
|
4227
|
-
dstF32[o2] = fround(fround(srcI32[o2]) * delta) + m0;
|
|
4228
|
-
dstF32[o2 + 1] = fround(fround(srcI32[o2 + 1]) * delta) + m1;
|
|
4229
|
-
dstF32[o2 + 2] = fround(fround(srcI32[o2 + 2]) * delta) + m2;
|
|
4230
|
-
}
|
|
4231
|
-
return true;
|
|
4232
|
-
}
|
|
4233
|
-
if (numComponents === 2) {
|
|
4234
|
-
const m0 = minValues[0], m1 = minValues[1];
|
|
4235
|
-
for (let o2 = 0; o2 < total; o2 += 2) {
|
|
4236
|
-
dstF32[o2] = fround(fround(srcI32[o2]) * delta) + m0;
|
|
4237
|
-
dstF32[o2 + 1] = fround(fround(srcI32[o2 + 1]) * delta) + m1;
|
|
4238
|
-
}
|
|
4239
|
-
return true;
|
|
4240
|
-
}
|
|
4241
|
-
let o = 0;
|
|
4242
|
-
for (let i = 0; i < numValues; i++) {
|
|
4243
|
-
for (let c = 0; c < numComponents; c++) {
|
|
4244
|
-
dstF32[o] = fround(fround(srcI32[o]) * delta) + minValues[c];
|
|
4245
|
-
o++;
|
|
4246
|
-
}
|
|
4247
|
-
}
|
|
4248
|
-
return true;
|
|
4249
|
-
}
|
|
4250
|
-
};
|
|
4251
|
-
|
|
4252
3955
|
// src/decoder/compression/attributes/SequentialQuantizationAttributeDecoder.ts
|
|
4253
3956
|
var SequentialQuantizationAttributeDecoder = class extends SequentialIntegerAttributeDecoder {
|
|
4254
|
-
|
|
3957
|
+
J = -1;
|
|
3958
|
+
$a = [];
|
|
3959
|
+
Cb = 0;
|
|
4255
3960
|
init(decoder, attributeId) {
|
|
4256
3961
|
if (!super.init(decoder, attributeId)) {
|
|
4257
3962
|
return false;
|
|
4258
3963
|
}
|
|
4259
|
-
return this.attribute.dataType ===
|
|
3964
|
+
return this.attribute.dataType === 9 /* FLOAT32 */;
|
|
4260
3965
|
}
|
|
3966
|
+
// The quantization parameters (AttributeQuantizationTransform::DecodeParameters).
|
|
4261
3967
|
decodeDataNeededByPortableTransform(_pointIds, buffer) {
|
|
4262
|
-
const
|
|
4263
|
-
|
|
4264
|
-
|
|
3968
|
+
const numComponents = this.attribute.numComponents;
|
|
3969
|
+
this.$a = new Array(numComponents);
|
|
3970
|
+
for (let i = 0; i < numComponents; i++) {
|
|
3971
|
+
const val = buffer.decodeFloat32();
|
|
3972
|
+
if (val === void 0) return false;
|
|
3973
|
+
this.$a[i] = val;
|
|
4265
3974
|
}
|
|
4266
|
-
|
|
3975
|
+
const range = buffer.decodeFloat32();
|
|
3976
|
+
if (range === void 0) return false;
|
|
3977
|
+
this.Cb = range;
|
|
3978
|
+
const qBits = buffer.decodeUint8();
|
|
3979
|
+
if (qBits === void 0 || qBits < 1 || qBits > 30) return false;
|
|
3980
|
+
this.J = qBits;
|
|
3981
|
+
return true;
|
|
4267
3982
|
}
|
|
4268
|
-
//
|
|
4269
|
-
|
|
4270
|
-
|
|
3983
|
+
// Dequantization is deferred to extractTo (see PointAttribute.setLazyQuantized).
|
|
3984
|
+
_a(_numValues) {
|
|
3985
|
+
const maxQuantizedValue = (1 << this.J >>> 0) - 1;
|
|
3986
|
+
if (maxQuantizedValue <= 0) return false;
|
|
3987
|
+
const delta = Math.fround(this.Cb / Math.fround(maxQuantizedValue));
|
|
3988
|
+
this.attribute.setLazyQuantized(this.R, this.$a, delta);
|
|
3989
|
+
return true;
|
|
4271
3990
|
}
|
|
4272
3991
|
};
|
|
4273
3992
|
|
|
4274
3993
|
// src/decoder/compression/attributes/SequentialAttributeDecodersController.ts
|
|
4275
3994
|
var SequentialAttributeDecodersController = class extends AttributesDecoder {
|
|
4276
|
-
|
|
3995
|
+
va = [];
|
|
4277
3996
|
// Replaced by the sequencer's output in _prepareSequence.
|
|
4278
|
-
|
|
4279
|
-
|
|
3997
|
+
La = new Int32Array(0);
|
|
3998
|
+
S;
|
|
4280
3999
|
constructor(sequencer) {
|
|
4281
4000
|
super();
|
|
4282
|
-
this.
|
|
4001
|
+
this.S = sequencer;
|
|
4283
4002
|
}
|
|
4284
4003
|
decodeAttributesDecoderData(buffer) {
|
|
4285
4004
|
if (!super.decodeAttributesDecoderData(buffer)) {
|
|
@@ -4293,19 +4012,19 @@ var SequentialAttributeDecodersController = class extends AttributesDecoder {
|
|
|
4293
4012
|
if (decoder === null || !decoder.init(this.getDecoder(), this.getAttributeId(i))) {
|
|
4294
4013
|
return false;
|
|
4295
4014
|
}
|
|
4296
|
-
this.
|
|
4015
|
+
this.va[i] = decoder;
|
|
4297
4016
|
}
|
|
4298
4017
|
return true;
|
|
4299
4018
|
}
|
|
4300
|
-
|
|
4301
|
-
if (!this.
|
|
4019
|
+
cc() {
|
|
4020
|
+
if (!this.S.generateSequence()) {
|
|
4302
4021
|
return false;
|
|
4303
4022
|
}
|
|
4304
|
-
this.
|
|
4023
|
+
this.La = this.S.getOutputPointIds();
|
|
4305
4024
|
const numAttributes = this.getNumAttributes();
|
|
4306
4025
|
for (let i = 0; i < numAttributes; i++) {
|
|
4307
4026
|
const pa = this.getDecoder().pointCloud().attribute(this.getAttributeId(i));
|
|
4308
|
-
if (!this.
|
|
4027
|
+
if (!this.S.updatePointToAttributeIndexMapping(pa)) {
|
|
4309
4028
|
return false;
|
|
4310
4029
|
}
|
|
4311
4030
|
}
|
|
@@ -4319,24 +4038,24 @@ var SequentialAttributeDecodersController = class extends AttributesDecoder {
|
|
|
4319
4038
|
// of the finish work reads the buffer, and dependents only read parent
|
|
4320
4039
|
// portable VALUES in finish, so ordering and output stay identical.
|
|
4321
4040
|
decodeAttributesParse(buffer) {
|
|
4322
|
-
if (!this.
|
|
4041
|
+
if (!this.cc()) {
|
|
4323
4042
|
return false;
|
|
4324
4043
|
}
|
|
4325
|
-
const decoders = this.
|
|
4044
|
+
const decoders = this.va;
|
|
4326
4045
|
for (let i = 0; i < decoders.length; i++) {
|
|
4327
|
-
if (!decoders[i].decodePortableAttributeParse(this.
|
|
4046
|
+
if (!decoders[i].decodePortableAttributeParse(this.La, buffer)) {
|
|
4328
4047
|
return false;
|
|
4329
4048
|
}
|
|
4330
4049
|
}
|
|
4331
4050
|
for (let i = 0; i < decoders.length; i++) {
|
|
4332
|
-
if (!decoders[i].decodeDataNeededByPortableTransform(this.
|
|
4051
|
+
if (!decoders[i].decodeDataNeededByPortableTransform(this.La, buffer)) {
|
|
4333
4052
|
return false;
|
|
4334
4053
|
}
|
|
4335
4054
|
}
|
|
4336
4055
|
return true;
|
|
4337
4056
|
}
|
|
4338
4057
|
collectPendingSymbolStreams(out) {
|
|
4339
|
-
const decoders = this.
|
|
4058
|
+
const decoders = this.va;
|
|
4340
4059
|
for (let i = 0; i < decoders.length; i++) {
|
|
4341
4060
|
const pending = decoders[i].pendingSymbolStream();
|
|
4342
4061
|
if (pending !== null) {
|
|
@@ -4345,14 +4064,14 @@ var SequentialAttributeDecodersController = class extends AttributesDecoder {
|
|
|
4345
4064
|
}
|
|
4346
4065
|
}
|
|
4347
4066
|
decodeAttributesFinish() {
|
|
4348
|
-
const decoders = this.
|
|
4067
|
+
const decoders = this.va;
|
|
4349
4068
|
for (let i = 0; i < decoders.length; i++) {
|
|
4350
4069
|
if (!decoders[i].decodePortableAttributeFinish()) {
|
|
4351
4070
|
return false;
|
|
4352
4071
|
}
|
|
4353
4072
|
}
|
|
4354
4073
|
for (let i = 0; i < decoders.length; i++) {
|
|
4355
|
-
if (!decoders[i].transformAttributeToOriginalFormat(this.
|
|
4074
|
+
if (!decoders[i].transformAttributeToOriginalFormat(this.La)) {
|
|
4356
4075
|
return false;
|
|
4357
4076
|
}
|
|
4358
4077
|
}
|
|
@@ -4363,17 +4082,17 @@ var SequentialAttributeDecodersController = class extends AttributesDecoder {
|
|
|
4363
4082
|
if (locId < 0) {
|
|
4364
4083
|
return null;
|
|
4365
4084
|
}
|
|
4366
|
-
return this.
|
|
4085
|
+
return this.va[locId].getPortableAttribute();
|
|
4367
4086
|
}
|
|
4368
4087
|
createSequentialDecoder(decoderType) {
|
|
4369
4088
|
switch (decoderType) {
|
|
4370
|
-
case
|
|
4089
|
+
case 0 /* SEQUENTIAL_ATTRIBUTE_ENCODER_GENERIC */:
|
|
4371
4090
|
return new SequentialAttributeDecoder();
|
|
4372
|
-
case
|
|
4091
|
+
case 1 /* SEQUENTIAL_ATTRIBUTE_ENCODER_INTEGER */:
|
|
4373
4092
|
return new SequentialIntegerAttributeDecoder();
|
|
4374
|
-
case
|
|
4093
|
+
case 2 /* SEQUENTIAL_ATTRIBUTE_ENCODER_QUANTIZATION */:
|
|
4375
4094
|
return new SequentialQuantizationAttributeDecoder();
|
|
4376
|
-
case
|
|
4095
|
+
case 3 /* SEQUENTIAL_ATTRIBUTE_ENCODER_NORMALS */:
|
|
4377
4096
|
return new SequentialNormalAttributeDecoder();
|
|
4378
4097
|
}
|
|
4379
4098
|
return null;
|
|
@@ -4402,27 +4121,27 @@ var kInvalidFaceIndex = -1;
|
|
|
4402
4121
|
var kInvalidVertexIndex2 = -1;
|
|
4403
4122
|
var DepthFirstTraverser = class {
|
|
4404
4123
|
a = null;
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4124
|
+
wa = null;
|
|
4125
|
+
T = null;
|
|
4126
|
+
Db = [];
|
|
4127
|
+
ea = 0;
|
|
4409
4128
|
// Identifies the traversal order for the shared traversal cache
|
|
4410
4129
|
// (MESH_TRAVERSAL_DEPTH_FIRST). See MeshTraversalSequencer.
|
|
4411
|
-
|
|
4130
|
+
Eb = 0;
|
|
4412
4131
|
// The sequencer derives the point id sequence from the corner map after
|
|
4413
4132
|
// the traversal (see traverseFromCorner).
|
|
4414
4133
|
emitsPointIds = false;
|
|
4415
4134
|
h = null;
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
|
|
4135
|
+
p = null;
|
|
4136
|
+
Fb = null;
|
|
4137
|
+
F = 0;
|
|
4419
4138
|
init(cornerTable, observer) {
|
|
4420
4139
|
this.a = cornerTable;
|
|
4421
|
-
this.
|
|
4140
|
+
this.wa = observer;
|
|
4422
4141
|
this.h = cornerTable.cornerToVertexArray();
|
|
4423
|
-
this.
|
|
4424
|
-
this.
|
|
4425
|
-
this.
|
|
4142
|
+
this.p = cornerTable.oppositeCornerArray();
|
|
4143
|
+
this.Fb = cornerTable.vertexLeftmostCornerArray();
|
|
4144
|
+
this.F = cornerTable.numCorners();
|
|
4426
4145
|
}
|
|
4427
4146
|
cornerTable() {
|
|
4428
4147
|
return this.a;
|
|
@@ -4436,8 +4155,8 @@ var DepthFirstTraverser = class {
|
|
|
4436
4155
|
// Decode-scoped scratch: released in bulk at the end of the decode.
|
|
4437
4156
|
onTraversalStart() {
|
|
4438
4157
|
const cornerTable = this.a;
|
|
4439
|
-
this.
|
|
4440
|
-
this.
|
|
4158
|
+
this.T = scratchUint8Zeroed(cornerTable.numFaces());
|
|
4159
|
+
this.Db = scratchInt32(this.F);
|
|
4441
4160
|
}
|
|
4442
4161
|
// Traverses every face, seeding a new traversal at the first corner of each
|
|
4443
4162
|
// face not yet reached. The visited check lives here rather than behind a
|
|
@@ -4446,8 +4165,8 @@ var DepthFirstTraverser = class {
|
|
|
4446
4165
|
// was measurable next to the traversal itself.
|
|
4447
4166
|
traverseAll() {
|
|
4448
4167
|
const numFaces = this.a.numFaces();
|
|
4449
|
-
const isFaceVisited = this.
|
|
4450
|
-
for (let f = 0; f < numFaces && this.
|
|
4168
|
+
const isFaceVisited = this.T;
|
|
4169
|
+
for (let f = 0; f < numFaces && this.ea < numFaces; ++f) {
|
|
4451
4170
|
if (isFaceVisited[f] === 0 && !this.traverseFromCorner(3 * f)) {
|
|
4452
4171
|
return false;
|
|
4453
4172
|
}
|
|
@@ -4455,19 +4174,19 @@ var DepthFirstTraverser = class {
|
|
|
4455
4174
|
return true;
|
|
4456
4175
|
}
|
|
4457
4176
|
traverseFromCorner(cornerId) {
|
|
4458
|
-
if (this.
|
|
4177
|
+
if (this.T[cornerId / 3 | 0]) {
|
|
4459
4178
|
return true;
|
|
4460
4179
|
}
|
|
4461
|
-
const isFaceVisited = this.
|
|
4462
|
-
const observer = this.
|
|
4180
|
+
const isFaceVisited = this.T;
|
|
4181
|
+
const observer = this.wa;
|
|
4463
4182
|
const cornerToVertex = this.h;
|
|
4464
|
-
const oppositeCorners = this.
|
|
4465
|
-
const vertexLeftmost = this.
|
|
4466
|
-
const stack = this.
|
|
4467
|
-
let numVisitedFaces = this.
|
|
4183
|
+
const oppositeCorners = this.p;
|
|
4184
|
+
const vertexLeftmost = this.Fb;
|
|
4185
|
+
const stack = this.Db;
|
|
4186
|
+
let numVisitedFaces = this.ea;
|
|
4468
4187
|
const encodingData = observer.z;
|
|
4469
|
-
const encodedToCornerMap = observer.
|
|
4470
|
-
const vertexToEncodedMap = observer.
|
|
4188
|
+
const encodedToCornerMap = observer.ab;
|
|
4189
|
+
const vertexToEncodedMap = observer.bb;
|
|
4471
4190
|
let numValues = encodingData.numValues;
|
|
4472
4191
|
let stackSize = 0;
|
|
4473
4192
|
stack[stackSize++] = cornerId;
|
|
@@ -4545,7 +4264,7 @@ var DepthFirstTraverser = class {
|
|
|
4545
4264
|
}
|
|
4546
4265
|
}
|
|
4547
4266
|
}
|
|
4548
|
-
this.
|
|
4267
|
+
this.ea = numVisitedFaces;
|
|
4549
4268
|
encodingData.numValues = numValues;
|
|
4550
4269
|
return true;
|
|
4551
4270
|
}
|
|
@@ -4557,51 +4276,51 @@ var kInvalidFaceIndex2 = -1;
|
|
|
4557
4276
|
var kMaxPriority = 3;
|
|
4558
4277
|
var MaxPredictionDegreeTraverser = class {
|
|
4559
4278
|
a = null;
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4279
|
+
wa = null;
|
|
4280
|
+
T = null;
|
|
4281
|
+
cb = null;
|
|
4282
|
+
ea = 0;
|
|
4564
4283
|
// One stack (bucket) per priority level [0, kMaxPriority).
|
|
4565
|
-
|
|
4566
|
-
|
|
4284
|
+
Ma = null;
|
|
4285
|
+
U = 0;
|
|
4567
4286
|
// Prediction degree accumulated per vertex during traversal.
|
|
4568
|
-
|
|
4287
|
+
db = null;
|
|
4569
4288
|
// Flat connectivity arrays (see DepthFirstTraverser for why).
|
|
4570
4289
|
h = null;
|
|
4571
|
-
|
|
4290
|
+
p = null;
|
|
4572
4291
|
// Identifies the traversal order for the shared traversal cache
|
|
4573
4292
|
// (MESH_TRAVERSAL_PREDICTION_DEGREE). See MeshTraversalSequencer.
|
|
4574
|
-
|
|
4293
|
+
Eb = 1;
|
|
4575
4294
|
// Point ids are appended through the observer as vertices are visited.
|
|
4576
4295
|
emitsPointIds = true;
|
|
4577
4296
|
init(cornerTable, observer) {
|
|
4578
4297
|
this.a = cornerTable;
|
|
4579
|
-
this.
|
|
4580
|
-
this.
|
|
4581
|
-
this.
|
|
4298
|
+
this.wa = observer;
|
|
4299
|
+
this.T = new Uint8Array(cornerTable.numFaces());
|
|
4300
|
+
this.cb = new Uint8Array(cornerTable.numVertices());
|
|
4582
4301
|
this.h = cornerTable.cornerToVertexArray();
|
|
4583
|
-
this.
|
|
4584
|
-
this.
|
|
4302
|
+
this.p = cornerTable.oppositeCornerArray();
|
|
4303
|
+
this.Ma = [[], [], []];
|
|
4585
4304
|
}
|
|
4586
4305
|
cornerTable() {
|
|
4587
4306
|
return this.a;
|
|
4588
4307
|
}
|
|
4589
4308
|
// corner is always valid (>= 0) where these are used.
|
|
4590
|
-
|
|
4309
|
+
Gb(c) {
|
|
4591
4310
|
return c % 3 === 2 ? c - 2 : c + 1;
|
|
4592
4311
|
}
|
|
4593
|
-
|
|
4312
|
+
Hb(c) {
|
|
4594
4313
|
return c % 3 === 0 ? c + 2 : c - 1;
|
|
4595
4314
|
}
|
|
4596
4315
|
onTraversalStart() {
|
|
4597
|
-
this.
|
|
4316
|
+
this.db = new Int32Array(this.a.numVertices());
|
|
4598
4317
|
}
|
|
4599
4318
|
// Same contract as DepthFirstTraverser.traverseAll. Seeds every face
|
|
4600
4319
|
// through traverseFromCorner (which re-checks the first face's vertices),
|
|
4601
4320
|
// exactly as the sequencer's loop always has.
|
|
4602
4321
|
traverseAll() {
|
|
4603
4322
|
const numFaces = this.a.numFaces();
|
|
4604
|
-
for (let f = 0; f < numFaces && this.
|
|
4323
|
+
for (let f = 0; f < numFaces && this.ea < numFaces; ++f) {
|
|
4605
4324
|
if (!this.traverseFromCorner(3 * f)) {
|
|
4606
4325
|
return false;
|
|
4607
4326
|
}
|
|
@@ -4610,11 +4329,11 @@ var MaxPredictionDegreeTraverser = class {
|
|
|
4610
4329
|
}
|
|
4611
4330
|
// Returns the priority of traversing the edge leading to cornerId. Mutates
|
|
4612
4331
|
// the prediction degree of the destination vertex.
|
|
4613
|
-
|
|
4332
|
+
Ib(cornerId) {
|
|
4614
4333
|
const vTip = this.h[cornerId];
|
|
4615
4334
|
let priority = 0;
|
|
4616
|
-
if (!this.
|
|
4617
|
-
const degree = ++this.
|
|
4335
|
+
if (!this.cb[vTip]) {
|
|
4336
|
+
const degree = ++this.db[vTip];
|
|
4618
4337
|
priority = degree > 1 ? 1 : 2;
|
|
4619
4338
|
}
|
|
4620
4339
|
if (priority >= kMaxPriority) {
|
|
@@ -4622,38 +4341,38 @@ var MaxPredictionDegreeTraverser = class {
|
|
|
4622
4341
|
}
|
|
4623
4342
|
return priority;
|
|
4624
4343
|
}
|
|
4625
|
-
|
|
4626
|
-
this.
|
|
4627
|
-
if (priority < this.
|
|
4628
|
-
this.
|
|
4344
|
+
Jb(ci, priority) {
|
|
4345
|
+
this.Ma[priority].push(ci);
|
|
4346
|
+
if (priority < this.U) {
|
|
4347
|
+
this.U = priority;
|
|
4629
4348
|
}
|
|
4630
4349
|
}
|
|
4631
4350
|
// Retrieves the next available corner to traverse, processed by priority.
|
|
4632
4351
|
// Returns kInvalidCornerIndex when no corner is available.
|
|
4633
|
-
|
|
4634
|
-
for (let i = this.
|
|
4635
|
-
const stack = this.
|
|
4352
|
+
dc() {
|
|
4353
|
+
for (let i = this.U; i < kMaxPriority; ++i) {
|
|
4354
|
+
const stack = this.Ma[i];
|
|
4636
4355
|
if (stack.length > 0) {
|
|
4637
4356
|
const ret = stack.pop();
|
|
4638
|
-
this.
|
|
4357
|
+
this.U = i;
|
|
4639
4358
|
return ret;
|
|
4640
4359
|
}
|
|
4641
4360
|
}
|
|
4642
4361
|
return kInvalidCornerIndex5;
|
|
4643
4362
|
}
|
|
4644
4363
|
traverseFromCorner(cornerId) {
|
|
4645
|
-
if (this.
|
|
4364
|
+
if (this.db.length === 0) {
|
|
4646
4365
|
return true;
|
|
4647
4366
|
}
|
|
4648
4367
|
const cornerToVertex = this.h;
|
|
4649
|
-
const oppositeCorners = this.
|
|
4650
|
-
const isFaceVisited = this.
|
|
4651
|
-
const isVertexVisited = this.
|
|
4652
|
-
const observer = this.
|
|
4653
|
-
this.
|
|
4654
|
-
this.
|
|
4655
|
-
const firstNext = this.
|
|
4656
|
-
const firstPrev = this.
|
|
4368
|
+
const oppositeCorners = this.p;
|
|
4369
|
+
const isFaceVisited = this.T;
|
|
4370
|
+
const isVertexVisited = this.cb;
|
|
4371
|
+
const observer = this.wa;
|
|
4372
|
+
this.Ma[0].push(cornerId);
|
|
4373
|
+
this.U = 0;
|
|
4374
|
+
const firstNext = this.Gb(cornerId);
|
|
4375
|
+
const firstPrev = this.Hb(cornerId);
|
|
4657
4376
|
const nextVert = cornerToVertex[firstNext];
|
|
4658
4377
|
const prevVert = cornerToVertex[firstPrev];
|
|
4659
4378
|
if (!isVertexVisited[nextVert]) {
|
|
@@ -4669,7 +4388,7 @@ var MaxPredictionDegreeTraverser = class {
|
|
|
4669
4388
|
isVertexVisited[tipVertex] = 1;
|
|
4670
4389
|
observer.onNewVertexVisited(tipVertex, cornerId);
|
|
4671
4390
|
}
|
|
4672
|
-
while ((cornerId = this.
|
|
4391
|
+
while ((cornerId = this.dc()) !== kInvalidCornerIndex5) {
|
|
4673
4392
|
let faceId = cornerId / 3 | 0;
|
|
4674
4393
|
if (isFaceVisited[faceId]) {
|
|
4675
4394
|
continue;
|
|
@@ -4677,34 +4396,34 @@ var MaxPredictionDegreeTraverser = class {
|
|
|
4677
4396
|
while (true) {
|
|
4678
4397
|
faceId = cornerId / 3 | 0;
|
|
4679
4398
|
isFaceVisited[faceId] = 1;
|
|
4680
|
-
this.
|
|
4399
|
+
this.ea++;
|
|
4681
4400
|
const vertId = cornerToVertex[cornerId];
|
|
4682
4401
|
if (!isVertexVisited[vertId]) {
|
|
4683
4402
|
isVertexVisited[vertId] = 1;
|
|
4684
4403
|
observer.onNewVertexVisited(vertId, cornerId);
|
|
4685
4404
|
}
|
|
4686
|
-
const rightCornerId = oppositeCorners[this.
|
|
4687
|
-
const leftCornerId = oppositeCorners[this.
|
|
4405
|
+
const rightCornerId = oppositeCorners[this.Gb(cornerId)];
|
|
4406
|
+
const leftCornerId = oppositeCorners[this.Hb(cornerId)];
|
|
4688
4407
|
const rightFaceId = rightCornerId === kInvalidCornerIndex5 ? kInvalidFaceIndex2 : rightCornerId / 3 | 0;
|
|
4689
4408
|
const leftFaceId = leftCornerId === kInvalidCornerIndex5 ? kInvalidFaceIndex2 : leftCornerId / 3 | 0;
|
|
4690
4409
|
const isRightFaceVisited = rightFaceId === kInvalidFaceIndex2 || isFaceVisited[rightFaceId] !== 0;
|
|
4691
4410
|
const isLeftFaceVisited = leftFaceId === kInvalidFaceIndex2 || isFaceVisited[leftFaceId] !== 0;
|
|
4692
4411
|
if (!isLeftFaceVisited) {
|
|
4693
|
-
const priority = this.
|
|
4694
|
-
if (isRightFaceVisited && priority <= this.
|
|
4412
|
+
const priority = this.Ib(leftCornerId);
|
|
4413
|
+
if (isRightFaceVisited && priority <= this.U) {
|
|
4695
4414
|
cornerId = leftCornerId;
|
|
4696
4415
|
continue;
|
|
4697
4416
|
} else {
|
|
4698
|
-
this.
|
|
4417
|
+
this.Jb(leftCornerId, priority);
|
|
4699
4418
|
}
|
|
4700
4419
|
}
|
|
4701
4420
|
if (!isRightFaceVisited) {
|
|
4702
|
-
const priority = this.
|
|
4703
|
-
if (priority <= this.
|
|
4421
|
+
const priority = this.Ib(rightCornerId);
|
|
4422
|
+
if (priority <= this.U) {
|
|
4704
4423
|
cornerId = rightCornerId;
|
|
4705
4424
|
continue;
|
|
4706
4425
|
} else {
|
|
4707
|
-
this.
|
|
4426
|
+
this.Jb(rightCornerId, priority);
|
|
4708
4427
|
}
|
|
4709
4428
|
}
|
|
4710
4429
|
break;
|
|
@@ -4717,66 +4436,66 @@ var MaxPredictionDegreeTraverser = class {
|
|
|
4717
4436
|
// src/decoder/compression/mesh/traverser/MeshAttributeIndicesEncodingObserver.ts
|
|
4718
4437
|
var MeshAttributeIndicesEncodingObserver = class {
|
|
4719
4438
|
z;
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
|
|
4439
|
+
S;
|
|
4440
|
+
bb;
|
|
4441
|
+
ab;
|
|
4442
|
+
Kb;
|
|
4724
4443
|
constructor(mesh, sequencer, encodingData) {
|
|
4725
4444
|
this.z = encodingData;
|
|
4726
|
-
this.
|
|
4727
|
-
this.
|
|
4728
|
-
this.
|
|
4729
|
-
this.
|
|
4445
|
+
this.S = sequencer;
|
|
4446
|
+
this.bb = encodingData.vertexToEncodedAttributeValueIndexMap;
|
|
4447
|
+
this.ab = encodingData.encodedAttributeValueIndexToCornerMap;
|
|
4448
|
+
this.Kb = mesh.faces_;
|
|
4730
4449
|
}
|
|
4731
4450
|
onNewVertexVisited(vertex, corner) {
|
|
4732
|
-
const pointId = this.
|
|
4733
|
-
this.
|
|
4451
|
+
const pointId = this.Kb[corner];
|
|
4452
|
+
this.S.addPointId(pointId);
|
|
4734
4453
|
const numValues = this.z.numValues;
|
|
4735
|
-
this.
|
|
4736
|
-
this.
|
|
4454
|
+
this.ab[numValues] = corner;
|
|
4455
|
+
this.bb[vertex] = numValues;
|
|
4737
4456
|
this.z.numValues++;
|
|
4738
4457
|
}
|
|
4739
4458
|
};
|
|
4740
4459
|
|
|
4741
4460
|
// src/decoder/compression/mesh/traverser/MeshTraversalSequencer.ts
|
|
4742
4461
|
var MeshTraversalSequencer = class {
|
|
4743
|
-
|
|
4462
|
+
D;
|
|
4744
4463
|
z;
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
|
|
4464
|
+
xa = null;
|
|
4465
|
+
u = new Int32Array(0);
|
|
4466
|
+
ya = 0;
|
|
4748
4467
|
// Per-decode cache, keyed by corner table, shared across the attribute
|
|
4749
4468
|
// decoders of one mesh (see MeshEdgebreakerDecoderImpl).
|
|
4750
|
-
|
|
4469
|
+
eb;
|
|
4751
4470
|
// The cache entry the last generateSequence resolved to (hit or store);
|
|
4752
4471
|
// carries the shared indicesMap.
|
|
4753
|
-
|
|
4472
|
+
fb = null;
|
|
4754
4473
|
// One representative corner per point id, when the connectivity decoder
|
|
4755
4474
|
// recorded them (see MeshEdgebreakerDecoderImpl._assignAttributeVerticesAndPoints).
|
|
4756
|
-
|
|
4475
|
+
fa;
|
|
4757
4476
|
constructor(mesh, encodingData, traversalCache, pointCorner) {
|
|
4758
|
-
this.
|
|
4477
|
+
this.D = mesh;
|
|
4759
4478
|
this.z = encodingData;
|
|
4760
|
-
this.
|
|
4761
|
-
this.
|
|
4479
|
+
this.eb = traversalCache;
|
|
4480
|
+
this.fa = pointCorner;
|
|
4762
4481
|
}
|
|
4763
4482
|
setTraverser(traverser) {
|
|
4764
|
-
this.
|
|
4483
|
+
this.xa = traverser;
|
|
4765
4484
|
}
|
|
4766
4485
|
generateSequence() {
|
|
4767
|
-
const cornerTable = this.
|
|
4768
|
-
const methodId = this.
|
|
4486
|
+
const cornerTable = this.xa.cornerTable();
|
|
4487
|
+
const methodId = this.xa.Eb;
|
|
4769
4488
|
const cacheKey = cornerTable.cornerToVertexArray();
|
|
4770
4489
|
const encodingData = this.z;
|
|
4771
|
-
let byMethod = this.
|
|
4490
|
+
let byMethod = this.eb.get(cacheKey);
|
|
4772
4491
|
const cached = byMethod && byMethod.get(methodId);
|
|
4773
4492
|
if (cached !== void 0) {
|
|
4774
|
-
this.
|
|
4493
|
+
this.u = cached.pointIds;
|
|
4775
4494
|
encodingData.adoptTraversalResult(cached.vertexMap, cached.cornerMap, cached.numValues);
|
|
4776
|
-
this.
|
|
4495
|
+
this.fb = cached;
|
|
4777
4496
|
return true;
|
|
4778
4497
|
}
|
|
4779
|
-
if (!this.
|
|
4498
|
+
if (!this.ec()) {
|
|
4780
4499
|
return false;
|
|
4781
4500
|
}
|
|
4782
4501
|
const numValues = encodingData.numValues;
|
|
@@ -4788,39 +4507,39 @@ var MeshTraversalSequencer = class {
|
|
|
4788
4507
|
}
|
|
4789
4508
|
if (byMethod === void 0) {
|
|
4790
4509
|
byMethod = /* @__PURE__ */ new Map();
|
|
4791
|
-
this.
|
|
4510
|
+
this.eb.set(cacheKey, byMethod);
|
|
4792
4511
|
}
|
|
4793
4512
|
const entry = {
|
|
4794
|
-
pointIds: this.
|
|
4513
|
+
pointIds: this.u,
|
|
4795
4514
|
vertexMap: encodingData.vertexToEncodedAttributeValueIndexMap,
|
|
4796
4515
|
cornerMap: encodingData.encodedAttributeValueIndexToCornerMap,
|
|
4797
4516
|
numValues,
|
|
4798
4517
|
indicesMap: null
|
|
4799
4518
|
};
|
|
4800
4519
|
byMethod.set(methodId, entry);
|
|
4801
|
-
this.
|
|
4520
|
+
this.fb = entry;
|
|
4802
4521
|
return true;
|
|
4803
4522
|
}
|
|
4804
4523
|
getOutputPointIds() {
|
|
4805
|
-
return this.
|
|
4524
|
+
return this.u;
|
|
4806
4525
|
}
|
|
4807
4526
|
addPointId(pointId) {
|
|
4808
|
-
this.
|
|
4527
|
+
this.u[this.ya++] = pointId;
|
|
4809
4528
|
}
|
|
4810
4529
|
updatePointToAttributeIndexMapping(attribute) {
|
|
4811
|
-
const entry = this.
|
|
4530
|
+
const entry = this.fb;
|
|
4812
4531
|
if (entry !== null && entry.indicesMap !== null) {
|
|
4813
4532
|
attribute.setExplicitMappingShared(entry.indicesMap);
|
|
4814
4533
|
return true;
|
|
4815
4534
|
}
|
|
4816
|
-
const cornerTable = this.
|
|
4817
|
-
const numFaces = this.
|
|
4818
|
-
const numPoints = this.
|
|
4535
|
+
const cornerTable = this.xa.cornerTable();
|
|
4536
|
+
const numFaces = this.D.numFaces();
|
|
4537
|
+
const numPoints = this.D.numPoints();
|
|
4819
4538
|
attribute.setExplicitMappingUnfilled(numPoints);
|
|
4820
4539
|
const cornerToVertex = cornerTable.cornerToVertexArray();
|
|
4821
4540
|
const vertexToAttEntry = this.z.vertexToEncodedAttributeValueIndexMap;
|
|
4822
4541
|
const indicesMap = attribute.indicesMap;
|
|
4823
|
-
const pointCorner = this.
|
|
4542
|
+
const pointCorner = this.fa;
|
|
4824
4543
|
if (pointCorner !== null) {
|
|
4825
4544
|
for (let p = 0; p < numPoints; ++p) {
|
|
4826
4545
|
const vertId = cornerToVertex[pointCorner[p]];
|
|
@@ -4835,7 +4554,7 @@ var MeshTraversalSequencer = class {
|
|
|
4835
4554
|
}
|
|
4836
4555
|
} else {
|
|
4837
4556
|
const numCorners = numFaces * 3;
|
|
4838
|
-
const faces = this.
|
|
4557
|
+
const faces = this.D.faces_;
|
|
4839
4558
|
for (let ci = 0; ci < numCorners; ++ci) {
|
|
4840
4559
|
const vertId = cornerToVertex[ci];
|
|
4841
4560
|
if (vertId < 0) {
|
|
@@ -4854,10 +4573,10 @@ var MeshTraversalSequencer = class {
|
|
|
4854
4573
|
}
|
|
4855
4574
|
return true;
|
|
4856
4575
|
}
|
|
4857
|
-
|
|
4858
|
-
this.
|
|
4859
|
-
this.
|
|
4860
|
-
const traverser = this.
|
|
4576
|
+
ec() {
|
|
4577
|
+
this.ya = 0;
|
|
4578
|
+
this.u = scratchInt32(this.D.numPoints());
|
|
4579
|
+
const traverser = this.xa;
|
|
4861
4580
|
traverser.onTraversalStart();
|
|
4862
4581
|
if (!traverser.traverseAll()) {
|
|
4863
4582
|
return false;
|
|
@@ -4865,15 +4584,15 @@ var MeshTraversalSequencer = class {
|
|
|
4865
4584
|
if (!traverser.emitsPointIds) {
|
|
4866
4585
|
const numValues = this.z.numValues;
|
|
4867
4586
|
const cornerMap = this.z.encodedAttributeValueIndexToCornerMap;
|
|
4868
|
-
const faces = this.
|
|
4869
|
-
const outPointIds = this.
|
|
4587
|
+
const faces = this.D.faces_;
|
|
4588
|
+
const outPointIds = this.u;
|
|
4870
4589
|
for (let i = 0; i < numValues; ++i) {
|
|
4871
4590
|
outPointIds[i] = faces[cornerMap[i]];
|
|
4872
4591
|
}
|
|
4873
|
-
this.
|
|
4592
|
+
this.ya = numValues;
|
|
4874
4593
|
}
|
|
4875
|
-
if (this.
|
|
4876
|
-
this.
|
|
4594
|
+
if (this.ya < this.u.length) {
|
|
4595
|
+
this.u = this.u.subarray(0, this.ya);
|
|
4877
4596
|
}
|
|
4878
4597
|
return true;
|
|
4879
4598
|
}
|
|
@@ -4882,36 +4601,38 @@ var MeshTraversalSequencer = class {
|
|
|
4882
4601
|
// src/decoder/compression/mesh/MeshEdgebreakerDecoderImpl.ts
|
|
4883
4602
|
var kInvalidCornerIndex6 = -1;
|
|
4884
4603
|
var MeshEdgebreakerDecoderImpl = class {
|
|
4885
|
-
|
|
4604
|
+
l;
|
|
4886
4605
|
a = null;
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4606
|
+
K = [];
|
|
4607
|
+
ga = new Uint8Array(0);
|
|
4608
|
+
V = 0;
|
|
4609
|
+
gb = new MeshAttributeIndicesEncodingData();
|
|
4610
|
+
Lb = -1;
|
|
4892
4611
|
// Cache of vertex-traversal results keyed by corner table, so attributes
|
|
4893
4612
|
// sharing connectivity traverse once.
|
|
4894
|
-
|
|
4613
|
+
fc = /* @__PURE__ */ new Map();
|
|
4895
4614
|
g = [];
|
|
4896
|
-
|
|
4615
|
+
G;
|
|
4897
4616
|
// One corner per point id (decode-scoped scratch), filled by
|
|
4898
4617
|
// _assignAttributeVerticesAndPoints; null when points are the base vertices.
|
|
4899
|
-
|
|
4618
|
+
fa = null;
|
|
4619
|
+
// Corners on a boundary edge, counted by _decodeAttributeConnectivities.
|
|
4620
|
+
Mb = 0;
|
|
4900
4621
|
constructor(decoder, TraversalDecoderClass) {
|
|
4901
|
-
this.
|
|
4902
|
-
this.
|
|
4622
|
+
this.l = decoder;
|
|
4623
|
+
this.G = new TraversalDecoderClass();
|
|
4903
4624
|
}
|
|
4904
4625
|
getCornerTable() {
|
|
4905
4626
|
return this.a;
|
|
4906
4627
|
}
|
|
4907
4628
|
// The attribute data set whose attributes decoder owns attId, if any.
|
|
4908
|
-
|
|
4629
|
+
Nb(attId) {
|
|
4909
4630
|
for (let i = 0; i < this.g.length; ++i) {
|
|
4910
4631
|
const ad = this.g[i];
|
|
4911
|
-
if (ad.decoderId < 0 || ad.decoderId >= this.
|
|
4632
|
+
if (ad.decoderId < 0 || ad.decoderId >= this.l.numAttributesDecoders()) {
|
|
4912
4633
|
continue;
|
|
4913
4634
|
}
|
|
4914
|
-
const dec = this.
|
|
4635
|
+
const dec = this.l.attributesDecoder(ad.decoderId);
|
|
4915
4636
|
for (let j = 0; j < dec.getNumAttributes(); ++j) {
|
|
4916
4637
|
if (dec.getAttributeId(j) === attId) {
|
|
4917
4638
|
return ad;
|
|
@@ -4921,16 +4642,17 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
4921
4642
|
return null;
|
|
4922
4643
|
}
|
|
4923
4644
|
getAttributeCornerTable(attId) {
|
|
4924
|
-
const ad = this.
|
|
4645
|
+
const ad = this.Nb(attId);
|
|
4925
4646
|
return ad !== null && ad.isConnectivityUsed ? ad.connectivityData : null;
|
|
4926
4647
|
}
|
|
4927
4648
|
getAttributeEncodingData(attId) {
|
|
4928
|
-
const ad = this.
|
|
4929
|
-
return ad !== null ? ad.encodingData : this.
|
|
4649
|
+
const ad = this.Nb(attId);
|
|
4650
|
+
return ad !== null ? ad.encodingData : this.gb;
|
|
4930
4651
|
}
|
|
4931
4652
|
createAttributesDecoder(attDecoderId) {
|
|
4932
|
-
const buffer = this.
|
|
4933
|
-
|
|
4653
|
+
const buffer = this.l.buffer();
|
|
4654
|
+
let attDataId = buffer.decodeUint8();
|
|
4655
|
+
if (attDataId !== void 0) attDataId = attDataId << 24 >> 24;
|
|
4934
4656
|
if (attDataId === void 0) return false;
|
|
4935
4657
|
const decoderType = buffer.decodeUint8();
|
|
4936
4658
|
if (decoderType === void 0) return false;
|
|
@@ -4943,55 +4665,57 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
4943
4665
|
}
|
|
4944
4666
|
this.g[attDataId].decoderId = attDecoderId;
|
|
4945
4667
|
} else {
|
|
4946
|
-
if (this.
|
|
4668
|
+
if (this.Lb >= 0) {
|
|
4947
4669
|
return false;
|
|
4948
4670
|
}
|
|
4949
|
-
this.
|
|
4671
|
+
this.Lb = attDecoderId;
|
|
4950
4672
|
}
|
|
4951
4673
|
const traversalMethod = buffer.decodeUint8();
|
|
4952
|
-
if (traversalMethod === void 0 || traversalMethod >=
|
|
4674
|
+
if (traversalMethod === void 0 || traversalMethod >= 2 /* NUM_TRAVERSAL_METHODS */) {
|
|
4953
4675
|
return false;
|
|
4954
4676
|
}
|
|
4955
4677
|
let encodingData;
|
|
4956
4678
|
let cornerTable;
|
|
4957
|
-
if (decoderType ===
|
|
4679
|
+
if (decoderType === 0 /* MESH_VERTEX_ATTRIBUTE */) {
|
|
4958
4680
|
if (attDataId < 0) {
|
|
4959
|
-
encodingData = this.
|
|
4681
|
+
encodingData = this.gb;
|
|
4960
4682
|
} else {
|
|
4961
4683
|
encodingData = this.g[attDataId].encodingData;
|
|
4962
4684
|
this.g[attDataId].isConnectivityUsed = false;
|
|
4963
4685
|
}
|
|
4964
4686
|
cornerTable = this.a;
|
|
4965
4687
|
} else {
|
|
4966
|
-
if (traversalMethod !==
|
|
4688
|
+
if (traversalMethod !== 0 /* MESH_TRAVERSAL_DEPTH_FIRST */ || attDataId < 0) {
|
|
4967
4689
|
return false;
|
|
4968
4690
|
}
|
|
4969
|
-
|
|
4970
|
-
|
|
4691
|
+
const ad = this.g[attDataId];
|
|
4692
|
+
if (ad.noInteriorSeams) this.gc(ad);
|
|
4693
|
+
encodingData = ad.encodingData;
|
|
4694
|
+
cornerTable = ad.connectivityData;
|
|
4971
4695
|
}
|
|
4972
|
-
const mesh = this.
|
|
4973
|
-
const sequencer = new MeshTraversalSequencer(mesh, encodingData, this.
|
|
4696
|
+
const mesh = this.l.mesh();
|
|
4697
|
+
const sequencer = new MeshTraversalSequencer(mesh, encodingData, this.fc, this.fa);
|
|
4974
4698
|
const observer = new MeshAttributeIndicesEncodingObserver(mesh, sequencer, encodingData);
|
|
4975
|
-
const traverser = traversalMethod ===
|
|
4699
|
+
const traverser = traversalMethod === 1 /* MESH_TRAVERSAL_PREDICTION_DEGREE */ ? new MaxPredictionDegreeTraverser() : new DepthFirstTraverser();
|
|
4976
4700
|
traverser.init(cornerTable, observer);
|
|
4977
4701
|
sequencer.setTraverser(traverser);
|
|
4978
|
-
return this.
|
|
4702
|
+
return this.l.setAttributesDecoder(attDecoderId, new SequentialAttributeDecodersController(sequencer));
|
|
4979
4703
|
}
|
|
4980
4704
|
decodeConnectivity() {
|
|
4981
|
-
const buffer = this.
|
|
4705
|
+
const buffer = this.l.buffer();
|
|
4982
4706
|
const numEncodedVertices = decodeVarint(buffer);
|
|
4983
4707
|
if (numEncodedVertices === void 0) return false;
|
|
4984
|
-
this.
|
|
4708
|
+
this.V = numEncodedVertices;
|
|
4985
4709
|
const numFaces = decodeVarint(buffer);
|
|
4986
4710
|
if (numFaces === void 0) return false;
|
|
4987
4711
|
if (numFaces > 2147483647 / 3) {
|
|
4988
4712
|
return false;
|
|
4989
4713
|
}
|
|
4990
|
-
if (this.
|
|
4714
|
+
if (this.V > numFaces * 3) {
|
|
4991
4715
|
return false;
|
|
4992
4716
|
}
|
|
4993
4717
|
const minNumFaceEdges = Math.floor(3 * numFaces / 2);
|
|
4994
|
-
const maxNumVertexEdges = this.
|
|
4718
|
+
const maxNumVertexEdges = this.V * (this.V - 1) / 2;
|
|
4995
4719
|
if (maxNumVertexEdges < minNumFaceEdges) {
|
|
4996
4720
|
return false;
|
|
4997
4721
|
}
|
|
@@ -5018,27 +4742,28 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5018
4742
|
ad.numSeamCorners = 0;
|
|
5019
4743
|
this.g.push(ad);
|
|
5020
4744
|
}
|
|
5021
|
-
this.a.reset(numFaces, this.
|
|
5022
|
-
this
|
|
5023
|
-
if (!this.
|
|
4745
|
+
this.a.reset(numFaces, this.V + numEncodedSplitSymbols);
|
|
4746
|
+
this.ga = scratchUint8Filled(this.V + numEncodedSplitSymbols, 1);
|
|
4747
|
+
if (!this.hc(buffer)) {
|
|
5024
4748
|
return false;
|
|
5025
4749
|
}
|
|
5026
|
-
this.
|
|
5027
|
-
this.
|
|
5028
|
-
this.
|
|
4750
|
+
this.G.init(this);
|
|
4751
|
+
this.G.setNumEncodedVertices(this.V + numEncodedSplitSymbols);
|
|
4752
|
+
this.G.setNumAttributeData(numAttributeData);
|
|
5029
4753
|
const traversalEndBuffer = new DecoderBuffer();
|
|
5030
|
-
if (!this.
|
|
4754
|
+
if (!this.G.start(traversalEndBuffer)) {
|
|
5031
4755
|
return false;
|
|
5032
4756
|
}
|
|
5033
|
-
const numConnectivityVerts = this.
|
|
4757
|
+
const numConnectivityVerts = this.ic(numEncodedSymbols);
|
|
5034
4758
|
if (numConnectivityVerts === -1) {
|
|
5035
4759
|
return false;
|
|
5036
4760
|
}
|
|
5037
4761
|
buffer.init(traversalEndBuffer.dataHead, traversalEndBuffer.remainingSize);
|
|
5038
4762
|
if (this.g.length > 0) {
|
|
5039
|
-
this.
|
|
4763
|
+
this.jc();
|
|
5040
4764
|
}
|
|
5041
|
-
this.
|
|
4765
|
+
this.G.done();
|
|
4766
|
+
const numBoundaryCorners = this.Mb;
|
|
5042
4767
|
const distinctTables = [];
|
|
5043
4768
|
const adoptions = [];
|
|
5044
4769
|
let previousConnectivityData = null;
|
|
@@ -5048,6 +4773,10 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5048
4773
|
const connectivityData = this.g[i].connectivityData;
|
|
5049
4774
|
const seamCorners = this.g[i].attributeSeamCorners;
|
|
5050
4775
|
const seamCount = this.g[i].numSeamCorners;
|
|
4776
|
+
if (seamCount === numBoundaryCorners) {
|
|
4777
|
+
this.g[i].noInteriorSeams = true;
|
|
4778
|
+
continue;
|
|
4779
|
+
}
|
|
5051
4780
|
let sameAsPrevious = previousConnectivityData !== null && seamCount === previousSeamCount;
|
|
5052
4781
|
if (sameAsPrevious) {
|
|
5053
4782
|
const previous = previousSeamCorners;
|
|
@@ -5073,14 +4802,14 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5073
4802
|
previousSeamCount = seamCount;
|
|
5074
4803
|
}
|
|
5075
4804
|
if (this.g.length === 0) {
|
|
5076
|
-
this.
|
|
5077
|
-
} else if (!this.
|
|
4805
|
+
this.kc(numConnectivityVerts);
|
|
4806
|
+
} else if (!this.lc(distinctTables)) {
|
|
5078
4807
|
return false;
|
|
5079
4808
|
}
|
|
5080
4809
|
for (let i = 0; i < adoptions.length; i += 2) {
|
|
5081
4810
|
adoptions[i].adoptFrom(adoptions[i + 1]);
|
|
5082
4811
|
}
|
|
5083
|
-
this.
|
|
4812
|
+
this.gb.init(this.a.numVertices());
|
|
5084
4813
|
for (let i = 0; i < this.g.length; ++i) {
|
|
5085
4814
|
let attConnectivityVerts = this.g[i].connectivityData.numVertices();
|
|
5086
4815
|
if (attConnectivityVerts < this.a.numVertices()) {
|
|
@@ -5090,11 +4819,11 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5090
4819
|
}
|
|
5091
4820
|
return true;
|
|
5092
4821
|
}
|
|
5093
|
-
|
|
5094
|
-
if (this.
|
|
4822
|
+
mc(encoderSymbolId, outResult) {
|
|
4823
|
+
if (this.K.length === 0) {
|
|
5095
4824
|
return false;
|
|
5096
4825
|
}
|
|
5097
|
-
const back = this.
|
|
4826
|
+
const back = this.K[this.K.length - 1];
|
|
5098
4827
|
if (back.sourceSymbolId > encoderSymbolId) {
|
|
5099
4828
|
outResult.encoderSplitSymbolId = -1;
|
|
5100
4829
|
return true;
|
|
@@ -5104,24 +4833,24 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5104
4833
|
}
|
|
5105
4834
|
outResult.faceEdge = back.sourceEdge;
|
|
5106
4835
|
outResult.encoderSplitSymbolId = back.splitSymbolId;
|
|
5107
|
-
this.
|
|
4836
|
+
this.K.pop();
|
|
5108
4837
|
return true;
|
|
5109
4838
|
}
|
|
5110
|
-
|
|
5111
|
-
const activeCornerStack = scratchInt32(numSymbols + this.
|
|
4839
|
+
ic(numSymbols) {
|
|
4840
|
+
const activeCornerStack = scratchInt32(numSymbols + this.K.length + 16);
|
|
5112
4841
|
let activeCornerStackSize = 0;
|
|
5113
4842
|
const topologySplitActiveCorners = /* @__PURE__ */ new Map();
|
|
5114
4843
|
const splitResult = { faceEdge: 0, encoderSplitSymbolId: 0 };
|
|
5115
4844
|
const invalidVertices = [];
|
|
5116
4845
|
const removeInvalidVertices = this.g.length === 0;
|
|
5117
|
-
let maxNumVertices = this
|
|
4846
|
+
let maxNumVertices = this.ga.length;
|
|
5118
4847
|
let numFacesDecoded = 0;
|
|
5119
4848
|
const cornerToVertex = this.a.h;
|
|
5120
|
-
const oppositeCorners = this.a.
|
|
4849
|
+
const oppositeCorners = this.a.p;
|
|
5121
4850
|
const vc = this.a;
|
|
5122
|
-
let vertexCorners = vc.
|
|
5123
|
-
const isVertHole = this
|
|
5124
|
-
const traversalDecoder = this.
|
|
4851
|
+
let vertexCorners = vc.v;
|
|
4852
|
+
const isVertHole = this.ga;
|
|
4853
|
+
const traversalDecoder = this.G;
|
|
5125
4854
|
for (let symbolId = 0; symbolId < numSymbols; ++symbolId) {
|
|
5126
4855
|
const faceIndex = numFacesDecoded++;
|
|
5127
4856
|
let checkTopologySplit = false;
|
|
@@ -5177,7 +4906,7 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5177
4906
|
newVertIndex = vc.j++;
|
|
5178
4907
|
} else {
|
|
5179
4908
|
newVertIndex = vc.addNewVertex();
|
|
5180
|
-
vertexCorners = vc.
|
|
4909
|
+
vertexCorners = vc.v;
|
|
5181
4910
|
}
|
|
5182
4911
|
if (vc.j > maxNumVertices) return -1;
|
|
5183
4912
|
cornerToVertex[oppCorner] = newVertIndex;
|
|
@@ -5247,7 +4976,7 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5247
4976
|
firstVertIndex = vc.addNewVertex();
|
|
5248
4977
|
vc.addNewVertex();
|
|
5249
4978
|
vc.addNewVertex();
|
|
5250
|
-
vertexCorners = vc.
|
|
4979
|
+
vertexCorners = vc.v;
|
|
5251
4980
|
}
|
|
5252
4981
|
if (vc.j > maxNumVertices) return -1;
|
|
5253
4982
|
cornerToVertex[corner] = firstVertIndex;
|
|
@@ -5262,9 +4991,9 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5262
4991
|
return -1;
|
|
5263
4992
|
}
|
|
5264
4993
|
traversalDecoder.newActiveCornerReached(activeCornerStack[activeCornerStackSize - 1]);
|
|
5265
|
-
if (checkTopologySplit && this.
|
|
4994
|
+
if (checkTopologySplit && this.K.length > 0) {
|
|
5266
4995
|
const encoderSymbolId = numSymbols - symbolId - 1;
|
|
5267
|
-
while (this.
|
|
4996
|
+
while (this.mc(encoderSymbolId, splitResult)) {
|
|
5268
4997
|
if (splitResult.encoderSplitSymbolId < 0) return -1;
|
|
5269
4998
|
const actTopCorner = activeCornerStack[activeCornerStackSize - 1];
|
|
5270
4999
|
let newActiveCorner;
|
|
@@ -5281,24 +5010,24 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5281
5010
|
if (vc.j > maxNumVertices) {
|
|
5282
5011
|
return -1;
|
|
5283
5012
|
}
|
|
5284
|
-
numFacesDecoded = this.
|
|
5013
|
+
numFacesDecoded = this.nc(activeCornerStack, activeCornerStackSize, numFacesDecoded);
|
|
5285
5014
|
if (numFacesDecoded === -1) {
|
|
5286
5015
|
return -1;
|
|
5287
5016
|
}
|
|
5288
5017
|
if (numFacesDecoded !== this.a.numFaces()) {
|
|
5289
5018
|
return -1;
|
|
5290
5019
|
}
|
|
5291
|
-
return this.
|
|
5020
|
+
return this.oc(invalidVertices);
|
|
5292
5021
|
}
|
|
5293
5022
|
// Connects the remaining active-stack corners to newly decoded start faces.
|
|
5294
5023
|
// Returns the updated decoded-face count, or -1 on malformed input.
|
|
5295
|
-
|
|
5024
|
+
nc(activeCornerStack, activeCornerStackSize, numFacesDecoded) {
|
|
5296
5025
|
const ct = this.a;
|
|
5026
|
+
const oppositeCorners = ct.p;
|
|
5297
5027
|
const cornerToVertex = ct.h;
|
|
5298
|
-
const
|
|
5299
|
-
const
|
|
5300
|
-
const
|
|
5301
|
-
const traversalDecoder = this.E;
|
|
5028
|
+
const vertexCorners = ct.v;
|
|
5029
|
+
const isVertHole = this.ga;
|
|
5030
|
+
const traversalDecoder = this.G;
|
|
5302
5031
|
const numCorners = ct.numCorners();
|
|
5303
5032
|
const numFaces = ct.numFaces();
|
|
5304
5033
|
const next = (c) => c < 0 ? -1 : c % 3 === 2 ? c - 2 : c + 1;
|
|
@@ -5346,28 +5075,12 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5346
5075
|
// Removes invalid (isolated) vertices by swapping them with the last valid
|
|
5347
5076
|
// vertex in the table, matching C++ mesh_edgebreaker_decoder_impl.cc (the
|
|
5348
5077
|
// forward iteration order matters). Returns the final vertex count, or -1.
|
|
5349
|
-
|
|
5078
|
+
oc(invalidVertices) {
|
|
5350
5079
|
const ct = this.a;
|
|
5351
5080
|
const cornerToVertex = ct.h;
|
|
5352
|
-
const
|
|
5353
|
-
const
|
|
5354
|
-
const isVertHole = this.$;
|
|
5355
|
-
const numCorners = ct.numCorners();
|
|
5356
|
-
const next = (c) => c < 0 ? -1 : c % 3 === 2 ? c - 2 : c + 1;
|
|
5357
|
-
const prev = (c) => c < 0 ? -1 : c % 3 === 0 ? c + 2 : c - 1;
|
|
5358
|
-
const vertex = (c) => c < 0 || c >= numCorners ? -1 : cornerToVertex[c];
|
|
5359
|
-
const opposite = (c) => c < 0 || c >= numCorners ? -1 : oppositeCorners[c];
|
|
5081
|
+
const vertexCorners = ct.v;
|
|
5082
|
+
const isVertHole = this.ga;
|
|
5360
5083
|
const leftMostCorner = (v) => v < 0 || v >= vertexCorners.length ? -1 : vertexCorners[v];
|
|
5361
|
-
const swingLeft = (c) => {
|
|
5362
|
-
const n = next(c);
|
|
5363
|
-
const o = opposite(n);
|
|
5364
|
-
return o < 0 ? -1 : next(o);
|
|
5365
|
-
};
|
|
5366
|
-
const swingRight = (c) => {
|
|
5367
|
-
const p = prev(c);
|
|
5368
|
-
const o = opposite(p);
|
|
5369
|
-
return o < 0 ? -1 : prev(o);
|
|
5370
|
-
};
|
|
5371
5084
|
let numVertices = ct.numVertices();
|
|
5372
5085
|
for (let ivIdx = 0; ivIdx < invalidVertices.length; ++ivIdx) {
|
|
5373
5086
|
const invalidVert = invalidVertices[ivIdx];
|
|
@@ -5380,22 +5093,22 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5380
5093
|
let cid = startCid;
|
|
5381
5094
|
let leftTraversal = true;
|
|
5382
5095
|
while (cid !== kInvalidCornerIndex6) {
|
|
5383
|
-
if (vertex(cid) !== srcVert) {
|
|
5096
|
+
if (ct.vertex(cid) !== srcVert) {
|
|
5384
5097
|
return -1;
|
|
5385
5098
|
}
|
|
5386
5099
|
cornerToVertex[cid] = invalidVert;
|
|
5387
5100
|
if (leftTraversal) {
|
|
5388
|
-
const nextC = swingLeft(cid);
|
|
5101
|
+
const nextC = ct.swingLeft(cid);
|
|
5389
5102
|
if (nextC === kInvalidCornerIndex6) {
|
|
5390
5103
|
leftTraversal = false;
|
|
5391
|
-
cid = swingRight(startCid);
|
|
5104
|
+
cid = ct.swingRight(startCid);
|
|
5392
5105
|
} else if (nextC === startCid) {
|
|
5393
5106
|
break;
|
|
5394
5107
|
} else {
|
|
5395
5108
|
cid = nextC;
|
|
5396
5109
|
}
|
|
5397
5110
|
} else {
|
|
5398
|
-
cid = swingRight(cid);
|
|
5111
|
+
cid = ct.swingRight(cid);
|
|
5399
5112
|
}
|
|
5400
5113
|
}
|
|
5401
5114
|
vertexCorners[invalidVert] = leftMostCorner(srcVert);
|
|
@@ -5408,7 +5121,7 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5408
5121
|
}
|
|
5409
5122
|
// Hole events were removed from the bitstream in 2.1; for 2.2 this only
|
|
5410
5123
|
// decodes the inline topology-split events.
|
|
5411
|
-
|
|
5124
|
+
hc(decoderBuffer) {
|
|
5412
5125
|
const numTopologySplits = decodeVarint(decoderBuffer);
|
|
5413
5126
|
if (numTopologySplits === void 0) return false;
|
|
5414
5127
|
if (numTopologySplits > 0) {
|
|
@@ -5426,12 +5139,12 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5426
5139
|
if (delta2 > eventData.sourceSymbolId) return false;
|
|
5427
5140
|
eventData.splitSymbolId = eventData.sourceSymbolId - delta2;
|
|
5428
5141
|
lastSourceSymbolId = eventData.sourceSymbolId;
|
|
5429
|
-
this.
|
|
5142
|
+
this.K.push(eventData);
|
|
5430
5143
|
}
|
|
5431
5144
|
decoderBuffer.startBitDecoding(false);
|
|
5432
5145
|
for (let i = 0; i < numTopologySplits; ++i) {
|
|
5433
5146
|
const edgeData = decoderBuffer.decodeLeastSignificantBits32(1);
|
|
5434
|
-
this.
|
|
5147
|
+
this.K[i].sourceEdge = edgeData & 1;
|
|
5435
5148
|
}
|
|
5436
5149
|
decoderBuffer.endBitDecoding();
|
|
5437
5150
|
}
|
|
@@ -5449,32 +5162,37 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5449
5162
|
// the face's base corner -- is just `oppCorner >= faceBaseCorner`, since the
|
|
5450
5163
|
// base corner is a multiple of 3. That removes the per-corner division; the
|
|
5451
5164
|
// invalid-corner case (-1) is still handled by the branch above it.
|
|
5452
|
-
|
|
5165
|
+
jc() {
|
|
5453
5166
|
const oppositeCorners = this.a.oppositeCornerArray();
|
|
5454
5167
|
const attributeData = this.g;
|
|
5455
5168
|
const numAttrData = attributeData.length;
|
|
5456
|
-
const connectivityDecoders = this.
|
|
5169
|
+
const connectivityDecoders = this.G.Ob;
|
|
5457
5170
|
const numCorners = this.a.numCorners();
|
|
5458
5171
|
const candidates = scratchInt32(numCorners);
|
|
5459
5172
|
let numCandidates = 0;
|
|
5173
|
+
let numBoundaryCorners = 0;
|
|
5460
5174
|
for (let corner = 0; corner < numCorners; corner += 3) {
|
|
5461
5175
|
let opp = oppositeCorners[corner];
|
|
5462
5176
|
candidates[numCandidates] = corner ^ opp >> 31;
|
|
5463
5177
|
numCandidates -= (opp | corner - opp - 1) >> 31;
|
|
5178
|
+
numBoundaryCorners -= opp >> 31;
|
|
5464
5179
|
opp = oppositeCorners[corner + 1];
|
|
5465
5180
|
candidates[numCandidates] = corner + 1 ^ opp >> 31;
|
|
5466
5181
|
numCandidates -= (opp | corner - opp - 1) >> 31;
|
|
5182
|
+
numBoundaryCorners -= opp >> 31;
|
|
5467
5183
|
opp = oppositeCorners[corner + 2];
|
|
5468
5184
|
candidates[numCandidates] = corner + 2 ^ opp >> 31;
|
|
5469
5185
|
numCandidates -= (opp | corner - opp - 1) >> 31;
|
|
5186
|
+
numBoundaryCorners -= opp >> 31;
|
|
5470
5187
|
}
|
|
5188
|
+
this.Mb = numBoundaryCorners;
|
|
5471
5189
|
for (let i = 0; i < numAttrData; ++i) {
|
|
5472
5190
|
const ad = attributeData[i];
|
|
5473
5191
|
const seamCorners = ad.attributeSeamCorners;
|
|
5474
5192
|
let numSeamCorners = ad.numSeamCorners;
|
|
5475
5193
|
const decoder = connectivityDecoders[i];
|
|
5476
|
-
const ans = decoder.
|
|
5477
|
-
const p = decoder.
|
|
5194
|
+
const ans = decoder.Va;
|
|
5195
|
+
const p = decoder.Wa;
|
|
5478
5196
|
const buf = ans.buf;
|
|
5479
5197
|
const bufStart = ans.bufStart;
|
|
5480
5198
|
let state = ans.state;
|
|
@@ -5502,8 +5220,8 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5502
5220
|
}
|
|
5503
5221
|
}
|
|
5504
5222
|
// Position-only connectivity: vertex indices equal point indices.
|
|
5505
|
-
|
|
5506
|
-
const mesh = this.
|
|
5223
|
+
kc(numConnectivityVerts) {
|
|
5224
|
+
const mesh = this.l.mesh();
|
|
5507
5225
|
const ct = this.a;
|
|
5508
5226
|
mesh.setNumFaces(ct.numFaces());
|
|
5509
5227
|
const numCorners = ct.numCorners();
|
|
@@ -5512,8 +5230,36 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5512
5230
|
for (let c = 0; c < numCorners; ++c) {
|
|
5513
5231
|
faces[c] = baseCornerToVertex[c];
|
|
5514
5232
|
}
|
|
5515
|
-
this.
|
|
5516
|
-
this.
|
|
5233
|
+
this.fa = null;
|
|
5234
|
+
this.l.pointCloud().setNumPoints(numConnectivityVerts);
|
|
5235
|
+
}
|
|
5236
|
+
// Builds an attribute corner table whose only seams are boundary edges (see
|
|
5237
|
+
// decodeConnectivity), for a per-corner decoder that asked for it. With no
|
|
5238
|
+
// interior seam every vertex ring is one attribute vertex, numbered in
|
|
5239
|
+
// vertex order with isolated vertices skipped -- what the ring walk in
|
|
5240
|
+
// _assignAttributeVerticesAndPoints assigns such a table, without the walk.
|
|
5241
|
+
gc(ad) {
|
|
5242
|
+
const ct = this.a;
|
|
5243
|
+
const table = ad.connectivityData;
|
|
5244
|
+
table.initEmpty(ct);
|
|
5245
|
+
table.reserveSeamEdges(ad.numSeamCorners);
|
|
5246
|
+
for (let s = 0; s < ad.numSeamCorners; ++s) table.addSeamEdge(ad.attributeSeamCorners[s]);
|
|
5247
|
+
const numVertices = ct.numVertices();
|
|
5248
|
+
const numCorners = ct.numCorners();
|
|
5249
|
+
const vertexLeftmost = ct.vertexLeftmostCornerArray();
|
|
5250
|
+
const cornerToVertex = ct.cornerToVertexArray();
|
|
5251
|
+
const vertexIds = scratchInt32(numVertices);
|
|
5252
|
+
const leftMost = scratchInt32(numVertices);
|
|
5253
|
+
let numAttVertices = 0;
|
|
5254
|
+
for (let v = 0; v < numVertices; ++v) {
|
|
5255
|
+
const c = vertexLeftmost[v];
|
|
5256
|
+
vertexIds[v] = c === kInvalidCornerIndex6 ? -1 : numAttVertices;
|
|
5257
|
+
if (c !== kInvalidCornerIndex6) leftMost[numAttVertices++] = c;
|
|
5258
|
+
}
|
|
5259
|
+
const c2v = table.Z;
|
|
5260
|
+
for (let c = 0; c < numCorners; ++c) c2v[c] = vertexIds[cornerToVertex[c]];
|
|
5261
|
+
table.setRecomputedVertices(leftMost, numAttVertices);
|
|
5262
|
+
ad.noInteriorSeams = false;
|
|
5517
5263
|
}
|
|
5518
5264
|
// One walk around every vertex ring that (a) numbers the attribute vertices
|
|
5519
5265
|
// of every distinct attribute corner table (C++ MeshAttributeCornerTable::
|
|
@@ -5535,8 +5281,8 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5535
5281
|
// corner of every boundary vertex, but allowed for by the C++ code) is
|
|
5536
5282
|
// extended leftwards first, so the walk covers exactly the corners the
|
|
5537
5283
|
// separate passes would have reached.
|
|
5538
|
-
|
|
5539
|
-
const mesh = this.
|
|
5284
|
+
lc(tables) {
|
|
5285
|
+
const mesh = this.l.mesh();
|
|
5540
5286
|
const ct = this.a;
|
|
5541
5287
|
mesh.setNumFaces(ct.numFaces());
|
|
5542
5288
|
const numCorners = ct.numCorners();
|
|
@@ -5544,7 +5290,7 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5544
5290
|
const faces = mesh.faces_;
|
|
5545
5291
|
const vertexLeftmost = ct.vertexLeftmostCornerArray();
|
|
5546
5292
|
const baseOpposite = ct.oppositeCornerArray();
|
|
5547
|
-
const isVertHole = this
|
|
5293
|
+
const isVertHole = this.ga;
|
|
5548
5294
|
const numTables = tables.length;
|
|
5549
5295
|
const attCornerToVertex = new Array(numTables);
|
|
5550
5296
|
const edgeOnSeam = new Array(numTables);
|
|
@@ -5552,9 +5298,9 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5552
5298
|
const leftMostMaps = new Array(numTables);
|
|
5553
5299
|
const numAttVertices = new Int32Array(numTables);
|
|
5554
5300
|
for (let t = 0; t < numTables; ++t) {
|
|
5555
|
-
attCornerToVertex[t] = tables[t].
|
|
5556
|
-
edgeOnSeam[t] = tables[t].
|
|
5557
|
-
vertexOnSeam[t] = tables[t].
|
|
5301
|
+
attCornerToVertex[t] = tables[t].Z;
|
|
5302
|
+
edgeOnSeam[t] = tables[t].Y;
|
|
5303
|
+
vertexOnSeam[t] = tables[t].ma;
|
|
5558
5304
|
leftMostMaps[t] = scratchInt32(numCorners);
|
|
5559
5305
|
}
|
|
5560
5306
|
const ring = scratchInt32(numCorners);
|
|
@@ -5562,9 +5308,33 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5562
5308
|
const pointCorner = scratchInt32(numCorners);
|
|
5563
5309
|
const idChange = scratchUint8Zeroed(numCorners);
|
|
5564
5310
|
let numPoints = 0;
|
|
5311
|
+
const plainPointId = scratchInt32(numVertices);
|
|
5312
|
+
const plainVertIds = new Array(numTables);
|
|
5313
|
+
for (let t = 0; t < numTables; ++t) plainVertIds[t] = scratchInt32(numVertices);
|
|
5565
5314
|
for (let v = 0; v < numVertices; ++v) {
|
|
5566
5315
|
const c = vertexLeftmost[v];
|
|
5567
5316
|
if (c === kInvalidCornerIndex6) continue;
|
|
5317
|
+
const hole = isVertHole[v] !== 0;
|
|
5318
|
+
let anySeam = false;
|
|
5319
|
+
for (let t = 0; t < numTables; ++t) {
|
|
5320
|
+
if (vertexOnSeam[t][v] !== 0) {
|
|
5321
|
+
anySeam = true;
|
|
5322
|
+
break;
|
|
5323
|
+
}
|
|
5324
|
+
}
|
|
5325
|
+
if (!hole && !anySeam) {
|
|
5326
|
+
for (let t = 0; t < numTables; ++t) {
|
|
5327
|
+
const vertId = numAttVertices[t];
|
|
5328
|
+
leftMostMaps[t][vertId] = c;
|
|
5329
|
+
plainVertIds[t][v] = vertId;
|
|
5330
|
+
numAttVertices[t] = vertId + 1;
|
|
5331
|
+
}
|
|
5332
|
+
const pointId2 = numPoints++;
|
|
5333
|
+
pointCorner[pointId2] = c;
|
|
5334
|
+
plainPointId[v] = pointId2;
|
|
5335
|
+
continue;
|
|
5336
|
+
}
|
|
5337
|
+
plainPointId[v] = -1;
|
|
5568
5338
|
let start = 0;
|
|
5569
5339
|
let k = 0;
|
|
5570
5340
|
let actC = c;
|
|
@@ -5652,20 +5422,6 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5652
5422
|
if (vertId !== firstVertId) idChange[first] = 1;
|
|
5653
5423
|
numAttVertices[t] = vertId + 1;
|
|
5654
5424
|
}
|
|
5655
|
-
const hole = isVertHole[v] !== 0;
|
|
5656
|
-
let anySeam = false;
|
|
5657
|
-
for (let t = 0; t < numTables; ++t) {
|
|
5658
|
-
if (vertexOnSeam[t][v] !== 0) {
|
|
5659
|
-
anySeam = true;
|
|
5660
|
-
break;
|
|
5661
|
-
}
|
|
5662
|
-
}
|
|
5663
|
-
if (!hole && !anySeam) {
|
|
5664
|
-
const pointId2 = numPoints++;
|
|
5665
|
-
pointCorner[pointId2] = c;
|
|
5666
|
-
for (let j2 = start; j2 < end; ++j2) faces[ring[j2]] = pointId2;
|
|
5667
|
-
continue;
|
|
5668
|
-
}
|
|
5669
5425
|
let j = start;
|
|
5670
5426
|
if (!hole) {
|
|
5671
5427
|
for (let t = 0; t < numTables; ++t) {
|
|
@@ -5705,11 +5461,19 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5705
5461
|
faces[rc] = pointId;
|
|
5706
5462
|
}
|
|
5707
5463
|
}
|
|
5464
|
+
const baseCornerToVertex = ct.cornerToVertexArray();
|
|
5465
|
+
for (let c = 0; c < numCorners; ++c) {
|
|
5466
|
+
const v = baseCornerToVertex[c];
|
|
5467
|
+
const pointId = plainPointId[v];
|
|
5468
|
+
if (pointId < 0) continue;
|
|
5469
|
+
faces[c] = pointId;
|
|
5470
|
+
for (let t = 0; t < numTables; ++t) attCornerToVertex[t][c] = plainVertIds[t][v];
|
|
5471
|
+
}
|
|
5708
5472
|
for (let t = 0; t < numTables; ++t) {
|
|
5709
5473
|
tables[t].setRecomputedVertices(leftMostMaps[t], numAttVertices[t]);
|
|
5710
5474
|
}
|
|
5711
|
-
this.
|
|
5712
|
-
this.
|
|
5475
|
+
this.fa = pointCorner;
|
|
5476
|
+
this.l.pointCloud().setNumPoints(numPoints);
|
|
5713
5477
|
return true;
|
|
5714
5478
|
}
|
|
5715
5479
|
};
|
|
@@ -5738,30 +5502,33 @@ var AttributeData = class {
|
|
|
5738
5502
|
encodingData = new MeshAttributeIndicesEncodingData();
|
|
5739
5503
|
attributeSeamCorners = new Int32Array(0);
|
|
5740
5504
|
numSeamCorners = 0;
|
|
5505
|
+
// Set when every seam is a boundary edge and connectivityData was therefore
|
|
5506
|
+
// left unbuilt (see decodeConnectivity); cleared once it is built on demand.
|
|
5507
|
+
noInteriorSeams = false;
|
|
5741
5508
|
};
|
|
5742
5509
|
var CornerTable = class {
|
|
5743
|
-
|
|
5744
|
-
|
|
5510
|
+
Pb = 0;
|
|
5511
|
+
F = 0;
|
|
5745
5512
|
j = 0;
|
|
5746
5513
|
h = null;
|
|
5747
5514
|
// corner -> vertex
|
|
5748
|
-
|
|
5515
|
+
p = null;
|
|
5749
5516
|
// corner -> opposite corner
|
|
5750
|
-
|
|
5517
|
+
v = null;
|
|
5751
5518
|
// vertex -> left-most corner
|
|
5752
5519
|
reset(numFaces, numVertices) {
|
|
5753
|
-
this.
|
|
5754
|
-
this.
|
|
5520
|
+
this.Pb = numFaces;
|
|
5521
|
+
this.F = numFaces * 3;
|
|
5755
5522
|
this.j = 0;
|
|
5756
|
-
this.h = scratchInt32Filled(this.
|
|
5757
|
-
this.
|
|
5758
|
-
this.
|
|
5523
|
+
this.h = scratchInt32Filled(this.F, -1);
|
|
5524
|
+
this.p = scratchInt32Filled(this.F, -1);
|
|
5525
|
+
this.v = scratchInt32Filled(numVertices, -1);
|
|
5759
5526
|
}
|
|
5760
5527
|
numFaces() {
|
|
5761
|
-
return this.
|
|
5528
|
+
return this.Pb;
|
|
5762
5529
|
}
|
|
5763
5530
|
numCorners() {
|
|
5764
|
-
return this.
|
|
5531
|
+
return this.F;
|
|
5765
5532
|
}
|
|
5766
5533
|
numVertices() {
|
|
5767
5534
|
return this.j;
|
|
@@ -5777,34 +5544,34 @@ var CornerTable = class {
|
|
|
5777
5544
|
return rem === 0 ? corner + 2 : corner - 1;
|
|
5778
5545
|
}
|
|
5779
5546
|
vertex(corner) {
|
|
5780
|
-
if (corner < 0 || corner >= this.
|
|
5547
|
+
if (corner < 0 || corner >= this.F) return -1;
|
|
5781
5548
|
return this.h[corner];
|
|
5782
5549
|
}
|
|
5783
5550
|
opposite(corner) {
|
|
5784
|
-
if (corner < 0 || corner >= this.
|
|
5785
|
-
return this.
|
|
5551
|
+
if (corner < 0 || corner >= this.F) return -1;
|
|
5552
|
+
return this.p[corner];
|
|
5786
5553
|
}
|
|
5787
5554
|
// Flat-array accessors; let callers avoid polymorphic per-corner dispatch.
|
|
5788
5555
|
cornerToVertexArray() {
|
|
5789
5556
|
return this.h;
|
|
5790
5557
|
}
|
|
5791
5558
|
oppositeCornerArray() {
|
|
5792
|
-
return this.
|
|
5559
|
+
return this.p;
|
|
5793
5560
|
}
|
|
5794
5561
|
vertexLeftmostCornerArray() {
|
|
5795
|
-
return this.
|
|
5562
|
+
return this.v;
|
|
5796
5563
|
}
|
|
5797
5564
|
// Mirrors C++ CornerTable::AddNewVertex() (push_back(kInvalidCornerIndex)).
|
|
5798
5565
|
addNewVertex() {
|
|
5799
5566
|
const newVertex = this.j;
|
|
5800
5567
|
this.j++;
|
|
5801
|
-
if (newVertex >= this.
|
|
5802
|
-
const newCapacity = Math.max(newVertex + 1, this.
|
|
5568
|
+
if (newVertex >= this.v.length) {
|
|
5569
|
+
const newCapacity = Math.max(newVertex + 1, this.v.length * 2, 64);
|
|
5803
5570
|
const newArr = scratchInt32Filled(newCapacity, -1);
|
|
5804
|
-
newArr.set(this.
|
|
5805
|
-
this.
|
|
5571
|
+
newArr.set(this.v);
|
|
5572
|
+
this.v = newArr;
|
|
5806
5573
|
}
|
|
5807
|
-
this.
|
|
5574
|
+
this.v[newVertex] = -1;
|
|
5808
5575
|
return newVertex;
|
|
5809
5576
|
}
|
|
5810
5577
|
// Next corner around a vertex, CCW. SwingLeft(c) = Next(Opposite(Next(c))).
|
|
@@ -5825,24 +5592,24 @@ var CornerTable = class {
|
|
|
5825
5592
|
|
|
5826
5593
|
// src/decoder/compression/mesh/MeshEdgebreakerTraversalDecoder.ts
|
|
5827
5594
|
var MeshEdgebreakerTraversalDecoder = class {
|
|
5828
|
-
|
|
5829
|
-
|
|
5830
|
-
|
|
5831
|
-
|
|
5832
|
-
|
|
5595
|
+
c = new DecoderBuffer();
|
|
5596
|
+
H = new DecoderBuffer();
|
|
5597
|
+
hb = null;
|
|
5598
|
+
Ob = [];
|
|
5599
|
+
Qb = 0;
|
|
5833
5600
|
// _symbolBuffer's bit cursor, captured once bit decoding starts: decodeSymbol
|
|
5834
5601
|
// runs per decoded face and would otherwise reach it through two property
|
|
5835
5602
|
// loads and a method call per read.
|
|
5836
|
-
|
|
5603
|
+
Rb = null;
|
|
5837
5604
|
init(decoder) {
|
|
5838
|
-
const srcBuffer = decoder.
|
|
5839
|
-
this.
|
|
5605
|
+
const srcBuffer = decoder.l.buffer();
|
|
5606
|
+
this.c.init(srcBuffer.dataHead, srcBuffer.remainingSize);
|
|
5840
5607
|
}
|
|
5841
5608
|
// Ignored by default; overridden by predictive/valence decoders.
|
|
5842
5609
|
setNumEncodedVertices(_numVertices) {
|
|
5843
5610
|
}
|
|
5844
5611
|
setNumAttributeData(numData) {
|
|
5845
|
-
this.
|
|
5612
|
+
this.Qb = numData;
|
|
5846
5613
|
}
|
|
5847
5614
|
// Sets outBuffer to the data encoded after the traversal section.
|
|
5848
5615
|
start(outBuffer) {
|
|
@@ -5855,19 +5622,19 @@ var MeshEdgebreakerTraversalDecoder = class {
|
|
|
5855
5622
|
if (!this.decodeAttributeSeams()) {
|
|
5856
5623
|
return false;
|
|
5857
5624
|
}
|
|
5858
|
-
outBuffer.init(this.
|
|
5625
|
+
outBuffer.init(this.c.dataHead, this.c.remainingSize);
|
|
5859
5626
|
return true;
|
|
5860
5627
|
}
|
|
5861
5628
|
decodeStartFaceConfiguration() {
|
|
5862
|
-
return this.
|
|
5629
|
+
return this.hb.decodeNextBit();
|
|
5863
5630
|
}
|
|
5864
5631
|
decodeSymbol() {
|
|
5865
|
-
const bd = this.
|
|
5632
|
+
const bd = this.Rb;
|
|
5866
5633
|
if (bd !== null) {
|
|
5867
|
-
const buf = bd.
|
|
5634
|
+
const buf = bd.Ea;
|
|
5868
5635
|
const off = bd.o;
|
|
5869
5636
|
const byteOffset = off >> 3;
|
|
5870
|
-
if (byteOffset + 4 < bd.
|
|
5637
|
+
if (byteOffset + 4 < bd.ka) {
|
|
5871
5638
|
const bits = (buf[byteOffset] | buf[byteOffset + 1] << 8 | buf[byteOffset + 2] << 16 | buf[byteOffset + 3] << 24) >>> (off & 7) & 7;
|
|
5872
5639
|
if ((bits & 1) === TOPOLOGY_C) {
|
|
5873
5640
|
bd.o = off + 1;
|
|
@@ -5877,11 +5644,11 @@ var MeshEdgebreakerTraversalDecoder = class {
|
|
|
5877
5644
|
return bits;
|
|
5878
5645
|
}
|
|
5879
5646
|
}
|
|
5880
|
-
let symbol = this.
|
|
5647
|
+
let symbol = this.H.decodeLeastSignificantBits32(1);
|
|
5881
5648
|
if (symbol === TOPOLOGY_C) {
|
|
5882
5649
|
return symbol;
|
|
5883
5650
|
}
|
|
5884
|
-
const symbolSuffix = this.
|
|
5651
|
+
const symbolSuffix = this.H.decodeLeastSignificantBits32(2);
|
|
5885
5652
|
symbol |= symbolSuffix << 1;
|
|
5886
5653
|
return symbol;
|
|
5887
5654
|
}
|
|
@@ -5890,39 +5657,39 @@ var MeshEdgebreakerTraversalDecoder = class {
|
|
|
5890
5657
|
mergeVertices(_dest, _source) {
|
|
5891
5658
|
}
|
|
5892
5659
|
done() {
|
|
5893
|
-
if (this.
|
|
5894
|
-
this.
|
|
5660
|
+
if (this.H.bitDecoderActive) {
|
|
5661
|
+
this.H.endBitDecoding();
|
|
5895
5662
|
}
|
|
5896
5663
|
}
|
|
5897
5664
|
decodeTraversalSymbols() {
|
|
5898
|
-
this.
|
|
5899
|
-
const traversalSize = this.
|
|
5665
|
+
this.H.init(this.c.dataHead, this.c.remainingSize);
|
|
5666
|
+
const traversalSize = this.H.startBitDecoding(true);
|
|
5900
5667
|
if (traversalSize === void 0) {
|
|
5901
5668
|
return false;
|
|
5902
5669
|
}
|
|
5903
|
-
this.
|
|
5904
|
-
this.
|
|
5905
|
-
if (traversalSize > this.
|
|
5670
|
+
this.Rb = this.H.la;
|
|
5671
|
+
this.c.init(this.H.dataHead, this.H.remainingSize);
|
|
5672
|
+
if (traversalSize > this.c.remainingSize) {
|
|
5906
5673
|
return false;
|
|
5907
5674
|
}
|
|
5908
|
-
this.
|
|
5675
|
+
this.c.advance(traversalSize);
|
|
5909
5676
|
return true;
|
|
5910
5677
|
}
|
|
5911
5678
|
decodeStartFaces() {
|
|
5912
5679
|
try {
|
|
5913
|
-
this.
|
|
5914
|
-
return this.
|
|
5680
|
+
this.hb = new RAnsBitDecoder();
|
|
5681
|
+
return this.hb.startDecoding(this.c);
|
|
5915
5682
|
} catch {
|
|
5916
5683
|
return false;
|
|
5917
5684
|
}
|
|
5918
5685
|
}
|
|
5919
5686
|
decodeAttributeSeams() {
|
|
5920
|
-
for (let i = 0; i < this.
|
|
5687
|
+
for (let i = 0; i < this.Qb; ++i) {
|
|
5921
5688
|
const decoder = new RAnsBitDecoder();
|
|
5922
|
-
if (!decoder.startDecoding(this.
|
|
5689
|
+
if (!decoder.startDecoding(this.c)) {
|
|
5923
5690
|
return false;
|
|
5924
5691
|
}
|
|
5925
|
-
this.
|
|
5692
|
+
this.Ob.push(decoder);
|
|
5926
5693
|
}
|
|
5927
5694
|
return true;
|
|
5928
5695
|
}
|
|
@@ -5932,10 +5699,10 @@ var MeshEdgebreakerTraversalDecoder = class {
|
|
|
5932
5699
|
var MeshEdgebreakerTraversalPredictiveDecoder = class extends MeshEdgebreakerTraversalDecoder {
|
|
5933
5700
|
a = null;
|
|
5934
5701
|
j = 0;
|
|
5935
|
-
|
|
5936
|
-
|
|
5702
|
+
x = -1;
|
|
5703
|
+
ha = -1;
|
|
5937
5704
|
i = [];
|
|
5938
|
-
|
|
5705
|
+
ib = null;
|
|
5939
5706
|
init(decoder) {
|
|
5940
5707
|
super.init(decoder);
|
|
5941
5708
|
this.a = decoder.getCornerTable();
|
|
@@ -5955,24 +5722,24 @@ var MeshEdgebreakerTraversalPredictiveDecoder = class extends MeshEdgebreakerTra
|
|
|
5955
5722
|
return false;
|
|
5956
5723
|
}
|
|
5957
5724
|
this.i = new Array(this.j).fill(0);
|
|
5958
|
-
this.
|
|
5959
|
-
return this.
|
|
5725
|
+
this.ib = new RAnsBitDecoder();
|
|
5726
|
+
return this.ib.startDecoding(outBuffer);
|
|
5960
5727
|
}
|
|
5961
5728
|
decodeSymbol() {
|
|
5962
|
-
if (this.
|
|
5963
|
-
if (this.
|
|
5964
|
-
this.
|
|
5965
|
-
return this.
|
|
5729
|
+
if (this.ha !== -1) {
|
|
5730
|
+
if (this.ib.decodeNextBit()) {
|
|
5731
|
+
this.x = this.ha;
|
|
5732
|
+
return this.ha;
|
|
5966
5733
|
}
|
|
5967
5734
|
}
|
|
5968
|
-
this.
|
|
5969
|
-
return this.
|
|
5735
|
+
this.x = super.decodeSymbol();
|
|
5736
|
+
return this.x;
|
|
5970
5737
|
}
|
|
5971
5738
|
newActiveCornerReached(corner) {
|
|
5972
5739
|
const ct = this.a;
|
|
5973
5740
|
const next = ct.next(corner);
|
|
5974
5741
|
const prev = ct.previous(corner);
|
|
5975
|
-
switch (this.
|
|
5742
|
+
switch (this.x) {
|
|
5976
5743
|
case TOPOLOGY_C:
|
|
5977
5744
|
case TOPOLOGY_S:
|
|
5978
5745
|
this.i[ct.vertex(next)] += 1;
|
|
@@ -5996,15 +5763,15 @@ var MeshEdgebreakerTraversalPredictiveDecoder = class extends MeshEdgebreakerTra
|
|
|
5996
5763
|
default:
|
|
5997
5764
|
break;
|
|
5998
5765
|
}
|
|
5999
|
-
if (this.
|
|
5766
|
+
if (this.x === TOPOLOGY_C || this.x === TOPOLOGY_R) {
|
|
6000
5767
|
const pivot = ct.vertex(ct.next(corner));
|
|
6001
5768
|
if (this.i[pivot] < 6) {
|
|
6002
|
-
this.
|
|
5769
|
+
this.ha = TOPOLOGY_R;
|
|
6003
5770
|
} else {
|
|
6004
|
-
this.
|
|
5771
|
+
this.ha = TOPOLOGY_C;
|
|
6005
5772
|
}
|
|
6006
5773
|
} else {
|
|
6007
|
-
this.
|
|
5774
|
+
this.ha = -1;
|
|
6008
5775
|
}
|
|
6009
5776
|
}
|
|
6010
5777
|
mergeVertices(dest, source) {
|
|
@@ -6016,14 +5783,14 @@ var MeshEdgebreakerTraversalPredictiveDecoder = class extends MeshEdgebreakerTra
|
|
|
6016
5783
|
var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraversalDecoder {
|
|
6017
5784
|
a = null;
|
|
6018
5785
|
j = 0;
|
|
6019
|
-
|
|
6020
|
-
|
|
6021
|
-
|
|
6022
|
-
|
|
5786
|
+
x = -1;
|
|
5787
|
+
Na = -1;
|
|
5788
|
+
Oa = 2;
|
|
5789
|
+
jb = 7;
|
|
6023
5790
|
i = new Int32Array(0);
|
|
6024
|
-
|
|
5791
|
+
ia = [];
|
|
6025
5792
|
// Int32Array, not number[]: read and written once per decoded symbol.
|
|
6026
|
-
|
|
5793
|
+
za = new Int32Array(0);
|
|
6027
5794
|
// corner -> vertex of _cornerTable, cached at init(); the array is created
|
|
6028
5795
|
// once by CornerTable.reset() before the traversal decoder is initialized and
|
|
6029
5796
|
// never replaced, so the per-symbol hot path can read it without two property
|
|
@@ -6044,11 +5811,11 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
|
|
|
6044
5811
|
if (!this.decodeAttributeSeams()) {
|
|
6045
5812
|
return false;
|
|
6046
5813
|
}
|
|
6047
|
-
outBuffer.init(this.
|
|
5814
|
+
outBuffer.init(this.c.dataHead, this.c.remainingSize);
|
|
6048
5815
|
this.i = scratchInt32Filled(this.j, 0);
|
|
6049
|
-
const numUniqueValences = this.
|
|
6050
|
-
this.
|
|
6051
|
-
this.
|
|
5816
|
+
const numUniqueValences = this.jb - this.Oa + 1;
|
|
5817
|
+
this.ia = new Array(numUniqueValences);
|
|
5818
|
+
this.za = new Int32Array(numUniqueValences);
|
|
6052
5819
|
const pending = [];
|
|
6053
5820
|
for (let i = 0; i < numUniqueValences; ++i) {
|
|
6054
5821
|
const numSymbols = decodeVarint(outBuffer);
|
|
@@ -6059,16 +5826,16 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
|
|
|
6059
5826
|
return false;
|
|
6060
5827
|
}
|
|
6061
5828
|
if (numSymbols > 0) {
|
|
6062
|
-
this.
|
|
5829
|
+
this.ia[i] = scratchUint32(numSymbols);
|
|
6063
5830
|
const scheme = outBuffer.decodeUint8();
|
|
6064
|
-
if (scheme ===
|
|
6065
|
-
if (!decodeTaggedSymbols(numSymbols, 1, outBuffer, this.
|
|
5831
|
+
if (scheme === 0 /* SYMBOL_CODING_TAGGED */) {
|
|
5832
|
+
if (!decodeTaggedSymbols(numSymbols, 1, outBuffer, this.ia[i])) {
|
|
6066
5833
|
return false;
|
|
6067
5834
|
}
|
|
6068
|
-
this.
|
|
5835
|
+
this.za[i] = numSymbols;
|
|
6069
5836
|
continue;
|
|
6070
5837
|
}
|
|
6071
|
-
if (scheme !==
|
|
5838
|
+
if (scheme !== 1 /* SYMBOL_CODING_RAW */) {
|
|
6072
5839
|
return false;
|
|
6073
5840
|
}
|
|
6074
5841
|
const maxBitLength = outBuffer.decodeUint8();
|
|
@@ -6085,27 +5852,27 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
|
|
|
6085
5852
|
if (!decoder.startDecoding(outBuffer)) {
|
|
6086
5853
|
return false;
|
|
6087
5854
|
}
|
|
6088
|
-
pending.push({ decoder, out: this.
|
|
6089
|
-
this.
|
|
5855
|
+
pending.push({ decoder, out: this.ia[i], count: numSymbols });
|
|
5856
|
+
this.za[i] = numSymbols;
|
|
6090
5857
|
} else {
|
|
6091
|
-
this.
|
|
6092
|
-
this.
|
|
5858
|
+
this.ia[i] = new Uint32Array(0);
|
|
5859
|
+
this.za[i] = 0;
|
|
6093
5860
|
}
|
|
6094
5861
|
}
|
|
6095
|
-
const lockstep = pending.filter((entry) => entry.decoder.
|
|
5862
|
+
const lockstep = pending.filter((entry) => !entry.decoder.m.coarse);
|
|
6096
5863
|
let p = 0;
|
|
6097
5864
|
while (lockstep.length - p >= 3) {
|
|
6098
5865
|
const a = lockstep[p];
|
|
6099
5866
|
const b = lockstep[p + 1];
|
|
6100
5867
|
const c = lockstep[p + 2];
|
|
6101
|
-
|
|
6102
|
-
a.decoder.
|
|
5868
|
+
ransDecodeSymbolsTrioU16(
|
|
5869
|
+
a.decoder.m,
|
|
6103
5870
|
a.out,
|
|
6104
5871
|
a.count,
|
|
6105
|
-
b.decoder.
|
|
5872
|
+
b.decoder.m,
|
|
6106
5873
|
b.out,
|
|
6107
5874
|
b.count,
|
|
6108
|
-
c.decoder.
|
|
5875
|
+
c.decoder.m,
|
|
6109
5876
|
c.out,
|
|
6110
5877
|
c.count
|
|
6111
5878
|
);
|
|
@@ -6114,35 +5881,35 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
|
|
|
6114
5881
|
if (lockstep.length - p === 2) {
|
|
6115
5882
|
const a = lockstep[p];
|
|
6116
5883
|
const b = lockstep[p + 1];
|
|
6117
|
-
|
|
5884
|
+
ransDecodeSymbolsPairU16(a.decoder.m, a.out, a.count, b.decoder.m, b.out, b.count);
|
|
6118
5885
|
p += 2;
|
|
6119
5886
|
}
|
|
6120
5887
|
for (; p < lockstep.length; ++p) {
|
|
6121
|
-
lockstep[p].decoder.
|
|
5888
|
+
lockstep[p].decoder.m.decodeSymbols(lockstep[p].out, lockstep[p].count);
|
|
6122
5889
|
}
|
|
6123
5890
|
for (const entry of pending) {
|
|
6124
|
-
if (
|
|
6125
|
-
entry.decoder.
|
|
5891
|
+
if (entry.decoder.m.coarse) {
|
|
5892
|
+
entry.decoder.m.decodeSymbols(entry.out, entry.count);
|
|
6126
5893
|
}
|
|
6127
5894
|
entry.decoder.endDecoding();
|
|
6128
5895
|
}
|
|
6129
5896
|
return true;
|
|
6130
5897
|
}
|
|
6131
5898
|
decodeSymbol() {
|
|
6132
|
-
if (this.
|
|
6133
|
-
const contextCounter = --this.
|
|
5899
|
+
if (this.Na !== -1) {
|
|
5900
|
+
const contextCounter = --this.za[this.Na];
|
|
6134
5901
|
if (contextCounter < 0) {
|
|
6135
5902
|
return TOPOLOGY_INVALID;
|
|
6136
5903
|
}
|
|
6137
|
-
const symbolId = this.
|
|
5904
|
+
const symbolId = this.ia[this.Na][contextCounter];
|
|
6138
5905
|
if (symbolId > 4) {
|
|
6139
5906
|
return TOPOLOGY_INVALID;
|
|
6140
5907
|
}
|
|
6141
|
-
this.
|
|
5908
|
+
this.x = edgeBreakerSymbolToTopologyId[symbolId];
|
|
6142
5909
|
} else {
|
|
6143
|
-
this.
|
|
5910
|
+
this.x = TOPOLOGY_E;
|
|
6144
5911
|
}
|
|
6145
|
-
return this.
|
|
5912
|
+
return this.x;
|
|
6146
5913
|
}
|
|
6147
5914
|
newActiveCornerReached(corner) {
|
|
6148
5915
|
const cornerToVertex = this.h;
|
|
@@ -6151,7 +5918,7 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
|
|
|
6151
5918
|
const prev = corner % 3 === 0 ? corner + 2 : corner - 1;
|
|
6152
5919
|
const vertNext = cornerToVertex[next];
|
|
6153
5920
|
const vertPrev = cornerToVertex[prev];
|
|
6154
|
-
switch (this.
|
|
5921
|
+
switch (this.x) {
|
|
6155
5922
|
case TOPOLOGY_C:
|
|
6156
5923
|
case TOPOLOGY_S:
|
|
6157
5924
|
valences[vertNext] += 1;
|
|
@@ -6177,14 +5944,14 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
|
|
|
6177
5944
|
}
|
|
6178
5945
|
const activeValence = valences[vertNext];
|
|
6179
5946
|
let clampedValence;
|
|
6180
|
-
if (activeValence < this.
|
|
6181
|
-
clampedValence = this.
|
|
6182
|
-
} else if (activeValence > this.
|
|
6183
|
-
clampedValence = this.
|
|
5947
|
+
if (activeValence < this.Oa) {
|
|
5948
|
+
clampedValence = this.Oa;
|
|
5949
|
+
} else if (activeValence > this.jb) {
|
|
5950
|
+
clampedValence = this.jb;
|
|
6184
5951
|
} else {
|
|
6185
5952
|
clampedValence = activeValence;
|
|
6186
5953
|
}
|
|
6187
|
-
this.
|
|
5954
|
+
this.Na = clampedValence - this.Oa;
|
|
6188
5955
|
}
|
|
6189
5956
|
mergeVertices(dest, source) {
|
|
6190
5957
|
this.i[dest] += this.i[source];
|
|
@@ -6194,53 +5961,53 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
|
|
|
6194
5961
|
// src/decoder/compression/mesh/MeshEdgebreakerDecoder.ts
|
|
6195
5962
|
var MeshEdgebreakerDecoder = class extends MeshDecoder {
|
|
6196
5963
|
// Set by initializeDecoder(), which runs before anything below is reached.
|
|
6197
|
-
|
|
5964
|
+
ja = null;
|
|
6198
5965
|
getCornerTable() {
|
|
6199
|
-
return this.
|
|
5966
|
+
return this.ja.getCornerTable();
|
|
6200
5967
|
}
|
|
6201
5968
|
getAttributeCornerTable(attId) {
|
|
6202
|
-
return this.
|
|
5969
|
+
return this.ja.getAttributeCornerTable(attId);
|
|
6203
5970
|
}
|
|
6204
5971
|
getAttributeEncodingData(attId) {
|
|
6205
|
-
return this.
|
|
5972
|
+
return this.ja.getAttributeEncodingData(attId);
|
|
6206
5973
|
}
|
|
6207
5974
|
initializeDecoder() {
|
|
6208
5975
|
const traversalDecoderType = this.buffer().decodeUint8();
|
|
6209
|
-
const TraversalDecoderClass = traversalDecoderType ===
|
|
5976
|
+
const TraversalDecoderClass = traversalDecoderType === 0 /* MESH_EDGEBREAKER_STANDARD_ENCODING */ ? MeshEdgebreakerTraversalDecoder : traversalDecoderType === 1 /* MESH_EDGEBREAKER_PREDICTIVE_ENCODING */ ? MeshEdgebreakerTraversalPredictiveDecoder : traversalDecoderType === 2 /* MESH_EDGEBREAKER_VALENCE_ENCODING */ ? MeshEdgebreakerTraversalValenceDecoder : null;
|
|
6210
5977
|
if (TraversalDecoderClass === null) {
|
|
6211
5978
|
return false;
|
|
6212
5979
|
}
|
|
6213
|
-
this.
|
|
5980
|
+
this.ja = new MeshEdgebreakerDecoderImpl(this, TraversalDecoderClass);
|
|
6214
5981
|
return true;
|
|
6215
5982
|
}
|
|
6216
5983
|
createAttributesDecoder(attDecoderId) {
|
|
6217
|
-
return this.
|
|
5984
|
+
return this.ja.createAttributesDecoder(attDecoderId);
|
|
6218
5985
|
}
|
|
6219
5986
|
decodeConnectivity() {
|
|
6220
|
-
return this.
|
|
5987
|
+
return this.ja.decodeConnectivity();
|
|
6221
5988
|
}
|
|
6222
5989
|
};
|
|
6223
5990
|
|
|
6224
5991
|
// src/decoder/compression/attributes/LinearSequencer.ts
|
|
6225
5992
|
var LinearSequencer = class {
|
|
6226
|
-
|
|
6227
|
-
|
|
5993
|
+
Pa;
|
|
5994
|
+
u = new Int32Array(0);
|
|
6228
5995
|
constructor(numPoints) {
|
|
6229
|
-
this.
|
|
5996
|
+
this.Pa = numPoints;
|
|
6230
5997
|
}
|
|
6231
5998
|
generateSequence() {
|
|
6232
|
-
if (this.
|
|
5999
|
+
if (this.Pa < 0) {
|
|
6233
6000
|
return false;
|
|
6234
6001
|
}
|
|
6235
|
-
const ids = new Int32Array(this.
|
|
6236
|
-
for (let i = 0; i < this.
|
|
6002
|
+
const ids = new Int32Array(this.Pa);
|
|
6003
|
+
for (let i = 0; i < this.Pa; ++i) {
|
|
6237
6004
|
ids[i] = i;
|
|
6238
6005
|
}
|
|
6239
|
-
this.
|
|
6006
|
+
this.u = ids;
|
|
6240
6007
|
return true;
|
|
6241
6008
|
}
|
|
6242
6009
|
getOutputPointIds() {
|
|
6243
|
-
return this.
|
|
6010
|
+
return this.u;
|
|
6244
6011
|
}
|
|
6245
6012
|
updatePointToAttributeIndexMapping(attribute) {
|
|
6246
6013
|
attribute.setIdentityMapping();
|
|
@@ -6267,7 +6034,7 @@ var MeshSequentialDecoder = class extends MeshDecoder {
|
|
|
6267
6034
|
return false;
|
|
6268
6035
|
}
|
|
6269
6036
|
if (connectivityMethod === 0) {
|
|
6270
|
-
if (!this.
|
|
6037
|
+
if (!this.pc(numFaces)) {
|
|
6271
6038
|
return false;
|
|
6272
6039
|
}
|
|
6273
6040
|
} else {
|
|
@@ -6306,7 +6073,7 @@ var MeshSequentialDecoder = class extends MeshDecoder {
|
|
|
6306
6073
|
new SequentialAttributeDecodersController(new LinearSequencer(this.pointCloud().numPoints()))
|
|
6307
6074
|
);
|
|
6308
6075
|
}
|
|
6309
|
-
|
|
6076
|
+
pc(numFaces) {
|
|
6310
6077
|
const numIndices = numFaces * 3;
|
|
6311
6078
|
const indicesBuffer = new Uint32Array(numIndices);
|
|
6312
6079
|
if (!decodeSymbols(numIndices, 1, this.buffer(), indicesBuffer)) {
|
|
@@ -6339,9 +6106,9 @@ var MeshSequentialDecoder = class extends MeshDecoder {
|
|
|
6339
6106
|
|
|
6340
6107
|
// src/decoder/compression/Decode.ts
|
|
6341
6108
|
function createMeshDecoder(method) {
|
|
6342
|
-
if (method ===
|
|
6109
|
+
if (method === 0 /* MESH_SEQUENTIAL_ENCODING */) {
|
|
6343
6110
|
return new MeshSequentialDecoder();
|
|
6344
|
-
} else if (method ===
|
|
6111
|
+
} else if (method === 1 /* MESH_EDGEBREAKER_ENCODING */) {
|
|
6345
6112
|
return new MeshEdgebreakerDecoder();
|
|
6346
6113
|
}
|
|
6347
6114
|
throw new Error("Unsupported mesh encoding method.");
|
|
@@ -6354,7 +6121,7 @@ var Decoder = class {
|
|
|
6354
6121
|
if (headerError !== "") {
|
|
6355
6122
|
return { mesh: null, ok: false, message: headerError };
|
|
6356
6123
|
}
|
|
6357
|
-
if (header.encoderType !==
|
|
6124
|
+
if (header.encoderType !== 1 /* TRIANGULAR_MESH */) {
|
|
6358
6125
|
return { mesh: null, ok: false, message: "Input is not a Draco triangular mesh." };
|
|
6359
6126
|
}
|
|
6360
6127
|
try {
|