void Awake()
 {
     ProceduralDuplication.AddToSimulate(this.gameObject);
     Destroy(this);
 }
Beispiel #2
0
    // Use this for initialization
    void Awake()
    {
        //Random.seed = 2;

        //Target is the value that represents the surface of mesh
        //For example the perlin noise has a range of -1 to 1 so the mid point is were we want the surface to cut through
        //The target value does not have to be the mid point it can be any value with in the range
        MarchingCubes.SetTarget(-0.8825f);

        //Winding order of triangles use 2,1,0 or 0,1,2
        MarchingCubes.SetWindingOrder(2, 1, 0);

        //Set the mode used to create the mesh
        //Cubes is faster and creates less verts, tetrahedrons is slower and creates more verts but better represents the mesh surface
        MarchingCubes.SetModeToCubes();
        //MarchingCubes.SetModeToTetrahedrons();

        //the index of the closest voronoi seed
        int[, ,] voxelVoronoi = new int[_width + 1, _height + 1, _length + 1];
        //smoothmin distances
        float[, ,] voxelSmoothMin = new float[_width + 1, _height + 1, _length + 1];
        //final values
        float[, ,] voxels = new float[_width + 1, _height + 1, _length + 1];
        int x, y, z;

        float start = Time.realtimeSinceStartup;

        Vector3[] seeds = new Vector3[numSeeds];

        for (int i = 0; i < seeds.Length; i++)
        {
            seeds[i] = new Vector3(Random.value * (_width + 1), Random.value * (_height + 1), Random.value * (_length + 1));
        }

        //populate the voronoi/smoothmin arrays
        for (x = 0; x < _width + 1; x++)
        {
            for (y = 0; y < _height + 1; y++)
            {
                for (z = 0; z < _length + 1; z++)
                {
                    Vector3 testPoint = new Vector3(x, y, z);

                    int   closestSeedIndex = 0;
                    float distance         = distanceOfMirrors(testPoint, seeds[0]);

                    for (int i = 1; i < seeds.Length; i++)
                    {
                        float queryDistance = distanceOfMirrors(testPoint, seeds[i]);
                        if (queryDistance < distance)
                        {
                            distance         = queryDistance;
                            closestSeedIndex = i;
                        }
                    }

                    voxelVoronoi[x, y, z] = closestSeedIndex;

                    voxelSmoothMin[x, y, z] = sminDistance(testPoint, seeds, k);
                }
            }
        }
        int yesCount = 0;
        int noCount  = 0;

        //Create a mesh for each seed
        for (int i = 0; i < seeds.Length; i++)
        {
            //Fill voxels with values. Im using perlin noise but any method to create voxels will work
            for (x = 0; x < _width + 1; x++)
            {
                for (y = 0; y < _height + 1; y++)
                {
                    for (z = 0; z < _length + 1; z++)
                    {
                        if (voxelVoronoi[x, y, z] != i) //we are not in the correct voronoi cell
                        {
                            voxels[x, y, z] = 1;        //outside
                            noCount++;
                        }
                        else
                        {
                            Vector3 queryPoint = new Vector3(x, y, z);
                            float   distance   = distanceOfMirrors(queryPoint, seeds[i]);
                            distance        = voxelSmoothMin[x, y, z] / distance;
                            voxels[x, y, z] = 1 - (distance * 2); //transform from 0..1 to 1..-1
                            yesCount++;
                        }
                    }
                }
            }

            Mesh mesh = MarchingCubes.CreateMesh(voxels, _scale);

            //The diffuse shader wants uvs so just fill with a empty array, there not actually used
            mesh.RecalculateNormals();

            m_mesh = Instantiate(meshPrefab);
            m_mesh.GetComponent <MeshFilter>().mesh = mesh;

            //Center mesh
            //m_mesh.transform.localPosition = scale * new Vector3(-width / 2, -height / 2, -length / 2);

            //meshcolliders need to be added as components to properly initialize
            //so I can't put it in the prefab
            m_mesh.AddComponent <MeshCollider>();

            ProceduralDuplication.AddToDuplicate(m_mesh);
        }
        Debug.Log("Time take = " + (Time.realtimeSinceStartup - start) * 1000.0f);
    }