/// <inheritdoc/>
        protected override Matrix44F ComputeProjection()
        {
            var projection = Matrix44F.CreatePerspectiveOffCenter(Left, Right, Bottom, Top, Near, Far);

            if (_nearClipPlane.HasValue)
            {
                Vector4F clipPlane = new Vector4F(_nearClipPlane.Value.Normal, -_nearClipPlane.Value.DistanceFromOrigin);

                // Calculate the clip-space corner point opposite the clipping plane as
                // (-sign(clipPlane.x), -sign(clipPlane.y), 1, 1) and transform it into
                // camera space by multiplying it by the inverse of the projection matrix.
                Vector4F q;
                q.X = (-Math.Sign(clipPlane.X) + projection.M02) / projection.M00;
                q.Y = (-Math.Sign(clipPlane.Y) + projection.M12) / projection.M11;
                q.Z = -1.0f;
                q.W = (1.0f + projection.M22) / projection.M23;

                // Calculate the scaled plane vector
                Vector4F c = clipPlane * (1.0f / Vector4F.Dot(clipPlane, q));

                // Replace the third row of the projection matrix
                projection.M20 = c.X;
                projection.M21 = c.Y;
                projection.M22 = c.Z;
                projection.M23 = c.W;
            }

            return(projection);
        }
Пример #2
0
        public void DotProduct()
        {
            // 0°
            Assert.AreEqual(1.0f, Vector4F.Dot(Vector4F.UnitX, Vector4F.UnitX));
            Assert.AreEqual(1.0f, Vector4F.Dot(Vector4F.UnitY, Vector4F.UnitY));
            Assert.AreEqual(1.0f, Vector4F.Dot(Vector4F.UnitZ, Vector4F.UnitZ));
            Assert.AreEqual(1.0f, Vector4F.Dot(Vector4F.UnitW, Vector4F.UnitW));

            // 180°
            Assert.AreEqual(-1.0f, Vector4F.Dot(Vector4F.UnitX, -Vector4F.UnitX));
            Assert.AreEqual(-1.0f, Vector4F.Dot(Vector4F.UnitY, -Vector4F.UnitY));
            Assert.AreEqual(-1.0f, Vector4F.Dot(Vector4F.UnitZ, -Vector4F.UnitZ));
            Assert.AreEqual(-1.0f, Vector4F.Dot(Vector4F.UnitW, -Vector4F.UnitW));

            // 90°
            Assert.AreEqual(0.0f, Vector4F.Dot(Vector4F.UnitX, Vector4F.UnitY));
            Assert.AreEqual(0.0f, Vector4F.Dot(Vector4F.UnitY, Vector4F.UnitZ));
            Assert.AreEqual(0.0f, Vector4F.Dot(Vector4F.UnitZ, Vector4F.UnitW));
            Assert.AreEqual(0.0f, Vector4F.Dot(Vector4F.UnitW, Vector4F.UnitX));

            // 45°
            float angle = (float)Math.Acos(Vector4F.Dot(new Vector4F(1, 1, 0, 0).Normalized, Vector4F.UnitX));

            Assert.IsTrue(Numeric.AreEqual(MathHelper.ToRadians(45), angle));
            angle = (float)Math.Acos(Vector4F.Dot(new Vector4F(0, 1, 1, 0).Normalized, Vector4F.UnitY));
            Assert.IsTrue(Numeric.AreEqual(MathHelper.ToRadians(45), angle));
            angle = (float)Math.Acos(Vector4F.Dot(new Vector4F(1, 0, 1, 0).Normalized, Vector4F.UnitZ));
            Assert.IsTrue(Numeric.AreEqual(MathHelper.ToRadians(45), angle));
            angle = (float)Math.Acos(Vector4F.Dot(new Vector4F(1, 0, 0, 1).Normalized, Vector4F.UnitW));
            Assert.IsTrue(Numeric.AreEqual(MathHelper.ToRadians(45), angle));
        }
Пример #3
0
        /// <summary>
        /// Determines whether the specified matrix is a valid pose matrix.
        /// </summary>
        /// <param name="matrix">The matrix.</param>
        /// <returns>
        /// <see langword="true"/> if the specified matrix is a valid pose matrix; otherwise,
        /// <see langword="false"/>.
        /// </returns>
        /// <remarks>
        /// This method makes a simple, low-performance test.
        /// </remarks>
        public static bool IsValid(Matrix44F matrix)
        {
            Vector4F v1 = matrix * Vector4F.UnitX;
            Vector4F v2 = matrix * Vector4F.UnitY;
            Vector4F v3 = matrix * Vector4F.UnitZ;

            return(Numeric.AreEqual(v1.LengthSquared, 1) &&
                   Numeric.AreEqual(v2.LengthSquared, 1) &&
                   Numeric.AreEqual(v3.LengthSquared, 1) &&
                   Numeric.IsZero(Vector4F.Dot(v1, v2)) &&
                   Numeric.IsZero(Vector4F.Dot(v2, v3)) &&
                   Numeric.IsZero(Vector4F.Dot(v1, v3)) &&
                   Numeric.AreEqual(1.0f, matrix.Determinant) &&
                   Numeric.IsZero(matrix.M30) &&
                   Numeric.IsZero(matrix.M31) &&
                   Numeric.IsZero(matrix.M32) &&
                   Numeric.AreEqual(matrix.M33, 1));
        }
Пример #4
0
        public void Dot()
        {
            Vector4F a = new Vector4F(1.0f, 2.0f, 3.0f, 4.0f);
            Vector4F b = new Vector4F(4.0f, 5.0f, 6.0f, 7.0f);

            double dot = a.Dot(b);
            Assert.AreEqual(1.0f * 4.0f + 2.0f * 5.0f + 3.0f * 6.0f + 4.0f * 7.0f, dot, 1e-14);
        }