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);
        }
Example #2
0
        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);
        }
Example #3
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 #4
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.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);

            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.CenterCube;
                return(true);
            }

            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;
            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 #5
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 #6
0
        /// <summary>
        /// Dispatches untyped items. Replaces DispatchNotTyped(). To get the same behavior as
        /// the old DispatchNotTyped(), set the TypeFilter property to null prior to calling.</summary>
        /// <param name="traverseList">The traverse list</param>
        /// <param name="camera">The camera</param>
        protected void DispatchTraverseList(ICollection <TraverseNode> traverseList, Camera camera)
        {
            // Prepare for geometric picking -- create the ray in world space and reset geometric hit-list.
            // First create the ray in viewing coordinates and transform to world coordinates.
            float    nx          = (m_x / (float)m_width) - 0.5f;  //normalized x
            float    ny          = 0.5f - (m_y / (float)m_height); //normalized y
            Ray3F    rayWorld    = camera.CreateRay(nx, ny);
            Matrix4F worldToView = camera.ViewMatrix;
            Matrix4F viewToWorld = new Matrix4F();

            viewToWorld.Invert(worldToView);
            rayWorld.Transform(viewToWorld);
            ClearHitList();

            // for geometric picking. will be cleared for each HitRecord.
            List <uint> userData = new List <uint>(1);

            // Dispatch traverse list
            int index = 0;

            foreach (TraverseNode node in traverseList)
            {
                // First test for filtering.
                IRenderObject renderObject = node.RenderObject;
                if (FilterByType(renderObject))
                {
                    IIntersectable intersectable = renderObject.GetIntersectable();
                    IGeometricPick geometricPick = intersectable as IGeometricPick;
                    if (geometricPick != null)
                    {
                        // Picking by geometry.
                        Matrix4F objToWorld = new Matrix4F(node.Transform);
                        Matrix4F worldToObj = new Matrix4F();
                        worldToObj.Invert(objToWorld);
                        Matrix4F viewToObj = Matrix4F.Multiply(viewToWorld, worldToObj);

                        if (m_frustumPick)
                        {
                            //The pick frustum is in view space. Transform to world space then object space.
                            Frustum frustumObj = new Frustum(m_viewFrust0);
                            frustumObj.Transform(viewToObj);

                            //Multi-pick. Get everything in the pick frustum (m_viewFrust0).
                            Vec3F eyeObj;
                            worldToObj.Transform(camera.Eye, out eyeObj);
                            userData.Clear();

                            if (geometricPick.IntersectFrustum(frustumObj, eyeObj, node.RenderState, userData))
                            {
                                // Prepare a multi-pick HitRecord, as if OpenGL had calculated this.
                                HitRecord hit = new HitRecord(
                                    node.GraphPath,
                                    renderObject,
                                    objToWorld,
                                    userData.ToArray());

                                m_geoHitList.Add(hit);
                            }
                        }
                        else
                        {                            //Single pick. We care about distance from camera eye.
                            //Make a copy of the ray in world-space and tranform it to object space.
                            Ray3F rayObj = rayWorld; //remember, Ray3F is a value type, not a reference type.
                            rayObj.Transform(worldToObj);

                            // Do the intersection test in object space.
                            userData.Clear();
                            Vec3F intersectionPt, surfaceNormal;
                            Vec3F nearestVert;
                            bool  intersected;
                            intersected = geometricPick.IntersectRay(
                                rayObj, camera, node.RenderState, objToWorld, this,
                                out intersectionPt, out nearestVert, out surfaceNormal, userData);

                            if (intersected)
                            {
                                // Transform to world space and then to screen space.
                                objToWorld.Transform(intersectionPt, out intersectionPt);
                                objToWorld.Transform(nearestVert, out nearestVert);
                                // Prepare a single-pick HitRecord, as if OpenGL had calculated this.
                                HitRecord hit = new HitRecord(
                                    node.GraphPath,
                                    renderObject,
                                    objToWorld,
                                    userData.ToArray());

                                // This is the one difference from OpenGL pick. We have the world pt already.
                                hit.WorldIntersection = intersectionPt;
                                hit.NearestVert       = nearestVert;

                                // Another difference is that it's possible to get the surface normal.
                                if (surfaceNormal != Vec3F.ZeroVector)
                                {
                                    objToWorld.TransformNormal(surfaceNormal, out surfaceNormal);
                                    surfaceNormal.Normalize();
                                    hit.Normal = surfaceNormal;
                                }

                                m_geoHitList.Add(hit);
                            }
                        }
                    }
                    else
                    {
                        // Picking by "rendering", using OpenGL pick.
                        PushMatrix(node.Transform, false);
                        Gl.glPushName(index);
                        IRenderPick pickInterface = renderObject as IRenderPick;
                        if (pickInterface != null)
                        {
                            pickInterface.PickDispatch(node.GraphPath, node.RenderState, this, camera);
                        }
                        else
                        {
                            renderObject.Dispatch(node.GraphPath, node.RenderState, this, camera);
                        }
                        Gl.glPopName();
                        PopMatrix();
                    }
                }

                index++;
            }
        }