public void Edit <T>(IAssetData asset) { Log.T($"Editing {asset.AssetName}.", _isDebugging); // Expand the base tilesheet if needed. var src = ModEntry.Instance.Helper.Content.Load <Texture2D>(ModValues.MachinePath); var dest = asset.AsImage(); var srcRect = new Rectangle(0, 0, 16, 32); var destRect = Propagator.getSourceRectForBigCraftable(ModValues.PropagatorIndex); if (destRect.Bottom > dest.Data.Height) { Log.D("Expanding bigCraftables tilesheet.", _isDebugging); var original = dest.Data; var texture = new Texture2D(Game1.graphics.GraphicsDevice, original.Width, destRect.Bottom); Log.D($"Original: {original.Width}x{original.Height}" + $"\nExpanded: {texture.Width}x{texture.Height}", _isDebugging); dest.ReplaceWith(texture); dest.PatchImage(original); } // Append machine sprite onto the default tilesheet. dest.PatchImage(src, srcRect, destRect); }
private void CreateCrack(double elementSize, XModel model, BidirectionalMesh2D <XNode, XContinuumElement2D> mesh, double jIntegralRadiusRatio) { var propagator = new Propagator(mesh, jIntegralRadiusRatio, new HomogeneousMaterialAuxiliaryStates(material), new HomogeneousSIFCalculator(material), new MaximumCircumferentialTensileStressCriterion(), new ConstantIncrement2D(1.5 * jIntegralRadiusRatio * elementSize)); var crack = new TrackingExteriorCrackLSM(propagator); crack.Mesh = mesh; // Create enrichments crack.CrackBodyEnrichment = new CrackBodyEnrichment2D(crack, new SignFunctionOpposite2D()); crack.CrackTipEnrichments = new CrackTipEnrichments2D(crack, CrackTipPosition.Single); //crackTip = new CrackTip2D(CrackTip2D.TipCurvePosition.CurveStart, polyline, new SingleElementEnrichment(), // 2.0, new HomogeneousMaterialAuxiliaryStates(globalHomogeneousMaterial), // new HomogeneousSIFCalculator(globalHomogeneousMaterial)); // Mesh geometry interaction var crackMouth = new CartesianPoint(beamLength, 0.5 * beamHeight); var crackTip = new CartesianPoint(0.5 * beamLength, 0.5 * beamHeight); crack.InitializeGeometry(crackMouth, crackTip); crack.UpdateEnrichments(); //TODO: elements are not enriched properly. this.Crack = crack; this.Propagator = propagator; }
/// <summary> /// Constructs a join propagator. /// </summary> /// <param name="left">Result of propagating changes in the left input to the join</param> /// <param name="right">Result of propagating changes in the right input to the join</param> /// <param name="node">Join operator in update mapping view over which to propagate changes</param> /// <param name="parent">Handler of propagation for the entire update mapping view</param> internal JoinPropagator(ChangeNode left, ChangeNode right, DbJoinExpression node, Propagator parent) { EntityUtil.CheckArgumentNull(left, "left"); EntityUtil.CheckArgumentNull(right, "right"); EntityUtil.CheckArgumentNull(node, "node"); EntityUtil.CheckArgumentNull(parent, "parent"); m_left = left; m_right = right; m_joinExpression = node; m_parent = parent; Debug.Assert(DbExpressionKind.LeftOuterJoin == node.ExpressionKind || DbExpressionKind.InnerJoin == node.ExpressionKind, "(Update/JoinPropagagtor/JoinEvaluator) " + "caller must ensure only left outer and inner joins are requested"); // Retrieve propagation rules for the join type of the expression. if (DbExpressionKind.InnerJoin == m_joinExpression.ExpressionKind) { m_insertRules = s_innerJoinInsertRules; m_deleteRules = s_innerJoinDeleteRules; } else { m_insertRules = s_leftOuterJoinInsertRules; m_deleteRules = s_leftOuterJoinDeleteRules; } // Figure out key selectors involved in the equi-join (if it isn't an equi-join, we don't support it) JoinConditionVisitor.GetKeySelectors(node.JoinCondition, out m_leftKeySelectors, out m_rightKeySelectors); // Find the key selector expressions in the left and right placeholders m_leftPlaceholderKey = ExtractKey(m_left.Placeholder, m_leftKeySelectors, m_parent); m_rightPlaceholderKey = ExtractKey(m_right.Placeholder, m_rightKeySelectors, m_parent); }
private void InitializeCrack() { var globalHomogeneousMaterial = HomogeneousElasticMaterial2D.CreateMaterialForPlaneStrain(E, v); IPropagator propagator = new Propagator(mesh, jIntegralRadiusOverElementSize, new HomogeneousMaterialAuxiliaryStates(globalHomogeneousMaterial), new HomogeneousSIFCalculator(globalHomogeneousMaterial), new MaximumCircumferentialTensileStressCriterion(), new ConstantIncrement2D(growthLength)); CrackMouth = new CartesianPoint(0.0, h / 2); var crackKink = new CartesianPoint(a, h / 2); var initialCrack = new PolyLine2D(CrackMouth, crackKink); initialCrack.UpdateGeometry(-dTheta, da); //var crackTip = new CartesianPoint(a + da * Math.Cos(dTheta), h/2 - da * Math.Sin(dTheta)); var lsmCrack = new TrackingExteriorCrackLSM(propagator, tipEnrichmentRadius, new RelativeAreaResolver(heavisideTol)); lsmCrack.Mesh = mesh; // Create enrichments lsmCrack.CrackBodyEnrichment = new CrackBodyEnrichment2D(lsmCrack); lsmCrack.CrackTipEnrichments = new CrackTipEnrichments2D(lsmCrack, CrackTipPosition.Single); if (lsmPlotDirectory != null) { lsmCrack.EnrichmentLogger = new EnrichmentLogger(Model, lsmCrack, lsmPlotDirectory); lsmCrack.LevelSetLogger = new LevelSetLogger(Model, lsmCrack, lsmPlotDirectory); lsmCrack.LevelSetComparer = new PreviousLevelSetComparer(lsmCrack, lsmPlotDirectory); } // Mesh geometry interaction lsmCrack.InitializeGeometry(initialCrack); //lsmCrack.UpdateGeometry(-dTheta, da); this.crack = lsmCrack; }
public override async Task Start(CancellationToken token) { if (Propagator != null && !Propagator.Completion.IsCompleted) { throw new Exception("You must call Stop method first, as the previous run is still pending"); } StartBuffering(); var feederTask = Task.Run(async() => { while (true) { if (token.IsCancellationRequested) { break; } if (!InternalBuffer.TryTake(out var item)) { Thread.Sleep(2000); continue; } _itemAvailableEvent.Set(); await Propagator.SendAsync(item, token); } }, token); await base.Start(token); }
public void PropagateTest() { var propagator = new Propagator(Propagator.DefaultNeighborsGetter); var context = new WaterContext(_map, propagator); var drop = new WaterDrop(0.1); context.AddDrop(drop, (2, 2)); context.PropagateWater(WaterContext.DefaultNeighborsGetter); var drops = context.Drops; Assert.Equal(4, drops.Count); }
public void MergeTest() { var propagator = new Propagator(Propagator.DefaultNeighborsGetter); var context = new WaterContext(_map, propagator); var drop = new WaterDrop(0.1); context.AddDrop(drop, (2, 2)); context.PropagateWater(WaterContext.DefaultNeighborsGetter); context.PropagateWater(WaterContext.DefaultNeighborsGetter); var dropsBefore = context.Drops.ToDictionary(x => x.Key, x => x.Value); context.Merge(); var dropsAfter = context.Drops.ToDictionary(x => x.Key, x => x.Value); Assert.Equal(16, dropsBefore.Count); Assert.Equal(9, dropsAfter.Count); }
internal void Run2(Action <string> action) { Resolution status = Propagator.Status; for (var retry = 0; retry < 5; retry++) { if (retry != 0) { status = Propagator.Clear(); } //if (status == Resolution.Contradiction) //{ // System.Console.WriteLine($"Found contradiction in initial conditions, retrying"); // continue; //} //if (config.Animate) if (true) { status = RunAnimate(Model, Propagator, Dest, SampleSet.ExportOptions, action); } else { status = Run(Propagator); } if (status == Resolution.Contradiction) { System.Console.WriteLine($"Found contradiction, retrying"); continue; } break; } Directory.CreateDirectory(Path.GetDirectoryName(Dest)); if (status == Resolution.Decided) { System.Console.WriteLine($"Writing {Dest}"); Exporter.Export(Model, Propagator, Dest, config, SampleSet.ExportOptions); File.Delete(Contdest); } else { System.Console.WriteLine($"Writing {Contdest}"); Exporter.Export(Model, Propagator, Contdest, config, SampleSet.ExportOptions); File.Delete(Dest); } }
private void CreatePropagator(UtilityNetworkDefinition utilityNetworkDefinition, TraceConfiguration traceConfiguration) { const int ABCPhase = 7; #region Create a Propagator // Get a NetworkAttribute object for the Phases Normal attribute from the UtilityNetworkDefinition using (NetworkAttribute normalPhaseAttribute = utilityNetworkDefinition.GetNetworkAttribute("Phases Normal")) { // Create a propagator to propagate the Phases Normal attribute downstream from the source, using a Bitwise And function // Allow traversal to continue as long as the Phases Normal value includes any of the ABC phases // (represented by the constant ABCPhase) Propagator phasePropagator = new Propagator(normalPhaseAttribute, PropagatorFunction.BitwiseAnd, Operator.IncludesAny, ABCPhase); // Assign this propagator to our trace configuration traceConfiguration.Propagators = new List <Propagator>() { phasePropagator }; } #endregion }
private void InitializeCrack() { IPropagator propagator; if (!writePropagation) { propagator = new FixedPropagator(propagationPath, null); } else { propagator = new Propagator(mesh, jIntegralRadiusOverElementSize, new HomogeneousMaterialAuxiliaryStates(globalHomogeneousMaterial), new HomogeneousSIFCalculator(globalHomogeneousMaterial), new MaximumCircumferentialTensileStressCriterion(), new ConstantIncrement2D(growthLength)); } var crackMouth = new CartesianPoint(webLeft, crackHeight); var crackTip = new CartesianPoint(webLeft + crackLength, crackHeight); var initialCrack = new PolyLine2D(crackMouth, crackTip); var lsmCrack = new TrackingExteriorCrackLSM(propagator, 0.0, new RelativeAreaResolver(heavisideTol)); lsmCrack.Mesh = mesh; // Create enrichments lsmCrack.CrackBodyEnrichment = new CrackBodyEnrichment2D(lsmCrack); lsmCrack.CrackTipEnrichments = new CrackTipEnrichments2D(lsmCrack, CrackTipPosition.Single); if (lsmPlotDirectory != null) { lsmCrack.EnrichmentLogger = new EnrichmentLogger(Model, lsmCrack, lsmPlotDirectory); lsmCrack.LevelSetLogger = new LevelSetLogger(Model, lsmCrack, lsmPlotDirectory); lsmCrack.LevelSetComparer = new PreviousLevelSetComparer(lsmCrack, lsmPlotDirectory); } // Mesh geometry interaction lsmCrack.InitializeGeometry(initialCrack); this.crack = lsmCrack; }
public static bool Go(Voxel voxel, Voxel.Coord center, int radius, Action <List <DynamicVoxel> > callback = null) { if (!voxel[center].Permanent) { // Break off a chunk of this voxel into a new DynamicMap. List <Voxel.Coord> edges = new List <Voxel.Coord>(); Voxel.Coord ripStart = center.Move(-radius, -radius, -radius); Voxel.Coord ripEnd = center.Move(radius, radius, radius); Dictionary <Voxel.Box, bool> permanentBoxes = new Dictionary <Voxel.Box, bool>(); foreach (Voxel.Coord c in ripStart.CoordinatesBetween(ripEnd)) { Voxel.Box box = voxel.GetBox(c); if (box != null && box.Type.Permanent) { permanentBoxes[box] = true; } } foreach (Voxel.Box b in permanentBoxes.Keys) { // Top and bottom for (int x = b.X - 1; x <= b.X + b.Width; x++) { for (int z = b.Z - 1; z <= b.Z + b.Depth; z++) { Voxel.Coord coord = new Voxel.Coord { X = x, Y = b.Y + b.Height, Z = z }; if (coord.Between(ripStart, ripEnd)) { edges.Add(coord); } coord = new Voxel.Coord { X = x, Y = b.Y - 1, Z = z }; if (coord.Between(ripStart, ripEnd)) { edges.Add(coord); } } } // Outer shell for (int y = b.Y; y < b.Y + b.Height; y++) { // Left and right for (int z = b.Z - 1; z <= b.Z + b.Depth; z++) { Voxel.Coord coord = new Voxel.Coord { X = b.X - 1, Y = y, Z = z }; if (coord.Between(ripStart, ripEnd)) { edges.Add(coord); } coord = new Voxel.Coord { X = b.X + b.Width, Y = y, Z = z }; if (coord.Between(ripStart, ripEnd)) { edges.Add(coord); } } // Backward and forward for (int x = b.X; x < b.X + b.Width; x++) { Voxel.Coord coord = new Voxel.Coord { X = x, Y = y, Z = b.Z - 1 }; if (coord.Between(ripStart, ripEnd)) { edges.Add(coord); } coord = new Voxel.Coord { X = x, Y = y, Z = b.Z + b.Depth }; if (coord.Between(ripStart, ripEnd)) { edges.Add(coord); } } } } if (edges.Contains(center)) { return(false); } // Top and bottom for (int x = ripStart.X; x <= ripEnd.X; x++) { for (int z = ripStart.Z; z <= ripEnd.Z; z++) { Voxel.Coord c = new Voxel.Coord { X = x, Y = ripStart.Y, Z = z }; Voxel.State s = voxel[c]; if (s != Voxel.States.Empty && !s.Permanent) { edges.Add(c); } c = new Voxel.Coord { X = x, Y = ripEnd.Y, Z = z }; s = voxel[c]; if (s != Voxel.States.Empty && !s.Permanent) { edges.Add(c); } } } // Sides for (int y = ripStart.Y + 1; y <= ripEnd.Y - 1; y++) { // Left and right for (int z = ripStart.Z; z <= ripEnd.Z; z++) { Voxel.Coord c = new Voxel.Coord { X = ripStart.X, Y = y, Z = z }; Voxel.State s = voxel[c]; if (s != Voxel.States.Empty && !s.Permanent) { edges.Add(c); } c = new Voxel.Coord { X = ripEnd.X, Y = y, Z = z }; s = voxel[c]; if (s != Voxel.States.Empty && !s.Permanent) { edges.Add(c); } } // Backward and forward for (int x = ripStart.X; x <= ripEnd.X; x++) { Voxel.Coord c = new Voxel.Coord { X = x, Y = y, Z = ripStart.Z }; Voxel.State s = voxel[c]; if (s != Voxel.States.Empty && !s.Permanent) { edges.Add(c); } c = new Voxel.Coord { X = x, Y = y, Z = ripEnd.Z }; s = voxel[c]; if (s != Voxel.States.Empty && !s.Permanent) { edges.Add(c); } } } Propagator p = WorldFactory.Instance.Get <Propagator>(); foreach (Voxel.Coord c in edges) { p.SparksLowPriority(voxel.GetAbsolutePosition(c), Propagator.Spark.Dangerous); } voxel.Empty(edges); voxel.Regenerate(callback); return(true); } return(false); }
// extracts key values from row expression private static CompositeKey ExtractKey(PropagatorResult change, ReadOnlyCollection<DbExpression> keySelectors, Propagator parent) { Debug.Assert(null != change && null != keySelectors && null != parent); PropagatorResult[] keyValues = new PropagatorResult[keySelectors.Count]; for (int i = 0; i < keySelectors.Count; i++) { PropagatorResult constant = Evaluator.Evaluate(keySelectors[i], change, parent); keyValues[i] = constant; } return new CompositeKey(keyValues); }
private void InitializeCrack() { // Left crack // Propagator IPropagator leftPropagator; if (!writePropagation) { leftPropagator = new FixedPropagator(leftPropagationPath, null); } else { leftPropagator = new Propagator(Mesh, jIntegralRadiusOverElementSize, new HomogeneousMaterialAuxiliaryStates(globalHomogeneousMaterial), new HomogeneousSIFCalculator(globalHomogeneousMaterial), new MaximumCircumferentialTensileStressCriterion(), new ConstantIncrement2D(growthLength)); } var initialLeftCrack = new PolyLine2D(new CartesianPoint(leftCrackMouthX, leftCrackMouthY), new CartesianPoint(leftCrackTipX, leftCrackTipY)); LeftCrack = new TrackingExteriorCrackLSM(leftPropagator, tipEnrichmentRadius, new RelativeAreaResolver(heavisideTol)); LeftCrack.Mesh = Mesh; // Create enrichments LeftCrack.CrackBodyEnrichment = new CrackBodyEnrichment2D(LeftCrack); LeftCrack.CrackTipEnrichments = new CrackTipEnrichments2D(LeftCrack, CrackTipPosition.Single); if (leftLsmPlotDirectory != null) { LeftCrack.EnrichmentLogger = new EnrichmentLogger(Model, LeftCrack, leftLsmPlotDirectory); LeftCrack.LevelSetLogger = new LevelSetLogger(Model, LeftCrack, leftLsmPlotDirectory); LeftCrack.LevelSetComparer = new PreviousLevelSetComparer(LeftCrack, leftLsmPlotDirectory); } // Mesh geometry interaction LeftCrack.InitializeGeometry(initialLeftCrack); // Right crack // Propagator IPropagator rightPropagator; if (!writePropagation) { rightPropagator = new FixedPropagator(rightPropagationPath, null); } else { rightPropagator = new Propagator(Mesh, jIntegralRadiusOverElementSize, new HomogeneousMaterialAuxiliaryStates(globalHomogeneousMaterial), new HomogeneousSIFCalculator(globalHomogeneousMaterial), new MaximumCircumferentialTensileStressCriterion(), new ConstantIncrement2D(growthLength)); } var initialRightCrack = new PolyLine2D(new CartesianPoint(rightCrackMouthX, rightCrackMouthY), new CartesianPoint(rightCrackTipX, rightCrackTipY)); RightCrack = new TrackingExteriorCrackLSM(rightPropagator, tipEnrichmentRadius, new RelativeAreaResolver(heavisideTol)); RightCrack.Mesh = Mesh; // Create enrichments RightCrack.CrackBodyEnrichment = new CrackBodyEnrichment2D(RightCrack); RightCrack.CrackTipEnrichments = new CrackTipEnrichments2D(RightCrack, CrackTipPosition.Single); if (rightLsmPlotDirectory != null) { RightCrack.EnrichmentLogger = new EnrichmentLogger(Model, RightCrack, rightLsmPlotDirectory); RightCrack.LevelSetLogger = new LevelSetLogger(Model, RightCrack, rightLsmPlotDirectory); RightCrack.LevelSetComparer = new PreviousLevelSetComparer(RightCrack, rightLsmPlotDirectory); } // Mesh geometry interaction RightCrack.InitializeGeometry(initialRightCrack); // Container for both cracks Crack = new MultipleCracksDisjoint(new TrackingExteriorCrackLSM[] { LeftCrack, RightCrack }); //Crack = new MultipleCracksDisjoint(new TrackingExteriorCrackLSM[] { leftCrack }); }
public override unsafe void Propagate() { // see VoxelLightChannel enum int channel = (int)Channel; // depropagate while (_depropQueue.TryDequeue(out var node)) { byte lightLevel = node.OriginalLight; // positive direction for (int axis = 0; axis < 3; axis++) { var neighbor = node; (&neighbor.Coords.X)[axis]++; if ((&neighbor.Coords.X)[axis] == VoxelChunk.SIZE) { var neighborChunkCoords = node.Chunk.Coords; (&neighborChunkCoords.X)[axis]++; neighbor.Chunk = Volume[neighborChunkCoords]; Propagator.addAlteredChunk(neighbor.Chunk); (&neighbor.Coords.X)[axis] = 0; } if (neighbor.Chunk != null) { byte *neighborLightPtr = neighbor.LightLevel(channel); byte neighborLight = *neighborLightPtr; neighbor.OriginalLight = neighborLight; if (!neighbor.IsOpaque) { if (neighborLight != 0 && (neighborLight < lightLevel)) { *neighborLightPtr = 0; _depropQueue.Enqueue(neighbor); } else if (neighborLight >= lightLevel) { _propQueue.Enqueue(new PropNode(neighbor.Chunk, neighbor.Coords)); } } } } // negative direction for (int axis = 0; axis < 3; axis++) { var neighbor = node; (&neighbor.Coords.X)[axis]--; if ((&neighbor.Coords.X)[axis] == -1) { var neighborChunkCoords = node.Chunk.Coords; (&neighborChunkCoords.X)[axis]--; neighbor.Chunk = Volume[neighborChunkCoords]; Propagator.addAlteredChunk(neighbor.Chunk); (&neighbor.Coords.X)[axis] = VoxelChunk.SIZE - 1; } if (neighbor.Chunk != null) { byte *neighborLightPtr = neighbor.LightLevel(channel); byte neighborLight = *neighborLightPtr; neighbor.OriginalLight = neighborLight; if (!neighbor.IsOpaque) { if (neighborLight != 0 && (neighborLight < lightLevel)) { *neighborLightPtr = 0; _depropQueue.Enqueue(neighbor); } else if (neighborLight >= lightLevel) { _propQueue.Enqueue(new PropNode(neighbor.Chunk, neighbor.Coords)); } } } } } // propagate while (_propQueue.TryDequeue(out var node)) { byte lightLevel = *node.Chunk.LightData[channel][node.Coords]; int neighborLightLevel = lightLevel - VoxelLight.LIGHT_DECREMENT; if (neighborLightLevel > 0) { // positive direction for (int axis = 0; axis < 3; axis++) { var neighbor = node; (&neighbor.Coords.X)[axis]++; if ((&neighbor.Coords.X)[axis] == VoxelChunk.SIZE) { var neighborChunkCoords = node.Chunk.Coords; (&neighborChunkCoords.X)[axis]++; neighbor.Chunk = Volume[neighborChunkCoords]; Propagator.addAlteredChunk(neighbor.Chunk); (&neighbor.Coords.X)[axis] = 0; } if (neighbor.Chunk != null) { byte *light = neighbor.LightLevel(channel); if (!neighbor.IsOpaque) { if (*light < neighborLightLevel) { *light = (byte)neighborLightLevel; _propQueue.Enqueue(neighbor); } } } } // negative direction for (int axis = 0; axis < 3; axis++) { var neighbor = node; (&neighbor.Coords.X)[axis]--; if ((&neighbor.Coords.X)[axis] == -1) { var neighborChunkCoords = node.Chunk.Coords; (&neighborChunkCoords.X)[axis]--; neighbor.Chunk = Volume[neighborChunkCoords]; Propagator.addAlteredChunk(neighbor.Chunk); (&neighbor.Coords.X)[axis] = VoxelChunk.SIZE - 1; } if (neighbor.Chunk != null) { byte *light = neighbor.LightLevel(channel); if (!neighbor.IsOpaque) { if (*light < neighborLightLevel) { *light = (byte)neighborLightLevel; _propQueue.Enqueue(neighbor); } } } } } } }
public override unsafe void Propagate() { // see VoxelLightChannel enum int channel = (int)Channel; // these values are used when checking if the current axis in question is the same as the sunlight direction. // we have one value for positive axes and one for negative int lAxisP = channel; // the first three are positive int lAxisN = channel - 3; // the second three are negative // depropagate while (_depropQueue.TryDequeue(out var node)) { byte lightLevel = node.OriginalLight; // positive direction for (int axis = 0; axis < 3; axis++) { var neighbor = node; (&neighbor.Coords.X)[axis]++; if ((&neighbor.Coords.X)[axis] == VoxelChunk.SIZE) { var neighborChunkCoords = node.Chunk.Coords; (&neighborChunkCoords.X)[axis]++; neighbor.Chunk = Volume[neighborChunkCoords]; Propagator.addAlteredChunk(neighbor.Chunk); (&neighbor.Coords.X)[axis] = 0; } if (neighbor.Chunk != null) { byte *neighborLightPtr = neighbor.LightLevel(channel); byte neighborLight = *neighborLightPtr; neighbor.OriginalLight = neighborLight; if (!neighbor.IsOpaque) { if (neighborLight != 0 && (neighborLight < lightLevel || (lightLevel == VoxelLight.MAX_LIGHT && axis == lAxisP))) { *neighborLightPtr = 0; _depropQueue.Enqueue(neighbor); } else if (neighborLight >= lightLevel) { _propQueue.Enqueue(new PropNode(neighbor.Chunk, neighbor.Coords)); } } } } // negative direction for (int axis = 0; axis < 3; axis++) { var neighbor = node; (&neighbor.Coords.X)[axis]--; if ((&neighbor.Coords.X)[axis] == -1) { var neighborChunkCoords = node.Chunk.Coords; (&neighborChunkCoords.X)[axis]--; neighbor.Chunk = Volume[neighborChunkCoords]; Propagator.addAlteredChunk(neighbor.Chunk); (&neighbor.Coords.X)[axis] = VoxelChunk.SIZE - 1; } if (neighbor.Chunk != null) { byte *neighborLightPtr = neighbor.LightLevel(channel); byte neighborLight = *neighborLightPtr; neighbor.OriginalLight = neighborLight; if (!neighbor.IsOpaque) { if (neighborLight != 0 && (neighborLight < lightLevel || (lightLevel == VoxelLight.MAX_LIGHT && axis == lAxisN))) { *neighborLightPtr = 0; _depropQueue.Enqueue(neighbor); } else if (neighborLight >= lightLevel) { _propQueue.Enqueue(new PropNode(neighbor.Chunk, neighbor.Coords)); } } } } } // propagate while (_propQueue.TryDequeue(out var node)) { byte lightLevel = *node.Chunk.LightData[channel][node.Coords]; int neighborLightLevel = lightLevel - VoxelLight.LIGHT_DECREMENT; if (neighborLightLevel > 0) { // positive direction for (int axis = 0; axis < 3; axis++) { var neighbor = node; (&neighbor.Coords.X)[axis]++; if ((&neighbor.Coords.X)[axis] == VoxelChunk.SIZE) { var neighborChunkCoords = node.Chunk.Coords; (&neighborChunkCoords.X)[axis]++; neighbor.Chunk = Volume[neighborChunkCoords]; Propagator.addAlteredChunk(neighbor.Chunk); (&neighbor.Coords.X)[axis] = 0; } if (neighbor.Chunk != null) { byte *light = neighbor.LightLevel(channel); if (!neighbor.IsOpaque) { if (axis == lAxisP && lightLevel == VoxelLight.MAX_LIGHT) { *light = VoxelLight.MAX_LIGHT; _propQueue.Enqueue(neighbor); } else if (*light < neighborLightLevel) { *light = (byte)neighborLightLevel; _propQueue.Enqueue(neighbor); } } } } // negative direction for (int axis = 0; axis < 3; axis++) { var neighbor = node; (&neighbor.Coords.X)[axis]--; if ((&neighbor.Coords.X)[axis] == -1) { var neighborChunkCoords = node.Chunk.Coords; (&neighborChunkCoords.X)[axis]--; neighbor.Chunk = Volume[neighborChunkCoords]; Propagator.addAlteredChunk(neighbor.Chunk); (&neighbor.Coords.X)[axis] = VoxelChunk.SIZE - 1; } if (neighbor.Chunk != null) { byte *light = neighbor.LightLevel(channel); if (!neighbor.IsOpaque) { if (axis == lAxisN && lightLevel == VoxelLight.MAX_LIGHT) { *light = VoxelLight.MAX_LIGHT; _propQueue.Enqueue(neighbor); } else if (*light < neighborLightLevel) { *light = (byte)neighborLightLevel; _propQueue.Enqueue(neighbor); } } } } } } }
public virtual async Task <TEntity> GetNextItemAsync(CancellationToken token) { return(await Propagator.ReceiveAsync(token)); }