diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnBox.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnBox.java index 1e7ff176d..9fb300909 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnBox.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnBox.java @@ -35,12 +35,12 @@ public class ColumnBox public static void addBoxQuadsToBuilder( LodQuadBuilder builder, short xSize, short ySize, short zSize, - short x, short y, short z, + short x, short minY, short z, int color, byte skyLight, byte blockLight, long topData, long bottomData, ColumnArrayView[][] adjData) { short maxX = (short) (x + xSize); - short maxY = (short) (y + ySize); + short maxY = (short) (minY + ySize); short maxZ = (short) (z + zSize); byte skyLightTop = skyLight; byte skyLightBot = RenderDataPointUtil.doesDataPointExist(bottomData) ? RenderDataPointUtil.getLightSky(bottomData) : 0; @@ -65,8 +65,8 @@ public class ColumnBox && builder.skyLightCullingBelow > maxY && ( - (RenderDataPointUtil.getAlpha(topData) < 255 && RenderDataPointUtil.getHeight(topData) >= builder.skyLightCullingBelow) - || (RenderDataPointUtil.getDepth(topData) >= builder.skyLightCullingBelow) + (RenderDataPointUtil.getAlpha(topData) < 255 && RenderDataPointUtil.getYMax(topData) >= builder.skyLightCullingBelow) + || (RenderDataPointUtil.getYMin(topData) >= builder.skyLightCullingBelow) || !RenderDataPointUtil.doesDataPointExist(topData) ) ) @@ -81,32 +81,32 @@ public class ColumnBox { if (!isTransparent && isTopTransparent && RenderDataPointUtil.doesDataPointExist(topData)) { - skyLightTop = (byte) MathUtil.clamp(0, 15 - (RenderDataPointUtil.getHeight(topData) - y), 15); - ySize = (short) (RenderDataPointUtil.getHeight(topData) - y - 1); + skyLightTop = (byte) MathUtil.clamp(0, 15 - (RenderDataPointUtil.getYMax(topData) - minY), 15); + ySize = (short) (RenderDataPointUtil.getYMax(topData) - minY - 1); } else if (isTransparent && !isBottomTransparent && RenderDataPointUtil.doesDataPointExist(bottomData)) { - y = (short) (y + ySize - 1); + minY = (short) (minY + ySize - 1); ySize = 1; } - maxY = (short) (y + ySize); + maxY = (short) (minY + ySize); } // add top and bottom faces if requested // - boolean skipTop = RenderDataPointUtil.doesDataPointExist(topData) && (RenderDataPointUtil.getDepth(topData) == maxY) && !isTopTransparent; + boolean skipTop = RenderDataPointUtil.doesDataPointExist(topData) && (RenderDataPointUtil.getYMin(topData) == maxY) && !isTopTransparent; if (!skipTop) { builder.addQuadUp(x, maxY, z, xSize, zSize, ColorUtil.applyShade(color, MC.getShade(ELodDirection.UP)), skyLightTop, blockLight); } - boolean skipBottom = RenderDataPointUtil.doesDataPointExist(bottomData) && (RenderDataPointUtil.getHeight(bottomData) == y) && !isBottomTransparent; + boolean skipBottom = RenderDataPointUtil.doesDataPointExist(bottomData) && (RenderDataPointUtil.getYMax(bottomData) == minY) && !isBottomTransparent; if (!skipBottom) { - builder.addQuadDown(x, y, z, xSize, zSize, ColorUtil.applyShade(color, MC.getShade(ELodDirection.DOWN)), skyLightBot, blockLight); + builder.addQuadDown(x, minY, z, xSize, zSize, ColorUtil.applyShade(color, MC.getShade(ELodDirection.DOWN)), skyLightBot, blockLight); } @@ -122,21 +122,21 @@ public class ColumnBox // add an adjacent face if this is opaque face or transparent over the void if (!isTransparent || overVoid) { - builder.addQuadAdj(ELodDirection.NORTH, x, y, z, xSize, ySize, color, (byte) 15, blockLight); + builder.addQuadAdj(ELodDirection.NORTH, x, minY, z, xSize, ySize, color, (byte) 15, blockLight); } } else if (adjDataNorth.length == 1) { - makeAdjVerticalQuad(builder, adjDataNorth[0], ELodDirection.NORTH, x, y, z, xSize, ySize, + makeAdjVerticalQuad(builder, adjDataNorth[0], ELodDirection.NORTH, x, minY, z, xSize, ySize, color, adjOverlapNorth, skyLightTop, blockLight, topData, bottomData); } else { - makeAdjVerticalQuad(builder, adjDataNorth[0], ELodDirection.NORTH, x, y, z, (short) (xSize / 2), ySize, + makeAdjVerticalQuad(builder, adjDataNorth[0], ELodDirection.NORTH, x, minY, z, (short) (xSize / 2), ySize, color, adjOverlapNorth, skyLightTop, blockLight, topData, bottomData); - makeAdjVerticalQuad(builder, adjDataNorth[1], ELodDirection.NORTH, (short) (x + xSize / 2), y, z, (short) (xSize / 2), ySize, + makeAdjVerticalQuad(builder, adjDataNorth[1], ELodDirection.NORTH, (short) (x + xSize / 2), minY, z, (short) (xSize / 2), ySize, color, adjOverlapNorth, skyLightTop, blockLight, topData, bottomData); } @@ -149,21 +149,21 @@ public class ColumnBox if (adjDataSouth == null) { if (!isTransparent || overVoid) - builder.addQuadAdj(ELodDirection.SOUTH, x, y, maxZ, xSize, ySize, color, (byte) 15, blockLight); + builder.addQuadAdj(ELodDirection.SOUTH, x, minY, maxZ, xSize, ySize, color, (byte) 15, blockLight); } else if (adjDataSouth.length == 1) { - makeAdjVerticalQuad(builder, adjDataSouth[0], ELodDirection.SOUTH, x, y, maxZ, xSize, ySize, + makeAdjVerticalQuad(builder, adjDataSouth[0], ELodDirection.SOUTH, x, minY, maxZ, xSize, ySize, color, adjOverlapSouth, skyLightTop, blockLight, topData, bottomData); } else { - makeAdjVerticalQuad(builder, adjDataSouth[0], ELodDirection.SOUTH, x, y, maxZ, (short) (xSize / 2), ySize, + makeAdjVerticalQuad(builder, adjDataSouth[0], ELodDirection.SOUTH, x, minY, maxZ, (short) (xSize / 2), ySize, color, adjOverlapSouth, skyLightTop, blockLight, topData, bottomData); - makeAdjVerticalQuad(builder, adjDataSouth[1], ELodDirection.SOUTH, (short) (x + xSize / 2), y, maxZ, (short) (xSize / 2), ySize, + makeAdjVerticalQuad(builder, adjDataSouth[1], ELodDirection.SOUTH, (short) (x + xSize / 2), minY, maxZ, (short) (xSize / 2), ySize, color, adjOverlapSouth, skyLightTop, blockLight, topData, bottomData); } @@ -176,25 +176,25 @@ public class ColumnBox if (adjDataWest == null) { if (!isTransparent || overVoid) - builder.addQuadAdj(ELodDirection.WEST, x, y, z, zSize, ySize, color, (byte) 15, blockLight); + builder.addQuadAdj(ELodDirection.WEST, x, minY, z, zSize, ySize, color, (byte) 15, blockLight); } else if (adjDataWest.length == 1) { - makeAdjVerticalQuad(builder, adjDataWest[0], ELodDirection.WEST, x, y, z, zSize, ySize, + makeAdjVerticalQuad(builder, adjDataWest[0], ELodDirection.WEST, x, minY, z, zSize, ySize, color, adjOverlapWest, skyLightTop, blockLight, topData, bottomData); } else { - makeAdjVerticalQuad(builder, adjDataWest[0], ELodDirection.WEST, x, y, z, (short) (zSize / 2), ySize, + makeAdjVerticalQuad(builder, adjDataWest[0], ELodDirection.WEST, x, minY, z, (short) (zSize / 2), ySize, color, adjOverlapWest, skyLightTop, blockLight, topData, bottomData); - makeAdjVerticalQuad(builder, adjDataWest[1], ELodDirection.WEST, x, y, (short) (z + zSize / 2), (short) (zSize / 2), ySize, + makeAdjVerticalQuad(builder, adjDataWest[1], ELodDirection.WEST, x, minY, (short) (z + zSize / 2), (short) (zSize / 2), ySize, color, adjOverlapWest, skyLightTop, blockLight, topData, bottomData); } } - + //EAST face vertex creation { ColumnArrayView[] adjDataEast = adjData[ELodDirection.EAST.ordinal() - 2]; @@ -202,20 +202,20 @@ public class ColumnBox if (adjData[ELodDirection.EAST.ordinal() - 2] == null) { if (!isTransparent || overVoid) - builder.addQuadAdj(ELodDirection.EAST, maxX, y, z, zSize, ySize, color, (byte) 15, blockLight); + builder.addQuadAdj(ELodDirection.EAST, maxX, minY, z, zSize, ySize, color, (byte) 15, blockLight); } else if (adjDataEast.length == 1) { - makeAdjVerticalQuad(builder, adjDataEast[0], ELodDirection.EAST, maxX, y, z, zSize, ySize, + makeAdjVerticalQuad(builder, adjDataEast[0], ELodDirection.EAST, maxX, minY, z, zSize, ySize, color, adjOverlapEast, skyLightTop, blockLight, topData, bottomData); } else { - makeAdjVerticalQuad(builder, adjDataEast[0], ELodDirection.EAST, maxX, y, z, (short) (zSize / 2), ySize, + makeAdjVerticalQuad(builder, adjDataEast[0], ELodDirection.EAST, maxX, minY, z, (short) (zSize / 2), ySize, color, adjOverlapEast, skyLightTop, blockLight, topData, bottomData); - makeAdjVerticalQuad(builder, adjDataEast[1], ELodDirection.EAST, maxX, y, (short) (z + zSize / 2), (short) (zSize / 2), ySize, + makeAdjVerticalQuad(builder, adjDataEast[1], ELodDirection.EAST, maxX, minY, (short) (z + zSize / 2), (short) (zSize / 2), ySize, color, adjOverlapEast, skyLightTop, blockLight, topData, bottomData); } @@ -225,7 +225,7 @@ public class ColumnBox // the overlap color can be used to see faces that shouldn't be rendered private static void makeAdjVerticalQuad( LodQuadBuilder builder, ColumnArrayView adjColumnView, ELodDirection direction, - short x, short y, short z, short horizontalWidth, short upDownWidth, + short x, short yMin, short z, short horizontalWidth, short ySize, int color, int debugOverlapColor, byte skyLightTop, byte blockLight, long topData, long bottomData) { @@ -234,19 +234,19 @@ public class ColumnBox if (adjColumnView == null || adjColumnView.size == 0 || RenderDataPointUtil.isVoid(adjColumnView.get(0))) { // there isn't any data adjacent to this LOD, add the vertical quad - builder.addQuadAdj(direction, x, y, z, horizontalWidth, upDownWidth, color, (byte) 15, blockLight); + builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, ySize, color, (byte) 15, blockLight); return; } - int inputMaxHeight = y + upDownWidth; + int yMax = yMin + ySize; int adjIndex; boolean firstFace = true; boolean inputAboveAdjLods = true; short previousAdjDepth = -1; byte nextTopSkyLight = skyLightTop; - boolean isTransparent = ColorUtil.getAlpha(color) < 255 && LodRenderer.transparencyEnabled; + boolean inputTransparent = ColorUtil.getAlpha(color) < 255 && LodRenderer.transparencyEnabled; boolean lastAdjWasTransparent = false; @@ -262,42 +262,42 @@ public class ColumnBox // Add adjacent faces if this LOD is surrounded by transparent LODs // (prevents invisible sides underwater) int adjCount = adjColumnView.size(); - for (adjIndex = 0; + for (adjIndex = 0; // iterates top down adjIndex < adjCount && RenderDataPointUtil.doesDataPointExist(adjColumnView.get(adjIndex)) && !RenderDataPointUtil.isVoid(adjColumnView.get(adjIndex)); adjIndex++) { long adjPoint = adjColumnView.get(adjIndex); - boolean isAdjTransparent = RenderDataPointUtil.getAlpha(adjPoint) < 255 && LodRenderer.transparencyEnabled; + boolean adjTransparent = RenderDataPointUtil.getAlpha(adjPoint) < 255 && LodRenderer.transparencyEnabled; // continue if this data point is transparent or the adjacent point is not - if (isTransparent || !isAdjTransparent) // TODO isTransparent may be unnecessary + if (inputTransparent || !adjTransparent) // TODO inputIsTransparent may be unnecessary { - short adjDepth = RenderDataPointUtil.getDepth(adjPoint); - short adjHeight = RenderDataPointUtil.getHeight(adjPoint); + short adjYMin = RenderDataPointUtil.getYMin(adjPoint); + short adjYMax = RenderDataPointUtil.getYMax(adjPoint); // if fake transparency is enabled, allow for 1 block of transparency, // everything under that should be opaque if (LodRenderer.transparencyEnabled && LodRenderer.fakeOceanFloor) { - if (lastAdjWasTransparent && !isAdjTransparent) + if (lastAdjWasTransparent && !adjTransparent) { - adjHeight = (short) (RenderDataPointUtil.getHeight(adjColumnView.get(adjIndex - 1)) - 1); + adjYMax = (short) (RenderDataPointUtil.getYMax(adjColumnView.get(adjIndex - 1)) - 1); } - else if (isAdjTransparent && (adjIndex+1) < adjCount) + else if (adjTransparent && (adjIndex+1) < adjCount) { if (RenderDataPointUtil.getAlpha(adjColumnView.get(adjIndex + 1)) == 255) { - adjDepth = (short) (adjHeight - 1); + adjYMin = (short) (adjYMax - 1); } } } - if (inputMaxHeight <= adjDepth) + if (yMax <= adjYMin) { // the adjacent LOD is above the input LOD and won't affect its rendering, // skip to the next adjacent @@ -306,27 +306,62 @@ public class ColumnBox inputAboveAdjLods = false; - if (adjHeight < y) // TODO why not adjMaxHeight? + if (adjYMax < yMin) { // the adjacent LOD is below the input LOD - // FIXME both of these methods cause black LODs when next to deep/dark water + // getting the skylight is more complicated + // since LODs can be adjacent to water, which changes how skylight works + byte skyLight; + if (adjIndex == 0) + { + // this adj LOD is at the highest position, + // its sky lighting won't be affected by anything above it + skyLight = RenderDataPointUtil.getLightSky(adjPoint); + } + else + { + // TODO improve the comments here, this is a bit confusing + long aboveAdjPoint = adjColumnView.get(adjIndex-1); + if (RenderDataPointUtil.getAlpha(aboveAdjPoint) != 255) + { + // above adjacent LOD is transparent... + + boolean inputMaxHigherThanAboveAdj = yMax > RenderDataPointUtil.getYMax(aboveAdjPoint); + if (inputMaxHigherThanAboveAdj) + { + // ...and higher than the input yMax, + // use its sky light + skyLight = RenderDataPointUtil.getLightSky(aboveAdjPoint); + } + else + { + // ...and at or below the input yMax, + skyLight = RenderDataPointUtil.getLightSky(adjPoint); + } + } + else + { + // LOD above adjacent is opaque, use the adj LOD's skylight + skyLight = RenderDataPointUtil.getLightSky(adjPoint); + } + } + + if (firstFace) { - builder.addQuadAdj(direction, x, y, z, horizontalWidth, upDownWidth, color, RenderDataPointUtil.getLightSky(adjPoint), - blockLight); + builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, ySize, color, skyLight, blockLight); } else { - // Now: adjMaxHeight < y < previousAdjDepth < inputMaxHeight + // Now: adjMaxHeight < y < previousAdjDepth < yMax if (previousAdjDepth == -1) { // TODO why is this an error? throw new RuntimeException("Loop error"); } - builder.addQuadAdj(direction, x, y, z, horizontalWidth, (short) (previousAdjDepth - y), color, - RenderDataPointUtil.getLightSky(adjPoint), blockLight); + builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, (short) (previousAdjDepth - yMin), color, skyLight, blockLight); previousAdjDepth = -1; } @@ -337,46 +372,46 @@ public class ColumnBox } - if (adjDepth <= y) + if (adjYMin <= yMin) { // the adjacent LOD's base is at or below the input's base - if (inputMaxHeight <= adjHeight) + if (yMax <= adjYMax) { // The input face is completely inside the adj's face, don't render it if (debugOverlapColor != 0) { - builder.addQuadAdj(direction, x, y, z, horizontalWidth, upDownWidth, debugOverlapColor, (byte) 15, (byte) 15); + builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, ySize, debugOverlapColor, (byte) 15, (byte) 15); } } else { // the adj data intersects the lower part of the input data, don't render below the intersection - if (adjHeight > y && debugOverlapColor != 0) + if (adjYMax > yMin && debugOverlapColor != 0) { - builder.addQuadAdj(direction, x, y, z, horizontalWidth, (short) (adjHeight - y), debugOverlapColor, (byte) 15, (byte) 15); + builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, (short) (adjYMax - yMin), debugOverlapColor, (byte) 15, (byte) 15); } - // if this is the only face, use the inputMaxHeight and break, + // if this is the only face, use the yMax and break, // if there was another face finish the last one and then break if (firstFace) { - builder.addQuadAdj(direction, x, adjHeight, z, horizontalWidth, (short) (inputMaxHeight - adjHeight), color, + builder.addQuadAdj(direction, x, adjYMax, z, horizontalWidth, (short) (yMax - adjYMax), color, RenderDataPointUtil.getLightSky(adjPoint), blockLight); } else { - // Now: depth <= y <= height <= previousAdjDepth < inputMaxHeight + // Now: depth <= y <= height <= previousAdjDepth < yMax if (previousAdjDepth == -1) { // TODO why is this an error? throw new RuntimeException("Loop error"); } - if (previousAdjDepth > adjHeight) + if (previousAdjDepth > adjYMax) { - builder.addQuadAdj(direction, x, adjHeight, z, horizontalWidth, (short) (previousAdjDepth - adjHeight), color, + builder.addQuadAdj(direction, x, adjYMax, z, horizontalWidth, (short) (previousAdjDepth - adjYMax), color, RenderDataPointUtil.getLightSky(adjPoint), blockLight); } previousAdjDepth = -1; @@ -391,43 +426,43 @@ public class ColumnBox - // In here always true: y < adjDepth < inputMaxHeight - // _________________&&: y < ________ (height and inputMaxHeight) + // In here always true: y < adjYMin < yMax + // _________________&&: y < ________ (height and yMax) - if (inputMaxHeight <= adjHeight) + if (adjYMax >= yMax) { - // Basically: y _______ < inputMaxHeight <= height - // _______&&: y < depth < inputMaxHeight + // Basically: y _______ < yMax <= height + // _______&&: y < depth < yMax // the adj data intersects the higher part of the current data if (debugOverlapColor != 0) { - builder.addQuadAdj(direction, x, adjDepth, z, horizontalWidth, (short) (inputMaxHeight - adjDepth), debugOverlapColor, (byte) 15, (byte) 15); + builder.addQuadAdj(direction, x, adjYMin, z, horizontalWidth, (short) (yMax - adjYMin), debugOverlapColor, (byte) 15, (byte) 15); } // we start the creation of a new face } else { - // Otherwise: y < _____ height < inputMaxHeight - // _______&&: y < depth ______ < inputMaxHeight + // Otherwise: y < _____ height < yMax + // _______&&: y < depth ______ < yMax if (debugOverlapColor != 0) { - builder.addQuadAdj(direction, x, adjDepth, z, horizontalWidth, (short) (adjHeight - adjDepth), debugOverlapColor, (byte) 15, (byte) 15); + builder.addQuadAdj(direction, x, adjYMin, z, horizontalWidth, (short) (adjYMax - adjYMin), debugOverlapColor, (byte) 15, (byte) 15); } if (firstFace) { - builder.addQuadAdj(direction, x, adjHeight, z, horizontalWidth, (short) (inputMaxHeight - adjHeight), color, + builder.addQuadAdj(direction, x, adjYMax, z, horizontalWidth, (short) (yMax - adjYMax), color, RenderDataPointUtil.getLightSky(adjPoint), blockLight); } else { - // Now: y < depth < height <= previousAdjDepth < inputMaxHeight + // Now: y < depth < height <= previousAdjDepth < yMax if (previousAdjDepth == -1) throw new RuntimeException("Loop error"); - if (previousAdjDepth > adjHeight) + if (previousAdjDepth > adjYMax) { - builder.addQuadAdj(direction, x, adjHeight, z, horizontalWidth, (short) (previousAdjDepth - adjHeight), color, + builder.addQuadAdj(direction, x, adjYMax, z, horizontalWidth, (short) (previousAdjDepth - adjYMax), color, RenderDataPointUtil.getLightSky(adjPoint), blockLight); } previousAdjDepth = -1; @@ -436,7 +471,7 @@ public class ColumnBox // set next top as current depth - previousAdjDepth = adjDepth; + previousAdjDepth = adjYMin; firstFace = false; nextTopSkyLight = skyLightTop; @@ -445,7 +480,7 @@ public class ColumnBox nextTopSkyLight = RenderDataPointUtil.getLightSky(adjColumnView.get(adjIndex + 1)); } - lastAdjWasTransparent = isAdjTransparent; + lastAdjWasTransparent = adjTransparent; } } @@ -455,12 +490,12 @@ public class ColumnBox { // the input LOD is above all adjacent LODs and won't be affected // by them, add the vertical quad using the input's lighting and height - builder.addQuadAdj(direction, x, y, z, horizontalWidth, upDownWidth, color, skyLightTop, blockLight); + builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, ySize, color, skyLightTop, blockLight); } else if (previousAdjDepth != -1) { // We need to finish the last quad. - builder.addQuadAdj(direction, x, y, z, horizontalWidth, (short) (previousAdjDepth - y), color, nextTopSkyLight, blockLight); + builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, (short) (previousAdjDepth - yMin), color, nextTopSkyLight, blockLight); } } } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBufferBuilder.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBufferBuilder.java index 95ab9852e..f0e7c3144 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBufferBuilder.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBufferBuilder.java @@ -163,9 +163,9 @@ public class ColumnRenderBufferBuilder // can be uncommented to limit which section positions are build and thus, rendered // useful when debugging a specific section // if (renderSource.sectionPos.sectionDetailLevel == 6 -// && renderSource.sectionPos.sectionZ == 0 && renderSource.sectionPos.sectionX == 3) +// && renderSource.sectionPos.sectionZ == 0 && renderSource.sectionPos.sectionX == 0) // { -// int test = 4; +// int test = 0; // } // else // { @@ -198,7 +198,7 @@ public class ColumnRenderBufferBuilder ColumnRenderSource.DebugSourceFlag debugSourceFlag = renderSource.debugGetFlag(x, z); - ColumnArrayView[][] adjData = new ColumnArrayView[4][]; + ColumnArrayView[][] adjColumnViews = new ColumnArrayView[4][]; // We extract the adj data in the four cardinal direction // we first reset the adjShadeDisabled. This is used to disable the shade on the @@ -272,14 +272,14 @@ public class ColumnRenderBufferBuilder if (adjDetailLevel == detailLevel || adjDetailLevel > detailLevel) { - adjData[lodDirection.ordinal() - 2] = new ColumnArrayView[1]; - adjData[lodDirection.ordinal() - 2][0] = adjRenderSource.getVerticalDataPointView(xAdj, zAdj); + adjColumnViews[lodDirection.ordinal() - 2] = new ColumnArrayView[1]; + adjColumnViews[lodDirection.ordinal() - 2][0] = adjRenderSource.getVerticalDataPointView(xAdj, zAdj); } else { - adjData[lodDirection.ordinal() - 2] = new ColumnArrayView[2]; - adjData[lodDirection.ordinal() - 2][0] = adjRenderSource.getVerticalDataPointView(xAdj, zAdj); - adjData[lodDirection.ordinal() - 2][1] = adjRenderSource.getVerticalDataPointView( + adjColumnViews[lodDirection.ordinal() - 2] = new ColumnArrayView[2]; + adjColumnViews[lodDirection.ordinal() - 2][0] = adjRenderSource.getVerticalDataPointView(xAdj, zAdj); + adjColumnViews[lodDirection.ordinal() - 2][1] = adjRenderSource.getVerticalDataPointView( xAdj + (lodDirection.getAxis() == ELodDirection.Axis.X ? 0 : 1), zAdj + (lodDirection.getAxis() == ELodDirection.Axis.Z ? 0 : 1)); } @@ -296,6 +296,12 @@ public class ColumnRenderBufferBuilder // We only stop when we find a block that is void or non-existing block for (int i = 0; i < columnRenderData.size(); i++) { + // can be uncommented to limit which vertical LOD is generated +// if (i != 0) +// { +// continue; +// } + long data = columnRenderData.get(i); // If the data is not render-able (Void or non-existing) we stop since there is // no data left in this position @@ -304,10 +310,10 @@ public class ColumnRenderBufferBuilder break; } - long adjDataTop = (i - 1) >= 0 ? columnRenderData.get(i - 1) : RenderDataPointUtil.EMPTY_DATA; - long adjDataBot = (i + 1) < columnRenderData.size() ? columnRenderData.get(i + 1) : RenderDataPointUtil.EMPTY_DATA; + long topDataPoint = (i - 1) >= 0 ? columnRenderData.get(i - 1) : RenderDataPointUtil.EMPTY_DATA; + long bottomDataPoint = (i + 1) < columnRenderData.size() ? columnRenderData.get(i + 1) : RenderDataPointUtil.EMPTY_DATA; - CubicLodTemplate.addLodToBuffer(data, adjDataTop, adjDataBot, adjData, detailLevel, + CubicLodTemplate.addLodToBuffer(data, topDataPoint, bottomDataPoint, adjColumnViews, detailLevel, x, z, quadBuilder, debugMode, debugSourceFlag); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/CubicLodTemplate.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/CubicLodTemplate.java index aa8ca2013..dea4ae9e8 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/CubicLodTemplate.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/CubicLodTemplate.java @@ -38,7 +38,7 @@ public class CubicLodTemplate { public static void addLodToBuffer( - long data, long topData, long bottomData, ColumnArrayView[][] adjData, + long data, long topData, long bottomData, ColumnArrayView[][] adjColumnViews, byte detailLevel, int offsetPosX, int offsetOosZ, LodQuadBuilder quadBuilder, EDebugRendering debugging, ColumnRenderSource.DebugSourceFlag debugSource) { @@ -46,15 +46,15 @@ public class CubicLodTemplate short width = (short) BitShiftUtil.powerOfTwo(detailLevel); short x = (short) blockOffsetPos.x; - short y = RenderDataPointUtil.getDepth(data); + short yMin = RenderDataPointUtil.getYMin(data); short z = (short) (short) blockOffsetPos.z; - short yHeight = (short) (RenderDataPointUtil.getHeight(data) - y); + short ySize = (short) (RenderDataPointUtil.getYMax(data) - yMin); - if (yHeight == 0) + if (ySize == 0) { return; } - else if (yHeight < 0) + else if (ySize < 0) { throw new IllegalArgumentException("Negative y size for the data! Data: " + RenderDataPointUtil.toString(data)); } @@ -112,11 +112,11 @@ public class CubicLodTemplate ColumnBox.addBoxQuadsToBuilder( quadBuilder, // buffer - width, yHeight, width, // setWidth - x, y, z, // setOffset + width, ySize, width, // setWidth + x, yMin, z, // setOffset color, // setColor RenderDataPointUtil.getLightSky(data), // setSkyLights fullBright ? 15 : RenderDataPointUtil.getLightBlock(data), // setBlockLights - topData, bottomData, adjData); // setAdjData + topData, bottomData, adjColumnViews); // setAdjData } } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodQuadBuilder.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodQuadBuilder.java index e2799975a..075fa82c8 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodQuadBuilder.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodQuadBuilder.java @@ -273,7 +273,8 @@ public class LodQuadBuilder throw new IllegalArgumentException("Invalid Axis enum: " + axis); } putVertex(bb, (short) (quad.x + dx), (short) (quad.y + dy), (short) (quad.z + dz), - quad.hasError ? ColorUtil.RED : quad.color, +// quad.hasError ? ColorUtil.RED : quad.color, // TODO add debug config + quad.color, quad.hasError ? 15 : quad.skyLight, quad.hasError ? 15 : quad.blockLight, mx, my, mz); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/util/RenderDataPointUtil.java b/core/src/main/java/com/seibel/distanthorizons/core/util/RenderDataPointUtil.java index aff391b2a..d599f35e1 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/util/RenderDataPointUtil.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/util/RenderDataPointUtil.java @@ -182,9 +182,10 @@ public class RenderDataPointUtil return dataPoint & ~(HEIGHT_SHIFTED_MASK | DEPTH_SHIFTED_MASK) | height | depth; } - public static short getHeight(long dataPoint) { return (short) ((dataPoint >>> HEIGHT_SHIFT) & HEIGHT_MASK); } - /** AKA the starting Y value above the parent {@link DhLevel#getMinY()} TODO is this correct? */ - public static short getDepth(long dataPoint) { return (short) ((dataPoint >>> DEPTH_SHIFT) & DEPTH_MASK); } + /** AKA the ending/top/highest Y value above {@link DhLevel#getMinY()} */ + public static short getYMax(long dataPoint) { return (short) ((dataPoint >>> HEIGHT_SHIFT) & HEIGHT_MASK); } + /** AKA the starting/bottom/lowest Y value above {@link DhLevel#getMinY()} */ + public static short getYMin(long dataPoint) { return (short) ((dataPoint >>> DEPTH_SHIFT) & DEPTH_MASK); } public static short getAlpha(long dataPoint) { return (short) ((((dataPoint >>> ALPHA_SHIFT) & ALPHA_MASK) << ALPHA_DOWNSIZE_SHIFT) | 0b1111); } public static short getRed(long dataPoint) { return (short) ((dataPoint >>> RED_SHIFT) & RED_MASK); } @@ -235,14 +236,14 @@ public class RenderDataPointUtil } else { - return "H:" + getHeight(dataPoint) + - " D:" + getDepth(dataPoint) + + return "Y+:" + getYMax(dataPoint) + + " Y-:" + getYMin(dataPoint) + " argb:" + getAlpha(dataPoint) + " " + getRed(dataPoint) + " " + getBlue(dataPoint) + " " + getGreen(dataPoint) + - " BL/SL:" + getLightBlock(dataPoint) + " " + - getLightSky(dataPoint) + + " BL:" + getLightBlock(dataPoint) + + " SL:" +getLightSky(dataPoint) + " G:" + getGenerationMode(dataPoint); } } @@ -303,8 +304,8 @@ public class RenderDataPointUtil boolean allDefault; long singleData; - short depth; - short height; + short yMin; + short yMax; int count = 0; int i; int ii; @@ -360,8 +361,8 @@ public class RenderDataPointUtil boolean connected = true; int newHeight = -10000; int newDepth = -10000; - int tempHeight; - int tempDepth; + int tempYMax; + int tempYMin; while (connected) { Arrays.fill(increaseIndex, false); @@ -372,34 +373,34 @@ public class RenderDataPointUtil tempData = sourceData.get(index * inputVerticalSize + indices[index]); if (!RenderDataPointUtil.isVoid(tempData) && RenderDataPointUtil.doesDataPointExist(tempData)) { - tempHeight = RenderDataPointUtil.getHeight(tempData); - tempDepth = RenderDataPointUtil.getDepth(tempData); - if (tempDepth >= newHeight) + tempYMax = RenderDataPointUtil.getYMax(tempData); + tempYMin = RenderDataPointUtil.getYMin(tempData); + if (tempYMin >= newHeight) { //First case //the column we are checking is higher than the current column - newDepth = tempDepth; - newHeight = tempHeight; + newDepth = tempYMin; + newHeight = tempYMax; Arrays.fill(increaseIndex, false); Arrays.fill(indexHandled, false); increaseIndex[index] = true; indexHandled[index] = true; } - else if ((tempDepth >= newDepth) && (tempHeight <= newHeight)) + else if ((tempYMin >= newDepth) && (tempYMax <= newHeight)) { //the column we are checking is contained in the current column //we simply increase this index increaseIndex[index] = true; indexHandled[index] = true; } - else if (tempHeight > newHeight && tempDepth <= newDepth) + else if (tempYMax > newHeight && tempYMin <= newDepth) { - newDepth = tempDepth; - newHeight = tempHeight; + newDepth = tempYMin; + newHeight = tempYMax; increaseIndex[index] = true; indexHandled[index] = true; } - else if (tempHeight > newDepth && tempHeight <= newHeight) + else if (tempYMax > newDepth && tempYMax <= newHeight) { //the column we are checking touches the current column from the bottom //for this reason we extend what's below @@ -408,17 +409,17 @@ public class RenderDataPointUtil //this index if (!indexHandled[index]) { - newDepth = tempDepth; + newDepth = tempYMin; increaseIndex[index] = true; indexHandled[index] = true; } } - else if (tempDepth < newHeight && tempDepth > newDepth) + else if (tempYMin < newHeight && tempYMin > newDepth) { //the column we are checking touches the current column from the top //for this reason we extend the top - newHeight = tempHeight; + newHeight = tempYMax; increaseIndex[index] = true; } } @@ -523,11 +524,11 @@ public class RenderDataPointUtil { //We firstly collect height and depth data //this will be added to each realtive long DataPoint - height = heightAndDepth[j * 2]; - depth = heightAndDepth[j * 2 + 1]; + yMax = heightAndDepth[j * 2]; + yMin = heightAndDepth[j * 2 + 1]; //if both height and depth are at 0 then we finished - if ((depth == 0 && height == 0) || j >= heightAndDepth.length / 2) + if ((yMin == 0 && yMax == 0) || j >= heightAndDepth.length / 2) { break; } @@ -556,8 +557,8 @@ public class RenderDataPointUtil if (doesDataPointExist(singleData) && !isVoid(singleData)) { dataIndexesCache[index]++; - if ((depth <= getDepth(singleData) && getDepth(singleData) < height) - || (depth < getHeight(singleData) && getHeight(singleData) <= height)) + if ((yMin <= getYMin(singleData) && getYMin(singleData) < yMax) + || (yMin < getYMax(singleData) && getYMax(singleData) <= yMax)) { data = singleData; break; @@ -607,7 +608,7 @@ public class RenderDataPointUtil // add simplification at the end due to color //} - output.set(j, createDataPoint(tempAlpha, (int) Math.sqrt(tempRed), (int) Math.sqrt(tempGreen), (int) Math.sqrt(tempBlue), height, depth, tempLightSky, tempLightBlock, genMode)); + output.set(j, createDataPoint(tempAlpha, (int) Math.sqrt(tempRed), (int) Math.sqrt(tempGreen), (int) Math.sqrt(tempBlue), yMax, yMin, tempLightSky, tempLightBlock, genMode)); } }