Browse Source

SceneBuilder, fixed excessive cloning, fixed incorrect transform assignment

Vicente Penades 3 years ago
parent
commit
b1cac43ea4

+ 1 - 1
src/SharpGLTF.Core/Transforms/AffineTransform.cs

@@ -21,7 +21,7 @@ namespace SharpGLTF.Transforms
     /// <remarks>
     /// <remarks>
     /// <para>
     /// <para>
     /// Depending on how <see cref="AffineTransform"/> structures are created, the underlaying<br/>
     /// Depending on how <see cref="AffineTransform"/> structures are created, the underlaying<br/>
-    /// fields must be interprested as a Matrix4x3 or a Scale/Rotation/Translation chain.
+    /// fields must be interpreted as a Matrix4x3 or a Scale/Rotation/Translation chain.
     /// </para>
     /// </para>
     /// <para>
     /// <para>
     /// This approach allows <see cref="AffineTransform"/> preserving the source transform, avoiding loosing<br/>
     /// This approach allows <see cref="AffineTransform"/> preserving the source transform, avoiding loosing<br/>

+ 2 - 2
src/SharpGLTF.Toolkit/Scenes/Content.cs

@@ -40,7 +40,7 @@ namespace SharpGLTF.Scenes
 
 
         public MeshContent(MESHBUILDER mesh)
         public MeshContent(MESHBUILDER mesh)
         {
         {
-            _Mesh = mesh;
+            this._Mesh = mesh;
         }
         }
 
 
         public Object Clone()
         public Object Clone()
@@ -50,7 +50,7 @@ namespace SharpGLTF.Scenes
 
 
         private MeshContent(MeshContent other)
         private MeshContent(MeshContent other)
         {
         {
-            this._Mesh = other._Mesh?.Clone(m => m.Clone());
+            this._Mesh = other._Mesh;
         }
         }
 
 
         #endregion
         #endregion

+ 10 - 2
src/SharpGLTF.Toolkit/Scenes/SceneBuilder.cs

@@ -245,6 +245,7 @@ namespace SharpGLTF.Scenes
         {
         {
             return _Instances
             return _Instances
                 .Select(item => item.Content.GetArmatureRoot())
                 .Select(item => item.Content.GetArmatureRoot())
+                .Where(item => item != null)
                 .Distinct()
                 .Distinct()
                 .ToList();
                 .ToList();
         }
         }
@@ -262,8 +263,16 @@ namespace SharpGLTF.Scenes
         /// </remarks>
         /// </remarks>
         public void ApplyBasisTransform(Matrix4x4 basisTransform, string basisNodeName = "BasisTransform")
         public void ApplyBasisTransform(Matrix4x4 basisTransform, string basisNodeName = "BasisTransform")
         {
         {
+            if (basisTransform == Matrix4x4.Identity) return;
+
             Guard.IsTrue(basisTransform.IsValid(_Extensions.MatrixCheck.WorldTransform), nameof(basisTransform));
             Guard.IsTrue(basisTransform.IsValid(_Extensions.MatrixCheck.WorldTransform), nameof(basisTransform));
 
 
+            // find all explicit transforms
+            foreach (var fixedXform in _Instances.Select(item => item.Content).OfType<FixedTransformer>())
+            {
+                fixedXform.ChildTransform = Transforms.AffineTransform.Multiply(fixedXform.ChildTransform, basisTransform);
+            }
+
             // gather all root nodes:
             // gather all root nodes:
             var rootNodes = this.FindArmatures();
             var rootNodes = this.FindArmatures();
 
 
@@ -318,8 +327,7 @@ namespace SharpGLTF.Scenes
             Guard.IsTrue(sceneTransform.IsValid(_Extensions.MatrixCheck.WorldTransform), nameof(sceneTransform));
             Guard.IsTrue(sceneTransform.IsValid(_Extensions.MatrixCheck.WorldTransform), nameof(sceneTransform));
 
 
             scene = scene.DeepClone();
             scene = scene.DeepClone();
-
-            if (sceneTransform != Matrix4x4.Identity) scene.ApplyBasisTransform(sceneTransform);
+            scene.ApplyBasisTransform(sceneTransform);
 
 
             this._Instances.AddRange(scene._Instances);
             this._Instances.AddRange(scene._Instances);
 
 

+ 6 - 1
src/SharpGLTF.Toolkit/Scenes/Transformers.cs

@@ -158,6 +158,7 @@ namespace SharpGLTF.Scenes
 
 
             public NodeBuilder GetNode(NodeBuilder node)
             public NodeBuilder GetNode(NodeBuilder node)
             {
             {
+                if (node == null) return null;
                 if (_NodeMap == null) return node;
                 if (_NodeMap == null) return node;
                 return _NodeMap.TryGetValue(node, out NodeBuilder clone) ? clone : node;
                 return _NodeMap.TryGetValue(node, out NodeBuilder clone) ? clone : node;
             }
             }
@@ -240,7 +241,11 @@ namespace SharpGLTF.Scenes
 
 
         public NodeBuilder ParentNode => _ParentNode;
         public NodeBuilder ParentNode => _ParentNode;
 
 
-        public TRANSFORM ChildTransform => _ChildTransform;
+        public TRANSFORM ChildTransform
+        {
+            get => _ChildTransform;
+            set => _ChildTransform = value;
+        }
 
 
         #endregion
         #endregion
 
 

+ 34 - 0
tests/SharpGLTF.Toolkit.Tests/Scenes/SceneBuilderTests.cs

@@ -936,5 +936,39 @@ namespace SharpGLTF.Scenes
             Assert.AreEqual(1, model2.LogicalMeshes.Count); // check the mesh is shared between the 2 scenes
             Assert.AreEqual(1, model2.LogicalMeshes.Count); // check the mesh is shared between the 2 scenes
         }
         }
 
 
+        [Test]
+        public void TestSceneAddition()
+        {
+            // create a cube mesh. This mesh will be shared along the way:
+
+            var cube = new MeshBuilder<VertexPosition, VertexEmpty, VertexEmpty>("Cube");
+            cube.AddCube(MaterialBuilder.CreateDefault(), Matrix4x4.Identity);
+
+            // create a scene
+
+            var scene1 = new SceneBuilder();
+            scene1.AddRigidMesh(cube, Matrix4x4.Identity);
+
+            // create another scene
+
+            var scene2 = new SceneBuilder();
+            scene2.AddScene(scene1, Matrix4x4.CreateTranslation(4, 0, 0));
+
+            Assert.AreEqual(new Vector3(4, 0, 0), scene2.Instances.First().Content.GetPoseWorldMatrix().Translation);
+
+
+            scene2.AddScene(scene1, Matrix4x4.CreateTranslation(2, 0, 0));
+            scene2.AddScene(scene1, Matrix4x4.CreateTranslation(0, 0, 0));
+
+            // convert to gltf
+
+            var gltf = scene2.ToGltf2();
+
+            Assert.AreEqual(1, gltf.LogicalMeshes.Count);
+            Assert.AreEqual(3, gltf.LogicalNodes.Count);
+
+            gltf.AttachToCurrentTest("Three cubes.glb");
+        }
+
     }
     }
 }
 }