/// <summary> /// Create a mesh for a RoundLine. /// </summary> /// <remarks> /// The RoundLine mesh has 3 sections: /// 1. Two quads, from 0 to 1 (left to right) /// 2. A half-disc, off the left side of the quad /// 3. A half-disc, off the right side of the quad /// /// The X and Y coordinates of the "normal" encode the rho and theta of each vertex /// The "texture" encodes whether to scale and translate the vertex horizontally by length and radius /// </remarks> private void CreateRoundLineMesh() { const int primsPerCap = 12; // A higher primsPerCap produces rounder endcaps at the cost of more vertices const int verticesPerCap = primsPerCap * 2 + 2; const int primsPerCore = 4; const int verticesPerCore = 8; numInstances = 200; numVertices = (verticesPerCore + verticesPerCap + verticesPerCap) * numInstances; numPrimitivesPerInstance = primsPerCore + primsPerCap + primsPerCap; numPrimitives = numPrimitivesPerInstance * numInstances; numIndices = 3 * numPrimitives; short[] indices = new short[numIndices]; RoundLineVertex[] tri = new RoundLineVertex[numVertices]; translationData = new float[numInstances * 4]; // Used in Draw() int iv = 0; int ii = 0; int iVertex; int iIndex; for (int instance = 0; instance < numInstances; instance++) { // core vertices const float pi2 = MathHelper.PiOver2; const float threePi2 = 3 * pi2; iVertex = iv; tri[iv++] = new RoundLineVertex(new Vector3(0.0f, -1.0f, 0), new Vector2(1, threePi2), new Vector2(0, 0), instance); tri[iv++] = new RoundLineVertex(new Vector3(0.0f, -1.0f, 0), new Vector2(1, threePi2), new Vector2(0, 1), instance); tri[iv++] = new RoundLineVertex(new Vector3(0.0f, 0.0f, 0), new Vector2(0, threePi2), new Vector2(0, 1), instance); tri[iv++] = new RoundLineVertex(new Vector3(0.0f, 0.0f, 0), new Vector2(0, threePi2), new Vector2(0, 0), instance); tri[iv++] = new RoundLineVertex(new Vector3(0.0f, 0.0f, 0), new Vector2(0, pi2), new Vector2(0, 1), instance); tri[iv++] = new RoundLineVertex(new Vector3(0.0f, 0.0f, 0), new Vector2(0, pi2), new Vector2(0, 0), instance); tri[iv++] = new RoundLineVertex(new Vector3(0.0f, 1.0f, 0), new Vector2(1, pi2), new Vector2(0, 1), instance); tri[iv++] = new RoundLineVertex(new Vector3(0.0f, 1.0f, 0), new Vector2(1, pi2), new Vector2(0, 0), instance); // core indices indices[ii++] = (short)(iVertex + 0); indices[ii++] = (short)(iVertex + 1); indices[ii++] = (short)(iVertex + 2); indices[ii++] = (short)(iVertex + 2); indices[ii++] = (short)(iVertex + 3); indices[ii++] = (short)(iVertex + 0); indices[ii++] = (short)(iVertex + 4); indices[ii++] = (short)(iVertex + 6); indices[ii++] = (short)(iVertex + 5); indices[ii++] = (short)(iVertex + 6); indices[ii++] = (short)(iVertex + 7); indices[ii++] = (short)(iVertex + 5); // left halfdisc iVertex = iv; iIndex = ii; for (int i = 0; i < primsPerCap + 1; i++) { float deltaTheta = MathHelper.Pi / primsPerCap; float theta0 = MathHelper.PiOver2 + i * deltaTheta; float theta1 = theta0 + deltaTheta / 2; // even-numbered indices are at the center of the halfdisc tri[iVertex + 0] = new RoundLineVertex(new Vector3(0, 0, 0), new Vector2(0, theta1), new Vector2(0, 0), instance); // odd-numbered indices are at the perimeter of the halfdisc float x = (float)Math.Cos(theta0); float y = (float)Math.Sin(theta0); tri[iVertex + 1] = new RoundLineVertex(new Vector3(x, y, 0), new Vector2(1, theta0), new Vector2(1, 0), instance); if (i < primsPerCap) { // indices follow this pattern: (0, 1, 3), (2, 3, 5), (4, 5, 7), ... indices[iIndex + 0] = (short)(iVertex + 0); indices[iIndex + 1] = (short)(iVertex + 1); indices[iIndex + 2] = (short)(iVertex + 3); iIndex += 3; ii += 3; } iVertex += 2; iv += 2; } // right halfdisc for (int i = 0; i < primsPerCap + 1; i++) { float deltaTheta = MathHelper.Pi / primsPerCap; float theta0 = 3 * MathHelper.PiOver2 + i * deltaTheta; float theta1 = theta0 + deltaTheta / 2; float theta2 = theta0 + deltaTheta; // even-numbered indices are at the center of the halfdisc tri[iVertex + 0] = new RoundLineVertex(new Vector3(0, 0, 0), new Vector2(0, theta1), new Vector2(0, 1), instance); // odd-numbered indices are at the perimeter of the halfdisc float x = (float)Math.Cos(theta0); float y = (float)Math.Sin(theta0); tri[iVertex + 1] = new RoundLineVertex(new Vector3(x, y, 0), new Vector2(1, theta0), new Vector2(1, 1), instance); if (i < primsPerCap) { // indices follow this pattern: (0, 1, 3), (2, 3, 5), (4, 5, 7), ... indices[iIndex + 0] = (short)(iVertex + 0); indices[iIndex + 1] = (short)(iVertex + 1); indices[iIndex + 2] = (short)(iVertex + 3); iIndex += 3; ii += 3; } iVertex += 2; iv += 2; } } vb = new VertexBuffer(device, typeof(RoundLineVertex), numVertices, BufferUsage.None); vb.SetData<RoundLineVertex>(tri); ib = new IndexBuffer(device, IndexElementSize.SixteenBits, numIndices, BufferUsage.None); ib.SetData<short>(indices); }
/// <summary> /// Create a mesh for a RoundLine. /// </summary> /// <remarks> /// The RoundLine mesh has 3 sections: /// 1. Two quads, from 0 to 1 (left to right) /// 2. A half-disc, off the left side of the quad /// 3. A half-disc, off the right side of the quad /// /// The X and Y coordinates of the "normal" encode the rho and theta of each vertex /// The "texture" encodes whether to scale and translate the vertex horizontally by length and radius /// </remarks> private void CreateRoundLineMesh() { const int PRIMS_PER_CAP = 12; // A higher primsPerCap produces rounder endcaps at the cost of more vertices const int VERTICES_PER_CAP = PRIMS_PER_CAP * 2 + 2; const int PRIMS_PER_CORE = 4; const int VERTICES_PER_CORE = 8; _numInstances = 200; _numVertices = (VERTICES_PER_CORE + VERTICES_PER_CAP + VERTICES_PER_CAP) * _numInstances; _numPrimitivesPerInstance = PRIMS_PER_CORE + PRIMS_PER_CAP + PRIMS_PER_CAP; _numPrimitives = _numPrimitivesPerInstance * _numInstances; _numIndices = 3 * _numPrimitives; var indices = new short[_numIndices]; _bytesPerVertex = RoundLineVertex.SIZE_IN_BYTES; var tri = new RoundLineVertex[_numVertices]; _translationData = new float[_numInstances * 4]; // Used in Draw() int iv = 0; int ii = 0; int iVertex; int iIndex; for (int instance = 0; instance < _numInstances; instance++) { // core vertices const float pi2 = MathHelper.PiOver2; const float threePi2 = 3 * pi2; iVertex = iv; tri[iv++] = new RoundLineVertex(new Vector3(0.0f, -1.0f, 0), new Vector2(1, threePi2), new Vector2(0, 0), instance); tri[iv++] = new RoundLineVertex(new Vector3(0.0f, -1.0f, 0), new Vector2(1, threePi2), new Vector2(0, 1), instance); tri[iv++] = new RoundLineVertex(new Vector3(0.0f, 0.0f, 0), new Vector2(0, threePi2), new Vector2(0, 1), instance); tri[iv++] = new RoundLineVertex(new Vector3(0.0f, 0.0f, 0), new Vector2(0, threePi2), new Vector2(0, 0), instance); tri[iv++] = new RoundLineVertex(new Vector3(0.0f, 0.0f, 0), new Vector2(0, pi2), new Vector2(0, 1), instance); tri[iv++] = new RoundLineVertex(new Vector3(0.0f, 0.0f, 0), new Vector2(0, pi2), new Vector2(0, 0), instance); tri[iv++] = new RoundLineVertex(new Vector3(0.0f, 1.0f, 0), new Vector2(1, pi2), new Vector2(0, 1), instance); tri[iv++] = new RoundLineVertex(new Vector3(0.0f, 1.0f, 0), new Vector2(1, pi2), new Vector2(0, 0), instance); // core indices indices[ii++] = (short)(iVertex + 0); indices[ii++] = (short)(iVertex + 1); indices[ii++] = (short)(iVertex + 2); indices[ii++] = (short)(iVertex + 2); indices[ii++] = (short)(iVertex + 3); indices[ii++] = (short)(iVertex + 0); indices[ii++] = (short)(iVertex + 4); indices[ii++] = (short)(iVertex + 6); indices[ii++] = (short)(iVertex + 5); indices[ii++] = (short)(iVertex + 6); indices[ii++] = (short)(iVertex + 7); indices[ii++] = (short)(iVertex + 5); // left halfdisc iVertex = iv; iIndex = ii; for (int i = 0; i < PRIMS_PER_CAP + 1; i++) { float deltaTheta = MathHelper.Pi / PRIMS_PER_CAP; float theta0 = MathHelper.PiOver2 + i * deltaTheta; float theta1 = theta0 + deltaTheta / 2; // even-numbered indices are at the center of the halfdisc tri[iVertex + 0] = new RoundLineVertex(new Vector3(0, 0, 0), new Vector2(0, theta1), new Vector2(0, 0), instance); // odd-numbered indices are at the perimeter of the halfdisc float x = (float)Math.Cos(theta0); float y = (float)Math.Sin(theta0); tri[iVertex + 1] = new RoundLineVertex(new Vector3(x, y, 0), new Vector2(1, theta0), new Vector2(1, 0), instance); if (i < PRIMS_PER_CAP) { // indices follow this pattern: (0, 1, 3), (2, 3, 5), (4, 5, 7), ... indices[iIndex + 0] = (short)(iVertex + 0); indices[iIndex + 1] = (short)(iVertex + 1); indices[iIndex + 2] = (short)(iVertex + 3); iIndex += 3; ii += 3; } iVertex += 2; iv += 2; } // right halfdisc for (int i = 0; i < PRIMS_PER_CAP + 1; i++) { float deltaTheta = MathHelper.Pi / PRIMS_PER_CAP; float theta0 = 3 * MathHelper.PiOver2 + i * deltaTheta; float theta1 = theta0 + deltaTheta / 2; // even-numbered indices are at the center of the halfdisc tri[iVertex + 0] = new RoundLineVertex(new Vector3(0, 0, 0), new Vector2(0, theta1), new Vector2(0, 1), instance); // odd-numbered indices are at the perimeter of the halfdisc float x = (float)Math.Cos(theta0); float y = (float)Math.Sin(theta0); tri[iVertex + 1] = new RoundLineVertex(new Vector3(x, y, 0), new Vector2(1, theta0), new Vector2(1, 1), instance); if (i < PRIMS_PER_CAP) { // indices follow this pattern: (0, 1, 3), (2, 3, 5), (4, 5, 7), ... indices[iIndex + 0] = (short)(iVertex + 0); indices[iIndex + 1] = (short)(iVertex + 1); indices[iIndex + 2] = (short)(iVertex + 3); iIndex += 3; ii += 3; } iVertex += 2; iv += 2; } } _vb = new VertexBuffer(_device, _numVertices * _bytesPerVertex, BufferUsage.None); _vb.SetData(tri); _vdecl = new VertexDeclaration(_device, RoundLineVertex.VertexElements); _ib = new IndexBuffer(_device, _numIndices * 2, BufferUsage.None, IndexElementSize.SixteenBits); _ib.SetData(indices); }