示例#1
0
 public ChannelPropagator(VoxelLightPropagator propagator, VoxelLightChannel channel)
 {
     Propagator   = propagator;
     Volume       = propagator.Volume;
     Channel      = channel;
     _propQueue   = new ConcurrentQueue <PropNode>();
     _depropQueue = new ConcurrentQueue <DepropNode>();
 }
        protected override void Process()
        {
            Input.Wait();
            var propagator = new VoxelLightPropagator(Volume);

            Parallel.For(0, 7, (i) => {
                if (i < 6)
                {
                    CalculateSunlight(Volume, i, propagator[i]);
                }
                else
                {
                    CalculatePoint(Volume, propagator[i]);
                }
            });
        }
示例#3
0
 public PointChannelPropagator(VoxelLightPropagator propagator)
     : base(propagator, VoxelLightChannel.Point)
 {
 }
示例#4
0
 public SunChannelPropagator(VoxelLightPropagator propagator, VoxelLightChannel channel)
     : base(propagator, channel)
 {
 }
        unsafe void WorkerThread()
        {
            var requests       = new Stack <VoxelChangeRequest>();
            var chunksToRemesh = new HashSet <VoxelChunk>();
            var propagator     = new VoxelLightPropagator(Volume);

            while (!_abortRequested)
            {
                _changeRequested.WaitOne();
                while (_changeRequests.TryDequeue(out var request))
                {
                    requests.Push(request);
                }
                while (requests.TryPop(out var request))
                {
                    var chunkCoords = Volume.GlobalToChunkCoords(request.Coords);
                    var chunk       = Volume[chunkCoords];
                    if (chunk != null)
                    {
                        var localCoords    = chunk.VolumeToLocalCoords(request.Coords);
                        var oldOpacity     = chunk.Voxels[localCoords].IsOpaque;
                        var voxel          = request.Voxel;
                        var newOpacity     = voxel.IsOpaque;
                        var pointLight     = chunk.LightData[VoxelLightChannel.Point][localCoords];
                        var typePointLight = voxel.PointLightLevel;
                        if (typePointLight > *pointLight)
                        {
                            propagator.PointPropagationChannel.QueueForPropagation(chunk, localCoords, typePointLight);
                        }
                        if (voxel.IsEmpty)
                        {
                            propagator.PointPropagationChannel.QueueForDepropagation(chunk, localCoords);
                        }
                        if (oldOpacity != newOpacity)
                        {
                            if (newOpacity)
                            {
                                propagator.QueueForDepropagation(chunk, localCoords);
                            }
                            else
                            {
                                propagator.QueueNeighborsForPropagation(chunk, localCoords);
                            }
                        }
                        chunk.Voxels[localCoords] = voxel;
                        chunksToRemesh.Add(chunk);
                        if (localCoords.X == 0)
                        {
                            var neighbor = Volume[chunk.Coords + new Coords(-1, 0, 0)];
                            if (neighbor is VoxelChunk neighborChunk)
                            {
                                chunksToRemesh.Add(neighborChunk);
                            }
                        }
                        else if (localCoords.X == VoxelChunk.SIZE - 1)
                        {
                            var neighbor = Volume[chunk.Coords + new Coords(1, 0, 0)];
                            if (neighbor is VoxelChunk neighborChunk)
                            {
                                chunksToRemesh.Add(neighborChunk);
                            }
                        }
                        if (localCoords.Y == 0)
                        {
                            var neighbor = Volume[chunk.Coords + new Coords(0, -1, 0)];
                            if (neighbor is VoxelChunk neighborChunk)
                            {
                                chunksToRemesh.Add(neighborChunk);
                            }
                        }
                        else if (localCoords.Y == VoxelChunk.SIZE - 1)
                        {
                            var neighbor = Volume[chunk.Coords + new Coords(0, 1, 0)];
                            if (neighbor is VoxelChunk neighborChunk)
                            {
                                chunksToRemesh.Add(neighborChunk);
                            }
                        }
                        if (localCoords.Z == 0)
                        {
                            var neighbor = Volume[chunk.Coords + new Coords(0, 0, -1)];
                            if (neighbor is VoxelChunk neighborChunk)
                            {
                                chunksToRemesh.Add(neighborChunk);
                            }
                        }
                        else if (localCoords.Z == VoxelChunk.SIZE - 1)
                        {
                            var neighbor = Volume[chunk.Coords + new Coords(0, 0, 1)];
                            if (neighbor is VoxelChunk neighborChunk)
                            {
                                chunksToRemesh.Add(neighborChunk);
                            }
                        }
                    }
                }
                propagator.StartPropagationTask();
                List <VoxelChunkMesh> meshes = null;
                if (chunksToRemesh.Count <= _multipleMeshThreshold)
                {
                    meshes = new List <VoxelChunkMesh>();
                }
                Parallel.ForEach(chunksToRemesh, (chunk) => {
                    var mesh = chunk.Mesh ?? new VoxelChunkMesh(chunk);
                    mesh.GenerateGeometryAndLighting();
                    if (meshes != null)
                    {
                        meshes.Add(mesh);
                    }
                    else
                    {
                        _singleMeshes.Enqueue(mesh);
                    }
                });
                if (meshes != null)
                {
                    _multipleMeshes.Enqueue(meshes);
                }
                propagator.Wait();
                Parallel.ForEach(propagator.AlteredChunks, (chunk) => {
                    var mesh = chunk.Mesh;
                    mesh.GenerateLighting();
                    _singleMeshes.Enqueue(mesh);
                });
                propagator.Clear();
                chunksToRemesh.Clear();
            }
        }