Quellcode durchsuchen

* Standardized handling for loading dependent assets for all loaders
If asset cannot be located, then the loader must replace the asset that
was supposed to be used with a placeholder, and raise a WARNING in the log
indicating that the asset cannot be located, containing both the name of the
dependent asset and the parent asset that is loading it

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8596 75d07b2b-3a1a-0410-a2c5-0572b91ccdca

sha..rd vor 14 Jahren
Ursprung
Commit
66127db26d

+ 25 - 33
engine/src/core-plugins/com/jme3/material/plugins/J3MLoader.java

@@ -41,6 +41,7 @@ import com.jme3.math.Vector2f;
 import com.jme3.math.Vector3f;
 import com.jme3.asset.AssetLoader;
 import com.jme3.asset.AssetManager;
+import com.jme3.asset.AssetNotFoundException;
 import com.jme3.asset.MaterialKey;
 import com.jme3.asset.TextureKey;
 import com.jme3.material.RenderState.BlendMode;
@@ -48,21 +49,23 @@ import com.jme3.material.RenderState.FaceCullMode;
 import com.jme3.material.TechniqueDef.LightMode;
 import com.jme3.material.TechniqueDef.ShadowMode;
 import com.jme3.shader.VarType;
-import com.jme3.texture.Image;
-import com.jme3.texture.Image.Format;
 import com.jme3.texture.Texture;
 import com.jme3.texture.Texture.WrapMode;
-import com.jme3.util.BufferUtils;
+import com.jme3.texture.Texture2D;
+import com.jme3.util.PlaceholderAssets;
 import java.io.IOException;
 import java.io.InputStream;
-import java.nio.ByteBuffer;
 import java.util.List;
 import com.jme3.util.blockparser.BlockLanguageParser;
 import com.jme3.util.blockparser.Statement;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 public class J3MLoader implements AssetLoader {
 
-    private AssetManager owner;
+    private static final Logger logger = Logger.getLogger(J3MLoader.class.getName());
+    
+    private AssetManager assetManager;
     private AssetKey key;
 
     private MaterialDef materialDef;
@@ -87,25 +90,6 @@ public class J3MLoader implements AssetLoader {
             throw new IOException("Expected '"+expected+"', got '"+got+"'!");
     }
 
-    private Image createColorTexture(ColorRGBA color){
-        if (color.getAlpha() == 1.0f){
-            // create RGB texture
-            ByteBuffer data = BufferUtils.createByteBuffer(3);
-            byte[] bytes = color.asBytesRGBA();
-            data.put(bytes[0]).put(bytes[1]).put(bytes[2]);
-            data.flip();
-
-            return new Image(Format.RGB8, 1, 1, data);
-        }else{
-            // create RGBA texture
-            ByteBuffer data = BufferUtils.createByteBuffer(4);
-            data.putInt(color.asIntRGBA());
-            data.flip();
-
-            return new Image(Format.RGBA8, 1, 1, data);
-        }
-    }
-
     // <TYPE> <LANG> : <SOURCE>
     private void readShaderStatement(String statement) throws IOException {
         String[] split = statement.split(":");
@@ -122,7 +106,6 @@ public class J3MLoader implements AssetLoader {
         }else if (typeAndLang[0].equals("FragmentShader")){
             fragName = split[1].trim();
         }
-        
     }
 
     // LightMode <MODE>
@@ -163,14 +146,23 @@ public class J3MLoader implements AssetLoader {
                 repeat = true;
             }
 
-            TextureKey key = new TextureKey(texturePath, flipY);
-            key.setAsCube(type == VarType.TextureCubeMap);
-            key.setGenerateMips(true);
+            TextureKey texKey = new TextureKey(texturePath, flipY);
+            texKey.setAsCube(type == VarType.TextureCubeMap);
+            texKey.setGenerateMips(true);
 
-            Texture tex = owner.loadTexture(key);
+            Texture tex;
+            try {
+                tex = assetManager.loadTexture(texKey);
+            } catch (AssetNotFoundException ex){
+                logger.log(Level.WARNING, "Cannot locate {0} for material {1}", new Object[]{texKey, key});
+                tex = null;
+            }
             if (tex != null){
-                if (repeat)
+                if (repeat){
                     tex.setWrap(WrapMode.Repeat);
+                }
+            }else{
+                tex = new Texture2D(PlaceholderAssets.getPlaceholderImage());
             }
             return tex;
         }else{
@@ -476,7 +468,7 @@ public class J3MLoader implements AssetLoader {
 
             String extendedMat = split[1].trim();
 
-            MaterialDef def = (MaterialDef) owner.loadAsset(new AssetKey(extendedMat));
+            MaterialDef def = (MaterialDef) assetManager.loadAsset(new AssetKey(extendedMat));
             if (def == null)
                 throw new IOException("Extended material "+extendedMat+" cannot be found.");
 
@@ -487,7 +479,7 @@ public class J3MLoader implements AssetLoader {
             if (extending){
                 throw new IOException("Expected ':', got '{'");
             }
-            materialDef = new MaterialDef(owner, materialName);
+            materialDef = new MaterialDef(assetManager, materialName);
             // NOTE: pass file name for defs so they can be loaded later
             materialDef.setAssetName(key.getName());
         }else{
@@ -518,7 +510,7 @@ public class J3MLoader implements AssetLoader {
     }
 
     public Object load(AssetInfo info) throws IOException {
-        this.owner = info.getManager();
+        this.assetManager = info.getManager();
 
         InputStream in = info.openStream();
         try {

+ 14 - 4
engine/src/core-plugins/com/jme3/scene/plugins/MTLLoader.java

@@ -33,8 +33,10 @@
 package com.jme3.scene.plugins;
 
 import com.jme3.asset.AssetInfo;
+import com.jme3.asset.AssetKey;
 import com.jme3.asset.AssetLoader;
 import com.jme3.asset.AssetManager;
+import com.jme3.asset.AssetNotFoundException;
 import com.jme3.asset.TextureKey;
 import com.jme3.material.Material;
 import com.jme3.material.MaterialList;
@@ -42,6 +44,8 @@ import com.jme3.material.RenderState.BlendMode;
 import com.jme3.math.ColorRGBA;
 import com.jme3.texture.Texture;
 import com.jme3.texture.Texture.WrapMode;
+import com.jme3.texture.Texture2D;
+import com.jme3.util.PlaceholderAssets;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
@@ -60,6 +64,7 @@ public class MTLLoader implements AssetLoader {
     //protected Material material;
     protected AssetManager assetManager;
     protected String folderName;
+    protected AssetKey key;
     
     protected Texture diffuseMap, normalMap, specularMap, alphaMap;
     protected ColorRGBA ambient = new ColorRGBA();
@@ -177,11 +182,15 @@ public class MTLLoader implements AssetLoader {
         path = split[split.length-1];
         
         String name = new File(path).getName();
-        TextureKey key = new TextureKey(folderName + name);
-        key.setGenerateMips(true);
-        Texture texture = assetManager.loadTexture(key);
-        if (texture != null){
+        TextureKey texKey = new TextureKey(folderName + name);
+        texKey.setGenerateMips(true);
+        Texture texture;
+        try {
+            texture = assetManager.loadTexture(texKey);
             texture.setWrap(WrapMode.Repeat);
+        } catch (AssetNotFoundException ex){
+            logger.log(Level.WARNING, "Cannot locate {0} for material {1}", new Object[]{texKey, key});
+            texture = new Texture2D(PlaceholderAssets.getPlaceholderImage());
         }
         return texture;
     }
@@ -288,6 +297,7 @@ public class MTLLoader implements AssetLoader {
     public Object load(AssetInfo info) throws IOException{
         reset();
         
+        this.key = info.getKey();
         this.assetManager = info.getManager();
         folderName = info.getKey().getFolder();
         matList = new MaterialList();

+ 4 - 5
engine/src/core-plugins/com/jme3/scene/plugins/OBJLoader.java

@@ -177,6 +177,7 @@ public final class OBJLoader implements AssetLoader {
         indexVertMap.clear();
 
         currentMatName = null;
+        matList = null;
         curIndex = 0;
         geomIndex = 0;
         scan = null;
@@ -324,10 +325,11 @@ public final class OBJLoader implements AssetLoader {
 
         // NOTE: Cut off any relative/absolute paths
         name = new File(name).getName();
+        AssetKey mtlKey = new AssetKey(key.getFolder() + name);
         try {
-            matList = (MaterialList) assetManager.loadAsset(key.getFolder() + name);
+            matList = (MaterialList) assetManager.loadAsset(mtlKey);
         } catch (AssetNotFoundException ex){
-            throw new AssetNotFoundException("Cannot load or find material " + name + " for model " + key.getName(), ex);
+            logger.log(Level.WARNING, "Cannot locate {0} for model {1}", new Object[]{name, key});
         }
 
         if (matList != null){
@@ -335,9 +337,6 @@ public final class OBJLoader implements AssetLoader {
             for (String matName : matList.keySet()){
                 matFaces.put(matName, new ArrayList<Face>());
             }
-        }else{
-            logger.log(Level.WARNING, "Can't find MTL file. " +
-                                      "Using default material for OBJ.");
         }
     }
 

+ 1 - 3
engine/src/core/com/jme3/asset/AssetKey.java

@@ -39,8 +39,6 @@ import com.jme3.export.OutputCapsule;
 import com.jme3.export.Savable;
 import java.io.IOException;
 import java.util.LinkedList;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 
 /**
  * <code>AssetKey</code> is a key that is used to
@@ -52,7 +50,7 @@ public class AssetKey<T> implements Savable {
     protected String name;
     protected transient String folder;
     protected transient String extension;
-
+    
     public AssetKey(String name){
         this.name = reducePath(name);
         this.extension = getExtension(this.name);

+ 0 - 1
engine/src/core/com/jme3/asset/ModelKey.java

@@ -47,7 +47,6 @@ public class ModelKey extends AssetKey<Spatial> {
     public ModelKey(){
         super();
     }
-
     @Override
     public boolean useSmartCache(){
         return true;

+ 10 - 1
engine/src/core/com/jme3/audio/AudioNode.java

@@ -33,13 +33,17 @@
 package com.jme3.audio;
 
 import com.jme3.asset.AssetManager;
+import com.jme3.asset.AssetNotFoundException;
 import com.jme3.export.InputCapsule;
 import com.jme3.export.JmeExporter;
 import com.jme3.export.JmeImporter;
 import com.jme3.export.OutputCapsule;
 import com.jme3.math.Vector3f;
 import com.jme3.scene.Node;
+import com.jme3.util.PlaceholderAssets;
 import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 /**
  * An <code>AudioNode</code> is used in jME3 for playing audio files.
@@ -775,7 +779,12 @@ public class AudioNode extends Node {
         positional = ic.readBoolean("positional", false);
         
         if (audioKey != null) {
-            data = im.getAssetManager().loadAudio(audioKey);
+            try {
+                data = im.getAssetManager().loadAudio(audioKey);
+            } catch (AssetNotFoundException ex){
+                Logger.getLogger(AudioNode.class.getName()).log(Level.FINE, "Cannot locate {0} for audio node {1}", new Object[]{audioKey, key});
+                data = PlaceholderAssets.getPlaceholderAudio();
+            }
         }
     }
 

+ 2 - 1
engine/src/core/com/jme3/scene/AssetLinkNode.java

@@ -171,7 +171,8 @@ public class AssetLinkNode extends Node {
                 children.add(child);
                 assetChildren.put(modelKey, child);
             } else {
-                Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "Could not load linked child spatial: {0}", modelKey.getName());
+                Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "Cannot locate {0} for asset link node {1}", 
+                                                                    new Object[]{ modelKey, key });
             }
         }
     }

+ 1 - 2
engine/src/core/com/jme3/scene/Geometry.java

@@ -541,8 +541,7 @@ public class Geometry extends Spatial {
                 material = im.getAssetManager().loadMaterial(matName);
             } catch (AssetNotFoundException ex) {
                 // Cannot find J3M file.
-                logger.log(Level.FINE, "Could not load J3M file {0} for Geometry.",
-                        matName);
+                logger.log(Level.FINE, "Cannot locate {0} for geometry {1}", new Object[]{matName, key});
             }
         }
         // If material is NULL, try to load it from the geometry

+ 8 - 5
engine/src/core/com/jme3/texture/Texture.java

@@ -34,12 +34,14 @@ package com.jme3.texture;
 
 import com.jme3.asset.Asset;
 import com.jme3.asset.AssetKey;
+import com.jme3.asset.AssetNotFoundException;
 import com.jme3.asset.TextureKey;
 import com.jme3.export.JmeExporter;
 import com.jme3.export.JmeImporter;
 import com.jme3.export.InputCapsule;
 import com.jme3.export.OutputCapsule;
 import com.jme3.export.Savable;
+import com.jme3.util.PlaceholderAssets;
 import java.io.IOException;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -588,11 +590,12 @@ public abstract class Texture implements Asset, Savable, Cloneable {
         // load texture from key, if available
         if (key != null) {
             // key is available, so try the texture from there.
-            Texture loadedTex = e.getAssetManager().loadTexture(key);
-            if (loadedTex == null) {
-                Logger.getLogger(Texture.class.getName()).log(Level.SEVERE, "Could not load texture: {0}", key.toString());
-            } else {
+            try {
+                Texture loadedTex = e.getAssetManager().loadTexture(key);
                 image = loadedTex.getImage();
+            } catch (AssetNotFoundException ex){
+                Logger.getLogger(Texture.class.getName()).log(Level.SEVERE, "Cannot locate texture {0}", key);
+                image = PlaceholderAssets.getPlaceholderImage();
             }
         }else{
             // no key is set on the texture. Attempt to load an embedded image
@@ -600,7 +603,7 @@ public abstract class Texture implements Asset, Savable, Cloneable {
             if (image == null){
                 // TODO: what to print out here? the texture has no key or data, there's no useful information .. 
                 // assume texture.name is set even though the key is null
-                Logger.getLogger(Texture.class.getName()).log(Level.SEVERE, "Could not load embedded image: {0}", toString() );
+                Logger.getLogger(Texture.class.getName()).log(Level.SEVERE, "Cannot load embedded image {0}", toString() );
             }
         }
 

+ 72 - 0
engine/src/core/com/jme3/util/PlaceholderAssets.java

@@ -0,0 +1,72 @@
+package com.jme3.util;
+
+import com.jme3.asset.AssetManager;
+import com.jme3.audio.AudioBuffer;
+import com.jme3.audio.AudioData;
+import com.jme3.texture.Image;
+import com.jme3.texture.Image.Format;
+import com.jme3.material.Material;
+import com.jme3.math.ColorRGBA;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Spatial;
+import com.jme3.scene.shape.Box;
+import java.nio.ByteBuffer;
+
+public class PlaceholderAssets {
+    
+    /**
+     * Checkerboard of white and red squares
+     */
+    private static final byte[] imageData = {
+        (byte)0xFF, (byte)0xFF, (byte)0xFF,
+        (byte)0xFF, (byte)0x00, (byte)0x00,
+        (byte)0xFF, (byte)0xFF, (byte)0xFF,
+        (byte)0xFF, (byte)0x00, (byte)0x00,
+        
+        (byte)0xFF, (byte)0x00, (byte)0x00,
+        (byte)0xFF, (byte)0xFF, (byte)0xFF,
+        (byte)0xFF, (byte)0x00, (byte)0x00,
+        (byte)0xFF, (byte)0xFF, (byte)0xFF,
+        
+        (byte)0xFF, (byte)0xFF, (byte)0xFF,
+        (byte)0xFF, (byte)0x00, (byte)0x00,
+        (byte)0xFF, (byte)0xFF, (byte)0xFF,
+        (byte)0xFF, (byte)0x00, (byte)0x00,
+        
+        (byte)0xFF, (byte)0x00, (byte)0x00,
+        (byte)0xFF, (byte)0xFF, (byte)0xFF,
+        (byte)0xFF, (byte)0x00, (byte)0x00,
+        (byte)0xFF, (byte)0xFF, (byte)0xFF,
+    };
+    
+    public static Image getPlaceholderImage(){
+        ByteBuffer tempData = BufferUtils.createByteBuffer(3 * 4 * 4);
+        tempData.put(imageData).flip();
+        return new Image(Format.RGB8, 4, 4, tempData);
+    }
+    
+    public static Material getPlaceholderMaterial(AssetManager assetManager){
+        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
+        mat.setColor("Color", ColorRGBA.Red);
+        return mat;
+    }
+    
+    public static Spatial getPlaceholderModel(AssetManager assetManager){
+        // What should be the size? Nobody knows
+        // the user's expected scale...
+        Box box = new Box(1, 1, 1);
+        Geometry geom = new Geometry("placeholder", box);
+        geom.setMaterial(getPlaceholderMaterial(assetManager));
+        return geom;
+    }
+    
+    public static AudioData getPlaceholderAudio(){
+        AudioBuffer audioBuf = new AudioBuffer();
+        audioBuf.setupFormat(1, 8, 44100);
+        ByteBuffer bb = BufferUtils.createByteBuffer(1);
+        bb.put((byte)0).flip();
+        audioBuf.updateData(bb);
+        return audioBuf;
+    }
+    
+}

+ 17 - 23
engine/src/ogre/com/jme3/scene/plugins/ogre/MaterialLoader.java

@@ -45,17 +45,14 @@ import com.jme3.math.ColorRGBA;
 import com.jme3.scene.plugins.ogre.matext.MaterialExtensionLoader;
 import com.jme3.scene.plugins.ogre.matext.MaterialExtensionSet;
 import com.jme3.scene.plugins.ogre.matext.OgreMaterialKey;
-import com.jme3.texture.Image;
-import com.jme3.texture.Image.Format;
 import com.jme3.texture.Texture;
 import com.jme3.texture.Texture.WrapMode;
 import com.jme3.texture.Texture2D;
-import com.jme3.util.BufferUtils;
+import com.jme3.util.PlaceholderAssets;
 import com.jme3.util.blockparser.BlockLanguageParser;
 import com.jme3.util.blockparser.Statement;
 import java.io.IOException;
 import java.io.InputStream;
-import java.nio.ByteBuffer;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Scanner;
@@ -137,23 +134,13 @@ public class MaterialLoader implements AssetLoader {
             cubic = true;
         }
 
-        TextureKey key = new TextureKey(folderName + path, false);
-        key.setGenerateMips(genMips);
-        key.setAsCube(cubic);
+        TextureKey texKey = new TextureKey(folderName + path, false);
+        texKey.setGenerateMips(genMips);
+        texKey.setAsCube(cubic);
 
-        Texture loadedTexture;
         try {
-            loadedTexture = assetManager.loadTexture(key);
-        } catch (AssetNotFoundException ex){
-            logger.log(Level.WARNING, "Failed to load texture " + key + " for material " + matName, ex);
-            loadedTexture = null;
-        }
-        if (loadedTexture == null){
-            ByteBuffer tempData = BufferUtils.createByteBuffer(3);
-            tempData.put((byte)0xFF).put((byte)0x00).put((byte)0x00);
-            textures[texUnit].setImage(new Image(Format.RGB8, 1,1,tempData));
-            logger.log(Level.WARNING, "Using RED texture instead of {0}", path);
-        }else{
+            Texture loadedTexture = assetManager.loadTexture(texKey);
+            
             textures[texUnit].setImage(loadedTexture.getImage());
             textures[texUnit].setMinFilter(loadedTexture.getMinFilter());
             textures[texUnit].setKey(loadedTexture.getKey());
@@ -164,8 +151,11 @@ public class MaterialLoader implements AssetLoader {
                 textures[texUnit].setName(texName);
                 texName = null;
             }else{
-                textures[texUnit].setName(key.getName());
+                textures[texUnit].setName(texKey.getName());
             }
+        } catch (AssetNotFoundException ex){
+            logger.log(Level.WARNING, "Cannot locate {0} for material {1}", new Object[]{texKey, matName});
+            textures[texUnit].setImage(PlaceholderAssets.getPlaceholderImage());
         }
     }
 
@@ -344,12 +334,16 @@ public class MaterialLoader implements AssetLoader {
             rs.setAlphaTest(true);
             rs.setAlphaFallOff(0.01f);
             rs.setBlendMode(RenderState.BlendMode.Alpha);
-            if (twoSide)
+            
+            if (twoSide){
                 rs.setFaceCullMode(RenderState.FaceCullMode.Off);
+            }
+            
 //            rs.setDepthWrite(false);
             mat.setTransparent(true);
-            if (!noLight)
+            if (!noLight){
                 mat.setBoolean("UseAlpha", true);
+            }
         }else{
             if (twoSide){
                 RenderState rs = mat.getAdditionalRenderState();
@@ -452,7 +446,7 @@ public class MaterialLoader implements AssetLoader {
                                           "Ogre3D materials with extended materials");
                 }
 
-                list = new MaterialExtensionLoader().load(assetManager, matExts, statements);
+                list = new MaterialExtensionLoader().load(assetManager, key, matExts, statements);
                 break;
             }else if (statement.getLine().startsWith("material")){
                 if (list == null){

+ 18 - 11
engine/src/ogre/com/jme3/scene/plugins/ogre/MeshLoader.java

@@ -55,6 +55,7 @@ import com.jme3.scene.VertexBuffer.Usage;
 import com.jme3.util.BufferUtils;
 import com.jme3.util.IntMap;
 import com.jme3.util.IntMap.Entry;
+import com.jme3.util.PlaceholderAssets;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.nio.Buffer;
@@ -97,6 +98,7 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
         Type.TexCoord6,
         Type.TexCoord7,
         Type.TexCoord8,};
+    private AssetKey key;
     private String meshName;
     private String folderName;
     private AssetManager assetManager;
@@ -201,19 +203,20 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
         Material mat = null;
         if (matName.endsWith(".j3m")) {
             // load as native jme3 material instance
-            mat = assetManager.loadMaterial(matName);
+            try {
+                mat = assetManager.loadMaterial(matName);
+            } catch (AssetNotFoundException ex){
+                // Warning will be raised (see below)
+            }
         } else {
             if (materialList != null) {
                 mat = materialList.get(matName);
             }
-            if (mat == null) {
-                logger.log(Level.WARNING, "Material {0} not found. Applying default material", matName);
-                mat = (Material) assetManager.loadMaterial("Common/Materials/RedColor.j3m");
-            }
         }
-
+        
         if (mat == null) {
-            throw new RuntimeException("Cannot locate material named " + matName);
+            logger.log(Level.WARNING, "Cannot locate {0} for model {1}", new Object[]{matName, key});
+            mat = PlaceholderAssets.getPlaceholderMaterial(assetManager);
         }
 
         if (mat.isTransparent()) {
@@ -550,7 +553,13 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
     }
 
     private void startSkeleton(String name) {
-        animData = (AnimData) assetManager.loadAsset(folderName + name + ".xml");
+        AssetKey assetKey = new AssetKey(folderName + name + ".xml");
+        try {
+            animData = (AnimData) assetManager.loadAsset(assetKey);
+        } catch (AssetNotFoundException ex){
+            logger.log(Level.WARNING, "Cannot locate {0} for model {1}", new Object[]{assetKey, key});
+            animData = null;
+        }
     }
 
     private void startSubmeshName(String indexStr, String nameStr) {
@@ -780,7 +789,7 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
 
     public Object load(AssetInfo info) throws IOException {
         try {
-            AssetKey key = info.getKey();
+            key = info.getKey();
             meshName = key.getName();
             folderName = key.getFolder();
             String ext = key.getExtension();
@@ -804,7 +813,6 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
                         materialList = (MaterialList) assetManager.loadAsset(materialKey);
                     } catch (AssetNotFoundException e) {
                         logger.log(Level.WARNING, "Cannot locate {0} for model {1}", new Object[]{materialKey, key});
-                        logger.log(Level.WARNING, "", e);
                     }
                 }
             }
@@ -818,7 +826,6 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
                     materialList = (MaterialList) assetManager.loadAsset(materialKey);
                 } catch (AssetNotFoundException e) {
                     logger.log(Level.WARNING, "Cannot locate {0} for model {1}", new Object[]{ materialKey, key });
-                    logger.log(Level.WARNING, "", e);
                 }
             }
             

+ 28 - 18
engine/src/ogre/com/jme3/scene/plugins/ogre/SceneLoader.java

@@ -32,6 +32,7 @@
 
 package com.jme3.scene.plugins.ogre;
 
+import com.jme3.asset.AssetKey;
 import com.jme3.scene.plugins.ogre.matext.OgreMaterialKey;
 import com.jme3.material.MaterialList;
 import com.jme3.asset.AssetInfo;
@@ -42,11 +43,10 @@ import com.jme3.light.DirectionalLight;
 import com.jme3.light.Light;
 import com.jme3.light.PointLight;
 import com.jme3.light.SpotLight;
-import com.jme3.math.FastMath;
 import com.jme3.math.Quaternion;
 import com.jme3.math.Vector3f;
-import com.jme3.scene.Node;
 import com.jme3.scene.Spatial;
+import com.jme3.util.PlaceholderAssets;
 import com.jme3.util.xml.SAXUtil;
 import java.io.IOException;
 import java.io.InputStreamReader;
@@ -70,13 +70,14 @@ public class SceneLoader extends DefaultHandler implements AssetLoader {
     private static final Logger logger = Logger.getLogger(SceneLoader.class.getName());
 
     private Stack<String> elementStack = new Stack<String>();
+    private AssetKey key;
     private String sceneName;
     private String folderName;
     private AssetManager assetManager;
     private MaterialList materialList;
-    private Node root;
-    private Node node;
-    private Node entityNode;
+    private com.jme3.scene.Node root;
+    private com.jme3.scene.Node node;
+    private com.jme3.scene.Node entityNode;
     private Light light;
     private int nodeIdx = 0;
     private static volatile int sceneIdx = 0;
@@ -248,9 +249,9 @@ public class SceneLoader extends DefaultHandler implements AssetLoader {
                 throw new SAXException("dotScene parse error: nodes element was specified twice");
             }
             if (sceneName == null)
-                root = new Node("OgreDotScene"+(++sceneIdx));
+                root = new com.jme3.scene.Node("OgreDotScene"+(++sceneIdx));
             else
-                root = new Node(sceneName+"-scene_node");
+                root = new com.jme3.scene.Node(sceneName+"-scene_node");
             
             node = root;
         }else if (qName.equals("externals")){
@@ -283,7 +284,7 @@ public class SceneLoader extends DefaultHandler implements AssetLoader {
             if (name == null)
                 name = "OgreNode-" + (++nodeIdx);
 
-            Node newNode = new Node(name);
+            com.jme3.scene.Node newNode = new com.jme3.scene.Node(name);
             if (node != null){
                 node.attachChild(newNode);
             }
@@ -327,11 +328,17 @@ public class SceneLoader extends DefaultHandler implements AssetLoader {
             // NOTE: append "xml" since its assumed mesh files are binary in dotScene
             meshFile += ".xml";
             
-            entityNode = new Node(name);
-            OgreMeshKey key = new OgreMeshKey(meshFile, materialList);
-            Spatial ogreMesh = assetManager.loadModel(key);
+            entityNode = new com.jme3.scene.Node(name);
+            OgreMeshKey meshKey = new OgreMeshKey(meshFile, materialList);
+            try {
+                Spatial ogreMesh = assetManager.loadModel(meshKey);
+                entityNode.attachChild(ogreMesh);
+            } catch (AssetNotFoundException ex){
+                logger.log(Level.WARNING, "Cannot locate {0} for scene {1}", new Object[]{meshKey, key});
+                // Attach placeholder asset.
+                entityNode.attachChild(PlaceholderAssets.getPlaceholderModel(assetManager));
+            }
             
-            entityNode.attachChild(ogreMesh);
             node.attachChild(entityNode);
             node = null;
         }else if (qName.equals("position")){
@@ -409,19 +416,22 @@ public class SceneLoader extends DefaultHandler implements AssetLoader {
     public void characters(char ch[], int start, int length) {
     }
 
+    
+    
     public Object load(AssetInfo info) throws IOException {
         try{
+            key = info.getKey();
             assetManager = info.getManager();
-            sceneName = info.getKey().getName();
-            String ext = info.getKey().getExtension();
-            folderName = info.getKey().getFolder();
+            sceneName = key.getName();
+            String ext = key.getExtension();
+            folderName = key.getFolder();
             sceneName = sceneName.substring(0, sceneName.length() - ext.length() - 1);
 
+            OgreMaterialKey materialKey = new OgreMaterialKey(sceneName+".material");
             try {
-                materialList = (MaterialList) 
-                      assetManager.loadAsset(new OgreMaterialKey(sceneName+".material"));
+                materialList = (MaterialList) assetManager.loadAsset(materialKey);
             } catch (AssetNotFoundException ex){
-                logger.log(Level.WARNING, "Cannot locate material file {0}", ex.getMessage());
+                logger.log(Level.WARNING, "Cannot locate {0} for scene {1}", new Object[]{materialKey, key});
                 materialList = null;
             }
 

+ 21 - 10
engine/src/ogre/com/jme3/scene/plugins/ogre/matext/MaterialExtensionLoader.java

@@ -32,17 +32,20 @@
 
 package com.jme3.scene.plugins.ogre.matext;
 
+import com.jme3.asset.AssetKey;
 import com.jme3.asset.AssetManager;
+import com.jme3.asset.AssetNotFoundException;
 import com.jme3.asset.TextureKey;
 import com.jme3.material.Material;
 import com.jme3.material.MaterialList;
 import com.jme3.scene.plugins.ogre.MaterialLoader;
 import com.jme3.texture.Texture;
 import com.jme3.texture.Texture.WrapMode;
+import com.jme3.texture.Texture2D;
+import com.jme3.util.PlaceholderAssets;
 import com.jme3.util.blockparser.Statement;
 import java.io.IOException;
 import java.util.List;
-import java.util.Scanner;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -53,6 +56,7 @@ public class MaterialExtensionLoader {
 
     private static final Logger logger = Logger.getLogger(MaterialExtensionLoader.class.getName());
 
+    private AssetKey key;
     private AssetManager assetManager;
     private MaterialList list;
     private MaterialExtensionSet matExts;
@@ -60,6 +64,7 @@ public class MaterialExtensionLoader {
     private String matName;
     private Material material;
 
+    
     private void readExtendingMaterialStatement(Statement statement) throws IOException {
         if (statement.getLine().startsWith("set_texture_alias")){
             String[] split = statement.getLine().split(" ", 3);
@@ -68,14 +73,19 @@ public class MaterialExtensionLoader {
 
             String jmeParamName = matExt.getTextureMapping(aliasName);
 
-            TextureKey key = new TextureKey(texturePath, false);
-            key.setGenerateMips(true);
-            key.setAsCube(false);
-            Texture tex = assetManager.loadTexture(key);
-            if (tex == null)
-                throw new IOException("Cannot load texture: " + texturePath);
-            tex.setWrap(WrapMode.Repeat);
-
+            TextureKey texKey = new TextureKey(texturePath, false);
+            texKey.setGenerateMips(true);
+            texKey.setAsCube(false);
+            Texture tex;
+            
+            try {
+                tex = assetManager.loadTexture(texKey);
+                tex.setWrap(WrapMode.Repeat);
+            } catch (AssetNotFoundException ex){
+                logger.log(Level.WARNING, "Cannot locate {0} for material {1}", new Object[]{texKey, key});
+                tex = new Texture2D( PlaceholderAssets.getPlaceholderImage() );
+            }
+            
             material.setTexture(jmeParamName, tex);
         }
     }
@@ -100,10 +110,11 @@ public class MaterialExtensionLoader {
         return material;
     }
 
-    public MaterialList load(AssetManager assetManager, MaterialExtensionSet matExts,
+    public MaterialList load(AssetManager assetManager, AssetKey key, MaterialExtensionSet matExts,
             List<Statement> statements) throws IOException{
         this.assetManager = assetManager;
         this.matExts = matExts;
+        this.key = key;
         
         list = new MaterialList();