private void BuildLine(IGeometry <T> geometry, ITessellationHints hints, Vector3[] colors, IPath path) { var vertexDataList = new List <T>(); var indexDataList = new List <uint>(); // Draw a line for (var i = 0; i < path.PathLocations.Length; ++i) { var vtx = new T(); vtx.SetPosition(path.PathLocations[i]); vtx.SetNormal(Vector3.UnitX); vtx.SetTexCoord(Vector2.Zero); vtx.SetColor3(colors[0]); vertexDataList.Add(vtx); indexDataList.Add((uint)i); } geometry.VertexData = vertexDataList.ToArray(); geometry.IndexData = indexDataList.ToArray(); geometry.VertexLayout = VertexLayoutHelpers.GetLayoutDescription(typeof(T)); var pSet = DrawElements <T> .Create( geometry, PrimitiveTopology.LineStrip, (uint)geometry.IndexData.Length, 1, 0, 0, 0); geometry.PrimitiveSets.Add(pSet); }
private void BuildCylinder(IGeometry <T> geometry, ITessellationHints hints, Vector3[] colors, IPath path) { var tangents = Util.Math.ComputePathTangents(path.PathLocations); var nSegments = (int)System.Math.Floor(10f * hints.DetailRatio); if (nSegments < 4) { nSegments = 4; } var shape = new Vector2[nSegments]; for (var i = 0; i < nSegments; ++i) { var theta = i * 2 * System.Math.PI / nSegments; var r = hints.Radius; shape[i] = new Vector2((float)(r * System.Math.Sin(theta)), (float)(r * System.Math.Cos(theta))); } var extrusion = Math.ExtrudeShape(shape, path.PathLocations); // Build from quad strips for (var j = 0; j < nSegments - 1; ++j) { Begin(); BuildFromIndicies(j, j + 1, extrusion, path); End(); } // Join the last bit... BuildFromIndicies(nSegments - 1, 0, extrusion, path); BuildVertexAndIndexArrays(out var vertexArray, out var indexArray, colors); geometry.VertexData = vertexArray; geometry.IndexData = indexArray; geometry.VertexLayout = VertexLayoutHelpers.GetLayoutDescription(typeof(T)); var pSet = DrawElements <T> .Create( geometry, PrimitiveTopology.TriangleList, (uint)geometry.IndexData.Length, 1, 0, 0, 0); geometry.PrimitiveSets.Add(pSet); }
internal void Build(IGeometry <T> geometry, ITessellationHints hints, Vector3[] colors, ISphere sphere) { if (hints.NormalsType == NormalsType.PerFace) { throw new ArgumentException("Per-Face Normals are not supported for spheres"); } if (hints.ColorsType == ColorsType.ColorPerFace) { throw new ArgumentException("Per-Face Colors are not supported for spheres"); } if (hints.ColorsType == ColorsType.ColorPerVertex) { throw new ArgumentException("Per-Vertex Colors are not supported for spheres"); } if (colors.Length < 1) { throw new ArgumentException("Must provide at least one color for spheres"); } uint numSegments = 40; uint numRows = 20; var ratio = hints.DetailRatio; if (ratio > 0.0f && ratio != 1.0f) { numRows = (uint)(numRows * ratio); if (numRows < MIN_NUM_ROWS) { numRows = MIN_NUM_ROWS; } numSegments = (uint)(numSegments * ratio); if (numSegments < MIN_NUM_SEGMENTS) { numSegments = MIN_NUM_SEGMENTS; } } var lDelta = (float)System.Math.PI / (float)numRows; var vDelta = 1.0f / (float)numRows; var angleDelta = (float)System.Math.PI * 2.0f / numSegments; var texCoordHorzDelta = 1.0f / numSegments; if (hints.CreateBackFace) { var lBase = -(float)System.Math.PI * 0.5f; var rBase = 0.0f; var zBase = -sphere.Radius; var vBase = 0.0f; var nzBase = -1.0f; var nRatioBase = 0.0f; for (uint rowi = 0; rowi < numRows; ++rowi) { var lTop = (float)(lBase + lDelta); var rTop = (float)System.Math.Cos(lTop) * sphere.Radius; var zTop = (float)System.Math.Sin(lTop) * sphere.Radius; var vTop = vBase + vDelta; var nzTop = (float)System.Math.Sin(lTop); var nRatioTop = (float)System.Math.Cos(lTop); Begin(); var angle = 0.0f; var texCoord = 0.0f; for (uint topi = 0; topi < numSegments; ++topi, angle += angleDelta, texCoord += texCoordHorzDelta) { var c = (float)System.Math.Cos(angle); var s = (float)System.Math.Sin(angle); Normal3f(-c * nRatioBase, -s * nRatioBase, -nzBase); TexCoord2f(texCoord, vBase); Vertex3f(c * rBase, s * rBase, zBase); Normal3f(-c * nRatioTop, -s * nRatioTop, -nzTop); TexCoord2f(texCoord, vTop); Vertex3f(c * rTop, s * rTop, zTop); } // do last point by hand to ensure no round off errors. Normal3f(-nRatioBase, 0.0f, -nzBase); TexCoord2f(1.0f, vBase); Vertex3f(rBase, 0.0f, zBase); Normal3f(-nRatioTop, 0.0f, -nzTop); TexCoord2f(1.0f, vTop); Vertex3f(rTop, 0.0f, zTop); End(); lBase = lTop; rBase = rTop; zBase = zTop; vBase = vTop; nzBase = nzTop; nRatioBase = nRatioTop; } } if (hints.CreateFrontFace) { var lBase = -(float)System.Math.PI * 0.5f; var rBase = 0.0f; var zBase = -sphere.Radius; var vBase = 0.0f; var nzBase = -1.0f; var nRatioBase = 0.0f; for (uint rowi = 0; rowi < numRows; ++rowi) { var lTop = lBase + lDelta; var rTop = (float)System.Math.Cos(lTop) * sphere.Radius; var zTop = (float)System.Math.Sin(lTop) * sphere.Radius; var vTop = vBase + vDelta; var nzTop = (float)System.Math.Sin(lTop); var nRatioTop = (float)System.Math.Cos(lTop); Begin(); var angle = 0.0f; var texCoord = 0.0f; for (uint topi = 0; topi < numSegments; ++topi, angle += angleDelta, texCoord += texCoordHorzDelta) { float c = (float)System.Math.Cos(angle); float s = (float)System.Math.Sin(angle); Normal3f(c * nRatioTop, s * nRatioTop, nzTop); TexCoord2f(texCoord, vTop); Vertex3f(c * rTop, s * rTop, zTop); Normal3f(c * nRatioBase, s * nRatioBase, nzBase); TexCoord2f(texCoord, vBase); Vertex3f(c * rBase, s * rBase, zBase); } // do last point by hand to ensure no round off errors. Normal3f(nRatioTop, 0.0f, nzTop); TexCoord2f(1.0f, vTop); Vertex3f(rTop, 0.0f, zTop); Normal3f(nRatioBase, 0.0f, nzBase); TexCoord2f(1.0f, vBase); Vertex3f(rBase, 0.0f, zBase); End(); lBase = lTop; rBase = rTop; zBase = zTop; vBase = vTop; nzBase = nzTop; nRatioBase = nRatioTop; } } BuildVertexAndIndexArrays(out var vertexArray, out var indexArray, colors); geometry.VertexData = vertexArray; geometry.IndexData = indexArray; geometry.VertexLayout = VertexLayoutHelpers.GetLayoutDescription(typeof(T)); var pSet = DrawElements <T> .Create( geometry, PrimitiveTopology.TriangleList, (uint)geometry.IndexData.Length, 1, 0, 0, 0); geometry.PrimitiveSets.Add(pSet); }
internal static void Build(IGeometry <T> geometry, ITessellationHints hints, Vector3 [] colors, IBox box) { var dx = box.HalfLengths.X; var dy = box.HalfLengths.Y; var dz = box.HalfLengths.Z; var normVec = Vector3.Normalize(box.HalfLengths); var nx = normVec.X; var ny = normVec.Y; var nz = normVec.Z; var vertices = new Vector3[8] { new Vector3(-dx, +dy, -dz), // T1, L1, Bk2 new Vector3(+dx, +dy, -dz), // T2, R2, Bk1 new Vector3(+dx, +dy, +dz), // T3, R1, F2 new Vector3(-dx, +dy, +dz), // T4, L2, F1 new Vector3(-dx, -dy, -dz), // B4, L4, Bk3 new Vector3(+dx, -dy, -dz), // B3, R3, Bk4 new Vector3(+dx, -dy, +dz), // B2, R4, F3 new Vector3(-dx, -dy, +dz), // B1, L3, F4 }; Vector3[] normals; if (hints.NormalsType == NormalsType.PerVertex) { normals = new Vector3[8] { new Vector3(-nx, +ny, -nz), // T1, L1, Bk2 new Vector3(+nx, +ny, -nz), // T2, R2, Bk1 new Vector3(+nx, +ny, +nz), // T3, R1, F2 new Vector3(-nx, +ny, +nz), // T4, L2, F1 new Vector3(-nx, -ny, -nz), // B4, L4, Bk3 new Vector3(+nx, -ny, -nz), // B3, R3, Bk4 new Vector3(+nx, -ny, +nz), // B2, R4, F3 new Vector3(-nx, -ny, +nz), // B1, L3, F4 }; } else { normals = new Vector3[6] { new Vector3(0, 1, 0), // T new Vector3(0, -1, 0), // B new Vector3(1, 0, 0), // R new Vector3(-1, 0, 0), // L new Vector3(0, 0, 1), // F new Vector3(0, 0, -1) // Bk }; } var texcoords = new Vector2[4] { new Vector2(+0, +0), new Vector2(+0, +1), new Vector2(+1, +1), new Vector2(+1, +0) }; var faces = new Face[6] { new Face(), // T new Face(), // B new Face(), // R new Face(), // L new Face(), // F new Face() // B }; // Set Positions { faces[0].VertexIndices.AddRange(new uint[] { 0, 1, 2, 3 }); // T faces[1].VertexIndices.AddRange(new uint[] { 7, 6, 5, 4 }); // B faces[2].VertexIndices.AddRange(new uint[] { 2, 1, 5, 6 }); // R faces[3].VertexIndices.AddRange(new uint[] { 0, 3, 7, 4 }); // L faces[4].VertexIndices.AddRange(new uint[] { 3, 2, 6, 7 }); // F faces[5].VertexIndices.AddRange(new uint[] { 1, 0, 4, 5 }); // B } // Set Tex Coords { for (uint i = 0; i < 6; ++i) { faces[i].TexCoordIndices.AddRange(new uint[] { 0, 1, 2, 3 }); } } // Set Normals if (hints.NormalsType == NormalsType.PerVertex) { faces[0].NormalIndices.AddRange(new uint[] { 0, 1, 2, 3 }); // T faces[1].NormalIndices.AddRange(new uint[] { 7, 6, 5, 4 }); // B faces[2].NormalIndices.AddRange(new uint[] { 2, 1, 5, 6 }); // R faces[3].NormalIndices.AddRange(new uint[] { 0, 3, 7, 4 }); // L faces[4].NormalIndices.AddRange(new uint[] { 3, 2, 6, 7 }); // F faces[5].NormalIndices.AddRange(new uint[] { 1, 0, 4, 5 }); // B } else // Per face Normals { for (uint i = 0; i < 6; ++i) { faces[i].NormalIndices.AddRange(new uint[] { i, i, i, i }); } } // Set Colors { switch (hints.ColorsType) { case ColorsType.ColorOverall: default: { if (colors.Length < 1) { throw new Exception("Not enough colors specified"); } for (uint i = 0; i < 6; ++i) { faces[i].ColorIndices.AddRange(new uint[] { 0, 0, 0, 0 }); } break; } case ColorsType.ColorPerFace: { if (colors.Length < 6) { throw new Exception("Not enough colors specified for per-face coloring"); } for (uint i = 0; i < 6; ++i) { faces[i].ColorIndices.AddRange(new uint[] { i, i, i, i }); } break; } case ColorsType.ColorPerVertex: { if (colors.Length < 8) { throw new Exception("Not enough colors specified for per-vertex coloring"); } faces[0].ColorIndices.AddRange(new uint[] { 0, 1, 2, 3 }); // T faces[1].ColorIndices.AddRange(new uint[] { 7, 6, 5, 4 }); // B faces[2].ColorIndices.AddRange(new uint[] { 2, 1, 5, 6 }); // R faces[3].ColorIndices.AddRange(new uint[] { 0, 3, 7, 4 }); // L faces[4].ColorIndices.AddRange(new uint[] { 3, 2, 6, 7 }); // F faces[5].ColorIndices.AddRange(new uint[] { 1, 0, 4, 5 }); // B break; } } } var vertexDataList = new List <T>(); foreach (var face in faces) { for (var i = 0; i < face.VertexIndices.Count; ++i) { var vtx = new T(); vtx.SetPosition(vertices[face.VertexIndices[i]]); vtx.SetNormal(normals[face.NormalIndices[i]]); vtx.SetColor3(colors[face.ColorIndices[i]]); vtx.SetTexCoord(texcoords[face.TexCoordIndices[i]]); vertexDataList.Add(vtx); } } geometry.VertexData = vertexDataList.ToArray(); uint[] indices = { 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23, }; geometry.IndexData = indices; geometry.VertexLayout = VertexLayoutHelpers.GetLayoutDescription(typeof(T)); var pSet = DrawElements <T> .Create( geometry, PrimitiveTopology.TriangleList, (uint)geometry.IndexData.Length, 1, 0, 0, 0); geometry.PrimitiveSets.Add(pSet); }