public bool contains(PTwo point) { if (!span.contains(point.s)) { return(false); } if (startRange.contains(point.t)) { if (endRange.contains(point.t)) { return(true); } else { // TODO: fill in better math int distToStart = point.s - span.start; return(distToStart < (span.range - distToStart)); } } else { if (endRange.contains(point.t)) { int distToStart = point.s - span.start; return(distToStart > (span.range - distToStart)); } } return(false); }
private static Quad LightDomainAround(int x, int z) { PTwo midPoint = new PTwo(x, z); PTwo lightTravel = new PTwo((int)Window.LIGHT_TRAVEL_MAX_DISTANCE); return(Quad.QuadWithOriginAndExtent(midPoint - lightTravel, midPoint + lightTravel)); }
private LightColumn lightestNeightbor(SimpleRange colRange, PTwo co) { LightColumn lightest = null; List <LightColumn> neighbors = m_lightColumnMap.lightColumnsAdjacentToAndFlushWithSimpleRangeAndPoint(colRange, co); if (neighbors.Count == 0) { return(null); } lightest = neighbors[0]; //CONSIDER: could be a little faster if we iterated over directions ourselves here... for (int i = 1; i < neighbors.Count; ++i) { LightColumn neicol = neighbors[i]; if (neicol.lightLevel > lightest.lightLevel) { lightest = neicol; } } return(lightest); }
private float lightValueAtFromPoint(PTwo destinationPoint, LightPoint fromPoint) { PTwo diff = PTwo.Abs(destinationPoint - fromPoint.point); int dist = diff.s + diff.t / 2; // very cheapo pythagoras return(lightAddedWithDistance(dist, fromPoint.lightValue)); }
//COPY PASTE OF ABOVE FUNC.! private List <PTwo> coordsXZOnInsideEdgeInDirection(Quad area, Direction dir) { PTwo nudge = DirectionUtil.NudgeCoordForDirectionPTwo(dir); Axis axis = DirectionUtil.AxisForDirection(dir); PTwo startPoint = area.origin; if (DirectionUtil.IsPosDirection(dir)) { if (axis == Axis.X) { startPoint.t += area.dimensions.t; } else { startPoint.s += area.dimensions.s; } } PTwo iterNudge = PTwo.Abs(nudge).flipSAndT(); int length = axis == Axis.X ? area.dimensions.t : area.dimensions.s; PTwo cursorPoint = startPoint; List <PTwo> result = new List <PTwo>(); for (int i = 0; i < length; ++i) { result.Add(cursorPoint + nudge); cursorPoint += iterNudge; } return(result); }
public static int GreaterDimension(PTwo _a) { if (_a.s > _a.t) { return(_a.s); } return(_a.t); }
private bool thereIsAdjacencyOnOneSideOrTheOther(PTwo pointToAdd) { if (checkAdjacencyAt(pointToAdd.s - 1, pointToAdd.t)) { return(true); } return(this.checkAdjacencyAt(pointToAdd.s + 1, pointToAdd.t)); }
public DiscreteDomainRangeList <LightColumn> this[PTwo patchRelPoint] { get { return(this[patchRelPoint.s, patchRelPoint.t]); } set { this[patchRelPoint.s, patchRelPoint.t] = value; } }
public static int LesserDimension(PTwo _a) { if (_a.s < _a.t) { return(_a.s); } return(_a.t); }
private void updateColumnAt(LightColumn lightcol, PTwo coord, LightColumn influencerColumn, Quad withinBounds) { if (!withinBounds.contains(coord)) { return; } bool tookInfluence = false; if (influencerColumn == null) { // addColumnIfNoiseCoordOO(lightcol); //DBG lightcol.setLightLevelToMax(); tookInfluence = true; } else { tookInfluence = lightcol.takeInfluenceFromColumn(influencerColumn); // if (tookInfluence) //DEBUG!!! // { // this.addDebugColumnIfNoiseCoZIsNeg(lightcol, 4); // this.addDebugColumnIfNoiseCoZIsNeg(influencerColumn, 1); // } } if (!tookInfluence) { return; } List <LightColumn> adjacentNeighbors = m_lightColumnMap.lightColumnsAdjacentToAndFlushWith(lightcol); if (adjacentNeighbors == null) { return; } for (int i = 0; i < adjacentNeighbors.Count; ++i) { LightColumn adjNeighbor = adjacentNeighbors[i]; //TEST WANT updateColumnAt(adjNeighbor, adjNeighbor.coord, lightcol, withinBounds); } // touch any connected columns below this light col // then check this column done on check list // foreach(LightColumn belowCol in m_lightColumnMap[coord].toList() ) // { // if (belowCol.Equals(lightcol)) // continue; // foreach(LightColumn adjCol in adjacentNeighbors) { // belowCol.takeInfluenceFromColumn(adjCol); // if (belowCol.lightLevel >= lightcol.lightLevel - Window.UNIT_FALL_OFF_BYTE * 2) // break; // } // } // columnDoneCheckList[coord.s,coord.t] = true; }
public bool addNewZCurtainSectionAt(PTwo xzco, Range1D continuityRangeAtZPlusOrMinusOne, Range1D airRange) { if (doAddNewZCurtainSectionAt(xzco, continuityRangeAtZPlusOrMinusOne, airRange)) { bounds = bounds.expandedToContainPoint(xzco); return(true); } return(false); }
//COPY PASTE OF ABOVE FUNC.! private void updateSurfaceHeightsInDirection(Quad area, Direction dir) { // return; PTwo nudge = DirectionUtil.NudgeCoordForDirectionPTwo(dir); Axis axis = DirectionUtil.AxisForDirection(dir); PTwo startPoint = area.origin; if (DirectionUtil.IsPosDirection(dir)) { if (axis == Axis.X) { startPoint.t += area.dimensions.t; } else { startPoint.s += area.dimensions.s; } } PTwo iterNudge = PTwo.Abs(nudge).flipSAndT(); int length = axis == Axis.X ? area.dimensions.t : area.dimensions.s; PTwo cursorPoint = startPoint; List <LightColumn> needUpdateColumns = new List <LightColumn>(); for (int i = 0; i < length; ++i) { // DiscreteDomainRangeList<LightColumn> licols = m_lightColumnMap[cursorPoint + nudge]; // if (licols == null) // continue; DiscreteDomainRangeList <LightColumn> insideCols = m_lightColumnMap[cursorPoint]; if (insideCols == null) { continue; } int surfaceHeightJustBeyondBorder = this.m_noisePatch.highestPointAtPatchRelativeCoord(cursorPoint + nudge); for (int j = 0; j < insideCols.Count; ++j) { LightColumn insideCol = insideCols[j]; if (insideCol.heightIsBelowExtent(surfaceHeightJustBeyondBorder)) { addToSurfaceExposedColumnIfNotContains(insideCol); needUpdateColumns.Add(insideCol); } } cursorPoint += iterNudge; } foreach (LightColumn col in needUpdateColumns) { updateColumnAt(col, col.coord, null, PatchQuad); } }
public DiscontinuityCurtain(PTwo xzStartCoord, Range1D continuityRangeAtZMinusOne, Range1D airRange) { bounds = Quad.UnitQuadWithPoint(xzStartCoord); ZCurtain inital_zc = new ZCurtain(xzStartCoord.t); inital_zc.setDiscontinuityStartWithSurfaceRange(continuityRangeAtZMinusOne, airRange); z_curtains.Add(inital_zc); }
public static PTwo[] SurroundingPTwoCoordsFromPTwo(PTwo coord) { PTwo[] surrounding = SurroundingNudgeCoordsFour(); for (int i = 0; i < 4; ++i) { surrounding[i] += coord; } return(surrounding); }
public ZDiscontinuityPointCoverageStatus zCoverageStatusForPoint(PTwo woco_pointxz) { if (!bounds.sRange().contains(woco_pointxz.s)) { return(ZDiscontinuityPointCoverageStatus.BeyondXDomain); } PTwo relCo = woco_pointxz - bounds.origin; return(z_curtains[relCo.s].z_contains(woco_pointxz.t)); }
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; }
public void addColumn(SimpleRange range, PTwo _xz, int debugInteger) { Column column = new Column(); column.range = range; column.xz = _xz; column.handyInteger = debugInteger; if (!columns.Contains(column)) { columns.Add(column); } }
public List <Range1D> this[PTwo pt] { get { if (ranges[pt.s, pt.t] == null) { ranges[pt.s, pt.t] = new List <Range1D>(); } return(ranges[pt.s, pt.t]); } set { ranges[pt.s, pt.t] = value; } }
private void updateColumnsWithHigherHighestSurface(List <Range1D> heightRanges, Coord pRelCoord, SurroundingSurfaceValues ssvs, bool shouldPropagateLight) { b.bug("update w higher highest surf"); int x = pRelCoord.x, y = pRelCoord.y, z = pRelCoord.z; SimpleRange justCoveredColumn = new SimpleRange(y, 1); Range1D highest = heightRanges[heightRanges.Count - 1]; LightColumn newlico = null; int lowestSurroundingSurface = ssvs.lowestValue(); if (highest.range == 1) { AssertUtil.Assert(heightRanges.Count > 1, "what we just 'covered' bedrock?"); Range1D secondHighest = heightRanges[heightRanges.Count - 2]; justCoveredColumn = new SimpleRange(secondHighest.extent(), y + 1 - secondHighest.extent()); //(extent - start) //new column SimpleRange newColRange = justCoveredColumn; newColRange.range--; newlico = new LightColumn(PTwo.PTwoXZFromCoord(pRelCoord), 0, newColRange); m_lightColumnMap.addColumnAt(newlico, x, z); if (newColRange.extent() > lowestSurroundingSurface) { newlico.lightLevel = Window.LIGHT_LEVEL_MAX_BYTE; surfaceExposedColumns.Add(newlico); } } List <LightColumn> adjColsFlushToJustCovered = m_lightColumnMap.lightColumnsAdjacentToAndFlushWithSimpleRangeAndPoint(justCoveredColumn, new PTwo(x, z)); foreach (LightColumn adjcol in adjColsFlushToJustCovered) { //adj cols could still be above if (adjcol.extent() <= y) { //get surrounding surface for these? SurroundingSurfaceValues assvs = m_noisePatch.surfaceValuesSurrounding(adjcol.coord); if (adjcol.extent() <= assvs.lowestValue()) { surfaceExposedColumns.Remove(adjcol); adjcol.lightLevel = 0; // put back? } } } resetAndUpdateColumnsWithin(LightDomainAround(x, z)); }
public float lightValueForPointClosestToPatchRelativeYZ(PTwo patchRelYZPoint) { // return Window.LIGHT_LEVEL_MAX * .5f; //TEST return(Mathf.Clamp((float)zLightLevels[patchRelYZPoint.t], 0, Window.LIGHT_LEVEL_MAX)); int spanOffset = Mathf.Clamp(patchRelYZPoint.t - trapezoid.span.start, 0, trapezoid.span.range); int heightOffSetStart = Mathf.Clamp(patchRelYZPoint.s - trapezoid.startRange.start, 0, trapezoid.startRange.range); int heightOffSetEnd = Mathf.Clamp(patchRelYZPoint.s - trapezoid.endRange.start, 0, trapezoid.endRange.range); float startLerp = Mathf.Lerp(trapLight.lowerNeg, trapLight.upperNeg, (heightOffSetStart / (float)trapezoid.startRange.range)); float endLerp = Mathf.Lerp(trapLight.lowerPos, trapLight.upperPos, (heightOffSetEnd / (float)trapezoid.endRange.range)); // return Window.LIGHT_LEVEL_MAX/12f; return(Mathf.Lerp(startLerp, endLerp, spanOffset / (float)trapezoid.span.range)); }
public static Coord CoordForPTwoAndNormalDirectionWithFaceAggregatorRules(PTwo ptwo, Direction dir) { Axis axis = AxisForDirection(dir); if (axis == Axis.X) { return(new Coord(0, ptwo.t, ptwo.s)); // Y is up , z is across (s) } if (axis == Axis.Y) { return(new Coord(ptwo.s, 0, ptwo.t)); } return(new Coord(ptwo.s, ptwo.t, 0)); }
public static PTwo NudgeCoordForDirectionPTwo(Direction dir) { PTwo result = new PTwo(0, 1); if (dir <= Direction.xneg) { result = new PTwo(1, 0); } if (!IsPosDirection(dir)) { result *= -1; } return(result); }
public void addNoisePatchAt(NoiseCoord nco, NoisePatch _npatch) { m_noisePatches.Add(nco, _npatch); //domain limits if (Quad.Equal(this.domain, Quad.theErsatzNullQuad())) { //first time domain = new Quad(new PTwo(nco.x, nco.z), PTwo.PTwoOne()); } else { domain = domain.expandedToContainPoint(new PTwo(nco.x, nco.z)); } ChunkManager.debugLinesAssistant.debugQuad = domain; }
//get the light columns at any woco that exists... public DiscreteDomainRangeList <LightColumn> lightColumnsAtWoco(int x, int z, NoiseCoord _noiseCoord) { Coord woconoco = CoordUtil.WorldCoordFromNoiseCoord(_noiseCoord); NoiseCoord nco = CoordUtil.NoiseCoordForWorldCoord(new Coord(x, 0, z) + woconoco); NoisePatch npatch = m_chunkManager.blocks.noisePatchAtNoiseCoord(nco); if (npatch == null) { return(null); } Coord pRelCo = CoordUtil.PatchRelativeBlockCoordForWorldBlockCoord(new Coord(x, 0, z)); // noisepatch return lightcol map at rel co return(npatch.lightColumnsAt(PTwo.PTwoXZFromCoord(pRelCo))); }
public FaceAggregator(Axis faceNormalAxis) { // face type assumed to be xz (for now) int across_dim = (int)ChunkManager.CHUNKLENGTH; int up_dim = (int)ChunkManager.CHUNKHEIGHT; if (faceNormalAxis == Axis.Y) { up_dim = (int)ChunkManager.CHUNKLENGTH; } faceSetTableHalfDims = new PTwo(across_dim, up_dim); faceSetTable = new int[faceSetTableHalfDims.s * 2, faceSetTableHalfDims.t]; faceNormal = faceNormalAxis; }
private void updateQuadBorderInDirection(Quad area, Direction dir) { PTwo nudge = DirectionUtil.NudgeCoordForDirectionPTwo(dir); Axis axis = DirectionUtil.AxisForDirection(dir); PTwo startPoint = area.origin; if (DirectionUtil.IsPosDirection(dir)) { if (axis == Axis.X) { startPoint.t += area.dimensions.t; } else { startPoint.s += area.dimensions.s; } } PTwo iterNudge = PTwo.Abs(nudge).flipSAndT(); int length = axis == Axis.X ? area.dimensions.t : area.dimensions.s; PTwo cursorPoint = startPoint; for (int i = 0; i < length; ++i) { DiscreteDomainRangeList <LightColumn> licols = m_lightColumnMap[cursorPoint + nudge]; if (licols == null) { continue; } DiscreteDomainRangeList <LightColumn> insideCols = m_lightColumnMap[cursorPoint]; if (insideCols == null) { continue; } for (int j = 0; j < licols.Count; ++j) { LightColumn outsideCol = licols[j]; for (int k = 0; k < insideCols.Count; ++k) { LightColumn insideCol = insideCols[k]; updateColumnAt(insideCol, insideCol.coord, outsideCol, area); } } cursorPoint += iterNudge; } }
private void checkAdjacentToSurfaceFourDirectionsAt(int spanOffset) { PTwo checkPoint = patchRelativeOriginPTwo; checkPoint.t += spanOffset; foreach (PTwo surrounding in DirectionUtil.SurroundingPTwoCoordsFromPTwo(checkPoint)) { int surfaceHeight = m_windowMap.surfaceHeightAt(surrounding.s, surrounding.t); if (windowHeightAtOffsetGreaterThanHeight(spanOffset, surfaceHeight)) { this.addLightLevelsWithAdjacentSurfaceHeightSpanOffset(surfaceHeight, spanOffset); } // else... } }
private bool heightIsAboveSurface(int spanOffset) { PTwo checkPoint = patchRelativeOriginPTwo; checkPoint.t += spanOffset; foreach (PTwo surrounding in DirectionUtil.SurroundingPTwoCoordsFromPTwo(checkPoint)) { int surfaceHeight = m_windowMap.surfaceHeightAt(surrounding.s, surrounding.t); if (windowHeightAtOffsetGreaterThanHeight(spanOffset, surfaceHeight)) { return(true); } } return(false); }
private void enlargeDomain() { foreach (KeyValuePair <NoiseCoord, NoisePatch> keyVal in m_noisePatches) { NoiseCoord nco = keyVal.Key; if (domain.isErsatzNull()) { domain = Quad.UnitQuadWithPoint(PTwo.PTwoXZFromNoiseCoord(nco)); } else { domain.expandedToContainPoint(PTwo.PTwoXZFromNoiseCoord(nco)); } } //debug ChunkManager.debugLinesAssistant.debugQuad = domain; }
public Tree sectionOfTreeContainedByNoisePatchNeighborInDirection(NeighborDirection neighborDir) { if (this.wasNotTruncated()) { return(null); } PTwo neighborRelOrigin = NeighborDirectionUtils.neighborPatchRelativeCoordForNeighborInDirection(neighborDir, this.nonTruncatedPatchRelativePlot.origin); Quad nonTruncNeighPlot = new Quad(neighborRelOrigin, this.undividedDimensions); Quad intersection = Quad.Intersection(nonTruncNeighPlot, new Quad(new PTwo(0, 0), noisePatchXZDims)); if (intersection.isErsatzNull()) { return(null); } return(new Tree(neighborRelOrigin, this.y_origin, this.seed, false)); }