model viewer: load normals and enable cull face

This commit is contained in:
Adam
2016-12-04 18:02:25 -05:00
parent b8c8140311
commit 22a6a3d402
7 changed files with 178 additions and 8 deletions

View File

@@ -1,5 +1,8 @@
package net.runelite.cache.definitions;
import net.runelite.cache.models.FaceNormal;
import net.runelite.cache.models.VertexNormal;
public class ModelDefinition
{
public short[] texTriangleX;
@@ -41,5 +44,103 @@ public class ModelDefinition
public int anInt2595;
public int vertexCount = 0;
public short[] texturePrimaryColor;
public VertexNormal[] normals;
public FaceNormal[] faceNormals;
public void computeNormals()
{
if (this.normals != null)
{
return;
}
this.normals = new VertexNormal[this.vertexCount];
int var1;
for (var1 = 0; var1 < this.vertexCount; ++var1)
{
this.normals[var1] = new VertexNormal();
}
for (var1 = 0; var1 < this.triangleFaceCount; ++var1)
{
int vertexA = this.trianglePointsX[var1];
int vertexB = this.trianglePointsY[var1];
int vertexC = this.trianglePointsZ[var1];
int xA = this.vertexX[vertexB] - this.vertexX[vertexA];
int yA = this.vertexY[vertexB] - this.vertexY[vertexA];
int zA = this.vertexZ[vertexB] - this.vertexZ[vertexA];
int xB = this.vertexX[vertexC] - this.vertexX[vertexA];
int yB = this.vertexY[vertexC] - this.vertexY[vertexA];
int zB = this.vertexZ[vertexC] - this.vertexZ[vertexA];
// Compute cross product
int var11 = yA * zB - yB * zA;
int var12 = zA * xB - zB * xA;
int var13 = xA * yB - xB * yA;
while (var11 > 8192 || var12 > 8192 || var13 > 8192 || var11 < -8192 || var12 < -8192 || var13 < -8192)
{
var11 >>= 1;
var12 >>= 1;
var13 >>= 1;
}
int length = (int) Math.sqrt((double) (var11 * var11 + var12 * var12 + var13 * var13));
if (length <= 0)
{
length = 1;
}
var11 = var11 * 256 / length;
var12 = var12 * 256 / length;
var13 = var13 * 256 / length;
byte var15;
if (this.faceRenderType == null)
{
var15 = 0;
}
else
{
var15 = this.faceRenderType[var1];
}
if (var15 == 0)
{
VertexNormal var16 = this.normals[vertexA];
var16.x += var11;
var16.y += var12;
var16.z += var13;
++var16.magnitude;
var16 = this.normals[vertexB];
var16.x += var11;
var16.y += var12;
var16.z += var13;
++var16.magnitude;
var16 = this.normals[vertexC];
var16.x += var11;
var16.y += var12;
var16.z += var13;
++var16.magnitude;
}
else if (var15 == 1)
{
if (this.faceNormals == null)
{
this.faceNormals = new FaceNormal[this.triangleFaceCount];
}
FaceNormal var17 = this.faceNormals[var1] = new FaceNormal();
var17.x = var11;
var17.y = var12;
var17.z = var13;
}
}
}
}

View File

@@ -18,6 +18,8 @@ public class ModelLoader
this.load2(def, var1);
}
def.computeNormals();
return def;
}

View File

@@ -0,0 +1,8 @@
package net.runelite.cache.models;
public class FaceNormal
{
public int x;
public int y;
public int z;
}

View File

@@ -0,0 +1,8 @@
package net.runelite.cache.models;
public class Vector3f
{
public float x;
public float y;
public float z;
}

View File

@@ -0,0 +1,30 @@
package net.runelite.cache.models;
public class VertexNormal
{
public int x;
public int y;
public int z;
public int magnitude;
public Vector3f normalize()
{
Vector3f v = new Vector3f();
int length = (int) Math.sqrt((double) (x * x + y * y + z * z));
if (length == 0)
{
length = 1;
}
v.x = (float) x / length;
v.y = (float) y / length;
v.z = (float) z / length;
assert v.x >= -1f && v.x <= 1f;
assert v.y >= -1f && v.y <= 1f;
assert v.z >= -1f && v.z <= 1f;
return v;
}
}

View File

@@ -107,7 +107,7 @@ public class Camera
{
Mouse.setGrabbed(true);
}
if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE))
if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE) || Keyboard.isKeyDown(Keyboard.KEY_LMENU))
{
Mouse.setGrabbed(false);
}

View File

@@ -40,6 +40,8 @@ import java.util.List;
import net.runelite.cache.definitions.ModelDefinition;
import net.runelite.cache.definitions.NpcDefinition;
import net.runelite.cache.definitions.loaders.ModelLoader;
import net.runelite.cache.models.Vector3f;
import net.runelite.cache.models.VertexNormal;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
@@ -116,16 +118,14 @@ public class ModelViewer
GL11.glFrustum(-aspect * near * fov, aspect * near * fov, -fov, fov, near, far);
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glCullFace(GL11.GL_BACK);
GL11.glEnable(GL11.GL_CULL_FACE);
long last = 0;
Camera camera = new Camera();
GL11.glMatrixMode(GL11.GL_MODELVIEW);
glRotatef(45, 1, 0, 0);
GL11.glPopMatrix();
while (!Display.isCloseRequested())
{
// Clear the screen and depth buffer
@@ -159,6 +159,19 @@ public class ModelViewer
int vertexB = md.trianglePointsY[i];
int vertexC = md.trianglePointsZ[i];
VertexNormal normalVertexA = md.normals[vertexA];
VertexNormal normalVertexB = md.normals[vertexB];
VertexNormal normalVertexC = md.normals[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;
int vertexAx = md.vertexX[vertexA];
int vertexAy = md.vertexY[vertexA];
int vertexAz = md.vertexZ[vertexA];
@@ -195,9 +208,17 @@ public class ModelViewer
GL11.glColor3f(rf, gf, bf);
GL11.glVertex3i(vertexAx, vertexAy, vertexAz);
GL11.glVertex3i(vertexBx, vertexBy, vertexBz);
GL11.glVertex3i(vertexCx, vertexCy, vertexCz);
// With GL11.GL_CCW we have to draw A -> C -> B when
// inverting y instead of A -> B -> C, or else with cull
// face will cull the wrong side
GL11.glNormal3f(nA.x, nA.y, nA.z);
GL11.glVertex3i(vertexAx, -vertexAy, vertexAz);
GL11.glNormal3f(nC.x, nC.y, nC.z);
GL11.glVertex3i(vertexCx, -vertexCy, vertexCz);
GL11.glNormal3f(nB.x, nB.y, nB.z);
GL11.glVertex3i(vertexBx, -vertexBy, vertexBz);
}
GL11.glEnd();