model viewer: load normals and enable cull face
This commit is contained in:
@@ -1,5 +1,8 @@
|
|||||||
package net.runelite.cache.definitions;
|
package net.runelite.cache.definitions;
|
||||||
|
|
||||||
|
import net.runelite.cache.models.FaceNormal;
|
||||||
|
import net.runelite.cache.models.VertexNormal;
|
||||||
|
|
||||||
public class ModelDefinition
|
public class ModelDefinition
|
||||||
{
|
{
|
||||||
public short[] texTriangleX;
|
public short[] texTriangleX;
|
||||||
@@ -41,5 +44,103 @@ 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 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);
|
this.load2(def, var1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def.computeNormals();
|
||||||
|
|
||||||
return def;
|
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);
|
Mouse.setGrabbed(true);
|
||||||
}
|
}
|
||||||
if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE))
|
if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE) || Keyboard.isKeyDown(Keyboard.KEY_LMENU))
|
||||||
{
|
{
|
||||||
Mouse.setGrabbed(false);
|
Mouse.setGrabbed(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ import java.util.List;
|
|||||||
import net.runelite.cache.definitions.ModelDefinition;
|
import net.runelite.cache.definitions.ModelDefinition;
|
||||||
import net.runelite.cache.definitions.NpcDefinition;
|
import net.runelite.cache.definitions.NpcDefinition;
|
||||||
import net.runelite.cache.definitions.loaders.ModelLoader;
|
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.CommandLine;
|
||||||
import org.apache.commons.cli.CommandLineParser;
|
import org.apache.commons.cli.CommandLineParser;
|
||||||
import org.apache.commons.cli.DefaultParser;
|
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.glFrustum(-aspect * near * fov, aspect * near * fov, -fov, fov, near, far);
|
||||||
|
|
||||||
GL11.glEnable(GL11.GL_DEPTH_TEST);
|
GL11.glEnable(GL11.GL_DEPTH_TEST);
|
||||||
|
|
||||||
GL11.glCullFace(GL11.GL_BACK);
|
GL11.glCullFace(GL11.GL_BACK);
|
||||||
|
GL11.glEnable(GL11.GL_CULL_FACE);
|
||||||
|
|
||||||
long last = 0;
|
long last = 0;
|
||||||
|
|
||||||
Camera camera = new Camera();
|
Camera camera = new Camera();
|
||||||
|
|
||||||
GL11.glMatrixMode(GL11.GL_MODELVIEW);
|
|
||||||
glRotatef(45, 1, 0, 0);
|
|
||||||
GL11.glPopMatrix();
|
|
||||||
|
|
||||||
while (!Display.isCloseRequested())
|
while (!Display.isCloseRequested())
|
||||||
{
|
{
|
||||||
// Clear the screen and depth buffer
|
// Clear the screen and depth buffer
|
||||||
@@ -159,6 +159,19 @@ public class ModelViewer
|
|||||||
int vertexB = md.trianglePointsY[i];
|
int vertexB = md.trianglePointsY[i];
|
||||||
int vertexC = md.trianglePointsZ[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 vertexAx = md.vertexX[vertexA];
|
||||||
int vertexAy = md.vertexY[vertexA];
|
int vertexAy = md.vertexY[vertexA];
|
||||||
int vertexAz = md.vertexZ[vertexA];
|
int vertexAz = md.vertexZ[vertexA];
|
||||||
@@ -195,9 +208,17 @@ public class ModelViewer
|
|||||||
|
|
||||||
GL11.glColor3f(rf, gf, bf);
|
GL11.glColor3f(rf, gf, bf);
|
||||||
|
|
||||||
GL11.glVertex3i(vertexAx, vertexAy, vertexAz);
|
// With GL11.GL_CCW we have to draw A -> C -> B when
|
||||||
GL11.glVertex3i(vertexBx, vertexBy, vertexBz);
|
// inverting y instead of A -> B -> C, or else with cull
|
||||||
GL11.glVertex3i(vertexCx, vertexCy, vertexCz);
|
// 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();
|
GL11.glEnd();
|
||||||
|
|||||||
Reference in New Issue
Block a user