public VisualisationWindow(ZArrayDescriptor desc, ICamera cam, int width, int height, int fsaa_samples, bool vsync) : base(width, height, new GraphicsMode(32, 24, 0, fsaa_samples)) { this.cam = cam; if(!vsync) this.VSync = VSyncMode.Off; }
public VisualisationWindow(ZArrayDescriptor desc, ICamera cam, int fsaa_samples = 0, bool vsync = true) : base(100, 100, new GraphicsMode(32, 24, 0, fsaa_samples)) { this.Width = DisplayDevice.Default.Width; this.Height = DisplayDevice.Default.Height - 70; this.Location = new System.Drawing.Point(0, 0); this.cam = cam; if (!vsync) this.VSync = VSyncMode.Off; }
private static Tuple<Vector3[], Vector4b[], uint[]> ParseZArray(ZArrayDescriptor desc, ColoringMethod coloring) { Vector3[,] vertexPositions = new Vector3[desc.width, desc.height]; Vector3[,] normals = new Vector3[desc.width, desc.height]; int z_max = 0, z_min = 0; for (int i = 0; i < desc.width; ++i) for (int j = 0; j < desc.height; ++j) { if (desc.array[i, j] > z_max) z_max = (int)desc.array[i, j]; if (desc.array[i, j] < z_min) z_min = (int)desc.array[i, j]; } int zCenterShift = (z_max + z_min) / 2; int xCenterShift = desc.width / 2; int yCenterShift = desc.height / 2; // this cycle to be optimized (?) for (int i = 0; i < desc.width - 1; ++i) { for (int j = 0; j < desc.height - 1; ++j) { int x = i - xCenterShift; int y = yCenterShift - j; vertexPositions[i + 1, j + 1] = new Vector3(x + 1, y + 1, desc.array[i + 1, j + 1] - zCenterShift); vertexPositions[i + 1, j] = new Vector3(x + 1, y, desc.array[i + 1, j] - zCenterShift); vertexPositions[i, j] = new Vector3(x, y, desc.array[i, j] - zCenterShift); vertexPositions[i, j + 1] = new Vector3(x, y + 1, desc.array[i, j + 1] - zCenterShift); vertexPositions[i + 1, j + 1] = new Vector3(x + 1, y + 1, desc.array[i + 1, j + 1] - zCenterShift); vertexPositions[i, j] = new Vector3(x, y, desc.array[i, j] - zCenterShift); Vector3 norm1 = Vector3.Cross( vertexPositions[i + 1, j + 1] - vertexPositions[i, j], vertexPositions[i + 1, j] - vertexPositions[i, j]).Normalized(); Vector3 norm2 = Vector3.Cross( vertexPositions[i, j + 1] - vertexPositions[i, j], vertexPositions[i + 1, j + 1] - vertexPositions[i, j]).Normalized(); Vector3.Add(ref normals[i, j], ref norm1, out normals[i, j]); Vector3.Add(ref normals[i + 1, j], ref norm1, out normals[i + 1, j]); Vector3.Add(ref normals[i + 1, j + 1], ref norm1, out normals[i + 1, j + 1]); Vector3.Add(ref normals[i, j], ref norm2, out normals[i, j]); Vector3.Add(ref normals[i, j + 1], ref norm2, out normals[i, j + 1]); Vector3.Add(ref normals[i + 1, j + 1], ref norm2, out normals[i + 1, j + 1]); } } // vertexes color calculated from average vertex normal Vector4b[] colors = new Vector4b[desc.width * desc.height]; uint ptr = 0; for (int i = 0; i < desc.width; ++i) { for (int j = 0; j < desc.height; ++j) { Vector3.Multiply(ref normals[i, j], 0.166666666f, out normals[i, j]); switch (coloring) { case ColoringMethod.Fullcolor: calcFullcolor(ref normals[i, j], ref colors[ptr++]); break; case ColoringMethod.Grayscale: calcGrayscale(ref normals[i, j], ref colors[ptr++]); break; } } } normals = null; GC.Collect(); // data arrangement Vector3[] positions = new Vector3[desc.width * desc.height]; uint[] elements = new uint[2 * (desc.width - 1) * (desc.height + 1)]; ptr = 0; for (int i = 0; i < desc.width; ++i) for (int j = 0; j < desc.height; ++j) positions[ptr++] = vertexPositions[i, j]; vertexPositions = null; GC.Collect(); ptr = 0; for (uint i = 0; i < desc.width - 1; ++i) { uint j; for (j = 0; j < desc.height; ++j) { elements[ptr++] = (uint)(i * desc.height + j); elements[ptr++] = (uint)((i + 1) * desc.height + j); } //elements[ptr++] = restartIndex; elements[ptr++] = (uint)((i + 1) * desc.height + j - 1); elements[ptr++] = (uint)((i + 1) * desc.height); } return new Tuple<Vector3[], Vector4b[], uint[]>(positions, colors, elements); }
public static void ZArrayToObject(ZArrayDescriptor desc, ColoringMethod coloring, string path) { Tuple<Vector3[], Vector4b[], uint[]> meshData = ParseZArray(desc, coloring); StreamWriter sw = new StreamWriter(path); sw.WriteLine("o surface"); // write verteces for (int i = 0; i < meshData.Item1.Length; ++i) sw.WriteLine("v " + meshData.Item1[i].X + " " + meshData.Item1[i].Y + " " + meshData.Item1[i].Z); // write normals for (int i = 0; i < meshData.Item2.Length; ++i) sw.WriteLine("vn " + ((float) meshData.Item2[i].V1) / 127.0f + " " + ((float) meshData.Item2[i].V2) / 127.0f + " " + ((float) meshData.Item2[i].V3) / 127.0f); // write indices for (int i = 0; i < desc.width - 1; ++i) for (int j = 0; j < desc.height - 1; ++j) { int v1 = 1 + (i * desc.height + j); int v2 = v1 + 1; // = 1 + (i * desc.height + j + 1); int v3 = v2 + desc.height; // = 1 + ((i + 1) * desc.height + j + 1); int v4 = v1 + desc.height; // = 1 + ((i + 1) * desc.height + j); sw.WriteLine("f " + v1 + "//" + v1 + " " + v2 + "//" + v2 + " " + v3 + "//" + v3 + " " + v4 + "//" + v4 + " "); } sw.WriteLine(""); sw.Close(); }
public static Mesh FromZArray(ZArrayDescriptor desc, ColoringMethod coloring) { Tuple<Vector3[], Vector4b[], uint[]> meshData = ParseZArray(desc, coloring); Mesh rv = new Mesh(meshData.Item1, meshData.Item2, meshData.Item3); rv.primitiveCount = meshData.Item3.Length; rv.primitiveType = PrimitiveType.TriangleStrip; return rv; }
public static ZArrayDescriptor createPerlin1d(int width, int height, int octaves) { ZArrayDescriptor z = new ZArrayDescriptor(); z.width = height; z.height = width; z.array = new float[z.width, z.height]; float y = 0, x = 0; for (int i = 0; i < z.width; ++i, x += 0.03f) { for (int j = 0; j < z.height; ++j, y += 0.03f) { z.array[i, j] = perlinNoise(x, y, octaves); } y = 0.0f; Console.WriteLine(i + "/" + z.width); } return z; }
public static ZArrayDescriptor createRandom(int width, int height) { ZArrayDescriptor desc = new ZArrayDescriptor(); desc.array = new float[height, width]; desc.width = width; desc.height = height; Random r = new Random(); for(int i = 0; i < width; ++i) for (int j = 0; j < height; ++j) { desc.array[j, i] = (float)(r.NextDouble() * 1); } return desc; }