Example #1
0
 public LightJobData(int3 chunkId, int3 chunkWorldPos, int3 dimensions, NativeArray <VoxelTypeID> voxels, NativeArray <LightValue> lights, NeighbourData neighbourData, NativeArray <bool> directionsValid, NativeArray <int> voxelTypeToEmissionMap, NativeArray <int> voxelTypeToAbsorptionMap, NativeArray <int3> directionVectors)
 {
     this.chunkId                  = chunkId;
     this.chunkWorldPos            = chunkWorldPos;
     this.dimensions               = dimensions;
     this.voxels                   = voxels;
     this.lights                   = lights;
     this.neighbourData            = neighbourData;
     this.directionsValid          = directionsValid;
     this.voxelTypeToEmissionMap   = voxelTypeToEmissionMap;
     this.voxelTypeToAbsorptionMap = voxelTypeToAbsorptionMap;
     this.directionVectors         = directionVectors;
 }
        public AbstractPipelineJob <MeshDescriptor> CreateMeshJob(Vector3Int chunkID)
        {
            Profiler.BeginSample("CreateMeshJob");

            var chunkDimensions = chunkManager.ChunkDimensions;

            var chunkData = chunkManager.GetReadOnlyChunkData(chunkID);

            //Copy chunk data to native array
            Profiler.BeginSample("VoxelsToNative");
            NativeArray <VoxelTypeID> voxels = chunkData.ToNative();

            Profiler.EndSample();


            NeighbourData neighbourData = new NeighbourData();

            //Cache neighbour data
            neighbourData = JobUtils.CacheNeighbourData(chunkID, chunkManager);


            var meshingJob = createMeshingJob(new MeshJobData(chunkDimensions.ToNative(),
                                                              chunkManager.IncludeLighting,
                                                              voxels,
                                                              chunkData.NativeRotations(),
                                                              chunkData.LightToNative(),
                                                              neighbourData,
                                                              voxelTypeManager.nativeMeshDatabase,
                                                              voxelTypeManager.nativeVoxelTypeDatabase,
                                                              Allocator.Persistent
                                                              ));


            var indexingWrapper = new JobWrapper <SortIndicesByMaterialJob>();

            //AsDeferredJobArray takes the length etc at the time of execution, rather than now.
            indexingWrapper.job.allTriangleIndices             = meshingJob.data.allTriangleIndices.AsDeferredJobArray();
            indexingWrapper.job.materialRuns                   = meshingJob.data.materialRuns.AsDeferredJobArray();
            indexingWrapper.job.packedRuns                     = new NativeList <MaterialRun>(Allocator.Persistent);
            indexingWrapper.job.packedIndices                  = new NativeList <int>(Allocator.Persistent);
            indexingWrapper.job.collisionMeshMaterialRunLength = meshingJob.data.collisionSubmesh.collisionMeshMaterialRunLength;


            Func <MeshDescriptor> cleanup = () =>
            {
                Profiler.BeginSample("MeshJobCleanup");
                Mesh mesh = new Mesh();

                if (meshingJob.data.vertices.Length >= ushort.MaxValue)
                {
                    //Cope with bigger meshes
                    mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
                }

                mesh.vertices = meshingJob.data.vertices.ToArray();
                if (meshingJob.data.includeLighting)
                {
                    mesh.colors = meshingJob.data.vertexColours.ToArray();
                }
                mesh.SetUVs(0, meshingJob.data.uvs.ToArray());
                mesh.normals = meshingJob.data.normals.ToArray();

                mesh.subMeshCount = indexingWrapper.job.packedRuns.Length;

                MeshDescriptor meshDescriptor = new MeshDescriptor();
                meshDescriptor.materialsBySubmesh = new Material[mesh.subMeshCount];

                for (int i = 0; i < indexingWrapper.job.packedRuns.Length; i++)
                {
                    var run   = indexingWrapper.job.packedRuns[i];
                    var slice = new NativeSlice <int>(indexingWrapper.job.packedIndices, run.range.start, run.range.Length);
                    mesh.SetTriangles(slice.ToArray(), i);
                    meshDescriptor.materialsBySubmesh[i] = voxelTypeManager.GetMaterial(run.materialID);
                }

                meshDescriptor.mesh = mesh;
                meshDescriptor.collidableLengthVertices = meshingJob.data.collisionSubmesh.collisionMeshLengthVertices[0];
                meshDescriptor.collidableLengthIndices  = meshingJob.data.collisionSubmesh.collisionMeshLengthTriangleIndices[0];

                //Disposal
                meshingJob.Dispose();

                //Dispose of packed containers
                indexingWrapper.job.packedIndices.Dispose();
                indexingWrapper.job.packedRuns.Dispose();

                Profiler.EndSample();

                return(meshDescriptor);
            };

            Profiler.EndSample();


            //Single threaded version
            if (!Parrallel)
            {
                return(new BasicFunctionJob <MeshDescriptor>(() =>
                {
                    meshingJob.Run();
                    indexingWrapper.Run();
                    return cleanup();
                }));
            }

            var meshingHandle = meshingJob.Schedule();
            var handle        = indexingWrapper.Schedule(meshingHandle);

            return(new PipelineUnityJob <MeshDescriptor>(handle, cleanup));
        }