//----------------------------------------------------------------------- //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); } }
// * // * Builds the mesh into the given TriangleBuffer // * @param buffer The TriangleBuffer on where to append the mesh. // * @exception Ogre::InvalidStateException Either shape or multishape must be defined! // * @exception Ogre::InvalidStateException Required parameter is zero! // //----------------------------------------------------------------------- // //ORIGINAL LINE: void addToTriangleBuffer(TriangleBuffer& buffer) const public override void addToTriangleBuffer(ref TriangleBuffer buffer) { if (mMultiShapeToExtrude.getShapeCount() == 0) { OGRE_EXCEPT("Ogre::Exception::ERR_INVALID_STATE", "At least one shape must be defined!", "Procedural::Extruder::addToTriangleBuffer(Procedural::TriangleBuffer)"); } ; // Triangulate the begin and end caps if (mCapped && mMultiShapeToExtrude.isClosed()) { GlobalMembers._extrudeCapImpl(ref buffer, mMultiShapeToExtrude, mMultiExtrusionPath, mScaleTracks, mRotationTracks); } // Extrude the paths contained in multiExtrusionPath for (uint j = 0; j < mMultiExtrusionPath.getPathCount(); ++j) { Path extrusionPath = mMultiExtrusionPath.getPath((int)j); Track rotationTrack = null; if (mRotationTracks.find(j) != -1) // mRotationTracks.end()) { { rotationTrack = mRotationTracks[j]; //mRotationTracks.find(j).second; extrusionPath = extrusionPath.mergeKeysWithTrack(mRotationTracks[j]); // (*mRotationTracks.find(j).second); } Track scaleTrack = null; if (mScaleTracks.find(j) != -1) // mScaleTracks.end()) { { rotationTrack = mScaleTracks[j]; //mScaleTracks.find(j).second; extrusionPath = extrusionPath.mergeKeysWithTrack(mScaleTracks[j]); // (*mScaleTracks.find(j).second); } Track pathTextureTrack = null; if (mPathTextureTracks.find(j) != -1) // mPathTextureTracks.end()) { { pathTextureTrack = mPathTextureTracks[j]; //mPathTextureTracks.find(j).second; extrusionPath = extrusionPath.mergeKeysWithTrack(mPathTextureTracks[j]); //(*mPathTextureTracks.find(j).second); } std_vector <std_pair <uint, uint> > segs = mMultiExtrusionPath.getNoIntersectionParts(j); //for (List<std.pair<uint, uint>>.Enumerator it = segs.GetEnumerator(); it.MoveNext(); ++it) { foreach (var it in segs) { for (uint i = 0; i < mMultiShapeToExtrude.getShapeCount(); i++) { Shape shapeToExtrude = mMultiShapeToExtrude.getShape(i); Track shapeTextureTrack = null; if (mShapeTextureTracks.find(i) != -1) // mShapeTextureTracks.end()) { { shapeTextureTrack = mShapeTextureTracks[i]; //mShapeTextureTracks.find(i).second; shapeToExtrude.mergeKeysWithTrack(shapeTextureTrack); } GlobalMembers._extrudeBodyImpl(ref buffer, shapeToExtrude, extrusionPath, (int)it.first, (int)it.second, shapeTextureTrack, rotationTrack, scaleTrack, pathTextureTrack); } } // Make the intersections //typedef std::vector<PathCoordinate> PathIntersection; std_vector <std_vector <MultiPath.PathCoordinate> > intersections = mMultiExtrusionPath.getIntersections(); //for (List<MultiPath.PathIntersection>.Enumerator it = intersections.GetEnumerator(); it.MoveNext(); ++it) { foreach (var it in intersections) { for (uint i = 0; i < mMultiShapeToExtrude.getShapeCount(); i++) { Track shapeTextureTrack = null; if (mShapeTextureTracks.find(i) != -1) // mShapeTextureTracks.end()) { shapeTextureTrack = mShapeTextureTracks[i]; //mShapeTextureTracks.find(i).second; } GlobalMembers._extrudeIntersectionImpl(ref buffer, it, mMultiExtrusionPath, mMultiShapeToExtrude.getShape(i), shapeTextureTrack); } } } }
//----------------------------------------------------------------------- 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]); } } } }