浏览代码

Ignore the __root__ node used for conversion from right-handed to left-handed when exporting to GLB

noalak 5 年之前
父节点
当前提交
7c58d16e90
共有 2 个文件被更改,包括 43 次插入3 次删除
  1. 1 0
      dist/preview release/what's new.md
  2. 42 3
      serializers/src/glTF/2.0/glTFExporter.ts

+ 1 - 0
dist/preview release/what's new.md

@@ -269,6 +269,7 @@
 - Playground will now render the returned scene from createScene() when there are multiple scenes added to engine ([Kyle Belfort](https://github.com/belfortk))
 - Playground will now render the returned scene from createScene() when there are multiple scenes added to engine ([Kyle Belfort](https://github.com/belfortk))
 - Fixed bug so Playground will now download .env texture files to ./textures in .zip  ([Kyle Belfort](https://github.com/belfortk))
 - Fixed bug so Playground will now download .env texture files to ./textures in .zip  ([Kyle Belfort](https://github.com/belfortk))
 - It was not possible to change the gaze and laser color in VR ([#7323](https://github.com/BabylonJS/Babylon.js/issues/7323)) ([RaananW](https://github.com/RaananW/))
 - It was not possible to change the gaze and laser color in VR ([#7323](https://github.com/BabylonJS/Babylon.js/issues/7323)) ([RaananW](https://github.com/RaananW/))
+- Ignore the root node used for conversion from right-handed to left-handed when exporting to GLB ([noalak](https://github.com/noalak/))
 
 
 ## Breaking changes
 ## Breaking changes
 
 

+ 42 - 3
serializers/src/glTF/2.0/glTFExporter.ts

@@ -1,7 +1,7 @@
 import { AccessorType, IBufferView, IAccessor, INode, IScene, IMesh, IMaterial, ITexture, IImage, ISampler, IAnimation, ImageMimeType, IMeshPrimitive, IBuffer, IGLTF, MeshPrimitiveMode, AccessorComponentType, ITextureInfo } from "babylonjs-gltf2interface";
 import { AccessorType, IBufferView, IAccessor, INode, IScene, IMesh, IMaterial, ITexture, IImage, ISampler, IAnimation, ImageMimeType, IMeshPrimitive, IBuffer, IGLTF, MeshPrimitiveMode, AccessorComponentType, ITextureInfo } from "babylonjs-gltf2interface";
 
 
 import { FloatArray, Nullable, IndicesArray } from "babylonjs/types";
 import { FloatArray, Nullable, IndicesArray } from "babylonjs/types";
-import { Viewport, Color3, Vector2, Vector3, Vector4, Quaternion } from "babylonjs/Maths/math";
+import { Viewport, Color3, Vector2, Vector3, Vector4, Quaternion, Epsilon } from "babylonjs/Maths/math";
 import { Tools } from "babylonjs/Misc/tools";
 import { Tools } from "babylonjs/Misc/tools";
 import { VertexBuffer } from "babylonjs/Meshes/buffer";
 import { VertexBuffer } from "babylonjs/Meshes/buffer";
 import { Node } from "babylonjs/node";
 import { Node } from "babylonjs/node";
@@ -1252,7 +1252,7 @@ export class _Exporter {
                         let sideOrientation = bufferMesh.overrideMaterialSideOrientation !== null ? bufferMesh.overrideMaterialSideOrientation : babylonMaterial.sideOrientation;
                         let sideOrientation = bufferMesh.overrideMaterialSideOrientation !== null ? bufferMesh.overrideMaterialSideOrientation : babylonMaterial.sideOrientation;
 
 
                         // Only reverse the winding if we have a clockwise winding
                         // Only reverse the winding if we have a clockwise winding
-                        if (sideOrientation === Material.ClockWiseSideOrientation) {
+                        if (this._convertToRightHandedSystem && sideOrientation === Material.ClockWiseSideOrientation) {
                             let byteOffset = indexBufferViewIndex != null ? this._bufferViews[indexBufferViewIndex].byteOffset : null;
                             let byteOffset = indexBufferViewIndex != null ? this._bufferViews[indexBufferViewIndex].byteOffset : null;
                             if (byteOffset == null) { byteOffset = 0; }
                             if (byteOffset == null) { byteOffset = 0; }
                             let babylonIndices: Nullable<IndicesArray> = null;
                             let babylonIndices: Nullable<IndicesArray> = null;
@@ -1294,6 +1294,26 @@ export class _Exporter {
     }
     }
 
 
     /**
     /**
+     * Check if the node is used to convert its descendants from right-handed to left-handed
+     * @param node The node to check
+     * @returns True if the node is used to convert its descendants from right-handed to left-handed. False otherwise
+     */
+    private isNodeConvertingToLeftHanded(node: Node): boolean {
+        if (node.name !== "__root__") {
+            return false;
+        }
+
+        if (node instanceof TransformNode &&
+            ((!node.rotationQuaternion && node.rotation && (node.rotation.x != 0 || node.rotation.z != 0 || Math.abs(node.rotation.y - Math.PI) > Epsilon)) || // rotation Quaternion has priority over Vector3
+            (node.rotationQuaternion && !node.rotationQuaternion.equals(new Quaternion(0, 1, 0, 0))) ||
+            !node.scaling.equalsToFloats(1, 1, -1))) {
+                return false;
+        }
+
+        return true;
+    }
+
+    /**
      * Creates a glTF scene based on the array of meshes
      * Creates a glTF scene based on the array of meshes
      * Returns the the total byte offset
      * Returns the the total byte offset
      * @param babylonScene Babylon scene to get the mesh data from
      * @param babylonScene Babylon scene to get the mesh data from
@@ -1305,6 +1325,25 @@ export class _Exporter {
         let glTFNode: INode;
         let glTFNode: INode;
         let directDescendents: Node[];
         let directDescendents: Node[];
         const nodes: Node[] = [...babylonScene.transformNodes, ...babylonScene.meshes, ...babylonScene.lights];
         const nodes: Node[] = [...babylonScene.transformNodes, ...babylonScene.meshes, ...babylonScene.lights];
+        let rootNodeToLeftHanded: Node;
+
+        // Check if a __root__ node is present
+        if (this._convertToRightHandedSystem) {
+            babylonScene.rootNodes.forEach((rootNode) => {
+                if (rootNodeToLeftHanded === undefined && this.isNodeConvertingToLeftHanded(rootNode)) {
+                    rootNodeToLeftHanded = rootNode;
+
+                    // Exclude the node from list of nodes to export
+                    const indexRootNode = nodes.indexOf(rootNode);
+                    if (indexRootNode !== -1) { // should always be true
+                        nodes.splice(indexRootNode, 1);
+                    }
+
+                    // Cancel conversion to right handed system
+                    this._convertToRightHandedSystem = false;
+                }
+            });
+        }
 
 
         return this._glTFMaterialExporter._convertMaterialsToGLTFAsync(babylonScene.materials, ImageMimeType.PNG, true).then(() => {
         return this._glTFMaterialExporter._convertMaterialsToGLTFAsync(babylonScene.materials, ImageMimeType.PNG, true).then(() => {
             return this.createNodeMapAndAnimationsAsync(babylonScene, nodes, binaryWriter).then((nodeMap) => {
             return this.createNodeMapAndAnimationsAsync(babylonScene, nodes, binaryWriter).then((nodeMap) => {
@@ -1329,7 +1368,7 @@ export class _Exporter {
                             }
                             }
                         }
                         }
 
 
-                        if (!babylonNode.parent) {
+                        if (!babylonNode.parent || babylonNode.parent === rootNodeToLeftHanded) {
                             if (this._options.shouldExportNode && !this._options.shouldExportNode(babylonNode)) {
                             if (this._options.shouldExportNode && !this._options.shouldExportNode(babylonNode)) {
                                 Tools.Log("Omitting " + babylonNode.name + " from scene.");
                                 Tools.Log("Omitting " + babylonNode.name + " from scene.");
                             }
                             }