Fix some black sky lighting, refactor ColumnBox and RenderDataPoint
This commit is contained in:
+111
-76
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+17
-11
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+8
-8
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user