public SimpleRange considerLightValuesFromOther(LightLevelTrapezoid other, bool subtract, SimpleRange withinRange, float influenceFactor) { int minInfluenceIndex = 258; int maxInfluenceIndex = 0; if (!SimpleRange.RangesIntersect(trapezoid.span, withinRange)) { return(new SimpleRange(0, 0)); } byte influenceFromOther = (byte)(Window.LIGHT_LEVEL_MAX * influenceFactor - Window.UNIT_FALL_OFF_BYTE); withinRange = SimpleRange.IntersectingRange(withinRange, new SimpleRange(0, NoisePatch.patchDimensions.z)); // safer... if (withinRange.isErsatzNull()) { return(new SimpleRange(0, 0)); } for (int i = withinRange.start; i < withinRange.extent(); ++i) { byte myCurrentLightLevel = zLightLevels[i]; byte othersLightLevel = other.zLightLevels[i]; // if (myCurrentLightLevel == Window.LIGHT_LEVEL_MAX_BYTE) // continue; byte influenceAmount = 0; if (myCurrentLightLevel <= influenceFromOther) { // if (subtract) { // } else { influenceAmount = (byte)(other.zLightLevels[i] - Window.UNIT_FALL_OFF_BYTE); // } } else { //cheap0 influenceAmount = (byte)(myCurrentLightLevel + (influenceFromOther / 2f * (subtract? -1 : 1))); } zLightLevels[i] = (byte)Mathf.Clamp(influenceAmount, 0, (int)Window.LIGHT_LEVEL_MAX_BYTE); minInfluenceIndex = Mathf.Min(minInfluenceIndex, i); maxInfluenceIndex = Mathf.Max(maxInfluenceIndex, i + 1); } if (maxInfluenceIndex == 0) { return(new SimpleRange(0, 0)); } return(SimpleRange.SimpleRangeWithStartAndExtent(minInfluenceIndex, maxInfluenceIndex)); }
private void updateRangeListAtXZ(List <Range1D> heightRanges, Coord pRelCoord, bool solidBlockRemoved, SurroundingSurfaceValues ssvs) { DiscreteDomainRangeList <LightColumn> liCols = m_lightColumnMap[pRelCoord.x, pRelCoord.z]; if (!solidBlockRemoved && heightRanges.Count <= 1) // equal zero would be down right silly. { return; } // y above highest extent? int highestDiscontinuity = liCols.highestExtent(); int lowestSurroundingLevel = ssvs.lowestValue(); //CASE WHERE A BLOCK IS ADDED TO THE TOP OF OR OVER TOP OF THE SURFACE if (pRelCoord.y > highestDiscontinuity && !solidBlockRemoved) { // Y MUST BE THE TOP BLOCK? int hRangeCount = heightRanges.Count; SimpleRange between = discontinuityBetween(heightRanges[hRangeCount - 2], heightRanges[hRangeCount - 1]); if (!between.isErsatzNull()) { AssertUtil.Assert(pRelCoord.y == between.extentMinusOne(), "confused. y is " + pRelCoord.y + " between range is " + between.toString()); int lightValue = pRelCoord.y >= lowestSurroundingLevel? (int)Window.LIGHT_LEVEL_MAX_BYTE : 0; LightColumn licol = new LightColumn(PTwo.PTwoXZFromCoord(pRelCoord), (byte)lightValue, between); liCols.Add(licol); return; // licol; } throw new Exception("don't want to be here. we think a block couldn't be placed vertically in between at this point"); } //TODO handle case where y is above surface, solid block removed // need to destroy some discon ranges (not incorporate y). Range1D highest = heightRanges[heightRanges.Count - 1]; if (pRelCoord.y > highest.extent()) { liCols.RemoveStartAbove(highest.extent()); } else { LightColumn newCol = liCols.Incorporate(pRelCoord.y, solidBlockRemoved); if (newCol != null) { newCol.coord = new PTwo(pRelCoord.x, pRelCoord.z); } // throw new Exception("lots of exceptions. we failed to incorp a solid block added."); } b.bug("we incorporated a pRelCOord: " + pRelCoord.toString() + "solid removed was: " + solidBlockRemoved); m_lightColumnMap[pRelCoord.x, pRelCoord.z] = liCols; }
private static List <SimpleRange> discontinuitiesFromHeightRanges(List <Range1D> heightRanges) { List <SimpleRange> result = new List <SimpleRange>(); for (int i = 1; i < heightRanges.Count; ++i) { SimpleRange between = discontinuityBetween(heightRanges[i - 1], heightRanges[i]); if (!between.isErsatzNull()) { result.Add(between); } } return(result); }