Advertisement
romulosd

MD2 Loader

Oct 14th, 2014
2,918
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
J 20.64 KB | None | 0 0
  1. package md2;
  2.  
  3. import static org.lwjgl.opengl.GL11.*;
  4.  
  5. import java.io.*;
  6. import java.nio.*;
  7. import java.nio.channels.*;
  8. import java.util.*;
  9.  
  10. public class MD2 {
  11.     public static Model loadMD2(String filename) throws IOException {
  12.         List/* <IFrame> */ifr = new ArrayList/* <IFrame> */();
  13.         loadFrames(filename, ifr);
  14.         return computeModel(ifr);
  15.     }
  16.  
  17.     public static Model loadMD2(InputStream in) throws IOException {
  18.         List/* <IFrame> */ifr = new ArrayList/* <IFrame> */();
  19.         loadFrames(in, ifr);
  20.         return computeModel(ifr);
  21.     }
  22.  
  23.     public static class FileHeader {
  24.         public int ident;
  25.         public int version;
  26.         public int skinwidth;
  27.         public int skinheight;
  28.         public int framesize; // byte size of each frame
  29.         public int num_skins;
  30.         public int num_xyz;
  31.         public int num_st; // greater than num_xyz for seams
  32.         public int num_tris;
  33.         public int num_glcmds; // dwords in strip/fan command list
  34.         public int num_frames;
  35.         public int ofs_skins; // each skin is a MAX_SKINNAME string
  36.         public int ofs_st; // byte offset from start for stverts
  37.         public int ofs_tris; // offset for dtriangles
  38.         public int ofs_frames; // offset for first frame
  39.         public int ofs_glcmds;
  40.         public int ofs_end; // end of file
  41.     };
  42.  
  43.     public static class FileCompressedVertex {
  44.         public byte[] v = new byte[3]; // scaled byte to fit in frame mins/maxs
  45.         public byte lightnormalindex;
  46.     }
  47.  
  48.     public static class FileFrame {
  49.         public float[] scale = new float[3]; // multiply byte verts by this
  50.         public float[] translate = new float[3]; // then add this
  51.         public String name; // frame name from grabbing
  52.         public FileCompressedVertex[] verts; // variable sized
  53.     }
  54.  
  55.     public static class FileModel {
  56.         public int[] glcmds;
  57.         public FileFrame[] frames;
  58.     }
  59.  
  60.     public static class PositionNormal implements Cloneable {
  61.         public float x, y, z;
  62.         public float nx, ny, nz;
  63.  
  64.         public Object clone() {
  65.             try {
  66.                 return super.clone();
  67.             } catch (CloneNotSupportedException e) {
  68.                 throw new RuntimeException(e);
  69.             }
  70.         }
  71.     }
  72.  
  73.     public static class TexCoord {
  74.         public float s, t;
  75.     }
  76.  
  77.     public static class Vertex {
  78.         public int pn_index;
  79.         public TexCoord tc = new TexCoord();
  80.     }
  81.  
  82.     public static class Triangle {
  83.         public Vertex[] v = new Vertex[3];
  84.         public boolean kill;
  85.     }
  86.  
  87.     public static class WingedEdge {
  88.         public int[] e = new int[2]; // vertex index
  89.         public int[] w = new int[2]; // triangle index: for "open" models, w[1]
  90.                                         // == -1 on open edges
  91.     }
  92.  
  93.     public static class Plane implements Cloneable {
  94.         public float a, b, c, d;
  95.  
  96.         public Object clone() {
  97.             try {
  98.                 return super.clone();
  99.             } catch (CloneNotSupportedException e) {
  100.                 throw new RuntimeException(e);
  101.             }
  102.         }
  103.     }
  104.  
  105.     public static class Frame implements Cloneable {
  106.         public PositionNormal[] pn; // [pn_index]
  107.         public Plane[] triplane; // [tri_num]
  108.  
  109.         public Object clone() {
  110.             Frame res = new Frame();
  111.             res.pn = new PositionNormal[pn.length];
  112.             for (int i = 0; i < pn.length; i++) {
  113.                 res.pn[i] = (PositionNormal) pn[i].clone();
  114.             }
  115.             res.triplane = new Plane[triplane.length];
  116.             for (int i = 0; i < triplane.length; i++) {
  117.                 res.triplane[i] = (Plane) triplane[i].clone();
  118.             }
  119.             return res;
  120.         }
  121.     }
  122.  
  123.     public static class Model {
  124.         public Frame[] f;
  125.         public Triangle[] tri; // [tri_num]
  126.         public WingedEdge[] edge; // [edge_num]
  127.     }
  128.  
  129.     public static void computePlane(PositionNormal a, PositionNormal b,
  130.             PositionNormal c, Plane p) {
  131.         float[] v0 = new float[3];
  132.         v0[0] = b.x - a.x;
  133.         v0[1] = b.y - a.y;
  134.         v0[2] = b.z - a.z;
  135.         float[] v1 = new float[3];
  136.         v1[0] = c.x - a.x;
  137.         v1[1] = c.y - a.y;
  138.         v1[2] = c.z - a.z;
  139.         float[] cr = new float[3];
  140.         cr[0] = v0[1] * v1[2] - v0[2] * v1[1];
  141.         cr[1] = v0[2] * v1[0] - v0[0] * v1[2];
  142.         cr[2] = v0[0] * v1[1] - v0[1] * v1[0];
  143.         float l = (float) Math.sqrt(cr[0] * cr[0] + cr[1] * cr[1] + cr[2]
  144.                 * cr[2]);
  145.         if (l == 0) {
  146.             // degenerate triangle
  147.             p.a = p.b = p.c = p.d = 0;
  148.             return;
  149.         }
  150.         p.a = cr[0] / l;
  151.         p.b = cr[1] / l;
  152.         p.c = cr[2] / l;
  153.  
  154.         p.d = -(p.a * a.x + p.b * a.y + p.c * a.z); // signed distance of a
  155.                                                     // point on the plane from
  156.                                                     // the origin
  157.     }
  158.  
  159.     // ----------------------------------------------------------------------
  160.     // Internals only below this point
  161.     //
  162.  
  163.     private static Model computeModel(List/* <IFrame> */ifr) throws IOException {
  164.         if (!compareFrames(ifr)) {
  165.             throw new IOException("unsuitable model -- frames aren't same");
  166.         }
  167.         Model m = new Model();
  168.         m.tri = ((IFrame) ifr.get(0)).tri;
  169.         m.f = new Frame[ifr.size()];
  170.         for (int i = 0; i < ifr.size(); i++) {
  171.             Frame f = new Frame();
  172.             m.f[i] = f;
  173.             IFrame it = (IFrame) ifr.get(i);
  174.             f.pn = it.pn;
  175.             computeFramePlanes(m.tri, f);
  176.         }
  177.         computeWingedEdges(m);
  178.         return m;
  179.     }
  180.  
  181.     private static class IFrame {
  182.         PositionNormal[] pn;
  183.         Triangle[] tri;
  184.     }
  185.  
  186.     // normal table lifted from Mark Kilgard's md2bump demo
  187.     private static final float[] normalTable = new float[] { -0.525731f,
  188.             0.000000f, 0.850651f, -0.442863f, 0.238856f, 0.864188f, -0.295242f,
  189.             0.000000f, 0.955423f, -0.309017f, 0.500000f, 0.809017f, -0.162460f,
  190.             0.262866f, 0.951056f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
  191.             0.850651f, 0.525731f, -0.147621f, 0.716567f, 0.681718f, 0.147621f,
  192.             0.716567f, 0.681718f, 0.000000f, 0.525731f, 0.850651f, 0.309017f,
  193.             0.500000f, 0.809017f, 0.525731f, 0.000000f, 0.850651f, 0.295242f,
  194.             0.000000f, 0.955423f, 0.442863f, 0.238856f, 0.864188f, 0.162460f,
  195.             0.262866f, 0.951056f, -0.681718f, 0.147621f, 0.716567f, -0.809017f,
  196.             0.309017f, 0.500000f, -0.587785f, 0.425325f, 0.688191f, -0.850651f,
  197.             0.525731f, 0.000000f, -0.864188f, 0.442863f, 0.238856f, -0.716567f,
  198.             0.681718f, 0.147621f, -0.688191f, 0.587785f, 0.425325f, -0.500000f,
  199.             0.809017f, 0.309017f, -0.238856f, 0.864188f, 0.442863f, -0.425325f,
  200.             0.688191f, 0.587785f, -0.716567f, 0.681718f, -0.147621f,
  201.             -0.500000f, 0.809017f, -0.309017f, -0.525731f, 0.850651f,
  202.             0.000000f, 0.000000f, 0.850651f, -0.525731f, -0.238856f, 0.864188f,
  203.             -0.442863f, 0.000000f, 0.955423f, -0.295242f, -0.262866f,
  204.             0.951056f, -0.162460f, 0.000000f, 1.000000f, 0.000000f, 0.000000f,
  205.             0.955423f, 0.295242f, -0.262866f, 0.951056f, 0.162460f, 0.238856f,
  206.             0.864188f, 0.442863f, 0.262866f, 0.951056f, 0.162460f, 0.500000f,
  207.             0.809017f, 0.309017f, 0.238856f, 0.864188f, -0.442863f, 0.262866f,
  208.             0.951056f, -0.162460f, 0.500000f, 0.809017f, -0.309017f, 0.850651f,
  209.             0.525731f, 0.000000f, 0.716567f, 0.681718f, 0.147621f, 0.716567f,
  210.             0.681718f, -0.147621f, 0.525731f, 0.850651f, 0.000000f, 0.425325f,
  211.             0.688191f, 0.587785f, 0.864188f, 0.442863f, 0.238856f, 0.688191f,
  212.             0.587785f, 0.425325f, 0.809017f, 0.309017f, 0.500000f, 0.681718f,
  213.             0.147621f, 0.716567f, 0.587785f, 0.425325f, 0.688191f, 0.955423f,
  214.             0.295242f, 0.000000f, 1.000000f, 0.000000f, 0.000000f, 0.951056f,
  215.             0.162460f, 0.262866f, 0.850651f, -0.525731f, 0.000000f, 0.955423f,
  216.             -0.295242f, 0.000000f, 0.864188f, -0.442863f, 0.238856f, 0.951056f,
  217.             -0.162460f, 0.262866f, 0.809017f, -0.309017f, 0.500000f, 0.681718f,
  218.             -0.147621f, 0.716567f, 0.850651f, 0.000000f, 0.525731f, 0.864188f,
  219.             0.442863f, -0.238856f, 0.809017f, 0.309017f, -0.500000f, 0.951056f,
  220.             0.162460f, -0.262866f, 0.525731f, 0.000000f, -0.850651f, 0.681718f,
  221.             0.147621f, -0.716567f, 0.681718f, -0.147621f, -0.716567f,
  222.             0.850651f, 0.000000f, -0.525731f, 0.809017f, -0.309017f,
  223.             -0.500000f, 0.864188f, -0.442863f, -0.238856f, 0.951056f,
  224.             -0.162460f, -0.262866f, 0.147621f, 0.716567f, -0.681718f,
  225.             0.309017f, 0.500000f, -0.809017f, 0.425325f, 0.688191f, -0.587785f,
  226.             0.442863f, 0.238856f, -0.864188f, 0.587785f, 0.425325f, -0.688191f,
  227.             0.688191f, 0.587785f, -0.425325f, -0.147621f, 0.716567f,
  228.             -0.681718f, -0.309017f, 0.500000f, -0.809017f, 0.000000f,
  229.             0.525731f, -0.850651f, -0.525731f, 0.000000f, -0.850651f,
  230.             -0.442863f, 0.238856f, -0.864188f, -0.295242f, 0.000000f,
  231.             -0.955423f, -0.162460f, 0.262866f, -0.951056f, 0.000000f,
  232.             0.000000f, -1.000000f, 0.295242f, 0.000000f, -0.955423f, 0.162460f,
  233.             0.262866f, -0.951056f, -0.442863f, -0.238856f, -0.864188f,
  234.             -0.309017f, -0.500000f, -0.809017f, -0.162460f, -0.262866f,
  235.             -0.951056f, 0.000000f, -0.850651f, -0.525731f, -0.147621f,
  236.             -0.716567f, -0.681718f, 0.147621f, -0.716567f, -0.681718f,
  237.             0.000000f, -0.525731f, -0.850651f, 0.309017f, -0.500000f,
  238.             -0.809017f, 0.442863f, -0.238856f, -0.864188f, 0.162460f,
  239.             -0.262866f, -0.951056f, 0.238856f, -0.864188f, -0.442863f,
  240.             0.500000f, -0.809017f, -0.309017f, 0.425325f, -0.688191f,
  241.             -0.587785f, 0.716567f, -0.681718f, -0.147621f, 0.688191f,
  242.             -0.587785f, -0.425325f, 0.587785f, -0.425325f, -0.688191f,
  243.             0.000000f, -0.955423f, -0.295242f, 0.000000f, -1.000000f,
  244.             0.000000f, 0.262866f, -0.951056f, -0.162460f, 0.000000f,
  245.             -0.850651f, 0.525731f, 0.000000f, -0.955423f, 0.295242f, 0.238856f,
  246.             -0.864188f, 0.442863f, 0.262866f, -0.951056f, 0.162460f, 0.500000f,
  247.             -0.809017f, 0.309017f, 0.716567f, -0.681718f, 0.147621f, 0.525731f,
  248.             -0.850651f, 0.000000f, -0.238856f, -0.864188f, -0.442863f,
  249.             -0.500000f, -0.809017f, -0.309017f, -0.262866f, -0.951056f,
  250.             -0.162460f, -0.850651f, -0.525731f, 0.000000f, -0.716567f,
  251.             -0.681718f, -0.147621f, -0.716567f, -0.681718f, 0.147621f,
  252.             -0.525731f, -0.850651f, 0.000000f, -0.500000f, -0.809017f,
  253.             0.309017f, -0.238856f, -0.864188f, 0.442863f, -0.262866f,
  254.             -0.951056f, 0.162460f, -0.864188f, -0.442863f, 0.238856f,
  255.             -0.809017f, -0.309017f, 0.500000f, -0.688191f, -0.587785f,
  256.             0.425325f, -0.681718f, -0.147621f, 0.716567f, -0.442863f,
  257.             -0.238856f, 0.864188f, -0.587785f, -0.425325f, 0.688191f,
  258.             -0.309017f, -0.500000f, 0.809017f, -0.147621f, -0.716567f,
  259.             0.681718f, -0.425325f, -0.688191f, 0.587785f, -0.162460f,
  260.             -0.262866f, 0.951056f, 0.442863f, -0.238856f, 0.864188f, 0.162460f,
  261.             -0.262866f, 0.951056f, 0.309017f, -0.500000f, 0.809017f, 0.147621f,
  262.             -0.716567f, 0.681718f, 0.000000f, -0.525731f, 0.850651f, 0.425325f,
  263.             -0.688191f, 0.587785f, 0.587785f, -0.425325f, 0.688191f, 0.688191f,
  264.             -0.587785f, 0.425325f, -0.955423f, 0.295242f, 0.000000f,
  265.             -0.951056f, 0.162460f, 0.262866f, -1.000000f, 0.000000f, 0.000000f,
  266.             -0.850651f, 0.000000f, 0.525731f, -0.955423f, -0.295242f,
  267.             0.000000f, -0.951056f, -0.162460f, 0.262866f, -0.864188f,
  268.             0.442863f, -0.238856f, -0.951056f, 0.162460f, -0.262866f,
  269.             -0.809017f, 0.309017f, -0.500000f, -0.864188f, -0.442863f,
  270.             -0.238856f, -0.951056f, -0.162460f, -0.262866f, -0.809017f,
  271.             -0.309017f, -0.500000f, -0.681718f, 0.147621f, -0.716567f,
  272.             -0.681718f, -0.147621f, -0.716567f, -0.850651f, 0.000000f,
  273.             -0.525731f, -0.688191f, 0.587785f, -0.425325f, -0.587785f,
  274.             0.425325f, -0.688191f, -0.425325f, 0.688191f, -0.587785f,
  275.             -0.425325f, -0.688191f, -0.587785f, -0.587785f, -0.425325f,
  276.             -0.688191f, -0.688191f, -0.587785f, -0.425325f };
  277.  
  278.     private static void loadFrames(String filename, List/* <IFrame> */md2p)
  279.             throws IOException {
  280.         FileModel mf = loadMD2File(filename);
  281.         computeFrames(mf, md2p);
  282.     }
  283.  
  284.     private static void loadFrames(InputStream in, List/* <IFrame> */md2p)
  285.             throws IOException {
  286.         FileModel mf = loadMD2File(in);
  287.         computeFrames(mf, md2p);
  288.     }
  289.  
  290.     private static void computeFrames(FileModel mf, List/* <IFrame> */md2p)
  291.             throws IOException {
  292.         for (int i = 0; i < mf.frames.length; i++) {
  293.             IFrame f = new IFrame();
  294.             md2p.add(f);
  295.             FileFrame curframe = mf.frames[i];
  296.             f.pn = new PositionNormal[curframe.verts.length];
  297.             for (int j = 0; j < curframe.verts.length; j++) {
  298.                 PositionNormal pn = new PositionNormal();
  299.                 pn.x = (((curframe.verts[j].v[0] & 0xFF) * curframe.scale[0]) + curframe.translate[0]) * .025f;
  300.                 pn.y = (((curframe.verts[j].v[1] & 0xFF) * curframe.scale[1]) + curframe.translate[1]) * .025f;
  301.                 pn.z = (((curframe.verts[j].v[2] & 0xFF) * curframe.scale[2]) + curframe.translate[2]) * .025f;
  302.                 int normal_index = curframe.verts[j].lightnormalindex & 0xFF;
  303.                 pn.nx = normalTable[3 * normal_index + 0];
  304.                 pn.ny = normalTable[3 * normal_index + 1];
  305.                 pn.nz = normalTable[3 * normal_index + 2];
  306.                 f.pn[j] = pn;
  307.             }
  308.  
  309.             List/* <Triangle> */tris = new ArrayList();
  310.             int[] idx = new int[1];
  311.             while (mf.glcmds[idx[0]] != 0) {
  312.                 int vertnum;
  313.                 boolean is_strip;
  314.                 if (mf.glcmds[idx[0]] > 0) {
  315.                     vertnum = mf.glcmds[idx[0]++];
  316.                     is_strip = true; // triangle strip
  317.                 } else {
  318.                     vertnum = -mf.glcmds[idx[0]++];
  319.                     is_strip = false; // triangle fan
  320.                 }
  321.  
  322.                 if (is_strip) {
  323.                     Vertex[] prev = new Vertex[2];
  324.                     prev[0] = extractVertex(mf.glcmds, idx);
  325.                     prev[1] = extractVertex(mf.glcmds, idx);
  326.                     for (int j = 2; j < vertnum; j++) {
  327.                         Triangle tri = new Triangle();
  328.                         if ((j % 2) == 0) {
  329.                             tri.v[0] = prev[0];
  330.                             tri.v[1] = prev[1];
  331.                             tri.v[2] = extractVertex(mf.glcmds, idx);
  332.                             prev[0] = tri.v[2];
  333.                         } else {
  334.                             tri.v[0] = prev[1];
  335.                             tri.v[1] = extractVertex(mf.glcmds, idx);
  336.                             tri.v[2] = prev[0];
  337.                             prev[1] = tri.v[1];
  338.                         }
  339.                         // swap v[1] and v[2] to fix triangle winding
  340.                         Vertex hold = tri.v[1];
  341.                         tri.v[1] = tri.v[2];
  342.                         tri.v[2] = hold;
  343.                         tris.add(tri);
  344.                     }
  345.                 } else {
  346.                     // is fan
  347.                     Vertex ctr = extractVertex(mf.glcmds, idx);
  348.                     Vertex prev = extractVertex(mf.glcmds, idx);
  349.                     for (int j = 2; j < vertnum; j++) {
  350.                         Triangle tri = new Triangle();
  351.                         tri.v[0] = ctr;
  352.                         tri.v[1] = prev;
  353.                         tri.v[2] = extractVertex(mf.glcmds, idx);
  354.                         prev = tri.v[2];
  355.                         // swap v[1] and v[2] to fix triangle winding
  356.                         Vertex hold = tri.v[1];
  357.                         tri.v[1] = tri.v[2];
  358.                         tri.v[2] = hold;
  359.                         tris.add(tri);
  360.                     }
  361.                 }
  362.             }
  363.             f.tri = (Triangle[]) tris.toArray(new Triangle[0]);
  364.         }
  365.     }
  366.  
  367.     private static FileModel loadMD2File(ByteBuffer buf) throws IOException {
  368.         buf.order(ByteOrder.LITTLE_ENDIAN);
  369.         FileModel md2p = new FileModel();
  370.         FileHeader header = readHeader(buf);
  371.         buf.position(header.ofs_frames);
  372.         readFrames(buf, header, md2p);
  373.         buf.position(header.ofs_glcmds);
  374.         readGLCommands(buf, header, md2p);
  375.         return md2p;
  376.     }
  377.  
  378.     private static FileModel loadMD2File(InputStream in) throws IOException {
  379.         in = new BufferedInputStream(in);
  380.         int avail = in.available();
  381.         byte[] data = new byte[avail];
  382.         int numRead = 0;
  383.         int pos = 0;
  384.         do {
  385.             if (pos + avail > data.length) {
  386.                 byte[] newData = new byte[pos + avail];
  387.                 System.arraycopy(data, 0, newData, 0, pos);
  388.                 data = newData;
  389.             }
  390.             numRead = in.read(data, pos, avail);
  391.             if (numRead >= 0) {
  392.                 pos += numRead;
  393.             }
  394.             avail = in.available();
  395.         } while (avail > 0 && numRead >= 0);
  396.         ByteBuffer buf = ByteBuffer.allocateDirect(pos);
  397.         buf.put(data, 0, pos);
  398.         buf.rewind();
  399.         return loadMD2File(buf);
  400.     }
  401.  
  402.     private static FileModel loadMD2File(String filename) throws IOException {
  403.         FileInputStream fis = new FileInputStream(filename);
  404.         FileChannel chan = fis.getChannel();
  405.         ByteBuffer buf = chan.map(FileChannel.MapMode.READ_ONLY, 0,
  406.                 fis.available());
  407.         FileModel md2p = loadMD2File(buf);
  408.         chan.close();
  409.         fis.close();
  410.         return md2p;
  411.     }
  412.  
  413.     private static FileHeader readHeader(ByteBuffer buf) {
  414.         FileHeader header = new FileHeader();
  415.         header.ident = buf.getInt();
  416.         header.version = buf.getInt();
  417.         header.skinwidth = buf.getInt();
  418.         header.skinheight = buf.getInt();
  419.         header.framesize = buf.getInt();
  420.         header.num_skins = buf.getInt();
  421.         header.num_xyz = buf.getInt();
  422.         header.num_st = buf.getInt();
  423.         header.num_tris = buf.getInt();
  424.         header.num_glcmds = buf.getInt();
  425.         header.num_frames = buf.getInt();
  426.         header.ofs_skins = buf.getInt();
  427.         header.ofs_st = buf.getInt();
  428.         header.ofs_tris = buf.getInt();
  429.         header.ofs_frames = buf.getInt();
  430.         header.ofs_glcmds = buf.getInt();
  431.         header.ofs_end = buf.getInt();
  432.         return header;
  433.     }
  434.  
  435.     private static int numVerts(int framesize) {
  436.         return (framesize >> 2) - 10;
  437.     }
  438.  
  439.     private static void readFrames(ByteBuffer buf, FileHeader header,
  440.             FileModel md2p) throws IOException {
  441.         int numframes = header.num_frames;
  442.         int framesize = header.framesize;
  443.         int numVerts = numVerts(framesize);
  444.         FileFrame[] frames = new FileFrame[numframes];
  445.         byte[] name = new byte[16];
  446.         for (int i = 0; i < numframes; i++) {
  447.             FileFrame frame = new FileFrame();
  448.             frame.scale[0] = buf.getFloat();
  449.             frame.scale[1] = buf.getFloat();
  450.             frame.scale[2] = buf.getFloat();
  451.             frame.translate[0] = buf.getFloat();
  452.             frame.translate[1] = buf.getFloat();
  453.             frame.translate[2] = buf.getFloat();
  454.             buf.get(name);
  455.             try {
  456.                 frame.name = new String(name, "US-ASCII");
  457.             } catch (UnsupportedEncodingException e) {
  458.                 throw new IOException(e.toString());
  459.             }
  460.             frame.verts = new FileCompressedVertex[numVerts];
  461.             for (int j = 0; j < numVerts; j++) {
  462.                 FileCompressedVertex vert = new FileCompressedVertex();
  463.                 buf.get(vert.v);
  464.                 vert.lightnormalindex = buf.get();
  465.                 frame.verts[j] = vert;
  466.             }
  467.             frames[i] = frame;
  468.         }
  469.         md2p.frames = frames;
  470.     }
  471.  
  472.     private static void readGLCommands(ByteBuffer buf, FileHeader header,
  473.             FileModel md2p) {
  474.         int num_glcmds = header.num_glcmds;
  475.         int[] glcmds = new int[num_glcmds];
  476.         for (int i = 0; i < num_glcmds; i++) {
  477.             glcmds[i] = buf.getInt();
  478.         }
  479.         md2p.glcmds = glcmds;
  480.     }
  481.  
  482.     private static Vertex extractVertex(int[] glcmds, int[] idx) {
  483.         Vertex v = new Vertex();
  484.         v.tc.s = Float.intBitsToFloat(glcmds[idx[0]++]);
  485.         v.tc.t = Float.intBitsToFloat(glcmds[idx[0]++]);
  486.         v.pn_index = glcmds[idx[0]++];
  487.         return v;
  488.     }
  489.  
  490.     private static boolean compareFrames(List/* <IFrame> */m) {
  491.         IFrame f0 = (IFrame) m.get(0);
  492.         boolean same_topology = true;
  493.         boolean same_texcoords = true;
  494.  
  495.         for (int i = 1; i < m.size(); i++) {
  496.             IFrame f = (IFrame) m.get(i);
  497.             if (f.pn.length != f0.pn.length) {
  498.                 System.err.println("pn size different for iframe " + i + " :  "
  499.                         + f0.pn.length + " != " + f.pn.length);
  500.                 same_topology = false;
  501.             }
  502.             if (f.tri.length != f0.tri.length) {
  503.                 System.err.println("tri size different for iframe " + i
  504.                         + " :  " + f0.tri.length + " != " + f.tri.length);
  505.                 same_topology = false;
  506.             }
  507.             if (same_topology) {
  508.                 for (int j = 0; j < f.tri.length; j++) {
  509.                     Triangle t0 = f0.tri[j];
  510.                     Triangle t = f.tri[j];
  511.                     for (int k = 0; k < 3; k++) {
  512.                         if (t0.v[k].pn_index != t.v[k].pn_index) {
  513.                             System.err
  514.                                     .println("tri " + j + " triangle pn_index "
  515.                                             + k + " different!");
  516.                             same_topology = false;
  517.                         }
  518.                         if (t0.v[k].tc.s != t.v[k].tc.s
  519.                                 || t0.v[k].tc.t != t.v[k].tc.t) {
  520.                             System.err.println("tri " + j + " triangle tc " + k
  521.                                     + " different!");
  522.                             same_texcoords = false;
  523.                         }
  524.                     }
  525.                 }
  526.             }
  527.         }
  528.  
  529.         return same_topology && same_texcoords;
  530.     }
  531.  
  532.     /**
  533.      * Computes the plane equations for each polygon of a frame.
  534.      */
  535.     private static void computeFramePlanes(Triangle[] tri, Frame f) {
  536.         f.triplane = new Plane[tri.length];
  537.         for (int i = 0; i < tri.length; i++) {
  538.             Triangle t = tri[i];
  539.             int ia = t.v[0].pn_index;
  540.             int ib = t.v[1].pn_index;
  541.             int ic = t.v[2].pn_index;
  542.             Plane p = new Plane();
  543.             computePlane(f.pn[ia], f.pn[ib], f.pn[ic], p);
  544.             f.triplane[i] = p;
  545.         }
  546.     }
  547.  
  548.     private static int computeWingedEdges(Model m) {
  549.         Triangle[] tri = m.tri;
  550.         List/* <WingedEdge> */edge = new ArrayList/* <WingedEdge> */();
  551.  
  552.         int tsize = tri.length;
  553.         for (int i = 0; i < tsize; i++) {
  554.             Triangle t = tri[i];
  555.             for (int j = 0; j < 3; j++) {
  556.                 WingedEdge we = new WingedEdge();
  557.                 we.e[0] = t.v[j].pn_index;
  558.                 we.e[1] = t.v[(j + 1) % 3].pn_index;
  559.                 we.w[0] = i;
  560.                 we.w[1] = -1; // subsequent attempt to add this edge will
  561.                                 // replace w[1]
  562.                 addEdge(edge, we);
  563.             }
  564.         }
  565.         int open_edge = 0;
  566.         for (int i = 0; i < edge.size(); i++) {
  567.             if (((WingedEdge) edge.get(i)).w[1] == -1)
  568.                 open_edge++;
  569.         }
  570.         // fprintf(stderr, "out of % edges, there were %d open edges\n",
  571.         // edge.size(), open_edge);
  572.         m.edge = (WingedEdge[]) edge.toArray(new WingedEdge[0]);
  573.         return open_edge;
  574.     }
  575.  
  576.     private static void addEdge(List/* <WingedEdge> */edge, WingedEdge we) {
  577.         int esize = edge.size();
  578.         for (int i = 0; i < esize; i++) {
  579.             WingedEdge we0 = (WingedEdge) edge.get(i);
  580.             if (we0.e[0] == we.e[0] && we0.e[1] == we.e[1]) {
  581.                 System.err
  582.                         .println("facingness different between polys on edge!");
  583.             }
  584.             if (we0.e[0] == we.e[1] && we0.e[1] == we.e[0]) {
  585.                 if (we0.w[1] != -1) {
  586.                     System.err.println("triple edge! bad...");
  587.                 }
  588.                 we0.w[1] = we.w[0]; // pair the edge and return
  589.                 return;
  590.             }
  591.         }
  592.         edge.add(we); // otherwise, add the new edge
  593.     }
  594.  
  595.     public void draw(Model md2) {
  596.  
  597.         //todo
  598.     }
  599.  
  600.     // public static void main() {
  601.     // try {
  602.     // MD2.Model model = loadMD2("/pilaar.md2");
  603.         // model.draw
  604.     // } catch (IOException e) {
  605.     // e.printStackTrace();
  606.     // }
  607.     // }
  608. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement