void createVertices() // Note: This can be done a lot more efficiently if multiple spheres have the same number of vertices { vertices = new VertexPositionColorNormal[nvertices]; Vector3 center = new Vector3(0, 0, 0); Vector3 rad = new Vector3(1, 0, 0); for (int x = 0; x < numVertices; x++) { float difx = 360.0f / (float)numVertices; for (int y = 0; y < numVertices; y++) { float dify = 360.0f / (float)numVertices; Matrix zrot = Matrix.CreateRotationZ(MathHelper.ToRadians(y * dify)); Matrix yrot = Matrix.CreateRotationY(MathHelper.ToRadians(x * difx)); Vector3 point = Vector3.Transform(Vector3.Transform(rad, zrot), yrot); point.Normalize(); Vector3 normal = point; vertices[x + y * numVertices] = new VertexPositionColorNormal() { Position = point, Color = color, Normal = normal }; } } }
private VertexPositionColorNormal[] CreateBox() { var vertices = new VertexPositionColorNormal[] { // Front Surface new VertexPositionColorNormal(new Vector3(-1.0f, -1.0f, 1.0f), Color.Blue, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(-1.0f, 1.0f, 1.0f), Color.Red, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(1.0f, -1.0f, 1.0f), Color.Red, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(1.0f, -1.0f, 1.0f), Color.Red, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(-1.0f, 1.0f, 1.0f), Color.Red, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(1.0f, 1.0f, 1.0f), Color.Blue, new Vector3(1, 0, 1)), // Back Surface new VertexPositionColorNormal(new Vector3(1.0f, -1.0f, -1.0f), Color.Yellow, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(1.0f, 1.0f, -1.0f), Color.Yellow, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(-1.0f, -1.0f, -1.0f), Color.Yellow, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(-1.0f, -1.0f, -1.0f), Color.Yellow, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(1.0f, 1.0f, -1.0f), Color.Yellow, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(-1.0f, 1.0f, -1.0f), Color.Yellow, new Vector3(1, 0, 1)), // Left Surface new VertexPositionColorNormal(new Vector3(-1.0f, -1.0f, -1.0f), Color.Blue, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(-1.0f, 1.0f, -1.0f), Color.Blue, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(-1.0f, -1.0f, 1.0f), Color.Blue, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(-1.0f, -1.0f, 1.0f), Color.Blue, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(-1.0f, 1.0f, -1.0f), Color.Blue, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(-1.0f, 1.0f, 1.0f), Color.Blue, new Vector3(1, 0, 1)), // Right Surface new VertexPositionColorNormal(new Vector3(1.0f, -1.0f, 1.0f), Color.Violet, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(1.0f, 1.0f, 1.0f), Color.Violet, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(1.0f, -1.0f, -1.0f), Color.Violet, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(1.0f, -1.0f, -1.0f), Color.Violet, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(1.0f, 1.0f, 1.0f), Color.Violet, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(1.0f, 1.0f, -1.0f), Color.Violet, new Vector3(1, 0, 1)), // Top Surface new VertexPositionColorNormal(new Vector3(-1.0f, 1.0f, 1.0f), Color.Green, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(-1.0f, 1.0f, -1.0f), Color.Green, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(1.0f, 1.0f, 1.0f), Color.Green, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(1.0f, 1.0f, 1.0f), Color.Green, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(-1.0f, 1.0f, -1.0f), Color.Green, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(1.0f, 1.0f, -1.0f), Color.Green, new Vector3(1, 0, 1)), // Bottom Surface new VertexPositionColorNormal(new Vector3(-1.0f, -1.0f, -1.0f), Color.Orange, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(-1.0f, -1.0f, 1.0f), Color.Orange, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(1.0f, -1.0f, -1.0f), Color.Orange, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(1.0f, -1.0f, -1.0f), Color.Orange, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(-1.0f, -1.0f, 1.0f), Color.Orange, new Vector3(1, 0, 1)), new VertexPositionColorNormal(new Vector3(1.0f, -1.0f, 1.0f), Color.Orange, new Vector3(1, 0, 1)), }; return vertices; }
public static IEnumerable <VertexPositionColorNormal> getTris(VertexPositionColorNormal[] source, int Depth, int Width) { VertexPositionColorNormal[,] Data = new VertexPositionColorNormal[Width, Depth]; //The new, easy to read 2D array for (int x = 0; x < Width; x++) //Convert! { for (int y = 0; y < Depth; y++) { Data[x, y] = source[x + y * Width]; } } var result = new List <VertexPositionColorNormal>(); for (int x = 0; x < Width - 1; x++) { for (int y = 0; y < Depth - 1; y++) { var a = Data[x, y]; var b = Data[x + 1, y]; var c = Data[x, y + 1]; if (a.Color != Color.Transparent && b.Color != Color.Transparent && c.Color != Color.Transparent) { result.Add(a); result.Add(b); result.Add(c); } } } for (int x = 1; x < Width; x++) { for (int y = 0; y < Depth - 1; y++) { var a = Data[x, y]; var b = Data[x, y + 1]; var c = Data[x - 1, y + 1]; if (a.Color != Color.Transparent && b.Color != Color.Transparent && c.Color != Color.Transparent) { result.Add(a); result.Add(b); result.Add(c); } } } return(result); }
private static void GenerateNormals(VertexPositionColorNormal[] vertices, int[] indices) { for (int i = 0; i < indices.Length / 3; i++) { Vector3 firstvec = vertices[indices[i * 3 + 1]].Position - vertices[indices[i * 3]].Position; Vector3 secondvec = vertices[indices[i * 3]].Position - vertices[indices[i * 3 + 2]].Position; Vector3 normal = Vector3.Cross(firstvec, secondvec); normal.Normalize(); vertices[indices[i * 3]].Normal += normal; vertices[indices[i * 3 + 1]].Normal += normal; vertices[indices[i * 3 + 2]].Normal += normal; } for (int i = 0; i < vertices.Length; i++) vertices[i].Normal.Normalize(); }
public override void Generate(int TerrainDepth, int TerrainWidth, int Spacing, GraphicsDevice gd) { var Terrain = new VertexPositionColorNormal[TerrainDepth * TerrainWidth]; for (int i = 0; i != TerrainWidth; i++) { for (int j = 0; j != TerrainDepth; j++) { VertexPositionColorNormal vpc = new VertexPositionColorNormal(); vpc.Color = Utils.BrownishColours[Utils.RNG.Next(Utils.BrownishColours.Length - 1)]; if (i == 0 || j == 0 || i == TerrainWidth - 1 || j == TerrainDepth - 1) { vpc.Position = new Vector3(Spacing * i, 0, Spacing * j); vpc.Position *= 1.125f; vpc.Position.Y = -500; vpc.Color.A = 0; } else { float X = (Spacing * i);// + (x - 1) * Consts.spacing) - (Consts.spacing / 2); //float Y = (proceduralGeneration.generateHeight( // Spacing * i, Spacing * j) * 1.5f);// - 60; //Y = Utils.Map(Y, -40, 40, -10, 10); //Y *= 2; float Y = Utils.generateOffset(Spacing * Utils.RNG.Next() * i, Spacing * Utils.RNG.Next() * j, 0.5f, 0.324234f) * 5; float Z = (Spacing * j);// + (y - 1) * Consts.spacing) - (Consts.spacing / 2); vpc.Position = new Vector3(X, Y, Z); } Terrain[i + j * TerrainWidth] = vpc; } } uint[, ][] empty; Terrain = Utils.getTrisAlternating(Terrain, TerrainDepth, TerrainWidth, out empty).ToArray(); Utils.GenerateNormals(ref Terrain); VertexBuffer = new VertexBuffer(gd, VertexPositionColorNormal.VertexDeclaration, Terrain.Length, BufferUsage.WriteOnly); VertexBuffer.SetData(Terrain); ID = new Color(Utils.RNG.Next(255), Utils.RNG.Next(255), Utils.RNG.Next(255)); }
private VertexPositionColorNormal[] loadVertices(HeightMap heightMap, float heightScale) { VertexPositionColorNormal[] vertices = new VertexPositionColorNormal[this.width * this.height]; for (int x = 0; x < this.width; x++) { for (int y = 0; y < this.height; y++) { int v = x + y * this.width; float h = heightMap[x, y] * heightScale; vertices[v].Position = new Vector3(x, h, -y); vertices[v].Color = Color.Green; } } return(vertices); }
public void GenerateCircle(int TerrainDepth, int TerrainWidth, int Spacing, float Radius, GraphicsDevice gd) { var TempVertices = new VertexPositionColorNormal[TerrainDepth, TerrainWidth]; this.Spacing = Spacing; ID = Color.White; Width = TerrainWidth; Depth = TerrainDepth; TotalWaterSizeX = TerrainWidth * Spacing; TotalWaterSizeZ = TerrainDepth * Spacing; tempVecs = new Vector3[Width * Depth]; for (int x = 0; x < TerrainDepth; x++) { for (int z = 0; z < TerrainWidth; z++) { VertexPositionColorNormal vpc = new VertexPositionColorNormal(); vpc.Position = new Vector3((x * Spacing) - (TotalWaterSizeX / 2f), -85, (z * Spacing) - (TotalWaterSizeZ / 2f)); vpc.Color = new Color(0, 0, 0, 0); if (Vector2.Distance(new Vector2(vpc.Position.X, vpc.Position.Z), new Vector2(0)) <= Radius) { vpc.Color = Utils.BlueishColours[Utils.RNG.Next(Utils.BlueishColours.Length - 1)]; //vpc.Color = Color.Lerp(vpc.Color, Color.Transparent, Vector2.Distance(new Vector2(vpc.Position.X, vpc.Position.Z), new Vector2(0)) / (Radius*2)); //vpc.Color = new Color(vpc.Color.ToVector4().Slerp(Color.Transparent.ToVector4(), Vector2.Distance(new Vector2(vpc.Position.X, vpc.Position.Z), new Vector2(0)) / (Radius))); } else if (Vector2.Distance(new Vector2(vpc.Position.X, vpc.Position.Z), new Vector2(0)) <= Radius + Spacing + 25) { vpc.Color = new Color(0, 0, 0, 1); } TempVertices[x, z] = vpc; tempVecs[x + z * Width] = vpc.Position; } } Indices = new uint[TerrainWidth, TerrainDepth][]; Vertices = Utils.getTrisAlternating(TempVertices, TerrainWidth, TerrainDepth, out Indices).ToArray(); Utils.GenerateNormals(ref Vertices); VertexBuffer = new VertexBuffer(gd, VertexPositionColorNormal.VertexDeclaration, Vertices.Length, BufferUsage.WriteOnly); VertexBuffer.SetData(Vertices); }
private unsafe void UpdateBuffers(RectangleF view, int zoomLevel, int sampleResolution = 9) { // y = latitude // x = longitude // we only need to generate this if our resolution changes or our index buffer is null if (_indexBuffer == null || sampleResolution != _lastResolution) { _indices = GenerateGridIndexBuffer(sampleResolution, sampleResolution); _indexBuffer = Buffer.Create(_tileTexture2D.Device, BindFlags.IndexBuffer, _indices); _triangleCount = _indices.Length / 3; } _lastResolution = sampleResolution; var vertexData = new VertexPositionColorNormal[sampleResolution * sampleResolution]; // sample data at vertices and create vertex buffer int pos = 0; for (int y = 0; y < sampleResolution; y++) { for (int x = 0; x < sampleResolution; x++) { float lat = x * (view.Width / sampleResolution) + view.Left; float lon = y * (view.Height / sampleResolution) + view.Top; float value = SampleData(lon, lat, zoomLevel); // if (ValueMax - ValueMin) float valueRatio = (value - ValueMin) / (ValueMax - ValueMin); vertexData[pos++] = new VertexPositionColorNormal( new Vector4((float)x / (sampleResolution - 1) * 256f, (float)y / (sampleResolution - 1) * 256f, 1, 1f), new Vector4(valueRatio, valueRatio, valueRatio, 0), Vector3.Zero); } } CalculateNormals(ref vertexData, ref _indices); _vertexBuffer = Buffer.Create(_tileTexture2D.Device, BindFlags.VertexBuffer, vertexData, structureByteStride: sizeof(VertexPositionColorNormal)); // SharpDX.Direct2D1.Mesh m = new Mesh(_renderTarget2D); // _renderTarget2D.drawt }
public void AddLine(Vector3 start, Vector3 end, Color startColor, Color endColor) { var startVert = new VertexPositionColorNormal(start, startColor, Vector3.Zero); var endVert = new VertexPositionColorNormal(end, endColor, Vector3.Zero); //int startIndex = Array.IndexOf(Vertices, startVert); //int endIndex = Array.IndexOf(Vertices, endVert); int startIndex = -1; int endIndex = -1; //If start vertex can't be recycled from an old one, make a new one. if (startIndex == -1) { AddVertex(startVert); startIndex = Vertices.Length - 1; } //If end vertex can't be recycled from an old one, make a new one. if (endIndex == -1) { AddVertex(endVert); endIndex = Vertices.Length - 1; } for (int i = 0; i < Indices.Length; i += 2) { int lineStart = Indices[i]; if ((i + 1) < Indices.Length) { int lineEnd = Indices[i + 1]; if (lineStart == startIndex && lineEnd == endIndex) { // Line literally already exists lmao return; } } } AddIndex((short)startIndex); AddIndex((short)endIndex); }
public void AddTri(Vector3 a, Vector3 b, Vector3 c) { //var dir = Vector3.Cross(b - a, c - a); //var norm = Vector3.Normalize(dir); var vertA = new VertexPositionColorNormal(a, Color.White, Vector3.Zero); var vertB = new VertexPositionColorNormal(b, Color.White, Vector3.Zero); var vertC = new VertexPositionColorNormal(c, Color.White, Vector3.Zero); int vertIndexA = Array.IndexOf(Vertices, vertA); int vertIndexB = Array.IndexOf(Vertices, vertB); int vertIndexC = Array.IndexOf(Vertices, vertC); //If vertex A can't be recycled from an old one, make a new one. if (vertIndexA == -1) { AddVertex(vertA); vertIndexA = Vertices.Length - 1; } //If vertex B can't be recycled from an old one, make a new one. if (vertIndexB == -1) { AddVertex(vertB); vertIndexB = Vertices.Length - 1; } //If vertex C can't be recycled from an old one, make a new one. if (vertIndexC == -1) { AddVertex(vertC); vertIndexC = Vertices.Length - 1; } AddIndex((short)vertIndexA); AddIndex((short)vertIndexB); AddIndex((short)vertIndexC); }
public static void GenerateNormals(ref VertexPositionColorNormal[] verts) { for (int i = 0; i < verts.Count() - 2; i += 3) { VertexPositionColorNormal vpcn1 = verts[i]; VertexPositionColorNormal vpcn2 = verts[i + 1]; VertexPositionColorNormal vpcn3 = verts[i + 2]; Vector3 v1 = vpcn2.Position - vpcn1.Position; Vector3 v2 = vpcn3.Position - vpcn1.Position; Vector3 normal = Vector3.Cross(v1, v2); normal.Normalize(); vpcn1.Normal = normal; vpcn2.Normal = normal; vpcn3.Normal = normal; verts[i] = vpcn1; verts[i + 1] = vpcn2; verts[i + 2] = vpcn3; } }
public void DrawTriangle(JVector pos1, JVector pos2, JVector pos3) { JVector n = JVector.Cross(pos2 - pos1, pos3 - pos1); n.Normalize(); Vector3 xn = new Vector3(n.X, n.Y, n.Z); VertexPositionColorNormal[] tri = new VertexPositionColorNormal[3] { new VertexPositionColorNormal(new Vector3(pos1.X, pos1.Y, pos1.Z), Color.Green, xn), new VertexPositionColorNormal(new Vector3(pos3.X, pos3.Y, pos3.Z), Color.Green, xn), new VertexPositionColorNormal(new Vector3(pos2.X, pos2.Y, pos2.Z), Color.Green, xn), }; effect.Parameters["World"].SetValue(Matrix.Identity); effect.Parameters["ViewProj"].SetValue(Camera.CurrentCamera.View * Camera.CurrentCamera.Projection); effect.CurrentTechnique = effect.Techniques["VBO"]; foreach (EffectPass p in effect.CurrentTechnique.Passes) { p.Apply(); device.DrawUserPrimitives(PrimitiveType.TriangleList, tri, 0, 1); } }
private VertexPositionColorNormal[] CreateTriangle() { var vertices = new VertexPositionColorNormal[6]; vertices[0].Position = new Vector3(-1f, -1f, 0f); vertices[0].Color = Color.Blue; vertices[0].Normal = new Vector3(1, 0, 1); vertices[1].Position = new Vector3(0, 1f, 0f); vertices[1].Color = Color.Green; vertices[1].Normal = new Vector3(1, 0, 1); vertices[2].Position = new Vector3(1f, -1f, 0f); vertices[2].Color = Color.White; vertices[2].Normal = new Vector3(1, 0, 1); vertices[3].Position = new Vector3(1f, -1f, 0f); vertices[3].Color = Color.White; vertices[3].Normal = new Vector3(1, 0, 1); vertices[4].Position = new Vector3(0, 1f, 0f); vertices[4].Color = Color.Green; vertices[4].Normal = new Vector3(1, 0, 1); vertices[5].Position = new Vector3(-1f, -1f, 0f); vertices[5].Color = Color.Blue; vertices[5].Normal = new Vector3(1, 0, 1); return vertices; }
public override void Generate(int TerrainDepth, int TerrainWidth, int Spacing, GraphicsDevice gd) { var TempVertices = new VertexPositionColorNormal[TerrainDepth, TerrainWidth]; this.Spacing = Spacing; Width = TerrainWidth; Depth = TerrainDepth; TotalWaterSizeX = TerrainWidth * Spacing; TotalWaterSizeZ = TerrainDepth * Spacing; tempVecs = new Vector3[Width * Depth]; for (int x = 0; x < TerrainDepth; x++) { for (int z = 0; z < TerrainWidth; z++) { VertexPositionColorNormal vpc = new VertexPositionColorNormal(); vpc.Position = new Vector3((x * Spacing) - (TotalWaterSizeX / 2f), -45, (z * Spacing) - (TotalWaterSizeZ / 2f)); vpc.Color = Utils.BlueishColours[Utils.RNG.Next(Utils.BlueishColours.Length - 1)]; if (x == 0 || z == 0 || x == TerrainWidth - 1 || z == TerrainDepth - 1) { vpc.Color.A = 0; } TempVertices[x, z] = vpc; tempVecs[x + z * Width] = vpc.Position; } } Indices = new uint[TerrainWidth, TerrainDepth][]; Vertices = Utils.getTrisAlternating(TempVertices, TerrainWidth, TerrainDepth, out Indices).ToArray(); Utils.GenerateNormals(ref Vertices); VertexBuffer = new VertexBuffer(gd, VertexPositionColorNormal.VertexDeclaration, Vertices.Length, BufferUsage.WriteOnly); VertexBuffer.SetData(Vertices); }
public Skybox(GraphicsDevice device, TextureCube environment, Effect shader) { this.Environment = environment; this.Shader = shader; this.Device = device; VertexPositionColorNormal[] vertices = new VertexPositionColorNormal[8] { new VertexPositionColorNormal(new Vector3(-1, 1, 1), new Vector3(-1, 1, 1), Color.AliceBlue), new VertexPositionColorNormal(new Vector3(1, 1, 1), new Vector3(-1, 1, 1), Color.AliceBlue), new VertexPositionColorNormal(new Vector3(1, 1, -1), new Vector3(-1, 1, 1), Color.AliceBlue), new VertexPositionColorNormal(new Vector3(-1, 1, -1), new Vector3(-1, 1, 1), Color.AliceBlue), new VertexPositionColorNormal(new Vector3(-1, -1, 1), new Vector3(-1, 1, 1), Color.AliceBlue), new VertexPositionColorNormal(new Vector3(1, -1, 1), new Vector3(-1, 1, 1), Color.AliceBlue), new VertexPositionColorNormal(new Vector3(1, -1, -1), new Vector3(-1, 1, 1), Color.AliceBlue), new VertexPositionColorNormal(new Vector3(-1, -1, -1), new Vector3(-1, 1, 1), Color.AliceBlue) }; //vertices[1].Position = new Vector3(1, 1, 1); //vertices[2].Position = new Vector3(1, 1, -1); //vertices[3].Position = new Vector3(-1, 1, -1); //vertices[4].Position = new Vector3(-1, -1, 1); //vertices[5].Position = new Vector3(1, -1, 1); //vertices[6].Position = new Vector3(1, -1, -1); //vertices[7].Position = new Vector3(-1, -1, -1); //vertices = null; ushort[] indices = new ushort[36]; // top indices[0] = 0; indices[1] = 1; indices[2] = 3; indices[3] = 2; indices[4] = 3; indices[5] = 1; //bottom indices[6] = 5; indices[7] = 4; indices[8] = 6; indices[9] = 7; indices[10] = 6; indices[11] = 4; // front indices[12] = 3; indices[13] = 2; indices[14] = 7; indices[15] = 6; indices[16] = 7; indices[17] = 2; // back indices[18] = 1; indices[19] = 0; indices[20] = 4; indices[21] = 4; indices[22] = 5; indices[23] = 1; // left indices[24] = 0; indices[25] = 3; indices[26] = 4; indices[27] = 4; indices[28] = 3; indices[29] = 7; // right indices[30] = 2; indices[31] = 1; indices[32] = 6; indices[33] = 5; indices[34] = 6; indices[35] = 1; //this.IndexBuffer = new IndexBuffer(device, 36 * sizeof(ushort), BufferUsage.WriteOnly, IndexElementSize.SixteenBits); this.VertexDeclaration = new VertexDeclaration(VertexPositionColorNormal.VertexDeclaration.GetVertexElements()); this.VertexBuffer = new VertexBuffer(device, typeof(VertexPositionColorNormal), vertices.Length, BufferUsage.WriteOnly); this.IndexBuffer = new IndexBuffer(device, IndexElementSize.SixteenBits, 36 * sizeof(ushort), BufferUsage.WriteOnly); this.VertexBuffer.SetData(vertices, 0, 8); this.IndexBuffer.SetData(indices, 0, 36); indices = null; }
private Tuple<VertexPositionColorNormal[], int[]> getCylinder(CorePoint[] points, int steps, bool reverse) { VertexPositionColorNormal[] vertices = new VertexPositionColorNormal[points.Length * steps]; int[] indices = new int[2*steps+2]; for (int i = 0; i < points.Length; i++) { CorePoint p = points[i]; for (int j = 0; j < steps; j++) { Matrix fromAxisAngle = Matrix.CreateFromAxisAngle(p.orient, (float) ((reverse?-1:1)*j * Math.PI * 2 / steps)); vertices[i*steps + j].Position = Vector3.Transform(p.up, fromAxisAngle)*p.radius + p.pos; vertices[i*steps + j].Normal = Vector3.TransformNormal(p.up, fromAxisAngle); vertices[i*steps + j].Color = p.color; } } for (int j = 0; j < steps; j++) { indices[2*j] = j; indices[2 * j + 1] = steps + j; } indices[2 * steps] = 0; indices[2 * steps + 1] = steps; return new Tuple<VertexPositionColorNormal[], int[]>(vertices, indices); }
private int AddVertexToMesh(Vector3 point, Color color, Vector3 normal) { //Make it into a vertex VertexPositionColorNormal v = new VertexPositionColorNormal(point, color, normal); //Check if vertex already exists //if (VertexList.Contains(v)) //return VertexList.IndexOf(v); //else { VertexList.Add(v); return VertexList.Count - 1; } }
public static Mesh Sphere(float radius, int m = 24, int n = 24) { // http://wiki.unity3d.com/index.php/ProceduralPrimitives var r = radius; var verts = new VertexPositionColorNormal[(m + 1) * (n + 2)]; verts[0] = new VertexPositionColorNormal { Position = r * Vector3.Up }; for (var i = 0; i < m; i++) { var a = (float)Math.PI * (float)(i + 1) / (m + 1); var cosa = (float)Math.Cos(a); var sina = (float)Math.Sin(a); for (var j = 0; j <= n; j++) { var b = 2.0f * (float)Math.PI * (float)(j == n ? 0 : j) / n; var cosb = (float)Math.Cos(b); var sinb = (float)Math.Sin(b); var pos = new Vector3(sina * cosb, cosa, sina * sinb) * r; verts[j + i * (n + 1) + 1] = new VertexPositionColorNormal { Position = pos, }; } } verts[verts.Length - 1] = new VertexPositionColorNormal { Position = r * Vector3.Down }; for (var i = 0; i < verts.Length; i++) { var norm = verts[i].Position; norm.Normalize(); verts[i].Normal = norm; } var numTris = 2 * verts.Length; var numIndices = 3 * numTris; var indices = new int[numIndices]; var idx = 0; for (var j = 0; j < n; j++) { indices[idx++] = j + 1; indices[idx++] = j + 2; indices[idx++] = 0; } for (var i = 0; i < m - 1; i++) { for (var j = 0; j < n; j++) { var c = j + i * (n + 1) + 1; var x = c + n + 1; indices[idx++] = c; indices[idx++] = x + 1; indices[idx++] = c + 1; indices[idx++] = c; indices[idx++] = x; indices[idx++] = x + 1; } } for (var j = 0; j < n; j++) { indices[idx++] = verts.Length - 1; indices[idx++] = verts.Length - (j + 2) - 1; indices[idx++] = verts.Length - (j + 1) - 1; } return(new Mesh(verts, indices)); }
public void Initialize(Microsoft.Xna.Framework.Game game, Color color, IEnumerable<Vector3> vertices, IEnumerable<Triangle<uint>> triangles) { _game = game; int vertCount = vertices.Count(); int triCount = triangles.Count(); _vertexBuffer = new VertexBuffer(game.GraphicsDevice, typeof(VertexPositionColorNormal), vertCount, BufferUsage.None); _indexBuffer = new IndexBuffer(game.GraphicsDevice, typeof(int), triCount * 3, BufferUsage.None); var data = new VertexPositionColorNormal[vertCount]; int c = 0; foreach (var vert in vertices) data[c++] = new VertexPositionColorNormal(new Vector3(vert.Y, vert.Z, vert.X), color, new Vector3(0)); var triData = new int[triCount*3]; c = 0; foreach (var tri in triangles) { triData[c] = (int)tri.V0; triData[c + 1] = (int) tri.V1; triData[c + 2] = (int) tri.V2; c += 3; switch (tri.Type) { case TriangleType.Water: data[tri.V0].Color = Color.Blue; data[tri.V1].Color = Color.Blue; data[tri.V2].Color = Color.Blue; break; } } GenerateNormals(data, triData); _vertexBuffer.SetData(data); _indexBuffer.SetData(triData); }
private void GenerateVertices() { _vertices = new VertexPositionColorNormal[_terrainHeight * _terrainWidth]; for (int x = 0; x < _terrainWidth; x++) { for (int y = 0; y < _terrainHeight; y++) { _vertices[x + y * _terrainWidth].Position = new Vector3(x, _heightData[x, y], -y) * _scale; _vertices[x + y * _terrainWidth].Normal = new Vector3(0, 0, 0); if (!_isWater) { if (_heightData[x, y] > 3) _vertices[x + y * _terrainWidth].Color = Color.LightGray; else _vertices[x + y * _terrainWidth].Color = Color.Green; } else { _vertices[x + y * _terrainWidth].Color = Color.DeepSkyBlue; } } } }
public static int ExtractMesh(World world, Layer layer, bool disableGreedyMeshing = false, bool disableAO = false) { /* * Extract all faces * - Store hidden faces (which should only be tops) in its own temporary list * - Put all visible faces in to the vertex buffer * - Mark the last primitive/index of visible faces and then insert hidden faces * - When rendering above zLevel, only render up to the end of visible faces * when rendering on the zlevel, render the entire buffer to show hidden faces */ layer.visibleMesh.Clear(); layer.hiddenMesh.Clear(); VertexPositionColorNormal[] vertices = new VertexPositionColorNormal[5]; var layerDepth = layer.Depth; var lowerLayer = world[layerDepth - 1]; var upperLayer = world[layerDepth + 1]; var depth = world.Depth; var size = world.Size; var cells = layer.GetCells(); var dims = new int[] { world.Size, 1, world.Size }; var f = new Func<int, int, int, uint>((i, j, k) => { var idx = i | k; if (i < 0 || k < 0 || i >= size || k >= size) return 0; MapCell cell; if (j < 0) { if (lowerLayer == null) return 0; cell = lowerLayer[i + k * size]; } else if (j > 0) { if (upperLayer == null) return 0; cell = upperLayer[i + k * size]; } else cell = cells[i + k * size]; if (cell.Hidden) return 0xff; return cell.ToUInt(); }); //Sweep over 3-axes // d0 = x, d1 = y, d2 = z for (var d = 0; d < 3; ++d) { int i, j, k, l, w, h , u = (d + 1) % 3 , v = (d + 2) % 3; int[] x = { 0, 0, 0 }; int[] q = { 0, 0, 0 }; int[,] posArea = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }; int[,] negArea = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }; if (mask.Length < dims[u] * dims[v]) { mask = new uint[dims[u] * dims[v] * 3 / 2]; maskLayout = new MaskLayout[dims[u] * dims[v] * 3 / 2]; } q[d] = 1; posArea[0, u] = -1; posArea[1, v] = -1; posArea[2, u] = 1; posArea[3, v] = 1; negArea[0, v] = -1; negArea[1, u] = -1; negArea[2, v] = 1; negArea[3, u] = 1; for (x[d] = -1; x[d] < dims[d]; ) { //Compute mask var n = 0; for (x[v] = 0; x[v] < dims[v]; ++x[v]) { for (x[u] = 0; x[u] < dims[u]; ++x[u], ++n) { var a = f(x[0], x[1], x[2]); var b = f(x[0] + q[0], x[1] + q[1], x[2] + q[2]); mask[n] = 0; maskLayout[n].data = 0u; if ((a != 0) == (b != 0)) { if (d == 1) { mask[n] = a; maskLayout[n].HiddenFace = true; } else { mask[n] = 0; } } else if (a != 0) { mask[n] = x[d] > -1 ? a : 0; maskLayout[n].BackFace = false; } else { if (d == 1) { mask[n] = 0; } else { mask[n] = x[d] < dims[d] - 1 ? b : 0; maskLayout[n].BackFace = true; } } if (disableAO || mask[n] == 0 || maskLayout[n].HiddenFace) { //maskLayout[n].data = 4095u; } else { uint side1 = 0, side2 = 0, corner = 0; var neighbors = new uint[4]; for (var t = 0; t < 4; ++t) { var tt = (t + 1) % 4; if (a != 0) { side1 = (f(x[0] + q[0] + posArea[t, 0], x[1] + q[1] + posArea[t, 1], x[2] + q[2] + posArea[t, 2]) > 0u ? 1u : 0u); side2 = (f(x[0] + q[0] + posArea[tt, 0], x[1] + q[1] + posArea[tt, 1], x[2] + q[2] + posArea[tt, 2]) > 0u ? 1u : 0u); } else { side1 = (f(x[0] + negArea[t, 0], x[1] + negArea[t, 1], x[2] + negArea[t, 2]) > 0u ? 1u : 0u); side2 = (f(x[0] + negArea[tt, 0], x[1] + negArea[tt, 1], x[2] + negArea[tt, 2]) > 0u ? 1u : 0u); } if (side1 > 0 && side2 > 0) { neighbors[t] = 0; } else { if (a != 0) { corner = (f(x[0] + q[0] + posArea[t, 0] + posArea[tt, 0], x[1] + q[1] + posArea[t, 1] + posArea[tt, 1], x[2] + q[2] + posArea[t, 2] + posArea[tt, 2]) > 0u ? 1u : 0u); } else { corner = (f(x[0] + negArea[t, 0] + negArea[tt, 0], x[1] + negArea[t, 1] + negArea[tt, 1], x[2] + negArea[t, 2] + negArea[tt, 2]) > 0u ? 1u : 0u); } neighbors[t] = 3u - (side1 + side2 + corner); } maskLayout[n].SetOcclusion(t, neighbors[t]); } uint a00 = neighbors[1], a01 = neighbors[2], a11 = neighbors[3], a10 = neighbors[0]; if (a00 + a01 + a11 + a10 != 12) maskLayout[n].AOFace = true; } } } //Increment x[d] ++x[d]; //Generate mesh for mask using lexicographic ordering n = 0; for (j = 0; j < dims[v]; ++j) { for (i = 0; i < dims[u]; ) { var c = mask[n]; if (c != 0) { var a = maskLayout[n]; if (disableGreedyMeshing || a.AOFace) { w = 1; h = 1; } else { //Compute width for (w = 1; c == mask[n + w] && (a.data == (maskLayout[n + w].data)) && i + w < dims[u]; ++w) { } //Compute height (this is slightly awkward var done = false; for (h = 1; j + h < dims[v]; ++h) { for (k = 0; k < w; ++k) { if (c != mask[n + k + h * dims[u]] || a.data != maskLayout[n + k + h * dims[u]].data) { done = true; break; } } if (done) { break; } } } //Add quad x[u] = i; x[v] = j; int[] du = { 0, 0, 0 }; int[] dv = { 0, 0, 0 }; var normal = new Vector3(q[0], q[1], q[2]); var aoFace = maskLayout[n].AOFace; if (!maskLayout[n].BackFace) { dv[v] = h; du[u] = w; } else { du[v] = h; dv[u] = w; normal = -normal; } var typeid = c & 0xff; var meta = MapCellDescriptor.MapCells[typeid]; var cr = meta.Color.R / 255f; var cg = meta.Color.G / 255f; var cb = meta.Color.B / 255f; var ao = 0f; var AOcurve = new float[] { 0.45f, 0.65f, 0.85f, 1.0f }; var auCurveFactor = new float[] { 1f, 0.99f, 0.98f, 0.97f, 0.96f }; var aoFactor = auCurveFactor[maskLayout[n].TotalOcclusion()]; for (var o = 0; o < 4; ++o) { var pao = disableAO ? 1f : AOcurve[maskLayout[n].GetOcclusion(o)]; //vertices[o].Color = new Color(cr * pao, cg * pao, cb * pao); vertices[o].Color = new Color(cr * pao, cg * pao, cb * pao); vertices[o].Normal = normal; ao += pao; } ao /= 4f; vertices[0].Position = new Vector3(x[0], x[1], x[2]); vertices[1].Position = new Vector3(x[0] + du[0], x[1] + du[1], x[2] + du[2]); vertices[2].Position = new Vector3(x[0] + du[0] + dv[0], x[1] + du[1] + dv[1], x[2] + du[2] + dv[2]); vertices[3].Position = new Vector3(x[0] + dv[0], x[1] + dv[1], x[2] + dv[2]); //vertices[0].Position += new Vector3(0.25f, 0.25f, 0.25f); //vertices[1].Position += new Vector3(0.25f, 0.25f, 0.25f); //vertices[2].Position += new Vector3(0.25f, 0.25f, 0.25f); //vertices[3].Position += new Vector3(0.25f, 0.25f, 0.25f); var mesh = a.HiddenFace ? layer.hiddenMesh : layer.visibleMesh; var v0 = mesh.Add(vertices[0]); var v1 = mesh.Add(vertices[1]); var v2 = mesh.Add(vertices[2]); var v3 = mesh.Add(vertices[3]); if (aoFace) { vertices[4].Position = (vertices[0].Position + vertices[1].Position + vertices[2].Position + vertices[3].Position) / 4; vertices[4].Normal = normal; vertices[4].Color = new Color(cr * ao, cg * ao, cb * ao); var v4 = mesh.Add(vertices[4]); mesh.Triangle(v0, v4, v1); mesh.Triangle(v1, v4, v2); mesh.Triangle(v2, v4, v3); mesh.Triangle(v3, v4, v0); } else { mesh.Quad(v0, v1, v2, v3); } //Zero-out mask for (l = 0; l < h; ++l) { for (k = 0; k < w; ++k) { mask[n + k + l * dims[u]] = 0; maskLayout[n + k + l * dims[u]].data = 0; } } //Increment counters and continue i += w; n += w; } else { ++i; ++n; } } } } } layer.visibleMesh.Update(); layer.hiddenMesh.Update(); return layer.visibleMesh.VertexCount + layer.hiddenMesh.VertexCount; }
public void BuildMesh() { SurfaceExtractor.ExtractMesh(this.world, this); return; /* * Extract all faces * - Store hidden faces (which should only be tops) in its own temporary list * - Put all visible faces in to the vertex buffer * - Mark the last primitive/index of visible faces and then insert hidden faces * - When rendering above zLevel, only render up to the end of visible faces * when rendering on the zlevel, render the entire buffer to show hidden faces */ visibleMesh.Clear(); VertexPositionColorNormal[] vertices = new VertexPositionColorNormal[4]; var dims = new int[] { world.Size, 1, world.Size }; var f = new Func<int, int, int, MapCell>((x, y, z) => { if (x < 0 || y < 0 || z < 0 || x >= dims[0] || y >= dims[1] || z >= dims[2]) return world[x, z, y]; return mapCells[x + z * world.Size]; }); //Sweep over 3-axes // d0 = x, d1 = y, d2 = z for (var d = 0; d < 3; ++d) { int i, j, k, l, w, h , u = (d + 1) % 3 , v = (d + 2) % 3; int[] x = { 0, 0, 0 }; int[] q = { 0, 0, 0 }; q[d] = 1; for (x[d] = -1; x[d] < dims[d]; ) { //Compute mask int[] du = { 0, 0, 0 }; int[] dv = { 0, 0, 0 }; for (x[v] = 0; x[v] < dims[v]; ++x[v]) { for (x[u] = 0; x[u] < dims[u]; ++x[u]) { var a = f(x[0], x[1], x[2]); var b = f(x[0] + q[0], x[1] + q[1], x[2] + q[2]); if ((!a.Meta.IsEmpty) == (!b.Meta.IsEmpty)) { continue; } //x[u] = i; x[v] = j; var normal = new Vector3(q[0], q[1], q[2]); MapCellDescriptor meta; if (!a.Meta.IsEmpty) { //normal quad du[v] = 1; dv[u] = 1; meta = a.Meta; vertices[0].Position = new Vector3(x[0], x[1], x[2]); vertices[1].Position = new Vector3(x[0] + du[0], x[1] + du[1], x[2] + du[2]); vertices[2].Position = new Vector3(x[0] + du[0] + dv[0], x[1] + du[1] + dv[1], x[2] + du[2] + dv[2]); vertices[3].Position = new Vector3(x[0] + dv[0], x[1] + dv[1], x[2] + dv[2]); } else { //continue; //backface quad dv[v] = 1; du[u] = 1; normal = -normal; meta = b.Meta; vertices[0].Position = new Vector3(x[0] + q[0], x[1] + q[1], x[2] + q[2]); vertices[1].Position = new Vector3(x[0] + q[0] + du[0], x[1] + q[1] + du[1], x[2] + q[2] + du[2]); vertices[2].Position = new Vector3(x[0] + q[0] + du[0] + dv[0], x[1] + q[1] + du[1] + dv[1], x[2] + q[2] + du[2] + dv[2]); vertices[3].Position = new Vector3(x[0] + q[0] + dv[0], x[1] + q[1] + dv[1], x[2] + q[2] + dv[2]); } for (var p = 0; p < 4; ++p) { vertices[p].Color = meta.Color; vertices[p].Normal = normal; } var v0 = visibleMesh.Add(vertices[0]); var v1 = visibleMesh.Add(vertices[1]); var v2 = visibleMesh.Add(vertices[2]); var v3 = visibleMesh.Add(vertices[3]); visibleMesh.Quad(v0, v1, v2, v3); } } //Increment x[d] ++x[d]; } } visibleMesh.Update(); }
public void CalculateIndexes(float threshold) { if (!FlatShading) { Indices.Clear(); } else { Indices = new List <int>(); } List <int> tri_count = new List <int>(); tree.ProcessCell(Indices, tri_count, threshold); if (!FlatShading) { IndexCount = Indices.Count; if (Indices.Count == 0) { return; } } if (!FlatShading) { IndexBuffer.SetData <int>(Indices.ToArray()); } else { List <VertexPositionColorNormal> new_vertices = new List <VertexPositionColorNormal>(); int t_index = 0; for (int i = 0; i < Indices.Count; i += 3) { int count = tri_count[t_index++]; Vector3 n = Vector3.Zero; if (count == 1) { n = GetNormalQ(Vertices, Indices[i + 2], Indices[i + 0], Indices[i + 1]); } else { n = GetNormalQ(Vertices, Indices[i + 2], Indices[i + 0], Indices[i + 1], Indices[i + 5], Indices[i + 3], Indices[i + 4]); } Vector3 nc = n * 0.5f + Vector3.One * 0.5f; nc.Normalize(); Color c = new Color(nc); VertexPositionColorNormal v0 = new VertexPositionColorNormal(Vertices[Indices[i + 0]].Position, c, n); VertexPositionColorNormal v1 = new VertexPositionColorNormal(Vertices[Indices[i + 1]].Position, c, n); VertexPositionColorNormal v2 = new VertexPositionColorNormal(Vertices[Indices[i + 2]].Position, c, n); new_vertices.Add(v0); new_vertices.Add(v1); new_vertices.Add(v2); if (count > 1) { VertexPositionColorNormal v3 = new VertexPositionColorNormal(Vertices[Indices[i + 3]].Position, c, n); VertexPositionColorNormal v4 = new VertexPositionColorNormal(Vertices[Indices[i + 4]].Position, c, n); VertexPositionColorNormal v5 = new VertexPositionColorNormal(Vertices[Indices[i + 5]].Position, c, n); new_vertices.Add(v3); new_vertices.Add(v4); new_vertices.Add(v5); i += 3; } } if (new_vertices.Count > 0) { VertexBuffer.SetData <VertexPositionColorNormal>(new_vertices.ToArray()); } VertexCount = new_vertices.Count; } }
internal void ComputeVerticesIndices(PAL Palette) { if (ComputedVertices == null) { ComputedVertices = new List <VertexPositionColorNormal>(); ComputedIndices = new List <int>(); var Normals = GetNormals(); var shifts = new Vector3[] { new Vector3(-1, -1, -1), new Vector3(-1, +1, -1), new Vector3(-1, -1, +1), new Vector3(-1, +1, +1), new Vector3(+1, -1, -1), new Vector3(+1, +1, -1), new Vector3(+1, -1, +1), new Vector3(+1, +1, +1), }; foreach (var sp in Body.Spans) { foreach (var v in sp.Voxels) { var Clr = Palette.Colors[v.ColorIndex]; var N = Normals[v.NormalIndex]; var obs = Body.ObscuredFrom(v.X, v.Y, v.Z); if (obs == Edges.All) { continue; } var realPos = Tail.Displacement(v.X, v.Y, v.Z); var start = ComputedVertices.Count; foreach (var sh in shifts) { var vpcn = new VertexPositionColorNormal(); var scaledShift = sh * Tail.Scale; var pos = realPos + scaledShift; vpcn.Position = pos; vpcn.Color = Clr; vpcn.Normal = N; ComputedVertices.Add(vpcn); } if (!obs.HasFlag(Edges.XLess)) { // 0123 ComputedIndices.Add(start + 0); ComputedIndices.Add(start + 1); ComputedIndices.Add(start + 2); ComputedIndices.Add(start + 1); ComputedIndices.Add(start + 2); ComputedIndices.Add(start + 3); } if (!obs.HasFlag(Edges.YLess)) { // 0246 ComputedIndices.Add(start + 0); ComputedIndices.Add(start + 2); ComputedIndices.Add(start + 4); ComputedIndices.Add(start + 2); ComputedIndices.Add(start + 4); ComputedIndices.Add(start + 6); } if (!obs.HasFlag(Edges.ZLess)) { // 0145 ComputedIndices.Add(start + 0); ComputedIndices.Add(start + 1); ComputedIndices.Add(start + 4); ComputedIndices.Add(start + 1); ComputedIndices.Add(start + 4); ComputedIndices.Add(start + 5); } if (!obs.HasFlag(Edges.ZMore)) { // 2367 ComputedIndices.Add(start + 2); ComputedIndices.Add(start + 3); ComputedIndices.Add(start + 6); ComputedIndices.Add(start + 3); ComputedIndices.Add(start + 6); ComputedIndices.Add(start + 7); } if (!obs.HasFlag(Edges.YMore)) { // 1357 ComputedIndices.Add(start + 1); ComputedIndices.Add(start + 3); ComputedIndices.Add(start + 5); ComputedIndices.Add(start + 3); ComputedIndices.Add(start + 5); ComputedIndices.Add(start + 7); } if (!obs.HasFlag(Edges.XMore)) { // 4567 ComputedIndices.Add(start + 4); ComputedIndices.Add(start + 5); ComputedIndices.Add(start + 6); ComputedIndices.Add(start + 5); ComputedIndices.Add(start + 6); ComputedIndices.Add(start + 7); } } } } }
private void Polygonize(int x, int y, int z) { if (Cells[x, y, z] == null) { return; } int cube_index = 0; for (int i = 0; i < 8; i++) { if (Sampler.Sample(new Vector3(x, y, z) + CornerDeltas[i]) < 0) { cube_index |= 1 << i; } } if (cube_index == 0 || cube_index == 255) { return; } Cells[x, y, z].Vertices = new Vertex[VerticesNumberTable[cube_index]]; /*for (int i = 0; i < 12; i++) * { * Cells[x, y, z].Edges[i].A = new Vector3(x, y, z) + CornerDeltas[EdgePairs[i, 0]]; * Cells[x, y, z].Edges[i].B = new Vector3(x, y, z) + CornerDeltas[EdgePairs[i, 1]]; * * Cells[x, y, z].Edges[i].ValueA = Sampler.Sample(Cells[x, y, z].Edges[i].A); * Cells[x, y, z].Edges[i].ValueB = Sampler.Sample(Cells[x, y, z].Edges[i].B); * }*/ int v_index = 0; Cells[x, y, z].Vertices[0] = new Vertex(); for (int e = 0; e < EdgesTable.GetLength(1); e++) { if (EdgesTable[cube_index, e] == -2) { break; } if (EdgesTable[cube_index, e] == -1) { v_index++; if (v_index < Cells[x, y, z].Vertices.Length) { Cells[x, y, z].Vertices[v_index] = new Vertex(); } continue; } //Cells[x, y, z].Vertices[v_index].Index = v_index; Cells[x, y, z].Vertices[v_index].Edges.Add(EdgesTable[cube_index, e]); Cells[x, y, z].Edges[EdgesTable[cube_index, e]].Vertices.Add(Cells[x, y, z].Vertices[v_index]); //Cells[x, y, z].Edges[EdgesTable[cube_index, e]].Flipped = Cells[x, y, z].Edges[EdgesTable[cube_index, e]].ValueA < 0; } foreach (Vertex v in Cells[x, y, z].Vertices) { Vertex tx = v; if (v == null) //for edges 241/243, which were originally marked as having 2 vertices...? { continue; } Vector3 point = new Vector3(); if (VertexMode != VertexModes.Block) { //QEF3D qef = new QEF3D(); QEFProper.QEFSolver qef = new QEFProper.QEFSolver(); VertexPlacement qem = new VertexPlacement(); for (int e_i = 0; e_i < tx.Edges.Count; e_i++) { Edge e = Cells[x, y, z].Edges[tx.Edges[e_i]]; if (VertexMode == VertexModes.Edges) { point += e.GetIntersection(); } else if (VertexMode == VertexModes.QEF) { qef.Add(e.GetIntersection() - new Vector3(x, y, z), Sampler.GetNormal(e.GetIntersection())); } else { qem.AddPlane(e.GetIntersection() - new Vector3(x, y, z), Sampler.GetNormal(e.GetIntersection())); } } if (VertexMode == VertexModes.Edges) { point /= (float)tx.Edges.Count; } else if (VertexMode == VertexModes.QEF) { point = qef.Solve(1e-6f, 4, 1e-6f) + new Vector3(x, y, z); } else { point = qem.Solve() + new Vector3(x, y, z); } } else { point = new Vector3(x, y, z) + Vector3.One * 0.5f; } //point = Vector3.Clamp(point, new Vector3(x, y, z), new Vector3(x + 1, y + 1, z + 1)); tx.Position = point; Vector3 norm = Sampler.GetNormal(point); Vector3 c_v = norm * 0.5f + Vector3.One * 0.5f; c_v.Normalize(); Color clr = new Color(c_v); if (!UseFlatShading) { tx.Index = Vertices.Count; VertexPositionColorNormal pv = new VertexPositionColorNormal(tx.Position, clr, norm); Vertices.Add(pv); } else { tx.Index = CalculatedVertices.Count; VertexPositionColor pv = new VertexPositionColor(tx.Position, clr); CalculatedVertices.Add(pv); } VertexPositionColor[] vs = new VertexPositionColor[24]; Color c = Color.Red; float vx = tx.Position.X; float vy = tx.Position.Y; float vz = tx.Position.Z; float r = 0.25f; vs[0] = new VertexPositionColor(new Vector3((vx + 0), (vy + 0), (vz + 0)), c); vs[1] = new VertexPositionColor(new Vector3((vx + r), (vy + 0), (vz + 0)), c); vs[2] = new VertexPositionColor(new Vector3((vx + r), (vy + 0), (vz + 0)), c); vs[3] = new VertexPositionColor(new Vector3((vx + r), (vy + r), (vz + 0)), c); vs[4] = new VertexPositionColor(new Vector3((vx + r), (vy + r), (vz + 0)), c); vs[5] = new VertexPositionColor(new Vector3((vx + 0), (vy + r), (vz + 0)), c); vs[6] = new VertexPositionColor(new Vector3((vx + 0), (vy + r), (vz + 0)), c); vs[7] = new VertexPositionColor(new Vector3((vx + 0), (vy + 0), (vz + 0)), c); vs[8] = new VertexPositionColor(new Vector3((vx + 0), (vy + 0), (vz + r)), c); vs[9] = new VertexPositionColor(new Vector3((vx + r), (vy + 0), (vz + r)), c); vs[10] = new VertexPositionColor(new Vector3((vx + r), (vy + 0), (vz + r)), c); vs[11] = new VertexPositionColor(new Vector3((vx + r), (vy + r), (vz + r)), c); vs[12] = new VertexPositionColor(new Vector3((vx + r), (vy + r), (vz + r)), c); vs[13] = new VertexPositionColor(new Vector3((vx + 0), (vy + r), (vz + r)), c); vs[14] = new VertexPositionColor(new Vector3((vx + 0), (vy + r), (vz + r)), c); vs[15] = new VertexPositionColor(new Vector3((vx + 0), (vy + 0), (vz + r)), c); vs[16] = new VertexPositionColor(new Vector3((vx + 0), (vy + 0), (vz + 0)), c); vs[17] = new VertexPositionColor(new Vector3((vx + 0), (vy + 0), (vz + r)), c); vs[18] = new VertexPositionColor(new Vector3((vx + 0), (vy + r), (vz + 0)), c); vs[19] = new VertexPositionColor(new Vector3((vx + 0), (vy + r), (vz + r)), c); vs[20] = new VertexPositionColor(new Vector3((vx + r), (vy + 0), (vz + 0)), c); vs[21] = new VertexPositionColor(new Vector3((vx + r), (vy + 0), (vz + r)), c); vs[22] = new VertexPositionColor(new Vector3((vx + r), (vy + r), (vz + 0)), c); vs[23] = new VertexPositionColor(new Vector3((vx + r), (vy + r), (vz + r)), c); OutlineBuffer.SetData <VertexPositionColor>(OutlineLocation * VertexPositionColor.VertexDeclaration.VertexStride, vs, 0, 24, VertexPositionColor.VertexDeclaration.VertexStride); OutlineLocation += 24; } }
public static IEnumerable <VertexPositionColorNormal> getTrisAlternating(VertexPositionColorNormal[] Data, int Depth, int Width, out uint[, ][] Indices) { VertexPositionColorNormal[,] source = new VertexPositionColorNormal[Width, Depth]; //The new, easy to read 2D array for (int x = 0; x < Width; x++) //Convert! { for (int y = 0; y < Depth; y++) { source[x, y] = Data[x + y * Width]; } } List <uint>[,] Indexes = new List <uint> [Width, Depth]; for (int i = 0; i != Width; i++) { for (int j = 0; j != Width; j++) { Indexes[i, j] = new List <uint>(); } } var result = new List <VertexPositionColorNormal>(); for (int x = 0; x < Width - 1; x++) { for (int y = 0; y < Depth - 1; y++) { if ((y + x % 2) % 2 == 0) { var a = source[x, y]; var b = source[x + 1, y]; var c = source[x + 1, y + 1]; if (a.Color != Color.Transparent && b.Color != Color.Transparent && c.Color != Color.Transparent) { result.Add(a); result.Add(b); result.Add(c); Indexes[x, y].Add((uint)((x + y * Width) * 6)); Indexes[x + 1, y].Add((uint)((x + y * Width) * 6) + 1); Indexes[x + 1, y + 1].Add((uint)((x + y * Width) * 6) + 2); } b = source[x + 1, y + 1]; c = source[x, y + 1]; if (a.Color != Color.Transparent && b.Color != Color.Transparent && c.Color != Color.Transparent) { result.Add(a); result.Add(b); result.Add(c); Indexes[x, y].Add((uint)((x + y * Width) * 6) + 3); Indexes[x + 1, y + 1].Add((uint)((x + y * Width) * 6) + 4); Indexes[x, y + 1].Add((uint)((x + y * Width) * 6) + 5); } } else { var a = source[x, y]; var b = source[x + 1, y]; var c = source[x, y + 1]; if (a.Color != Color.Transparent && b.Color != Color.Transparent && c.Color != Color.Transparent) { result.Add(a); result.Add(b); result.Add(c); Indexes[x, y].Add((uint)((x + y * Width) * 6)); Indexes[x + 1, y].Add((uint)((x + y * Width) * 6) + 1); Indexes[x, y + 1].Add((uint)((x + y * Width) * 6) + 2); } a = source[x + 1, y]; b = source[x + 1, y + 1]; c = source[x, y + 1]; if (a.Color != Color.Transparent && b.Color != Color.Transparent && c.Color != Color.Transparent) { result.Add(a); result.Add(b); result.Add(c); Indexes[x + 1, y].Add((uint)((x + y * Width) * 6) + 3); Indexes[x + 1, y + 1].Add((uint)((x + y * Width) * 6) + 4); Indexes[x, y + 1].Add((uint)((x + y * Width) * 6) + 5); } } } } Indices = new uint[Width, Depth][]; for (int i = 0; i != Width; i++) { for (int j = 0; j != Width; j++) { Indices[i, j] = Indexes[i, j].ToArray(); } } return(result); }
void generate(object ctx) { building = true; List<int> inds = new List<int>(Icosphere.Indicies); List<VertexPositionColorNormal> verts = new List<VertexPositionColorNormal>(); for (int i = 0; i < Icosphere.Verticies.Length; i++) { verts.Add(new VertexPositionColorNormal(Icosphere.Verticies[i] / Icosphere.Verticies[i].Length(), Icosphere.Verticies[i], landColor)); } IndexBuffer = new Dictionary<int, int[]>(); IndexBuffer[0] = inds.ToArray(); LODv = new List<int>(); LODv.Add(verts.Count); int levels = (int)ctx; for (int l = 1; l < levels; l++) { List<int> newinds = new List<int>(); for (int i = 0; i < inds.Count; i+=3) { int i1 = inds[i], i2 = inds[i + 1], i3 = inds[i + 2]; Vector3 v1 = verts[i1].Position, v2 = verts[i2].Position, v3 = verts[i3].Position; Vector3 v4 = (v1 + v3) / 2f; Vector3 v5 = (v1 + v2) / 2f; Vector3 v6 = (v3 + v2) / 2f; v4.Normalize(); v5.Normalize(); v6.Normalize(); verts.Add(new VertexPositionColorNormal(v4, v4, landColor)); verts.Add(new VertexPositionColorNormal(v5, v5, landColor)); verts.Add(new VertexPositionColorNormal(v6, v6, landColor)); int i4 = verts.Count - 3; int i5 = verts.Count - 2; int i6 = verts.Count - 1; newinds.AddRange(new int[] { i1, i5, i4 }); newinds.AddRange(new int[] { i4, i5, i6 }); newinds.AddRange(new int[] { i3, i4, i6 }); newinds.AddRange(new int[] { i6, i5, i2 }); } inds = new List<int>(newinds); IndexBuffer[l] = inds.ToArray(); LODv.Add(verts.Count); } VertexBuffer = verts.ToArray(); if (HasWater) WaterVertexBuffer = new VertexPositionColorPolar[VertexBuffer.Length]; if (HasAtmosphere) AtmosphereVertexBuffer = new VertexPositionColorNormal[VertexBuffer.Length]; // set terrain heights for (int i = 0; i < VertexBuffer.Length; i++) { // water verts if (HasWater){ WaterVertexBuffer[i] = new VertexPositionColorPolar(VertexBuffer[i].Position, Vector2.Zero, waterColor); WaterVertexBuffer[i].Polar.X = (float)Math.Asin(WaterVertexBuffer[i].Position.Z); WaterVertexBuffer[i].Polar.Y = (float)Math.Atan2(WaterVertexBuffer[i].Position.Y, WaterVertexBuffer[i].Position.X); WaterVertexBuffer[i].Position *= Radius; } // atmo verts if (HasAtmosphere) { AtmosphereVertexBuffer[i] = new VertexPositionColorNormal(VertexBuffer[i].Position, VertexBuffer[i].Position, atmosphereColor); AtmosphereVertexBuffer[i].Normal.Normalize(); AtmosphereVertexBuffer[i].Position *= AtmosphereHeight; } // land verts VertexBuffer[i].Color = landColor; float h = getHeight(VertexBuffer[i].Position); if (h <= Radius) VertexBuffer[i].Color = oceanFloorColor; VertexBuffer[i].Position *= h; VertexBuffer[i].Normal = Vector3.Zero; } for (int i = 0; i < IndexBuffer[levels - 1].Length; i+=3) { int i1 = IndexBuffer[levels - 1][i]; int i2 = IndexBuffer[levels - 1][i + 1]; int i3 = IndexBuffer[levels - 1][i + 2]; Vector3 norm = -Vector3.Cross(VertexBuffer[i1].Position - VertexBuffer[i2].Position, VertexBuffer[i1].Position - VertexBuffer[i3].Position); VertexBuffer[i1].Normal += norm; VertexBuffer[i2].Normal += norm; VertexBuffer[i3].Normal += norm; } for (int i = 0; i < VertexBuffer.Length; i++) VertexBuffer[i].Normal.Normalize(); if (HasWater){ waves[0] = new Wave(.5f, 2, Vector2.UnitX, 50, 1f); waves[1] = new Wave(.2f, 2, Vector2.UnitY, 50, .2f); } built = true; building = false; }
private Tuple<VertexPositionColorNormal[], int[]> getCylinderCap(CorePoint point, int steps, bool reverse, bool backwards) { VertexPositionColorNormal[] vertices = new VertexPositionColorNormal[steps * steps]; int[] indices = new int[2 * steps + 2]; for (int i = 0; i < steps; i++) { for (int j = 0; j < steps; j++) { float t = (float) j/(steps - 1); Vector3 newp = point.pos - point.radius* point.orient*(backwards ? 1 : -1)*t; float newr = point.radius*(float)Math.Sqrt(1-(1-t)*(1-t)); Vector3 newn = newr*point.up + newp - point.pos; newn.Normalize(); Matrix rotationMatrix = Matrix.CreateFromAxisAngle(point.orient, (float)((reverse ? -1 : 1) * j * Math.PI * 2 / steps)); vertices[i * steps + j].Position = Vector3.Transform(point.up, rotationMatrix) * newr + newp; vertices[i * steps + j].Normal = Vector3.TransformNormal(newn, rotationMatrix); vertices[i * steps + j].Color = point.color; } } for (int j = 0; j < steps; j++) { indices[2 * j] = j; indices[2 * j + 1] = steps + j; } indices[2 * steps] = 0; indices[2 * steps + 1] = steps; return new Tuple<VertexPositionColorNormal[], int[]>(vertices, indices); }
public void Polygonize(List <VertexPositionColorNormal> vertices, int size) { int bitmask = 0; for (int i = 0; i < 4; i++) { if (Sampler.Sample(Positions[i]) < 0) { bitmask |= Bitmasks[i]; } } if (bitmask == 0 || bitmask == 15) { return; } List <Vector2> vs = new List <Vector2>(); switch (bitmask) { case 0x0: break; case 0x1: vs.Add(GetPosition(0, 1)); vs.Add(GetPosition(2, 0)); break; case 0x2: vs.Add(GetPosition(3, 2)); vs.Add(GetPosition(2, 0)); break; case 0x3: vs.Add(GetPosition(3, 2)); vs.Add(GetPosition(0, 1)); break; //Counterclockwise lines stop here because I grew lazy... case 0x4: vs.Add(GetPosition(3, 2)); vs.Add(GetPosition(1, 3)); break; case 0x5: vs.Add(GetPosition(0, 2)); vs.Add(GetPosition(3, 2)); vs.Add(GetPosition(0, 1)); vs.Add(GetPosition(1, 3)); break; case 0x6: vs.Add(GetPosition(0, 2)); vs.Add(GetPosition(1, 3)); break; case 0x7: vs.Add(GetPosition(0, 1)); vs.Add(GetPosition(1, 3)); break; case 0x8: vs.Add(GetPosition(0, 1)); vs.Add(GetPosition(1, 3)); break; case 0x9: vs.Add(GetPosition(0, 2)); vs.Add(GetPosition(1, 3)); break; case 0xA: vs.Add(GetPosition(0, 2)); vs.Add(GetPosition(0, 1)); vs.Add(GetPosition(3, 2)); vs.Add(GetPosition(1, 3)); break; case 0xB: vs.Add(GetPosition(3, 2)); vs.Add(GetPosition(1, 3)); break; case 0xC: vs.Add(GetPosition(0, 1)); vs.Add(GetPosition(3, 2)); break; case 0xD: vs.Add(GetPosition(0, 2)); vs.Add(GetPosition(3, 2)); break; case 0xE: vs.Add(GetPosition(0, 1)); vs.Add(GetPosition(2, 0)); break; case 0xF: break; } for (int i = 0; i < vs.Count; i += 2) { VertexPositionColorNormal v0 = new VertexPositionColorNormal(new Vector3(vs[i], 0) * size, Color.Blue, Vector3.One); VertexPositionColorNormal v1 = new VertexPositionColorNormal(new Vector3(vs[i + 1], 0) * size, Color.Blue, Vector3.One); vertices.Add(v0); vertices.Add(v1); } }
public static int ExtractMesh(VoxelVolume volume, bool disableGreedyMeshing = false, bool disableAO = false) { volume.PrepareMesh(); VertexPositionColorNormal[] vertices = new VertexPositionColorNormal[5]; var dims = volume.dims; var f = new Func<int, int, int, uint>((i, j, k) => { if (i < 0 || j < 0 || k < 0 || i >= dims[0] || j >= dims[1] || k >= dims[2]) return volume.GetRelativeVoxel(i, j, k); //return cm.GetVoxelByRelative(volume.X, volume.Y, volume.Z, i, j, k); var r = volume[i + dims[0] * (j + dims[1] * k)]; if (r > 0 && (r & 0x1000000u) > 0u) { r = 0; } return r; }); //Sweep over 3-axes // d0 = x, d1 = y, d2 = z for (var d = 0; d < 3; ++d) { int i, j, k, l, w, h , u = (d + 1) % 3 , v = (d + 2) % 3; int[] x = { 0, 0, 0 }; int[] q = { 0, 0, 0 }; int[,] posArea = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }; int[,] negArea = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }; if (mask.Length < dims[u] * dims[v]) { mask = new uint[dims[u] * dims[v]]; maskLayout = new MaskLayout[dims[u] * dims[v]]; } q[d] = 1; posArea[0, u] = -1; posArea[1, v] = -1; posArea[2, u] = 1; posArea[3, v] = 1; negArea[0, v] = -1; negArea[1, u] = -1; negArea[2, v] = 1; negArea[3, u] = 1; for (x[d] = -1; x[d] < dims[d]; ) { //Compute mask var n = 0; for (x[v] = 0; x[v] < dims[v]; ++x[v]) { for (x[u] = 0; x[u] < dims[u]; ++x[u], ++n) { var a = f(x[0], x[1], x[2]); var b = f(x[0] + q[0], x[1] + q[1], x[2] + q[2]); maskLayout[n].data = 0u; if ((a != 0) == (b != 0)) { mask[n] = 0; } else if (a != 0) { mask[n] = x[d] > -1 ? a : 0; maskLayout[n].BackFace = false; } else { mask[n] = x[d] < dims[d] - 1 ? b : 0; maskLayout[n].BackFace = true; } if (disableAO || mask[n] == 0) { //maskLayout[n].data = 4095u; } else { uint side1 = 0, side2 = 0, corner = 0; var neighbors = new uint[4]; for (var t = 0; t < 4; ++t) { var tt = (t + 1) % 4; if (a != 0) { side1 = (f(x[0] + q[0] + posArea[t, 0], x[1] + q[1] + posArea[t, 1], x[2] + q[2] + posArea[t, 2]) > 0u ? 1u : 0u); side2 = (f(x[0] + q[0] + posArea[tt, 0], x[1] + q[1] + posArea[tt, 1], x[2] + q[2] + posArea[tt, 2]) > 0u ? 1u : 0u); } else { side1 = (f(x[0] + negArea[t, 0], x[1] + negArea[t, 1], x[2] + negArea[t, 2]) > 0u ? 1u : 0u); side2 = (f(x[0] + negArea[tt, 0], x[1] + negArea[tt, 1], x[2] + negArea[tt, 2]) > 0u ? 1u : 0u); } if (side1 > 0 && side2 > 0) { neighbors[t] = 0; } else { if (a != 0) { corner = (f(x[0] + q[0] + posArea[t, 0] + posArea[tt, 0], x[1] + q[1] + posArea[t, 1] + posArea[tt, 1], x[2] + q[2] + posArea[t, 2] + posArea[tt, 2]) > 0u ? 1u : 0u); } else { corner = (f(x[0] + negArea[t, 0] + negArea[tt, 0], x[1] + negArea[t, 1] + negArea[tt, 1], x[2] + negArea[t, 2] + negArea[tt, 2]) > 0u ? 1u : 0u); } neighbors[t] = 3u - (side1 + side2 + corner); } maskLayout[n].SetOcclusion(t, neighbors[t]); } uint a00 = neighbors[1], a01 = neighbors[2], a11 = neighbors[3], a10 = neighbors[0]; //if (a00 + a01 + a11 + a10 != 12) // maskLayout[n].AOFace = true; } } } //Increment x[d] ++x[d]; //Generate mesh for mask using lexicographic ordering n = 0; for (j = 0; j < dims[v]; ++j) { for (i = 0; i < dims[u]; ) { var c = mask[n]; if (c != 0) { var a = maskLayout[n]; if (disableGreedyMeshing || a.AOFace) { w = 1; h = 1; } else { //Compute width for (w = 1; c == mask[n + w] && (a.data == (maskLayout[n + w].data)) && i + w < dims[u]; ++w) { } //Compute height (this is slightly awkward var done = false; for (h = 1; j + h < dims[v]; ++h) { for (k = 0; k < w; ++k) { if (c != mask[n + k + h * dims[u]] || a.data != maskLayout[n + k + h * dims[u]].data) { done = true; break; } } if (done) { break; } } } //Add quad x[u] = i; x[v] = j; int[] du = { 0, 0, 0 }; int[] dv = { 0, 0, 0 }; var normal = new Vector3(q[0], q[1], q[2]); var aoFace = maskLayout[n].AOFace; if (!maskLayout[n].BackFace) { dv[v] = h; du[u] = w; } else { du[v] = h; dv[u] = w; normal = -normal; } var cr = ((c >> 16) & 0xff) / 255f; var cg = ((c >> 8) & 0xff) / 255f; var cb = (c & 0xff) / 255f; var ao = 0f; var AOcurve = new float[] { 0.45f, 0.65f, 0.85f, 1.0f }; var auCurveFactor = new float[] { 1f, 0.99f, 0.98f, 0.97f, 0.96f }; var aoFactor = auCurveFactor[maskLayout[n].TotalOcclusion()]; for (var o = 0; o < 4; ++o) { var pao = disableAO ? 1f : AOcurve[maskLayout[n].GetOcclusion(o)]; //vertices[o].Color = new Color(cr * pao, cg * pao, cb * pao); vertices[o].Color = new Color(cr * aoFactor, cg * aoFactor, cb * aoFactor); vertices[o].Normal = normal; ao += pao; } ao /= 4f; if (aoFace) { vertices[0].Position = new Vector3(x[0], x[1], x[2]); vertices[1].Position = new Vector3(x[0] + du[0], x[1] + du[1], x[2] + du[2]); vertices[2].Position = new Vector3(x[0] + du[0] + dv[0], x[1] + du[1] + dv[1], x[2] + du[2] + dv[2]); vertices[3].Position = new Vector3(x[0] + dv[0], x[1] + dv[1], x[2] + dv[2]); vertices[4].Position = (vertices[0].Position + vertices[1].Position + vertices[2].Position + vertices[3].Position) / 4; vertices[4].Normal = normal; vertices[4].Color = new Color(cr * ao, cg * ao, cb * ao); } else { vertices[0].Position = new Vector3(x[0], x[1], x[2]); vertices[1].Position = new Vector3(x[0] + du[0], x[1] + du[1], x[2] + du[2]); vertices[2].Position = new Vector3(x[0] + du[0] + dv[0], x[1] + du[1] + dv[1], x[2] + du[2] + dv[2]); vertices[3].Position = new Vector3(x[0] + dv[0], x[1] + dv[1], x[2] + dv[2]); } var v0 = (ushort)volume.opaqueMesh.Add(vertices[0]); var v1 = (ushort)volume.opaqueMesh.Add(vertices[1]); var v2 = (ushort)volume.opaqueMesh.Add(vertices[2]); var v3 = (ushort)volume.opaqueMesh.Add(vertices[3]); if (aoFace) { var v4 = (ushort)volume.opaqueMesh.Add(vertices[4]); volume.opaqueMesh.Triangle(v0, v4, v1); volume.opaqueMesh.Triangle(v1, v4, v2); volume.opaqueMesh.Triangle(v2, v4, v3); volume.opaqueMesh.Triangle(v3, v4, v0); } else { volume.opaqueMesh.Quad(v0, v1, v2, v3); } //Zero-out mask for (l = 0; l < h; ++l) { for (k = 0; k < w; ++k) { mask[n + k + l * dims[u]] = 0; maskLayout[n + k + l * dims[u]].data = 4095u; } } //Increment counters and continue i += w; n += w; } else { ++i; ++n; } } } } } volume.opaqueMesh.Update(); return volume.opaqueMesh.VertexCount; }
public void MakeRoadGeometry(GraphicsDevice device) { roadObject = new VertexBufferObject(Center, Area); List <VertexPositionColorNormal> roadverts = new List <VertexPositionColorNormal>(); List <int> roadinds = new List <int>(); Color roadColor = new Color(87, 59, 12); float roadwidth = 1.5f; foreach (Road r in Roads) { float d = Vector3.Distance(r.A, r.B); Vector3 dir = r.B - r.A; dir.Normalize(); Vector3 fxz = r.B - r.A; fxz.Y = 0; fxz.Normalize(); Vector3 right = Vector3.Cross(Vector3.Up, fxz) * roadwidth * .5f; int ioff = roadverts.Count; int vc = 0; for (float t = -1; t < d + 1; t += .5f) { Vector3 p = r.A - Center + dir * t; p.Y = Area.HeightAt(p + Center) - Center.Y; Vector3 p1 = p - right; Vector3 p2 = p + right; p1.Y = Area.HeightAt(p1 + Center) - Center.Y + .05f; p2.Y = Area.HeightAt(p2 + Center) - Center.Y + .05f; roadverts.Add(new VertexPositionColorNormal(p1, roadColor, Vector3.Zero)); roadverts.Add(new VertexPositionColorNormal(p2, roadColor, Vector3.Zero)); vc += 2; } int ic = roadinds.Count; for (int i = 0; i < vc - 2; i += 2) { // top square roadinds.Add(ioff + i); roadinds.Add(ioff + i + 1); roadinds.Add(ioff + i + 2); roadinds.Add(ioff + i + 1); roadinds.Add(ioff + i + 3); roadinds.Add(ioff + i + 2); } // normals for (int i = ic; i < roadinds.Count; i += 3) { VertexPositionColorNormal v1 = roadverts[roadinds[i]], v2 = roadverts[roadinds[i + 1]], v3 = roadverts[roadinds[i + 2]]; Vector3 d1 = v1.Position - v2.Position; Vector3 d2 = v3.Position - v1.Position; d1.Normalize(); d2.Normalize(); Vector3 normal = Vector3.Cross(d1, d2); v1.Normal += normal; v2.Normal += normal; v3.Normal += normal; roadverts[roadinds[i]] = v1; roadverts[roadinds[i + 1]] = v2; roadverts[roadinds[i + 2]] = v3; } for (int i = ioff; i < roadverts.Count; i++) { roadverts[i].Normal.Normalize(); } } // weld some verticies together // to form nice edges for (int i = 0; i < roadverts.Count; i++) { for (int j = 0; j < roadverts.Count; j++) { if (i != j) { float d = Vector3.DistanceSquared(roadverts[i].Position, roadverts[j].Position); if (d < .2f) { Vector3 mid = (roadverts[i].Position + roadverts[j].Position) * .5f; roadverts[i] = new VertexPositionColorNormal(mid, roadverts[i].Color, roadverts[i].Normal); roadverts[j] = new VertexPositionColorNormal(mid, roadverts[j].Color, roadverts[j].Normal); } } } } roadObject.VBuffer = new VertexBuffer(device, typeof(VertexPositionColorNormal), roadverts.Count, BufferUsage.WriteOnly); roadObject.VBuffer.SetData(roadverts.ToArray()); roadObject.IBuffer = new IndexBuffer(device, typeof(int), roadinds.Count, BufferUsage.WriteOnly); roadObject.IBuffer.SetData(roadinds.ToArray()); }
public void GenerateAt(int x, int y, int z) { int corners = 0; for (int i = 0; i < 8; i++) { if (map[x + i / 4, y + i % 4 / 2, z + i % 2] < 0) { corners |= 1 << i; } } if (corners == 0 || corners == 255) { return; } VertexPositionColor[] vs = new VertexPositionColor[24]; Color c = Color.LightSteelBlue; vs[0] = new VertexPositionColor(new Vector3((x + 0), (y + 0), (z + 0)), c); vs[1] = new VertexPositionColor(new Vector3((x + 1), (y + 0), (z + 0)), c); vs[2] = new VertexPositionColor(new Vector3((x + 1), (y + 0), (z + 0)), c); vs[3] = new VertexPositionColor(new Vector3((x + 1), (y + 1), (z + 0)), c); vs[4] = new VertexPositionColor(new Vector3((x + 1), (y + 1), (z + 0)), c); vs[5] = new VertexPositionColor(new Vector3((x + 0), (y + 1), (z + 0)), c); vs[6] = new VertexPositionColor(new Vector3((x + 0), (y + 1), (z + 0)), c); vs[7] = new VertexPositionColor(new Vector3((x + 0), (y + 0), (z + 0)), c); vs[8] = new VertexPositionColor(new Vector3((x + 0), (y + 0), (z + 1)), c); vs[9] = new VertexPositionColor(new Vector3((x + 1), (y + 0), (z + 1)), c); vs[10] = new VertexPositionColor(new Vector3((x + 1), (y + 0), (z + 1)), c); vs[11] = new VertexPositionColor(new Vector3((x + 1), (y + 1), (z + 1)), c); vs[12] = new VertexPositionColor(new Vector3((x + 1), (y + 1), (z + 1)), c); vs[13] = new VertexPositionColor(new Vector3((x + 0), (y + 1), (z + 1)), c); vs[14] = new VertexPositionColor(new Vector3((x + 0), (y + 1), (z + 1)), c); vs[15] = new VertexPositionColor(new Vector3((x + 0), (y + 0), (z + 1)), c); vs[16] = new VertexPositionColor(new Vector3((x + 0), (y + 0), (z + 0)), c); vs[17] = new VertexPositionColor(new Vector3((x + 0), (y + 0), (z + 1)), c); vs[18] = new VertexPositionColor(new Vector3((x + 0), (y + 1), (z + 0)), c); vs[19] = new VertexPositionColor(new Vector3((x + 0), (y + 1), (z + 1)), c); vs[20] = new VertexPositionColor(new Vector3((x + 1), (y + 0), (z + 0)), c); vs[21] = new VertexPositionColor(new Vector3((x + 1), (y + 0), (z + 1)), c); vs[22] = new VertexPositionColor(new Vector3((x + 1), (y + 1), (z + 0)), c); vs[23] = new VertexPositionColor(new Vector3((x + 1), (y + 1), (z + 1)), c); OutlineBuffer.SetData <VertexPositionColor>(OutlineLocation * VertexPositionColor.VertexDeclaration.VertexStride, vs, 0, 24, VertexPositionColor.VertexDeclaration.VertexStride); OutlineLocation += 24; QEF3D qef = new QEF3D(); Vector3 average_normal = new Vector3(); for (int i = 0; i < 12; i++) { int c1 = edges[i, 0]; int c2 = edges[i, 1]; int m1 = (corners >> c1) & 1; int m2 = (corners >> c2) & 1; if (m1 == m2) { continue; } float d1 = map[x + c1 / 4, y + c1 % 4 / 2, z + c1 % 2]; float d2 = map[x + c2 / 4, y + c2 % 4 / 2, z + c2 % 2]; Vector3 p1 = new Vector3((float)((c1 / 4)), (float)((c1 % 4 / 2)), (float)((c1 % 2))); Vector3 p2 = new Vector3((float)((c2 / 4)), (float)((c2 % 4 / 2)), (float)((c2 % 2))); Vector3 intersection = Sampler.GetIntersection(p1, p2, d1, d2); Vector3 normal = Sampler.GetNormal(intersection + new Vector3(x, y, z)); //GetNormal(x, y); average_normal += normal; qef.Add(intersection, normal); } Vector3 p = qef.Solve2(0, 16, 0); Vector3 n = average_normal / (float)qef.Intersections.Count; VertexPositionColorNormal[] v2 = new VertexPositionColorNormal[1]; Vector3 c_v = n * 0.5f + Vector3.One * 0.5f; c_v.Normalize(); Color clr = new Color(c_v); v2[0] = new VertexPositionColorNormal(new Vector3((p.X + x), (p.Y + y), (p.Z + z)), clr, n); VertexBuffer.SetData <VertexPositionColorNormal>(VertexCount * VertexPositionColorNormal.VertexDeclaration.VertexStride, v2, 0, 1, VertexPositionColorNormal.VertexDeclaration.VertexStride); vertex_indexes[x, y, z] = VertexCount; VertexCount++; /*vs[0] = new VertexPositionColor(new Vector3((x + 0) , (y + 0) , 0), Color.Black); * vs[1] = new VertexPositionColor(new Vector3((x + 1) , (y + 0) , 0), Color.Black); * vs[2] = new VertexPositionColor(new Vector3((x + 1) , (y + 0) , 0), Color.Black); * vs[3] = new VertexPositionColor(new Vector3((x + 1) , (y + 1) , 0), Color.Black); * vs[4] = new VertexPositionColor(new Vector3((x + 1) , (y + 1) , 0), Color.Black); * vs[5] = new VertexPositionColor(new Vector3((x + 0) , (y + 1) , 0), Color.Black); * vs[6] = new VertexPositionColor(new Vector3((x + 0) , (y + 1) , 0), Color.Black); * vs[7] = new VertexPositionColor(new Vector3((x + 0) , (y + 0) , 0), Color.Black); * * vs[8] = new VertexPositionColor(new Vector3((p.X + x) , (p.Y + y) , 0), Color.Black); * vs[9] = new VertexPositionColor(new Vector3((p.X + x + .1f) , (p.Y + y + .1f) , 0), Color.Black); * index = 10; * * VertexBuffer.SetData<VertexPositionColor>(VertexCount * VertexPositionColor.VertexDeclaration.VertexStride, vs, 0, index, VertexPositionColor.VertexDeclaration.VertexStride); * VertexCount += index;*/ }
public Ground(ContentManager content, float Y) { heightMap = new float[width + 1, length + 1]; vertices = new VertexPositionColorNormal[width * length * 6]; //we are intentionally duplicating vertices, hence the * 6 and lack of indexing positionY = Y; var random = new Random(); //Generate terrain for (int x = 0; x <= width; x++) { for (int y = 0; y <= length; y++) { float value = ((float)noiseSource.GetValue(x * 0.5f, (y + positionY / scale.Y) * 0.5f, 0.5f) + 0) / 1; //If this tile is under the road then make it have 0 height so it doesn't stick out if (Math.Abs(x - width / 2) * scale.X < Road.Size * 0.6f) { value = 0; } heightMap[x, y] = value; } } //After generating the heightmap, generate the actual vertices for (int x = 0; x < width; x++) { for (int y = 0; y < length; y++) { int i = (width * y + x) * 6; //Starting vertex index for this tile VertexPositionColorNormal vertex; //6 vertices per tile (x, y) for (int j = 0; j < 6; j++) { vertex = new VertexPositionColorNormal(); //Assign position float ox = x + offsets[j].X; float oy = y + offsets[j].Y; float height = heightMap[(int)ox, (int)oy]; vertex.Position = new Vector3(ox * scale.X, oy * scale.Y, height * 1.5f); //Generate base color based on the following array //Each index corresponds to a different "biome" //The base color therefore implicitly depends on the biome (and usually explicitly depends on height) Vector3[] colors = { new Vector3(0.2f, (heightMap[(int)ox, (int)oy] + 1) / 4 + 0.3f, 0.3f), new Vector3(height.Map(-1, 1, 0.4f, 0.9f), 0.4f, 0.3f), new Vector3(height.Map(-1, 1, 0.7f, 0.9f),height.Map(-1, 1,0.6f, 0.8f), height.Map(-1, 1, 0.2f, 0.5f)), }; //Determine which biome to use based on current position float val = Math.Abs(y + positionY) / biomeScale % colors.Length; int primary = (int)val; //Current biome color int secondary = (primary + 1) % colors.Length; //Next biome color //Smoothly blend between the biome colors if we are in between biomes float blendAmt = 1 - (float)Math.Pow((val - primary) * 2 - 1f, 2); if (val - primary < 0.8f) { blendAmt = 1; } Vector3 blended = colors[primary] * blendAmt + colors[secondary] * (1 - blendAmt); //Assign color Color color = new Color(blended.X, blended.Y, blended.Z); vertex.Color = color; vertices[i + j] = vertex; //Base tile index + local index } } } //These calculations depend on an entire triangle, so I compute them afterwards for (int i = 0; i < vertices.Length; i += 3) { //Compute normal Vector3 u = vertices[i].Position - vertices[i + 1].Position; Vector3 v = vertices[i].Position - vertices[i + 2].Position; Vector3 normal = Vector3.Cross(v, u); normal.Normalize(); //Compute average color of the 3 vertices of a triangle Color color = Color.White; color.R = Math.Max(Math.Max(vertices[i + 0].Color.R, vertices[i + 1].Color.R), vertices[i + 2].Color.R); color.G = Math.Max(Math.Max(vertices[i + 0].Color.G, vertices[i + 1].Color.G), vertices[i + 2].Color.G); color.B = Math.Max(Math.Max(vertices[i + 0].Color.B, vertices[i + 1].Color.B), vertices[i + 2].Color.B); //Assign the same normal and average color to all 3 vertices for (int j = 0; j < 3; j++) { vertices[i + j].Normal = normal; vertices[i + j].Color = color; } } }
public static IEnumerable <VertexPositionColorNormal> getTrisAlternatingOld(VertexPositionColorNormal[] Data, int Depth, int Width) { VertexPositionColorNormal[,] source = new VertexPositionColorNormal[Width, Depth]; //The new, easy to read 2D array for (int x = 0; x < Width; x++) //Convert! { for (int y = 0; y < Depth; y++) { source[x, y] = Data[x + y * Width]; } } var result = new List <VertexPositionColorNormal>(); for (int x = 0; x < Width - 1; x++) { for (int y = 0; y < Depth - 1; y++) { if ((y + x % 2) % 2 == 0) { var a = source[x, y]; var b = source[x + 1, y]; var c = source[x + 1, y + 1]; if (a.Color != Color.Transparent && b.Color != Color.Transparent && c.Color != Color.Transparent) { result.Add(a); result.Add(b); result.Add(c); } b = source[x + 1, y + 1]; c = source[x, y + 1]; if (a.Color != Color.Transparent && b.Color != Color.Transparent && c.Color != Color.Transparent) { result.Add(a); result.Add(b); result.Add(c); } } else { var a = source[x, y]; var b = source[x + 1, y]; var c = source[x, y + 1]; if (a.Color != Color.Transparent && b.Color != Color.Transparent && c.Color != Color.Transparent) { result.Add(a); result.Add(b); result.Add(c); } a = source[x + 1, y]; b = source[x + 1, y + 1]; c = source[x, y + 1]; if (a.Color != Color.Transparent && b.Color != Color.Transparent && c.Color != Color.Transparent) { result.Add(a); result.Add(b); result.Add(c); } } } } return(result); }
public void Initialize(Microsoft.Xna.Framework.Game game, Color color, float[] verts, int[] tris) { _game = game; _vertexBuffer = new VertexBuffer(game.GraphicsDevice, typeof(VertexPositionColorNormal), verts.Length / 3, BufferUsage.None); _indexBuffer = new IndexBuffer(game.GraphicsDevice, typeof(int), tris.Length, BufferUsage.None); var data = new VertexPositionColorNormal[verts.Length/3]; for (int i = 0; i < verts.Length / 3; i++) data[i] = new VertexPositionColorNormal(new Vector3(-verts[(i*3) + 0], verts[(i*3)+1], -verts[(i*3)+2]), color, new Vector3(0)); GenerateNormals(data, tris); _vertexBuffer.SetData(data); _indexBuffer.SetData(tris); }
public void GenerateAt(int x, int y) { int corners = 0; for (int i = 0; i < 4; i++) { if (map[x + i / 2, y + i % 2] < 0) { corners |= 1 << i; } } if (corners == 0 || corners == 15) { return; } VertexPositionColor[] vs = new VertexPositionColor[10]; Color c = Color.LightSteelBlue; vs[0] = new VertexPositionColor(new Vector3((x + 0) * Size, (y + 0) * Size, 0), c); vs[1] = new VertexPositionColor(new Vector3((x + 1) * Size, (y + 0) * Size, 0), c); vs[2] = new VertexPositionColor(new Vector3((x + 1) * Size, (y + 0) * Size, 0), c); vs[3] = new VertexPositionColor(new Vector3((x + 1) * Size, (y + 1) * Size, 0), c); vs[4] = new VertexPositionColor(new Vector3((x + 1) * Size, (y + 1) * Size, 0), c); vs[5] = new VertexPositionColor(new Vector3((x + 0) * Size, (y + 1) * Size, 0), c); vs[6] = new VertexPositionColor(new Vector3((x + 0) * Size, (y + 1) * Size, 0), c); vs[7] = new VertexPositionColor(new Vector3((x + 0) * Size, (y + 0) * Size, 0), c); OutlineBuffer.SetData <VertexPositionColor>(OutlineLocation * VertexPositionColor.VertexDeclaration.VertexStride, vs, 0, 8, VertexPositionColor.VertexDeclaration.VertexStride); OutlineLocation += 8; QEF qef = new QEF(); Vector3 average_normal = new Vector3(); for (int i = 0; i < 4; i++) { int c1 = edges[i, 0]; int c2 = edges[i, 1]; int m1 = (corners >> c1) & 1; int m2 = (corners >> c2) & 1; if (m1 == m2) { continue; } float d1 = map[x + c1 / 2, y + c1 % 2]; float d2 = map[x + c2 / 2, y + c2 % 2]; Vector2 p1 = new Vector2((float)((c1 / 2)), (float)((c1 % 2))); Vector2 p2 = new Vector2((float)((c2 / 2)), (float)((c2 % 2))); Vector2 intersection = Sampler.GetIntersection(p1, p2, d1, d2); Vector2 normal = Sampler.GetNormal(intersection + new Vector2(x, y)); //GetNormal(x, y); average_normal += new Vector3(normal, 0); qef.Add(intersection, normal); } average_normal /= (float)qef.Intersections.Count; average_normal.Normalize(); vertices[x, y] = qef.Solve2(0, 16, 0); Vector2 p = vertices[x, y]; Color n_c = new Color(average_normal * 0.5f + Vector3.One * 0.5f); VertexPositionColorNormal v = new VertexPositionColorNormal(new Vector3((p.X + x) * Size, (p.Y + y) * Size, 0), n_c, average_normal); Vertices.Add(v); vertex_indexes[x, y] = VertexCount; VertexCount++; }
private void ConstructCube() { vertices = new VertexPositionColorNormal[NUM_VERTICES]; //Values are set from the bottomleftfront corner of a box. // Calculate the position of the vertices on the top face. Vector3 topLeftFront = position + new Vector3(0.0f, 1.0f, 0.0f) * Size; Vector3 topLeftBack = position + new Vector3(0.0f, 1.0f, 1.0f) * Size; Vector3 topRightFront = position + new Vector3(1.0f, 1.0f, 0.0f) * Size; Vector3 topRightBack = position + new Vector3(1.0f, 1.0f, 1.0f) * Size; // Calculate the position of the vertices on the bottom face. Vector3 btmLeftFront = position + new Vector3(0.0f, 0.0f, 0.0f) * Size; Vector3 btmLeftBack = position + new Vector3(0.0f, 0.0f, 1.0f) * Size; Vector3 btmRightFront = position + new Vector3(1.0f, 0.0f, 0.0f) * Size; Vector3 btmRightBack = position + new Vector3(1.0f, 0.0f, 1.0f) * Size; // Normal vectors for each face (needed for lighting / display) Vector3 normalFront = new Vector3(0.0f, 0.0f, 1.0f) * Size; Vector3 normalBack = new Vector3(0.0f, 0.0f, -1.0f) * Size; Vector3 normalTop = new Vector3(0.0f, 1.0f, 0.0f) * Size; Vector3 normalBottom = new Vector3(0.0f, -1.0f, 0.0f) * Size; Vector3 normalLeft = new Vector3(-1.0f, 0.0f, 0.0f) * Size; Vector3 normalRight = new Vector3(1.0f, 0.0f, 0.0f) * Size; // UV texture coordinates Vector2 textureTopLeft = new Vector2(1.0f * Size.X, 0.0f * Size.Y); Vector2 textureTopRight = new Vector2(0.0f * Size.X, 0.0f * Size.Y); Vector2 textureBottomLeft = new Vector2(1.0f * Size.X, 1.0f * Size.Y); Vector2 textureBottomRight = new Vector2(0.0f * Size.X, 1.0f * Size.Y); // Add the vertices for the FRONT face. vertices[0] = new VertexPositionColorNormal(topLeftFront, Color, normalFront); vertices[1] = new VertexPositionColorNormal(btmLeftFront, Color, normalFront); vertices[2] = new VertexPositionColorNormal(topRightFront, Color, normalFront); vertices[3] = new VertexPositionColorNormal(btmLeftFront, Color, normalFront); vertices[4] = new VertexPositionColorNormal(btmRightFront, Color, normalFront); vertices[5] = new VertexPositionColorNormal(topRightFront, Color, normalFront); // Add the vertices for the BACK face. vertices[6] = new VertexPositionColorNormal(topLeftBack, Color, normalBack); vertices[7] = new VertexPositionColorNormal(topRightBack, Color, normalBack); vertices[8] = new VertexPositionColorNormal(btmLeftBack, Color, normalBack); vertices[9] = new VertexPositionColorNormal(btmLeftBack, Color, normalBack); vertices[10] = new VertexPositionColorNormal(topRightBack, Color, normalBack); vertices[11] = new VertexPositionColorNormal(btmRightBack, Color, normalBack); // Add the vertices for the TOP face. vertices[12] = new VertexPositionColorNormal(topLeftFront, Color, normalTop); vertices[13] = new VertexPositionColorNormal(topRightBack, Color, normalTop); vertices[14] = new VertexPositionColorNormal(topLeftBack, Color, normalTop); vertices[15] = new VertexPositionColorNormal(topLeftFront, Color, normalTop); vertices[16] = new VertexPositionColorNormal(topRightFront, Color, normalTop); vertices[17] = new VertexPositionColorNormal(topRightBack, Color, normalTop); // Add the vertices for the BOTTOM face. vertices[18] = new VertexPositionColorNormal(btmLeftFront, Color,normalBottom); vertices[19] = new VertexPositionColorNormal(btmLeftBack, Color, normalBottom); vertices[20] = new VertexPositionColorNormal(btmRightBack, Color, normalBottom); vertices[21] = new VertexPositionColorNormal(btmLeftFront, Color, normalBottom); vertices[22] = new VertexPositionColorNormal(btmRightBack, Color, normalBottom); vertices[23] = new VertexPositionColorNormal(btmRightFront, Color, normalBottom); // Add the vertices for the LEFT face. vertices[24] = new VertexPositionColorNormal(topLeftFront, Color, normalLeft); vertices[25] = new VertexPositionColorNormal(btmLeftBack, Color, normalLeft); vertices[26] = new VertexPositionColorNormal(btmLeftFront, Color, normalLeft); vertices[27] = new VertexPositionColorNormal(topLeftBack, Color, normalLeft); vertices[28] = new VertexPositionColorNormal(btmLeftBack, Color, normalLeft); vertices[29] = new VertexPositionColorNormal(topLeftFront, Color, normalLeft); // Add the vertices for the RIGHT face. vertices[30] = new VertexPositionColorNormal(topRightFront, Color, normalRight); vertices[31] = new VertexPositionColorNormal(btmRightFront, Color, normalRight); vertices[32] = new VertexPositionColorNormal(btmRightBack, Color, normalRight); vertices[33] = new VertexPositionColorNormal(topRightBack, Color, normalRight); vertices[34] = new VertexPositionColorNormal(topRightFront, Color, normalRight); vertices[35] = new VertexPositionColorNormal(btmRightBack, Color, normalRight); _isConstructed = true; }
private void AddFlatTriangle(bool flipped, params int[] indexes) { VertexPositionColorNormal[] verts = new VertexPositionColorNormal[indexes.Length]; for (int i = 0; i < verts.Length; i++) { verts[i] = new VertexPositionColorNormal(CalculatedVertices[indexes[i]].Position, CalculatedVertices[indexes[i]].Color, Vector3.Zero); } if (indexes.Length > 3) { if (!flipped) { Vector3 n = GetNormalQ(ref verts, 2, 0, 1, 1, 3, 2); Vector3 c_v = n * 0.5f + Vector3.One * 0.5f; c_v.Normalize(); Color clr = new Color(c_v); Vector3 d = new Vector3(-.1f, -1f, -.1f); d.Normalize(); float g = (Vector3.Dot(n, d) + 1.0f) * 0.5f; //clr = new Color(0, g, 0); for (int i = 0; i < 4; i++) { verts[i].Normal = n; verts[i].Color = clr; } //GetNormal(ref verts, 2, 0, 1); Vertices.Add(verts[2]); Vertices.Add(verts[0]); Vertices.Add(verts[1]); //GetNormal(ref verts, 1, 3, 2); Vertices.Add(verts[1]); Vertices.Add(verts[3]); Vertices.Add(verts[2]); } else { Vector3 n = GetNormalQ(ref verts, 2, 1, 0, 1, 2, 3); Vector3 c_v = n * 0.5f + Vector3.One * 0.5f; c_v.Normalize(); Color clr = new Color(c_v); Vector3 d = new Vector3(-.1f, -1f, -.1f); d.Normalize(); float g = (Vector3.Dot(n, d) + 1.0f) * 0.5f; //clr = new Color(0, g, 0); for (int i = 0; i < 4; i++) { verts[i].Normal = n; verts[i].Color = clr; } //GetNormal(ref verts, 2, 1, 0); Vertices.Add(verts[2]); Vertices.Add(verts[1]); Vertices.Add(verts[0]); //GetNormal(ref verts, 1, 2, 3); Vertices.Add(verts[1]); Vertices.Add(verts[2]); Vertices.Add(verts[3]); } } else if (indexes.Length == 3) { /*GetNormal(ref verts, 0, 1, 2); * Vertices.Add(verts[0]); * Vertices.Add(verts[1]); * Vertices.Add(verts[2]);*/ } }
private bool CreateMesh(out VertexPositionColorNormal[] verts, out short[] indices) { List<VertexPositionColorNormal> vertsList = new List<VertexPositionColorNormal>(); List<short> indicesList = new List<short>(); #region NonSolid if (!Solid) { for (int x = 0; x < Control.CHUNK_SIZE; x++) { for (int y = 0; y < Control.CHUNK_SIZE; y++) { for (int z = 0; z < Control.CHUNK_SIZE; z++) { Block cData = _data[x, y, z]; if (cData == 0x00 || cData == (byte)BT.Reserved) continue; Color color = cData.color; #region Left if (this[x - 1, y, z] == 0x00) //Left side visible? { short numVerts = (short)vertsList.Count; Vector3 Normal = Vector3.Left; vertsList.Add(new VertexPositionColorNormal(new Vector3(x, y, z), Normal, color));//bottom front vertsList.Add(new VertexPositionColorNormal(new Vector3(x, y, z + 1), Normal, color));//bottom back vertsList.Add(new VertexPositionColorNormal(new Vector3(x, y + 1, z), Normal, color));//top front vertsList.Add(new VertexPositionColorNormal(new Vector3(x, y + 1, z + 1), Normal, color));//top back indicesList.Add(numVerts); indicesList.Add((short)(numVerts + 2)); indicesList.Add((short)(numVerts + 1)); indicesList.Add((short)(numVerts + 1)); indicesList.Add((short)(numVerts + 2)); indicesList.Add((short)(numVerts + 3)); } #endregion #region Right if (this[x + 1, y, z] == 0x00) //Right side visible? { short numVerts = (short)vertsList.Count; Vector3 Normal = Vector3.Right; vertsList.Add(new VertexPositionColorNormal(new Vector3(x + 1, y, z), Normal, color));//bottom front vertsList.Add(new VertexPositionColorNormal(new Vector3(x + 1, y, z + 1), Normal, color));//bottom back vertsList.Add(new VertexPositionColorNormal(new Vector3(x + 1, y + 1, z), Normal, color));//top front vertsList.Add(new VertexPositionColorNormal(new Vector3(x + 1, y + 1, z + 1), Normal, color));//top back indicesList.Add(numVerts); indicesList.Add((short)(numVerts + 1)); indicesList.Add((short)(numVerts + 2)); indicesList.Add((short)(numVerts + 2)); indicesList.Add((short)(numVerts + 1)); indicesList.Add((short)(numVerts + 3)); } #endregion #region Bottom if (this[x, y - 1, z] == 0x00) //Bottom side visible? { short numVerts = (short)vertsList.Count; Vector3 Normal = Vector3.Down; vertsList.Add(new VertexPositionColorNormal(new Vector3(x, y, z), Normal, color)); //left front vertsList.Add(new VertexPositionColorNormal(new Vector3(x, y, z + 1), Normal, color)); //left back vertsList.Add(new VertexPositionColorNormal(new Vector3(x + 1, y, z), Normal, color)); //right front vertsList.Add(new VertexPositionColorNormal(new Vector3(x + 1, y, z + 1), Normal, color)); //right back indicesList.Add(numVerts); indicesList.Add((short)(numVerts + 1)); indicesList.Add((short)(numVerts + 2)); indicesList.Add((short)(numVerts + 2)); indicesList.Add((short)(numVerts + 1)); indicesList.Add((short)(numVerts + 3)); } #endregion #region Top if (this[x, y + 1, z] == 0x00) //Top side visible? { short numVerts = (short)vertsList.Count; Vector3 Normal = Vector3.Up; vertsList.Add(new VertexPositionColorNormal(new Vector3(x, y + 1, z), Normal, color)); //left front vertsList.Add(new VertexPositionColorNormal(new Vector3(x, y + 1, z + 1), Normal, color)); //left back vertsList.Add(new VertexPositionColorNormal(new Vector3(x + 1, y + 1, z), Normal, color)); //right front vertsList.Add(new VertexPositionColorNormal(new Vector3(x + 1, y + 1, z + 1), Normal, color)); //right back indicesList.Add(numVerts); indicesList.Add((short)(numVerts + 2)); indicesList.Add((short)(numVerts + 1)); indicesList.Add((short)(numVerts + 1)); indicesList.Add((short)(numVerts + 2)); indicesList.Add((short)(numVerts + 3)); } #endregion #region Front if (this[x, y, z - 1] == 0x00) //Front side visible? { short numVerts = (short)vertsList.Count; Vector3 Normal = Vector3.Forward; vertsList.Add(new VertexPositionColorNormal(new Vector3(x, y, z), Normal, color)); //left bottom vertsList.Add(new VertexPositionColorNormal(new Vector3(x, y + 1, z), Normal, color)); //left top vertsList.Add(new VertexPositionColorNormal(new Vector3(x + 1, y, z), Normal, color)); //right bottom vertsList.Add(new VertexPositionColorNormal(new Vector3(x + 1, y + 1, z), Normal, color)); //right top indicesList.Add(numVerts); indicesList.Add((short)(numVerts + 2)); indicesList.Add((short)(numVerts + 3)); indicesList.Add((short)(numVerts + 3)); indicesList.Add((short)(numVerts + 1)); indicesList.Add(numVerts); } #endregion #region Back if (this[x, y, z + 1] == 0x00) //Back visible? { short numVerts = (short)vertsList.Count; Vector3 Normal = Vector3.Backward; vertsList.Add(new VertexPositionColorNormal(new Vector3(x, y, z + 1), Normal, color)); //left bottom vertsList.Add(new VertexPositionColorNormal(new Vector3(x, y + 1, z + 1), Normal, color)); //left top vertsList.Add(new VertexPositionColorNormal(new Vector3(x + 1, y, z + 1), Normal, color)); //right bottom vertsList.Add(new VertexPositionColorNormal(new Vector3(x + 1, y + 1, z + 1), Normal, color)); //right top indicesList.Add(numVerts); indicesList.Add((short)(numVerts + 1)); indicesList.Add((short)(numVerts + 2)); indicesList.Add((short)(numVerts + 2)); indicesList.Add((short)(numVerts + 1)); indicesList.Add((short)(numVerts + 3)); } #endregion } } } } #endregion #region Solid else { #region Check Sides bool drawFront = true, drawBack = true, drawLeft = true, drawRight = true, drawBottom = true, drawTop = true; Chunk c = MapManager.GetChunk(Position + Int3.Backward); if (c != null) if (c[CF.isLoaded] && c.Solid) drawFront = false; c = MapManager.GetChunk(Position + Int3.Forward); if (c != null) if (c[CF.isLoaded] && c.Solid) drawBack = false; c = MapManager.GetChunk(Position + Int3.Left); if (c != null) if (c[CF.isLoaded] && c.Solid) drawLeft = false; c = MapManager.GetChunk(Position + Int3.Right); if (c != null) if (c[CF.isLoaded] && c.Solid) drawRight = false; c = MapManager.GetChunk(Position + Int3.Up); if (c != null) if (c[CF.isLoaded] && c.Solid) drawTop = false; c = MapManager.GetChunk(Position + Int3.Down); if (c != null) if (c[CF.isLoaded] && c.Solid) drawBottom = false; c = null; #endregion if (drawBack || drawBottom || drawFront || drawLeft || drawRight || drawTop) { for (int index0 = 0; index0 < Control.CHUNK_SIZE; index0++) { for (int index1 = 0; index1 < Control.CHUNK_SIZE; index1++) { int x, y, z; Block cData; Color color; #region Front if (drawFront) { x = index0; y = index1; z = 0; cData = _data[x, y, z]; color = cData.color; #region Front Verts if (this[x, y, z - 1] == 0x00) //Front side visible? { short numVerts = (short)vertsList.Count; Vector3 Normal = Vector3.Forward; vertsList.Add(new VertexPositionColorNormal(new Vector3(x, y, z), Normal, color)); //left bottom vertsList.Add(new VertexPositionColorNormal(new Vector3(x, y + 1, z), Normal, color)); //left top vertsList.Add(new VertexPositionColorNormal(new Vector3(x + 1, y, z), Normal, color)); //right bottom vertsList.Add(new VertexPositionColorNormal(new Vector3(x + 1, y + 1, z), Normal, color)); //right top indicesList.Add(numVerts); indicesList.Add((short)(numVerts + 2)); indicesList.Add((short)(numVerts + 3)); indicesList.Add((short)(numVerts + 3)); indicesList.Add((short)(numVerts + 1)); indicesList.Add(numVerts); } #endregion } #endregion #region Back if (drawBack) { x = index0; y = index1; z = Control.CHUNK_SIZE - 1; cData = _data[x, y, z]; color = cData.color; #region Back Verts if (this[x, y, z + 1] == 0x00) //Back visible? { short numVerts = (short)vertsList.Count; Vector3 Normal = Vector3.Backward; vertsList.Add(new VertexPositionColorNormal(new Vector3(x, y, z + 1), Normal, color)); //left bottom vertsList.Add(new VertexPositionColorNormal(new Vector3(x, y + 1, z + 1), Normal, color)); //left top vertsList.Add(new VertexPositionColorNormal(new Vector3(x + 1, y, z + 1), Normal, color)); //right bottom vertsList.Add(new VertexPositionColorNormal(new Vector3(x + 1, y + 1, z + 1), Normal, color)); //right top indicesList.Add(numVerts); indicesList.Add((short)(numVerts + 1)); indicesList.Add((short)(numVerts + 2)); indicesList.Add((short)(numVerts + 2)); indicesList.Add((short)(numVerts + 1)); indicesList.Add((short)(numVerts + 3)); } #endregion } #endregion #region Bottom if (drawBottom) { x = index0; y = 0; z = index1; cData = _data[x, y, z]; color = cData.color; #region Bottom Verts if (this[x, y - 1, z] == 0x00) //Bottom side visible? { short numVerts = (short)vertsList.Count; Vector3 Normal = Vector3.Down; vertsList.Add(new VertexPositionColorNormal(new Vector3(x, y, z), Normal, color)); //left front vertsList.Add(new VertexPositionColorNormal(new Vector3(x, y, z + 1), Normal, color)); //left back vertsList.Add(new VertexPositionColorNormal(new Vector3(x + 1, y, z), Normal, color)); //right front vertsList.Add(new VertexPositionColorNormal(new Vector3(x + 1, y, z + 1), Normal, color)); //right back indicesList.Add(numVerts); indicesList.Add((short)(numVerts + 1)); indicesList.Add((short)(numVerts + 2)); indicesList.Add((short)(numVerts + 2)); indicesList.Add((short)(numVerts + 1)); indicesList.Add((short)(numVerts + 3)); } #endregion } #endregion #region Top if (drawTop) { x = index0; y = Control.CHUNK_SIZE - 1; z = index1; cData = _data[x, y, z]; color = cData.color; #region Top Verts if (this[x, y + 1, z] == 0x00) //Top side visible? { short numVerts = (short)vertsList.Count; Vector3 Normal = Vector3.Up; vertsList.Add(new VertexPositionColorNormal(new Vector3(x, y + 1, z), Normal, color)); //left front vertsList.Add(new VertexPositionColorNormal(new Vector3(x, y + 1, z + 1), Normal, color)); //left back vertsList.Add(new VertexPositionColorNormal(new Vector3(x + 1, y + 1, z), Normal, color)); //right front vertsList.Add(new VertexPositionColorNormal(new Vector3(x + 1, y + 1, z + 1), Normal, color)); //right back indicesList.Add(numVerts); indicesList.Add((short)(numVerts + 2)); indicesList.Add((short)(numVerts + 1)); indicesList.Add((short)(numVerts + 1)); indicesList.Add((short)(numVerts + 2)); indicesList.Add((short)(numVerts + 3)); } #endregion } #endregion #region Left if (drawLeft) { x = 0; y = index0; z = index1; cData = _data[x, y, z]; color = cData.color; #region Left Verts if (this[x - 1, y, z] == 0x00) //Left side visible? { short numVerts = (short)vertsList.Count; Vector3 Normal = Vector3.Left; vertsList.Add(new VertexPositionColorNormal(new Vector3(x, y, z), Normal, color));//bottom front vertsList.Add(new VertexPositionColorNormal(new Vector3(x, y, z + 1), Normal, color));//bottom back vertsList.Add(new VertexPositionColorNormal(new Vector3(x, y + 1, z), Normal, color));//top front vertsList.Add(new VertexPositionColorNormal(new Vector3(x, y + 1, z + 1), Normal, color));//top back indicesList.Add(numVerts); indicesList.Add((short)(numVerts + 2)); indicesList.Add((short)(numVerts + 1)); indicesList.Add((short)(numVerts + 1)); indicesList.Add((short)(numVerts + 2)); indicesList.Add((short)(numVerts + 3)); } #endregion } #endregion #region Right if (drawRight) { x = Control.CHUNK_SIZE - 1; y = index0; z = index1; cData = _data[x, y, z]; color = cData.color; #region Right Verts if (this[x + 1, y, z] == 0x00) //Right side visible? { short numVerts = (short)vertsList.Count; Vector3 Normal = Vector3.Right; vertsList.Add(new VertexPositionColorNormal(new Vector3(x + 1, y, z), Normal, color));//bottom front vertsList.Add(new VertexPositionColorNormal(new Vector3(x + 1, y, z + 1), Normal, color));//bottom back vertsList.Add(new VertexPositionColorNormal(new Vector3(x + 1, y + 1, z), Normal, color));//top front vertsList.Add(new VertexPositionColorNormal(new Vector3(x + 1, y + 1, z + 1), Normal, color));//top back indicesList.Add(numVerts); indicesList.Add((short)(numVerts + 1)); indicesList.Add((short)(numVerts + 2)); indicesList.Add((short)(numVerts + 2)); indicesList.Add((short)(numVerts + 1)); indicesList.Add((short)(numVerts + 3)); } #endregion } #endregion } } } } #endregion if (indicesList.Count == 0) { verts = null; indices = null; return false; } verts = vertsList.ToArray(); indices = indicesList.ToArray(); vertsList.Clear(); indicesList.Clear(); return true; }