private static void EndCap_DomeHard(ref int pointOffset, ref double[] rotateAnglesForPerp, MeshGeometry3D geometry, Point[] pointsTheta, Transform3D transform, Transform3D normalTransform, TubeRingDome ring, double capHeight, bool isFirst) { // NOTE: There is one more than NumSegmentsPhi Point[] pointsPhi = ring.GetUnitPointsPhi(ring.NumSegmentsPhi); Point3D point; Vector3D normal; int zOffset = pointOffset; #region Triangles - Rings for (int phiCntr = 1; phiCntr < pointsPhi.Length - 1; phiCntr++) // The top cone will be added after this loop { for (int thetaCntr = 0; thetaCntr < pointsTheta.Length - 1; thetaCntr++) { // Phi points are going from bottom to equator <----------- NO????????? // Phi points are going from the equator to the top // pointsTheta are already the length they are supposed to be (not nessassarily a unit circle) #region Top/Left triangle point = new Point3D( pointsTheta[thetaCntr].X * pointsPhi[phiCntr].Y, pointsTheta[thetaCntr].Y * pointsPhi[phiCntr].Y, capHeight * pointsPhi[phiCntr].X); geometry.Positions.Add(transform.Transform(point)); point = new Point3D( pointsTheta[thetaCntr].X * pointsPhi[phiCntr + 1].Y, pointsTheta[thetaCntr].Y * pointsPhi[phiCntr + 1].Y, capHeight * pointsPhi[phiCntr + 1].X); geometry.Positions.Add(transform.Transform(point)); point = new Point3D( pointsTheta[thetaCntr + 1].X * pointsPhi[phiCntr + 1].Y, pointsTheta[thetaCntr + 1].Y * pointsPhi[phiCntr + 1].Y, capHeight * pointsPhi[phiCntr + 1].X); geometry.Positions.Add(transform.Transform(point)); normal = GetNormal(geometry.Positions[zOffset + 0], geometry.Positions[zOffset + 1], geometry.Positions[zOffset + 2]); geometry.Normals.Add(normal); // the normals point straight out of the face geometry.Normals.Add(normal); geometry.Normals.Add(normal); geometry.TriangleIndices.Add(zOffset + 0); geometry.TriangleIndices.Add(zOffset + 1); geometry.TriangleIndices.Add(zOffset + 2); #endregion zOffset += 3; #region Bottom/Right triangle point = new Point3D( pointsTheta[thetaCntr].X * pointsPhi[phiCntr].Y, pointsTheta[thetaCntr].Y * pointsPhi[phiCntr].Y, capHeight * pointsPhi[phiCntr].X); geometry.Positions.Add(transform.Transform(point)); point = new Point3D( pointsTheta[thetaCntr + 1].X * pointsPhi[phiCntr + 1].Y, pointsTheta[thetaCntr + 1].Y * pointsPhi[phiCntr + 1].Y, capHeight * pointsPhi[phiCntr + 1].X); geometry.Positions.Add(transform.Transform(point)); point = new Point3D( pointsTheta[thetaCntr + 1].X * pointsPhi[phiCntr].Y, pointsTheta[thetaCntr + 1].Y * pointsPhi[phiCntr].Y, capHeight * pointsPhi[phiCntr].X); geometry.Positions.Add(transform.Transform(point)); normal = GetNormal(geometry.Positions[zOffset + 0], geometry.Positions[zOffset + 1], geometry.Positions[zOffset + 2]); geometry.Normals.Add(normal); // the normals point straight out of the face geometry.Normals.Add(normal); geometry.Normals.Add(normal); geometry.TriangleIndices.Add(zOffset + 0); geometry.TriangleIndices.Add(zOffset + 1); geometry.TriangleIndices.Add(zOffset + 2); #endregion zOffset += 3; } // Connecting the last 2 points to the first 2 #region Top/Left triangle point = new Point3D( pointsTheta[pointsTheta.Length - 1].X * pointsPhi[phiCntr].Y, pointsTheta[pointsTheta.Length - 1].Y * pointsPhi[phiCntr].Y, capHeight * pointsPhi[phiCntr].X); geometry.Positions.Add(transform.Transform(point)); point = new Point3D( pointsTheta[pointsTheta.Length - 1].X * pointsPhi[phiCntr + 1].Y, pointsTheta[pointsTheta.Length - 1].Y * pointsPhi[phiCntr + 1].Y, capHeight * pointsPhi[phiCntr + 1].X); geometry.Positions.Add(transform.Transform(point)); point = new Point3D( pointsTheta[0].X * pointsPhi[phiCntr + 1].Y, // wrapping theta back around pointsTheta[0].Y * pointsPhi[phiCntr + 1].Y, capHeight * pointsPhi[phiCntr + 1].X); geometry.Positions.Add(transform.Transform(point)); normal = GetNormal(geometry.Positions[zOffset + 0], geometry.Positions[zOffset + 1], geometry.Positions[zOffset + 2]); geometry.Normals.Add(normal); // the normals point straight out of the face geometry.Normals.Add(normal); geometry.Normals.Add(normal); geometry.TriangleIndices.Add(zOffset + 0); geometry.TriangleIndices.Add(zOffset + 1); geometry.TriangleIndices.Add(zOffset + 2); #endregion zOffset += 3; #region Bottom/Right triangle point = new Point3D( pointsTheta[pointsTheta.Length - 1].X * pointsPhi[phiCntr].Y, pointsTheta[pointsTheta.Length - 1].Y * pointsPhi[phiCntr].Y, capHeight * pointsPhi[phiCntr].X); geometry.Positions.Add(transform.Transform(point)); point = new Point3D( pointsTheta[0].X * pointsPhi[phiCntr + 1].Y, pointsTheta[0].Y * pointsPhi[phiCntr + 1].Y, capHeight * pointsPhi[phiCntr + 1].X); geometry.Positions.Add(transform.Transform(point)); point = new Point3D( pointsTheta[0].X * pointsPhi[phiCntr].Y, pointsTheta[0].Y * pointsPhi[phiCntr].Y, capHeight * pointsPhi[phiCntr].X); geometry.Positions.Add(transform.Transform(point)); normal = GetNormal(geometry.Positions[zOffset + 0], geometry.Positions[zOffset + 1], geometry.Positions[zOffset + 2]); geometry.Normals.Add(normal); // the normals point straight out of the face geometry.Normals.Add(normal); geometry.Normals.Add(normal); geometry.TriangleIndices.Add(zOffset + 0); geometry.TriangleIndices.Add(zOffset + 1); geometry.TriangleIndices.Add(zOffset + 2); #endregion zOffset += 3; } #endregion #region Triangles - Cap // This is basically the same idea as EndCap_ConeHard, except for the extra phi bits Point3D topPoint = transform.Transform(new Point3D(0, 0, capHeight)); for (int thetaCntr = 0; thetaCntr < pointsTheta.Length - 1; thetaCntr++) { point = new Point3D( pointsTheta[thetaCntr].X * pointsPhi[1].Y, pointsTheta[thetaCntr].Y * pointsPhi[1].Y, capHeight * pointsPhi[1].X); geometry.Positions.Add(transform.Transform(point)); point = new Point3D( pointsTheta[thetaCntr + 1].X * pointsPhi[1].Y, pointsTheta[thetaCntr + 1].Y * pointsPhi[1].Y, capHeight * pointsPhi[1].X); geometry.Positions.Add(transform.Transform(point)); geometry.Positions.Add(topPoint); normal = GetNormal(geometry.Positions[zOffset + 0], geometry.Positions[zOffset + 1], geometry.Positions[zOffset + 2]); geometry.Normals.Add(normal); // the normals point straight out of the face geometry.Normals.Add(normal); geometry.Normals.Add(normal); geometry.TriangleIndices.Add(zOffset + 0); geometry.TriangleIndices.Add(zOffset + 1); geometry.TriangleIndices.Add(zOffset + 2); zOffset += 3; } // The last triangle links back to zero point = new Point3D( pointsTheta[pointsTheta.Length - 1].X * pointsPhi[1].Y, pointsTheta[pointsTheta.Length - 1].Y * pointsPhi[1].Y, capHeight * pointsPhi[1].X); geometry.Positions.Add(transform.Transform(point)); point = new Point3D( pointsTheta[0].X * pointsPhi[1].Y, pointsTheta[0].Y * pointsPhi[1].Y, capHeight * pointsPhi[1].X); geometry.Positions.Add(transform.Transform(point)); geometry.Positions.Add(topPoint); normal = GetNormal(geometry.Positions[zOffset + 0], geometry.Positions[zOffset + 1], geometry.Positions[zOffset + 2]); geometry.Normals.Add(normal); // the normals point straight out of the face geometry.Normals.Add(normal); geometry.Normals.Add(normal); geometry.TriangleIndices.Add(zOffset + 0); geometry.TriangleIndices.Add(zOffset + 1); geometry.TriangleIndices.Add(zOffset + 2); zOffset += 3; #endregion pointOffset = geometry.Positions.Count; }
private static void EndCap_DomeSoft(ref int pointOffset, ref double[] rotateAnglesForPerp, MeshGeometry3D geometry, Point[] pointsTheta, Transform3D transform, Transform3D normalTransform, TubeRingDome ring, double capHeight, bool isFirst) { // NOTE: There is one more than NumSegmentsPhi Point[] pointsPhi = ring.GetUnitPointsPhi(ring.NumSegmentsPhi); #region Positions/Normals //for (int phiCntr = 0; phiCntr < numSegmentsPhi; phiCntr++) // The top point will be added after this loop for (int phiCntr = pointsPhi.Length - 1; phiCntr > 0; phiCntr--) { if (!isFirst && ring.MergeNormalWithPrevIfSoft) { // Just reuse the points/normals from the previous ring continue; } for (int thetaCntr = 0; thetaCntr < pointsTheta.Length; thetaCntr++) { // Phi points are going from bottom to equator. // pointsTheta are already the length they are supposed to be (not nessassarily a unit circle) Point3D point = new Point3D( pointsTheta[thetaCntr].X * pointsPhi[phiCntr].Y, pointsTheta[thetaCntr].Y * pointsPhi[phiCntr].Y, capHeight * pointsPhi[phiCntr].X); geometry.Positions.Add(transform.Transform(point)); if (ring.MergeNormalWithPrevIfSoft) { //TODO: Merge the normal with rotateAngleForPerp (see the GetCone method) throw new ApplicationException("finish this"); } else { geometry.Normals.Add(normalTransform.Transform(point).ToVector().ToUnit()); // the normal is the same as the point for a sphere (but no tranlate transform) } } } // This is north pole point geometry.Positions.Add(transform.Transform(new Point3D(0, 0, capHeight))); geometry.Normals.Add(normalTransform.Transform(new Vector3D(0, 0, capHeight < 0 ? -1 : 1))); // they can enter a negative height (which would make a bowl) #endregion #region Triangles - Rings int zOffsetBottom = pointOffset; int zOffsetTop; for (int phiCntr = 0; phiCntr < ring.NumSegmentsPhi - 1; phiCntr++) // The top cone will be added after this loop { zOffsetTop = zOffsetBottom + pointsTheta.Length; for (int thetaCntr = 0; thetaCntr < pointsTheta.Length - 1; thetaCntr++) { // Top/Left triangle geometry.TriangleIndices.Add(zOffsetBottom + thetaCntr + 0); geometry.TriangleIndices.Add(zOffsetTop + thetaCntr + 1); geometry.TriangleIndices.Add(zOffsetTop + thetaCntr + 0); // Bottom/Right triangle geometry.TriangleIndices.Add(zOffsetBottom + thetaCntr + 0); geometry.TriangleIndices.Add(zOffsetBottom + thetaCntr + 1); geometry.TriangleIndices.Add(zOffsetTop + thetaCntr + 1); } // Connecting the last 2 points to the first 2 // Top/Left triangle geometry.TriangleIndices.Add(zOffsetBottom + (pointsTheta.Length - 1) + 0); geometry.TriangleIndices.Add(zOffsetTop); // wrapping back around geometry.TriangleIndices.Add(zOffsetTop + (pointsTheta.Length - 1) + 0); // Bottom/Right triangle geometry.TriangleIndices.Add(zOffsetBottom + (pointsTheta.Length - 1) + 0); geometry.TriangleIndices.Add(zOffsetBottom); geometry.TriangleIndices.Add(zOffsetTop); // Prep for the next ring zOffsetBottom = zOffsetTop; } #endregion #region Triangles - Cap int topIndex = geometry.Positions.Count - 1; for (int cntr = 0; cntr < pointsTheta.Length - 1; cntr++) { geometry.TriangleIndices.Add(zOffsetBottom + cntr + 0); geometry.TriangleIndices.Add(zOffsetBottom + cntr + 1); geometry.TriangleIndices.Add(topIndex); } // The last triangle links back to zero geometry.TriangleIndices.Add(zOffsetBottom + pointsTheta.Length - 1 + 0); geometry.TriangleIndices.Add(zOffsetBottom + 0); geometry.TriangleIndices.Add(topIndex); //for (int cntr = 0; cntr < pointsTheta.Length - 1; cntr++) //{ // geometry.TriangleIndices.Add(zOffsetBottom + cntr + 0); // geometry.TriangleIndices.Add(topIndex); // geometry.TriangleIndices.Add(zOffsetBottom + cntr + 1); //} //// The last triangle links back to zero //geometry.TriangleIndices.Add(zOffsetBottom + pointsTheta.Length - 1 + 0); //geometry.TriangleIndices.Add(topIndex); //geometry.TriangleIndices.Add(zOffsetBottom + 0); #endregion pointOffset = geometry.Positions.Count; }