Пример #1
0
        //    *
        //	 * Builds the mesh into the given TriangleBuffer
        //	 * @param buffer The TriangleBuffer on where to append the mesh.
        //	 * @exception Ogre::InvalidStateException Either shape or multishape must be defined!
        //	 * @exception Ogre::InvalidStateException Required parameter is zero!
        //
        //-----------------------------------------------------------------------
        //
        //ORIGINAL LINE: void addToTriangleBuffer(TriangleBuffer& buffer) const
        public override void addToTriangleBuffer(ref TriangleBuffer buffer)
        {
            if (mMultiShapeToExtrude.getShapeCount() == 0)
            {
                OGRE_EXCEPT("Ogre::Exception::ERR_INVALID_STATE", "At least one shape must be defined!", "Procedural::Extruder::addToTriangleBuffer(Procedural::TriangleBuffer)");
            }
            ;

            // Triangulate the begin and end caps
            if (mCapped && mMultiShapeToExtrude.isClosed())
            {
                GlobalMembers._extrudeCapImpl(ref buffer, mMultiShapeToExtrude, mMultiExtrusionPath, mScaleTracks, mRotationTracks);
            }

            // Extrude the paths contained in multiExtrusionPath
            for (uint j = 0; j < mMultiExtrusionPath.getPathCount(); ++j)
            {
                Path  extrusionPath = mMultiExtrusionPath.getPath((int)j);
                Track rotationTrack = null;
                if (mRotationTracks.find(j) != -1)                                        // mRotationTracks.end()) {
                {
                    rotationTrack = mRotationTracks[j];                                   //mRotationTracks.find(j).second;
                    extrusionPath = extrusionPath.mergeKeysWithTrack(mRotationTracks[j]); // (*mRotationTracks.find(j).second);
                }
                Track scaleTrack = null;
                if (mScaleTracks.find(j) != -1)                                        // mScaleTracks.end()) {
                {
                    rotationTrack = mScaleTracks[j];                                   //mScaleTracks.find(j).second;
                    extrusionPath = extrusionPath.mergeKeysWithTrack(mScaleTracks[j]); // (*mScaleTracks.find(j).second);
                }
                Track pathTextureTrack = null;
                if (mPathTextureTracks.find(j) != -1)                                           // mPathTextureTracks.end()) {
                {
                    pathTextureTrack = mPathTextureTracks[j];                                   //mPathTextureTracks.find(j).second;
                    extrusionPath    = extrusionPath.mergeKeysWithTrack(mPathTextureTracks[j]); //(*mPathTextureTracks.find(j).second);
                }

                std_vector <std_pair <uint, uint> > segs = mMultiExtrusionPath.getNoIntersectionParts(j);

                //for (List<std.pair<uint, uint>>.Enumerator it = segs.GetEnumerator(); it.MoveNext(); ++it) {
                foreach (var it in segs)
                {
                    for (uint i = 0; i < mMultiShapeToExtrude.getShapeCount(); i++)
                    {
                        Shape shapeToExtrude    = mMultiShapeToExtrude.getShape(i);
                        Track shapeTextureTrack = null;
                        if (mShapeTextureTracks.find(i) != -1)          // mShapeTextureTracks.end()) {
                        {
                            shapeTextureTrack = mShapeTextureTracks[i]; //mShapeTextureTracks.find(i).second;
                            shapeToExtrude.mergeKeysWithTrack(shapeTextureTrack);
                        }
                        GlobalMembers._extrudeBodyImpl(ref buffer, shapeToExtrude, extrusionPath, (int)it.first, (int)it.second, shapeTextureTrack, rotationTrack, scaleTrack, pathTextureTrack);
                    }
                }

                // Make the intersections
                //typedef std::vector<PathCoordinate> PathIntersection;
                std_vector <std_vector <MultiPath.PathCoordinate> > intersections = mMultiExtrusionPath.getIntersections();
                //for (List<MultiPath.PathIntersection>.Enumerator it = intersections.GetEnumerator(); it.MoveNext(); ++it) {
                foreach (var it in intersections)
                {
                    for (uint i = 0; i < mMultiShapeToExtrude.getShapeCount(); i++)
                    {
                        Track shapeTextureTrack = null;
                        if (mShapeTextureTracks.find(i) != -1)          // mShapeTextureTracks.end())
                        {
                            shapeTextureTrack = mShapeTextureTracks[i]; //mShapeTextureTracks.find(i).second;
                        }
                        GlobalMembers._extrudeIntersectionImpl(ref buffer, it, mMultiExtrusionPath, mMultiShapeToExtrude.getShape(i), shapeTextureTrack);
                    }
                }
            }
        }
Пример #2
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;
                    }
                }
            }
        }