minidraco 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -25
- package/dist/index.d.ts +13 -11
- package/dist/index.js +1223 -1456
- package/dist/pool.js +36 -36
- package/dist/three.d.ts +13 -11
- package/dist/three.js +1253 -1487
- package/dist/worker.js +1234 -1458
- package/package.json +1 -1
package/dist/three.js
CHANGED
|
@@ -11,37 +11,22 @@ import {
|
|
|
11
11
|
} from "three";
|
|
12
12
|
|
|
13
13
|
// src/decoder/core/DracoTypes.ts
|
|
14
|
-
var DataType = {
|
|
15
|
-
INVALID: 0,
|
|
16
|
-
INT8: 1,
|
|
17
|
-
UINT8: 2,
|
|
18
|
-
INT16: 3,
|
|
19
|
-
UINT16: 4,
|
|
20
|
-
INT32: 5,
|
|
21
|
-
UINT32: 6,
|
|
22
|
-
INT64: 7,
|
|
23
|
-
UINT64: 8,
|
|
24
|
-
FLOAT32: 9,
|
|
25
|
-
FLOAT64: 10,
|
|
26
|
-
BOOL: 11,
|
|
27
|
-
TYPES_COUNT: 12
|
|
28
|
-
};
|
|
29
14
|
function dataTypeLength(dt) {
|
|
30
15
|
switch (dt) {
|
|
31
|
-
case
|
|
32
|
-
case
|
|
33
|
-
case
|
|
16
|
+
case 1 /* INT8 */:
|
|
17
|
+
case 2 /* UINT8 */:
|
|
18
|
+
case 11 /* BOOL */:
|
|
34
19
|
return 1;
|
|
35
|
-
case
|
|
36
|
-
case
|
|
20
|
+
case 3 /* INT16 */:
|
|
21
|
+
case 4 /* UINT16 */:
|
|
37
22
|
return 2;
|
|
38
|
-
case
|
|
39
|
-
case
|
|
40
|
-
case
|
|
23
|
+
case 5 /* INT32 */:
|
|
24
|
+
case 6 /* UINT32 */:
|
|
25
|
+
case 9 /* FLOAT32 */:
|
|
41
26
|
return 4;
|
|
42
|
-
case
|
|
43
|
-
case
|
|
44
|
-
case
|
|
27
|
+
case 7 /* INT64 */:
|
|
28
|
+
case 8 /* UINT64 */:
|
|
29
|
+
case 10 /* FLOAT64 */:
|
|
45
30
|
return 8;
|
|
46
31
|
default:
|
|
47
32
|
return -1;
|
|
@@ -59,73 +44,73 @@ var Type = {
|
|
|
59
44
|
NAMED_ATTRIBUTES_COUNT: 5
|
|
60
45
|
};
|
|
61
46
|
var GeometryAttribute = class {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
47
|
+
d = null;
|
|
48
|
+
z = 1;
|
|
49
|
+
P = 9 /* FLOAT32 */;
|
|
50
|
+
_a = false;
|
|
51
|
+
Q = 0;
|
|
52
|
+
R = 0;
|
|
53
|
+
Ja = Type.INVALID;
|
|
54
|
+
Ka = 0;
|
|
70
55
|
init(attributeType, buffer, numComponents, dataType, normalized, byteStride, byteOffset) {
|
|
71
|
-
this.
|
|
72
|
-
this.
|
|
73
|
-
this.
|
|
74
|
-
this.
|
|
75
|
-
this.
|
|
76
|
-
this.
|
|
77
|
-
this.
|
|
56
|
+
this.d = buffer;
|
|
57
|
+
this.z = numComponents;
|
|
58
|
+
this.P = dataType;
|
|
59
|
+
this._a = normalized;
|
|
60
|
+
this.Q = byteStride;
|
|
61
|
+
this.R = byteOffset;
|
|
62
|
+
this.Ja = attributeType;
|
|
78
63
|
}
|
|
79
64
|
resetBuffer(buffer, byteStride, byteOffset) {
|
|
80
|
-
this.
|
|
81
|
-
this.
|
|
82
|
-
this.
|
|
65
|
+
this.d = buffer;
|
|
66
|
+
this.Q = byteStride;
|
|
67
|
+
this.R = byteOffset;
|
|
83
68
|
}
|
|
84
69
|
get attributeType() {
|
|
85
|
-
return this.
|
|
70
|
+
return this.Ja;
|
|
86
71
|
}
|
|
87
72
|
get dataType() {
|
|
88
|
-
return this.
|
|
73
|
+
return this.P;
|
|
89
74
|
}
|
|
90
75
|
get numComponents() {
|
|
91
|
-
return this.
|
|
76
|
+
return this.z;
|
|
92
77
|
}
|
|
93
78
|
get buffer() {
|
|
94
|
-
return this.
|
|
79
|
+
return this.d;
|
|
95
80
|
}
|
|
96
81
|
get byteStride() {
|
|
97
|
-
return this.
|
|
82
|
+
return this.Q;
|
|
98
83
|
}
|
|
99
84
|
get byteOffset() {
|
|
100
|
-
return this.
|
|
85
|
+
return this.R;
|
|
101
86
|
}
|
|
102
87
|
get uniqueId() {
|
|
103
|
-
return this.
|
|
88
|
+
return this.Ka;
|
|
104
89
|
}
|
|
105
90
|
set uniqueId(id) {
|
|
106
|
-
this.
|
|
91
|
+
this.Ka = id;
|
|
107
92
|
}
|
|
108
93
|
};
|
|
109
94
|
|
|
110
95
|
// src/decoder/point_cloud/PointCloud.ts
|
|
111
96
|
var NAMED_ATTRIBUTES_COUNT = 8;
|
|
112
97
|
var PointCloud = class {
|
|
113
|
-
|
|
98
|
+
wb = 0;
|
|
114
99
|
attributes_ = [];
|
|
115
100
|
// named_attribute_index_[type] = [att_id, ...], one list per named type.
|
|
116
|
-
|
|
101
|
+
$a = [[], [], [], [], [], [], [], []];
|
|
117
102
|
numNamedAttributes(type) {
|
|
118
103
|
if (type < 0 || type >= NAMED_ATTRIBUTES_COUNT) {
|
|
119
104
|
return 0;
|
|
120
105
|
}
|
|
121
|
-
return this
|
|
106
|
+
return this.$a[type].length;
|
|
122
107
|
}
|
|
123
108
|
getNamedAttributeId(type, i) {
|
|
124
109
|
if (i === void 0) i = 0;
|
|
125
110
|
if (this.numNamedAttributes(type) <= i) {
|
|
126
111
|
return -1;
|
|
127
112
|
}
|
|
128
|
-
return this
|
|
113
|
+
return this.$a[type][i];
|
|
129
114
|
}
|
|
130
115
|
getNamedAttribute(type, i) {
|
|
131
116
|
if (i === void 0) i = 0;
|
|
@@ -165,31 +150,26 @@ var PointCloud = class {
|
|
|
165
150
|
this.attributes_.push(null);
|
|
166
151
|
}
|
|
167
152
|
if (pa.attributeType < NAMED_ATTRIBUTES_COUNT) {
|
|
168
|
-
this
|
|
153
|
+
this.$a[pa.attributeType].push(attId);
|
|
169
154
|
}
|
|
170
155
|
pa.uniqueId = attId;
|
|
171
156
|
this.attributes_[attId] = pa;
|
|
172
157
|
}
|
|
173
158
|
numPoints() {
|
|
174
|
-
return this.
|
|
159
|
+
return this.wb;
|
|
175
160
|
}
|
|
176
161
|
setNumPoints(num) {
|
|
177
|
-
this.
|
|
162
|
+
this.wb = num;
|
|
178
163
|
}
|
|
179
164
|
};
|
|
180
165
|
|
|
181
166
|
// src/decoder/mesh/Mesh.ts
|
|
182
|
-
var MeshAttributeElementType = {
|
|
183
|
-
MESH_VERTEX_ATTRIBUTE: 0,
|
|
184
|
-
MESH_CORNER_ATTRIBUTE: 1,
|
|
185
|
-
MESH_FACE_ATTRIBUTE: 2
|
|
186
|
-
};
|
|
187
167
|
var Mesh = class extends PointCloud {
|
|
188
168
|
// Flat Int32Array, 3 point indices per face, for cache locality and to avoid
|
|
189
169
|
// a per-face allocation. faces_[3*f + c] is corner c of face f; corner index
|
|
190
170
|
// ci maps directly to faces_[ci].
|
|
191
171
|
faces_ = new Int32Array(0);
|
|
192
|
-
|
|
172
|
+
xb = 0;
|
|
193
173
|
// Sizes faces_ to hold numFaces faces. Called once per decode, before any
|
|
194
174
|
// face index is written (edgebreaker: _assignPointsToCorners; sequential:
|
|
195
175
|
// decodeConnectivity), so the buffer is allocated exactly here — the
|
|
@@ -201,10 +181,42 @@ var Mesh = class extends PointCloud {
|
|
|
201
181
|
grown.set(this.faces_);
|
|
202
182
|
this.faces_ = grown;
|
|
203
183
|
}
|
|
204
|
-
this.
|
|
184
|
+
this.xb = numFaces;
|
|
205
185
|
}
|
|
206
186
|
numFaces() {
|
|
207
|
-
return this.
|
|
187
|
+
return this.xb;
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
// src/decoder/core/DataBuffer.ts
|
|
192
|
+
var DataBuffer = class {
|
|
193
|
+
p = new Uint8Array(0);
|
|
194
|
+
// Resizes to `size` bytes (contents preserved); when `data` is given, grows
|
|
195
|
+
// as needed and copies its first `size` bytes in.
|
|
196
|
+
update(data, size) {
|
|
197
|
+
if (data === null) {
|
|
198
|
+
this.yb(size);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
if (size > this.p.length) {
|
|
202
|
+
this.yb(size);
|
|
203
|
+
}
|
|
204
|
+
this.p.set(data.length === size ? data : data.subarray(0, size));
|
|
205
|
+
}
|
|
206
|
+
// The caller passes a Uint8Array of exactly dataSize bytes in the common
|
|
207
|
+
// case; avoid allocating a wrapper view per value (dominates storage time /
|
|
208
|
+
// GC pressure).
|
|
209
|
+
write(bytePos, inArray, dataSize) {
|
|
210
|
+
this.p.set(inArray.length === dataSize ? inArray : inArray.subarray(0, dataSize), bytePos);
|
|
211
|
+
}
|
|
212
|
+
get data() {
|
|
213
|
+
return this.p;
|
|
214
|
+
}
|
|
215
|
+
yb(newSize) {
|
|
216
|
+
if (newSize === this.p.length) return;
|
|
217
|
+
const newData = new Uint8Array(newSize);
|
|
218
|
+
newData.set(this.p.subarray(0, Math.min(this.p.length, newSize)));
|
|
219
|
+
this.p = newData;
|
|
208
220
|
}
|
|
209
221
|
};
|
|
210
222
|
|
|
@@ -289,155 +301,140 @@ var releaseScratch = () => {
|
|
|
289
301
|
borrowedUint8.length = 0;
|
|
290
302
|
};
|
|
291
303
|
|
|
292
|
-
// src/decoder/core/DataBuffer.ts
|
|
293
|
-
var DataBuffer = class {
|
|
294
|
-
n = new Uint8Array(0);
|
|
295
|
-
// Resizes to `size` bytes (contents preserved); when `data` is given, grows
|
|
296
|
-
// as needed and copies its first `size` bytes in.
|
|
297
|
-
update(data, size) {
|
|
298
|
-
if (data === null) {
|
|
299
|
-
this.lb(size);
|
|
300
|
-
return;
|
|
301
|
-
}
|
|
302
|
-
if (size > this.n.length) {
|
|
303
|
-
this.lb(size);
|
|
304
|
-
}
|
|
305
|
-
this.n.set(data.length === size ? data : data.subarray(0, size));
|
|
306
|
-
}
|
|
307
|
-
// Replaces the contents with a decode-scoped scratch buffer of exactly
|
|
308
|
-
// `size` bytes; the previous contents are dropped and the new ones are
|
|
309
|
-
// arbitrary, so every byte must be written before it is read. Only for
|
|
310
|
-
// buffers that never outlive the decode (see ScratchArena) — the portable
|
|
311
|
-
// attributes the integer decoders build and discard per attribute are the
|
|
312
|
-
// one caller, and their per-primitive allocation showed up in profiles.
|
|
313
|
-
adoptScratch(size) {
|
|
314
|
-
this.n = scratchUint8(size);
|
|
315
|
-
}
|
|
316
|
-
// The caller passes a Uint8Array of exactly dataSize bytes in the common
|
|
317
|
-
// case; avoid allocating a wrapper view per value (dominates storage time /
|
|
318
|
-
// GC pressure).
|
|
319
|
-
write(bytePos, inArray, dataSize) {
|
|
320
|
-
this.n.set(inArray.length === dataSize ? inArray : inArray.subarray(0, dataSize), bytePos);
|
|
321
|
-
}
|
|
322
|
-
get data() {
|
|
323
|
-
return this.n;
|
|
324
|
-
}
|
|
325
|
-
lb(newSize) {
|
|
326
|
-
if (newSize === this.n.length) return;
|
|
327
|
-
const newData = new Uint8Array(newSize);
|
|
328
|
-
newData.set(this.n.subarray(0, Math.min(this.n.length, newSize)));
|
|
329
|
-
this.n = newData;
|
|
330
|
-
}
|
|
331
|
-
};
|
|
332
|
-
|
|
333
304
|
// src/decoder/attributes/PointAttribute.ts
|
|
334
305
|
function viewCtorFor(dt) {
|
|
335
306
|
switch (dt) {
|
|
336
|
-
case
|
|
307
|
+
case 1 /* INT8 */:
|
|
337
308
|
return Int8Array;
|
|
338
|
-
case
|
|
309
|
+
case 2 /* UINT8 */:
|
|
339
310
|
return Uint8Array;
|
|
340
|
-
case
|
|
311
|
+
case 3 /* INT16 */:
|
|
341
312
|
return Int16Array;
|
|
342
|
-
case
|
|
313
|
+
case 4 /* UINT16 */:
|
|
343
314
|
return Uint16Array;
|
|
344
|
-
case
|
|
315
|
+
case 5 /* INT32 */:
|
|
345
316
|
return Int32Array;
|
|
346
|
-
case
|
|
317
|
+
case 6 /* UINT32 */:
|
|
347
318
|
return Uint32Array;
|
|
348
|
-
case
|
|
319
|
+
case 9 /* FLOAT32 */:
|
|
349
320
|
return Float32Array;
|
|
350
|
-
case
|
|
321
|
+
case 10 /* FLOAT64 */:
|
|
351
322
|
return Float64Array;
|
|
352
323
|
default:
|
|
353
324
|
return null;
|
|
354
325
|
}
|
|
355
326
|
}
|
|
327
|
+
var LAZY_NONE = 0;
|
|
328
|
+
var LAZY_INTEGER = 1;
|
|
329
|
+
var LAZY_QUANTIZED = 2;
|
|
330
|
+
var LAZY_OCTAHEDRON = 3;
|
|
356
331
|
var PointAttribute = class extends GeometryAttribute {
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
Pb = null;
|
|
332
|
+
E = false;
|
|
333
|
+
ab = 0;
|
|
334
|
+
F = [];
|
|
335
|
+
$ = null;
|
|
362
336
|
// Lazily-created cached typed-array view over the attribute buffer, keyed
|
|
363
337
|
// on (constructor, underlying ArrayBuffer). An attribute only ever reads
|
|
364
338
|
// through the one view type its data type dictates.
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
339
|
+
zb = null;
|
|
340
|
+
Ab = null;
|
|
341
|
+
Bb = null;
|
|
342
|
+
// Deferred inverse transform. The integer attribute decoders leave their
|
|
343
|
+
// decoded values here as int32 -- quantized floats, octahedral normals or
|
|
344
|
+
// plain integers -- with the transform's parameters, and extractTo applies
|
|
345
|
+
// the transform while gathering the values into point order: one pass over
|
|
346
|
+
// the points instead of an inverse-transform pass into a per-value buffer
|
|
347
|
+
// followed by a gather from it, and no such buffer at all.
|
|
348
|
+
La = LAZY_NONE;
|
|
349
|
+
aa = null;
|
|
350
|
+
Cb = [];
|
|
351
|
+
Ma = 0;
|
|
368
352
|
constructor(geometryAttribute) {
|
|
369
353
|
super();
|
|
370
354
|
if (geometryAttribute instanceof GeometryAttribute) {
|
|
371
|
-
this.
|
|
372
|
-
this.
|
|
373
|
-
this.Y = geometryAttribute.Y;
|
|
374
|
-
this.Qa = geometryAttribute.Qa;
|
|
375
|
-
this.O = geometryAttribute.O;
|
|
355
|
+
this.d = geometryAttribute.d;
|
|
356
|
+
this.z = geometryAttribute.z;
|
|
376
357
|
this.P = geometryAttribute.P;
|
|
377
|
-
this.
|
|
378
|
-
this.
|
|
358
|
+
this._a = geometryAttribute._a;
|
|
359
|
+
this.Q = geometryAttribute.Q;
|
|
360
|
+
this.R = geometryAttribute.R;
|
|
361
|
+
this.Ja = geometryAttribute.Ja;
|
|
362
|
+
this.Ka = geometryAttribute.Ka;
|
|
379
363
|
}
|
|
380
364
|
}
|
|
381
365
|
// Intentionally shadows GeometryAttribute.init with a different signature (matches draco.js / C++ source).
|
|
382
366
|
// @ts-expect-error -- signature intentionally differs from the base class, as in the source.
|
|
383
367
|
init(attributeType, numComponents, dataType, normalized, numAttributeValues) {
|
|
384
|
-
this
|
|
368
|
+
this.$ = new DataBuffer();
|
|
385
369
|
const byteStride = dataTypeLength(dataType) * numComponents;
|
|
386
|
-
super.init(attributeType, this
|
|
370
|
+
super.init(attributeType, this.$, numComponents, dataType, normalized, byteStride, 0);
|
|
387
371
|
this.reset(numAttributeValues);
|
|
388
372
|
this.setIdentityMapping();
|
|
389
373
|
}
|
|
390
374
|
reset(numAttributeValues) {
|
|
391
|
-
if (this
|
|
392
|
-
this
|
|
375
|
+
if (this.$ === null) {
|
|
376
|
+
this.$ = new DataBuffer();
|
|
393
377
|
}
|
|
394
378
|
const entrySize = dataTypeLength(this.dataType) * this.numComponents;
|
|
395
|
-
this
|
|
396
|
-
this.resetBuffer(this
|
|
397
|
-
this.
|
|
379
|
+
this.$.update(null, numAttributeValues * entrySize);
|
|
380
|
+
this.resetBuffer(this.$, entrySize, 0);
|
|
381
|
+
this.ab = numAttributeValues;
|
|
398
382
|
return true;
|
|
399
383
|
}
|
|
400
|
-
//
|
|
401
|
-
//
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
this.
|
|
409
|
-
this.
|
|
410
|
-
|
|
411
|
-
|
|
384
|
+
// Sizes the attribute without allocating storage, for the deferred
|
|
385
|
+
// transforms below (the values live in the decoder's portable attribute).
|
|
386
|
+
resetLazy(numAttributeValues) {
|
|
387
|
+
this.ab = numAttributeValues;
|
|
388
|
+
}
|
|
389
|
+
// numValues decoded integers of the attribute's own integer type, stored as
|
|
390
|
+
// int32; extractTo converts them to the requested output type.
|
|
391
|
+
setLazyInteger(values) {
|
|
392
|
+
this.La = LAZY_INTEGER;
|
|
393
|
+
this.aa = values;
|
|
394
|
+
}
|
|
395
|
+
// Quantized float values: value * delta + min per component (float32
|
|
396
|
+
// arithmetic, see _extractQuantized), as the C++ Dequantizer computes them.
|
|
397
|
+
setLazyQuantized(values, minValues, delta) {
|
|
398
|
+
this.La = LAZY_QUANTIZED;
|
|
399
|
+
this.aa = values;
|
|
400
|
+
this.Cb = minValues;
|
|
401
|
+
this.Ma = delta;
|
|
402
|
+
}
|
|
403
|
+
// Octahedral normals: two quantized coordinates per value, dequantized by
|
|
404
|
+
// `scale` and turned into unit vectors (see _extractOctahedron).
|
|
405
|
+
setLazyOctahedron(values, scale) {
|
|
406
|
+
this.La = LAZY_OCTAHEDRON;
|
|
407
|
+
this.aa = values;
|
|
408
|
+
this.Ma = scale;
|
|
412
409
|
}
|
|
413
410
|
get size() {
|
|
414
|
-
return this.
|
|
411
|
+
return this.ab;
|
|
415
412
|
}
|
|
416
413
|
mappedIndex(pointIndex) {
|
|
417
|
-
if (this.
|
|
414
|
+
if (this.E) {
|
|
418
415
|
return pointIndex;
|
|
419
416
|
}
|
|
420
|
-
return this.
|
|
417
|
+
return this.F[pointIndex];
|
|
421
418
|
}
|
|
422
419
|
get isMappingIdentity() {
|
|
423
|
-
return this.
|
|
420
|
+
return this.E;
|
|
424
421
|
}
|
|
425
422
|
get indicesMapSize() {
|
|
426
|
-
if (this.
|
|
423
|
+
if (this.E) {
|
|
427
424
|
return 0;
|
|
428
425
|
}
|
|
429
|
-
return this.
|
|
426
|
+
return this.F.length;
|
|
430
427
|
}
|
|
431
428
|
// Direct access to the explicit point->value index map (a Uint32Array after
|
|
432
429
|
// any of the setExplicitMapping* calls). Lets hot mapping loops write
|
|
433
430
|
// entries without a per-entry dispatch.
|
|
434
431
|
get indicesMap() {
|
|
435
|
-
return this.
|
|
432
|
+
return this.F;
|
|
436
433
|
}
|
|
437
434
|
// Implicit mapping: point index equals attribute entry index.
|
|
438
435
|
setIdentityMapping() {
|
|
439
|
-
this.
|
|
440
|
-
this.
|
|
436
|
+
this.E = true;
|
|
437
|
+
this.F = [];
|
|
441
438
|
}
|
|
442
439
|
// Explicit mapping without an invalid-index fill. Only for callers that
|
|
443
440
|
// provably write every entry right away (the fill was ~4% of decode time on
|
|
@@ -447,80 +444,76 @@ var PointAttribute = class extends GeometryAttribute {
|
|
|
447
444
|
// and avoids boxed-number storage; it is read once per point per attribute.
|
|
448
445
|
// Must be UNSIGNED so the 0xFFFFFFFF invalid sentinel round-trips intact.
|
|
449
446
|
setExplicitMappingUnfilled(numPoints) {
|
|
450
|
-
this.
|
|
451
|
-
this.
|
|
447
|
+
this.E = false;
|
|
448
|
+
this.F = new Uint32Array(numPoints);
|
|
452
449
|
}
|
|
453
450
|
// Adopts an already-computed map, shared with other attributes of the same
|
|
454
451
|
// mesh. The map must be treated as read-only from here on (reads go through
|
|
455
452
|
// mappedIndex/extractTo).
|
|
456
453
|
setExplicitMappingShared(map) {
|
|
457
|
-
this.
|
|
458
|
-
this.
|
|
454
|
+
this.E = false;
|
|
455
|
+
this.F = map;
|
|
459
456
|
}
|
|
460
457
|
// Like setExplicitMappingUnfilled, but from decode-scoped scratch. Only for
|
|
461
458
|
// attributes that never escape the decode (see ScratchArena) -- the portable
|
|
462
459
|
// attributes the sequential decoders build and discard.
|
|
463
460
|
setExplicitMappingScratch(numPoints) {
|
|
464
|
-
this.
|
|
465
|
-
this.
|
|
466
|
-
}
|
|
467
|
-
setAttributeTransformData(transformData) {
|
|
468
|
-
this.Pb = transformData;
|
|
461
|
+
this.E = false;
|
|
462
|
+
this.F = scratchUint32(numPoints);
|
|
469
463
|
}
|
|
470
464
|
// Cached typed-array view of the given type over the attribute buffer.
|
|
471
|
-
|
|
472
|
-
if (this.
|
|
473
|
-
this.
|
|
474
|
-
this.
|
|
475
|
-
this.
|
|
476
|
-
}
|
|
477
|
-
return this.
|
|
478
|
-
}
|
|
479
|
-
// Mirrors C++ PointAttribute::ConvertValue<T>()
|
|
480
|
-
// byteOffset 0 and entries are
|
|
481
|
-
// through a typed-array view instead
|
|
465
|
+
Db(Ctor, bufData) {
|
|
466
|
+
if (this.zb !== Ctor || this.Ab !== bufData.buffer) {
|
|
467
|
+
this.zb = Ctor;
|
|
468
|
+
this.Ab = bufData.buffer;
|
|
469
|
+
this.Bb = new Ctor(bufData.buffer);
|
|
470
|
+
}
|
|
471
|
+
return this.Bb;
|
|
472
|
+
}
|
|
473
|
+
// Mirrors C++ PointAttribute::ConvertValue<T>() for buffer-backed
|
|
474
|
+
// attributes. Attribute buffers start at byteOffset 0 and entries are
|
|
475
|
+
// naturally aligned, so every type reads through a typed-array view instead
|
|
476
|
+
// of a per-component DataView dispatch.
|
|
482
477
|
convertValue(attIndex, outVal) {
|
|
483
|
-
const
|
|
484
|
-
const
|
|
485
|
-
const
|
|
486
|
-
const nc = this.E;
|
|
487
|
-
if (dt === DataType.INT32) {
|
|
488
|
-
const view2 = this.Sa(Int32Array, bufData);
|
|
489
|
-
const baseIndex2 = bufData.byteOffset + bytePos >> 2;
|
|
490
|
-
for (let i = 0; i < nc; ++i) {
|
|
491
|
-
outVal[i] = view2[baseIndex2 + i];
|
|
492
|
-
}
|
|
493
|
-
return;
|
|
494
|
-
}
|
|
495
|
-
const Ctor = viewCtorFor(dt);
|
|
478
|
+
const bufData = this.d.data;
|
|
479
|
+
const nc = this.z;
|
|
480
|
+
const Ctor = viewCtorFor(this.P);
|
|
496
481
|
if (Ctor === null) {
|
|
497
|
-
for (let i = 0; i < nc; ++i)
|
|
498
|
-
outVal[i] = 0;
|
|
499
|
-
}
|
|
482
|
+
for (let i = 0; i < nc; ++i) outVal[i] = 0;
|
|
500
483
|
return;
|
|
501
484
|
}
|
|
502
|
-
const view = this.
|
|
503
|
-
const baseIndex = (bufData.byteOffset +
|
|
504
|
-
for (let i = 0; i < nc; ++i)
|
|
505
|
-
outVal[i] = view[baseIndex + i];
|
|
506
|
-
}
|
|
485
|
+
const view = this.Db(Ctor, bufData);
|
|
486
|
+
const baseIndex = (bufData.byteOffset + this.R + this.Q * attIndex) / Ctor.BYTES_PER_ELEMENT;
|
|
487
|
+
for (let i = 0; i < nc; ++i) outVal[i] = view[baseIndex + i];
|
|
507
488
|
}
|
|
508
|
-
// Flat-array extraction of all values into one output typed array
|
|
509
|
-
//
|
|
489
|
+
// Flat-array extraction of all values into one output typed array, in point
|
|
490
|
+
// order (applying the deferred transform, if any, on the way).
|
|
510
491
|
extractTo(OutputTypedArray, numPoints) {
|
|
511
|
-
const numComponents = this.
|
|
492
|
+
const numComponents = this.z;
|
|
512
493
|
const array = new OutputTypedArray(numPoints * numComponents);
|
|
513
|
-
|
|
514
|
-
if (this.e === null || numPoints === 0 || Ctor === null) {
|
|
494
|
+
if (numPoints === 0) {
|
|
515
495
|
return array;
|
|
516
496
|
}
|
|
517
|
-
const
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
497
|
+
const kind = this.La;
|
|
498
|
+
if (kind !== LAZY_NONE) {
|
|
499
|
+
if (this.aa !== null) {
|
|
500
|
+
if (kind === LAZY_QUANTIZED) this.gc(array, numPoints);
|
|
501
|
+
else if (kind === LAZY_OCTAHEDRON) this.hc(array, numPoints);
|
|
502
|
+
else this.ic(array, numPoints);
|
|
503
|
+
}
|
|
504
|
+
return array;
|
|
505
|
+
}
|
|
506
|
+
const Ctor = viewCtorFor(this.P);
|
|
507
|
+
if (this.d === null || Ctor === null) {
|
|
508
|
+
return array;
|
|
509
|
+
}
|
|
510
|
+
const bufData = this.d.data;
|
|
511
|
+
const isIdentity = this.E;
|
|
512
|
+
const indicesMap = this.F;
|
|
513
|
+
const srcView = this.Db(Ctor, bufData);
|
|
521
514
|
const shift = 31 - Math.clz32(Ctor.BYTES_PER_ELEMENT);
|
|
522
|
-
const srcStart = bufData.byteOffset + this.
|
|
523
|
-
const strideElements = this.
|
|
515
|
+
const srcStart = bufData.byteOffset + this.R >> shift;
|
|
516
|
+
const strideElements = this.Q >> shift;
|
|
524
517
|
if (isIdentity && strideElements === numComponents) {
|
|
525
518
|
const srcEnd = srcStart + numPoints * numComponents;
|
|
526
519
|
if (srcView.constructor === OutputTypedArray) {
|
|
@@ -528,59 +521,130 @@ var PointAttribute = class extends GeometryAttribute {
|
|
|
528
521
|
return array;
|
|
529
522
|
}
|
|
530
523
|
}
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
array[dst + j] = srcView[srcOffset + j];
|
|
537
|
-
}
|
|
538
|
-
dst += numComponents;
|
|
539
|
-
}
|
|
540
|
-
} else if (numComponents === 3) {
|
|
541
|
-
let dst = 0;
|
|
542
|
-
for (let i = 0; i < numPoints; i++) {
|
|
543
|
-
const srcOffset = srcStart + indicesMap[i] * strideElements;
|
|
544
|
-
array[dst] = srcView[srcOffset];
|
|
545
|
-
array[dst + 1] = srcView[srcOffset + 1];
|
|
546
|
-
array[dst + 2] = srcView[srcOffset + 2];
|
|
547
|
-
dst += 3;
|
|
548
|
-
}
|
|
549
|
-
} else if (numComponents === 2) {
|
|
550
|
-
let dst = 0;
|
|
551
|
-
for (let i = 0; i < numPoints; i++) {
|
|
552
|
-
const srcOffset = srcStart + indicesMap[i] * strideElements;
|
|
553
|
-
array[dst] = srcView[srcOffset];
|
|
554
|
-
array[dst + 1] = srcView[srcOffset + 1];
|
|
555
|
-
dst += 2;
|
|
556
|
-
}
|
|
557
|
-
} else if (numComponents === 4) {
|
|
558
|
-
let dst = 0;
|
|
559
|
-
for (let i = 0; i < numPoints; i++) {
|
|
560
|
-
const srcOffset = srcStart + indicesMap[i] * strideElements;
|
|
561
|
-
array[dst] = srcView[srcOffset];
|
|
562
|
-
array[dst + 1] = srcView[srcOffset + 1];
|
|
563
|
-
array[dst + 2] = srcView[srcOffset + 2];
|
|
564
|
-
array[dst + 3] = srcView[srcOffset + 3];
|
|
565
|
-
dst += 4;
|
|
566
|
-
}
|
|
567
|
-
} else if (numComponents === 1) {
|
|
568
|
-
let dst = 0;
|
|
569
|
-
for (let i = 0; i < numPoints; i++) {
|
|
570
|
-
array[dst++] = srcView[srcStart + indicesMap[i] * strideElements];
|
|
571
|
-
}
|
|
572
|
-
} else {
|
|
573
|
-
let dst = 0;
|
|
574
|
-
for (let i = 0; i < numPoints; i++) {
|
|
575
|
-
const srcOffset = srcStart + indicesMap[i] * strideElements;
|
|
576
|
-
for (let j = 0; j < numComponents; j++) {
|
|
577
|
-
array[dst + j] = srcView[srcOffset + j];
|
|
578
|
-
}
|
|
579
|
-
dst += numComponents;
|
|
524
|
+
let dst = 0;
|
|
525
|
+
for (let i = 0; i < numPoints; i++) {
|
|
526
|
+
const srcOffset = srcStart + (isIdentity ? i : indicesMap[i]) * strideElements;
|
|
527
|
+
for (let j = 0; j < numComponents; j++) {
|
|
528
|
+
array[dst + j] = srcView[srcOffset + j];
|
|
580
529
|
}
|
|
530
|
+
dst += numComponents;
|
|
581
531
|
}
|
|
582
532
|
return array;
|
|
583
533
|
}
|
|
534
|
+
// The deferred transforms, each fused with the point-order gather. One
|
|
535
|
+
// function per transform so the engine tiers each up on its own complete
|
|
536
|
+
// type feedback (a single body for all three deoptimized once per newly
|
|
537
|
+
// seen kind, which made the first decodes of a session measurably slower).
|
|
538
|
+
// Every float step is rounded to float32 exactly where the C++ decoder's
|
|
539
|
+
// float arithmetic rounds (Dequantizer, OctahedronToolBox), so the values
|
|
540
|
+
// are bit-identical to the reference decoder whatever the output array type.
|
|
541
|
+
// Point -> value index; the identity mapping (sequential meshes) gets a
|
|
542
|
+
// plain iota so the loops carry no per-point branch.
|
|
543
|
+
bb(numPoints) {
|
|
544
|
+
if (!this.E) return this.F;
|
|
545
|
+
const map = new Uint32Array(numPoints);
|
|
546
|
+
for (let p = 0; p < numPoints; ++p) map[p] = p;
|
|
547
|
+
return map;
|
|
548
|
+
}
|
|
549
|
+
// The C++ starts from static_cast<float>(value). An integer below 2^24 is
|
|
550
|
+
// exact as a float32 and its product with a float32 is exact as a double,
|
|
551
|
+
// so for such values `fround(value * scale)` is that float32 product
|
|
552
|
+
// without the (measurably costly) int-to-float32-to-double round trip per
|
|
553
|
+
// component. Larger values (quantization above 24 bits, never seen in
|
|
554
|
+
// practice) are rounded in place once here, after which the same holds.
|
|
555
|
+
Eb() {
|
|
556
|
+
const values = this.aa;
|
|
557
|
+
for (let i = 0; i < values.length; ++i) {
|
|
558
|
+
if (values[i] >= 16777216 || values[i] <= -16777216) {
|
|
559
|
+
for (let j = 0; j < values.length; ++j) values[j] = Math.fround(values[j]);
|
|
560
|
+
break;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
return values;
|
|
564
|
+
}
|
|
565
|
+
// C++ Dequantizer: float(value) * delta + min, all in float32.
|
|
566
|
+
gc(out, numPoints) {
|
|
567
|
+
const values = this.Eb();
|
|
568
|
+
const map = this.bb(numPoints);
|
|
569
|
+
const numComponents = this.z;
|
|
570
|
+
const fround = Math.fround;
|
|
571
|
+
const delta = this.Ma;
|
|
572
|
+
const min = this.Cb;
|
|
573
|
+
if (numComponents === 3) {
|
|
574
|
+
const m0 = min[0];
|
|
575
|
+
const m1 = min[1];
|
|
576
|
+
const m2 = min[2];
|
|
577
|
+
for (let p = 0, d = 0; p < numPoints; ++p, d += 3) {
|
|
578
|
+
const s = map[p] * 3;
|
|
579
|
+
out[d] = fround(fround(values[s] * delta) + m0);
|
|
580
|
+
out[d + 1] = fround(fround(values[s + 1] * delta) + m1);
|
|
581
|
+
out[d + 2] = fround(fround(values[s + 2] * delta) + m2);
|
|
582
|
+
}
|
|
583
|
+
return;
|
|
584
|
+
}
|
|
585
|
+
if (numComponents === 2) {
|
|
586
|
+
const m0 = min[0];
|
|
587
|
+
const m1 = min[1];
|
|
588
|
+
for (let p = 0, d = 0; p < numPoints; ++p, d += 2) {
|
|
589
|
+
const s = map[p] * 2;
|
|
590
|
+
out[d] = fround(fround(values[s] * delta) + m0);
|
|
591
|
+
out[d + 1] = fround(fround(values[s + 1] * delta) + m1);
|
|
592
|
+
}
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
595
|
+
for (let p = 0, d = 0; p < numPoints; ++p) {
|
|
596
|
+
const s = map[p] * numComponents;
|
|
597
|
+
for (let c = 0; c < numComponents; ++c) {
|
|
598
|
+
out[d++] = fround(fround(values[s + c] * delta) + min[c]);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
// OctahedronToolBox.QuantizedOctahedralCoordsToUnitVector, two quantized
|
|
603
|
+
// coordinates per value to one unit vector per point.
|
|
604
|
+
hc(out, numPoints) {
|
|
605
|
+
const values = this.Eb();
|
|
606
|
+
const map = this.bb(numPoints);
|
|
607
|
+
const fround = Math.fround;
|
|
608
|
+
const scale = this.Ma;
|
|
609
|
+
for (let p = 0, d = 0; p < numPoints; ++p, d += 3) {
|
|
610
|
+
const s = map[p] * 2;
|
|
611
|
+
let y = fround(fround(values[s] * scale) - 1);
|
|
612
|
+
let z = fround(fround(values[s + 1] * scale) - 1);
|
|
613
|
+
const x = fround(fround(1 - Math.abs(y)) - Math.abs(z));
|
|
614
|
+
let xOffset = -x;
|
|
615
|
+
if (xOffset < 0) xOffset = 0;
|
|
616
|
+
y = fround(y + (y < 0 ? xOffset : -xOffset));
|
|
617
|
+
z = fround(z + (z < 0 ? xOffset : -xOffset));
|
|
618
|
+
const normSquared = fround(fround(fround(x * x) + fround(y * y)) + fround(z * z));
|
|
619
|
+
if (normSquared < 1e-6) {
|
|
620
|
+
out[d] = 0;
|
|
621
|
+
out[d + 1] = 0;
|
|
622
|
+
out[d + 2] = 0;
|
|
623
|
+
} else {
|
|
624
|
+
const k = fround(1 / fround(Math.sqrt(normSquared)));
|
|
625
|
+
out[d] = fround(x * k);
|
|
626
|
+
out[d + 1] = fround(y * k);
|
|
627
|
+
out[d + 2] = fround(z * k);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
// The int32 values wrap to the attribute's own integer type (as storing
|
|
632
|
+
// them into it would) before the output store converts them.
|
|
633
|
+
ic(out, numPoints) {
|
|
634
|
+
const values = this.aa;
|
|
635
|
+
const map = this.bb(numPoints);
|
|
636
|
+
const numComponents = this.z;
|
|
637
|
+
const dt = this.P;
|
|
638
|
+
const shift = 32 - 8 * dataTypeLength(dt);
|
|
639
|
+
const signed = dt === 1 /* INT8 */ || dt === 3 /* INT16 */ || dt === 5 /* INT32 */;
|
|
640
|
+
for (let p = 0, d = 0; p < numPoints; ++p) {
|
|
641
|
+
const s = map[p] * numComponents;
|
|
642
|
+
for (let c = 0; c < numComponents; ++c) {
|
|
643
|
+
const v = values[s + c] << shift;
|
|
644
|
+
out[d++] = signed ? v >> shift : v >>> shift;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
}
|
|
584
648
|
};
|
|
585
649
|
|
|
586
650
|
// src/decoder/core/VarintDecoding.ts
|
|
@@ -602,21 +666,21 @@ function decodeVarint(buffer) {
|
|
|
602
666
|
|
|
603
667
|
// src/decoder/core/DecoderBuffer.ts
|
|
604
668
|
var BitDecoder = class {
|
|
605
|
-
|
|
669
|
+
Na = null;
|
|
606
670
|
q = 0;
|
|
607
|
-
|
|
671
|
+
ra = 0;
|
|
608
672
|
reset(uint8Array, byteLength) {
|
|
609
|
-
this.
|
|
610
|
-
this.
|
|
673
|
+
this.Na = uint8Array;
|
|
674
|
+
this.ra = byteLength;
|
|
611
675
|
this.q = 0;
|
|
612
676
|
}
|
|
613
677
|
getBits(nbits) {
|
|
614
678
|
if (nbits > 32) return void 0;
|
|
615
|
-
const buf = this.
|
|
679
|
+
const buf = this.Na;
|
|
616
680
|
let off = this.q;
|
|
617
681
|
const byteOffset = off >> 3;
|
|
618
682
|
const bitShift = off & 7;
|
|
619
|
-
if (byteOffset + 4 < this.
|
|
683
|
+
if (byteOffset + 4 < this.ra) {
|
|
620
684
|
const val = (buf[byteOffset] | buf[byteOffset + 1] << 8 | buf[byteOffset + 2] << 16 | buf[byteOffset + 3] << 24) >>> 0;
|
|
621
685
|
let result;
|
|
622
686
|
if (nbits > 32 - bitShift) {
|
|
@@ -635,7 +699,7 @@ var BitDecoder = class {
|
|
|
635
699
|
let currOff = off;
|
|
636
700
|
while (bitsRead < nbits) {
|
|
637
701
|
const bOff = currOff >> 3;
|
|
638
|
-
if (bOff >= this.
|
|
702
|
+
if (bOff >= this.ra) return void 0;
|
|
639
703
|
const bShift = currOff & 7;
|
|
640
704
|
const bitsAvail = 8 - bShift;
|
|
641
705
|
const bitsNeeded = nbits - bitsRead;
|
|
@@ -650,61 +714,49 @@ var BitDecoder = class {
|
|
|
650
714
|
}
|
|
651
715
|
};
|
|
652
716
|
var DecoderBuffer = class {
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
717
|
+
p = null;
|
|
718
|
+
Oa = null;
|
|
719
|
+
M = 0;
|
|
720
|
+
e = 0;
|
|
721
|
+
sa = new BitDecoder();
|
|
722
|
+
Pa = false;
|
|
659
723
|
init(data, dataSize = data.length) {
|
|
660
|
-
this.
|
|
661
|
-
this.
|
|
662
|
-
this.
|
|
663
|
-
this.
|
|
724
|
+
this.p = data;
|
|
725
|
+
this.Oa = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
726
|
+
this.M = dataSize;
|
|
727
|
+
this.e = 0;
|
|
664
728
|
}
|
|
665
729
|
// Typed little-endian reads.
|
|
666
730
|
decodeUint8() {
|
|
667
|
-
if (this.
|
|
668
|
-
const val = this.
|
|
669
|
-
this.
|
|
670
|
-
return val;
|
|
671
|
-
}
|
|
672
|
-
decodeInt8() {
|
|
673
|
-
if (this.d + 1 > this.z) return void 0;
|
|
674
|
-
const val = this.la.getInt8(this.d);
|
|
675
|
-
this.d += 1;
|
|
731
|
+
if (this.e + 1 > this.M) return void 0;
|
|
732
|
+
const val = this.p[this.e];
|
|
733
|
+
this.e += 1;
|
|
676
734
|
return val;
|
|
677
735
|
}
|
|
678
736
|
decodeUint16() {
|
|
679
|
-
if (this.
|
|
680
|
-
const val = this.
|
|
681
|
-
this.
|
|
737
|
+
if (this.e + 2 > this.M) return void 0;
|
|
738
|
+
const val = this.Oa.getUint16(this.e, true);
|
|
739
|
+
this.e += 2;
|
|
682
740
|
return val;
|
|
683
741
|
}
|
|
684
742
|
decodeInt32() {
|
|
685
|
-
if (this.
|
|
686
|
-
const val = this.
|
|
687
|
-
this.
|
|
743
|
+
if (this.e + 4 > this.M) return void 0;
|
|
744
|
+
const val = this.Oa.getInt32(this.e, true);
|
|
745
|
+
this.e += 4;
|
|
688
746
|
return val;
|
|
689
747
|
}
|
|
690
748
|
decodeFloat32() {
|
|
691
|
-
if (this.
|
|
692
|
-
const val = this.
|
|
693
|
-
this.
|
|
749
|
+
if (this.e + 4 > this.M) return void 0;
|
|
750
|
+
const val = this.Oa.getFloat32(this.e, true);
|
|
751
|
+
this.e += 4;
|
|
694
752
|
return val;
|
|
695
753
|
}
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
const result = this.n.slice(this.d, this.d + size);
|
|
699
|
-
this.d += size;
|
|
700
|
-
return result;
|
|
701
|
-
}
|
|
702
|
-
// Zero-copy variant of decodeBytes: a view into the stream, only valid until
|
|
703
|
-
// the caller's next chance to mutate the buffer — copy out before keeping it.
|
|
754
|
+
// A view into the stream (no copy), only valid until the caller's next
|
|
755
|
+
// chance to mutate the buffer — copy out before keeping it.
|
|
704
756
|
decodeBytesView(size) {
|
|
705
|
-
if (this.
|
|
706
|
-
const result = this.
|
|
707
|
-
this.
|
|
757
|
+
if (this.e + size > this.M) return void 0;
|
|
758
|
+
const result = this.p.subarray(this.e, this.e + size);
|
|
759
|
+
this.e += size;
|
|
708
760
|
return result;
|
|
709
761
|
}
|
|
710
762
|
// Only the 2.2+ layout (varint size prefix): older bitstreams are rejected
|
|
@@ -716,80 +768,39 @@ var DecoderBuffer = class {
|
|
|
716
768
|
if (size === void 0) return void 0;
|
|
717
769
|
outSize = size;
|
|
718
770
|
}
|
|
719
|
-
this.
|
|
720
|
-
this.
|
|
771
|
+
this.Pa = true;
|
|
772
|
+
this.sa.reset(this.p.subarray(this.e), this.M - this.e);
|
|
721
773
|
return outSize;
|
|
722
774
|
}
|
|
723
775
|
endBitDecoding() {
|
|
724
|
-
this.
|
|
725
|
-
this.
|
|
776
|
+
this.Pa = false;
|
|
777
|
+
this.e += Math.ceil(this.sa.q / 8);
|
|
726
778
|
}
|
|
727
779
|
decodeLeastSignificantBits32(nbits) {
|
|
728
|
-
if (!this.
|
|
729
|
-
return this.
|
|
780
|
+
if (!this.Pa) return void 0;
|
|
781
|
+
return this.sa.getBits(nbits);
|
|
730
782
|
}
|
|
731
783
|
advance(bytes) {
|
|
732
|
-
this.
|
|
784
|
+
this.e += bytes;
|
|
733
785
|
}
|
|
734
786
|
get data() {
|
|
735
|
-
return this.
|
|
787
|
+
return this.p;
|
|
736
788
|
}
|
|
737
789
|
get dataHead() {
|
|
738
|
-
return this.
|
|
790
|
+
return this.p.subarray(this.e);
|
|
739
791
|
}
|
|
740
792
|
get remainingSize() {
|
|
741
|
-
return this.
|
|
793
|
+
return this.M - this.e;
|
|
742
794
|
}
|
|
743
795
|
get decodedSize() {
|
|
744
|
-
return this.
|
|
796
|
+
return this.e;
|
|
745
797
|
}
|
|
746
798
|
get bitDecoderActive() {
|
|
747
|
-
return this.
|
|
799
|
+
return this.Pa;
|
|
748
800
|
}
|
|
749
801
|
};
|
|
750
802
|
|
|
751
803
|
// src/decoder/compression/config/CompressionShared.ts
|
|
752
|
-
var EncodedGeometryType = {
|
|
753
|
-
POINT_CLOUD: 0,
|
|
754
|
-
TRIANGULAR_MESH: 1
|
|
755
|
-
};
|
|
756
|
-
var MeshEncoderMethod = {
|
|
757
|
-
MESH_SEQUENTIAL_ENCODING: 0,
|
|
758
|
-
MESH_EDGEBREAKER_ENCODING: 1
|
|
759
|
-
};
|
|
760
|
-
var SequentialAttributeEncoderType = {
|
|
761
|
-
SEQUENTIAL_ATTRIBUTE_ENCODER_GENERIC: 0,
|
|
762
|
-
SEQUENTIAL_ATTRIBUTE_ENCODER_INTEGER: 1,
|
|
763
|
-
SEQUENTIAL_ATTRIBUTE_ENCODER_QUANTIZATION: 2,
|
|
764
|
-
SEQUENTIAL_ATTRIBUTE_ENCODER_NORMALS: 3
|
|
765
|
-
};
|
|
766
|
-
var PredictionSchemeMethod = {
|
|
767
|
-
PREDICTION_NONE: -2,
|
|
768
|
-
MESH_PREDICTION_PARALLELOGRAM: 1,
|
|
769
|
-
MESH_PREDICTION_MULTI_PARALLELOGRAM: 2,
|
|
770
|
-
MESH_PREDICTION_CONSTRAINED_MULTI_PARALLELOGRAM: 4,
|
|
771
|
-
MESH_PREDICTION_TEX_COORDS_PORTABLE: 5,
|
|
772
|
-
MESH_PREDICTION_GEOMETRIC_NORMAL: 6,
|
|
773
|
-
NUM_PREDICTION_SCHEMES: 7
|
|
774
|
-
};
|
|
775
|
-
var PredictionSchemeTransformType = {
|
|
776
|
-
PREDICTION_TRANSFORM_NONE: -1,
|
|
777
|
-
PREDICTION_TRANSFORM_WRAP: 1,
|
|
778
|
-
PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON: 2,
|
|
779
|
-
PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON_CANONICALIZED: 3,
|
|
780
|
-
NUM_PREDICTION_SCHEME_TRANSFORM_TYPES: 4
|
|
781
|
-
};
|
|
782
|
-
var MeshTraversalMethod = {
|
|
783
|
-
MESH_TRAVERSAL_DEPTH_FIRST: 0,
|
|
784
|
-
MESH_TRAVERSAL_PREDICTION_DEGREE: 1,
|
|
785
|
-
NUM_TRAVERSAL_METHODS: 2
|
|
786
|
-
};
|
|
787
|
-
var MeshEdgebreakerConnectivityEncodingMethod = {
|
|
788
|
-
MESH_EDGEBREAKER_STANDARD_ENCODING: 0,
|
|
789
|
-
MESH_EDGEBREAKER_PREDICTIVE_ENCODING: 1,
|
|
790
|
-
// Deprecated.
|
|
791
|
-
MESH_EDGEBREAKER_VALENCE_ENCODING: 2
|
|
792
|
-
};
|
|
793
804
|
var DracoHeader = class {
|
|
794
805
|
versionMajor = 0;
|
|
795
806
|
versionMinor = 0;
|
|
@@ -797,76 +808,72 @@ var DracoHeader = class {
|
|
|
797
808
|
encoderMethod = 0;
|
|
798
809
|
flags = 0;
|
|
799
810
|
};
|
|
800
|
-
var SymbolCodingMethod = {
|
|
801
|
-
SYMBOL_CODING_TAGGED: 0,
|
|
802
|
-
SYMBOL_CODING_RAW: 1
|
|
803
|
-
};
|
|
804
811
|
var METADATA_FLAG_MASK = 32768;
|
|
805
812
|
|
|
806
813
|
// src/decoder/metadata/MetadataDecoder.ts
|
|
807
814
|
var kMaxSubmetadataLevel = 1e3;
|
|
808
815
|
var MetadataDecoder = class {
|
|
809
816
|
constructor(buffer_) {
|
|
810
|
-
this.
|
|
817
|
+
this.G = buffer_;
|
|
811
818
|
}
|
|
812
819
|
buffer_;
|
|
813
820
|
// Skips per-attribute metadata followed by the geometry-level metadata.
|
|
814
821
|
skipGeometryMetadata() {
|
|
815
|
-
const numAttMetadata = decodeVarint(this.
|
|
822
|
+
const numAttMetadata = decodeVarint(this.G);
|
|
816
823
|
if (numAttMetadata === void 0) {
|
|
817
824
|
return false;
|
|
818
825
|
}
|
|
819
826
|
for (let i = 0; i < numAttMetadata; ++i) {
|
|
820
|
-
if (decodeVarint(this.
|
|
827
|
+
if (decodeVarint(this.G) === void 0) {
|
|
821
828
|
return false;
|
|
822
829
|
}
|
|
823
|
-
if (!this.
|
|
830
|
+
if (!this.cb(0)) {
|
|
824
831
|
return false;
|
|
825
832
|
}
|
|
826
833
|
}
|
|
827
|
-
return this.
|
|
834
|
+
return this.cb(0);
|
|
828
835
|
}
|
|
829
836
|
// Discards one metadata block (key-value entries plus nested sub-metadata).
|
|
830
837
|
// Sub-blocks read depth-first in stream order, matching the C++ stack traversal.
|
|
831
|
-
|
|
838
|
+
cb(level) {
|
|
832
839
|
if (level > kMaxSubmetadataLevel) {
|
|
833
840
|
return false;
|
|
834
841
|
}
|
|
835
|
-
const numEntries = decodeVarint(this.
|
|
842
|
+
const numEntries = decodeVarint(this.G);
|
|
836
843
|
if (numEntries === void 0) {
|
|
837
844
|
return false;
|
|
838
845
|
}
|
|
839
846
|
for (let i = 0; i < numEntries; ++i) {
|
|
840
|
-
const nameSkipped = this.
|
|
841
|
-
const dataSize = nameSkipped ? decodeVarint(this.
|
|
842
|
-
if (dataSize === void 0 || dataSize === 0 || !this.
|
|
847
|
+
const nameSkipped = this.Fb();
|
|
848
|
+
const dataSize = nameSkipped ? decodeVarint(this.G) : void 0;
|
|
849
|
+
if (dataSize === void 0 || dataSize === 0 || !this.Gb(dataSize)) {
|
|
843
850
|
return false;
|
|
844
851
|
}
|
|
845
852
|
}
|
|
846
|
-
const numSubMetadata = decodeVarint(this.
|
|
847
|
-
if (numSubMetadata === void 0 || numSubMetadata > this.
|
|
853
|
+
const numSubMetadata = decodeVarint(this.G);
|
|
854
|
+
if (numSubMetadata === void 0 || numSubMetadata > this.G.remainingSize) {
|
|
848
855
|
return false;
|
|
849
856
|
}
|
|
850
857
|
for (let i = 0; i < numSubMetadata; ++i) {
|
|
851
|
-
if (!this.
|
|
858
|
+
if (!this.Fb() || !this.cb(level + 1)) {
|
|
852
859
|
return false;
|
|
853
860
|
}
|
|
854
861
|
}
|
|
855
862
|
return true;
|
|
856
863
|
}
|
|
857
864
|
// Skips a name (uint8 length prefix followed by that many bytes).
|
|
858
|
-
|
|
859
|
-
const nameLen = this.
|
|
865
|
+
Fb() {
|
|
866
|
+
const nameLen = this.G.decodeUint8();
|
|
860
867
|
if (nameLen === void 0) {
|
|
861
868
|
return false;
|
|
862
869
|
}
|
|
863
|
-
return this.
|
|
870
|
+
return this.Gb(nameLen);
|
|
864
871
|
}
|
|
865
|
-
|
|
866
|
-
if (size > this.
|
|
872
|
+
Gb(size) {
|
|
873
|
+
if (size > this.G.remainingSize) {
|
|
867
874
|
return false;
|
|
868
875
|
}
|
|
869
|
-
this.
|
|
876
|
+
this.G.advance(size);
|
|
870
877
|
return true;
|
|
871
878
|
}
|
|
872
879
|
};
|
|
@@ -936,12 +943,13 @@ var RAnsDecoder = class {
|
|
|
936
943
|
// flat
|
|
937
944
|
cumProbTable = null;
|
|
938
945
|
// flat
|
|
939
|
-
//
|
|
946
|
+
// Coarse mode (see ransBuildLookUpTable): no full-precision lut; a
|
|
940
947
|
// 256-entry bucket table narrows each lookup to a symbol range that a short
|
|
941
948
|
// cumProb scan finishes. cumProbTable then carries one extra trailing entry
|
|
942
949
|
// (== ransPrecision) so the scan needs no bounds check.
|
|
943
950
|
coarse = false;
|
|
944
951
|
bucketShift = 0;
|
|
952
|
+
// Uint16 unless the alphabet needs wider ids, so real streams keep one table type.
|
|
945
953
|
bucketTable = null;
|
|
946
954
|
// Stream state inlined (not a nested AnsDecoder) so the ransRead() hot loop
|
|
947
955
|
// touches own props; initialized by ansReadInit.
|
|
@@ -1001,47 +1009,14 @@ var RAnsDecoder = class {
|
|
|
1001
1009
|
}
|
|
1002
1010
|
// Batch ransRead() into out[0..count): all fields hoisted to locals, state
|
|
1003
1011
|
// written back once. Removes per-symbol property reads and call indirection.
|
|
1004
|
-
// lutTable's element type varies per decoder (Uint8/16/32 by symbol count),
|
|
1005
|
-
// which would make the hot lutTable[rem] access site polymorphic — dispatch
|
|
1006
|
-
// once here so each loop body stays monomorphic on its concrete type. The
|
|
1007
|
-
// three bodies are intentionally identical copies.
|
|
1008
1012
|
decodeSymbols(out, count) {
|
|
1009
1013
|
if (this.coarse) {
|
|
1010
|
-
this.
|
|
1014
|
+
this.jc(out, count);
|
|
1011
1015
|
return;
|
|
1012
1016
|
}
|
|
1013
|
-
|
|
1014
|
-
if (lutTable instanceof Uint8Array) {
|
|
1015
|
-
this.Rb(out, count, lutTable);
|
|
1016
|
-
} else if (lutTable instanceof Uint16Array) {
|
|
1017
|
-
this.Sb(out, count, lutTable);
|
|
1018
|
-
} else {
|
|
1019
|
-
this.Tb(out, count, lutTable);
|
|
1020
|
-
}
|
|
1021
|
-
}
|
|
1022
|
-
Rb(out, count, lutTable) {
|
|
1023
|
-
const buf = this.buf;
|
|
1024
|
-
const lRansBase = this.lRansBase;
|
|
1025
|
-
const ransPrecisionBits = this.ransPrecisionBits;
|
|
1026
|
-
const ransPrecisionMask = this.ransPrecisionMask;
|
|
1027
|
-
const probTable = this.probTable;
|
|
1028
|
-
const cumProbTable = this.cumProbTable;
|
|
1029
|
-
let state = this.state;
|
|
1030
|
-
let bufOffset = this.bufOffset;
|
|
1031
|
-
const bufStart = this.bufStart;
|
|
1032
|
-
for (let i = 0; i < count; ++i) {
|
|
1033
|
-
while (state < lRansBase && bufOffset > bufStart) {
|
|
1034
|
-
state = state << 8 | buf[--bufOffset];
|
|
1035
|
-
}
|
|
1036
|
-
const rem = state & ransPrecisionMask;
|
|
1037
|
-
const symbol = lutTable[rem];
|
|
1038
|
-
out[i] = symbol;
|
|
1039
|
-
state = (state >>> ransPrecisionBits) * probTable[symbol] + rem - cumProbTable[symbol];
|
|
1040
|
-
}
|
|
1041
|
-
this.state = state;
|
|
1042
|
-
this.bufOffset = bufOffset;
|
|
1017
|
+
this.kc(out, count, this.lutTable);
|
|
1043
1018
|
}
|
|
1044
|
-
|
|
1019
|
+
kc(out, count, lutTable) {
|
|
1045
1020
|
const buf = this.buf;
|
|
1046
1021
|
const lRansBase = this.lRansBase;
|
|
1047
1022
|
const ransPrecisionBits = this.ransPrecisionBits;
|
|
@@ -1065,7 +1040,7 @@ var RAnsDecoder = class {
|
|
|
1065
1040
|
}
|
|
1066
1041
|
// Short-stream loop: bucket table + cumProb scan instead of the full lut.
|
|
1067
1042
|
// Same state arithmetic as the lut loops, so the output is identical.
|
|
1068
|
-
|
|
1043
|
+
jc(out, count) {
|
|
1069
1044
|
const buf = this.buf;
|
|
1070
1045
|
const lRansBase = this.lRansBase;
|
|
1071
1046
|
const ransPrecisionBits = this.ransPrecisionBits;
|
|
@@ -1090,28 +1065,6 @@ var RAnsDecoder = class {
|
|
|
1090
1065
|
this.state = state;
|
|
1091
1066
|
this.bufOffset = bufOffset;
|
|
1092
1067
|
}
|
|
1093
|
-
Tb(out, count, lutTable) {
|
|
1094
|
-
const buf = this.buf;
|
|
1095
|
-
const lRansBase = this.lRansBase;
|
|
1096
|
-
const ransPrecisionBits = this.ransPrecisionBits;
|
|
1097
|
-
const ransPrecisionMask = this.ransPrecisionMask;
|
|
1098
|
-
const probTable = this.probTable;
|
|
1099
|
-
const cumProbTable = this.cumProbTable;
|
|
1100
|
-
let state = this.state;
|
|
1101
|
-
let bufOffset = this.bufOffset;
|
|
1102
|
-
const bufStart = this.bufStart;
|
|
1103
|
-
for (let i = 0; i < count; ++i) {
|
|
1104
|
-
while (state < lRansBase && bufOffset > bufStart) {
|
|
1105
|
-
state = state << 8 | buf[--bufOffset];
|
|
1106
|
-
}
|
|
1107
|
-
const rem = state & ransPrecisionMask;
|
|
1108
|
-
const symbol = lutTable[rem];
|
|
1109
|
-
out[i] = symbol;
|
|
1110
|
-
state = (state >>> ransPrecisionBits) * probTable[symbol] + rem - cumProbTable[symbol];
|
|
1111
|
-
}
|
|
1112
|
-
this.state = state;
|
|
1113
|
-
this.bufOffset = bufOffset;
|
|
1114
|
-
}
|
|
1115
1068
|
// Builds the decoding tables. Returns false on bad input data.
|
|
1116
1069
|
//
|
|
1117
1070
|
// expectedCount is how many symbols the caller will decode from this stream.
|
|
@@ -1121,10 +1074,13 @@ var RAnsDecoder = class {
|
|
|
1121
1074
|
// get a coarse 256-entry bucket table (symbol at the start of each
|
|
1122
1075
|
// precision/256-wide bucket) and finish each lookup with a scan of the
|
|
1123
1076
|
// cumulative probabilities; long streams keep the exact lut, whose per-symbol
|
|
1124
|
-
// cost is lower.
|
|
1077
|
+
// cost is lower. The coarse tables also serve an alphabet wider than a
|
|
1078
|
+
// Uint16 lut entry (raw symbol coding allows 2^18 symbols; no real file
|
|
1079
|
+
// has been seen past 2^14), rather than keeping a Uint32 copy of every
|
|
1080
|
+
// lut loop for it.
|
|
1125
1081
|
ransBuildLookUpTable(tokenProbs, numSymbols, expectedCount = 2147483647) {
|
|
1126
1082
|
const ransPrecision = this.ransPrecision;
|
|
1127
|
-
const coarse = numSymbols
|
|
1083
|
+
const coarse = numSymbols > 65536 || expectedCount * COARSE_STREAM_FACTOR < ransPrecision;
|
|
1128
1084
|
this.coarse = coarse;
|
|
1129
1085
|
const probTable = acquirePooled(Uint32Array, numSymbols);
|
|
1130
1086
|
const cumProbTable = acquirePooled(Uint32Array, numSymbols + 1);
|
|
@@ -1147,7 +1103,7 @@ var RAnsDecoder = class {
|
|
|
1147
1103
|
}
|
|
1148
1104
|
cumProbTable[numSymbols] = ransPrecision;
|
|
1149
1105
|
const bucketShift = this.ransPrecisionBits - COARSE_BUCKET_BITS;
|
|
1150
|
-
const bucketTable = acquirePooled(Uint16Array, 1 << COARSE_BUCKET_BITS);
|
|
1106
|
+
const bucketTable = numSymbols > 65536 ? acquirePooled(Uint32Array, 1 << COARSE_BUCKET_BITS) : acquirePooled(Uint16Array, 1 << COARSE_BUCKET_BITS);
|
|
1151
1107
|
this.bucketShift = bucketShift;
|
|
1152
1108
|
this.bucketTable = bucketTable;
|
|
1153
1109
|
let symbol = 0;
|
|
@@ -1158,8 +1114,7 @@ var RAnsDecoder = class {
|
|
|
1158
1114
|
}
|
|
1159
1115
|
return true;
|
|
1160
1116
|
}
|
|
1161
|
-
const
|
|
1162
|
-
const lutTable = acquirePooled(LutArray, ransPrecision);
|
|
1117
|
+
const lutTable = acquirePooled(Uint16Array, ransPrecision);
|
|
1163
1118
|
this.lutTable = lutTable;
|
|
1164
1119
|
let actProb = 0;
|
|
1165
1120
|
for (let i = 0; i < numSymbols; ++i) {
|
|
@@ -1186,66 +1141,9 @@ var RAnsDecoder = class {
|
|
|
1186
1141
|
return true;
|
|
1187
1142
|
}
|
|
1188
1143
|
};
|
|
1189
|
-
function ransDecodeSymbolsPairU8(a, outA, countA, b, outB, countB) {
|
|
1190
|
-
const lutA = a.lutTable;
|
|
1191
|
-
const lutB = b.lutTable;
|
|
1192
|
-
const bufA = a.buf;
|
|
1193
|
-
const bufB = b.buf;
|
|
1194
|
-
const probA = a.probTable;
|
|
1195
|
-
const probB = b.probTable;
|
|
1196
|
-
const cumA = a.cumProbTable;
|
|
1197
|
-
const cumB = b.cumProbTable;
|
|
1198
|
-
const lBaseA = a.lRansBase;
|
|
1199
|
-
const lBaseB = b.lRansBase;
|
|
1200
|
-
const bitsA = a.ransPrecisionBits;
|
|
1201
|
-
const bitsB = b.ransPrecisionBits;
|
|
1202
|
-
const maskA = a.ransPrecisionMask;
|
|
1203
|
-
const maskB = b.ransPrecisionMask;
|
|
1204
|
-
const startA = a.bufStart;
|
|
1205
|
-
const startB = b.bufStart;
|
|
1206
|
-
let stateA = a.state;
|
|
1207
|
-
let stateB = b.state;
|
|
1208
|
-
let offA = a.bufOffset;
|
|
1209
|
-
let offB = b.bufOffset;
|
|
1210
|
-
const shared = countA < countB ? countA : countB;
|
|
1211
|
-
for (let i = 0; i < shared; ++i) {
|
|
1212
|
-
while (stateA < lBaseA && offA > startA) {
|
|
1213
|
-
stateA = stateA << 8 | bufA[--offA];
|
|
1214
|
-
}
|
|
1215
|
-
while (stateB < lBaseB && offB > startB) {
|
|
1216
|
-
stateB = stateB << 8 | bufB[--offB];
|
|
1217
|
-
}
|
|
1218
|
-
const remA = stateA & maskA;
|
|
1219
|
-
const remB = stateB & maskB;
|
|
1220
|
-
const symA = lutA[remA];
|
|
1221
|
-
const symB = lutB[remB];
|
|
1222
|
-
outA[i] = symA;
|
|
1223
|
-
outB[i] = symB;
|
|
1224
|
-
stateA = (stateA >>> bitsA) * probA[symA] + remA - cumA[symA];
|
|
1225
|
-
stateB = (stateB >>> bitsB) * probB[symB] + remB - cumB[symB];
|
|
1226
|
-
}
|
|
1227
|
-
a.state = stateA;
|
|
1228
|
-
a.bufOffset = offA;
|
|
1229
|
-
b.state = stateB;
|
|
1230
|
-
b.bufOffset = offB;
|
|
1231
|
-
if (shared < countA) {
|
|
1232
|
-
a.decodeSymbols(outA.subarray(shared), countA - shared);
|
|
1233
|
-
}
|
|
1234
|
-
if (shared < countB) {
|
|
1235
|
-
b.decodeSymbols(outB.subarray(shared), countB - shared);
|
|
1236
|
-
}
|
|
1237
|
-
}
|
|
1238
1144
|
function ransDecodeSymbolsPair(a, outA, countA, b, outB, countB) {
|
|
1239
|
-
|
|
1240
|
-
const lutB = b.lutTable;
|
|
1241
|
-
if (lutA instanceof Uint8Array && lutB instanceof Uint8Array) {
|
|
1242
|
-
ransDecodeSymbolsPairU8(a, outA, countA, b, outB, countB);
|
|
1243
|
-
} else if (lutA instanceof Uint16Array && lutB instanceof Uint16Array) {
|
|
1145
|
+
if (!a.coarse && !b.coarse) {
|
|
1244
1146
|
ransDecodeSymbolsPairU16(a, outA, countA, b, outB, countB);
|
|
1245
|
-
} else if (lutA instanceof Uint8Array && lutB instanceof Uint16Array) {
|
|
1246
|
-
ransDecodeSymbolsPairU8U16(a, outA, countA, b, outB, countB);
|
|
1247
|
-
} else if (lutA instanceof Uint16Array && lutB instanceof Uint8Array) {
|
|
1248
|
-
ransDecodeSymbolsPairU8U16(b, outB, countB, a, outA, countA);
|
|
1249
1147
|
} else {
|
|
1250
1148
|
a.decodeSymbols(outA, countA);
|
|
1251
1149
|
b.decodeSymbols(outB, countB);
|
|
@@ -1300,56 +1198,7 @@ function ransDecodeSymbolsPairU16(a, outA, countA, b, outB, countB) {
|
|
|
1300
1198
|
b.decodeSymbols(outB.subarray(shared), countB - shared);
|
|
1301
1199
|
}
|
|
1302
1200
|
}
|
|
1303
|
-
function
|
|
1304
|
-
const lutA = a.lutTable;
|
|
1305
|
-
const lutB = b.lutTable;
|
|
1306
|
-
const bufA = a.buf;
|
|
1307
|
-
const bufB = b.buf;
|
|
1308
|
-
const probA = a.probTable;
|
|
1309
|
-
const probB = b.probTable;
|
|
1310
|
-
const cumA = a.cumProbTable;
|
|
1311
|
-
const cumB = b.cumProbTable;
|
|
1312
|
-
const lBaseA = a.lRansBase;
|
|
1313
|
-
const lBaseB = b.lRansBase;
|
|
1314
|
-
const bitsA = a.ransPrecisionBits;
|
|
1315
|
-
const bitsB = b.ransPrecisionBits;
|
|
1316
|
-
const maskA = a.ransPrecisionMask;
|
|
1317
|
-
const maskB = b.ransPrecisionMask;
|
|
1318
|
-
const startA = a.bufStart;
|
|
1319
|
-
const startB = b.bufStart;
|
|
1320
|
-
let stateA = a.state;
|
|
1321
|
-
let stateB = b.state;
|
|
1322
|
-
let offA = a.bufOffset;
|
|
1323
|
-
let offB = b.bufOffset;
|
|
1324
|
-
const shared = countA < countB ? countA : countB;
|
|
1325
|
-
for (let i = 0; i < shared; ++i) {
|
|
1326
|
-
while (stateA < lBaseA && offA > startA) {
|
|
1327
|
-
stateA = stateA << 8 | bufA[--offA];
|
|
1328
|
-
}
|
|
1329
|
-
while (stateB < lBaseB && offB > startB) {
|
|
1330
|
-
stateB = stateB << 8 | bufB[--offB];
|
|
1331
|
-
}
|
|
1332
|
-
const remA = stateA & maskA;
|
|
1333
|
-
const remB = stateB & maskB;
|
|
1334
|
-
const symA = lutA[remA];
|
|
1335
|
-
const symB = lutB[remB];
|
|
1336
|
-
outA[i] = symA;
|
|
1337
|
-
outB[i] = symB;
|
|
1338
|
-
stateA = (stateA >>> bitsA) * probA[symA] + remA - cumA[symA];
|
|
1339
|
-
stateB = (stateB >>> bitsB) * probB[symB] + remB - cumB[symB];
|
|
1340
|
-
}
|
|
1341
|
-
a.state = stateA;
|
|
1342
|
-
a.bufOffset = offA;
|
|
1343
|
-
b.state = stateB;
|
|
1344
|
-
b.bufOffset = offB;
|
|
1345
|
-
if (shared < countA) {
|
|
1346
|
-
a.decodeSymbols(outA.subarray(shared), countA - shared);
|
|
1347
|
-
}
|
|
1348
|
-
if (shared < countB) {
|
|
1349
|
-
b.decodeSymbols(outB.subarray(shared), countB - shared);
|
|
1350
|
-
}
|
|
1351
|
-
}
|
|
1352
|
-
function ransDecodeSymbolsTrioU8(a, outA, countA, b, outB, countB, c, outC, countC) {
|
|
1201
|
+
function ransDecodeSymbolsTrioU16(a, outA, countA, b, outB, countB, c, outC, countC) {
|
|
1353
1202
|
const lutA = a.lutTable;
|
|
1354
1203
|
const lutB = b.lutTable;
|
|
1355
1204
|
const lutC = c.lutTable;
|
|
@@ -1419,7 +1268,7 @@ function ransDecodeSymbolsTrioU8(a, outA, countA, b, outB, countB, c, outC, coun
|
|
|
1419
1268
|
if (restB > 0) tails.push([b, outB.subarray(shared), restB]);
|
|
1420
1269
|
if (restC > 0) tails.push([c, outC.subarray(shared), restC]);
|
|
1421
1270
|
if (tails.length === 2) {
|
|
1422
|
-
|
|
1271
|
+
ransDecodeSymbolsPairU16(tails[0][0], tails[0][1], tails[0][2], tails[1][0], tails[1][1], tails[1][2]);
|
|
1423
1272
|
} else {
|
|
1424
1273
|
for (const [decoder, out, count] of tails) {
|
|
1425
1274
|
decoder.decodeSymbols(out, count);
|
|
@@ -1429,14 +1278,14 @@ function ransDecodeSymbolsTrioU8(a, outA, countA, b, outB, countB, c, outC, coun
|
|
|
1429
1278
|
|
|
1430
1279
|
// src/decoder/compression/point_cloud/PointCloudDecoder.ts
|
|
1431
1280
|
var PointCloudDecoder = class {
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1281
|
+
S = null;
|
|
1282
|
+
d = null;
|
|
1283
|
+
v = [];
|
|
1284
|
+
Qa = [];
|
|
1436
1285
|
// Returns an error message, or '' on success (outHeader is then populated).
|
|
1437
1286
|
static decodeHeader(buffer, outHeader) {
|
|
1438
1287
|
const kIoErrorMsg = "Failed to parse Draco header.";
|
|
1439
|
-
const bytes = buffer.
|
|
1288
|
+
const bytes = buffer.decodeBytesView(5);
|
|
1440
1289
|
if (bytes === void 0) {
|
|
1441
1290
|
return kIoErrorMsg;
|
|
1442
1291
|
}
|
|
@@ -1461,12 +1310,12 @@ var PointCloudDecoder = class {
|
|
|
1461
1310
|
}
|
|
1462
1311
|
// Main entry point, given the already-parsed header (see Decode.ts).
|
|
1463
1312
|
decode(header, inBuffer, outPointCloud) {
|
|
1464
|
-
this.
|
|
1465
|
-
this.
|
|
1313
|
+
this.d = inBuffer;
|
|
1314
|
+
this.S = outPointCloud;
|
|
1466
1315
|
if (header.versionMajor !== 2 || header.versionMinor !== 2) {
|
|
1467
1316
|
return "Unsupported bitstream version (Draco 2.2 meshes only).";
|
|
1468
1317
|
}
|
|
1469
|
-
if (header.flags & METADATA_FLAG_MASK && !new MetadataDecoder(this.
|
|
1318
|
+
if (header.flags & METADATA_FLAG_MASK && !new MetadataDecoder(this.d).skipGeometryMetadata()) {
|
|
1470
1319
|
return "Failed to decode metadata.";
|
|
1471
1320
|
}
|
|
1472
1321
|
if (!this.initializeDecoder()) {
|
|
@@ -1484,30 +1333,30 @@ var PointCloudDecoder = class {
|
|
|
1484
1333
|
if (attDecoderId < 0) {
|
|
1485
1334
|
return false;
|
|
1486
1335
|
}
|
|
1487
|
-
while (this.
|
|
1488
|
-
this.
|
|
1336
|
+
while (this.v.length <= attDecoderId) {
|
|
1337
|
+
this.v.push(null);
|
|
1489
1338
|
}
|
|
1490
|
-
this.
|
|
1339
|
+
this.v[attDecoderId] = decoder;
|
|
1491
1340
|
return true;
|
|
1492
1341
|
}
|
|
1493
1342
|
getPortableAttribute(parentAttId) {
|
|
1494
|
-
if (parentAttId < 0 || parentAttId >= this.
|
|
1343
|
+
if (parentAttId < 0 || parentAttId >= this.S.numAttributes()) {
|
|
1495
1344
|
return null;
|
|
1496
1345
|
}
|
|
1497
|
-
const parentAttDecoderId = this.
|
|
1498
|
-
return this.
|
|
1346
|
+
const parentAttDecoderId = this.Qa[parentAttId];
|
|
1347
|
+
return this.v[parentAttDecoderId].getPortableAttribute(parentAttId);
|
|
1499
1348
|
}
|
|
1500
1349
|
attributesDecoder(decId) {
|
|
1501
|
-
return this.
|
|
1350
|
+
return this.v[decId];
|
|
1502
1351
|
}
|
|
1503
1352
|
numAttributesDecoders() {
|
|
1504
|
-
return this.
|
|
1353
|
+
return this.v.length;
|
|
1505
1354
|
}
|
|
1506
1355
|
pointCloud() {
|
|
1507
|
-
return this.
|
|
1356
|
+
return this.S;
|
|
1508
1357
|
}
|
|
1509
1358
|
buffer() {
|
|
1510
|
-
return this.
|
|
1359
|
+
return this.d;
|
|
1511
1360
|
}
|
|
1512
1361
|
// -- Protected virtual methods (override in subclasses) --
|
|
1513
1362
|
initializeDecoder() {
|
|
@@ -1521,7 +1370,7 @@ var PointCloudDecoder = class {
|
|
|
1521
1370
|
return true;
|
|
1522
1371
|
}
|
|
1523
1372
|
decodePointAttributes() {
|
|
1524
|
-
const numAttributesDecoders = this.
|
|
1373
|
+
const numAttributesDecoders = this.d.decodeUint8();
|
|
1525
1374
|
if (numAttributesDecoders === void 0) {
|
|
1526
1375
|
return false;
|
|
1527
1376
|
}
|
|
@@ -1530,32 +1379,32 @@ var PointCloudDecoder = class {
|
|
|
1530
1379
|
return false;
|
|
1531
1380
|
}
|
|
1532
1381
|
}
|
|
1533
|
-
for (let i = 0; i < this.
|
|
1534
|
-
if (!this.
|
|
1382
|
+
for (let i = 0; i < this.v.length; ++i) {
|
|
1383
|
+
if (!this.v[i].init(this, this.S)) {
|
|
1535
1384
|
return false;
|
|
1536
1385
|
}
|
|
1537
1386
|
}
|
|
1538
1387
|
for (let i = 0; i < numAttributesDecoders; ++i) {
|
|
1539
|
-
if (!this.
|
|
1388
|
+
if (!this.v[i].decodeAttributesDecoderData(this.d)) {
|
|
1540
1389
|
return false;
|
|
1541
1390
|
}
|
|
1542
1391
|
}
|
|
1543
1392
|
for (let i = 0; i < numAttributesDecoders; ++i) {
|
|
1544
|
-
const numAttributes = this.
|
|
1393
|
+
const numAttributes = this.v[i].getNumAttributes();
|
|
1545
1394
|
for (let j = 0; j < numAttributes; ++j) {
|
|
1546
|
-
const attId = this.
|
|
1547
|
-
while (this.
|
|
1548
|
-
this.
|
|
1395
|
+
const attId = this.v[i].getAttributeId(j);
|
|
1396
|
+
while (this.Qa.length <= attId) {
|
|
1397
|
+
this.Qa.push(0);
|
|
1549
1398
|
}
|
|
1550
|
-
this.
|
|
1399
|
+
this.Qa[attId] = i;
|
|
1551
1400
|
}
|
|
1552
1401
|
}
|
|
1553
1402
|
return this.decodeAllAttributes();
|
|
1554
1403
|
}
|
|
1555
1404
|
decodeAllAttributes() {
|
|
1556
|
-
const decoders = this.
|
|
1405
|
+
const decoders = this.v;
|
|
1557
1406
|
for (let i2 = 0; i2 < decoders.length; i2++) {
|
|
1558
|
-
if (!decoders[i2].decodeAttributesParse(this.
|
|
1407
|
+
if (!decoders[i2].decodeAttributesParse(this.d)) {
|
|
1559
1408
|
return false;
|
|
1560
1409
|
}
|
|
1561
1410
|
}
|
|
@@ -1587,10 +1436,10 @@ var PointCloudDecoder = class {
|
|
|
1587
1436
|
|
|
1588
1437
|
// src/decoder/compression/mesh/MeshDecoder.ts
|
|
1589
1438
|
var MeshDecoder = class extends PointCloudDecoder {
|
|
1590
|
-
|
|
1439
|
+
H = null;
|
|
1591
1440
|
// Returns an error message, or '' on success.
|
|
1592
1441
|
decodeMesh(header, inBuffer, outMesh) {
|
|
1593
|
-
this.
|
|
1442
|
+
this.H = outMesh;
|
|
1594
1443
|
return this.decode(header, inBuffer, outMesh);
|
|
1595
1444
|
}
|
|
1596
1445
|
// Connectivity accessors used by the mesh prediction schemes; the sequential
|
|
@@ -1605,7 +1454,7 @@ var MeshDecoder = class extends PointCloudDecoder {
|
|
|
1605
1454
|
return null;
|
|
1606
1455
|
}
|
|
1607
1456
|
mesh() {
|
|
1608
|
-
return this.
|
|
1457
|
+
return this.H;
|
|
1609
1458
|
}
|
|
1610
1459
|
decodeGeometryData() {
|
|
1611
1460
|
return this.decodeConnectivity() && super.decodeGeometryData();
|
|
@@ -1616,60 +1465,60 @@ var MeshDecoder = class extends PointCloudDecoder {
|
|
|
1616
1465
|
var kInvalidCornerIndex = -1;
|
|
1617
1466
|
var kInvalidVertexIndex = -1;
|
|
1618
1467
|
var MeshAttributeCornerTable = class {
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1468
|
+
ba = [];
|
|
1469
|
+
ta = [];
|
|
1470
|
+
ca = [];
|
|
1471
|
+
ua = [];
|
|
1623
1472
|
// Attribute-vertex count. C++ keeps a vertex -> attribute-entry map here, but
|
|
1624
1473
|
// the decoder only ever reads its size, so track the count directly instead
|
|
1625
1474
|
// of allocating an Int32Array per attribute corner table.
|
|
1626
|
-
|
|
1627
|
-
|
|
1475
|
+
va = 0;
|
|
1476
|
+
w = null;
|
|
1628
1477
|
// Lazily built; see oppositeCornerArray.
|
|
1629
|
-
|
|
1478
|
+
T = null;
|
|
1630
1479
|
// Every corner passed to addSeamEdge (may contain duplicates); lets
|
|
1631
1480
|
// oppositeCornerArray patch seams without scanning every corner's flag.
|
|
1632
1481
|
// Preallocated to its exact upper bound (2 per seam edge) by the caller via
|
|
1633
1482
|
// reserveSeamEdges -- a plain array grown by push() was measurable on
|
|
1634
1483
|
// seam-heavy files.
|
|
1635
|
-
|
|
1636
|
-
|
|
1484
|
+
da = [];
|
|
1485
|
+
U = 0;
|
|
1637
1486
|
initEmpty(table) {
|
|
1638
1487
|
if (table === null) {
|
|
1639
1488
|
return false;
|
|
1640
1489
|
}
|
|
1641
|
-
this.
|
|
1642
|
-
this.
|
|
1643
|
-
this.
|
|
1644
|
-
this.
|
|
1645
|
-
this.
|
|
1646
|
-
this.
|
|
1647
|
-
this.
|
|
1648
|
-
this.
|
|
1649
|
-
this.
|
|
1490
|
+
this.ba = scratchUint8Zeroed(table.numCorners());
|
|
1491
|
+
this.ta = scratchUint8Zeroed(table.numVertices());
|
|
1492
|
+
this.ca = scratchInt32Filled(table.numCorners(), kInvalidVertexIndex);
|
|
1493
|
+
this.va = 0;
|
|
1494
|
+
this.ua = [];
|
|
1495
|
+
this.T = null;
|
|
1496
|
+
this.da = [];
|
|
1497
|
+
this.U = 0;
|
|
1498
|
+
this.w = table;
|
|
1650
1499
|
return true;
|
|
1651
1500
|
}
|
|
1652
1501
|
// Sizes the seam-corner list for numSeamEdges upcoming addSeamEdge calls
|
|
1653
1502
|
// (each adds at most two corners). Decode-scoped scratch.
|
|
1654
1503
|
reserveSeamEdges(numSeamEdges) {
|
|
1655
|
-
this.
|
|
1656
|
-
this.
|
|
1504
|
+
this.da = scratchInt32(numSeamEdges * 2);
|
|
1505
|
+
this.U = 0;
|
|
1657
1506
|
}
|
|
1658
1507
|
addSeamEdge(c) {
|
|
1659
|
-
const cornerToVertex = this.
|
|
1660
|
-
const oppositeCorners = this.
|
|
1661
|
-
const isEdge = this.
|
|
1662
|
-
const isVert = this.
|
|
1663
|
-
const seamCorners = this.
|
|
1508
|
+
const cornerToVertex = this.w.cornerToVertexArray();
|
|
1509
|
+
const oppositeCorners = this.w.oppositeCornerArray();
|
|
1510
|
+
const isEdge = this.ba;
|
|
1511
|
+
const isVert = this.ta;
|
|
1512
|
+
const seamCorners = this.da;
|
|
1664
1513
|
isEdge[c] = 1;
|
|
1665
|
-
seamCorners[this.
|
|
1514
|
+
seamCorners[this.U++] = c;
|
|
1666
1515
|
let rem = c - (c / 3 | 0) * 3;
|
|
1667
1516
|
isVert[cornerToVertex[rem === 2 ? c - 2 : c + 1]] = 1;
|
|
1668
1517
|
isVert[cornerToVertex[rem === 0 ? c + 2 : c - 1]] = 1;
|
|
1669
1518
|
const oppCorner = oppositeCorners[c];
|
|
1670
1519
|
if (oppCorner !== kInvalidCornerIndex) {
|
|
1671
1520
|
isEdge[oppCorner] = 1;
|
|
1672
|
-
seamCorners[this.
|
|
1521
|
+
seamCorners[this.U++] = oppCorner;
|
|
1673
1522
|
rem = oppCorner - (oppCorner / 3 | 0) * 3;
|
|
1674
1523
|
isVert[cornerToVertex[rem === 2 ? oppCorner - 2 : oppCorner + 1]] = 1;
|
|
1675
1524
|
isVert[cornerToVertex[rem === 0 ? oppCorner + 2 : oppCorner - 1]] = 1;
|
|
@@ -1680,23 +1529,23 @@ var MeshAttributeCornerTable = class {
|
|
|
1680
1529
|
// over the per-vertex left-most corners here). leftMostMap is decode-scoped
|
|
1681
1530
|
// scratch sized for at least numNewVertices entries.
|
|
1682
1531
|
setRecomputedVertices(leftMostMap, numNewVertices) {
|
|
1683
|
-
this.
|
|
1684
|
-
this.
|
|
1532
|
+
this.va = numNewVertices;
|
|
1533
|
+
this.ua = leftMostMap.length === numNewVertices ? leftMostMap : leftMostMap.subarray(0, numNewVertices);
|
|
1685
1534
|
}
|
|
1686
1535
|
isCornerOppositeToSeamEdge(corner) {
|
|
1687
|
-
return this.
|
|
1536
|
+
return this.ba[corner];
|
|
1688
1537
|
}
|
|
1689
1538
|
opposite(corner) {
|
|
1690
1539
|
if (corner === kInvalidCornerIndex || this.isCornerOppositeToSeamEdge(corner)) {
|
|
1691
1540
|
return kInvalidCornerIndex;
|
|
1692
1541
|
}
|
|
1693
|
-
return this.
|
|
1542
|
+
return this.w.opposite(corner);
|
|
1694
1543
|
}
|
|
1695
1544
|
next(corner) {
|
|
1696
|
-
return this.
|
|
1545
|
+
return this.w.next(corner);
|
|
1697
1546
|
}
|
|
1698
1547
|
previous(corner) {
|
|
1699
|
-
return this.
|
|
1548
|
+
return this.w.previous(corner);
|
|
1700
1549
|
}
|
|
1701
1550
|
swingRight(corner) {
|
|
1702
1551
|
return this.previous(this.opposite(this.previous(corner)));
|
|
@@ -1705,68 +1554,68 @@ var MeshAttributeCornerTable = class {
|
|
|
1705
1554
|
return this.next(this.opposite(this.next(corner)));
|
|
1706
1555
|
}
|
|
1707
1556
|
numVertices() {
|
|
1708
|
-
return this.
|
|
1557
|
+
return this.va;
|
|
1709
1558
|
}
|
|
1710
1559
|
numFaces() {
|
|
1711
|
-
return this.
|
|
1560
|
+
return this.w.numFaces();
|
|
1712
1561
|
}
|
|
1713
1562
|
numCorners() {
|
|
1714
|
-
return this.
|
|
1563
|
+
return this.w.numCorners();
|
|
1715
1564
|
}
|
|
1716
1565
|
// --- Flat-array accessors: let DepthFirstTraverser avoid per-corner dispatch. ---
|
|
1717
1566
|
cornerToVertexArray() {
|
|
1718
|
-
return this.
|
|
1567
|
+
return this.ca;
|
|
1719
1568
|
}
|
|
1720
1569
|
// Seam-aware opposite corners (seam edges -> -1), matching opposite(). Cached on
|
|
1721
1570
|
// first use; seams and connectivity are finalized before traversal, so it's stable.
|
|
1722
1571
|
oppositeCornerArray() {
|
|
1723
|
-
if (this.
|
|
1724
|
-
const nc = this.
|
|
1725
|
-
const base = this.
|
|
1726
|
-
const seamCorners = this.
|
|
1727
|
-
const numSeamCorners = this.
|
|
1572
|
+
if (this.T === null) {
|
|
1573
|
+
const nc = this.w.numCorners();
|
|
1574
|
+
const base = this.w.oppositeCornerArray();
|
|
1575
|
+
const seamCorners = this.da;
|
|
1576
|
+
const numSeamCorners = this.U;
|
|
1728
1577
|
if (numSeamCorners === 0) {
|
|
1729
|
-
this.
|
|
1578
|
+
this.T = base;
|
|
1730
1579
|
} else {
|
|
1731
1580
|
const eff = scratchInt32(nc);
|
|
1732
1581
|
eff.set(base.length === nc ? base : base.subarray(0, nc));
|
|
1733
1582
|
for (let i = 0; i < numSeamCorners; ++i) {
|
|
1734
1583
|
eff[seamCorners[i]] = kInvalidCornerIndex;
|
|
1735
1584
|
}
|
|
1736
|
-
this.
|
|
1585
|
+
this.T = eff;
|
|
1737
1586
|
}
|
|
1738
1587
|
}
|
|
1739
|
-
return this.
|
|
1588
|
+
return this.T;
|
|
1740
1589
|
}
|
|
1741
1590
|
vertexLeftmostCornerArray() {
|
|
1742
|
-
return this.
|
|
1591
|
+
return this.ua;
|
|
1743
1592
|
}
|
|
1744
1593
|
// Takes over another table's state wholesale. Only valid when both tables
|
|
1745
1594
|
// were built from the same corner table and the same seam edges, in which
|
|
1746
1595
|
// case every one of these is identical and read-only from here on.
|
|
1747
1596
|
adoptFrom(other) {
|
|
1748
|
-
this.
|
|
1749
|
-
this.
|
|
1750
|
-
this.
|
|
1751
|
-
this.
|
|
1752
|
-
this.
|
|
1753
|
-
this.
|
|
1754
|
-
this.
|
|
1755
|
-
this.
|
|
1756
|
-
this.
|
|
1597
|
+
this.w = other.w;
|
|
1598
|
+
this.ba = other.ba;
|
|
1599
|
+
this.ta = other.ta;
|
|
1600
|
+
this.ca = other.ca;
|
|
1601
|
+
this.va = other.va;
|
|
1602
|
+
this.ua = other.ua;
|
|
1603
|
+
this.T = other.T;
|
|
1604
|
+
this.da = other.da;
|
|
1605
|
+
this.U = other.U;
|
|
1757
1606
|
}
|
|
1758
1607
|
};
|
|
1759
1608
|
|
|
1760
1609
|
// src/decoder/compression/attributes/AttributesDecoder.ts
|
|
1761
1610
|
var AttributesDecoder = class {
|
|
1762
|
-
|
|
1611
|
+
Ra = [];
|
|
1763
1612
|
// Inverse of _pointAttributeIds: point attribute id -> local id.
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1613
|
+
wa = [];
|
|
1614
|
+
Hb = null;
|
|
1615
|
+
S = null;
|
|
1767
1616
|
init(decoder, pointCloud) {
|
|
1768
|
-
this.
|
|
1769
|
-
this.
|
|
1617
|
+
this.Hb = decoder;
|
|
1618
|
+
this.S = pointCloud;
|
|
1770
1619
|
return true;
|
|
1771
1620
|
}
|
|
1772
1621
|
decodeAttributesDecoderData(buffer) {
|
|
@@ -1774,8 +1623,8 @@ var AttributesDecoder = class {
|
|
|
1774
1623
|
if (numAttributes === void 0 || numAttributes === 0 || numAttributes > 5 * buffer.remainingSize) {
|
|
1775
1624
|
return false;
|
|
1776
1625
|
}
|
|
1777
|
-
this.
|
|
1778
|
-
const pc = this.
|
|
1626
|
+
this.Ra.length = numAttributes;
|
|
1627
|
+
const pc = this.S;
|
|
1779
1628
|
for (let i = 0; i < numAttributes; i++) {
|
|
1780
1629
|
const attType = buffer.decodeUint8();
|
|
1781
1630
|
if (attType === void 0) return false;
|
|
@@ -1788,7 +1637,7 @@ var AttributesDecoder = class {
|
|
|
1788
1637
|
if (attType >= Type.NAMED_ATTRIBUTES_COUNT) {
|
|
1789
1638
|
return false;
|
|
1790
1639
|
}
|
|
1791
|
-
if (dataType ===
|
|
1640
|
+
if (dataType === 0 /* INVALID */ || dataType >= 12 /* TYPES_COUNT */) {
|
|
1792
1641
|
return false;
|
|
1793
1642
|
}
|
|
1794
1643
|
if (numComponents === 0) {
|
|
@@ -1801,42 +1650,42 @@ var AttributesDecoder = class {
|
|
|
1801
1650
|
ga.uniqueId = uniqueId;
|
|
1802
1651
|
const attId = pc.addAttribute(new PointAttribute(ga));
|
|
1803
1652
|
pc.attribute(attId).uniqueId = uniqueId;
|
|
1804
|
-
this.
|
|
1805
|
-
while (this.
|
|
1806
|
-
this.
|
|
1653
|
+
this.Ra[i] = attId;
|
|
1654
|
+
while (this.wa.length <= attId) {
|
|
1655
|
+
this.wa.push(-1);
|
|
1807
1656
|
}
|
|
1808
|
-
this.
|
|
1657
|
+
this.wa[attId] = i;
|
|
1809
1658
|
}
|
|
1810
1659
|
return true;
|
|
1811
1660
|
}
|
|
1812
1661
|
getAttributeId(i) {
|
|
1813
|
-
return this.
|
|
1662
|
+
return this.Ra[i];
|
|
1814
1663
|
}
|
|
1815
1664
|
getNumAttributes() {
|
|
1816
|
-
return this.
|
|
1665
|
+
return this.Ra.length;
|
|
1817
1666
|
}
|
|
1818
1667
|
getDecoder() {
|
|
1819
|
-
return this.
|
|
1668
|
+
return this.Hb;
|
|
1820
1669
|
}
|
|
1821
1670
|
getLocalIdForPointAttribute(pointAttributeId) {
|
|
1822
|
-
if (pointAttributeId >= this.
|
|
1671
|
+
if (pointAttributeId >= this.wa.length) {
|
|
1823
1672
|
return -1;
|
|
1824
1673
|
}
|
|
1825
|
-
return this.
|
|
1674
|
+
return this.wa[pointAttributeId];
|
|
1826
1675
|
}
|
|
1827
1676
|
};
|
|
1828
1677
|
|
|
1829
1678
|
// src/decoder/compression/attributes/SequentialAttributeDecoder.ts
|
|
1830
1679
|
var SequentialAttributeDecoder = class {
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1680
|
+
n = null;
|
|
1681
|
+
I = null;
|
|
1682
|
+
Ib = -1;
|
|
1834
1683
|
// Decoded portable attribute (after lossless decoding).
|
|
1835
|
-
|
|
1684
|
+
ea = null;
|
|
1836
1685
|
init(decoder, attributeId) {
|
|
1837
|
-
this.
|
|
1838
|
-
this.
|
|
1839
|
-
this.
|
|
1686
|
+
this.n = decoder;
|
|
1687
|
+
this.I = decoder.pointCloud().attribute(attributeId);
|
|
1688
|
+
this.Ib = attributeId;
|
|
1840
1689
|
return true;
|
|
1841
1690
|
}
|
|
1842
1691
|
// --- Two-phase decode ---
|
|
@@ -1847,14 +1696,20 @@ var SequentialAttributeDecoder = class {
|
|
|
1847
1696
|
// stream simply do the whole decode in Parse (decodeValues); the defaults
|
|
1848
1697
|
// below are theirs.
|
|
1849
1698
|
decodePortableAttributeParse(pointIds, buffer) {
|
|
1850
|
-
if (this.
|
|
1699
|
+
if (this.I.numComponents <= 0) {
|
|
1851
1700
|
return false;
|
|
1852
1701
|
}
|
|
1853
|
-
if (!this.
|
|
1702
|
+
if (!this.Jb(pointIds.length)) {
|
|
1854
1703
|
return false;
|
|
1855
1704
|
}
|
|
1856
1705
|
return this.decodeValues(pointIds, buffer);
|
|
1857
1706
|
}
|
|
1707
|
+
// Sizes (and here allocates) the attribute's storage for numValues values;
|
|
1708
|
+
// the integer decoders override it to skip the allocation, their values
|
|
1709
|
+
// staying in the portable attribute (see PointAttribute.setLazyInteger).
|
|
1710
|
+
Jb(numValues) {
|
|
1711
|
+
return this.I.reset(numValues);
|
|
1712
|
+
}
|
|
1858
1713
|
pendingSymbolStream() {
|
|
1859
1714
|
return null;
|
|
1860
1715
|
}
|
|
@@ -1870,35 +1725,35 @@ var SequentialAttributeDecoder = class {
|
|
|
1870
1725
|
return true;
|
|
1871
1726
|
}
|
|
1872
1727
|
getPortableAttribute() {
|
|
1873
|
-
if (!this.
|
|
1874
|
-
const size = this.
|
|
1875
|
-
this.
|
|
1876
|
-
const src = this.
|
|
1877
|
-
const dst = this.
|
|
1728
|
+
if (!this.I.isMappingIdentity && this.ea && this.ea.isMappingIdentity) {
|
|
1729
|
+
const size = this.I.indicesMapSize;
|
|
1730
|
+
this.ea.setExplicitMappingScratch(size);
|
|
1731
|
+
const src = this.I.indicesMap;
|
|
1732
|
+
const dst = this.ea.indicesMap;
|
|
1878
1733
|
if (src.length === size) {
|
|
1879
1734
|
dst.set(src);
|
|
1880
1735
|
} else {
|
|
1881
1736
|
dst.set(src.subarray(0, size));
|
|
1882
1737
|
}
|
|
1883
1738
|
}
|
|
1884
|
-
return this.
|
|
1739
|
+
return this.ea;
|
|
1885
1740
|
}
|
|
1886
1741
|
get attribute() {
|
|
1887
|
-
return this.
|
|
1742
|
+
return this.I;
|
|
1888
1743
|
}
|
|
1889
1744
|
get attributeId() {
|
|
1890
|
-
return this.
|
|
1745
|
+
return this.Ib;
|
|
1891
1746
|
}
|
|
1892
1747
|
get decoder() {
|
|
1893
|
-
return this.
|
|
1748
|
+
return this.n;
|
|
1894
1749
|
}
|
|
1895
1750
|
initPredictionScheme(ps) {
|
|
1896
1751
|
for (let i = 0; i < ps.getNumParentAttributes(); i++) {
|
|
1897
|
-
const attId = this.
|
|
1752
|
+
const attId = this.n.pointCloud().getNamedAttributeId(ps.getParentAttributeType(i));
|
|
1898
1753
|
if (attId === -1) {
|
|
1899
1754
|
return false;
|
|
1900
1755
|
}
|
|
1901
|
-
const pa = this.
|
|
1756
|
+
const pa = this.n.getPortableAttribute(attId);
|
|
1902
1757
|
if (pa === null || !ps.setParentAttribute(pa)) {
|
|
1903
1758
|
return false;
|
|
1904
1759
|
}
|
|
@@ -1908,13 +1763,13 @@ var SequentialAttributeDecoder = class {
|
|
|
1908
1763
|
// Decodes raw attribute values in their original format.
|
|
1909
1764
|
decodeValues(pointIds, buffer) {
|
|
1910
1765
|
const numValues = pointIds.length;
|
|
1911
|
-
const entrySize = this.
|
|
1766
|
+
const entrySize = this.I.byteStride;
|
|
1912
1767
|
const totalSize = numValues * entrySize;
|
|
1913
1768
|
const valueData = buffer.decodeBytesView(totalSize);
|
|
1914
1769
|
if (valueData === void 0) {
|
|
1915
1770
|
return false;
|
|
1916
1771
|
}
|
|
1917
|
-
this.
|
|
1772
|
+
this.I.buffer.write(0, valueData, totalSize);
|
|
1918
1773
|
return true;
|
|
1919
1774
|
}
|
|
1920
1775
|
};
|
|
@@ -1929,14 +1784,14 @@ function convertSymbolsToSignedInts(input, count, output) {
|
|
|
1929
1784
|
|
|
1930
1785
|
// src/decoder/compression/entropy/RAnsSymbolDecoder.ts
|
|
1931
1786
|
var RAnsSymbolDecoder = class {
|
|
1932
|
-
|
|
1933
|
-
|
|
1787
|
+
Kb = 0;
|
|
1788
|
+
o;
|
|
1934
1789
|
constructor(uniqueSymbolsBitLength) {
|
|
1935
1790
|
const unclamped = Math.trunc(3 * uniqueSymbolsBitLength / 2);
|
|
1936
|
-
this.
|
|
1791
|
+
this.o = new RAnsDecoder(unclamped < 12 ? 12 : unclamped > 20 ? 20 : unclamped);
|
|
1937
1792
|
}
|
|
1938
1793
|
get numSymbols() {
|
|
1939
|
-
return this.
|
|
1794
|
+
return this.Kb;
|
|
1940
1795
|
}
|
|
1941
1796
|
// Initialize the decoder and decode the probability table. expectedCount is
|
|
1942
1797
|
// the number of symbols the caller will decode (lets short streams skip the
|
|
@@ -1944,7 +1799,7 @@ var RAnsSymbolDecoder = class {
|
|
|
1944
1799
|
create(buffer, expectedCount = 2147483647) {
|
|
1945
1800
|
const numSymbols = decodeVarint(buffer);
|
|
1946
1801
|
if (numSymbols === void 0) return false;
|
|
1947
|
-
this.
|
|
1802
|
+
this.Kb = numSymbols;
|
|
1948
1803
|
if (Math.trunc(numSymbols / 64) > buffer.remainingSize) {
|
|
1949
1804
|
return false;
|
|
1950
1805
|
}
|
|
@@ -1977,7 +1832,7 @@ var RAnsSymbolDecoder = class {
|
|
|
1977
1832
|
}
|
|
1978
1833
|
}
|
|
1979
1834
|
buffer.advance(pos - startPos);
|
|
1980
|
-
return this.
|
|
1835
|
+
return this.o.ransBuildLookUpTable(probabilityTable, numSymbols, expectedCount);
|
|
1981
1836
|
}
|
|
1982
1837
|
// Starts decoding, advancing buffer past the encoded data.
|
|
1983
1838
|
startDecoding(buffer) {
|
|
@@ -1988,10 +1843,10 @@ var RAnsSymbolDecoder = class {
|
|
|
1988
1843
|
}
|
|
1989
1844
|
const base = buffer.decodedSize;
|
|
1990
1845
|
buffer.advance(Number(bytesEncoded));
|
|
1991
|
-
return ansReadInit(this.
|
|
1846
|
+
return ansReadInit(this.o, buffer.data, base + Number(bytesEncoded), base, this.o.lRansBase, 4);
|
|
1992
1847
|
}
|
|
1993
1848
|
endDecoding() {
|
|
1994
|
-
this.
|
|
1849
|
+
this.o.readEnd();
|
|
1995
1850
|
}
|
|
1996
1851
|
};
|
|
1997
1852
|
|
|
@@ -2001,9 +1856,9 @@ function decodeSymbols(numValues, numComponents, srcBuffer, outValues) {
|
|
|
2001
1856
|
return true;
|
|
2002
1857
|
}
|
|
2003
1858
|
const scheme = srcBuffer.decodeUint8();
|
|
2004
|
-
if (scheme ===
|
|
1859
|
+
if (scheme === 0 /* SYMBOL_CODING_TAGGED */) {
|
|
2005
1860
|
return decodeTaggedSymbols(numValues, numComponents, srcBuffer, outValues);
|
|
2006
|
-
} else if (scheme ===
|
|
1861
|
+
} else if (scheme === 1 /* SYMBOL_CODING_RAW */) {
|
|
2007
1862
|
return decodeRawSymbols(numValues, srcBuffer, outValues);
|
|
2008
1863
|
}
|
|
2009
1864
|
return false;
|
|
@@ -2019,11 +1874,11 @@ function decodeTaggedSymbols(numValues, numComponents, srcBuffer, outValues) {
|
|
|
2019
1874
|
if (numValues > 0 && tagDecoder.numSymbols === 0) {
|
|
2020
1875
|
return false;
|
|
2021
1876
|
}
|
|
2022
|
-
const tagAns = tagDecoder.
|
|
1877
|
+
const tagAns = tagDecoder.o;
|
|
2023
1878
|
srcBuffer.startBitDecoding(false);
|
|
2024
|
-
const bd = srcBuffer.
|
|
2025
|
-
const buf = bd.
|
|
2026
|
-
const byteLength = bd.
|
|
1879
|
+
const bd = srcBuffer.sa;
|
|
1880
|
+
const buf = bd.Na;
|
|
1881
|
+
const byteLength = bd.ra;
|
|
2027
1882
|
let bitOffset = bd.q;
|
|
2028
1883
|
let valueId = 0;
|
|
2029
1884
|
for (let i = 0; i < numValues; i += numComponents) {
|
|
@@ -2091,15 +1946,15 @@ function decodeRawSymbols(numValues, srcBuffer, outValues) {
|
|
|
2091
1946
|
if (decoder === null) {
|
|
2092
1947
|
return false;
|
|
2093
1948
|
}
|
|
2094
|
-
decoder.
|
|
1949
|
+
decoder.o.decodeSymbols(outValues, numValues);
|
|
2095
1950
|
decoder.endDecoding();
|
|
2096
1951
|
return true;
|
|
2097
1952
|
}
|
|
2098
1953
|
|
|
2099
1954
|
// src/decoder/compression/bit_coders/RAnsBitDecoder.ts
|
|
2100
1955
|
var RAnsBitDecoder = class {
|
|
2101
|
-
|
|
2102
|
-
|
|
1956
|
+
db = new AnsDecoder();
|
|
1957
|
+
eb = 0;
|
|
2103
1958
|
// ANS_P8_PRECISION - probZero, precomputed
|
|
2104
1959
|
// Returns false when the data is invalid.
|
|
2105
1960
|
startDecoding(sourceBuffer) {
|
|
@@ -2107,21 +1962,21 @@ var RAnsBitDecoder = class {
|
|
|
2107
1962
|
if (probZero === void 0) {
|
|
2108
1963
|
return false;
|
|
2109
1964
|
}
|
|
2110
|
-
this.
|
|
1965
|
+
this.eb = ANS_P8_PRECISION - probZero;
|
|
2111
1966
|
const sizeInBytes = decodeVarint(sourceBuffer);
|
|
2112
1967
|
if (sizeInBytes === void 0 || sizeInBytes > sourceBuffer.remainingSize) {
|
|
2113
1968
|
return false;
|
|
2114
1969
|
}
|
|
2115
1970
|
const base = sourceBuffer.decodedSize;
|
|
2116
|
-
if (!ansReadInit(this.
|
|
1971
|
+
if (!ansReadInit(this.db, sourceBuffer.data, base + sizeInBytes, base, ANS_L_BASE, 3)) {
|
|
2117
1972
|
return false;
|
|
2118
1973
|
}
|
|
2119
1974
|
sourceBuffer.advance(sizeInBytes);
|
|
2120
1975
|
return true;
|
|
2121
1976
|
}
|
|
2122
1977
|
decodeNextBit() {
|
|
2123
|
-
const ans = this.
|
|
2124
|
-
const p = this.
|
|
1978
|
+
const ans = this.db;
|
|
1979
|
+
const p = this.eb;
|
|
2125
1980
|
if (ans.state < ANS_L_BASE && ans.bufOffset > ans.bufStart) {
|
|
2126
1981
|
ans.state = ans.state << 8 | ans.buf[--ans.bufOffset];
|
|
2127
1982
|
}
|
|
@@ -2217,18 +2072,18 @@ var MAX_NUM_PARALLELOGRAMS = 4;
|
|
|
2217
2072
|
var MeshPredictionSchemeConstrainedMultiParallelogramDecoder = class extends MeshPredictionSchemeDecoder {
|
|
2218
2073
|
// Crease edges stored per context (number of available parallelograms),
|
|
2219
2074
|
// one list per context up to MAX_NUM_PARALLELOGRAMS.
|
|
2220
|
-
|
|
2075
|
+
Sa = [[], [], [], []];
|
|
2221
2076
|
decodePredictionData(buffer) {
|
|
2222
2077
|
for (let i = 0; i < MAX_NUM_PARALLELOGRAMS; ++i) {
|
|
2223
2078
|
const numFlags = decodeVarint(buffer);
|
|
2224
2079
|
if (numFlags === void 0) return false;
|
|
2225
2080
|
if (numFlags > this.c.cornerTable.numCorners()) return false;
|
|
2226
2081
|
if (numFlags > 0) {
|
|
2227
|
-
this.
|
|
2082
|
+
this.Sa[i] = new Array(numFlags);
|
|
2228
2083
|
const decoder = new RAnsBitDecoder();
|
|
2229
2084
|
if (!decoder.startDecoding(buffer)) return false;
|
|
2230
2085
|
for (let j = 0; j < numFlags; ++j) {
|
|
2231
|
-
this.
|
|
2086
|
+
this.Sa[i][j] = decoder.decodeNextBit();
|
|
2232
2087
|
}
|
|
2233
2088
|
decoder.endDecoding();
|
|
2234
2089
|
}
|
|
@@ -2287,8 +2142,8 @@ var MeshPredictionSchemeConstrainedMultiParallelogramDecoder = class extends Mes
|
|
|
2287
2142
|
for (let i = 0; i < numParallelograms; ++i) {
|
|
2288
2143
|
const context = numParallelograms - 1;
|
|
2289
2144
|
const pos = isCreaseEdgePos[context]++;
|
|
2290
|
-
if (this.
|
|
2291
|
-
const isCrease = this.
|
|
2145
|
+
if (this.Sa[context].length <= pos) return false;
|
|
2146
|
+
const isCrease = this.Sa[context][pos];
|
|
2292
2147
|
if (!isCrease) {
|
|
2293
2148
|
++numUsedParallelograms;
|
|
2294
2149
|
for (let j = 0; j < numComponents; ++j) {
|
|
@@ -2326,23 +2181,23 @@ var MeshPredictionSchemeData = class {
|
|
|
2326
2181
|
|
|
2327
2182
|
// src/decoder/compression/attributes/NormalCompressionUtils.ts
|
|
2328
2183
|
var OctahedronToolBox = class {
|
|
2329
|
-
|
|
2330
|
-
|
|
2184
|
+
N = -1;
|
|
2185
|
+
xa = -1;
|
|
2331
2186
|
m = -1;
|
|
2332
|
-
|
|
2187
|
+
lc = 1;
|
|
2333
2188
|
f = -1;
|
|
2334
2189
|
// q: quantization bits, valid range 2..30.
|
|
2335
2190
|
setQuantizationBits(q) {
|
|
2336
2191
|
if (q < 2 || q > 30) return false;
|
|
2337
|
-
this.
|
|
2338
|
-
this.
|
|
2339
|
-
this.m = this.
|
|
2340
|
-
this.
|
|
2192
|
+
this.N = q;
|
|
2193
|
+
this.xa = (1 << q) - 1;
|
|
2194
|
+
this.m = this.xa - 1;
|
|
2195
|
+
this.lc = Math.fround(2 / Math.fround(this.m));
|
|
2341
2196
|
this.f = this.m / 2 | 0;
|
|
2342
2197
|
return true;
|
|
2343
2198
|
}
|
|
2344
2199
|
quantizationBits() {
|
|
2345
|
-
return this.
|
|
2200
|
+
return this.N;
|
|
2346
2201
|
}
|
|
2347
2202
|
// Canonicalizes edge points into consistent quadrants. Writes result into
|
|
2348
2203
|
// out[0], out[1] (caller-owned reusable 2-element array).
|
|
@@ -2399,14 +2254,14 @@ var OctahedronToolBox = class {
|
|
|
2399
2254
|
}
|
|
2400
2255
|
}
|
|
2401
2256
|
// The octahedral -> unit vector direction (quantizedOctahedralCoordsToUnitVector
|
|
2402
|
-
// in the source) lives inlined in
|
|
2257
|
+
// in the source) lives inlined in PointAttribute._extractOctahedron.
|
|
2403
2258
|
};
|
|
2404
2259
|
|
|
2405
2260
|
// src/decoder/compression/attributes/prediction_schemes/MeshPredictionSchemeGeometricNormalPredictorArea.ts
|
|
2406
2261
|
var UPPER_BOUND = 1 << 29;
|
|
2407
2262
|
function fillInt32PositionCache(cache, att, map, numEntries, tempPos) {
|
|
2408
2263
|
const bufData = att.buffer && att.buffer.data;
|
|
2409
|
-
if (att.dataType ===
|
|
2264
|
+
if (att.dataType === 5 /* INT32 */ && att.numComponents === 3 && bufData) {
|
|
2410
2265
|
const src = new Int32Array(bufData.buffer);
|
|
2411
2266
|
const srcStart = bufData.byteOffset + att.byteOffset >> 2;
|
|
2412
2267
|
const stride = att.byteStride >> 2;
|
|
@@ -2440,31 +2295,31 @@ function fillInt32PositionCache(cache, att, map, numEntries, tempPos) {
|
|
|
2440
2295
|
}
|
|
2441
2296
|
}
|
|
2442
2297
|
var MeshPredictionSchemeGeometricNormalPredictorArea = class {
|
|
2443
|
-
|
|
2444
|
-
|
|
2298
|
+
ya = null;
|
|
2299
|
+
za = null;
|
|
2445
2300
|
c;
|
|
2446
|
-
|
|
2447
|
-
|
|
2301
|
+
fb = new Array(3);
|
|
2302
|
+
Aa = null;
|
|
2448
2303
|
// flat Int32 positions, indexed by data id
|
|
2449
|
-
|
|
2450
|
-
|
|
2304
|
+
s = null;
|
|
2305
|
+
Lb = null;
|
|
2451
2306
|
// corner -> posCache offset, precomputed
|
|
2452
2307
|
constructor(meshData) {
|
|
2453
2308
|
this.c = meshData;
|
|
2454
2309
|
}
|
|
2455
2310
|
setPositionAttribute(positionAttribute) {
|
|
2456
|
-
this.
|
|
2311
|
+
this.ya = positionAttribute;
|
|
2457
2312
|
}
|
|
2458
2313
|
setEntryToPointIdMap(map) {
|
|
2459
|
-
this.
|
|
2314
|
+
this.za = map;
|
|
2460
2315
|
}
|
|
2461
2316
|
buildPositionCache(numEntries) {
|
|
2462
2317
|
const posCache = scratchInt32(numEntries * 3);
|
|
2463
|
-
fillInt32PositionCache(posCache, this.
|
|
2464
|
-
this.
|
|
2318
|
+
fillInt32PositionCache(posCache, this.ya, this.za, numEntries, this.fb);
|
|
2319
|
+
this.Aa = posCache;
|
|
2465
2320
|
const table = this.c.cornerTable;
|
|
2466
2321
|
const cornerToVertex = table.cornerToVertexArray();
|
|
2467
|
-
this.
|
|
2322
|
+
this.s = table.oppositeCornerArray();
|
|
2468
2323
|
const vertexToDataMap = this.c.vertexToDataMap;
|
|
2469
2324
|
const nc = cornerToVertex.length;
|
|
2470
2325
|
const c2o = scratchInt32(nc);
|
|
@@ -2472,12 +2327,12 @@ var MeshPredictionSchemeGeometricNormalPredictorArea = class {
|
|
|
2472
2327
|
const v = cornerToVertex[c];
|
|
2473
2328
|
c2o[c] = v < 0 ? -1 : vertexToDataMap[v] * 3;
|
|
2474
2329
|
}
|
|
2475
|
-
this.
|
|
2330
|
+
this.Lb = c2o;
|
|
2476
2331
|
}
|
|
2477
2332
|
computePredictedValue(cornerId, prediction) {
|
|
2478
|
-
const oppositeCorners = this.
|
|
2479
|
-
const cornerToOffset = this.
|
|
2480
|
-
const posCache = this.
|
|
2333
|
+
const oppositeCorners = this.s;
|
|
2334
|
+
const cornerToOffset = this.Lb;
|
|
2335
|
+
const posCache = this.Aa;
|
|
2481
2336
|
const centerOffset = cornerToOffset[cornerId];
|
|
2482
2337
|
const centX = posCache[centerOffset];
|
|
2483
2338
|
const centY = posCache[centerOffset + 1];
|
|
@@ -2554,12 +2409,12 @@ var MeshPredictionSchemeGeometricNormalPredictorArea = class {
|
|
|
2554
2409
|
// src/decoder/compression/attributes/prediction_schemes/MeshPredictionSchemeGeometricNormalDecoder.ts
|
|
2555
2410
|
var GEOMETRY_ATTRIBUTE_POSITION = 0;
|
|
2556
2411
|
var MeshPredictionSchemeGeometricNormalDecoder = class extends MeshPredictionSchemeDecoder {
|
|
2557
|
-
|
|
2412
|
+
t;
|
|
2558
2413
|
B = new OctahedronToolBox();
|
|
2559
|
-
|
|
2414
|
+
gb = new RAnsBitDecoder();
|
|
2560
2415
|
constructor(transform, meshData) {
|
|
2561
2416
|
super(transform, meshData);
|
|
2562
|
-
this.
|
|
2417
|
+
this.t = new MeshPredictionSchemeGeometricNormalPredictorArea(meshData);
|
|
2563
2418
|
}
|
|
2564
2419
|
getNumParentAttributes() {
|
|
2565
2420
|
return 1;
|
|
@@ -2570,25 +2425,25 @@ var MeshPredictionSchemeGeometricNormalDecoder = class extends MeshPredictionSch
|
|
|
2570
2425
|
setParentAttribute(att) {
|
|
2571
2426
|
if (att.attributeType !== GEOMETRY_ATTRIBUTE_POSITION) return false;
|
|
2572
2427
|
if (att.numComponents !== 3) return false;
|
|
2573
|
-
this.
|
|
2428
|
+
this.t.setPositionAttribute(att);
|
|
2574
2429
|
return true;
|
|
2575
2430
|
}
|
|
2576
2431
|
decodePredictionData(buffer) {
|
|
2577
2432
|
if (!this.h.decodeTransformData(buffer)) return false;
|
|
2578
|
-
return this.
|
|
2433
|
+
return this.gb.startDecoding(buffer);
|
|
2579
2434
|
}
|
|
2580
2435
|
computeOriginalValues(inCorr, outData, _size, _numComponents, entryToPointIdMap) {
|
|
2581
2436
|
this.B.setQuantizationBits(this.h.quantizationBits());
|
|
2582
|
-
this.
|
|
2437
|
+
this.t.setEntryToPointIdMap(entryToPointIdMap);
|
|
2583
2438
|
const cornerMapSize = this.c.dataToCornerMap.length;
|
|
2584
|
-
this.
|
|
2439
|
+
this.t.buildPositionCache(cornerMapSize);
|
|
2585
2440
|
const predNormal3D = new Int32Array(3);
|
|
2586
2441
|
const predNormalOct = new Int32Array(2);
|
|
2587
2442
|
for (let dataId = 0; dataId < cornerMapSize; ++dataId) {
|
|
2588
2443
|
const cornerId = this.c.dataToCornerMap[dataId];
|
|
2589
|
-
this.
|
|
2444
|
+
this.t.computePredictedValue(cornerId, predNormal3D);
|
|
2590
2445
|
this.B.canonicalizeIntegerVector(predNormal3D);
|
|
2591
|
-
if (this.
|
|
2446
|
+
if (this.gb.decodeNextBit()) {
|
|
2592
2447
|
predNormal3D[0] = -predNormal3D[0];
|
|
2593
2448
|
predNormal3D[1] = -predNormal3D[1];
|
|
2594
2449
|
predNormal3D[2] = -predNormal3D[2];
|
|
@@ -2597,7 +2452,7 @@ var MeshPredictionSchemeGeometricNormalDecoder = class extends MeshPredictionSch
|
|
|
2597
2452
|
const dataOffset = dataId * 2;
|
|
2598
2453
|
this.h.computeOriginalValue(predNormalOct, 0, inCorr, dataOffset, outData, dataOffset);
|
|
2599
2454
|
}
|
|
2600
|
-
this.
|
|
2455
|
+
this.gb.endDecoding();
|
|
2601
2456
|
return true;
|
|
2602
2457
|
}
|
|
2603
2458
|
};
|
|
@@ -2664,7 +2519,7 @@ var MeshPredictionSchemeParallelogramDecoder = class extends MeshPredictionSchem
|
|
|
2664
2519
|
// zigzag form, unpacking each one inline.
|
|
2665
2520
|
computeOriginalValuesZigzag(inCorr, outData, _size, numComponents, _entryToPointIdMap) {
|
|
2666
2521
|
this.h.init(numComponents);
|
|
2667
|
-
return this.
|
|
2522
|
+
return this.mc(inCorr, outData, numComponents, true);
|
|
2668
2523
|
}
|
|
2669
2524
|
// The wrap transform's corrections are zigzag-coded; with `zigzag` set the
|
|
2670
2525
|
// decode folds the (val >>> 1) ^ -(val & 1) unpacking into each correction
|
|
@@ -2672,15 +2527,15 @@ var MeshPredictionSchemeParallelogramDecoder = class extends MeshPredictionSchem
|
|
|
2672
2527
|
// whole array (see computeOriginalValuesZigzag). Every correction is read
|
|
2673
2528
|
// exactly once before its slot is overwritten, so the in-place aliasing of
|
|
2674
2529
|
// inCorr and outData is preserved.
|
|
2675
|
-
|
|
2530
|
+
mc(inCorr, outData, numComponents, zigzag) {
|
|
2676
2531
|
if (numComponents === 2) {
|
|
2677
|
-
return this.
|
|
2532
|
+
return this.nc(inCorr, outData, zigzag);
|
|
2678
2533
|
}
|
|
2679
2534
|
if (numComponents === 3) {
|
|
2680
|
-
return this.
|
|
2535
|
+
return this.oc(inCorr, outData, zigzag);
|
|
2681
2536
|
}
|
|
2682
2537
|
if (numComponents === 4) {
|
|
2683
|
-
return this.
|
|
2538
|
+
return this.pc(inCorr, outData, zigzag);
|
|
2684
2539
|
}
|
|
2685
2540
|
const table = this.c.cornerTable;
|
|
2686
2541
|
const vertexToDataMap = this.c.vertexToDataMap;
|
|
@@ -2688,9 +2543,9 @@ var MeshPredictionSchemeParallelogramDecoder = class extends MeshPredictionSchem
|
|
|
2688
2543
|
const cornerToVertex = table.cornerToVertexArray();
|
|
2689
2544
|
const dataToCornerMap = this.c.dataToCornerMap;
|
|
2690
2545
|
const transform = this.h;
|
|
2691
|
-
const minValue = transform.
|
|
2546
|
+
const minValue = transform.fa;
|
|
2692
2547
|
const maxValue = transform.m;
|
|
2693
|
-
const maxDif = transform
|
|
2548
|
+
const maxDif = transform.ga;
|
|
2694
2549
|
for (let c = 0; c < numComponents; ++c) {
|
|
2695
2550
|
let pred = 0;
|
|
2696
2551
|
if (pred > maxValue) {
|
|
@@ -2769,16 +2624,16 @@ var MeshPredictionSchemeParallelogramDecoder = class extends MeshPredictionSchem
|
|
|
2769
2624
|
}
|
|
2770
2625
|
return true;
|
|
2771
2626
|
}
|
|
2772
|
-
|
|
2627
|
+
nc(inCorr, outData, zigzag) {
|
|
2773
2628
|
const table = this.c.cornerTable;
|
|
2774
2629
|
const vertexToDataMap = this.c.vertexToDataMap;
|
|
2775
2630
|
const oppositeCorners = table.oppositeCornerArray();
|
|
2776
2631
|
const cornerToVertex = table.cornerToVertexArray();
|
|
2777
2632
|
const dataToCornerMap = this.c.dataToCornerMap;
|
|
2778
2633
|
const transform = this.h;
|
|
2779
|
-
const minValue = transform.
|
|
2634
|
+
const minValue = transform.fa;
|
|
2780
2635
|
const maxValue = transform.m;
|
|
2781
|
-
const maxDif = transform
|
|
2636
|
+
const maxDif = transform.ga;
|
|
2782
2637
|
let pred0 = 0;
|
|
2783
2638
|
let pred1 = 0;
|
|
2784
2639
|
if (pred0 > maxValue) {
|
|
@@ -2867,16 +2722,16 @@ var MeshPredictionSchemeParallelogramDecoder = class extends MeshPredictionSchem
|
|
|
2867
2722
|
}
|
|
2868
2723
|
return true;
|
|
2869
2724
|
}
|
|
2870
|
-
|
|
2725
|
+
oc(inCorr, outData, zigzag) {
|
|
2871
2726
|
const table = this.c.cornerTable;
|
|
2872
2727
|
const vertexToDataMap = this.c.vertexToDataMap;
|
|
2873
2728
|
const oppositeCorners = table.oppositeCornerArray();
|
|
2874
2729
|
const cornerToVertex = table.cornerToVertexArray();
|
|
2875
2730
|
const dataToCornerMap = this.c.dataToCornerMap;
|
|
2876
2731
|
const transform = this.h;
|
|
2877
|
-
const minValue = transform.
|
|
2732
|
+
const minValue = transform.fa;
|
|
2878
2733
|
const maxValue = transform.m;
|
|
2879
|
-
const maxDif = transform
|
|
2734
|
+
const maxDif = transform.ga;
|
|
2880
2735
|
let pred0 = 0;
|
|
2881
2736
|
let pred1 = 0;
|
|
2882
2737
|
let pred2 = 0;
|
|
@@ -2996,16 +2851,16 @@ var MeshPredictionSchemeParallelogramDecoder = class extends MeshPredictionSchem
|
|
|
2996
2851
|
}
|
|
2997
2852
|
// Four components: tangents, RGBA colors, skin joints/weights. Same
|
|
2998
2853
|
// structure as the 2/3-component loops.
|
|
2999
|
-
|
|
2854
|
+
pc(inCorr, outData, zigzag) {
|
|
3000
2855
|
const table = this.c.cornerTable;
|
|
3001
2856
|
const vertexToDataMap = this.c.vertexToDataMap;
|
|
3002
2857
|
const oppositeCorners = table.oppositeCornerArray();
|
|
3003
2858
|
const cornerToVertex = table.cornerToVertexArray();
|
|
3004
2859
|
const dataToCornerMap = this.c.dataToCornerMap;
|
|
3005
2860
|
const transform = this.h;
|
|
3006
|
-
const minValue = transform.
|
|
2861
|
+
const minValue = transform.fa;
|
|
3007
2862
|
const maxValue = transform.m;
|
|
3008
|
-
const maxDif = transform
|
|
2863
|
+
const maxDif = transform.ga;
|
|
3009
2864
|
let pred0 = 0;
|
|
3010
2865
|
if (pred0 > maxValue) {
|
|
3011
2866
|
pred0 = maxValue;
|
|
@@ -3124,39 +2979,39 @@ function bigIntSqrt(value) {
|
|
|
3124
2979
|
return x;
|
|
3125
2980
|
}
|
|
3126
2981
|
var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
2982
|
+
ya = null;
|
|
2983
|
+
za = null;
|
|
2984
|
+
u = new Int32Array(2);
|
|
2985
|
+
Ta = new Uint8Array(0);
|
|
2986
|
+
Ba = 0;
|
|
3132
2987
|
c;
|
|
3133
|
-
|
|
2988
|
+
fb = new Array(3);
|
|
3134
2989
|
// Flat Int32 position cache so fetches are array reads, not convertValue calls.
|
|
3135
|
-
|
|
2990
|
+
Aa = null;
|
|
3136
2991
|
j = null;
|
|
3137
2992
|
constructor(meshData) {
|
|
3138
2993
|
this.c = meshData;
|
|
3139
2994
|
}
|
|
3140
2995
|
setPositionAttribute(positionAttribute) {
|
|
3141
|
-
this.
|
|
2996
|
+
this.ya = positionAttribute;
|
|
3142
2997
|
}
|
|
3143
2998
|
setEntryToPointIdMap(map) {
|
|
3144
|
-
this.
|
|
2999
|
+
this.za = map;
|
|
3145
3000
|
}
|
|
3146
3001
|
get predictedValue() {
|
|
3147
|
-
return this.
|
|
3002
|
+
return this.u;
|
|
3148
3003
|
}
|
|
3149
3004
|
resizeOrientations(numOrientations) {
|
|
3150
|
-
this.
|
|
3151
|
-
this.
|
|
3005
|
+
this.Ta = new Uint8Array(numOrientations);
|
|
3006
|
+
this.Ba = numOrientations;
|
|
3152
3007
|
}
|
|
3153
3008
|
setOrientation(i, v) {
|
|
3154
|
-
this.
|
|
3009
|
+
this.Ta[i] = v ? 1 : 0;
|
|
3155
3010
|
}
|
|
3156
3011
|
buildPositionCache(numEntries) {
|
|
3157
3012
|
const posCache = new Int32Array(numEntries * 3);
|
|
3158
|
-
fillInt32PositionCache(posCache, this.
|
|
3159
|
-
this.
|
|
3013
|
+
fillInt32PositionCache(posCache, this.ya, this.za, numEntries, this.fb);
|
|
3014
|
+
this.Aa = posCache;
|
|
3160
3015
|
this.j = this.c.cornerTable.cornerToVertexArray();
|
|
3161
3016
|
}
|
|
3162
3017
|
computePredictedValue(cornerId, data, dataId) {
|
|
@@ -3175,11 +3030,11 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
3175
3030
|
const nUV0 = data[nDataOff], nUV1 = data[nDataOff + 1];
|
|
3176
3031
|
const pUV0 = data[pDataOff], pUV1 = data[pDataOff + 1];
|
|
3177
3032
|
if (pUV0 === nUV0 && pUV1 === nUV1) {
|
|
3178
|
-
this.
|
|
3179
|
-
this.
|
|
3033
|
+
this.u[0] = pUV0;
|
|
3034
|
+
this.u[1] = pUV1;
|
|
3180
3035
|
return true;
|
|
3181
3036
|
}
|
|
3182
|
-
const posCache = this.
|
|
3037
|
+
const posCache = this.Aa;
|
|
3183
3038
|
let posOffset = dataId * 3;
|
|
3184
3039
|
const tip0 = posCache[posOffset];
|
|
3185
3040
|
const tip1 = posCache[posOffset + 1];
|
|
@@ -3216,7 +3071,7 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
3216
3071
|
const pnAbsMaxG = Math.max(Math.abs(pn0), Math.abs(pn1), Math.abs(pn2));
|
|
3217
3072
|
const cnDotPnAbs = Math.abs(cnDotPn);
|
|
3218
3073
|
if (cnNorm2 > SAFE_PRODUCT / pnNorm2Squared || nUVAbsMax > SAFE_PRODUCT / pnNorm2Squared || pnUVAbsMax > 0 && cnDotPnAbs > SAFE_PRODUCT / pnUVAbsMax || pnAbsMaxG > 0 && cnDotPnAbs > SAFE_PRODUCT / pnAbsMaxG) {
|
|
3219
|
-
return this.
|
|
3074
|
+
return this.qc(
|
|
3220
3075
|
tip0,
|
|
3221
3076
|
tip1,
|
|
3222
3077
|
tip2,
|
|
@@ -3248,16 +3103,16 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
3248
3103
|
const normSquared = Math.floor(Math.sqrt(cxNorm2Squared * pnNorm2Squared));
|
|
3249
3104
|
const cxUV0 = pnUV1 * normSquared;
|
|
3250
3105
|
const cxUV1 = -pnUV0 * normSquared;
|
|
3251
|
-
if (this.
|
|
3106
|
+
if (this.Ba === 0) {
|
|
3252
3107
|
return false;
|
|
3253
3108
|
}
|
|
3254
|
-
const orientation = this.
|
|
3109
|
+
const orientation = this.Ta[--this.Ba];
|
|
3255
3110
|
if (orientation) {
|
|
3256
|
-
this.
|
|
3257
|
-
this.
|
|
3111
|
+
this.u[0] = Math.trunc((xUV0 + cxUV0) / pnNorm2Squared);
|
|
3112
|
+
this.u[1] = Math.trunc((xUV1 + cxUV1) / pnNorm2Squared);
|
|
3258
3113
|
} else {
|
|
3259
|
-
this.
|
|
3260
|
-
this.
|
|
3114
|
+
this.u[0] = Math.trunc((xUV0 - cxUV0) / pnNorm2Squared);
|
|
3115
|
+
this.u[1] = Math.trunc((xUV1 - cxUV1) / pnNorm2Squared);
|
|
3261
3116
|
}
|
|
3262
3117
|
return true;
|
|
3263
3118
|
}
|
|
@@ -3272,13 +3127,13 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
3272
3127
|
if (dataId > 0) {
|
|
3273
3128
|
dataOffset = (dataId - 1) * 2;
|
|
3274
3129
|
} else {
|
|
3275
|
-
this.
|
|
3276
|
-
this.
|
|
3130
|
+
this.u[0] = 0;
|
|
3131
|
+
this.u[1] = 0;
|
|
3277
3132
|
return true;
|
|
3278
3133
|
}
|
|
3279
3134
|
}
|
|
3280
|
-
this.
|
|
3281
|
-
this.
|
|
3135
|
+
this.u[0] = data[dataOffset];
|
|
3136
|
+
this.u[1] = data[dataOffset + 1];
|
|
3282
3137
|
return true;
|
|
3283
3138
|
}
|
|
3284
3139
|
// 64-bit-exact projection prediction, used when the double path would lose
|
|
@@ -3286,7 +3141,7 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
3286
3141
|
// <uint64_t>, including the uint64 wraparound in IntSqrt(cxNorm2*pnNorm2) and
|
|
3287
3142
|
// the unsigned add/sub forming the final UV. Returns false in the same
|
|
3288
3143
|
// overflow cases as the double path so encoder and decoder agree on fallback.
|
|
3289
|
-
|
|
3144
|
+
qc(tip0, tip1, tip2, next0, next1, next2, pn0, pn1, pn2, nUV0, nUV1, pUV0, pUV1, pnNorm2SquaredNum) {
|
|
3290
3145
|
const B = BigInt;
|
|
3291
3146
|
const tip = [B(tip0), B(tip1), B(tip2)];
|
|
3292
3147
|
const nxt = [B(next0), B(next1), B(next2)];
|
|
@@ -3320,8 +3175,8 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
3320
3175
|
const normSquared = bigIntSqrt(cxNorm2 * pnN2 & MASK64);
|
|
3321
3176
|
const cxUV0 = B.asIntN(64, pnUV1 * normSquared);
|
|
3322
3177
|
const cxUV1 = B.asIntN(64, -pnUV0 * normSquared);
|
|
3323
|
-
if (this.
|
|
3324
|
-
const orientation = this.
|
|
3178
|
+
if (this.Ba === 0) return false;
|
|
3179
|
+
const orientation = this.Ta[--this.Ba];
|
|
3325
3180
|
let s0, s1;
|
|
3326
3181
|
if (orientation) {
|
|
3327
3182
|
s0 = B.asUintN(64, B.asUintN(64, xUV0) + B.asUintN(64, cxUV0));
|
|
@@ -3330,8 +3185,8 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
3330
3185
|
s0 = B.asUintN(64, B.asUintN(64, xUV0) - B.asUintN(64, cxUV0));
|
|
3331
3186
|
s1 = B.asUintN(64, B.asUintN(64, xUV1) - B.asUintN(64, cxUV1));
|
|
3332
3187
|
}
|
|
3333
|
-
this.
|
|
3334
|
-
this.
|
|
3188
|
+
this.u[0] = Number(B.asIntN(32, B.asIntN(64, s0) / pnN2));
|
|
3189
|
+
this.u[1] = Number(B.asIntN(32, B.asIntN(64, s1) / pnN2));
|
|
3335
3190
|
return true;
|
|
3336
3191
|
}
|
|
3337
3192
|
};
|
|
@@ -3339,10 +3194,10 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
3339
3194
|
// src/decoder/compression/attributes/prediction_schemes/MeshPredictionSchemeTexCoordsPortableDecoder.ts
|
|
3340
3195
|
var GEOMETRY_ATTRIBUTE_POSITION2 = 0;
|
|
3341
3196
|
var MeshPredictionSchemeTexCoordsPortableDecoder = class extends MeshPredictionSchemeDecoder {
|
|
3342
|
-
|
|
3197
|
+
t;
|
|
3343
3198
|
constructor(transform, meshData) {
|
|
3344
3199
|
super(transform, meshData);
|
|
3345
|
-
this.
|
|
3200
|
+
this.t = new MeshPredictionSchemeTexCoordsPortablePredictor(meshData);
|
|
3346
3201
|
}
|
|
3347
3202
|
getNumParentAttributes() {
|
|
3348
3203
|
return 1;
|
|
@@ -3353,13 +3208,13 @@ var MeshPredictionSchemeTexCoordsPortableDecoder = class extends MeshPredictionS
|
|
|
3353
3208
|
setParentAttribute(att) {
|
|
3354
3209
|
if (att.attributeType !== GEOMETRY_ATTRIBUTE_POSITION2) return false;
|
|
3355
3210
|
if (att.numComponents !== 3) return false;
|
|
3356
|
-
this.
|
|
3211
|
+
this.t.setPositionAttribute(att);
|
|
3357
3212
|
return true;
|
|
3358
3213
|
}
|
|
3359
3214
|
decodePredictionData(buffer) {
|
|
3360
3215
|
const numOrientations = buffer.decodeInt32();
|
|
3361
3216
|
if (numOrientations === void 0 || numOrientations < 0) return false;
|
|
3362
|
-
this.
|
|
3217
|
+
this.t.resizeOrientations(numOrientations);
|
|
3363
3218
|
let lastOrientation = true;
|
|
3364
3219
|
const decoder = new RAnsBitDecoder();
|
|
3365
3220
|
if (!decoder.startDecoding(buffer)) return false;
|
|
@@ -3367,7 +3222,7 @@ var MeshPredictionSchemeTexCoordsPortableDecoder = class extends MeshPredictionS
|
|
|
3367
3222
|
if (!decoder.decodeNextBit()) {
|
|
3368
3223
|
lastOrientation = !lastOrientation;
|
|
3369
3224
|
}
|
|
3370
|
-
this.
|
|
3225
|
+
this.t.setOrientation(i, lastOrientation);
|
|
3371
3226
|
}
|
|
3372
3227
|
decoder.endDecoding();
|
|
3373
3228
|
return super.decodePredictionData(buffer);
|
|
@@ -3376,17 +3231,17 @@ var MeshPredictionSchemeTexCoordsPortableDecoder = class extends MeshPredictionS
|
|
|
3376
3231
|
if (numComponents !== 2) {
|
|
3377
3232
|
return false;
|
|
3378
3233
|
}
|
|
3379
|
-
this.
|
|
3234
|
+
this.t.setEntryToPointIdMap(entryToPointIdMap);
|
|
3380
3235
|
this.h.init(numComponents);
|
|
3381
3236
|
const cornerMapSize = this.c.dataToCornerMap.length;
|
|
3382
|
-
this.
|
|
3237
|
+
this.t.buildPositionCache(cornerMapSize);
|
|
3383
3238
|
for (let p = 0; p < cornerMapSize; ++p) {
|
|
3384
3239
|
const cornerId = this.c.dataToCornerMap[p];
|
|
3385
|
-
if (!this.
|
|
3240
|
+
if (!this.t.computePredictedValue(cornerId, outData, p)) {
|
|
3386
3241
|
return false;
|
|
3387
3242
|
}
|
|
3388
3243
|
const dstOffset = p * numComponents;
|
|
3389
|
-
this.h.computeOriginalValue(this.
|
|
3244
|
+
this.h.computeOriginalValue(this.t.predictedValue, 0, inCorr, dstOffset, outData, dstOffset);
|
|
3390
3245
|
}
|
|
3391
3246
|
return true;
|
|
3392
3247
|
}
|
|
@@ -3413,27 +3268,27 @@ var PredictionSchemeDeltaDecoder = class extends PredictionSchemeDecoder {
|
|
|
3413
3268
|
// src/decoder/compression/attributes/prediction_schemes/PredictionSchemeDecoderFactory.ts
|
|
3414
3269
|
function createMeshPredictionSchemeDecoder(method, transform, meshData) {
|
|
3415
3270
|
const transformType = transform.getType();
|
|
3416
|
-
if (transformType ===
|
|
3417
|
-
if (method ===
|
|
3271
|
+
if (transformType === 3 /* PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON_CANONICALIZED */ || transformType === 2 /* PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON */) {
|
|
3272
|
+
if (method === 6 /* MESH_PREDICTION_GEOMETRIC_NORMAL */) {
|
|
3418
3273
|
return new MeshPredictionSchemeGeometricNormalDecoder(transform, meshData);
|
|
3419
3274
|
}
|
|
3420
3275
|
return null;
|
|
3421
3276
|
}
|
|
3422
3277
|
switch (method) {
|
|
3423
|
-
case
|
|
3278
|
+
case 1 /* MESH_PREDICTION_PARALLELOGRAM */:
|
|
3424
3279
|
return new MeshPredictionSchemeParallelogramDecoder(transform, meshData);
|
|
3425
|
-
case
|
|
3280
|
+
case 2 /* MESH_PREDICTION_MULTI_PARALLELOGRAM */:
|
|
3426
3281
|
return new MeshPredictionSchemeMultiParallelogramDecoder(transform, meshData);
|
|
3427
|
-
case
|
|
3282
|
+
case 4 /* MESH_PREDICTION_CONSTRAINED_MULTI_PARALLELOGRAM */:
|
|
3428
3283
|
return new MeshPredictionSchemeConstrainedMultiParallelogramDecoder(transform, meshData);
|
|
3429
|
-
case
|
|
3284
|
+
case 5 /* MESH_PREDICTION_TEX_COORDS_PORTABLE */:
|
|
3430
3285
|
return new MeshPredictionSchemeTexCoordsPortableDecoder(transform, meshData);
|
|
3431
3286
|
default:
|
|
3432
3287
|
return null;
|
|
3433
3288
|
}
|
|
3434
3289
|
}
|
|
3435
3290
|
function createPredictionSchemeForDecoder(method, attId, decoder, transform) {
|
|
3436
|
-
if (method ===
|
|
3291
|
+
if (method === -2 /* PREDICTION_NONE */) {
|
|
3437
3292
|
return null;
|
|
3438
3293
|
}
|
|
3439
3294
|
const meshDecoder = decoder;
|
|
@@ -3454,24 +3309,24 @@ function createPredictionSchemeForDecoder(method, attId, decoder, transform) {
|
|
|
3454
3309
|
|
|
3455
3310
|
// src/decoder/compression/attributes/prediction_schemes/PredictionSchemeWrapDecodingTransform.ts
|
|
3456
3311
|
var PredictionSchemeWrapDecodingTransform = class {
|
|
3457
|
-
|
|
3458
|
-
|
|
3312
|
+
z = 0;
|
|
3313
|
+
fa = 0;
|
|
3459
3314
|
m = 0;
|
|
3460
|
-
|
|
3315
|
+
ga = 0;
|
|
3461
3316
|
getType() {
|
|
3462
|
-
return
|
|
3317
|
+
return 1 /* PREDICTION_TRANSFORM_WRAP */;
|
|
3463
3318
|
}
|
|
3464
3319
|
init(numComponents) {
|
|
3465
|
-
this.
|
|
3320
|
+
this.z = numComponents;
|
|
3466
3321
|
}
|
|
3467
3322
|
areCorrectionsPositive() {
|
|
3468
3323
|
return false;
|
|
3469
3324
|
}
|
|
3470
3325
|
computeOriginalValue(predictedVals, predictedOffset, corrVals, corrOffset, outOriginalVals, outOffset) {
|
|
3471
|
-
const nc = this.
|
|
3472
|
-
const minValue = this.
|
|
3326
|
+
const nc = this.z;
|
|
3327
|
+
const minValue = this.fa;
|
|
3473
3328
|
const maxValue = this.m;
|
|
3474
|
-
const maxDif = this
|
|
3329
|
+
const maxDif = this.ga;
|
|
3475
3330
|
for (let i = 0; i < nc; ++i) {
|
|
3476
3331
|
let pred = predictedVals[predictedOffset + i];
|
|
3477
3332
|
if (pred > maxValue) {
|
|
@@ -3495,63 +3350,65 @@ var PredictionSchemeWrapDecodingTransform = class {
|
|
|
3495
3350
|
if (maxValue === void 0) return false;
|
|
3496
3351
|
const dif = maxValue - minValue;
|
|
3497
3352
|
if (dif < 0 || dif >= 2147483647) return false;
|
|
3498
|
-
this.
|
|
3353
|
+
this.fa = minValue;
|
|
3499
3354
|
this.m = maxValue;
|
|
3500
|
-
this
|
|
3355
|
+
this.ga = 1 + dif;
|
|
3501
3356
|
return true;
|
|
3502
3357
|
}
|
|
3503
3358
|
};
|
|
3504
3359
|
|
|
3505
3360
|
// src/decoder/compression/attributes/SequentialIntegerAttributeDecoder.ts
|
|
3506
3361
|
var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder {
|
|
3507
|
-
|
|
3362
|
+
ha = null;
|
|
3508
3363
|
// Two-phase decode state (see SequentialAttributeDecoder): the parse phase
|
|
3509
3364
|
// stashes the primed raw-symbol stream here so the controller can batch and
|
|
3510
3365
|
// pair several attributes' decodes; the finish phase consumes it.
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3366
|
+
ia = null;
|
|
3367
|
+
hb = 0;
|
|
3368
|
+
Mb = null;
|
|
3514
3369
|
// Int32 view over the portable attribute's storage (see preparePortableAttribute).
|
|
3515
|
-
|
|
3370
|
+
V = null;
|
|
3516
3371
|
// --- Two-phase decode (parse headers / batch symbol decode / finish) ---
|
|
3517
3372
|
pendingSymbolStream() {
|
|
3518
|
-
if (this.
|
|
3373
|
+
if (this.ia === null) {
|
|
3519
3374
|
return null;
|
|
3520
3375
|
}
|
|
3521
|
-
const portableData = this.
|
|
3376
|
+
const portableData = this.V;
|
|
3522
3377
|
return {
|
|
3523
|
-
ans: this.
|
|
3524
|
-
out: new Uint32Array(portableData.buffer, portableData.byteOffset, this.
|
|
3525
|
-
count: this.
|
|
3378
|
+
ans: this.ia.o,
|
|
3379
|
+
out: new Uint32Array(portableData.buffer, portableData.byteOffset, this.hb),
|
|
3380
|
+
count: this.hb
|
|
3526
3381
|
};
|
|
3527
3382
|
}
|
|
3528
3383
|
decodePortableAttributeFinish() {
|
|
3529
|
-
if (this.
|
|
3530
|
-
this.
|
|
3531
|
-
this.
|
|
3384
|
+
if (this.ia !== null) {
|
|
3385
|
+
this.ia.endDecoding();
|
|
3386
|
+
this.ia = null;
|
|
3532
3387
|
}
|
|
3533
|
-
return this.
|
|
3388
|
+
return this.rc(this.Mb);
|
|
3534
3389
|
}
|
|
3535
3390
|
// The parse phase of the integer decode: prediction scheme, portable
|
|
3536
3391
|
// attribute, the symbol stream (raw streams are deferred to the finish
|
|
3537
3392
|
// phase) and the prediction data.
|
|
3538
3393
|
decodeValues(pointIds, buffer) {
|
|
3539
|
-
this.
|
|
3540
|
-
|
|
3394
|
+
this.Mb = pointIds;
|
|
3395
|
+
let predictionSchemeMethod = buffer.decodeUint8();
|
|
3396
|
+
if (predictionSchemeMethod !== void 0) predictionSchemeMethod = predictionSchemeMethod << 24 >> 24;
|
|
3541
3397
|
if (predictionSchemeMethod === void 0) return false;
|
|
3542
|
-
if (predictionSchemeMethod <
|
|
3398
|
+
if (predictionSchemeMethod < -2 /* PREDICTION_NONE */ || predictionSchemeMethod >= 7 /* NUM_PREDICTION_SCHEMES */) {
|
|
3543
3399
|
return false;
|
|
3544
3400
|
}
|
|
3545
|
-
if (predictionSchemeMethod !==
|
|
3546
|
-
|
|
3401
|
+
if (predictionSchemeMethod !== -2 /* PREDICTION_NONE */) {
|
|
3402
|
+
let predictionTransformType = buffer.decodeUint8();
|
|
3403
|
+
if (predictionTransformType !== void 0) predictionTransformType = predictionTransformType << 24 >> 24;
|
|
3547
3404
|
if (predictionTransformType === void 0) return false;
|
|
3548
|
-
if (predictionTransformType <
|
|
3405
|
+
if (predictionTransformType < -1 /* PREDICTION_TRANSFORM_NONE */ || predictionTransformType >= 4 /* NUM_PREDICTION_SCHEME_TRANSFORM_TYPES */) {
|
|
3549
3406
|
return false;
|
|
3550
3407
|
}
|
|
3551
|
-
this.
|
|
3408
|
+
this.ha = this.createIntPredictionScheme(predictionSchemeMethod, predictionTransformType);
|
|
3552
3409
|
}
|
|
3553
|
-
if (this.
|
|
3554
|
-
if (!this.initPredictionScheme(this.
|
|
3410
|
+
if (this.ha) {
|
|
3411
|
+
if (!this.initPredictionScheme(this.ha)) {
|
|
3555
3412
|
return false;
|
|
3556
3413
|
}
|
|
3557
3414
|
}
|
|
@@ -3562,7 +3419,7 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
|
|
|
3562
3419
|
const numEntries = pointIds.length;
|
|
3563
3420
|
const numValues = numEntries * numComponents;
|
|
3564
3421
|
this.preparePortableAttribute(numEntries, numComponents);
|
|
3565
|
-
const portableAttributeData = this.
|
|
3422
|
+
const portableAttributeData = this.V;
|
|
3566
3423
|
if (portableAttributeData === null) {
|
|
3567
3424
|
return false;
|
|
3568
3425
|
}
|
|
@@ -3571,14 +3428,14 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
|
|
|
3571
3428
|
if (compressed > 0) {
|
|
3572
3429
|
if (numValues > 0) {
|
|
3573
3430
|
const scheme = buffer.decodeUint8();
|
|
3574
|
-
if (scheme ===
|
|
3431
|
+
if (scheme === 1 /* SYMBOL_CODING_RAW */) {
|
|
3575
3432
|
const decoder = parseRawSymbolStream(numValues, buffer);
|
|
3576
3433
|
if (decoder === null) {
|
|
3577
3434
|
return false;
|
|
3578
3435
|
}
|
|
3579
|
-
this.
|
|
3580
|
-
this.
|
|
3581
|
-
} else if (scheme ===
|
|
3436
|
+
this.ia = decoder;
|
|
3437
|
+
this.hb = numValues;
|
|
3438
|
+
} else if (scheme === 0 /* SYMBOL_CODING_TAGGED */) {
|
|
3582
3439
|
const outUint32 = new Uint32Array(portableAttributeData.buffer, portableAttributeData.byteOffset, numValues);
|
|
3583
3440
|
if (!decodeTaggedSymbols(numValues, numComponents, buffer, outUint32)) {
|
|
3584
3441
|
return false;
|
|
@@ -3601,25 +3458,25 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
|
|
|
3601
3458
|
portableAttributeData[i] = val;
|
|
3602
3459
|
}
|
|
3603
3460
|
}
|
|
3604
|
-
if (this.
|
|
3605
|
-
if (!this.
|
|
3461
|
+
if (this.ha) {
|
|
3462
|
+
if (!this.ha.decodePredictionData(buffer)) {
|
|
3606
3463
|
return false;
|
|
3607
3464
|
}
|
|
3608
3465
|
}
|
|
3609
3466
|
return true;
|
|
3610
3467
|
}
|
|
3611
3468
|
// The post-symbol tail of the decode: zigzag unpacking and prediction.
|
|
3612
|
-
|
|
3469
|
+
rc(pointIds) {
|
|
3613
3470
|
const numComponents = this.getNumValueComponents();
|
|
3614
3471
|
const numValues = pointIds.length * numComponents;
|
|
3615
|
-
const data = this.
|
|
3472
|
+
const data = this.V;
|
|
3616
3473
|
if (data === null) {
|
|
3617
3474
|
return false;
|
|
3618
3475
|
}
|
|
3619
3476
|
if (numValues === 0) {
|
|
3620
3477
|
return true;
|
|
3621
3478
|
}
|
|
3622
|
-
const ps = this.
|
|
3479
|
+
const ps = this.ha;
|
|
3623
3480
|
if (ps === null) {
|
|
3624
3481
|
convertSymbolsToSignedInts(new Uint32Array(data.buffer, data.byteOffset, numValues), numValues, data);
|
|
3625
3482
|
return true;
|
|
@@ -3634,11 +3491,11 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
|
|
|
3634
3491
|
return ps.computeOriginalValues(data, data, numValues, numComponents, pointIds);
|
|
3635
3492
|
}
|
|
3636
3493
|
transformAttributeToOriginalFormat(pointIds) {
|
|
3637
|
-
return this.
|
|
3494
|
+
return this.ib(pointIds.length);
|
|
3638
3495
|
}
|
|
3639
3496
|
// Prediction scheme for decoding integer values; subclasses override for others.
|
|
3640
3497
|
createIntPredictionScheme(method, transformType) {
|
|
3641
|
-
if (transformType !==
|
|
3498
|
+
if (transformType !== 1 /* PREDICTION_TRANSFORM_WRAP */) {
|
|
3642
3499
|
return null;
|
|
3643
3500
|
}
|
|
3644
3501
|
const transform = new PredictionSchemeWrapDecodingTransform();
|
|
@@ -3647,19 +3504,21 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
|
|
|
3647
3504
|
getNumValueComponents() {
|
|
3648
3505
|
return this.attribute.numComponents;
|
|
3649
3506
|
}
|
|
3650
|
-
//
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3507
|
+
// The decoded values stay in the portable attribute; the final attribute
|
|
3508
|
+
// only takes its size (see PointAttribute.setLazyInteger and the overrides
|
|
3509
|
+
// in the quantization / normal decoders).
|
|
3510
|
+
Jb(numValues) {
|
|
3511
|
+
this.attribute.resetLazy(numValues);
|
|
3512
|
+
return true;
|
|
3513
|
+
}
|
|
3514
|
+
// Hands the decoded integer values to the attribute, converted to its
|
|
3515
|
+
// integer type on extraction.
|
|
3516
|
+
ib(_numValues) {
|
|
3517
|
+
const dt = this.attribute.dataType;
|
|
3518
|
+
if (dt < 1 /* INT8 */ || dt > 6 /* UINT32 */) {
|
|
3656
3519
|
return false;
|
|
3657
3520
|
}
|
|
3658
|
-
|
|
3659
|
-
if (total > 0) {
|
|
3660
|
-
const dstData = attribute.buffer.data;
|
|
3661
|
-
new IntArray(dstData.buffer, dstData.byteOffset + attribute.byteOffset, total).set(this.ta);
|
|
3662
|
-
}
|
|
3521
|
+
this.attribute.setLazyInteger(this.V);
|
|
3663
3522
|
return true;
|
|
3664
3523
|
}
|
|
3665
3524
|
preparePortableAttribute(numEntries, numComponents) {
|
|
@@ -3668,107 +3527,18 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
|
|
|
3668
3527
|
this.attribute.attributeType,
|
|
3669
3528
|
null,
|
|
3670
3529
|
numComponents,
|
|
3671
|
-
|
|
3530
|
+
5 /* INT32 */,
|
|
3672
3531
|
false,
|
|
3673
|
-
numComponents * dataTypeLength(
|
|
3532
|
+
numComponents * dataTypeLength(5 /* INT32 */),
|
|
3674
3533
|
0
|
|
3675
3534
|
);
|
|
3676
3535
|
const portAtt = new PointAttribute(ga);
|
|
3677
3536
|
portAtt.setIdentityMapping();
|
|
3678
|
-
portAtt.
|
|
3537
|
+
portAtt.reset(numEntries);
|
|
3679
3538
|
portAtt.uniqueId = this.attribute.uniqueId;
|
|
3680
|
-
this.
|
|
3539
|
+
this.ea = portAtt;
|
|
3681
3540
|
const data = portAtt.buffer.data;
|
|
3682
|
-
this.
|
|
3683
|
-
}
|
|
3684
|
-
};
|
|
3685
|
-
|
|
3686
|
-
// src/decoder/attributes/AttributeTransformType.ts
|
|
3687
|
-
var AttributeTransformType = {
|
|
3688
|
-
INVALID: -1,
|
|
3689
|
-
NO_TRANSFORM: 0,
|
|
3690
|
-
QUANTIZATION_TRANSFORM: 1,
|
|
3691
|
-
OCTAHEDRON_TRANSFORM: 2
|
|
3692
|
-
};
|
|
3693
|
-
|
|
3694
|
-
// src/decoder/attributes/AttributeTransformData.ts
|
|
3695
|
-
var AttributeTransformData = class {
|
|
3696
|
-
transformType = AttributeTransformType.INVALID;
|
|
3697
|
-
_b = [];
|
|
3698
|
-
$b = [];
|
|
3699
|
-
appendParameterValue(value, type) {
|
|
3700
|
-
this._b.push(value);
|
|
3701
|
-
this.$b.push(type);
|
|
3702
|
-
}
|
|
3703
|
-
};
|
|
3704
|
-
|
|
3705
|
-
// src/decoder/attributes/AttributeTransform.ts
|
|
3706
|
-
var AttributeTransform = class {
|
|
3707
|
-
transferToAttribute(attribute) {
|
|
3708
|
-
const transformData = new AttributeTransformData();
|
|
3709
|
-
this.copyToAttributeTransformData(transformData);
|
|
3710
|
-
attribute.setAttributeTransformData(transformData);
|
|
3711
|
-
return true;
|
|
3712
|
-
}
|
|
3713
|
-
};
|
|
3714
|
-
|
|
3715
|
-
// src/decoder/attributes/AttributeOctahedronTransform.ts
|
|
3716
|
-
var AttributeOctahedronTransform = class extends AttributeTransform {
|
|
3717
|
-
A = -1;
|
|
3718
|
-
copyToAttributeTransformData(outData) {
|
|
3719
|
-
outData.transformType = AttributeTransformType.OCTAHEDRON_TRANSFORM;
|
|
3720
|
-
outData.appendParameterValue(this.A, "int32");
|
|
3721
|
-
}
|
|
3722
|
-
decodeParameters(attribute, decoderBuffer) {
|
|
3723
|
-
const qBits = decoderBuffer.decodeUint8();
|
|
3724
|
-
if (qBits === void 0) return false;
|
|
3725
|
-
this.A = qBits;
|
|
3726
|
-
return true;
|
|
3727
|
-
}
|
|
3728
|
-
inverseTransformAttribute(attribute, targetAttribute) {
|
|
3729
|
-
if (targetAttribute.dataType !== DataType.FLOAT32) {
|
|
3730
|
-
return false;
|
|
3731
|
-
}
|
|
3732
|
-
const numPoints = targetAttribute.size;
|
|
3733
|
-
const numComponents = targetAttribute.numComponents;
|
|
3734
|
-
if (numComponents !== 3) {
|
|
3735
|
-
return false;
|
|
3736
|
-
}
|
|
3737
|
-
const toolBox = new OctahedronToolBox();
|
|
3738
|
-
if (!toolBox.setQuantizationBits(this.A)) {
|
|
3739
|
-
return false;
|
|
3740
|
-
}
|
|
3741
|
-
const srcData = attribute.buffer.data;
|
|
3742
|
-
const srcI32 = new Int32Array(srcData.buffer, srcData.byteOffset + attribute.byteOffset, numPoints * 2);
|
|
3743
|
-
const dstData = targetAttribute.buffer.data;
|
|
3744
|
-
const dstF32 = new Float32Array(dstData.buffer, dstData.byteOffset + targetAttribute.byteOffset, numPoints * 3);
|
|
3745
|
-
const fround = Math.fround;
|
|
3746
|
-
const scale = toolBox.tb;
|
|
3747
|
-
let si = 0;
|
|
3748
|
-
let di = 0;
|
|
3749
|
-
for (let i = 0; i < numPoints; i++) {
|
|
3750
|
-
let y = fround(fround(fround(srcI32[si]) * scale) - 1);
|
|
3751
|
-
let z = fround(fround(fround(srcI32[si + 1]) * scale) - 1);
|
|
3752
|
-
si += 2;
|
|
3753
|
-
const x = fround(fround(1 - Math.abs(y)) - Math.abs(z));
|
|
3754
|
-
let xOffset = -x;
|
|
3755
|
-
if (xOffset < 0) xOffset = 0;
|
|
3756
|
-
y = fround(y + (y < 0 ? xOffset : -xOffset));
|
|
3757
|
-
z = fround(z + (z < 0 ? xOffset : -xOffset));
|
|
3758
|
-
const normSquared = fround(fround(fround(x * x) + fround(y * y)) + fround(z * z));
|
|
3759
|
-
if (normSquared < 1e-6) {
|
|
3760
|
-
dstF32[di] = 0;
|
|
3761
|
-
dstF32[di + 1] = 0;
|
|
3762
|
-
dstF32[di + 2] = 0;
|
|
3763
|
-
} else {
|
|
3764
|
-
const d = fround(1 / fround(Math.sqrt(normSquared)));
|
|
3765
|
-
dstF32[di] = fround(x * d);
|
|
3766
|
-
dstF32[di + 1] = fround(y * d);
|
|
3767
|
-
dstF32[di + 2] = fround(z * d);
|
|
3768
|
-
}
|
|
3769
|
-
di += 3;
|
|
3770
|
-
}
|
|
3771
|
-
return true;
|
|
3541
|
+
this.V = numEntries === 0 ? null : new Int32Array(data.buffer, data.byteOffset + portAtt.byteOffset, numEntries * numComponents);
|
|
3772
3542
|
}
|
|
3773
3543
|
};
|
|
3774
3544
|
|
|
@@ -3784,7 +3554,7 @@ var PredictionSchemeNormalOctahedronTransformBase = class {
|
|
|
3784
3554
|
quantizationBits() {
|
|
3785
3555
|
return this.B.quantizationBits();
|
|
3786
3556
|
}
|
|
3787
|
-
|
|
3557
|
+
Nb(maxQuantizedValue) {
|
|
3788
3558
|
if (maxQuantizedValue % 2 === 0) return false;
|
|
3789
3559
|
let q = 0;
|
|
3790
3560
|
let v = maxQuantizedValue;
|
|
@@ -3799,21 +3569,21 @@ var PredictionSchemeNormalOctahedronTransformBase = class {
|
|
|
3799
3569
|
// src/decoder/compression/attributes/prediction_schemes/PredictionSchemeNormalOctahedronCanonicalizedDecodingTransform.ts
|
|
3800
3570
|
var PredictionSchemeNormalOctahedronCanonicalizedDecodingTransform = class extends PredictionSchemeNormalOctahedronTransformBase {
|
|
3801
3571
|
getType() {
|
|
3802
|
-
return
|
|
3572
|
+
return 3 /* PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON_CANONICALIZED */;
|
|
3803
3573
|
}
|
|
3804
3574
|
decodeTransformData(buffer) {
|
|
3805
3575
|
const maxQuantizedValue = buffer.decodeInt32();
|
|
3806
3576
|
if (maxQuantizedValue === void 0) return false;
|
|
3807
3577
|
const centerValue = buffer.decodeInt32();
|
|
3808
3578
|
if (centerValue === void 0) return false;
|
|
3809
|
-
if (!this.
|
|
3579
|
+
if (!this.Nb(maxQuantizedValue)) return false;
|
|
3810
3580
|
const q = this.B.quantizationBits();
|
|
3811
3581
|
return q >= 2 && q <= 30;
|
|
3812
3582
|
}
|
|
3813
3583
|
computeOriginalValue(predVals, predOffset, corrVals, corrOffset, outOrigVals, outOffset) {
|
|
3814
3584
|
const toolBox = this.B;
|
|
3815
3585
|
const center = toolBox.f;
|
|
3816
|
-
const maxQuantizedValue = toolBox.
|
|
3586
|
+
const maxQuantizedValue = toolBox.xa;
|
|
3817
3587
|
const corrS = corrVals[corrOffset];
|
|
3818
3588
|
const corrT = corrVals[corrOffset + 1];
|
|
3819
3589
|
let predS = predVals[predOffset] - center;
|
|
@@ -3941,7 +3711,7 @@ var PredictionSchemeNormalOctahedronCanonicalizedDecodingTransform = class exten
|
|
|
3941
3711
|
computeOriginalValuesDelta(inCorr, outData, size, numComponents) {
|
|
3942
3712
|
const toolBox = this.B;
|
|
3943
3713
|
const center = toolBox.f;
|
|
3944
|
-
const maxQuantizedValue = toolBox.
|
|
3714
|
+
const maxQuantizedValue = toolBox.xa;
|
|
3945
3715
|
let prevS = 0;
|
|
3946
3716
|
let prevT = 0;
|
|
3947
3717
|
for (let i = 0; i < size; i += numComponents) {
|
|
@@ -4070,17 +3840,17 @@ var PredictionSchemeNormalOctahedronCanonicalizedDecodingTransform = class exten
|
|
|
4070
3840
|
// src/decoder/compression/attributes/prediction_schemes/PredictionSchemeNormalOctahedronDecodingTransform.ts
|
|
4071
3841
|
var PredictionSchemeNormalOctahedronDecodingTransform = class extends PredictionSchemeNormalOctahedronTransformBase {
|
|
4072
3842
|
getType() {
|
|
4073
|
-
return
|
|
3843
|
+
return 2 /* PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON */;
|
|
4074
3844
|
}
|
|
4075
3845
|
decodeTransformData(buffer) {
|
|
4076
3846
|
const maxQuantizedValue = buffer.decodeInt32();
|
|
4077
3847
|
if (maxQuantizedValue === void 0) return false;
|
|
4078
|
-
return this.
|
|
3848
|
+
return this.Nb(maxQuantizedValue);
|
|
4079
3849
|
}
|
|
4080
3850
|
computeOriginalValue(predVals, predOffset, corrVals, corrOffset, outOrigVals, outOffset) {
|
|
4081
3851
|
const toolBox = this.B;
|
|
4082
3852
|
const center = toolBox.f;
|
|
4083
|
-
const maxQuantizedValue = toolBox.
|
|
3853
|
+
const maxQuantizedValue = toolBox.xa;
|
|
4084
3854
|
const predS = predVals[predOffset] - center;
|
|
4085
3855
|
const predT = predVals[predOffset + 1] - center;
|
|
4086
3856
|
const corrS = corrVals[corrOffset];
|
|
@@ -4159,28 +3929,34 @@ var PredictionSchemeNormalOctahedronDecodingTransform = class extends Prediction
|
|
|
4159
3929
|
|
|
4160
3930
|
// src/decoder/compression/attributes/SequentialNormalAttributeDecoder.ts
|
|
4161
3931
|
var SequentialNormalAttributeDecoder = class extends SequentialIntegerAttributeDecoder {
|
|
4162
|
-
|
|
3932
|
+
N = -1;
|
|
4163
3933
|
init(decoder, attributeId) {
|
|
4164
3934
|
if (!super.init(decoder, attributeId)) {
|
|
4165
3935
|
return false;
|
|
4166
3936
|
}
|
|
4167
|
-
return this.attribute.numComponents === 3 && this.attribute.dataType ===
|
|
3937
|
+
return this.attribute.numComponents === 3 && this.attribute.dataType === 9 /* FLOAT32 */;
|
|
4168
3938
|
}
|
|
4169
3939
|
// Normals quantize into two octahedral components.
|
|
4170
3940
|
getNumValueComponents() {
|
|
4171
3941
|
return 2;
|
|
4172
3942
|
}
|
|
3943
|
+
// The octahedral quantization bits (AttributeOctahedronTransform::DecodeParameters).
|
|
4173
3944
|
decodeDataNeededByPortableTransform(_pointIds, buffer) {
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
return
|
|
3945
|
+
const qBits = buffer.decodeUint8();
|
|
3946
|
+
if (qBits === void 0) return false;
|
|
3947
|
+
this.N = qBits;
|
|
3948
|
+
return true;
|
|
4178
3949
|
}
|
|
4179
|
-
|
|
4180
|
-
|
|
3950
|
+
// The octahedral-to-unit-vector transform is deferred to extractTo (see
|
|
3951
|
+
// PointAttribute.setLazyOctahedron).
|
|
3952
|
+
ib(_numPoints) {
|
|
3953
|
+
const q = this.N;
|
|
3954
|
+
if (q < 2 || q > 30) return false;
|
|
3955
|
+
this.attribute.setLazyOctahedron(this.V, Math.fround(2 / Math.fround((1 << q) - 2)));
|
|
3956
|
+
return true;
|
|
4181
3957
|
}
|
|
4182
3958
|
createIntPredictionScheme(method, transformType) {
|
|
4183
|
-
const transform = transformType ===
|
|
3959
|
+
const transform = transformType === 2 /* PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON */ ? new PredictionSchemeNormalOctahedronDecodingTransform() : transformType === 3 /* PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON_CANONICALIZED */ ? new PredictionSchemeNormalOctahedronCanonicalizedDecodingTransform() : null;
|
|
4184
3960
|
if (transform === null) {
|
|
4185
3961
|
return null;
|
|
4186
3962
|
}
|
|
@@ -4188,110 +3964,53 @@ var SequentialNormalAttributeDecoder = class extends SequentialIntegerAttributeD
|
|
|
4188
3964
|
}
|
|
4189
3965
|
};
|
|
4190
3966
|
|
|
4191
|
-
// src/decoder/attributes/AttributeQuantizationTransform.ts
|
|
4192
|
-
var AttributeQuantizationTransform = class extends AttributeTransform {
|
|
4193
|
-
A = -1;
|
|
4194
|
-
ua = [];
|
|
4195
|
-
Za = 0;
|
|
4196
|
-
copyToAttributeTransformData(outData) {
|
|
4197
|
-
outData.transformType = AttributeTransformType.QUANTIZATION_TRANSFORM;
|
|
4198
|
-
outData.appendParameterValue(this.A, "int32");
|
|
4199
|
-
for (let i = 0; i < this.ua.length; i++) {
|
|
4200
|
-
outData.appendParameterValue(this.ua[i], "float32");
|
|
4201
|
-
}
|
|
4202
|
-
outData.appendParameterValue(this.Za, "float32");
|
|
4203
|
-
}
|
|
4204
|
-
decodeParameters(attribute, decoderBuffer) {
|
|
4205
|
-
const numComponents = attribute.numComponents;
|
|
4206
|
-
this.ua = new Array(numComponents);
|
|
4207
|
-
for (let i = 0; i < numComponents; i++) {
|
|
4208
|
-
const val = decoderBuffer.decodeFloat32();
|
|
4209
|
-
if (val === void 0) return false;
|
|
4210
|
-
this.ua[i] = val;
|
|
4211
|
-
}
|
|
4212
|
-
const range = decoderBuffer.decodeFloat32();
|
|
4213
|
-
if (range === void 0) return false;
|
|
4214
|
-
this.Za = range;
|
|
4215
|
-
const qBits = decoderBuffer.decodeUint8();
|
|
4216
|
-
if (qBits === void 0 || qBits < 1 || qBits > 30) return false;
|
|
4217
|
-
this.A = qBits;
|
|
4218
|
-
return true;
|
|
4219
|
-
}
|
|
4220
|
-
inverseTransformAttribute(attribute, targetAttribute) {
|
|
4221
|
-
if (targetAttribute.dataType !== DataType.FLOAT32) {
|
|
4222
|
-
return false;
|
|
4223
|
-
}
|
|
4224
|
-
const maxQuantizedValue = (1 << this.A >>> 0) - 1;
|
|
4225
|
-
if (maxQuantizedValue <= 0) return false;
|
|
4226
|
-
const delta = Math.fround(this.Za / Math.fround(maxQuantizedValue));
|
|
4227
|
-
const numComponents = targetAttribute.numComponents;
|
|
4228
|
-
const numValues = targetAttribute.size;
|
|
4229
|
-
const total = numValues * numComponents;
|
|
4230
|
-
const minValues = this.ua;
|
|
4231
|
-
const srcData = attribute.buffer.data;
|
|
4232
|
-
const srcI32 = new Int32Array(srcData.buffer, srcData.byteOffset + attribute.byteOffset, total);
|
|
4233
|
-
const dstData = targetAttribute.buffer.data;
|
|
4234
|
-
const dstF32 = new Float32Array(dstData.buffer, dstData.byteOffset + targetAttribute.byteOffset, total);
|
|
4235
|
-
const fround = Math.fround;
|
|
4236
|
-
if (numComponents === 3) {
|
|
4237
|
-
const m0 = minValues[0], m1 = minValues[1], m2 = minValues[2];
|
|
4238
|
-
for (let o2 = 0; o2 < total; o2 += 3) {
|
|
4239
|
-
dstF32[o2] = fround(fround(srcI32[o2]) * delta) + m0;
|
|
4240
|
-
dstF32[o2 + 1] = fround(fround(srcI32[o2 + 1]) * delta) + m1;
|
|
4241
|
-
dstF32[o2 + 2] = fround(fround(srcI32[o2 + 2]) * delta) + m2;
|
|
4242
|
-
}
|
|
4243
|
-
return true;
|
|
4244
|
-
}
|
|
4245
|
-
if (numComponents === 2) {
|
|
4246
|
-
const m0 = minValues[0], m1 = minValues[1];
|
|
4247
|
-
for (let o2 = 0; o2 < total; o2 += 2) {
|
|
4248
|
-
dstF32[o2] = fround(fround(srcI32[o2]) * delta) + m0;
|
|
4249
|
-
dstF32[o2 + 1] = fround(fround(srcI32[o2 + 1]) * delta) + m1;
|
|
4250
|
-
}
|
|
4251
|
-
return true;
|
|
4252
|
-
}
|
|
4253
|
-
let o = 0;
|
|
4254
|
-
for (let i = 0; i < numValues; i++) {
|
|
4255
|
-
for (let c = 0; c < numComponents; c++) {
|
|
4256
|
-
dstF32[o] = fround(fround(srcI32[o]) * delta) + minValues[c];
|
|
4257
|
-
o++;
|
|
4258
|
-
}
|
|
4259
|
-
}
|
|
4260
|
-
return true;
|
|
4261
|
-
}
|
|
4262
|
-
};
|
|
4263
|
-
|
|
4264
3967
|
// src/decoder/compression/attributes/SequentialQuantizationAttributeDecoder.ts
|
|
4265
3968
|
var SequentialQuantizationAttributeDecoder = class extends SequentialIntegerAttributeDecoder {
|
|
4266
|
-
|
|
3969
|
+
N = -1;
|
|
3970
|
+
jb = [];
|
|
3971
|
+
Ob = 0;
|
|
4267
3972
|
init(decoder, attributeId) {
|
|
4268
3973
|
if (!super.init(decoder, attributeId)) {
|
|
4269
3974
|
return false;
|
|
4270
3975
|
}
|
|
4271
|
-
return this.attribute.dataType ===
|
|
3976
|
+
return this.attribute.dataType === 9 /* FLOAT32 */;
|
|
4272
3977
|
}
|
|
3978
|
+
// The quantization parameters (AttributeQuantizationTransform::DecodeParameters).
|
|
4273
3979
|
decodeDataNeededByPortableTransform(_pointIds, buffer) {
|
|
4274
|
-
const
|
|
4275
|
-
|
|
4276
|
-
|
|
3980
|
+
const numComponents = this.attribute.numComponents;
|
|
3981
|
+
this.jb = new Array(numComponents);
|
|
3982
|
+
for (let i = 0; i < numComponents; i++) {
|
|
3983
|
+
const val = buffer.decodeFloat32();
|
|
3984
|
+
if (val === void 0) return false;
|
|
3985
|
+
this.jb[i] = val;
|
|
4277
3986
|
}
|
|
4278
|
-
|
|
3987
|
+
const range = buffer.decodeFloat32();
|
|
3988
|
+
if (range === void 0) return false;
|
|
3989
|
+
this.Ob = range;
|
|
3990
|
+
const qBits = buffer.decodeUint8();
|
|
3991
|
+
if (qBits === void 0 || qBits < 1 || qBits > 30) return false;
|
|
3992
|
+
this.N = qBits;
|
|
3993
|
+
return true;
|
|
4279
3994
|
}
|
|
4280
|
-
//
|
|
4281
|
-
|
|
4282
|
-
|
|
3995
|
+
// Dequantization is deferred to extractTo (see PointAttribute.setLazyQuantized).
|
|
3996
|
+
ib(_numValues) {
|
|
3997
|
+
const maxQuantizedValue = (1 << this.N >>> 0) - 1;
|
|
3998
|
+
if (maxQuantizedValue <= 0) return false;
|
|
3999
|
+
const delta = Math.fround(this.Ob / Math.fround(maxQuantizedValue));
|
|
4000
|
+
this.attribute.setLazyQuantized(this.V, this.jb, delta);
|
|
4001
|
+
return true;
|
|
4283
4002
|
}
|
|
4284
4003
|
};
|
|
4285
4004
|
|
|
4286
4005
|
// src/decoder/compression/attributes/SequentialAttributeDecodersController.ts
|
|
4287
4006
|
var SequentialAttributeDecodersController = class extends AttributesDecoder {
|
|
4288
|
-
|
|
4007
|
+
Ca = [];
|
|
4289
4008
|
// Replaced by the sequencer's output in _prepareSequence.
|
|
4290
|
-
|
|
4291
|
-
|
|
4009
|
+
Ua = new Int32Array(0);
|
|
4010
|
+
W;
|
|
4292
4011
|
constructor(sequencer) {
|
|
4293
4012
|
super();
|
|
4294
|
-
this.
|
|
4013
|
+
this.W = sequencer;
|
|
4295
4014
|
}
|
|
4296
4015
|
decodeAttributesDecoderData(buffer) {
|
|
4297
4016
|
if (!super.decodeAttributesDecoderData(buffer)) {
|
|
@@ -4305,19 +4024,19 @@ var SequentialAttributeDecodersController = class extends AttributesDecoder {
|
|
|
4305
4024
|
if (decoder === null || !decoder.init(this.getDecoder(), this.getAttributeId(i))) {
|
|
4306
4025
|
return false;
|
|
4307
4026
|
}
|
|
4308
|
-
this.
|
|
4027
|
+
this.Ca[i] = decoder;
|
|
4309
4028
|
}
|
|
4310
4029
|
return true;
|
|
4311
4030
|
}
|
|
4312
|
-
|
|
4313
|
-
if (!this.
|
|
4031
|
+
sc() {
|
|
4032
|
+
if (!this.W.generateSequence()) {
|
|
4314
4033
|
return false;
|
|
4315
4034
|
}
|
|
4316
|
-
this.
|
|
4035
|
+
this.Ua = this.W.getOutputPointIds();
|
|
4317
4036
|
const numAttributes = this.getNumAttributes();
|
|
4318
4037
|
for (let i = 0; i < numAttributes; i++) {
|
|
4319
4038
|
const pa = this.getDecoder().pointCloud().attribute(this.getAttributeId(i));
|
|
4320
|
-
if (!this.
|
|
4039
|
+
if (!this.W.updatePointToAttributeIndexMapping(pa)) {
|
|
4321
4040
|
return false;
|
|
4322
4041
|
}
|
|
4323
4042
|
}
|
|
@@ -4331,24 +4050,24 @@ var SequentialAttributeDecodersController = class extends AttributesDecoder {
|
|
|
4331
4050
|
// of the finish work reads the buffer, and dependents only read parent
|
|
4332
4051
|
// portable VALUES in finish, so ordering and output stay identical.
|
|
4333
4052
|
decodeAttributesParse(buffer) {
|
|
4334
|
-
if (!this.
|
|
4053
|
+
if (!this.sc()) {
|
|
4335
4054
|
return false;
|
|
4336
4055
|
}
|
|
4337
|
-
const decoders = this.
|
|
4056
|
+
const decoders = this.Ca;
|
|
4338
4057
|
for (let i = 0; i < decoders.length; i++) {
|
|
4339
|
-
if (!decoders[i].decodePortableAttributeParse(this.
|
|
4058
|
+
if (!decoders[i].decodePortableAttributeParse(this.Ua, buffer)) {
|
|
4340
4059
|
return false;
|
|
4341
4060
|
}
|
|
4342
4061
|
}
|
|
4343
4062
|
for (let i = 0; i < decoders.length; i++) {
|
|
4344
|
-
if (!decoders[i].decodeDataNeededByPortableTransform(this.
|
|
4063
|
+
if (!decoders[i].decodeDataNeededByPortableTransform(this.Ua, buffer)) {
|
|
4345
4064
|
return false;
|
|
4346
4065
|
}
|
|
4347
4066
|
}
|
|
4348
4067
|
return true;
|
|
4349
4068
|
}
|
|
4350
4069
|
collectPendingSymbolStreams(out) {
|
|
4351
|
-
const decoders = this.
|
|
4070
|
+
const decoders = this.Ca;
|
|
4352
4071
|
for (let i = 0; i < decoders.length; i++) {
|
|
4353
4072
|
const pending = decoders[i].pendingSymbolStream();
|
|
4354
4073
|
if (pending !== null) {
|
|
@@ -4357,14 +4076,14 @@ var SequentialAttributeDecodersController = class extends AttributesDecoder {
|
|
|
4357
4076
|
}
|
|
4358
4077
|
}
|
|
4359
4078
|
decodeAttributesFinish() {
|
|
4360
|
-
const decoders = this.
|
|
4079
|
+
const decoders = this.Ca;
|
|
4361
4080
|
for (let i = 0; i < decoders.length; i++) {
|
|
4362
4081
|
if (!decoders[i].decodePortableAttributeFinish()) {
|
|
4363
4082
|
return false;
|
|
4364
4083
|
}
|
|
4365
4084
|
}
|
|
4366
4085
|
for (let i = 0; i < decoders.length; i++) {
|
|
4367
|
-
if (!decoders[i].transformAttributeToOriginalFormat(this.
|
|
4086
|
+
if (!decoders[i].transformAttributeToOriginalFormat(this.Ua)) {
|
|
4368
4087
|
return false;
|
|
4369
4088
|
}
|
|
4370
4089
|
}
|
|
@@ -4375,17 +4094,17 @@ var SequentialAttributeDecodersController = class extends AttributesDecoder {
|
|
|
4375
4094
|
if (locId < 0) {
|
|
4376
4095
|
return null;
|
|
4377
4096
|
}
|
|
4378
|
-
return this.
|
|
4097
|
+
return this.Ca[locId].getPortableAttribute();
|
|
4379
4098
|
}
|
|
4380
4099
|
createSequentialDecoder(decoderType) {
|
|
4381
4100
|
switch (decoderType) {
|
|
4382
|
-
case
|
|
4101
|
+
case 0 /* SEQUENTIAL_ATTRIBUTE_ENCODER_GENERIC */:
|
|
4383
4102
|
return new SequentialAttributeDecoder();
|
|
4384
|
-
case
|
|
4103
|
+
case 1 /* SEQUENTIAL_ATTRIBUTE_ENCODER_INTEGER */:
|
|
4385
4104
|
return new SequentialIntegerAttributeDecoder();
|
|
4386
|
-
case
|
|
4105
|
+
case 2 /* SEQUENTIAL_ATTRIBUTE_ENCODER_QUANTIZATION */:
|
|
4387
4106
|
return new SequentialQuantizationAttributeDecoder();
|
|
4388
|
-
case
|
|
4107
|
+
case 3 /* SEQUENTIAL_ATTRIBUTE_ENCODER_NORMALS */:
|
|
4389
4108
|
return new SequentialNormalAttributeDecoder();
|
|
4390
4109
|
}
|
|
4391
4110
|
return null;
|
|
@@ -4414,27 +4133,27 @@ var kInvalidFaceIndex = -1;
|
|
|
4414
4133
|
var kInvalidVertexIndex2 = -1;
|
|
4415
4134
|
var DepthFirstTraverser = class {
|
|
4416
4135
|
a = null;
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4136
|
+
Da = null;
|
|
4137
|
+
X = null;
|
|
4138
|
+
Pb = [];
|
|
4139
|
+
ja = 0;
|
|
4421
4140
|
// Identifies the traversal order for the shared traversal cache
|
|
4422
4141
|
// (MESH_TRAVERSAL_DEPTH_FIRST). See MeshTraversalSequencer.
|
|
4423
|
-
|
|
4142
|
+
Qb = 0;
|
|
4424
4143
|
// The sequencer derives the point id sequence from the corner map after
|
|
4425
4144
|
// the traversal (see traverseFromCorner).
|
|
4426
4145
|
emitsPointIds = false;
|
|
4427
4146
|
j = null;
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4147
|
+
s = null;
|
|
4148
|
+
Rb = null;
|
|
4149
|
+
J = 0;
|
|
4431
4150
|
init(cornerTable, observer) {
|
|
4432
4151
|
this.a = cornerTable;
|
|
4433
|
-
this.
|
|
4152
|
+
this.Da = observer;
|
|
4434
4153
|
this.j = cornerTable.cornerToVertexArray();
|
|
4435
|
-
this.
|
|
4436
|
-
this.
|
|
4437
|
-
this.
|
|
4154
|
+
this.s = cornerTable.oppositeCornerArray();
|
|
4155
|
+
this.Rb = cornerTable.vertexLeftmostCornerArray();
|
|
4156
|
+
this.J = cornerTable.numCorners();
|
|
4438
4157
|
}
|
|
4439
4158
|
cornerTable() {
|
|
4440
4159
|
return this.a;
|
|
@@ -4448,8 +4167,8 @@ var DepthFirstTraverser = class {
|
|
|
4448
4167
|
// Decode-scoped scratch: released in bulk at the end of the decode.
|
|
4449
4168
|
onTraversalStart() {
|
|
4450
4169
|
const cornerTable = this.a;
|
|
4451
|
-
this.
|
|
4452
|
-
this.
|
|
4170
|
+
this.X = scratchUint8Zeroed(cornerTable.numFaces());
|
|
4171
|
+
this.Pb = scratchInt32(this.J);
|
|
4453
4172
|
}
|
|
4454
4173
|
// Traverses every face, seeding a new traversal at the first corner of each
|
|
4455
4174
|
// face not yet reached. The visited check lives here rather than behind a
|
|
@@ -4458,8 +4177,8 @@ var DepthFirstTraverser = class {
|
|
|
4458
4177
|
// was measurable next to the traversal itself.
|
|
4459
4178
|
traverseAll() {
|
|
4460
4179
|
const numFaces = this.a.numFaces();
|
|
4461
|
-
const isFaceVisited = this.
|
|
4462
|
-
for (let f = 0; f < numFaces && this.
|
|
4180
|
+
const isFaceVisited = this.X;
|
|
4181
|
+
for (let f = 0; f < numFaces && this.ja < numFaces; ++f) {
|
|
4463
4182
|
if (isFaceVisited[f] === 0 && !this.traverseFromCorner(3 * f)) {
|
|
4464
4183
|
return false;
|
|
4465
4184
|
}
|
|
@@ -4467,19 +4186,19 @@ var DepthFirstTraverser = class {
|
|
|
4467
4186
|
return true;
|
|
4468
4187
|
}
|
|
4469
4188
|
traverseFromCorner(cornerId) {
|
|
4470
|
-
if (this.
|
|
4189
|
+
if (this.X[cornerId / 3 | 0]) {
|
|
4471
4190
|
return true;
|
|
4472
4191
|
}
|
|
4473
|
-
const isFaceVisited = this.
|
|
4474
|
-
const observer = this.
|
|
4192
|
+
const isFaceVisited = this.X;
|
|
4193
|
+
const observer = this.Da;
|
|
4475
4194
|
const cornerToVertex = this.j;
|
|
4476
|
-
const oppositeCorners = this.
|
|
4477
|
-
const vertexLeftmost = this.
|
|
4478
|
-
const stack = this.
|
|
4479
|
-
let numVisitedFaces = this.
|
|
4195
|
+
const oppositeCorners = this.s;
|
|
4196
|
+
const vertexLeftmost = this.Rb;
|
|
4197
|
+
const stack = this.Pb;
|
|
4198
|
+
let numVisitedFaces = this.ja;
|
|
4480
4199
|
const encodingData = observer.C;
|
|
4481
|
-
const encodedToCornerMap = observer
|
|
4482
|
-
const vertexToEncodedMap = observer.
|
|
4200
|
+
const encodedToCornerMap = observer.kb;
|
|
4201
|
+
const vertexToEncodedMap = observer.lb;
|
|
4483
4202
|
let numValues = encodingData.numValues;
|
|
4484
4203
|
let stackSize = 0;
|
|
4485
4204
|
stack[stackSize++] = cornerId;
|
|
@@ -4557,7 +4276,7 @@ var DepthFirstTraverser = class {
|
|
|
4557
4276
|
}
|
|
4558
4277
|
}
|
|
4559
4278
|
}
|
|
4560
|
-
this.
|
|
4279
|
+
this.ja = numVisitedFaces;
|
|
4561
4280
|
encodingData.numValues = numValues;
|
|
4562
4281
|
return true;
|
|
4563
4282
|
}
|
|
@@ -4569,51 +4288,51 @@ var kInvalidFaceIndex2 = -1;
|
|
|
4569
4288
|
var kMaxPriority = 3;
|
|
4570
4289
|
var MaxPredictionDegreeTraverser = class {
|
|
4571
4290
|
a = null;
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4291
|
+
Da = null;
|
|
4292
|
+
X = null;
|
|
4293
|
+
mb = null;
|
|
4294
|
+
ja = 0;
|
|
4576
4295
|
// One stack (bucket) per priority level [0, kMaxPriority).
|
|
4577
|
-
|
|
4578
|
-
|
|
4296
|
+
Va = null;
|
|
4297
|
+
Y = 0;
|
|
4579
4298
|
// Prediction degree accumulated per vertex during traversal.
|
|
4580
|
-
|
|
4299
|
+
nb = null;
|
|
4581
4300
|
// Flat connectivity arrays (see DepthFirstTraverser for why).
|
|
4582
4301
|
j = null;
|
|
4583
|
-
|
|
4302
|
+
s = null;
|
|
4584
4303
|
// Identifies the traversal order for the shared traversal cache
|
|
4585
4304
|
// (MESH_TRAVERSAL_PREDICTION_DEGREE). See MeshTraversalSequencer.
|
|
4586
|
-
|
|
4305
|
+
Qb = 1;
|
|
4587
4306
|
// Point ids are appended through the observer as vertices are visited.
|
|
4588
4307
|
emitsPointIds = true;
|
|
4589
4308
|
init(cornerTable, observer) {
|
|
4590
4309
|
this.a = cornerTable;
|
|
4591
|
-
this.
|
|
4592
|
-
this.
|
|
4593
|
-
this.
|
|
4310
|
+
this.Da = observer;
|
|
4311
|
+
this.X = new Uint8Array(cornerTable.numFaces());
|
|
4312
|
+
this.mb = new Uint8Array(cornerTable.numVertices());
|
|
4594
4313
|
this.j = cornerTable.cornerToVertexArray();
|
|
4595
|
-
this.
|
|
4596
|
-
this.
|
|
4314
|
+
this.s = cornerTable.oppositeCornerArray();
|
|
4315
|
+
this.Va = [[], [], []];
|
|
4597
4316
|
}
|
|
4598
4317
|
cornerTable() {
|
|
4599
4318
|
return this.a;
|
|
4600
4319
|
}
|
|
4601
4320
|
// corner is always valid (>= 0) where these are used.
|
|
4602
|
-
|
|
4321
|
+
Sb(c) {
|
|
4603
4322
|
return c % 3 === 2 ? c - 2 : c + 1;
|
|
4604
4323
|
}
|
|
4605
|
-
|
|
4324
|
+
Tb(c) {
|
|
4606
4325
|
return c % 3 === 0 ? c + 2 : c - 1;
|
|
4607
4326
|
}
|
|
4608
4327
|
onTraversalStart() {
|
|
4609
|
-
this.
|
|
4328
|
+
this.nb = new Int32Array(this.a.numVertices());
|
|
4610
4329
|
}
|
|
4611
4330
|
// Same contract as DepthFirstTraverser.traverseAll. Seeds every face
|
|
4612
4331
|
// through traverseFromCorner (which re-checks the first face's vertices),
|
|
4613
4332
|
// exactly as the sequencer's loop always has.
|
|
4614
4333
|
traverseAll() {
|
|
4615
4334
|
const numFaces = this.a.numFaces();
|
|
4616
|
-
for (let f = 0; f < numFaces && this.
|
|
4335
|
+
for (let f = 0; f < numFaces && this.ja < numFaces; ++f) {
|
|
4617
4336
|
if (!this.traverseFromCorner(3 * f)) {
|
|
4618
4337
|
return false;
|
|
4619
4338
|
}
|
|
@@ -4622,11 +4341,11 @@ var MaxPredictionDegreeTraverser = class {
|
|
|
4622
4341
|
}
|
|
4623
4342
|
// Returns the priority of traversing the edge leading to cornerId. Mutates
|
|
4624
4343
|
// the prediction degree of the destination vertex.
|
|
4625
|
-
|
|
4344
|
+
Ub(cornerId) {
|
|
4626
4345
|
const vTip = this.j[cornerId];
|
|
4627
4346
|
let priority = 0;
|
|
4628
|
-
if (!this.
|
|
4629
|
-
const degree = ++this.
|
|
4347
|
+
if (!this.mb[vTip]) {
|
|
4348
|
+
const degree = ++this.nb[vTip];
|
|
4630
4349
|
priority = degree > 1 ? 1 : 2;
|
|
4631
4350
|
}
|
|
4632
4351
|
if (priority >= kMaxPriority) {
|
|
@@ -4634,38 +4353,38 @@ var MaxPredictionDegreeTraverser = class {
|
|
|
4634
4353
|
}
|
|
4635
4354
|
return priority;
|
|
4636
4355
|
}
|
|
4637
|
-
|
|
4638
|
-
this.
|
|
4639
|
-
if (priority < this.
|
|
4640
|
-
this.
|
|
4356
|
+
Vb(ci, priority) {
|
|
4357
|
+
this.Va[priority].push(ci);
|
|
4358
|
+
if (priority < this.Y) {
|
|
4359
|
+
this.Y = priority;
|
|
4641
4360
|
}
|
|
4642
4361
|
}
|
|
4643
4362
|
// Retrieves the next available corner to traverse, processed by priority.
|
|
4644
4363
|
// Returns kInvalidCornerIndex when no corner is available.
|
|
4645
|
-
|
|
4646
|
-
for (let i = this.
|
|
4647
|
-
const stack = this.
|
|
4364
|
+
tc() {
|
|
4365
|
+
for (let i = this.Y; i < kMaxPriority; ++i) {
|
|
4366
|
+
const stack = this.Va[i];
|
|
4648
4367
|
if (stack.length > 0) {
|
|
4649
4368
|
const ret = stack.pop();
|
|
4650
|
-
this.
|
|
4369
|
+
this.Y = i;
|
|
4651
4370
|
return ret;
|
|
4652
4371
|
}
|
|
4653
4372
|
}
|
|
4654
4373
|
return kInvalidCornerIndex5;
|
|
4655
4374
|
}
|
|
4656
4375
|
traverseFromCorner(cornerId) {
|
|
4657
|
-
if (this.
|
|
4376
|
+
if (this.nb.length === 0) {
|
|
4658
4377
|
return true;
|
|
4659
4378
|
}
|
|
4660
4379
|
const cornerToVertex = this.j;
|
|
4661
|
-
const oppositeCorners = this.
|
|
4662
|
-
const isFaceVisited = this.
|
|
4663
|
-
const isVertexVisited = this.
|
|
4664
|
-
const observer = this.
|
|
4665
|
-
this.
|
|
4666
|
-
this.
|
|
4667
|
-
const firstNext = this.
|
|
4668
|
-
const firstPrev = this.
|
|
4380
|
+
const oppositeCorners = this.s;
|
|
4381
|
+
const isFaceVisited = this.X;
|
|
4382
|
+
const isVertexVisited = this.mb;
|
|
4383
|
+
const observer = this.Da;
|
|
4384
|
+
this.Va[0].push(cornerId);
|
|
4385
|
+
this.Y = 0;
|
|
4386
|
+
const firstNext = this.Sb(cornerId);
|
|
4387
|
+
const firstPrev = this.Tb(cornerId);
|
|
4669
4388
|
const nextVert = cornerToVertex[firstNext];
|
|
4670
4389
|
const prevVert = cornerToVertex[firstPrev];
|
|
4671
4390
|
if (!isVertexVisited[nextVert]) {
|
|
@@ -4681,7 +4400,7 @@ var MaxPredictionDegreeTraverser = class {
|
|
|
4681
4400
|
isVertexVisited[tipVertex] = 1;
|
|
4682
4401
|
observer.onNewVertexVisited(tipVertex, cornerId);
|
|
4683
4402
|
}
|
|
4684
|
-
while ((cornerId = this.
|
|
4403
|
+
while ((cornerId = this.tc()) !== kInvalidCornerIndex5) {
|
|
4685
4404
|
let faceId = cornerId / 3 | 0;
|
|
4686
4405
|
if (isFaceVisited[faceId]) {
|
|
4687
4406
|
continue;
|
|
@@ -4689,34 +4408,34 @@ var MaxPredictionDegreeTraverser = class {
|
|
|
4689
4408
|
while (true) {
|
|
4690
4409
|
faceId = cornerId / 3 | 0;
|
|
4691
4410
|
isFaceVisited[faceId] = 1;
|
|
4692
|
-
this.
|
|
4411
|
+
this.ja++;
|
|
4693
4412
|
const vertId = cornerToVertex[cornerId];
|
|
4694
4413
|
if (!isVertexVisited[vertId]) {
|
|
4695
4414
|
isVertexVisited[vertId] = 1;
|
|
4696
4415
|
observer.onNewVertexVisited(vertId, cornerId);
|
|
4697
4416
|
}
|
|
4698
|
-
const rightCornerId = oppositeCorners[this.
|
|
4699
|
-
const leftCornerId = oppositeCorners[this.
|
|
4417
|
+
const rightCornerId = oppositeCorners[this.Sb(cornerId)];
|
|
4418
|
+
const leftCornerId = oppositeCorners[this.Tb(cornerId)];
|
|
4700
4419
|
const rightFaceId = rightCornerId === kInvalidCornerIndex5 ? kInvalidFaceIndex2 : rightCornerId / 3 | 0;
|
|
4701
4420
|
const leftFaceId = leftCornerId === kInvalidCornerIndex5 ? kInvalidFaceIndex2 : leftCornerId / 3 | 0;
|
|
4702
4421
|
const isRightFaceVisited = rightFaceId === kInvalidFaceIndex2 || isFaceVisited[rightFaceId] !== 0;
|
|
4703
4422
|
const isLeftFaceVisited = leftFaceId === kInvalidFaceIndex2 || isFaceVisited[leftFaceId] !== 0;
|
|
4704
4423
|
if (!isLeftFaceVisited) {
|
|
4705
|
-
const priority = this.
|
|
4706
|
-
if (isRightFaceVisited && priority <= this.
|
|
4424
|
+
const priority = this.Ub(leftCornerId);
|
|
4425
|
+
if (isRightFaceVisited && priority <= this.Y) {
|
|
4707
4426
|
cornerId = leftCornerId;
|
|
4708
4427
|
continue;
|
|
4709
4428
|
} else {
|
|
4710
|
-
this.
|
|
4429
|
+
this.Vb(leftCornerId, priority);
|
|
4711
4430
|
}
|
|
4712
4431
|
}
|
|
4713
4432
|
if (!isRightFaceVisited) {
|
|
4714
|
-
const priority = this.
|
|
4715
|
-
if (priority <= this.
|
|
4433
|
+
const priority = this.Ub(rightCornerId);
|
|
4434
|
+
if (priority <= this.Y) {
|
|
4716
4435
|
cornerId = rightCornerId;
|
|
4717
4436
|
continue;
|
|
4718
4437
|
} else {
|
|
4719
|
-
this.
|
|
4438
|
+
this.Vb(rightCornerId, priority);
|
|
4720
4439
|
}
|
|
4721
4440
|
}
|
|
4722
4441
|
break;
|
|
@@ -4729,66 +4448,66 @@ var MaxPredictionDegreeTraverser = class {
|
|
|
4729
4448
|
// src/decoder/compression/mesh/traverser/MeshAttributeIndicesEncodingObserver.ts
|
|
4730
4449
|
var MeshAttributeIndicesEncodingObserver = class {
|
|
4731
4450
|
C;
|
|
4732
|
-
|
|
4733
|
-
|
|
4734
|
-
|
|
4735
|
-
|
|
4451
|
+
W;
|
|
4452
|
+
lb;
|
|
4453
|
+
kb;
|
|
4454
|
+
Wb;
|
|
4736
4455
|
constructor(mesh, sequencer, encodingData) {
|
|
4737
4456
|
this.C = encodingData;
|
|
4738
|
-
this.
|
|
4739
|
-
this.
|
|
4740
|
-
this
|
|
4741
|
-
this.
|
|
4457
|
+
this.W = sequencer;
|
|
4458
|
+
this.lb = encodingData.vertexToEncodedAttributeValueIndexMap;
|
|
4459
|
+
this.kb = encodingData.encodedAttributeValueIndexToCornerMap;
|
|
4460
|
+
this.Wb = mesh.faces_;
|
|
4742
4461
|
}
|
|
4743
4462
|
onNewVertexVisited(vertex, corner) {
|
|
4744
|
-
const pointId = this.
|
|
4745
|
-
this.
|
|
4463
|
+
const pointId = this.Wb[corner];
|
|
4464
|
+
this.W.addPointId(pointId);
|
|
4746
4465
|
const numValues = this.C.numValues;
|
|
4747
|
-
this
|
|
4748
|
-
this.
|
|
4466
|
+
this.kb[numValues] = corner;
|
|
4467
|
+
this.lb[vertex] = numValues;
|
|
4749
4468
|
this.C.numValues++;
|
|
4750
4469
|
}
|
|
4751
4470
|
};
|
|
4752
4471
|
|
|
4753
4472
|
// src/decoder/compression/mesh/traverser/MeshTraversalSequencer.ts
|
|
4754
4473
|
var MeshTraversalSequencer = class {
|
|
4755
|
-
|
|
4474
|
+
H;
|
|
4756
4475
|
C;
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
|
|
4476
|
+
Ea = null;
|
|
4477
|
+
x = new Int32Array(0);
|
|
4478
|
+
Fa = 0;
|
|
4760
4479
|
// Per-decode cache, keyed by corner table, shared across the attribute
|
|
4761
4480
|
// decoders of one mesh (see MeshEdgebreakerDecoderImpl).
|
|
4762
|
-
|
|
4481
|
+
ob;
|
|
4763
4482
|
// The cache entry the last generateSequence resolved to (hit or store);
|
|
4764
4483
|
// carries the shared indicesMap.
|
|
4765
|
-
|
|
4484
|
+
pb = null;
|
|
4766
4485
|
// One representative corner per point id, when the connectivity decoder
|
|
4767
4486
|
// recorded them (see MeshEdgebreakerDecoderImpl._assignAttributeVerticesAndPoints).
|
|
4768
|
-
|
|
4487
|
+
ka;
|
|
4769
4488
|
constructor(mesh, encodingData, traversalCache, pointCorner) {
|
|
4770
|
-
this.
|
|
4489
|
+
this.H = mesh;
|
|
4771
4490
|
this.C = encodingData;
|
|
4772
|
-
this.
|
|
4773
|
-
this.
|
|
4491
|
+
this.ob = traversalCache;
|
|
4492
|
+
this.ka = pointCorner;
|
|
4774
4493
|
}
|
|
4775
4494
|
setTraverser(traverser) {
|
|
4776
|
-
this.
|
|
4495
|
+
this.Ea = traverser;
|
|
4777
4496
|
}
|
|
4778
4497
|
generateSequence() {
|
|
4779
|
-
const cornerTable = this.
|
|
4780
|
-
const methodId = this.
|
|
4498
|
+
const cornerTable = this.Ea.cornerTable();
|
|
4499
|
+
const methodId = this.Ea.Qb;
|
|
4781
4500
|
const cacheKey = cornerTable.cornerToVertexArray();
|
|
4782
4501
|
const encodingData = this.C;
|
|
4783
|
-
let byMethod = this.
|
|
4502
|
+
let byMethod = this.ob.get(cacheKey);
|
|
4784
4503
|
const cached = byMethod && byMethod.get(methodId);
|
|
4785
4504
|
if (cached !== void 0) {
|
|
4786
|
-
this.
|
|
4505
|
+
this.x = cached.pointIds;
|
|
4787
4506
|
encodingData.adoptTraversalResult(cached.vertexMap, cached.cornerMap, cached.numValues);
|
|
4788
|
-
this.
|
|
4507
|
+
this.pb = cached;
|
|
4789
4508
|
return true;
|
|
4790
4509
|
}
|
|
4791
|
-
if (!this.
|
|
4510
|
+
if (!this.uc()) {
|
|
4792
4511
|
return false;
|
|
4793
4512
|
}
|
|
4794
4513
|
const numValues = encodingData.numValues;
|
|
@@ -4800,39 +4519,39 @@ var MeshTraversalSequencer = class {
|
|
|
4800
4519
|
}
|
|
4801
4520
|
if (byMethod === void 0) {
|
|
4802
4521
|
byMethod = /* @__PURE__ */ new Map();
|
|
4803
|
-
this.
|
|
4522
|
+
this.ob.set(cacheKey, byMethod);
|
|
4804
4523
|
}
|
|
4805
4524
|
const entry = {
|
|
4806
|
-
pointIds: this.
|
|
4525
|
+
pointIds: this.x,
|
|
4807
4526
|
vertexMap: encodingData.vertexToEncodedAttributeValueIndexMap,
|
|
4808
4527
|
cornerMap: encodingData.encodedAttributeValueIndexToCornerMap,
|
|
4809
4528
|
numValues,
|
|
4810
4529
|
indicesMap: null
|
|
4811
4530
|
};
|
|
4812
4531
|
byMethod.set(methodId, entry);
|
|
4813
|
-
this.
|
|
4532
|
+
this.pb = entry;
|
|
4814
4533
|
return true;
|
|
4815
4534
|
}
|
|
4816
4535
|
getOutputPointIds() {
|
|
4817
|
-
return this.
|
|
4536
|
+
return this.x;
|
|
4818
4537
|
}
|
|
4819
4538
|
addPointId(pointId) {
|
|
4820
|
-
this.
|
|
4539
|
+
this.x[this.Fa++] = pointId;
|
|
4821
4540
|
}
|
|
4822
4541
|
updatePointToAttributeIndexMapping(attribute) {
|
|
4823
|
-
const entry = this.
|
|
4542
|
+
const entry = this.pb;
|
|
4824
4543
|
if (entry !== null && entry.indicesMap !== null) {
|
|
4825
4544
|
attribute.setExplicitMappingShared(entry.indicesMap);
|
|
4826
4545
|
return true;
|
|
4827
4546
|
}
|
|
4828
|
-
const cornerTable = this.
|
|
4829
|
-
const numFaces = this.
|
|
4830
|
-
const numPoints = this.
|
|
4547
|
+
const cornerTable = this.Ea.cornerTable();
|
|
4548
|
+
const numFaces = this.H.numFaces();
|
|
4549
|
+
const numPoints = this.H.numPoints();
|
|
4831
4550
|
attribute.setExplicitMappingUnfilled(numPoints);
|
|
4832
4551
|
const cornerToVertex = cornerTable.cornerToVertexArray();
|
|
4833
4552
|
const vertexToAttEntry = this.C.vertexToEncodedAttributeValueIndexMap;
|
|
4834
4553
|
const indicesMap = attribute.indicesMap;
|
|
4835
|
-
const pointCorner = this.
|
|
4554
|
+
const pointCorner = this.ka;
|
|
4836
4555
|
if (pointCorner !== null) {
|
|
4837
4556
|
for (let p = 0; p < numPoints; ++p) {
|
|
4838
4557
|
const vertId = cornerToVertex[pointCorner[p]];
|
|
@@ -4847,7 +4566,7 @@ var MeshTraversalSequencer = class {
|
|
|
4847
4566
|
}
|
|
4848
4567
|
} else {
|
|
4849
4568
|
const numCorners = numFaces * 3;
|
|
4850
|
-
const faces = this.
|
|
4569
|
+
const faces = this.H.faces_;
|
|
4851
4570
|
for (let ci = 0; ci < numCorners; ++ci) {
|
|
4852
4571
|
const vertId = cornerToVertex[ci];
|
|
4853
4572
|
if (vertId < 0) {
|
|
@@ -4866,10 +4585,10 @@ var MeshTraversalSequencer = class {
|
|
|
4866
4585
|
}
|
|
4867
4586
|
return true;
|
|
4868
4587
|
}
|
|
4869
|
-
|
|
4870
|
-
this.
|
|
4871
|
-
this.
|
|
4872
|
-
const traverser = this.
|
|
4588
|
+
uc() {
|
|
4589
|
+
this.Fa = 0;
|
|
4590
|
+
this.x = scratchInt32(this.H.numPoints());
|
|
4591
|
+
const traverser = this.Ea;
|
|
4873
4592
|
traverser.onTraversalStart();
|
|
4874
4593
|
if (!traverser.traverseAll()) {
|
|
4875
4594
|
return false;
|
|
@@ -4877,15 +4596,15 @@ var MeshTraversalSequencer = class {
|
|
|
4877
4596
|
if (!traverser.emitsPointIds) {
|
|
4878
4597
|
const numValues = this.C.numValues;
|
|
4879
4598
|
const cornerMap = this.C.encodedAttributeValueIndexToCornerMap;
|
|
4880
|
-
const faces = this.
|
|
4881
|
-
const outPointIds = this.
|
|
4599
|
+
const faces = this.H.faces_;
|
|
4600
|
+
const outPointIds = this.x;
|
|
4882
4601
|
for (let i = 0; i < numValues; ++i) {
|
|
4883
4602
|
outPointIds[i] = faces[cornerMap[i]];
|
|
4884
4603
|
}
|
|
4885
|
-
this.
|
|
4604
|
+
this.Fa = numValues;
|
|
4886
4605
|
}
|
|
4887
|
-
if (this.
|
|
4888
|
-
this.
|
|
4606
|
+
if (this.Fa < this.x.length) {
|
|
4607
|
+
this.x = this.x.subarray(0, this.Fa);
|
|
4889
4608
|
}
|
|
4890
4609
|
return true;
|
|
4891
4610
|
}
|
|
@@ -4894,36 +4613,38 @@ var MeshTraversalSequencer = class {
|
|
|
4894
4613
|
// src/decoder/compression/mesh/MeshEdgebreakerDecoderImpl.ts
|
|
4895
4614
|
var kInvalidCornerIndex6 = -1;
|
|
4896
4615
|
var MeshEdgebreakerDecoderImpl = class {
|
|
4897
|
-
|
|
4616
|
+
n;
|
|
4898
4617
|
a = null;
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
4618
|
+
O = [];
|
|
4619
|
+
la = new Uint8Array(0);
|
|
4620
|
+
Z = 0;
|
|
4621
|
+
qb = new MeshAttributeIndicesEncodingData();
|
|
4622
|
+
Xb = -1;
|
|
4904
4623
|
// Cache of vertex-traversal results keyed by corner table, so attributes
|
|
4905
4624
|
// sharing connectivity traverse once.
|
|
4906
|
-
|
|
4625
|
+
vc = /* @__PURE__ */ new Map();
|
|
4907
4626
|
i = [];
|
|
4908
|
-
|
|
4627
|
+
K;
|
|
4909
4628
|
// One corner per point id (decode-scoped scratch), filled by
|
|
4910
4629
|
// _assignAttributeVerticesAndPoints; null when points are the base vertices.
|
|
4911
|
-
|
|
4630
|
+
ka = null;
|
|
4631
|
+
// Corners on a boundary edge, counted by _decodeAttributeConnectivities.
|
|
4632
|
+
Yb = 0;
|
|
4912
4633
|
constructor(decoder, TraversalDecoderClass) {
|
|
4913
|
-
this.
|
|
4914
|
-
this.
|
|
4634
|
+
this.n = decoder;
|
|
4635
|
+
this.K = new TraversalDecoderClass();
|
|
4915
4636
|
}
|
|
4916
4637
|
getCornerTable() {
|
|
4917
4638
|
return this.a;
|
|
4918
4639
|
}
|
|
4919
4640
|
// The attribute data set whose attributes decoder owns attId, if any.
|
|
4920
|
-
|
|
4641
|
+
Zb(attId) {
|
|
4921
4642
|
for (let i = 0; i < this.i.length; ++i) {
|
|
4922
4643
|
const ad = this.i[i];
|
|
4923
|
-
if (ad.decoderId < 0 || ad.decoderId >= this.
|
|
4644
|
+
if (ad.decoderId < 0 || ad.decoderId >= this.n.numAttributesDecoders()) {
|
|
4924
4645
|
continue;
|
|
4925
4646
|
}
|
|
4926
|
-
const dec = this.
|
|
4647
|
+
const dec = this.n.attributesDecoder(ad.decoderId);
|
|
4927
4648
|
for (let j = 0; j < dec.getNumAttributes(); ++j) {
|
|
4928
4649
|
if (dec.getAttributeId(j) === attId) {
|
|
4929
4650
|
return ad;
|
|
@@ -4933,16 +4654,17 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
4933
4654
|
return null;
|
|
4934
4655
|
}
|
|
4935
4656
|
getAttributeCornerTable(attId) {
|
|
4936
|
-
const ad = this.
|
|
4657
|
+
const ad = this.Zb(attId);
|
|
4937
4658
|
return ad !== null && ad.isConnectivityUsed ? ad.connectivityData : null;
|
|
4938
4659
|
}
|
|
4939
4660
|
getAttributeEncodingData(attId) {
|
|
4940
|
-
const ad = this.
|
|
4941
|
-
return ad !== null ? ad.encodingData : this.
|
|
4661
|
+
const ad = this.Zb(attId);
|
|
4662
|
+
return ad !== null ? ad.encodingData : this.qb;
|
|
4942
4663
|
}
|
|
4943
4664
|
createAttributesDecoder(attDecoderId) {
|
|
4944
|
-
const buffer = this.
|
|
4945
|
-
|
|
4665
|
+
const buffer = this.n.buffer();
|
|
4666
|
+
let attDataId = buffer.decodeUint8();
|
|
4667
|
+
if (attDataId !== void 0) attDataId = attDataId << 24 >> 24;
|
|
4946
4668
|
if (attDataId === void 0) return false;
|
|
4947
4669
|
const decoderType = buffer.decodeUint8();
|
|
4948
4670
|
if (decoderType === void 0) return false;
|
|
@@ -4955,55 +4677,57 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
4955
4677
|
}
|
|
4956
4678
|
this.i[attDataId].decoderId = attDecoderId;
|
|
4957
4679
|
} else {
|
|
4958
|
-
if (this.
|
|
4680
|
+
if (this.Xb >= 0) {
|
|
4959
4681
|
return false;
|
|
4960
4682
|
}
|
|
4961
|
-
this.
|
|
4683
|
+
this.Xb = attDecoderId;
|
|
4962
4684
|
}
|
|
4963
4685
|
const traversalMethod = buffer.decodeUint8();
|
|
4964
|
-
if (traversalMethod === void 0 || traversalMethod >=
|
|
4686
|
+
if (traversalMethod === void 0 || traversalMethod >= 2 /* NUM_TRAVERSAL_METHODS */) {
|
|
4965
4687
|
return false;
|
|
4966
4688
|
}
|
|
4967
4689
|
let encodingData;
|
|
4968
4690
|
let cornerTable;
|
|
4969
|
-
if (decoderType ===
|
|
4691
|
+
if (decoderType === 0 /* MESH_VERTEX_ATTRIBUTE */) {
|
|
4970
4692
|
if (attDataId < 0) {
|
|
4971
|
-
encodingData = this.
|
|
4693
|
+
encodingData = this.qb;
|
|
4972
4694
|
} else {
|
|
4973
4695
|
encodingData = this.i[attDataId].encodingData;
|
|
4974
4696
|
this.i[attDataId].isConnectivityUsed = false;
|
|
4975
4697
|
}
|
|
4976
4698
|
cornerTable = this.a;
|
|
4977
4699
|
} else {
|
|
4978
|
-
if (traversalMethod !==
|
|
4700
|
+
if (traversalMethod !== 0 /* MESH_TRAVERSAL_DEPTH_FIRST */ || attDataId < 0) {
|
|
4979
4701
|
return false;
|
|
4980
4702
|
}
|
|
4981
|
-
|
|
4982
|
-
|
|
4703
|
+
const ad = this.i[attDataId];
|
|
4704
|
+
if (ad.noInteriorSeams) this.wc(ad);
|
|
4705
|
+
encodingData = ad.encodingData;
|
|
4706
|
+
cornerTable = ad.connectivityData;
|
|
4983
4707
|
}
|
|
4984
|
-
const mesh = this.
|
|
4985
|
-
const sequencer = new MeshTraversalSequencer(mesh, encodingData, this.
|
|
4708
|
+
const mesh = this.n.mesh();
|
|
4709
|
+
const sequencer = new MeshTraversalSequencer(mesh, encodingData, this.vc, this.ka);
|
|
4986
4710
|
const observer = new MeshAttributeIndicesEncodingObserver(mesh, sequencer, encodingData);
|
|
4987
|
-
const traverser = traversalMethod ===
|
|
4711
|
+
const traverser = traversalMethod === 1 /* MESH_TRAVERSAL_PREDICTION_DEGREE */ ? new MaxPredictionDegreeTraverser() : new DepthFirstTraverser();
|
|
4988
4712
|
traverser.init(cornerTable, observer);
|
|
4989
4713
|
sequencer.setTraverser(traverser);
|
|
4990
|
-
return this.
|
|
4714
|
+
return this.n.setAttributesDecoder(attDecoderId, new SequentialAttributeDecodersController(sequencer));
|
|
4991
4715
|
}
|
|
4992
4716
|
decodeConnectivity() {
|
|
4993
|
-
const buffer = this.
|
|
4717
|
+
const buffer = this.n.buffer();
|
|
4994
4718
|
const numEncodedVertices = decodeVarint(buffer);
|
|
4995
4719
|
if (numEncodedVertices === void 0) return false;
|
|
4996
|
-
this.
|
|
4720
|
+
this.Z = numEncodedVertices;
|
|
4997
4721
|
const numFaces = decodeVarint(buffer);
|
|
4998
4722
|
if (numFaces === void 0) return false;
|
|
4999
4723
|
if (numFaces > 2147483647 / 3) {
|
|
5000
4724
|
return false;
|
|
5001
4725
|
}
|
|
5002
|
-
if (this.
|
|
4726
|
+
if (this.Z > numFaces * 3) {
|
|
5003
4727
|
return false;
|
|
5004
4728
|
}
|
|
5005
4729
|
const minNumFaceEdges = Math.floor(3 * numFaces / 2);
|
|
5006
|
-
const maxNumVertexEdges = this.
|
|
4730
|
+
const maxNumVertexEdges = this.Z * (this.Z - 1) / 2;
|
|
5007
4731
|
if (maxNumVertexEdges < minNumFaceEdges) {
|
|
5008
4732
|
return false;
|
|
5009
4733
|
}
|
|
@@ -5030,27 +4754,28 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5030
4754
|
ad.numSeamCorners = 0;
|
|
5031
4755
|
this.i.push(ad);
|
|
5032
4756
|
}
|
|
5033
|
-
this.a.reset(numFaces, this.
|
|
5034
|
-
this.
|
|
5035
|
-
if (!this.
|
|
4757
|
+
this.a.reset(numFaces, this.Z + numEncodedSplitSymbols);
|
|
4758
|
+
this.la = scratchUint8Filled(this.Z + numEncodedSplitSymbols, 1);
|
|
4759
|
+
if (!this.xc(buffer)) {
|
|
5036
4760
|
return false;
|
|
5037
4761
|
}
|
|
5038
|
-
this.
|
|
5039
|
-
this.
|
|
5040
|
-
this.
|
|
4762
|
+
this.K.init(this);
|
|
4763
|
+
this.K.setNumEncodedVertices(this.Z + numEncodedSplitSymbols);
|
|
4764
|
+
this.K.setNumAttributeData(numAttributeData);
|
|
5041
4765
|
const traversalEndBuffer = new DecoderBuffer();
|
|
5042
|
-
if (!this.
|
|
4766
|
+
if (!this.K.start(traversalEndBuffer)) {
|
|
5043
4767
|
return false;
|
|
5044
4768
|
}
|
|
5045
|
-
const numConnectivityVerts = this.
|
|
4769
|
+
const numConnectivityVerts = this.yc(numEncodedSymbols);
|
|
5046
4770
|
if (numConnectivityVerts === -1) {
|
|
5047
4771
|
return false;
|
|
5048
4772
|
}
|
|
5049
4773
|
buffer.init(traversalEndBuffer.dataHead, traversalEndBuffer.remainingSize);
|
|
5050
4774
|
if (this.i.length > 0) {
|
|
5051
|
-
this.
|
|
4775
|
+
this.zc();
|
|
5052
4776
|
}
|
|
5053
|
-
this.
|
|
4777
|
+
this.K.done();
|
|
4778
|
+
const numBoundaryCorners = this.Yb;
|
|
5054
4779
|
const distinctTables = [];
|
|
5055
4780
|
const adoptions = [];
|
|
5056
4781
|
let previousConnectivityData = null;
|
|
@@ -5060,6 +4785,10 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5060
4785
|
const connectivityData = this.i[i].connectivityData;
|
|
5061
4786
|
const seamCorners = this.i[i].attributeSeamCorners;
|
|
5062
4787
|
const seamCount = this.i[i].numSeamCorners;
|
|
4788
|
+
if (seamCount === numBoundaryCorners) {
|
|
4789
|
+
this.i[i].noInteriorSeams = true;
|
|
4790
|
+
continue;
|
|
4791
|
+
}
|
|
5063
4792
|
let sameAsPrevious = previousConnectivityData !== null && seamCount === previousSeamCount;
|
|
5064
4793
|
if (sameAsPrevious) {
|
|
5065
4794
|
const previous = previousSeamCorners;
|
|
@@ -5085,14 +4814,14 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5085
4814
|
previousSeamCount = seamCount;
|
|
5086
4815
|
}
|
|
5087
4816
|
if (this.i.length === 0) {
|
|
5088
|
-
this.
|
|
5089
|
-
} else if (!this.
|
|
4817
|
+
this.Ac(numConnectivityVerts);
|
|
4818
|
+
} else if (!this.Bc(distinctTables)) {
|
|
5090
4819
|
return false;
|
|
5091
4820
|
}
|
|
5092
4821
|
for (let i = 0; i < adoptions.length; i += 2) {
|
|
5093
4822
|
adoptions[i].adoptFrom(adoptions[i + 1]);
|
|
5094
4823
|
}
|
|
5095
|
-
this.
|
|
4824
|
+
this.qb.init(this.a.numVertices());
|
|
5096
4825
|
for (let i = 0; i < this.i.length; ++i) {
|
|
5097
4826
|
let attConnectivityVerts = this.i[i].connectivityData.numVertices();
|
|
5098
4827
|
if (attConnectivityVerts < this.a.numVertices()) {
|
|
@@ -5102,11 +4831,11 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5102
4831
|
}
|
|
5103
4832
|
return true;
|
|
5104
4833
|
}
|
|
5105
|
-
|
|
5106
|
-
if (this.
|
|
4834
|
+
Cc(encoderSymbolId, outResult) {
|
|
4835
|
+
if (this.O.length === 0) {
|
|
5107
4836
|
return false;
|
|
5108
4837
|
}
|
|
5109
|
-
const back = this.
|
|
4838
|
+
const back = this.O[this.O.length - 1];
|
|
5110
4839
|
if (back.sourceSymbolId > encoderSymbolId) {
|
|
5111
4840
|
outResult.encoderSplitSymbolId = -1;
|
|
5112
4841
|
return true;
|
|
@@ -5116,24 +4845,24 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5116
4845
|
}
|
|
5117
4846
|
outResult.faceEdge = back.sourceEdge;
|
|
5118
4847
|
outResult.encoderSplitSymbolId = back.splitSymbolId;
|
|
5119
|
-
this.
|
|
4848
|
+
this.O.pop();
|
|
5120
4849
|
return true;
|
|
5121
4850
|
}
|
|
5122
|
-
|
|
5123
|
-
const activeCornerStack = scratchInt32(numSymbols + this.
|
|
4851
|
+
yc(numSymbols) {
|
|
4852
|
+
const activeCornerStack = scratchInt32(numSymbols + this.O.length + 16);
|
|
5124
4853
|
let activeCornerStackSize = 0;
|
|
5125
4854
|
const topologySplitActiveCorners = /* @__PURE__ */ new Map();
|
|
5126
4855
|
const splitResult = { faceEdge: 0, encoderSplitSymbolId: 0 };
|
|
5127
4856
|
const invalidVertices = [];
|
|
5128
4857
|
const removeInvalidVertices = this.i.length === 0;
|
|
5129
|
-
let maxNumVertices = this.
|
|
4858
|
+
let maxNumVertices = this.la.length;
|
|
5130
4859
|
let numFacesDecoded = 0;
|
|
5131
4860
|
const cornerToVertex = this.a.j;
|
|
5132
|
-
const oppositeCorners = this.a.
|
|
4861
|
+
const oppositeCorners = this.a.s;
|
|
5133
4862
|
const vc = this.a;
|
|
5134
|
-
let vertexCorners = vc.
|
|
5135
|
-
const isVertHole = this.
|
|
5136
|
-
const traversalDecoder = this.
|
|
4863
|
+
let vertexCorners = vc.y;
|
|
4864
|
+
const isVertHole = this.la;
|
|
4865
|
+
const traversalDecoder = this.K;
|
|
5137
4866
|
for (let symbolId = 0; symbolId < numSymbols; ++symbolId) {
|
|
5138
4867
|
const faceIndex = numFacesDecoded++;
|
|
5139
4868
|
let checkTopologySplit = false;
|
|
@@ -5189,7 +4918,7 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5189
4918
|
newVertIndex = vc.l++;
|
|
5190
4919
|
} else {
|
|
5191
4920
|
newVertIndex = vc.addNewVertex();
|
|
5192
|
-
vertexCorners = vc.
|
|
4921
|
+
vertexCorners = vc.y;
|
|
5193
4922
|
}
|
|
5194
4923
|
if (vc.l > maxNumVertices) return -1;
|
|
5195
4924
|
cornerToVertex[oppCorner] = newVertIndex;
|
|
@@ -5259,7 +4988,7 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5259
4988
|
firstVertIndex = vc.addNewVertex();
|
|
5260
4989
|
vc.addNewVertex();
|
|
5261
4990
|
vc.addNewVertex();
|
|
5262
|
-
vertexCorners = vc.
|
|
4991
|
+
vertexCorners = vc.y;
|
|
5263
4992
|
}
|
|
5264
4993
|
if (vc.l > maxNumVertices) return -1;
|
|
5265
4994
|
cornerToVertex[corner] = firstVertIndex;
|
|
@@ -5274,9 +5003,9 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5274
5003
|
return -1;
|
|
5275
5004
|
}
|
|
5276
5005
|
traversalDecoder.newActiveCornerReached(activeCornerStack[activeCornerStackSize - 1]);
|
|
5277
|
-
if (checkTopologySplit && this.
|
|
5006
|
+
if (checkTopologySplit && this.O.length > 0) {
|
|
5278
5007
|
const encoderSymbolId = numSymbols - symbolId - 1;
|
|
5279
|
-
while (this.
|
|
5008
|
+
while (this.Cc(encoderSymbolId, splitResult)) {
|
|
5280
5009
|
if (splitResult.encoderSplitSymbolId < 0) return -1;
|
|
5281
5010
|
const actTopCorner = activeCornerStack[activeCornerStackSize - 1];
|
|
5282
5011
|
let newActiveCorner;
|
|
@@ -5293,24 +5022,24 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5293
5022
|
if (vc.l > maxNumVertices) {
|
|
5294
5023
|
return -1;
|
|
5295
5024
|
}
|
|
5296
|
-
numFacesDecoded = this.
|
|
5025
|
+
numFacesDecoded = this.Dc(activeCornerStack, activeCornerStackSize, numFacesDecoded);
|
|
5297
5026
|
if (numFacesDecoded === -1) {
|
|
5298
5027
|
return -1;
|
|
5299
5028
|
}
|
|
5300
5029
|
if (numFacesDecoded !== this.a.numFaces()) {
|
|
5301
5030
|
return -1;
|
|
5302
5031
|
}
|
|
5303
|
-
return this.
|
|
5032
|
+
return this.Ec(invalidVertices);
|
|
5304
5033
|
}
|
|
5305
5034
|
// Connects the remaining active-stack corners to newly decoded start faces.
|
|
5306
5035
|
// Returns the updated decoded-face count, or -1 on malformed input.
|
|
5307
|
-
|
|
5036
|
+
Dc(activeCornerStack, activeCornerStackSize, numFacesDecoded) {
|
|
5308
5037
|
const ct = this.a;
|
|
5038
|
+
const oppositeCorners = ct.s;
|
|
5309
5039
|
const cornerToVertex = ct.j;
|
|
5310
|
-
const
|
|
5311
|
-
const
|
|
5312
|
-
const
|
|
5313
|
-
const traversalDecoder = this.I;
|
|
5040
|
+
const vertexCorners = ct.y;
|
|
5041
|
+
const isVertHole = this.la;
|
|
5042
|
+
const traversalDecoder = this.K;
|
|
5314
5043
|
const numCorners = ct.numCorners();
|
|
5315
5044
|
const numFaces = ct.numFaces();
|
|
5316
5045
|
const next = (c) => c < 0 ? -1 : c % 3 === 2 ? c - 2 : c + 1;
|
|
@@ -5358,28 +5087,12 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5358
5087
|
// Removes invalid (isolated) vertices by swapping them with the last valid
|
|
5359
5088
|
// vertex in the table, matching C++ mesh_edgebreaker_decoder_impl.cc (the
|
|
5360
5089
|
// forward iteration order matters). Returns the final vertex count, or -1.
|
|
5361
|
-
|
|
5090
|
+
Ec(invalidVertices) {
|
|
5362
5091
|
const ct = this.a;
|
|
5363
5092
|
const cornerToVertex = ct.j;
|
|
5364
|
-
const
|
|
5365
|
-
const
|
|
5366
|
-
const isVertHole = this.ea;
|
|
5367
|
-
const numCorners = ct.numCorners();
|
|
5368
|
-
const next = (c) => c < 0 ? -1 : c % 3 === 2 ? c - 2 : c + 1;
|
|
5369
|
-
const prev = (c) => c < 0 ? -1 : c % 3 === 0 ? c + 2 : c - 1;
|
|
5370
|
-
const vertex = (c) => c < 0 || c >= numCorners ? -1 : cornerToVertex[c];
|
|
5371
|
-
const opposite = (c) => c < 0 || c >= numCorners ? -1 : oppositeCorners[c];
|
|
5093
|
+
const vertexCorners = ct.y;
|
|
5094
|
+
const isVertHole = this.la;
|
|
5372
5095
|
const leftMostCorner = (v) => v < 0 || v >= vertexCorners.length ? -1 : vertexCorners[v];
|
|
5373
|
-
const swingLeft = (c) => {
|
|
5374
|
-
const n = next(c);
|
|
5375
|
-
const o = opposite(n);
|
|
5376
|
-
return o < 0 ? -1 : next(o);
|
|
5377
|
-
};
|
|
5378
|
-
const swingRight = (c) => {
|
|
5379
|
-
const p = prev(c);
|
|
5380
|
-
const o = opposite(p);
|
|
5381
|
-
return o < 0 ? -1 : prev(o);
|
|
5382
|
-
};
|
|
5383
5096
|
let numVertices = ct.numVertices();
|
|
5384
5097
|
for (let ivIdx = 0; ivIdx < invalidVertices.length; ++ivIdx) {
|
|
5385
5098
|
const invalidVert = invalidVertices[ivIdx];
|
|
@@ -5392,22 +5105,22 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5392
5105
|
let cid = startCid;
|
|
5393
5106
|
let leftTraversal = true;
|
|
5394
5107
|
while (cid !== kInvalidCornerIndex6) {
|
|
5395
|
-
if (vertex(cid) !== srcVert) {
|
|
5108
|
+
if (ct.vertex(cid) !== srcVert) {
|
|
5396
5109
|
return -1;
|
|
5397
5110
|
}
|
|
5398
5111
|
cornerToVertex[cid] = invalidVert;
|
|
5399
5112
|
if (leftTraversal) {
|
|
5400
|
-
const nextC = swingLeft(cid);
|
|
5113
|
+
const nextC = ct.swingLeft(cid);
|
|
5401
5114
|
if (nextC === kInvalidCornerIndex6) {
|
|
5402
5115
|
leftTraversal = false;
|
|
5403
|
-
cid = swingRight(startCid);
|
|
5116
|
+
cid = ct.swingRight(startCid);
|
|
5404
5117
|
} else if (nextC === startCid) {
|
|
5405
5118
|
break;
|
|
5406
5119
|
} else {
|
|
5407
5120
|
cid = nextC;
|
|
5408
5121
|
}
|
|
5409
5122
|
} else {
|
|
5410
|
-
cid = swingRight(cid);
|
|
5123
|
+
cid = ct.swingRight(cid);
|
|
5411
5124
|
}
|
|
5412
5125
|
}
|
|
5413
5126
|
vertexCorners[invalidVert] = leftMostCorner(srcVert);
|
|
@@ -5420,7 +5133,7 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5420
5133
|
}
|
|
5421
5134
|
// Hole events were removed from the bitstream in 2.1; for 2.2 this only
|
|
5422
5135
|
// decodes the inline topology-split events.
|
|
5423
|
-
|
|
5136
|
+
xc(decoderBuffer) {
|
|
5424
5137
|
const numTopologySplits = decodeVarint(decoderBuffer);
|
|
5425
5138
|
if (numTopologySplits === void 0) return false;
|
|
5426
5139
|
if (numTopologySplits > 0) {
|
|
@@ -5438,12 +5151,12 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5438
5151
|
if (delta2 > eventData.sourceSymbolId) return false;
|
|
5439
5152
|
eventData.splitSymbolId = eventData.sourceSymbolId - delta2;
|
|
5440
5153
|
lastSourceSymbolId = eventData.sourceSymbolId;
|
|
5441
|
-
this.
|
|
5154
|
+
this.O.push(eventData);
|
|
5442
5155
|
}
|
|
5443
5156
|
decoderBuffer.startBitDecoding(false);
|
|
5444
5157
|
for (let i = 0; i < numTopologySplits; ++i) {
|
|
5445
5158
|
const edgeData = decoderBuffer.decodeLeastSignificantBits32(1);
|
|
5446
|
-
this.
|
|
5159
|
+
this.O[i].sourceEdge = edgeData & 1;
|
|
5447
5160
|
}
|
|
5448
5161
|
decoderBuffer.endBitDecoding();
|
|
5449
5162
|
}
|
|
@@ -5461,32 +5174,37 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5461
5174
|
// the face's base corner -- is just `oppCorner >= faceBaseCorner`, since the
|
|
5462
5175
|
// base corner is a multiple of 3. That removes the per-corner division; the
|
|
5463
5176
|
// invalid-corner case (-1) is still handled by the branch above it.
|
|
5464
|
-
|
|
5177
|
+
zc() {
|
|
5465
5178
|
const oppositeCorners = this.a.oppositeCornerArray();
|
|
5466
5179
|
const attributeData = this.i;
|
|
5467
5180
|
const numAttrData = attributeData.length;
|
|
5468
|
-
const connectivityDecoders = this.
|
|
5181
|
+
const connectivityDecoders = this.K._b;
|
|
5469
5182
|
const numCorners = this.a.numCorners();
|
|
5470
5183
|
const candidates = scratchInt32(numCorners);
|
|
5471
5184
|
let numCandidates = 0;
|
|
5185
|
+
let numBoundaryCorners = 0;
|
|
5472
5186
|
for (let corner = 0; corner < numCorners; corner += 3) {
|
|
5473
5187
|
let opp = oppositeCorners[corner];
|
|
5474
5188
|
candidates[numCandidates] = corner ^ opp >> 31;
|
|
5475
5189
|
numCandidates -= (opp | corner - opp - 1) >> 31;
|
|
5190
|
+
numBoundaryCorners -= opp >> 31;
|
|
5476
5191
|
opp = oppositeCorners[corner + 1];
|
|
5477
5192
|
candidates[numCandidates] = corner + 1 ^ opp >> 31;
|
|
5478
5193
|
numCandidates -= (opp | corner - opp - 1) >> 31;
|
|
5194
|
+
numBoundaryCorners -= opp >> 31;
|
|
5479
5195
|
opp = oppositeCorners[corner + 2];
|
|
5480
5196
|
candidates[numCandidates] = corner + 2 ^ opp >> 31;
|
|
5481
5197
|
numCandidates -= (opp | corner - opp - 1) >> 31;
|
|
5198
|
+
numBoundaryCorners -= opp >> 31;
|
|
5482
5199
|
}
|
|
5200
|
+
this.Yb = numBoundaryCorners;
|
|
5483
5201
|
for (let i = 0; i < numAttrData; ++i) {
|
|
5484
5202
|
const ad = attributeData[i];
|
|
5485
5203
|
const seamCorners = ad.attributeSeamCorners;
|
|
5486
5204
|
let numSeamCorners = ad.numSeamCorners;
|
|
5487
5205
|
const decoder = connectivityDecoders[i];
|
|
5488
|
-
const ans = decoder.
|
|
5489
|
-
const p = decoder.
|
|
5206
|
+
const ans = decoder.db;
|
|
5207
|
+
const p = decoder.eb;
|
|
5490
5208
|
const buf = ans.buf;
|
|
5491
5209
|
const bufStart = ans.bufStart;
|
|
5492
5210
|
let state = ans.state;
|
|
@@ -5514,8 +5232,8 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5514
5232
|
}
|
|
5515
5233
|
}
|
|
5516
5234
|
// Position-only connectivity: vertex indices equal point indices.
|
|
5517
|
-
|
|
5518
|
-
const mesh = this.
|
|
5235
|
+
Ac(numConnectivityVerts) {
|
|
5236
|
+
const mesh = this.n.mesh();
|
|
5519
5237
|
const ct = this.a;
|
|
5520
5238
|
mesh.setNumFaces(ct.numFaces());
|
|
5521
5239
|
const numCorners = ct.numCorners();
|
|
@@ -5524,8 +5242,36 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5524
5242
|
for (let c = 0; c < numCorners; ++c) {
|
|
5525
5243
|
faces[c] = baseCornerToVertex[c];
|
|
5526
5244
|
}
|
|
5527
|
-
this.
|
|
5528
|
-
this.
|
|
5245
|
+
this.ka = null;
|
|
5246
|
+
this.n.pointCloud().setNumPoints(numConnectivityVerts);
|
|
5247
|
+
}
|
|
5248
|
+
// Builds an attribute corner table whose only seams are boundary edges (see
|
|
5249
|
+
// decodeConnectivity), for a per-corner decoder that asked for it. With no
|
|
5250
|
+
// interior seam every vertex ring is one attribute vertex, numbered in
|
|
5251
|
+
// vertex order with isolated vertices skipped -- what the ring walk in
|
|
5252
|
+
// _assignAttributeVerticesAndPoints assigns such a table, without the walk.
|
|
5253
|
+
wc(ad) {
|
|
5254
|
+
const ct = this.a;
|
|
5255
|
+
const table = ad.connectivityData;
|
|
5256
|
+
table.initEmpty(ct);
|
|
5257
|
+
table.reserveSeamEdges(ad.numSeamCorners);
|
|
5258
|
+
for (let s = 0; s < ad.numSeamCorners; ++s) table.addSeamEdge(ad.attributeSeamCorners[s]);
|
|
5259
|
+
const numVertices = ct.numVertices();
|
|
5260
|
+
const numCorners = ct.numCorners();
|
|
5261
|
+
const vertexLeftmost = ct.vertexLeftmostCornerArray();
|
|
5262
|
+
const cornerToVertex = ct.cornerToVertexArray();
|
|
5263
|
+
const vertexIds = scratchInt32(numVertices);
|
|
5264
|
+
const leftMost = scratchInt32(numVertices);
|
|
5265
|
+
let numAttVertices = 0;
|
|
5266
|
+
for (let v = 0; v < numVertices; ++v) {
|
|
5267
|
+
const c = vertexLeftmost[v];
|
|
5268
|
+
vertexIds[v] = c === kInvalidCornerIndex6 ? -1 : numAttVertices;
|
|
5269
|
+
if (c !== kInvalidCornerIndex6) leftMost[numAttVertices++] = c;
|
|
5270
|
+
}
|
|
5271
|
+
const c2v = table.ca;
|
|
5272
|
+
for (let c = 0; c < numCorners; ++c) c2v[c] = vertexIds[cornerToVertex[c]];
|
|
5273
|
+
table.setRecomputedVertices(leftMost, numAttVertices);
|
|
5274
|
+
ad.noInteriorSeams = false;
|
|
5529
5275
|
}
|
|
5530
5276
|
// One walk around every vertex ring that (a) numbers the attribute vertices
|
|
5531
5277
|
// of every distinct attribute corner table (C++ MeshAttributeCornerTable::
|
|
@@ -5547,8 +5293,8 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5547
5293
|
// corner of every boundary vertex, but allowed for by the C++ code) is
|
|
5548
5294
|
// extended leftwards first, so the walk covers exactly the corners the
|
|
5549
5295
|
// separate passes would have reached.
|
|
5550
|
-
|
|
5551
|
-
const mesh = this.
|
|
5296
|
+
Bc(tables) {
|
|
5297
|
+
const mesh = this.n.mesh();
|
|
5552
5298
|
const ct = this.a;
|
|
5553
5299
|
mesh.setNumFaces(ct.numFaces());
|
|
5554
5300
|
const numCorners = ct.numCorners();
|
|
@@ -5556,7 +5302,7 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5556
5302
|
const faces = mesh.faces_;
|
|
5557
5303
|
const vertexLeftmost = ct.vertexLeftmostCornerArray();
|
|
5558
5304
|
const baseOpposite = ct.oppositeCornerArray();
|
|
5559
|
-
const isVertHole = this.
|
|
5305
|
+
const isVertHole = this.la;
|
|
5560
5306
|
const numTables = tables.length;
|
|
5561
5307
|
const attCornerToVertex = new Array(numTables);
|
|
5562
5308
|
const edgeOnSeam = new Array(numTables);
|
|
@@ -5564,9 +5310,9 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5564
5310
|
const leftMostMaps = new Array(numTables);
|
|
5565
5311
|
const numAttVertices = new Int32Array(numTables);
|
|
5566
5312
|
for (let t = 0; t < numTables; ++t) {
|
|
5567
|
-
attCornerToVertex[t] = tables[t].
|
|
5568
|
-
edgeOnSeam[t] = tables[t].
|
|
5569
|
-
vertexOnSeam[t] = tables[t].
|
|
5313
|
+
attCornerToVertex[t] = tables[t].ca;
|
|
5314
|
+
edgeOnSeam[t] = tables[t].ba;
|
|
5315
|
+
vertexOnSeam[t] = tables[t].ta;
|
|
5570
5316
|
leftMostMaps[t] = scratchInt32(numCorners);
|
|
5571
5317
|
}
|
|
5572
5318
|
const ring = scratchInt32(numCorners);
|
|
@@ -5574,9 +5320,33 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5574
5320
|
const pointCorner = scratchInt32(numCorners);
|
|
5575
5321
|
const idChange = scratchUint8Zeroed(numCorners);
|
|
5576
5322
|
let numPoints = 0;
|
|
5323
|
+
const plainPointId = scratchInt32(numVertices);
|
|
5324
|
+
const plainVertIds = new Array(numTables);
|
|
5325
|
+
for (let t = 0; t < numTables; ++t) plainVertIds[t] = scratchInt32(numVertices);
|
|
5577
5326
|
for (let v = 0; v < numVertices; ++v) {
|
|
5578
5327
|
const c = vertexLeftmost[v];
|
|
5579
5328
|
if (c === kInvalidCornerIndex6) continue;
|
|
5329
|
+
const hole = isVertHole[v] !== 0;
|
|
5330
|
+
let anySeam = false;
|
|
5331
|
+
for (let t = 0; t < numTables; ++t) {
|
|
5332
|
+
if (vertexOnSeam[t][v] !== 0) {
|
|
5333
|
+
anySeam = true;
|
|
5334
|
+
break;
|
|
5335
|
+
}
|
|
5336
|
+
}
|
|
5337
|
+
if (!hole && !anySeam) {
|
|
5338
|
+
for (let t = 0; t < numTables; ++t) {
|
|
5339
|
+
const vertId = numAttVertices[t];
|
|
5340
|
+
leftMostMaps[t][vertId] = c;
|
|
5341
|
+
plainVertIds[t][v] = vertId;
|
|
5342
|
+
numAttVertices[t] = vertId + 1;
|
|
5343
|
+
}
|
|
5344
|
+
const pointId2 = numPoints++;
|
|
5345
|
+
pointCorner[pointId2] = c;
|
|
5346
|
+
plainPointId[v] = pointId2;
|
|
5347
|
+
continue;
|
|
5348
|
+
}
|
|
5349
|
+
plainPointId[v] = -1;
|
|
5580
5350
|
let start = 0;
|
|
5581
5351
|
let k = 0;
|
|
5582
5352
|
let actC = c;
|
|
@@ -5664,20 +5434,6 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5664
5434
|
if (vertId !== firstVertId) idChange[first] = 1;
|
|
5665
5435
|
numAttVertices[t] = vertId + 1;
|
|
5666
5436
|
}
|
|
5667
|
-
const hole = isVertHole[v] !== 0;
|
|
5668
|
-
let anySeam = false;
|
|
5669
|
-
for (let t = 0; t < numTables; ++t) {
|
|
5670
|
-
if (vertexOnSeam[t][v] !== 0) {
|
|
5671
|
-
anySeam = true;
|
|
5672
|
-
break;
|
|
5673
|
-
}
|
|
5674
|
-
}
|
|
5675
|
-
if (!hole && !anySeam) {
|
|
5676
|
-
const pointId2 = numPoints++;
|
|
5677
|
-
pointCorner[pointId2] = c;
|
|
5678
|
-
for (let j2 = start; j2 < end; ++j2) faces[ring[j2]] = pointId2;
|
|
5679
|
-
continue;
|
|
5680
|
-
}
|
|
5681
5437
|
let j = start;
|
|
5682
5438
|
if (!hole) {
|
|
5683
5439
|
for (let t = 0; t < numTables; ++t) {
|
|
@@ -5717,11 +5473,19 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5717
5473
|
faces[rc] = pointId;
|
|
5718
5474
|
}
|
|
5719
5475
|
}
|
|
5476
|
+
const baseCornerToVertex = ct.cornerToVertexArray();
|
|
5477
|
+
for (let c = 0; c < numCorners; ++c) {
|
|
5478
|
+
const v = baseCornerToVertex[c];
|
|
5479
|
+
const pointId = plainPointId[v];
|
|
5480
|
+
if (pointId < 0) continue;
|
|
5481
|
+
faces[c] = pointId;
|
|
5482
|
+
for (let t = 0; t < numTables; ++t) attCornerToVertex[t][c] = plainVertIds[t][v];
|
|
5483
|
+
}
|
|
5720
5484
|
for (let t = 0; t < numTables; ++t) {
|
|
5721
5485
|
tables[t].setRecomputedVertices(leftMostMaps[t], numAttVertices[t]);
|
|
5722
5486
|
}
|
|
5723
|
-
this.
|
|
5724
|
-
this.
|
|
5487
|
+
this.ka = pointCorner;
|
|
5488
|
+
this.n.pointCloud().setNumPoints(numPoints);
|
|
5725
5489
|
return true;
|
|
5726
5490
|
}
|
|
5727
5491
|
};
|
|
@@ -5750,30 +5514,33 @@ var AttributeData = class {
|
|
|
5750
5514
|
encodingData = new MeshAttributeIndicesEncodingData();
|
|
5751
5515
|
attributeSeamCorners = new Int32Array(0);
|
|
5752
5516
|
numSeamCorners = 0;
|
|
5517
|
+
// Set when every seam is a boundary edge and connectivityData was therefore
|
|
5518
|
+
// left unbuilt (see decodeConnectivity); cleared once it is built on demand.
|
|
5519
|
+
noInteriorSeams = false;
|
|
5753
5520
|
};
|
|
5754
5521
|
var CornerTable = class {
|
|
5755
|
-
|
|
5756
|
-
|
|
5522
|
+
$b = 0;
|
|
5523
|
+
J = 0;
|
|
5757
5524
|
l = 0;
|
|
5758
5525
|
j = null;
|
|
5759
5526
|
// corner -> vertex
|
|
5760
|
-
|
|
5527
|
+
s = null;
|
|
5761
5528
|
// corner -> opposite corner
|
|
5762
|
-
|
|
5529
|
+
y = null;
|
|
5763
5530
|
// vertex -> left-most corner
|
|
5764
5531
|
reset(numFaces, numVertices) {
|
|
5765
|
-
this
|
|
5766
|
-
this.
|
|
5532
|
+
this.$b = numFaces;
|
|
5533
|
+
this.J = numFaces * 3;
|
|
5767
5534
|
this.l = 0;
|
|
5768
|
-
this.j = scratchInt32Filled(this.
|
|
5769
|
-
this.
|
|
5770
|
-
this.
|
|
5535
|
+
this.j = scratchInt32Filled(this.J, -1);
|
|
5536
|
+
this.s = scratchInt32Filled(this.J, -1);
|
|
5537
|
+
this.y = scratchInt32Filled(numVertices, -1);
|
|
5771
5538
|
}
|
|
5772
5539
|
numFaces() {
|
|
5773
|
-
return this
|
|
5540
|
+
return this.$b;
|
|
5774
5541
|
}
|
|
5775
5542
|
numCorners() {
|
|
5776
|
-
return this.
|
|
5543
|
+
return this.J;
|
|
5777
5544
|
}
|
|
5778
5545
|
numVertices() {
|
|
5779
5546
|
return this.l;
|
|
@@ -5789,34 +5556,34 @@ var CornerTable = class {
|
|
|
5789
5556
|
return rem === 0 ? corner + 2 : corner - 1;
|
|
5790
5557
|
}
|
|
5791
5558
|
vertex(corner) {
|
|
5792
|
-
if (corner < 0 || corner >= this.
|
|
5559
|
+
if (corner < 0 || corner >= this.J) return -1;
|
|
5793
5560
|
return this.j[corner];
|
|
5794
5561
|
}
|
|
5795
5562
|
opposite(corner) {
|
|
5796
|
-
if (corner < 0 || corner >= this.
|
|
5797
|
-
return this.
|
|
5563
|
+
if (corner < 0 || corner >= this.J) return -1;
|
|
5564
|
+
return this.s[corner];
|
|
5798
5565
|
}
|
|
5799
5566
|
// Flat-array accessors; let callers avoid polymorphic per-corner dispatch.
|
|
5800
5567
|
cornerToVertexArray() {
|
|
5801
5568
|
return this.j;
|
|
5802
5569
|
}
|
|
5803
5570
|
oppositeCornerArray() {
|
|
5804
|
-
return this.
|
|
5571
|
+
return this.s;
|
|
5805
5572
|
}
|
|
5806
5573
|
vertexLeftmostCornerArray() {
|
|
5807
|
-
return this.
|
|
5574
|
+
return this.y;
|
|
5808
5575
|
}
|
|
5809
5576
|
// Mirrors C++ CornerTable::AddNewVertex() (push_back(kInvalidCornerIndex)).
|
|
5810
5577
|
addNewVertex() {
|
|
5811
5578
|
const newVertex = this.l;
|
|
5812
5579
|
this.l++;
|
|
5813
|
-
if (newVertex >= this.
|
|
5814
|
-
const newCapacity = Math.max(newVertex + 1, this.
|
|
5580
|
+
if (newVertex >= this.y.length) {
|
|
5581
|
+
const newCapacity = Math.max(newVertex + 1, this.y.length * 2, 64);
|
|
5815
5582
|
const newArr = scratchInt32Filled(newCapacity, -1);
|
|
5816
|
-
newArr.set(this.
|
|
5817
|
-
this.
|
|
5583
|
+
newArr.set(this.y);
|
|
5584
|
+
this.y = newArr;
|
|
5818
5585
|
}
|
|
5819
|
-
this.
|
|
5586
|
+
this.y[newVertex] = -1;
|
|
5820
5587
|
return newVertex;
|
|
5821
5588
|
}
|
|
5822
5589
|
// Next corner around a vertex, CCW. SwingLeft(c) = Next(Opposite(Next(c))).
|
|
@@ -5837,24 +5604,24 @@ var CornerTable = class {
|
|
|
5837
5604
|
|
|
5838
5605
|
// src/decoder/compression/mesh/MeshEdgebreakerTraversalDecoder.ts
|
|
5839
5606
|
var MeshEdgebreakerTraversalDecoder = class {
|
|
5840
|
-
|
|
5841
|
-
|
|
5842
|
-
|
|
5843
|
-
|
|
5844
|
-
|
|
5607
|
+
d = new DecoderBuffer();
|
|
5608
|
+
L = new DecoderBuffer();
|
|
5609
|
+
rb = null;
|
|
5610
|
+
_b = [];
|
|
5611
|
+
ac = 0;
|
|
5845
5612
|
// _symbolBuffer's bit cursor, captured once bit decoding starts: decodeSymbol
|
|
5846
5613
|
// runs per decoded face and would otherwise reach it through two property
|
|
5847
5614
|
// loads and a method call per read.
|
|
5848
|
-
|
|
5615
|
+
bc = null;
|
|
5849
5616
|
init(decoder) {
|
|
5850
|
-
const srcBuffer = decoder.
|
|
5851
|
-
this.
|
|
5617
|
+
const srcBuffer = decoder.n.buffer();
|
|
5618
|
+
this.d.init(srcBuffer.dataHead, srcBuffer.remainingSize);
|
|
5852
5619
|
}
|
|
5853
5620
|
// Ignored by default; overridden by predictive/valence decoders.
|
|
5854
5621
|
setNumEncodedVertices(_numVertices) {
|
|
5855
5622
|
}
|
|
5856
5623
|
setNumAttributeData(numData) {
|
|
5857
|
-
this.
|
|
5624
|
+
this.ac = numData;
|
|
5858
5625
|
}
|
|
5859
5626
|
// Sets outBuffer to the data encoded after the traversal section.
|
|
5860
5627
|
start(outBuffer) {
|
|
@@ -5867,19 +5634,19 @@ var MeshEdgebreakerTraversalDecoder = class {
|
|
|
5867
5634
|
if (!this.decodeAttributeSeams()) {
|
|
5868
5635
|
return false;
|
|
5869
5636
|
}
|
|
5870
|
-
outBuffer.init(this.
|
|
5637
|
+
outBuffer.init(this.d.dataHead, this.d.remainingSize);
|
|
5871
5638
|
return true;
|
|
5872
5639
|
}
|
|
5873
5640
|
decodeStartFaceConfiguration() {
|
|
5874
|
-
return this.
|
|
5641
|
+
return this.rb.decodeNextBit();
|
|
5875
5642
|
}
|
|
5876
5643
|
decodeSymbol() {
|
|
5877
|
-
const bd = this.
|
|
5644
|
+
const bd = this.bc;
|
|
5878
5645
|
if (bd !== null) {
|
|
5879
|
-
const buf = bd.
|
|
5646
|
+
const buf = bd.Na;
|
|
5880
5647
|
const off = bd.q;
|
|
5881
5648
|
const byteOffset = off >> 3;
|
|
5882
|
-
if (byteOffset + 4 < bd.
|
|
5649
|
+
if (byteOffset + 4 < bd.ra) {
|
|
5883
5650
|
const bits = (buf[byteOffset] | buf[byteOffset + 1] << 8 | buf[byteOffset + 2] << 16 | buf[byteOffset + 3] << 24) >>> (off & 7) & 7;
|
|
5884
5651
|
if ((bits & 1) === TOPOLOGY_C) {
|
|
5885
5652
|
bd.q = off + 1;
|
|
@@ -5889,11 +5656,11 @@ var MeshEdgebreakerTraversalDecoder = class {
|
|
|
5889
5656
|
return bits;
|
|
5890
5657
|
}
|
|
5891
5658
|
}
|
|
5892
|
-
let symbol = this.
|
|
5659
|
+
let symbol = this.L.decodeLeastSignificantBits32(1);
|
|
5893
5660
|
if (symbol === TOPOLOGY_C) {
|
|
5894
5661
|
return symbol;
|
|
5895
5662
|
}
|
|
5896
|
-
const symbolSuffix = this.
|
|
5663
|
+
const symbolSuffix = this.L.decodeLeastSignificantBits32(2);
|
|
5897
5664
|
symbol |= symbolSuffix << 1;
|
|
5898
5665
|
return symbol;
|
|
5899
5666
|
}
|
|
@@ -5902,39 +5669,39 @@ var MeshEdgebreakerTraversalDecoder = class {
|
|
|
5902
5669
|
mergeVertices(_dest, _source) {
|
|
5903
5670
|
}
|
|
5904
5671
|
done() {
|
|
5905
|
-
if (this.
|
|
5906
|
-
this.
|
|
5672
|
+
if (this.L.bitDecoderActive) {
|
|
5673
|
+
this.L.endBitDecoding();
|
|
5907
5674
|
}
|
|
5908
5675
|
}
|
|
5909
5676
|
decodeTraversalSymbols() {
|
|
5910
|
-
this.
|
|
5911
|
-
const traversalSize = this.
|
|
5677
|
+
this.L.init(this.d.dataHead, this.d.remainingSize);
|
|
5678
|
+
const traversalSize = this.L.startBitDecoding(true);
|
|
5912
5679
|
if (traversalSize === void 0) {
|
|
5913
5680
|
return false;
|
|
5914
5681
|
}
|
|
5915
|
-
this.
|
|
5916
|
-
this.
|
|
5917
|
-
if (traversalSize > this.
|
|
5682
|
+
this.bc = this.L.sa;
|
|
5683
|
+
this.d.init(this.L.dataHead, this.L.remainingSize);
|
|
5684
|
+
if (traversalSize > this.d.remainingSize) {
|
|
5918
5685
|
return false;
|
|
5919
5686
|
}
|
|
5920
|
-
this.
|
|
5687
|
+
this.d.advance(traversalSize);
|
|
5921
5688
|
return true;
|
|
5922
5689
|
}
|
|
5923
5690
|
decodeStartFaces() {
|
|
5924
5691
|
try {
|
|
5925
|
-
this.
|
|
5926
|
-
return this.
|
|
5692
|
+
this.rb = new RAnsBitDecoder();
|
|
5693
|
+
return this.rb.startDecoding(this.d);
|
|
5927
5694
|
} catch {
|
|
5928
5695
|
return false;
|
|
5929
5696
|
}
|
|
5930
5697
|
}
|
|
5931
5698
|
decodeAttributeSeams() {
|
|
5932
|
-
for (let i = 0; i < this.
|
|
5699
|
+
for (let i = 0; i < this.ac; ++i) {
|
|
5933
5700
|
const decoder = new RAnsBitDecoder();
|
|
5934
|
-
if (!decoder.startDecoding(this.
|
|
5701
|
+
if (!decoder.startDecoding(this.d)) {
|
|
5935
5702
|
return false;
|
|
5936
5703
|
}
|
|
5937
|
-
this.
|
|
5704
|
+
this._b.push(decoder);
|
|
5938
5705
|
}
|
|
5939
5706
|
return true;
|
|
5940
5707
|
}
|
|
@@ -5944,10 +5711,10 @@ var MeshEdgebreakerTraversalDecoder = class {
|
|
|
5944
5711
|
var MeshEdgebreakerTraversalPredictiveDecoder = class extends MeshEdgebreakerTraversalDecoder {
|
|
5945
5712
|
a = null;
|
|
5946
5713
|
l = 0;
|
|
5947
|
-
|
|
5948
|
-
|
|
5714
|
+
A = -1;
|
|
5715
|
+
ma = -1;
|
|
5949
5716
|
k = [];
|
|
5950
|
-
|
|
5717
|
+
sb = null;
|
|
5951
5718
|
init(decoder) {
|
|
5952
5719
|
super.init(decoder);
|
|
5953
5720
|
this.a = decoder.getCornerTable();
|
|
@@ -5967,24 +5734,24 @@ var MeshEdgebreakerTraversalPredictiveDecoder = class extends MeshEdgebreakerTra
|
|
|
5967
5734
|
return false;
|
|
5968
5735
|
}
|
|
5969
5736
|
this.k = new Array(this.l).fill(0);
|
|
5970
|
-
this.
|
|
5971
|
-
return this.
|
|
5737
|
+
this.sb = new RAnsBitDecoder();
|
|
5738
|
+
return this.sb.startDecoding(outBuffer);
|
|
5972
5739
|
}
|
|
5973
5740
|
decodeSymbol() {
|
|
5974
|
-
if (this.
|
|
5975
|
-
if (this.
|
|
5976
|
-
this.
|
|
5977
|
-
return this.
|
|
5741
|
+
if (this.ma !== -1) {
|
|
5742
|
+
if (this.sb.decodeNextBit()) {
|
|
5743
|
+
this.A = this.ma;
|
|
5744
|
+
return this.ma;
|
|
5978
5745
|
}
|
|
5979
5746
|
}
|
|
5980
|
-
this.
|
|
5981
|
-
return this.
|
|
5747
|
+
this.A = super.decodeSymbol();
|
|
5748
|
+
return this.A;
|
|
5982
5749
|
}
|
|
5983
5750
|
newActiveCornerReached(corner) {
|
|
5984
5751
|
const ct = this.a;
|
|
5985
5752
|
const next = ct.next(corner);
|
|
5986
5753
|
const prev = ct.previous(corner);
|
|
5987
|
-
switch (this.
|
|
5754
|
+
switch (this.A) {
|
|
5988
5755
|
case TOPOLOGY_C:
|
|
5989
5756
|
case TOPOLOGY_S:
|
|
5990
5757
|
this.k[ct.vertex(next)] += 1;
|
|
@@ -6008,15 +5775,15 @@ var MeshEdgebreakerTraversalPredictiveDecoder = class extends MeshEdgebreakerTra
|
|
|
6008
5775
|
default:
|
|
6009
5776
|
break;
|
|
6010
5777
|
}
|
|
6011
|
-
if (this.
|
|
5778
|
+
if (this.A === TOPOLOGY_C || this.A === TOPOLOGY_R) {
|
|
6012
5779
|
const pivot = ct.vertex(ct.next(corner));
|
|
6013
5780
|
if (this.k[pivot] < 6) {
|
|
6014
|
-
this.
|
|
5781
|
+
this.ma = TOPOLOGY_R;
|
|
6015
5782
|
} else {
|
|
6016
|
-
this.
|
|
5783
|
+
this.ma = TOPOLOGY_C;
|
|
6017
5784
|
}
|
|
6018
5785
|
} else {
|
|
6019
|
-
this.
|
|
5786
|
+
this.ma = -1;
|
|
6020
5787
|
}
|
|
6021
5788
|
}
|
|
6022
5789
|
mergeVertices(dest, source) {
|
|
@@ -6028,14 +5795,14 @@ var MeshEdgebreakerTraversalPredictiveDecoder = class extends MeshEdgebreakerTra
|
|
|
6028
5795
|
var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraversalDecoder {
|
|
6029
5796
|
a = null;
|
|
6030
5797
|
l = 0;
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
|
|
6034
|
-
|
|
5798
|
+
A = -1;
|
|
5799
|
+
Wa = -1;
|
|
5800
|
+
Xa = 2;
|
|
5801
|
+
tb = 7;
|
|
6035
5802
|
k = new Int32Array(0);
|
|
6036
|
-
|
|
5803
|
+
na = [];
|
|
6037
5804
|
// Int32Array, not number[]: read and written once per decoded symbol.
|
|
6038
|
-
|
|
5805
|
+
Ga = new Int32Array(0);
|
|
6039
5806
|
// corner -> vertex of _cornerTable, cached at init(); the array is created
|
|
6040
5807
|
// once by CornerTable.reset() before the traversal decoder is initialized and
|
|
6041
5808
|
// never replaced, so the per-symbol hot path can read it without two property
|
|
@@ -6056,11 +5823,11 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
|
|
|
6056
5823
|
if (!this.decodeAttributeSeams()) {
|
|
6057
5824
|
return false;
|
|
6058
5825
|
}
|
|
6059
|
-
outBuffer.init(this.
|
|
5826
|
+
outBuffer.init(this.d.dataHead, this.d.remainingSize);
|
|
6060
5827
|
this.k = scratchInt32Filled(this.l, 0);
|
|
6061
|
-
const numUniqueValences = this.
|
|
6062
|
-
this.
|
|
6063
|
-
this.
|
|
5828
|
+
const numUniqueValences = this.tb - this.Xa + 1;
|
|
5829
|
+
this.na = new Array(numUniqueValences);
|
|
5830
|
+
this.Ga = new Int32Array(numUniqueValences);
|
|
6064
5831
|
const pending = [];
|
|
6065
5832
|
for (let i = 0; i < numUniqueValences; ++i) {
|
|
6066
5833
|
const numSymbols = decodeVarint(outBuffer);
|
|
@@ -6071,16 +5838,16 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
|
|
|
6071
5838
|
return false;
|
|
6072
5839
|
}
|
|
6073
5840
|
if (numSymbols > 0) {
|
|
6074
|
-
this.
|
|
5841
|
+
this.na[i] = scratchUint32(numSymbols);
|
|
6075
5842
|
const scheme = outBuffer.decodeUint8();
|
|
6076
|
-
if (scheme ===
|
|
6077
|
-
if (!decodeTaggedSymbols(numSymbols, 1, outBuffer, this.
|
|
5843
|
+
if (scheme === 0 /* SYMBOL_CODING_TAGGED */) {
|
|
5844
|
+
if (!decodeTaggedSymbols(numSymbols, 1, outBuffer, this.na[i])) {
|
|
6078
5845
|
return false;
|
|
6079
5846
|
}
|
|
6080
|
-
this.
|
|
5847
|
+
this.Ga[i] = numSymbols;
|
|
6081
5848
|
continue;
|
|
6082
5849
|
}
|
|
6083
|
-
if (scheme !==
|
|
5850
|
+
if (scheme !== 1 /* SYMBOL_CODING_RAW */) {
|
|
6084
5851
|
return false;
|
|
6085
5852
|
}
|
|
6086
5853
|
const maxBitLength = outBuffer.decodeUint8();
|
|
@@ -6097,27 +5864,27 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
|
|
|
6097
5864
|
if (!decoder.startDecoding(outBuffer)) {
|
|
6098
5865
|
return false;
|
|
6099
5866
|
}
|
|
6100
|
-
pending.push({ decoder, out: this.
|
|
6101
|
-
this.
|
|
5867
|
+
pending.push({ decoder, out: this.na[i], count: numSymbols });
|
|
5868
|
+
this.Ga[i] = numSymbols;
|
|
6102
5869
|
} else {
|
|
6103
|
-
this.
|
|
6104
|
-
this.
|
|
5870
|
+
this.na[i] = new Uint32Array(0);
|
|
5871
|
+
this.Ga[i] = 0;
|
|
6105
5872
|
}
|
|
6106
5873
|
}
|
|
6107
|
-
const lockstep = pending.filter((entry) => entry.decoder.
|
|
5874
|
+
const lockstep = pending.filter((entry) => !entry.decoder.o.coarse);
|
|
6108
5875
|
let p = 0;
|
|
6109
5876
|
while (lockstep.length - p >= 3) {
|
|
6110
5877
|
const a = lockstep[p];
|
|
6111
5878
|
const b = lockstep[p + 1];
|
|
6112
5879
|
const c = lockstep[p + 2];
|
|
6113
|
-
|
|
6114
|
-
a.decoder.
|
|
5880
|
+
ransDecodeSymbolsTrioU16(
|
|
5881
|
+
a.decoder.o,
|
|
6115
5882
|
a.out,
|
|
6116
5883
|
a.count,
|
|
6117
|
-
b.decoder.
|
|
5884
|
+
b.decoder.o,
|
|
6118
5885
|
b.out,
|
|
6119
5886
|
b.count,
|
|
6120
|
-
c.decoder.
|
|
5887
|
+
c.decoder.o,
|
|
6121
5888
|
c.out,
|
|
6122
5889
|
c.count
|
|
6123
5890
|
);
|
|
@@ -6126,35 +5893,35 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
|
|
|
6126
5893
|
if (lockstep.length - p === 2) {
|
|
6127
5894
|
const a = lockstep[p];
|
|
6128
5895
|
const b = lockstep[p + 1];
|
|
6129
|
-
|
|
5896
|
+
ransDecodeSymbolsPairU16(a.decoder.o, a.out, a.count, b.decoder.o, b.out, b.count);
|
|
6130
5897
|
p += 2;
|
|
6131
5898
|
}
|
|
6132
5899
|
for (; p < lockstep.length; ++p) {
|
|
6133
|
-
lockstep[p].decoder.
|
|
5900
|
+
lockstep[p].decoder.o.decodeSymbols(lockstep[p].out, lockstep[p].count);
|
|
6134
5901
|
}
|
|
6135
5902
|
for (const entry of pending) {
|
|
6136
|
-
if (
|
|
6137
|
-
entry.decoder.
|
|
5903
|
+
if (entry.decoder.o.coarse) {
|
|
5904
|
+
entry.decoder.o.decodeSymbols(entry.out, entry.count);
|
|
6138
5905
|
}
|
|
6139
5906
|
entry.decoder.endDecoding();
|
|
6140
5907
|
}
|
|
6141
5908
|
return true;
|
|
6142
5909
|
}
|
|
6143
5910
|
decodeSymbol() {
|
|
6144
|
-
if (this.
|
|
6145
|
-
const contextCounter = --this.
|
|
5911
|
+
if (this.Wa !== -1) {
|
|
5912
|
+
const contextCounter = --this.Ga[this.Wa];
|
|
6146
5913
|
if (contextCounter < 0) {
|
|
6147
5914
|
return TOPOLOGY_INVALID;
|
|
6148
5915
|
}
|
|
6149
|
-
const symbolId = this.
|
|
5916
|
+
const symbolId = this.na[this.Wa][contextCounter];
|
|
6150
5917
|
if (symbolId > 4) {
|
|
6151
5918
|
return TOPOLOGY_INVALID;
|
|
6152
5919
|
}
|
|
6153
|
-
this.
|
|
5920
|
+
this.A = edgeBreakerSymbolToTopologyId[symbolId];
|
|
6154
5921
|
} else {
|
|
6155
|
-
this.
|
|
5922
|
+
this.A = TOPOLOGY_E;
|
|
6156
5923
|
}
|
|
6157
|
-
return this.
|
|
5924
|
+
return this.A;
|
|
6158
5925
|
}
|
|
6159
5926
|
newActiveCornerReached(corner) {
|
|
6160
5927
|
const cornerToVertex = this.j;
|
|
@@ -6163,7 +5930,7 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
|
|
|
6163
5930
|
const prev = corner % 3 === 0 ? corner + 2 : corner - 1;
|
|
6164
5931
|
const vertNext = cornerToVertex[next];
|
|
6165
5932
|
const vertPrev = cornerToVertex[prev];
|
|
6166
|
-
switch (this.
|
|
5933
|
+
switch (this.A) {
|
|
6167
5934
|
case TOPOLOGY_C:
|
|
6168
5935
|
case TOPOLOGY_S:
|
|
6169
5936
|
valences[vertNext] += 1;
|
|
@@ -6189,14 +5956,14 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
|
|
|
6189
5956
|
}
|
|
6190
5957
|
const activeValence = valences[vertNext];
|
|
6191
5958
|
let clampedValence;
|
|
6192
|
-
if (activeValence < this.
|
|
6193
|
-
clampedValence = this.
|
|
6194
|
-
} else if (activeValence > this.
|
|
6195
|
-
clampedValence = this.
|
|
5959
|
+
if (activeValence < this.Xa) {
|
|
5960
|
+
clampedValence = this.Xa;
|
|
5961
|
+
} else if (activeValence > this.tb) {
|
|
5962
|
+
clampedValence = this.tb;
|
|
6196
5963
|
} else {
|
|
6197
5964
|
clampedValence = activeValence;
|
|
6198
5965
|
}
|
|
6199
|
-
this.
|
|
5966
|
+
this.Wa = clampedValence - this.Xa;
|
|
6200
5967
|
}
|
|
6201
5968
|
mergeVertices(dest, source) {
|
|
6202
5969
|
this.k[dest] += this.k[source];
|
|
@@ -6206,53 +5973,53 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
|
|
|
6206
5973
|
// src/decoder/compression/mesh/MeshEdgebreakerDecoder.ts
|
|
6207
5974
|
var MeshEdgebreakerDecoder = class extends MeshDecoder {
|
|
6208
5975
|
// Set by initializeDecoder(), which runs before anything below is reached.
|
|
6209
|
-
|
|
5976
|
+
oa = null;
|
|
6210
5977
|
getCornerTable() {
|
|
6211
|
-
return this.
|
|
5978
|
+
return this.oa.getCornerTable();
|
|
6212
5979
|
}
|
|
6213
5980
|
getAttributeCornerTable(attId) {
|
|
6214
|
-
return this.
|
|
5981
|
+
return this.oa.getAttributeCornerTable(attId);
|
|
6215
5982
|
}
|
|
6216
5983
|
getAttributeEncodingData(attId) {
|
|
6217
|
-
return this.
|
|
5984
|
+
return this.oa.getAttributeEncodingData(attId);
|
|
6218
5985
|
}
|
|
6219
5986
|
initializeDecoder() {
|
|
6220
5987
|
const traversalDecoderType = this.buffer().decodeUint8();
|
|
6221
|
-
const TraversalDecoderClass = traversalDecoderType ===
|
|
5988
|
+
const TraversalDecoderClass = traversalDecoderType === 0 /* MESH_EDGEBREAKER_STANDARD_ENCODING */ ? MeshEdgebreakerTraversalDecoder : traversalDecoderType === 1 /* MESH_EDGEBREAKER_PREDICTIVE_ENCODING */ ? MeshEdgebreakerTraversalPredictiveDecoder : traversalDecoderType === 2 /* MESH_EDGEBREAKER_VALENCE_ENCODING */ ? MeshEdgebreakerTraversalValenceDecoder : null;
|
|
6222
5989
|
if (TraversalDecoderClass === null) {
|
|
6223
5990
|
return false;
|
|
6224
5991
|
}
|
|
6225
|
-
this.
|
|
5992
|
+
this.oa = new MeshEdgebreakerDecoderImpl(this, TraversalDecoderClass);
|
|
6226
5993
|
return true;
|
|
6227
5994
|
}
|
|
6228
5995
|
createAttributesDecoder(attDecoderId) {
|
|
6229
|
-
return this.
|
|
5996
|
+
return this.oa.createAttributesDecoder(attDecoderId);
|
|
6230
5997
|
}
|
|
6231
5998
|
decodeConnectivity() {
|
|
6232
|
-
return this.
|
|
5999
|
+
return this.oa.decodeConnectivity();
|
|
6233
6000
|
}
|
|
6234
6001
|
};
|
|
6235
6002
|
|
|
6236
6003
|
// src/decoder/compression/attributes/LinearSequencer.ts
|
|
6237
6004
|
var LinearSequencer = class {
|
|
6238
|
-
|
|
6239
|
-
|
|
6005
|
+
Ya;
|
|
6006
|
+
x = new Int32Array(0);
|
|
6240
6007
|
constructor(numPoints) {
|
|
6241
|
-
this.
|
|
6008
|
+
this.Ya = numPoints;
|
|
6242
6009
|
}
|
|
6243
6010
|
generateSequence() {
|
|
6244
|
-
if (this.
|
|
6011
|
+
if (this.Ya < 0) {
|
|
6245
6012
|
return false;
|
|
6246
6013
|
}
|
|
6247
|
-
const ids = new Int32Array(this.
|
|
6248
|
-
for (let i = 0; i < this.
|
|
6014
|
+
const ids = new Int32Array(this.Ya);
|
|
6015
|
+
for (let i = 0; i < this.Ya; ++i) {
|
|
6249
6016
|
ids[i] = i;
|
|
6250
6017
|
}
|
|
6251
|
-
this.
|
|
6018
|
+
this.x = ids;
|
|
6252
6019
|
return true;
|
|
6253
6020
|
}
|
|
6254
6021
|
getOutputPointIds() {
|
|
6255
|
-
return this.
|
|
6022
|
+
return this.x;
|
|
6256
6023
|
}
|
|
6257
6024
|
updatePointToAttributeIndexMapping(attribute) {
|
|
6258
6025
|
attribute.setIdentityMapping();
|
|
@@ -6279,7 +6046,7 @@ var MeshSequentialDecoder = class extends MeshDecoder {
|
|
|
6279
6046
|
return false;
|
|
6280
6047
|
}
|
|
6281
6048
|
if (connectivityMethod === 0) {
|
|
6282
|
-
if (!this.
|
|
6049
|
+
if (!this.Fc(numFaces)) {
|
|
6283
6050
|
return false;
|
|
6284
6051
|
}
|
|
6285
6052
|
} else {
|
|
@@ -6318,7 +6085,7 @@ var MeshSequentialDecoder = class extends MeshDecoder {
|
|
|
6318
6085
|
new SequentialAttributeDecodersController(new LinearSequencer(this.pointCloud().numPoints()))
|
|
6319
6086
|
);
|
|
6320
6087
|
}
|
|
6321
|
-
|
|
6088
|
+
Fc(numFaces) {
|
|
6322
6089
|
const numIndices = numFaces * 3;
|
|
6323
6090
|
const indicesBuffer = new Uint32Array(numIndices);
|
|
6324
6091
|
if (!decodeSymbols(numIndices, 1, this.buffer(), indicesBuffer)) {
|
|
@@ -6351,9 +6118,9 @@ var MeshSequentialDecoder = class extends MeshDecoder {
|
|
|
6351
6118
|
|
|
6352
6119
|
// src/decoder/compression/Decode.ts
|
|
6353
6120
|
function createMeshDecoder(method) {
|
|
6354
|
-
if (method ===
|
|
6121
|
+
if (method === 0 /* MESH_SEQUENTIAL_ENCODING */) {
|
|
6355
6122
|
return new MeshSequentialDecoder();
|
|
6356
|
-
} else if (method ===
|
|
6123
|
+
} else if (method === 1 /* MESH_EDGEBREAKER_ENCODING */) {
|
|
6357
6124
|
return new MeshEdgebreakerDecoder();
|
|
6358
6125
|
}
|
|
6359
6126
|
throw new Error("Unsupported mesh encoding method.");
|
|
@@ -6366,7 +6133,7 @@ var Decoder = class {
|
|
|
6366
6133
|
if (headerError !== "") {
|
|
6367
6134
|
return { mesh: null, ok: false, message: headerError };
|
|
6368
6135
|
}
|
|
6369
|
-
if (header.encoderType !==
|
|
6136
|
+
if (header.encoderType !== 1 /* TRIANGULAR_MESH */) {
|
|
6370
6137
|
return { mesh: null, ok: false, message: "Input is not a Draco triangular mesh." };
|
|
6371
6138
|
}
|
|
6372
6139
|
try {
|
|
@@ -6429,12 +6196,12 @@ var MinidracoLoader = class extends Loader {
|
|
|
6429
6196
|
mainThreadByteThreshold;
|
|
6430
6197
|
// The pool, once its module has loaded; null again after dispose() so a
|
|
6431
6198
|
// later decode spawns a fresh one.
|
|
6432
|
-
|
|
6433
|
-
|
|
6199
|
+
qa = null;
|
|
6200
|
+
ub = null;
|
|
6434
6201
|
// Set when the pool module fails to load or the pool breaks: decoding
|
|
6435
6202
|
// transparently falls back to the main thread.
|
|
6436
|
-
|
|
6437
|
-
|
|
6203
|
+
vb = false;
|
|
6204
|
+
Ha = null;
|
|
6438
6205
|
// Accepts either a LoadingManager (three-compatible form) or an options bag.
|
|
6439
6206
|
constructor(managerOrOptions) {
|
|
6440
6207
|
const options = isLoadingManager(managerOrOptions) ? { manager: managerOrOptions } : managerOrOptions ?? {};
|
|
@@ -6448,7 +6215,7 @@ var MinidracoLoader = class extends Loader {
|
|
|
6448
6215
|
// (bundlers emit it as a hashed asset), and CDN origins are handled by the
|
|
6449
6216
|
// blob bootstrap in the pool. Takes effect for the next pool spawned.
|
|
6450
6217
|
setWorkerUrl(url) {
|
|
6451
|
-
this.
|
|
6218
|
+
this.Ha = url;
|
|
6452
6219
|
return this;
|
|
6453
6220
|
}
|
|
6454
6221
|
// No-ops kept for API compatibility with THREE.DRACOLoader — minidraco has
|
|
@@ -6465,7 +6232,7 @@ var MinidracoLoader = class extends Loader {
|
|
|
6465
6232
|
}
|
|
6466
6233
|
setWorkerLimit(limit) {
|
|
6467
6234
|
this.workerLimit = limit;
|
|
6468
|
-
if (this.
|
|
6235
|
+
if (this.qa !== null) this.qa.limit = limit;
|
|
6469
6236
|
return this;
|
|
6470
6237
|
}
|
|
6471
6238
|
// Toggle the worker pool on/off. true enables the pool, keeping the current
|
|
@@ -6477,15 +6244,15 @@ var MinidracoLoader = class extends Loader {
|
|
|
6477
6244
|
// Loads the pool module and spawns the whole pool now, so the workers' JIT
|
|
6478
6245
|
// warmup overlaps the model download instead of the first decode burst.
|
|
6479
6246
|
preload() {
|
|
6480
|
-
if (this.
|
|
6481
|
-
this.
|
|
6247
|
+
if (this.dc()) {
|
|
6248
|
+
this.ec().then((pool) => pool?.spawnAll());
|
|
6482
6249
|
}
|
|
6483
6250
|
return this;
|
|
6484
6251
|
}
|
|
6485
6252
|
dispose() {
|
|
6486
|
-
if (this.
|
|
6487
|
-
this.
|
|
6488
|
-
this.
|
|
6253
|
+
if (this.qa !== null) this.qa.dispose();
|
|
6254
|
+
this.qa = null;
|
|
6255
|
+
this.ub = null;
|
|
6489
6256
|
return this;
|
|
6490
6257
|
}
|
|
6491
6258
|
load(url, onLoad, onProgress, onError) {
|
|
@@ -6525,21 +6292,21 @@ var MinidracoLoader = class extends Loader {
|
|
|
6525
6292
|
return cachedTask.promise;
|
|
6526
6293
|
}
|
|
6527
6294
|
}
|
|
6528
|
-
const geometryPending = this.
|
|
6295
|
+
const geometryPending = this.Ic(buffer, taskConfig);
|
|
6529
6296
|
_taskCache.set(buffer, { key: taskKey, promise: geometryPending });
|
|
6530
6297
|
return geometryPending;
|
|
6531
6298
|
}
|
|
6532
|
-
async
|
|
6533
|
-
if (this.
|
|
6299
|
+
async Ic(buffer, taskConfig) {
|
|
6300
|
+
if (this.dc()) {
|
|
6534
6301
|
if (buffer.byteLength > this.mainThreadByteThreshold) {
|
|
6535
|
-
const pool = await this.
|
|
6302
|
+
const pool = await this.ec();
|
|
6536
6303
|
if (pool !== null) {
|
|
6537
6304
|
try {
|
|
6538
6305
|
const raw = await pool.decode(buffer, taskConfig);
|
|
6539
|
-
return this.
|
|
6306
|
+
return this.fc(raw, taskConfig);
|
|
6540
6307
|
} catch (error) {
|
|
6541
6308
|
if (error?.isDecodeError) throw error;
|
|
6542
|
-
this.
|
|
6309
|
+
this.vb = true;
|
|
6543
6310
|
}
|
|
6544
6311
|
}
|
|
6545
6312
|
} else {
|
|
@@ -6548,28 +6315,28 @@ var MinidracoLoader = class extends Loader {
|
|
|
6548
6315
|
}
|
|
6549
6316
|
return this._decodeBuffer(buffer, taskConfig);
|
|
6550
6317
|
}
|
|
6551
|
-
|
|
6552
|
-
return this.workerLimit > 0 && typeof Worker !== "undefined" && !this.
|
|
6318
|
+
dc() {
|
|
6319
|
+
return this.workerLimit > 0 && typeof Worker !== "undefined" && !this.vb;
|
|
6553
6320
|
}
|
|
6554
6321
|
// The pool, loading its module on first use. Resolves null (and marks the
|
|
6555
6322
|
// workers broken) when the module cannot be loaded, e.g. a bundler that does
|
|
6556
6323
|
// not split dynamic imports out of dependencies.
|
|
6557
|
-
|
|
6558
|
-
this.
|
|
6559
|
-
(module) => this.
|
|
6324
|
+
ec() {
|
|
6325
|
+
this.ub ??= import("./pool.js").then(
|
|
6326
|
+
(module) => this.qa = new module.WorkerPool(this.workerLimit, this.Ha),
|
|
6560
6327
|
() => {
|
|
6561
|
-
this.
|
|
6328
|
+
this.vb = true;
|
|
6562
6329
|
return null;
|
|
6563
6330
|
}
|
|
6564
6331
|
);
|
|
6565
|
-
return this.
|
|
6332
|
+
return this.ub;
|
|
6566
6333
|
}
|
|
6567
|
-
|
|
6334
|
+
fc(raw, taskConfig) {
|
|
6568
6335
|
const geometry = new BufferGeometry();
|
|
6569
6336
|
for (const attribute of raw.attributes) {
|
|
6570
6337
|
const bufferAttribute = new BufferAttribute(attribute.array, attribute.itemSize);
|
|
6571
6338
|
if (attribute.name === "color") {
|
|
6572
|
-
this.
|
|
6339
|
+
this.Jc(bufferAttribute, taskConfig.vertexColorSpace);
|
|
6573
6340
|
bufferAttribute.normalized = !(attribute.array instanceof Float32Array);
|
|
6574
6341
|
}
|
|
6575
6342
|
geometry.setAttribute(attribute.name, bufferAttribute);
|
|
@@ -6608,12 +6375,11 @@ var MinidracoLoader = class extends Loader {
|
|
|
6608
6375
|
itemSize: attribute.numComponents
|
|
6609
6376
|
});
|
|
6610
6377
|
}
|
|
6611
|
-
const
|
|
6612
|
-
const indices = new Uint32Array(numFaces * 3);
|
|
6613
|
-
|
|
6614
|
-
return this.Ob({ indices, attributes }, taskConfig);
|
|
6378
|
+
const faces = dracoGeometry.faces_;
|
|
6379
|
+
const indices = new Uint32Array(faces.buffer, faces.byteOffset, dracoGeometry.numFaces() * 3);
|
|
6380
|
+
return this.fc({ indices, attributes }, taskConfig);
|
|
6615
6381
|
}
|
|
6616
|
-
|
|
6382
|
+
Jc(attribute, inputColorSpace) {
|
|
6617
6383
|
if (inputColorSpace !== SRGBColorSpace) return;
|
|
6618
6384
|
const _color = new Color();
|
|
6619
6385
|
for (let i = 0, il = attribute.count; i < il; i++) {
|