Browse Source

Added missing methods and tests to work with cameras

Vicente Penades 6 năm trước cách đây
mục cha
commit
1d6dd90b13

+ 2 - 2
src/SharpGLTF.Core/Schema2/gltf.Camera.cs

@@ -155,7 +155,7 @@ namespace SharpGLTF.Schema2
         /// <summary>
         /// Gets the projection matrix for the current settings
         /// </summary>
-        public System.Numerics.Matrix4x4 Matrix => Transforms.Camera.CreateOrthographicMatrix(XMag, YMag, ZNear, ZFar);
+        public System.Numerics.Matrix4x4 Matrix => Transforms.Projection.CreateOrthographicMatrix(XMag, YMag, ZNear, ZFar);
 
         #endregion
     }
@@ -209,7 +209,7 @@ namespace SharpGLTF.Schema2
         /// <summary>
         /// Gets the projection matrix for the current settings
         /// </summary>
-        public System.Numerics.Matrix4x4 Matrix => Transforms.Camera.CreateOrthographicMatrix(AspectRatio.AsValue(1), VerticalFOV, ZNear, ZFar);
+        public System.Numerics.Matrix4x4 Matrix => Transforms.Projection.CreateOrthographicMatrix(AspectRatio.AsValue(1), VerticalFOV, ZNear, ZFar);
 
         #endregion
     }

+ 16 - 0
src/SharpGLTF.Core/Schema2/gltf.Node.cs

@@ -197,6 +197,22 @@ namespace SharpGLTF.Schema2
 
         #region properties - content
 
+        /// <summary>
+        /// Gets or sets the <see cref="Schema2.Camera"/> of this <see cref="Node"/>.
+        /// </summary>
+        public Camera Camera
+        {
+            get => this._camera.HasValue ? this.LogicalParent.LogicalCameras[this._camera.Value] : null;
+            set
+            {
+                if (value == null) { this._camera = null; return; }
+
+                Guard.MustShareLogicalParent(this.LogicalParent, value, nameof(value));
+
+                this._camera = value.LogicalIndex;
+            }
+        }
+
         /// <summary>
         /// Gets or sets the <see cref="Schema2.Mesh"/> of this <see cref="Node"/>.
         /// </summary>

+ 3 - 4
src/SharpGLTF.Core/Transforms/Camera.cs → src/SharpGLTF.Core/Transforms/Projection.cs

@@ -9,7 +9,7 @@ namespace SharpGLTF.Transforms
     /// Utility class to calculate camera matrices
     /// </summary>
     /// <see href="https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#projection-matrices"/>
-    public static class Camera
+    public static class Projection
     {
         /// <summary>
         /// Calculates an orthographic projection matrix.
@@ -61,8 +61,9 @@ namespace SharpGLTF.Transforms
             Guard.MustBeGreaterThan(zfar, znear, nameof(zfar));
 
             var v = (float)Math.Tan(0.5 * yfov);
+            var h = aspectRatio * v;
 
-            var x = 1 / (aspectRatio * v);
+            var x = 1 / h;
             var y = 1 / v;
             var z = -1f;
             var w = -2 * znear;
@@ -82,7 +83,5 @@ namespace SharpGLTF.Transforms
                 0, 0, -1, 0
                 );
         }
-
-
     }
 }

+ 20 - 0
src/SharpGLTF.Toolkit/Schema2/SceneExtensions.cs

@@ -86,6 +86,26 @@ namespace SharpGLTF.Schema2
                 .WithSkinBinding(joints);
         }
 
+        public static Node WithPerspectiveCamera(this Node node, float? aspectRatio, float fovy, float znear, float zfar = float.PositiveInfinity)
+        {
+            var camera = node.LogicalParent.CreateCamera();
+            camera.SetPerspectiveMode(aspectRatio, fovy, znear, zfar);
+
+            node.Camera = camera;
+
+            return node;
+        }
+
+        public static Node WithOrthographicCamera(this Node node, float xmag, float ymag, float znear, float zfar)
+        {
+            var camera = node.LogicalParent.CreateCamera();
+            camera.SetOrthographicMode(xmag, ymag, znear, zfar);
+
+            node.Camera = camera;
+
+            return node;
+        }
+
         #endregion
 
         #region evaluation

+ 28 - 1
tests/SharpGLTF.Tests/Schema2/Authoring/BasicSceneCreationTests.cs

@@ -186,6 +186,33 @@ namespace SharpGLTF.Schema2.Authoring
 
             model.AttachToCurrentTest("result.glb");
             model.AttachToCurrentTest("result.gltf");
-        }        
+        }
+
+        [Test(Description = "Creates a scene with a perspective camera")]
+        public void CreateSceneWithCamera()
+        {
+            TestContext.CurrentContext.AttachShowDirLink();
+            TestContext.CurrentContext.AttachGltfValidatorLinks();
+
+            var mesh = new Geometry.MeshBuilder<Geometry.VertexTypes.VertexPositionNormal>();
+
+            mesh.AddCube(new Materials.MaterialBuilder(), Matrix4x4.Identity);            
+
+            var model = ModelRoot.CreateModel();
+
+            model.CreateMeshes(mesh);
+
+            model.UseScene(0)
+                .CreateNode()
+                .WithMesh(model.LogicalMeshes[0]);
+
+            model.UseScene(0)
+                .CreateNode()
+                .WithLocalTranslation(new Vector3(0, 3, 10))
+                .WithPerspectiveCamera(null, 1, 0.1f);                
+
+            model.AttachToCurrentTest("result.glb");
+            model.AttachToCurrentTest("result.gltf");
+        }
     }
 }