|
@@ -224,12 +224,10 @@ var BABYLON;
|
|
|
this.materials = new Array();
|
|
|
this.textures = new Array();
|
|
|
this.imageData = {};
|
|
|
- if (options !== undefined) {
|
|
|
+ this.convertToRightHandedSystem = !this.babylonScene.useRightHandedSystem;
|
|
|
+ if (options) {
|
|
|
this.options = options;
|
|
|
}
|
|
|
- var totalByteLength = 0;
|
|
|
- totalByteLength = this.createScene(this.babylonScene, totalByteLength, null);
|
|
|
- this.totalByteLength = totalByteLength;
|
|
|
}
|
|
|
/**
|
|
|
* Creates a buffer view based on teh supplied arguments
|
|
@@ -242,7 +240,7 @@ var BABYLON;
|
|
|
*/
|
|
|
_Exporter.prototype.createBufferView = function (bufferIndex, byteOffset, byteLength, byteStride, name) {
|
|
|
var bufferview = { buffer: bufferIndex, byteLength: byteLength };
|
|
|
- if (byteOffset > 0) {
|
|
|
+ if (byteOffset) {
|
|
|
bufferview.byteOffset = byteOffset;
|
|
|
}
|
|
|
if (name) {
|
|
@@ -255,13 +253,14 @@ var BABYLON;
|
|
|
};
|
|
|
/**
|
|
|
* Creates an accessor based on the supplied arguments
|
|
|
- * @param bufferviewIndex
|
|
|
- * @param name
|
|
|
- * @param type
|
|
|
- * @param componentType
|
|
|
- * @param count
|
|
|
- * @param min
|
|
|
- * @param max
|
|
|
+ * @param bufferviewIndex - The index of the bufferview referenced by this accessor.
|
|
|
+ * @param name - The name of the accessor.
|
|
|
+ * @param type - The type of the accessor.
|
|
|
+ * @param componentType - The datatype of components in the attribute.
|
|
|
+ * @param count - The number of attributes referenced by this accessor.
|
|
|
+ * @param byteOffset - The offset relative to the start of the bufferView in bytes.
|
|
|
+ * @param min - Minimum value of each component in this attribute.
|
|
|
+ * @param max - Maximum value of each component in this attribute.
|
|
|
* @returns - accessor for glTF
|
|
|
*/
|
|
|
_Exporter.prototype.createAccessor = function (bufferviewIndex, name, type, componentType, count, byteOffset, min, max) {
|
|
@@ -278,40 +277,60 @@ var BABYLON;
|
|
|
return accessor;
|
|
|
};
|
|
|
/**
|
|
|
- * Calculates the minimum and maximum values of an array of floats, based on stride
|
|
|
- * @param buff - Data to check for min and max values.
|
|
|
- * @param vertexStart - Start offset to calculate min and max values.
|
|
|
+ * Calculates the minimum and maximum values of an array of position floats.
|
|
|
+ * @param positions - Positions array of a mesh.
|
|
|
+ * @param vertexStart - Starting vertex offset to calculate min and max values.
|
|
|
* @param vertexCount - Number of vertices to check for min and max values.
|
|
|
- * @param stride - Offset between consecutive attributes.
|
|
|
- * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
|
|
|
* @returns - min number array and max number array.
|
|
|
*/
|
|
|
- _Exporter.prototype.calculateMinMax = function (buff, vertexStart, vertexCount, stride, useRightHandedSystem) {
|
|
|
+ _Exporter.prototype.calculateMinMaxPositions = function (positions, vertexStart, vertexCount) {
|
|
|
var min = [Infinity, Infinity, Infinity];
|
|
|
var max = [-Infinity, -Infinity, -Infinity];
|
|
|
+ var positionStrideSize = 3;
|
|
|
var end = vertexStart + vertexCount;
|
|
|
- if (vertexCount > 0) {
|
|
|
+ if (vertexCount) {
|
|
|
for (var i = vertexStart; i < end; ++i) {
|
|
|
- var index = stride * i;
|
|
|
- var scale = 1;
|
|
|
- for (var j = 0; j < stride; ++j) {
|
|
|
- if (j === (stride - 1) && !useRightHandedSystem) {
|
|
|
- scale = -1;
|
|
|
- }
|
|
|
- var num = scale * buff[index];
|
|
|
+ var indexOffset = positionStrideSize * i;
|
|
|
+ var position = new BABYLON.Vector3(positions[indexOffset], positions[indexOffset + 1], positions[indexOffset + 2]);
|
|
|
+ var vector = this.convertToRightHandedSystem ? _Exporter.GetRightHandedVector3(position).asArray() : position.asArray();
|
|
|
+ for (var j = 0; j < positionStrideSize; ++j) {
|
|
|
+ var num = vector[j];
|
|
|
if (num < min[j]) {
|
|
|
min[j] = num;
|
|
|
}
|
|
|
if (num > max[j]) {
|
|
|
max[j] = num;
|
|
|
}
|
|
|
- ++index;
|
|
|
+ ++indexOffset;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return { min: min, max: max };
|
|
|
};
|
|
|
/**
|
|
|
+ * Converts a vector3 array to right-handed.
|
|
|
+ * @param vector - vector3 Array to convert to right-handed.
|
|
|
+ * @returns - right-handed Vector3 array.
|
|
|
+ */
|
|
|
+ _Exporter.GetRightHandedVector3 = function (vector) {
|
|
|
+ return new BABYLON.Vector3(vector.x, vector.y, -vector.z);
|
|
|
+ };
|
|
|
+ /**
|
|
|
+ * Converts a vector4 array to right-handed.
|
|
|
+ * @param vector - vector4 Array to convert to right-handed.
|
|
|
+ * @returns - right-handed vector4 array.
|
|
|
+ */
|
|
|
+ _Exporter.GetRightHandedVector4 = function (vector) {
|
|
|
+ return new BABYLON.Vector4(vector.x, vector.y, -vector.z, -vector.w);
|
|
|
+ };
|
|
|
+ /**
|
|
|
+ * Converts a quaternion to right-handed.
|
|
|
+ * @param quaternion - Source quaternion to convert to right-handed.
|
|
|
+ */
|
|
|
+ _Exporter.GetRightHandedQuaternion = function (quaternion) {
|
|
|
+ return new BABYLON.Quaternion(-quaternion.x, -quaternion.y, quaternion.z, quaternion.w);
|
|
|
+ };
|
|
|
+ /**
|
|
|
* Writes mesh attribute data to a data buffer.
|
|
|
* Returns the bytelength of the data.
|
|
|
* @param vertexBufferKind - Indicates what kind of vertex data is being passed in.
|
|
@@ -319,112 +338,35 @@ var BABYLON;
|
|
|
* @param strideSize - Represents the offset between consecutive attributes
|
|
|
* @param byteOffset - The offset to start counting bytes from.
|
|
|
* @param dataBuffer - The buffer to write the binary data to.
|
|
|
- * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
|
|
|
* @returns - Byte length of the attribute data.
|
|
|
*/
|
|
|
- _Exporter.prototype.writeAttributeData = function (vertexBufferKind, meshAttributeArray, strideSize, vertexBufferOffset, byteOffset, dataBuffer, useRightHandedSystem) {
|
|
|
+ _Exporter.prototype.writeAttributeData = function (vertexBufferKind, meshAttributeArray, strideSize, vertexBufferOffset, byteOffset, dataBuffer) {
|
|
|
var byteOff = byteOffset;
|
|
|
- var start = 0;
|
|
|
var end = meshAttributeArray.length / strideSize;
|
|
|
var byteLength = 0;
|
|
|
- switch (vertexBufferKind) {
|
|
|
- case BABYLON.VertexBuffer.PositionKind: {
|
|
|
- for (var k = start; k < end; ++k) {
|
|
|
- var index = k * strideSize;
|
|
|
- dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
|
|
|
- byteOff += 4;
|
|
|
- dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 1], true);
|
|
|
- byteOff += 4;
|
|
|
- if (useRightHandedSystem) {
|
|
|
- dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 2], true);
|
|
|
- }
|
|
|
- else {
|
|
|
- dataBuffer.setFloat32(byteOff, -meshAttributeArray[index + 2], true);
|
|
|
- }
|
|
|
- byteOff += 4;
|
|
|
- }
|
|
|
- byteLength = meshAttributeArray.length * 4;
|
|
|
- break;
|
|
|
- }
|
|
|
- case BABYLON.VertexBuffer.NormalKind: {
|
|
|
- for (var k = start; k < end; ++k) {
|
|
|
- var index = k * strideSize;
|
|
|
- dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
|
|
|
- byteOff += 4;
|
|
|
- dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 1], true);
|
|
|
- byteOff += 4;
|
|
|
- if (useRightHandedSystem) {
|
|
|
- dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 2], true);
|
|
|
- }
|
|
|
- else {
|
|
|
- dataBuffer.setFloat32(byteOff, -meshAttributeArray[index + 2], true);
|
|
|
- }
|
|
|
- byteOff += 4;
|
|
|
- }
|
|
|
- byteLength = meshAttributeArray.length * 4;
|
|
|
- break;
|
|
|
- }
|
|
|
- case BABYLON.VertexBuffer.TangentKind: {
|
|
|
- for (var k = start; k < end; ++k) {
|
|
|
- var index = k * strideSize;
|
|
|
- dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
|
|
|
- byteOff += 4;
|
|
|
- dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 1], true);
|
|
|
- byteOff += 4;
|
|
|
- if (useRightHandedSystem) {
|
|
|
- dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 2], true);
|
|
|
- }
|
|
|
- else {
|
|
|
- dataBuffer.setFloat32(byteOff, -meshAttributeArray[index + 2], true);
|
|
|
- }
|
|
|
- byteOff += 4;
|
|
|
- dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 3], true);
|
|
|
- byteOff += 4;
|
|
|
- }
|
|
|
- byteLength = meshAttributeArray.length * 4;
|
|
|
- break;
|
|
|
+ for (var k = 0; k < end; ++k) {
|
|
|
+ var index = k * strideSize;
|
|
|
+ var vector = [];
|
|
|
+ if (vertexBufferKind === BABYLON.VertexBuffer.PositionKind || vertexBufferKind === BABYLON.VertexBuffer.NormalKind) {
|
|
|
+ var vertexData = new BABYLON.Vector3(meshAttributeArray[index], meshAttributeArray[index + 1], meshAttributeArray[index + 2]);
|
|
|
+ vector = this.convertToRightHandedSystem ? _Exporter.GetRightHandedVector3(vertexData).asArray() : vertexData.asArray();
|
|
|
}
|
|
|
- case BABYLON.VertexBuffer.ColorKind: {
|
|
|
- for (var k = start; k < end; ++k) {
|
|
|
- var index = k * strideSize;
|
|
|
- dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
|
|
|
- byteOff += 4;
|
|
|
- dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 1], true);
|
|
|
- byteOff += 4;
|
|
|
- dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 2], true);
|
|
|
- byteOff += 4;
|
|
|
- dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 3], true);
|
|
|
- byteOff += 4;
|
|
|
- }
|
|
|
- byteLength = meshAttributeArray.length * 4;
|
|
|
- break;
|
|
|
+ else if (vertexBufferKind === BABYLON.VertexBuffer.TangentKind || vertexBufferKind === BABYLON.VertexBuffer.ColorKind) {
|
|
|
+ var vertexData = new BABYLON.Vector4(meshAttributeArray[index], meshAttributeArray[index + 1], meshAttributeArray[index + 2], meshAttributeArray[index + 3]);
|
|
|
+ vector = (this.convertToRightHandedSystem && !(vertexBufferKind === BABYLON.VertexBuffer.ColorKind)) ? _Exporter.GetRightHandedVector4(vertexData).asArray() : vertexData.asArray();
|
|
|
}
|
|
|
- case BABYLON.VertexBuffer.UVKind: {
|
|
|
- for (var k = start; k < end; ++k) {
|
|
|
- var index = k * strideSize;
|
|
|
- dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
|
|
|
- byteOff += 4;
|
|
|
- dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 1], true);
|
|
|
- byteOff += 4;
|
|
|
- }
|
|
|
- byteLength = meshAttributeArray.length * 4;
|
|
|
- break;
|
|
|
+ else if (vertexBufferKind === BABYLON.VertexBuffer.UVKind || vertexBufferKind === BABYLON.VertexBuffer.UV2Kind) {
|
|
|
+ vector = [meshAttributeArray[index], meshAttributeArray[index + 1]];
|
|
|
}
|
|
|
- case BABYLON.VertexBuffer.UV2Kind: {
|
|
|
- for (var k = start; k < end; ++k) {
|
|
|
- var index = k * strideSize;
|
|
|
- dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
|
|
|
- byteOff += 4;
|
|
|
- dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 1], true);
|
|
|
- byteOff += 4;
|
|
|
- }
|
|
|
- byteLength = meshAttributeArray.length * 4;
|
|
|
- break;
|
|
|
+ else {
|
|
|
+ BABYLON.Tools.Warn("Unsupported Vertex Buffer Type: " + vertexBufferKind);
|
|
|
}
|
|
|
- default: {
|
|
|
- throw new Error("Unsupported vertex buffer type: " + vertexBufferKind);
|
|
|
+ for (var i = 0; i < vector.length; ++i) {
|
|
|
+ dataBuffer.setFloat32(byteOff, vector[i], true);
|
|
|
+ byteOff += 4;
|
|
|
}
|
|
|
}
|
|
|
+ byteLength = meshAttributeArray.length * 4;
|
|
|
return byteLength;
|
|
|
};
|
|
|
/**
|
|
@@ -439,32 +381,32 @@ var BABYLON;
|
|
|
var glTF = {
|
|
|
asset: this.asset
|
|
|
};
|
|
|
- if (buffer.byteLength > 0) {
|
|
|
+ if (buffer.byteLength) {
|
|
|
glTF.buffers = [buffer];
|
|
|
}
|
|
|
- if (this.nodes && this.nodes.length !== 0) {
|
|
|
+ if (this.nodes && this.nodes.length) {
|
|
|
glTF.nodes = this.nodes;
|
|
|
}
|
|
|
- if (this.meshes && this.meshes.length !== 0) {
|
|
|
+ if (this.meshes && this.meshes.length) {
|
|
|
glTF.meshes = this.meshes;
|
|
|
}
|
|
|
- if (this.scenes && this.scenes.length !== 0) {
|
|
|
+ if (this.scenes && this.scenes.length) {
|
|
|
glTF.scenes = this.scenes;
|
|
|
glTF.scene = 0;
|
|
|
}
|
|
|
- if (this.bufferViews && this.bufferViews.length !== 0) {
|
|
|
+ if (this.bufferViews && this.bufferViews.length) {
|
|
|
glTF.bufferViews = this.bufferViews;
|
|
|
}
|
|
|
- if (this.accessors && this.accessors.length !== 0) {
|
|
|
+ if (this.accessors && this.accessors.length) {
|
|
|
glTF.accessors = this.accessors;
|
|
|
}
|
|
|
- if (this.materials && this.materials.length !== 0) {
|
|
|
+ if (this.materials && this.materials.length) {
|
|
|
glTF.materials = this.materials;
|
|
|
}
|
|
|
- if (this.textures && this.textures.length !== 0) {
|
|
|
+ if (this.textures && this.textures.length) {
|
|
|
glTF.textures = this.textures;
|
|
|
}
|
|
|
- if (this.images && this.images.length !== 0) {
|
|
|
+ if (this.images && this.images.length) {
|
|
|
if (!shouldUseGlb) {
|
|
|
glTF.images = this.images;
|
|
|
}
|
|
@@ -475,7 +417,7 @@ var BABYLON;
|
|
|
var byteOffset = this.totalByteLength;
|
|
|
for (var i = 0; i < imageLength; ++i) {
|
|
|
var image = this.images[i];
|
|
|
- if (image.uri !== undefined) {
|
|
|
+ if (image.uri) {
|
|
|
var imageData = this.imageData[image.uri];
|
|
|
var imageName = image.uri.split('.')[0] + " image";
|
|
|
var bufferView = this.createBufferView(0, byteOffset, imageData.data.length, undefined, imageName);
|
|
@@ -503,15 +445,15 @@ var BABYLON;
|
|
|
* @returns - GLTFData with glTF file data.
|
|
|
*/
|
|
|
_Exporter.prototype._generateGLTF = function (glTFPrefix) {
|
|
|
- var jsonText = this.generateJSON(false, glTFPrefix, true);
|
|
|
var binaryBuffer = this.generateBinary();
|
|
|
+ var jsonText = this.generateJSON(false, glTFPrefix, true);
|
|
|
var bin = new Blob([binaryBuffer], { type: 'application/octet-stream' });
|
|
|
var glTFFileName = glTFPrefix + '.gltf';
|
|
|
var glTFBinFile = glTFPrefix + '.bin';
|
|
|
var container = new BABYLON._GLTFData();
|
|
|
container.glTFFiles[glTFFileName] = jsonText;
|
|
|
container.glTFFiles[glTFBinFile] = bin;
|
|
|
- if (this.imageData !== null) {
|
|
|
+ if (this.imageData) {
|
|
|
for (var image in this.imageData) {
|
|
|
container.glTFFiles[image] = new Blob([this.imageData[image].data], { type: this.imageData[image].mimeType });
|
|
|
}
|
|
@@ -524,10 +466,8 @@ var BABYLON;
|
|
|
*/
|
|
|
_Exporter.prototype.generateBinary = function () {
|
|
|
var byteOffset = 0;
|
|
|
- var binaryBuffer = new ArrayBuffer(this.totalByteLength);
|
|
|
- var dataBuffer = new DataView(binaryBuffer);
|
|
|
- byteOffset = this.createScene(this.babylonScene, byteOffset, dataBuffer);
|
|
|
- return binaryBuffer;
|
|
|
+ byteOffset = this.createScene(this.babylonScene, byteOffset);
|
|
|
+ return this.binaryBuffer;
|
|
|
};
|
|
|
/**
|
|
|
* Pads the number to a multiple of 4
|
|
@@ -546,8 +486,8 @@ var BABYLON;
|
|
|
* @returns - object with glb filename as key and data as value
|
|
|
*/
|
|
|
_Exporter.prototype._generateGLB = function (glTFPrefix) {
|
|
|
- var jsonText = this.generateJSON(true);
|
|
|
var binaryBuffer = this.generateBinary();
|
|
|
+ var jsonText = this.generateJSON(true);
|
|
|
var glbFileName = glTFPrefix + '.glb';
|
|
|
var headerLength = 12;
|
|
|
var chunkLengthPrefix = 8;
|
|
@@ -613,36 +553,20 @@ var BABYLON;
|
|
|
* Sets the TRS for each node
|
|
|
* @param node - glTF Node for storing the transformation data.
|
|
|
* @param babylonMesh - Babylon mesh used as the source for the transformation data.
|
|
|
- * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
|
|
|
*/
|
|
|
- _Exporter.prototype.setNodeTransformation = function (node, babylonMesh, useRightHandedSystem) {
|
|
|
+ _Exporter.prototype.setNodeTransformation = function (node, babylonMesh) {
|
|
|
if (!(babylonMesh.position.x === 0 && babylonMesh.position.y === 0 && babylonMesh.position.z === 0)) {
|
|
|
- if (useRightHandedSystem) {
|
|
|
- node.translation = babylonMesh.position.asArray();
|
|
|
- }
|
|
|
- else {
|
|
|
- node.translation = [babylonMesh.position.x, babylonMesh.position.y, -babylonMesh.position.z];
|
|
|
- }
|
|
|
+ node.translation = this.convertToRightHandedSystem ? _Exporter.GetRightHandedVector3(babylonMesh.position).asArray() : babylonMesh.position.asArray();
|
|
|
}
|
|
|
if (!(babylonMesh.scaling.x === 1 && babylonMesh.scaling.y === 1 && babylonMesh.scaling.z === 1)) {
|
|
|
- if (useRightHandedSystem) {
|
|
|
- node.scale = babylonMesh.scaling.asArray();
|
|
|
- }
|
|
|
- else {
|
|
|
- node.scale = [babylonMesh.scaling.x, babylonMesh.scaling.y, -babylonMesh.scaling.z];
|
|
|
- }
|
|
|
+ node.scale = babylonMesh.scaling.asArray();
|
|
|
}
|
|
|
var rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(babylonMesh.rotation.y, babylonMesh.rotation.x, babylonMesh.rotation.z);
|
|
|
if (babylonMesh.rotationQuaternion) {
|
|
|
rotationQuaternion = rotationQuaternion.multiply(babylonMesh.rotationQuaternion);
|
|
|
}
|
|
|
if (!(rotationQuaternion.x === 0 && rotationQuaternion.y === 0 && rotationQuaternion.z === 0 && rotationQuaternion.w === 1)) {
|
|
|
- if (useRightHandedSystem) {
|
|
|
- node.rotation = rotationQuaternion.asArray();
|
|
|
- }
|
|
|
- else {
|
|
|
- node.rotation = [-rotationQuaternion.x, -rotationQuaternion.y, rotationQuaternion.z, rotationQuaternion.w];
|
|
|
- }
|
|
|
+ node.rotation = this.convertToRightHandedSystem ? _Exporter.GetRightHandedQuaternion(rotationQuaternion).asArray() : rotationQuaternion.asArray();
|
|
|
}
|
|
|
};
|
|
|
/**
|
|
@@ -650,11 +574,10 @@ var BABYLON;
|
|
|
* @param kind - Indicates the type of vertices data.
|
|
|
* @param babylonMesh - The Babylon mesh to get the vertices data from.
|
|
|
* @param byteOffset - The offset from the buffer to start indexing from.
|
|
|
- * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
|
|
|
* @param dataBuffer - The buffer to write the bufferview data to.
|
|
|
* @returns bytelength of the bufferview data.
|
|
|
*/
|
|
|
- _Exporter.prototype.createBufferViewKind = function (kind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer) {
|
|
|
+ _Exporter.prototype.createBufferViewKind = function (kind, babylonMesh, byteOffset, dataBuffer) {
|
|
|
var bufferMesh = null;
|
|
|
var byteLength = 0;
|
|
|
if (babylonMesh instanceof BABYLON.Mesh) {
|
|
@@ -663,62 +586,29 @@ var BABYLON;
|
|
|
else if (babylonMesh instanceof BABYLON.InstancedMesh) {
|
|
|
bufferMesh = babylonMesh.sourceMesh;
|
|
|
}
|
|
|
- if (bufferMesh !== null) {
|
|
|
+ if (bufferMesh) {
|
|
|
var vertexBuffer = null;
|
|
|
var vertexBufferOffset = null;
|
|
|
var vertexData = null;
|
|
|
var vertexStrideSize = null;
|
|
|
- if (bufferMesh.getVerticesDataKinds().indexOf(kind) > -1) {
|
|
|
+ if (bufferMesh.isVerticesDataPresent(kind)) {
|
|
|
vertexBuffer = bufferMesh.getVertexBuffer(kind);
|
|
|
- vertexBufferOffset = vertexBuffer.getOffset();
|
|
|
- vertexData = vertexBuffer.getData();
|
|
|
- vertexStrideSize = vertexBuffer.getStrideSize();
|
|
|
- if (dataBuffer && vertexData) {
|
|
|
- byteLength = this.writeAttributeData(kind, vertexData, vertexStrideSize, vertexBufferOffset, byteOffset, dataBuffer, useRightHandedSystem);
|
|
|
- byteOffset += byteLength;
|
|
|
- }
|
|
|
- else {
|
|
|
- var bufferViewName = null;
|
|
|
- switch (kind) {
|
|
|
- case BABYLON.VertexBuffer.PositionKind: {
|
|
|
- byteLength = vertexData.length * 4;
|
|
|
- bufferViewName = "Position - " + bufferMesh.name;
|
|
|
- break;
|
|
|
- }
|
|
|
- case BABYLON.VertexBuffer.NormalKind: {
|
|
|
- byteLength = vertexData.length * 4;
|
|
|
- bufferViewName = "Normal - " + bufferMesh.name;
|
|
|
- break;
|
|
|
- }
|
|
|
- case BABYLON.VertexBuffer.TangentKind: {
|
|
|
- byteLength = vertexData.length * 4;
|
|
|
- bufferViewName = "Tangent - " + bufferMesh.name;
|
|
|
- break;
|
|
|
- }
|
|
|
- case BABYLON.VertexBuffer.ColorKind: {
|
|
|
- byteLength = vertexData.length * 4;
|
|
|
- bufferViewName = "Color - " + bufferMesh.name;
|
|
|
- break;
|
|
|
+ if (vertexBuffer) {
|
|
|
+ vertexBufferOffset = vertexBuffer.getOffset();
|
|
|
+ vertexData = vertexBuffer.getData();
|
|
|
+ if (vertexData) {
|
|
|
+ vertexStrideSize = vertexBuffer.getStrideSize();
|
|
|
+ if (dataBuffer && vertexData) {
|
|
|
+ byteLength = this.writeAttributeData(kind, vertexData, vertexStrideSize, vertexBufferOffset, byteOffset, dataBuffer);
|
|
|
+ byteOffset += byteLength;
|
|
|
}
|
|
|
- case BABYLON.VertexBuffer.UVKind: {
|
|
|
+ else {
|
|
|
byteLength = vertexData.length * 4;
|
|
|
- bufferViewName = "TexCoord 0 - " + bufferMesh.name;
|
|
|
- break;
|
|
|
- }
|
|
|
- case BABYLON.VertexBuffer.UV2Kind: {
|
|
|
- byteLength = vertexData.length * 4;
|
|
|
- bufferViewName = "TexCoord 1 - " + bufferMesh.name;
|
|
|
- break;
|
|
|
- }
|
|
|
- default: {
|
|
|
- BABYLON.Tools.Warn("Unsupported VertexBuffer kind: " + kind);
|
|
|
+ var bufferView = this.createBufferView(0, byteOffset, byteLength, vertexStrideSize * 4, kind + " - " + bufferMesh.name);
|
|
|
+ byteOffset += byteLength;
|
|
|
+ this.bufferViews.push(bufferView);
|
|
|
}
|
|
|
}
|
|
|
- if (bufferViewName !== null) {
|
|
|
- var bufferView = this.createBufferView(0, byteOffset, byteLength, vertexStrideSize * 4, bufferViewName);
|
|
|
- byteOffset += byteLength;
|
|
|
- this.bufferViews.push(bufferView);
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -729,11 +619,10 @@ var BABYLON;
|
|
|
* @param mesh - glTF Mesh object to store the primitive attribute information.
|
|
|
* @param babylonMesh - Babylon mesh to get the primitive attribute data from.
|
|
|
* @param byteOffset - The offset in bytes of the buffer data.
|
|
|
- * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
|
|
|
* @param dataBuffer - Buffer to write the attribute data to.
|
|
|
* @returns - bytelength of the primitive attributes plus the passed in byteOffset.
|
|
|
*/
|
|
|
- _Exporter.prototype.setPrimitiveAttributes = function (mesh, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer) {
|
|
|
+ _Exporter.prototype.setPrimitiveAttributes = function (mesh, babylonMesh, byteOffset, dataBuffer) {
|
|
|
var bufferMesh = null;
|
|
|
if (babylonMesh instanceof BABYLON.Mesh) {
|
|
|
bufferMesh = babylonMesh;
|
|
@@ -741,147 +630,134 @@ var BABYLON;
|
|
|
else if (babylonMesh instanceof BABYLON.InstancedMesh) {
|
|
|
bufferMesh = babylonMesh.sourceMesh;
|
|
|
}
|
|
|
- var positionBufferViewIndex = null;
|
|
|
- var normalBufferViewIndex = null;
|
|
|
- var colorBufferViewIndex = null;
|
|
|
- var tangentBufferViewIndex = null;
|
|
|
- var texCoord0BufferViewIndex = null;
|
|
|
- var texCoord1BufferViewIndex = null;
|
|
|
+ var attributeData = [
|
|
|
+ { kind: BABYLON.VertexBuffer.PositionKind, accessorType: "VEC3" /* VEC3 */ },
|
|
|
+ { kind: BABYLON.VertexBuffer.NormalKind, accessorType: "VEC3" /* VEC3 */ },
|
|
|
+ { kind: BABYLON.VertexBuffer.ColorKind, accessorType: "VEC4" /* VEC4 */ },
|
|
|
+ { kind: BABYLON.VertexBuffer.TangentKind, accessorType: "VEC4" /* VEC4 */ },
|
|
|
+ { kind: BABYLON.VertexBuffer.UVKind, accessorType: "VEC2" /* VEC2 */ },
|
|
|
+ { kind: BABYLON.VertexBuffer.UV2Kind, accessorType: "VEC2" /* VEC2 */ },
|
|
|
+ ];
|
|
|
var indexBufferViewIndex = null;
|
|
|
- if (bufferMesh !== null) {
|
|
|
+ if (bufferMesh) {
|
|
|
// For each BabylonMesh, create bufferviews for each 'kind'
|
|
|
- if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.PositionKind)) {
|
|
|
- byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.PositionKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
|
|
|
- positionBufferViewIndex = this.bufferViews.length - 1;
|
|
|
- }
|
|
|
- if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
|
|
|
- byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.NormalKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
|
|
|
- normalBufferViewIndex = this.bufferViews.length - 1;
|
|
|
- }
|
|
|
- if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.ColorKind)) {
|
|
|
- byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.ColorKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
|
|
|
- colorBufferViewIndex = this.bufferViews.length - 1;
|
|
|
- }
|
|
|
- if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.TangentKind)) {
|
|
|
- byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.TangentKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
|
|
|
- colorBufferViewIndex = this.bufferViews.length - 1;
|
|
|
- }
|
|
|
- if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
|
|
|
- byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.UVKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
|
|
|
- texCoord0BufferViewIndex = this.bufferViews.length - 1;
|
|
|
- }
|
|
|
- if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UV2Kind)) {
|
|
|
- byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.UV2Kind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
|
|
|
- texCoord1BufferViewIndex = this.bufferViews.length - 1;
|
|
|
- }
|
|
|
- if (bufferMesh.getTotalIndices() > 0) {
|
|
|
- var indices = bufferMesh.getIndices();
|
|
|
- if (dataBuffer) {
|
|
|
- var end = indices.length;
|
|
|
- var byteOff = byteOffset;
|
|
|
- for (var k = 0; k < end; ++k) {
|
|
|
- dataBuffer.setUint32(byteOff, indices[k], true);
|
|
|
- byteOff += 4;
|
|
|
- }
|
|
|
- byteOffset = byteOff;
|
|
|
- }
|
|
|
- else {
|
|
|
- var byteLength = indices.length * 4;
|
|
|
- var bufferView = this.createBufferView(0, byteOffset, byteLength, undefined, "Indices - " + bufferMesh.name);
|
|
|
- byteOffset += byteLength;
|
|
|
- this.bufferViews.push(bufferView);
|
|
|
- indexBufferViewIndex = this.bufferViews.length - 1;
|
|
|
+ for (var _i = 0, attributeData_1 = attributeData; _i < attributeData_1.length; _i++) {
|
|
|
+ var attribute = attributeData_1[_i];
|
|
|
+ var attributeKind = attribute.kind;
|
|
|
+ if (bufferMesh.isVerticesDataPresent(attributeKind)) {
|
|
|
+ byteOffset += this.createBufferViewKind(attributeKind, babylonMesh, byteOffset, dataBuffer);
|
|
|
+ attribute.bufferViewIndex = this.bufferViews.length - 1;
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
- // go through all mesh primitives (submeshes)
|
|
|
- for (var j = 0; j < babylonMesh.subMeshes.length; ++j) {
|
|
|
- var submesh = babylonMesh.subMeshes[j];
|
|
|
- var meshPrimitive = { attributes: {} };
|
|
|
- if (bufferMesh !== null) {
|
|
|
- // Create a bufferview storing all the positions
|
|
|
- if (!dataBuffer) {
|
|
|
- // Loop through each attribute of the submesh (mesh primitive)
|
|
|
- if (positionBufferViewIndex !== null) {
|
|
|
- var positionVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.PositionKind);
|
|
|
- var positions = positionVertexBuffer.getData();
|
|
|
- var positionStrideSize = positionVertexBuffer.getStrideSize();
|
|
|
- // Create accessor
|
|
|
- var result = this.calculateMinMax(positions, 0, positions.length / positionStrideSize, positionStrideSize, useRightHandedSystem);
|
|
|
- var accessor = this.createAccessor(positionBufferViewIndex, "Position", "VEC3" /* VEC3 */, 5126 /* FLOAT */, positions.length / positionStrideSize, 0, result.min, result.max);
|
|
|
- this.accessors.push(accessor);
|
|
|
- meshPrimitive.attributes.POSITION = this.accessors.length - 1;
|
|
|
- }
|
|
|
- if (normalBufferViewIndex !== null) {
|
|
|
- var normalVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.NormalKind);
|
|
|
- var normals = normalVertexBuffer.getData();
|
|
|
- var normalStrideSize = normalVertexBuffer.getStrideSize();
|
|
|
- // Create accessor
|
|
|
- var accessor = this.createAccessor(normalBufferViewIndex, "Normal", "VEC3" /* VEC3 */, 5126 /* FLOAT */, normals.length / normalStrideSize);
|
|
|
- this.accessors.push(accessor);
|
|
|
- meshPrimitive.attributes.NORMAL = this.accessors.length - 1;
|
|
|
- }
|
|
|
- if (tangentBufferViewIndex !== null) {
|
|
|
- var tangentVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.TangentKind);
|
|
|
- var tangents = tangentVertexBuffer.getData();
|
|
|
- var tangentStrideSize = tangentVertexBuffer.getStrideSize();
|
|
|
- // Create accessor
|
|
|
- var accessor = this.createAccessor(tangentBufferViewIndex, "Tangent", "VEC4" /* VEC4 */, 5126 /* FLOAT */, tangents.length / tangentStrideSize);
|
|
|
- this.accessors.push(accessor);
|
|
|
- meshPrimitive.attributes.TANGENT = this.accessors.length - 1;
|
|
|
- }
|
|
|
- if (colorBufferViewIndex !== null) {
|
|
|
- var colorVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.ColorKind);
|
|
|
- var colors = colorVertexBuffer.getData();
|
|
|
- var colorStrideSize = colorVertexBuffer.getStrideSize();
|
|
|
- // Create accessor
|
|
|
- var accessor = this.createAccessor(colorBufferViewIndex, "Color", "VEC4" /* VEC4 */, 5126 /* FLOAT */, colors.length / colorStrideSize);
|
|
|
- this.accessors.push(accessor);
|
|
|
- meshPrimitive.attributes.COLOR_0 = this.accessors.length - 1;
|
|
|
- }
|
|
|
- if (texCoord0BufferViewIndex !== null) {
|
|
|
- // Create accessor
|
|
|
- var texCoord0VertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.UVKind);
|
|
|
- var texCoord0s = texCoord0VertexBuffer.getData();
|
|
|
- var texCoord0StrideSize = texCoord0VertexBuffer.getStrideSize();
|
|
|
- var accessor = this.createAccessor(texCoord0BufferViewIndex, "Texture Coords 0", "VEC2" /* VEC2 */, 5126 /* FLOAT */, texCoord0s.length / texCoord0StrideSize);
|
|
|
- this.accessors.push(accessor);
|
|
|
- meshPrimitive.attributes.TEXCOORD_0 = this.accessors.length - 1;
|
|
|
- }
|
|
|
- if (texCoord1BufferViewIndex !== null) {
|
|
|
- // Create accessor
|
|
|
- var texCoord1VertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.UV2Kind);
|
|
|
- var texCoord1s = texCoord1VertexBuffer.getData();
|
|
|
- var texCoord1StrideSize = texCoord1VertexBuffer.getStrideSize();
|
|
|
- var accessor = this.createAccessor(texCoord1BufferViewIndex, "Texture Coords 1", "VEC2" /* VEC2 */, 5126 /* FLOAT */, texCoord1s.length / texCoord1StrideSize);
|
|
|
- this.accessors.push(accessor);
|
|
|
- meshPrimitive.attributes.TEXCOORD_1 = this.accessors.length - 1;
|
|
|
+ if (bufferMesh.getTotalIndices()) {
|
|
|
+ var indices = bufferMesh.getIndices();
|
|
|
+ if (indices) {
|
|
|
+ if (dataBuffer) {
|
|
|
+ var end = indices.length;
|
|
|
+ var byteOff = byteOffset;
|
|
|
+ for (var k = 0; k < end; ++k) {
|
|
|
+ dataBuffer.setUint32(byteOff, indices[k], true);
|
|
|
+ byteOff += 4;
|
|
|
+ }
|
|
|
+ byteOffset = byteOff;
|
|
|
}
|
|
|
- if (indexBufferViewIndex) {
|
|
|
- // Create accessor
|
|
|
- var accessor = this.createAccessor(indexBufferViewIndex, "Indices", "SCALAR" /* SCALAR */, 5125 /* UNSIGNED_INT */, submesh.indexCount, submesh.indexStart * 4);
|
|
|
- this.accessors.push(accessor);
|
|
|
- meshPrimitive.indices = this.accessors.length - 1;
|
|
|
+ else {
|
|
|
+ var byteLength = indices.length * 4;
|
|
|
+ var bufferView = this.createBufferView(0, byteOffset, byteLength, undefined, "Indices - " + bufferMesh.name);
|
|
|
+ byteOffset += byteLength;
|
|
|
+ this.bufferViews.push(bufferView);
|
|
|
+ indexBufferViewIndex = this.bufferViews.length - 1;
|
|
|
}
|
|
|
}
|
|
|
- if (bufferMesh.material) {
|
|
|
- if (bufferMesh.material instanceof BABYLON.StandardMaterial || bufferMesh.material instanceof BABYLON.PBRMetallicRoughnessMaterial) {
|
|
|
- var materialIndex = babylonMesh.getScene().materials.indexOf(bufferMesh.material);
|
|
|
- meshPrimitive.material = materialIndex;
|
|
|
+ }
|
|
|
+ if (babylonMesh.subMeshes) {
|
|
|
+ // go through all mesh primitives (submeshes)
|
|
|
+ for (var _a = 0, _b = babylonMesh.subMeshes; _a < _b.length; _a++) {
|
|
|
+ var submesh = _b[_a];
|
|
|
+ var meshPrimitive = { attributes: {} };
|
|
|
+ // Create a bufferview storing all the positions
|
|
|
+ if (!dataBuffer) {
|
|
|
+ for (var _c = 0, attributeData_2 = attributeData; _c < attributeData_2.length; _c++) {
|
|
|
+ var attribute = attributeData_2[_c];
|
|
|
+ var attributeKind = attribute.kind;
|
|
|
+ if (bufferMesh.isVerticesDataPresent(attributeKind)) {
|
|
|
+ var vertexBuffer = bufferMesh.getVertexBuffer(attributeKind);
|
|
|
+ if (vertexBuffer) {
|
|
|
+ var bufferData = vertexBuffer.getData();
|
|
|
+ if (bufferData) {
|
|
|
+ var strideSize = vertexBuffer.getStrideSize();
|
|
|
+ var minMax = void 0;
|
|
|
+ var min = null;
|
|
|
+ var max = null;
|
|
|
+ var bufferViewIndex = attribute.bufferViewIndex;
|
|
|
+ if (bufferViewIndex != undefined) {
|
|
|
+ if (attributeKind == BABYLON.VertexBuffer.PositionKind) {
|
|
|
+ minMax = this.calculateMinMaxPositions(bufferData, 0, bufferData.length / strideSize);
|
|
|
+ min = minMax.min;
|
|
|
+ max = minMax.max;
|
|
|
+ }
|
|
|
+ var accessor = this.createAccessor(bufferViewIndex, attributeKind + " - " + babylonMesh.name, attribute.accessorType, 5126 /* FLOAT */, bufferData.length / strideSize, 0, min, max);
|
|
|
+ this.accessors.push(accessor);
|
|
|
+ switch (attributeKind) {
|
|
|
+ case BABYLON.VertexBuffer.PositionKind: {
|
|
|
+ meshPrimitive.attributes.POSITION = this.accessors.length - 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case BABYLON.VertexBuffer.NormalKind: {
|
|
|
+ meshPrimitive.attributes.NORMAL = this.accessors.length - 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case BABYLON.VertexBuffer.ColorKind: {
|
|
|
+ meshPrimitive.attributes.COLOR_0 = this.accessors.length - 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case BABYLON.VertexBuffer.TangentKind: {
|
|
|
+ meshPrimitive.attributes.TANGENT = this.accessors.length - 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case BABYLON.VertexBuffer.UVKind: {
|
|
|
+ meshPrimitive.attributes.TEXCOORD_0 = this.accessors.length - 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case BABYLON.VertexBuffer.UV2Kind: {
|
|
|
+ meshPrimitive.attributes.TEXCOORD_1 = this.accessors.length - 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ default: {
|
|
|
+ BABYLON.Tools.Warn("Unsupported Vertex Buffer Type: " + attributeKind);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (indexBufferViewIndex) {
|
|
|
+ // Create accessor
|
|
|
+ var accessor = this.createAccessor(indexBufferViewIndex, "indices - " + babylonMesh.name, "SCALAR" /* SCALAR */, 5125 /* UNSIGNED_INT */, submesh.indexCount, submesh.indexStart * 4, null, null);
|
|
|
+ this.accessors.push(accessor);
|
|
|
+ meshPrimitive.indices = this.accessors.length - 1;
|
|
|
+ }
|
|
|
}
|
|
|
- else if (bufferMesh.material instanceof BABYLON.MultiMaterial) {
|
|
|
- var babylonMultiMaterial = bufferMesh.material;
|
|
|
- var material = babylonMultiMaterial.subMaterials[submesh.materialIndex];
|
|
|
- if (material !== null) {
|
|
|
- var materialIndex = babylonMesh.getScene().materials.indexOf(material);
|
|
|
+ if (bufferMesh.material) {
|
|
|
+ if (bufferMesh.material instanceof BABYLON.StandardMaterial || bufferMesh.material instanceof BABYLON.PBRMetallicRoughnessMaterial) {
|
|
|
+ var materialIndex = babylonMesh.getScene().materials.indexOf(bufferMesh.material);
|
|
|
meshPrimitive.material = materialIndex;
|
|
|
}
|
|
|
+ else if (bufferMesh.material instanceof BABYLON.MultiMaterial) {
|
|
|
+ var babylonMultiMaterial = bufferMesh.material;
|
|
|
+ var material = babylonMultiMaterial.subMaterials[submesh.materialIndex];
|
|
|
+ if (material) {
|
|
|
+ var materialIndex = babylonMesh.getScene().materials.indexOf(material);
|
|
|
+ meshPrimitive.material = materialIndex;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ BABYLON.Tools.Warn("Material type " + bufferMesh.material.getClassName() + " for material " + bufferMesh.material.name + " is not yet implemented in glTF serializer.");
|
|
|
+ }
|
|
|
}
|
|
|
- else {
|
|
|
- BABYLON.Tools.Warn("Material type " + bufferMesh.material.getClassName() + " for material " + bufferMesh.material.name + " is not yet implemented in glTF serializer.");
|
|
|
- }
|
|
|
+ mesh.primitives.push(meshPrimitive);
|
|
|
}
|
|
|
- mesh.primitives.push(meshPrimitive);
|
|
|
}
|
|
|
}
|
|
|
return byteOffset;
|
|
@@ -891,47 +767,90 @@ var BABYLON;
|
|
|
* Returns the the total byte offset.
|
|
|
* @param babylonScene - Babylon scene to get the mesh data from.
|
|
|
* @param byteOffset - Offset to start from in bytes.
|
|
|
- * @param dataBuffer - Buffer to write geometry data to.
|
|
|
* @returns bytelength + byteoffset
|
|
|
*/
|
|
|
- _Exporter.prototype.createScene = function (babylonScene, byteOffset, dataBuffer) {
|
|
|
- if (babylonScene.meshes.length > 0) {
|
|
|
+ _Exporter.prototype.createScene = function (babylonScene, byteOffset) {
|
|
|
+ if (babylonScene.meshes.length) {
|
|
|
var babylonMeshes = babylonScene.meshes;
|
|
|
var scene = { nodes: new Array() };
|
|
|
- if (dataBuffer == null) {
|
|
|
- GLTF2._GLTFMaterial.ConvertMaterialsToGLTF(babylonScene.materials, "image/jpeg" /* JPEG */, this.images, this.textures, this.materials, this.imageData, true);
|
|
|
- }
|
|
|
+ GLTF2._GLTFMaterial.ConvertMaterialsToGLTF(babylonScene.materials, "image/jpeg" /* JPEG */, this.images, this.textures, this.materials, this.imageData, true);
|
|
|
+ var result = this.createNodeMap(babylonScene, byteOffset);
|
|
|
+ this.nodeMap = result.nodeMap;
|
|
|
+ this.totalByteLength = result.byteOffset;
|
|
|
+ this.binaryBuffer = new ArrayBuffer(this.totalByteLength);
|
|
|
+ var dataBuffer = new DataView(this.binaryBuffer);
|
|
|
for (var i = 0; i < babylonMeshes.length; ++i) {
|
|
|
if (this.options &&
|
|
|
- this.options.shouldExportMesh !== undefined &&
|
|
|
+ this.options.shouldExportMesh != undefined &&
|
|
|
!this.options.shouldExportMesh(babylonMeshes[i])) {
|
|
|
continue;
|
|
|
}
|
|
|
else {
|
|
|
- // create node to hold translation/rotation/scale and the mesh
|
|
|
- var node = { mesh: -1 };
|
|
|
var babylonMesh = babylonMeshes[i];
|
|
|
- var useRightHandedSystem = babylonMesh.getScene().useRightHandedSystem;
|
|
|
- // Set transformation
|
|
|
- this.setNodeTransformation(node, babylonMesh, useRightHandedSystem);
|
|
|
- // create mesh
|
|
|
- var mesh = { primitives: new Array() };
|
|
|
- mesh.primitives = [];
|
|
|
- byteOffset = this.setPrimitiveAttributes(mesh, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
|
|
|
- // go through all mesh primitives (submeshes)
|
|
|
- this.meshes.push(mesh);
|
|
|
- node.mesh = this.meshes.length - 1;
|
|
|
- if (babylonMesh.name) {
|
|
|
- node.name = babylonMesh.name;
|
|
|
+ // Build Hierarchy with the node map.
|
|
|
+ var glTFNodeIndex = this.nodeMap[babylonMesh.uniqueId];
|
|
|
+ var glTFNode = this.nodes[glTFNodeIndex];
|
|
|
+ if (!babylonMesh.parent) {
|
|
|
+ scene.nodes.push(glTFNodeIndex);
|
|
|
}
|
|
|
- this.nodes.push(node);
|
|
|
- scene.nodes.push(this.nodes.length - 1);
|
|
|
+ var directDescendents = babylonMesh.getDescendants(true);
|
|
|
+ if (!glTFNode.children && directDescendents && directDescendents.length) {
|
|
|
+ glTFNode.children = [];
|
|
|
+ for (var _i = 0, directDescendents_1 = directDescendents; _i < directDescendents_1.length; _i++) {
|
|
|
+ var descendent = directDescendents_1[_i];
|
|
|
+ glTFNode.children.push(this.nodeMap[descendent.uniqueId]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ var mesh = { primitives: new Array() };
|
|
|
+ byteOffset = this.setPrimitiveAttributes(mesh, babylonMesh, byteOffset, dataBuffer);
|
|
|
}
|
|
|
}
|
|
|
this.scenes.push(scene);
|
|
|
}
|
|
|
return byteOffset;
|
|
|
};
|
|
|
+ /**
|
|
|
+ * Creates a mapping of Node unique id to node index
|
|
|
+ * @param scene - Babylon Scene.
|
|
|
+ * @param byteOffset - The initial byte offset.
|
|
|
+ * @returns - Node mapping of unique id to index.
|
|
|
+ */
|
|
|
+ _Exporter.prototype.createNodeMap = function (scene, byteOffset) {
|
|
|
+ var nodeMap = {};
|
|
|
+ for (var _i = 0, _a = scene.meshes; _i < _a.length; _i++) {
|
|
|
+ var babylonMesh = _a[_i];
|
|
|
+ var result = this.createNode(babylonMesh, byteOffset, null);
|
|
|
+ this.nodes.push(result.node);
|
|
|
+ nodeMap[babylonMesh.uniqueId] = this.nodes.length - 1;
|
|
|
+ byteOffset = result.byteOffset;
|
|
|
+ }
|
|
|
+ return { nodeMap: nodeMap, byteOffset: byteOffset };
|
|
|
+ };
|
|
|
+ /**
|
|
|
+ * Creates a glTF node from a Babylon mesh.
|
|
|
+ * @param babylonMesh - Source Babylon mesh.
|
|
|
+ * @param byteOffset - The initial byte offset.
|
|
|
+ * @param dataBuffer - Buffer for storing geometry data.
|
|
|
+ * @returns - Object containing an INode and byteoffset.
|
|
|
+ */
|
|
|
+ _Exporter.prototype.createNode = function (babylonMesh, byteOffset, dataBuffer) {
|
|
|
+ // create node to hold translation/rotation/scale and the mesh
|
|
|
+ var node = {};
|
|
|
+ if (babylonMesh.name) {
|
|
|
+ node.name = babylonMesh.name;
|
|
|
+ }
|
|
|
+ // Set transformation
|
|
|
+ this.setNodeTransformation(node, babylonMesh);
|
|
|
+ // create mesh
|
|
|
+ var mesh = { primitives: new Array() };
|
|
|
+ mesh.primitives = [];
|
|
|
+ byteOffset = this.setPrimitiveAttributes(mesh, babylonMesh, byteOffset, dataBuffer);
|
|
|
+ if (mesh.primitives.length) {
|
|
|
+ this.meshes.push(mesh);
|
|
|
+ node.mesh = this.meshes.length - 1;
|
|
|
+ }
|
|
|
+ return { node: node, byteOffset: byteOffset };
|
|
|
+ };
|
|
|
return _Exporter;
|
|
|
}());
|
|
|
GLTF2._Exporter = _Exporter;
|