From 66127db26d3280c2865d5cda84612c122c61e371 Mon Sep 17 00:00:00 2001 From: "sha..rd" Date: Tue, 8 Nov 2011 04:51:58 +0000 Subject: [PATCH] * 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 --- .../com/jme3/material/plugins/J3MLoader.java | 58 +++++++-------- .../com/jme3/scene/plugins/MTLLoader.java | 18 +++-- .../com/jme3/scene/plugins/OBJLoader.java | 9 ++- engine/src/core/com/jme3/asset/AssetKey.java | 4 +- engine/src/core/com/jme3/asset/ModelKey.java | 1 - engine/src/core/com/jme3/audio/AudioNode.java | 11 ++- .../core/com/jme3/scene/AssetLinkNode.java | 3 +- engine/src/core/com/jme3/scene/Geometry.java | 3 +- engine/src/core/com/jme3/texture/Texture.java | 13 ++-- .../core/com/jme3/util/PlaceholderAssets.java | 72 +++++++++++++++++++ .../scene/plugins/ogre/MaterialLoader.java | 40 +++++------ .../jme3/scene/plugins/ogre/MeshLoader.java | 29 +++++--- .../jme3/scene/plugins/ogre/SceneLoader.java | 46 +++++++----- .../ogre/matext/MaterialExtensionLoader.java | 31 +++++--- 14 files changed, 221 insertions(+), 117 deletions(-) create mode 100644 engine/src/core/com/jme3/util/PlaceholderAssets.java diff --git a/engine/src/core-plugins/com/jme3/material/plugins/J3MLoader.java b/engine/src/core-plugins/com/jme3/material/plugins/J3MLoader.java index 4e427e5d2..702e4e761 100644 --- a/engine/src/core-plugins/com/jme3/material/plugins/J3MLoader.java +++ b/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); - } - } - // : 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 @@ -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 { diff --git a/engine/src/core-plugins/com/jme3/scene/plugins/MTLLoader.java b/engine/src/core-plugins/com/jme3/scene/plugins/MTLLoader.java index 10cd23683..bebb72411 100644 --- a/engine/src/core-plugins/com/jme3/scene/plugins/MTLLoader.java +++ b/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(); diff --git a/engine/src/core-plugins/com/jme3/scene/plugins/OBJLoader.java b/engine/src/core-plugins/com/jme3/scene/plugins/OBJLoader.java index 7c02dd512..8854ec1d9 100644 --- a/engine/src/core-plugins/com/jme3/scene/plugins/OBJLoader.java +++ b/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()); } - }else{ - logger.log(Level.WARNING, "Can't find MTL file. " + - "Using default material for OBJ."); } } diff --git a/engine/src/core/com/jme3/asset/AssetKey.java b/engine/src/core/com/jme3/asset/AssetKey.java index e06b0e82e..955128682 100644 --- a/engine/src/core/com/jme3/asset/AssetKey.java +++ b/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; /** * AssetKey is a key that is used to @@ -52,7 +50,7 @@ public class AssetKey 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); diff --git a/engine/src/core/com/jme3/asset/ModelKey.java b/engine/src/core/com/jme3/asset/ModelKey.java index dcf87c3a0..fcf5c5399 100644 --- a/engine/src/core/com/jme3/asset/ModelKey.java +++ b/engine/src/core/com/jme3/asset/ModelKey.java @@ -47,7 +47,6 @@ public class ModelKey extends AssetKey { public ModelKey(){ super(); } - @Override public boolean useSmartCache(){ return true; diff --git a/engine/src/core/com/jme3/audio/AudioNode.java b/engine/src/core/com/jme3/audio/AudioNode.java index 47917cd59..fe8d312a0 100644 --- a/engine/src/core/com/jme3/audio/AudioNode.java +++ b/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 AudioNode 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(); + } } } diff --git a/engine/src/core/com/jme3/scene/AssetLinkNode.java b/engine/src/core/com/jme3/scene/AssetLinkNode.java index ca0068228..cfc477830 100644 --- a/engine/src/core/com/jme3/scene/AssetLinkNode.java +++ b/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 }); } } } diff --git a/engine/src/core/com/jme3/scene/Geometry.java b/engine/src/core/com/jme3/scene/Geometry.java index 927571910..2b99aff91 100644 --- a/engine/src/core/com/jme3/scene/Geometry.java +++ b/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 diff --git a/engine/src/core/com/jme3/texture/Texture.java b/engine/src/core/com/jme3/texture/Texture.java index f6bf17a0f..9ad7c2eee 100644 --- a/engine/src/core/com/jme3/texture/Texture.java +++ b/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() ); } } diff --git a/engine/src/core/com/jme3/util/PlaceholderAssets.java b/engine/src/core/com/jme3/util/PlaceholderAssets.java new file mode 100644 index 000000000..2bf8dbb3f --- /dev/null +++ b/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; + } + +} diff --git a/engine/src/ogre/com/jme3/scene/plugins/ogre/MaterialLoader.java b/engine/src/ogre/com/jme3/scene/plugins/ogre/MaterialLoader.java index 4b4f115a9..aeb8eca8a 100644 --- a/engine/src/ogre/com/jme3/scene/plugins/ogre/MaterialLoader.java +++ b/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){ diff --git a/engine/src/ogre/com/jme3/scene/plugins/ogre/MeshLoader.java b/engine/src/ogre/com/jme3/scene/plugins/ogre/MeshLoader.java index ba1a8f158..261ed5204 100644 --- a/engine/src/ogre/com/jme3/scene/plugins/ogre/MeshLoader.java +++ b/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); } } diff --git a/engine/src/ogre/com/jme3/scene/plugins/ogre/SceneLoader.java b/engine/src/ogre/com/jme3/scene/plugins/ogre/SceneLoader.java index a4d9576f7..0794f0a31 100644 --- a/engine/src/ogre/com/jme3/scene/plugins/ogre/SceneLoader.java +++ b/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 elementStack = new Stack(); + 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; } diff --git a/engine/src/ogre/com/jme3/scene/plugins/ogre/matext/MaterialExtensionLoader.java b/engine/src/ogre/com/jme3/scene/plugins/ogre/matext/MaterialExtensionLoader.java index ff70f9cd3..d497d51c1 100644 --- a/engine/src/ogre/com/jme3/scene/plugins/ogre/matext/MaterialExtensionLoader.java +++ b/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 statements) throws IOException{ this.assetManager = assetManager; this.matExts = matExts; + this.key = key; list = new MaterialList();