/*
|
* $RCSf ObjectFileMaterials.java,v $
|
*
|
* Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
|
*
|
* Redistribution and use in source and binary forms, with or without
|
* modification, are permitted provided that the following conditions
|
* are
|
*
|
* - Redistribution of source code must retain the above copyright
|
* notice, this list of conditions and the following disclaimer.
|
*
|
* - Redistribution in binary form must reproduce the above copyright
|
* notice, this list of conditions and the following disclaimer in
|
* the documentation and/or other materials provided with the
|
* distribution.
|
*
|
* Neither the name of Sun Microsystems, Inc. or the names of
|
* contributors may be used to endorse or promote products derived
|
* from this software without specific prior written permission.
|
*
|
* This software is provided "AS IS," without a warranty of any
|
* kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
|
* WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
|
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
|
* EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
|
* NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
|
* USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
|
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
|
* ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
|
* CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
|
* REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
|
* INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
|
* POSSIBILITY OF SUCH DAMAGES.
|
*
|
* You acknowledge that this software is not designed, licensed or
|
* intended for use in the design, construction, operation or
|
* maintenance of any nuclear facility.
|
*
|
* $Revis 1.6 $
|
* $D 2007/02/0920:10 $
|
* $St Exp $
|
*/
|
|
//package com.sun.j3d.loaders.objectfile;
|
import javax.media.j3d.Appearance;
|
import javax.media.j3d.Material;
|
import javax.media.j3d.Shape3D;
|
import javax.vecmath.Color3f;
|
import com.sun.j3d.loaders.ParsingErrorException;
|
import com.sun.j3d.loaders.IncorrectFormatException;
|
import java.io.FileNotFoundException;
|
import java.io.StringReader;
|
import java.io.Reader;
|
import java.io.FileReader;
|
import java.io.BufferedReader;
|
import java.io.BufferedInputStream;
|
import java.io.InputStreamReader;
|
import java.io.IOException;
|
import java.io.FileInputStream;
|
import java.util.HashMap;
|
//import com.sun.j3d.loaders.objectfile.DefaultMaterials;
|
import java.net.URL;
|
import java.net.MalformedURLException;
|
import java.awt.Toolkit;
|
import java.awt.Image;
|
import java.awt.image.BufferedImage;
|
import javax.media.j3d.Texture2D;
|
import java.awt.image.ImageObserver;
|
import java.awt.image.PixelGrabber;
|
import java.awt.image.DataBufferInt;
|
import javax.media.j3d.ImageComponent2D;
|
import javax.media.j3d.TexCoordGeneration;
|
import java.security.AccessController;
|
import java.security.PrivilegedAction;
|
import javax.media.j3d.GeometryArray;
|
import com.sun.j3d.utils.image.TextureLoader;
|
import javax.media.j3d.TransparencyAttributes;
|
|
class ObjectFileMaterials implements ImageObserver
|
{
|
// DEBUG
|
// 1 = Name of materials
|
// 16 = Tokens
|
private static final int DEBUG = 17;
|
private String curName = null;
|
private ObjectFileMaterial cur = null;
|
private HashMap materials; // key=String name of material
|
// value=ObjectFileMaterial
|
private String basePath;
|
private boolean fromUrl;
|
|
private class ObjectFileMaterial
|
{
|
|
public Color3f Ka;
|
public Color3f Kd;
|
public Color3f Ks;
|
public int illum;
|
public float Ns;
|
public Texture2D t;
|
public boolean transparent;
|
public float transparencyLevel;
|
public String map_kd;
|
public String map_bump;
|
}
|
|
void assignMaterial(String matName, Shape3D shape)
|
{
|
ObjectFileMaterial p = null;
|
|
if ((DEBUG & 1) != 0)
|
{
|
System.out.println("Color " + matName);
|
}
|
|
Material m = new Material();
|
p = (ObjectFileMaterial) materials.get(matName);
|
if (p != null)
|
m.setUserData(p.map_kd);
|
Appearance a = new Appearance();
|
|
if (p != null)
|
{
|
// Set ambient & diffuse color
|
if (p.Ka != null)
|
{
|
m.setAmbientColor(p.Ka);
|
}
|
if (p.Kd != null)
|
{
|
m.setDiffuseColor(p.Kd);
|
}
|
|
// Set specular color
|
if ((p.Ks != null) && (p.illum != 1))
|
{
|
m.setSpecularColor(p.Ks);
|
} else if (p.illum == 1)
|
{
|
m.setSpecularColor(0.0f, 0.0f, 0.0f);
|
}
|
|
if (p.illum >= 1)
|
{
|
m.setLightingEnable(true);
|
} else if (p.illum == 0)
|
{
|
m.setLightingEnable(false);
|
}
|
|
if (p.Ns != -1.0f)
|
{
|
m.setShininess(p.Ns);
|
}
|
|
if (p.t != null)
|
{
|
a.setTexture(p.t);
|
// Create Texture Coordinates if not already present
|
if ((((GeometryArray) shape.getGeometry()).getVertexFormat() & GeometryArray.TEXTURE_COORDINATE_2) == 0)
|
{
|
TexCoordGeneration tcg = new TexCoordGeneration();
|
a.setTexCoordGeneration(tcg);
|
}
|
}
|
|
if (p.transparent)
|
{
|
a.setTransparencyAttributes(new TransparencyAttributes(
|
TransparencyAttributes.NICEST,
|
p.transparencyLevel));
|
}
|
}
|
a.setMaterial(m);
|
if (p != null)
|
a.setUserData(p.map_bump);
|
if ((DEBUG & 1) != 0)
|
{
|
System.out.println(m);
|
}
|
shape.setAppearance(a);
|
} // End of assignMaterial
|
|
private void readName(ObjectFileParser st)
|
throws ParsingErrorException
|
{
|
st.getToken();
|
|
if (st.ttype == ObjectFileParser.TT_WORD)
|
{
|
|
if (curName != null)
|
{
|
materials.put(curName, cur);
|
}
|
curName = new String(st.sval);
|
cur = new ObjectFileMaterial();
|
}
|
st.skipToNextLine();
|
} // End of readName
|
|
private void readAmbient(ObjectFileParser st)
|
throws ParsingErrorException
|
{
|
Color3f p = new Color3f();
|
|
st.getNumber();
|
p.x = (float) st.nval;
|
st.getNumber();
|
p.y = (float) st.nval;
|
st.getNumber();
|
p.z = (float) st.nval;
|
|
cur.Ka = p;
|
|
st.skipToNextLine();
|
} // End of readAmbient
|
|
private void readDiffuse(ObjectFileParser st)
|
throws ParsingErrorException
|
{
|
Color3f p = new Color3f();
|
|
st.getNumber();
|
p.x = (float) st.nval;
|
st.getNumber();
|
p.y = (float) st.nval;
|
st.getNumber();
|
p.z = (float) st.nval;
|
|
cur.Kd = p;
|
|
st.skipToNextLine();
|
} // End of readDiffuse
|
|
private void readSpecular(ObjectFileParser st)
|
throws ParsingErrorException
|
{
|
Color3f p = new Color3f();
|
|
st.getNumber();
|
p.x = (float) st.nval;
|
st.getNumber();
|
p.y = (float) st.nval;
|
st.getNumber();
|
p.z = (float) st.nval;
|
|
cur.Ks = p;
|
|
st.skipToNextLine();
|
} // End of readSpecular
|
|
private void readIllum(ObjectFileParser st)
|
throws ParsingErrorException
|
{
|
|
st.getNumber();
|
cur.illum = (int) st.nval;
|
|
st.skipToNextLine();
|
} // End of readSpecular
|
|
private void readTransparency(ObjectFileParser st)
|
throws ParsingErrorException
|
{
|
|
st.getNumber();
|
cur.transparencyLevel = (float) st.nval;
|
if (cur.transparencyLevel < 1.0f)
|
{
|
cur.transparent = true;
|
}
|
st.skipToNextLine();
|
} // End of readTransparency
|
|
private void readShininess(ObjectFileParser st)
|
throws ParsingErrorException
|
{
|
float f;
|
|
st.getNumber();
|
cur.Ns = (float) st.nval;
|
if (cur.Ns < 1.0f)
|
{
|
cur.Ns = 1.0f;
|
} else if (cur.Ns > 128.0f)
|
{
|
cur.Ns = 128.0f;
|
}
|
|
st.skipToNextLine();
|
} // End of readSpecular
|
|
public void readMapBump(ObjectFileParser st)
|
{
|
// Filenames are case sensitive
|
st.lowerCaseMode(false);
|
|
// Get name of texture file (skip path)
|
String tFile = null;
|
do
|
{
|
st.getToken();
|
if (st.ttype == ObjectFileParser.TT_WORD)
|
{
|
tFile = st.sval;
|
}
|
} while (st.ttype != ObjectFileParser.TT_EOL);
|
|
st.lowerCaseMode(true);
|
|
if ((DEBUG & 1) != 0)
|
{
|
System.out.println(tFile);
|
}
|
|
cur.map_bump = tFile;
|
}
|
|
public void readMapKd(ObjectFileParser st)
|
{
|
// Filenames are case sensitive
|
st.lowerCaseMode(false);
|
|
// Get name of texture file (skip path)
|
String tFile = null;
|
do
|
{
|
st.getToken();
|
if (st.ttype == ObjectFileParser.TT_WORD)
|
{
|
tFile = st.sval;
|
}
|
} while (st.ttype != ObjectFileParser.TT_EOL);
|
|
st.lowerCaseMode(true);
|
|
if ((DEBUG & 1) != 0)
|
{
|
System.out.println(tFile);
|
}
|
|
cur.map_kd = tFile;
|
|
if (false) // tFile != null)
|
{
|
// Check for filename with no extension
|
if (tFile.lastIndexOf('.') != -1)
|
{
|
try
|
{
|
// Convert filename to lower case for extension comparisons
|
String suffix = tFile.substring(
|
tFile.lastIndexOf('.') + 1).toLowerCase();
|
|
TextureLoader t = null;
|
|
if ((suffix.equals("int")) || (suffix.equals("inta")) || (suffix.equals("rgb")) || (suffix.equals("rgba")) || (suffix.equals("bw")) || (suffix.equals("sgi")))
|
{
|
RgbFile f;
|
if (fromUrl)
|
{
|
f = new RgbFile(new URL(basePath + tFile).openStream());
|
} else
|
{
|
f = new RgbFile(new FileInputStream(
|
basePath + tFile));
|
}
|
BufferedImage bi = f.getImage();
|
|
boolean luminance = suffix.equals("int") || suffix.equals("inta");
|
boolean alpha = suffix.equals("inta") || suffix.equals("rgba");
|
cur.transparent = alpha;
|
|
String s = null;
|
if (luminance && alpha)
|
{
|
s = "LUM8_ALPHA8";
|
} else if (luminance)
|
{
|
s = "LUMINANCE";
|
} else if (alpha)
|
{
|
s = "RGBA";
|
} else
|
{
|
s = "RGB";
|
}
|
|
t = new TextureLoader(bi, s,
|
TextureLoader.GENERATE_MIPMAP);
|
} else
|
{
|
// For all other file types, use the TextureLoader
|
if (fromUrl)
|
{
|
t = new TextureLoader(new URL(basePath + tFile), "RGB",
|
TextureLoader.GENERATE_MIPMAP, null);
|
} else
|
{
|
t = new TextureLoader(basePath + tFile,
|
"RGB",
|
TextureLoader.GENERATE_MIPMAP, null);
|
}
|
}
|
Texture2D texture = (Texture2D) t.getTexture();
|
if (texture != null)
|
{
|
cur.t = texture;
|
}
|
} catch (FileNotFoundException e)
|
{
|
// Texture won't get loaded if file can't be found
|
} catch (MalformedURLException e)
|
{
|
// Texture won't get loaded if file can't be found
|
} catch (IOException e)
|
{
|
// Texture won't get loaded if file can't be found
|
}
|
}
|
}
|
st.skipToNextLine();
|
} // End of readMapKd
|
|
private void readFile(ObjectFileParser st)
|
throws ParsingErrorException
|
{
|
int t;
|
st.getToken();
|
while (st.ttype != ObjectFileParser.TT_EOF)
|
{
|
|
// Print out one token for each line
|
if ((DEBUG & 16) != 0)
|
{
|
System.out.print("Token ");
|
if (st.ttype == ObjectFileParser.TT_EOL)
|
{
|
System.out.println("EOL");
|
} else if (st.ttype == ObjectFileParser.TT_WORD)
|
{
|
System.out.println(st.sval);
|
} else
|
{
|
System.out.println((char) st.ttype);
|
}
|
}
|
|
if (st.ttype == ObjectFileParser.TT_WORD)
|
{
|
if (st.sval.equals("newmtl"))
|
{
|
readName(st);
|
} else if (st.sval.equals("ka"))
|
{
|
readAmbient(st);
|
} else if (st.sval.equals("kd"))
|
{
|
readDiffuse(st);
|
} else if (st.sval.equals("ks"))
|
{
|
readSpecular(st);
|
} else if (st.sval.equals("illum"))
|
{
|
readIllum(st);
|
} else if (st.sval.equals("d"))
|
{
|
readTransparency(st);
|
} else if (st.sval.equals("ns"))
|
{
|
readShininess(st);
|
} else if (st.sval.equals("tf"))
|
{
|
st.skipToNextLine();
|
} else if (st.sval.equals("sharpness"))
|
{
|
st.skipToNextLine();
|
} else if (st.sval.equals("map_kd"))
|
{
|
readMapKd(st);
|
} else if (st.sval.equals("map_ka"))
|
{
|
st.skipToNextLine();
|
} else if (st.sval.equals("map_ks"))
|
{
|
st.skipToNextLine();
|
} else if (st.sval.equals("map_ns"))
|
{
|
st.skipToNextLine();
|
} else if (st.sval.equals("map_bump"))
|
{
|
readMapBump(st);
|
//st.skipToNextLine();
|
}
|
}
|
|
st.skipToNextLine();
|
|
// Get next token
|
st.getToken();
|
}
|
if (curName != null)
|
{
|
materials.put(curName, cur);
|
}
|
} // End of readFile
|
|
void readMaterialFile(boolean fromUrl, String basePath,
|
String fileName) throws ParsingErrorException
|
{
|
|
Reader reader;
|
|
this.basePath = basePath;
|
this.fromUrl = fromUrl;
|
|
try
|
{
|
if (fromUrl)
|
{
|
reader = (Reader) (new InputStreamReader(
|
new BufferedInputStream((new URL(basePath + fileName).openStream()))));
|
} else
|
{
|
reader = new BufferedReader(new FileReader(basePath + fileName));
|
}
|
} catch (IOException e)
|
{
|
// couldn't find it - ignore mtllib
|
return;
|
}
|
if ((DEBUG & 1) != 0)
|
{
|
System.out.println("Material f " + basePath + fileName);
|
}
|
|
ObjectFileParser st = new ObjectFileParser(reader);
|
readFile(st);
|
} // End of readMaterialFile
|
|
ObjectFileMaterials() throws ParsingErrorException
|
{
|
Reader reader = new StringReader(DefaultMaterials.materials);
|
|
ObjectFileParser st = new ObjectFileParser(reader);
|
materials = new HashMap(50);
|
readFile(st);
|
} // End of ObjectFileMaterials
|
|
/**
|
* Implement the ImageObserver interface. Needed to load jpeg and gif
|
* files using the Toolkit.
|
*/
|
public boolean imageUpdate(Image img, int flags, int x, int y,
|
int w, int h)
|
{
|
|
return (flags & (ALLBITS | ABORT)) == 0;
|
} // End of imageUpdate
|
} // End of class ObjectFileMaterials
|
|
// End of file ObjectFileMaterials.java
|