Ejemplo n.º 1
0
    public static void GenerateMeshForChunks(List <Chunk> chunksToProcess)
    {
        List <JobData <MarchingCubeJob> > jobDataList = new List <JobData <MarchingCubeJob> >();

        foreach (Chunk chunk in chunksToProcess)
        {
            MarchingCubeJob job = new MarchingCubeJob()
            {
                counter    = new NativeCounter(Allocator.TempJob),
                voxelData  = new NativeArray <VoxelData>(voxelData[chunk.id], Allocator.TempJob),
                vertexData = new NativeArray <VertexData>(voxelData[chunk.id].Length * 15, Allocator.TempJob),
                triangles  = new NativeArray <ushort>(voxelData[chunk.id].Length * 15, Allocator.TempJob)
            };
            jobDataList.Add(new JobData <MarchingCubeJob>(job, job.Schedule()));
        }
        for (int i = 0; i < chunksToProcess.Count; i++)
        {
            Chunk chunk = chunksToProcess[i];
            JobData <MarchingCubeJob> jobData = jobDataList[i];

            jobData.handle.Complete();
            chunk.SetMeshData(jobData.job.counter.Count * 3, jobData.job.vertexData, jobData.job.triangles);
            jobData.job.Dispose();

            chunk.workState.Next();
            chunk.workState.Next();
        }
    }
    private void CreateOctree()
    {
        int maxSize = Mathf.RoundToInt(Mathf.Pow(2, maxHierarchyIndex)) + 3;

        //Make native containers
        NativeList <Octree> octrees      = new NativeList <Octree>(Allocator.TempJob);
        NativeList <Octree> totalOctrees = new NativeList <Octree>(Allocator.TempJob);
        NativeArray <float> densities    = new NativeArray <float>(maxSize * maxSize * maxSize, Allocator.TempJob);
        //Mesh native containers
        NativeList <Vector3> vertices     = new NativeList <Vector3>(Allocator.TempJob);
        NativeList <int>     triangles    = new NativeList <int>(Allocator.TempJob);
        NativeList <Color>   vertexColors = new NativeList <Color>(Allocator.TempJob);
        Stopwatch            stopwatch    = new Stopwatch();

        stopwatch.Start();
        //Create the jobs and execute them
        DensityJob densityJob = new DensityJob
        {
            densities = densities,
            maxSize   = maxSize,
            data      = data
        };

        densityJob.Run(maxSize * maxSize * maxSize);
        OctreeJob octreeJob = new OctreeJob
        {
            maxHierarchyIndex    = maxHierarchyIndex,
            isoThreshold         = isoThreshold,
            isoObstacleThreshold = isoObstacleThreshold,
            voxels       = densities,
            finalOctrees = octrees,
            totalOctrees = totalOctrees
        };

        octreeJob.Run();
        MarchingCubeJob mcJob = new MarchingCubeJob
        {
            octrees      = octrees,
            vertices     = vertices,
            vertexColors = vertexColors,
            triangles    = triangles,
            densities    = densities,
            isoThreshold = isoThreshold,
            gridSize     = new int3(maxSize, maxSize, maxSize)
        };

        mcJob.Run();
        //Gizmo draw
        if (drawGizmos)
        {
            foreach (var octree in totalOctrees)
            {
                Gizmos.color = Color.Lerp(Color.black, Color.white, (float)octree.hierarchyIndex / (float)maxHierarchyIndex);
                Gizmos.DrawWireCube(math.float3(new float3(octree.position) + ((float)octree.size / 2f)), new Vector3(octree.size, octree.size, octree.size));
            }

            Octree     currentOctree = totalOctrees[octreeIndexTest];
            List <int> neighbours    = FindNeighbours(totalOctrees, octreeIndexTest);

            foreach (var item in neighbours)
            {
                Octree octreeNeighbour = totalOctrees[item];
                Gizmos.color = Color.red;
                Gizmos.DrawWireCube(octreeNeighbour.center, new Vector3(octreeNeighbour.size, octreeNeighbour.size, octreeNeighbour.size));
            }
            Gizmos.color = Color.blue;
            Gizmos.DrawWireCube(currentOctree.center, new Vector3(currentOctree.size, currentOctree.size, currentOctree.size));
        }

        Mesh mesh = new Mesh()
        {
            vertices = vertices.ToArray(), colors = vertexColors.ToArray(), triangles = triangles.ToArray()
        };

        mesh.Optimize();
        mesh.RecalculateNormals();
        GetComponent <MeshFilter>().mesh         = mesh;
        GetComponent <MeshCollider>().sharedMesh = mesh;

        //Release the native containers from the memory
        vertices.Dispose();
        triangles.Dispose();
        octrees.Dispose();
        densities.Dispose();

        UnityEngine.Debug.Log("Final: " + stopwatch.ElapsedMilliseconds);
        stopwatch.Stop();
    }
Ejemplo n.º 3
0
    //Generates the MarchingCube mesh
    public void GenerateMesh(TerrainGenerationData _terrainGenerationData, TerrainColorData _terrainColorData, Vector3Int chunkPos, TerrainGenerator _terrain, int[] _triTable, float3[] _edgeTable, float3[] _edgeTable2, int LOD = 0, bool resetMesh = true, bool immediate = false)
    {
        Stopwatch stopwatch = new Stopwatch();

        stopwatch.Start();
        if (resetMesh)
        {
            GetComponent <MeshFilter>().sharedMesh = new Mesh();
        }
        completed             = false;
        terrainGenerationData = _terrainGenerationData;
        terrainColorData      = _terrainColorData;
        terrain       = _terrain;
        chunkPosition = chunkPos;
        int resolution = terrainGenerationData.resolution - LOD;

        voxels         = new NativeArray <float>((resolution + 2) * (resolution + 2) * (resolution + 2), Allocator.Persistent);
        vertices       = new NativeArray <float3>(12 * resolution * resolution * resolution, Allocator.Persistent);
        finalVertices  = new NativeList <Vector3>(Allocator.Persistent);
        triangles      = new NativeArray <int>(16 * resolution * resolution * resolution, Allocator.Persistent);
        finalTriangles = new NativeList <int>(Allocator.Persistent);
        colors         = new NativeArray <Color>(12 * resolution * resolution * resolution, Allocator.Persistent);
        finalColors    = new NativeList <Color>(Allocator.Persistent);
        triTable       = new NativeArray <int>(_triTable.Length, Allocator.Persistent);
        edgeTable      = new NativeArray <float3>(12, Allocator.Persistent);
        edgeTable2     = new NativeArray <float3>(12, Allocator.Persistent);
        edgeTable.CopyFrom(_edgeTable);
        edgeTable2.CopyFrom(_edgeTable2);
        triTable.CopyFrom(_triTable);
        if (_terrainGenerationData.usePregeneratedVoxelData)
        {
            MarchingCubeVoxelJob voxelJob = new MarchingCubeVoxelJob()
            {
                voxels                = voxels,
                chunkPosition         = new float3(chunkPosition.x * 10, chunkPosition.y * 10, chunkPosition.z * 10),
                scale                 = (float)10 / (float)resolution,
                resolution            = resolution + 2,
                terrainGenerationData = _terrainGenerationData
            };
            voxelHandle = voxelJob.Schedule((resolution + 2) * (resolution + 2) * (resolution + 2), 64);
        }
        MarchingCubeJob job = new MarchingCubeJob()
        {
            edgeTable             = edgeTable,
            edgeTable2            = edgeTable2,
            scale                 = (float)10 / (float)resolution,
            LOD                   = LOD,
            voxels                = voxels,
            resolution            = resolution,
            triangulationTable    = triTable,
            chunkPosition         = new float3(chunkPosition.x * 10, chunkPosition.y * 10, chunkPosition.z * 10),
            vertices              = vertices,
            triangles             = triangles,
            colors                = colors,
            terrainGenerationData = _terrainGenerationData,
            terrainColorData      = _terrainColorData
        };

        if (_terrainGenerationData.usePregeneratedVoxelData)
        {
            jobHandle = job.Schedule(resolution * resolution * resolution, 64, voxelHandle);
        }
        else
        {
            jobHandle = job.Schedule(resolution * resolution * resolution, 64);
        }


        MarchingCubeOptimizeJob optimize = new MarchingCubeOptimizeJob()
        {
            vertices       = vertices,
            finalVertices  = finalVertices,
            triangles      = triangles,
            finalTriangles = finalTriangles,
            colors         = colors,
            finalColors    = finalColors
        };

        optimizeHandle = optimize.Schedule(jobHandle);

        if (immediate)
        {
            CompleteChunkJob();
            stopwatch.Stop();
            UnityEngine.Debug.Log(stopwatch.ElapsedMilliseconds);
        }
    }