void GraphParticles() { currColor = coloring; currFn = sampleFunction; float yMax = float.NegativeInfinity; float yMin = float.PositiveInfinity; float maxMag = float.NegativeInfinity; TwoVariableFunctions.TwoVariableFunction fn = TwoVariableFunctions.twoVarFns[(int)sampleFunction]; float t = Time.timeSinceLevelLoad; for (int i = 0; i < particles.Length; i++) { Vector3 pos = particles[i].position; float y = fn(pos.x, pos.z); if (y > yMax) { yMax = y; } if (y < yMin) { yMin = y; } if (pos.magnitude > maxMag) { maxMag = pos.magnitude; } particles[i].position = new Vector3(pos.x, y, pos.z); if (coloring == ColoringMethod.NORMAL) { Vector3 f = pos + front; Vector3 b = pos + back; Vector3 l = pos + left; Vector3 r = pos + right; f += new Vector3(0, fn(f.x, f.z)); b += new Vector3(0, fn(b.x, b.z)); l += new Vector3(0, fn(l.x, l.z)); r += new Vector3(0, fn(r.x, r.z)); Vector3 n = Vector3.Cross(r, f); n += Vector3.Cross(f, l); n += Vector3.Cross(l, b); n += Vector3.Cross(b, r); normals[i] = n.normalized; } } for (int i = 0; i < particles.Length; i++) { switch (coloring) { case ColoringMethod.GRADIENT: float y = particles[i].position.y; particles[i].startColor = gradient.Evaluate((y - yMin) / (yMax - yMin)); break; case ColoringMethod.CONTOUR: float y0 = particles[i].position.y; float ratio = (y0 - yMin) / (yMax - yMin); if (ratio * 100f % 10f < 1.5f || ratio * 100f % 10f > 9.5f) { particles[i].startColor = Color.grey; } else { particles[i].startColor = Color.white; } break; case ColoringMethod.DISTANCE: float m = particles[i].position.magnitude; particles[i].startColor = gradient.Evaluate(m / maxMag); break; case ColoringMethod.SOLID: particles[i].startColor = Color.cyan; break; case ColoringMethod.NORMAL: particles[i].startColor = new Color((normals[i].x + 1f) / 2f, (normals[i].y + 1f) / 2f, (normals[i].z + 1f) / 2f); break; } } }
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(); }
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 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; }