protected override Matrix4F GetManipulatorMatrix()
        {
            ITransformable node = GetManipulatorNode(TransformationTypes.Scale);

            if (node == null)
            {
                return(null);
            }

            Path <DomNode> path         = new Path <DomNode>(node.Cast <DomNode>().GetPath());
            Matrix4F       localToWorld = TransformUtils.CalcPathTransform(path, path.Count - 1);

            // local transform
            Matrix4F toworld = new Matrix4F(localToWorld);

            // Offset by pivot
            Matrix4F P = new Matrix4F();

            P.Translation = node.Pivot;
            toworld.Mul(P, toworld);

            // Normalize
            toworld.Normalize(toworld);

            return(toworld);
        }
        protected override Matrix4F GetManipulatorMatrix()
        {
            ITransformable node = GetManipulatorNode(TransformationTypes.Translation);

            if (node == null)
            {
                return(null);
            }

            ISnapSettings  snapSettings = (ISnapSettings)DesignView;
            Path <DomNode> path         = new Path <DomNode>(node.Cast <DomNode>().GetPath());
            Matrix4F       localToWorld = TransformUtils.CalcPathTransform(path, path.Count - 1);

            Matrix4F toworld = new Matrix4F();

            if (snapSettings.ManipulateLocalAxis)
            {
                toworld.Set(localToWorld);
                toworld.Normalize(toworld);
            }
            else
            {
                toworld.Translation = localToWorld.Translation;
            }

            Vec3F offset = TransformUtils.CalcSnapFromOffset(node, snapSettings.SnapFrom);

            // Offset by pivot
            Matrix4F P = new Matrix4F();

            P.Translation = offset;
            toworld.Mul(toworld, P);

            return(toworld);
        }
Beispiel #3
0
        /// <summary>
        /// Projects the specified x and y, in normalized window coordinates, onto the grid,
        /// and snaps it to the nearest grid vertex if necessary.
        /// Normalized window coordinates are in the range [-0.5,0.5] with +x pointing to the
        /// right and +y pointing up.</summary>
        /// <param name="x">Window x in normalized window coords</param>
        /// <param name="y">Window y in normalized window coords</param>
        /// <param name="camera">Camera</param>
        /// <returns>Projection of x and y onto the grid, in world space.</returns>
        public Vec3F Project(float x, float y, Camera camera)
        {
            Ray3F ray = camera.CreateRay(x, y);

            Matrix4F V = new Matrix4F(camera.ViewMatrix);
            V.Mul(m_invAxisSystem, V);

            if (camera.Frustum.IsOrtho)
            {
                V = new Matrix4F(m_V);
                V.Translation = camera.ViewMatrix.Translation;
            }

            // origin
            Vec3F delta = new Vec3F(0, Height, 0);
            V.Transform(delta, out delta);
            Vec3F o = delta;

            // Up vec
            Vec3F axis = V.YAxis;
            Vec3F projPt = ray.IntersectPlane(axis, -Vec3F.Dot(o, axis));

            // Transform back into world space
            Matrix4F Inv = new Matrix4F();
            Inv.Invert(camera.ViewMatrix);
            Inv.Transform(projPt, out projPt);

            if (Snap)
            {
                projPt = SnapPoint(projPt);
            }
            return projPt;
        }
Beispiel #4
0
 /// <summary>
 /// Computes world transformation matrix for the given 
 /// Transformable node.</summary>        
 public static Matrix4F ComputeWorldTransform(ITransformable xform)
 {
     Matrix4F world = new Matrix4F();
     DomNode node = xform.As<DomNode>();
     foreach (DomNode n in node.Lineage)
     {
         ITransformable xformNode = n.As<ITransformable>();
         if (xformNode != null)
         {
             world.Mul(world, xformNode.Transform);
         }
     }
     return world;
 }
Beispiel #5
0
        /// <summary>
        /// Calculates the transformation matrix corresponding to the given transform components
        /// </summary>
        /// <param name="translation">Translation</param>
        /// <param name="rotation">Rotation</param>
        /// <param name="scale">Scale</param>
        /// <param name="scalePivot">Translation to origin of scaling</param>
        /// <param name="scalePivotTranslate">Translation after scaling</param>
        /// <param name="rotatePivot">Translation to origin of rotation</param>
        /// <param name="rotatePivotTranslate">Translation after rotation</param>
        /// <returns>transformation matrix corresponding to the given transform components</returns>
        public static Matrix4F CalcTransform(
            Vec3F translation,
            Vec3F rotation,
            Vec3F scale,
            Vec3F pivot)
        {
            Matrix4F M    = new Matrix4F();
            Matrix4F temp = new Matrix4F();

            M.Set(-pivot);

            temp.Scale(scale);
            M.Mul(M, temp);

            if (rotation.X != 0)
            {
                temp.RotX(rotation.X);
                M.Mul(M, temp);
            }

            if (rotation.Y != 0)
            {
                temp.RotY(rotation.Y);
                M.Mul(M, temp);
            }

            if (rotation.Z != 0)
            {
                temp.RotZ(rotation.Z);
                M.Mul(M, temp);
            }

            temp.Set(pivot + translation);
            M.Mul(M, temp);

            return(M);
        }
Beispiel #6
0
        /// <summary>
        /// Computes world transformation matrix for the given
        /// Transformable node.</summary>
        public static Matrix4F ComputeWorldTransform(ITransformable xform)
        {
            Matrix4F world = new Matrix4F();
            DomNode  node  = xform.As <DomNode>();

            foreach (DomNode n in node.Lineage)
            {
                ITransformable xformNode = n.As <ITransformable>();
                if (xformNode != null)
                {
                    world.Mul(world, xformNode.Transform);
                }
            }
            return(world);
        }
Beispiel #7
0
        /// <summary>
        /// Calculates the world space matrix of the given path</summary>
        /// <param name="path">The path</param>
        /// <param name="start">Starting index</param>
        /// <param name="M">the world matrix</param>
        public static void CalcPathTransform(Matrix4F M, Path <DomNode> path, int start)
        {
            for (int i = start; i >= 0; i--)
            {
                if (path[i] != null)
                {
                    ITransformable renderable =
                        path[i].As <ITransformable>();

                    if (renderable != null)
                    {
                        M.Mul(M, renderable.Transform);
                    }
                }
            }
        }
Beispiel #8
0
        /// <summary>
        /// Calculates the world space matrix of the given path</summary>
        /// <param name="path">The path</param>
        /// <param name="start">Starting index</param>
        /// <param name="M">the world matrix</param>        
        public static void CalcPathTransform(Matrix4F M, Path<DomNode> path, int start)
        {
            for (int i = start; i >= 0; i--)
            {
                if (path[i] != null)
                {
                    ITransformable renderable =
                        path[i].As<ITransformable>();

                    if (renderable != null)
                    {
                        M.Mul(M, renderable.Transform);
                    }
                }
            }
        }
Beispiel #9
0
        /// <summary>
        /// Adjusts child transform, making it the concatenation with its parent's transform.
        /// Is recursive, looking for parents that also implement IRenderableNode.</summary>
        /// <param name="parent">Parent node</param>
        /// <param name="child">Child node</param>
        public static void RemoveChild(ITransformable parent, ITransformable child)
        {
            Path <DomNode> path         = new Path <DomNode>(parent.Cast <DomNode>().GetPath());
            Matrix4F       parentMatrix = TransformUtils.CalcPathTransform(path, path.Count - 1);

            Matrix4F childMatrix    = child.Transform;
            Matrix4F newChildMatrix = Matrix4F.Multiply(childMatrix, parentMatrix);

            Vec3F newTranslation = child.Translation;

            parentMatrix.Transform(ref newTranslation);

            Vec3F newRotation = new Vec3F();

            newChildMatrix.GetEulerAngles(out newRotation.X, out newRotation.Y, out newRotation.Z);
            child.Rotation = newRotation;

            Vec3F newScale = newChildMatrix.GetScale();

            child.Scale = newScale;

            // We can compose together all of the separate transformations now.
            Matrix4F newTransform = CalcTransform(
                newTranslation,
                newRotation,
                newScale,
                child.ScalePivot,
                child.ScalePivotTranslation,
                child.RotatePivot,
                child.RotatePivotTranslation);

            // However, the composed matrix may not equal newChildMatrix due to rotating
            //  or scaling around a pivot. In the general case, it may be impossible to
            //  decompose newChildMatrix into all of these separate components. For example,
            //  a sheer transformation cannot be reproduced by a single rotation and scale.
            //  But for common cases, only the translation is out-of-sync now, so apply a fix.
            Vec3F    desiredTranslation = newChildMatrix.Translation;
            Vec3F    currentTranslation = newTransform.Translation;
            Vec3F    fixupTranslation   = desiredTranslation - currentTranslation;
            Matrix4F fixupTransform     = new Matrix4F(fixupTranslation);

            newTransform.Mul(newTransform, fixupTransform);

            // Save the fix and the final transform.
            child.Translation = newTranslation + fixupTranslation;
            child.Transform   = newTransform;
        }
Beispiel #10
0
        /// <summary>
        /// Calculates the width and height of the view frustum at the given 3D location</summary>
        /// <param name="camera">The camera</param>
        /// <param name="globalTransform">The world space matrix specifying a position</param>
        /// <param name="h">The height of the view frustum at the given position</param>
        /// <param name="w">The width of the view frustum at the given position</param>
        public static void CalcWorldDimensions(Camera camera, Matrix4F globalTransform, out float h, out float w)
        {
            Matrix4F W = new Matrix4F();

            W.Mul(globalTransform, camera.ViewMatrix);

            // World height on origin's z value
            if (camera.Frustum.IsOrtho)
            {
                w = camera.Frustum.Right - camera.Frustum.Left;
                h = camera.Frustum.Top - camera.Frustum.Bottom;
            }
            else
            {
                float minusZ = -W.Translation.Z;
                h = minusZ * (float)Math.Tan(camera.Frustum.FovY / 2.0f) * 2.0f;
                w = minusZ * (float)Math.Tan(camera.Frustum.FovX / 2.0f) * 2.0f;
            }
        }
Beispiel #11
0
        /// <summary>
        /// Gets the view matrix corresponding to a "look at" point</summary>
        /// <param name="azimuth">Camera pan, in radians</param>
        /// <param name="elevation">Camera tilt, in radians</param>
        /// <param name="lookAt">"Look at" direction</param>
        /// <param name="dolly">Distance from "look at" point</param>
        /// <returns>View matrix corresponding to the "look at" point</returns>
        public static Matrix4F LookAtMatrix(float azimuth, float elevation, Vec3F lookAt, float dolly)
        {
            Matrix4F R = LookAtRotationMatrix(azimuth, elevation, lookAt);

            R.ZTranslation = -dolly;

            Matrix4F T = new Matrix4F
                         (
                1, 0, 0, 0,
                0, 1, 0, 0,
                0, 0, 1, 0,
                -lookAt.X, -lookAt.Y, -lookAt.Z, 1
                         );

            Matrix4F result = new Matrix4F();

            result.Mul(T, R);

            return(result);
        }
Beispiel #12
0
        /// <summary>
        /// Calculates the world space matrix of the given SceneNode path, starting from a given index</summary>
        /// <param name="path">The SceneNode path</param>
        /// <param name="start">Starting index within the path</param>
        /// <returns>The world space matrix</returns>
        public static Matrix4F CalcPathTransform(SceneNode[] path, int start)
        {
            Matrix4F M = new Matrix4F();

            for (int i = start; i < path.Length; i++)
            {
                if (path[i].Source != null)
                {
                    ITransformable renderable =
                        path[i].Source.As <ITransformable>();

                    if (renderable != null)
                    {
                        M.Mul(M, renderable.Transform);
                    }
                }
            }

            return(M);
        }
Beispiel #13
0
        /// <summary>
        /// Calculates the world space matrix of the given SceneNode path, starting from a given index</summary>
        /// <param name="path">The SceneNode path</param>
        /// <param name="start">Starting index within the path</param>
        /// <returns>The world space matrix</returns>
        public static Matrix4F CalcPathTransform(SceneNode[] path, int start)
        {
            Matrix4F M = new Matrix4F();

            for (int i = start; i < path.Length; i++)
            {
                if (path[i].Source != null)
                {
                    ITransformable renderable =
                        path[i].Source.As<ITransformable>();

                    if (renderable != null)
                    {
                        M.Mul(M, renderable.Transform);
                    }
                }
            }

            return M;
        }
Beispiel #14
0
        /// <summary>
        /// Calculates the world space matrix of the given path
        /// </summary>
        /// <param name="path">The path</param>
        /// <param name="start">Starting index</param>
        /// <returns>The world space matrix</returns>
        public static Matrix4F CalcPathTransform(Path <DomNode> path, int start)
        {
            Matrix4F M = new Matrix4F();

            for (int i = start; i >= 0; i--)
            {
                if (path[i] != null)
                {
                    ITransformable renderable =
                        path[i].As <ITransformable>();

                    if (renderable != null)
                    {
                        M.Mul(M, renderable.Transform);
                    }
                }
            }

            return(M);
        }
Beispiel #15
0
        protected override Matrix4F GetManipulatorMatrix()
        {
            ITransformable node = GetManipulatorNode(TransformationTypes.Pivot);

            if (node == null)
            {
                return(null);
            }

            Path <DomNode> path         = new Path <DomNode>(node.Cast <DomNode>().GetPath());
            Matrix4F       localToWorld = TransformUtils.CalcPathTransform(path, path.Count - 1);

            // Offset by pivot
            Matrix4F Pv = new Matrix4F();

            Pv.Set(node.Pivot);
            localToWorld.Mul(Pv, localToWorld);
            localToWorld.OrthoNormalize(localToWorld);
            return(new Matrix4F(localToWorld.Translation));
        }
Beispiel #16
0
        /// <summary>
        /// Calculates the world space matrix of the given path
        /// </summary>
        /// <param name="path">The path</param>
        /// <param name="start">Starting index</param>
        /// <returns>The world space matrix</returns>
        public static Matrix4F CalcPathTransform(Path<DomNode> path, int start)
        {
            Matrix4F M = new Matrix4F();

            for (int i = start; i >= 0; i--)
            {
                if (path[i] != null)
                {
                    ITransformable renderable =
                        path[i].As<ITransformable>();

                    if (renderable != null)
                    {
                        M.Mul(M, renderable.Transform);
                    }
                }
            }

            return M;
        }
        /// <summary>
        /// Handles mouse-move events</summary>
        /// <param name="sender">Control that raised original event</param>
        /// <param name="e">Event args</param>
        /// <returns>true, if controller handled the event</returns>
        public override bool MouseMove(object sender, MouseEventArgs e)
        {
            if (m_dragging &&
                InputScheme.ActiveControlScheme.IsControllingCamera(Control.ModifierKeys, e))
            {
                float dx = (float)(e.X - m_lastMousePoint.X) / 150.0f;
                float dy = (float)(e.Y - m_lastMousePoint.Y) / 150.0f;

                if (InputScheme.ActiveControlScheme.IsElevating(Control.ModifierKeys, e))
                {
                    // move camera up/down
                    Vec3F p = Camera.Eye;
                    p.Y += (dy < 0) ? m_scale : -m_scale;
                    Camera.Set(p);
                }
                else if (InputScheme.ActiveControlScheme.IsTurning(Control.ModifierKeys, e))
                {
                    // pitch and yaw camera
                    Matrix4F mat = Matrix4F.RotAxisRH(Camera.Right, -dy); // pitch along camera right
                    Matrix4F yaw = new Matrix4F();
                    yaw.RotY(-dx);
                    mat.Mul(yaw, mat);

                    Vec3F lookAt = Camera.LookAt;
                    Vec3F up     = Camera.Up;
                    mat.Transform(ref lookAt);
                    mat.Transform(ref up);

                    Vec3F position = Camera.Eye;
                    float d        = Camera.DistanceFromLookAt;
                    Camera.Set(position, position + lookAt * d, up);
                }

                m_lastMousePoint = e.Location;

                return(true);
            }

            return(base.MouseMove(sender, e));
        }
Beispiel #18
0
        private void CalcAxisLengths(Camera camera, Matrix4F globalTransform, out float s1, out float s2, out float s3)
        {
            float worldHeight;

            // Calc view space matrix
            Matrix4F V = new Matrix4F();

            V.Mul(globalTransform, camera.ViewMatrix);

            // World height on origin's z value
            if (camera.Frustum.IsOrtho)
            {
                worldHeight = (camera.Frustum.Top - camera.Frustum.Bottom) / 2;
            }
            else
            {
                worldHeight = -V.ZTranslation * (float)Math.Tan(camera.Frustum.FovY / 2.0f);
            }

            s1 = (m_axisRatio * worldHeight) / V.XAxis.Length;
            s2 = (m_axisRatio * worldHeight) / V.YAxis.Length;
            s3 = (m_axisRatio * worldHeight) / V.ZAxis.Length;
        }
Beispiel #19
0
        /// <summary>
        /// Pushes a matrix onto the matrix stack</summary>
        /// <param name="matrix">The matrix</param>
        /// <param name="multiply">If true, multiply matrix by top matrix</param>
        public void PushMatrix(Matrix4F matrix, bool multiply)
        {
            if (m_matrixStackFreeze)
            {
                throw new InvalidOperationException(
                          "the IRenderObject does not implement ISetsLocalTransform");
            }

            int      count     = m_matrixStack.Count;
            Matrix4F topMatrix = (count > 0) ? m_matrixStack[count - 1] : Matrix4F.Identity;

            Matrix4F newMatrix = new Matrix4F();

            if (multiply)
            {
                newMatrix.Mul(matrix, topMatrix);
            }
            else
            {
                newMatrix.Set(matrix);
            }

            m_matrixStack.Add(newMatrix);
        }
Beispiel #20
0
        /// <summary>
        /// Calculates the transformation matrix corresponding to the given transform components
        /// </summary>
        /// <param name="translation">Translation</param>
        /// <param name="rotation">Rotation</param>
        /// <param name="scale">Scale</param>
        /// <param name="scalePivot">Translation to origin of scaling</param>
        /// <param name="scalePivotTranslate">Translation after scaling</param>
        /// <param name="rotatePivot">Translation to origin of rotation</param>
        /// <param name="rotatePivotTranslate">Translation after rotation</param>
        /// <returns>transformation matrix corresponding to the given transform components</returns>
        public static Matrix4F CalcTransform(
            Vec3F translation,
            Vec3F rotation,
            Vec3F scale,
            Vec3F pivot)
        {
            Matrix4F M = new Matrix4F();
            Matrix4F temp = new Matrix4F();

            M.Set(-pivot);

            temp.Scale(scale);
            M.Mul(M, temp);

            if (rotation.X != 0)
            {
                temp.RotX(rotation.X);
                M.Mul(M, temp);
            }

            if (rotation.Y != 0)
            {
                temp.RotY(rotation.Y);
                M.Mul(M, temp);
            }

            if (rotation.Z != 0)
            {
                temp.RotZ(rotation.Z);
                M.Mul(M, temp);
            }

            temp.Set(pivot + translation);
            M.Mul(M, temp);

            return M;
        }
Beispiel #21
0
        /// <summary>
        /// Adjusts child transform, making it relative to new parent node's transform.
        /// Is recursive, looking for parents that also implement IRenderableNode.</summary>
        /// <param name="parent">Parent node</param>
        /// <param name="child">Child node</param>
        public static void AddChild(ITransformable parent, ITransformable child)
        {
            Path <DomNode> path          = new Path <DomNode>(parent.Cast <DomNode>().GetPath());
            Matrix4F       parentToWorld = TransformUtils.CalcPathTransform(path, path.Count - 1);

            // We want 'child' to appear in the same place in the world after adding to 'parent'.
            // local-point * original-local-to-world = world-point
            // new-local-point * new-local-to-parent * parent-to-world = world-point
            // ==> new-local-to-parent * parent-to-world = original-local-to-world
            // (multiply both sides by inverse of parent-to-world; call it world-to-parent)
            // ==> new-local-to-parent = original-local-to-world * world-to-parent
            Matrix4F worldToParent = new Matrix4F();

            worldToParent.Invert(parentToWorld);
            Matrix4F originalLocalToWorld = child.Transform;
            Matrix4F newLocalToParent     = Matrix4F.Multiply(originalLocalToWorld, worldToParent);

            // The translation component of newLocalToParent consists of pivot translation
            //  as well as the child.Translation. So, start with the original child.Translation
            //  and transform it into our new space.
            Vec3F newTranslation = child.Translation;

            worldToParent.Transform(ref newTranslation);

            // There's only one way of getting rotation info, so get it straight from matrix.
            Vec3F newRotation = new Vec3F();

            newLocalToParent.GetEulerAngles(out newRotation.X, out newRotation.Y, out newRotation.Z);
            child.Rotation = newRotation;

            // Likewise with scale.
            Vec3F newScale = newLocalToParent.GetScale();

            child.Scale = newScale;

            // We can compose together all of the separate transformations now.
            Matrix4F newTransform = CalcTransform(
                newTranslation,
                newRotation,
                newScale,
                child.ScalePivot,
                child.ScalePivotTranslation,
                child.RotatePivot,
                child.RotatePivotTranslation);

            // However, the composed matrix may not equal newLocalToParent due to rotating
            //  or scaling around a pivot. In the general case, it may be impossible to
            //  decompose newLocalToParent into all of these separate components. For example,
            //  a sheer transformation cannot be reproduced by a single rotation and scale.
            //  But for common cases, only the translation is out-of-sync now, so apply a fix.
            Vec3F    desiredTranslation = newLocalToParent.Translation;
            Vec3F    currentTranslation = newTransform.Translation;
            Vec3F    fixupTranslation   = desiredTranslation - currentTranslation;
            Matrix4F fixupTransform     = new Matrix4F(fixupTranslation);

            newTransform.Mul(newTransform, fixupTransform);

            // Save the fix and the final transform. Storing the fix in RotatePivotTranslation
            //  is done elsewhere, as well.
            child.Translation = newTranslation + fixupTranslation;
            child.Transform   = newTransform;
        }
        private void RenderProperties(IEnumerable <object> objects, bool renderCaption, bool renderBound, bool renderPivot)
        {
            bool renderAny = renderCaption || renderBound || renderPivot;

            if (renderAny == false)
            {
                return;
            }

            Util3D.RenderFlag = BasicRendererFlags.WireFrame;
            Matrix4F vp = Camera.ViewMatrix * Camera.ProjectionMatrix;

            foreach (object obj in objects)
            {
                IBoundable bnode = obj.As <IBoundable>();
                if (bnode == null || bnode.BoundingBox.IsEmpty || obj.Is <IGameObjectFolder>())
                {
                    continue;
                }

                INameable      nnode = obj.As <INameable>();
                ITransformable trans = obj.As <ITransformable>();

                if (renderBound)
                {
                    Util3D.DrawAABB(bnode.BoundingBox);
                }
                if (renderCaption && nnode != null)
                {
                    Vec3F topCenter = bnode.BoundingBox.Center;
                    topCenter.Y = bnode.BoundingBox.Max.Y;
                    Point pt = Project(vp, topCenter);
                    GameEngine.DrawText2D(nnode.Name, Util3D.CaptionFont, pt.X, pt.Y, Color.White);
                }
            }

            if (renderPivot)
            {
                Util3D.RenderFlag = BasicRendererFlags.WireFrame
                                    | BasicRendererFlags.DisableDepthTest;

                // create few temp matrics to
                Matrix4F toWorld  = new Matrix4F();
                Matrix4F PV       = new Matrix4F();
                Matrix4F sc       = new Matrix4F();
                Matrix4F bl       = new Matrix4F();
                Matrix4F recXform = new Matrix4F();
                foreach (object obj in objects)
                {
                    ITransformable trans = obj.As <ITransformable>();
                    IBoundable     bnode = obj.As <IBoundable>();
                    if (trans == null || bnode == null || bnode.BoundingBox.IsEmpty || obj.Is <IGameObjectFolder>())
                    {
                        continue;
                    }

                    Path <DomNode> path = new Path <DomNode>(trans.Cast <DomNode>().GetPath());
                    toWorld.Set(Vec3F.ZeroVector);
                    TransformUtils.CalcPathTransform(toWorld, path, path.Count - 1);

                    // Offset by pivot
                    PV.Set(trans.Pivot);
                    toWorld.Mul(PV, toWorld);
                    Vec3F pos = toWorld.Translation;

                    float s;
                    Util.CalcAxisLengths(Camera, pos, out s);
                    s /= 12.0f;
                    sc.Scale(s);
                    Util.CreateBillboard(bl, pos, Camera.WorldEye, Camera.Up, Camera.LookAt);

                    Matrix4F.Multiply(sc, bl, recXform);

                    Util3D.DrawPivot(recXform, Color.Yellow);
                }
            }
        }
Beispiel #23
0
        /// <summary>
        /// Projects the specified x and y, in normalized window coordinates, onto the grid,
        /// and snaps it to the nearest grid vertex if necessary.
        /// Normalized window coordinates are in the range [-0.5,0.5] with +x pointing to the
        /// right and +y pointing up.</summary>
        /// <param name="x">Window x in normalized window coords</param>
        /// <param name="y">Window y in normalized window coords</param>
        /// <param name="camera">Camera</param>
        /// <returns>Projection of x and y onto the grid, in world space.</returns>
        public Vec3F Project(float x, float y, Camera camera)
        {
            Ray3F ray = camera.CreateRay(x, y);

            Matrix4F V = new Matrix4F(camera.ViewMatrix);
            V.Mul(m_invAxisSystem, V);

            if (camera.Frustum.IsOrtho)
            {
                V = new Matrix4F(m_V);
                V.Translation = camera.ViewMatrix.Translation;
            }

            // origin
            Vec3F delta = new Vec3F(0, Height, 0);
            V.Transform(delta, out delta);
            Vec3F o = delta;

            // Up vec
            Vec3F axis = V.YAxis;
            Vec3F projPt = ray.IntersectPlane(axis, -Vec3F.Dot(o, axis));

            // Transform back into world space
            Matrix4F Inv = new Matrix4F();
            Inv.Invert(camera.ViewMatrix);
            Inv.Transform(projPt, out projPt);

            if (Snap)
            {
                projPt = SnapPoint(projPt);
            }
            return projPt;
        }
Beispiel #24
0
        /// <summary>
        /// Performs actions during control drag</summary>
        /// <param name="hit">Hit record</param>
        /// <param name="x">Mouse x position</param>
        /// <param name="y">Mouse y position</param>
        /// <param name="action">Render action</param>
        /// <param name="camera">Camera</param>
        /// <param name="transform">Transform</param>
        /// <returns>Translation, in world coordinates</returns>
        public Vec3F OnDrag(HitRecord hit, float x, float y, IRenderAction action, Camera camera, Matrix4F transform)
        {
            float    a1, a2;
            Matrix4F W = new Matrix4F();

            W.Mul(transform, camera.ViewMatrix);

            // Setup rays, in view space. (-z goes into the screen.)
            Ray3F ray0 = camera.CreateRay(m_iX, m_iY);
            Ray3F ray  = camera.CreateRay(x, y);

            // Build axis and origin in view space
            Vec3F xAxis  = W.XAxis;
            Vec3F yAxis  = W.YAxis;
            Vec3F zAxis  = W.ZAxis;
            Vec3F origin = W.Translation;

            Vec3F trans = new Vec3F();

            // Choose the best projection plane according to the projection angle
            switch ((HitElement)hit.RenderObjectData[1])
            {
            case HitElement.X_ARROW:
            {
                a1 = Math.Abs(Vec3F.Dot(ray0.Direction, yAxis));
                a2 = Math.Abs(Vec3F.Dot(ray0.Direction, zAxis));
                Vec3F axis       = (a1 > a2 ? yAxis : zAxis);
                Vec3F p0         = ray0.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                Vec3F p1         = ray.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                float dragAmount = Vec3F.Dot(xAxis, p1 - p0);
                Vec3F xLocal     = transform.XAxis;
                trans = dragAmount * xLocal;
            }
            break;

            case HitElement.Y_ARROW:
            {
                a1 = Math.Abs(Vec3F.Dot(ray0.Direction, zAxis));
                a2 = Math.Abs(Vec3F.Dot(ray0.Direction, xAxis));
                Vec3F axis       = (a1 > a2 ? zAxis : xAxis);
                Vec3F p0         = ray0.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                Vec3F p1         = ray.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                float dragAmount = Vec3F.Dot(yAxis, p1 - p0);
                Vec3F yLocal     = transform.YAxis;
                trans = dragAmount * yLocal;
            }
            break;

            case HitElement.Z_ARROW:
            {
                a1 = Math.Abs(Vec3F.Dot(ray0.Direction, xAxis));
                a2 = Math.Abs(Vec3F.Dot(ray0.Direction, yAxis));
                Vec3F axis       = (a1 > a2 ? xAxis : yAxis);
                Vec3F p0         = ray0.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                Vec3F p1         = ray.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                float dragAmount = Vec3F.Dot(zAxis, p1 - p0);
                Vec3F zLocal     = transform.ZAxis;
                trans = dragAmount * zLocal;
            }
            break;

            case HitElement.XY_SQUARE:
            {
                Vec3F p0         = ray0.IntersectPlane(zAxis, -Vec3F.Dot(zAxis, origin));
                Vec3F p1         = ray.IntersectPlane(zAxis, -Vec3F.Dot(zAxis, origin));
                Vec3F deltaLocal = p1 - p0;
                float dragX      = Vec3F.Dot(xAxis, deltaLocal);
                float dragY      = Vec3F.Dot(yAxis, deltaLocal);
                Vec3F xLocal     = transform.XAxis;
                Vec3F yLocal     = transform.YAxis;
                trans = dragX * xLocal + dragY * yLocal;
            }
            break;

            case HitElement.YZ_SQUARE:
            {
                Vec3F p0         = ray0.IntersectPlane(xAxis, -Vec3F.Dot(xAxis, origin));
                Vec3F p1         = ray.IntersectPlane(xAxis, -Vec3F.Dot(xAxis, origin));
                Vec3F deltaLocal = p1 - p0;
                float dragY      = Vec3F.Dot(yAxis, deltaLocal);
                float dragZ      = Vec3F.Dot(zAxis, deltaLocal);
                Vec3F yLocal     = transform.YAxis;
                Vec3F zLocal     = transform.ZAxis;
                trans = dragY * yLocal + dragZ * zLocal;
            }
            break;

            case HitElement.XZ_SQUARE:
            {
                Vec3F p0         = ray0.IntersectPlane(yAxis, -Vec3F.Dot(yAxis, origin));
                Vec3F p1         = ray.IntersectPlane(yAxis, -Vec3F.Dot(yAxis, origin));
                Vec3F deltaLocal = p1 - p0;
                float dragX      = Vec3F.Dot(xAxis, deltaLocal);
                float dragZ      = Vec3F.Dot(zAxis, deltaLocal);
                Vec3F xLocal     = transform.XAxis;
                Vec3F zLocal     = transform.ZAxis;
                trans = dragX * xLocal + dragZ * zLocal;
            }
            break;
            }
            return(trans);
        }
Beispiel #25
0
        public override void OnDragging(ViewControl vc, Point scrPt)
        {
            if (m_hitRegion == HitRegion.None || m_activeOp == null || m_activeOp.NodeList.Count == 0)
                return;
            Camera cam = vc.Camera;

            Matrix4F view = cam.ViewMatrix;
            Matrix4F proj = cam.ProjectionMatrix;

            Matrix4F axisMtrx = HitMatrix * view;
            Ray3F hitRay = HitRayV;
            Ray3F dragRay = vc.GetRay(scrPt, proj);
            
            Vec3F xAxis = axisMtrx.XAxis;
            Vec3F yAxis = axisMtrx.YAxis;
            Vec3F zAxis = axisMtrx.ZAxis;
            Vec3F origin = axisMtrx.Translation;
            
            Vec3F rotAxis = new Vec3F();            
            float theta = 0;

            float snapAngle = ((ISnapSettings)DesignView).SnapAngle;
            switch (m_hitRegion)
            {                
                case HitRegion.XAxis:
                    {
                        Plane3F xplane = new Plane3F(xAxis, origin);
                        theta = CalcAngle(origin, xplane, hitRay, dragRay, snapAngle);
                        rotAxis = HitMatrix.XAxis;                        
                    }
                    break;
                case HitRegion.YAxis:
                    {
                        Plane3F yplane = new Plane3F(yAxis, origin);
                        theta = CalcAngle(origin, yplane, hitRay, dragRay, snapAngle);
                        rotAxis = HitMatrix.YAxis;                        
                    }
                    break;
                case HitRegion.ZAxis:
                    {
                        Plane3F zplane = new Plane3F(zAxis, origin);
                        theta = CalcAngle(origin, zplane, hitRay, dragRay, snapAngle);
                        rotAxis = HitMatrix.ZAxis;
                    }
                    break;
                case HitRegion.LookAxis:
                    {                        
                        // for billboard objects the look vector is object's negative position in viewspace.
                        Vec3F lookAxis = Vec3F.Normalize(-origin);
                        Plane3F plane = new Plane3F(lookAxis, origin);
                        theta = CalcAngle(origin, plane, hitRay, dragRay, snapAngle);                        
                        rotAxis = m_lookAxisHitMtrx.ZAxis;
                    }
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }

            AngleAxisF axf = new AngleAxisF(-theta, rotAxis);
            Matrix4F deltaMtrx = new Matrix4F(axf);                                   
            Matrix4F rotMtrx = new Matrix4F();

            for (int i = 0; i < m_activeOp.NodeList.Count; i++)
            {
                ITransformable node = m_activeOp.NodeList[i];                              
                rotMtrx.Mul(m_rotations[i], deltaMtrx);                
                float ax, ay, az;
                rotMtrx.GetEulerAngles(out ax, out ay, out az);                                
                node.Rotation = new Vec3F(ax, ay, az);      
            }
        }
        private void RenderProperties(IEnumerable<object> objects, bool renderCaption, bool renderBound, bool renderPivot)
        {                      
            if (renderCaption || renderBound)
            {
                Util3D.RenderFlag = BasicRendererFlags.WireFrame;
                Matrix4F vp = Camera.ViewMatrix * Camera.ProjectionMatrix;
                foreach (object obj in objects)
                {
                    IBoundable bnode = obj.As<IBoundable>();
                    if (bnode == null || bnode.BoundingBox.IsEmpty || obj.Is<IGameObjectFolder>()) continue;

                    INameable nnode = obj.As<INameable>();
                    ITransformable trans = obj.As<ITransformable>();

                    if (renderBound)
                    {
                        Util3D.DrawAABB(bnode.BoundingBox);
                    }
                    if (renderCaption && nnode != null)
                    {
                        Vec3F topCenter = bnode.BoundingBox.Center;
                        topCenter.Y = bnode.BoundingBox.Max.Y;
                        Point pt = Project(vp, topCenter);
                        GameEngine.DrawText2D(nnode.Name, Util3D.CaptionFont, pt.X, pt.Y, Color.White);
                    }
                }
            }

            if (renderPivot)
            {
                Util3D.RenderFlag = BasicRendererFlags.WireFrame | BasicRendererFlags.DisableDepthTest;

                // create few temp matrics to
                Matrix4F toWorld = new Matrix4F();
                Matrix4F PV = new Matrix4F();
                Matrix4F sc = new Matrix4F();
                Matrix4F bl = new Matrix4F();
                Matrix4F recXform = new Matrix4F();
                foreach (object obj in objects)
                {
                    ITransformable trans = obj.As<ITransformable>();
                    IBoundable bnode = obj.As<IBoundable>();
                    if (trans == null || bnode == null || bnode.BoundingBox.IsEmpty || obj.Is<IGameObjectFolder>()) continue;

                    Path<DomNode> path = new Path<DomNode>(trans.Cast<DomNode>().GetPath());
                    toWorld.Set(Vec3F.ZeroVector);
                    TransformUtils.CalcPathTransform(toWorld, path, path.Count - 1);

                    // Offset by pivot
                    PV.Set(trans.Pivot);
                    toWorld.Mul(PV, toWorld);
                    Vec3F pos = toWorld.Translation;

                    const float pivotDiameter = 16; // in pixels
                    float s = Util.CalcAxisScale(Camera, pos, pivotDiameter, Height);                    
                    sc.Scale(s);
                    Util.CreateBillboard(bl, pos, Camera.WorldEye, Camera.Up, Camera.LookAt);
                    recXform = sc * bl;
                    Util3D.DrawPivot(recXform, Color.Yellow);
                }
            }
        }
        public override void OnDragging(ViewControl vc, Point scrPt)
        {
            if (m_hitRegion == HitRegion.None || m_activeOp == null || m_activeOp.NodeList.Count == 0)
            {
                return;
            }

            Matrix4F view = vc.Camera.ViewMatrix;
            // compute world * view
            Matrix4F wv = new Matrix4F();

            wv.Mul(HitMatrix, view);

            // create ray in view space.
            Ray3F rayV = vc.GetRay(scrPt, vc.Camera.ProjectionMatrix);

            Vec3F xAxis  = wv.XAxis;
            Vec3F yAxis  = wv.YAxis;
            Vec3F zAxis  = wv.ZAxis;
            Vec3F origin = wv.Translation;

            m_scale = new Vec3F(1, 1, 1);
            float scale = 1;
            float a1, a2;

            switch (m_hitRegion)
            {
            case HitRegion.XAxis:
            case HitRegion.NegXAxis:
            {
                a1 = Math.Abs(Vec3F.Dot(HitRayV.Direction, yAxis));
                a2 = Math.Abs(Vec3F.Dot(HitRayV.Direction, zAxis));
                Vec3F axis       = (a1 > a2 ? yAxis : zAxis);
                Vec3F p0         = HitRayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                Vec3F p1         = rayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                float dragAmount = Vec3F.Dot((p1 - p0), xAxis);
                if (m_hitRegion == HitRegion.NegXAxis)
                {
                    dragAmount *= -1;
                }
                m_scale.X = 1.0f + dragAmount / m_hitScale;
                scale     = m_scale.X;
            }

            break;

            case HitRegion.YAxis:
            case HitRegion.NegYAxis:
            {
                a1 = Math.Abs(Vec3F.Dot(HitRayV.Direction, zAxis));
                a2 = Math.Abs(Vec3F.Dot(HitRayV.Direction, xAxis));
                Vec3F axis       = (a1 > a2 ? zAxis : xAxis);
                Vec3F p0         = HitRayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                Vec3F p1         = rayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                float dragAmount = Vec3F.Dot((p1 - p0), yAxis);
                if (m_hitRegion == HitRegion.NegYAxis)
                {
                    dragAmount *= -1;
                }
                m_scale.Y = 1.0f + dragAmount / m_hitScale;
                scale     = m_scale.Y;
            }
            break;

            case HitRegion.ZAxis:
            case HitRegion.NegZAxis:
            {
                a1 = Math.Abs(Vec3F.Dot(HitRayV.Direction, xAxis));
                a2 = Math.Abs(Vec3F.Dot(HitRayV.Direction, yAxis));
                Vec3F axis       = (a1 > a2 ? xAxis : yAxis);
                Vec3F p0         = HitRayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                Vec3F p1         = rayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                float dragAmount = Vec3F.Dot((p1 - p0), zAxis);
                if (m_hitRegion == HitRegion.NegZAxis)
                {
                    dragAmount *= -1;
                }
                m_scale.Z = 1.0f + dragAmount / m_hitScale;
                scale     = m_scale.Z;
            }
            break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            if (m_isUniformScaling)
            {
                m_scale = new Vec3F(scale, scale, scale);
            }


            // scale
            for (int i = 0; i < m_activeOp.NodeList.Count; i++)
            {
                ITransformable node = m_activeOp.NodeList[i];
                node.Scale = Vec3F.Mul(m_originalScales[i], m_scale);

                Matrix4F mtrx = TransformUtils.CalcTransform(
                    Vec3F.ZeroVector,
                    node.Rotation,
                    node.Scale,
                    m_pivotOffset[i]);
                node.Translation = m_originalTranslations[i] + mtrx.Translation;
            }
        }
        protected override Matrix4F GetManipulatorMatrix()
        {
            ITransformable node = GetManipulatorNode(TransformationTypes.Translation);
            if (node == null ) return null;

            ISnapSettings snapSettings = (ISnapSettings)DesignView;            
            Path<DomNode> path = new Path<DomNode>(node.Cast<DomNode>().GetPath());
            Matrix4F localToWorld = TransformUtils.CalcPathTransform(path, path.Count - 1);
            
            Matrix4F toworld = new Matrix4F();
            if (snapSettings.ManipulateLocalAxis)
            {
                toworld.Set(localToWorld);
                toworld.Normalize(toworld);                
            }
            else
            {
                toworld.Translation = localToWorld.Translation;                
            }

            Vec3F offset = TransformUtils.CalcSnapFromOffset(node, snapSettings.SnapFrom);
          
            // Offset by pivot
            Matrix4F P = new Matrix4F();
            P.Translation = offset;
            toworld.Mul(toworld,P);
                        
            return toworld;
        }
Beispiel #29
0
        private void CalcAxisLengths(Camera camera, Matrix4F globalTransform, out float s1, out float s2, out float s3)
        {
            float worldHeight;

            // Calc view space matrix
            Matrix4F V = new Matrix4F();
            V.Mul(globalTransform, camera.ViewMatrix);

            // World height on origin's z value
            if (camera.Frustum.IsOrtho)
            {
                worldHeight = (camera.Frustum.Top - camera.Frustum.Bottom) / 2;
            }
            else
            {
                worldHeight = -V.ZTranslation * (float)Math.Tan(camera.Frustum.FovY / 2.0f);
            }

            s1 = (m_axisRatio * worldHeight) / V.XAxis.Length;
            s2 = (m_axisRatio * worldHeight) / V.YAxis.Length;
            s3 = (m_axisRatio * worldHeight) / V.ZAxis.Length;
        }
Beispiel #30
0
        /// <summary>
        /// Performs actions during control drag</summary>
        /// <param name="hit">Hit record</param>
        /// <param name="x">Mouse x position</param>
        /// <param name="y">Mouse y position</param>
        /// <param name="action">Render action</param>
        /// <param name="camera">Camera</param>
        /// <param name="transform">Transform</param>
        /// <returns>Translation, in world coordinates</returns>
        public Vec3F OnDrag(HitRecord hit, float x, float y, IRenderAction action, Camera camera, Matrix4F transform)
        {
            float a1, a2;
            Matrix4F W = new Matrix4F();
            W.Mul(transform, camera.ViewMatrix);

            // Setup rays, in view space. (-z goes into the screen.)
            Ray3F ray0 = camera.CreateRay(m_iX, m_iY);
            Ray3F ray = camera.CreateRay(x, y);

            // Build axis and origin in view space
            Vec3F xAxis = W.XAxis;
            Vec3F yAxis = W.YAxis;
            Vec3F zAxis = W.ZAxis;
            Vec3F origin = W.Translation;

            Vec3F trans = new Vec3F();

            // Choose the best projection plane according to the projection angle
            switch ((HitElement)hit.RenderObjectData[1])
            {
                case HitElement.X_ARROW:
                    {
                        a1 = Math.Abs(Vec3F.Dot(ray0.Direction, yAxis));
                        a2 = Math.Abs(Vec3F.Dot(ray0.Direction, zAxis));
                        Vec3F axis = (a1 > a2 ? yAxis : zAxis);
                        Vec3F p0 = ray0.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                        Vec3F p1 = ray.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                        float dragAmount = Vec3F.Dot(xAxis, p1 - p0);
                        Vec3F xLocal = transform.XAxis;
                        trans = dragAmount * xLocal;
                    }
                    break;

                case HitElement.Y_ARROW:
                    {
                        a1 = Math.Abs(Vec3F.Dot(ray0.Direction, zAxis));
                        a2 = Math.Abs(Vec3F.Dot(ray0.Direction, xAxis));
                        Vec3F axis = (a1 > a2 ? zAxis : xAxis);
                        Vec3F p0 = ray0.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                        Vec3F p1 = ray.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                        float dragAmount = Vec3F.Dot(yAxis, p1 - p0);
                        Vec3F yLocal = transform.YAxis;
                        trans = dragAmount * yLocal;
                    }
                    break;

                case HitElement.Z_ARROW:
                    {
                        a1 = Math.Abs(Vec3F.Dot(ray0.Direction, xAxis));
                        a2 = Math.Abs(Vec3F.Dot(ray0.Direction, yAxis));
                        Vec3F axis = (a1 > a2 ? xAxis : yAxis);
                        Vec3F p0 = ray0.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                        Vec3F p1 = ray.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                        float dragAmount = Vec3F.Dot(zAxis, p1 - p0);
                        Vec3F zLocal = transform.ZAxis;
                        trans = dragAmount * zLocal;
                    }
                    break;
                
                case HitElement.XY_SQUARE:
                    {
                        Vec3F p0 = ray0.IntersectPlane(zAxis, -Vec3F.Dot(zAxis, origin));
                        Vec3F p1 = ray.IntersectPlane(zAxis, -Vec3F.Dot(zAxis, origin));
                        Vec3F deltaLocal = p1 - p0;
                        float dragX = Vec3F.Dot(xAxis, deltaLocal);
                        float dragY = Vec3F.Dot(yAxis, deltaLocal);
                        Vec3F xLocal = transform.XAxis;
                        Vec3F yLocal = transform.YAxis;
                        trans = dragX * xLocal + dragY * yLocal;
                    }
                    break;

                case HitElement.YZ_SQUARE:
                    {
                        Vec3F p0 = ray0.IntersectPlane(xAxis, -Vec3F.Dot(xAxis, origin));
                        Vec3F p1 = ray.IntersectPlane(xAxis, -Vec3F.Dot(xAxis, origin));
                        Vec3F deltaLocal = p1 - p0;
                        float dragY = Vec3F.Dot(yAxis, deltaLocal);
                        float dragZ = Vec3F.Dot(zAxis, deltaLocal);
                        Vec3F yLocal = transform.YAxis;
                        Vec3F zLocal = transform.ZAxis;
                        trans = dragY * yLocal + dragZ * zLocal;
                    }
                    break;

                case HitElement.XZ_SQUARE:
                    {
                        Vec3F p0 = ray0.IntersectPlane(yAxis, -Vec3F.Dot(yAxis, origin));
                        Vec3F p1 = ray.IntersectPlane(yAxis, -Vec3F.Dot(yAxis, origin));
                        Vec3F deltaLocal = p1 - p0;
                        float dragX = Vec3F.Dot(xAxis, deltaLocal);
                        float dragZ = Vec3F.Dot(zAxis, deltaLocal);
                        Vec3F xLocal = transform.XAxis;
                        Vec3F zLocal = transform.ZAxis;
                        trans = dragX * xLocal + dragZ * zLocal;
                    }
                    break;
            }
            return trans;
        }
Beispiel #31
0
        public void Render(Camera cam)
        {
            GameEngine.SetRendererFlag(BasicRendererFlags.WireFrame);
            IGrid grid = this.As<IGrid>();

            if (grid.Visible == false)
                return;

            float s = grid.Size;

            Matrix4F scale = new Matrix4F();
            scale.Scale(new Vec3F(s, s, s));

            Matrix4F gridXform = new Matrix4F();
            if (cam.Frustum.IsOrtho)
            {
                float dist = cam.ViewMatrix.Translation.Z;
                ViewTypes vt = cam.ViewType;
                if (vt == ViewTypes.Top)
                {
                    gridXform.Translation
                        = new Vec3F(0, dist, 0);
                }
                else if (vt == ViewTypes.Bottom)
                {
                    gridXform.Translation
                        = new Vec3F(0, -dist, 0);
                }
                else if (vt == ViewTypes.Right)
                {
                    gridXform.RotZ(MathHelper.PiOver2);
                    gridXform.Translation
                        = new Vec3F(dist, 0, 0);
                }
                else if (vt == ViewTypes.Left)
                {
                    gridXform.RotZ(MathHelper.PiOver2);
                    gridXform.Translation
                        = new Vec3F(-dist, 0, 0);

                }
                else if (vt == ViewTypes.Front)
                {
                    gridXform.RotX(MathHelper.PiOver2);
                    gridXform.Translation
                        = new Vec3F(0, 0, dist);

                }
                else if (vt == ViewTypes.Back)
                {
                    gridXform.RotX(MathHelper.PiOver2);
                    gridXform.Translation
                        = new Vec3F(0, 0, -dist);

                }
                gridXform.Mul(scale, gridXform);
            }
            else
            {
                Matrix4F trans = new Matrix4F();
                trans.Translation = new Vec3F(0, grid.Height, 0);
                gridXform = Matrix4F.Multiply(scale, trans);
            }

            GameEngine.DrawPrimitive(PrimitiveType.LineList, m_gridVBId, 0, m_gridVertexCount, Color.LightGray,
                                     Matrix4F.Multiply(gridXform, cam.AxisSystem));

            GameEngine.DrawPrimitive(PrimitiveType.LineList, m_basisAxesVBId, 0, m_basisAxesVertexCount, Color.White,
                                     gridXform);
        }
Beispiel #32
0
        /// <summary>
        /// Pushes a matrix onto the matrix stack</summary>
        /// <param name="matrix">The matrix</param>
        /// <param name="multiply">If true, multiply matrix by top matrix</param>
        public void PushMatrix(Matrix4F matrix, bool multiply)
        {
            if (m_matrixStackFreeze)
                throw new InvalidOperationException(
                    "the IRenderObject does not implement ISetsLocalTransform");

            int count = m_matrixStack.Count;
            Matrix4F topMatrix = (count > 0) ? m_matrixStack[count - 1] : Matrix4F.Identity;

            Matrix4F newMatrix = new Matrix4F();
            if (multiply)
                newMatrix.Mul(matrix, topMatrix);
            else
                newMatrix.Set(matrix);

            m_matrixStack.Add(newMatrix);
        }
Beispiel #33
0
        public override void OnDragging(ViewControl vc, Point scrPt)
        {
            if (m_hitRegion == HitRegion.None || m_activeOp == null || m_activeOp.NodeList.Count == 0)
                return;

            Matrix4F view = vc.Camera.ViewMatrix;
            // compute world * view
            Matrix4F wv = new Matrix4F();
            wv.Mul(HitMatrix, view);

            // create ray in view space.
            Ray3F rayV = vc.GetRay(scrPt,vc.Camera.ProjectionMatrix);

            Vec3F xAxis = wv.XAxis;
            Vec3F yAxis = wv.YAxis;
            Vec3F zAxis = wv.ZAxis;
            Vec3F origin = wv.Translation;

            //Vec3F pos;
            m_scale = new Vec3F(1, 1, 1);
            float scale = 1;
            float a1, a2;

            switch (m_hitRegion)
            {
                case HitRegion.XAxis:
                    {
                        a1 = Math.Abs(Vec3F.Dot(HitRayV.Direction, yAxis));
                        a2 = Math.Abs(Vec3F.Dot(HitRayV.Direction, zAxis));
                        Vec3F axis = (a1 > a2 ? yAxis : zAxis);
                        Vec3F p0 = HitRayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                        Vec3F p1 = rayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                        float dragAmount = Vec3F.Dot((p1 - p0), xAxis);
                        m_scale.X = 1.0f + dragAmount / m_hitScale;
                        scale = m_scale.X;
                    }

                    break;
                case HitRegion.YAxis:
                    {
                        a1 = Math.Abs(Vec3F.Dot(HitRayV.Direction, zAxis));
                        a2 = Math.Abs(Vec3F.Dot(HitRayV.Direction, xAxis));
                        Vec3F axis = (a1 > a2 ? zAxis : xAxis);
                        Vec3F p0 = HitRayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                        Vec3F p1 = rayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                        float dragAmount = Vec3F.Dot((p1 - p0), yAxis);
                        m_scale.Y = 1.0f + dragAmount / m_hitScale;
                        scale = m_scale.Y;
                    }
                    break;
                case HitRegion.ZAxis:
                    {
                        a1 = Math.Abs(Vec3F.Dot(HitRayV.Direction, xAxis));
                        a2 = Math.Abs(Vec3F.Dot(HitRayV.Direction, yAxis));
                        Vec3F axis = (a1 > a2 ? xAxis : yAxis);
                        Vec3F p0 = HitRayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                        Vec3F p1 = rayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                        float dragAmount = Vec3F.Dot((p1 - p0), zAxis);
                        m_scale.Z = 1.0f + dragAmount / m_hitScale;
                        scale = m_scale.Z;
                    }
                    break;
                case HitRegion.CenterCube:
                    {

                        Vec3F axis = new Vec3F(0, 0, 1);
                        Vec3F p0 = HitRayV.IntersectPlane(axis, -origin.Z);
                        Vec3F p1 = rayV.IntersectPlane(axis, -origin.Z);
                        Vec3F dragVec = p1 - p0;

                        float dragAmount = 1.0f + dragVec.X / m_hitScale;
                        m_scale.X = dragAmount ;
                        m_scale.Y = dragAmount ;
                        m_scale.Z = dragAmount ;
                        scale = m_scale.X;

                    }
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }

            if(m_isUniformScaling)
                m_scale = new Vec3F(scale,scale,scale);

            // scale
            for (int i = 0; i < m_activeOp.NodeList.Count; i++)
            {
                ITransformable transformable = m_activeOp.NodeList[i];
                transformable.Scale = Vec3F.Mul(m_originalValues[i], m_scale);
            }
        }
Beispiel #34
0
        /// <summary>
        /// Calculates the width and height of the view frustum at the given 3D location</summary>
        /// <param name="camera">The camera</param>
        /// <param name="globalTransform">The world space matrix specifying a position</param>
        /// <param name="h">The height of the view frustum at the given position</param>
        /// <param name="w">The width of the view frustum at the given position</param>
        public static void CalcWorldDimensions(Camera camera, Matrix4F globalTransform, out float h, out float w)
        {
            Matrix4F W = new Matrix4F();
            W.Mul(globalTransform, camera.ViewMatrix);

            // World height on origin's z value
            if (camera.Frustum.IsOrtho)
            {
                w = camera.Frustum.Right - camera.Frustum.Left;
                h = camera.Frustum.Top - camera.Frustum.Bottom;
            }
            else
            {
                float minusZ = -W.Translation.Z;
                h = minusZ * (float)Math.Tan(camera.Frustum.FovY / 2.0f) * 2.0f;
                w = minusZ * (float)Math.Tan(camera.Frustum.FovX / 2.0f) * 2.0f;
            }
        }
        public override void OnDragging(ViewControl vc, Point scrPt)
        {
            if (m_hitRegion == HitRegion.None || NodeList.Count == 0)
                return;
            Camera cam = vc.Camera;

            Matrix4F view = cam.ViewMatrix;
            Matrix4F mtrx = cam.ProjectionMatrix;

            Matrix4F axisMtrx = HitMatrix * view;
            Ray3F hitRay = HitRayV;
            Ray3F dragRay = vc.GetRay(scrPt, mtrx);
            
            Vec3F xAxis = axisMtrx.XAxis;
            Vec3F yAxis = axisMtrx.YAxis;
            Vec3F zAxis = axisMtrx.ZAxis;
            Vec3F origin = axisMtrx.Translation;
            
            Vec3F rotAxis = new Vec3F();
            float theta = 0;
            
            switch (m_hitRegion)
            {                
                case HitRegion.XAxis:
                    {
                        Plane3F xplane = new Plane3F(xAxis, origin);
                        theta = CalcAngle(origin, xplane, hitRay, dragRay);
                        rotAxis = HitMatrix.XAxis;                     
                    }
                    break;
                case HitRegion.YAxis:
                    {
                        Plane3F yplane = new Plane3F(yAxis, origin);
                        theta = CalcAngle(origin, yplane, hitRay, dragRay);
                        rotAxis = HitMatrix.YAxis;

                    }
                    break;
                case HitRegion.ZAxis:
                    {
                        Plane3F zplane = new Plane3F(zAxis, origin);
                        theta = CalcAngle(origin, zplane, hitRay, dragRay);
                        rotAxis = HitMatrix.ZAxis;
                    }
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }

            AngleAxisF axf = new AngleAxisF(-theta, rotAxis);
            Matrix4F deltaMtrx = new Matrix4F(axf);                                   
            Matrix4F rotMtrx = new Matrix4F();            
            for (int i = 0; i < NodeList.Count; i++)
            {                                
                ITransformable node = NodeList[i];                
                rotMtrx.Set(m_rotations[i]);
                rotMtrx.Mul(rotMtrx, deltaMtrx);                
                float ax, ay, az;
                rotMtrx.GetEulerAngles(out ax, out ay, out az);                
                node.Rotation = new Vec3F(ax,ay,az);
            }

        }
Beispiel #36
0
Datei: Node.cs Projekt: zparr/ATF
        /// <summary>
        /// Performs initialization when the adapter's node is set.
        /// This method is called each time the adapter is connected to its underlying node.
        /// Typically overridden by creators of DOM adapters.</summary>
        protected override void OnNodeSet()
        {
            base.OnNodeSet();

            // get trans, scale, and rot.
            foreach (DomNode domNode in this.DomNode.GetChildList(Schema.node.scaleChild))
            {
                m_scale = Tools.GetVector3(domNode, Schema.TargetableFloat3.Attribute);
                break;
            }

            foreach (DomNode domNode in this.DomNode.GetChildList(Schema.node.translateChild))
            {
                m_translation = Tools.GetVector3(domNode, Schema.TargetableFloat3.Attribute);
                break;
            }

            const float PiOver180 = (float)(Math.PI / 180.0f);

            foreach (DomNode node in DomNode.GetChildList(Schema.node.rotateChild))
            {
                double[] arr   = (double[])node.GetAttribute(Schema.rotate.Attribute);
                float    angle = (float)arr[3] * PiOver180;
                string   sid   = node.GetAttribute(Schema.rotate.sidAttribute) as string;
                if (string.IsNullOrEmpty(sid))
                {
                    continue;
                }
                if (sid == "rotateX")
                {
                    m_rotation.X = angle;
                }
                else if (sid == "rotateY")
                {
                    m_rotation.Y = angle;
                }
                else if (sid == "rotateZ")
                {
                    m_rotation.Z = angle;
                }
            }

            Matrix4F M    = new Matrix4F();
            Matrix4F temp = new Matrix4F();

            temp.Scale(Scale);
            M.Mul(M, temp);

            if (m_rotation.X != 0)
            {
                temp.RotX(m_rotation.X);
                M.Mul(M, temp);
            }

            if (m_rotation.Y != 0)
            {
                temp.RotY(m_rotation.Y);
                M.Mul(M, temp);
            }

            if (m_rotation.Z != 0)
            {
                temp.RotZ(m_rotation.Z);
                M.Mul(M, temp);
            }

            temp.Set(Translation);
            M.Mul(M, temp);

            Transform     = M;
            m_boundingBox = new Cached <Box>(CalculateBoundingBox);
            Visible       = true;
        }
Beispiel #37
0
        public void Render(Camera cam)
        {
            GameEngine.SetRendererFlag(BasicRendererFlags.WireFrame);
            IGrid grid = this.As <IGrid>();

            if (grid.Visible == false)
            {
                return;
            }

            float s = grid.Size;

            Matrix4F scale = new Matrix4F();

            scale.Scale(new Vec3F(s, s, s));

            Matrix4F gridXform = new Matrix4F();

            if (cam.Frustum.IsOrtho)
            {
                float     dist = cam.ViewMatrix.Translation.Z;
                ViewTypes vt   = cam.ViewType;
                if (vt == ViewTypes.Top)
                {
                    gridXform.Translation
                        = new Vec3F(0, dist, 0);
                }
                else if (vt == ViewTypes.Bottom)
                {
                    gridXform.Translation
                        = new Vec3F(0, -dist, 0);
                }
                else if (vt == ViewTypes.Right)
                {
                    gridXform.RotZ(MathHelper.PiOver2);
                    gridXform.Translation
                        = new Vec3F(dist, 0, 0);
                }
                else if (vt == ViewTypes.Left)
                {
                    gridXform.RotZ(MathHelper.PiOver2);
                    gridXform.Translation
                        = new Vec3F(-dist, 0, 0);
                }
                else if (vt == ViewTypes.Front)
                {
                    gridXform.RotX(MathHelper.PiOver2);
                    gridXform.Translation
                        = new Vec3F(0, 0, dist);
                }
                else if (vt == ViewTypes.Back)
                {
                    gridXform.RotX(MathHelper.PiOver2);
                    gridXform.Translation
                        = new Vec3F(0, 0, -dist);
                }
                gridXform.Mul(scale, gridXform);
            }
            else
            {
                Matrix4F trans = new Matrix4F();
                trans.Translation = new Vec3F(0, grid.Height, 0);
                gridXform         = Matrix4F.Multiply(scale, trans);
            }

            GameEngine.DrawPrimitive(PrimitiveType.LineList, m_gridVBId, 0, m_gridVertexCount, Color.LightGray,
                                     gridXform);
        }
Beispiel #38
0
        public override void OnDragging(ViewControl vc, Point scrPt)
        {
            if (m_hitRegion == HitRegion.None || NodeList.Count == 0)
            {
                return;
            }

            Matrix4F view = vc.Camera.ViewMatrix;
            // compute world * view
            Matrix4F wv = new Matrix4F();

            wv.Mul(HitMatrix, view);

            // create ray in view space.
            Ray3F rayV = vc.GetRay(scrPt, vc.Camera.ProjectionMatrix);


            Vec3F xAxis  = wv.XAxis;
            Vec3F yAxis  = wv.YAxis;
            Vec3F zAxis  = wv.ZAxis;
            Vec3F origin = wv.Translation;

            //Vec3F pos;
            m_scale = new Vec3F(1, 1, 1);
            float scale = 1;
            float a1, a2;

            switch (m_hitRegion)
            {
            case HitRegion.XAxis:
            {
                a1 = Math.Abs(Vec3F.Dot(HitRayV.Direction, yAxis));
                a2 = Math.Abs(Vec3F.Dot(HitRayV.Direction, zAxis));
                Vec3F axis       = (a1 > a2 ? yAxis : zAxis);
                Vec3F p0         = HitRayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                Vec3F p1         = rayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                float dragAmount = Vec3F.Dot((p1 - p0), xAxis);
                m_scale.X = 1.0f + dragAmount / m_hitScale;
                scale     = m_scale.X;
            }

            break;

            case HitRegion.YAxis:
            {
                a1 = Math.Abs(Vec3F.Dot(HitRayV.Direction, zAxis));
                a2 = Math.Abs(Vec3F.Dot(HitRayV.Direction, xAxis));
                Vec3F axis       = (a1 > a2 ? zAxis : xAxis);
                Vec3F p0         = HitRayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                Vec3F p1         = rayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                float dragAmount = Vec3F.Dot((p1 - p0), yAxis);
                m_scale.Y = 1.0f + dragAmount / m_hitScale;
                scale     = m_scale.Y;
            }
            break;

            case HitRegion.ZAxis:
            {
                a1 = Math.Abs(Vec3F.Dot(HitRayV.Direction, xAxis));
                a2 = Math.Abs(Vec3F.Dot(HitRayV.Direction, yAxis));
                Vec3F axis       = (a1 > a2 ? xAxis : yAxis);
                Vec3F p0         = HitRayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                Vec3F p1         = rayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                float dragAmount = Vec3F.Dot((p1 - p0), zAxis);
                m_scale.Z = 1.0f + dragAmount / m_hitScale;
                scale     = m_scale.Z;
            }
            break;

            case HitRegion.FreeRect:
            {
                Vec3F axis    = new Vec3F(0, 0, 1);
                Vec3F p0      = HitRayV.IntersectPlane(axis, -origin.Z);
                Vec3F p1      = rayV.IntersectPlane(axis, -origin.Z);
                Vec3F dragVec = p1 - p0;

                float dragAmount = 1.0f + dragVec.X / m_hitScale;
                m_scale.X = dragAmount;
                m_scale.Y = dragAmount;
                m_scale.Z = dragAmount;
                scale     = m_scale.X;
            }
            break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            if (m_isUniformScaling)
            {
                m_scale = new Vec3F(scale, scale, scale);
            }

            // scale
            for (int i = 0; i < NodeList.Count; i++)
            {
                ITransformable transformable = NodeList[i];
                transformable.Scale = Vec3F.Mul(m_originalValues[i], m_scale);
            }
        }
Beispiel #39
0
        public override void OnDragging(ViewControl vc, Point scrPt)
        {
            if (m_hitRegion == HitRegion.None || m_activeOp == null || m_activeOp.NodeList.Count == 0)
                return;

            Matrix4F view = vc.Camera.ViewMatrix;
            // compute world * view
            Matrix4F wv = new Matrix4F();
            wv.Mul(HitMatrix, view);

            // create ray in view space.
            Ray3F rayV = vc.GetRay(scrPt, vc.Camera.ProjectionMatrix);

            Vec3F xAxis = wv.XAxis;
            Vec3F yAxis = wv.YAxis;
            Vec3F zAxis = wv.ZAxis;
            Vec3F origin = wv.Translation;

            m_scale = new Vec3F(1, 1, 1);
            float scale = 1;
            float a1, a2;

            switch (m_hitRegion)
            {
                case HitRegion.XAxis:
                case HitRegion.NegXAxis:
                    {
                        a1 = Math.Abs(Vec3F.Dot(HitRayV.Direction, yAxis));
                        a2 = Math.Abs(Vec3F.Dot(HitRayV.Direction, zAxis));
                        Vec3F axis = (a1 > a2 ? yAxis : zAxis);
                        Vec3F p0 = HitRayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                        Vec3F p1 = rayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                        float dragAmount = Vec3F.Dot((p1 - p0), xAxis);
                        if (m_hitRegion == HitRegion.NegXAxis)
                        {
                            dragAmount *= -1;
                        }
                        m_scale.X = 1.0f + dragAmount / m_hitScale;
                        scale = m_scale.X;

                    }

                    break;
                case HitRegion.YAxis:
                case HitRegion.NegYAxis:
                    {
                        a1 = Math.Abs(Vec3F.Dot(HitRayV.Direction, zAxis));
                        a2 = Math.Abs(Vec3F.Dot(HitRayV.Direction, xAxis));
                        Vec3F axis = (a1 > a2 ? zAxis : xAxis);
                        Vec3F p0 = HitRayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                        Vec3F p1 = rayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                        float dragAmount = Vec3F.Dot((p1 - p0), yAxis);
                        if (m_hitRegion == HitRegion.NegYAxis)
                        {
                            dragAmount *= -1;
                        }
                        m_scale.Y = 1.0f + dragAmount / m_hitScale;
                        scale = m_scale.Y;

                    }
                    break;
                case HitRegion.ZAxis:
                case HitRegion.NegZAxis:
                    {
                        a1 = Math.Abs(Vec3F.Dot(HitRayV.Direction, xAxis));
                        a2 = Math.Abs(Vec3F.Dot(HitRayV.Direction, yAxis));
                        Vec3F axis = (a1 > a2 ? xAxis : yAxis);
                        Vec3F p0 = HitRayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                        Vec3F p1 = rayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                        float dragAmount = Vec3F.Dot((p1 - p0), zAxis);
                        if (m_hitRegion == HitRegion.NegZAxis)
                        {
                            dragAmount *= -1;
                        }
                        m_scale.Z = 1.0f + dragAmount / m_hitScale;
                        scale = m_scale.Z;

                    }
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
            }

            if(m_isUniformScaling)
                m_scale = new Vec3F(scale,scale,scale);

            // scale
            for (int i = 0; i < m_activeOp.NodeList.Count; i++)
            {
                ITransformable node = m_activeOp.NodeList[i];
                node.Scale = Vec3F.Mul(m_originalScales[i], m_scale);

                Matrix4F mtrx = TransformUtils.CalcTransform(
                   Vec3F.ZeroVector,
                   node.Rotation,
                   node.Scale,
                    m_pivotOffset[i]);
                node.Translation = m_originalTranslations[i] + mtrx.Translation;

            }
        }
Beispiel #40
0
        public override void OnDragging(ViewControl vc, Point scrPt)
        {
            if (m_hitRegion == HitRegion.None || NodeList.Count == 0)
            {
                return;
            }
            Camera cam = vc.Camera;

            Matrix4F view = cam.ViewMatrix;
            Matrix4F mtrx = cam.ProjectionMatrix;

            Matrix4F axisMtrx = HitMatrix * view;
            Ray3F    hitRay   = HitRayV;
            Ray3F    dragRay  = vc.GetRay(scrPt, mtrx);

            Vec3F xAxis  = axisMtrx.XAxis;
            Vec3F yAxis  = axisMtrx.YAxis;
            Vec3F zAxis  = axisMtrx.ZAxis;
            Vec3F origin = axisMtrx.Translation;

            Vec3F rotAxis = new Vec3F();
            float theta   = 0;

            float snapAngle = ((ISnapSettings)DesignView).SnapAngle;

            switch (m_hitRegion)
            {
            case HitRegion.XAxis:
            {
                Plane3F xplane = new Plane3F(xAxis, origin);
                theta   = CalcAngle(origin, xplane, hitRay, dragRay, snapAngle);
                rotAxis = HitMatrix.XAxis;
            }
            break;

            case HitRegion.YAxis:
            {
                Plane3F yplane = new Plane3F(yAxis, origin);
                theta   = CalcAngle(origin, yplane, hitRay, dragRay, snapAngle);
                rotAxis = HitMatrix.YAxis;
            }
            break;

            case HitRegion.ZAxis:
            {
                Plane3F zplane = new Plane3F(zAxis, origin);
                theta   = CalcAngle(origin, zplane, hitRay, dragRay, snapAngle);
                rotAxis = HitMatrix.ZAxis;
            }
            break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            AngleAxisF axf       = new AngleAxisF(-theta, rotAxis);
            Matrix4F   deltaMtrx = new Matrix4F(axf);
            Matrix4F   rotMtrx   = new Matrix4F();

            for (int i = 0; i < NodeList.Count; i++)
            {
                ITransformable node = NodeList[i];
                rotMtrx.Mul(m_rotations[i], deltaMtrx);
                float ax, ay, az;
                rotMtrx.GetEulerAngles(out ax, out ay, out az);
                node.Rotation = new Vec3F(ax, ay, az);
            }
        }
Beispiel #41
0
        protected override Matrix4F GetManipulatorMatrix()
        {
            ITransformable node = GetManipulatorNode(TransformationTypes.Rotation);
            if (node == null ) return null;
            
            Path<DomNode> path = new Path<DomNode>(node.Cast<DomNode>().GetPath());
            Matrix4F localToWorld = TransformUtils.CalcPathTransform(path, path.Count - 1);

            // local transform
            Matrix4F toworld = new Matrix4F(localToWorld);

            // Offset by rotate pivot
            Matrix4F P = new Matrix4F();
            P.Translation = node.Pivot;
            toworld.Mul(P, toworld);

            // Normalize            
            toworld.Normalize(toworld);

            return toworld;
        }
Beispiel #42
0
        /// <summary>
        /// Performs initialization when the adapter's node is set.
        /// This method is called each time the adapter is connected to its underlying node.
        /// Typically overridden by creators of DOM adapters.</summary>
        protected override void OnNodeSet()
        {
            base.OnNodeSet();

            // get trans, scale, and rot.
            foreach (DomNode domNode in this.DomNode.GetChildList(Schema.node.scaleChild))
            {
                m_scale = Tools.GetVector3(domNode, Schema.TargetableFloat3.Attribute);
                break;
            }

            foreach (DomNode domNode in this.DomNode.GetChildList(Schema.node.translateChild))
            {
                m_translation = Tools.GetVector3(domNode, Schema.TargetableFloat3.Attribute);
                break;
            }
                        
            const float PiOver180 = (float)(Math.PI / 180.0f);
            foreach (DomNode node in DomNode.GetChildList(Schema.node.rotateChild))
            {                
                double[] arr = (double[])node.GetAttribute(Schema.rotate.Attribute);
                float angle = (float)arr[3] * PiOver180;
                string sid = node.GetAttribute(Schema.rotate.sidAttribute) as string;
                if (string.IsNullOrEmpty(sid))
                    continue;
                if (sid == "rotateX")
                    m_rotation.X = angle;
                else if (sid == "rotateY")
                    m_rotation.Y = angle;
                else if (sid == "rotateZ")
                    m_rotation.Z = angle;
            }

            Matrix4F M = new Matrix4F();
            Matrix4F temp = new Matrix4F();

            temp.Scale(Scale);
            M.Mul(M, temp);

            if (m_rotation.X != 0)
            {
                temp.RotX(m_rotation.X);
                M.Mul(M, temp);
            }

            if (m_rotation.Y != 0)
            {
                temp.RotY(m_rotation.Y);
                M.Mul(M, temp);
            }

            if (m_rotation.Z != 0)
            {
                temp.RotZ(m_rotation.Z);
                M.Mul(M, temp);
            }

            temp.Set(Translation);
            M.Mul(M, temp);

            Transform = M;
            m_boundingBox = new Cached<Box>(CalculateBoundingBox);
            Visible = true;
        }
Beispiel #43
0
        private void RenderProperties(GUILayer.SimpleRenderingContext context, IEnumerable <object> objects, bool renderCaption, bool renderBound, bool renderPivot)
        {
            if (renderCaption || renderBound)
            {
                Util3D.SetRenderFlag(context, BasicRendererFlags.WireFrame);
                Matrix4F vp = Camera.ViewMatrix * Camera.ProjectionMatrix;
                foreach (object obj in objects)
                {
                    IBoundable bnode = obj.As <IBoundable>();
                    if (bnode == null || bnode.BoundingBox.IsEmpty || obj.Is <IGameObjectFolder>())
                    {
                        continue;
                    }

                    INameable      nnode = obj.As <INameable>();
                    ITransformable trans = obj.As <ITransformable>();

                    if (renderBound)
                    {
                        Util3D.DrawAABB(context, bnode.BoundingBox);
                    }
                    if (renderCaption && nnode != null)
                    {
                        Vec3F topCenter = bnode.BoundingBox.Center;
                        topCenter.Y = bnode.BoundingBox.Max.Y;
                        Point pt = Project(vp, topCenter);
                        GameEngine.DrawText2D(nnode.Name, Util3D.CaptionFont, pt.X, pt.Y, Color.White);
                    }
                }
            }

            if (renderPivot)
            {
                Util3D.SetRenderFlag(context, BasicRendererFlags.WireFrame | BasicRendererFlags.DisableDepthTest);

                // create few temp matrics to
                Matrix4F toWorld  = new Matrix4F();
                Matrix4F PV       = new Matrix4F();
                Matrix4F sc       = new Matrix4F();
                Matrix4F bl       = new Matrix4F();
                Matrix4F recXform = new Matrix4F();
                foreach (object obj in objects)
                {
                    ITransformable trans = obj.As <ITransformable>();
                    IBoundable     bnode = obj.As <IBoundable>();
                    if (trans == null || bnode == null || bnode.BoundingBox.IsEmpty || obj.Is <IGameObjectFolder>())
                    {
                        continue;
                    }

                    Path <DomNode> path = new Path <DomNode>(trans.Cast <DomNode>().GetPath());
                    toWorld.Set(Vec3F.ZeroVector);
                    TransformUtils.CalcPathTransform(toWorld, path, path.Count - 1);

                    // Offset by pivot
                    PV.Set(trans.Pivot);
                    toWorld.Mul(PV, toWorld);
                    Vec3F pos = toWorld.Translation;

                    const float pivotDiameter = 16; // in pixels
                    float       s             = Util.CalcAxisScale(Camera, pos, pivotDiameter, Height);
                    sc.Scale(s);
                    Util.CreateBillboard(bl, pos, Camera.WorldEye, Camera.Up, Camera.LookAt);
                    recXform = sc * bl;
                    Util3D.DrawPivot(context, recXform, Color.Yellow);
                }
            }
        }
Beispiel #44
0
        /// <summary>
        /// Gets the view matrix corresponding to a "look at" point</summary>
        /// <param name="azimuth">Camera pan, in radians</param>
        /// <param name="elevation">Camera tilt, in radians</param>
        /// <param name="lookAt">"Look at" direction</param>
        /// <param name="dolly">Distance from "look at" point</param>
        /// <returns>View matrix corresponding to the "look at" point</returns>
        public static Matrix4F LookAtMatrix(float azimuth, float elevation, Vec3F lookAt, float dolly)
        {
            Matrix4F R = LookAtRotationMatrix(azimuth, elevation, lookAt);
            R.ZTranslation = -dolly;

            Matrix4F T = new Matrix4F
            (
                1, 0, 0, 0,
                0, 1, 0, 0,
                0, 0, 1, 0,
                -lookAt.X, -lookAt.Y, -lookAt.Z, 1
            );

            Matrix4F result = new Matrix4F();
            result.Mul(T, R);

            return result;
        }