cache: add .obj model exporter
This commit is contained in:
@@ -5,6 +5,7 @@ import net.runelite.cache.models.VertexNormal;
|
|||||||
|
|
||||||
public class ModelDefinition
|
public class ModelDefinition
|
||||||
{
|
{
|
||||||
|
public int id;
|
||||||
public short[] texTriangleX;
|
public short[] texTriangleX;
|
||||||
public int[] vertexX;
|
public int[] vertexX;
|
||||||
public byte[] faceRenderPriorities;
|
public byte[] faceRenderPriorities;
|
||||||
@@ -44,8 +45,8 @@ public class ModelDefinition
|
|||||||
public int anInt2595;
|
public int anInt2595;
|
||||||
public int vertexCount = 0;
|
public int vertexCount = 0;
|
||||||
public short[] texturePrimaryColor;
|
public short[] texturePrimaryColor;
|
||||||
public VertexNormal[] normals;
|
public transient VertexNormal[] normals;
|
||||||
public FaceNormal[] faceNormals;
|
public transient FaceNormal[] faceNormals;
|
||||||
|
|
||||||
public void computeNormals()
|
public void computeNormals()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,9 +5,10 @@ import net.runelite.cache.io.InputStream;
|
|||||||
|
|
||||||
public class ModelLoader
|
public class ModelLoader
|
||||||
{
|
{
|
||||||
public ModelDefinition load(byte[] var1)
|
public ModelDefinition load(int modelId, byte[] var1)
|
||||||
{
|
{
|
||||||
ModelDefinition def = new ModelDefinition();
|
ModelDefinition def = new ModelDefinition();
|
||||||
|
def.id = modelId;
|
||||||
|
|
||||||
if (var1[var1.length - 1] == -1 && var1[var1.length - 2] == -1)
|
if (var1[var1.length - 1] == -1 && var1[var1.length - 2] == -1)
|
||||||
{
|
{
|
||||||
|
|||||||
92
cache/src/main/java/net/runelite/cache/models/ObjExporter.java
vendored
Normal file
92
cache/src/main/java/net/runelite/cache/models/ObjExporter.java
vendored
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* 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.cache.models;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import net.runelite.cache.definitions.ModelDefinition;
|
||||||
|
|
||||||
|
public class ObjExporter
|
||||||
|
{
|
||||||
|
private final ModelDefinition model;
|
||||||
|
|
||||||
|
public ObjExporter(ModelDefinition model)
|
||||||
|
{
|
||||||
|
this.model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void export(PrintWriter objWriter, PrintWriter mtlWriter) throws IOException
|
||||||
|
{
|
||||||
|
model.computeNormals();
|
||||||
|
|
||||||
|
objWriter.println("mtllib " + model.id + ".mtl");
|
||||||
|
|
||||||
|
objWriter.println("o runescapemodel");
|
||||||
|
|
||||||
|
for (int i = 0; i < model.vertexCount; ++i)
|
||||||
|
{
|
||||||
|
objWriter.println(" v " + model.vertexX[i] + " " + model.vertexY[i] + " " + model.vertexZ[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (VertexNormal normal : model.normals)
|
||||||
|
{
|
||||||
|
objWriter.println(" vn " + normal.x + " " + normal.y + " " + normal.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < model.triangleFaceCount; ++i)
|
||||||
|
{
|
||||||
|
objWriter.println(" usemtl color" + model.faceColor[i]);
|
||||||
|
objWriter.println(" f " + (model.trianglePointsX[i] + 1) + " " + (model.trianglePointsY[i] + 1) + " " + (model.trianglePointsZ[i] + 1));
|
||||||
|
objWriter.println("");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < model.faceColor.length; ++i)
|
||||||
|
{
|
||||||
|
mtlWriter.println("newmtl color" + model.faceColor[i]);
|
||||||
|
|
||||||
|
Color color = rs2hsbToColor(model.faceColor[i]);
|
||||||
|
|
||||||
|
double r = color.getRed() / 255.0;
|
||||||
|
double g = color.getGreen() / 255.0;
|
||||||
|
double b = color.getBlue() / 255.0;
|
||||||
|
|
||||||
|
mtlWriter.println(" Kd " + r + " " + g + " " + b);
|
||||||
|
|
||||||
|
if (model.faceAlphas != null)
|
||||||
|
{
|
||||||
|
mtlWriter.println(" d " + (model.faceAlphas[i] & 0xFF) / 255.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Color rs2hsbToColor(int hsb)
|
||||||
|
{
|
||||||
|
int decode_hue = (hsb >> 10) & 0x3f;
|
||||||
|
int decode_saturation = (hsb >> 7) & 0x07;
|
||||||
|
int decode_brightness = (hsb & 0x7f);
|
||||||
|
return Color.getHSBColor((float) decode_hue / 63, (float) decode_saturation / 7, (float) decode_brightness / 127);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -69,7 +69,7 @@ public class ModelDumperTest
|
|||||||
byte[] contents = file.getContents();
|
byte[] contents = file.getContents();
|
||||||
|
|
||||||
ModelLoader loader = new ModelLoader();
|
ModelLoader loader = new ModelLoader();
|
||||||
loader.load(contents);
|
loader.load(archive.getArchiveId(), contents);
|
||||||
|
|
||||||
Files.write(contents, new java.io.File(modelDir, archive.getArchiveId() + ".model"));
|
Files.write(contents, new java.io.File(modelDir, archive.getArchiveId() + ".model"));
|
||||||
//Files.write(gson.toJson(loader), new java.io.File(modelDir, archive.getArchiveId() + ".json"), Charset.defaultCharset());
|
//Files.write(gson.toJson(loader), new java.io.File(modelDir, archive.getArchiveId() + ".json"), Charset.defaultCharset());
|
||||||
|
|||||||
52
cache/src/test/java/net/runelite/cache/models/ObjExporterTest.java
vendored
Normal file
52
cache/src/test/java/net/runelite/cache/models/ObjExporterTest.java
vendored
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* 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.cache.models;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import net.runelite.cache.definitions.ModelDefinition;
|
||||||
|
import net.runelite.cache.definitions.loaders.ModelLoader;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class ObjExporterTest
|
||||||
|
{
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testExport() throws Exception
|
||||||
|
{
|
||||||
|
ModelLoader loader = new ModelLoader();
|
||||||
|
ModelDefinition model = loader.load(11048, Files.readAllBytes(new File("D:\\rs\\07\\cache\\models\\11048.model").toPath()));
|
||||||
|
|
||||||
|
ObjExporter exporter = new ObjExporter(model);
|
||||||
|
try (PrintWriter objWriter = new PrintWriter(new FileWriter(new File("C:\\rs\\temp\\11048.obj")));
|
||||||
|
PrintWriter mtlWriter = new PrintWriter(new FileWriter(new File("C:\\rs\\temp\\11048.mtl"))))
|
||||||
|
{
|
||||||
|
exporter.export(objWriter, mtlWriter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -558,7 +558,7 @@ public class ModelViewer
|
|||||||
{
|
{
|
||||||
ModelLoader loader = new ModelLoader();
|
ModelLoader loader = new ModelLoader();
|
||||||
byte[] b = Files.readAllBytes(new File("models/" + id + ".model").toPath());
|
byte[] b = Files.readAllBytes(new File("models/" + id + ".model").toPath());
|
||||||
md = loader.load(b);
|
md = loader.load(id, b);
|
||||||
models[id] = md;
|
models[id] = md;
|
||||||
return md;
|
return md;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user