Code:
package com.common.cache.reader.loaders.models;
import com.common.cache.Cache;
import com.common.cache.reader.loaders.CacheData;
import com.common.cache.reader.store.Store;
import com.common.net.game.io.InputStream;
import com.common.net.game.io.OutputStream;
import com.common.cache.reader.utils.CacheIndex;
import com.common.utils.logger.Logger;
import lombok.Getter;
/**
* Loads the model information such as vertexes, normals, face color, particles, textures, etc..
* This model loader supports all the format up to at least revision 838. It will automatically choose
* which format to use depending on the first/last few bytes of the model.
*
* https://www.rune-server.ee/runescape-development/rs2-client/snippets/468189-100-refactored-model-header.html
*/
public class Model extends CacheData {
private static final CacheIndex MODEL__INDEX = CacheIndex.MODELS;
private enum Format { OLD, NEW, EOC, MULTI }
public static Model getModel(int modelId) {
return getModel(Cache.getCache(), modelId);
}
public static Model getModel(Store store, int modelId) {
if (modelId < 0 || modelId >= store.getIndex(MODEL__INDEX).getFilesCount()) {
return null;
}
if (store.getIndex(MODEL__INDEX).getStoredData() == null) {
store.getIndex(MODEL__INDEX).setStoredData(new CacheData[store.getIndex(MODEL__INDEX).getFilesCount()]);
}
Model defs = (Model)store.getIndex(MODEL__INDEX).getStoredData()[modelId];
if (defs != null) {
return defs;
}
byte[] data = store.getIndex(MODEL__INDEX).getFile(modelId, 0);
if (data == null) {
return null;
}
defs = new Model(data, modelId);
store.getIndex(MODEL__INDEX).getStoredData()[modelId] = defs;
return defs;
}
@Getter private int maxDepth;
private int numTextureTriangles;
@Getter private short[] textureIds;
private int[] texturePrimaryColor;
private int[] textureSecondaryColor;
@Getter private short[] textureCoords;
@Getter private byte[] textureRenderTypes;
@Getter private short[] textureTriangleX;
@Getter private short[] textureTriangleY;
@Getter private short[] textureTriangleZ;
/* added */
@Getter private transient float[][] faceTextureUCoordinates;
@Getter private transient float[][] faceTextureVCoordinates;
@Getter private transient VertexNormal[] vertexNormals;//different ones, unique to compute normals
/*
* Rs3 params
*/
private int numUVCoords;// unused
@Getter private float[] textureCoordU;// unused
@Getter private float[] textureCoordV;// unused
private byte[] uvCoordVertexA;// unused
private byte[] uvCoordVertexB;// unused
private byte[] uvCoordVertexC;// unused
private int[] anIntArray1669;// unused
@Getter private int numVertices = 0;
@Getter private int[] vertexX;
@Getter private int[] vertexY;
@Getter private int[] vertexZ;
@Getter private int[] vertexSkins;
@Getter private int numTriangles;
@Getter private byte[] trianglePriorities;
@Getter private int[] triangleSkinValues;
@Getter private short[] triangleViewspaceX;
@Getter private short[] triangleViewspaceY;
@Getter private short[] triangleViewspaceZ;
@Getter private byte[] faceAlpha;
@Getter private short[] faceColor;
@Getter private byte[] faceRenderType;
@Getter private SurfaceSkin[] surfaceSkins;
@Getter private VertexNormal[] isolatedVertexNormals;
@Getter private Particle[] particles;
@Getter private int[] particleDirectionX;
@Getter private int[] particleDirectionY;
@Getter private int[] particleDirectionZ;
private byte[] particleLifespanX;
private byte[] particleLifespanY;
private int[] particleLifespanZ;
private short[] aShortArray879;
private short[] aShortArray892;
@Getter private int modelId;
@Getter private Format format;
private int version = 12;
private byte priority;
public Model(Model[] models) {
decodeMulti(models);
}
public boolean isEOC() {
return format == Format.EOC;
}
private Model(byte[] data) {
decode(data);
}
private Model(byte[] data, int modelId) {
this.modelId = modelId;
initModel();
decode(data);
}
private void initModel() {
maxDepth = 0;
numTriangles = 0;
priority = (byte) 0;
numTextureTriangles = 0;
}
@Override
public void decode(byte[] data) {
if (isCurrentFormat(data) && !isNewFormat(data)) {
decodeEOCModel(data);
} else {
if (isNewFormat(data)) {
decodeNewModel(data);
} else {
decodeOldModel(data);
}
}
if (version < 13) {
resizeModel(2);
}
}
private void decodeMulti(Model[] models) {
this.format = Format.MULTI;
maxDepth = 0;
numTriangles = 0;
priority = (byte) 0;
numTextureTriangles = 0;
numVertices = 0;
numTriangles = 0;
numUVCoords = 0;
int i_2_ = 0;
int i_3_ = 0;
int i_4_ = 0;
boolean bool = false;
boolean bool_5_ = false;
boolean bool_6_ = false;
boolean bool_7_ = false;
boolean bool_8_ = false;
boolean bool_9_ = false;
priority = (byte) -1;
for (int i_10_ = 0; i_10_ < models.length; i_10_++) {
Model model_Pt1 = models[i_10_];
if (model_Pt1 != null) {
numVertices += model_Pt1.numVertices;
numTriangles += model_Pt1.numTriangles;
numTextureTriangles += model_Pt1.numTextureTriangles;
numUVCoords += model_Pt1.numUVCoords;// ADDED RS3
if (model_Pt1.particles != null) {
i_2_ += model_Pt1.particles.length;
}
if (model_Pt1.surfaceSkins != null) {
i_3_ += model_Pt1.surfaceSkins.length;
}
if (model_Pt1.isolatedVertexNormals != null) {
i_4_ += model_Pt1.isolatedVertexNormals.length;
}
bool = bool | model_Pt1.faceRenderType != null;
if (model_Pt1.trianglePriorities != null) {
bool_5_ = true;
}
else {
if (priority == -1) {
priority = model_Pt1.priority;
}
if (priority != model_Pt1.priority) {
bool_5_ = true;
}
}
bool_6_ = bool_6_ | model_Pt1.faceAlpha != null;
bool_7_ = bool_7_ | model_Pt1.textureCoords != null;
bool_8_ = bool_8_ | model_Pt1.textureIds != null;
bool_9_ = bool_9_ | model_Pt1.triangleSkinValues != null;
}
}
vertexX = new int[numVertices];
vertexY = new int[numVertices];
vertexZ = new int[numVertices];
vertexSkins = new int[numVertices];
aShortArray879 = new short[numVertices];
triangleViewspaceX = new short[numTriangles];
triangleViewspaceY = new short[numTriangles];
triangleViewspaceZ = new short[numTriangles];
if (bool) {
faceRenderType = new byte[numTriangles];
}
if (bool_5_) {
trianglePriorities = new byte[numTriangles];
}
if (bool_6_) {
faceAlpha = new byte[numTriangles];
}
if (bool_7_) {
textureCoords = new short[numTriangles];
}
faceColor = new short[numTriangles];
if (bool_8_) {
textureIds = new short[numTriangles];
}
if (bool_9_) {
triangleSkinValues = new int[numTriangles];
}
aShortArray892 = new short[numTriangles];
if (numTextureTriangles > 0) {
textureRenderTypes = new byte[numTextureTriangles];
textureTriangleX = new short[numTextureTriangles];
textureTriangleY = new short[numTextureTriangles];
textureTriangleZ = new short[numTextureTriangles];
particleDirectionX = new int[numTextureTriangles];
particleDirectionY = new int[numTextureTriangles];
particleDirectionZ = new int[numTextureTriangles];
particleLifespanX = new byte[numTextureTriangles];
particleLifespanY = new byte[numTextureTriangles];
particleLifespanZ = new int[numTextureTriangles];
texturePrimaryColor = new int[numTextureTriangles];
textureSecondaryColor = new int[numTextureTriangles];
}
/*
* Rs3 START
*/
if (numUVCoords > 0) {
textureCoordU = new float[numUVCoords];
textureCoordV = new float[numUVCoords];
anIntArray1669 = new int[numVertices];
uvCoordVertexA = new byte[numTriangles];
uvCoordVertexB = new byte[numTriangles];
uvCoordVertexC = new byte[numTriangles];
}
/*
* RS3 END
*/
if (i_4_ > 0) {
isolatedVertexNormals = new VertexNormal[i_4_];
}
if (i_2_ > 0) {
particles = new Particle[i_2_];
}
if (i_3_ > 0) {
surfaceSkins = new SurfaceSkin[i_3_];
}
int[] is = new int[numVertices];
int[] is_100_ = new int[numUVCoords];
int[] is_101_ = new int[numVertices];
int[] is_102_ = new int[numVertices];
int[] is_103_ = new int[3];
numVertices = 0;
numTriangles = 0;
numTextureTriangles = 0;
numUVCoords = 0;// ADDED RS3
i_2_ = 0;
i_3_ = 0;
i_4_ = 0;
for (int i_12_ = 0; i_12_ < models.length; i_12_++) {
short i_13_ = (short) (1 << i_12_);
Model model_Pt2 = models[i_12_];
if (model_Pt2 != null) {
boolean[] bools = new boolean[model_Pt2.numVertices];
if (model_Pt2.isolatedVertexNormals != null) {
for (int i_15_ = 0; i_15_ < model_Pt2.isolatedVertexNormals.length; i_15_++) {
VertexNormal class94 = model_Pt2.isolatedVertexNormals[i_15_];
isolatedVertexNormals[i_4_++] = class94.generateVertexNormalFromY((class94.getY()) + numTriangles);
}
}
/*
* RS3 START
*/
if (model_Pt2.isEOC()) {
for (int i_109_ = 0; i_109_ < model_Pt2.numTriangles; i_109_++) {
is_103_[0] = model_Pt2.triangleViewspaceX[i_109_];
is_103_[1] = model_Pt2.triangleViewspaceY[i_109_];
is_103_[2] = model_Pt2.triangleViewspaceZ[i_109_];
for (int i_110_ = 0; i_110_ < 3; i_110_++) {
int i_111_ = is_103_[i_110_];
int i_112_ = model_Pt2.vertexX[i_111_];
int i_113_ = model_Pt2.vertexY[i_111_];
int i_114_ = model_Pt2.vertexZ[i_111_];
int i_115_;
for (i_115_ = 0; i_115_ < numVertices; i_115_++) {
if (i_112_ == vertexX[i_115_] && i_113_ == vertexY[i_115_] && i_114_ == vertexZ[i_115_]) {
aShortArray879[i_115_] |= i_13_;
is_101_[i_111_] = i_115_;
break;
}
}
if (model_Pt2.numUVCoords > 0 && !bools[i_111_]) {
int i_116_ = ((i_111_ < model_Pt2.numVertices - 1 ? model_Pt2.anIntArray1669[i_111_ + 1] : model_Pt2.numUVCoords) - model_Pt2.anIntArray1669[i_111_]);
for (int i_117_ = 0; i_117_ < i_116_; i_117_++) {
textureCoordU[numUVCoords] = (model_Pt2.textureCoordU[(model_Pt2.anIntArray1669[i_111_] + i_117_)]);
textureCoordV[numUVCoords] = (model_Pt2.textureCoordV[(model_Pt2.anIntArray1669[i_111_] + i_117_)]);
is_100_[numUVCoords] = i_115_ << 16 | is[i_115_] + i_117_;
numUVCoords++;
}
is_102_[i_111_] = is[i_115_];
is[i_115_] += i_116_;
bools[i_111_] = true;
}
if (i_115_ >= numVertices) {
vertexX[numVertices] = i_112_;
vertexY[numVertices] = i_113_;
vertexZ[numVertices] = i_114_;
aShortArray879[numVertices] = i_13_;
vertexSkins[numVertices] = (model_Pt2.vertexSkins != null ? model_Pt2.vertexSkins[i_111_] : -1);
is_101_[i_111_] = numVertices;
numVertices++;
}
}
}
}
/*
* RS3 END
*/
for (int i_16_ = 0; i_16_ < model_Pt2.numTriangles; i_16_++) {
if (bool && model_Pt2.faceRenderType != null) {
faceRenderType[numTriangles] = model_Pt2.faceRenderType[i_16_];
}
if (bool_5_) {
if (model_Pt2.trianglePriorities != null) {
trianglePriorities[numTriangles] = model_Pt2.trianglePriorities[i_16_];
} else {
trianglePriorities[numTriangles] = model_Pt2.priority;
}
}
if (bool_6_ && model_Pt2.faceAlpha != null) {
faceAlpha[numTriangles] = model_Pt2.faceAlpha[i_16_];
}
if (bool_8_) {
if (model_Pt2.textureIds != null) {
textureIds[numTriangles] = model_Pt2.textureIds[i_16_];
} else {
textureIds[numTriangles] = (short) -1;
}
}
if (bool_9_) {
if (model_Pt2.triangleSkinValues != null) {
triangleSkinValues[numTriangles] = model_Pt2.triangleSkinValues[i_16_];
} else {
triangleSkinValues[numTriangles] = -1;
}
}
/*
* RS3 START
*/
if (model_Pt2.numUVCoords > 0) {
uvCoordVertexA[numTriangles] = (byte) (model_Pt2.uvCoordVertexA[i_16_] + is_102_[(model_Pt2.triangleViewspaceX[i_16_])]);
uvCoordVertexB[numTriangles] = (byte) (model_Pt2.uvCoordVertexB[i_16_] + is_102_[(model_Pt2.triangleViewspaceY[i_16_])]);
uvCoordVertexC[numTriangles] = (byte) (model_Pt2.uvCoordVertexC[i_16_] + is_102_[(model_Pt2.triangleViewspaceZ[i_16_])]);
}
/*
* RS3 END
*/
triangleViewspaceX[numTriangles] = (short) method1186(model_Pt2, model_Pt2.triangleViewspaceX[i_16_], i_13_);
triangleViewspaceY[numTriangles] = (short) method1186(model_Pt2, model_Pt2.triangleViewspaceY[i_16_], i_13_);
triangleViewspaceZ[numTriangles] = (short) method1186(model_Pt2, model_Pt2.triangleViewspaceZ[i_16_], i_13_);
aShortArray892[numTriangles] = i_13_;
faceColor[numTriangles] = model_Pt2.faceColor[i_16_];
numTriangles++;
}
if (model_Pt2.particles != null) {
for (int i_17_ = 0; i_17_ < model_Pt2.particles.length; i_17_++) {
int i_18_ = method1186(model_Pt2, (model_Pt2.particles[i_17_].getX()), i_13_);
int i_19_ = method1186(model_Pt2, (model_Pt2.particles[i_17_].getY()), i_13_);
int i_20_ = method1186(model_Pt2, (model_Pt2.particles[i_17_].getZ()), i_13_);
particles[i_2_] = model_Pt2.particles[i_17_].generateNewParticleFromVertexes(i_18_, i_19_, i_20_);
i_2_++;
}
}
if (model_Pt2.surfaceSkins != null) {
for (int i_21_ = 0; i_21_ < model_Pt2.surfaceSkins.length; i_21_++) {
int i_22_ = method1186(model_Pt2, (model_Pt2.surfaceSkins[i_21_].getPoint()), i_13_);
surfaceSkins[i_3_] = model_Pt2.surfaceSkins[i_21_].generateSurfaceSkinFromPoint(i_22_);
i_3_++;
}
}
}
}
maxDepth = numVertices;
/*
* RS3 START
*/
if (numUVCoords > 0) {
//Class330_Sub40_Sub1.method3584(is_100_, textureCoordU, textureCoordV, (byte) 2);
int i_125_ = 0;
int i_126_ = 0;
for (; i_125_ < numVertices; i_125_++) {
anIntArray1669[i_125_] = i_126_;
i_126_ += is[i_125_];
}
}
/*
* RS3 END
*/
int i_23_ = 0;
for (int i_24_ = 0; i_24_ < models.length; i_24_++) {
short i_25_ = (short) (1 << i_24_);
Model model_Pt3 = models[i_24_];
if (model_Pt3 != null) {
/*
* RS3 START
*/
if (model_Pt3.isEOC()) {
if (bool_7_) {
int i_131_ = 0;
while (i_131_ < model_Pt3.numTriangles) {
textureCoords[i_23_] = (model_Pt3.textureCoords != null ? model_Pt3.textureCoords[i_131_] : (short) -1);
if (textureCoords[i_23_] > -1 && textureCoords[i_23_] < 32766) {
textureCoords[i_23_] = (short) (textureCoords[i_23_] + numTextureTriangles);
}
i_131_++;
i_23_++;
}
}
/*
* RS3 END
*/
} else {
for (int i_27_ = 0; i_27_ < model_Pt3.numTriangles; i_27_++) {
if (bool_7_) {
textureCoords[i_23_++] = (short) ((model_Pt3.textureCoords != null && (model_Pt3.textureCoords[i_27_] != -1)) ? (model_Pt3.textureCoords[i_27_] + numTextureTriangles) : -1);
}
}
}
for (int i_28_ = 0; i_28_ < model_Pt3.numTextureTriangles; i_28_++) {
byte i_29_ = (textureRenderTypes[numTextureTriangles] = model_Pt3.textureRenderTypes[i_28_]);
if (i_29_ == 0) {
textureTriangleX[numTextureTriangles] = (short) method1186(model_Pt3, (model_Pt3.textureTriangleX[i_28_]), i_25_);
textureTriangleY[numTextureTriangles] = (short) method1186(model_Pt3, (model_Pt3.textureTriangleY[i_28_]), i_25_);
textureTriangleZ[numTextureTriangles] = (short) method1186(model_Pt3, (model_Pt3.textureTriangleZ[i_28_]), i_25_);
}
if (i_29_ >= 1 && i_29_ <= 3) {
textureTriangleX[numTextureTriangles] = model_Pt3.textureTriangleX[i_28_];
textureTriangleY[numTextureTriangles] = model_Pt3.textureTriangleY[i_28_];
textureTriangleZ[numTextureTriangles] = model_Pt3.textureTriangleZ[i_28_];
particleDirectionX[numTextureTriangles] = model_Pt3.particleDirectionX[i_28_];
particleDirectionY[numTextureTriangles] = model_Pt3.particleDirectionY[i_28_];
particleDirectionZ[numTextureTriangles] = model_Pt3.particleDirectionZ[i_28_];
particleLifespanX[numTextureTriangles] = model_Pt3.particleLifespanX[i_28_];
particleLifespanY[numTextureTriangles] = model_Pt3.particleLifespanY[i_28_];
particleLifespanZ[numTextureTriangles] = model_Pt3.particleLifespanZ[i_28_];
}
if (i_29_ == 2) {
texturePrimaryColor[numTextureTriangles] = model_Pt3.texturePrimaryColor[i_28_];
textureSecondaryColor[numTextureTriangles] = model_Pt3.textureSecondaryColor[i_28_];
}
numTextureTriangles++;
}
}
}
}
private int method1186(Model model, int index, short i_31_) {
int i_32_ = model.vertexX[index];
int i_33_ = model.vertexY[index];
int i_34_ = model.vertexZ[index];
for (int i_35_ = 0; i_35_ < numVertices; i_35_++) {
if (i_32_ == vertexX[i_35_] && i_33_ == vertexY[i_35_] && i_34_ == vertexZ[i_35_]) {
aShortArray879[i_35_] |= i_31_;
return i_35_;
}
}
vertexX[numVertices] = i_32_;
vertexY[numVertices] = i_33_;
vertexZ[numVertices] = i_34_;
aShortArray879[numVertices] = i_31_;
vertexSkins[numVertices] = (model.vertexSkins != null ? model.vertexSkins[index] : -1);
return numVertices++;
}
private void calculateMaxDepth(InputStream inputStream, InputStream inputStream2) {
short i = 0;
short i_37_ = 0;
short i_38_ = 0;
int i_39_ = 0;
for (int i_40_ = 0; i_40_ < numTriangles; i_40_++) {
int i_41_ = inputStream2.readUByte();
int reali_41_ = i_41_ & 0x7;
if (reali_41_ == 1) {
i = (short) (inputStream.method3645() + i_39_);
i_39_ = i;
i_37_ = (short) (inputStream.method3645() + i_39_);
i_39_ = i_37_;
i_38_ = (short) (inputStream.method3645() + i_39_);
i_39_ = i_38_;
triangleViewspaceX[i_40_] = i;
triangleViewspaceY[i_40_] = i_37_;
triangleViewspaceZ[i_40_] = i_38_;
if (i > maxDepth) {
maxDepth = i;
}
if (i_37_ > maxDepth) {
maxDepth = i_37_;
}
if (i_38_ > maxDepth) {
maxDepth = i_38_;
}
}
if (reali_41_ == 2) {
i_37_ = i_38_;
i_38_ = (short) (inputStream.method3645() + i_39_);
i_39_ = i_38_;
triangleViewspaceX[i_40_] = i;
triangleViewspaceY[i_40_] = i_37_;
triangleViewspaceZ[i_40_] = i_38_;
if (i_38_ > maxDepth) {
maxDepth = i_38_;
}
}
if (reali_41_ == 3) {
i = i_38_;
i_38_ = (short) (inputStream.method3645() + i_39_);
i_39_ = i_38_;
triangleViewspaceX[i_40_] = i;
triangleViewspaceY[i_40_] = i_37_;
triangleViewspaceZ[i_40_] = i_38_;
if (i_38_ > maxDepth) {
maxDepth = i_38_;
}
}
if (reali_41_ == 4) {
short i_42_ = i;
i = i_37_;
i_37_ = i_42_;
i_38_ = (short) (inputStream.method3645() + i_39_);
i_39_ = i_38_;
triangleViewspaceX[i_40_] = i;
triangleViewspaceY[i_40_] = i_37_;
triangleViewspaceZ[i_40_] = i_38_;
if (i_38_ > maxDepth) {
maxDepth = i_38_;
}
}
}
maxDepth++;
}
private void calculateMaxDepth(InputStream inputStream, InputStream inputStream2, InputStream inputStream3) {
short i = 0;
short i_290_ = 0;
short i_291_ = 0;
int i_292_ = 0;
for (int i_293_ = 0; i_293_ < numTriangles; i_293_++) {
int i_294_ = inputStream2.readUByte();
int i_295_ = i_294_ & 0x7;
if (i_295_ == 1) {
triangleViewspaceX[i_293_] = i = (short) (inputStream.method3645() + i_292_);
i_292_ = i;
triangleViewspaceY[i_293_] = i_290_ = (short) (inputStream.method3645() + i_292_);
i_292_ = i_290_;
triangleViewspaceZ[i_293_] = i_291_ = (short) (inputStream.method3645() + i_292_);
i_292_ = i_291_;
if (i > maxDepth) {
maxDepth = i;
}
if (i_290_ > maxDepth) {
maxDepth = i_290_;
}
if (i_291_ > maxDepth) {
maxDepth = i_291_;
}
}
if (i_295_ == 2) {
i_290_ = i_291_;
i_291_ = (short) (inputStream.method3645() + i_292_);
i_292_ = i_291_;
triangleViewspaceX[i_293_] = i;
triangleViewspaceY[i_293_] = i_290_;
triangleViewspaceZ[i_293_] = i_291_;
if (i_291_ > maxDepth) {
maxDepth = i_291_;
}
}
if (i_295_ == 3) {
i = i_291_;
i_291_ = (short) (inputStream.method3645() + i_292_);
i_292_ = i_291_;
triangleViewspaceX[i_293_] = i;
triangleViewspaceY[i_293_] = i_290_;
triangleViewspaceZ[i_293_] = i_291_;
if (i_291_ > maxDepth) {
maxDepth = i_291_;
}
}
if (i_295_ == 4) {
short i_296_ = i;
i = i_290_;
i_290_ = i_296_;
i_291_ = (short) (inputStream.method3645() + i_292_);
i_292_ = i_291_;
triangleViewspaceX[i_293_] = i;
triangleViewspaceY[i_293_] = i_290_;
triangleViewspaceZ[i_293_] = i_291_;
if (i_291_ > maxDepth) {
maxDepth = i_291_;
}
}
if (numUVCoords > 0 && (i_294_ & 0x8) != 0) {
uvCoordVertexA[i_293_] = (byte) (inputStream3.readUByte());
uvCoordVertexB[i_293_] = (byte) (inputStream3.readUByte());
uvCoordVertexC[i_293_] = (byte) (inputStream3.readUByte());
}
}
maxDepth++;
}
private void decodeTexturedTriangles(InputStream inputStream, InputStream inputStream2, InputStream inputStream3,
InputStream inputStream4, InputStream inputStream5, InputStream inputStream6) {
for (int i = 0; i < numTextureTriangles; i++) {
int i_48_ = textureRenderTypes[i] & 0xff;
if (i_48_ == 0) {
textureTriangleX[i] = (short) inputStream.readUShort();
textureTriangleY[i] = (short) inputStream.readUShort();
textureTriangleZ[i] = (short) inputStream.readUShort();
}
if (i_48_ == 1) {
textureTriangleX[i] = (short) inputStream2.readUShort();
textureTriangleY[i] = (short) inputStream2.readUShort();
textureTriangleZ[i] = (short) inputStream2.readUShort();
if (version < 15) {
particleDirectionX[i] = inputStream3.readUShort();
if (version < 14) {
particleDirectionY[i] = inputStream3.readUShort();
}
else {
particleDirectionY[i] = inputStream3.read24BitInt();
}
particleDirectionZ[i] = inputStream3.readUShort();
} else {
particleDirectionX[i] = inputStream3.read24BitInt();
particleDirectionY[i] = inputStream3.read24BitInt();
particleDirectionZ[i] = inputStream3.read24BitInt();
}
particleLifespanX[i] = inputStream4.readByte();
particleLifespanY[i] = inputStream5.readByte();
particleLifespanZ[i] = inputStream6.readByte();
}
if (i_48_ == 2) {
textureTriangleX[i] = (short) inputStream2.readUShort();
textureTriangleY[i] = (short) inputStream2.readUShort();
textureTriangleZ[i] = (short) inputStream2.readUShort();
if (version < 15) {
particleDirectionX[i] = inputStream3.readUShort();
if (version < 14) {
particleDirectionY[i] = inputStream3.readUShort();
} else {
particleDirectionY[i] = inputStream3.read24BitInt();
}
particleDirectionZ[i] = inputStream3.readUShort();
} else {
particleDirectionX[i] = inputStream3.read24BitInt();
particleDirectionY[i] = inputStream3.read24BitInt();
particleDirectionZ[i] = inputStream3.read24BitInt();
}
particleLifespanX[i] = inputStream4.readByte();
particleLifespanY[i] = inputStream5.readByte();
particleLifespanZ[i] = inputStream6.readByte();
texturePrimaryColor[i] = inputStream6.readByte();
textureSecondaryColor[i] = inputStream6.readByte();
}
if (i_48_ == 3) {
textureTriangleX[i] = (short) inputStream2.readUShort();
textureTriangleY[i] = (short) inputStream2.readUShort();
textureTriangleZ[i] = (short) inputStream2.readUShort();
if (version < 15) {
particleDirectionX[i] = inputStream3.readUShort();
if (version < 14) {
particleDirectionY[i] = inputStream3.readUShort();
} else {
particleDirectionY[i] = inputStream3.read24BitInt();
}
particleDirectionZ[i] = inputStream3.readUShort();
} else {
particleDirectionX[i] = inputStream3.read24BitInt();
particleDirectionY[i] = inputStream3.read24BitInt();
particleDirectionZ[i] = inputStream3.read24BitInt();
}
particleLifespanX[i] = inputStream4.readByte();
particleLifespanY[i] = inputStream5.readByte();
particleLifespanZ[i] = inputStream6.readByte();
}
}
}
public void resizeModel(int i) {
for (int i_140_ = 0; i_140_ < numVertices; i_140_++) {
vertexX[i_140_] <<= i;
vertexY[i_140_] <<= i;
vertexZ[i_140_] <<= i;
}
if (numTextureTriangles > 0 && particleDirectionX != null) {
for (int i_141_ = 0; i_141_ < particleDirectionX.length; i_141_++) {
particleDirectionX[i_141_] <<= i;
particleDirectionY[i_141_] <<= i;
if (textureRenderTypes.length > i_141_ && textureRenderTypes[i_141_] != 1) {
particleDirectionZ[i_141_] <<= i;
}
}
}
}
private void decodeOldModel(byte[] is) {
this.format = Format.OLD;
boolean bool = false;
boolean bool_106_ = false;
InputStream class330_sub46 = new InputStream(is);
InputStream class330_sub46_107_ = new InputStream(is);
InputStream class330_sub46_108_ = new InputStream(is);
InputStream class330_sub46_109_ = new InputStream(is);
InputStream class330_sub46_110_ = new InputStream(is);
class330_sub46.setOffset(is.length - 18);
numVertices = class330_sub46.readUShort();
numTriangles = class330_sub46.readUShort();
numTextureTriangles = class330_sub46.readUByte();
int i = class330_sub46.readUByte();
int i_111_ = class330_sub46.readUByte();
int i_112_ = class330_sub46.readUByte();
int i_113_ = class330_sub46.readUByte();
int i_114_ = class330_sub46.readUByte();
int i_115_ = class330_sub46.readUShort();
int i_116_ = class330_sub46.readUShort();
int i_117_ = class330_sub46.readUShort();
int i_118_ = class330_sub46.readUShort();
int i_119_ = 0;
int i_120_ = i_119_;
i_119_ += numVertices;
int i_121_ = i_119_;
i_119_ += numTriangles;
int i_122_ = i_119_;
if (i_111_ == 255) {
i_119_ += numTriangles;
}
int i_123_ = i_119_;
if (i_113_ == 1) {
i_119_ += numTriangles;
}
int i_124_ = i_119_;
if (i == 1) {
i_119_ += numTriangles;
}
int i_125_ = i_119_;
if (i_114_ == 1) {
i_119_ += numVertices;
}
int i_126_ = i_119_;
if (i_112_ == 1) {
i_119_ += numTriangles;
}
int i_127_ = i_119_;
i_119_ += i_118_;
int i_128_ = i_119_;
i_119_ += numTriangles * 2;
int i_129_ = i_119_;
i_119_ += numTextureTriangles * 6;
int i_130_ = i_119_;
i_119_ += i_115_;
int i_131_ = i_119_;
i_119_ += i_116_;
int i_132_ = i_119_;
i_119_ += i_117_;
vertexX = new int[numVertices];
vertexY = new int[numVertices];
vertexZ = new int[numVertices];
triangleViewspaceX = new short[numTriangles];
triangleViewspaceY = new short[numTriangles];
triangleViewspaceZ = new short[numTriangles];
if (numTextureTriangles > 0) {
textureRenderTypes = new byte[numTextureTriangles];
textureTriangleX = new short[numTextureTriangles];
textureTriangleY = new short[numTextureTriangles];
textureTriangleZ = new short[numTextureTriangles];
}
if (i_114_ == 1) {
vertexSkins = new int[numVertices];
}
if (i == 1) {
faceRenderType = new byte[numTriangles];
textureCoords = new short[numTriangles];
textureIds = new short[numTriangles];
}
if (i_111_ == 255) {
trianglePriorities = new byte[numTriangles];
} else {
priority = (byte) i_111_;
}
if (i_112_ == 1) {
faceAlpha = new byte[numTriangles];
}
if (i_113_ == 1) {
triangleSkinValues = new int[numTriangles];
}
faceColor = new short[numTriangles];
class330_sub46.setOffset(i_120_);
class330_sub46_107_.setOffset(i_130_);
class330_sub46_108_.setOffset(i_131_);
class330_sub46_109_.setOffset(i_132_);
class330_sub46_110_.setOffset(i_125_);
int i_133_ = 0;
int i_134_ = 0;
int i_135_ = 0;
for (int i_136_ = 0; i_136_ < numVertices; i_136_++) {
int i_137_ = class330_sub46.readUByte();
int i_138_ = 0;
if ((i_137_ & 0x1) != 0) {
i_138_ = class330_sub46_107_.method3645();
}
int i_139_ = 0;
if ((i_137_ & 0x2) != 0) {
i_139_ = class330_sub46_108_.method3645();
}
int i_140_ = 0;
if ((i_137_ & 0x4) != 0) {
i_140_ = class330_sub46_109_.method3645();
}
vertexX[i_136_] = i_133_ + i_138_;
vertexY[i_136_] = i_134_ + i_139_;
vertexZ[i_136_] = i_135_ + i_140_;
i_133_ = vertexX[i_136_];
i_134_ = vertexY[i_136_];
i_135_ = vertexZ[i_136_];
if (i_114_ == 1) {
vertexSkins[i_136_] = class330_sub46_110_.readUByte();
}
}
class330_sub46.setOffset(i_128_);
class330_sub46_107_.setOffset(i_124_);
class330_sub46_108_.setOffset(i_122_);
class330_sub46_109_.setOffset( i_126_);
class330_sub46_110_.setOffset(i_123_);
for (int i_141_ = 0; i_141_ < numTriangles; i_141_++) {
faceColor[i_141_] = (short) class330_sub46.readUShort();
if (i == 1) {
int i_142_ = class330_sub46_107_.readUByte();
if ((i_142_ & 0x1) == 1) {
faceRenderType[i_141_] = (byte) 1;
bool = true;
} else {
faceRenderType[i_141_] = (byte) 0;
}
if ((i_142_ & 0x2) == 2) {
textureCoords[i_141_] = (short) (i_142_ >> 2);
textureIds[i_141_] = faceColor[i_141_];
faceColor[i_141_] = (short) 127;
if (textureIds[i_141_] != -1) {
bool_106_ = true;
}
} else {
textureCoords[i_141_] = (short) -1;
textureIds[i_141_] = (short) -1;
}
}
if (i_111_ == 255) {
trianglePriorities[i_141_] = class330_sub46_108_.readByte();
}
if (i_112_ == 1) {
faceAlpha[i_141_] = class330_sub46_109_.readByte();
}
if (i_113_ == 1) {
triangleSkinValues[i_141_] = class330_sub46_110_.readUByte();
}
}
maxDepth = -1;
class330_sub46.setOffset(i_127_);
class330_sub46_107_.setOffset(i_121_);
short i_143_ = 0;
short i_144_ = 0;
short i_145_ = 0;
int i_146_ = 0;
for (int i_147_ = 0; i_147_ < numTriangles; i_147_++) {
int i_148_ = class330_sub46_107_.readUByte();
if (i_148_ == 1) {
i_143_ = (short) (class330_sub46.method3645() + i_146_);
i_146_ = i_143_;
i_144_ = (short) (class330_sub46.method3645() + i_146_);
i_146_ = i_144_;
i_145_ = (short) (class330_sub46.method3645() + i_146_);
i_146_ = i_145_;
triangleViewspaceX[i_147_] = i_143_;
triangleViewspaceY[i_147_] = i_144_;
triangleViewspaceZ[i_147_] = i_145_;
if (i_143_ > maxDepth) {
maxDepth = i_143_;
}
if (i_144_ > maxDepth) {
maxDepth = i_144_;
}
if (i_145_ > maxDepth) {
maxDepth = i_145_;
}
}
if (i_148_ == 2) {
i_144_ = i_145_;
i_145_ = (short) (class330_sub46.method3645() + i_146_);
i_146_ = i_145_;
triangleViewspaceX[i_147_] = i_143_;
triangleViewspaceY[i_147_] = i_144_;
triangleViewspaceZ[i_147_] = i_145_;
if (i_145_ > maxDepth) {
maxDepth = i_145_;
}
}
if (i_148_ == 3) {
i_143_ = i_145_;
i_145_ = (short) (class330_sub46.method3645() + i_146_);
i_146_ = i_145_;
triangleViewspaceX[i_147_] = i_143_;
triangleViewspaceY[i_147_] = i_144_;
triangleViewspaceZ[i_147_] = i_145_;
if (i_145_ > maxDepth) {
maxDepth = i_145_;
}
}
if (i_148_ == 4) {
short i_149_ = i_143_;
i_143_ = i_144_;
i_144_ = i_149_;
i_145_ = (short) (class330_sub46.method3645() + i_146_);
i_146_ = i_145_;
triangleViewspaceX[i_147_] = i_143_;
triangleViewspaceY[i_147_] = i_144_;
triangleViewspaceZ[i_147_] = i_145_;
if (i_145_ > maxDepth) {
maxDepth = i_145_;
}
}
}
maxDepth++;
class330_sub46.setOffset(i_129_);
for (int i_150_ = 0; i_150_ < numTextureTriangles; i_150_++) {
textureRenderTypes[i_150_] = (byte) 0;
textureTriangleX[i_150_] = (short) class330_sub46.readUShort();
textureTriangleY[i_150_] = (short) class330_sub46.readUShort();
textureTriangleZ[i_150_] = (short) class330_sub46.readUShort();
}
if (textureCoords != null) {
boolean bool_151_ = false;
for (int i_152_ = 0; i_152_ < numTriangles; i_152_++) {
int i_153_ = textureCoords[i_152_] & 0xff;
if (i_153_ != 255) {
if (((textureTriangleX[i_153_] & 0xffff) == triangleViewspaceX[i_152_]) && ((textureTriangleY[i_153_] & 0xffff) == triangleViewspaceY[i_152_]) && ((textureTriangleZ[i_153_] & 0xffff) == triangleViewspaceZ[i_152_])) {
textureCoords[i_152_] = (short) -1;
} else {
bool_151_ = true;
}
}
}
if (!bool_151_) {
textureCoords = null;
}
}
if (!bool_106_) {
textureIds = null;
}
if (!bool) {
faceRenderType = null;
}
}
private void decodeNewModel(byte[] is) {
this.format = Format.NEW;
InputStream class330_sub46 = new InputStream(is);
InputStream class330_sub46_156_ = new InputStream(is);
InputStream class330_sub46_157_ = new InputStream(is);
InputStream class330_sub46_158_ = new InputStream(is);
InputStream class330_sub46_159_ = new InputStream(is);
InputStream class330_sub46_160_ = new InputStream(is);
InputStream class330_sub46_161_ = new InputStream(is);
class330_sub46.setOffset(is.length - 23);
numVertices = class330_sub46.readUShort();
numTriangles = class330_sub46.readUShort();
numTextureTriangles = class330_sub46.readUByte();
int i = class330_sub46.readUByte();
boolean bool = (i & 0x1) == 1;
boolean bool_162_ = (i & 0x2) == 2;
boolean bool_163_ = (i & 0x4) == 4;
boolean bool_164_ = (i & 0x8) == 8;
boolean bool_165_ = (i & 0x10) == 16;
boolean bool_166_ = (i & 0x20) == 32;
boolean bool_167_ = (i & 0x40) == 64;
if (bool_164_) {
//class330_sub46.offset -= -2029760457;
//version = class330_sub46.readUnsignedByte();
//class330_sub46.offset += 1941605862;
class330_sub46.back(7);
version = class330_sub46.readUByte();
class330_sub46.skip(6);
}
int i_168_ = class330_sub46.readUByte();
int i_169_ = class330_sub46.readUByte();
int i_170_ = class330_sub46.readUByte();
int i_171_ = class330_sub46.readUByte();
int i_172_ = class330_sub46.readUByte();
int i_173_ = class330_sub46.readUShort();
int i_174_ = class330_sub46.readUShort();
int i_175_ = class330_sub46.readUShort();
int i_176_ = class330_sub46.readUShort();
int i_177_ = class330_sub46.readUShort();
int i_178_;
if (bool_165_) {
i_178_ = class330_sub46.readUShort();
} else if (i_172_ == 1) {
i_178_ = numVertices;
} else {
i_178_ = 0;
}
int i_179_;
if (bool_166_) {
i_179_ = class330_sub46.readUShort();
} else if (i_170_ == 1) {
i_179_ = numTriangles;
} else {
i_179_ = 0;
}
int i_180_ = 0;
int i_181_ = 0;
int i_182_ = 0;
if (numTextureTriangles > 0) {
textureRenderTypes = new byte[numTextureTriangles];
class330_sub46.setOffset(0);
for (int i_183_ = 0; i_183_ < numTextureTriangles; i_183_++) {
byte i_184_ = (textureRenderTypes[i_183_] = class330_sub46.readByte());
if (i_184_ == 0) {
i_180_++;
}
if (i_184_ >= 1 && i_184_ <= 3) {
i_181_++;
}
if (i_184_ == 2) {
i_182_++;
}
}
}
int i_185_ = numTextureTriangles;
int i_186_ = i_185_;
i_185_ += numVertices;
int i_187_ = i_185_;
if (bool) {
i_185_ += numTriangles;
}
int i_188_ = i_185_;
i_185_ += numTriangles;
int i_189_ = i_185_;
if (i_168_ == 255) {
i_185_ += numTriangles;
}
int i_190_ = i_185_;
i_185_ += i_179_;
int i_191_ = i_185_;
i_185_ += i_178_;
int i_192_ = i_185_;
if (i_169_ == 1) {
i_185_ += numTriangles;
}
int i_193_ = i_185_;
i_185_ += i_176_;
int i_194_ = i_185_;
if (i_171_ == 1) {
i_185_ += numTriangles * 2;
}
int i_195_ = i_185_;
i_185_ += i_177_;
int i_196_ = i_185_;
i_185_ += numTriangles * 2;
int i_197_ = i_185_;
i_185_ += i_173_;
int i_198_ = i_185_;
i_185_ += i_174_;
int i_199_ = i_185_;
i_185_ += i_175_;
int i_200_ = i_185_;
i_185_ += i_180_ * 6;
int i_201_ = i_185_;
i_185_ += i_181_ * 6;
int i_202_ = 6;
if (version == 14) {
i_202_ = 7;
} else if (version >= 15) {
i_202_ = 9;
}
int i_203_ = i_185_;
i_185_ += i_181_ * i_202_;
int i_204_ = i_185_;
i_185_ += i_181_;
int i_205_ = i_185_;
i_185_ += i_181_;
int i_206_ = i_185_;
i_185_ += i_181_ + i_182_ * 2;
int i_207_ = i_185_;
vertexX = new int[numVertices];
vertexY = new int[numVertices];
vertexZ = new int[numVertices];
triangleViewspaceX = new short[numTriangles];
triangleViewspaceY = new short[numTriangles];
triangleViewspaceZ = new short[numTriangles];
if (i_172_ == 1) {
vertexSkins = new int[numVertices];
}
if (bool) {
faceRenderType = new byte[numTriangles];
}
if (i_168_ == 255) {
trianglePriorities = new byte[numTriangles];
} else {
priority = (byte) i_168_;
}
if (i_169_ == 1) {
faceAlpha = new byte[numTriangles];
}
if (i_170_ == 1) {
triangleSkinValues = new int[numTriangles];
}
if (i_171_ == 1) {
textureIds = new short[numTriangles];
}
if (i_171_ == 1 && numTextureTriangles > 0) {
textureCoords = new short[numTriangles];
}
faceColor = new short[numTriangles];
if (numTextureTriangles > 0) {
textureTriangleX = new short[numTextureTriangles];
textureTriangleY = new short[numTextureTriangles];
textureTriangleZ = new short[numTextureTriangles];
if (i_181_ > 0) {
particleDirectionX = new int[i_181_];
particleDirectionY = new int[i_181_];
particleDirectionZ = new int[i_181_];
particleLifespanX = new byte[i_181_];
particleLifespanY = new byte[i_181_];
particleLifespanZ = new int[i_181_];
}
if (i_182_ > 0) {
texturePrimaryColor = new int[i_182_];
textureSecondaryColor = new int[i_182_];
}
}
class330_sub46.setOffset(i_186_);
class330_sub46_156_.setOffset(i_197_);
class330_sub46_157_.setOffset(i_198_);
class330_sub46_158_.setOffset(i_199_);
class330_sub46_159_.setOffset(i_191_);
int i_208_ = 0;
int i_209_ = 0;
int i_210_ = 0;
for (int i_211_ = 0; i_211_ < numVertices; i_211_++) {
int i_212_ = class330_sub46.readUByte();
int i_213_ = 0;
if ((i_212_ & 0x1) != 0) {
i_213_ = class330_sub46_156_.method3645();
}
int i_214_ = 0;
if ((i_212_ & 0x2) != 0) {
i_214_ = class330_sub46_157_.method3645();
}
int i_215_ = 0;
if ((i_212_ & 0x4) != 0) {
i_215_ = class330_sub46_158_.method3645();
}
vertexX[i_211_] = i_208_ + i_213_;
vertexY[i_211_] = i_209_ + i_214_;
vertexZ[i_211_] = i_210_ + i_215_;
i_208_ = vertexX[i_211_];
i_209_ = vertexY[i_211_];
i_210_ = vertexZ[i_211_];
if (i_172_ == 1) {
if (bool_165_) {
vertexSkins[i_211_] = class330_sub46_159_.method3766();
} else {
vertexSkins[i_211_] = class330_sub46_159_.readUByte();
if (vertexSkins[i_211_] == 255) {
vertexSkins[i_211_] = -1;
}
}
}
}
class330_sub46.setOffset(i_196_);
class330_sub46_156_.setOffset(i_187_);
class330_sub46_157_.setOffset(i_189_);
class330_sub46_158_.setOffset(i_192_);
class330_sub46_159_.setOffset(i_190_);
class330_sub46_160_.setOffset(i_194_);
class330_sub46_161_.setOffset(i_195_);
for (int i_216_ = 0; i_216_ < numTriangles; i_216_++) {
faceColor[i_216_] = (short) class330_sub46.readUShort();
if (bool) {
faceRenderType[i_216_] = class330_sub46_156_.readByte();
}
if (i_168_ == 255) {
trianglePriorities[i_216_] = class330_sub46_157_.readByte();
}
if (i_169_ == 1) {
faceAlpha[i_216_] = class330_sub46_158_.readByte();
}
if (i_170_ == 1) {
if (bool_166_) {
triangleSkinValues[i_216_] = class330_sub46_159_.method3766();
} else {
triangleSkinValues[i_216_] = class330_sub46_159_.readUByte();
if (triangleSkinValues[i_216_] == 255) {
triangleSkinValues[i_216_] = -1;
}
}
}
if (i_171_ == 1) {
textureIds[i_216_] = (short) (class330_sub46_160_.readUShort() - 1);
}
if (textureCoords != null) {
if (textureIds[i_216_] != -1) {
textureCoords[i_216_] = (short) (class330_sub46_161_.readUByte() - 1);
} else {
textureCoords[i_216_] = (short) -1;
}
}
}
maxDepth = -1;
class330_sub46.setOffset(i_193_);
class330_sub46_156_.setOffset(i_188_);
calculateMaxDepth(class330_sub46, class330_sub46_156_);
class330_sub46.setOffset(i_200_);
class330_sub46_156_.setOffset(i_201_);
class330_sub46_157_.setOffset(i_203_);
class330_sub46_158_.setOffset(i_204_);
class330_sub46_159_.setOffset(i_205_);
class330_sub46_160_.setOffset(i_206_);
decodeTexturedTriangles(class330_sub46, class330_sub46_156_, class330_sub46_157_, class330_sub46_158_, class330_sub46_159_, class330_sub46_160_);
class330_sub46.setOffset(i_207_);
if (bool_162_) {
int i_217_ = class330_sub46.readUByte();
if (i_217_ > 0) {
particles = new Particle[i_217_];
for (int i_218_ = 0; i_218_ < i_217_; i_218_++) {
int i_219_ = class330_sub46.readUShort();
int i_220_ = class330_sub46.readUShort();
byte i_221_;
if (i_168_ == 255) {
i_221_ = trianglePriorities[i_220_];
} else {
i_221_ = (byte) i_168_;
}
particles[i_218_] = new Particle(i_219_, triangleViewspaceX[i_220_], triangleViewspaceY[i_220_], triangleViewspaceZ[i_220_], i_221_);
}
}
int i_222_ = class330_sub46.readUByte();
if (i_222_ > 0) {
surfaceSkins = new SurfaceSkin[i_222_];
for (int i_223_ = 0; i_223_ < i_222_; i_223_++) {
int i_224_ = class330_sub46.readUShort();
int i_225_ = class330_sub46.readUShort();
surfaceSkins[i_223_] = new SurfaceSkin(i_224_, i_225_);
}
}
}
if (bool_163_) {
int i_226_ = class330_sub46.readUByte();
if (i_226_ > 0) {
isolatedVertexNormals = new VertexNormal[i_226_];
for (int i_227_ = 0; i_227_ < i_226_; i_227_++) {
int i_228_ = class330_sub46.readUShort();
int i_229_ = class330_sub46.readUShort();
int i_230_;
if (bool_167_) {
i_230_ = class330_sub46.method3766();
} else {
i_230_ = class330_sub46.readUByte();
if (i_230_ == 255) {
i_230_ = -1;
}
}
byte i_231_ = class330_sub46.readByte();
isolatedVertexNormals[i_227_] = new VertexNormal(i_228_, i_229_, i_230_, i_231_);
}
}
}
}
private void decodeEOCModel(byte[] is) {
this.format = Format.EOC;
numTriangles = 0;
priority = (byte) 0;
numTextureTriangles = 0;
InputStream[] buffers = new InputStream[7];
for (int i = 0; i < buffers.length; i++) {
buffers[i] = new InputStream(is);
}
/**
* Before 789 there were two types of models, old format and new format
* On 768 they updated both formats to have a number at the beginning to
* identify them 0 for old; 1 for new On 789 they removed old format
* models and reformatted every model to follow this format
*/
int identifier = buffers[0].readUByte();
if (identifier != 1) {
Logger.error("Invalid identifier #" + identifier);
} else {
buffers[0].readUByte();
version = buffers[0].readUByte();
buffers[0].setOffset(is.length - 26);
numVertices = buffers[0].readUShort();
numTriangles = buffers[0].readUShort();
numTextureTriangles = buffers[0].readUShort();
int footerFlags = buffers[0].readUByte();
boolean hasFillAttributes = (footerFlags & 0x1) == 1;
boolean hasSurfaceEffects = (footerFlags & 0x2) == 2;
boolean hasVertexNormals = (footerFlags & 0x4) == 4;
boolean hasManyVertices = (footerFlags & 0x10) == 16;
boolean hasManyTriangles = (footerFlags & 0x20) == 32;
boolean hasManyVertexNormals = (footerFlags & 0x40) == 64;
boolean hasUVCoordinates = (footerFlags & 0x80) == 128;
int modelPriority = buffers[0].readUByte();
int modelAlpha = buffers[0].readUByte();
int modelTriangleSkinValue = buffers[0].readUByte();
int modelTexture = buffers[0].readUByte();
int modelVertexSkins = buffers[0].readUByte();
int modelVerticesX = buffers[0].readUShort();
int modelVerticesY = buffers[0].readUShort();
int modelVerticesZ = buffers[0].readUShort();
int modelVertexPoint = buffers[0].readUShort();
int modelTextureCoords = buffers[0].readUShort();
int vertices = buffers[0].readUShort();
int triangles = buffers[0].readUShort();
if (!hasManyVertices) {
if (modelVertexSkins == 1) {
vertices = numVertices;
} else {
vertices = 0;
}
}
if (!hasManyTriangles) {
if (modelTriangleSkinValue == 1) {
triangles = numTriangles;
} else {
triangles = 0;
}
}
int textureAmount = 0;
int particleAmount = 0;
int particleColor = 0;
if (numTextureTriangles > 0) {
textureRenderTypes = new byte[numTextureTriangles];
buffers[0].setOffset(3);
for (int tri = 0; tri < numTextureTriangles; tri++) {
byte renderType = textureRenderTypes[tri] = buffers[0].readByte();
if (renderType == 0) {
textureAmount++;
}
if (renderType >= 1 && renderType <= 3) {
particleAmount++;
}
if (renderType == 2) {
particleColor++;
}
}
}
int pos = 3 + numTextureTriangles;
int vertexFlagsPos = pos;
pos += numVertices;
int renderTypePos = pos;
if (hasFillAttributes) {
pos += numTriangles;
}
int depthTriTypeOffset = pos;
pos += numTriangles;
int priorityPos = pos;
if (modelPriority == 255) {
pos += numTriangles;
}
int triangleSkinPos = pos;
pos += triangles;
int vertexSkinsPos = pos;
pos += vertices;
int alphaPos = pos;
if (modelAlpha == 1) {
pos += numTriangles;
}
int depthTriViewspaceOffset = pos;
pos += modelVertexPoint;
int texturePos = pos;
if (modelTexture == 1) {
pos += numTriangles * 2;
}
int textureCoordPos = pos;
pos += modelTextureCoords;
int colorPos = pos;
pos += numTriangles * 2;
int vertexXOffsetPos = pos;
pos += modelVerticesX;
int vertexYOffsetPos = pos;
pos += modelVerticesY;
int vertexZOffsetPos = pos;
pos += modelVerticesZ;
int texturedTriangleType0Offset = pos;
pos += textureAmount * 6;
int texturedTriangleOffset = pos;
pos += particleAmount * 6;
int particleVersion = 6;
if (version == 14) {
particleVersion = 7;
} else if (version >= 15) {
particleVersion = 9;
}
int particleDirectionOffset = pos;
pos += particleAmount * particleVersion;
int particleXLifespanOffset = pos;
pos += particleAmount;
int particleYLifespanOffset = pos;
pos += particleAmount;
int particleZLifespanAndTextureColorOffset = pos;
pos += particleAmount + particleColor * 2;
int surfaceEffectsOffset = pos;
int uvCoordPos = is.length;
int uvCoordModPos2 = is.length;
int texCoordUPos = is.length;
int texCoordVPos = is.length;
if (hasUVCoordinates) {
InputStream uvBuffer = new InputStream(is);
uvBuffer.setOffset(is.length - 26);
uvBuffer.back(is[uvBuffer.getOffset() - 1]);
numUVCoords = uvBuffer.readUShort();
int unknown1 = uvBuffer.readUShort();
int unknown2 = uvBuffer.readUShort();
uvCoordPos = surfaceEffectsOffset + unknown1;
uvCoordModPos2 = uvCoordPos + unknown2;
texCoordUPos = uvCoordModPos2 + numVertices;
texCoordVPos = texCoordUPos + numUVCoords * 2;
}
vertexX = new int[numVertices];
vertexY = new int[numVertices];
vertexZ = new int[numVertices];
triangleViewspaceX = new short[numTriangles];
triangleViewspaceY = new short[numTriangles];
triangleViewspaceZ = new short[numTriangles];
if (modelVertexSkins == 1) {
vertexSkins = new int[numVertices];
}
if (hasFillAttributes) {
faceRenderType = new byte[numTriangles];
}
if (modelPriority == 255) {
trianglePriorities = new byte[numTriangles];
} else {
priority = (byte) modelPriority;
}
if (modelAlpha == 1) {
faceAlpha = new byte[numTriangles];
}
if (modelTriangleSkinValue == 1) {
triangleSkinValues = new int[numTriangles];
}
if (modelTexture == 1) {
textureIds = new short[numTriangles];
}
if (modelTexture == 1 && (numTextureTriangles > 0 || numUVCoords > 0)) {
textureCoords = new short[numTriangles];
}
faceColor = new short[numTriangles];
if (numTextureTriangles > 0) {
textureTriangleX = new short[numTextureTriangles];
textureTriangleY = new short[numTextureTriangles];
textureTriangleZ = new short[numTextureTriangles];
if (particleAmount > 0) {
particleDirectionX = new int[particleAmount];
particleDirectionY = new int[particleAmount];
particleDirectionZ = new int[particleAmount];
particleLifespanX = new byte[particleAmount];
particleLifespanY = new byte[particleAmount];
particleLifespanZ = new int[particleAmount];
}
if (particleColor > 0) {
texturePrimaryColor = new int[particleColor];
textureSecondaryColor = new int[particleColor];
}
}
buffers[0].setOffset(vertexFlagsPos);
buffers[1].setOffset(vertexXOffsetPos);
buffers[2].setOffset(vertexYOffsetPos);
buffers[3].setOffset(vertexZOffsetPos);
buffers[4].setOffset(vertexSkinsPos);
int vX = 0;
int vY = 0;
int vZ = 0;
for (int point = 0; point < numVertices; point++) {
int vertexFlags = buffers[0].readUByte();
int vertexXOffset = 0;
if ((vertexFlags & 0x1) != 0) {
vertexXOffset = buffers[1].method3645();
}
int vertexYOffset = 0;
if ((vertexFlags & 0x2) != 0) {
vertexYOffset = buffers[2].method3645();
}
int vertexZOffset = 0;
if ((vertexFlags & 0x4) != 0) {
vertexZOffset = buffers[3].method3645();
}
vertexX[point] = vX + vertexXOffset;
vertexY[point] = vY + vertexYOffset;
vertexZ[point] = vZ + vertexZOffset;
vX = vertexX[point];
vY = vertexY[point];
vZ = vertexZ[point];
if (modelVertexSkins == 1) {
if (hasManyVertices) {
vertexSkins[point] = buffers[4].method3766();
}
else {
vertexSkins[point] = buffers[4].readUByte();
if (vertexSkins[point] == 255) {
vertexSkins[point] = -1;
}
}
}
}
if (numUVCoords > 0) {
buffers[0].setOffset(uvCoordModPos2);
buffers[1].setOffset(texCoordUPos);
buffers[2].setOffset(texCoordVPos);
anIntArray1669 = new int[numVertices];
int coord = 0;
int size = 0;
for (; coord < numVertices; coord++) {
anIntArray1669[coord] = size;
size += buffers[0].readUByte();
}
uvCoordVertexA = new byte[numTriangles];
uvCoordVertexB = new byte[numTriangles];
uvCoordVertexC = new byte[numTriangles];
textureCoordU = new float[numUVCoords];
textureCoordV = new float[numUVCoords];
for (coord = 0; coord < numUVCoords; coord++) {
textureCoordU[coord] = (buffers[1].readShort() / 4096.0F);
textureCoordV[coord] = (buffers[2].readShort() / 4096.0F);
}
}
/*
* for (int tri = 0; tri < numTriangles; tri++) { int unknownInt1 =
* buffers[0].readUnsignedByte(); int unknownInt2 = 0; if
* ((unknownInt1 & 0x1) != 0) unknownInt2 = buffers[3].method3645();
* int unknownInt3 = 0; if ((unknownInt1 & 0x2) != 0) unknownInt3 =
* buffers[4].method3645(); int unknownInt4 = 0; if ((unknownInt1 &
* 0x4) != 0) unknownInt4 = buffers[5].method3645(); vertexX[tri] =
* vX + unknownInt2; vertexY[tri] = vY + unknownInt3; vertexZ[tri] =
* vZ + unknownInt4; vX = vertexX[tri]; vY = vertexY[tri]; vZ =
* vertexZ[tri]; if (modelVertexSkins == 1) { if (hasManyVertices)
* textureCoords[tri] = buffers[6].method3766(); else {
* textureCoords[tri] = buffers[6].readUnsignedByte(); if
* (textureCoords[tri] == 255) textureCoords[tri] = -1; } } }
*/
buffers[0].setOffset(colorPos);
buffers[1].setOffset(renderTypePos);
buffers[2].setOffset(priorityPos);
buffers[3].setOffset(alphaPos);
buffers[4].setOffset(triangleSkinPos);
buffers[5].setOffset(texturePos);
buffers[6].setOffset(textureCoordPos);
for (int tri = 0; tri < numTriangles; tri++) {
faceColor[tri] = (short) (buffers[0].readUShort());
if (hasFillAttributes) {
faceRenderType[tri] = buffers[1].readByte();
}
if (modelPriority == 255) {
trianglePriorities[tri] = buffers[2].readByte();
}
if (modelAlpha == 1) {
faceAlpha[tri] = buffers[3].readByte();
}
if (modelTriangleSkinValue == 1) {
if (hasManyTriangles) {
triangleSkinValues[tri] = buffers[4].method3766();
} else {
triangleSkinValues[tri] = buffers[4].readUByte();
if (triangleSkinValues[tri] == 255) {
triangleSkinValues[tri] = -1;
}
}
}
if (modelTexture == 1) {
textureIds[tri] = (short) ((buffers[5].readUShort()) - 1);
}
if (textureCoords != null) {// texturedecoder
if (textureIds[tri] != -1) {
if (version >= 16) {
textureCoords[tri] = (short) (buffers[6].readSmart() - 1);
} else {
textureCoords[tri] = (short) ((buffers[6].readUByte()) - 1);
}
} else {
textureCoords[tri] = (short) -1;
}
}
}
maxDepth = -1;
buffers[0].setOffset(depthTriViewspaceOffset);
buffers[1].setOffset(depthTriTypeOffset);
buffers[2].setOffset(uvCoordPos);
calculateMaxDepth(buffers[0], buffers[1], buffers[2]);
buffers[0].setOffset(texturedTriangleType0Offset);
buffers[1].setOffset(texturedTriangleOffset);
buffers[2].setOffset(particleDirectionOffset);
buffers[3].setOffset(particleXLifespanOffset);
buffers[4].setOffset(particleYLifespanOffset);
buffers[5].setOffset(particleZLifespanAndTextureColorOffset);
decodeTexturedTriangles(buffers[0], buffers[1], buffers[2], buffers[3], buffers[4], buffers[5]); // NEW DECODER
buffers[0].setOffset(surfaceEffectsOffset);
if (hasSurfaceEffects) {
int numFaces = buffers[0].readUByte();
if (numFaces > 0) {
particles = new Particle[numFaces];
for (int face = 0; face < numFaces; face++) {
int faceId = buffers[0].readUShort();
int point = buffers[0].readUShort();
byte pri;
if (modelPriority == 255) {
pri = trianglePriorities[point];
} else {
pri = (byte) modelPriority;
}
particles[face] = new Particle(faceId, triangleViewspaceX[point], triangleViewspaceY[point], triangleViewspaceZ[point], pri);
}
}
int numSkins = buffers[0].readUByte();
if (numSkins > 0) {
surfaceSkins = new SurfaceSkin[numSkins];
for (int face = 0; face < numSkins; face++) {
int skin = buffers[0].readUShort();
int point = buffers[0].readUShort();
surfaceSkins[face] = new SurfaceSkin(skin, point);
}
}
}
if (hasVertexNormals) {
int numVertexNormals = buffers[0].readUByte();
if (numVertexNormals > 0) {
isolatedVertexNormals = new VertexNormal[numVertexNormals];
for (int vertex = 0; vertex < numVertexNormals; vertex++) {
int x = buffers[0].readUShort();
int y = buffers[0].readUShort();
int z;
if (hasManyVertexNormals) {
z = buffers[0].method3766();
} else {
z = buffers[0].readUByte();
if (z == 255) {
z = -1;
}
}
byte divisor = buffers[0].readByte();
isolatedVertexNormals[vertex] = new VertexNormal(x, y, z, divisor);
}
}
}
}
}
public void computeNormals() {
if (vertexNormals != null) {
return;
}
/*if (isolatedVertexNormals != null && isolatedVertexNormals.length >= numTriangles) {
return;
}*/
//System.out.println("computing normals...");
vertexNormals = new VertexNormal[numTriangles]; // numVertices];
int var1;
for (var1 = 0; var1 < numTriangles; ++var1) { // numVertices; ++var1)
vertexNormals[var1] = new VertexNormal();
}
for (var1 = 0; var1 < numTriangles; ++var1) {
int vertexA = triangleViewspaceX[var1];
int vertexB = triangleViewspaceY[var1];
int vertexC = triangleViewspaceZ[var1];
int xA = vertexX[vertexB] - vertexX[vertexA];
int yA = vertexY[vertexB] - vertexY[vertexA];
int zA = vertexZ[vertexB] - vertexZ[vertexA];
int xB = vertexX[vertexC] - vertexX[vertexA];
int yB = vertexY[vertexC] - vertexY[vertexA];
int zB = vertexZ[vertexC] - 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 (faceRenderType == null) {
var15 = 0;
} else {
var15 = faceRenderType[var1];
}
if (var15 == 0) {
VertexNormal var16 = vertexNormals[vertexA];
var16.setX(var16.getX() + var11);
var16.setY(var16.getY() + var12);
var16.setZ(var16.getZ() + var13);
var16.setDivisor(var16.getDivisor() + 1);
var16 = vertexNormals[vertexB];
var16.setX(var16.getX() + var11);
var16.setY(var16.getY() + var12);
var16.setZ(var16.getZ() + var13);
var16.setDivisor(var16.getDivisor() + 1);
var16 = vertexNormals[vertexC];
var16.setX(var16.getX() + var11);
var16.setY(var16.getY() + var12);
var16.setZ(var16.getZ() + var13);
var16.setDivisor(var16.getDivisor() + 1);
}
else if (var15 == 1) {
/*if (faceNormals == null)
{
faceNormals = new FaceNormal[faceCount];
}
FaceNormal var17 = faceNormals[var1] = new FaceNormal();
var17.x = var11;
var17.y = var12;
var17.z = var13;*/
}
}
}
private void method4492(int i, int i_277_, int i_278_, int i_279_, int i_280_, int i_281_, float[] fs, float f, int i_282_, float f_283_, float[] fs_284_) {
i -= i_279_;
i_277_ -= i_280_;
i_278_ -= i_281_;
float f_285_ = ((float) i * fs[0] + (float) i_277_ * fs[1] + (float) i_278_ * fs[2]);
float f_286_ = ((float) i * fs[3] + (float) i_277_ * fs[4] + (float) i_278_ * fs[5]);
float f_287_ = ((float) i * fs[6] + (float) i_277_ * fs[7] + (float) i_278_ * fs[8]);
float f_288_ = (((float) Math.atan2((double) f_285_, (double) f_287_) / 6.2831855F) + 0.5F);
if (f != 1.0F) {
f_288_ *= f;
}
float f_289_ = f_286_ + 0.5F + f_283_;
if (i_282_ == 1) {
float f_290_ = f_288_;
f_288_ = -f_289_;
f_289_ = f_290_;
} else if (i_282_ == 2) {
f_288_ = -f_288_;
f_289_ = -f_289_;
} else if (i_282_ == 3) {
float f_291_ = f_288_;
f_288_ = f_289_;
f_289_ = -f_291_;
}
fs_284_[0] = f_288_;
fs_284_[1] = f_289_;
}
private int method4442(float f, float f_15_, float f_16_) {
float f_17_ = f < 0.0F ? -f : f;
float f_18_ = f_15_ < 0.0F ? -f_15_ : f_15_;
float f_19_ = f_16_ < 0.0F ? -f_16_ : f_16_;
if (f_18_ > f_17_ && f_18_ > f_19_) {
if (f_15_ > 0.0F) {
return 0;
}
return 1;
}
if (f_19_ > f_17_ && f_19_ > f_18_) {
if (f_16_ > 0.0F) {
return 2;
}
return 3;
}
if (f > 0.0F) {
return 4;
}
return 5;
}
private void method4443(int i, int i_20_, int i_21_, int i_22_, int i_23_, int i_24_, int i_25_, float[] fs, int i_26_, float f, float f_27_, float f_28_, float[] fs_29_) {
i -= i_22_;
i_20_ -= i_23_;
i_21_ -= i_24_;
float f_30_ = ((float) i * fs[0] + (float) i_20_ * fs[1] + (float) i_21_ * fs[2]);
float f_31_ = ((float) i * fs[3] + (float) i_20_ * fs[4] + (float) i_21_ * fs[5]);
float f_32_ = ((float) i * fs[6] + (float) i_20_ * fs[7] + (float) i_21_ * fs[8]);
float f_33_;
float f_34_;
if (i_25_ == 0) {
f_33_ = f_30_ + f + 0.5F;
f_34_ = -f_32_ + f_28_ + 0.5F;
} else if (i_25_ == 1) {
f_33_ = f_30_ + f + 0.5F;
f_34_ = f_32_ + f_28_ + 0.5F;
} else if (i_25_ == 2) {
f_33_ = -f_30_ + f + 0.5F;
f_34_ = -f_31_ + f_27_ + 0.5F;
} else if (i_25_ == 3) {
f_33_ = f_30_ + f + 0.5F;
f_34_ = -f_31_ + f_27_ + 0.5F;
} else if (i_25_ == 4) {
f_33_ = f_32_ + f_28_ + 0.5F;
f_34_ = -f_31_ + f_27_ + 0.5F;
} else {
f_33_ = -f_32_ + f_28_ + 0.5F;
f_34_ = -f_31_ + f_27_ + 0.5F;
}
if (i_26_ == 1) {
float f_35_ = f_33_;
f_33_ = -f_34_;
f_34_ = f_35_;
} else if (i_26_ == 2) {
f_33_ = -f_33_;
f_34_ = -f_34_;
} else if (i_26_ == 3) {
float f_36_ = f_33_;
f_33_ = f_34_;
f_34_ = -f_36_;
}
fs_29_[0] = f_33_;
fs_29_[1] = f_34_;
}
private void method4441(int i, int i_0_, int i_1_, int i_2_, int i_3_, int i_4_, float[] fs, int i_5_, float f, float[] fs_6_) {
i -= i_2_;
i_0_ -= i_3_;
i_1_ -= i_4_;
float f_7_ = (float) i * fs[0] + (float) i_0_ * fs[1] + (float) i_1_ * fs[2];
float f_8_ = (float) i * fs[3] + (float) i_0_ * fs[4] + (float) i_1_ * fs[5];
float f_9_ = (float) i * fs[6] + (float) i_0_ * fs[7] + (float) i_1_ * fs[8];
float f_10_ = (float) Math.sqrt((double) (f_7_ * f_7_ + f_8_ * f_8_ + f_9_ * f_9_));
float f_11_ = ((float) Math.atan2((double) f_7_, (double) f_9_) / 6.2831855F + 0.5F);
float f_12_ = ((float) Math.asin((double) (f_8_ / f_10_)) / 3.1415927F + 0.5F + f);
if (i_5_ == 1) {
float f_13_ = f_11_;
f_11_ = -f_12_;
f_12_ = f_13_;
} else if (i_5_ == 2) {
f_11_ = -f_11_;
f_12_ = -f_12_;
} else if (i_5_ == 3) {
float f_14_ = f_11_;
f_11_ = f_12_;
f_12_ = -f_14_;
}
fs_6_[0] = f_11_;
fs_6_[1] = f_12_;
}
private Class97 method4444(Model class98, int i) {//, int[] is, int i) {
int[] is_37_ = null;
int[] is_38_ = null;
int[] is_39_ = null;
float[][] fs = null;
if (class98.textureCoords != null) {
int i_40_ = class98.numTextureTriangles;
int[] is_41_ = new int[i_40_];
int[] is_42_ = new int[i_40_];
int[] is_43_ = new int[i_40_];
int[] is_44_ = new int[i_40_];
int[] is_45_ = new int[i_40_];
int[] is_46_ = new int[i_40_];
for (int i_47_ = 0; i_47_ < i_40_; i_47_++) {
is_41_[i_47_] = 2147483647;
is_42_[i_47_] = -2147483647;
is_43_[i_47_] = 2147483647;
is_44_[i_47_] = -2147483647;
is_45_[i_47_] = 2147483647;
is_46_[i_47_] = -2147483647;
}
for (int i_48_ = 0; i_48_ < i; i_48_++) {
int i_49_ = i_48_;//is[i_48_];
if (class98.textureCoords[i_49_] > -1 && class98.textureCoords[i_49_] < 32766) {
int i_50_ = class98.textureCoords[i_49_] & 0xff;
for (int i_51_ = 0; i_51_ < 3; i_51_++) {
short i_52_;
if (i_51_ == 0) {
i_52_ = class98.triangleViewspaceX[i_49_];
} else if (i_51_ == 1) {
i_52_ = class98.triangleViewspaceY[i_49_];
} else {
i_52_ = class98.triangleViewspaceZ[i_49_];
}
int i_53_ = class98.vertexX[i_52_];
int i_54_ = class98.vertexY[i_52_];
int i_55_ = class98.vertexZ[i_52_];
if (i_53_ < is_41_[i_50_]) {
is_41_[i_50_] = i_53_;
}
if (i_53_ > is_42_[i_50_]) {
is_42_[i_50_] = i_53_;
}
if (i_54_ < is_43_[i_50_]) {
is_43_[i_50_] = i_54_;
}
if (i_54_ > is_44_[i_50_]) {
is_44_[i_50_] = i_54_;
}
if (i_55_ < is_45_[i_50_]) {
is_45_[i_50_] = i_55_;
}
if (i_55_ > is_46_[i_50_]) {
is_46_[i_50_] = i_55_;
}
}
}
}
is_37_ = new int[i_40_];
is_38_ = new int[i_40_];
is_39_ = new int[i_40_];
fs = new float[i_40_][];
for (int i_56_ = 0; i_56_ < i_40_; i_56_++) {
byte i_57_ = class98.textureRenderTypes[i_56_];
if (i_57_ > 0) {
is_37_[i_56_] = (is_41_[i_56_] + is_42_[i_56_]) / 2;
is_38_[i_56_] = (is_43_[i_56_] + is_44_[i_56_]) / 2;
is_39_[i_56_] = (is_45_[i_56_] + is_46_[i_56_]) / 2;
float f;
float f_58_;
float f_59_;
if (i_57_ == 1) {
int i_60_ = class98.particleDirectionX[i_56_];
if (i_60_ == 0) {
f = 1.0F;
f_59_ = 1.0F;
} else if (i_60_ > 0) {
f = 1.0F;
f_59_ = (float) i_60_ / 1024.0F;
} else {
f_59_ = 1.0F;
f = (float) -i_60_ / 1024.0F;
}
f_58_ = 64.0F / (float) class98.particleDirectionY[i_56_];
} else if (i_57_ == 2) {
f = 64.0F / (float) class98.particleDirectionX[i_56_];
f_58_ = 64.0F / (float) class98.particleDirectionY[i_56_];
f_59_ = 64.0F / (float) class98.particleDirectionZ[i_56_];
} else {
f = (float) class98.particleDirectionX[i_56_] / 1024.0F;
f_58_ = (float) class98.particleDirectionY[i_56_] / 1024.0F;
f_59_ = (float) class98.particleDirectionZ[i_56_] / 1024.0F;
}
fs[i_56_] = method4459(class98.textureTriangleX[i_56_], class98.textureTriangleY[i_56_], class98.textureTriangleZ[i_56_], class98.particleLifespanX[i_56_] & 0xff, f, f_58_, f_59_);
}
}
}
return new Class97(is_37_, is_38_, is_39_, fs);
}
private float[] method4459(int i, int i_188_, int i_189_, int i_190_, float f, float f_191_, float f_192_) {
float[] fs = new float[9];
float[] fs_193_ = new float[9];
float f_194_ = (float) Math.cos((double) ((float) i_190_ * 0.024543693F));
float f_195_ = (float) Math.sin((double) ((float) i_190_ * 0.024543693F));
float f_196_ = 1.0F - f_194_;
fs[0] = f_194_;
fs[1] = 0.0F;
fs[2] = f_195_;
fs[3] = 0.0F;
fs[4] = 1.0F;
fs[5] = 0.0F;
fs[6] = -f_195_;
fs[7] = 0.0F;
fs[8] = f_194_;
float[] fs_197_ = new float[9];
float f_198_ = 1.0F;
float f_199_ = 0.0F;
f_194_ = (float) i_188_ / 32767.0F;
f_195_ = -(float) Math.sqrt((double) (1.0F - f_194_ * f_194_));
f_196_ = 1.0F - f_194_;
float f_200_ = (float) Math.sqrt((double) (i * i + i_189_ * i_189_));
if (f_200_ == 0.0F && f_194_ == 0.0F) {
fs_193_ = fs;
} else {
if (f_200_ != 0.0F) {
f_198_ = (float) -i_189_ / f_200_;
f_199_ = (float) i / f_200_;
}
fs_197_[0] = f_194_ + f_198_ * f_198_ * f_196_;
fs_197_[1] = f_199_ * f_195_;
fs_197_[2] = f_199_ * f_198_ * f_196_;
fs_197_[3] = -f_199_ * f_195_;
fs_197_[4] = f_194_;
fs_197_[5] = f_198_ * f_195_;
fs_197_[6] = f_198_ * f_199_ * f_196_;
fs_197_[7] = -f_198_ * f_195_;
fs_197_[8] = f_194_ + f_199_ * f_199_ * f_196_;
fs_193_[0] = fs[0] * fs_197_[0] + fs[1] * fs_197_[3] + fs[2] * fs_197_[6];
fs_193_[1] = fs[0] * fs_197_[1] + fs[1] * fs_197_[4] + fs[2] * fs_197_[7];
fs_193_[2] = fs[0] * fs_197_[2] + fs[1] * fs_197_[5] + fs[2] * fs_197_[8];
fs_193_[3] = fs[3] * fs_197_[0] + fs[4] * fs_197_[3] + fs[5] * fs_197_[6];
fs_193_[4] = fs[3] * fs_197_[1] + fs[4] * fs_197_[4] + fs[5] * fs_197_[7];
fs_193_[5] = fs[3] * fs_197_[2] + fs[4] * fs_197_[5] + fs[5] * fs_197_[8];
fs_193_[6] = fs[6] * fs_197_[0] + fs[7] * fs_197_[3] + fs[8] * fs_197_[6];
fs_193_[7] = fs[6] * fs_197_[1] + fs[7] * fs_197_[4] + fs[8] * fs_197_[7];
fs_193_[8] = fs[6] * fs_197_[2] + fs[7] * fs_197_[5] + fs[8] * fs_197_[8];
}
fs_193_[0] *= f;
fs_193_[1] *= f;
fs_193_[2] *= f;
fs_193_[3] *= f_191_;
fs_193_[4] *= f_191_;
fs_193_[5] *= f_191_;
fs_193_[6] *= f_192_;
fs_193_[7] *= f_192_;
fs_193_[8] *= f_192_;
return fs_193_;
}
private static class Class97 {
@Getter private int[] anIntArray867;
@Getter private float[][] aFloatArrayArray868;
@Getter private int[] anIntArray869;
@Getter private int[] anIntArray870;
Class97(int[] is, int[] is_0_, int[] is_1_, float[][] fs) {
anIntArray867 = is;
anIntArray870 = is_0_;
anIntArray869 = is_1_;
aFloatArrayArray868 = fs;
}
}
public Model(int numVertices, int numTriangles, int numTextureTriangles) {
this.numVertices = 0;// added
this.numTriangles = 0;
maxDepth = 0;
priority = (byte) 0;
numTextureTriangles = 0;
vertexX = new int[numVertices];
vertexY = new int[numVertices];
vertexZ = new int[numVertices];
vertexSkins = new int[numVertices];
triangleViewspaceX = new short[numTriangles];
triangleViewspaceY = new short[numTriangles];
triangleViewspaceZ = new short[numTriangles];
faceRenderType = new byte[numTriangles];
trianglePriorities = new byte[numTriangles];
faceAlpha = new byte[numTriangles];
textureCoords = new short[numTriangles];
faceColor = new short[numTriangles];
textureIds = new short[numTriangles];
triangleSkinValues = new int[numTriangles];
if (numTextureTriangles > 0) {
textureRenderTypes = new byte[numTextureTriangles];
textureTriangleX = new short[numTextureTriangles];
textureTriangleY = new short[numTextureTriangles];
textureTriangleZ = new short[numTextureTriangles];
particleDirectionX = new int[numTextureTriangles];
particleDirectionY = new int[numTextureTriangles];
particleDirectionZ = new int[numTextureTriangles];
particleLifespanX = new byte[numTextureTriangles];
particleLifespanY = new byte[numTextureTriangles];
particleLifespanZ = new int[numTextureTriangles];
texturePrimaryColor = new int[numTextureTriangles];
textureSecondaryColor = new int[numTextureTriangles];
}
}
private boolean isCurrentFormat(byte[] data) {
return (data[0] == 1 || data[0] == 0);
}
private boolean isNewFormat(byte[] data) {
return data[data.length - 2] == -1 && data[data.length - 1] == -1;
}
@Override
protected void decodeOpcode(InputStream stream, int opcode) {
/* empty as decoding is not opcode-based */
}
@Override
public void encode(OutputStream stream) {
/* no */
}
}
vertexX/vertexY/vertexZ for offsets (apply your +x/y/z to all the vertexes in each array)