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/dist/three.js CHANGED
@@ -46,31 +46,31 @@ var Type = {
46
46
  var GeometryAttribute = class {
47
47
  d = null;
48
48
  y = 1;
49
- S = 9 /* FLOAT32 */;
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.S = dataType;
58
+ this.T = dataType;
59
59
  this.Za = normalized;
60
- this.T = byteStride;
61
- this.U = byteOffset;
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.T = byteStride;
67
- this.U = byteOffset;
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.S;
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.T;
82
+ return this.U;
83
83
  }
84
84
  get byteOffset() {
85
- return this.U;
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
- ub = 0;
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.ub;
159
+ return this.sb;
160
160
  }
161
161
  setNumPoints(num) {
162
- this.ub = num;
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
- vb = 0;
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.vb = numFaces;
184
+ this.tb = numFaces;
185
185
  }
186
186
  numFaces() {
187
- return this.vb;
187
+ return this.tb;
188
188
  }
189
189
  };
190
190
 
191
191
  // src/decoder/core/DataBuffer.ts
192
192
  var DataBuffer = class {
193
- o = new Uint8Array(0);
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.wb(size);
198
+ this.ub(size);
199
199
  return;
200
200
  }
201
- if (size > this.o.length) {
202
- this.wb(size);
201
+ if (size > this.h.length) {
202
+ this.ub(size);
203
203
  }
204
- this.o.set(data.length === size ? data : data.subarray(0, size));
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.o.set(inArray.length === dataSize ? inArray : inArray.subarray(0, dataSize), bytePos);
210
+ this.h.set(inArray.length === dataSize ? inArray : inArray.subarray(0, dataSize), bytePos);
211
211
  }
212
212
  get data() {
213
- return this.o;
213
+ return this.h;
214
214
  }
215
- wb(newSize) {
216
- if (newSize === this.o.length) return;
215
+ ub(newSize) {
216
+ if (newSize === this.h.length) return;
217
217
  const newData = new Uint8Array(newSize);
218
- newData.set(this.o.subarray(0, Math.min(this.o.length, newSize)));
219
- this.o = newData;
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 MAX_CLASS = 28;
225
- var freeInt32 = [];
226
- var freeUint32 = [];
227
- var freeUint8 = [];
228
- for (let i = 0; i <= MAX_CLASS; ++i) {
229
- freeInt32.push([]);
230
- freeUint32.push([]);
231
- freeUint8.push([]);
232
- }
233
- var borrowedInt32 = [];
234
- var borrowedUint32 = [];
235
- var borrowedUint8 = [];
236
- var sizeClass = (size) => size <= 1 ? 0 : 32 - Math.clz32(size - 1);
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 k = sizeClass(size);
239
- if (k > MAX_CLASS) return new Int32Array(size);
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 k = sizeClass(size);
248
- if (k > MAX_CLASS) return new Uint32Array(size);
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 capacity = byteCapacity(size);
258
- const k = sizeClass(capacity);
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
- for (let i = 0; i < borrowedInt32.length; ++i) {
288
- const buffer = borrowedInt32[i];
289
- freeInt32[sizeClass(buffer.length)].push(buffer);
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
- borrowedInt32.length = 0;
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
- D = false;
333
- $a = 0;
334
- E = [];
335
- ca = null;
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
- Ka = LAZY_NONE;
349
- da = null;
350
- Ab = [];
351
- La = 0;
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
- ab = false;
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.ca = new DataBuffer();
331
+ this.W = new DataBuffer();
372
332
  const byteStride = dataTypeLength(dataType) * numComponents;
373
- super.init(attributeType, this.ca, numComponents, dataType, normalized, byteStride, 0);
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.ca === null) {
379
- this.ca = new DataBuffer();
338
+ if (this.W === null) {
339
+ this.W = new DataBuffer();
380
340
  }
381
341
  const entrySize = dataTypeLength(this.dataType) * this.numComponents;
382
- this.ca.update(null, numAttributeValues * entrySize);
383
- this.resetBuffer(this.ca, entrySize, 0);
384
- this.$a = numAttributeValues;
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.$a = numAttributeValues;
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.Ka = LAZY_INTEGER;
396
- this.da = values;
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.Ka = LAZY_QUANTIZED;
402
- this.da = values;
403
- this.Ab = minValues;
404
- this.La = delta;
405
- this.ab = bounded;
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.Ka = LAZY_OCTAHEDRON;
411
- this.da = values;
412
- this.La = scale;
413
- this.ab = bounded;
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.$a;
385
+ return this.Ka;
417
386
  }
418
387
  mappedIndex(pointIndex) {
419
- if (this.D) {
388
+ if (this.E) {
420
389
  return pointIndex;
421
390
  }
422
- return this.E[pointIndex];
391
+ return this.F[pointIndex];
423
392
  }
424
393
  get isMappingIdentity() {
425
- return this.D;
394
+ return this.E;
426
395
  }
427
396
  get indicesMapSize() {
428
- if (this.D) {
397
+ if (this.E) {
429
398
  return 0;
430
399
  }
431
- return this.E.length;
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.E;
406
+ return this.F;
438
407
  }
439
408
  // Implicit mapping: point index equals attribute entry index.
440
409
  setIdentityMapping() {
441
- this.D = true;
442
- this.E = [];
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.D = false;
453
- this.E = new Uint32Array(numPoints);
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.D = false;
460
- this.E = map;
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.D = false;
467
- this.E = scratchUint32(numPoints);
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
- Bb(Ctor, bufData) {
471
- if (this.xb !== Ctor || this.yb !== bufData.buffer) {
472
- this.xb = Ctor;
473
- this.yb = bufData.buffer;
474
- this.zb = new Ctor(bufData.buffer);
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.zb;
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.S);
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.Bb(Ctor, bufData);
491
- const baseIndex = (bufData.byteOffset + this.U + this.T * attIndex) / Ctor.BYTES_PER_ELEMENT;
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.Ka;
471
+ const kind = this.La;
503
472
  if (kind !== LAZY_NONE) {
504
- if (this.da !== null) {
505
- if (kind === LAZY_QUANTIZED) this.ec(array, numPoints);
506
- else if (kind === LAZY_OCTAHEDRON) this.fc(array, numPoints);
507
- else this.gc(array, numPoints);
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.S);
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.D;
517
- const indicesMap = this.E;
518
- const srcView = this.Bb(Ctor, bufData);
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.U >> shift;
521
- const strideElements = this.T >> shift;
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
- bb(numPoints) {
549
- if (!this.D) return this.E;
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
- Cb() {
563
- const values = this.da;
564
- if (this.ab) return values;
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
- ec(out, numPoints) {
575
- const values = this.Cb();
576
- const map = this.bb(numPoints);
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.La;
580
- const min = this.Ab;
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(fround(values[s] * delta) + m0);
588
- out[d + 1] = fround(fround(values[s + 1] * delta) + m1);
589
- out[d + 2] = fround(fround(values[s + 2] * delta) + m2);
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(fround(values[s] * delta) + m0);
599
- out[d + 1] = fround(fround(values[s + 1] * delta) + m1);
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(fround(values[s + c] * delta) + min[c]);
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
- fc(out, numPoints) {
613
- const values = this.Cb();
614
- const map = this.bb(numPoints);
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.La;
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
- let xOffset = -x;
623
- if (xOffset < 0) xOffset = 0;
624
- y = fround(y + (y < 0 ? xOffset : -xOffset));
625
- z = fround(z + (z < 0 ? xOffset : -xOffset));
626
- const normSquared = fround(fround(fround(x * x) + fround(y * y)) + fround(z * z));
627
- if (normSquared < 1e-6) {
628
- out[d] = 0;
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
- gc(out, numPoints) {
642
- const values = this.da;
643
- const map = this.bb(numPoints);
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.S;
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
- Ma = null;
678
- s = 0;
649
+ Na = null;
650
+ q = 0;
679
651
  qa = 0;
680
- reset(uint8Array, byteLength) {
681
- this.Ma = uint8Array;
682
- this.qa = byteLength;
683
- this.s = 0;
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.Ma;
688
- let off = this.s;
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.s = off + nbits;
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.s = currOff;
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
- o = null;
726
- Na = null;
727
- O = 0;
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.o = data;
733
- this.Na = new DataView(data.buffer, data.byteOffset, data.byteLength);
734
- this.O = dataSize;
735
- this.e = 0;
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.e + 1 > this.O) return void 0;
740
- const val = this.o[this.e];
741
- this.e += 1;
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
- if (this.e + 2 > this.O) return void 0;
746
- const val = this.Na.getUint16(this.e, true);
747
- this.e += 2;
748
- return val;
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
- if (this.e + 4 > this.O) return void 0;
752
- const val = this.Na.getInt32(this.e, true);
753
- this.e += 4;
754
- return val;
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
- if (this.e + 4 > this.O) return void 0;
758
- const val = this.Na.getFloat32(this.e, true);
759
- this.e += 4;
760
- return val;
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.e + size > this.O) return void 0;
766
- const result = this.o.subarray(this.e, this.e + size);
767
- this.e += size;
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.o.subarray(this.e), this.O - this.e);
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.e += Math.ceil(this.ra.s / 8);
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.e += bytes;
778
+ this.i += bytes;
793
779
  }
794
780
  get data() {
795
- return this.o;
796
- }
797
- get dataHead() {
798
- return this.o.subarray(this.e);
781
+ return this.h;
799
782
  }
800
783
  get remainingSize() {
801
- return this.O - this.e;
784
+ return this.B - this.i;
802
785
  }
803
786
  get decodedSize() {
804
- return this.e;
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.F = buffer_;
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.F);
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.F) === void 0) {
818
+ if (decodeVarint(this.G) === void 0) {
836
819
  return false;
837
820
  }
838
- if (!this.cb(0)) {
821
+ if (!this.bb(0)) {
839
822
  return false;
840
823
  }
841
824
  }
842
- return this.cb(0);
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
- cb(level) {
829
+ bb(level) {
847
830
  if (level > kMaxSubmetadataLevel) {
848
831
  return false;
849
832
  }
850
- const numEntries = decodeVarint(this.F);
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.Db();
856
- const dataSize = nameSkipped ? decodeVarint(this.F) : void 0;
857
- if (dataSize === void 0 || dataSize === 0 || !this.Eb(dataSize)) {
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.F);
862
- if (numSubMetadata === void 0 || numSubMetadata > this.F.remainingSize) {
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.Db() || !this.cb(level + 1)) {
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
- Db() {
874
- const nameLen = this.F.decodeUint8();
856
+ Bb() {
857
+ const nameLen = this.G.decodeUint8();
875
858
  if (nameLen === void 0) {
876
859
  return false;
877
860
  }
878
- return this.Eb(nameLen);
861
+ return this.Cb(nameLen);
879
862
  }
880
- Eb(size) {
881
- if (size > this.F.remainingSize) {
863
+ Cb(size) {
864
+ if (size > this.G.remainingSize) {
882
865
  return false;
883
866
  }
884
- this.F.advance(size);
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 ransRead() hot loop
963
- // touches own props; initialized by ansReadInit.
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
- ransRead() {
996
- const buf = this.buf;
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
- V = null;
1276
+ X = null;
1317
1277
  d = null;
1318
- w = [];
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.V = outPointCloud;
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.w.length <= attDecoderId) {
1372
- this.w.push(null);
1331
+ while (this.v.length <= attDecoderId) {
1332
+ this.v.push(null);
1373
1333
  }
1374
- this.w[attDecoderId] = decoder;
1334
+ this.v[attDecoderId] = decoder;
1375
1335
  return true;
1376
1336
  }
1377
1337
  getPortableAttribute(parentAttId) {
1378
- if (parentAttId < 0 || parentAttId >= this.V.numAttributes()) {
1338
+ if (parentAttId < 0 || parentAttId >= this.X.numAttributes()) {
1379
1339
  return null;
1380
1340
  }
1381
1341
  const parentAttDecoderId = this.Pa[parentAttId];
1382
- return this.w[parentAttDecoderId].getPortableAttribute(parentAttId);
1342
+ return this.v[parentAttDecoderId].getPortableAttribute(parentAttId);
1383
1343
  }
1384
1344
  attributesDecoder(decId) {
1385
- return this.w[decId];
1345
+ return this.v[decId];
1386
1346
  }
1387
1347
  numAttributesDecoders() {
1388
- return this.w.length;
1348
+ return this.v.length;
1389
1349
  }
1390
1350
  pointCloud() {
1391
- return this.V;
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.w.length; ++i) {
1418
- if (!this.w[i].init(this, this.V)) {
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.w[i].decodeAttributesDecoderData(this.d)) {
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.w[i].getNumAttributes();
1388
+ const numAttributes = this.v[i].getNumAttributes();
1429
1389
  for (let j = 0; j < numAttributes; ++j) {
1430
- const attId = this.w[i].getAttributeId(j);
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.w;
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
- G = null;
1422
+ H = null;
1463
1423
  // Returns an error message, or '' on success.
1464
1424
  decodeMesh(header, inBuffer, outMesh) {
1465
- this.G = outMesh;
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.G;
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 = new Uint8Array(0);
1492
- W = new Int32Array(0);
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
- B = new Uint8Array(0);
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
- H = null;
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
- I = new Int32Array(0);
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.H = table;
1473
+ this.I = table;
1514
1474
  this.sa = scratchUint8Zeroed(table.numVertices());
1515
- this.I = scratchInt32(numCorners);
1516
- this.I.set(table.oppositeCornerArray());
1517
- this.W = scratchInt32(numCorners);
1518
- this.W.set(table.cornerToVertexArray());
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 vertices.
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.H.cornerToVertexArray();
1524
- const opposite = this.I;
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
- let rem = c - (c / 3 | 0) * 3;
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.B = onBoundary;
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.H = table;
1552
- this.I = table.oppositeCornerArray();
1553
- this.W = table.cornerToVertexArray();
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.I[corner];
1518
+ return this.J[corner];
1561
1519
  }
1562
1520
  next(corner) {
1563
- return this.H.next(corner);
1521
+ return this.I.next(corner);
1564
1522
  }
1565
1523
  previous(corner) {
1566
- return this.H.previous(corner);
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.H.numFaces();
1536
+ return this.I.numFaces();
1579
1537
  }
1580
1538
  numCorners() {
1581
- return this.H.numCorners();
1539
+ return this.I.numCorners();
1582
1540
  }
1583
1541
  // --- Flat-array accessors: let DepthFirstTraverser avoid per-corner dispatch. ---
1584
1542
  cornerToVertexArray() {
1585
- return this.W;
1543
+ return this.Y;
1586
1544
  }
1587
1545
  // Seam-aware opposite corners (seam edges -> -1), matching opposite().
1588
1546
  oppositeCornerArray() {
1589
- return this.I;
1547
+ return this.J;
1590
1548
  }
1591
1549
  vertexOnBoundaryArray() {
1592
- return this.B;
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.H = other.H;
1556
+ this.I = other.I;
1599
1557
  this.sa = other.sa;
1600
- this.W = other.W;
1558
+ this.Y = other.Y;
1601
1559
  this.ta = other.ta;
1602
- this.B = other.B;
1603
- this.I = other.I;
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
- Fb = null;
1613
- V = null;
1570
+ Db = null;
1571
+ X = null;
1614
1572
  init(decoder, pointCloud) {
1615
- this.Fb = decoder;
1616
- this.V = pointCloud;
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.V;
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.Fb;
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
- n = null;
1679
- J = null;
1680
- Gb = -1;
1636
+ o = null;
1637
+ K = null;
1638
+ Eb = -1;
1681
1639
  // Decoded portable attribute (after lossless decoding).
1682
- ea = null;
1640
+ Z = null;
1683
1641
  init(decoder, attributeId) {
1684
- this.n = decoder;
1685
- this.J = decoder.pointCloud().attribute(attributeId);
1686
- this.Gb = attributeId;
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.J.numComponents <= 0) {
1655
+ if (this.K.numComponents <= 0) {
1698
1656
  return false;
1699
1657
  }
1700
- if (!this.Hb(pointIds.length)) {
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
- Hb(numValues) {
1709
- return this.J.reset(numValues);
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.J.isMappingIdentity && this.ea && this.ea.isMappingIdentity) {
1727
- const size = this.J.indicesMapSize;
1728
- this.ea.setExplicitMappingScratch(size);
1729
- const src = this.J.indicesMap;
1730
- const dst = this.ea.indicesMap;
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.ea;
1695
+ return this.Z;
1738
1696
  }
1739
1697
  get attribute() {
1740
- return this.J;
1698
+ return this.K;
1741
1699
  }
1742
1700
  get attributeId() {
1743
- return this.Gb;
1701
+ return this.Eb;
1744
1702
  }
1745
1703
  get decoder() {
1746
- return this.n;
1704
+ return this.o;
1747
1705
  }
1748
1706
  initPredictionScheme(ps) {
1749
1707
  for (let i = 0; i < ps.getNumParentAttributes(); i++) {
1750
- const attId = this.n.pointCloud().getNamedAttributeId(ps.getParentAttributeType(i));
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.n.getPortableAttribute(attId);
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.J.byteStride;
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.J.buffer.write(0, valueData, totalSize);
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
- Ib = 0;
1786
- K;
1743
+ Gb = 0;
1744
+ L;
1787
1745
  constructor(uniqueSymbolsBitLength) {
1788
1746
  const unclamped = Math.trunc(3 * uniqueSymbolsBitLength / 2);
1789
- this.K = new RAnsDecoder(unclamped < 12 ? 12 : unclamped > 20 ? 20 : unclamped);
1747
+ this.L = new RAnsDecoder(unclamped < 12 ? 12 : unclamped > 20 ? 20 : unclamped);
1790
1748
  }
1791
1749
  get numSymbols() {
1792
- return this.Ib;
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.Ib = numSymbols;
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.K.ransBuildLookUpTable(probabilityTable, numSymbols, expectedCount);
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.K, buffer.data, base + Number(bytesEncoded), base, this.K.lRansBase, 4);
1802
+ return ansReadInit(this.L, buffer.data, base + Number(bytesEncoded), base, this.L.lRansBase, 4);
1845
1803
  }
1846
1804
  endDecoding() {
1847
- this.K.readEnd();
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 tagAns = tagDecoder.K;
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.Ma;
1848
+ const buf = bd.Na;
1879
1849
  const byteLength = bd.qa;
1880
- let bitOffset = bd.s;
1850
+ let bitOffset = bd.q;
1881
1851
  let valueId = 0;
1882
1852
  for (let i = 0; i < numValues; i += numComponents) {
1883
- const bitLength = tagAns.ransRead();
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.s = bitOffset;
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.s;
1888
+ bitOffset = bd.q;
1908
1889
  } else {
1909
- bd.s = bitOffset;
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.s;
1898
+ bitOffset = bd.q;
1918
1899
  }
1919
1900
  }
1920
- bd.s = bitOffset;
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.K.decodeSymbols(outValues, numValues);
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
- f;
1981
+ e;
1999
1982
  constructor(transform) {
2000
- this.f = transform;
1983
+ this.e = transform;
2001
1984
  }
2002
1985
  /** True if all correction values are guaranteed to be positive. */
2003
1986
  areCorrectionsPositive() {
2004
- return this.f.areCorrectionsPositive();
1987
+ return this.e.areCorrectionsPositive();
2005
1988
  }
2006
1989
  boundsValues(limit) {
2007
- return this.f.boundsValues(limit);
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.f.decodeTransformData(buffer);
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.f.init(numComponents);
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.f.computeOriginalValue(predVals[0], 0, inCorr, 0, outData, 0);
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.f.computeOriginalValue(outData, srcOffset, inCorr, dstOffset, outData, dstOffset);
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.f.computeOriginalValue(multiPredVals, 0, inCorr, dstOffset, outData, dstOffset);
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
- P = -1;
2216
+ O = -1;
2234
2217
  fa = -1;
2235
- m = -1;
2218
+ n = -1;
2236
2219
  jc = 1;
2237
- h = -1;
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.P = q;
2224
+ this.O = q;
2242
2225
  this.fa = (1 << q) - 1;
2243
- this.m = this.fa - 1;
2244
- this.jc = Math.fround(2 / Math.fround(this.m));
2245
- this.h = this.m / 2 | 0;
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.P;
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.m || s === this.m && t === 0) {
2255
- s = this.m;
2256
- t = this.m;
2257
- } else if (s === 0 && t > this.h) {
2258
- t = this.h - (t - this.h);
2259
- } else if (s === this.m && t < this.h) {
2260
- t = this.h + (this.h - t);
2261
- } else if (t === this.m && s < this.h) {
2262
- s = this.h + (this.h - s);
2263
- } else if (t === 0 && s > this.h) {
2264
- s = this.h - (s - this.h);
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.h;
2275
- t = intVec[2] + this.h;
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.m - Math.abs(intVec[2]);
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.m - Math.abs(intVec[1]);
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.h;
2277
+ vec[0] = this.f;
2295
2278
  } else {
2296
- vec[0] = Math.trunc(vec[0] * this.h / absSum);
2297
- vec[1] = Math.trunc(vec[1] * this.h / absSum);
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.h - Math.abs(vec[0]) - Math.abs(vec[1]);
2282
+ vec[2] = this.f - Math.abs(vec[0]) - Math.abs(vec[1]);
2300
2283
  } else {
2301
- vec[2] = -(this.h - Math.abs(vec[0]) - Math.abs(vec[1]));
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, tempPos) {
2312
- const bufData = att.buffer && att.buffer.data;
2313
- if (att.dataType === 5 /* INT32 */ && att.numComponents === 3 && bufData) {
2314
- const src = new Int32Array(bufData.buffer);
2315
- const srcStart = bufData.byteOffset + att.byteOffset >> 2;
2316
- const stride = att.byteStride >> 2;
2317
- const isIdentity = att.isMappingIdentity;
2318
- const indicesMap = att.indicesMap;
2319
- if (isIdentity) {
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
- for (let d = 0; d < numEntries; ++d) {
2338
- att.convertValue(att.mappedIndex(map[d]), tempPos);
2339
- const o = d * 3;
2340
- cache[o] = tempPos[0];
2341
- cache[o + 1] = tempPos[1];
2342
- cache[o + 2] = tempPos[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
- db = new Array(3);
2351
- za = null;
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
- buildPositionCache(numEntries) {
2366
- const posCache = scratchInt32(numEntries * 3);
2367
- fillInt32PositionCache(posCache, this.xa, this.ya, numEntries, this.db);
2368
- this.za = posCache;
2369
- const table = this.c.cornerTable;
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 nc = cornerToVertex.length;
2374
- const c2o = scratchInt32(nc);
2375
- for (let c = 0; c < nc; ++c) {
2376
- const v = cornerToVertex[c];
2377
- c2o[c] = v < 0 ? -1 : vertexToDataMap[v] * 3;
2378
- }
2379
- this.Jb = c2o;
2380
- }
2381
- computePredictedValue(cornerId, prediction) {
2382
- const oppositeCorners = this.q;
2383
- const cornerToOffset = this.Jb;
2384
- const posCache = this.za;
2385
- const centerOffset = cornerToOffset[cornerId];
2386
- const centX = posCache[centerOffset];
2387
- const centY = posCache[centerOffset + 1];
2388
- const centZ = posCache[centerOffset + 2];
2389
- let normalX = 0, normalY = 0, normalZ = 0;
2390
- let currentCorner = cornerId;
2391
- let leftTraversal = true;
2392
- while (currentCorner >= 0) {
2393
- const rem = currentCorner - (currentCorner / 3 | 0) * 3;
2394
- const cNext = rem === 2 ? currentCorner - 2 : currentCorner + 1;
2395
- const cPrev = rem === 0 ? currentCorner + 2 : currentCorner - 1;
2396
- let posOffset = cornerToOffset[cNext];
2397
- const nextX = posCache[posOffset];
2398
- const nextY = posCache[posOffset + 1];
2399
- const nextZ = posCache[posOffset + 2];
2400
- posOffset = cornerToOffset[cPrev];
2401
- const prevX = posCache[posOffset];
2402
- const prevY = posCache[posOffset + 1];
2403
- const prevZ = posCache[posOffset + 2];
2404
- const dNextX = nextX - centX;
2405
- const dNextY = nextY - centY;
2406
- const dNextZ = nextZ - centZ;
2407
- const dPrevX = prevX - centX;
2408
- const dPrevY = prevY - centY;
2409
- const dPrevZ = prevZ - centZ;
2410
- normalX += dNextY * dPrevZ - dNextZ * dPrevY;
2411
- normalY += dNextZ * dPrevX - dNextX * dPrevZ;
2412
- normalZ += dNextX * dPrevY - dNextY * dPrevX;
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
- t;
2391
+ s;
2462
2392
  z = new OctahedronToolBox();
2463
- eb = new RAnsBitDecoder();
2393
+ cb = new RAnsBitDecoder();
2464
2394
  constructor(transform, meshData) {
2465
2395
  super(transform, meshData);
2466
- this.t = new MeshPredictionSchemeGeometricNormalPredictorArea(meshData);
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.t.setPositionAttribute(att);
2407
+ this.s.setPositionAttribute(att);
2478
2408
  return true;
2479
2409
  }
2480
2410
  decodePredictionData(buffer) {
2481
- if (!this.f.decodeTransformData(buffer)) return false;
2482
- return this.eb.startDecoding(buffer);
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.f.quantizationBits());
2486
- this.t.setEntryToPointIdMap(entryToPointIdMap);
2415
+ this.z.setQuantizationBits(this.e.quantizationBits());
2416
+ this.s.setEntryToPointIdMap(entryToPointIdMap);
2487
2417
  const cornerMapSize = this.c.dataToCornerMap.length;
2488
- this.t.buildPositionCache(cornerMapSize);
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
- const cornerId = this.c.dataToCornerMap[dataId];
2493
- this.t.computePredictedValue(cornerId, predNormal3D);
2422
+ this.s.computePredictedValue(dataId, predNormal3D);
2494
2423
  this.z.canonicalizeIntegerVector(predNormal3D);
2495
- if (this.eb.decodeNextBit()) {
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.f.computeOriginalValue(predNormalOct, 0, inCorr, dataOffset, outData, dataOffset);
2431
+ this.e.computeOriginalValue(predNormalOct, 0, inCorr, dataOffset, outData, dataOffset);
2503
2432
  }
2504
- this.eb.endDecoding();
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.f.init(numComponents);
2442
+ this.e.init(numComponents);
2514
2443
  const predVals = new Int32Array(numComponents);
2515
2444
  const parallelogramPredVals = new Int32Array(numComponents);
2516
- this.f.computeOriginalValue(predVals, 0, inCorr, 0, outData, 0);
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.f.computeOriginalValue(outData, srcOffset, inCorr, dstOffset, outData, dstOffset);
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.f.computeOriginalValue(predVals, 0, inCorr, dstOffset, outData, dstOffset);
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.f.init(numComponents);
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.f;
2591
- const minValue = transform.X;
2592
- const maxValue = transform.m;
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.f;
2659
- const minValue = transform.X;
2660
- const maxValue = transform.m;
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.f;
2737
- const minValue = transform.X;
2738
- const maxValue = transform.m;
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.f;
2846
- const minValue = transform.X;
2847
- const maxValue = transform.m;
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
- u = new Int32Array(2);
2954
- Sa = new Uint8Array(0);
2955
- Aa = 0;
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
- za = null;
2960
- j = null;
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.u;
2899
+ return this.t;
2972
2900
  }
2973
2901
  resizeOrientations(numOrientations) {
2974
2902
  this.Sa = new Uint8Array(numOrientations);
2975
- this.Aa = numOrientations;
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, this.db);
2983
- this.za = posCache;
2984
- this.j = this.c.cornerTable.cornerToVertexArray();
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.j;
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.u[0] = pUV0;
3003
- this.u[1] = pUV1;
2930
+ this.t[0] = pUV0;
2931
+ this.t[1] = pUV1;
3004
2932
  return true;
3005
2933
  }
3006
- const posCache = this.za;
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 > SAFE_PRODUCT / pnNorm2Squared || nUVAbsMax > SAFE_PRODUCT / pnNorm2Squared || pnUVAbsMax > 0 && cnDotPnAbs > SAFE_PRODUCT / pnUVAbsMax || pnAbsMaxG > 0 && cnDotPnAbs > SAFE_PRODUCT / pnAbsMaxG) {
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.Aa === 0) {
2993
+ if (this.za === 0) {
3076
2994
  return false;
3077
2995
  }
3078
- const orientation = this.Sa[--this.Aa];
2996
+ const orientation = this.Sa[--this.za];
3079
2997
  if (orientation) {
3080
- this.u[0] = Math.trunc((xUV0 + cxUV0) / pnNorm2Squared);
3081
- this.u[1] = Math.trunc((xUV1 + cxUV1) / pnNorm2Squared);
2998
+ this.t[0] = Math.trunc((xUV0 + cxUV0) / pnNorm2Squared);
2999
+ this.t[1] = Math.trunc((xUV1 + cxUV1) / pnNorm2Squared);
3082
3000
  } else {
3083
- this.u[0] = Math.trunc((xUV0 - cxUV0) / pnNorm2Squared);
3084
- this.u[1] = Math.trunc((xUV1 - cxUV1) / pnNorm2Squared);
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.u[0] = 0;
3100
- this.u[1] = 0;
3017
+ this.t[0] = 0;
3018
+ this.t[1] = 0;
3101
3019
  return true;
3102
3020
  }
3103
3021
  }
3104
- this.u[0] = data[dataOffset];
3105
- this.u[1] = data[dataOffset + 1];
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.Aa === 0) return false;
3148
- const orientation = this.Sa[--this.Aa];
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.u[0] = Number(B.asIntN(32, B.asIntN(64, s0) / pnN2));
3158
- this.u[1] = Number(B.asIntN(32, B.asIntN(64, s1) / pnN2));
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
- t;
3084
+ s;
3167
3085
  constructor(transform, meshData) {
3168
3086
  super(transform, meshData);
3169
- this.t = new MeshPredictionSchemeTexCoordsPortablePredictor(meshData);
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.t.setPositionAttribute(att);
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.t.resizeOrientations(numOrientations);
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.t.setOrientation(i, lastOrientation);
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.t.setEntryToPointIdMap(entryToPointIdMap);
3204
- this.f.init(numComponents);
3121
+ this.s.setEntryToPointIdMap(entryToPointIdMap);
3122
+ this.e.init(numComponents);
3205
3123
  const cornerMapSize = this.c.dataToCornerMap.length;
3206
- this.t.buildPositionCache(cornerMapSize);
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.t.computePredictedValue(cornerId, outData, p)) {
3127
+ if (!this.s.computePredictedValue(cornerId, outData, p)) {
3210
3128
  return false;
3211
3129
  }
3212
3130
  const dstOffset = p * numComponents;
3213
- this.f.computeOriginalValue(this.t.predictedValue, 0, inCorr, dstOffset, outData, dstOffset);
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.f;
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
- X = 0;
3279
- m = 0;
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.m < limit && this.X > -limit;
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.X;
3296
- const maxValue = this.m;
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.X = minValue;
3322
- this.m = maxValue;
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
- Q = null;
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
- fb = 0;
3336
- Kb = null;
3337
- // Int32 view over the portable attribute's storage (see preparePortableAttribute).
3338
- Y = null;
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.Y;
3264
+ const portableData = this.Q;
3345
3265
  return {
3346
- ans: this.ha.K,
3347
- out: new Uint32Array(portableData.buffer, portableData.byteOffset, this.fb),
3348
- count: this.fb
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.Kb);
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.Kb = pointIds;
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.Q = this.createIntPredictionScheme(predictionSchemeMethod, predictionTransformType);
3296
+ this.P = this.createIntPredictionScheme(predictionSchemeMethod, predictionTransformType);
3377
3297
  }
3378
- if (this.Q) {
3379
- if (!this.initPredictionScheme(this.Q)) {
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.Y;
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.fb = numValues;
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.Q) {
3430
- if (!this.Q.decodePredictionData(buffer)) {
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.Y;
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.Q;
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.gb(pointIds.length);
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.Q !== null && this.Q.boundsValues(16777216);
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
- Hb(numValues) {
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
- gb(_numValues) {
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.Y);
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
- const ga = new GeometryAttribute();
3501
- ga.init(
3502
- this.attribute.attributeType,
3503
- null,
3504
- numComponents,
3505
- 5 /* INT32 */,
3506
- false,
3507
- numComponents * dataTypeLength(5 /* INT32 */),
3508
- 0
3509
- );
3510
- const portAtt = new PointAttribute(ga);
3511
- portAtt.setIdentityMapping();
3512
- portAtt.reset(numEntries);
3513
- portAtt.uniqueId = this.attribute.uniqueId;
3514
- this.ea = portAtt;
3515
- const data = portAtt.buffer.data;
3516
- this.Y = numEntries === 0 ? null : new Int32Array(data.buffer, data.byteOffset + portAtt.byteOffset, numEntries * numComponents);
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.h;
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.h;
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.h;
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
- P = -1;
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.P = qBits;
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
- gb(_numPoints) {
3932
- const q = this.P;
3867
+ eb(_numPoints) {
3868
+ const q = this.O;
3933
3869
  if (q < 2 || q > 30) return false;
3934
3870
  this.attribute.setLazyOctahedron(
3935
- this.Y,
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
- P = -1;
3953
- hb = [];
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.hb = new Array(numComponents);
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.hb[i] = val;
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.P = qBits;
3911
+ this.O = qBits;
3976
3912
  return true;
3977
3913
  }
3978
3914
  // Dequantization is deferred to extractTo (see PointAttribute.setLazyQuantized).
3979
- gb(_numValues) {
3980
- const maxQuantizedValue = (1 << this.P >>> 0) - 1;
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.Y, this.hb, delta, this.Lb());
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
- Ba = [];
3926
+ ia = [];
3991
3927
  // Replaced by the sequencer's output in _prepareSequence.
3992
- Ta = new Int32Array(0);
3993
- Z;
3928
+ Ta = EMPTY_INT32;
3929
+ $;
3994
3930
  constructor(sequencer) {
3995
3931
  super();
3996
- this.Z = sequencer;
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.Ba[i] = decoder;
3946
+ this.ia[i] = decoder;
4011
3947
  }
4012
3948
  return true;
4013
3949
  }
4014
- qc() {
4015
- if (!this.Z.generateSequence()) {
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.Z.getOutputPointIds();
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.Z.updatePointToAttributeIndexMapping(pa)) {
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.Ba;
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.Ba;
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.Ba;
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.Ba[locId].getPortableAttribute();
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
- Ca = null;
4120
- _ = null;
4057
+ Aa = null;
4058
+ Ba = null;
4121
4059
  Ob = [];
4122
- ia = 0;
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 traverseFromCorner).
4065
+ // the traversal (see traverseAll).
4128
4066
  emitsPointIds = false;
4129
- j = null;
4130
- q = null;
4131
- B = null;
4132
- L = 0;
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.Ca = observer;
4136
- this.j = cornerTable.cornerToVertexArray();
4137
- this.q = cornerTable.oppositeCornerArray();
4138
- this.B = cornerTable.vertexOnBoundaryArray();
4139
- this.L = cornerTable.numCorners();
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 (traverseFromCorner).
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._ = scratchUint8Zeroed(cornerTable.numFaces());
4154
- this.Ob = scratchInt32(this.L);
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. The visited check lives here rather than behind a
4158
- // traverseFromCorner call per face: on a connected mesh nearly every face is
4159
- // already visited by the time its seed comes up, and that call-and-return
4160
- // was measurable next to the traversal itself.
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
- for (let f = 0; f < numFaces && this.ia < numFaces; ++f) {
4165
- if (isFaceVisited[f] === 0 && !this.traverseFromCorner(3 * f)) {
4166
- return false;
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.ia;
4115
+ let numVisitedFaces = this.Ca;
4182
4116
  const encodingData = observer.p;
4183
- const encodedToCornerMap = observer.ib;
4184
- const vertexToEncodedMap = observer.jb;
4117
+ const encodedToCornerMap = observer.gb;
4118
+ const vertexToEncodedMap = observer.hb;
4119
+ const parents = this.Qb;
4185
4120
  let numValues = encodingData.numValues;
4186
- let stackSize = 0;
4187
- stack[stackSize++] = cornerId;
4188
- const nextCorner = cornerId % 3 === 2 ? cornerId - 2 : cornerId + 1;
4189
- const prevCorner = cornerId % 3 === 0 ? cornerId + 2 : cornerId - 1;
4190
- const nextVert = cornerToVertex[nextCorner];
4191
- const prevVert = cornerToVertex[prevCorner];
4192
- if (nextVert === kInvalidVertexIndex || prevVert === kInvalidVertexIndex) {
4193
- return false;
4194
- }
4195
- if (vertexToEncodedMap[nextVert] < 0) {
4196
- encodedToCornerMap[numValues] = nextCorner;
4197
- vertexToEncodedMap[nextVert] = numValues++;
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
- while (true) {
4211
- isFaceVisited[faceId] = 1;
4212
- numVisitedFaces++;
4213
- const vertId = cornerToVertex[cornerId];
4214
- if (vertId === kInvalidVertexIndex) {
4215
- encodingData.numValues = numValues;
4216
- return false;
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
- const faceBase = faceId * 3;
4219
- const nextCornerId = cornerId === faceBase + 2 ? faceBase : cornerId + 1;
4220
- if (vertexToEncodedMap[vertId] < 0) {
4221
- encodedToCornerMap[numValues] = cornerId;
4222
- vertexToEncodedMap[vertId] = numValues++;
4223
- if (vertexOnBoundary[vertId] === 0) {
4224
- cornerId = oppositeCorners[nextCornerId];
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
- const rightCornerId = oppositeCorners[nextCornerId];
4230
- const prevCornerId = cornerId === faceBase ? faceBase + 2 : cornerId - 1;
4231
- const leftCornerId = oppositeCorners[prevCornerId];
4232
- const rightFaceId = rightCornerId === kInvalidCornerIndex4 ? kInvalidFaceIndex : rightCornerId / 3 | 0;
4233
- const leftFaceId = leftCornerId === kInvalidCornerIndex4 ? kInvalidFaceIndex : leftCornerId / 3 | 0;
4234
- const isRightVisited = rightFaceId === kInvalidFaceIndex || isFaceVisited[rightFaceId];
4235
- const isLeftVisited = leftFaceId === kInvalidFaceIndex || isFaceVisited[leftFaceId];
4236
- if (isRightVisited) {
4237
- if (isLeftVisited) {
4238
- stackSize--;
4239
- break;
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
- } else {
4245
- if (isLeftVisited) {
4246
- cornerId = rightCornerId;
4247
- faceId = rightFaceId;
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
- stack[stackSize - 1] = leftCornerId;
4250
- stack[stackSize++] = rightCornerId;
4251
- break;
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.ia = numVisitedFaces;
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
- Ca = null;
4269
- _ = null;
4270
- kb = null;
4271
- ia = 0;
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
- $ = 0;
4239
+ aa = 0;
4275
4240
  // Prediction degree accumulated per vertex during traversal.
4276
- lb = null;
4241
+ jb = null;
4277
4242
  // Flat connectivity arrays (see DepthFirstTraverser for why).
4278
- j = null;
4279
- q = null;
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.Ca = observer;
4288
- this._ = new Uint8Array(cornerTable.numFaces());
4289
- this.kb = new Uint8Array(cornerTable.numVertices());
4290
- this.j = cornerTable.cornerToVertexArray();
4291
- this.q = cornerTable.oppositeCornerArray();
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
- Qb(c) {
4263
+ Rb(c) {
4299
4264
  return c % 3 === 2 ? c - 2 : c + 1;
4300
4265
  }
4301
- Rb(c) {
4266
+ Sb(c) {
4302
4267
  return c % 3 === 0 ? c + 2 : c - 1;
4303
4268
  }
4304
4269
  onTraversalStart() {
4305
- this.lb = new Int32Array(this.a.numVertices());
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.ia < numFaces; ++f) {
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
- Sb(cornerId) {
4322
- const vTip = this.j[cornerId];
4286
+ Tb(cornerId) {
4287
+ const vTip = this.k[cornerId];
4323
4288
  let priority = 0;
4324
- if (!this.kb[vTip]) {
4325
- const degree = ++this.lb[vTip];
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
- Tb(ci, priority) {
4298
+ Ub(ci, priority) {
4334
4299
  this.Ua[priority].push(ci);
4335
- if (priority < this.$) {
4336
- this.$ = priority;
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.$; i < kMaxPriority; ++i) {
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.$ = i;
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.lb.length === 0) {
4318
+ if (this.jb.length === 0) {
4354
4319
  return true;
4355
4320
  }
4356
- const cornerToVertex = this.j;
4357
- const oppositeCorners = this.q;
4358
- const isFaceVisited = this._;
4359
- const isVertexVisited = this.kb;
4360
- const observer = this.Ca;
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.$ = 0;
4363
- const firstNext = this.Qb(cornerId);
4364
- const firstPrev = this.Rb(cornerId);
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.ia++;
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.Qb(cornerId)];
4395
- const leftCornerId = oppositeCorners[this.Rb(cornerId)];
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.Sb(leftCornerId);
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.Tb(leftCornerId, priority);
4371
+ this.Ub(leftCornerId, priority);
4407
4372
  }
4408
4373
  }
4409
4374
  if (!isRightFaceVisited) {
4410
- const priority = this.Sb(rightCornerId);
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.Tb(rightCornerId, priority);
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
- Z;
4429
- jb;
4430
- ib;
4431
- Ub;
4393
+ $;
4394
+ hb;
4395
+ gb;
4396
+ Vb;
4432
4397
  constructor(mesh, sequencer, encodingData) {
4433
4398
  this.p = encodingData;
4434
- this.Z = sequencer;
4435
- this.jb = encodingData.vertexToEncodedAttributeValueIndexMap;
4436
- this.ib = encodingData.encodedAttributeValueIndexToCornerMap;
4437
- this.Ub = mesh.faces_;
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.Ub[corner];
4441
- this.Z.addPointId(pointId);
4405
+ const pointId = this.Vb[corner];
4406
+ this.$.addPointId(pointId);
4442
4407
  const numValues = this.p.numValues;
4443
- this.ib[numValues] = corner;
4444
- this.jb[vertex] = numValues;
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
- G;
4416
+ H;
4452
4417
  p;
4453
- Da = null;
4454
- x = new Int32Array(0);
4455
- Ea = 0;
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
- mb;
4423
+ kb;
4459
4424
  // The cache entry the last generateSequence resolved to (hit or store);
4460
4425
  // carries the shared indicesMap.
4461
- nb = null;
4426
+ lb = null;
4462
4427
  // One representative corner per point id, when the connectivity decoder
4463
4428
  // recorded them (see MeshEdgebreakerDecoderImpl._assignAttributeVerticesAndPoints).
4464
- ja;
4465
- constructor(mesh, encodingData, traversalCache, pointCorner) {
4466
- this.G = mesh;
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.mb = traversalCache;
4469
- this.ja = pointCorner;
4435
+ this.kb = traversalCache;
4436
+ this.ba = pointCorner;
4437
+ this.Ea = pointVertexTable;
4470
4438
  }
4471
4439
  setTraverser(traverser) {
4472
- this.Da = traverser;
4473
- }
4474
- generateSequence() {
4475
- const cornerTable = this.Da.cornerTable();
4476
- const methodId = this.Da.Pb;
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.mb.get(cacheKey);
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.nb = cached;
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.mb.set(cacheKey, byMethod);
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: null
4484
+ parents
4508
4485
  };
4509
4486
  byMethod.set(methodId, entry);
4510
4487
  encodingData.cacheEntry = entry;
4511
- this.nb = entry;
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.Ea++] = pointId;
4495
+ this.x[this.Da++] = pointId;
4519
4496
  }
4520
4497
  updatePointToAttributeIndexMapping(attribute) {
4521
- const entry = this.nb;
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.Da.cornerTable();
4527
- const numFaces = this.G.numFaces();
4528
- const numPoints = this.G.numPoints();
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.ja;
4534
- if (pointCorner !== null) {
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.G.faces_;
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.Ea = 0;
4569
- this.x = scratchInt32(this.G.numPoints());
4570
- const traverser = this.Da;
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.G.faces_;
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.Ea = numValues;
4568
+ this.Da = numValues;
4584
4569
  }
4585
- if (this.Ea < this.x.length) {
4586
- this.x = this.x.subarray(0, this.Ea);
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
- n;
4580
+ o;
4596
4581
  a = null;
4597
4582
  R = [];
4598
- ka = new Uint8Array(0);
4599
- aa = 0;
4600
- ob = new MeshAttributeIndicesEncodingData();
4601
- Vb = -1;
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
- i = [];
4606
- M;
4590
+ j = [];
4591
+ N;
4607
4592
  // One corner per point id (decode-scoped scratch), filled by
4608
- // _assignAttributeVerticesAndPoints; null when points are the base vertices.
4609
- ja = null;
4610
- // Corners on a boundary edge, counted by _decodeAttributeConnectivities.
4611
- Wb = 0;
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.n = decoder;
4614
- this.M = new TraversalDecoderClass();
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.i.length; ++i) {
4622
- const ad = this.i[i];
4623
- if (ad.decoderId < 0 || ad.decoderId >= this.n.numAttributesDecoders()) {
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.n.attributesDecoder(ad.decoderId);
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.ob;
4628
+ return ad !== null ? ad.encodingData : this.mb;
4642
4629
  }
4643
4630
  createAttributesDecoder(attDecoderId) {
4644
- const buffer = this.n.buffer();
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.i.length) {
4638
+ if (attDataId >= this.j.length) {
4652
4639
  return false;
4653
4640
  }
4654
- if (this.i[attDataId].decoderId >= 0) {
4641
+ if (this.j[attDataId].decoderId >= 0) {
4655
4642
  return false;
4656
4643
  }
4657
- this.i[attDataId].decoderId = attDecoderId;
4644
+ this.j[attDataId].decoderId = attDecoderId;
4658
4645
  } else {
4659
- if (this.Vb >= 0) {
4646
+ if (this.Wb >= 0) {
4660
4647
  return false;
4661
4648
  }
4662
- this.Vb = attDecoderId;
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.ob;
4659
+ encodingData = this.mb;
4673
4660
  } else {
4674
- encodingData = this.i[attDataId].encodingData;
4675
- this.i[attDataId].isConnectivityUsed = false;
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.i[attDataId];
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.n.mesh();
4688
- const sequencer = new MeshTraversalSequencer(mesh, encodingData, this.tc, this.ja);
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.n.setAttributesDecoder(attDecoderId, new SequentialAttributeDecodersController(sequencer));
4686
+ return this.o.setAttributesDecoder(attDecoderId, new SequentialAttributeDecodersController(sequencer));
4694
4687
  }
4695
4688
  decodeConnectivity() {
4696
- const buffer = this.n.buffer();
4689
+ const buffer = this.o.buffer();
4697
4690
  const numEncodedVertices = decodeVarint(buffer);
4698
4691
  if (numEncodedVertices === void 0) return false;
4699
- this.aa = numEncodedVertices;
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.aa > numFaces * 3) {
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.aa * (this.aa - 1) / 2;
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.i.push(ad);
4727
+ this.j.push(ad);
4735
4728
  }
4736
- this.a.reset(numFaces, this.aa + numEncodedSplitSymbols);
4737
- this.ka = scratchUint8Filled(this.aa + numEncodedSplitSymbols, 1);
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.M.init(this);
4742
- this.M.setNumEncodedVertices(this.aa + numEncodedSplitSymbols);
4743
- this.M.setNumAttributeData(numAttributeData);
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.M.start(traversalEndBuffer)) {
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.init(traversalEndBuffer.dataHead, traversalEndBuffer.remainingSize);
4745
+ buffer.initFrom(traversalEndBuffer);
4753
4746
  this.a.finishBoundaries();
4754
- if (this.i.length > 0) {
4747
+ if (this.j.length > 0) {
4755
4748
  this.xc();
4756
4749
  }
4757
- this.M.done();
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.i.length; ++i) {
4766
- const connectivityData = this.i[i].connectivityData;
4767
- const seamCorners = this.i[i].attributeSeamCorners;
4768
- const seamCount = this.i[i].numSeamCorners;
4769
- if (seamCount === numBoundaryCorners) {
4770
- this.i[i].noInteriorSeams = true;
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.i.length === 0) {
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.ob.init(this.a.numVertices());
4806
- for (let i = 0; i < this.i.length; ++i) {
4807
- let attConnectivityVerts = this.i[i].connectivityData.numVertices();
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.i[i].encodingData.init(attConnectivityVerts);
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.i.length === 0;
4830
+ const removeInvalidVertices = this.j.length === 0;
4839
4831
  let maxNumVertices = this.ka.length;
4840
4832
  let numFacesDecoded = 0;
4841
- const cornerToVertex = this.a.j;
4842
- const oppositeCorners = this.a.q;
4833
+ const cornerToVertex = this.a.k;
4834
+ const oppositeCorners = this.a.w;
4843
4835
  const vc = this.a;
4844
- let vertexCorners = vc.v;
4836
+ let vertexCorners = vc.u;
4845
4837
  const isVertHole = this.ka;
4846
- const traversalDecoder = this.M;
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.k < vertexCorners.length) {
4899
- newVertIndex = vc.k++;
4890
+ if (vc.l < vertexCorners.length) {
4891
+ newVertIndex = vc.l++;
4900
4892
  } else {
4901
4893
  newVertIndex = vc.addNewVertex();
4902
- vertexCorners = vc.v;
4894
+ vertexCorners = vc.u;
4903
4895
  }
4904
- if (vc.k > maxNumVertices) return -1;
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.k + 3 <= vertexCorners.length) {
4966
- firstVertIndex = vc.k;
4967
- vc.k += 3;
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.v;
4964
+ vertexCorners = vc.u;
4973
4965
  }
4974
- if (vc.k > maxNumVertices) return -1;
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.k > maxNumVertices) {
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.q;
5020
- const cornerToVertex = ct.j;
5021
- const vertexCorners = ct.v;
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.M;
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.j;
5074
- const vertexCorners = ct.v;
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; the
5157
- // invalid-corner case (-1) is still handled by the branch above it.
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.i;
5152
+ const attributeData = this.j;
5161
5153
  const numAttrData = attributeData.length;
5162
- const connectivityDecoders = this.M.Yb;
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
- let opp = oppositeCorners[corner];
5169
- candidates[numCandidates] = corner ^ opp >> 31;
5170
- numCandidates -= (opp | corner - opp - 1) >> 31;
5171
- numBoundaryCorners -= opp >> 31;
5172
- opp = oppositeCorners[corner + 1];
5173
- candidates[numCandidates] = corner + 1 ^ opp >> 31;
5174
- numCandidates -= (opp | corner - opp - 1) >> 31;
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.n.mesh();
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.ja = null;
5209
- this.n.pointCloud().setNumPoints(numConnectivityVerts);
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.n.mesh();
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].W;
5269
- attOpposite[t] = tables[t].I;
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 ring = scratchInt32(numCorners);
5277
- const ringNext = scratchInt32(numCorners);
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(numCorners);
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.ja = pointCorner;
5402
- this.n.pointCloud().setNumPoints(numPoints);
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] = cc;
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 = new Int32Array(0);
5490
- encodedAttributeValueIndexToCornerMap = new Int32Array(0);
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 = new Int32Array(0);
5507
+ attributeSeamCorners = EMPTY_INT32;
5517
5508
  numSeamCorners = 0;
5518
- // Set when every seam is a boundary edge and connectivityData was therefore
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
- L = 0;
5525
- k = 0;
5526
- j = null;
5515
+ M = 0;
5516
+ l = 0;
5517
+ k = null;
5527
5518
  // corner -> vertex
5528
- q = null;
5519
+ w = null;
5529
5520
  // corner -> opposite corner
5530
- v = null;
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
- B = null;
5527
+ C = null;
5537
5528
  reset(numFaces, numVertices) {
5538
5529
  this.Zb = numFaces;
5539
- this.L = numFaces * 3;
5540
- this.k = 0;
5541
- this.j = scratchInt32Filled(this.L, -1);
5542
- this.q = scratchInt32Filled(this.L, -1);
5543
- this.v = scratchInt32Filled(numVertices, -1);
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.L;
5540
+ return this.M;
5550
5541
  }
5551
5542
  numVertices() {
5552
- return this.k;
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.L) return -1;
5566
- return this.j[corner];
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.L) return -1;
5570
- return this.q[corner];
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.j;
5565
+ return this.k;
5575
5566
  }
5576
5567
  oppositeCornerArray() {
5577
- return this.q;
5568
+ return this.w;
5578
5569
  }
5579
5570
  vertexLeftmostCornerArray() {
5580
- return this.v;
5571
+ return this.u;
5581
5572
  }
5582
5573
  vertexOnBoundaryArray() {
5583
- return this.B;
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.k;
5589
- const vertexCorners = this.v;
5590
- const oppositeCorners = this.q;
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.B = onBoundary;
5587
+ this.C = onBoundary;
5597
5588
  }
5598
5589
  // Mirrors C++ CornerTable::AddNewVertex() (push_back(kInvalidCornerIndex)).
5599
5590
  addNewVertex() {
5600
- const newVertex = this.k;
5601
- this.k++;
5602
- if (newVertex >= this.v.length) {
5603
- const newCapacity = Math.max(newVertex + 1, this.v.length * 2, 64);
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.v);
5606
- this.v = newArr;
5596
+ newArr.set(this.u);
5597
+ this.u = newArr;
5607
5598
  }
5608
- this.v[newVertex] = -1;
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
- N = new DecoderBuffer();
5631
- pb = null;
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.n.buffer();
5640
- this.d.init(srcBuffer.dataHead, srcBuffer.remainingSize);
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.init(this.d.dataHead, this.d.remainingSize);
5650
+ outBuffer.initFrom(this.d);
5660
5651
  return true;
5661
5652
  }
5662
5653
  decodeStartFaceConfiguration() {
5663
- return this.pb.decodeNextBit();
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.Ma;
5669
- const off = bd.s;
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.s = off + 1;
5665
+ bd.q = off + 1;
5675
5666
  return TOPOLOGY_C;
5676
5667
  }
5677
- bd.s = off + 3;
5668
+ bd.q = off + 3;
5678
5669
  return bits;
5679
5670
  }
5680
5671
  }
5681
- let symbol = this.N.decodeLeastSignificantBits32(1);
5672
+ let symbol = this.S.decodeLeastSignificantBits32(1);
5682
5673
  if (symbol === TOPOLOGY_C) {
5683
5674
  return symbol;
5684
5675
  }
5685
- const symbolSuffix = this.N.decodeLeastSignificantBits32(2);
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.N.bitDecoderActive) {
5695
- this.N.endBitDecoding();
5685
+ if (this.S.bitDecoderActive) {
5686
+ this.S.endBitDecoding();
5696
5687
  }
5697
5688
  }
5698
5689
  decodeTraversalSymbols() {
5699
- this.N.init(this.d.dataHead, this.d.remainingSize);
5700
- const traversalSize = this.N.startBitDecoding(true);
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.N.ra;
5705
- this.d.init(this.N.dataHead, this.N.remainingSize);
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.pb = new RAnsBitDecoder();
5715
- return this.pb.startDecoding(this.d);
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
- k = 0;
5726
+ l = 0;
5736
5727
  A = -1;
5737
5728
  la = -1;
5738
- l = [];
5739
- qb = null;
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.k = numVertices;
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.k) {
5746
+ if (numSplitSymbols >= this.l) {
5756
5747
  return false;
5757
5748
  }
5758
- this.l = new Array(this.k).fill(0);
5759
- this.qb = new RAnsBitDecoder();
5760
- return this.qb.startDecoding(outBuffer);
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.qb.decodeNextBit()) {
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.l[ct.vertex(next)] += 1;
5780
- this.l[ct.vertex(prev)] += 1;
5770
+ this.m[ct.vertex(next)] += 1;
5771
+ this.m[ct.vertex(prev)] += 1;
5781
5772
  break;
5782
5773
  case TOPOLOGY_R:
5783
- this.l[ct.vertex(corner)] += 1;
5784
- this.l[ct.vertex(next)] += 1;
5785
- this.l[ct.vertex(prev)] += 2;
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.l[ct.vertex(corner)] += 1;
5789
- this.l[ct.vertex(next)] += 2;
5790
- this.l[ct.vertex(prev)] += 1;
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.l[ct.vertex(corner)] += 2;
5794
- this.l[ct.vertex(next)] += 2;
5795
- this.l[ct.vertex(prev)] += 2;
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.l[pivot] < 6) {
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.l[dest] += this.l[source];
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
- k = 0;
5810
+ l = 0;
5820
5811
  A = -1;
5821
5812
  Va = -1;
5822
5813
  Wa = 2;
5823
- rb = 7;
5824
- l = new Int32Array(0);
5814
+ pb = 7;
5815
+ m = EMPTY_INT32;
5825
5816
  ma = [];
5826
5817
  // Int32Array, not number[]: read and written once per decoded symbol.
5827
- Fa = new Int32Array(0);
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
- j = new Int32Array(0);
5823
+ k = EMPTY_INT32;
5833
5824
  init(decoder) {
5834
5825
  super.init(decoder);
5835
5826
  this.a = decoder.getCornerTable();
5836
- this.j = this.a.j;
5827
+ this.k = this.a.k;
5837
5828
  }
5838
5829
  setNumEncodedVertices(numVertices) {
5839
- this.k = numVertices;
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.init(this.d.dataHead, this.d.remainingSize);
5849
- this.l = scratchInt32Filled(this.k, 0);
5850
- const numUniqueValences = this.rb - this.Wa + 1;
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.K, out: this.ma[i], count: numSymbols });
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.j;
5920
- const valences = this.l;
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.rb) {
5954
- clampedValence = this.rb;
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.l[dest] += this.l[source];
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
- sb = null;
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
- tb = false;
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.sb = null;
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.tb = true;
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.tb;
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.sb ??= import("./pool.js").then(
6308
+ this.qb ??= import("./pool.js").then(
6318
6309
  (module) => this.pa = new module.WorkerPool(this.workerLimit, this.Ga),
6319
6310
  () => {
6320
- this.tb = true;
6311
+ this.rb = true;
6321
6312
  return null;
6322
6313
  }
6323
6314
  );
6324
- return this.sb;
6315
+ return this.qb;
6325
6316
  }
6326
6317
  dc(raw, taskConfig) {
6327
6318
  const geometry = new BufferGeometry();