/// Get the key value couple before current point. /// If current point is below minimum key, issues minimum key/value // //ORIGINAL LINE: std::map<Real, Real>.Enumerator _getKeyValueBefore(float pos) const //public std.map<Real, Real>.Enumerator _getKeyValueBefore(float pos) public std_pair <float, float> _getKeyValueBefore(float pos) { std_pair <float, float> it = mKeyFrames.upper_bound(pos); int index = mKeyFrames.find(pos); //if (it==mKeyFrames.begin()) if (index == 0) { return(it); } else { return(mKeyFrames.lower_bound(pos)); //return --it; } //std::map<Real, Real>::const_iterator it = mKeyFrames.upper_bound(pos); //if (it==mKeyFrames.begin()) // return it; //else // return --it; }
//-------------------------------------------------------------- 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; } } } } } }
//-------------------------------------------------------------- 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; } } } } } }
// * // * Executes the Constrained Delaunay Triangulation algorithm // * @param output A vector of index where is outputed the resulting triangle indexes // * @param outputVertices A vector of vertices where is outputed the resulting triangle vertices // * @exception Ogre::InvalidStateException Either shape or multishape or segment list must be defined // //void triangulate(ref List<int>& output, ref List<Vector2>& outputVertices) const; public void triangulate(std_vector <int> output, PointList outputVertices) { if (mShapeToTriangulate == null && mMultiShapeToTriangulate == null && mSegmentListToTriangulate == null) { throw new NullReferenceException("Ogre::Exception::ERR_INVALID_STATE," + "Either shape or multishape or segment list must be defined!" + ", Procedural::Triangulator::triangulate(std::vector<int>&, PointList&)"); } //Ogre::Timer mTimer; //Mogre.Timer mTimer = new Timer(); //mTimer.Reset(); DelaunayTriangleBuffer dtb = new std_list <Triangle>(); // Do the Delaunay triangulation std_vector <int> segmentListIndices = new std_vector <int>(); if (mShapeToTriangulate != null) { outputVertices = new std_vector <Vector2>(mShapeToTriangulate.getPoints()); for (int i = 0; i < mShapeToTriangulate.getSegCount(); ++i) { segmentListIndices.push_back(i); segmentListIndices.push_back(mShapeToTriangulate.getBoundedIndex(i + 1)); } } else if (mMultiShapeToTriangulate != null) { outputVertices = new std_vector <Vector2>(mMultiShapeToTriangulate.getPoints()); int index = 0; for (int i = 0; i < mMultiShapeToTriangulate.getShapeCount(); ++i) { Shape shape = mMultiShapeToTriangulate.getShape((uint)i); for (int j = 0; j < shape.getSegCount(); j++) { segmentListIndices.push_back(index + j); segmentListIndices.push_back(index + shape.getBoundedIndex(j + 1)); } index += shape.getSegCount(); } } else if (mSegmentListToTriangulate != null) { //std_map<Vector2, int, Vector2Comparator> backMap; std_map <Vector2, int> backMap = new std_map <Vector2, int>(new Vector2Comparator()); //for (std::vector<Segment2D>::iterator it = mSegmentListToTriangulate->begin(); it!= mSegmentListToTriangulate->end(); it++) foreach (var it in mSegmentListToTriangulate) { if ((it.mA - it.mB).SquaredLength < 1e-6) { continue; } //std::map<Vector2, int, Vector2Comparator>::iterator it2 = backMap.find(it->mA); int it2_pos = backMap.find(it.mA); //if (it2 != backMap.end()) if (it2_pos != -1) { //segmentListIndices.push_back(it2->second); segmentListIndices.push_back(backMap[it.mA]); } else { //backMap[it->mA] = outputVertices.size(); backMap.insert(it.mA, outputVertices.size()); segmentListIndices.push_back(outputVertices.size()); outputVertices.push_back(it.mA); } //it2 = backMap.find(it.mB); it2_pos = backMap.find(it.mB); //if (it2 != backMap.end()) if (it2_pos != -1) { //segmentListIndices.push_back(it2.second); segmentListIndices.push_back(backMap[it.mB]); } else { //backMap[it->mB] = outputVertices.size(); backMap.insert(it.mB, outputVertices.size()); segmentListIndices.push_back(outputVertices.size()); outputVertices.push_back(it.mB); } } if (mManualSuperTriangle != null) { Triangle superTriangle = new Triangle(outputVertices); for (int i = 0; i < 3; i++) { //std::map<Vector2, int, Vector2Comparator>::iterator it = backMap.find(mManualSuperTriangle->mPoints[i]); int it_pos = backMap.find(mManualSuperTriangle.mPoints[i]); //if (it != backMap.end()) if (it_pos != -1) { //segmentListIndices.push_back(it->second); //superTriangle.i[i] = it->second; superTriangle.i[i] = backMap[mManualSuperTriangle.mPoints[i]]; } else { //backMap[mManualSuperTriangle->mPoints[i]] = outputVertices.size(); backMap.insert(mManualSuperTriangle.mPoints[i], outputVertices.size()); //segmentListIndices.push_back(outputVertices.size()); superTriangle.i[i] = outputVertices.size(); outputVertices.push_back(mManualSuperTriangle.mPoints[i]); } } dtb.push_back(superTriangle); } } //Utils::log("Triangulator preparation : " + StringConverter::toString(mTimer.getMicroseconds() / 1000.0f) + " ms"); delaunay(outputVertices, ref dtb); //Utils::log("Triangulator delaunay : " + StringConverter::toString(mTimer.getMicroseconds() / 1000.0f) + " ms"); // Add contraints _addConstraints(ref dtb, outputVertices, segmentListIndices); //Utils::log("Triangulator constraints : " + StringConverter::toString(mTimer.getMicroseconds() / 1000.0f) + " ms"); //Outputs index buffer //for (DelaunayTriangleBuffer::iterator it = dtb.begin(); it!=dtb.end(); ++it) foreach (var it in dtb) { if (!it.isDegenerate()) { output.push_back(it.i[0]); output.push_back(it.i[1]); output.push_back(it.i[2]); } } // Remove super triangle if (mRemoveOutside) { outputVertices.pop_back(); outputVertices.pop_back(); outputVertices.pop_back(); } //Utils::log("Triangulator output : " + StringConverter::toString(mTimer.getMicroseconds() / 1000.0f) + " ms"); }
//----------------------------------------------------------------------- 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); } } }