Example #1
0
        ////////////////////
        /// DRAWING METHODS
        /// DRAWING METHODS
        ////////////////////

        void DrawElement(ShapeElement element)
        {
            // Debug.Log("Drawing element . Points: " + element.knots.Length);
            for (int i = 0; i < element.knots.Length - 1; i++)
            {
                //CREATE A BEZIER SEGMENT
                BezierSegment seg = new BezierSegment();
                seg.A = GetScaledVector(element.knots[i].KWorldPos(transform));              //START POINT
                seg.B = GetScaledVector(element.knots[i].KHandleOutWorldPos(transform));     //START TANGENT
                seg.C = GetScaledVector(element.knots[i + 1].KHandleInWorldPos(transform));  //END TANGENT
                seg.D = GetScaledVector(element.knots[i + 1].KWorldPos(transform));          //END POINT

                //NON SCALED

                /*
                 * //CREATE A BEZIER SEGMENT
                 * BezierSegment seg = new BezierSegment();
                 * seg.A = element.knots[i].KWorldPos(transform);              //START POINT
                 * seg.B = element.knots[i].KHandleOutWorldPos(transform);     //START TANGENT
                 * seg.C = element.knots[i + 1].KHandleInWorldPos(transform);  //END TANGENT
                 * seg.D = element.knots[i + 1].KWorldPos(transform);          //END POINT
                 */
                //Draw it
                DrawBezierSegment(seg);
            }
        }
Example #2
0
        /// <summary>
        /// Gets the sum of all individuals segments in this curve
        /// </summary>
        /// <returns></returns>
        public static float GetCurveLength(ShapeElement element, Transform theT)
        {
            float TotalLenghtSum = 0;

            //Draw Each Element

            for (int i = 0; i < element.knots.Length - 1; i++)
            {
                //CREATE A BEZIER SEGMENT
                BezierSegment seg = new BezierSegment();
                seg.A = element.knots[i].KWorldPos(theT);              //START POINT
                seg.B = element.knots[i].KHandleOutWorldPos(theT);     //START TANGENT
                seg.C = element.knots[i + 1].KHandleInWorldPos(theT);  //END TANGENT
                seg.D = element.knots[i + 1].KWorldPos(theT);          //END POINT

                float totalLength = GetLengthSimpsons(0f, 1f, seg);
                TotalLenghtSum = TotalLenghtSum + totalLength;
            }

            return(TotalLenghtSum);
        }
        void DrawElementHandles(ShapeElement element)
        {
            // Debug.Log("Drawing element . Points: " + element.knots.Length);
            //DRAW KNOTS
            for (int i = 0; i < element.knots.Length; i++)
            {
                if (element.knots[i].isSelected)
                //if (element.knots[i] == Target.selectedKnot)
                {
                    DrawKnotMovementHandle(element.knots[i]);

                    switch (element.knots[i].kType)
                    {
                    case KnotType.Linear:
                        break;

                    case KnotType.Smooth:
                        break;

                    case KnotType.Bezier:
                        DrawKnotBezierHandles(element.knots[i], true, true);
                        break;

                    default:
                        break;
                    }


                    //if (element.knots[i].kType == KnotType.Bezier || element.knots[i].kType == KnotType.Smooth)
                    //{
                    //    DrawKnotBezierHandles(element.knots[i], true, true);
                    // }
                }
                else
                {
                    DrawKnotSelector(element.knots[i]);
                }
            }
        }
Example #4
0
        ////////////////////////////////////////
        /// INITIALIZATION
        /// INITIALIZATION
        ////////////////////////////////////////

        void CreateDefaultCurve()
        {
            //Reset the elements Array
            elements = new ShapeElement[1];
            //Add an element to the array
            elements[0] = new ShapeElement();

            //Create the Knot Array
            elements[0].knots = new ShapeKnot[2];

            //Create the first knot
            elements[0].knots[0] = new ShapeKnot();
            //Setup the element Index
            elements[0].knots[0].myElementIndex = 0;
            //Setup knot index
            elements[0].knots[0].myIndex = 0;

            //Position of the first knot
            elements[0].knots[0].kPos = new Vector3(0, 0, -5);
            //Handle in of the first Knot
            elements[0].knots[0].kHandleIn = new Vector3(0, 0, -2);
            //Handle out of the first Knot
            elements[0].knots[0].kHandleOut = new Vector3(0, 0, 2);

            //Create the second knot
            elements[0].knots[1] = new ShapeKnot();
            //Setup the element Index
            elements[0].knots[1].myElementIndex = 0;
            //Setup knot index
            elements[0].knots[1].myIndex = 1;

            //Position of the second knot
            elements[0].knots[1].kPos = new Vector3(0, 0, 5);
            //Handle in of the second Knot
            elements[0].knots[1].kHandleIn = new Vector3(0, 0, -2);
            //Handle out of the second Knot
            elements[0].knots[1].kHandleOut = new Vector3(0, 0, 2);
        }
Example #5
0
        ////////////////////////////////////////
        /// SPLINE UPDATE
        /// SPLINE UPDATE
        ////////////////////////////////////////

        /*   RECALCULATE LINEAR
         *  In this mode the Control Points ( tangents) go half-way the distance between them ant their neighbouring control point
         *  tangentIn of knot[n] will go half way toward knot[n-1].tangentOut
         *  tangentOut of knot[n] will go half way toward knot[n+1].tangentIn
         */

        void RecalculateLinearKnot(ShapeElement element, int knotIndex)
        {
            //Debug.Log("recalculating index " + knotIndex.ToString());
            //Local Variables
            Vector3 knotWorldPos = element.knots[knotIndex].KWorldPos(transform);
            Vector3 tempWorldPos = Vector3.zero;

            bool calculateOutHandle = !(knotIndex == element.knots.Length - 1);
            bool calculateInHandle  = !(knotIndex == 0);

            if (calculateOutHandle)
            {
                Vector3 handleOutTarget = element.knots[knotIndex + 1].KHandleInWorldPos(transform);
                tempWorldPos = Vector3.Lerp(knotWorldPos, handleOutTarget, 0.5f);
                element.knots[knotIndex].kHandleOut = tempWorldPos - knotWorldPos;
            }
            if (calculateInHandle)
            {
                Vector3 handleInTarget = element.knots[knotIndex - 1].KHandleOutWorldPos(transform);
                tempWorldPos = Vector3.Lerp(knotWorldPos, handleInTarget, 0.5f);
                element.knots[knotIndex].kHandleIn = tempWorldPos - knotWorldPos;
            }
        }
Example #6
0
        //Divide the curve into equal steps
        public static List <Vector3> ResampleCurve(int numSteps, ShapeElement element, Transform theT)
        {
            float totalLenght   = GetCurveLength(element, theT);
            float sectionLength = totalLenght / numSteps;


            List <Vector3> curveSteps = new List <Vector3>();


            /*
             *      20          8          35                 17                -segmentLenghts     N
             *
             * X -------------X--------X-------------------X-----------X          -theSegs            N
             *
             * 0              20      28                   63          80         -knotDistances      N+1
             *
             */

            //Create A list of Bezier Segment
            List <BezierSegment> theSegs = new List <BezierSegment>();
            //Create A list of Bezier Segment Lengths
            List <float> segmentLenghts = new List <float>();


            for (int i = 0; i < element.knots.Length - 1; i++)
            {
                //CREATE A BEZIER SEGMENT
                BezierSegment seg = new BezierSegment();
                seg.A = element.knots[i].KWorldPos(theT);              //START POINT
                seg.B = element.knots[i].KHandleOutWorldPos(theT);     //START TANGENT
                seg.C = element.knots[i + 1].KHandleInWorldPos(theT);  //END TANGENT
                seg.D = element.knots[i + 1].KWorldPos(theT);          //END POINT

                theSegs.Add(seg);

                segmentLenghts.Add(GetLengthSimpsons(0f, 1f, seg));
            }


            //Create a list of knot Distances
            List <float> knotDistances = new List <float>();
            float        tempDist      = 0;

            knotDistances.Add(tempDist);
            for (int i = 0; i < segmentLenghts.Count; i++)
            {
                tempDist = tempDist + segmentLenghts[i];
                knotDistances.Add(tempDist);
            }

            //Add the first point
            curveSteps.Clear();
            curveSteps.Add(theSegs[0].A);

            //For each step
            for (int i = 1; i < numSteps; i++)
            {
                //Get this point dist
                float distAlong = sectionLength * i;

                //Find out in wich segment it falls
                int currSegIndex = 0;
                for (int f = 0; f < knotDistances.Count - 1; f++)
                {
                    if (distAlong > knotDistances[f])
                    {
                        if (distAlong < knotDistances[f + 1])
                        {
                            currSegIndex = f;
                        }
                    }
                }

                //Find out at which distance along that segment the point falls
                float segPointDist = distAlong - knotDistances[currSegIndex];

                //Use Newton–Raphsons method to find the t value from the start of the curve
                //to the end of the distance we have
                float t = FindTValue(segPointDist, segmentLenghts[currSegIndex], theSegs[currSegIndex]);

                //Get the coordinate on the Bezier curve at this t value
                Vector3 pos = DeCasteljausAlgorithm(t, theSegs[currSegIndex]);

                //Add the next point to the curveSteps list
                curveSteps.Add(pos);
            }
            return(curveSteps);
        }
Example #7
0
        /*   RECALCULATE SMOOTH
         *  Algorithm based on : http://www.efg2.com/Lab/Graphics/Jean-YvesQueinecBezierCurves.htm
         */

        void RecalculateSmoothKnot(ShapeElement element, int knotIndex)
        {
            //Debug.Log("recalculating index " + knotIndex.ToString());
            //Local Variables

            bool isLast  = (knotIndex == element.knots.Length - 1);
            bool isFirst = (knotIndex == 0);


            if (!isLast && !isFirst)
            {
                //GET THE POINTS TO BE USED

                Vector3 k0Pos = element.knots[knotIndex - 1].KWorldPos(transform);
                Vector3 k1Pos = element.knots[knotIndex].KWorldPos(transform);
                Vector3 k2Pos = element.knots[knotIndex + 1].KWorldPos(transform);


                //GET THE OFFSETED LINE

                //Get base Vector
                Vector3 BaseVec           = k0Pos - k2Pos;
                float   baseVecHalfLenght = Vector3.Magnitude(BaseVec) / 2;

                Vector3 q0 = k1Pos + Vector3.Normalize(BaseVec) * baseVecHalfLenght;
                Vector3 q1 = k1Pos + Vector3.Normalize(-BaseVec) * baseVecHalfLenght;



                //GET THE IN TANGENT

                //GET k2-k1 Vector3

                Vector3 k2k1Vec = k2Pos - k1Pos;

                //Get the smoothed point dist
                float smoothPoint = k2k1Vec.magnitude / 4;

                Vector3 pIn0 = k1Pos + Vector3.Normalize(k2k1Vec) * smoothPoint;
                Vector3 pIn1 = Vector3.Lerp(k0Pos, k1Pos, 0.5f);

                Vector3 inTangent = SS_Common.GetLineIntersection(q0, q1, pIn0, pIn1);

                //ASSIGN THE TANGENT
                element.knots[knotIndex].kHandleIn = inTangent - k1Pos;



                //GET THE OUT TANGENT

                Vector3 k0k1Vec = k0Pos - k1Pos;

                //Get the smoothed point dist
                smoothPoint = k0k1Vec.magnitude / 4;

                Vector3 pOut0 = k1Pos + Vector3.Normalize(k0k1Vec) * smoothPoint;
                Vector3 pOut1 = Vector3.Lerp(k1Pos, k2Pos, 0.5f);


                Vector3 outTangent = SS_Common.GetLineIntersection(q0, q1, pOut0, pOut1);

                //ASSIGN THE TANGENT
                element.knots[knotIndex].kHandleOut = k1Pos - outTangent;
            }



            if (isFirst)    //We only calculate the OutTangent
            {
                Vector3 k0Pos = element.knots[0].KWorldPos(transform);
                Vector3 k1Pos = element.knots[1].KWorldPos(transform);
                Vector3 k2Pos = element.knots[2].KWorldPos(transform);

                //FIRST LINE P
                //Midpoint of knot[0] , knot[1]   = "P0"
                Vector3 p0 = Vector3.Lerp(k0Pos, k1Pos, 0.5f);

                //Dir of   knot[2] - knot[1]  = k2k1Dir
                Vector3 k2k1Dir = k2Pos - k1Pos;

                //Half distance between knot[2] - knot[1] = k2k1halfDist
                float k2k1HalfDist = k2k1Dir.magnitude / 2;

                //Get Point starting at "P0" traveling "k2k1halfDist" in "k2k1Dir" direction = "P1"
                Vector3 p1 = p0 + Vector3.Normalize(k2k1Dir) * k2k1HalfDist;

                //SECOND LINE K
                //K0 = knot[0]
                Vector3 q0 = k0Pos;

                //Get vector from knot[0] to knot[2] = "k0k2Vector"
                Vector3 k0k2Vector = k2Pos - k0Pos;

                //Get a quarter of the length of "k0k1Vector" = "smoothLength"
                float smoothLength = Vector3.Magnitude(k0k2Vector) / 4;

                //K1 = Starting at P1 travel "smoothLength" along  "k0k2Vector" direction
                Vector3 q1 = p1 + Vector3.Normalize(k0k2Vector) * smoothLength;

                //GET INTERSECTION
                Vector3 intersection = SS_Common.GetLineIntersection(p0, p1, q0, q1);

                element.knots[0].kHandleOut = intersection - k0Pos;
            }

            if (isLast) //We only calculate the inTangent
            {
                Vector3 k0Pos = element.knots[knotIndex].KWorldPos(transform);
                Vector3 k1Pos = element.knots[knotIndex - 1].KWorldPos(transform);
                Vector3 k2Pos = element.knots[knotIndex - 2].KWorldPos(transform);

                //FIRST LINE P
                //Midpoint of knot[0] , knot[1]   = "P0"
                Vector3 p0 = Vector3.Lerp(k0Pos, k1Pos, 0.5f);

                //Dir of   knot[2] - knot[1]  = k2k1Dir
                Vector3 k2k1Dir = k2Pos - k1Pos;

                //Half distance between knot[2] - knot[1] = k2k1halfDist
                float k2k1HalfDist = k2k1Dir.magnitude / 2;

                //Get Point starting at "P0" traveling "k2k1halfDist" in "k2k1Dir" direction = "P1"
                Vector3 p1 = p0 + Vector3.Normalize(k2k1Dir) * k2k1HalfDist;

                //SECOND LINE K
                //K0 = knot[0]
                Vector3 q0 = k0Pos;

                //Get vector from knot[0] to knot[2] = "k0k2Vector"
                Vector3 k0k2Vector = k2Pos - k0Pos;

                //Get a quarter of the length of "k0k1Vector" = "smoothLength"
                float smoothLength = Vector3.Magnitude(k0k2Vector) / 4;

                //K1 = Starting at P1 travel "smoothLength" along  "k0k2Vector" direction
                Vector3 q1 = p1 + Vector3.Normalize(k0k2Vector) * smoothLength;

                //GET INTERSECTION
                Vector3 intersection = SS_Common.GetLineIntersection(p0, p1, q0, q1);


                element.knots[knotIndex].kHandleIn = intersection - k0Pos;
            }
        }