//-------------------------------------------------------------- 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); }
// * 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)]); }
//----------------------------------------------------------------------- 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); } }
/// 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); }
//----------------------------------------------------------------------- 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); } }
// * // * 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]); } }
//----------------------------------------------------------------------- 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]); } } } }
// * // * 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); }
// * // * 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); }
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); } } }
// 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); } }
//----------------------------------------------------------------------- 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); }
// //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; } } } } } }
//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); } }
//----------------------------------------------------------------------- // //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]); } }
/// Returns the number of shapes in that MultiShape // //ORIGINAL LINE: uint getShapeCount() const public int getShapeCount() { return(mShapes.size()); }