From 9f01583627d573018fb695055d73f950160303c7 Mon Sep 17 00:00:00 2001 From: Hooder Date: Sat, 16 May 2026 19:25:37 +0200 Subject: [PATCH 1/2] ModelOverride Offset --- schemas/model_overrides.schema.json | 11 ++++++ .../renderer/zone/ModelStreamingManager.java | 6 ++- .../rs117/hd/renderer/zone/SceneUploader.java | 37 +++++++++++++++++++ .../scene/model_overrides/ModelOverride.java | 4 ++ 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/schemas/model_overrides.schema.json b/schemas/model_overrides.schema.json index d550e37bcc..c5c1802c27 100644 --- a/schemas/model_overrides.schema.json +++ b/schemas/model_overrides.schema.json @@ -218,6 +218,17 @@ "type": "boolean", "description": "Disable priority sorting, instead sorting solely based on distance. Useful for new models where Jagex provide incorrect priorities." }, + "modelOffsetRelative": { + "type": "boolean", + "description": "Applies model offset relative to the models orientation." + }, + "modelOffset": { + "type": "array", + "description": "XYZ Offset applied in world space by default, modelOffsetRelative enables rotating the offset by the models orientation", + "items": { + "type": "integer" + } + }, "materialOverrides": { "type": "object", "description": "A subset of options can be tweaked separately for specific materials of the model.", diff --git a/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java b/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java index 7b9a941558..0ac8be7905 100644 --- a/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java +++ b/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java @@ -303,6 +303,7 @@ private void uploadTempModel( SceneUploader sceneUploader = SceneUploader.POOL.acquire(); FacePrioritySorter facePrioritySorter = shouldSort ? FacePrioritySorter.POOL.acquire() : null ) { + final int preOrientation = HDUtils.getModelPreOrientation(gameObject.getConfig()); shouldSort &= sceneUploader.preprocessTempModel( worldProjection, plugin.cameraFrustum, @@ -313,6 +314,7 @@ private void uploadTempModel( modelOverride, m, isPlayer, + preOrientation, orientation, x, y, z ); @@ -321,7 +323,6 @@ private void uploadTempModel( if (shouldSort && !isSquashed) facePrioritySorter.sortModelFaces(visibleFaces, m); - final int preOrientation = HDUtils.getModelPreOrientation(gameObject.getConfig()); if (culledFaces.length > 0 && modelOverride.castShadows && plugin.configShadowMode != ShadowMode.OFF && @@ -565,6 +566,7 @@ private void uploadDynamicModel( SceneUploader sceneUploader = SceneUploader.POOL.acquire(); FacePrioritySorter facePrioritySorter = shouldSort ? FacePrioritySorter.POOL.acquire() : null ) { + final int preOrientation = HDUtils.getModelPreOrientation(HDUtils.getObjectConfig(tileObject)); shouldSort &= sceneUploader.preprocessTempModel( projection, plugin.cameraFrustum, @@ -575,11 +577,11 @@ private void uploadDynamicModel( modelOverride, m, false, + preOrientation, orient, x, y, z ); - final int preOrientation = HDUtils.getModelPreOrientation(HDUtils.getObjectConfig(tileObject)); final boolean isSquashed = ctx.uboWorldViewStruct != null && ctx.uboWorldViewStruct.isSquashed(); if (shouldSort && !isSquashed) facePrioritySorter.sortModelFaces(visibleFaces, m, true); diff --git a/src/main/java/rs117/hd/renderer/zone/SceneUploader.java b/src/main/java/rs117/hd/renderer/zone/SceneUploader.java index bf48d1af96..c5c5c583e8 100644 --- a/src/main/java/rs117/hd/renderer/zone/SceneUploader.java +++ b/src/main/java/rs117/hd/renderer/zone/SceneUploader.java @@ -1396,6 +1396,24 @@ private int uploadStaticModel( orientCos = COSINE[orientation]; } + int offsetX = modelOverride.modelOffset[0]; + int offsetY = modelOverride.modelOffset[1]; + int offsetZ = modelOverride.modelOffset[2]; + + if(offsetX != 0 || offsetY != 0 || offsetZ != 0) { + if (modelOverride.modelOffsetRelative && (offsetX != 0 || offsetZ != 0) && (preOrientation != 0 || orientation != 0)) { + final int offsetOrientSin = SINE[mod(orientation != 0 ? orientation : preOrientation, 2048)]; + final int offsetOrientCos = COSINE[mod(orientation != 0 ? orientation : preOrientation, 2048)]; + + offsetX = modelOverride.modelOffset[2] * offsetOrientSin + modelOverride.modelOffset[0] * offsetOrientCos >> 16; + offsetZ = modelOverride.modelOffset[2] * offsetOrientCos - modelOverride.modelOffset[0] * offsetOrientSin >> 16; + } + + x += offsetX; + y += offsetY; + z += offsetZ; + } + for (int v = 0, vertexOffset = 0; v < vertexCount; ++v) { int vx = (int) vertexX[v]; int vy = (int) vertexY[v]; @@ -1716,6 +1734,7 @@ public boolean preprocessTempModel( ModelOverride modelOverride, Model model, boolean sortAllFaces, + int preOrientation, int orientation, int x, int y, int z ) { @@ -1741,6 +1760,24 @@ public boolean preprocessTempModel( orientCosf = COSINE[orientation] / 65536f; } + int offsetX = modelOverride.modelOffset[0]; + int offsetY = modelOverride.modelOffset[1]; + int offsetZ = modelOverride.modelOffset[2]; + + if(offsetX != 0 || offsetY != 0 || offsetZ != 0) { + if (modelOverride.modelOffsetRelative && (offsetX != 0 || offsetZ != 0) && (preOrientation != 0 || orientation != 0)) { + final int offsetOrientSin = SINE[mod(orientation != 0 ? orientation : preOrientation, 2048)]; + final int offsetOrientCos = COSINE[mod(orientation != 0 ? orientation : preOrientation, 2048)]; + + offsetX = modelOverride.modelOffset[2] * offsetOrientSin + modelOverride.modelOffset[0] * offsetOrientCos >> 16; + offsetZ = modelOverride.modelOffset[2] * offsetOrientCos - modelOverride.modelOffset[0] * offsetOrientSin >> 16; + } + + x += offsetX; + y += offsetY; + z += offsetZ; + } + boolean shouldSort = true; boolean allVertsVisible = true; for (int v = 0, vertexOffset = 0; v < vertexCount; ++v) { diff --git a/src/main/java/rs117/hd/scene/model_overrides/ModelOverride.java b/src/main/java/rs117/hd/scene/model_overrides/ModelOverride.java index 3b03fe3281..b288dbda29 100644 --- a/src/main/java/rs117/hd/scene/model_overrides/ModelOverride.java +++ b/src/main/java/rs117/hd/scene/model_overrides/ModelOverride.java @@ -81,6 +81,8 @@ public class ModelOverride public boolean invertDisplacementStrength = false; public int depthBias = -1; public boolean disablePrioritySorting = false; + public boolean modelOffsetRelative = false; + public int[] modelOffset = { 0, 0, 0, }; @JsonAdapter(AABB.ArrayAdapter.class) public AABB[] hideInAreas = {}; @@ -249,6 +251,8 @@ public ModelOverride copy() { invertDisplacementStrength, depthBias, disablePrioritySorting, + modelOffsetRelative, + modelOffset, hideInAreas, materialOverrides, colorOverrides, From f739d25e9eab315da9f69ad753f5784d7a0699f3 Mon Sep 17 00:00:00 2001 From: Ruffled <105522716+RuffledPlume@users.noreply.github.com> Date: Sat, 16 May 2026 23:06:44 +0100 Subject: [PATCH 2/2] Move ModelOffset calculation into ModelOverride to reduce duplicated code --- .../rs117/hd/renderer/zone/SceneUploader.java | 46 +++++-------------- .../scene/model_overrides/ModelOverride.java | 19 ++++++++ 2 files changed, 30 insertions(+), 35 deletions(-) diff --git a/src/main/java/rs117/hd/renderer/zone/SceneUploader.java b/src/main/java/rs117/hd/renderer/zone/SceneUploader.java index c5c5c583e8..9005d6d0d8 100644 --- a/src/main/java/rs117/hd/renderer/zone/SceneUploader.java +++ b/src/main/java/rs117/hd/renderer/zone/SceneUploader.java @@ -145,6 +145,7 @@ public interface OnBeforeProcessTileFunc { private final Material[] faceMaterials = new Material[MAX_FACE_COUNT]; private final UvType[] faceUVTypes = new UvType[MAX_FACE_COUNT]; + private final int[] modelOffset = new int[3]; private final float[] projected = new float[4]; // Lazily initialized staging buffers, only used by uploadTempModel @@ -772,13 +773,14 @@ private void uploadZoneRenderable( assert uz < 25 : uz; } try { + modelOverride.applyModelOffset(modelOffset, preOrientation, orient); zone.addAlphaModel( plugin, materialManager, zone.glVaoA, zone.tboF.getTexId(), model, modelOverride, alphaStart, alphaEnd, - x - basex, y, z - basez, + (x - basex) + modelOffset[0], y + modelOffset[1], (z - basez) + modelOffset[2], lx, lz, ux, uz, rid, level, id ); @@ -1396,23 +1398,10 @@ private int uploadStaticModel( orientCos = COSINE[orientation]; } - int offsetX = modelOverride.modelOffset[0]; - int offsetY = modelOverride.modelOffset[1]; - int offsetZ = modelOverride.modelOffset[2]; - - if(offsetX != 0 || offsetY != 0 || offsetZ != 0) { - if (modelOverride.modelOffsetRelative && (offsetX != 0 || offsetZ != 0) && (preOrientation != 0 || orientation != 0)) { - final int offsetOrientSin = SINE[mod(orientation != 0 ? orientation : preOrientation, 2048)]; - final int offsetOrientCos = COSINE[mod(orientation != 0 ? orientation : preOrientation, 2048)]; - - offsetX = modelOverride.modelOffset[2] * offsetOrientSin + modelOverride.modelOffset[0] * offsetOrientCos >> 16; - offsetZ = modelOverride.modelOffset[2] * offsetOrientCos - modelOverride.modelOffset[0] * offsetOrientSin >> 16; - } - - x += offsetX; - y += offsetY; - z += offsetZ; - } + modelOverride.applyModelOffset(modelOffset, preOrientation, orientation); + x += modelOffset[0]; + y += modelOffset[1]; + z += modelOffset[2]; for (int v = 0, vertexOffset = 0; v < vertexCount; ++v) { int vx = (int) vertexX[v]; @@ -1760,23 +1749,10 @@ public boolean preprocessTempModel( orientCosf = COSINE[orientation] / 65536f; } - int offsetX = modelOverride.modelOffset[0]; - int offsetY = modelOverride.modelOffset[1]; - int offsetZ = modelOverride.modelOffset[2]; - - if(offsetX != 0 || offsetY != 0 || offsetZ != 0) { - if (modelOverride.modelOffsetRelative && (offsetX != 0 || offsetZ != 0) && (preOrientation != 0 || orientation != 0)) { - final int offsetOrientSin = SINE[mod(orientation != 0 ? orientation : preOrientation, 2048)]; - final int offsetOrientCos = COSINE[mod(orientation != 0 ? orientation : preOrientation, 2048)]; - - offsetX = modelOverride.modelOffset[2] * offsetOrientSin + modelOverride.modelOffset[0] * offsetOrientCos >> 16; - offsetZ = modelOverride.modelOffset[2] * offsetOrientCos - modelOverride.modelOffset[0] * offsetOrientSin >> 16; - } - - x += offsetX; - y += offsetY; - z += offsetZ; - } + modelOverride.applyModelOffset(modelOffset, preOrientation, orientation); + x += modelOffset[0]; + y += modelOffset[1]; + z += modelOffset[2]; boolean shouldSort = true; boolean allVertsVisible = true; diff --git a/src/main/java/rs117/hd/scene/model_overrides/ModelOverride.java b/src/main/java/rs117/hd/scene/model_overrides/ModelOverride.java index b288dbda29..b8b97875ea 100644 --- a/src/main/java/rs117/hd/scene/model_overrides/ModelOverride.java +++ b/src/main/java/rs117/hd/scene/model_overrides/ModelOverride.java @@ -629,6 +629,25 @@ public void revertRotation(Model model) { } } + public void applyModelOffset(int[] result, int preOrientation, int orientation) { + int offsetX = modelOffset[0]; + int offsetY = modelOffset[1]; + int offsetZ = modelOffset[2]; + + if (modelOffsetRelative && (offsetX != 0 || offsetZ != 0) && (preOrientation != 0 || orientation != 0)) { + final int offsetOrientSin = SINE[mod(orientation != 0 ? orientation : preOrientation, 2048)]; + final int offsetOrientCos = COSINE[mod(orientation != 0 ? orientation : preOrientation, 2048)]; + + final int offsetXTemp = offsetX; + offsetX = offsetZ * offsetOrientSin + offsetXTemp * offsetOrientCos >> 16; + offsetZ = offsetZ * offsetOrientCos - offsetXTemp * offsetOrientSin >> 16; + } + + result[0] = offsetX; + result[1] = offsetY; + result[2] = offsetZ; + } + @Nullable public final ModelOverride testColorOverrides(int ahsl) { ModelOverride override = null;