final InputStream md2Stream = resource.openStream();
if (md2Stream == null) {
throw new NullPointerException("Unable to load null streams");
}
// final Md2DataStore store = new Md2DataStore();
final LittleEndianRandomAccessDataInput bis = new LittleEndianRandomAccessDataInput(md2Stream);
// parse the header
final Md2Header header = new Md2Header(bis.readInt(), bis.readInt(), bis.readInt(), bis.readInt(), bis
.readInt(), bis.readInt(), bis.readInt(), bis.readInt(), bis.readInt(), bis.readInt(), bis
.readInt(), bis.readInt(), bis.readInt(), bis.readInt(), bis.readInt(), bis.readInt(), bis
.readInt());
// Check magic word and version
if (header.magic != ('2' << 24) + ('P' << 16) + ('D' << 8) + 'I') {
throw new Ardor3dException("Not an MD2 file.");
}
if (header.version != 8) {
throw new Ardor3dException("Invalid file version (Version not 8)!");
}
// Parse out texture names
final String[] texNames = new String[header.numSkins];
bis.seek(header.offsetSkins);
for (int i = 0; i < header.numSkins; i++) {
texNames[i] = bis.readString(64);
}
// Parse out tex coords
final float[] texCoords = new float[2 * header.numTexCoords];
bis.seek(header.offsetTexCoords);
final float inverseWidth = 1f / header.skinWidth;
final float inverseHeight = 1f / header.skinHeight;
for (int i = 0; i < header.numTexCoords; i++) {
texCoords[i * 2 + 0] = bis.readShort() * inverseWidth;
texCoords[i * 2 + 1] = bis.readShort() * inverseHeight;
}
// Parse out triangles
final short[] triangles = new short[header.numTriangles * 6];
bis.seek(header.offsetTriangles);
for (int i = 0; i < header.numTriangles; i++) {
triangles[i * 6 + 0] = bis.readShort(); // vert index 0
triangles[i * 6 + 1] = bis.readShort(); // vert index 1
triangles[i * 6 + 2] = bis.readShort(); // vert index 2
triangles[i * 6 + 3] = bis.readShort(); // texcoord index 0
triangles[i * 6 + 4] = bis.readShort(); // texcoord index 1
triangles[i * 6 + 5] = bis.readShort(); // texcoord index 2
}
// Parse out gl commands
final Md2GlCommand[] commands = new Md2GlCommand[header.numGlCommands];
bis.seek(header.offsetGlCommands);
int length, absLength;
Md2GlCommand cmd;
final List<Integer> fanIndices = Lists.newArrayList();
final List<Integer> stripIndices = Lists.newArrayList();
for (int i = 0; i < header.numGlCommands; i++) {
length = bis.readInt();
if (length == 0) {
break;
}
absLength = Math.abs(length);
commands[i] = cmd = new Md2GlCommand(length >= 0 ? IndexMode.TriangleStrip : IndexMode.TriangleFan,
absLength);
if (cmd.mode == IndexMode.TriangleFan) {
fanIndices.add(i);
} else {
stripIndices.add(i);
}
for (int j = 0; j < absLength; j++) {
cmd.texCoords[j * 2 + 0] = bis.readFloat();
cmd.texCoords[j * 2 + 1] = bis.readFloat();
cmd.vertIndices[j] = bis.readInt();
}
}
// Parse out frames
final Md2Frame[] frames = new Md2Frame[header.numFrames];
bis.seek(header.offsetFrames);
final Vector3 scale = new Vector3();
final Vector3 translate = new Vector3();
for (int i = 0; i < header.numFrames; i++) {
scale.set(bis.readFloat(), bis.readFloat(), bis.readFloat());
translate.set(bis.readFloat(), bis.readFloat(), bis.readFloat());
final String name = bis.readString(16);
final byte[] vertData = new byte[header.numVertices * 4];
bis.readFully(vertData);
frames[i] = new Md2Frame(vertData, name, scale, translate);
}
// make index modes/counts to be used throughout meshes
int vertexCount = 0;