@babylonjs/serializers 7.44.0 → 7.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.d.ts +3 -3
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.js +10 -42
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_draco_mesh_compression.d.ts +32 -0
- package/glTF/2.0/Extensions/KHR_draco_mesh_compression.js +136 -0
- package/glTF/2.0/Extensions/KHR_draco_mesh_compression.js.map +1 -0
- package/glTF/2.0/Extensions/index.d.ts +1 -0
- package/glTF/2.0/Extensions/index.js +1 -0
- package/glTF/2.0/Extensions/index.js.map +1 -1
- package/glTF/2.0/bufferManager.d.ts +68 -0
- package/glTF/2.0/bufferManager.js +152 -0
- package/glTF/2.0/bufferManager.js.map +1 -0
- package/glTF/2.0/dataWriter.d.ts +5 -3
- package/glTF/2.0/dataWriter.js +30 -12
- package/glTF/2.0/dataWriter.js.map +1 -1
- package/glTF/2.0/glTFAnimation.d.ts +7 -7
- package/glTF/2.0/glTFAnimation.js +30 -51
- package/glTF/2.0/glTFAnimation.js.map +1 -1
- package/glTF/2.0/glTFExporter.d.ts +5 -4
- package/glTF/2.0/glTFExporter.js +89 -137
- package/glTF/2.0/glTFExporter.js.map +1 -1
- package/glTF/2.0/glTFExporterExtension.d.ts +14 -10
- package/glTF/2.0/glTFExporterExtension.js.map +1 -1
- package/glTF/2.0/glTFMaterialExporter.js +25 -15
- package/glTF/2.0/glTFMaterialExporter.js.map +1 -1
- package/glTF/2.0/glTFMorphTargetsUtilities.d.ts +2 -2
- package/glTF/2.0/glTFMorphTargetsUtilities.js +23 -25
- package/glTF/2.0/glTFMorphTargetsUtilities.js.map +1 -1
- package/glTF/2.0/glTFSerializer.d.ts +8 -0
- package/glTF/2.0/glTFSerializer.js.map +1 -1
- package/glTF/2.0/glTFUtilities.d.ts +11 -27
- package/glTF/2.0/glTFUtilities.js +17 -49
- package/glTF/2.0/glTFUtilities.js.map +1 -1
- package/package.json +3 -3
package/glTF/2.0/glTFExporter.js
CHANGED
@@ -9,8 +9,8 @@ import { Engine } from "@babylonjs/core/Engines/engine.js";
|
|
9
9
|
import { EngineStore } from "@babylonjs/core/Engines/engineStore.js";
|
10
10
|
import { GLTFMaterialExporter } from "./glTFMaterialExporter.js";
|
11
11
|
import { GLTFData } from "./glTFData.js";
|
12
|
-
import { ConvertToRightHandedPosition, ConvertToRightHandedRotation,
|
13
|
-
import {
|
12
|
+
import { ConvertToRightHandedPosition, ConvertToRightHandedRotation, DataArrayToUint8Array, GetAccessorType, GetAttributeType, GetMinMax, GetPrimitiveMode, IsNoopNode, IsTriangleFillMode, IsParentAddedByImporter, ConvertToRightHandedNode, RotateNode180Y, FloatsNeed16BitInteger, IsStandardVertexAttribute, IndicesArrayToTypedArray, } from "./glTFUtilities.js";
|
13
|
+
import { BufferManager } from "./bufferManager.js";
|
14
14
|
import { Camera } from "@babylonjs/core/Cameras/camera.js";
|
15
15
|
import { MultiMaterial } from "@babylonjs/core/Materials/multiMaterial.js";
|
16
16
|
import { PBRMaterial } from "@babylonjs/core/Materials/PBR/pbrMaterial.js";
|
@@ -26,7 +26,7 @@ class ExporterState {
|
|
26
26
|
constructor(convertToRightHanded, wasAddedByNoopNode) {
|
27
27
|
// Babylon indices array, start, count, offset, flip -> glTF accessor index
|
28
28
|
this._indicesAccessorMap = new Map();
|
29
|
-
// Babylon buffer -> glTF buffer view
|
29
|
+
// Babylon buffer -> glTF buffer view
|
30
30
|
this._vertexBufferViewMap = new Map();
|
31
31
|
// Babylon vertex buffer, start, count -> glTF accessor index
|
32
32
|
this._vertexAccessorMap = new Map();
|
@@ -78,12 +78,12 @@ class ExporterState {
|
|
78
78
|
getVertexBufferView(buffer) {
|
79
79
|
return this._vertexBufferViewMap.get(buffer);
|
80
80
|
}
|
81
|
-
setVertexBufferView(buffer,
|
82
|
-
this._vertexBufferViewMap.set(buffer,
|
81
|
+
setVertexBufferView(buffer, bufferView) {
|
82
|
+
this._vertexBufferViewMap.set(buffer, bufferView);
|
83
83
|
}
|
84
|
-
setRemappedBufferView(buffer, vertexBuffer,
|
84
|
+
setRemappedBufferView(buffer, vertexBuffer, bufferView) {
|
85
85
|
this._remappedBufferView.set(buffer, new Map());
|
86
|
-
this._remappedBufferView.get(buffer).set(vertexBuffer,
|
86
|
+
this._remappedBufferView.get(buffer).set(vertexBuffer, bufferView);
|
87
87
|
}
|
88
88
|
getRemappedBufferView(buffer, vertexBuffer) {
|
89
89
|
return this._remappedBufferView.get(buffer)?.get(vertexBuffer);
|
@@ -149,11 +149,8 @@ export class GLTFExporter {
|
|
149
149
|
_extensionsPreExportTextureAsync(context, babylonTexture, mimeType) {
|
150
150
|
return this._applyExtensions(babylonTexture, (extension, node) => extension.preExportTextureAsync && extension.preExportTextureAsync(context, node, mimeType));
|
151
151
|
}
|
152
|
-
_extensionsPostExportMeshPrimitiveAsync(context, meshPrimitive, babylonSubMesh) {
|
153
|
-
return this._applyExtensions(meshPrimitive, (extension, node) => extension.postExportMeshPrimitiveAsync && extension.postExportMeshPrimitiveAsync(context, node, babylonSubMesh));
|
154
|
-
}
|
155
152
|
_extensionsPostExportNodeAsync(context, node, babylonNode, nodeMap, convertToRightHanded) {
|
156
|
-
return this._applyExtensions(node, (extension, node) => extension.postExportNodeAsync && extension.postExportNodeAsync(context, node, babylonNode, nodeMap, convertToRightHanded, this.
|
153
|
+
return this._applyExtensions(node, (extension, node) => extension.postExportNodeAsync && extension.postExportNodeAsync(context, node, babylonNode, nodeMap, convertToRightHanded, this._bufferManager));
|
157
154
|
}
|
158
155
|
_extensionsPostExportMaterialAsync(context, material, babylonMaterial) {
|
159
156
|
return this._applyExtensions(material, (extension, node) => extension.postExportMaterialAsync && extension.postExportMaterialAsync(context, node, babylonMaterial));
|
@@ -176,6 +173,22 @@ export class GLTFExporter {
|
|
176
173
|
}
|
177
174
|
}
|
178
175
|
}
|
176
|
+
_extensionsPostExportMeshPrimitive(primitive) {
|
177
|
+
for (const name of GLTFExporter._ExtensionNames) {
|
178
|
+
const extension = this._extensions[name];
|
179
|
+
if (extension.postExportMeshPrimitive) {
|
180
|
+
extension.postExportMeshPrimitive(primitive, this._bufferManager, this._accessors);
|
181
|
+
}
|
182
|
+
}
|
183
|
+
}
|
184
|
+
async _extensionsPreGenerateBinaryAsync() {
|
185
|
+
for (const name of GLTFExporter._ExtensionNames) {
|
186
|
+
const extension = this._extensions[name];
|
187
|
+
if (extension.preGenerateBinaryAsync) {
|
188
|
+
await extension.preGenerateBinaryAsync(this._bufferManager);
|
189
|
+
}
|
190
|
+
}
|
191
|
+
}
|
179
192
|
_forEachExtensions(action) {
|
180
193
|
for (const name of GLTFExporter._ExtensionNames) {
|
181
194
|
const extension = this._extensions[name];
|
@@ -228,10 +241,10 @@ export class GLTFExporter {
|
|
228
241
|
this._skins = [];
|
229
242
|
this._textures = [];
|
230
243
|
this._imageData = {};
|
231
|
-
this.
|
244
|
+
this._shouldUseGlb = false;
|
232
245
|
this._materialExporter = new GLTFMaterialExporter(this);
|
233
246
|
this._extensions = {};
|
234
|
-
this.
|
247
|
+
this._bufferManager = new BufferManager();
|
235
248
|
this._shouldExportNodeMap = new Map();
|
236
249
|
// Babylon node -> glTF node index
|
237
250
|
this._nodeMap = new Map();
|
@@ -256,6 +269,7 @@ export class GLTFExporter {
|
|
256
269
|
exportUnusedUVs: false,
|
257
270
|
removeNoopRootNodes: true,
|
258
271
|
includeCoordinateSystemConversionNodes: false,
|
272
|
+
meshCompressionMethod: "None",
|
259
273
|
...options,
|
260
274
|
};
|
261
275
|
this._loadExtensions();
|
@@ -287,11 +301,8 @@ export class GLTFExporter {
|
|
287
301
|
}
|
288
302
|
return true;
|
289
303
|
}
|
290
|
-
_generateJSON(
|
304
|
+
_generateJSON(bufferByteLength, fileName, prettyPrint) {
|
291
305
|
const buffer = { byteLength: bufferByteLength };
|
292
|
-
let imageData;
|
293
|
-
let bufferView;
|
294
|
-
let byteOffset = bufferByteLength;
|
295
306
|
if (buffer.byteLength) {
|
296
307
|
this._glTF.buffers = [buffer];
|
297
308
|
}
|
@@ -330,30 +341,9 @@ export class GLTFExporter {
|
|
330
341
|
this._glTF.skins = this._skins;
|
331
342
|
}
|
332
343
|
if (this._images && this._images.length) {
|
333
|
-
|
334
|
-
this._glTF.images = this._images;
|
335
|
-
}
|
336
|
-
else {
|
337
|
-
this._glTF.images = [];
|
338
|
-
this._images.forEach((image) => {
|
339
|
-
if (image.uri) {
|
340
|
-
imageData = this._imageData[image.uri];
|
341
|
-
this._orderedImageData.push(imageData);
|
342
|
-
bufferView = CreateBufferView(0, byteOffset, imageData.data.byteLength, undefined);
|
343
|
-
byteOffset += imageData.data.byteLength;
|
344
|
-
this._bufferViews.push(bufferView);
|
345
|
-
image.bufferView = this._bufferViews.length - 1;
|
346
|
-
image.name = fileName;
|
347
|
-
image.mimeType = imageData.mimeType;
|
348
|
-
image.uri = undefined;
|
349
|
-
this._glTF.images.push(image);
|
350
|
-
}
|
351
|
-
});
|
352
|
-
// Replace uri with bufferview and mime type for glb
|
353
|
-
buffer.byteLength = byteOffset;
|
354
|
-
}
|
344
|
+
this._glTF.images = this._images;
|
355
345
|
}
|
356
|
-
if (!
|
346
|
+
if (!this._shouldUseGlb) {
|
357
347
|
buffer.uri = fileName + ".bin";
|
358
348
|
}
|
359
349
|
return prettyPrint ? JSON.stringify(this._glTF, null, 2) : JSON.stringify(this._glTF);
|
@@ -361,7 +351,7 @@ export class GLTFExporter {
|
|
361
351
|
async generateGLTFAsync(glTFPrefix) {
|
362
352
|
const binaryBuffer = await this._generateBinaryAsync();
|
363
353
|
this._extensionsOnExporting();
|
364
|
-
const jsonText = this._generateJSON(
|
354
|
+
const jsonText = this._generateJSON(binaryBuffer.byteLength, glTFPrefix, true);
|
365
355
|
const bin = new Blob([binaryBuffer], { type: "application/octet-stream" });
|
366
356
|
const glTFFileName = glTFPrefix + ".gltf";
|
367
357
|
const glTFBinFile = glTFPrefix + ".bin";
|
@@ -377,7 +367,8 @@ export class GLTFExporter {
|
|
377
367
|
}
|
378
368
|
async _generateBinaryAsync() {
|
379
369
|
await this._exportSceneAsync();
|
380
|
-
|
370
|
+
await this._extensionsPreGenerateBinaryAsync();
|
371
|
+
return this._bufferManager.generateBinary(this._bufferViews);
|
381
372
|
}
|
382
373
|
/**
|
383
374
|
* Pads the number to a multiple of 4
|
@@ -390,28 +381,24 @@ export class GLTFExporter {
|
|
390
381
|
return padding;
|
391
382
|
}
|
392
383
|
async generateGLBAsync(glTFPrefix) {
|
384
|
+
this._shouldUseGlb = true;
|
393
385
|
const binaryBuffer = await this._generateBinaryAsync();
|
394
386
|
this._extensionsOnExporting();
|
395
|
-
const jsonText = this._generateJSON(
|
387
|
+
const jsonText = this._generateJSON(binaryBuffer.byteLength);
|
396
388
|
const glbFileName = glTFPrefix + ".glb";
|
397
389
|
const headerLength = 12;
|
398
390
|
const chunkLengthPrefix = 8;
|
399
391
|
let jsonLength = jsonText.length;
|
400
392
|
let encodedJsonText;
|
401
|
-
let imageByteLength = 0;
|
402
393
|
// make use of TextEncoder when available
|
403
394
|
if (typeof TextEncoder !== "undefined") {
|
404
395
|
const encoder = new TextEncoder();
|
405
396
|
encodedJsonText = encoder.encode(jsonText);
|
406
397
|
jsonLength = encodedJsonText.length;
|
407
398
|
}
|
408
|
-
for (let i = 0; i < this._orderedImageData.length; ++i) {
|
409
|
-
imageByteLength += this._orderedImageData[i].data.byteLength;
|
410
|
-
}
|
411
399
|
const jsonPadding = this._getPadding(jsonLength);
|
412
400
|
const binPadding = this._getPadding(binaryBuffer.byteLength);
|
413
|
-
const
|
414
|
-
const byteLength = headerLength + 2 * chunkLengthPrefix + jsonLength + jsonPadding + binaryBuffer.byteLength + binPadding + imageByteLength + imagePadding;
|
401
|
+
const byteLength = headerLength + 2 * chunkLengthPrefix + jsonLength + jsonPadding + binaryBuffer.byteLength + binPadding;
|
415
402
|
// header
|
416
403
|
const headerBuffer = new ArrayBuffer(headerLength);
|
417
404
|
const headerBufferView = new DataView(headerBuffer);
|
@@ -450,7 +437,7 @@ export class GLTFExporter {
|
|
450
437
|
// binary chunk
|
451
438
|
const binaryChunkBuffer = new ArrayBuffer(chunkLengthPrefix);
|
452
439
|
const binaryChunkBufferView = new DataView(binaryChunkBuffer);
|
453
|
-
binaryChunkBufferView.setUint32(0, binaryBuffer.byteLength + binPadding
|
440
|
+
binaryChunkBufferView.setUint32(0, binaryBuffer.byteLength + binPadding, true);
|
454
441
|
binaryChunkBufferView.setUint32(4, 0x004e4942, true);
|
455
442
|
// binary padding
|
456
443
|
const binPaddingBuffer = new ArrayBuffer(binPadding);
|
@@ -458,18 +445,7 @@ export class GLTFExporter {
|
|
458
445
|
for (let i = 0; i < binPadding; ++i) {
|
459
446
|
binPaddingView[i] = 0;
|
460
447
|
}
|
461
|
-
const
|
462
|
-
const imagePaddingView = new Uint8Array(imagePaddingBuffer);
|
463
|
-
for (let i = 0; i < imagePadding; ++i) {
|
464
|
-
imagePaddingView[i] = 0;
|
465
|
-
}
|
466
|
-
const glbData = [headerBuffer, jsonChunkBuffer, binaryChunkBuffer, binaryBuffer];
|
467
|
-
// binary data
|
468
|
-
for (let i = 0; i < this._orderedImageData.length; ++i) {
|
469
|
-
glbData.push(this._orderedImageData[i].data);
|
470
|
-
}
|
471
|
-
glbData.push(binPaddingBuffer);
|
472
|
-
glbData.push(imagePaddingBuffer);
|
448
|
+
const glbData = [headerBuffer, jsonChunkBuffer, binaryChunkBuffer, binaryBuffer, binPaddingBuffer];
|
473
449
|
const glbFile = new Blob(glbData, { type: "application/octet-stream" });
|
474
450
|
const container = new GLTFData();
|
475
451
|
container.files[glbFileName] = glbFile;
|
@@ -617,21 +593,16 @@ export class GLTFExporter {
|
|
617
593
|
const skinedNodes = this._nodesSkinMap.get(skin);
|
618
594
|
// Only create skeleton if it has at least one joint and is used by a mesh.
|
619
595
|
if (skin.joints.length > 0 && skinedNodes !== undefined) {
|
620
|
-
//
|
621
|
-
const
|
622
|
-
const
|
623
|
-
|
624
|
-
|
625
|
-
this._bufferViews.push(bufferView);
|
626
|
-
const bufferViewIndex = this._bufferViews.length - 1;
|
627
|
-
const bindMatrixAccessor = CreateAccessor(bufferViewIndex, "MAT4" /* AccessorType.MAT4 */, 5126 /* AccessorComponentType.FLOAT */, inverseBindMatrices.length, null, null);
|
628
|
-
const inverseBindAccessorIndex = this._accessors.push(bindMatrixAccessor) - 1;
|
629
|
-
skin.inverseBindMatrices = inverseBindAccessorIndex;
|
630
|
-
inverseBindMatrices.forEach((mat) => {
|
631
|
-
mat.m.forEach((cell) => {
|
632
|
-
this._dataWriter.writeFloat32(cell);
|
633
|
-
});
|
596
|
+
// Put IBM data into TypedArraybuffer view
|
597
|
+
const byteLength = inverseBindMatrices.length * 64; // Always a 4 x 4 matrix of 32 bit float
|
598
|
+
const inverseBindMatricesData = new Float32Array(byteLength / 4);
|
599
|
+
inverseBindMatrices.forEach((mat, index) => {
|
600
|
+
inverseBindMatricesData.set(mat.m, index * 16);
|
634
601
|
});
|
602
|
+
// Create buffer view and accessor
|
603
|
+
const bufferView = this._bufferManager.createBufferView(inverseBindMatricesData);
|
604
|
+
this._accessors.push(this._bufferManager.createAccessor(bufferView, "MAT4" /* AccessorType.MAT4 */, 5126 /* AccessorComponentType.FLOAT */, inverseBindMatrices.length));
|
605
|
+
skin.inverseBindMatrices = this._accessors.length - 1;
|
635
606
|
this._skins.push(skin);
|
636
607
|
for (const skinedNode of skinedNodes) {
|
637
608
|
skinedNode.skin = this._skins.length - 1;
|
@@ -682,7 +653,7 @@ export class GLTFExporter {
|
|
682
653
|
this._exportAndAssignCameras();
|
683
654
|
this._exportAndAssignSkeletons();
|
684
655
|
if (this._babylonScene.animationGroups.length) {
|
685
|
-
_GLTFAnimation._CreateNodeAndMorphAnimationFromAnimationGroups(this._babylonScene, this._animations, this._nodeMap, this.
|
656
|
+
_GLTFAnimation._CreateNodeAndMorphAnimationFromAnimationGroups(this._babylonScene, this._animations, this._nodeMap, this._bufferManager, this._bufferViews, this._accessors, this._animationSampleRate, stateLH.getNodesSet());
|
686
657
|
}
|
687
658
|
}
|
688
659
|
_shouldExportNode(babylonNode) {
|
@@ -706,6 +677,9 @@ export class GLTFExporter {
|
|
706
677
|
const vertexBuffers = babylonNode.geometry.getVertexBuffers();
|
707
678
|
if (vertexBuffers) {
|
708
679
|
for (const kind in vertexBuffers) {
|
680
|
+
if (!IsStandardVertexAttribute(kind)) {
|
681
|
+
continue;
|
682
|
+
}
|
709
683
|
const vertexBuffer = vertexBuffers[kind];
|
710
684
|
state.setHasVertexColorAlpha(vertexBuffer, babylonNode.hasVertexAlpha);
|
711
685
|
const buffer = vertexBuffer._buffer;
|
@@ -772,10 +746,13 @@ export class GLTFExporter {
|
|
772
746
|
case VertexBuffer.NormalKind:
|
773
747
|
case VertexBuffer.TangentKind: {
|
774
748
|
EnumerateFloatValues(bytes, byteOffset, byteStride, size, type, maxTotalVertices * size, normalized, (values) => {
|
775
|
-
const
|
776
|
-
|
777
|
-
|
778
|
-
|
749
|
+
const length = Math.sqrt(values[0] * values[0] + values[1] * values[1] + values[2] * values[2]);
|
750
|
+
if (length > 0) {
|
751
|
+
const invLength = 1 / length;
|
752
|
+
values[0] *= invLength;
|
753
|
+
values[1] *= invLength;
|
754
|
+
values[2] *= invLength;
|
755
|
+
}
|
779
756
|
});
|
780
757
|
break;
|
781
758
|
}
|
@@ -832,12 +809,11 @@ export class GLTFExporter {
|
|
832
809
|
// Save converted bytes for min/max computation.
|
833
810
|
state.convertedToRightHandedBuffers.set(buffer, bytes);
|
834
811
|
}
|
835
|
-
|
836
|
-
this.
|
837
|
-
|
838
|
-
state.setVertexBufferView(buffer, this._bufferViews.length - 1);
|
812
|
+
// Create buffer view, but defer accessor creation for later. Instead, track it via ExporterState.
|
813
|
+
const bufferView = this._bufferManager.createBufferView(bytes, byteStride);
|
814
|
+
state.setVertexBufferView(buffer, bufferView);
|
839
815
|
const floatMatricesIndices = new Map();
|
840
|
-
// If buffers are of type
|
816
|
+
// If buffers are of type MatricesIndicesKind and have float values, we need to create a new buffer instead.
|
841
817
|
for (const vertexBuffer of vertexBuffers) {
|
842
818
|
switch (vertexBuffer.getKind()) {
|
843
819
|
case VertexBuffer.MatricesIndicesKind:
|
@@ -862,24 +838,13 @@ export class GLTFExporter {
|
|
862
838
|
if (!array) {
|
863
839
|
continue;
|
864
840
|
}
|
865
|
-
const
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
newArray[index] = array[index];
|
870
|
-
}
|
871
|
-
this._dataWriter.writeUint16Array(newArray);
|
872
|
-
this._bufferViews.push(CreateBufferView(0, byteOffset, newArray.byteLength, 4 * 2));
|
841
|
+
const is16Bit = FloatsNeed16BitInteger(array);
|
842
|
+
const newArray = new (is16Bit ? Uint16Array : Uint8Array)(array.length);
|
843
|
+
for (let index = 0; index < array.length; index++) {
|
844
|
+
newArray[index] = array[index];
|
873
845
|
}
|
874
|
-
|
875
|
-
|
876
|
-
for (let index = 0; index < array.length; index++) {
|
877
|
-
newArray[index] = array[index];
|
878
|
-
}
|
879
|
-
this._dataWriter.writeUint8Array(newArray);
|
880
|
-
this._bufferViews.push(CreateBufferView(0, byteOffset, newArray.byteLength, 4));
|
881
|
-
}
|
882
|
-
state.setRemappedBufferView(buffer, vertexBuffer, this._bufferViews.length - 1);
|
846
|
+
const bufferView = this._bufferManager.createBufferView(newArray, 4 * (is16Bit ? 2 : 1));
|
847
|
+
state.setRemappedBufferView(buffer, vertexBuffer, bufferView);
|
883
848
|
}
|
884
849
|
}
|
885
850
|
const morphTargets = Array.from(morphTagetsMeshesMap.keys());
|
@@ -888,7 +853,7 @@ export class GLTFExporter {
|
|
888
853
|
if (!meshes) {
|
889
854
|
continue;
|
890
855
|
}
|
891
|
-
const glTFMorphTarget = BuildMorphTargetBuffers(morphTarget, meshes[0], this.
|
856
|
+
const glTFMorphTarget = BuildMorphTargetBuffers(morphTarget, meshes[0], this._bufferManager, this._bufferViews, this._accessors, state.convertToRightHanded);
|
892
857
|
for (const mesh of meshes) {
|
893
858
|
state.bindMorphDataToMesh(mesh, glTFMorphTarget);
|
894
859
|
}
|
@@ -922,9 +887,9 @@ export class GLTFExporter {
|
|
922
887
|
};
|
923
888
|
const idleGLTFAnimations = [];
|
924
889
|
if (!this._babylonScene.animationGroups.length) {
|
925
|
-
_GLTFAnimation._CreateMorphTargetAnimationFromMorphTargetAnimations(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, this._nodeMap, this._nodes, this.
|
890
|
+
_GLTFAnimation._CreateMorphTargetAnimationFromMorphTargetAnimations(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, this._nodeMap, this._nodes, this._bufferManager, this._bufferViews, this._accessors, this._animationSampleRate, state.convertToRightHanded, this._options.shouldExportAnimation);
|
926
891
|
if (babylonNode.animations.length) {
|
927
|
-
_GLTFAnimation._CreateNodeAnimationFromNodeAnimations(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, this._nodeMap, this._nodes, this.
|
892
|
+
_GLTFAnimation._CreateNodeAnimationFromNodeAnimations(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, this._nodeMap, this._nodes, this._bufferManager, this._bufferViews, this._accessors, this._animationSampleRate, state.convertToRightHanded, this._options.shouldExportAnimation);
|
928
893
|
}
|
929
894
|
}
|
930
895
|
if (runtimeGLTFAnimation.channels.length && runtimeGLTFAnimation.samplers.length) {
|
@@ -1047,13 +1012,10 @@ export class GLTFExporter {
|
|
1047
1012
|
if (indicesToExport) {
|
1048
1013
|
let accessorIndex = state.getIndicesAccessor(indices, start, count, offset, flip);
|
1049
1014
|
if (accessorIndex === undefined) {
|
1050
|
-
const
|
1051
|
-
const
|
1052
|
-
this._dataWriter.writeUint8Array(bytes);
|
1053
|
-
this._bufferViews.push(CreateBufferView(0, bufferViewByteOffset, bytes.length));
|
1054
|
-
const bufferViewIndex = this._bufferViews.length - 1;
|
1015
|
+
const bytes = IndicesArrayToTypedArray(indicesToExport, start, count, is32Bits);
|
1016
|
+
const bufferView = this._bufferManager.createBufferView(bytes);
|
1055
1017
|
const componentType = is32Bits ? 5125 /* AccessorComponentType.UNSIGNED_INT */ : 5123 /* AccessorComponentType.UNSIGNED_SHORT */;
|
1056
|
-
this._accessors.push(
|
1018
|
+
this._accessors.push(this._bufferManager.createAccessor(bufferView, "SCALAR" /* AccessorType.SCALAR */, componentType, count, 0));
|
1057
1019
|
accessorIndex = this._accessors.length - 1;
|
1058
1020
|
state.setIndicesAccessor(indices, start, count, offset, flip, accessorIndex);
|
1059
1021
|
}
|
@@ -1074,30 +1036,19 @@ export class GLTFExporter {
|
|
1074
1036
|
if (accessorIndex === undefined) {
|
1075
1037
|
// Get min/max from converted or original data.
|
1076
1038
|
const data = state.convertedToRightHandedBuffers.get(vertexBuffer._buffer) || vertexBuffer._buffer.getData();
|
1077
|
-
const minMax = kind === VertexBuffer.PositionKind ? GetMinMax(data, vertexBuffer, start, count) :
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
const byteOffset = vertexBuffer.byteOffset + start * vertexBuffer.byteStride;
|
1091
|
-
this._accessors.push(CreateAccessor(bufferViewIndex, GetAccessorType(kind, state.hasVertexColorAlpha(vertexBuffer)), vertexBuffer.type, count, byteOffset, minMax, vertexBuffer.normalized // TODO: Find other places where this is needed.
|
1092
|
-
));
|
1093
|
-
accessorIndex = this._accessors.length - 1;
|
1094
|
-
state.setVertexAccessor(vertexBuffer, start, count, accessorIndex);
|
1095
|
-
primitive.attributes[GetAttributeType(kind)] = accessorIndex;
|
1096
|
-
}
|
1097
|
-
}
|
1098
|
-
else {
|
1099
|
-
primitive.attributes[GetAttributeType(kind)] = accessorIndex;
|
1100
|
-
}
|
1039
|
+
const minMax = kind === VertexBuffer.PositionKind ? GetMinMax(data, vertexBuffer, start, count) : undefined;
|
1040
|
+
// For the remapped buffer views we created for float matrices indices, make sure to use their updated information.
|
1041
|
+
const isFloatMatricesIndices = (kind === VertexBuffer.MatricesIndicesKind || kind === VertexBuffer.MatricesIndicesExtraKind) && vertexBuffer.type === VertexBuffer.FLOAT;
|
1042
|
+
const vertexBufferType = isFloatMatricesIndices ? VertexBuffer.UNSIGNED_BYTE : vertexBuffer.type;
|
1043
|
+
const vertexBufferNormalized = isFloatMatricesIndices ? undefined : vertexBuffer.normalized;
|
1044
|
+
const bufferView = isFloatMatricesIndices ? state.getRemappedBufferView(vertexBuffer._buffer, vertexBuffer) : state.getVertexBufferView(vertexBuffer._buffer);
|
1045
|
+
const byteOffset = vertexBuffer.byteOffset + start * vertexBuffer.byteStride;
|
1046
|
+
this._accessors.push(this._bufferManager.createAccessor(bufferView, GetAccessorType(kind, state.hasVertexColorAlpha(vertexBuffer)), vertexBufferType, count, byteOffset, minMax, vertexBufferNormalized // TODO: Find other places where this is needed.
|
1047
|
+
));
|
1048
|
+
accessorIndex = this._accessors.length - 1;
|
1049
|
+
state.setVertexAccessor(vertexBuffer, start, count, accessorIndex);
|
1050
|
+
}
|
1051
|
+
primitive.attributes[GetAttributeType(kind)] = accessorIndex;
|
1101
1052
|
}
|
1102
1053
|
async _exportMaterialAsync(babylonMaterial, vertexBuffers, subMesh, primitive) {
|
1103
1054
|
let materialIndex = this._materialMap.get(babylonMaterial);
|
@@ -1179,13 +1130,14 @@ export class GLTFExporter {
|
|
1179
1130
|
for (const vertexBuffer of Object.values(vertexBuffers)) {
|
1180
1131
|
this._exportVertexBuffer(vertexBuffer, babylonMaterial, subMesh.verticesStart, subMesh.verticesCount, state, primitive);
|
1181
1132
|
}
|
1182
|
-
mesh.primitives.push(primitive);
|
1183
1133
|
if (morphTargets) {
|
1184
1134
|
primitive.targets = [];
|
1185
1135
|
for (const gltfMorphTarget of morphTargets) {
|
1186
1136
|
primitive.targets.push(gltfMorphTarget.attributes);
|
1187
1137
|
}
|
1188
1138
|
}
|
1139
|
+
mesh.primitives.push(primitive);
|
1140
|
+
this._extensionsPostExportMeshPrimitive(primitive);
|
1189
1141
|
}
|
1190
1142
|
}
|
1191
1143
|
if (morphTargets) {
|