Remove model viewer

It was subtree split to https://github.com/runelite/modelviewer
This commit is contained in:
Adam
2018-10-31 17:55:42 -04:00
parent 2496e9e2a7
commit 97849ee1c2
13 changed files with 0 additions and 2592 deletions

View File

@@ -10,7 +10,6 @@ If you have any questions, please join our IRC channel on [irc.rizon.net #runeli
- [cache](cache/src/main/java/net/runelite/cache) - Libraries used for reading/writing cache files, as well as the data in it
- [http-api](http-api/src/main/java/net/runelite/http/api) - API for api.runelite.net
- [http-service](http-service/src/main/java/net/runelite/http/service) - Service for api.runelite.net
- [model-viewer](model-viewer/src/main/java/net/runelite/modelviewer) - RS Model, NPC/Object, and terrain viewer
- [runelite-api](runelite-api/src/main/java/net/runelite/api) - RuneLite API, interfaces for accessing the client
- [runelite-mixins](runelite-mixins/src/main/java/net/runelite) - Mixins which are injected into the injected client's classes
- [runescape-api](runescape-api/src/main/java/net/runelite) - Mappings correspond to these interfaces, runelite-api is a subset of this

View File

@@ -1,105 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2016-2017, 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.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>net.runelite</groupId>
<artifactId>runelite-parent</artifactId>
<version>1.4.24-SNAPSHOT</version>
</parent>
<artifactId>modelviewer</artifactId>
<name>Model Viewer</name>
<dependencies>
<dependency>
<groupId>net.runelite</groupId>
<artifactId>cache</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.lwjgl.lwjgl</groupId>
<artifactId>lwjgl</artifactId>
<version>2.9.3</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.googlecode.mavennatives</groupId>
<artifactId>maven-nativedependencies-plugin</artifactId>
<version>0.0.6</version>
<executions>
<execution>
<id>unpacknatives</id>
<phase>generate-resources</phase>
<goals>
<!--suppress MavenModelInspection (this line is for IDEA)-->
<goal>copy</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -1,212 +0,0 @@
/*
* Copyright (c) 2016-2017, 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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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 net.runelite.cache.models.Vector3f;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import static org.lwjgl.opengl.GL11.glRotatef;
import static org.lwjgl.opengl.GL11.glTranslatef;
public class Camera
{
private static final float MAX_X = 89;
public float moveSpeed = 0.60f;
private float mouseSensitivity = 0.05f;
private Vector3f pos = new Vector3f(0, 0, 0);
private Vector3f rotation = new Vector3f(0, 0, 0);
public void apply()
{
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.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 void acceptInput(float delta)
{
acceptInputRotate(delta);
acceptInputGrab();
acceptInputMove(delta);
}
public 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.y %= 360.0f;
rotation.x %= 360.0f;
// bound y between (-180, 180]
if (rotation.y > 180.0f)
{
rotation.y = -360.0f + rotation.y;
}
if (rotation.y <= -180.0f)
{
rotation.y = 360.0f + rotation.y;
}
// cap x to prevent from flipping upsidedown
if (rotation.x < -MAX_X)
{
rotation.x = -MAX_X;
}
if (rotation.x > MAX_X)
{
rotation.x = MAX_X;
}
}
}
public void acceptInputGrab()
{
if (Mouse.isInsideWindow() && Mouse.isButtonDown(0))
{
Mouse.setGrabbed(true);
}
if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE) || Keyboard.isKeyDown(Keyboard.KEY_LMENU))
{
Mouse.setGrabbed(false);
}
}
public 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;
// sin(0) = 0
// cos(0) = 1
if (keyFlyUp)
{
pos.y += Math.cos(Math.toRadians(rotation.x)) * speed;
pos.z -= Math.cos(Math.toRadians(rotation.y)) * Math.sin(Math.toRadians(rotation.x)) * speed;
pos.x += Math.sin(Math.toRadians(rotation.x)) * Math.sin(Math.toRadians(rotation.y)) * speed;
}
if (keyFlyDown)
{
pos.y -= Math.cos(Math.toRadians(rotation.x)) * speed;
pos.z += Math.cos(Math.toRadians(rotation.y)) * Math.sin(Math.toRadians(rotation.x)) * speed;
pos.x -= Math.sin(Math.toRadians(rotation.x)) * Math.sin(Math.toRadians(rotation.y)) * speed;
}
if (keyDown)
{
pos.x -= Math.sin(Math.toRadians(rotation.y)) * speed;
pos.z += Math.cos(Math.toRadians(rotation.x)) * Math.cos(Math.toRadians(rotation.y)) * speed;
pos.y += Math.sin(Math.toRadians(rotation.x)) * speed;
}
if (keyUp)
{
pos.x += Math.sin(Math.toRadians(rotation.y)) * speed;
pos.z -= Math.cos(Math.toRadians(rotation.x)) * Math.cos(Math.toRadians(rotation.y)) * speed;
pos.y -= Math.sin(Math.toRadians(rotation.x)) * 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 void setSpeed(float speed)
{
moveSpeed = speed;
}
public void setPos(Vector3f pos)
{
this.pos = pos;
}
public Vector3f getPos()
{
return pos;
}
public Vector3f getRotation()
{
return rotation;
}
public void setRotation(Vector3f rotation)
{
this.rotation = rotation;
}
public void setMouseSensitivity(float mouseSensitivity)
{
this.mouseSensitivity = mouseSensitivity;
}
public float getMouseSensitivity()
{
return mouseSensitivity;
}
}

View File

@@ -1,64 +0,0 @@
/*
* Copyright (c) 2017, 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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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 com.google.gson.Gson;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import net.runelite.cache.definitions.KitDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class KitManager
{
private static final Logger logger = LoggerFactory.getLogger(KitManager.class);
private static Map<Integer, KitDefinition> kits = new HashMap<>();
public static KitDefinition getKit(int id)
{
KitDefinition def = kits.get(id);
if (def != null)
{
return def;
}
try (FileInputStream in = new FileInputStream(new File("kits/" + id + ".json")))
{
def = new Gson().fromJson(new InputStreamReader(in), KitDefinition.class);
kits.put(id, def);
return def;
}
catch (IOException ex)
{
logger.warn(null, ex);
return null;
}
}
}

View File

@@ -1,36 +0,0 @@
/*
* Copyright (c) 2017, 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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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 lombok.Value;
@Value
public class ModelKey
{
private final int modelId;
private final int defId;
private final int type;
private final int orientation;
}

View File

@@ -1,181 +0,0 @@
/*
* Copyright (c) 2017, 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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
import net.runelite.cache.IndexType;
import net.runelite.cache.definitions.ModelDefinition;
import net.runelite.cache.definitions.ObjectDefinition;
import net.runelite.cache.definitions.loaders.ModelLoader;
import net.runelite.cache.fs.Archive;
import net.runelite.cache.fs.Index;
import net.runelite.cache.fs.Storage;
import net.runelite.cache.fs.Store;
import net.runelite.cache.region.Location;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ModelManager
{
private static final Logger logger = LoggerFactory.getLogger(ModelManager.class);
private final Store store;
private final Map<ModelKey, ModelDefinition> models = new HashMap<>();
private final ModelLoader loader = new ModelLoader();
public ModelManager(Store store)
{
this.store = store;
}
public ModelDefinition getModel(int id)
{
return this.getModel(new ModelKey(id, -1, -1, -1), null);
}
public ModelDefinition getModel(int id, ObjectDefinition object, Location location)
{
final int type, rot;
if (location != null)
{
type = location.getType();
rot = location.getOrientation();
}
else
{
type = rot = 0;
}
return this.getModel(new ModelKey(id, object.getId(), type, rot), md ->
{
// this logic is from method3697 in 140
if (object.getObjectTypes() == null)
{
boolean isRotate = object.isRotated();
if (type == 2 && rot > 3)
{
isRotate = !isRotate;
}
if (isRotate)
{
md.method1493();
}
}
else
{
boolean isRotate = object.isRotated() ^ rot > 3;
if (isRotate)
{
md.method1493();
}
}
if (type == 4 && rot > 3)
{
md.rotate(256);
md.move(45, 0, -45);
}
switch (rot & 3)
{
case 1:
md.rotate1();
break;
case 2:
md.rotate2();
break;
case 3:
md.rotate3();
break;
}
short[] recolorToFind = object.getRecolorToFind();
if (recolorToFind != null)
{
short[] recolorToReplace = object.getRecolorToReplace();
for (int i = 0; i < recolorToFind.length; ++i)
{
md.recolor(recolorToFind[i], recolorToReplace[i]);
}
}
short[] retextureToFind = object.getRetextureToFind();
if (retextureToFind != null)
{
short[] textureToReplace = object.getTextureToReplace();
for (int i = 0; i < retextureToFind.length; ++i)
{
md.retexture(retextureToFind[i], textureToReplace[i]);
}
}
if (object.getModelSizeX() != 128 || object.getModelSizeHeight() != 128 || object.getModelSizeY() != 128)
{
md.resize(object.getModelSizeX(), object.getModelSizeHeight(), object.getModelSizeY());
}
if (object.getOffsetX() != 0 || object.getOffsetHeight() != 0 || object.getOffsetY() != 0)
{
md.move((short) object.getOffsetX(), (short) object.getOffsetHeight(), (short) object.getOffsetY());
}
});
}
private ModelDefinition getModel(ModelKey key, Consumer<ModelDefinition> loadConsumer)
{
ModelDefinition md = models.get(key);
if (md != null)
{
return md;
}
Storage storage = store.getStorage();
Index index = store.getIndex(IndexType.MODELS);
Archive modelArchive = index.getArchive(key.getModelId());
byte[] contents;
try
{
contents = modelArchive.decompress(storage.loadArchive(modelArchive));
}
catch (IOException e)
{
throw new RuntimeException(e);
}
md = loader.load(modelArchive.getArchiveId(), contents);
if (loadConsumer != null)
{
loadConsumer.accept(md);
}
md.computeNormals();
md.computeMaxPriority();
models.put(key, md);
return md;
}
}

View File

@@ -1,999 +0,0 @@
/*
* Copyright (c) 2016-2018, 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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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 com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import java.awt.Color;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import net.runelite.cache.ConfigType;
import net.runelite.cache.IndexType;
import net.runelite.cache.NpcManager;
import net.runelite.cache.ObjectManager;
import net.runelite.cache.OverlayManager;
import net.runelite.cache.SpriteManager;
import net.runelite.cache.TextureManager;
import net.runelite.cache.UnderlayManager;
import net.runelite.cache.definitions.FrameDefinition;
import net.runelite.cache.definitions.FramemapDefinition;
import net.runelite.cache.definitions.KitDefinition;
import net.runelite.cache.definitions.LocationsDefinition;
import net.runelite.cache.definitions.MapDefinition;
import net.runelite.cache.definitions.ModelDefinition;
import net.runelite.cache.definitions.NpcDefinition;
import net.runelite.cache.definitions.ObjectDefinition;
import net.runelite.cache.definitions.SequenceDefinition;
import net.runelite.cache.definitions.SpriteDefinition;
import net.runelite.cache.definitions.TextureDefinition;
import net.runelite.cache.definitions.loaders.FrameLoader;
import net.runelite.cache.definitions.loaders.FramemapLoader;
import net.runelite.cache.definitions.loaders.LocationsLoader;
import net.runelite.cache.definitions.loaders.MapLoader;
import net.runelite.cache.definitions.loaders.SequenceLoader;
import net.runelite.cache.fs.Archive;
import net.runelite.cache.fs.ArchiveFiles;
import net.runelite.cache.fs.FSFile;
import net.runelite.cache.fs.Index;
import net.runelite.cache.fs.Storage;
import net.runelite.cache.fs.Store;
import net.runelite.cache.item.ColorPalette;
import net.runelite.cache.models.Vector3f;
import net.runelite.cache.models.VertexNormal;
import net.runelite.cache.region.Location;
import net.runelite.cache.region.Position;
import net.runelite.cache.region.Region;
import net.runelite.cache.util.XteaKeyManager;
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.GL_NEAREST;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MAG_FILTER;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MIN_FILTER;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_S;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_T;
import static org.lwjgl.opengl.GL11.glStencilMask;
import static org.lwjgl.opengl.GL11.glTexParameteri;
import static org.lwjgl.opengl.GL12.GL_CLAMP_TO_EDGE;
import static org.lwjgl.opengl.GL43.GL_DEBUG_OUTPUT;
import static org.lwjgl.opengl.GL43.glDebugMessageCallback;
import org.lwjgl.opengl.KHRDebugCallback;
import org.lwjgl.opengl.PixelFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ModelViewer
{
private static final Logger logger = LoggerFactory.getLogger(ModelViewer.class);
/**
* size of a tile in local coordinates
*/
private static final int TILE_SCALE = 128;
private static final int[] palette = new ColorPalette(0.6, 0, 512).getColorPalette();//0.6, 0.7, 0.8, 0.9
private static ObjectManager objectManager;
private static TextureManager textureManager;
private static SpriteManager spriteManager;
private static ModelManager modelManager;
private static Map<Integer, Texture> textures = new HashMap<>();
private static Map<Integer, SequenceDefinition> seqs = new HashMap<>();
private static Multimap<Integer, FrameDefinition> frames = HashMultimap.create();
public static void main(String[] args) throws Exception
{
Options options = new Options();
options.addOption(null, "store", true, "store directory");
options.addOption(null, "objectdir", true, "objects directory");
options.addOption(null, "npc", true, "npc to render");
options.addOption(null, "object", true, "object to render");
options.addOption(null, "model", true, "model to render");
options.addOption(null, "map", true, "map region to render");
options.addOption(null, "kits", true, "kits to render");
options.addOption(null, "seq", true, "sequence id");
CommandLineParser parser = new DefaultParser();
CommandLine cmd = parser.parse(options, args);
NpcDefinition npcdef = null;
ObjectDefinition objdef = null;
Store store = null;
UnderlayManager underlayManager = null;
OverlayManager overlayManager = null;
NpcManager npcManager = null;
Integer seq = null;
List<ModelDefinition> models = new ArrayList<>();
Region region = null;
if (cmd.hasOption("store"))
{
store = new Store(new File(cmd.getOptionValue("store")));
store.load();
underlayManager = new UnderlayManager(store);
underlayManager.load();
overlayManager = new OverlayManager(store);
overlayManager.load();
objectManager = new ObjectManager(store);
objectManager.load();
textureManager = new TextureManager(store);
textureManager.load();
spriteManager = new SpriteManager(store);
spriteManager.load();
npcManager = new NpcManager(store);
npcManager.load();
modelManager = new ModelManager(store);
if (cmd.hasOption("seq"))
{
loadSeqs(store);
loadFrames(store);
}
}
if (cmd.hasOption("model"))
{
// render model
String model = cmd.getOptionValue("model");
ModelDefinition md = modelManager.getModel(Integer.parseInt(model));
models.add(md);
}
if (cmd.hasOption("npc"))
{
String npc = cmd.getOptionValue("npc");
npcdef = npcManager.get(Integer.parseInt(npc));
for (int model : npcdef.models)
{
ModelDefinition md = modelManager.getModel(model);
for (int i = 0; i < npcdef.recolorToFind.length; i++)
{
md.recolor(npcdef.recolorToFind[i], npcdef.recolorToReplace[i]);
}
models.add(md);
}
}
if (cmd.hasOption("object"))
{
String obj = cmd.getOptionValue("object");
objdef = objectManager.getObject(Integer.parseInt(obj));
for (int model : objdef.getObjectModels())
{
models.add(modelManager.getModel(model, objdef, null));
}
}
if (cmd.hasOption("map"))
{
String map = cmd.getOptionValue("map");
String[] s = map.split(",");
int x, y;
if (s.length == 1)
{
int regionId = Integer.parseInt(s[0]);
x = regionId >> 8;
y = regionId & 0xFF;
}
else
{
x = Integer.parseInt(s[0]);
y = Integer.parseInt(s[1]);
}
XteaKeyManager keyManager = new XteaKeyManager();
keyManager.loadKeys();
int[] keys = keyManager.getKeys(x << 8 | y);
Storage storage = store.getStorage();
Index index = store.getIndex(IndexType.MAPS);
Archive mapArchive = index.findArchiveByName("m" + x + "_" + y);
Archive locationsArchive = index.findArchiveByName("l" + x + "_" + y);
region = new Region(x, y);
byte[] mapData = mapArchive.decompress(storage.loadArchive(mapArchive));
MapLoader mapLoader = new MapLoader();
MapDefinition mapDef = mapLoader.load(x, y, mapData);
region.loadTerrain(mapDef);
if (keys != null)
{
byte[] locationData = locationsArchive.decompress(storage.loadArchive(locationsArchive), keys);
LocationsLoader locationsLoader = new LocationsLoader();
LocationsDefinition locDef = locationsLoader.load(x, y, locationData);
region.loadLocations(locDef);
}
}
if (cmd.hasOption("kits"))
{
String kits = cmd.getOptionValue("kits");
Integer[] kitIds = Arrays.stream(kits.split(",")).map(s -> Integer.parseInt(s)).toArray(Integer[]::new);
for (int kitId : kitIds)
{
KitDefinition kit = KitManager.getKit(kitId);
for (int model : kit.modelIds)
{
ModelDefinition md = modelManager.getModel(model);
models.add(md);
}
}
}
if (cmd.hasOption("seq"))
{
seq = Integer.parseInt(cmd.getOptionValue("seq"));
}
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(new PixelFormat(0, 8, 8));
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 = 10000;
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.glEnable(GL_DEBUG_OUTPUT);
glDebugMessageCallback(new KHRDebugCallback());
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glCullFace(GL11.GL_BACK);
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
long last = 0;
Camera camera = new Camera();
Scene scene = null;
if (region != null)
{
scene = new Scene(underlayManager, overlayManager);
scene.loadRegion(region, objectManager);
}
SequenceDefinition sequenceDefinition = null;
int frameCount = 0;
int frameLength = 0;
if (seq != null)
{
sequenceDefinition = seqs.get(seq);
frameCount = 0;
frameLength = sequenceDefinition.frameLenghts[0];
}
while (!Display.isCloseRequested())
{
// Clear the screen and depth buffer
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
if (seq != null)
{
if (frameLength-- <= 0)
{
frameCount++;
frameLength = sequenceDefinition.frameLenghts[frameCount % sequenceDefinition.frameIDs.length];
}
int seqFrameId = sequenceDefinition.frameIDs[frameCount % sequenceDefinition.frameIDs.length];
Collection<FrameDefinition> frames = ModelViewer.frames.get(seqFrameId >>> 16);
int frameFileId = seqFrameId & 65535;
Optional<FrameDefinition> first = frames.stream().filter(frame -> frame.id == frameFileId).findFirst();
FrameDefinition frame = first.get();
FramemapDefinition framemap = frame.framemap;
ModelDefinition.animOffsetX = ModelDefinition.animOffsetY = ModelDefinition.animOffsetZ = 0;
for (ModelDefinition def : models)
{
def.resetAnim();
}
for (int i = 0; i < frame.translatorCount; ++i)
{
int type = frame.indexFrameIds[i];
int fmType = framemap.types[type];
int[] fm = framemap.frameMaps[type];
int dx = frame.translator_x[i];
int dy = frame.translator_y[i];
int dz = frame.translator_z[i];
for (ModelDefinition def : models)
{
def.animate(fmType, fm, dx, dy, dz);
}
}
}
GL11.glClear(GL11.GL_STENCIL_BUFFER_BIT);
for (int prio = 255; prio >= 0; --prio)
{
for (ModelDefinition def : models)
{
drawModel(def, prio, prio == 255);
}
}
if (region != null)
{
drawScene(region, scene);
}
Display.update();
Display.sync(50); // fps
long delta = System.currentTimeMillis() - last;
last = System.currentTimeMillis();
camera.acceptInput(delta);
camera.apply();
}
Display.destroy();
}
private static void drawModel(ModelDefinition md, int prio, boolean first)
{
GL11.glEnable(GL11.GL_STENCIL_TEST);
glStencilMask(0xff);
GL11.glStencilOp(GL11.GL_KEEP, GL11.GL_REPLACE, GL11.GL_REPLACE);
GL11.glStencilFunc(GL11.GL_GEQUAL, prio, 0xff);
for (int i = 0; i < md.faceCount; ++i)
{
if (md.faceRenderTypes != null)
{
byte faceRenderType = md.faceRenderTypes[i];
if ((faceRenderType & 2) != 0)
{
continue; // what is this?
}
}
int vertexA = md.faceVertexIndices1[i];
int vertexB = md.faceVertexIndices2[i];
int vertexC = md.faceVertexIndices3[i];
if (md.faceRenderPriorities != null)
{
int priority = md.faceRenderPriorities[i] & 0xFF;
if (priority != prio)
{
continue;
}
}
else
{
if (!first)
{
continue;
}
}
VertexNormal normalVertexA = md.vertexNormals[vertexA];
VertexNormal normalVertexB = md.vertexNormals[vertexB];
VertexNormal normalVertexC = md.vertexNormals[vertexC];
Vector3f nA = normalVertexA.normalize();
Vector3f nB = normalVertexB.normalize();
Vector3f nC = normalVertexC.normalize();
// Invert y
nA.y = -nA.y;
nB.y = -nB.y;
nC.y = -nC.y;
// and z
nA.z = -nA.z;
nB.z = -nB.z;
nC.z = -nC.z;
int vertexAx = md.vertexPositionsX[vertexA];
int vertexAy = md.vertexPositionsY[vertexA];
int vertexAz = md.vertexPositionsZ[vertexA];
int vertexBx = md.vertexPositionsX[vertexB];
int vertexBy = md.vertexPositionsY[vertexB];
int vertexBz = md.vertexPositionsZ[vertexB];
int vertexCx = md.vertexPositionsX[vertexC];
int vertexCy = md.vertexPositionsY[vertexC];
int vertexCz = md.vertexPositionsZ[vertexC];
short textureId = md.faceTextures != null ? md.faceTextures[i] : -1;
int alpha = md.faceAlphas != null ? (md.faceAlphas[i] & 0xFF) : 255;
if (alpha == 0)
{
alpha = 255;
}
Color color;
float[] u = null;
float[] v = null;
if (textureId != -1)
{
color = Color.WHITE;
Texture texture = getTexture(textureId);
assert texture != null;
if (md.faceTextureUCoordinates == null || md.faceTextureVCoordinates == null)
{
md.computeTextureUVCoordinates();
}
u = md.faceTextureUCoordinates[i];
v = md.faceTextureVCoordinates[i];
int glTexture = texture.getOpenglId();
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, glTexture);
}
else
{
color = new Color(getPaletteColor(md.faceColors[i]));
}
// convert to range of 0-1
float rf = (float) color.getRed() / 255f;
float gf = (float) color.getGreen() / 255f;
float bf = (float) color.getBlue() / 255f;
float af = (float) alpha / 255f;
GL11.glBegin(GL11.GL_TRIANGLES);
GL11.glColor4f(rf, gf, bf, af);
GL11.glNormal3f(nA.x, nA.y, nA.z);
if (textureId != -1)
{
GL11.glTexCoord2f(u[0], v[0]);
}
GL11.glVertex3i(vertexAx, -vertexAy, -vertexAz);
GL11.glNormal3f(nB.x, nB.y, nB.z);
if (textureId != -1)
{
GL11.glTexCoord2f(u[1], v[1]);
}
GL11.glVertex3i(vertexBx, -vertexBy, -vertexBz);
GL11.glNormal3f(nC.x, nC.y, nC.z);
if (textureId != -1)
{
GL11.glTexCoord2f(u[2], v[2]);
}
GL11.glVertex3i(vertexCx, -vertexCy, -vertexCz);
GL11.glEnd();
if (textureId != -1)
{
GL11.glDisable(GL11.GL_TEXTURE_2D);
}
}
GL11.glDisable(GL11.GL_STENCIL_TEST);
}
private static void drawScene(Region region, Scene scene)
{
for (int z = 0; z < Region.Z; ++z)
{
SceneTileModel[][] sceneTileModels = scene.getSceneTiles()[z];
SceneTilePaint[][] sceneTilePaint = scene.getSceneTilePaint()[z];
for (int x = 0; x < Region.X; ++x)
{
for (int y = 0; y < Region.Y; ++y)
{
SceneTilePaint paint = sceneTilePaint[x][y];
if (paint != null)
{
drawSceneTilePaint(region, x, y, z, paint);
}
else
{
drawSceneTileModel(region, x, y, z, sceneTileModels[x][y]);
}
}
}
}
drawLocations(region);
}
private static void drawSceneTilePaint(Region region, int regionX, int regionY, int z, SceneTilePaint sceneTilePaint)
{
if (sceneTilePaint == null)
{
return;
}
int glTexture = -1;
Color swColor;
Color seColor;
Color neColor;
Color nwColor;
if (sceneTilePaint.texture > -1)
{
swColor = seColor = neColor = nwColor = Color.WHITE;
Texture texture = getTexture(sceneTilePaint.texture);
glTexture = texture.getOpenglId();
assert glTexture > -1;
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, glTexture);
}
else
{
if (sceneTilePaint.swColor == 12345678)
{
return;
}
swColor = new Color(getPaletteColor(sceneTilePaint.swColor));
seColor = new Color(getPaletteColor(sceneTilePaint.seColor));
neColor = new Color(getPaletteColor(sceneTilePaint.neColor));
nwColor = new Color(getPaletteColor(sceneTilePaint.nwColor));
}
GL11.glBegin(GL11.GL_TRIANGLES);
int x = regionX * TILE_SCALE;
int y = regionY * TILE_SCALE;
int z1 = -region.getTileHeight(z, regionX, regionY);
int z2 = regionX + 1 < Region.X ? -region.getTileHeight(z, regionX + 1, regionY) : z1;
int z3 = regionY + 1 < Region.Y ? -region.getTileHeight(z, regionX, regionY + 1) : z1;
int z4 = regionX + 1 < Region.X && regionY + 1 < Region.Y ? -region.getTileHeight(z, regionX + 1, regionY + 1) : z1;
// triangle 1
glColor3f(swColor);
if (glTexture > -1)
{
GL11.glTexCoord2f(0, 0);
}
GL11.glVertex3i(x, z1, -y);
glColor3f(seColor);
if (glTexture > -1)
{
GL11.glTexCoord2f(1, 0);
}
GL11.glVertex3i(x + TILE_SCALE, z2, -y);
glColor3f(nwColor);
if (glTexture > -1)
{
GL11.glTexCoord2f(0, 1);
}
GL11.glVertex3i(x, z3, -(y + TILE_SCALE));
// triangle 2
if (glTexture > -1)
{
GL11.glTexCoord2f(0, 1);
}
GL11.glVertex3i(x, z3, -(y + TILE_SCALE));
glColor3f(seColor);
if (glTexture > -1)
{
GL11.glTexCoord2f(1, 0);
}
GL11.glVertex3i(x + TILE_SCALE, z2, -y);
glColor3f(neColor);
if (glTexture > -1)
{
GL11.glTexCoord2f(1, 1);
}
GL11.glVertex3i(x + TILE_SCALE, z4, -(y + TILE_SCALE));
GL11.glEnd();
if (glTexture > -1)
{
GL11.glDisable(GL11.GL_TEXTURE_2D);
}
}
private static void drawSceneTileModel(Region region, int regionX, int regionY, int z, SceneTileModel sceneTileModel)
{
if (sceneTileModel == null)
{
return;
}
for (int i = 0; i < sceneTileModel.faceX.length; ++i)
{
int vertexA = sceneTileModel.faceX[i];
int vertexB = sceneTileModel.faceY[i];
int vertexC = sceneTileModel.faceZ[i];
int vertexAx = sceneTileModel.vertexX[vertexA];
int vertexAy = sceneTileModel.vertexY[vertexA];
int vertexAz = sceneTileModel.vertexZ[vertexA];
int vertexBx = sceneTileModel.vertexX[vertexB];
int vertexBy = sceneTileModel.vertexY[vertexB];
int vertexBz = sceneTileModel.vertexZ[vertexB];
int vertexCx = sceneTileModel.vertexX[vertexC];
int vertexCy = sceneTileModel.vertexY[vertexC];
int vertexCz = sceneTileModel.vertexZ[vertexC];
int colorA = sceneTileModel.triangleColorA[i];
int colorB = sceneTileModel.triangleColorB[i];
int colorC = sceneTileModel.triangleColorC[i];
int textureId = sceneTileModel.triangleTextureId == null ? -1 : sceneTileModel.triangleTextureId[i];
Color colorAc, colorBc, colorCc;
int glTexture = -1;
if (textureId != -1)
{
colorAc = colorBc = colorCc = Color.WHITE;
Texture texture = getTexture(textureId);
glTexture = texture.getOpenglId();
assert glTexture > -1;
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, glTexture);
}
else
{
if (colorA == 12345678)
{
return;
}
colorAc = new Color(getPaletteColor(colorA));
colorBc = new Color(getPaletteColor(colorB));
colorCc = new Color(getPaletteColor(colorC));
}
GL11.glBegin(GL11.GL_TRIANGLES);
glColor3f(colorAc);
if (glTexture > -1)
{
GL11.glTexCoord2f(0, 0);
}
GL11.glVertex3i(vertexAx, -vertexAy, -vertexAz);
glColor3f(colorBc);
if (glTexture > -1)
{
GL11.glTexCoord2f(1, 0);
}
GL11.glVertex3i(vertexBx, -vertexBy, -vertexBz);
glColor3f(colorCc);
if (glTexture > -1)
{
GL11.glTexCoord2f(0, 1);
}
GL11.glVertex3i(vertexCx, -vertexCy, -vertexCz);
GL11.glEnd();
if (glTexture > -1)
{
GL11.glDisable(GL11.GL_TEXTURE_2D);
}
}
}
private static void glColor3f(Color color)
{
GL11.glColor3f((float) color.getRed() / 255f, (float) color.getGreen() / 255f, (float) color.getBlue() / 255f);
}
private static void drawLocations(Region region)
{
for (Location location : region.getLocations())
{
int id = location.getId();
ObjectDefinition object = getObject(id);
if (object == null || object.getObjectModels() == null)
{
continue;
}
Position objectPos = location.getPosition();
int width;
int length;
if (location.getOrientation() != 1 && location.getOrientation() != 3)
{
width = object.getSizeX();
length = object.getSizeY();
}
else
{
width = object.getSizeY();
length = object.getSizeX();
}
int regionX = objectPos.getX() - region.getBaseX();
int regionY = objectPos.getY() - region.getBaseY();
int height = Integer.MIN_VALUE;
for (int xOff = 0; xOff < width; xOff++)
{
for (int yOff = 0; yOff < length; yOff++)
{
if (regionX + xOff < Region.X && regionY + yOff < Region.Y)
{
height = Math.max(height, -region.getTileHeight(objectPos.getZ(), regionX + xOff, regionY + yOff));
}
}
}
GL11.glMatrixMode(GL11.GL_MODELVIEW);
// TILE_SCALE/2 to draw the object from the center of the tile it is on
GL11.glTranslatef(
(regionX * TILE_SCALE) + ((width * TILE_SCALE) / 2),
height,
(-regionY * TILE_SCALE) - ((length * TILE_SCALE) / 2)
);
GL11.glClear(GL11.GL_STENCIL_BUFFER_BIT);
int max = -1;
for (int i = 0; i < object.getObjectModels().length; ++i)
{
if (object.getObjectTypes() != null && object.getObjectTypes()[i] != location.getType())
{
continue;
}
ModelDefinition md = modelManager.getModel(object.getObjectModels()[i], object, location);
if (md != null)
{
if (md.maxPriority > max)
{
max = md.maxPriority;
}
}
}
for (int prio = max; prio >= 0; --prio)
{
for (int i = 0; i < object.getObjectModels().length; ++i)
{
if (object.getObjectTypes() != null && object.getObjectTypes()[i] != location.getType())
{
continue;
}
ModelDefinition md = modelManager.getModel(object.getObjectModels()[i], object, location);
if (md == null)
{
continue;
}
drawModel(md, prio, prio == max);
}
}
GL11.glTranslatef(
(-regionX * TILE_SCALE) - ((width * TILE_SCALE) / 2),
-height,
(regionY * TILE_SCALE) + ((length * TILE_SCALE) / 2)
);
}
}
private static ObjectDefinition getObject(int id)
{
return objectManager.getObject(id);
}
private static Texture getTexture(int id)
{
Texture texture = textures.get(id);
if (texture != null)
{
return texture;
}
TextureDefinition textureDefinition = textureManager.findTexture(id);
SpriteDefinition spriteDefinition = spriteManager.findSprite(textureDefinition.getFileIds()[0], 0);
int width = spriteDefinition.getWidth();
int height = spriteDefinition.getHeight();
int[] rgb = spriteDefinition.getPixels();
ByteBuffer buffer = ByteBuffer.allocateDirect(rgb.length * 4);
for (int i = 0; i < rgb.length; ++i)
{
int pixel = rgb[i];
// argb -> rgba
int a = pixel >>> 24;
int r = (pixel >> 16) & 0xff;
int g = (pixel >> 8) & 0xff;
int b = pixel & 0xff;
buffer.put((byte) r);
buffer.put((byte) g);
buffer.put((byte) b);
buffer.put((byte) a);
}
buffer.position(0);
int glTexture = GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, glTexture);
//Setup filtering, i.e. how OpenGL will interpolate the pixels when scaling up or down
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//Setup wrap mode, i.e. how OpenGL will handle pixels outside of the expected range
//Note: GL_CLAMP_TO_EDGE is part of GL12
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, width, height, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
GL11.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR); // Linear Filtering
GL11.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR); // Linear Filtering
texture = new Texture(rgb, width, height, glTexture);
textures.put(id, texture);
return texture;
}
private static void loadSeqs(Store store) throws IOException
{
Storage storage = store.getStorage();
Index index = store.getIndex(IndexType.CONFIGS);
Archive archive = index.getArchive(ConfigType.SEQUENCE.getId());
byte[] archiveData = storage.loadArchive(archive);
ArchiveFiles files = archive.getFiles(archiveData);
for (FSFile file : files.getFiles())
{
SequenceLoader loader = new SequenceLoader();
SequenceDefinition seq = loader.load(file.getFileId(), file.getContents());
seqs.put(file.getFileId(), seq);
}
}
private static void loadFrames(Store store) throws IOException
{
Storage storage = store.getStorage();
Index frameIndex = store.getIndex(IndexType.FRAMES);
Index framemapIndex = store.getIndex(IndexType.FRAMEMAPS);
for (Archive archive : frameIndex.getArchives())
{
byte[] archiveData = storage.loadArchive(archive);
ArchiveFiles archiveFiles = archive.getFiles(archiveData);
for (FSFile archiveFile : archiveFiles.getFiles())
{
byte[] contents = archiveFile.getContents();
int framemapArchiveId = (contents[0] & 0xff) << 8 | contents[1] & 0xff;
Archive framemapArchive = framemapIndex.getArchives().get(framemapArchiveId);
archiveData = storage.loadArchive(framemapArchive);
byte[] framemapContents = framemapArchive.decompress(archiveData);
FramemapLoader fmloader = new FramemapLoader();
FramemapDefinition framemap = fmloader.load(framemapArchive.getArchiveId(), framemapContents);
FrameLoader frameLoader = new FrameLoader();
FrameDefinition frame = frameLoader.load(framemap, archiveFile.getFileId(), contents);
frames.put(archive.getArchiveId(), frame);
}
}
}
public static int getPaletteColor(int hsb)
{
return palette[hsb & 0xFFFF];
}
// 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);
int rgb = Color.HSBtoRGB((float) decode_hue / 63, (float) decode_saturation / 7, (float) decode_brightness / 127);
return adjustRGB(rgb & 0xFFFFFF, 0.6);
}
private static int adjustRGB(int rgb, double brightness)
{
double rp = (double) (rgb >> 16) / 256.0D;
double gp = (double) (rgb >> 8 & 255) / 256.0D;
double bp = (double) (rgb & 255) / 256.0D;
rp = Math.pow(rp, brightness);
gp = Math.pow(gp, brightness);
bp = Math.pow(bp, brightness);
int r = (int) (rp * 256.0D);
int g = (int) (gp * 256.0D);
int b = (int) (bp * 256.0D);
return b + (g << 8) + (r << 16);
}
}

View File

@@ -1,463 +0,0 @@
/*
* Copyright (c) 2018, 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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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 lombok.AllArgsConstructor;
import lombok.Getter;
import net.runelite.cache.ObjectManager;
import net.runelite.cache.definitions.ObjectDefinition;
import net.runelite.cache.definitions.OverlayDefinition;
import net.runelite.cache.definitions.UnderlayDefinition;
import net.runelite.cache.definitions.providers.OverlayProvider;
import net.runelite.cache.definitions.providers.UnderlayProvider;
import net.runelite.cache.item.ColorPalette;
import net.runelite.cache.region.Location;
import net.runelite.cache.region.Region;
@AllArgsConstructor
public class Scene
{
private static final int REGION_SIZE = 64;
private static final int BLEND = 5;
private static final ColorPalette colorPalette = new ColorPalette(0.9d, 0, 512);
static
{
assert Region.X == Region.Y;
}
private final int[] hues = new int[REGION_SIZE];
private final int[] sats = new int[REGION_SIZE];
private final int[] light = new int[REGION_SIZE];
private final int[] mul = new int[REGION_SIZE];
private final int[] num = new int[REGION_SIZE];
private final UnderlayProvider underlayProvider;
private final OverlayProvider overlayProvider;
@Getter
private final SceneTileModel[][][] sceneTiles = new SceneTileModel[Region.Z][Region.X][Region.Y];
@Getter
private final SceneTilePaint[][][] sceneTilePaint = new SceneTilePaint[Region.Z][Region.X][Region.Y];
private byte[][] createShadows(Region region, ObjectManager manager)
{
byte[][] shadow = new byte[Region.X + 8][Region.Y + 8];
for (Location location : region.getLocations())
{
int id = location.getId();
ObjectDefinition object = manager.getObject(id);
if (object == null || object.getObjectModels() == null)
{
continue;
}
if (!object.isABool2097())
{
continue;
}
int regionX = location.getPosition().getX() - region.getBaseX();
int regionY = location.getPosition().getY() - region.getBaseY();
if (location.getType() == 0)
{
if (location.getOrientation() == 0)
{
shadow[regionX][regionY] = 50;
shadow[regionX][regionY + 1] = 50;
}
else if (location.getOrientation() == 1)
{
shadow[regionX][regionY + 1] = 50;
shadow[regionX + 1][regionY + 1] = 50;
}
else if (location.getOrientation() == 2)
{
shadow[regionX + 1][regionY] = 50;
shadow[regionX + 1][regionY + 1] = 50;
}
else if (location.getOrientation() == 3)
{
shadow[regionX][regionY] = 50;
shadow[regionX + 1][regionY] = 50;
}
}
else if (location.getType() == 1 || location.getType() == 3)
{
if (location.getOrientation() == 0)
{
shadow[regionX][regionY + 1] = 50;
}
else if (location.getOrientation() == 1)
{
shadow[regionX + 1][regionY + 1] = 50;
}
else if (location.getOrientation() == 2)
{
shadow[regionX + 1][regionY] = 50;
}
else if (location.getOrientation() == 3)
{
shadow[regionX][regionY] = 50;
}
}
else if (location.getType() == 10 || location.getType() == 11)
{
int width;
int length;
if (location.getOrientation() != 1 && location.getOrientation() != 3)
{
width = object.getSizeX();
length = object.getSizeY();
}
else
{
width = object.getSizeY();
length = object.getSizeX();
}
int var23 = 15;
for (int x = 0; x <= width; x++)
{
int xOff = x + regionX;
for (int y = 0; y <= length; y++)
{
int yOff = y + regionY;
if (var23 > shadow[xOff][yOff])
{
shadow[xOff][yOff] = (byte) var23;
}
}
}
}
}
return shadow;
}
public void loadRegion(Region region, ObjectManager manager)
{
byte[][] shadow = createShadows(region, manager);
int[][] field3834 = new int[Region.X][Region.Y];
int var11 = (int) Math.sqrt(5100.0D);
int var63 = var11 * 768 >> 8;
for (int z = 0; z < Region.Z; ++z)
{
for (int x = 1; x < Region.X - 1; ++x)
{
for (int y = 1; y < Region.Y - 1; ++y)
{
int dx = region.getTileHeight(z, x + 1, y) - region.getTileHeight(z, x - 1, y);
int dy = region.getTileHeight(z, x, y + 1) - region.getTileHeight(z, x, y - 1);
int var17 = (int) Math.sqrt((double) (dx * dx + dy * dy + 65536));
int var18 = (dx << 8) / var17;
int var50 = 65536 / var17;
int var20 = (dy << 8) / var17;
int var21 = (var20 * -50 + var18 * -50 + var50 * -10) / var63 + 96;
int var22 = (shadow[y - 1][x] >> 2) + (shadow[y][x - 1] >> 2) + (shadow[y + 1][x] >> 3) + (shadow[y][x + 1] >> 3) + (shadow[y][x] >> 1);
field3834[y][x] = var21 - var22;
}
}
for (int i = 0; i < REGION_SIZE; ++i)
{
hues[i] = 0;
sats[i] = 0;
light[i] = 0;
mul[i] = 0;
num[i] = 0;
}
for (int x = -BLEND; x < Region.X + BLEND; ++x)
{
for (int y = 0; y < Region.Y; ++y)
{
int xr = x + BLEND;
if (xr >= 0 && xr < Region.X)
{
int underlayId = region.getUnderlayId(z, xr, y);
if (underlayId > 0)
{
UnderlayDefinition underlay = underlayProvider.provide(underlayId - 1);
hues[y] += underlay.getHue();
sats[y] += underlay.getSaturation();
light[y] += underlay.getLightness();
mul[y] += underlay.getHueMultiplier();
num[y]++;
}
}
int xl = x - BLEND;
if (xl >= 0 && xl < Region.X)
{
int underlayId = region.getUnderlayId(z, xl, y);
if (underlayId > 0)
{
UnderlayDefinition underlay = underlayProvider.provide(underlayId - 1);
hues[y] -= underlay.getHue();
sats[y] -= underlay.getSaturation();
light[y] -= underlay.getLightness();
mul[y] -= underlay.getHueMultiplier();
num[y]--;
}
}
}
if (x >= 1 && x < Region.X - 1)
{
int runningHues = 0;
int runningSat = 0;
int runningLight = 0;
int runningMultiplier = 0;
int runningNumber = 0;
for (int y = -BLEND; y < Region.Y + BLEND; ++y)
{
int yu = y + BLEND;
if (yu >= 0 && yu < Region.Y)
{
runningHues += hues[yu];
runningSat += sats[yu];
runningLight += light[yu];
runningMultiplier += mul[yu];
runningNumber += num[yu];
}
int yd = y - BLEND;
if (yd >= 0 && yd < Region.Y)
{
runningHues -= hues[yd];
runningSat -= sats[yd];
runningLight -= light[yd];
runningMultiplier -= mul[yd];
runningNumber -= num[yd];
}
if (y >= 1 && y < Region.Y - 1)
{
int underlayId = region.getUnderlayId(z, x, y);
int overlayId = region.getOverlayId(z, x, y);
if (underlayId > 0 || overlayId > 0)
{
int tileHeight = region.getTileHeight(z, x, y);
int tileHeightX1 = region.getTileHeight(z, x + 1, y);
int tileHeightX1Y1 = region.getTileHeight(z, x + 1, y + 1);
int tileHeightY1 = region.getTileHeight(z, x, y + 1);
int m1 = field3834[x][y];
int m2 = field3834[x + 1][y];
int m3 = field3834[x + 1][y + 1];
int m4 = field3834[x][y + 1];
int underlayHsl = -1;
if (underlayId > 0)
{
int avgHue = runningHues * 256 / runningMultiplier;
int avgSat = runningSat / runningNumber;
int avgLight = runningLight / runningNumber;
underlayHsl = packHsl(avgHue, avgSat, avgLight);
}
int underlayColor = 0;
if (underlayHsl != -1)
{
underlayColor = colorPalette.getColorPalette()[method2115(underlayHsl, 96)];
}
if (overlayId == 0)
{
addTile(z, x, y, 0, 0, -1,
tileHeight, tileHeightX1, tileHeightX1Y1, tileHeightY1,
method2115(underlayHsl, m1), method2115(underlayHsl, m2), method2115(underlayHsl, m3), method2115(underlayHsl, m4),
0, 0, 0, 0,
underlayColor, 0);
}
else
{
int shape = region.getOverlayPath(z, x, y) + 1;
int rotation = region.getOverlayRotation(z, x, y);
OverlayDefinition overlay = overlayProvider.provide(overlayId - 1);
int textureId = overlay.getTexture();
int overlayHsl;
if (textureId >= 0)
{
overlayHsl = -2;
}
else if (overlay.getRgbColor() == 0xFF_00FF)
{
overlayHsl = -2;
textureId = -1;
}
else
{
int hue = overlay.getHue();
int sat = overlay.getSaturation();
int light = overlay.getLightness();
overlayHsl = packHsl(hue, sat, light);
}
int overlayColor = 0;
if (overlayHsl != -2)
{
int var0 = adjustHSLListness0(overlayHsl, 96);
overlayColor = colorPalette.getColorPalette()[var0];
}
if (overlay.getSecondaryRgbColor() != -1)
{
int hue = overlay.getOtherHue();
int sat = overlay.getOtherSaturation();
int olight = overlay.getOtherLightness();
int hsl = packHsl(hue, sat, olight);
int var0 = adjustHSLListness0(hsl, 96);
overlayColor = colorPalette.getColorPalette()[var0];
}
addTile(z, x, y, shape, rotation, textureId,
tileHeight, tileHeightX1, tileHeightX1Y1, tileHeightY1,
method2115(underlayHsl, m1), method2115(underlayHsl, m2), method2115(underlayHsl, m3), method2115(underlayHsl, m4),
adjustHSLListness0(overlayHsl, m1), adjustHSLListness0(overlayHsl, m2), adjustHSLListness0(overlayHsl, m3), adjustHSLListness0(overlayHsl, m4),
underlayColor, overlayColor);
}
}
}
}
}
}
}
}
private void addTile(int z, int x, int y, int shape, int overlayRot, int texture,
int tileHeight, int tileHeightX1, int tileHeightX1Y1, int tileHeightY1,
int underlayColor, int underlayColorX1, int underlayColorX1Y1, int underlayColorY1,
int overlayColor, int overlayColorX1, int overlayColorX1Y1, int overlayColorY1,
int underlayColorRgb, int overlayColorRgb) // for the map
{
if (shape == 0)
{
SceneTilePaint sceneTilePaint = new SceneTilePaint(underlayColor, underlayColorX1, underlayColorX1Y1, underlayColorY1, -1, underlayColorRgb, false);
this.sceneTilePaint[z][x][y] = sceneTilePaint;
}
else if (shape == 1)
{
SceneTilePaint sceneTilePaint = new SceneTilePaint(overlayColor, overlayColorX1, overlayColorX1Y1, overlayColorY1, texture, underlayColorRgb, tileHeightX1 == tileHeight && tileHeight == tileHeightX1Y1 && tileHeightY1 == tileHeight);
this.sceneTilePaint[z][x][y] = sceneTilePaint;
}
else
{
SceneTileModel sceneTileModel = new SceneTileModel(shape, overlayRot, texture, x, y,
tileHeight, tileHeightX1, tileHeightX1Y1, tileHeightY1,
underlayColor, underlayColorX1, underlayColorX1Y1, underlayColorY1,
overlayColor, overlayColorX1, overlayColorX1Y1, overlayColorY1,
underlayColorRgb, overlayColorRgb);
sceneTiles[z][x][y] = sceneTileModel;
}
}
private static int packHsl(int h, int s, int l)
{
if (l > 179)
{
s /= 2;
}
if (l > 192)
{
s /= 2;
}
if (l > 217)
{
s /= 2;
}
if (l > 243)
{
s /= 2;
}
int hsl = (s / 32 << 7) + (h / 4 << 10) + l / 2;
return hsl;
}
private static int method2115(int hsl, int var1)
{
if (hsl == -1)
{
return 12345678;
}
else
{
var1 = (hsl & 127) * var1 / 128;
if (var1 < 2)
{
var1 = 2;
}
else if (var1 > 126)
{
var1 = 126;
}
return (hsl & 65408) + var1;
}
}
static final int adjustHSLListness0(int var0, int var1)
{
if (var0 == -2)
{
return 12345678;
}
else if (var0 == -1)
{
if (var1 < 2)
{
var1 = 2;
}
else if (var1 > 126)
{
var1 = 126;
}
return var1;
}
else
{
var1 = (var0 & 127) * var1 / 128;
if (var1 < 2)
{
var1 = 2;
}
else if (var1 > 126)
{
var1 = 126;
}
return (var0 & 65408) + var1;
}
}
}

View File

@@ -1,305 +0,0 @@
/*
* Copyright (c) 2018, 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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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 lombok.Getter;
@Getter
public class SceneTileModel
{
private static final int[][] TILE_VERTICES;
private static final int[][] TILE_FACES;
private static final int TILE_SIZE = 128;
private static final int HALF_TILE_SIZE = TILE_SIZE / 2;
private static final int QUARTER_TILE_SIZE = TILE_SIZE / 4;
private static final int THREE_QUARTER_TILE_SIZE = TILE_SIZE * 3 / 4;
final int[] vertexX;
final int[] vertexY;
final int[] vertexZ;
private final int[] var26;
private final int[] var27;
final int[] faceX;
final int[] faceY;
final int[] faceZ;
final int[] triangleColorA;
final int[] triangleColorB;
final int[] triangleColorC;
int[] triangleTextureId;
static
{
TILE_VERTICES = new int[][]{{1, 3, 5, 7}, {1, 3, 5, 7}, {1, 3, 5, 7}, {1, 3, 5, 7, 6}, {1, 3, 5, 7, 6}, {1, 3, 5, 7, 6}, {1, 3, 5, 7, 6}, {1, 3, 5, 7, 2, 6}, {1, 3, 5, 7, 2, 8}, {1, 3, 5, 7, 2, 8}, {1, 3, 5, 7, 11, 12}, {1, 3, 5, 7, 11, 12}, {1, 3, 5, 7, 13, 14}};
TILE_FACES = new int[][]{{0, 1, 2, 3, 0, 0, 1, 3}, {1, 1, 2, 3, 1, 0, 1, 3}, {0, 1, 2, 3, 1, 0, 1, 3}, {0, 0, 1, 2, 0, 0, 2, 4, 1, 0, 4, 3}, {0, 0, 1, 4, 0, 0, 4, 3, 1, 1, 2, 4}, {0, 0, 4, 3, 1, 0, 1, 2, 1, 0, 2, 4}, {0, 1, 2, 4, 1, 0, 1, 4, 1, 0, 4, 3}, {0, 4, 1, 2, 0, 4, 2, 5, 1, 0, 4, 5, 1, 0, 5, 3}, {0, 4, 1, 2, 0, 4, 2, 3, 0, 4, 3, 5, 1, 0, 4, 5}, {0, 0, 4, 5, 1, 4, 1, 2, 1, 4, 2, 3, 1, 4, 3, 5}, {0, 0, 1, 5, 0, 1, 4, 5, 0, 1, 2, 4, 1, 0, 5, 3, 1, 5, 4, 3, 1, 4, 2, 3}, {1, 0, 1, 5, 1, 1, 4, 5, 1, 1, 2, 4, 0, 0, 5, 3, 0, 5, 4, 3, 0, 4, 2, 3}, {1, 0, 5, 4, 1, 0, 1, 5, 0, 0, 4, 3, 0, 4, 5, 3, 0, 5, 2, 3, 0, 1, 2, 5}};
}
public SceneTileModel(int shape, int overlayRott, int texture, int x, int y,
int tileHeight, int tileHeightX1, int tileHeightX1Y1, int tileHeightY1,
int var10, int var11, int var12, int var13,
int var14, int var15, int var16, int var17,
int var18, int var19)
{
final int[] vertexInfo = TILE_VERTICES[shape];
final int vertexInfoLength = vertexInfo.length;
vertexX = new int[vertexInfoLength];
vertexY = new int[vertexInfoLength];
vertexZ = new int[vertexInfoLength];
var26 = new int[vertexInfoLength];
var27 = new int[vertexInfoLength];
final int tileBaseX = x * TILE_SIZE;
final int tileBaseY = y * TILE_SIZE;
for (int idx = 0; idx < vertexInfoLength; ++idx)
{
int curInfo = vertexInfo[idx];
if ((curInfo & 1) == 0 && curInfo <= 8)
{
curInfo = (curInfo - overlayRott - overlayRott - 1 & 7) + 1;
}
if (curInfo > 8 && curInfo <= 12)
{
curInfo = (curInfo - 9 - overlayRott & 3) + 9;
}
if (curInfo > 12 && curInfo <= 16)
{
curInfo = (curInfo - 13 - overlayRott & 3) + 13;
}
int vertexX, vertexY, vertexZ;
int var35, var36;
if (curInfo == 1)
{
vertexX = tileBaseX;
vertexZ = tileBaseY;
vertexY = tileHeight;
var35 = var10;
var36 = var14;
}
else if (curInfo == 2)
{
vertexX = tileBaseX + HALF_TILE_SIZE;
vertexZ = tileBaseY;
vertexY = tileHeightX1 + tileHeight >> 1;
var35 = var11 + var10 >> 1;
var36 = var15 + var14 >> 1;
}
else if (curInfo == 3)
{
vertexX = tileBaseX + TILE_SIZE;
vertexZ = tileBaseY;
vertexY = tileHeightX1;
var35 = var11;
var36 = var15;
}
else if (curInfo == 4)
{
vertexX = tileBaseX + TILE_SIZE;
vertexZ = tileBaseY + HALF_TILE_SIZE;
vertexY = tileHeightX1Y1 + tileHeightX1 >> 1;
var35 = var11 + var12 >> 1;
var36 = var15 + var16 >> 1;
}
else if (curInfo == 5)
{
vertexX = tileBaseX + TILE_SIZE;
vertexZ = tileBaseY + TILE_SIZE;
vertexY = tileHeightX1Y1;
var35 = var12;
var36 = var16;
}
else if (curInfo == 6)
{
vertexX = tileBaseX + HALF_TILE_SIZE;
vertexZ = tileBaseY + TILE_SIZE;
vertexY = tileHeightX1Y1 + tileHeightY1 >> 1;
var35 = var13 + var12 >> 1;
var36 = var17 + var16 >> 1;
}
else if (curInfo == 7)
{
vertexX = tileBaseX;
vertexZ = tileBaseY + TILE_SIZE;
vertexY = tileHeightY1;
var35 = var13;
var36 = var17;
}
else if (curInfo == 8)
{
vertexX = tileBaseX;
vertexZ = tileBaseY + HALF_TILE_SIZE;
vertexY = tileHeightY1 + tileHeight >> 1;
var35 = var13 + var10 >> 1;
var36 = var17 + var14 >> 1;
}
else if (curInfo == 9)
{
vertexX = tileBaseX + HALF_TILE_SIZE;
vertexZ = tileBaseY + QUARTER_TILE_SIZE;
vertexY = tileHeightX1 + tileHeight >> 1;
var35 = var11 + var10 >> 1;
var36 = var15 + var14 >> 1;
}
else if (curInfo == 10)
{
vertexX = tileBaseX + THREE_QUARTER_TILE_SIZE;
vertexZ = tileBaseY + HALF_TILE_SIZE;
vertexY = tileHeightX1Y1 + tileHeightX1 >> 1;
var35 = var11 + var12 >> 1;
var36 = var15 + var16 >> 1;
}
else if (curInfo == 11)
{
vertexX = tileBaseX + HALF_TILE_SIZE;
vertexZ = tileBaseY + THREE_QUARTER_TILE_SIZE;
vertexY = tileHeightX1Y1 + tileHeightY1 >> 1;
var35 = var13 + var12 >> 1;
var36 = var17 + var16 >> 1;
}
else if (curInfo == 12)
{
vertexX = tileBaseX + QUARTER_TILE_SIZE;
vertexZ = tileBaseY + HALF_TILE_SIZE;
vertexY = tileHeightY1 + tileHeight >> 1;
var35 = var13 + var10 >> 1;
var36 = var17 + var14 >> 1;
}
else if (curInfo == 13)
{
vertexX = tileBaseX + QUARTER_TILE_SIZE;
vertexZ = tileBaseY + QUARTER_TILE_SIZE;
vertexY = tileHeight;
var35 = var10;
var36 = var14;
}
else if (curInfo == 14)
{
vertexX = tileBaseX + THREE_QUARTER_TILE_SIZE;
vertexZ = tileBaseY + QUARTER_TILE_SIZE;
vertexY = tileHeightX1;
var35 = var11;
var36 = var15;
}
else if (curInfo == 15)
{
vertexX = tileBaseX + THREE_QUARTER_TILE_SIZE;
vertexZ = tileBaseY + THREE_QUARTER_TILE_SIZE;
vertexY = tileHeightX1Y1;
var35 = var12;
var36 = var16;
}
else
{
vertexX = tileBaseX + QUARTER_TILE_SIZE;
vertexZ = tileBaseY + THREE_QUARTER_TILE_SIZE;
vertexY = tileHeightY1;
var35 = var13;
var36 = var17;
}
this.vertexX[idx] = vertexX;
this.vertexY[idx] = vertexY;
this.vertexZ[idx] = vertexZ;
var26[idx] = var35;
var27[idx] = var36;
}
final int[] faceInfo = TILE_FACES[shape];
final int faceInfoLength = faceInfo.length / 4;
faceX = new int[faceInfoLength];
faceY = new int[faceInfoLength];
faceZ = new int[faceInfoLength];
triangleColorA = new int[faceInfoLength];
triangleColorB = new int[faceInfoLength];
triangleColorC = new int[faceInfoLength];
if (texture != -1)
{
triangleTextureId = new int[faceInfoLength];
}
int offset = 0;
for (int idx = 0; idx < faceInfoLength; ++idx)
{
int var = faceInfo[offset];
int faceX = faceInfo[offset + 1];
int faceY = faceInfo[offset + 2];
int faceZ = faceInfo[offset + 3];
offset += 4;
if (faceX < 4)
{
faceX = faceX - overlayRott & 3;
}
if (faceY < 4)
{
faceY = faceY - overlayRott & 3;
}
if (faceZ < 4)
{
faceZ = faceZ - overlayRott & 3;
}
this.faceX[idx] = faceX;
this.faceY[idx] = faceY;
this.faceZ[idx] = faceZ;
if (var == 0)
{
this.triangleColorA[idx] = var26[faceX];
this.triangleColorB[idx] = var26[faceY];
this.triangleColorC[idx] = var26[faceZ];
if (this.triangleTextureId != null)
{
this.triangleTextureId[idx] = -1;
}
}
else
{
this.triangleColorA[idx] = var27[faceX];
this.triangleColorB[idx] = var27[faceY];
this.triangleColorC[idx] = var27[faceZ];
if (this.triangleTextureId != null)
{
this.triangleTextureId[idx] = texture;
}
}
}
}
}

View File

@@ -1,39 +0,0 @@
/*
* Copyright (c) 2018, 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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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 lombok.AllArgsConstructor;
@AllArgsConstructor
public class SceneTilePaint
{
final int swColor;
final int seColor;
final int neColor;
final int nwColor;
final int texture;
final int rgb;
final boolean flatShade;
}

View File

@@ -1,125 +0,0 @@
/*
* Copyright (c) 2017, 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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.apache.commons.io.IOUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import static org.lwjgl.opengl.GL20.GL_INFO_LOG_LENGTH;
import static org.lwjgl.opengl.GL20.glGetProgrami;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ShaderManager
{
private static final Logger logger = LoggerFactory.getLogger(ShaderManager.class);
private static final int ERR_LEN = 1024;
private int program;
private int vertexShader;
private int fragmentShader;
public void load(InputStream vertexShaderStream, InputStream fragShaderStream) throws IOException
{
program = GL20.glCreateProgram();
vertexShader = GL20.glCreateShader(GL20.GL_VERTEX_SHADER);
fragmentShader = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER);
String vertexShaderStr = IOUtils.toString(new InputStreamReader(vertexShaderStream));
String fragShaderStr = IOUtils.toString(new InputStreamReader(fragShaderStream));
GL20.glShaderSource(vertexShader, vertexShaderStr);
GL20.glCompileShader(vertexShader);
if (GL20.glGetShader(vertexShader, GL20.GL_COMPILE_STATUS) == GL11.GL_TRUE)
{
GL20.glAttachShader(program, vertexShader);
}
else
{
String err = GL20.glGetShaderInfoLog(vertexShader, ERR_LEN);
logger.warn("Error compiling vertex shader: {}", err);
}
GL20.glShaderSource(fragmentShader, fragShaderStr);
GL20.glCompileShader(fragmentShader);
if (GL20.glGetShader(fragmentShader, GL20.GL_COMPILE_STATUS) == GL11.GL_TRUE)
{
GL20.glAttachShader(program, fragmentShader);
}
else
{
String err = GL20.glGetShaderInfoLog(fragmentShader, ERR_LEN);
logger.warn("Error compiling fragment shader: {}", err);
}
GL20.glLinkProgram(program);
if (GL20.glGetProgram(program, GL20.GL_LINK_STATUS) == GL11.GL_FALSE)
{
String err = GL20.glGetProgramInfoLog(program, glGetProgrami(program, GL_INFO_LOG_LENGTH));
logger.warn("Error linking program: {}", err);
}
GL20.glValidateProgram(program);
}
public void destroy()
{
GL20.glDeleteShader(vertexShader);
GL20.glDeleteShader(fragmentShader);
GL20.glDeleteProgram(program);
}
public void use()
{
GL20.glUseProgram(program);
}
void unuse()
{
GL20.glUseProgram(0);
}
public int getProgram()
{
return program;
}
public int getVertexShader()
{
return vertexShader;
}
public int getFragmentShader()
{
return fragmentShader;
}
}

View File

@@ -1,61 +0,0 @@
/*
* Copyright (c) 2016-2017, 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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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 Texture
{
private final int[] rgb;
private final int width;
private final int height;
private final int openglId;
public Texture(int[] rgb, int width, int height, int openglId)
{
this.rgb = rgb;
this.width = width;
this.height = height;
this.openglId = openglId;
}
public int[] getRgb()
{
return rgb;
}
public int getWidth()
{
return width;
}
public int getHeight()
{
return height;
}
public int getOpenglId()
{
return openglId;
}
}

View File

@@ -116,7 +116,6 @@
<module>cache-client</module>
<module>cache-server</module>
<module>cache-updater</module>
<module>model-viewer</module>
<module>runelite-api</module>
<module>runelite-client</module>
<module>runelite-mixins</module>