@babylonjs/serializers 7.11.4 → 7.13.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/glTFAnimation.js +2 -3
- package/glTF/2.0/glTFAnimation.js.map +1 -1
- package/glTF/2.0/glTFExporter.d.ts +1 -21
- package/glTF/2.0/glTFExporter.js +137 -172
- package/glTF/2.0/glTFExporter.js.map +1 -1
- package/glTF/2.0/glTFUtilities.d.ts +2 -1
- package/glTF/2.0/glTFUtilities.js.map +1 -1
- package/package.json +3 -3
package/glTF/2.0/glTFExporter.js
CHANGED
@@ -67,6 +67,26 @@ function convertNodeHandedness(node) {
|
|
67
67
|
node.scale = scale.asArray();
|
68
68
|
}
|
69
69
|
}
|
70
|
+
function getBinaryWriterFunc(binaryWriter, attributeComponentKind) {
|
71
|
+
switch (attributeComponentKind) {
|
72
|
+
case 5121 /* AccessorComponentType.UNSIGNED_BYTE */: {
|
73
|
+
return binaryWriter.setUInt8.bind(binaryWriter);
|
74
|
+
}
|
75
|
+
case 5123 /* AccessorComponentType.UNSIGNED_SHORT */: {
|
76
|
+
return binaryWriter.setUInt16.bind(binaryWriter);
|
77
|
+
}
|
78
|
+
case 5125 /* AccessorComponentType.UNSIGNED_INT */: {
|
79
|
+
return binaryWriter.setUInt32.bind(binaryWriter);
|
80
|
+
}
|
81
|
+
case 5126 /* AccessorComponentType.FLOAT */: {
|
82
|
+
return binaryWriter.setFloat32.bind(binaryWriter);
|
83
|
+
}
|
84
|
+
default: {
|
85
|
+
Tools.Warn("Unsupported Attribute Component kind: " + attributeComponentKind);
|
86
|
+
return null;
|
87
|
+
}
|
88
|
+
}
|
89
|
+
}
|
70
90
|
/**
|
71
91
|
* Converts Babylon Scene into glTF 2.0.
|
72
92
|
* @internal
|
@@ -600,122 +620,98 @@ export class _Exporter {
|
|
600
620
|
vertexAttributes = [];
|
601
621
|
}
|
602
622
|
}
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
case 5123 /* AccessorComponentType.UNSIGNED_SHORT */: {
|
610
|
-
writeBinaryFunc = binaryWriter.setUInt16.bind(binaryWriter);
|
611
|
-
break;
|
612
|
-
}
|
613
|
-
case 5125 /* AccessorComponentType.UNSIGNED_INT */: {
|
614
|
-
writeBinaryFunc = binaryWriter.setUInt32.bind(binaryWriter);
|
615
|
-
break;
|
616
|
-
}
|
617
|
-
case 5126 /* AccessorComponentType.FLOAT */: {
|
618
|
-
writeBinaryFunc = binaryWriter.setFloat32.bind(binaryWriter);
|
619
|
-
break;
|
620
|
-
}
|
621
|
-
default: {
|
622
|
-
Tools.Warn("Unsupported Attribute Component kind: " + attributeComponentKind);
|
623
|
-
return;
|
624
|
-
}
|
625
|
-
}
|
626
|
-
for (const vertexAttribute of vertexAttributes) {
|
627
|
-
for (const component of vertexAttribute) {
|
628
|
-
writeBinaryFunc(component);
|
623
|
+
const writeBinaryFunc = getBinaryWriterFunc(binaryWriter, attributeComponentKind);
|
624
|
+
if (writeBinaryFunc) {
|
625
|
+
for (const vertexAttribute of vertexAttributes) {
|
626
|
+
for (const component of vertexAttribute) {
|
627
|
+
writeBinaryFunc(component);
|
628
|
+
}
|
629
629
|
}
|
630
630
|
}
|
631
631
|
}
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
* @param meshPrimitive the mesh primitive
|
638
|
-
* @param meshAttributeArray Array containing the attribute data
|
639
|
-
* @param morphTargetAttributeArray
|
640
|
-
* @param stride Specifies the space between data
|
641
|
-
* @param binaryWriter The buffer to write the binary data to
|
642
|
-
* @param minMax
|
643
|
-
*/
|
644
|
-
writeMorphTargetAttributeData(vertexBufferKind, attributeComponentKind, meshPrimitive, meshAttributeArray, morphTargetAttributeArray, stride, binaryWriter, minMax) {
|
645
|
-
let vertexAttributes = [];
|
646
|
-
let index;
|
647
|
-
let difference = new Vector3();
|
648
|
-
let difference4 = new Vector4(0, 0, 0, 0);
|
632
|
+
_createMorphTargetBufferViewKind(vertexBufferKind, accessorType, attributeComponentKind, mesh, morphTarget, binaryWriter, byteStride) {
|
633
|
+
let vertexCount;
|
634
|
+
let minMax;
|
635
|
+
const morphData = [];
|
636
|
+
const difference = TmpVectors.Vector3[0];
|
649
637
|
switch (vertexBufferKind) {
|
650
638
|
case VertexBuffer.PositionKind: {
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
639
|
+
const morphPositions = morphTarget.getPositions();
|
640
|
+
if (!morphPositions) {
|
641
|
+
return null;
|
642
|
+
}
|
643
|
+
const originalPositions = mesh.getVerticesData(VertexBuffer.PositionKind, undefined, undefined, true);
|
644
|
+
const vertexStart = 0;
|
645
|
+
const min = new Vector3(Infinity, Infinity, Infinity);
|
646
|
+
const max = new Vector3(-Infinity, -Infinity, -Infinity);
|
647
|
+
vertexCount = originalPositions.length / 3;
|
648
|
+
for (let i = vertexStart; i < vertexCount; ++i) {
|
649
|
+
const originalPosition = Vector3.FromArray(originalPositions, i * 3);
|
650
|
+
const morphPosition = Vector3.FromArray(morphPositions, i * 3);
|
651
|
+
morphPosition.subtractToRef(originalPosition, difference);
|
652
|
+
min.copyFromFloats(Math.min(difference.x, min.x), Math.min(difference.y, min.y), Math.min(difference.z, min.z));
|
653
|
+
max.copyFromFloats(Math.max(difference.x, max.x), Math.max(difference.y, max.y), Math.max(difference.z, max.z));
|
654
|
+
morphData.push(difference.x, difference.y, difference.z);
|
661
655
|
}
|
656
|
+
minMax = { min, max };
|
662
657
|
break;
|
663
658
|
}
|
664
659
|
case VertexBuffer.NormalKind: {
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
660
|
+
const morphNormals = morphTarget.getNormals();
|
661
|
+
if (!morphNormals) {
|
662
|
+
return null;
|
663
|
+
}
|
664
|
+
const originalNormals = mesh.getVerticesData(VertexBuffer.NormalKind, undefined, undefined, true);
|
665
|
+
const vertexStart = 0;
|
666
|
+
vertexCount = originalNormals.length / 3;
|
667
|
+
for (let i = vertexStart; i < vertexCount; ++i) {
|
668
|
+
const originalNormal = Vector3.FromArray(originalNormals, i * 3).normalize();
|
669
|
+
const morphNormal = Vector3.FromArray(morphNormals, i * 3).normalize();
|
670
|
+
morphNormal.subtractToRef(originalNormal, difference);
|
671
|
+
morphData.push(difference.x, difference.y, difference.z);
|
671
672
|
}
|
672
673
|
break;
|
673
674
|
}
|
674
675
|
case VertexBuffer.TangentKind: {
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
676
|
+
const morphTangents = morphTarget.getTangents();
|
677
|
+
if (!morphTangents) {
|
678
|
+
return null;
|
679
|
+
}
|
680
|
+
// Handedness cannot be displaced, so morph target tangents omit the w component
|
681
|
+
accessorType = "VEC3" /* AccessorType.VEC3 */;
|
682
|
+
byteStride = 12; // 3 components (x/y/z) * 4 bytes (float32)
|
683
|
+
const originalTangents = mesh.getVerticesData(VertexBuffer.TangentKind, undefined, undefined, true);
|
684
|
+
const vertexStart = 0;
|
685
|
+
vertexCount = originalTangents.length / 4;
|
686
|
+
for (let i = vertexStart; i < vertexCount; ++i) {
|
687
|
+
// Only read the x, y, z components and ignore w
|
688
|
+
const originalTangent = Vector3.FromArray(originalTangents, i * 4);
|
689
|
+
_GLTFUtilities._NormalizeTangentFromRef(originalTangent);
|
690
|
+
// Morph target tangents omit the w component so it won't be present in the data
|
691
|
+
const morphTangent = Vector3.FromArray(morphTangents, i * 3);
|
692
|
+
_GLTFUtilities._NormalizeTangentFromRef(morphTangent);
|
693
|
+
morphTangent.subtractToRef(originalTangent, difference);
|
694
|
+
morphData.push(difference.x, difference.y, difference.z);
|
683
695
|
}
|
684
696
|
break;
|
685
697
|
}
|
686
698
|
default: {
|
687
|
-
|
688
|
-
vertexAttributes = [];
|
699
|
+
return null;
|
689
700
|
}
|
690
701
|
}
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
writeBinaryFunc = binaryWriter.setUInt8.bind(binaryWriter);
|
695
|
-
break;
|
696
|
-
}
|
697
|
-
case 5123 /* AccessorComponentType.UNSIGNED_SHORT */: {
|
698
|
-
writeBinaryFunc = binaryWriter.setUInt16.bind(binaryWriter);
|
699
|
-
break;
|
700
|
-
}
|
701
|
-
case 5125 /* AccessorComponentType.UNSIGNED_INT */: {
|
702
|
-
writeBinaryFunc = binaryWriter.setUInt32.bind(binaryWriter);
|
703
|
-
break;
|
704
|
-
}
|
705
|
-
case 5126 /* AccessorComponentType.FLOAT */: {
|
706
|
-
writeBinaryFunc = binaryWriter.setFloat32.bind(binaryWriter);
|
707
|
-
break;
|
708
|
-
}
|
709
|
-
default: {
|
710
|
-
Tools.Warn("Unsupported Attribute Component kind: " + attributeComponentKind);
|
711
|
-
return;
|
712
|
-
}
|
702
|
+
const binaryWriterFunc = getBinaryWriterFunc(binaryWriter, attributeComponentKind);
|
703
|
+
if (!binaryWriterFunc) {
|
704
|
+
return null;
|
713
705
|
}
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
706
|
+
const typeByteLength = VertexBuffer.GetTypeByteLength(attributeComponentKind);
|
707
|
+
const byteLength = morphData.length * typeByteLength;
|
708
|
+
const bufferView = _GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, `${vertexBufferKind} - ${morphTarget.name} (Morph Target)`);
|
709
|
+
this._bufferViews.push(bufferView);
|
710
|
+
const bufferViewIndex = this._bufferViews.length - 1;
|
711
|
+
for (const value of morphData) {
|
712
|
+
binaryWriterFunc(value);
|
718
713
|
}
|
714
|
+
return { bufferViewIndex, vertexCount, accessorType, minMax };
|
719
715
|
}
|
720
716
|
/**
|
721
717
|
* Generates glTF json data
|
@@ -1018,68 +1014,6 @@ export class _Exporter {
|
|
1018
1014
|
}
|
1019
1015
|
}
|
1020
1016
|
}
|
1021
|
-
/**
|
1022
|
-
* Creates a bufferview based on the vertices type for the Babylon mesh
|
1023
|
-
* @param babylonSubMesh The Babylon submesh that the morph target is applied to
|
1024
|
-
* @param meshPrimitive
|
1025
|
-
* @param babylonMorphTarget the morph target to be exported
|
1026
|
-
* @param binaryWriter The buffer to write the bufferview data to
|
1027
|
-
*/
|
1028
|
-
_setMorphTargetAttributes(babylonSubMesh, meshPrimitive, babylonMorphTarget, binaryWriter) {
|
1029
|
-
if (babylonMorphTarget) {
|
1030
|
-
if (!meshPrimitive.targets) {
|
1031
|
-
meshPrimitive.targets = [];
|
1032
|
-
}
|
1033
|
-
const target = {};
|
1034
|
-
const mesh = babylonSubMesh.getMesh();
|
1035
|
-
if (babylonMorphTarget.hasNormals) {
|
1036
|
-
const vertexNormals = mesh.getVerticesData(VertexBuffer.NormalKind, undefined, undefined, true);
|
1037
|
-
const morphNormals = babylonMorphTarget.getNormals();
|
1038
|
-
const count = babylonSubMesh.verticesCount;
|
1039
|
-
const byteStride = 12; // 3 x 4 byte floats
|
1040
|
-
const byteLength = count * byteStride;
|
1041
|
-
const bufferView = _GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, babylonMorphTarget.name + "_NORMAL");
|
1042
|
-
this._bufferViews.push(bufferView);
|
1043
|
-
const bufferViewIndex = this._bufferViews.length - 1;
|
1044
|
-
const accessor = _GLTFUtilities._CreateAccessor(bufferViewIndex, babylonMorphTarget.name + " - " + "NORMAL", "VEC3" /* AccessorType.VEC3 */, 5126 /* AccessorComponentType.FLOAT */, count, 0, null, null);
|
1045
|
-
this._accessors.push(accessor);
|
1046
|
-
target.NORMAL = this._accessors.length - 1;
|
1047
|
-
this.writeMorphTargetAttributeData(VertexBuffer.NormalKind, 5126 /* AccessorComponentType.FLOAT */, babylonSubMesh, vertexNormals, morphNormals, byteStride / 4, binaryWriter);
|
1048
|
-
}
|
1049
|
-
if (babylonMorphTarget.hasPositions) {
|
1050
|
-
const vertexPositions = mesh.getVerticesData(VertexBuffer.PositionKind, undefined, undefined, true);
|
1051
|
-
const morphPositions = babylonMorphTarget.getPositions();
|
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 + "_POSITION");
|
1056
|
-
this._bufferViews.push(bufferView);
|
1057
|
-
const bufferViewIndex = this._bufferViews.length - 1;
|
1058
|
-
const minMax = { min: new Vector3(Infinity, Infinity, Infinity), max: new Vector3(-Infinity, -Infinity, -Infinity) };
|
1059
|
-
const accessor = _GLTFUtilities._CreateAccessor(bufferViewIndex, babylonMorphTarget.name + " - " + "POSITION", "VEC3" /* AccessorType.VEC3 */, 5126 /* AccessorComponentType.FLOAT */, count, 0, null, null);
|
1060
|
-
this._accessors.push(accessor);
|
1061
|
-
target.POSITION = this._accessors.length - 1;
|
1062
|
-
this.writeMorphTargetAttributeData(VertexBuffer.PositionKind, 5126 /* AccessorComponentType.FLOAT */, babylonSubMesh, vertexPositions, morphPositions, byteStride / 4, binaryWriter, minMax);
|
1063
|
-
accessor.min = minMax.min.asArray();
|
1064
|
-
accessor.max = minMax.max.asArray();
|
1065
|
-
}
|
1066
|
-
if (babylonMorphTarget.hasTangents) {
|
1067
|
-
const vertexTangents = mesh.getVerticesData(VertexBuffer.TangentKind, undefined, undefined, true);
|
1068
|
-
const morphTangents = babylonMorphTarget.getTangents();
|
1069
|
-
const count = babylonSubMesh.verticesCount;
|
1070
|
-
const byteStride = 12; // 3 x 4 byte floats
|
1071
|
-
const byteLength = count * byteStride;
|
1072
|
-
const bufferView = _GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, babylonMorphTarget.name + "_NORMAL");
|
1073
|
-
this._bufferViews.push(bufferView);
|
1074
|
-
const bufferViewIndex = this._bufferViews.length - 1;
|
1075
|
-
const accessor = _GLTFUtilities._CreateAccessor(bufferViewIndex, babylonMorphTarget.name + " - " + "TANGENT", "VEC3" /* AccessorType.VEC3 */, 5126 /* AccessorComponentType.FLOAT */, count, 0, null, null);
|
1076
|
-
this._accessors.push(accessor);
|
1077
|
-
target.TANGENT = this._accessors.length - 1;
|
1078
|
-
this.writeMorphTargetAttributeData(VertexBuffer.TangentKind, 5126 /* AccessorComponentType.FLOAT */, babylonSubMesh, vertexTangents, morphTangents, byteStride / 4, binaryWriter);
|
1079
|
-
}
|
1080
|
-
meshPrimitive.targets.push(target);
|
1081
|
-
}
|
1082
|
-
}
|
1083
1017
|
/**
|
1084
1018
|
* The primitive mode of the Babylon mesh
|
1085
1019
|
* @param babylonMesh The BabylonJS mesh
|
@@ -1143,46 +1077,46 @@ export class _Exporter {
|
|
1143
1077
|
* @param meshPrimitive glTF mesh primitive
|
1144
1078
|
* @param attributeKind vertex attribute
|
1145
1079
|
*/
|
1146
|
-
_setAttributeKind(
|
1080
|
+
_setAttributeKind(attributes, attributeKind) {
|
1147
1081
|
switch (attributeKind) {
|
1148
1082
|
case VertexBuffer.PositionKind: {
|
1149
|
-
|
1083
|
+
attributes.POSITION = this._accessors.length - 1;
|
1150
1084
|
break;
|
1151
1085
|
}
|
1152
1086
|
case VertexBuffer.NormalKind: {
|
1153
|
-
|
1087
|
+
attributes.NORMAL = this._accessors.length - 1;
|
1154
1088
|
break;
|
1155
1089
|
}
|
1156
1090
|
case VertexBuffer.ColorKind: {
|
1157
|
-
|
1091
|
+
attributes.COLOR_0 = this._accessors.length - 1;
|
1158
1092
|
break;
|
1159
1093
|
}
|
1160
1094
|
case VertexBuffer.TangentKind: {
|
1161
|
-
|
1095
|
+
attributes.TANGENT = this._accessors.length - 1;
|
1162
1096
|
break;
|
1163
1097
|
}
|
1164
1098
|
case VertexBuffer.UVKind: {
|
1165
|
-
|
1099
|
+
attributes.TEXCOORD_0 = this._accessors.length - 1;
|
1166
1100
|
break;
|
1167
1101
|
}
|
1168
1102
|
case VertexBuffer.UV2Kind: {
|
1169
|
-
|
1103
|
+
attributes.TEXCOORD_1 = this._accessors.length - 1;
|
1170
1104
|
break;
|
1171
1105
|
}
|
1172
1106
|
case VertexBuffer.MatricesIndicesKind: {
|
1173
|
-
|
1107
|
+
attributes.JOINTS_0 = this._accessors.length - 1;
|
1174
1108
|
break;
|
1175
1109
|
}
|
1176
1110
|
case VertexBuffer.MatricesIndicesExtraKind: {
|
1177
|
-
|
1111
|
+
attributes.JOINTS_1 = this._accessors.length - 1;
|
1178
1112
|
break;
|
1179
1113
|
}
|
1180
1114
|
case VertexBuffer.MatricesWeightsKind: {
|
1181
|
-
|
1115
|
+
attributes.WEIGHTS_0 = this._accessors.length - 1;
|
1182
1116
|
break;
|
1183
1117
|
}
|
1184
1118
|
case VertexBuffer.MatricesWeightsExtraKind: {
|
1185
|
-
|
1119
|
+
attributes.WEIGHTS_1 = this._accessors.length - 1;
|
1186
1120
|
break;
|
1187
1121
|
}
|
1188
1122
|
default: {
|
@@ -1240,6 +1174,20 @@ export class _Exporter {
|
|
1240
1174
|
this._createBufferViewKind(attributeKind, attributeComponentKind, babylonTransformNode, binaryWriter, attribute.byteStride);
|
1241
1175
|
attribute.bufferViewIndex = this._bufferViews.length - 1;
|
1242
1176
|
vertexAttributeBufferViews[attributeKind] = attribute.bufferViewIndex;
|
1177
|
+
// Write any morph target data to the buffer and create an associated buffer view
|
1178
|
+
if (morphTargetManager) {
|
1179
|
+
for (let i = 0; i < morphTargetManager.numTargets; ++i) {
|
1180
|
+
const morphTarget = morphTargetManager.getTarget(i);
|
1181
|
+
const morphTargetInfo = this._createMorphTargetBufferViewKind(attributeKind, attribute.accessorType, attributeComponentKind, bufferMesh, morphTarget, binaryWriter, attribute.byteStride);
|
1182
|
+
// Store info about the morph target that will be needed later when creating per-submesh accessors
|
1183
|
+
if (morphTargetInfo) {
|
1184
|
+
if (!attribute.morphTargetInfo) {
|
1185
|
+
attribute.morphTargetInfo = [];
|
1186
|
+
}
|
1187
|
+
attribute.morphTargetInfo[i] = morphTargetInfo;
|
1188
|
+
}
|
1189
|
+
}
|
1190
|
+
}
|
1243
1191
|
}
|
1244
1192
|
}
|
1245
1193
|
if (bufferMesh.getTotalIndices()) {
|
@@ -1308,7 +1256,7 @@ export class _Exporter {
|
|
1308
1256
|
}
|
1309
1257
|
const accessor = _GLTFUtilities._CreateAccessor(bufferViewIndex, attributeKind + " - " + babylonTransformNode.name, attribute.accessorType, attribute.accessorComponentType, vertexData.length / stride, 0, minMax.min, minMax.max);
|
1310
1258
|
this._accessors.push(accessor);
|
1311
|
-
this._setAttributeKind(meshPrimitive, attributeKind);
|
1259
|
+
this._setAttributeKind(meshPrimitive.attributes, attributeKind);
|
1312
1260
|
}
|
1313
1261
|
}
|
1314
1262
|
}
|
@@ -1347,6 +1295,7 @@ export class _Exporter {
|
|
1347
1295
|
meshPrimitive.material = materialIndex;
|
1348
1296
|
}
|
1349
1297
|
}
|
1298
|
+
// If there are morph targets, write out targets and associated accessors
|
1350
1299
|
if (morphTargetManager) {
|
1351
1300
|
// By convention, morph target names are stored in the mesh extras.
|
1352
1301
|
if (!mesh.extras) {
|
@@ -1354,9 +1303,25 @@ export class _Exporter {
|
|
1354
1303
|
}
|
1355
1304
|
mesh.extras.targetNames = [];
|
1356
1305
|
for (let i = 0; i < morphTargetManager.numTargets; ++i) {
|
1357
|
-
const
|
1358
|
-
|
1359
|
-
|
1306
|
+
const morphTarget = morphTargetManager.getTarget(i);
|
1307
|
+
mesh.extras.targetNames.push(morphTarget.name);
|
1308
|
+
for (const attribute of attributeData) {
|
1309
|
+
const morphTargetInfo = attribute.morphTargetInfo?.[i];
|
1310
|
+
if (morphTargetInfo) {
|
1311
|
+
// Write the accessor
|
1312
|
+
const byteOffset = 0;
|
1313
|
+
const accessor = _GLTFUtilities._CreateAccessor(morphTargetInfo.bufferViewIndex, `${attribute.kind} - ${morphTarget.name} (Morph Target)`, morphTargetInfo.accessorType, attribute.accessorComponentType, morphTargetInfo.vertexCount, byteOffset, morphTargetInfo.minMax?.min?.asArray() ?? null, morphTargetInfo.minMax?.max?.asArray() ?? null);
|
1314
|
+
this._accessors.push(accessor);
|
1315
|
+
// Create a target that references the new accessor
|
1316
|
+
if (!meshPrimitive.targets) {
|
1317
|
+
meshPrimitive.targets = [];
|
1318
|
+
}
|
1319
|
+
if (!meshPrimitive.targets[i]) {
|
1320
|
+
meshPrimitive.targets[i] = {};
|
1321
|
+
}
|
1322
|
+
this._setAttributeKind(meshPrimitive.targets[i], attribute.kind);
|
1323
|
+
}
|
1324
|
+
}
|
1360
1325
|
}
|
1361
1326
|
}
|
1362
1327
|
mesh.primitives.push(meshPrimitive);
|