minidraco 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1112 -1121
- package/dist/pool.js +19 -19
- package/dist/three.d.ts +3 -2
- package/dist/three.js +1120 -1129
- package/dist/worker.js +1112 -1121
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -34,31 +34,31 @@ var Type = {
|
|
|
34
34
|
var GeometryAttribute = class {
|
|
35
35
|
c = null;
|
|
36
36
|
v = 1;
|
|
37
|
-
|
|
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.
|
|
46
|
+
this.P = dataType;
|
|
47
47
|
this.Pa = normalized;
|
|
48
|
-
this.
|
|
49
|
-
this.
|
|
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.
|
|
55
|
-
this.
|
|
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.
|
|
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.
|
|
70
|
+
return this.Q;
|
|
71
71
|
}
|
|
72
72
|
get byteOffset() {
|
|
73
|
-
return this.
|
|
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
|
-
|
|
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.
|
|
147
|
+
return this.gb;
|
|
148
148
|
}
|
|
149
149
|
setNumPoints(num) {
|
|
150
|
-
this.
|
|
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
|
-
|
|
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.
|
|
172
|
+
this.hb = numFaces;
|
|
173
173
|
}
|
|
174
174
|
numFaces() {
|
|
175
|
-
return this.
|
|
175
|
+
return this.hb;
|
|
176
176
|
}
|
|
177
177
|
};
|
|
178
178
|
|
|
179
179
|
// src/decoder/core/DataBuffer.ts
|
|
180
180
|
var DataBuffer = class {
|
|
181
|
-
|
|
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.
|
|
186
|
+
this.ib(size);
|
|
187
187
|
return;
|
|
188
188
|
}
|
|
189
|
-
if (size > this.
|
|
190
|
-
this.
|
|
189
|
+
if (size > this.f.length) {
|
|
190
|
+
this.ib(size);
|
|
191
191
|
}
|
|
192
|
-
this.
|
|
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.
|
|
198
|
+
this.f.set(inArray.length === dataSize ? inArray : inArray.subarray(0, dataSize), bytePos);
|
|
199
199
|
}
|
|
200
200
|
get data() {
|
|
201
|
-
return this.
|
|
201
|
+
return this.f;
|
|
202
202
|
}
|
|
203
|
-
|
|
204
|
-
if (newSize === this.
|
|
203
|
+
ib(newSize) {
|
|
204
|
+
if (newSize === this.f.length) return;
|
|
205
205
|
const newData = new Uint8Array(newSize);
|
|
206
|
-
newData.set(this.
|
|
207
|
-
this.
|
|
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
|
|
213
|
-
var
|
|
214
|
-
var
|
|
215
|
-
var
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
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
|
|
227
|
-
|
|
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
|
|
236
|
-
|
|
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
|
|
246
|
-
|
|
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
|
-
|
|
276
|
-
|
|
277
|
-
|
|
245
|
+
if (outgrown > 0) {
|
|
246
|
+
arena = new ArrayBuffer(outgrown + top);
|
|
247
|
+
outgrown = 0;
|
|
278
248
|
}
|
|
279
|
-
|
|
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
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
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
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
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
|
-
|
|
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.
|
|
319
|
+
this.S = new DataBuffer();
|
|
360
320
|
const byteStride = dataTypeLength(dataType) * numComponents;
|
|
361
|
-
super.init(attributeType, this.
|
|
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.
|
|
367
|
-
this.
|
|
326
|
+
if (this.S === null) {
|
|
327
|
+
this.S = new DataBuffer();
|
|
368
328
|
}
|
|
369
329
|
const entrySize = dataTypeLength(this.dataType) * this.numComponents;
|
|
370
|
-
this.
|
|
371
|
-
this.resetBuffer(this.
|
|
372
|
-
this.
|
|
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.
|
|
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.
|
|
384
|
-
this
|
|
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.
|
|
390
|
-
this
|
|
391
|
-
this.
|
|
392
|
-
this.
|
|
393
|
-
this.
|
|
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.
|
|
399
|
-
this
|
|
400
|
-
this.
|
|
401
|
-
this.
|
|
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.
|
|
373
|
+
return this.Ba;
|
|
405
374
|
}
|
|
406
375
|
mappedIndex(pointIndex) {
|
|
407
|
-
if (this.
|
|
376
|
+
if (this.A) {
|
|
408
377
|
return pointIndex;
|
|
409
378
|
}
|
|
410
|
-
return this.
|
|
379
|
+
return this.B[pointIndex];
|
|
411
380
|
}
|
|
412
381
|
get isMappingIdentity() {
|
|
413
|
-
return this.
|
|
382
|
+
return this.A;
|
|
414
383
|
}
|
|
415
384
|
get indicesMapSize() {
|
|
416
|
-
if (this.
|
|
385
|
+
if (this.A) {
|
|
417
386
|
return 0;
|
|
418
387
|
}
|
|
419
|
-
return this.
|
|
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.
|
|
394
|
+
return this.B;
|
|
426
395
|
}
|
|
427
396
|
// Implicit mapping: point index equals attribute entry index.
|
|
428
397
|
setIdentityMapping() {
|
|
429
|
-
this.
|
|
430
|
-
this.
|
|
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.
|
|
441
|
-
this.
|
|
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.
|
|
448
|
-
this.
|
|
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.
|
|
455
|
-
this.
|
|
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
|
-
|
|
459
|
-
if (this.
|
|
460
|
-
this.
|
|
461
|
-
this.
|
|
462
|
-
this.
|
|
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.
|
|
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.
|
|
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.
|
|
479
|
-
const baseIndex = (bufData.byteOffset + this.
|
|
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.
|
|
459
|
+
const kind = this.Ca;
|
|
491
460
|
if (kind !== LAZY_NONE) {
|
|
492
|
-
if (this
|
|
493
|
-
if (kind ===
|
|
494
|
-
|
|
495
|
-
else
|
|
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.
|
|
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.
|
|
505
|
-
const indicesMap = this.
|
|
506
|
-
const srcView = this.
|
|
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.
|
|
509
|
-
const strideElements = this.
|
|
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
|
-
|
|
537
|
-
if (!this.
|
|
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
|
-
|
|
551
|
-
const values = this
|
|
552
|
-
if (this.
|
|
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
|
-
|
|
563
|
-
|
|
564
|
-
const
|
|
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.
|
|
568
|
-
const min = this.
|
|
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(
|
|
576
|
-
out[d + 1] = fround(
|
|
577
|
-
out[d + 2] = fround(
|
|
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(
|
|
587
|
-
out[d + 1] = fround(
|
|
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(
|
|
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
|
-
|
|
601
|
-
|
|
602
|
-
|
|
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.
|
|
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
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
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
|
-
|
|
630
|
-
const values = this
|
|
631
|
-
const map = this.
|
|
601
|
+
Qb(out, numPoints) {
|
|
602
|
+
const values = this.$;
|
|
603
|
+
const map = this.Sa(numPoints);
|
|
632
604
|
const numComponents = this.v;
|
|
633
|
-
const dt = this.
|
|
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
|
-
|
|
666
|
-
|
|
637
|
+
Ea = null;
|
|
638
|
+
o = 0;
|
|
667
639
|
ja = 0;
|
|
668
|
-
reset(uint8Array,
|
|
669
|
-
this.
|
|
670
|
-
this.ja =
|
|
671
|
-
this.
|
|
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.
|
|
676
|
-
let off = this.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
714
|
-
|
|
715
|
-
|
|
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.
|
|
721
|
-
this.
|
|
722
|
-
this.
|
|
723
|
-
|
|
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.
|
|
728
|
-
const val = this.
|
|
729
|
-
this.
|
|
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
|
-
|
|
734
|
-
|
|
735
|
-
this.
|
|
736
|
-
|
|
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
|
-
|
|
740
|
-
|
|
741
|
-
this.
|
|
742
|
-
|
|
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
|
-
|
|
746
|
-
|
|
747
|
-
this.
|
|
748
|
-
|
|
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.
|
|
754
|
-
const result = this.
|
|
755
|
-
this.
|
|
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.
|
|
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.
|
|
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.
|
|
766
|
+
this.g += bytes;
|
|
781
767
|
}
|
|
782
768
|
get data() {
|
|
783
|
-
return this.
|
|
784
|
-
}
|
|
785
|
-
get dataHead() {
|
|
786
|
-
return this.m.subarray(this.d);
|
|
769
|
+
return this.f;
|
|
787
770
|
}
|
|
788
771
|
get remainingSize() {
|
|
789
|
-
return this.
|
|
772
|
+
return this.y - this.g;
|
|
790
773
|
}
|
|
791
774
|
get decodedSize() {
|
|
792
|
-
return this.
|
|
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.
|
|
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.
|
|
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.
|
|
806
|
+
if (decodeVarint(this.C) === void 0) {
|
|
824
807
|
return false;
|
|
825
808
|
}
|
|
826
|
-
if (!this.
|
|
809
|
+
if (!this.Ta(0)) {
|
|
827
810
|
return false;
|
|
828
811
|
}
|
|
829
812
|
}
|
|
830
|
-
return this.
|
|
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
|
-
|
|
817
|
+
Ta(level) {
|
|
835
818
|
if (level > kMaxSubmetadataLevel) {
|
|
836
819
|
return false;
|
|
837
820
|
}
|
|
838
|
-
const numEntries = decodeVarint(this.
|
|
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.
|
|
844
|
-
const dataSize = nameSkipped ? decodeVarint(this.
|
|
845
|
-
if (dataSize === void 0 || dataSize === 0 || !this.
|
|
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.
|
|
850
|
-
if (numSubMetadata === void 0 || numSubMetadata > this.
|
|
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.
|
|
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
|
-
|
|
862
|
-
const nameLen = this.
|
|
844
|
+
pb() {
|
|
845
|
+
const nameLen = this.C.decodeUint8();
|
|
863
846
|
if (nameLen === void 0) {
|
|
864
847
|
return false;
|
|
865
848
|
}
|
|
866
|
-
return this.
|
|
849
|
+
return this.qb(nameLen);
|
|
867
850
|
}
|
|
868
|
-
|
|
869
|
-
if (size > this.
|
|
851
|
+
qb(size) {
|
|
852
|
+
if (size > this.C.remainingSize) {
|
|
870
853
|
return false;
|
|
871
854
|
}
|
|
872
|
-
this.
|
|
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
|
|
951
|
-
//
|
|
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
|
-
|
|
984
|
-
|
|
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
|
-
|
|
1264
|
+
T = null;
|
|
1305
1265
|
c = null;
|
|
1306
|
-
|
|
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.
|
|
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.
|
|
1360
|
-
this.
|
|
1319
|
+
while (this.s.length <= attDecoderId) {
|
|
1320
|
+
this.s.push(null);
|
|
1361
1321
|
}
|
|
1362
|
-
this.
|
|
1322
|
+
this.s[attDecoderId] = decoder;
|
|
1363
1323
|
return true;
|
|
1364
1324
|
}
|
|
1365
1325
|
getPortableAttribute(parentAttId) {
|
|
1366
|
-
if (parentAttId < 0 || parentAttId >= this.
|
|
1326
|
+
if (parentAttId < 0 || parentAttId >= this.T.numAttributes()) {
|
|
1367
1327
|
return null;
|
|
1368
1328
|
}
|
|
1369
1329
|
const parentAttDecoderId = this.Ga[parentAttId];
|
|
1370
|
-
return this.
|
|
1330
|
+
return this.s[parentAttDecoderId].getPortableAttribute(parentAttId);
|
|
1371
1331
|
}
|
|
1372
1332
|
attributesDecoder(decId) {
|
|
1373
|
-
return this.
|
|
1333
|
+
return this.s[decId];
|
|
1374
1334
|
}
|
|
1375
1335
|
numAttributesDecoders() {
|
|
1376
|
-
return this.
|
|
1336
|
+
return this.s.length;
|
|
1377
1337
|
}
|
|
1378
1338
|
pointCloud() {
|
|
1379
|
-
return this.
|
|
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.
|
|
1406
|
-
if (!this.
|
|
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.
|
|
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.
|
|
1376
|
+
const numAttributes = this.s[i].getNumAttributes();
|
|
1417
1377
|
for (let j = 0; j < numAttributes; ++j) {
|
|
1418
|
-
const attId = this.
|
|
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.
|
|
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
|
-
|
|
1410
|
+
D = null;
|
|
1451
1411
|
// Returns an error message, or '' on success.
|
|
1452
1412
|
decodeMesh(header, inBuffer, outMesh) {
|
|
1453
|
-
this.
|
|
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.
|
|
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 =
|
|
1480
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
1461
|
+
this.E = table;
|
|
1502
1462
|
this.la = scratchUint8Zeroed(table.numVertices());
|
|
1503
|
-
this.
|
|
1504
|
-
this.
|
|
1505
|
-
this.
|
|
1506
|
-
this.
|
|
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
|
|
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.
|
|
1512
|
-
const opposite = this.
|
|
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
|
-
|
|
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.
|
|
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.
|
|
1540
|
-
this.
|
|
1541
|
-
this.
|
|
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.
|
|
1506
|
+
return this.F[corner];
|
|
1549
1507
|
}
|
|
1550
1508
|
next(corner) {
|
|
1551
|
-
return this.
|
|
1509
|
+
return this.E.next(corner);
|
|
1552
1510
|
}
|
|
1553
1511
|
previous(corner) {
|
|
1554
|
-
return this.
|
|
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.
|
|
1524
|
+
return this.E.numFaces();
|
|
1567
1525
|
}
|
|
1568
1526
|
numCorners() {
|
|
1569
|
-
return this.
|
|
1527
|
+
return this.E.numCorners();
|
|
1570
1528
|
}
|
|
1571
1529
|
// --- Flat-array accessors: let DepthFirstTraverser avoid per-corner dispatch. ---
|
|
1572
1530
|
cornerToVertexArray() {
|
|
1573
|
-
return this.
|
|
1531
|
+
return this.U;
|
|
1574
1532
|
}
|
|
1575
1533
|
// Seam-aware opposite corners (seam edges -> -1), matching opposite().
|
|
1576
1534
|
oppositeCornerArray() {
|
|
1577
|
-
return this.
|
|
1535
|
+
return this.F;
|
|
1578
1536
|
}
|
|
1579
1537
|
vertexOnBoundaryArray() {
|
|
1580
|
-
return this.
|
|
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.
|
|
1544
|
+
this.E = other.E;
|
|
1587
1545
|
this.la = other.la;
|
|
1588
|
-
this.
|
|
1546
|
+
this.U = other.U;
|
|
1589
1547
|
this.ma = other.ma;
|
|
1590
|
-
this.
|
|
1591
|
-
this.
|
|
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
|
-
|
|
1601
|
-
|
|
1558
|
+
rb = null;
|
|
1559
|
+
T = null;
|
|
1602
1560
|
init(decoder, pointCloud) {
|
|
1603
|
-
this.
|
|
1604
|
-
this.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1624
|
+
m = null;
|
|
1625
|
+
G = null;
|
|
1626
|
+
sb = -1;
|
|
1669
1627
|
// Decoded portable attribute (after lossless decoding).
|
|
1670
|
-
|
|
1628
|
+
V = null;
|
|
1671
1629
|
init(decoder, attributeId) {
|
|
1672
|
-
this.
|
|
1673
|
-
this.
|
|
1674
|
-
this.
|
|
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.
|
|
1643
|
+
if (this.G.numComponents <= 0) {
|
|
1686
1644
|
return false;
|
|
1687
1645
|
}
|
|
1688
|
-
if (!this.
|
|
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
|
-
|
|
1697
|
-
return this.
|
|
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.
|
|
1715
|
-
const size = this.
|
|
1716
|
-
this
|
|
1717
|
-
const src = this.
|
|
1718
|
-
const dst = this
|
|
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.
|
|
1686
|
+
return this.G;
|
|
1729
1687
|
}
|
|
1730
1688
|
get attributeId() {
|
|
1731
|
-
return this.
|
|
1689
|
+
return this.sb;
|
|
1732
1690
|
}
|
|
1733
1691
|
get decoder() {
|
|
1734
|
-
return this.
|
|
1692
|
+
return this.m;
|
|
1735
1693
|
}
|
|
1736
1694
|
initPredictionScheme(ps) {
|
|
1737
1695
|
for (let i = 0; i < ps.getNumParentAttributes(); i++) {
|
|
1738
|
-
const attId = this.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
1774
|
-
|
|
1731
|
+
ub = 0;
|
|
1732
|
+
H;
|
|
1775
1733
|
constructor(uniqueSymbolsBitLength) {
|
|
1776
1734
|
const unclamped = Math.trunc(3 * uniqueSymbolsBitLength / 2);
|
|
1777
|
-
this.
|
|
1735
|
+
this.H = new RAnsDecoder(unclamped < 12 ? 12 : unclamped > 20 ? 20 : unclamped);
|
|
1778
1736
|
}
|
|
1779
1737
|
get numSymbols() {
|
|
1780
|
-
return this.
|
|
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.
|
|
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.
|
|
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.
|
|
1790
|
+
return ansReadInit(this.H, buffer.data, base + Number(bytesEncoded), base, this.H.lRansBase, 4);
|
|
1833
1791
|
}
|
|
1834
1792
|
endDecoding() {
|
|
1835
|
-
this.
|
|
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
|
|
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.
|
|
1836
|
+
const buf = bd.Ea;
|
|
1867
1837
|
const byteLength = bd.ja;
|
|
1868
|
-
let bitOffset = bd.
|
|
1838
|
+
let bitOffset = bd.o;
|
|
1869
1839
|
let valueId = 0;
|
|
1870
1840
|
for (let i = 0; i < numValues; i += numComponents) {
|
|
1871
|
-
|
|
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.
|
|
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.
|
|
1876
|
+
bitOffset = bd.o;
|
|
1896
1877
|
} else {
|
|
1897
|
-
bd.
|
|
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.
|
|
1886
|
+
bitOffset = bd.o;
|
|
1906
1887
|
}
|
|
1907
1888
|
}
|
|
1908
|
-
|
|
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.
|
|
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
|
-
|
|
1969
|
+
d;
|
|
1987
1970
|
constructor(transform) {
|
|
1988
|
-
this.
|
|
1971
|
+
this.d = transform;
|
|
1989
1972
|
}
|
|
1990
1973
|
/** True if all correction values are guaranteed to be positive. */
|
|
1991
1974
|
areCorrectionsPositive() {
|
|
1992
|
-
return this.
|
|
1975
|
+
return this.d.areCorrectionsPositive();
|
|
1993
1976
|
}
|
|
1994
1977
|
boundsValues(limit) {
|
|
1995
|
-
return this.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
2204
|
+
K = -1;
|
|
2222
2205
|
aa = -1;
|
|
2223
|
-
|
|
2206
|
+
l = -1;
|
|
2224
2207
|
Vb = 1;
|
|
2225
|
-
|
|
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.
|
|
2212
|
+
this.K = q;
|
|
2230
2213
|
this.aa = (1 << q) - 1;
|
|
2231
|
-
this.
|
|
2232
|
-
this.Vb = Math.fround(2 / Math.fround(this.
|
|
2233
|
-
this.
|
|
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.
|
|
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.
|
|
2243
|
-
s = this.
|
|
2244
|
-
t = this.
|
|
2245
|
-
} else if (s === 0 && t > this.
|
|
2246
|
-
t = this.
|
|
2247
|
-
} else if (s === this.
|
|
2248
|
-
t = this.
|
|
2249
|
-
} else if (t === this.
|
|
2250
|
-
s = this.
|
|
2251
|
-
} else if (t === 0 && s > this.
|
|
2252
|
-
s = this.
|
|
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.
|
|
2263
|
-
t = intVec[2] + this.
|
|
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.
|
|
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.
|
|
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.
|
|
2265
|
+
vec[0] = this.e;
|
|
2283
2266
|
} else {
|
|
2284
|
-
vec[0] = Math.trunc(vec[0] * this.
|
|
2285
|
-
vec[1] = Math.trunc(vec[1] * this.
|
|
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.
|
|
2270
|
+
vec[2] = this.e - Math.abs(vec[0]) - Math.abs(vec[1]);
|
|
2288
2271
|
} else {
|
|
2289
|
-
vec[2] = -(this.
|
|
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
|
|
2300
|
-
const
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
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
|
-
|
|
2326
|
-
|
|
2327
|
-
const
|
|
2328
|
-
cache[o] =
|
|
2329
|
-
cache[o + 1] =
|
|
2330
|
-
cache[o + 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
|
-
|
|
2339
|
-
|
|
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
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
this.
|
|
2357
|
-
const
|
|
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
|
|
2362
|
-
const
|
|
2363
|
-
for (let c = 0; c <
|
|
2364
|
-
const
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
const
|
|
2382
|
-
const
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
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
|
-
|
|
2379
|
+
p;
|
|
2450
2380
|
w = new OctahedronToolBox();
|
|
2451
|
-
|
|
2381
|
+
Ua = new RAnsBitDecoder();
|
|
2452
2382
|
constructor(transform, meshData) {
|
|
2453
2383
|
super(transform, meshData);
|
|
2454
|
-
this.
|
|
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.
|
|
2395
|
+
this.p.setPositionAttribute(att);
|
|
2466
2396
|
return true;
|
|
2467
2397
|
}
|
|
2468
2398
|
decodePredictionData(buffer) {
|
|
2469
|
-
if (!this.
|
|
2470
|
-
return this.
|
|
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.
|
|
2474
|
-
this.
|
|
2403
|
+
this.w.setQuantizationBits(this.d.quantizationBits());
|
|
2404
|
+
this.p.setEntryToPointIdMap(entryToPointIdMap);
|
|
2475
2405
|
const cornerMapSize = this.b.dataToCornerMap.length;
|
|
2476
|
-
this.
|
|
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
|
-
|
|
2481
|
-
this.q.computePredictedValue(cornerId, predNormal3D);
|
|
2410
|
+
this.p.computePredictedValue(dataId, predNormal3D);
|
|
2482
2411
|
this.w.canonicalizeIntegerVector(predNormal3D);
|
|
2483
|
-
if (this.
|
|
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.
|
|
2419
|
+
this.d.computeOriginalValue(predNormalOct, 0, inCorr, dataOffset, outData, dataOffset);
|
|
2491
2420
|
}
|
|
2492
|
-
this.
|
|
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.
|
|
2430
|
+
this.d.init(numComponents);
|
|
2502
2431
|
const predVals = new Int32Array(numComponents);
|
|
2503
2432
|
const parallelogramPredVals = new Int32Array(numComponents);
|
|
2504
|
-
this.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
2579
|
-
const minValue = transform.
|
|
2580
|
-
const maxValue = transform.
|
|
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.
|
|
2647
|
-
const minValue = transform.
|
|
2648
|
-
const maxValue = transform.
|
|
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.
|
|
2725
|
-
const minValue = transform.
|
|
2726
|
-
const maxValue = transform.
|
|
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.
|
|
2834
|
-
const minValue = transform.
|
|
2835
|
-
const maxValue = transform.
|
|
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
|
-
|
|
2942
|
-
Ja =
|
|
2943
|
-
|
|
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
|
-
|
|
2948
|
-
|
|
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.
|
|
2887
|
+
return this.q;
|
|
2960
2888
|
}
|
|
2961
2889
|
resizeOrientations(numOrientations) {
|
|
2962
2890
|
this.Ja = new Uint8Array(numOrientations);
|
|
2963
|
-
this.
|
|
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
|
|
2971
|
-
this.
|
|
2972
|
-
this.
|
|
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.
|
|
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.
|
|
2991
|
-
this.
|
|
2918
|
+
this.q[0] = pUV0;
|
|
2919
|
+
this.q[1] = pUV1;
|
|
2992
2920
|
return true;
|
|
2993
2921
|
}
|
|
2994
|
-
const posCache = this.
|
|
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
|
|
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.
|
|
2981
|
+
if (this.sa === 0) {
|
|
3064
2982
|
return false;
|
|
3065
2983
|
}
|
|
3066
|
-
const orientation = this.Ja[--this.
|
|
2984
|
+
const orientation = this.Ja[--this.sa];
|
|
3067
2985
|
if (orientation) {
|
|
3068
|
-
this.
|
|
3069
|
-
this.
|
|
2986
|
+
this.q[0] = Math.trunc((xUV0 + cxUV0) / pnNorm2Squared);
|
|
2987
|
+
this.q[1] = Math.trunc((xUV1 + cxUV1) / pnNorm2Squared);
|
|
3070
2988
|
} else {
|
|
3071
|
-
this.
|
|
3072
|
-
this.
|
|
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.
|
|
3088
|
-
this.
|
|
3005
|
+
this.q[0] = 0;
|
|
3006
|
+
this.q[1] = 0;
|
|
3089
3007
|
return true;
|
|
3090
3008
|
}
|
|
3091
3009
|
}
|
|
3092
|
-
this.
|
|
3093
|
-
this.
|
|
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.
|
|
3136
|
-
const orientation = this.Ja[--this.
|
|
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.
|
|
3146
|
-
this.
|
|
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
|
-
|
|
3072
|
+
p;
|
|
3155
3073
|
constructor(transform, meshData) {
|
|
3156
3074
|
super(transform, meshData);
|
|
3157
|
-
this.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
3192
|
-
this.
|
|
3109
|
+
this.p.setEntryToPointIdMap(entryToPointIdMap);
|
|
3110
|
+
this.d.init(numComponents);
|
|
3193
3111
|
const cornerMapSize = this.b.dataToCornerMap.length;
|
|
3194
|
-
this.
|
|
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.
|
|
3115
|
+
if (!this.p.computePredictedValue(cornerId, outData, p)) {
|
|
3198
3116
|
return false;
|
|
3199
3117
|
}
|
|
3200
3118
|
const dstOffset = p * numComponents;
|
|
3201
|
-
this.
|
|
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.
|
|
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
|
-
|
|
3267
|
-
|
|
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.
|
|
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.
|
|
3284
|
-
const maxValue = this.
|
|
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.
|
|
3310
|
-
this.
|
|
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
|
-
|
|
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
|
-
|
|
3324
|
-
|
|
3325
|
-
//
|
|
3326
|
-
|
|
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.
|
|
3252
|
+
const portableData = this.M;
|
|
3333
3253
|
return {
|
|
3334
|
-
ans: this.ca.
|
|
3335
|
-
out: new Uint32Array(portableData.buffer, portableData.byteOffset, this.
|
|
3336
|
-
count: this.
|
|
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.
|
|
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.
|
|
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.
|
|
3284
|
+
this.L = this.createIntPredictionScheme(predictionSchemeMethod, predictionTransformType);
|
|
3365
3285
|
}
|
|
3366
|
-
if (this.
|
|
3367
|
-
if (!this.initPredictionScheme(this.
|
|
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.
|
|
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.
|
|
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.
|
|
3418
|
-
if (!this.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
3920
|
-
const q = this.
|
|
3855
|
+
Wa(_numPoints) {
|
|
3856
|
+
const q = this.K;
|
|
3921
3857
|
if (q < 2 || q > 30) return false;
|
|
3922
3858
|
this.attribute.setLazyOctahedron(
|
|
3923
|
-
this.
|
|
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
|
-
|
|
3941
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
3899
|
+
this.K = qBits;
|
|
3964
3900
|
return true;
|
|
3965
3901
|
}
|
|
3966
3902
|
// Dequantization is deferred to extractTo (see PointAttribute.setLazyQuantized).
|
|
3967
|
-
|
|
3968
|
-
const maxQuantizedValue = (1 << this.
|
|
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.
|
|
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
|
-
|
|
3914
|
+
da = [];
|
|
3979
3915
|
// Replaced by the sequencer's output in _prepareSequence.
|
|
3980
|
-
Ka =
|
|
3981
|
-
|
|
3916
|
+
Ka = EMPTY_INT32;
|
|
3917
|
+
X;
|
|
3982
3918
|
constructor(sequencer) {
|
|
3983
3919
|
super();
|
|
3984
|
-
this.
|
|
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.
|
|
3934
|
+
this.da[i] = decoder;
|
|
3999
3935
|
}
|
|
4000
3936
|
return true;
|
|
4001
3937
|
}
|
|
4002
|
-
ac() {
|
|
4003
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
4108
|
-
|
|
4045
|
+
ta = null;
|
|
4046
|
+
ua = null;
|
|
4109
4047
|
Cb = [];
|
|
4110
|
-
|
|
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
|
|
4053
|
+
// the traversal (see traverseAll).
|
|
4116
4054
|
emitsPointIds = false;
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
|
|
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.
|
|
4124
|
-
this.
|
|
4125
|
-
this.
|
|
4126
|
-
this.
|
|
4127
|
-
this.
|
|
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 (
|
|
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.
|
|
4142
|
-
this.Cb = scratchInt32(this.
|
|
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.
|
|
4146
|
-
//
|
|
4147
|
-
//
|
|
4148
|
-
//
|
|
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.
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
|
|
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.
|
|
4103
|
+
let numVisitedFaces = this.va;
|
|
4170
4104
|
const encodingData = observer.n;
|
|
4171
|
-
const encodedToCornerMap = observer.
|
|
4172
|
-
const vertexToEncodedMap = observer
|
|
4105
|
+
const encodedToCornerMap = observer.Ya;
|
|
4106
|
+
const vertexToEncodedMap = observer.Za;
|
|
4107
|
+
const parents = this.Eb;
|
|
4173
4108
|
let numValues = encodingData.numValues;
|
|
4174
|
-
let
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
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
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
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
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
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
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
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
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
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
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
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.
|
|
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
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
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
|
-
|
|
4227
|
+
Y = 0;
|
|
4263
4228
|
// Prediction degree accumulated per vertex during traversal.
|
|
4264
|
-
|
|
4229
|
+
$a = null;
|
|
4265
4230
|
// Flat connectivity arrays (see DepthFirstTraverser for why).
|
|
4266
|
-
|
|
4267
|
-
|
|
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.
|
|
4276
|
-
this.
|
|
4277
|
-
this.
|
|
4278
|
-
this.
|
|
4279
|
-
this.
|
|
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
|
-
|
|
4251
|
+
Fb(c) {
|
|
4287
4252
|
return c % 3 === 2 ? c - 2 : c + 1;
|
|
4288
4253
|
}
|
|
4289
|
-
|
|
4254
|
+
Gb(c) {
|
|
4290
4255
|
return c % 3 === 0 ? c + 2 : c - 1;
|
|
4291
4256
|
}
|
|
4292
4257
|
onTraversalStart() {
|
|
4293
|
-
this
|
|
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.
|
|
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
|
-
|
|
4310
|
-
const vTip = this.
|
|
4274
|
+
Hb(cornerId) {
|
|
4275
|
+
const vTip = this.i[cornerId];
|
|
4311
4276
|
let priority = 0;
|
|
4312
|
-
if (!this.
|
|
4313
|
-
const degree = ++this
|
|
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
|
-
|
|
4286
|
+
Ib(ci, priority) {
|
|
4322
4287
|
this.La[priority].push(ci);
|
|
4323
|
-
if (priority < this.
|
|
4324
|
-
this.
|
|
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.
|
|
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.
|
|
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.
|
|
4306
|
+
if (this.$a.length === 0) {
|
|
4342
4307
|
return true;
|
|
4343
4308
|
}
|
|
4344
|
-
const cornerToVertex = this.
|
|
4345
|
-
const oppositeCorners = this.
|
|
4346
|
-
const isFaceVisited = this.
|
|
4347
|
-
const isVertexVisited = this.
|
|
4348
|
-
const observer = this.
|
|
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.
|
|
4351
|
-
const firstNext = this.
|
|
4352
|
-
const firstPrev = this.
|
|
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.
|
|
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.
|
|
4383
|
-
const leftCornerId = oppositeCorners[this.
|
|
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.
|
|
4390
|
-
if (isRightFaceVisited && priority <= this.
|
|
4354
|
+
const priority = this.Hb(leftCornerId);
|
|
4355
|
+
if (isRightFaceVisited && priority <= this.Y) {
|
|
4391
4356
|
cornerId = leftCornerId;
|
|
4392
4357
|
continue;
|
|
4393
4358
|
} else {
|
|
4394
|
-
this.
|
|
4359
|
+
this.Ib(leftCornerId, priority);
|
|
4395
4360
|
}
|
|
4396
4361
|
}
|
|
4397
4362
|
if (!isRightFaceVisited) {
|
|
4398
|
-
const priority = this.
|
|
4399
|
-
if (priority <= this.
|
|
4363
|
+
const priority = this.Hb(rightCornerId);
|
|
4364
|
+
if (priority <= this.Y) {
|
|
4400
4365
|
cornerId = rightCornerId;
|
|
4401
4366
|
continue;
|
|
4402
4367
|
} else {
|
|
4403
|
-
this.
|
|
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
|
-
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4381
|
+
X;
|
|
4382
|
+
Za;
|
|
4383
|
+
Ya;
|
|
4384
|
+
Jb;
|
|
4420
4385
|
constructor(mesh, sequencer, encodingData) {
|
|
4421
4386
|
this.n = encodingData;
|
|
4422
|
-
this.
|
|
4423
|
-
this
|
|
4424
|
-
this.
|
|
4425
|
-
this.
|
|
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.
|
|
4429
|
-
this.
|
|
4393
|
+
const pointId = this.Jb[corner];
|
|
4394
|
+
this.X.addPointId(pointId);
|
|
4430
4395
|
const numValues = this.n.numValues;
|
|
4431
|
-
this.
|
|
4432
|
-
this
|
|
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
|
-
|
|
4404
|
+
D;
|
|
4440
4405
|
n;
|
|
4441
|
-
|
|
4442
|
-
u =
|
|
4443
|
-
|
|
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
|
-
|
|
4411
|
+
ab;
|
|
4447
4412
|
// The cache entry the last generateSequence resolved to (hit or store);
|
|
4448
4413
|
// carries the shared indicesMap.
|
|
4449
|
-
|
|
4414
|
+
bb = null;
|
|
4450
4415
|
// One representative corner per point id, when the connectivity decoder
|
|
4451
4416
|
// recorded them (see MeshEdgebreakerDecoderImpl._assignAttributeVerticesAndPoints).
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
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.
|
|
4457
|
-
this.
|
|
4423
|
+
this.ab = traversalCache;
|
|
4424
|
+
this.Z = pointCorner;
|
|
4425
|
+
this.xa = pointVertexTable;
|
|
4458
4426
|
}
|
|
4459
4427
|
setTraverser(traverser) {
|
|
4460
|
-
this.
|
|
4461
|
-
}
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
4472
|
+
parents
|
|
4496
4473
|
};
|
|
4497
4474
|
byMethod.set(methodId, entry);
|
|
4498
4475
|
encodingData.cacheEntry = entry;
|
|
4499
|
-
this.
|
|
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.
|
|
4483
|
+
this.u[this.wa++] = pointId;
|
|
4507
4484
|
}
|
|
4508
4485
|
updatePointToAttributeIndexMapping(attribute) {
|
|
4509
|
-
const entry = this.
|
|
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.
|
|
4515
|
-
const numFaces = this.
|
|
4516
|
-
const numPoints = this.
|
|
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.
|
|
4522
|
-
if (
|
|
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.
|
|
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.
|
|
4557
|
-
this.u = scratchInt32(this.
|
|
4558
|
-
const traverser = this.
|
|
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.
|
|
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.
|
|
4556
|
+
this.wa = numValues;
|
|
4572
4557
|
}
|
|
4573
|
-
if (this.
|
|
4574
|
-
this.u = this.u.subarray(0, this.
|
|
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
|
-
|
|
4568
|
+
m;
|
|
4584
4569
|
a = null;
|
|
4585
4570
|
N = [];
|
|
4586
|
-
fa =
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
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
|
-
|
|
4594
|
-
|
|
4578
|
+
h = [];
|
|
4579
|
+
J;
|
|
4595
4580
|
// One corner per point id (decode-scoped scratch), filled by
|
|
4596
|
-
// _assignAttributeVerticesAndPoints; null
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
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.
|
|
4602
|
-
this.
|
|
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.
|
|
4610
|
-
const ad = this.
|
|
4611
|
-
if (ad.decoderId < 0 || ad.decoderId >= this.
|
|
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.
|
|
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.
|
|
4616
|
+
return ad !== null ? ad.encodingData : this.cb;
|
|
4630
4617
|
}
|
|
4631
4618
|
createAttributesDecoder(attDecoderId) {
|
|
4632
|
-
const buffer = this.
|
|
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.
|
|
4626
|
+
if (attDataId >= this.h.length) {
|
|
4640
4627
|
return false;
|
|
4641
4628
|
}
|
|
4642
|
-
if (this.
|
|
4629
|
+
if (this.h[attDataId].decoderId >= 0) {
|
|
4643
4630
|
return false;
|
|
4644
4631
|
}
|
|
4645
|
-
this.
|
|
4632
|
+
this.h[attDataId].decoderId = attDecoderId;
|
|
4646
4633
|
} else {
|
|
4647
|
-
if (this.
|
|
4634
|
+
if (this.Kb >= 0) {
|
|
4648
4635
|
return false;
|
|
4649
4636
|
}
|
|
4650
|
-
this.
|
|
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.
|
|
4647
|
+
encodingData = this.cb;
|
|
4661
4648
|
} else {
|
|
4662
|
-
encodingData = this.
|
|
4663
|
-
this.
|
|
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.
|
|
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.
|
|
4676
|
-
const sequencer = new MeshTraversalSequencer(
|
|
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.
|
|
4674
|
+
return this.m.setAttributesDecoder(attDecoderId, new SequentialAttributeDecodersController(sequencer));
|
|
4682
4675
|
}
|
|
4683
4676
|
decodeConnectivity() {
|
|
4684
|
-
const buffer = this.
|
|
4677
|
+
const buffer = this.m.buffer();
|
|
4685
4678
|
const numEncodedVertices = decodeVarint(buffer);
|
|
4686
4679
|
if (numEncodedVertices === void 0) return false;
|
|
4687
|
-
this.
|
|
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.
|
|
4686
|
+
if (this._ > numFaces * 3) {
|
|
4694
4687
|
return false;
|
|
4695
4688
|
}
|
|
4696
4689
|
const minNumFaceEdges = Math.floor(3 * numFaces / 2);
|
|
4697
|
-
const maxNumVertexEdges = this.
|
|
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.
|
|
4715
|
+
this.h.push(ad);
|
|
4723
4716
|
}
|
|
4724
|
-
this.a.reset(numFaces, this.
|
|
4725
|
-
this.fa = scratchUint8Filled(this.
|
|
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.
|
|
4730
|
-
this.
|
|
4731
|
-
this.
|
|
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.
|
|
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.
|
|
4733
|
+
buffer.initFrom(traversalEndBuffer);
|
|
4741
4734
|
this.a.finishBoundaries();
|
|
4742
|
-
if (this.
|
|
4735
|
+
if (this.h.length > 0) {
|
|
4743
4736
|
this.hc();
|
|
4744
4737
|
}
|
|
4745
|
-
this.
|
|
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.
|
|
4754
|
-
const connectivityData = this.
|
|
4755
|
-
const seamCorners = this.
|
|
4756
|
-
const seamCount = this.
|
|
4757
|
-
if (seamCount ===
|
|
4758
|
-
this.
|
|
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.
|
|
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.
|
|
4794
|
-
for (let i = 0; i < this.
|
|
4795
|
-
let attConnectivityVerts = this.
|
|
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.
|
|
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.
|
|
4818
|
+
const removeInvalidVertices = this.h.length === 0;
|
|
4827
4819
|
let maxNumVertices = this.fa.length;
|
|
4828
4820
|
let numFacesDecoded = 0;
|
|
4829
|
-
const cornerToVertex = this.a.
|
|
4830
|
-
const oppositeCorners = this.a.
|
|
4821
|
+
const cornerToVertex = this.a.i;
|
|
4822
|
+
const oppositeCorners = this.a.t;
|
|
4831
4823
|
const vc = this.a;
|
|
4832
|
-
let vertexCorners = vc.
|
|
4824
|
+
let vertexCorners = vc.r;
|
|
4833
4825
|
const isVertHole = this.fa;
|
|
4834
|
-
const traversalDecoder = this.
|
|
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.
|
|
4887
|
-
newVertIndex = vc.
|
|
4878
|
+
if (vc.j < vertexCorners.length) {
|
|
4879
|
+
newVertIndex = vc.j++;
|
|
4888
4880
|
} else {
|
|
4889
4881
|
newVertIndex = vc.addNewVertex();
|
|
4890
|
-
vertexCorners = vc.
|
|
4882
|
+
vertexCorners = vc.r;
|
|
4891
4883
|
}
|
|
4892
|
-
if (vc.
|
|
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.
|
|
4954
|
-
firstVertIndex = vc.
|
|
4955
|
-
vc.
|
|
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.
|
|
4952
|
+
vertexCorners = vc.r;
|
|
4961
4953
|
}
|
|
4962
|
-
if (vc.
|
|
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.
|
|
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.
|
|
5008
|
-
const cornerToVertex = ct.
|
|
5009
|
-
const vertexCorners = ct.
|
|
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.
|
|
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.
|
|
5062
|
-
const vertexCorners = ct.
|
|
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
|
|
5145
|
-
// invalid
|
|
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.
|
|
5140
|
+
const attributeData = this.h;
|
|
5149
5141
|
const numAttrData = attributeData.length;
|
|
5150
|
-
const connectivityDecoders = this.
|
|
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
|
-
|
|
5157
|
-
|
|
5158
|
-
numCandidates
|
|
5159
|
-
|
|
5160
|
-
|
|
5161
|
-
|
|
5162
|
-
|
|
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.
|
|
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.
|
|
5197
|
-
this.
|
|
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.
|
|
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].
|
|
5257
|
-
attOpposite[t] = tables[t].
|
|
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
|
|
5265
|
-
const
|
|
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(
|
|
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.
|
|
5390
|
-
this.
|
|
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] =
|
|
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 =
|
|
5478
|
-
encodedAttributeValueIndexToCornerMap =
|
|
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 =
|
|
5495
|
+
attributeSeamCorners = EMPTY_INT32;
|
|
5505
5496
|
numSeamCorners = 0;
|
|
5506
|
-
// Set when
|
|
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
|
-
|
|
5513
|
-
|
|
5514
|
-
|
|
5503
|
+
I = 0;
|
|
5504
|
+
j = 0;
|
|
5505
|
+
i = null;
|
|
5515
5506
|
// corner -> vertex
|
|
5516
|
-
|
|
5507
|
+
t = null;
|
|
5517
5508
|
// corner -> opposite corner
|
|
5518
|
-
|
|
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
|
-
|
|
5515
|
+
z = null;
|
|
5525
5516
|
reset(numFaces, numVertices) {
|
|
5526
5517
|
this.Nb = numFaces;
|
|
5527
|
-
this.
|
|
5528
|
-
this.
|
|
5529
|
-
this.
|
|
5530
|
-
this.
|
|
5531
|
-
this.
|
|
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.
|
|
5528
|
+
return this.I;
|
|
5538
5529
|
}
|
|
5539
5530
|
numVertices() {
|
|
5540
|
-
return this.
|
|
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.
|
|
5554
|
-
return this.
|
|
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.
|
|
5558
|
-
return this.
|
|
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.
|
|
5553
|
+
return this.i;
|
|
5563
5554
|
}
|
|
5564
5555
|
oppositeCornerArray() {
|
|
5565
|
-
return this.
|
|
5556
|
+
return this.t;
|
|
5566
5557
|
}
|
|
5567
5558
|
vertexLeftmostCornerArray() {
|
|
5568
|
-
return this.
|
|
5559
|
+
return this.r;
|
|
5569
5560
|
}
|
|
5570
5561
|
vertexOnBoundaryArray() {
|
|
5571
|
-
return this.
|
|
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.
|
|
5577
|
-
const vertexCorners = this.
|
|
5578
|
-
const oppositeCorners = this.
|
|
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.
|
|
5575
|
+
this.z = onBoundary;
|
|
5585
5576
|
}
|
|
5586
5577
|
// Mirrors C++ CornerTable::AddNewVertex() (push_back(kInvalidCornerIndex)).
|
|
5587
5578
|
addNewVertex() {
|
|
5588
|
-
const newVertex = this.
|
|
5589
|
-
this.
|
|
5590
|
-
if (newVertex >= this.
|
|
5591
|
-
const newCapacity = Math.max(newVertex + 1, this.
|
|
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.
|
|
5594
|
-
this.
|
|
5584
|
+
newArr.set(this.r);
|
|
5585
|
+
this.r = newArr;
|
|
5595
5586
|
}
|
|
5596
|
-
this.
|
|
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
|
-
|
|
5619
|
-
|
|
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.
|
|
5628
|
-
this.c.
|
|
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.
|
|
5638
|
+
outBuffer.initFrom(this.c);
|
|
5648
5639
|
return true;
|
|
5649
5640
|
}
|
|
5650
5641
|
decodeStartFaceConfiguration() {
|
|
5651
|
-
return this.
|
|
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.
|
|
5657
|
-
const off = bd.
|
|
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.
|
|
5653
|
+
bd.o = off + 1;
|
|
5663
5654
|
return TOPOLOGY_C;
|
|
5664
5655
|
}
|
|
5665
|
-
bd.
|
|
5656
|
+
bd.o = off + 3;
|
|
5666
5657
|
return bits;
|
|
5667
5658
|
}
|
|
5668
5659
|
}
|
|
5669
|
-
let symbol = this.
|
|
5660
|
+
let symbol = this.O.decodeLeastSignificantBits32(1);
|
|
5670
5661
|
if (symbol === TOPOLOGY_C) {
|
|
5671
5662
|
return symbol;
|
|
5672
5663
|
}
|
|
5673
|
-
const symbolSuffix = this.
|
|
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.
|
|
5683
|
-
this.
|
|
5673
|
+
if (this.O.bitDecoderActive) {
|
|
5674
|
+
this.O.endBitDecoding();
|
|
5684
5675
|
}
|
|
5685
5676
|
}
|
|
5686
5677
|
decodeTraversalSymbols() {
|
|
5687
|
-
this.
|
|
5688
|
-
const traversalSize = this.
|
|
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.
|
|
5693
|
-
this.c.
|
|
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.
|
|
5703
|
-
return this.
|
|
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
|
-
|
|
5714
|
+
j = 0;
|
|
5724
5715
|
x = -1;
|
|
5725
5716
|
ga = -1;
|
|
5726
|
-
|
|
5727
|
-
|
|
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.
|
|
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.
|
|
5734
|
+
if (numSplitSymbols >= this.j) {
|
|
5744
5735
|
return false;
|
|
5745
5736
|
}
|
|
5746
|
-
this.
|
|
5747
|
-
this.
|
|
5748
|
-
return this.
|
|
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.
|
|
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.
|
|
5768
|
-
this.
|
|
5758
|
+
this.k[ct.vertex(next)] += 1;
|
|
5759
|
+
this.k[ct.vertex(prev)] += 1;
|
|
5769
5760
|
break;
|
|
5770
5761
|
case TOPOLOGY_R:
|
|
5771
|
-
this.
|
|
5772
|
-
this.
|
|
5773
|
-
this.
|
|
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.
|
|
5777
|
-
this.
|
|
5778
|
-
this.
|
|
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.
|
|
5782
|
-
this.
|
|
5783
|
-
this.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
5798
|
+
j = 0;
|
|
5808
5799
|
x = -1;
|
|
5809
5800
|
Ma = -1;
|
|
5810
5801
|
Na = 2;
|
|
5811
|
-
|
|
5812
|
-
|
|
5802
|
+
fb = 7;
|
|
5803
|
+
k = EMPTY_INT32;
|
|
5813
5804
|
ha = [];
|
|
5814
5805
|
// Int32Array, not number[]: read and written once per decoded symbol.
|
|
5815
|
-
ya =
|
|
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
|
-
|
|
5811
|
+
i = EMPTY_INT32;
|
|
5821
5812
|
init(decoder) {
|
|
5822
5813
|
super.init(decoder);
|
|
5823
5814
|
this.a = decoder.getCornerTable();
|
|
5824
|
-
this.
|
|
5815
|
+
this.i = this.a.i;
|
|
5825
5816
|
}
|
|
5826
5817
|
setNumEncodedVertices(numVertices) {
|
|
5827
|
-
this.
|
|
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.
|
|
5837
|
-
this.
|
|
5838
|
-
const numUniqueValences = this.
|
|
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.
|
|
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.
|
|
5908
|
-
const valences = this.
|
|
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.
|
|
5942
|
-
clampedValence = this.
|
|
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.
|
|
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
|
}
|