Improve overlapped quads handling + fix minLevel being used to clamp getMaxVerticalData(), causing invalid sized containers being added to incorrect detail level slot in a region.
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
|
||||
package com.seibel.lod.core.builders.lodBuilding;
|
||||
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
@@ -287,6 +288,10 @@ public class LodBuilder
|
||||
|
||||
//ApiShared.LOGGER.info("Generate chunk: {}, {} ({}, {}) at genMode {}",
|
||||
// chunk.getChunkPosX(), chunk.getChunkPosZ(), chunk.getMinX(), chunk.getMinZ(), config.distanceGenerationMode);
|
||||
if (targetLevel != region.getMinDetailLevel()) {
|
||||
//Concurrency issues happened.
|
||||
throw new ConcurrentModificationException("Min detail level changed while writing data");
|
||||
}
|
||||
region.addChunkOfData(targetLevel,
|
||||
LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL, chunkX, targetLevel),
|
||||
LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL, chunkZ, targetLevel),
|
||||
|
||||
+8
-8
@@ -31,7 +31,7 @@ import static com.seibel.lod.core.render.LodRenderer.EVENT_LOGGER;
|
||||
* @author ?
|
||||
* @version 4-9-2022
|
||||
*/
|
||||
public class BufferQuad
|
||||
public final class BufferQuad
|
||||
{
|
||||
final short x;
|
||||
final short y;
|
||||
@@ -39,11 +39,12 @@ public class BufferQuad
|
||||
short widthEastWest;
|
||||
/** This is both North/South and Up/Down since the merging logic is the same either way */
|
||||
short widthNorthSouthOrUpDown;
|
||||
int color;
|
||||
final int color;
|
||||
final byte skyLight;
|
||||
final byte blockLight;
|
||||
final LodDirection direction;
|
||||
|
||||
|
||||
boolean hasError = false;
|
||||
|
||||
BufferQuad(short x, short y, short z, short widthEastWest, short widthNorthSouthOrUpDown,
|
||||
int color, byte skylight, byte blocklight,
|
||||
@@ -64,16 +65,13 @@ public class BufferQuad
|
||||
this.blockLight = blocklight;
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/** a rough but fast calculation */
|
||||
double calculateDistance(double relativeX, double relativeY, double relativeZ)
|
||||
{
|
||||
return Math.pow(relativeX - x, 2) + Math.pow(relativeY - y, 2) + Math.pow(relativeZ - z, 2);
|
||||
}
|
||||
|
||||
|
||||
/** compares this quad's position to the given quad */
|
||||
public int compare(BufferQuad quad, BufferMergeDirectionEnum compareDirection)
|
||||
{
|
||||
@@ -131,6 +129,7 @@ public class BufferQuad
|
||||
*/
|
||||
public boolean tryMerge(BufferQuad quad, BufferMergeDirectionEnum mergeDirection)
|
||||
{
|
||||
if (quad.hasError || this.hasError) return false;
|
||||
// only merge quads that are in the same direction
|
||||
if (direction != quad.direction)
|
||||
return false;
|
||||
@@ -244,7 +243,8 @@ public class BufferQuad
|
||||
{
|
||||
// these quads are overlapping, they can't be merged
|
||||
EVENT_LOGGER.warn("Overlapping quads detected!");
|
||||
quad.color = ColorUtil.rgbToInt(255, 0, 0);
|
||||
quad.hasError = true;
|
||||
this.hasError = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+42
-24
@@ -53,36 +53,54 @@ public class CubicLodTemplate
|
||||
}
|
||||
|
||||
int color;
|
||||
if (debugging != DebugMode.OFF && debugging != DebugMode.SHOW_WIREFRAME)
|
||||
{
|
||||
if (debugging == DebugMode.SHOW_DETAIL || debugging == DebugMode.SHOW_DETAIL_WIREFRAME)
|
||||
color = LodUtil.DEBUG_DETAIL_LEVEL_COLORS[detailLevel];
|
||||
else /// if (debugging == DebugMode.SHOW_GENMODE || debugging ==
|
||||
/// DebugMode.SHOW_GENMODE_WIREFRAME)
|
||||
color = LodUtil.DEBUG_DETAIL_LEVEL_COLORS[DataPointUtil.getGenerationMode(data)];
|
||||
}
|
||||
else
|
||||
{
|
||||
float saturationMultiplier = (float)CONFIG.client().graphics().advancedGraphics().getSaturationMultiplier();
|
||||
float brightnessMultiplier = (float)CONFIG.client().graphics().advancedGraphics().getBrightnessMultiplier();
|
||||
|
||||
if (saturationMultiplier == 1.0 && brightnessMultiplier == 1.0) {
|
||||
color = DataPointUtil.getColor(data);
|
||||
} else {
|
||||
float[] ahsv = ColorUtil.argbToAhsv(DataPointUtil.getColor(data));
|
||||
color = ColorUtil.ahsvToArgb(ahsv[0], ahsv[1], ahsv[2] * saturationMultiplier, ahsv[3] * brightnessMultiplier);
|
||||
//ApiShared.LOGGER.info("Raw color:[{}], AHSV:{}, Out color:[{}]",
|
||||
// ColorUtil.toString(DataPointUtil.getColor(data)),
|
||||
// ahsv, ColorUtil.toString(color));
|
||||
boolean fullBright = false;
|
||||
switch (debugging) {
|
||||
case OFF:
|
||||
case SHOW_WIREFRAME:
|
||||
{
|
||||
float saturationMultiplier = (float)CONFIG.client().graphics().advancedGraphics().getSaturationMultiplier();
|
||||
float brightnessMultiplier = (float)CONFIG.client().graphics().advancedGraphics().getBrightnessMultiplier();
|
||||
if (saturationMultiplier == 1.0 && brightnessMultiplier == 1.0) {
|
||||
color = DataPointUtil.getColor(data);
|
||||
} else {
|
||||
float[] ahsv = ColorUtil.argbToAhsv(DataPointUtil.getColor(data));
|
||||
color = ColorUtil.ahsvToArgb(ahsv[0], ahsv[1], ahsv[2] * saturationMultiplier, ahsv[3] * brightnessMultiplier);
|
||||
//ApiShared.LOGGER.info("Raw color:[{}], AHSV:{}, Out color:[{}]",
|
||||
// ColorUtil.toString(DataPointUtil.getColor(data)),
|
||||
// ahsv, ColorUtil.toString(color));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SHOW_DETAIL:
|
||||
case SHOW_DETAIL_WIREFRAME:
|
||||
{
|
||||
color = LodUtil.DEBUG_DETAIL_LEVEL_COLORS[detailLevel];
|
||||
fullBright = true;
|
||||
break;
|
||||
}
|
||||
case SHOW_GENMODE:
|
||||
case SHOW_GENMODE_WIREFRAME:
|
||||
{
|
||||
color = LodUtil.DEBUG_DETAIL_LEVEL_COLORS[DataPointUtil.getGenerationMode(data)];
|
||||
fullBright = true;
|
||||
break;
|
||||
}
|
||||
case SHOW_OVERLAPPING_QUADS:
|
||||
case SHOW_NON_OVERLAPPING_QUADS_WIREFRAME:
|
||||
{
|
||||
color = ColorUtil.WHITE;
|
||||
fullBright = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown debug mode: " + debugging);
|
||||
}
|
||||
|
||||
|
||||
LodBox.addBoxQuadsToBuilder(quadBuilder, // buffer
|
||||
width, dy, width, // setWidth
|
||||
x, y, z, // setOffset
|
||||
color, // setColor
|
||||
DataPointUtil.getLightSky(data), DataPointUtil.getLightBlock(data), // setLights
|
||||
DataPointUtil.getLightSky(data), // setSkyLights
|
||||
fullBright ? 15 : DataPointUtil.getLightBlock(data), // setBlockLights
|
||||
topData, botData, adjData, adjFillBlack); // setAdjData
|
||||
}
|
||||
}
|
||||
|
||||
+5
-2
@@ -306,8 +306,11 @@ public class LodQuadBuilder
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid Axis enum: " + axis);
|
||||
}
|
||||
putVertex(bb, (short) (quad.x + dx), (short) (quad.y + dy), (short) (quad.z + dz), quad.color,
|
||||
quad.skyLight, quad.blockLight, mx, my, mz);
|
||||
putVertex(bb, (short) (quad.x + dx), (short) (quad.y + dy), (short) (quad.z + dz),
|
||||
quad.hasError ? ColorUtil.RED : quad.color,
|
||||
quad.hasError ? 15 : quad.skyLight,
|
||||
quad.hasError ? 15 : quad.blockLight,
|
||||
mx, my, mz);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,13 @@ public enum DebugMode
|
||||
SHOW_GENMODE,
|
||||
|
||||
/** LOD colors are based on their gen mode, and draws in wireframe. */
|
||||
SHOW_GENMODE_WIREFRAME;
|
||||
SHOW_GENMODE_WIREFRAME,
|
||||
|
||||
/** Only draw overlapping LOD quads. */
|
||||
SHOW_OVERLAPPING_QUADS,
|
||||
|
||||
/** Only draw overlapping LOD quads, and draws in wireframe. */
|
||||
SHOW_OVERLAPPING_QUADS_WIREFRAME;
|
||||
|
||||
/** used when cycling through the different modes */
|
||||
private DebugMode next;
|
||||
@@ -55,7 +61,9 @@ public enum DebugMode
|
||||
SHOW_DETAIL.next = SHOW_DETAIL_WIREFRAME;
|
||||
SHOW_DETAIL_WIREFRAME.next = SHOW_GENMODE;
|
||||
SHOW_GENMODE.next = SHOW_GENMODE_WIREFRAME;
|
||||
SHOW_GENMODE_WIREFRAME.next = OFF;
|
||||
SHOW_GENMODE_WIREFRAME.next = SHOW_OVERLAPPING_QUADS;
|
||||
SHOW_OVERLAPPING_QUADS.next = SHOW_OVERLAPPING_QUADS_WIREFRAME;
|
||||
SHOW_OVERLAPPING_QUADS_WIREFRAME.next = OFF;
|
||||
}
|
||||
|
||||
/** returns the next debug mode */
|
||||
|
||||
@@ -294,6 +294,7 @@ public class LodDimension
|
||||
detail = DetailDistanceUtil.getDetailLevelFromDistance(minDistance);
|
||||
if (region.getMinDetailLevel() < detail) {
|
||||
if (region.needSaving) return; // FIXME: A crude attempt at lowering chance of race condition!
|
||||
if (region.isWriting.get()!=0) return;
|
||||
region.cutTree(detail);
|
||||
region.needSignalToRegenBuffer = true;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ public class LodRegion {
|
||||
private static final byte POSSIBLE_LOD = LodUtil.DETAIL_OPTIONS;
|
||||
|
||||
/** Holds the lowest (least detailed) detail level in this region */
|
||||
private byte minDetailLevel;
|
||||
private volatile byte minDetailLevel;
|
||||
public byte lastMaxDetailLevel = LodUtil.REGION_DETAIL_LEVEL;
|
||||
|
||||
/**
|
||||
@@ -161,9 +161,12 @@ public class LodRegion {
|
||||
// detailLevel changes.
|
||||
if (this.dataContainer[detailLevel] == null)
|
||||
return false;// this.dataContainer[detailLevel] = new VerticalLevelContainer(detailLevel);
|
||||
if (this.dataContainer[detailLevel].getVerticalSize() != verticalSize)
|
||||
throw new RuntimeException("Provided data's verticalSize is different from current storage's verticalSize!");
|
||||
|
||||
if (this.dataContainer[detailLevel].getVerticalSize() != verticalSize) {
|
||||
throw new RuntimeException(
|
||||
String.format("Provided data's verticalSize [%d]" +
|
||||
" is different from current storage's verticalSize [%d] at detail [%d]",
|
||||
verticalSize, this.dataContainer[detailLevel].getVerticalSize(), detailLevel));
|
||||
}
|
||||
boolean updated = this.dataContainer[detailLevel].addChunkOfData(data, posX, posZ, widthX, widthZ, override);
|
||||
//ApiShared.LOGGER.info("addChunkOfData(region:{}, level:{}, x:{}, z:{}, wx:{}, wz:{}, override:{}, updated:{})",
|
||||
// getRegionPos(), detailLevel, posX, posZ, widthX, widthZ, override, updated);
|
||||
@@ -501,7 +504,7 @@ public class LodRegion {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Updates all children.
|
||||
* <p>
|
||||
@@ -646,10 +649,10 @@ public class LodRegion {
|
||||
+ "only allows adding LevelContainers with a " + "detail level of [" + (minDetailLevel - 1) + "]");
|
||||
}
|
||||
|
||||
dataContainer[levelContainer.getDetailLevel()] = levelContainer;
|
||||
if (levelContainer.getDetailLevel() == minDetailLevel - 1)
|
||||
minDetailLevel = levelContainer.getDetailLevel();
|
||||
|
||||
dataContainer[levelContainer.getDetailLevel()] = levelContainer;
|
||||
needRecheckGenPoint = true;
|
||||
}
|
||||
|
||||
@@ -662,10 +665,9 @@ public class LodRegion {
|
||||
*/
|
||||
public void cutTree(byte detailLevel) {
|
||||
if (detailLevel > minDetailLevel) {
|
||||
minDetailLevel = detailLevel;
|
||||
for (byte detailLevelIndex = 0; detailLevelIndex < detailLevel; detailLevelIndex++)
|
||||
dataContainer[detailLevelIndex] = null;
|
||||
|
||||
minDetailLevel = detailLevel;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -250,7 +250,8 @@ public class LodRenderer
|
||||
LagSpikeCatcher drawSetPolygon = new LagSpikeCatcher();
|
||||
if (CONFIG.client().advanced().debugging().getDebugMode() == DebugMode.SHOW_DETAIL_WIREFRAME
|
||||
|| CONFIG.client().advanced().debugging().getDebugMode() == DebugMode.SHOW_GENMODE_WIREFRAME
|
||||
|| CONFIG.client().advanced().debugging().getDebugMode() == DebugMode.SHOW_WIREFRAME) {
|
||||
|| CONFIG.client().advanced().debugging().getDebugMode() == DebugMode.SHOW_WIREFRAME
|
||||
|| CONFIG.client().advanced().debugging().getDebugMode() == DebugMode.SHOW_OVERLAPPING_QUADS_WIREFRAME) {
|
||||
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_LINE);
|
||||
//GL32.glDisable(GL32.GL_CULL_FACE);
|
||||
}
|
||||
|
||||
@@ -38,6 +38,8 @@ public class ColorUtil
|
||||
public static final int BLACK = rgbToInt(0,0,0);
|
||||
public static final int WHITE = rgbToInt(255,255,255);
|
||||
public static final int TRANSPARENT = rgbToInt(0, 0, 0, 0);
|
||||
|
||||
public static final int RED = rgbToInt(255,0,0);
|
||||
|
||||
private static final IMinecraftClientWrapper MC = SingletonHandler.get(IMinecraftClientWrapper.class);
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ public class DetailDistanceUtil
|
||||
|
||||
public static int getMaxVerticalData(int detail)
|
||||
{
|
||||
return CONFIG.client().graphics().quality().getVerticalQuality().maxVerticalData[LodUtil.clamp(minDetail, detail, LodUtil.REGION_DETAIL_LEVEL)];
|
||||
return CONFIG.client().graphics().quality().getVerticalQuality().maxVerticalData[detail];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
-1
@@ -842,7 +842,10 @@ public interface ILodConfigWrapperSingleton extends IBindable
|
||||
+ " " + DebugMode.SHOW_DETAIL + ": Fake chunks color will be based on their detail level. \n"
|
||||
+ " " + DebugMode.SHOW_DETAIL_WIREFRAME + ": Fake chunks color will be based on their detail level, drawn as a wireframe. \n"
|
||||
+ " " + DebugMode.SHOW_GENMODE + ": Fake chunks color will be based on their distant generation mode. \n"
|
||||
+ " " + DebugMode.SHOW_GENMODE_WIREFRAME + ": Fake chunks color will be based on their distant generation mode, drawn as a wireframe. \n";
|
||||
+ " " + DebugMode.SHOW_GENMODE_WIREFRAME + ": Fake chunks color will be based on their distant generation mode, drawn as a wireframe. \n"
|
||||
+ " " + DebugMode.SHOW_OVERLAPPING_QUADS + ": Fake chunks will be drawn with total white, but overlapping quads will be drawn with red. \n"
|
||||
+ " " + DebugMode.SHOW_OVERLAPPING_QUADS_WIREFRAME + ": Fake chunks will be drawn with total white, \n"
|
||||
+ " but overlapping quads will be drawn with red, drawn as a wireframe. \n";
|
||||
DebugMode getDebugMode();
|
||||
void setDebugMode(DebugMode newDebugMode);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user