//--------------------------------------------------------------
        public void modify()
        {
            if (mInputTriangleBuffer == null)
            {
                OGRE_EXCEPT("Exception::ERR_INVALID_STATE", "Input triangle buffer must be set", "__FUNCTION__");
            }
            ;
            std_vector <TriangleBuffer.Vertex> newVertices    = new std_vector <TriangleBuffer.Vertex>();
            std_vector <TriangleBuffer.Vertex> originVertices = mInputTriangleBuffer.getVertices();
            std_vector <int> originIndices = mInputTriangleBuffer.getIndices();

            for (int i = 0; i < originIndices.size(); i += 3)
            {
                newVertices.push_back(originVertices[originIndices[i]]);
                newVertices.push_back(originVertices[originIndices[i + 1]]);
                newVertices.push_back(originVertices[originIndices[i + 2]]);
            }
            mInputTriangleBuffer.getVertices().clear();
            mInputTriangleBuffer.getVertices().reserve(newVertices.size());
            //for (List<TriangleBuffer.Vertex>.Enumerator it = newVertices.GetEnumerator(); it.MoveNext(); ++it)
            //	mInputTriangleBuffer.getVertices().push_back(it.Current);
            foreach (var it in newVertices)
            {
                mInputTriangleBuffer.getVertices().push_back(it);
            }
            mInputTriangleBuffer.getIndices().clear();
            mInputTriangleBuffer.getIndices().reserve(newVertices.size());
            for (int i = 0; i < newVertices.size(); i++)
            {
                mInputTriangleBuffer.getIndices().push_back(i);
            }
        }
 /// Copy constructor from an Ogre simplespline
 public CatmullRomSpline3(Mogre.SimpleSpline input)
 {
     mPoints.resize((int)input.NumPoints);
     for (ushort i = 0; i < input.NumPoints; i++)
     {
         mPoints.push_back(input.GetPoint(i));
     }
 }
Exemple #3
0
 public void append(TriangleBuffer other)
 {
     rebaseOffset();
     foreach (var it in other.mIndices)
     {
         mIndices.push_back(globalOffset + it);
     }
     foreach (var it in other.mVertices)
     {
         mVertices.push_back(it);
     }
 }
        //
        //ORIGINAL LINE: List<std::pair<uint, uint> > getNoIntersectionParts(uint pathIndex) const
        /// <summary>
        /// 获取非交集
        /// </summary>
        /// <param name="pathIndex"></param>
        /// <returns></returns>
        public std_vector <std_pair <uint, uint> > getNoIntersectionParts(uint pathIndex)
        {
            Path path = mPaths[(int)pathIndex];
            std_vector <std_pair <uint, uint> > result = new std_vector <std_pair <uint, uint> >();
            std_vector <int> intersections             = new std_vector <int>();

            //for (std.map<PathCoordinate, List<PathCoordinate>>.Enumerator it = mIntersectionsMap.begin(); it != mIntersectionsMap.end(); ++it) {
            foreach (var it in mIntersectionsMap)
            {
                if (it.Key.pathIndex == pathIndex)
                {
                    intersections.push_back((int)it.Key.pointIndex);
                }
            }
            //std.sort(intersections.GetEnumerator(), intersections.end());
            intersections.Sort((x, y) => {
                return(x - y);//正序排序(重写int比较器,|x|>|y|返回正数,|x|=|y|返回0,|x|<|y|返回负数)
            });
            //Array.Sort(intersections.ToArray());

            int begin = 0;

            //for (std::vector<int>::iterator it = intersections.begin(); it!= intersections.end(); ++it)
            //{
            //    if (*it-1>begin)
            //        result.push_back(std::pair<unsigned int, unsigned int>(begin, *it-1));
            //    begin = *it+1;
            //}
            //if (path.getSegCount() > begin)
            //    result.push_back(std::pair<unsigned int, unsigned int>(begin, path.getSegCount()));

            //for (List<int>.Enumerator it = intersections.GetEnumerator(); it.MoveNext(); ++it)
            foreach (var it in intersections)
            {
                if (it - 1 > begin)
                {
                    result.push_back(new std_pair <uint, uint>((uint)begin, (uint)it - 1));
                }
                begin = it + 1;
            }
            if (path.getSegCount() > begin)
            {
                result.push_back(new std_pair <uint, uint>((uint)begin, (uint)path.getSegCount()));
            }
            return(result);
        }
        //-----------------------------------------------------------------------
        /// <summary>
        /// 查找交集
        /// </summary>
        public void _calcIntersections()
        {
            mIntersectionsMap.Clear();
            mIntersections.Clear();
            //std::map<Ogre::Vector3, PathIntersection, Vector3Comparator> pointSet;
            std_map <Vector3, std_vector <PathCoordinate> > pointSet = new std_map <Vector3, std_vector <PathCoordinate> >(new Vector3Comparator());
            //       for (std::vector<Path>::iterator it = mPaths.begin(); it!= mPaths.end(); ++it)
            uint it_index = 0;

            foreach (var it in mPaths)
            {
                uint it_point_index = 0;
                //for (std::vector<Ogre::Vector3>::const_iterator it2 = it->getPoints().begin(); it2 != it->getPoints().end(); ++it2)
                foreach (var it2 in it._getPoints())
                {
                    //PathCoordinate pc(it-mPaths.begin(), it2-it->getPoints().begin());
                    PathCoordinate pc = new PathCoordinate(it_index, it_point_index);
                    //if (pointSet.find(*it2)==pointSet.end())
                    if (!pointSet.ContainsKey(it2))
                    {
                        std_vector <PathCoordinate> pi = new std_vector <PathCoordinate>();
                        pi.Add(pc);
                        //pointSet[it2] = pi;
                        pointSet.Add(it2, pi);
                    }
                    else
                    {
                        pointSet[it2].push_back(pc);
                    }

                    it_point_index++;
                }
                it_index++;
            }
            //for (std::map<Ogre::Vector3, PathIntersection, Vector3Comparator>::iterator it = pointSet.begin(); it != pointSet.end(); ++it)
            foreach (var it_ps in pointSet)
            {
                if (it_ps.Value.size() > 1)
                {
                    foreach (var it2 in it_ps.Value)
                    {
                        //mIntersectionsMap[*it2] = it->second;
                        if (mIntersectionsMap.ContainsKey(it2))
                        {
                            mIntersectionsMap[it2] = it_ps.Value;
                        }
                        else
                        {
                            mIntersectionsMap.Add(it2, it_ps.Value);
                        }
                    }
                    mIntersections.push_back(it_ps.Value);
                }
            }
            //
        }
 public static void computeCatmullRomPoints(Vector3 P1, Vector3 P2, Vector3 P3, Vector3 P4, uint numSeg, ref std_vector <Vector3> pointList)
 {
     for (uint j = 0; j < numSeg; ++j)
     {
         float   t  = (float)j / (float)numSeg;
         float   t2 = t * t;
         float   t3 = t * t2;
         Vector3 P  = 0.5f * ((-t3 + 2.0f * t2 - t) * P1 + (3.0f * t3 - 5.0f * t2 + 2.0f) * P2 + (-3.0f * t3 + 4.0f * t2 + t) * P3 + (t3 - t2) * P4);
         pointList.push_back(P);
     }
 }
        //C++ TO C# CONVERTER TODO TASK: The original C++ template specifier was replaced with a C# generic specifier, which may not produce the same behavior:
        //ORIGINAL LINE: template <class T>

        //public static void computeKochanekBartelsPoints<T>(KochanekBartelsSplineControlPoint<T> P1, KochanekBartelsSplineControlPoint<T> P2, KochanekBartelsSplineControlPoint<T> P3, KochanekBartelsSplineControlPoint<T> P4, uint numSeg, ref List<T> pointList) {
        //    Vector2 m0 = (1 - P2.tension) * (1 + P2.bias) * (1 + P2.continuity) / 2.0f * (P2.position - P1.position) + (1 - P2.tension) * (1 - P2.bias) * (1 - P2.continuity) / 2.0f * (P3.position - P2.position);
        //    Vector2 m1 = (1 - P3.tension) * (1 + P3.bias) * (1 - P3.continuity) / 2.0f * (P3.position - P2.position) + (1 - P3.tension) * (1 - P3.bias) * (1 + P3.continuity) / 2.0f * (P4.position - P3.position);

        //    for (uint j = 0; j < numSeg; ++j) {
        //        float t = (float)j / (float)numSeg;
        //        float t2 = t * t;
        //        float t3 = t2 * t;
        //        T P = (2 * t3 - 3 * t2 + 1) * P2.position + (t3 - 2 * t2 + t) * m0 + (-2 * t3 + 3 * t2) * P3.position + (t3 - t2) * m1;
        //        pointList.Add(P);
        //    }
        //}
        public static void computeKochanekBartelsPoints(KochanekBartelsSplineControlPoint <Vector2> P1, KochanekBartelsSplineControlPoint <Vector2> P2, KochanekBartelsSplineControlPoint <Vector2> P3, KochanekBartelsSplineControlPoint <Vector2> P4, uint numSeg, ref std_vector <Vector2> pointList)
        {
            Vector2 m0 = (1 - P2.tension) * (1 + P2.bias) * (1 + P2.continuity) / 2.0f * (P2.position - P1.position) + (1 - P2.tension) * (1 - P2.bias) * (1 - P2.continuity) / 2.0f * (P3.position - P2.position);
            Vector2 m1 = (1 - P3.tension) * (1 + P3.bias) * (1 - P3.continuity) / 2.0f * (P3.position - P2.position) + (1 - P3.tension) * (1 - P3.bias) * (1 + P3.continuity) / 2.0f * (P4.position - P3.position);

            for (uint j = 0; j < numSeg; ++j)
            {
                float   t  = (float)j / (float)numSeg;
                float   t2 = t * t;
                float   t3 = t2 * t;
                Vector2 P  = (2 * t3 - 3 * t2 + 1) * P2.position + (t3 - 2 * t2 + t) * m0 + (-2 * t3 + 3 * t2) * P3.position + (t3 - t2) * m1;
                pointList.push_back(P);
            }
        }
 /// Adds a control point
 public BezierCurve2 addPoint(Vector2 pt)
 {
     mPoints.push_back(pt);
     return(this);
 }
        //std_vector<std::string> split(const std::string& str, const std::string& delimiters, bool removeEmpty = true);
        std_vector<string> split(string str, string delimiters, bool removeEmpty) {
            std_vector<string> tokens = new std_vector<string>();
            //std::string::size_type delimPos = 0, tokenPos = 0, pos = 0;
            //int delimPos = 0, tokenPos = 0, pos = 0;
            //if (str.empty()) return tokens;
            if (string.IsNullOrEmpty(str)) return tokens;
            string[] strsplits = str.Split(delimiters.ToCharArray());
            foreach (var v in strsplits) {
                if (removeEmpty) {
                    if (!string.IsNullOrEmpty(v)) {
                        tokens.push_back(v);
                    }
                }
                else {
                    tokens.push_back(v);
                }
            }
            //while (true)
            //{
            //    delimPos = str.find_first_of(delimiters, pos);
            //    tokenPos = str.find_first_not_of(delimiters, pos);

            //    if (std::string::npos != delimPos)
            //    {
            //        if (std::string::npos != tokenPos)
            //        {
            //            if (tokenPos < delimPos)
            //                tokens.push_back(str.substr(pos,delimPos-pos));
            //            else
            //            {
            //                if (!removeEmpty) tokens.push_back("");
            //            }
            //        }
            //        else
            //        {
            //            if (!removeEmpty) tokens.push_back("");
            //        }
            //        pos = delimPos+1;
            //    }
            //    else
            //    {
            //        if (std::string::npos != tokenPos)
            //            tokens.push_back(str.substr(pos));
            //        else
            //        {
            //            if (!removeEmpty) tokens.push_back("");
            //        }
            //        break;
            //    }
            //}
            return tokens;
        }
 /// Adds a control point
 public CubicHermiteSpline2 addPoint(Vector2 p, Vector2 before, Vector2 after)
 {
     mPoints.push_back(new CubicHermiteSplineControlPoint <Vector2>(p, before, after));
     return(this);
 }
 /// Adds a control point
 public RoundedCornerSpline2 addPoint(Vector2 p)
 {
     mPoints.push_back(p);
     return(this);
 }
 /// Adds a control point
 public CatmullRomSpline2 addPoint(Vector2 pt)
 {
     mPoints.push_back(pt);
     return(this);
 }
 /// Adds a control point
 public KochanekBartelsSpline2 addPoint(float x, float y)
 {
     mPoints.push_back(new KochanekBartelsSplineControlPoint <Vector2>(new Vector2(x, y)));
     return(this);
 }
 //--------------------------------------------------------------
 public void modify() {
     if (mInputTriangleBuffer == null)
         OGRE_EXCEPT("Exception::ERR_INVALID_STATE", "Input triangle buffer must be set", "__FUNCTION__");
     ;
     std_vector<TriangleBuffer.Vertex> newVertices = new std_vector<TriangleBuffer.Vertex>();
     std_vector<TriangleBuffer.Vertex> originVertices = mInputTriangleBuffer.getVertices();
     std_vector<int> originIndices = mInputTriangleBuffer.getIndices();
     for (int i = 0; i < originIndices.size(); i += 3) {
         newVertices.push_back(originVertices[originIndices[i]]);
         newVertices.push_back(originVertices[originIndices[i + 1]]);
         newVertices.push_back(originVertices[originIndices[i + 2]]);
     }
     mInputTriangleBuffer.getVertices().clear();
     mInputTriangleBuffer.getVertices().reserve(newVertices.size());
     //for (List<TriangleBuffer.Vertex>.Enumerator it = newVertices.GetEnumerator(); it.MoveNext(); ++it)
     //	mInputTriangleBuffer.getVertices().push_back(it.Current);
     foreach (var it in newVertices) {
         mInputTriangleBuffer.getVertices().push_back(it);
     }
     mInputTriangleBuffer.getIndices().clear();
     mInputTriangleBuffer.getIndices().reserve(newVertices.size());
     for (int i = 0; i < newVertices.size(); i++)
         mInputTriangleBuffer.getIndices().push_back(i);
 }
 /// Adds a control point
 public CubicHermiteSpline3 addPoint(Vector3 p, Vector3 before, Vector3 after)
 {
     mPoints.push_back(new ControlPoint(p, before, after));
     return(this);
 }
Exemple #16
0
        //-----------------------------------------------------------------------

        public static void _retriangulate(ref TriangleBuffer newMesh, TriangleBuffer inputMesh, std_vector <Intersect> intersectionList, bool first)
        {
            std_vector <TriangleBuffer.Vertex> vec = inputMesh.getVertices();
            std_vector <int> ind = inputMesh.getIndices();
            // Triangulate
            //  Group intersections by triangle indice
            std_map <int, std_vector <Segment3D> > meshIntersects = new std_map <int, std_vector <Segment3D> >();

            //for (List<Intersect>.Enumerator it = intersectionList.GetEnumerator(); it.MoveNext(); ++it)
            foreach (var it in intersectionList)
            {
                int it2_find;
                if (first)
                {
                    it2_find = meshIntersects.find(it.mTri1);
                }
                else
                {
                    it2_find = meshIntersects.find(it.mTri2);
                }
                if (it2_find != -1)
                {
                    std_pair <int, std_vector <Segment3D> > it2 = meshIntersects.get((uint)it2_find);
                    it2.second.push_back(it.mSeg);
                }
                else
                {
                    std_vector <Segment3D> vec2 = new std_vector <Segment3D>();
                    vec2.push_back(it.mSeg);
                    if (first)
                    {
                        meshIntersects[it.mTri1] = vec2;
                    }
                    else
                    {
                        meshIntersects[it.mTri2] = vec2;
                    }
                }
            }
            // Build a new TriangleBuffer holding non-intersected triangles and retriangulated-intersected triangles
            //for (List<TriangleBuffer.Vertex>.Enumerator it = vec.GetEnumerator(); it.MoveNext(); ++it)
            foreach (var it in vec)
            {
                newMesh.vertex(it);
            }
            //for (int i = 0; i < (int)ind.Count / 3; i++)
            //    if (meshIntersects.find(i) == meshIntersects.end())
            //        newMesh.triangle(ind[i * 3], ind[i * 3 + 1], ind[i * 3 + 2]);
            for (int i = 0; i < (int)ind.size() / 3; i++)
            {
                if (meshIntersects.find(i) == -1)
                {
                    newMesh.triangle(ind[i * 3], ind[i * 3 + 1], ind[i * 3 + 2]);
                }
            }

            int numNonIntersected1 = newMesh.getIndices().size();

            //for (std.map<int, List<Segment3D> >.Enumerator it = meshIntersects.begin(); it.MoveNext(); ++it)
            foreach (var it in meshIntersects)
            {
                std_vector <Segment3D> segments = it.Value;
                int     triIndex    = it.Key;
                Vector3 v1          = vec[ind[triIndex * 3]].mPosition;
                Vector3 v2          = vec[ind[triIndex * 3 + 1]].mPosition;
                Vector3 v3          = vec[ind[triIndex * 3 + 2]].mPosition;
                Vector3 triNormal   = ((v2 - v1).CrossProduct(v3 - v1)).NormalisedCopy;
                Vector3 xAxis       = triNormal.Perpendicular;
                Vector3 yAxis       = triNormal.CrossProduct(xAxis);
                Vector3 planeOrigin = vec[ind[triIndex * 3]].mPosition;

                // Project intersection segments onto triangle plane
                std_vector <Segment2D> segments2 = new std_vector <Segment2D>();

                //for (List<Segment3D>.Enumerator it2 = segments.GetEnumerator(); it2.MoveNext(); it2++)
                //    segments2.Add(projectOnAxis(it2.Current, planeOrigin, xAxis, yAxis));
                foreach (var it2 in segments)
                {
                    segments2.push_back(projectOnAxis(it2, planeOrigin, xAxis, yAxis));
                }
                //for (List<Segment2D>.Enumerator it2 = segments2.GetEnumerator(); it2.MoveNext();)
                int it2_c = segments2.Count;
                for (int j = it2_c - 1; j >= 0; j--)
                {
                    Segment2D it2 = segments2[j];
                    if ((it2.mA - it2.mB).SquaredLength < 1e-5)
                    {
                        //C++ TO C# CONVERTER TODO TASK: There is no direct equivalent to the STL vector 'erase' method in C#:
                        //it2 = segments2.erase(it2);
                        segments2.RemoveAt(j);
                    }
                    //else
                }
                // Triangulate
                Triangulator t = new Triangulator();
                //Triangle2D[[]] tri = new Triangle2D[ind[triIndex * 3]](projectOnAxis(vec.mPosition, planeOrigin, xAxis, yAxis), projectOnAxis(vec[ind[triIndex * 3 + 1]].mPosition, planeOrigin, xAxis, yAxis), projectOnAxis(vec[ind[triIndex * 3 + 2]].mPosition, planeOrigin, xAxis, yAxis));
                Triangle2D tri = new Triangle2D(projectOnAxis(vec[ind[triIndex * 3]].mPosition, planeOrigin, xAxis, yAxis),
                                                projectOnAxis(vec[ind[triIndex * 3 + 1]].mPosition, planeOrigin, xAxis, yAxis),
                                                projectOnAxis(vec[ind[triIndex * 3 + 2]].mPosition, planeOrigin, xAxis, yAxis));
                std_vector <Vector2> outPointList = new std_vector <Vector2>();//PointList outPointList;
                std_vector <int>     outIndice    = new std_vector <int>();
                t.setManualSuperTriangle(tri).setRemoveOutside(false).setSegmentListToTriangulate(ref segments2).triangulate(outIndice, outPointList);

                // Deproject and add to triangleBuffer
                newMesh.rebaseOffset();
                //for (List<int>.Enumerator it = outIndice.GetEnumerator(); it.MoveNext(); ++it)
                //    newMesh.index(it.Current);
                foreach (var oindex in outIndice)
                {
                    newMesh.index(oindex);
                }
                float   x1  = tri.mPoints[0].x;
                float   y1  = tri.mPoints[0].y;
                Vector2 uv1 = vec[ind[triIndex * 3]].mUV;
                float   x2  = tri.mPoints[1].x;
                float   y2  = tri.mPoints[1].y;
                Vector2 uv2 = vec[ind[triIndex * 3 + 1]].mUV;
                float   x3  = tri.mPoints[2].x;
                float   y3  = tri.mPoints[2].y;
                Vector2 uv3 = vec[ind[triIndex * 3 + 2]].mUV;
                float   DET = x1 * y2 - x2 * y1 + x2 * y3 - x3 * y2 + x3 * y1 - x1 * y3;
                Vector2 A   = ((y2 - y3) * uv1 + (y3 - y1) * uv2 + (y1 - y2) * uv3) / DET;
                Vector2 B   = ((x3 - x2) * uv1 + (x1 - x3) * uv2 + (x2 - x1) * uv3) / DET;
                Vector2 C   = ((x2 * y3 - x3 * y2) * uv1 + (x3 * y1 - x1 * y3) * uv2 + (x1 * y2 - x2 * y1) * uv3) / DET;

                //for (List<Vector2>.Enumerator it = outPointList.GetEnumerator(); it.MoveNext(); ++it)
                foreach (var it2 in outPointList)
                {
                    Vector2 uv = A * it2.x + B * it2.y + C;
                    newMesh.position(deprojectOnAxis(it2, planeOrigin, xAxis, yAxis));
                    newMesh.normal(triNormal);
                    newMesh.textureCoord(uv);
                }
            }
        }
Exemple #17
0
        //    *
        //	 * Builds the mesh into the given TriangleBuffer
        //	 * @param buffer The TriangleBuffer on where to append the mesh.
        //
        //
        //ORIGINAL LINE: void addToTriangleBuffer(TriangleBuffer& buffer) const
        public override void addToTriangleBuffer(ref TriangleBuffer buffer)
        {
            std_vector <Vector3> vertices = new  std_vector <Vector3>();
            int offset = 0;

            /// Step 1 : Generate icosahedron
            float phi     = 0.5f * (1.0f + Math.Sqrt(5.0f));
            float invnorm = 1f / Math.Sqrt(phi * phi + 1f);

            vertices.push_back(invnorm * new Vector3(-1f, phi, 0f));  //0
            vertices.push_back(invnorm * new Vector3(1f, phi, 0f));   //1
            vertices.push_back(invnorm * new Vector3(0f, 1f, -phi));  //2
            vertices.push_back(invnorm * new Vector3(0f, 1f, phi));   //3
            vertices.push_back(invnorm * new Vector3(-phi, 0f, -1f)); //4
            vertices.push_back(invnorm * new Vector3(-phi, 0f, 1f));  //5
            vertices.push_back(invnorm * new Vector3(phi, 0f, -1f));  //6
            vertices.push_back(invnorm * new Vector3(phi, 0f, 1f));   //7
            vertices.push_back(invnorm * new Vector3(0f, -1f, -phi)); //8
            vertices.push_back(invnorm * new Vector3(0f, -1f, phi));  //9
            vertices.push_back(invnorm * new Vector3(-1f, -phi, 0f)); //10
            vertices.push_back(invnorm * new Vector3(1f, -phi, 0f));  //11

            int[] firstFaces = { 0,   1,  2,
                                 0,   3,  1,
                                 0,   4,  5,
                                 1,   7,  6,
                                 1,   6,  2,
                                 1,   3,  7,
                                 0,   2,  4,
                                 0,   5,  3,
                                 2,   6,  8,
                                 2,   8,  4,
                                 3,   5,  9,
                                 3,   9,  7,
                                 11,  6,  7,
                                 10,  5,  4,
                                 10,  4,  8,
                                 10,  9,  5,
                                 11,  8,  6,
                                 11,  7,  9,
                                 10,  8, 11,
                                 10, 11, 9 };

            //C++ TO C# CONVERTER WARNING: This 'sizeof' ratio was replaced with a direct reference to the array length:
            //ORIGINAL LINE: std::vector<int> faces(firstFaces, firstFaces + sizeof(firstFaces)/sizeof(*firstFaces));
            // 定义一个容纳100个int型数据的容器,初值赋为0
            //vector<int> vecMyHouse(100,0);
            std_vector <int> faces = new  std_vector <int>(firstFaces);//(firstFaces, firstFaces + firstFaces.Length);

            int size = 60;

            /// Step 2 : tessellate
            for (ushort iteration = 0; iteration < mNumIterations; iteration++)
            {
                size *= 4;
                std_vector <int> newFaces = new std_vector <int>();
                newFaces.Clear();
                //newFaces.resize(size);
                for (int i = 0; i < size / 12; i++)
                {
                    int     i1  = faces[i * 3];
                    int     i2  = faces[i * 3 + 1];
                    int     i3  = faces[i * 3 + 2];
                    int     i12 = vertices.Count;
                    int     i23 = i12 + 1;
                    int     i13 = i12 + 2;
                    Vector3 v1  = vertices[i1];
                    Vector3 v2  = vertices[i2];
                    Vector3 v3  = vertices[i3];
                    //make 1 vertice at the center of each edge and project it onto the sphere
                    vertices.push_back((v1 + v2).NormalisedCopy);
                    vertices.push_back((v2 + v3).NormalisedCopy);
                    vertices.push_back((v1 + v3).NormalisedCopy);
                    //now recreate indices
                    newFaces.push_back(i1);
                    newFaces.push_back(i12);
                    newFaces.push_back(i13);
                    newFaces.push_back(i2);
                    newFaces.push_back(i23);
                    newFaces.push_back(i12);
                    newFaces.push_back(i3);
                    newFaces.push_back(i13);
                    newFaces.push_back(i23);
                    newFaces.push_back(i12);
                    newFaces.push_back(i23);
                    newFaces.push_back(i13);
                }
                //faces.swap(newFaces);
                faces = newFaces;
            }

            /// Step 3 : generate texcoords
            std_vector <Vector2> texCoords = new std_vector <Vector2>();

            for (ushort i = 0; i < vertices.size(); i++)
            {
                Vector3 vec   = vertices[i];
                float   u     = 0f;
                float   v     = 0f;
                float   r0    = sqrtf(vec.x * vec.x + vec.z * vec.z);
                float   alpha = 0f;
                alpha = atan2f(vec.z, vec.x);
                u     = alpha / Math.TWO_PI + .5f;
                v     = atan2f(vec.y, r0) / Math.PI + .5f;
                texCoords.push_back(new Vector2(u, v));
            }

            /// Step 4 : fix texcoords
            // find vertices to split
            std_vector <int> indexToSplit = new  std_vector <int>();

            for (int i = 0; i < faces.size() / 3; i++)
            {
                Vector2 t0 = texCoords[faces[i * 3 + 0]];
                Vector2 t1 = texCoords[faces[i * 3 + 1]];
                Vector2 t2 = texCoords[faces[i * 3 + 2]];
                if (Math.Abs(t2.x - t0.x) > 0.5)
                {
                    if (t0.x < 0.5)
                    {
                        indexToSplit.push_back(faces[i * 3]);
                    }
                    else
                    {
                        indexToSplit.push_back(faces[i * 3 + 2]);
                    }
                }
                if (Math.Abs(t1.x - t0.x) > 0.5)
                {
                    if (t0.x < 0.5)
                    {
                        indexToSplit.push_back(faces[i * 3]);
                    }
                    else
                    {
                        indexToSplit.push_back(faces[i * 3 + 1]);
                    }
                }
                if (Math.Abs(t2.x - t1.x) > 0.5)
                {
                    if (t1.x < 0.5)
                    {
                        indexToSplit.push_back(faces[i * 3 + 1]);
                    }
                    else
                    {
                        indexToSplit.push_back(faces[i * 3 + 2]);
                    }
                }
            }

            //split vertices
            for (ushort i = 0; i < indexToSplit.size(); i++)
            {
                int index = indexToSplit[i];
                //duplicate vertex
                Vector3 v = vertices[index];
                Vector2 t = texCoords[index] + Vector2.UNIT_X;
                vertices.push_back(v);
                texCoords.push_back(t);
                int newIndex = vertices.size() - 1;
                //reassign indices
                for (ushort j = 0; j < faces.size(); j++)
                {
                    if (faces[j] == index)
                    {
                        int index1 = faces[(j + 1) % 3 + (j / 3) * 3];
                        int index2 = faces[(j + 2) % 3 + (j / 3) * 3];
                        if ((texCoords[index1].x > 0.5f) || (texCoords[index2].x > 0.5f))
                        {
                            faces[j] = newIndex;
                        }
                    }
                }
            }

            /// Step 5 : realize
            buffer.rebaseOffset();
            buffer.estimateVertexCount((uint)vertices.size());
            buffer.estimateIndexCount((uint)size);

            for (ushort i = 0; i < vertices.size(); i++)
            {
                addPoint(ref buffer, mRadius * vertices[i], vertices[i], new Vector2(texCoords[i].x, texCoords[i].y));
            }
            for (ushort i = 0; i < size; i++)
            {
                buffer.index(offset + faces[i]);
            }
            offset += vertices.size();
        }
 public MultiPath addPath(Path path)
 {
     mPaths.push_back(path);
     return(this);
 }
 //* Adds a point to the path, as a Vector3
 public Path addPoint(Vector3 pt)
 {
     mPoints.push_back(pt);
     return(this);
 }
        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);
            }
        }
            // SvgLoaderPath(std::vector<std::string> p, unsigned int ns);
            public SvgLoaderPath(std_vector <string> p, uint ns)
            {
                parts   = p;
                mNumSeg = ns;
                px      = 0.0f;
                py      = 0.0f;
                index   = 0;
                char lastCmd = (char)0;

                while (index < p.Count)
                {
                    try {
                        char newCmd = parts[index][0];
                        bool next   = true;
                        if (lastCmd != newCmd && newCmd != '.' && newCmd != '-' && (newCmd < '0' || newCmd > '9') && curve.size() > 3 && ((lastCmd == 'c' || lastCmd == 'C') && (newCmd == 's' || newCmd == 'S') || (lastCmd == 'q' || lastCmd == 'Q') && (newCmd == 't' || newCmd == 'T')))
                        {
                            // finish curve
                            finishCurve(lastCmd);
                        }
                        switch (newCmd)
                        {
                        case 'l':
                            parseLineTo(true, next);
                            break;

                        case 'L':
                            parseLineTo(false, next);
                            break;

                        case 'm':
                            parseMoveTo(true, next);
                            newCmd = 'l';
                            break;

                        case 'M':
                            parseMoveTo(false, next);
                            newCmd = 'L';
                            break;

                        case 'h':
                            parseHLineTo(true, next);
                            break;

                        case 'H':
                            parseHLineTo(false, next);
                            break;

                        case 'v':
                            parseVLineTo(true, next);
                            break;

                        case 'V':
                            parseVLineTo(false, next);
                            break;

                        case 'c':
                            curve.push_back(point);
                            parseCurveCTo(true, next);
                            break;

                        case 'C':
                            curve.push_back(point);
                            parseCurveCTo(false, next);
                            break;

                        case 's':
                            parseCurveSTo(true, next);
                            break;

                        case 'S':
                            parseCurveSTo(false, next);
                            break;

                        case 'q':
                            curve.push_back(point);
                            parseCurveQTo(true, next);
                            break;

                        case 'Q':
                            curve.push_back(point);
                            parseCurveQTo(false, next);
                            break;

                        case 't':
                            parseCurveTTo(true, next);
                            break;

                        case 'T':
                            parseCurveTTo(false, next);
                            break;

                        case 'a':
                            parseArcTo(true, next);
                            break;

                        case 'A':
                            parseArcTo(false, next);
                            break;

                        case 'z':
                        case 'Z':
                            shape.close();
                            index++;
                            break;

                        default:
                            newCmd = lastCmd;
                            next   = false;
                            switch (lastCmd)
                            {
                            case 'l':
                                parseLineTo(true, next);
                                break;

                            case 'L':
                                parseLineTo(false, next);
                                break;

                            case 'm':
                                parseMoveTo(true, next);
                                break;

                            case 'M':
                                parseMoveTo(false, next);
                                break;

                            case 'h':
                                parseHLineTo(true, next);
                                break;

                            case 'H':
                                parseHLineTo(false, next);
                                break;

                            case 'v':
                                parseVLineTo(true, next);
                                break;

                            case 'V':
                                parseVLineTo(false, next);
                                break;

                            case 'c':
                                parseCurveCTo(true, next);
                                break;

                            case 'C':
                                parseCurveCTo(false, next);
                                break;

                            case 's':
                                parseCurveSTo(true, next);
                                break;

                            case 'S':
                                parseCurveSTo(false, next);
                                break;

                            case 'q':
                                parseCurveQTo(true, next);
                                break;

                            case 'Q':
                                parseCurveQTo(false, next);
                                break;

                            case 't':
                                parseCurveTTo(true, next);
                                break;

                            case 'T':
                                parseCurveTTo(false, next);
                                break;

                            case 'a':
                                parseArcTo(true, next);
                                break;

                            case 'A':
                                parseArcTo(false, next);
                                break;

                            default:
                                break;
                            }
                            break;
                        }
                        lastCmd = newCmd;
                    }
                    catch {
                    }
                }
                if (curve.size() > 0)
                {
                    finishCurve(lastCmd);
                }
            }
        //std_vector<std::string> split(const std::string& str, const std::string& delimiters, bool removeEmpty = true);
        std_vector <string> split(string str, string delimiters, bool removeEmpty)
        {
            std_vector <string> tokens = new std_vector <string>();

            //std::string::size_type delimPos = 0, tokenPos = 0, pos = 0;
            //int delimPos = 0, tokenPos = 0, pos = 0;
            //if (str.empty()) return tokens;
            if (string.IsNullOrEmpty(str))
            {
                return(tokens);
            }
            string[] strsplits = str.Split(delimiters.ToCharArray());
            foreach (var v in strsplits)
            {
                if (removeEmpty)
                {
                    if (!string.IsNullOrEmpty(v))
                    {
                        tokens.push_back(v);
                    }
                }
                else
                {
                    tokens.push_back(v);
                }
            }
            //while (true)
            //{
            //    delimPos = str.find_first_of(delimiters, pos);
            //    tokenPos = str.find_first_not_of(delimiters, pos);

            //    if (std::string::npos != delimPos)
            //    {
            //        if (std::string::npos != tokenPos)
            //        {
            //            if (tokenPos < delimPos)
            //                tokens.push_back(str.substr(pos,delimPos-pos));
            //            else
            //            {
            //                if (!removeEmpty) tokens.push_back("");
            //            }
            //        }
            //        else
            //        {
            //            if (!removeEmpty) tokens.push_back("");
            //        }
            //        pos = delimPos+1;
            //    }
            //    else
            //    {
            //        if (std::string::npos != tokenPos)
            //            tokens.push_back(str.substr(pos));
            //        else
            //        {
            //            if (!removeEmpty) tokens.push_back("");
            //        }
            //        break;
            //    }
            //}
            return(tokens);
        }
        //-----------------------------------------------------------------------
        //typedef std::vector<PathCoordinate> PathIntersection;
        public static void _extrudeIntersectionImpl(ref TriangleBuffer buffer, std_vector <MultiPath.PathCoordinate> intersection, MultiPath multiPath, Shape shape, Track shapeTextureTrack)
        {
            Vector3    intersectionLocation = multiPath.getPath((int)intersection[0].pathIndex).getPoint((int)intersection[0].pointIndex);
            Quaternion firstOrientation     = Utils._computeQuaternion(multiPath.getPath((int)intersection[0].pathIndex).getDirectionBefore((int)intersection[0].pointIndex));
            Vector3    refX = firstOrientation * Vector3.UNIT_X;
            Vector3    refZ = firstOrientation * Vector3.UNIT_Z;

            std_vector <Vector2> v2s = new std_vector <Vector2>();
            std_vector <MultiPath.PathCoordinate> coords = new std_vector <MultiPath.PathCoordinate>();
            std_vector <float> direction = new std_vector <float>();

            for (int i = 0; i < intersection.size(); ++i)
            {
                Path path       = multiPath.getPath((int)intersection[i].pathIndex);
                int  pointIndex = (int)intersection[i].pointIndex;
                if (pointIndex > 0 || path.isClosed())
                {
                    Vector3 vb  = path.getDirectionBefore(pointIndex);
                    Vector2 vb2 = new Vector2(vb.DotProduct(refX), vb.DotProduct(refZ));
                    v2s.push_back(vb2);
                    coords.push_back(intersection[i]);
                    direction.push_back(1);
                }
                if (pointIndex < path.getSegCount() || path.isClosed())
                {
                    Vector3 va  = -path.getDirectionAfter(pointIndex);
                    Vector2 va2 = new Vector2(va.DotProduct(refX), va.DotProduct(refZ));
                    v2s.push_back(va2);
                    coords.push_back(intersection[i]);
                    direction.push_back(-1);
                }
            }

            std_map <Radian, int> angles = new std_map <Radian, int>();

            for (int i = 1; i < v2s.Count; ++i)
            {
                //angles[Utils.angleTo(v2s[0], v2s[i])] = i;
                angles.insert(Utils.angleTo(v2s[0], v2s[i]), i);
            }
            std_vector <int> orderedIndices = new std_vector <int>();

            orderedIndices.push_back(0);
            //for (std_map<Radian, int>.Enumerator it = angles.begin(); it != angles.end(); ++it)
            foreach (var it in angles)
            {
                orderedIndices.push_back(it.Value);
            }
            for (int i = 0; i < orderedIndices.size(); ++i)
            {
                int    idx         = orderedIndices[i];
                int    idxBefore   = orderedIndices[Utils.modulo(i - 1, orderedIndices.Count)];
                int    idxAfter    = orderedIndices[Utils.modulo(i + 1, orderedIndices.Count)];
                Radian angleBefore = (Utils.angleBetween(v2s[idx], v2s[idxBefore]) - (Radian)Math.PI) / 2;
                Radian angleAfter  = ((Radian)Math.PI - Utils.angleBetween(v2s[idx], v2s[idxAfter])) / 2;

                int  pointIndex = (int)((int)coords[idx].pointIndex - direction[idx]);
                Path path       = multiPath.getPath((int)coords[idx].pathIndex);

                Quaternion qStd      = Utils._computeQuaternion(path.getAvgDirection(pointIndex) * direction[idx]);
                float      lineicPos = 0f;
                float      uTexCoord = path.getLengthAtPoint(pointIndex) / path.getTotalLength();

                // Shape making the joint with "standard extrusion"
                _extrudeShape(ref buffer, shape, path.getPoint(pointIndex), qStd, qStd, 1.0f, 1.0f, 1.0f, shape.getTotalLength(), uTexCoord, true, shapeTextureTrack);

                // Modified shape at the intersection
                Quaternion q = new Quaternion();
                if (direction[idx] > 0f)
                {
                    q = Utils._computeQuaternion(path.getDirectionBefore((int)coords[idx].pointIndex));
                }
                else
                {
                    q = Utils._computeQuaternion(-path.getDirectionAfter((int)coords[idx].pointIndex));
                }
                Quaternion qLeft      = q * new Quaternion(angleBefore, Vector3.UNIT_Y);
                Quaternion qRight     = q * new Quaternion(angleAfter, Vector3.UNIT_Y);
                float      scaleLeft  = 1.0f / Math.Abs(Math.Cos(angleBefore));
                float      scaleRight = 1.0f / Math.Abs(Math.Cos(angleAfter));

                uTexCoord = path.getLengthAtPoint((int)coords[idx].pointIndex) / path.getTotalLength();
                _extrudeShape(ref buffer, shape, path.getPoint((int)coords[idx].pointIndex), qLeft, qRight, 1.0f, scaleLeft, scaleRight, shape.getTotalLength(), uTexCoord, false, shapeTextureTrack);
            }
        }
        //
        //ORIGINAL LINE: List<std::pair<uint, uint> > getNoIntersectionParts(uint pathIndex) const
        /// <summary>
        /// 获取非交集
        /// </summary>
        /// <param name="pathIndex"></param>
        /// <returns></returns>
        public std_vector<std_pair<uint, uint>> getNoIntersectionParts(uint pathIndex) {
            Path path = mPaths[(int)pathIndex];
            std_vector<std_pair<uint, uint>> result = new std_vector<std_pair<uint, uint>>();
            std_vector<int> intersections = new std_vector<int>();
            //for (std.map<PathCoordinate, List<PathCoordinate>>.Enumerator it = mIntersectionsMap.begin(); it != mIntersectionsMap.end(); ++it) {
            foreach (var it in mIntersectionsMap) {
                if (it.Key.pathIndex == pathIndex) {
                    intersections.push_back((int)it.Key.pointIndex);
                }
            }
            //std.sort(intersections.GetEnumerator(), intersections.end());
            intersections.Sort((x, y) => {
                return x - y;//正序排序(重写int比较器,|x|>|y|返回正数,|x|=|y|返回0,|x|<|y|返回负数)  
            });
            //Array.Sort(intersections.ToArray());

            int begin = 0;
            //for (std::vector<int>::iterator it = intersections.begin(); it!= intersections.end(); ++it)
            //{
            //    if (*it-1>begin)
            //        result.push_back(std::pair<unsigned int, unsigned int>(begin, *it-1));
            //    begin = *it+1;
            //}
            //if (path.getSegCount() > begin)
            //    result.push_back(std::pair<unsigned int, unsigned int>(begin, path.getSegCount()));

            //for (List<int>.Enumerator it = intersections.GetEnumerator(); it.MoveNext(); ++it)
            foreach (var it in intersections) {
                if (it - 1 > begin)
                    result.push_back(new std_pair<uint, uint>((uint)begin, (uint)it - 1));
                begin = it + 1;
            }
            if (path.getSegCount() > begin)
                result.push_back(new std_pair<uint, uint>((uint)begin, (uint)path.getSegCount()));
            return result;
        }
Exemple #25
0
        void _addConstraints(ref DelaunayTriangleBuffer tbuffer, PointList pl, std_vector <int> segmentListIndices)
        {
            std_vector <DelaunaySegment> segList = new std_vector <DelaunaySegment>();

            //Utils::log("a co");
            //for (DelaunayTriangleBuffer::iterator it = tbuffer.begin(); it!=tbuffer.end();it++)
            //	Utils::log(it->debugDescription());

            // First, list all the segments that are not already in one of the delaunay triangles
            //for (std::vector<int>::const_iterator it2 = segmentListIndices.begin(); it2 != segmentListIndices.end(); it2++)
            for (int i = 0; i < segmentListIndices.Count; i++)
            {
                //int i1 = *it2;
                int i1 = segmentListIndices[i];
                //it2++;
                i++;
                //int i2 = *it2;
                int i2 = segmentListIndices[i];

                bool isAlreadyIn = false;
                //for (DelaunayTriangleBuffer::iterator it = tbuffer.begin(); it!=tbuffer.end(); ++it)
                foreach (var it in tbuffer)
                {
                    if (it.containsSegment(i1, i2))
                    {
                        isAlreadyIn = true;
                        break;
                    }
                }
                // only do something for segments not already in DT
                if (!isAlreadyIn)
                {
                    segList.push_back(new DelaunaySegment(i1, i2));
                }
            }

            // Re-Triangulate according to the new segments
            //for (std::vector<DelaunaySegment>::iterator itSeg=segList.begin(); itSeg!=segList.end(); itSeg++)
            for (int ii = segList.Count - 1; ii >= 0; ii--)
            {
                DelaunaySegment itSeg = segList[ii];
                //Utils::log("itseg " + StringConverter::toString(itSeg->i1) + "," + StringConverter::toString(itSeg->i2) + " " + StringConverter::toString(pl[itSeg->i1]) + "," + StringConverter::toString(pl[itSeg->i2]));
                // Remove all triangles intersecting the segment and keep a list of outside edges
                std_set <DelaunaySegment> segments = new std_set <DelaunaySegment>();
                Segment2D seg1 = new Segment2D(pl[itSeg.i1], pl[itSeg.i2]);
                //for (DelaunayTriangleBuffer::iterator itTri = tbuffer.begin(); itTri!=tbuffer.end(); )
                for (int jj = tbuffer.Count - 1; jj >= 0; jj--)
                {
                    Triangle itTri = tbuffer.getElement(jj).Value;
                    bool     isTriangleIntersected = false;
                    bool     isDegenerate          = false;
                    int      degenIndex;
                    for (int i = 0; i < 3; i++)
                    {
                        //Early out if 2 points are in fact the same
                        if (itTri.i[i] == itSeg.i1 || itTri.i[i] == itSeg.i2 || itTri.i[(i + 1) % 3] == itSeg.i1 || itTri.i[(i + 1) % 3] == itSeg.i2)
                        {
                            if (itTri.isDegenerate())
                            {
                                if (itTri.i[i] == itSeg.i1 || itTri.i[(i + 1) % 3] == itSeg.i1)
                                {
                                    degenIndex = itSeg.i1;
                                }
                                else if (itTri.i[i] == itSeg.i2 || itTri.i[(i + 1) % 3] == itSeg.i2)
                                {
                                    degenIndex = itSeg.i2;
                                }
                                isTriangleIntersected = true;
                                isDegenerate          = true;
                            }
                            else
                            {
                                continue;
                            }
                        }
                        Segment2D seg2 = new Segment2D(itTri.p(i), itTri.p((i + 1) % 3));
                        if (seg1.intersects(seg2))
                        {
                            isTriangleIntersected = true;
                            break;
                        }
                    }
                    if (isTriangleIntersected)
                    {
                        //if (isDegenerate)
                        //Utils::log("degen " + itTri->debugDescription());
                        for (int k = 0; k < 3; k++)
                        {
                            DelaunaySegment d1 = new DelaunaySegment(itTri.i[k], itTri.i[(k + 1) % 3]);
                            if (segments.find(d1) != segments.end())
                            {
                                segments.erase(d1);
                            }
                            else if (segments.find(d1.inverse()) != segments.end())
                            {
                                segments.erase(d1.inverse());
                            }
                            else
                            {
                                segments.insert(d1);
                            }
                        }
                        //itTri=tbuffer.erase(itTri);
                        tbuffer.erase(jj);
                    }
                    //else
                    //	itTri++;
                }

                // Divide the list of points (coming from remaining segments) in 2 groups : "above" and "below"
                std_vector <int> pointsAbove = new std_vector <int>();
                std_vector <int> pointsBelow = new std_vector <int>();
                int  pt      = itSeg.i1;
                bool isAbove = true;
                while (segments.size() > 0)
                {
                    //find next point
                    //for (std::set<DelaunaySegment>::iterator it = segments.begin(); it!=segments.end(); ++it)
                    DelaunaySegment[] segments_all = segments.get_allocator();
                    for (int i = 0; i < segments_all.Length; ++i)
                    {
                        DelaunaySegment it = segments_all[i];//segments.find(i,true);
                        if (it.i1 == pt || it.i2 == pt)
                        {
                            //Utils::log("next " + StringConverter::toString(pt));

                            if (it.i1 == pt)
                            {
                                pt = it.i2;
                            }
                            else
                            {
                                pt = it.i1;
                            }
                            segments.erase(it);
                            if (pt == itSeg.i2)
                            {
                                isAbove = false;
                            }
                            else if (pt != itSeg.i1)
                            {
                                if (isAbove)
                                {
                                    pointsAbove.push_back(pt);
                                }
                                else
                                {
                                    pointsBelow.push_back(pt);
                                }
                            }
                            break;
                        }
                    }
                }

                // Recursively triangulate both polygons
                _recursiveTriangulatePolygon(itSeg, pointsAbove, tbuffer, pl);
                _recursiveTriangulatePolygon(itSeg.inverse(), pointsBelow, tbuffer, pl);
            }
            // Clean up segments outside of multishape
            if (mRemoveOutside)
            {
                if (mMultiShapeToTriangulate != null && mMultiShapeToTriangulate.isClosed())
                {
                    //for (DelaunayTriangleBuffer::iterator it = tbuffer.begin(); it!=tbuffer.end();)
                    for (int i = tbuffer.Count - 1; i >= 0; i--)
                    {
                        Triangle it            = tbuffer.getElement(i).Value;
                        bool     isTriangleOut = !mMultiShapeToTriangulate.isPointInside(it.getMidPoint());

                        if (isTriangleOut)
                        {
                            //it = tbuffer.erase(it);
                            tbuffer.erase(i);
                        }
                        //else
                        //	++it;
                    }
                }
                else if (mShapeToTriangulate != null && mShapeToTriangulate.isClosed())
                {
                    //for (DelaunayTriangleBuffer::iterator it = tbuffer.begin(); it!=tbuffer.end();)
                    for (int i = tbuffer.Count - 1; i >= 0; i--)
                    {
                        Triangle it            = tbuffer.getElement(i).Value;
                        bool     isTriangleOut = !mShapeToTriangulate.isPointInside(it.getMidPoint());

                        if (isTriangleOut)
                        {
                            //it = tbuffer.erase(it);
                            tbuffer.erase(i);
                        }
                        //else
                        //	++it;
                    }
                }
            }
        }
Exemple #26
0
        //-----------------------------------------------------------------------

        //
        //ORIGINAL LINE: void addToTriangleBuffer(TriangleBuffer& buffer) const
        public override void addToTriangleBuffer(ref TriangleBuffer buffer)
        {
            std_vector <TriangleBuffer.Vertex> vec1 = mMesh1.getVertices();
            std_vector <int> ind1 = mMesh1.getIndices();
            std_vector <TriangleBuffer.Vertex> vec2 = mMesh2.getVertices();
            std_vector <int> ind2 = mMesh2.getIndices();
            Segment3D        intersectionResult = new Segment3D();

            std_vector <Intersect> intersectionList = new std_vector <Intersect>();

            // Find all intersections between mMesh1 and mMesh2
            int idx1 = 0;

            //for (std::vector<int>::const_iterator it = ind1.begin(); it != ind1.end(); idx1++)
            for (int i = 0; i < ind1.Count; i += 3, idx1++)
            {
                int it = ind1[i];
                //Triangle3D t1(vec1[*it++].mPosition, vec1[*it++].mPosition, vec1[*it++].mPosition);
                Triangle3D t1   = new Triangle3D(vec1[it].mPosition, vec1[it + 1].mPosition, vec1[it + 2].mPosition);
                int        idx2 = 0;
                //for (std::vector<int>::const_iterator it2 = ind2.begin(); it2 != ind2.end(); idx2++)
                for (int j = 0; j < ind2.Count; j += 3, idx2++)
                {
                    int it2 = ind2[j];
                    //Triangle3D t2(vec2[*it2++].mPosition, vec2[*it2++].mPosition, vec2[*it2++].mPosition);
                    Triangle3D t2 = new Triangle3D(vec2[it2].mPosition, vec2[it2 + 1].mPosition, vec2[it2 + 2].mPosition);
                    if (t1.findIntersect(t2, ref intersectionResult))
                    {
                        Intersect intersect = new Intersect(intersectionResult, idx1, idx2);
                        intersectionList.push_back(intersect);
                    }
                }
            }
            // Remove all intersection segments too small to be relevant
            //for (std::vector<Intersect>::iterator it = intersectionList.begin(); it != intersectionList.end();)
            //    if ((it.mSeg.mB - it.mSeg.mA).squaredLength() < 1e-8)
            //        it = intersectionList.erase(it);
            //    else
            //        ++it;
            for (int i = intersectionList.Count - 1; i >= 0; i--)
            {
                Intersect it = intersectionList[i];
                if ((it.mSeg.mB - it.mSeg.mA).SquaredLength < 1e-8)
                {
                    intersectionList.erase((uint)i);
                }
            }


            // Retriangulate
            TriangleBuffer newMesh1 = new TriangleBuffer();
            TriangleBuffer newMesh2 = new TriangleBuffer();

            GlobalMembersProceduralBoolean._retriangulate(ref newMesh1, mMesh1, intersectionList, true);
            GlobalMembersProceduralBoolean._retriangulate(ref newMesh2, mMesh2, intersectionList, false);

            //buffer.append(newMesh1);
            //buffer.append(newMesh2);
            //return;

            // Trace contours
            std_vector <Path>      contours    = new std_vector <Path>();
            std_vector <Segment3D> segmentSoup = new std_vector <Segment3D>();

            //for (std::vector<Intersect>::iterator it = intersectionList.begin(); it != intersectionList.end(); ++it)
            foreach (var it in intersectionList)
            {
                segmentSoup.push_back(it.mSeg);
            }
            new Path().buildFromSegmentSoup(segmentSoup, ref contours);

            // Build a lookup from segment to triangle
            TriLookup triLookup1 = new std_multimap <Segment3D, int>(new Seg3Comparator()), triLookup2 = new std_multimap <Segment3D, int>(new Seg3Comparator());

            GlobalMembersProceduralBoolean._buildTriLookup(ref triLookup1, newMesh1);
            GlobalMembersProceduralBoolean._buildTriLookup(ref triLookup2, newMesh2);

            std_set <Segment3D> limits = new std_set <Segment3D>(new Seg3Comparator());

            //for (std::vector<Segment3D>::iterator it = segmentSoup.begin(); it != segmentSoup.end(); ++it)
            foreach (var it in segmentSoup)
            {
                limits.insert(it.orderedCopy());
            }
            // Build resulting mesh
            //for (std::vector<Path>::iterator it = contours.begin(); it != contours.end(); ++it)
            foreach (var it in contours)
            {
                // Find 2 seed triangles for each contour
                Segment3D firstSeg = new Segment3D(it.getPoint(0), it.getPoint(1));
                //std_pair<TriLookup::iterator, TriLookup::iterator> it2mesh1 = triLookup1.equal_range(firstSeg.orderedCopy());
                //std_pair<TriLookup::iterator, TriLookup::iterator> it2mesh2 = triLookup2.equal_range(firstSeg.orderedCopy());
                std_pair <std_pair <Segment3D, List <int> >, std_pair <Segment3D, List <int> > > it2mesh1 = triLookup1.equal_range(firstSeg.orderedCopy());
                std_pair <std_pair <Segment3D, List <int> >, std_pair <Segment3D, List <int> > > it2mesh2 = triLookup2.equal_range(firstSeg.orderedCopy());
                int mesh1seed1 = 0, mesh1seed2 = 0, mesh2seed1 = 0, mesh2seed2 = 0;

                //if (it2mesh1.first != triLookup1.end() && it2mesh2.first != triLookup2.end())
                if (it2mesh1.first != null && it2mesh2.first != null)
                {
                    // check which of seed1 and seed2 must be included (it can be 0, 1 or both)
                    //mesh1seed1 = it2mesh1.first.second;
                    //mesh1seed2 = (--it2mesh1.second).second;
                    //mesh2seed1 = it2mesh2.first.second;
                    //mesh2seed2 = (--it2mesh2.second).second;
                    mesh1seed1 = it2mesh1.first.second[0];
                    mesh1seed2 = it2mesh1.first.second[it2mesh1.first.second.Count - 1]; //(--it2mesh1.second).second[0];
                    mesh2seed1 = it2mesh2.first.second[0];
                    mesh2seed2 = it2mesh2.first.second[it2mesh2.first.second.Count - 1]; //(--it2mesh2.second).second[0];

                    if (mesh1seed1 == mesh1seed2)
                    {
                        mesh1seed2 = -1;
                    }
                    if (mesh2seed1 == mesh2seed2)
                    {
                        mesh2seed2 = -1;
                    }

                    Vector3 vMesh1 = new Vector3(0f, 0f, 0f), nMesh1 = new Vector3(0f, 0f, 0f), vMesh2 = new Vector3(0f, 0f, 0f), nMesh2 = new Vector3(0f, 0f, 0f);
                    for (int i = 0; i < 3; i++)
                    {
                        Vector3 pos = newMesh1.getVertices()[newMesh1.getIndices()[mesh1seed1 * 3 + i]].mPosition;
                        if ((pos - firstSeg.mA).SquaredLength > 1e-6 && (pos - firstSeg.mB).SquaredLength > 1e-6)
                        {
                            vMesh1 = pos;
                            nMesh1 = newMesh1.getVertices()[newMesh1.getIndices()[mesh1seed1 * 3 + i]].mNormal;
                            break;
                        }
                    }

                    for (int i = 0; i < 3; i++)
                    {
                        Vector3 pos = newMesh2.getVertices()[newMesh2.getIndices()[mesh2seed1 * 3 + i]].mPosition;
                        if ((pos - firstSeg.mA).SquaredLength > 1e-6 && (pos - firstSeg.mB).SquaredLength > 1e-6)
                        {
                            vMesh2 = pos;
                            nMesh2 = newMesh2.getVertices()[newMesh2.getIndices()[mesh2seed1 * 3 + i]].mNormal;
                            break;
                        }
                    }

                    bool M2S1InsideM1 = (nMesh1.DotProduct(vMesh2 - firstSeg.mA) < 0f);
                    bool M1S1InsideM2 = (nMesh2.DotProduct(vMesh1 - firstSeg.mA) < 0f);

                    GlobalMembersProceduralBoolean._removeFromTriLookup(mesh1seed1, ref triLookup1);
                    GlobalMembersProceduralBoolean._removeFromTriLookup(mesh2seed1, ref triLookup2);
                    GlobalMembersProceduralBoolean._removeFromTriLookup(mesh1seed2, ref triLookup1);
                    GlobalMembersProceduralBoolean._removeFromTriLookup(mesh2seed2, ref triLookup2);

                    // Recursively add all neighbours of these triangles
                    // Stop when a contour is touched
                    switch (mBooleanOperation)
                    {
                    case BooleanOperation.BT_UNION:
                        if (M1S1InsideM2)
                        {
                            GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh1, mesh1seed2, ref triLookup1, limits, false);
                        }
                        else
                        {
                            GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh1, mesh1seed1, ref triLookup1, limits, false);
                        }
                        if (M2S1InsideM1)
                        {
                            GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh2, mesh2seed2, ref triLookup2, limits, false);
                        }
                        else
                        {
                            GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh2, mesh2seed1, ref triLookup2, limits, false);
                        }
                        break;

                    case BooleanOperation.BT_INTERSECTION:
                        if (M1S1InsideM2)
                        {
                            GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh1, mesh1seed1, ref triLookup1, limits, false);
                        }
                        else
                        {
                            GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh1, mesh1seed2, ref triLookup1, limits, false);
                        }
                        if (M2S1InsideM1)
                        {
                            GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh2, mesh2seed1, ref triLookup2, limits, false);
                        }
                        else
                        {
                            GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh2, mesh2seed2, ref triLookup2, limits, false);
                        }
                        break;

                    case BooleanOperation.BT_DIFFERENCE:
                        if (M1S1InsideM2)
                        {
                            GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh1, mesh1seed2, ref triLookup1, limits, false);
                        }
                        else
                        {
                            GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh1, mesh1seed1, ref triLookup1, limits, false);
                        }
                        if (M2S1InsideM1)
                        {
                            GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh2, mesh2seed1, ref triLookup2, limits, true);
                        }
                        else
                        {
                            GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh2, mesh2seed2, ref triLookup2, limits, true);
                        }
                        break;
                    }
                }
            }
        }
 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);
     }
 }
Exemple #28
0
        //    *
        //	 * Executes the Constrained Delaunay Triangulation algorithm
        //	 * @param output A vector of index where is outputed the resulting triangle indexes
        //	 * @param outputVertices A vector of vertices where is outputed the resulting triangle vertices
        //	 * @exception Ogre::InvalidStateException Either shape or multishape or segment list must be defined
        //
        //void triangulate(ref List<int>& output, ref List<Vector2>& outputVertices) const;
        public void triangulate(std_vector <int> output, PointList outputVertices)
        {
            if (mShapeToTriangulate == null && mMultiShapeToTriangulate == null && mSegmentListToTriangulate == null)
            {
                throw new NullReferenceException("Ogre::Exception::ERR_INVALID_STATE," + "Either shape or multishape or segment list must be defined!" + ",  Procedural::Triangulator::triangulate(std::vector<int>&, PointList&)");
            }
            //Ogre::Timer mTimer;
            //Mogre.Timer mTimer = new Timer();
            //mTimer.Reset();
            DelaunayTriangleBuffer dtb = new std_list <Triangle>();
            // Do the Delaunay triangulation
            std_vector <int> segmentListIndices = new std_vector <int>();

            if (mShapeToTriangulate != null)
            {
                outputVertices = new std_vector <Vector2>(mShapeToTriangulate.getPoints());
                for (int i = 0; i < mShapeToTriangulate.getSegCount(); ++i)
                {
                    segmentListIndices.push_back(i);
                    segmentListIndices.push_back(mShapeToTriangulate.getBoundedIndex(i + 1));
                }
            }
            else if (mMultiShapeToTriangulate != null)
            {
                outputVertices = new std_vector <Vector2>(mMultiShapeToTriangulate.getPoints());
                int index = 0;
                for (int i = 0; i < mMultiShapeToTriangulate.getShapeCount(); ++i)
                {
                    Shape shape = mMultiShapeToTriangulate.getShape((uint)i);
                    for (int j = 0; j < shape.getSegCount(); j++)
                    {
                        segmentListIndices.push_back(index + j);
                        segmentListIndices.push_back(index + shape.getBoundedIndex(j + 1));
                    }
                    index += shape.getSegCount();
                }
            }
            else if (mSegmentListToTriangulate != null)
            {
                //std_map<Vector2, int, Vector2Comparator> backMap;
                std_map <Vector2, int> backMap = new std_map <Vector2, int>(new Vector2Comparator());
                //for (std::vector<Segment2D>::iterator it = mSegmentListToTriangulate->begin(); it!= mSegmentListToTriangulate->end(); it++)
                foreach (var it in mSegmentListToTriangulate)
                {
                    if ((it.mA - it.mB).SquaredLength < 1e-6)
                    {
                        continue;
                    }

                    //std::map<Vector2, int, Vector2Comparator>::iterator it2 = backMap.find(it->mA);
                    int it2_pos = backMap.find(it.mA);
                    //if (it2 != backMap.end())
                    if (it2_pos != -1)
                    {
                        //segmentListIndices.push_back(it2->second);
                        segmentListIndices.push_back(backMap[it.mA]);
                    }
                    else
                    {
                        //backMap[it->mA] = outputVertices.size();
                        backMap.insert(it.mA, outputVertices.size());
                        segmentListIndices.push_back(outputVertices.size());
                        outputVertices.push_back(it.mA);
                    }

                    //it2 = backMap.find(it.mB);
                    it2_pos = backMap.find(it.mB);
                    //if (it2 != backMap.end())
                    if (it2_pos != -1)
                    {
                        //segmentListIndices.push_back(it2.second);
                        segmentListIndices.push_back(backMap[it.mB]);
                    }
                    else
                    {
                        //backMap[it->mB] = outputVertices.size();
                        backMap.insert(it.mB, outputVertices.size());
                        segmentListIndices.push_back(outputVertices.size());
                        outputVertices.push_back(it.mB);
                    }
                }

                if (mManualSuperTriangle != null)
                {
                    Triangle superTriangle = new Triangle(outputVertices);
                    for (int i = 0; i < 3; i++)
                    {
                        //std::map<Vector2, int, Vector2Comparator>::iterator it = backMap.find(mManualSuperTriangle->mPoints[i]);
                        int it_pos = backMap.find(mManualSuperTriangle.mPoints[i]);
                        //if (it != backMap.end())
                        if (it_pos != -1)
                        {
                            //segmentListIndices.push_back(it->second);
                            //superTriangle.i[i] = it->second;
                            superTriangle.i[i] = backMap[mManualSuperTriangle.mPoints[i]];
                        }
                        else
                        {
                            //backMap[mManualSuperTriangle->mPoints[i]] = outputVertices.size();
                            backMap.insert(mManualSuperTriangle.mPoints[i], outputVertices.size());
                            //segmentListIndices.push_back(outputVertices.size());
                            superTriangle.i[i] = outputVertices.size();
                            outputVertices.push_back(mManualSuperTriangle.mPoints[i]);
                        }
                    }

                    dtb.push_back(superTriangle);
                }
            }
            //Utils::log("Triangulator preparation : " + StringConverter::toString(mTimer.getMicroseconds() / 1000.0f) + " ms");
            delaunay(outputVertices, ref dtb);
            //Utils::log("Triangulator delaunay : " + StringConverter::toString(mTimer.getMicroseconds() / 1000.0f) + " ms");
            // Add contraints
            _addConstraints(ref dtb, outputVertices, segmentListIndices);
            //Utils::log("Triangulator constraints : " + StringConverter::toString(mTimer.getMicroseconds() / 1000.0f) + " ms");
            //Outputs index buffer
            //for (DelaunayTriangleBuffer::iterator it = dtb.begin(); it!=dtb.end(); ++it)
            foreach (var it in dtb)
            {
                if (!it.isDegenerate())
                {
                    output.push_back(it.i[0]);
                    output.push_back(it.i[1]);
                    output.push_back(it.i[2]);
                }
            }
            // Remove super triangle
            if (mRemoveOutside)
            {
                outputVertices.pop_back();
                outputVertices.pop_back();
                outputVertices.pop_back();
            }
            //Utils::log("Triangulator output : " + StringConverter::toString(mTimer.getMicroseconds() / 1000.0f) + " ms");
        }
        //-----------------------------------------------------------------------
        //
        //ORIGINAL LINE: void _findAllIntersections(const Shape& STLAllocator<U, AllocPolicy>, List<IntersectionInShape>& intersections) const
        private void _findAllIntersections(Shape other, ref std_vector<IntersectionInShape> intersections) {
            for (ushort i = 0; i < getSegCount(); i++) {
                Segment2D seg1 = new Segment2D(getPoint(i), getPoint(i + 1));

                for (ushort j = 0; j < other.getSegCount(); j++) {
                    Segment2D seg2 = new Segment2D(other.getPoint(j), other.getPoint(j + 1));

                    Vector2 intersect = new Vector2();
                    if (seg1.findIntersect(seg2, ref intersect)) {
                        IntersectionInShape inter = new IntersectionInShape(i, j, intersect);
                        // check if intersection is "borderline" : too near to a vertex
                        if ((seg1.mA - intersect).SquaredLength < 1e-8) {
                            inter.onVertex[0] = true;
                        }
                        if ((seg1.mB - intersect).SquaredLength < 1e-8) {
                            inter.onVertex[0] = true;
                            inter.index[0]++;
                        }
                        if ((seg2.mA - intersect).SquaredLength < 1e-8) {
                            inter.onVertex[1] = true;
                        }
                        if ((seg2.mB - intersect).SquaredLength < 1e-8) {
                            inter.onVertex[1] = true;
                            inter.index[1]++;
                        }

                        intersections.push_back(inter);
                    }
                }
            }
        }
Exemple #30
0
 /// Constructor from a single shape
 public MultiShape(Shape shape)
 {
     mShapes.push_back(shape);
 }