/// <summary> /// Create a Quad (--,+-,++,-+) winding anticlockwise /// </summary> /// <param name="width">Width required</param> /// <param name="height">Height required</param> /// <param name="rotationradians">Any rotation</param> /// <param name="pos">World position</param> /// <param name="scale">Any sizing for both axis</param> /// <param name="ccw">Counter clock wise winding</param> /// <returns>Quad</returns> public static Vector4[] CreateQuad(float width, float height, Vector3?rotationradians = null, Vector3?pos = null, float scale = 1.0f, bool ccw = true) { width = width / 2.0f * scale; height = height / 2.0f * scale; Vector4[] vertices1; if (ccw) { vertices1 = new Vector4[] { new Vector4(-width, 0, -height, 1.0f), // -, - new Vector4(+width, 0, -height, 1.0f), // +, - new Vector4(+width, 0, +height, 1.0f), // +, + new Vector4(-width, 0, +height, 1.0f), // -, + }; } else { vertices1 = new Vector4[] { new Vector4(-width, 0, -height, 1.0f), // -, - new Vector4(-width, 0, +height, 1.0f), // -, + new Vector4(+width, 0, +height, 1.0f), // +, + new Vector4(+width, 0, -height, 1.0f), // +, - }; } GLStaticsVector4.RotPos(ref vertices1, rotationradians, pos); return(vertices1); }
/// <summary> /// Create a box using lines /// </summary> /// <param name="width">Box width</param> /// <param name="depth">Box depth</param> /// <param name="height">Box height</param> /// <param name="pos">Position of box in world</param> /// <param name="rotationradians">Any box rotation</param> /// <returns>Array of points of the box</returns> public static Vector4[] CreateBox(float width, float depth, float height, Vector3 pos, Vector3?rotationradians = null) { Vector4[] botvertices = CreateQuad(width, depth, pos: new Vector3(pos.X, pos.Y - height / 2, pos.Z)); Vector4[] topvertices = CreateQuad(width, depth, pos: new Vector3(pos.X, pos.Y + height / 2, pos.Z)); Vector4[] box = new Vector4[24]; box[0] = botvertices[0]; box[1] = botvertices[1]; box[2] = botvertices[1]; box[3] = botvertices[2]; box[4] = botvertices[2]; box[5] = botvertices[3]; box[6] = botvertices[3]; box[7] = botvertices[0]; box[8] = topvertices[0]; box[9] = topvertices[1]; box[10] = topvertices[1]; box[11] = topvertices[2]; box[12] = topvertices[2]; box[13] = topvertices[3]; box[14] = topvertices[3]; box[15] = topvertices[0]; box[16] = botvertices[0]; box[17] = topvertices[0]; box[18] = botvertices[1]; box[19] = topvertices[1]; box[20] = botvertices[2]; box[21] = topvertices[2]; box[22] = botvertices[3]; box[23] = topvertices[3]; GLStaticsVector4.RotPos(ref box, rotationradians); return(box); }
/// <summary> /// Create a Quad (--,+-,-+,++) for tristrips /// </summary> /// <param name="width">Width required</param> /// <param name="height">Height required</param> /// <param name="rotationradians">Any rotation</param> /// <param name="pos">World position</param> /// <param name="scale">Any sizing for both axis</param> /// <returns>Quad</returns> public static Vector4[] CreateQuadTriStrip(float width, float height, Vector3?rotationradians = null, Vector3?pos = null, float scale = 1.0f) { width = width / 2.0f * scale; height = height / 2.0f * scale; Vector4[] vertices2 = { new Vector4(-width, 0, -height, 1.0f), //BL new Vector4(+width, 0, -height, 1.0f), //BR new Vector4(-width, 0, +height, 1.0f), //TL new Vector4(+width, 0, +height, 1.0f), //TR }; GLStaticsVector4.RotPos(ref vertices2, rotationradians, pos); return(vertices2); }
/// <summary> /// Create a point cube - a set of vertex on each point of a cube /// </summary> /// <param name="size">Size of cub</param> /// <param name="pos">Optional, offset position to place model</param> /// <returns></returns> public static Vector4[] CreateVertexPointCube(float size, Vector3?pos = null) { size = size / 2f; // halv side - and other half + Vector4[] vertices = { new Vector4(new Vector4(-size, size, size, 1.0f)), // arranged as wound clockwise around top, then around bottom new Vector4(new Vector4(size, size, size, 1.0f)), new Vector4(new Vector4(size, size, -size, 1.0f)), new Vector4(new Vector4(-size, size, -size, 1.0f)), new Vector4(new Vector4(-size, -size, size, 1.0f)), new Vector4(new Vector4(size, -size, size, 1.0f)), new Vector4(new Vector4(size, -size, -size, 1.0f)), new Vector4(new Vector4(-size, -size, -size, 1.0f)), }; if (pos != null) { GLStaticsVector4.Translate(ref vertices, pos.Value); } return(vertices); }
/// <summary> /// Sphere in triangles /// </summary> /// <param name="recursionlevel">Detail level, 3 provides a good sphere</param> /// <param name="size">Size of sphere</param> /// <param name="pos">Optional world position</param> /// <param name="ccw">Winding of triangles</param> /// <returns>Tuple of Vertex with W=1 and texcoords</returns> static public Tuple <Vector4[], Vector2[]> CreateTexturedSphereFromTriangles(int recursionlevel, float size, Vector3?pos = null, bool ccw = true) { var faces = CreateSphereFaces(recursionlevel, size); Vector4[] coords = new Vector4[faces.Count * 3]; Vector2[] texcoords = new Vector2[faces.Count * 3]; float zcorr = ccw ? -1 : 1; int p = 0; foreach (var tri in faces) { var uv1 = GetSphereCoord(tri.V1); var uv2 = GetSphereCoord(tri.V2); var uv3 = GetSphereCoord(tri.V3); FixColorStrip(ref uv1, ref uv2, ref uv3); //System.Diagnostics.Debug.WriteLine(tri.V1 + "->" + uv1 + " " + // tri.V2 + "->" + uv2 + " " + // tri.V3 + "->" + uv3 + " " // ); coords[p] = new Vector4(new Vector3(tri.V1.X, tri.V1.Y, zcorr * tri.V1.Z), 1); // we swap Z for CCW winding order texcoords[p++] = uv1; coords[p] = new Vector4(new Vector3(tri.V2.X, tri.V2.Y, zcorr * tri.V2.Z), 1); texcoords[p++] = uv2; coords[p] = new Vector4(new Vector3(tri.V3.X, tri.V3.Y, zcorr * tri.V3.Z), 1); texcoords[p++] = uv3; } if (pos != null) { GLStaticsVector4.Translate(ref coords, pos.Value); } return(new Tuple <Vector4[], Vector2[]>(coords, texcoords)); }
/// <summary> /// Sphere in triangles /// </summary> /// <param name="recursionlevel">Detail level, 3 provides a good sphere</param> /// <param name="size">Size of sphere</param> /// <param name="pos">Optional world position</param> /// <param name="ccw">Winding of triangles</param> /// <returns>Vertex with W=1</returns> public static Vector4[] CreateSphereFromTriangles(int recursionlevel, float size, Vector3?pos = null, bool ccw = true) { var faces = CreateSphereFaces(recursionlevel, size); List <Vector4> vertices = new List <Vector4>(); float zcorr = ccw ? -1 : 1; foreach (var tri in faces) { vertices.Add(new Vector4(tri.V1.X, tri.V1.Y, zcorr * tri.V1.Z, 1.0f)); vertices.Add(new Vector4(tri.V2.X, tri.V2.Y, zcorr * tri.V2.Z, 1.0f)); vertices.Add(new Vector4(tri.V3.X, tri.V3.Y, zcorr * tri.V3.Z, 1.0f)); } var array = vertices.ToArray(); if (pos != null) { GLStaticsVector4.Translate(ref array, pos.Value); } return(array); }
/// <summary>A solid cube built with triangles</summary> /// <param name="size">Size of sides</param> /// <param name="sides">What sides to construct</param> /// <param name="pos">Optional, offset position to place model</param> /// <returns>Vector4 array of positions (w=1)</returns> public static Vector4[] CreateSolidCubeFromTriangles(float size, Sides[] sides, Vector3?pos = null) { size = size / 2f; // halv side - and other half + List <Vector4> vert = new List <Vector4>(); bool all = Array.IndexOf(sides, Sides.All) >= 0; if (all || Array.IndexOf(sides, Sides.Left) >= 0) { vert.AddRange(new Vector4[] { new Vector4(new Vector4(-size, -size, -size, 1.0f)), // left side, lower right triangle new Vector4(new Vector4(-size, size, -size, 1.0f)), new Vector4(new Vector4(-size, -size, size, 1.0f)), new Vector4(new Vector4(-size, -size, size, 1.0f)), // left side, upper left triangle new Vector4(new Vector4(-size, size, -size, 1.0f)), new Vector4(new Vector4(-size, size, size, 1.0f)), }); } if (all || Array.IndexOf(sides, Sides.Right) >= 0) { vert.AddRange(new Vector4[] { new Vector4(new Vector4(size, -size, size, 1.0f)), // right side, lower right triangle new Vector4(new Vector4(size, size, size, 1.0f)), new Vector4(new Vector4(size, -size, -size, 1.0f)), new Vector4(new Vector4(size, -size, -size, 1.0f)), // right side, upper left triangle new Vector4(new Vector4(size, size, size, 1.0f)), new Vector4(new Vector4(size, size, -size, 1.0f)), }); } if (all || Array.IndexOf(sides, Sides.Bottom) >= 0) { vert.AddRange(new Vector4[] { new Vector4(new Vector4(size, -size, size, 1.0f)), // bottom face, lower right new Vector4(new Vector4(size, -size, -size, 1.0f)), new Vector4(new Vector4(-size, -size, size, 1.0f)), new Vector4(new Vector4(-size, -size, size, 1.0f)), //bottom face, upper left new Vector4(new Vector4(size, -size, -size, 1.0f)), new Vector4(new Vector4(-size, -size, -size, 1.0f)), }); } if (all || Array.IndexOf(sides, Sides.Top) >= 0) { vert.AddRange(new Vector4[] { new Vector4(new Vector4(size, size, -size, 1.0f)), // top face new Vector4(new Vector4(size, size, size, 1.0f)), new Vector4(new Vector4(-size, size, -size, 1.0f)), new Vector4(new Vector4(-size, size, -size, 1.0f)), new Vector4(new Vector4(size, size, size, 1.0f)), new Vector4(new Vector4(-size, size, size, 1.0f)), }); } if (all || Array.IndexOf(sides, Sides.Front) >= 0) { vert.AddRange(new Vector4[] { new Vector4(new Vector4(size, -size, -size, 1.0f)), // front face, lower right new Vector4(new Vector4(size, size, -size, 1.0f)), new Vector4(new Vector4(-size, -size, -size, 1.0f)), new Vector4(new Vector4(-size, -size, -size, 1.0f)), // front face, upper left new Vector4(new Vector4(size, size, -size, 1.0f)), new Vector4(new Vector4(-size, size, -size, 1.0f)), }); } if (all || Array.IndexOf(sides, Sides.Back) >= 0) { vert.AddRange(new Vector4[] { new Vector4(new Vector4(-size, -size, size, 1.0f)), // back face, lower right new Vector4(new Vector4(-size, size, size, 1.0f)), new Vector4(new Vector4(size, -size, size, 1.0f)), new Vector4(new Vector4(size, -size, size, 1.0f)), // back face, upper left new Vector4(new Vector4(-size, size, size, 1.0f)), new Vector4(new Vector4(size, size, size, 1.0f)), }); } var array = vert.ToArray(); if (pos != null) { GLStaticsVector4.Translate(ref array, pos.Value); } return(array); }