home *** CD-ROM | disk | FTP | other *** search
/ Late Night VRML 2.0 with Java CD-ROM / code.zip / Ch13 / mdl2vrml.java < prev    next >
Text File  |  1997-01-14  |  21KB  |  353 lines

  1. // Read a Quake MDL file and export it as VRML
  2.  
  3. // Written by Bernie Roehl, November 1996
  4.  
  5. import java.io.*;
  6. import java.util.*;
  7. import quake.*;
  8.  
  9. public class mdl2vrml {
  10.         public static void main(String args[])
  11.         throws MDLFormatException, IOException {
  12.                 boolean textures = false, animation = false;
  13.                 int argnum = 0;
  14.                 for (argnum = 0; argnum < args.length; ++argnum) {
  15.                         if (args[argnum].startsWith("-t"))
  16.                                 textures = true;
  17.                         else if (args[argnum].startsWith("-a"))
  18.                                 animation = true;
  19.                         else
  20.                                 break;
  21.                 }
  22.                 String mdl_filename = new String(args[argnum]);
  23.                 DataInputStream input = new DataInputStream(new FileInputStream(mdl_filename));
  24.                 MDLFile mdl = new MDLFile(input);
  25.                 System.out.println("#VRML V2.0 utf8\n");
  26.                 System.out.println("# Generated by mdl2wrl\n");
  27.                 System.out.println("# Original file was '" + mdl_filename + "'");
  28.                 System.out.println("# Data from original file:");
  29.                 System.out.println("#   Model radius = " + mdl.getRadius());
  30.                 System.out.println("#   Scale = " + mdl.getScale());
  31.                 System.out.println("#   Origin = " + mdl.getOrigin());
  32.                 System.out.println("#   Offsets = " + mdl.getOffsets());
  33.                 System.out.println("#   " + mdl.getNumberOfVertices() + " vertices");
  34.                 System.out.println("#   " + mdl.getNumberOfTriangles() + " triangles");
  35.                 System.out.println("#   " + mdl.getNumberOfFrameGroups() + " frames");
  36.                 System.out.println("#   " + mdl.getNumberOfSkins() + " skins, each " + mdl.getSkinWidth() + " by " + mdl.getSkinHeight());
  37.                 System.out.println();
  38.  
  39.                 if (animation)
  40.                         System.out.println("Group { children [ DEF TOUCH TouchSensor { }");
  41.                 System.out.println("Shape {");
  42.                 System.out.println("\tappearance Appearance {");
  43.  
  44.                 if (textures) {
  45.                         int dot_offset = mdl_filename.lastIndexOf('.');
  46.                         String basename = mdl_filename.substring(0, dot_offset);
  47.                         byte[] palette = load_palette("PALETTE");
  48.                         for (int i = 0; i < mdl.getNumberOfSkins(); ++i) {
  49.                                 Skin s = mdl.getSkin(i);
  50.                                 for (int j = 0; j < s.getNumberOfPictures(); ++j) {
  51.                                         byte[] picture = s.getPicture(j);
  52.                                         String filename = new String(basename + i + "_" + j + ".bmp");
  53.                                         BMP.dump(filename, picture, mdl.getSkinWidth(), mdl.getSkinHeight(), palette);
  54.                                         if (i != 0 || j != 0)
  55.                                                 System.out.print("#");
  56.                                         System.out.println("\t\ttexture ImageTexture { url \"" + filename + "\" }");
  57.                                 }
  58.                         }
  59.                 }
  60.  
  61.                 System.out.println("\t\tmaterial Material {");
  62.                 System.out.println("\t\t\tdiffuseColor 1 1 1");
  63.                 System.out.println("\t\t}");
  64.                 System.out.println("\t}");
  65.  
  66.                 System.out.println("\tgeometry");
  67.                 System.out.println("\tIndexedFaceSet {");
  68.  
  69.                 Frame f = mdl.getFrameGroup(0).getSubFrame(0);
  70.  
  71.                 System.out.print("\t\tcoord ");
  72.                 if (animation)
  73.                         System.out.print("DEF C ");
  74.                 System.out.println("Coordinate {");
  75.                 System.out.println("\t\t\tpoint [");
  76.                 for (int i = 0; i < mdl.getNumberOfVertices(); ++i)
  77.                         emit_vertex(f.getVertex(i), mdl);
  78.                 System.out.println("\t\t\t]");
  79.                 System.out.println("\t\t}");
  80.  
  81.                 System.out.print("\t\tnormal ");
  82.                 if (animation)
  83.                         System.out.print("DEF N ");
  84.                 System.out.println("Normal {");
  85.                 System.out.println("\t\t\tvector [");
  86.                 for (int i = 0; i < mdl.getNumberOfVertices(); ++i)
  87.                         emit_normal(f.getVertex(i), mdl);
  88.                 System.out.println("\t\t\t]");
  89.                 System.out.println("\t\t}");
  90.  
  91.                 System.out.println("\t\tcoordIndex [");
  92.                 for (int i = 0; i < mdl.getNumberOfTriangles(); ++i) {
  93.                         Triangle t = mdl.getTriangle(i);
  94.                         if (t.getPoint(0) != t.getPoint(1) &&
  95.                             t.getPoint(1) != t.getPoint(2) &&
  96.                             t.getPoint(2) != t.getPoint(0))
  97.                         System.out.println("\t\t\t" + t.getPoint(0) + " "
  98.                             + t.getPoint(1) + " " + t.getPoint(2) + " -1");
  99.                 }
  100.                 System.out.println("\t\t]");
  101.  
  102.                 if (textures) {
  103.                         System.out.println("\t\ttexCoord TextureCoordinate {");
  104.                         System.out.println("\t\t\tpoint [");
  105.                         for (int i = 0; i < mdl.getNumberOfVertices(); ++i) {
  106.                                 TextureVertex v = mdl.getTextureVertex(i);
  107.                                 System.out.print("\t\t\t\t" +
  108.                                         (v.getS()/(float) mdl.getSkinWidth()) + " " +
  109.                                         (v.getT()/(float) mdl.getSkinHeight()));
  110.                                 if (v.isOnseam())
  111.                                         System.out.print("  # onseam");
  112.                                 System.out.println();
  113.                         }
  114.                         for (int i = 0; i < mdl.getNumberOfVertices(); ++i) {
  115.                                 TextureVertex v = mdl.getTextureVertex(i);
  116.                                 System.out.print("\t\t\t\t" +
  117.                                         ((v.getS() + mdl.getSkinWidth()/2)/(float) mdl.getSkinWidth()) + " " +
  118.                                         (v.getT()/(float) mdl.getSkinHeight()));
  119.                                 if (v.isOnseam())
  120.                                         System.out.print("  # onseam");
  121.                                 System.out.println();
  122.                         }
  123.                         System.out.println("\t\t\t]");
  124.                         System.out.println("\t\t}");
  125.                         System.out.println("\t\ttexCoordIndex [");
  126.                         for (int i = 0; i < mdl.getNumberOfTriangles(); ++i) {
  127.                                 Triangle t = mdl.getTriangle(i);
  128.                                 if (t.getPoint(0) == t.getPoint(1) ||
  129.                                     t.getPoint(1) == t.getPoint(2) ||
  130.                                     t.getPoint(2) == t.getPoint(0))
  131.                                     continue;
  132.                                 System.out.print("\t\t\t");
  133.                                 if (t.isFrontFacing())
  134.                                          System.out.print(
  135.                                                 t.getPoint(0) + " " +
  136.                                                 t.getPoint(1) + " " +
  137.                                                 t.getPoint(2));
  138.                                 else {
  139.                                         if (mdl.getTextureVertex(t.getPoint(0)).isOnseam())
  140.                                                 System.out.print((t.getPoint(0) + mdl.getNumberOfVertices()) + " ");
  141.                                         else
  142.                                                 System.out.print(t.getPoint(0) + " ");
  143.                                         if (mdl.getTextureVertex(t.getPoint(1)).isOnseam())
  144.                                                 System.out.print((t.getPoint(1) + mdl.getNumberOfVertices()) + " ");
  145.                                         else
  146.                                                 System.out.print(t.getPoint(1) + " ");
  147.                                         if (mdl.getTextureVertex(t.getPoint(2)).isOnseam())
  148.                                                 System.out.print((t.getPoint(2) + mdl.getNumberOfVertices()));
  149.                                         else
  150.                                                 System.out.print(t.getPoint(2));
  151.                                 }
  152.                                 System.out.println(" -1");
  153.                         }
  154.                         System.out.println("\t\t]");
  155.                 }
  156.  
  157.                 System.out.println("\t}");   // end of IndexedFaceSet
  158.                 System.out.println("}");     // end of Shape
  159.                 if (animation)
  160.                         System.out.println("] }");  // end of Group node with TouchSensor in it
  161.  
  162.                 if (animation) {
  163.                         // check for multiple-frame groups
  164.                         for (int i = 0; i < mdl.getNumberOfFrameGroups(); ++i) {
  165.                                 if (mdl.getFrameGroup(i).getNumberOfSubFrames() != 1) {
  166.                                         System.err.println("sorry, multiple-frame groups not supported");
  167.                                         System.exit(2);
  168.                                 }
  169.                         }
  170.  
  171.                         Vector seqlist = new Vector();
  172.                         // find all the sequences
  173.                         Sequence seq = new Sequence(trimDigits(getFrame(mdl, 0).getName()), 0);
  174.                         for (int i = 1; i < mdl.getNumberOfFrameGroups(); ++i) {
  175.                                 String name = trimDigits(getFrame(mdl, i).getName());
  176.                                 if (!name.equals(seq.getName())) {
  177.                                         seq.setEnd(i-1);
  178.                                         seqlist.addElement(seq);
  179.                                         seq = new Sequence(name, i);
  180.                                 }
  181.                         }
  182.                         seq.setEnd(mdl.getNumberOfFrameGroups()-1);
  183.  
  184.                         for (Enumeration e = seqlist.elements(); e.hasMoreElements(); ) {
  185.                                 Frame fr;
  186.                                 Sequence s = (Sequence) e.nextElement();
  187.                                 System.out.println("DEF " + s.getName() + "_CI CoordinateInterpolator {");
  188.                                 System.out.println("\tkey [");
  189.                                 int nvalues = s.getEnd() - s.getStart() + 1;
  190.                                 for (int i = 0; i <= nvalues; ++i)
  191.                                         System.out.println("\t\t" + i / (float) nvalues);
  192.                                 System.out.println("\t]");
  193.                                 System.out.println("\tkeyValue [");
  194.                                 for (int i = 0; i < nvalues; ++i) {
  195.                                         fr = getFrame(mdl, s.getStart()+i);
  196.                                         for (int j = 0; j < mdl.getNumberOfVertices(); ++j)
  197.                                                 emit_vertex(fr.getVertex(j), mdl);
  198.                                 }
  199.                                 fr = getFrame(mdl, s.getStart());
  200.                                 for (int j = 0; j < mdl.getNumberOfVertices(); ++j)
  201.                                         emit_vertex(fr.getVertex(j), mdl);
  202.                                 System.out.println("\t]");
  203.                                 System.out.println("}");
  204.  
  205.                                 // normals
  206.                                 System.out.println("DEF " + s.getName() + "_NI NormalInterpolator {");
  207.                                 System.out.println("\tkey [");
  208.                                 for (int i = 0; i <= nvalues; ++i)
  209.                                         System.out.println("\t\t" + i / (float) nvalues);
  210.                                 System.out.println("\t]");
  211.                                 System.out.println("\tkeyValue [");
  212.                                 for (int i = 0; i < nvalues; ++i) {
  213.                                         fr = getFrame(mdl, s.getStart()+i);
  214.                                         for (int j = 0; j < mdl.getNumberOfVertices(); ++j)
  215.                                                 emit_normal(fr.getVertex(j), mdl);
  216.                                 }
  217.                                 fr = getFrame(mdl, s.getStart());
  218.                                 for (int j = 0; j < mdl.getNumberOfVertices(); ++j)
  219.                                         emit_normal(fr.getVertex(j), mdl);
  220.                                 System.out.println("\t]");
  221.                                 System.out.println("}");
  222.  
  223.                                 System.out.println("DEF " + s.getName() + "_TS TimeSensor { loop FALSE cycleInterval 5 stopTime -1 }");
  224.                                 System.out.println("ROUTE " + s.getName() + "_TS.fraction_changed TO " + s.getName() + "_CI.set_fraction");
  225.                                 System.out.println("ROUTE " + s.getName() + "_CI.value_changed TO C.point");
  226.                                 System.out.println("ROUTE " + s.getName() + "_TS.fraction_changed TO " + s.getName() + "_NI.set_fraction");
  227.                                 System.out.println("ROUTE " + s.getName() + "_NI.value_changed TO N.vector");
  228.                                 System.out.println();
  229.                         }
  230.                         System.out.println();
  231.  
  232.                         for (Enumeration e = seqlist.elements(); e.hasMoreElements(); ) {
  233.                                 Sequence s = (Sequence) e.nextElement();
  234.                                 System.out.println("#ROUTE TOUCH.touchTime TO " + s.getName() + "_TS.startTime");
  235.                         }
  236.                 }
  237.         }
  238.  
  239.         static double[][] normals = {
  240.                 {-0.5257,0.0000,0.8507},{-0.4429,0.2389,0.8642},{-0.2952,0.0000,0.9554},
  241.                 {-0.3090,0.5000,0.8090},{-0.1625,0.2629,0.9511},{0.0000,0.0000,1.0000},
  242.                 {0.0000,0.8507,0.5257},{-0.1476,0.7166,0.6817},{0.1476,0.7166,0.6817},
  243.                 {0.0000,0.5257,0.8507},{0.3090,0.5000,0.8090},{0.5257,0.0000,0.8507},
  244.                 {0.2952,0.0000,0.9554},{0.4429,0.2389,0.8642},{0.1625,0.2629,0.9511},
  245.                 {-0.6817,0.1476,0.7166},{-0.8090,0.3090,0.5000},{-0.5878,0.4253,0.6882},
  246.                 {-0.8507,0.5257,0.0000},{-0.8642,0.4429,0.2389},{-0.7166,0.6817,0.1476},
  247.                 {-0.6882,0.5878,0.4253},{-0.5000,0.8090,0.3090},{-0.2389,0.8642,0.4429},
  248.                 {-0.4253,0.6882,0.5878},{-0.7166,0.6817,-0.1476},{-0.5000,0.8090,-0.3090},
  249.                 {-0.5257,0.8507,0.0000},{0.0000,0.8507,-0.5257},{-0.2389,0.8642,-0.4429},
  250.                 {0.0000,0.9554,-0.2952},{-0.2629,0.9511,-0.1625},{0.0000,1.0000,0.0000},
  251.                 {0.0000,0.9554,0.2952},{-0.2629,0.9511,0.1625},{0.2389,0.8642,0.4429},
  252.                 {0.2629,0.9511,0.1625},{0.5000,0.8090,0.3090},{0.2389,0.8642,-0.4429},
  253.                 {0.2629,0.9511,-0.1625},{0.5000,0.8090,-0.3090},{0.8507,0.5257,0.0000},
  254.                 {0.7166,0.6817,0.1476},{0.7166,0.6817,-0.1476},{0.5257,0.8507,0.0000},
  255.                 {0.4253,0.6882,0.5878},{0.8642,0.4429,0.2389},{0.6882,0.5878,0.4253},
  256.                 {0.8090,0.3090,0.5000},{0.6817,0.1476,0.7166},{0.5878,0.4253,0.6882},
  257.                 {0.9554,0.2952,0.0000},{1.0000,0.0000,0.0000},{0.9511,0.1625,0.2629},
  258.                 {0.8507,-0.5257,0.0000},{0.9554,-0.2952,0.0000},{0.8642,-0.4429,0.2389},
  259.                 {0.9511,-0.1625,0.2629},{0.8090,-0.3090,0.5000},{0.6817,-0.1476,0.7166},
  260.                 {0.8507,0.0000,0.5257},{0.8642,0.4429,-0.2389},{0.8090,0.3090,-0.5000},
  261.                 {0.9511,0.1625,-0.2629},{0.5257,0.0000,-0.8507},{0.6817,0.1476,-0.7166},
  262.                 {0.6817,-0.1476,-0.7166},{0.8507,0.0000,-0.5257},{0.8090,-0.3090,-0.5000},
  263.                 {0.8642,-0.4429,-0.2389},{0.9511,-0.1625,-0.2629},{0.1476,0.7166,-0.6817},
  264.                 {0.3090,0.5000,-0.8090},{0.4253,0.6882,-0.5878},{0.4429,0.2389,-0.8642},
  265.                 {0.5878,0.4253,-0.6882},{0.6882,0.5878,-0.4253},{-0.1476,0.7166,-0.6817},
  266.                 {-0.3090,0.5000,-0.8090},{0.0000,0.5257,-0.8507},{-0.5257,0.0000,-0.8507},
  267.                 {-0.4429,0.2389,-0.8642},{-0.2952,0.0000,-0.9554},{-0.1625,0.2629,-0.9511},
  268.                 {0.0000,0.0000,-1.0000},{0.2952,0.0000,-0.9554},{0.1625,0.2629,-0.9511},
  269.                 {-0.4429,-0.2389,-0.8642},{-0.3090,-0.5000,-0.8090},{-0.1625,-0.2629,-0.9511},
  270.                 {0.0000,-0.8507,-0.5257},{-0.1476,-0.7166,-0.6817},{0.1476,-0.7166,-0.6817},
  271.                 {0.0000,-0.5257,-0.8507},{0.3090,-0.5000,-0.8090},{0.4429,-0.2389,-0.8642},
  272.                 {0.1625,-0.2629,-0.9511},{0.2389,-0.8642,-0.4429},{0.5000,-0.8090,-0.3090},
  273.                 {0.4253,-0.6882,-0.5878},{0.7166,-0.6817,-0.1476},{0.6882,-0.5878,-0.4253},
  274.                 {0.5878,-0.4253,-0.6882},{0.0000,-0.9554,-0.2952},{0.0000,-1.0000,0.0000},
  275.                 {0.2629,-0.9511,-0.1625},{0.0000,-0.8507,0.5257},{0.0000,-0.9554,0.2952},
  276.                 {0.2389,-0.8642,0.4429},{0.2629,-0.9511,0.1625},{0.5000,-0.8090,0.3090},
  277.                 {0.7166,-0.6817,0.1476},{0.5257,-0.8507,0.0000},{-0.2389,-0.8642,-0.4429},
  278.                 {-0.5000,-0.8090,-0.3090},{-0.2629,-0.9511,-0.1625},{-0.8507,-0.5257,0.0000},
  279.                 {-0.7166,-0.6817,-0.1476},{-0.7166,-0.6817,0.1476},{-0.5257,-0.8507,0.0000},
  280.                 {-0.5000,-0.8090,0.3090},{-0.2389,-0.8642,0.4429},{-0.2629,-0.9511,0.1625},
  281.                 {-0.8642,-0.4429,0.2389},{-0.8090,-0.3090,0.5000},{-0.6882,-0.5878,0.4253},
  282.                 {-0.6817,-0.1476,0.7166},{-0.4429,-0.2389,0.8642},{-0.5878,-0.4253,0.6882},
  283.                 {-0.3090,-0.5000,0.8090},{-0.1476,-0.7166,0.6817},{-0.4253,-0.6882,0.5878},
  284.                 {-0.1625,-0.2629,0.9511},{0.4429,-0.2389,0.8642},{0.1625,-0.2629,0.9511},
  285.                 {0.3090,-0.5000,0.8090},{0.1476,-0.7166,0.6817},{0.0000,-0.5257,0.8507},
  286.                 {0.4253,-0.6882,0.5878},{0.5878,-0.4253,0.6882},{0.6882,-0.5878,0.4253},
  287.                 {-0.9554,0.2952,0.0000},{-0.9511,0.1625,0.2629},{-1.0000,0.0000,0.0000},
  288.                 {-0.8507,0.0000,0.5257},{-0.9554,-0.2952,0.0000},{-0.9511,-0.1625,0.2629},
  289.                 {-0.8642,0.4429,-0.2389},{-0.9511,0.1625,-0.2629},{-0.8090,0.3090,-0.5000},
  290.                 {-0.8642,-0.4429,-0.2389},{-0.9511,-0.1625,-0.2629},{-0.8090,-0.3090,-0.5000},
  291.                 {-0.6817,0.1476,-0.7166},{-0.6817,-0.1476,-0.7166},{-0.8507,0.0000,-0.5257},
  292.                 {-0.6882,0.5878,-0.4253},{-0.5878,0.4253,-0.6882},{-0.4253,0.6882,-0.5878},
  293.                 {-0.4253,-0.6882,-0.5878},{-0.5878,-0.4253,-0.6882},{-0.6882,-0.5878,-0.4253}
  294.         };
  295.  
  296.         static String trimDigits(String str) {
  297.                 for (int i = 0; i < str.length(); ++i)
  298.                         if (Character.isDigit(str.charAt(i)))
  299.                                 return str.substring(0, i);
  300.                 return str;
  301.         }
  302.  
  303.         static Frame getFrame(MDLFile mdl, int n) {
  304.                 return mdl.getFrameGroup(n).getSubFrame(0);
  305.         }
  306.  
  307.         static void emit_vertex(Trivertex vertex, MDLFile mdl) {
  308.                 float vrmlScale = 0.0254f;
  309.                 System.out.println("\t\t\t\t" +
  310.                         vrmlScale * (vertex.getX() * mdl.getScale().getX() + mdl.getOrigin().getX()) +
  311.                         " " +
  312.                         vrmlScale * (vertex.getZ() * mdl.getScale().getZ() + mdl.getOrigin().getZ()) +
  313.                         " " +
  314.                         vrmlScale * (vertex.getY() * mdl.getScale().getY() + mdl.getOrigin().getY())
  315.                         );
  316.         }
  317.  
  318.         static void emit_normal(Trivertex vertex, MDLFile mdl) {
  319.                 double normal[] = normals[vertex.getLightNormalIndex()];
  320.                 System.out.println("\t\t\t\t" + normal[0] + " " + normal[2] + " " + normal[1]);
  321.         }
  322.  
  323.         static byte[] load_palette(String filename)
  324.                 throws IOException, FileNotFoundException {
  325.                 DataInputStream in = new DataInputStream(new FileInputStream(filename));
  326.                 byte[] pal = new byte[1024];
  327.                 for (int i = 0; i < 1024; i += 4) {
  328.                         pal[i+2] = in.readByte();  // red
  329.                         pal[i+1] = in.readByte();  // green
  330.                         pal[i+0] = in.readByte();  // blue
  331.                         pal[i+3] = 0;                      // reserved
  332.                 }
  333.                 return pal;
  334.         }
  335.  
  336. }
  337.  
  338. class Sequence {
  339.         protected String name;
  340.         protected int start, end;
  341.  
  342.         String getName() { return name; }
  343.         int getStart() { return start; }
  344.         int getEnd() { return end; }
  345.         void setEnd(int endvalue) { end = endvalue; }
  346.  
  347.         public Sequence(String namestr, int startvalue) {
  348.                 name = new String(namestr);
  349.                 start = startvalue;
  350.         }
  351. }
  352.  
  353.