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/index.js CHANGED
@@ -34,31 +34,31 @@ var Type = {
34
34
  var GeometryAttribute = class {
35
35
  c = null;
36
36
  v = 1;
37
- O = 9 /* FLOAT32 */;
37
+ P = 9 /* FLOAT32 */;
38
38
  Pa = false;
39
- P = 0;
40
39
  Q = 0;
40
+ R = 0;
41
41
  za = Type.INVALID;
42
42
  Aa = 0;
43
43
  init(attributeType, buffer, numComponents, dataType, normalized, byteStride, byteOffset) {
44
44
  this.c = buffer;
45
45
  this.v = numComponents;
46
- this.O = dataType;
46
+ this.P = dataType;
47
47
  this.Pa = normalized;
48
- this.P = byteStride;
49
- this.Q = byteOffset;
48
+ this.Q = byteStride;
49
+ this.R = byteOffset;
50
50
  this.za = attributeType;
51
51
  }
52
52
  resetBuffer(buffer, byteStride, byteOffset) {
53
53
  this.c = buffer;
54
- this.P = byteStride;
55
- this.Q = byteOffset;
54
+ this.Q = byteStride;
55
+ this.R = byteOffset;
56
56
  }
57
57
  get attributeType() {
58
58
  return this.za;
59
59
  }
60
60
  get dataType() {
61
- return this.O;
61
+ return this.P;
62
62
  }
63
63
  get numComponents() {
64
64
  return this.v;
@@ -67,10 +67,10 @@ var GeometryAttribute = class {
67
67
  return this.c;
68
68
  }
69
69
  get byteStride() {
70
- return this.P;
70
+ return this.Q;
71
71
  }
72
72
  get byteOffset() {
73
- return this.Q;
73
+ return this.R;
74
74
  }
75
75
  get uniqueId() {
76
76
  return this.Aa;
@@ -83,7 +83,7 @@ var GeometryAttribute = class {
83
83
  // src/decoder/point_cloud/PointCloud.ts
84
84
  var NAMED_ATTRIBUTES_COUNT = 8;
85
85
  var PointCloud = class {
86
- ib = 0;
86
+ gb = 0;
87
87
  attributes_ = [];
88
88
  // named_attribute_index_[type] = [att_id, ...], one list per named type.
89
89
  Qa = [[], [], [], [], [], [], [], []];
@@ -144,10 +144,10 @@ var PointCloud = class {
144
144
  this.attributes_[attId] = pa;
145
145
  }
146
146
  numPoints() {
147
- return this.ib;
147
+ return this.gb;
148
148
  }
149
149
  setNumPoints(num) {
150
- this.ib = num;
150
+ this.gb = num;
151
151
  }
152
152
  };
153
153
 
@@ -157,7 +157,7 @@ var Mesh = class extends PointCloud {
157
157
  // a per-face allocation. faces_[3*f + c] is corner c of face f; corner index
158
158
  // ci maps directly to faces_[ci].
159
159
  faces_ = new Int32Array(0);
160
- jb = 0;
160
+ hb = 0;
161
161
  // Sizes faces_ to hold numFaces faces. Called once per decode, before any
162
162
  // face index is written (edgebreaker: _assignPointsToCorners; sequential:
163
163
  // decodeConnectivity), so the buffer is allocated exactly here — the
@@ -169,124 +169,84 @@ var Mesh = class extends PointCloud {
169
169
  grown.set(this.faces_);
170
170
  this.faces_ = grown;
171
171
  }
172
- this.jb = numFaces;
172
+ this.hb = numFaces;
173
173
  }
174
174
  numFaces() {
175
- return this.jb;
175
+ return this.hb;
176
176
  }
177
177
  };
178
178
 
179
179
  // src/decoder/core/DataBuffer.ts
180
180
  var DataBuffer = class {
181
- m = new Uint8Array(0);
181
+ f = new Uint8Array(0);
182
182
  // Resizes to `size` bytes (contents preserved); when `data` is given, grows
183
183
  // as needed and copies its first `size` bytes in.
184
184
  update(data, size) {
185
185
  if (data === null) {
186
- this.kb(size);
186
+ this.ib(size);
187
187
  return;
188
188
  }
189
- if (size > this.m.length) {
190
- this.kb(size);
189
+ if (size > this.f.length) {
190
+ this.ib(size);
191
191
  }
192
- this.m.set(data.length === size ? data : data.subarray(0, size));
192
+ this.f.set(data.length === size ? data : data.subarray(0, size));
193
193
  }
194
194
  // The caller passes a Uint8Array of exactly dataSize bytes in the common
195
195
  // case; avoid allocating a wrapper view per value (dominates storage time /
196
196
  // GC pressure).
197
197
  write(bytePos, inArray, dataSize) {
198
- this.m.set(inArray.length === dataSize ? inArray : inArray.subarray(0, dataSize), bytePos);
198
+ this.f.set(inArray.length === dataSize ? inArray : inArray.subarray(0, dataSize), bytePos);
199
199
  }
200
200
  get data() {
201
- return this.m;
201
+ return this.f;
202
202
  }
203
- kb(newSize) {
204
- if (newSize === this.m.length) return;
203
+ ib(newSize) {
204
+ if (newSize === this.f.length) return;
205
205
  const newData = new Uint8Array(newSize);
206
- newData.set(this.m.subarray(0, Math.min(this.m.length, newSize)));
207
- this.m = newData;
206
+ if (this.f.length > 0) newData.set(this.f.subarray(0, Math.min(this.f.length, newSize)));
207
+ this.f = newData;
208
208
  }
209
209
  };
210
210
 
211
211
  // src/decoder/core/ScratchArena.ts
212
- var MAX_CLASS = 28;
213
- var freeInt32 = [];
214
- var freeUint32 = [];
215
- var freeUint8 = [];
216
- for (let i = 0; i <= MAX_CLASS; ++i) {
217
- freeInt32.push([]);
218
- freeUint32.push([]);
219
- freeUint8.push([]);
220
- }
221
- var borrowedInt32 = [];
222
- var borrowedUint32 = [];
223
- var borrowedUint8 = [];
224
- var sizeClass = (size) => size <= 1 ? 0 : 32 - Math.clz32(size - 1);
212
+ var arena = new ArrayBuffer(1 << 16);
213
+ var top = 0;
214
+ var outgrown = 0;
215
+ var carve = (bytes) => {
216
+ const size = bytes + 7 & ~7;
217
+ if (top + size > arena.byteLength) {
218
+ outgrown += top;
219
+ arena = new ArrayBuffer(Math.max(arena.byteLength * 2, size));
220
+ top = 0;
221
+ }
222
+ const offset = top;
223
+ top += size;
224
+ return offset;
225
+ };
225
226
  var scratchInt32 = (size) => {
226
- const k = sizeClass(size);
227
- if (k > MAX_CLASS) return new Int32Array(size);
228
- const bucket = freeInt32[k];
229
- let pooled = bucket.length > 0 ? bucket.pop() : new Int32Array(size);
230
- if (pooled.length < size) pooled = new Int32Array(1 << k);
231
- borrowedInt32.push(pooled);
232
- return pooled.length === size ? pooled : pooled.subarray(0, size);
227
+ const offset = carve(size * 4);
228
+ return new Int32Array(arena, offset, size);
233
229
  };
234
230
  var scratchUint32 = (size) => {
235
- const k = sizeClass(size);
236
- if (k > MAX_CLASS) return new Uint32Array(size);
237
- const bucket = freeUint32[k];
238
- let pooled = bucket.length > 0 ? bucket.pop() : new Uint32Array(size);
239
- if (pooled.length < size) pooled = new Uint32Array(1 << k);
240
- borrowedUint32.push(pooled);
241
- return pooled.length === size ? pooled : pooled.subarray(0, size);
231
+ const offset = carve(size * 4);
232
+ return new Uint32Array(arena, offset, size);
242
233
  };
243
- var byteCapacity = (size) => size < 8 ? 8 : size + 7 & ~7;
244
234
  var scratchUint8 = (size) => {
245
- const capacity = byteCapacity(size);
246
- const k = sizeClass(capacity);
247
- if (k > MAX_CLASS) return new Uint8Array(capacity);
248
- const bucket = freeUint8[k];
249
- let pooled = bucket.length > 0 ? bucket.pop() : new Uint8Array(capacity);
250
- if (pooled.length < size) pooled = new Uint8Array(1 << k);
251
- borrowedUint8.push(pooled);
252
- return pooled.length === size ? pooled : pooled.subarray(0, size);
253
- };
254
- var scratchInt32Filled = (size, value) => {
255
- const view = scratchInt32(size);
256
- view.fill(value);
257
- return view;
258
- };
259
- var scratchUint32Zeroed = (size) => {
260
- const view = scratchUint32(size);
261
- view.fill(0);
262
- return view;
263
- };
264
- var scratchUint8Zeroed = (size) => {
265
- const view = scratchUint8(size);
266
- view.fill(0);
267
- return view;
268
- };
269
- var scratchUint8Filled = (size, value) => {
270
- const view = scratchUint8(size);
271
- view.fill(value);
272
- return view;
235
+ const offset = carve(size);
236
+ return new Uint8Array(arena, offset, size);
273
237
  };
238
+ var scratchInt32Filled = (size, value) => scratchInt32(size).fill(value);
239
+ var scratchUint32Zeroed = (size) => scratchUint32(size).fill(0);
240
+ var scratchUint8Zeroed = (size) => scratchUint8(size).fill(0);
241
+ var scratchUint8Filled = (size, value) => scratchUint8(size).fill(value);
242
+ var EMPTY_INT32 = new Int32Array(0);
243
+ var EMPTY_UINT8 = new Uint8Array(0);
274
244
  var releaseScratch = () => {
275
- for (let i = 0; i < borrowedInt32.length; ++i) {
276
- const buffer = borrowedInt32[i];
277
- freeInt32[sizeClass(buffer.length)].push(buffer);
245
+ if (outgrown > 0) {
246
+ arena = new ArrayBuffer(outgrown + top);
247
+ outgrown = 0;
278
248
  }
279
- for (let i = 0; i < borrowedUint32.length; ++i) {
280
- const buffer = borrowedUint32[i];
281
- freeUint32[sizeClass(buffer.length)].push(buffer);
282
- }
283
- for (let i = 0; i < borrowedUint8.length; ++i) {
284
- const buffer = borrowedUint8[i];
285
- freeUint8[sizeClass(buffer.length)].push(buffer);
286
- }
287
- borrowedInt32.length = 0;
288
- borrowedUint32.length = 0;
289
- borrowedUint8.length = 0;
249
+ top = 0;
290
250
  };
291
251
 
292
252
  // src/decoder/attributes/PointAttribute.ts
@@ -317,38 +277,38 @@ var LAZY_INTEGER = 1;
317
277
  var LAZY_QUANTIZED = 2;
318
278
  var LAZY_OCTAHEDRON = 3;
319
279
  var PointAttribute = class extends GeometryAttribute {
320
- z = false;
321
- Ra = 0;
322
- A = [];
323
- Z = null;
280
+ A = false;
281
+ Ba = 0;
282
+ B = [];
283
+ S = null;
324
284
  // Lazily-created cached typed-array view over the attribute buffer, keyed
325
285
  // on (constructor, underlying ArrayBuffer). An attribute only ever reads
326
286
  // through the one view type its data type dictates.
287
+ jb = null;
288
+ kb = null;
327
289
  lb = null;
328
- mb = null;
329
- nb = null;
330
290
  // Deferred inverse transform. The integer attribute decoders leave their
331
291
  // decoded values here as int32 -- quantized floats, octahedral normals or
332
292
  // plain integers -- with the transform's parameters, and extractTo applies
333
293
  // the transform while gathering the values into point order: one pass over
334
294
  // the points instead of an inverse-transform pass into a per-value buffer
335
295
  // followed by a gather from it, and no such buffer at all.
336
- Ba = LAZY_NONE;
337
- _ = null;
338
- ob = [];
339
- Ca = 0;
296
+ Ca = LAZY_NONE;
297
+ $ = null;
298
+ mb = [];
299
+ Da = 0;
340
300
  // Set when the decoder knows every lazy value is below 2^24 in magnitude
341
301
  // (see _lazyFloatValues); the extraction then skips its scan.
342
- Sa = false;
302
+ Ra = false;
343
303
  constructor(geometryAttribute) {
344
304
  super();
345
305
  if (geometryAttribute instanceof GeometryAttribute) {
346
306
  this.c = geometryAttribute.c;
347
307
  this.v = geometryAttribute.v;
348
- this.O = geometryAttribute.O;
349
- this.Pa = geometryAttribute.Pa;
350
308
  this.P = geometryAttribute.P;
309
+ this.Pa = geometryAttribute.Pa;
351
310
  this.Q = geometryAttribute.Q;
311
+ this.R = geometryAttribute.R;
352
312
  this.za = geometryAttribute.za;
353
313
  this.Aa = geometryAttribute.Aa;
354
314
  }
@@ -356,78 +316,87 @@ var PointAttribute = class extends GeometryAttribute {
356
316
  // Intentionally shadows GeometryAttribute.init with a different signature (matches draco.js / C++ source).
357
317
  // @ts-expect-error -- signature intentionally differs from the base class, as in the source.
358
318
  init(attributeType, numComponents, dataType, normalized, numAttributeValues) {
359
- this.Z = new DataBuffer();
319
+ this.S = new DataBuffer();
360
320
  const byteStride = dataTypeLength(dataType) * numComponents;
361
- super.init(attributeType, this.Z, numComponents, dataType, normalized, byteStride, 0);
321
+ super.init(attributeType, this.S, numComponents, dataType, normalized, byteStride, 0);
362
322
  this.reset(numAttributeValues);
363
323
  this.setIdentityMapping();
364
324
  }
365
325
  reset(numAttributeValues) {
366
- if (this.Z === null) {
367
- this.Z = new DataBuffer();
326
+ if (this.S === null) {
327
+ this.S = new DataBuffer();
368
328
  }
369
329
  const entrySize = dataTypeLength(this.dataType) * this.numComponents;
370
- this.Z.update(null, numAttributeValues * entrySize);
371
- this.resetBuffer(this.Z, entrySize, 0);
372
- this.Ra = numAttributeValues;
330
+ this.S.update(null, numAttributeValues * entrySize);
331
+ this.resetBuffer(this.S, entrySize, 0);
332
+ this.Ba = numAttributeValues;
373
333
  return true;
374
334
  }
335
+ // Takes `data` (numAttributeValues values in the attribute's layout) as its
336
+ // storage, without a copy.
337
+ resetWithData(data, numAttributeValues) {
338
+ const buffer = new DataBuffer();
339
+ buffer.f = data;
340
+ this.S = buffer;
341
+ this.resetBuffer(buffer, dataTypeLength(this.dataType) * this.numComponents, 0);
342
+ this.Ba = numAttributeValues;
343
+ }
375
344
  // Sizes the attribute without allocating storage, for the deferred
376
345
  // transforms below (the values live in the decoder's portable attribute).
377
346
  resetLazy(numAttributeValues) {
378
- this.Ra = numAttributeValues;
347
+ this.Ba = numAttributeValues;
379
348
  }
380
349
  // numValues decoded integers of the attribute's own integer type, stored as
381
350
  // int32; extractTo converts them to the requested output type.
382
351
  setLazyInteger(values) {
383
- this.Ba = LAZY_INTEGER;
384
- this._ = values;
352
+ this.Ca = LAZY_INTEGER;
353
+ this.$ = values;
385
354
  }
386
355
  // Quantized float values: value * delta + min per component (float32
387
356
  // arithmetic, see _extractQuantized), as the C++ Dequantizer computes them.
388
357
  setLazyQuantized(values, minValues, delta, bounded) {
389
- this.Ba = LAZY_QUANTIZED;
390
- this._ = values;
391
- this.ob = minValues;
392
- this.Ca = delta;
393
- this.Sa = bounded;
358
+ this.Ca = LAZY_QUANTIZED;
359
+ this.$ = values;
360
+ this.mb = minValues;
361
+ this.Da = delta;
362
+ this.Ra = bounded;
394
363
  }
395
364
  // Octahedral normals: two quantized coordinates per value, dequantized by
396
365
  // `scale` and turned into unit vectors (see _extractOctahedron).
397
366
  setLazyOctahedron(values, scale, bounded) {
398
- this.Ba = LAZY_OCTAHEDRON;
399
- this._ = values;
400
- this.Ca = scale;
401
- this.Sa = bounded;
367
+ this.Ca = LAZY_OCTAHEDRON;
368
+ this.$ = values;
369
+ this.Da = scale;
370
+ this.Ra = bounded;
402
371
  }
403
372
  get size() {
404
- return this.Ra;
373
+ return this.Ba;
405
374
  }
406
375
  mappedIndex(pointIndex) {
407
- if (this.z) {
376
+ if (this.A) {
408
377
  return pointIndex;
409
378
  }
410
- return this.A[pointIndex];
379
+ return this.B[pointIndex];
411
380
  }
412
381
  get isMappingIdentity() {
413
- return this.z;
382
+ return this.A;
414
383
  }
415
384
  get indicesMapSize() {
416
- if (this.z) {
385
+ if (this.A) {
417
386
  return 0;
418
387
  }
419
- return this.A.length;
388
+ return this.B.length;
420
389
  }
421
390
  // Direct access to the explicit point->value index map (a Uint32Array after
422
391
  // any of the setExplicitMapping* calls). Lets hot mapping loops write
423
392
  // entries without a per-entry dispatch.
424
393
  get indicesMap() {
425
- return this.A;
394
+ return this.B;
426
395
  }
427
396
  // Implicit mapping: point index equals attribute entry index.
428
397
  setIdentityMapping() {
429
- this.z = true;
430
- this.A = [];
398
+ this.A = true;
399
+ this.B = [];
431
400
  }
432
401
  // Explicit mapping without an invalid-index fill. Only for callers that
433
402
  // provably write every entry right away (the fill was ~4% of decode time on
@@ -437,31 +406,31 @@ var PointAttribute = class extends GeometryAttribute {
437
406
  // and avoids boxed-number storage; it is read once per point per attribute.
438
407
  // Must be UNSIGNED so the 0xFFFFFFFF invalid sentinel round-trips intact.
439
408
  setExplicitMappingUnfilled(numPoints) {
440
- this.z = false;
441
- this.A = new Uint32Array(numPoints);
409
+ this.A = false;
410
+ this.B = new Uint32Array(numPoints);
442
411
  }
443
412
  // Adopts an already-computed map, shared with other attributes of the same
444
413
  // mesh. The map must be treated as read-only from here on (reads go through
445
414
  // mappedIndex/extractTo).
446
415
  setExplicitMappingShared(map) {
447
- this.z = false;
448
- this.A = map;
416
+ this.A = false;
417
+ this.B = map;
449
418
  }
450
419
  // Like setExplicitMappingUnfilled, but from decode-scoped scratch. Only for
451
420
  // attributes that never escape the decode (see ScratchArena) -- the portable
452
421
  // attributes the sequential decoders build and discard.
453
422
  setExplicitMappingScratch(numPoints) {
454
- this.z = false;
455
- this.A = scratchUint32(numPoints);
423
+ this.A = false;
424
+ this.B = scratchUint32(numPoints);
456
425
  }
457
426
  // Cached typed-array view of the given type over the attribute buffer.
458
- pb(Ctor, bufData) {
459
- if (this.lb !== Ctor || this.mb !== bufData.buffer) {
460
- this.lb = Ctor;
461
- this.mb = bufData.buffer;
462
- this.nb = new Ctor(bufData.buffer);
427
+ nb(Ctor, bufData) {
428
+ if (this.jb !== Ctor || this.kb !== bufData.buffer) {
429
+ this.jb = Ctor;
430
+ this.kb = bufData.buffer;
431
+ this.lb = new Ctor(bufData.buffer);
463
432
  }
464
- return this.nb;
433
+ return this.lb;
465
434
  }
466
435
  // Mirrors C++ PointAttribute::ConvertValue<T>() for buffer-backed
467
436
  // attributes. Attribute buffers start at byteOffset 0 and entries are
@@ -470,13 +439,13 @@ var PointAttribute = class extends GeometryAttribute {
470
439
  convertValue(attIndex, outVal) {
471
440
  const bufData = this.c.data;
472
441
  const nc = this.v;
473
- const Ctor = viewCtorFor(this.O);
442
+ const Ctor = viewCtorFor(this.P);
474
443
  if (Ctor === null) {
475
444
  for (let i = 0; i < nc; ++i) outVal[i] = 0;
476
445
  return;
477
446
  }
478
- const view = this.pb(Ctor, bufData);
479
- const baseIndex = (bufData.byteOffset + this.Q + this.P * attIndex) / Ctor.BYTES_PER_ELEMENT;
447
+ const view = this.nb(Ctor, bufData);
448
+ const baseIndex = (bufData.byteOffset + this.R + this.Q * attIndex) / Ctor.BYTES_PER_ELEMENT;
480
449
  for (let i = 0; i < nc; ++i) outVal[i] = view[baseIndex + i];
481
450
  }
482
451
  // Flat-array extraction of all values into one output typed array, in point
@@ -487,26 +456,31 @@ var PointAttribute = class extends GeometryAttribute {
487
456
  if (numPoints === 0) {
488
457
  return array;
489
458
  }
490
- const kind = this.Ba;
459
+ const kind = this.Ca;
491
460
  if (kind !== LAZY_NONE) {
492
- if (this._ !== null) {
493
- if (kind === LAZY_QUANTIZED) this.Qb(array, numPoints);
494
- else if (kind === LAZY_OCTAHEDRON) this.Rb(array, numPoints);
495
- else this.Sb(array, numPoints);
461
+ if (this.$ !== null) {
462
+ if (kind === LAZY_INTEGER) {
463
+ this.Qb(array, numPoints);
464
+ } else {
465
+ const floats = array instanceof Float32Array ? array : new Float32Array(array.length);
466
+ if (kind === LAZY_QUANTIZED) this.Rb(floats, numPoints);
467
+ else this.Sb(floats, numPoints);
468
+ if (floats !== array) array.set(floats);
469
+ }
496
470
  }
497
471
  return array;
498
472
  }
499
- const Ctor = viewCtorFor(this.O);
473
+ const Ctor = viewCtorFor(this.P);
500
474
  if (this.c === null || Ctor === null) {
501
475
  return array;
502
476
  }
503
477
  const bufData = this.c.data;
504
- const isIdentity = this.z;
505
- const indicesMap = this.A;
506
- const srcView = this.pb(Ctor, bufData);
478
+ const isIdentity = this.A;
479
+ const indicesMap = this.B;
480
+ const srcView = this.nb(Ctor, bufData);
507
481
  const shift = 31 - Math.clz32(Ctor.BYTES_PER_ELEMENT);
508
- const srcStart = bufData.byteOffset + this.Q >> shift;
509
- const strideElements = this.P >> shift;
482
+ const srcStart = bufData.byteOffset + this.R >> shift;
483
+ const strideElements = this.Q >> shift;
510
484
  if (isIdentity && strideElements === numComponents) {
511
485
  const srcEnd = srcStart + numPoints * numComponents;
512
486
  if (srcView.constructor === OutputTypedArray) {
@@ -533,8 +507,8 @@ var PointAttribute = class extends GeometryAttribute {
533
507
  // are bit-identical to the reference decoder whatever the output array type.
534
508
  // Point -> value index; the identity mapping (sequential meshes) gets a
535
509
  // plain iota so the loops carry no per-point branch.
536
- Ta(numPoints) {
537
- if (!this.z) return this.A;
510
+ Sa(numPoints) {
511
+ if (!this.A) return this.B;
538
512
  const map = new Uint32Array(numPoints);
539
513
  for (let p = 0; p < numPoints; ++p) map[p] = p;
540
514
  return map;
@@ -547,9 +521,9 @@ var PointAttribute = class extends GeometryAttribute {
547
521
  // practice) are rounded in place once here, after which the same holds.
548
522
  // The decoder marks the attribute bounded when its prediction transform
549
523
  // already confines the values to that range, and the scan is skipped.
550
- qb() {
551
- const values = this._;
552
- if (this.Sa) return values;
524
+ ob() {
525
+ const values = this.$;
526
+ if (this.Ra) return values;
553
527
  for (let i = 0; i < values.length; ++i) {
554
528
  if (values[i] >= 16777216 || values[i] <= -16777216) {
555
529
  for (let j = 0; j < values.length; ++j) values[j] = Math.fround(values[j]);
@@ -558,23 +532,24 @@ var PointAttribute = class extends GeometryAttribute {
558
532
  }
559
533
  return values;
560
534
  }
561
- // C++ Dequantizer: float(value) * delta + min, all in float32.
562
- Qb(out, numPoints) {
563
- const values = this.qb();
564
- const map = this.Ta(numPoints);
535
+ // C++ Dequantizer: float(value) * delta + min, all in float32 (the final
536
+ // rounding is the Float32Array store's).
537
+ Rb(out, numPoints) {
538
+ const values = this.ob();
539
+ const map = this.Sa(numPoints);
565
540
  const numComponents = this.v;
566
541
  const fround = Math.fround;
567
- const delta = this.Ca;
568
- const min = this.ob;
542
+ const delta = this.Da;
543
+ const min = this.mb;
569
544
  if (numComponents === 3) {
570
545
  const m0 = min[0];
571
546
  const m1 = min[1];
572
547
  const m2 = min[2];
573
548
  for (let p = 0, d = 0; p < numPoints; ++p, d += 3) {
574
549
  const s = map[p] * 3;
575
- out[d] = fround(fround(values[s] * delta) + m0);
576
- out[d + 1] = fround(fround(values[s + 1] * delta) + m1);
577
- out[d + 2] = fround(fround(values[s + 2] * delta) + m2);
550
+ out[d] = fround(values[s] * delta) + m0;
551
+ out[d + 1] = fround(values[s + 1] * delta) + m1;
552
+ out[d + 2] = fround(values[s + 2] * delta) + m2;
578
553
  }
579
554
  return;
580
555
  }
@@ -583,54 +558,51 @@ var PointAttribute = class extends GeometryAttribute {
583
558
  const m1 = min[1];
584
559
  for (let p = 0, d = 0; p < numPoints; ++p, d += 2) {
585
560
  const s = map[p] * 2;
586
- out[d] = fround(fround(values[s] * delta) + m0);
587
- out[d + 1] = fround(fround(values[s + 1] * delta) + m1);
561
+ out[d] = fround(values[s] * delta) + m0;
562
+ out[d + 1] = fround(values[s + 1] * delta) + m1;
588
563
  }
589
564
  return;
590
565
  }
591
566
  for (let p = 0, d = 0; p < numPoints; ++p) {
592
567
  const s = map[p] * numComponents;
593
568
  for (let c = 0; c < numComponents; ++c) {
594
- out[d++] = fround(fround(values[s + c] * delta) + min[c]);
569
+ out[d++] = fround(values[s + c] * delta) + min[c];
595
570
  }
596
571
  }
597
572
  }
598
573
  // OctahedronToolBox.QuantizedOctahedralCoordsToUnitVector, two quantized
599
- // coordinates per value to one unit vector per point.
600
- Rb(out, numPoints) {
601
- const values = this.qb();
602
- const map = this.Ta(numPoints);
574
+ // coordinates per value to one unit vector per point, branch-free: the
575
+ // signs of the normals' components are unpredictable, so the fold picks
576
+ // its direction arithmetically (multiplying by +-1 is exact, zero signs
577
+ // included). The C++ zero-vector guard (squared norm below 1e-6) is left
578
+ // out because no input reaches it: |x| + |y| + |z| >= 1 before the fold,
579
+ // which moves y and z by at most |x|, so some component stays above 1/6.
580
+ Sb(out, numPoints) {
581
+ const values = this.ob();
582
+ const map = this.Sa(numPoints);
603
583
  const fround = Math.fround;
604
- const scale = this.Ca;
584
+ const scale = this.Da;
605
585
  for (let p = 0, d = 0; p < numPoints; ++p, d += 3) {
606
586
  const s = map[p] * 2;
607
587
  let y = fround(fround(values[s] * scale) - 1);
608
588
  let z = fround(fround(values[s + 1] * scale) - 1);
609
589
  const x = fround(fround(1 - Math.abs(y)) - Math.abs(z));
610
- let xOffset = -x;
611
- if (xOffset < 0) xOffset = 0;
612
- y = fround(y + (y < 0 ? xOffset : -xOffset));
613
- z = fround(z + (z < 0 ? xOffset : -xOffset));
614
- const normSquared = fround(fround(fround(x * x) + fround(y * y)) + fround(z * z));
615
- if (normSquared < 1e-6) {
616
- out[d] = 0;
617
- out[d + 1] = 0;
618
- out[d + 2] = 0;
619
- } else {
620
- const k = fround(1 / fround(Math.sqrt(normSquared)));
621
- out[d] = fround(x * k);
622
- out[d + 1] = fround(y * k);
623
- out[d + 2] = fround(z * k);
624
- }
590
+ const xOffset = Math.max(-x, 0);
591
+ y = fround(y + xOffset * (2 * +(y < 0) - 1));
592
+ z = fround(z + xOffset * (2 * +(z < 0) - 1));
593
+ const k = fround(1 / fround(Math.sqrt(fround(fround(fround(x * x) + fround(y * y)) + fround(z * z)))));
594
+ out[d] = x * k;
595
+ out[d + 1] = y * k;
596
+ out[d + 2] = z * k;
625
597
  }
626
598
  }
627
599
  // The int32 values wrap to the attribute's own integer type (as storing
628
600
  // them into it would) before the output store converts them.
629
- Sb(out, numPoints) {
630
- const values = this._;
631
- const map = this.Ta(numPoints);
601
+ Qb(out, numPoints) {
602
+ const values = this.$;
603
+ const map = this.Sa(numPoints);
632
604
  const numComponents = this.v;
633
- const dt = this.O;
605
+ const dt = this.P;
634
606
  const shift = 32 - 8 * dataTypeLength(dt);
635
607
  const signed = dt === 1 /* INT8 */ || dt === 3 /* INT16 */ || dt === 5 /* INT32 */;
636
608
  for (let p = 0, d = 0; p < numPoints; ++p) {
@@ -662,18 +634,18 @@ function decodeVarint(buffer) {
662
634
 
663
635
  // src/decoder/core/DecoderBuffer.ts
664
636
  var BitDecoder = class {
665
- Da = null;
666
- p = 0;
637
+ Ea = null;
638
+ o = 0;
667
639
  ja = 0;
668
- reset(uint8Array, byteLength) {
669
- this.Da = uint8Array;
670
- this.ja = byteLength;
671
- this.p = 0;
640
+ reset(uint8Array, start, end) {
641
+ this.Ea = uint8Array;
642
+ this.ja = end;
643
+ this.o = start * 8;
672
644
  }
673
645
  getBits(nbits) {
674
646
  if (nbits > 32) return void 0;
675
- const buf = this.Da;
676
- let off = this.p;
647
+ const buf = this.Ea;
648
+ let off = this.o;
677
649
  const byteOffset = off >> 3;
678
650
  const bitShift = off & 7;
679
651
  if (byteOffset + 4 < this.ja) {
@@ -687,7 +659,7 @@ var BitDecoder = class {
687
659
  } else {
688
660
  result = val >>> bitShift;
689
661
  }
690
- this.p = off + nbits;
662
+ this.o = off + nbits;
691
663
  return nbits === 32 ? result : result & (1 << nbits) - 1;
692
664
  }
693
665
  let value = 0;
@@ -705,54 +677,68 @@ var BitDecoder = class {
705
677
  bitsRead += bitsToRead;
706
678
  currOff += bitsToRead;
707
679
  }
708
- this.p = currOff;
680
+ this.o = currOff;
709
681
  return value;
710
682
  }
711
683
  };
684
+ var floatBytes = new Uint8Array(4);
685
+ var floatView = new DataView(floatBytes.buffer);
712
686
  var DecoderBuffer = class {
713
- m = null;
714
- Ea = null;
715
- K = 0;
716
- d = 0;
687
+ f = null;
688
+ y = 0;
689
+ g = 0;
717
690
  ka = new BitDecoder();
718
691
  Fa = false;
719
692
  init(data, dataSize = data.length) {
720
- this.m = data;
721
- this.Ea = new DataView(data.buffer, data.byteOffset, data.byteLength);
722
- this.K = dataSize;
723
- this.d = 0;
693
+ this.f = data;
694
+ this.y = dataSize;
695
+ this.g = 0;
696
+ }
697
+ // Continues where `other` stands: same bytes, same position (offsets stay
698
+ // absolute, so no view of the remaining bytes is made).
699
+ initFrom(other) {
700
+ this.f = other.f;
701
+ this.y = other.y;
702
+ this.g = other.g;
724
703
  }
725
704
  // Typed little-endian reads.
726
705
  decodeUint8() {
727
- if (this.d + 1 > this.K) return void 0;
728
- const val = this.m[this.d];
729
- this.d += 1;
706
+ if (this.g + 1 > this.y) return void 0;
707
+ const val = this.f[this.g];
708
+ this.g += 1;
730
709
  return val;
731
710
  }
732
711
  decodeUint16() {
733
- if (this.d + 2 > this.K) return void 0;
734
- const val = this.Ea.getUint16(this.d, true);
735
- this.d += 2;
736
- return val;
712
+ const pos = this.g;
713
+ if (pos + 2 > this.y) return void 0;
714
+ const data = this.f;
715
+ this.g = pos + 2;
716
+ return data[pos] | data[pos + 1] << 8;
737
717
  }
738
718
  decodeInt32() {
739
- if (this.d + 4 > this.K) return void 0;
740
- const val = this.Ea.getInt32(this.d, true);
741
- this.d += 4;
742
- return val;
719
+ const pos = this.g;
720
+ if (pos + 4 > this.y) return void 0;
721
+ const data = this.f;
722
+ this.g = pos + 4;
723
+ return data[pos] | data[pos + 1] << 8 | data[pos + 2] << 16 | data[pos + 3] << 24;
743
724
  }
744
725
  decodeFloat32() {
745
- if (this.d + 4 > this.K) return void 0;
746
- const val = this.Ea.getFloat32(this.d, true);
747
- this.d += 4;
748
- return val;
726
+ const pos = this.g;
727
+ if (pos + 4 > this.y) return void 0;
728
+ const data = this.f;
729
+ this.g = pos + 4;
730
+ floatBytes[0] = data[pos];
731
+ floatBytes[1] = data[pos + 1];
732
+ floatBytes[2] = data[pos + 2];
733
+ floatBytes[3] = data[pos + 3];
734
+ return floatView.getFloat32(0, true);
749
735
  }
750
736
  // A view into the stream (no copy), only valid until the caller's next
751
737
  // chance to mutate the buffer — copy out before keeping it.
752
738
  decodeBytesView(size) {
753
- if (this.d + size > this.K) return void 0;
754
- const result = this.m.subarray(this.d, this.d + size);
755
- this.d += size;
739
+ if (this.g + size > this.y) return void 0;
740
+ const result = this.f.subarray(this.g, this.g + size);
741
+ this.g += size;
756
742
  return result;
757
743
  }
758
744
  // Only the 2.2+ layout (varint size prefix): older bitstreams are rejected
@@ -765,31 +751,28 @@ var DecoderBuffer = class {
765
751
  outSize = size;
766
752
  }
767
753
  this.Fa = true;
768
- this.ka.reset(this.m.subarray(this.d), this.K - this.d);
754
+ this.ka.reset(this.f, this.g, this.y);
769
755
  return outSize;
770
756
  }
771
757
  endBitDecoding() {
772
758
  this.Fa = false;
773
- this.d += Math.ceil(this.ka.p / 8);
759
+ this.g = Math.ceil(this.ka.o / 8);
774
760
  }
775
761
  decodeLeastSignificantBits32(nbits) {
776
762
  if (!this.Fa) return void 0;
777
763
  return this.ka.getBits(nbits);
778
764
  }
779
765
  advance(bytes) {
780
- this.d += bytes;
766
+ this.g += bytes;
781
767
  }
782
768
  get data() {
783
- return this.m;
784
- }
785
- get dataHead() {
786
- return this.m.subarray(this.d);
769
+ return this.f;
787
770
  }
788
771
  get remainingSize() {
789
- return this.K - this.d;
772
+ return this.y - this.g;
790
773
  }
791
774
  get decodedSize() {
792
- return this.d;
775
+ return this.g;
793
776
  }
794
777
  get bitDecoderActive() {
795
778
  return this.Fa;
@@ -810,66 +793,66 @@ var METADATA_FLAG_MASK = 32768;
810
793
  var kMaxSubmetadataLevel = 1e3;
811
794
  var MetadataDecoder = class {
812
795
  constructor(buffer_) {
813
- this.B = buffer_;
796
+ this.C = buffer_;
814
797
  }
815
798
  buffer_;
816
799
  // Skips per-attribute metadata followed by the geometry-level metadata.
817
800
  skipGeometryMetadata() {
818
- const numAttMetadata = decodeVarint(this.B);
801
+ const numAttMetadata = decodeVarint(this.C);
819
802
  if (numAttMetadata === void 0) {
820
803
  return false;
821
804
  }
822
805
  for (let i = 0; i < numAttMetadata; ++i) {
823
- if (decodeVarint(this.B) === void 0) {
806
+ if (decodeVarint(this.C) === void 0) {
824
807
  return false;
825
808
  }
826
- if (!this.Ua(0)) {
809
+ if (!this.Ta(0)) {
827
810
  return false;
828
811
  }
829
812
  }
830
- return this.Ua(0);
813
+ return this.Ta(0);
831
814
  }
832
815
  // Discards one metadata block (key-value entries plus nested sub-metadata).
833
816
  // Sub-blocks read depth-first in stream order, matching the C++ stack traversal.
834
- Ua(level) {
817
+ Ta(level) {
835
818
  if (level > kMaxSubmetadataLevel) {
836
819
  return false;
837
820
  }
838
- const numEntries = decodeVarint(this.B);
821
+ const numEntries = decodeVarint(this.C);
839
822
  if (numEntries === void 0) {
840
823
  return false;
841
824
  }
842
825
  for (let i = 0; i < numEntries; ++i) {
843
- const nameSkipped = this.rb();
844
- const dataSize = nameSkipped ? decodeVarint(this.B) : void 0;
845
- if (dataSize === void 0 || dataSize === 0 || !this.sb(dataSize)) {
826
+ const nameSkipped = this.pb();
827
+ const dataSize = nameSkipped ? decodeVarint(this.C) : void 0;
828
+ if (dataSize === void 0 || dataSize === 0 || !this.qb(dataSize)) {
846
829
  return false;
847
830
  }
848
831
  }
849
- const numSubMetadata = decodeVarint(this.B);
850
- if (numSubMetadata === void 0 || numSubMetadata > this.B.remainingSize) {
832
+ const numSubMetadata = decodeVarint(this.C);
833
+ if (numSubMetadata === void 0 || numSubMetadata > this.C.remainingSize) {
851
834
  return false;
852
835
  }
853
836
  for (let i = 0; i < numSubMetadata; ++i) {
854
- if (!this.rb() || !this.Ua(level + 1)) {
837
+ if (!this.pb() || !this.Ta(level + 1)) {
855
838
  return false;
856
839
  }
857
840
  }
858
841
  return true;
859
842
  }
860
843
  // Skips a name (uint8 length prefix followed by that many bytes).
861
- rb() {
862
- const nameLen = this.B.decodeUint8();
844
+ pb() {
845
+ const nameLen = this.C.decodeUint8();
863
846
  if (nameLen === void 0) {
864
847
  return false;
865
848
  }
866
- return this.sb(nameLen);
849
+ return this.qb(nameLen);
867
850
  }
868
- sb(size) {
869
- if (size > this.B.remainingSize) {
851
+ qb(size) {
852
+ if (size > this.C.remainingSize) {
870
853
  return false;
871
854
  }
872
- this.B.advance(size);
855
+ this.C.advance(size);
873
856
  return true;
874
857
  }
875
858
  };
@@ -947,8 +930,8 @@ var RAnsDecoder = class {
947
930
  bucketShift = 0;
948
931
  // Uint16 unless the alphabet needs wider ids, so real streams keep one table type.
949
932
  bucketTable = null;
950
- // Stream state inlined (not a nested AnsDecoder) so the ransRead() hot loop
951
- // touches own props; initialized by ansReadInit.
933
+ // Stream state inlined (not a nested AnsDecoder) so the decode loops touch
934
+ // own props; initialized by ansReadInit.
952
935
  buf = null;
953
936
  bufOffset = 0;
954
937
  // First valid byte of this decoder's slice within buf (absolute offsets,
@@ -980,31 +963,8 @@ var RAnsDecoder = class {
980
963
  }
981
964
  return this.state === this.lRansBase;
982
965
  }
983
- ransRead() {
984
- const buf = this.buf;
985
- const lRansBase = this.lRansBase;
986
- let state = this.state;
987
- let bufOffset = this.bufOffset;
988
- const bufStart = this.bufStart;
989
- while (state < lRansBase && bufOffset > bufStart) {
990
- state = state << 8 | buf[--bufOffset];
991
- }
992
- const quo = state >>> this.ransPrecisionBits;
993
- const rem = state & this.ransPrecisionMask;
994
- let symbol;
995
- if (this.coarse) {
996
- const cumProbTable = this.cumProbTable;
997
- symbol = this.bucketTable[rem >> this.bucketShift];
998
- while (cumProbTable[symbol + 1] <= rem) symbol++;
999
- } else {
1000
- symbol = this.lutTable[rem];
1001
- }
1002
- this.state = quo * this.probTable[symbol] + rem - this.cumProbTable[symbol];
1003
- this.bufOffset = bufOffset;
1004
- return symbol;
1005
- }
1006
- // Batch ransRead() into out[0..count): all fields hoisted to locals, state
1007
- // written back once. Removes per-symbol property reads and call indirection.
966
+ // Decodes count symbols into out[0..count): all fields hoisted to locals,
967
+ // state written back once.
1008
968
  decodeSymbols(out, count) {
1009
969
  if (this.coarse) {
1010
970
  this.Tb(out, count);
@@ -1301,9 +1261,9 @@ function ransDecodeSymbolsTrioU16(a, outA, countA, b, outB, countB, c, outC, cou
1301
1261
 
1302
1262
  // src/decoder/compression/point_cloud/PointCloudDecoder.ts
1303
1263
  var PointCloudDecoder = class {
1304
- R = null;
1264
+ T = null;
1305
1265
  c = null;
1306
- t = [];
1266
+ s = [];
1307
1267
  Ga = [];
1308
1268
  // Returns an error message, or '' on success (outHeader is then populated).
1309
1269
  static decodeHeader(buffer, outHeader) {
@@ -1334,7 +1294,7 @@ var PointCloudDecoder = class {
1334
1294
  // Main entry point, given the already-parsed header (see Decode.ts).
1335
1295
  decode(header, inBuffer, outPointCloud) {
1336
1296
  this.c = inBuffer;
1337
- this.R = outPointCloud;
1297
+ this.T = outPointCloud;
1338
1298
  if (header.versionMajor !== 2 || header.versionMinor !== 2) {
1339
1299
  return "Unsupported bitstream version (Draco 2.2 meshes only).";
1340
1300
  }
@@ -1356,27 +1316,27 @@ var PointCloudDecoder = class {
1356
1316
  if (attDecoderId < 0) {
1357
1317
  return false;
1358
1318
  }
1359
- while (this.t.length <= attDecoderId) {
1360
- this.t.push(null);
1319
+ while (this.s.length <= attDecoderId) {
1320
+ this.s.push(null);
1361
1321
  }
1362
- this.t[attDecoderId] = decoder;
1322
+ this.s[attDecoderId] = decoder;
1363
1323
  return true;
1364
1324
  }
1365
1325
  getPortableAttribute(parentAttId) {
1366
- if (parentAttId < 0 || parentAttId >= this.R.numAttributes()) {
1326
+ if (parentAttId < 0 || parentAttId >= this.T.numAttributes()) {
1367
1327
  return null;
1368
1328
  }
1369
1329
  const parentAttDecoderId = this.Ga[parentAttId];
1370
- return this.t[parentAttDecoderId].getPortableAttribute(parentAttId);
1330
+ return this.s[parentAttDecoderId].getPortableAttribute(parentAttId);
1371
1331
  }
1372
1332
  attributesDecoder(decId) {
1373
- return this.t[decId];
1333
+ return this.s[decId];
1374
1334
  }
1375
1335
  numAttributesDecoders() {
1376
- return this.t.length;
1336
+ return this.s.length;
1377
1337
  }
1378
1338
  pointCloud() {
1379
- return this.R;
1339
+ return this.T;
1380
1340
  }
1381
1341
  buffer() {
1382
1342
  return this.c;
@@ -1402,20 +1362,20 @@ var PointCloudDecoder = class {
1402
1362
  return false;
1403
1363
  }
1404
1364
  }
1405
- for (let i = 0; i < this.t.length; ++i) {
1406
- if (!this.t[i].init(this, this.R)) {
1365
+ for (let i = 0; i < this.s.length; ++i) {
1366
+ if (!this.s[i].init(this, this.T)) {
1407
1367
  return false;
1408
1368
  }
1409
1369
  }
1410
1370
  for (let i = 0; i < numAttributesDecoders; ++i) {
1411
- if (!this.t[i].decodeAttributesDecoderData(this.c)) {
1371
+ if (!this.s[i].decodeAttributesDecoderData(this.c)) {
1412
1372
  return false;
1413
1373
  }
1414
1374
  }
1415
1375
  for (let i = 0; i < numAttributesDecoders; ++i) {
1416
- const numAttributes = this.t[i].getNumAttributes();
1376
+ const numAttributes = this.s[i].getNumAttributes();
1417
1377
  for (let j = 0; j < numAttributes; ++j) {
1418
- const attId = this.t[i].getAttributeId(j);
1378
+ const attId = this.s[i].getAttributeId(j);
1419
1379
  while (this.Ga.length <= attId) {
1420
1380
  this.Ga.push(0);
1421
1381
  }
@@ -1425,7 +1385,7 @@ var PointCloudDecoder = class {
1425
1385
  return this.decodeAllAttributes();
1426
1386
  }
1427
1387
  decodeAllAttributes() {
1428
- const decoders = this.t;
1388
+ const decoders = this.s;
1429
1389
  for (let i = 0; i < decoders.length; i++) {
1430
1390
  if (!decoders[i].decodeAttributesParse(this.c)) {
1431
1391
  return false;
@@ -1447,10 +1407,10 @@ var PointCloudDecoder = class {
1447
1407
 
1448
1408
  // src/decoder/compression/mesh/MeshDecoder.ts
1449
1409
  var MeshDecoder = class extends PointCloudDecoder {
1450
- C = null;
1410
+ D = null;
1451
1411
  // Returns an error message, or '' on success.
1452
1412
  decodeMesh(header, inBuffer, outMesh) {
1453
- this.C = outMesh;
1413
+ this.D = outMesh;
1454
1414
  return this.decode(header, inBuffer, outMesh);
1455
1415
  }
1456
1416
  // Connectivity accessors used by the mesh prediction schemes; the sequential
@@ -1465,7 +1425,7 @@ var MeshDecoder = class extends PointCloudDecoder {
1465
1425
  return null;
1466
1426
  }
1467
1427
  mesh() {
1468
- return this.C;
1428
+ return this.D;
1469
1429
  }
1470
1430
  decodeGeometryData() {
1471
1431
  return this.decodeConnectivity() && super.decodeGeometryData();
@@ -1476,21 +1436,21 @@ var MeshDecoder = class extends PointCloudDecoder {
1476
1436
  var kInvalidCornerIndex = -1;
1477
1437
  var MeshAttributeCornerTable = class {
1478
1438
  // Base vertices touched by a seam edge of this table.
1479
- la = new Uint8Array(0);
1480
- S = new Int32Array(0);
1439
+ la = EMPTY_UINT8;
1440
+ U = EMPTY_INT32;
1481
1441
  // Attribute vertex -> 1 when its fan is open in this table (see
1482
1442
  // CornerTable._vertexOnBoundary). The C++ also keeps each attribute
1483
1443
  // vertex's left-most corner, but the decoder only ever asked it whether
1484
1444
  // that corner sits on a boundary, which this answers directly.
1485
- y = new Uint8Array(0);
1445
+ z = EMPTY_UINT8;
1486
1446
  // Attribute-vertex count. C++ keeps a vertex -> attribute-entry map here, but
1487
1447
  // the decoder only ever reads its size, so track the count directly instead
1488
1448
  // of allocating an Int32Array per attribute corner table.
1489
1449
  ma = 0;
1490
- D = null;
1450
+ E = null;
1491
1451
  // The base table's opposite corners with both corners of every seam edge
1492
1452
  // set to -1: what opposite() answers, and what the traversals read.
1493
- E = new Int32Array(0);
1453
+ F = EMPTY_INT32;
1494
1454
  // Starts the table as a copy of the base connectivity; addSeamEdge then
1495
1455
  // cuts the seams and the ring pass numbers the vertices. Decode-scoped
1496
1456
  // scratch throughout: the table lives only until the decode finishes (the
@@ -1498,30 +1458,28 @@ var MeshAttributeCornerTable = class {
1498
1458
  // file from allocating a fresh set per attribute per prim.
1499
1459
  initEmpty(table) {
1500
1460
  const numCorners = table.numCorners();
1501
- this.D = table;
1461
+ this.E = table;
1502
1462
  this.la = scratchUint8Zeroed(table.numVertices());
1503
- this.E = scratchInt32(numCorners);
1504
- this.E.set(table.oppositeCornerArray());
1505
- this.S = scratchInt32(numCorners);
1506
- this.S.set(table.cornerToVertexArray());
1463
+ this.F = scratchInt32(numCorners);
1464
+ this.F.set(table.oppositeCornerArray());
1465
+ this.U = scratchInt32(numCorners);
1466
+ this.U.set(table.cornerToVertexArray());
1507
1467
  this.ma = 0;
1508
1468
  }
1509
- // Cuts the edge opposite corner c (and its twin) and flags its two vertices.
1469
+ // Cuts the interior edge opposite corner c (and its twin) and flags its two
1470
+ // vertices. (Boundary edges are open in the base table already, and flagging
1471
+ // their vertices would only send them through the ring walk to come out
1472
+ // unsplit.)
1510
1473
  addSeamEdge(c) {
1511
- const cornerToVertex = this.D.cornerToVertexArray();
1512
- const opposite = this.E;
1474
+ const cornerToVertex = this.E.cornerToVertexArray();
1475
+ const opposite = this.F;
1513
1476
  const isVert = this.la;
1514
1477
  const oppCorner = opposite[c];
1515
1478
  opposite[c] = kInvalidCornerIndex;
1516
- let rem = c - (c / 3 | 0) * 3;
1479
+ opposite[oppCorner] = kInvalidCornerIndex;
1480
+ const rem = c - (c / 3 | 0) * 3;
1517
1481
  isVert[cornerToVertex[rem === 2 ? c - 2 : c + 1]] = 1;
1518
1482
  isVert[cornerToVertex[rem === 0 ? c + 2 : c - 1]] = 1;
1519
- if (oppCorner !== kInvalidCornerIndex) {
1520
- opposite[oppCorner] = kInvalidCornerIndex;
1521
- rem = oppCorner - (oppCorner / 3 | 0) * 3;
1522
- isVert[cornerToVertex[rem === 2 ? oppCorner - 2 : oppCorner + 1]] = 1;
1523
- isVert[cornerToVertex[rem === 0 ? oppCorner + 2 : oppCorner - 1]] = 1;
1524
- }
1525
1483
  }
1526
1484
  // Installs the vertex numbering computed by the edgebreaker decoder's ring
1527
1485
  // pass, which fills corner_to_vertex_map_ directly and hands over the
@@ -1529,29 +1487,29 @@ var MeshAttributeCornerTable = class {
1529
1487
  // least numVertices entries).
1530
1488
  setRecomputedVertices(onBoundary, numVertices) {
1531
1489
  this.ma = numVertices;
1532
- this.y = onBoundary;
1490
+ this.z = onBoundary;
1533
1491
  }
1534
1492
  // A table without interior seams is the base connectivity itself: every
1535
1493
  // vertex ring is one attribute vertex, and the boundary edges are already
1536
1494
  // open in the base opposite table. Shares the base arrays (read-only from
1537
1495
  // here on), so its traversal also resolves to the base table's cached one.
1538
1496
  initAsBase(table) {
1539
- this.D = table;
1540
- this.E = table.oppositeCornerArray();
1541
- this.S = table.cornerToVertexArray();
1497
+ this.E = table;
1498
+ this.F = table.oppositeCornerArray();
1499
+ this.U = table.cornerToVertexArray();
1542
1500
  this.setRecomputedVertices(table.vertexOnBoundaryArray(), table.numVertices());
1543
1501
  }
1544
1502
  opposite(corner) {
1545
1503
  if (corner === kInvalidCornerIndex) {
1546
1504
  return kInvalidCornerIndex;
1547
1505
  }
1548
- return this.E[corner];
1506
+ return this.F[corner];
1549
1507
  }
1550
1508
  next(corner) {
1551
- return this.D.next(corner);
1509
+ return this.E.next(corner);
1552
1510
  }
1553
1511
  previous(corner) {
1554
- return this.D.previous(corner);
1512
+ return this.E.previous(corner);
1555
1513
  }
1556
1514
  swingRight(corner) {
1557
1515
  return this.previous(this.opposite(this.previous(corner)));
@@ -1563,32 +1521,32 @@ var MeshAttributeCornerTable = class {
1563
1521
  return this.ma;
1564
1522
  }
1565
1523
  numFaces() {
1566
- return this.D.numFaces();
1524
+ return this.E.numFaces();
1567
1525
  }
1568
1526
  numCorners() {
1569
- return this.D.numCorners();
1527
+ return this.E.numCorners();
1570
1528
  }
1571
1529
  // --- Flat-array accessors: let DepthFirstTraverser avoid per-corner dispatch. ---
1572
1530
  cornerToVertexArray() {
1573
- return this.S;
1531
+ return this.U;
1574
1532
  }
1575
1533
  // Seam-aware opposite corners (seam edges -> -1), matching opposite().
1576
1534
  oppositeCornerArray() {
1577
- return this.E;
1535
+ return this.F;
1578
1536
  }
1579
1537
  vertexOnBoundaryArray() {
1580
- return this.y;
1538
+ return this.z;
1581
1539
  }
1582
1540
  // Takes over another table's state wholesale. Only valid when both tables
1583
1541
  // were built from the same corner table and the same seam edges, in which
1584
1542
  // case every one of these is identical and read-only from here on.
1585
1543
  adoptFrom(other) {
1586
- this.D = other.D;
1544
+ this.E = other.E;
1587
1545
  this.la = other.la;
1588
- this.S = other.S;
1546
+ this.U = other.U;
1589
1547
  this.ma = other.ma;
1590
- this.y = other.y;
1591
- this.E = other.E;
1548
+ this.z = other.z;
1549
+ this.F = other.F;
1592
1550
  }
1593
1551
  };
1594
1552
 
@@ -1597,11 +1555,11 @@ var AttributesDecoder = class {
1597
1555
  Ha = [];
1598
1556
  // Inverse of _pointAttributeIds: point attribute id -> local id.
1599
1557
  na = [];
1600
- tb = null;
1601
- R = null;
1558
+ rb = null;
1559
+ T = null;
1602
1560
  init(decoder, pointCloud) {
1603
- this.tb = decoder;
1604
- this.R = pointCloud;
1561
+ this.rb = decoder;
1562
+ this.T = pointCloud;
1605
1563
  return true;
1606
1564
  }
1607
1565
  decodeAttributesDecoderData(buffer) {
@@ -1610,7 +1568,7 @@ var AttributesDecoder = class {
1610
1568
  return false;
1611
1569
  }
1612
1570
  this.Ha.length = numAttributes;
1613
- const pc = this.R;
1571
+ const pc = this.T;
1614
1572
  for (let i = 0; i < numAttributes; i++) {
1615
1573
  const attType = buffer.decodeUint8();
1616
1574
  if (attType === void 0) return false;
@@ -1651,7 +1609,7 @@ var AttributesDecoder = class {
1651
1609
  return this.Ha.length;
1652
1610
  }
1653
1611
  getDecoder() {
1654
- return this.tb;
1612
+ return this.rb;
1655
1613
  }
1656
1614
  getLocalIdForPointAttribute(pointAttributeId) {
1657
1615
  if (pointAttributeId >= this.na.length) {
@@ -1663,15 +1621,15 @@ var AttributesDecoder = class {
1663
1621
 
1664
1622
  // src/decoder/compression/attributes/SequentialAttributeDecoder.ts
1665
1623
  var SequentialAttributeDecoder = class {
1666
- l = null;
1667
- F = null;
1668
- ub = -1;
1624
+ m = null;
1625
+ G = null;
1626
+ sb = -1;
1669
1627
  // Decoded portable attribute (after lossless decoding).
1670
- $ = null;
1628
+ V = null;
1671
1629
  init(decoder, attributeId) {
1672
- this.l = decoder;
1673
- this.F = decoder.pointCloud().attribute(attributeId);
1674
- this.ub = attributeId;
1630
+ this.m = decoder;
1631
+ this.G = decoder.pointCloud().attribute(attributeId);
1632
+ this.sb = attributeId;
1675
1633
  return true;
1676
1634
  }
1677
1635
  // --- Two-phase decode ---
@@ -1682,10 +1640,10 @@ var SequentialAttributeDecoder = class {
1682
1640
  // stream simply do the whole decode in Parse (decodeValues); the defaults
1683
1641
  // below are theirs.
1684
1642
  decodePortableAttributeParse(pointIds, buffer) {
1685
- if (this.F.numComponents <= 0) {
1643
+ if (this.G.numComponents <= 0) {
1686
1644
  return false;
1687
1645
  }
1688
- if (!this.vb(pointIds.length)) {
1646
+ if (!this.tb(pointIds.length)) {
1689
1647
  return false;
1690
1648
  }
1691
1649
  return this.decodeValues(pointIds, buffer);
@@ -1693,8 +1651,8 @@ var SequentialAttributeDecoder = class {
1693
1651
  // Sizes (and here allocates) the attribute's storage for numValues values;
1694
1652
  // the integer decoders override it to skip the allocation, their values
1695
1653
  // staying in the portable attribute (see PointAttribute.setLazyInteger).
1696
- vb(numValues) {
1697
- return this.F.reset(numValues);
1654
+ tb(numValues) {
1655
+ return this.G.reset(numValues);
1698
1656
  }
1699
1657
  pendingSymbolStream() {
1700
1658
  return null;
@@ -1711,35 +1669,35 @@ var SequentialAttributeDecoder = class {
1711
1669
  return true;
1712
1670
  }
1713
1671
  getPortableAttribute() {
1714
- if (!this.F.isMappingIdentity && this.$ && this.$.isMappingIdentity) {
1715
- const size = this.F.indicesMapSize;
1716
- this.$.setExplicitMappingScratch(size);
1717
- const src = this.F.indicesMap;
1718
- const dst = this.$.indicesMap;
1672
+ if (!this.G.isMappingIdentity && this.V && this.V.isMappingIdentity) {
1673
+ const size = this.G.indicesMapSize;
1674
+ this.V.setExplicitMappingScratch(size);
1675
+ const src = this.G.indicesMap;
1676
+ const dst = this.V.indicesMap;
1719
1677
  if (src.length === size) {
1720
1678
  dst.set(src);
1721
1679
  } else {
1722
1680
  dst.set(src.subarray(0, size));
1723
1681
  }
1724
1682
  }
1725
- return this.$;
1683
+ return this.V;
1726
1684
  }
1727
1685
  get attribute() {
1728
- return this.F;
1686
+ return this.G;
1729
1687
  }
1730
1688
  get attributeId() {
1731
- return this.ub;
1689
+ return this.sb;
1732
1690
  }
1733
1691
  get decoder() {
1734
- return this.l;
1692
+ return this.m;
1735
1693
  }
1736
1694
  initPredictionScheme(ps) {
1737
1695
  for (let i = 0; i < ps.getNumParentAttributes(); i++) {
1738
- const attId = this.l.pointCloud().getNamedAttributeId(ps.getParentAttributeType(i));
1696
+ const attId = this.m.pointCloud().getNamedAttributeId(ps.getParentAttributeType(i));
1739
1697
  if (attId === -1) {
1740
1698
  return false;
1741
1699
  }
1742
- const pa = this.l.getPortableAttribute(attId);
1700
+ const pa = this.m.getPortableAttribute(attId);
1743
1701
  if (pa === null || !ps.setParentAttribute(pa)) {
1744
1702
  return false;
1745
1703
  }
@@ -1749,13 +1707,13 @@ var SequentialAttributeDecoder = class {
1749
1707
  // Decodes raw attribute values in their original format.
1750
1708
  decodeValues(pointIds, buffer) {
1751
1709
  const numValues = pointIds.length;
1752
- const entrySize = this.F.byteStride;
1710
+ const entrySize = this.G.byteStride;
1753
1711
  const totalSize = numValues * entrySize;
1754
1712
  const valueData = buffer.decodeBytesView(totalSize);
1755
1713
  if (valueData === void 0) {
1756
1714
  return false;
1757
1715
  }
1758
- this.F.buffer.write(0, valueData, totalSize);
1716
+ this.G.buffer.write(0, valueData, totalSize);
1759
1717
  return true;
1760
1718
  }
1761
1719
  };
@@ -1770,14 +1728,14 @@ function convertSymbolsToSignedInts(input, count, output) {
1770
1728
 
1771
1729
  // src/decoder/compression/entropy/RAnsSymbolDecoder.ts
1772
1730
  var RAnsSymbolDecoder = class {
1773
- wb = 0;
1774
- G;
1731
+ ub = 0;
1732
+ H;
1775
1733
  constructor(uniqueSymbolsBitLength) {
1776
1734
  const unclamped = Math.trunc(3 * uniqueSymbolsBitLength / 2);
1777
- this.G = new RAnsDecoder(unclamped < 12 ? 12 : unclamped > 20 ? 20 : unclamped);
1735
+ this.H = new RAnsDecoder(unclamped < 12 ? 12 : unclamped > 20 ? 20 : unclamped);
1778
1736
  }
1779
1737
  get numSymbols() {
1780
- return this.wb;
1738
+ return this.ub;
1781
1739
  }
1782
1740
  // Initialize the decoder and decode the probability table. expectedCount is
1783
1741
  // the number of symbols the caller will decode (lets short streams skip the
@@ -1785,7 +1743,7 @@ var RAnsSymbolDecoder = class {
1785
1743
  create(buffer, expectedCount = 2147483647) {
1786
1744
  const numSymbols = decodeVarint(buffer);
1787
1745
  if (numSymbols === void 0) return false;
1788
- this.wb = numSymbols;
1746
+ this.ub = numSymbols;
1789
1747
  if (Math.trunc(numSymbols / 64) > buffer.remainingSize) {
1790
1748
  return false;
1791
1749
  }
@@ -1818,7 +1776,7 @@ var RAnsSymbolDecoder = class {
1818
1776
  }
1819
1777
  }
1820
1778
  buffer.advance(pos - startPos);
1821
- return this.G.ransBuildLookUpTable(probabilityTable, numSymbols, expectedCount);
1779
+ return this.H.ransBuildLookUpTable(probabilityTable, numSymbols, expectedCount);
1822
1780
  }
1823
1781
  // Starts decoding, advancing buffer past the encoded data.
1824
1782
  startDecoding(buffer) {
@@ -1829,10 +1787,10 @@ var RAnsSymbolDecoder = class {
1829
1787
  }
1830
1788
  const base = buffer.decodedSize;
1831
1789
  buffer.advance(Number(bytesEncoded));
1832
- return ansReadInit(this.G, buffer.data, base + Number(bytesEncoded), base, this.G.lRansBase, 4);
1790
+ return ansReadInit(this.H, buffer.data, base + Number(bytesEncoded), base, this.H.lRansBase, 4);
1833
1791
  }
1834
1792
  endDecoding() {
1835
- this.G.readEnd();
1793
+ this.H.readEnd();
1836
1794
  }
1837
1795
  };
1838
1796
 
@@ -1860,15 +1818,38 @@ function decodeTaggedSymbols(numValues, numComponents, srcBuffer, outValues) {
1860
1818
  if (numValues > 0 && tagDecoder.numSymbols === 0) {
1861
1819
  return false;
1862
1820
  }
1863
- const tagAns = tagDecoder.G;
1821
+ const ans = tagDecoder.H;
1822
+ const ansBuf = ans.buf;
1823
+ const ansStart = ans.bufStart;
1824
+ const lRansBase = ans.lRansBase;
1825
+ const precisionBits = ans.ransPrecisionBits;
1826
+ const precisionMask = ans.ransPrecisionMask;
1827
+ const probTable = ans.probTable;
1828
+ const cumProbTable = ans.cumProbTable;
1829
+ const lutTable = ans.lutTable;
1830
+ const bucketTable = ans.bucketTable;
1831
+ const bucketShift = ans.bucketShift;
1832
+ let state = ans.state;
1833
+ let ansOffset = ans.bufOffset;
1864
1834
  srcBuffer.startBitDecoding(false);
1865
1835
  const bd = srcBuffer.ka;
1866
- const buf = bd.Da;
1836
+ const buf = bd.Ea;
1867
1837
  const byteLength = bd.ja;
1868
- let bitOffset = bd.p;
1838
+ let bitOffset = bd.o;
1869
1839
  let valueId = 0;
1870
1840
  for (let i = 0; i < numValues; i += numComponents) {
1871
- const bitLength = tagAns.ransRead();
1841
+ while (state < lRansBase && ansOffset > ansStart) {
1842
+ state = state << 8 | ansBuf[--ansOffset];
1843
+ }
1844
+ const rem = state & precisionMask;
1845
+ let bitLength;
1846
+ if (lutTable !== null) {
1847
+ bitLength = lutTable[rem];
1848
+ } else {
1849
+ bitLength = bucketTable[rem >> bucketShift];
1850
+ while (cumProbTable[bitLength + 1] <= rem) bitLength++;
1851
+ }
1852
+ state = (state >>> precisionBits) * probTable[bitLength] + rem - cumProbTable[bitLength];
1872
1853
  if (bitLength < 32) {
1873
1854
  const mask = (1 << bitLength) - 1;
1874
1855
  let j = 0;
@@ -1884,7 +1865,7 @@ function decodeTaggedSymbols(numValues, numComponents, srcBuffer, outValues) {
1884
1865
  outValues[valueId++] = value & mask;
1885
1866
  }
1886
1867
  if (j === numComponents) continue;
1887
- bd.p = bitOffset;
1868
+ bd.o = bitOffset;
1888
1869
  for (; j < numComponents; ++j) {
1889
1870
  const val = bd.getBits(bitLength);
1890
1871
  if (val === void 0) {
@@ -1892,9 +1873,9 @@ function decodeTaggedSymbols(numValues, numComponents, srcBuffer, outValues) {
1892
1873
  }
1893
1874
  outValues[valueId++] = val;
1894
1875
  }
1895
- bitOffset = bd.p;
1876
+ bitOffset = bd.o;
1896
1877
  } else {
1897
- bd.p = bitOffset;
1878
+ bd.o = bitOffset;
1898
1879
  for (let j = 0; j < numComponents; ++j) {
1899
1880
  const val = bd.getBits(bitLength);
1900
1881
  if (val === void 0) {
@@ -1902,10 +1883,12 @@ function decodeTaggedSymbols(numValues, numComponents, srcBuffer, outValues) {
1902
1883
  }
1903
1884
  outValues[valueId++] = val;
1904
1885
  }
1905
- bitOffset = bd.p;
1886
+ bitOffset = bd.o;
1906
1887
  }
1907
1888
  }
1908
- bd.p = bitOffset;
1889
+ ans.state = state;
1890
+ ans.bufOffset = ansOffset;
1891
+ bd.o = bitOffset;
1909
1892
  tagDecoder.endDecoding();
1910
1893
  srcBuffer.endBitDecoding();
1911
1894
  return true;
@@ -1932,7 +1915,7 @@ function decodeRawSymbols(numValues, srcBuffer, outValues) {
1932
1915
  if (decoder === null) {
1933
1916
  return false;
1934
1917
  }
1935
- decoder.G.decodeSymbols(outValues, numValues);
1918
+ decoder.H.decodeSymbols(outValues, numValues);
1936
1919
  decoder.endDecoding();
1937
1920
  return true;
1938
1921
  }
@@ -1983,16 +1966,16 @@ var RAnsBitDecoder = class {
1983
1966
 
1984
1967
  // src/decoder/compression/attributes/prediction_schemes/PredictionSchemeDecoder.ts
1985
1968
  var PredictionSchemeDecoder = class {
1986
- e;
1969
+ d;
1987
1970
  constructor(transform) {
1988
- this.e = transform;
1971
+ this.d = transform;
1989
1972
  }
1990
1973
  /** True if all correction values are guaranteed to be positive. */
1991
1974
  areCorrectionsPositive() {
1992
- return this.e.areCorrectionsPositive();
1975
+ return this.d.areCorrectionsPositive();
1993
1976
  }
1994
1977
  boundsValues(limit) {
1995
- return this.e.boundsValues(limit);
1978
+ return this.d.boundsValues(limit);
1996
1979
  }
1997
1980
  getNumParentAttributes() {
1998
1981
  return 0;
@@ -2004,7 +1987,7 @@ var PredictionSchemeDecoder = class {
2004
1987
  return false;
2005
1988
  }
2006
1989
  decodePredictionData(buffer) {
2007
- return this.e.decodeTransformData(buffer);
1990
+ return this.d.decodeTransformData(buffer);
2008
1991
  }
2009
1992
  /**
2010
1993
  * Like computeOriginalValues, but inCorr still holds unsigned zigzag-coded
@@ -2080,12 +2063,12 @@ var MeshPredictionSchemeConstrainedMultiParallelogramDecoder = class extends Mes
2080
2063
  return super.decodePredictionData(buffer);
2081
2064
  }
2082
2065
  computeOriginalValues(inCorr, outData, _size, numComponents, _entryToPointIdMap) {
2083
- this.e.init(numComponents);
2066
+ this.d.init(numComponents);
2084
2067
  const predVals = [];
2085
2068
  for (let i = 0; i < MAX_NUM_PARALLELOGRAMS; ++i) {
2086
2069
  predVals.push(new Int32Array(numComponents));
2087
2070
  }
2088
- this.e.computeOriginalValue(predVals[0], 0, inCorr, 0, outData, 0);
2071
+ this.d.computeOriginalValue(predVals[0], 0, inCorr, 0, outData, 0);
2089
2072
  const table = this.b.cornerTable;
2090
2073
  const vertexToDataMap = this.b.vertexToDataMap;
2091
2074
  const oppositeCorners = table.oppositeCornerArray();
@@ -2144,12 +2127,12 @@ var MeshPredictionSchemeConstrainedMultiParallelogramDecoder = class extends Mes
2144
2127
  const dstOffset = p * numComponents;
2145
2128
  if (numUsedParallelograms === 0) {
2146
2129
  const srcOffset = (p - 1) * numComponents;
2147
- this.e.computeOriginalValue(outData, srcOffset, inCorr, dstOffset, outData, dstOffset);
2130
+ this.d.computeOriginalValue(outData, srcOffset, inCorr, dstOffset, outData, dstOffset);
2148
2131
  } else {
2149
2132
  for (let c = 0; c < numComponents; ++c) {
2150
2133
  multiPredVals[c] = multiPredVals[c] / numUsedParallelograms | 0;
2151
2134
  }
2152
- this.e.computeOriginalValue(multiPredVals, 0, inCorr, dstOffset, outData, dstOffset);
2135
+ this.d.computeOriginalValue(multiPredVals, 0, inCorr, dstOffset, outData, dstOffset);
2153
2136
  }
2154
2137
  }
2155
2138
  return true;
@@ -2218,38 +2201,38 @@ var MeshPredictionSchemeData = class {
2218
2201
 
2219
2202
  // src/decoder/compression/attributes/NormalCompressionUtils.ts
2220
2203
  var OctahedronToolBox = class {
2221
- L = -1;
2204
+ K = -1;
2222
2205
  aa = -1;
2223
- k = -1;
2206
+ l = -1;
2224
2207
  Vb = 1;
2225
- f = -1;
2208
+ e = -1;
2226
2209
  // q: quantization bits, valid range 2..30.
2227
2210
  setQuantizationBits(q) {
2228
2211
  if (q < 2 || q > 30) return false;
2229
- this.L = q;
2212
+ this.K = q;
2230
2213
  this.aa = (1 << q) - 1;
2231
- this.k = this.aa - 1;
2232
- this.Vb = Math.fround(2 / Math.fround(this.k));
2233
- this.f = this.k / 2 | 0;
2214
+ this.l = this.aa - 1;
2215
+ this.Vb = Math.fround(2 / Math.fround(this.l));
2216
+ this.e = this.l / 2 | 0;
2234
2217
  return true;
2235
2218
  }
2236
2219
  quantizationBits() {
2237
- return this.L;
2220
+ return this.K;
2238
2221
  }
2239
2222
  // Canonicalizes edge points into consistent quadrants. Writes result into
2240
2223
  // out[0], out[1] (caller-owned reusable 2-element array).
2241
2224
  canonicalizeOctahedralCoords(s, t, out) {
2242
- if (s === 0 && t === 0 || s === 0 && t === this.k || s === this.k && t === 0) {
2243
- s = this.k;
2244
- t = this.k;
2245
- } else if (s === 0 && t > this.f) {
2246
- t = this.f - (t - this.f);
2247
- } else if (s === this.k && t < this.f) {
2248
- t = this.f + (this.f - t);
2249
- } else if (t === this.k && s < this.f) {
2250
- s = this.f + (this.f - s);
2251
- } else if (t === 0 && s > this.f) {
2252
- s = this.f - (s - this.f);
2225
+ if (s === 0 && t === 0 || s === 0 && t === this.l || s === this.l && t === 0) {
2226
+ s = this.l;
2227
+ t = this.l;
2228
+ } else if (s === 0 && t > this.e) {
2229
+ t = this.e - (t - this.e);
2230
+ } else if (s === this.l && t < this.e) {
2231
+ t = this.e + (this.e - t);
2232
+ } else if (t === this.l && s < this.e) {
2233
+ s = this.e + (this.e - s);
2234
+ } else if (t === 0 && s > this.e) {
2235
+ s = this.e - (s - this.e);
2253
2236
  }
2254
2237
  out[0] = s;
2255
2238
  out[1] = t;
@@ -2259,18 +2242,18 @@ var OctahedronToolBox = class {
2259
2242
  integerVectorToQuantizedOctahedralCoords(intVec, out) {
2260
2243
  let s, t;
2261
2244
  if (intVec[0] >= 0) {
2262
- s = intVec[1] + this.f;
2263
- t = intVec[2] + this.f;
2245
+ s = intVec[1] + this.e;
2246
+ t = intVec[2] + this.e;
2264
2247
  } else {
2265
2248
  if (intVec[1] < 0) {
2266
2249
  s = Math.abs(intVec[2]);
2267
2250
  } else {
2268
- s = this.k - Math.abs(intVec[2]);
2251
+ s = this.l - Math.abs(intVec[2]);
2269
2252
  }
2270
2253
  if (intVec[2] < 0) {
2271
2254
  t = Math.abs(intVec[1]);
2272
2255
  } else {
2273
- t = this.k - Math.abs(intVec[1]);
2256
+ t = this.l - Math.abs(intVec[1]);
2274
2257
  }
2275
2258
  }
2276
2259
  this.canonicalizeOctahedralCoords(s, t, out);
@@ -2279,14 +2262,14 @@ var OctahedronToolBox = class {
2279
2262
  canonicalizeIntegerVector(vec) {
2280
2263
  const absSum = Math.abs(vec[0]) + Math.abs(vec[1]) + Math.abs(vec[2]);
2281
2264
  if (absSum === 0) {
2282
- vec[0] = this.f;
2265
+ vec[0] = this.e;
2283
2266
  } else {
2284
- vec[0] = Math.trunc(vec[0] * this.f / absSum);
2285
- vec[1] = Math.trunc(vec[1] * this.f / absSum);
2267
+ vec[0] = Math.trunc(vec[0] * this.e / absSum);
2268
+ vec[1] = Math.trunc(vec[1] * this.e / absSum);
2286
2269
  if (vec[2] >= 0) {
2287
- vec[2] = this.f - Math.abs(vec[0]) - Math.abs(vec[1]);
2270
+ vec[2] = this.e - Math.abs(vec[0]) - Math.abs(vec[1]);
2288
2271
  } else {
2289
- vec[2] = -(this.f - Math.abs(vec[0]) - Math.abs(vec[1]));
2272
+ vec[2] = -(this.e - Math.abs(vec[0]) - Math.abs(vec[1]));
2290
2273
  }
2291
2274
  }
2292
2275
  }
@@ -2296,38 +2279,23 @@ var OctahedronToolBox = class {
2296
2279
 
2297
2280
  // src/decoder/compression/attributes/prediction_schemes/MeshPredictionSchemeGeometricNormalPredictorArea.ts
2298
2281
  var UPPER_BOUND = 1 << 29;
2299
- function fillInt32PositionCache(cache, att, map, numEntries, tempPos) {
2300
- const bufData = att.buffer && att.buffer.data;
2301
- if (att.dataType === 5 /* INT32 */ && att.numComponents === 3 && bufData) {
2302
- const src = new Int32Array(bufData.buffer);
2303
- const srcStart = bufData.byteOffset + att.byteOffset >> 2;
2304
- const stride = att.byteStride >> 2;
2305
- const isIdentity = att.isMappingIdentity;
2306
- const indicesMap = att.indicesMap;
2307
- if (isIdentity) {
2308
- for (let d = 0; d < numEntries; ++d) {
2309
- const srcOffset = srcStart + map[d] * stride;
2310
- const o = d * 3;
2311
- cache[o] = src[srcOffset];
2312
- cache[o + 1] = src[srcOffset + 1];
2313
- cache[o + 2] = src[srcOffset + 2];
2314
- }
2315
- } else {
2316
- for (let d = 0; d < numEntries; ++d) {
2317
- const srcOffset = srcStart + indicesMap[map[d]] * stride;
2318
- const o = d * 3;
2319
- cache[o] = src[srcOffset];
2320
- cache[o + 1] = src[srcOffset + 1];
2321
- cache[o + 2] = src[srcOffset + 2];
2322
- }
2282
+ function fillInt32PositionCache(cache, att, map, numEntries) {
2283
+ const bytes = att.buffer.data;
2284
+ const src = new Int32Array(bytes.buffer, bytes.byteOffset, bytes.length >> 2);
2285
+ if (att.isMappingIdentity) {
2286
+ for (let d = 0, o = 0; d < numEntries; ++d, o += 3) {
2287
+ const s = map[d] * 3;
2288
+ cache[o] = src[s];
2289
+ cache[o + 1] = src[s + 1];
2290
+ cache[o + 2] = src[s + 2];
2323
2291
  }
2324
2292
  } else {
2325
- for (let d = 0; d < numEntries; ++d) {
2326
- att.convertValue(att.mappedIndex(map[d]), tempPos);
2327
- const o = d * 3;
2328
- cache[o] = tempPos[0];
2329
- cache[o + 1] = tempPos[1];
2330
- cache[o + 2] = tempPos[2];
2293
+ const indicesMap = att.indicesMap;
2294
+ for (let d = 0, o = 0; d < numEntries; ++d, o += 3) {
2295
+ const s = indicesMap[map[d]] * 3;
2296
+ cache[o] = src[s];
2297
+ cache[o + 1] = src[s + 1];
2298
+ cache[o + 2] = src[s + 2];
2331
2299
  }
2332
2300
  }
2333
2301
  }
@@ -2335,12 +2303,8 @@ var MeshPredictionSchemeGeometricNormalPredictorArea = class {
2335
2303
  qa = null;
2336
2304
  ra = null;
2337
2305
  b;
2338
- Va = new Array(3);
2339
- sa = null;
2340
- // flat Int32 positions, indexed by data id
2341
- o = null;
2342
- xb = null;
2343
- // corner -> posCache offset, precomputed
2306
+ // Per value: the area-weighted normal sum of its vertex's faces.
2307
+ vb = null;
2344
2308
  constructor(meshData) {
2345
2309
  this.b = meshData;
2346
2310
  }
@@ -2350,86 +2314,52 @@ var MeshPredictionSchemeGeometricNormalPredictorArea = class {
2350
2314
  setEntryToPointIdMap(map) {
2351
2315
  this.ra = map;
2352
2316
  }
2353
- buildPositionCache(numEntries) {
2354
- const posCache = scratchInt32(numEntries * 3);
2355
- fillInt32PositionCache(posCache, this.qa, this.ra, numEntries, this.Va);
2356
- this.sa = posCache;
2357
- const table = this.b.cornerTable;
2358
- const cornerToVertex = table.cornerToVertexArray();
2359
- this.o = table.oppositeCornerArray();
2317
+ // Sums every face's area vector into its corners' values (see above).
2318
+ computeNormalSums(numEntries) {
2319
+ const pos = scratchInt32(numEntries * 3);
2320
+ fillInt32PositionCache(pos, this.qa, this.ra, numEntries);
2321
+ const cornerToVertex = this.b.cornerTable.cornerToVertexArray();
2360
2322
  const vertexToDataMap = this.b.vertexToDataMap;
2361
- const nc = cornerToVertex.length;
2362
- const c2o = scratchInt32(nc);
2363
- for (let c = 0; c < nc; ++c) {
2364
- const v = cornerToVertex[c];
2365
- c2o[c] = v < 0 ? -1 : vertexToDataMap[v] * 3;
2366
- }
2367
- this.xb = c2o;
2368
- }
2369
- computePredictedValue(cornerId, prediction) {
2370
- const oppositeCorners = this.o;
2371
- const cornerToOffset = this.xb;
2372
- const posCache = this.sa;
2373
- const centerOffset = cornerToOffset[cornerId];
2374
- const centX = posCache[centerOffset];
2375
- const centY = posCache[centerOffset + 1];
2376
- const centZ = posCache[centerOffset + 2];
2377
- let normalX = 0, normalY = 0, normalZ = 0;
2378
- let currentCorner = cornerId;
2379
- let leftTraversal = true;
2380
- while (currentCorner >= 0) {
2381
- const rem = currentCorner - (currentCorner / 3 | 0) * 3;
2382
- const cNext = rem === 2 ? currentCorner - 2 : currentCorner + 1;
2383
- const cPrev = rem === 0 ? currentCorner + 2 : currentCorner - 1;
2384
- let posOffset = cornerToOffset[cNext];
2385
- const nextX = posCache[posOffset];
2386
- const nextY = posCache[posOffset + 1];
2387
- const nextZ = posCache[posOffset + 2];
2388
- posOffset = cornerToOffset[cPrev];
2389
- const prevX = posCache[posOffset];
2390
- const prevY = posCache[posOffset + 1];
2391
- const prevZ = posCache[posOffset + 2];
2392
- const dNextX = nextX - centX;
2393
- const dNextY = nextY - centY;
2394
- const dNextZ = nextZ - centZ;
2395
- const dPrevX = prevX - centX;
2396
- const dPrevY = prevY - centY;
2397
- const dPrevZ = prevZ - centZ;
2398
- normalX += dNextY * dPrevZ - dNextZ * dPrevY;
2399
- normalY += dNextZ * dPrevX - dNextX * dPrevZ;
2400
- normalZ += dNextX * dPrevY - dNextY * dPrevX;
2401
- if (leftTraversal) {
2402
- const opp = oppositeCorners[cNext];
2403
- if (opp < 0) {
2404
- currentCorner = -1;
2405
- } else {
2406
- const oppRem = opp - (opp / 3 | 0) * 3;
2407
- currentCorner = oppRem === 2 ? opp - 2 : opp + 1;
2408
- }
2409
- if (currentCorner < 0) {
2410
- const startRem = cornerId - (cornerId / 3 | 0) * 3;
2411
- const startPrev = startRem === 0 ? cornerId + 2 : cornerId - 1;
2412
- const startOpp = oppositeCorners[startPrev];
2413
- if (startOpp < 0) {
2414
- currentCorner = -1;
2415
- } else {
2416
- const startOppRem = startOpp - (startOpp / 3 | 0) * 3;
2417
- currentCorner = startOppRem === 0 ? startOpp + 2 : startOpp - 1;
2418
- }
2419
- leftTraversal = false;
2420
- } else if (currentCorner === cornerId) {
2421
- currentCorner = -1;
2422
- }
2423
- } else {
2424
- const opp = oppositeCorners[cPrev];
2425
- if (opp < 0) {
2426
- currentCorner = -1;
2427
- } else {
2428
- const oppRem = opp - (opp / 3 | 0) * 3;
2429
- currentCorner = oppRem === 0 ? opp + 2 : opp - 1;
2430
- }
2431
- }
2432
- }
2323
+ const sums = new Float64Array(numEntries * 3);
2324
+ const numCorners = cornerToVertex.length;
2325
+ for (let c = 0; c < numCorners; c += 3) {
2326
+ const v0 = cornerToVertex[c];
2327
+ const v1 = cornerToVertex[c + 1];
2328
+ const v2 = cornerToVertex[c + 2];
2329
+ if ((v0 | v1 | v2) < 0) return false;
2330
+ const o0 = vertexToDataMap[v0] * 3;
2331
+ const o1 = vertexToDataMap[v1] * 3;
2332
+ const o2 = vertexToDataMap[v2] * 3;
2333
+ const x0 = pos[o0];
2334
+ const y0 = pos[o0 + 1];
2335
+ const z0 = pos[o0 + 2];
2336
+ const ax = pos[o1] - x0;
2337
+ const ay = pos[o1 + 1] - y0;
2338
+ const az = pos[o1 + 2] - z0;
2339
+ const bx = pos[o2] - x0;
2340
+ const by = pos[o2 + 1] - y0;
2341
+ const bz = pos[o2 + 2] - z0;
2342
+ const nx = ay * bz - az * by;
2343
+ const ny = az * bx - ax * bz;
2344
+ const nz = ax * by - ay * bx;
2345
+ sums[o0] += nx;
2346
+ sums[o0 + 1] += ny;
2347
+ sums[o0 + 2] += nz;
2348
+ sums[o1] += nx;
2349
+ sums[o1 + 1] += ny;
2350
+ sums[o1 + 2] += nz;
2351
+ sums[o2] += nx;
2352
+ sums[o2 + 1] += ny;
2353
+ sums[o2 + 2] += nz;
2354
+ }
2355
+ this.vb = sums;
2356
+ return true;
2357
+ }
2358
+ computePredictedValue(dataId, prediction) {
2359
+ const sums = this.vb;
2360
+ let normalX = sums[dataId * 3];
2361
+ let normalY = sums[dataId * 3 + 1];
2362
+ let normalZ = sums[dataId * 3 + 2];
2433
2363
  const absSum = Math.abs(normalX) + Math.abs(normalY) + Math.abs(normalZ);
2434
2364
  if (absSum > UPPER_BOUND) {
2435
2365
  const quotient = Math.floor(absSum / UPPER_BOUND);
@@ -2446,12 +2376,12 @@ var MeshPredictionSchemeGeometricNormalPredictorArea = class {
2446
2376
  // src/decoder/compression/attributes/prediction_schemes/MeshPredictionSchemeGeometricNormalDecoder.ts
2447
2377
  var GEOMETRY_ATTRIBUTE_POSITION = 0;
2448
2378
  var MeshPredictionSchemeGeometricNormalDecoder = class extends MeshPredictionSchemeDecoder {
2449
- q;
2379
+ p;
2450
2380
  w = new OctahedronToolBox();
2451
- Wa = new RAnsBitDecoder();
2381
+ Ua = new RAnsBitDecoder();
2452
2382
  constructor(transform, meshData) {
2453
2383
  super(transform, meshData);
2454
- this.q = new MeshPredictionSchemeGeometricNormalPredictorArea(meshData);
2384
+ this.p = new MeshPredictionSchemeGeometricNormalPredictorArea(meshData);
2455
2385
  }
2456
2386
  getNumParentAttributes() {
2457
2387
  return 1;
@@ -2462,34 +2392,33 @@ var MeshPredictionSchemeGeometricNormalDecoder = class extends MeshPredictionSch
2462
2392
  setParentAttribute(att) {
2463
2393
  if (att.attributeType !== GEOMETRY_ATTRIBUTE_POSITION) return false;
2464
2394
  if (att.numComponents !== 3) return false;
2465
- this.q.setPositionAttribute(att);
2395
+ this.p.setPositionAttribute(att);
2466
2396
  return true;
2467
2397
  }
2468
2398
  decodePredictionData(buffer) {
2469
- if (!this.e.decodeTransformData(buffer)) return false;
2470
- return this.Wa.startDecoding(buffer);
2399
+ if (!this.d.decodeTransformData(buffer)) return false;
2400
+ return this.Ua.startDecoding(buffer);
2471
2401
  }
2472
2402
  computeOriginalValues(inCorr, outData, _size, _numComponents, entryToPointIdMap) {
2473
- this.w.setQuantizationBits(this.e.quantizationBits());
2474
- this.q.setEntryToPointIdMap(entryToPointIdMap);
2403
+ this.w.setQuantizationBits(this.d.quantizationBits());
2404
+ this.p.setEntryToPointIdMap(entryToPointIdMap);
2475
2405
  const cornerMapSize = this.b.dataToCornerMap.length;
2476
- this.q.buildPositionCache(cornerMapSize);
2406
+ if (!this.p.computeNormalSums(cornerMapSize)) return false;
2477
2407
  const predNormal3D = new Int32Array(3);
2478
2408
  const predNormalOct = new Int32Array(2);
2479
2409
  for (let dataId = 0; dataId < cornerMapSize; ++dataId) {
2480
- const cornerId = this.b.dataToCornerMap[dataId];
2481
- this.q.computePredictedValue(cornerId, predNormal3D);
2410
+ this.p.computePredictedValue(dataId, predNormal3D);
2482
2411
  this.w.canonicalizeIntegerVector(predNormal3D);
2483
- if (this.Wa.decodeNextBit()) {
2412
+ if (this.Ua.decodeNextBit()) {
2484
2413
  predNormal3D[0] = -predNormal3D[0];
2485
2414
  predNormal3D[1] = -predNormal3D[1];
2486
2415
  predNormal3D[2] = -predNormal3D[2];
2487
2416
  }
2488
2417
  this.w.integerVectorToQuantizedOctahedralCoords(predNormal3D, predNormalOct);
2489
2418
  const dataOffset = dataId * 2;
2490
- this.e.computeOriginalValue(predNormalOct, 0, inCorr, dataOffset, outData, dataOffset);
2419
+ this.d.computeOriginalValue(predNormalOct, 0, inCorr, dataOffset, outData, dataOffset);
2491
2420
  }
2492
- this.Wa.endDecoding();
2421
+ this.Ua.endDecoding();
2493
2422
  return true;
2494
2423
  }
2495
2424
  };
@@ -2498,10 +2427,10 @@ var MeshPredictionSchemeGeometricNormalDecoder = class extends MeshPredictionSch
2498
2427
  var kInvalidCornerIndex3 = -1;
2499
2428
  var MeshPredictionSchemeMultiParallelogramDecoder = class extends MeshPredictionSchemeDecoder {
2500
2429
  computeOriginalValues(inCorr, outData, _size, numComponents, _entryToPointIdMap) {
2501
- this.e.init(numComponents);
2430
+ this.d.init(numComponents);
2502
2431
  const predVals = new Int32Array(numComponents);
2503
2432
  const parallelogramPredVals = new Int32Array(numComponents);
2504
- this.e.computeOriginalValue(predVals, 0, inCorr, 0, outData, 0);
2433
+ this.d.computeOriginalValue(predVals, 0, inCorr, 0, outData, 0);
2505
2434
  const table = this.b.cornerTable;
2506
2435
  const vertexToDataMap = this.b.vertexToDataMap;
2507
2436
  const oppositeCorners = table.oppositeCornerArray();
@@ -2538,12 +2467,12 @@ var MeshPredictionSchemeMultiParallelogramDecoder = class extends MeshPrediction
2538
2467
  const dstOffset = p * numComponents;
2539
2468
  if (numParallelograms === 0) {
2540
2469
  const srcOffset = (p - 1) * numComponents;
2541
- this.e.computeOriginalValue(outData, srcOffset, inCorr, dstOffset, outData, dstOffset);
2470
+ this.d.computeOriginalValue(outData, srcOffset, inCorr, dstOffset, outData, dstOffset);
2542
2471
  } else {
2543
2472
  for (let c = 0; c < numComponents; ++c) {
2544
2473
  predVals[c] = predVals[c] / numParallelograms | 0;
2545
2474
  }
2546
- this.e.computeOriginalValue(predVals, 0, inCorr, dstOffset, outData, dstOffset);
2475
+ this.d.computeOriginalValue(predVals, 0, inCorr, dstOffset, outData, dstOffset);
2547
2476
  }
2548
2477
  }
2549
2478
  return true;
@@ -2555,7 +2484,7 @@ var MeshPredictionSchemeParallelogramDecoder = class extends MeshPredictionSchem
2555
2484
  // Zigzag-fused variant: decodes corrections that are still in their unsigned
2556
2485
  // zigzag form, unpacking each one inline.
2557
2486
  computeOriginalValuesZigzag(inCorr, outData, _size, numComponents, _entryToPointIdMap) {
2558
- this.e.init(numComponents);
2487
+ this.d.init(numComponents);
2559
2488
  return this.Wb(inCorr, outData, numComponents, true);
2560
2489
  }
2561
2490
  // The wrap transform's corrections are zigzag-coded; with `zigzag` set the
@@ -2575,9 +2504,9 @@ var MeshPredictionSchemeParallelogramDecoder = class extends MeshPredictionSchem
2575
2504
  return this.Zb(inCorr, outData, zigzag);
2576
2505
  }
2577
2506
  const parents = this.b.parallelogramParents();
2578
- const transform = this.e;
2579
- const minValue = transform.T;
2580
- const maxValue = transform.k;
2507
+ const transform = this.d;
2508
+ const minValue = transform.W;
2509
+ const maxValue = transform.l;
2581
2510
  const maxDif = transform.ba;
2582
2511
  for (let c = 0; c < numComponents; ++c) {
2583
2512
  let pred = 0;
@@ -2643,9 +2572,9 @@ var MeshPredictionSchemeParallelogramDecoder = class extends MeshPredictionSchem
2643
2572
  }
2644
2573
  Xb(inCorr, outData, zigzag) {
2645
2574
  const parents = this.b.parallelogramParents();
2646
- const transform = this.e;
2647
- const minValue = transform.T;
2648
- const maxValue = transform.k;
2575
+ const transform = this.d;
2576
+ const minValue = transform.W;
2577
+ const maxValue = transform.l;
2649
2578
  const maxDif = transform.ba;
2650
2579
  let pred0 = 0;
2651
2580
  let pred1 = 0;
@@ -2721,9 +2650,9 @@ var MeshPredictionSchemeParallelogramDecoder = class extends MeshPredictionSchem
2721
2650
  }
2722
2651
  Yb(inCorr, outData, zigzag) {
2723
2652
  const parents = this.b.parallelogramParents();
2724
- const transform = this.e;
2725
- const minValue = transform.T;
2726
- const maxValue = transform.k;
2653
+ const transform = this.d;
2654
+ const minValue = transform.W;
2655
+ const maxValue = transform.l;
2727
2656
  const maxDif = transform.ba;
2728
2657
  let pred0 = 0;
2729
2658
  let pred1 = 0;
@@ -2830,9 +2759,9 @@ var MeshPredictionSchemeParallelogramDecoder = class extends MeshPredictionSchem
2830
2759
  // structure as the 2/3-component loops.
2831
2760
  Zb(inCorr, outData, zigzag) {
2832
2761
  const parents = this.b.parallelogramParents();
2833
- const transform = this.e;
2834
- const minValue = transform.T;
2835
- const maxValue = transform.k;
2762
+ const transform = this.d;
2763
+ const minValue = transform.W;
2764
+ const maxValue = transform.l;
2836
2765
  const maxDif = transform.ba;
2837
2766
  let pred0 = 0;
2838
2767
  if (pred0 > maxValue) {
@@ -2938,14 +2867,13 @@ function bigIntSqrt(value) {
2938
2867
  var MeshPredictionSchemeTexCoordsPortablePredictor = class {
2939
2868
  qa = null;
2940
2869
  ra = null;
2941
- r = new Int32Array(2);
2942
- Ja = new Uint8Array(0);
2943
- ta = 0;
2870
+ q = new Int32Array(2);
2871
+ Ja = EMPTY_UINT8;
2872
+ sa = 0;
2944
2873
  b;
2945
- Va = new Array(3);
2946
2874
  // Flat Int32 position cache so fetches are array reads, not convertValue calls.
2947
- sa = null;
2948
- h = null;
2875
+ wb = null;
2876
+ i = null;
2949
2877
  constructor(meshData) {
2950
2878
  this.b = meshData;
2951
2879
  }
@@ -2956,26 +2884,26 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
2956
2884
  this.ra = map;
2957
2885
  }
2958
2886
  get predictedValue() {
2959
- return this.r;
2887
+ return this.q;
2960
2888
  }
2961
2889
  resizeOrientations(numOrientations) {
2962
2890
  this.Ja = new Uint8Array(numOrientations);
2963
- this.ta = numOrientations;
2891
+ this.sa = numOrientations;
2964
2892
  }
2965
2893
  setOrientation(i, v) {
2966
2894
  this.Ja[i] = v ? 1 : 0;
2967
2895
  }
2968
2896
  buildPositionCache(numEntries) {
2969
2897
  const posCache = new Int32Array(numEntries * 3);
2970
- fillInt32PositionCache(posCache, this.qa, this.ra, numEntries, this.Va);
2971
- this.sa = posCache;
2972
- this.h = this.b.cornerTable.cornerToVertexArray();
2898
+ fillInt32PositionCache(posCache, this.qa, this.ra, numEntries);
2899
+ this.wb = posCache;
2900
+ this.i = this.b.cornerTable.cornerToVertexArray();
2973
2901
  }
2974
2902
  computePredictedValue(cornerId, data, dataId) {
2975
2903
  const rem = cornerId - (cornerId / 3 | 0) * 3;
2976
2904
  const nextCornerId = rem === 2 ? cornerId - 2 : cornerId + 1;
2977
2905
  const prevCornerId = rem === 0 ? cornerId + 2 : cornerId - 1;
2978
- const cornerToVertex = this.h;
2906
+ const cornerToVertex = this.i;
2979
2907
  const nextVertId = cornerToVertex[nextCornerId];
2980
2908
  const prevVertId = cornerToVertex[prevCornerId];
2981
2909
  const vertexToDataMap = this.b.vertexToDataMap;
@@ -2987,11 +2915,11 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
2987
2915
  const nUV0 = data[nDataOff], nUV1 = data[nDataOff + 1];
2988
2916
  const pUV0 = data[pDataOff], pUV1 = data[pDataOff + 1];
2989
2917
  if (pUV0 === nUV0 && pUV1 === nUV1) {
2990
- this.r[0] = pUV0;
2991
- this.r[1] = pUV1;
2918
+ this.q[0] = pUV0;
2919
+ this.q[1] = pUV1;
2992
2920
  return true;
2993
2921
  }
2994
- const posCache = this.sa;
2922
+ const posCache = this.wb;
2995
2923
  let posOffset = dataId * 3;
2996
2924
  const tip0 = posCache[posOffset];
2997
2925
  const tip1 = posCache[posOffset + 1];
@@ -3015,19 +2943,12 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
3015
2943
  const cnDotPn = pn0 * cn0 + pn1 * cn1 + pn2 * cn2;
3016
2944
  const pnUV0 = pUV0 - nUV0;
3017
2945
  const pnUV1 = pUV1 - nUV1;
3018
- const INT64_MAX = 2 ** 63;
3019
2946
  const nUVAbsMax = Math.max(Math.abs(nUV0), Math.abs(nUV1));
3020
- if (nUVAbsMax > INT64_MAX / pnNorm2Squared) {
3021
- return false;
3022
- }
3023
2947
  const pnUVAbsMax = Math.max(Math.abs(pnUV0), Math.abs(pnUV1));
3024
- if (pnUVAbsMax > 0 && Math.abs(cnDotPn) > INT64_MAX / pnUVAbsMax) {
3025
- return false;
3026
- }
3027
2948
  const cnNorm2 = cn0 * cn0 + cn1 * cn1 + cn2 * cn2;
3028
2949
  const pnAbsMaxG = Math.max(Math.abs(pn0), Math.abs(pn1), Math.abs(pn2));
3029
2950
  const cnDotPnAbs = Math.abs(cnDotPn);
3030
- if (cnNorm2 > SAFE_PRODUCT / pnNorm2Squared || nUVAbsMax > SAFE_PRODUCT / pnNorm2Squared || pnUVAbsMax > 0 && cnDotPnAbs > SAFE_PRODUCT / pnUVAbsMax || pnAbsMaxG > 0 && cnDotPnAbs > SAFE_PRODUCT / pnAbsMaxG) {
2951
+ if (!(cnNorm2 * pnNorm2Squared < SAFE_PRODUCT && nUVAbsMax * pnNorm2Squared < SAFE_PRODUCT && cnDotPnAbs * pnUVAbsMax < SAFE_PRODUCT && cnDotPnAbs * pnAbsMaxG < SAFE_PRODUCT)) {
3031
2952
  return this._b(
3032
2953
  tip0,
3033
2954
  tip1,
@@ -3047,9 +2968,6 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
3047
2968
  }
3048
2969
  const xUV0 = nUV0 * pnNorm2Squared + cnDotPn * pnUV0;
3049
2970
  const xUV1 = nUV1 * pnNorm2Squared + cnDotPn * pnUV1;
3050
- if (pnAbsMaxG > 0 && cnDotPnAbs > INT64_MAX / pnAbsMaxG) {
3051
- return false;
3052
- }
3053
2971
  const xPos0 = next0 + Math.trunc(cnDotPn * pn0 / pnNorm2Squared);
3054
2972
  const xPos1 = next1 + Math.trunc(cnDotPn * pn1 / pnNorm2Squared);
3055
2973
  const xPos2 = next2 + Math.trunc(cnDotPn * pn2 / pnNorm2Squared);
@@ -3060,16 +2978,16 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
3060
2978
  const normSquared = Math.floor(Math.sqrt(cxNorm2Squared * pnNorm2Squared));
3061
2979
  const cxUV0 = pnUV1 * normSquared;
3062
2980
  const cxUV1 = -pnUV0 * normSquared;
3063
- if (this.ta === 0) {
2981
+ if (this.sa === 0) {
3064
2982
  return false;
3065
2983
  }
3066
- const orientation = this.Ja[--this.ta];
2984
+ const orientation = this.Ja[--this.sa];
3067
2985
  if (orientation) {
3068
- this.r[0] = Math.trunc((xUV0 + cxUV0) / pnNorm2Squared);
3069
- this.r[1] = Math.trunc((xUV1 + cxUV1) / pnNorm2Squared);
2986
+ this.q[0] = Math.trunc((xUV0 + cxUV0) / pnNorm2Squared);
2987
+ this.q[1] = Math.trunc((xUV1 + cxUV1) / pnNorm2Squared);
3070
2988
  } else {
3071
- this.r[0] = Math.trunc((xUV0 - cxUV0) / pnNorm2Squared);
3072
- this.r[1] = Math.trunc((xUV1 - cxUV1) / pnNorm2Squared);
2989
+ this.q[0] = Math.trunc((xUV0 - cxUV0) / pnNorm2Squared);
2990
+ this.q[1] = Math.trunc((xUV1 - cxUV1) / pnNorm2Squared);
3073
2991
  }
3074
2992
  return true;
3075
2993
  }
@@ -3084,13 +3002,13 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
3084
3002
  if (dataId > 0) {
3085
3003
  dataOffset = (dataId - 1) * 2;
3086
3004
  } else {
3087
- this.r[0] = 0;
3088
- this.r[1] = 0;
3005
+ this.q[0] = 0;
3006
+ this.q[1] = 0;
3089
3007
  return true;
3090
3008
  }
3091
3009
  }
3092
- this.r[0] = data[dataOffset];
3093
- this.r[1] = data[dataOffset + 1];
3010
+ this.q[0] = data[dataOffset];
3011
+ this.q[1] = data[dataOffset + 1];
3094
3012
  return true;
3095
3013
  }
3096
3014
  // 64-bit-exact projection prediction, used when the double path would lose
@@ -3132,8 +3050,8 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
3132
3050
  const normSquared = bigIntSqrt(cxNorm2 * pnN2 & MASK64);
3133
3051
  const cxUV0 = B.asIntN(64, pnUV1 * normSquared);
3134
3052
  const cxUV1 = B.asIntN(64, -pnUV0 * normSquared);
3135
- if (this.ta === 0) return false;
3136
- const orientation = this.Ja[--this.ta];
3053
+ if (this.sa === 0) return false;
3054
+ const orientation = this.Ja[--this.sa];
3137
3055
  let s0, s1;
3138
3056
  if (orientation) {
3139
3057
  s0 = B.asUintN(64, B.asUintN(64, xUV0) + B.asUintN(64, cxUV0));
@@ -3142,8 +3060,8 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
3142
3060
  s0 = B.asUintN(64, B.asUintN(64, xUV0) - B.asUintN(64, cxUV0));
3143
3061
  s1 = B.asUintN(64, B.asUintN(64, xUV1) - B.asUintN(64, cxUV1));
3144
3062
  }
3145
- this.r[0] = Number(B.asIntN(32, B.asIntN(64, s0) / pnN2));
3146
- this.r[1] = Number(B.asIntN(32, B.asIntN(64, s1) / pnN2));
3063
+ this.q[0] = Number(B.asIntN(32, B.asIntN(64, s0) / pnN2));
3064
+ this.q[1] = Number(B.asIntN(32, B.asIntN(64, s1) / pnN2));
3147
3065
  return true;
3148
3066
  }
3149
3067
  };
@@ -3151,10 +3069,10 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
3151
3069
  // src/decoder/compression/attributes/prediction_schemes/MeshPredictionSchemeTexCoordsPortableDecoder.ts
3152
3070
  var GEOMETRY_ATTRIBUTE_POSITION2 = 0;
3153
3071
  var MeshPredictionSchemeTexCoordsPortableDecoder = class extends MeshPredictionSchemeDecoder {
3154
- q;
3072
+ p;
3155
3073
  constructor(transform, meshData) {
3156
3074
  super(transform, meshData);
3157
- this.q = new MeshPredictionSchemeTexCoordsPortablePredictor(meshData);
3075
+ this.p = new MeshPredictionSchemeTexCoordsPortablePredictor(meshData);
3158
3076
  }
3159
3077
  getNumParentAttributes() {
3160
3078
  return 1;
@@ -3165,13 +3083,13 @@ var MeshPredictionSchemeTexCoordsPortableDecoder = class extends MeshPredictionS
3165
3083
  setParentAttribute(att) {
3166
3084
  if (att.attributeType !== GEOMETRY_ATTRIBUTE_POSITION2) return false;
3167
3085
  if (att.numComponents !== 3) return false;
3168
- this.q.setPositionAttribute(att);
3086
+ this.p.setPositionAttribute(att);
3169
3087
  return true;
3170
3088
  }
3171
3089
  decodePredictionData(buffer) {
3172
3090
  const numOrientations = buffer.decodeInt32();
3173
3091
  if (numOrientations === void 0 || numOrientations < 0) return false;
3174
- this.q.resizeOrientations(numOrientations);
3092
+ this.p.resizeOrientations(numOrientations);
3175
3093
  let lastOrientation = true;
3176
3094
  const decoder = new RAnsBitDecoder();
3177
3095
  if (!decoder.startDecoding(buffer)) return false;
@@ -3179,7 +3097,7 @@ var MeshPredictionSchemeTexCoordsPortableDecoder = class extends MeshPredictionS
3179
3097
  if (!decoder.decodeNextBit()) {
3180
3098
  lastOrientation = !lastOrientation;
3181
3099
  }
3182
- this.q.setOrientation(i, lastOrientation);
3100
+ this.p.setOrientation(i, lastOrientation);
3183
3101
  }
3184
3102
  decoder.endDecoding();
3185
3103
  return super.decodePredictionData(buffer);
@@ -3188,17 +3106,17 @@ var MeshPredictionSchemeTexCoordsPortableDecoder = class extends MeshPredictionS
3188
3106
  if (numComponents !== 2) {
3189
3107
  return false;
3190
3108
  }
3191
- this.q.setEntryToPointIdMap(entryToPointIdMap);
3192
- this.e.init(numComponents);
3109
+ this.p.setEntryToPointIdMap(entryToPointIdMap);
3110
+ this.d.init(numComponents);
3193
3111
  const cornerMapSize = this.b.dataToCornerMap.length;
3194
- this.q.buildPositionCache(cornerMapSize);
3112
+ this.p.buildPositionCache(cornerMapSize);
3195
3113
  for (let p = 0; p < cornerMapSize; ++p) {
3196
3114
  const cornerId = this.b.dataToCornerMap[p];
3197
- if (!this.q.computePredictedValue(cornerId, outData, p)) {
3115
+ if (!this.p.computePredictedValue(cornerId, outData, p)) {
3198
3116
  return false;
3199
3117
  }
3200
3118
  const dstOffset = p * numComponents;
3201
- this.e.computeOriginalValue(this.q.predictedValue, 0, inCorr, dstOffset, outData, dstOffset);
3119
+ this.d.computeOriginalValue(this.p.predictedValue, 0, inCorr, dstOffset, outData, dstOffset);
3202
3120
  }
3203
3121
  return true;
3204
3122
  }
@@ -3207,7 +3125,7 @@ var MeshPredictionSchemeTexCoordsPortableDecoder = class extends MeshPredictionS
3207
3125
  // src/decoder/compression/attributes/prediction_schemes/PredictionSchemeDeltaDecoder.ts
3208
3126
  var PredictionSchemeDeltaDecoder = class extends PredictionSchemeDecoder {
3209
3127
  computeOriginalValues(inCorr, outData, size, numComponents, _entryToPointIdMap) {
3210
- const transform = this.e;
3128
+ const transform = this.d;
3211
3129
  transform.init(numComponents);
3212
3130
  if (transform.computeOriginalValuesDelta) {
3213
3131
  transform.computeOriginalValuesDelta(inCorr, outData, size, numComponents);
@@ -3263,8 +3181,8 @@ function createPredictionSchemeForDecoder(method, attId, decoder, transform) {
3263
3181
  // src/decoder/compression/attributes/prediction_schemes/PredictionSchemeWrapDecodingTransform.ts
3264
3182
  var PredictionSchemeWrapDecodingTransform = class {
3265
3183
  v = 0;
3266
- T = 0;
3267
- k = 0;
3184
+ W = 0;
3185
+ l = 0;
3268
3186
  ba = 0;
3269
3187
  getType() {
3270
3188
  return 1 /* PREDICTION_TRANSFORM_WRAP */;
@@ -3276,12 +3194,12 @@ var PredictionSchemeWrapDecodingTransform = class {
3276
3194
  return false;
3277
3195
  }
3278
3196
  boundsValues(limit) {
3279
- return this.k < limit && this.T > -limit;
3197
+ return this.l < limit && this.W > -limit;
3280
3198
  }
3281
3199
  computeOriginalValue(predictedVals, predictedOffset, corrVals, corrOffset, outOriginalVals, outOffset) {
3282
3200
  const nc = this.v;
3283
- const minValue = this.T;
3284
- const maxValue = this.k;
3201
+ const minValue = this.W;
3202
+ const maxValue = this.l;
3285
3203
  const maxDif = this.ba;
3286
3204
  for (let i = 0; i < nc; ++i) {
3287
3205
  let pred = predictedVals[predictedOffset + i];
@@ -3306,8 +3224,8 @@ var PredictionSchemeWrapDecodingTransform = class {
3306
3224
  if (maxValue === void 0) return false;
3307
3225
  const dif = maxValue - minValue;
3308
3226
  if (dif < 0 || dif >= 2147483647) return false;
3309
- this.T = minValue;
3310
- this.k = maxValue;
3227
+ this.W = minValue;
3228
+ this.l = maxValue;
3311
3229
  this.ba = 1 + dif;
3312
3230
  return true;
3313
3231
  }
@@ -3315,25 +3233,27 @@ var PredictionSchemeWrapDecodingTransform = class {
3315
3233
 
3316
3234
  // src/decoder/compression/attributes/SequentialIntegerAttributeDecoder.ts
3317
3235
  var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder {
3318
- M = null;
3236
+ L = null;
3319
3237
  // Two-phase decode state (see SequentialAttributeDecoder): the parse phase
3320
3238
  // stashes the primed raw-symbol stream here so the controller can batch and
3321
3239
  // pair several attributes' decodes; the finish phase consumes it.
3322
3240
  ca = null;
3323
- Xa = 0;
3324
- yb = null;
3325
- // Int32 view over the portable attribute's storage (see preparePortableAttribute).
3326
- U = null;
3241
+ Va = 0;
3242
+ xb = null;
3243
+ // The decoded (portable) values, numComponents per entry (see
3244
+ // preparePortableAttribute).
3245
+ M = null;
3246
+ yb = 0;
3327
3247
  // --- Two-phase decode (parse headers / batch symbol decode / finish) ---
3328
3248
  pendingSymbolStream() {
3329
3249
  if (this.ca === null) {
3330
3250
  return null;
3331
3251
  }
3332
- const portableData = this.U;
3252
+ const portableData = this.M;
3333
3253
  return {
3334
- ans: this.ca.G,
3335
- out: new Uint32Array(portableData.buffer, portableData.byteOffset, this.Xa),
3336
- count: this.Xa
3254
+ ans: this.ca.H,
3255
+ out: new Uint32Array(portableData.buffer, portableData.byteOffset, this.Va),
3256
+ count: this.Va
3337
3257
  };
3338
3258
  }
3339
3259
  decodePortableAttributeFinish() {
@@ -3341,13 +3261,13 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
3341
3261
  this.ca.endDecoding();
3342
3262
  this.ca = null;
3343
3263
  }
3344
- return this.$b(this.yb);
3264
+ return this.$b(this.xb);
3345
3265
  }
3346
3266
  // The parse phase of the integer decode: prediction scheme, portable
3347
3267
  // attribute, the symbol stream (raw streams are deferred to the finish
3348
3268
  // phase) and the prediction data.
3349
3269
  decodeValues(pointIds, buffer) {
3350
- this.yb = pointIds;
3270
+ this.xb = pointIds;
3351
3271
  let predictionSchemeMethod = buffer.decodeUint8();
3352
3272
  if (predictionSchemeMethod !== void 0) predictionSchemeMethod = predictionSchemeMethod << 24 >> 24;
3353
3273
  if (predictionSchemeMethod === void 0) return false;
@@ -3361,10 +3281,10 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
3361
3281
  if (predictionTransformType < -1 /* PREDICTION_TRANSFORM_NONE */ || predictionTransformType >= 4 /* NUM_PREDICTION_SCHEME_TRANSFORM_TYPES */) {
3362
3282
  return false;
3363
3283
  }
3364
- this.M = this.createIntPredictionScheme(predictionSchemeMethod, predictionTransformType);
3284
+ this.L = this.createIntPredictionScheme(predictionSchemeMethod, predictionTransformType);
3365
3285
  }
3366
- if (this.M) {
3367
- if (!this.initPredictionScheme(this.M)) {
3286
+ if (this.L) {
3287
+ if (!this.initPredictionScheme(this.L)) {
3368
3288
  return false;
3369
3289
  }
3370
3290
  }
@@ -3375,7 +3295,7 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
3375
3295
  const numEntries = pointIds.length;
3376
3296
  const numValues = numEntries * numComponents;
3377
3297
  this.preparePortableAttribute(numEntries, numComponents);
3378
- const portableAttributeData = this.U;
3298
+ const portableAttributeData = this.M;
3379
3299
  if (portableAttributeData === null) {
3380
3300
  return false;
3381
3301
  }
@@ -3390,7 +3310,7 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
3390
3310
  return false;
3391
3311
  }
3392
3312
  this.ca = decoder;
3393
- this.Xa = numValues;
3313
+ this.Va = numValues;
3394
3314
  } else if (scheme === 0 /* SYMBOL_CODING_TAGGED */) {
3395
3315
  const outUint32 = new Uint32Array(portableAttributeData.buffer, portableAttributeData.byteOffset, numValues);
3396
3316
  if (!decodeTaggedSymbols(numValues, numComponents, buffer, outUint32)) {
@@ -3414,8 +3334,8 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
3414
3334
  portableAttributeData[i] = val;
3415
3335
  }
3416
3336
  }
3417
- if (this.M) {
3418
- if (!this.M.decodePredictionData(buffer)) {
3337
+ if (this.L) {
3338
+ if (!this.L.decodePredictionData(buffer)) {
3419
3339
  return false;
3420
3340
  }
3421
3341
  }
@@ -3425,14 +3345,14 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
3425
3345
  $b(pointIds) {
3426
3346
  const numComponents = this.getNumValueComponents();
3427
3347
  const numValues = pointIds.length * numComponents;
3428
- const data = this.U;
3348
+ const data = this.M;
3429
3349
  if (data === null) {
3430
3350
  return false;
3431
3351
  }
3432
3352
  if (numValues === 0) {
3433
3353
  return true;
3434
3354
  }
3435
- const ps = this.M;
3355
+ const ps = this.L;
3436
3356
  if (ps === null) {
3437
3357
  convertSymbolsToSignedInts(new Uint32Array(data.buffer, data.byteOffset, numValues), numValues, data);
3438
3358
  return true;
@@ -3447,7 +3367,7 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
3447
3367
  return ps.computeOriginalValues(data, data, numValues, numComponents, pointIds);
3448
3368
  }
3449
3369
  transformAttributeToOriginalFormat(pointIds) {
3450
- return this.Ya(pointIds.length);
3370
+ return this.Wa(pointIds.length);
3451
3371
  }
3452
3372
  // Prediction scheme for decoding integer values; subclasses override for others.
3453
3373
  createIntPredictionScheme(method, transformType) {
@@ -3465,43 +3385,59 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
3465
3385
  // see PointAttribute._lazyFloatValues): true when a prediction transform
3466
3386
  // clamps them into such a range. Unpredicted values are unbounded.
3467
3387
  zb() {
3468
- return this.M !== null && this.M.boundsValues(16777216);
3388
+ return this.L !== null && this.L.boundsValues(16777216);
3469
3389
  }
3470
3390
  // The decoded values stay in the portable attribute; the final attribute
3471
3391
  // only takes its size (see PointAttribute.setLazyInteger and the overrides
3472
3392
  // in the quantization / normal decoders).
3473
- vb(numValues) {
3393
+ tb(numValues) {
3474
3394
  this.attribute.resetLazy(numValues);
3475
3395
  return true;
3476
3396
  }
3477
3397
  // Hands the decoded integer values to the attribute, converted to its
3478
3398
  // integer type on extraction.
3479
- Ya(_numValues) {
3399
+ Wa(_numValues) {
3480
3400
  const dt = this.attribute.dataType;
3481
3401
  if (dt < 1 /* INT8 */ || dt > 6 /* UINT32 */) {
3482
3402
  return false;
3483
3403
  }
3484
- this.attribute.setLazyInteger(this.U);
3404
+ this.attribute.setLazyInteger(this.M);
3485
3405
  return true;
3486
3406
  }
3407
+ // Heap-backed: the decoded values are what the final attribute hands out
3408
+ // (see _storeValues), so they outlive the decode. The portable
3409
+ // PointAttribute around them is only built if a dependent attribute's
3410
+ // predictor asks for it (see getPortableAttribute).
3487
3411
  preparePortableAttribute(numEntries, numComponents) {
3488
- const ga = new GeometryAttribute();
3489
- ga.init(
3490
- this.attribute.attributeType,
3491
- null,
3492
- numComponents,
3493
- 5 /* INT32 */,
3494
- false,
3495
- numComponents * dataTypeLength(5 /* INT32 */),
3496
- 0
3497
- );
3498
- const portAtt = new PointAttribute(ga);
3499
- portAtt.setIdentityMapping();
3500
- portAtt.reset(numEntries);
3501
- portAtt.uniqueId = this.attribute.uniqueId;
3502
- this.$ = portAtt;
3503
- const data = portAtt.buffer.data;
3504
- this.U = numEntries === 0 ? null : new Int32Array(data.buffer, data.byteOffset + portAtt.byteOffset, numEntries * numComponents);
3412
+ this.yb = numComponents;
3413
+ this.M = numEntries === 0 ? null : new Int32Array(numEntries * numComponents);
3414
+ }
3415
+ getPortableAttribute() {
3416
+ const numComponents = this.yb;
3417
+ if (this.V === null && numComponents > 0) {
3418
+ const ga = new GeometryAttribute();
3419
+ ga.init(
3420
+ this.attribute.attributeType,
3421
+ null,
3422
+ numComponents,
3423
+ 5 /* INT32 */,
3424
+ false,
3425
+ numComponents * dataTypeLength(5 /* INT32 */),
3426
+ 0
3427
+ );
3428
+ const portAtt = new PointAttribute(ga);
3429
+ portAtt.setIdentityMapping();
3430
+ const data = this.M;
3431
+ if (data === null) portAtt.reset(0);
3432
+ else
3433
+ portAtt.resetWithData(
3434
+ new Uint8Array(data.buffer, data.byteOffset, data.byteLength),
3435
+ data.length / numComponents
3436
+ );
3437
+ portAtt.uniqueId = this.attribute.uniqueId;
3438
+ this.V = portAtt;
3439
+ }
3440
+ return super.getPortableAttribute();
3505
3441
  }
3506
3442
  };
3507
3443
 
@@ -3549,7 +3485,7 @@ var PredictionSchemeNormalOctahedronCanonicalizedDecodingTransform = class exten
3549
3485
  }
3550
3486
  computeOriginalValue(predVals, predOffset, corrVals, corrOffset, outOrigVals, outOffset) {
3551
3487
  const toolBox = this.w;
3552
- const center = toolBox.f;
3488
+ const center = toolBox.e;
3553
3489
  const maxQuantizedValue = toolBox.aa;
3554
3490
  const corrS = corrVals[corrOffset];
3555
3491
  const corrT = corrVals[corrOffset + 1];
@@ -3677,7 +3613,7 @@ var PredictionSchemeNormalOctahedronCanonicalizedDecodingTransform = class exten
3677
3613
  // sync; only the plumbing differs.
3678
3614
  computeOriginalValuesDelta(inCorr, outData, size, numComponents) {
3679
3615
  const toolBox = this.w;
3680
- const center = toolBox.f;
3616
+ const center = toolBox.e;
3681
3617
  const maxQuantizedValue = toolBox.aa;
3682
3618
  let prevS = 0;
3683
3619
  let prevT = 0;
@@ -3816,7 +3752,7 @@ var PredictionSchemeNormalOctahedronDecodingTransform = class extends Prediction
3816
3752
  }
3817
3753
  computeOriginalValue(predVals, predOffset, corrVals, corrOffset, outOrigVals, outOffset) {
3818
3754
  const toolBox = this.w;
3819
- const center = toolBox.f;
3755
+ const center = toolBox.e;
3820
3756
  const maxQuantizedValue = toolBox.aa;
3821
3757
  const predS = predVals[predOffset] - center;
3822
3758
  const predT = predVals[predOffset + 1] - center;
@@ -3896,7 +3832,7 @@ var PredictionSchemeNormalOctahedronDecodingTransform = class extends Prediction
3896
3832
 
3897
3833
  // src/decoder/compression/attributes/SequentialNormalAttributeDecoder.ts
3898
3834
  var SequentialNormalAttributeDecoder = class extends SequentialIntegerAttributeDecoder {
3899
- L = -1;
3835
+ K = -1;
3900
3836
  init(decoder, attributeId) {
3901
3837
  if (!super.init(decoder, attributeId)) {
3902
3838
  return false;
@@ -3911,16 +3847,16 @@ var SequentialNormalAttributeDecoder = class extends SequentialIntegerAttributeD
3911
3847
  decodeDataNeededByPortableTransform(_pointIds, buffer) {
3912
3848
  const qBits = buffer.decodeUint8();
3913
3849
  if (qBits === void 0) return false;
3914
- this.L = qBits;
3850
+ this.K = qBits;
3915
3851
  return true;
3916
3852
  }
3917
3853
  // The octahedral-to-unit-vector transform is deferred to extractTo (see
3918
3854
  // PointAttribute.setLazyOctahedron).
3919
- Ya(_numPoints) {
3920
- const q = this.L;
3855
+ Wa(_numPoints) {
3856
+ const q = this.K;
3921
3857
  if (q < 2 || q > 30) return false;
3922
3858
  this.attribute.setLazyOctahedron(
3923
- this.U,
3859
+ this.M,
3924
3860
  Math.fround(2 / Math.fround((1 << q) - 2)),
3925
3861
  this.zb()
3926
3862
  );
@@ -3937,8 +3873,8 @@ var SequentialNormalAttributeDecoder = class extends SequentialIntegerAttributeD
3937
3873
 
3938
3874
  // src/decoder/compression/attributes/SequentialQuantizationAttributeDecoder.ts
3939
3875
  var SequentialQuantizationAttributeDecoder = class extends SequentialIntegerAttributeDecoder {
3940
- L = -1;
3941
- Za = [];
3876
+ K = -1;
3877
+ Xa = [];
3942
3878
  Bb = 0;
3943
3879
  init(decoder, attributeId) {
3944
3880
  if (!super.init(decoder, attributeId)) {
@@ -3949,39 +3885,39 @@ var SequentialQuantizationAttributeDecoder = class extends SequentialIntegerAttr
3949
3885
  // The quantization parameters (AttributeQuantizationTransform::DecodeParameters).
3950
3886
  decodeDataNeededByPortableTransform(_pointIds, buffer) {
3951
3887
  const numComponents = this.attribute.numComponents;
3952
- this.Za = new Array(numComponents);
3888
+ this.Xa = new Array(numComponents);
3953
3889
  for (let i = 0; i < numComponents; i++) {
3954
3890
  const val = buffer.decodeFloat32();
3955
3891
  if (val === void 0) return false;
3956
- this.Za[i] = val;
3892
+ this.Xa[i] = val;
3957
3893
  }
3958
3894
  const range = buffer.decodeFloat32();
3959
3895
  if (range === void 0) return false;
3960
3896
  this.Bb = range;
3961
3897
  const qBits = buffer.decodeUint8();
3962
3898
  if (qBits === void 0 || qBits < 1 || qBits > 30) return false;
3963
- this.L = qBits;
3899
+ this.K = qBits;
3964
3900
  return true;
3965
3901
  }
3966
3902
  // Dequantization is deferred to extractTo (see PointAttribute.setLazyQuantized).
3967
- Ya(_numValues) {
3968
- const maxQuantizedValue = (1 << this.L >>> 0) - 1;
3903
+ Wa(_numValues) {
3904
+ const maxQuantizedValue = (1 << this.K >>> 0) - 1;
3969
3905
  if (maxQuantizedValue <= 0) return false;
3970
3906
  const delta = Math.fround(this.Bb / Math.fround(maxQuantizedValue));
3971
- this.attribute.setLazyQuantized(this.U, this.Za, delta, this.zb());
3907
+ this.attribute.setLazyQuantized(this.M, this.Xa, delta, this.zb());
3972
3908
  return true;
3973
3909
  }
3974
3910
  };
3975
3911
 
3976
3912
  // src/decoder/compression/attributes/SequentialAttributeDecodersController.ts
3977
3913
  var SequentialAttributeDecodersController = class extends AttributesDecoder {
3978
- ua = [];
3914
+ da = [];
3979
3915
  // Replaced by the sequencer's output in _prepareSequence.
3980
- Ka = new Int32Array(0);
3981
- V;
3916
+ Ka = EMPTY_INT32;
3917
+ X;
3982
3918
  constructor(sequencer) {
3983
3919
  super();
3984
- this.V = sequencer;
3920
+ this.X = sequencer;
3985
3921
  }
3986
3922
  decodeAttributesDecoderData(buffer) {
3987
3923
  if (!super.decodeAttributesDecoderData(buffer)) {
@@ -3995,19 +3931,21 @@ var SequentialAttributeDecodersController = class extends AttributesDecoder {
3995
3931
  if (decoder === null || !decoder.init(this.getDecoder(), this.getAttributeId(i))) {
3996
3932
  return false;
3997
3933
  }
3998
- this.ua[i] = decoder;
3934
+ this.da[i] = decoder;
3999
3935
  }
4000
3936
  return true;
4001
3937
  }
4002
- ac() {
4003
- if (!this.V.generateSequence()) {
3938
+ ac(buffer) {
3939
+ const first = this.da[0];
3940
+ const parallelogram = first instanceof SequentialIntegerAttributeDecoder && buffer.remainingSize > 0 && buffer.data[buffer.decodedSize] === 1 /* MESH_PREDICTION_PARALLELOGRAM */;
3941
+ if (!this.X.generateSequence(parallelogram)) {
4004
3942
  return false;
4005
3943
  }
4006
- this.Ka = this.V.getOutputPointIds();
3944
+ this.Ka = this.X.getOutputPointIds();
4007
3945
  const numAttributes = this.getNumAttributes();
4008
3946
  for (let i = 0; i < numAttributes; i++) {
4009
3947
  const pa = this.getDecoder().pointCloud().attribute(this.getAttributeId(i));
4010
- if (!this.V.updatePointToAttributeIndexMapping(pa)) {
3948
+ if (!this.X.updatePointToAttributeIndexMapping(pa)) {
4011
3949
  return false;
4012
3950
  }
4013
3951
  }
@@ -4021,10 +3959,10 @@ var SequentialAttributeDecodersController = class extends AttributesDecoder {
4021
3959
  // of the finish work reads the buffer, and dependents only read parent
4022
3960
  // portable VALUES in finish, so ordering and output stay identical.
4023
3961
  decodeAttributesParse(buffer) {
4024
- if (!this.ac()) {
3962
+ if (!this.ac(buffer)) {
4025
3963
  return false;
4026
3964
  }
4027
- const decoders = this.ua;
3965
+ const decoders = this.da;
4028
3966
  for (let i = 0; i < decoders.length; i++) {
4029
3967
  if (!decoders[i].decodePortableAttributeParse(this.Ka, buffer)) {
4030
3968
  return false;
@@ -4038,7 +3976,7 @@ var SequentialAttributeDecodersController = class extends AttributesDecoder {
4038
3976
  return true;
4039
3977
  }
4040
3978
  collectPendingSymbolStreams(out) {
4041
- const decoders = this.ua;
3979
+ const decoders = this.da;
4042
3980
  for (let i = 0; i < decoders.length; i++) {
4043
3981
  const pending = decoders[i].pendingSymbolStream();
4044
3982
  if (pending !== null) {
@@ -4047,7 +3985,7 @@ var SequentialAttributeDecodersController = class extends AttributesDecoder {
4047
3985
  }
4048
3986
  }
4049
3987
  decodeAttributesFinish() {
4050
- const decoders = this.ua;
3988
+ const decoders = this.da;
4051
3989
  for (let i = 0; i < decoders.length; i++) {
4052
3990
  if (!decoders[i].decodePortableAttributeFinish()) {
4053
3991
  return false;
@@ -4065,7 +4003,7 @@ var SequentialAttributeDecodersController = class extends AttributesDecoder {
4065
4003
  if (locId < 0) {
4066
4004
  return null;
4067
4005
  }
4068
- return this.ua[locId].getPortableAttribute();
4006
+ return this.da[locId].getPortableAttribute();
4069
4007
  }
4070
4008
  createSequentialDecoder(decoderType) {
4071
4009
  switch (decoderType) {
@@ -4104,27 +4042,35 @@ var kInvalidFaceIndex = -1;
4104
4042
  var kInvalidVertexIndex = -1;
4105
4043
  var DepthFirstTraverser = class {
4106
4044
  a = null;
4107
- va = null;
4108
- W = null;
4045
+ ta = null;
4046
+ ua = null;
4109
4047
  Cb = [];
4110
- da = 0;
4048
+ va = 0;
4111
4049
  // Identifies the traversal order for the shared traversal cache
4112
4050
  // (MESH_TRAVERSAL_DEPTH_FIRST). See MeshTraversalSequencer.
4113
4051
  Db = 0;
4114
4052
  // The sequencer derives the point id sequence from the corner map after
4115
- // the traversal (see traverseFromCorner).
4053
+ // the traversal (see traverseAll).
4116
4054
  emitsPointIds = false;
4117
- h = null;
4118
- o = null;
4119
- y = null;
4120
- H = 0;
4055
+ i = null;
4056
+ t = null;
4057
+ z = null;
4058
+ I = 0;
4059
+ // When set (see MeshTraversalSequencer.generateSequence), each new value's
4060
+ // parallelogram parents are recorded here as it is numbered: parents[3p ..
4061
+ // 3p+2] are the value ids of the vertices of the face opposite its corner,
4062
+ // or parents[3p] is -1 when that face is missing or has a vertex not
4063
+ // numbered yet -- exactly MeshPredictionSchemeData.parallelogramParents'
4064
+ // "parent decoded after it" test, since values are numbered in order.
4065
+ // The traversal has just touched those corners, so they are read hot.
4066
+ Eb = null;
4121
4067
  init(cornerTable, observer) {
4122
4068
  this.a = cornerTable;
4123
- this.va = observer;
4124
- this.h = cornerTable.cornerToVertexArray();
4125
- this.o = cornerTable.oppositeCornerArray();
4126
- this.y = cornerTable.vertexOnBoundaryArray();
4127
- this.H = cornerTable.numCorners();
4069
+ this.ta = observer;
4070
+ this.i = cornerTable.cornerToVertexArray();
4071
+ this.t = cornerTable.oppositeCornerArray();
4072
+ this.z = cornerTable.vertexOnBoundaryArray();
4073
+ this.I = cornerTable.numCorners();
4128
4074
  }
4129
4075
  cornerTable() {
4130
4076
  return this.a;
@@ -4134,118 +4080,137 @@ var DepthFirstTraverser = class {
4134
4080
  // this entirely, including the visited-flag zero-fill (worth ~0.5% on the
4135
4081
  // ~500-primitive manablade bundle, which shares attribute corner tables across
4136
4082
  // primitives). Uint8Array (0/1) instead of Array(bool): these flags are read
4137
- // and written on every corner of the hottest decode loop (traverseFromCorner).
4083
+ // and written on every corner of the hottest decode loop (traverseAll).
4138
4084
  // Decode-scoped scratch: released in bulk at the end of the decode.
4139
4085
  onTraversalStart() {
4140
4086
  const cornerTable = this.a;
4141
- this.W = scratchUint8Zeroed(cornerTable.numFaces());
4142
- this.Cb = scratchInt32(this.H);
4087
+ this.ua = scratchUint8Zeroed(cornerTable.numFaces());
4088
+ this.Cb = scratchInt32(this.I);
4143
4089
  }
4144
4090
  // Traverses every face, seeding a new traversal at the first corner of each
4145
- // face not yet reached. The visited check lives here rather than behind a
4146
- // traverseFromCorner call per face: on a connected mesh nearly every face is
4147
- // already visited by the time its seed comes up, and that call-and-return
4148
- // was measurable next to the traversal itself.
4091
+ // face not yet reached. One function for the seeds and the walks they
4092
+ // start: a mesh cut into many pieces (small parts, or UV islands in an
4093
+ // attribute table) seeds a new walk every few faces, and a call per seed
4094
+ // would reload the whole traversal state each time.
4149
4095
  traverseAll() {
4150
4096
  const numFaces = this.a.numFaces();
4151
- const isFaceVisited = this.W;
4152
- for (let f = 0; f < numFaces && this.da < numFaces; ++f) {
4153
- if (isFaceVisited[f] === 0 && !this.traverseFromCorner(3 * f)) {
4154
- return false;
4155
- }
4156
- }
4157
- return true;
4158
- }
4159
- traverseFromCorner(cornerId) {
4160
- if (this.W[cornerId / 3 | 0]) {
4161
- return true;
4162
- }
4163
- const isFaceVisited = this.W;
4164
- const observer = this.va;
4165
- const cornerToVertex = this.h;
4166
- const oppositeCorners = this.o;
4167
- const vertexOnBoundary = this.y;
4097
+ const isFaceVisited = this.ua;
4098
+ const observer = this.ta;
4099
+ const cornerToVertex = this.i;
4100
+ const oppositeCorners = this.t;
4101
+ const vertexOnBoundary = this.z;
4168
4102
  const stack = this.Cb;
4169
- let numVisitedFaces = this.da;
4103
+ let numVisitedFaces = this.va;
4170
4104
  const encodingData = observer.n;
4171
- const encodedToCornerMap = observer._a;
4172
- const vertexToEncodedMap = observer.$a;
4105
+ const encodedToCornerMap = observer.Ya;
4106
+ const vertexToEncodedMap = observer.Za;
4107
+ const parents = this.Eb;
4173
4108
  let numValues = encodingData.numValues;
4174
- let stackSize = 0;
4175
- stack[stackSize++] = cornerId;
4176
- const nextCorner = cornerId % 3 === 2 ? cornerId - 2 : cornerId + 1;
4177
- const prevCorner = cornerId % 3 === 0 ? cornerId + 2 : cornerId - 1;
4178
- const nextVert = cornerToVertex[nextCorner];
4179
- const prevVert = cornerToVertex[prevCorner];
4180
- if (nextVert === kInvalidVertexIndex || prevVert === kInvalidVertexIndex) {
4181
- return false;
4182
- }
4183
- if (vertexToEncodedMap[nextVert] < 0) {
4184
- encodedToCornerMap[numValues] = nextCorner;
4185
- vertexToEncodedMap[nextVert] = numValues++;
4186
- }
4187
- if (vertexToEncodedMap[prevVert] < 0) {
4188
- encodedToCornerMap[numValues] = prevCorner;
4189
- vertexToEncodedMap[prevVert] = numValues++;
4190
- }
4191
- while (stackSize > 0) {
4192
- cornerId = stack[stackSize - 1];
4193
- let faceId = cornerId / 3 | 0;
4194
- if (cornerId === kInvalidCornerIndex4 || isFaceVisited[faceId]) {
4195
- stackSize--;
4196
- continue;
4109
+ for (let f = 0; f < numFaces && numVisitedFaces < numFaces; ++f) {
4110
+ if (isFaceVisited[f] !== 0) continue;
4111
+ let cornerId = 3 * f;
4112
+ let stackSize = 0;
4113
+ stack[stackSize++] = cornerId;
4114
+ const nextCorner = cornerId + 1;
4115
+ const prevCorner = cornerId + 2;
4116
+ const nextVert = cornerToVertex[nextCorner];
4117
+ const prevVert = cornerToVertex[prevCorner];
4118
+ if (nextVert === kInvalidVertexIndex || prevVert === kInvalidVertexIndex) {
4119
+ encodingData.numValues = numValues;
4120
+ return false;
4197
4121
  }
4198
- while (true) {
4199
- isFaceVisited[faceId] = 1;
4200
- numVisitedFaces++;
4201
- const vertId = cornerToVertex[cornerId];
4202
- if (vertId === kInvalidVertexIndex) {
4203
- encodingData.numValues = numValues;
4204
- return false;
4122
+ if (vertexToEncodedMap[nextVert] < 0) {
4123
+ encodedToCornerMap[numValues] = nextCorner;
4124
+ if (parents !== null)
4125
+ recordParents(parents, numValues, nextCorner, oppositeCorners, cornerToVertex, vertexToEncodedMap);
4126
+ vertexToEncodedMap[nextVert] = numValues++;
4127
+ }
4128
+ if (vertexToEncodedMap[prevVert] < 0) {
4129
+ encodedToCornerMap[numValues] = prevCorner;
4130
+ if (parents !== null)
4131
+ recordParents(parents, numValues, prevCorner, oppositeCorners, cornerToVertex, vertexToEncodedMap);
4132
+ vertexToEncodedMap[prevVert] = numValues++;
4133
+ }
4134
+ while (stackSize > 0) {
4135
+ cornerId = stack[stackSize - 1];
4136
+ let faceId = cornerId / 3 | 0;
4137
+ if (cornerId === kInvalidCornerIndex4 || isFaceVisited[faceId]) {
4138
+ stackSize--;
4139
+ continue;
4205
4140
  }
4206
- const faceBase = faceId * 3;
4207
- const nextCornerId = cornerId === faceBase + 2 ? faceBase : cornerId + 1;
4208
- if (vertexToEncodedMap[vertId] < 0) {
4209
- encodedToCornerMap[numValues] = cornerId;
4210
- vertexToEncodedMap[vertId] = numValues++;
4211
- if (vertexOnBoundary[vertId] === 0) {
4212
- cornerId = oppositeCorners[nextCornerId];
4213
- faceId = cornerId / 3 | 0;
4214
- continue;
4141
+ while (true) {
4142
+ isFaceVisited[faceId] = 1;
4143
+ numVisitedFaces++;
4144
+ const vertId = cornerToVertex[cornerId];
4145
+ if (vertId === kInvalidVertexIndex) {
4146
+ encodingData.numValues = numValues;
4147
+ return false;
4215
4148
  }
4216
- }
4217
- const rightCornerId = oppositeCorners[nextCornerId];
4218
- const prevCornerId = cornerId === faceBase ? faceBase + 2 : cornerId - 1;
4219
- const leftCornerId = oppositeCorners[prevCornerId];
4220
- const rightFaceId = rightCornerId === kInvalidCornerIndex4 ? kInvalidFaceIndex : rightCornerId / 3 | 0;
4221
- const leftFaceId = leftCornerId === kInvalidCornerIndex4 ? kInvalidFaceIndex : leftCornerId / 3 | 0;
4222
- const isRightVisited = rightFaceId === kInvalidFaceIndex || isFaceVisited[rightFaceId];
4223
- const isLeftVisited = leftFaceId === kInvalidFaceIndex || isFaceVisited[leftFaceId];
4224
- if (isRightVisited) {
4225
- if (isLeftVisited) {
4226
- stackSize--;
4227
- break;
4228
- } else {
4229
- cornerId = leftCornerId;
4230
- faceId = leftFaceId;
4149
+ const faceBase = faceId * 3;
4150
+ const nextCornerId = cornerId === faceBase + 2 ? faceBase : cornerId + 1;
4151
+ if (vertexToEncodedMap[vertId] < 0) {
4152
+ encodedToCornerMap[numValues] = cornerId;
4153
+ if (parents !== null)
4154
+ recordParents(parents, numValues, cornerId, oppositeCorners, cornerToVertex, vertexToEncodedMap);
4155
+ vertexToEncodedMap[vertId] = numValues++;
4156
+ if (vertexOnBoundary[vertId] === 0) {
4157
+ cornerId = oppositeCorners[nextCornerId];
4158
+ faceId = cornerId / 3 | 0;
4159
+ continue;
4160
+ }
4231
4161
  }
4232
- } else {
4233
- if (isLeftVisited) {
4234
- cornerId = rightCornerId;
4235
- faceId = rightFaceId;
4162
+ const rightCornerId = oppositeCorners[nextCornerId];
4163
+ const prevCornerId = cornerId === faceBase ? faceBase + 2 : cornerId - 1;
4164
+ const leftCornerId = oppositeCorners[prevCornerId];
4165
+ const rightFaceId = rightCornerId === kInvalidCornerIndex4 ? kInvalidFaceIndex : rightCornerId / 3 | 0;
4166
+ const leftFaceId = leftCornerId === kInvalidCornerIndex4 ? kInvalidFaceIndex : leftCornerId / 3 | 0;
4167
+ const isRightVisited = rightFaceId === kInvalidFaceIndex || isFaceVisited[rightFaceId];
4168
+ const isLeftVisited = leftFaceId === kInvalidFaceIndex || isFaceVisited[leftFaceId];
4169
+ if (isRightVisited) {
4170
+ if (isLeftVisited) {
4171
+ stackSize--;
4172
+ break;
4173
+ } else {
4174
+ cornerId = leftCornerId;
4175
+ faceId = leftFaceId;
4176
+ }
4236
4177
  } else {
4237
- stack[stackSize - 1] = leftCornerId;
4238
- stack[stackSize++] = rightCornerId;
4239
- break;
4178
+ if (isLeftVisited) {
4179
+ cornerId = rightCornerId;
4180
+ faceId = rightFaceId;
4181
+ } else {
4182
+ stack[stackSize - 1] = leftCornerId;
4183
+ stack[stackSize++] = rightCornerId;
4184
+ break;
4185
+ }
4240
4186
  }
4241
4187
  }
4242
4188
  }
4243
4189
  }
4244
- this.da = numVisitedFaces;
4190
+ this.va = numVisitedFaces;
4245
4191
  encodingData.numValues = numValues;
4246
4192
  return true;
4247
4193
  }
4248
4194
  };
4195
+ function recordParents(parents, value, corner, oppositeCorners, cornerToVertex, vertexToEncodedMap) {
4196
+ const o = value * 3;
4197
+ const oci = oppositeCorners[corner];
4198
+ if (oci < 0) {
4199
+ parents[o] = -1;
4200
+ return;
4201
+ }
4202
+ const rem = oci - (oci / 3 | 0) * 3;
4203
+ const a = vertexToEncodedMap[cornerToVertex[oci]];
4204
+ const b = vertexToEncodedMap[cornerToVertex[rem === 2 ? oci - 2 : oci + 1]];
4205
+ const c = vertexToEncodedMap[cornerToVertex[rem === 0 ? oci + 2 : oci - 1]];
4206
+ if ((a | b | c) < 0) {
4207
+ parents[o] = -1;
4208
+ } else {
4209
+ parents[o] = a;
4210
+ parents[o + 1] = b;
4211
+ parents[o + 2] = c;
4212
+ }
4213
+ }
4249
4214
 
4250
4215
  // src/decoder/compression/mesh/traverser/MaxPredictionDegreeTraverser.ts
4251
4216
  var kInvalidCornerIndex5 = -1;
@@ -4253,18 +4218,18 @@ var kInvalidFaceIndex2 = -1;
4253
4218
  var kMaxPriority = 3;
4254
4219
  var MaxPredictionDegreeTraverser = class {
4255
4220
  a = null;
4256
- va = null;
4257
- W = null;
4258
- ab = null;
4259
- da = 0;
4221
+ ta = null;
4222
+ ua = null;
4223
+ _a = null;
4224
+ va = 0;
4260
4225
  // One stack (bucket) per priority level [0, kMaxPriority).
4261
4226
  La = null;
4262
- X = 0;
4227
+ Y = 0;
4263
4228
  // Prediction degree accumulated per vertex during traversal.
4264
- bb = null;
4229
+ $a = null;
4265
4230
  // Flat connectivity arrays (see DepthFirstTraverser for why).
4266
- h = null;
4267
- o = null;
4231
+ i = null;
4232
+ t = null;
4268
4233
  // Identifies the traversal order for the shared traversal cache
4269
4234
  // (MESH_TRAVERSAL_PREDICTION_DEGREE). See MeshTraversalSequencer.
4270
4235
  Db = 1;
@@ -4272,32 +4237,32 @@ var MaxPredictionDegreeTraverser = class {
4272
4237
  emitsPointIds = true;
4273
4238
  init(cornerTable, observer) {
4274
4239
  this.a = cornerTable;
4275
- this.va = observer;
4276
- this.W = new Uint8Array(cornerTable.numFaces());
4277
- this.ab = new Uint8Array(cornerTable.numVertices());
4278
- this.h = cornerTable.cornerToVertexArray();
4279
- this.o = cornerTable.oppositeCornerArray();
4240
+ this.ta = observer;
4241
+ this.ua = new Uint8Array(cornerTable.numFaces());
4242
+ this._a = new Uint8Array(cornerTable.numVertices());
4243
+ this.i = cornerTable.cornerToVertexArray();
4244
+ this.t = cornerTable.oppositeCornerArray();
4280
4245
  this.La = [[], [], []];
4281
4246
  }
4282
4247
  cornerTable() {
4283
4248
  return this.a;
4284
4249
  }
4285
4250
  // corner is always valid (>= 0) where these are used.
4286
- Eb(c) {
4251
+ Fb(c) {
4287
4252
  return c % 3 === 2 ? c - 2 : c + 1;
4288
4253
  }
4289
- Fb(c) {
4254
+ Gb(c) {
4290
4255
  return c % 3 === 0 ? c + 2 : c - 1;
4291
4256
  }
4292
4257
  onTraversalStart() {
4293
- this.bb = new Int32Array(this.a.numVertices());
4258
+ this.$a = new Int32Array(this.a.numVertices());
4294
4259
  }
4295
4260
  // Same contract as DepthFirstTraverser.traverseAll. Seeds every face
4296
4261
  // through traverseFromCorner (which re-checks the first face's vertices),
4297
4262
  // exactly as the sequencer's loop always has.
4298
4263
  traverseAll() {
4299
4264
  const numFaces = this.a.numFaces();
4300
- for (let f = 0; f < numFaces && this.da < numFaces; ++f) {
4265
+ for (let f = 0; f < numFaces && this.va < numFaces; ++f) {
4301
4266
  if (!this.traverseFromCorner(3 * f)) {
4302
4267
  return false;
4303
4268
  }
@@ -4306,11 +4271,11 @@ var MaxPredictionDegreeTraverser = class {
4306
4271
  }
4307
4272
  // Returns the priority of traversing the edge leading to cornerId. Mutates
4308
4273
  // the prediction degree of the destination vertex.
4309
- Gb(cornerId) {
4310
- const vTip = this.h[cornerId];
4274
+ Hb(cornerId) {
4275
+ const vTip = this.i[cornerId];
4311
4276
  let priority = 0;
4312
- if (!this.ab[vTip]) {
4313
- const degree = ++this.bb[vTip];
4277
+ if (!this._a[vTip]) {
4278
+ const degree = ++this.$a[vTip];
4314
4279
  priority = degree > 1 ? 1 : 2;
4315
4280
  }
4316
4281
  if (priority >= kMaxPriority) {
@@ -4318,38 +4283,38 @@ var MaxPredictionDegreeTraverser = class {
4318
4283
  }
4319
4284
  return priority;
4320
4285
  }
4321
- Hb(ci, priority) {
4286
+ Ib(ci, priority) {
4322
4287
  this.La[priority].push(ci);
4323
- if (priority < this.X) {
4324
- this.X = priority;
4288
+ if (priority < this.Y) {
4289
+ this.Y = priority;
4325
4290
  }
4326
4291
  }
4327
4292
  // Retrieves the next available corner to traverse, processed by priority.
4328
4293
  // Returns kInvalidCornerIndex when no corner is available.
4329
4294
  bc() {
4330
- for (let i = this.X; i < kMaxPriority; ++i) {
4295
+ for (let i = this.Y; i < kMaxPriority; ++i) {
4331
4296
  const stack = this.La[i];
4332
4297
  if (stack.length > 0) {
4333
4298
  const ret = stack.pop();
4334
- this.X = i;
4299
+ this.Y = i;
4335
4300
  return ret;
4336
4301
  }
4337
4302
  }
4338
4303
  return kInvalidCornerIndex5;
4339
4304
  }
4340
4305
  traverseFromCorner(cornerId) {
4341
- if (this.bb.length === 0) {
4306
+ if (this.$a.length === 0) {
4342
4307
  return true;
4343
4308
  }
4344
- const cornerToVertex = this.h;
4345
- const oppositeCorners = this.o;
4346
- const isFaceVisited = this.W;
4347
- const isVertexVisited = this.ab;
4348
- const observer = this.va;
4309
+ const cornerToVertex = this.i;
4310
+ const oppositeCorners = this.t;
4311
+ const isFaceVisited = this.ua;
4312
+ const isVertexVisited = this._a;
4313
+ const observer = this.ta;
4349
4314
  this.La[0].push(cornerId);
4350
- this.X = 0;
4351
- const firstNext = this.Eb(cornerId);
4352
- const firstPrev = this.Fb(cornerId);
4315
+ this.Y = 0;
4316
+ const firstNext = this.Fb(cornerId);
4317
+ const firstPrev = this.Gb(cornerId);
4353
4318
  const nextVert = cornerToVertex[firstNext];
4354
4319
  const prevVert = cornerToVertex[firstPrev];
4355
4320
  if (!isVertexVisited[nextVert]) {
@@ -4373,34 +4338,34 @@ var MaxPredictionDegreeTraverser = class {
4373
4338
  while (true) {
4374
4339
  faceId = cornerId / 3 | 0;
4375
4340
  isFaceVisited[faceId] = 1;
4376
- this.da++;
4341
+ this.va++;
4377
4342
  const vertId = cornerToVertex[cornerId];
4378
4343
  if (!isVertexVisited[vertId]) {
4379
4344
  isVertexVisited[vertId] = 1;
4380
4345
  observer.onNewVertexVisited(vertId, cornerId);
4381
4346
  }
4382
- const rightCornerId = oppositeCorners[this.Eb(cornerId)];
4383
- const leftCornerId = oppositeCorners[this.Fb(cornerId)];
4347
+ const rightCornerId = oppositeCorners[this.Fb(cornerId)];
4348
+ const leftCornerId = oppositeCorners[this.Gb(cornerId)];
4384
4349
  const rightFaceId = rightCornerId === kInvalidCornerIndex5 ? kInvalidFaceIndex2 : rightCornerId / 3 | 0;
4385
4350
  const leftFaceId = leftCornerId === kInvalidCornerIndex5 ? kInvalidFaceIndex2 : leftCornerId / 3 | 0;
4386
4351
  const isRightFaceVisited = rightFaceId === kInvalidFaceIndex2 || isFaceVisited[rightFaceId] !== 0;
4387
4352
  const isLeftFaceVisited = leftFaceId === kInvalidFaceIndex2 || isFaceVisited[leftFaceId] !== 0;
4388
4353
  if (!isLeftFaceVisited) {
4389
- const priority = this.Gb(leftCornerId);
4390
- if (isRightFaceVisited && priority <= this.X) {
4354
+ const priority = this.Hb(leftCornerId);
4355
+ if (isRightFaceVisited && priority <= this.Y) {
4391
4356
  cornerId = leftCornerId;
4392
4357
  continue;
4393
4358
  } else {
4394
- this.Hb(leftCornerId, priority);
4359
+ this.Ib(leftCornerId, priority);
4395
4360
  }
4396
4361
  }
4397
4362
  if (!isRightFaceVisited) {
4398
- const priority = this.Gb(rightCornerId);
4399
- if (priority <= this.X) {
4363
+ const priority = this.Hb(rightCornerId);
4364
+ if (priority <= this.Y) {
4400
4365
  cornerId = rightCornerId;
4401
4366
  continue;
4402
4367
  } else {
4403
- this.Hb(rightCornerId, priority);
4368
+ this.Ib(rightCornerId, priority);
4404
4369
  }
4405
4370
  }
4406
4371
  break;
@@ -4413,65 +4378,77 @@ var MaxPredictionDegreeTraverser = class {
4413
4378
  // src/decoder/compression/mesh/traverser/MeshAttributeIndicesEncodingObserver.ts
4414
4379
  var MeshAttributeIndicesEncodingObserver = class {
4415
4380
  n;
4416
- V;
4417
- $a;
4418
- _a;
4419
- Ib;
4381
+ X;
4382
+ Za;
4383
+ Ya;
4384
+ Jb;
4420
4385
  constructor(mesh, sequencer, encodingData) {
4421
4386
  this.n = encodingData;
4422
- this.V = sequencer;
4423
- this.$a = encodingData.vertexToEncodedAttributeValueIndexMap;
4424
- this._a = encodingData.encodedAttributeValueIndexToCornerMap;
4425
- this.Ib = mesh.faces_;
4387
+ this.X = sequencer;
4388
+ this.Za = encodingData.vertexToEncodedAttributeValueIndexMap;
4389
+ this.Ya = encodingData.encodedAttributeValueIndexToCornerMap;
4390
+ this.Jb = mesh.faces_;
4426
4391
  }
4427
4392
  onNewVertexVisited(vertex, corner) {
4428
- const pointId = this.Ib[corner];
4429
- this.V.addPointId(pointId);
4393
+ const pointId = this.Jb[corner];
4394
+ this.X.addPointId(pointId);
4430
4395
  const numValues = this.n.numValues;
4431
- this._a[numValues] = corner;
4432
- this.$a[vertex] = numValues;
4396
+ this.Ya[numValues] = corner;
4397
+ this.Za[vertex] = numValues;
4433
4398
  this.n.numValues++;
4434
4399
  }
4435
4400
  };
4436
4401
 
4437
4402
  // src/decoder/compression/mesh/traverser/MeshTraversalSequencer.ts
4438
4403
  var MeshTraversalSequencer = class {
4439
- C;
4404
+ D;
4440
4405
  n;
4441
- wa = null;
4442
- u = new Int32Array(0);
4443
- xa = 0;
4406
+ ea = null;
4407
+ u = EMPTY_INT32;
4408
+ wa = 0;
4444
4409
  // Per-decode cache, keyed by corner table, shared across the attribute
4445
4410
  // decoders of one mesh (see MeshEdgebreakerDecoderImpl).
4446
- cb;
4411
+ ab;
4447
4412
  // The cache entry the last generateSequence resolved to (hit or store);
4448
4413
  // carries the shared indicesMap.
4449
- db = null;
4414
+ bb = null;
4450
4415
  // One representative corner per point id, when the connectivity decoder
4451
4416
  // recorded them (see MeshEdgebreakerDecoderImpl._assignAttributeVerticesAndPoints).
4452
- ea;
4453
- constructor(mesh, encodingData, traversalCache, pointCorner) {
4454
- this.C = mesh;
4417
+ Z;
4418
+ // The corner table whose vertex ids are the point ids, if any.
4419
+ xa;
4420
+ constructor(mesh, encodingData, traversalCache, pointCorner, pointVertexTable) {
4421
+ this.D = mesh;
4455
4422
  this.n = encodingData;
4456
- this.cb = traversalCache;
4457
- this.ea = pointCorner;
4423
+ this.ab = traversalCache;
4424
+ this.Z = pointCorner;
4425
+ this.xa = pointVertexTable;
4458
4426
  }
4459
4427
  setTraverser(traverser) {
4460
- this.wa = traverser;
4461
- }
4462
- generateSequence() {
4463
- const cornerTable = this.wa.cornerTable();
4464
- const methodId = this.wa.Db;
4428
+ this.ea = traverser;
4429
+ }
4430
+ // With parallelogramParents set, a depth-first traversal also records the
4431
+ // parallelogram parents of its values (see
4432
+ // MeshPredictionSchemeData.parallelogramParents), stored with the result.
4433
+ generateSequence(parallelogramParents) {
4434
+ const cornerTable = this.ea.cornerTable();
4435
+ const methodId = this.ea.Db;
4465
4436
  const cacheKey = cornerTable.cornerToVertexArray();
4466
4437
  const encodingData = this.n;
4467
- let byMethod = this.cb.get(cacheKey);
4438
+ let byMethod = this.ab.get(cacheKey);
4468
4439
  const cached = byMethod && byMethod.get(methodId);
4469
4440
  if (cached !== void 0) {
4470
4441
  this.u = cached.pointIds;
4471
4442
  encodingData.adoptTraversalResult(cached);
4472
- this.db = cached;
4443
+ this.bb = cached;
4473
4444
  return true;
4474
4445
  }
4446
+ const traverser = this.ea;
4447
+ let parents = null;
4448
+ if (parallelogramParents && traverser instanceof DepthFirstTraverser) {
4449
+ parents = scratchInt32(encodingData.vertexToEncodedAttributeValueIndexMap.length * 3);
4450
+ traverser.Eb = parents;
4451
+ }
4475
4452
  if (!this.cc()) {
4476
4453
  return false;
4477
4454
  }
@@ -4484,7 +4461,7 @@ var MeshTraversalSequencer = class {
4484
4461
  }
4485
4462
  if (byMethod === void 0) {
4486
4463
  byMethod = /* @__PURE__ */ new Map();
4487
- this.cb.set(cacheKey, byMethod);
4464
+ this.ab.set(cacheKey, byMethod);
4488
4465
  }
4489
4466
  const entry = {
4490
4467
  pointIds: this.u,
@@ -4492,34 +4469,42 @@ var MeshTraversalSequencer = class {
4492
4469
  cornerMap: encodingData.encodedAttributeValueIndexToCornerMap,
4493
4470
  numValues,
4494
4471
  indicesMap: null,
4495
- parents: null
4472
+ parents
4496
4473
  };
4497
4474
  byMethod.set(methodId, entry);
4498
4475
  encodingData.cacheEntry = entry;
4499
- this.db = entry;
4476
+ this.bb = entry;
4500
4477
  return true;
4501
4478
  }
4502
4479
  getOutputPointIds() {
4503
4480
  return this.u;
4504
4481
  }
4505
4482
  addPointId(pointId) {
4506
- this.u[this.xa++] = pointId;
4483
+ this.u[this.wa++] = pointId;
4507
4484
  }
4508
4485
  updatePointToAttributeIndexMapping(attribute) {
4509
- const entry = this.db;
4486
+ const entry = this.bb;
4510
4487
  if (entry !== null && entry.indicesMap !== null) {
4511
4488
  attribute.setExplicitMappingShared(entry.indicesMap);
4512
4489
  return true;
4513
4490
  }
4514
- const cornerTable = this.wa.cornerTable();
4515
- const numFaces = this.C.numFaces();
4516
- const numPoints = this.C.numPoints();
4491
+ const cornerTable = this.ea.cornerTable();
4492
+ const numFaces = this.D.numFaces();
4493
+ const numPoints = this.D.numPoints();
4517
4494
  attribute.setExplicitMappingUnfilled(numPoints);
4518
4495
  const cornerToVertex = cornerTable.cornerToVertexArray();
4519
4496
  const vertexToAttEntry = this.n.vertexToEncodedAttributeValueIndexMap;
4520
4497
  const indicesMap = attribute.indicesMap;
4521
- const pointCorner = this.ea;
4522
- if (pointCorner !== null) {
4498
+ const pointCorner = this.Z;
4499
+ if (cornerTable === this.xa) {
4500
+ for (let p = 0; p < numPoints; ++p) {
4501
+ const attEntryId = vertexToAttEntry[p];
4502
+ if (attEntryId < 0 || attEntryId >= numPoints) {
4503
+ return false;
4504
+ }
4505
+ indicesMap[p] = attEntryId;
4506
+ }
4507
+ } else if (pointCorner !== null) {
4523
4508
  for (let p = 0; p < numPoints; ++p) {
4524
4509
  const vertId = cornerToVertex[pointCorner[p]];
4525
4510
  if (vertId < 0) {
@@ -4533,7 +4518,7 @@ var MeshTraversalSequencer = class {
4533
4518
  }
4534
4519
  } else {
4535
4520
  const numCorners = numFaces * 3;
4536
- const faces = this.C.faces_;
4521
+ const faces = this.D.faces_;
4537
4522
  for (let ci = 0; ci < numCorners; ++ci) {
4538
4523
  const vertId = cornerToVertex[ci];
4539
4524
  if (vertId < 0) {
@@ -4553,9 +4538,9 @@ var MeshTraversalSequencer = class {
4553
4538
  return true;
4554
4539
  }
4555
4540
  cc() {
4556
- this.xa = 0;
4557
- this.u = scratchInt32(this.C.numPoints());
4558
- const traverser = this.wa;
4541
+ this.wa = 0;
4542
+ this.u = scratchInt32(this.D.numPoints());
4543
+ const traverser = this.ea;
4559
4544
  traverser.onTraversalStart();
4560
4545
  if (!traverser.traverseAll()) {
4561
4546
  return false;
@@ -4563,15 +4548,15 @@ var MeshTraversalSequencer = class {
4563
4548
  if (!traverser.emitsPointIds) {
4564
4549
  const numValues = this.n.numValues;
4565
4550
  const cornerMap = this.n.encodedAttributeValueIndexToCornerMap;
4566
- const faces = this.C.faces_;
4551
+ const faces = this.D.faces_;
4567
4552
  const outPointIds = this.u;
4568
4553
  for (let i = 0; i < numValues; ++i) {
4569
4554
  outPointIds[i] = faces[cornerMap[i]];
4570
4555
  }
4571
- this.xa = numValues;
4556
+ this.wa = numValues;
4572
4557
  }
4573
- if (this.xa < this.u.length) {
4574
- this.u = this.u.subarray(0, this.xa);
4558
+ if (this.wa < this.u.length) {
4559
+ this.u = this.u.subarray(0, this.wa);
4575
4560
  }
4576
4561
  return true;
4577
4562
  }
@@ -4580,38 +4565,40 @@ var MeshTraversalSequencer = class {
4580
4565
  // src/decoder/compression/mesh/MeshEdgebreakerDecoderImpl.ts
4581
4566
  var kInvalidCornerIndex6 = -1;
4582
4567
  var MeshEdgebreakerDecoderImpl = class {
4583
- l;
4568
+ m;
4584
4569
  a = null;
4585
4570
  N = [];
4586
- fa = new Uint8Array(0);
4587
- Y = 0;
4588
- eb = new MeshAttributeIndicesEncodingData();
4589
- Jb = -1;
4571
+ fa = EMPTY_UINT8;
4572
+ _ = 0;
4573
+ cb = new MeshAttributeIndicesEncodingData();
4574
+ Kb = -1;
4590
4575
  // Cache of vertex-traversal results keyed by corner table, so attributes
4591
4576
  // sharing connectivity traverse once.
4592
4577
  dc = /* @__PURE__ */ new Map();
4593
- g = [];
4594
- I;
4578
+ h = [];
4579
+ J;
4595
4580
  // One corner per point id (decode-scoped scratch), filled by
4596
- // _assignAttributeVerticesAndPoints; null when points are the base vertices.
4597
- ea = null;
4598
- // Corners on a boundary edge, counted by _decodeAttributeConnectivities.
4599
- Kb = 0;
4581
+ // _assignAttributeVerticesAndPoints; null for a mesh without attribute data
4582
+ // (see _assignPointsToVertices).
4583
+ Z = null;
4584
+ // The corner table whose vertex ids are the point ids, if any (see
4585
+ // MeshTraversalSequencer.updatePointToAttributeIndexMapping).
4586
+ xa = null;
4600
4587
  constructor(decoder, TraversalDecoderClass) {
4601
- this.l = decoder;
4602
- this.I = new TraversalDecoderClass();
4588
+ this.m = decoder;
4589
+ this.J = new TraversalDecoderClass();
4603
4590
  }
4604
4591
  getCornerTable() {
4605
4592
  return this.a;
4606
4593
  }
4607
4594
  // The attribute data set whose attributes decoder owns attId, if any.
4608
4595
  Lb(attId) {
4609
- for (let i = 0; i < this.g.length; ++i) {
4610
- const ad = this.g[i];
4611
- if (ad.decoderId < 0 || ad.decoderId >= this.l.numAttributesDecoders()) {
4596
+ for (let i = 0; i < this.h.length; ++i) {
4597
+ const ad = this.h[i];
4598
+ if (ad.decoderId < 0 || ad.decoderId >= this.m.numAttributesDecoders()) {
4612
4599
  continue;
4613
4600
  }
4614
- const dec = this.l.attributesDecoder(ad.decoderId);
4601
+ const dec = this.m.attributesDecoder(ad.decoderId);
4615
4602
  for (let j = 0; j < dec.getNumAttributes(); ++j) {
4616
4603
  if (dec.getAttributeId(j) === attId) {
4617
4604
  return ad;
@@ -4626,28 +4613,28 @@ var MeshEdgebreakerDecoderImpl = class {
4626
4613
  }
4627
4614
  getAttributeEncodingData(attId) {
4628
4615
  const ad = this.Lb(attId);
4629
- return ad !== null ? ad.encodingData : this.eb;
4616
+ return ad !== null ? ad.encodingData : this.cb;
4630
4617
  }
4631
4618
  createAttributesDecoder(attDecoderId) {
4632
- const buffer = this.l.buffer();
4619
+ const buffer = this.m.buffer();
4633
4620
  let attDataId = buffer.decodeUint8();
4634
4621
  if (attDataId !== void 0) attDataId = attDataId << 24 >> 24;
4635
4622
  if (attDataId === void 0) return false;
4636
4623
  const decoderType = buffer.decodeUint8();
4637
4624
  if (decoderType === void 0) return false;
4638
4625
  if (attDataId >= 0) {
4639
- if (attDataId >= this.g.length) {
4626
+ if (attDataId >= this.h.length) {
4640
4627
  return false;
4641
4628
  }
4642
- if (this.g[attDataId].decoderId >= 0) {
4629
+ if (this.h[attDataId].decoderId >= 0) {
4643
4630
  return false;
4644
4631
  }
4645
- this.g[attDataId].decoderId = attDecoderId;
4632
+ this.h[attDataId].decoderId = attDecoderId;
4646
4633
  } else {
4647
- if (this.Jb >= 0) {
4634
+ if (this.Kb >= 0) {
4648
4635
  return false;
4649
4636
  }
4650
- this.Jb = attDecoderId;
4637
+ this.Kb = attDecoderId;
4651
4638
  }
4652
4639
  const traversalMethod = buffer.decodeUint8();
4653
4640
  if (traversalMethod === void 0 || traversalMethod >= 2 /* NUM_TRAVERSAL_METHODS */) {
@@ -4657,44 +4644,50 @@ var MeshEdgebreakerDecoderImpl = class {
4657
4644
  let cornerTable;
4658
4645
  if (decoderType === 0 /* MESH_VERTEX_ATTRIBUTE */) {
4659
4646
  if (attDataId < 0) {
4660
- encodingData = this.eb;
4647
+ encodingData = this.cb;
4661
4648
  } else {
4662
- encodingData = this.g[attDataId].encodingData;
4663
- this.g[attDataId].isConnectivityUsed = false;
4649
+ encodingData = this.h[attDataId].encodingData;
4650
+ this.h[attDataId].isConnectivityUsed = false;
4664
4651
  }
4665
4652
  cornerTable = this.a;
4666
4653
  } else {
4667
4654
  if (traversalMethod !== 0 /* MESH_TRAVERSAL_DEPTH_FIRST */ || attDataId < 0) {
4668
4655
  return false;
4669
4656
  }
4670
- const ad = this.g[attDataId];
4657
+ const ad = this.h[attDataId];
4671
4658
  if (ad.noInteriorSeams) this.ec(ad);
4672
4659
  encodingData = ad.encodingData;
4673
4660
  cornerTable = ad.connectivityData;
4674
4661
  }
4675
- const mesh = this.l.mesh();
4676
- const sequencer = new MeshTraversalSequencer(mesh, encodingData, this.dc, this.ea);
4662
+ const mesh = this.m.mesh();
4663
+ const sequencer = new MeshTraversalSequencer(
4664
+ mesh,
4665
+ encodingData,
4666
+ this.dc,
4667
+ this.Z,
4668
+ this.xa
4669
+ );
4677
4670
  const observer = new MeshAttributeIndicesEncodingObserver(mesh, sequencer, encodingData);
4678
4671
  const traverser = traversalMethod === 1 /* MESH_TRAVERSAL_PREDICTION_DEGREE */ ? new MaxPredictionDegreeTraverser() : new DepthFirstTraverser();
4679
4672
  traverser.init(cornerTable, observer);
4680
4673
  sequencer.setTraverser(traverser);
4681
- return this.l.setAttributesDecoder(attDecoderId, new SequentialAttributeDecodersController(sequencer));
4674
+ return this.m.setAttributesDecoder(attDecoderId, new SequentialAttributeDecodersController(sequencer));
4682
4675
  }
4683
4676
  decodeConnectivity() {
4684
- const buffer = this.l.buffer();
4677
+ const buffer = this.m.buffer();
4685
4678
  const numEncodedVertices = decodeVarint(buffer);
4686
4679
  if (numEncodedVertices === void 0) return false;
4687
- this.Y = numEncodedVertices;
4680
+ this._ = numEncodedVertices;
4688
4681
  const numFaces = decodeVarint(buffer);
4689
4682
  if (numFaces === void 0) return false;
4690
4683
  if (numFaces > 2147483647 / 3) {
4691
4684
  return false;
4692
4685
  }
4693
- if (this.Y > numFaces * 3) {
4686
+ if (this._ > numFaces * 3) {
4694
4687
  return false;
4695
4688
  }
4696
4689
  const minNumFaceEdges = Math.floor(3 * numFaces / 2);
4697
- const maxNumVertexEdges = this.Y * (this.Y - 1) / 2;
4690
+ const maxNumVertexEdges = this._ * (this._ - 1) / 2;
4698
4691
  if (maxNumVertexEdges < minNumFaceEdges) {
4699
4692
  return false;
4700
4693
  }
@@ -4719,43 +4712,42 @@ var MeshEdgebreakerDecoderImpl = class {
4719
4712
  const ad = new AttributeData();
4720
4713
  ad.attributeSeamCorners = scratchInt32(numFaces * 3);
4721
4714
  ad.numSeamCorners = 0;
4722
- this.g.push(ad);
4715
+ this.h.push(ad);
4723
4716
  }
4724
- this.a.reset(numFaces, this.Y + numEncodedSplitSymbols);
4725
- this.fa = scratchUint8Filled(this.Y + numEncodedSplitSymbols, 1);
4717
+ this.a.reset(numFaces, this._ + numEncodedSplitSymbols);
4718
+ this.fa = scratchUint8Filled(this._ + numEncodedSplitSymbols, 1);
4726
4719
  if (!this.fc(buffer)) {
4727
4720
  return false;
4728
4721
  }
4729
- this.I.init(this);
4730
- this.I.setNumEncodedVertices(this.Y + numEncodedSplitSymbols);
4731
- this.I.setNumAttributeData(numAttributeData);
4722
+ this.J.init(this);
4723
+ this.J.setNumEncodedVertices(this._ + numEncodedSplitSymbols);
4724
+ this.J.setNumAttributeData(numAttributeData);
4732
4725
  const traversalEndBuffer = new DecoderBuffer();
4733
- if (!this.I.start(traversalEndBuffer)) {
4726
+ if (!this.J.start(traversalEndBuffer)) {
4734
4727
  return false;
4735
4728
  }
4736
4729
  const numConnectivityVerts = this.gc(numEncodedSymbols);
4737
4730
  if (numConnectivityVerts === -1) {
4738
4731
  return false;
4739
4732
  }
4740
- buffer.init(traversalEndBuffer.dataHead, traversalEndBuffer.remainingSize);
4733
+ buffer.initFrom(traversalEndBuffer);
4741
4734
  this.a.finishBoundaries();
4742
- if (this.g.length > 0) {
4735
+ if (this.h.length > 0) {
4743
4736
  this.hc();
4744
4737
  }
4745
- this.I.done();
4746
- const numBoundaryCorners = this.Kb;
4738
+ this.J.done();
4747
4739
  const distinctTables = [];
4748
4740
  const seamEdgeCounts = [];
4749
4741
  const adoptions = [];
4750
4742
  let previousConnectivityData = null;
4751
4743
  let previousSeamCorners = null;
4752
4744
  let previousSeamCount = 0;
4753
- for (let i = 0; i < this.g.length; ++i) {
4754
- const connectivityData = this.g[i].connectivityData;
4755
- const seamCorners = this.g[i].attributeSeamCorners;
4756
- const seamCount = this.g[i].numSeamCorners;
4757
- if (seamCount === numBoundaryCorners) {
4758
- this.g[i].noInteriorSeams = true;
4745
+ for (let i = 0; i < this.h.length; ++i) {
4746
+ const connectivityData = this.h[i].connectivityData;
4747
+ const seamCorners = this.h[i].attributeSeamCorners;
4748
+ const seamCount = this.h[i].numSeamCorners;
4749
+ if (seamCount === 0) {
4750
+ this.h[i].noInteriorSeams = true;
4759
4751
  continue;
4760
4752
  }
4761
4753
  let sameAsPrevious = previousConnectivityData !== null && seamCount === previousSeamCount;
@@ -4782,7 +4774,7 @@ var MeshEdgebreakerDecoderImpl = class {
4782
4774
  previousSeamCorners = seamCorners;
4783
4775
  previousSeamCount = seamCount;
4784
4776
  }
4785
- if (this.g.length === 0) {
4777
+ if (this.h.length === 0) {
4786
4778
  this.ic(numConnectivityVerts);
4787
4779
  } else if (!this.jc(distinctTables, seamEdgeCounts)) {
4788
4780
  return false;
@@ -4790,13 +4782,13 @@ var MeshEdgebreakerDecoderImpl = class {
4790
4782
  for (let i = 0; i < adoptions.length; i += 2) {
4791
4783
  adoptions[i].adoptFrom(adoptions[i + 1]);
4792
4784
  }
4793
- this.eb.init(this.a.numVertices());
4794
- for (let i = 0; i < this.g.length; ++i) {
4795
- let attConnectivityVerts = this.g[i].connectivityData.numVertices();
4785
+ this.cb.init(this.a.numVertices());
4786
+ for (let i = 0; i < this.h.length; ++i) {
4787
+ let attConnectivityVerts = this.h[i].connectivityData.numVertices();
4796
4788
  if (attConnectivityVerts < this.a.numVertices()) {
4797
4789
  attConnectivityVerts = this.a.numVertices();
4798
4790
  }
4799
- this.g[i].encodingData.init(attConnectivityVerts);
4791
+ this.h[i].encodingData.init(attConnectivityVerts);
4800
4792
  }
4801
4793
  return true;
4802
4794
  }
@@ -4823,15 +4815,15 @@ var MeshEdgebreakerDecoderImpl = class {
4823
4815
  const topologySplitActiveCorners = /* @__PURE__ */ new Map();
4824
4816
  const splitResult = { faceEdge: 0, encoderSplitSymbolId: 0 };
4825
4817
  const invalidVertices = [];
4826
- const removeInvalidVertices = this.g.length === 0;
4818
+ const removeInvalidVertices = this.h.length === 0;
4827
4819
  let maxNumVertices = this.fa.length;
4828
4820
  let numFacesDecoded = 0;
4829
- const cornerToVertex = this.a.h;
4830
- const oppositeCorners = this.a.o;
4821
+ const cornerToVertex = this.a.i;
4822
+ const oppositeCorners = this.a.t;
4831
4823
  const vc = this.a;
4832
- let vertexCorners = vc.s;
4824
+ let vertexCorners = vc.r;
4833
4825
  const isVertHole = this.fa;
4834
- const traversalDecoder = this.I;
4826
+ const traversalDecoder = this.J;
4835
4827
  for (let symbolId = 0; symbolId < numSymbols; ++symbolId) {
4836
4828
  const faceIndex = numFacesDecoded++;
4837
4829
  let checkTopologySplit = false;
@@ -4883,13 +4875,13 @@ var MeshEdgebreakerDecoderImpl = class {
4883
4875
  oppositeCorners[oppCorner] = cornerA;
4884
4876
  oppositeCorners[cornerA] = oppCorner;
4885
4877
  let newVertIndex;
4886
- if (vc.i < vertexCorners.length) {
4887
- newVertIndex = vc.i++;
4878
+ if (vc.j < vertexCorners.length) {
4879
+ newVertIndex = vc.j++;
4888
4880
  } else {
4889
4881
  newVertIndex = vc.addNewVertex();
4890
- vertexCorners = vc.s;
4882
+ vertexCorners = vc.r;
4891
4883
  }
4892
- if (vc.i > maxNumVertices) return -1;
4884
+ if (vc.j > maxNumVertices) return -1;
4893
4885
  cornerToVertex[oppCorner] = newVertIndex;
4894
4886
  vertexCorners[newVertIndex] = oppCorner;
4895
4887
  const pA = cornerA % 3 === 0 ? cornerA + 2 : cornerA - 1;
@@ -4950,16 +4942,16 @@ var MeshEdgebreakerDecoderImpl = class {
4950
4942
  } else if (symbol === TOPOLOGY_E) {
4951
4943
  const corner = 3 * faceIndex;
4952
4944
  let firstVertIndex;
4953
- if (vc.i + 3 <= vertexCorners.length) {
4954
- firstVertIndex = vc.i;
4955
- vc.i += 3;
4945
+ if (vc.j + 3 <= vertexCorners.length) {
4946
+ firstVertIndex = vc.j;
4947
+ vc.j += 3;
4956
4948
  } else {
4957
4949
  firstVertIndex = vc.addNewVertex();
4958
4950
  vc.addNewVertex();
4959
4951
  vc.addNewVertex();
4960
- vertexCorners = vc.s;
4952
+ vertexCorners = vc.r;
4961
4953
  }
4962
- if (vc.i > maxNumVertices) return -1;
4954
+ if (vc.j > maxNumVertices) return -1;
4963
4955
  cornerToVertex[corner] = firstVertIndex;
4964
4956
  cornerToVertex[corner + 1] = firstVertIndex + 1;
4965
4957
  cornerToVertex[corner + 2] = firstVertIndex + 2;
@@ -4988,7 +4980,7 @@ var MeshEdgebreakerDecoderImpl = class {
4988
4980
  }
4989
4981
  }
4990
4982
  }
4991
- if (vc.i > maxNumVertices) {
4983
+ if (vc.j > maxNumVertices) {
4992
4984
  return -1;
4993
4985
  }
4994
4986
  numFacesDecoded = this.lc(activeCornerStack, activeCornerStackSize, numFacesDecoded);
@@ -5004,11 +4996,11 @@ var MeshEdgebreakerDecoderImpl = class {
5004
4996
  // Returns the updated decoded-face count, or -1 on malformed input.
5005
4997
  lc(activeCornerStack, activeCornerStackSize, numFacesDecoded) {
5006
4998
  const ct = this.a;
5007
- const oppositeCorners = ct.o;
5008
- const cornerToVertex = ct.h;
5009
- const vertexCorners = ct.s;
4999
+ const oppositeCorners = ct.t;
5000
+ const cornerToVertex = ct.i;
5001
+ const vertexCorners = ct.r;
5010
5002
  const isVertHole = this.fa;
5011
- const traversalDecoder = this.I;
5003
+ const traversalDecoder = this.J;
5012
5004
  const numCorners = ct.numCorners();
5013
5005
  const numFaces = ct.numFaces();
5014
5006
  const next = (c) => c < 0 ? -1 : c % 3 === 2 ? c - 2 : c + 1;
@@ -5058,8 +5050,8 @@ var MeshEdgebreakerDecoderImpl = class {
5058
5050
  // forward iteration order matters). Returns the final vertex count, or -1.
5059
5051
  mc(invalidVertices) {
5060
5052
  const ct = this.a;
5061
- const cornerToVertex = ct.h;
5062
- const vertexCorners = ct.s;
5053
+ const cornerToVertex = ct.i;
5054
+ const vertexCorners = ct.r;
5063
5055
  const isVertHole = this.fa;
5064
5056
  const leftMostCorner = (v) => v < 0 || v >= vertexCorners.length ? -1 : vertexCorners[v];
5065
5057
  let numVertices = ct.numVertices();
@@ -5141,32 +5133,24 @@ var MeshEdgebreakerDecoderImpl = class {
5141
5133
  //
5142
5134
  // The face comparison the C++ makes -- floor(oppCorner/3) >= floor(cc/3) for
5143
5135
  // the face's base corner -- is just `oppCorner >= faceBaseCorner`, since the
5144
- // base corner is a multiple of 3. That removes the per-corner division; the
5145
- // invalid-corner case (-1) is still handled by the branch above it.
5136
+ // base corner is a multiple of 3. That removes the per-corner division, and
5137
+ // an invalid (-1) opposite fails it too.
5146
5138
  hc() {
5147
5139
  const oppositeCorners = this.a.oppositeCornerArray();
5148
- const attributeData = this.g;
5140
+ const attributeData = this.h;
5149
5141
  const numAttrData = attributeData.length;
5150
- const connectivityDecoders = this.I.Mb;
5142
+ const connectivityDecoders = this.J.Mb;
5151
5143
  const numCorners = this.a.numCorners();
5152
5144
  const candidates = scratchInt32(numCorners);
5153
5145
  let numCandidates = 0;
5154
- let numBoundaryCorners = 0;
5155
5146
  for (let corner = 0; corner < numCorners; corner += 3) {
5156
- let opp = oppositeCorners[corner];
5157
- candidates[numCandidates] = corner ^ opp >> 31;
5158
- numCandidates -= (opp | corner - opp - 1) >> 31;
5159
- numBoundaryCorners -= opp >> 31;
5160
- opp = oppositeCorners[corner + 1];
5161
- candidates[numCandidates] = corner + 1 ^ opp >> 31;
5162
- numCandidates -= (opp | corner - opp - 1) >> 31;
5163
- numBoundaryCorners -= opp >> 31;
5164
- opp = oppositeCorners[corner + 2];
5165
- candidates[numCandidates] = corner + 2 ^ opp >> 31;
5166
- numCandidates -= (opp | corner - opp - 1) >> 31;
5167
- numBoundaryCorners -= opp >> 31;
5168
- }
5169
- this.Kb = numBoundaryCorners;
5147
+ candidates[numCandidates] = corner;
5148
+ numCandidates -= corner - oppositeCorners[corner] - 1 >> 31;
5149
+ candidates[numCandidates] = corner + 1;
5150
+ numCandidates -= corner - oppositeCorners[corner + 1] - 1 >> 31;
5151
+ candidates[numCandidates] = corner + 2;
5152
+ numCandidates -= corner - oppositeCorners[corner + 2] - 1 >> 31;
5153
+ }
5170
5154
  let i = 0;
5171
5155
  for (; i + 2 <= numAttrData; i += 2) {
5172
5156
  decodeSeamBits2(
@@ -5184,7 +5168,7 @@ var MeshEdgebreakerDecoderImpl = class {
5184
5168
  }
5185
5169
  // Position-only connectivity: vertex indices equal point indices.
5186
5170
  ic(numConnectivityVerts) {
5187
- const mesh = this.l.mesh();
5171
+ const mesh = this.m.mesh();
5188
5172
  const ct = this.a;
5189
5173
  mesh.setNumFaces(ct.numFaces());
5190
5174
  const numCorners = ct.numCorners();
@@ -5193,8 +5177,8 @@ var MeshEdgebreakerDecoderImpl = class {
5193
5177
  for (let c = 0; c < numCorners; ++c) {
5194
5178
  faces[c] = baseCornerToVertex[c];
5195
5179
  }
5196
- this.ea = null;
5197
- this.l.pointCloud().setNumPoints(numConnectivityVerts);
5180
+ this.Z = null;
5181
+ this.m.pointCloud().setNumPoints(numConnectivityVerts);
5198
5182
  }
5199
5183
  // Sets up an attribute corner table whose only seams are boundary edges
5200
5184
  // (see decodeConnectivity), for a per-corner decoder that asked for it:
@@ -5235,7 +5219,7 @@ var MeshEdgebreakerDecoderImpl = class {
5235
5219
  // (or left through the seam-aware table, which stops at the boundary), so
5236
5220
  // an open ring is walked from that corner too.
5237
5221
  jc(tables, seamEdgeCounts) {
5238
- const mesh = this.l.mesh();
5222
+ const mesh = this.m.mesh();
5239
5223
  const ct = this.a;
5240
5224
  mesh.setNumFaces(ct.numFaces());
5241
5225
  const numCorners = ct.numCorners();
@@ -5247,24 +5231,41 @@ var MeshEdgebreakerDecoderImpl = class {
5247
5231
  const isVertHole = this.fa;
5248
5232
  const baseOnBoundary = ct.vertexOnBoundaryArray();
5249
5233
  const numTables = tables.length;
5234
+ if (numTables === 0) {
5235
+ let isolated = false;
5236
+ for (let v = 0; v < numVertices; ++v) {
5237
+ if (vertexLeftmost[v] < 0) {
5238
+ isolated = true;
5239
+ break;
5240
+ }
5241
+ }
5242
+ if (!isolated) {
5243
+ faces.set(baseCornerToVertex);
5244
+ this.Z = vertexLeftmost;
5245
+ this.xa = ct;
5246
+ this.m.pointCloud().setNumPoints(numVertices);
5247
+ return true;
5248
+ }
5249
+ }
5250
5250
  const attCornerToVertex = new Array(numTables);
5251
5251
  const attOpposite = new Array(numTables);
5252
5252
  const vertexOnSeam = new Array(numTables);
5253
5253
  const onBoundaryMaps = new Array(numTables);
5254
5254
  const numExtraVertices = new Int32Array(numTables);
5255
5255
  for (let t = 0; t < numTables; ++t) {
5256
- attCornerToVertex[t] = tables[t].S;
5257
- attOpposite[t] = tables[t].E;
5256
+ attCornerToVertex[t] = tables[t].U;
5257
+ attOpposite[t] = tables[t].F;
5258
5258
  vertexOnSeam[t] = tables[t].la;
5259
5259
  const onBoundary = scratchUint8(numVertices + 2 * seamEdgeCounts[t]);
5260
5260
  onBoundary.set(baseOnBoundary);
5261
5261
  onBoundary.fill(1, numVertices);
5262
5262
  onBoundaryMaps[t] = onBoundary;
5263
5263
  }
5264
- const ring = scratchInt32(numCorners);
5265
- const ringNext = scratchInt32(numCorners);
5264
+ const ringSize = numTables > 0 ? numCorners : 0;
5265
+ const ring = scratchInt32(ringSize);
5266
+ const ringNext = scratchInt32(ringSize);
5266
5267
  const pointCorner = scratchInt32(numCorners);
5267
- const idChange = scratchUint8Zeroed(numCorners);
5268
+ const idChange = scratchUint8Zeroed(ringSize);
5268
5269
  let numPoints = 0;
5269
5270
  const plainPointId = scratchInt32(numVertices);
5270
5271
  let numWalked = 0;
@@ -5386,8 +5387,8 @@ var MeshEdgebreakerDecoderImpl = class {
5386
5387
  for (let t = 0; t < numTables; ++t) {
5387
5388
  tables[t].setRecomputedVertices(onBoundaryMaps[t], numVertices + numExtraVertices[t]);
5388
5389
  }
5389
- this.ea = pointCorner;
5390
- this.l.pointCloud().setNumPoints(numPoints);
5390
+ this.Z = pointCorner;
5391
+ this.m.pointCloud().setNumPoints(numPoints);
5391
5392
  return true;
5392
5393
  }
5393
5394
  };
@@ -5401,11 +5402,6 @@ function decodeSeamBits1(candidates, numCandidates, ad, decoder) {
5401
5402
  let state = ans.state;
5402
5403
  let bufOffset = ans.bufOffset;
5403
5404
  for (let n = 0; n < numCandidates; ++n) {
5404
- const cc = candidates[n];
5405
- if (cc < 0) {
5406
- seamCorners[numSeamCorners++] = ~cc;
5407
- continue;
5408
- }
5409
5405
  if (state < ANS_L_BASE && bufOffset > bufStart) {
5410
5406
  state = state << 8 | buf[--bufOffset];
5411
5407
  }
@@ -5414,7 +5410,7 @@ function decodeSeamBits1(candidates, numCandidates, ad, decoder) {
5414
5410
  const mask = rem - p >> 31;
5415
5411
  const stateIfZero = state - xn - p;
5416
5412
  state = stateIfZero + (mask & xn + rem - stateIfZero);
5417
- seamCorners[numSeamCorners] = cc;
5413
+ seamCorners[numSeamCorners] = candidates[n];
5418
5414
  numSeamCorners -= mask;
5419
5415
  }
5420
5416
  ans.state = state;
@@ -5440,11 +5436,6 @@ function decodeSeamBits2(candidates, numCandidates, ad0, decoder0, ad1, decoder1
5440
5436
  let off1 = ans1.bufOffset;
5441
5437
  for (let n = 0; n < numCandidates; ++n) {
5442
5438
  const cc = candidates[n];
5443
- if (cc < 0) {
5444
- seam0[num0++] = ~cc;
5445
- seam1[num1++] = ~cc;
5446
- continue;
5447
- }
5448
5439
  if (state0 < ANS_L_BASE && off0 > start0) {
5449
5440
  state0 = state0 << 8 | buf0[--off0];
5450
5441
  }
@@ -5474,8 +5465,8 @@ function decodeSeamBits2(candidates, numCandidates, ad0, decoder0, ad1, decoder1
5474
5465
  ad1.numSeamCorners = num1;
5475
5466
  }
5476
5467
  var MeshAttributeIndicesEncodingData = class {
5477
- vertexToEncodedAttributeValueIndexMap = new Int32Array(0);
5478
- encodedAttributeValueIndexToCornerMap = new Int32Array(0);
5468
+ vertexToEncodedAttributeValueIndexMap = EMPTY_INT32;
5469
+ encodedAttributeValueIndexToCornerMap = EMPTY_INT32;
5479
5470
  numValues = 0;
5480
5471
  // The traversal cache entry the maps came from (see MeshTraversalSequencer);
5481
5472
  // carries what later passes derive from the traversal and share.
@@ -5501,43 +5492,43 @@ var AttributeData = class {
5501
5492
  connectivityData = new MeshAttributeCornerTable();
5502
5493
  isConnectivityUsed = true;
5503
5494
  encodingData = new MeshAttributeIndicesEncodingData();
5504
- attributeSeamCorners = new Int32Array(0);
5495
+ attributeSeamCorners = EMPTY_INT32;
5505
5496
  numSeamCorners = 0;
5506
- // Set when every seam is a boundary edge and connectivityData was therefore
5497
+ // Set when the set has no interior seam and connectivityData was therefore
5507
5498
  // left unbuilt (see decodeConnectivity); cleared once it is built on demand.
5508
5499
  noInteriorSeams = false;
5509
5500
  };
5510
5501
  var CornerTable = class {
5511
5502
  Nb = 0;
5512
- H = 0;
5513
- i = 0;
5514
- h = null;
5503
+ I = 0;
5504
+ j = 0;
5505
+ i = null;
5515
5506
  // corner -> vertex
5516
- o = null;
5507
+ t = null;
5517
5508
  // corner -> opposite corner
5518
- s = null;
5509
+ r = null;
5519
5510
  // vertex -> left-most corner
5520
5511
  // vertex -> 1 when its fan is open (C++ IsOnBoundary: the edge left of
5521
5512
  // the left-most corner has no opposite face), computed once after the
5522
5513
  // connectivity decode (see finishBoundaries) for the traversals, whose
5523
5514
  // critical path would otherwise chase two dependent loads per new vertex.
5524
- y = null;
5515
+ z = null;
5525
5516
  reset(numFaces, numVertices) {
5526
5517
  this.Nb = numFaces;
5527
- this.H = numFaces * 3;
5528
- this.i = 0;
5529
- this.h = scratchInt32Filled(this.H, -1);
5530
- this.o = scratchInt32Filled(this.H, -1);
5531
- this.s = scratchInt32Filled(numVertices, -1);
5518
+ this.I = numFaces * 3;
5519
+ this.j = 0;
5520
+ this.i = scratchInt32Filled(this.I, -1);
5521
+ this.t = scratchInt32Filled(this.I, -1);
5522
+ this.r = scratchInt32Filled(numVertices, -1);
5532
5523
  }
5533
5524
  numFaces() {
5534
5525
  return this.Nb;
5535
5526
  }
5536
5527
  numCorners() {
5537
- return this.H;
5528
+ return this.I;
5538
5529
  }
5539
5530
  numVertices() {
5540
- return this.i;
5531
+ return this.j;
5541
5532
  }
5542
5533
  next(corner) {
5543
5534
  if (corner < 0) return -1;
@@ -5550,50 +5541,50 @@ var CornerTable = class {
5550
5541
  return rem === 0 ? corner + 2 : corner - 1;
5551
5542
  }
5552
5543
  vertex(corner) {
5553
- if (corner < 0 || corner >= this.H) return -1;
5554
- return this.h[corner];
5544
+ if (corner < 0 || corner >= this.I) return -1;
5545
+ return this.i[corner];
5555
5546
  }
5556
5547
  opposite(corner) {
5557
- if (corner < 0 || corner >= this.H) return -1;
5558
- return this.o[corner];
5548
+ if (corner < 0 || corner >= this.I) return -1;
5549
+ return this.t[corner];
5559
5550
  }
5560
5551
  // Flat-array accessors; let callers avoid polymorphic per-corner dispatch.
5561
5552
  cornerToVertexArray() {
5562
- return this.h;
5553
+ return this.i;
5563
5554
  }
5564
5555
  oppositeCornerArray() {
5565
- return this.o;
5556
+ return this.t;
5566
5557
  }
5567
5558
  vertexLeftmostCornerArray() {
5568
- return this.s;
5559
+ return this.r;
5569
5560
  }
5570
5561
  vertexOnBoundaryArray() {
5571
- return this.y;
5562
+ return this.z;
5572
5563
  }
5573
5564
  // Derives _vertexOnBoundary from the finished connectivity (decode-scoped
5574
5565
  // scratch). Isolated vertices count as boundary; they are never traversed.
5575
5566
  finishBoundaries() {
5576
- const numVertices = this.i;
5577
- const vertexCorners = this.s;
5578
- const oppositeCorners = this.o;
5567
+ const numVertices = this.j;
5568
+ const vertexCorners = this.r;
5569
+ const oppositeCorners = this.t;
5579
5570
  const onBoundary = scratchUint8(numVertices);
5580
5571
  for (let v = 0; v < numVertices; ++v) {
5581
5572
  const lc = vertexCorners[v];
5582
5573
  onBoundary[v] = lc < 0 || oppositeCorners[lc % 3 === 2 ? lc - 2 : lc + 1] < 0 ? 1 : 0;
5583
5574
  }
5584
- this.y = onBoundary;
5575
+ this.z = onBoundary;
5585
5576
  }
5586
5577
  // Mirrors C++ CornerTable::AddNewVertex() (push_back(kInvalidCornerIndex)).
5587
5578
  addNewVertex() {
5588
- const newVertex = this.i;
5589
- this.i++;
5590
- if (newVertex >= this.s.length) {
5591
- const newCapacity = Math.max(newVertex + 1, this.s.length * 2, 64);
5579
+ const newVertex = this.j;
5580
+ this.j++;
5581
+ if (newVertex >= this.r.length) {
5582
+ const newCapacity = Math.max(newVertex + 1, this.r.length * 2, 64);
5592
5583
  const newArr = scratchInt32Filled(newCapacity, -1);
5593
- newArr.set(this.s);
5594
- this.s = newArr;
5584
+ newArr.set(this.r);
5585
+ this.r = newArr;
5595
5586
  }
5596
- this.s[newVertex] = -1;
5587
+ this.r[newVertex] = -1;
5597
5588
  return newVertex;
5598
5589
  }
5599
5590
  // Next corner around a vertex, CCW. SwingLeft(c) = Next(Opposite(Next(c))).
@@ -5615,8 +5606,8 @@ var CornerTable = class {
5615
5606
  // src/decoder/compression/mesh/MeshEdgebreakerTraversalDecoder.ts
5616
5607
  var MeshEdgebreakerTraversalDecoder = class {
5617
5608
  c = new DecoderBuffer();
5618
- J = new DecoderBuffer();
5619
- fb = null;
5609
+ O = new DecoderBuffer();
5610
+ db = null;
5620
5611
  Mb = [];
5621
5612
  Ob = 0;
5622
5613
  // _symbolBuffer's bit cursor, captured once bit decoding starts: decodeSymbol
@@ -5624,8 +5615,8 @@ var MeshEdgebreakerTraversalDecoder = class {
5624
5615
  // loads and a method call per read.
5625
5616
  Pb = null;
5626
5617
  init(decoder) {
5627
- const srcBuffer = decoder.l.buffer();
5628
- this.c.init(srcBuffer.dataHead, srcBuffer.remainingSize);
5618
+ const srcBuffer = decoder.m.buffer();
5619
+ this.c.initFrom(srcBuffer);
5629
5620
  }
5630
5621
  // Ignored by default; overridden by predictive/valence decoders.
5631
5622
  setNumEncodedVertices(_numVertices) {
@@ -5644,33 +5635,33 @@ var MeshEdgebreakerTraversalDecoder = class {
5644
5635
  if (!this.decodeAttributeSeams()) {
5645
5636
  return false;
5646
5637
  }
5647
- outBuffer.init(this.c.dataHead, this.c.remainingSize);
5638
+ outBuffer.initFrom(this.c);
5648
5639
  return true;
5649
5640
  }
5650
5641
  decodeStartFaceConfiguration() {
5651
- return this.fb.decodeNextBit();
5642
+ return this.db.decodeNextBit();
5652
5643
  }
5653
5644
  decodeSymbol() {
5654
5645
  const bd = this.Pb;
5655
5646
  if (bd !== null) {
5656
- const buf = bd.Da;
5657
- const off = bd.p;
5647
+ const buf = bd.Ea;
5648
+ const off = bd.o;
5658
5649
  const byteOffset = off >> 3;
5659
5650
  if (byteOffset + 4 < bd.ja) {
5660
5651
  const bits = (buf[byteOffset] | buf[byteOffset + 1] << 8 | buf[byteOffset + 2] << 16 | buf[byteOffset + 3] << 24) >>> (off & 7) & 7;
5661
5652
  if ((bits & 1) === TOPOLOGY_C) {
5662
- bd.p = off + 1;
5653
+ bd.o = off + 1;
5663
5654
  return TOPOLOGY_C;
5664
5655
  }
5665
- bd.p = off + 3;
5656
+ bd.o = off + 3;
5666
5657
  return bits;
5667
5658
  }
5668
5659
  }
5669
- let symbol = this.J.decodeLeastSignificantBits32(1);
5660
+ let symbol = this.O.decodeLeastSignificantBits32(1);
5670
5661
  if (symbol === TOPOLOGY_C) {
5671
5662
  return symbol;
5672
5663
  }
5673
- const symbolSuffix = this.J.decodeLeastSignificantBits32(2);
5664
+ const symbolSuffix = this.O.decodeLeastSignificantBits32(2);
5674
5665
  symbol |= symbolSuffix << 1;
5675
5666
  return symbol;
5676
5667
  }
@@ -5679,18 +5670,18 @@ var MeshEdgebreakerTraversalDecoder = class {
5679
5670
  mergeVertices(_dest, _source) {
5680
5671
  }
5681
5672
  done() {
5682
- if (this.J.bitDecoderActive) {
5683
- this.J.endBitDecoding();
5673
+ if (this.O.bitDecoderActive) {
5674
+ this.O.endBitDecoding();
5684
5675
  }
5685
5676
  }
5686
5677
  decodeTraversalSymbols() {
5687
- this.J.init(this.c.dataHead, this.c.remainingSize);
5688
- const traversalSize = this.J.startBitDecoding(true);
5678
+ this.O.initFrom(this.c);
5679
+ const traversalSize = this.O.startBitDecoding(true);
5689
5680
  if (traversalSize === void 0) {
5690
5681
  return false;
5691
5682
  }
5692
- this.Pb = this.J.ka;
5693
- this.c.init(this.J.dataHead, this.J.remainingSize);
5683
+ this.Pb = this.O.ka;
5684
+ this.c.initFrom(this.O);
5694
5685
  if (traversalSize > this.c.remainingSize) {
5695
5686
  return false;
5696
5687
  }
@@ -5699,8 +5690,8 @@ var MeshEdgebreakerTraversalDecoder = class {
5699
5690
  }
5700
5691
  decodeStartFaces() {
5701
5692
  try {
5702
- this.fb = new RAnsBitDecoder();
5703
- return this.fb.startDecoding(this.c);
5693
+ this.db = new RAnsBitDecoder();
5694
+ return this.db.startDecoding(this.c);
5704
5695
  } catch {
5705
5696
  return false;
5706
5697
  }
@@ -5720,17 +5711,17 @@ var MeshEdgebreakerTraversalDecoder = class {
5720
5711
  // src/decoder/compression/mesh/MeshEdgebreakerTraversalPredictiveDecoder.ts
5721
5712
  var MeshEdgebreakerTraversalPredictiveDecoder = class extends MeshEdgebreakerTraversalDecoder {
5722
5713
  a = null;
5723
- i = 0;
5714
+ j = 0;
5724
5715
  x = -1;
5725
5716
  ga = -1;
5726
- j = [];
5727
- gb = null;
5717
+ k = [];
5718
+ eb = null;
5728
5719
  init(decoder) {
5729
5720
  super.init(decoder);
5730
5721
  this.a = decoder.getCornerTable();
5731
5722
  }
5732
5723
  setNumEncodedVertices(numVertices) {
5733
- this.i = numVertices;
5724
+ this.j = numVertices;
5734
5725
  }
5735
5726
  start(outBuffer) {
5736
5727
  if (!super.start(outBuffer)) {
@@ -5740,16 +5731,16 @@ var MeshEdgebreakerTraversalPredictiveDecoder = class extends MeshEdgebreakerTra
5740
5731
  if (numSplitSymbols === void 0 || numSplitSymbols < 0) {
5741
5732
  return false;
5742
5733
  }
5743
- if (numSplitSymbols >= this.i) {
5734
+ if (numSplitSymbols >= this.j) {
5744
5735
  return false;
5745
5736
  }
5746
- this.j = new Array(this.i).fill(0);
5747
- this.gb = new RAnsBitDecoder();
5748
- return this.gb.startDecoding(outBuffer);
5737
+ this.k = new Array(this.j).fill(0);
5738
+ this.eb = new RAnsBitDecoder();
5739
+ return this.eb.startDecoding(outBuffer);
5749
5740
  }
5750
5741
  decodeSymbol() {
5751
5742
  if (this.ga !== -1) {
5752
- if (this.gb.decodeNextBit()) {
5743
+ if (this.eb.decodeNextBit()) {
5753
5744
  this.x = this.ga;
5754
5745
  return this.ga;
5755
5746
  }
@@ -5764,30 +5755,30 @@ var MeshEdgebreakerTraversalPredictiveDecoder = class extends MeshEdgebreakerTra
5764
5755
  switch (this.x) {
5765
5756
  case TOPOLOGY_C:
5766
5757
  case TOPOLOGY_S:
5767
- this.j[ct.vertex(next)] += 1;
5768
- this.j[ct.vertex(prev)] += 1;
5758
+ this.k[ct.vertex(next)] += 1;
5759
+ this.k[ct.vertex(prev)] += 1;
5769
5760
  break;
5770
5761
  case TOPOLOGY_R:
5771
- this.j[ct.vertex(corner)] += 1;
5772
- this.j[ct.vertex(next)] += 1;
5773
- this.j[ct.vertex(prev)] += 2;
5762
+ this.k[ct.vertex(corner)] += 1;
5763
+ this.k[ct.vertex(next)] += 1;
5764
+ this.k[ct.vertex(prev)] += 2;
5774
5765
  break;
5775
5766
  case TOPOLOGY_L:
5776
- this.j[ct.vertex(corner)] += 1;
5777
- this.j[ct.vertex(next)] += 2;
5778
- this.j[ct.vertex(prev)] += 1;
5767
+ this.k[ct.vertex(corner)] += 1;
5768
+ this.k[ct.vertex(next)] += 2;
5769
+ this.k[ct.vertex(prev)] += 1;
5779
5770
  break;
5780
5771
  case TOPOLOGY_E:
5781
- this.j[ct.vertex(corner)] += 2;
5782
- this.j[ct.vertex(next)] += 2;
5783
- this.j[ct.vertex(prev)] += 2;
5772
+ this.k[ct.vertex(corner)] += 2;
5773
+ this.k[ct.vertex(next)] += 2;
5774
+ this.k[ct.vertex(prev)] += 2;
5784
5775
  break;
5785
5776
  default:
5786
5777
  break;
5787
5778
  }
5788
5779
  if (this.x === TOPOLOGY_C || this.x === TOPOLOGY_R) {
5789
5780
  const pivot = ct.vertex(ct.next(corner));
5790
- if (this.j[pivot] < 6) {
5781
+ if (this.k[pivot] < 6) {
5791
5782
  this.ga = TOPOLOGY_R;
5792
5783
  } else {
5793
5784
  this.ga = TOPOLOGY_C;
@@ -5797,34 +5788,34 @@ var MeshEdgebreakerTraversalPredictiveDecoder = class extends MeshEdgebreakerTra
5797
5788
  }
5798
5789
  }
5799
5790
  mergeVertices(dest, source) {
5800
- this.j[dest] += this.j[source];
5791
+ this.k[dest] += this.k[source];
5801
5792
  }
5802
5793
  };
5803
5794
 
5804
5795
  // src/decoder/compression/mesh/MeshEdgebreakerTraversalValenceDecoder.ts
5805
5796
  var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraversalDecoder {
5806
5797
  a = null;
5807
- i = 0;
5798
+ j = 0;
5808
5799
  x = -1;
5809
5800
  Ma = -1;
5810
5801
  Na = 2;
5811
- hb = 7;
5812
- j = new Int32Array(0);
5802
+ fb = 7;
5803
+ k = EMPTY_INT32;
5813
5804
  ha = [];
5814
5805
  // Int32Array, not number[]: read and written once per decoded symbol.
5815
- ya = new Int32Array(0);
5806
+ ya = EMPTY_INT32;
5816
5807
  // corner -> vertex of _cornerTable, cached at init(); the array is created
5817
5808
  // once by CornerTable.reset() before the traversal decoder is initialized and
5818
5809
  // never replaced, so the per-symbol hot path can read it without two property
5819
5810
  // loads.
5820
- h = new Int32Array(0);
5811
+ i = EMPTY_INT32;
5821
5812
  init(decoder) {
5822
5813
  super.init(decoder);
5823
5814
  this.a = decoder.getCornerTable();
5824
- this.h = this.a.h;
5815
+ this.i = this.a.i;
5825
5816
  }
5826
5817
  setNumEncodedVertices(numVertices) {
5827
- this.i = numVertices;
5818
+ this.j = numVertices;
5828
5819
  }
5829
5820
  start(outBuffer) {
5830
5821
  if (!this.decodeStartFaces()) {
@@ -5833,9 +5824,9 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
5833
5824
  if (!this.decodeAttributeSeams()) {
5834
5825
  return false;
5835
5826
  }
5836
- outBuffer.init(this.c.dataHead, this.c.remainingSize);
5837
- this.j = scratchInt32Filled(this.i, 0);
5838
- const numUniqueValences = this.hb - this.Na + 1;
5827
+ outBuffer.initFrom(this.c);
5828
+ this.k = scratchInt32Filled(this.j, 0);
5829
+ const numUniqueValences = this.fb - this.Na + 1;
5839
5830
  this.ha = new Array(numUniqueValences);
5840
5831
  this.ya = new Int32Array(numUniqueValences);
5841
5832
  const pending = [];
@@ -5876,7 +5867,7 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
5876
5867
  return false;
5877
5868
  }
5878
5869
  pending.push(decoder);
5879
- streams.push({ ans: decoder.G, out: this.ha[i], count: numSymbols });
5870
+ streams.push({ ans: decoder.H, out: this.ha[i], count: numSymbols });
5880
5871
  this.ya[i] = numSymbols;
5881
5872
  } else {
5882
5873
  this.ha[i] = new Uint32Array(0);
@@ -5904,8 +5895,8 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
5904
5895
  return this.x;
5905
5896
  }
5906
5897
  newActiveCornerReached(corner) {
5907
- const cornerToVertex = this.h;
5908
- const valences = this.j;
5898
+ const cornerToVertex = this.i;
5899
+ const valences = this.k;
5909
5900
  const next = corner % 3 === 2 ? corner - 2 : corner + 1;
5910
5901
  const prev = corner % 3 === 0 ? corner + 2 : corner - 1;
5911
5902
  const vertNext = cornerToVertex[next];
@@ -5938,15 +5929,15 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
5938
5929
  let clampedValence;
5939
5930
  if (activeValence < this.Na) {
5940
5931
  clampedValence = this.Na;
5941
- } else if (activeValence > this.hb) {
5942
- clampedValence = this.hb;
5932
+ } else if (activeValence > this.fb) {
5933
+ clampedValence = this.fb;
5943
5934
  } else {
5944
5935
  clampedValence = activeValence;
5945
5936
  }
5946
5937
  this.Ma = clampedValence - this.Na;
5947
5938
  }
5948
5939
  mergeVertices(dest, source) {
5949
- this.j[dest] += this.j[source];
5940
+ this.k[dest] += this.k[source];
5950
5941
  }
5951
5942
  };
5952
5943
 
@@ -5987,7 +5978,7 @@ var LinearSequencer = class {
5987
5978
  constructor(numPoints) {
5988
5979
  this.Oa = numPoints;
5989
5980
  }
5990
- generateSequence() {
5981
+ generateSequence(_parallelogramParents) {
5991
5982
  if (this.Oa < 0) {
5992
5983
  return false;
5993
5984
  }