//    *
        //	 * Build a path from bezier control points
        //	 * @exception Ogre::InvalidStateException The curve must at least contain 2 points
        //

        //-----------------------------------------------------------------------
        public Path realizePath()
        {
            if (mPoints.size() < 2)
            {
                OGRE_EXCEPT("Ogre::Exception::ERR_INVALID_STATE", "The curve must at least contain 2 points", "Procedural::BezierCurve3::realizePath()");
            }
            ;

            uint[] coef = new uint[mPoints.size()];
            if (mPoints.size() == 2)
            {
                coef[0] = 1;
                coef[1] = 1;
            }
            else if (mPoints.size() == 3)
            {
                coef[0] = 1;
                coef[1] = 2;
                coef[2] = 1;
            }
            else if (mPoints.size() == 4)
            {
                coef[0] = 1;
                coef[1] = 3;
                coef[2] = 3;
                coef[3] = 1;
            }
            else
            {
                for (uint i = 0; i < (int)mPoints.Count; i++)
                {
                    coef[i] = Utils.binom((uint)mPoints.Count - 1, i);
                }
            }

            uint  div = (uint)(mPoints.Count - 1) * mNumSeg + 1;
            float dt  = 1.0f / (float)div;

            Path  path = new Path();
            float t    = 0.0f;

            while (t < 1.0f)
            {
                float x = 0.0f;
                float y = 0.0f;
                float z = 0.0f;
                for (int i = 0; i < (int)mPoints.size(); i++)
                {
                    float fac = coef[i] * (float)System.Math.Pow(t, i) * (float)System.Math.Pow(1.0f - t, (int)mPoints.Count - 1 - i);
                    x += fac * mPoints[i].x;
                    y += fac * mPoints[i].y;
                    z += fac * mPoints[i].z;
                }
                path.addPoint(x, y, z);
                t += dt;
            }
            coef = null;

            return(path);
        }
        //    *
        //	 * Builds a path from control points
        //
        //-----------------------------------------------------------------------
        public Path realizePath()
        {
            Path path = new Path();

            //Precompute tangents
            for (uint i = 0; i < mPoints.size(); ++i)
            {
                ControlPoint mp = mPoints[(int)i];
                GlobalMembers.computeTangents(ref mp, safeGetPoint(i - 1).position, safeGetPoint(i + 1).position);
            }
            int numPoints = mClosed ? mPoints.size() : (mPoints.size() - 1);

            for (int i = 0; i < numPoints; ++i)
            {
                ControlPoint         pointBefore             = mPoints[i];
                ControlPoint         pointAfter              = safeGetPoint((uint)i + 1);
                std_vector <Vector3> path_getPointsReference = path.getPointsReference();
                GlobalMembers.computeCubicHermitePoints(pointBefore, pointAfter, mNumSeg, ref path_getPointsReference);

                if (i == mPoints.size() - 2 && !mClosed)
                {
                    path.addPoint(pointAfter.position);
                }
            }
            if (mClosed)
            {
                path.close();
            }

            return(path);
        }
        //    *
        //	 * Build a path from Catmull-Rom control points
        //
        //-----------------------------------------------------------------------
        public Path realizePath()
        {
            Path path = new Path();

            int numPoints = mClosed ? mPoints.Count : mPoints.Count - 1;

            for (uint i = 0; i < numPoints; ++i)
            {
                Vector3 P1 = safeGetPoint(i - 1);
                Vector3 P2 = safeGetPoint(i);
                Vector3 P3 = safeGetPoint(i + 1);
                Vector3 P4 = safeGetPoint(i + 2);
                std_vector <Vector3> lref = path.getPointsReference();
                GlobalMembers.computeCatmullRomPoints(P1, P2, P3, P4, mNumSeg, ref lref);

                if (i == mPoints.size() - 2 && !mClosed)
                {
                    path.addPoint(P3);
                }
            }
            if (mClosed)
            {
                path.close();
            }

            return(path);
        }
        /// Outputs a path
        public Path realizePath()
        {
            Path p = new Path();

            for (uint i = 0; i <= mNumSeg; ++i)
            {
                p.addPoint((1 - i / (float)mNumSeg) * mPoint1 + i / (float)mNumSeg * mPoint2);
            }
            return(p);
        }
        /// Creates a path with the keys of this path and extra keys coming from a track
        //
        //ORIGINAL LINE: Path mergeKeysWithTrack(const Track& track) const
        public Path mergeKeysWithTrack(Track track)
        {
            if (!track.isInsertPoint() || track.getAddressingMode() == Track.AddressingMode.AM_POINT)
            {
                return(this);
            }
            float totalLength = getTotalLength();

            float lineicPos     = 0;
            float pathLineicPos = 0;
            Path  outputPath    = new Path();

            outputPath.addPoint(getPoint(0));
            for (int i = 1; i < mPoints.size();)
            {
                float nextLineicPos = pathLineicPos + (mPoints[i] - mPoints[i - 1]).Length;

                std_pair <float, float> it = track._getKeyValueAfter(lineicPos, lineicPos / totalLength, (uint)(i - 1));

                float nextTrackPos = it.first;
                if (track.getAddressingMode() == Track.AddressingMode.AM_RELATIVE_LINEIC)
                {
                    nextTrackPos *= totalLength;
                }

                // Adds the closest point to the curve, being either from the path or the track
                if (nextLineicPos <= nextTrackPos || lineicPos >= nextTrackPos)
                {
                    outputPath.addPoint(mPoints[i]);
                    i++;
                    lineicPos     = nextLineicPos;
                    pathLineicPos = nextLineicPos;
                }
                else
                {
                    outputPath.addPoint(getPosition(i - 1, (nextTrackPos - pathLineicPos) / (nextLineicPos - pathLineicPos)));
                    lineicPos = nextTrackPos;
                }
            }
            return(outputPath);
        }
        //    *
        //	 * Builds a shape from control points
        //
        //-----------------------------------------------------------------------
        public Path realizePath()
        {
            Path  helix      = new Path();
            float angleStep  = Math.TWO_PI / (float)(mNumSegPath);
            float heightStep = mHeight / (float)(mNumSegPath);

            for (int i = 0; i < mNumRound * mNumSegPath; i++)
            {
                helix.addPoint(mRadius * Math.Cos(angleStep * i), heightStep * i, mRadius * Math.Sin(angleStep * i));
            }

            return(helix);
        }
        /// Extracts a part of the shape as a new path
        /// @param first first index to be in the new path
        /// @param last last index to be in the new path
        public Path extractSubPath(int first, int last)  //提取 抽出 抽取
        {
            Path p = new Path();

            for (int i = first; i < last; i++)
            {
                p.addPoint(mPoints[i]);
            }
            if (mClosed)
            {
                p.close();
            }
            return(p);
        }
        /// Converts the shape to a path, with Y=0
        //-----------------------------------------------------------------------
        //
        //ORIGINAL LINE: Path convertToPath() const
        public Path convertToPath() {
            Path p = new Path();
            //for (List<Vector2>.Enumerator it = mPoints.GetEnumerator(); it.MoveNext(); ++it)
            foreach (var it in mPoints) {
                p.addPoint(it.x, 0, it.y);
            }
            if (mClosed)
                p.close();

            return p;
        }
 public void buildFromSegmentSoup(std_vector<Segment3D> segList, ref std_vector<Path> @out)
 {
     //typedef std::multimap<Vector3, Vector3, Vector3Comparator> Vec3MultiMap;
     //Vec3MultiMap segs;
    std_multimap<Vector3,Vector3>segs=new std_multimap<Vector3,Vector3>(new Vector3Comparator());
    // for (std::vector<Segment3D>::const_iterator it = segList.begin(); it != segList.end(); ++it)
    foreach(var it in segList)
    {
         //segs.insert(std::pair<Vector3, Vector3 > (it->mA, it->mB));
         //segs.insert(std::pair<Vector3, Vector3 > (it->mB, it->mA));
        segs.insert(it.mA,it.mB);
        segs.insert(it.mB,it.mA);
     }
     while (!segs.empty())
     {
        Vector3 headFirst = segs.get(0).first;//segs.begin()->first;
         Vector3 headSecond = segs.get(0).second[0];//segs.begin()->second;
         Path p=new Path();
         p.addPoint(headFirst).addPoint(headSecond);
         //Vec3MultiMap::iterator firstSeg = segs.begin();
         int firstSeg_pos=segs.begin();
         Vector3 firstSeg=segs.get(0).first;
         //std::pair<Vec3MultiMap::iterator, Vec3MultiMap::iterator> correspondants2 = segs.equal_range(headSecond);
        std_pair<std_pair<Vector3,List<Vector3>>,std_pair<Vector3,List<Vector3>>>  correspondants2 = segs.equal_range(headSecond);
         //for (Vec3MultiMap::iterator it = correspondants2.first; it != correspondants2.second;)
         for(int i=correspondants2.first.second.Count-1;i>=0;i--)
         {
            // Vec3MultiMap::iterator removeIt = it++;
             Vector3 removeIt=correspondants2.first.second[i];
             //if ((removeIt->second - firstSeg->first).squaredLength() < 1e-8)
             if((removeIt-firstSeg).SquaredLength<1e-8)
                 segs.erase(removeIt);
         }
         segs.erase(firstSeg);
         bool foundSomething = true;
         while (!segs.empty() && foundSomething)
         {
             foundSomething = false;
             //Vec3MultiMap::iterator next = segs.find(headSecond);
             int next_pos = segs.find(headSecond);
             //if (next != segs.end())
             if(next_pos!=-1)
             {
                 std_pair<Vector3,List<Vector3>>next=segs.get((uint)next_pos);
                 foundSomething = true;
                 headSecond = next.second[0];
                 p.addPoint(headSecond);
                 //std::pair<Vec3MultiMap::iterator, Vec3MultiMap::iterator> correspondants = segs.equal_range(headSecond);
                 std_pair<std_pair<Vector3,List<Vector3>>,std_pair<Vector3,List<Vector3>>>correspondants = segs.equal_range(headSecond);
                 //for (Vec3MultiMap::iterator it = correspondants.first; it != correspondants.second;)
                 for (int i = correspondants.first.second.Count - 1; i >= 0;i-- ) {
                     //Vec3MultiMap::iterator removeIt = it++;
                     Vector3 removeIt = correspondants.first.second[i];
                     //if ((removeIt->second - next->first).squaredLength() < 1e-8)
                     if ((removeIt - next.first).SquaredLength < 1e-8)
                         segs.erase(removeIt);
                 }
                 //segs.erase(next);
                 segs.erase(next.first);
             }
             //Vec3MultiMap::iterator previous = segs.find(headFirst);
             int previous_pos=segs.find(headFirst);
             //if (previous != segs.end())
             if(previous_pos!=-1)
             {
                 std_pair<Vector3, List<Vector3>> previous = segs.get((uint)previous_pos);
                 foundSomething = true;
                 //p.insertPoint(0, previous.second);
                 p.insertPoint(0, previous.second[0]);//???
                 headFirst = previous.second[0];
                 //std::pair<Vec3MultiMap::iterator, Vec3MultiMap::iterator> correspondants = segs.equal_range(headFirst);
                 std_pair<std_pair<Vector3,List<Vector3>>,std_pair<Vector3,List<Vector3>>>correspondants = segs.equal_range(headFirst);
                 //for (Vec3MultiMap::iterator it = correspondants.first; it != correspondants.second;)
                 for(int i=correspondants.first.second.Count-1;i>=0;i--)
                 {
                     //Vec3MultiMap::iterator removeIt = it++;
                     Vector3 removeIt=correspondants.first.second[i];
                     //if ((removeIt->second - previous->first).squaredLength() < 1e-8)
                     if((removeIt-previous.first).SquaredLength<1e-8) 
                     segs.erase(removeIt);
                 }
                 //segs.erase(previous);
                 segs.erase(previous.first);
             }
         }
         if ((p.getPoint(0)-p.getPoint(p.getSegCount() + 1)).SquaredLength < 1e-6)
         {
             p.getPointsReference().pop_back();
             p.close();
         }
         @out.push_back(p);
     }
 }
 /// Extracts a part of the shape as a new path
 /// @param first first index to be in the new path
 /// @param last last index to be in the new path
 public Path extractSubPath(int first, int last) {//提取 抽出 抽取 
     Path p = new Path();
     for (int i = first; i < last; i++) {
         p.addPoint(mPoints[i]);
     }
     if (mClosed) {
         p.close();
     }
     return p;
 }
        /// Creates a path with the keys of this path and extra keys coming from a track
        //
        //ORIGINAL LINE: Path mergeKeysWithTrack(const Track& track) const
        public Path mergeKeysWithTrack(Track track) {
            if (!track.isInsertPoint() || track.getAddressingMode() == Track.AddressingMode.AM_POINT)
                return this;
            float totalLength = getTotalLength();

            float lineicPos = 0;
            float pathLineicPos = 0;
            Path outputPath = new Path();
            outputPath.addPoint(getPoint(0));
            for (int i = 1; i < mPoints.size(); ) {
                float nextLineicPos = pathLineicPos + (mPoints[i] - mPoints[i - 1]).Length;

                std_pair<float, float> it = track._getKeyValueAfter(lineicPos, lineicPos / totalLength, (uint)(i - 1));

                float nextTrackPos = it.first;
                if (track.getAddressingMode() == Track.AddressingMode.AM_RELATIVE_LINEIC)
                    nextTrackPos *= totalLength;

                // Adds the closest point to the curve, being either from the path or the track
                if (nextLineicPos <= nextTrackPos || lineicPos >= nextTrackPos) {
                    outputPath.addPoint(mPoints[i]);
                    i++;
                    lineicPos = nextLineicPos;
                    pathLineicPos = nextLineicPos;
                }
                else {
                    outputPath.addPoint(getPosition(i - 1, (nextTrackPos - pathLineicPos) / (nextLineicPos - pathLineicPos)));
                    lineicPos = nextTrackPos;
                }
            }
            return outputPath;
        }
Example #12
0
        public void buildFromSegmentSoup(std_vector <Segment3D> segList, ref std_vector <Path> @out)
        {
            //typedef std::multimap<Vector3, Vector3, Vector3Comparator> Vec3MultiMap;
            //Vec3MultiMap segs;
            std_multimap <Vector3, Vector3> segs = new std_multimap <Vector3, Vector3>(new Vector3Comparator());

            // for (std::vector<Segment3D>::const_iterator it = segList.begin(); it != segList.end(); ++it)
            foreach (var it in segList)
            {
                //segs.insert(std::pair<Vector3, Vector3 > (it->mA, it->mB));
                //segs.insert(std::pair<Vector3, Vector3 > (it->mB, it->mA));
                segs.insert(it.mA, it.mB);
                segs.insert(it.mB, it.mA);
            }
            while (!segs.empty())
            {
                Vector3 headFirst  = segs.get(0).first;     //segs.begin()->first;
                Vector3 headSecond = segs.get(0).second[0]; //segs.begin()->second;
                Path    p          = new Path();
                p.addPoint(headFirst).addPoint(headSecond);
                //Vec3MultiMap::iterator firstSeg = segs.begin();
                int     firstSeg_pos = segs.begin();
                Vector3 firstSeg     = segs.get(0).first;
                //std::pair<Vec3MultiMap::iterator, Vec3MultiMap::iterator> correspondants2 = segs.equal_range(headSecond);
                std_pair <std_pair <Vector3, List <Vector3> >, std_pair <Vector3, List <Vector3> > > correspondants2 = segs.equal_range(headSecond);
                //for (Vec3MultiMap::iterator it = correspondants2.first; it != correspondants2.second;)
                for (int i = correspondants2.first.second.Count - 1; i >= 0; i--)
                {
                    // Vec3MultiMap::iterator removeIt = it++;
                    Vector3 removeIt = correspondants2.first.second[i];
                    //if ((removeIt->second - firstSeg->first).squaredLength() < 1e-8)
                    if ((removeIt - firstSeg).SquaredLength < 1e-8)
                    {
                        segs.erase(removeIt);
                    }
                }
                segs.erase(firstSeg);
                bool foundSomething = true;
                while (!segs.empty() && foundSomething)
                {
                    foundSomething = false;
                    //Vec3MultiMap::iterator next = segs.find(headSecond);
                    int next_pos = segs.find(headSecond);
                    //if (next != segs.end())
                    if (next_pos != -1)
                    {
                        std_pair <Vector3, List <Vector3> > next = segs.get((uint)next_pos);
                        foundSomething = true;
                        headSecond     = next.second[0];
                        p.addPoint(headSecond);
                        //std::pair<Vec3MultiMap::iterator, Vec3MultiMap::iterator> correspondants = segs.equal_range(headSecond);
                        std_pair <std_pair <Vector3, List <Vector3> >, std_pair <Vector3, List <Vector3> > > correspondants = segs.equal_range(headSecond);
                        //for (Vec3MultiMap::iterator it = correspondants.first; it != correspondants.second;)
                        for (int i = correspondants.first.second.Count - 1; i >= 0; i--)
                        {
                            //Vec3MultiMap::iterator removeIt = it++;
                            Vector3 removeIt = correspondants.first.second[i];
                            //if ((removeIt->second - next->first).squaredLength() < 1e-8)
                            if ((removeIt - next.first).SquaredLength < 1e-8)
                            {
                                segs.erase(removeIt);
                            }
                        }
                        //segs.erase(next);
                        segs.erase(next.first);
                    }
                    //Vec3MultiMap::iterator previous = segs.find(headFirst);
                    int previous_pos = segs.find(headFirst);
                    //if (previous != segs.end())
                    if (previous_pos != -1)
                    {
                        std_pair <Vector3, List <Vector3> > previous = segs.get((uint)previous_pos);
                        foundSomething = true;
                        //p.insertPoint(0, previous.second);
                        p.insertPoint(0, previous.second[0]);//???
                        headFirst = previous.second[0];
                        //std::pair<Vec3MultiMap::iterator, Vec3MultiMap::iterator> correspondants = segs.equal_range(headFirst);
                        std_pair <std_pair <Vector3, List <Vector3> >, std_pair <Vector3, List <Vector3> > > correspondants = segs.equal_range(headFirst);
                        //for (Vec3MultiMap::iterator it = correspondants.first; it != correspondants.second;)
                        for (int i = correspondants.first.second.Count - 1; i >= 0; i--)
                        {
                            //Vec3MultiMap::iterator removeIt = it++;
                            Vector3 removeIt = correspondants.first.second[i];
                            //if ((removeIt->second - previous->first).squaredLength() < 1e-8)
                            if ((removeIt - previous.first).SquaredLength < 1e-8)
                            {
                                segs.erase(removeIt);
                            }
                        }
                        //segs.erase(previous);
                        segs.erase(previous.first);
                    }
                }
                if ((p.getPoint(0) - p.getPoint(p.getSegCount() + 1)).SquaredLength < 1e-6)
                {
                    p.getPointsReference().pop_back();
                    p.close();
                }
                @out.push_back(p);
            }
        }
        //    *
        //	 * Builds a shape from control points
        //	 * \exception Ogre::InvalidStateException The path contains no points
        //

        //-----------------------------------------------------------------------
        public Path realizePath()
        {
            if (mPoints.empty())
            {
                OGRE_EXCEPT("Ogre::Exception::ERR_INVALID_STATE", "The path contains no points", "Procedural::RoundedCornerSpline3::realizePath()");
            }
            ;

            Path path      = new Path();
            int  numPoints = mClosed ? mPoints.Count : (mPoints.Count - 2);

            if (!mClosed)
            {
                path.addPoint(mPoints[0]);
            }

            for (uint i = 0; i < numPoints; ++i)
            {
                Vector3 p0 = safeGetPoint(i);
                Vector3 p1 = safeGetPoint(i + 1);
                Vector3 p2 = safeGetPoint(i + 2);

                Vector3 vBegin = p1 - p0;
                Vector3 vEnd   = p2 - p1;

                // We're capping the radius if it's too big compared to segment length
                float radius            = mRadius;
                float smallestSegLength = System.Math.Min(vBegin.Length, vEnd.Length);
                if (smallestSegLength < 2 * mRadius)
                {
                    radius = smallestSegLength / 2.0f;
                }

                Vector3 pBegin = p1 - vBegin.NormalisedCopy * radius;
                Vector3 pEnd   = p1 + vEnd.NormalisedCopy * radius;
                Mogre_Procedural.Plane plane1 = new Plane(vBegin, pBegin);
                Mogre_Procedural.Plane plane2 = new Plane(vEnd, pEnd);
                Line axis = new Line();
                plane1.intersect(plane2, ref axis);

                Vector3    vradBegin  = axis.shortestPathToPoint(pBegin);
                Vector3    vradEnd    = axis.shortestPathToPoint(pEnd);
                Quaternion q          = vradBegin.GetRotationTo(vradEnd);
                Vector3    center     = pBegin - vradBegin;
                Radian     angleTotal = new Radian();
                Vector3    vAxis      = new Vector3();
                q.ToAngleAxis(out angleTotal, out vAxis);

                for (uint j = 0; j <= mNumSeg; j++)
                {
                    q.FromAngleAxis(angleTotal * (float)j / (float)mNumSeg, vAxis);
                    path.addPoint(center + q * vradBegin);
                }
            }

            if (!mClosed)
            {
                path.addPoint(mPoints[mPoints.size() - 1]);
            }

            if (mClosed)
            {
                path.close();
            }

            return(path);
        }