001: /*
002: * $RCSfile: LwoSurface.java,v $
003: *
004: * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * - Redistribution of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * - Redistribution in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * Neither the name of Sun Microsystems, Inc. or the names of
019: * contributors may be used to endorse or promote products derived
020: * from this software without specific prior written permission.
021: *
022: * This software is provided "AS IS," without a warranty of any
023: * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
024: * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
025: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
026: * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
027: * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
028: * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
029: * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
030: * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
031: * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
032: * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
033: * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
034: * POSSIBILITY OF SUCH DAMAGES.
035: *
036: * You acknowledge that this software is not designed, licensed or
037: * intended for use in the design, construction, operation or
038: * maintenance of any nuclear facility.
039: *
040: * $Revision: 1.4 $
041: * $Date: 2007/02/09 17:20:08 $
042: * $State: Exp $
043: */
044:
045: package com.sun.j3d.loaders.lw3d;
046:
047: import java.awt.Image;
048: import java.io.IOException;
049: import java.util.Vector;
050: import java.util.Enumeration;
051: import javax.vecmath.Color3f;
052: import javax.vecmath.Vector3f;
053: import com.sun.j3d.loaders.lw3d.LWOBFileReader;
054: import com.sun.j3d.internal.J3dUtilsI18N;
055: import java.io.FileNotFoundException;
056: import com.sun.j3d.loaders.IncorrectFormatException;
057: import com.sun.j3d.loaders.ParsingErrorException;
058:
059: /**
060: * This class is responsible for retrieving the surface parameters for a
061: * particular surface from a binary Object file and turning that data
062: * into Java3D data. These surface parameters include
063: * diffuse/specular/emissive properties, color, shininess, transparency,
064: * and textures. For textures, this class instantiates a LwoTexture object
065: * to parse that data and turn it into Java3D texture data.
066: */
067:
068: class LwoSurface extends ParserObject {
069:
070: LWOBFileReader theReader;
071: int red = 255, green = 255, blue = 255;
072: float diffuse = 0.0f, specular = 0.0f, transparency = 0.0f,
073: luminosity = 0.0f;
074: float creaseAngle = 0.0f;
075: int gloss = 128;
076: Color3f color, diffuseColor, specularColor, emissiveColor;
077: float shininess;
078: Image theImage = null;
079: Vector3f textureCenter = null, textureSize = null;
080: int textureAxis;
081: String surfName;
082: Vector textureList = new Vector();
083:
084: /**
085: * Constructor that parses surface data from the binary file
086: * and creates the necessary Java3d objects
087: */
088: LwoSurface(LWOBFileReader reader, int length, int debugVals)
089: throws FileNotFoundException {
090:
091: super (debugVals);
092: debugOutputLn(TRACE, "LwoSurface()");
093: theReader = reader;
094: getSurf(length);
095: setJ3dColors();
096: }
097:
098: /**
099: * Creates Java3d color objects from the lw3d surface data
100: */
101: void setJ3dColors() {
102: color = new Color3f((float) red / (float) 255, (float) green
103: / (float) 255, (float) blue / (float) 255);
104: diffuseColor = new Color3f(diffuse * color.x,
105: diffuse * color.y, diffuse * color.z);
106: specularColor = new Color3f(specular * color.x, specular
107: * color.y, specular * color.z);
108: emissiveColor = new Color3f(luminosity * color.x, luminosity
109: * color.y, luminosity * color.z);
110: shininess = (float) (128.0 * ((float) gloss / 1024.0));
111: }
112:
113: Color3f getColor() {
114: return color;
115: }
116:
117: Color3f getDiffuseColor() {
118: return diffuseColor;
119: }
120:
121: Color3f getSpecularColor() {
122: return specularColor;
123: }
124:
125: Color3f getEmissiveColor() {
126: return emissiveColor;
127: }
128:
129: float getShininess() {
130: return shininess;
131: }
132:
133: float getCreaseAngle() {
134: return creaseAngle;
135: }
136:
137: /**
138: * Returns the LwoTexture for the surface, if any is defined. Note that
139: * lw3d allows users to define multiple textures for any surface, which
140: * is not possible through Java3d. Therefore, we just grab the first
141: * texture in any list of textures for a surface
142: */
143: LwoTexture getTexture() {
144: debugOutputLn(TRACE, "getTexture()");
145: try {
146: if (textureList.isEmpty()) {
147: return null;
148: } else {
149: return (LwoTexture) textureList.elementAt(0);
150: }
151: } catch (ArrayIndexOutOfBoundsException e) {
152: debugOutputLn(EXCEPTION,
153: "getTexture(), exception returning first element: "
154: + e);
155: return null;
156: }
157: }
158:
159: String getSurfName() {
160: return surfName;
161: }
162:
163: float getTransparency() {
164: return transparency;
165: }
166:
167: /**
168: * Parses the binary file and gets all data for this surface
169: */
170: void getSurf(int length) throws FileNotFoundException,
171: IncorrectFormatException, ParsingErrorException {
172:
173: debugOutputLn(TRACE, "getSurf()");
174:
175: // These "got*" booleans are to help use read the best version of
176: // the data - the float values for these parameters should take
177: // precedence over the other format
178: boolean gotLuminosityFloat = false;
179: boolean gotTransparencyFloat = false;
180: boolean gotDiffuseFloat = false;
181: boolean gotSpecularFloat = false;
182: int surfStopMarker = theReader.getMarker() + length;
183: surfName = theReader.getString();
184: String tokenString = theReader.getToken();
185: while (!(tokenString == null)
186: && theReader.getMarker() < surfStopMarker) {
187: debugOutputLn(VALUES, " tokenString = " + tokenString);
188: debugOutputLn(VALUES, " marker, stop = "
189: + theReader.getMarker() + ", " + surfStopMarker);
190: String textureToken = null;
191: int fieldLength = theReader.getShortInt();
192: debugOutputLn(VALUES, " fl = " + fieldLength);
193:
194: if (tokenString.equals("COLR")) {
195: debugOutputLn(LINE_TRACE, " COLR");
196: try {
197: red = theReader.read();
198: green = theReader.read();
199: blue = theReader.read();
200: theReader.read();
201: } catch (IOException e) {
202: throw new ParsingErrorException(e.getMessage());
203: }
204: if (fieldLength != 4)
205: throw new IncorrectFormatException(J3dUtilsI18N
206: .getString("LwoSurface0"));
207: } else if (tokenString.equals("FLAG")) {
208: debugOutputLn(LINE_TRACE, " FLAG");
209: theReader.skipLength(fieldLength);
210: } else if (tokenString.equals("VLUM")) {
211: debugOutputLn(LINE_TRACE, " VLUM");
212: luminosity = theReader.getFloat();
213: gotLuminosityFloat = true;
214: } else if (tokenString.equals("LUMI")) {
215: debugOutputLn(LINE_TRACE, " LUMI");
216: if (gotLuminosityFloat)
217: theReader.skipLength(fieldLength);
218: else
219: luminosity = (float) (theReader.getShortInt()) / 255;
220: } else if (tokenString.equals("VDIF")) {
221: debugOutputLn(LINE_TRACE, " VDIF");
222: if (fieldLength != 4)
223: throw new IncorrectFormatException("VDIF problem");
224: diffuse = theReader.getFloat();
225: gotDiffuseFloat = true;
226: debugOutputLn(VALUES, "diff = " + diffuse);
227: } else if (tokenString.equals("DIFF")) {
228: debugOutputLn(LINE_TRACE, " DIFF");
229: if (gotDiffuseFloat)
230: theReader.skipLength(fieldLength);
231: else
232: diffuse = (float) theReader.getShortInt() / 255;
233: } else if (tokenString.equals("VTRN")) {
234: debugOutputLn(LINE_TRACE, " VTRN");
235: transparency = theReader.getFloat();
236: gotTransparencyFloat = true;
237: } else if (tokenString.equals("TRAN")) {
238: debugOutputLn(LINE_TRACE, " TRAN");
239: if (gotTransparencyFloat)
240: theReader.skipLength(fieldLength);
241: else
242: transparency = (float) theReader.getShortInt() / 255;
243: } else if (tokenString.equals("VSPC")) {
244: debugOutputLn(LINE_TRACE, " VSPC");
245: specular = theReader.getFloat();
246: gotSpecularFloat = true;
247: debugOutputLn(VALUES, "spec = " + specular);
248: } else if (tokenString.equals("SPEC")) {
249: debugOutputLn(LINE_TRACE, " SPEC");
250: if (gotSpecularFloat)
251: theReader.skipLength(fieldLength);
252: else {
253: if (fieldLength == 4) // Bug in some LW versions
254: specular = (float) theReader.getInt() / 255;
255: else
256: specular = (float) theReader.getShortInt() / 255;
257: }
258: } else if (tokenString.equals("GLOS")) {
259: debugOutputLn(LINE_TRACE, " GLOS");
260: if (fieldLength == 4)
261: gloss = theReader.getInt();
262: else
263: gloss = theReader.getShortInt();
264: } else if (tokenString.equals("SMAN")) {
265: debugOutputLn(LINE_TRACE, " SMAN");
266: creaseAngle = theReader.getFloat();
267: } else if (tokenString.endsWith("TEX")) {
268: // Textures are complex - hand off this bit to the
269: // LwoTexture class
270: LwoTexture texture = new LwoTexture(theReader,
271: surfStopMarker - theReader.getMarker(),
272: tokenString, debugPrinter.getValidOutput());
273: textureToken = texture.getNextToken();
274: if (texture.isHandled())
275: textureList.addElement(texture);
276: debugOutputLn(WARNING, "val = " + tokenString);
277: } else {
278: debugOutputLn(WARNING, "unrecognized token: "
279: + tokenString);
280: theReader.skipLength(fieldLength);
281: }
282: if (theReader.getMarker() < surfStopMarker) {
283: if (textureToken == null)
284: tokenString = theReader.getToken();
285: else
286: tokenString = textureToken;
287: }
288: }
289: }
290:
291: }
|