/// <summary>
        /// Handles key-down 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 KeyDown(object sender, KeyEventArgs e)
        {
            m_keyMap[e.KeyValue] = true;

            ControlScheme controlSchm = InputScheme.ActiveControlScheme;
            // W A S D for forward, strafe left, backward, strafe right, is the default
            Vec3F dir = new Vec3F();
            if (m_keyMap[(int)controlSchm.Left1] ||
                m_keyMap[(int)controlSchm.Left2])
                dir = dir - Camera.Right;
            if (m_keyMap[(int)controlSchm.Right1] ||
                m_keyMap[(int)controlSchm.Right2])
                dir = dir + Camera.Right;
            if (m_keyMap[(int)controlSchm.Forward1] ||
                m_keyMap[(int)controlSchm.Forward2])
                dir = dir + Camera.LookAt;
            if (m_keyMap[(int)controlSchm.Back1] ||
                m_keyMap[(int)controlSchm.Back2])
                dir = dir - Camera.LookAt;

            bool handled = controlSchm.IsControllingCamera(Control.ModifierKeys, e);
            

            if (handled)
            {
                dir.Normalize();
                Camera.Set(Camera.Eye + dir * m_scale);
            }

            return handled;
        }
Beispiel #2
0
        /// <summary>
        /// Extends sphere to enclose another sphere</summary>
        /// <param name="sphere">Sphere to enclose</param>
        /// <returns>Extended sphere</returns>
        public Sphere3F Extend(Sphere3F sphere)
        {
            if (!m_initialized)
            {
                Center = sphere.Center;
                Radius = sphere.Radius;
                m_initialized = true;
            }
            else if (!Contains(sphere))
            {
                if (Center == sphere.Center)
                {
                    Radius = sphere.Radius;
                }
                else
                {
                    Vec3F normal = Vec3F.Normalize(sphere.Center - Center);
                    Vec3F p1 = sphere.Center + (normal * sphere.Radius);
                    Vec3F p2 = Center - (normal * Radius);
                    Radius = (p2 - p1).Length / 2.0f;
                    Center = (p1 + p2) / 2.0f;
                }
            }

            return this;
        }
Beispiel #3
0
        private void TestToStringWithCulture(CultureInfo culture)
        {
            CultureInfo originalCulture = Thread.CurrentThread.CurrentCulture;
            Thread.CurrentThread.CurrentCulture = culture;
            try
            {
                string listSeparator = culture.TextInfo.ListSeparator;
                string decimalSeparator = culture.NumberFormat.NumberDecimalSeparator;
                var o = new BezierSpline();
                var controlPoint1 = new Vec3F(1.1f, 2.2f, 3.3f);
                var controlPoint2 = new Vec3F(4.4f, 5.5f, 6.6f);
                var controlPoint3 = new Vec3F(7.7f, 8.8f, 9.9f);
                var incomingTangent = new Vec3F(-1.0f, -2.0f, -3.0f);
                var outgoingTangent = new Vec3F(1.0f, 2.0f, 3.0f);
                o.Add(new BezierPoint(controlPoint1, incomingTangent, outgoingTangent));
                o.Add(new BezierPoint(controlPoint2, incomingTangent, outgoingTangent));
                o.Add(new BezierPoint(controlPoint3, incomingTangent, outgoingTangent));

                string s = o.ToString(null, null);
                TestToStringResults(o, s, listSeparator, decimalSeparator);

                string s2 = o.ToString();
                Assert.AreEqual(s, s2);

                s = o.ToString("G", culture);
                TestToStringResults(o, s, listSeparator, decimalSeparator);

                s = o.ToString("R", culture);
                TestToStringResults(o, s, listSeparator, decimalSeparator);
            }
            finally
            {
                Thread.CurrentThread.CurrentCulture = originalCulture;
            }
        }
Beispiel #4
0
        /// <summary>
        /// Handles key-down 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 KeyDown(object sender, KeyEventArgs e)
        {
            m_keyMap[e.KeyValue] = true;

            // W A S D for forward, strafe left, backward, strafe right, is the default
            Vec3F dir = new Vec3F();
            if (m_keyMap[(int)CanvasControl3D.ControlScheme.Left1] ||
                m_keyMap[(int)CanvasControl3D.ControlScheme.Left2])
                dir = dir - Camera.Right;
            if (m_keyMap[(int)CanvasControl3D.ControlScheme.Right1] ||
                m_keyMap[(int)CanvasControl3D.ControlScheme.Right2]) 
                dir = dir + Camera.Right;
            if (m_keyMap[(int)CanvasControl3D.ControlScheme.Forward1] ||
                m_keyMap[(int)CanvasControl3D.ControlScheme.Forward2])
                dir = dir + Camera.LookAt;
            if (m_keyMap[(int)CanvasControl3D.ControlScheme.Back1] ||
                m_keyMap[(int)CanvasControl3D.ControlScheme.Back2])
                dir = dir - Camera.LookAt;

            bool handled = CanvasControl3D.ControlScheme.IsControllingCamera(Control.ModifierKeys, e);

            if (handled)
            {
                dir.Normalize();
                Vec3F p = Camera.Eye;
                float y = p.Y;
                p += dir * m_scale;
                p.Y = y;
                Camera.Set(p);
            }

            return handled;
        }
Beispiel #5
0
 /// <summary>
 /// Finds the intersection point of the ray with the given plane. Checks
 /// for the ray being parallel with the plane or the ray pointing away
 /// from the plane</summary>
 /// <param name="plane">Must be constructed "by the rules" of Plane3F</param>
 /// <param name="intersectionPoint">The resulting intersection point or
 /// the zero-point if there was no intersection</param>
 /// <returns>True if the ray points towards the plane and intersects it</returns>
 public bool IntersectPlane(Plane3F plane, out Vec3F intersectionPoint)
 {
     // both the normal and direction must be unit vectors.
     float cos = Vec3F.Dot(plane.Normal, Direction);
     if (Math.Abs(cos) > 0.0001f)
     {
         // dist > 0 means "on the same side as the normal", aka, "the front".
         float dist = plane.SignedDistance(Origin);
         // There are two cases for the ray shooting away from the plane:
         // 1. If the ray is in front of the plane and pointing away,
         //  then 'cos' and 'dist' are both > 0.
         // 2. If the ray is in back of the plane and pointing away,
         //  then 'cos' and 'dist' are both < 0.
         // So, if the signs are the same, then there's no intersection.
         // So, if 'cos' * 'dist' is positive, then there's no intersection.
         if (cos * dist < 0.0)
         {
             // There are two cases for the ray hitting the plane:
             // 1. Origin is behind the plane, so the ray and normal are aligned
             //  and 'dist' is < 0. We need to negate 'dist'.
             // 2. Origin is in front of the plane, so the ray needs to be negated
             //  so that cos(angle-180) is calculated. 'dist' is > 0.
             // Either way, we've got a -1 thrown into the mix. Tricky!
             float t = -dist / cos;
             intersectionPoint = Origin + (Direction * t);
             return true;
         }
     }
     intersectionPoint = new Vec3F(0, 0, 0);
     return false;
 }
Beispiel #6
0
        private void TestToStringWithCulture(CultureInfo culture)
        {
            CultureInfo originalCulture = Thread.CurrentThread.CurrentCulture;
            Thread.CurrentThread.CurrentCulture = culture;
            try
            {
                string listSeparator = culture.TextInfo.ListSeparator;
                string decimalSeparator = culture.NumberFormat.NumberDecimalSeparator;
                var corner1 = new Vec3F(1.1f, 2.2f, 3.3f);
                var corner2 = new Vec3F(4.4f, 5.5f, 6.6f);
                var o = new Box(corner1, corner2);

                string s = o.ToString(null, null);
                TestToStringResults(o, s, listSeparator, decimalSeparator);

                s = o.ToString("G", culture);
                TestToStringResults(o, s, listSeparator, decimalSeparator);

                s = o.ToString("R", culture);
                TestToStringResults(o, s, listSeparator, decimalSeparator);
            }
            finally
            {
                Thread.CurrentThread.CurrentCulture = originalCulture;
            }
        }
Beispiel #7
0
        private void TestToStringWithCulture(CultureInfo culture)
        {
            CultureInfo originalCulture = Thread.CurrentThread.CurrentCulture;
            Thread.CurrentThread.CurrentCulture = culture;
            try
            {
                string listSeparator = culture.TextInfo.ListSeparator;
                string decimalSeparator = culture.NumberFormat.NumberDecimalSeparator;
                var normal = new Vec3F(1.1f, 2.2f, 3.3f);
                normal.Normalize();
                var o = new Plane3F(normal, 4.4f);

                string s = o.ToString(null, null);
                TestToStringResults(o, s, listSeparator, decimalSeparator);

                string s2 = o.ToString();
                Assert.AreEqual(s, s2);

                s = o.ToString("G", culture);
                TestToStringResults(o, s, listSeparator, decimalSeparator);

                s = o.ToString("R", culture);
                TestToStringResults(o, s, listSeparator, decimalSeparator);
            }
            finally
            {
                Thread.CurrentThread.CurrentCulture = originalCulture;
            }
        }
Beispiel #8
0
 /// <summary>
 /// Snaps the given point to the nearest grid vertex</summary>
 /// <param name="pt">Point to snap, in world space</param>
 /// <returns>Point, from given point, snapped to grid, in world space</returns>
 public Vec3F SnapPoint(Vec3F pt)
 {
     float segment = Size / (float)Subdivisions;
     Vec3F snap = new Vec3F((int)(pt.X / segment), 0, (int)(pt.Z / segment));
     snap = snap * segment;
     snap.Y = Height;
     return snap;
 }
Beispiel #9
0
 /// <summary>
 /// Draws a colored line from point 1 to point 2</summary>
 /// <param name="p1">Point 1</param>
 /// <param name="p2">Point 2</param>        
 public static void DrawLine(Vec3F p1, Vec3F p2)
 {
     Gl.glBegin(Gl.GL_LINES);
     Gl.glVertex3d(p1.X, p1.Y, p1.Z);
     Gl.glVertex3d(p2.X, p2.Y, p2.Z);
     Gl.glEnd();
     Util3D.RenderStats.VertexCount += 2;
 }
Beispiel #10
0
 /// <summary>
 /// Constructs a plane from 3 non-linear points on the plane, such that
 /// Normal * p = Distance</summary>
 /// <param name="p1">First point</param>
 /// <param name="p2">Second point</param>
 /// <param name="p3">Third point</param>
 public Plane3F(Vec3F p1, Vec3F p2, Vec3F p3)
 {
     Vec3F d12 = p2 - p1;
     Vec3F d13 = p3 - p1;
     Vec3F normal = Vec3F.Cross(d12, d13);
     Normal = Vec3F.Normalize(normal);
     Distance = Vec3F.Dot(Normal, p1);
 }
Beispiel #11
0
 /// <summary>
 /// Decomposes the given matrix to translation, scale, 
 /// and rotation and set them to given Transformable node.        
 /// </summary>        
 public static void SetTransform(ITransformable xform, Matrix4F mtrx)
 {
     xform.Translation = mtrx.Translation;
     xform.Scale = mtrx.GetScale();
     Vec3F rot = new Vec3F();
     mtrx.GetEulerAngles(out rot.X, out rot.Y, out rot.Z);
     xform.Rotation = rot;
     xform.UpdateTransform();
 }
Beispiel #12
0
 /// <summary>
 /// Draws a colored line from point 1 to point 2</summary>
 /// <param name="p1">Point 1</param>
 /// <param name="p2">Point 2</param>
 /// <param name="color">Line color</param>
 public static void DrawLine(Vec3F p1, Vec3F p2, Color color)
 {
     Gl.glBegin(Gl.GL_LINES);
     Gl.glColor3ub(color.R, color.G, color.B);
     Gl.glVertex3d(p1.X, p1.Y, p1.Z);
     Gl.glVertex3d(p2.X, p2.Y, p2.Z);
     Gl.glEnd();
     Util3D.RenderStats.VertexCount += 2;
 }
Beispiel #13
0
        /// <summary>
        /// Evaluate the curve on parameter t [0,1]</summary>
        /// <param name="t">Parameter</param>
        /// <returns>Resulting 3D vector</returns>
        public Vec3F Evaluate(float t)
        {
            Vec3F result = new Vec3F();

            float tSquared = t * t;
            float tCubed = tSquared * t;

            result = (m_coefficients[0] * tCubed) + (m_coefficients[1] * tSquared) + (m_coefficients[2] * t) + m_ctrlPoints[0];
            return result;
        }
Beispiel #14
0
        // creates grid unit grid.
        public void CreateVertices()
        {
            DeleteVertexBuffer();

            IGrid grid = this.As<IGrid>();
            m_subDiv = grid.Subdivisions;
            float corner = 0.5f;                  // grid.Size / 2.0f;
            float step = 1.0f / (float)m_subDiv;   // grid.Size / (float)subDiv;

            int numLines = (m_subDiv + 1) * 2;
            int numVerts = numLines * 2;

            var vertices = new Vec3F[numVerts];

            int index = 0;
            float s = -corner;

            // Create vertical lines
            for (int i = 0; i <= m_subDiv; i++)
            {
                vertices[index] = new Vec3F(s, 0, corner);
                vertices[index + 1] = new Vec3F(s, 0, -corner);

                index += 2;
                s += step;
            }

            // Create horizontal lines
            s = -corner;
            for (int i = 0; i <= m_subDiv; i++)
            {
                vertices[index] = new Vec3F(corner, 0, s);
                vertices[index + 1] = new Vec3F(-corner, 0, s);

                index += 2;
                s += step;
            }

            m_gridVBId = GameEngine.CreateVertexBuffer(vertices);
            m_gridVertexCount = (uint)vertices.Length;

            {
                var vs = new VertexPC[6];
                vs[0] = new VertexPC(  0.0f,   0.0f,   0.0f, 0xff0000ff);
                vs[1] = new VertexPC(corner,   0.0f,   0.0f, 0xff0000ff);
                vs[2] = new VertexPC(  0.0f,   0.0f,   0.0f, 0xff00ff00);
                vs[3] = new VertexPC(  0.0f, corner,   0.0f, 0xff00ff00);
                vs[4] = new VertexPC(  0.0f,   0.0f,   0.0f, 0xffff0000);
                vs[5] = new VertexPC(  0.0f,   0.0f, corner, 0xffff0000);

                m_basisAxesVBId = GameEngine.CreateVertexBuffer(vs);
                m_basisAxesVertexCount = (uint)vs.Length;
            }
        }
Beispiel #15
0
        /// <summary>
        /// Construct a Bezier curve from 4 control points</summary>
        /// <param name="controlPoints">Array of control points</param>
        public BezierCurve(Vec3F[] controlPoints)
        {
            m_ctrlPoints = controlPoints;

            // Calcualte coefficients
            m_coefficients = new Vec3F[3];

            m_coefficients[2] = 3.0f * (m_ctrlPoints[1] - m_ctrlPoints[0]);
            m_coefficients[1] = 3.0f * (m_ctrlPoints[2] - m_ctrlPoints[1]) - m_coefficients[2];
            m_coefficients[0] = m_ctrlPoints[3] - m_ctrlPoints[0] - m_coefficients[2] - m_coefficients[1];
        }
Beispiel #16
0
        /// <summary>
        /// Gets the DomNode attribute as a Vec3F and returns true, or returns false if the attribute
        /// doesn't exist</summary>
        /// <param name="domNode">DomNode holding the attribute</param>
        /// <param name="attribute">Attribute of the DomNode that contains the data</param>
        /// <param name="result">The resulting Vec3F. Is (0,0,0) if the attribute couldn't be found</param>
        /// <returns>True iff the attribute was found and was converted to a Vec3F</returns>
        public static bool GetVector(DomNode domNode, AttributeInfo attribute, out Vec3F result)
        {
            float[] floats = domNode.GetAttribute(attribute) as float[];
            if (floats != null)
            {
                result = new Vec3F(floats);
                return true;
            }

            result = new Vec3F();
            return false;
        }
        public override void OnBeginDrag()
        {
            if (m_hitRegion == HitRegion.None || !CanManipulate(m_node))
                return;
            var transactionContext = DesignView.Context.As<ITransactionContext>();
            transactionContext.Begin("Move".Localize());
            m_originalPivot = m_node.Pivot;

            Path<DomNode> path = new Path<DomNode>(m_node.Cast<DomNode>().GetPath());
            Matrix4F localToWorld = TransformUtils.CalcPathTransform(path, path.Count - 1);
            m_worldToLocal = new Matrix4F();
            m_worldToLocal.Invert(localToWorld);
        }
Beispiel #18
0
        private void TestToStringResults(Vec3F o, string s, string listSeparator, string decimalSeparator)
        {
            string[] results = s.Split(new[] { listSeparator }, StringSplitOptions.RemoveEmptyEntries);
            Assert.AreEqual(results.Length, 3);
            foreach (string oneFloatString in results)
                Assert.True(oneFloatString.Contains(decimalSeparator));
            Assert.AreEqual(float.Parse(results[0]), o.X);
            Assert.AreEqual(float.Parse(results[1]), o.Y);
            Assert.AreEqual(float.Parse(results[2]), o.Z);

            Vec3F roundTrip = Vec3F.Parse(s);
            Assert.AreEqual(roundTrip.X, o.X);
            Assert.AreEqual(roundTrip.Y, o.Y);
            Assert.AreEqual(roundTrip.Z, o.Z);
        }
Beispiel #19
0
        public Point WorldToSurfaceSpace(Vec3F posW)
        {
            Point result = new Point();
            TerrainGob terrain = this.GetParentAs<TerrainGob>();
            ImageData hmImg = terrain.GetSurface();
            ImageData mpImg = GetSurface();
            Point posH = terrain.WorldToSurfaceSpace(posW);

            float dx = (float)mpImg.Width / (float)hmImg.Width;
            float dy = (float)mpImg.Height / (float)hmImg.Height;

            result.X = (int)Math.Round(posH.X * dx);
            result.Y = (int)Math.Round(posH.Y * dy);
            return result;
        }
Beispiel #20
0
        /// <summary>
        /// Draws a 3D arrow from point 1 to point 2 using an OpenGL display list for greatly improved
        /// performance. This method must not be called in between Gl.glNewList and Gl.glEndList.</summary>
        /// <param name="p1">Point 1</param>
        /// <param name="p2">Point 2</param>
        /// <param name="coneSize">Arrow head base diameter</param>
        public static void DrawArrowDisplayList(Vec3F p1, Vec3F p2, float coneSize)
        {
            Gl.glBegin(Gl.GL_LINES);
            Gl.glVertex3f(p1.X, p1.Y, p1.Z);
            Gl.glVertex3f(p2.X, p2.Y, p2.Z);
            Gl.glEnd();

            Gl.glPushMatrix();
            Gl.glTranslatef(p2.X, p2.Y, p2.Z);
            Gl.glPushMatrix();
            Util3D.glMultMatrixf(LookAtMatrix(p2 - p1));
            DrawConeDisplayList(coneSize, coneSize * 2, RenderStyle.Solid);
            Gl.glPopMatrix();
            Gl.glPopMatrix();
            Util3D.RenderStats.VertexCount += 2;
        }
Beispiel #21
0
        /// <summary>
        /// Sets this frustum to frustum represented by the given values</summary>
        /// <param name="fovY">Y field-of-view</param>
        /// <param name="aspectRatio">Aspect ration of frustum cross section</param>
        /// <param name="near">Near plane distance</param>
        /// <param name="far">Far plane distance</param>
        public void SetPerspective(float fovY, float aspectRatio, float near, float far)
        {
            float tanY = (float)Math.Tan((double)fovY / 2.0);
            float tanX = tanY * aspectRatio;
            Vec3F xAxis = new Vec3F(-1, 0, -tanX);
            Vec3F yAxis = new Vec3F(0, -1, -tanY);
            float nX = xAxis.Length;
            float nY = yAxis.Length;

            // The view coordinate system has +y pointing up, +x to the right, +z out of the screen.
            m_planes[iRight].Set(new Vec3F(-1, 0, -tanX) / nX, 0.0f);
            m_planes[iLeft].Set(new Vec3F(1, 0, -tanX) / nX, 0.0f);
            m_planes[iTop].Set(new Vec3F(0, -1, -tanY) / nY, 0.0f);
            m_planes[iBottom].Set(new Vec3F(0, 1, -tanY) / nY, 0.0f);
            m_planes[iNear].Set(new Vec3F(0, 0, -1), near);
            m_planes[iFar].Set(new Vec3F(0, 0, 1), -far);
        }
Beispiel #22
0
        /// <summary>
        /// Extends box to contain the given point, or if this box is uninitialized, the box is
        /// initialized from the point</summary>
        /// <param name="p">Point</param>
        /// <returns>Extended box</returns>
        public void Extend(Vec3F p)
        {
            if (m_initialized == false)
            {
                Min = Max = p;
                m_initialized = true;
            }
            else
            {
                Min.X = Math.Min(Min.X, p.X);
                Min.Y = Math.Min(Min.Y, p.Y);
                Min.Z = Math.Min(Min.Z, p.Z);

                Max.X = Math.Max(Max.X, p.X);
                Max.Y = Math.Max(Max.Y, p.Y);
                Max.Z = Math.Max(Max.Z, p.Z);
            }
        }
Beispiel #23
0
        /// <summary>
        /// Handles mouse-down 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 MouseDown(object sender, MouseEventArgs e)
        {
            if (InputScheme.ActiveControlScheme.IsControllingCamera(Control.ModifierKeys, e))
            {
                m_lastMousePoint = e.Location;
                m_dragging = true;

                Control c = sender as Control;
                m_width = c.Width;
                m_height = c.Height;

                // get initial rotation
                m_firstPoint = ProjectToArcball(m_lastMousePoint);

                return true;
            }

            return base.MouseDown(sender, e);
        }
Beispiel #24
0
 /// <summary>
 /// Gets all the data required to completely represent this camera's state, so that it can
 /// later be restored by calling SetState(). Note that the aspect ratio is not saved and
 /// restored, because it should be set depending on the aspect ratio of the viewport; it would
 /// be wrong to restore the camera's aspect ratio after the user has resized the window, for example.</summary>
 /// <param name="perspective">Camera view type</param>
 /// <param name="eye">Eye point in "world view" space</param>
 /// <param name="lookAtPoint">Camera look-at point in "world view" space</param>
 /// <param name="upVector">Camera up direction in "world view" space</param>
 /// <param name="yFov">Y-field-of-view in radians</param>
 /// <param name="nearZ">Current near plane distance value for the current projection type</param>
 /// <param name="farZ">Current far plane distance value for the current projection type</param>
 /// <param name="focusRadius">Focus radius around the "look at" point</param>
 public void GetState(
     out ViewTypes perspective,
     out Vec3F eye,
     out Vec3F lookAtPoint,
     out Vec3F upVector,
     out float yFov,
     out float nearZ,
     out float farZ,
     out float focusRadius)
 {
     perspective = m_viewType;
     eye = Eye;
     lookAtPoint = LookAtPoint;
     upVector = Up;
     yFov = YFov;
     nearZ = NearZ;
     farZ = FarZ;
     focusRadius = FocusRadius;
 }
Beispiel #25
0
 /// <summary>
 /// Calculates required scale such that when it applied to an 
 /// object. The object maintain a constant size in pixel regardless of 
 /// its distance from camera.
 /// Used for computing size of 3d manipulators.</summary>
 /// <param name="camera"></param>
 /// <param name="objectPosW"></param>
 /// <param name="sizeInPixels"></param>
 /// <param name="viewHeight"></param>        
 public static float CalcAxisScale(Camera camera,
     Vec3F objectPosW,
     float sizeInPixels,
     float viewHeight)
 {
     float worldHeight;
     // World height on origin's z value
     if (camera.Frustum.IsOrtho)
     {
         worldHeight = (camera.Frustum.Top - camera.Frustum.Bottom);
     }
     else
     {
         Matrix4F view = camera.ViewMatrix;
         Vec3F objPosV;
         view.Transform(objectPosW, out objPosV);
         worldHeight = 2.0f * Math.Abs(objPosV.Z) * (float)Math.Tan(camera.Frustum.FovY / 2.0f);
     }
     return sizeInPixels * (worldHeight / viewHeight);
 }
Beispiel #26
0
        public IControlPoint InsertPoint(uint index, float x, float y, float z)
        {            
            IControlPoint cpt = CreateControlPoint();
            int numSteps = GetAttribute<int>(Schema.curveType.stepsAttribute);
            int interpolationType = GetAttribute<int>(Schema.curveType.interpolationTypeAttribute);            
            if (interpolationType != 0 && numSteps > 0)
            {
                index = index / (uint)numSteps;
            }


            Path<DomNode> path = new Path<DomNode>(DomNode.GetPath());
            Matrix4F toworld = TransformUtils.CalcPathTransform(path, path.Count - 1);
            Matrix4F worldToLocal = new Matrix4F();
            worldToLocal.Invert(toworld);
            Vec3F pos = new Vec3F(x, y, z);
            worldToLocal.Transform(ref pos);
            cpt.Translation = pos;
            ControlPoints.Insert((int)index + 1, cpt);
            return cpt;
        }
Beispiel #27
0
        private static float CalcAngle(Vec3F v0, Vec3F v1, Vec3F axis, float snapAngle)
        {
            const float twoPi = (float)(2.0 * Math.PI);
            float       angle = Vec3F.Dot(v0, v1);

            if (angle > 1.0f)
            {
                angle = 1.0f;
            }
            else if (angle <= -1.0f)
            {
                angle = 1.0f;
            }
            angle = (float)Math.Acos(angle);

            // Check if v0 is left of v1
            Vec3F cross = Vec3F.Cross(v0, v1);

            if (Vec3F.Dot(cross, axis) < 0)
            {
                angle = twoPi - angle;
            }
            // round to nearest multiple of preference
            if (snapAngle > 0)
            {
                if (angle >= 0)
                {
                    int n = (int)((angle + snapAngle * 0.5f) / snapAngle);
                    angle = n * snapAngle;
                }
                else
                {
                    int n = (int)((angle - snapAngle * 0.5f) / snapAngle);
                    angle = n * snapAngle;
                }
            }
            // const float epsilone = (float)1e-7;
            // if (twoPi - angle <= epsilone) angle = 0.0f;
            return(angle);
        }
Beispiel #28
0
        /// <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 #29
0
        private static float CalcAngle(Vec3F v0, Vec3F v1, Vec3F axis, float snapAngle)
        {
            float angle = Vec3F.Dot(v0, v1);

            if (angle > 1.0f)
            {
                angle = 1.0f;
            }
            else if (angle < -1.0f)
            {
                angle = 1.0f;
            }
            angle = (float)Math.Acos(angle);

            // Check if v0 is left of v1
            Vec3F cross = Vec3F.Cross(v0, v1);

            if (Vec3F.Dot(cross, axis) < 0)
            {
                angle = -angle;
            }

            // round to nearest multiple of preference
            if (snapAngle > 0)
            {
                if (angle >= 0)
                {
                    int n = (int)((angle + snapAngle * 0.5) / snapAngle);
                    angle = n * snapAngle;
                }
                else
                {
                    int n = (int)((angle - snapAngle * 0.5) / snapAngle);
                    angle = n * snapAngle;
                }
            }

            return(angle);
        }
Beispiel #30
0
        /// <summary>
        /// Sets this cammera's state completely. Complements GetState().</summary>
        /// <param name="root">The XML element containing the state of a camera</param>
        /// <param name="xmlDoc">The XML document that owns 'root'</param>
        public void SetState(XmlElement root, XmlDocument xmlDoc)
        {
            ViewTypes viewType;
            Vec3F     eye;
            Vec3F     lookAtPoint;
            Vec3F     upVector;
            float     yFov;
            float     nearZ;
            float     farZ;
            float     focusRadius;

            string value;

            value    = root.GetAttribute("viewType");
            viewType = (ViewTypes)int.Parse(value, NumberStyles.AllowHexSpecifier);

            value = root.GetAttribute("eye");
            eye   = Vec3F.Parse(value);

            value       = root.GetAttribute("lookAtPoint");
            lookAtPoint = Vec3F.Parse(value);

            value    = root.GetAttribute("upVector");
            upVector = Vec3F.Parse(value);

            value = root.GetAttribute("yFov");
            yFov  = float.Parse(value);

            value = root.GetAttribute("nearZ");
            nearZ = float.Parse(value);

            value = root.GetAttribute("farZ");
            farZ  = float.Parse(value);

            value       = root.GetAttribute("focusRadius");
            focusRadius = float.Parse(value);

            SetState(viewType, eye, lookAtPoint, upVector, yFov, nearZ, farZ, focusRadius);
        }
Beispiel #31
0
        public override void OnEndDrag(ViewControl vc, Point scrPt)
        {
            if (NodeList.Count > 0)
            {
                for (int k = 0; k < NodeList.Count; k++)
                {
                    IManipulatorNotify notifier = NodeList[k].As <IManipulatorNotify>();
                    if (notifier != null)
                    {
                        notifier.OnEndDrag();
                    }
                }
                var transactionContext = DesignView.Context.As <ITransactionContext>();
                try
                {
                    if (transactionContext.InTransaction)
                    {
                        transactionContext.End();
                    }
                }
                catch (InvalidTransactionException ex)
                {
                    if (transactionContext.InTransaction)
                    {
                        transactionContext.Cancel();
                    }

                    if (ex.ReportError)
                    {
                        Outputs.WriteLine(OutputMessageType.Error, ex.Message);
                    }
                }
            }

            NodeList.Clear();
            m_originalValues = null;
            m_hitRegion      = HitRegion.None;
            m_scale          = new Vec3F(1, 1, 1);
        }
Beispiel #32
0
        /// <summary>
        /// Handles key-down 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 KeyDown(object sender, KeyEventArgs e)
        {
            m_keyMap[e.KeyValue] = true;

            // W A S D for forward, strafe left, backward, strafe right, is the default
            Vec3F dir = new Vec3F();

            if (m_keyMap[(int)CanvasControl3D.ControlScheme.Left1] ||
                m_keyMap[(int)CanvasControl3D.ControlScheme.Left2])
            {
                dir = dir - Camera.Right;
            }
            if (m_keyMap[(int)CanvasControl3D.ControlScheme.Right1] ||
                m_keyMap[(int)CanvasControl3D.ControlScheme.Right2])
            {
                dir = dir + Camera.Right;
            }
            if (m_keyMap[(int)CanvasControl3D.ControlScheme.Forward1] ||
                m_keyMap[(int)CanvasControl3D.ControlScheme.Forward2])
            {
                dir = dir + Camera.LookAt;
            }
            if (m_keyMap[(int)CanvasControl3D.ControlScheme.Back1] ||
                m_keyMap[(int)CanvasControl3D.ControlScheme.Back2])
            {
                dir = dir - Camera.LookAt;
            }

            bool handled = CanvasControl3D.ControlScheme.IsControllingCamera(Control.ModifierKeys, e);


            if (handled)
            {
                dir.Normalize();
                Camera.Set(Camera.Eye + dir * m_scale);
            }

            return(handled);
        }
Beispiel #33
0
        private void UpdateGeometry()
        {
            // create orthornormal basis from lookAt and up vectors
            m_lookAt = m_lookAtPoint - m_eye;
            m_lookAt.Normalize();

            m_right = Vec3F.Cross(m_lookAt, m_up);
            m_right.Normalize();

            m_up = Vec3F.Cross(m_right, m_lookAt);
            //m_up.Normalize(); // m_right is already unit length

            m_lookAtDistance = Vec3F.Distance(m_eye, m_lookAtPoint);

            if (ProjectionType == ProjectionType.Orthographic)
            {
                SetOrthographic(m_lookAtDistance);
            }
            else
            {
                OnCameraChanged(EventArgs.Empty);
            }
        }
Beispiel #34
0
 /// <summary>
 /// Sets this cammera's state completely. Complements GetState().</summary>
 /// <param name="viewType">Camera view type</param>
 /// <param name="eye">Eye point in "world view" space</param>
 /// <param name="lookAtPoint">Camera look-at point in "world view" space</param>
 /// <param name="upVector">Camera up direction in "world view" space</param>
 /// <param name="yFov">Y-field-of-view in radians</param>
 /// <param name="nearZ">Current near plane distance value for the current projection type</param>
 /// <param name="farZ">Current far plane distance value for the current projection type</param>
 /// <param name="focusRadius">Focus radius around the "look at" point</param>
 public void SetState(
     ViewTypes viewType,
     Vec3F eye,
     Vec3F lookAtPoint,
     Vec3F upVector,
     float yFov,
     float nearZ,
     float farZ,
     float focusRadius)
 {
     // to avoid duplicate camera events, let's batch up all the changes.
     m_changingCamera = true;
     try
     {
         m_viewType = viewType;
         Set(eye, lookAtPoint, upVector);
         if (viewType == ViewTypes.Perspective)
         {
             SetPerspective(yFov, m_aspectRatio, nearZ, farZ);
         }
         else
         {
             float d = DistanceFromLookAt;
             SetOrthographic(d * m_aspectRatio / 2,
                             -d * m_aspectRatio / 2,
                             d / 2,
                             -d / 2,
                             nearZ,
                             farZ);
         }
     }
     finally
     {
         m_changingCamera = false;
     }
     OnCameraChanged(EventArgs.Empty);
 }
        public override bool Pick(ViewControl vc, Point scrPt)
        {
            m_hitRegion = HitRegion.None;
            if (base.Pick(vc, scrPt) == false)
                return false;

            Camera camera = vc.Camera;
            
            Matrix4F view = camera.ViewMatrix;
            Matrix4F vp = view  * camera.ProjectionMatrix;
            Matrix4F wvp = HitMatrix * vp;
            
            Ray3F rayL = vc.GetRay(scrPt,wvp);

            float s = Util.CalcAxisScale(vc.Camera, HitMatrix.Translation, AxisLength, vc.Height);

                // There's only one hot-spot for this manipulator:
                //      a square at the manipulator origin.
            Vec3F min = new Vec3F(-0.5f, -0.5f, -0.5f);
            Vec3F max = new Vec3F(0.5f, 0.5f, 0.5f);
            AABB box = new AABB(min, max);

            float centerCubeScale = s * CenterCubeSize;
            Matrix4F centerCubeXform = new Matrix4F();
            centerCubeXform.Scale(centerCubeScale);
            centerCubeXform.Invert(centerCubeXform);
            Ray3F ray = rayL;
            ray.Transform(centerCubeXform);
            if (box.Intersect(ray))
            {
                m_hitRegion = HitRegion.XYSquare;
                return true;
            }

            m_hitRegion = HitRegion.None;
            return false;
        }
        /// <summary>
        /// Synchronizes the camera to the controller's current state</summary>
        /// <param name="camera">Camera</param>
        protected override void ControllerToCamera(Camera camera)
        {
            Vec3F lookAt = camera.LookAt;
            Vec3F right  = camera.Right;
            Vec3F up     = camera.Up;

            if (camera.ViewType == ViewTypes.Perspective)
            {
                Camera.PerspectiveNearZ = CalculatePerspectiveNearZ();

                // override the camera's frame of reference
                float sinPhi   = (float)Math.Sin(m_elevation);
                float cosPhi   = (float)Math.Cos(m_elevation);
                float sinTheta = (float)Math.Sin(m_azimuth);
                float cosTheta = (float)Math.Cos(m_azimuth);

                lookAt = new Vec3F(-cosPhi * sinTheta, -sinPhi, -cosPhi * cosTheta);
                right  = new Vec3F(cosTheta, 0, -sinTheta);
                up     = Vec3F.Cross(right, lookAt); // TODO compute from sin/cos values
            }

            float lookAtOffset = 0;

            if (m_distanceFromLookAt < m_dollyThreshold) // do we need to start dollying?
            {
                lookAtOffset = m_distanceFromLookAt - m_dollyThreshold;
            }

            float eyeOffset = m_distanceFromLookAt;

            Camera.Set(
                m_lookAtPoint - (eyeOffset * lookAt),       // eye point
                m_lookAtPoint - (lookAtOffset * lookAt),    // look-at point
                up);                                        // up vector

            base.ControllerToCamera(camera);
        }
Beispiel #37
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 #38
0
        public override void Render(ViewControl vc)
        {
            Matrix4F normWorld = GetManipulatorMatrix();

            if (normWorld == null)
            {
                return;
            }

            Util3D.RenderFlag = BasicRendererFlags.WireFrame | BasicRendererFlags.DisableDepthTest;
            Color xcolor = (m_hitRegion == HitRegion.XAxis) ? Color.LightSalmon : Color.Red;
            Color ycolor = (m_hitRegion == HitRegion.YAxis) ? Color.LightGreen : Color.Green;
            Color Zcolor = (m_hitRegion == HitRegion.ZAxis) ? Color.LightBlue : Color.Blue;

            float s;

            Util.CalcAxisLengths(vc.Camera, normWorld.Translation, out s);
            Vec3F axScale = new Vec3F(s, s, s);

            Matrix4F scale = new Matrix4F();

            scale.Scale(axScale);
            Matrix4F xform = scale * normWorld;

            Util3D.DrawCircle(xform, Zcolor);

            Matrix4F rot = new Matrix4F();

            rot.RotY(MathHelper.PiOver2);
            xform = scale * rot * normWorld;
            Util3D.DrawCircle(xform, xcolor);

            rot.RotX(MathHelper.PiOver2);
            xform = scale * rot * normWorld;
            Util3D.DrawCircle(xform, ycolor);
        }
Beispiel #39
0
        /// <summary>
        /// Intersects the specified client point with the scene, knowing that the given
        /// HitRecords were the result of having called Dispatch with these same client points</summary>
        /// <param name="x">Client x coordinate</param>
        /// <param name="y">Client y coordinate</param>
        /// <param name="hits">The hits</param>
        /// <param name="pt">The intersection point</param>
        /// <param name="surfaceNormal">The surface normal of the target object at the intersection
        /// point, or the zero vector if the surface normal could not be found. Check against
        /// Vec3F.ZeroVector before using.</param>
        /// <returns>True iff client point intersects scene</returns>
        protected bool Intersect(int x, int y, HitRecord[] hits, ref Vec3F pt, out Vec3F surfaceNormal)
        {
            surfaceNormal = new Vec3F();

            if (hits.Length == 0)
            {
                return(false);
            }

            HitRecord hit = hits[0];

            if (hit.HasNormal)
            {
                surfaceNormal = hit.Normal;
            }

            if (hit.HasWorldIntersection)
            {
                pt = hit.WorldIntersection;
                return(true);
            }

            return(false);
        }
Beispiel #40
0
        public override void OnBeginDrag()
        {
            if (m_hitRegion == HitRegion.None)
                return;

            m_cancelDrag = false;
            Clear(); // cached values.

            var op = new ManipulatorActiveOperation(
                "Move", DesignView.Context.As<ISelectionContext>(),
                (ITransformable node) => (node.TransformationType & TransformationTypes.Translation) != 0,
                Control.ModifierKeys == m_duplicateKey);

            m_originalValues = new Vec3F[op.NodeList.Count];
            m_originalRotations = new Vec3F[op.NodeList.Count];
            for (int k = 0; k < op.NodeList.Count; k++)
            {
                ITransformable node = op.NodeList[k];
                m_originalValues[k] = node.Translation;
                m_originalRotations[k] = node.Rotation;
            }

            m_activeOp = op;
        }
Beispiel #41
0
        private void TestToStringWithCulture(CultureInfo culture)
        {
            CultureInfo originalCulture = Thread.CurrentThread.CurrentCulture;

            Thread.CurrentThread.CurrentCulture = culture;
            try
            {
                string listSeparator    = culture.TextInfo.ListSeparator;
                string decimalSeparator = culture.NumberFormat.NumberDecimalSeparator;
                var    o               = new BezierSpline();
                var    controlPoint1   = new Vec3F(1.1f, 2.2f, 3.3f);
                var    controlPoint2   = new Vec3F(4.4f, 5.5f, 6.6f);
                var    controlPoint3   = new Vec3F(7.7f, 8.8f, 9.9f);
                var    incomingTangent = new Vec3F(-1.0f, -2.0f, -3.0f);
                var    outgoingTangent = new Vec3F(1.0f, 2.0f, 3.0f);
                o.Add(new BezierPoint(controlPoint1, incomingTangent, outgoingTangent));
                o.Add(new BezierPoint(controlPoint2, incomingTangent, outgoingTangent));
                o.Add(new BezierPoint(controlPoint3, incomingTangent, outgoingTangent));

                string s = o.ToString(null, null);
                TestToStringResults(o, s, listSeparator, decimalSeparator);

                string s2 = o.ToString();
                Assert.AreEqual(s, s2);

                s = o.ToString("G", culture);
                TestToStringResults(o, s, listSeparator, decimalSeparator);

                s = o.ToString("R", culture);
                TestToStringResults(o, s, listSeparator, decimalSeparator);
            }
            finally
            {
                Thread.CurrentThread.CurrentCulture = originalCulture;
            }
        }
Beispiel #42
0
        public IControlPoint InsertPoint(uint index, float x, float y, float z)
        {
            IControlPoint cpt               = CreateControlPoint();
            int           numSteps          = GetAttribute <int>(Schema.curveType.stepsAttribute);
            int           interpolationType = GetAttribute <int>(Schema.curveType.interpolationTypeAttribute);

            if (interpolationType != 0 && numSteps > 0)
            {
                index = index / (uint)numSteps;
            }


            Path <DomNode> path         = new Path <DomNode>(DomNode.GetPath());
            Matrix4F       toworld      = TransformUtils.CalcPathTransform(path, path.Count - 1);
            Matrix4F       worldToLocal = new Matrix4F();

            worldToLocal.Invert(toworld);
            Vec3F pos = new Vec3F(x, y, z);

            worldToLocal.Transform(ref pos);
            cpt.Translation = pos;
            ControlPoints.Insert((int)index + 1, cpt);
            return(cpt);
        }
Beispiel #43
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 #44
0
        /// <summary>
        /// Creates Billboard matrix from the given parameters.</summary>
        public static void CreateBillboard(Matrix4F matrix, Vec3F objectPos, Vec3F camPos, Vec3F camUp, Vector3 camLook)
        {
            Vector3 look = objectPos - camPos;
            float   len  = look.LengthSquared;

            if (len < 0.0001f)
            {
                look = -camLook;
            }
            else
            {
                look.Normalize();
            }

            Vector3 right = Vec3F.Cross(camUp, look);

            right.Normalize();
            Vector3 up = Vec3F.Cross(look, right);

            matrix.M11 = right.X;
            matrix.M12 = right.Y;
            matrix.M13 = right.Z;
            matrix.M14 = 0f;
            matrix.M21 = up.X;
            matrix.M22 = up.Y;
            matrix.M23 = up.Z;
            matrix.M24 = 0f;
            matrix.M31 = look.X;
            matrix.M32 = look.Y;
            matrix.M33 = look.Z;
            matrix.M34 = 0f;
            matrix.M41 = objectPos.X;
            matrix.M42 = objectPos.Y;
            matrix.M43 = objectPos.Z;
            matrix.M44 = 1f;
        }
        private Vec3F ProjectToArcball(Point point)
        {
            float x = (float)point.X / (m_width / 2);    // Scale so bounds map to [0,0] - [2,2]
            float y = (float)point.Y / (m_height / 2);

            x = x - 1;                           // Translate 0,0 to the center
            y = 1 - y;                           // Flip so +Y is up
            if (x < -1)
                x = -1;
            else if (x > 1)
                x = 1;
            if (y < -1)
                y = -1;
            else if (y > 1)
                y = 1;

            float z2 = 1 - x * x - y * y;       // z^2 = 1 - x^2 - y^2
            float z = z2 > 0 ? (float)Math.Sqrt(z2) : 0;

            Vec3F p = new Vec3F(x, y, z);
            p.Normalize();

            return p;
        }
        /// <summary>
        /// Synchronizes the camera to the controller's current state</summary>
        /// <param name="camera">Camera</param>
        protected override void ControllerToCamera(Camera camera)
        {
            Vec3F lookAt = Camera.LookAt;
            Vec3F up = Camera.Up;
            if (camera.ViewType == ViewTypes.Perspective)
            {
                
                QuatF rotation = m_rotation * m_currentRotation;
                rotation = rotation.Inverse;
                Matrix4F transform = new Matrix4F(rotation);

                lookAt = new Vec3F(0, 0, -1);
                up = new Vec3F(0, 1, 0);
                transform.Transform(ref lookAt);
                transform.Transform(ref up);
            }

            float eyeOffset = m_distanceFromLookAt;
            float lookAtOffset = 0;
            if (m_distanceFromLookAt < m_dollyThreshold) // do we need to start dollying?
            {
                eyeOffset = m_distanceFromLookAt;
                lookAtOffset = m_distanceFromLookAt - m_dollyThreshold;
            }

            Camera.Set(
                m_lookAtPoint - (eyeOffset * lookAt),       // eye
                m_lookAtPoint - (lookAtOffset * lookAt),    // lookAt
                up);                                        // up

            base.ControllerToCamera(camera);
        }
        private bool CalculateTerrainIntersection(ViewControl vc, Ray3F ray, GUILayer.IntersectionTestSceneWrapper testScene, out Vec3F result)
        {
            var nativeVC = vc as NativeDesignControl;

            if (nativeVC == null)
            {
                result = Vec3F.ZeroVector; return(false);
            }

            var pick = XLEBridgeUtils.Picking.RayPick(nativeVC.Adapter, ray, XLEBridgeUtils.Picking.Flags.Terrain);

            if (pick != null && pick.Length > 0)
            {
                result = pick[0].hitPt;
                return(true);
            }

            result = Vec3F.ZeroVector;
            return(false);
        }
Beispiel #48
0
        public Entity Spawn(UpperString type, Vec3F position, BitAngle angle = default)
        {
            ActorDefinition definition = DecorateManager.Find(type);

            return(Spawn(definition, position, angle));
        }
Beispiel #49
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);
                }
            }
        }
        public override void OnBeginDrag()
        {
            if (m_hitRegion == HitRegion.None)
            {
                return;
            }

            m_cancelDrag = false;
            Clear(); // cached values.

            var selectionContext   = DesignView.Context.As <ISelectionContext>();
            var selection          = selectionContext.Selection;
            var transactionContext = DesignView.Context.As <ITransactionContext>();

            IEnumerable <DomNode> rootDomNodes = DomNode.GetRoots(selection.AsIEnumerable <DomNode>());

            m_duplicating = Control.ModifierKeys == m_duplicateKey;

            if (m_duplicating)
            {
                List <DomNode> originals = new List <DomNode>();
                foreach (DomNode node in rootDomNodes)
                {
                    ITransformable transformable = node.As <ITransformable>();
                    if (!CanManipulate(transformable))
                    {
                        continue;
                    }

                    originals.Add(node);
                }
                if (originals.Count > 0)
                {
                    DomNode[] copies = DomNode.Copy(originals);

                    transactionContext.Begin("Copy And Move".Localize());

                    List <object> newSelection = new List <object>();
                    // re-parent copy
                    for (int i = 0; i < copies.Length; i++)
                    {
                        DomNode copy     = copies[i];
                        DomNode original = originals[i];

                        ChildInfo chInfo = original.ChildInfo;
                        if (chInfo.IsList)
                        {
                            original.Parent.GetChildList(chInfo).Add(copy);
                        }
                        else
                        {
                            original.Parent.SetChild(chInfo, copy);
                        }

                        newSelection.Add(Util.AdaptDomPath(copy));
                        copy.InitializeExtensions();
                    }

                    selectionContext.SetRange(newSelection);
                    NodeList.AddRange(copies.AsIEnumerable <ITransformable>());
                }
            }
            else
            {
                foreach (DomNode node in rootDomNodes)
                {
                    ITransformable transformable = node.As <ITransformable>();
                    if (!CanManipulate(transformable))
                    {
                        continue;
                    }
                    NodeList.Add(transformable);
                }

                if (NodeList.Count > 0)
                {
                    transactionContext.Begin("Move".Localize());
                }
            }

            m_originalValues    = new Vec3F[NodeList.Count];
            m_originalRotations = new Vec3F[NodeList.Count];
            for (int k = 0; k < NodeList.Count; k++)
            {
                ITransformable     node     = NodeList[k];
                IManipulatorNotify notifier = node.As <IManipulatorNotify>();
                if (notifier != null)
                {
                    notifier.OnBeginDrag();
                }
                m_originalValues[k]    = node.Translation;
                m_originalRotations[k] = node.Rotation;
            }
        }
        public override void OnDragging(ViewControl vc, Point scrPt)
        {
            if (m_cancelDrag || m_hitRegion == HitRegion.None || NodeList.Count == 0)
            {
                return;
            }

            bool hitAxis = m_hitRegion == HitRegion.XAxis ||
                           m_hitRegion == HitRegion.YAxis ||
                           m_hitRegion == HitRegion.ZAxis;


            Matrix4F view = vc.Camera.ViewMatrix;
            Matrix4F proj = vc.Camera.ProjectionMatrix;
            Matrix4F vp   = view * proj;

            // create ray in world space.
            Ray3F rayW = vc.GetRay(scrPt, vp);

            // create ray in view space.
            Ray3F rayV      = vc.GetRay(scrPt, proj);
            Vec3F translate = m_translatorControl.OnDragging(rayV);

            ISnapSettings snapSettings = (ISnapSettings)DesignView;
            bool          snapToGeom   = Control.ModifierKeys == m_snapGeometryKey;

            if (snapToGeom)
            {
                Vec3F manipPos = HitMatrix.Translation;
                Vec3F manipMove;
                if (hitAxis)
                {
                    //Make rayw to point toward moving axis and starting
                    // from manipulator’s world position.
                    rayW.Direction = Vec3F.Normalize(translate);
                    rayW.Origin    = manipPos;
                    manipMove      = Vec3F.ZeroVector;
                    m_cancelDrag   = true; //stop further snap-to's
                }
                else
                {
                    manipMove = rayW.ProjectPoint(manipPos) - manipPos;
                }

                for (int i = 0; i < NodeList.Count; i++)
                {
                    ITransformable node               = NodeList[i];
                    Vec3F          snapOffset         = TransformUtils.CalcSnapFromOffset(node, snapSettings.SnapFrom);
                    Path <DomNode> path               = new Path <DomNode>(Adapters.Cast <DomNode>(node).GetPath());
                    Matrix4F       parentLocalToWorld = TransformUtils.CalcPathTransform(path, path.Count - 2);
                    Vec3F          orgPosW;
                    parentLocalToWorld.Transform(m_originalValues[i], out orgPosW);

                    Matrix4F parentWorldToLocal = new Matrix4F();
                    parentWorldToLocal.Invert(parentLocalToWorld);

                    rayW.MoveToIncludePoint(orgPosW + snapOffset + manipMove);

                    HitRecord[] hits    = GameEngine.RayPick(view, proj, rayW, true);
                    bool        cansnap = false;
                    HitRecord   target  = new HitRecord();
                    if (hits.Length > 0)
                    {
                        // find hit record.
                        foreach (var hit in hits)
                        {
                            if (m_snapFilter.CanSnapTo(node, GameEngine.GetAdapterFromId(hit.instanceId)))
                            {
                                target  = hit;
                                cansnap = true;
                                break;
                            }
                        }
                    }

                    if (cansnap)
                    {
                        Vec3F pos;
                        if (target.hasNearestVert && snapSettings.SnapVertex)
                        {
                            pos = target.nearestVertex;
                        }
                        else
                        {
                            pos = target.hitPt;
                        }

                        pos -= snapOffset;
                        parentWorldToLocal.Transform(ref pos);
                        Vec3F diff = pos - node.Transform.Translation;
                        node.Translation += diff;
                        bool rotateOnSnap = snapSettings.RotateOnSnap &&
                                            target.hasNormal &&
                                            (node.TransformationType & TransformationTypes.Rotation) != 0;
                        if (rotateOnSnap)
                        {
                            Vec3F localSurfaceNormal;
                            parentWorldToLocal.TransformNormal(target.normal, out localSurfaceNormal);
                            node.Rotation = TransformUtils.RotateToVector(
                                m_originalRotations[i],
                                localSurfaceNormal,
                                AxisSystemType.YIsUp);
                        }
                    }
                }
            }
            else
            {
                IGrid grid       = DesignView.Context.Cast <IGame>().Grid;
                bool  snapToGrid = Control.ModifierKeys == m_snapGridKey &&
                                   grid.Visible &&
                                   vc.Camera.ViewType == ViewTypes.Perspective;
                float gridHeight = grid.Height;
                // translate.
                for (int i = 0; i < NodeList.Count; i++)
                {
                    ITransformable node = NodeList[i];
                    Path <DomNode> path = new Path <DomNode>(Adapters.Cast <DomNode>(node).GetPath());
                    Matrix4F       parentLocalToWorld = TransformUtils.CalcPathTransform(path, path.Count - 2);
                    Matrix4F       parentWorldToLocal = new Matrix4F();
                    parentWorldToLocal.Invert(parentLocalToWorld);
                    Vec3F localTranslation;
                    parentWorldToLocal.TransformVector(translate, out localTranslation);
                    Vec3F trans = m_originalValues[i] + localTranslation;

                    if (snapToGrid)
                    {
                        if (grid.Snap)
                        {
                            trans = grid.SnapPoint(trans);
                        }
                        else
                        {
                            trans.Y = gridHeight;
                        }
                    }

                    node.Translation = trans;
                }
            }
        }
Beispiel #52
0
        public override void Render(ViewControl vc)
        {
            BasicRendererFlags solid = BasicRendererFlags.Solid
                                       | BasicRendererFlags.DisableDepthTest;
            BasicRendererFlags wire = BasicRendererFlags.WireFrame
                                      | BasicRendererFlags.DisableDepthTest;

            Matrix4F normWorld = GetManipulatorMatrix();

            if (normWorld == null)
            {
                return;
            }
            Camera camera = vc.Camera;

            int axis = (int)m_hitRegion;

            // axis colors
            Color saveColor = m_axisColor[axis];

            m_axisColor[axis] = m_highlightColor;
            Color xcolor  = m_axisColor[(int)HitRegion.XAxis];
            Color ycolor  = m_axisColor[(int)HitRegion.YAxis];
            Color zcolor  = m_axisColor[(int)HitRegion.ZAxis];
            Color nxcolor = m_axisColor[(int)HitRegion.NegXAxis];
            Color nycolor = m_axisColor[(int)HitRegion.NegYAxis];
            Color nzcolor = m_axisColor[(int)HitRegion.NegZAxis];

            m_axisColor[axis] = saveColor;

            Vec3F deltaTrans = Vec3F.ZeroVector;

            if (m_hitRegion != HitRegion.None)
            {
                normWorld.Translation = HitMatrix.Translation;
            }

            Vec3F pos = normWorld.Translation;
            float s;

            Util.CalcAxisLengths(vc.Camera, pos, out s);

            Vec3F sv           = new Vec3F(s, s, s);
            Vec3F axscale      = new Vec3F(s, s, s);
            Vec3F negAxscale   = new Vec3F(-s, -s, -s);
            bool  negativeAxis = m_hitRegion == HitRegion.NegXAxis || m_hitRegion == HitRegion.NegYAxis || m_hitRegion == HitRegion.NegZAxis;

            if (negativeAxis)
            {
                negAxscale.X *= Math.Abs(m_scale.X);
                negAxscale.Y *= Math.Abs(m_scale.Y);
                negAxscale.Z *= Math.Abs(m_scale.Z);
            }
            else
            {
                axscale.X *= Math.Abs(m_scale.X);
                axscale.Y *= Math.Abs(m_scale.Y);
                axscale.Z *= Math.Abs(m_scale.Z);
            }

            Matrix4F scale = new Matrix4F();

            scale.Scale(axscale);
            Matrix4F xform = scale * normWorld;

            Util3D.RenderFlag = wire;

            Util3D.DrawX(xform, xcolor);
            Util3D.DrawY(xform, ycolor);
            Util3D.DrawZ(xform, zcolor);

            scale.Scale(negAxscale);
            xform = scale * normWorld;

            Util3D.DrawX(xform, nxcolor);
            Util3D.DrawY(xform, nycolor);
            Util3D.DrawZ(xform, nzcolor);

            Vec3F handle      = sv * HandleRatio;
            float handleWidth = handle.X / 2;

            scale.Scale(handle);
            Matrix4F trans = new Matrix4F();



            Util3D.RenderFlag = solid;

            // X handle
            trans.Translation = new Vec3F(axscale.X - handleWidth, 0, 0);
            xform             = scale * trans * normWorld;
            Util3D.DrawCube(xform, xcolor);

            // y handle
            trans.Translation = new Vec3F(0, axscale.Y - handleWidth, 0);
            xform             = scale * trans * normWorld;
            Util3D.DrawCube(xform, ycolor);

            // z handle
            trans.Translation = new Vec3F(0, 0, axscale.Z - handleWidth);
            xform             = scale * trans * normWorld;
            Util3D.DrawCube(xform, zcolor);


            // -x handle
            trans.Translation = new Vec3F(negAxscale.X + handleWidth, 0, 0);
            xform             = scale * trans * normWorld;
            Util3D.DrawCube(xform, nxcolor);

            // -y handle
            trans.Translation = new Vec3F(0, negAxscale.Y + handleWidth, 0);
            xform             = scale * trans * normWorld;
            Util3D.DrawCube(xform, nycolor);

            // -z handle
            trans.Translation = new Vec3F(0, 0, negAxscale.Z + handleWidth);
            xform             = scale * trans * normWorld;
            Util3D.DrawCube(xform, nzcolor);
        }
Beispiel #53
0
        public override void OnBeginDrag()
        {
            if (m_hitRegion == HitRegion.None)
            {
                return;
            }

            var selection          = DesignView.Context.As <ISelectionContext>().Selection;
            var transactionContext = DesignView.Context.As <ITransactionContext>();

            NodeList.Clear();

            m_isUniformScaling = false;

            IEnumerable <DomNode> rootDomNodes = DomNode.GetRoots(selection.AsIEnumerable <DomNode>());

            foreach (DomNode node in rootDomNodes)
            {
                ITransformable transNode = node.As <ITransformable>();
                if (transNode == null || (transNode.TransformationType & TransformationTypes.Scale) == 0)
                {
                    continue;
                }

                IVisible vn = node.As <IVisible>();
                if (!vn.Visible)
                {
                    continue;
                }

                ILockable lockable = node.As <ILockable>();
                if (lockable.IsLocked)
                {
                    continue;
                }

                // force uniform scaling if any node requires it
                if ((transNode.TransformationType & TransformationTypes.UniformScale) == TransformationTypes.UniformScale)
                {
                    m_isUniformScaling = true;
                }

                NodeList.Add(transNode);

                IManipulatorNotify notifier = transNode.As <IManipulatorNotify>();
                if (notifier != null)
                {
                    notifier.OnBeginDrag();
                }
            }


            // to compute offset use bounding box in local space.
            Vec3F offset = Vec3F.ZeroVector;// 0.5f; // use bounding box in local space

            switch (m_hitRegion)
            {
            case HitRegion.XAxis:
            case HitRegion.YAxis:
            case HitRegion.ZAxis:
                offset = new Vec3F(-1, -1, -1);
                break;

            case HitRegion.NegXAxis:
            case HitRegion.NegYAxis:
            case HitRegion.NegZAxis:
                offset = new Vec3F(1, 1, 1);
                break;

            default:
                break;
            }

            m_originalScales       = new Vec3F[NodeList.Count];
            m_originalTranslations = new Vec3F[NodeList.Count];
            m_pivotOffset          = new Vec3F[NodeList.Count];
            int k = 0;

            foreach (ITransformable node in NodeList)
            {
                IBoundable boundable = node.As <IBoundable>();
                Vec3F      pivot     = Vec3F.Mul(boundable.LocalBoundingBox.Radius, offset);
                m_pivotOffset[k] = pivot;

                m_originalScales[k] = node.Scale;

                Matrix4F mtrx = TransformUtils.CalcTransform(
                    Vec3F.ZeroVector,
                    node.Rotation,
                    node.Scale,
                    pivot
                    );

                m_originalTranslations[k] = node.Translation - mtrx.Translation;
                k++;
            }

            if (NodeList.Count > 0)
            {
                transactionContext.Begin("Extend".Localize());
            }
        }
        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;
            }
        }
        public override void OnBeginDrag(ViewControl vc, Point scrPt)
        {
            if (m_hitRegion == HitRegion.None)
            {
                return;
            }

            m_activeOp = null;

            var op = new ManipulatorActiveOperation(
                "Extend", DesignView.Context.As <ISelectionContext>(),
                (ITransformable node) => (node.TransformationType & TransformationTypes.Scale) != 0,
                false);

            // to compute offset use bounding box in local space.
            Vec3F offset = Vec3F.ZeroVector;// 0.5f; // use bounding box in local space

            switch (m_hitRegion)
            {
            case HitRegion.XAxis:
            case HitRegion.YAxis:
            case HitRegion.ZAxis:
                offset = new Vec3F(-1, -1, -1);
                break;

            case HitRegion.NegXAxis:
            case HitRegion.NegYAxis:
            case HitRegion.NegZAxis:
                offset = new Vec3F(1, 1, 1);
                break;

            default:
                break;
            }

            m_isUniformScaling     = false;
            m_originalScales       = new Vec3F[op.NodeList.Count];
            m_originalTranslations = new Vec3F[op.NodeList.Count];
            m_pivotOffset          = new Vec3F[op.NodeList.Count];
            int k = 0;

            foreach (ITransformable node in op.NodeList)
            {
                //  if any of the selected nodes are marked as "UniformScale", then the
                //  entire operation must be a uniform scale operaion
                if ((node.TransformationType & TransformationTypes.UniformScale) == TransformationTypes.UniformScale)
                {
                    m_isUniformScaling = true;
                }

                IBoundable boundable = node.As <IBoundable>();
                Vec3F      pivot     = Vec3F.Mul(boundable.LocalBoundingBox.Radius, offset);
                m_pivotOffset[k] = pivot;

                m_originalScales[k] = node.Scale;

                Matrix4F mtrx = TransformUtils.CalcTransform(
                    Vec3F.ZeroVector,
                    node.Rotation,
                    node.Scale,
                    pivot
                    );

                m_originalTranslations[k] = node.Translation - mtrx.Translation;
                k++;
            }

            m_activeOp = op;
        }
        public override void Render(object opaqueContext, ViewControl vc)
        {
            Matrix4F normWorld = GetManipulatorMatrix();

            if (normWorld == null)
            {
                return;
            }

            var context = opaqueContext as GUILayer.SimpleRenderingContext;

            if (context == null)
            {
                return;
            }

            int axis = (int)m_hitRegion;

            // axis colors
            Color saveColor = m_axisColor[axis];

            m_axisColor[axis] = m_highlightColor;
            Color xcolor  = m_axisColor[(int)HitRegion.XAxis];
            Color ycolor  = m_axisColor[(int)HitRegion.YAxis];
            Color zcolor  = m_axisColor[(int)HitRegion.ZAxis];
            Color nxcolor = m_axisColor[(int)HitRegion.NegXAxis];
            Color nycolor = m_axisColor[(int)HitRegion.NegYAxis];
            Color nzcolor = m_axisColor[(int)HitRegion.NegZAxis];

            m_axisColor[axis] = saveColor;


            if (m_hitRegion != HitRegion.None)
            {
                normWorld.Translation = HitMatrix.Translation;
            }

            Vec3F pos = normWorld.Translation;
            float s   = Util.CalcAxisScale(vc.Camera, pos, AxisLength, vc.Height);

            Vec3F sv           = new Vec3F(s, s, s);
            Vec3F axscale      = new Vec3F(s * AxisThickness, s, s * AxisThickness);
            bool  negativeAxis = m_hitRegion == HitRegion.NegXAxis || m_hitRegion == HitRegion.NegYAxis || m_hitRegion == HitRegion.NegZAxis;
            Vec3F dragScale    = new Vec3F(Math.Abs(m_scale.X),
                                           Math.Abs(m_scale.Y), Math.Abs(m_scale.Z));



            Matrix4F rot   = new Matrix4F();
            Matrix4F scale = new Matrix4F();

            axscale.Y = negativeAxis ? s : s * dragScale.X;
            scale.Scale(axscale);
            rot.RotZ(-MathHelper.PiOver2);
            Matrix4F xform = scale * rot * normWorld;

            Util3D.DrawCylinder(context, xform, xcolor);

            axscale.Y = negativeAxis ? s : s * dragScale.Y;
            scale.Scale(axscale);
            xform = scale * normWorld;
            Util3D.DrawCylinder(context, xform, ycolor);

            axscale.Y = negativeAxis ? s : s * dragScale.Z;
            scale.Scale(axscale);
            rot.RotX(MathHelper.PiOver2);
            xform = scale * rot * normWorld;
            Util3D.DrawCylinder(context, xform, zcolor);


            rot.RotZ(MathHelper.PiOver2);
            axscale.Y = negativeAxis ? s * dragScale.X : s;
            scale.Scale(axscale);
            xform = scale * rot * normWorld;
            Util3D.DrawCylinder(context, xform, nxcolor);

            rot.RotZ(MathHelper.Pi);
            axscale.Y = negativeAxis ? s * dragScale.Y : s;
            scale.Scale(axscale);
            xform = scale * rot * normWorld;
            Util3D.DrawCylinder(context, xform, nycolor);

            rot.RotX(-MathHelper.PiOver2);
            axscale.Y = negativeAxis ? s * dragScale.Z : s;
            scale.Scale(axscale);
            xform = scale * rot * normWorld;
            Util3D.DrawCylinder(context, xform, nzcolor);


            // draw center cube
            scale.Scale(s * (1.0f / 16.0f));
            xform = scale * normWorld;
            Util3D.DrawCube(context, xform, Color.White);

            Vec3F handle      = sv * AxisHandle;
            float handleWidth = handle.X / 2;

            scale.Scale(handle);
            Matrix4F trans = new Matrix4F();


            // X handle
            float drag = m_hitRegion == HitRegion.XAxis ? dragScale.X : 1.0f;

            trans.Translation = new Vec3F(drag * sv.X - handleWidth, 0, 0);
            xform             = scale * trans * normWorld;
            Util3D.DrawCube(context, xform, xcolor);

            // y handle
            drag = m_hitRegion == HitRegion.YAxis ? dragScale.Y : 1.0f;
            trans.Translation = new Vec3F(0, drag * sv.Y - handleWidth, 0);
            xform             = scale * trans * normWorld;
            Util3D.DrawCube(context, xform, ycolor);

            // z handle
            drag = m_hitRegion == HitRegion.ZAxis ? dragScale.Z : 1.0f;
            trans.Translation = new Vec3F(0, 0, drag * sv.Z - handleWidth);
            xform             = scale * trans * normWorld;
            Util3D.DrawCube(context, xform, zcolor);


            // -x handle
            drag = m_hitRegion == HitRegion.NegXAxis ? dragScale.X : 1.0f;
            trans.Translation = new Vec3F(-sv.X * drag + handleWidth, 0, 0);
            xform             = scale * trans * normWorld;
            Util3D.DrawCube(context, xform, nxcolor);

            // -y handle
            drag = m_hitRegion == HitRegion.NegYAxis ? dragScale.Y : 1.0f;
            trans.Translation = new Vec3F(0, -sv.Y * drag + handleWidth, 0);
            xform             = scale * trans * normWorld;
            Util3D.DrawCube(context, xform, nycolor);

            // -z handle
            drag = m_hitRegion == HitRegion.NegZAxis ? dragScale.Z : 1.0f;
            trans.Translation = new Vec3F(0, 0, -sv.Z * drag + handleWidth);
            xform             = scale * trans * normWorld;
            Util3D.DrawCube(context, xform, nzcolor);
        }
 /// <summary>
 /// Constructor</summary>
 /// <param name="angleLimits">Maximum angle values in radians</param>
 /// <param name="channels">Axes (x, y, and/or z) of 'angleLimits' that are valid</param>
 public EulerAngleLimits(Vec3F angleLimits, EulerAngleChannels channels)
 {
     m_angleLimits = angleLimits;
     m_channels    = channels;
 }
 /// <summary>
 /// Constructor</summary>
 /// <param name="angles">Array of 3 floats containing the maximum angle values in radians</param>
 /// <param name="channels">Axes (x, y, and/or z) of 'angles' that are valid</param>
 public EulerAngleLimits(float[] angles, EulerAngleChannels channels)
 {
     m_angleLimits = new Vec3F(angles);
     m_channels    = channels;
 }
        public override ManipulatorPickResult Pick(ViewControl vc, Point scrPt)
        {
            m_hitRegion = HitRegion.None;
            if (base.Pick(vc, scrPt) == ManipulatorPickResult.Miss)
            {
                return(ManipulatorPickResult.Miss);
            }

            Camera camera = vc.Camera;
            float  s      = Util.CalcAxisScale(vc.Camera, HitMatrix.Translation, AxisLength, vc.Height);

            Matrix4F vp  = camera.ViewMatrix * camera.ProjectionMatrix;
            Matrix4F wvp = HitMatrix * vp;

            // get ray in object space  space.
            Ray3F rayL = vc.GetRay(scrPt, wvp);

            m_scale    = new Vec3F(1, 1, 1);
            m_hitScale = s;


            Vec3F    min      = new Vec3F(-0.5f, -0.5f, -0.5f);
            Vec3F    max      = new Vec3F(0.5f, 0.5f, 0.5f);
            AABB     box      = new AABB(min, max);
            Matrix4F boxScale = new Matrix4F();
            Matrix4F boxTrans = new Matrix4F();
            Matrix4F BoxMtrx  = new Matrix4F();

            float handleScale = s * AxisHandle;

            // +X axis
            boxScale.Scale(new Vec3F(s, handleScale, handleScale));
            boxTrans.Translation = new Vec3F(s / 2, 0, 0);
            BoxMtrx = boxScale * boxTrans;

            Ray3F ray = rayL;

            BoxMtrx.Invert(BoxMtrx);
            ray.Transform(BoxMtrx);

            if (box.Intersect(ray))
            {
                m_hitRegion = HitRegion.XAxis;
                return(ManipulatorPickResult.DeferredBeginDrag);
            }

            // -X
            boxTrans.Translation = new Vec3F(-s / 2, 0, 0);
            BoxMtrx = boxScale * boxTrans;

            ray = rayL;
            BoxMtrx.Invert(BoxMtrx);
            ray.Transform(BoxMtrx);

            if (box.Intersect(ray))
            {
                m_hitRegion = HitRegion.NegXAxis;
                return(ManipulatorPickResult.DeferredBeginDrag);
            }

            // y axis
            boxScale.Scale(new Vec3F(handleScale, s, handleScale));
            boxTrans.Translation = new Vec3F(0, s / 2, 0);
            BoxMtrx = boxScale * boxTrans;

            ray = rayL;
            BoxMtrx.Invert(BoxMtrx);
            ray.Transform(BoxMtrx);
            if (box.Intersect(ray))
            {
                m_hitRegion = HitRegion.YAxis;
                return(ManipulatorPickResult.DeferredBeginDrag);
            }

            // -Y
            boxTrans.Translation = new Vec3F(0, -s / 2, 0);
            BoxMtrx = boxScale * boxTrans;
            ray     = rayL;
            BoxMtrx.Invert(BoxMtrx);
            ray.Transform(BoxMtrx);
            if (box.Intersect(ray))
            {
                m_hitRegion = HitRegion.NegYAxis;
                return(ManipulatorPickResult.DeferredBeginDrag);
            }


            // z axis
            boxScale.Scale(new Vec3F(handleScale, handleScale, s));
            boxTrans.Translation = new Vec3F(0, 0, s / 2);
            BoxMtrx = boxScale * boxTrans;

            ray = rayL;
            BoxMtrx.Invert(BoxMtrx);
            ray.Transform(BoxMtrx);
            if (box.Intersect(ray))
            {
                m_hitRegion = HitRegion.ZAxis;
                return(ManipulatorPickResult.DeferredBeginDrag);
            }

            // -Z
            boxTrans.Translation = new Vec3F(0, 0, -s / 2);
            BoxMtrx = boxScale * boxTrans;

            ray = rayL;
            BoxMtrx.Invert(BoxMtrx);
            ray.Transform(BoxMtrx);
            if (box.Intersect(ray))
            {
                m_hitRegion = HitRegion.NegZAxis;
                return(ManipulatorPickResult.DeferredBeginDrag);
            }

            return(ManipulatorPickResult.Miss);
        }
Beispiel #60
0
        public Entity Spawn(int editorID, Vec3F position, BitAngle angle = default)
        {
            ActorDefinition definition = DecorateManager.Find(editorID);

            return(Spawn(definition, position, angle));
        }