/src/org/mt4j/util/modelImporter/fileObj/ObjectFileMaterials.java
Java | 671 lines | 399 code | 115 blank | 157 comment | 141 complexity | f05d751946ea0ff07ae422c9f330d214 MD5 | raw file
1/* 2 * $RCSfile: ObjectFile.java,v $ 3 * 4 * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * - Redistribution of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * - Redistribution in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 18 * Neither the name of Sun Microsystems, Inc. or the names of 19 * contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * This software is provided "AS IS," without a warranty of any 23 * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND 24 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, 25 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY 26 * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL 27 * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF 28 * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS 29 * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR 30 * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, 31 * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND 32 * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR 33 * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE 34 * POSSIBILITY OF SUCH DAMAGES. 35 * 36 * You acknowledge that this software is not designed, licensed or 37 * intended for use in the design, construction, operation or 38 * maintenance of any nuclear facility. 39 * 40 * $Revision: 1.6 $ 41 * $Date: 2009/12/21 13:55:05 $ 42 * $State: Exp $ 43 */ 44 45package org.mt4j.util.modelImporter.fileObj; 46 47import java.awt.Image; 48import java.awt.image.ImageObserver; 49import java.io.BufferedInputStream; 50import java.io.BufferedReader; 51import java.io.File; 52import java.io.FileNotFoundException; 53import java.io.FileReader; 54import java.io.IOException; 55import java.io.InputStream; 56import java.io.InputStreamReader; 57import java.io.Reader; 58import java.net.URL; 59import java.util.HashMap; 60import java.util.Map; 61import java.util.WeakHashMap; 62 63import javax.media.opengl.GL; 64 65import org.mt4j.components.visibleComponents.shapes.AbstractShape; 66import org.mt4j.util.MT4jSettings; 67import org.mt4j.util.math.Tools3D; 68import org.mt4j.util.opengl.GLMaterial; 69import org.mt4j.util.opengl.GLTexture; 70import org.mt4j.util.opengl.GLTextureSettings; 71import org.mt4j.util.opengl.GLTexture.EXPANSION_FILTER; 72import org.mt4j.util.opengl.GLTexture.SHRINKAGE_FILTER; 73import org.mt4j.util.opengl.GLTexture.TEXTURE_TARGET; 74import org.mt4j.util.opengl.GLTexture.WRAP_MODE; 75 76import processing.core.PApplet; 77import processing.core.PImage; 78 79 80class ObjectFileMaterials implements ImageObserver { 81 // DEBUG 82 // 1 = Name of materials 83 // 16 = Tokens 84 private static final int DEBUG = 0; 85 86 private String curName = null; 87 private ObjectFileMaterial cur = null; 88 89 private HashMap materials; // key=String name of material 90 // value=ObjectFileMaterial 91 92 private Map<String, PImage> textureCache = new WeakHashMap<String, PImage>(); 93 PApplet pa; 94 95 private String basePath; 96 private boolean fromUrl; 97 98 private class ObjectFileMaterial { 99// public Color3f Ka; 100// public Color3f Kd; 101// public Color3f Ks; 102 public float[] Ka; 103 public float[] Kd; 104 public float[] Ks; 105 106 public int illum; 107 public float Ns; 108// public Texture2D t; 109 public PImage t; 110 public boolean transparent; 111 public float transparencyLevel; 112 113 public PImage d; 114 115 } 116 117 118 119 120 void assignMaterial(GL gl, String matName, AbstractShape shape) { 121 ObjectFileMaterial p = null; 122 123 if ((DEBUG & 1) != 0) 124 System.out.println("Color " + matName); 125 126 GLMaterial m = new GLMaterial(gl); 127 p = (ObjectFileMaterial)materials.get(matName); 128// Appearance a = new Appearance(); 129 130 if (p != null) { 131 132 // Set ambient & diffuse color 133 if (p.Ka != null) 134// m.setAmbient(p.Ka); 135 m.setAmbient(new float[]{p.Ka[0],p.Ka[1],p.Ka[2], 1.0f}); //we have to add the last value, else material will not be opaque 136 137 if (p.Kd != null) 138// m.setDiffuse(p.Kd); 139 m.setDiffuse(new float[]{p.Kd[0],p.Kd[1],p.Kd[2], 1.0f}); 140 141 // Set specular color 142 if ((p.Ks != null) && (p.illum != 1)) 143// m.setSpecular(p.Ks); 144 m.setSpecular(new float[]{p.Ks[0],p.Ks[1],p.Ks[2], 1.0f}); 145 else if (p.illum == 1) 146 m.setSpecular(new float[]{0.0f, 0.0f, 0.0f, 1.0f}); 147 148// if (p.illum >= 1) m.setLightingEnable(true); 149// else if (p.illum == 0) m.setLightingEnable(false); 150 151 if (p.Ns != -1.0f) 152 m.setShininess(p.Ns); 153 154 155 if (p.t != null) { 156 PImage tex = p.t; 157 158// /* 159 //Apply alpha mask from transparancy map to the texture 160 if (p.d != null){ 161 //System.out.println("Trying to add alpha mask for material: " + matName); 162 163 PImage alphaMap = p.d; 164 if (alphaMap.width == tex.width && alphaMap.height == tex.height){ 165 tex.mask(alphaMap); 166 167 if (tex instanceof GLTexture) { 168 GLTexture glTex = (GLTexture) tex; 169// glTex.putPixelsIntoTexture(tex); 170 glTex.loadGLTexture(tex); 171 } 172 }else{ 173 //System.out.println("Alpha map isnt the same size as the texture for material: " + matName); 174 } 175 } 176// */ 177 178 shape.setTexture(tex); 179 System.out.println("Texture assigned to object: " + shape.getName()); 180 } 181 182// if (p.transparent) 183// a.setTransparencyAttributes(new TransparencyAttributes(TransparencyAttributes.NICEST,p.transparencyLevel)); 184 185 shape.setMaterial(m); 186 }else{ 187 System.err.println("No material \"" + matName + "\" found for object " + shape.getName()); 188 } 189 190 if ((DEBUG & 1) != 0) 191 System.out.println(m); 192 } // End of assignMaterial 193 194 195 private void readName(ObjectFileParser st) throws ParsingErrorException { 196 st.getToken(); 197 198 if (st.ttype == ObjectFileParser.TT_WORD) { 199 200 if (curName != null) materials.put(curName, cur); 201 curName = st.sval; 202 cur = new ObjectFileMaterial(); 203 } 204 st.skipToNextLine(); 205 } // End of readName 206 207 208 private void readAmbient(ObjectFileParser st) throws ParsingErrorException { 209// Color3f p = new Color3f(); 210 float[] p = new float[3]; 211 212 st.getNumber(); 213 p[0] = (float)st.nval; 214 st.getNumber(); 215 p[1] = (float)st.nval; 216 st.getNumber(); 217 p[2] = (float)st.nval; 218 219 cur.Ka = p; 220 221 st.skipToNextLine(); 222 } // End of readAmbient 223 224 225 private void readDiffuse(ObjectFileParser st) throws ParsingErrorException { 226// Color3f p = new Color3f(); 227 float[] p = new float[3]; 228 229 st.getNumber(); 230 p[0] = (float)st.nval; 231 st.getNumber(); 232 p[1] = (float)st.nval; 233 st.getNumber(); 234 p[2] = (float)st.nval; 235 236 cur.Kd = p; 237 238 st.skipToNextLine(); 239 } // End of readDiffuse 240 241 242 private void readSpecular(ObjectFileParser st) throws ParsingErrorException { 243// Color3f p = new Color3f(); 244 float[] p = new float[3]; 245 246 st.getNumber(); 247 p[0] = (float)st.nval; 248 st.getNumber(); 249 p[1] = (float)st.nval; 250 st.getNumber(); 251 p[2] = (float)st.nval; 252 253 cur.Ks = p; 254 255 st.skipToNextLine(); 256 } // End of readSpecular 257 258 259 private void readIllum(ObjectFileParser st) throws ParsingErrorException { 260 st.getNumber(); 261 cur.illum = (int)st.nval; 262 263 st.skipToNextLine(); 264 } // End of readSpecular 265 266 private void readTransparency(ObjectFileParser st) throws ParsingErrorException { 267 st.getNumber(); 268 cur.transparencyLevel = (float)st.nval; 269 if ( cur.transparencyLevel < 1.0f ){ 270 cur.transparent = true; 271 } 272 st.skipToNextLine(); 273 } // End of readTransparency 274 275 private void readShininess(ObjectFileParser st) throws ParsingErrorException { 276 float f; 277 278 st.getNumber(); 279 cur.Ns = (float)st.nval; 280 if (cur.Ns < 1.0f) cur.Ns = 1.0f; 281 else if (cur.Ns > 128.0f) cur.Ns = 128.0f; 282 283 st.skipToNextLine(); 284 } // End of readSpecular 285 286 287 288 public void readMapKd(ObjectFileParser st) { 289 // Filenames are case sensitive 290 st.lowerCaseMode(false); 291 292 // Get name of texture file (skip path) 293 String tFile = ""; 294 do { 295 st.getToken(); 296// if (st.ttype == ObjectFileParser.TT_WORD){ 297// tFile += st.sval; 298// 299// } 300 if (st.ttype != ObjectFileParser.TT_EOL ){ 301 tFile += st.sval; 302 } 303 304 } while (st.ttype != ObjectFileParser.TT_EOL); 305 306 st.lowerCaseMode(true); 307 308 if (!tFile.equals("")) { 309 310 PImage texture = null; 311 312 // Check for filename with no extension 313 if (tFile.lastIndexOf('.') != -1) { 314 try { 315 // Convert filename to lower case for extension comparisons 316 String suffix = tFile.substring(tFile.lastIndexOf('.') + 1).toLowerCase(); 317 318// TextureLoader t = null; 319 320 tFile = toLowerCase(tFile); 321 322 if ((suffix.equals("int")) || (suffix.equals("inta")) || 323 (suffix.equals("rgb")) || (suffix.equals("rgba")) || 324 (suffix.equals("bw")) || (suffix.equals("sgi")) 325 ) { 326 327 PImage cachedImage = textureCache.get(tFile); 328 if (cachedImage != null){ 329 texture = cachedImage; 330 //System.out.println("->Loaded texture from CACHE : \"" + tFile + "\""); 331 }else{ 332 File textureFile = new File(basePath + tFile); 333 if (textureFile.exists()){ 334 boolean success = textureFile.renameTo(new File(basePath + tFile)); 335 if (!success) { 336 // File was not successfully renamed 337 System.out.println("failed to RENAME file: " + textureFile.getAbsolutePath()); 338 } 339 340 if (MT4jSettings.getInstance().isOpenGlMode()){ 341 PImage img = pa.loadImage(basePath + tFile); 342 if (Tools3D.isPowerOfTwoDimension(img)){ 343 texture = new GLTexture(pa, img, new GLTextureSettings(TEXTURE_TARGET.TEXTURE_2D, SHRINKAGE_FILTER.Trilinear, EXPANSION_FILTER.Bilinear, WRAP_MODE.REPEAT, WRAP_MODE.REPEAT)); 344 }else{ 345 texture = new GLTexture(pa, img, new GLTextureSettings(TEXTURE_TARGET.RECTANGULAR, SHRINKAGE_FILTER.Trilinear, EXPANSION_FILTER.Bilinear, WRAP_MODE.REPEAT, WRAP_MODE.REPEAT)); 346// ((GLTexture)texture).setFilter(SHRINKAGE_FILTER.BilinearNoMipMaps, EXPANSION_FILTER.Bilinear); 347 } 348 }else{ 349 texture = pa.loadImage(basePath + tFile); 350 } 351 textureCache.put(tFile, texture); 352 }else{ 353 System.out.println("Trying to load obj texture from: " + basePath + tFile); 354 if (MT4jSettings.getInstance().isOpenGlMode()){ 355 PImage img = pa.loadImage(basePath + tFile); 356 if (Tools3D.isPowerOfTwoDimension(img)){ 357 texture = new GLTexture(pa, img, new GLTextureSettings(TEXTURE_TARGET.TEXTURE_2D, SHRINKAGE_FILTER.Trilinear, EXPANSION_FILTER.Bilinear, WRAP_MODE.REPEAT, WRAP_MODE.REPEAT)); 358 }else{ 359 texture = new GLTexture(pa, img, new GLTextureSettings(TEXTURE_TARGET.RECTANGULAR, SHRINKAGE_FILTER.Trilinear, EXPANSION_FILTER.Bilinear, WRAP_MODE.REPEAT, WRAP_MODE.REPEAT)); 360// ((GLTexture)texture).setFilter(SHRINKAGE_FILTER.BilinearNoMipMaps, EXPANSION_FILTER.Bilinear); 361 } 362 }else{ 363 texture = pa.loadImage(basePath + tFile); 364 } 365 textureCache.put(tFile, texture); 366 } 367 } 368 369// RgbFile f; 370// if (fromUrl) { 371// f = new RgbFile(new URL(basePath + tFile).openStream()); 372// } else { 373// f = new RgbFile(new FileInputStream(basePath + tFile)); 374// } 375// BufferedImage bi = f.getImage(); 376 377 boolean luminance = suffix.equals("int") || suffix.equals("inta"); 378 boolean alpha = suffix.equals("inta") || suffix.equals("rgba"); 379 cur.transparent = alpha; 380 381 String s = null; 382 if (luminance && alpha) s = "LUM8_ALPHA8"; 383 else if (luminance) s = "LUMINANCE"; 384 else if (alpha) s = "RGBA"; 385 else s = "RGB"; 386 387// t = new TextureLoader(bi, s, TextureLoader.GENERATE_MIPMAP); 388 } else { 389// tFile.toLowerCase(); 390// tFile.toLowerCase(Locale.ENGLISH); 391// basePath.toLowerCase(); 392 393 PImage cachedImage = textureCache.get(tFile); 394 if (cachedImage != null){ 395 texture = cachedImage; 396 //System.out.println("->Loaded texture from CACHE : \"" + tFile + "\""); 397 }else{ 398 File textureFile = new File(basePath + tFile); 399 if (textureFile.exists()){ 400 boolean success = textureFile.renameTo(new File(basePath + tFile)); 401 if (!success) { 402 // File was not successfully renamed 403 System.out.println("failed to RENAME file: " + textureFile.getAbsolutePath()); 404 } 405 406 if (MT4jSettings.getInstance().isOpenGlMode()){ 407 PImage img = pa.loadImage(basePath + tFile); 408 if (Tools3D.isPowerOfTwoDimension(img)){ 409 texture = new GLTexture(pa, img, new GLTextureSettings(TEXTURE_TARGET.TEXTURE_2D, SHRINKAGE_FILTER.Trilinear, EXPANSION_FILTER.Bilinear, WRAP_MODE.REPEAT, WRAP_MODE.REPEAT)); 410 }else{ 411 texture = new GLTexture(pa, img, new GLTextureSettings(TEXTURE_TARGET.RECTANGULAR, SHRINKAGE_FILTER.Trilinear, EXPANSION_FILTER.Bilinear, WRAP_MODE.REPEAT, WRAP_MODE.REPEAT)); 412// ((GLTexture)texture).setFilter(SHRINKAGE_FILTER.BilinearNoMipMaps, EXPANSION_FILTER.Bilinear); 413 } 414 }else{ 415 texture = pa.loadImage(basePath + tFile); 416 } 417 textureCache.put(tFile, texture); 418 }else{ 419 System.out.println("Trying to load obj texture from: " + basePath + tFile); 420 if (MT4jSettings.getInstance().isOpenGlMode()){ 421 PImage img = pa.loadImage(basePath + tFile); 422 if (Tools3D.isPowerOfTwoDimension(img)){ 423 texture = new GLTexture(pa, img, new GLTextureSettings(TEXTURE_TARGET.TEXTURE_2D, SHRINKAGE_FILTER.Trilinear, EXPANSION_FILTER.Bilinear, WRAP_MODE.REPEAT, WRAP_MODE.REPEAT)); 424 }else{ 425 texture = new GLTexture(pa, img, new GLTextureSettings(TEXTURE_TARGET.RECTANGULAR, SHRINKAGE_FILTER.Trilinear, EXPANSION_FILTER.Bilinear, WRAP_MODE.REPEAT, WRAP_MODE.REPEAT)); 426// ((GLTexture)texture).setFilter(SHRINKAGE_FILTER.BilinearNoMipMaps, EXPANSION_FILTER.Bilinear); 427 } 428 }else{ 429 texture = pa.loadImage(basePath + tFile); 430 } 431 textureCache.put(tFile, texture); 432 } 433 } 434 435// if (ConstantsAndSettings.getInstance().isOpenGlMode()){ 436// GLTexture glTex = new GLTexture(pa, basePath + tFile); 437// texture = glTex; 438// }else{ 439// texture = pa.loadImage(basePath + tFile); 440// } 441 442// // For all other file types, use the TextureLoader 443// if (fromUrl) { 444// t = new TextureLoader(new URL(basePath + tFile), "RGB", 445// TextureLoader.GENERATE_MIPMAP, null); 446// } else { 447// t = new TextureLoader(basePath + tFile, "RGB", 448// TextureLoader.GENERATE_MIPMAP, null); 449// } 450 } 451 452 453// Texture2D texture = (Texture2D)t.getTexture(); 454 455 456 if (texture != null) 457 cur.t = texture; 458 } 459 catch (Exception e) { 460 // Texture won't get loaded if file can't be found 461 e.printStackTrace(); 462 } 463// catch (MalformedURLException e) { 464// // Texture won't get loaded if file can't be found 465// } 466// catch (IOException e) { 467// // Texture won't get loaded if file can't be found 468// } 469 } 470 } 471 st.skipToNextLine(); 472 } // End of readMapKd 473 474 475 /** 476 * 477 * @param string 478 * @return 479 */ 480 public String toLowerCase(String string){ 481 char[] chars = new char[string.length()]; 482 for (int i = 0; i < chars.length; i++) { 483 char c = string.charAt(i); 484 c = Character.toLowerCase(c); 485 chars[i] = c; 486 } 487 return new String(chars); 488 } 489 490 public void readMapD(ObjectFileParser st) { 491 // Filenames are case sensitive 492 st.lowerCaseMode(false); 493 // Get name of texture file (skip path) 494 String tFile = ""; 495 496 do { 497 st.getToken(); 498// if (st.ttype == ObjectFileParser.TT_WORD){ 499// tFile += st.sval; 500// } 501 if (st.ttype != ObjectFileParser.TT_EOL ){ 502 tFile += st.sval; 503 } 504 }while (st.ttype != ObjectFileParser.TT_EOL); 505 506 st.lowerCaseMode(true); 507 508 if (!tFile.equals("")) { 509 PImage alphaMap; 510 // Check for filename with no extension 511 if (tFile.lastIndexOf('.') != -1) { 512 try { 513 // Convert filename to lower case for extension comparisons 514 String suffix = tFile.substring(tFile.lastIndexOf('.') + 1).toLowerCase(); 515 516 if ((suffix.equals("int")) || (suffix.equals("inta")) || 517 (suffix.equals("rgb")) || (suffix.equals("rgba")) || 518 (suffix.equals("bw")) || (suffix.equals("sgi")) 519 ) { 520 tFile = toLowerCase(tFile); 521 alphaMap = pa.loadImage(basePath + tFile); 522 } else { 523 tFile = toLowerCase(tFile); 524 alphaMap = pa.loadImage(basePath + tFile); 525 } 526 527 if (alphaMap != null){ 528 cur.d = alphaMap; 529 } 530 }catch (Exception e) { 531 // Texture won't get loaded if file can't be found 532 e.printStackTrace(); 533 } 534 } 535 } 536 st.skipToNextLine(); 537 } // End of readMapKd 538 539 540 /** 541 * 542 * @param st 543 * @throws ParsingErrorException 544 */ 545 private void readFile(ObjectFileParser st) throws ParsingErrorException { 546 int t; 547 st.getToken(); 548 while (st.ttype != ObjectFileParser.TT_EOF) { 549 550 // Print out one token for each line 551 if ((DEBUG & 16) != 0) { 552 System.out.print("Token "); 553 if (st.ttype == ObjectFileParser.TT_EOL) System.out.println("EOL"); 554 else if (st.ttype == ObjectFileParser.TT_WORD) 555 System.out.println(st.sval); 556 else System.out.println((char)st.ttype); 557 } 558 559 if (st.ttype == ObjectFileParser.TT_WORD) { 560 if (st.sval.equals("newmtl")) { 561 readName(st); 562 } else if (st.sval.equals("ka")) { 563 readAmbient(st); 564 } else if (st.sval.equals("kd")) { 565 readDiffuse(st); 566 } else if (st.sval.equals("ks")) { 567 readSpecular(st); 568 } else if (st.sval.equals("illum")) { 569 readIllum(st); 570 } else if (st.sval.equals("d")) { 571 readTransparency(st); 572 } else if (st.sval.equals("ns")) { 573 readShininess(st); 574 } else if (st.sval.equals("tf")) { 575 st.skipToNextLine(); 576 } else if (st.sval.equals("sharpness")) { 577 st.skipToNextLine(); 578 } else if (st.sval.equals("map_kd")) { 579 readMapKd(st); 580 } else if (st.sval.equals("map_ka")) { 581 st.skipToNextLine(); 582 } else if (st.sval.equals("map_ks")) { 583 st.skipToNextLine(); 584 } else if (st.sval.equals("map_ns")) { 585 st.skipToNextLine(); 586 } else if (st.sval.equals("bump")) { 587 st.skipToNextLine(); 588 }else if (st.sval.equals("map_d")) { 589 readMapD(st); 590 } 591 } 592 593 st.skipToNextLine(); 594 595 // Get next token 596 st.getToken(); 597 } 598 if (curName != null) materials.put(curName, cur); 599 } // End of readFile 600 601 602 /** 603 * 604 * @param basePath 605 * @param fileName 606 * @throws ParsingErrorException 607 */ 608 void readMaterialFile(String basePath, String fileName) throws ParsingErrorException { 609 Reader reader; 610 611 this.basePath = basePath; 612// this.fromUrl = fromUrl; 613 614 try { 615 if (fromUrl) { 616 reader = (Reader) 617 (new InputStreamReader( 618 new BufferedInputStream( 619 (new URL(basePath + fileName).openStream())))); 620 } else { 621 File f = new File(basePath+fileName); 622 if (f.exists()){ 623 reader = new BufferedReader(new FileReader(basePath + fileName)); 624 }else{ 625 InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(basePath + fileName); 626 if (stream == null){ 627 stream = pa.getClass().getResourceAsStream(basePath + fileName); 628 } 629 if (stream == null){ 630 throw new FileNotFoundException("File not found: " + basePath + fileName); 631 } 632 reader = new BufferedReader(new InputStreamReader(stream)); 633 } 634 635 } 636 } 637 catch (IOException e) { 638 // couldn't find it - ignore mtllib 639 e.printStackTrace(); 640 return; 641 } 642 if ((DEBUG & 1) != 0) 643 System.out.println("Material file: " + basePath + fileName); 644 645 ObjectFileParser st = new ObjectFileParser(reader); 646 readFile(st); 647 } // End of readMaterialFile 648 649 650 ObjectFileMaterials() throws ParsingErrorException { 651// Reader reader = new StringReader(DefaultMaterials.materials); 652// 653// ObjectFileParser st = new ObjectFileParser(reader); 654 materials = new HashMap(50); 655// readFile(st); 656 } // End of ObjectFileMaterials 657 658 659 /** 660 * Implement the ImageObserver interface. Needed to load jpeg and gif 661 * files using the Toolkit. 662 */ 663 public boolean imageUpdate(Image img, int flags, 664 int x, int y, int w, int h) { 665 666 return (flags & (ALLBITS | ABORT)) == 0; 667 } // End of imageUpdate 668 669} // End of class ObjectFileMaterials 670 671// End of file ObjectFileMaterials.java