minidraco 0.1.1 → 0.3.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 +38 -77
- package/dist/index.d.ts +1 -99
- package/dist/index.js +1575 -1496
- package/dist/three.d.ts +23 -7
- package/dist/three.js +1691 -1535
- package/dist/worker.js +1627 -1522
- package/package.json +1 -1
package/dist/three.js
CHANGED
|
@@ -10,284 +10,158 @@ import {
|
|
|
10
10
|
SRGBColorSpace
|
|
11
11
|
} from "three";
|
|
12
12
|
|
|
13
|
-
// src/decoder/core/
|
|
14
|
-
|
|
15
|
-
|
|
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
|
+
function dataTypeLength(dt) {
|
|
30
|
+
switch (dt) {
|
|
31
|
+
case DataType.INT8:
|
|
32
|
+
case DataType.UINT8:
|
|
33
|
+
return 1;
|
|
34
|
+
case DataType.INT16:
|
|
35
|
+
case DataType.UINT16:
|
|
36
|
+
return 2;
|
|
37
|
+
case DataType.INT32:
|
|
38
|
+
case DataType.UINT32:
|
|
39
|
+
return 4;
|
|
40
|
+
case DataType.INT64:
|
|
41
|
+
case DataType.UINT64:
|
|
42
|
+
return 8;
|
|
43
|
+
case DataType.FLOAT32:
|
|
44
|
+
return 4;
|
|
45
|
+
case DataType.FLOAT64:
|
|
46
|
+
return 8;
|
|
47
|
+
case DataType.BOOL:
|
|
48
|
+
return 1;
|
|
49
|
+
default:
|
|
50
|
+
return -1;
|
|
51
|
+
}
|
|
16
52
|
}
|
|
17
53
|
|
|
18
|
-
// src/decoder/
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
54
|
+
// src/decoder/attributes/GeometryAttribute.ts
|
|
55
|
+
var Type = {
|
|
56
|
+
INVALID: -1,
|
|
57
|
+
POSITION: 0,
|
|
58
|
+
NORMAL: 1,
|
|
59
|
+
COLOR: 2,
|
|
60
|
+
TEX_COORD: 3,
|
|
61
|
+
GENERIC: 4,
|
|
62
|
+
NAMED_ATTRIBUTES_COUNT: 5
|
|
63
|
+
};
|
|
64
|
+
var GeometryAttribute = class {
|
|
65
|
+
_buffer;
|
|
66
|
+
_numComponents;
|
|
67
|
+
_dataType;
|
|
68
|
+
_normalized;
|
|
69
|
+
_byteStride;
|
|
70
|
+
_byteOffset;
|
|
71
|
+
_attributeType;
|
|
72
|
+
_uniqueId;
|
|
73
|
+
constructor() {
|
|
74
|
+
this._buffer = null;
|
|
75
|
+
this._numComponents = 1;
|
|
76
|
+
this._dataType = DataType.FLOAT32;
|
|
77
|
+
this._normalized = false;
|
|
78
|
+
this._byteStride = 0;
|
|
79
|
+
this._byteOffset = 0;
|
|
80
|
+
this._attributeType = Type.INVALID;
|
|
81
|
+
this._uniqueId = 0;
|
|
23
82
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
83
|
+
init(attributeType, buffer, numComponents, dataType, normalized, byteStride, byteOffset) {
|
|
84
|
+
this._buffer = buffer;
|
|
85
|
+
this._numComponents = numComponents;
|
|
86
|
+
this._dataType = dataType;
|
|
87
|
+
this._normalized = normalized;
|
|
88
|
+
this._byteStride = byteStride;
|
|
89
|
+
this._byteOffset = byteOffset;
|
|
90
|
+
this._attributeType = attributeType;
|
|
30
91
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if (next & 128) {
|
|
47
|
-
bytes.push(next & 127);
|
|
48
|
-
} else {
|
|
49
|
-
bytes.push(next);
|
|
50
|
-
done = true;
|
|
51
|
-
break;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
if (!done) return void 0;
|
|
55
|
-
result = bytes[bytes.length - 1];
|
|
56
|
-
for (let k = bytes.length - 2; k >= 0; k--) {
|
|
57
|
-
result = result * 128 + bytes[k];
|
|
58
|
-
}
|
|
59
|
-
return result;
|
|
92
|
+
// Returns a Uint8Array view of the buffer starting at the attribute entry.
|
|
93
|
+
getAddress(attIndex) {
|
|
94
|
+
const bytePos = this._byteOffset + this._byteStride * attIndex;
|
|
95
|
+
return this._buffer.data.subarray(bytePos);
|
|
96
|
+
}
|
|
97
|
+
copyFrom(srcAtt) {
|
|
98
|
+
this._numComponents = srcAtt._numComponents;
|
|
99
|
+
this._dataType = srcAtt._dataType;
|
|
100
|
+
this._normalized = srcAtt._normalized;
|
|
101
|
+
this._byteStride = srcAtt._byteStride;
|
|
102
|
+
this._byteOffset = srcAtt._byteOffset;
|
|
103
|
+
this._attributeType = srcAtt._attributeType;
|
|
104
|
+
this._uniqueId = srcAtt._uniqueId;
|
|
105
|
+
if (srcAtt._buffer === null) {
|
|
106
|
+
this._buffer = null;
|
|
60
107
|
} else {
|
|
61
|
-
|
|
108
|
+
if (this._buffer === null) {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
this._buffer.update(srcAtt._buffer.data, srcAtt._buffer.dataSize);
|
|
62
112
|
}
|
|
113
|
+
return true;
|
|
63
114
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const value = decodeVarintUnsigned(buffer, maxBytes);
|
|
69
|
-
if (value === void 0) return void 0;
|
|
70
|
-
if (signed) {
|
|
71
|
-
return convertSymbolToSignedInt(value);
|
|
115
|
+
resetBuffer(buffer, byteStride, byteOffset) {
|
|
116
|
+
this._buffer = buffer;
|
|
117
|
+
this._byteStride = byteStride;
|
|
118
|
+
this._byteOffset = byteOffset;
|
|
72
119
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
// src/decoder/core/DecoderBuffer.ts
|
|
77
|
-
var BitDecoder = class {
|
|
78
|
-
_bitBuffer;
|
|
79
|
-
_bitOffset;
|
|
80
|
-
_byteLength;
|
|
81
|
-
constructor() {
|
|
82
|
-
this._bitBuffer = null;
|
|
83
|
-
this._bitOffset = 0;
|
|
84
|
-
this._byteLength = 0;
|
|
120
|
+
get attributeType() {
|
|
121
|
+
return this._attributeType;
|
|
85
122
|
}
|
|
86
|
-
|
|
87
|
-
this.
|
|
88
|
-
this._byteLength = byteLength;
|
|
89
|
-
this._bitOffset = 0;
|
|
123
|
+
get dataType() {
|
|
124
|
+
return this._dataType;
|
|
90
125
|
}
|
|
91
|
-
|
|
92
|
-
return this.
|
|
126
|
+
get numComponents() {
|
|
127
|
+
return this._numComponents;
|
|
93
128
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
} else {
|
|
109
|
-
result = val >>> bitShift;
|
|
110
|
-
}
|
|
111
|
-
this._bitOffset = off + nbits;
|
|
112
|
-
return nbits === 32 ? result : result & (1 << nbits) - 1;
|
|
113
|
-
}
|
|
114
|
-
let value = 0;
|
|
115
|
-
let bitsRead = 0;
|
|
116
|
-
let currOff = off;
|
|
117
|
-
while (bitsRead < nbits) {
|
|
118
|
-
const bOff = currOff >> 3;
|
|
119
|
-
if (bOff >= this._byteLength) break;
|
|
120
|
-
const bShift = currOff & 7;
|
|
121
|
-
const bitsAvail = 8 - bShift;
|
|
122
|
-
const bitsNeeded = nbits - bitsRead;
|
|
123
|
-
const bitsToRead = bitsAvail < bitsNeeded ? bitsAvail : bitsNeeded;
|
|
124
|
-
const mask = (1 << bitsToRead) - 1;
|
|
125
|
-
value |= (buf[bOff] >> bShift & mask) << bitsRead;
|
|
126
|
-
bitsRead += bitsToRead;
|
|
127
|
-
currOff += bitsToRead;
|
|
128
|
-
}
|
|
129
|
-
this._bitOffset = currOff;
|
|
130
|
-
return value;
|
|
129
|
+
get buffer() {
|
|
130
|
+
return this._buffer;
|
|
131
|
+
}
|
|
132
|
+
get byteStride() {
|
|
133
|
+
return this._byteStride;
|
|
134
|
+
}
|
|
135
|
+
get byteOffset() {
|
|
136
|
+
return this._byteOffset;
|
|
137
|
+
}
|
|
138
|
+
get uniqueId() {
|
|
139
|
+
return this._uniqueId;
|
|
140
|
+
}
|
|
141
|
+
set uniqueId(id) {
|
|
142
|
+
this._uniqueId = id;
|
|
131
143
|
}
|
|
132
144
|
};
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
_bitstreamVersion;
|
|
145
|
+
|
|
146
|
+
// src/decoder/point_cloud/PointCloud.ts
|
|
147
|
+
var NAMED_ATTRIBUTES_COUNT = 8;
|
|
148
|
+
var PointCloud = class {
|
|
149
|
+
num_points_;
|
|
150
|
+
attributes_;
|
|
151
|
+
named_attribute_index_;
|
|
141
152
|
constructor() {
|
|
142
|
-
this.
|
|
143
|
-
this.
|
|
144
|
-
this.
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
this._bitMode = false;
|
|
148
|
-
this._bitstreamVersion = 0;
|
|
149
|
-
}
|
|
150
|
-
init(data, dataSize, version) {
|
|
151
|
-
if (data instanceof ArrayBuffer) {
|
|
152
|
-
this._data = new Uint8Array(data);
|
|
153
|
-
} else if (data instanceof Uint8Array) {
|
|
154
|
-
this._data = data;
|
|
155
|
-
} else {
|
|
156
|
-
this._data = new Uint8Array(data);
|
|
153
|
+
this.num_points_ = 0;
|
|
154
|
+
this.attributes_ = [];
|
|
155
|
+
this.named_attribute_index_ = [];
|
|
156
|
+
for (let i = 0; i < NAMED_ATTRIBUTES_COUNT; ++i) {
|
|
157
|
+
this.named_attribute_index_.push([]);
|
|
157
158
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
this._bitstreamVersion = version;
|
|
159
|
+
}
|
|
160
|
+
numNamedAttributes(type) {
|
|
161
|
+
if (type < 0 || type >= NAMED_ATTRIBUTES_COUNT) {
|
|
162
|
+
return 0;
|
|
163
163
|
}
|
|
164
|
-
|
|
165
|
-
// Typed little-endian reads.
|
|
166
|
-
decodeUint8() {
|
|
167
|
-
if (this._pos + 1 > this._dataSize) return void 0;
|
|
168
|
-
const val = this._data[this._pos];
|
|
169
|
-
this._pos += 1;
|
|
170
|
-
return val;
|
|
171
|
-
}
|
|
172
|
-
decodeInt8() {
|
|
173
|
-
if (this._pos + 1 > this._dataSize) return void 0;
|
|
174
|
-
const val = this._dataView.getInt8(this._pos);
|
|
175
|
-
this._pos += 1;
|
|
176
|
-
return val;
|
|
177
|
-
}
|
|
178
|
-
decodeUint16() {
|
|
179
|
-
if (this._pos + 2 > this._dataSize) return void 0;
|
|
180
|
-
const val = this._dataView.getUint16(this._pos, true);
|
|
181
|
-
this._pos += 2;
|
|
182
|
-
return val;
|
|
183
|
-
}
|
|
184
|
-
decodeUint32() {
|
|
185
|
-
if (this._pos + 4 > this._dataSize) return void 0;
|
|
186
|
-
const val = this._dataView.getUint32(this._pos, true);
|
|
187
|
-
this._pos += 4;
|
|
188
|
-
return val;
|
|
189
|
-
}
|
|
190
|
-
decodeInt32() {
|
|
191
|
-
if (this._pos + 4 > this._dataSize) return void 0;
|
|
192
|
-
const val = this._dataView.getInt32(this._pos, true);
|
|
193
|
-
this._pos += 4;
|
|
194
|
-
return val;
|
|
195
|
-
}
|
|
196
|
-
decodeFloat32() {
|
|
197
|
-
if (this._pos + 4 > this._dataSize) return void 0;
|
|
198
|
-
const val = this._dataView.getFloat32(this._pos, true);
|
|
199
|
-
this._pos += 4;
|
|
200
|
-
return val;
|
|
201
|
-
}
|
|
202
|
-
decodeUint64() {
|
|
203
|
-
if (this._pos + 8 > this._dataSize) return void 0;
|
|
204
|
-
const lo = this._dataView.getUint32(this._pos, true);
|
|
205
|
-
const hi = this._dataView.getUint32(this._pos + 4, true);
|
|
206
|
-
this._pos += 8;
|
|
207
|
-
return hi * 4294967296 + lo;
|
|
208
|
-
}
|
|
209
|
-
decodeBytes(size) {
|
|
210
|
-
if (this._pos + size > this._dataSize) return void 0;
|
|
211
|
-
const result = this._data.slice(this._pos, this._pos + size);
|
|
212
|
-
this._pos += size;
|
|
213
|
-
return result;
|
|
214
|
-
}
|
|
215
|
-
startBitDecoding(decodeSize) {
|
|
216
|
-
let outSize = 0;
|
|
217
|
-
if (decodeSize) {
|
|
218
|
-
if (this._bitstreamVersion < bitstreamVersion(2, 2)) {
|
|
219
|
-
outSize = this.decodeUint64();
|
|
220
|
-
if (outSize === void 0) return void 0;
|
|
221
|
-
} else {
|
|
222
|
-
outSize = decodeVarint(this, false);
|
|
223
|
-
if (outSize === void 0) return void 0;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
this._bitMode = true;
|
|
227
|
-
this._bitDecoder.reset(this._data.subarray(this._pos), this._dataSize - this._pos);
|
|
228
|
-
return outSize;
|
|
229
|
-
}
|
|
230
|
-
endBitDecoding() {
|
|
231
|
-
this._bitMode = false;
|
|
232
|
-
const bitsDecoded = this._bitDecoder.bitsDecoded();
|
|
233
|
-
const bytesDecoded = Math.ceil(bitsDecoded / 8);
|
|
234
|
-
this._pos += bytesDecoded;
|
|
235
|
-
}
|
|
236
|
-
decodeLeastSignificantBits32(nbits) {
|
|
237
|
-
if (!this._bitMode) return void 0;
|
|
238
|
-
return this._bitDecoder.getBits(nbits);
|
|
239
|
-
}
|
|
240
|
-
decodeVarintUint32() {
|
|
241
|
-
return decodeVarint(this, false);
|
|
242
|
-
}
|
|
243
|
-
decodeVarintUint64() {
|
|
244
|
-
return decodeVarint(this, false);
|
|
245
|
-
}
|
|
246
|
-
advance(bytes) {
|
|
247
|
-
this._pos += bytes;
|
|
248
|
-
}
|
|
249
|
-
get bitstreamVersion() {
|
|
250
|
-
return this._bitstreamVersion;
|
|
251
|
-
}
|
|
252
|
-
set bitstreamVersion(v) {
|
|
253
|
-
this._bitstreamVersion = v;
|
|
254
|
-
}
|
|
255
|
-
get data() {
|
|
256
|
-
return this._data;
|
|
257
|
-
}
|
|
258
|
-
get dataHead() {
|
|
259
|
-
return this._data.subarray(this._pos);
|
|
260
|
-
}
|
|
261
|
-
get remainingSize() {
|
|
262
|
-
return this._dataSize - this._pos;
|
|
263
|
-
}
|
|
264
|
-
get decodedSize() {
|
|
265
|
-
return this._pos;
|
|
266
|
-
}
|
|
267
|
-
get bitDecoderActive() {
|
|
268
|
-
return this._bitMode;
|
|
269
|
-
}
|
|
270
|
-
};
|
|
271
|
-
|
|
272
|
-
// src/decoder/point_cloud/PointCloud.ts
|
|
273
|
-
var NAMED_ATTRIBUTES_COUNT = 8;
|
|
274
|
-
var PointCloud = class {
|
|
275
|
-
num_points_;
|
|
276
|
-
attributes_;
|
|
277
|
-
named_attribute_index_;
|
|
278
|
-
constructor() {
|
|
279
|
-
this.num_points_ = 0;
|
|
280
|
-
this.attributes_ = [];
|
|
281
|
-
this.named_attribute_index_ = [];
|
|
282
|
-
for (let i = 0; i < NAMED_ATTRIBUTES_COUNT; ++i) {
|
|
283
|
-
this.named_attribute_index_.push([]);
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
numNamedAttributes(type) {
|
|
287
|
-
if (type < 0 || type >= NAMED_ATTRIBUTES_COUNT) {
|
|
288
|
-
return 0;
|
|
289
|
-
}
|
|
290
|
-
return this.named_attribute_index_[type].length;
|
|
164
|
+
return this.named_attribute_index_[type].length;
|
|
291
165
|
}
|
|
292
166
|
getNamedAttributeId(type, i) {
|
|
293
167
|
if (i === void 0) i = 0;
|
|
@@ -368,25 +242,17 @@ var Mesh = class extends PointCloud {
|
|
|
368
242
|
this.numFaces_ = 0;
|
|
369
243
|
this.attribute_data_ = [];
|
|
370
244
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
const grown = new Int32Array(numFaces * 3);
|
|
376
|
-
grown.set(this.faces_);
|
|
377
|
-
this.faces_ = grown;
|
|
378
|
-
}
|
|
379
|
-
addFace(face) {
|
|
380
|
-
const f = this.numFaces_;
|
|
381
|
-
this._ensureFaceCapacity(f + 1);
|
|
382
|
-
const o = f * 3;
|
|
383
|
-
this.faces_[o] = face[0];
|
|
384
|
-
this.faces_[o + 1] = face[1];
|
|
385
|
-
this.faces_[o + 2] = face[2];
|
|
386
|
-
this.numFaces_ = f + 1;
|
|
387
|
-
}
|
|
245
|
+
// Sizes faces_ to hold numFaces faces. Called once per decode, before any
|
|
246
|
+
// face index is written (edgebreaker: _assignPointsToCorners; sequential:
|
|
247
|
+
// decodeConnectivity), so the buffer is allocated exactly here — the
|
|
248
|
+
// decoders fill faces_ directly rather than appending face-by-face.
|
|
388
249
|
setNumFaces(numFaces) {
|
|
389
|
-
|
|
250
|
+
const needed = numFaces * 3;
|
|
251
|
+
if (this.faces_.length < needed) {
|
|
252
|
+
const grown = new Int32Array(needed);
|
|
253
|
+
grown.set(this.faces_);
|
|
254
|
+
this.faces_ = grown;
|
|
255
|
+
}
|
|
390
256
|
this.numFaces_ = numFaces;
|
|
391
257
|
}
|
|
392
258
|
numFaces() {
|
|
@@ -405,1248 +271,1401 @@ var Mesh = class extends PointCloud {
|
|
|
405
271
|
}
|
|
406
272
|
};
|
|
407
273
|
|
|
408
|
-
// src/decoder/
|
|
409
|
-
var
|
|
410
|
-
|
|
411
|
-
var kDracoMeshBitstreamVersionMajor = 2;
|
|
412
|
-
var kDracoMeshBitstreamVersionMinor = 2;
|
|
413
|
-
function DRACO_BITSTREAM_VERSION(major, minor) {
|
|
414
|
-
return major << 8 | minor;
|
|
415
|
-
}
|
|
416
|
-
var EncodedGeometryType = {
|
|
417
|
-
INVALID_GEOMETRY_TYPE: -1,
|
|
418
|
-
POINT_CLOUD: 0,
|
|
419
|
-
TRIANGULAR_MESH: 1,
|
|
420
|
-
NUM_ENCODED_GEOMETRY_TYPES: 2
|
|
421
|
-
};
|
|
422
|
-
var MeshEncoderMethod = {
|
|
423
|
-
MESH_SEQUENTIAL_ENCODING: 0,
|
|
424
|
-
MESH_EDGEBREAKER_ENCODING: 1
|
|
425
|
-
};
|
|
426
|
-
var SequentialAttributeEncoderType = {
|
|
427
|
-
SEQUENTIAL_ATTRIBUTE_ENCODER_GENERIC: 0,
|
|
428
|
-
SEQUENTIAL_ATTRIBUTE_ENCODER_INTEGER: 1,
|
|
429
|
-
SEQUENTIAL_ATTRIBUTE_ENCODER_QUANTIZATION: 2,
|
|
430
|
-
SEQUENTIAL_ATTRIBUTE_ENCODER_NORMALS: 3
|
|
431
|
-
};
|
|
432
|
-
var PredictionSchemeMethod = {
|
|
433
|
-
PREDICTION_NONE: -2,
|
|
434
|
-
PREDICTION_UNDEFINED: -1,
|
|
435
|
-
PREDICTION_DIFFERENCE: 0,
|
|
436
|
-
MESH_PREDICTION_PARALLELOGRAM: 1,
|
|
437
|
-
MESH_PREDICTION_MULTI_PARALLELOGRAM: 2,
|
|
438
|
-
MESH_PREDICTION_TEX_COORDS_DEPRECATED: 3,
|
|
439
|
-
MESH_PREDICTION_CONSTRAINED_MULTI_PARALLELOGRAM: 4,
|
|
440
|
-
MESH_PREDICTION_TEX_COORDS_PORTABLE: 5,
|
|
441
|
-
MESH_PREDICTION_GEOMETRIC_NORMAL: 6,
|
|
442
|
-
NUM_PREDICTION_SCHEMES: 7
|
|
443
|
-
};
|
|
444
|
-
var PredictionSchemeTransformType = {
|
|
445
|
-
PREDICTION_TRANSFORM_NONE: -1,
|
|
446
|
-
PREDICTION_TRANSFORM_DELTA: 0,
|
|
447
|
-
PREDICTION_TRANSFORM_WRAP: 1,
|
|
448
|
-
PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON: 2,
|
|
449
|
-
PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON_CANONICALIZED: 3,
|
|
450
|
-
NUM_PREDICTION_SCHEME_TRANSFORM_TYPES: 4
|
|
451
|
-
};
|
|
452
|
-
var MeshTraversalMethod = {
|
|
453
|
-
MESH_TRAVERSAL_DEPTH_FIRST: 0,
|
|
454
|
-
MESH_TRAVERSAL_PREDICTION_DEGREE: 1,
|
|
455
|
-
NUM_TRAVERSAL_METHODS: 2
|
|
456
|
-
};
|
|
457
|
-
var MeshEdgebreakerConnectivityEncodingMethod = {
|
|
458
|
-
MESH_EDGEBREAKER_STANDARD_ENCODING: 0,
|
|
459
|
-
MESH_EDGEBREAKER_PREDICTIVE_ENCODING: 1,
|
|
460
|
-
// Deprecated.
|
|
461
|
-
MESH_EDGEBREAKER_VALENCE_ENCODING: 2
|
|
462
|
-
};
|
|
463
|
-
var DracoHeader = class {
|
|
464
|
-
dracoString;
|
|
465
|
-
versionMajor;
|
|
466
|
-
versionMinor;
|
|
467
|
-
encoderType;
|
|
468
|
-
encoderMethod;
|
|
469
|
-
flags;
|
|
470
|
-
constructor() {
|
|
471
|
-
this.dracoString = new Int8Array(5);
|
|
472
|
-
this.versionMajor = 0;
|
|
473
|
-
this.versionMinor = 0;
|
|
474
|
-
this.encoderType = 0;
|
|
475
|
-
this.encoderMethod = 0;
|
|
476
|
-
this.flags = 0;
|
|
477
|
-
}
|
|
478
|
-
};
|
|
479
|
-
var NormalPredictionMode = {
|
|
480
|
-
ONE_TRIANGLE: 0,
|
|
481
|
-
// To be deprecated.
|
|
482
|
-
TRIANGLE_AREA: 1
|
|
483
|
-
};
|
|
484
|
-
var SymbolCodingMethod = {
|
|
485
|
-
SYMBOL_CODING_TAGGED: 0,
|
|
486
|
-
SYMBOL_CODING_RAW: 1,
|
|
487
|
-
NUM_SYMBOL_CODING_METHODS: 2
|
|
488
|
-
};
|
|
489
|
-
var METADATA_FLAG_MASK = 32768;
|
|
490
|
-
|
|
491
|
-
// src/decoder/compression/config/DracoOptions.ts
|
|
492
|
-
var DracoOptions = class {
|
|
493
|
-
_globalOptions;
|
|
494
|
-
_attributeOptions;
|
|
274
|
+
// src/decoder/core/DataBuffer.ts
|
|
275
|
+
var DataBuffer = class {
|
|
276
|
+
_data;
|
|
495
277
|
constructor() {
|
|
496
|
-
this.
|
|
497
|
-
this._attributeOptions = /* @__PURE__ */ new Map();
|
|
278
|
+
this._data = new Uint8Array(0);
|
|
498
279
|
}
|
|
499
|
-
|
|
500
|
-
if (
|
|
501
|
-
|
|
280
|
+
update(data, size, offset = 0) {
|
|
281
|
+
if (data === null || data === void 0) {
|
|
282
|
+
if (size + offset < 0) return false;
|
|
283
|
+
this._resize(size + offset);
|
|
284
|
+
} else {
|
|
285
|
+
if (size < 0) return false;
|
|
286
|
+
if (size + offset > this._data.length) {
|
|
287
|
+
this._resize(size + offset);
|
|
288
|
+
}
|
|
289
|
+
const view = data;
|
|
290
|
+
const src = new Uint8Array(view.buffer || data, view.byteOffset || 0, size);
|
|
291
|
+
this._data.set(src, offset);
|
|
502
292
|
}
|
|
503
|
-
return
|
|
293
|
+
return true;
|
|
504
294
|
}
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
return this._attributeOptions.get(attKey);
|
|
508
|
-
}
|
|
509
|
-
return null;
|
|
295
|
+
resize(newSize) {
|
|
296
|
+
this._resize(newSize);
|
|
510
297
|
}
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
return
|
|
298
|
+
write(bytePos, inArray, dataSize) {
|
|
299
|
+
if (inArray instanceof Uint8Array) {
|
|
300
|
+
this._data.set(inArray.length === dataSize ? inArray : inArray.subarray(0, dataSize), bytePos);
|
|
301
|
+
return;
|
|
515
302
|
}
|
|
516
|
-
|
|
303
|
+
const view = inArray;
|
|
304
|
+
const src = new Uint8Array(view.buffer || inArray, view.byteOffset || 0, dataSize);
|
|
305
|
+
this._data.set(src, bytePos);
|
|
517
306
|
}
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
// src/decoder/compression/config/DecoderOptions.ts
|
|
521
|
-
var DecoderOptions = class extends DracoOptions {
|
|
522
|
-
constructor() {
|
|
523
|
-
super();
|
|
307
|
+
get data() {
|
|
308
|
+
return this._data;
|
|
524
309
|
}
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
// src/decoder/core/Status.ts
|
|
528
|
-
var StatusCode = {
|
|
529
|
-
OK: 0,
|
|
530
|
-
DRACO_ERROR: -1,
|
|
531
|
-
IO_ERROR: -2,
|
|
532
|
-
INVALID_PARAMETER: -3,
|
|
533
|
-
UNSUPPORTED_VERSION: -4,
|
|
534
|
-
UNKNOWN_VERSION: -5,
|
|
535
|
-
UNSUPPORTED_FEATURE: -6
|
|
536
|
-
};
|
|
537
|
-
var Status = class {
|
|
538
|
-
code;
|
|
539
|
-
errorMsg;
|
|
540
|
-
constructor(code = StatusCode.OK, errorMsg = "") {
|
|
541
|
-
this.code = code;
|
|
542
|
-
this.errorMsg = errorMsg;
|
|
310
|
+
get dataSize() {
|
|
311
|
+
return this._data.length;
|
|
543
312
|
}
|
|
544
|
-
|
|
545
|
-
|
|
313
|
+
_resize(newSize) {
|
|
314
|
+
if (newSize === this._data.length) return;
|
|
315
|
+
const newData = new Uint8Array(newSize);
|
|
316
|
+
newData.set(this._data.subarray(0, Math.min(this._data.length, newSize)));
|
|
317
|
+
this._data = newData;
|
|
546
318
|
}
|
|
547
319
|
};
|
|
548
|
-
function okStatus() {
|
|
549
|
-
return new Status(StatusCode.OK);
|
|
550
|
-
}
|
|
551
320
|
|
|
552
|
-
// src/decoder/
|
|
553
|
-
var
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
321
|
+
// src/decoder/attributes/GeometryIndices.ts
|
|
322
|
+
var kInvalidAttributeValueIndex = 4294967295 >>> 0;
|
|
323
|
+
|
|
324
|
+
// src/decoder/attributes/PointAttribute.ts
|
|
325
|
+
var PointAttribute = class extends GeometryAttribute {
|
|
326
|
+
_identityMapping;
|
|
327
|
+
_numUniqueEntries;
|
|
328
|
+
_indicesMap;
|
|
329
|
+
_attributeBuffer;
|
|
330
|
+
_attributeTransformData;
|
|
331
|
+
// Lazily-created cached views over the attribute buffer.
|
|
332
|
+
_cachedFloat32View;
|
|
333
|
+
_cachedFloat32Buffer;
|
|
334
|
+
_cachedInt32View;
|
|
335
|
+
_cachedInt32Buffer;
|
|
336
|
+
_cachedUint32View;
|
|
337
|
+
_cachedUint32Buffer;
|
|
338
|
+
_cachedUint16View;
|
|
339
|
+
_cachedUint16Buffer;
|
|
340
|
+
_cachedInt16View;
|
|
341
|
+
_cachedInt16Buffer;
|
|
342
|
+
_cachedUint8View;
|
|
343
|
+
_cachedUint8Buffer;
|
|
344
|
+
_cachedInt8View;
|
|
345
|
+
_cachedInt8Buffer;
|
|
346
|
+
_cachedFloat64View;
|
|
347
|
+
_cachedFloat64Buffer;
|
|
348
|
+
_cachedDataView;
|
|
349
|
+
_cachedDVBuffer;
|
|
350
|
+
constructor(geometryAttribute) {
|
|
351
|
+
super();
|
|
352
|
+
this._identityMapping = false;
|
|
353
|
+
this._numUniqueEntries = 0;
|
|
354
|
+
this._indicesMap = [];
|
|
355
|
+
this._attributeBuffer = null;
|
|
356
|
+
this._attributeTransformData = null;
|
|
357
|
+
if (geometryAttribute instanceof GeometryAttribute) {
|
|
358
|
+
this._buffer = geometryAttribute._buffer;
|
|
359
|
+
this._numComponents = geometryAttribute._numComponents;
|
|
360
|
+
this._dataType = geometryAttribute._dataType;
|
|
361
|
+
this._normalized = geometryAttribute._normalized;
|
|
362
|
+
this._byteStride = geometryAttribute._byteStride;
|
|
363
|
+
this._byteOffset = geometryAttribute._byteOffset;
|
|
364
|
+
this._attributeType = geometryAttribute._attributeType;
|
|
365
|
+
this._uniqueId = geometryAttribute._uniqueId;
|
|
366
|
+
}
|
|
558
367
|
}
|
|
559
|
-
//
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
368
|
+
// Intentionally shadows GeometryAttribute.init with a different signature (matches draco.js / C++ source).
|
|
369
|
+
// @ts-expect-error -- signature intentionally differs from the base class, as in the source.
|
|
370
|
+
init(attributeType, numComponents, dataType, normalized, numAttributeValues) {
|
|
371
|
+
this._attributeBuffer = new DataBuffer();
|
|
372
|
+
const byteStride = dataTypeLength(dataType) * numComponents;
|
|
373
|
+
super.init(attributeType, this._attributeBuffer, numComponents, dataType, normalized, byteStride, 0);
|
|
374
|
+
this.reset(numAttributeValues);
|
|
375
|
+
this.setIdentityMapping();
|
|
376
|
+
}
|
|
377
|
+
reset(numAttributeValues) {
|
|
378
|
+
if (this._attributeBuffer === null) {
|
|
379
|
+
this._attributeBuffer = new DataBuffer();
|
|
565
380
|
}
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
381
|
+
const entrySize = dataTypeLength(this.dataType) * this.numComponents;
|
|
382
|
+
this._attributeBuffer.update(null, numAttributeValues * entrySize);
|
|
383
|
+
this.resetBuffer(this._attributeBuffer, entrySize, 0);
|
|
384
|
+
this._numUniqueEntries = numAttributeValues;
|
|
385
|
+
return true;
|
|
386
|
+
}
|
|
387
|
+
get size() {
|
|
388
|
+
return this._numUniqueEntries;
|
|
389
|
+
}
|
|
390
|
+
mappedIndex(pointIndex) {
|
|
391
|
+
if (this._identityMapping) {
|
|
392
|
+
return pointIndex;
|
|
573
393
|
}
|
|
574
|
-
return this.
|
|
394
|
+
return this._indicesMap[pointIndex];
|
|
575
395
|
}
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
396
|
+
get isMappingIdentity() {
|
|
397
|
+
return this._identityMapping;
|
|
398
|
+
}
|
|
399
|
+
get indicesMapSize() {
|
|
400
|
+
if (this._identityMapping) {
|
|
401
|
+
return 0;
|
|
581
402
|
}
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
403
|
+
return this._indicesMap.length;
|
|
404
|
+
}
|
|
405
|
+
// Direct access to the explicit point->value index map (Uint32Array after
|
|
406
|
+
// setExplicitMapping). Lets hot mapping loops write entries without a
|
|
407
|
+
// per-entry setPointMapEntry() dispatch.
|
|
408
|
+
get indicesMap() {
|
|
409
|
+
return this._indicesMap;
|
|
410
|
+
}
|
|
411
|
+
// Implicit mapping: point index equals attribute entry index.
|
|
412
|
+
setIdentityMapping() {
|
|
413
|
+
this._identityMapping = true;
|
|
414
|
+
this._indicesMap = [];
|
|
415
|
+
}
|
|
416
|
+
setExplicitMapping(numPoints) {
|
|
417
|
+
this._identityMapping = false;
|
|
418
|
+
this._indicesMap = new Uint32Array(numPoints);
|
|
419
|
+
this._indicesMap.fill(kInvalidAttributeValueIndex);
|
|
420
|
+
}
|
|
421
|
+
// Like setExplicitMapping but skips the invalid-index fill. Only for callers
|
|
422
|
+
// that provably write every entry right away (the fill was ~4% of decode
|
|
423
|
+
// time on primitive-heavy files). The array still starts zeroed by the
|
|
424
|
+
// engine, so a buggy caller reads valid-looking zeros — hence opt-in.
|
|
425
|
+
setExplicitMappingUnfilled(numPoints) {
|
|
426
|
+
this._identityMapping = false;
|
|
427
|
+
this._indicesMap = new Uint32Array(numPoints);
|
|
428
|
+
}
|
|
429
|
+
setAttributeTransformData(transformData) {
|
|
430
|
+
this._attributeTransformData = transformData;
|
|
431
|
+
}
|
|
432
|
+
// Mirrors C++ PointAttribute::ConvertValue<T>().
|
|
433
|
+
convertValue(attIndex, outVal) {
|
|
434
|
+
const bytePos = this._byteOffset + this._byteStride * attIndex;
|
|
435
|
+
const bufData = this._buffer.data;
|
|
436
|
+
const dt = this._dataType;
|
|
437
|
+
const nc = this._numComponents;
|
|
438
|
+
if (dt === DataType.FLOAT32) {
|
|
439
|
+
if (this._cachedFloat32View === void 0 || this._cachedFloat32Buffer !== bufData.buffer) {
|
|
440
|
+
this._cachedFloat32Buffer = bufData.buffer;
|
|
441
|
+
this._cachedFloat32View = new Float32Array(bufData.buffer);
|
|
442
|
+
}
|
|
443
|
+
const baseIndex = bufData.byteOffset + bytePos >> 2;
|
|
444
|
+
for (let i = 0; i < nc; ++i) {
|
|
445
|
+
outVal[i] = this._cachedFloat32View[baseIndex + i];
|
|
446
|
+
}
|
|
447
|
+
return;
|
|
585
448
|
}
|
|
586
|
-
|
|
587
|
-
if (
|
|
588
|
-
|
|
449
|
+
if (dt === DataType.INT32) {
|
|
450
|
+
if (this._cachedInt32View === void 0 || this._cachedInt32Buffer !== bufData.buffer) {
|
|
451
|
+
this._cachedInt32Buffer = bufData.buffer;
|
|
452
|
+
this._cachedInt32View = new Int32Array(bufData.buffer);
|
|
453
|
+
}
|
|
454
|
+
const baseIndex = bufData.byteOffset + bytePos >> 2;
|
|
455
|
+
for (let i = 0; i < nc; ++i) {
|
|
456
|
+
outVal[i] = this._cachedInt32View[baseIndex + i];
|
|
589
457
|
}
|
|
458
|
+
return;
|
|
590
459
|
}
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
460
|
+
if (dt === DataType.UINT32) {
|
|
461
|
+
if (this._cachedUint32View === void 0 || this._cachedUint32Buffer !== bufData.buffer) {
|
|
462
|
+
this._cachedUint32Buffer = bufData.buffer;
|
|
463
|
+
this._cachedUint32View = new Uint32Array(bufData.buffer);
|
|
464
|
+
}
|
|
465
|
+
const baseIndex = bufData.byteOffset + bytePos >> 2;
|
|
466
|
+
for (let i = 0; i < nc; ++i) {
|
|
467
|
+
outVal[i] = this._cachedUint32View[baseIndex + i];
|
|
468
|
+
}
|
|
469
|
+
return;
|
|
594
470
|
}
|
|
595
|
-
if (
|
|
596
|
-
|
|
471
|
+
if (this._cachedDataView === void 0 || this._cachedDVBuffer !== bufData.buffer) {
|
|
472
|
+
this._cachedDVBuffer = bufData.buffer;
|
|
473
|
+
this._cachedDataView = new DataView(bufData.buffer, bufData.byteOffset, bufData.byteLength);
|
|
597
474
|
}
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
475
|
+
const dv = this._cachedDataView;
|
|
476
|
+
for (let i = 0; i < nc; ++i) {
|
|
477
|
+
switch (dt) {
|
|
478
|
+
case DataType.INT8:
|
|
479
|
+
outVal[i] = dv.getInt8(bytePos + i);
|
|
480
|
+
break;
|
|
481
|
+
case DataType.UINT8:
|
|
482
|
+
outVal[i] = dv.getUint8(bytePos + i);
|
|
483
|
+
break;
|
|
484
|
+
case DataType.INT16:
|
|
485
|
+
outVal[i] = dv.getInt16(bytePos + i * 2, true);
|
|
486
|
+
break;
|
|
487
|
+
case DataType.UINT16:
|
|
488
|
+
outVal[i] = dv.getUint16(bytePos + i * 2, true);
|
|
489
|
+
break;
|
|
490
|
+
case DataType.INT32:
|
|
491
|
+
outVal[i] = dv.getInt32(bytePos + i * 4, true);
|
|
492
|
+
break;
|
|
493
|
+
case DataType.UINT32:
|
|
494
|
+
outVal[i] = dv.getUint32(bytePos + i * 4, true);
|
|
495
|
+
break;
|
|
496
|
+
case DataType.FLOAT64:
|
|
497
|
+
outVal[i] = dv.getFloat64(bytePos + i * 8, true);
|
|
498
|
+
break;
|
|
499
|
+
default:
|
|
500
|
+
outVal[i] = 0;
|
|
501
|
+
break;
|
|
604
502
|
}
|
|
605
503
|
}
|
|
606
|
-
return true;
|
|
607
504
|
}
|
|
608
|
-
//
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
505
|
+
// Flat-array extraction of all values into one output typed array (avoids the
|
|
506
|
+
// per-point temp-array copy via cached typed-array views over the buffer).
|
|
507
|
+
extractTo(OutputTypedArray, numPoints) {
|
|
508
|
+
const numComponents = this._numComponents;
|
|
509
|
+
const array = new OutputTypedArray(numPoints * numComponents);
|
|
510
|
+
if (this._buffer == null || this._buffer.data == null || numPoints === 0) {
|
|
511
|
+
return array;
|
|
612
512
|
}
|
|
613
|
-
const
|
|
614
|
-
|
|
615
|
-
|
|
513
|
+
const bufData = this._buffer.data;
|
|
514
|
+
const dt = this._dataType;
|
|
515
|
+
const isIdentity = this._identityMapping;
|
|
516
|
+
const indicesMap = this._indicesMap;
|
|
517
|
+
const byteStride = this._byteStride;
|
|
518
|
+
const byteOffset = this._byteOffset;
|
|
519
|
+
let srcView = null;
|
|
520
|
+
let shift = 0;
|
|
521
|
+
if (dt === DataType.FLOAT32) {
|
|
522
|
+
if (this._cachedFloat32View === void 0 || this._cachedFloat32Buffer !== bufData.buffer) {
|
|
523
|
+
this._cachedFloat32Buffer = bufData.buffer;
|
|
524
|
+
this._cachedFloat32View = new Float32Array(bufData.buffer);
|
|
525
|
+
}
|
|
526
|
+
srcView = this._cachedFloat32View;
|
|
527
|
+
shift = 2;
|
|
528
|
+
} else if (dt === DataType.INT32) {
|
|
529
|
+
if (this._cachedInt32View === void 0 || this._cachedInt32Buffer !== bufData.buffer) {
|
|
530
|
+
this._cachedInt32Buffer = bufData.buffer;
|
|
531
|
+
this._cachedInt32View = new Int32Array(bufData.buffer);
|
|
532
|
+
}
|
|
533
|
+
srcView = this._cachedInt32View;
|
|
534
|
+
shift = 2;
|
|
535
|
+
} else if (dt === DataType.UINT32) {
|
|
536
|
+
if (this._cachedUint32View === void 0 || this._cachedUint32Buffer !== bufData.buffer) {
|
|
537
|
+
this._cachedUint32Buffer = bufData.buffer;
|
|
538
|
+
this._cachedUint32View = new Uint32Array(bufData.buffer);
|
|
539
|
+
}
|
|
540
|
+
srcView = this._cachedUint32View;
|
|
541
|
+
shift = 2;
|
|
542
|
+
} else if (dt === DataType.UINT16) {
|
|
543
|
+
if (this._cachedUint16View === void 0 || this._cachedUint16Buffer !== bufData.buffer) {
|
|
544
|
+
this._cachedUint16Buffer = bufData.buffer;
|
|
545
|
+
this._cachedUint16View = new Uint16Array(bufData.buffer);
|
|
546
|
+
}
|
|
547
|
+
srcView = this._cachedUint16View;
|
|
548
|
+
shift = 1;
|
|
549
|
+
} else if (dt === DataType.INT16) {
|
|
550
|
+
if (this._cachedInt16View === void 0 || this._cachedInt16Buffer !== bufData.buffer) {
|
|
551
|
+
this._cachedInt16Buffer = bufData.buffer;
|
|
552
|
+
this._cachedInt16View = new Int16Array(bufData.buffer);
|
|
553
|
+
}
|
|
554
|
+
srcView = this._cachedInt16View;
|
|
555
|
+
shift = 1;
|
|
556
|
+
} else if (dt === DataType.UINT8) {
|
|
557
|
+
if (this._cachedUint8View === void 0 || this._cachedUint8Buffer !== bufData.buffer) {
|
|
558
|
+
this._cachedUint8Buffer = bufData.buffer;
|
|
559
|
+
this._cachedUint8View = new Uint8Array(bufData.buffer);
|
|
560
|
+
}
|
|
561
|
+
srcView = this._cachedUint8View;
|
|
562
|
+
shift = 0;
|
|
563
|
+
} else if (dt === DataType.INT8) {
|
|
564
|
+
if (this._cachedInt8View === void 0 || this._cachedInt8Buffer !== bufData.buffer) {
|
|
565
|
+
this._cachedInt8Buffer = bufData.buffer;
|
|
566
|
+
this._cachedInt8View = new Int8Array(bufData.buffer);
|
|
567
|
+
}
|
|
568
|
+
srcView = this._cachedInt8View;
|
|
569
|
+
shift = 0;
|
|
570
|
+
} else if (dt === DataType.FLOAT64) {
|
|
571
|
+
if (this._cachedFloat64View === void 0 || this._cachedFloat64Buffer !== bufData.buffer) {
|
|
572
|
+
this._cachedFloat64Buffer = bufData.buffer;
|
|
573
|
+
this._cachedFloat64View = new Float64Array(bufData.buffer);
|
|
574
|
+
}
|
|
575
|
+
srcView = this._cachedFloat64View;
|
|
576
|
+
shift = 3;
|
|
616
577
|
}
|
|
617
|
-
if (
|
|
618
|
-
|
|
578
|
+
if (srcView !== null) {
|
|
579
|
+
const srcStart = bufData.byteOffset + byteOffset >> shift;
|
|
580
|
+
const strideElements = byteStride >> shift;
|
|
581
|
+
if (isIdentity && strideElements === numComponents) {
|
|
582
|
+
const srcEnd = srcStart + numPoints * numComponents;
|
|
583
|
+
if (srcView.constructor === OutputTypedArray) {
|
|
584
|
+
array.set(srcView.subarray(srcStart, srcEnd));
|
|
585
|
+
return array;
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
if (isIdentity) {
|
|
589
|
+
let dst = 0;
|
|
590
|
+
for (let i = 0; i < numPoints; i++) {
|
|
591
|
+
const srcOffset = srcStart + i * strideElements;
|
|
592
|
+
for (let j = 0; j < numComponents; j++) {
|
|
593
|
+
array[dst + j] = srcView[srcOffset + j];
|
|
594
|
+
}
|
|
595
|
+
dst += numComponents;
|
|
596
|
+
}
|
|
597
|
+
} else if (numComponents === 3) {
|
|
598
|
+
let dst = 0;
|
|
599
|
+
for (let i = 0; i < numPoints; i++) {
|
|
600
|
+
const srcOffset = srcStart + indicesMap[i] * strideElements;
|
|
601
|
+
array[dst] = srcView[srcOffset];
|
|
602
|
+
array[dst + 1] = srcView[srcOffset + 1];
|
|
603
|
+
array[dst + 2] = srcView[srcOffset + 2];
|
|
604
|
+
dst += 3;
|
|
605
|
+
}
|
|
606
|
+
} else if (numComponents === 2) {
|
|
607
|
+
let dst = 0;
|
|
608
|
+
for (let i = 0; i < numPoints; i++) {
|
|
609
|
+
const srcOffset = srcStart + indicesMap[i] * strideElements;
|
|
610
|
+
array[dst] = srcView[srcOffset];
|
|
611
|
+
array[dst + 1] = srcView[srcOffset + 1];
|
|
612
|
+
dst += 2;
|
|
613
|
+
}
|
|
614
|
+
} else if (numComponents === 4) {
|
|
615
|
+
let dst = 0;
|
|
616
|
+
for (let i = 0; i < numPoints; i++) {
|
|
617
|
+
const srcOffset = srcStart + indicesMap[i] * strideElements;
|
|
618
|
+
array[dst] = srcView[srcOffset];
|
|
619
|
+
array[dst + 1] = srcView[srcOffset + 1];
|
|
620
|
+
array[dst + 2] = srcView[srcOffset + 2];
|
|
621
|
+
array[dst + 3] = srcView[srcOffset + 3];
|
|
622
|
+
dst += 4;
|
|
623
|
+
}
|
|
624
|
+
} else if (numComponents === 1) {
|
|
625
|
+
let dst = 0;
|
|
626
|
+
for (let i = 0; i < numPoints; i++) {
|
|
627
|
+
array[dst++] = srcView[srcStart + indicesMap[i] * strideElements];
|
|
628
|
+
}
|
|
629
|
+
} else {
|
|
630
|
+
let dst = 0;
|
|
631
|
+
for (let i = 0; i < numPoints; i++) {
|
|
632
|
+
const srcOffset = srcStart + indicesMap[i] * strideElements;
|
|
633
|
+
for (let j = 0; j < numComponents; j++) {
|
|
634
|
+
array[dst + j] = srcView[srcOffset + j];
|
|
635
|
+
}
|
|
636
|
+
dst += numComponents;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
return array;
|
|
640
|
+
}
|
|
641
|
+
const temp = new Array(numComponents);
|
|
642
|
+
for (let i = 0; i < numPoints; i++) {
|
|
643
|
+
const attIndex = isIdentity ? i : indicesMap[i];
|
|
644
|
+
this.convertValue(attIndex, temp);
|
|
645
|
+
const dstOffset = i * numComponents;
|
|
646
|
+
for (let j = 0; j < numComponents; j++) {
|
|
647
|
+
array[dstOffset + j] = temp[j];
|
|
648
|
+
}
|
|
619
649
|
}
|
|
620
|
-
return
|
|
650
|
+
return array;
|
|
621
651
|
}
|
|
622
|
-
//
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
if (
|
|
626
|
-
|
|
652
|
+
// Intentionally returns void while the base class returns boolean (matches the source's shape).
|
|
653
|
+
// @ts-expect-error -- return type intentionally differs from the base class, as in the source.
|
|
654
|
+
copyFrom(srcAtt) {
|
|
655
|
+
if (this.buffer === null) {
|
|
656
|
+
this._attributeBuffer = new DataBuffer();
|
|
657
|
+
this.resetBuffer(this._attributeBuffer, 0, 0);
|
|
627
658
|
}
|
|
628
|
-
if (
|
|
629
|
-
return
|
|
659
|
+
if (!super.copyFrom(srcAtt)) {
|
|
660
|
+
return;
|
|
661
|
+
}
|
|
662
|
+
this._identityMapping = srcAtt._identityMapping;
|
|
663
|
+
this._numUniqueEntries = srcAtt._numUniqueEntries;
|
|
664
|
+
this._indicesMap = srcAtt._indicesMap.slice();
|
|
665
|
+
if (srcAtt._attributeTransformData) {
|
|
666
|
+
this._attributeTransformData = srcAtt._attributeTransformData;
|
|
667
|
+
} else {
|
|
668
|
+
this._attributeTransformData = null;
|
|
630
669
|
}
|
|
631
|
-
return this.buffer_.decodeBytes(nameLen) !== void 0;
|
|
632
670
|
}
|
|
633
671
|
};
|
|
634
672
|
|
|
635
|
-
// src/decoder/
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
this._pointCloud = null;
|
|
646
|
-
this._buffer = null;
|
|
647
|
-
this._versionMajor = 0;
|
|
648
|
-
this._versionMinor = 0;
|
|
649
|
-
this._options = null;
|
|
650
|
-
this._attributesDecoders = [];
|
|
651
|
-
this._attributeToDecoderMap = [];
|
|
673
|
+
// src/decoder/core/Macros.ts
|
|
674
|
+
function bitstreamVersion(major, minor) {
|
|
675
|
+
return (major & 255) << 8 | minor & 255;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
// src/decoder/core/BitUtils.ts
|
|
679
|
+
function convertSymbolsToSignedInts(input, count, output) {
|
|
680
|
+
for (let i = 0; i < count; i++) {
|
|
681
|
+
const val = input[i];
|
|
682
|
+
output[i] = val >>> 1 ^ -(val & 1);
|
|
652
683
|
}
|
|
653
|
-
|
|
654
|
-
|
|
684
|
+
}
|
|
685
|
+
function convertSymbolToSignedInt(val) {
|
|
686
|
+
const isPositive = (val & 1) === 0;
|
|
687
|
+
val >>>= 1;
|
|
688
|
+
if (isPositive) {
|
|
689
|
+
return val;
|
|
655
690
|
}
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
if (versionMajor === void 0) {
|
|
672
|
-
return new Status(StatusCode.IO_ERROR, kIoErrorMsg);
|
|
673
|
-
}
|
|
674
|
-
outHeader.versionMajor = versionMajor;
|
|
675
|
-
const versionMinor = buffer.decodeUint8();
|
|
676
|
-
if (versionMinor === void 0) {
|
|
677
|
-
return new Status(StatusCode.IO_ERROR, kIoErrorMsg);
|
|
678
|
-
}
|
|
679
|
-
outHeader.versionMinor = versionMinor;
|
|
680
|
-
const encoderType = buffer.decodeUint8();
|
|
681
|
-
if (encoderType === void 0) {
|
|
682
|
-
return new Status(StatusCode.IO_ERROR, kIoErrorMsg);
|
|
683
|
-
}
|
|
684
|
-
outHeader.encoderType = encoderType;
|
|
685
|
-
const encoderMethod = buffer.decodeUint8();
|
|
686
|
-
if (encoderMethod === void 0) {
|
|
687
|
-
return new Status(StatusCode.IO_ERROR, kIoErrorMsg);
|
|
691
|
+
return -val - 1;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
// src/decoder/core/VarintDecoding.ts
|
|
695
|
+
function decodeVarintUnsigned(buffer, maxBytes) {
|
|
696
|
+
let result = 0;
|
|
697
|
+
let multiplier = 1;
|
|
698
|
+
for (let i = 0; i < maxBytes; i++) {
|
|
699
|
+
const byte = buffer.decodeUint8();
|
|
700
|
+
if (byte === void 0) return void 0;
|
|
701
|
+
if (byte & 128) {
|
|
702
|
+
result += (byte & 127) * multiplier;
|
|
703
|
+
multiplier *= 128;
|
|
704
|
+
} else {
|
|
705
|
+
return result + byte * multiplier;
|
|
688
706
|
}
|
|
689
|
-
outHeader.encoderMethod = encoderMethod;
|
|
690
|
-
const flags = buffer.decodeUint16();
|
|
691
|
-
if (flags === void 0) {
|
|
692
|
-
return new Status(StatusCode.IO_ERROR, kIoErrorMsg);
|
|
693
|
-
}
|
|
694
|
-
outHeader.flags = flags;
|
|
695
|
-
return okStatus();
|
|
696
707
|
}
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
this.
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
708
|
+
return void 0;
|
|
709
|
+
}
|
|
710
|
+
function decodeVarint(buffer, signed = false) {
|
|
711
|
+
const maxBytes = 10;
|
|
712
|
+
const value = decodeVarintUnsigned(buffer, maxBytes);
|
|
713
|
+
if (value === void 0) return void 0;
|
|
714
|
+
if (signed) {
|
|
715
|
+
return convertSymbolToSignedInt(value);
|
|
716
|
+
}
|
|
717
|
+
return value;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
// src/decoder/core/DecoderBuffer.ts
|
|
721
|
+
var BitDecoder = class {
|
|
722
|
+
_bitBuffer;
|
|
723
|
+
_bitOffset;
|
|
724
|
+
_byteLength;
|
|
725
|
+
constructor() {
|
|
726
|
+
this._bitBuffer = null;
|
|
727
|
+
this._bitOffset = 0;
|
|
728
|
+
this._byteLength = 0;
|
|
729
|
+
}
|
|
730
|
+
reset(uint8Array, byteLength) {
|
|
731
|
+
this._bitBuffer = uint8Array;
|
|
732
|
+
this._byteLength = byteLength;
|
|
733
|
+
this._bitOffset = 0;
|
|
734
|
+
}
|
|
735
|
+
bitsDecoded() {
|
|
736
|
+
return this._bitOffset;
|
|
737
|
+
}
|
|
738
|
+
getBits(nbits) {
|
|
739
|
+
if (nbits > 32) return void 0;
|
|
740
|
+
const buf = this._bitBuffer;
|
|
741
|
+
let off = this._bitOffset;
|
|
742
|
+
const byteOffset = off >> 3;
|
|
743
|
+
const bitShift = off & 7;
|
|
744
|
+
if (byteOffset + 4 < this._byteLength) {
|
|
745
|
+
const val = (buf[byteOffset] | buf[byteOffset + 1] << 8 | buf[byteOffset + 2] << 16 | buf[byteOffset + 3] << 24) >>> 0;
|
|
746
|
+
let result;
|
|
747
|
+
if (nbits > 32 - bitShift) {
|
|
748
|
+
const val2 = buf[byteOffset + 4];
|
|
749
|
+
const low = val >>> bitShift;
|
|
750
|
+
const high = val2 << 32 - bitShift;
|
|
751
|
+
result = (low | high) >>> 0;
|
|
752
|
+
} else {
|
|
753
|
+
result = val >>> bitShift;
|
|
731
754
|
}
|
|
755
|
+
this._bitOffset = off + nbits;
|
|
756
|
+
return nbits === 32 ? result : result & (1 << nbits) - 1;
|
|
732
757
|
}
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
758
|
+
let value = 0;
|
|
759
|
+
let bitsRead = 0;
|
|
760
|
+
let currOff = off;
|
|
761
|
+
while (bitsRead < nbits) {
|
|
762
|
+
const bOff = currOff >> 3;
|
|
763
|
+
if (bOff >= this._byteLength) return void 0;
|
|
764
|
+
const bShift = currOff & 7;
|
|
765
|
+
const bitsAvail = 8 - bShift;
|
|
766
|
+
const bitsNeeded = nbits - bitsRead;
|
|
767
|
+
const bitsToRead = bitsAvail < bitsNeeded ? bitsAvail : bitsNeeded;
|
|
768
|
+
const mask = (1 << bitsToRead) - 1;
|
|
769
|
+
value |= (buf[bOff] >> bShift & mask) << bitsRead;
|
|
770
|
+
bitsRead += bitsToRead;
|
|
771
|
+
currOff += bitsToRead;
|
|
741
772
|
}
|
|
742
|
-
|
|
773
|
+
this._bitOffset = currOff;
|
|
774
|
+
return value;
|
|
743
775
|
}
|
|
744
|
-
|
|
745
|
-
|
|
776
|
+
};
|
|
777
|
+
var DecoderBuffer = class {
|
|
778
|
+
_data;
|
|
779
|
+
_dataView;
|
|
780
|
+
_dataSize;
|
|
781
|
+
_pos;
|
|
782
|
+
_bitDecoder;
|
|
783
|
+
_bitMode;
|
|
784
|
+
_bitstreamVersion;
|
|
785
|
+
constructor() {
|
|
786
|
+
this._data = null;
|
|
787
|
+
this._dataView = null;
|
|
788
|
+
this._dataSize = 0;
|
|
789
|
+
this._pos = 0;
|
|
790
|
+
this._bitDecoder = new BitDecoder();
|
|
791
|
+
this._bitMode = false;
|
|
792
|
+
this._bitstreamVersion = 0;
|
|
746
793
|
}
|
|
747
|
-
|
|
748
|
-
if (
|
|
749
|
-
|
|
794
|
+
init(data, dataSize, version) {
|
|
795
|
+
if (data instanceof ArrayBuffer) {
|
|
796
|
+
this._data = new Uint8Array(data);
|
|
797
|
+
} else if (data instanceof Uint8Array) {
|
|
798
|
+
this._data = data;
|
|
799
|
+
} else {
|
|
800
|
+
this._data = new Uint8Array(data);
|
|
750
801
|
}
|
|
751
|
-
|
|
752
|
-
|
|
802
|
+
this._dataView = new DataView(this._data.buffer, this._data.byteOffset, this._data.byteLength);
|
|
803
|
+
this._dataSize = dataSize !== void 0 ? dataSize : this._data.length;
|
|
804
|
+
this._pos = 0;
|
|
805
|
+
if (version !== void 0) {
|
|
806
|
+
this._bitstreamVersion = version;
|
|
753
807
|
}
|
|
754
|
-
this._attributesDecoders[attDecoderId] = decoder;
|
|
755
|
-
return true;
|
|
756
808
|
}
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
return
|
|
809
|
+
// Typed little-endian reads.
|
|
810
|
+
decodeUint8() {
|
|
811
|
+
if (this._pos + 1 > this._dataSize) return void 0;
|
|
812
|
+
const val = this._data[this._pos];
|
|
813
|
+
this._pos += 1;
|
|
814
|
+
return val;
|
|
763
815
|
}
|
|
764
|
-
|
|
765
|
-
|
|
816
|
+
decodeInt8() {
|
|
817
|
+
if (this._pos + 1 > this._dataSize) return void 0;
|
|
818
|
+
const val = this._dataView.getInt8(this._pos);
|
|
819
|
+
this._pos += 1;
|
|
820
|
+
return val;
|
|
766
821
|
}
|
|
767
|
-
|
|
768
|
-
|
|
822
|
+
decodeUint16() {
|
|
823
|
+
if (this._pos + 2 > this._dataSize) return void 0;
|
|
824
|
+
const val = this._dataView.getUint16(this._pos, true);
|
|
825
|
+
this._pos += 2;
|
|
826
|
+
return val;
|
|
769
827
|
}
|
|
770
|
-
|
|
771
|
-
|
|
828
|
+
decodeUint32() {
|
|
829
|
+
if (this._pos + 4 > this._dataSize) return void 0;
|
|
830
|
+
const val = this._dataView.getUint32(this._pos, true);
|
|
831
|
+
this._pos += 4;
|
|
832
|
+
return val;
|
|
772
833
|
}
|
|
773
|
-
|
|
774
|
-
|
|
834
|
+
decodeInt32() {
|
|
835
|
+
if (this._pos + 4 > this._dataSize) return void 0;
|
|
836
|
+
const val = this._dataView.getInt32(this._pos, true);
|
|
837
|
+
this._pos += 4;
|
|
838
|
+
return val;
|
|
775
839
|
}
|
|
776
|
-
|
|
777
|
-
|
|
840
|
+
decodeFloat32() {
|
|
841
|
+
if (this._pos + 4 > this._dataSize) return void 0;
|
|
842
|
+
const val = this._dataView.getFloat32(this._pos, true);
|
|
843
|
+
this._pos += 4;
|
|
844
|
+
return val;
|
|
778
845
|
}
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
846
|
+
decodeUint64() {
|
|
847
|
+
if (this._pos + 8 > this._dataSize) return void 0;
|
|
848
|
+
const lo = this._dataView.getUint32(this._pos, true);
|
|
849
|
+
const hi = this._dataView.getUint32(this._pos + 4, true);
|
|
850
|
+
this._pos += 8;
|
|
851
|
+
return hi * 4294967296 + lo;
|
|
782
852
|
}
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
853
|
+
decodeBytes(size) {
|
|
854
|
+
if (this._pos + size > this._dataSize) return void 0;
|
|
855
|
+
const result = this._data.slice(this._pos, this._pos + size);
|
|
856
|
+
this._pos += size;
|
|
857
|
+
return result;
|
|
786
858
|
}
|
|
787
|
-
|
|
788
|
-
|
|
859
|
+
// Zero-copy variant of decodeBytes: a view into the stream, only valid until
|
|
860
|
+
// the caller's next chance to mutate the buffer — copy out before keeping it.
|
|
861
|
+
decodeBytesView(size) {
|
|
862
|
+
if (this._pos + size > this._dataSize) return void 0;
|
|
863
|
+
const result = this._data.subarray(this._pos, this._pos + size);
|
|
864
|
+
this._pos += size;
|
|
865
|
+
return result;
|
|
789
866
|
}
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
if (
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
}
|
|
800
|
-
for (let i = 0; i < this._attributesDecoders.length; ++i) {
|
|
801
|
-
if (!this._attributesDecoders[i].init(this, this._pointCloud)) {
|
|
802
|
-
return false;
|
|
803
|
-
}
|
|
804
|
-
}
|
|
805
|
-
for (let i = 0; i < numAttributesDecoders; ++i) {
|
|
806
|
-
if (!this._attributesDecoders[i].decodeAttributesDecoderData(this._buffer)) {
|
|
807
|
-
return false;
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
for (let i = 0; i < numAttributesDecoders; ++i) {
|
|
811
|
-
const numAttributes = this._attributesDecoders[i].getNumAttributes();
|
|
812
|
-
for (let j = 0; j < numAttributes; ++j) {
|
|
813
|
-
const attId = this._attributesDecoders[i].getAttributeId(j);
|
|
814
|
-
while (this._attributeToDecoderMap.length <= attId) {
|
|
815
|
-
this._attributeToDecoderMap.push(0);
|
|
816
|
-
}
|
|
817
|
-
this._attributeToDecoderMap[attId] = i;
|
|
867
|
+
startBitDecoding(decodeSize) {
|
|
868
|
+
let outSize = 0;
|
|
869
|
+
if (decodeSize) {
|
|
870
|
+
if (this._bitstreamVersion < bitstreamVersion(2, 2)) {
|
|
871
|
+
outSize = this.decodeUint64();
|
|
872
|
+
if (outSize === void 0) return void 0;
|
|
873
|
+
} else {
|
|
874
|
+
outSize = decodeVarint(this, false);
|
|
875
|
+
if (outSize === void 0) return void 0;
|
|
818
876
|
}
|
|
819
877
|
}
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
if (!this.onAttributesDecoded()) {
|
|
824
|
-
return false;
|
|
825
|
-
}
|
|
826
|
-
return true;
|
|
878
|
+
this._bitMode = true;
|
|
879
|
+
this._bitDecoder.reset(this._data.subarray(this._pos), this._dataSize - this._pos);
|
|
880
|
+
return outSize;
|
|
827
881
|
}
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
}
|
|
834
|
-
return true;
|
|
882
|
+
endBitDecoding() {
|
|
883
|
+
this._bitMode = false;
|
|
884
|
+
const bitsDecoded = this._bitDecoder.bitsDecoded();
|
|
885
|
+
const bytesDecoded = Math.ceil(bitsDecoded / 8);
|
|
886
|
+
this._pos += bytesDecoded;
|
|
835
887
|
}
|
|
836
|
-
|
|
837
|
-
return
|
|
888
|
+
decodeLeastSignificantBits32(nbits) {
|
|
889
|
+
if (!this._bitMode) return void 0;
|
|
890
|
+
return this._bitDecoder.getBits(nbits);
|
|
838
891
|
}
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
if (!metadataDecoder.skipGeometryMetadata(this._buffer)) {
|
|
842
|
-
return new Status(StatusCode.DRACO_ERROR, "Failed to decode metadata.");
|
|
843
|
-
}
|
|
844
|
-
return okStatus();
|
|
892
|
+
decodeVarintUint32() {
|
|
893
|
+
return decodeVarint(this, false);
|
|
845
894
|
}
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
// src/decoder/compression/mesh/MeshDecoder.ts
|
|
849
|
-
var MeshDecoder = class extends PointCloudDecoder {
|
|
850
|
-
_mesh;
|
|
851
|
-
constructor() {
|
|
852
|
-
super();
|
|
853
|
-
this._mesh = null;
|
|
895
|
+
decodeVarintUint64() {
|
|
896
|
+
return decodeVarint(this, false);
|
|
854
897
|
}
|
|
855
|
-
|
|
856
|
-
|
|
898
|
+
advance(bytes) {
|
|
899
|
+
this._pos += bytes;
|
|
857
900
|
}
|
|
858
|
-
|
|
859
|
-
this.
|
|
860
|
-
return this.decode(options, inBuffer, outMesh);
|
|
901
|
+
get bitstreamVersion() {
|
|
902
|
+
return this._bitstreamVersion;
|
|
861
903
|
}
|
|
862
|
-
|
|
863
|
-
|
|
904
|
+
set bitstreamVersion(v) {
|
|
905
|
+
this._bitstreamVersion = v;
|
|
864
906
|
}
|
|
865
|
-
|
|
866
|
-
return
|
|
907
|
+
get data() {
|
|
908
|
+
return this._data;
|
|
867
909
|
}
|
|
868
|
-
|
|
869
|
-
return
|
|
910
|
+
get dataHead() {
|
|
911
|
+
return this._data.subarray(this._pos);
|
|
870
912
|
}
|
|
871
|
-
|
|
872
|
-
return this.
|
|
913
|
+
get remainingSize() {
|
|
914
|
+
return this._dataSize - this._pos;
|
|
873
915
|
}
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
return false;
|
|
877
|
-
}
|
|
878
|
-
if (!this.decodeConnectivity()) {
|
|
879
|
-
return false;
|
|
880
|
-
}
|
|
881
|
-
return super.decodeGeometryData();
|
|
916
|
+
get decodedSize() {
|
|
917
|
+
return this._pos;
|
|
882
918
|
}
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
return false;
|
|
919
|
+
get bitDecoderActive() {
|
|
920
|
+
return this._bitMode;
|
|
886
921
|
}
|
|
887
922
|
};
|
|
888
923
|
|
|
889
|
-
// src/decoder/
|
|
890
|
-
var
|
|
891
|
-
var
|
|
892
|
-
var
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
924
|
+
// src/decoder/core/ScratchArena.ts
|
|
925
|
+
var freeInt32 = [];
|
|
926
|
+
var freeUint8 = [];
|
|
927
|
+
var borrowedInt32 = [];
|
|
928
|
+
var borrowedUint8 = [];
|
|
929
|
+
var acquire = (free, borrowed, size) => {
|
|
930
|
+
for (let i = free.length - 1; i >= 0; --i) {
|
|
931
|
+
const buffer = free[i];
|
|
932
|
+
if (buffer.length >= size) {
|
|
933
|
+
free[i] = free[free.length - 1];
|
|
934
|
+
free.pop();
|
|
935
|
+
borrowed.push(buffer);
|
|
936
|
+
return buffer;
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
return null;
|
|
940
|
+
};
|
|
941
|
+
var scratchInt32 = (size) => {
|
|
942
|
+
const pooled = acquire(freeInt32, borrowedInt32, size);
|
|
943
|
+
if (pooled !== null) return pooled.subarray(0, size);
|
|
944
|
+
const fresh = new Int32Array(size);
|
|
945
|
+
borrowedInt32.push(fresh);
|
|
946
|
+
return fresh;
|
|
947
|
+
};
|
|
948
|
+
var scratchUint8Zeroed = (size) => {
|
|
949
|
+
const pooled = acquire(freeUint8, borrowedUint8, size);
|
|
950
|
+
if (pooled !== null) {
|
|
951
|
+
const view = pooled.subarray(0, size);
|
|
952
|
+
view.fill(0);
|
|
953
|
+
return view;
|
|
954
|
+
}
|
|
955
|
+
const fresh = new Uint8Array(size);
|
|
956
|
+
borrowedUint8.push(fresh);
|
|
957
|
+
return fresh;
|
|
958
|
+
};
|
|
959
|
+
var releaseScratch = () => {
|
|
960
|
+
for (const buffer of borrowedInt32) freeInt32.push(buffer);
|
|
961
|
+
for (const buffer of borrowedUint8) freeUint8.push(buffer);
|
|
962
|
+
borrowedInt32.length = 0;
|
|
963
|
+
borrowedUint8.length = 0;
|
|
964
|
+
};
|
|
965
|
+
|
|
966
|
+
// src/decoder/compression/config/CompressionShared.ts
|
|
967
|
+
var kDracoPointCloudBitstreamVersionMajor = 2;
|
|
968
|
+
var kDracoPointCloudBitstreamVersionMinor = 3;
|
|
969
|
+
var kDracoMeshBitstreamVersionMajor = 2;
|
|
970
|
+
var kDracoMeshBitstreamVersionMinor = 2;
|
|
971
|
+
function DRACO_BITSTREAM_VERSION(major, minor) {
|
|
972
|
+
return major << 8 | minor;
|
|
973
|
+
}
|
|
974
|
+
var EncodedGeometryType = {
|
|
975
|
+
INVALID_GEOMETRY_TYPE: -1,
|
|
976
|
+
POINT_CLOUD: 0,
|
|
977
|
+
TRIANGULAR_MESH: 1,
|
|
978
|
+
NUM_ENCODED_GEOMETRY_TYPES: 2
|
|
979
|
+
};
|
|
980
|
+
var MeshEncoderMethod = {
|
|
981
|
+
MESH_SEQUENTIAL_ENCODING: 0,
|
|
982
|
+
MESH_EDGEBREAKER_ENCODING: 1
|
|
983
|
+
};
|
|
984
|
+
var SequentialAttributeEncoderType = {
|
|
985
|
+
SEQUENTIAL_ATTRIBUTE_ENCODER_GENERIC: 0,
|
|
986
|
+
SEQUENTIAL_ATTRIBUTE_ENCODER_INTEGER: 1,
|
|
987
|
+
SEQUENTIAL_ATTRIBUTE_ENCODER_QUANTIZATION: 2,
|
|
988
|
+
SEQUENTIAL_ATTRIBUTE_ENCODER_NORMALS: 3
|
|
989
|
+
};
|
|
990
|
+
var PredictionSchemeMethod = {
|
|
991
|
+
PREDICTION_NONE: -2,
|
|
992
|
+
PREDICTION_UNDEFINED: -1,
|
|
993
|
+
PREDICTION_DIFFERENCE: 0,
|
|
994
|
+
MESH_PREDICTION_PARALLELOGRAM: 1,
|
|
995
|
+
MESH_PREDICTION_MULTI_PARALLELOGRAM: 2,
|
|
996
|
+
MESH_PREDICTION_TEX_COORDS_DEPRECATED: 3,
|
|
997
|
+
MESH_PREDICTION_CONSTRAINED_MULTI_PARALLELOGRAM: 4,
|
|
998
|
+
MESH_PREDICTION_TEX_COORDS_PORTABLE: 5,
|
|
999
|
+
MESH_PREDICTION_GEOMETRIC_NORMAL: 6,
|
|
1000
|
+
NUM_PREDICTION_SCHEMES: 7
|
|
1001
|
+
};
|
|
1002
|
+
var PredictionSchemeTransformType = {
|
|
1003
|
+
PREDICTION_TRANSFORM_NONE: -1,
|
|
1004
|
+
PREDICTION_TRANSFORM_DELTA: 0,
|
|
1005
|
+
PREDICTION_TRANSFORM_WRAP: 1,
|
|
1006
|
+
PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON: 2,
|
|
1007
|
+
PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON_CANONICALIZED: 3,
|
|
1008
|
+
NUM_PREDICTION_SCHEME_TRANSFORM_TYPES: 4
|
|
1009
|
+
};
|
|
1010
|
+
var MeshTraversalMethod = {
|
|
1011
|
+
MESH_TRAVERSAL_DEPTH_FIRST: 0,
|
|
1012
|
+
MESH_TRAVERSAL_PREDICTION_DEGREE: 1,
|
|
1013
|
+
NUM_TRAVERSAL_METHODS: 2
|
|
1014
|
+
};
|
|
1015
|
+
var MeshEdgebreakerConnectivityEncodingMethod = {
|
|
1016
|
+
MESH_EDGEBREAKER_STANDARD_ENCODING: 0,
|
|
1017
|
+
MESH_EDGEBREAKER_PREDICTIVE_ENCODING: 1,
|
|
1018
|
+
// Deprecated.
|
|
1019
|
+
MESH_EDGEBREAKER_VALENCE_ENCODING: 2
|
|
1020
|
+
};
|
|
1021
|
+
var DracoHeader = class {
|
|
1022
|
+
dracoString;
|
|
1023
|
+
versionMajor;
|
|
1024
|
+
versionMinor;
|
|
1025
|
+
encoderType;
|
|
1026
|
+
encoderMethod;
|
|
1027
|
+
flags;
|
|
905
1028
|
constructor() {
|
|
906
|
-
this.
|
|
907
|
-
this.
|
|
908
|
-
this.
|
|
909
|
-
this.
|
|
910
|
-
this.
|
|
911
|
-
this.
|
|
912
|
-
this.corner_table_ = null;
|
|
913
|
-
this._effectiveOpposite = null;
|
|
914
|
-
this._seamCorners = [];
|
|
1029
|
+
this.dracoString = new Int8Array(5);
|
|
1030
|
+
this.versionMajor = 0;
|
|
1031
|
+
this.versionMinor = 0;
|
|
1032
|
+
this.encoderType = 0;
|
|
1033
|
+
this.encoderMethod = 0;
|
|
1034
|
+
this.flags = 0;
|
|
915
1035
|
}
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
1036
|
+
};
|
|
1037
|
+
var NormalPredictionMode = {
|
|
1038
|
+
ONE_TRIANGLE: 0,
|
|
1039
|
+
// To be deprecated.
|
|
1040
|
+
TRIANGLE_AREA: 1
|
|
1041
|
+
};
|
|
1042
|
+
var SymbolCodingMethod = {
|
|
1043
|
+
SYMBOL_CODING_TAGGED: 0,
|
|
1044
|
+
SYMBOL_CODING_RAW: 1,
|
|
1045
|
+
NUM_SYMBOL_CODING_METHODS: 2
|
|
1046
|
+
};
|
|
1047
|
+
var METADATA_FLAG_MASK = 32768;
|
|
1048
|
+
|
|
1049
|
+
// src/decoder/compression/config/DracoOptions.ts
|
|
1050
|
+
var DracoOptions = class {
|
|
1051
|
+
_globalOptions;
|
|
1052
|
+
_attributeOptions;
|
|
1053
|
+
constructor() {
|
|
1054
|
+
this._globalOptions = /* @__PURE__ */ new Map();
|
|
1055
|
+
this._attributeOptions = /* @__PURE__ */ new Map();
|
|
1056
|
+
}
|
|
1057
|
+
getGlobalBool(name, defaultVal) {
|
|
1058
|
+
if (this._globalOptions.has(name)) {
|
|
1059
|
+
return !!this._globalOptions.get(name);
|
|
919
1060
|
}
|
|
920
|
-
|
|
921
|
-
this.is_vertex_on_seam_ = new Uint8Array(table.numVertices());
|
|
922
|
-
this.corner_to_vertex_map_ = new Int32Array(table.numCorners()).fill(kInvalidVertexIndex);
|
|
923
|
-
this.vertex_to_attribute_entry_id_map_ = [];
|
|
924
|
-
this.vertex_to_left_most_corner_map_ = [];
|
|
925
|
-
this._effectiveOpposite = null;
|
|
926
|
-
this._seamCorners = [];
|
|
927
|
-
this.corner_table_ = table;
|
|
928
|
-
this.no_interior_seams_ = true;
|
|
929
|
-
return true;
|
|
1061
|
+
return defaultVal;
|
|
930
1062
|
}
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
const isEdge = this.is_edge_on_seam_;
|
|
935
|
-
const isVert = this.is_vertex_on_seam_;
|
|
936
|
-
isEdge[c] = 1;
|
|
937
|
-
this._seamCorners.push(c);
|
|
938
|
-
let rem = c - (c / 3 | 0) * 3;
|
|
939
|
-
isVert[cornerToVertex[rem === 2 ? c - 2 : c + 1]] = 1;
|
|
940
|
-
isVert[cornerToVertex[rem === 0 ? c + 2 : c - 1]] = 1;
|
|
941
|
-
const oppCorner = oppositeCorners[c];
|
|
942
|
-
if (oppCorner !== kInvalidCornerIndex) {
|
|
943
|
-
this.no_interior_seams_ = false;
|
|
944
|
-
isEdge[oppCorner] = 1;
|
|
945
|
-
this._seamCorners.push(oppCorner);
|
|
946
|
-
rem = oppCorner - (oppCorner / 3 | 0) * 3;
|
|
947
|
-
isVert[cornerToVertex[rem === 2 ? oppCorner - 2 : oppCorner + 1]] = 1;
|
|
948
|
-
isVert[cornerToVertex[rem === 0 ? oppCorner + 2 : oppCorner - 1]] = 1;
|
|
1063
|
+
findAttributeOptions(attKey) {
|
|
1064
|
+
if (this._attributeOptions.has(attKey)) {
|
|
1065
|
+
return this._attributeOptions.get(attKey);
|
|
949
1066
|
}
|
|
1067
|
+
return null;
|
|
950
1068
|
}
|
|
951
|
-
|
|
952
|
-
|
|
1069
|
+
getAttributeBool(attKey, name, defaultVal) {
|
|
1070
|
+
const attOpts = this.findAttributeOptions(attKey);
|
|
1071
|
+
if (attOpts !== null && attOpts.has(name)) {
|
|
1072
|
+
return !!attOpts.get(name);
|
|
1073
|
+
}
|
|
1074
|
+
return this.getGlobalBool(name, defaultVal);
|
|
953
1075
|
}
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
const leftMostMap = new Int32Array(numCorners);
|
|
961
|
-
const cornerToVertex = this.corner_to_vertex_map_;
|
|
962
|
-
const isVertexOnSeam = this.is_vertex_on_seam_;
|
|
963
|
-
const isEdgeOnSeam = this.is_edge_on_seam_;
|
|
964
|
-
const seamOpp = this.oppositeCornerArray();
|
|
965
|
-
const baseOpp = ct.oppositeCornerArray();
|
|
966
|
-
const vertexLeftmost = ct.vertexLeftmostCornerArray();
|
|
967
|
-
let numNewVertices = 0;
|
|
968
|
-
for (let v = 0; v < numBaseVertices; ++v) {
|
|
969
|
-
const c = vertexLeftmost[v];
|
|
970
|
-
if (c === kInvalidCornerIndex) continue;
|
|
971
|
-
if (!isVertexOnSeam[v]) {
|
|
972
|
-
const firstVertId = numNewVertices++;
|
|
973
|
-
leftMostMap[firstVertId] = c;
|
|
974
|
-
cornerToVertex[c] = firstVertId;
|
|
975
|
-
let pv = c % 3 === 0 ? c + 2 : c - 1;
|
|
976
|
-
let bopp = baseOpp[pv];
|
|
977
|
-
let actC = bopp < 0 ? kInvalidCornerIndex : bopp % 3 === 0 ? bopp + 2 : bopp - 1;
|
|
978
|
-
while (actC !== kInvalidCornerIndex && actC !== c) {
|
|
979
|
-
cornerToVertex[actC] = firstVertId;
|
|
980
|
-
pv = actC % 3 === 0 ? actC + 2 : actC - 1;
|
|
981
|
-
bopp = baseOpp[pv];
|
|
982
|
-
actC = bopp < 0 ? kInvalidCornerIndex : bopp % 3 === 0 ? bopp + 2 : bopp - 1;
|
|
983
|
-
}
|
|
984
|
-
} else {
|
|
985
|
-
let firstVertId = numNewVertices++;
|
|
986
|
-
let firstC = c;
|
|
987
|
-
let actC;
|
|
988
|
-
let nx = firstC % 3 === 2 ? firstC - 2 : firstC + 1;
|
|
989
|
-
let opp = seamOpp[nx];
|
|
990
|
-
actC = opp < 0 ? kInvalidCornerIndex : opp % 3 === 2 ? opp - 2 : opp + 1;
|
|
991
|
-
while (actC !== kInvalidCornerIndex) {
|
|
992
|
-
firstC = actC;
|
|
993
|
-
nx = firstC % 3 === 2 ? firstC - 2 : firstC + 1;
|
|
994
|
-
opp = seamOpp[nx];
|
|
995
|
-
actC = opp < 0 ? kInvalidCornerIndex : opp % 3 === 2 ? opp - 2 : opp + 1;
|
|
996
|
-
if (actC === c) return false;
|
|
997
|
-
}
|
|
998
|
-
cornerToVertex[firstC] = firstVertId;
|
|
999
|
-
leftMostMap[firstVertId] = firstC;
|
|
1000
|
-
let pv = firstC % 3 === 0 ? firstC + 2 : firstC - 1;
|
|
1001
|
-
let bopp = baseOpp[pv];
|
|
1002
|
-
actC = bopp < 0 ? kInvalidCornerIndex : bopp % 3 === 0 ? bopp + 2 : bopp - 1;
|
|
1003
|
-
while (actC !== kInvalidCornerIndex && actC !== firstC) {
|
|
1004
|
-
const nAct = actC % 3 === 2 ? actC - 2 : actC + 1;
|
|
1005
|
-
if (isEdgeOnSeam[nAct]) {
|
|
1006
|
-
firstVertId = numNewVertices++;
|
|
1007
|
-
leftMostMap[firstVertId] = actC;
|
|
1008
|
-
}
|
|
1009
|
-
cornerToVertex[actC] = firstVertId;
|
|
1010
|
-
pv = actC % 3 === 0 ? actC + 2 : actC - 1;
|
|
1011
|
-
bopp = baseOpp[pv];
|
|
1012
|
-
actC = bopp < 0 ? kInvalidCornerIndex : bopp % 3 === 0 ? bopp + 2 : bopp - 1;
|
|
1013
|
-
}
|
|
1014
|
-
}
|
|
1015
|
-
}
|
|
1016
|
-
this.vertex_to_attribute_entry_id_map_ = new Int32Array(numNewVertices);
|
|
1017
|
-
this.vertex_to_left_most_corner_map_ = leftMostMap.subarray(0, numNewVertices);
|
|
1018
|
-
return true;
|
|
1019
|
-
}
|
|
1020
|
-
isCornerOppositeToSeamEdge(corner) {
|
|
1021
|
-
return this.is_edge_on_seam_[corner];
|
|
1022
|
-
}
|
|
1023
|
-
opposite(corner) {
|
|
1024
|
-
if (corner === kInvalidCornerIndex || this.isCornerOppositeToSeamEdge(corner)) {
|
|
1025
|
-
return kInvalidCornerIndex;
|
|
1026
|
-
}
|
|
1027
|
-
return this.corner_table_.opposite(corner);
|
|
1028
|
-
}
|
|
1029
|
-
next(corner) {
|
|
1030
|
-
return this.corner_table_.next(corner);
|
|
1031
|
-
}
|
|
1032
|
-
previous(corner) {
|
|
1033
|
-
return this.corner_table_.previous(corner);
|
|
1034
|
-
}
|
|
1035
|
-
swingRight(corner) {
|
|
1036
|
-
return this.previous(this.opposite(this.previous(corner)));
|
|
1037
|
-
}
|
|
1038
|
-
swingLeft(corner) {
|
|
1039
|
-
return this.next(this.opposite(this.next(corner)));
|
|
1040
|
-
}
|
|
1041
|
-
numVertices() {
|
|
1042
|
-
return this.vertex_to_attribute_entry_id_map_.length;
|
|
1043
|
-
}
|
|
1044
|
-
numFaces() {
|
|
1045
|
-
return this.corner_table_.numFaces();
|
|
1046
|
-
}
|
|
1047
|
-
numCorners() {
|
|
1048
|
-
return this.corner_table_.numCorners();
|
|
1049
|
-
}
|
|
1050
|
-
vertex(corner) {
|
|
1051
|
-
return this.confidentVertex(corner);
|
|
1052
|
-
}
|
|
1053
|
-
confidentVertex(corner) {
|
|
1054
|
-
return this.corner_to_vertex_map_[corner];
|
|
1055
|
-
}
|
|
1056
|
-
leftMostCorner(v) {
|
|
1057
|
-
return this.vertex_to_left_most_corner_map_[v];
|
|
1076
|
+
};
|
|
1077
|
+
|
|
1078
|
+
// src/decoder/compression/config/DecoderOptions.ts
|
|
1079
|
+
var DecoderOptions = class extends DracoOptions {
|
|
1080
|
+
constructor() {
|
|
1081
|
+
super();
|
|
1058
1082
|
}
|
|
1059
|
-
|
|
1060
|
-
|
|
1083
|
+
};
|
|
1084
|
+
|
|
1085
|
+
// src/decoder/core/Status.ts
|
|
1086
|
+
var StatusCode = {
|
|
1087
|
+
OK: 0,
|
|
1088
|
+
DRACO_ERROR: -1,
|
|
1089
|
+
IO_ERROR: -2,
|
|
1090
|
+
INVALID_PARAMETER: -3,
|
|
1091
|
+
UNSUPPORTED_VERSION: -4,
|
|
1092
|
+
UNKNOWN_VERSION: -5,
|
|
1093
|
+
UNSUPPORTED_FEATURE: -6
|
|
1094
|
+
};
|
|
1095
|
+
var Status = class {
|
|
1096
|
+
code;
|
|
1097
|
+
errorMsg;
|
|
1098
|
+
constructor(code = StatusCode.OK, errorMsg = "") {
|
|
1099
|
+
this.code = code;
|
|
1100
|
+
this.errorMsg = errorMsg;
|
|
1061
1101
|
}
|
|
1062
|
-
|
|
1063
|
-
return this.
|
|
1102
|
+
ok() {
|
|
1103
|
+
return this.code === StatusCode.OK;
|
|
1064
1104
|
}
|
|
1065
|
-
|
|
1066
|
-
|
|
1105
|
+
};
|
|
1106
|
+
function okStatus() {
|
|
1107
|
+
return new Status(StatusCode.OK);
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
// src/decoder/metadata/MetadataDecoder.ts
|
|
1111
|
+
var kMaxSubmetadataLevel = 1e3;
|
|
1112
|
+
var MetadataDecoder = class {
|
|
1113
|
+
buffer_;
|
|
1114
|
+
constructor() {
|
|
1115
|
+
this.buffer_ = null;
|
|
1067
1116
|
}
|
|
1068
|
-
//
|
|
1069
|
-
|
|
1070
|
-
|
|
1117
|
+
// Skips per-attribute metadata followed by the geometry-level metadata.
|
|
1118
|
+
skipGeometryMetadata(inBuffer) {
|
|
1119
|
+
this.buffer_ = inBuffer;
|
|
1120
|
+
const numAttMetadata = decodeVarint(this.buffer_);
|
|
1121
|
+
if (numAttMetadata === void 0) {
|
|
1122
|
+
return false;
|
|
1123
|
+
}
|
|
1124
|
+
for (let i = 0; i < numAttMetadata; ++i) {
|
|
1125
|
+
if (decodeVarint(this.buffer_) === void 0) {
|
|
1126
|
+
return false;
|
|
1127
|
+
}
|
|
1128
|
+
if (!this._skipMetadata(0)) {
|
|
1129
|
+
return false;
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
return this._skipMetadata(0);
|
|
1071
1133
|
}
|
|
1072
|
-
//
|
|
1073
|
-
// first
|
|
1074
|
-
|
|
1075
|
-
if (
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
}
|
|
1086
|
-
this._effectiveOpposite = eff;
|
|
1134
|
+
// Discards one metadata block (key-value entries plus nested sub-metadata).
|
|
1135
|
+
// Sub-blocks read depth-first in stream order, matching the C++ stack traversal.
|
|
1136
|
+
_skipMetadata(level) {
|
|
1137
|
+
if (level > kMaxSubmetadataLevel) {
|
|
1138
|
+
return false;
|
|
1139
|
+
}
|
|
1140
|
+
const numEntries = decodeVarint(this.buffer_);
|
|
1141
|
+
if (numEntries === void 0) {
|
|
1142
|
+
return false;
|
|
1143
|
+
}
|
|
1144
|
+
for (let i = 0; i < numEntries; ++i) {
|
|
1145
|
+
if (!this._skipEntry()) {
|
|
1146
|
+
return false;
|
|
1087
1147
|
}
|
|
1088
1148
|
}
|
|
1089
|
-
|
|
1149
|
+
const numSubMetadata = decodeVarint(this.buffer_);
|
|
1150
|
+
if (numSubMetadata === void 0) {
|
|
1151
|
+
return false;
|
|
1152
|
+
}
|
|
1153
|
+
if (numSubMetadata > this.buffer_.remainingSize) {
|
|
1154
|
+
return false;
|
|
1155
|
+
}
|
|
1156
|
+
for (let i = 0; i < numSubMetadata; ++i) {
|
|
1157
|
+
if (!this._skipName()) {
|
|
1158
|
+
return false;
|
|
1159
|
+
}
|
|
1160
|
+
if (!this._skipMetadata(level + 1)) {
|
|
1161
|
+
return false;
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
return true;
|
|
1090
1165
|
}
|
|
1091
|
-
|
|
1092
|
-
|
|
1166
|
+
// Skips a key-value entry: name then a length-prefixed value.
|
|
1167
|
+
_skipEntry() {
|
|
1168
|
+
if (!this._skipName()) {
|
|
1169
|
+
return false;
|
|
1170
|
+
}
|
|
1171
|
+
const dataSize = decodeVarint(this.buffer_);
|
|
1172
|
+
if (dataSize === void 0 || dataSize === 0) {
|
|
1173
|
+
return false;
|
|
1174
|
+
}
|
|
1175
|
+
return this._skipBytes(dataSize);
|
|
1093
1176
|
}
|
|
1094
|
-
//
|
|
1095
|
-
|
|
1096
|
-
|
|
1177
|
+
// Skips a name (uint8 length prefix followed by that many bytes).
|
|
1178
|
+
_skipName() {
|
|
1179
|
+
const nameLen = this.buffer_.decodeUint8();
|
|
1180
|
+
if (nameLen === void 0) {
|
|
1181
|
+
return false;
|
|
1182
|
+
}
|
|
1183
|
+
if (nameLen === 0) {
|
|
1184
|
+
return true;
|
|
1185
|
+
}
|
|
1186
|
+
return this._skipBytes(nameLen);
|
|
1097
1187
|
}
|
|
1098
|
-
|
|
1099
|
-
if (
|
|
1100
|
-
|
|
1101
|
-
const seamB = other.is_edge_on_seam_;
|
|
1102
|
-
if (seamA.length !== seamB.length) return false;
|
|
1103
|
-
for (let i = 0, l = seamA.length; i < l; ++i) {
|
|
1104
|
-
if (seamA[i] !== seamB[i]) return false;
|
|
1188
|
+
_skipBytes(size) {
|
|
1189
|
+
if (size > this.buffer_.remainingSize) {
|
|
1190
|
+
return false;
|
|
1105
1191
|
}
|
|
1192
|
+
this.buffer_.advance(size);
|
|
1106
1193
|
return true;
|
|
1107
1194
|
}
|
|
1108
|
-
adoptVertexRecompute(other) {
|
|
1109
|
-
this.corner_to_vertex_map_ = other.corner_to_vertex_map_;
|
|
1110
|
-
this.vertex_to_attribute_entry_id_map_ = other.vertex_to_attribute_entry_id_map_;
|
|
1111
|
-
this.vertex_to_left_most_corner_map_ = other.vertex_to_left_most_corner_map_;
|
|
1112
|
-
this.no_interior_seams_ = other.no_interior_seams_;
|
|
1113
|
-
this._effectiveOpposite = other._effectiveOpposite;
|
|
1114
|
-
this._seamCorners = other._seamCorners;
|
|
1115
|
-
}
|
|
1116
|
-
isDegenerated(faceIndex) {
|
|
1117
|
-
return this.corner_table_.isDegenerated(faceIndex);
|
|
1118
|
-
}
|
|
1119
1195
|
};
|
|
1120
1196
|
|
|
1121
|
-
// src/decoder/
|
|
1122
|
-
var
|
|
1123
|
-
|
|
1124
|
-
INT8: 1,
|
|
1125
|
-
UINT8: 2,
|
|
1126
|
-
INT16: 3,
|
|
1127
|
-
UINT16: 4,
|
|
1128
|
-
INT32: 5,
|
|
1129
|
-
UINT32: 6,
|
|
1130
|
-
INT64: 7,
|
|
1131
|
-
UINT64: 8,
|
|
1132
|
-
FLOAT32: 9,
|
|
1133
|
-
FLOAT64: 10,
|
|
1134
|
-
BOOL: 11,
|
|
1135
|
-
TYPES_COUNT: 12
|
|
1136
|
-
};
|
|
1137
|
-
function dataTypeLength(dt) {
|
|
1138
|
-
switch (dt) {
|
|
1139
|
-
case DataType.INT8:
|
|
1140
|
-
case DataType.UINT8:
|
|
1141
|
-
return 1;
|
|
1142
|
-
case DataType.INT16:
|
|
1143
|
-
case DataType.UINT16:
|
|
1144
|
-
return 2;
|
|
1145
|
-
case DataType.INT32:
|
|
1146
|
-
case DataType.UINT32:
|
|
1147
|
-
return 4;
|
|
1148
|
-
case DataType.INT64:
|
|
1149
|
-
case DataType.UINT64:
|
|
1150
|
-
return 8;
|
|
1151
|
-
case DataType.FLOAT32:
|
|
1152
|
-
return 4;
|
|
1153
|
-
case DataType.FLOAT64:
|
|
1154
|
-
return 8;
|
|
1155
|
-
case DataType.BOOL:
|
|
1156
|
-
return 1;
|
|
1157
|
-
default:
|
|
1158
|
-
return -1;
|
|
1159
|
-
}
|
|
1160
|
-
}
|
|
1161
|
-
|
|
1162
|
-
// src/decoder/attributes/GeometryAttribute.ts
|
|
1163
|
-
var Type = {
|
|
1164
|
-
INVALID: -1,
|
|
1165
|
-
POSITION: 0,
|
|
1166
|
-
NORMAL: 1,
|
|
1167
|
-
COLOR: 2,
|
|
1168
|
-
TEX_COORD: 3,
|
|
1169
|
-
GENERIC: 4,
|
|
1170
|
-
NAMED_ATTRIBUTES_COUNT: 5
|
|
1171
|
-
};
|
|
1172
|
-
var GeometryAttribute = class {
|
|
1197
|
+
// src/decoder/compression/point_cloud/PointCloudDecoder.ts
|
|
1198
|
+
var PointCloudDecoder = class _PointCloudDecoder {
|
|
1199
|
+
_pointCloud;
|
|
1173
1200
|
_buffer;
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
_attributeType;
|
|
1180
|
-
_uniqueId;
|
|
1201
|
+
_versionMajor;
|
|
1202
|
+
_versionMinor;
|
|
1203
|
+
_options;
|
|
1204
|
+
_attributesDecoders;
|
|
1205
|
+
_attributeToDecoderMap;
|
|
1181
1206
|
constructor() {
|
|
1207
|
+
this._pointCloud = null;
|
|
1182
1208
|
this._buffer = null;
|
|
1183
|
-
this.
|
|
1184
|
-
this.
|
|
1185
|
-
this.
|
|
1186
|
-
this.
|
|
1187
|
-
this.
|
|
1188
|
-
this._attributeType = Type.INVALID;
|
|
1189
|
-
this._uniqueId = 0;
|
|
1209
|
+
this._versionMajor = 0;
|
|
1210
|
+
this._versionMinor = 0;
|
|
1211
|
+
this._options = null;
|
|
1212
|
+
this._attributesDecoders = [];
|
|
1213
|
+
this._attributeToDecoderMap = [];
|
|
1190
1214
|
}
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
this._numComponents = numComponents;
|
|
1194
|
-
this._dataType = dataType;
|
|
1195
|
-
this._normalized = normalized;
|
|
1196
|
-
this._byteStride = byteStride;
|
|
1197
|
-
this._byteOffset = byteOffset;
|
|
1198
|
-
this._attributeType = attributeType;
|
|
1215
|
+
getGeometryType() {
|
|
1216
|
+
return EncodedGeometryType.POINT_CLOUD;
|
|
1199
1217
|
}
|
|
1200
|
-
// Returns a
|
|
1201
|
-
|
|
1202
|
-
const
|
|
1203
|
-
|
|
1218
|
+
// Returns a Status; on success outHeader is populated.
|
|
1219
|
+
static decodeHeader(buffer, outHeader) {
|
|
1220
|
+
const kIoErrorMsg = "Failed to parse Draco header.";
|
|
1221
|
+
const bytes = buffer.decodeBytes(5);
|
|
1222
|
+
if (bytes === void 0) {
|
|
1223
|
+
return new Status(StatusCode.IO_ERROR, kIoErrorMsg);
|
|
1224
|
+
}
|
|
1225
|
+
for (let i = 0; i < 5; i++) {
|
|
1226
|
+
outHeader.dracoString[i] = bytes[i];
|
|
1227
|
+
}
|
|
1228
|
+
const magic = String.fromCharCode(bytes[0], bytes[1], bytes[2], bytes[3], bytes[4]);
|
|
1229
|
+
if (magic !== "DRACO") {
|
|
1230
|
+
return new Status(StatusCode.DRACO_ERROR, "Not a Draco file.");
|
|
1231
|
+
}
|
|
1232
|
+
const versionMajor = buffer.decodeUint8();
|
|
1233
|
+
if (versionMajor === void 0) {
|
|
1234
|
+
return new Status(StatusCode.IO_ERROR, kIoErrorMsg);
|
|
1235
|
+
}
|
|
1236
|
+
outHeader.versionMajor = versionMajor;
|
|
1237
|
+
const versionMinor = buffer.decodeUint8();
|
|
1238
|
+
if (versionMinor === void 0) {
|
|
1239
|
+
return new Status(StatusCode.IO_ERROR, kIoErrorMsg);
|
|
1240
|
+
}
|
|
1241
|
+
outHeader.versionMinor = versionMinor;
|
|
1242
|
+
const encoderType = buffer.decodeUint8();
|
|
1243
|
+
if (encoderType === void 0) {
|
|
1244
|
+
return new Status(StatusCode.IO_ERROR, kIoErrorMsg);
|
|
1245
|
+
}
|
|
1246
|
+
outHeader.encoderType = encoderType;
|
|
1247
|
+
const encoderMethod = buffer.decodeUint8();
|
|
1248
|
+
if (encoderMethod === void 0) {
|
|
1249
|
+
return new Status(StatusCode.IO_ERROR, kIoErrorMsg);
|
|
1250
|
+
}
|
|
1251
|
+
outHeader.encoderMethod = encoderMethod;
|
|
1252
|
+
const flags = buffer.decodeUint16();
|
|
1253
|
+
if (flags === void 0) {
|
|
1254
|
+
return new Status(StatusCode.IO_ERROR, kIoErrorMsg);
|
|
1255
|
+
}
|
|
1256
|
+
outHeader.flags = flags;
|
|
1257
|
+
return okStatus();
|
|
1204
1258
|
}
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
this.
|
|
1208
|
-
this.
|
|
1209
|
-
this.
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1259
|
+
// Main entry point for point cloud decoding.
|
|
1260
|
+
decode(options, inBuffer, outPointCloud) {
|
|
1261
|
+
this._options = options;
|
|
1262
|
+
this._buffer = inBuffer;
|
|
1263
|
+
this._pointCloud = outPointCloud;
|
|
1264
|
+
const header = new DracoHeader();
|
|
1265
|
+
const headerStatus = _PointCloudDecoder.decodeHeader(this._buffer, header);
|
|
1266
|
+
if (!headerStatus.ok()) {
|
|
1267
|
+
return headerStatus;
|
|
1268
|
+
}
|
|
1269
|
+
if (header.encoderType !== this.getGeometryType()) {
|
|
1270
|
+
return new Status(StatusCode.DRACO_ERROR, "Using incompatible decoder for the input geometry.");
|
|
1271
|
+
}
|
|
1272
|
+
this._versionMajor = header.versionMajor;
|
|
1273
|
+
this._versionMinor = header.versionMinor;
|
|
1274
|
+
const maxSupportedMajorVersion = header.encoderType === EncodedGeometryType.POINT_CLOUD ? kDracoPointCloudBitstreamVersionMajor : kDracoMeshBitstreamVersionMajor;
|
|
1275
|
+
const maxSupportedMinorVersion = header.encoderType === EncodedGeometryType.POINT_CLOUD ? kDracoPointCloudBitstreamVersionMinor : kDracoMeshBitstreamVersionMinor;
|
|
1276
|
+
if (this._versionMajor < 1 || this._versionMajor > maxSupportedMajorVersion) {
|
|
1277
|
+
return new Status(StatusCode.UNKNOWN_VERSION, "Unknown major version.");
|
|
1278
|
+
}
|
|
1279
|
+
if (this._versionMajor === maxSupportedMajorVersion && this._versionMinor > maxSupportedMinorVersion) {
|
|
1280
|
+
return new Status(StatusCode.UNKNOWN_VERSION, "Unknown minor version.");
|
|
1281
|
+
}
|
|
1282
|
+
this._buffer.bitstreamVersion = DRACO_BITSTREAM_VERSION(this._versionMajor, this._versionMinor);
|
|
1283
|
+
if (header.encoderType === EncodedGeometryType.TRIANGULAR_MESH && this._buffer.bitstreamVersion < DRACO_BITSTREAM_VERSION(2, 2)) {
|
|
1284
|
+
return new Status(
|
|
1285
|
+
StatusCode.UNKNOWN_VERSION,
|
|
1286
|
+
"Unsupported bitstream version (only Draco 2.2 meshes are supported)."
|
|
1287
|
+
);
|
|
1288
|
+
}
|
|
1289
|
+
if (header.flags & METADATA_FLAG_MASK) {
|
|
1290
|
+
const metadataStatus = this._decodeMetadata();
|
|
1291
|
+
if (!metadataStatus.ok()) {
|
|
1292
|
+
return metadataStatus;
|
|
1218
1293
|
}
|
|
1219
|
-
this._buffer.update(srcAtt._buffer.data, srcAtt._buffer.dataSize);
|
|
1220
1294
|
}
|
|
1295
|
+
if (!this.initializeDecoder()) {
|
|
1296
|
+
return new Status(StatusCode.DRACO_ERROR, "Failed to initialize the decoder.");
|
|
1297
|
+
}
|
|
1298
|
+
if (!this.decodeGeometryData()) {
|
|
1299
|
+
return new Status(StatusCode.DRACO_ERROR, "Failed to decode geometry data.");
|
|
1300
|
+
}
|
|
1301
|
+
if (!this.decodePointAttributes()) {
|
|
1302
|
+
return new Status(StatusCode.DRACO_ERROR, "Failed to decode point attributes.");
|
|
1303
|
+
}
|
|
1304
|
+
return okStatus();
|
|
1305
|
+
}
|
|
1306
|
+
bitstreamVersion() {
|
|
1307
|
+
return DRACO_BITSTREAM_VERSION(this._versionMajor, this._versionMinor);
|
|
1308
|
+
}
|
|
1309
|
+
setAttributesDecoder(attDecoderId, decoder) {
|
|
1310
|
+
if (attDecoderId < 0) {
|
|
1311
|
+
return false;
|
|
1312
|
+
}
|
|
1313
|
+
while (this._attributesDecoders.length <= attDecoderId) {
|
|
1314
|
+
this._attributesDecoders.push(null);
|
|
1315
|
+
}
|
|
1316
|
+
this._attributesDecoders[attDecoderId] = decoder;
|
|
1221
1317
|
return true;
|
|
1222
1318
|
}
|
|
1223
|
-
|
|
1224
|
-
this.
|
|
1225
|
-
|
|
1226
|
-
|
|
1319
|
+
getPortableAttribute(parentAttId) {
|
|
1320
|
+
if (parentAttId < 0 || parentAttId >= this._pointCloud.numAttributes()) {
|
|
1321
|
+
return null;
|
|
1322
|
+
}
|
|
1323
|
+
const parentAttDecoderId = this._attributeToDecoderMap[parentAttId];
|
|
1324
|
+
return this._attributesDecoders[parentAttDecoderId].getPortableAttribute(parentAttId);
|
|
1227
1325
|
}
|
|
1228
|
-
|
|
1229
|
-
return this.
|
|
1326
|
+
attributesDecoder(decId) {
|
|
1327
|
+
return this._attributesDecoders[decId];
|
|
1230
1328
|
}
|
|
1231
|
-
|
|
1232
|
-
return this.
|
|
1329
|
+
numAttributesDecoders() {
|
|
1330
|
+
return this._attributesDecoders.length;
|
|
1233
1331
|
}
|
|
1234
|
-
|
|
1235
|
-
return this.
|
|
1332
|
+
pointCloud() {
|
|
1333
|
+
return this._pointCloud;
|
|
1236
1334
|
}
|
|
1237
|
-
|
|
1335
|
+
buffer() {
|
|
1238
1336
|
return this._buffer;
|
|
1239
1337
|
}
|
|
1240
|
-
|
|
1241
|
-
return this.
|
|
1242
|
-
}
|
|
1243
|
-
get byteOffset() {
|
|
1244
|
-
return this._byteOffset;
|
|
1338
|
+
options() {
|
|
1339
|
+
return this._options;
|
|
1245
1340
|
}
|
|
1246
|
-
|
|
1247
|
-
|
|
1341
|
+
// -- Protected virtual methods (override in subclasses) --
|
|
1342
|
+
initializeDecoder() {
|
|
1343
|
+
return true;
|
|
1248
1344
|
}
|
|
1249
|
-
|
|
1250
|
-
|
|
1345
|
+
// Must be implemented by derived classes.
|
|
1346
|
+
createAttributesDecoder(_attDecoderId) {
|
|
1347
|
+
return false;
|
|
1251
1348
|
}
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
// src/decoder/core/DataBuffer.ts
|
|
1255
|
-
var DataBuffer = class {
|
|
1256
|
-
_data;
|
|
1257
|
-
constructor() {
|
|
1258
|
-
this._data = new Uint8Array(0);
|
|
1349
|
+
decodeGeometryData() {
|
|
1350
|
+
return true;
|
|
1259
1351
|
}
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
}
|
|
1265
|
-
|
|
1266
|
-
if (
|
|
1267
|
-
|
|
1352
|
+
decodePointAttributes() {
|
|
1353
|
+
const numAttributesDecoders = this._buffer.decodeUint8();
|
|
1354
|
+
if (numAttributesDecoders === void 0) {
|
|
1355
|
+
return false;
|
|
1356
|
+
}
|
|
1357
|
+
for (let i = 0; i < numAttributesDecoders; ++i) {
|
|
1358
|
+
if (!this.createAttributesDecoder(i)) {
|
|
1359
|
+
return false;
|
|
1268
1360
|
}
|
|
1269
|
-
const view = data;
|
|
1270
|
-
const src = new Uint8Array(view.buffer || data, view.byteOffset || 0, size);
|
|
1271
|
-
this._data.set(src, offset);
|
|
1272
1361
|
}
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
}
|
|
1278
|
-
write(bytePos, inArray, dataSize) {
|
|
1279
|
-
if (inArray instanceof Uint8Array) {
|
|
1280
|
-
this._data.set(inArray.length === dataSize ? inArray : inArray.subarray(0, dataSize), bytePos);
|
|
1281
|
-
return;
|
|
1362
|
+
for (let i = 0; i < this._attributesDecoders.length; ++i) {
|
|
1363
|
+
if (!this._attributesDecoders[i].init(this, this._pointCloud)) {
|
|
1364
|
+
return false;
|
|
1365
|
+
}
|
|
1282
1366
|
}
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
get data() {
|
|
1288
|
-
return this._data;
|
|
1289
|
-
}
|
|
1290
|
-
get dataSize() {
|
|
1291
|
-
return this._data.length;
|
|
1292
|
-
}
|
|
1293
|
-
_resize(newSize) {
|
|
1294
|
-
if (newSize === this._data.length) return;
|
|
1295
|
-
const newData = new Uint8Array(newSize);
|
|
1296
|
-
newData.set(this._data.subarray(0, Math.min(this._data.length, newSize)));
|
|
1297
|
-
this._data = newData;
|
|
1298
|
-
}
|
|
1299
|
-
};
|
|
1300
|
-
|
|
1301
|
-
// src/decoder/attributes/GeometryIndices.ts
|
|
1302
|
-
var kInvalidAttributeValueIndex = 4294967295 >>> 0;
|
|
1303
|
-
|
|
1304
|
-
// src/decoder/attributes/PointAttribute.ts
|
|
1305
|
-
var PointAttribute = class extends GeometryAttribute {
|
|
1306
|
-
_identityMapping;
|
|
1307
|
-
_numUniqueEntries;
|
|
1308
|
-
_indicesMap;
|
|
1309
|
-
_attributeBuffer;
|
|
1310
|
-
_attributeTransformData;
|
|
1311
|
-
// Lazily-created cached views over the attribute buffer.
|
|
1312
|
-
_cachedFloat32View;
|
|
1313
|
-
_cachedFloat32Buffer;
|
|
1314
|
-
_cachedInt32View;
|
|
1315
|
-
_cachedInt32Buffer;
|
|
1316
|
-
_cachedUint32View;
|
|
1317
|
-
_cachedUint32Buffer;
|
|
1318
|
-
_cachedUint16View;
|
|
1319
|
-
_cachedUint16Buffer;
|
|
1320
|
-
_cachedInt16View;
|
|
1321
|
-
_cachedInt16Buffer;
|
|
1322
|
-
_cachedUint8View;
|
|
1323
|
-
_cachedUint8Buffer;
|
|
1324
|
-
_cachedInt8View;
|
|
1325
|
-
_cachedInt8Buffer;
|
|
1326
|
-
_cachedFloat64View;
|
|
1327
|
-
_cachedFloat64Buffer;
|
|
1328
|
-
_cachedDataView;
|
|
1329
|
-
_cachedDVBuffer;
|
|
1330
|
-
constructor(geometryAttribute) {
|
|
1331
|
-
super();
|
|
1332
|
-
this._identityMapping = false;
|
|
1333
|
-
this._numUniqueEntries = 0;
|
|
1334
|
-
this._indicesMap = [];
|
|
1335
|
-
this._attributeBuffer = null;
|
|
1336
|
-
this._attributeTransformData = null;
|
|
1337
|
-
if (geometryAttribute instanceof GeometryAttribute) {
|
|
1338
|
-
this._buffer = geometryAttribute._buffer;
|
|
1339
|
-
this._numComponents = geometryAttribute._numComponents;
|
|
1340
|
-
this._dataType = geometryAttribute._dataType;
|
|
1341
|
-
this._normalized = geometryAttribute._normalized;
|
|
1342
|
-
this._byteStride = geometryAttribute._byteStride;
|
|
1343
|
-
this._byteOffset = geometryAttribute._byteOffset;
|
|
1344
|
-
this._attributeType = geometryAttribute._attributeType;
|
|
1345
|
-
this._uniqueId = geometryAttribute._uniqueId;
|
|
1367
|
+
for (let i = 0; i < numAttributesDecoders; ++i) {
|
|
1368
|
+
if (!this._attributesDecoders[i].decodeAttributesDecoderData(this._buffer)) {
|
|
1369
|
+
return false;
|
|
1370
|
+
}
|
|
1346
1371
|
}
|
|
1372
|
+
for (let i = 0; i < numAttributesDecoders; ++i) {
|
|
1373
|
+
const numAttributes = this._attributesDecoders[i].getNumAttributes();
|
|
1374
|
+
for (let j = 0; j < numAttributes; ++j) {
|
|
1375
|
+
const attId = this._attributesDecoders[i].getAttributeId(j);
|
|
1376
|
+
while (this._attributeToDecoderMap.length <= attId) {
|
|
1377
|
+
this._attributeToDecoderMap.push(0);
|
|
1378
|
+
}
|
|
1379
|
+
this._attributeToDecoderMap[attId] = i;
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
if (!this.decodeAllAttributes()) {
|
|
1383
|
+
return false;
|
|
1384
|
+
}
|
|
1385
|
+
if (!this.onAttributesDecoded()) {
|
|
1386
|
+
return false;
|
|
1387
|
+
}
|
|
1388
|
+
return true;
|
|
1347
1389
|
}
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
super.init(attributeType, this._attributeBuffer, numComponents, dataType, normalized, byteStride, 0);
|
|
1354
|
-
this.reset(numAttributeValues);
|
|
1355
|
-
this.setIdentityMapping();
|
|
1356
|
-
}
|
|
1357
|
-
reset(numAttributeValues) {
|
|
1358
|
-
if (this._attributeBuffer === null) {
|
|
1359
|
-
this._attributeBuffer = new DataBuffer();
|
|
1390
|
+
decodeAllAttributes() {
|
|
1391
|
+
for (let i = 0; i < this._attributesDecoders.length; i++) {
|
|
1392
|
+
if (!this._attributesDecoders[i].decodeAttributes(this._buffer)) {
|
|
1393
|
+
return false;
|
|
1394
|
+
}
|
|
1360
1395
|
}
|
|
1361
|
-
const entrySize = dataTypeLength(this.dataType) * this.numComponents;
|
|
1362
|
-
this._attributeBuffer.update(null, numAttributeValues * entrySize);
|
|
1363
|
-
this.resetBuffer(this._attributeBuffer, entrySize, 0);
|
|
1364
|
-
this._numUniqueEntries = numAttributeValues;
|
|
1365
1396
|
return true;
|
|
1366
1397
|
}
|
|
1367
|
-
|
|
1368
|
-
return
|
|
1398
|
+
onAttributesDecoded() {
|
|
1399
|
+
return true;
|
|
1369
1400
|
}
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1401
|
+
_decodeMetadata() {
|
|
1402
|
+
const metadataDecoder = new MetadataDecoder();
|
|
1403
|
+
if (!metadataDecoder.skipGeometryMetadata(this._buffer)) {
|
|
1404
|
+
return new Status(StatusCode.DRACO_ERROR, "Failed to decode metadata.");
|
|
1373
1405
|
}
|
|
1374
|
-
return
|
|
1406
|
+
return okStatus();
|
|
1375
1407
|
}
|
|
1376
|
-
|
|
1377
|
-
|
|
1408
|
+
};
|
|
1409
|
+
|
|
1410
|
+
// src/decoder/compression/mesh/MeshDecoder.ts
|
|
1411
|
+
var MeshDecoder = class extends PointCloudDecoder {
|
|
1412
|
+
_mesh;
|
|
1413
|
+
constructor() {
|
|
1414
|
+
super();
|
|
1415
|
+
this._mesh = null;
|
|
1378
1416
|
}
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
return 0;
|
|
1382
|
-
}
|
|
1383
|
-
return this._indicesMap.length;
|
|
1417
|
+
getGeometryType() {
|
|
1418
|
+
return EncodedGeometryType.TRIANGULAR_MESH;
|
|
1384
1419
|
}
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
get indicesMap() {
|
|
1389
|
-
return this._indicesMap;
|
|
1420
|
+
decodeMesh(options, inBuffer, outMesh) {
|
|
1421
|
+
this._mesh = outMesh;
|
|
1422
|
+
return this.decode(options, inBuffer, outMesh);
|
|
1390
1423
|
}
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
this._identityMapping = true;
|
|
1394
|
-
this._indicesMap = [];
|
|
1424
|
+
getCornerTable() {
|
|
1425
|
+
return null;
|
|
1395
1426
|
}
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
this._indicesMap = new Uint32Array(numPoints);
|
|
1399
|
-
this._indicesMap.fill(kInvalidAttributeValueIndex);
|
|
1427
|
+
getAttributeCornerTable(_attId) {
|
|
1428
|
+
return null;
|
|
1400
1429
|
}
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
// time on primitive-heavy files). The array still starts zeroed by the
|
|
1404
|
-
// engine, so a buggy caller reads valid-looking zeros — hence opt-in.
|
|
1405
|
-
setExplicitMappingUnfilled(numPoints) {
|
|
1406
|
-
this._identityMapping = false;
|
|
1407
|
-
this._indicesMap = new Uint32Array(numPoints);
|
|
1430
|
+
getAttributeEncodingData(_attId) {
|
|
1431
|
+
return null;
|
|
1408
1432
|
}
|
|
1409
|
-
|
|
1410
|
-
this.
|
|
1433
|
+
mesh() {
|
|
1434
|
+
return this._mesh;
|
|
1411
1435
|
}
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
const bufData = this._buffer.data;
|
|
1416
|
-
const dt = this._dataType;
|
|
1417
|
-
const nc = this._numComponents;
|
|
1418
|
-
if (dt === DataType.FLOAT32) {
|
|
1419
|
-
if (this._cachedFloat32View === void 0 || this._cachedFloat32Buffer !== bufData.buffer) {
|
|
1420
|
-
this._cachedFloat32Buffer = bufData.buffer;
|
|
1421
|
-
this._cachedFloat32View = new Float32Array(bufData.buffer);
|
|
1422
|
-
}
|
|
1423
|
-
const baseIndex = bufData.byteOffset + bytePos >> 2;
|
|
1424
|
-
for (let i = 0; i < nc; ++i) {
|
|
1425
|
-
outVal[i] = this._cachedFloat32View[baseIndex + i];
|
|
1426
|
-
}
|
|
1427
|
-
return;
|
|
1428
|
-
}
|
|
1429
|
-
if (dt === DataType.INT32) {
|
|
1430
|
-
if (this._cachedInt32View === void 0 || this._cachedInt32Buffer !== bufData.buffer) {
|
|
1431
|
-
this._cachedInt32Buffer = bufData.buffer;
|
|
1432
|
-
this._cachedInt32View = new Int32Array(bufData.buffer);
|
|
1433
|
-
}
|
|
1434
|
-
const baseIndex = bufData.byteOffset + bytePos >> 2;
|
|
1435
|
-
for (let i = 0; i < nc; ++i) {
|
|
1436
|
-
outVal[i] = this._cachedInt32View[baseIndex + i];
|
|
1437
|
-
}
|
|
1438
|
-
return;
|
|
1439
|
-
}
|
|
1440
|
-
if (dt === DataType.UINT32) {
|
|
1441
|
-
if (this._cachedUint32View === void 0 || this._cachedUint32Buffer !== bufData.buffer) {
|
|
1442
|
-
this._cachedUint32Buffer = bufData.buffer;
|
|
1443
|
-
this._cachedUint32View = new Uint32Array(bufData.buffer);
|
|
1444
|
-
}
|
|
1445
|
-
const baseIndex = bufData.byteOffset + bytePos >> 2;
|
|
1446
|
-
for (let i = 0; i < nc; ++i) {
|
|
1447
|
-
outVal[i] = this._cachedUint32View[baseIndex + i];
|
|
1448
|
-
}
|
|
1449
|
-
return;
|
|
1450
|
-
}
|
|
1451
|
-
if (this._cachedDataView === void 0 || this._cachedDVBuffer !== bufData.buffer) {
|
|
1452
|
-
this._cachedDVBuffer = bufData.buffer;
|
|
1453
|
-
this._cachedDataView = new DataView(bufData.buffer, bufData.byteOffset, bufData.byteLength);
|
|
1436
|
+
decodeGeometryData() {
|
|
1437
|
+
if (this._mesh === null) {
|
|
1438
|
+
return false;
|
|
1454
1439
|
}
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
switch (dt) {
|
|
1458
|
-
case DataType.INT8:
|
|
1459
|
-
outVal[i] = dv.getInt8(bytePos + i);
|
|
1460
|
-
break;
|
|
1461
|
-
case DataType.UINT8:
|
|
1462
|
-
outVal[i] = dv.getUint8(bytePos + i);
|
|
1463
|
-
break;
|
|
1464
|
-
case DataType.INT16:
|
|
1465
|
-
outVal[i] = dv.getInt16(bytePos + i * 2, true);
|
|
1466
|
-
break;
|
|
1467
|
-
case DataType.UINT16:
|
|
1468
|
-
outVal[i] = dv.getUint16(bytePos + i * 2, true);
|
|
1469
|
-
break;
|
|
1470
|
-
case DataType.INT32:
|
|
1471
|
-
outVal[i] = dv.getInt32(bytePos + i * 4, true);
|
|
1472
|
-
break;
|
|
1473
|
-
case DataType.UINT32:
|
|
1474
|
-
outVal[i] = dv.getUint32(bytePos + i * 4, true);
|
|
1475
|
-
break;
|
|
1476
|
-
case DataType.FLOAT64:
|
|
1477
|
-
outVal[i] = dv.getFloat64(bytePos + i * 8, true);
|
|
1478
|
-
break;
|
|
1479
|
-
default:
|
|
1480
|
-
outVal[i] = 0;
|
|
1481
|
-
break;
|
|
1482
|
-
}
|
|
1440
|
+
if (!this.decodeConnectivity()) {
|
|
1441
|
+
return false;
|
|
1483
1442
|
}
|
|
1443
|
+
return super.decodeGeometryData();
|
|
1484
1444
|
}
|
|
1485
|
-
//
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1445
|
+
// Overridden by derived classes.
|
|
1446
|
+
decodeConnectivity() {
|
|
1447
|
+
return false;
|
|
1448
|
+
}
|
|
1449
|
+
};
|
|
1450
|
+
|
|
1451
|
+
// src/decoder/mesh/MeshAttributeCornerTable.ts
|
|
1452
|
+
var kInvalidCornerIndex = -1;
|
|
1453
|
+
var kInvalidVertexIndex = -1;
|
|
1454
|
+
var MeshAttributeCornerTable = class {
|
|
1455
|
+
is_edge_on_seam_;
|
|
1456
|
+
is_vertex_on_seam_;
|
|
1457
|
+
no_interior_seams_;
|
|
1458
|
+
corner_to_vertex_map_;
|
|
1459
|
+
vertex_to_left_most_corner_map_;
|
|
1460
|
+
vertex_to_attribute_entry_id_map_;
|
|
1461
|
+
corner_table_;
|
|
1462
|
+
// Lazily built; see oppositeCornerArray.
|
|
1463
|
+
_effectiveOpposite;
|
|
1464
|
+
// Every corner passed to addSeamEdge (may contain duplicates); lets
|
|
1465
|
+
// oppositeCornerArray patch seams without scanning every corner's flag.
|
|
1466
|
+
_seamCorners;
|
|
1467
|
+
constructor() {
|
|
1468
|
+
this.is_edge_on_seam_ = [];
|
|
1469
|
+
this.is_vertex_on_seam_ = [];
|
|
1470
|
+
this.no_interior_seams_ = true;
|
|
1471
|
+
this.corner_to_vertex_map_ = [];
|
|
1472
|
+
this.vertex_to_left_most_corner_map_ = [];
|
|
1473
|
+
this.vertex_to_attribute_entry_id_map_ = [];
|
|
1474
|
+
this.corner_table_ = null;
|
|
1475
|
+
this._effectiveOpposite = null;
|
|
1476
|
+
this._seamCorners = [];
|
|
1477
|
+
}
|
|
1478
|
+
initEmpty(table) {
|
|
1479
|
+
if (table === null) {
|
|
1480
|
+
return false;
|
|
1492
1481
|
}
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
} else if (dt === DataType.UINT16) {
|
|
1523
|
-
if (this._cachedUint16View === void 0 || this._cachedUint16Buffer !== bufData.buffer) {
|
|
1524
|
-
this._cachedUint16Buffer = bufData.buffer;
|
|
1525
|
-
this._cachedUint16View = new Uint16Array(bufData.buffer);
|
|
1526
|
-
}
|
|
1527
|
-
srcView = this._cachedUint16View;
|
|
1528
|
-
shift = 1;
|
|
1529
|
-
} else if (dt === DataType.INT16) {
|
|
1530
|
-
if (this._cachedInt16View === void 0 || this._cachedInt16Buffer !== bufData.buffer) {
|
|
1531
|
-
this._cachedInt16Buffer = bufData.buffer;
|
|
1532
|
-
this._cachedInt16View = new Int16Array(bufData.buffer);
|
|
1533
|
-
}
|
|
1534
|
-
srcView = this._cachedInt16View;
|
|
1535
|
-
shift = 1;
|
|
1536
|
-
} else if (dt === DataType.UINT8) {
|
|
1537
|
-
if (this._cachedUint8View === void 0 || this._cachedUint8Buffer !== bufData.buffer) {
|
|
1538
|
-
this._cachedUint8Buffer = bufData.buffer;
|
|
1539
|
-
this._cachedUint8View = new Uint8Array(bufData.buffer);
|
|
1540
|
-
}
|
|
1541
|
-
srcView = this._cachedUint8View;
|
|
1542
|
-
shift = 0;
|
|
1543
|
-
} else if (dt === DataType.INT8) {
|
|
1544
|
-
if (this._cachedInt8View === void 0 || this._cachedInt8Buffer !== bufData.buffer) {
|
|
1545
|
-
this._cachedInt8Buffer = bufData.buffer;
|
|
1546
|
-
this._cachedInt8View = new Int8Array(bufData.buffer);
|
|
1547
|
-
}
|
|
1548
|
-
srcView = this._cachedInt8View;
|
|
1549
|
-
shift = 0;
|
|
1550
|
-
} else if (dt === DataType.FLOAT64) {
|
|
1551
|
-
if (this._cachedFloat64View === void 0 || this._cachedFloat64Buffer !== bufData.buffer) {
|
|
1552
|
-
this._cachedFloat64Buffer = bufData.buffer;
|
|
1553
|
-
this._cachedFloat64View = new Float64Array(bufData.buffer);
|
|
1554
|
-
}
|
|
1555
|
-
srcView = this._cachedFloat64View;
|
|
1556
|
-
shift = 3;
|
|
1482
|
+
this.is_edge_on_seam_ = new Uint8Array(table.numCorners());
|
|
1483
|
+
this.is_vertex_on_seam_ = new Uint8Array(table.numVertices());
|
|
1484
|
+
this.corner_to_vertex_map_ = new Int32Array(table.numCorners()).fill(kInvalidVertexIndex);
|
|
1485
|
+
this.vertex_to_attribute_entry_id_map_ = [];
|
|
1486
|
+
this.vertex_to_left_most_corner_map_ = [];
|
|
1487
|
+
this._effectiveOpposite = null;
|
|
1488
|
+
this._seamCorners = [];
|
|
1489
|
+
this.corner_table_ = table;
|
|
1490
|
+
this.no_interior_seams_ = true;
|
|
1491
|
+
return true;
|
|
1492
|
+
}
|
|
1493
|
+
addSeamEdge(c) {
|
|
1494
|
+
const cornerToVertex = this.corner_table_.cornerToVertexArray();
|
|
1495
|
+
const oppositeCorners = this.corner_table_.oppositeCornerArray();
|
|
1496
|
+
const isEdge = this.is_edge_on_seam_;
|
|
1497
|
+
const isVert = this.is_vertex_on_seam_;
|
|
1498
|
+
isEdge[c] = 1;
|
|
1499
|
+
this._seamCorners.push(c);
|
|
1500
|
+
let rem = c - (c / 3 | 0) * 3;
|
|
1501
|
+
isVert[cornerToVertex[rem === 2 ? c - 2 : c + 1]] = 1;
|
|
1502
|
+
isVert[cornerToVertex[rem === 0 ? c + 2 : c - 1]] = 1;
|
|
1503
|
+
const oppCorner = oppositeCorners[c];
|
|
1504
|
+
if (oppCorner !== kInvalidCornerIndex) {
|
|
1505
|
+
this.no_interior_seams_ = false;
|
|
1506
|
+
isEdge[oppCorner] = 1;
|
|
1507
|
+
this._seamCorners.push(oppCorner);
|
|
1508
|
+
rem = oppCorner - (oppCorner / 3 | 0) * 3;
|
|
1509
|
+
isVert[cornerToVertex[rem === 2 ? oppCorner - 2 : oppCorner + 1]] = 1;
|
|
1510
|
+
isVert[cornerToVertex[rem === 0 ? oppCorner + 2 : oppCorner - 1]] = 1;
|
|
1557
1511
|
}
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
array[dst + 1] = srcView[srcOffset + 1];
|
|
1592
|
-
dst += 2;
|
|
1593
|
-
}
|
|
1594
|
-
} else if (numComponents === 4) {
|
|
1595
|
-
let dst = 0;
|
|
1596
|
-
for (let i = 0; i < numPoints; i++) {
|
|
1597
|
-
const srcOffset = srcStart + indicesMap[i] * strideElements;
|
|
1598
|
-
array[dst] = srcView[srcOffset];
|
|
1599
|
-
array[dst + 1] = srcView[srcOffset + 1];
|
|
1600
|
-
array[dst + 2] = srcView[srcOffset + 2];
|
|
1601
|
-
array[dst + 3] = srcView[srcOffset + 3];
|
|
1602
|
-
dst += 4;
|
|
1512
|
+
}
|
|
1513
|
+
recomputeVertices(_cornerTable, _vertexIds) {
|
|
1514
|
+
return this._recomputeVerticesInternal();
|
|
1515
|
+
}
|
|
1516
|
+
// Only the C++ RecomputeVertices(nullptr, nullptr) path: the decoder always
|
|
1517
|
+
// rebuilds the attribute-vertex maps from connectivity alone.
|
|
1518
|
+
_recomputeVerticesInternal() {
|
|
1519
|
+
const ct = this.corner_table_;
|
|
1520
|
+
const numCorners = ct.numCorners();
|
|
1521
|
+
const numBaseVertices = ct.numVertices();
|
|
1522
|
+
const leftMostMap = new Int32Array(numCorners);
|
|
1523
|
+
const cornerToVertex = this.corner_to_vertex_map_;
|
|
1524
|
+
const isVertexOnSeam = this.is_vertex_on_seam_;
|
|
1525
|
+
const isEdgeOnSeam = this.is_edge_on_seam_;
|
|
1526
|
+
const seamOpp = this.oppositeCornerArray();
|
|
1527
|
+
const baseOpp = ct.oppositeCornerArray();
|
|
1528
|
+
const vertexLeftmost = ct.vertexLeftmostCornerArray();
|
|
1529
|
+
let numNewVertices = 0;
|
|
1530
|
+
for (let v = 0; v < numBaseVertices; ++v) {
|
|
1531
|
+
const c = vertexLeftmost[v];
|
|
1532
|
+
if (c === kInvalidCornerIndex) continue;
|
|
1533
|
+
if (!isVertexOnSeam[v]) {
|
|
1534
|
+
const firstVertId = numNewVertices++;
|
|
1535
|
+
leftMostMap[firstVertId] = c;
|
|
1536
|
+
cornerToVertex[c] = firstVertId;
|
|
1537
|
+
let pv = c % 3 === 0 ? c + 2 : c - 1;
|
|
1538
|
+
let bopp = baseOpp[pv];
|
|
1539
|
+
let actC = bopp < 0 ? kInvalidCornerIndex : bopp % 3 === 0 ? bopp + 2 : bopp - 1;
|
|
1540
|
+
while (actC !== kInvalidCornerIndex && actC !== c) {
|
|
1541
|
+
cornerToVertex[actC] = firstVertId;
|
|
1542
|
+
pv = actC % 3 === 0 ? actC + 2 : actC - 1;
|
|
1543
|
+
bopp = baseOpp[pv];
|
|
1544
|
+
actC = bopp < 0 ? kInvalidCornerIndex : bopp % 3 === 0 ? bopp + 2 : bopp - 1;
|
|
1603
1545
|
}
|
|
1604
|
-
} else
|
|
1605
|
-
let
|
|
1606
|
-
|
|
1607
|
-
|
|
1546
|
+
} else {
|
|
1547
|
+
let firstVertId = numNewVertices++;
|
|
1548
|
+
let firstC = c;
|
|
1549
|
+
let actC;
|
|
1550
|
+
let nx = firstC % 3 === 2 ? firstC - 2 : firstC + 1;
|
|
1551
|
+
let opp = seamOpp[nx];
|
|
1552
|
+
actC = opp < 0 ? kInvalidCornerIndex : opp % 3 === 2 ? opp - 2 : opp + 1;
|
|
1553
|
+
while (actC !== kInvalidCornerIndex) {
|
|
1554
|
+
firstC = actC;
|
|
1555
|
+
nx = firstC % 3 === 2 ? firstC - 2 : firstC + 1;
|
|
1556
|
+
opp = seamOpp[nx];
|
|
1557
|
+
actC = opp < 0 ? kInvalidCornerIndex : opp % 3 === 2 ? opp - 2 : opp + 1;
|
|
1558
|
+
if (actC === c) return false;
|
|
1608
1559
|
}
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1560
|
+
cornerToVertex[firstC] = firstVertId;
|
|
1561
|
+
leftMostMap[firstVertId] = firstC;
|
|
1562
|
+
let pv = firstC % 3 === 0 ? firstC + 2 : firstC - 1;
|
|
1563
|
+
let bopp = baseOpp[pv];
|
|
1564
|
+
actC = bopp < 0 ? kInvalidCornerIndex : bopp % 3 === 0 ? bopp + 2 : bopp - 1;
|
|
1565
|
+
while (actC !== kInvalidCornerIndex && actC !== firstC) {
|
|
1566
|
+
const nAct = actC % 3 === 2 ? actC - 2 : actC + 1;
|
|
1567
|
+
if (isEdgeOnSeam[nAct]) {
|
|
1568
|
+
firstVertId = numNewVertices++;
|
|
1569
|
+
leftMostMap[firstVertId] = actC;
|
|
1615
1570
|
}
|
|
1616
|
-
|
|
1571
|
+
cornerToVertex[actC] = firstVertId;
|
|
1572
|
+
pv = actC % 3 === 0 ? actC + 2 : actC - 1;
|
|
1573
|
+
bopp = baseOpp[pv];
|
|
1574
|
+
actC = bopp < 0 ? kInvalidCornerIndex : bopp % 3 === 0 ? bopp + 2 : bopp - 1;
|
|
1617
1575
|
}
|
|
1618
1576
|
}
|
|
1619
|
-
return array;
|
|
1620
|
-
}
|
|
1621
|
-
const temp = new Array(numComponents);
|
|
1622
|
-
for (let i = 0; i < numPoints; i++) {
|
|
1623
|
-
const attIndex = isIdentity ? i : indicesMap[i];
|
|
1624
|
-
this.convertValue(attIndex, temp);
|
|
1625
|
-
const dstOffset = i * numComponents;
|
|
1626
|
-
for (let j = 0; j < numComponents; j++) {
|
|
1627
|
-
array[dstOffset + j] = temp[j];
|
|
1628
|
-
}
|
|
1629
1577
|
}
|
|
1630
|
-
|
|
1578
|
+
this.vertex_to_attribute_entry_id_map_ = new Int32Array(numNewVertices);
|
|
1579
|
+
this.vertex_to_left_most_corner_map_ = leftMostMap.subarray(0, numNewVertices);
|
|
1580
|
+
return true;
|
|
1631
1581
|
}
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1582
|
+
isCornerOppositeToSeamEdge(corner) {
|
|
1583
|
+
return this.is_edge_on_seam_[corner];
|
|
1584
|
+
}
|
|
1585
|
+
opposite(corner) {
|
|
1586
|
+
if (corner === kInvalidCornerIndex || this.isCornerOppositeToSeamEdge(corner)) {
|
|
1587
|
+
return kInvalidCornerIndex;
|
|
1638
1588
|
}
|
|
1639
|
-
|
|
1640
|
-
|
|
1589
|
+
return this.corner_table_.opposite(corner);
|
|
1590
|
+
}
|
|
1591
|
+
next(corner) {
|
|
1592
|
+
return this.corner_table_.next(corner);
|
|
1593
|
+
}
|
|
1594
|
+
previous(corner) {
|
|
1595
|
+
return this.corner_table_.previous(corner);
|
|
1596
|
+
}
|
|
1597
|
+
swingRight(corner) {
|
|
1598
|
+
return this.previous(this.opposite(this.previous(corner)));
|
|
1599
|
+
}
|
|
1600
|
+
swingLeft(corner) {
|
|
1601
|
+
return this.next(this.opposite(this.next(corner)));
|
|
1602
|
+
}
|
|
1603
|
+
numVertices() {
|
|
1604
|
+
return this.vertex_to_attribute_entry_id_map_.length;
|
|
1605
|
+
}
|
|
1606
|
+
numFaces() {
|
|
1607
|
+
return this.corner_table_.numFaces();
|
|
1608
|
+
}
|
|
1609
|
+
numCorners() {
|
|
1610
|
+
return this.corner_table_.numCorners();
|
|
1611
|
+
}
|
|
1612
|
+
vertex(corner) {
|
|
1613
|
+
return this.confidentVertex(corner);
|
|
1614
|
+
}
|
|
1615
|
+
confidentVertex(corner) {
|
|
1616
|
+
return this.corner_to_vertex_map_[corner];
|
|
1617
|
+
}
|
|
1618
|
+
leftMostCorner(v) {
|
|
1619
|
+
return this.vertex_to_left_most_corner_map_[v];
|
|
1620
|
+
}
|
|
1621
|
+
// --- Flat-array accessors: let DepthFirstTraverser avoid per-corner dispatch. ---
|
|
1622
|
+
cornerToVertexArray() {
|
|
1623
|
+
return this.corner_to_vertex_map_;
|
|
1624
|
+
}
|
|
1625
|
+
// Seam-aware opposite corners (seam edges -> -1), matching opposite(). Cached on
|
|
1626
|
+
// first use; seams and connectivity are finalized before traversal, so it's stable.
|
|
1627
|
+
oppositeCornerArray() {
|
|
1628
|
+
if (this._effectiveOpposite === null) {
|
|
1629
|
+
const nc = this.corner_table_.numCorners();
|
|
1630
|
+
const base = this.corner_table_.oppositeCornerArray();
|
|
1631
|
+
const seamCorners = this._seamCorners;
|
|
1632
|
+
if (seamCorners.length === 0) {
|
|
1633
|
+
this._effectiveOpposite = base;
|
|
1634
|
+
} else {
|
|
1635
|
+
const eff = scratchInt32(nc);
|
|
1636
|
+
eff.set(base.length === nc ? base : base.subarray(0, nc));
|
|
1637
|
+
for (let i = 0, l = seamCorners.length; i < l; ++i) {
|
|
1638
|
+
eff[seamCorners[i]] = kInvalidCornerIndex;
|
|
1639
|
+
}
|
|
1640
|
+
this._effectiveOpposite = eff;
|
|
1641
|
+
}
|
|
1641
1642
|
}
|
|
1642
|
-
this.
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1643
|
+
return this._effectiveOpposite;
|
|
1644
|
+
}
|
|
1645
|
+
vertexLeftmostCornerArray() {
|
|
1646
|
+
return this.vertex_to_left_most_corner_map_;
|
|
1647
|
+
}
|
|
1648
|
+
// Per-base-vertex seam flag (Uint8Array); exposed so hot dedup loops inline the lookup.
|
|
1649
|
+
vertexOnSeamArray() {
|
|
1650
|
+
return this.is_vertex_on_seam_;
|
|
1651
|
+
}
|
|
1652
|
+
hasSameSeams(other) {
|
|
1653
|
+
if (other === null || other === void 0) return false;
|
|
1654
|
+
const seamA = this.is_edge_on_seam_;
|
|
1655
|
+
const seamB = other.is_edge_on_seam_;
|
|
1656
|
+
if (seamA.length !== seamB.length) return false;
|
|
1657
|
+
for (let i = 0, l = seamA.length; i < l; ++i) {
|
|
1658
|
+
if (seamA[i] !== seamB[i]) return false;
|
|
1649
1659
|
}
|
|
1660
|
+
return true;
|
|
1661
|
+
}
|
|
1662
|
+
adoptVertexRecompute(other) {
|
|
1663
|
+
this.corner_to_vertex_map_ = other.corner_to_vertex_map_;
|
|
1664
|
+
this.vertex_to_attribute_entry_id_map_ = other.vertex_to_attribute_entry_id_map_;
|
|
1665
|
+
this.vertex_to_left_most_corner_map_ = other.vertex_to_left_most_corner_map_;
|
|
1666
|
+
this.no_interior_seams_ = other.no_interior_seams_;
|
|
1667
|
+
this._effectiveOpposite = other._effectiveOpposite;
|
|
1668
|
+
this._seamCorners = other._seamCorners;
|
|
1650
1669
|
}
|
|
1651
1670
|
};
|
|
1652
1671
|
|
|
@@ -1863,15 +1882,12 @@ var SequentialAttributeDecoder = class {
|
|
|
1863
1882
|
decodeValues(pointIds, buffer) {
|
|
1864
1883
|
const numValues = pointIds.length;
|
|
1865
1884
|
const entrySize = this._attribute.byteStride;
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
return false;
|
|
1871
|
-
}
|
|
1872
|
-
this._attribute.buffer.write(outBytePos, valueData, entrySize);
|
|
1873
|
-
outBytePos += entrySize;
|
|
1885
|
+
const totalSize = numValues * entrySize;
|
|
1886
|
+
const valueData = buffer.decodeBytesView(totalSize);
|
|
1887
|
+
if (valueData === void 0) {
|
|
1888
|
+
return false;
|
|
1874
1889
|
}
|
|
1890
|
+
this._attribute.buffer.write(0, valueData, totalSize);
|
|
1875
1891
|
return true;
|
|
1876
1892
|
}
|
|
1877
1893
|
setPortableAttribute(att) {
|
|
@@ -2009,6 +2025,9 @@ var RAnsDecoder = class {
|
|
|
2009
2025
|
this.bufOffset = offset - 3;
|
|
2010
2026
|
this.state = memGetLe24(buf, offset - 3) & 4194303;
|
|
2011
2027
|
} else if (x === 3) {
|
|
2028
|
+
if (offset - base < 4) {
|
|
2029
|
+
return 1;
|
|
2030
|
+
}
|
|
2012
2031
|
this.bufOffset = offset - 4;
|
|
2013
2032
|
this.state = memGetLe32(buf, offset - 4) & 1073741823;
|
|
2014
2033
|
} else {
|
|
@@ -2053,12 +2072,69 @@ var RAnsDecoder = class {
|
|
|
2053
2072
|
}
|
|
2054
2073
|
// Batch ransRead() into out[0..count): all fields hoisted to locals, state
|
|
2055
2074
|
// written back once. Removes per-symbol property reads and call indirection.
|
|
2075
|
+
// lutTable's element type varies per decoder (Uint8/16/32 by symbol count),
|
|
2076
|
+
// which would make the hot lutTable[rem] access site polymorphic — dispatch
|
|
2077
|
+
// once here so each loop body stays monomorphic on its concrete type. The
|
|
2078
|
+
// three bodies are intentionally identical copies.
|
|
2056
2079
|
decodeSymbols(out, count) {
|
|
2080
|
+
const lutTable = this.lutTable;
|
|
2081
|
+
if (lutTable instanceof Uint8Array) {
|
|
2082
|
+
this._decodeSymbolsU8(out, count, lutTable);
|
|
2083
|
+
} else if (lutTable instanceof Uint16Array) {
|
|
2084
|
+
this._decodeSymbolsU16(out, count, lutTable);
|
|
2085
|
+
} else {
|
|
2086
|
+
this._decodeSymbolsU32(out, count, lutTable);
|
|
2087
|
+
}
|
|
2088
|
+
}
|
|
2089
|
+
_decodeSymbolsU8(out, count, lutTable) {
|
|
2090
|
+
const buf = this.buf;
|
|
2091
|
+
const lRansBase = this.lRansBase;
|
|
2092
|
+
const ransPrecisionBits = this.ransPrecisionBits;
|
|
2093
|
+
const ransPrecisionMask = this.ransPrecisionMask;
|
|
2094
|
+
const probTable = this.probTable;
|
|
2095
|
+
const cumProbTable = this.cumProbTable;
|
|
2096
|
+
let state = this.state;
|
|
2097
|
+
let bufOffset = this.bufOffset;
|
|
2098
|
+
const bufStart = this.bufStart;
|
|
2099
|
+
for (let i = 0; i < count; ++i) {
|
|
2100
|
+
while (state < lRansBase && bufOffset > bufStart) {
|
|
2101
|
+
state = state << 8 | buf[--bufOffset];
|
|
2102
|
+
}
|
|
2103
|
+
const rem = state & ransPrecisionMask;
|
|
2104
|
+
const symbol = lutTable[rem];
|
|
2105
|
+
out[i] = symbol;
|
|
2106
|
+
state = (state >>> ransPrecisionBits) * probTable[symbol] + rem - cumProbTable[symbol];
|
|
2107
|
+
}
|
|
2108
|
+
this.state = state;
|
|
2109
|
+
this.bufOffset = bufOffset;
|
|
2110
|
+
}
|
|
2111
|
+
_decodeSymbolsU16(out, count, lutTable) {
|
|
2112
|
+
const buf = this.buf;
|
|
2113
|
+
const lRansBase = this.lRansBase;
|
|
2114
|
+
const ransPrecisionBits = this.ransPrecisionBits;
|
|
2115
|
+
const ransPrecisionMask = this.ransPrecisionMask;
|
|
2116
|
+
const probTable = this.probTable;
|
|
2117
|
+
const cumProbTable = this.cumProbTable;
|
|
2118
|
+
let state = this.state;
|
|
2119
|
+
let bufOffset = this.bufOffset;
|
|
2120
|
+
const bufStart = this.bufStart;
|
|
2121
|
+
for (let i = 0; i < count; ++i) {
|
|
2122
|
+
while (state < lRansBase && bufOffset > bufStart) {
|
|
2123
|
+
state = state << 8 | buf[--bufOffset];
|
|
2124
|
+
}
|
|
2125
|
+
const rem = state & ransPrecisionMask;
|
|
2126
|
+
const symbol = lutTable[rem];
|
|
2127
|
+
out[i] = symbol;
|
|
2128
|
+
state = (state >>> ransPrecisionBits) * probTable[symbol] + rem - cumProbTable[symbol];
|
|
2129
|
+
}
|
|
2130
|
+
this.state = state;
|
|
2131
|
+
this.bufOffset = bufOffset;
|
|
2132
|
+
}
|
|
2133
|
+
_decodeSymbolsU32(out, count, lutTable) {
|
|
2057
2134
|
const buf = this.buf;
|
|
2058
2135
|
const lRansBase = this.lRansBase;
|
|
2059
2136
|
const ransPrecisionBits = this.ransPrecisionBits;
|
|
2060
2137
|
const ransPrecisionMask = this.ransPrecisionMask;
|
|
2061
|
-
const lutTable = this.lutTable;
|
|
2062
2138
|
const probTable = this.probTable;
|
|
2063
2139
|
const cumProbTable = this.cumProbTable;
|
|
2064
2140
|
let state = this.state;
|
|
@@ -2119,16 +2195,12 @@ function computeRAnsPrecisionFromUniqueSymbolsBitLength(symbolsBitLength) {
|
|
|
2119
2195
|
return unclamped;
|
|
2120
2196
|
}
|
|
2121
2197
|
var RAnsSymbolDecoder = class {
|
|
2122
|
-
uniqueSymbolsBitLength_;
|
|
2123
2198
|
ransPrecisionBits_;
|
|
2124
|
-
ransPrecision_;
|
|
2125
2199
|
probabilityTable_;
|
|
2126
2200
|
numSymbols_;
|
|
2127
2201
|
ans_;
|
|
2128
2202
|
constructor(uniqueSymbolsBitLength) {
|
|
2129
|
-
this.uniqueSymbolsBitLength_ = uniqueSymbolsBitLength;
|
|
2130
2203
|
this.ransPrecisionBits_ = computeRAnsPrecisionFromUniqueSymbolsBitLength(uniqueSymbolsBitLength);
|
|
2131
|
-
this.ransPrecision_ = 1 << this.ransPrecisionBits_;
|
|
2132
2204
|
this.probabilityTable_ = null;
|
|
2133
2205
|
this.numSymbols_ = 0;
|
|
2134
2206
|
this.ans_ = new RAnsDecoder(this.ransPrecisionBits_);
|
|
@@ -3540,8 +3612,7 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
3540
3612
|
}
|
|
3541
3613
|
const xUV0 = nUV0 * pnNorm2Squared + cnDotPn * pnUV0;
|
|
3542
3614
|
const xUV1 = nUV1 * pnNorm2Squared + cnDotPn * pnUV1;
|
|
3543
|
-
|
|
3544
|
-
if (pnAbsMax > 0 && Math.abs(cnDotPn) > INT64_MAX / pnAbsMax) {
|
|
3615
|
+
if (pnAbsMaxG > 0 && cnDotPnAbs > INT64_MAX / pnAbsMaxG) {
|
|
3545
3616
|
return false;
|
|
3546
3617
|
}
|
|
3547
3618
|
const xPos0 = next0 + Math.trunc(cnDotPn * pn0 / pnNorm2Squared);
|
|
@@ -3909,7 +3980,7 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
|
|
|
3909
3980
|
if (portableAttributeData.byteLength < 4 * numValues) {
|
|
3910
3981
|
return false;
|
|
3911
3982
|
}
|
|
3912
|
-
const bytes = buffer.
|
|
3983
|
+
const bytes = buffer.decodeBytesView(4 * numValues);
|
|
3913
3984
|
if (bytes === void 0) return false;
|
|
3914
3985
|
const srcView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
3915
3986
|
for (let i = 0; i < numValues; i++) {
|
|
@@ -3919,12 +3990,13 @@ var SequentialIntegerAttributeDecoder = class extends SequentialAttributeDecoder
|
|
|
3919
3990
|
if (buffer.remainingSize < numBytes * numValues) {
|
|
3920
3991
|
return false;
|
|
3921
3992
|
}
|
|
3993
|
+
const bytes = buffer.decodeBytesView(numBytes * numValues);
|
|
3994
|
+
if (bytes === void 0) return false;
|
|
3922
3995
|
for (let i = 0; i < numValues; i++) {
|
|
3923
|
-
const valueBytes = buffer.decodeBytes(numBytes);
|
|
3924
|
-
if (valueBytes === void 0) return false;
|
|
3925
3996
|
let val = 0;
|
|
3997
|
+
const valueOffset = i * numBytes;
|
|
3926
3998
|
for (let b = 0; b < numBytes; b++) {
|
|
3927
|
-
val |=
|
|
3999
|
+
val |= bytes[valueOffset + b] << b * 8;
|
|
3928
4000
|
}
|
|
3929
4001
|
portableAttributeData[i] = val;
|
|
3930
4002
|
}
|
|
@@ -4586,15 +4658,6 @@ var AttributeQuantizationTransform = class _AttributeQuantizationTransform exten
|
|
|
4586
4658
|
}
|
|
4587
4659
|
return true;
|
|
4588
4660
|
}
|
|
4589
|
-
get quantizationBits() {
|
|
4590
|
-
return this._quantizationBits;
|
|
4591
|
-
}
|
|
4592
|
-
get range() {
|
|
4593
|
-
return this._range;
|
|
4594
|
-
}
|
|
4595
|
-
minValue(axis) {
|
|
4596
|
-
return this._minValues[axis];
|
|
4597
|
-
}
|
|
4598
4661
|
static _isQuantizationValid(quantizationBits) {
|
|
4599
4662
|
return quantizationBits >= 1 && quantizationBits <= 30;
|
|
4600
4663
|
}
|
|
@@ -4673,7 +4736,7 @@ var SequentialAttributeDecodersController = class extends AttributesDecoder {
|
|
|
4673
4736
|
if (!this._sequencer) {
|
|
4674
4737
|
return false;
|
|
4675
4738
|
}
|
|
4676
|
-
if (!this._sequencer.generateSequence(
|
|
4739
|
+
if (!this._sequencer.generateSequence()) {
|
|
4677
4740
|
return false;
|
|
4678
4741
|
}
|
|
4679
4742
|
this._pointIds = this._sequencer.getOutputPointIds();
|
|
@@ -4797,19 +4860,29 @@ var DepthFirstTraverser = class {
|
|
|
4797
4860
|
init(cornerTable, observer) {
|
|
4798
4861
|
this._cornerTable = cornerTable;
|
|
4799
4862
|
this._observer = observer;
|
|
4800
|
-
this._isFaceVisited =
|
|
4801
|
-
this._isVertexVisited =
|
|
4863
|
+
this._isFaceVisited = null;
|
|
4864
|
+
this._isVertexVisited = null;
|
|
4802
4865
|
this._numVisitedFaces = 0;
|
|
4803
4866
|
this._cornerToVertex = cornerTable.cornerToVertexArray();
|
|
4804
4867
|
this._oppositeCorners = cornerTable.oppositeCornerArray();
|
|
4805
4868
|
this._vertexLeftmost = cornerTable.vertexLeftmostCornerArray();
|
|
4806
4869
|
this._numCorners = cornerTable.numCorners();
|
|
4807
|
-
this._cornerTraversalStack = new Int32Array(this._numCorners);
|
|
4808
4870
|
}
|
|
4809
4871
|
cornerTable() {
|
|
4810
4872
|
return this._cornerTable;
|
|
4811
4873
|
}
|
|
4874
|
+
// Scratch buffers are set up here rather than in init() so a shared-traversal
|
|
4875
|
+
// -cache hit — where generateSequence returns before any traversal — skips
|
|
4876
|
+
// this entirely, including the visited-flag zero-fill (worth ~0.5% on the
|
|
4877
|
+
// 488-primitive manablade-static bundle, which shares attribute corner tables across
|
|
4878
|
+
// primitives). Uint8Array (0/1) instead of Array(bool): these flags are read
|
|
4879
|
+
// and written on every corner of the hottest decode loop (traverseFromCorner).
|
|
4880
|
+
// Decode-scoped scratch: released in bulk at the end of the decode.
|
|
4812
4881
|
onTraversalStart() {
|
|
4882
|
+
const cornerTable = this._cornerTable;
|
|
4883
|
+
this._isFaceVisited = scratchUint8Zeroed(cornerTable.numFaces());
|
|
4884
|
+
this._isVertexVisited = scratchUint8Zeroed(cornerTable.numVertices());
|
|
4885
|
+
this._cornerTraversalStack = scratchInt32(this._numCorners);
|
|
4813
4886
|
}
|
|
4814
4887
|
onTraversalEnd() {
|
|
4815
4888
|
}
|
|
@@ -4825,6 +4898,14 @@ var DepthFirstTraverser = class {
|
|
|
4825
4898
|
const vertexLeftmost = this._vertexLeftmost;
|
|
4826
4899
|
const stack = this._cornerTraversalStack;
|
|
4827
4900
|
let numVisitedFaces = this._numVisitedFaces;
|
|
4901
|
+
const sequencer = observer._sequencer;
|
|
4902
|
+
const encodingData = observer._encodingData;
|
|
4903
|
+
const obsFaces = observer._faces;
|
|
4904
|
+
const encodedToCornerMap = observer._encodedToCornerMap;
|
|
4905
|
+
const vertexToEncodedMap = observer._vertexToEncodedMap;
|
|
4906
|
+
const outPointIds = sequencer._outPointIds;
|
|
4907
|
+
let numOutPoints = sequencer._numOutPoints;
|
|
4908
|
+
let numValues = encodingData.numValues;
|
|
4828
4909
|
let stackSize = 0;
|
|
4829
4910
|
stack[stackSize++] = cornerId;
|
|
4830
4911
|
const nextCorner = cornerId % 3 === 2 ? cornerId - 2 : cornerId + 1;
|
|
@@ -4836,11 +4917,15 @@ var DepthFirstTraverser = class {
|
|
|
4836
4917
|
}
|
|
4837
4918
|
if (!isVertexVisited[nextVert]) {
|
|
4838
4919
|
isVertexVisited[nextVert] = 1;
|
|
4839
|
-
|
|
4920
|
+
outPointIds[numOutPoints++] = obsFaces[nextCorner];
|
|
4921
|
+
encodedToCornerMap[numValues] = nextCorner;
|
|
4922
|
+
vertexToEncodedMap[nextVert] = numValues++;
|
|
4840
4923
|
}
|
|
4841
4924
|
if (!isVertexVisited[prevVert]) {
|
|
4842
4925
|
isVertexVisited[prevVert] = 1;
|
|
4843
|
-
|
|
4926
|
+
outPointIds[numOutPoints++] = obsFaces[prevCorner];
|
|
4927
|
+
encodedToCornerMap[numValues] = prevCorner;
|
|
4928
|
+
vertexToEncodedMap[prevVert] = numValues++;
|
|
4844
4929
|
}
|
|
4845
4930
|
while (stackSize > 0) {
|
|
4846
4931
|
cornerId = stack[stackSize - 1];
|
|
@@ -4854,6 +4939,8 @@ var DepthFirstTraverser = class {
|
|
|
4854
4939
|
numVisitedFaces++;
|
|
4855
4940
|
const vertId = cornerToVertex[cornerId];
|
|
4856
4941
|
if (vertId === kInvalidVertexIndex2) {
|
|
4942
|
+
sequencer._numOutPoints = numOutPoints;
|
|
4943
|
+
encodingData.numValues = numValues;
|
|
4857
4944
|
return false;
|
|
4858
4945
|
}
|
|
4859
4946
|
if (!isVertexVisited[vertId]) {
|
|
@@ -4864,7 +4951,9 @@ var DepthFirstTraverser = class {
|
|
|
4864
4951
|
onBoundary = oppositeCorners[nextLc] < 0;
|
|
4865
4952
|
}
|
|
4866
4953
|
isVertexVisited[vertId] = 1;
|
|
4867
|
-
|
|
4954
|
+
outPointIds[numOutPoints++] = obsFaces[cornerId];
|
|
4955
|
+
encodedToCornerMap[numValues] = cornerId;
|
|
4956
|
+
vertexToEncodedMap[vertId] = numValues++;
|
|
4868
4957
|
if (!onBoundary) {
|
|
4869
4958
|
const nextCornerId2 = cornerId % 3 === 2 ? cornerId - 2 : cornerId + 1;
|
|
4870
4959
|
cornerId = oppositeCorners[nextCornerId2];
|
|
@@ -4901,6 +4990,8 @@ var DepthFirstTraverser = class {
|
|
|
4901
4990
|
}
|
|
4902
4991
|
}
|
|
4903
4992
|
this._numVisitedFaces = numVisitedFaces;
|
|
4993
|
+
sequencer._numOutPoints = numOutPoints;
|
|
4994
|
+
encodingData.numValues = numValues;
|
|
4904
4995
|
return true;
|
|
4905
4996
|
}
|
|
4906
4997
|
};
|
|
@@ -5113,7 +5204,7 @@ var MeshTraversalSequencer = class {
|
|
|
5113
5204
|
setTraverser(traverser) {
|
|
5114
5205
|
this._traverser = traverser;
|
|
5115
5206
|
}
|
|
5116
|
-
generateSequence(
|
|
5207
|
+
generateSequence() {
|
|
5117
5208
|
const cornerTable = this._traverser.cornerTable();
|
|
5118
5209
|
const methodId = this._traverser._traversalMethodId;
|
|
5119
5210
|
const cacheKey = cornerTable.cornerToVertexArray();
|
|
@@ -5451,7 +5542,7 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5451
5542
|
return true;
|
|
5452
5543
|
}
|
|
5453
5544
|
_decodeConnectivity(numSymbols) {
|
|
5454
|
-
const activeCornerStack =
|
|
5545
|
+
const activeCornerStack = scratchInt32(numSymbols + this._topologySplitData.length + 16);
|
|
5455
5546
|
let activeCornerStackSize = 0;
|
|
5456
5547
|
const topologySplitActiveCorners = /* @__PURE__ */ new Map();
|
|
5457
5548
|
const invalidVertices = [];
|
|
@@ -6052,7 +6143,8 @@ var CornerTable = class {
|
|
|
6052
6143
|
const newVertex = this._numVertices;
|
|
6053
6144
|
this._numVertices++;
|
|
6054
6145
|
if (newVertex >= this._vertexCorners.length) {
|
|
6055
|
-
const
|
|
6146
|
+
const newCapacity = Math.max(newVertex + 1, this._vertexCorners.length * 2, 64);
|
|
6147
|
+
const newArr = new Int32Array(newCapacity);
|
|
6056
6148
|
newArr.fill(-1);
|
|
6057
6149
|
newArr.set(this._vertexCorners);
|
|
6058
6150
|
this._vertexCorners = newArr;
|
|
@@ -6315,7 +6407,7 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
|
|
|
6315
6407
|
this._activeContext = -1;
|
|
6316
6408
|
this._minValence = 2;
|
|
6317
6409
|
this._maxValence = 7;
|
|
6318
|
-
this._vertexValences =
|
|
6410
|
+
this._vertexValences = new Int32Array(0);
|
|
6319
6411
|
this._contextSymbols = [];
|
|
6320
6412
|
this._contextCounters = [];
|
|
6321
6413
|
}
|
|
@@ -6339,7 +6431,7 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
|
|
|
6339
6431
|
if (this._numVertices < 0) {
|
|
6340
6432
|
return false;
|
|
6341
6433
|
}
|
|
6342
|
-
this._vertexValences = new
|
|
6434
|
+
this._vertexValences = new Int32Array(this._numVertices);
|
|
6343
6435
|
const numUniqueValences = this._maxValence - this._minValence + 1;
|
|
6344
6436
|
this._contextSymbols = new Array(numUniqueValences);
|
|
6345
6437
|
this._contextCounters = new Array(numUniqueValences);
|
|
@@ -6381,34 +6473,37 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
|
|
|
6381
6473
|
return this._lastSymbol;
|
|
6382
6474
|
}
|
|
6383
6475
|
newActiveCornerReached(corner) {
|
|
6384
|
-
const
|
|
6385
|
-
const
|
|
6386
|
-
const
|
|
6476
|
+
const cornerToVertex = this._cornerTable._cornerToVertex;
|
|
6477
|
+
const valences = this._vertexValences;
|
|
6478
|
+
const next = corner % 3 === 2 ? corner - 2 : corner + 1;
|
|
6479
|
+
const prev = corner % 3 === 0 ? corner + 2 : corner - 1;
|
|
6480
|
+
const vertNext = cornerToVertex[next];
|
|
6481
|
+
const vertPrev = cornerToVertex[prev];
|
|
6387
6482
|
switch (this._lastSymbol) {
|
|
6388
6483
|
case TOPOLOGY_C:
|
|
6389
6484
|
case TOPOLOGY_S:
|
|
6390
|
-
|
|
6391
|
-
|
|
6485
|
+
valences[vertNext] += 1;
|
|
6486
|
+
valences[vertPrev] += 1;
|
|
6392
6487
|
break;
|
|
6393
6488
|
case TOPOLOGY_R:
|
|
6394
|
-
|
|
6395
|
-
|
|
6396
|
-
|
|
6489
|
+
valences[cornerToVertex[corner]] += 1;
|
|
6490
|
+
valences[vertNext] += 1;
|
|
6491
|
+
valences[vertPrev] += 2;
|
|
6397
6492
|
break;
|
|
6398
6493
|
case TOPOLOGY_L:
|
|
6399
|
-
|
|
6400
|
-
|
|
6401
|
-
|
|
6494
|
+
valences[cornerToVertex[corner]] += 1;
|
|
6495
|
+
valences[vertNext] += 2;
|
|
6496
|
+
valences[vertPrev] += 1;
|
|
6402
6497
|
break;
|
|
6403
6498
|
case TOPOLOGY_E:
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
|
|
6499
|
+
valences[cornerToVertex[corner]] += 2;
|
|
6500
|
+
valences[vertNext] += 2;
|
|
6501
|
+
valences[vertPrev] += 2;
|
|
6407
6502
|
break;
|
|
6408
6503
|
default:
|
|
6409
6504
|
break;
|
|
6410
6505
|
}
|
|
6411
|
-
const activeValence =
|
|
6506
|
+
const activeValence = valences[vertNext];
|
|
6412
6507
|
let clampedValence;
|
|
6413
6508
|
if (activeValence < this._minValence) {
|
|
6414
6509
|
clampedValence = this._minValence;
|
|
@@ -6527,45 +6622,30 @@ var MeshSequentialDecoder = class extends MeshDecoder {
|
|
|
6527
6622
|
return false;
|
|
6528
6623
|
}
|
|
6529
6624
|
} else {
|
|
6625
|
+
const mesh = this.mesh();
|
|
6626
|
+
mesh.setNumFaces(numFaces);
|
|
6627
|
+
const faces = mesh.faces_;
|
|
6628
|
+
const numIndices = numFaces * 3;
|
|
6629
|
+
const buffer = this.buffer();
|
|
6530
6630
|
if (numPoints < 256) {
|
|
6531
|
-
|
|
6532
|
-
|
|
6533
|
-
|
|
6534
|
-
const val = this.buffer().decodeUint8();
|
|
6535
|
-
if (val === void 0) return false;
|
|
6536
|
-
face[j] = val;
|
|
6537
|
-
}
|
|
6538
|
-
this.mesh().addFace(face);
|
|
6539
|
-
}
|
|
6631
|
+
const src = buffer.decodeBytesView(numIndices);
|
|
6632
|
+
if (src === void 0) return false;
|
|
6633
|
+
for (let i = 0; i < numIndices; ++i) faces[i] = src[i];
|
|
6540
6634
|
} else if (numPoints < 1 << 16) {
|
|
6541
|
-
|
|
6542
|
-
|
|
6543
|
-
|
|
6544
|
-
const val = this.buffer().decodeUint16();
|
|
6545
|
-
if (val === void 0) return false;
|
|
6546
|
-
face[j] = val;
|
|
6547
|
-
}
|
|
6548
|
-
this.mesh().addFace(face);
|
|
6549
|
-
}
|
|
6635
|
+
const src = buffer.decodeBytesView(numIndices * 2);
|
|
6636
|
+
if (src === void 0) return false;
|
|
6637
|
+
for (let i = 0; i < numIndices; ++i) faces[i] = src[i * 2] | src[i * 2 + 1] << 8;
|
|
6550
6638
|
} else if (numPoints < 1 << 21) {
|
|
6551
|
-
for (let i = 0; i <
|
|
6552
|
-
const
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
if (val === void 0) return false;
|
|
6556
|
-
face[j] = val;
|
|
6557
|
-
}
|
|
6558
|
-
this.mesh().addFace(face);
|
|
6639
|
+
for (let i = 0; i < numIndices; ++i) {
|
|
6640
|
+
const val = decodeVarint(buffer);
|
|
6641
|
+
if (val === void 0) return false;
|
|
6642
|
+
faces[i] = val;
|
|
6559
6643
|
}
|
|
6560
6644
|
} else {
|
|
6561
|
-
|
|
6562
|
-
|
|
6563
|
-
|
|
6564
|
-
|
|
6565
|
-
if (val === void 0) return false;
|
|
6566
|
-
face[j] = val;
|
|
6567
|
-
}
|
|
6568
|
-
this.mesh().addFace(face);
|
|
6645
|
+
const src = buffer.decodeBytesView(numIndices * 4);
|
|
6646
|
+
if (src === void 0) return false;
|
|
6647
|
+
for (let i = 0; i < numIndices; ++i) {
|
|
6648
|
+
faces[i] = src[i * 4] | src[i * 4 + 1] << 8 | src[i * 4 + 2] << 16 | src[i * 4 + 3] << 24;
|
|
6569
6649
|
}
|
|
6570
6650
|
}
|
|
6571
6651
|
}
|
|
@@ -6579,32 +6659,31 @@ var MeshSequentialDecoder = class extends MeshDecoder {
|
|
|
6579
6659
|
);
|
|
6580
6660
|
}
|
|
6581
6661
|
_decodeAndDecompressIndices(numFaces) {
|
|
6582
|
-
const
|
|
6583
|
-
|
|
6662
|
+
const numIndices = numFaces * 3;
|
|
6663
|
+
const indicesBuffer = new Uint32Array(numIndices);
|
|
6664
|
+
if (!decodeSymbols(numIndices, 1, this.buffer(), indicesBuffer)) {
|
|
6584
6665
|
return false;
|
|
6585
6666
|
}
|
|
6667
|
+
const mesh = this.mesh();
|
|
6668
|
+
mesh.setNumFaces(numFaces);
|
|
6669
|
+
const faces = mesh.faces_;
|
|
6586
6670
|
let lastIndexValue = 0;
|
|
6587
|
-
let
|
|
6588
|
-
|
|
6589
|
-
|
|
6590
|
-
|
|
6591
|
-
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
|
|
6595
|
-
|
|
6596
|
-
|
|
6597
|
-
|
|
6598
|
-
} else {
|
|
6599
|
-
if (indexDiff > 2147483647 - lastIndexValue) {
|
|
6600
|
-
return false;
|
|
6601
|
-
}
|
|
6671
|
+
for (let i = 0; i < numIndices; ++i) {
|
|
6672
|
+
const encodedVal = indicesBuffer[i];
|
|
6673
|
+
let indexDiff = encodedVal >>> 1;
|
|
6674
|
+
if (encodedVal & 1) {
|
|
6675
|
+
if (indexDiff > lastIndexValue) {
|
|
6676
|
+
return false;
|
|
6677
|
+
}
|
|
6678
|
+
indexDiff = -indexDiff;
|
|
6679
|
+
} else {
|
|
6680
|
+
if (indexDiff > 2147483647 - lastIndexValue) {
|
|
6681
|
+
return false;
|
|
6602
6682
|
}
|
|
6603
|
-
const indexValue = indexDiff + lastIndexValue | 0;
|
|
6604
|
-
face[j] = indexValue;
|
|
6605
|
-
lastIndexValue = indexValue;
|
|
6606
6683
|
}
|
|
6607
|
-
|
|
6684
|
+
const indexValue = indexDiff + lastIndexValue | 0;
|
|
6685
|
+
faces[i] = indexValue;
|
|
6686
|
+
lastIndexValue = indexValue;
|
|
6608
6687
|
}
|
|
6609
6688
|
return true;
|
|
6610
6689
|
}
|
|
@@ -6662,9 +6741,15 @@ var Decoder = class {
|
|
|
6662
6741
|
if (result.header.encoderType !== EncodedGeometryType.TRIANGULAR_MESH) {
|
|
6663
6742
|
return { ok: false, message: "Input is not a mesh." };
|
|
6664
6743
|
}
|
|
6665
|
-
|
|
6666
|
-
|
|
6667
|
-
|
|
6744
|
+
try {
|
|
6745
|
+
const decoder = createMeshDecoder(result.header.encoderMethod);
|
|
6746
|
+
const status = decoder.decodeMesh(this.options_, inBuffer, outGeometry);
|
|
6747
|
+
return { ok: status.ok(), message: status.errorMsg };
|
|
6748
|
+
} catch (error) {
|
|
6749
|
+
return { ok: false, message: error instanceof Error ? error.message : String(error) };
|
|
6750
|
+
} finally {
|
|
6751
|
+
releaseScratch();
|
|
6752
|
+
}
|
|
6668
6753
|
}
|
|
6669
6754
|
options() {
|
|
6670
6755
|
return this.options_;
|
|
@@ -6675,18 +6760,17 @@ var Decoder = class {
|
|
|
6675
6760
|
var decodeDracoMesh = (data) => {
|
|
6676
6761
|
const buffer = new DecoderBuffer();
|
|
6677
6762
|
buffer.init(data, data.length);
|
|
6678
|
-
if (Decoder.getEncodedGeometryType(buffer) !== EncodedGeometryType.TRIANGULAR_MESH) {
|
|
6679
|
-
throw new Error("minidraco: Input is not a Draco triangular mesh.");
|
|
6680
|
-
}
|
|
6681
6763
|
const decoder = new Decoder();
|
|
6682
6764
|
const result = decoder.decodeMeshFromBuffer(buffer);
|
|
6683
6765
|
if (!result.ok || result.mesh === null) {
|
|
6684
|
-
|
|
6766
|
+
const message = result.message === "Input is not a mesh." ? "Input is not a Draco triangular mesh." : result.message;
|
|
6767
|
+
throw new Error(`minidraco: ${message}`);
|
|
6685
6768
|
}
|
|
6686
6769
|
return result.mesh;
|
|
6687
6770
|
};
|
|
6688
6771
|
|
|
6689
6772
|
// src/three/index.ts
|
|
6773
|
+
var isLoadingManager = (value) => typeof value?.itemStart === "function";
|
|
6690
6774
|
var _taskCache = /* @__PURE__ */ new WeakMap();
|
|
6691
6775
|
var _attributeTypeMap = {
|
|
6692
6776
|
POSITION: Type.POSITION,
|
|
@@ -6704,13 +6788,24 @@ var _typedArrayMap = {
|
|
|
6704
6788
|
Uint16Array,
|
|
6705
6789
|
Uint32Array
|
|
6706
6790
|
};
|
|
6707
|
-
var
|
|
6791
|
+
var MinidracoLoader = class extends Loader {
|
|
6708
6792
|
defaultAttributeIDs;
|
|
6709
6793
|
defaultAttributeTypes;
|
|
6710
6794
|
workerLimit;
|
|
6795
|
+
// Opt-in (0 = disabled): buffers at or below this size decode on the main
|
|
6796
|
+
// thread instead of paying the ~0.5 ms worker message roundtrip.
|
|
6797
|
+
// Worth enabling (e.g. 4096) when the main thread is otherwise idle during
|
|
6798
|
+
// loads — in a full GLTFLoader parse the main thread is already busy
|
|
6799
|
+
// building geometries, and measurements show the pool wins there even for
|
|
6800
|
+
// tiny primitives.
|
|
6801
|
+
mainThreadByteThreshold;
|
|
6711
6802
|
_workers;
|
|
6712
6803
|
_taskId;
|
|
6713
6804
|
_tasks;
|
|
6805
|
+
// Tasks queued during the current microtask; flushed as one batched message
|
|
6806
|
+
// per worker (a 488-primitive scene costs 4 postMessages, not 488).
|
|
6807
|
+
_batch;
|
|
6808
|
+
_batchScheduled;
|
|
6714
6809
|
// Set when spawning a worker fails (bundler without module-worker support,
|
|
6715
6810
|
// file:// pages, …): decoding transparently falls back to the main thread.
|
|
6716
6811
|
_workersBroken;
|
|
@@ -6718,8 +6813,10 @@ var MiniDRACOLoader = class extends Loader {
|
|
|
6718
6813
|
// Same-origin blob bootstrap used when the worker asset lives on a CDN
|
|
6719
6814
|
// origin (created lazily, revoked on dispose).
|
|
6720
6815
|
_workerBlobUrl;
|
|
6721
|
-
|
|
6722
|
-
|
|
6816
|
+
// Accepts either a LoadingManager (three-compatible form) or an options bag.
|
|
6817
|
+
constructor(managerOrOptions) {
|
|
6818
|
+
const options = isLoadingManager(managerOrOptions) ? { manager: managerOrOptions } : managerOrOptions ?? {};
|
|
6819
|
+
super(options.manager);
|
|
6723
6820
|
this.defaultAttributeIDs = {
|
|
6724
6821
|
position: "POSITION",
|
|
6725
6822
|
normal: "NORMAL",
|
|
@@ -6732,10 +6829,13 @@ var MiniDRACOLoader = class extends Loader {
|
|
|
6732
6829
|
color: "Float32Array",
|
|
6733
6830
|
uv: "Float32Array"
|
|
6734
6831
|
};
|
|
6735
|
-
this.workerLimit = 4;
|
|
6832
|
+
this.workerLimit = options.workers === false ? 0 : options.workerLimit ?? 4;
|
|
6833
|
+
this.mainThreadByteThreshold = options.mainThreadByteThreshold ?? 0;
|
|
6736
6834
|
this._workers = [];
|
|
6737
6835
|
this._taskId = 0;
|
|
6738
6836
|
this._tasks = /* @__PURE__ */ new Map();
|
|
6837
|
+
this._batch = [];
|
|
6838
|
+
this._batchScheduled = false;
|
|
6739
6839
|
this._workersBroken = false;
|
|
6740
6840
|
this._workerUrl = null;
|
|
6741
6841
|
this._workerBlobUrl = null;
|
|
@@ -6748,8 +6848,12 @@ var MiniDRACOLoader = class extends Loader {
|
|
|
6748
6848
|
this._workerUrl = url;
|
|
6749
6849
|
return this;
|
|
6750
6850
|
}
|
|
6751
|
-
//
|
|
6752
|
-
// external decoder files to configure.
|
|
6851
|
+
// No-ops kept for API compatibility with THREE.DRACOLoader — minidraco has
|
|
6852
|
+
// no external decoder files to configure. The params are `unknown` (not
|
|
6853
|
+
// `string`/`object`) so the signatures stay assignable to THREE.DRACOLoader
|
|
6854
|
+
// across three versions, whose setDecoderPath has grown to accept a
|
|
6855
|
+
// `string | DecoderPaths` — letting `new MinidracoLoader()` be passed to
|
|
6856
|
+
// GLTFLoader.setDRACOLoader() with no cast.
|
|
6753
6857
|
setDecoderPath(_path) {
|
|
6754
6858
|
return this;
|
|
6755
6859
|
}
|
|
@@ -6760,13 +6864,30 @@ var MiniDRACOLoader = class extends Loader {
|
|
|
6760
6864
|
this.workerLimit = limit;
|
|
6761
6865
|
return this;
|
|
6762
6866
|
}
|
|
6867
|
+
// Toggle the worker pool on/off. false decodes synchronously on the main
|
|
6868
|
+
// thread; true enables the pool, keeping the current size or falling back to
|
|
6869
|
+
// the default 4 if it was disabled. For a specific pool size use
|
|
6870
|
+
// setWorkerLimit(n).
|
|
6871
|
+
setWorkers(enabled) {
|
|
6872
|
+
this.workerLimit = enabled ? this.workerLimit || 4 : 0;
|
|
6873
|
+
return this;
|
|
6874
|
+
}
|
|
6763
6875
|
preload() {
|
|
6764
|
-
if (this._workersAvailable())
|
|
6876
|
+
if (this._workersAvailable()) {
|
|
6877
|
+
while (this._workers.length < this.workerLimit && this._getWorker() !== null) {
|
|
6878
|
+
}
|
|
6879
|
+
}
|
|
6765
6880
|
return this;
|
|
6766
6881
|
}
|
|
6767
6882
|
dispose() {
|
|
6768
6883
|
for (const entry of this._workers) entry.worker.terminate();
|
|
6769
6884
|
this._workers = [];
|
|
6885
|
+
const disposedError = new Error("MinidracoLoader: disposed while decoding");
|
|
6886
|
+
disposedError.isDecodeError = true;
|
|
6887
|
+
for (const task of this._batch) task.reject(disposedError);
|
|
6888
|
+
this._batch = [];
|
|
6889
|
+
this._batchScheduled = false;
|
|
6890
|
+
for (const [, task] of this._tasks) task.reject(disposedError);
|
|
6770
6891
|
this._tasks.clear();
|
|
6771
6892
|
if (this._workerBlobUrl !== null) {
|
|
6772
6893
|
URL.revokeObjectURL(this._workerBlobUrl);
|
|
@@ -6809,10 +6930,6 @@ var MiniDRACOLoader = class extends Loader {
|
|
|
6809
6930
|
const cachedTask = _taskCache.get(buffer);
|
|
6810
6931
|
if (cachedTask.key === taskKey) {
|
|
6811
6932
|
return cachedTask.promise;
|
|
6812
|
-
} else if (buffer.byteLength === 0) {
|
|
6813
|
-
throw new Error(
|
|
6814
|
-
"MiniDRACOLoader: Unable to re-decode a buffer with different settings. Buffer has already been transferred."
|
|
6815
|
-
);
|
|
6816
6933
|
}
|
|
6817
6934
|
}
|
|
6818
6935
|
const geometryPending = this._runTask(buffer, taskConfig);
|
|
@@ -6821,12 +6938,16 @@ var MiniDRACOLoader = class extends Loader {
|
|
|
6821
6938
|
}
|
|
6822
6939
|
async _runTask(buffer, taskConfig) {
|
|
6823
6940
|
if (this._workersAvailable()) {
|
|
6824
|
-
|
|
6825
|
-
|
|
6826
|
-
|
|
6827
|
-
|
|
6828
|
-
|
|
6829
|
-
|
|
6941
|
+
if (buffer.byteLength > this.mainThreadByteThreshold) {
|
|
6942
|
+
try {
|
|
6943
|
+
const raw = await this._decodeInWorker(buffer, taskConfig);
|
|
6944
|
+
return this._buildGeometryFromRaw(raw, taskConfig);
|
|
6945
|
+
} catch (error) {
|
|
6946
|
+
if (error?.isDecodeError) throw error;
|
|
6947
|
+
this._workersBroken = true;
|
|
6948
|
+
}
|
|
6949
|
+
} else {
|
|
6950
|
+
await Promise.resolve();
|
|
6830
6951
|
}
|
|
6831
6952
|
}
|
|
6832
6953
|
return this._decodeBuffer(buffer, taskConfig);
|
|
@@ -6855,17 +6976,18 @@ var MiniDRACOLoader = class extends Loader {
|
|
|
6855
6976
|
}
|
|
6856
6977
|
const entry = { worker, pending: 0 };
|
|
6857
6978
|
worker.onmessage = (event) => {
|
|
6858
|
-
const { id, ok, indices, attributes, error }
|
|
6859
|
-
|
|
6860
|
-
|
|
6861
|
-
|
|
6862
|
-
|
|
6863
|
-
|
|
6864
|
-
|
|
6865
|
-
|
|
6866
|
-
|
|
6867
|
-
|
|
6868
|
-
|
|
6979
|
+
for (const { id, ok, indices, attributes, error } of event.data.results) {
|
|
6980
|
+
const task = this._tasks.get(id);
|
|
6981
|
+
if (!task) continue;
|
|
6982
|
+
this._tasks.delete(id);
|
|
6983
|
+
task.entry.pending--;
|
|
6984
|
+
if (ok) {
|
|
6985
|
+
task.resolve({ indices, attributes });
|
|
6986
|
+
} else {
|
|
6987
|
+
const decodeError = new Error(error);
|
|
6988
|
+
decodeError.isDecodeError = true;
|
|
6989
|
+
task.reject(decodeError);
|
|
6990
|
+
}
|
|
6869
6991
|
}
|
|
6870
6992
|
};
|
|
6871
6993
|
worker.onerror = (event) => {
|
|
@@ -6873,7 +6995,7 @@ var MiniDRACOLoader = class extends Loader {
|
|
|
6873
6995
|
for (const [id, task] of this._tasks) {
|
|
6874
6996
|
if (task.entry.worker === worker) {
|
|
6875
6997
|
this._tasks.delete(id);
|
|
6876
|
-
task.reject(new Error(`
|
|
6998
|
+
task.reject(new Error(`MinidracoLoader worker failed: ${event.message ?? "unknown error"}`));
|
|
6877
6999
|
}
|
|
6878
7000
|
}
|
|
6879
7001
|
};
|
|
@@ -6885,22 +7007,56 @@ var MiniDRACOLoader = class extends Loader {
|
|
|
6885
7007
|
return best;
|
|
6886
7008
|
}
|
|
6887
7009
|
_decodeInWorker(buffer, taskConfig) {
|
|
6888
|
-
const entry = this._getWorker();
|
|
6889
|
-
if (entry === null) {
|
|
6890
|
-
return Promise.reject(new Error("MiniDRACOLoader: worker unavailable"));
|
|
6891
|
-
}
|
|
6892
7010
|
const id = this._taskId++;
|
|
6893
7011
|
return new Promise((resolve, reject) => {
|
|
6894
|
-
this.
|
|
6895
|
-
|
|
7012
|
+
this._batch.push({ id, buffer, taskConfig, resolve, reject });
|
|
7013
|
+
if (!this._batchScheduled) {
|
|
7014
|
+
this._batchScheduled = true;
|
|
7015
|
+
queueMicrotask(() => this._flushBatch());
|
|
7016
|
+
}
|
|
7017
|
+
});
|
|
7018
|
+
}
|
|
7019
|
+
_flushBatch() {
|
|
7020
|
+
this._batchScheduled = false;
|
|
7021
|
+
const batch = this._batch;
|
|
7022
|
+
if (batch.length === 0) return;
|
|
7023
|
+
this._batch = [];
|
|
7024
|
+
while (this._workers.length < Math.min(this.workerLimit, batch.length) && this._getWorker() !== null) {
|
|
7025
|
+
}
|
|
7026
|
+
if (this._workersBroken || this._workers.length === 0) {
|
|
7027
|
+
const error = new Error("MinidracoLoader: worker unavailable");
|
|
7028
|
+
for (const task of batch) task.reject(error);
|
|
7029
|
+
return;
|
|
7030
|
+
}
|
|
7031
|
+
batch.sort((a, b) => b.buffer.byteLength - a.buffer.byteLength);
|
|
7032
|
+
let totalBytes = 0;
|
|
7033
|
+
for (const task of batch) totalBytes += task.buffer.byteLength;
|
|
7034
|
+
const averageBytes = totalBytes / batch.length;
|
|
7035
|
+
const buckets = this._workers.map((entry) => ({
|
|
7036
|
+
entry,
|
|
7037
|
+
tasks: [],
|
|
7038
|
+
bytes: entry.pending * averageBytes
|
|
7039
|
+
}));
|
|
7040
|
+
for (const task of batch) {
|
|
7041
|
+
let best = buckets[0];
|
|
7042
|
+
for (const bucket of buckets) if (bucket.bytes < best.bytes) best = bucket;
|
|
7043
|
+
best.tasks.push(task);
|
|
7044
|
+
best.bytes += task.buffer.byteLength;
|
|
7045
|
+
}
|
|
7046
|
+
for (const { entry, tasks } of buckets) {
|
|
7047
|
+
if (tasks.length === 0) continue;
|
|
7048
|
+
entry.pending += tasks.length;
|
|
7049
|
+
for (const task of tasks) this._tasks.set(task.id, { resolve: task.resolve, reject: task.reject, entry });
|
|
6896
7050
|
entry.worker.postMessage({
|
|
6897
|
-
|
|
6898
|
-
|
|
6899
|
-
|
|
6900
|
-
|
|
6901
|
-
|
|
7051
|
+
tasks: tasks.map((task) => ({
|
|
7052
|
+
id: task.id,
|
|
7053
|
+
buffer: task.buffer,
|
|
7054
|
+
attributeIDs: task.taskConfig.attributeIDs,
|
|
7055
|
+
attributeTypes: task.taskConfig.attributeTypes,
|
|
7056
|
+
useUniqueIDs: task.taskConfig.useUniqueIDs
|
|
7057
|
+
}))
|
|
6902
7058
|
});
|
|
6903
|
-
}
|
|
7059
|
+
}
|
|
6904
7060
|
}
|
|
6905
7061
|
_buildGeometryFromRaw(raw, taskConfig) {
|
|
6906
7062
|
const geometry = new BufferGeometry();
|
|
@@ -6964,6 +7120,6 @@ var MiniDRACOLoader = class extends Loader {
|
|
|
6964
7120
|
}
|
|
6965
7121
|
};
|
|
6966
7122
|
export {
|
|
6967
|
-
|
|
6968
|
-
|
|
7123
|
+
MinidracoLoader as DRACOLoader,
|
|
7124
|
+
MinidracoLoader
|
|
6969
7125
|
};
|