minidraco 0.1.0 → 0.2.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 +50 -20
- package/dist/index.d.ts +1 -2
- package/dist/index.js +234 -139
- package/dist/three.d.ts +26 -7
- package/dist/three.js +381 -176
- package/dist/worker.js +287 -169
- package/package.json +6 -1
package/dist/index.js
CHANGED
|
@@ -200,6 +200,14 @@ var DecoderBuffer = class {
|
|
|
200
200
|
this._pos += size;
|
|
201
201
|
return result;
|
|
202
202
|
}
|
|
203
|
+
// Zero-copy variant of decodeBytes: a view into the stream, only valid until
|
|
204
|
+
// the caller's next chance to mutate the buffer — copy out before keeping it.
|
|
205
|
+
decodeBytesView(size) {
|
|
206
|
+
if (this._pos + size > this._dataSize) return void 0;
|
|
207
|
+
const result = this._data.subarray(this._pos, this._pos + size);
|
|
208
|
+
this._pos += size;
|
|
209
|
+
return result;
|
|
210
|
+
}
|
|
203
211
|
startBitDecoding(decodeSize) {
|
|
204
212
|
let outSize = 0;
|
|
205
213
|
if (decodeSize) {
|
|
@@ -257,6 +265,48 @@ var DecoderBuffer = class {
|
|
|
257
265
|
}
|
|
258
266
|
};
|
|
259
267
|
|
|
268
|
+
// src/decoder/core/ScratchArena.ts
|
|
269
|
+
var freeInt32 = [];
|
|
270
|
+
var freeUint8 = [];
|
|
271
|
+
var borrowedInt32 = [];
|
|
272
|
+
var borrowedUint8 = [];
|
|
273
|
+
var acquire = (free, borrowed, size) => {
|
|
274
|
+
for (let i = free.length - 1; i >= 0; --i) {
|
|
275
|
+
const buffer = free[i];
|
|
276
|
+
if (buffer.length >= size) {
|
|
277
|
+
free[i] = free[free.length - 1];
|
|
278
|
+
free.pop();
|
|
279
|
+
borrowed.push(buffer);
|
|
280
|
+
return buffer;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return null;
|
|
284
|
+
};
|
|
285
|
+
var scratchInt32 = (size) => {
|
|
286
|
+
const pooled = acquire(freeInt32, borrowedInt32, size);
|
|
287
|
+
if (pooled !== null) return pooled.subarray(0, size);
|
|
288
|
+
const fresh = new Int32Array(size);
|
|
289
|
+
borrowedInt32.push(fresh);
|
|
290
|
+
return fresh;
|
|
291
|
+
};
|
|
292
|
+
var scratchUint8Zeroed = (size) => {
|
|
293
|
+
const pooled = acquire(freeUint8, borrowedUint8, size);
|
|
294
|
+
if (pooled !== null) {
|
|
295
|
+
const view = pooled.subarray(0, size);
|
|
296
|
+
view.fill(0);
|
|
297
|
+
return view;
|
|
298
|
+
}
|
|
299
|
+
const fresh = new Uint8Array(size);
|
|
300
|
+
borrowedUint8.push(fresh);
|
|
301
|
+
return fresh;
|
|
302
|
+
};
|
|
303
|
+
var releaseScratch = () => {
|
|
304
|
+
for (const buffer of borrowedInt32) freeInt32.push(buffer);
|
|
305
|
+
for (const buffer of borrowedUint8) freeUint8.push(buffer);
|
|
306
|
+
borrowedInt32.length = 0;
|
|
307
|
+
borrowedUint8.length = 0;
|
|
308
|
+
};
|
|
309
|
+
|
|
260
310
|
// src/decoder/point_cloud/PointCloud.ts
|
|
261
311
|
var NAMED_ATTRIBUTES_COUNT = 8;
|
|
262
312
|
var PointCloud = class {
|
|
@@ -356,25 +406,17 @@ var Mesh = class extends PointCloud {
|
|
|
356
406
|
this.numFaces_ = 0;
|
|
357
407
|
this.attribute_data_ = [];
|
|
358
408
|
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
const grown = new Int32Array(numFaces * 3);
|
|
364
|
-
grown.set(this.faces_);
|
|
365
|
-
this.faces_ = grown;
|
|
366
|
-
}
|
|
367
|
-
addFace(face) {
|
|
368
|
-
const f = this.numFaces_;
|
|
369
|
-
this._ensureFaceCapacity(f + 1);
|
|
370
|
-
const o = f * 3;
|
|
371
|
-
this.faces_[o] = face[0];
|
|
372
|
-
this.faces_[o + 1] = face[1];
|
|
373
|
-
this.faces_[o + 2] = face[2];
|
|
374
|
-
this.numFaces_ = f + 1;
|
|
375
|
-
}
|
|
409
|
+
// Sizes faces_ to hold numFaces faces. Called once per decode, before any
|
|
410
|
+
// face index is written (edgebreaker: _assignPointsToCorners; sequential:
|
|
411
|
+
// decodeConnectivity), so the buffer is allocated exactly here — the
|
|
412
|
+
// decoders fill faces_ directly rather than appending face-by-face.
|
|
376
413
|
setNumFaces(numFaces) {
|
|
377
|
-
|
|
414
|
+
const needed = numFaces * 3;
|
|
415
|
+
if (this.faces_.length < needed) {
|
|
416
|
+
const grown = new Int32Array(needed);
|
|
417
|
+
grown.set(this.faces_);
|
|
418
|
+
this.faces_ = grown;
|
|
419
|
+
}
|
|
378
420
|
this.numFaces_ = numFaces;
|
|
379
421
|
}
|
|
380
422
|
numFaces() {
|
|
@@ -1044,15 +1086,6 @@ var MeshAttributeCornerTable = class {
|
|
|
1044
1086
|
leftMostCorner(v) {
|
|
1045
1087
|
return this.vertex_to_left_most_corner_map_[v];
|
|
1046
1088
|
}
|
|
1047
|
-
face(corner) {
|
|
1048
|
-
return this.corner_table_.face(corner);
|
|
1049
|
-
}
|
|
1050
|
-
firstCorner(faceIndex) {
|
|
1051
|
-
return this.corner_table_.firstCorner(faceIndex);
|
|
1052
|
-
}
|
|
1053
|
-
allCorners(faceIndex) {
|
|
1054
|
-
return this.corner_table_.allCorners(faceIndex);
|
|
1055
|
-
}
|
|
1056
1089
|
// --- Flat-array accessors: let DepthFirstTraverser avoid per-corner dispatch. ---
|
|
1057
1090
|
cornerToVertexArray() {
|
|
1058
1091
|
return this.corner_to_vertex_map_;
|
|
@@ -1067,7 +1100,8 @@ var MeshAttributeCornerTable = class {
|
|
|
1067
1100
|
if (seamCorners.length === 0) {
|
|
1068
1101
|
this._effectiveOpposite = base;
|
|
1069
1102
|
} else {
|
|
1070
|
-
const eff =
|
|
1103
|
+
const eff = scratchInt32(nc);
|
|
1104
|
+
eff.set(base.length === nc ? base : base.subarray(0, nc));
|
|
1071
1105
|
for (let i = 0, l = seamCorners.length; i < l; ++i) {
|
|
1072
1106
|
eff[seamCorners[i]] = kInvalidCornerIndex;
|
|
1073
1107
|
}
|
|
@@ -1101,9 +1135,6 @@ var MeshAttributeCornerTable = class {
|
|
|
1101
1135
|
this._effectiveOpposite = other._effectiveOpposite;
|
|
1102
1136
|
this._seamCorners = other._seamCorners;
|
|
1103
1137
|
}
|
|
1104
|
-
isDegenerated(faceIndex) {
|
|
1105
|
-
return this.corner_table_.isDegenerated(faceIndex);
|
|
1106
|
-
}
|
|
1107
1138
|
};
|
|
1108
1139
|
|
|
1109
1140
|
// src/decoder/core/DracoTypes.ts
|
|
@@ -1851,15 +1882,12 @@ var SequentialAttributeDecoder = class {
|
|
|
1851
1882
|
decodeValues(pointIds, buffer) {
|
|
1852
1883
|
const numValues = pointIds.length;
|
|
1853
1884
|
const entrySize = this._attribute.byteStride;
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
return false;
|
|
1859
|
-
}
|
|
1860
|
-
this._attribute.buffer.write(outBytePos, valueData, entrySize);
|
|
1861
|
-
outBytePos += entrySize;
|
|
1885
|
+
const totalSize = numValues * entrySize;
|
|
1886
|
+
const valueData = buffer.decodeBytesView(totalSize);
|
|
1887
|
+
if (valueData === void 0) {
|
|
1888
|
+
return false;
|
|
1862
1889
|
}
|
|
1890
|
+
this._attribute.buffer.write(0, valueData, totalSize);
|
|
1863
1891
|
return true;
|
|
1864
1892
|
}
|
|
1865
1893
|
setPortableAttribute(att) {
|
|
@@ -1997,6 +2025,9 @@ var RAnsDecoder = class {
|
|
|
1997
2025
|
this.bufOffset = offset - 3;
|
|
1998
2026
|
this.state = memGetLe24(buf, offset - 3) & 4194303;
|
|
1999
2027
|
} else if (x === 3) {
|
|
2028
|
+
if (offset - base < 4) {
|
|
2029
|
+
return 1;
|
|
2030
|
+
}
|
|
2000
2031
|
this.bufOffset = offset - 4;
|
|
2001
2032
|
this.state = memGetLe32(buf, offset - 4) & 1073741823;
|
|
2002
2033
|
} else {
|
|
@@ -2041,12 +2072,69 @@ var RAnsDecoder = class {
|
|
|
2041
2072
|
}
|
|
2042
2073
|
// Batch ransRead() into out[0..count): all fields hoisted to locals, state
|
|
2043
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.
|
|
2044
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) {
|
|
2045
2134
|
const buf = this.buf;
|
|
2046
2135
|
const lRansBase = this.lRansBase;
|
|
2047
2136
|
const ransPrecisionBits = this.ransPrecisionBits;
|
|
2048
2137
|
const ransPrecisionMask = this.ransPrecisionMask;
|
|
2049
|
-
const lutTable = this.lutTable;
|
|
2050
2138
|
const probTable = this.probTable;
|
|
2051
2139
|
const cumProbTable = this.cumProbTable;
|
|
2052
2140
|
let state = this.state;
|
|
@@ -2107,16 +2195,12 @@ function computeRAnsPrecisionFromUniqueSymbolsBitLength(symbolsBitLength) {
|
|
|
2107
2195
|
return unclamped;
|
|
2108
2196
|
}
|
|
2109
2197
|
var RAnsSymbolDecoder = class {
|
|
2110
|
-
uniqueSymbolsBitLength_;
|
|
2111
2198
|
ransPrecisionBits_;
|
|
2112
|
-
ransPrecision_;
|
|
2113
2199
|
probabilityTable_;
|
|
2114
2200
|
numSymbols_;
|
|
2115
2201
|
ans_;
|
|
2116
2202
|
constructor(uniqueSymbolsBitLength) {
|
|
2117
|
-
this.uniqueSymbolsBitLength_ = uniqueSymbolsBitLength;
|
|
2118
2203
|
this.ransPrecisionBits_ = computeRAnsPrecisionFromUniqueSymbolsBitLength(uniqueSymbolsBitLength);
|
|
2119
|
-
this.ransPrecision_ = 1 << this.ransPrecisionBits_;
|
|
2120
2204
|
this.probabilityTable_ = null;
|
|
2121
2205
|
this.numSymbols_ = 0;
|
|
2122
2206
|
this.ans_ = new RAnsDecoder(this.ransPrecisionBits_);
|
|
@@ -3528,8 +3612,7 @@ var MeshPredictionSchemeTexCoordsPortablePredictor = class {
|
|
|
3528
3612
|
}
|
|
3529
3613
|
const xUV0 = nUV0 * pnNorm2Squared + cnDotPn * pnUV0;
|
|
3530
3614
|
const xUV1 = nUV1 * pnNorm2Squared + cnDotPn * pnUV1;
|
|
3531
|
-
|
|
3532
|
-
if (pnAbsMax > 0 && Math.abs(cnDotPn) > INT64_MAX / pnAbsMax) {
|
|
3615
|
+
if (pnAbsMaxG > 0 && cnDotPnAbs > INT64_MAX / pnAbsMaxG) {
|
|
3533
3616
|
return false;
|
|
3534
3617
|
}
|
|
3535
3618
|
const xPos0 = next0 + Math.trunc(cnDotPn * pn0 / pnNorm2Squared);
|
|
@@ -4574,15 +4657,6 @@ var AttributeQuantizationTransform = class _AttributeQuantizationTransform exten
|
|
|
4574
4657
|
}
|
|
4575
4658
|
return true;
|
|
4576
4659
|
}
|
|
4577
|
-
get quantizationBits() {
|
|
4578
|
-
return this._quantizationBits;
|
|
4579
|
-
}
|
|
4580
|
-
get range() {
|
|
4581
|
-
return this._range;
|
|
4582
|
-
}
|
|
4583
|
-
minValue(axis) {
|
|
4584
|
-
return this._minValues[axis];
|
|
4585
|
-
}
|
|
4586
4660
|
static _isQuantizationValid(quantizationBits) {
|
|
4587
4661
|
return quantizationBits >= 1 && quantizationBits <= 30;
|
|
4588
4662
|
}
|
|
@@ -4661,7 +4735,7 @@ var SequentialAttributeDecodersController = class extends AttributesDecoder {
|
|
|
4661
4735
|
if (!this._sequencer) {
|
|
4662
4736
|
return false;
|
|
4663
4737
|
}
|
|
4664
|
-
if (!this._sequencer.generateSequence(
|
|
4738
|
+
if (!this._sequencer.generateSequence()) {
|
|
4665
4739
|
return false;
|
|
4666
4740
|
}
|
|
4667
4741
|
this._pointIds = this._sequencer.getOutputPointIds();
|
|
@@ -4785,19 +4859,29 @@ var DepthFirstTraverser = class {
|
|
|
4785
4859
|
init(cornerTable, observer) {
|
|
4786
4860
|
this._cornerTable = cornerTable;
|
|
4787
4861
|
this._observer = observer;
|
|
4788
|
-
this._isFaceVisited =
|
|
4789
|
-
this._isVertexVisited =
|
|
4862
|
+
this._isFaceVisited = null;
|
|
4863
|
+
this._isVertexVisited = null;
|
|
4790
4864
|
this._numVisitedFaces = 0;
|
|
4791
4865
|
this._cornerToVertex = cornerTable.cornerToVertexArray();
|
|
4792
4866
|
this._oppositeCorners = cornerTable.oppositeCornerArray();
|
|
4793
4867
|
this._vertexLeftmost = cornerTable.vertexLeftmostCornerArray();
|
|
4794
4868
|
this._numCorners = cornerTable.numCorners();
|
|
4795
|
-
this._cornerTraversalStack = new Int32Array(this._numCorners);
|
|
4796
4869
|
}
|
|
4797
4870
|
cornerTable() {
|
|
4798
4871
|
return this._cornerTable;
|
|
4799
4872
|
}
|
|
4873
|
+
// Scratch buffers are set up here rather than in init() so a shared-traversal
|
|
4874
|
+
// -cache hit — where generateSequence returns before any traversal — skips
|
|
4875
|
+
// this entirely, including the visited-flag zero-fill (worth ~0.5% on the
|
|
4876
|
+
// 488-primitive manablade-static bundle, which shares attribute corner tables across
|
|
4877
|
+
// primitives). Uint8Array (0/1) instead of Array(bool): these flags are read
|
|
4878
|
+
// and written on every corner of the hottest decode loop (traverseFromCorner).
|
|
4879
|
+
// Decode-scoped scratch: released in bulk at the end of the decode.
|
|
4800
4880
|
onTraversalStart() {
|
|
4881
|
+
const cornerTable = this._cornerTable;
|
|
4882
|
+
this._isFaceVisited = scratchUint8Zeroed(cornerTable.numFaces());
|
|
4883
|
+
this._isVertexVisited = scratchUint8Zeroed(cornerTable.numVertices());
|
|
4884
|
+
this._cornerTraversalStack = scratchInt32(this._numCorners);
|
|
4801
4885
|
}
|
|
4802
4886
|
onTraversalEnd() {
|
|
4803
4887
|
}
|
|
@@ -4813,6 +4897,14 @@ var DepthFirstTraverser = class {
|
|
|
4813
4897
|
const vertexLeftmost = this._vertexLeftmost;
|
|
4814
4898
|
const stack = this._cornerTraversalStack;
|
|
4815
4899
|
let numVisitedFaces = this._numVisitedFaces;
|
|
4900
|
+
const sequencer = observer._sequencer;
|
|
4901
|
+
const encodingData = observer._encodingData;
|
|
4902
|
+
const obsFaces = observer._faces;
|
|
4903
|
+
const encodedToCornerMap = observer._encodedToCornerMap;
|
|
4904
|
+
const vertexToEncodedMap = observer._vertexToEncodedMap;
|
|
4905
|
+
const outPointIds = sequencer._outPointIds;
|
|
4906
|
+
let numOutPoints = sequencer._numOutPoints;
|
|
4907
|
+
let numValues = encodingData.numValues;
|
|
4816
4908
|
let stackSize = 0;
|
|
4817
4909
|
stack[stackSize++] = cornerId;
|
|
4818
4910
|
const nextCorner = cornerId % 3 === 2 ? cornerId - 2 : cornerId + 1;
|
|
@@ -4824,11 +4916,15 @@ var DepthFirstTraverser = class {
|
|
|
4824
4916
|
}
|
|
4825
4917
|
if (!isVertexVisited[nextVert]) {
|
|
4826
4918
|
isVertexVisited[nextVert] = 1;
|
|
4827
|
-
|
|
4919
|
+
outPointIds[numOutPoints++] = obsFaces[nextCorner];
|
|
4920
|
+
encodedToCornerMap[numValues] = nextCorner;
|
|
4921
|
+
vertexToEncodedMap[nextVert] = numValues++;
|
|
4828
4922
|
}
|
|
4829
4923
|
if (!isVertexVisited[prevVert]) {
|
|
4830
4924
|
isVertexVisited[prevVert] = 1;
|
|
4831
|
-
|
|
4925
|
+
outPointIds[numOutPoints++] = obsFaces[prevCorner];
|
|
4926
|
+
encodedToCornerMap[numValues] = prevCorner;
|
|
4927
|
+
vertexToEncodedMap[prevVert] = numValues++;
|
|
4832
4928
|
}
|
|
4833
4929
|
while (stackSize > 0) {
|
|
4834
4930
|
cornerId = stack[stackSize - 1];
|
|
@@ -4842,6 +4938,8 @@ var DepthFirstTraverser = class {
|
|
|
4842
4938
|
numVisitedFaces++;
|
|
4843
4939
|
const vertId = cornerToVertex[cornerId];
|
|
4844
4940
|
if (vertId === kInvalidVertexIndex2) {
|
|
4941
|
+
sequencer._numOutPoints = numOutPoints;
|
|
4942
|
+
encodingData.numValues = numValues;
|
|
4845
4943
|
return false;
|
|
4846
4944
|
}
|
|
4847
4945
|
if (!isVertexVisited[vertId]) {
|
|
@@ -4852,7 +4950,9 @@ var DepthFirstTraverser = class {
|
|
|
4852
4950
|
onBoundary = oppositeCorners[nextLc] < 0;
|
|
4853
4951
|
}
|
|
4854
4952
|
isVertexVisited[vertId] = 1;
|
|
4855
|
-
|
|
4953
|
+
outPointIds[numOutPoints++] = obsFaces[cornerId];
|
|
4954
|
+
encodedToCornerMap[numValues] = cornerId;
|
|
4955
|
+
vertexToEncodedMap[vertId] = numValues++;
|
|
4856
4956
|
if (!onBoundary) {
|
|
4857
4957
|
const nextCornerId2 = cornerId % 3 === 2 ? cornerId - 2 : cornerId + 1;
|
|
4858
4958
|
cornerId = oppositeCorners[nextCornerId2];
|
|
@@ -4889,6 +4989,8 @@ var DepthFirstTraverser = class {
|
|
|
4889
4989
|
}
|
|
4890
4990
|
}
|
|
4891
4991
|
this._numVisitedFaces = numVisitedFaces;
|
|
4992
|
+
sequencer._numOutPoints = numOutPoints;
|
|
4993
|
+
encodingData.numValues = numValues;
|
|
4892
4994
|
return true;
|
|
4893
4995
|
}
|
|
4894
4996
|
};
|
|
@@ -5101,7 +5203,7 @@ var MeshTraversalSequencer = class {
|
|
|
5101
5203
|
setTraverser(traverser) {
|
|
5102
5204
|
this._traverser = traverser;
|
|
5103
5205
|
}
|
|
5104
|
-
generateSequence(
|
|
5206
|
+
generateSequence() {
|
|
5105
5207
|
const cornerTable = this._traverser.cornerTable();
|
|
5106
5208
|
const methodId = this._traverser._traversalMethodId;
|
|
5107
5209
|
const cacheKey = cornerTable.cornerToVertexArray();
|
|
@@ -5439,7 +5541,7 @@ var MeshEdgebreakerDecoderImpl = class {
|
|
|
5439
5541
|
return true;
|
|
5440
5542
|
}
|
|
5441
5543
|
_decodeConnectivity(numSymbols) {
|
|
5442
|
-
const activeCornerStack =
|
|
5544
|
+
const activeCornerStack = scratchInt32(numSymbols + this._topologySplitData.length + 16);
|
|
5443
5545
|
let activeCornerStackSize = 0;
|
|
5444
5546
|
const topologySplitActiveCorners = /* @__PURE__ */ new Map();
|
|
5445
5547
|
const invalidVertices = [];
|
|
@@ -6303,7 +6405,7 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
|
|
|
6303
6405
|
this._activeContext = -1;
|
|
6304
6406
|
this._minValence = 2;
|
|
6305
6407
|
this._maxValence = 7;
|
|
6306
|
-
this._vertexValences =
|
|
6408
|
+
this._vertexValences = new Int32Array(0);
|
|
6307
6409
|
this._contextSymbols = [];
|
|
6308
6410
|
this._contextCounters = [];
|
|
6309
6411
|
}
|
|
@@ -6327,7 +6429,7 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
|
|
|
6327
6429
|
if (this._numVertices < 0) {
|
|
6328
6430
|
return false;
|
|
6329
6431
|
}
|
|
6330
|
-
this._vertexValences = new
|
|
6432
|
+
this._vertexValences = new Int32Array(this._numVertices);
|
|
6331
6433
|
const numUniqueValences = this._maxValence - this._minValence + 1;
|
|
6332
6434
|
this._contextSymbols = new Array(numUniqueValences);
|
|
6333
6435
|
this._contextCounters = new Array(numUniqueValences);
|
|
@@ -6369,34 +6471,37 @@ var MeshEdgebreakerTraversalValenceDecoder = class extends MeshEdgebreakerTraver
|
|
|
6369
6471
|
return this._lastSymbol;
|
|
6370
6472
|
}
|
|
6371
6473
|
newActiveCornerReached(corner) {
|
|
6372
|
-
const
|
|
6373
|
-
const
|
|
6374
|
-
const
|
|
6474
|
+
const cornerToVertex = this._cornerTable._cornerToVertex;
|
|
6475
|
+
const valences = this._vertexValences;
|
|
6476
|
+
const next = corner % 3 === 2 ? corner - 2 : corner + 1;
|
|
6477
|
+
const prev = corner % 3 === 0 ? corner + 2 : corner - 1;
|
|
6478
|
+
const vertNext = cornerToVertex[next];
|
|
6479
|
+
const vertPrev = cornerToVertex[prev];
|
|
6375
6480
|
switch (this._lastSymbol) {
|
|
6376
6481
|
case TOPOLOGY_C:
|
|
6377
6482
|
case TOPOLOGY_S:
|
|
6378
|
-
|
|
6379
|
-
|
|
6483
|
+
valences[vertNext] += 1;
|
|
6484
|
+
valences[vertPrev] += 1;
|
|
6380
6485
|
break;
|
|
6381
6486
|
case TOPOLOGY_R:
|
|
6382
|
-
|
|
6383
|
-
|
|
6384
|
-
|
|
6487
|
+
valences[cornerToVertex[corner]] += 1;
|
|
6488
|
+
valences[vertNext] += 1;
|
|
6489
|
+
valences[vertPrev] += 2;
|
|
6385
6490
|
break;
|
|
6386
6491
|
case TOPOLOGY_L:
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
|
|
6492
|
+
valences[cornerToVertex[corner]] += 1;
|
|
6493
|
+
valences[vertNext] += 2;
|
|
6494
|
+
valences[vertPrev] += 1;
|
|
6390
6495
|
break;
|
|
6391
6496
|
case TOPOLOGY_E:
|
|
6392
|
-
|
|
6393
|
-
|
|
6394
|
-
|
|
6497
|
+
valences[cornerToVertex[corner]] += 2;
|
|
6498
|
+
valences[vertNext] += 2;
|
|
6499
|
+
valences[vertPrev] += 2;
|
|
6395
6500
|
break;
|
|
6396
6501
|
default:
|
|
6397
6502
|
break;
|
|
6398
6503
|
}
|
|
6399
|
-
const activeValence =
|
|
6504
|
+
const activeValence = valences[vertNext];
|
|
6400
6505
|
let clampedValence;
|
|
6401
6506
|
if (activeValence < this._minValence) {
|
|
6402
6507
|
clampedValence = this._minValence;
|
|
@@ -6515,45 +6620,30 @@ var MeshSequentialDecoder = class extends MeshDecoder {
|
|
|
6515
6620
|
return false;
|
|
6516
6621
|
}
|
|
6517
6622
|
} else {
|
|
6623
|
+
const mesh = this.mesh();
|
|
6624
|
+
mesh.setNumFaces(numFaces);
|
|
6625
|
+
const faces = mesh.faces_;
|
|
6626
|
+
const numIndices = numFaces * 3;
|
|
6627
|
+
const buffer = this.buffer();
|
|
6518
6628
|
if (numPoints < 256) {
|
|
6519
|
-
|
|
6520
|
-
|
|
6521
|
-
|
|
6522
|
-
const val = this.buffer().decodeUint8();
|
|
6523
|
-
if (val === void 0) return false;
|
|
6524
|
-
face[j] = val;
|
|
6525
|
-
}
|
|
6526
|
-
this.mesh().addFace(face);
|
|
6527
|
-
}
|
|
6629
|
+
const src = buffer.decodeBytesView(numIndices);
|
|
6630
|
+
if (src === void 0) return false;
|
|
6631
|
+
for (let i = 0; i < numIndices; ++i) faces[i] = src[i];
|
|
6528
6632
|
} else if (numPoints < 1 << 16) {
|
|
6529
|
-
|
|
6530
|
-
|
|
6531
|
-
|
|
6532
|
-
const val = this.buffer().decodeUint16();
|
|
6533
|
-
if (val === void 0) return false;
|
|
6534
|
-
face[j] = val;
|
|
6535
|
-
}
|
|
6536
|
-
this.mesh().addFace(face);
|
|
6537
|
-
}
|
|
6633
|
+
const src = buffer.decodeBytesView(numIndices * 2);
|
|
6634
|
+
if (src === void 0) return false;
|
|
6635
|
+
for (let i = 0; i < numIndices; ++i) faces[i] = src[i * 2] | src[i * 2 + 1] << 8;
|
|
6538
6636
|
} else if (numPoints < 1 << 21) {
|
|
6539
|
-
for (let i = 0; i <
|
|
6540
|
-
const
|
|
6541
|
-
|
|
6542
|
-
|
|
6543
|
-
if (val === void 0) return false;
|
|
6544
|
-
face[j] = val;
|
|
6545
|
-
}
|
|
6546
|
-
this.mesh().addFace(face);
|
|
6637
|
+
for (let i = 0; i < numIndices; ++i) {
|
|
6638
|
+
const val = decodeVarint(buffer);
|
|
6639
|
+
if (val === void 0) return false;
|
|
6640
|
+
faces[i] = val;
|
|
6547
6641
|
}
|
|
6548
6642
|
} else {
|
|
6549
|
-
|
|
6550
|
-
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
if (val === void 0) return false;
|
|
6554
|
-
face[j] = val;
|
|
6555
|
-
}
|
|
6556
|
-
this.mesh().addFace(face);
|
|
6643
|
+
const src = buffer.decodeBytesView(numIndices * 4);
|
|
6644
|
+
if (src === void 0) return false;
|
|
6645
|
+
for (let i = 0; i < numIndices; ++i) {
|
|
6646
|
+
faces[i] = src[i * 4] | src[i * 4 + 1] << 8 | src[i * 4 + 2] << 16 | src[i * 4 + 3] << 24;
|
|
6557
6647
|
}
|
|
6558
6648
|
}
|
|
6559
6649
|
}
|
|
@@ -6567,32 +6657,31 @@ var MeshSequentialDecoder = class extends MeshDecoder {
|
|
|
6567
6657
|
);
|
|
6568
6658
|
}
|
|
6569
6659
|
_decodeAndDecompressIndices(numFaces) {
|
|
6570
|
-
const
|
|
6571
|
-
|
|
6660
|
+
const numIndices = numFaces * 3;
|
|
6661
|
+
const indicesBuffer = new Uint32Array(numIndices);
|
|
6662
|
+
if (!decodeSymbols(numIndices, 1, this.buffer(), indicesBuffer)) {
|
|
6572
6663
|
return false;
|
|
6573
6664
|
}
|
|
6665
|
+
const mesh = this.mesh();
|
|
6666
|
+
mesh.setNumFaces(numFaces);
|
|
6667
|
+
const faces = mesh.faces_;
|
|
6574
6668
|
let lastIndexValue = 0;
|
|
6575
|
-
let
|
|
6576
|
-
|
|
6577
|
-
|
|
6578
|
-
|
|
6579
|
-
|
|
6580
|
-
|
|
6581
|
-
|
|
6582
|
-
|
|
6583
|
-
|
|
6584
|
-
|
|
6585
|
-
|
|
6586
|
-
} else {
|
|
6587
|
-
if (indexDiff > 2147483647 - lastIndexValue) {
|
|
6588
|
-
return false;
|
|
6589
|
-
}
|
|
6669
|
+
for (let i = 0; i < numIndices; ++i) {
|
|
6670
|
+
const encodedVal = indicesBuffer[i];
|
|
6671
|
+
let indexDiff = encodedVal >>> 1;
|
|
6672
|
+
if (encodedVal & 1) {
|
|
6673
|
+
if (indexDiff > lastIndexValue) {
|
|
6674
|
+
return false;
|
|
6675
|
+
}
|
|
6676
|
+
indexDiff = -indexDiff;
|
|
6677
|
+
} else {
|
|
6678
|
+
if (indexDiff > 2147483647 - lastIndexValue) {
|
|
6679
|
+
return false;
|
|
6590
6680
|
}
|
|
6591
|
-
const indexValue = indexDiff + lastIndexValue | 0;
|
|
6592
|
-
face[j] = indexValue;
|
|
6593
|
-
lastIndexValue = indexValue;
|
|
6594
6681
|
}
|
|
6595
|
-
|
|
6682
|
+
const indexValue = indexDiff + lastIndexValue | 0;
|
|
6683
|
+
faces[i] = indexValue;
|
|
6684
|
+
lastIndexValue = indexValue;
|
|
6596
6685
|
}
|
|
6597
6686
|
return true;
|
|
6598
6687
|
}
|
|
@@ -6650,9 +6739,15 @@ var Decoder = class {
|
|
|
6650
6739
|
if (result.header.encoderType !== EncodedGeometryType.TRIANGULAR_MESH) {
|
|
6651
6740
|
return { ok: false, message: "Input is not a mesh." };
|
|
6652
6741
|
}
|
|
6653
|
-
|
|
6654
|
-
|
|
6655
|
-
|
|
6742
|
+
try {
|
|
6743
|
+
const decoder = createMeshDecoder(result.header.encoderMethod);
|
|
6744
|
+
const status = decoder.decodeMesh(this.options_, inBuffer, outGeometry);
|
|
6745
|
+
return { ok: status.ok(), message: status.errorMsg };
|
|
6746
|
+
} catch (error) {
|
|
6747
|
+
return { ok: false, message: error instanceof Error ? error.message : String(error) };
|
|
6748
|
+
} finally {
|
|
6749
|
+
releaseScratch();
|
|
6750
|
+
}
|
|
6656
6751
|
}
|
|
6657
6752
|
options() {
|
|
6658
6753
|
return this.options_;
|
package/dist/three.d.ts
CHANGED
|
@@ -113,8 +113,6 @@ declare class Mesh extends PointCloud {
|
|
|
113
113
|
elementType: number;
|
|
114
114
|
}[];
|
|
115
115
|
constructor();
|
|
116
|
-
_ensureFaceCapacity(numFaces: number): void;
|
|
117
|
-
addFace(face: ArrayLike<number>): void;
|
|
118
116
|
setNumFaces(numFaces: number): void;
|
|
119
117
|
numFaces(): number;
|
|
120
118
|
face(faceId: number): number[];
|
|
@@ -123,6 +121,12 @@ declare class Mesh extends PointCloud {
|
|
|
123
121
|
|
|
124
122
|
type AttributeIDs = Record<string, number | string>;
|
|
125
123
|
type AttributeTypes = Record<string, string>;
|
|
124
|
+
interface MiniDRACOLoaderOptions {
|
|
125
|
+
manager?: LoadingManager;
|
|
126
|
+
workers?: boolean;
|
|
127
|
+
workerLimit?: number;
|
|
128
|
+
syncByteThreshold?: number;
|
|
129
|
+
}
|
|
126
130
|
interface TaskConfig {
|
|
127
131
|
attributeIDs: AttributeIDs;
|
|
128
132
|
attributeTypes: AttributeTypes;
|
|
@@ -142,10 +146,18 @@ interface WorkerEntry {
|
|
|
142
146
|
worker: Worker;
|
|
143
147
|
pending: number;
|
|
144
148
|
}
|
|
149
|
+
interface QueuedTask {
|
|
150
|
+
id: number;
|
|
151
|
+
buffer: ArrayBuffer;
|
|
152
|
+
taskConfig: TaskConfig;
|
|
153
|
+
resolve: (raw: RawGeometry) => void;
|
|
154
|
+
reject: (error: unknown) => void;
|
|
155
|
+
}
|
|
145
156
|
declare class MiniDRACOLoader extends Loader<BufferGeometry> {
|
|
146
157
|
defaultAttributeIDs: AttributeIDs;
|
|
147
158
|
defaultAttributeTypes: AttributeTypes;
|
|
148
159
|
workerLimit: number;
|
|
160
|
+
syncByteThreshold: number;
|
|
149
161
|
_workers: WorkerEntry[];
|
|
150
162
|
_taskId: number;
|
|
151
163
|
_tasks: Map<number, {
|
|
@@ -153,11 +165,17 @@ declare class MiniDRACOLoader extends Loader<BufferGeometry> {
|
|
|
153
165
|
reject: (error: unknown) => void;
|
|
154
166
|
entry: WorkerEntry;
|
|
155
167
|
}>;
|
|
168
|
+
_batch: QueuedTask[];
|
|
169
|
+
_batchScheduled: boolean;
|
|
156
170
|
_workersBroken: boolean;
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
171
|
+
_workerUrl: string | URL | null;
|
|
172
|
+
_workerBlobUrl: string | null;
|
|
173
|
+
constructor(managerOrOptions?: LoadingManager | MiniDRACOLoaderOptions);
|
|
174
|
+
setWorkerUrl(url: string | URL | null): this;
|
|
175
|
+
setDecoderPath(_path?: unknown): this;
|
|
176
|
+
setDecoderConfig(_config?: unknown): this;
|
|
160
177
|
setWorkerLimit(limit: number): this;
|
|
178
|
+
setWorkers(enabled: boolean): this;
|
|
161
179
|
preload(): this;
|
|
162
180
|
dispose(): this;
|
|
163
181
|
load(url: string, onLoad: (geometry: BufferGeometry) => void, onProgress?: (event: ProgressEvent) => void, onError?: (err: unknown) => void): void;
|
|
@@ -166,12 +184,13 @@ declare class MiniDRACOLoader extends Loader<BufferGeometry> {
|
|
|
166
184
|
decodeGeometry(buffer: ArrayBuffer, taskConfig: TaskConfig): Promise<BufferGeometry>;
|
|
167
185
|
_runTask(buffer: ArrayBuffer, taskConfig: TaskConfig): Promise<BufferGeometry>;
|
|
168
186
|
_workersAvailable(): boolean;
|
|
169
|
-
_getWorker(): WorkerEntry;
|
|
187
|
+
_getWorker(): WorkerEntry | null;
|
|
170
188
|
_decodeInWorker(buffer: ArrayBuffer, taskConfig: TaskConfig): Promise<RawGeometry>;
|
|
189
|
+
_flushBatch(): void;
|
|
171
190
|
_buildGeometryFromRaw(raw: RawGeometry, taskConfig: TaskConfig): BufferGeometry;
|
|
172
191
|
_decodeBuffer(buffer: ArrayBuffer, taskConfig: TaskConfig): BufferGeometry;
|
|
173
192
|
_buildGeometry(dracoGeometry: Mesh, taskConfig: TaskConfig): BufferGeometry;
|
|
174
193
|
_assignVertexColorSpace(attribute: BufferAttribute, inputColorSpace: string): void;
|
|
175
194
|
}
|
|
176
195
|
|
|
177
|
-
export { type AttributeIDs, type AttributeTypes, MiniDRACOLoader as DRACOLoader, MiniDRACOLoader };
|
|
196
|
+
export { type AttributeIDs, type AttributeTypes, MiniDRACOLoader as DRACOLoader, MiniDRACOLoader, type MiniDRACOLoaderOptions };
|