// * // * 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) { buffer.rebaseOffset(); buffer.estimateVertexCount((mNumSegHeight + 1) * (mNumSegBase + 1) + mNumSegBase + 2); buffer.estimateIndexCount(mNumSegHeight * mNumSegBase * 6 + 3 * mNumSegBase); float deltaAngle = (Math.TWO_PI / mNumSegBase); float deltaHeight = mHeight / (float)mNumSegHeight; int offset = 0; Vector3 refNormal = new Vector3(mRadius, mHeight, 0.0f); Quaternion q = new Quaternion(); for (uint i = 0; i <= mNumSegHeight; i++) { float r0 = mRadius * (1 - i / (float)mNumSegHeight); for (uint j = 0; j <= mNumSegBase; j++) { float x0 = r0 * cosf(j * deltaAngle); float z0 = r0 * sinf(j * deltaAngle); q.FromAngleAxis(new Radian(-deltaAngle * j), Vector3.UNIT_Y); addPoint(ref buffer, new Vector3(x0, i * deltaHeight, z0), q * refNormal, new Vector2(j / (float)mNumSegBase, i / (float)mNumSegHeight)); if (i != mNumSegHeight && j != mNumSegBase) { buffer.index(offset + (int)mNumSegBase + 2); buffer.index(offset); buffer.index(offset + (int)mNumSegBase + 1); buffer.index(offset + (int)mNumSegBase + +2); buffer.index(offset + 1); buffer.index(offset); } offset++; } } //low cap int centerIndex = offset; addPoint(ref buffer, Vector3.ZERO, Vector3.NEGATIVE_UNIT_Y, Vector2.UNIT_Y); offset++; for (uint j = 0; j <= mNumSegBase; j++) { float x0 = mRadius * cosf(j * deltaAngle); float z0 = mRadius * sinf(j * deltaAngle); addPoint(ref buffer, new Vector3(x0, 0.0f, z0), Vector3.NEGATIVE_UNIT_Y, new Vector2(j / (float)mNumSegBase, 0.0f)); if (j != mNumSegBase) { buffer.index(centerIndex); buffer.index(offset); buffer.index(offset + 1); } offset++; } }
// * // * 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) { buffer.rebaseOffset(); buffer.estimateVertexCount((mNumSegCircle + 1) * (mNumSegSection + 1)); buffer.estimateIndexCount((mNumSegCircle) * (mNumSegSection + 1) * 6); float deltaSection = (Math.TWO_PI / mNumSegSection); float deltaCircle = (Math.TWO_PI / mNumSegCircle); int offset = 0; for (uint i = 0; i <= mNumSegCircle; i++) { for (uint j = 0; j <= mNumSegSection; j++) { Vector3 c0 = new Vector3(mRadius, 0.0f, 0.0f); Vector3 v0 = new Vector3(mRadius + mSectionRadius * cosf(j * deltaSection), mSectionRadius * sinf(j * deltaSection), 0.0f); Quaternion q = new Quaternion(); q.FromAngleAxis(new Radian(i * deltaCircle), Vector3.UNIT_Y); Vector3 v = q * v0; Vector3 c = q * c0; addPoint(ref buffer, v, (v - c).NormalisedCopy, new Vector2(i / (float)mNumSegCircle, j / (float)mNumSegSection)); if (i != mNumSegCircle) { buffer.index(offset + (int)mNumSegSection + 1); buffer.index(offset); buffer.index(offset + (int)mNumSegSection); buffer.index(offset + (int)mNumSegSection + 1); buffer.index(offset + 1); buffer.index(offset); } offset++; } } }
/// Internal. Builds a "corner" of the rounded box, ie a 1/8th of a sphere // //ORIGINAL LINE: void _addCorner(TriangleBuffer& buffer, bool isXPositive, bool isYPositive, bool isZPositive) const private void _addCorner(ref TriangleBuffer buffer, bool isXPositive, bool isYPositive, bool isZPositive) { buffer.rebaseOffset(); buffer.estimateVertexCount((uint)((mChamferNumSeg + 1) * (mChamferNumSeg + 1))); buffer.estimateIndexCount((uint)(mChamferNumSeg * mChamferNumSeg * 6)); int offset = 0; Vector3 offsetPosition = new Vector3((isXPositive ? 1 : -1) * .5f * mSizeX, (isYPositive ? 1 : -1) * .5f * mSizeY, (isZPositive ? 1 : -1) * .5f * mSizeZ); float deltaRingAngle = (Math.HALF_PI / mChamferNumSeg); float deltaSegAngle = (Math.HALF_PI / mChamferNumSeg); float offsetRingAngle = isYPositive ? 0 : Math.HALF_PI; float offsetSegAngle = 0f; if (isXPositive && isZPositive) { offsetSegAngle = 0; } if ((!isXPositive) && isZPositive) { offsetSegAngle = 1.5f * Math.PI; } if (isXPositive && (!isZPositive)) { offsetSegAngle = Math.HALF_PI; } if ((!isXPositive) && (!isZPositive)) { offsetSegAngle = Math.PI; } // Generate the group of rings for the sphere for (ushort ring = 0; ring <= mChamferNumSeg; ring++) { float r0 = mChamferSize * sinf(ring * deltaRingAngle + offsetRingAngle); float y0 = mChamferSize * cosf(ring * deltaRingAngle + offsetRingAngle); // Generate the group of segments for the current ring for (ushort seg = 0; seg <= mChamferNumSeg; seg++) { float x0 = r0 * sinf(seg * deltaSegAngle + offsetSegAngle); float z0 = r0 * cosf(seg * deltaSegAngle + offsetSegAngle); // Add one vertex to the strip which makes up the sphere addPoint(ref buffer, new Vector3(x0 + offsetPosition.x, y0 + offsetPosition.y, z0 + offsetPosition.z), new Vector3(x0, y0, z0).NormalisedCopy, new Vector2((float)seg / (float)mChamferNumSeg, (float)ring / (float)mChamferNumSeg)); if ((ring != mChamferNumSeg) && (seg != mChamferNumSeg)) { // each vertex (except the last) has six indices pointing to it buffer.index(offset + mChamferNumSeg + 2); buffer.index(offset); buffer.index(offset + mChamferNumSeg + 1); buffer.index(offset + mChamferNumSeg + 2); buffer.index(offset + 1); buffer.index(offset); } offset++; } // end for seg } // end for ring }
// * // * 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]); } }
// * // * 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) { buffer.rebaseOffset(); buffer.estimateVertexCount((uint)((mNumSegCircle * mP + 1) * (mNumSegSection + 1))); buffer.estimateIndexCount((uint)((mNumSegCircle * mP) * (mNumSegSection + 1) * 6)); int offset = 0; for (uint i = 0; i <= mNumSegCircle * mP; i++) { float phi = Math.TWO_PI * i / (float)mNumSegCircle; float x0 = mRadius * (2 + cosf(mQ * phi / (float)mP)) * cosf(phi) / 3.0f; float y0 = mRadius * sinf(mQ * phi / (float)mP) / 3.0f; float z0 = mRadius * (2 + cosf(mQ * phi / (float)mP)) * sinf(phi) / 3.0f; float phi1 = Math.TWO_PI * (i + 1) / (float)mNumSegCircle; float x1 = mRadius * (2 + cosf(mQ * phi1 / (float)mP)) * cosf(phi1) / 3.0f; float y1 = mRadius * sinf(mQ * phi1 / mP) / 3.0f; float z1 = mRadius * (2 + cosf(mQ * phi1 / (float)mP)) * sinf(phi1) / 3.0f; Vector3 v0 = new Vector3(x0, y0, z0); Vector3 v1 = new Vector3(x1, y1, z1); Vector3 direction = ((v1 - v0).NormalisedCopy); Quaternion q = Utils._computeQuaternion(direction); for (uint j = 0; j <= mNumSegSection; j++) { float alpha = Math.TWO_PI * j / mNumSegSection; Vector3 vp = mSectionRadius * (q * new Vector3(cosf(alpha), sinf(alpha), 0)); addPoint(ref buffer, v0 + vp, vp.NormalisedCopy, new Vector2(i / (float)mNumSegCircle, j / (float)mNumSegSection)); if (i != mNumSegCircle * mP) { buffer.index(offset + (int)mNumSegSection + 1); buffer.index(offset + (int)mNumSegSection); buffer.index(offset); buffer.index(offset + (int)mNumSegSection + 1); buffer.index(offset); buffer.index(offset + 1); } offset++; } } }
//----------------------------------------------------------------------- // //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]); } }
// * // * 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) { buffer.rebaseOffset(); if (mCapped) { buffer.estimateVertexCount((mNumSegHeight + 1) * (mNumSegBase + 1) + 2 * (mNumSegBase + 1) + 2); buffer.estimateIndexCount(mNumSegHeight * (mNumSegBase + 1) * 6 + 6 * mNumSegBase); } else { buffer.estimateVertexCount((mNumSegHeight + 1) * (mNumSegBase + 1)); buffer.estimateIndexCount(mNumSegHeight * (mNumSegBase + 1) * 6); } float deltaAngle = (Math.TWO_PI / mNumSegBase); float deltaHeight = mHeight / (float)mNumSegHeight; int offset = 0; for (uint i = 0; i <= mNumSegHeight; i++) { for (uint j = 0; j <= mNumSegBase; j++) { float x0 = mRadius * cosf(j * deltaAngle); float z0 = mRadius * sinf(j * deltaAngle); addPoint(ref buffer, new Vector3(x0, (float)i * deltaHeight, z0), new Vector3(x0, 0f, z0).NormalisedCopy, new Vector2((float)j / (float)mNumSegBase, (float)i / (float)mNumSegHeight)); if (i != mNumSegHeight) { buffer.index(offset + (int)mNumSegBase + 1); buffer.index(offset); buffer.index(offset + (int)mNumSegBase); buffer.index(offset + (int)mNumSegBase + 1); buffer.index(offset + 1); buffer.index(offset); } offset++; } } if (mCapped) { //low cap int centerIndex = offset; addPoint(ref buffer, Vector3.ZERO, Vector3.NEGATIVE_UNIT_Y, Vector2.ZERO); offset++; for (uint j = 0; j <= mNumSegBase; j++) { float x0 = cosf(j * deltaAngle); float z0 = sinf(j * deltaAngle); addPoint(ref buffer, new Vector3(mRadius * x0, 0.0f, mRadius * z0), Vector3.NEGATIVE_UNIT_Y, new Vector2(x0, z0)); if (j != mNumSegBase) { buffer.index(centerIndex); buffer.index(offset); buffer.index(offset + 1); } offset++; } // high cap centerIndex = offset; addPoint(ref buffer, new Vector3(0, mHeight, 0), Vector3.UNIT_Y, Vector2.ZERO); offset++; for (uint j = 0; j <= mNumSegBase; j++) { float x0 = cosf(j * deltaAngle); float z0 = sinf(j * deltaAngle); addPoint(ref buffer, new Vector3(x0 * mRadius, mHeight, mRadius * z0), Vector3.UNIT_Y, new Vector2(x0, z0)); if (j != mNumSegBase) { buffer.index(centerIndex); buffer.index(offset + 1); buffer.index(offset); } offset++; } } }
//----------------------------------------------------------------------- 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 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) { buffer.rebaseOffset(); buffer.estimateVertexCount((mNumSegX + 1) * (mNumSegY + 1)); buffer.estimateIndexCount(mNumSegX * mNumSegY * 6); int offset = 0; Vector3 vX = mNormal.Perpendicular; Vector3 vY = mNormal.CrossProduct(vX); Vector3 delta1 = mSizeX / (float)mNumSegX * vX; Vector3 delta2 = mSizeY / (float)mNumSegY * vY; // build one corner of the square Vector3 orig = -0.5f * mSizeX * vX - 0.5f * mSizeY * vY; for (ushort i1 = 0; i1 <= mNumSegX; i1++) { for (ushort i2 = 0; i2 <= mNumSegY; i2++) { addPoint(ref buffer, orig + i1 * delta1 + i2 * delta2, mNormal, new Vector2(i1 / (float)mNumSegX, i2 / (float)mNumSegY)); } } bool reverse = false; if (delta1.CrossProduct(delta2).DotProduct(mNormal) > 0f) { reverse = true; } for (ushort n1 = 0; n1 < mNumSegX; n1++) { for (ushort n2 = 0; n2 < mNumSegY; n2++) { if (reverse) { buffer.index(offset + 0); buffer.index(offset + (int)(mNumSegY + 1)); buffer.index(offset + 1); buffer.index(offset + 1); buffer.index(offset + (int)(mNumSegY + 1)); buffer.index(offset + (int)(mNumSegY + 1) + 1); } else { buffer.index(offset + 0); buffer.index(offset + 1); buffer.index(offset + (int)(mNumSegY + 1)); buffer.index(offset + 1); buffer.index(offset + (int)(mNumSegY + 1) + 1); buffer.index(offset + (int)(mNumSegY + 1)); } offset++; } offset++; } //return this; }
//----------------------------------------------------------------------- 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); } } }
// * // * 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) { buffer.rebaseOffset(); buffer.estimateVertexCount((2 * mNumRings + 2) * (mNumSegments + 1) + (mNumSegHeight - 1) * (mNumSegments + 1)); buffer.estimateIndexCount((2 * mNumRings + 1) * (mNumSegments + 1) * 6 + (mNumSegHeight - 1) * (mNumSegments + 1) * 6); float fDeltaRingAngle = (Math.HALF_PI / mNumRings); float fDeltaSegAngle = (Math.TWO_PI / mNumSegments); float sphereRatio = mRadius / (2 * mRadius + mHeight); float cylinderRatio = mHeight / (2 * mRadius + mHeight); int offset = 0; // Top half sphere // Generate the group of rings for the sphere for (uint ring = 0; ring <= mNumRings; ring++) { float r0 = mRadius * sinf(ring * fDeltaRingAngle); float y0 = mRadius * cosf(ring * fDeltaRingAngle); // Generate the group of segments for the current ring for (uint seg = 0; seg <= mNumSegments; seg++) { float x0 = r0 * cosf(seg * fDeltaSegAngle); float z0 = r0 * sinf(seg * fDeltaSegAngle); // Add one vertex to the strip which makes up the sphere addPoint(ref buffer, new Vector3(x0, 0.5f * mHeight + y0, z0), new Vector3(x0, y0, z0).NormalisedCopy, new Vector2((float)seg / (float)mNumSegments, (float)ring / (float)mNumRings * sphereRatio)); // each vertex (except the last) has six indices pointing to it buffer.index(offset + (int)mNumSegments + 1); buffer.index(offset + (int)mNumSegments); buffer.index(offset); buffer.index(offset + (int)mNumSegments + 1); buffer.index(offset); buffer.index(offset + 1); offset++; } // end for seg } // end for ring // Cylinder part float deltaAngle = (Math.TWO_PI / mNumSegments); float deltamHeight = mHeight / (float)mNumSegHeight; for (ushort i = 1; i < mNumSegHeight; i++) { for (ushort j = 0; j <= mNumSegments; j++) { float x0 = mRadius * cosf(j * deltaAngle); float z0 = mRadius * sinf(j * deltaAngle); addPoint(ref buffer, new Vector3(x0, 0.5f * mHeight - i * deltamHeight, z0), new Vector3(x0, 0, z0).NormalisedCopy, new Vector2(j / (float)mNumSegments, i / (float)mNumSegHeight * cylinderRatio + sphereRatio)); buffer.index(offset + (int)mNumSegments + 1); buffer.index(offset + (int)mNumSegments); buffer.index(offset); buffer.index(offset + (int)mNumSegments + 1); buffer.index(offset); buffer.index(offset + 1); offset++; } } // Bottom half sphere // Generate the group of rings for the sphere for (uint ring = 0; ring <= mNumRings; ring++) { float r0 = mRadius * sinf(Math.HALF_PI + ring * fDeltaRingAngle); float y0 = mRadius * cosf(Math.HALF_PI + ring * fDeltaRingAngle); // Generate the group of segments for the current ring for (uint seg = 0; seg <= mNumSegments; seg++) { float x0 = r0 * cosf(seg * fDeltaSegAngle); float z0 = r0 * sinf(seg * fDeltaSegAngle); // Add one vertex to the strip which makes up the sphere addPoint(ref buffer, new Vector3(x0, -0.5f * mHeight + y0, z0), new Vector3(x0, y0, z0).NormalisedCopy, new Vector2((float)seg / (float)mNumSegments, (float)ring / (float)mNumRings * sphereRatio + cylinderRatio + sphereRatio)); if (ring != mNumRings) { // each vertex (except the last) has six indices pointing to it buffer.index(offset + (int)mNumSegments + 1); buffer.index(offset + (int)mNumSegments); buffer.index(offset); buffer.index(offset + (int)mNumSegments + 1); buffer.index(offset); buffer.index(offset + 1); } offset++; } // end for seg } // end for ring }
// * // * 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) { buffer.rebaseOffset(); buffer.estimateVertexCount((mNumSegHeight + 1) * (mNumSegBase + 1) * 2 + (mNumSegBase + 1) * 4); buffer.estimateIndexCount(6 * (mNumSegBase + 1) * mNumSegHeight * 2 + 6 * mNumSegBase * 2); float deltaAngle = (Math.TWO_PI / mNumSegBase); float deltaHeight = mHeight / (float)mNumSegHeight; int offset = 0; for (uint i = 0; i <= mNumSegHeight; i++) { for (uint j = 0; j <= mNumSegBase; j++) { float x0 = mOuterRadius * cosf(j * deltaAngle); float z0 = mOuterRadius * sinf(j * deltaAngle); addPoint(ref buffer, new Vector3(x0, i * deltaHeight, z0), new Vector3(x0, 0, z0).NormalisedCopy, new Vector2(j / (float)mNumSegBase, i / (float)mNumSegHeight)); if (i != mNumSegHeight) { buffer.index(offset + (int)mNumSegBase + 1); buffer.index(offset); buffer.index(offset + (int)mNumSegBase); buffer.index(offset + (int)mNumSegBase + 1); buffer.index(offset + 1); buffer.index(offset); } offset++; } } for (uint i = 0; i <= mNumSegHeight; i++) { for (uint j = 0; j <= mNumSegBase; j++) { float x0 = mInnerRadius * cosf(j * deltaAngle); float z0 = mInnerRadius * sinf(j * deltaAngle); addPoint(ref buffer, new Vector3(x0, i * deltaHeight, z0), -new Vector3(x0, 0, z0).NormalisedCopy, new Vector2(j / (float)mNumSegBase, i / (float)mNumSegHeight)); if (i != mNumSegHeight) { buffer.index(offset + (int)mNumSegBase + 1); buffer.index(offset + (int)mNumSegBase); buffer.index(offset); buffer.index(offset + (int)mNumSegBase + 1); buffer.index(offset); buffer.index(offset + 1); } offset++; } } //low cap for (uint j = 0; j <= mNumSegBase; j++) { float x0 = mInnerRadius * cosf(j * deltaAngle); float z0 = mInnerRadius * sinf(j * deltaAngle); addPoint(ref buffer, new Vector3(x0, 0.0f, z0), Vector3.NEGATIVE_UNIT_Y, new Vector2(j / (float)mNumSegBase, 1.0f)); x0 = mOuterRadius * cosf(j * deltaAngle); z0 = mOuterRadius * sinf(j * deltaAngle); addPoint(ref buffer, new Vector3(x0, 0.0f, z0), Vector3.NEGATIVE_UNIT_Y, new Vector2(j / (float)mNumSegBase, 0.0f)); if (j != mNumSegBase) { buffer.index(offset); buffer.index(offset + 1); buffer.index(offset + 3); buffer.index(offset + 2); buffer.index(offset); buffer.index(offset + 3); } offset += 2; } //high cap for (uint j = 0; j <= mNumSegBase; j++) { float x0 = mInnerRadius * cosf(j * deltaAngle); float z0 = mInnerRadius * sinf(j * deltaAngle); addPoint(ref buffer, new Vector3(x0, mHeight, z0), Vector3.UNIT_Y, new Vector2(j / (float)mNumSegBase, 0.0f)); x0 = mOuterRadius * cosf(j * deltaAngle); z0 = mOuterRadius * sinf(j * deltaAngle); addPoint(ref buffer, new Vector3(x0, mHeight, z0), Vector3.UNIT_Y, new Vector2(j / (float)mNumSegBase, 1.0f)); if (j != mNumSegBase) { buffer.index(offset + 1); buffer.index(offset); buffer.index(offset + 3); buffer.index(offset); buffer.index(offset + 2); buffer.index(offset + 3); } offset += 2; } }
/// Internal. Builds an "edge" of the rounded box, ie a quarter cylinder //* // * xPos,yPos,zPos : 1 => positive // -1 => negative // 0 => undefined // // //ORIGINAL LINE: void _addEdge(TriangleBuffer& buffer, short xPos, short yPos, short zPos) const private void _addEdge(ref TriangleBuffer buffer, short xPos, short yPos, short zPos) { int offset = 0; Vector3 centerPosition = 0.5f * xPos * mSizeX * Vector3.UNIT_X + .5f * yPos * mSizeY * Vector3.UNIT_Y + .5f * zPos * mSizeZ * Vector3.UNIT_Z; Vector3 vy0 = (1.0f - Math.Abs(xPos)) * Vector3.UNIT_X + (1.0f - Math.Abs(yPos)) * Vector3.UNIT_Y + (1.0f - Math.Abs(zPos)) * Vector3.UNIT_Z; //extrusion direction Vector3 vx0 = Utils.vectorAntiPermute(vy0); Vector3 vz0 = Utils.vectorPermute(vy0); if (vx0.DotProduct(centerPosition) < 0.0) { vx0 = -vx0; } if (vz0.DotProduct(centerPosition) < 0.0) { vz0 = -vz0; } if (vx0.CrossProduct(vy0).DotProduct(vz0) < 0.0) { vy0 = -vy0; } float height = (1 - Math.Abs(xPos)) * mSizeX + (1 - Math.Abs(yPos)) * mSizeY + (1 - Math.Abs(zPos)) * mSizeZ; Vector3 offsetPosition = centerPosition - .5f * height * vy0; int numSegHeight = 1; if (xPos == 0) { numSegHeight = mNumSegX; } else if (yPos == 0) { numSegHeight = mNumSegY; } else if (zPos == 0) { numSegHeight = mNumSegZ; } float deltaAngle = (Math.HALF_PI / mChamferNumSeg); float deltaHeight = height / (float)numSegHeight; buffer.rebaseOffset(); buffer.estimateIndexCount((uint)(6 * numSegHeight * mChamferNumSeg)); buffer.estimateVertexCount((uint)((numSegHeight + 1) * (mChamferNumSeg + 1))); for (ushort i = 0; i <= numSegHeight; i++) { for (ushort j = 0; j <= mChamferNumSeg; j++) { float x0 = mChamferSize * cosf(j * deltaAngle); float z0 = mChamferSize * sinf(j * deltaAngle); //addPoint(ref buffer, new Vector3(x0 * vx0 + i * deltaHeight * vy0 + z0 * vz0 + offsetPosition), (x0 * vx0 + z0 * vz0).NormalisedCopy, new Vector2(j / (float)mChamferNumSeg, i / (float)numSegHeight)); //addPoint(buffer, Vector3(x0 * vx0 + i * deltaHeight * vy0 + z0 * vz0 + offsetPosition), // (x0 * vx0 + z0 * vz0).normalisedCopy(), // Vector2(j / (Real)mChamferNumSeg, i / (Real)numSegHeight)); addPoint(ref buffer, (x0 * vx0 + i * deltaHeight * vy0 + z0 * vz0 + offsetPosition), (x0 * vx0 + z0 * vz0).NormalisedCopy, new Vector2(j / (float)mChamferNumSeg, i / (float)numSegHeight) ); if (i != numSegHeight && j != mChamferNumSeg) { buffer.index(offset + mChamferNumSeg + 2); buffer.index(offset); buffer.index(offset + mChamferNumSeg + 1); buffer.index(offset + mChamferNumSeg + 2); buffer.index(offset + 1); buffer.index(offset); } offset++; } } }