* MTL loader now supports Blender shadeless materials
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7513 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
698c50d8fd
commit
b428d8ac48
@ -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(){
|
||||||
@ -77,14 +87,66 @@ public class MTLLoader implements AssetLoader {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void startMaterial(String name){
|
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 = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
|
||||||
material.setBoolean("UseMaterialColors", true);
|
material.setBoolean("UseMaterialColors", true);
|
||||||
material.setColor("Ambient", ColorRGBA.DarkGray);
|
material.setColor("Ambient", ambient);
|
||||||
material.setColor("Diffuse", ColorRGBA.White);
|
material.setColor("Diffuse", diffuse);
|
||||||
material.setColor("Specular", ColorRGBA.Black);
|
material.setColor("Specular", specular);
|
||||||
material.setFloat("Shininess", 16f); // prevents "premature culling" bug
|
material.setFloat("Shininess", shininess); // prevents "premature culling" bug
|
||||||
matList.put(name, material);
|
|
||||||
|
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){
|
||||||
|
if (matName != null){
|
||||||
|
// material is already in cache, generate it
|
||||||
|
createMaterial();
|
||||||
|
}
|
||||||
|
|
||||||
|
// now, reset the params and set the name to start a new 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,13 +72,17 @@ 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 final HashMap<Vertex, Integer> vertIndexMap = new HashMap<Vertex, Integer>();
|
protected String currentMatName;
|
||||||
protected final IntMap<Vertex> indexVertMap = new IntMap<Vertex>();
|
protected String currentObjectName;
|
||||||
|
|
||||||
|
protected final HashMap<Vertex, Integer> vertIndexMap = new HashMap<Vertex, Integer>(100);
|
||||||
|
protected final IntMap<Vertex> indexVertMap = new IntMap<Vertex>(100);
|
||||||
protected int curIndex = 0;
|
protected int curIndex = 0;
|
||||||
|
protected int objectIndex = 0;
|
||||||
protected int geomIndex = 0;
|
protected int geomIndex = 0;
|
||||||
|
|
||||||
protected Scanner scan;
|
protected Scanner scan;
|
||||||
@ -130,6 +135,35 @@ public final class OBJLoader implements AssetLoader {
|
|||||||
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();
|
||||||
texCoords.clear();
|
texCoords.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…
x
Reference in New Issue
Block a user