Exemple #1
0
    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;
 }