Add model dumper and basic model viewer
This commit is contained in:
218
model-viewer/src/main/java/net/runelite/modelviewer/Camera.java
Normal file
218
model-viewer/src/main/java/net/runelite/modelviewer/Camera.java
Normal file
@@ -0,0 +1,218 @@
|
||||
package net.runelite.modelviewer;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.input.Mouse;
|
||||
import static org.lwjgl.opengl.GL11.glRotatef;
|
||||
import static org.lwjgl.opengl.GL11.glTranslatef;
|
||||
|
||||
public class Camera {
|
||||
public static float moveSpeed = 0.05f;
|
||||
|
||||
private static float maxLook = 85;
|
||||
|
||||
private static float mouseSensitivity = 0.05f;
|
||||
|
||||
private static Vector3f pos;
|
||||
private static Vector3f rotation;
|
||||
|
||||
public static void create() {
|
||||
pos = new Vector3f(0, 0, 0);
|
||||
rotation = new Vector3f(0, 0, 0);
|
||||
}
|
||||
|
||||
public static void apply() {
|
||||
if(rotation.y / 360 > 1) {
|
||||
rotation.y -= 360;
|
||||
} else if(rotation.y / 360 < -1) {
|
||||
rotation.y += 360;
|
||||
}
|
||||
// glLoadIdentity();
|
||||
glRotatef(rotation.x, 1, 0, 0);
|
||||
glRotatef(rotation.y, 0, 1, 0);
|
||||
glRotatef(rotation.z, 0, 0, 1);
|
||||
glTranslatef(-pos.x, -pos.y, -pos.z);
|
||||
}
|
||||
|
||||
public static void acceptInput(float delta) {
|
||||
acceptInputRotate(delta);
|
||||
acceptInputGrab();
|
||||
acceptInputMove(delta);
|
||||
}
|
||||
|
||||
public static void acceptInputRotate(float delta) {
|
||||
if(Mouse.isGrabbed()) {
|
||||
float mouseDX = Mouse.getDX();
|
||||
float mouseDY = -Mouse.getDY();
|
||||
rotation.y += mouseDX * mouseSensitivity * delta;
|
||||
rotation.x += mouseDY * mouseSensitivity * delta;
|
||||
rotation.x = Math.max(-maxLook, Math.min(maxLook, rotation.x));
|
||||
}
|
||||
}
|
||||
|
||||
public static void acceptInputGrab() {
|
||||
if(Mouse.isInsideWindow() && Mouse.isButtonDown(0)) {
|
||||
Mouse.setGrabbed(true);
|
||||
}
|
||||
if(Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {
|
||||
Mouse.setGrabbed(false);
|
||||
}
|
||||
}
|
||||
|
||||
public static void acceptInputMove(float delta) {
|
||||
boolean keyUp = Keyboard.isKeyDown(Keyboard.KEY_W);
|
||||
boolean keyDown = Keyboard.isKeyDown(Keyboard.KEY_S);
|
||||
boolean keyRight = Keyboard.isKeyDown(Keyboard.KEY_D);
|
||||
boolean keyLeft = Keyboard.isKeyDown(Keyboard.KEY_A);
|
||||
boolean keyFast = Keyboard.isKeyDown(Keyboard.KEY_Q);
|
||||
boolean keySlow = Keyboard.isKeyDown(Keyboard.KEY_E);
|
||||
boolean keyFlyUp = Keyboard.isKeyDown(Keyboard.KEY_SPACE);
|
||||
boolean keyFlyDown = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT);
|
||||
|
||||
|
||||
float speed;
|
||||
|
||||
if(keyFast) {
|
||||
speed = moveSpeed * 5;
|
||||
}
|
||||
else if(keySlow) {
|
||||
speed = moveSpeed / 2;
|
||||
}
|
||||
else {
|
||||
speed = moveSpeed;
|
||||
}
|
||||
|
||||
speed *= delta;
|
||||
|
||||
if(keyFlyUp) {
|
||||
pos.y += speed;
|
||||
}
|
||||
if(keyFlyDown) {
|
||||
pos.y -= speed;
|
||||
}
|
||||
|
||||
if(keyDown) {
|
||||
pos.x -= Math.sin(Math.toRadians(rotation.y)) * speed;
|
||||
pos.z += Math.cos(Math.toRadians(rotation.y)) * speed;
|
||||
}
|
||||
if(keyUp) {
|
||||
pos.x += Math.sin(Math.toRadians(rotation.y)) * speed;
|
||||
pos.z -= Math.cos(Math.toRadians(rotation.y)) * speed;
|
||||
}
|
||||
if(keyLeft) {
|
||||
pos.x += Math.sin(Math.toRadians(rotation.y - 90)) * speed;
|
||||
pos.z -= Math.cos(Math.toRadians(rotation.y - 90)) * speed;
|
||||
}
|
||||
if(keyRight) {
|
||||
pos.x += Math.sin(Math.toRadians(rotation.y + 90)) * speed;
|
||||
pos.z -= Math.cos(Math.toRadians(rotation.y + 90)) * speed;
|
||||
}
|
||||
}
|
||||
|
||||
public static void setSpeed(float speed) {
|
||||
moveSpeed = speed;
|
||||
}
|
||||
|
||||
public static void setPos(Vector3f pos) {
|
||||
Camera.pos = pos;
|
||||
}
|
||||
|
||||
public static Vector3f getPos() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
public static void setX(float x) {
|
||||
pos.x = x;
|
||||
}
|
||||
|
||||
public static float getX() {
|
||||
return pos.x;
|
||||
}
|
||||
|
||||
public static void addToX(float x) {
|
||||
pos.x += x;
|
||||
}
|
||||
|
||||
public static void setY(float y) {
|
||||
pos.y = y;
|
||||
}
|
||||
|
||||
public static float getY() {
|
||||
return pos.y;
|
||||
}
|
||||
|
||||
public static void addToY(float y) {
|
||||
pos.y += y;
|
||||
}
|
||||
|
||||
public static void setZ(float z) {
|
||||
pos.z = z;
|
||||
}
|
||||
|
||||
public static float getZ() {
|
||||
return pos.z;
|
||||
}
|
||||
|
||||
public static void addToZ(float z) {
|
||||
pos.z += z;
|
||||
}
|
||||
|
||||
public static void setRotation(Vector3f rotation) {
|
||||
Camera.rotation = rotation;
|
||||
}
|
||||
|
||||
public static Vector3f getRotation() {
|
||||
return rotation;
|
||||
}
|
||||
|
||||
public static void setRotationX(float x) {
|
||||
rotation.x = x;
|
||||
}
|
||||
|
||||
public static float getRotationX() {
|
||||
return rotation.x;
|
||||
}
|
||||
|
||||
public static void addToRotationX(float x) {
|
||||
rotation.x += x;
|
||||
}
|
||||
|
||||
public static void setRotationY(float y) {
|
||||
rotation.y = y;
|
||||
}
|
||||
|
||||
public static float getRotationY() {
|
||||
return rotation.y;
|
||||
}
|
||||
|
||||
public static void addToRotationY(float y) {
|
||||
rotation.y += y;
|
||||
}
|
||||
|
||||
public static void setRotationZ(float z) {
|
||||
rotation.z = z;
|
||||
}
|
||||
|
||||
public static float getRotationZ() {
|
||||
return rotation.z;
|
||||
}
|
||||
|
||||
public static void addToRotationZ(float z) {
|
||||
rotation.z += z;
|
||||
}
|
||||
|
||||
public static void setMaxLook(float maxLook) {
|
||||
Camera.maxLook = maxLook;
|
||||
}
|
||||
|
||||
public static float getMaxLook() {
|
||||
return maxLook;
|
||||
}
|
||||
|
||||
public static void setMouseSensitivity(float mouseSensitivity) {
|
||||
Camera.mouseSensitivity = mouseSensitivity;
|
||||
}
|
||||
|
||||
public static float getMouseSensitivity() {
|
||||
return mouseSensitivity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Adam <Adam@sigterm.info>
|
||||
* 4. Neither the name of the Adam <Adam@sigterm.info> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY Adam <Adam@sigterm.info> ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL Adam <Adam@sigterm.info> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.modelviewer;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import net.runelite.cache.definitions.loaders.ModelLoader;
|
||||
import org.lwjgl.opengl.Display;
|
||||
import org.lwjgl.opengl.DisplayMode;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
public class ModelViewer
|
||||
{
|
||||
public static void main(String[] args) throws Exception
|
||||
{
|
||||
if (args.length < 1)
|
||||
{
|
||||
System.err.println("Usage: modelfile");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
ModelLoader md = new ModelLoader();
|
||||
byte[] b = Files.readAllBytes(new File(args[0]).toPath());
|
||||
md.load(b);
|
||||
|
||||
Display.setDisplayMode(new DisplayMode(800, 600));
|
||||
Display.setTitle("Model Viewer");
|
||||
Display.setInitialBackground((float) Color.gray.getRed() / 255f, (float) Color.gray.getGreen() / 255f, (float) Color.gray.getBlue() / 255f);
|
||||
Display.create();
|
||||
|
||||
GL11.glMatrixMode(GL11.GL_PROJECTION);
|
||||
GL11.glLoadIdentity();
|
||||
double aspect = 1;
|
||||
double near = 1; // near should be chosen as far into the scene as possible
|
||||
double far = 1000;
|
||||
double fov = 1; // 1 gives you a 90° field of view. It's tan(fov_angle)/2.
|
||||
GL11.glFrustum(-aspect * near * fov, aspect * near * fov, -fov, fov, near, far);
|
||||
|
||||
GL11.glCullFace(GL11.GL_BACK);
|
||||
|
||||
long last = 0;
|
||||
|
||||
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)
|
||||
{
|
||||
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 - 50);
|
||||
GL11.glVertex3i(vertexBx, vertexBy, vertexBz - 50);
|
||||
GL11.glVertex3i(vertexCx, vertexCy, vertexCz - 50);
|
||||
}
|
||||
|
||||
GL11.glEnd();
|
||||
|
||||
Display.update();
|
||||
Display.sync(50); // fps
|
||||
|
||||
long delta = System.currentTimeMillis() - last;
|
||||
last = System.currentTimeMillis();
|
||||
|
||||
Camera.create();
|
||||
Camera.acceptInput(delta);
|
||||
|
||||
Camera.apply();
|
||||
}
|
||||
|
||||
Display.destroy();
|
||||
}
|
||||
|
||||
// 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) {
|
||||
float[] HSB = Color.RGBtoHSB(red, green, blue, null);
|
||||
float hue = (HSB[0]);
|
||||
float saturation = (HSB[1]);
|
||||
float brightness = (HSB[2]);
|
||||
int encode_hue = (int) (hue * 63); //to 6-bits
|
||||
int encode_saturation = (int) (saturation * 7); //to 3-bits
|
||||
int encode_brightness = (int) (brightness * 127); //to 7-bits
|
||||
return (encode_hue << 10) + (encode_saturation << 7) + (encode_brightness);
|
||||
}
|
||||
|
||||
public static int RS2HSB_to_RGB(int RS2HSB) {
|
||||
int decode_hue = (RS2HSB >> 10) & 0x3f;
|
||||
int decode_saturation = (RS2HSB >> 7) & 0x07;
|
||||
int decode_brightness = (RS2HSB & 0x7f);
|
||||
return Color.HSBtoRGB((float)decode_hue/63, (float)decode_saturation/7, (float)decode_brightness/127);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Adam <Adam@sigterm.info>
|
||||
* 4. Neither the name of the Adam <Adam@sigterm.info> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY Adam <Adam@sigterm.info> ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL Adam <Adam@sigterm.info> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.modelviewer;
|
||||
|
||||
public class Vector3f
|
||||
{
|
||||
public float x, y, z;
|
||||
|
||||
public Vector3f(float x, float y, float z)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "Vector3f{" + "x=" + x + ", y=" + y + ", z=" + z + '}';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user