From 5c18ad825bd1f9327fb11b95dd69a845e90a7755 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 4 Dec 2016 13:54:53 -0500 Subject: [PATCH] model viewer: allow viewing npcs with multiple models --- model-viewer/pom.xml | 6 + .../java/net/runelite/modelviewer/Camera.java | 2 +- .../net/runelite/modelviewer/ModelViewer.java | 162 +++++++++++++----- 3 files changed, 125 insertions(+), 45 deletions(-) diff --git a/model-viewer/pom.xml b/model-viewer/pom.xml index 99ed63dc7c..e60b5bb27c 100644 --- a/model-viewer/pom.xml +++ b/model-viewer/pom.xml @@ -66,6 +66,12 @@ 1.7.12 + + commons-cli + commons-cli + 1.3.1 + + junit junit diff --git a/model-viewer/src/main/java/net/runelite/modelviewer/Camera.java b/model-viewer/src/main/java/net/runelite/modelviewer/Camera.java index c2b639b77e..aef196670e 100644 --- a/model-viewer/src/main/java/net/runelite/modelviewer/Camera.java +++ b/model-viewer/src/main/java/net/runelite/modelviewer/Camera.java @@ -39,7 +39,7 @@ public class Camera { private static final float MAX_X = 89; - public float moveSpeed = 0.05f; + public float moveSpeed = 0.20f; private float mouseSensitivity = 0.05f; diff --git a/model-viewer/src/main/java/net/runelite/modelviewer/ModelViewer.java b/model-viewer/src/main/java/net/runelite/modelviewer/ModelViewer.java index 5474a35262..8df9cb49ea 100644 --- a/model-viewer/src/main/java/net/runelite/modelviewer/ModelViewer.java +++ b/model-viewer/src/main/java/net/runelite/modelviewer/ModelViewer.java @@ -29,28 +29,78 @@ */ package net.runelite.modelviewer; +import com.google.gson.Gson; import java.awt.Color; import java.io.File; +import java.io.FileInputStream; +import java.io.InputStreamReader; import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; import net.runelite.cache.definitions.ModelDefinition; +import net.runelite.cache.definitions.NpcDefinition; import net.runelite.cache.definitions.loaders.ModelLoader; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.Options; import org.lwjgl.opengl.Display; import org.lwjgl.opengl.DisplayMode; import org.lwjgl.opengl.GL11; +import static org.lwjgl.opengl.GL11.glRotatef; public class ModelViewer { public static void main(String[] args) throws Exception { - if (args.length < 1) - { - System.err.println("Usage: modelfile"); - System.exit(1); - } + Options options = new Options(); - ModelLoader loader = new ModelLoader(); - byte[] b = Files.readAllBytes(new File(args[0]).toPath()); - ModelDefinition md = loader.load(b); + options.addOption(null, "npcdir", true, "npc directory"); + options.addOption(null, "modeldir", true, "model directory"); + options.addOption(null, "npc", true, "npc to render"); + options.addOption(null, "model", true, "model to render"); + + CommandLineParser parser = new DefaultParser(); + CommandLine cmd = parser.parse(options, args); + + String npcdir = cmd.getOptionValue("npcdir"); + String modeldir = cmd.getOptionValue("modeldir"); + + NpcDefinition npcdef = null; + List models = new ArrayList<>(); + + if (cmd.hasOption("model")) + { + // render model + String model = cmd.getOptionValue("model"); + + ModelLoader loader = new ModelLoader(); + byte[] b = Files.readAllBytes(new File(modeldir + "/" + model + ".model").toPath()); + ModelDefinition md = loader.load(b); + models.add(md); + } + else if (cmd.hasOption("npc")) + { + String npc = cmd.getOptionValue("npc"); + + try (FileInputStream fin = new FileInputStream(npcdir + "/" + npc + ".json")) + { + npcdef = new Gson().fromJson(new InputStreamReader(fin), NpcDefinition.class); + } + + for (int model : npcdef.models) + { + ModelLoader mloader = new ModelLoader(); + byte[] b = Files.readAllBytes(new File(modeldir + "/" + model + ".model").toPath()); + ModelDefinition md = mloader.load(b); + models.add(md); + } + } + else + { + System.out.println("Must specify model or npc"); + return; + } Display.setDisplayMode(new DisplayMode(800, 600)); Display.setTitle("Model Viewer"); @@ -71,50 +121,20 @@ public class ModelViewer Camera camera = new Camera(); + GL11.glMatrixMode(GL11.GL_MODELVIEW); + glRotatef(45, 1, 0, 0); + GL11.glPopMatrix(); + while (!Display.isCloseRequested()) { // Clear the screen and depth buffer GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); - GL11.glBegin(GL11.GL_TRIANGLES); - - for (int i = 0; i < md.triangleFaceCount; ++i) + for (ModelDefinition def : models) { - int vertexA = md.trianglePointsX[i]; - int vertexB = md.trianglePointsY[i]; - int vertexC = md.trianglePointsZ[i]; - - int vertexAx = md.vertexX[vertexA]; - int vertexAy = md.vertexY[vertexA]; - int vertexAz = md.vertexZ[vertexA]; - - int vertexBx = md.vertexX[vertexB]; - int vertexBy = md.vertexY[vertexB]; - int vertexBz = md.vertexZ[vertexB]; - - int vertexCx = md.vertexX[vertexC]; - int vertexCy = md.vertexY[vertexC]; - int vertexCz = md.vertexZ[vertexC]; - - short hsb = md.faceColor[i]; - - int rgb = RS2HSB_to_RGB(hsb); - Color c = new Color(rgb); - - // convert to range of 0-1 - float rf = (float) c.getRed() / 255f; - float gf = (float) c.getGreen() / 255f; - float bf = (float) c.getBlue() / 255f; - - GL11.glColor3f(rf, gf, bf); - - GL11.glVertex3i(vertexAx, vertexAy, vertexAz); - GL11.glVertex3i(vertexBx, vertexBy, vertexBz); - GL11.glVertex3i(vertexCx, vertexCy, vertexCz); + drawModel(npcdef, def); } - GL11.glEnd(); - Display.update(); Display.sync(50); // fps @@ -128,6 +148,60 @@ public class ModelViewer Display.destroy(); } + private static void drawModel(NpcDefinition npcdef, ModelDefinition md) + { + GL11.glBegin(GL11.GL_TRIANGLES); + + for (int i = 0; i < md.triangleFaceCount; ++i) + { + int vertexA = md.trianglePointsX[i]; + int vertexB = md.trianglePointsY[i]; + int vertexC = md.trianglePointsZ[i]; + + int vertexAx = md.vertexX[vertexA]; + int vertexAy = md.vertexY[vertexA]; + int vertexAz = md.vertexZ[vertexA]; + + int vertexBx = md.vertexX[vertexB]; + int vertexBy = md.vertexY[vertexB]; + int vertexBz = md.vertexZ[vertexB]; + + int vertexCx = md.vertexX[vertexC]; + int vertexCy = md.vertexY[vertexC]; + int vertexCz = md.vertexZ[vertexC]; + + short hsb = md.faceColor[i]; + + // Check recolor + if (npcdef != null && npcdef.recolorToFind != null) + { + for (int j = 0; j < npcdef.recolorToFind.length; ++j) + { + if (npcdef.recolorToFind[j] == hsb) + { + hsb = npcdef.recolorToReplace[j]; + } + } + } + + int rgb = RS2HSB_to_RGB(hsb); + Color c = new Color(rgb); + + // convert to range of 0-1 + float rf = (float) c.getRed() / 255f; + float gf = (float) c.getGreen() / 255f; + float bf = (float) c.getBlue() / 255f; + + GL11.glColor3f(rf, gf, bf); + + GL11.glVertex3i(vertexAx, vertexAy, vertexAz); + GL11.glVertex3i(vertexBx, vertexBy, vertexBz); + GL11.glVertex3i(vertexCx, vertexCy, vertexCz); + } + + GL11.glEnd(); + } + // found these two functions here https://www.rune-server.org/runescape-development/rs2-client/tools/589900-rs2-hsb-color-picker.html public static int RGB_to_RS2HSB(int red, int green, int blue) {