/// <inheritdoc /> public override List <int> GenerateIndexList(int resolutionU, int resolutionV, int indexOffset = 0) { // The index list of a model tells the GPU between which vertices to draw triangles. Each three consecutive // indices constitute a single triangle. Since the Capsule vertex array consists of several lists stitched // together, the indices of the shaft and endCap will have shifted by some amount. Therefore, calculate // this index offset for all submodels: int indexOffset2 = indexOffset + Hemisphere.CalculateVertexCount(resolutionU, resolutionU / 4) - resolutionU; int indexOffset3 = indexOffset2 + Cylinder.CalculateVertexCount(resolutionU, resolutionV) - resolutionU; int indexOffset4 = indexOffset3 + Hemisphere.CalculateVertexCount(resolutionU, resolutionU / 4) - resolutionU; // Generate the startCap indices as normal: List <int> startCapList = startCap.GenerateIndexList(resolutionU, resolutionU / 4, indexOffset); // Generate a shaft, using the last ring of the startCap to begin with. This is done by subtracting // `resolutionU` from indexOffset2. This automatically stitches the gap between the start cap and the shaft: List <int> shaftList = shaft.GenerateIndexList(resolutionU, resolutionV - 1, indexOffset2); // Generate the endCap indices as normal: List <int> endCapList = endCap.GenerateIndexList(resolutionU, resolutionU / 4, indexOffset3); // The final ring between the endCap and the shaft must be generated manually: List <int> stitchList = new List <int>(resolutionU); // Add a ring of triangles: for (int i = 1; i < resolutionU - 1; i++) { int invertedI = resolutionU - i; stitchList.Add(indexOffset + invertedI + indexOffset4); stitchList.Add(indexOffset + (i + 1) + indexOffset3 - resolutionU); stitchList.Add(indexOffset + i + indexOffset3 - resolutionU); stitchList.Add(indexOffset + (invertedI - 1) + indexOffset4); stitchList.Add(indexOffset + (i + 1) + indexOffset3 - resolutionU); stitchList.Add(indexOffset + invertedI + indexOffset4); } // Stitch the end of the ring of triangles: stitchList.Add(indexOffset + 1 + indexOffset4); stitchList.Add(indexOffset + indexOffset3 - resolutionU); stitchList.Add(indexOffset + resolutionU - 1 + indexOffset3 - resolutionU); stitchList.Add(indexOffset + indexOffset4); stitchList.Add(indexOffset + indexOffset3 - resolutionU); stitchList.Add(indexOffset + 1 + indexOffset4); stitchList.Add(indexOffset + resolutionU - 1 + indexOffset4); stitchList.Add(indexOffset + 1 + indexOffset3 - resolutionU); stitchList.Add(indexOffset + indexOffset3 - resolutionU); stitchList.Add(indexOffset + indexOffset4); stitchList.Add(indexOffset + resolutionU - 1 + indexOffset4); stitchList.Add(indexOffset + indexOffset3 - resolutionU); return(startCapList.Concat(shaftList).Concat(endCapList).Concat(stitchList).ToList()); }
public override List <int> GenerateIndexList(int resolutionU, int resolutionV, int indexOffset = 0) { int indexOffset2 = indexOffset + Hemisphere.CalculateVertexCount(resolutionU, resolutionU / 4); int indexOffset3 = indexOffset + indexOffset2 + Cylinder.CalculateVertexCount(resolutionU, resolutionV); List <int> startCapList = startCap.GenerateIndexList(resolutionU, resolutionU / 4, indexOffset); List <int> shaftList = shaft.GenerateIndexList(resolutionU, resolutionV, indexOffset2); List <int> endCapList = endCap.GenerateIndexList(resolutionU, resolutionU / 4, indexOffset3); return(startCapList.Concat(shaftList).Concat(endCapList).ToList()); }
/// <inheritdoc /> public override List <Vertex> GenerateVertexList(int resolutionU, int resolutionV) { // Generate the vertices of two end caps, and a shaft in between: List <Vertex> startCapList = startCap.GenerateVertexList(resolutionU, resolutionU / 4); List <Vertex> endCapList = endCap.GenerateVertexList(resolutionU, resolutionU / 4); // Using a slice, remove the first and last ring of vertices of the shaft, which overlap with the last // rings of the startCap and endCap respectively. Later we will stitch the shaft and end caps together with // triangles between them, during the GenerateIndexList() step. Slice <Vertex> shaftSlice = new Slice <Vertex>( shaft.GenerateVertexList(resolutionU, resolutionV), resolutionU, Cylinder.CalculateVertexCount(resolutionU, resolutionV) - 2 * resolutionU); // Recalculate the surface normal between the cylinder and the start cap: for (int i = 0; i < (resolutionU - 1); i++) { dvec3 surfacePosition = startCapList[(resolutionU / 4 - 1) * resolutionU + i + 1].Position; dvec3 du = surfacePosition - startCapList[(resolutionU / 4 - 1) * resolutionU + i + 1 + 1].Position; dvec3 dv = surfacePosition - shaftSlice[i].Position; // Calculate the position of the rings of vertices: dvec3 surfaceNormal = dvec3.Cross(du.Normalized, dv.Normalized); startCapList[(resolutionU / 4 - 1) * resolutionU + i + 1] = new Vertex((vec3)surfacePosition, (vec3)surfaceNormal); } // Stitch the end of the triangles: dvec3 surfacePosition2 = startCapList[(resolutionU / 4 - 1) * resolutionU + resolutionU].Position; dvec3 du2 = surfacePosition2 - startCapList[(resolutionU / 4 - 1) * resolutionU + 1].Position; dvec3 dv2 = surfacePosition2 - shaftSlice[resolutionU].Position; // Calculate the position of the rings of vertices: dvec3 surfaceNormal2 = dvec3.Cross(du2.Normalized, dv2.Normalized); startCapList[(resolutionU / 4 - 1) * resolutionU + resolutionU] = new Vertex((vec3)surfacePosition2, (vec3)surfaceNormal2); return(startCapList.Concat(shaftSlice).Concat(endCapList).ToList()); }