* MTL loader now supports Blender shadeless materials

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7513 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
Sha..rd 14 years ago
parent 698c50d8fd
commit b428d8ac48
  1. 166
      engine/src/core-plugins/com/jme3/scene/plugins/MTLLoader.java
  2. 46
      engine/src/core-plugins/com/jme3/scene/plugins/OBJLoader.java

@ -36,12 +36,10 @@ import com.jme3.asset.AssetInfo;
import com.jme3.asset.AssetLoader; import com.jme3.asset.AssetLoader;
import com.jme3.asset.AssetManager; import com.jme3.asset.AssetManager;
import com.jme3.asset.TextureKey; import com.jme3.asset.TextureKey;
import com.jme3.material.MatParam;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.material.MaterialList; import com.jme3.material.MaterialList;
import com.jme3.material.RenderState.BlendMode; import com.jme3.material.RenderState.BlendMode;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
import com.jme3.texture.Image.Format;
import com.jme3.texture.Texture; import com.jme3.texture.Texture;
import com.jme3.texture.Texture.WrapMode; import com.jme3.texture.Texture.WrapMode;
import java.io.File; import java.io.File;
@ -54,14 +52,26 @@ public class MTLLoader implements AssetLoader {
protected Scanner scan; protected Scanner scan;
protected MaterialList matList; protected MaterialList matList;
protected Material material; //protected Material material;
protected AssetManager assetManager; protected AssetManager assetManager;
protected String folderName; protected String folderName;
protected Texture diffuseMap, normalMap, specularMap, alphaMap;
protected ColorRGBA ambient = new ColorRGBA();
protected ColorRGBA diffuse = new ColorRGBA();
protected ColorRGBA specular = new ColorRGBA();
protected float shininess = 16;
protected boolean shadeless;
protected String matName;
protected float alpha = 1;
protected boolean transparent = false;
public void reset(){ public void reset(){
scan = null; scan = null;
matList = null; matList = null;
material = null; // material = null;
resetMaterial();
} }
protected ColorRGBA readColor(){ protected ColorRGBA readColor(){
@ -76,15 +86,67 @@ public class MTLLoader implements AssetLoader {
scan.useDelimiter("\\p{javaWhitespace}+"); scan.useDelimiter("\\p{javaWhitespace}+");
return result; return result;
} }
protected void resetMaterial(){
ambient.set(ColorRGBA.Black);
diffuse.set(ColorRGBA.Black);
specular.set(ColorRGBA.Black);
shininess = 16;
shadeless = false;
transparent = false;
matName = null;
diffuseMap = null;
specularMap = null;
normalMap = null;
alphaMap = null;
alpha = 1;
}
protected void createMaterial(){
Material material;
if (alpha < 1f){
diffuse.a = alpha;
}
if (shadeless){
material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", diffuse);
material.setTexture("ColorMap", diffuseMap);
// TODO: Add handling for alpha map?
}else{
material = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
material.setBoolean("UseMaterialColors", true);
material.setColor("Ambient", ambient);
material.setColor("Diffuse", diffuse);
material.setColor("Specular", specular);
material.setFloat("Shininess", shininess); // prevents "premature culling" bug
if (diffuseMap != null) material.setTexture("DiffuseMap", diffuseMap);
if (specularMap != null) material.setTexture("SpecularMap", specularMap);
if (normalMap != null) material.setTexture("NormalMap", normalMap);
if (alphaMap != null) material.setTexture("AlphaMap", alphaMap);
}
if (transparent){
material.setTransparent(true);
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
material.getAdditionalRenderState().setAlphaTest(true);
material.getAdditionalRenderState().setAlphaFallOff(0.01f);
}
matList.put(matName, material);
}
protected void startMaterial(String name){ protected void startMaterial(String name){
material = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); if (matName != null){
material.setBoolean("UseMaterialColors", true); // material is already in cache, generate it
material.setColor("Ambient", ColorRGBA.DarkGray); createMaterial();
material.setColor("Diffuse", ColorRGBA.White); }
material.setColor("Specular", ColorRGBA.Black);
material.setFloat("Shininess", 16f); // prevents "premature culling" bug // now, reset the params and set the name to start a new material
matList.put(name, material); resetMaterial();
matName = name;
} }
protected Texture loadTexture(String path){ protected Texture loadTexture(String path){
@ -116,95 +178,56 @@ public class MTLLoader implements AssetLoader {
String name = scan.next(); String name = scan.next();
startMaterial(name); startMaterial(name);
}else if (cmd.equals("ka")){ }else if (cmd.equals("ka")){
material.setColor("Ambient", readColor()); ambient.set(readColor());
}else if (cmd.equals("kd")){ }else if (cmd.equals("kd")){
ColorRGBA color = readColor(); diffuse.set(readColor());
MatParam param = material.getParam("Diffuse");
if (param != null){
color.a = ((ColorRGBA) param.getValue()).getAlpha();
}
material.setColor("Diffuse", color);
}else if (cmd.equals("ks")){ }else if (cmd.equals("ks")){
material.setColor("Specular", readColor()); specular.set(readColor());
}else if (cmd.equals("ns")){ }else if (cmd.equals("ns")){
material.setFloat("Shininess", scan.nextFloat() /* (128f / 1000f)*/ ); shininess = scan.nextFloat(); /* (128f / 1000f)*/
}else if (cmd.equals("d") || cmd.equals("tr")){ }else if (cmd.equals("d") || cmd.equals("tr")){
float alpha = scan.nextFloat(); alpha = scan.nextFloat();
if (alpha < 1f){ transparent = true;
MatParam param = material.getParam("Diffuse");
ColorRGBA color;
if (param != null)
color = (ColorRGBA) param.getValue();
else
color = new ColorRGBA(ColorRGBA.White);
color.a = alpha;
material.setColor("Diffuse", color);
material.setTransparent(true);
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
}
}else if (cmd.equals("map_ka")){ }else if (cmd.equals("map_ka")){
// ignore it for now // ignore it for now
nextStatement(); nextStatement();
}else if (cmd.equals("map_kd")){ }else if (cmd.equals("map_kd")){
String path = nextStatement(); String path = nextStatement();
material.setTexture("DiffuseMap", loadTexture(path)); diffuseMap = loadTexture(path);
}else if (cmd.equals("map_bump") || cmd.equals("bump")){ }else if (cmd.equals("map_bump") || cmd.equals("bump")){
if (material.getParam("NormalMap") == null){ if (normalMap == null){
String path = nextStatement(); String path = nextStatement();
Texture texture = loadTexture(path); normalMap = loadTexture(path);
if (texture != null){
material.setTexture("NormalMap", texture);
if (texture.getImage().getFormat() == Format.LATC){
material.setBoolean("LATC", true);
}
}
} }
}else if (cmd.equals("map_ks")){ }else if (cmd.equals("map_ks")){
String path = nextStatement(); String path = nextStatement();
Texture texture = loadTexture(path); specularMap = loadTexture(path);
if (texture != null){ if (specularMap != null){
material.setTexture("SpecularMap", texture);
// NOTE: since specular color is modulated with specmap // NOTE: since specular color is modulated with specmap
// make sure we have it set // make sure we have it set
MatParam specParam = material.getParam("Specular"); if (specular.equals(ColorRGBA.Black)){
if (specParam == null){ specular.set(ColorRGBA.White);
material.setColor("Specular", ColorRGBA.White);
}else{
ColorRGBA spec = (ColorRGBA) specParam.getValue();
if (spec.equals(ColorRGBA.Black)){
material.setColor("Specular", ColorRGBA.White);
}
} }
} }
}else if (cmd.equals("map_d")){ }else if (cmd.equals("map_d")){
String path = scan.next(); String path = scan.next();
Texture texture = loadTexture(path); alphaMap = loadTexture(path);
if (texture != null){ transparent = true;
material.setTexture("AlphaMap", texture);
material.setTransparent(true);
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
material.getAdditionalRenderState().setAlphaTest(true);
material.getAdditionalRenderState().setAlphaFallOff(0.01f);
}
}else if (cmd.equals("illum")){ }else if (cmd.equals("illum")){
int mode = scan.nextInt(); int mode = scan.nextInt();
switch (mode){ switch (mode){
case 0: case 0:
// no ambient // no lighting
material.setColor("Ambient", ColorRGBA.Black); shadeless = true;
break; break;
case 4: case 4:
case 6: case 6:
case 7: case 7:
case 9: case 9:
// Enable transparency // Enable transparency
material.setTransparent(true);
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
// Works best if diffuse map has an alpha channel // Works best if diffuse map has an alpha channel
transparent = true;
break; break;
} }
}else if (cmd.equals("ke") || cmd.equals("ni")){ }else if (cmd.equals("ke") || cmd.equals("ni")){
@ -230,6 +253,13 @@ public class MTLLoader implements AssetLoader {
matList = new MaterialList(); matList = new MaterialList();
while (readLine()); while (readLine());
if (matName != null){
// still have a material in the vars
createMaterial();
resetMaterial();
}
MaterialList list = matList; MaterialList list = matList;
reset(); reset();

@ -43,6 +43,7 @@ import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh; import com.jme3.scene.Mesh;
import com.jme3.scene.Mesh.Mode; import com.jme3.scene.Mesh.Mode;
import com.jme3.scene.Node; import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.VertexBuffer; import com.jme3.scene.VertexBuffer;
import com.jme3.scene.mesh.IndexBuffer; import com.jme3.scene.mesh.IndexBuffer;
import com.jme3.scene.mesh.IndexIntBuffer; import com.jme3.scene.mesh.IndexIntBuffer;
@ -71,14 +72,18 @@ public final class OBJLoader implements AssetLoader {
protected final ArrayList<Vector3f> verts = new ArrayList<Vector3f>(); protected final ArrayList<Vector3f> verts = new ArrayList<Vector3f>();
protected final ArrayList<Vector2f> texCoords = new ArrayList<Vector2f>(); protected final ArrayList<Vector2f> texCoords = new ArrayList<Vector2f>();
protected final ArrayList<Vector3f> norms = new ArrayList<Vector3f>(); protected final ArrayList<Vector3f> norms = new ArrayList<Vector3f>();
protected final ArrayList<Face> faces = new ArrayList<Face>(); protected final ArrayList<Face> faces = new ArrayList<Face>();
protected final HashMap<String, ArrayList<Face>> matFaces = new HashMap<String, ArrayList<Face>>(); protected final HashMap<String, ArrayList<Face>> matFaces = new HashMap<String, ArrayList<Face>>();
protected String currentMatName; protected String currentMatName;
protected String currentObjectName;
protected final HashMap<Vertex, Integer> vertIndexMap = new HashMap<Vertex, Integer>(); protected final HashMap<Vertex, Integer> vertIndexMap = new HashMap<Vertex, Integer>(100);
protected final IntMap<Vertex> indexVertMap = new IntMap<Vertex>(); protected final IntMap<Vertex> indexVertMap = new IntMap<Vertex>(100);
protected int curIndex = 0; protected int curIndex = 0;
protected int geomIndex = 0; protected int objectIndex = 0;
protected int geomIndex = 0;
protected Scanner scan; protected Scanner scan;
protected ModelKey key; protected ModelKey key;
@ -125,10 +130,39 @@ public final class OBJLoader implements AssetLoader {
return hash; return hash;
} }
} }
protected static class Face { protected static class Face {
Vertex[] verticies; Vertex[] verticies;
} }
protected class ObjectGroup {
final String objectName;
public ObjectGroup(String objectName){
this.objectName = objectName;
}
public Spatial createGeometry(){
Node groupNode = new Node(objectName);
// if (matFaces.size() > 0){
// for (Entry<String, ArrayList<Face>> entry : matFaces.entrySet()){
// ArrayList<Face> materialFaces = entry.getValue();
// if (materialFaces.size() > 0){
// Geometry geom = createGeometry(materialFaces, entry.getKey());
// objNode.attachChild(geom);
// }
// }
// }else if (faces.size() > 0){
// // generate final geometry
// Geometry geom = createGeometry(faces, null);
// objNode.attachChild(geom);
// }
return groupNode;
}
}
public void reset(){ public void reset(){
verts.clear(); verts.clear();
@ -351,7 +385,7 @@ public final class OBJLoader implements AssetLoader {
} }
protected Geometry createGeometry(ArrayList<Face> faceList, String matName) throws IOException{ protected Geometry createGeometry(ArrayList<Face> faceList, String matName) throws IOException{
if (faceList.size() == 0) if (faceList.isEmpty())
throw new IOException("No geometry data to generate mesh"); throw new IOException("No geometry data to generate mesh");
// Create mesh from the faces // Create mesh from the faces

Loading…
Cancel
Save