Fix beacons not reloading (and improve logic)
This commit is contained in:
@@ -629,10 +629,10 @@ public class LodQuadTree extends QuadTree<LodRenderSection> implements IDebugRen
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the section only needs to be updated if a buffer is currently present
|
|
||||||
LodRenderSection renderSection = this.tryGetValue(pos);
|
LodRenderSection renderSection = this.tryGetValue(pos);
|
||||||
if (renderSection != null)
|
if (renderSection != null)
|
||||||
{
|
{
|
||||||
|
// the section only needs to be updated if a buffer is currently present
|
||||||
if (renderSection.gpuUploadComplete())
|
if (renderSection.gpuUploadComplete())
|
||||||
{
|
{
|
||||||
if (renderSection.gpuUploadInProgress()
|
if (renderSection.gpuUploadInProgress()
|
||||||
|
|||||||
+97
-53
@@ -50,9 +50,9 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import javax.annotation.WillNotClose;
|
import javax.annotation.WillNotClose;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A render section represents an area that could be rendered.
|
* A render section represents an area that could be rendered.
|
||||||
@@ -82,6 +82,11 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
|
|||||||
public final BeaconRenderHandler beaconRenderHandler;
|
public final BeaconRenderHandler beaconRenderHandler;
|
||||||
@Nullable
|
@Nullable
|
||||||
public final BeaconBeamRepo beaconBeamRepo;
|
public final BeaconBeamRepo beaconBeamRepo;
|
||||||
|
/**
|
||||||
|
* locking is necessary to prevent some weird threading issues
|
||||||
|
* causing beacons to appear/disappear at the wrong times.
|
||||||
|
*/
|
||||||
|
private final ReentrantLock beaconRenderHandlingLock = new ReentrantLock();
|
||||||
|
|
||||||
|
|
||||||
private boolean renderingEnabled = false;
|
private boolean renderingEnabled = false;
|
||||||
@@ -386,76 +391,115 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
|
|||||||
/** gets the active beacon list and stops/starts beacon rendering as necessary */
|
/** gets the active beacon list and stops/starts beacon rendering as necessary */
|
||||||
private void refreshActiveBeaconList()
|
private void refreshActiveBeaconList()
|
||||||
{
|
{
|
||||||
// do nothing if beacon rendering or repos are unavailable
|
try
|
||||||
if (this.beaconBeamRepo == null
|
|
||||||
|| this.beaconRenderHandler == null)
|
|
||||||
{
|
{
|
||||||
return;
|
this.beaconRenderHandlingLock.lock();
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Synchronized to prevent two threads for accessing the array at once
|
|
||||||
synchronized (this.activeBeaconList)
|
|
||||||
{
|
|
||||||
List<BeaconBeamDTO> activeBeacons = this.beaconBeamRepo.getAllBeamsForPos(this.pos);
|
|
||||||
|
|
||||||
// swap old and new active beacon list
|
// do nothing if beacon rendering or repos are unavailable
|
||||||
this.activeBeaconList.clear();
|
if (this.beaconBeamRepo == null
|
||||||
this.activeBeaconList.addAll(activeBeacons);
|
|| this.beaconRenderHandler == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Synchronized to prevent two threads for accessing the array at once
|
||||||
|
synchronized (this.activeBeaconList)
|
||||||
|
{
|
||||||
|
ArrayList<BeaconBeamDTO> activeBeacons = this.beaconBeamRepo.getAllBeamsForPos(this.pos);
|
||||||
|
|
||||||
|
// swap old and new active beacon list
|
||||||
|
this.activeBeaconList.clear();
|
||||||
|
this.activeBeaconList.addAll(activeBeacons);
|
||||||
|
|
||||||
|
// if the beacons are currently rendering,
|
||||||
|
// re-create them so we can see any potential changes
|
||||||
|
if (this.beaconsRendering)
|
||||||
|
{
|
||||||
|
this.tryDisableBeacons();
|
||||||
|
this.tryEnableBeacons();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
this.beaconRenderHandlingLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void tryDisableBeacons()
|
public void tryDisableBeacons()
|
||||||
{
|
{
|
||||||
// do nothing if beacon rendering is unavailable
|
try
|
||||||
if (this.beaconRenderHandler == null)
|
|
||||||
{
|
{
|
||||||
return;
|
this.beaconRenderHandlingLock.lock();
|
||||||
|
|
||||||
|
|
||||||
|
// do nothing if beacon rendering is unavailable
|
||||||
|
if (this.beaconRenderHandler == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.beaconsRendering)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.beaconsRendering = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (Config.Client.Advanced.Debugging.DebugWireframe.showRenderSectionStatus.get())
|
||||||
|
{
|
||||||
|
// show that this position has just been disabled
|
||||||
|
DebugRenderer.makeParticle(
|
||||||
|
new DebugRenderer.BoxParticle(
|
||||||
|
new DebugRenderer.Box(this.pos, 128f, 156f, 0.09f, Color.CYAN.darker()),
|
||||||
|
0.2, 32f
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (this.activeBeaconList)
|
||||||
|
{
|
||||||
|
this.beaconRenderHandler.stopRenderingBeaconsInRange(this.pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
if (!this.beaconsRendering)
|
|
||||||
{
|
{
|
||||||
return;
|
this.beaconRenderHandlingLock.unlock();
|
||||||
}
|
|
||||||
this.beaconsRendering = false;
|
|
||||||
|
|
||||||
|
|
||||||
if (Config.Client.Advanced.Debugging.DebugWireframe.showRenderSectionStatus.get())
|
|
||||||
{
|
|
||||||
// show that this position has just been disabled
|
|
||||||
DebugRenderer.makeParticle(
|
|
||||||
new DebugRenderer.BoxParticle(
|
|
||||||
new DebugRenderer.Box(this.pos, 128f, 156f, 0.09f, Color.CYAN.darker()),
|
|
||||||
0.2, 32f
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (this.activeBeaconList)
|
|
||||||
{
|
|
||||||
this.beaconRenderHandler.stopRenderingBeacons(this.activeBeaconList);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void tryEnableBeacons()
|
public void tryEnableBeacons()
|
||||||
{
|
{
|
||||||
// do nothing if beacon rendering is unavailable
|
try
|
||||||
if (this.beaconRenderHandler == null)
|
|
||||||
{
|
{
|
||||||
return;
|
this.beaconRenderHandlingLock.lock();
|
||||||
|
|
||||||
|
|
||||||
|
// do nothing if beacon rendering is unavailable
|
||||||
|
if (this.beaconRenderHandler == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.beaconsRendering)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.beaconsRendering = true;
|
||||||
|
|
||||||
|
|
||||||
|
synchronized (this.activeBeaconList)
|
||||||
|
{
|
||||||
|
byte absoluteDetailLevel = (byte)(DhSectionPos.getDetailLevel(this.pos) - DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL);
|
||||||
|
this.beaconRenderHandler.startRenderingBeacons(this.activeBeaconList, absoluteDetailLevel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
if (this.beaconsRendering)
|
|
||||||
{
|
{
|
||||||
return;
|
this.beaconRenderHandlingLock.unlock();
|
||||||
}
|
|
||||||
this.beaconsRendering = true;
|
|
||||||
|
|
||||||
|
|
||||||
synchronized (this.activeBeaconList)
|
|
||||||
{
|
|
||||||
byte absoluteDetailLevel = (byte)(DhSectionPos.getDetailLevel(this.pos) - DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL);
|
|
||||||
this.beaconRenderHandler.startRenderingBeacons(this.activeBeaconList, absoluteDetailLevel);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+46
-61
@@ -60,9 +60,12 @@ public class BeaconRenderHandler
|
|||||||
|
|
||||||
private final ReentrantLock updateLock = new ReentrantLock();
|
private final ReentrantLock updateLock = new ReentrantLock();
|
||||||
|
|
||||||
private final IDhApiRenderableBoxGroup beaconBoxGroup;
|
/** only contains the beacons currently being rendered (culled beacons will be missing) */
|
||||||
|
private final IDhApiRenderableBoxGroup activeBeaconBoxRenderGroup;
|
||||||
|
/** contains all beacons that could be rendered (including those that are being culled) */
|
||||||
private final ArrayList<DhApiRenderableBox> fullBeaconBoxList = new ArrayList<>();
|
private final ArrayList<DhApiRenderableBox> fullBeaconBoxList = new ArrayList<>();
|
||||||
private final HashSet<DhBlockPos> beaconBlockPosSet = new HashSet<>();
|
/** contains all beacons that could be rendered */
|
||||||
|
private final HashSet<DhBlockPos> fullBeaconBlockPosSet = new HashSet<>();
|
||||||
|
|
||||||
private boolean cullingThreadRunning = false;
|
private boolean cullingThreadRunning = false;
|
||||||
private boolean updateRenderDataNextFrame = false;
|
private boolean updateRenderDataNextFrame = false;
|
||||||
@@ -72,24 +75,28 @@ public class BeaconRenderHandler
|
|||||||
//=============//
|
//=============//
|
||||||
// constructor //
|
// constructor //
|
||||||
//=============//
|
//=============//
|
||||||
|
//region
|
||||||
|
|
||||||
public BeaconRenderHandler(@NotNull GenericObjectRenderer renderer)
|
public BeaconRenderHandler(@NotNull GenericObjectRenderer renderer)
|
||||||
{
|
{
|
||||||
this.beaconBoxGroup = GenericRenderObjectFactory.INSTANCE.createAbsolutePositionedGroup(ModInfo.NAME+":Beacons", new ArrayList<>(0));
|
this.activeBeaconBoxRenderGroup = GenericRenderObjectFactory.INSTANCE.createAbsolutePositionedGroup(ModInfo.NAME+":Beacons", new ArrayList<>(0));
|
||||||
this.beaconBoxGroup.setBlockLight(LodUtil.MAX_MC_LIGHT);
|
this.activeBeaconBoxRenderGroup.setBlockLight(LodUtil.MAX_MC_LIGHT);
|
||||||
this.beaconBoxGroup.setSkyLight(LodUtil.MAX_MC_LIGHT);
|
this.activeBeaconBoxRenderGroup.setSkyLight(LodUtil.MAX_MC_LIGHT);
|
||||||
this.beaconBoxGroup.setSsaoEnabled(false);
|
this.activeBeaconBoxRenderGroup.setSsaoEnabled(false);
|
||||||
this.beaconBoxGroup.setShading(DhApiRenderableBoxGroupShading.getUnshaded());
|
this.activeBeaconBoxRenderGroup.setShading(DhApiRenderableBoxGroupShading.getUnshaded());
|
||||||
this.beaconBoxGroup.setPreRenderFunc(this::beforeRender);
|
this.activeBeaconBoxRenderGroup.setPreRenderFunc(this::beforeRender);
|
||||||
|
|
||||||
renderer.add(this.beaconBoxGroup);
|
renderer.add(this.activeBeaconBoxRenderGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=================//
|
//=================//
|
||||||
// render handling //
|
// render handling //
|
||||||
//=================//
|
//=================//
|
||||||
|
//region
|
||||||
|
|
||||||
public void startRenderingBeacons(ArrayList<BeaconBeamDTO> beaconList, byte detailLevel)
|
public void startRenderingBeacons(ArrayList<BeaconBeamDTO> beaconList, byte detailLevel)
|
||||||
{
|
{
|
||||||
@@ -143,12 +150,15 @@ public class BeaconRenderHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//LOGGER.info("startRenderingBeacons ["+sortedBeaconList+"]");
|
||||||
|
|
||||||
// add each beacon to the renderer
|
// add each beacon to the renderer
|
||||||
for (int i = 0; i < sortedBeaconList.size(); i++)
|
for (int i = 0; i < sortedBeaconList.size(); i++)
|
||||||
{
|
{
|
||||||
BeaconBeamDTO beacon = sortedBeaconList.get(i);
|
BeaconBeamDTO beacon = sortedBeaconList.get(i);
|
||||||
if (!this.beaconBlockPosSet.add(beacon.blockPos))
|
if (!this.fullBeaconBlockPosSet.add(beacon.blockPos))
|
||||||
{
|
{
|
||||||
|
// skip already present beacons
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,9 +171,9 @@ public class BeaconRenderHandler
|
|||||||
EDhApiBlockMaterial.ILLUMINATED
|
EDhApiBlockMaterial.ILLUMINATED
|
||||||
);
|
);
|
||||||
|
|
||||||
this.beaconBoxGroup.add(beaconBox);
|
this.activeBeaconBoxRenderGroup.add(beaconBox);
|
||||||
this.fullBeaconBoxList.add(beaconBox);
|
this.fullBeaconBoxList.add(beaconBox);
|
||||||
this.beaconBoxGroup.triggerBoxChange();
|
this.activeBeaconBoxRenderGroup.triggerBoxChange();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@@ -172,58 +182,28 @@ public class BeaconRenderHandler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stopRenderingBeacons(ArrayList<BeaconBeamDTO> beaconList)
|
public void stopRenderingBeaconsInRange(long pos)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
this.updateLock.lock();
|
this.updateLock.lock();
|
||||||
|
|
||||||
for (int i = 0; i < beaconList.size(); i++)
|
Predicate<DhApiRenderableBox> removeBoxPredicate = (DhApiRenderableBox box) ->
|
||||||
{
|
{
|
||||||
BeaconBeamDTO beacon = beaconList.get(i);
|
DhBlockPos blockPos = new DhBlockPos((int)box.minPos.x, (int)box.minPos.y, (int)box.minPos.z);
|
||||||
DhBlockPos beaconPos = beacon.blockPos;
|
boolean contains = DhSectionPos.contains(pos, blockPos);
|
||||||
if (!this.beaconBlockPosSet.remove(beaconPos))
|
//if (contains)
|
||||||
{
|
//{
|
||||||
continue;
|
// LOGGER.info("stopRenderingBeaconsInRange ["+DhSectionPos.toString(pos)+"] ["+blockPos+"]");
|
||||||
}
|
//}
|
||||||
|
return contains;
|
||||||
Predicate<DhApiRenderableBox> removePredicate = (DhApiRenderableBox box) ->
|
};
|
||||||
{
|
this.activeBeaconBoxRenderGroup.removeIf(removeBoxPredicate);
|
||||||
return box.minPos.x == beaconPos.getX()
|
this.fullBeaconBoxList.removeIf(removeBoxPredicate);
|
||||||
&& box.minPos.y == beaconPos.getY() + 1 // plus 1 because the beam starts above the beacon
|
|
||||||
&& box.minPos.z == beaconPos.getZ();
|
|
||||||
};
|
|
||||||
this.beaconBoxGroup.removeIf(removePredicate);
|
|
||||||
this.fullBeaconBoxList.removeIf(removePredicate);
|
|
||||||
|
|
||||||
this.beaconBoxGroup.triggerBoxChange();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
this.updateLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateBeaconColor(BeaconBeamDTO newBeam)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
this.updateLock.lock();
|
|
||||||
|
|
||||||
DhBlockPos pos = newBeam.blockPos;
|
this.fullBeaconBlockPosSet.removeIf((DhBlockPos blockPos) -> DhSectionPos.contains(pos, blockPos));
|
||||||
for (int i = 0; i < this.fullBeaconBoxList.size(); i++)
|
|
||||||
{
|
this.activeBeaconBoxRenderGroup.triggerBoxChange();
|
||||||
DhApiRenderableBox box = this.fullBeaconBoxList.get(i);
|
|
||||||
if (box.minPos.x == pos.getX()
|
|
||||||
&& box.minPos.y == pos.getY() + 1 // plus 1 because the beam starts above the beacon
|
|
||||||
&& box.minPos.z == pos.getZ())
|
|
||||||
{
|
|
||||||
box.color = newBeam.color;
|
|
||||||
this.beaconBoxGroup.triggerBoxChange();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -245,10 +225,10 @@ public class BeaconRenderHandler
|
|||||||
// this must be called on the render thread to prevent concurrency issues
|
// this must be called on the render thread to prevent concurrency issues
|
||||||
if (this.updateRenderDataNextFrame)
|
if (this.updateRenderDataNextFrame)
|
||||||
{
|
{
|
||||||
this.beaconBoxGroup.triggerBoxChange();
|
this.activeBeaconBoxRenderGroup.triggerBoxChange();
|
||||||
this.updateRenderDataNextFrame = false;
|
this.updateRenderDataNextFrame = false;
|
||||||
}
|
}
|
||||||
this.beaconBoxGroup.setActive(Config.Client.Advanced.Graphics.GenericRendering.enableBeaconRendering.get());
|
this.activeBeaconBoxRenderGroup.setActive(Config.Client.Advanced.Graphics.GenericRendering.enableBeaconRendering.get());
|
||||||
}
|
}
|
||||||
/** does nothing if the culling thread is already running */
|
/** does nothing if the culling thread is already running */
|
||||||
private void tryUpdateBeaconCullingAsync()
|
private void tryUpdateBeaconCullingAsync()
|
||||||
@@ -284,7 +264,7 @@ public class BeaconRenderHandler
|
|||||||
// Clear the existing box group so we can re-populate it.
|
// Clear the existing box group so we can re-populate it.
|
||||||
// Since the box group is only used when we trigger an update, clearing it here
|
// Since the box group is only used when we trigger an update, clearing it here
|
||||||
// and repopulating it is fine.
|
// and repopulating it is fine.
|
||||||
this.beaconBoxGroup.clear();
|
this.activeBeaconBoxRenderGroup.clear();
|
||||||
|
|
||||||
// While iterating over every beacon isn't a great way of doing this,
|
// While iterating over every beacon isn't a great way of doing this,
|
||||||
// when 940 beacons were tested this only took ~0.9 Milliseconds, so as long as
|
// when 940 beacons were tested this only took ~0.9 Milliseconds, so as long as
|
||||||
@@ -295,7 +275,7 @@ public class BeaconRenderHandler
|
|||||||
double distance = Vec3d.getHorizontalDistance(cameraPos, box.minPos);
|
double distance = Vec3d.getHorizontalDistance(cameraPos, box.minPos);
|
||||||
if (distance > dhFadeDistance)
|
if (distance > dhFadeDistance)
|
||||||
{
|
{
|
||||||
this.beaconBoxGroup.add(box);
|
this.activeBeaconBoxRenderGroup.add(box);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,11 +297,14 @@ public class BeaconRenderHandler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//================//
|
//================//
|
||||||
// helper classes //
|
// helper classes //
|
||||||
//================//
|
//================//
|
||||||
|
//region
|
||||||
|
|
||||||
private static class NegativeInfiniteBlockPosComparator implements Comparator<BeaconBeamDTO>
|
private static class NegativeInfiniteBlockPosComparator implements Comparator<BeaconBeamDTO>
|
||||||
{
|
{
|
||||||
@@ -340,6 +323,8 @@ public class BeaconRenderHandler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ public class BeaconBeamRepo extends AbstractDhRepo<DhBlockPos, BeaconBeamDTO>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<BeaconBeamDTO> getAllBeamsForPos(long pos)
|
public ArrayList<BeaconBeamDTO> getAllBeamsForPos(long pos)
|
||||||
{
|
{
|
||||||
int minBlockX = DhSectionPos.getMinCornerBlockX(pos);
|
int minBlockX = DhSectionPos.getMinCornerBlockX(pos);
|
||||||
int minBlockZ = DhSectionPos.getMinCornerBlockZ(pos);
|
int minBlockZ = DhSectionPos.getMinCornerBlockZ(pos);
|
||||||
@@ -200,7 +200,7 @@ public class BeaconBeamRepo extends AbstractDhRepo<DhBlockPos, BeaconBeamDTO>
|
|||||||
"WHERE " +
|
"WHERE " +
|
||||||
"? <= BlockPosX AND BlockPosX <= ? AND " +
|
"? <= BlockPosX AND BlockPosX <= ? AND " +
|
||||||
"? <= BlockPosZ AND BlockPosZ <= ?";
|
"? <= BlockPosZ AND BlockPosZ <= ?";
|
||||||
public List<BeaconBeamDTO> getAllBeamsInBlockPosRange(
|
public ArrayList<BeaconBeamDTO> getAllBeamsInBlockPosRange(
|
||||||
int minBlockX, int maxBlockX,
|
int minBlockX, int maxBlockX,
|
||||||
int minBlockZ, int maxBlockZ
|
int minBlockZ, int maxBlockZ
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user