Пример #1
0
 public virtual bool Pick(ViewControl vc, Point scrPt)
 {
     Matrix4F normWorld = GetManipulatorMatrix();
     if (normWorld == null) return false;
     HitRayV = vc.GetRay(scrPt, vc.Camera.ProjectionMatrix);            
     HitMatrix.Set(normWorld);            
     return true;
 }
Пример #2
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;
        }
Пример #3
0
        public override void OnDragging(ViewControl vc, Point scrPt)
        {
            if (m_hitRegion == HitRegion.None || !CanManipulate(m_node))
                return;

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

            Vec3F translate = m_translatorControl.OnDragging(rayV);

            Vec3F localTranslation;
            m_worldToLocal.TransformVector(translate, out localTranslation);
            m_node.Pivot = m_originalPivot + localTranslation;
        }
        public override bool Pick(ViewControl vc, Point scrPt)
        {
            m_hitRegion = HitRegion.None;
            if (base.Pick(vc, scrPt) == false)
                return false;

            m_node = GetManipulatorNode(TransformationTypes.Pivot);

            Camera camera = vc.Camera;            
            Matrix4F view = camera.ViewMatrix;
            Matrix4F vp = view * camera.ProjectionMatrix;
            Matrix4F wvp = HitMatrix * vp;

            Ray3F rayL = vc.GetRay(scrPt, wvp);
            m_hitRegion = m_translatorControl.Pick(vc, HitMatrix, view, rayL, HitRayV);
            bool picked = m_hitRegion != HitRegion.None;
            return picked;
        }
Пример #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 view = camera.ViewMatrix;
            Matrix4F vp = view  * camera.ProjectionMatrix;
            Matrix4F wvp = HitMatrix * vp;
            
            Ray3F rayL = vc.GetRay(scrPt,wvp);

            m_hitRegion = m_translatorControl.Pick(HitMatrix, view, rayL, HitRayV, s);
            
            bool picked = m_hitRegion != HitRegion.None;                      
            return picked;
        }
Пример #6
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;
            
            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;
        }
Пример #7
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;
        }
Пример #8
0
        public override void OnDragging(ViewControl vc, Point scrPt)
        {
            if (m_hitRegion == HitRegion.None || m_activeOp == null || m_activeOp.NodeList.Count == 0)
                return;
            Camera cam = vc.Camera;

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

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

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

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

            for (int i = 0; i < m_activeOp.NodeList.Count; i++)
            {
                ITransformable node = m_activeOp.NodeList[i];                              
                rotMtrx.Mul(m_rotations[i], deltaMtrx);                
                float ax, ay, az;
                rotMtrx.GetEulerAngles(out ax, out ay, out az);                                
                node.Rotation = new Vec3F(ax, ay, az);      
            }
        }
Пример #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 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 true;
            }

            // -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 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;
            }

            // -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 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;
            }

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

            return false;
        }
Пример #10
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;

            }
        }
Пример #11
0
        public override void OnDragging(ViewControl vc, Point scrPt)
        {
            if (m_hitRegion == HitRegion.None || NodeList.Count == 0)
                return;
            Camera cam = vc.Camera;

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

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

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

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

        }
Пример #12
0
        public override void OnDragging(ViewControl vc, Point scrPt)
        {
            if (m_hitRegion == HitRegion.None || m_activeOp == null || m_activeOp.NodeList.Count == 0)
                return;

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

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

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

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

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

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

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

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

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

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

            // scale
            for (int i = 0; i < m_activeOp.NodeList.Count; i++)
            {
                ITransformable transformable = m_activeOp.NodeList[i];
                transformable.Scale = Vec3F.Mul(m_originalValues[i], m_scale);
            }
        }
Пример #13
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;
        }
Пример #14
0
        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;
                }                
            }
        }