예제 #1
0
    protected override bool CalculateVoxel(Voxel voxel, int x, int y, int z)
    {
        float noiseValue = fractalNoise.Sample3D(offset.x + x / (float)width, y / (float)height, offset.y + z / (float)length);

        voxel.Data = noiseValue;
        return(true);
    }
예제 #2
0
    /*public override void NodeGUI ()
     * {
     *      GUILayout.BeginHorizontal();
     *      GUILayout.BeginVertical();
     *      xConnection.DisplayLayout ();
     *      yConnection.DisplayLayout ();
     *      zConnection.DisplayLayout ();
     *      GUILayout.EndVertical();
     *      outputConnection.DisplayLayout();
     *      GUILayout.EndHorizontal ();
     * }*/

    public override bool Calculate()
    {
        float x          = xConnection.GetValue <float>();
        float y          = yConnection.GetValue <float>();
        float z          = zConnection.GetValue <float>();
        float noiseValue = fractal.Sample3D(x, y, z);

        outputConnection.SetValue <float>(noiseValue);
        return(true);
    }
예제 #3
0
        private float[] GenerateFractalVoxels(int width, int height, int length)
        {
            INoise       perlin  = new PerlinNoise(seed, 2.0f);
            FractalNoise fractal = new FractalNoise(perlin, 3, .5f);

            float[] voxels = new float[width * height * length];
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    for (int z = 0; z < length; z++)
                    {
                        float fx = x / (width - 1f);
                        float fy = y / (height - 1f);
                        float fz = z / (length - 1f);

                        int idx = x + y * width + z * width * height;

                        voxels[idx] = fractal.Sample3D(fx, fy, fz);
                    }
                }
            }
            return(voxels);
        }
예제 #4
0
        void Start()
        {
            INoise       perlin  = new PerlinNoise(seed, 2.0f);
            FractalNoise fractal = new FractalNoise(perlin, 3, 1.0f);

            //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.
            Marching marching = null;

            if (mode == MARCHING_MODE.TETRAHEDRON)
            {
                marching = new MarchingTertrahedron();
            }
            else
            {
                marching = new MarchingCubes();
            }

            //Surface 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 where 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.
            marching.Surface = 0.0f;

            //The size of voxel array.
            int width  = 32;
            int height = 32;
            int length = 10;

            float[] voxels = new float[width * height * length];

            //Fill voxels with values. Im using perlin noise but any method to create voxels will work.
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    for (int z = 0; z < length; z++)
                    {
                        float fx = x / (width - 1.0f);
                        float fy = y / (height - 1.0f);
                        float fz = z / (length - 1.0f);

                        int idx = x + y * width + z * width * height;

                        voxels[idx] = fractal.Sample3D(fx, fy, fz);
                    }
                }
            }

            List <Vector3> verts   = new List <Vector3>();
            List <int>     indices = new List <int>();

            //The mesh produced is not optimal. There is one vert for each index.
            //Would need to weld vertices for better quality mesh.
            marching.Generate(voxels, width, height, length, verts, indices);

            //A mesh in unity can only be made up of 65000 verts.
            //Need to split the verts between multiple meshes.

            int maxVertsPerMesh = 30000; //must be divisible by 3, ie 3 verts == 1 triangle
            int numMeshes       = verts.Count / maxVertsPerMesh + 1;

            for (int i = 0; i < numMeshes; i++)
            {
                List <Vector3> splitVerts   = new List <Vector3>();
                List <int>     splitIndices = new List <int>();

                for (int j = 0; j < maxVertsPerMesh; j++)
                {
                    int idx = i * maxVertsPerMesh + j;

                    if (idx < verts.Count)
                    {
                        splitVerts.Add(verts[idx]);
                        splitIndices.Add(j);
                    }
                }

                if (splitVerts.Count == 0)
                {
                    continue;
                }

                Mesh mesh = new Mesh();
                mesh.SetVertices(splitVerts);
                mesh.SetTriangles(splitIndices, 0);
                mesh.RecalculateBounds();
                mesh.RecalculateNormals();

                GameObject go = new GameObject("Mesh");
                go.transform.parent = transform;
                go.AddComponent <MeshFilter>();
                go.AddComponent <MeshRenderer>();
                go.GetComponent <Renderer>().material = m_material;
                go.GetComponent <MeshFilter>().mesh   = mesh;
                go.transform.localPosition            = new Vector3(-width / 2, -height / 2, -length / 2);

                meshes.Add(go);
            }
        }
    public void InitialiseVoxels()
    {
        if (RockNoiseLayer)
        {
            RockNoiseLayer.Initialise();
        }
        if (DirtNoiseLayer)
        {
            DirtNoiseLayer.Initialise();
        }

        INoise       noise        = GetNoise(m_noiseType, 0, m_frequency, m_amplitude);
        FractalNoise fractalNoise = new FractalNoise(noise, m_octaves, m_frequency, m_amplitude);

        for (int x = 0; x < chunkSizeXZ; x++)
        {
            for (int z = 0; z < chunkSizeXZ; z++)
            {
                float bedrockHeight = 2;
                float rockHeight    = 0;
                float dirtHeight    = 0;
                //float sandHeight = 12;

                if (RockNoiseLayer)
                {
                    rockHeight += RockNoiseLayer.SampleValue(
                        x / (float)(m_worldResolution - 1),
                        z / (float)(m_worldResolution - 1)
                        );
                }

                if (DirtNoiseLayer)
                {
                    dirtHeight += DirtNoiseLayer.SampleValue(
                        x / (float)(m_worldResolution - 1),
                        z / (float)(m_worldResolution - 1)
                        );
                }

                for (int y = 0; y < chunkHeight; y++)
                {
                    Voxel v = voxelGrid[x, y, z];

                    if (x == 0 || x == chunkSizeXZ - 1 ||
                        y == 0 || y == chunkHeight - 1 ||
                        z == 0 || z == chunkSizeXZ - 1)
                    {
                        v.VoxelType = 0;
                        v.Value     = 0;
                    }
                    else
                    {
                        if (y <= bedrockHeight)
                        {
                            v.VoxelType = 1;
                        }
                        else if (y <= rockHeight)
                        {
                            v.VoxelType = 2;
                        }
                        else if (y <= dirtHeight)
                        {
                            v.VoxelType = 3;
                        }
                        //else if (y <= sandHeight)
                        //{
                        //	v.VoxelType = 4;
                        //}
                        else
                        {
                            v.VoxelType = 0;
                        }

                        float pointValue = fractalNoise.Sample3D(
                            x / (float)(m_worldResolution - 1),
                            y / (float)(m_worldResolution - 1),
                            z / (float)(m_worldResolution - 1)
                            );

                        v.Value = pointValue;
                    }
                }
            }
        }
    }
예제 #6
0
    void Generate()
    {
        DateTime startTime = System.DateTime.Now;

        INoise       perlin  = new PerlinNoise(seed, 2f);
        FractalNoise fractal = new FractalNoise(perlin, 3, 1f);

        MarchingCube marching = new MarchingCube();

        Marching.Surface = 0f;

        width  = sizeScale;
        height = sizeScale;
        length = sizeScale;

        float[] voxels = new float[width * height * length];

        //Fill voxels with values. Im using perlin noise but any method to create voxels will work.
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                for (int z = 0; z < length; z++)
                {
                    float fx = x / (width - 1.0f);
                    float fy = y / (height - 1.0f);
                    float fz = z / (length - 1.0f);

                    int idx = x + y * width + z * width * height;

                    voxels[idx] = fractal.Sample3D(fx, fy, fz);
                }
            }
        }

        verts   = new List <Vector3>();
        indices = new List <int>();


        if (useJobSystem)
        {
            MarchingCubeParallel          marching_p = new MarchingCubeParallel(0);
            MarchingCubeParallel.MarchJob job;
            JobHandle handle = marching_p.Generate(new List <float>(voxels), width, height, length, out job);
            StartCoroutine(Wait4Complete(handle, job));
        }
        else
        {
            marching.Generate(voxels, width, height, length, verts, indices);
            int maxVertsPerMesh = 30000; //must be divisible by 3, ie 3 verts == 1 triangle
            int numMeshes       = verts.Count / maxVertsPerMesh + 1;
            for (int i = 0; i < numMeshes; i++)
            {
                List <Vector3> splitVerts   = new List <Vector3>();
                List <int>     splitIndices = new List <int>();

                for (int j = 0; j < maxVertsPerMesh; j++)
                {
                    int idx = i * maxVertsPerMesh + j;

                    if (idx < verts.Count)
                    {
                        splitVerts.Add(verts[idx]);
                        splitIndices.Add(j);
                    }
                }

                if (splitVerts.Count == 0)
                {
                    continue;
                }

                Mesh mesh = new Mesh();
                mesh.SetVertices(splitVerts);
                mesh.SetTriangles(splitIndices, 0);
                mesh.RecalculateBounds();
                mesh.RecalculateNormals();

                GameObject go = new GameObject("Mesh");
                go.transform.parent = transform;
                go.AddComponent <MeshFilter>();
                go.AddComponent <MeshRenderer>();
                go.GetComponent <Renderer>().material = m_material;
                go.GetComponent <MeshFilter>().mesh   = mesh;
                go.transform.localPosition            = new Vector3(-width / 2, -height / 2, -length / 2);

                meshes.Add(go);
            }
        }
        double timeCost = System.DateTime.Now.Subtract(startTime).TotalMilliseconds;

        print("Time Cost : " + timeCost + " at size " + (8 * sizeScale));
    }
예제 #7
0
        void Start()
        {
            INoise       perlin  = new PerlinNoise(seed, 2.0f);
            FractalNoise fractal = new FractalNoise(perlin, 3, 1.0f);

            //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.
            Marching marching = null;

            if (mode == MARCHING_MODE.TETRAHEDRON)
            {
                marching = new MarchingTertrahedron();
            }
            else
            {
                marching = new MarchingCubes();
            }

            //Surface 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 where 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.
            marching.Surface = 0.0f;

            //The size of voxel array.
            int width  = 32;
            int height = 32;
            int length = 32;

            float[] voxels = new float[width * height * length];

            //Fill voxels with values. Im using perlin noise but any method to create voxels will work.
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    for (int z = 0; z < length; z++)
                    {
                        float fx = x / (width - 1.0f);
                        float fy = y / (height - 1.0f);
                        float fz = z / (length - 1.0f);

                        int idx = x + y * width + z * width * height;

                        voxels[idx] = fractal.Sample3D(fx, fy, fz);
                    }
                }
            }

            List <Vector3> verts   = new List <Vector3>();
            List <int>     indices = new List <int>();

            System.Diagnostics.Stopwatch measure = new System.Diagnostics.Stopwatch();
            measure.Start();

            marching.Generate(voxels, width, height, length, verts, indices);

            verts = MeshUtils.WeldVertices(verts, indices);

            measure.Stop();

            Debug.Log(string.Format("Time elapsed: {0}", measure.Elapsed));

            Mesh mesh = new Mesh();

            mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
            mesh.SetVertices(verts);
            mesh.SetTriangles(indices, 0);
            mesh.RecalculateBounds();
            mesh.RecalculateNormals();

            GameObject go = new GameObject("Mesh");

            go.transform.parent = transform;
            go.AddComponent <MeshFilter>();
            go.AddComponent <MeshRenderer>();
            go.GetComponent <Renderer>().material = m_material;
            go.GetComponent <MeshFilter>().mesh   = mesh;
            go.transform.localPosition            = new Vector3(-width / 2, -height / 2, -length / 2);
        }