Ejemplo n.º 1
0
        public void RecalcPrimaryDependant(Canguro.View.GraphicView activeView, PointMagnet primaryPoint, LineMagnet[] globalAxes)
        {
            if (primaryPoint != null)
            {
                // Move area to lay on the primaryPoint and to set its direction any canonic
                // plane (X=x, Y=y or Z=z) which is the most paralell to the screen plane
                position = primaryPoint.Position;

                // Get screen plane normal
                Vector3 s0 = screenNormal[0], s1 = screenNormal[1], sNormal;
                activeView.Unproject(ref s0);
                activeView.Unproject(ref s1);
                sNormal = s0 - s1;

                // Assign the area normal to the most paralell canonical plane
                // (giving priority to the Z plane)
                int maxCosIndex = 2;
                float cosX, cosY, cosZ;
                cosX = Vector3.Dot(sNormal, globalAxes[0].Direction);
                cosY = Vector3.Dot(sNormal, globalAxes[1].Direction);
                cosZ = Vector3.Dot(sNormal, globalAxes[2].Direction);

                if (Math.Abs(cosZ) < minZPlaneAngle)
                    maxCosIndex = (cosX >= cosY) ? ((cosX > cosZ) ? 0 : 2) : ((cosY > cosZ) ? 1 : 2);

                normal = globalAxes[maxCosIndex].Direction;
            }
            else
            {
                position = Vector3.Empty;
                normal = globalAxes[2].Direction;
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Method to return the four bounding planes given two points in screen coordinates 
        /// (as in two mouse clicks). A plane can be defined by a point on it and its normal,
        /// which is what is beaing returned for each of the four planes as defined by selectWindow.
        /// 
        /// For this, 8 points are calculated, two for each corner, for the front and back plane.
        /// This defines a box. The points are to be defined as pointing towards the screen (i.e. a1 lies
        /// in the middle of the volume and a2 is in the front plane), regardless of the coordinate system
        /// used (left or right handed), and the second point will be at the screen plane.
        /// </summary>
        /// <param name="activeView">The view that's used for calculating the bounding planes</param>
        /// <param name="fx1">Clicked first point, X screen coordinate</param>
        /// <param name="fy1">Clicked first point, Y screen coordinate</param>
        /// <param name="fx2">Clicked second point, X screen coordinate</param>
        /// <param name="fy2">Clicked second point, Y screen coordinate</param>
        /// <param name="nAB">Returns the calculated normal for the plane AB</param>
        /// <param name="sAB">Returns a point on the calculated plane AB</param>
        /// <param name="nBC">Returns the calculated normal for the plane BC</param>
        /// <param name="sBC">Returns a point on the calculated plane BC</param>
        /// <param name="nCD">Returns the calculated normal for the plane CD</param>
        /// <param name="sCD">Returns a point on the calculated plane CD</param>
        /// <param name="nDA">Returns the calculated normal for the plane DA</param>
        /// <param name="sDA">Returns a point on the calculated plane DA</param>
        private void getPlanes(Canguro.View.GraphicView activeView, int fx1, int fy1, int fx2, int fy2,
            out Vector3 nAB, out Vector3 sAB, out Vector3 nBC, out Vector3 sBC,
            out Vector3 nCD, out Vector3 sCD, out Vector3 nDA, out Vector3 sDA,
            ref Vector3[] corners1, ref Vector3[] corners2)
        {
            // First calculate the 8 points (2 for each corner)
            Vector3 a1 = new Vector3(fx1, fy1, 0.5f);
            Vector3 a2 = new Vector3(fx1, fy1, 1);
            Vector3 b1 = new Vector3(fx2, fy1, 0.5f);
            Vector3 b2 = new Vector3(fx2, fy1, 1);
            Vector3 c1 = new Vector3(fx2, fy2, 0.5f);
            Vector3 c2 = new Vector3(fx2, fy2, 1);
            Vector3 d1 = new Vector3(fx1, fy2, 0.5f);
            Vector3 d2 = new Vector3(fx1, fy2, 1);
            activeView.Unproject(ref a1);
            activeView.Unproject(ref a2);
            activeView.Unproject(ref b1);
            activeView.Unproject(ref b2);
            activeView.Unproject(ref c1);
            activeView.Unproject(ref c2);
            activeView.Unproject(ref d1);
            activeView.Unproject(ref d2);

            if (corners1 != null && corners2 != null && corners1.Length == 4 && corners2.Length == 4)
            {
                corners1[0] = a1;
                corners1[1] = b1;
                corners1[2] = c1;
                corners1[3] = d1;

                corners2[0] = a2;
                corners2[1] = b2;
                corners2[2] = c2;
                corners2[3] = d2;
            }

            // Now calculate the normals
            // If points P and Q are consecutive and in CCW order, then
            // normal = (q2 - p1) x (q1 - p1)
            nAB = Vector3.Normalize(Vector3.Cross((b2 - a1), (b1 - a1)));
            nBC = Vector3.Normalize(Vector3.Cross((c2 - b1), (c1 - b1)));
            nCD = Vector3.Normalize(Vector3.Cross((d2 - c1), (d1 - c1)));
            nDA = Vector3.Normalize(Vector3.Cross((a2 - d1), (a1 - d1)));

            // Now assign the points on the planes.
            // Points calculated at the corners are used here
            sAB = a1;
            sBC = c1;
            sCD = c1;
            sDA = a1;
        }
Ejemplo n.º 3
0
        public Vector3 GetViewableObjectsCentroid(Canguro.View.GraphicView activeView)
        {
            // Set window equal to viewport to select everything visible
            int fx1 = activeView.Viewport.X;
            int fy1 = activeView.Viewport.Y;
            int fx2 = activeView.Viewport.X + activeView.Viewport.Width;
            int fy2 = activeView.Viewport.Y + activeView.Viewport.Height;

            List<Canguro.Model.Item> crossingItems = new List<Canguro.Model.Item>();
            SelectWindow(activeView, fx1, fy1, fx2, fy2, crossingItems, Canguro.Controller.SelectionFilter.Joints | Canguro.Controller.SelectionFilter.Lines);

            int centroidPts = 0;
            Vector3 centroid = Vector3.Empty;

            foreach (Canguro.Model.Item item in crossingItems)
            {
                if (item is Canguro.Model.Joint)
                {
                    centroidPts++;
                    centroid += ((Canguro.Model.Joint)item).Position;
                }
                else if (item is Canguro.Model.LineElement)
                {
                    centroidPts++;
                    centroid += ((Canguro.Model.LineElement)item).I.Position;
                    centroidPts++;
                    centroid += ((Canguro.Model.LineElement)item).J.Position;
                }
            }

            if (centroidPts > 0)
                return centroid * (1.0f / centroidPts);
            else
            {
                //if nothing is in view, then return the center of the viewing frustum
                Vector3 screenCenter = new Vector3(activeView.Viewport.X + activeView.Viewport.Width / 2, activeView.Viewport.Y + activeView.Viewport.Height / 2, 0.5f);
                activeView.Unproject(ref screenCenter);
                return screenCenter;
            }
        }
Ejemplo n.º 4
0
        public override float Snap(Canguro.View.GraphicView activeView, Point mousePoint)
        {
            // Get ray from mouse position
            Vector3 rayP1 = new Vector3(mousePoint.X, mousePoint.Y, 1f);
            Vector3 rayP2 = new Vector3(mousePoint.X, mousePoint.Y, 0f);
            activeView.Unproject(ref rayP1);
            activeView.Unproject(ref rayP2);
            Vector3 ray = rayP2 - rayP1;
            ray.Normalize();

            // Check best plane angle
            Vector3 normalTmp = normal;
            float cosAngle = Math.Abs(Vector3.Dot(ray, normal));
            if (cosAngle < 0.03f)
            {
                float xCosAngle = Math.Abs(Vector3.Dot(ray, CommonAxes.GlobalAxes[0]));
                float yCosAngle = Math.Abs(Vector3.Dot(ray, CommonAxes.GlobalAxes[1]));
                float zCosAngle = Math.Abs(Vector3.Dot(ray, CommonAxes.GlobalAxes[2]));

                if (xCosAngle >= yCosAngle)
                {
                    if (xCosAngle > zCosAngle)
                        normalTmp = CommonAxes.GlobalAxes[0];   // YZ Plane
                    else
                        normalTmp = CommonAxes.GlobalAxes[2];   // XY Plane
                }
                else if (yCosAngle > zCosAngle)
                    normalTmp = CommonAxes.GlobalAxes[1];   // XZ Plane
                else
                    normalTmp = CommonAxes.GlobalAxes[2];   // XY Plane
            }

            float r = Vector3.Dot(position - rayP1, normalTmp) / Vector3.Dot(ray, normalTmp);
            snapPosition = rayP1 + Vector3.Scale(ray, r);

            return lastSnapFitness = 0f;
        }