@loaders.gl/draco 4.3.4 → 4.4.0-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dist.dev.js +13059 -1021
- package/dist/dist.min.js +12 -3
- package/dist/draco-arrow-loader.d.ts +30 -0
- package/dist/draco-arrow-loader.d.ts.map +1 -0
- package/dist/draco-arrow-loader.js +20 -0
- package/dist/draco-arrow-loader.js.map +1 -0
- package/dist/draco-format.d.ts +13 -0
- package/dist/draco-format.d.ts.map +1 -0
- package/dist/draco-format.js +16 -0
- package/dist/draco-format.js.map +1 -0
- package/dist/draco-loader.d.ts +29 -2
- package/dist/draco-loader.d.ts.map +1 -1
- package/dist/draco-loader.js +21 -1
- package/dist/draco-loader.js.map +1 -0
- package/dist/draco-worker-node.js +429 -185
- package/dist/draco-worker-node.js.map +4 -4
- package/dist/draco-worker.js +188 -116
- package/dist/draco-worker.js.map +4 -4
- package/dist/draco-writer-worker-node.js +301 -76
- package/dist/draco-writer-worker-node.js.map +4 -4
- package/dist/draco-writer-worker.js +61 -7
- package/dist/draco-writer-worker.js.map +2 -2
- package/dist/draco-writer.d.ts +16 -0
- package/dist/draco-writer.d.ts.map +1 -1
- package/dist/draco-writer.js +21 -1
- package/dist/draco-writer.js.map +1 -0
- package/dist/draco3d/draco3d-types.js +1 -0
- package/dist/draco3d/draco3d-types.js.map +1 -0
- package/dist/index.cjs +865 -811
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +5 -48
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -38
- package/dist/index.js.map +1 -0
- package/dist/lib/draco-builder.d.ts.map +1 -1
- package/dist/lib/draco-builder.js +1 -0
- package/dist/lib/draco-builder.js.map +1 -0
- package/dist/lib/draco-module-loader.d.ts +3 -2
- package/dist/lib/draco-module-loader.d.ts.map +1 -1
- package/dist/lib/draco-module-loader.js +53 -10
- package/dist/lib/draco-module-loader.js.map +1 -0
- package/dist/lib/draco-parser.d.ts.map +1 -1
- package/dist/lib/draco-parser.js +4 -1
- package/dist/lib/draco-parser.js.map +1 -0
- package/dist/lib/draco-types.js +1 -0
- package/dist/lib/draco-types.js.map +1 -0
- package/dist/lib/utils/get-draco-schema.d.ts.map +1 -1
- package/dist/lib/utils/get-draco-schema.js +2 -1
- package/dist/lib/utils/get-draco-schema.js.map +1 -0
- package/dist/lib/utils/version.js +2 -1
- package/dist/lib/utils/version.js.map +1 -0
- package/dist/libs/libs/draco_decoder.wasm +0 -0
- package/dist/libs/libs/draco_encoder.js +52 -0
- package/dist/libs/libs/draco_wasm_wrapper.js +117 -0
- package/dist/workers/draco-worker-node.js +1 -0
- package/dist/workers/draco-worker-node.js.map +1 -0
- package/dist/workers/draco-worker.js +1 -0
- package/dist/workers/draco-worker.js.map +1 -0
- package/dist/workers/draco-writer-worker-node.cjs +18 -0
- package/dist/workers/draco-writer-worker-node.cjs.map +1 -0
- package/dist/workers/draco-writer-worker-node.d.cts +2 -0
- package/dist/workers/draco-writer-worker-node.d.cts.map +1 -0
- package/dist/workers/draco-writer-worker-node.js +1 -0
- package/dist/workers/draco-writer-worker-node.js.map +1 -0
- package/dist/workers/draco-writer-worker.js +1 -0
- package/dist/workers/draco-writer-worker.js.map +1 -0
- package/package.json +19 -6
- package/src/draco-arrow-loader.ts +25 -0
- package/src/draco-format.ts +18 -0
- package/src/draco-loader.ts +26 -3
- package/src/draco-writer.ts +22 -1
- package/src/index.ts +5 -45
- package/src/lib/draco-module-loader.ts +87 -23
- package/src/lib/draco-parser.ts +3 -1
- package/src/lib/utils/get-draco-schema.ts +2 -1
- package/src/workers/draco-writer-worker-node.cjs +18 -0
package/dist/index.cjs
CHANGED
|
@@ -22,979 +22,1019 @@ var dist_exports = {};
|
|
|
22
22
|
__export(dist_exports, {
|
|
23
23
|
DRACO_EXTERNAL_LIBRARIES: () => DRACO_EXTERNAL_LIBRARIES,
|
|
24
24
|
DRACO_EXTERNAL_LIBRARY_URLS: () => DRACO_EXTERNAL_LIBRARY_URLS,
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
DracoArrowLoader: () => DracoArrowLoader,
|
|
26
|
+
DracoLoader: () => DracoLoader,
|
|
27
|
+
DracoWorkerLoader: () => DracoWorkerLoader,
|
|
27
28
|
DracoWriter: () => DracoWriter,
|
|
28
29
|
DracoWriterWorker: () => DracoWriterWorker
|
|
29
30
|
});
|
|
30
31
|
module.exports = __toCommonJS(dist_exports);
|
|
31
32
|
|
|
32
|
-
// dist/lib/
|
|
33
|
-
var
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
var
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
mimeTypes: ["application/octet-stream"],
|
|
47
|
-
binary: true,
|
|
48
|
-
tests: ["DRACO"],
|
|
49
|
-
options: {
|
|
50
|
-
draco: {
|
|
51
|
-
decoderType: typeof WebAssembly === "object" ? "wasm" : "js",
|
|
52
|
-
// 'js' for IE11
|
|
53
|
-
libraryPath: "libs/",
|
|
54
|
-
extraAttributes: {},
|
|
55
|
-
attributeNameEntry: void 0
|
|
56
|
-
}
|
|
57
|
-
}
|
|
33
|
+
// dist/lib/draco-module-loader.js
|
|
34
|
+
var import_worker_utils = require("@loaders.gl/worker-utils");
|
|
35
|
+
var DRACO_DECODER_VERSION = "1.5.6";
|
|
36
|
+
var DRACO_ENCODER_VERSION = "1.4.1";
|
|
37
|
+
var STATIC_DECODER_URL = `https://www.gstatic.com/draco/versioned/decoders/${DRACO_DECODER_VERSION}`;
|
|
38
|
+
var DRACO_EXTERNAL_LIBRARIES = {
|
|
39
|
+
/** The primary Draco3D encoder, javascript wrapper part */
|
|
40
|
+
DECODER: "draco_wasm_wrapper.js",
|
|
41
|
+
/** The primary draco decoder, compiled web assembly part */
|
|
42
|
+
DECODER_WASM: "draco_decoder.wasm",
|
|
43
|
+
/** Fallback decoder for non-webassebly environments. Very big bundle, lower performance */
|
|
44
|
+
FALLBACK_DECODER: "draco_decoder.js",
|
|
45
|
+
/** Draco encoder */
|
|
46
|
+
ENCODER: "draco_encoder.js"
|
|
58
47
|
};
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
48
|
+
var DRACO_EXTERNAL_LIBRARY_URLS = {
|
|
49
|
+
[DRACO_EXTERNAL_LIBRARIES.DECODER]: `${STATIC_DECODER_URL}/${DRACO_EXTERNAL_LIBRARIES.DECODER}`,
|
|
50
|
+
[DRACO_EXTERNAL_LIBRARIES.DECODER_WASM]: `${STATIC_DECODER_URL}/${DRACO_EXTERNAL_LIBRARIES.DECODER_WASM}`,
|
|
51
|
+
[DRACO_EXTERNAL_LIBRARIES.FALLBACK_DECODER]: `${STATIC_DECODER_URL}/${DRACO_EXTERNAL_LIBRARIES.FALLBACK_DECODER}`,
|
|
52
|
+
[DRACO_EXTERNAL_LIBRARIES.ENCODER]: `https://raw.githubusercontent.com/google/draco/${DRACO_ENCODER_VERSION}/javascript/${DRACO_EXTERNAL_LIBRARIES.ENCODER}`
|
|
53
|
+
};
|
|
54
|
+
var loadDecoderPromise;
|
|
55
|
+
var loadEncoderPromise;
|
|
56
|
+
async function loadDracoDecoderModule(options = {}, type) {
|
|
57
|
+
const modules = options.modules || {};
|
|
58
|
+
if (modules.draco3d) {
|
|
59
|
+
loadDecoderPromise ||= modules.draco3d.createDecoderModule({}).then((draco) => {
|
|
60
|
+
return { draco };
|
|
61
|
+
});
|
|
62
|
+
} else {
|
|
63
|
+
loadDecoderPromise ||= loadDracoDecoder(options, type);
|
|
73
64
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
65
|
+
return await loadDecoderPromise;
|
|
66
|
+
}
|
|
67
|
+
async function loadDracoEncoderModule(options) {
|
|
68
|
+
const modules = options.modules || {};
|
|
69
|
+
if (modules.draco3d) {
|
|
70
|
+
loadEncoderPromise ||= modules.draco3d.createEncoderModule({}).then((draco) => {
|
|
71
|
+
return { draco };
|
|
72
|
+
});
|
|
73
|
+
} else {
|
|
74
|
+
loadEncoderPromise ||= loadDracoEncoder(options);
|
|
77
75
|
}
|
|
78
|
-
return
|
|
76
|
+
return await loadEncoderPromise;
|
|
79
77
|
}
|
|
80
|
-
function
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
78
|
+
function getLibraryExport(library, exportName) {
|
|
79
|
+
if (library && typeof library === "object") {
|
|
80
|
+
if (library.default) {
|
|
81
|
+
return library.default;
|
|
82
|
+
}
|
|
83
|
+
if (library[exportName]) {
|
|
84
|
+
return library[exportName];
|
|
85
|
+
}
|
|
85
86
|
}
|
|
86
|
-
return
|
|
87
|
+
return library;
|
|
87
88
|
}
|
|
88
|
-
function
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
async function loadDracoDecoder(options, type) {
|
|
90
|
+
let DracoDecoderModule;
|
|
91
|
+
let wasmBinary;
|
|
92
|
+
switch (type) {
|
|
93
|
+
case "js":
|
|
94
|
+
DracoDecoderModule = await (0, import_worker_utils.loadLibrary)(DRACO_EXTERNAL_LIBRARY_URLS[DRACO_EXTERNAL_LIBRARIES.FALLBACK_DECODER], "draco", options, DRACO_EXTERNAL_LIBRARIES.FALLBACK_DECODER);
|
|
95
|
+
break;
|
|
96
|
+
case "wasm":
|
|
97
|
+
default:
|
|
98
|
+
try {
|
|
99
|
+
[DracoDecoderModule, wasmBinary] = await Promise.all([
|
|
100
|
+
await (0, import_worker_utils.loadLibrary)(DRACO_EXTERNAL_LIBRARY_URLS[DRACO_EXTERNAL_LIBRARIES.DECODER], "draco", options, DRACO_EXTERNAL_LIBRARIES.DECODER),
|
|
101
|
+
await (0, import_worker_utils.loadLibrary)(DRACO_EXTERNAL_LIBRARY_URLS[DRACO_EXTERNAL_LIBRARIES.DECODER_WASM], "draco", options, DRACO_EXTERNAL_LIBRARIES.DECODER_WASM)
|
|
102
|
+
]);
|
|
103
|
+
} catch {
|
|
104
|
+
DracoDecoderModule = null;
|
|
105
|
+
wasmBinary = null;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
DracoDecoderModule = getLibraryExport(DracoDecoderModule, "DracoDecoderModule");
|
|
109
|
+
DracoDecoderModule = DracoDecoderModule || globalThis.DracoDecoderModule;
|
|
110
|
+
if (!DracoDecoderModule && !import_worker_utils.isBrowser) {
|
|
111
|
+
[DracoDecoderModule, wasmBinary] = await Promise.all([
|
|
112
|
+
await (0, import_worker_utils.loadLibrary)(DRACO_EXTERNAL_LIBRARY_URLS[DRACO_EXTERNAL_LIBRARIES.DECODER], "draco", { ...options, useLocalLibraries: true }, DRACO_EXTERNAL_LIBRARIES.DECODER),
|
|
113
|
+
await (0, import_worker_utils.loadLibrary)(DRACO_EXTERNAL_LIBRARY_URLS[DRACO_EXTERNAL_LIBRARIES.DECODER_WASM], "draco", { ...options, useLocalLibraries: true }, DRACO_EXTERNAL_LIBRARIES.DECODER_WASM)
|
|
114
|
+
]);
|
|
115
|
+
DracoDecoderModule = getLibraryExport(DracoDecoderModule, "DracoDecoderModule");
|
|
116
|
+
DracoDecoderModule = DracoDecoderModule || globalThis.DracoDecoderModule;
|
|
117
|
+
}
|
|
118
|
+
return await initializeDracoDecoder(DracoDecoderModule, wasmBinary);
|
|
92
119
|
}
|
|
93
|
-
function
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
for (const key in metadata) {
|
|
97
|
-
serializedMetadata[`${key}.string`] = JSON.stringify(metadata[key]);
|
|
120
|
+
function initializeDracoDecoder(DracoDecoderModule, wasmBinary) {
|
|
121
|
+
if (typeof DracoDecoderModule !== "function") {
|
|
122
|
+
throw new Error("DracoDecoderModule could not be loaded");
|
|
98
123
|
}
|
|
99
|
-
|
|
124
|
+
const options = {};
|
|
125
|
+
if (wasmBinary) {
|
|
126
|
+
options.wasmBinary = wasmBinary;
|
|
127
|
+
}
|
|
128
|
+
return new Promise((resolve) => {
|
|
129
|
+
DracoDecoderModule({
|
|
130
|
+
...options,
|
|
131
|
+
onModuleLoaded: (draco) => resolve({ draco })
|
|
132
|
+
// Module is Promise-like. Wrap in object to avoid loop.
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
async function loadDracoEncoder(options) {
|
|
137
|
+
let DracoEncoderModule = await (0, import_worker_utils.loadLibrary)(DRACO_EXTERNAL_LIBRARY_URLS[DRACO_EXTERNAL_LIBRARIES.ENCODER], "draco", options, DRACO_EXTERNAL_LIBRARIES.ENCODER);
|
|
138
|
+
DracoEncoderModule = getLibraryExport(DracoEncoderModule, "DracoEncoderModule");
|
|
139
|
+
DracoEncoderModule = DracoEncoderModule || globalThis.DracoEncoderModule;
|
|
140
|
+
if (!DracoEncoderModule && !import_worker_utils.isBrowser) {
|
|
141
|
+
DracoEncoderModule = await (0, import_worker_utils.loadLibrary)(DRACO_EXTERNAL_LIBRARY_URLS[DRACO_EXTERNAL_LIBRARIES.ENCODER], "draco", { ...options, useLocalLibraries: true }, DRACO_EXTERNAL_LIBRARIES.ENCODER);
|
|
142
|
+
DracoEncoderModule = getLibraryExport(DracoEncoderModule, "DracoEncoderModule");
|
|
143
|
+
DracoEncoderModule = DracoEncoderModule || globalThis.DracoEncoderModule;
|
|
144
|
+
}
|
|
145
|
+
if (typeof DracoEncoderModule !== "function") {
|
|
146
|
+
throw new Error("DracoEncoderModule could not be loaded");
|
|
147
|
+
}
|
|
148
|
+
return new Promise((resolve) => {
|
|
149
|
+
DracoEncoderModule({
|
|
150
|
+
onModuleLoaded: (draco) => resolve({ draco })
|
|
151
|
+
// Module is Promise-like. Wrap in object to avoid loop.
|
|
152
|
+
});
|
|
153
|
+
});
|
|
100
154
|
}
|
|
101
155
|
|
|
102
|
-
// dist/lib/draco-
|
|
103
|
-
var
|
|
156
|
+
// dist/lib/draco-builder.js
|
|
157
|
+
var GLTF_TO_DRACO_ATTRIBUTE_NAME_MAP = {
|
|
104
158
|
POSITION: "POSITION",
|
|
105
159
|
NORMAL: "NORMAL",
|
|
106
|
-
|
|
107
|
-
|
|
160
|
+
COLOR_0: "COLOR",
|
|
161
|
+
TEXCOORD_0: "TEX_COORD"
|
|
108
162
|
};
|
|
109
|
-
var
|
|
110
|
-
1: Int8Array,
|
|
111
|
-
2: Uint8Array,
|
|
112
|
-
3: Int16Array,
|
|
113
|
-
4: Uint16Array,
|
|
114
|
-
5: Int32Array,
|
|
115
|
-
6: Uint32Array,
|
|
116
|
-
// 7: BigInt64Array,
|
|
117
|
-
// 8: BigUint64Array,
|
|
118
|
-
9: Float32Array
|
|
119
|
-
// 10: Float64Array
|
|
120
|
-
// 11: BOOL - What array type do we use for this?
|
|
163
|
+
var noop = () => {
|
|
121
164
|
};
|
|
122
|
-
var
|
|
123
|
-
var DracoParser = class {
|
|
165
|
+
var DracoBuilder = class {
|
|
124
166
|
draco;
|
|
125
|
-
|
|
126
|
-
|
|
167
|
+
dracoEncoder;
|
|
168
|
+
dracoMeshBuilder;
|
|
169
|
+
dracoMetadataBuilder;
|
|
170
|
+
log;
|
|
127
171
|
// draco - the draco decoder, either import `draco3d` or load dynamically
|
|
128
172
|
constructor(draco) {
|
|
129
173
|
this.draco = draco;
|
|
130
|
-
this.
|
|
131
|
-
this.
|
|
174
|
+
this.dracoEncoder = new this.draco.Encoder();
|
|
175
|
+
this.dracoMeshBuilder = new this.draco.MeshBuilder();
|
|
176
|
+
this.dracoMetadataBuilder = new this.draco.MetadataBuilder();
|
|
132
177
|
}
|
|
133
|
-
/**
|
|
134
|
-
* Destroy draco resources
|
|
135
|
-
*/
|
|
136
178
|
destroy() {
|
|
137
|
-
this.
|
|
138
|
-
this.
|
|
179
|
+
this.destroyEncodedObject(this.dracoMeshBuilder);
|
|
180
|
+
this.destroyEncodedObject(this.dracoEncoder);
|
|
181
|
+
this.destroyEncodedObject(this.dracoMetadataBuilder);
|
|
182
|
+
this.dracoMeshBuilder = null;
|
|
183
|
+
this.dracoEncoder = null;
|
|
184
|
+
this.draco = null;
|
|
139
185
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
*/
|
|
145
|
-
parseSync(arrayBuffer, options = {}) {
|
|
146
|
-
const buffer = new this.draco.DecoderBuffer();
|
|
147
|
-
buffer.Init(new Int8Array(arrayBuffer), arrayBuffer.byteLength);
|
|
148
|
-
this._disableAttributeTransforms(options);
|
|
149
|
-
const geometry_type = this.decoder.GetEncodedGeometryType(buffer);
|
|
150
|
-
const dracoGeometry = geometry_type === this.draco.TRIANGULAR_MESH ? new this.draco.Mesh() : new this.draco.PointCloud();
|
|
151
|
-
try {
|
|
152
|
-
let dracoStatus;
|
|
153
|
-
switch (geometry_type) {
|
|
154
|
-
case this.draco.TRIANGULAR_MESH:
|
|
155
|
-
dracoStatus = this.decoder.DecodeBufferToMesh(buffer, dracoGeometry);
|
|
156
|
-
break;
|
|
157
|
-
case this.draco.POINT_CLOUD:
|
|
158
|
-
dracoStatus = this.decoder.DecodeBufferToPointCloud(buffer, dracoGeometry);
|
|
159
|
-
break;
|
|
160
|
-
default:
|
|
161
|
-
throw new Error("DRACO: Unknown geometry type.");
|
|
162
|
-
}
|
|
163
|
-
if (!dracoStatus.ok() || !dracoGeometry.ptr) {
|
|
164
|
-
const message = `DRACO decompression failed: ${dracoStatus.error_msg()}`;
|
|
165
|
-
throw new Error(message);
|
|
166
|
-
}
|
|
167
|
-
const loaderData = this._getDracoLoaderData(dracoGeometry, geometry_type, options);
|
|
168
|
-
const geometry = this._getMeshData(dracoGeometry, loaderData, options);
|
|
169
|
-
const boundingBox = (0, import_schema2.getMeshBoundingBox)(geometry.attributes);
|
|
170
|
-
const schema = getDracoSchema(geometry.attributes, loaderData, geometry.indices);
|
|
171
|
-
const data = {
|
|
172
|
-
loader: "draco",
|
|
173
|
-
loaderData,
|
|
174
|
-
header: {
|
|
175
|
-
vertexCount: dracoGeometry.num_points(),
|
|
176
|
-
boundingBox
|
|
177
|
-
},
|
|
178
|
-
...geometry,
|
|
179
|
-
schema
|
|
180
|
-
};
|
|
181
|
-
return data;
|
|
182
|
-
} finally {
|
|
183
|
-
this.draco.destroy(buffer);
|
|
184
|
-
if (dracoGeometry) {
|
|
185
|
-
this.draco.destroy(dracoGeometry);
|
|
186
|
-
}
|
|
186
|
+
// TBD - when does this need to be called?
|
|
187
|
+
destroyEncodedObject(object) {
|
|
188
|
+
if (object) {
|
|
189
|
+
this.draco.destroy(object);
|
|
187
190
|
}
|
|
188
191
|
}
|
|
189
|
-
// Draco specific "loader data"
|
|
190
192
|
/**
|
|
191
|
-
*
|
|
192
|
-
* @param
|
|
193
|
-
* @param geometry_type
|
|
193
|
+
* Encode mesh or point cloud
|
|
194
|
+
* @param mesh =({})
|
|
194
195
|
* @param options
|
|
195
|
-
* @returns
|
|
196
196
|
*/
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
return
|
|
201
|
-
geometry_type,
|
|
202
|
-
num_attributes: dracoGeometry.num_attributes(),
|
|
203
|
-
num_points: dracoGeometry.num_points(),
|
|
204
|
-
num_faces: dracoGeometry instanceof this.draco.Mesh ? dracoGeometry.num_faces() : 0,
|
|
205
|
-
metadata,
|
|
206
|
-
attributes
|
|
207
|
-
};
|
|
197
|
+
encodeSync(mesh, options = {}) {
|
|
198
|
+
this.log = noop;
|
|
199
|
+
this._setOptions(options);
|
|
200
|
+
return options.pointcloud ? this._encodePointCloud(mesh, options) : this._encodeMesh(mesh, options);
|
|
208
201
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
metadata
|
|
230
|
-
};
|
|
231
|
-
const quantization = this._getQuantizationTransform(dracoAttribute, options);
|
|
232
|
-
if (quantization) {
|
|
233
|
-
dracoAttributes[dracoAttribute.unique_id()].quantization_transform = quantization;
|
|
202
|
+
// PRIVATE
|
|
203
|
+
_getAttributesFromMesh(mesh) {
|
|
204
|
+
const attributes = { ...mesh, ...mesh.attributes };
|
|
205
|
+
if (mesh.indices) {
|
|
206
|
+
attributes.indices = mesh.indices;
|
|
207
|
+
}
|
|
208
|
+
return attributes;
|
|
209
|
+
}
|
|
210
|
+
_encodePointCloud(pointcloud, options) {
|
|
211
|
+
const dracoPointCloud = new this.draco.PointCloud();
|
|
212
|
+
if (options.metadata) {
|
|
213
|
+
this._addGeometryMetadata(dracoPointCloud, options.metadata);
|
|
214
|
+
}
|
|
215
|
+
const attributes = this._getAttributesFromMesh(pointcloud);
|
|
216
|
+
this._createDracoPointCloud(dracoPointCloud, attributes, options);
|
|
217
|
+
const dracoData = new this.draco.DracoInt8Array();
|
|
218
|
+
try {
|
|
219
|
+
const encodedLen = this.dracoEncoder.EncodePointCloudToDracoBuffer(dracoPointCloud, false, dracoData);
|
|
220
|
+
if (!(encodedLen > 0)) {
|
|
221
|
+
throw new Error("Draco encoding failed.");
|
|
234
222
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
223
|
+
this.log(`DRACO encoded ${dracoPointCloud.num_points()} points
|
|
224
|
+
with ${dracoPointCloud.num_attributes()} attributes into ${encodedLen} bytes`);
|
|
225
|
+
return dracoInt8ArrayToArrayBuffer(dracoData);
|
|
226
|
+
} finally {
|
|
227
|
+
this.destroyEncodedObject(dracoData);
|
|
228
|
+
this.destroyEncodedObject(dracoPointCloud);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
_encodeMesh(mesh, options) {
|
|
232
|
+
const dracoMesh = new this.draco.Mesh();
|
|
233
|
+
if (options.metadata) {
|
|
234
|
+
this._addGeometryMetadata(dracoMesh, options.metadata);
|
|
235
|
+
}
|
|
236
|
+
const attributes = this._getAttributesFromMesh(mesh);
|
|
237
|
+
this._createDracoMesh(dracoMesh, attributes, options);
|
|
238
|
+
const dracoData = new this.draco.DracoInt8Array();
|
|
239
|
+
try {
|
|
240
|
+
const encodedLen = this.dracoEncoder.EncodeMeshToDracoBuffer(dracoMesh, dracoData);
|
|
241
|
+
if (encodedLen <= 0) {
|
|
242
|
+
throw new Error("Draco encoding failed.");
|
|
238
243
|
}
|
|
244
|
+
this.log(`DRACO encoded ${dracoMesh.num_points()} points
|
|
245
|
+
with ${dracoMesh.num_attributes()} attributes into ${encodedLen} bytes`);
|
|
246
|
+
return dracoInt8ArrayToArrayBuffer(dracoData);
|
|
247
|
+
} finally {
|
|
248
|
+
this.destroyEncodedObject(dracoData);
|
|
249
|
+
this.destroyEncodedObject(dracoMesh);
|
|
239
250
|
}
|
|
240
|
-
return dracoAttributes;
|
|
241
251
|
}
|
|
242
252
|
/**
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
* @param dracoGeometry
|
|
246
|
-
* @param options
|
|
253
|
+
* Set encoding options.
|
|
254
|
+
* @param {{speed?: any; method?: any; quantization?: any;}} options
|
|
247
255
|
*/
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
if (!positionAttribute) {
|
|
252
|
-
throw new Error("DRACO: No position attribute found.");
|
|
256
|
+
_setOptions(options) {
|
|
257
|
+
if ("speed" in options) {
|
|
258
|
+
this.dracoEncoder.SetSpeedOptions(...options.speed);
|
|
253
259
|
}
|
|
254
|
-
if (
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
return {
|
|
258
|
-
topology: "triangle-strip",
|
|
259
|
-
mode: 4,
|
|
260
|
-
// GL.TRIANGLES
|
|
261
|
-
attributes,
|
|
262
|
-
indices: {
|
|
263
|
-
value: this._getTriangleStripIndices(dracoGeometry),
|
|
264
|
-
size: 1
|
|
265
|
-
}
|
|
266
|
-
};
|
|
267
|
-
case "triangle-list":
|
|
268
|
-
default:
|
|
269
|
-
return {
|
|
270
|
-
topology: "triangle-list",
|
|
271
|
-
mode: 5,
|
|
272
|
-
// GL.TRIANGLE_STRIP
|
|
273
|
-
attributes,
|
|
274
|
-
indices: {
|
|
275
|
-
value: this._getTriangleListIndices(dracoGeometry),
|
|
276
|
-
size: 1
|
|
277
|
-
}
|
|
278
|
-
};
|
|
279
|
-
}
|
|
260
|
+
if ("method" in options) {
|
|
261
|
+
const dracoMethod = this.draco[options.method || "MESH_SEQUENTIAL_ENCODING"];
|
|
262
|
+
this.dracoEncoder.SetEncodingMethod(dracoMethod);
|
|
280
263
|
}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
};
|
|
287
|
-
}
|
|
288
|
-
_getMeshAttributes(loaderData, dracoGeometry, options) {
|
|
289
|
-
const attributes = {};
|
|
290
|
-
for (const loaderAttribute of Object.values(loaderData.attributes)) {
|
|
291
|
-
const attributeName = this._deduceAttributeName(loaderAttribute, options);
|
|
292
|
-
loaderAttribute.name = attributeName;
|
|
293
|
-
const values = this._getAttributeValues(dracoGeometry, loaderAttribute);
|
|
294
|
-
if (values) {
|
|
295
|
-
const { value, size } = values;
|
|
296
|
-
attributes[attributeName] = {
|
|
297
|
-
value,
|
|
298
|
-
size,
|
|
299
|
-
byteOffset: loaderAttribute.byte_offset,
|
|
300
|
-
byteStride: loaderAttribute.byte_stride,
|
|
301
|
-
normalized: loaderAttribute.normalized
|
|
302
|
-
};
|
|
264
|
+
if ("quantization" in options) {
|
|
265
|
+
for (const attribute in options.quantization) {
|
|
266
|
+
const bits = options.quantization[attribute];
|
|
267
|
+
const dracoPosition = this.draco[attribute];
|
|
268
|
+
this.dracoEncoder.SetAttributeQuantization(dracoPosition, bits);
|
|
303
269
|
}
|
|
304
270
|
}
|
|
305
|
-
return attributes;
|
|
306
271
|
}
|
|
307
|
-
// MESH INDICES EXTRACTION
|
|
308
272
|
/**
|
|
309
|
-
*
|
|
310
|
-
* @param
|
|
273
|
+
* @param {Mesh} dracoMesh
|
|
274
|
+
* @param {object} attributes
|
|
275
|
+
* @returns {Mesh}
|
|
311
276
|
*/
|
|
312
|
-
|
|
313
|
-
const
|
|
314
|
-
const numIndices = numFaces * 3;
|
|
315
|
-
const byteLength = numIndices * INDEX_ITEM_SIZE;
|
|
316
|
-
const ptr = this.draco._malloc(byteLength);
|
|
277
|
+
_createDracoMesh(dracoMesh, attributes, options) {
|
|
278
|
+
const optionalMetadata = options.attributesMetadata || {};
|
|
317
279
|
try {
|
|
318
|
-
this.
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
280
|
+
const positions = this._getPositionAttribute(attributes);
|
|
281
|
+
if (!positions) {
|
|
282
|
+
throw new Error("positions");
|
|
283
|
+
}
|
|
284
|
+
const vertexCount = positions.length / 3;
|
|
285
|
+
for (let attributeName in attributes) {
|
|
286
|
+
const attribute = attributes[attributeName];
|
|
287
|
+
attributeName = GLTF_TO_DRACO_ATTRIBUTE_NAME_MAP[attributeName] || attributeName;
|
|
288
|
+
const uniqueId = this._addAttributeToMesh(dracoMesh, attributeName, attribute, vertexCount);
|
|
289
|
+
if (uniqueId !== -1) {
|
|
290
|
+
this._addAttributeMetadata(dracoMesh, uniqueId, {
|
|
291
|
+
name: attributeName,
|
|
292
|
+
...optionalMetadata[attributeName] || {}
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
} catch (error) {
|
|
297
|
+
this.destroyEncodedObject(dracoMesh);
|
|
298
|
+
throw error;
|
|
322
299
|
}
|
|
300
|
+
return dracoMesh;
|
|
323
301
|
}
|
|
324
302
|
/**
|
|
325
|
-
*
|
|
326
|
-
* @param
|
|
303
|
+
* @param {} dracoPointCloud
|
|
304
|
+
* @param {object} attributes
|
|
327
305
|
*/
|
|
328
|
-
|
|
329
|
-
const
|
|
306
|
+
_createDracoPointCloud(dracoPointCloud, attributes, options) {
|
|
307
|
+
const optionalMetadata = options.attributesMetadata || {};
|
|
330
308
|
try {
|
|
331
|
-
this.
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
309
|
+
const positions = this._getPositionAttribute(attributes);
|
|
310
|
+
if (!positions) {
|
|
311
|
+
throw new Error("positions");
|
|
312
|
+
}
|
|
313
|
+
const vertexCount = positions.length / 3;
|
|
314
|
+
for (let attributeName in attributes) {
|
|
315
|
+
const attribute = attributes[attributeName];
|
|
316
|
+
attributeName = GLTF_TO_DRACO_ATTRIBUTE_NAME_MAP[attributeName] || attributeName;
|
|
317
|
+
const uniqueId = this._addAttributeToMesh(dracoPointCloud, attributeName, attribute, vertexCount);
|
|
318
|
+
if (uniqueId !== -1) {
|
|
319
|
+
this._addAttributeMetadata(dracoPointCloud, uniqueId, {
|
|
320
|
+
name: attributeName,
|
|
321
|
+
...optionalMetadata[attributeName] || {}
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
} catch (error) {
|
|
326
|
+
this.destroyEncodedObject(dracoPointCloud);
|
|
327
|
+
throw error;
|
|
335
328
|
}
|
|
329
|
+
return dracoPointCloud;
|
|
336
330
|
}
|
|
337
331
|
/**
|
|
338
|
-
*
|
|
339
|
-
* @param dracoGeometry
|
|
340
|
-
* @param dracoAttribute
|
|
332
|
+
* @param mesh
|
|
341
333
|
* @param attributeName
|
|
334
|
+
* @param attribute
|
|
335
|
+
* @param vertexCount
|
|
342
336
|
*/
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
console.warn(`DRACO: Unsupported attribute type ${attribute.data_type}`);
|
|
347
|
-
return null;
|
|
337
|
+
_addAttributeToMesh(mesh, attributeName, attribute, vertexCount) {
|
|
338
|
+
if (!ArrayBuffer.isView(attribute)) {
|
|
339
|
+
return -1;
|
|
348
340
|
}
|
|
349
|
-
const
|
|
350
|
-
const
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
try {
|
|
357
|
-
const dracoAttribute = this.decoder.GetAttribute(dracoGeometry, attribute.attribute_index);
|
|
358
|
-
this.decoder.GetAttributeDataArrayForAllPoints(dracoGeometry, dracoAttribute, dataType, byteLength, ptr);
|
|
359
|
-
value = new TypedArrayCtor(this.draco.HEAPF32.buffer, ptr, numValues).slice();
|
|
360
|
-
} finally {
|
|
361
|
-
this.draco._free(ptr);
|
|
341
|
+
const type = this._getDracoAttributeType(attributeName);
|
|
342
|
+
const size = attribute.length / vertexCount;
|
|
343
|
+
if (type === "indices") {
|
|
344
|
+
const numFaces = attribute.length / 3;
|
|
345
|
+
this.log(`Adding attribute ${attributeName}, size ${numFaces}`);
|
|
346
|
+
this.dracoMeshBuilder.AddFacesToMesh(mesh, numFaces, attribute);
|
|
347
|
+
return -1;
|
|
362
348
|
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
349
|
+
this.log(`Adding attribute ${attributeName}, size ${size}`);
|
|
350
|
+
const builder = this.dracoMeshBuilder;
|
|
351
|
+
const { buffer } = attribute;
|
|
352
|
+
switch (attribute.constructor) {
|
|
353
|
+
case Int8Array:
|
|
354
|
+
return builder.AddInt8Attribute(mesh, type, vertexCount, size, new Int8Array(buffer));
|
|
355
|
+
case Int16Array:
|
|
356
|
+
return builder.AddInt16Attribute(mesh, type, vertexCount, size, new Int16Array(buffer));
|
|
357
|
+
case Int32Array:
|
|
358
|
+
return builder.AddInt32Attribute(mesh, type, vertexCount, size, new Int32Array(buffer));
|
|
359
|
+
case Uint8Array:
|
|
360
|
+
case Uint8ClampedArray:
|
|
361
|
+
return builder.AddUInt8Attribute(mesh, type, vertexCount, size, new Uint8Array(buffer));
|
|
362
|
+
case Uint16Array:
|
|
363
|
+
return builder.AddUInt16Attribute(mesh, type, vertexCount, size, new Uint16Array(buffer));
|
|
364
|
+
case Uint32Array:
|
|
365
|
+
return builder.AddUInt32Attribute(mesh, type, vertexCount, size, new Uint32Array(buffer));
|
|
366
|
+
case Float32Array:
|
|
367
|
+
return builder.AddFloatAttribute(mesh, type, vertexCount, size, new Float32Array(buffer));
|
|
368
|
+
default:
|
|
369
|
+
console.warn("Unsupported attribute type", attribute);
|
|
370
|
+
return -1;
|
|
378
371
|
}
|
|
379
|
-
return attributeNames;
|
|
380
372
|
}
|
|
381
|
-
*/
|
|
382
373
|
/**
|
|
383
|
-
*
|
|
384
|
-
*
|
|
385
|
-
*
|
|
386
|
-
* types
|
|
387
|
-
* @param attributeData
|
|
374
|
+
* DRACO can compress attributes of know type better
|
|
375
|
+
* TODO - expose an attribute type map?
|
|
376
|
+
* @param attributeName
|
|
388
377
|
*/
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
378
|
+
_getDracoAttributeType(attributeName) {
|
|
379
|
+
switch (attributeName.toLowerCase()) {
|
|
380
|
+
case "indices":
|
|
381
|
+
return "indices";
|
|
382
|
+
case "position":
|
|
383
|
+
case "positions":
|
|
384
|
+
case "vertices":
|
|
385
|
+
return this.draco.POSITION;
|
|
386
|
+
case "normal":
|
|
387
|
+
case "normals":
|
|
388
|
+
return this.draco.NORMAL;
|
|
389
|
+
case "color":
|
|
390
|
+
case "colors":
|
|
391
|
+
return this.draco.COLOR;
|
|
392
|
+
case "texcoord":
|
|
393
|
+
case "texcoords":
|
|
394
|
+
return this.draco.TEX_COORD;
|
|
395
|
+
default:
|
|
396
|
+
return this.draco.GENERIC;
|
|
395
397
|
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
398
|
+
}
|
|
399
|
+
_getPositionAttribute(attributes) {
|
|
400
|
+
for (const attributeName in attributes) {
|
|
401
|
+
const attribute = attributes[attributeName];
|
|
402
|
+
const dracoType = this._getDracoAttributeType(attributeName);
|
|
403
|
+
if (dracoType === this.draco.POSITION) {
|
|
404
|
+
return attribute;
|
|
401
405
|
}
|
|
402
406
|
}
|
|
403
|
-
|
|
404
|
-
if (attribute.metadata[entryName]) {
|
|
405
|
-
return attribute.metadata[entryName].string;
|
|
406
|
-
}
|
|
407
|
-
return `CUSTOM_ATTRIBUTE_${uniqueId}`;
|
|
408
|
-
}
|
|
409
|
-
// METADATA EXTRACTION
|
|
410
|
-
/** Get top level metadata */
|
|
411
|
-
_getTopLevelMetadata(dracoGeometry) {
|
|
412
|
-
const dracoMetadata = this.decoder.GetMetadata(dracoGeometry);
|
|
413
|
-
return this._getDracoMetadata(dracoMetadata);
|
|
414
|
-
}
|
|
415
|
-
/** Get per attribute metadata */
|
|
416
|
-
_getAttributeMetadata(dracoGeometry, attributeId) {
|
|
417
|
-
const dracoMetadata = this.decoder.GetAttributeMetadata(dracoGeometry, attributeId);
|
|
418
|
-
return this._getDracoMetadata(dracoMetadata);
|
|
407
|
+
return null;
|
|
419
408
|
}
|
|
420
409
|
/**
|
|
421
|
-
*
|
|
422
|
-
* @param
|
|
423
|
-
* @
|
|
410
|
+
* Add metadata for the geometry.
|
|
411
|
+
* @param dracoGeometry - WASM Draco Object
|
|
412
|
+
* @param metadata
|
|
424
413
|
*/
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
const result = {};
|
|
430
|
-
const numEntries = this.metadataQuerier.NumEntries(dracoMetadata);
|
|
431
|
-
for (let entryIndex = 0; entryIndex < numEntries; entryIndex++) {
|
|
432
|
-
const entryName = this.metadataQuerier.GetEntryName(dracoMetadata, entryIndex);
|
|
433
|
-
result[entryName] = this._getDracoMetadataField(dracoMetadata, entryName);
|
|
434
|
-
}
|
|
435
|
-
return result;
|
|
414
|
+
_addGeometryMetadata(dracoGeometry, metadata) {
|
|
415
|
+
const dracoMetadata = new this.draco.Metadata();
|
|
416
|
+
this._populateDracoMetadata(dracoMetadata, metadata);
|
|
417
|
+
this.dracoMeshBuilder.AddMetadata(dracoGeometry, dracoMetadata);
|
|
436
418
|
}
|
|
437
419
|
/**
|
|
438
|
-
*
|
|
439
|
-
* @param
|
|
440
|
-
* @param
|
|
420
|
+
* Add metadata for an attribute to geometry.
|
|
421
|
+
* @param dracoGeometry - WASM Draco Object
|
|
422
|
+
* @param uniqueAttributeId
|
|
423
|
+
* @param metadata
|
|
441
424
|
*/
|
|
442
|
-
|
|
443
|
-
const
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
const intArray = getInt32Array(dracoArray);
|
|
447
|
-
return {
|
|
448
|
-
int: this.metadataQuerier.GetIntEntry(dracoMetadata, entryName),
|
|
449
|
-
string: this.metadataQuerier.GetStringEntry(dracoMetadata, entryName),
|
|
450
|
-
double: this.metadataQuerier.GetDoubleEntry(dracoMetadata, entryName),
|
|
451
|
-
intArray
|
|
452
|
-
};
|
|
453
|
-
} finally {
|
|
454
|
-
this.draco.destroy(dracoArray);
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
// QUANTIZED ATTRIBUTE SUPPORT (NO DECOMPRESSION)
|
|
458
|
-
/** Skip transforms for specific attribute types */
|
|
459
|
-
_disableAttributeTransforms(options) {
|
|
460
|
-
const { quantizedAttributes = [], octahedronAttributes = [] } = options;
|
|
461
|
-
const skipAttributes = [...quantizedAttributes, ...octahedronAttributes];
|
|
462
|
-
for (const dracoAttributeName of skipAttributes) {
|
|
463
|
-
this.decoder.SkipAttributeTransform(this.draco[dracoAttributeName]);
|
|
464
|
-
}
|
|
425
|
+
_addAttributeMetadata(dracoGeometry, uniqueAttributeId, metadata) {
|
|
426
|
+
const dracoAttributeMetadata = new this.draco.Metadata();
|
|
427
|
+
this._populateDracoMetadata(dracoAttributeMetadata, metadata);
|
|
428
|
+
this.dracoMeshBuilder.SetMetadataForAttribute(dracoGeometry, uniqueAttributeId, dracoAttributeMetadata);
|
|
465
429
|
}
|
|
466
430
|
/**
|
|
467
|
-
*
|
|
468
|
-
* @
|
|
431
|
+
* Add contents of object or map to a WASM Draco Metadata Object
|
|
432
|
+
* @param dracoMetadata - WASM Draco Object
|
|
433
|
+
* @param metadata
|
|
469
434
|
*/
|
|
470
|
-
|
|
471
|
-
const
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
return null;
|
|
489
|
-
}
|
|
490
|
-
_getOctahedronTransform(dracoAttribute, options) {
|
|
491
|
-
const { octahedronAttributes = [] } = options;
|
|
492
|
-
const attribute_type = dracoAttribute.attribute_type();
|
|
493
|
-
const octahedron = octahedronAttributes.map((type) => this.decoder[type]).includes(attribute_type);
|
|
494
|
-
if (octahedron) {
|
|
495
|
-
const transform = new this.draco.AttributeQuantizationTransform();
|
|
496
|
-
try {
|
|
497
|
-
if (transform.InitFromAttribute(dracoAttribute)) {
|
|
498
|
-
return {
|
|
499
|
-
quantization_bits: transform.quantization_bits()
|
|
500
|
-
};
|
|
501
|
-
}
|
|
502
|
-
} finally {
|
|
503
|
-
this.draco.destroy(transform);
|
|
435
|
+
_populateDracoMetadata(dracoMetadata, metadata) {
|
|
436
|
+
for (const [key, value] of getEntries(metadata)) {
|
|
437
|
+
switch (typeof value) {
|
|
438
|
+
case "number":
|
|
439
|
+
if (Math.trunc(value) === value) {
|
|
440
|
+
this.dracoMetadataBuilder.AddIntEntry(dracoMetadata, key, value);
|
|
441
|
+
} else {
|
|
442
|
+
this.dracoMetadataBuilder.AddDoubleEntry(dracoMetadata, key, value);
|
|
443
|
+
}
|
|
444
|
+
break;
|
|
445
|
+
case "object":
|
|
446
|
+
if (value instanceof Int32Array) {
|
|
447
|
+
this.dracoMetadataBuilder.AddIntEntryArray(dracoMetadata, key, value, value.length);
|
|
448
|
+
}
|
|
449
|
+
break;
|
|
450
|
+
case "string":
|
|
451
|
+
default:
|
|
452
|
+
this.dracoMetadataBuilder.AddStringEntry(dracoMetadata, key, value);
|
|
504
453
|
}
|
|
505
454
|
}
|
|
506
|
-
return null;
|
|
507
455
|
}
|
|
508
456
|
};
|
|
509
|
-
function
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
case Int16Array:
|
|
516
|
-
return draco.DT_INT16;
|
|
517
|
-
case Int32Array:
|
|
518
|
-
return draco.DT_INT32;
|
|
519
|
-
case Uint8Array:
|
|
520
|
-
return draco.DT_UINT8;
|
|
521
|
-
case Uint16Array:
|
|
522
|
-
return draco.DT_UINT16;
|
|
523
|
-
case Uint32Array:
|
|
524
|
-
return draco.DT_UINT32;
|
|
525
|
-
default:
|
|
526
|
-
return draco.DT_INVALID;
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
function getInt32Array(dracoArray) {
|
|
530
|
-
const numValues = dracoArray.size();
|
|
531
|
-
const intArray = new Int32Array(numValues);
|
|
532
|
-
for (let i = 0; i < numValues; i++) {
|
|
533
|
-
intArray[i] = dracoArray.GetValue(i);
|
|
457
|
+
function dracoInt8ArrayToArrayBuffer(dracoData) {
|
|
458
|
+
const byteLength = dracoData.size();
|
|
459
|
+
const outputBuffer = new ArrayBuffer(byteLength);
|
|
460
|
+
const outputData = new Int8Array(outputBuffer);
|
|
461
|
+
for (let i = 0; i < byteLength; ++i) {
|
|
462
|
+
outputData[i] = dracoData.GetValue(i);
|
|
534
463
|
}
|
|
535
|
-
return
|
|
464
|
+
return outputBuffer;
|
|
536
465
|
}
|
|
537
|
-
function
|
|
538
|
-
const
|
|
539
|
-
|
|
540
|
-
for (let i = 0; i < numValues; i++) {
|
|
541
|
-
intArray[i] = dracoArray.GetValue(i);
|
|
542
|
-
}
|
|
543
|
-
return intArray;
|
|
466
|
+
function getEntries(container) {
|
|
467
|
+
const hasEntriesFunc = container.entries && !container.hasOwnProperty("entries");
|
|
468
|
+
return hasEntriesFunc ? container.entries() : Object.entries(container);
|
|
544
469
|
}
|
|
545
470
|
|
|
546
|
-
// dist/lib/
|
|
547
|
-
var
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
var
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
471
|
+
// dist/lib/utils/version.js
|
|
472
|
+
var VERSION = true ? "4.4.0-alpha.10" : "latest";
|
|
473
|
+
|
|
474
|
+
// dist/draco-writer.js
|
|
475
|
+
var DEFAULT_DRACO_WRITER_OPTIONS = {
|
|
476
|
+
pointcloud: false,
|
|
477
|
+
// Set to true if pointcloud (mode: 0, no indices)
|
|
478
|
+
attributeNameEntry: "name"
|
|
479
|
+
// Draco Compression Parameters
|
|
480
|
+
// method: 'MESH_EDGEBREAKER_ENCODING', // Use draco defaults
|
|
481
|
+
// speed: [5, 5], // Use draco defaults
|
|
482
|
+
// quantization: { // Use draco defaults
|
|
483
|
+
// POSITION: 10
|
|
484
|
+
// }
|
|
560
485
|
};
|
|
561
|
-
var
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
486
|
+
var DracoWriterWorker = {
|
|
487
|
+
id: "draco-writer",
|
|
488
|
+
name: "Draco compressed geometry writer",
|
|
489
|
+
module: "draco",
|
|
490
|
+
version: VERSION,
|
|
491
|
+
worker: true,
|
|
492
|
+
options: {
|
|
493
|
+
draco: {},
|
|
494
|
+
source: null
|
|
495
|
+
}
|
|
566
496
|
};
|
|
567
|
-
var
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
497
|
+
var DracoWriter = {
|
|
498
|
+
name: "DRACO",
|
|
499
|
+
id: "draco",
|
|
500
|
+
module: "draco",
|
|
501
|
+
version: VERSION,
|
|
502
|
+
extensions: ["drc"],
|
|
503
|
+
mimeTypes: ["application/octet-stream"],
|
|
504
|
+
options: {
|
|
505
|
+
draco: DEFAULT_DRACO_WRITER_OPTIONS
|
|
506
|
+
},
|
|
507
|
+
encode
|
|
508
|
+
};
|
|
509
|
+
async function encode(data, options = {}) {
|
|
510
|
+
const { draco } = await loadDracoEncoderModule(options.core || {});
|
|
511
|
+
const dracoBuilder = new DracoBuilder(draco);
|
|
512
|
+
try {
|
|
513
|
+
return dracoBuilder.encodeSync(data, options.draco);
|
|
514
|
+
} finally {
|
|
515
|
+
dracoBuilder.destroy();
|
|
577
516
|
}
|
|
578
|
-
return await loadDecoderPromise;
|
|
579
517
|
}
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
518
|
+
|
|
519
|
+
// dist/lib/draco-parser.js
|
|
520
|
+
var import_schema_utils2 = require("@loaders.gl/schema-utils");
|
|
521
|
+
|
|
522
|
+
// dist/lib/utils/get-draco-schema.js
|
|
523
|
+
var import_schema_utils = require("@loaders.gl/schema-utils");
|
|
524
|
+
function getDracoSchema(attributes, loaderData, indices) {
|
|
525
|
+
const metadata = makeMetadata(loaderData.metadata);
|
|
526
|
+
const fields = [];
|
|
527
|
+
const namedLoaderDataAttributes = transformAttributesLoaderData(loaderData.attributes);
|
|
528
|
+
for (const attributeName in attributes) {
|
|
529
|
+
const attribute = attributes[attributeName];
|
|
530
|
+
const field = getArrowFieldFromAttribute(attributeName, attribute, namedLoaderDataAttributes[attributeName]);
|
|
531
|
+
fields.push(field);
|
|
588
532
|
}
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
let DracoDecoderModule;
|
|
593
|
-
let wasmBinary;
|
|
594
|
-
switch (options.draco && options.draco.decoderType) {
|
|
595
|
-
case "js":
|
|
596
|
-
DracoDecoderModule = await (0, import_worker_utils.loadLibrary)(DRACO_EXTERNAL_LIBRARY_URLS[DRACO_EXTERNAL_LIBRARIES.FALLBACK_DECODER], "draco", options, DRACO_EXTERNAL_LIBRARIES.FALLBACK_DECODER);
|
|
597
|
-
break;
|
|
598
|
-
case "wasm":
|
|
599
|
-
default:
|
|
600
|
-
[DracoDecoderModule, wasmBinary] = await Promise.all([
|
|
601
|
-
await (0, import_worker_utils.loadLibrary)(DRACO_EXTERNAL_LIBRARY_URLS[DRACO_EXTERNAL_LIBRARIES.DECODER], "draco", options, DRACO_EXTERNAL_LIBRARIES.DECODER),
|
|
602
|
-
await (0, import_worker_utils.loadLibrary)(DRACO_EXTERNAL_LIBRARY_URLS[DRACO_EXTERNAL_LIBRARIES.DECODER_WASM], "draco", options, DRACO_EXTERNAL_LIBRARIES.DECODER_WASM)
|
|
603
|
-
]);
|
|
533
|
+
if (indices) {
|
|
534
|
+
const indicesField = getArrowFieldFromAttribute("indices", indices);
|
|
535
|
+
fields.push(indicesField);
|
|
604
536
|
}
|
|
605
|
-
|
|
606
|
-
return await initializeDracoDecoder(DracoDecoderModule, wasmBinary);
|
|
537
|
+
return { fields, metadata };
|
|
607
538
|
}
|
|
608
|
-
function
|
|
609
|
-
const
|
|
610
|
-
|
|
611
|
-
|
|
539
|
+
function transformAttributesLoaderData(loaderData) {
|
|
540
|
+
const result = {};
|
|
541
|
+
for (const key in loaderData) {
|
|
542
|
+
const dracoAttribute = loaderData[key];
|
|
543
|
+
result[dracoAttribute.name || "undefined"] = dracoAttribute;
|
|
612
544
|
}
|
|
613
|
-
return
|
|
614
|
-
DracoDecoderModule({
|
|
615
|
-
...options,
|
|
616
|
-
onModuleLoaded: (draco) => resolve({ draco })
|
|
617
|
-
// Module is Promise-like. Wrap in object to avoid loop.
|
|
618
|
-
});
|
|
619
|
-
});
|
|
545
|
+
return result;
|
|
620
546
|
}
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
return
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
547
|
+
function getArrowFieldFromAttribute(attributeName, attribute, loaderData) {
|
|
548
|
+
const metadataMap = loaderData ? makeMetadata(loaderData.metadata) : void 0;
|
|
549
|
+
const field = (0, import_schema_utils.deduceMeshField)(attributeName, attribute, metadataMap);
|
|
550
|
+
return field;
|
|
551
|
+
}
|
|
552
|
+
function makeMetadata(metadata) {
|
|
553
|
+
Object.entries(metadata);
|
|
554
|
+
const serializedMetadata = {};
|
|
555
|
+
for (const key in metadata) {
|
|
556
|
+
serializedMetadata[`${key}.string`] = JSON.stringify(metadata[key]);
|
|
557
|
+
}
|
|
558
|
+
return serializedMetadata;
|
|
630
559
|
}
|
|
631
560
|
|
|
632
|
-
// dist/lib/draco-
|
|
633
|
-
var
|
|
561
|
+
// dist/lib/draco-parser.js
|
|
562
|
+
var DRACO_TO_GLTF_ATTRIBUTE_NAME_MAP = {
|
|
634
563
|
POSITION: "POSITION",
|
|
635
564
|
NORMAL: "NORMAL",
|
|
636
|
-
|
|
637
|
-
|
|
565
|
+
COLOR: "COLOR_0",
|
|
566
|
+
TEX_COORD: "TEXCOORD_0"
|
|
638
567
|
};
|
|
639
|
-
var
|
|
568
|
+
var DRACO_DATA_TYPE_TO_TYPED_ARRAY_MAP = {
|
|
569
|
+
1: Int8Array,
|
|
570
|
+
2: Uint8Array,
|
|
571
|
+
3: Int16Array,
|
|
572
|
+
4: Uint16Array,
|
|
573
|
+
5: Int32Array,
|
|
574
|
+
6: Uint32Array,
|
|
575
|
+
// 7: BigInt64Array,
|
|
576
|
+
// 8: BigUint64Array,
|
|
577
|
+
9: Float32Array
|
|
578
|
+
// 10: Float64Array
|
|
579
|
+
// 11: BOOL - What array type do we use for this?
|
|
640
580
|
};
|
|
641
|
-
var
|
|
581
|
+
var INDEX_ITEM_SIZE = 4;
|
|
582
|
+
var DracoParser = class {
|
|
642
583
|
draco;
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
dracoMetadataBuilder;
|
|
646
|
-
log;
|
|
584
|
+
decoder;
|
|
585
|
+
metadataQuerier;
|
|
647
586
|
// draco - the draco decoder, either import `draco3d` or load dynamically
|
|
648
587
|
constructor(draco) {
|
|
649
588
|
this.draco = draco;
|
|
650
|
-
this.
|
|
651
|
-
this.
|
|
652
|
-
this.dracoMetadataBuilder = new this.draco.MetadataBuilder();
|
|
589
|
+
this.decoder = new this.draco.Decoder();
|
|
590
|
+
this.metadataQuerier = new this.draco.MetadataQuerier();
|
|
653
591
|
}
|
|
592
|
+
/**
|
|
593
|
+
* Destroy draco resources
|
|
594
|
+
*/
|
|
654
595
|
destroy() {
|
|
655
|
-
this.
|
|
656
|
-
this.
|
|
657
|
-
this.destroyEncodedObject(this.dracoMetadataBuilder);
|
|
658
|
-
this.dracoMeshBuilder = null;
|
|
659
|
-
this.dracoEncoder = null;
|
|
660
|
-
this.draco = null;
|
|
596
|
+
this.draco.destroy(this.decoder);
|
|
597
|
+
this.draco.destroy(this.metadataQuerier);
|
|
661
598
|
}
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
599
|
+
/**
|
|
600
|
+
* NOTE: caller must call `destroyGeometry` on the return value after using it
|
|
601
|
+
* @param arrayBuffer
|
|
602
|
+
* @param options
|
|
603
|
+
*/
|
|
604
|
+
parseSync(arrayBuffer, options = {}) {
|
|
605
|
+
const buffer = new this.draco.DecoderBuffer();
|
|
606
|
+
buffer.Init(new Int8Array(arrayBuffer), arrayBuffer.byteLength);
|
|
607
|
+
this._disableAttributeTransforms(options);
|
|
608
|
+
const geometry_type = this.decoder.GetEncodedGeometryType(buffer);
|
|
609
|
+
const dracoGeometry = geometry_type === this.draco.TRIANGULAR_MESH ? new this.draco.Mesh() : new this.draco.PointCloud();
|
|
610
|
+
try {
|
|
611
|
+
let dracoStatus;
|
|
612
|
+
switch (geometry_type) {
|
|
613
|
+
case this.draco.TRIANGULAR_MESH:
|
|
614
|
+
dracoStatus = this.decoder.DecodeBufferToMesh(buffer, dracoGeometry);
|
|
615
|
+
break;
|
|
616
|
+
case this.draco.POINT_CLOUD:
|
|
617
|
+
dracoStatus = this.decoder.DecodeBufferToPointCloud(buffer, dracoGeometry);
|
|
618
|
+
break;
|
|
619
|
+
default:
|
|
620
|
+
throw new Error("DRACO: Unknown geometry type.");
|
|
621
|
+
}
|
|
622
|
+
if (!dracoStatus.ok() || !dracoGeometry.ptr) {
|
|
623
|
+
const message = `DRACO decompression failed: ${dracoStatus.error_msg()}`;
|
|
624
|
+
throw new Error(message);
|
|
625
|
+
}
|
|
626
|
+
const loaderData = this._getDracoLoaderData(dracoGeometry, geometry_type, options);
|
|
627
|
+
const geometry = this._getMeshData(dracoGeometry, loaderData, options);
|
|
628
|
+
const boundingBox = (0, import_schema_utils2.getMeshBoundingBox)(geometry.attributes);
|
|
629
|
+
const schema = getDracoSchema(geometry.attributes, loaderData, geometry.indices);
|
|
630
|
+
const data = {
|
|
631
|
+
loader: "draco",
|
|
632
|
+
loaderData,
|
|
633
|
+
header: {
|
|
634
|
+
vertexCount: dracoGeometry.num_points(),
|
|
635
|
+
boundingBox
|
|
636
|
+
},
|
|
637
|
+
...geometry,
|
|
638
|
+
schema
|
|
639
|
+
};
|
|
640
|
+
return data;
|
|
641
|
+
} finally {
|
|
642
|
+
this.draco.destroy(buffer);
|
|
643
|
+
if (dracoGeometry) {
|
|
644
|
+
this.draco.destroy(dracoGeometry);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
// Draco specific "loader data"
|
|
649
|
+
/**
|
|
650
|
+
* Extract
|
|
651
|
+
* @param dracoGeometry
|
|
652
|
+
* @param geometry_type
|
|
653
|
+
* @param options
|
|
654
|
+
* @returns
|
|
655
|
+
*/
|
|
656
|
+
_getDracoLoaderData(dracoGeometry, geometry_type, options) {
|
|
657
|
+
const metadata = this._getTopLevelMetadata(dracoGeometry);
|
|
658
|
+
const attributes = this._getDracoAttributes(dracoGeometry, options);
|
|
659
|
+
return {
|
|
660
|
+
geometry_type,
|
|
661
|
+
num_attributes: dracoGeometry.num_attributes(),
|
|
662
|
+
num_points: dracoGeometry.num_points(),
|
|
663
|
+
num_faces: dracoGeometry instanceof this.draco.Mesh ? dracoGeometry.num_faces() : 0,
|
|
664
|
+
metadata,
|
|
665
|
+
attributes
|
|
666
|
+
};
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* Extract all draco provided information and metadata for each attribute
|
|
670
|
+
* @param dracoGeometry
|
|
671
|
+
* @param options
|
|
672
|
+
* @returns
|
|
673
|
+
*/
|
|
674
|
+
_getDracoAttributes(dracoGeometry, options) {
|
|
675
|
+
const dracoAttributes = {};
|
|
676
|
+
for (let attributeId = 0; attributeId < dracoGeometry.num_attributes(); attributeId++) {
|
|
677
|
+
const dracoAttribute = this.decoder.GetAttribute(dracoGeometry, attributeId);
|
|
678
|
+
const metadata = this._getAttributeMetadata(dracoGeometry, attributeId);
|
|
679
|
+
dracoAttributes[dracoAttribute.unique_id()] = {
|
|
680
|
+
unique_id: dracoAttribute.unique_id(),
|
|
681
|
+
attribute_type: dracoAttribute.attribute_type(),
|
|
682
|
+
data_type: dracoAttribute.data_type(),
|
|
683
|
+
num_components: dracoAttribute.num_components(),
|
|
684
|
+
byte_offset: dracoAttribute.byte_offset(),
|
|
685
|
+
byte_stride: dracoAttribute.byte_stride(),
|
|
686
|
+
normalized: dracoAttribute.normalized(),
|
|
687
|
+
attribute_index: attributeId,
|
|
688
|
+
metadata
|
|
689
|
+
};
|
|
690
|
+
const quantization = this._getQuantizationTransform(dracoAttribute, options);
|
|
691
|
+
if (quantization) {
|
|
692
|
+
dracoAttributes[dracoAttribute.unique_id()].quantization_transform = quantization;
|
|
693
|
+
}
|
|
694
|
+
const octahedron = this._getOctahedronTransform(dracoAttribute, options);
|
|
695
|
+
if (octahedron) {
|
|
696
|
+
dracoAttributes[dracoAttribute.unique_id()].octahedron_transform = octahedron;
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
return dracoAttributes;
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Get standard loaders.gl mesh category data
|
|
703
|
+
* Extracts the geometry from draco
|
|
704
|
+
* @param dracoGeometry
|
|
705
|
+
* @param options
|
|
706
|
+
*/
|
|
707
|
+
_getMeshData(dracoGeometry, loaderData, options) {
|
|
708
|
+
const attributes = this._getMeshAttributes(loaderData, dracoGeometry, options);
|
|
709
|
+
const positionAttribute = attributes.POSITION;
|
|
710
|
+
if (!positionAttribute) {
|
|
711
|
+
throw new Error("DRACO: No position attribute found.");
|
|
712
|
+
}
|
|
713
|
+
if (dracoGeometry instanceof this.draco.Mesh) {
|
|
714
|
+
switch (options.topology) {
|
|
715
|
+
case "triangle-strip":
|
|
716
|
+
return {
|
|
717
|
+
topology: "triangle-strip",
|
|
718
|
+
// TODO - mode is wrong?
|
|
719
|
+
mode: 4,
|
|
720
|
+
// GL.TRIANGLES
|
|
721
|
+
attributes,
|
|
722
|
+
indices: {
|
|
723
|
+
value: this._getTriangleStripIndices(dracoGeometry),
|
|
724
|
+
size: 1
|
|
725
|
+
}
|
|
726
|
+
};
|
|
727
|
+
case "triangle-list":
|
|
728
|
+
default:
|
|
729
|
+
return {
|
|
730
|
+
topology: "triangle-list",
|
|
731
|
+
// TODO - mode is wrong?
|
|
732
|
+
mode: 5,
|
|
733
|
+
// GL.TRIANGLE_STRIP
|
|
734
|
+
attributes,
|
|
735
|
+
indices: {
|
|
736
|
+
value: this._getTriangleListIndices(dracoGeometry),
|
|
737
|
+
size: 1
|
|
738
|
+
}
|
|
739
|
+
};
|
|
740
|
+
}
|
|
666
741
|
}
|
|
742
|
+
return {
|
|
743
|
+
topology: "point-list",
|
|
744
|
+
mode: 0,
|
|
745
|
+
// GL.POINTS
|
|
746
|
+
attributes
|
|
747
|
+
};
|
|
667
748
|
}
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
749
|
+
_getMeshAttributes(loaderData, dracoGeometry, options) {
|
|
750
|
+
const attributes = {};
|
|
751
|
+
for (const loaderAttribute of Object.values(loaderData.attributes)) {
|
|
752
|
+
const attributeName = this._deduceAttributeName(loaderAttribute, options);
|
|
753
|
+
loaderAttribute.name = attributeName;
|
|
754
|
+
const values = this._getAttributeValues(dracoGeometry, loaderAttribute);
|
|
755
|
+
if (values) {
|
|
756
|
+
const { value, size } = values;
|
|
757
|
+
attributes[attributeName] = {
|
|
758
|
+
value,
|
|
759
|
+
size,
|
|
760
|
+
byteOffset: loaderAttribute.byte_offset,
|
|
761
|
+
byteStride: loaderAttribute.byte_stride,
|
|
762
|
+
normalized: loaderAttribute.normalized
|
|
763
|
+
};
|
|
764
|
+
}
|
|
683
765
|
}
|
|
684
766
|
return attributes;
|
|
685
767
|
}
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
const
|
|
768
|
+
// MESH INDICES EXTRACTION
|
|
769
|
+
/**
|
|
770
|
+
* For meshes, we need indices to define the faces.
|
|
771
|
+
* @param dracoGeometry
|
|
772
|
+
*/
|
|
773
|
+
_getTriangleListIndices(dracoGeometry) {
|
|
774
|
+
const numFaces = dracoGeometry.num_faces();
|
|
775
|
+
const numIndices = numFaces * 3;
|
|
776
|
+
const byteLength = numIndices * INDEX_ITEM_SIZE;
|
|
777
|
+
const ptr = this.draco._malloc(byteLength);
|
|
694
778
|
try {
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
throw new Error("Draco encoding failed.");
|
|
698
|
-
}
|
|
699
|
-
this.log(`DRACO encoded ${dracoPointCloud.num_points()} points
|
|
700
|
-
with ${dracoPointCloud.num_attributes()} attributes into ${encodedLen} bytes`);
|
|
701
|
-
return dracoInt8ArrayToArrayBuffer(dracoData);
|
|
779
|
+
this.decoder.GetTrianglesUInt32Array(dracoGeometry, byteLength, ptr);
|
|
780
|
+
return new Uint32Array(this.draco.HEAPF32.buffer, ptr, numIndices).slice();
|
|
702
781
|
} finally {
|
|
703
|
-
this.
|
|
704
|
-
this.destroyEncodedObject(dracoPointCloud);
|
|
782
|
+
this.draco._free(ptr);
|
|
705
783
|
}
|
|
706
784
|
}
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
const
|
|
713
|
-
this._createDracoMesh(dracoMesh, attributes, options);
|
|
714
|
-
const dracoData = new this.draco.DracoInt8Array();
|
|
785
|
+
/**
|
|
786
|
+
* For meshes, we need indices to define the faces.
|
|
787
|
+
* @param dracoGeometry
|
|
788
|
+
*/
|
|
789
|
+
_getTriangleStripIndices(dracoGeometry) {
|
|
790
|
+
const dracoArray = new this.draco.DracoInt32Array();
|
|
715
791
|
try {
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
throw new Error("Draco encoding failed.");
|
|
719
|
-
}
|
|
720
|
-
this.log(`DRACO encoded ${dracoMesh.num_points()} points
|
|
721
|
-
with ${dracoMesh.num_attributes()} attributes into ${encodedLen} bytes`);
|
|
722
|
-
return dracoInt8ArrayToArrayBuffer(dracoData);
|
|
792
|
+
this.decoder.GetTriangleStripsFromMesh(dracoGeometry, dracoArray);
|
|
793
|
+
return getUint32Array(dracoArray);
|
|
723
794
|
} finally {
|
|
724
|
-
this.
|
|
725
|
-
this.destroyEncodedObject(dracoMesh);
|
|
795
|
+
this.draco.destroy(dracoArray);
|
|
726
796
|
}
|
|
727
797
|
}
|
|
728
798
|
/**
|
|
729
|
-
*
|
|
730
|
-
* @param
|
|
799
|
+
*
|
|
800
|
+
* @param dracoGeometry
|
|
801
|
+
* @param dracoAttribute
|
|
802
|
+
* @param attributeName
|
|
731
803
|
*/
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
const dracoMethod = this.draco[options.method || "MESH_SEQUENTIAL_ENCODING"];
|
|
738
|
-
this.dracoEncoder.SetEncodingMethod(dracoMethod);
|
|
739
|
-
}
|
|
740
|
-
if ("quantization" in options) {
|
|
741
|
-
for (const attribute in options.quantization) {
|
|
742
|
-
const bits = options.quantization[attribute];
|
|
743
|
-
const dracoPosition = this.draco[attribute];
|
|
744
|
-
this.dracoEncoder.SetAttributeQuantization(dracoPosition, bits);
|
|
745
|
-
}
|
|
804
|
+
_getAttributeValues(dracoGeometry, attribute) {
|
|
805
|
+
const TypedArrayCtor = DRACO_DATA_TYPE_TO_TYPED_ARRAY_MAP[attribute.data_type];
|
|
806
|
+
if (!TypedArrayCtor) {
|
|
807
|
+
console.warn(`DRACO: Unsupported attribute type ${attribute.data_type}`);
|
|
808
|
+
return null;
|
|
746
809
|
}
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
const optionalMetadata = options.attributesMetadata || {};
|
|
810
|
+
const numComponents = attribute.num_components;
|
|
811
|
+
const numPoints = dracoGeometry.num_points();
|
|
812
|
+
const numValues = numPoints * numComponents;
|
|
813
|
+
const byteLength = numValues * TypedArrayCtor.BYTES_PER_ELEMENT;
|
|
814
|
+
const dataType = getDracoDataType(this.draco, TypedArrayCtor);
|
|
815
|
+
let value;
|
|
816
|
+
const ptr = this.draco._malloc(byteLength);
|
|
755
817
|
try {
|
|
756
|
-
const
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
for (let attributeName in attributes) {
|
|
762
|
-
const attribute = attributes[attributeName];
|
|
763
|
-
attributeName = GLTF_TO_DRACO_ATTRIBUTE_NAME_MAP[attributeName] || attributeName;
|
|
764
|
-
const uniqueId = this._addAttributeToMesh(dracoMesh, attributeName, attribute, vertexCount);
|
|
765
|
-
if (uniqueId !== -1) {
|
|
766
|
-
this._addAttributeMetadata(dracoMesh, uniqueId, {
|
|
767
|
-
name: attributeName,
|
|
768
|
-
...optionalMetadata[attributeName] || {}
|
|
769
|
-
});
|
|
770
|
-
}
|
|
771
|
-
}
|
|
772
|
-
} catch (error) {
|
|
773
|
-
this.destroyEncodedObject(dracoMesh);
|
|
774
|
-
throw error;
|
|
818
|
+
const dracoAttribute = this.decoder.GetAttribute(dracoGeometry, attribute.attribute_index);
|
|
819
|
+
this.decoder.GetAttributeDataArrayForAllPoints(dracoGeometry, dracoAttribute, dataType, byteLength, ptr);
|
|
820
|
+
value = new TypedArrayCtor(this.draco.HEAPF32.buffer, ptr, numValues).slice();
|
|
821
|
+
} finally {
|
|
822
|
+
this.draco._free(ptr);
|
|
775
823
|
}
|
|
776
|
-
return
|
|
824
|
+
return { value, size: numComponents };
|
|
777
825
|
}
|
|
826
|
+
// Attribute names
|
|
778
827
|
/**
|
|
779
|
-
*
|
|
780
|
-
*
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
for (let attributeName in attributes) {
|
|
791
|
-
const attribute = attributes[attributeName];
|
|
792
|
-
attributeName = GLTF_TO_DRACO_ATTRIBUTE_NAME_MAP[attributeName] || attributeName;
|
|
793
|
-
const uniqueId = this._addAttributeToMesh(dracoPointCloud, attributeName, attribute, vertexCount);
|
|
794
|
-
if (uniqueId !== -1) {
|
|
795
|
-
this._addAttributeMetadata(dracoPointCloud, uniqueId, {
|
|
796
|
-
name: attributeName,
|
|
797
|
-
...optionalMetadata[attributeName] || {}
|
|
798
|
-
});
|
|
799
|
-
}
|
|
800
|
-
}
|
|
801
|
-
} catch (error) {
|
|
802
|
-
this.destroyEncodedObject(dracoPointCloud);
|
|
803
|
-
throw error;
|
|
828
|
+
* DRACO does not store attribute names - We need to deduce an attribute name
|
|
829
|
+
* for each attribute
|
|
830
|
+
_getAttributeNames(
|
|
831
|
+
dracoGeometry: Mesh | PointCloud,
|
|
832
|
+
options: DracoParseOptions
|
|
833
|
+
): {[unique_id: number]: string} {
|
|
834
|
+
const attributeNames: {[unique_id: number]: string} = {};
|
|
835
|
+
for (let attributeId = 0; attributeId < dracoGeometry.num_attributes(); attributeId++) {
|
|
836
|
+
const dracoAttribute = this.decoder.GetAttribute(dracoGeometry, attributeId);
|
|
837
|
+
const attributeName = this._deduceAttributeName(dracoAttribute, options);
|
|
838
|
+
attributeNames[attributeName] = attributeName;
|
|
804
839
|
}
|
|
805
|
-
return
|
|
840
|
+
return attributeNames;
|
|
806
841
|
}
|
|
842
|
+
*/
|
|
807
843
|
/**
|
|
808
|
-
*
|
|
809
|
-
* @
|
|
810
|
-
*
|
|
811
|
-
*
|
|
844
|
+
* Deduce an attribute name.
|
|
845
|
+
* @note DRACO does not save attribute names, just general type (POSITION, COLOR)
|
|
846
|
+
* to help optimize compression. We generate GLTF compatible names for the Draco-recognized
|
|
847
|
+
* types
|
|
848
|
+
* @param attributeData
|
|
812
849
|
*/
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
850
|
+
_deduceAttributeName(attribute, options) {
|
|
851
|
+
const uniqueId = attribute.unique_id;
|
|
852
|
+
for (const [attributeName, attributeUniqueId] of Object.entries(options.extraAttributes || {})) {
|
|
853
|
+
if (attributeUniqueId === uniqueId) {
|
|
854
|
+
return attributeName;
|
|
855
|
+
}
|
|
816
856
|
}
|
|
817
|
-
const
|
|
818
|
-
const
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
return -1;
|
|
857
|
+
const thisAttributeType = attribute.attribute_type;
|
|
858
|
+
for (const dracoAttributeConstant in DRACO_TO_GLTF_ATTRIBUTE_NAME_MAP) {
|
|
859
|
+
const attributeType = this.draco[dracoAttributeConstant];
|
|
860
|
+
if (attributeType === thisAttributeType) {
|
|
861
|
+
return DRACO_TO_GLTF_ATTRIBUTE_NAME_MAP[dracoAttributeConstant];
|
|
862
|
+
}
|
|
824
863
|
}
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
switch (attribute.constructor) {
|
|
829
|
-
case Int8Array:
|
|
830
|
-
return builder.AddInt8Attribute(mesh, type, vertexCount, size, new Int8Array(buffer));
|
|
831
|
-
case Int16Array:
|
|
832
|
-
return builder.AddInt16Attribute(mesh, type, vertexCount, size, new Int16Array(buffer));
|
|
833
|
-
case Int32Array:
|
|
834
|
-
return builder.AddInt32Attribute(mesh, type, vertexCount, size, new Int32Array(buffer));
|
|
835
|
-
case Uint8Array:
|
|
836
|
-
case Uint8ClampedArray:
|
|
837
|
-
return builder.AddUInt8Attribute(mesh, type, vertexCount, size, new Uint8Array(buffer));
|
|
838
|
-
case Uint16Array:
|
|
839
|
-
return builder.AddUInt16Attribute(mesh, type, vertexCount, size, new Uint16Array(buffer));
|
|
840
|
-
case Uint32Array:
|
|
841
|
-
return builder.AddUInt32Attribute(mesh, type, vertexCount, size, new Uint32Array(buffer));
|
|
842
|
-
case Float32Array:
|
|
843
|
-
return builder.AddFloatAttribute(mesh, type, vertexCount, size, new Float32Array(buffer));
|
|
844
|
-
default:
|
|
845
|
-
console.warn("Unsupported attribute type", attribute);
|
|
846
|
-
return -1;
|
|
864
|
+
const entryName = options.attributeNameEntry || "name";
|
|
865
|
+
if (attribute.metadata[entryName]) {
|
|
866
|
+
return attribute.metadata[entryName].string;
|
|
847
867
|
}
|
|
868
|
+
return `CUSTOM_ATTRIBUTE_${uniqueId}`;
|
|
869
|
+
}
|
|
870
|
+
// METADATA EXTRACTION
|
|
871
|
+
/** Get top level metadata */
|
|
872
|
+
_getTopLevelMetadata(dracoGeometry) {
|
|
873
|
+
const dracoMetadata = this.decoder.GetMetadata(dracoGeometry);
|
|
874
|
+
return this._getDracoMetadata(dracoMetadata);
|
|
875
|
+
}
|
|
876
|
+
/** Get per attribute metadata */
|
|
877
|
+
_getAttributeMetadata(dracoGeometry, attributeId) {
|
|
878
|
+
const dracoMetadata = this.decoder.GetAttributeMetadata(dracoGeometry, attributeId);
|
|
879
|
+
return this._getDracoMetadata(dracoMetadata);
|
|
848
880
|
}
|
|
849
881
|
/**
|
|
850
|
-
*
|
|
851
|
-
*
|
|
852
|
-
* @
|
|
882
|
+
* Extract metadata field values
|
|
883
|
+
* @param dracoMetadata
|
|
884
|
+
* @returns
|
|
853
885
|
*/
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
return "indices";
|
|
858
|
-
case "position":
|
|
859
|
-
case "positions":
|
|
860
|
-
case "vertices":
|
|
861
|
-
return this.draco.POSITION;
|
|
862
|
-
case "normal":
|
|
863
|
-
case "normals":
|
|
864
|
-
return this.draco.NORMAL;
|
|
865
|
-
case "color":
|
|
866
|
-
case "colors":
|
|
867
|
-
return this.draco.COLOR;
|
|
868
|
-
case "texcoord":
|
|
869
|
-
case "texcoords":
|
|
870
|
-
return this.draco.TEX_COORD;
|
|
871
|
-
default:
|
|
872
|
-
return this.draco.GENERIC;
|
|
886
|
+
_getDracoMetadata(dracoMetadata) {
|
|
887
|
+
if (!dracoMetadata || !dracoMetadata.ptr) {
|
|
888
|
+
return {};
|
|
873
889
|
}
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
for (
|
|
877
|
-
const
|
|
878
|
-
|
|
879
|
-
if (dracoType === this.draco.POSITION) {
|
|
880
|
-
return attribute;
|
|
881
|
-
}
|
|
890
|
+
const result = {};
|
|
891
|
+
const numEntries = this.metadataQuerier.NumEntries(dracoMetadata);
|
|
892
|
+
for (let entryIndex = 0; entryIndex < numEntries; entryIndex++) {
|
|
893
|
+
const entryName = this.metadataQuerier.GetEntryName(dracoMetadata, entryIndex);
|
|
894
|
+
result[entryName] = this._getDracoMetadataField(dracoMetadata, entryName);
|
|
882
895
|
}
|
|
883
|
-
return
|
|
896
|
+
return result;
|
|
884
897
|
}
|
|
885
898
|
/**
|
|
886
|
-
*
|
|
887
|
-
* @param
|
|
888
|
-
* @param
|
|
899
|
+
* Extracts possible values for one metadata entry by name
|
|
900
|
+
* @param dracoMetadata
|
|
901
|
+
* @param entryName
|
|
889
902
|
*/
|
|
890
|
-
|
|
891
|
-
const
|
|
892
|
-
|
|
893
|
-
|
|
903
|
+
_getDracoMetadataField(dracoMetadata, entryName) {
|
|
904
|
+
const dracoArray = new this.draco.DracoInt32Array();
|
|
905
|
+
try {
|
|
906
|
+
this.metadataQuerier.GetIntEntryArray(dracoMetadata, entryName, dracoArray);
|
|
907
|
+
const intArray = getInt32Array(dracoArray);
|
|
908
|
+
return {
|
|
909
|
+
int: this.metadataQuerier.GetIntEntry(dracoMetadata, entryName),
|
|
910
|
+
string: this.metadataQuerier.GetStringEntry(dracoMetadata, entryName),
|
|
911
|
+
double: this.metadataQuerier.GetDoubleEntry(dracoMetadata, entryName),
|
|
912
|
+
intArray
|
|
913
|
+
};
|
|
914
|
+
} finally {
|
|
915
|
+
this.draco.destroy(dracoArray);
|
|
916
|
+
}
|
|
894
917
|
}
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
this._populateDracoMetadata(dracoAttributeMetadata, metadata);
|
|
904
|
-
this.dracoMeshBuilder.SetMetadataForAttribute(dracoGeometry, uniqueAttributeId, dracoAttributeMetadata);
|
|
918
|
+
// QUANTIZED ATTRIBUTE SUPPORT (NO DECOMPRESSION)
|
|
919
|
+
/** Skip transforms for specific attribute types */
|
|
920
|
+
_disableAttributeTransforms(options) {
|
|
921
|
+
const { quantizedAttributes = [], octahedronAttributes = [] } = options;
|
|
922
|
+
const skipAttributes = [...quantizedAttributes, ...octahedronAttributes];
|
|
923
|
+
for (const dracoAttributeName of skipAttributes) {
|
|
924
|
+
this.decoder.SkipAttributeTransform(this.draco[dracoAttributeName]);
|
|
925
|
+
}
|
|
905
926
|
}
|
|
906
927
|
/**
|
|
907
|
-
*
|
|
908
|
-
* @
|
|
909
|
-
* @param metadata
|
|
928
|
+
* Extract (and apply?) Position Transform
|
|
929
|
+
* @todo not used
|
|
910
930
|
*/
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
931
|
+
_getQuantizationTransform(dracoAttribute, options) {
|
|
932
|
+
const { quantizedAttributes = [] } = options;
|
|
933
|
+
const attribute_type = dracoAttribute.attribute_type();
|
|
934
|
+
const skip = quantizedAttributes.map((type) => this.decoder[type]).includes(attribute_type);
|
|
935
|
+
if (skip) {
|
|
936
|
+
const transform = new this.draco.AttributeQuantizationTransform();
|
|
937
|
+
try {
|
|
938
|
+
if (transform.InitFromAttribute(dracoAttribute)) {
|
|
939
|
+
return {
|
|
940
|
+
quantization_bits: transform.quantization_bits(),
|
|
941
|
+
range: transform.range(),
|
|
942
|
+
min_values: new Float32Array([1, 2, 3]).map((i) => transform.min_value(i))
|
|
943
|
+
};
|
|
944
|
+
}
|
|
945
|
+
} finally {
|
|
946
|
+
this.draco.destroy(transform);
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
return null;
|
|
950
|
+
}
|
|
951
|
+
_getOctahedronTransform(dracoAttribute, options) {
|
|
952
|
+
const { octahedronAttributes = [] } = options;
|
|
953
|
+
const attribute_type = dracoAttribute.attribute_type();
|
|
954
|
+
const octahedron = octahedronAttributes.map((type) => this.decoder[type]).includes(attribute_type);
|
|
955
|
+
if (octahedron) {
|
|
956
|
+
const transform = new this.draco.AttributeQuantizationTransform();
|
|
957
|
+
try {
|
|
958
|
+
if (transform.InitFromAttribute(dracoAttribute)) {
|
|
959
|
+
return {
|
|
960
|
+
quantization_bits: transform.quantization_bits()
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
} finally {
|
|
964
|
+
this.draco.destroy(transform);
|
|
929
965
|
}
|
|
930
966
|
}
|
|
967
|
+
return null;
|
|
931
968
|
}
|
|
932
969
|
};
|
|
933
|
-
function
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
970
|
+
function getDracoDataType(draco, attributeType) {
|
|
971
|
+
switch (attributeType) {
|
|
972
|
+
case Float32Array:
|
|
973
|
+
return draco.DT_FLOAT32;
|
|
974
|
+
case Int8Array:
|
|
975
|
+
return draco.DT_INT8;
|
|
976
|
+
case Int16Array:
|
|
977
|
+
return draco.DT_INT16;
|
|
978
|
+
case Int32Array:
|
|
979
|
+
return draco.DT_INT32;
|
|
980
|
+
case Uint8Array:
|
|
981
|
+
return draco.DT_UINT8;
|
|
982
|
+
case Uint16Array:
|
|
983
|
+
return draco.DT_UINT16;
|
|
984
|
+
case Uint32Array:
|
|
985
|
+
return draco.DT_UINT32;
|
|
986
|
+
default:
|
|
987
|
+
return draco.DT_INVALID;
|
|
939
988
|
}
|
|
940
|
-
return outputBuffer;
|
|
941
989
|
}
|
|
942
|
-
function
|
|
943
|
-
const
|
|
944
|
-
|
|
990
|
+
function getInt32Array(dracoArray) {
|
|
991
|
+
const numValues = dracoArray.size();
|
|
992
|
+
const intArray = new Int32Array(numValues);
|
|
993
|
+
for (let i = 0; i < numValues; i++) {
|
|
994
|
+
intArray[i] = dracoArray.GetValue(i);
|
|
995
|
+
}
|
|
996
|
+
return intArray;
|
|
945
997
|
}
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
attributeNameEntry: "name"
|
|
952
|
-
// Draco Compression Parameters
|
|
953
|
-
// method: 'MESH_EDGEBREAKER_ENCODING', // Use draco defaults
|
|
954
|
-
// speed: [5, 5], // Use draco defaults
|
|
955
|
-
// quantization: { // Use draco defaults
|
|
956
|
-
// POSITION: 10
|
|
957
|
-
// }
|
|
958
|
-
};
|
|
959
|
-
var DracoWriter = {
|
|
960
|
-
name: "DRACO",
|
|
961
|
-
id: "draco",
|
|
962
|
-
module: "draco",
|
|
963
|
-
version: VERSION,
|
|
964
|
-
extensions: ["drc"],
|
|
965
|
-
options: {
|
|
966
|
-
draco: DEFAULT_DRACO_WRITER_OPTIONS
|
|
967
|
-
},
|
|
968
|
-
encode
|
|
969
|
-
};
|
|
970
|
-
async function encode(data, options = {}) {
|
|
971
|
-
const { draco } = await loadDracoEncoderModule(options);
|
|
972
|
-
const dracoBuilder = new DracoBuilder(draco);
|
|
973
|
-
try {
|
|
974
|
-
return dracoBuilder.encodeSync(data, options.draco);
|
|
975
|
-
} finally {
|
|
976
|
-
dracoBuilder.destroy();
|
|
998
|
+
function getUint32Array(dracoArray) {
|
|
999
|
+
const numValues = dracoArray.size();
|
|
1000
|
+
const intArray = new Int32Array(numValues);
|
|
1001
|
+
for (let i = 0; i < numValues; i++) {
|
|
1002
|
+
intArray[i] = dracoArray.GetValue(i);
|
|
977
1003
|
}
|
|
1004
|
+
return intArray;
|
|
978
1005
|
}
|
|
979
1006
|
|
|
980
|
-
// dist/
|
|
981
|
-
var
|
|
982
|
-
|
|
983
|
-
|
|
1007
|
+
// dist/draco-loader.js
|
|
1008
|
+
var DracoWorkerLoader = {
|
|
1009
|
+
dataType: null,
|
|
1010
|
+
batchType: null,
|
|
1011
|
+
name: "Draco",
|
|
1012
|
+
id: "draco",
|
|
984
1013
|
module: "draco",
|
|
1014
|
+
// shapes: ['mesh'],
|
|
985
1015
|
version: VERSION,
|
|
986
1016
|
worker: true,
|
|
1017
|
+
extensions: ["drc"],
|
|
1018
|
+
mimeTypes: ["application/octet-stream"],
|
|
1019
|
+
binary: true,
|
|
1020
|
+
tests: ["DRACO"],
|
|
987
1021
|
options: {
|
|
988
|
-
draco: {
|
|
989
|
-
|
|
1022
|
+
draco: {
|
|
1023
|
+
decoderType: typeof WebAssembly === "object" ? "wasm" : "js",
|
|
1024
|
+
// 'js' for IE11
|
|
1025
|
+
libraryPath: "libs/",
|
|
1026
|
+
extraAttributes: {},
|
|
1027
|
+
attributeNameEntry: void 0
|
|
1028
|
+
}
|
|
990
1029
|
}
|
|
991
1030
|
};
|
|
992
|
-
var
|
|
993
|
-
...
|
|
1031
|
+
var DracoLoader = {
|
|
1032
|
+
...DracoWorkerLoader,
|
|
994
1033
|
parse
|
|
995
1034
|
};
|
|
996
1035
|
async function parse(arrayBuffer, options) {
|
|
997
|
-
|
|
1036
|
+
var _a;
|
|
1037
|
+
const { draco } = await loadDracoDecoderModule(options == null ? void 0 : options.core, ((_a = options == null ? void 0 : options.draco) == null ? void 0 : _a.decoderType) || "wasm");
|
|
998
1038
|
const dracoParser = new DracoParser(draco);
|
|
999
1039
|
try {
|
|
1000
1040
|
return dracoParser.parseSync(arrayBuffer, options == null ? void 0 : options.draco);
|
|
@@ -1002,4 +1042,18 @@ async function parse(arrayBuffer, options) {
|
|
|
1002
1042
|
dracoParser.destroy();
|
|
1003
1043
|
}
|
|
1004
1044
|
}
|
|
1045
|
+
|
|
1046
|
+
// dist/draco-arrow-loader.js
|
|
1047
|
+
var import_schema_utils3 = require("@loaders.gl/schema-utils");
|
|
1048
|
+
var DracoArrowLoader = {
|
|
1049
|
+
...DracoLoader,
|
|
1050
|
+
dataType: null,
|
|
1051
|
+
worker: false,
|
|
1052
|
+
parse: parse2
|
|
1053
|
+
};
|
|
1054
|
+
async function parse2(arrayBuffer, options) {
|
|
1055
|
+
const mesh = await DracoLoader.parse(arrayBuffer, options);
|
|
1056
|
+
const arrowTable = (0, import_schema_utils3.convertMeshToTable)(mesh, "arrow-table");
|
|
1057
|
+
return arrowTable;
|
|
1058
|
+
}
|
|
1005
1059
|
//# sourceMappingURL=index.cjs.map
|