@babylonjs/serializers 5.20.0 → 5.22.1
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/OBJ/objSerializer.js +35 -39
- package/OBJ/objSerializer.js.map +1 -1
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.js +44 -52
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_lights_punctual.js +49 -56
- package/glTF/2.0/Extensions/KHR_lights_punctual.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_clearcoat.js +31 -38
- package/glTF/2.0/Extensions/KHR_materials_clearcoat.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_ior.js +18 -25
- package/glTF/2.0/Extensions/KHR_materials_ior.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_iridescence.js +25 -32
- package/glTF/2.0/Extensions/KHR_materials_iridescence.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_sheen.js +24 -32
- package/glTF/2.0/Extensions/KHR_materials_sheen.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_specular.js +29 -37
- package/glTF/2.0/Extensions/KHR_materials_specular.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_transmission.js +29 -37
- package/glTF/2.0/Extensions/KHR_materials_transmission.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_unlit.js +15 -22
- package/glTF/2.0/Extensions/KHR_materials_unlit.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_volume.js +31 -39
- package/glTF/2.0/Extensions/KHR_materials_volume.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_texture_transform.js +33 -42
- package/glTF/2.0/Extensions/KHR_texture_transform.js.map +1 -1
- package/glTF/2.0/glTFAnimation.js +171 -187
- package/glTF/2.0/glTFAnimation.js.map +1 -1
- package/glTF/2.0/glTFData.js +9 -11
- package/glTF/2.0/glTFData.js.map +1 -1
- package/glTF/2.0/glTFExporter.js +498 -544
- package/glTF/2.0/glTFExporter.js.map +1 -1
- package/glTF/2.0/glTFMaterialExporter.js +385 -423
- package/glTF/2.0/glTFMaterialExporter.js.map +1 -1
- package/glTF/2.0/glTFSerializer.js +20 -25
- package/glTF/2.0/glTFSerializer.js.map +1 -1
- package/glTF/2.0/glTFUtilities.js +45 -49
- package/glTF/2.0/glTFUtilities.js.map +1 -1
- package/glTF/2.0/shaders/textureTransform.fragment.js +7 -3
- package/glTF/2.0/shaders/textureTransform.fragment.js.map +1 -1
- package/legacy/legacy-glTF2Serializer.js +16 -16
- package/legacy/legacy-glTF2Serializer.js.map +1 -1
- package/legacy/legacy-objSerializer.js +2 -2
- package/legacy/legacy-objSerializer.js.map +1 -1
- package/legacy/legacy-stlSerializer.js +2 -2
- package/legacy/legacy-stlSerializer.js.map +1 -1
- package/package.json +5 -8
- package/stl/stlSerializer.js +29 -38
- package/stl/stlSerializer.js.map +1 -1
package/glTF/2.0/glTFExporter.js
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
import { __spreadArray } from "tslib";
|
2
1
|
import { Vector2, Vector3, Vector4, Quaternion } from "@babylonjs/core/Maths/math.vector.js";
|
3
2
|
import { Color3, Color4 } from "@babylonjs/core/Maths/math.color.js";
|
4
3
|
import { Tools } from "@babylonjs/core/Misc/tools.js";
|
@@ -20,20 +19,20 @@ import { MultiMaterial } from "@babylonjs/core/Materials/multiMaterial.js";
|
|
20
19
|
* Converts Babylon Scene into glTF 2.0.
|
21
20
|
* @hidden
|
22
21
|
*/
|
23
|
-
|
22
|
+
export class _Exporter {
|
24
23
|
/**
|
25
24
|
* Creates a glTF Exporter instance, which can accept optional exporter options
|
26
25
|
* @param babylonScene Babylon scene object
|
27
26
|
* @param options Options to modify the behavior of the exporter
|
28
27
|
*/
|
29
|
-
|
28
|
+
constructor(babylonScene, options) {
|
30
29
|
/*
|
31
30
|
* Specifies if root Babylon empty nodes that act as a coordinate space transform should be included in export
|
32
31
|
*/
|
33
32
|
this._includeCoordinateSystemConversionNodes = false;
|
34
33
|
this._extensions = {};
|
35
34
|
this._glTF = {
|
36
|
-
asset: { generator:
|
35
|
+
asset: { generator: `Babylon.js v${Engine.Version}`, version: "2.0" },
|
37
36
|
};
|
38
37
|
babylonScene = babylonScene || EngineStore.LastCreatedScene;
|
39
38
|
if (!babylonScene) {
|
@@ -61,162 +60,151 @@ var _Exporter = /** @class */ (function () {
|
|
61
60
|
this._glTFMaterialExporter = new _GLTFMaterialExporter(this);
|
62
61
|
this._loadExtensions();
|
63
62
|
}
|
64
|
-
|
65
|
-
var _this = this;
|
63
|
+
_applyExtension(node, extensions, index, actionAsync) {
|
66
64
|
if (index >= extensions.length) {
|
67
65
|
return Promise.resolve(node);
|
68
66
|
}
|
69
|
-
|
67
|
+
const currentPromise = actionAsync(extensions[index], node);
|
70
68
|
if (!currentPromise) {
|
71
69
|
return this._applyExtension(node, extensions, index + 1, actionAsync);
|
72
70
|
}
|
73
|
-
return currentPromise.then(
|
74
|
-
}
|
75
|
-
|
76
|
-
|
77
|
-
for (
|
78
|
-
|
79
|
-
extensions.push(this._extensions[name_1]);
|
71
|
+
return currentPromise.then((newNode) => this._applyExtension(newNode, extensions, index + 1, actionAsync));
|
72
|
+
}
|
73
|
+
_applyExtensions(node, actionAsync) {
|
74
|
+
const extensions = [];
|
75
|
+
for (const name of _Exporter._ExtensionNames) {
|
76
|
+
extensions.push(this._extensions[name]);
|
80
77
|
}
|
81
78
|
return this._applyExtension(node, extensions, 0, actionAsync);
|
82
|
-
}
|
83
|
-
|
84
|
-
return this._applyExtensions(babylonTexture,
|
85
|
-
}
|
86
|
-
|
87
|
-
return this._applyExtensions(meshPrimitive,
|
88
|
-
}
|
89
|
-
|
90
|
-
return this._applyExtensions(node,
|
91
|
-
}
|
92
|
-
|
93
|
-
return this._applyExtensions(material,
|
94
|
-
}
|
95
|
-
|
96
|
-
|
97
|
-
for (
|
98
|
-
|
99
|
-
var extension = this._extensions[name_2];
|
79
|
+
}
|
80
|
+
_extensionsPreExportTextureAsync(context, babylonTexture, mimeType) {
|
81
|
+
return this._applyExtensions(babylonTexture, (extension, node) => extension.preExportTextureAsync && extension.preExportTextureAsync(context, node, mimeType));
|
82
|
+
}
|
83
|
+
_extensionsPostExportMeshPrimitiveAsync(context, meshPrimitive, babylonSubMesh, binaryWriter) {
|
84
|
+
return this._applyExtensions(meshPrimitive, (extension, node) => extension.postExportMeshPrimitiveAsync && extension.postExportMeshPrimitiveAsync(context, node, babylonSubMesh, binaryWriter));
|
85
|
+
}
|
86
|
+
_extensionsPostExportNodeAsync(context, node, babylonNode, nodeMap, binaryWriter) {
|
87
|
+
return this._applyExtensions(node, (extension, node) => extension.postExportNodeAsync && extension.postExportNodeAsync(context, node, babylonNode, nodeMap, binaryWriter));
|
88
|
+
}
|
89
|
+
_extensionsPostExportMaterialAsync(context, material, babylonMaterial) {
|
90
|
+
return this._applyExtensions(material, (extension, node) => extension.postExportMaterialAsync && extension.postExportMaterialAsync(context, node, babylonMaterial));
|
91
|
+
}
|
92
|
+
_extensionsPostExportMaterialAdditionalTextures(context, material, babylonMaterial) {
|
93
|
+
const output = [];
|
94
|
+
for (const name of _Exporter._ExtensionNames) {
|
95
|
+
const extension = this._extensions[name];
|
100
96
|
if (extension.postExportMaterialAdditionalTextures) {
|
101
|
-
output.push
|
97
|
+
output.push(...extension.postExportMaterialAdditionalTextures(context, material, babylonMaterial));
|
102
98
|
}
|
103
99
|
}
|
104
100
|
return output;
|
105
|
-
}
|
106
|
-
|
107
|
-
for (
|
108
|
-
|
109
|
-
var extension = this._extensions[name_3];
|
101
|
+
}
|
102
|
+
_extensionsPostExportTextures(context, textureInfo, babylonTexture) {
|
103
|
+
for (const name of _Exporter._ExtensionNames) {
|
104
|
+
const extension = this._extensions[name];
|
110
105
|
if (extension.postExportTexture) {
|
111
106
|
extension.postExportTexture(context, textureInfo, babylonTexture);
|
112
107
|
}
|
113
108
|
}
|
114
|
-
}
|
115
|
-
|
116
|
-
for (
|
117
|
-
|
118
|
-
var extension = this._extensions[name_4];
|
109
|
+
}
|
110
|
+
_forEachExtensions(action) {
|
111
|
+
for (const name of _Exporter._ExtensionNames) {
|
112
|
+
const extension = this._extensions[name];
|
119
113
|
if (extension.enabled) {
|
120
114
|
action(extension);
|
121
115
|
}
|
122
116
|
}
|
123
|
-
}
|
124
|
-
|
125
|
-
|
126
|
-
this._forEachExtensions(function (extension) {
|
117
|
+
}
|
118
|
+
_extensionsOnExporting() {
|
119
|
+
this._forEachExtensions((extension) => {
|
127
120
|
if (extension.wasUsed) {
|
128
|
-
if (
|
129
|
-
|
121
|
+
if (this._glTF.extensionsUsed == null) {
|
122
|
+
this._glTF.extensionsUsed = [];
|
130
123
|
}
|
131
|
-
if (
|
132
|
-
|
124
|
+
if (this._glTF.extensionsUsed.indexOf(extension.name) === -1) {
|
125
|
+
this._glTF.extensionsUsed.push(extension.name);
|
133
126
|
}
|
134
127
|
if (extension.required) {
|
135
|
-
if (
|
136
|
-
|
128
|
+
if (this._glTF.extensionsRequired == null) {
|
129
|
+
this._glTF.extensionsRequired = [];
|
137
130
|
}
|
138
|
-
if (
|
139
|
-
|
131
|
+
if (this._glTF.extensionsRequired.indexOf(extension.name) === -1) {
|
132
|
+
this._glTF.extensionsRequired.push(extension.name);
|
140
133
|
}
|
141
134
|
}
|
142
|
-
if (
|
143
|
-
|
135
|
+
if (this._glTF.extensions == null) {
|
136
|
+
this._glTF.extensions = {};
|
144
137
|
}
|
145
138
|
if (extension.onExporting) {
|
146
139
|
extension.onExporting();
|
147
140
|
}
|
148
141
|
}
|
149
142
|
});
|
150
|
-
}
|
143
|
+
}
|
151
144
|
/**
|
152
145
|
* Load glTF serializer extensions
|
153
146
|
*/
|
154
|
-
|
155
|
-
for (
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
var extension = this._extensions[extensionKey];
|
147
|
+
_loadExtensions() {
|
148
|
+
for (const name of _Exporter._ExtensionNames) {
|
149
|
+
const extension = _Exporter._ExtensionFactories[name](this);
|
150
|
+
this._extensions[name] = extension;
|
151
|
+
}
|
152
|
+
}
|
153
|
+
dispose() {
|
154
|
+
for (const extensionKey in this._extensions) {
|
155
|
+
const extension = this._extensions[extensionKey];
|
164
156
|
extension.dispose();
|
165
157
|
}
|
166
|
-
}
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
},
|
171
|
-
enumerable: false,
|
172
|
-
configurable: true
|
173
|
-
});
|
158
|
+
}
|
159
|
+
get options() {
|
160
|
+
return this._options;
|
161
|
+
}
|
174
162
|
/**
|
175
163
|
* Registers a glTF exporter extension
|
176
164
|
* @param name Name of the extension to export
|
177
165
|
* @param factory The factory function that creates the exporter extension
|
178
166
|
*/
|
179
|
-
|
167
|
+
static RegisterExtension(name, factory) {
|
180
168
|
if (_Exporter.UnregisterExtension(name)) {
|
181
|
-
Tools.Warn(
|
169
|
+
Tools.Warn(`Extension with the name ${name} already exists`);
|
182
170
|
}
|
183
171
|
_Exporter._ExtensionFactories[name] = factory;
|
184
172
|
_Exporter._ExtensionNames.push(name);
|
185
|
-
}
|
173
|
+
}
|
186
174
|
/**
|
187
175
|
* Un-registers an exporter extension
|
188
176
|
* @param name The name fo the exporter extension
|
189
177
|
* @returns A boolean indicating whether the extension has been un-registered
|
190
178
|
*/
|
191
|
-
|
179
|
+
static UnregisterExtension(name) {
|
192
180
|
if (!_Exporter._ExtensionFactories[name]) {
|
193
181
|
return false;
|
194
182
|
}
|
195
183
|
delete _Exporter._ExtensionFactories[name];
|
196
|
-
|
184
|
+
const index = _Exporter._ExtensionNames.indexOf(name);
|
197
185
|
if (index !== -1) {
|
198
186
|
_Exporter._ExtensionNames.splice(index, 1);
|
199
187
|
}
|
200
188
|
return true;
|
201
|
-
}
|
202
|
-
|
189
|
+
}
|
190
|
+
_reorderIndicesBasedOnPrimitiveMode(submesh, primitiveMode, babylonIndices, byteOffset, binaryWriter) {
|
203
191
|
switch (primitiveMode) {
|
204
192
|
case Material.TriangleFillMode: {
|
205
193
|
if (!byteOffset) {
|
206
194
|
byteOffset = 0;
|
207
195
|
}
|
208
|
-
for (
|
209
|
-
|
196
|
+
for (let i = submesh.indexStart, length = submesh.indexStart + submesh.indexCount; i < length; i = i + 3) {
|
197
|
+
const index = byteOffset + i * 4;
|
210
198
|
// swap the second and third indices
|
211
|
-
|
212
|
-
|
199
|
+
const secondIndex = binaryWriter.getUInt32(index + 4);
|
200
|
+
const thirdIndex = binaryWriter.getUInt32(index + 8);
|
213
201
|
binaryWriter.setUInt32(thirdIndex, index + 4);
|
214
202
|
binaryWriter.setUInt32(secondIndex, index + 8);
|
215
203
|
}
|
216
204
|
break;
|
217
205
|
}
|
218
206
|
case Material.TriangleFanDrawMode: {
|
219
|
-
for (
|
207
|
+
for (let i = submesh.indexStart + submesh.indexCount - 1, start = submesh.indexStart; i >= start; --i) {
|
220
208
|
binaryWriter.setUInt32(babylonIndices[i], byteOffset);
|
221
209
|
byteOffset += 4;
|
222
210
|
}
|
@@ -230,7 +218,7 @@ var _Exporter = /** @class */ (function () {
|
|
230
218
|
break;
|
231
219
|
}
|
232
220
|
}
|
233
|
-
}
|
221
|
+
}
|
234
222
|
/**
|
235
223
|
* Reorders the vertex attribute data based on the primitive mode. This is necessary when indices are not available and the winding order is
|
236
224
|
* clock-wise during export to glTF
|
@@ -243,7 +231,7 @@ var _Exporter = /** @class */ (function () {
|
|
243
231
|
* @param binaryWriter The binary data for the glTF file
|
244
232
|
* @param convertToRightHandedSystem Converts the values to right-handed
|
245
233
|
*/
|
246
|
-
|
234
|
+
_reorderVertexAttributeDataBasedOnPrimitiveMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem) {
|
247
235
|
if (convertToRightHandedSystem && sideOrientation === Material.ClockWiseSideOrientation) {
|
248
236
|
switch (primitiveMode) {
|
249
237
|
case Material.TriangleFillMode: {
|
@@ -260,7 +248,7 @@ var _Exporter = /** @class */ (function () {
|
|
260
248
|
}
|
261
249
|
}
|
262
250
|
}
|
263
|
-
}
|
251
|
+
}
|
264
252
|
/**
|
265
253
|
* Reorders the vertex attributes in the correct triangle mode order . This is necessary when indices are not available and the winding order is
|
266
254
|
* clock-wise during export to glTF
|
@@ -273,20 +261,20 @@ var _Exporter = /** @class */ (function () {
|
|
273
261
|
* @param binaryWriter The binary data for the glTF file
|
274
262
|
* @param convertToRightHandedSystem Converts the values to right-handed
|
275
263
|
*/
|
276
|
-
|
277
|
-
|
264
|
+
_reorderTriangleFillMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem) {
|
265
|
+
const vertexBuffer = this._getVertexBufferFromMesh(vertexBufferKind, submesh.getMesh());
|
278
266
|
if (vertexBuffer) {
|
279
|
-
|
267
|
+
const stride = vertexBuffer.byteStride / VertexBuffer.GetTypeByteLength(vertexBuffer.type);
|
280
268
|
if (submesh.verticesCount % 3 !== 0) {
|
281
269
|
Tools.Error("The submesh vertices for the triangle fill mode is not divisible by 3!");
|
282
270
|
}
|
283
271
|
else {
|
284
|
-
|
285
|
-
|
272
|
+
const vertexData = [];
|
273
|
+
let index = 0;
|
286
274
|
switch (vertexBufferKind) {
|
287
275
|
case VertexBuffer.PositionKind:
|
288
276
|
case VertexBuffer.NormalKind: {
|
289
|
-
for (
|
277
|
+
for (let x = submesh.verticesStart; x < submesh.verticesStart + submesh.verticesCount; x = x + 3) {
|
290
278
|
index = x * stride;
|
291
279
|
vertexData.push(Vector3.FromArray(meshAttributeArray, index));
|
292
280
|
vertexData.push(Vector3.FromArray(meshAttributeArray, index + 2 * stride));
|
@@ -295,7 +283,7 @@ var _Exporter = /** @class */ (function () {
|
|
295
283
|
break;
|
296
284
|
}
|
297
285
|
case VertexBuffer.TangentKind: {
|
298
|
-
for (
|
286
|
+
for (let x = submesh.verticesStart; x < submesh.verticesStart + submesh.verticesCount; x = x + 3) {
|
299
287
|
index = x * stride;
|
300
288
|
vertexData.push(Vector4.FromArray(meshAttributeArray, index));
|
301
289
|
vertexData.push(Vector4.FromArray(meshAttributeArray, index + 2 * stride));
|
@@ -304,8 +292,8 @@ var _Exporter = /** @class */ (function () {
|
|
304
292
|
break;
|
305
293
|
}
|
306
294
|
case VertexBuffer.ColorKind: {
|
307
|
-
|
308
|
-
for (
|
295
|
+
const size = vertexBuffer.getSize();
|
296
|
+
for (let x = submesh.verticesStart; x < submesh.verticesStart + submesh.verticesCount; x = x + size) {
|
309
297
|
index = x * stride;
|
310
298
|
if (size === 4) {
|
311
299
|
vertexData.push(Vector4.FromArray(meshAttributeArray, index));
|
@@ -322,7 +310,7 @@ var _Exporter = /** @class */ (function () {
|
|
322
310
|
}
|
323
311
|
case VertexBuffer.UVKind:
|
324
312
|
case VertexBuffer.UV2Kind: {
|
325
|
-
for (
|
313
|
+
for (let x = submesh.verticesStart; x < submesh.verticesStart + submesh.verticesCount; x = x + 3) {
|
326
314
|
index = x * stride;
|
327
315
|
vertexData.push(Vector2.FromArray(meshAttributeArray, index));
|
328
316
|
vertexData.push(Vector2.FromArray(meshAttributeArray, index + 2 * stride));
|
@@ -331,16 +319,16 @@ var _Exporter = /** @class */ (function () {
|
|
331
319
|
break;
|
332
320
|
}
|
333
321
|
default: {
|
334
|
-
Tools.Error(
|
322
|
+
Tools.Error(`Unsupported Vertex Buffer type: ${vertexBufferKind}`);
|
335
323
|
}
|
336
324
|
}
|
337
325
|
this._writeVertexAttributeData(vertexData, byteOffset, vertexBufferKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem);
|
338
326
|
}
|
339
327
|
}
|
340
328
|
else {
|
341
|
-
Tools.Warn(
|
329
|
+
Tools.Warn(`reorderTriangleFillMode: Vertex Buffer Kind ${vertexBufferKind} not present!`);
|
342
330
|
}
|
343
|
-
}
|
331
|
+
}
|
344
332
|
/**
|
345
333
|
* Reorders the vertex attributes in the correct triangle strip order. This is necessary when indices are not available and the winding order is
|
346
334
|
* clock-wise during export to glTF
|
@@ -353,12 +341,12 @@ var _Exporter = /** @class */ (function () {
|
|
353
341
|
* @param binaryWriter The binary data for the glTF file
|
354
342
|
* @param convertToRightHandedSystem Converts the values to right-handed
|
355
343
|
*/
|
356
|
-
|
357
|
-
|
344
|
+
_reorderTriangleStripDrawMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem) {
|
345
|
+
const vertexBuffer = this._getVertexBufferFromMesh(vertexBufferKind, submesh.getMesh());
|
358
346
|
if (vertexBuffer) {
|
359
|
-
|
360
|
-
|
361
|
-
|
347
|
+
const stride = vertexBuffer.byteStride / VertexBuffer.GetTypeByteLength(vertexBuffer.type);
|
348
|
+
const vertexData = [];
|
349
|
+
let index = 0;
|
362
350
|
switch (vertexBufferKind) {
|
363
351
|
case VertexBuffer.PositionKind:
|
364
352
|
case VertexBuffer.NormalKind: {
|
@@ -368,14 +356,14 @@ var _Exporter = /** @class */ (function () {
|
|
368
356
|
break;
|
369
357
|
}
|
370
358
|
case VertexBuffer.TangentKind: {
|
371
|
-
for (
|
359
|
+
for (let x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {
|
372
360
|
index = x * stride;
|
373
361
|
vertexData.push(Vector4.FromArray(meshAttributeArray, index));
|
374
362
|
}
|
375
363
|
break;
|
376
364
|
}
|
377
365
|
case VertexBuffer.ColorKind: {
|
378
|
-
for (
|
366
|
+
for (let x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {
|
379
367
|
index = x * stride;
|
380
368
|
vertexBuffer.getSize() === 4
|
381
369
|
? vertexData.push(Vector4.FromArray(meshAttributeArray, index))
|
@@ -385,22 +373,22 @@ var _Exporter = /** @class */ (function () {
|
|
385
373
|
}
|
386
374
|
case VertexBuffer.UVKind:
|
387
375
|
case VertexBuffer.UV2Kind: {
|
388
|
-
for (
|
376
|
+
for (let x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {
|
389
377
|
index = x * stride;
|
390
378
|
vertexData.push(Vector2.FromArray(meshAttributeArray, index));
|
391
379
|
}
|
392
380
|
break;
|
393
381
|
}
|
394
382
|
default: {
|
395
|
-
Tools.Error(
|
383
|
+
Tools.Error(`Unsupported Vertex Buffer type: ${vertexBufferKind}`);
|
396
384
|
}
|
397
385
|
}
|
398
386
|
this._writeVertexAttributeData(vertexData, byteOffset + 12, vertexBufferKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem);
|
399
387
|
}
|
400
388
|
else {
|
401
|
-
Tools.Warn(
|
389
|
+
Tools.Warn(`reorderTriangleStripDrawMode: Vertex buffer kind ${vertexBufferKind} not present!`);
|
402
390
|
}
|
403
|
-
}
|
391
|
+
}
|
404
392
|
/**
|
405
393
|
* Reorders the vertex attributes in the correct triangle fan order. This is necessary when indices are not available and the winding order is
|
406
394
|
* clock-wise during export to glTF
|
@@ -413,30 +401,30 @@ var _Exporter = /** @class */ (function () {
|
|
413
401
|
* @param binaryWriter The binary data for the glTF file
|
414
402
|
* @param convertToRightHandedSystem Converts the values to right-handed
|
415
403
|
*/
|
416
|
-
|
417
|
-
|
404
|
+
_reorderTriangleFanMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem) {
|
405
|
+
const vertexBuffer = this._getVertexBufferFromMesh(vertexBufferKind, submesh.getMesh());
|
418
406
|
if (vertexBuffer) {
|
419
|
-
|
420
|
-
|
421
|
-
|
407
|
+
const stride = vertexBuffer.byteStride / VertexBuffer.GetTypeByteLength(vertexBuffer.type);
|
408
|
+
const vertexData = [];
|
409
|
+
let index = 0;
|
422
410
|
switch (vertexBufferKind) {
|
423
411
|
case VertexBuffer.PositionKind:
|
424
412
|
case VertexBuffer.NormalKind: {
|
425
|
-
for (
|
413
|
+
for (let x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {
|
426
414
|
index = x * stride;
|
427
415
|
vertexData.push(Vector3.FromArray(meshAttributeArray, index));
|
428
416
|
}
|
429
417
|
break;
|
430
418
|
}
|
431
419
|
case VertexBuffer.TangentKind: {
|
432
|
-
for (
|
420
|
+
for (let x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {
|
433
421
|
index = x * stride;
|
434
422
|
vertexData.push(Vector4.FromArray(meshAttributeArray, index));
|
435
423
|
}
|
436
424
|
break;
|
437
425
|
}
|
438
426
|
case VertexBuffer.ColorKind: {
|
439
|
-
for (
|
427
|
+
for (let x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {
|
440
428
|
index = x * stride;
|
441
429
|
vertexData.push(Vector4.FromArray(meshAttributeArray, index));
|
442
430
|
vertexBuffer.getSize() === 4
|
@@ -447,22 +435,22 @@ var _Exporter = /** @class */ (function () {
|
|
447
435
|
}
|
448
436
|
case VertexBuffer.UVKind:
|
449
437
|
case VertexBuffer.UV2Kind: {
|
450
|
-
for (
|
438
|
+
for (let x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {
|
451
439
|
index = x * stride;
|
452
440
|
vertexData.push(Vector2.FromArray(meshAttributeArray, index));
|
453
441
|
}
|
454
442
|
break;
|
455
443
|
}
|
456
444
|
default: {
|
457
|
-
Tools.Error(
|
445
|
+
Tools.Error(`Unsupported Vertex Buffer type: ${vertexBufferKind}`);
|
458
446
|
}
|
459
447
|
}
|
460
448
|
this._writeVertexAttributeData(vertexData, byteOffset, vertexBufferKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem);
|
461
449
|
}
|
462
450
|
else {
|
463
|
-
Tools.Warn(
|
451
|
+
Tools.Warn(`reorderTriangleFanMode: Vertex buffer kind ${vertexBufferKind} not present!`);
|
464
452
|
}
|
465
|
-
}
|
453
|
+
}
|
466
454
|
/**
|
467
455
|
* Writes the vertex attribute data to binary
|
468
456
|
* @param vertices The vertices to write to the binary writer
|
@@ -472,9 +460,8 @@ var _Exporter = /** @class */ (function () {
|
|
472
460
|
* @param binaryWriter The writer containing the binary data
|
473
461
|
* @param convertToRightHandedSystem Converts the values to right-handed
|
474
462
|
*/
|
475
|
-
|
476
|
-
for (
|
477
|
-
var vertex = vertices_1[_i];
|
463
|
+
_writeVertexAttributeData(vertices, byteOffset, vertexAttributeKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem) {
|
464
|
+
for (const vertex of vertices) {
|
478
465
|
if (convertToRightHandedSystem && !(vertexAttributeKind === VertexBuffer.ColorKind) && !(vertex instanceof Vector2)) {
|
479
466
|
if (vertex instanceof Vector3) {
|
480
467
|
if (vertexAttributeKind === VertexBuffer.NormalKind) {
|
@@ -497,13 +484,12 @@ var _Exporter = /** @class */ (function () {
|
|
497
484
|
else if (vertexAttributeKind === VertexBuffer.TangentKind && vertex instanceof Vector4) {
|
498
485
|
_GLTFUtilities._NormalizeTangentFromRef(vertex);
|
499
486
|
}
|
500
|
-
for (
|
501
|
-
var component = _b[_a];
|
487
|
+
for (const component of vertex.asArray()) {
|
502
488
|
binaryWriter.setFloat32(component, byteOffset);
|
503
489
|
byteOffset += 4;
|
504
490
|
}
|
505
491
|
}
|
506
|
-
}
|
492
|
+
}
|
507
493
|
/**
|
508
494
|
* Writes mesh attribute data to a data buffer
|
509
495
|
* Returns the bytelength of the data
|
@@ -515,14 +501,14 @@ var _Exporter = /** @class */ (function () {
|
|
515
501
|
* @param convertToRightHandedSystem Converts the values to right-handed
|
516
502
|
* @param babylonTransformNode
|
517
503
|
*/
|
518
|
-
|
519
|
-
|
520
|
-
|
504
|
+
_writeAttributeData(vertexBufferKind, attributeComponentKind, meshAttributeArray, stride, binaryWriter, convertToRightHandedSystem, babylonTransformNode) {
|
505
|
+
let vertexAttributes = [];
|
506
|
+
let index;
|
521
507
|
switch (vertexBufferKind) {
|
522
508
|
case VertexBuffer.PositionKind: {
|
523
|
-
for (
|
509
|
+
for (let k = 0, length = meshAttributeArray.length / stride; k < length; ++k) {
|
524
510
|
index = k * stride;
|
525
|
-
|
511
|
+
const vertexData = Vector3.FromArray(meshAttributeArray, index);
|
526
512
|
if (convertToRightHandedSystem) {
|
527
513
|
_GLTFUtilities._GetRightHandedPositionVector3FromRef(vertexData);
|
528
514
|
}
|
@@ -531,9 +517,9 @@ var _Exporter = /** @class */ (function () {
|
|
531
517
|
break;
|
532
518
|
}
|
533
519
|
case VertexBuffer.NormalKind: {
|
534
|
-
for (
|
520
|
+
for (let k = 0, length = meshAttributeArray.length / stride; k < length; ++k) {
|
535
521
|
index = k * stride;
|
536
|
-
|
522
|
+
const vertexData = Vector3.FromArray(meshAttributeArray, index);
|
537
523
|
if (convertToRightHandedSystem) {
|
538
524
|
_GLTFUtilities._GetRightHandedNormalVector3FromRef(vertexData);
|
539
525
|
}
|
@@ -543,9 +529,9 @@ var _Exporter = /** @class */ (function () {
|
|
543
529
|
break;
|
544
530
|
}
|
545
531
|
case VertexBuffer.TangentKind: {
|
546
|
-
for (
|
532
|
+
for (let k = 0, length = meshAttributeArray.length / stride; k < length; ++k) {
|
547
533
|
index = k * stride;
|
548
|
-
|
534
|
+
const vertexData = Vector4.FromArray(meshAttributeArray, index);
|
549
535
|
if (convertToRightHandedSystem) {
|
550
536
|
_GLTFUtilities._GetRightHandedVector4FromRef(vertexData);
|
551
537
|
}
|
@@ -555,10 +541,10 @@ var _Exporter = /** @class */ (function () {
|
|
555
541
|
break;
|
556
542
|
}
|
557
543
|
case VertexBuffer.ColorKind: {
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
for (
|
544
|
+
const meshMaterial = babylonTransformNode.material;
|
545
|
+
const convertToLinear = meshMaterial ? meshMaterial.getClassName() === "StandardMaterial" : true;
|
546
|
+
const vertexData = stride === 3 ? new Color3() : new Color4();
|
547
|
+
for (let k = 0, length = meshAttributeArray.length / stride; k < length; ++k) {
|
562
548
|
index = k * stride;
|
563
549
|
if (stride === 3) {
|
564
550
|
Color3.FromArrayToRef(meshAttributeArray, index, vertexData);
|
@@ -578,7 +564,7 @@ var _Exporter = /** @class */ (function () {
|
|
578
564
|
}
|
579
565
|
case VertexBuffer.UVKind:
|
580
566
|
case VertexBuffer.UV2Kind: {
|
581
|
-
for (
|
567
|
+
for (let k = 0, length = meshAttributeArray.length / stride; k < length; ++k) {
|
582
568
|
index = k * stride;
|
583
569
|
vertexAttributes.push(convertToRightHandedSystem ? [meshAttributeArray[index], meshAttributeArray[index + 1]] : [meshAttributeArray[index], meshAttributeArray[index + 1]]);
|
584
570
|
}
|
@@ -586,18 +572,18 @@ var _Exporter = /** @class */ (function () {
|
|
586
572
|
}
|
587
573
|
case VertexBuffer.MatricesIndicesKind:
|
588
574
|
case VertexBuffer.MatricesIndicesExtraKind: {
|
589
|
-
for (
|
575
|
+
for (let k = 0, length = meshAttributeArray.length / stride; k < length; ++k) {
|
590
576
|
index = k * stride;
|
591
|
-
|
577
|
+
const vertexData = Vector4.FromArray(meshAttributeArray, index);
|
592
578
|
vertexAttributes.push(vertexData.asArray());
|
593
579
|
}
|
594
580
|
break;
|
595
581
|
}
|
596
582
|
case VertexBuffer.MatricesWeightsKind:
|
597
583
|
case VertexBuffer.MatricesWeightsExtraKind: {
|
598
|
-
for (
|
584
|
+
for (let k = 0, length = meshAttributeArray.length / stride; k < length; ++k) {
|
599
585
|
index = k * stride;
|
600
|
-
|
586
|
+
const vertexData = Vector4.FromArray(meshAttributeArray, index);
|
601
587
|
vertexAttributes.push(vertexData.asArray());
|
602
588
|
}
|
603
589
|
break;
|
@@ -607,7 +593,7 @@ var _Exporter = /** @class */ (function () {
|
|
607
593
|
vertexAttributes = [];
|
608
594
|
}
|
609
595
|
}
|
610
|
-
|
596
|
+
let writeBinaryFunc;
|
611
597
|
switch (attributeComponentKind) {
|
612
598
|
case 5121 /* UNSIGNED_BYTE */: {
|
613
599
|
writeBinaryFunc = binaryWriter.setUInt8.bind(binaryWriter);
|
@@ -630,14 +616,12 @@ var _Exporter = /** @class */ (function () {
|
|
630
616
|
return;
|
631
617
|
}
|
632
618
|
}
|
633
|
-
for (
|
634
|
-
|
635
|
-
for (var _a = 0, vertexAttribute_1 = vertexAttribute; _a < vertexAttribute_1.length; _a++) {
|
636
|
-
var component = vertexAttribute_1[_a];
|
619
|
+
for (const vertexAttribute of vertexAttributes) {
|
620
|
+
for (const component of vertexAttribute) {
|
637
621
|
writeBinaryFunc(component);
|
638
622
|
}
|
639
623
|
}
|
640
|
-
}
|
624
|
+
}
|
641
625
|
/**
|
642
626
|
* Writes mesh attribute data to a data buffer
|
643
627
|
* Returns the bytelength of the data
|
@@ -652,17 +636,17 @@ var _Exporter = /** @class */ (function () {
|
|
652
636
|
* @param convertToRightHandedSystem Converts the values to right-handed
|
653
637
|
* @param minMax
|
654
638
|
*/
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
639
|
+
writeMorphTargetAttributeData(vertexBufferKind, attributeComponentKind, meshPrimitive, morphTarget, meshAttributeArray, morphTargetAttributeArray, stride, binaryWriter, convertToRightHandedSystem, minMax) {
|
640
|
+
let vertexAttributes = [];
|
641
|
+
let index;
|
642
|
+
let difference = new Vector3();
|
643
|
+
let difference4 = new Vector4(0, 0, 0, 0);
|
660
644
|
switch (vertexBufferKind) {
|
661
645
|
case VertexBuffer.PositionKind: {
|
662
|
-
for (
|
646
|
+
for (let k = meshPrimitive.verticesStart; k < meshPrimitive.verticesCount; ++k) {
|
663
647
|
index = meshPrimitive.indexStart + k * stride;
|
664
|
-
|
665
|
-
|
648
|
+
const vertexData = Vector3.FromArray(meshAttributeArray, index);
|
649
|
+
const morphData = Vector3.FromArray(morphTargetAttributeArray, index);
|
666
650
|
difference = morphData.subtractToRef(vertexData, difference);
|
667
651
|
if (convertToRightHandedSystem) {
|
668
652
|
_GLTFUtilities._GetRightHandedPositionVector3FromRef(difference);
|
@@ -676,11 +660,11 @@ var _Exporter = /** @class */ (function () {
|
|
676
660
|
break;
|
677
661
|
}
|
678
662
|
case VertexBuffer.NormalKind: {
|
679
|
-
for (
|
663
|
+
for (let k = meshPrimitive.verticesStart; k < meshPrimitive.verticesCount; ++k) {
|
680
664
|
index = meshPrimitive.indexStart + k * stride;
|
681
|
-
|
665
|
+
const vertexData = Vector3.FromArray(meshAttributeArray, index);
|
682
666
|
vertexData.normalize();
|
683
|
-
|
667
|
+
const morphData = Vector3.FromArray(morphTargetAttributeArray, index);
|
684
668
|
morphData.normalize();
|
685
669
|
difference = morphData.subtractToRef(vertexData, difference);
|
686
670
|
if (convertToRightHandedSystem) {
|
@@ -691,11 +675,11 @@ var _Exporter = /** @class */ (function () {
|
|
691
675
|
break;
|
692
676
|
}
|
693
677
|
case VertexBuffer.TangentKind: {
|
694
|
-
for (
|
678
|
+
for (let k = meshPrimitive.verticesStart; k < meshPrimitive.verticesCount; ++k) {
|
695
679
|
index = meshPrimitive.indexStart + k * (stride + 1);
|
696
|
-
|
680
|
+
const vertexData = Vector4.FromArray(meshAttributeArray, index);
|
697
681
|
_GLTFUtilities._NormalizeTangentFromRef(vertexData);
|
698
|
-
|
682
|
+
const morphData = Vector4.FromArray(morphTargetAttributeArray, index);
|
699
683
|
_GLTFUtilities._NormalizeTangentFromRef(morphData);
|
700
684
|
difference4 = morphData.subtractToRef(vertexData, difference4);
|
701
685
|
if (convertToRightHandedSystem) {
|
@@ -710,7 +694,7 @@ var _Exporter = /** @class */ (function () {
|
|
710
694
|
vertexAttributes = [];
|
711
695
|
}
|
712
696
|
}
|
713
|
-
|
697
|
+
let writeBinaryFunc;
|
714
698
|
switch (attributeComponentKind) {
|
715
699
|
case 5121 /* UNSIGNED_BYTE */: {
|
716
700
|
writeBinaryFunc = binaryWriter.setUInt8.bind(binaryWriter);
|
@@ -733,14 +717,12 @@ var _Exporter = /** @class */ (function () {
|
|
733
717
|
return;
|
734
718
|
}
|
735
719
|
}
|
736
|
-
for (
|
737
|
-
|
738
|
-
for (var _a = 0, vertexAttribute_2 = vertexAttribute; _a < vertexAttribute_2.length; _a++) {
|
739
|
-
var component = vertexAttribute_2[_a];
|
720
|
+
for (const vertexAttribute of vertexAttributes) {
|
721
|
+
for (const component of vertexAttribute) {
|
740
722
|
writeBinaryFunc(component);
|
741
723
|
}
|
742
724
|
}
|
743
|
-
}
|
725
|
+
}
|
744
726
|
/**
|
745
727
|
* Generates glTF json data
|
746
728
|
* @param shouldUseGlb Indicates whether the json should be written for a glb file
|
@@ -748,13 +730,12 @@ var _Exporter = /** @class */ (function () {
|
|
748
730
|
* @param prettyPrint Indicates whether the json file should be pretty printed (true) or not (false)
|
749
731
|
* @returns json data as string
|
750
732
|
*/
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
var byteOffset = this._totalByteLength;
|
733
|
+
_generateJSON(shouldUseGlb, glTFPrefix, prettyPrint) {
|
734
|
+
const buffer = { byteLength: this._totalByteLength };
|
735
|
+
let imageName;
|
736
|
+
let imageData;
|
737
|
+
let bufferView;
|
738
|
+
let byteOffset = this._totalByteLength;
|
758
739
|
if (buffer.byteLength) {
|
759
740
|
this._glTF.buffers = [buffer];
|
760
741
|
}
|
@@ -798,22 +779,22 @@ var _Exporter = /** @class */ (function () {
|
|
798
779
|
}
|
799
780
|
else {
|
800
781
|
this._glTF.images = [];
|
801
|
-
this._images.forEach(
|
782
|
+
this._images.forEach((image) => {
|
802
783
|
if (image.uri) {
|
803
|
-
imageData =
|
804
|
-
|
784
|
+
imageData = this._imageData[image.uri];
|
785
|
+
this._orderedImageData.push(imageData);
|
805
786
|
imageName = image.uri.split(".")[0] + " image";
|
806
787
|
bufferView = _GLTFUtilities._CreateBufferView(0, byteOffset, imageData.data.length, undefined, imageName);
|
807
788
|
byteOffset += imageData.data.buffer.byteLength;
|
808
|
-
|
809
|
-
image.bufferView =
|
789
|
+
this._bufferViews.push(bufferView);
|
790
|
+
image.bufferView = this._bufferViews.length - 1;
|
810
791
|
image.name = imageName;
|
811
792
|
image.mimeType = imageData.mimeType;
|
812
793
|
image.uri = undefined;
|
813
|
-
if (!
|
814
|
-
|
794
|
+
if (!this._glTF.images) {
|
795
|
+
this._glTF.images = [];
|
815
796
|
}
|
816
|
-
|
797
|
+
this._glTF.images.push(image);
|
817
798
|
}
|
818
799
|
});
|
819
800
|
// Replace uri with bufferview and mime type for glb
|
@@ -823,113 +804,108 @@ var _Exporter = /** @class */ (function () {
|
|
823
804
|
if (!shouldUseGlb) {
|
824
805
|
buffer.uri = glTFPrefix + ".bin";
|
825
806
|
}
|
826
|
-
|
807
|
+
const jsonText = prettyPrint ? JSON.stringify(this._glTF, null, 2) : JSON.stringify(this._glTF);
|
827
808
|
return jsonText;
|
828
|
-
}
|
809
|
+
}
|
829
810
|
/**
|
830
811
|
* Generates data for .gltf and .bin files based on the glTF prefix string
|
831
812
|
* @param glTFPrefix Text to use when prefixing a glTF file
|
832
813
|
* @param dispose Dispose the exporter
|
833
814
|
* @returns GLTFData with glTF file data
|
834
815
|
*/
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
var glTFBinFile = glTFPrefix + ".bin";
|
844
|
-
var container = new GLTFData();
|
816
|
+
_generateGLTFAsync(glTFPrefix, dispose = true) {
|
817
|
+
return this._generateBinaryAsync().then((binaryBuffer) => {
|
818
|
+
this._extensionsOnExporting();
|
819
|
+
const jsonText = this._generateJSON(false, glTFPrefix, true);
|
820
|
+
const bin = new Blob([binaryBuffer], { type: "application/octet-stream" });
|
821
|
+
const glTFFileName = glTFPrefix + ".gltf";
|
822
|
+
const glTFBinFile = glTFPrefix + ".bin";
|
823
|
+
const container = new GLTFData();
|
845
824
|
container.glTFFiles[glTFFileName] = jsonText;
|
846
825
|
container.glTFFiles[glTFBinFile] = bin;
|
847
|
-
if (
|
848
|
-
for (
|
849
|
-
container.glTFFiles[image] = new Blob([
|
826
|
+
if (this._imageData) {
|
827
|
+
for (const image in this._imageData) {
|
828
|
+
container.glTFFiles[image] = new Blob([this._imageData[image].data], { type: this._imageData[image].mimeType });
|
850
829
|
}
|
851
830
|
}
|
852
831
|
if (dispose) {
|
853
|
-
|
832
|
+
this.dispose();
|
854
833
|
}
|
855
834
|
return container;
|
856
835
|
});
|
857
|
-
}
|
836
|
+
}
|
858
837
|
/**
|
859
838
|
* Creates a binary buffer for glTF
|
860
839
|
* @returns array buffer for binary data
|
861
840
|
*/
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
_this._localEngine.dispose();
|
841
|
+
_generateBinaryAsync() {
|
842
|
+
const binaryWriter = new _BinaryWriter(4);
|
843
|
+
return this._createSceneAsync(this._babylonScene, binaryWriter).then(() => {
|
844
|
+
if (this._localEngine) {
|
845
|
+
this._localEngine.dispose();
|
868
846
|
}
|
869
847
|
return binaryWriter.getArrayBuffer();
|
870
848
|
});
|
871
|
-
}
|
849
|
+
}
|
872
850
|
/**
|
873
851
|
* Pads the number to a multiple of 4
|
874
852
|
* @param num number to pad
|
875
853
|
* @returns padded number
|
876
854
|
*/
|
877
|
-
|
878
|
-
|
879
|
-
|
855
|
+
_getPadding(num) {
|
856
|
+
const remainder = num % 4;
|
857
|
+
const padding = remainder === 0 ? remainder : 4 - remainder;
|
880
858
|
return padding;
|
881
|
-
}
|
859
|
+
}
|
882
860
|
/**
|
883
861
|
* @param glTFPrefix
|
884
862
|
* @param dispose
|
885
863
|
* @hidden
|
886
864
|
*/
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
var encodedJsonText;
|
898
|
-
var imageByteLength = 0;
|
865
|
+
_generateGLBAsync(glTFPrefix, dispose = true) {
|
866
|
+
return this._generateBinaryAsync().then((binaryBuffer) => {
|
867
|
+
this._extensionsOnExporting();
|
868
|
+
const jsonText = this._generateJSON(true);
|
869
|
+
const glbFileName = glTFPrefix + ".glb";
|
870
|
+
const headerLength = 12;
|
871
|
+
const chunkLengthPrefix = 8;
|
872
|
+
let jsonLength = jsonText.length;
|
873
|
+
let encodedJsonText;
|
874
|
+
let imageByteLength = 0;
|
899
875
|
// make use of TextEncoder when available
|
900
876
|
if (typeof TextEncoder !== "undefined") {
|
901
|
-
|
877
|
+
const encoder = new TextEncoder();
|
902
878
|
encodedJsonText = encoder.encode(jsonText);
|
903
879
|
jsonLength = encodedJsonText.length;
|
904
880
|
}
|
905
|
-
for (
|
906
|
-
imageByteLength +=
|
881
|
+
for (let i = 0; i < this._orderedImageData.length; ++i) {
|
882
|
+
imageByteLength += this._orderedImageData[i].data.byteLength;
|
907
883
|
}
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
884
|
+
const jsonPadding = this._getPadding(jsonLength);
|
885
|
+
const binPadding = this._getPadding(binaryBuffer.byteLength);
|
886
|
+
const imagePadding = this._getPadding(imageByteLength);
|
887
|
+
const byteLength = headerLength + 2 * chunkLengthPrefix + jsonLength + jsonPadding + binaryBuffer.byteLength + binPadding + imageByteLength + imagePadding;
|
912
888
|
//header
|
913
|
-
|
914
|
-
|
889
|
+
const headerBuffer = new ArrayBuffer(headerLength);
|
890
|
+
const headerBufferView = new DataView(headerBuffer);
|
915
891
|
headerBufferView.setUint32(0, 0x46546c67, true); //glTF
|
916
892
|
headerBufferView.setUint32(4, 2, true); // version
|
917
893
|
headerBufferView.setUint32(8, byteLength, true); // total bytes in file
|
918
894
|
//json chunk
|
919
|
-
|
920
|
-
|
895
|
+
const jsonChunkBuffer = new ArrayBuffer(chunkLengthPrefix + jsonLength + jsonPadding);
|
896
|
+
const jsonChunkBufferView = new DataView(jsonChunkBuffer);
|
921
897
|
jsonChunkBufferView.setUint32(0, jsonLength + jsonPadding, true);
|
922
898
|
jsonChunkBufferView.setUint32(4, 0x4e4f534a, true);
|
923
899
|
//json chunk bytes
|
924
|
-
|
900
|
+
const jsonData = new Uint8Array(jsonChunkBuffer, chunkLengthPrefix);
|
925
901
|
// if TextEncoder was available, we can simply copy the encoded array
|
926
902
|
if (encodedJsonText) {
|
927
903
|
jsonData.set(encodedJsonText);
|
928
904
|
}
|
929
905
|
else {
|
930
|
-
|
931
|
-
for (
|
932
|
-
|
906
|
+
const blankCharCode = "_".charCodeAt(0);
|
907
|
+
for (let i = 0; i < jsonLength; ++i) {
|
908
|
+
const charCode = jsonText.charCodeAt(i);
|
933
909
|
// if the character doesn't fit into a single UTF-16 code unit, just put a blank character
|
934
910
|
if (charCode != jsonText.codePointAt(i)) {
|
935
911
|
jsonData[i] = blankCharCode;
|
@@ -940,52 +916,52 @@ var _Exporter = /** @class */ (function () {
|
|
940
916
|
}
|
941
917
|
}
|
942
918
|
//json padding
|
943
|
-
|
944
|
-
for (
|
919
|
+
const jsonPaddingView = new Uint8Array(jsonChunkBuffer, chunkLengthPrefix + jsonLength);
|
920
|
+
for (let i = 0; i < jsonPadding; ++i) {
|
945
921
|
jsonPaddingView[i] = 0x20;
|
946
922
|
}
|
947
923
|
//binary chunk
|
948
|
-
|
949
|
-
|
924
|
+
const binaryChunkBuffer = new ArrayBuffer(chunkLengthPrefix);
|
925
|
+
const binaryChunkBufferView = new DataView(binaryChunkBuffer);
|
950
926
|
binaryChunkBufferView.setUint32(0, binaryBuffer.byteLength + imageByteLength + imagePadding, true);
|
951
927
|
binaryChunkBufferView.setUint32(4, 0x004e4942, true);
|
952
928
|
// binary padding
|
953
|
-
|
954
|
-
|
955
|
-
for (
|
929
|
+
const binPaddingBuffer = new ArrayBuffer(binPadding);
|
930
|
+
const binPaddingView = new Uint8Array(binPaddingBuffer);
|
931
|
+
for (let i = 0; i < binPadding; ++i) {
|
956
932
|
binPaddingView[i] = 0;
|
957
933
|
}
|
958
|
-
|
959
|
-
|
960
|
-
for (
|
934
|
+
const imagePaddingBuffer = new ArrayBuffer(imagePadding);
|
935
|
+
const imagePaddingView = new Uint8Array(imagePaddingBuffer);
|
936
|
+
for (let i = 0; i < imagePadding; ++i) {
|
961
937
|
imagePaddingView[i] = 0;
|
962
938
|
}
|
963
|
-
|
939
|
+
const glbData = [headerBuffer, jsonChunkBuffer, binaryChunkBuffer, binaryBuffer];
|
964
940
|
// binary data
|
965
|
-
for (
|
966
|
-
glbData.push(
|
941
|
+
for (let i = 0; i < this._orderedImageData.length; ++i) {
|
942
|
+
glbData.push(this._orderedImageData[i].data.buffer);
|
967
943
|
}
|
968
944
|
glbData.push(binPaddingBuffer);
|
969
945
|
glbData.push(imagePaddingBuffer);
|
970
|
-
|
971
|
-
|
946
|
+
const glbFile = new Blob(glbData, { type: "application/octet-stream" });
|
947
|
+
const container = new GLTFData();
|
972
948
|
container.glTFFiles[glbFileName] = glbFile;
|
973
|
-
if (
|
974
|
-
|
949
|
+
if (this._localEngine != null) {
|
950
|
+
this._localEngine.dispose();
|
975
951
|
}
|
976
952
|
if (dispose) {
|
977
|
-
|
953
|
+
this.dispose();
|
978
954
|
}
|
979
955
|
return container;
|
980
956
|
});
|
981
|
-
}
|
957
|
+
}
|
982
958
|
/**
|
983
959
|
* Sets the TRS for each node
|
984
960
|
* @param node glTF Node for storing the transformation data
|
985
961
|
* @param babylonTransformNode Babylon mesh used as the source for the transformation data
|
986
962
|
* @param convertToRightHandedSystem Converts the values to right-handed
|
987
963
|
*/
|
988
|
-
|
964
|
+
_setNodeTransformation(node, babylonTransformNode, convertToRightHandedSystem) {
|
989
965
|
if (!babylonTransformNode.getPivotPoint().equalsToFloats(0, 0, 0)) {
|
990
966
|
Tools.Warn("Pivot points are not supported in the glTF serializer");
|
991
967
|
}
|
@@ -997,7 +973,7 @@ var _Exporter = /** @class */ (function () {
|
|
997
973
|
if (!babylonTransformNode.scaling.equalsToFloats(1, 1, 1)) {
|
998
974
|
node.scale = babylonTransformNode.scaling.asArray();
|
999
975
|
}
|
1000
|
-
|
976
|
+
const rotationQuaternion = Quaternion.RotationYawPitchRoll(babylonTransformNode.rotation.y, babylonTransformNode.rotation.x, babylonTransformNode.rotation.z);
|
1001
977
|
if (babylonTransformNode.rotationQuaternion) {
|
1002
978
|
rotationQuaternion.multiplyInPlace(babylonTransformNode.rotationQuaternion);
|
1003
979
|
}
|
@@ -1007,28 +983,28 @@ var _Exporter = /** @class */ (function () {
|
|
1007
983
|
}
|
1008
984
|
node.rotation = rotationQuaternion.normalize().asArray();
|
1009
985
|
}
|
1010
|
-
}
|
1011
|
-
|
986
|
+
}
|
987
|
+
_setCameraTransformation(node, babylonCamera, convertToRightHandedSystem) {
|
1012
988
|
if (!babylonCamera.position.equalsToFloats(0, 0, 0)) {
|
1013
989
|
node.translation = convertToRightHandedSystem ? _GLTFUtilities._GetRightHandedPositionVector3(babylonCamera.position).asArray() : babylonCamera.position.asArray();
|
1014
990
|
}
|
1015
|
-
|
991
|
+
const rotationQuaternion = babylonCamera.rotationQuaternion; // we target the local transformation if one.
|
1016
992
|
if (rotationQuaternion && !Quaternion.IsIdentity(rotationQuaternion)) {
|
1017
993
|
if (convertToRightHandedSystem) {
|
1018
994
|
_GLTFUtilities._GetRightHandedQuaternionFromRef(rotationQuaternion);
|
1019
995
|
}
|
1020
996
|
node.rotation = rotationQuaternion.normalize().asArray();
|
1021
997
|
}
|
1022
|
-
}
|
1023
|
-
|
998
|
+
}
|
999
|
+
_getVertexBufferFromMesh(attributeKind, bufferMesh) {
|
1024
1000
|
if (bufferMesh.isVerticesDataPresent(attributeKind)) {
|
1025
|
-
|
1001
|
+
const vertexBuffer = bufferMesh.getVertexBuffer(attributeKind);
|
1026
1002
|
if (vertexBuffer) {
|
1027
1003
|
return vertexBuffer;
|
1028
1004
|
}
|
1029
1005
|
}
|
1030
1006
|
return null;
|
1031
|
-
}
|
1007
|
+
}
|
1032
1008
|
/**
|
1033
1009
|
* Creates a bufferview based on the vertices type for the Babylon mesh
|
1034
1010
|
* @param kind Indicates the type of vertices data
|
@@ -1038,24 +1014,24 @@ var _Exporter = /** @class */ (function () {
|
|
1038
1014
|
* @param byteStride
|
1039
1015
|
* @param convertToRightHandedSystem Converts the values to right-handed
|
1040
1016
|
*/
|
1041
|
-
|
1042
|
-
|
1017
|
+
_createBufferViewKind(kind, attributeComponentKind, babylonTransformNode, binaryWriter, byteStride, convertToRightHandedSystem) {
|
1018
|
+
const bufferMesh = babylonTransformNode instanceof Mesh
|
1043
1019
|
? babylonTransformNode
|
1044
1020
|
: babylonTransformNode instanceof InstancedMesh
|
1045
1021
|
? babylonTransformNode.sourceMesh
|
1046
1022
|
: null;
|
1047
1023
|
if (bufferMesh) {
|
1048
|
-
|
1049
|
-
|
1024
|
+
const vertexBuffer = bufferMesh.getVertexBuffer(kind);
|
1025
|
+
const vertexData = bufferMesh.getVerticesData(kind);
|
1050
1026
|
if (vertexBuffer && vertexData) {
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1027
|
+
const typeByteLength = VertexBuffer.GetTypeByteLength(attributeComponentKind);
|
1028
|
+
const byteLength = vertexData.length * typeByteLength;
|
1029
|
+
const bufferView = _GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, kind + " - " + bufferMesh.name);
|
1054
1030
|
this._bufferViews.push(bufferView);
|
1055
1031
|
this._writeAttributeData(kind, attributeComponentKind, vertexData, byteStride / typeByteLength, binaryWriter, convertToRightHandedSystem, babylonTransformNode);
|
1056
1032
|
}
|
1057
1033
|
}
|
1058
|
-
}
|
1034
|
+
}
|
1059
1035
|
/**
|
1060
1036
|
* Creates a bufferview based on the vertices type for the Babylon mesh
|
1061
1037
|
* @param babylonSubMesh The Babylon submesh that the morph target is applied to
|
@@ -1064,37 +1040,37 @@ var _Exporter = /** @class */ (function () {
|
|
1064
1040
|
* @param binaryWriter The buffer to write the bufferview data to
|
1065
1041
|
* @param convertToRightHandedSystem Converts the values to right-handed
|
1066
1042
|
*/
|
1067
|
-
|
1043
|
+
_setMorphTargetAttributes(babylonSubMesh, meshPrimitive, babylonMorphTarget, binaryWriter, convertToRightHandedSystem) {
|
1068
1044
|
if (babylonMorphTarget) {
|
1069
1045
|
if (!meshPrimitive.targets) {
|
1070
1046
|
meshPrimitive.targets = [];
|
1071
1047
|
}
|
1072
|
-
|
1048
|
+
const target = {};
|
1073
1049
|
if (babylonMorphTarget.hasNormals) {
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1050
|
+
const vertexNormals = babylonSubMesh.getMesh().getVerticesData(VertexBuffer.NormalKind);
|
1051
|
+
const morphNormals = babylonMorphTarget.getNormals();
|
1052
|
+
const count = babylonSubMesh.verticesCount;
|
1053
|
+
const byteStride = 12; // 3 x 4 byte floats
|
1054
|
+
const byteLength = count * byteStride;
|
1055
|
+
const bufferView = _GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, babylonMorphTarget.name + "_NORMAL");
|
1080
1056
|
this._bufferViews.push(bufferView);
|
1081
|
-
|
1082
|
-
|
1057
|
+
const bufferViewIndex = this._bufferViews.length - 1;
|
1058
|
+
const accessor = _GLTFUtilities._CreateAccessor(bufferViewIndex, babylonMorphTarget.name + " - " + "NORMAL", "VEC3" /* VEC3 */, 5126 /* FLOAT */, count, 0, null, null);
|
1083
1059
|
this._accessors.push(accessor);
|
1084
1060
|
target.NORMAL = this._accessors.length - 1;
|
1085
1061
|
this.writeMorphTargetAttributeData(VertexBuffer.NormalKind, 5126 /* FLOAT */, babylonSubMesh, babylonMorphTarget, vertexNormals, morphNormals, byteStride / 4, binaryWriter, convertToRightHandedSystem);
|
1086
1062
|
}
|
1087
1063
|
if (babylonMorphTarget.hasPositions) {
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1064
|
+
const vertexPositions = babylonSubMesh.getMesh().getVerticesData(VertexBuffer.PositionKind);
|
1065
|
+
const morphPositions = babylonMorphTarget.getPositions();
|
1066
|
+
const count = babylonSubMesh.verticesCount;
|
1067
|
+
const byteStride = 12; // 3 x 4 byte floats
|
1068
|
+
const byteLength = count * byteStride;
|
1069
|
+
const bufferView = _GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, babylonMorphTarget.name + "_POSITION");
|
1094
1070
|
this._bufferViews.push(bufferView);
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1071
|
+
const bufferViewIndex = this._bufferViews.length - 1;
|
1072
|
+
const minMax = { min: new Vector3(Infinity, Infinity, Infinity), max: new Vector3(-Infinity, -Infinity, -Infinity) };
|
1073
|
+
const accessor = _GLTFUtilities._CreateAccessor(bufferViewIndex, babylonMorphTarget.name + " - " + "POSITION", "VEC3" /* VEC3 */, 5126 /* FLOAT */, count, 0, null, null);
|
1098
1074
|
this._accessors.push(accessor);
|
1099
1075
|
target.POSITION = this._accessors.length - 1;
|
1100
1076
|
this.writeMorphTargetAttributeData(VertexBuffer.PositionKind, 5126 /* FLOAT */, babylonSubMesh, babylonMorphTarget, vertexPositions, morphPositions, byteStride / 4, binaryWriter, convertToRightHandedSystem, minMax);
|
@@ -1102,38 +1078,38 @@ var _Exporter = /** @class */ (function () {
|
|
1102
1078
|
accessor.max = minMax.max.asArray();
|
1103
1079
|
}
|
1104
1080
|
if (babylonMorphTarget.hasTangents) {
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1081
|
+
const vertexTangents = babylonSubMesh.getMesh().getVerticesData(VertexBuffer.TangentKind);
|
1082
|
+
const morphTangents = babylonMorphTarget.getTangents();
|
1083
|
+
const count = babylonSubMesh.verticesCount;
|
1084
|
+
const byteStride = 12; // 3 x 4 byte floats
|
1085
|
+
const byteLength = count * byteStride;
|
1086
|
+
const bufferView = _GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, babylonMorphTarget.name + "_NORMAL");
|
1111
1087
|
this._bufferViews.push(bufferView);
|
1112
|
-
|
1113
|
-
|
1088
|
+
const bufferViewIndex = this._bufferViews.length - 1;
|
1089
|
+
const accessor = _GLTFUtilities._CreateAccessor(bufferViewIndex, babylonMorphTarget.name + " - " + "TANGENT", "VEC3" /* VEC3 */, 5126 /* FLOAT */, count, 0, null, null);
|
1114
1090
|
this._accessors.push(accessor);
|
1115
1091
|
target.TANGENT = this._accessors.length - 1;
|
1116
1092
|
this.writeMorphTargetAttributeData(VertexBuffer.TangentKind, 5126 /* FLOAT */, babylonSubMesh, babylonMorphTarget, vertexTangents, morphTangents, byteStride / 4, binaryWriter, convertToRightHandedSystem);
|
1117
1093
|
}
|
1118
1094
|
meshPrimitive.targets.push(target);
|
1119
1095
|
}
|
1120
|
-
}
|
1096
|
+
}
|
1121
1097
|
/**
|
1122
1098
|
* The primitive mode of the Babylon mesh
|
1123
1099
|
* @param babylonMesh The BabylonJS mesh
|
1124
1100
|
*/
|
1125
|
-
|
1101
|
+
_getMeshPrimitiveMode(babylonMesh) {
|
1126
1102
|
if (babylonMesh instanceof LinesMesh) {
|
1127
1103
|
return Material.LineListDrawMode;
|
1128
1104
|
}
|
1129
1105
|
return babylonMesh.material ? babylonMesh.material.fillMode : Material.TriangleFillMode;
|
1130
|
-
}
|
1106
|
+
}
|
1131
1107
|
/**
|
1132
1108
|
* Sets the primitive mode of the glTF mesh primitive
|
1133
1109
|
* @param meshPrimitive glTF mesh primitive
|
1134
1110
|
* @param primitiveMode The primitive mode
|
1135
1111
|
*/
|
1136
|
-
|
1112
|
+
_setPrimitiveMode(meshPrimitive, primitiveMode) {
|
1137
1113
|
switch (primitiveMode) {
|
1138
1114
|
case Material.TriangleFillMode: {
|
1139
1115
|
// glTF defaults to using Triangle Mode
|
@@ -1168,14 +1144,14 @@ var _Exporter = /** @class */ (function () {
|
|
1168
1144
|
break;
|
1169
1145
|
}
|
1170
1146
|
}
|
1171
|
-
}
|
1147
|
+
}
|
1172
1148
|
/**
|
1173
1149
|
* Sets the vertex attribute accessor based of the glTF mesh primitive
|
1174
1150
|
* @param meshPrimitive glTF mesh primitive
|
1175
1151
|
* @param attributeKind vertex attribute
|
1176
1152
|
* @returns boolean specifying if uv coordinates are present
|
1177
1153
|
*/
|
1178
|
-
|
1154
|
+
_setAttributeKind(meshPrimitive, attributeKind) {
|
1179
1155
|
switch (attributeKind) {
|
1180
1156
|
case VertexBuffer.PositionKind: {
|
1181
1157
|
meshPrimitive.attributes.POSITION = this._accessors.length - 1;
|
@@ -1221,7 +1197,7 @@ var _Exporter = /** @class */ (function () {
|
|
1221
1197
|
Tools.Warn("Unsupported Vertex Buffer Type: " + attributeKind);
|
1222
1198
|
}
|
1223
1199
|
}
|
1224
|
-
}
|
1200
|
+
}
|
1225
1201
|
/**
|
1226
1202
|
* Sets data for the primitive attributes of each submesh
|
1227
1203
|
* @param mesh glTF Mesh object to store the primitive attribute information
|
@@ -1229,19 +1205,18 @@ var _Exporter = /** @class */ (function () {
|
|
1229
1205
|
* @param binaryWriter Buffer to write the attribute data to
|
1230
1206
|
* @param convertToRightHandedSystem Converts the values to right-handed
|
1231
1207
|
*/
|
1232
|
-
|
1233
|
-
|
1234
|
-
|
1235
|
-
|
1236
|
-
|
1237
|
-
var minMax;
|
1208
|
+
_setPrimitiveAttributesAsync(mesh, babylonTransformNode, binaryWriter, convertToRightHandedSystem) {
|
1209
|
+
const promises = [];
|
1210
|
+
let bufferMesh = null;
|
1211
|
+
let bufferView;
|
1212
|
+
let minMax;
|
1238
1213
|
if (babylonTransformNode instanceof Mesh) {
|
1239
1214
|
bufferMesh = babylonTransformNode;
|
1240
1215
|
}
|
1241
1216
|
else if (babylonTransformNode instanceof InstancedMesh) {
|
1242
1217
|
bufferMesh = babylonTransformNode.sourceMesh;
|
1243
1218
|
}
|
1244
|
-
|
1219
|
+
const attributeData = [
|
1245
1220
|
{ kind: VertexBuffer.PositionKind, accessorType: "VEC3" /* VEC3 */, accessorComponentType: 5126 /* FLOAT */, byteStride: 12 },
|
1246
1221
|
{ kind: VertexBuffer.NormalKind, accessorType: "VEC3" /* VEC3 */, accessorComponentType: 5126 /* FLOAT */, byteStride: 12 },
|
1247
1222
|
{ kind: VertexBuffer.ColorKind, accessorType: "VEC4" /* VEC4 */, accessorComponentType: 5126 /* FLOAT */, byteStride: 16 },
|
@@ -1254,17 +1229,16 @@ var _Exporter = /** @class */ (function () {
|
|
1254
1229
|
{ kind: VertexBuffer.MatricesWeightsExtraKind, accessorType: "VEC4" /* VEC4 */, accessorComponentType: 5126 /* FLOAT */, byteStride: 16 },
|
1255
1230
|
];
|
1256
1231
|
if (bufferMesh) {
|
1257
|
-
|
1258
|
-
|
1259
|
-
|
1260
|
-
|
1232
|
+
let indexBufferViewIndex = null;
|
1233
|
+
const primitiveMode = this._getMeshPrimitiveMode(bufferMesh);
|
1234
|
+
const vertexAttributeBufferViews = {};
|
1235
|
+
const morphTargetManager = bufferMesh.morphTargetManager;
|
1261
1236
|
// For each BabylonMesh, create bufferviews for each 'kind'
|
1262
|
-
for (
|
1263
|
-
|
1264
|
-
|
1265
|
-
var attributeComponentKind = attribute.accessorComponentType;
|
1237
|
+
for (const attribute of attributeData) {
|
1238
|
+
const attributeKind = attribute.kind;
|
1239
|
+
const attributeComponentKind = attribute.accessorComponentType;
|
1266
1240
|
if (bufferMesh.isVerticesDataPresent(attributeKind)) {
|
1267
|
-
|
1241
|
+
const vertexBuffer = this._getVertexBufferFromMesh(attributeKind, bufferMesh);
|
1268
1242
|
attribute.byteStride = vertexBuffer
|
1269
1243
|
? vertexBuffer.getSize() * VertexBuffer.GetTypeByteLength(attribute.accessorComponentType)
|
1270
1244
|
: VertexBuffer.DeduceStride(attributeKind) * 4;
|
@@ -1277,27 +1251,26 @@ var _Exporter = /** @class */ (function () {
|
|
1277
1251
|
}
|
1278
1252
|
}
|
1279
1253
|
if (bufferMesh.getTotalIndices()) {
|
1280
|
-
|
1254
|
+
const indices = bufferMesh.getIndices();
|
1281
1255
|
if (indices) {
|
1282
|
-
|
1256
|
+
const byteLength = indices.length * 4;
|
1283
1257
|
bufferView = _GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, undefined, "Indices - " + bufferMesh.name);
|
1284
1258
|
this._bufferViews.push(bufferView);
|
1285
1259
|
indexBufferViewIndex = this._bufferViews.length - 1;
|
1286
|
-
for (
|
1260
|
+
for (let k = 0, length = indices.length; k < length; ++k) {
|
1287
1261
|
binaryWriter.setUInt32(indices[k]);
|
1288
1262
|
}
|
1289
1263
|
}
|
1290
1264
|
}
|
1291
1265
|
if (bufferMesh.subMeshes) {
|
1292
1266
|
// go through all mesh primitives (submeshes)
|
1293
|
-
for (
|
1294
|
-
|
1295
|
-
|
1296
|
-
var materialIndex = null;
|
1267
|
+
for (const submesh of bufferMesh.subMeshes) {
|
1268
|
+
let babylonMaterial = submesh.getMaterial() || bufferMesh.getScene().defaultMaterial;
|
1269
|
+
let materialIndex = null;
|
1297
1270
|
if (babylonMaterial) {
|
1298
1271
|
if (bufferMesh instanceof LinesMesh) {
|
1299
1272
|
// get the color from the lines mesh and set it in the material
|
1300
|
-
|
1273
|
+
const material = {
|
1301
1274
|
name: bufferMesh.name + " material",
|
1302
1275
|
};
|
1303
1276
|
if (!bufferMesh.color.equals(Color3.White()) || bufferMesh.alpha < 1) {
|
@@ -1309,7 +1282,7 @@ var _Exporter = /** @class */ (function () {
|
|
1309
1282
|
materialIndex = this._materials.length - 1;
|
1310
1283
|
}
|
1311
1284
|
else if (babylonMaterial instanceof MultiMaterial) {
|
1312
|
-
|
1285
|
+
const subMaterial = babylonMaterial.subMaterials[submesh.materialIndex];
|
1313
1286
|
if (subMaterial) {
|
1314
1287
|
babylonMaterial = subMaterial;
|
1315
1288
|
materialIndex = this._materialMap[babylonMaterial.uniqueId];
|
@@ -1319,30 +1292,29 @@ var _Exporter = /** @class */ (function () {
|
|
1319
1292
|
materialIndex = this._materialMap[babylonMaterial.uniqueId];
|
1320
1293
|
}
|
1321
1294
|
}
|
1322
|
-
|
1323
|
-
|
1295
|
+
const glTFMaterial = materialIndex != null ? this._materials[materialIndex] : null;
|
1296
|
+
const meshPrimitive = { attributes: {} };
|
1324
1297
|
this._setPrimitiveMode(meshPrimitive, primitiveMode);
|
1325
|
-
for (
|
1326
|
-
|
1327
|
-
var attributeKind = attribute.kind;
|
1298
|
+
for (const attribute of attributeData) {
|
1299
|
+
const attributeKind = attribute.kind;
|
1328
1300
|
if ((attributeKind === VertexBuffer.UVKind || attributeKind === VertexBuffer.UV2Kind) && !this._options.exportUnusedUVs) {
|
1329
1301
|
if (!glTFMaterial || !this._glTFMaterialExporter._hasTexturesPresent(glTFMaterial)) {
|
1330
1302
|
continue;
|
1331
1303
|
}
|
1332
1304
|
}
|
1333
|
-
|
1305
|
+
const vertexData = bufferMesh.getVerticesData(attributeKind);
|
1334
1306
|
if (vertexData) {
|
1335
|
-
|
1307
|
+
const vertexBuffer = this._getVertexBufferFromMesh(attributeKind, bufferMesh);
|
1336
1308
|
if (vertexBuffer) {
|
1337
|
-
|
1338
|
-
|
1309
|
+
const stride = vertexBuffer.getSize();
|
1310
|
+
const bufferViewIndex = attribute.bufferViewIndex;
|
1339
1311
|
if (bufferViewIndex != undefined) {
|
1340
1312
|
// check to see if bufferviewindex has a numeric value assigned.
|
1341
1313
|
minMax = { min: null, max: null };
|
1342
1314
|
if (attributeKind == VertexBuffer.PositionKind) {
|
1343
1315
|
minMax = _GLTFUtilities._CalculateMinMaxPositions(vertexData, 0, vertexData.length / stride, convertToRightHandedSystem);
|
1344
1316
|
}
|
1345
|
-
|
1317
|
+
const accessor = _GLTFUtilities._CreateAccessor(bufferViewIndex, attributeKind + " - " + babylonTransformNode.name, attribute.accessorType, attribute.accessorComponentType, vertexData.length / stride, 0, minMax.min, minMax.max);
|
1346
1318
|
this._accessors.push(accessor);
|
1347
1319
|
this._setAttributeKind(meshPrimitive, attributeKind);
|
1348
1320
|
}
|
@@ -1351,21 +1323,21 @@ var _Exporter = /** @class */ (function () {
|
|
1351
1323
|
}
|
1352
1324
|
if (indexBufferViewIndex) {
|
1353
1325
|
// Create accessor
|
1354
|
-
|
1326
|
+
const accessor = _GLTFUtilities._CreateAccessor(indexBufferViewIndex, "indices - " + babylonTransformNode.name, "SCALAR" /* SCALAR */, 5125 /* UNSIGNED_INT */, submesh.indexCount, submesh.indexStart * 4, null, null);
|
1355
1327
|
this._accessors.push(accessor);
|
1356
1328
|
meshPrimitive.indices = this._accessors.length - 1;
|
1357
1329
|
}
|
1358
1330
|
if (materialIndex != null && Object.keys(meshPrimitive.attributes).length > 0) {
|
1359
|
-
|
1331
|
+
const sideOrientation = bufferMesh.overrideMaterialSideOrientation !== null ? bufferMesh.overrideMaterialSideOrientation : babylonMaterial.sideOrientation;
|
1360
1332
|
if ((sideOrientation == Material.ClockWiseSideOrientation && this._babylonScene.useRightHandedSystem) ||
|
1361
1333
|
(sideOrientation == Material.ClockWiseSideOrientation &&
|
1362
1334
|
convertToRightHandedSystem &&
|
1363
|
-
bufferMesh.overrideMaterialSideOrientation !==
|
1364
|
-
|
1335
|
+
bufferMesh.overrideMaterialSideOrientation !== bufferMesh.material?.sideOrientation)) {
|
1336
|
+
let byteOffset = indexBufferViewIndex != null ? this._bufferViews[indexBufferViewIndex].byteOffset : null;
|
1365
1337
|
if (byteOffset == null) {
|
1366
1338
|
byteOffset = 0;
|
1367
1339
|
}
|
1368
|
-
|
1340
|
+
let babylonIndices = null;
|
1369
1341
|
if (indexBufferViewIndex != null) {
|
1370
1342
|
babylonIndices = bufferMesh.getIndices();
|
1371
1343
|
}
|
@@ -1373,15 +1345,14 @@ var _Exporter = /** @class */ (function () {
|
|
1373
1345
|
this._reorderIndicesBasedOnPrimitiveMode(submesh, primitiveMode, babylonIndices, byteOffset, binaryWriter);
|
1374
1346
|
}
|
1375
1347
|
else {
|
1376
|
-
for (
|
1377
|
-
|
1378
|
-
var vertexData = bufferMesh.getVerticesData(attribute.kind);
|
1348
|
+
for (const attribute of attributeData) {
|
1349
|
+
const vertexData = bufferMesh.getVerticesData(attribute.kind);
|
1379
1350
|
if (vertexData) {
|
1380
|
-
|
1381
|
-
if (!
|
1382
|
-
|
1351
|
+
let byteOffset = this._bufferViews[vertexAttributeBufferViews[attribute.kind]].byteOffset;
|
1352
|
+
if (!byteOffset) {
|
1353
|
+
byteOffset = 0;
|
1383
1354
|
}
|
1384
|
-
this._reorderVertexAttributeDataBasedOnPrimitiveMode(submesh, primitiveMode, sideOrientation, attribute.kind, vertexData,
|
1355
|
+
this._reorderVertexAttributeDataBasedOnPrimitiveMode(submesh, primitiveMode, sideOrientation, attribute.kind, vertexData, byteOffset, binaryWriter, convertToRightHandedSystem);
|
1385
1356
|
}
|
1386
1357
|
}
|
1387
1358
|
}
|
@@ -1389,8 +1360,8 @@ var _Exporter = /** @class */ (function () {
|
|
1389
1360
|
meshPrimitive.material = materialIndex;
|
1390
1361
|
}
|
1391
1362
|
if (morphTargetManager) {
|
1392
|
-
|
1393
|
-
for (
|
1363
|
+
let target;
|
1364
|
+
for (let i = 0; i < morphTargetManager.numTargets; ++i) {
|
1394
1365
|
target = morphTargetManager.getTarget(i);
|
1395
1366
|
this._setMorphTargetAttributes(submesh, meshPrimitive, target, binaryWriter, convertToRightHandedSystem);
|
1396
1367
|
}
|
@@ -1401,22 +1372,22 @@ var _Exporter = /** @class */ (function () {
|
|
1401
1372
|
}
|
1402
1373
|
}
|
1403
1374
|
}
|
1404
|
-
return Promise.all(promises).then(
|
1375
|
+
return Promise.all(promises).then(() => {
|
1405
1376
|
/* do nothing */
|
1406
1377
|
});
|
1407
|
-
}
|
1378
|
+
}
|
1408
1379
|
/**
|
1409
1380
|
* Check if the node is used to convert its descendants from a right handed coordinate system to the Babylon scene's coordinate system.
|
1410
1381
|
* @param node The node to check
|
1411
1382
|
* @returns True if the node is used to convert its descendants from right-handed to left-handed. False otherwise
|
1412
1383
|
*/
|
1413
|
-
|
1384
|
+
_isBabylonCoordinateSystemConvertingNode(node) {
|
1414
1385
|
if (node instanceof TransformNode) {
|
1415
1386
|
if (node.name !== "__root__") {
|
1416
1387
|
return false;
|
1417
1388
|
}
|
1418
1389
|
// Transform
|
1419
|
-
|
1390
|
+
const matrix = node.getWorldMatrix();
|
1420
1391
|
if (matrix.determinant() === 1) {
|
1421
1392
|
return false;
|
1422
1393
|
}
|
@@ -1430,51 +1401,50 @@ var _Exporter = /** @class */ (function () {
|
|
1430
1401
|
return true;
|
1431
1402
|
}
|
1432
1403
|
return false;
|
1433
|
-
}
|
1404
|
+
}
|
1434
1405
|
/**
|
1435
1406
|
* Creates a glTF scene based on the array of meshes
|
1436
1407
|
* Returns the the total byte offset
|
1437
1408
|
* @param babylonScene Babylon scene to get the mesh data from
|
1438
1409
|
* @param binaryWriter Buffer to write binary data to
|
1439
1410
|
*/
|
1440
|
-
|
1441
|
-
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
1447
|
-
var rootNodesToLeftHanded = [];
|
1411
|
+
_createSceneAsync(babylonScene, binaryWriter) {
|
1412
|
+
const scene = { nodes: [] };
|
1413
|
+
let glTFNodeIndex;
|
1414
|
+
let glTFNode;
|
1415
|
+
let directDescendents;
|
1416
|
+
const nodes = [...babylonScene.transformNodes, ...babylonScene.meshes, ...babylonScene.lights, ...babylonScene.cameras];
|
1417
|
+
const rootNodesToLeftHanded = [];
|
1448
1418
|
this._convertToRightHandedSystem = !babylonScene.useRightHandedSystem;
|
1449
1419
|
this._convertToRightHandedSystemMap = {};
|
1450
1420
|
// Set default values for all nodes
|
1451
|
-
babylonScene.rootNodes.forEach(
|
1452
|
-
|
1453
|
-
rootNode.getDescendants(false).forEach(
|
1454
|
-
|
1421
|
+
babylonScene.rootNodes.forEach((rootNode) => {
|
1422
|
+
this._convertToRightHandedSystemMap[rootNode.uniqueId] = this._convertToRightHandedSystem;
|
1423
|
+
rootNode.getDescendants(false).forEach((descendant) => {
|
1424
|
+
this._convertToRightHandedSystemMap[descendant.uniqueId] = this._convertToRightHandedSystem;
|
1455
1425
|
});
|
1456
1426
|
});
|
1457
1427
|
// Check if root nodes converting to left-handed are present
|
1458
|
-
babylonScene.rootNodes.forEach(
|
1459
|
-
if (
|
1428
|
+
babylonScene.rootNodes.forEach((rootNode) => {
|
1429
|
+
if (this._isBabylonCoordinateSystemConvertingNode(rootNode)) {
|
1460
1430
|
rootNodesToLeftHanded.push(rootNode);
|
1461
1431
|
// Exclude the node from list of nodes to export
|
1462
|
-
|
1432
|
+
const indexRootNode = nodes.indexOf(rootNode);
|
1463
1433
|
if (indexRootNode !== -1) {
|
1464
1434
|
// should always be true
|
1465
1435
|
nodes.splice(indexRootNode, 1);
|
1466
1436
|
}
|
1467
1437
|
// Cancel conversion to right handed system
|
1468
|
-
rootNode.getDescendants(false).forEach(
|
1469
|
-
|
1438
|
+
rootNode.getDescendants(false).forEach((descendant) => {
|
1439
|
+
this._convertToRightHandedSystemMap[descendant.uniqueId] = false;
|
1470
1440
|
});
|
1471
1441
|
}
|
1472
1442
|
});
|
1473
1443
|
// Export babylon cameras to glTFCamera
|
1474
|
-
|
1475
|
-
babylonScene.cameras.forEach(
|
1476
|
-
if (!
|
1477
|
-
|
1444
|
+
const cameraMap = new Map();
|
1445
|
+
babylonScene.cameras.forEach((camera) => {
|
1446
|
+
if (!this._options.shouldExportNode || this._options.shouldExportNode(camera)) {
|
1447
|
+
const glTFCamera = {
|
1478
1448
|
type: camera.mode === Camera.PERSPECTIVE_CAMERA ? "perspective" /* PERSPECTIVE */ : "orthographic" /* ORTHOGRAPHIC */,
|
1479
1449
|
};
|
1480
1450
|
if (camera.name) {
|
@@ -1489,8 +1459,8 @@ var _Exporter = /** @class */ (function () {
|
|
1489
1459
|
};
|
1490
1460
|
}
|
1491
1461
|
else if (glTFCamera.type === "orthographic" /* ORTHOGRAPHIC */) {
|
1492
|
-
|
1493
|
-
|
1462
|
+
const halfWidth = camera.orthoLeft && camera.orthoRight ? 0.5 * (camera.orthoRight - camera.orthoLeft) : camera.getEngine().getRenderWidth() * 0.5;
|
1463
|
+
const halfHeight = camera.orthoBottom && camera.orthoTop ? 0.5 * (camera.orthoTop - camera.orthoBottom) : camera.getEngine().getRenderHeight() * 0.5;
|
1494
1464
|
glTFCamera.orthographic = {
|
1495
1465
|
xmag: halfWidth,
|
1496
1466
|
ymag: halfHeight,
|
@@ -1498,28 +1468,27 @@ var _Exporter = /** @class */ (function () {
|
|
1498
1468
|
zfar: camera.maxZ,
|
1499
1469
|
};
|
1500
1470
|
}
|
1501
|
-
cameraMap.set(camera,
|
1502
|
-
|
1471
|
+
cameraMap.set(camera, this._cameras.length);
|
1472
|
+
this._cameras.push(glTFCamera);
|
1503
1473
|
}
|
1504
1474
|
});
|
1505
|
-
|
1506
|
-
return this._glTFMaterialExporter._convertMaterialsToGLTFAsync(exportMaterials, "image/png" /* PNG */, true).then(
|
1507
|
-
return
|
1508
|
-
return
|
1509
|
-
|
1510
|
-
|
1511
|
-
if (
|
1475
|
+
const [exportNodes, exportMaterials] = this._getExportNodes(nodes);
|
1476
|
+
return this._glTFMaterialExporter._convertMaterialsToGLTFAsync(exportMaterials, "image/png" /* PNG */, true).then(() => {
|
1477
|
+
return this._createNodeMapAndAnimationsAsync(babylonScene, exportNodes, binaryWriter).then((nodeMap) => {
|
1478
|
+
return this._createSkinsAsync(babylonScene, nodeMap, binaryWriter).then((skinMap) => {
|
1479
|
+
this._nodeMap = nodeMap;
|
1480
|
+
this._totalByteLength = binaryWriter.getByteOffset();
|
1481
|
+
if (this._totalByteLength == undefined) {
|
1512
1482
|
throw new Error("undefined byte length!");
|
1513
1483
|
}
|
1514
1484
|
// Build Hierarchy with the node map.
|
1515
|
-
for (
|
1516
|
-
|
1517
|
-
glTFNodeIndex = _this._nodeMap[babylonNode.uniqueId];
|
1485
|
+
for (const babylonNode of nodes) {
|
1486
|
+
glTFNodeIndex = this._nodeMap[babylonNode.uniqueId];
|
1518
1487
|
if (glTFNodeIndex !== undefined) {
|
1519
|
-
glTFNode =
|
1488
|
+
glTFNode = this._nodes[glTFNodeIndex];
|
1520
1489
|
if (babylonNode.metadata) {
|
1521
|
-
if (
|
1522
|
-
glTFNode.extras =
|
1490
|
+
if (this._options.metadataSelector) {
|
1491
|
+
glTFNode.extras = this._options.metadataSelector(babylonNode.metadata);
|
1523
1492
|
}
|
1524
1493
|
else if (babylonNode.metadata.gltf) {
|
1525
1494
|
glTFNode.extras = babylonNode.metadata.gltf.extras;
|
@@ -1529,11 +1498,11 @@ var _Exporter = /** @class */ (function () {
|
|
1529
1498
|
glTFNode.camera = cameraMap.get(babylonNode);
|
1530
1499
|
}
|
1531
1500
|
if (!babylonNode.parent || rootNodesToLeftHanded.indexOf(babylonNode.parent) !== -1) {
|
1532
|
-
if (
|
1501
|
+
if (this._options.shouldExportNode && !this._options.shouldExportNode(babylonNode)) {
|
1533
1502
|
Tools.Log("Omitting " + babylonNode.name + " from scene.");
|
1534
1503
|
}
|
1535
1504
|
else {
|
1536
|
-
|
1505
|
+
const convertToRightHandedSystem = this._convertToRightHandedSystemMap[babylonNode.uniqueId];
|
1537
1506
|
if (convertToRightHandedSystem) {
|
1538
1507
|
if (glTFNode.translation) {
|
1539
1508
|
glTFNode.translation[2] *= -1;
|
@@ -1547,18 +1516,17 @@ var _Exporter = /** @class */ (function () {
|
|
1547
1516
|
}
|
1548
1517
|
}
|
1549
1518
|
if (babylonNode instanceof Mesh) {
|
1550
|
-
|
1519
|
+
const babylonMesh = babylonNode;
|
1551
1520
|
if (babylonMesh.skeleton) {
|
1552
1521
|
glTFNode.skin = skinMap[babylonMesh.skeleton.uniqueId];
|
1553
1522
|
}
|
1554
1523
|
}
|
1555
1524
|
directDescendents = babylonNode.getDescendants(true);
|
1556
1525
|
if (!glTFNode.children && directDescendents && directDescendents.length) {
|
1557
|
-
|
1558
|
-
for (
|
1559
|
-
|
1560
|
-
|
1561
|
-
children.push(_this._nodeMap[descendent.uniqueId]);
|
1526
|
+
const children = [];
|
1527
|
+
for (const descendent of directDescendents) {
|
1528
|
+
if (this._nodeMap[descendent.uniqueId] != null) {
|
1529
|
+
children.push(this._nodeMap[descendent.uniqueId]);
|
1562
1530
|
}
|
1563
1531
|
}
|
1564
1532
|
if (children.length) {
|
@@ -1568,31 +1536,29 @@ var _Exporter = /** @class */ (function () {
|
|
1568
1536
|
}
|
1569
1537
|
}
|
1570
1538
|
if (scene.nodes.length) {
|
1571
|
-
|
1539
|
+
this._scenes.push(scene);
|
1572
1540
|
}
|
1573
1541
|
});
|
1574
1542
|
});
|
1575
1543
|
});
|
1576
|
-
}
|
1544
|
+
}
|
1577
1545
|
/**
|
1578
1546
|
* Getting the nodes and materials that would be exported.
|
1579
1547
|
* @param nodes Babylon transform nodes
|
1580
1548
|
* @returns Array of nodes which would be exported.
|
1581
1549
|
* @returns Set of materials which would be exported.
|
1582
1550
|
*/
|
1583
|
-
|
1584
|
-
|
1585
|
-
|
1586
|
-
for (
|
1587
|
-
var babylonNode = nodes_2[_i];
|
1551
|
+
_getExportNodes(nodes) {
|
1552
|
+
const exportNodes = [];
|
1553
|
+
const exportMaterials = new Set();
|
1554
|
+
for (const babylonNode of nodes) {
|
1588
1555
|
if (!this._options.shouldExportNode || this._options.shouldExportNode(babylonNode)) {
|
1589
1556
|
exportNodes.push(babylonNode);
|
1590
|
-
|
1557
|
+
const babylonMesh = babylonNode;
|
1591
1558
|
if (babylonMesh.subMeshes && babylonMesh.subMeshes.length > 0) {
|
1592
|
-
|
1559
|
+
const material = babylonMesh.material || babylonMesh.getScene().defaultMaterial;
|
1593
1560
|
if (material instanceof MultiMaterial) {
|
1594
|
-
for (
|
1595
|
-
var subMaterial = _b[_a];
|
1561
|
+
for (const subMaterial of material.subMaterials) {
|
1596
1562
|
if (subMaterial) {
|
1597
1563
|
exportMaterials.add(subMaterial);
|
1598
1564
|
}
|
@@ -1604,11 +1570,11 @@ var _Exporter = /** @class */ (function () {
|
|
1604
1570
|
}
|
1605
1571
|
}
|
1606
1572
|
else {
|
1607
|
-
|
1573
|
+
`Excluding node ${babylonNode.name}`;
|
1608
1574
|
}
|
1609
1575
|
}
|
1610
1576
|
return [exportNodes, exportMaterials];
|
1611
|
-
}
|
1577
|
+
}
|
1612
1578
|
/**
|
1613
1579
|
* Creates a mapping of Node unique id to node index and handles animations
|
1614
1580
|
* @param babylonScene Babylon Scene
|
@@ -1616,64 +1582,59 @@ var _Exporter = /** @class */ (function () {
|
|
1616
1582
|
* @param binaryWriter Buffer to write binary data to
|
1617
1583
|
* @returns Node mapping of unique id to index
|
1618
1584
|
*/
|
1619
|
-
|
1620
|
-
|
1621
|
-
|
1622
|
-
|
1623
|
-
|
1624
|
-
var runtimeGLTFAnimation = {
|
1585
|
+
_createNodeMapAndAnimationsAsync(babylonScene, nodes, binaryWriter) {
|
1586
|
+
let promiseChain = Promise.resolve();
|
1587
|
+
const nodeMap = {};
|
1588
|
+
let nodeIndex;
|
1589
|
+
const runtimeGLTFAnimation = {
|
1625
1590
|
name: "runtime animations",
|
1626
1591
|
channels: [],
|
1627
1592
|
samplers: [],
|
1628
1593
|
};
|
1629
|
-
|
1630
|
-
|
1631
|
-
promiseChain = promiseChain.then(
|
1632
|
-
|
1633
|
-
return
|
1634
|
-
|
1594
|
+
const idleGLTFAnimations = [];
|
1595
|
+
for (const babylonNode of nodes) {
|
1596
|
+
promiseChain = promiseChain.then(() => {
|
1597
|
+
const convertToRightHandedSystem = this._convertToRightHandedSystemMap[babylonNode.uniqueId];
|
1598
|
+
return this._createNodeAsync(babylonNode, binaryWriter, convertToRightHandedSystem).then((node) => {
|
1599
|
+
const promise = this._extensionsPostExportNodeAsync("createNodeAsync", node, babylonNode, nodeMap, binaryWriter);
|
1635
1600
|
if (promise == null) {
|
1636
|
-
Tools.Warn(
|
1601
|
+
Tools.Warn(`Not exporting node ${babylonNode.name}`);
|
1637
1602
|
return Promise.resolve();
|
1638
1603
|
}
|
1639
1604
|
else {
|
1640
|
-
return promise.then(
|
1605
|
+
return promise.then((node) => {
|
1641
1606
|
if (!node) {
|
1642
1607
|
return;
|
1643
1608
|
}
|
1644
|
-
|
1645
|
-
nodeIndex =
|
1609
|
+
this._nodes.push(node);
|
1610
|
+
nodeIndex = this._nodes.length - 1;
|
1646
1611
|
nodeMap[babylonNode.uniqueId] = nodeIndex;
|
1647
1612
|
if (!babylonScene.animationGroups.length) {
|
1648
|
-
_GLTFAnimation._CreateMorphTargetAnimationFromMorphTargetAnimations(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap,
|
1613
|
+
_GLTFAnimation._CreateMorphTargetAnimationFromMorphTargetAnimations(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, this._nodes, binaryWriter, this._bufferViews, this._accessors, convertToRightHandedSystem, this._animationSampleRate);
|
1649
1614
|
if (babylonNode.animations.length) {
|
1650
|
-
_GLTFAnimation._CreateNodeAnimationFromNodeAnimations(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap,
|
1615
|
+
_GLTFAnimation._CreateNodeAnimationFromNodeAnimations(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, this._nodes, binaryWriter, this._bufferViews, this._accessors, convertToRightHandedSystem, this._animationSampleRate);
|
1651
1616
|
}
|
1652
1617
|
}
|
1653
1618
|
});
|
1654
1619
|
}
|
1655
1620
|
});
|
1656
1621
|
});
|
1657
|
-
};
|
1658
|
-
for (var _i = 0, nodes_3 = nodes; _i < nodes_3.length; _i++) {
|
1659
|
-
var babylonNode = nodes_3[_i];
|
1660
|
-
_loop_1(babylonNode);
|
1661
1622
|
}
|
1662
|
-
return promiseChain.then(
|
1623
|
+
return promiseChain.then(() => {
|
1663
1624
|
if (runtimeGLTFAnimation.channels.length && runtimeGLTFAnimation.samplers.length) {
|
1664
|
-
|
1625
|
+
this._animations.push(runtimeGLTFAnimation);
|
1665
1626
|
}
|
1666
|
-
idleGLTFAnimations.forEach(
|
1627
|
+
idleGLTFAnimations.forEach((idleGLTFAnimation) => {
|
1667
1628
|
if (idleGLTFAnimation.channels.length && idleGLTFAnimation.samplers.length) {
|
1668
|
-
|
1629
|
+
this._animations.push(idleGLTFAnimation);
|
1669
1630
|
}
|
1670
1631
|
});
|
1671
1632
|
if (babylonScene.animationGroups.length) {
|
1672
|
-
_GLTFAnimation._CreateNodeAndMorphAnimationFromAnimationGroups(babylonScene,
|
1633
|
+
_GLTFAnimation._CreateNodeAndMorphAnimationFromAnimationGroups(babylonScene, this._animations, nodeMap, this._nodes, binaryWriter, this._bufferViews, this._accessors, this._convertToRightHandedSystemMap, this._animationSampleRate);
|
1673
1634
|
}
|
1674
1635
|
return nodeMap;
|
1675
1636
|
});
|
1676
|
-
}
|
1637
|
+
}
|
1677
1638
|
/**
|
1678
1639
|
* Creates a glTF node from a Babylon mesh
|
1679
1640
|
* @param babylonNode Source Babylon mesh
|
@@ -1681,45 +1642,44 @@ var _Exporter = /** @class */ (function () {
|
|
1681
1642
|
* @param convertToRightHandedSystem Converts the values to right-handed
|
1682
1643
|
* @returns glTF node
|
1683
1644
|
*/
|
1684
|
-
|
1685
|
-
|
1686
|
-
return Promise.resolve().then(function () {
|
1645
|
+
_createNodeAsync(babylonNode, binaryWriter, convertToRightHandedSystem) {
|
1646
|
+
return Promise.resolve().then(() => {
|
1687
1647
|
// create node to hold translation/rotation/scale and the mesh
|
1688
|
-
|
1648
|
+
const node = {};
|
1689
1649
|
// create mesh
|
1690
|
-
|
1650
|
+
const mesh = { primitives: [] };
|
1691
1651
|
if (babylonNode.name) {
|
1692
1652
|
node.name = babylonNode.name;
|
1693
1653
|
}
|
1694
1654
|
if (babylonNode instanceof TransformNode) {
|
1695
1655
|
// Set transformation
|
1696
|
-
|
1656
|
+
this._setNodeTransformation(node, babylonNode, convertToRightHandedSystem);
|
1697
1657
|
if (babylonNode instanceof Mesh) {
|
1698
|
-
|
1658
|
+
const morphTargetManager = babylonNode.morphTargetManager;
|
1699
1659
|
if (morphTargetManager && morphTargetManager.numTargets > 0) {
|
1700
1660
|
mesh.weights = [];
|
1701
|
-
for (
|
1661
|
+
for (let i = 0; i < morphTargetManager.numTargets; ++i) {
|
1702
1662
|
mesh.weights.push(morphTargetManager.getTarget(i).influence);
|
1703
1663
|
}
|
1704
1664
|
}
|
1705
1665
|
}
|
1706
|
-
return
|
1666
|
+
return this._setPrimitiveAttributesAsync(mesh, babylonNode, binaryWriter, convertToRightHandedSystem).then(() => {
|
1707
1667
|
if (mesh.primitives.length) {
|
1708
|
-
|
1709
|
-
node.mesh =
|
1668
|
+
this._meshes.push(mesh);
|
1669
|
+
node.mesh = this._meshes.length - 1;
|
1710
1670
|
}
|
1711
1671
|
return node;
|
1712
1672
|
});
|
1713
1673
|
}
|
1714
1674
|
else if (babylonNode instanceof Camera) {
|
1715
|
-
|
1675
|
+
this._setCameraTransformation(node, babylonNode, convertToRightHandedSystem);
|
1716
1676
|
return node;
|
1717
1677
|
}
|
1718
1678
|
else {
|
1719
1679
|
return node;
|
1720
1680
|
}
|
1721
1681
|
});
|
1722
|
-
}
|
1682
|
+
}
|
1723
1683
|
/**
|
1724
1684
|
* Creates a glTF skin from a Babylon skeleton
|
1725
1685
|
* @param babylonScene Babylon Scene
|
@@ -1727,23 +1687,21 @@ var _Exporter = /** @class */ (function () {
|
|
1727
1687
|
* @param binaryWriter Buffer to write binary data to
|
1728
1688
|
* @returns Node mapping of unique id to index
|
1729
1689
|
*/
|
1730
|
-
|
1731
|
-
|
1732
|
-
|
1733
|
-
|
1734
|
-
for (var _i = 0, _b = babylonScene.skeletons; _i < _b.length; _i++) {
|
1735
|
-
var skeleton = _b[_i];
|
1690
|
+
_createSkinsAsync(babylonScene, nodeMap, binaryWriter) {
|
1691
|
+
const promiseChain = Promise.resolve();
|
1692
|
+
const skinMap = {};
|
1693
|
+
for (const skeleton of babylonScene.skeletons) {
|
1736
1694
|
if (skeleton.bones.length <= 0) {
|
1737
1695
|
continue;
|
1738
1696
|
}
|
1739
1697
|
// create skin
|
1740
|
-
|
1741
|
-
|
1742
|
-
|
1743
|
-
|
1744
|
-
for (
|
1745
|
-
|
1746
|
-
|
1698
|
+
const skin = { joints: [] };
|
1699
|
+
const inverseBindMatrices = [];
|
1700
|
+
const boneIndexMap = {};
|
1701
|
+
let maxBoneIndex = -1;
|
1702
|
+
for (let i = 0; i < skeleton.bones.length; ++i) {
|
1703
|
+
const bone = skeleton.bones[i];
|
1704
|
+
const boneIndex = bone.getIndex() ?? i;
|
1747
1705
|
if (boneIndex !== -1) {
|
1748
1706
|
boneIndexMap[boneIndex] = bone;
|
1749
1707
|
if (boneIndex > maxBoneIndex) {
|
@@ -1751,10 +1709,10 @@ var _Exporter = /** @class */ (function () {
|
|
1751
1709
|
}
|
1752
1710
|
}
|
1753
1711
|
}
|
1754
|
-
for (
|
1755
|
-
|
1712
|
+
for (let boneIndex = 0; boneIndex <= maxBoneIndex; ++boneIndex) {
|
1713
|
+
const bone = boneIndexMap[boneIndex];
|
1756
1714
|
inverseBindMatrices.push(bone.getInvertedAbsoluteTransform());
|
1757
|
-
|
1715
|
+
const transformNode = bone.getTransformNode();
|
1758
1716
|
if (transformNode) {
|
1759
1717
|
skin.joints.push(nodeMap[transformNode.uniqueId]);
|
1760
1718
|
}
|
@@ -1763,43 +1721,41 @@ var _Exporter = /** @class */ (function () {
|
|
1763
1721
|
}
|
1764
1722
|
}
|
1765
1723
|
// create buffer view for inverse bind matrices
|
1766
|
-
|
1767
|
-
|
1768
|
-
|
1769
|
-
|
1724
|
+
const byteStride = 64; // 4 x 4 matrix of 32 bit float
|
1725
|
+
const byteLength = inverseBindMatrices.length * byteStride;
|
1726
|
+
const bufferViewOffset = binaryWriter.getByteOffset();
|
1727
|
+
const bufferView = _GLTFUtilities._CreateBufferView(0, bufferViewOffset, byteLength, undefined, "InverseBindMatrices" + " - " + skeleton.name);
|
1770
1728
|
this._bufferViews.push(bufferView);
|
1771
|
-
|
1772
|
-
|
1773
|
-
|
1729
|
+
const bufferViewIndex = this._bufferViews.length - 1;
|
1730
|
+
const bindMatrixAccessor = _GLTFUtilities._CreateAccessor(bufferViewIndex, "InverseBindMatrices" + " - " + skeleton.name, "MAT4" /* MAT4 */, 5126 /* FLOAT */, inverseBindMatrices.length, null, null, null);
|
1731
|
+
const inverseBindAccessorIndex = this._accessors.push(bindMatrixAccessor) - 1;
|
1774
1732
|
skin.inverseBindMatrices = inverseBindAccessorIndex;
|
1775
1733
|
this._skins.push(skin);
|
1776
1734
|
skinMap[skeleton.uniqueId] = this._skins.length - 1;
|
1777
|
-
inverseBindMatrices.forEach(
|
1778
|
-
mat.m.forEach(
|
1735
|
+
inverseBindMatrices.forEach((mat) => {
|
1736
|
+
mat.m.forEach((cell) => {
|
1779
1737
|
binaryWriter.setFloat32(cell);
|
1780
1738
|
});
|
1781
1739
|
});
|
1782
1740
|
}
|
1783
|
-
return promiseChain.then(
|
1741
|
+
return promiseChain.then(() => {
|
1784
1742
|
return skinMap;
|
1785
1743
|
});
|
1786
|
-
}
|
1787
|
-
|
1788
|
-
|
1789
|
-
|
1790
|
-
}());
|
1791
|
-
export { _Exporter };
|
1744
|
+
}
|
1745
|
+
}
|
1746
|
+
_Exporter._ExtensionNames = new Array();
|
1747
|
+
_Exporter._ExtensionFactories = {};
|
1792
1748
|
/**
|
1793
1749
|
* @hidden
|
1794
1750
|
*
|
1795
1751
|
* Stores glTF binary data. If the array buffer byte length is exceeded, it doubles in size dynamically
|
1796
1752
|
*/
|
1797
|
-
|
1753
|
+
export class _BinaryWriter {
|
1798
1754
|
/**
|
1799
1755
|
* Initialize binary writer with an initial byte length
|
1800
1756
|
* @param byteLength Initial byte length of the array buffer
|
1801
1757
|
*/
|
1802
|
-
|
1758
|
+
constructor(byteLength) {
|
1803
1759
|
this._arrayBuffer = new ArrayBuffer(byteLength);
|
1804
1760
|
this._dataView = new DataView(this._arrayBuffer);
|
1805
1761
|
this._byteOffset = 0;
|
@@ -1808,40 +1764,40 @@ var _BinaryWriter = /** @class */ (function () {
|
|
1808
1764
|
* Resize the array buffer to the specified byte length
|
1809
1765
|
* @param byteLength
|
1810
1766
|
*/
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
1815
|
-
for (
|
1767
|
+
_resizeBuffer(byteLength) {
|
1768
|
+
const newBuffer = new ArrayBuffer(byteLength);
|
1769
|
+
const oldUint8Array = new Uint8Array(this._arrayBuffer);
|
1770
|
+
const newUint8Array = new Uint8Array(newBuffer);
|
1771
|
+
for (let i = 0, length = newUint8Array.byteLength; i < length; ++i) {
|
1816
1772
|
newUint8Array[i] = oldUint8Array[i];
|
1817
1773
|
}
|
1818
1774
|
this._arrayBuffer = newBuffer;
|
1819
1775
|
this._dataView = new DataView(this._arrayBuffer);
|
1820
1776
|
return newBuffer;
|
1821
|
-
}
|
1777
|
+
}
|
1822
1778
|
/**
|
1823
1779
|
* Get an array buffer with the length of the byte offset
|
1824
1780
|
* @returns ArrayBuffer resized to the byte offset
|
1825
1781
|
*/
|
1826
|
-
|
1782
|
+
getArrayBuffer() {
|
1827
1783
|
return this._resizeBuffer(this.getByteOffset());
|
1828
|
-
}
|
1784
|
+
}
|
1829
1785
|
/**
|
1830
1786
|
* Get the byte offset of the array buffer
|
1831
1787
|
* @returns byte offset
|
1832
1788
|
*/
|
1833
|
-
|
1789
|
+
getByteOffset() {
|
1834
1790
|
if (this._byteOffset == undefined) {
|
1835
1791
|
throw new Error("Byte offset is undefined!");
|
1836
1792
|
}
|
1837
1793
|
return this._byteOffset;
|
1838
|
-
}
|
1794
|
+
}
|
1839
1795
|
/**
|
1840
1796
|
* Stores an UInt8 in the array buffer
|
1841
1797
|
* @param entry
|
1842
1798
|
* @param byteOffset If defined, specifies where to set the value as an offset.
|
1843
1799
|
*/
|
1844
|
-
|
1800
|
+
setUInt8(entry, byteOffset) {
|
1845
1801
|
if (byteOffset != null) {
|
1846
1802
|
if (byteOffset < this._byteOffset) {
|
1847
1803
|
this._dataView.setUint8(byteOffset, entry);
|
@@ -1857,13 +1813,13 @@ var _BinaryWriter = /** @class */ (function () {
|
|
1857
1813
|
this._dataView.setUint8(this._byteOffset, entry);
|
1858
1814
|
this._byteOffset += 1;
|
1859
1815
|
}
|
1860
|
-
}
|
1816
|
+
}
|
1861
1817
|
/**
|
1862
1818
|
* Stores an UInt16 in the array buffer
|
1863
1819
|
* @param entry
|
1864
1820
|
* @param byteOffset If defined, specifies where to set the value as an offset.
|
1865
1821
|
*/
|
1866
|
-
|
1822
|
+
setUInt16(entry, byteOffset) {
|
1867
1823
|
if (byteOffset != null) {
|
1868
1824
|
if (byteOffset < this._byteOffset) {
|
1869
1825
|
this._dataView.setUint16(byteOffset, entry, true);
|
@@ -1879,12 +1835,12 @@ var _BinaryWriter = /** @class */ (function () {
|
|
1879
1835
|
this._dataView.setUint16(this._byteOffset, entry, true);
|
1880
1836
|
this._byteOffset += 2;
|
1881
1837
|
}
|
1882
|
-
}
|
1838
|
+
}
|
1883
1839
|
/**
|
1884
1840
|
* Gets an UInt32 in the array buffer
|
1885
1841
|
* @param byteOffset If defined, specifies where to set the value as an offset.
|
1886
1842
|
*/
|
1887
|
-
|
1843
|
+
getUInt32(byteOffset) {
|
1888
1844
|
if (byteOffset < this._byteOffset) {
|
1889
1845
|
return this._dataView.getUint32(byteOffset, true);
|
1890
1846
|
}
|
@@ -1892,30 +1848,30 @@ var _BinaryWriter = /** @class */ (function () {
|
|
1892
1848
|
Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!");
|
1893
1849
|
throw new Error("BinaryWriter: byteoffset is greater than the current binary buffer length!");
|
1894
1850
|
}
|
1895
|
-
}
|
1896
|
-
|
1851
|
+
}
|
1852
|
+
getVector3Float32FromRef(vector3, byteOffset) {
|
1897
1853
|
if (byteOffset + 8 > this._byteOffset) {
|
1898
|
-
Tools.Error(
|
1854
|
+
Tools.Error(`BinaryWriter: byteoffset is greater than the current binary buffer length!`);
|
1899
1855
|
}
|
1900
1856
|
else {
|
1901
1857
|
vector3.x = this._dataView.getFloat32(byteOffset, true);
|
1902
1858
|
vector3.y = this._dataView.getFloat32(byteOffset + 4, true);
|
1903
1859
|
vector3.z = this._dataView.getFloat32(byteOffset + 8, true);
|
1904
1860
|
}
|
1905
|
-
}
|
1906
|
-
|
1861
|
+
}
|
1862
|
+
setVector3Float32FromRef(vector3, byteOffset) {
|
1907
1863
|
if (byteOffset + 8 > this._byteOffset) {
|
1908
|
-
Tools.Error(
|
1864
|
+
Tools.Error(`BinaryWriter: byteoffset is greater than the current binary buffer length!`);
|
1909
1865
|
}
|
1910
1866
|
else {
|
1911
1867
|
this._dataView.setFloat32(byteOffset, vector3.x, true);
|
1912
1868
|
this._dataView.setFloat32(byteOffset + 4, vector3.y, true);
|
1913
1869
|
this._dataView.setFloat32(byteOffset + 8, vector3.z, true);
|
1914
1870
|
}
|
1915
|
-
}
|
1916
|
-
|
1871
|
+
}
|
1872
|
+
getVector4Float32FromRef(vector4, byteOffset) {
|
1917
1873
|
if (byteOffset + 12 > this._byteOffset) {
|
1918
|
-
Tools.Error(
|
1874
|
+
Tools.Error(`BinaryWriter: byteoffset is greater than the current binary buffer length!`);
|
1919
1875
|
}
|
1920
1876
|
else {
|
1921
1877
|
vector4.x = this._dataView.getFloat32(byteOffset, true);
|
@@ -1923,10 +1879,10 @@ var _BinaryWriter = /** @class */ (function () {
|
|
1923
1879
|
vector4.z = this._dataView.getFloat32(byteOffset + 8, true);
|
1924
1880
|
vector4.w = this._dataView.getFloat32(byteOffset + 12, true);
|
1925
1881
|
}
|
1926
|
-
}
|
1927
|
-
|
1882
|
+
}
|
1883
|
+
setVector4Float32FromRef(vector4, byteOffset) {
|
1928
1884
|
if (byteOffset + 12 > this._byteOffset) {
|
1929
|
-
Tools.Error(
|
1885
|
+
Tools.Error(`BinaryWriter: byteoffset is greater than the current binary buffer length!`);
|
1930
1886
|
}
|
1931
1887
|
else {
|
1932
1888
|
this._dataView.setFloat32(byteOffset, vector4.x, true);
|
@@ -1934,13 +1890,13 @@ var _BinaryWriter = /** @class */ (function () {
|
|
1934
1890
|
this._dataView.setFloat32(byteOffset + 8, vector4.z, true);
|
1935
1891
|
this._dataView.setFloat32(byteOffset + 12, vector4.w, true);
|
1936
1892
|
}
|
1937
|
-
}
|
1893
|
+
}
|
1938
1894
|
/**
|
1939
1895
|
* Stores a Float32 in the array buffer
|
1940
1896
|
* @param entry
|
1941
1897
|
* @param byteOffset
|
1942
1898
|
*/
|
1943
|
-
|
1899
|
+
setFloat32(entry, byteOffset) {
|
1944
1900
|
if (isNaN(entry)) {
|
1945
1901
|
Tools.Error("Invalid data being written!");
|
1946
1902
|
}
|
@@ -1957,13 +1913,13 @@ var _BinaryWriter = /** @class */ (function () {
|
|
1957
1913
|
}
|
1958
1914
|
this._dataView.setFloat32(this._byteOffset, entry, true);
|
1959
1915
|
this._byteOffset += 4;
|
1960
|
-
}
|
1916
|
+
}
|
1961
1917
|
/**
|
1962
1918
|
* Stores an UInt32 in the array buffer
|
1963
1919
|
* @param entry
|
1964
1920
|
* @param byteOffset If defined, specifies where to set the value as an offset.
|
1965
1921
|
*/
|
1966
|
-
|
1922
|
+
setUInt32(entry, byteOffset) {
|
1967
1923
|
if (byteOffset != null) {
|
1968
1924
|
if (byteOffset < this._byteOffset) {
|
1969
1925
|
this._dataView.setUint32(byteOffset, entry, true);
|
@@ -1979,13 +1935,13 @@ var _BinaryWriter = /** @class */ (function () {
|
|
1979
1935
|
this._dataView.setUint32(this._byteOffset, entry, true);
|
1980
1936
|
this._byteOffset += 4;
|
1981
1937
|
}
|
1982
|
-
}
|
1938
|
+
}
|
1983
1939
|
/**
|
1984
1940
|
* Stores an Int16 in the array buffer
|
1985
1941
|
* @param entry
|
1986
1942
|
* @param byteOffset If defined, specifies where to set the value as an offset.
|
1987
1943
|
*/
|
1988
|
-
|
1944
|
+
setInt16(entry, byteOffset) {
|
1989
1945
|
if (byteOffset != null) {
|
1990
1946
|
if (byteOffset < this._byteOffset) {
|
1991
1947
|
this._dataView.setInt16(byteOffset, entry, true);
|
@@ -2001,13 +1957,13 @@ var _BinaryWriter = /** @class */ (function () {
|
|
2001
1957
|
this._dataView.setInt16(this._byteOffset, entry, true);
|
2002
1958
|
this._byteOffset += 2;
|
2003
1959
|
}
|
2004
|
-
}
|
1960
|
+
}
|
2005
1961
|
/**
|
2006
1962
|
* Stores a byte in the array buffer
|
2007
1963
|
* @param entry
|
2008
1964
|
* @param byteOffset If defined, specifies where to set the value as an offset.
|
2009
1965
|
*/
|
2010
|
-
|
1966
|
+
setByte(entry, byteOffset) {
|
2011
1967
|
if (byteOffset != null) {
|
2012
1968
|
if (byteOffset < this._byteOffset) {
|
2013
1969
|
this._dataView.setInt8(byteOffset, entry);
|
@@ -2023,8 +1979,6 @@ var _BinaryWriter = /** @class */ (function () {
|
|
2023
1979
|
this._dataView.setInt8(this._byteOffset, entry);
|
2024
1980
|
this._byteOffset++;
|
2025
1981
|
}
|
2026
|
-
}
|
2027
|
-
|
2028
|
-
}());
|
2029
|
-
export { _BinaryWriter };
|
1982
|
+
}
|
1983
|
+
}
|
2030
1984
|
//# sourceMappingURL=glTFExporter.js.map
|