//--------------------------------------------------------------
        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);
            }
        }
        //    *
        //	 * Builds a shape from control points
        //
        //-----------------------------------------------------------------------
        //Shape KochanekBartelsSpline2::realizeShape()
        public Shape realizeShape()
        {
            Shape shape = new Shape();

            int numPoints = mClosed ? mPoints.size() : (mPoints.size() - 1);

            for (uint i = 0; i < numPoints; ++i)
            {
                ControlPoint2        P1 = safeGetPoint(i - 1);
                ControlPoint2        P2 = safeGetPoint(i);
                ControlPoint2        P3 = safeGetPoint(i + 1);
                ControlPoint2        P4 = safeGetPoint(i + 2);
                std_vector <Vector2> shape_getPointsReference = shape.getPointsReference();
                GlobalMembers.computeKochanekBartelsPoints(P1, P2, P3, P4, mNumSeg, ref shape_getPointsReference);

                if (i == mPoints.size() - 2 && !mClosed)
                {
                    shape.addPoint(P3.position);
                }
            }
            if (mClosed)
            {
                shape.close();
            }
            shape.setOutSide(mOutSide);
            return(shape);
        }
        //    *
        //	 * Builds a path from control points
        //
        //-----------------------------------------------------------------------
        public Path realizePath()
        {
            Path path = new Path();

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

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

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

            return(path);
        }
        //    *
        //	 * Build a shape from bezier control points
        //	 * @exception Ogre::InvalidStateException The curve must at least contain 2 points
        //

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

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

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

            Shape shape = new Shape();
            float t     = 0.0f;

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

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

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

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

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

            return(path);
        }
示例#6
0
 //    * Safely gets a given point.
 //	 * Takes into account whether the path is closed or not.
 //	 * @param i the index of the point.
 //	 *          if it is <0 or >maxPoint, cycle through the list of points
 //
 //
 //ORIGINAL LINE: const Ogre::Vector3& getPoint(int i) const
 public Vector3 getPoint(int i)
 {
     if (mClosed)
     {
         return(mPoints[Utils.modulo(i, mPoints.size())]);
     }
     return(mPoints[Utils.cap(i, 0, mPoints.size() - 1)]);
 }
        //    *
        //	 * Build a path from bezier control points
        //	 * @exception Ogre::InvalidStateException The curve must at least contain 2 points
        //

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

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

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

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

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

            return(path);
        }
 /// Safely gets a control point
 //
 //ORIGINAL LINE: inline const CubicHermiteSplineControlPoint<Ogre::Vector2>& safeGetPoint(uint i) const
 public CubicHermiteSplineControlPoint <Vector2> safeGetPoint(int i)
 {
     if (mClosed)
     {
         return(mPoints[Utils.modulo((int)i, mPoints.size())]);
     }
     return(mPoints[Utils.cap((int)i, 0, mPoints.size() - 1)]);
 }
示例#9
0
 //-----------------------------------------------------------------------
 void parsePolygon(ref MultiShape @out, XmlNode pPolygonNode)
 {
     //if (pPolygonNode->first_attribute("points"))
     if (pPolygonNode.Attributes["points"] != null)
     {
         //if (pPolygonNode->first_attribute("points")->value_size() < 3) return;
         if (string.IsNullOrEmpty(pPolygonNode.Attributes["points"].Value))
         {
             return;
         }
         if (pPolygonNode.Attributes["points"].Value.Length < 3)
         {
             return;
         }
         string temp             = xtrim(pPolygonNode.Attributes["points"].Value);
         std_vector <string> pts = split(temp, " ");
         if (pts.size() == 0)
         {
             return;
         }
         Shape s = new Shape();
         for (int i = 0; i < pts.size() - 1; i += 2)
         {
             s.addPoint(parseReal(pts[i + 0]), parseReal(pts[i + 1]));
         }
         if (s.getPointsReference().size() == 0)
         {
             return;
         }
         s.close();
         //		if(pPolygonNode->first_attribute("id"))
         //		ss.id = pPolygonNode->first_attribute("id")->value();
         s.translate(getAttribTranslate(pPolygonNode));
         @out.addShape(s);
     }
 }
示例#10
0
 /// Applies normal inversion on the triangle buffer
 public TriangleBuffer invertNormals()
 {
     foreach (var it in mVertices)
     {
         it.mNormal = -it.mNormal;
     }
     for (int i = 0; i < mIndices.size(); ++i)
     {
         if (i % 3 == 1)
         {
             //std::swap(mIndices[i], mIndices[i-1]);
             list_swap <int>(mIndices, i, i - 1);
         }
     }
     return(this);
 }
示例#11
0
        //-----------------------------------------------------------------------
        void parsePath(ref MultiShape @out, XmlNode pPathNode)
        {
            //if (pPathNode->first_attribute("d"))
            if (pPathNode.Attributes["d"] != null)
            {
                string temp = xtrim(pPathNode.Attributes["d"].Value, " .-0123456789mMlLhHvVcCsSqQtTaAzZ");
                std_vector <string> parts = split(temp, " ");
                for (int i = 0; i < parts.size(); i++)
                {
                    if (parts[i].Length > 1 && !(parts[i][0] == '-' || ('0' <= parts[i][0] && parts[i][0] <= '9')))
                    {
                        parts.insert(parts.begin() + i + 1, parts[i] + 1);
                        //parts[i].erase(1, parts[i].size());
                        parts[i] = parts[i].Remove(1);
                    }
                }

                SvgLoaderPath sp = new SvgLoaderPath(parts, mNumSeg);
                if (!sp.isValid())
                {
                    return;
                }
                Shape   ss   = sp.getSvgShape();
                Vector2 line = ss.getPoint(1) - ss.getPoint(0);
                //Real deg = line.angleBetween(ss.getPoint(2) - ss.getPoint(0)).valueDegrees();
                float deg = Utils.angleBetween(line, ss.getPoint(2) - ss.getPoint(0)).ValueDegrees;
                if ((0 <= deg && deg <= 180.0f) || (-180.0f <= deg && deg <= 0))
                {
                    ss.setOutSide(Side.SIDE_LEFT);
                }
                else
                {
                    ss.setOutSide(Side.SIDE_RIGHT);
                }

                //if(pPathNode->first_attribute("id"))
                //	ss.id = pPathNode->first_attribute("id")->value();
                ss.translate(getAttribTranslate(pPathNode));
                @out.addShape(ss);
            }
        }
示例#12
0
        //    *
        //	 * Builds the mesh into the given TriangleBuffer
        //	 * @param buffer The TriangleBuffer on where to append the mesh.
        //
        //void addToTriangleBuffer(ref TriangleBuffer& buffer) const;
        //-----------------------------------------------------------------------
        //void Triangulator::addToTriangleBuffer(TriangleBuffer& buffer) const
        public override void addToTriangleBuffer(ref TriangleBuffer buffer)
        {
            PointList        pointList   = new std_vector <Vector2>();
            std_vector <int> indexBuffer = new std_vector <int>();

            triangulate(indexBuffer, pointList);
            for (int j = 0; j < pointList.size(); j++)
            {
                Vector2 vp2    = pointList[j];
                Vector3 vp     = new Vector3(vp2.x, vp2.y, 0f);
                Vector3 normal = -Vector3.UNIT_Z;

                addPoint(ref buffer, vp, normal, new Vector2(vp2.x, vp2.y));
            }

            for (int i = 0; i < indexBuffer.size() / 3; i++)
            {
                buffer.index(indexBuffer[i * 3]);
                buffer.index(indexBuffer[i * 3 + 2]);
                buffer.index(indexBuffer[i * 3 + 1]);
            }
        }
示例#13
0
 //-----------------------------------------------------------------------
 Vector2 getAttribTranslate(XmlNode pNode)
 {
     //if (pNode->first_attribute("transform"))
     if (pNode.Attributes["transform"] != null)
     {
         string temp  = (pNode.Attributes["transform"].Value);
         int    begin = temp.IndexOf("translate(");//temp.find("translate(");
         //if (begin==std::string::npos)
         if (begin == -1)
         {
             return(Vector2.ZERO);
         }
         begin += 10;
         int end = temp.IndexOf(")");//temp.find(")", begin);
         //if (end == std::string::npos)
         if (end == -1)
         {
             return(Vector2.ZERO);
         }
         //std::string temp2 = temp.substr(begin, end-begin);
         string temp2 = temp.Substring(begin, end - begin);
         //std::vector<std::string> parts = split(xtrim(temp2.c_str()), std::string(" "));
         std_vector <string> parts = split(xtrim(temp2), " ");
         if (parts.size() == 2)
         {
             return(new Vector2(parseReal(parts[0]), parseReal(parts[1])));//return Vector2(StringConverter::parseReal(parts[0]), StringConverter::parseReal(parts[1]));
         }
         else
         {
             return(Vector2.ZERO);
         }
     }
     else
     {
         return(Vector2.ZERO);
     }
 }
        //-----------------------------------------------------------------------
        public static void _extrudeCapImpl(ref TriangleBuffer buffer, MultiShape multiShapeToExtrude, MultiPath extrusionMultiPath, TrackMap scaleTracks, TrackMap rotationTracks)
        {
            std_vector <int> indexBuffer = new std_vector <int>();
            // PointList pointList;
            std_vector <Vector2> pointList = new std_vector <Vector2>();

            Triangulator t = new Triangulator();

            t.setMultiShapeToTriangulate(multiShapeToExtrude);
            t.triangulate(indexBuffer, pointList);

            for (uint i = 0; i < extrusionMultiPath.getPathCount(); ++i)
            {
                Path  extrusionPath = extrusionMultiPath.getPath((int)i);
                Track scaleTrack    = null;
                Track rotationTrack = null;
                if (scaleTracks.find(i) != -1)         // scaleTracks.end())
                {
                    scaleTrack = scaleTracks[i];       //.find(i).second;
                }
                if (rotationTracks.find(i) != -1)      // rotationTracks.end())
                {
                    rotationTrack = rotationTracks[i]; //.find(i).second;
                }
                //begin cap
                //if (extrusionMultiPath.getIntersectionsMap().find(MultiPath.PathCoordinate(i, 0)) == extrusionMultiPath.getIntersectionsMap().end())
                if (extrusionMultiPath.getIntersectionsMap().find(new MultiPath.PathCoordinate(i, 0)) == -1)
                {
                    buffer.rebaseOffset();
                    buffer.estimateIndexCount((uint)indexBuffer.Count);
                    buffer.estimateVertexCount((uint)pointList.Count);

                    Quaternion qBegin = Utils._computeQuaternion(extrusionPath.getDirectionAfter(0));
                    if (rotationTrack != null)
                    {
                        float angle = rotationTrack.getFirstValue();
                        qBegin = qBegin * new Quaternion((Radian)angle, Vector3.UNIT_Z);
                    }
                    float scaleBegin = 1.0f;
                    if (scaleTrack != null)
                    {
                        scaleBegin = scaleTrack.getFirstValue();
                    }

                    for (int j = 0; j < pointList.size(); j++)
                    {
                        Vector2 vp2    = pointList[j];
                        Vector3 vp     = new Vector3(vp2.x, vp2.y, 0);
                        Vector3 normal = -Vector3.UNIT_Z;

                        Vector3 newPoint = extrusionPath.getPoint(0) + qBegin * (scaleBegin * vp);
                        buffer.vertex(newPoint, qBegin * normal, vp2);
                    }
                    for (int i2 = 0; i2 < indexBuffer.Count / 3; i2++)
                    {
                        buffer.index(indexBuffer[i2 * 3]);
                        buffer.index(indexBuffer[i2 * 3 + 2]);
                        buffer.index(indexBuffer[i2 * 3 + 1]);
                    }
                }

                //end cap
                //if (extrusionMultiPath.getIntersectionsMap().find(MultiPath.PathCoordinate(i, extrusionPath.getSegCount())) == extrusionMultiPath.getIntersectionsMap().end())
                if (extrusionMultiPath.getIntersectionsMap().find(new MultiPath.PathCoordinate(i, (uint)extrusionPath.getSegCount())) == -1)
                {
                    buffer.rebaseOffset();
                    buffer.estimateIndexCount((uint)indexBuffer.Count);
                    buffer.estimateVertexCount((uint)pointList.Count);

                    Quaternion qEnd = Utils._computeQuaternion(extrusionPath.getDirectionBefore(extrusionPath.getSegCount()));
                    if (rotationTrack != null)
                    {
                        float angle = rotationTrack.getLastValue();
                        qEnd = qEnd * new Quaternion((Radian)angle, Vector3.UNIT_Z);
                    }
                    float scaleEnd = 1.0f;
                    if (scaleTrack != null)
                    {
                        scaleEnd = scaleTrack.getLastValue();
                    }

                    for (int j = 0; j < pointList.Count; j++)
                    {
                        Vector2 vp2 = pointList[j];
                        Vector3 vp  = new Vector3(vp2.x, vp2.y, 0f);
                        //C++ TO C# CONVERTER WARNING: The following line was determined to be a copy constructor call - this should be verified and a copy constructor should be created if it does not yet exist:
                        //ORIGINAL LINE: Vector3 normal = Vector3::UNIT_Z;
                        Vector3 normal = (Vector3.UNIT_Z);

                        Vector3 newPoint = extrusionPath.getPoint(extrusionPath.getSegCount()) + qEnd * (scaleEnd * vp);
                        buffer.vertex(newPoint, qEnd * normal, vp2);
                    }
                    for (int ii = 0; ii < indexBuffer.Count / 3; ii++)
                    {
                        buffer.index(indexBuffer[ii * 3]);
                        buffer.index(indexBuffer[ii * 3 + 1]);
                        buffer.index(indexBuffer[ii * 3 + 2]);
                    }
                }
            }
        }
示例#15
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();
        }
        //    *
        //	 * Builds a shape from control points
        //	 * \exception Ogre::InvalidStateException The path contains no points
        //

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

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

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

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

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

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

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

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

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

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

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

            return(path);
        }
示例#17
0
 //    *
 //	 * Rebase index offset : call that function before you add a new mesh to the triangle buffer
 //
 public void rebaseOffset()
 {
     globalOffset = mVertices.size();
 }
        //    *
        //	 * Builds a shape from control points
        //	 * \exception Ogre::InvalidStateException The path contains no points
        //
        //-----------------------------------------------------------------------
        public Shape realizeShape()
        {
            if (mPoints.empty())
            {
                OGRE_EXCEPT("Ogre::Exception::ERR_INVALID_STATE", "The shape contains no points", "Procedural::RoundedCornerSpline2::realizePath()");
            }
            ;

            Shape shape     = new Shape();
            int   numPoints = mClosed ? mPoints.Count : (mPoints.Count - 2);

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

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

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

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

                Vector2 pBegin = p1 - vBegin.NormalisedCopy * radius;
                Vector2 pEnd   = p1 + vEnd.NormalisedCopy * radius;
                Line2D  line1  = new Line2D(pBegin, vBegin.Perpendicular);
                Line2D  line2  = new Line2D(pEnd, vEnd.Perpendicular);
                Vector2 center = new Vector2();
                line1.findIntersect(line2, ref center);
                Vector2 vradBegin  = pBegin - center;
                Vector2 vradEnd    = pEnd - center;
                Radian  angleTotal = Utils.angleBetween(vradBegin, vradEnd);
                if (vradBegin.CrossProduct(vradEnd) < 0f)
                {
                    angleTotal = -angleTotal;
                }

                for (uint j = 0; j <= mNumSeg; j++)
                {
                    Vector2 deltaVector = Utils.rotateVector2(vradBegin, (float)j * angleTotal / (float)mNumSeg);
                    shape.addPoint(center + deltaVector);
                }
            }

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

            if (mClosed)
            {
                shape.close();
            }
            shape.setOutSide(mOutSide);

            return(shape);
        }
示例#19
0
            void parseArcTo(bool rel, bool next)
            {
                if (next)
                {
                    index++;
                }
                float rx = 0.0f;

                if (!parseReal(ref rx))
                {
                    OGRE_EXCEPT("Exception::ERR_INVALIDPARAMS", "Expecting a Real number", "parseCurveSTo");
                }
                float ry = 0.0f;

                if (!parseReal(ref ry))
                {
                    OGRE_EXCEPT("Exception::ERR_INVALIDPARAMS", "Expecting a Real number", "parseCurveSTo");
                }
                float x_axis_rotation = 0.0f;

                if (!parseReal(ref x_axis_rotation))
                {
                    OGRE_EXCEPT("Exception::ERR_INVALIDPARAMS", "Expecting a Real number", "parseCurveSTo");
                }
                float large_arc_flag = 0.0f;

                if (!parseReal(ref large_arc_flag))
                {
                    OGRE_EXCEPT("Exception::ERR_INVALIDPARAMS", "Expecting a Real number", "parseCurveSTo");
                }
                float sweep_flag = 0.0f;

                if (!parseReal(ref sweep_flag))
                {
                    OGRE_EXCEPT("Exception::ERR_INVALIDPARAMS", "Expecting a Real number", "parseCurveSTo");
                }
                float x = 0.0f;

                if (!parseReal(ref x))
                {
                    OGRE_EXCEPT("Exception::ERR_INVALIDPARAMS", "Expecting a Real number", "parseCurveSTo");
                }
                float y = 0.0f;

                if (!parseReal(ref y))
                {
                    OGRE_EXCEPT("Exception::ERR_INVALIDPARAMS", "Expecting a Real number", "parseCurveSTo");
                }

                float RadiansPerDegree = Math.PI / 180.0f;
                float epx       = rel ? point.x + x : x;
                float epy       = rel ? point.y + y : y;
                bool  largeArc  = (large_arc_flag > 0);
                bool  clockwise = (sweep_flag > 0);

                if (epx == point.x && epy == point.y)
                {
                    return;
                }

                if (rx == 0.0f && ry == 0.0f)
                {
                    point = new Vector2(epx, epy);
                    shape.addPoint(point);
                    return;
                }

                float sinPhi = sin(x_axis_rotation * RadiansPerDegree);
                float cosPhi = cos(x_axis_rotation * RadiansPerDegree);

                float x1dash = cosPhi * (point.x - epx) / 2.0f + sinPhi * (point.y - epy) / 2.0f;
                float y1dash = -sinPhi * (point.x - epx) / 2.0f + cosPhi * (point.y - epy) / 2.0f;

                float root;
                float numerator = rx * rx * ry * ry - rx * rx * y1dash * y1dash - ry * ry * x1dash * x1dash;

                if (numerator < 0.0)
                {
                    float s = (float)sqrt(1.0f - numerator / (rx * rx * ry * ry));

                    rx  *= s;
                    ry  *= s;
                    root = 0.0f;
                }
                else
                {
                    root = ((largeArc && clockwise) || (!largeArc && !clockwise) ? -1.0f : 1.0f) * sqrt(numerator / (rx * rx * y1dash * y1dash + ry * ry * x1dash * x1dash));
                }

                float cxdash = root * rx * y1dash / ry;
                float cydash = -root * ry * x1dash / rx;

                float cx = cosPhi * cxdash - sinPhi * cydash + (point.x + epx) / 2.0f;
                float cy = sinPhi * cxdash + cosPhi * cydash + (point.y + epy) / 2.0f;

                float theta1 = CalculateVectorAngle(1.0f, 0.0f, (x1dash - cxdash) / rx, (y1dash - cydash) / ry);
                float dtheta = CalculateVectorAngle((x1dash - cxdash) / rx, (y1dash - cydash) / ry, (-x1dash - cxdash) / rx, (-y1dash - cydash) / ry);

                if (!clockwise && dtheta > 0)
                {
                    dtheta -= 2.0f * Math.PI;
                }
                else if (clockwise && dtheta < 0)
                {
                    dtheta += 2.0f * Math.PI;
                }

                int   segments = (int)ceil((double)abs(dtheta / (Math.PI / 2.0f)));
                float delta    = dtheta / segments;
                float t        = 8.0f / 3.0f * sin(delta / 4.0f) * sin(delta / 4.0f) / sin(delta / 2.0f);

                float startX = point.x;
                float startY = point.y;

                BezierCurve2 bezier = new BezierCurve2();

                bezier.addPoint(startX, startY);
                for (int i = 0; i < segments; ++i)
                {
                    float cosTheta1 = cos(theta1);
                    float sinTheta1 = sin(theta1);
                    float theta2    = theta1 + delta;
                    float cosTheta2 = cos(theta2);
                    float sinTheta2 = sin(theta2);

                    float endpointX = cosPhi * rx * cosTheta2 - sinPhi * ry * sinTheta2 + cx;
                    float endpointY = sinPhi * rx * cosTheta2 + cosPhi * ry * sinTheta2 + cy;

                    float dx1 = t * (-cosPhi * rx * sinTheta1 - sinPhi * ry * cosTheta1);
                    float dy1 = t * (-sinPhi * rx * sinTheta1 + cosPhi * ry * cosTheta1);

                    float dxe = t * (cosPhi * rx * sinTheta2 + sinPhi * ry * cosTheta2);
                    float dye = t * (sinPhi * rx * sinTheta2 - cosPhi * ry * cosTheta2);

                    bezier.addPoint(startX + dx1, startY + dy1);
                    bezier.addPoint(endpointX + dxe, endpointY + dye);

                    theta1 = theta2;
                    startX = endpointX;
                    startY = endpointY;
                }
                point = new Vector2(epx, epy);
                bezier.addPoint(point);
                bezier.setNumSeg(mNumSeg);
                std_vector <Vector2> pointList = bezier.realizeShape().getPointsReference();//getPoints();
                Vector2 lp = shape.getPoint(shape.getPoints().Length - 1);

                //for (std::vector<Vector2>::iterator iter = pointList.begin(); iter != pointList.end(); iter++)
                for (int ii = 0; ii < pointList.size(); ii++)
                {
                    //if (iter == pointList.begin())
                    if (ii == 0)
                    {
                        //if (*iter != lp) shape.addPoint(*iter);
                        if (pointList[ii] != lp)
                        {
                            shape.addPoint(pointList[ii]);
                        }
                    }
                    else
                    {
                        shape.addPoint(pointList[ii]);//shape.addPoint(*iter);
                    }
                }
            }
示例#20
0
            // 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);
                }
            }
示例#21
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);
                }
            }
        }
        //-----------------------------------------------------------------------
        //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);
            }
        }
        //--------------------------------------------------------------
        public void modify()
        {
            if (mInputTriangleBuffer == null)
            {
                OGRE_EXCEPT("Exception::ERR_INVALID_STATE", "Input triangle buffer must be set", "__FUNCTION__");
            }
            ;

            if (mComputeMode == NormalComputeMode.NCM_TRIANGLE)
            {
                if (mMustWeldUnweldFirst)
                {
                    new UnweldVerticesModifier().setInputTriangleBuffer(mInputTriangleBuffer).modify();
                }

                std_vector <int> indices = mInputTriangleBuffer.getIndices();
                std_vector <TriangleBuffer.Vertex> vertices = mInputTriangleBuffer.getVertices();
                for (int i = 0; i < indices.size(); i += 3)
                {
                    Vector3 v1 = vertices[indices[i]].mPosition;
                    Vector3 v2 = vertices[indices[i + 1]].mPosition;
                    Vector3 v3 = vertices[indices[i + 2]].mPosition;
                    Vector3 n  = (v2 - v1).CrossProduct(v3 - v1).NormalisedCopy;
                    //
                    //ORIGINAL LINE: vertices[indices[i]].mNormal = n;
                    vertices[indices[i]].mNormal = (n);
                    //
                    //ORIGINAL LINE: vertices[indices[i+1]].mNormal = n;
                    vertices[indices[i + 1]].mNormal = (n);
                    //
                    //ORIGINAL LINE: vertices[indices[i+2]].mNormal = n;
                    vertices[indices[i + 2]].mNormal = (n);
                }
            }
            else
            {
                if (mMustWeldUnweldFirst)
                {
                    new WeldVerticesModifier().setInputTriangleBuffer(mInputTriangleBuffer).modify();
                }
                std_vector <int> indices = mInputTriangleBuffer.getIndices();
                std_vector <TriangleBuffer.Vertex> vertices   = mInputTriangleBuffer.getVertices();
                std_vector <std_vector <Vector3> > tmpNormals = new std_vector <std_vector <Vector3> >();
                tmpNormals.resize(vertices.size());
                for (int i = 0; i < indices.size(); i += 3)
                {
                    Vector3 v1 = vertices[indices[i]].mPosition;
                    Vector3 v2 = vertices[indices[i + 1]].mPosition;
                    Vector3 v3 = vertices[indices[i + 2]].mPosition;
                    Vector3 n  = (v2 - v1).CrossProduct(v3 - v1);
                    tmpNormals[indices[i]].push_back(n);
                    tmpNormals[indices[i + 1]].push_back(n);
                    tmpNormals[indices[i + 2]].push_back(n);
                }
                for (int i = 0; i < vertices.size(); i++)
                {
                    Vector3 n = (Vector3.ZERO);
                    for (int j = 0; j < tmpNormals[i].size(); j++)
                    {
                        n += tmpNormals[i][j];
                    }
                    vertices[i].mNormal = n.NormalisedCopy;
                }
            }
        }
 //--------------------------------------------------------------
 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);
 }
示例#25
0
 //
 //ORIGINAL LINE: uint getPathCount() const
 public int getPathCount()
 {
     return(mPaths.size());
 }
        //--------------------------------------------------------------
        public void modify()
        {
            if (mInputTriangleBuffer == null)
            {
                OGRE_EXCEPT("Exception::ERR_INVALID_STATE", "Input triangle buffer must be set", "__FUNCTION__");
            }
            ;
            //std.map<Vector3, int, Vector3Comparator> mapExistingVertices = new std.map<Vector3, int, Vector3Comparator>();
            std_map <Vector3, int>             mapExistingVertices = new std_map <Vector3, int>(new Vector3Comparator());
            std_vector <TriangleBuffer.Vertex> vertices            = mInputTriangleBuffer.getVertices();
            std_vector <int> indices = mInputTriangleBuffer.getIndices();

            int newSize = vertices.size();

            //	for (std::vector<TriangleBuffer::Vertex>::iterator it = vertices.begin(); it!= vertices.end(); ++it)
            for (int i = 0; i < vertices.Count; i++)
            {
                //size_t currentIndex = it - vertices.begin();
                TriangleBuffer.Vertex it = vertices[i];
                int currentIndex         = i;
                if (currentIndex >= newSize)
                {
                    break;
                }
                //if (mapExistingVertices.find(it.mPosition) == mapExistingVertices.end())
                //	mapExistingVertices[it.mPosition] = currentIndex;
                if (mapExistingVertices.find(it.mPosition) == -1)
                {
                    mapExistingVertices.insert(it.mPosition, currentIndex);
                }
                else
                {
                    int existingIndex = mapExistingVertices[it.mPosition];
                    --newSize;
                    if (currentIndex == newSize)
                    {
                        //for (std::vector<int>::iterator it2 = indices.begin(); it2 != indices.end(); ++it2)
                        for (int j = 0; j < indices.Count; j++)
                        {
                            int it2 = indices[j];
                            if (it2 == currentIndex)
                            {
                                //*it2 = existingIndex;
                                indices[j] = existingIndex;
                            }
                        }
                    }
                    else
                    {
                        int lastIndex = newSize;
                        //*it = vertices[lastIndex];
                        it = vertices[lastIndex];
                        //for (std::vector<int>::iterator it2 = indices.begin(); it2 != indices.end(); ++it2)
                        for (int j = 0; j < indices.Count; j++)
                        {
                            int it2 = indices[j];
                            //if (*it2 == currentIndex)
                            if (it2 == currentIndex)
                            {
                                //*it2 = existingIndex;
                                indices[j] = existingIndex;
                            }
                            //else if (*it2 == lastIndex)
                            else if (it2 == lastIndex)
                            {
                                //*it2 = currentIndex;
                                indices[j] = currentIndex;
                            }
                        }
                    }
                }
            }
        }
示例#27
0
        //void Triangulator::_recursiveTriangulatePolygon(const DelaunaySegment& cuttingSeg, std::vector<int> inputPoints, DelaunayTriangleBuffer& tbuffer, const PointList&  pointList) const
        void _recursiveTriangulatePolygon(DelaunaySegment cuttingSeg, std_vector <int> inputPoints, DelaunayTriangleBuffer tbuffer, PointList pointList)
        {
            if (inputPoints.size() == 0)
            {
                return;
            }
            if (inputPoints.size() == 1)
            {
                Triangle t2 = new Triangle(pointList);
                //t.setVertices(cuttingSeg.i1, cuttingSeg.i2, inputPoints.begin());
                t2.setVertices(cuttingSeg.i1, cuttingSeg.i2, inputPoints.front());
                t2.makeDirectIfNeeded();
                tbuffer.push_back(t2);
                return;
            }
            // Find a point which, when associated with seg.i1 and seg.i2, builds a Delaunay triangle
            //std::vector<int>::iterator currentPoint = inputPoints.begin();
            int  currentPoint_pos = inputPoints.begin();
            int  currentPoint     = inputPoints.front();
            bool found            = false;

            while (!found)
            {
                bool isDelaunay = true;
                //Circle c=new Circle(pointList[*currentPoint], pointList[cuttingSeg.i1], pointList[cuttingSeg.i2]);
                Circle c = new Circle(pointList[currentPoint], pointList[cuttingSeg.i1], pointList[cuttingSeg.i2]);
                //for (std::vector<int>::iterator it = inputPoints.begin(); it!=inputPoints.end(); ++it)
                int idx = -1;
                foreach (var it in inputPoints)
                {
                    idx++;
                    //if (c.isPointInside(pointList[*it]) && (*it != *currentPoint))
                    if (c.isPointInside(pointList[it]) && (it != currentPoint))
                    {
                        isDelaunay       = false;
                        currentPoint     = it;
                        currentPoint_pos = idx;
                        break;
                    }
                }
                if (isDelaunay)
                {
                    found = true;
                }
            }

            // Insert current triangle
            Triangle t = new Triangle(pointList);

            //t.setVertices(*currentPoint, cuttingSeg.i1, cuttingSeg.i2);
            t.setVertices(currentPoint, cuttingSeg.i1, cuttingSeg.i2);
            t.makeDirectIfNeeded();
            tbuffer.push_back(t);

            // Recurse
            //DelaunaySegment newCut1=new DelaunaySegment(cuttingSeg.i1, *currentPoint);
            //DelaunaySegment newCut2=new DelaunaySegment(cuttingSeg.i2, *currentPoint);
            DelaunaySegment newCut1 = new DelaunaySegment(cuttingSeg.i1, currentPoint);
            DelaunaySegment newCut2 = new DelaunaySegment(cuttingSeg.i2, currentPoint);
            //std_vector<int> set1=new std_vector<int>(inputPoints.begin(), currentPoint);
            //std_vector<int> set2=new std_vector<int>(currentPoint+1, inputPoints.end());
            std_vector <int> set1 = new std_vector <int>();

            set1.assign(inputPoints.ToArray(), inputPoints.begin(), currentPoint_pos);
            std_vector <int> set2 = new std_vector <int>();

            set2.assign(inputPoints.ToArray(), currentPoint_pos + 1, inputPoints.end());

            if (!set1.empty())
            {
                _recursiveTriangulatePolygon(newCut1, set1, tbuffer, pointList);
            }
            if (!set2.empty())
            {
                _recursiveTriangulatePolygon(newCut2, set2, tbuffer, pointList);
            }
        }
示例#28
0
        //-----------------------------------------------------------------------
        //
        //ORIGINAL LINE: void _latheCapImpl(TriangleBuffer& buffer) const
        private void _latheCapImpl(ref TriangleBuffer buffer)
        {
            std_vector <int>     indexBuffer = new std_vector <int>();
            std_vector <Vector2> pointList   = new std_vector <Vector2>();

            buffer.rebaseOffset();

            Triangulator t              = new Triangulator();
            Shape        shapeCopy      = new Shape();
            MultiShape   multishapeCopy = new MultiShape();

            if (mShapeToExtrude != null)
            {
                //
                //ORIGINAL LINE: shapeCopy = *mShapeToExtrude;
                shapeCopy = (mShapeToExtrude);
                shapeCopy.close();
                t.setShapeToTriangulate(shapeCopy);
            }
            else
            {
                //
                //ORIGINAL LINE: multishapeCopy = *mMultiShapeToExtrude;
                multishapeCopy = (mMultiShapeToExtrude);
                multishapeCopy.close();
                t.setMultiShapeToTriangulate(mMultiShapeToExtrude);
            }
            t.triangulate(indexBuffer, pointList);
            buffer.estimateIndexCount(2 * (uint)indexBuffer.Count);
            buffer.estimateVertexCount(2 * (uint)pointList.Count);

            //begin cap
            buffer.rebaseOffset();
            Quaternion q = new Quaternion();

            q.FromAngleAxis(mAngleBegin, Vector3.UNIT_Y);
            for (int j = 0; j < pointList.size(); j++)
            {
                Vector2 vp2 = pointList[j];
                Vector3 vp  = new Vector3(vp2.x, vp2.y, 0);
                //C++ TO C# CONVERTER WARNING: The following line was determined to be a copy constructor call - this should be verified and a copy constructor should be created if it does not yet exist:
                //ORIGINAL LINE: Vector3 normal = Vector3::UNIT_Z;
                Vector3 normal = (Vector3.UNIT_Z);

                addPoint(ref buffer, q * vp, q * normal, vp2);
            }

            for (int i = 0; i < indexBuffer.size() / 3; i++)
            {
                buffer.index(indexBuffer[i * 3]);
                buffer.index(indexBuffer[i * 3 + 1]);
                buffer.index(indexBuffer[i * 3 + 2]);
            }
            //end cap
            buffer.rebaseOffset();
            q.FromAngleAxis(mAngleEnd, Vector3.UNIT_Y);
            for (int j = 0; j < pointList.size(); j++)
            {
                Vector2 vp2    = pointList[j];
                Vector3 vp     = new Vector3(vp2.x, vp2.y, 0);
                Vector3 normal = -Vector3.UNIT_Z;

                addPoint(ref buffer, q * vp, q * normal, vp2);
            }

            for (int i = 0; i < indexBuffer.size() / 3; i++)
            {
                buffer.index(indexBuffer[i * 3]);
                buffer.index(indexBuffer[i * 3 + 2]);
                buffer.index(indexBuffer[i * 3 + 1]);
            }
        }
示例#29
0
 /// Returns the number of shapes in that MultiShape
 //
 //ORIGINAL LINE: uint getShapeCount() const
 public int getShapeCount()
 {
     return(mShapes.size());
 }