private void GetDefaultVertices(eDir s, double scale, out VertexT2dN3dV3d first, out VertexT2dN3dV3d second, out VertexT2dN3dV3d third) { VertexT2dN3dV3d t1 = new VertexT2dN3dV3d(), t2 = new VertexT2dN3dV3d(), t3 = new VertexT2dN3dV3d(); switch (s) { case eDir.FrontTopRight: t1 = new VertexT2dN3dV3d(new Vector2d(0.5, 1.0), Vector3d.UnitY, Vector3d.UnitY * scale); t2 = new VertexT2dN3dV3d(new Vector2d(0.0, 0.0), Vector3d.UnitZ, Vector3d.UnitZ * scale); t3 = new VertexT2dN3dV3d(new Vector2d(0.5, 0.0), Vector3d.UnitX, Vector3d.UnitX * scale); break; case eDir.FrontBottomRight: t1 = new VertexT2dN3dV3d(new Vector2d(0.5, 0.0), Vector3d.UnitX, Vector3d.UnitX * scale); t2 = new VertexT2dN3dV3d(new Vector2d(0.0, 0.0), Vector3d.UnitZ, Vector3d.UnitZ * scale); t3 = new VertexT2dN3dV3d(new Vector2d(0.5, 1.0), -Vector3d.UnitY, -Vector3d.UnitY * scale); break; case eDir.FrontBottomLeft: t1 = new VertexT2dN3dV3d(new Vector2d(0.5, 0.0), Vector3d.UnitX, Vector3d.UnitX * scale); t2 = new VertexT2dN3dV3d(new Vector2d(0.5, 1.0), -Vector3d.UnitY, -Vector3d.UnitY * scale); t3 = new VertexT2dN3dV3d(new Vector2d(1.0, 0.0), -Vector3d.UnitZ, -Vector3d.UnitZ * scale); break; case eDir.FrontTopLeft: t1 = new VertexT2dN3dV3d(new Vector2d(1.0, 0.0), -Vector3d.UnitZ, -Vector3d.UnitZ * scale); t2 = new VertexT2dN3dV3d(new Vector2d(0.5, 1.0), Vector3d.UnitY, Vector3d.UnitY * scale); t3 = new VertexT2dN3dV3d(new Vector2d(0.5, 0.0), Vector3d.UnitX, Vector3d.UnitX * scale); break; case eDir.BackTopRight: t1 = new VertexT2dN3dV3d(new Vector2d(0.5, 1.0), Vector3d.UnitY, Vector3d.UnitY * scale); t2 = new VertexT2dN3dV3d(new Vector2d(0.0, 1.0), -Vector3d.UnitX, -Vector3d.UnitX * scale); t3 = new VertexT2dN3dV3d(new Vector2d(0.0, 0.0), Vector3d.UnitZ, Vector3d.UnitZ * scale); break; case eDir.BackBottomRight: t1 = new VertexT2dN3dV3d(new Vector2d(0.5, 1.0), -Vector3d.UnitY, -Vector3d.UnitY * scale); t2 = new VertexT2dN3dV3d(new Vector2d(0.0, 0.0), Vector3d.UnitZ, Vector3d.UnitZ * scale); t3 = new VertexT2dN3dV3d(new Vector2d(0.0, 1.0), -Vector3d.UnitX, -Vector3d.UnitX * scale); break; case eDir.BackBottomLeft: t1 = new VertexT2dN3dV3d(new Vector2d(0.5, 1.0), -Vector3d.UnitY, -Vector3d.UnitY * scale); t2 = new VertexT2dN3dV3d(new Vector2d(1.0, 1.0), -Vector3d.UnitX, -Vector3d.UnitX * scale); t3 = new VertexT2dN3dV3d(new Vector2d(1.0, 0.0), -Vector3d.UnitZ, -Vector3d.UnitZ * scale); break; case eDir.BackTopLeft: t1 = new VertexT2dN3dV3d(new Vector2d(0.5, 1.0), Vector3d.UnitY, Vector3d.UnitY * scale); t2 = new VertexT2dN3dV3d(new Vector2d(1.0, 0.0), -Vector3d.UnitZ, -Vector3d.UnitZ * scale); t3 = new VertexT2dN3dV3d(new Vector2d(1.0, 1.0), -Vector3d.UnitX, -Vector3d.UnitX * scale); break; } first = t1; second = t2; third = t3; }
public static void GetArray(ref List <Chunk> c, out VertexT2dN3dV3d[] vbo, out uint[] ibo) { uint VertexCounter = 0; uint IndexCounter = 0; foreach (Chunk ch in c) { VertexCounter += ch.VertexCount; IndexCounter += ch.IndexCount; } vbo = new VertexT2dN3dV3d[VertexCounter]; ibo = new uint[IndexCounter]; VertexCounter = 0; IndexCounter = 0; foreach (Chunk ch in c) { for (int i = 0; i < ch.Vertices.Length; i++) { vbo[VertexCounter + i] = ch.Vertices[i]; } for (int i = 0; i < ch.Indices.Length; i++) { ibo[IndexCounter + i] = ch.Indices[i] + VertexCounter; } VertexCounter += (uint)ch.VertexCount; IndexCounter += (uint)ch.IndexCount; } }
internal static void GetVertexArray(ref TetrahedronFace[] input, out VertexT2dN3dV3d[] output) { output = new VertexT2dN3dV3d[input.Length * 3]; int counter = 0; for (int i = 0; i < input.Length; i++) { input[i].GetVertices(out output[counter + 0], out output[counter + 1], out output[counter + 2]); counter += 3; } }
/// <summary>Returns 3 Vertices which form a CCW triangle.</summary> public void GetVertices(out VertexT2dN3dV3d first, out VertexT2dN3dV3d second, out VertexT2dN3dV3d third) { first.TexCoord = this.ATexCoord; first.Normal = this.Normal; first.Position = this.APosition; second.TexCoord = this.BTexCoord; second.Normal = this.Normal; second.Position = this.BPosition; third.TexCoord = this.CTexCoord; third.Normal = this.Normal; third.Position = this.CPosition; }
public void GetArraysforVbo(out PrimitiveType primitives, out VertexT2dN3dV3d[] vertices, out uint[] indices) { primitives = PrimitiveMode; vertices = new VertexT2dN3dV3d[VertexArray.Length]; for (uint i = 0; i < VertexArray.Length; i++) { vertices[i].TexCoord = VertexArray[i].TexCoord; vertices[i].Normal = VertexArray[i].Normal; vertices[i].Position = VertexArray[i].Position; } indices = IndexArray; }
public VboShape(ref PrimitiveType primitives, ref VertexT2dN3dV3d[] vertices, ref uint[] indices, bool useDL) : base(useDL) { PrimitiveMode = primitives; VertexArray = new VertexT2dN3dV3d[vertices.Length]; for (uint i = 0; i < vertices.Length; i++) { VertexArray[i] = vertices[i]; } IndexArray = new uint[indices.Length]; for (uint i = 0; i < indices.Length; i++) { IndexArray[i] = indices[i]; } }
private void Subdivide(double Scale, ref VertexT2dN3dV3d first, ref VertexT2dN3dV3d second, ref VertexT2dN3dV3d third, out Chunk c) { c = new Chunk(6, 12); c.Vertices[0] = first; Vector3d.Lerp(ref first.Position, ref second.Position, 0.5, out c.Vertices[1].Normal); c.Vertices[1].Normal.Normalize(); c.Vertices[1].Position = c.Vertices[1].Normal * Scale; Vector2d.Lerp(ref first.TexCoord, ref second.TexCoord, 0.5, out c.Vertices[1].TexCoord); Vector3d.Lerp(ref third.Position, ref first.Position, 0.5, out c.Vertices[2].Normal); c.Vertices[2].Normal.Normalize(); c.Vertices[2].Position = c.Vertices[2].Normal * Scale; Vector2d.Lerp(ref third.TexCoord, ref first.TexCoord, 0.5, out c.Vertices[2].TexCoord); c.Vertices[3] = second; Vector3d.Lerp(ref second.Position, ref third.Position, 0.5, out c.Vertices[4].Normal); c.Vertices[4].Normal.Normalize(); c.Vertices[4].Position = c.Vertices[4].Normal * Scale; Vector2d.Lerp(ref second.TexCoord, ref third.TexCoord, 0.5, out c.Vertices[4].TexCoord); c.Vertices[5] = third; #region Indices c.Indices[0] = 0; c.Indices[1] = 1; c.Indices[2] = 2; c.Indices[3] = 2; c.Indices[4] = 1; c.Indices[5] = 4; c.Indices[6] = 1; c.Indices[7] = 3; c.Indices[8] = 4; c.Indices[9] = 2; c.Indices[10] = 4; c.Indices[11] = 5; #endregion Indices }
public TorusKnot(int pathsteps, int shapevertices, double radius, int p, int q, int TexCount, bool useDL) : base(useDL) { Trace.Assert(pathsteps >= MINPathSteps, "A Path must have at least " + MINPathSteps + " Steps to form a volume."); Trace.Assert(shapevertices >= MINShapeVertices, "A Shape must contain at least " + MINShapeVertices + " Vertices to be considered valid and create a volume."); Trace.Assert(TexCount >= 1, "at least 1 Texture set is required."); PrimitiveMode = PrimitiveType.TriangleStrip; Vector3d[] PathPositions = new Vector3d[pathsteps]; #region Find the center Points for each step on the path for (int i = 0; i < pathsteps; i++) { double Angle = (i / (double)pathsteps) * TwoPi; double AngleTimesP = Angle * p; double AngleTimesQ = Angle * q; double r = (0.5 * (2.0 + System.Math.Sin(AngleTimesQ))); PathPositions[i] = new Vector3d((r * System.Math.Cos(AngleTimesP)), (r * System.Math.Cos(AngleTimesQ)), (r * System.Math.Sin(AngleTimesP))); } #endregion Find the center Points for each step on the path #region Find the Torus length Vector3d result; double[] Lengths = new double[pathsteps]; Vector3d.Subtract(ref PathPositions[pathsteps - 1], ref PathPositions[0], out result); Lengths[0] = result.Length; double TotalLength = result.Length; for (int i = 1; i < pathsteps; i++) // skipping { Vector3d.Subtract(ref PathPositions[i - 1], ref PathPositions[i], out result); Lengths[i] = result.Length; TotalLength += result.Length; } Trace.WriteLine("the TorusKnot's length is: " + TotalLength + " "); #endregion Find the Torus length VertexArray = new VertexT2dN3dV3d[pathsteps * shapevertices]; #region Loft a circle Shape along the path double TwoPiThroughVert = TwoPi / shapevertices; // precalc for reuse for (uint i = 0; i < pathsteps; i++) { Vector3d last, next, normal, tangent; if (i == pathsteps - 1) { next = PathPositions[0]; } else { next = PathPositions[i + 1]; } if (i == 0) { last = PathPositions[pathsteps - 1]; } else { last = PathPositions[i - 1]; } Vector3d.Subtract(ref next, ref last, out tangent); // Guesstimate tangent tangent.Normalize(); Vector3d.Add(ref next, ref last, out normal); // Approximate N normal.Normalize(); Vector3d.Multiply(ref normal, radius, out normal); // scale the shape to desired radius for (uint j = 0; j < shapevertices; j++) { uint index = i * (uint)shapevertices + j; // Create a point on the plane and rotate it Matrix4d RotationMatrix = Matrix4d.Rotate(tangent, -(j * TwoPiThroughVert)); Vector3d point = Vector3d.TransformVector(normal, RotationMatrix); Vector3d.Add(ref PathPositions[i], ref point, out VertexArray[index].Position); // Since the used shape is a circle, the Vertex normal's heading is easy to find Vector3d.Subtract(ref VertexArray[index].Position, ref PathPositions[i], out VertexArray[index].Normal); VertexArray[index].Normal.Normalize(); // just generate some semi-useful UVs to fill blanks VertexArray[index].TexCoord = new Vector2d((double)(i / TotalLength / TexCount), j / (shapevertices - 1.0)); } } #endregion Loft a circle Shape along the path PathPositions = null; // not needed anymore uint currentindex = 0; #region Build a Triangle strip from the Vertices IndexArray = new uint[pathsteps * (shapevertices * 2 + 2)]; // 2 triangles per vertex, +2 due to added degenerate triangles for (uint i = 0; i < pathsteps; i++) { uint RowCurrent = i * (uint)shapevertices; uint RowBelow; if (i == pathsteps - 1) { RowBelow = 0; // for the last row, the first row is the following } else { RowBelow = (i + 1) * (uint)shapevertices; } // new ring begins here for (uint j = 0; j < shapevertices; j++) { IndexArray[currentindex++] = RowCurrent + j; IndexArray[currentindex++] = RowBelow + j; } // ring ends here, repeat first 2 vertices to insert 2 degenerate triangles to reach following ring IndexArray[currentindex++] = RowCurrent; IndexArray[currentindex++] = RowBelow; } #endregion Build a Triangle strip from the Vertices }
public SlicedSphere(double radius, Vector3d offset, eSubdivisions subdivs, eDir[] sides, bool useDL) : base(useDL) { double Diameter = radius; PrimitiveMode = PrimitiveType.Triangles; if (sides[0] == eDir.All) { sides = new eDir[] { eDir.FrontTopRight, eDir.FrontBottomRight, eDir.FrontBottomLeft, eDir.FrontTopLeft, eDir.BackTopRight, eDir.BackBottomRight, eDir.BackBottomLeft, eDir.BackTopLeft, }; } VertexArray = new VertexT2dN3dV3d[sides.Length * 3]; IndexArray = new uint[sides.Length * 3]; uint counter = 0; foreach (eDir s in sides) { GetDefaultVertices(s, Diameter, out VertexArray[counter + 0], out VertexArray[counter + 1], out VertexArray[counter + 2]); IndexArray[counter + 0] = counter + 0; IndexArray[counter + 1] = counter + 1; IndexArray[counter + 2] = counter + 2; counter += 3; } if (subdivs != eSubdivisions.Zero) { for (int s = 0; s < (int)subdivs; s++) { #region Assemble Chunks and convert to Arrays List <Chunk> AllChunks = new List <Chunk>(); for (uint i = 0; i < IndexArray.Length; i += 3) { Chunk chu; Subdivide(Diameter, ref VertexArray[IndexArray[i + 0]], ref VertexArray[IndexArray[i + 1]], ref VertexArray[IndexArray[i + 2]], out chu); AllChunks.Add(chu); } Chunk.GetArray(ref AllChunks, out VertexArray, out IndexArray); AllChunks.Clear(); #endregion Assemble Chunks and convert to Arrays } } for (int i = 0; i < VertexArray.Length; i++) { Vector3d.Add(ref VertexArray[i].Position, ref offset, out VertexArray[i].Position); } }
public SlicedHose(eSide side, uint subdivs, double scale, Vector3d offset1, Vector3d offset2, bool useDL) : base(useDL) { PrimitiveMode = PrimitiveType.Triangles; Vector3d start = Vector3d.Zero, end = Vector3d.Zero; double TexCoordStart = 0f, TexCoordEnd = 0f; switch (side) { #region Around X Axis case eSide.BottomRight: start = -Vector3d.UnitY; end = Vector3d.UnitZ; TexCoordStart = 0.0; TexCoordEnd = 0.25; break; case eSide.TopRight: start = Vector3d.UnitZ; end = Vector3d.UnitY; TexCoordStart = 0.25; TexCoordEnd = 0.5; break; case eSide.TopLeft: start = Vector3d.UnitY; end = -Vector3d.UnitZ; TexCoordStart = 0.5; TexCoordEnd = 0.75; break; case eSide.BottomLeft: start = -Vector3d.UnitZ; end = -Vector3d.UnitY; TexCoordStart = 0.75; TexCoordEnd = 1.0; break; #endregion Around X Axis #region Around Y Axis case eSide.FrontRight: start = Vector3d.UnitX; end = Vector3d.UnitZ; TexCoordStart = 0.0; TexCoordEnd = 0.25; break; case eSide.BackRight: start = Vector3d.UnitZ; end = -Vector3d.UnitX; TexCoordStart = 0.25; TexCoordEnd = 0.5; break; case eSide.BackLeft: start = -Vector3d.UnitX; end = -Vector3d.UnitZ; TexCoordStart = 0.5; TexCoordEnd = 0.75; break; case eSide.FrontLeft: start = -Vector3d.UnitZ; end = Vector3d.UnitX; TexCoordStart = 0.75; TexCoordEnd = 1.0; break; #endregion Around Y Axis #region Around Z Axis case eSide.FrontBottom: start = -Vector3d.UnitY; end = Vector3d.UnitX; TexCoordStart = 0.0; TexCoordEnd = 0.25; break; case eSide.BackBottom: start = -Vector3d.UnitX; end = -Vector3d.UnitY; TexCoordStart = 0.25; TexCoordEnd = 0.5; break; case eSide.BackTop: start = Vector3d.UnitY; end = -Vector3d.UnitX; TexCoordStart = 0.5; TexCoordEnd = 0.75; break; case eSide.FrontTop: start = Vector3d.UnitX; end = Vector3d.UnitY; TexCoordStart = 0.75; TexCoordEnd = 1.0; break; #endregion Around Z Axis } VertexT2dN3dV3d[] temp = new VertexT2dN3dV3d[2 + subdivs]; double divisor = 1.0 / ((double)temp.Length - 1.0); for (int i = 0; i < temp.Length; i++) { float Multiplier = (float)(i * divisor); temp[i].TexCoord.X = TexCoordStart * Multiplier + TexCoordEnd * (1.0f - Multiplier); Slerp(ref start, ref end, Multiplier, out temp[i].Normal); temp[i].Normal.Normalize(); temp[i].Position = temp[i].Normal; temp[i].Position *= scale; } VertexArray = new VertexT2dN3dV3d[temp.Length * 2]; IndexArray = new uint[(temp.Length - 1) * 2 * 3]; uint VertexCounter = 0, IndexCounter = 0, QuadCounter = 0; for (int i = 0; i < temp.Length; i++) { VertexArray[VertexCounter + 0].TexCoord.X = temp[i].TexCoord.X; VertexArray[VertexCounter + 0].TexCoord.Y = 0.0; VertexArray[VertexCounter + 0].Normal = temp[i].Normal; VertexArray[VertexCounter + 0].Position = temp[i].Position + offset1; VertexArray[VertexCounter + 1].TexCoord.X = temp[i].TexCoord.X; VertexArray[VertexCounter + 1].TexCoord.Y = 1.0; VertexArray[VertexCounter + 1].Normal = temp[i].Normal; VertexArray[VertexCounter + 1].Position = temp[i].Position + offset2; VertexCounter += 2; if (i < temp.Length - 1) { IndexArray[IndexCounter + 0] = QuadCounter + 0; IndexArray[IndexCounter + 1] = QuadCounter + 1; IndexArray[IndexCounter + 2] = QuadCounter + 2; IndexArray[IndexCounter + 3] = QuadCounter + 2; IndexArray[IndexCounter + 4] = QuadCounter + 1; IndexArray[IndexCounter + 5] = QuadCounter + 3; IndexCounter += 6; QuadCounter += 2; } } }
public MengerSponge(double scale, eSubdivisions subdivs, bool useDL) : base(useDL) { List <MengerCube> Cubes; switch (subdivs) { case eSubdivisions.None: CreateDefaultMengerSponge(scale, out Cubes); break; case eSubdivisions.One: case eSubdivisions.Two: case eSubdivisions.Three: CreateDefaultMengerSponge(scale, out Cubes); for (int i = 0; i < (int)subdivs; i++) { List <MengerCube> temp; SubdivideMengerSponge(ref Cubes, out temp); Cubes = temp; } break; default: throw new ArgumentOutOfRangeException("Subdivisions other than contained in the enum cause overflows and are not allowed."); } PrimitiveMode = PrimitiveType.Triangles; #region Get Array Dimensions uint VertexCount = 0, IndexCount = 0; foreach (MengerCube c in Cubes) { uint t1, t2; c.GetArraySizes(out t1, out t2); VertexCount += t1; IndexCount += t2; } VertexArray = new VertexT2dN3dV3d[VertexCount]; IndexArray = new uint[IndexCount]; #endregion Get Array Dimensions List <Chunk> AllChunks = new List <Chunk>(); #region Build a temporary List of all loose pieces foreach (MengerCube c in Cubes) { c.GetVboAndIbo(ref AllChunks); } #endregion Build a temporary List of all loose pieces #region Assemble pieces into a single VBO and IBO VertexCount = 0; IndexCount = 0; foreach (Chunk ch in AllChunks) { for (int i = 0; i < ch.Vertices.Length; i++) { VertexArray[VertexCount + i] = ch.Vertices[i]; } for (int i = 0; i < ch.Indices.Length; i++) { IndexArray[IndexCount + i] = ch.Indices[i] + VertexCount; } VertexCount += (uint)ch.Vertices.Length; IndexCount += (uint)ch.Indices.Length; } #endregion Assemble pieces into a single VBO and IBO AllChunks.Clear(); }