Fix beacons un-loading incorrectly in some situations
Specifically neighboring chunks updating and in some cases flying away too fast
This commit is contained in:
@@ -26,10 +26,8 @@ import com.seibel.distanthorizons.core.generation.DhLightingEngine;
|
||||
import com.seibel.distanthorizons.core.level.IDhLevel;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.logging.f3.F3Screen;
|
||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||
import com.seibel.distanthorizons.core.pos.DhBlockPos2D;
|
||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||
import com.seibel.distanthorizons.core.render.renderer.DebugRenderer;
|
||||
import com.seibel.distanthorizons.core.sql.dto.BeaconBeamDTO;
|
||||
import com.seibel.distanthorizons.core.util.TimerUtil;
|
||||
@@ -350,7 +348,7 @@ public class SharedApi
|
||||
|
||||
// get this chunk's active beacons
|
||||
List<BeaconBeamDTO> beaconBeamList = chunkWrapper.getAllActiveBeacons();
|
||||
dhLevel.ensureBeaconBeamsAtPos(DhSectionPos.encode(chunkWrapper.getChunkPos()), beaconBeamList);
|
||||
dhLevel.setBeaconBeamsForChunk(chunkWrapper.getChunkPos(), beaconBeamList);
|
||||
|
||||
|
||||
dhLevel.updateChunkAsync(chunkWrapper);
|
||||
|
||||
@@ -48,6 +48,7 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public abstract class AbstractDhLevel implements IDhLevel
|
||||
{
|
||||
@@ -199,11 +200,13 @@ public abstract class AbstractDhLevel implements IDhLevel
|
||||
}
|
||||
|
||||
|
||||
HashMap<DhBlockPos, IDhApiRenderableBoxGroup> beamRenderGroupByPos = new HashMap<>();
|
||||
HashMap<DhBlockPos, IDhApiRenderableBoxGroup> beamRenderGroupByBlockPos = new HashMap<>();
|
||||
HashMap<DhBlockPos, AtomicInteger> beamRefCountByPos = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void ensureBeaconBeamsAtPos(long pos, List<BeaconBeamDTO> newBeamList)
|
||||
public void setBeaconBeamsForChunk(DhChunkPos chunkPos, List<BeaconBeamDTO> newBeamList)
|
||||
{
|
||||
long pos = DhSectionPos.encode(chunkPos);
|
||||
if (this.beaconBeamRepo != null)
|
||||
{
|
||||
HashSet<DhBlockPos> allPosSet = new HashSet<>();
|
||||
@@ -231,6 +234,12 @@ public abstract class AbstractDhLevel implements IDhLevel
|
||||
|
||||
for (DhBlockPos beaconPos : allPosSet)
|
||||
{
|
||||
if (!chunkPos.contains(beaconPos))
|
||||
{
|
||||
// don't update beacons outside the updated chunk
|
||||
continue;
|
||||
}
|
||||
|
||||
BeaconBeamDTO existingBeam = existingBeamByPos.get(beaconPos);
|
||||
BeaconBeamDTO newBeam = newBeamByPos.get(beaconPos);
|
||||
|
||||
@@ -245,19 +254,31 @@ public abstract class AbstractDhLevel implements IDhLevel
|
||||
|
||||
IDhApiRenderableBoxGroup beaconBox = GenericObjectRenderer.INSTANCE.createForSingleBox(new DhApiRenderableBox(
|
||||
new DhApiVec3f(newBeam.pos.x, newBeam.pos.y+1, newBeam.pos.z),
|
||||
new DhApiVec3f(newBeam.pos.x+1, 2_000, newBeam.pos.z+1),
|
||||
new DhApiVec3f(newBeam.pos.x+1, 6_000, newBeam.pos.z+1),
|
||||
newBeam.color
|
||||
));
|
||||
beaconBox.setBlockLight(LodUtil.MAX_MC_LIGHT);
|
||||
beaconBox.setSkyLight(LodUtil.MAX_MC_LIGHT);
|
||||
this.beamRenderGroupByPos.put(newBeam.pos, beaconBox);
|
||||
|
||||
this.beamRenderGroupByBlockPos.put(newBeam.pos, beaconBox);
|
||||
this.beamRefCountByPos.compute(newBeam.pos, (beamPos, refCount) ->
|
||||
{
|
||||
if (refCount == null)
|
||||
{
|
||||
refCount = new AtomicInteger(0);
|
||||
}
|
||||
refCount.getAndIncrement();
|
||||
return refCount;
|
||||
});
|
||||
|
||||
GenericObjectRenderer.INSTANCE.add(beaconBox);
|
||||
}
|
||||
else if (existingBeam != null && newBeam == null)
|
||||
{
|
||||
// beam no longer exists at position, remove
|
||||
this.beaconBeamRepo.deleteWithKey(beaconPos);
|
||||
IDhApiRenderableBoxGroup beaconBox = this.beamRenderGroupByPos.remove(existingBeam.pos);
|
||||
this.beaconBeamRepo.deleteWithKey(beaconPos); // TODO broken when updating adjacent chunks
|
||||
this.beamRefCountByPos.remove(existingBeam.pos);
|
||||
IDhApiRenderableBoxGroup beaconBox = this.beamRenderGroupByBlockPos.remove(existingBeam.pos);
|
||||
if (beaconBox != null)
|
||||
{
|
||||
GenericObjectRenderer.INSTANCE.remove(beaconBox.getId());
|
||||
@@ -269,6 +290,81 @@ public abstract class AbstractDhLevel implements IDhLevel
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadBeaconBeamsInPos(long pos)
|
||||
{
|
||||
if (this.beaconBeamRepo != null)
|
||||
{
|
||||
// get beams in pos
|
||||
List<BeaconBeamDTO> existingBeamList = this.beaconBeamRepo.getAllBeamsForSectionPos(pos);
|
||||
for (int i = 0; i < existingBeamList.size(); i++)
|
||||
{
|
||||
BeaconBeamDTO beam = existingBeamList.get(i);
|
||||
|
||||
IDhApiRenderableBoxGroup beaconBox = GenericObjectRenderer.INSTANCE.createForSingleBox(new DhApiRenderableBox(
|
||||
new DhApiVec3f(beam.pos.x, beam.pos.y+1, beam.pos.z),
|
||||
new DhApiVec3f(beam.pos.x+1, 6_000, beam.pos.z+1),
|
||||
beam.color
|
||||
));
|
||||
beaconBox.setBlockLight(LodUtil.MAX_MC_LIGHT);
|
||||
beaconBox.setSkyLight(LodUtil.MAX_MC_LIGHT);
|
||||
|
||||
this.beamRefCountByPos.compute(beam.pos, (beamPos, refCount) ->
|
||||
{
|
||||
if (refCount == null)
|
||||
{
|
||||
refCount = new AtomicInteger(0);
|
||||
}
|
||||
|
||||
if (refCount.getAndIncrement() == 0)
|
||||
{
|
||||
this.beamRenderGroupByBlockPos.put(beam.pos, beaconBox);
|
||||
GenericObjectRenderer.INSTANCE.add(beaconBox);
|
||||
}
|
||||
|
||||
return refCount;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unloadBeaconBeamsInPos(long pos)
|
||||
{
|
||||
if (this.beaconBeamRepo != null)
|
||||
{
|
||||
// get beams in pos
|
||||
List<BeaconBeamDTO> existingBeamList = this.beaconBeamRepo.getAllBeamsForSectionPos(pos);
|
||||
for (int i = 0; i < existingBeamList.size(); i++)
|
||||
{
|
||||
BeaconBeamDTO beam = existingBeamList.get(i);
|
||||
|
||||
// beam no longer exists at position, remove
|
||||
this.beamRefCountByPos.compute(beam.pos, (beamPos, refCount) ->
|
||||
{
|
||||
if (refCount == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (refCount.decrementAndGet() == 0)
|
||||
{
|
||||
IDhApiRenderableBoxGroup beaconBox = this.beamRenderGroupByBlockPos.remove(beam.pos);
|
||||
if (beaconBox != null)
|
||||
{
|
||||
GenericObjectRenderer.INSTANCE.remove(beaconBox.getId());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return refCount;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
|
||||
@@ -22,7 +22,6 @@ package com.seibel.distanthorizons.core.level;
|
||||
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
|
||||
import com.seibel.distanthorizons.core.file.fullDatafile.FullDataSourceProviderV2;
|
||||
import com.seibel.distanthorizons.core.file.structure.AbstractSaveStructure;
|
||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||
import com.seibel.distanthorizons.core.sql.dto.BeaconBeamDTO;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||
@@ -46,8 +45,10 @@ public interface IDhLevel extends AutoCloseable
|
||||
void setChunkHash(DhChunkPos pos, int chunkHash);
|
||||
void updateChunkAsync(IChunkWrapper chunk);
|
||||
|
||||
void loadBeaconBeamsInPos(long pos);
|
||||
List<BeaconBeamDTO> getAllBeamsForSectionPos(long pos);
|
||||
void ensureBeaconBeamsAtPos(long pos, List<BeaconBeamDTO> beamList);
|
||||
void setBeaconBeamsForChunk(DhChunkPos chunkPos, List<BeaconBeamDTO> beamList);
|
||||
void unloadBeaconBeamsInPos(long pos);
|
||||
|
||||
FullDataSourceProviderV2 getFullDataProvider();
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
package com.seibel.distanthorizons.core.pos;
|
||||
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
|
||||
public class DhChunkPos
|
||||
{
|
||||
public final int x; // Low 32 bits
|
||||
@@ -29,6 +31,10 @@ public class DhChunkPos
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// constructors //
|
||||
//==============//
|
||||
|
||||
public DhChunkPos(int x, int z)
|
||||
{
|
||||
this.x = x;
|
||||
@@ -51,6 +57,10 @@ public class DhChunkPos
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
// methods //
|
||||
//=========//
|
||||
|
||||
public DhBlockPos center() { return new DhBlockPos(8 + this.x << 4, 0, 8 + this.z << 4); }
|
||||
public DhBlockPos corner() { return new DhBlockPos(this.x << 4, 0, this.z << 4); }
|
||||
|
||||
@@ -64,8 +74,24 @@ public class DhChunkPos
|
||||
|
||||
public DhBlockPos2D getMinBlockPos() { return new DhBlockPos2D(this.x << 4, this.z << 4); }
|
||||
|
||||
public boolean contains(DhBlockPos pos)
|
||||
{
|
||||
int minBlockX = this.getMinBlockX();
|
||||
int minBlockZ = this.getMinBlockZ();
|
||||
int maxBlockX = minBlockX + LodUtil.CHUNK_WIDTH;
|
||||
int maxBlockZ = minBlockZ + LodUtil.CHUNK_WIDTH;
|
||||
|
||||
return minBlockX <= pos.x && pos.x <= maxBlockX
|
||||
&& minBlockZ <= pos.z && pos.z <= maxBlockZ;
|
||||
}
|
||||
|
||||
public long getLong() { return toLong(this.x, this.z); }
|
||||
|
||||
|
||||
//================//
|
||||
// base overrides //
|
||||
//================//
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.seibel.distanthorizons.core.pos.DhBlockPos2D;
|
||||
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||
import com.seibel.distanthorizons.core.render.renderer.DebugRenderer;
|
||||
import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable;
|
||||
import com.seibel.distanthorizons.core.sql.repo.BeaconBeamRepo;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.util.ThreadUtil;
|
||||
import com.seibel.distanthorizons.core.util.objects.quadTree.QuadNode;
|
||||
@@ -329,6 +330,10 @@ public class LodQuadTree extends QuadTree<LodRenderSection> implements IDebugRen
|
||||
}
|
||||
|
||||
// all child positions are loaded, disable this section and enable its children.
|
||||
if (renderSection.renderingEnabled)
|
||||
{
|
||||
this.level.unloadBeaconBeamsInPos(renderSection.pos);
|
||||
}
|
||||
renderSection.renderingEnabled = false;
|
||||
|
||||
// walk back down the tree and enable the child sections //TODO there are probably more efficient ways of doing this, but this will work for now
|
||||
@@ -383,6 +388,7 @@ public class LodQuadTree extends QuadTree<LodRenderSection> implements IDebugRen
|
||||
if (!renderSection.renderingEnabled)
|
||||
{
|
||||
renderSection.renderingEnabled = true;
|
||||
this.level.loadBeaconBeamsInPos(renderSection.pos);
|
||||
|
||||
// delete/disable children, all of them will be a lower detail level than requested
|
||||
quadNode.deleteAllChildren((childRenderSection) ->
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
|
||||
package com.seibel.distanthorizons.core.render;
|
||||
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiVec3f;
|
||||
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.ColumnRenderSource;
|
||||
@@ -28,11 +31,16 @@ import com.seibel.distanthorizons.core.enums.EDhDirection;
|
||||
import com.seibel.distanthorizons.core.file.fullDatafile.FullDataSourceProviderV2;
|
||||
import com.seibel.distanthorizons.core.level.IDhClientLevel;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||
import com.seibel.distanthorizons.core.render.glObject.GLProxy;
|
||||
import com.seibel.distanthorizons.core.render.renderer.GenericObjectRenderer;
|
||||
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.sql.dto.BeaconBeamDTO;
|
||||
import com.seibel.distanthorizons.core.sql.repo.BeaconBeamRepo;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
||||
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@@ -41,6 +49,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import javax.annotation.WillNotClose;
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
@@ -416,6 +425,7 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
|
||||
}
|
||||
|
||||
|
||||
this.level.unloadBeaconBeamsInPos(this.pos);
|
||||
|
||||
if (this.renderBuffer != null)
|
||||
{
|
||||
|
||||
@@ -121,7 +121,7 @@ public class BeaconBeamRepo extends AbstractDhRepo<DhBlockPos, BeaconBeamDTO>
|
||||
"UPDATE "+this.getTableName()+" \n" +
|
||||
"SET \n" +
|
||||
" ColorR = ?, ColorG = ?, ColorB = ?, \n" +
|
||||
" ,LastModifiedUnixDateTime = ? \n" +
|
||||
" LastModifiedUnixDateTime = ? \n" +
|
||||
"WHERE BlockPosX = ? AND BlockPosY = ? AND BlockPosZ = ?";
|
||||
PreparedStatement statement = this.createPreparedStatement(sql);
|
||||
|
||||
|
||||
+3
-3
@@ -254,11 +254,11 @@ public interface IChunkWrapper extends IBindable
|
||||
ArrayList<DhBlockPos> blockPosList = this.getBlockLightPosList();
|
||||
for (int i = 0; i < blockPosList.size(); i++)
|
||||
{
|
||||
DhBlockPos pos = blockPosList.get(i).convertToChunkRelativePos();
|
||||
IBlockStateWrapper block = this.getBlockState(pos);
|
||||
DhBlockPos pos = blockPosList.get(i);
|
||||
IBlockStateWrapper block = this.getBlockState(pos.convertToChunkRelativePos());
|
||||
if (block.getSerialString().toLowerCase().contains("minecraft:beacon"))
|
||||
{
|
||||
BeaconBeamDTO beam = new BeaconBeamDTO(pos, Color.WHITE); // TODO
|
||||
BeaconBeamDTO beam = new BeaconBeamDTO(blockPosList.get(i), Color.WHITE);
|
||||
beaconPosList.add(beam);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user