Exemple #1
0
        public static bool UnProject(Vector4d winPos, Matrix4d modelMatrix, Matrix4d projMatrix, double[] viewport, ref Vector4d objPos)
        {
            Matrix4d p           = Matrix4d.Mult(modelMatrix, projMatrix);
            Matrix4d finalMatrix = Matrix4d.Invert(p);
            Vector4d @in         = winPos;

            // Map x and y from window coordinates
            @in.X = (@in.X - viewport[0]) / viewport[2];
            @in.Y = (@in.Y - viewport[1]) / viewport[3];
            // Map to range -1 to 1
            @in.X = @in.X * 2.0 - 1.0;
            @in.Y = @in.Y * 2.0 - 1.0;
            @in.Z = @in.Z * 2.0 - 1.0;
            @in.W = 1.0;
            Vector4d @out = Vector4d.Transform(@in, finalMatrix);

            if (@out.W == 0.0)
            {
                return(false);
            }

            @out.X /= @out.W;
            @out.Y /= @out.W;
            @out.Z /= @out.W;
            objPos  = @out;

            return(true);
        }
Exemple #2
0
 /// <summary>
 /// Inserts one new child node to this parent node.
 /// </summary>
 /// <param name="ch">Child node to add.</param>
 /// <param name="toParent">Transform from local space of the child to the parent's space.</param>
 public virtual void InsertChild(ISceneNode ch, Matrix4d toParent)
 {
     children.AddLast(ch);
     ch.ToParent = toParent;
     toParent.Invert();
     ch.FromParent = toParent;
     ch.Parent     = this;
 }
Exemple #3
0
        /// <summary>
        /// Projects a 2d screenspace coordinate to world coordinates.
        /// </summary>
        public static Vector3d Unproject(Vector3d Point, Matrix4d View, Matrix4d Proj)
        {
            Matrix4d ma    = Matrix4d.Mult(View, Proj);
            Matrix4d ima   = Matrix4d.Invert(ma);
            Vector4d coord = new Vector4d(Point.X, Point.Y, Point.Z, 1.0);
            Vector4d res   = Vector4d.Transform(coord, ima);

            return(new Vector3d(res.X / res.W, res.Y / res.W, res.Z / res.W));
        }
Exemple #4
0
        /// <summary>
        /// Complete non-mandatory (deferred) values in the Intersection instance.
        /// </summary>
        public void Complete()
        {
            if (Solid != null)
            {
                // World coordinates.
                LocalToWorld = Solid.ToWorld();
                WorldToLocal = LocalToWorld;
                WorldToLocal.Invert();
                Vector3d.TransformPosition(ref CoordLocal, ref LocalToWorld, out CoordWorld);

                // Object coordinates.
                LocalToObject = Solid.ToObject();
                Vector3d.TransformPosition(ref CoordLocal, ref LocalToObject, out CoordObject);

                // Appearance.
                // Reflectance model.
                ReflectanceModel = (IReflectanceModel)Solid.GetAttribute(PropertyName.REFLECTANCE_MODEL);
                if (ReflectanceModel == null)
                {
                    ReflectanceModel = new PhongModel();
                }

                // Material.
                Material = (IMaterial)Solid.GetAttribute(PropertyName.MATERIAL);
                if (Material == null)
                {
                    Material = ReflectanceModel.DefaultMaterial();
                }

                // Surface color (accepts a color provided by a Solid).
                if (SurfaceColor == null)
                {
                    double[] col = (double[])Solid.GetAttribute(PropertyName.COLOR);
                    SurfaceColor = (double[])((col != null) ? col.Clone() : Material.Color.Clone());
                }

                // List of textures.
                Textures = Solid.GetTextures();

                // Solid is responsible for completing remaining values.
                // Usually: Normal, TextureCoord.
                Solid.CompleteIntersection(this);
                Normal.Normalize();
                if (Enter != Front)
                {
                    Vector3d.Multiply(ref Normal, -1.0, out Normal);
                }
            }

            if (SurfaceColor == null)
            {
                SurfaceColor = new double[] { 0.0, 0.0, 0.0 }
            }
            ;

            completed = true;
        }
        private static Vector3d UnProject(Vector3d screen, Matrix4d modelviewMatrix, Matrix4d projectionMatrix, int[] viewport)
        {
            Vector4d pos = Vector4d.Zero;

            pos.X = ((screen.X - (double)viewport[0]) / (double)viewport[2]) * 2.0 - 1.0;
            pos.Y = ((screen.Y - (double)viewport[1]) / (double)viewport[3]) * 2.0 - 1.0;
            pos.Z = (2.0 * screen.Z) - 1.0;
            pos.W = 1.0;

            Vector4d pos2 = Vector4d.Transform(pos, Matrix4d.Invert(Matrix4d.Mult(modelviewMatrix, projectionMatrix)));

            return(new Vector3d(pos2.X, pos2.Y, pos2.Z) / pos2.W);
        }
Exemple #6
0
        /// <summary>
        /// Unprojects the specified point on the screen with the specified depth
        /// to the 3D space.
        /// </summary>
        /// <param name="screenLocation">The point on the screen</param>
        /// <param name="depth">The depth value in the range [0, 1] (near to far)</param>
        /// <returns>The corresponding 3D point on the screen</returns>
        public static Vector3d UnProject(Point screenLocation, double depth)
        {
            int[]    viewport = GetViewportArray();
            Vector4d pos      = new Vector4d();

            // Map x and y from window coordinates, map to range -1 to 1
            pos.X = (screenLocation.X - viewport[0]) / (double)viewport[2] * 2.0f - 1.0f;
            pos.Y = 1 - (screenLocation.Y - viewport[1]) / (double)viewport[3] * 2.0f;
            pos.Z = depth * 2.0f - 1.0f;
            pos.W = 1.0f;

            Vector4d pos2    = Vector4d.Transform(pos, Matrix4d.Invert(GetModelViewMatrix() * GetProjectionMatrix()));
            Vector3d pos_out = new Vector3d(pos2.X, pos2.Y, pos2.Z);

            return(pos_out / pos2.W);
        }
Exemple #7
0
        /// <summary>
        /// Complete non-mandatory (deferred) values in the Intersection instance.
        /// </summary>
        public void Complete()
        {
            if (Solid != null)
            {
                // world coordinates:
                LocalToWorld = Solid.ToWorld();
                WorldToLocal = LocalToWorld;
                WorldToLocal.Invert();
                Vector3d.TransformPosition(ref CoordLocal, ref LocalToWorld, out CoordWorld);

                // object coordinates:
                LocalToObject = Solid.ToObject();
                Vector3d.TransformPosition(ref CoordLocal, ref LocalToObject, out CoordObject);

                // appearance:
                ReflectanceModel = (IReflectanceModel)Solid.GetAttribute(PropertyName.REFLECTANCE_MODEL);
                if (ReflectanceModel == null)
                {
                    ReflectanceModel = new PhongModel();
                }
                Material = (IMaterial)Solid.GetAttribute(PropertyName.MATERIAL);
                if (Material == null)
                {
                    Material = ReflectanceModel.DefaultMaterial();
                }
                double[] col = (double[])Solid.GetAttribute(PropertyName.COLOR);
                SurfaceColor = (double[])((col != null) ? col.Clone() : Material.Color.Clone());
                Textures     = Solid.GetTextures();

                // Solid is responsible for completing remaining values:
                Solid.CompleteIntersection(this);
                Normal.Normalize();
                if (Enter != Front)
                {
                    Vector3d.Multiply(ref Normal, -1.0, out Normal);
                }
            }

            if (SurfaceColor == null)
            {
                SurfaceColor = new double[] { 0.0, 0.2, 0.3 }
            }
            ;

            completed = true;
        }
Exemple #8
0
        /// <summary>
        /// Bestimmt die Kosten für die Kontraktion der angegebenen Vertices.
        /// </summary>
        /// <param name="s">
        /// Der erste Vertex des Paares.
        /// </param>
        /// <param name="t">
        /// Der zweite Vertex des Paares.
        /// </param>
        /// <returns>
        /// Eine Instanz der Pair-Klasse.
        /// </returns>
        Pair ComputeMinimumCostPair(int s, int t)
        {
            Vector3d target;
            double   cost;
            var      q = Q[s] + Q[t];
            // Siehe [Gar97], Abschnitt 4 ("Approximating Error With Quadrics").
            var m = new Matrix4d()
            {
                M11 = q.M11, M12 = q.M12, M13 = q.M13, M14 = q.M14,
                M21 = q.M12, M22 = q.M22, M23 = q.M23, M24 = q.M24,
                M31 = q.M13, M32 = q.M23, M33 = q.M33, M34 = q.M34,
                M41 = 0, M42 = 0, M43 = 0, M44 = 1
            };

            // Wenn m invertierbar ist, lässt sich die optimale Position bestimmen.
//			if (m.Determinant != 0) {
            try {
                // Determinante ist ungleich 0 für invertierbare Matrizen.
                var inv = Matrix4d.Invert(m);
                target = new Vector3d(inv.M14, inv.M24, inv.M34);
                cost   = ComputeVertexError(target, q);
            } catch (InvalidOperationException) {
//			} else {
                // Ansonsten den besten Wert aus Position von Vertex 1, Vertex 2 und
                // Mittelpunkt wählen.
                var v1 = vertices[s];
                var v2 = vertices[t];
                var mp = new Vector3d()
                {
                    X = (v1.X + v2.X) / 2,
                    Y = (v1.Y + v2.Y) / 2,
                    Z = (v1.Z + v2.Z) / 2
                };
                var candidates = new[] {
                    new { cost = ComputeVertexError(v1, q), target = v1 },
                    new { cost = ComputeVertexError(v2, q), target = v2 },
                    new { cost = ComputeVertexError(mp, q), target = mp }
                };
                var best = (from p in candidates
                            orderby p.cost
                            select p).First();
                target = best.target;
                cost   = best.cost;
            }
            return(new Pair(s, t, target, cost));
        }
Exemple #9
0
        /// <summary>
        /// Converts a screen space point into a corresponding point in world space.
        /// </summary>
        /// <param name="coordinate">The coordinate to project</param>
        /// <param name="viewport">The viewport dimensions</param>
        /// <param name="projection">The projection matrix</param>
        /// <param name="modelview">The modelview matrix</param>
        /// <returns>The coordinate in world space.</returns>
        public static Coordinate Unproject(Coordinate coordinate, int[] viewport, Matrix4d projection, Matrix4d modelview)
        {
            var matrix = Matrix4d.Invert(Matrix4d.Mult(modelview, projection));
            var source = new Vector4d(
                (coordinate.DX - viewport[0]) * 2 / viewport[2] - 1,
                (coordinate.DY - viewport[1]) * 2 / viewport[3] - 1,
                2 * coordinate.DZ - 1,
                1);
            var vector = Vector4d.Transform(source, matrix);

            if (Math.Abs(vector.W - 0) < 0.00001)
            {
                return(null);
            }
            var result = Vector3d.Divide(vector.Xyz, vector.W);

            return(new Coordinate((decimal)result.X, (decimal)result.Y, (decimal)result.Z));
        }
Exemple #10
0
        /// <summary>Gets the vector of where the mouse cursor currently is.</summary>
        /// <param name="projection"></param>
        /// <param name="modelView"></param>
        /// <param name="offsetX">will get the coords of the pixel to the right of the mouse cursor if true</param>
        /// <param name="offsetY">will get the coords of the pixel below the mouse cursor if true</param>
        private static Vector3d GetMousePosition(ref Matrix4d projection, ref Matrix4d modelView, bool offsetX, bool offsetY)
        {
            Matrix4d view;

            Matrix4d.Mult(ref modelView, ref projection, out view);
            int   x     = Settings.Game.Mouse.X + (offsetX ? 1 : 0);
            int   y     = Settings.Game.Height + (offsetY ? 1 : 0) - Settings.Game.Mouse.Y - 1;       //invert Y, window coords are opposite
            float depth = 0;

            GL.ReadPixels(x, y, 1, 1, PixelFormat.DepthComponent, PixelType.Float, ref depth);
            var viewPosition = new Vector4d
                               (
                (float)x / Settings.Game.Width * 2.0f - 1.0f,                   //map X to -1 to 1 range
                (float)y / Settings.Game.Height * 2.0f - 1.0f,                  //map Y to -1 to 1 range
                depth * 2.0f - 1.0f,                                            //map Z to -1 to 1 range
                1.0f
                               );
            var temp = Vector4d.Transform(viewPosition, Matrix4d.Invert(view));

            return(new Vector3d(temp.X, temp.Y, temp.Z) / temp.W);
        }
Exemple #11
0
        private static Vector4d UnProject(Matrix4d projection, Matrix4d view, Size viewport, Vector2d mouse)
        {
            Vector4d vec;

            vec.X = 2.0f * mouse.X / (float)viewport.Width - 1;
            vec.Y = -(2.0f * mouse.Y / (float)viewport.Height - 1);
            vec.Z = 0;
            vec.W = 1.0f;

            Matrix4d viewInv = Matrix4d.Invert(view);
            Matrix4d projInv = Matrix4d.Invert(projection);

            Vector4d.Transform(ref vec, ref projInv, out vec);
            Vector4d.Transform(ref vec, ref viewInv, out vec);

            if (vec.W > float.Epsilon || vec.W < float.Epsilon)
            {
                vec.X /= vec.W;
                vec.Y /= vec.W;
                vec.Z /= vec.W;
            }

            return(vec);
        }
Exemple #12
0
        /// <summary>Transform a Normal by the given Matrix</summary>
        /// <remarks>
        /// This calculates the inverse of the given matrix, use TransformNormalInverse if you
        /// already have the inverse to avoid this extra calculation
        /// </remarks>
        /// <param name="norm">The normal to transform</param>
        /// <param name="mat">The desired transformation</param>
        /// <param name="result">The transformed normal</param>
        public static void TransformNormal(ref Vector3d norm, ref Matrix4d mat, out Vector3d result)
        {
            Matrix4d Inverse = Matrix4d.Invert(mat);

            Vector3d.TransformNormalInverse(ref norm, ref Inverse, out result);
        }
Exemple #13
0
 /// <summary>Transform a Normal by the given Matrix</summary>
 /// <remarks>
 /// This calculates the inverse of the given matrix, use TransformNormalInverse if you
 /// already have the inverse to avoid this extra calculation
 /// </remarks>
 /// <param name="norm">The normal to transform</param>
 /// <param name="mat">The desired transformation</param>
 /// <returns>The transformed normal</returns>
 public static Vector3d TransformNormal(Vector3d norm, Matrix4d mat)
 {
     mat.Invert();
     return(TransformNormalInverse(norm, mat));
 }
 private void UpdateTransposeInverse()
 {
     if (!transposeInverseDirty) {
         return;
     }
     transposeInverseDirty = false;
     transposeInverse = Matrix4d.Scale(scale);
     // TODO: Apply rotation
     transposeInverse = Matrix4d.Mult(Matrix4d.CreateTranslation(translation), transposeInverse);
     transposeInverse.Invert();
     transposeInverse.Transpose();
 }
Exemple #15
0
 public UMatrix4 Invert()
 {
     return(new UMatrix4(Matrix4d.Invert(Matrix)));
 }
Exemple #16
0
        /// <summary>
        /// Complete non-mandatory (deferred) values in the Intersection instance.
        /// </summary>
        public void Complete()
        {
            if (Solid != null)
            {
                // World coordinates.
                LocalToWorld = Solid.ToWorld();
                WorldToLocal = LocalToWorld;
                WorldToLocal.Invert();
                Vector3d.TransformPosition(ref CoordLocal, ref LocalToWorld, out CoordWorld);

                // Object coordinates.
                LocalToObject = Solid.ToObject();
                Vector3d.TransformPosition(ref CoordLocal, ref LocalToObject, out CoordObject);

                // Appearance.
                // Reflectance model.
                ReflectanceModel = (IReflectanceModel)Solid.GetAttribute(PropertyName.REFLECTANCE_MODEL);
                if (ReflectanceModel == null)
                {
                    ReflectanceModel = new PhongModel();
                }

                // Material.
                Material = (IMaterial)Solid.GetAttribute(PropertyName.MATERIAL);
                if (Material == null)
                {
                    Material = ReflectanceModel.DefaultMaterial();
                }

                // Surface color (accepts a color provided by a Solid).
                if (SurfaceColor == null)
                {
                    double[] col = (double[])Solid.GetAttribute(PropertyName.COLOR);
                    SurfaceColor = (double[])((col != null) ? col.Clone() : Material.Color.Clone());
                }

                // List of textures.
                Textures = Solid.GetTextures();

                // Solid is responsible for completing remaining values.
                // Usually: TangentU, TangentV, NormalLocal, TextureCoord.
                Solid.CompleteIntersection(this);

                // Tangent space - NormalLocal, TangentU, TangentV.
                if (Geometry.IsZeroFast(TangentU.LengthFast))
                {
                    // I need NormalLocal if I have no tangent vecotrs.
                    Geometry.GetTangents(ref NormalLocal, out TangentU, out TangentV);
                }
                else
                if (Geometry.IsZeroFast(NormalLocal.LengthFast))
                {
                    // I have local tangent vectors but no local normal.
                    Vector3d.Cross(ref TangentU, ref TangentV, out NormalLocal);
                }

                // Normal vector: if not computed yet, 'TangentU x TangentV' will do the job.
                if (Geometry.IsZeroFast(Normal.LengthFast))
                {
                    Vector3d tu, tv;
                    tu = Vector3d.TransformVector(TangentU, LocalToWorld);
                    tv = Vector3d.TransformVector(TangentV, LocalToWorld);
                    Vector3d.Cross(ref tu, ref tv, out Normal);
                }
                Normal.Normalize(); // to be sure...

                if (Enter != Front)
                {
                    Vector3d.Multiply(ref Normal, -1.0, out Normal);
                }
            }

            if (SurfaceColor == null)
            {
                SurfaceColor = new double[] { 0.0, 0.0, 0.0 }
            }
            ;

            completed = true;
        }