public void buildFromSegmentSoup(std_vector<Segment3D> segList, ref std_vector<Path> @out) { //typedef std::multimap<Vector3, Vector3, Vector3Comparator> Vec3MultiMap; //Vec3MultiMap segs; std_multimap<Vector3,Vector3>segs=new std_multimap<Vector3,Vector3>(new Vector3Comparator()); // for (std::vector<Segment3D>::const_iterator it = segList.begin(); it != segList.end(); ++it) foreach(var it in segList) { //segs.insert(std::pair<Vector3, Vector3 > (it->mA, it->mB)); //segs.insert(std::pair<Vector3, Vector3 > (it->mB, it->mA)); segs.insert(it.mA,it.mB); segs.insert(it.mB,it.mA); } while (!segs.empty()) { Vector3 headFirst = segs.get(0).first;//segs.begin()->first; Vector3 headSecond = segs.get(0).second[0];//segs.begin()->second; Path p=new Path(); p.addPoint(headFirst).addPoint(headSecond); //Vec3MultiMap::iterator firstSeg = segs.begin(); int firstSeg_pos=segs.begin(); Vector3 firstSeg=segs.get(0).first; //std::pair<Vec3MultiMap::iterator, Vec3MultiMap::iterator> correspondants2 = segs.equal_range(headSecond); std_pair<std_pair<Vector3,List<Vector3>>,std_pair<Vector3,List<Vector3>>> correspondants2 = segs.equal_range(headSecond); //for (Vec3MultiMap::iterator it = correspondants2.first; it != correspondants2.second;) for(int i=correspondants2.first.second.Count-1;i>=0;i--) { // Vec3MultiMap::iterator removeIt = it++; Vector3 removeIt=correspondants2.first.second[i]; //if ((removeIt->second - firstSeg->first).squaredLength() < 1e-8) if((removeIt-firstSeg).SquaredLength<1e-8) segs.erase(removeIt); } segs.erase(firstSeg); bool foundSomething = true; while (!segs.empty() && foundSomething) { foundSomething = false; //Vec3MultiMap::iterator next = segs.find(headSecond); int next_pos = segs.find(headSecond); //if (next != segs.end()) if(next_pos!=-1) { std_pair<Vector3,List<Vector3>>next=segs.get((uint)next_pos); foundSomething = true; headSecond = next.second[0]; p.addPoint(headSecond); //std::pair<Vec3MultiMap::iterator, Vec3MultiMap::iterator> correspondants = segs.equal_range(headSecond); std_pair<std_pair<Vector3,List<Vector3>>,std_pair<Vector3,List<Vector3>>>correspondants = segs.equal_range(headSecond); //for (Vec3MultiMap::iterator it = correspondants.first; it != correspondants.second;) for (int i = correspondants.first.second.Count - 1; i >= 0;i-- ) { //Vec3MultiMap::iterator removeIt = it++; Vector3 removeIt = correspondants.first.second[i]; //if ((removeIt->second - next->first).squaredLength() < 1e-8) if ((removeIt - next.first).SquaredLength < 1e-8) segs.erase(removeIt); } //segs.erase(next); segs.erase(next.first); } //Vec3MultiMap::iterator previous = segs.find(headFirst); int previous_pos=segs.find(headFirst); //if (previous != segs.end()) if(previous_pos!=-1) { std_pair<Vector3, List<Vector3>> previous = segs.get((uint)previous_pos); foundSomething = true; //p.insertPoint(0, previous.second); p.insertPoint(0, previous.second[0]);//??? headFirst = previous.second[0]; //std::pair<Vec3MultiMap::iterator, Vec3MultiMap::iterator> correspondants = segs.equal_range(headFirst); std_pair<std_pair<Vector3,List<Vector3>>,std_pair<Vector3,List<Vector3>>>correspondants = segs.equal_range(headFirst); //for (Vec3MultiMap::iterator it = correspondants.first; it != correspondants.second;) for(int i=correspondants.first.second.Count-1;i>=0;i--) { //Vec3MultiMap::iterator removeIt = it++; Vector3 removeIt=correspondants.first.second[i]; //if ((removeIt->second - previous->first).squaredLength() < 1e-8) if((removeIt-previous.first).SquaredLength<1e-8) segs.erase(removeIt); } //segs.erase(previous); segs.erase(previous.first); } } if ((p.getPoint(0)-p.getPoint(p.getSegCount() + 1)).SquaredLength < 1e-6) { p.getPointsReference().pop_back(); p.close(); } @out.push_back(p); } }
//----------------------------------------------------------------------- //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 static void _extrudeBodyImpl(ref TriangleBuffer buffer, Shape shapeToExtrude, Path pathToExtrude, int pathBeginIndex, int pathEndIndex, Track shapeTextureTrack, Track rotationTrack, Track scaleTrack, Track pathTextureTrack) { if (pathToExtrude == null || shapeToExtrude == null) { OGRE_EXCEPT("Ogre::Exception::ERR_INVALID_STATE", "Shape and Path must not be null!", "Procedural::Extruder::_extrudeBodyImpl(Procedural::TriangleBuffer&, const Procedural::Shape*)"); } ; uint numSegPath = (uint)(pathEndIndex - pathBeginIndex); uint numSegShape = (uint)shapeToExtrude.getSegCount(); if (numSegPath == 0 || numSegShape == 0) { OGRE_EXCEPT("Ogre::Exception::ERR_INVALID_STATE", "Shape and path must contain at least two points", "Procedural::Extruder::_extrudeBodyImpl(Procedural::TriangleBuffer&, const Procedural::Shape*)"); } ; float totalPathLength = pathToExtrude.getTotalLength(); float totalShapeLength = shapeToExtrude.getTotalLength(); // Merge shape and path with tracks float lineicPos = pathToExtrude.getLengthAtPoint(pathBeginIndex); Path path = pathToExtrude; numSegPath = (uint)(pathEndIndex - pathBeginIndex); numSegShape = (uint)shapeToExtrude.getSegCount(); // Estimate vertex and index count buffer.rebaseOffset(); buffer.estimateIndexCount(numSegShape * numSegPath * 6); buffer.estimateVertexCount((numSegShape + 1) * (numSegPath + 1)); Vector3 oldup = new Vector3(); for (int i = pathBeginIndex; i <= pathEndIndex; ++i) { Vector3 v0 = path.getPoint(i); Vector3 direction = path.getAvgDirection(i); Quaternion q = Utils._computeQuaternion(direction); Radian angle = Utils.angleBetween((q * Vector3.UNIT_Y), (oldup)); if (i > pathBeginIndex && angle > (Radian)Math.HALF_PI / 2.0f) { q = Utils._computeQuaternion(direction, oldup); } oldup = q * Vector3.UNIT_Y; float scale = 1.0f; if (i > pathBeginIndex) { lineicPos += (v0 - path.getPoint(i - 1)).Length; } // Get the values of angle and scale if (rotationTrack != null) { float angle_2 = 0f; angle_2 = rotationTrack.getValue(lineicPos, lineicPos / totalPathLength, (uint)i); q = q * new Quaternion((Radian)angle_2, Vector3.UNIT_Z); } if (scaleTrack != null) { scale = scaleTrack.getValue(lineicPos, lineicPos / totalPathLength, (uint)i); } float uTexCoord = 0f; if (pathTextureTrack != null) { uTexCoord = pathTextureTrack.getValue(lineicPos, lineicPos / totalPathLength, (uint)i); } else { uTexCoord = lineicPos / totalPathLength; } _extrudeShape(ref buffer, shapeToExtrude, v0, q, q, scale, 1.0f, 1.0f, totalShapeLength, uTexCoord, i < pathEndIndex, shapeTextureTrack); } }
//----------------------------------------------------------------------- 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]); } } } }
public void buildFromSegmentSoup(std_vector <Segment3D> segList, ref std_vector <Path> @out) { //typedef std::multimap<Vector3, Vector3, Vector3Comparator> Vec3MultiMap; //Vec3MultiMap segs; std_multimap <Vector3, Vector3> segs = new std_multimap <Vector3, Vector3>(new Vector3Comparator()); // for (std::vector<Segment3D>::const_iterator it = segList.begin(); it != segList.end(); ++it) foreach (var it in segList) { //segs.insert(std::pair<Vector3, Vector3 > (it->mA, it->mB)); //segs.insert(std::pair<Vector3, Vector3 > (it->mB, it->mA)); segs.insert(it.mA, it.mB); segs.insert(it.mB, it.mA); } while (!segs.empty()) { Vector3 headFirst = segs.get(0).first; //segs.begin()->first; Vector3 headSecond = segs.get(0).second[0]; //segs.begin()->second; Path p = new Path(); p.addPoint(headFirst).addPoint(headSecond); //Vec3MultiMap::iterator firstSeg = segs.begin(); int firstSeg_pos = segs.begin(); Vector3 firstSeg = segs.get(0).first; //std::pair<Vec3MultiMap::iterator, Vec3MultiMap::iterator> correspondants2 = segs.equal_range(headSecond); std_pair <std_pair <Vector3, List <Vector3> >, std_pair <Vector3, List <Vector3> > > correspondants2 = segs.equal_range(headSecond); //for (Vec3MultiMap::iterator it = correspondants2.first; it != correspondants2.second;) for (int i = correspondants2.first.second.Count - 1; i >= 0; i--) { // Vec3MultiMap::iterator removeIt = it++; Vector3 removeIt = correspondants2.first.second[i]; //if ((removeIt->second - firstSeg->first).squaredLength() < 1e-8) if ((removeIt - firstSeg).SquaredLength < 1e-8) { segs.erase(removeIt); } } segs.erase(firstSeg); bool foundSomething = true; while (!segs.empty() && foundSomething) { foundSomething = false; //Vec3MultiMap::iterator next = segs.find(headSecond); int next_pos = segs.find(headSecond); //if (next != segs.end()) if (next_pos != -1) { std_pair <Vector3, List <Vector3> > next = segs.get((uint)next_pos); foundSomething = true; headSecond = next.second[0]; p.addPoint(headSecond); //std::pair<Vec3MultiMap::iterator, Vec3MultiMap::iterator> correspondants = segs.equal_range(headSecond); std_pair <std_pair <Vector3, List <Vector3> >, std_pair <Vector3, List <Vector3> > > correspondants = segs.equal_range(headSecond); //for (Vec3MultiMap::iterator it = correspondants.first; it != correspondants.second;) for (int i = correspondants.first.second.Count - 1; i >= 0; i--) { //Vec3MultiMap::iterator removeIt = it++; Vector3 removeIt = correspondants.first.second[i]; //if ((removeIt->second - next->first).squaredLength() < 1e-8) if ((removeIt - next.first).SquaredLength < 1e-8) { segs.erase(removeIt); } } //segs.erase(next); segs.erase(next.first); } //Vec3MultiMap::iterator previous = segs.find(headFirst); int previous_pos = segs.find(headFirst); //if (previous != segs.end()) if (previous_pos != -1) { std_pair <Vector3, List <Vector3> > previous = segs.get((uint)previous_pos); foundSomething = true; //p.insertPoint(0, previous.second); p.insertPoint(0, previous.second[0]);//??? headFirst = previous.second[0]; //std::pair<Vec3MultiMap::iterator, Vec3MultiMap::iterator> correspondants = segs.equal_range(headFirst); std_pair <std_pair <Vector3, List <Vector3> >, std_pair <Vector3, List <Vector3> > > correspondants = segs.equal_range(headFirst); //for (Vec3MultiMap::iterator it = correspondants.first; it != correspondants.second;) for (int i = correspondants.first.second.Count - 1; i >= 0; i--) { //Vec3MultiMap::iterator removeIt = it++; Vector3 removeIt = correspondants.first.second[i]; //if ((removeIt->second - previous->first).squaredLength() < 1e-8) if ((removeIt - previous.first).SquaredLength < 1e-8) { segs.erase(removeIt); } } //segs.erase(previous); segs.erase(previous.first); } } if ((p.getPoint(0) - p.getPoint(p.getSegCount() + 1)).SquaredLength < 1e-6) { p.getPointsReference().pop_back(); p.close(); } @out.push_back(p); } }