diff --git a/runelite-api/src/main/java/net/runelite/api/IndexDataBase.java b/runelite-api/src/main/java/net/runelite/api/IndexDataBase.java index 8ffba7c9ef..2c25d61ee4 100644 --- a/runelite-api/src/main/java/net/runelite/api/IndexDataBase.java +++ b/runelite-api/src/main/java/net/runelite/api/IndexDataBase.java @@ -49,8 +49,6 @@ public interface IndexDataBase int[][] getFileIds(); - byte[] getFile(int groupId, int fileId); - int getGroupFileCount(int groupId); int[] getFileCounts(); diff --git a/runelite-api/src/main/java/net/runelite/api/Model.java b/runelite-api/src/main/java/net/runelite/api/Model.java index 0b38bcf3af..fdff0fcd11 100644 --- a/runelite-api/src/main/java/net/runelite/api/Model.java +++ b/runelite-api/src/main/java/net/runelite/api/Model.java @@ -24,10 +24,6 @@ */ package net.runelite.api; -import net.runelite.api.model.Triangle; -import net.runelite.api.model.Vertex; -import java.util.List; - /** * Represents the model of an object. */ diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java index ceadb07016..646bca55bf 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java @@ -69,6 +69,7 @@ import static net.runelite.api.MenuAction.UNKNOWN; import net.runelite.api.MenuEntry; import net.runelite.api.MessageNode; import net.runelite.api.Model; +import net.runelite.api.ModelData; import net.runelite.api.NPC; import net.runelite.api.NPCComposition; import net.runelite.api.NameableContainer; @@ -145,6 +146,7 @@ import net.runelite.rs.api.RSArchive; import net.runelite.rs.api.RSChatChannel; import net.runelite.rs.api.RSClanChannel; import net.runelite.rs.api.RSClient; +import net.runelite.rs.api.RSDualNode; import net.runelite.rs.api.RSEnumComposition; import net.runelite.rs.api.RSEvictingDualNodeHashTable; import net.runelite.rs.api.RSFriendSystem; @@ -292,6 +294,9 @@ public abstract class RSClientMixin implements RSClient @Inject public long delayNanoTime; + @Inject + public RSEvictingDualNodeHashTable tmpModelDataCache = newEvictingDualNodeHashTable(16); + @Inject private List outdatedScripts = new ArrayList<>(); @@ -1054,11 +1059,11 @@ public abstract class RSClientMixin implements RSClient int targetIndex = 0; if (target instanceof NPC) { - targetIndex = ((NPC)target).getIndex() + 1; + targetIndex = ((NPC) target).getIndex() + 1; } else if (target instanceof Player) { - targetIndex = -(((Player)target).getPlayerId() + 1); + targetIndex = -(((Player) target).getPlayerId() + 1); } RSProjectile projectile = client.newProjectile(id, plane, startX, startY, startZ, startCycle, endCycle, slope, startHeight, targetIndex, endHeight); @@ -2611,7 +2616,7 @@ public abstract class RSClientMixin implements RSClient { for (int i = 0; i < colorToFind.length; ++i) { - modeldata.recolor(colorToFind[i], colorToReplace[i]); + modeldata.rs$recolor(colorToFind[i], colorToReplace[i]); } } @@ -2791,5 +2796,45 @@ public abstract class RSClientMixin implements RSClient check("Widget_cachedSpriteMasks", client.getSpriteMasksCache()); check("WorldMapElement_cachedSprites", client.getSpritesCache()); } + + @Inject + @Override + public RSModelData mergeModels(ModelData[] var0, int var1) + { + return newModelData(var0, var1); + } + + @Inject + @Override + public RSModelData mergeModels(ModelData... var0) + { + return newModelData(var0, var0.length); + } + + @Inject + public IndexDataBase getIndex(int id) + { + return RSClientMixin.archives[id]; + } + + @Inject + @Override + public RSModelData loadModelData(int var0) + { + RSModelData modelData = (RSModelData) this.tmpModelDataCache.get(var0); + + if (modelData == null) + { + modelData = getModelData(RSClientMixin.archives[7], var0, 0); + if (modelData == null) + { + return null; + } + + this.tmpModelDataCache.put((RSDualNode) modelData, (long) var0); + } + + return modelData.newModelData(modelData, true, true, true, true); + } } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSModelDataMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSModelDataMixin.java index 15b1e4223f..af852eebc5 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSModelDataMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSModelDataMixin.java @@ -24,12 +24,18 @@ */ package net.runelite.mixins; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import net.runelite.api.Model; +import net.runelite.api.ModelData; import net.runelite.api.mixins.Copy; import net.runelite.api.mixins.Inject; import net.runelite.api.mixins.Mixin; import net.runelite.api.mixins.Replace; import net.runelite.api.mixins.Shadow; +import net.runelite.api.model.Triangle; +import net.runelite.api.model.Vertex; import net.runelite.rs.api.RSClient; import net.runelite.rs.api.RSModel; import net.runelite.rs.api.RSModelData; @@ -124,13 +130,13 @@ public abstract class RSModelDataMixin implements RSModelData return; } - final int[] vertexPositionsX = getVertexX(); - final int[] vertexPositionsY = getVertexY(); - final int[] vertexPositionsZ = getVertexZ(); + final int[] vertexPositionsX = getVerticesX(); + final int[] vertexPositionsY = getVerticesY(); + final int[] vertexPositionsZ = getVerticesZ(); - final int[] trianglePointsX = getTrianglePointsX(); - final int[] trianglePointsY = getTrianglePointsY(); - final int[] trianglePointsZ = getTrianglePointsZ(); + final int[] trianglePointsX = getFaceIndices1(); + final int[] trianglePointsY = getFaceIndices2(); + final int[] trianglePointsZ = getFaceIndices3(); final short[] texTriangleX = getTexTriangleX(); final short[] texTriangleY = getTexTriangleY(); @@ -138,7 +144,7 @@ public abstract class RSModelDataMixin implements RSModelData final byte[] textureCoords = getTextureCoords(); - int faceCount = getTriangleFaceCount(); + int faceCount = getFaceCount(); float[] faceTextureUCoordinates = new float[faceCount * 6]; for (int i = 0; i < faceCount; i++) @@ -222,4 +228,215 @@ public abstract class RSModelDataMixin implements RSModelData faceTextureUVCoordinates = faceTextureUCoordinates; } + + @Override + @Inject + public List getVertices() + { + int[] verticesX = getVerticesX(); + int[] verticesY = getVerticesY(); + int[] verticesZ = getVerticesZ(); + + List vertices = new ArrayList(getVerticesCount()); + + for (int i = 0; i < getVerticesCount(); ++i) + { + Vertex v = new Vertex( + verticesX[i], + verticesY[i], + verticesZ[i] + ); + vertices.add(v); + } + + return vertices; + } + + @Override + @Inject + public List getTriangles() + { + int[] trianglesX = getFaceIndices1(); + int[] trianglesY = getFaceIndices2(); + int[] trianglesZ = getFaceIndices3(); + + List vertices = getVertices(); + List triangles = new ArrayList<>(getFaceCount()); + + for (int i = 0; i < getFaceCount(); ++i) + { + int triangleX = trianglesX[i]; + int triangleY = trianglesY[i]; + int triangleZ = trianglesZ[i]; + + Triangle triangle = new Triangle( + vertices.get(triangleX), + vertices.get(triangleY), + vertices.get(triangleZ) + ); + triangles.add(triangle); + } + + return triangles; + } + + @Inject + @Override + public RSModel light() + { + return this.toModel(ModelData.DEFAULT_AMBIENT, ModelData.DEFAULT_CONTRAST, ModelData.DEFAULT_X, ModelData.DEFAULT_Y, ModelData.DEFAULT_Z); + } + + @Inject + @Override + public RSModel light(int var1, int var2, int var3, int var4, int var5) + { + return this.toModel(var1, var2, var3, var4, var5); + } + + @Inject + @Override + public RSModelData recolor(short colorToReplace, short colorToReplaceWith) + { + this.rs$recolor(colorToReplace, colorToReplaceWith); + + return this; + } + + @Inject + @Override + public RSModelData retexture(short find, short replace) + { + this.rs$retexture(find, replace); + + return this; + } + + @Inject + @Override + public RSModelData cloneVertices() + { + int[] newVericesX = Arrays.copyOf(this.getVerticesX(), this.getVerticesX().length); + int[] newVericesY = Arrays.copyOf(this.getVerticesY(), this.getVerticesX().length); + int[] newVericesZ = Arrays.copyOf(this.getVerticesZ(), this.getVerticesX().length); + + this.setVerticesX(newVericesX); + this.setVerticesY(newVericesY); + this.setVerticesZ(newVericesZ); + + return this; + } + + @Inject + @Override + public RSModelData cloneColors() + { + short[] newFaceColor = Arrays.copyOf(this.getFaceColors(), this.getFaceColors().length); + this.setFaceColors(newFaceColor); + + return this; + } + + @Inject + @Override + public RSModelData cloneTextures() + { + short[] newFaceColor = Arrays.copyOf(this.getFaceTextures(), this.getFaceTextures().length); + this.setFaceTextures(newFaceColor); + + return this; + } + + @Inject + @Override + public RSModelData cloneTransparencies() + { + byte[] newFaceColor = Arrays.copyOf(this.getFaceTransparencies(), this.getFaceTransparencies().length); + this.setFaceTransparencies(newFaceColor); + + return this; + } + + @Inject + @Override + public RSModelData rotateY90Ccw() + { + for (int var1 = 0; var1 < this.getVerticesCount(); ++var1) + { + int var2 = this.getVerticesX()[var1]; + this.getVerticesX()[var1] = this.getVerticesZ()[var1]; + this.getVerticesZ()[var1] = -var2; + } + + this.invalidate(); + + return this; + } + + @Inject + @Override + public RSModelData rotateY180Ccw() + { + for (int var1 = 0; var1 < this.getVerticesCount(); ++var1) + { + this.getVerticesX()[var1] = -this.getVerticesX()[var1]; + this.getVerticesZ()[var1] = -this.getVerticesZ()[var1]; + } + + this.invalidate(); + + return this; + } + + @Inject + @Override + public RSModelData rotateY270Ccw() + { + for (int var1 = 0; var1 < this.getVerticesCount(); ++var1) + { + int var2 = this.getVerticesZ()[var1]; + this.getVerticesZ()[var1] = this.getVerticesX()[var1]; + this.getVerticesX()[var1] = -var2; + } + + this.invalidate(); + + return this; + } + + @Inject + @Override + public RSModelData scale(int var1, int var2, int var3) + { + for (int i = 0; i < this.getVerticesCount(); ++i) + { + this.getVerticesX()[i] = this.getVerticesX()[i] * var1 / 128; + this.getVerticesY()[i] = this.getVerticesY()[i] * var2 / 128; + this.getVerticesZ()[i] = this.getVerticesZ()[i] * var3 / 128; + } + + this.invalidate(); + + return this; + } + + @Inject + @Override + public RSModelData translate(int var1, int var2, int var3) + { + for (int i = 0; i < this.getVerticesCount(); ++i) + { + int[] vertexX = this.getVerticesX(); + int[] vertexY = this.getVerticesY(); + int[] vertexZ = this.getVerticesZ(); + + vertexX[i] += var1; + vertexY[i] += var2; + vertexZ[i] += var3; + } + + this.invalidate(); + + return this; + } } \ No newline at end of file diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSModelMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSModelMixin.java index c18e32c59d..ad4bdb45e2 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSModelMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSModelMixin.java @@ -196,6 +196,51 @@ public abstract class RSModelMixin implements RSModel rsModel.setFaceTextureUVCoordinates(rl$faceTextureUVCoordinates); } + @Inject + @Override + public RSModel rotateY90Ccw() + { + this.rs$rotateY90Ccw(); + + return this; + } + + @Inject + @Override + public RSModel rotateY180Ccw() + { + this.rs$rotateY180Ccw(); + + return this; + } + + @Inject + @Override + public RSModel rotateY270Ccw() + { + this.rs$rotateY270Ccw(); + + return this; + } + + @Inject + @Override + public RSModel scale(int var1, int var2, int var3) + { + this.rs$scale(var1, var2, var3); + + return this; + } + + @Inject + @Override + public RSModel translate(int var1, int var2, int var3) + { + this.rs$translate(var1, var2, var3); + + return this; + } + @Inject public void interpolateFrames(RSFrames frames, int frameId, RSFrames nextFrames, int nextFrameId, int interval, int intervalCount) { diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSSequenceDefinitionMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSSequenceDefinitionMixin.java index 579835ce2d..69da68972d 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSSequenceDefinitionMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSSequenceDefinitionMixin.java @@ -125,30 +125,30 @@ public abstract class RSSequenceDefinitionMixin implements RSSequenceDefinition rotation &= 3; if (rotation == 1) { - animatedModel.rotateY270Ccw(); + animatedModel.rs$rotateY270Ccw(); } else if (rotation == 2) { - animatedModel.rotateY180Ccw(); + animatedModel.rs$rotateY180Ccw(); } else if (rotation == 3) { - animatedModel.rotateY90Ccw(); + animatedModel.rs$rotateY90Ccw(); } animatedModel.interpolateFrames(frames, frameIdx, nextFrames, nextFrameIdx, interval, getFrameLengths()[frame]); // reapply rotation after animating if (rotation == 1) { - animatedModel.rotateY90Ccw(); + animatedModel.rs$rotateY90Ccw(); } else if (rotation == 2) { - animatedModel.rotateY180Ccw(); + animatedModel.rs$rotateY180Ccw(); } else if (rotation == 3) { - animatedModel.rotateY270Ccw(); + animatedModel.rs$rotateY270Ccw(); } return animatedModel; } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSAbstractArchive.java b/runescape-api/src/main/java/net/runelite/rs/api/RSAbstractArchive.java index 1a0c8d2b68..ac7dd9c82e 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSAbstractArchive.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSAbstractArchive.java @@ -21,10 +21,6 @@ public interface RSAbstractArchive extends IndexDataBase @Override int[][] getFileIds(); - @Import("getFile") - @Override - byte[] getFile(int groupId, int fileId); - @Import("getGroupFileCount") @Override int getGroupFileCount(int groupId); @@ -32,4 +28,8 @@ public interface RSAbstractArchive extends IndexDataBase @Import("fileCounts") @Override int[] getFileCounts(); + + @Import("getFile") + @Override + byte[] loadData(int groupId, int fileId); } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java b/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java index 1e662044d5..8384c55b49 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java @@ -29,6 +29,7 @@ import java.util.Map; import net.runelite.api.AmbientSoundEffect; import net.runelite.api.Client; import net.runelite.api.Deque; +import net.runelite.api.ModelData; import net.runelite.api.SpritePixels; import net.runelite.api.World; import net.runelite.api.clan.ClanRank; @@ -1569,4 +1570,10 @@ public interface RSClient extends RSGameEngine, Client @Construct RSProjectile newProjectile(int var1, int var2, int var3, int var4, int var5, int var6, int var7, int var8, int var9, int var10, int var11); + + @Construct + RSModelData newModelData(ModelData[] var1, int var2); + + @Construct + RSEvictingDualNodeHashTable newEvictingDualNodeHashTable(int var1); } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSEvictingDualNodeHashTable.java b/runescape-api/src/main/java/net/runelite/rs/api/RSEvictingDualNodeHashTable.java index f4bf30fbc3..56b7084799 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSEvictingDualNodeHashTable.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSEvictingDualNodeHashTable.java @@ -8,6 +8,9 @@ public interface RSEvictingDualNodeHashTable extends NodeCache @Import("get") RSDualNode get(long id); + @Import("put") + void put(RSDualNode var1, long var2); + @Import("dualNode") RSDualNode getDualNode(); diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSModel.java b/runescape-api/src/main/java/net/runelite/rs/api/RSModel.java index afeacaabe9..4a4754f36b 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSModel.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSModel.java @@ -110,13 +110,19 @@ public interface RSModel extends RSRenderable, Model RSModel toSharedSpotAnimModel(boolean b); @Import("rotateY90Ccw") - void rotateY90Ccw(); + void rs$rotateY90Ccw(); @Import("rotateY180") - void rotateY180Ccw(); + void rs$rotateY180Ccw(); @Import("rotateY270Ccw") - void rotateY270Ccw(); + void rs$rotateY270Ccw(); + + @Import("scale") + void rs$scale(int var1, int var2, int var3); + + @Import("offsetBy") + void rs$translate(int var1, int var2, int var3); @Import("radius") @Override diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSModelData.java b/runescape-api/src/main/java/net/runelite/rs/api/RSModelData.java index 3d8cb0e9c0..2e85e438df 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSModelData.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSModelData.java @@ -1,29 +1,40 @@ package net.runelite.rs.api; +import net.runelite.api.ModelData; +import net.runelite.mapping.Construct; import net.runelite.mapping.Import; -public interface RSModelData extends RSRenderable +public interface RSModelData extends RSRenderable, ModelData { @Import("faceCount") - int getTriangleFaceCount(); + int getFaceCount(); @Import("indices1") - int[] getTrianglePointsX(); + int[] getFaceIndices1(); @Import("indices2") - int[] getTrianglePointsY(); + int[] getFaceIndices2(); @Import("indices3") - int[] getTrianglePointsZ(); + int[] getFaceIndices3(); @Import("verticesX") - int[] getVertexX(); + int[] getVerticesX(); + + @Import("verticesX") + void setVerticesX(int[] var1); @Import("verticesY") - int[] getVertexY(); + int[] getVerticesY(); + + @Import("verticesY") + void setVerticesY(int[] var1); @Import("verticesZ") - int[] getVertexZ(); + int[] getVerticesZ(); + + @Import("verticesZ") + void setVerticesZ(int[] var1); @Import("texTriangleX") short[] getTexTriangleX(); @@ -37,6 +48,21 @@ public interface RSModelData extends RSRenderable @Import("faceTextures") short[] getFaceTextures(); + @Import("faceTextures") + void setFaceTextures(short[] var1); + + @Import("faceAlphas") + byte[] getFaceTransparencies(); + + @Import("faceAlphas") + void setFaceTransparencies(byte[] var1); + + @Import("faceColors") + short[] getFaceColors(); + + @Import("faceColors") + void setFaceColors(short[] var1); + @Import("textureCoords") byte[] getTextureCoords(); @@ -53,7 +79,10 @@ public interface RSModelData extends RSRenderable RSVertexNormal[] getVertexVertices(); @Import("recolor") - void recolor(short var1, short var2); + void rs$recolor(short var1, short var2); + + @Import("retexture") + void rs$retexture(short var1, short var2); @Import("toModel") RSModel toModel(int var1, int var2, int var3, int var4, int var5); @@ -63,4 +92,13 @@ public interface RSModelData extends RSRenderable @Import("contrast") short getContrast(); + + @Import("invalidate") + void invalidate(); + + @Import("copyModelData") + RSModelData shallowCopy(); + + @Construct + RSModelData newModelData(ModelData var1, boolean var2, boolean var3, boolean var4, boolean var5); } diff --git a/runescape-client/src/main/java/ModelData.java b/runescape-client/src/main/java/ModelData.java index 0278204c71..42140520b6 100644 --- a/runescape-client/src/main/java/ModelData.java +++ b/runescape-client/src/main/java/ModelData.java @@ -1640,7 +1640,8 @@ public class ModelData extends Renderable { @ObfuscatedSignature( descriptor = "()Lge;" ) - public ModelData method3751() { + @Export("copyModelData") + public ModelData copyModelData() { ModelData var1 = new ModelData(); if (this.faceRenderTypes != null) { var1.faceRenderTypes = new byte[this.faceCount]; diff --git a/runescape-client/src/main/java/ObjectComposition.java b/runescape-client/src/main/java/ObjectComposition.java index 7ec9123cdf..f1c597c82b 100644 --- a/runescape-client/src/main/java/ObjectComposition.java +++ b/runescape-client/src/main/java/ObjectComposition.java @@ -612,7 +612,7 @@ public class ObjectComposition extends DualNode { } if (this.nonFlatShading) { - var9 = ((ModelData)var9).method3751(); + var9 = ((ModelData)var9).copyModelData(); } if (this.clipType >= 0) {