Add unexplored fog

This commit is contained in:
James Seibel
2025-09-06 10:54:08 -05:00
parent 9857eb337f
commit 71f1dce956
3 changed files with 107 additions and 30 deletions
@@ -19,7 +19,9 @@
package com.seibel.distanthorizons.core.level;
import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiChunkModifiedEvent;
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading;
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
import com.seibel.distanthorizons.core.file.fullDatafile.DelayedFullDataSourceSaveCache;
import com.seibel.distanthorizons.core.generation.DhLightingEngine;
@@ -29,6 +31,7 @@ import com.seibel.distanthorizons.core.pos.DhSectionPos;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
import com.seibel.distanthorizons.core.render.renderer.generic.CloudRenderHandler;
import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer;
import com.seibel.distanthorizons.core.render.renderer.generic.GenericRenderObjectFactory;
import com.seibel.distanthorizons.core.sql.dto.BeaconBeamDTO;
import com.seibel.distanthorizons.core.sql.dto.ChunkHashDTO;
import com.seibel.distanthorizons.core.sql.repo.AbstractDhRepo;
@@ -38,6 +41,7 @@ import com.seibel.distanthorizons.core.util.KeyedLockContainer;
import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
import com.seibel.distanthorizons.coreapi.ModInfo;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.Nullable;
@@ -73,13 +77,15 @@ public abstract class AbstractDhLevel implements IDhLevel
@Nullable
protected CloudRenderHandler cloudRenderHandler;
private IDhApiRenderableBoxGroup unexploredFogRenderableBoxGroup;
//=============//
// constructor //
//=============//
protected AbstractDhLevel() { }
protected AbstractDhLevel() { }
/**
* Creating the repos requires access to the level file, which isn't
@@ -361,6 +367,32 @@ public abstract class AbstractDhLevel implements IDhLevel
//================//
// unexplored fog //
//================//
public IDhApiRenderableBoxGroup getUnexploredFogRenderableBoxGroup()
{
if (this.unexploredFogRenderableBoxGroup == null)
{
this.unexploredFogRenderableBoxGroup = GenericRenderObjectFactory.INSTANCE.createAbsolutePositionedGroup(ModInfo.NAME+":UnexploredFog", new ArrayList<>(512));
this.unexploredFogRenderableBoxGroup.setBlockLight(LodUtil.MIN_MC_LIGHT);
this.unexploredFogRenderableBoxGroup.setSkyLight(LodUtil.MAX_MC_LIGHT);
this.unexploredFogRenderableBoxGroup.setSsaoEnabled(true);
this.unexploredFogRenderableBoxGroup.setShading(DhApiRenderableBoxGroupShading.getDefaultShaded());
GenericObjectRenderer genericRenderer = this.getGenericRenderer();
if (genericRenderer != null)
{
genericRenderer.add(this.unexploredFogRenderableBoxGroup);
}
}
return this.unexploredFogRenderableBoxGroup;
}
//================//
// base overrides //
//================//
@@ -377,6 +409,15 @@ public abstract class AbstractDhLevel implements IDhLevel
this.beaconBeamRepo.close();
}
GenericObjectRenderer genericRenderer = this.getGenericRenderer();
if (genericRenderer != null
&& this.unexploredFogRenderableBoxGroup != null)
{
genericRenderer.remove(this.unexploredFogRenderableBoxGroup.getId());
}
this.delayedFullDataSourceSaveCache.close();
}
@@ -19,6 +19,7 @@
package com.seibel.distanthorizons.core.level;
import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup;
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
import com.seibel.distanthorizons.core.file.fullDatafile.FullDataSourceProviderV2;
import com.seibel.distanthorizons.core.file.fullDatafile.GeneratedFullDataSourceProvider;
@@ -61,9 +62,14 @@ public interface IDhLevel extends AutoCloseable, GeneratedFullDataSourceProvider
void updateBeaconBeamsForChunkPos(DhChunkPos chunkPos, List<BeaconBeamDTO> activeBeamList);
void updateBeaconBeamsForSectionPos(long sectionPos, List<BeaconBeamDTO> activeBeamList);
/** @return null on server-only levels */
@Nullable
BeaconBeamRepo getBeaconBeamRepo();
/** @return null on server-only levels */
@Nullable
IDhApiRenderableBoxGroup getUnexploredFogRenderableBoxGroup();
FullDataSourceProviderV2 getFullDataProvider();
ISaveStructure getSaveStructure();
@@ -21,7 +21,6 @@ package com.seibel.distanthorizons.core.render;
import com.google.common.base.Suppliers;
import com.google.common.cache.Cache;
import com.seibel.distanthorizons.api.DhApi;
import com.seibel.distanthorizons.api.enums.rendering.EDhApiBlockMaterial;
import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3d;
@@ -45,14 +44,12 @@ import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable;
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.ColumnRenderBuffer;
import com.seibel.distanthorizons.core.render.renderer.DebugRenderer;
import com.seibel.distanthorizons.core.render.renderer.generic.BeaconRenderHandler;
import com.seibel.distanthorizons.core.render.renderer.generic.RenderableBoxGroup;
import com.seibel.distanthorizons.core.sql.dto.BeaconBeamDTO;
import com.seibel.distanthorizons.core.sql.repo.BeaconBeamRepo;
import com.seibel.distanthorizons.core.util.KeyedLockContainer;
import com.seibel.distanthorizons.core.util.threading.PriorityTaskPicker;
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.coreapi.ModInfo;
import com.seibel.distanthorizons.coreapi.util.MathUtil;
import it.unimi.dsi.fastutil.longs.LongArrayList;
import org.apache.logging.log4j.Logger;
@@ -88,7 +85,7 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
private final Cache<Long, CachedColumnRenderSource> cachedRenderSourceByPos;
private final AtomicInteger uploadTaskCountRef;
private final IDhApiRenderableBoxGroup fogRenderableBoxGroup;
private final DhApiRenderableBox unexploredFogRenderableBox;
/**
* contains the list of beacons currently being rendered in this section
@@ -162,35 +159,40 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
this.fullDataSourceProvider = fullDataSourceProvider;
this.uploadTaskCountRef = uploadTaskCountRef;
this.beaconRenderHandler = this.quadTree.beaconRenderHandler;
this.beaconBeamRepo = this.level.getBeaconBeamRepo();
this.unexploredFogRenderableBox = this.createUnexploredFogRenderableBox();
DebugRenderer.register(this, Config.Client.Advanced.Debugging.DebugWireframe.showRenderSectionStatus);
}
private DhApiRenderableBox createUnexploredFogRenderableBox()
{
// width
float fogWidthInBlocks = (float) DhSectionPos.getBlockWidth(this.pos);
// random height
// pseudo random height (should be consistent for a given position)
int fogHeightRange = (int) ((this.level.getMaxY() - this.level.getMinY()) * 0.25);
int halfFogHeightRange = fogHeightRange / 2;
float randomHeightModifier = (float) (DhSectionPos.hashCode(this.pos) % fogHeightRange) - halfFogHeightRange;
// random color
// pseudo random color (should be consistent for a given position)
int randomColorModifier = (DhSectionPos.hashCode(this.pos) % 30) - 15;
int randomGrayColorValue = 90 + randomColorModifier;
randomGrayColorValue = MathUtil.clamp(1, randomGrayColorValue, 256); // clamp to prevent accidental out-of-range colors
ArrayList<DhApiRenderableBox> boxList = new ArrayList<>();
boxList.add(new DhApiRenderableBox(
new DhApiVec3d(0,0,0),
new DhApiVec3d(fogWidthInBlocks, this.level.getMaxY() + randomHeightModifier, fogWidthInBlocks),
new Color(randomGrayColorValue, randomGrayColorValue, randomGrayColorValue), EDhApiBlockMaterial.UNKNOWN));
this.fogRenderableBoxGroup = new RenderableBoxGroup(
ModInfo.NAME + ":UnexploredFog",
new DhApiVec3d(DhSectionPos.getMinCornerBlockX(this.pos), level.getMinY(), DhSectionPos.getMinCornerBlockZ(this.pos)),
boxList, true);
this.beaconRenderHandler = this.quadTree.beaconRenderHandler;
this.beaconBeamRepo = this.level.getBeaconBeamRepo();
return new DhApiRenderableBox(
// min pos
new DhApiVec3d(DhSectionPos.getMinCornerBlockX(this.pos),
0,
DhSectionPos.getMinCornerBlockZ(this.pos)),
// max pos
new DhApiVec3d(DhSectionPos.getMinCornerBlockX(this.pos) + fogWidthInBlocks,
this.level.getMaxY() + randomHeightModifier,
DhSectionPos.getMinCornerBlockZ(this.pos) + fogWidthInBlocks),
new Color(randomGrayColorValue, randomGrayColorValue, randomGrayColorValue), EDhApiBlockMaterial.UNKNOWN);
DebugRenderer.register(this, Config.Client.Advanced.Debugging.DebugWireframe.showRenderSectionStatus);
}
@@ -244,6 +246,14 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
this.getAndBuildRenderDataRunnable = () ->
{
// reset the fog
this.stopRenderingUnexploredFog();
if (!this.getFullDataSourceExists())
{
// no render data is present, fill the area with "fog"
this.startRenderingUnexploredFog();
}
this.getAndRefreshRenderingBeacons();
this.getAndUploadRenderDataToGpuAsync()
.thenRun(() ->
@@ -459,19 +469,12 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
public void setRenderingEnabled(boolean enabled) { this.renderingEnabled = enabled;}
/** @see LodRenderSection#setRenderingEnabled */
public void onRenderingEnabled()
{
this.startRenderingBeacons();
if (!this.getFullDataSourceExists())
{
this.level.getGenericRenderer().add(this.fogRenderableBoxGroup);
}
}
public void onRenderingEnabled() { this.startRenderingBeacons(); }
/** @see LodRenderSection#setRenderingEnabled */
public void onRenderingDisabled()
{
this.stopRenderingBeacons();
this.level.getGenericRenderer().remove(this.fogRenderableBoxGroup.getId());
this.stopRenderingUnexploredFog();
if (Config.Client.Advanced.Debugging.DebugWireframe.showRenderSectionStatus.get())
{
@@ -666,6 +669,33 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
//================//
// unexplored fog //
//================//
private void startRenderingUnexploredFog()
{
IDhApiRenderableBoxGroup boxGroup = this.level.getUnexploredFogRenderableBoxGroup();
if (boxGroup != null) // box group will be null for server levels, that shouldn't be a problem here, but just in case
{
boxGroup.add(this.unexploredFogRenderableBox);
boxGroup.triggerBoxChange();
}
}
private void stopRenderingUnexploredFog()
{
IDhApiRenderableBoxGroup boxGroup = this.level.getUnexploredFogRenderableBoxGroup();
if (boxGroup != null) // box group will be null for server levels, that shouldn't be a problem here, but just in case
{
if (boxGroup.remove(this.unexploredFogRenderableBox))
{
boxGroup.triggerBoxChange();
}
}
}
//==============//
// base methods //
@@ -717,7 +747,7 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
this.stopRenderingBeacons();
this.level.getGenericRenderer().remove(this.fogRenderableBoxGroup.getId());
this.stopRenderingUnexploredFog();
if (this.renderBuffer != null)
{