diff --git a/src/main/java/rs117/hd/renderer/zone/FacePrioritySorter.java b/src/main/java/rs117/hd/renderer/zone/FacePrioritySorter.java index 72b635f7a2..c242d324cc 100644 --- a/src/main/java/rs117/hd/renderer/zone/FacePrioritySorter.java +++ b/src/main/java/rs117/hd/renderer/zone/FacePrioritySorter.java @@ -172,7 +172,7 @@ else if (pri == 10) } } - void sortStaticModelFacesByDistance( + public void sortStaticModelFacesByDistance( Zone.AlphaModel m, int yawCos, int yawSin, int pitchCos, int pitchSin diff --git a/src/main/java/rs117/hd/renderer/zone/SceneManager.java b/src/main/java/rs117/hd/renderer/zone/SceneManager.java index 1dc0955529..4c77823082 100644 --- a/src/main/java/rs117/hd/renderer/zone/SceneManager.java +++ b/src/main/java/rs117/hd/renderer/zone/SceneManager.java @@ -5,9 +5,7 @@ import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collectors; @@ -23,6 +21,8 @@ import rs117.hd.opengl.uniforms.UBOWorldViews; import rs117.hd.overlays.FrameTimer; import rs117.hd.overlays.Timer; +import rs117.hd.renderer.zone.jobs.RoofChangesJob; +import rs117.hd.renderer.zone.jobs.ZoneUploadJob; import rs117.hd.scene.AreaManager; import rs117.hd.scene.EnvironmentManager; import rs117.hd.scene.FishingSpotReplacer; @@ -93,7 +93,6 @@ public class SceneManager { private final WorldViewContext root = new WorldViewContext(null, null, null); private final WorldViewContext[] subs = new WorldViewContext[MAX_WORLDVIEWS]; - private final Map nextRoofChanges = new HashMap<>(); private ZoneSceneContext nextSceneContext; private Zone[][] nextZones; private final List sortedZones = new ArrayList<>(); @@ -357,45 +356,7 @@ private static boolean isEdgeTile(Zone[][] zones, int zx, int zz) { task -> lightManager.loadSceneLights(nextSceneContext) ); - private final GenericJob calculateRoofChangesTask = GenericJob.build( - "calculateRoofChanges", - (task) -> { - Scene prev = client.getTopLevelWorldView().getScene(); - Scene scene = nextSceneContext.scene; - - // Calculate roof ids for the zone - final int[][][] prids = prev.getRoofs(); - final int[][][] nrids = scene.getRoofs(); - - final int dx = scene.getBaseX() - prev.getBaseX() >> 3; - final int dy = scene.getBaseY() - prev.getBaseY() >> 3; - - nextRoofChanges.clear(); - for (int x = 0; x < EXTENDED_SCENE_SIZE; ++x) { - for (int z = 0; z < EXTENDED_SCENE_SIZE; ++z) { - int ox = x + (dx << 3); - int oz = z + (dy << 3); - - for (int level = 0; level < 4; ++level) { - task.workerHandleCancel(); - // old zone still in scene? - if (ox >= 0 && oz >= 0 && ox < EXTENDED_SCENE_SIZE && oz < EXTENDED_SCENE_SIZE) { - int prid = prids[level][ox][oz]; - int nrid = nrids[level][x][z]; - if (prid > 0 && nrid > 0 && prid != nrid) { - Integer old = nextRoofChanges.putIfAbsent(prid, nrid); - if (old == null) { - log.trace("Roof change: {} -> {}", prid, nrid); - } else if (old != nrid) { - log.debug("Roof change mismatch: {} -> {} vs {}", prid, nrid, old); - } - } - } - } - } - } - } - ); + private final RoofChangesJob calculateRoofChangesTask = new RoofChangesJob(); public synchronized void loadScene(WorldView worldView, Scene scene) { try { @@ -500,6 +461,8 @@ public synchronized void loadScene(WorldView worldView, Scene scene) { } // Queue after ensuring previous scene has been cancelled + calculateRoofChangesTask.prev = client.getTopLevelWorldView().getScene(); + calculateRoofChangesTask.scene = nextSceneContext.scene; calculateRoofChangesTask.queue(); final int dx = scene.getBaseX() - prev.getBaseX() >> 3; @@ -620,14 +583,18 @@ public void swapScene(Scene scene) { calculateRoofChangesTask.waitForCompletion(); WorldViewContext ctx = root; - if (!nextRoofChanges.isEmpty()) { - for (int x = 0; x < ctx.sizeX; ++x) { - for (int z = 0; z < ctx.sizeZ; ++z) { - Zone zone = nextZones[x][z]; - if (zone.needsRoofUpdate) { - zone.needsRoofUpdate = false; - zone.updateRoofs(nextRoofChanges); - } + for (int x = 0; x < ctx.sizeX; ++x) { + for (int z = 0; z < ctx.sizeZ; ++z) { + Zone zone = nextZones[x][z]; + if(calculateRoofChangesTask.doesZoneHaveRoofMismatch(x, z)) { + zone.needsRoofUpdate = false; + zone.rebuild = true; + continue; + } + + if (zone.needsRoofUpdate) { + zone.needsRoofUpdate = false; + zone.updateRoofs(calculateRoofChangesTask.result); } } } diff --git a/src/main/java/rs117/hd/renderer/zone/WorldViewContext.java b/src/main/java/rs117/hd/renderer/zone/WorldViewContext.java index a9cdebb4ea..71a705b74c 100644 --- a/src/main/java/rs117/hd/renderer/zone/WorldViewContext.java +++ b/src/main/java/rs117/hd/renderer/zone/WorldViewContext.java @@ -15,6 +15,7 @@ import rs117.hd.HdPlugin; import rs117.hd.opengl.uniforms.UBOWorldViews; import rs117.hd.opengl.uniforms.UBOWorldViews.WorldViewStruct; +import rs117.hd.renderer.zone.jobs.ZoneUploadJob; import rs117.hd.utils.Camera; import rs117.hd.utils.CommandBuffer; import rs117.hd.utils.DestructibleHandler; @@ -53,17 +54,17 @@ public class WorldViewContext { @Inject private SceneManager sceneManager; - final int worldViewId; - final int sizeX, sizeZ; + public final int worldViewId; + public final int sizeX, sizeZ; @Nullable - WorldViewStruct uboWorldViewStruct; - ZoneSceneContext sceneContext; - Zone[][] zones; - GLBuffer vboM; - boolean isLoading = true; - - int minLevel, level, maxLevel; - Set hideRoofIds; + public WorldViewStruct uboWorldViewStruct; + public ZoneSceneContext sceneContext; + public Zone[][] zones; + public GLBuffer vboM; + public boolean isLoading = true; + + public int minLevel, level, maxLevel; + public Set hideRoofIds; private final Comparator alphaSortComparator = Comparator.comparingInt((Zone z) -> z.dist).reversed(); private final List alphaZones = new ArrayList<>(); diff --git a/src/main/java/rs117/hd/renderer/zone/Zone.java b/src/main/java/rs117/hd/renderer/zone/Zone.java index 23f576eb05..4457fa103d 100644 --- a/src/main/java/rs117/hd/renderer/zone/Zone.java +++ b/src/main/java/rs117/hd/renderer/zone/Zone.java @@ -16,6 +16,9 @@ import net.runelite.api.*; import org.lwjgl.system.MemoryStack; import rs117.hd.HdPlugin; +import rs117.hd.renderer.zone.jobs.EboAlphaWriterJob; +import rs117.hd.renderer.zone.jobs.StaticAlphaSortingJob; +import rs117.hd.renderer.zone.jobs.ZoneUploadJob; import rs117.hd.scene.MaterialManager; import rs117.hd.scene.SceneContext; import rs117.hd.scene.materials.Material; @@ -85,8 +88,8 @@ public class Zone implements Destructible { public HashSet animatedDynamicObjectIds = new HashSet<>(); - final StaticAlphaSortingJob alphaSortingJob = new StaticAlphaSortingJob(); - ZoneUploadJob uploadJob; + private final StaticAlphaSortingJob alphaSortingJob = new StaticAlphaSortingJob(); + public ZoneUploadJob uploadJob; int[] levelOffsets = new int[5]; // buffer pos in ints for the end of the level @@ -417,19 +420,19 @@ public static class AlphaModel { byte flags; // only set for static geometry as they require sorting - int radius; - int[] packedFaces; - int[] sortedFaces; - int sortedFacesLen; + public int radius; + public int[] packedFaces; + public int[] sortedFaces; + public int sortedFacesLen; int dist; - int asyncSortIdx = -1; + public int asyncSortIdx = -1; static final int SKIP = 1; // temporary model is in a closer zone static final int TEMP = 2; // temporary model added to a closer zone static final int SORT_COMPLETED = 4; - void setSorted() { + public void setSorted() { flags |= SORT_COMPLETED; } diff --git a/src/main/java/rs117/hd/renderer/zone/EboAlphaWriterJob.java b/src/main/java/rs117/hd/renderer/zone/jobs/EboAlphaWriterJob.java similarity index 92% rename from src/main/java/rs117/hd/renderer/zone/EboAlphaWriterJob.java rename to src/main/java/rs117/hd/renderer/zone/jobs/EboAlphaWriterJob.java index 6ad58bdc23..d8490cbecf 100644 --- a/src/main/java/rs117/hd/renderer/zone/EboAlphaWriterJob.java +++ b/src/main/java/rs117/hd/renderer/zone/jobs/EboAlphaWriterJob.java @@ -1,8 +1,9 @@ -package rs117.hd.renderer.zone; +package rs117.hd.renderer.zone.jobs; import java.nio.IntBuffer; import java.util.ArrayDeque; import lombok.extern.slf4j.Slf4j; +import rs117.hd.renderer.zone.Zone; import rs117.hd.utils.buffer.GLMappedBufferIntWriter; import rs117.hd.utils.jobs.Job; diff --git a/src/main/java/rs117/hd/renderer/zone/jobs/RoofChangesJob.java b/src/main/java/rs117/hd/renderer/zone/jobs/RoofChangesJob.java new file mode 100644 index 0000000000..eb22aa6331 --- /dev/null +++ b/src/main/java/rs117/hd/renderer/zone/jobs/RoofChangesJob.java @@ -0,0 +1,60 @@ +package rs117.hd.renderer.zone.jobs; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.*; +import rs117.hd.utils.jobs.Job; + +import static net.runelite.api.Constants.*; + +@Slf4j +public class RoofChangesJob extends Job { + + public Scene prev; + public Scene scene; + + public final boolean[] mismatched = new boolean[EXTENDED_SCENE_SIZE * EXTENDED_SCENE_SIZE]; + public final Map result = new HashMap<>(); + + @Override + protected void onRun() { + // Calculate roof ids for the zone + final int[][][] prids = prev.getRoofs(); + final int[][][] nrids = scene.getRoofs(); + + final int dx = scene.getBaseX() - prev.getBaseX() >> 3; + final int dy = scene.getBaseY() - prev.getBaseY() >> 3; + + result.clear(); + Arrays.fill(mismatched, false); + for (int x = 0; x < EXTENDED_SCENE_SIZE; ++x) { + for (int z = 0; z < EXTENDED_SCENE_SIZE; ++z) { + int ox = x + (dx << 3); + int oz = z + (dy << 3); + + for (int level = 0; level < 4; ++level) { + // old zone still in scene? + if (ox >= 0 && oz >= 0 && ox < EXTENDED_SCENE_SIZE && oz < EXTENDED_SCENE_SIZE) { + int prid = prids[level][ox][oz]; + int nrid = nrids[level][x][z]; + if (prid > 0 && nrid > 0 && prid != nrid) { + Integer old = result.putIfAbsent(prid, nrid); + if (old == null) { + log.trace("Roof change: {} -> {}", prid, nrid); + } else if (old != nrid) { + log.debug("Roof change mismatch: {} -> {} vs {}", prid, nrid, old); + mismatched[x * EXTENDED_SCENE_SIZE + z] = true; + } + } + } + } + } + } + } + + public boolean doesZoneHaveRoofMismatch(int x, int z) { + return mismatched[x * EXTENDED_SCENE_SIZE + z]; + } +} diff --git a/src/main/java/rs117/hd/renderer/zone/StaticAlphaSortingJob.java b/src/main/java/rs117/hd/renderer/zone/jobs/StaticAlphaSortingJob.java similarity index 96% rename from src/main/java/rs117/hd/renderer/zone/StaticAlphaSortingJob.java rename to src/main/java/rs117/hd/renderer/zone/jobs/StaticAlphaSortingJob.java index fb885b14c3..41f05006c1 100644 --- a/src/main/java/rs117/hd/renderer/zone/StaticAlphaSortingJob.java +++ b/src/main/java/rs117/hd/renderer/zone/jobs/StaticAlphaSortingJob.java @@ -1,10 +1,11 @@ -package rs117.hd.renderer.zone; +package rs117.hd.renderer.zone.jobs; import java.util.Arrays; import java.util.concurrent.atomic.AtomicIntegerArray; import lombok.RequiredArgsConstructor; import rs117.hd.overlays.FrameTimer; import rs117.hd.overlays.Timer; +import rs117.hd.renderer.zone.FacePrioritySorter; import rs117.hd.renderer.zone.Zone.AlphaModel; import rs117.hd.utils.Camera; import rs117.hd.utils.jobs.Job; diff --git a/src/main/java/rs117/hd/renderer/zone/ZoneUploadJob.java b/src/main/java/rs117/hd/renderer/zone/jobs/ZoneUploadJob.java similarity index 92% rename from src/main/java/rs117/hd/renderer/zone/ZoneUploadJob.java rename to src/main/java/rs117/hd/renderer/zone/jobs/ZoneUploadJob.java index e7f41ee7a0..79307b027f 100644 --- a/src/main/java/rs117/hd/renderer/zone/ZoneUploadJob.java +++ b/src/main/java/rs117/hd/renderer/zone/jobs/ZoneUploadJob.java @@ -1,8 +1,12 @@ -package rs117.hd.renderer.zone; +package rs117.hd.renderer.zone.jobs; import java.util.concurrent.ConcurrentLinkedQueue; import lombok.extern.slf4j.Slf4j; import net.runelite.api.*; +import rs117.hd.renderer.zone.SceneUploader; +import rs117.hd.renderer.zone.WorldViewContext; +import rs117.hd.renderer.zone.Zone; +import rs117.hd.renderer.zone.ZoneSceneContext; import rs117.hd.utils.DestructibleHandler; import rs117.hd.utils.buffer.GLBuffer; import rs117.hd.utils.buffer.GLTextureBuffer; @@ -18,10 +22,10 @@ public final class ZoneUploadJob extends Job { private WorldViewContext viewContext; private ZoneSceneContext sceneContext; - Zone zone; - int x, z; - long revealAfterTimestampMs; - boolean shouldUnmap; + public Zone zone; + public int x, z; + public long revealAfterTimestampMs; + public boolean shouldUnmap; @Override protected void onRun() throws InterruptedException {