Example #1
0
        public override bool Pick(ViewControl vc, Point scrPt)
        {
            m_hitRegion = HitRegion.None;
            if (base.Pick(vc, scrPt) == false)
            {
                return(false);
            }

            Camera camera = vc.Camera;
            float  rad;

            Util.CalcAxisLengths(camera, HitMatrix.Translation, out rad);
            float tolerance = rad / 10.0f;

            // compute ray in object space  space.
            Matrix4F vp   = camera.ViewMatrix * camera.ProjectionMatrix;
            Matrix4F wvp  = HitMatrix * vp;
            Ray3F    rayL = vc.GetRay(scrPt, wvp);

            Plane3F xplane = new Plane3F(Vec3F.XAxis, Vec3F.ZeroVector);
            Plane3F yplane = new Plane3F(Vec3F.YAxis, Vec3F.ZeroVector);
            Plane3F zplane = new Plane3F(Vec3F.ZAxis, Vec3F.ZeroVector);

            Vec3F pt;
            float xdelta = float.MaxValue;
            float ydelta = float.MaxValue;
            float zdelta = float.MaxValue;

            if (rayL.IntersectPlane(xplane, out pt))
            {
                xdelta = Math.Abs(pt.Length - rad);
            }

            if (rayL.IntersectPlane(yplane, out pt))
            {
                ydelta = Math.Abs(pt.Length - rad);
            }

            if (rayL.IntersectPlane(zplane, out pt))
            {
                zdelta = Math.Abs(pt.Length - rad);
            }

            if (xdelta < tolerance && xdelta < ydelta && xdelta < zdelta)
            {
                m_hitRegion = HitRegion.XAxis;
            }
            else if (ydelta < tolerance && ydelta < zdelta)
            {
                m_hitRegion = HitRegion.YAxis;
            }
            else if (zdelta < tolerance)
            {
                m_hitRegion = HitRegion.ZAxis;
            }

            return(m_hitRegion != HitRegion.None);
        }
Example #2
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;
        }
Example #3
0
        private static float CalcAngle(Vec3F origin, Plane3F plane, Ray3F ray0, Ray3F ray1, float snapAngle)
        {
            float theta = 0;
            Vec3F p0;
            Vec3F p1;

            if (ray0.IntersectPlane(plane, out p0) &&
                ray1.IntersectPlane(plane, out p1))
            {
                Vec3F v0 = Vec3F.Normalize(p0 - origin);
                Vec3F v1 = Vec3F.Normalize(p1 - origin);
                theta = CalcAngle(v0, v1, plane.Normal, snapAngle);
            }
            return(theta);
        }
Example #4
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;
            }
        }
Example #5
0
        public override bool Pick(ViewControl vc, Point scrPt)
        {
            m_hitRegion = HitRegion.None;
            if (base.Pick(vc, scrPt) == false)
            {
                return(false);
            }

            Camera camera = vc.Camera;
            float  s;

            Util.CalcAxisLengths(camera, HitMatrix.Translation, out s);

            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;

            float    rectScale   = s * FreeRectRatio;
            Vec3F    topRight    = rectScale * (new Vec3F(1, 1, 0));
            Vec3F    topLeft     = rectScale * (new Vec3F(-1, 1, 0));
            Vec3F    bottomLeft  = rectScale * (new Vec3F(-1, -1, 0));
            Vec3F    bottomRight = rectScale * (new Vec3F(1, -1, 0));
            Matrix4F planeXform  = Util.CreateBillboard(HitMatrix.Translation, camera.WorldEye, camera.Up, camera.LookAt);
            Matrix4F wvpPlane    = planeXform * vp;

            // create ray in plane's local space.
            Ray3F rayP = vc.GetRay(scrPt, wvpPlane);

            Plane3F plane = new Plane3F(topRight, topLeft, bottomLeft);
            Vec3F   p;

            bool intersect = rayP.IntersectPlane(plane, out p);

            if (intersect)
            {
                bool inside = p.X > topLeft.X &&
                              p.X <topRight.X &&
                                   p.Y> bottomLeft.Y &&
                              p.Y < topLeft.Y;
                if (inside)
                {
                    m_hitRegion = HitRegion.FreeRect;
                    return(true);
                }
            }

            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 * HandleRatio;

            // 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(true);
            }

            // 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(true);
            }

            // 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(true);
            }

            return(false);
        }
Example #6
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);
            }
        }
Example #7
0
        public HitRegion Pick(ViewControl vc, Matrix4F world, Matrix4F view, Ray3F rayL, Ray3F rayV)
        {
            float s = Util.CalcAxisScale(vc.Camera, world.Translation, Manipulator.AxisLength, vc.Height);

            m_hitRegion = HitRegion.None;
            m_hitRayV   = rayV;

            m_hitMatrix.Set(world);
            m_hitWorldView = world * view;

            float sl = s * SquareLength;


            // test xy square.
            Vec3F   p1    = new Vec3F(0, 0, 0);
            Vec3F   p2    = new Vec3F(sl, 0, 0);
            Vec3F   p3    = new Vec3F(sl, sl, 0);
            Vec3F   p4    = new Vec3F(0, sl, 0);
            Plane3F plane = new Plane3F(p1, p2, p3);
            Vec3F   p;

            if (rayL.IntersectPlane(plane, out p))
            {
                // test point in 2d rectangle.
                if (p.X > p1.X && p.X < p2.X &&
                    p.Y > p1.Y && p.Y < p4.Y)
                {
                    m_hitRegion = HitRegion.XYSquare;
                    return(m_hitRegion);
                }
            }

            // test xz square
            p1    = new Vec3F(0, 0, 0);
            p2    = new Vec3F(sl, 0, 0);
            p3    = new Vec3F(sl, 0, sl);
            p4    = new Vec3F(0, 0, sl);
            plane = new Plane3F(p1, p2, p3);
            if (rayL.IntersectPlane(plane, out p))
            {
                // test point in 2d rectangle.
                if (p.X > p1.X && p.X < p2.X &&
                    p.Z > p1.Z && p.Z < p4.Z)
                {
                    m_hitRegion = HitRegion.XZSquare;
                    return(m_hitRegion);
                }
            }


            // test yz square
            p1    = new Vec3F(0, 0, 0);
            p2    = new Vec3F(0, 0, sl);
            p3    = new Vec3F(0, sl, sl);
            p4    = new Vec3F(0, sl, 0);
            plane = new Plane3F(p1, p2, p3);
            if (rayL.IntersectPlane(plane, out p))
            {
                // test point in 2d rectangle.
                if (p.Z > p1.Z && p.Z < p2.Z &&
                    p.Y > p1.Z && p.Y < p4.Y)
                {
                    m_hitRegion = HitRegion.YZSquare;
                    return(m_hitRegion);
                }
            }

            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();

            // X axis
            boxScale.Scale(new Vec3F(s, s * ConeDiameter, s * ConeDiameter));
            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(m_hitRegion);
            }

            // y axis
            boxScale.Scale(new Vec3F(s * ConeDiameter, s, s * ConeDiameter));
            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(m_hitRegion);
            }

            // z axis
            boxScale.Scale(new Vec3F(s * ConeDiameter, s * ConeDiameter, 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(m_hitRegion);
        }
Example #8
0
        public Vec3F OnDragging(Ray3F rayV)
        {
            if (m_hitRegion == HitRegion.None)
            {
                return(Vec3F.ZeroVector);
            }


            Vec3F xLocal = m_hitMatrix.XAxis;
            Vec3F yLocal = m_hitMatrix.YAxis;
            Vec3F zLocal = m_hitMatrix.ZAxis;

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

            Vec3F translate;
            float a1, a2;

            switch (m_hitRegion)
            {
            case HitRegion.XAxis:
            {
                a1 = Math.Abs(Vec3F.Dot(m_hitRayV.Direction, yAxis));
                a2 = Math.Abs(Vec3F.Dot(m_hitRayV.Direction, zAxis));
                Vec3F axis       = (a1 > a2 ? yAxis : zAxis);
                Vec3F p0         = m_hitRayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                Vec3F p1         = rayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                float dragAmount = Vec3F.Dot((p1 - p0), xAxis);
                translate = dragAmount * xLocal;
            }

            break;

            case HitRegion.YAxis:
            {
                a1 = Math.Abs(Vec3F.Dot(m_hitRayV.Direction, zAxis));
                a2 = Math.Abs(Vec3F.Dot(m_hitRayV.Direction, xAxis));
                Vec3F axis       = (a1 > a2 ? zAxis : xAxis);
                Vec3F p0         = m_hitRayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                Vec3F p1         = rayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                float dragAmount = Vec3F.Dot((p1 - p0), yAxis);
                translate = dragAmount * yLocal;
            }
            break;

            case HitRegion.ZAxis:
            {
                a1 = Math.Abs(Vec3F.Dot(m_hitRayV.Direction, xAxis));
                a2 = Math.Abs(Vec3F.Dot(m_hitRayV.Direction, yAxis));
                Vec3F axis       = (a1 > a2 ? xAxis : yAxis);
                Vec3F p0         = m_hitRayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                Vec3F p1         = rayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                float dragAmount = Vec3F.Dot((p1 - p0), zAxis);
                translate = dragAmount * zLocal;
            }
            break;

            case HitRegion.XYSquare:
            {
                Vec3F p0         = m_hitRayV.IntersectPlane(zAxis, -Vec3F.Dot(zAxis, origin));
                Vec3F p1         = rayV.IntersectPlane(zAxis, -Vec3F.Dot(zAxis, origin));
                Vec3F deltaLocal = p1 - p0;
                float dragX      = Vec3F.Dot(xAxis, deltaLocal);
                float dragY      = Vec3F.Dot(yAxis, deltaLocal);
                translate = dragX * xLocal + dragY * yLocal;
            }
            break;

            case HitRegion.YZSquare:
            {
                Vec3F p0         = m_hitRayV.IntersectPlane(xAxis, -Vec3F.Dot(xAxis, origin));
                Vec3F p1         = rayV.IntersectPlane(xAxis, -Vec3F.Dot(xAxis, origin));
                Vec3F deltaLocal = p1 - p0;
                float dragY      = Vec3F.Dot(yAxis, deltaLocal);
                float dragZ      = Vec3F.Dot(zAxis, deltaLocal);
                translate = dragY * yLocal + dragZ * zLocal;
            }
            break;

            case HitRegion.XZSquare:
            {
                Vec3F p0         = m_hitRayV.IntersectPlane(yAxis, -Vec3F.Dot(yAxis, origin));
                Vec3F p1         = rayV.IntersectPlane(yAxis, -Vec3F.Dot(yAxis, origin));
                Vec3F deltaLocal = p1 - p0;
                float dragX      = Vec3F.Dot(xAxis, deltaLocal);
                float dragZ      = Vec3F.Dot(zAxis, deltaLocal);
                translate = dragX * xLocal + dragZ * zLocal;
            }
            break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            return(translate);
        }
Example #9
0
        public override bool Pick(ViewControl vc, Point scrPt)
        {
            m_hitRegion = HitRegion.None;
            if (base.Pick(vc, scrPt) == false)
            {
                return(false);
            }

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

            float rad       = s * Util3D.RingCenterRadias;
            float lrad      = rad * LookRingScale;
            float tolerance = s * Util3D.RingThickness;

            Matrix4F billboard
                = Util.CreateBillboard(HitMatrix.Translation, vc.Camera.WorldEye, vc.Camera.Up, vc.Camera.LookAt);

            m_lookAxisHitMtrx = billboard;
            // compute ray in object space  space.
            Matrix4F vp   = camera.ViewMatrix * camera.ProjectionMatrix;
            Matrix4F wvp  = HitMatrix * vp;
            Ray3F    rayL = vc.GetRay(scrPt, wvp);

            Matrix4F wvp2  = billboard * vp;
            Ray3F    rayL2 = vc.GetRay(scrPt, wvp2);

            Plane3F xplane = new Plane3F(Vec3F.XAxis, Vec3F.ZeroVector);
            Plane3F yplane = new Plane3F(Vec3F.YAxis, Vec3F.ZeroVector);
            Plane3F zplane = new Plane3F(Vec3F.ZAxis, Vec3F.ZeroVector);


            Vec3F pt;
            float xdelta    = float.MaxValue;
            float ydelta    = float.MaxValue;
            float zdelta    = float.MaxValue;
            float lookdelta = float.MaxValue;

            if (rayL.IntersectPlane(xplane, out pt))
            {
                xdelta = Math.Abs(pt.Length - rad);
            }

            if (rayL.IntersectPlane(yplane, out pt))
            {
                ydelta = Math.Abs(pt.Length - rad);
            }

            if (rayL.IntersectPlane(zplane, out pt))
            {
                zdelta = Math.Abs(pt.Length - rad);
            }

            if (rayL2.IntersectPlane(zplane, out pt))
            {
                lookdelta = Math.Abs(pt.Length - lrad);
            }

            if (xdelta < tolerance && xdelta < ydelta && xdelta < zdelta &&
                xdelta < lookdelta)
            {
                m_hitRegion = HitRegion.XAxis;
            }
            else if (ydelta < tolerance && ydelta < zdelta &&
                     ydelta < lookdelta)
            {
                m_hitRegion = HitRegion.YAxis;
            }
            else if (zdelta < tolerance && zdelta < lookdelta)
            {
                m_hitRegion = HitRegion.ZAxis;
            }
            else if (lookdelta < tolerance)
            {
                m_hitRegion = HitRegion.LookAxis;
            }

            return(m_hitRegion != HitRegion.None);
        }
Example #10
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);
        }