001: /*
002: * $RCSfile: ObjectFileMaterials.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.6 $
041: * $Date: 2007/02/09 17:20:10 $
042: * $State: Exp $
043: */
044:
045: package com.sun.j3d.loaders.objectfile;
046:
047: import javax.media.j3d.Appearance;
048: import javax.media.j3d.Material;
049: import javax.media.j3d.Shape3D;
050: import javax.vecmath.Color3f;
051: import com.sun.j3d.loaders.ParsingErrorException;
052: import com.sun.j3d.loaders.IncorrectFormatException;
053: import java.io.FileNotFoundException;
054: import java.io.StringReader;
055: import java.io.Reader;
056: import java.io.FileReader;
057: import java.io.BufferedReader;
058: import java.io.BufferedInputStream;
059: import java.io.InputStreamReader;
060: import java.io.IOException;
061: import java.io.FileInputStream;
062: import java.util.HashMap;
063: import com.sun.j3d.loaders.objectfile.DefaultMaterials;
064: import java.net.URL;
065: import java.net.MalformedURLException;
066: import java.awt.Toolkit;
067: import java.awt.Image;
068: import java.awt.image.BufferedImage;
069: import javax.media.j3d.Texture2D;
070: import java.awt.image.ImageObserver;
071: import java.awt.image.PixelGrabber;
072: import java.awt.image.DataBufferInt;
073: import javax.media.j3d.ImageComponent2D;
074: import javax.media.j3d.TexCoordGeneration;
075: import java.security.AccessController;
076: import java.security.PrivilegedAction;
077: import javax.media.j3d.GeometryArray;
078: import com.sun.j3d.utils.image.TextureLoader;
079: import javax.media.j3d.TransparencyAttributes;
080:
081: class ObjectFileMaterials implements ImageObserver {
082: // DEBUG
083: // 1 = Name of materials
084: // 16 = Tokens
085: private static final int DEBUG = 0;
086:
087: private String curName = null;
088: private ObjectFileMaterial cur = null;
089:
090: private HashMap materials; // key=String name of material
091: // value=ObjectFileMaterial
092:
093: private String basePath;
094: private boolean fromUrl;
095:
096: private class ObjectFileMaterial {
097:
098: public Color3f Ka;
099: public Color3f Kd;
100: public Color3f Ks;
101: public int illum;
102: public float Ns;
103: public Texture2D t;
104: public boolean transparent;
105: public float transparencyLevel;
106:
107: }
108:
109: void assignMaterial(String matName, Shape3D shape) {
110: ObjectFileMaterial p = null;
111:
112: if ((DEBUG & 1) != 0)
113: System.out.println("Color " + matName);
114:
115: Material m = new Material();
116: p = (ObjectFileMaterial) materials.get(matName);
117: Appearance a = new Appearance();
118:
119: if (p != null) {
120: // Set ambient & diffuse color
121: if (p.Ka != null)
122: m.setAmbientColor(p.Ka);
123: if (p.Kd != null)
124: m.setDiffuseColor(p.Kd);
125:
126: // Set specular color
127: if ((p.Ks != null) && (p.illum != 1))
128: m.setSpecularColor(p.Ks);
129: else if (p.illum == 1)
130: m.setSpecularColor(0.0f, 0.0f, 0.0f);
131:
132: if (p.illum >= 1)
133: m.setLightingEnable(true);
134: else if (p.illum == 0)
135: m.setLightingEnable(false);
136:
137: if (p.Ns != -1.0f)
138: m.setShininess(p.Ns);
139:
140: if (p.t != null) {
141: a.setTexture(p.t);
142: // Create Texture Coordinates if not already present
143: if ((((GeometryArray) shape.getGeometry())
144: .getVertexFormat() & GeometryArray.TEXTURE_COORDINATE_2) == 0) {
145: TexCoordGeneration tcg = new TexCoordGeneration();
146: a.setTexCoordGeneration(tcg);
147: }
148: }
149:
150: if (p.transparent)
151: a.setTransparencyAttributes(new TransparencyAttributes(
152: TransparencyAttributes.NICEST,
153: p.transparencyLevel));
154: }
155: a.setMaterial(m);
156: if ((DEBUG & 1) != 0)
157: System.out.println(m);
158: shape.setAppearance(a);
159: } // End of assignMaterial
160:
161: private void readName(ObjectFileParser st)
162: throws ParsingErrorException {
163: st.getToken();
164:
165: if (st.ttype == ObjectFileParser.TT_WORD) {
166:
167: if (curName != null)
168: materials.put(curName, cur);
169: curName = new String(st.sval);
170: cur = new ObjectFileMaterial();
171: }
172: st.skipToNextLine();
173: } // End of readName
174:
175: private void readAmbient(ObjectFileParser st)
176: throws ParsingErrorException {
177: Color3f p = new Color3f();
178:
179: st.getNumber();
180: p.x = (float) st.nval;
181: st.getNumber();
182: p.y = (float) st.nval;
183: st.getNumber();
184: p.z = (float) st.nval;
185:
186: cur.Ka = p;
187:
188: st.skipToNextLine();
189: } // End of readAmbient
190:
191: private void readDiffuse(ObjectFileParser st)
192: throws ParsingErrorException {
193: Color3f p = new Color3f();
194:
195: st.getNumber();
196: p.x = (float) st.nval;
197: st.getNumber();
198: p.y = (float) st.nval;
199: st.getNumber();
200: p.z = (float) st.nval;
201:
202: cur.Kd = p;
203:
204: st.skipToNextLine();
205: } // End of readDiffuse
206:
207: private void readSpecular(ObjectFileParser st)
208: throws ParsingErrorException {
209: Color3f p = new Color3f();
210:
211: st.getNumber();
212: p.x = (float) st.nval;
213: st.getNumber();
214: p.y = (float) st.nval;
215: st.getNumber();
216: p.z = (float) st.nval;
217:
218: cur.Ks = p;
219:
220: st.skipToNextLine();
221: } // End of readSpecular
222:
223: private void readIllum(ObjectFileParser st)
224: throws ParsingErrorException {
225:
226: st.getNumber();
227: cur.illum = (int) st.nval;
228:
229: st.skipToNextLine();
230: } // End of readSpecular
231:
232: private void readTransparency(ObjectFileParser st)
233: throws ParsingErrorException {
234:
235: st.getNumber();
236: cur.transparencyLevel = (float) st.nval;
237: if (cur.transparencyLevel < 1.0f) {
238: cur.transparent = true;
239: }
240: st.skipToNextLine();
241: } // End of readTransparency
242:
243: private void readShininess(ObjectFileParser st)
244: throws ParsingErrorException {
245: float f;
246:
247: st.getNumber();
248: cur.Ns = (float) st.nval;
249: if (cur.Ns < 1.0f)
250: cur.Ns = 1.0f;
251: else if (cur.Ns > 128.0f)
252: cur.Ns = 128.0f;
253:
254: st.skipToNextLine();
255: } // End of readSpecular
256:
257: public void readMapKd(ObjectFileParser st) {
258: // Filenames are case sensitive
259: st.lowerCaseMode(false);
260:
261: // Get name of texture file (skip path)
262: String tFile = null;
263: do {
264: st.getToken();
265: if (st.ttype == ObjectFileParser.TT_WORD)
266: tFile = st.sval;
267: } while (st.ttype != ObjectFileParser.TT_EOL);
268:
269: st.lowerCaseMode(true);
270:
271: if (tFile != null) {
272: // Check for filename with no extension
273: if (tFile.lastIndexOf('.') != -1) {
274: try {
275: // Convert filename to lower case for extension comparisons
276: String suffix = tFile.substring(
277: tFile.lastIndexOf('.') + 1).toLowerCase();
278:
279: TextureLoader t = null;
280:
281: if ((suffix.equals("int"))
282: || (suffix.equals("inta"))
283: || (suffix.equals("rgb"))
284: || (suffix.equals("rgba"))
285: || (suffix.equals("bw"))
286: || (suffix.equals("sgi"))) {
287: RgbFile f;
288: if (fromUrl) {
289: f = new RgbFile(new URL(basePath + tFile)
290: .openStream());
291: } else {
292: f = new RgbFile(new FileInputStream(
293: basePath + tFile));
294: }
295: BufferedImage bi = f.getImage();
296:
297: boolean luminance = suffix.equals("int")
298: || suffix.equals("inta");
299: boolean alpha = suffix.equals("inta")
300: || suffix.equals("rgba");
301: cur.transparent = alpha;
302:
303: String s = null;
304: if (luminance && alpha)
305: s = "LUM8_ALPHA8";
306: else if (luminance)
307: s = "LUMINANCE";
308: else if (alpha)
309: s = "RGBA";
310: else
311: s = "RGB";
312:
313: t = new TextureLoader(bi, s,
314: TextureLoader.GENERATE_MIPMAP);
315: } else {
316: // For all other file types, use the TextureLoader
317: if (fromUrl) {
318: t = new TextureLoader(new URL(basePath
319: + tFile), "RGB",
320: TextureLoader.GENERATE_MIPMAP, null);
321: } else {
322: t = new TextureLoader(basePath + tFile,
323: "RGB",
324: TextureLoader.GENERATE_MIPMAP, null);
325: }
326: }
327: Texture2D texture = (Texture2D) t.getTexture();
328: if (texture != null)
329: cur.t = texture;
330: } catch (FileNotFoundException e) {
331: // Texture won't get loaded if file can't be found
332: } catch (MalformedURLException e) {
333: // Texture won't get loaded if file can't be found
334: } catch (IOException e) {
335: // Texture won't get loaded if file can't be found
336: }
337: }
338: }
339: st.skipToNextLine();
340: } // End of readMapKd
341:
342: private void readFile(ObjectFileParser st)
343: throws ParsingErrorException {
344: int t;
345: st.getToken();
346: while (st.ttype != ObjectFileParser.TT_EOF) {
347:
348: // Print out one token for each line
349: if ((DEBUG & 16) != 0) {
350: System.out.print("Token ");
351: if (st.ttype == ObjectFileParser.TT_EOL)
352: System.out.println("EOL");
353: else if (st.ttype == ObjectFileParser.TT_WORD)
354: System.out.println(st.sval);
355: else
356: System.out.println((char) st.ttype);
357: }
358:
359: if (st.ttype == ObjectFileParser.TT_WORD) {
360: if (st.sval.equals("newmtl")) {
361: readName(st);
362: } else if (st.sval.equals("ka")) {
363: readAmbient(st);
364: } else if (st.sval.equals("kd")) {
365: readDiffuse(st);
366: } else if (st.sval.equals("ks")) {
367: readSpecular(st);
368: } else if (st.sval.equals("illum")) {
369: readIllum(st);
370: } else if (st.sval.equals("d")) {
371: readTransparency(st);
372: } else if (st.sval.equals("ns")) {
373: readShininess(st);
374: } else if (st.sval.equals("tf")) {
375: st.skipToNextLine();
376: } else if (st.sval.equals("sharpness")) {
377: st.skipToNextLine();
378: } else if (st.sval.equals("map_kd")) {
379: readMapKd(st);
380: } else if (st.sval.equals("map_ka")) {
381: st.skipToNextLine();
382: } else if (st.sval.equals("map_ks")) {
383: st.skipToNextLine();
384: } else if (st.sval.equals("map_ns")) {
385: st.skipToNextLine();
386: } else if (st.sval.equals("bump")) {
387: st.skipToNextLine();
388: }
389: }
390:
391: st.skipToNextLine();
392:
393: // Get next token
394: st.getToken();
395: }
396: if (curName != null)
397: materials.put(curName, cur);
398: } // End of readFile
399:
400: void readMaterialFile(boolean fromUrl, String basePath,
401: String fileName) throws ParsingErrorException {
402:
403: Reader reader;
404:
405: this .basePath = basePath;
406: this .fromUrl = fromUrl;
407:
408: try {
409: if (fromUrl) {
410: reader = (Reader) (new InputStreamReader(
411: new BufferedInputStream((new URL(basePath
412: + fileName).openStream()))));
413: } else {
414: reader = new BufferedReader(new FileReader(basePath
415: + fileName));
416: }
417: } catch (IOException e) {
418: // couldn't find it - ignore mtllib
419: return;
420: }
421: if ((DEBUG & 1) != 0)
422: System.out.println("Material file: " + basePath + fileName);
423:
424: ObjectFileParser st = new ObjectFileParser(reader);
425: readFile(st);
426: } // End of readMaterialFile
427:
428: ObjectFileMaterials() throws ParsingErrorException {
429: Reader reader = new StringReader(DefaultMaterials.materials);
430:
431: ObjectFileParser st = new ObjectFileParser(reader);
432: materials = new HashMap(50);
433: readFile(st);
434: } // End of ObjectFileMaterials
435:
436: /**
437: * Implement the ImageObserver interface. Needed to load jpeg and gif
438: * files using the Toolkit.
439: */
440: public boolean imageUpdate(Image img, int flags, int x, int y,
441: int w, int h) {
442:
443: return (flags & (ALLBITS | ABORT)) == 0;
444: } // End of imageUpdate
445:
446: } // End of class ObjectFileMaterials
447:
448: // End of file ObjectFileMaterials.java
|