use of net.runelite.cache.models.VertexNormal in project ostracker by OSTracker.
the class ModelConverter method convert.
public void convert(int modelId, boolean overwriteFiles) {
File f = modelFiles.get(modelId);
if (f == null) {
throw new NullPointerException("A file for model " + modelId + " could not be found in the cache");
}
java.io.File materialsFile = new java.io.File(OSTracker.MODEL_DUMP_ROOT, modelId + "/materials.mtl");
java.io.File modelFile = new java.io.File(OSTracker.MODEL_DUMP_ROOT, modelId + "/model.obj");
if (!materialsFile.exists() || !modelFile.exists() || overwriteFiles) {
materialsFile.getParentFile().mkdirs();
byte[] modelBytes = f.getContents();
ModelDefinition definition = modelLoader.load(modelId, modelBytes);
definition.computeNormals();
definition.computeTextureUVCoordinates();
LOGGER.info("Dumping " + materialsFile);
try (PrintWriter writer = new PrintWriter(materialsFile)) {
for (int i = 0; i < definition.faceCount; i++) {
short textureId = -1;
if (definition.faceTextures != null) {
textureId = definition.faceTextures[i];
}
writer.println("newmtl m" + i);
if (textureId == -1) {
int hsb = definition.faceColors[i] & 0xFFFF;
int hue = (hsb >> 10) & 0x3F;
int saturation = (hsb >> 7) & 0x7;
int brightness = hsb & 0x7F;
int rgb = Color.HSBtoRGB(hue / 63F, saturation / 7F, brightness / 127F);
int red = (rgb >> 16) & 0xFF;
int green = (rgb >> 8) & 0xFF;
int blue = rgb & 0xFF;
double r = red / 255F;
double g = green / 255F;
double b = blue / 255F;
writer.println(" Kd " + r + " " + g + " " + b);
} else {
File textureFile = textureFiles.get((int) textureId);
if (textureFile != null) {
TextureDefinition textureDefinition = textureLoader.load(textureId, textureFile.getContents());
writer.println(" map_Kd ../../sprites/" + textureDefinition.getFileIds()[0] + "/0.png");
} else {
LOGGER.error("Model " + modelId + " was not dumped, because texture " + textureId + " was missing");
return;
}
}
int alpha = 0;
if (definition.faceAlphas != null) {
alpha = definition.faceAlphas[i] & 0xFF;
}
if (alpha != 0) {
writer.println(" d " + alpha / 255F);
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
LOGGER.info("Dumping " + modelFile);
try (PrintWriter writer = new PrintWriter(modelFile)) {
writer.println("mtllib materials.mtl");
for (int i = 0; i < definition.vertexCount; i++) {
writer.println("v " + definition.vertexPositionsX[i] + " " + definition.vertexPositionsY[i] * -1 + " " + definition.vertexPositionsZ[i] * -1);
}
if (definition.faceTextures != null) {
for (int i = 0; i < definition.faceCount; i++) {
writer.println("vt " + definition.faceTextureUCoordinates[i][0] + " " + definition.faceTextureVCoordinates[i][0]);
writer.println("vt " + definition.faceTextureUCoordinates[i][1] + " " + definition.faceTextureVCoordinates[i][1]);
writer.println("vt " + definition.faceTextureUCoordinates[i][2] + " " + definition.faceTextureVCoordinates[i][2]);
}
}
for (int i = 0; i < definition.vertexCount; i++) {
VertexNormal normal = definition.vertexNormals[i];
writer.println("vn " + normal.x + " " + normal.y + " " + normal.z);
}
for (int i = 0; i < definition.faceCount; i++) {
// Those shouldn't be drawn.
if (definition.faceRenderTypes == null || definition.faceRenderTypes[i] != 2) {
int x = definition.faceVertexIndices1[i] + 1;
int y = definition.faceVertexIndices2[i] + 1;
int z = definition.faceVertexIndices3[i] + 1;
writer.println("usemtl m" + i);
if (definition.faceTextures != null) {
writer.println("f " + x + "/" + (i * 3 + 1) + " " + y + "/" + (i * 3 + 2) + " " + z + "/" + (i * 3 + 3));
} else {
writer.println("f " + x + " " + y + " " + z);
}
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
use of net.runelite.cache.models.VertexNormal in project ostracker by OSTracker.
the class ModelData method method1624.
public final Model method1624(int var1, int var2, int var3, int var4, int var5) {
this.computeNormals();
int var6 = (int) Math.sqrt((double) (var3 * var3 + var4 * var4 + var5 * var5));
int var7 = var2 * var6 >> 8;
Model var8 = new Model();
var8.field1412 = new int[this.triangleFaceCount];
var8.field1416 = new int[this.triangleFaceCount];
var8.field1379 = new int[this.triangleFaceCount];
if (this.texturePointCount > 0 && this.textureCoords != null) {
// var16 contains how many faces use a specific texture
int[] var16 = new int[this.texturePointCount];
int var10;
for (var10 = 0; var10 < this.triangleFaceCount; ++var10) {
if (this.textureCoords[var10] != -1) {
++var16[this.textureCoords[var10] & 255];
}
}
var8.field1385 = 0;
for (var10 = 0; var10 < this.texturePointCount; ++var10) {
if (var16[var10] > 0 && this.textureRenderTypes[var10] == 0) {
++var8.field1385;
}
}
var8.texTriangleX = new int[var8.field1385];
var8.texTriangleY = new int[var8.field1385];
var8.texTriangleZ = new int[var8.field1385];
var10 = 0;
int var11;
for (var11 = 0; var11 < this.texturePointCount; ++var11) {
if (var16[var11] > 0 && this.textureRenderTypes[var11] == 0) {
var8.texTriangleX[var10] = this.texTriangleX[var11] & '';
var8.texTriangleY[var10] = this.texTriangleY[var11] & '';
var8.texTriangleZ[var10] = this.texTriangleZ[var11] & '';
var16[var11] = var10++;
} else {
var16[var11] = -1;
}
}
var8.triangleTextureIndex = new byte[this.triangleFaceCount];
for (var11 = 0; var11 < this.triangleFaceCount; ++var11) {
if (this.textureCoords[var11] != -1) {
var8.triangleTextureIndex[var11] = (byte) var16[this.textureCoords[var11] & 255];
} else {
var8.triangleTextureIndex[var11] = -1;
}
}
}
for (int var9 = 0; var9 < this.triangleFaceCount; ++var9) {
byte var17;
if (this.faceRenderType == null) {
var17 = 0;
} else {
var17 = this.faceRenderType[var9];
}
byte var18;
if (this.faceAlphas == null) {
var18 = 0;
} else {
var18 = this.faceAlphas[var9];
}
short var12;
if (this.faceTextures == null) {
var12 = -1;
} else {
var12 = this.faceTextures[var9];
}
if (var18 == -2) {
var17 = 3;
}
if (var18 == -1) {
var17 = 2;
}
VertexNormal var13;
int var14;
FaceNormal var19;
if (var12 == -1) {
if (var17 != 0) {
if (var17 == 1) {
var19 = this.faceNormals[var9];
var14 = var1 + (var3 * var19.x + var4 * var19.y + var5 * var19.z) / (var7 + var7 / 2);
var8.field1412[var9] = method1568(this.faceColor[var9] & '', var14);
var8.field1379[var9] = -1;
} else if (var17 == 3) {
var8.field1412[var9] = 128;
var8.field1379[var9] = -1;
} else {
var8.field1379[var9] = -2;
}
} else {
int var15 = this.faceColor[var9] & '';
if (this.normals2 != null && this.normals2[this.trianglePointsX[var9]] != null) {
var13 = this.normals2[this.trianglePointsX[var9]];
} else {
var13 = this.normals[this.trianglePointsX[var9]];
}
var14 = var1 + (var3 * var13.x + var4 * var13.y + var5 * var13.z) / (var7 * var13.magnitude);
var8.field1412[var9] = method1568(var15, var14);
if (this.normals2 != null && this.normals2[this.trianglePointsY[var9]] != null) {
var13 = this.normals2[this.trianglePointsY[var9]];
} else {
var13 = this.normals[this.trianglePointsY[var9]];
}
var14 = var1 + (var3 * var13.x + var4 * var13.y + var5 * var13.z) / (var7 * var13.magnitude);
var8.field1416[var9] = method1568(var15, var14);
if (this.normals2 != null && this.normals2[this.trianglePointsZ[var9]] != null) {
var13 = this.normals2[this.trianglePointsZ[var9]];
} else {
var13 = this.normals[this.trianglePointsZ[var9]];
}
var14 = var1 + (var3 * var13.x + var4 * var13.y + var5 * var13.z) / (var7 * var13.magnitude);
var8.field1379[var9] = method1568(var15, var14);
}
} else if (var17 != 0) {
if (var17 == 1) {
var19 = this.faceNormals[var9];
var14 = var1 + (var3 * var19.x + var4 * var19.y + var5 * var19.z) / (var7 + var7 / 2);
var8.field1412[var9] = method1569(var14);
var8.field1379[var9] = -1;
} else {
var8.field1379[var9] = -2;
}
} else {
if (this.normals2 != null && this.normals2[this.trianglePointsX[var9]] != null) {
var13 = this.normals2[this.trianglePointsX[var9]];
} else {
var13 = this.normals[this.trianglePointsX[var9]];
}
var14 = var1 + (var3 * var13.x + var4 * var13.y + var5 * var13.z) / (var7 * var13.magnitude);
var8.field1412[var9] = method1569(var14);
if (this.normals2 != null && this.normals2[this.trianglePointsY[var9]] != null) {
var13 = this.normals2[this.trianglePointsY[var9]];
} else {
var13 = this.normals[this.trianglePointsY[var9]];
}
var14 = var1 + (var3 * var13.x + var4 * var13.y + var5 * var13.z) / (var7 * var13.magnitude);
var8.field1416[var9] = method1569(var14);
if (this.normals2 != null && this.normals2[this.trianglePointsZ[var9]] != null) {
var13 = this.normals2[this.trianglePointsZ[var9]];
} else {
var13 = this.normals[this.trianglePointsZ[var9]];
}
var14 = var1 + (var3 * var13.x + var4 * var13.y + var5 * var13.z) / (var7 * var13.magnitude);
var8.field1379[var9] = method1569(var14);
}
}
this.computeAnimationTables();
var8.field1369 = this.vertexCount;
var8.verticesX = this.vertexX;
var8.verticesY = this.vertexY;
var8.verticesZ = this.vertexZ;
var8.field1384 = this.triangleFaceCount;
var8.indices1 = this.trianglePointsX;
var8.indices2 = this.trianglePointsY;
var8.indices3 = this.trianglePointsZ;
var8.field1383 = this.faceRenderPriorities;
var8.field1381 = this.faceAlphas;
var8.faceTextures = this.faceTextures;
return var8;
}
use of net.runelite.cache.models.VertexNormal in project runelite by runelite.
the class ModelDefinition method computeNormals.
public void computeNormals() {
if (this.vertexNormals != null) {
return;
}
this.vertexNormals = new VertexNormal[this.vertexCount];
int var1;
for (var1 = 0; var1 < this.vertexCount; ++var1) {
this.vertexNormals[var1] = new VertexNormal();
}
for (var1 = 0; var1 < this.faceCount; ++var1) {
int vertexA = this.faceVertexIndices1[var1];
int vertexB = this.faceVertexIndices2[var1];
int vertexC = this.faceVertexIndices3[var1];
int xA = this.vertexPositionsX[vertexB] - this.vertexPositionsX[vertexA];
int yA = this.vertexPositionsY[vertexB] - this.vertexPositionsY[vertexA];
int zA = this.vertexPositionsZ[vertexB] - this.vertexPositionsZ[vertexA];
int xB = this.vertexPositionsX[vertexC] - this.vertexPositionsX[vertexA];
int yB = this.vertexPositionsY[vertexC] - this.vertexPositionsY[vertexA];
int zB = this.vertexPositionsZ[vertexC] - this.vertexPositionsZ[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.faceRenderTypes == null) {
var15 = 0;
} else {
var15 = this.faceRenderTypes[var1];
}
if (var15 == 0) {
VertexNormal var16 = this.vertexNormals[vertexA];
var16.x += var11;
var16.y += var12;
var16.z += var13;
++var16.magnitude;
var16 = this.vertexNormals[vertexB];
var16.x += var11;
var16.y += var12;
var16.z += var13;
++var16.magnitude;
var16 = this.vertexNormals[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.faceCount];
}
FaceNormal var17 = this.faceNormals[var1] = new FaceNormal();
var17.x = var11;
var17.y = var12;
var17.z = var13;
}
}
}
use of net.runelite.cache.models.VertexNormal in project runelite by runelite.
the class ItemSpriteFactory method light.
private static Model light(ModelDefinition def, int ambient, int contrast, int x, int y, int z) {
def.computeNormals();
int somethingMagnitude = (int) Math.sqrt((double) (z * z + x * x + y * y));
int var7 = somethingMagnitude * contrast >> 8;
Model litModel = new Model();
litModel.field1856 = new int[def.faceCount];
litModel.field1854 = new int[def.faceCount];
litModel.field1823 = new int[def.faceCount];
if (def.textureTriangleCount > 0 && def.textureCoordinates != null) {
int[] var9 = new int[def.textureTriangleCount];
int var10;
for (var10 = 0; var10 < def.faceCount; ++var10) {
if (def.textureCoordinates[var10] != -1) {
++var9[def.textureCoordinates[var10] & 255];
}
}
litModel.field1852 = 0;
for (var10 = 0; var10 < def.textureTriangleCount; ++var10) {
if (var9[var10] > 0 && def.textureRenderTypes[var10] == 0) {
++litModel.field1852;
}
}
litModel.field1844 = new int[litModel.field1852];
litModel.field1865 = new int[litModel.field1852];
litModel.field1846 = new int[litModel.field1852];
var10 = 0;
for (int i = 0; i < def.textureTriangleCount; ++i) {
if (var9[i] > 0 && def.textureRenderTypes[i] == 0) {
litModel.field1844[var10] = def.textureTriangleVertexIndices1[i] & '\uffff';
litModel.field1865[var10] = def.textureTriangleVertexIndices2[i] & '\uffff';
litModel.field1846[var10] = def.textureTriangleVertexIndices3[i] & '\uffff';
var9[i] = var10++;
} else {
var9[i] = -1;
}
}
litModel.field1840 = new byte[def.faceCount];
for (int i = 0; i < def.faceCount; ++i) {
if (def.textureCoordinates[i] != -1) {
litModel.field1840[i] = (byte) var9[def.textureCoordinates[i] & 255];
} else {
litModel.field1840[i] = -1;
}
}
}
for (int faceIdx = 0; faceIdx < def.faceCount; ++faceIdx) {
byte faceType;
if (def.faceRenderTypes == null) {
faceType = 0;
} else {
faceType = def.faceRenderTypes[faceIdx];
}
byte faceAlpha;
if (def.faceAlphas == null) {
faceAlpha = 0;
} else {
faceAlpha = def.faceAlphas[faceIdx];
}
short faceTexture;
if (def.faceTextures == null) {
faceTexture = -1;
} else {
faceTexture = def.faceTextures[faceIdx];
}
if (faceAlpha == -2) {
faceType = 3;
}
if (faceAlpha == -1) {
faceType = 2;
}
VertexNormal vertexNormal;
int tmp;
FaceNormal faceNormal;
if (faceTexture == -1) {
if (faceType != 0) {
if (faceType == 1) {
faceNormal = def.faceNormals[faceIdx];
tmp = (y * faceNormal.y + z * faceNormal.z + x * faceNormal.x) / (var7 / 2 + var7) + ambient;
litModel.field1856[faceIdx] = method2608(def.faceColors[faceIdx] & '\uffff', tmp);
litModel.field1823[faceIdx] = -1;
} else if (faceType == 3) {
litModel.field1856[faceIdx] = 128;
litModel.field1823[faceIdx] = -1;
} else {
litModel.field1823[faceIdx] = -2;
}
} else {
int var15 = def.faceColors[faceIdx] & '\uffff';
vertexNormal = def.vertexNormals[def.faceVertexIndices1[faceIdx]];
tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient;
litModel.field1856[faceIdx] = method2608(var15, tmp);
vertexNormal = def.vertexNormals[def.faceVertexIndices2[faceIdx]];
tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient;
litModel.field1854[faceIdx] = method2608(var15, tmp);
vertexNormal = def.vertexNormals[def.faceVertexIndices3[faceIdx]];
tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient;
litModel.field1823[faceIdx] = method2608(var15, tmp);
}
} else if (faceType != 0) {
if (faceType == 1) {
faceNormal = def.faceNormals[faceIdx];
tmp = (y * faceNormal.y + z * faceNormal.z + x * faceNormal.x) / (var7 / 2 + var7) + ambient;
litModel.field1856[faceIdx] = bound2to126(tmp);
litModel.field1823[faceIdx] = -1;
} else {
litModel.field1823[faceIdx] = -2;
}
} else {
vertexNormal = def.vertexNormals[def.faceVertexIndices1[faceIdx]];
tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient;
litModel.field1856[faceIdx] = bound2to126(tmp);
vertexNormal = def.vertexNormals[def.faceVertexIndices2[faceIdx]];
tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient;
litModel.field1854[faceIdx] = bound2to126(tmp);
vertexNormal = def.vertexNormals[def.faceVertexIndices3[faceIdx]];
tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient;
litModel.field1823[faceIdx] = bound2to126(tmp);
}
}
litModel.verticesCount = def.vertexCount;
litModel.verticesX = def.vertexPositionsX;
litModel.verticesY = def.vertexPositionsY;
litModel.verticesZ = def.vertexPositionsZ;
litModel.indicesCount = def.faceCount;
litModel.indices1 = def.faceVertexIndices1;
litModel.indices2 = def.faceVertexIndices2;
litModel.indices3 = def.faceVertexIndices3;
litModel.field1838 = def.faceRenderPriorities;
litModel.field1882 = def.faceAlphas;
litModel.field1842 = def.priority;
litModel.field1841 = def.faceTextures;
return litModel;
}
use of net.runelite.cache.models.VertexNormal in project runelite by runelite.
the class ModelViewer method drawModel.
private static void drawModel(ModelDefinition md, short[] recolourToFind, short[] recolourToReplace) {
for (int i = 0; i < md.faceCount; ++i) {
if (md.faceRenderTypes != null) {
byte faceRenderType = md.faceRenderTypes[i];
if ((faceRenderType & 2) != 0) {
// what is this?
continue;
}
}
int vertexA = md.faceVertexIndices1[i];
int vertexB = md.faceVertexIndices2[i];
int vertexC = md.faceVertexIndices3[i];
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;
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;
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 {
short hsb = md.faceColors[i];
// Check recolor
if (recolourToFind != null) {
for (int j = 0; j < recolourToFind.length; ++j) {
if (recolourToFind[j] == hsb) {
hsb = recolourToReplace[j];
}
}
}
int rgb = RS2HSB_to_RGB(hsb);
color = new Color(rgb);
}
// convert to range of 0-1
float rf = (float) color.getRed() / 255f;
float gf = (float) color.getGreen() / 255f;
float bf = (float) color.getBlue() / 255f;
GL11.glBegin(GL11.GL_TRIANGLES);
GL11.glColor3f(rf, gf, bf);
// 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);
if (textureId != -1) {
GL11.glTexCoord2f(u[0], v[0]);
}
GL11.glVertex3i(vertexAx, -vertexAy, vertexAz);
GL11.glNormal3f(nC.x, nC.y, nC.z);
if (textureId != -1) {
GL11.glTexCoord2f(u[2], v[2]);
}
GL11.glVertex3i(vertexCx, -vertexCy, vertexCz);
GL11.glNormal3f(nB.x, nB.y, nB.z);
if (textureId != -1) {
GL11.glTexCoord2f(u[1], v[1]);
}
GL11.glVertex3i(vertexBx, -vertexBy, vertexBz);
GL11.glEnd();
if (textureId != -1) {
GL11.glDisable(GL11.GL_TEXTURE_2D);
}
}
}
Aggregations