home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Late Night VRML 2.0 with Java CD-ROM
/
code.zip
/
Ch13
/
mdl2vrml.java
< prev
next >
Wrap
Text File
|
1997-01-14
|
21KB
|
353 lines
// Read a Quake MDL file and export it as VRML
// Written by Bernie Roehl, November 1996
import java.io.*;
import java.util.*;
import quake.*;
public class mdl2vrml {
public static void main(String args[])
throws MDLFormatException, IOException {
boolean textures = false, animation = false;
int argnum = 0;
for (argnum = 0; argnum < args.length; ++argnum) {
if (args[argnum].startsWith("-t"))
textures = true;
else if (args[argnum].startsWith("-a"))
animation = true;
else
break;
}
String mdl_filename = new String(args[argnum]);
DataInputStream input = new DataInputStream(new FileInputStream(mdl_filename));
MDLFile mdl = new MDLFile(input);
System.out.println("#VRML V2.0 utf8\n");
System.out.println("# Generated by mdl2wrl\n");
System.out.println("# Original file was '" + mdl_filename + "'");
System.out.println("# Data from original file:");
System.out.println("# Model radius = " + mdl.getRadius());
System.out.println("# Scale = " + mdl.getScale());
System.out.println("# Origin = " + mdl.getOrigin());
System.out.println("# Offsets = " + mdl.getOffsets());
System.out.println("# " + mdl.getNumberOfVertices() + " vertices");
System.out.println("# " + mdl.getNumberOfTriangles() + " triangles");
System.out.println("# " + mdl.getNumberOfFrameGroups() + " frames");
System.out.println("# " + mdl.getNumberOfSkins() + " skins, each " + mdl.getSkinWidth() + " by " + mdl.getSkinHeight());
System.out.println();
if (animation)
System.out.println("Group { children [ DEF TOUCH TouchSensor { }");
System.out.println("Shape {");
System.out.println("\tappearance Appearance {");
if (textures) {
int dot_offset = mdl_filename.lastIndexOf('.');
String basename = mdl_filename.substring(0, dot_offset);
byte[] palette = load_palette("PALETTE");
for (int i = 0; i < mdl.getNumberOfSkins(); ++i) {
Skin s = mdl.getSkin(i);
for (int j = 0; j < s.getNumberOfPictures(); ++j) {
byte[] picture = s.getPicture(j);
String filename = new String(basename + i + "_" + j + ".bmp");
BMP.dump(filename, picture, mdl.getSkinWidth(), mdl.getSkinHeight(), palette);
if (i != 0 || j != 0)
System.out.print("#");
System.out.println("\t\ttexture ImageTexture { url \"" + filename + "\" }");
}
}
}
System.out.println("\t\tmaterial Material {");
System.out.println("\t\t\tdiffuseColor 1 1 1");
System.out.println("\t\t}");
System.out.println("\t}");
System.out.println("\tgeometry");
System.out.println("\tIndexedFaceSet {");
Frame f = mdl.getFrameGroup(0).getSubFrame(0);
System.out.print("\t\tcoord ");
if (animation)
System.out.print("DEF C ");
System.out.println("Coordinate {");
System.out.println("\t\t\tpoint [");
for (int i = 0; i < mdl.getNumberOfVertices(); ++i)
emit_vertex(f.getVertex(i), mdl);
System.out.println("\t\t\t]");
System.out.println("\t\t}");
System.out.print("\t\tnormal ");
if (animation)
System.out.print("DEF N ");
System.out.println("Normal {");
System.out.println("\t\t\tvector [");
for (int i = 0; i < mdl.getNumberOfVertices(); ++i)
emit_normal(f.getVertex(i), mdl);
System.out.println("\t\t\t]");
System.out.println("\t\t}");
System.out.println("\t\tcoordIndex [");
for (int i = 0; i < mdl.getNumberOfTriangles(); ++i) {
Triangle t = mdl.getTriangle(i);
if (t.getPoint(0) != t.getPoint(1) &&
t.getPoint(1) != t.getPoint(2) &&
t.getPoint(2) != t.getPoint(0))
System.out.println("\t\t\t" + t.getPoint(0) + " "
+ t.getPoint(1) + " " + t.getPoint(2) + " -1");
}
System.out.println("\t\t]");
if (textures) {
System.out.println("\t\ttexCoord TextureCoordinate {");
System.out.println("\t\t\tpoint [");
for (int i = 0; i < mdl.getNumberOfVertices(); ++i) {
TextureVertex v = mdl.getTextureVertex(i);
System.out.print("\t\t\t\t" +
(v.getS()/(float) mdl.getSkinWidth()) + " " +
(v.getT()/(float) mdl.getSkinHeight()));
if (v.isOnseam())
System.out.print(" # onseam");
System.out.println();
}
for (int i = 0; i < mdl.getNumberOfVertices(); ++i) {
TextureVertex v = mdl.getTextureVertex(i);
System.out.print("\t\t\t\t" +
((v.getS() + mdl.getSkinWidth()/2)/(float) mdl.getSkinWidth()) + " " +
(v.getT()/(float) mdl.getSkinHeight()));
if (v.isOnseam())
System.out.print(" # onseam");
System.out.println();
}
System.out.println("\t\t\t]");
System.out.println("\t\t}");
System.out.println("\t\ttexCoordIndex [");
for (int i = 0; i < mdl.getNumberOfTriangles(); ++i) {
Triangle t = mdl.getTriangle(i);
if (t.getPoint(0) == t.getPoint(1) ||
t.getPoint(1) == t.getPoint(2) ||
t.getPoint(2) == t.getPoint(0))
continue;
System.out.print("\t\t\t");
if (t.isFrontFacing())
System.out.print(
t.getPoint(0) + " " +
t.getPoint(1) + " " +
t.getPoint(2));
else {
if (mdl.getTextureVertex(t.getPoint(0)).isOnseam())
System.out.print((t.getPoint(0) + mdl.getNumberOfVertices()) + " ");
else
System.out.print(t.getPoint(0) + " ");
if (mdl.getTextureVertex(t.getPoint(1)).isOnseam())
System.out.print((t.getPoint(1) + mdl.getNumberOfVertices()) + " ");
else
System.out.print(t.getPoint(1) + " ");
if (mdl.getTextureVertex(t.getPoint(2)).isOnseam())
System.out.print((t.getPoint(2) + mdl.getNumberOfVertices()));
else
System.out.print(t.getPoint(2));
}
System.out.println(" -1");
}
System.out.println("\t\t]");
}
System.out.println("\t}"); // end of IndexedFaceSet
System.out.println("}"); // end of Shape
if (animation)
System.out.println("] }"); // end of Group node with TouchSensor in it
if (animation) {
// check for multiple-frame groups
for (int i = 0; i < mdl.getNumberOfFrameGroups(); ++i) {
if (mdl.getFrameGroup(i).getNumberOfSubFrames() != 1) {
System.err.println("sorry, multiple-frame groups not supported");
System.exit(2);
}
}
Vector seqlist = new Vector();
// find all the sequences
Sequence seq = new Sequence(trimDigits(getFrame(mdl, 0).getName()), 0);
for (int i = 1; i < mdl.getNumberOfFrameGroups(); ++i) {
String name = trimDigits(getFrame(mdl, i).getName());
if (!name.equals(seq.getName())) {
seq.setEnd(i-1);
seqlist.addElement(seq);
seq = new Sequence(name, i);
}
}
seq.setEnd(mdl.getNumberOfFrameGroups()-1);
for (Enumeration e = seqlist.elements(); e.hasMoreElements(); ) {
Frame fr;
Sequence s = (Sequence) e.nextElement();
System.out.println("DEF " + s.getName() + "_CI CoordinateInterpolator {");
System.out.println("\tkey [");
int nvalues = s.getEnd() - s.getStart() + 1;
for (int i = 0; i <= nvalues; ++i)
System.out.println("\t\t" + i / (float) nvalues);
System.out.println("\t]");
System.out.println("\tkeyValue [");
for (int i = 0; i < nvalues; ++i) {
fr = getFrame(mdl, s.getStart()+i);
for (int j = 0; j < mdl.getNumberOfVertices(); ++j)
emit_vertex(fr.getVertex(j), mdl);
}
fr = getFrame(mdl, s.getStart());
for (int j = 0; j < mdl.getNumberOfVertices(); ++j)
emit_vertex(fr.getVertex(j), mdl);
System.out.println("\t]");
System.out.println("}");
// normals
System.out.println("DEF " + s.getName() + "_NI NormalInterpolator {");
System.out.println("\tkey [");
for (int i = 0; i <= nvalues; ++i)
System.out.println("\t\t" + i / (float) nvalues);
System.out.println("\t]");
System.out.println("\tkeyValue [");
for (int i = 0; i < nvalues; ++i) {
fr = getFrame(mdl, s.getStart()+i);
for (int j = 0; j < mdl.getNumberOfVertices(); ++j)
emit_normal(fr.getVertex(j), mdl);
}
fr = getFrame(mdl, s.getStart());
for (int j = 0; j < mdl.getNumberOfVertices(); ++j)
emit_normal(fr.getVertex(j), mdl);
System.out.println("\t]");
System.out.println("}");
System.out.println("DEF " + s.getName() + "_TS TimeSensor { loop FALSE cycleInterval 5 stopTime -1 }");
System.out.println("ROUTE " + s.getName() + "_TS.fraction_changed TO " + s.getName() + "_CI.set_fraction");
System.out.println("ROUTE " + s.getName() + "_CI.value_changed TO C.point");
System.out.println("ROUTE " + s.getName() + "_TS.fraction_changed TO " + s.getName() + "_NI.set_fraction");
System.out.println("ROUTE " + s.getName() + "_NI.value_changed TO N.vector");
System.out.println();
}
System.out.println();
for (Enumeration e = seqlist.elements(); e.hasMoreElements(); ) {
Sequence s = (Sequence) e.nextElement();
System.out.println("#ROUTE TOUCH.touchTime TO " + s.getName() + "_TS.startTime");
}
}
}
static double[][] normals = {
{-0.5257,0.0000,0.8507},{-0.4429,0.2389,0.8642},{-0.2952,0.0000,0.9554},
{-0.3090,0.5000,0.8090},{-0.1625,0.2629,0.9511},{0.0000,0.0000,1.0000},
{0.0000,0.8507,0.5257},{-0.1476,0.7166,0.6817},{0.1476,0.7166,0.6817},
{0.0000,0.5257,0.8507},{0.3090,0.5000,0.8090},{0.5257,0.0000,0.8507},
{0.2952,0.0000,0.9554},{0.4429,0.2389,0.8642},{0.1625,0.2629,0.9511},
{-0.6817,0.1476,0.7166},{-0.8090,0.3090,0.5000},{-0.5878,0.4253,0.6882},
{-0.8507,0.5257,0.0000},{-0.8642,0.4429,0.2389},{-0.7166,0.6817,0.1476},
{-0.6882,0.5878,0.4253},{-0.5000,0.8090,0.3090},{-0.2389,0.8642,0.4429},
{-0.4253,0.6882,0.5878},{-0.7166,0.6817,-0.1476},{-0.5000,0.8090,-0.3090},
{-0.5257,0.8507,0.0000},{0.0000,0.8507,-0.5257},{-0.2389,0.8642,-0.4429},
{0.0000,0.9554,-0.2952},{-0.2629,0.9511,-0.1625},{0.0000,1.0000,0.0000},
{0.0000,0.9554,0.2952},{-0.2629,0.9511,0.1625},{0.2389,0.8642,0.4429},
{0.2629,0.9511,0.1625},{0.5000,0.8090,0.3090},{0.2389,0.8642,-0.4429},
{0.2629,0.9511,-0.1625},{0.5000,0.8090,-0.3090},{0.8507,0.5257,0.0000},
{0.7166,0.6817,0.1476},{0.7166,0.6817,-0.1476},{0.5257,0.8507,0.0000},
{0.4253,0.6882,0.5878},{0.8642,0.4429,0.2389},{0.6882,0.5878,0.4253},
{0.8090,0.3090,0.5000},{0.6817,0.1476,0.7166},{0.5878,0.4253,0.6882},
{0.9554,0.2952,0.0000},{1.0000,0.0000,0.0000},{0.9511,0.1625,0.2629},
{0.8507,-0.5257,0.0000},{0.9554,-0.2952,0.0000},{0.8642,-0.4429,0.2389},
{0.9511,-0.1625,0.2629},{0.8090,-0.3090,0.5000},{0.6817,-0.1476,0.7166},
{0.8507,0.0000,0.5257},{0.8642,0.4429,-0.2389},{0.8090,0.3090,-0.5000},
{0.9511,0.1625,-0.2629},{0.5257,0.0000,-0.8507},{0.6817,0.1476,-0.7166},
{0.6817,-0.1476,-0.7166},{0.8507,0.0000,-0.5257},{0.8090,-0.3090,-0.5000},
{0.8642,-0.4429,-0.2389},{0.9511,-0.1625,-0.2629},{0.1476,0.7166,-0.6817},
{0.3090,0.5000,-0.8090},{0.4253,0.6882,-0.5878},{0.4429,0.2389,-0.8642},
{0.5878,0.4253,-0.6882},{0.6882,0.5878,-0.4253},{-0.1476,0.7166,-0.6817},
{-0.3090,0.5000,-0.8090},{0.0000,0.5257,-0.8507},{-0.5257,0.0000,-0.8507},
{-0.4429,0.2389,-0.8642},{-0.2952,0.0000,-0.9554},{-0.1625,0.2629,-0.9511},
{0.0000,0.0000,-1.0000},{0.2952,0.0000,-0.9554},{0.1625,0.2629,-0.9511},
{-0.4429,-0.2389,-0.8642},{-0.3090,-0.5000,-0.8090},{-0.1625,-0.2629,-0.9511},
{0.0000,-0.8507,-0.5257},{-0.1476,-0.7166,-0.6817},{0.1476,-0.7166,-0.6817},
{0.0000,-0.5257,-0.8507},{0.3090,-0.5000,-0.8090},{0.4429,-0.2389,-0.8642},
{0.1625,-0.2629,-0.9511},{0.2389,-0.8642,-0.4429},{0.5000,-0.8090,-0.3090},
{0.4253,-0.6882,-0.5878},{0.7166,-0.6817,-0.1476},{0.6882,-0.5878,-0.4253},
{0.5878,-0.4253,-0.6882},{0.0000,-0.9554,-0.2952},{0.0000,-1.0000,0.0000},
{0.2629,-0.9511,-0.1625},{0.0000,-0.8507,0.5257},{0.0000,-0.9554,0.2952},
{0.2389,-0.8642,0.4429},{0.2629,-0.9511,0.1625},{0.5000,-0.8090,0.3090},
{0.7166,-0.6817,0.1476},{0.5257,-0.8507,0.0000},{-0.2389,-0.8642,-0.4429},
{-0.5000,-0.8090,-0.3090},{-0.2629,-0.9511,-0.1625},{-0.8507,-0.5257,0.0000},
{-0.7166,-0.6817,-0.1476},{-0.7166,-0.6817,0.1476},{-0.5257,-0.8507,0.0000},
{-0.5000,-0.8090,0.3090},{-0.2389,-0.8642,0.4429},{-0.2629,-0.9511,0.1625},
{-0.8642,-0.4429,0.2389},{-0.8090,-0.3090,0.5000},{-0.6882,-0.5878,0.4253},
{-0.6817,-0.1476,0.7166},{-0.4429,-0.2389,0.8642},{-0.5878,-0.4253,0.6882},
{-0.3090,-0.5000,0.8090},{-0.1476,-0.7166,0.6817},{-0.4253,-0.6882,0.5878},
{-0.1625,-0.2629,0.9511},{0.4429,-0.2389,0.8642},{0.1625,-0.2629,0.9511},
{0.3090,-0.5000,0.8090},{0.1476,-0.7166,0.6817},{0.0000,-0.5257,0.8507},
{0.4253,-0.6882,0.5878},{0.5878,-0.4253,0.6882},{0.6882,-0.5878,0.4253},
{-0.9554,0.2952,0.0000},{-0.9511,0.1625,0.2629},{-1.0000,0.0000,0.0000},
{-0.8507,0.0000,0.5257},{-0.9554,-0.2952,0.0000},{-0.9511,-0.1625,0.2629},
{-0.8642,0.4429,-0.2389},{-0.9511,0.1625,-0.2629},{-0.8090,0.3090,-0.5000},
{-0.8642,-0.4429,-0.2389},{-0.9511,-0.1625,-0.2629},{-0.8090,-0.3090,-0.5000},
{-0.6817,0.1476,-0.7166},{-0.6817,-0.1476,-0.7166},{-0.8507,0.0000,-0.5257},
{-0.6882,0.5878,-0.4253},{-0.5878,0.4253,-0.6882},{-0.4253,0.6882,-0.5878},
{-0.4253,-0.6882,-0.5878},{-0.5878,-0.4253,-0.6882},{-0.6882,-0.5878,-0.4253}
};
static String trimDigits(String str) {
for (int i = 0; i < str.length(); ++i)
if (Character.isDigit(str.charAt(i)))
return str.substring(0, i);
return str;
}
static Frame getFrame(MDLFile mdl, int n) {
return mdl.getFrameGroup(n).getSubFrame(0);
}
static void emit_vertex(Trivertex vertex, MDLFile mdl) {
float vrmlScale = 0.0254f;
System.out.println("\t\t\t\t" +
vrmlScale * (vertex.getX() * mdl.getScale().getX() + mdl.getOrigin().getX()) +
" " +
vrmlScale * (vertex.getZ() * mdl.getScale().getZ() + mdl.getOrigin().getZ()) +
" " +
vrmlScale * (vertex.getY() * mdl.getScale().getY() + mdl.getOrigin().getY())
);
}
static void emit_normal(Trivertex vertex, MDLFile mdl) {
double normal[] = normals[vertex.getLightNormalIndex()];
System.out.println("\t\t\t\t" + normal[0] + " " + normal[2] + " " + normal[1]);
}
static byte[] load_palette(String filename)
throws IOException, FileNotFoundException {
DataInputStream in = new DataInputStream(new FileInputStream(filename));
byte[] pal = new byte[1024];
for (int i = 0; i < 1024; i += 4) {
pal[i+2] = in.readByte(); // red
pal[i+1] = in.readByte(); // green
pal[i+0] = in.readByte(); // blue
pal[i+3] = 0; // reserved
}
return pal;
}
}
class Sequence {
protected String name;
protected int start, end;
String getName() { return name; }
int getStart() { return start; }
int getEnd() { return end; }
void setEnd(int endvalue) { end = endvalue; }
public Sequence(String namestr, int startvalue) {
name = new String(namestr);
start = startvalue;
}
}