minidraco 0.8.0 → 0.9.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 +6 -6
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1112 -1121
- package/dist/pool.js +19 -19
- package/dist/three.d.ts +3 -2
- package/dist/three.js +1120 -1129
- package/dist/worker.js +1112 -1121
- package/package.json +1 -1
package/dist/three.js
CHANGED
|
@@ -46,31 +46,31 @@ var Type = {
|
|
|
46
46
|
var GeometryAttribute = class {
|
|
47
47
|
d = null;
|
|
48
48
|
y = 1;
|
|
49
|
-
|
|
49
|
+
T = 9 /* FLOAT32 */;
|
|
50
50
|
Za = false;
|
|
51
|
-
T = 0;
|
|
52
51
|
U = 0;
|
|
52
|
+
V = 0;
|
|
53
53
|
Ia = Type.INVALID;
|
|
54
54
|
Ja = 0;
|
|
55
55
|
init(attributeType, buffer, numComponents, dataType, normalized, byteStride, byteOffset) {
|
|
56
56
|
this.d = buffer;
|
|
57
57
|
this.y = numComponents;
|
|
58
|
-
this.
|
|
58
|
+
this.T = dataType;
|
|
59
59
|
this.Za = normalized;
|
|
60
|
-
this.
|
|
61
|
-
this.
|
|
60
|
+
this.U = byteStride;
|
|
61
|
+
this.V = byteOffset;
|
|
62
62
|
this.Ia = attributeType;
|
|
63
63
|
}
|
|
64
64
|
resetBuffer(buffer, byteStride, byteOffset) {
|
|
65
65
|
this.d = buffer;
|
|
66
|
-
this.
|
|
67
|
-
this.
|
|
66
|
+
this.U = byteStride;
|
|
67
|
+
this.V = byteOffset;
|
|
68
68
|
}
|
|
69
69
|
get attributeType() {
|
|
70
70
|
return this.Ia;
|
|
71
71
|
}
|
|
72
72
|
get dataType() {
|
|
73
|
-
return this.
|
|
73
|
+
return this.T;
|
|
74
74
|
}
|
|
75
75
|
get numComponents() {
|
|
76
76
|
return this.y;
|
|
@@ -79,10 +79,10 @@ var GeometryAttribute = class {
|
|
|
79
79
|
return this.d;
|
|
80
80
|
}
|
|
81
81
|
get byteStride() {
|
|
82
|
-
return this.
|
|
82
|
+
return this.U;
|
|
83
83
|
}
|
|
84
84
|
get byteOffset() {
|
|
85
|
-
return this.
|
|
85
|
+
return this.V;
|
|
86
86
|
}
|
|
87
87
|
get uniqueId() {
|
|
88
88
|
return this.Ja;
|
|
@@ -95,7 +95,7 @@ var GeometryAttribute = class {
|
|
|
95
95
|
// src/decoder/point_cloud/PointCloud.ts
|
|
96
96
|
var NAMED_ATTRIBUTES_COUNT = 8;
|
|
97
97
|
var PointCloud = class {
|
|
98
|
-
|
|
98
|
+
sb = 0;
|
|
99
99
|
attributes_ = [];
|
|
100
100
|
// named_attribute_index_[type] = [att_id, ...], one list per named type.
|
|
101
101
|
_a = [[], [], [], [], [], [], [], []];
|
|
@@ -156,10 +156,10 @@ var PointCloud = class {
|
|
|
156
156
|
this.attributes_[attId] = pa;
|
|
157
157
|
}
|
|
158
158
|
numPoints() {
|
|
159
|
-
return this.
|
|
159
|
+
return this.sb;
|
|
160
160
|
}
|
|
161
161
|
setNumPoints(num) {
|
|
162
|
-
this.
|
|
162
|
+
this.sb = num;
|
|
163
163
|
}
|
|
164
164
|
};
|
|
165
165
|
|
|
@@ -169,7 +169,7 @@ var Mesh = class extends PointCloud {
|
|
|
169
169
|
// a per-face allocation. faces_[3*f + c] is corner c of face f; corner index
|
|
170
170
|
// ci maps directly to faces_[ci].
|
|
171
171
|
faces_ = new Int32Array(0);
|
|
172
|
-
|
|
172
|
+
tb = 0;
|
|
173
173
|
// Sizes faces_ to hold numFaces faces. Called once per decode, before any
|
|
174
174
|
// face index is written (edgebreaker: _assignPointsToCorners; sequential:
|
|
175
175
|
// decodeConnectivity), so the buffer is allocated exactly here — the
|
|
@@ -181,124 +181,84 @@ var Mesh = class extends PointCloud {
|
|
|
181
181
|
grown.set(this.faces_);
|
|
182
182
|
this.faces_ = grown;
|
|
183
183
|
}
|
|
184
|
-
this.
|
|
184
|
+
this.tb = numFaces;
|
|
185
185
|
}
|
|
186
186
|
numFaces() {
|
|
187
|
-
return this.
|
|
187
|
+
return this.tb;
|
|
188
188
|
}
|
|
189
189
|
};
|
|
190
190
|
|
|
191
191
|
// src/decoder/core/DataBuffer.ts
|
|
192
192
|
var DataBuffer = class {
|
|
193
|
-
|
|
193
|
+
h = new Uint8Array(0);
|
|
194
194
|
// Resizes to `size` bytes (contents preserved); when `data` is given, grows
|
|
195
195
|
// as needed and copies its first `size` bytes in.
|
|
196
196
|
update(data, size) {
|
|
197
197
|
if (data === null) {
|
|
198
|
-
this.
|
|
198
|
+
this.ub(size);
|
|
199
199
|
return;
|
|
200
200
|
}
|
|
201
|
-
if (size > this.
|
|
202
|
-
this.
|
|
201
|
+
if (size > this.h.length) {
|
|
202
|
+
this.ub(size);
|
|
203
203
|
}
|
|
204
|
-
this.
|
|
204
|
+
this.h.set(data.length === size ? data : data.subarray(0, size));
|
|
205
205
|
}
|
|
206
206
|
// The caller passes a Uint8Array of exactly dataSize bytes in the common
|
|
207
207
|
// case; avoid allocating a wrapper view per value (dominates storage time /
|
|
208
208
|
// GC pressure).
|
|
209
209
|
write(bytePos, inArray, dataSize) {
|
|
210
|
-
this.
|
|
210
|
+
this.h.set(inArray.length === dataSize ? inArray : inArray.subarray(0, dataSize), bytePos);
|
|
211
211
|
}
|
|
212
212
|
get data() {
|
|
213
|
-
return this.
|
|
213
|
+
return this.h;
|
|
214
214
|
}
|
|
215
|
-
|
|
216
|
-
if (newSize === this.
|
|
215
|
+
ub(newSize) {
|
|
216
|
+
if (newSize === this.h.length) return;
|
|
217
217
|
const newData = new Uint8Array(newSize);
|
|
218
|
-
newData.set(this.
|
|
219
|
-
this.
|
|
218
|
+
if (this.h.length > 0) newData.set(this.h.subarray(0, Math.min(this.h.length, newSize)));
|
|
219
|
+
this.h = newData;
|
|
220
220
|
}
|
|
221
221
|
};
|
|
222
222
|
|
|
223
223
|
// src/decoder/core/ScratchArena.ts
|
|
224
|
-
var
|
|
225
|
-
var
|
|
226
|
-
var
|
|
227
|
-
var
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
224
|
+
var arena = new ArrayBuffer(1 << 16);
|
|
225
|
+
var top = 0;
|
|
226
|
+
var outgrown = 0;
|
|
227
|
+
var carve = (bytes) => {
|
|
228
|
+
const size = bytes + 7 & ~7;
|
|
229
|
+
if (top + size > arena.byteLength) {
|
|
230
|
+
outgrown += top;
|
|
231
|
+
arena = new ArrayBuffer(Math.max(arena.byteLength * 2, size));
|
|
232
|
+
top = 0;
|
|
233
|
+
}
|
|
234
|
+
const offset = top;
|
|
235
|
+
top += size;
|
|
236
|
+
return offset;
|
|
237
|
+
};
|
|
237
238
|
var scratchInt32 = (size) => {
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
const bucket = freeInt32[k];
|
|
241
|
-
let pooled = bucket.length > 0 ? bucket.pop() : new Int32Array(size);
|
|
242
|
-
if (pooled.length < size) pooled = new Int32Array(1 << k);
|
|
243
|
-
borrowedInt32.push(pooled);
|
|
244
|
-
return pooled.length === size ? pooled : pooled.subarray(0, size);
|
|
239
|
+
const offset = carve(size * 4);
|
|
240
|
+
return new Int32Array(arena, offset, size);
|
|
245
241
|
};
|
|
246
242
|
var scratchUint32 = (size) => {
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
const bucket = freeUint32[k];
|
|
250
|
-
let pooled = bucket.length > 0 ? bucket.pop() : new Uint32Array(size);
|
|
251
|
-
if (pooled.length < size) pooled = new Uint32Array(1 << k);
|
|
252
|
-
borrowedUint32.push(pooled);
|
|
253
|
-
return pooled.length === size ? pooled : pooled.subarray(0, size);
|
|
243
|
+
const offset = carve(size * 4);
|
|
244
|
+
return new Uint32Array(arena, offset, size);
|
|
254
245
|
};
|
|
255
|
-
var byteCapacity = (size) => size < 8 ? 8 : size + 7 & ~7;
|
|
256
246
|
var scratchUint8 = (size) => {
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
if (k > MAX_CLASS) return new Uint8Array(capacity);
|
|
260
|
-
const bucket = freeUint8[k];
|
|
261
|
-
let pooled = bucket.length > 0 ? bucket.pop() : new Uint8Array(capacity);
|
|
262
|
-
if (pooled.length < size) pooled = new Uint8Array(1 << k);
|
|
263
|
-
borrowedUint8.push(pooled);
|
|
264
|
-
return pooled.length === size ? pooled : pooled.subarray(0, size);
|
|
265
|
-
};
|
|
266
|
-
var scratchInt32Filled = (size, value) => {
|
|
267
|
-
const view = scratchInt32(size);
|
|
268
|
-
view.fill(value);
|
|
269
|
-
return view;
|
|
270
|
-
};
|
|
271
|
-
var scratchUint32Zeroed = (size) => {
|
|
272
|
-
const view = scratchUint32(size);
|
|
273
|
-
view.fill(0);
|
|
274
|
-
return view;
|
|
275
|
-
};
|
|
276
|
-
var scratchUint8Zeroed = (size) => {
|
|
277
|
-
const view = scratchUint8(size);
|
|
278
|
-
view.fill(0);
|
|
279
|
-
return view;
|
|
280
|
-
};
|
|
281
|
-
var scratchUint8Filled = (size, value) => {
|
|
282
|
-
const view = scratchUint8(size);
|
|
283
|
-
view.fill(value);
|
|
284
|
-
return view;
|
|
247
|
+
const offset = carve(size);
|
|
248
|
+
return new Uint8Array(arena, offset, size);
|
|
285
249
|
};
|
|
250
|
+
var scratchInt32Filled = (size, value) => scratchInt32(size).fill(value);
|
|
251
|
+
var scratchUint32Zeroed = (size) => scratchUint32(size).fill(0);
|
|
252
|
+
var scratchUint8Zeroed = (size) => scratchUint8(size).fill(0);
|
|
253
|
+
var scratchUint8Filled = (size, value) => scratchUint8(size).fill(value);
|
|
254
|
+
var EMPTY_INT32 = new Int32Array(0);
|
|
255
|
+
var EMPTY_UINT8 = new Uint8Array(0);
|
|
286
256
|
var releaseScratch = () => {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
}
|
|
291
|
-
for (let i = 0; i < borrowedUint32.length; ++i) {
|
|
292
|
-
const buffer = borrowedUint32[i];
|
|
293
|
-
freeUint32[sizeClass(buffer.length)].push(buffer);
|
|
294
|
-
}
|
|
295
|
-
for (let i = 0; i < borrowedUint8.length; ++i) {
|
|
296
|
-
const buffer = borrowedUint8[i];
|
|
297
|
-
freeUint8[sizeClass(buffer.length)].push(buffer);
|
|
257
|
+
if (outgrown > 0) {
|
|
258
|
+
arena = new ArrayBuffer(outgrown + top);
|
|
259
|
+
outgrown = 0;
|
|
298
260
|
}
|
|
299
|
-
|
|
300
|
-
borrowedUint32.length = 0;
|
|
301
|
-
borrowedUint8.length = 0;
|
|
261
|
+
top = 0;
|
|
302
262
|
};
|
|
303
263
|
|
|
304
264
|
// src/decoder/attributes/PointAttribute.ts
|
|
@@ -329,38 +289,38 @@ var LAZY_INTEGER = 1;
|
|
|
329
289
|
var LAZY_QUANTIZED = 2;
|
|
330
290
|
var LAZY_OCTAHEDRON = 3;
|
|
331
291
|
var PointAttribute = class extends GeometryAttribute {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
292
|
+
E = false;
|
|
293
|
+
Ka = 0;
|
|
294
|
+
F = [];
|
|
295
|
+
W = null;
|
|
336
296
|
// Lazily-created cached typed-array view over the attribute buffer, keyed
|
|
337
297
|
// on (constructor, underlying ArrayBuffer). An attribute only ever reads
|
|
338
298
|
// through the one view type its data type dictates.
|
|
299
|
+
vb = null;
|
|
300
|
+
wb = null;
|
|
339
301
|
xb = null;
|
|
340
|
-
yb = null;
|
|
341
|
-
zb = null;
|
|
342
302
|
// Deferred inverse transform. The integer attribute decoders leave their
|
|
343
303
|
// decoded values here as int32 -- quantized floats, octahedral normals or
|
|
344
304
|
// plain integers -- with the transform's parameters, and extractTo applies
|
|
345
305
|
// the transform while gathering the values into point order: one pass over
|
|
346
306
|
// the points instead of an inverse-transform pass into a per-value buffer
|
|
347
307
|
// followed by a gather from it, and no such buffer at all.
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
308
|
+
La = LAZY_NONE;
|
|
309
|
+
ea = null;
|
|
310
|
+
yb = [];
|
|
311
|
+
Ma = 0;
|
|
352
312
|
// Set when the decoder knows every lazy value is below 2^24 in magnitude
|
|
353
313
|
// (see _lazyFloatValues); the extraction then skips its scan.
|
|
354
|
-
|
|
314
|
+
$a = false;
|
|
355
315
|
constructor(geometryAttribute) {
|
|
356
316
|
super();
|
|
357
317
|
if (geometryAttribute instanceof GeometryAttribute) {
|
|
358
318
|
this.d = geometryAttribute.d;
|
|
359
319
|
this.y = geometryAttribute.y;
|
|
360
|
-
this.S = geometryAttribute.S;
|
|
361
|
-
this.Za = geometryAttribute.Za;
|
|
362
320
|
this.T = geometryAttribute.T;
|
|
321
|
+
this.Za = geometryAttribute.Za;
|
|
363
322
|
this.U = geometryAttribute.U;
|
|
323
|
+
this.V = geometryAttribute.V;
|
|
364
324
|
this.Ia = geometryAttribute.Ia;
|
|
365
325
|
this.Ja = geometryAttribute.Ja;
|
|
366
326
|
}
|
|
@@ -368,78 +328,87 @@ var PointAttribute = class extends GeometryAttribute {
|
|
|
368
328
|
// Intentionally shadows GeometryAttribute.init with a different signature (matches draco.js / C++ source).
|
|
369
329
|
// @ts-expect-error -- signature intentionally differs from the base class, as in the source.
|
|
370
330
|
init(attributeType, numComponents, dataType, normalized, numAttributeValues) {
|
|
371
|
-
this.
|
|
331
|
+
this.W = new DataBuffer();
|
|
372
332
|
const byteStride = dataTypeLength(dataType) * numComponents;
|
|
373
|
-
super.init(attributeType, this.
|
|
333
|
+
super.init(attributeType, this.W, numComponents, dataType, normalized, byteStride, 0);
|
|
374
334
|
this.reset(numAttributeValues);
|
|
375
335
|
this.setIdentityMapping();
|
|
376
336
|
}
|
|
377
337
|
reset(numAttributeValues) {
|
|
378
|
-
if (this.
|
|
379
|
-
this.
|
|
338
|
+
if (this.W === null) {
|
|
339
|
+
this.W = new DataBuffer();
|
|
380
340
|
}
|
|
381
341
|
const entrySize = dataTypeLength(this.dataType) * this.numComponents;
|
|
382
|
-
this.
|
|
383
|
-
this.resetBuffer(this.
|
|
384
|
-
this
|
|
342
|
+
this.W.update(null, numAttributeValues * entrySize);
|
|
343
|
+
this.resetBuffer(this.W, entrySize, 0);
|
|
344
|
+
this.Ka = numAttributeValues;
|
|
385
345
|
return true;
|
|
386
346
|
}
|
|
347
|
+
// Takes `data` (numAttributeValues values in the attribute's layout) as its
|
|
348
|
+
// storage, without a copy.
|
|
349
|
+
resetWithData(data, numAttributeValues) {
|
|
350
|
+
const buffer = new DataBuffer();
|
|
351
|
+
buffer.h = data;
|
|
352
|
+
this.W = buffer;
|
|
353
|
+
this.resetBuffer(buffer, dataTypeLength(this.dataType) * this.numComponents, 0);
|
|
354
|
+
this.Ka = numAttributeValues;
|
|
355
|
+
}
|
|
387
356
|
// Sizes the attribute without allocating storage, for the deferred
|
|
388
357
|
// transforms below (the values live in the decoder's portable attribute).
|
|
389
358
|
resetLazy(numAttributeValues) {
|
|
390
|
-
this
|
|
359
|
+
this.Ka = numAttributeValues;
|
|
391
360
|
}
|
|
392
361
|
// numValues decoded integers of the attribute's own integer type, stored as
|
|
393
362
|
// int32; extractTo converts them to the requested output type.
|
|
394
363
|
setLazyInteger(values) {
|
|
395
|
-
this.
|
|
396
|
-
this.
|
|
364
|
+
this.La = LAZY_INTEGER;
|
|
365
|
+
this.ea = values;
|
|
397
366
|
}
|
|
398
367
|
// Quantized float values: value * delta + min per component (float32
|
|
399
368
|
// arithmetic, see _extractQuantized), as the C++ Dequantizer computes them.
|
|
400
369
|
setLazyQuantized(values, minValues, delta, bounded) {
|
|
401
|
-
this.
|
|
402
|
-
this.
|
|
403
|
-
this.
|
|
404
|
-
this.
|
|
405
|
-
this
|
|
370
|
+
this.La = LAZY_QUANTIZED;
|
|
371
|
+
this.ea = values;
|
|
372
|
+
this.yb = minValues;
|
|
373
|
+
this.Ma = delta;
|
|
374
|
+
this.$a = bounded;
|
|
406
375
|
}
|
|
407
376
|
// Octahedral normals: two quantized coordinates per value, dequantized by
|
|
408
377
|
// `scale` and turned into unit vectors (see _extractOctahedron).
|
|
409
378
|
setLazyOctahedron(values, scale, bounded) {
|
|
410
|
-
this.
|
|
411
|
-
this.
|
|
412
|
-
this.
|
|
413
|
-
this
|
|
379
|
+
this.La = LAZY_OCTAHEDRON;
|
|
380
|
+
this.ea = values;
|
|
381
|
+
this.Ma = scale;
|
|
382
|
+
this.$a = bounded;
|
|
414
383
|
}
|
|
415
384
|
get size() {
|
|
416
|
-
return this
|
|
385
|
+
return this.Ka;
|
|
417
386
|
}
|
|
418
387
|
mappedIndex(pointIndex) {
|
|
419
|
-
if (this.
|
|
388
|
+
if (this.E) {
|
|
420
389
|
return pointIndex;
|
|
421
390
|
}
|
|
422
|
-
return this.
|
|
391
|
+
return this.F[pointIndex];
|
|
423
392
|
}
|
|
424
393
|
get isMappingIdentity() {
|
|
425
|
-
return this.
|
|
394
|
+
return this.E;
|
|
426
395
|
}
|
|
427
396
|
get indicesMapSize() {
|
|
428
|
-
if (this.
|
|
397
|
+
if (this.E) {
|
|
429
398
|
return 0;
|
|
430
399
|
}
|
|
431
|
-
return this.
|
|
400
|
+
return this.F.length;
|
|
432
401
|
}
|
|
433
402
|
// Direct access to the explicit point->value index map (a Uint32Array after
|
|
434
403
|
// any of the setExplicitMapping* calls). Lets hot mapping loops write
|
|
435
404
|
// entries without a per-entry dispatch.
|
|
436
405
|
get indicesMap() {
|
|
437
|
-
return this.
|
|
406
|
+
return this.F;
|
|
438
407
|
}
|
|
439
408
|
// Implicit mapping: point index equals attribute entry index.
|
|
440
409
|
setIdentityMapping() {
|
|
441
|
-
this.
|
|
442
|
-
this.
|
|
410
|
+
this.E = true;
|
|
411
|
+
this.F = [];
|
|
443
412
|
}
|
|
444
413
|
// Explicit mapping without an invalid-index fill. Only for callers that
|
|
445
414
|
// provably write every entry right away (the fill was ~4% of decode time on
|
|
@@ -449,31 +418,31 @@ var PointAttribute = class extends GeometryAttribute {
|
|
|
449
418
|
// and avoids boxed-number storage; it is read once per point per attribute.
|
|
450
419
|
// Must be UNSIGNED so the 0xFFFFFFFF invalid sentinel round-trips intact.
|
|
451
420
|
setExplicitMappingUnfilled(numPoints) {
|
|
452
|
-
this.
|
|
453
|
-
this.
|
|
421
|
+
this.E = false;
|
|
422
|
+
this.F = new Uint32Array(numPoints);
|
|
454
423
|
}
|
|
455
424
|
// Adopts an already-computed map, shared with other attributes of the same
|
|
456
425
|
// mesh. The map must be treated as read-only from here on (reads go through
|
|
457
426
|
// mappedIndex/extractTo).
|
|
458
427
|
setExplicitMappingShared(map) {
|
|
459
|
-
this.
|
|
460
|
-
this.
|
|
428
|
+
this.E = false;
|
|
429
|
+
this.F = map;
|
|
461
430
|
}
|
|
462
431
|
// Like setExplicitMappingUnfilled, but from decode-scoped scratch. Only for
|
|
463
432
|
// attributes that never escape the decode (see ScratchArena) -- the portable
|
|
464
433
|
// attributes the sequential decoders build and discard.
|
|
465
434
|
setExplicitMappingScratch(numPoints) {
|
|
466
|
-
this.
|
|
467
|
-
this.
|
|
435
|
+
this.E = false;
|
|
436
|
+
this.F = scratchUint32(numPoints);
|
|
468
437
|
}
|
|
469
438
|
// Cached typed-array view of the given type over the attribute buffer.
|
|
470
|
-
|
|
471
|
-
if (this.
|
|
472
|
-
this.
|
|
473
|
-
this.
|
|
474
|
-
this.
|
|
439
|
+
zb(Ctor, bufData) {
|
|
440
|
+
if (this.vb !== Ctor || this.wb !== bufData.buffer) {
|
|
441
|
+
this.vb = Ctor;
|
|
442
|
+
this.wb = bufData.buffer;
|
|
443
|
+
this.xb = new Ctor(bufData.buffer);
|
|
475
444
|
}
|
|
476
|
-
return this.
|
|
445
|
+
return this.xb;
|
|
477
446
|
}
|
|
478
447
|
// Mirrors C++ PointAttribute::ConvertValue<T>() for buffer-backed
|
|
479
448
|
// attributes. Attribute buffers start at byteOffset 0 and entries are
|
|
@@ -482,13 +451,13 @@ var PointAttribute = class extends GeometryAttribute {
|
|
|
482
451
|
convertValue(attIndex, outVal) {
|
|
483
452
|
const bufData = this.d.data;
|
|
484
453
|
const nc = this.y;
|
|
485
|
-
const Ctor = viewCtorFor(this.
|
|
454
|
+
const Ctor = viewCtorFor(this.T);
|
|
486
455
|
if (Ctor === null) {
|
|
487
456
|
for (let i = 0; i < nc; ++i) outVal[i] = 0;
|
|
488
457
|
return;
|
|
489
458
|
}
|
|
490
|
-
const view = this.
|
|
491
|
-
const baseIndex = (bufData.byteOffset + this.
|
|
459
|
+
const view = this.zb(Ctor, bufData);
|
|
460
|
+
const baseIndex = (bufData.byteOffset + this.V + this.U * attIndex) / Ctor.BYTES_PER_ELEMENT;
|
|
492
461
|
for (let i = 0; i < nc; ++i) outVal[i] = view[baseIndex + i];
|
|
493
462
|
}
|
|
494
463
|
// Flat-array extraction of all values into one output typed array, in point
|
|
@@ -499,26 +468,31 @@ var PointAttribute = class extends GeometryAttribute {
|
|
|
499
468
|
if (numPoints === 0) {
|
|
500
469
|
return array;
|
|
501
470
|
}
|
|
502
|
-
const kind = this.
|
|
471
|
+
const kind = this.La;
|
|
503
472
|
if (kind !== LAZY_NONE) {
|
|
504
|
-
if (this.
|
|
505
|
-
if (kind ===
|
|
506
|
-
|
|
507
|
-
else
|
|
473
|
+
if (this.ea !== null) {
|
|
474
|
+
if (kind === LAZY_INTEGER) {
|
|
475
|
+
this.ec(array, numPoints);
|
|
476
|
+
} else {
|
|
477
|
+
const floats = array instanceof Float32Array ? array : new Float32Array(array.length);
|
|
478
|
+
if (kind === LAZY_QUANTIZED) this.fc(floats, numPoints);
|
|
479
|
+
else this.gc(floats, numPoints);
|
|
480
|
+
if (floats !== array) array.set(floats);
|
|
481
|
+
}
|
|
508
482
|
}
|
|
509
483
|
return array;
|
|
510
484
|
}
|
|
511
|
-
const Ctor = viewCtorFor(this.
|
|
485
|
+
const Ctor = viewCtorFor(this.T);
|
|
512
486
|
if (this.d === null || Ctor === null) {
|
|
513
487
|
return array;
|
|
514
488
|
}
|
|
515
489
|
const bufData = this.d.data;
|
|
516
|
-
const isIdentity = this.
|
|
517
|
-
const indicesMap = this.
|
|
518
|
-
const srcView = this.
|
|
490
|
+
const isIdentity = this.E;
|
|
491
|
+
const indicesMap = this.F;
|
|
492
|
+
const srcView = this.zb(Ctor, bufData);
|
|
519
493
|
const shift = 31 - Math.clz32(Ctor.BYTES_PER_ELEMENT);
|
|
520
|
-
const srcStart = bufData.byteOffset + this.
|
|
521
|
-
const strideElements = this.
|
|
494
|
+
const srcStart = bufData.byteOffset + this.V >> shift;
|
|
495
|
+
const strideElements = this.U >> shift;
|
|
522
496
|
if (isIdentity && strideElements === numComponents) {
|
|
523
497
|
const srcEnd = srcStart + numPoints * numComponents;
|
|
524
498
|
if (srcView.constructor === OutputTypedArray) {
|
|
@@ -545,8 +519,8 @@ var PointAttribute = class extends GeometryAttribute {
|
|
|
545
519
|
// are bit-identical to the reference decoder whatever the output array type.
|
|
546
520
|
// Point -> value index; the identity mapping (sequential meshes) gets a
|
|
547
521
|
// plain iota so the loops carry no per-point branch.
|
|
548
|
-
|
|
549
|
-
if (!this.
|
|
522
|
+
ab(numPoints) {
|
|
523
|
+
if (!this.E) return this.F;
|
|
550
524
|
const map = new Uint32Array(numPoints);
|
|
551
525
|
for (let p = 0; p < numPoints; ++p) map[p] = p;
|
|
552
526
|
return map;
|
|
@@ -559,9 +533,9 @@ var PointAttribute = class extends GeometryAttribute {
|
|
|
559
533
|
// practice) are rounded in place once here, after which the same holds.
|
|
560
534
|
// The decoder marks the attribute bounded when its prediction transform
|
|
561
535
|
// already confines the values to that range, and the scan is skipped.
|
|
562
|
-
|
|
563
|
-
const values = this.
|
|
564
|
-
if (this
|
|
536
|
+
Ab() {
|
|
537
|
+
const values = this.ea;
|
|
538
|
+
if (this.$a) return values;
|
|
565
539
|
for (let i = 0; i < values.length; ++i) {
|
|
566
540
|
if (values[i] >= 16777216 || values[i] <= -16777216) {
|
|
567
541
|
for (let j = 0; j < values.length; ++j) values[j] = Math.fround(values[j]);
|
|
@@ -570,23 +544,24 @@ var PointAttribute = class extends GeometryAttribute {
|
|
|
570
544
|
}
|
|
571
545
|
return values;
|
|
572
546
|
}
|
|
573
|
-
// C++ Dequantizer: float(value) * delta + min, all in float32
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
const
|
|
547
|
+
// C++ Dequantizer: float(value) * delta + min, all in float32 (the final
|
|
548
|
+
// rounding is the Float32Array store's).
|
|
549
|
+
fc(out, numPoints) {
|
|
550
|
+
const values = this.Ab();
|
|
551
|
+
const map = this.ab(numPoints);
|
|
577
552
|
const numComponents = this.y;
|
|
578
553
|
const fround = Math.fround;
|
|
579
|
-
const delta = this.
|
|
580
|
-
const min = this.
|
|
554
|
+
const delta = this.Ma;
|
|
555
|
+
const min = this.yb;
|
|
581
556
|
if (numComponents === 3) {
|
|
582
557
|
const m0 = min[0];
|
|
583
558
|
const m1 = min[1];
|
|
584
559
|
const m2 = min[2];
|
|
585
560
|
for (let p = 0, d = 0; p < numPoints; ++p, d += 3) {
|
|
586
561
|
const s = map[p] * 3;
|
|
587
|
-
out[d] = fround(
|
|
588
|
-
out[d + 1] = fround(
|
|
589
|
-
out[d + 2] = fround(
|
|
562
|
+
out[d] = fround(values[s] * delta) + m0;
|
|
563
|
+
out[d + 1] = fround(values[s + 1] * delta) + m1;
|
|
564
|
+
out[d + 2] = fround(values[s + 2] * delta) + m2;
|
|
590
565
|
}
|
|
591
566
|
return;
|
|
592
567
|
}
|
|
@@ -595,54 +570,51 @@ var PointAttribute = class extends GeometryAttribute {
|
|
|
595
570
|
const m1 = min[1];
|
|
596
571
|
for (let p = 0, d = 0; p < numPoints; ++p, d += 2) {
|
|
597
572
|
const s = map[p] * 2;
|
|
598
|
-
out[d] = fround(
|
|
599
|
-
out[d + 1] = fround(
|
|
573
|
+
out[d] = fround(values[s] * delta) + m0;
|
|
574
|
+
out[d + 1] = fround(values[s + 1] * delta) + m1;
|
|
600
575
|
}
|
|
601
576
|
return;
|
|
602
577
|
}
|
|
603
578
|
for (let p = 0, d = 0; p < numPoints; ++p) {
|
|
604
579
|
const s = map[p] * numComponents;
|
|
605
580
|
for (let c = 0; c < numComponents; ++c) {
|
|
606
|
-
out[d++] = fround(
|
|
581
|
+
out[d++] = fround(values[s + c] * delta) + min[c];
|
|
607
582
|
}
|
|
608
583
|
}
|
|
609
584
|
}
|
|
610
585
|
// OctahedronToolBox.QuantizedOctahedralCoordsToUnitVector, two quantized
|
|
611
|
-
// coordinates per value to one unit vector per point
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
586
|
+
// coordinates per value to one unit vector per point, branch-free: the
|
|
587
|
+
// signs of the normals' components are unpredictable, so the fold picks
|
|
588
|
+
// its direction arithmetically (multiplying by +-1 is exact, zero signs
|
|
589
|
+
// included). The C++ zero-vector guard (squared norm below 1e-6) is left
|
|
590
|
+
// out because no input reaches it: |x| + |y| + |z| >= 1 before the fold,
|
|
591
|
+
// which moves y and z by at most |x|, so some component stays above 1/6.
|
|
592
|
+
gc(out, numPoints) {
|
|
593
|
+
const values = this.Ab();
|
|
594
|
+
const map = this.ab(numPoints);
|
|
615
595
|
const fround = Math.fround;
|
|
616
|
-
const scale = this.
|
|
596
|
+
const scale = this.Ma;
|
|
617
597
|
for (let p = 0, d = 0; p < numPoints; ++p, d += 3) {
|
|
618
598
|
const s = map[p] * 2;
|
|
619
599
|
let y = fround(fround(values[s] * scale) - 1);
|
|
620
600
|
let z = fround(fround(values[s + 1] * scale) - 1);
|
|
621
601
|
const x = fround(fround(1 - Math.abs(y)) - Math.abs(z));
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
out[d + 1] = 0;
|
|
630
|
-
out[d + 2] = 0;
|
|
631
|
-
} else {
|
|
632
|
-
const k = fround(1 / fround(Math.sqrt(normSquared)));
|
|
633
|
-
out[d] = fround(x * k);
|
|
634
|
-
out[d + 1] = fround(y * k);
|
|
635
|
-
out[d + 2] = fround(z * k);
|
|
636
|
-
}
|
|
602
|
+
const xOffset = Math.max(-x, 0);
|
|
603
|
+
y = fround(y + xOffset * (2 * +(y < 0) - 1));
|
|
604
|
+
z = fround(z + xOffset * (2 * +(z < 0) - 1));
|
|
605
|
+
const k = fround(1 / fround(Math.sqrt(fround(fround(fround(x * x) + fround(y * y)) + fround(z * z)))));
|
|
606
|
+
out[d] = x * k;
|
|
607
|
+
out[d + 1] = y * k;
|
|
608
|
+
out[d + 2] = z * k;
|
|
637
609
|
}
|
|
638
610
|
}
|
|
639
611
|
// The int32 values wrap to the attribute's own integer type (as storing
|
|
640
612
|
// them into it would) before the output store converts them.
|
|
641
|
-
|
|
642
|
-
const values = this.
|
|
643
|
-
const map = this.
|
|
613
|
+
ec(out, numPoints) {
|
|
614
|
+
const values = this.ea;
|
|
615
|
+
const map = this.ab(numPoints);
|
|
644
616
|
const numComponents = this.y;
|
|
645
|
-
const dt = this.
|
|
617
|
+
const dt = this.T;
|
|
646
618
|
const shift = 32 - 8 * dataTypeLength(dt);
|
|
647
619
|
const signed = dt === 1 /* INT8 */ || dt === 3 /* INT16 */ || dt === 5 /* INT32 */;
|
|
648
620
|
for (let p = 0, d = 0; p < numPoints; ++p) {
|
|
@@ -674,18 +646,18 @@ function decodeVarint(buffer) {
|
|
|
674
646
|
|
|
675
647
|
// src/decoder/core/DecoderBuffer.ts
|
|
676
648
|
var BitDecoder = class {
|
|
677
|
-
|
|
678
|
-
|
|
649
|
+
Na = null;
|
|
650
|
+
q = 0;
|
|
679
651
|
qa = 0;
|
|
680
|
-
reset(uint8Array,
|
|
681
|
-
this.
|
|
682
|
-
this.qa =
|
|
683
|
-
this.
|
|
652
|
+
reset(uint8Array, start, end) {
|
|
653
|
+
this.Na = uint8Array;
|
|
654
|
+
this.qa = end;
|
|
655
|
+
this.q = start * 8;
|
|
684
656
|
}
|
|
685
657
|
getBits(nbits) {
|
|
686
658
|
if (nbits > 32) return void 0;
|
|
687
|
-
const buf = this.
|
|
688
|
-
let off = this.
|
|
659
|
+
const buf = this.Na;
|
|
660
|
+
let off = this.q;
|
|
689
661
|
const byteOffset = off >> 3;
|
|
690
662
|
const bitShift = off & 7;
|
|
691
663
|
if (byteOffset + 4 < this.qa) {
|
|
@@ -699,7 +671,7 @@ var BitDecoder = class {
|
|
|
699
671
|
} else {
|
|
700
672
|
result = val >>> bitShift;
|
|
701
673
|
}
|
|
702
|
-
this.
|
|
674
|
+
this.q = off + nbits;
|
|
703
675
|
return nbits === 32 ? result : result & (1 << nbits) - 1;
|
|
704
676
|
}
|
|
705
677
|
let value = 0;
|
|
@@ -717,54 +689,68 @@ var BitDecoder = class {
|
|
|
717
689
|
bitsRead += bitsToRead;
|
|
718
690
|
currOff += bitsToRead;
|
|
719
691
|
}
|
|
720
|
-
this.
|
|
692
|
+
this.q = currOff;
|
|
721
693
|
return value;
|
|
722
694
|
}
|
|
723
695
|
};
|
|
696
|
+
var floatBytes = new Uint8Array(4);
|
|
697
|
+
var floatView = new DataView(floatBytes.buffer);
|
|
724
698
|
var DecoderBuffer = class {
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
e = 0;
|
|
699
|
+
h = null;
|
|
700
|
+
B = 0;
|
|
701
|
+
i = 0;
|
|
729
702
|
ra = new BitDecoder();
|
|
730
703
|
Oa = false;
|
|
731
704
|
init(data, dataSize = data.length) {
|
|
732
|
-
this.
|
|
733
|
-
this.
|
|
734
|
-
this.
|
|
735
|
-
|
|
705
|
+
this.h = data;
|
|
706
|
+
this.B = dataSize;
|
|
707
|
+
this.i = 0;
|
|
708
|
+
}
|
|
709
|
+
// Continues where `other` stands: same bytes, same position (offsets stay
|
|
710
|
+
// absolute, so no view of the remaining bytes is made).
|
|
711
|
+
initFrom(other) {
|
|
712
|
+
this.h = other.h;
|
|
713
|
+
this.B = other.B;
|
|
714
|
+
this.i = other.i;
|
|
736
715
|
}
|
|
737
716
|
// Typed little-endian reads.
|
|
738
717
|
decodeUint8() {
|
|
739
|
-
if (this.
|
|
740
|
-
const val = this.
|
|
741
|
-
this.
|
|
718
|
+
if (this.i + 1 > this.B) return void 0;
|
|
719
|
+
const val = this.h[this.i];
|
|
720
|
+
this.i += 1;
|
|
742
721
|
return val;
|
|
743
722
|
}
|
|
744
723
|
decodeUint16() {
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
this.
|
|
748
|
-
|
|
724
|
+
const pos = this.i;
|
|
725
|
+
if (pos + 2 > this.B) return void 0;
|
|
726
|
+
const data = this.h;
|
|
727
|
+
this.i = pos + 2;
|
|
728
|
+
return data[pos] | data[pos + 1] << 8;
|
|
749
729
|
}
|
|
750
730
|
decodeInt32() {
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
this.
|
|
754
|
-
|
|
731
|
+
const pos = this.i;
|
|
732
|
+
if (pos + 4 > this.B) return void 0;
|
|
733
|
+
const data = this.h;
|
|
734
|
+
this.i = pos + 4;
|
|
735
|
+
return data[pos] | data[pos + 1] << 8 | data[pos + 2] << 16 | data[pos + 3] << 24;
|
|
755
736
|
}
|
|
756
737
|
decodeFloat32() {
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
this.
|
|
760
|
-
|
|
738
|
+
const pos = this.i;
|
|
739
|
+
if (pos + 4 > this.B) return void 0;
|
|
740
|
+
const data = this.h;
|
|
741
|
+
this.i = pos + 4;
|
|
742
|
+
floatBytes[0] = data[pos];
|
|
743
|
+
floatBytes[1] = data[pos + 1];
|
|
744
|
+
floatBytes[2] = data[pos + 2];
|
|
745
|
+
floatBytes[3] = data[pos + 3];
|
|
746
|
+
return floatView.getFloat32(0, true);
|
|
761
747
|
}
|
|
762
748
|
// A view into the stream (no copy), only valid until the caller's next
|
|
763
749
|
// chance to mutate the buffer — copy out before keeping it.
|
|
764
750
|
decodeBytesView(size) {
|
|
765
|
-
if (this.
|
|
766
|
-
const result = this.
|
|
767
|
-
this.
|
|
751
|
+
if (this.i + size > this.B) return void 0;
|
|
752
|
+
const result = this.h.subarray(this.i, this.i + size);
|
|
753
|
+
this.i += size;
|
|
768
754
|
return result;
|
|
769
755
|
}
|
|
770
756
|
// Only the 2.2+ layout (varint size prefix): older bitstreams are rejected
|
|
@@ -777,31 +763,28 @@ var DecoderBuffer = class {
|
|
|
777
763
|
outSize = size;
|
|
778
764
|
}
|
|
779
765
|
this.Oa = true;
|
|
780
|
-
this.ra.reset(this.
|
|
766
|
+
this.ra.reset(this.h, this.i, this.B);
|
|
781
767
|
return outSize;
|
|
782
768
|
}
|
|
783
769
|
endBitDecoding() {
|
|
784
770
|
this.Oa = false;
|
|
785
|
-
this.
|
|
771
|
+
this.i = Math.ceil(this.ra.q / 8);
|
|
786
772
|
}
|
|
787
773
|
decodeLeastSignificantBits32(nbits) {
|
|
788
774
|
if (!this.Oa) return void 0;
|
|
789
775
|
return this.ra.getBits(nbits);
|
|
790
776
|
}
|
|
791
777
|
advance(bytes) {
|
|
792
|
-
this.
|
|
778
|
+
this.i += bytes;
|
|
793
779
|
}
|
|
794
780
|
get data() {
|
|
795
|
-
return this.
|
|
796
|
-
}
|
|
797
|
-
get dataHead() {
|
|
798
|
-
return this.o.subarray(this.e);
|
|
781
|
+
return this.h;
|
|
799
782
|
}
|
|
800
783
|
get remainingSize() {
|
|
801
|
-
return this.
|
|
784
|
+
return this.B - this.i;
|
|
802
785
|
}
|
|
803
786
|
get decodedSize() {
|
|
804
|
-
return this.
|
|
787
|
+
return this.i;
|
|
805
788
|
}
|
|
806
789
|
get bitDecoderActive() {
|
|
807
790
|
return this.Oa;
|
|
@@ -822,66 +805,66 @@ var METADATA_FLAG_MASK = 32768;
|
|
|
822
805
|
var kMaxSubmetadataLevel = 1e3;
|
|
823
806
|
var MetadataDecoder = class {
|
|
824
807
|
constructor(buffer_) {
|
|
825
|
-
this.
|
|
808
|
+
this.G = buffer_;
|
|
826
809
|
}
|
|
827
810
|
buffer_;
|
|
828
811
|
// Skips per-attribute metadata followed by the geometry-level metadata.
|
|
829
812
|
skipGeometryMetadata() {
|
|
830
|
-
const numAttMetadata = decodeVarint(this.
|
|
813
|
+
const numAttMetadata = decodeVarint(this.G);
|
|
831
814
|
if (numAttMetadata === void 0) {
|
|
832
815
|
return false;
|
|
833
816
|
}
|
|
834
817
|
for (let i = 0; i < numAttMetadata; ++i) {
|
|
835
|
-
if (decodeVarint(this.
|
|
818
|
+
if (decodeVarint(this.G) === void 0) {
|
|
836
819
|
return false;
|
|
837
820
|
}
|
|
838
|
-
if (!this.
|
|
821
|
+
if (!this.bb(0)) {
|
|
839
822
|
return false;
|
|
840
823
|
}
|
|
841
824
|
}
|
|
842
|
-
return this.
|
|
825
|
+
return this.bb(0);
|
|
843
826
|
}
|
|
844
827
|
// Discards one metadata block (key-value entries plus nested sub-metadata).
|
|
845
828
|
// Sub-blocks read depth-first in stream order, matching the C++ stack traversal.
|
|
846
|
-
|
|
829
|
+
bb(level) {
|
|
847
830
|
if (level > kMaxSubmetadataLevel) {
|
|
848
831
|
return false;
|
|
849
832
|
}
|
|
850
|
-
const numEntries = decodeVarint(this.
|
|
833
|
+
const numEntries = decodeVarint(this.G);
|
|
851
834
|
if (numEntries === void 0) {
|
|
852
835
|
return false;
|
|
853
836
|
}
|
|
854
837
|
for (let i = 0; i < numEntries; ++i) {
|
|
855
|
-
const nameSkipped = this.
|
|
856
|
-
const dataSize = nameSkipped ? decodeVarint(this.
|
|
857
|
-
if (dataSize === void 0 || dataSize === 0 || !this.
|
|
838
|
+
const nameSkipped = this.Bb();
|
|
839
|
+
const dataSize = nameSkipped ? decodeVarint(this.G) : void 0;
|
|
840
|
+
if (dataSize === void 0 || dataSize === 0 || !this.Cb(dataSize)) {
|
|
858
841
|
return false;
|
|
859
842
|
}
|
|
860
843
|
}
|
|
861
|
-
const numSubMetadata = decodeVarint(this.
|
|
862
|
-
if (numSubMetadata === void 0 || numSubMetadata > this.
|
|
844
|
+
const numSubMetadata = decodeVarint(this.G);
|
|
845
|
+
if (numSubMetadata === void 0 || numSubMetadata > this.G.remainingSize) {
|
|
863
846
|
return false;
|
|
864
847
|
}
|
|
865
848
|
for (let i = 0; i < numSubMetadata; ++i) {
|
|
866
|
-
if (!this.
|
|
849
|
+
if (!this.Bb() || !this.bb(level + 1)) {
|
|
867
850
|
return false;
|
|
868
851
|
}
|
|
869
852
|
}
|
|
870
853
|
return true;
|
|
871
854
|
}
|
|
872
855
|
// Skips a name (uint8 length prefix followed by that many bytes).
|
|
873
|
-
|
|
874
|
-
const nameLen = this.
|
|
856
|
+
Bb() {
|
|
857
|
+
const nameLen = this.G.decodeUint8();
|
|
875
858
|
if (nameLen === void 0) {
|
|
876
859
|
return false;
|
|
877
860
|
}
|
|
878
|
-
return this.
|
|
861
|
+
return this.Cb(nameLen);
|
|
879
862
|
}
|
|
880
|
-
|
|
881
|
-
if (size > this.
|
|
863
|
+
Cb(size) {
|
|
864
|
+
if (size > this.G.remainingSize) {
|
|
882
865
|
return false;
|
|
883
866
|
}
|
|
884
|
-
this.
|
|
867
|
+
this.G.advance(size);
|
|
885
868
|
return true;
|
|
886
869
|
}
|
|
887
870
|
};
|
|
@@ -959,8 +942,8 @@ var RAnsDecoder = class {
|
|
|
959
942
|
bucketShift = 0;
|
|
960
943
|
// Uint16 unless the alphabet needs wider ids, so real streams keep one table type.
|
|
961
944
|
bucketTable = null;
|
|
962
|
-
// Stream state inlined (not a nested AnsDecoder) so the
|
|
963
|
-
//
|
|
945
|
+
// Stream state inlined (not a nested AnsDecoder) so the decode loops touch
|
|
946
|
+
// own props; initialized by ansReadInit.
|
|
964
947
|
buf = null;
|
|
965
948
|
bufOffset = 0;
|
|
966
949
|
// First valid byte of this decoder's slice within buf (absolute offsets,
|
|
@@ -992,31 +975,8 @@ var RAnsDecoder = class {
|
|
|
992
975
|
}
|
|
993
976
|
return this.state === this.lRansBase;
|
|
994
977
|
}
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
const lRansBase = this.lRansBase;
|
|
998
|
-
let state = this.state;
|
|
999
|
-
let bufOffset = this.bufOffset;
|
|
1000
|
-
const bufStart = this.bufStart;
|
|
1001
|
-
while (state < lRansBase && bufOffset > bufStart) {
|
|
1002
|
-
state = state << 8 | buf[--bufOffset];
|
|
1003
|
-
}
|
|
1004
|
-
const quo = state >>> this.ransPrecisionBits;
|
|
1005
|
-
const rem = state & this.ransPrecisionMask;
|
|
1006
|
-
let symbol;
|
|
1007
|
-
if (this.coarse) {
|
|
1008
|
-
const cumProbTable = this.cumProbTable;
|
|
1009
|
-
symbol = this.bucketTable[rem >> this.bucketShift];
|
|
1010
|
-
while (cumProbTable[symbol + 1] <= rem) symbol++;
|
|
1011
|
-
} else {
|
|
1012
|
-
symbol = this.lutTable[rem];
|
|
1013
|
-
}
|
|
1014
|
-
this.state = quo * this.probTable[symbol] + rem - this.cumProbTable[symbol];
|
|
1015
|
-
this.bufOffset = bufOffset;
|
|
1016
|
-
return symbol;
|
|
1017
|
-
}
|
|
1018
|
-
// Batch ransRead() into out[0..count): all fields hoisted to locals, state
|
|
1019
|
-
// written back once. Removes per-symbol property reads and call indirection.
|
|
978
|
+
// Decodes count symbols into out[0..count): all fields hoisted to locals,
|
|
979
|
+
// state written back once.
|
|
1020
980
|
decodeSymbols(out, count) {
|
|
1021
981
|
if (this.coarse) {
|
|
1022
982
|
this.hc(out, count);
|
|
@@ -1313,9 +1273,9 @@ function ransDecodeSymbolsTrioU16(a, outA, countA, b, outB, countB, c, outC, cou
|
|
|
1313
1273
|
|
|
1314
1274
|
// src/decoder/compression/point_cloud/PointCloudDecoder.ts
|
|
1315
1275
|
var PointCloudDecoder = class {
|
|
1316
|
-
|
|
1276
|
+
X = null;
|
|
1317
1277
|
d = null;
|
|
1318
|
-
|
|
1278
|
+
v = [];
|
|
1319
1279
|
Pa = [];
|
|
1320
1280
|
// Returns an error message, or '' on success (outHeader is then populated).
|
|
1321
1281
|
static decodeHeader(buffer, outHeader) {
|
|
@@ -1346,7 +1306,7 @@ var PointCloudDecoder = class {
|
|
|
1346
1306
|
// Main entry point, given the already-parsed header (see Decode.ts).
|
|
1347
1307
|
decode(header, inBuffer, outPointCloud) {
|
|
1348
1308
|
this.d = inBuffer;
|
|
1349
|
-
this.
|
|
1309
|
+
this.X = outPointCloud;
|
|
1350
1310
|
if (header.versionMajor !== 2 || header.versionMinor !== 2) {
|
|
1351
1311
|
return "Unsupported bitstream version (Draco 2.2 meshes only).";
|
|
1352
1312
|
}
|
|
@@ -1368,27 +1328,27 @@ var PointCloudDecoder = class {
|
|
|
1368
1328
|
if (attDecoderId < 0) {
|
|
1369
1329
|
return false;
|
|
1370
1330
|
}
|
|
1371
|
-
while (this.
|
|
1372
|
-
this.
|
|
1331
|
+
while (this.v.length <= attDecoderId) {
|
|
1332
|
+
this.v.push(null);
|
|
1373
1333
|
}
|
|
1374
|
-
this.
|
|
1334
|
+
this.v[attDecoderId] = decoder;
|
|
1375
1335
|
return true;
|
|
1376
1336
|
}
|
|
1377
1337
|
getPortableAttribute(parentAttId) {
|
|
1378
|
-
if (parentAttId < 0 || parentAttId >= this.
|
|
1338
|
+
if (parentAttId < 0 || parentAttId >= this.X.numAttributes()) {
|
|
1379
1339
|
return null;
|
|
1380
1340
|
}
|
|
1381
1341
|
const parentAttDecoderId = this.Pa[parentAttId];
|
|
1382
|
-
return this.
|
|
1342
|
+
return this.v[parentAttDecoderId].getPortableAttribute(parentAttId);
|
|
1383
1343
|
}
|
|
1384
1344
|
attributesDecoder(decId) {
|
|
1385
|
-
return this.
|
|
1345
|
+
return this.v[decId];
|
|
1386
1346
|
}
|
|
1387
1347
|
numAttributesDecoders() {
|
|
1388
|
-
return this.
|
|
1348
|
+
return this.v.length;
|
|
1389
1349
|
}
|
|
1390
1350
|
pointCloud() {
|
|
1391
|
-
return this.
|
|
1351
|
+
return this.X;
|
|
1392
1352
|
}
|
|
1393
1353
|
buffer() {
|
|
1394
1354
|
return this.d;
|
|
@@ -1414,20 +1374,20 @@ var PointCloudDecoder = class {
|
|
|
1414
1374
|
return false;
|
|
1415
1375
|
}
|
|
1416
1376
|
}
|
|
1417
|
-
for (let i = 0; i < this.
|
|
1418
|
-
if (!this.
|
|
1377
|
+
for (let i = 0; i < this.v.length; ++i) {
|
|
1378
|
+
if (!this.v[i].init(this, this.X)) {
|
|
1419
1379
|
return false;
|
|
1420
1380
|
}
|
|
1421
1381
|
}
|
|
1422
1382
|
for (let i = 0; i < numAttributesDecoders; ++i) {
|
|
1423
|
-
if (!this.
|
|
1383
|
+
if (!this.v[i].decodeAttributesDecoderData(this.d)) {
|
|
1424
1384
|
return false;
|
|
1425
1385
|
}
|
|
1426
1386
|
}
|
|
1427
1387
|
for (let i = 0; i < numAttributesDecoders; ++i) {
|
|
1428
|
-
const numAttributes = this.
|
|
1388
|
+
const numAttributes = this.v[i].getNumAttributes();
|
|
1429
1389
|
for (let j = 0; j < numAttributes; ++j) {
|
|
1430
|
-
const attId = this.
|
|
1390
|
+
const attId = this.v[i].getAttributeId(j);
|
|
1431
1391
|
while (this.Pa.length <= attId) {
|
|
1432
1392
|
this.Pa.push(0);
|
|
1433
1393
|
}
|
|
@@ -1437,7 +1397,7 @@ var PointCloudDecoder = class {
|
|
|
1437
1397
|
return this.decodeAllAttributes();
|
|
1438
1398
|
}
|
|
1439
1399
|
decodeAllAttributes() {
|
|
1440
|
-
const decoders = this.
|
|
1400
|
+
const decoders = this.v;
|
|
1441
1401
|
for (let i = 0; i < decoders.length; i++) {
|
|
1442
1402
|
if (!decoders[i].decodeAttributesParse(this.d)) {
|
|
1443
1403
|
return false;
|
|
@@ -1459,10 +1419,10 @@ var PointCloudDecoder = class {
|
|
|
1459
1419
|
|
|
1460
1420
|
// src/decoder/compression/mesh/MeshDecoder.ts
|
|
1461
1421
|
var MeshDecoder = class extends PointCloudDecoder {
|
|
1462
|
-
|
|
1422
|
+
H = null;
|
|
1463
1423
|
// Returns an error message, or '' on success.
|
|
1464
1424
|
decodeMesh(header, inBuffer, outMesh) {
|
|
1465
|
-
this.
|
|
1425
|
+
this.H = outMesh;
|
|
1466
1426
|
return this.decode(header, inBuffer, outMesh);
|
|
1467
1427
|
}
|
|
1468
1428
|
// Connectivity accessors used by the mesh prediction schemes; the sequential
|
|
@@ -1477,7 +1437,7 @@ var MeshDecoder = class extends PointCloudDecoder {
|
|
|
1477
1437
|
return null;
|
|
1478
1438
|
}
|
|
1479
1439
|
mesh() {
|
|
1480
|
-
return this.
|
|
1440
|
+
return this.H;
|
|
1481
1441
|
}
|
|
1482
1442
|
decodeGeometryData() {
|
|
1483
1443
|
return this.decodeConnectivity() && super.decodeGeometryData();
|
|
@@ -1488,21 +1448,21 @@ var MeshDecoder = class extends PointCloudDecoder {
|
|
|
1488
1448
|
var kInvalidCornerIndex = -1;
|
|
1489
1449
|
var MeshAttributeCornerTable = class {
|
|
1490
1450
|
// Base vertices touched by a seam edge of this table.
|
|
1491
|
-
sa =
|
|
1492
|
-
|
|
1451
|
+
sa = EMPTY_UINT8;
|
|
1452
|
+
Y = EMPTY_INT32;
|
|
1493
1453
|
// Attribute vertex -> 1 when its fan is open in this table (see
|
|
1494
1454
|
// CornerTable._vertexOnBoundary). The C++ also keeps each attribute
|
|
1495
1455
|
// vertex's left-most corner, but the decoder only ever asked it whether
|
|
1496
1456
|
// that corner sits on a boundary, which this answers directly.
|
|
1497
|
-
|
|
1457
|
+
C = EMPTY_UINT8;
|
|
1498
1458
|
// Attribute-vertex count. C++ keeps a vertex -> attribute-entry map here, but
|
|
1499
1459
|
// the decoder only ever reads its size, so track the count directly instead
|
|
1500
1460
|
// of allocating an Int32Array per attribute corner table.
|
|
1501
1461
|
ta = 0;
|
|
1502
|
-
|
|
1462
|
+
I = null;
|
|
1503
1463
|
// The base table's opposite corners with both corners of every seam edge
|
|
1504
1464
|
// set to -1: what opposite() answers, and what the traversals read.
|
|
1505
|
-
|
|
1465
|
+
J = EMPTY_INT32;
|
|
1506
1466
|
// Starts the table as a copy of the base connectivity; addSeamEdge then
|
|
1507
1467
|
// cuts the seams and the ring pass numbers the vertices. Decode-scoped
|
|
1508
1468
|
// scratch throughout: the table lives only until the decode finishes (the
|
|
@@ -1510,30 +1470,28 @@ var MeshAttributeCornerTable = class {
|
|
|
1510
1470
|
// file from allocating a fresh set per attribute per prim.
|
|
1511
1471
|
initEmpty(table) {
|
|
1512
1472
|
const numCorners = table.numCorners();
|
|
1513
|
-
this.
|
|
1473
|
+
this.I = table;
|
|
1514
1474
|
this.sa = scratchUint8Zeroed(table.numVertices());
|
|
1515
|
-
this.
|
|
1516
|
-
this.
|
|
1517
|
-
this.
|
|
1518
|
-
this.
|
|
1475
|
+
this.J = scratchInt32(numCorners);
|
|
1476
|
+
this.J.set(table.oppositeCornerArray());
|
|
1477
|
+
this.Y = scratchInt32(numCorners);
|
|
1478
|
+
this.Y.set(table.cornerToVertexArray());
|
|
1519
1479
|
this.ta = 0;
|
|
1520
1480
|
}
|
|
1521
|
-
// Cuts the edge opposite corner c (and its twin) and flags its two
|
|
1481
|
+
// Cuts the interior edge opposite corner c (and its twin) and flags its two
|
|
1482
|
+
// vertices. (Boundary edges are open in the base table already, and flagging
|
|
1483
|
+
// their vertices would only send them through the ring walk to come out
|
|
1484
|
+
// unsplit.)
|
|
1522
1485
|
addSeamEdge(c) {
|
|
1523
|
-
const cornerToVertex = this.
|
|
1524
|
-
const opposite = this.
|
|
1486
|
+
const cornerToVertex = this.I.cornerToVertexArray();
|
|
1487
|
+
const opposite = this.J;
|
|
1525
1488
|
const isVert = this.sa;
|
|
1526
1489
|
const oppCorner = opposite[c];
|
|
1527
1490
|
opposite[c] = kInvalidCornerIndex;
|
|
1528
|
-
|
|
1491
|
+
opposite[oppCorner] = kInvalidCornerIndex;
|
|
1492
|
+
const rem = c - (c / 3 | 0) * 3;
|
|
1529
1493
|
isVert[cornerToVertex[rem === 2 ? c - 2 : c + 1]] = 1;
|
|
1530
1494
|
isVert[cornerToVertex[rem === 0 ? c + 2 : c - 1]] = 1;
|
|
1531
|
-
if (oppCorner !== kInvalidCornerIndex) {
|
|
1532
|
-
opposite[oppCorner] = kInvalidCornerIndex;
|
|
1533
|
-
rem = oppCorner - (oppCorner / 3 | 0) * 3;
|
|
1534
|
-
isVert[cornerToVertex[rem === 2 ? oppCorner - 2 : oppCorner + 1]] = 1;
|
|
1535
|
-
isVert[cornerToVertex[rem === 0 ? oppCorner + 2 : oppCorner - 1]] = 1;
|
|
1536
|
-
}
|
|
1537
1495
|
}
|
|
1538
1496
|
// Installs the vertex numbering computed by the edgebreaker decoder's ring
|
|
1539
1497
|
// pass, which fills corner_to_vertex_map_ directly and hands over the
|
|
@@ -1541,29 +1499,29 @@ var MeshAttributeCornerTable = class {
|
|
|
1541
1499
|
// least numVertices entries).
|
|
1542
1500
|
setRecomputedVertices(onBoundary, numVertices) {
|
|
1543
1501
|
this.ta = numVertices;
|
|
1544
|
-
this.
|
|
1502
|
+
this.C = onBoundary;
|
|
1545
1503
|
}
|
|
1546
1504
|
// A table without interior seams is the base connectivity itself: every
|
|
1547
1505
|
// vertex ring is one attribute vertex, and the boundary edges are already
|
|
1548
1506
|
// open in the base opposite table. Shares the base arrays (read-only from
|
|
1549
1507
|
// here on), so its traversal also resolves to the base table's cached one.
|
|
1550
1508
|
initAsBase(table) {
|
|
1551
|
-
this.
|
|
1552
|
-
this.
|
|
1553
|
-
this.
|
|
1509
|
+
this.I = table;
|
|
1510
|
+
this.J = table.oppositeCornerArray();
|
|
1511
|
+
this.Y = table.cornerToVertexArray();
|
|
1554
1512
|
this.setRecomputedVertices(table.vertexOnBoundaryArray(), table.numVertices());
|
|
1555
1513
|
}
|
|
1556
1514
|
opposite(corner) {
|
|
1557
1515
|
if (corner === kInvalidCornerIndex) {
|
|
1558
1516
|
return kInvalidCornerIndex;
|
|
1559
1517
|
}
|
|
1560
|
-
return this.
|
|
1518
|
+
return this.J[corner];
|
|
1561
1519
|
}
|
|
1562
1520
|
next(corner) {
|
|
1563
|
-
return this.
|
|
1521
|
+
return this.I.next(corner);
|
|
1564
1522
|
}
|
|
1565
1523
|
previous(corner) {
|
|
1566
|
-
return this.
|
|
1524
|
+
return this.I.previous(corner);
|
|
1567
1525
|
}
|
|
1568
1526
|
swingRight(corner) {
|
|
1569
1527
|
return this.previous(this.opposite(this.previous(corner)));
|
|
@@ -1575,32 +1533,32 @@ var MeshAttributeCornerTable = class {
|
|
|
1575
1533
|
return this.ta;
|
|
1576
1534
|
}
|
|
1577
1535
|
numFaces() {
|
|
1578
|
-
return this.
|
|
1536
|
+
return this.I.numFaces();
|
|
1579
1537
|
}
|
|
1580
1538
|
numCorners() {
|
|
1581
|
-
return this.
|
|
1539
|
+
return this.I.numCorners();
|
|
1582
1540
|
}
|
|
1583
1541
|
// --- Flat-array accessors: let DepthFirstTraverser avoid per-corner dispatch. ---
|
|
1584
1542
|
cornerToVertexArray() {
|
|
1585
|
-
return this.
|
|
1543
|
+
return this.Y;
|
|
1586
1544
|
}
|
|
1587
1545
|
// Seam-aware opposite corners (seam edges -> -1), matching opposite().
|
|
1588
1546
|
oppositeCornerArray() {
|
|
1589
|
-
return this.
|
|
1547
|
+
return this.J;
|
|
1590
1548
|
}
|
|
1591
1549
|
vertexOnBoundaryArray() {
|
|
1592
|
-
return this.
|
|
1550
|
+
return this.C;
|
|
1593
1551
|
}
|
|
1594
1552
|
// Takes over another table's state wholesale. Only valid when both tables
|
|
1595
1553
|
// were built from the same corner table and the same seam edges, in which
|
|
1596
1554
|
// case every one of these is identical and read-only from here on.
|
|
1597
1555
|
adoptFrom(other) {
|
|
1598
|
-
this.
|
|
1556
|
+
this.I = other.I;
|
|
1599
1557
|
this.sa = other.sa;
|
|
1600
|
-
this.
|
|
1558
|
+
this.Y = other.Y;
|
|
1601
1559
|
this.ta = other.ta;
|
|
1602
|
-
this.
|
|
1603
|
-
this.
|
|
1560
|
+
this.C = other.C;
|
|
1561
|
+
this.J = other.J;
|
|
1604
1562
|
}
|
|
1605
1563
|
};
|
|
1606
1564
|
|
|
@@ -1609,11 +1567,11 @@ var AttributesDecoder = class {
|
|
|
1609
1567
|
Qa = [];
|
|
1610
1568
|
// Inverse of _pointAttributeIds: point attribute id -> local id.
|
|
1611
1569
|
ua = [];
|
|
1612
|
-
|
|
1613
|
-
|
|
1570
|
+
Db = null;
|
|
1571
|
+
X = null;
|
|
1614
1572
|
init(decoder, pointCloud) {
|
|
1615
|
-
this.
|
|
1616
|
-
this.
|
|
1573
|
+
this.Db = decoder;
|
|
1574
|
+
this.X = pointCloud;
|
|
1617
1575
|
return true;
|
|
1618
1576
|
}
|
|
1619
1577
|
decodeAttributesDecoderData(buffer) {
|
|
@@ -1622,7 +1580,7 @@ var AttributesDecoder = class {
|
|
|
1622
1580
|
return false;
|
|
1623
1581
|
}
|
|
1624
1582
|
this.Qa.length = numAttributes;
|
|
1625
|
-
const pc = this.
|
|
1583
|
+
const pc = this.X;
|
|
1626
1584
|
for (let i = 0; i < numAttributes; i++) {
|
|
1627
1585
|
const attType = buffer.decodeUint8();
|
|
1628
1586
|
if (attType === void 0) return false;
|
|
@@ -1663,7 +1621,7 @@ var AttributesDecoder = class {
|
|
|
1663
1621
|
return this.Qa.length;
|
|
1664
1622
|
}
|
|
1665
1623
|
getDecoder() {
|
|
1666
|
-
return this.
|
|
1624
|
+
return this.Db;
|
|
1667
1625
|
}
|
|
1668
1626
|
getLocalIdForPointAttribute(pointAttributeId) {
|
|
1669
1627
|
if (pointAttributeId >= this.ua.length) {
|
|
@@ -1675,15 +1633,15 @@ var AttributesDecoder = class {
|
|
|
1675
1633
|
|
|
1676
1634
|
// src/decoder/compression/attributes/SequentialAttributeDecoder.ts
|
|
1677
1635
|
var SequentialAttributeDecoder = class {
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1636
|
+
o = null;
|
|
1637
|
+
K = null;
|
|
1638
|
+
Eb = -1;
|
|
1681
1639
|
// Decoded portable attribute (after lossless decoding).
|
|
1682
|
-
|
|
1640
|
+
Z = null;
|
|
1683
1641
|
init(decoder, attributeId) {
|
|
1684
|
-
this.
|
|
1685
|
-
this.
|
|
1686
|
-
this.
|
|
1642
|
+
this.o = decoder;
|
|
1643
|
+
this.K = decoder.pointCloud().attribute(attributeId);
|
|
1644
|
+
this.Eb = attributeId;
|
|
1687
1645
|
return true;
|
|
1688
1646
|
}
|
|
1689
1647
|
// --- Two-phase decode ---
|
|
@@ -1694,10 +1652,10 @@ var SequentialAttributeDecoder = class {
|
|
|
1694
1652
|
// stream simply do the whole decode in Parse (decodeValues); the defaults
|
|
1695
1653
|
// below are theirs.
|
|
1696
1654
|
decodePortableAttributeParse(pointIds, buffer) {
|
|
1697
|
-
if (this.
|
|
1655
|
+
if (this.K.numComponents <= 0) {
|
|
1698
1656
|
return false;
|
|
1699
1657
|
}
|
|
1700
|
-
if (!this.
|
|
1658
|
+
if (!this.Fb(pointIds.length)) {
|
|
1701
1659
|
return false;
|
|
1702
1660
|
}
|
|
1703
1661
|
return this.decodeValues(pointIds, buffer);
|
|
@@ -1705,8 +1663,8 @@ var SequentialAttributeDecoder = class {
|
|
|
1705
1663
|
// Sizes (and here allocates) the attribute's storage for numValues values;
|
|
1706
1664
|
// the integer decoders override it to skip the allocation, their values
|
|
1707
1665
|
// staying in the portable attribute (see PointAttribute.setLazyInteger).
|
|
1708
|
-
|
|
1709
|
-
return this.
|
|
1666
|
+
Fb(numValues) {
|
|
1667
|
+
return this.K.reset(numValues);
|
|
1710
1668
|
}
|
|
1711
1669
|
pendingSymbolStream() {
|
|
1712
1670
|
return null;
|
|
@@ -1723,35 +1681,35 @@ var SequentialAttributeDecoder = class {
|
|
|
1723
1681
|
return true;
|
|
1724
1682
|
}
|
|
1725
1683
|
getPortableAttribute() {
|
|
1726
|
-
if (!this.
|
|
1727
|
-
const size = this.
|
|
1728
|
-
this.
|
|
1729
|
-
const src = this.
|
|
1730
|
-
const dst = this.
|
|
1684
|
+
if (!this.K.isMappingIdentity && this.Z && this.Z.isMappingIdentity) {
|
|
1685
|
+
const size = this.K.indicesMapSize;
|
|
1686
|
+
this.Z.setExplicitMappingScratch(size);
|
|
1687
|
+
const src = this.K.indicesMap;
|
|
1688
|
+
const dst = this.Z.indicesMap;
|
|
1731
1689
|
if (src.length === size) {
|
|
1732
1690
|
dst.set(src);
|
|
1733
1691
|
} else {
|
|
1734
1692
|
dst.set(src.subarray(0, size));
|
|
1735
1693
|
}
|
|
1736
1694
|
}
|
|
1737
|
-
return this.
|
|
1695
|
+
return this.Z;
|
|
1738
1696
|
}
|
|
1739
1697
|
get attribute() {
|
|
1740
|
-
return this.
|
|
1698
|
+
return this.K;
|
|
1741
1699
|
}
|
|
1742
1700
|
get attributeId() {
|
|
1743
|
-
return this.
|
|
1701
|
+
return this.Eb;
|
|
1744
1702
|
}
|
|
1745
1703
|
get decoder() {
|
|
1746
|
-
return this.
|
|
1704
|
+
return this.o;
|
|
1747
1705
|
}
|
|
1748
1706
|
initPredictionScheme(ps) {
|
|
1749
1707
|
for (let i = 0; i < ps.getNumParentAttributes(); i++) {
|
|
1750
|
-
const attId = this.
|
|
1708
|
+
const attId = this.o.pointCloud().getNamedAttributeId(ps.getParentAttributeType(i));
|
|
1751
1709
|
if (attId === -1) {
|
|
1752
1710
|
return false;
|
|
1753
1711
|
}
|
|
1754
|
-
const pa = this.
|
|
1712
|
+
const pa = this.o.getPortableAttribute(attId);
|
|
1755
1713
|
if (pa === null || !ps.setParentAttribute(pa)) {
|
|
1756
1714
|
return false;
|
|
1757
1715
|
}
|
|
@@ -1761,13 +1719,13 @@ var SequentialAttributeDecoder = class {
|
|
|
1761
1719
|
// Decodes raw attribute values in their original format.
|
|
1762
1720
|
decodeValues(pointIds, buffer) {
|
|
1763
1721
|
const numValues = pointIds.length;
|
|
1764
|
-
const entrySize = this.
|
|
1722
|
+
const entrySize = this.K.byteStride;
|
|
1765
1723
|
const totalSize = numValues * entrySize;
|
|
1766
1724
|
const valueData = buffer.decodeBytesView(totalSize);
|
|
1767
1725
|
if (valueData === void 0) {
|
|
1768
1726
|
return false;
|
|
1769
1727
|
}
|
|
1770
|
-
this.
|
|
1728
|
+
this.K.buffer.write(0, valueData, totalSize);
|
|
1771
1729
|
return true;
|
|
1772
1730
|
}
|
|
1773
1731
|
};
|
|
@@ -1782,14 +1740,14 @@ function convertSymbolsToSignedInts(input, count, output) {
|
|
|
1782
1740
|
|
|
1783
1741
|
// src/decoder/compression/entropy/RAnsSymbolDecoder.ts
|
|
1784
1742
|
var RAnsSymbolDecoder = class {
|
|
1785
|
-
|
|
1786
|
-
|
|
1743
|
+
Gb = 0;
|
|
1744
|
+
L;
|
|
1787
1745
|
constructor(uniqueSymbolsBitLength) {
|
|
1788
1746
|
const unclamped = Math.trunc(3 * uniqueSymbolsBitLength / 2);
|
|
1789
|
-
this.
|
|
1747
|
+
this.L = new RAnsDecoder(unclamped < 12 ? 12 : unclamped > 20 ? 20 : unclamped);
|
|
1790
1748
|
}
|
|
1791
1749
|
get numSymbols() {
|
|
1792
|
-
return this.
|
|
1750
|
+
return this.Gb;
|
|
1793
1751
|
}
|
|
1794
1752
|
// Initialize the decoder and decode the probability table. expectedCount is
|
|
1795
1753
|
// the number of symbols the caller will decode (lets short streams skip the
|
|
@@ -1797,7 +1755,7 @@ var RAnsSymbolDecoder = class {
|
|
|
1797
1755
|
create(buffer, expectedCount = 2147483647) {
|
|
1798
1756
|
const numSymbols = decodeVarint(buffer);
|
|
1799
1757
|
if (numSymbols === void 0) return false;
|
|
1800
|
-
this.
|
|
1758
|
+
this.Gb = numSymbols;
|
|
1801
1759
|
if (Math.trunc(numSymbols / 64) > buffer.remainingSize) {
|
|
1802
1760
|
return false;
|
|
1803
1761
|
}
|
|
@@ -1830,7 +1788,7 @@ var RAnsSymbolDecoder = class {
|
|
|
1830
1788
|
}
|
|
1831
1789
|
}
|
|
1832
1790
|
buffer.advance(pos - startPos);
|
|
1833
|
-
return this.
|
|
1791
|
+
return this.L.ransBuildLookUpTable(probabilityTable, numSymbols, expectedCount);
|
|
1834
1792
|
}
|
|
1835
1793
|
// Starts decoding, advancing buffer past the encoded data.
|
|
1836
1794
|
startDecoding(buffer) {
|
|
@@ -1841,10 +1799,10 @@ var RAnsSymbolDecoder = class {
|
|
|
1841
1799
|
}
|
|
1842
1800
|
const base = buffer.decodedSize;
|
|
1843
1801
|
buffer.advance(Number(bytesEncoded));
|
|
1844
|
-
return ansReadInit(this.
|
|
1802
|
+
return ansReadInit(this.L, buffer.data, base + Number(bytesEncoded), base, this.L.lRansBase, 4);
|
|
1845
1803
|
}
|
|
1846
1804
|
endDecoding() {
|
|
1847
|
-
this.
|
|
1805
|
+
this.L.readEnd();
|
|
1848
1806
|
}
|
|
1849
1807
|
};
|
|
1850
1808
|
|
|
@@ -1872,15 +1830,38 @@ function decodeTaggedSymbols(numValues, numComponents, srcBuffer, outValues) {
|
|
|
1872
1830
|
if (numValues > 0 && tagDecoder.numSymbols === 0) {
|
|
1873
1831
|
return false;
|
|
1874
1832
|
}
|
|
1875
|
-
const
|
|
1833
|
+
const ans = tagDecoder.L;
|
|
1834
|
+
const ansBuf = ans.buf;
|
|
1835
|
+
const ansStart = ans.bufStart;
|
|
1836
|
+
const lRansBase = ans.lRansBase;
|
|
1837
|
+
const precisionBits = ans.ransPrecisionBits;
|
|
1838
|
+
const precisionMask = ans.ransPrecisionMask;
|
|
1839
|
+
const probTable = ans.probTable;
|
|
1840
|
+
const cumProbTable = ans.cumProbTable;
|
|
1841
|
+
const lutTable = ans.lutTable;
|
|
1842
|
+
const bucketTable = ans.bucketTable;
|
|
1843
|
+
const bucketShift = ans.bucketShift;
|
|
1844
|
+
let state = ans.state;
|
|
1845
|
+
let ansOffset = ans.bufOffset;
|
|
1876
1846
|
srcBuffer.startBitDecoding(false);
|
|
1877
1847
|
const bd = srcBuffer.ra;
|
|
1878
|
-
const buf = bd.
|
|
1848
|
+
const buf = bd.Na;
|
|
1879
1849
|
const byteLength = bd.qa;
|
|
1880
|
-
let bitOffset = bd.
|
|
1850
|
+
let bitOffset = bd.q;
|
|
1881
1851
|
let valueId = 0;
|
|
1882
1852
|
for (let i = 0; i < numValues; i += numComponents) {
|
|
1883
|
-
|
|
1853
|
+
while (state < lRansBase && ansOffset > ansStart) {
|
|
1854
|
+
state = state << 8 | ansBuf[--ansOffset];
|
|
1855
|
+
}
|
|
1856
|
+
const rem = state & precisionMask;
|
|
1857
|
+
let bitLength;
|
|
1858
|
+
if (lutTable !== null) {
|
|
1859
|
+
bitLength = lutTable[rem];
|
|
1860
|
+
} else {
|
|
1861
|
+
bitLength = bucketTable[rem >> bucketShift];
|
|
1862
|
+
while (cumProbTable[bitLength + 1] <= rem) bitLength++;
|
|
1863
|
+
}
|
|
1864
|
+
state = (state >>> precisionBits) * probTable[bitLength] + rem - cumProbTable[bitLength];
|
|
1884
1865
|
if (bitLength < 32) {
|
|
1885
1866
|
const mask = (1 << bitLength) - 1;
|
|
1886
1867
|
let j = 0;
|
|
@@ -1896,7 +1877,7 @@ function decodeTaggedSymbols(numValues, numComponents, srcBuffer, outValues) {
|
|
|
1896
1877
|
outValues[valueId++] = value & mask;
|
|
1897
1878
|
}
|
|
1898
1879
|
if (j === numComponents) continue;
|
|
1899
|
-
bd.
|
|
1880
|
+
bd.q = bitOffset;
|
|
1900
1881
|
for (; j < numComponents; ++j) {
|
|
1901
1882
|
const val = bd.getBits(bitLength);
|
|
1902
1883
|
if (val === void 0) {
|
|
@@ -1904,9 +1885,9 @@ function decodeTaggedSymbols(numValues, numComponents, srcBuffer, outValues) {
|
|
|
1904
1885
|
}
|
|
1905
1886
|
outValues[valueId++] = val;
|
|
1906
1887
|
}
|
|
1907
|
-
bitOffset = bd.
|
|
1888
|
+
bitOffset = bd.q;
|
|
1908
1889
|
} else {
|
|
1909
|
-
bd.
|
|
1890
|
+
bd.q = bitOffset;
|
|
1910
1891
|
for (let j = 0; j < numComponents; ++j) {
|
|
1911
1892
|
const val = bd.getBits(bitLength);
|
|
1912
1893
|
if (val === void 0) {
|
|
@@ -1914,10 +1895,12 @@ function decodeTaggedSymbols(numValues, numComponents, srcBuffer, outValues) {
|
|
|
1914
1895
|
}
|
|
1915
1896
|
outValues[valueId++] = val;
|
|
1916
1897
|
}
|
|
1917
|
-
bitOffset = bd.
|
|
1898
|
+
bitOffset = bd.q;
|
|
1918
1899
|
}
|
|
1919
1900
|
}
|
|
1920
|
-
|
|
1901
|
+
ans.state = state;
|
|
1902
|
+
ans.bufOffset = ansOffset;
|
|
1903
|
+
bd.q = bitOffset;
|
|
1921
1904
|
tagDecoder.endDecoding();
|
|
1922
1905
|
srcBuffer.endBitDecoding();
|
|
1923
1906
|
return true;
|
|
@@ -1944,7 +1927,7 @@ function decodeRawSymbols(numValues, srcBuffer, outValues) {
|
|
|
1944
1927
|
if (decoder === null) {
|
|
1945
1928
|
return false;
|
|
1946
1929
|
}
|
|
1947
|
-
decoder.
|
|
1930
|
+
decoder.L.decodeSymbols(outValues, numValues);
|
|
1948
1931
|
decoder.endDecoding();
|
|
1949
1932
|
return true;
|
|
1950
1933
|
}
|
|
@@ -1995,16 +1978,16 @@ var RAnsBitDecoder = class {
|
|
|
1995
1978
|
|
|
1996
1979
|
// src/decoder/compression/attributes/prediction_schemes/PredictionSchemeDecoder.ts
|
|
1997
1980
|
var PredictionSchemeDecoder = class {
|
|
1998
|
-
|
|
1981
|
+
e;
|
|
1999
1982
|
constructor(transform) {
|
|
2000
|
-
this.
|
|
1983
|
+
this.e = transform;
|
|
2001
1984
|
}
|
|
2002
1985
|
/** True if all correction values are guaranteed to be positive. */
|
|
2003
1986
|
areCorrectionsPositive() {
|
|
2004
|
-
return this.
|
|
1987
|
+
return this.e.areCorrectionsPositive();
|
|
2005
1988
|
}
|
|
2006
1989
|
boundsValues(limit) {
|
|
2007
|
-
return this.
|
|
1990
|
+
return this.e.boundsValues(limit);
|
|
2008
1991
|
}
|
|
2009
1992
|
getNumParentAttributes() {
|
|
2010
1993
|
return 0;
|
|
@@ -2016,7 +1999,7 @@ var PredictionSchemeDecoder = class {
|
|
|
2016
1999
|
return false;
|
|
2017
2000
|
}
|
|
2018
2001
|
decodePredictionData(buffer) {
|
|
2019
|
-
return this.
|
|
2002
|
+
return this.e.decodeTransformData(buffer);
|
|
2020
2003
|
}
|
|
2021
2004
|
/**
|
|
2022
2005
|
* Like computeOriginalValues, but inCorr still holds unsigned zigzag-coded
|
|
@@ -2092,12 +2075,12 @@ var MeshPredictionSchemeConstrainedMultiParallelogramDecoder = class extends Mes
|
|
|
2092
2075
|
return super.decodePredictionData(buffer);
|
|
2093
2076
|
}
|
|
2094
2077
|
computeOriginalValues(inCorr, outData, _size, numComponents, _entryToPointIdMap) {
|
|
2095
|
-
this.
|
|
2078
|
+
this.e.init(numComponents);
|
|
2096
2079
|
const predVals = [];
|
|
2097
2080
|
for (let i = 0; i < MAX_NUM_PARALLELOGRAMS; ++i) {
|
|
2098
2081
|
predVals.push(new Int32Array(numComponents));
|
|
2099
2082
|
}
|
|
2100
|
-
this.
|
|
2083
|
+
this.e.computeOriginalValue(predVals[0], 0, inCorr, 0, outData, 0);
|
|
2101
2084
|
const table = this.c.cornerTable;
|
|
2102
2085
|
const vertexToDataMap = this.c.vertexToDataMap;
|
|
2103
2086
|
const oppositeCorners = table.oppositeCornerArray();
|
|
@@ -2156,12 +2139,12 @@ var MeshPredictionSchemeConstrainedMultiParallelogramDecoder = class extends Mes
|
|
|
2156
2139
|
const dstOffset = p * numComponents;
|
|
2157
2140
|
if (numUsedParallelograms === 0) {
|
|
2158
2141
|
const srcOffset = (p - 1) * numComponents;
|
|
2159
|
-
this.
|
|
2142
|
+
this.e.computeOriginalValue(outData, srcOffset, inCorr, dstOffset, outData, dstOffset);
|
|
2160
2143
|
} else {
|
|
2161
2144
|
for (let c = 0; c < numComponents; ++c) {
|
|
2162
2145
|
multiPredVals[c] = multiPredVals[c] / numUsedParallelograms | 0;
|
|
2163
2146
|
}
|
|
2164
|
-
this.
|
|
2147
|
+
this.e.computeOriginalValue(multiPredVals, 0, inCorr, dstOffset, outData, dstOffset);
|
|
2165
2148
|
}
|
|
2166
2149
|
}
|
|
2167
2150
|
return true;
|
|
@@ -2230,38 +2213,38 @@ var MeshPredictionSchemeData = class {
|
|
|
2230
2213
|
|
|
2231
2214
|
// src/decoder/compression/attributes/NormalCompressionUtils.ts
|
|
2232
2215
|
var OctahedronToolBox = class {
|
|
2233
|
-
|
|
2216
|
+
O = -1;
|
|
2234
2217
|
fa = -1;
|
|
2235
|
-
|
|
2218
|
+
n = -1;
|
|
2236
2219
|
jc = 1;
|
|
2237
|
-
|
|
2220
|
+
f = -1;
|
|
2238
2221
|
// q: quantization bits, valid range 2..30.
|
|
2239
2222
|
setQuantizationBits(q) {
|
|
2240
2223
|
if (q < 2 || q > 30) return false;
|
|
2241
|
-
this.
|
|
2224
|
+
this.O = q;
|
|
2242
2225
|
this.fa = (1 << q) - 1;
|
|
2243
|
-
this.
|
|
2244
|
-
this.jc = Math.fround(2 / Math.fround(this.
|
|
2245
|
-
this.
|
|
2226
|
+
this.n = this.fa - 1;
|
|
2227
|
+
this.jc = Math.fround(2 / Math.fround(this.n));
|
|
2228
|
+
this.f = this.n / 2 | 0;
|
|
2246
2229
|
return true;
|
|
2247
2230
|
}
|
|
2248
2231
|
quantizationBits() {
|
|
2249
|
-
return this.
|
|
2232
|
+
return this.O;
|
|
2250
2233
|
}
|
|
2251
2234
|
// Canonicalizes edge points into consistent quadrants. Writes result into
|
|
2252
2235
|
// out[0], out[1] (caller-owned reusable 2-element array).
|
|
2253
2236
|
canonicalizeOctahedralCoords(s, t, out) {
|
|
2254
|
-
if (s === 0 && t === 0 || s === 0 && t === this.
|
|
2255
|
-
s = this.
|
|
2256
|
-
t = this.
|
|
2257
|
-
} else if (s === 0 && t > this.
|
|
2258
|
-
t = this.
|
|
2259
|
-
} else if (s === this.
|
|
2260
|
-
t = this.
|
|
2261
|
-
} else if (t === this.
|
|
2262
|
-
s = this.
|
|
2263
|
-
} else if (t === 0 && s > this.
|
|
2264
|
-
s = this.
|
|
2237
|
+
if (s === 0 && t === 0 || s === 0 && t === this.n || s === this.n && t === 0) {
|
|
2238
|
+
s = this.n;
|
|
2239
|
+
t = this.n;
|
|
2240
|
+
} else if (s === 0 && t > this.f) {
|
|
2241
|
+
t = this.f - (t - this.f);
|
|
2242
|
+
} else if (s === this.n && t < this.f) {
|
|
2243
|
+
t = this.f + (this.f - t);
|
|
2244
|
+
} else if (t === this.n && s < this.f) {
|
|
2245
|
+
s = this.f + (this.f - s);
|
|
2246
|
+
} else if (t === 0 && s > this.f) {
|
|
2247
|
+
s = this.f - (s - this.f);
|
|
2265
2248
|
}
|
|
2266
2249
|
out[0] = s;
|
|
2267
2250
|
out[1] = t;
|
|
@@ -2271,18 +2254,18 @@ var OctahedronToolBox = class {
|
|
|
2271
2254
|
integerVectorToQuantizedOctahedralCoords(intVec, out) {
|
|
2272
2255
|
let s, t;
|
|
2273
2256
|
if (intVec[0] >= 0) {
|
|
2274
|
-
s = intVec[1] + this.
|
|
2275
|
-
t = intVec[2] + this.
|
|
2257
|
+
s = intVec[1] + this.f;
|
|
2258
|
+
t = intVec[2] + this.f;
|
|
2276
2259
|
} else {
|
|
2277
2260
|
if (intVec[1] < 0) {
|
|
2278
2261
|
s = Math.abs(intVec[2]);
|
|
2279
2262
|
} else {
|
|
2280
|
-
s = this.
|
|
2263
|
+
s = this.n - Math.abs(intVec[2]);
|
|
2281
2264
|
}
|
|
2282
2265
|
if (intVec[2] < 0) {
|
|
2283
2266
|
t = Math.abs(intVec[1]);
|
|
2284
2267
|
} else {
|
|
2285
|
-
t = this.
|
|
2268
|
+
t = this.n - Math.abs(intVec[1]);
|
|
2286
2269
|
}
|
|
2287
2270
|
}
|
|
2288
2271
|
this.canonicalizeOctahedralCoords(s, t, out);
|
|
@@ -2291,14 +2274,14 @@ var OctahedronToolBox = class {
|
|
|
2291
2274
|
canonicalizeIntegerVector(vec) {
|
|
2292
2275
|
const absSum = Math.abs(vec[0]) + Math.abs(vec[1]) + Math.abs(vec[2]);
|
|
2293
2276
|
if (absSum === 0) {
|
|
2294
|
-
vec[0] = this.
|
|
2277
|
+
vec[0] = this.f;
|
|
2295
2278
|
} else {
|
|
2296
|
-
vec[0] = Math.trunc(vec[0] * this.
|
|
2297
|
-
vec[1] = Math.trunc(vec[1] * this.
|
|
2279
|
+
vec[0] = Math.trunc(vec[0] * this.f / absSum);
|
|
2280
|
+
vec[1] = Math.trunc(vec[1] * this.f / absSum);
|
|
2298
2281
|
if (vec[2] >= 0) {
|
|
2299
|
-
vec[2] = this.
|
|
2282
|
+
vec[2] = this.f - Math.abs(vec[0]) - Math.abs(vec[1]);
|
|
2300
2283
|
} else {
|
|
2301
|
-
vec[2] = -(this.
|
|
2284
|
+
vec[2] = -(this.f - Math.abs(vec[0]) - Math.abs(vec[1]));
|
|
2302
2285
|
}
|
|
2303
2286
|
}
|
|
2304
2287
|
}
|
|
@@ -2308,38 +2291,23 @@ var OctahedronToolBox = class {
|
|
|
2308
2291
|
|
|
2309
2292
|
// src/decoder/compression/attributes/prediction_schemes/MeshPredictionSchemeGeometricNormalPredictorArea.ts
|
|
2310
2293
|
var UPPER_BOUND = 1 << 29;
|
|
2311
|
-
function fillInt32PositionCache(cache, att, map, numEntries
|
|
2312
|
-
const
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
for (let d = 0; d < numEntries; ++d) {
|
|
2321
|
-
const srcOffset = srcStart + map[d] * stride;
|
|
2322
|
-
const o = d * 3;
|
|
2323
|
-
cache[o] = src[srcOffset];
|
|
2324
|
-
cache[o + 1] = src[srcOffset + 1];
|
|
2325
|
-
cache[o + 2] = src[srcOffset + 2];
|
|
2326
|
-
}
|
|
2327
|
-
} else {
|
|
2328
|
-
for (let d = 0; d < numEntries; ++d) {
|
|
2329
|
-
const srcOffset = srcStart + indicesMap[map[d]] * stride;
|
|
2330
|
-
const o = d * 3;
|
|
2331
|
-
cache[o] = src[srcOffset];
|
|
2332
|
-
cache[o + 1] = src[srcOffset + 1];
|
|
2333
|
-
cache[o + 2] = src[srcOffset + 2];
|
|
2334
|
-
}
|
|
2294
|
+
function fillInt32PositionCache(cache, att, map, numEntries) {
|
|
2295
|
+
const bytes = att.buffer.data;
|
|
2296
|
+
const src = new Int32Array(bytes.buffer, bytes.byteOffset, bytes.length >> 2);
|
|
2297
|
+
if (att.isMappingIdentity) {
|
|
2298
|
+
for (let d = 0, o = 0; d < numEntries; ++d, o += 3) {
|
|
2299
|
+
const s = map[d] * 3;
|
|
2300
|
+
cache[o] = src[s];
|
|
2301
|
+
cache[o + 1] = src[s + 1];
|
|
2302
|
+
cache[o + 2] = src[s + 2];
|
|
2335
2303
|
}
|
|
2336
2304
|
} else {
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
const
|
|
2340
|
-
cache[o] =
|
|
2341
|
-
cache[o + 1] =
|
|
2342
|
-
cache[o + 2] =
|
|
2305
|
+
const indicesMap = att.indicesMap;
|
|
2306
|
+
for (let d = 0, o = 0; d < numEntries; ++d, o += 3) {
|
|
2307
|
+
const s = indicesMap[map[d]] * 3;
|
|
2308
|
+
cache[o] = src[s];
|
|
2309
|
+
cache[o + 1] = src[s + 1];
|
|
2310
|
+
cache[o + 2] = src[s + 2];
|
|
2343
2311
|
}
|
|
2344
2312
|
}
|
|
2345
2313
|
}
|
|
@@ -2347,12 +2315,8 @@ var MeshPredictionSchemeGeometricNormalPredictorArea = class {
|
|
|
2347
2315
|
xa = null;
|
|
2348
2316
|
ya = null;
|
|
2349
2317
|
c;
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
// flat Int32 positions, indexed by data id
|
|
2353
|
-
q = null;
|
|
2354
|
-
Jb = null;
|
|
2355
|
-
// corner -> posCache offset, precomputed
|
|
2318
|
+
// Per value: the area-weighted normal sum of its vertex's faces.
|
|
2319
|
+
Hb = null;
|
|
2356
2320
|
constructor(meshData) {
|
|
2357
2321
|
this.c = meshData;
|
|
2358
2322
|
}
|
|
@@ -2362,86 +2326,52 @@ var MeshPredictionSchemeGeometricNormalPredictorArea = class {
|
|
|
2362
2326
|
setEntryToPointIdMap(map) {
|
|
2363
2327
|
this.ya = map;
|
|
2364
2328
|
}
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
this.
|
|
2369
|
-
const
|
|
2370
|
-
const cornerToVertex = table.cornerToVertexArray();
|
|
2371
|
-
this.q = table.oppositeCornerArray();
|
|
2329
|
+
// Sums every face's area vector into its corners' values (see above).
|
|
2330
|
+
computeNormalSums(numEntries) {
|
|
2331
|
+
const pos = scratchInt32(numEntries * 3);
|
|
2332
|
+
fillInt32PositionCache(pos, this.xa, this.ya, numEntries);
|
|
2333
|
+
const cornerToVertex = this.c.cornerTable.cornerToVertexArray();
|
|
2372
2334
|
const vertexToDataMap = this.c.vertexToDataMap;
|
|
2373
|
-
const
|
|
2374
|
-
const
|
|
2375
|
-
for (let c = 0; c <
|
|
2376
|
-
const
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
const
|
|
2394
|
-
const
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
if (leftTraversal) {
|
|
2414
|
-
const opp = oppositeCorners[cNext];
|
|
2415
|
-
if (opp < 0) {
|
|
2416
|
-
currentCorner = -1;
|
|
2417
|
-
} else {
|
|
2418
|
-
const oppRem = opp - (opp / 3 | 0) * 3;
|
|
2419
|
-
currentCorner = oppRem === 2 ? opp - 2 : opp + 1;
|
|
2420
|
-
}
|
|
2421
|
-
if (currentCorner < 0) {
|
|
2422
|
-
const startRem = cornerId - (cornerId / 3 | 0) * 3;
|
|
2423
|
-
const startPrev = startRem === 0 ? cornerId + 2 : cornerId - 1;
|
|
2424
|
-
const startOpp = oppositeCorners[startPrev];
|
|
2425
|
-
if (startOpp < 0) {
|
|
2426
|
-
currentCorner = -1;
|
|
2427
|
-
} else {
|
|
2428
|
-
const startOppRem = startOpp - (startOpp / 3 | 0) * 3;
|
|
2429
|
-
currentCorner = startOppRem === 0 ? startOpp + 2 : startOpp - 1;
|
|
2430
|
-
}
|
|
2431
|
-
leftTraversal = false;
|
|
2432
|
-
} else if (currentCorner === cornerId) {
|
|
2433
|
-
currentCorner = -1;
|
|
2434
|
-
}
|
|
2435
|
-
} else {
|
|
2436
|
-
const opp = oppositeCorners[cPrev];
|
|
2437
|
-
if (opp < 0) {
|
|
2438
|
-
currentCorner = -1;
|
|
2439
|
-
} else {
|
|
2440
|
-
const oppRem = opp - (opp / 3 | 0) * 3;
|
|
2441
|
-
currentCorner = oppRem === 0 ? opp + 2 : opp - 1;
|
|
2442
|
-
}
|
|
2443
|
-
}
|
|
2444
|
-
}
|
|
2335
|
+
const sums = new Float64Array(numEntries * 3);
|
|
2336
|
+
const numCorners = cornerToVertex.length;
|
|
2337
|
+
for (let c = 0; c < numCorners; c += 3) {
|
|
2338
|
+
const v0 = cornerToVertex[c];
|
|
2339
|
+
const v1 = cornerToVertex[c + 1];
|
|
2340
|
+
const v2 = cornerToVertex[c + 2];
|
|
2341
|
+
if ((v0 | v1 | v2) < 0) return false;
|
|
2342
|
+
const o0 = vertexToDataMap[v0] * 3;
|
|
2343
|
+
const o1 = vertexToDataMap[v1] * 3;
|
|
2344
|
+
const o2 = vertexToDataMap[v2] * 3;
|
|
2345
|
+
const x0 = pos[o0];
|
|
2346
|
+
const y0 = pos[o0 + 1];
|
|
2347
|
+
const z0 = pos[o0 + 2];
|
|
2348
|
+
const ax = pos[o1] - x0;
|
|
2349
|
+
const ay = pos[o1 + 1] - y0;
|
|
2350
|
+
const az = pos[o1 + 2] - z0;
|
|
2351
|
+
const bx = pos[o2] - x0;
|
|
2352
|
+
const by = pos[o2 + 1] - y0;
|
|
2353
|
+
const bz = pos[o2 + 2] - z0;
|
|
2354
|
+
const nx = ay * bz - az * by;
|
|
2355
|
+
const ny = az * bx - ax * bz;
|
|
2356
|
+
const nz = ax * by - ay * bx;
|
|
2357
|
+
sums[o0] += nx;
|
|
2358
|
+
sums[o0 + 1] += ny;
|
|
2359
|
+
sums[o0 + 2] += nz;
|
|
2360
|
+
sums[o1] += nx;
|
|
2361
|
+
sums[o1 + 1] += ny;
|
|
2362
|
+
sums[o1 + 2] += nz;
|
|
2363
|
+
sums[o2] += nx;
|
|
2364
|
+
sums[o2 + 1] += ny;
|
|
2365
|
+
sums[o2 + 2] += nz;
|
|
2366
|
+
}
|
|
2367
|
+
this.Hb = sums;
|
|
2368
|
+
return true;
|
|
2369
|
+
}
|
|
2370
|
+
computePredictedValue(dataId, prediction) {
|
|
2371
|
+
const sums = this.Hb;
|
|
2372
|
+
let normalX = sums[dataId * 3];
|
|
2373
|
+
let normalY = sums[dataId * 3 + 1];
|
|
2374
|
+
let normalZ = sums[dataId * 3 + 2];
|
|
2445
2375
|
const absSum = Math.abs(normalX) + Math.abs(normalY) + Math.abs(normalZ);
|
|
2446
2376
|
if (absSum > UPPER_BOUND) {
|
|
2447
2377
|
const quotient = Math.floor(absSum / UPPER_BOUND);
|
|
@@ -2458,12 +2388,12 @@ var MeshPredictionSchemeGeometricNormalPredictorArea = class {
|
|
|
2458
2388
|
// src/decoder/compression/attributes/prediction_schemes/MeshPredictionSchemeGeometricNormalDecoder.ts
|
|
2459
2389
|
var GEOMETRY_ATTRIBUTE_POSITION = 0;
|
|
2460
2390
|
var MeshPredictionSchemeGeometricNormalDecoder = class extends MeshPredictionSchemeDecoder {
|
|
2461
|
-
|
|
2391
|
+
s;
|
|
2462
2392
|
z = new OctahedronToolBox();
|
|
2463
|
-
|
|
2393
|
+
cb = new RAnsBitDecoder();
|
|
2464
2394
|
constructor(transform, meshData) {
|
|
2465
2395
|
super(transform, meshData);
|
|
2466
|
-
this.
|
|
2396
|
+
this.s = new MeshPredictionSchemeGeometricNormalPredictorArea(meshData);
|
|
2467
2397
|
}
|
|
2468
2398
|
getNumParentAttributes() {
|
|
2469
2399
|
return 1;
|
|
@@ -2474,34 +2404,33 @@ var MeshPredictionSchemeGeometricNormalDecoder = class extends MeshPredictionSch
|
|
|
2474
2404
|
setParentAttribute(att) {
|
|
2475
2405
|
if (att.attributeType !== GEOMETRY_ATTRIBUTE_POSITION) return false;
|
|
2476
2406
|
if (att.numComponents !== 3) return false;
|
|
2477
|
-
this.
|
|
2407
|
+
this.s.setPositionAttribute(att);
|
|
2478
2408
|
return true;
|
|
2479
2409
|
}
|
|
2480
2410
|
decodePredictionData(buffer) {
|
|
2481
|
-
if (!this.
|
|
2482
|
-
return this.
|
|
2411
|
+
if (!this.e.decodeTransformData(buffer)) return false;
|
|
2412
|
+
return this.cb.startDecoding(buffer);
|
|
2483
2413
|
}
|
|
2484
2414
|
computeOriginalValues(inCorr, outData, _size, _numComponents, entryToPointIdMap) {
|
|
2485
|
-
this.z.setQuantizationBits(this.
|
|
2486
|
-
this.
|
|
2415
|
+
this.z.setQuantizationBits(this.e.quantizationBits());
|
|
2416
|
+
this.s.setEntryToPointIdMap(entryToPointIdMap);
|
|
2487
2417
|
const cornerMapSize = this.c.dataToCornerMap.length;
|
|
2488
|
-
this.
|
|
2418
|
+
if (!this.s.computeNormalSums(cornerMapSize)) return false;
|
|
2489
2419
|
const predNormal3D = new Int32Array(3);
|
|
2490
2420
|
const predNormalOct = new Int32Array(2);
|
|
2491
2421
|
for (let dataId = 0; dataId < cornerMapSize; ++dataId) {
|
|
2492
|
-
|
|
2493
|
-
this.t.computePredictedValue(cornerId, predNormal3D);
|
|
2422
|
+
this.s.computePredictedValue(dataId, predNormal3D);
|
|
2494
2423
|
this.z.canonicalizeIntegerVector(predNormal3D);
|
|
2495
|
-
if (this.
|
|
2424
|
+
if (this.cb.decodeNextBit()) {
|
|
2496
2425
|
predNormal3D[0] = -predNormal3D[0];
|
|
2497
2426
|
predNormal3D[1] = -predNormal3D[1];
|
|
2498
2427
|
predNormal3D[2] = -predNormal3D[2];
|
|
2499
2428
|
}
|
|
2500
2429
|
this.z.integerVectorToQuantizedOctahedralCoords(predNormal3D, predNormalOct);
|
|
2501
2430
|
const dataOffset = dataId * 2;
|
|
2502
|
-
this.
|
|
2431
|
+
this.e.computeOriginalValue(predNormalOct, 0, inCorr, dataOffset, outData, dataOffset);
|
|
2503
2432
|
}
|
|
2504
|
-
this.
|
|
2433
|
+
this.cb.endDecoding();
|
|
2505
2434
|
return true;
|
|
2506
2435
|
}
|
|
2507
2436
|
};
|
|
@@ -2510,10 +2439,10 @@ var MeshPredictionSchemeGeometricNormalDecoder = class extends MeshPredictionSch
|
|
|
2510
2439
|
var kInvalidCornerIndex3 = -1;
|
|
2511
2440
|
var MeshPredictionSchemeMultiParallelogramDecoder = class extends MeshPredictionSchemeDecoder {
|
|
2512
2441
|
computeOriginalValues(inCorr, outData, _size, numComponents, _entryToPointIdMap) {
|
|
2513
|
-
this.
|
|
2442
|
+
this.e.init(numComponents);
|
|
2514
2443
|
const predVals = new Int32Array(numComponents);
|
|
2515
2444
|
const parallelogramPredVals = new Int32Array(numComponents);
|
|
2516
|
-
this.
|
|
2445
|
+
this.e.computeOriginalValue(predVals, 0, inCorr, 0, outData, 0);
|
|
2517
2446
|
const table = this.c.cornerTable;
|
|
2518
2447
|
const vertexToDataMap = this.c.vertexToDataMap;
|
|
2519
2448
|
const oppositeCorners = table.oppositeCornerArray();
|
|
@@ -2550,12 +2479,12 @@ var MeshPredictionSchemeMultiParallelogramDecoder = class extends MeshPrediction
|
|
|
2550
2479
|
const dstOffset = p * numComponents;
|
|
2551
2480
|
if (numParallelograms === 0) {
|
|
2552
2481
|
const srcOffset = (p - 1) * numComponents;
|
|
2553
|
-
this.
|
|
2482
|
+
this.e.computeOriginalValue(outData, srcOffset, inCorr, dstOffset, outData, dstOffset);
|
|
2554
2483
|
} else {
|
|
2555
2484
|
for (let c = 0; c < numComponents; ++c) {
|
|
2556
2485
|
predVals[c] = predVals[c] / numParallelograms | 0;
|
|
2557
2486
|
}
|
|
2558
|
-
this.
|
|
2487
|
+
this.e.computeOriginalValue(predVals, 0, inCorr, dstOffset, outData, dstOffset);
|
|
2559
2488
|
}
|
|
2560
2489
|
}
|
|
2561
2490
|
return true;
|
|
@@ -2567,7 +2496,7 @@ var MeshPredictionSchemeParallelogramDecoder = class extends MeshPredictionSchem
|
|
|
2567
2496
|
// Zigzag-fused variant: decodes corrections that are still in their unsigned
|
|
2568
2497
|
// zigzag form, unpacking each one inline.
|
|
2569
2498
|
computeOriginalValuesZigzag(inCorr, outData, _size, numComponents, _entryToPointIdMap) {
|
|
2570
|
-
this.
|
|
2499
|
+
this.e.init(numComponents);
|
|
2571
2500
|
return this.kc(inCorr, outData, numComponents, true);
|
|
2572
2501
|
}
|
|
2573
2502
|
// The wrap transform's corrections are zigzag-coded; with `zigzag` set the
|
|
@@ -2587,9 +2516,9 @@ var MeshPredictionSchemeParallelogramDecoder = class extends MeshPredictionSchem
|
|
|
2587
2516
|
return this.nc(inCorr, outData, zigzag);
|
|
2588
2517
|
}
|
|
2589
2518
|
const parents = this.c.parallelogramParents();
|
|
2590
|
-
const transform = this.
|
|
2591
|
-
const minValue = transform.
|
|
2592
|
-
const maxValue = transform.
|
|
2519
|
+
const transform = this.e;
|
|
2520
|
+
const minValue = transform._;
|
|
2521
|
+
const maxValue = transform.n;
|
|
2593
2522
|
const maxDif = transform.ga;
|
|
2594
2523
|
for (let c = 0; c < numComponents; ++c) {
|
|
2595
2524
|
let pred = 0;
|
|
@@ -2655,9 +2584,9 @@ var MeshPredictionSchemeParallelogramDecoder = class extends MeshPredictionSchem
|
|
|
2655
2584
|
}
|
|
2656
2585
|
lc(inCorr, outData, zigzag) {
|
|
2657
2586
|
const parents = this.c.parallelogramParents();
|
|
2658
|
-
const transform = this.
|
|
2659
|
-
const minValue = transform.
|
|
2660
|
-
const maxValue = transform.
|
|
2587
|
+
const transform = this.e;
|
|
2588
|
+
const minValue = transform._;
|
|
2589
|
+
const maxValue = transform.n;
|
|
2661
2590
|
const maxDif = transform.ga;
|
|
2662
2591
|
let pred0 = 0;
|
|
2663
2592
|
let pred1 = 0;
|
|
@@ -2733,9 +2662,9 @@ var MeshPredictionSchemeParallelogramDecoder = class extends MeshPredictionSchem
|
|
|
2733
2662
|
}
|
|
2734
2663
|
mc(inCorr, outData, zigzag) {
|
|
2735
2664
|
const parents = this.c.parallelogramParents();
|
|
2736
|
-
const transform = this.
|
|
2737
|
-
const minValue = transform.
|
|
2738
|
-
const maxValue = transform.
|
|
2665
|
+
const transform = this.e;
|
|
2666
|
+
const minValue = transform._;
|
|
2667
|
+
const maxValue = transform.n;
|
|
2739
2668
|
const maxDif = transform.ga;
|
|
2740
2669
|
let pred0 = 0;
|
|
2741
2670
|
let pred1 = 0;
|
|
@@ -2842,9 +2771,9 @@ var MeshPredictionSchemeParallelogramDecoder = class extends MeshPredictionSchem
|
|
|
2842
2771
|
// structure as the 2/3-component loops.
|
|
2843
2772
|
nc(inCorr, outData, zigzag) {
|
|
2844
2773
|
const parents = this.c.parallelogramParents();
|
|
2845
|
-
const transform = this.
|
|
2846
|
-
const minValue = transform.
|
|
2847
|
-
const maxValue = transform.
|
|
2774
|
+
const transform = this.e;
|
|
2775
|
+
const minValue = transform._;
|
|
2776
|
+
const maxValue = transform.n;
|
|
2848
2777
|
const maxDif = transform.ga;
|
|
2849
2778
|
let pred0 = 0;
|
|
2850
2779
|
if (pred0 > maxValue) {
|
|
@@ -2950,14 +2879,13 @@ function bigIntSqrt(value) {
|
|
|
2950
2879
|
var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
2951
2880
|
xa = null;
|
|
2952
2881
|
ya = null;
|
|
2953
|
-
|
|
2954
|
-
Sa =
|
|
2955
|
-
|
|
2882
|
+
t = new Int32Array(2);
|
|
2883
|
+
Sa = EMPTY_UINT8;
|
|
2884
|
+
za = 0;
|
|
2956
2885
|
c;
|
|
2957
|
-
db = new Array(3);
|
|
2958
2886
|
// Flat Int32 position cache so fetches are array reads, not convertValue calls.
|
|
2959
|
-
|
|
2960
|
-
|
|
2887
|
+
Ib = null;
|
|
2888
|
+
k = null;
|
|
2961
2889
|
constructor(meshData) {
|
|
2962
2890
|
this.c = meshData;
|
|
2963
2891
|
}
|
|
@@ -2968,26 +2896,26 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
2968
2896
|
this.ya = map;
|
|
2969
2897
|
}
|
|
2970
2898
|
get predictedValue() {
|
|
2971
|
-
return this.
|
|
2899
|
+
return this.t;
|
|
2972
2900
|
}
|
|
2973
2901
|
resizeOrientations(numOrientations) {
|
|
2974
2902
|
this.Sa = new Uint8Array(numOrientations);
|
|
2975
|
-
this.
|
|
2903
|
+
this.za = numOrientations;
|
|
2976
2904
|
}
|
|
2977
2905
|
setOrientation(i, v) {
|
|
2978
2906
|
this.Sa[i] = v ? 1 : 0;
|
|
2979
2907
|
}
|
|
2980
2908
|
buildPositionCache(numEntries) {
|
|
2981
2909
|
const posCache = new Int32Array(numEntries * 3);
|
|
2982
|
-
fillInt32PositionCache(posCache, this.xa, this.ya, numEntries
|
|
2983
|
-
this.
|
|
2984
|
-
this.
|
|
2910
|
+
fillInt32PositionCache(posCache, this.xa, this.ya, numEntries);
|
|
2911
|
+
this.Ib = posCache;
|
|
2912
|
+
this.k = this.c.cornerTable.cornerToVertexArray();
|
|
2985
2913
|
}
|
|
2986
2914
|
computePredictedValue(cornerId, data, dataId) {
|
|
2987
2915
|
const rem = cornerId - (cornerId / 3 | 0) * 3;
|
|
2988
2916
|
const nextCornerId = rem === 2 ? cornerId - 2 : cornerId + 1;
|
|
2989
2917
|
const prevCornerId = rem === 0 ? cornerId + 2 : cornerId - 1;
|
|
2990
|
-
const cornerToVertex = this.
|
|
2918
|
+
const cornerToVertex = this.k;
|
|
2991
2919
|
const nextVertId = cornerToVertex[nextCornerId];
|
|
2992
2920
|
const prevVertId = cornerToVertex[prevCornerId];
|
|
2993
2921
|
const vertexToDataMap = this.c.vertexToDataMap;
|
|
@@ -2999,11 +2927,11 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
2999
2927
|
const nUV0 = data[nDataOff], nUV1 = data[nDataOff + 1];
|
|
3000
2928
|
const pUV0 = data[pDataOff], pUV1 = data[pDataOff + 1];
|
|
3001
2929
|
if (pUV0 === nUV0 && pUV1 === nUV1) {
|
|
3002
|
-
this.
|
|
3003
|
-
this.
|
|
2930
|
+
this.t[0] = pUV0;
|
|
2931
|
+
this.t[1] = pUV1;
|
|
3004
2932
|
return true;
|
|
3005
2933
|
}
|
|
3006
|
-
const posCache = this.
|
|
2934
|
+
const posCache = this.Ib;
|
|
3007
2935
|
let posOffset = dataId * 3;
|
|
3008
2936
|
const tip0 = posCache[posOffset];
|
|
3009
2937
|
const tip1 = posCache[posOffset + 1];
|
|
@@ -3027,19 +2955,12 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
3027
2955
|
const cnDotPn = pn0 * cn0 + pn1 * cn1 + pn2 * cn2;
|
|
3028
2956
|
const pnUV0 = pUV0 - nUV0;
|
|
3029
2957
|
const pnUV1 = pUV1 - nUV1;
|
|
3030
|
-
const INT64_MAX = 2 ** 63;
|
|
3031
2958
|
const nUVAbsMax = Math.max(Math.abs(nUV0), Math.abs(nUV1));
|
|
3032
|
-
if (nUVAbsMax > INT64_MAX / pnNorm2Squared) {
|
|
3033
|
-
return false;
|
|
3034
|
-
}
|
|
3035
2959
|
const pnUVAbsMax = Math.max(Math.abs(pnUV0), Math.abs(pnUV1));
|
|
3036
|
-
if (pnUVAbsMax > 0 && Math.abs(cnDotPn) > INT64_MAX / pnUVAbsMax) {
|
|
3037
|
-
return false;
|
|
3038
|
-
}
|
|
3039
2960
|
const cnNorm2 = cn0 * cn0 + cn1 * cn1 + cn2 * cn2;
|
|
3040
2961
|
const pnAbsMaxG = Math.max(Math.abs(pn0), Math.abs(pn1), Math.abs(pn2));
|
|
3041
2962
|
const cnDotPnAbs = Math.abs(cnDotPn);
|
|
3042
|
-
if (cnNorm2
|
|
2963
|
+
if (!(cnNorm2 * pnNorm2Squared < SAFE_PRODUCT && nUVAbsMax * pnNorm2Squared < SAFE_PRODUCT && cnDotPnAbs * pnUVAbsMax < SAFE_PRODUCT && cnDotPnAbs * pnAbsMaxG < SAFE_PRODUCT)) {
|
|
3043
2964
|
return this.oc(
|
|
3044
2965
|
tip0,
|
|
3045
2966
|
tip1,
|
|
@@ -3059,9 +2980,6 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
3059
2980
|
}
|
|
3060
2981
|
const xUV0 = nUV0 * pnNorm2Squared + cnDotPn * pnUV0;
|
|
3061
2982
|
const xUV1 = nUV1 * pnNorm2Squared + cnDotPn * pnUV1;
|
|
3062
|
-
if (pnAbsMaxG > 0 && cnDotPnAbs > INT64_MAX / pnAbsMaxG) {
|
|
3063
|
-
return false;
|
|
3064
|
-
}
|
|
3065
2983
|
const xPos0 = next0 + Math.trunc(cnDotPn * pn0 / pnNorm2Squared);
|
|
3066
2984
|
const xPos1 = next1 + Math.trunc(cnDotPn * pn1 / pnNorm2Squared);
|
|
3067
2985
|
const xPos2 = next2 + Math.trunc(cnDotPn * pn2 / pnNorm2Squared);
|
|
@@ -3072,16 +2990,16 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
3072
2990
|
const normSquared = Math.floor(Math.sqrt(cxNorm2Squared * pnNorm2Squared));
|
|
3073
2991
|
const cxUV0 = pnUV1 * normSquared;
|
|
3074
2992
|
const cxUV1 = -pnUV0 * normSquared;
|
|
3075
|
-
if (this.
|
|
2993
|
+
if (this.za === 0) {
|
|
3076
2994
|
return false;
|
|
3077
2995
|
}
|
|
3078
|
-
const orientation = this.Sa[--this.
|
|
2996
|
+
const orientation = this.Sa[--this.za];
|
|
3079
2997
|
if (orientation) {
|
|
3080
|
-
this.
|
|
3081
|
-
this.
|
|
2998
|
+
this.t[0] = Math.trunc((xUV0 + cxUV0) / pnNorm2Squared);
|
|
2999
|
+
this.t[1] = Math.trunc((xUV1 + cxUV1) / pnNorm2Squared);
|
|
3082
3000
|
} else {
|
|
3083
|
-
this.
|
|
3084
|
-
this.
|
|
3001
|
+
this.t[0] = Math.trunc((xUV0 - cxUV0) / pnNorm2Squared);
|
|
3002
|
+
this.t[1] = Math.trunc((xUV1 - cxUV1) / pnNorm2Squared);
|
|
3085
3003
|
}
|
|
3086
3004
|
return true;
|
|
3087
3005
|
}
|
|
@@ -3096,13 +3014,13 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
3096
3014
|
if (dataId > 0) {
|
|
3097
3015
|
dataOffset = (dataId - 1) * 2;
|
|
3098
3016
|
} else {
|
|
3099
|
-
this.
|
|
3100
|
-
this.
|
|
3017
|
+
this.t[0] = 0;
|
|
3018
|
+
this.t[1] = 0;
|
|
3101
3019
|
return true;
|
|
3102
3020
|
}
|
|
3103
3021
|
}
|
|
3104
|
-
this.
|
|
3105
|
-
this.
|
|
3022
|
+
this.t[0] = data[dataOffset];
|
|
3023
|
+
this.t[1] = data[dataOffset + 1];
|
|
3106
3024
|
return true;
|
|
3107
3025
|
}
|
|
3108
3026
|
// 64-bit-exact projection prediction, used when the double path would lose
|
|
@@ -3144,8 +3062,8 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
3144
3062
|
const normSquared = bigIntSqrt(cxNorm2 * pnN2 & MASK64);
|
|
3145
3063
|
const cxUV0 = B.asIntN(64, pnUV1 * normSquared);
|
|
3146
3064
|
const cxUV1 = B.asIntN(64, -pnUV0 * normSquared);
|
|
3147
|
-
if (this.
|
|
3148
|
-
const orientation = this.Sa[--this.
|
|
3065
|
+
if (this.za === 0) return false;
|
|
3066
|
+
const orientation = this.Sa[--this.za];
|
|
3149
3067
|
let s0, s1;
|
|
3150
3068
|
if (orientation) {
|
|
3151
3069
|
s0 = B.asUintN(64, B.asUintN(64, xUV0) + B.asUintN(64, cxUV0));
|
|
@@ -3154,8 +3072,8 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
3154
3072
|
s0 = B.asUintN(64, B.asUintN(64, xUV0) - B.asUintN(64, cxUV0));
|
|
3155
3073
|
s1 = B.asUintN(64, B.asUintN(64, xUV1) - B.asUintN(64, cxUV1));
|
|
3156
3074
|
}
|
|
3157
|
-
this.
|
|
3158
|
-
this.
|
|
3075
|
+
this.t[0] = Number(B.asIntN(32, B.asIntN(64, s0) / pnN2));
|
|
3076
|
+
this.t[1] = Number(B.asIntN(32, B.asIntN(64, s1) / pnN2));
|
|
3159
3077
|
return true;
|
|
3160
3078
|
}
|
|
3161
3079
|
};
|
|
@@ -3163,10 +3081,10 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
3163
3081
|
// src/decoder/compression/attributes/prediction_schemes/MeshPredictionSchemeTexCoordsPortableDecoder.ts
|
|
3164
3082
|
var GEOMETRY_ATTRIBUTE_POSITION2 = 0;
|
|
3165
3083
|
var MeshPredictionSchemeTexCoordsPortableDecoder = class extends MeshPredictionSchemeDecoder {
|
|
3166
|
-
|
|
3084
|
+
s;
|
|
3167
3085
|
constructor(transform, meshData) {
|
|
3168
3086
|
super(transform, meshData);
|
|
3169
|
-
this.
|
|
3087
|
+
this.s = new MeshPredictionSchemeTexCoordsPortablePredictor(meshData);
|
|
3170
3088
|
}
|
|
3171
3089
|
getNumParentAttributes() {
|
|
3172
3090
|
return 1;
|
|
@@ -3177,13 +3095,13 @@ var MeshPredictionSchemeTexCoordsPortableDecoder = class extends MeshPredictionS
|
|
|
3177
3095
|
setParentAttribute(att) {
|
|
3178
3096
|
if (att.attributeType !== GEOMETRY_ATTRIBUTE_POSITION2) return false;
|
|
3179
3097
|
if (att.numComponents !== 3) return false;
|
|
3180
|
-
this.
|
|
3098
|
+
this.s.setPositionAttribute(att);
|
|
3181
3099
|
return true;
|
|
3182
3100
|
}
|
|
3183
3101
|
decodePredictionData(buffer) {
|
|
3184
3102
|
const numOrientations = buffer.decodeInt32();
|
|
3185
3103
|
if (numOrientations === void 0 || numOrientations < 0) return false;
|
|
3186
|
-
this.
|
|
3104
|
+
this.s.resizeOrientations(numOrientations);
|
|
3187
3105
|
let lastOrientation = true;
|
|
3188
3106
|
const decoder = new RAnsBitDecoder();
|
|
3189
3107
|
if (!decoder.startDecoding(buffer)) return false;
|
|
@@ -3191,7 +3109,7 @@ var MeshPredictionSchemeTexCoordsPortableDecoder = class extends MeshPredictionS
|
|
|
3191
3109
|
if (!decoder.decodeNextBit()) {
|
|
3192
3110
|
lastOrientation = !lastOrientation;
|
|
3193
3111
|
}
|
|
3194
|
-
this.
|
|
3112
|
+
this.s.setOrientation(i, lastOrientation);
|
|
3195
3113
|
}
|
|
3196
3114
|
decoder.endDecoding();
|
|
3197
3115
|
return super.decodePredictionData(buffer);
|
|
@@ -3200,17 +3118,17 @@ var MeshPredictionSchemeTexCoordsPortableDecoder = class extends MeshPredictionS
|
|
|
3200
3118
|
if (numComponents !== 2) {
|
|
3201
3119
|
return false;
|
|
3202
3120
|
}
|
|
3203
|
-
this.
|
|
3204
|
-
this.
|
|
3121
|
+
this.s.setEntryToPointIdMap(entryToPointIdMap);
|
|
3122
|
+
this.e.init(numComponents);
|
|
3205
3123
|
const cornerMapSize = this.c.dataToCornerMap.length;
|
|
3206
|
-
this.
|
|
3124
|
+
this.s.buildPositionCache(cornerMapSize);
|
|
3207
3125
|
for (let p = 0; p < cornerMapSize; ++p) {
|
|
3208
3126
|
const cornerId = this.c.dataToCornerMap[p];
|
|
3209
|
-
if (!this.
|
|
3127
|
+
if (!this.s.computePredictedValue(cornerId, outData, p)) {
|
|
3210
3128
|
return false;
|
|
3211
3129
|
}
|
|
3212
3130
|
const dstOffset = p * numComponents;
|
|
3213
|
-
this.
|
|
3131
|
+
this.e.computeOriginalValue(this.s.predictedValue, 0, inCorr, dstOffset, outData, dstOffset);
|
|
3214
3132
|
}
|
|
3215
3133
|
return true;
|
|
3216
3134
|
}
|
|
@@ -3219,7 +3137,7 @@ var MeshPredictionSchemeTexCoordsPortableDecoder = class extends MeshPredictionS
|
|
|
3219
3137
|
// src/decoder/compression/attributes/prediction_schemes/PredictionSchemeDeltaDecoder.ts
|
|
3220
3138
|
var PredictionSchemeDeltaDecoder = class extends PredictionSchemeDecoder {
|
|
3221
3139
|
computeOriginalValues(inCorr, outData, size, numComponents, _entryToPointIdMap) {
|
|
3222
|
-
const transform = this.
|
|
3140
|
+
const transform = this.e;
|
|
3223
3141
|
transform.init(numComponents);
|
|
3224
3142
|
if (transform.computeOriginalValuesDelta) {
|
|
3225
3143
|
transform.computeOriginalValuesDelta(inCorr, outData, size, numComponents);
|
|
@@ -3275,8 +3193,8 @@ function createPredictionSchemeForDecoder(method, attId, decoder, transform) {
|
|
|
3275
3193
|
// src/decoder/compression/attributes/prediction_schemes/PredictionSchemeWrapDecodingTransform.ts
|
|
3276
3194
|
var PredictionSchemeWrapDecodingTransform = class {
|
|
3277
3195
|
y = 0;
|
|
3278
|
-
|
|
3279
|
-
|
|
3196
|
+
_ = 0;
|
|
3197
|
+
n = 0;
|
|
3280
3198
|
ga = 0;
|
|
3281
3199
|
getType() {
|
|
3282
3200
|
return 1 /* PREDICTION_TRANSFORM_WRAP */;
|
|
@@ -3288,12 +3206,12 @@ var PredictionSchemeWrapDecodingTransform = class {
|
|
|
3288
3206
|
return false;
|
|
3289
3207
|
}
|
|
3290
3208
|
boundsValues(limit) {
|
|
3291
|
-
return this.
|
|
3209
|
+
return this.n < limit && this._ > -limit;
|
|
3292
3210
|
}
|
|
3293
3211
|
computeOriginalValue(predictedVals, predictedOffset, corrVals, corrOffset, outOriginalVals, outOffset) {
|
|
3294
3212
|
const nc = this.y;
|
|
3295
|
-
const minValue = this.
|
|
3296
|
-
const maxValue = this.
|
|
3213
|
+
const minValue = this._;
|
|
3214
|
+
const maxValue = this.n;
|
|
3297
3215
|
const maxDif = this.ga;
|
|
3298
3216
|
for (let i = 0; i < nc; ++i) {
|
|
3299
3217
|
let pred = predictedVals[predictedOffset + i];
|
|
@@ -3318,8 +3236,8 @@ var PredictionSchemeWrapDecodingTransform = class {
|
|
|
3318
3236
|
if (maxValue === void 0) return false;
|
|
3319
3237
|
const dif = maxValue - minValue;
|
|
3320
3238
|
if (dif < 0 || dif >= 2147483647) return false;
|
|
3321
|
-
this.
|
|
3322
|
-
this.
|
|
3239
|
+
this._ = minValue;
|
|
3240
|
+
this.n = maxValue;
|
|
3323
3241
|
this.ga = 1 + dif;
|
|
3324
3242
|
return true;
|
|
3325
3243
|
}
|
|
@@ -3327,25 +3245,27 @@ var PredictionSchemeWrapDecodingTransform = class {
|
|
|
3327
3245
|
|
|
3328
3246
|
// src/decoder/compression/attributes/SequentialIntegerAttributeDecoder.ts
|
|
3329
3247
|
var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder {
|
|
3330
|
-
|
|
3248
|
+
P = null;
|
|
3331
3249
|
// Two-phase decode state (see SequentialAttributeDecoder): the parse phase
|
|
3332
3250
|
// stashes the primed raw-symbol stream here so the controller can batch and
|
|
3333
3251
|
// pair several attributes' decodes; the finish phase consumes it.
|
|
3334
3252
|
ha = null;
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
//
|
|
3338
|
-
|
|
3253
|
+
db = 0;
|
|
3254
|
+
Jb = null;
|
|
3255
|
+
// The decoded (portable) values, numComponents per entry (see
|
|
3256
|
+
// preparePortableAttribute).
|
|
3257
|
+
Q = null;
|
|
3258
|
+
Kb = 0;
|
|
3339
3259
|
// --- Two-phase decode (parse headers / batch symbol decode / finish) ---
|
|
3340
3260
|
pendingSymbolStream() {
|
|
3341
3261
|
if (this.ha === null) {
|
|
3342
3262
|
return null;
|
|
3343
3263
|
}
|
|
3344
|
-
const portableData = this.
|
|
3264
|
+
const portableData = this.Q;
|
|
3345
3265
|
return {
|
|
3346
|
-
ans: this.ha.
|
|
3347
|
-
out: new Uint32Array(portableData.buffer, portableData.byteOffset, this.
|
|
3348
|
-
count: this.
|
|
3266
|
+
ans: this.ha.L,
|
|
3267
|
+
out: new Uint32Array(portableData.buffer, portableData.byteOffset, this.db),
|
|
3268
|
+
count: this.db
|
|
3349
3269
|
};
|
|
3350
3270
|
}
|
|
3351
3271
|
decodePortableAttributeFinish() {
|
|
@@ -3353,13 +3273,13 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
|
|
|
3353
3273
|
this.ha.endDecoding();
|
|
3354
3274
|
this.ha = null;
|
|
3355
3275
|
}
|
|
3356
|
-
return this.pc(this.
|
|
3276
|
+
return this.pc(this.Jb);
|
|
3357
3277
|
}
|
|
3358
3278
|
// The parse phase of the integer decode: prediction scheme, portable
|
|
3359
3279
|
// attribute, the symbol stream (raw streams are deferred to the finish
|
|
3360
3280
|
// phase) and the prediction data.
|
|
3361
3281
|
decodeValues(pointIds, buffer) {
|
|
3362
|
-
this.
|
|
3282
|
+
this.Jb = pointIds;
|
|
3363
3283
|
let predictionSchemeMethod = buffer.decodeUint8();
|
|
3364
3284
|
if (predictionSchemeMethod !== void 0) predictionSchemeMethod = predictionSchemeMethod << 24 >> 24;
|
|
3365
3285
|
if (predictionSchemeMethod === void 0) return false;
|
|
@@ -3373,10 +3293,10 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
|
|
|
3373
3293
|
if (predictionTransformType < -1 /* PREDICTION_TRANSFORM_NONE */ || predictionTransformType >= 4 /* NUM_PREDICTION_SCHEME_TRANSFORM_TYPES */) {
|
|
3374
3294
|
return false;
|
|
3375
3295
|
}
|
|
3376
|
-
this.
|
|
3296
|
+
this.P = this.createIntPredictionScheme(predictionSchemeMethod, predictionTransformType);
|
|
3377
3297
|
}
|
|
3378
|
-
if (this.
|
|
3379
|
-
if (!this.initPredictionScheme(this.
|
|
3298
|
+
if (this.P) {
|
|
3299
|
+
if (!this.initPredictionScheme(this.P)) {
|
|
3380
3300
|
return false;
|
|
3381
3301
|
}
|
|
3382
3302
|
}
|
|
@@ -3387,7 +3307,7 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
|
|
|
3387
3307
|
const numEntries = pointIds.length;
|
|
3388
3308
|
const numValues = numEntries * numComponents;
|
|
3389
3309
|
this.preparePortableAttribute(numEntries, numComponents);
|
|
3390
|
-
const portableAttributeData = this.
|
|
3310
|
+
const portableAttributeData = this.Q;
|
|
3391
3311
|
if (portableAttributeData === null) {
|
|
3392
3312
|
return false;
|
|
3393
3313
|
}
|
|
@@ -3402,7 +3322,7 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
|
|
|
3402
3322
|
return false;
|
|
3403
3323
|
}
|
|
3404
3324
|
this.ha = decoder;
|
|
3405
|
-
this.
|
|
3325
|
+
this.db = numValues;
|
|
3406
3326
|
} else if (scheme === 0 /* SYMBOL_CODING_TAGGED */) {
|
|
3407
3327
|
const outUint32 = new Uint32Array(portableAttributeData.buffer, portableAttributeData.byteOffset, numValues);
|
|
3408
3328
|
if (!decodeTaggedSymbols(numValues, numComponents, buffer, outUint32)) {
|
|
@@ -3426,8 +3346,8 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
|
|
|
3426
3346
|
portableAttributeData[i] = val;
|
|
3427
3347
|
}
|
|
3428
3348
|
}
|
|
3429
|
-
if (this.
|
|
3430
|
-
if (!this.
|
|
3349
|
+
if (this.P) {
|
|
3350
|
+
if (!this.P.decodePredictionData(buffer)) {
|
|
3431
3351
|
return false;
|
|
3432
3352
|
}
|
|
3433
3353
|
}
|
|
@@ -3437,14 +3357,14 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
|
|
|
3437
3357
|
pc(pointIds) {
|
|
3438
3358
|
const numComponents = this.getNumValueComponents();
|
|
3439
3359
|
const numValues = pointIds.length * numComponents;
|
|
3440
|
-
const data = this.
|
|
3360
|
+
const data = this.Q;
|
|
3441
3361
|
if (data === null) {
|
|
3442
3362
|
return false;
|
|
3443
3363
|
}
|
|
3444
3364
|
if (numValues === 0) {
|
|
3445
3365
|
return true;
|
|
3446
3366
|
}
|
|
3447
|
-
const ps = this.
|
|
3367
|
+
const ps = this.P;
|
|
3448
3368
|
if (ps === null) {
|
|
3449
3369
|
convertSymbolsToSignedInts(new Uint32Array(data.buffer, data.byteOffset, numValues), numValues, data);
|
|
3450
3370
|
return true;
|
|
@@ -3459,7 +3379,7 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
|
|
|
3459
3379
|
return ps.computeOriginalValues(data, data, numValues, numComponents, pointIds);
|
|
3460
3380
|
}
|
|
3461
3381
|
transformAttributeToOriginalFormat(pointIds) {
|
|
3462
|
-
return this.
|
|
3382
|
+
return this.eb(pointIds.length);
|
|
3463
3383
|
}
|
|
3464
3384
|
// Prediction scheme for decoding integer values; subclasses override for others.
|
|
3465
3385
|
createIntPredictionScheme(method, transformType) {
|
|
@@ -3477,43 +3397,59 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
|
|
|
3477
3397
|
// see PointAttribute._lazyFloatValues): true when a prediction transform
|
|
3478
3398
|
// clamps them into such a range. Unpredicted values are unbounded.
|
|
3479
3399
|
Lb() {
|
|
3480
|
-
return this.
|
|
3400
|
+
return this.P !== null && this.P.boundsValues(16777216);
|
|
3481
3401
|
}
|
|
3482
3402
|
// The decoded values stay in the portable attribute; the final attribute
|
|
3483
3403
|
// only takes its size (see PointAttribute.setLazyInteger and the overrides
|
|
3484
3404
|
// in the quantization / normal decoders).
|
|
3485
|
-
|
|
3405
|
+
Fb(numValues) {
|
|
3486
3406
|
this.attribute.resetLazy(numValues);
|
|
3487
3407
|
return true;
|
|
3488
3408
|
}
|
|
3489
3409
|
// Hands the decoded integer values to the attribute, converted to its
|
|
3490
3410
|
// integer type on extraction.
|
|
3491
|
-
|
|
3411
|
+
eb(_numValues) {
|
|
3492
3412
|
const dt = this.attribute.dataType;
|
|
3493
3413
|
if (dt < 1 /* INT8 */ || dt > 6 /* UINT32 */) {
|
|
3494
3414
|
return false;
|
|
3495
3415
|
}
|
|
3496
|
-
this.attribute.setLazyInteger(this.
|
|
3416
|
+
this.attribute.setLazyInteger(this.Q);
|
|
3497
3417
|
return true;
|
|
3498
3418
|
}
|
|
3419
|
+
// Heap-backed: the decoded values are what the final attribute hands out
|
|
3420
|
+
// (see _storeValues), so they outlive the decode. The portable
|
|
3421
|
+
// PointAttribute around them is only built if a dependent attribute's
|
|
3422
|
+
// predictor asks for it (see getPortableAttribute).
|
|
3499
3423
|
preparePortableAttribute(numEntries, numComponents) {
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3424
|
+
this.Kb = numComponents;
|
|
3425
|
+
this.Q = numEntries === 0 ? null : new Int32Array(numEntries * numComponents);
|
|
3426
|
+
}
|
|
3427
|
+
getPortableAttribute() {
|
|
3428
|
+
const numComponents = this.Kb;
|
|
3429
|
+
if (this.Z === null && numComponents > 0) {
|
|
3430
|
+
const ga = new GeometryAttribute();
|
|
3431
|
+
ga.init(
|
|
3432
|
+
this.attribute.attributeType,
|
|
3433
|
+
null,
|
|
3434
|
+
numComponents,
|
|
3435
|
+
5 /* INT32 */,
|
|
3436
|
+
false,
|
|
3437
|
+
numComponents * dataTypeLength(5 /* INT32 */),
|
|
3438
|
+
0
|
|
3439
|
+
);
|
|
3440
|
+
const portAtt = new PointAttribute(ga);
|
|
3441
|
+
portAtt.setIdentityMapping();
|
|
3442
|
+
const data = this.Q;
|
|
3443
|
+
if (data === null) portAtt.reset(0);
|
|
3444
|
+
else
|
|
3445
|
+
portAtt.resetWithData(
|
|
3446
|
+
new Uint8Array(data.buffer, data.byteOffset, data.byteLength),
|
|
3447
|
+
data.length / numComponents
|
|
3448
|
+
);
|
|
3449
|
+
portAtt.uniqueId = this.attribute.uniqueId;
|
|
3450
|
+
this.Z = portAtt;
|
|
3451
|
+
}
|
|
3452
|
+
return super.getPortableAttribute();
|
|
3517
3453
|
}
|
|
3518
3454
|
};
|
|
3519
3455
|
|
|
@@ -3561,7 +3497,7 @@ var PredictionSchemeNormalOctahedronCanonicalizedDecodingTransform = class exten
|
|
|
3561
3497
|
}
|
|
3562
3498
|
computeOriginalValue(predVals, predOffset, corrVals, corrOffset, outOrigVals, outOffset) {
|
|
3563
3499
|
const toolBox = this.z;
|
|
3564
|
-
const center = toolBox.
|
|
3500
|
+
const center = toolBox.f;
|
|
3565
3501
|
const maxQuantizedValue = toolBox.fa;
|
|
3566
3502
|
const corrS = corrVals[corrOffset];
|
|
3567
3503
|
const corrT = corrVals[corrOffset + 1];
|
|
@@ -3689,7 +3625,7 @@ var PredictionSchemeNormalOctahedronCanonicalizedDecodingTransform = class exten
|
|
|
3689
3625
|
// sync; only the plumbing differs.
|
|
3690
3626
|
computeOriginalValuesDelta(inCorr, outData, size, numComponents) {
|
|
3691
3627
|
const toolBox = this.z;
|
|
3692
|
-
const center = toolBox.
|
|
3628
|
+
const center = toolBox.f;
|
|
3693
3629
|
const maxQuantizedValue = toolBox.fa;
|
|
3694
3630
|
let prevS = 0;
|
|
3695
3631
|
let prevT = 0;
|
|
@@ -3828,7 +3764,7 @@ var PredictionSchemeNormalOctahedronDecodingTransform = class extends Prediction
|
|
|
3828
3764
|
}
|
|
3829
3765
|
computeOriginalValue(predVals, predOffset, corrVals, corrOffset, outOrigVals, outOffset) {
|
|
3830
3766
|
const toolBox = this.z;
|
|
3831
|
-
const center = toolBox.
|
|
3767
|
+
const center = toolBox.f;
|
|
3832
3768
|
const maxQuantizedValue = toolBox.fa;
|
|
3833
3769
|
const predS = predVals[predOffset] - center;
|
|
3834
3770
|
const predT = predVals[predOffset + 1] - center;
|
|
@@ -3908,7 +3844,7 @@ var PredictionSchemeNormalOctahedronDecodingTransform = class extends Prediction
|
|
|
3908
3844
|
|
|
3909
3845
|
// src/decoder/compression/attributes/SequentialNormalAttributeDecoder.ts
|
|
3910
3846
|
var SequentialNormalAttributeDecoder = class extends SequentialIntegerAttributeDecoder {
|
|
3911
|
-
|
|
3847
|
+
O = -1;
|
|
3912
3848
|
init(decoder, attributeId) {
|
|
3913
3849
|
if (!super.init(decoder, attributeId)) {
|
|
3914
3850
|
return false;
|
|
@@ -3923,16 +3859,16 @@ var SequentialNormalAttributeDecoder = class extends SequentialIntegerAttributeD
|
|
|
3923
3859
|
decodeDataNeededByPortableTransform(_pointIds, buffer) {
|
|
3924
3860
|
const qBits = buffer.decodeUint8();
|
|
3925
3861
|
if (qBits === void 0) return false;
|
|
3926
|
-
this.
|
|
3862
|
+
this.O = qBits;
|
|
3927
3863
|
return true;
|
|
3928
3864
|
}
|
|
3929
3865
|
// The octahedral-to-unit-vector transform is deferred to extractTo (see
|
|
3930
3866
|
// PointAttribute.setLazyOctahedron).
|
|
3931
|
-
|
|
3932
|
-
const q = this.
|
|
3867
|
+
eb(_numPoints) {
|
|
3868
|
+
const q = this.O;
|
|
3933
3869
|
if (q < 2 || q > 30) return false;
|
|
3934
3870
|
this.attribute.setLazyOctahedron(
|
|
3935
|
-
this.
|
|
3871
|
+
this.Q,
|
|
3936
3872
|
Math.fround(2 / Math.fround((1 << q) - 2)),
|
|
3937
3873
|
this.Lb()
|
|
3938
3874
|
);
|
|
@@ -3949,8 +3885,8 @@ var SequentialNormalAttributeDecoder = class extends SequentialIntegerAttributeD
|
|
|
3949
3885
|
|
|
3950
3886
|
// src/decoder/compression/attributes/SequentialQuantizationAttributeDecoder.ts
|
|
3951
3887
|
var SequentialQuantizationAttributeDecoder = class extends SequentialIntegerAttributeDecoder {
|
|
3952
|
-
|
|
3953
|
-
|
|
3888
|
+
O = -1;
|
|
3889
|
+
fb = [];
|
|
3954
3890
|
Nb = 0;
|
|
3955
3891
|
init(decoder, attributeId) {
|
|
3956
3892
|
if (!super.init(decoder, attributeId)) {
|
|
@@ -3961,39 +3897,39 @@ var SequentialQuantizationAttributeDecoder = class extends SequentialIntegerAttr
|
|
|
3961
3897
|
// The quantization parameters (AttributeQuantizationTransform::DecodeParameters).
|
|
3962
3898
|
decodeDataNeededByPortableTransform(_pointIds, buffer) {
|
|
3963
3899
|
const numComponents = this.attribute.numComponents;
|
|
3964
|
-
this.
|
|
3900
|
+
this.fb = new Array(numComponents);
|
|
3965
3901
|
for (let i = 0; i < numComponents; i++) {
|
|
3966
3902
|
const val = buffer.decodeFloat32();
|
|
3967
3903
|
if (val === void 0) return false;
|
|
3968
|
-
this.
|
|
3904
|
+
this.fb[i] = val;
|
|
3969
3905
|
}
|
|
3970
3906
|
const range = buffer.decodeFloat32();
|
|
3971
3907
|
if (range === void 0) return false;
|
|
3972
3908
|
this.Nb = range;
|
|
3973
3909
|
const qBits = buffer.decodeUint8();
|
|
3974
3910
|
if (qBits === void 0 || qBits < 1 || qBits > 30) return false;
|
|
3975
|
-
this.
|
|
3911
|
+
this.O = qBits;
|
|
3976
3912
|
return true;
|
|
3977
3913
|
}
|
|
3978
3914
|
// Dequantization is deferred to extractTo (see PointAttribute.setLazyQuantized).
|
|
3979
|
-
|
|
3980
|
-
const maxQuantizedValue = (1 << this.
|
|
3915
|
+
eb(_numValues) {
|
|
3916
|
+
const maxQuantizedValue = (1 << this.O >>> 0) - 1;
|
|
3981
3917
|
if (maxQuantizedValue <= 0) return false;
|
|
3982
3918
|
const delta = Math.fround(this.Nb / Math.fround(maxQuantizedValue));
|
|
3983
|
-
this.attribute.setLazyQuantized(this.
|
|
3919
|
+
this.attribute.setLazyQuantized(this.Q, this.fb, delta, this.Lb());
|
|
3984
3920
|
return true;
|
|
3985
3921
|
}
|
|
3986
3922
|
};
|
|
3987
3923
|
|
|
3988
3924
|
// src/decoder/compression/attributes/SequentialAttributeDecodersController.ts
|
|
3989
3925
|
var SequentialAttributeDecodersController = class extends AttributesDecoder {
|
|
3990
|
-
|
|
3926
|
+
ia = [];
|
|
3991
3927
|
// Replaced by the sequencer's output in _prepareSequence.
|
|
3992
|
-
Ta =
|
|
3993
|
-
|
|
3928
|
+
Ta = EMPTY_INT32;
|
|
3929
|
+
$;
|
|
3994
3930
|
constructor(sequencer) {
|
|
3995
3931
|
super();
|
|
3996
|
-
this
|
|
3932
|
+
this.$ = sequencer;
|
|
3997
3933
|
}
|
|
3998
3934
|
decodeAttributesDecoderData(buffer) {
|
|
3999
3935
|
if (!super.decodeAttributesDecoderData(buffer)) {
|
|
@@ -4007,19 +3943,21 @@ var SequentialAttributeDecodersController = class extends AttributesDecoder {
|
|
|
4007
3943
|
if (decoder === null || !decoder.init(this.getDecoder(), this.getAttributeId(i))) {
|
|
4008
3944
|
return false;
|
|
4009
3945
|
}
|
|
4010
|
-
this.
|
|
3946
|
+
this.ia[i] = decoder;
|
|
4011
3947
|
}
|
|
4012
3948
|
return true;
|
|
4013
3949
|
}
|
|
4014
|
-
qc() {
|
|
4015
|
-
|
|
3950
|
+
qc(buffer) {
|
|
3951
|
+
const first = this.ia[0];
|
|
3952
|
+
const parallelogram = first instanceof SequentialIntegerAttributeDecoder && buffer.remainingSize > 0 && buffer.data[buffer.decodedSize] === 1 /* MESH_PREDICTION_PARALLELOGRAM */;
|
|
3953
|
+
if (!this.$.generateSequence(parallelogram)) {
|
|
4016
3954
|
return false;
|
|
4017
3955
|
}
|
|
4018
|
-
this.Ta = this
|
|
3956
|
+
this.Ta = this.$.getOutputPointIds();
|
|
4019
3957
|
const numAttributes = this.getNumAttributes();
|
|
4020
3958
|
for (let i = 0; i < numAttributes; i++) {
|
|
4021
3959
|
const pa = this.getDecoder().pointCloud().attribute(this.getAttributeId(i));
|
|
4022
|
-
if (!this
|
|
3960
|
+
if (!this.$.updatePointToAttributeIndexMapping(pa)) {
|
|
4023
3961
|
return false;
|
|
4024
3962
|
}
|
|
4025
3963
|
}
|
|
@@ -4033,10 +3971,10 @@ var SequentialAttributeDecodersController = class extends AttributesDecoder {
|
|
|
4033
3971
|
// of the finish work reads the buffer, and dependents only read parent
|
|
4034
3972
|
// portable VALUES in finish, so ordering and output stay identical.
|
|
4035
3973
|
decodeAttributesParse(buffer) {
|
|
4036
|
-
if (!this.qc()) {
|
|
3974
|
+
if (!this.qc(buffer)) {
|
|
4037
3975
|
return false;
|
|
4038
3976
|
}
|
|
4039
|
-
const decoders = this.
|
|
3977
|
+
const decoders = this.ia;
|
|
4040
3978
|
for (let i = 0; i < decoders.length; i++) {
|
|
4041
3979
|
if (!decoders[i].decodePortableAttributeParse(this.Ta, buffer)) {
|
|
4042
3980
|
return false;
|
|
@@ -4050,7 +3988,7 @@ var SequentialAttributeDecodersController = class extends AttributesDecoder {
|
|
|
4050
3988
|
return true;
|
|
4051
3989
|
}
|
|
4052
3990
|
collectPendingSymbolStreams(out) {
|
|
4053
|
-
const decoders = this.
|
|
3991
|
+
const decoders = this.ia;
|
|
4054
3992
|
for (let i = 0; i < decoders.length; i++) {
|
|
4055
3993
|
const pending = decoders[i].pendingSymbolStream();
|
|
4056
3994
|
if (pending !== null) {
|
|
@@ -4059,7 +3997,7 @@ var SequentialAttributeDecodersController = class extends AttributesDecoder {
|
|
|
4059
3997
|
}
|
|
4060
3998
|
}
|
|
4061
3999
|
decodeAttributesFinish() {
|
|
4062
|
-
const decoders = this.
|
|
4000
|
+
const decoders = this.ia;
|
|
4063
4001
|
for (let i = 0; i < decoders.length; i++) {
|
|
4064
4002
|
if (!decoders[i].decodePortableAttributeFinish()) {
|
|
4065
4003
|
return false;
|
|
@@ -4077,7 +4015,7 @@ var SequentialAttributeDecodersController = class extends AttributesDecoder {
|
|
|
4077
4015
|
if (locId < 0) {
|
|
4078
4016
|
return null;
|
|
4079
4017
|
}
|
|
4080
|
-
return this.
|
|
4018
|
+
return this.ia[locId].getPortableAttribute();
|
|
4081
4019
|
}
|
|
4082
4020
|
createSequentialDecoder(decoderType) {
|
|
4083
4021
|
switch (decoderType) {
|
|
@@ -4116,27 +4054,35 @@ var kInvalidFaceIndex = -1;
|
|
|
4116
4054
|
var kInvalidVertexIndex = -1;
|
|
4117
4055
|
var DepthFirstTraverser = class {
|
|
4118
4056
|
a = null;
|
|
4119
|
-
|
|
4120
|
-
|
|
4057
|
+
Aa = null;
|
|
4058
|
+
Ba = null;
|
|
4121
4059
|
Ob = [];
|
|
4122
|
-
|
|
4060
|
+
Ca = 0;
|
|
4123
4061
|
// Identifies the traversal order for the shared traversal cache
|
|
4124
4062
|
// (MESH_TRAVERSAL_DEPTH_FIRST). See MeshTraversalSequencer.
|
|
4125
4063
|
Pb = 0;
|
|
4126
4064
|
// The sequencer derives the point id sequence from the corner map after
|
|
4127
|
-
// the traversal (see
|
|
4065
|
+
// the traversal (see traverseAll).
|
|
4128
4066
|
emitsPointIds = false;
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4067
|
+
k = null;
|
|
4068
|
+
w = null;
|
|
4069
|
+
C = null;
|
|
4070
|
+
M = 0;
|
|
4071
|
+
// When set (see MeshTraversalSequencer.generateSequence), each new value's
|
|
4072
|
+
// parallelogram parents are recorded here as it is numbered: parents[3p ..
|
|
4073
|
+
// 3p+2] are the value ids of the vertices of the face opposite its corner,
|
|
4074
|
+
// or parents[3p] is -1 when that face is missing or has a vertex not
|
|
4075
|
+
// numbered yet -- exactly MeshPredictionSchemeData.parallelogramParents'
|
|
4076
|
+
// "parent decoded after it" test, since values are numbered in order.
|
|
4077
|
+
// The traversal has just touched those corners, so they are read hot.
|
|
4078
|
+
Qb = null;
|
|
4133
4079
|
init(cornerTable, observer) {
|
|
4134
4080
|
this.a = cornerTable;
|
|
4135
|
-
this.
|
|
4136
|
-
this.
|
|
4137
|
-
this.
|
|
4138
|
-
this.
|
|
4139
|
-
this.
|
|
4081
|
+
this.Aa = observer;
|
|
4082
|
+
this.k = cornerTable.cornerToVertexArray();
|
|
4083
|
+
this.w = cornerTable.oppositeCornerArray();
|
|
4084
|
+
this.C = cornerTable.vertexOnBoundaryArray();
|
|
4085
|
+
this.M = cornerTable.numCorners();
|
|
4140
4086
|
}
|
|
4141
4087
|
cornerTable() {
|
|
4142
4088
|
return this.a;
|
|
@@ -4146,118 +4092,137 @@ var DepthFirstTraverser = class {
|
|
|
4146
4092
|
// this entirely, including the visited-flag zero-fill (worth ~0.5% on the
|
|
4147
4093
|
// ~500-primitive manablade bundle, which shares attribute corner tables across
|
|
4148
4094
|
// primitives). Uint8Array (0/1) instead of Array(bool): these flags are read
|
|
4149
|
-
// and written on every corner of the hottest decode loop (
|
|
4095
|
+
// and written on every corner of the hottest decode loop (traverseAll).
|
|
4150
4096
|
// Decode-scoped scratch: released in bulk at the end of the decode.
|
|
4151
4097
|
onTraversalStart() {
|
|
4152
4098
|
const cornerTable = this.a;
|
|
4153
|
-
this.
|
|
4154
|
-
this.Ob = scratchInt32(this.
|
|
4099
|
+
this.Ba = scratchUint8Zeroed(cornerTable.numFaces());
|
|
4100
|
+
this.Ob = scratchInt32(this.M);
|
|
4155
4101
|
}
|
|
4156
4102
|
// Traverses every face, seeding a new traversal at the first corner of each
|
|
4157
|
-
// face not yet reached.
|
|
4158
|
-
//
|
|
4159
|
-
//
|
|
4160
|
-
//
|
|
4103
|
+
// face not yet reached. One function for the seeds and the walks they
|
|
4104
|
+
// start: a mesh cut into many pieces (small parts, or UV islands in an
|
|
4105
|
+
// attribute table) seeds a new walk every few faces, and a call per seed
|
|
4106
|
+
// would reload the whole traversal state each time.
|
|
4161
4107
|
traverseAll() {
|
|
4162
4108
|
const numFaces = this.a.numFaces();
|
|
4163
|
-
const isFaceVisited = this.
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
}
|
|
4169
|
-
return true;
|
|
4170
|
-
}
|
|
4171
|
-
traverseFromCorner(cornerId) {
|
|
4172
|
-
if (this._[cornerId / 3 | 0]) {
|
|
4173
|
-
return true;
|
|
4174
|
-
}
|
|
4175
|
-
const isFaceVisited = this._;
|
|
4176
|
-
const observer = this.Ca;
|
|
4177
|
-
const cornerToVertex = this.j;
|
|
4178
|
-
const oppositeCorners = this.q;
|
|
4179
|
-
const vertexOnBoundary = this.B;
|
|
4109
|
+
const isFaceVisited = this.Ba;
|
|
4110
|
+
const observer = this.Aa;
|
|
4111
|
+
const cornerToVertex = this.k;
|
|
4112
|
+
const oppositeCorners = this.w;
|
|
4113
|
+
const vertexOnBoundary = this.C;
|
|
4180
4114
|
const stack = this.Ob;
|
|
4181
|
-
let numVisitedFaces = this.
|
|
4115
|
+
let numVisitedFaces = this.Ca;
|
|
4182
4116
|
const encodingData = observer.p;
|
|
4183
|
-
const encodedToCornerMap = observer.
|
|
4184
|
-
const vertexToEncodedMap = observer.
|
|
4117
|
+
const encodedToCornerMap = observer.gb;
|
|
4118
|
+
const vertexToEncodedMap = observer.hb;
|
|
4119
|
+
const parents = this.Qb;
|
|
4185
4120
|
let numValues = encodingData.numValues;
|
|
4186
|
-
let
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
}
|
|
4199
|
-
if (vertexToEncodedMap[prevVert] < 0) {
|
|
4200
|
-
encodedToCornerMap[numValues] = prevCorner;
|
|
4201
|
-
vertexToEncodedMap[prevVert] = numValues++;
|
|
4202
|
-
}
|
|
4203
|
-
while (stackSize > 0) {
|
|
4204
|
-
cornerId = stack[stackSize - 1];
|
|
4205
|
-
let faceId = cornerId / 3 | 0;
|
|
4206
|
-
if (cornerId === kInvalidCornerIndex4 || isFaceVisited[faceId]) {
|
|
4207
|
-
stackSize--;
|
|
4208
|
-
continue;
|
|
4121
|
+
for (let f = 0; f < numFaces && numVisitedFaces < numFaces; ++f) {
|
|
4122
|
+
if (isFaceVisited[f] !== 0) continue;
|
|
4123
|
+
let cornerId = 3 * f;
|
|
4124
|
+
let stackSize = 0;
|
|
4125
|
+
stack[stackSize++] = cornerId;
|
|
4126
|
+
const nextCorner = cornerId + 1;
|
|
4127
|
+
const prevCorner = cornerId + 2;
|
|
4128
|
+
const nextVert = cornerToVertex[nextCorner];
|
|
4129
|
+
const prevVert = cornerToVertex[prevCorner];
|
|
4130
|
+
if (nextVert === kInvalidVertexIndex || prevVert === kInvalidVertexIndex) {
|
|
4131
|
+
encodingData.numValues = numValues;
|
|
4132
|
+
return false;
|
|
4209
4133
|
}
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4134
|
+
if (vertexToEncodedMap[nextVert] < 0) {
|
|
4135
|
+
encodedToCornerMap[numValues] = nextCorner;
|
|
4136
|
+
if (parents !== null)
|
|
4137
|
+
recordParents(parents, numValues, nextCorner, oppositeCorners, cornerToVertex, vertexToEncodedMap);
|
|
4138
|
+
vertexToEncodedMap[nextVert] = numValues++;
|
|
4139
|
+
}
|
|
4140
|
+
if (vertexToEncodedMap[prevVert] < 0) {
|
|
4141
|
+
encodedToCornerMap[numValues] = prevCorner;
|
|
4142
|
+
if (parents !== null)
|
|
4143
|
+
recordParents(parents, numValues, prevCorner, oppositeCorners, cornerToVertex, vertexToEncodedMap);
|
|
4144
|
+
vertexToEncodedMap[prevVert] = numValues++;
|
|
4145
|
+
}
|
|
4146
|
+
while (stackSize > 0) {
|
|
4147
|
+
cornerId = stack[stackSize - 1];
|
|
4148
|
+
let faceId = cornerId / 3 | 0;
|
|
4149
|
+
if (cornerId === kInvalidCornerIndex4 || isFaceVisited[faceId]) {
|
|
4150
|
+
stackSize--;
|
|
4151
|
+
continue;
|
|
4217
4152
|
}
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
faceId = cornerId / 3 | 0;
|
|
4226
|
-
continue;
|
|
4153
|
+
while (true) {
|
|
4154
|
+
isFaceVisited[faceId] = 1;
|
|
4155
|
+
numVisitedFaces++;
|
|
4156
|
+
const vertId = cornerToVertex[cornerId];
|
|
4157
|
+
if (vertId === kInvalidVertexIndex) {
|
|
4158
|
+
encodingData.numValues = numValues;
|
|
4159
|
+
return false;
|
|
4227
4160
|
}
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
} else {
|
|
4241
|
-
cornerId = leftCornerId;
|
|
4242
|
-
faceId = leftFaceId;
|
|
4161
|
+
const faceBase = faceId * 3;
|
|
4162
|
+
const nextCornerId = cornerId === faceBase + 2 ? faceBase : cornerId + 1;
|
|
4163
|
+
if (vertexToEncodedMap[vertId] < 0) {
|
|
4164
|
+
encodedToCornerMap[numValues] = cornerId;
|
|
4165
|
+
if (parents !== null)
|
|
4166
|
+
recordParents(parents, numValues, cornerId, oppositeCorners, cornerToVertex, vertexToEncodedMap);
|
|
4167
|
+
vertexToEncodedMap[vertId] = numValues++;
|
|
4168
|
+
if (vertexOnBoundary[vertId] === 0) {
|
|
4169
|
+
cornerId = oppositeCorners[nextCornerId];
|
|
4170
|
+
faceId = cornerId / 3 | 0;
|
|
4171
|
+
continue;
|
|
4172
|
+
}
|
|
4243
4173
|
}
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4174
|
+
const rightCornerId = oppositeCorners[nextCornerId];
|
|
4175
|
+
const prevCornerId = cornerId === faceBase ? faceBase + 2 : cornerId - 1;
|
|
4176
|
+
const leftCornerId = oppositeCorners[prevCornerId];
|
|
4177
|
+
const rightFaceId = rightCornerId === kInvalidCornerIndex4 ? kInvalidFaceIndex : rightCornerId / 3 | 0;
|
|
4178
|
+
const leftFaceId = leftCornerId === kInvalidCornerIndex4 ? kInvalidFaceIndex : leftCornerId / 3 | 0;
|
|
4179
|
+
const isRightVisited = rightFaceId === kInvalidFaceIndex || isFaceVisited[rightFaceId];
|
|
4180
|
+
const isLeftVisited = leftFaceId === kInvalidFaceIndex || isFaceVisited[leftFaceId];
|
|
4181
|
+
if (isRightVisited) {
|
|
4182
|
+
if (isLeftVisited) {
|
|
4183
|
+
stackSize--;
|
|
4184
|
+
break;
|
|
4185
|
+
} else {
|
|
4186
|
+
cornerId = leftCornerId;
|
|
4187
|
+
faceId = leftFaceId;
|
|
4188
|
+
}
|
|
4248
4189
|
} else {
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4190
|
+
if (isLeftVisited) {
|
|
4191
|
+
cornerId = rightCornerId;
|
|
4192
|
+
faceId = rightFaceId;
|
|
4193
|
+
} else {
|
|
4194
|
+
stack[stackSize - 1] = leftCornerId;
|
|
4195
|
+
stack[stackSize++] = rightCornerId;
|
|
4196
|
+
break;
|
|
4197
|
+
}
|
|
4252
4198
|
}
|
|
4253
4199
|
}
|
|
4254
4200
|
}
|
|
4255
4201
|
}
|
|
4256
|
-
this.
|
|
4202
|
+
this.Ca = numVisitedFaces;
|
|
4257
4203
|
encodingData.numValues = numValues;
|
|
4258
4204
|
return true;
|
|
4259
4205
|
}
|
|
4260
4206
|
};
|
|
4207
|
+
function recordParents(parents, value, corner, oppositeCorners, cornerToVertex, vertexToEncodedMap) {
|
|
4208
|
+
const o = value * 3;
|
|
4209
|
+
const oci = oppositeCorners[corner];
|
|
4210
|
+
if (oci < 0) {
|
|
4211
|
+
parents[o] = -1;
|
|
4212
|
+
return;
|
|
4213
|
+
}
|
|
4214
|
+
const rem = oci - (oci / 3 | 0) * 3;
|
|
4215
|
+
const a = vertexToEncodedMap[cornerToVertex[oci]];
|
|
4216
|
+
const b = vertexToEncodedMap[cornerToVertex[rem === 2 ? oci - 2 : oci + 1]];
|
|
4217
|
+
const c = vertexToEncodedMap[cornerToVertex[rem === 0 ? oci + 2 : oci - 1]];
|
|
4218
|
+
if ((a | b | c) < 0) {
|
|
4219
|
+
parents[o] = -1;
|
|
4220
|
+
} else {
|
|
4221
|
+
parents[o] = a;
|
|
4222
|
+
parents[o + 1] = b;
|
|
4223
|
+
parents[o + 2] = c;
|
|
4224
|
+
}
|
|
4225
|
+
}
|
|
4261
4226
|
|
|
4262
4227
|
// src/decoder/compression/mesh/traverser/MaxPredictionDegreeTraverser.ts
|
|
4263
4228
|
var kInvalidCornerIndex5 = -1;
|
|
@@ -4265,18 +4230,18 @@ var kInvalidFaceIndex2 = -1;
|
|
|
4265
4230
|
var kMaxPriority = 3;
|
|
4266
4231
|
var MaxPredictionDegreeTraverser = class {
|
|
4267
4232
|
a = null;
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4233
|
+
Aa = null;
|
|
4234
|
+
Ba = null;
|
|
4235
|
+
ib = null;
|
|
4236
|
+
Ca = 0;
|
|
4272
4237
|
// One stack (bucket) per priority level [0, kMaxPriority).
|
|
4273
4238
|
Ua = null;
|
|
4274
|
-
|
|
4239
|
+
aa = 0;
|
|
4275
4240
|
// Prediction degree accumulated per vertex during traversal.
|
|
4276
|
-
|
|
4241
|
+
jb = null;
|
|
4277
4242
|
// Flat connectivity arrays (see DepthFirstTraverser for why).
|
|
4278
|
-
|
|
4279
|
-
|
|
4243
|
+
k = null;
|
|
4244
|
+
w = null;
|
|
4280
4245
|
// Identifies the traversal order for the shared traversal cache
|
|
4281
4246
|
// (MESH_TRAVERSAL_PREDICTION_DEGREE). See MeshTraversalSequencer.
|
|
4282
4247
|
Pb = 1;
|
|
@@ -4284,32 +4249,32 @@ var MaxPredictionDegreeTraverser = class {
|
|
|
4284
4249
|
emitsPointIds = true;
|
|
4285
4250
|
init(cornerTable, observer) {
|
|
4286
4251
|
this.a = cornerTable;
|
|
4287
|
-
this.
|
|
4288
|
-
this.
|
|
4289
|
-
this.
|
|
4290
|
-
this.
|
|
4291
|
-
this.
|
|
4252
|
+
this.Aa = observer;
|
|
4253
|
+
this.Ba = new Uint8Array(cornerTable.numFaces());
|
|
4254
|
+
this.ib = new Uint8Array(cornerTable.numVertices());
|
|
4255
|
+
this.k = cornerTable.cornerToVertexArray();
|
|
4256
|
+
this.w = cornerTable.oppositeCornerArray();
|
|
4292
4257
|
this.Ua = [[], [], []];
|
|
4293
4258
|
}
|
|
4294
4259
|
cornerTable() {
|
|
4295
4260
|
return this.a;
|
|
4296
4261
|
}
|
|
4297
4262
|
// corner is always valid (>= 0) where these are used.
|
|
4298
|
-
|
|
4263
|
+
Rb(c) {
|
|
4299
4264
|
return c % 3 === 2 ? c - 2 : c + 1;
|
|
4300
4265
|
}
|
|
4301
|
-
|
|
4266
|
+
Sb(c) {
|
|
4302
4267
|
return c % 3 === 0 ? c + 2 : c - 1;
|
|
4303
4268
|
}
|
|
4304
4269
|
onTraversalStart() {
|
|
4305
|
-
this.
|
|
4270
|
+
this.jb = new Int32Array(this.a.numVertices());
|
|
4306
4271
|
}
|
|
4307
4272
|
// Same contract as DepthFirstTraverser.traverseAll. Seeds every face
|
|
4308
4273
|
// through traverseFromCorner (which re-checks the first face's vertices),
|
|
4309
4274
|
// exactly as the sequencer's loop always has.
|
|
4310
4275
|
traverseAll() {
|
|
4311
4276
|
const numFaces = this.a.numFaces();
|
|
4312
|
-
for (let f = 0; f < numFaces && this.
|
|
4277
|
+
for (let f = 0; f < numFaces && this.Ca < numFaces; ++f) {
|
|
4313
4278
|
if (!this.traverseFromCorner(3 * f)) {
|
|
4314
4279
|
return false;
|
|
4315
4280
|
}
|
|
@@ -4318,11 +4283,11 @@ var MaxPredictionDegreeTraverser = class {
|
|
|
4318
4283
|
}
|
|
4319
4284
|
// Returns the priority of traversing the edge leading to cornerId. Mutates
|
|
4320
4285
|
// the prediction degree of the destination vertex.
|
|
4321
|
-
|
|
4322
|
-
const vTip = this.
|
|
4286
|
+
Tb(cornerId) {
|
|
4287
|
+
const vTip = this.k[cornerId];
|
|
4323
4288
|
let priority = 0;
|
|
4324
|
-
if (!this.
|
|
4325
|
-
const degree = ++this.
|
|
4289
|
+
if (!this.ib[vTip]) {
|
|
4290
|
+
const degree = ++this.jb[vTip];
|
|
4326
4291
|
priority = degree > 1 ? 1 : 2;
|
|
4327
4292
|
}
|
|
4328
4293
|
if (priority >= kMaxPriority) {
|
|
@@ -4330,38 +4295,38 @@ var MaxPredictionDegreeTraverser = class {
|
|
|
4330
4295
|
}
|
|
4331
4296
|
return priority;
|
|
4332
4297
|
}
|
|
4333
|
-
|
|
4298
|
+
Ub(ci, priority) {
|
|
4334
4299
|
this.Ua[priority].push(ci);
|
|
4335
|
-
if (priority < this
|
|
4336
|
-
this
|
|
4300
|
+
if (priority < this.aa) {
|
|
4301
|
+
this.aa = priority;
|
|
4337
4302
|
}
|
|
4338
4303
|
}
|
|
4339
4304
|
// Retrieves the next available corner to traverse, processed by priority.
|
|
4340
4305
|
// Returns kInvalidCornerIndex when no corner is available.
|
|
4341
4306
|
rc() {
|
|
4342
|
-
for (let i = this
|
|
4307
|
+
for (let i = this.aa; i < kMaxPriority; ++i) {
|
|
4343
4308
|
const stack = this.Ua[i];
|
|
4344
4309
|
if (stack.length > 0) {
|
|
4345
4310
|
const ret = stack.pop();
|
|
4346
|
-
this
|
|
4311
|
+
this.aa = i;
|
|
4347
4312
|
return ret;
|
|
4348
4313
|
}
|
|
4349
4314
|
}
|
|
4350
4315
|
return kInvalidCornerIndex5;
|
|
4351
4316
|
}
|
|
4352
4317
|
traverseFromCorner(cornerId) {
|
|
4353
|
-
if (this.
|
|
4318
|
+
if (this.jb.length === 0) {
|
|
4354
4319
|
return true;
|
|
4355
4320
|
}
|
|
4356
|
-
const cornerToVertex = this.
|
|
4357
|
-
const oppositeCorners = this.
|
|
4358
|
-
const isFaceVisited = this.
|
|
4359
|
-
const isVertexVisited = this.
|
|
4360
|
-
const observer = this.
|
|
4321
|
+
const cornerToVertex = this.k;
|
|
4322
|
+
const oppositeCorners = this.w;
|
|
4323
|
+
const isFaceVisited = this.Ba;
|
|
4324
|
+
const isVertexVisited = this.ib;
|
|
4325
|
+
const observer = this.Aa;
|
|
4361
4326
|
this.Ua[0].push(cornerId);
|
|
4362
|
-
this
|
|
4363
|
-
const firstNext = this.
|
|
4364
|
-
const firstPrev = this.
|
|
4327
|
+
this.aa = 0;
|
|
4328
|
+
const firstNext = this.Rb(cornerId);
|
|
4329
|
+
const firstPrev = this.Sb(cornerId);
|
|
4365
4330
|
const nextVert = cornerToVertex[firstNext];
|
|
4366
4331
|
const prevVert = cornerToVertex[firstPrev];
|
|
4367
4332
|
if (!isVertexVisited[nextVert]) {
|
|
@@ -4385,34 +4350,34 @@ var MaxPredictionDegreeTraverser = class {
|
|
|
4385
4350
|
while (true) {
|
|
4386
4351
|
faceId = cornerId / 3 | 0;
|
|
4387
4352
|
isFaceVisited[faceId] = 1;
|
|
4388
|
-
this.
|
|
4353
|
+
this.Ca++;
|
|
4389
4354
|
const vertId = cornerToVertex[cornerId];
|
|
4390
4355
|
if (!isVertexVisited[vertId]) {
|
|
4391
4356
|
isVertexVisited[vertId] = 1;
|
|
4392
4357
|
observer.onNewVertexVisited(vertId, cornerId);
|
|
4393
4358
|
}
|
|
4394
|
-
const rightCornerId = oppositeCorners[this.
|
|
4395
|
-
const leftCornerId = oppositeCorners[this.
|
|
4359
|
+
const rightCornerId = oppositeCorners[this.Rb(cornerId)];
|
|
4360
|
+
const leftCornerId = oppositeCorners[this.Sb(cornerId)];
|
|
4396
4361
|
const rightFaceId = rightCornerId === kInvalidCornerIndex5 ? kInvalidFaceIndex2 : rightCornerId / 3 | 0;
|
|
4397
4362
|
const leftFaceId = leftCornerId === kInvalidCornerIndex5 ? kInvalidFaceIndex2 : leftCornerId / 3 | 0;
|
|
4398
4363
|
const isRightFaceVisited = rightFaceId === kInvalidFaceIndex2 || isFaceVisited[rightFaceId] !== 0;
|
|
4399
4364
|
const isLeftFaceVisited = leftFaceId === kInvalidFaceIndex2 || isFaceVisited[leftFaceId] !== 0;
|
|
4400
4365
|
if (!isLeftFaceVisited) {
|
|
4401
|
-
const priority = this.
|
|
4402
|
-
if (isRightFaceVisited && priority <= this
|
|
4366
|
+
const priority = this.Tb(leftCornerId);
|
|
4367
|
+
if (isRightFaceVisited && priority <= this.aa) {
|
|
4403
4368
|
cornerId = leftCornerId;
|
|
4404
4369
|
continue;
|
|
4405
4370
|
} else {
|
|
4406
|
-
this.
|
|
4371
|
+
this.Ub(leftCornerId, priority);
|
|
4407
4372
|
}
|
|
4408
4373
|
}
|
|
4409
4374
|
if (!isRightFaceVisited) {
|
|
4410
|
-
const priority = this.
|
|
4411
|
-
if (priority <= this
|
|
4375
|
+
const priority = this.Tb(rightCornerId);
|
|
4376
|
+
if (priority <= this.aa) {
|
|
4412
4377
|
cornerId = rightCornerId;
|
|
4413
4378
|
continue;
|
|
4414
4379
|
} else {
|
|
4415
|
-
this.
|
|
4380
|
+
this.Ub(rightCornerId, priority);
|
|
4416
4381
|
}
|
|
4417
4382
|
}
|
|
4418
4383
|
break;
|
|
@@ -4425,65 +4390,77 @@ var MaxPredictionDegreeTraverser = class {
|
|
|
4425
4390
|
// src/decoder/compression/mesh/traverser/MeshAttributeIndicesEncodingObserver.ts
|
|
4426
4391
|
var MeshAttributeIndicesEncodingObserver = class {
|
|
4427
4392
|
p;
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4393
|
+
$;
|
|
4394
|
+
hb;
|
|
4395
|
+
gb;
|
|
4396
|
+
Vb;
|
|
4432
4397
|
constructor(mesh, sequencer, encodingData) {
|
|
4433
4398
|
this.p = encodingData;
|
|
4434
|
-
this
|
|
4435
|
-
this.
|
|
4436
|
-
this.
|
|
4437
|
-
this.
|
|
4399
|
+
this.$ = sequencer;
|
|
4400
|
+
this.hb = encodingData.vertexToEncodedAttributeValueIndexMap;
|
|
4401
|
+
this.gb = encodingData.encodedAttributeValueIndexToCornerMap;
|
|
4402
|
+
this.Vb = mesh.faces_;
|
|
4438
4403
|
}
|
|
4439
4404
|
onNewVertexVisited(vertex, corner) {
|
|
4440
|
-
const pointId = this.
|
|
4441
|
-
this
|
|
4405
|
+
const pointId = this.Vb[corner];
|
|
4406
|
+
this.$.addPointId(pointId);
|
|
4442
4407
|
const numValues = this.p.numValues;
|
|
4443
|
-
this.
|
|
4444
|
-
this.
|
|
4408
|
+
this.gb[numValues] = corner;
|
|
4409
|
+
this.hb[vertex] = numValues;
|
|
4445
4410
|
this.p.numValues++;
|
|
4446
4411
|
}
|
|
4447
4412
|
};
|
|
4448
4413
|
|
|
4449
4414
|
// src/decoder/compression/mesh/traverser/MeshTraversalSequencer.ts
|
|
4450
4415
|
var MeshTraversalSequencer = class {
|
|
4451
|
-
|
|
4416
|
+
H;
|
|
4452
4417
|
p;
|
|
4453
|
-
|
|
4454
|
-
x =
|
|
4455
|
-
|
|
4418
|
+
ja = null;
|
|
4419
|
+
x = EMPTY_INT32;
|
|
4420
|
+
Da = 0;
|
|
4456
4421
|
// Per-decode cache, keyed by corner table, shared across the attribute
|
|
4457
4422
|
// decoders of one mesh (see MeshEdgebreakerDecoderImpl).
|
|
4458
|
-
|
|
4423
|
+
kb;
|
|
4459
4424
|
// The cache entry the last generateSequence resolved to (hit or store);
|
|
4460
4425
|
// carries the shared indicesMap.
|
|
4461
|
-
|
|
4426
|
+
lb = null;
|
|
4462
4427
|
// One representative corner per point id, when the connectivity decoder
|
|
4463
4428
|
// recorded them (see MeshEdgebreakerDecoderImpl._assignAttributeVerticesAndPoints).
|
|
4464
|
-
|
|
4465
|
-
|
|
4466
|
-
|
|
4429
|
+
ba;
|
|
4430
|
+
// The corner table whose vertex ids are the point ids, if any.
|
|
4431
|
+
Ea;
|
|
4432
|
+
constructor(mesh, encodingData, traversalCache, pointCorner, pointVertexTable) {
|
|
4433
|
+
this.H = mesh;
|
|
4467
4434
|
this.p = encodingData;
|
|
4468
|
-
this.
|
|
4469
|
-
this.
|
|
4435
|
+
this.kb = traversalCache;
|
|
4436
|
+
this.ba = pointCorner;
|
|
4437
|
+
this.Ea = pointVertexTable;
|
|
4470
4438
|
}
|
|
4471
4439
|
setTraverser(traverser) {
|
|
4472
|
-
this.
|
|
4473
|
-
}
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4440
|
+
this.ja = traverser;
|
|
4441
|
+
}
|
|
4442
|
+
// With parallelogramParents set, a depth-first traversal also records the
|
|
4443
|
+
// parallelogram parents of its values (see
|
|
4444
|
+
// MeshPredictionSchemeData.parallelogramParents), stored with the result.
|
|
4445
|
+
generateSequence(parallelogramParents) {
|
|
4446
|
+
const cornerTable = this.ja.cornerTable();
|
|
4447
|
+
const methodId = this.ja.Pb;
|
|
4477
4448
|
const cacheKey = cornerTable.cornerToVertexArray();
|
|
4478
4449
|
const encodingData = this.p;
|
|
4479
|
-
let byMethod = this.
|
|
4450
|
+
let byMethod = this.kb.get(cacheKey);
|
|
4480
4451
|
const cached = byMethod && byMethod.get(methodId);
|
|
4481
4452
|
if (cached !== void 0) {
|
|
4482
4453
|
this.x = cached.pointIds;
|
|
4483
4454
|
encodingData.adoptTraversalResult(cached);
|
|
4484
|
-
this.
|
|
4455
|
+
this.lb = cached;
|
|
4485
4456
|
return true;
|
|
4486
4457
|
}
|
|
4458
|
+
const traverser = this.ja;
|
|
4459
|
+
let parents = null;
|
|
4460
|
+
if (parallelogramParents && traverser instanceof DepthFirstTraverser) {
|
|
4461
|
+
parents = scratchInt32(encodingData.vertexToEncodedAttributeValueIndexMap.length * 3);
|
|
4462
|
+
traverser.Qb = parents;
|
|
4463
|
+
}
|
|
4487
4464
|
if (!this.sc()) {
|
|
4488
4465
|
return false;
|
|
4489
4466
|
}
|
|
@@ -4496,7 +4473,7 @@ var MeshTraversalSequencer = class {
|
|
|
4496
4473
|
}
|
|
4497
4474
|
if (byMethod === void 0) {
|
|
4498
4475
|
byMethod = /* @__PURE__ */ new Map();
|
|
4499
|
-
this.
|
|
4476
|
+
this.kb.set(cacheKey, byMethod);
|
|
4500
4477
|
}
|
|
4501
4478
|
const entry = {
|
|
4502
4479
|
pointIds: this.x,
|
|
@@ -4504,34 +4481,42 @@ var MeshTraversalSequencer = class {
|
|
|
4504
4481
|
cornerMap: encodingData.encodedAttributeValueIndexToCornerMap,
|
|
4505
4482
|
numValues,
|
|
4506
4483
|
indicesMap: null,
|
|
4507
|
-
parents
|
|
4484
|
+
parents
|
|
4508
4485
|
};
|
|
4509
4486
|
byMethod.set(methodId, entry);
|
|
4510
4487
|
encodingData.cacheEntry = entry;
|
|
4511
|
-
this.
|
|
4488
|
+
this.lb = entry;
|
|
4512
4489
|
return true;
|
|
4513
4490
|
}
|
|
4514
4491
|
getOutputPointIds() {
|
|
4515
4492
|
return this.x;
|
|
4516
4493
|
}
|
|
4517
4494
|
addPointId(pointId) {
|
|
4518
|
-
this.x[this.
|
|
4495
|
+
this.x[this.Da++] = pointId;
|
|
4519
4496
|
}
|
|
4520
4497
|
updatePointToAttributeIndexMapping(attribute) {
|
|
4521
|
-
const entry = this.
|
|
4498
|
+
const entry = this.lb;
|
|
4522
4499
|
if (entry !== null && entry.indicesMap !== null) {
|
|
4523
4500
|
attribute.setExplicitMappingShared(entry.indicesMap);
|
|
4524
4501
|
return true;
|
|
4525
4502
|
}
|
|
4526
|
-
const cornerTable = this.
|
|
4527
|
-
const numFaces = this.
|
|
4528
|
-
const numPoints = this.
|
|
4503
|
+
const cornerTable = this.ja.cornerTable();
|
|
4504
|
+
const numFaces = this.H.numFaces();
|
|
4505
|
+
const numPoints = this.H.numPoints();
|
|
4529
4506
|
attribute.setExplicitMappingUnfilled(numPoints);
|
|
4530
4507
|
const cornerToVertex = cornerTable.cornerToVertexArray();
|
|
4531
4508
|
const vertexToAttEntry = this.p.vertexToEncodedAttributeValueIndexMap;
|
|
4532
4509
|
const indicesMap = attribute.indicesMap;
|
|
4533
|
-
const pointCorner = this.
|
|
4534
|
-
if (
|
|
4510
|
+
const pointCorner = this.ba;
|
|
4511
|
+
if (cornerTable === this.Ea) {
|
|
4512
|
+
for (let p = 0; p < numPoints; ++p) {
|
|
4513
|
+
const attEntryId = vertexToAttEntry[p];
|
|
4514
|
+
if (attEntryId < 0 || attEntryId >= numPoints) {
|
|
4515
|
+
return false;
|
|
4516
|
+
}
|
|
4517
|
+
indicesMap[p] = attEntryId;
|
|
4518
|
+
}
|
|
4519
|
+
} else if (pointCorner !== null) {
|
|
4535
4520
|
for (let p = 0; p < numPoints; ++p) {
|
|
4536
4521
|
const vertId = cornerToVertex[pointCorner[p]];
|
|
4537
4522
|
if (vertId < 0) {
|
|
@@ -4545,7 +4530,7 @@ var MeshTraversalSequencer = class {
|
|
|
4545
4530
|
}
|
|
4546
4531
|
} else {
|
|
4547
4532
|
const numCorners = numFaces * 3;
|
|
4548
|
-
const faces = this.
|
|
4533
|
+
const faces = this.H.faces_;
|
|
4549
4534
|
for (let ci = 0; ci < numCorners; ++ci) {
|
|
4550
4535
|
const vertId = cornerToVertex[ci];
|
|
4551
4536
|
if (vertId < 0) {
|
|
@@ -4565,9 +4550,9 @@ var MeshTraversalSequencer = class {
|
|
|
4565
4550
|
return true;
|
|
4566
4551
|
}
|
|
4567
4552
|
sc() {
|
|
4568
|
-
this.
|
|
4569
|
-
this.x = scratchInt32(this.
|
|
4570
|
-
const traverser = this.
|
|
4553
|
+
this.Da = 0;
|
|
4554
|
+
this.x = scratchInt32(this.H.numPoints());
|
|
4555
|
+
const traverser = this.ja;
|
|
4571
4556
|
traverser.onTraversalStart();
|
|
4572
4557
|
if (!traverser.traverseAll()) {
|
|
4573
4558
|
return false;
|
|
@@ -4575,15 +4560,15 @@ var MeshTraversalSequencer = class {
|
|
|
4575
4560
|
if (!traverser.emitsPointIds) {
|
|
4576
4561
|
const numValues = this.p.numValues;
|
|
4577
4562
|
const cornerMap = this.p.encodedAttributeValueIndexToCornerMap;
|
|
4578
|
-
const faces = this.
|
|
4563
|
+
const faces = this.H.faces_;
|
|
4579
4564
|
const outPointIds = this.x;
|
|
4580
4565
|
for (let i = 0; i < numValues; ++i) {
|
|
4581
4566
|
outPointIds[i] = faces[cornerMap[i]];
|
|
4582
4567
|
}
|
|
4583
|
-
this.
|
|
4568
|
+
this.Da = numValues;
|
|
4584
4569
|
}
|
|
4585
|
-
if (this.
|
|
4586
|
-
this.x = this.x.subarray(0, this.
|
|
4570
|
+
if (this.Da < this.x.length) {
|
|
4571
|
+
this.x = this.x.subarray(0, this.Da);
|
|
4587
4572
|
}
|
|
4588
4573
|
return true;
|
|
4589
4574
|
}
|
|
@@ -4592,38 +4577,40 @@ var MeshTraversalSequencer = class {
|
|
|
4592
4577
|
// src/decoder/compression/mesh/MeshEdgebreakerDecoderImpl.ts
|
|
4593
4578
|
var kInvalidCornerIndex6 = -1;
|
|
4594
4579
|
var MeshEdgebreakerDecoderImpl = class {
|
|
4595
|
-
|
|
4580
|
+
o;
|
|
4596
4581
|
a = null;
|
|
4597
4582
|
R = [];
|
|
4598
|
-
ka =
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4583
|
+
ka = EMPTY_UINT8;
|
|
4584
|
+
ca = 0;
|
|
4585
|
+
mb = new MeshAttributeIndicesEncodingData();
|
|
4586
|
+
Wb = -1;
|
|
4602
4587
|
// Cache of vertex-traversal results keyed by corner table, so attributes
|
|
4603
4588
|
// sharing connectivity traverse once.
|
|
4604
4589
|
tc = /* @__PURE__ */ new Map();
|
|
4605
|
-
|
|
4606
|
-
|
|
4590
|
+
j = [];
|
|
4591
|
+
N;
|
|
4607
4592
|
// One corner per point id (decode-scoped scratch), filled by
|
|
4608
|
-
// _assignAttributeVerticesAndPoints; null
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4593
|
+
// _assignAttributeVerticesAndPoints; null for a mesh without attribute data
|
|
4594
|
+
// (see _assignPointsToVertices).
|
|
4595
|
+
ba = null;
|
|
4596
|
+
// The corner table whose vertex ids are the point ids, if any (see
|
|
4597
|
+
// MeshTraversalSequencer.updatePointToAttributeIndexMapping).
|
|
4598
|
+
Ea = null;
|
|
4612
4599
|
constructor(decoder, TraversalDecoderClass) {
|
|
4613
|
-
this.
|
|
4614
|
-
this.
|
|
4600
|
+
this.o = decoder;
|
|
4601
|
+
this.N = new TraversalDecoderClass();
|
|
4615
4602
|
}
|
|
4616
4603
|
getCornerTable() {
|
|
4617
4604
|
return this.a;
|
|
4618
4605
|
}
|
|
4619
4606
|
// The attribute data set whose attributes decoder owns attId, if any.
|
|
4620
4607
|
Xb(attId) {
|
|
4621
|
-
for (let i = 0; i < this.
|
|
4622
|
-
const ad = this.
|
|
4623
|
-
if (ad.decoderId < 0 || ad.decoderId >= this.
|
|
4608
|
+
for (let i = 0; i < this.j.length; ++i) {
|
|
4609
|
+
const ad = this.j[i];
|
|
4610
|
+
if (ad.decoderId < 0 || ad.decoderId >= this.o.numAttributesDecoders()) {
|
|
4624
4611
|
continue;
|
|
4625
4612
|
}
|
|
4626
|
-
const dec = this.
|
|
4613
|
+
const dec = this.o.attributesDecoder(ad.decoderId);
|
|
4627
4614
|
for (let j = 0; j < dec.getNumAttributes(); ++j) {
|
|
4628
4615
|
if (dec.getAttributeId(j) === attId) {
|
|
4629
4616
|
return ad;
|
|
@@ -4638,28 +4625,28 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
4638
4625
|
}
|
|
4639
4626
|
getAttributeEncodingData(attId) {
|
|
4640
4627
|
const ad = this.Xb(attId);
|
|
4641
|
-
return ad !== null ? ad.encodingData : this.
|
|
4628
|
+
return ad !== null ? ad.encodingData : this.mb;
|
|
4642
4629
|
}
|
|
4643
4630
|
createAttributesDecoder(attDecoderId) {
|
|
4644
|
-
const buffer = this.
|
|
4631
|
+
const buffer = this.o.buffer();
|
|
4645
4632
|
let attDataId = buffer.decodeUint8();
|
|
4646
4633
|
if (attDataId !== void 0) attDataId = attDataId << 24 >> 24;
|
|
4647
4634
|
if (attDataId === void 0) return false;
|
|
4648
4635
|
const decoderType = buffer.decodeUint8();
|
|
4649
4636
|
if (decoderType === void 0) return false;
|
|
4650
4637
|
if (attDataId >= 0) {
|
|
4651
|
-
if (attDataId >= this.
|
|
4638
|
+
if (attDataId >= this.j.length) {
|
|
4652
4639
|
return false;
|
|
4653
4640
|
}
|
|
4654
|
-
if (this.
|
|
4641
|
+
if (this.j[attDataId].decoderId >= 0) {
|
|
4655
4642
|
return false;
|
|
4656
4643
|
}
|
|
4657
|
-
this.
|
|
4644
|
+
this.j[attDataId].decoderId = attDecoderId;
|
|
4658
4645
|
} else {
|
|
4659
|
-
if (this.
|
|
4646
|
+
if (this.Wb >= 0) {
|
|
4660
4647
|
return false;
|
|
4661
4648
|
}
|
|
4662
|
-
this.
|
|
4649
|
+
this.Wb = attDecoderId;
|
|
4663
4650
|
}
|
|
4664
4651
|
const traversalMethod = buffer.decodeUint8();
|
|
4665
4652
|
if (traversalMethod === void 0 || traversalMethod >= 2 /* NUM_TRAVERSAL_METHODS */) {
|
|
@@ -4669,44 +4656,50 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
4669
4656
|
let cornerTable;
|
|
4670
4657
|
if (decoderType === 0 /* MESH_VERTEX_ATTRIBUTE */) {
|
|
4671
4658
|
if (attDataId < 0) {
|
|
4672
|
-
encodingData = this.
|
|
4659
|
+
encodingData = this.mb;
|
|
4673
4660
|
} else {
|
|
4674
|
-
encodingData = this.
|
|
4675
|
-
this.
|
|
4661
|
+
encodingData = this.j[attDataId].encodingData;
|
|
4662
|
+
this.j[attDataId].isConnectivityUsed = false;
|
|
4676
4663
|
}
|
|
4677
4664
|
cornerTable = this.a;
|
|
4678
4665
|
} else {
|
|
4679
4666
|
if (traversalMethod !== 0 /* MESH_TRAVERSAL_DEPTH_FIRST */ || attDataId < 0) {
|
|
4680
4667
|
return false;
|
|
4681
4668
|
}
|
|
4682
|
-
const ad = this.
|
|
4669
|
+
const ad = this.j[attDataId];
|
|
4683
4670
|
if (ad.noInteriorSeams) this.uc(ad);
|
|
4684
4671
|
encodingData = ad.encodingData;
|
|
4685
4672
|
cornerTable = ad.connectivityData;
|
|
4686
4673
|
}
|
|
4687
|
-
const mesh = this.
|
|
4688
|
-
const sequencer = new MeshTraversalSequencer(
|
|
4674
|
+
const mesh = this.o.mesh();
|
|
4675
|
+
const sequencer = new MeshTraversalSequencer(
|
|
4676
|
+
mesh,
|
|
4677
|
+
encodingData,
|
|
4678
|
+
this.tc,
|
|
4679
|
+
this.ba,
|
|
4680
|
+
this.Ea
|
|
4681
|
+
);
|
|
4689
4682
|
const observer = new MeshAttributeIndicesEncodingObserver(mesh, sequencer, encodingData);
|
|
4690
4683
|
const traverser = traversalMethod === 1 /* MESH_TRAVERSAL_PREDICTION_DEGREE */ ? new MaxPredictionDegreeTraverser() : new DepthFirstTraverser();
|
|
4691
4684
|
traverser.init(cornerTable, observer);
|
|
4692
4685
|
sequencer.setTraverser(traverser);
|
|
4693
|
-
return this.
|
|
4686
|
+
return this.o.setAttributesDecoder(attDecoderId, new SequentialAttributeDecodersController(sequencer));
|
|
4694
4687
|
}
|
|
4695
4688
|
decodeConnectivity() {
|
|
4696
|
-
const buffer = this.
|
|
4689
|
+
const buffer = this.o.buffer();
|
|
4697
4690
|
const numEncodedVertices = decodeVarint(buffer);
|
|
4698
4691
|
if (numEncodedVertices === void 0) return false;
|
|
4699
|
-
this.
|
|
4692
|
+
this.ca = numEncodedVertices;
|
|
4700
4693
|
const numFaces = decodeVarint(buffer);
|
|
4701
4694
|
if (numFaces === void 0) return false;
|
|
4702
4695
|
if (numFaces > 2147483647 / 3) {
|
|
4703
4696
|
return false;
|
|
4704
4697
|
}
|
|
4705
|
-
if (this.
|
|
4698
|
+
if (this.ca > numFaces * 3) {
|
|
4706
4699
|
return false;
|
|
4707
4700
|
}
|
|
4708
4701
|
const minNumFaceEdges = Math.floor(3 * numFaces / 2);
|
|
4709
|
-
const maxNumVertexEdges = this.
|
|
4702
|
+
const maxNumVertexEdges = this.ca * (this.ca - 1) / 2;
|
|
4710
4703
|
if (maxNumVertexEdges < minNumFaceEdges) {
|
|
4711
4704
|
return false;
|
|
4712
4705
|
}
|
|
@@ -4731,43 +4724,42 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
4731
4724
|
const ad = new AttributeData();
|
|
4732
4725
|
ad.attributeSeamCorners = scratchInt32(numFaces * 3);
|
|
4733
4726
|
ad.numSeamCorners = 0;
|
|
4734
|
-
this.
|
|
4727
|
+
this.j.push(ad);
|
|
4735
4728
|
}
|
|
4736
|
-
this.a.reset(numFaces, this.
|
|
4737
|
-
this.ka = scratchUint8Filled(this.
|
|
4729
|
+
this.a.reset(numFaces, this.ca + numEncodedSplitSymbols);
|
|
4730
|
+
this.ka = scratchUint8Filled(this.ca + numEncodedSplitSymbols, 1);
|
|
4738
4731
|
if (!this.vc(buffer)) {
|
|
4739
4732
|
return false;
|
|
4740
4733
|
}
|
|
4741
|
-
this.
|
|
4742
|
-
this.
|
|
4743
|
-
this.
|
|
4734
|
+
this.N.init(this);
|
|
4735
|
+
this.N.setNumEncodedVertices(this.ca + numEncodedSplitSymbols);
|
|
4736
|
+
this.N.setNumAttributeData(numAttributeData);
|
|
4744
4737
|
const traversalEndBuffer = new DecoderBuffer();
|
|
4745
|
-
if (!this.
|
|
4738
|
+
if (!this.N.start(traversalEndBuffer)) {
|
|
4746
4739
|
return false;
|
|
4747
4740
|
}
|
|
4748
4741
|
const numConnectivityVerts = this.wc(numEncodedSymbols);
|
|
4749
4742
|
if (numConnectivityVerts === -1) {
|
|
4750
4743
|
return false;
|
|
4751
4744
|
}
|
|
4752
|
-
buffer.
|
|
4745
|
+
buffer.initFrom(traversalEndBuffer);
|
|
4753
4746
|
this.a.finishBoundaries();
|
|
4754
|
-
if (this.
|
|
4747
|
+
if (this.j.length > 0) {
|
|
4755
4748
|
this.xc();
|
|
4756
4749
|
}
|
|
4757
|
-
this.
|
|
4758
|
-
const numBoundaryCorners = this.Wb;
|
|
4750
|
+
this.N.done();
|
|
4759
4751
|
const distinctTables = [];
|
|
4760
4752
|
const seamEdgeCounts = [];
|
|
4761
4753
|
const adoptions = [];
|
|
4762
4754
|
let previousConnectivityData = null;
|
|
4763
4755
|
let previousSeamCorners = null;
|
|
4764
4756
|
let previousSeamCount = 0;
|
|
4765
|
-
for (let i = 0; i < this.
|
|
4766
|
-
const connectivityData = this.
|
|
4767
|
-
const seamCorners = this.
|
|
4768
|
-
const seamCount = this.
|
|
4769
|
-
if (seamCount ===
|
|
4770
|
-
this.
|
|
4757
|
+
for (let i = 0; i < this.j.length; ++i) {
|
|
4758
|
+
const connectivityData = this.j[i].connectivityData;
|
|
4759
|
+
const seamCorners = this.j[i].attributeSeamCorners;
|
|
4760
|
+
const seamCount = this.j[i].numSeamCorners;
|
|
4761
|
+
if (seamCount === 0) {
|
|
4762
|
+
this.j[i].noInteriorSeams = true;
|
|
4771
4763
|
continue;
|
|
4772
4764
|
}
|
|
4773
4765
|
let sameAsPrevious = previousConnectivityData !== null && seamCount === previousSeamCount;
|
|
@@ -4794,7 +4786,7 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
4794
4786
|
previousSeamCorners = seamCorners;
|
|
4795
4787
|
previousSeamCount = seamCount;
|
|
4796
4788
|
}
|
|
4797
|
-
if (this.
|
|
4789
|
+
if (this.j.length === 0) {
|
|
4798
4790
|
this.yc(numConnectivityVerts);
|
|
4799
4791
|
} else if (!this.zc(distinctTables, seamEdgeCounts)) {
|
|
4800
4792
|
return false;
|
|
@@ -4802,13 +4794,13 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
4802
4794
|
for (let i = 0; i < adoptions.length; i += 2) {
|
|
4803
4795
|
adoptions[i].adoptFrom(adoptions[i + 1]);
|
|
4804
4796
|
}
|
|
4805
|
-
this.
|
|
4806
|
-
for (let i = 0; i < this.
|
|
4807
|
-
let attConnectivityVerts = this.
|
|
4797
|
+
this.mb.init(this.a.numVertices());
|
|
4798
|
+
for (let i = 0; i < this.j.length; ++i) {
|
|
4799
|
+
let attConnectivityVerts = this.j[i].connectivityData.numVertices();
|
|
4808
4800
|
if (attConnectivityVerts < this.a.numVertices()) {
|
|
4809
4801
|
attConnectivityVerts = this.a.numVertices();
|
|
4810
4802
|
}
|
|
4811
|
-
this.
|
|
4803
|
+
this.j[i].encodingData.init(attConnectivityVerts);
|
|
4812
4804
|
}
|
|
4813
4805
|
return true;
|
|
4814
4806
|
}
|
|
@@ -4835,15 +4827,15 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
4835
4827
|
const topologySplitActiveCorners = /* @__PURE__ */ new Map();
|
|
4836
4828
|
const splitResult = { faceEdge: 0, encoderSplitSymbolId: 0 };
|
|
4837
4829
|
const invalidVertices = [];
|
|
4838
|
-
const removeInvalidVertices = this.
|
|
4830
|
+
const removeInvalidVertices = this.j.length === 0;
|
|
4839
4831
|
let maxNumVertices = this.ka.length;
|
|
4840
4832
|
let numFacesDecoded = 0;
|
|
4841
|
-
const cornerToVertex = this.a.
|
|
4842
|
-
const oppositeCorners = this.a.
|
|
4833
|
+
const cornerToVertex = this.a.k;
|
|
4834
|
+
const oppositeCorners = this.a.w;
|
|
4843
4835
|
const vc = this.a;
|
|
4844
|
-
let vertexCorners = vc.
|
|
4836
|
+
let vertexCorners = vc.u;
|
|
4845
4837
|
const isVertHole = this.ka;
|
|
4846
|
-
const traversalDecoder = this.
|
|
4838
|
+
const traversalDecoder = this.N;
|
|
4847
4839
|
for (let symbolId = 0; symbolId < numSymbols; ++symbolId) {
|
|
4848
4840
|
const faceIndex = numFacesDecoded++;
|
|
4849
4841
|
let checkTopologySplit = false;
|
|
@@ -4895,13 +4887,13 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
4895
4887
|
oppositeCorners[oppCorner] = cornerA;
|
|
4896
4888
|
oppositeCorners[cornerA] = oppCorner;
|
|
4897
4889
|
let newVertIndex;
|
|
4898
|
-
if (vc.
|
|
4899
|
-
newVertIndex = vc.
|
|
4890
|
+
if (vc.l < vertexCorners.length) {
|
|
4891
|
+
newVertIndex = vc.l++;
|
|
4900
4892
|
} else {
|
|
4901
4893
|
newVertIndex = vc.addNewVertex();
|
|
4902
|
-
vertexCorners = vc.
|
|
4894
|
+
vertexCorners = vc.u;
|
|
4903
4895
|
}
|
|
4904
|
-
if (vc.
|
|
4896
|
+
if (vc.l > maxNumVertices) return -1;
|
|
4905
4897
|
cornerToVertex[oppCorner] = newVertIndex;
|
|
4906
4898
|
vertexCorners[newVertIndex] = oppCorner;
|
|
4907
4899
|
const pA = cornerA % 3 === 0 ? cornerA + 2 : cornerA - 1;
|
|
@@ -4962,16 +4954,16 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
4962
4954
|
} else if (symbol === TOPOLOGY_E) {
|
|
4963
4955
|
const corner = 3 * faceIndex;
|
|
4964
4956
|
let firstVertIndex;
|
|
4965
|
-
if (vc.
|
|
4966
|
-
firstVertIndex = vc.
|
|
4967
|
-
vc.
|
|
4957
|
+
if (vc.l + 3 <= vertexCorners.length) {
|
|
4958
|
+
firstVertIndex = vc.l;
|
|
4959
|
+
vc.l += 3;
|
|
4968
4960
|
} else {
|
|
4969
4961
|
firstVertIndex = vc.addNewVertex();
|
|
4970
4962
|
vc.addNewVertex();
|
|
4971
4963
|
vc.addNewVertex();
|
|
4972
|
-
vertexCorners = vc.
|
|
4964
|
+
vertexCorners = vc.u;
|
|
4973
4965
|
}
|
|
4974
|
-
if (vc.
|
|
4966
|
+
if (vc.l > maxNumVertices) return -1;
|
|
4975
4967
|
cornerToVertex[corner] = firstVertIndex;
|
|
4976
4968
|
cornerToVertex[corner + 1] = firstVertIndex + 1;
|
|
4977
4969
|
cornerToVertex[corner + 2] = firstVertIndex + 2;
|
|
@@ -5000,7 +4992,7 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5000
4992
|
}
|
|
5001
4993
|
}
|
|
5002
4994
|
}
|
|
5003
|
-
if (vc.
|
|
4995
|
+
if (vc.l > maxNumVertices) {
|
|
5004
4996
|
return -1;
|
|
5005
4997
|
}
|
|
5006
4998
|
numFacesDecoded = this.Bc(activeCornerStack, activeCornerStackSize, numFacesDecoded);
|
|
@@ -5016,11 +5008,11 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5016
5008
|
// Returns the updated decoded-face count, or -1 on malformed input.
|
|
5017
5009
|
Bc(activeCornerStack, activeCornerStackSize, numFacesDecoded) {
|
|
5018
5010
|
const ct = this.a;
|
|
5019
|
-
const oppositeCorners = ct.
|
|
5020
|
-
const cornerToVertex = ct.
|
|
5021
|
-
const vertexCorners = ct.
|
|
5011
|
+
const oppositeCorners = ct.w;
|
|
5012
|
+
const cornerToVertex = ct.k;
|
|
5013
|
+
const vertexCorners = ct.u;
|
|
5022
5014
|
const isVertHole = this.ka;
|
|
5023
|
-
const traversalDecoder = this.
|
|
5015
|
+
const traversalDecoder = this.N;
|
|
5024
5016
|
const numCorners = ct.numCorners();
|
|
5025
5017
|
const numFaces = ct.numFaces();
|
|
5026
5018
|
const next = (c) => c < 0 ? -1 : c % 3 === 2 ? c - 2 : c + 1;
|
|
@@ -5070,8 +5062,8 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5070
5062
|
// forward iteration order matters). Returns the final vertex count, or -1.
|
|
5071
5063
|
Cc(invalidVertices) {
|
|
5072
5064
|
const ct = this.a;
|
|
5073
|
-
const cornerToVertex = ct.
|
|
5074
|
-
const vertexCorners = ct.
|
|
5065
|
+
const cornerToVertex = ct.k;
|
|
5066
|
+
const vertexCorners = ct.u;
|
|
5075
5067
|
const isVertHole = this.ka;
|
|
5076
5068
|
const leftMostCorner = (v) => v < 0 || v >= vertexCorners.length ? -1 : vertexCorners[v];
|
|
5077
5069
|
let numVertices = ct.numVertices();
|
|
@@ -5153,32 +5145,24 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5153
5145
|
//
|
|
5154
5146
|
// The face comparison the C++ makes -- floor(oppCorner/3) >= floor(cc/3) for
|
|
5155
5147
|
// the face's base corner -- is just `oppCorner >= faceBaseCorner`, since the
|
|
5156
|
-
// base corner is a multiple of 3. That removes the per-corner division
|
|
5157
|
-
// invalid
|
|
5148
|
+
// base corner is a multiple of 3. That removes the per-corner division, and
|
|
5149
|
+
// an invalid (-1) opposite fails it too.
|
|
5158
5150
|
xc() {
|
|
5159
5151
|
const oppositeCorners = this.a.oppositeCornerArray();
|
|
5160
|
-
const attributeData = this.
|
|
5152
|
+
const attributeData = this.j;
|
|
5161
5153
|
const numAttrData = attributeData.length;
|
|
5162
|
-
const connectivityDecoders = this.
|
|
5154
|
+
const connectivityDecoders = this.N.Yb;
|
|
5163
5155
|
const numCorners = this.a.numCorners();
|
|
5164
5156
|
const candidates = scratchInt32(numCorners);
|
|
5165
5157
|
let numCandidates = 0;
|
|
5166
|
-
let numBoundaryCorners = 0;
|
|
5167
5158
|
for (let corner = 0; corner < numCorners; corner += 3) {
|
|
5168
|
-
|
|
5169
|
-
|
|
5170
|
-
numCandidates
|
|
5171
|
-
|
|
5172
|
-
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
numBoundaryCorners -= opp >> 31;
|
|
5176
|
-
opp = oppositeCorners[corner + 2];
|
|
5177
|
-
candidates[numCandidates] = corner + 2 ^ opp >> 31;
|
|
5178
|
-
numCandidates -= (opp | corner - opp - 1) >> 31;
|
|
5179
|
-
numBoundaryCorners -= opp >> 31;
|
|
5180
|
-
}
|
|
5181
|
-
this.Wb = numBoundaryCorners;
|
|
5159
|
+
candidates[numCandidates] = corner;
|
|
5160
|
+
numCandidates -= corner - oppositeCorners[corner] - 1 >> 31;
|
|
5161
|
+
candidates[numCandidates] = corner + 1;
|
|
5162
|
+
numCandidates -= corner - oppositeCorners[corner + 1] - 1 >> 31;
|
|
5163
|
+
candidates[numCandidates] = corner + 2;
|
|
5164
|
+
numCandidates -= corner - oppositeCorners[corner + 2] - 1 >> 31;
|
|
5165
|
+
}
|
|
5182
5166
|
let i = 0;
|
|
5183
5167
|
for (; i + 2 <= numAttrData; i += 2) {
|
|
5184
5168
|
decodeSeamBits2(
|
|
@@ -5196,7 +5180,7 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5196
5180
|
}
|
|
5197
5181
|
// Position-only connectivity: vertex indices equal point indices.
|
|
5198
5182
|
yc(numConnectivityVerts) {
|
|
5199
|
-
const mesh = this.
|
|
5183
|
+
const mesh = this.o.mesh();
|
|
5200
5184
|
const ct = this.a;
|
|
5201
5185
|
mesh.setNumFaces(ct.numFaces());
|
|
5202
5186
|
const numCorners = ct.numCorners();
|
|
@@ -5205,8 +5189,8 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5205
5189
|
for (let c = 0; c < numCorners; ++c) {
|
|
5206
5190
|
faces[c] = baseCornerToVertex[c];
|
|
5207
5191
|
}
|
|
5208
|
-
this.
|
|
5209
|
-
this.
|
|
5192
|
+
this.ba = null;
|
|
5193
|
+
this.o.pointCloud().setNumPoints(numConnectivityVerts);
|
|
5210
5194
|
}
|
|
5211
5195
|
// Sets up an attribute corner table whose only seams are boundary edges
|
|
5212
5196
|
// (see decodeConnectivity), for a per-corner decoder that asked for it:
|
|
@@ -5247,7 +5231,7 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5247
5231
|
// (or left through the seam-aware table, which stops at the boundary), so
|
|
5248
5232
|
// an open ring is walked from that corner too.
|
|
5249
5233
|
zc(tables, seamEdgeCounts) {
|
|
5250
|
-
const mesh = this.
|
|
5234
|
+
const mesh = this.o.mesh();
|
|
5251
5235
|
const ct = this.a;
|
|
5252
5236
|
mesh.setNumFaces(ct.numFaces());
|
|
5253
5237
|
const numCorners = ct.numCorners();
|
|
@@ -5259,24 +5243,41 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5259
5243
|
const isVertHole = this.ka;
|
|
5260
5244
|
const baseOnBoundary = ct.vertexOnBoundaryArray();
|
|
5261
5245
|
const numTables = tables.length;
|
|
5246
|
+
if (numTables === 0) {
|
|
5247
|
+
let isolated = false;
|
|
5248
|
+
for (let v = 0; v < numVertices; ++v) {
|
|
5249
|
+
if (vertexLeftmost[v] < 0) {
|
|
5250
|
+
isolated = true;
|
|
5251
|
+
break;
|
|
5252
|
+
}
|
|
5253
|
+
}
|
|
5254
|
+
if (!isolated) {
|
|
5255
|
+
faces.set(baseCornerToVertex);
|
|
5256
|
+
this.ba = vertexLeftmost;
|
|
5257
|
+
this.Ea = ct;
|
|
5258
|
+
this.o.pointCloud().setNumPoints(numVertices);
|
|
5259
|
+
return true;
|
|
5260
|
+
}
|
|
5261
|
+
}
|
|
5262
5262
|
const attCornerToVertex = new Array(numTables);
|
|
5263
5263
|
const attOpposite = new Array(numTables);
|
|
5264
5264
|
const vertexOnSeam = new Array(numTables);
|
|
5265
5265
|
const onBoundaryMaps = new Array(numTables);
|
|
5266
5266
|
const numExtraVertices = new Int32Array(numTables);
|
|
5267
5267
|
for (let t = 0; t < numTables; ++t) {
|
|
5268
|
-
attCornerToVertex[t] = tables[t].
|
|
5269
|
-
attOpposite[t] = tables[t].
|
|
5268
|
+
attCornerToVertex[t] = tables[t].Y;
|
|
5269
|
+
attOpposite[t] = tables[t].J;
|
|
5270
5270
|
vertexOnSeam[t] = tables[t].sa;
|
|
5271
5271
|
const onBoundary = scratchUint8(numVertices + 2 * seamEdgeCounts[t]);
|
|
5272
5272
|
onBoundary.set(baseOnBoundary);
|
|
5273
5273
|
onBoundary.fill(1, numVertices);
|
|
5274
5274
|
onBoundaryMaps[t] = onBoundary;
|
|
5275
5275
|
}
|
|
5276
|
-
const
|
|
5277
|
-
const
|
|
5276
|
+
const ringSize = numTables > 0 ? numCorners : 0;
|
|
5277
|
+
const ring = scratchInt32(ringSize);
|
|
5278
|
+
const ringNext = scratchInt32(ringSize);
|
|
5278
5279
|
const pointCorner = scratchInt32(numCorners);
|
|
5279
|
-
const idChange = scratchUint8Zeroed(
|
|
5280
|
+
const idChange = scratchUint8Zeroed(ringSize);
|
|
5280
5281
|
let numPoints = 0;
|
|
5281
5282
|
const plainPointId = scratchInt32(numVertices);
|
|
5282
5283
|
let numWalked = 0;
|
|
@@ -5398,8 +5399,8 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5398
5399
|
for (let t = 0; t < numTables; ++t) {
|
|
5399
5400
|
tables[t].setRecomputedVertices(onBoundaryMaps[t], numVertices + numExtraVertices[t]);
|
|
5400
5401
|
}
|
|
5401
|
-
this.
|
|
5402
|
-
this.
|
|
5402
|
+
this.ba = pointCorner;
|
|
5403
|
+
this.o.pointCloud().setNumPoints(numPoints);
|
|
5403
5404
|
return true;
|
|
5404
5405
|
}
|
|
5405
5406
|
};
|
|
@@ -5413,11 +5414,6 @@ function decodeSeamBits1(candidates, numCandidates, ad, decoder) {
|
|
|
5413
5414
|
let state = ans.state;
|
|
5414
5415
|
let bufOffset = ans.bufOffset;
|
|
5415
5416
|
for (let n = 0; n < numCandidates; ++n) {
|
|
5416
|
-
const cc = candidates[n];
|
|
5417
|
-
if (cc < 0) {
|
|
5418
|
-
seamCorners[numSeamCorners++] = ~cc;
|
|
5419
|
-
continue;
|
|
5420
|
-
}
|
|
5421
5417
|
if (state < ANS_L_BASE && bufOffset > bufStart) {
|
|
5422
5418
|
state = state << 8 | buf[--bufOffset];
|
|
5423
5419
|
}
|
|
@@ -5426,7 +5422,7 @@ function decodeSeamBits1(candidates, numCandidates, ad, decoder) {
|
|
|
5426
5422
|
const mask = rem - p >> 31;
|
|
5427
5423
|
const stateIfZero = state - xn - p;
|
|
5428
5424
|
state = stateIfZero + (mask & xn + rem - stateIfZero);
|
|
5429
|
-
seamCorners[numSeamCorners] =
|
|
5425
|
+
seamCorners[numSeamCorners] = candidates[n];
|
|
5430
5426
|
numSeamCorners -= mask;
|
|
5431
5427
|
}
|
|
5432
5428
|
ans.state = state;
|
|
@@ -5452,11 +5448,6 @@ function decodeSeamBits2(candidates, numCandidates, ad0, decoder0, ad1, decoder1
|
|
|
5452
5448
|
let off1 = ans1.bufOffset;
|
|
5453
5449
|
for (let n = 0; n < numCandidates; ++n) {
|
|
5454
5450
|
const cc = candidates[n];
|
|
5455
|
-
if (cc < 0) {
|
|
5456
|
-
seam0[num0++] = ~cc;
|
|
5457
|
-
seam1[num1++] = ~cc;
|
|
5458
|
-
continue;
|
|
5459
|
-
}
|
|
5460
5451
|
if (state0 < ANS_L_BASE && off0 > start0) {
|
|
5461
5452
|
state0 = state0 << 8 | buf0[--off0];
|
|
5462
5453
|
}
|
|
@@ -5486,8 +5477,8 @@ function decodeSeamBits2(candidates, numCandidates, ad0, decoder0, ad1, decoder1
|
|
|
5486
5477
|
ad1.numSeamCorners = num1;
|
|
5487
5478
|
}
|
|
5488
5479
|
var MeshAttributeIndicesEncodingData = class {
|
|
5489
|
-
vertexToEncodedAttributeValueIndexMap =
|
|
5490
|
-
encodedAttributeValueIndexToCornerMap =
|
|
5480
|
+
vertexToEncodedAttributeValueIndexMap = EMPTY_INT32;
|
|
5481
|
+
encodedAttributeValueIndexToCornerMap = EMPTY_INT32;
|
|
5491
5482
|
numValues = 0;
|
|
5492
5483
|
// The traversal cache entry the maps came from (see MeshTraversalSequencer);
|
|
5493
5484
|
// carries what later passes derive from the traversal and share.
|
|
@@ -5513,43 +5504,43 @@ var AttributeData = class {
|
|
|
5513
5504
|
connectivityData = new MeshAttributeCornerTable();
|
|
5514
5505
|
isConnectivityUsed = true;
|
|
5515
5506
|
encodingData = new MeshAttributeIndicesEncodingData();
|
|
5516
|
-
attributeSeamCorners =
|
|
5507
|
+
attributeSeamCorners = EMPTY_INT32;
|
|
5517
5508
|
numSeamCorners = 0;
|
|
5518
|
-
// Set when
|
|
5509
|
+
// Set when the set has no interior seam and connectivityData was therefore
|
|
5519
5510
|
// left unbuilt (see decodeConnectivity); cleared once it is built on demand.
|
|
5520
5511
|
noInteriorSeams = false;
|
|
5521
5512
|
};
|
|
5522
5513
|
var CornerTable = class {
|
|
5523
5514
|
Zb = 0;
|
|
5524
|
-
|
|
5525
|
-
|
|
5526
|
-
|
|
5515
|
+
M = 0;
|
|
5516
|
+
l = 0;
|
|
5517
|
+
k = null;
|
|
5527
5518
|
// corner -> vertex
|
|
5528
|
-
|
|
5519
|
+
w = null;
|
|
5529
5520
|
// corner -> opposite corner
|
|
5530
|
-
|
|
5521
|
+
u = null;
|
|
5531
5522
|
// vertex -> left-most corner
|
|
5532
5523
|
// vertex -> 1 when its fan is open (C++ IsOnBoundary: the edge left of
|
|
5533
5524
|
// the left-most corner has no opposite face), computed once after the
|
|
5534
5525
|
// connectivity decode (see finishBoundaries) for the traversals, whose
|
|
5535
5526
|
// critical path would otherwise chase two dependent loads per new vertex.
|
|
5536
|
-
|
|
5527
|
+
C = null;
|
|
5537
5528
|
reset(numFaces, numVertices) {
|
|
5538
5529
|
this.Zb = numFaces;
|
|
5539
|
-
this.
|
|
5540
|
-
this.
|
|
5541
|
-
this.
|
|
5542
|
-
this.
|
|
5543
|
-
this.
|
|
5530
|
+
this.M = numFaces * 3;
|
|
5531
|
+
this.l = 0;
|
|
5532
|
+
this.k = scratchInt32Filled(this.M, -1);
|
|
5533
|
+
this.w = scratchInt32Filled(this.M, -1);
|
|
5534
|
+
this.u = scratchInt32Filled(numVertices, -1);
|
|
5544
5535
|
}
|
|
5545
5536
|
numFaces() {
|
|
5546
5537
|
return this.Zb;
|
|
5547
5538
|
}
|
|
5548
5539
|
numCorners() {
|
|
5549
|
-
return this.
|
|
5540
|
+
return this.M;
|
|
5550
5541
|
}
|
|
5551
5542
|
numVertices() {
|
|
5552
|
-
return this.
|
|
5543
|
+
return this.l;
|
|
5553
5544
|
}
|
|
5554
5545
|
next(corner) {
|
|
5555
5546
|
if (corner < 0) return -1;
|
|
@@ -5562,50 +5553,50 @@ var CornerTable = class {
|
|
|
5562
5553
|
return rem === 0 ? corner + 2 : corner - 1;
|
|
5563
5554
|
}
|
|
5564
5555
|
vertex(corner) {
|
|
5565
|
-
if (corner < 0 || corner >= this.
|
|
5566
|
-
return this.
|
|
5556
|
+
if (corner < 0 || corner >= this.M) return -1;
|
|
5557
|
+
return this.k[corner];
|
|
5567
5558
|
}
|
|
5568
5559
|
opposite(corner) {
|
|
5569
|
-
if (corner < 0 || corner >= this.
|
|
5570
|
-
return this.
|
|
5560
|
+
if (corner < 0 || corner >= this.M) return -1;
|
|
5561
|
+
return this.w[corner];
|
|
5571
5562
|
}
|
|
5572
5563
|
// Flat-array accessors; let callers avoid polymorphic per-corner dispatch.
|
|
5573
5564
|
cornerToVertexArray() {
|
|
5574
|
-
return this.
|
|
5565
|
+
return this.k;
|
|
5575
5566
|
}
|
|
5576
5567
|
oppositeCornerArray() {
|
|
5577
|
-
return this.
|
|
5568
|
+
return this.w;
|
|
5578
5569
|
}
|
|
5579
5570
|
vertexLeftmostCornerArray() {
|
|
5580
|
-
return this.
|
|
5571
|
+
return this.u;
|
|
5581
5572
|
}
|
|
5582
5573
|
vertexOnBoundaryArray() {
|
|
5583
|
-
return this.
|
|
5574
|
+
return this.C;
|
|
5584
5575
|
}
|
|
5585
5576
|
// Derives _vertexOnBoundary from the finished connectivity (decode-scoped
|
|
5586
5577
|
// scratch). Isolated vertices count as boundary; they are never traversed.
|
|
5587
5578
|
finishBoundaries() {
|
|
5588
|
-
const numVertices = this.
|
|
5589
|
-
const vertexCorners = this.
|
|
5590
|
-
const oppositeCorners = this.
|
|
5579
|
+
const numVertices = this.l;
|
|
5580
|
+
const vertexCorners = this.u;
|
|
5581
|
+
const oppositeCorners = this.w;
|
|
5591
5582
|
const onBoundary = scratchUint8(numVertices);
|
|
5592
5583
|
for (let v = 0; v < numVertices; ++v) {
|
|
5593
5584
|
const lc = vertexCorners[v];
|
|
5594
5585
|
onBoundary[v] = lc < 0 || oppositeCorners[lc % 3 === 2 ? lc - 2 : lc + 1] < 0 ? 1 : 0;
|
|
5595
5586
|
}
|
|
5596
|
-
this.
|
|
5587
|
+
this.C = onBoundary;
|
|
5597
5588
|
}
|
|
5598
5589
|
// Mirrors C++ CornerTable::AddNewVertex() (push_back(kInvalidCornerIndex)).
|
|
5599
5590
|
addNewVertex() {
|
|
5600
|
-
const newVertex = this.
|
|
5601
|
-
this.
|
|
5602
|
-
if (newVertex >= this.
|
|
5603
|
-
const newCapacity = Math.max(newVertex + 1, this.
|
|
5591
|
+
const newVertex = this.l;
|
|
5592
|
+
this.l++;
|
|
5593
|
+
if (newVertex >= this.u.length) {
|
|
5594
|
+
const newCapacity = Math.max(newVertex + 1, this.u.length * 2, 64);
|
|
5604
5595
|
const newArr = scratchInt32Filled(newCapacity, -1);
|
|
5605
|
-
newArr.set(this.
|
|
5606
|
-
this.
|
|
5596
|
+
newArr.set(this.u);
|
|
5597
|
+
this.u = newArr;
|
|
5607
5598
|
}
|
|
5608
|
-
this.
|
|
5599
|
+
this.u[newVertex] = -1;
|
|
5609
5600
|
return newVertex;
|
|
5610
5601
|
}
|
|
5611
5602
|
// Next corner around a vertex, CCW. SwingLeft(c) = Next(Opposite(Next(c))).
|
|
@@ -5627,8 +5618,8 @@ var CornerTable = class {
|
|
|
5627
5618
|
// src/decoder/compression/mesh/MeshEdgebreakerTraversalDecoder.ts
|
|
5628
5619
|
var MeshEdgebreakerTraversalDecoder = class {
|
|
5629
5620
|
d = new DecoderBuffer();
|
|
5630
|
-
|
|
5631
|
-
|
|
5621
|
+
S = new DecoderBuffer();
|
|
5622
|
+
nb = null;
|
|
5632
5623
|
Yb = [];
|
|
5633
5624
|
_b = 0;
|
|
5634
5625
|
// _symbolBuffer's bit cursor, captured once bit decoding starts: decodeSymbol
|
|
@@ -5636,8 +5627,8 @@ var MeshEdgebreakerTraversalDecoder = class {
|
|
|
5636
5627
|
// loads and a method call per read.
|
|
5637
5628
|
$b = null;
|
|
5638
5629
|
init(decoder) {
|
|
5639
|
-
const srcBuffer = decoder.
|
|
5640
|
-
this.d.
|
|
5630
|
+
const srcBuffer = decoder.o.buffer();
|
|
5631
|
+
this.d.initFrom(srcBuffer);
|
|
5641
5632
|
}
|
|
5642
5633
|
// Ignored by default; overridden by predictive/valence decoders.
|
|
5643
5634
|
setNumEncodedVertices(_numVertices) {
|
|
@@ -5656,33 +5647,33 @@ var MeshEdgebreakerTraversalDecoder = class {
|
|
|
5656
5647
|
if (!this.decodeAttributeSeams()) {
|
|
5657
5648
|
return false;
|
|
5658
5649
|
}
|
|
5659
|
-
outBuffer.
|
|
5650
|
+
outBuffer.initFrom(this.d);
|
|
5660
5651
|
return true;
|
|
5661
5652
|
}
|
|
5662
5653
|
decodeStartFaceConfiguration() {
|
|
5663
|
-
return this.
|
|
5654
|
+
return this.nb.decodeNextBit();
|
|
5664
5655
|
}
|
|
5665
5656
|
decodeSymbol() {
|
|
5666
5657
|
const bd = this.$b;
|
|
5667
5658
|
if (bd !== null) {
|
|
5668
|
-
const buf = bd.
|
|
5669
|
-
const off = bd.
|
|
5659
|
+
const buf = bd.Na;
|
|
5660
|
+
const off = bd.q;
|
|
5670
5661
|
const byteOffset = off >> 3;
|
|
5671
5662
|
if (byteOffset + 4 < bd.qa) {
|
|
5672
5663
|
const bits = (buf[byteOffset] | buf[byteOffset + 1] << 8 | buf[byteOffset + 2] << 16 | buf[byteOffset + 3] << 24) >>> (off & 7) & 7;
|
|
5673
5664
|
if ((bits & 1) === TOPOLOGY_C) {
|
|
5674
|
-
bd.
|
|
5665
|
+
bd.q = off + 1;
|
|
5675
5666
|
return TOPOLOGY_C;
|
|
5676
5667
|
}
|
|
5677
|
-
bd.
|
|
5668
|
+
bd.q = off + 3;
|
|
5678
5669
|
return bits;
|
|
5679
5670
|
}
|
|
5680
5671
|
}
|
|
5681
|
-
let symbol = this.
|
|
5672
|
+
let symbol = this.S.decodeLeastSignificantBits32(1);
|
|
5682
5673
|
if (symbol === TOPOLOGY_C) {
|
|
5683
5674
|
return symbol;
|
|
5684
5675
|
}
|
|
5685
|
-
const symbolSuffix = this.
|
|
5676
|
+
const symbolSuffix = this.S.decodeLeastSignificantBits32(2);
|
|
5686
5677
|
symbol |= symbolSuffix << 1;
|
|
5687
5678
|
return symbol;
|
|
5688
5679
|
}
|
|
@@ -5691,18 +5682,18 @@ var MeshEdgebreakerTraversalDecoder = class {
|
|
|
5691
5682
|
mergeVertices(_dest, _source) {
|
|
5692
5683
|
}
|
|
5693
5684
|
done() {
|
|
5694
|
-
if (this.
|
|
5695
|
-
this.
|
|
5685
|
+
if (this.S.bitDecoderActive) {
|
|
5686
|
+
this.S.endBitDecoding();
|
|
5696
5687
|
}
|
|
5697
5688
|
}
|
|
5698
5689
|
decodeTraversalSymbols() {
|
|
5699
|
-
this.
|
|
5700
|
-
const traversalSize = this.
|
|
5690
|
+
this.S.initFrom(this.d);
|
|
5691
|
+
const traversalSize = this.S.startBitDecoding(true);
|
|
5701
5692
|
if (traversalSize === void 0) {
|
|
5702
5693
|
return false;
|
|
5703
5694
|
}
|
|
5704
|
-
this.$b = this.
|
|
5705
|
-
this.d.
|
|
5695
|
+
this.$b = this.S.ra;
|
|
5696
|
+
this.d.initFrom(this.S);
|
|
5706
5697
|
if (traversalSize > this.d.remainingSize) {
|
|
5707
5698
|
return false;
|
|
5708
5699
|
}
|
|
@@ -5711,8 +5702,8 @@ var MeshEdgebreakerTraversalDecoder = class {
|
|
|
5711
5702
|
}
|
|
5712
5703
|
decodeStartFaces() {
|
|
5713
5704
|
try {
|
|
5714
|
-
this.
|
|
5715
|
-
return this.
|
|
5705
|
+
this.nb = new RAnsBitDecoder();
|
|
5706
|
+
return this.nb.startDecoding(this.d);
|
|
5716
5707
|
} catch {
|
|
5717
5708
|
return false;
|
|
5718
5709
|
}
|
|
@@ -5732,17 +5723,17 @@ var MeshEdgebreakerTraversalDecoder = class {
|
|
|
5732
5723
|
// src/decoder/compression/mesh/MeshEdgebreakerTraversalPredictiveDecoder.ts
|
|
5733
5724
|
var MeshEdgebreakerTraversalPredictiveDecoder = class extends MeshEdgebreakerTraversalDecoder {
|
|
5734
5725
|
a = null;
|
|
5735
|
-
|
|
5726
|
+
l = 0;
|
|
5736
5727
|
A = -1;
|
|
5737
5728
|
la = -1;
|
|
5738
|
-
|
|
5739
|
-
|
|
5729
|
+
m = [];
|
|
5730
|
+
ob = null;
|
|
5740
5731
|
init(decoder) {
|
|
5741
5732
|
super.init(decoder);
|
|
5742
5733
|
this.a = decoder.getCornerTable();
|
|
5743
5734
|
}
|
|
5744
5735
|
setNumEncodedVertices(numVertices) {
|
|
5745
|
-
this.
|
|
5736
|
+
this.l = numVertices;
|
|
5746
5737
|
}
|
|
5747
5738
|
start(outBuffer) {
|
|
5748
5739
|
if (!super.start(outBuffer)) {
|
|
@@ -5752,16 +5743,16 @@ var MeshEdgebreakerTraversalPredictiveDecoder = class extends MeshEdgebreakerTra
|
|
|
5752
5743
|
if (numSplitSymbols === void 0 || numSplitSymbols < 0) {
|
|
5753
5744
|
return false;
|
|
5754
5745
|
}
|
|
5755
|
-
if (numSplitSymbols >= this.
|
|
5746
|
+
if (numSplitSymbols >= this.l) {
|
|
5756
5747
|
return false;
|
|
5757
5748
|
}
|
|
5758
|
-
this.
|
|
5759
|
-
this.
|
|
5760
|
-
return this.
|
|
5749
|
+
this.m = new Array(this.l).fill(0);
|
|
5750
|
+
this.ob = new RAnsBitDecoder();
|
|
5751
|
+
return this.ob.startDecoding(outBuffer);
|
|
5761
5752
|
}
|
|
5762
5753
|
decodeSymbol() {
|
|
5763
5754
|
if (this.la !== -1) {
|
|
5764
|
-
if (this.
|
|
5755
|
+
if (this.ob.decodeNextBit()) {
|
|
5765
5756
|
this.A = this.la;
|
|
5766
5757
|
return this.la;
|
|
5767
5758
|
}
|
|
@@ -5776,30 +5767,30 @@ var MeshEdgebreakerTraversalPredictiveDecoder = class extends MeshEdgebreakerTra
|
|
|
5776
5767
|
switch (this.A) {
|
|
5777
5768
|
case TOPOLOGY_C:
|
|
5778
5769
|
case TOPOLOGY_S:
|
|
5779
|
-
this.
|
|
5780
|
-
this.
|
|
5770
|
+
this.m[ct.vertex(next)] += 1;
|
|
5771
|
+
this.m[ct.vertex(prev)] += 1;
|
|
5781
5772
|
break;
|
|
5782
5773
|
case TOPOLOGY_R:
|
|
5783
|
-
this.
|
|
5784
|
-
this.
|
|
5785
|
-
this.
|
|
5774
|
+
this.m[ct.vertex(corner)] += 1;
|
|
5775
|
+
this.m[ct.vertex(next)] += 1;
|
|
5776
|
+
this.m[ct.vertex(prev)] += 2;
|
|
5786
5777
|
break;
|
|
5787
5778
|
case TOPOLOGY_L:
|
|
5788
|
-
this.
|
|
5789
|
-
this.
|
|
5790
|
-
this.
|
|
5779
|
+
this.m[ct.vertex(corner)] += 1;
|
|
5780
|
+
this.m[ct.vertex(next)] += 2;
|
|
5781
|
+
this.m[ct.vertex(prev)] += 1;
|
|
5791
5782
|
break;
|
|
5792
5783
|
case TOPOLOGY_E:
|
|
5793
|
-
this.
|
|
5794
|
-
this.
|
|
5795
|
-
this.
|
|
5784
|
+
this.m[ct.vertex(corner)] += 2;
|
|
5785
|
+
this.m[ct.vertex(next)] += 2;
|
|
5786
|
+
this.m[ct.vertex(prev)] += 2;
|
|
5796
5787
|
break;
|
|
5797
5788
|
default:
|
|
5798
5789
|
break;
|
|
5799
5790
|
}
|
|
5800
5791
|
if (this.A === TOPOLOGY_C || this.A === TOPOLOGY_R) {
|
|
5801
5792
|
const pivot = ct.vertex(ct.next(corner));
|
|
5802
|
-
if (this.
|
|
5793
|
+
if (this.m[pivot] < 6) {
|
|
5803
5794
|
this.la = TOPOLOGY_R;
|
|
5804
5795
|
} else {
|
|
5805
5796
|
this.la = TOPOLOGY_C;
|
|
@@ -5809,34 +5800,34 @@ var MeshEdgebreakerTraversalPredictiveDecoder = class extends MeshEdgebreakerTra
|
|
|
5809
5800
|
}
|
|
5810
5801
|
}
|
|
5811
5802
|
mergeVertices(dest, source) {
|
|
5812
|
-
this.
|
|
5803
|
+
this.m[dest] += this.m[source];
|
|
5813
5804
|
}
|
|
5814
5805
|
};
|
|
5815
5806
|
|
|
5816
5807
|
// src/decoder/compression/mesh/MeshEdgebreakerTraversalValenceDecoder.ts
|
|
5817
5808
|
var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraversalDecoder {
|
|
5818
5809
|
a = null;
|
|
5819
|
-
|
|
5810
|
+
l = 0;
|
|
5820
5811
|
A = -1;
|
|
5821
5812
|
Va = -1;
|
|
5822
5813
|
Wa = 2;
|
|
5823
|
-
|
|
5824
|
-
|
|
5814
|
+
pb = 7;
|
|
5815
|
+
m = EMPTY_INT32;
|
|
5825
5816
|
ma = [];
|
|
5826
5817
|
// Int32Array, not number[]: read and written once per decoded symbol.
|
|
5827
|
-
Fa =
|
|
5818
|
+
Fa = EMPTY_INT32;
|
|
5828
5819
|
// corner -> vertex of _cornerTable, cached at init(); the array is created
|
|
5829
5820
|
// once by CornerTable.reset() before the traversal decoder is initialized and
|
|
5830
5821
|
// never replaced, so the per-symbol hot path can read it without two property
|
|
5831
5822
|
// loads.
|
|
5832
|
-
|
|
5823
|
+
k = EMPTY_INT32;
|
|
5833
5824
|
init(decoder) {
|
|
5834
5825
|
super.init(decoder);
|
|
5835
5826
|
this.a = decoder.getCornerTable();
|
|
5836
|
-
this.
|
|
5827
|
+
this.k = this.a.k;
|
|
5837
5828
|
}
|
|
5838
5829
|
setNumEncodedVertices(numVertices) {
|
|
5839
|
-
this.
|
|
5830
|
+
this.l = numVertices;
|
|
5840
5831
|
}
|
|
5841
5832
|
start(outBuffer) {
|
|
5842
5833
|
if (!this.decodeStartFaces()) {
|
|
@@ -5845,9 +5836,9 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
|
|
|
5845
5836
|
if (!this.decodeAttributeSeams()) {
|
|
5846
5837
|
return false;
|
|
5847
5838
|
}
|
|
5848
|
-
outBuffer.
|
|
5849
|
-
this.
|
|
5850
|
-
const numUniqueValences = this.
|
|
5839
|
+
outBuffer.initFrom(this.d);
|
|
5840
|
+
this.m = scratchInt32Filled(this.l, 0);
|
|
5841
|
+
const numUniqueValences = this.pb - this.Wa + 1;
|
|
5851
5842
|
this.ma = new Array(numUniqueValences);
|
|
5852
5843
|
this.Fa = new Int32Array(numUniqueValences);
|
|
5853
5844
|
const pending = [];
|
|
@@ -5888,7 +5879,7 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
|
|
|
5888
5879
|
return false;
|
|
5889
5880
|
}
|
|
5890
5881
|
pending.push(decoder);
|
|
5891
|
-
streams.push({ ans: decoder.
|
|
5882
|
+
streams.push({ ans: decoder.L, out: this.ma[i], count: numSymbols });
|
|
5892
5883
|
this.Fa[i] = numSymbols;
|
|
5893
5884
|
} else {
|
|
5894
5885
|
this.ma[i] = new Uint32Array(0);
|
|
@@ -5916,8 +5907,8 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
|
|
|
5916
5907
|
return this.A;
|
|
5917
5908
|
}
|
|
5918
5909
|
newActiveCornerReached(corner) {
|
|
5919
|
-
const cornerToVertex = this.
|
|
5920
|
-
const valences = this.
|
|
5910
|
+
const cornerToVertex = this.k;
|
|
5911
|
+
const valences = this.m;
|
|
5921
5912
|
const next = corner % 3 === 2 ? corner - 2 : corner + 1;
|
|
5922
5913
|
const prev = corner % 3 === 0 ? corner + 2 : corner - 1;
|
|
5923
5914
|
const vertNext = cornerToVertex[next];
|
|
@@ -5950,15 +5941,15 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
|
|
|
5950
5941
|
let clampedValence;
|
|
5951
5942
|
if (activeValence < this.Wa) {
|
|
5952
5943
|
clampedValence = this.Wa;
|
|
5953
|
-
} else if (activeValence > this.
|
|
5954
|
-
clampedValence = this.
|
|
5944
|
+
} else if (activeValence > this.pb) {
|
|
5945
|
+
clampedValence = this.pb;
|
|
5955
5946
|
} else {
|
|
5956
5947
|
clampedValence = activeValence;
|
|
5957
5948
|
}
|
|
5958
5949
|
this.Va = clampedValence - this.Wa;
|
|
5959
5950
|
}
|
|
5960
5951
|
mergeVertices(dest, source) {
|
|
5961
|
-
this.
|
|
5952
|
+
this.m[dest] += this.m[source];
|
|
5962
5953
|
}
|
|
5963
5954
|
};
|
|
5964
5955
|
|
|
@@ -5999,7 +5990,7 @@ var LinearSequencer = class {
|
|
|
5999
5990
|
constructor(numPoints) {
|
|
6000
5991
|
this.Xa = numPoints;
|
|
6001
5992
|
}
|
|
6002
|
-
generateSequence() {
|
|
5993
|
+
generateSequence(_parallelogramParents) {
|
|
6003
5994
|
if (this.Xa < 0) {
|
|
6004
5995
|
return false;
|
|
6005
5996
|
}
|
|
@@ -6189,10 +6180,10 @@ var MinidracoLoader = class extends Loader {
|
|
|
6189
6180
|
// The pool, once its module has loaded; null again after dispose() so a
|
|
6190
6181
|
// later decode spawns a fresh one.
|
|
6191
6182
|
pa = null;
|
|
6192
|
-
|
|
6183
|
+
qb = null;
|
|
6193
6184
|
// Set when the pool module fails to load or the pool breaks: decoding
|
|
6194
6185
|
// transparently falls back to the main thread.
|
|
6195
|
-
|
|
6186
|
+
rb = false;
|
|
6196
6187
|
Ga = null;
|
|
6197
6188
|
// Accepts either a LoadingManager (three-compatible form) or an options bag.
|
|
6198
6189
|
constructor(managerOrOptions) {
|
|
@@ -6244,7 +6235,7 @@ var MinidracoLoader = class extends Loader {
|
|
|
6244
6235
|
dispose() {
|
|
6245
6236
|
if (this.pa !== null) this.pa.dispose();
|
|
6246
6237
|
this.pa = null;
|
|
6247
|
-
this.
|
|
6238
|
+
this.qb = null;
|
|
6248
6239
|
return this;
|
|
6249
6240
|
}
|
|
6250
6241
|
load(url, onLoad, onProgress, onError) {
|
|
@@ -6298,7 +6289,7 @@ var MinidracoLoader = class extends Loader {
|
|
|
6298
6289
|
return this.dc(raw, taskConfig);
|
|
6299
6290
|
} catch (error) {
|
|
6300
6291
|
if (error?.isDecodeError) throw error;
|
|
6301
|
-
this.
|
|
6292
|
+
this.rb = true;
|
|
6302
6293
|
}
|
|
6303
6294
|
}
|
|
6304
6295
|
} else {
|
|
@@ -6308,20 +6299,20 @@ var MinidracoLoader = class extends Loader {
|
|
|
6308
6299
|
return this._decodeBuffer(buffer, taskConfig);
|
|
6309
6300
|
}
|
|
6310
6301
|
bc() {
|
|
6311
|
-
return this.workerLimit > 0 && typeof Worker !== "undefined" && !this.
|
|
6302
|
+
return this.workerLimit > 0 && typeof Worker !== "undefined" && !this.rb;
|
|
6312
6303
|
}
|
|
6313
6304
|
// The pool, loading its module on first use. Resolves null (and marks the
|
|
6314
6305
|
// workers broken) when the module cannot be loaded, e.g. a bundler that does
|
|
6315
6306
|
// not split dynamic imports out of dependencies.
|
|
6316
6307
|
cc() {
|
|
6317
|
-
this.
|
|
6308
|
+
this.qb ??= import("./pool.js").then(
|
|
6318
6309
|
(module) => this.pa = new module.WorkerPool(this.workerLimit, this.Ga),
|
|
6319
6310
|
() => {
|
|
6320
|
-
this.
|
|
6311
|
+
this.rb = true;
|
|
6321
6312
|
return null;
|
|
6322
6313
|
}
|
|
6323
6314
|
);
|
|
6324
|
-
return this.
|
|
6315
|
+
return this.qb;
|
|
6325
6316
|
}
|
|
6326
6317
|
dc(raw, taskConfig) {
|
|
6327
6318
|
const geometry = new BufferGeometry();
|