model viewer: load normals and enable cull face
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ public class ModelLoader
|
||||
this.load2(def, var1);
|
||||
}
|
||||
|
||||
def.computeNormals();
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
|
||||
8
cache/src/main/java/net/runelite/cache/models/FaceNormal.java
vendored
Normal file
8
cache/src/main/java/net/runelite/cache/models/FaceNormal.java
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
package net.runelite.cache.models;
|
||||
|
||||
public class FaceNormal
|
||||
{
|
||||
public int x;
|
||||
public int y;
|
||||
public int z;
|
||||
}
|
||||
8
cache/src/main/java/net/runelite/cache/models/Vector3f.java
vendored
Normal file
8
cache/src/main/java/net/runelite/cache/models/Vector3f.java
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
package net.runelite.cache.models;
|
||||
|
||||
public class Vector3f
|
||||
{
|
||||
public float x;
|
||||
public float y;
|
||||
public float z;
|
||||
}
|
||||
30
cache/src/main/java/net/runelite/cache/models/VertexNormal.java
vendored
Normal file
30
cache/src/main/java/net/runelite/cache/models/VertexNormal.java
vendored
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user