diff --git a/jme3-android/src/main/java/com/jme3/asset/AndroidAssetManager.java b/jme3-android/src/main/java/com/jme3/asset/AndroidAssetManager.java deleted file mode 100644 index 9873a8476..000000000 --- a/jme3-android/src/main/java/com/jme3/asset/AndroidAssetManager.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2009-2012 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.jme3.asset; - -import com.jme3.asset.plugins.AndroidLocator; -import com.jme3.asset.plugins.ClasspathLocator; -import com.jme3.audio.plugins.AndroidAudioLoader; -import com.jme3.audio.plugins.NativeVorbisLoader; -import com.jme3.audio.plugins.WAVLoader; -import com.jme3.system.AppSettings; -import com.jme3.system.android.JmeAndroidSystem; -import com.jme3.texture.plugins.AndroidBufferImageLoader; -import com.jme3.texture.plugins.AndroidNativeImageLoader; -import java.net.URL; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * AndroidAssetManager is an implementation of DesktopAssetManager for Android - * - * @author larynx - */ -public class AndroidAssetManager extends DesktopAssetManager { - - private static final Logger logger = Logger.getLogger(AndroidAssetManager.class.getName()); - - private void registerLoaderSafe(String loaderClass, String ... extensions) { - try { - Class loader = (Class) Class.forName(loaderClass); - registerLoader(loader, extensions); - } catch (Exception e){ - logger.log(Level.WARNING, "Failed to load AssetLoader", e); - } - } - - /** - * AndroidAssetManager constructor - * If URL == null then a default list of locators and loaders for android is set - * @param configFile - */ - public AndroidAssetManager(URL configFile) { - System.setProperty("org.xml.sax.driver", "org.xmlpull.v1.sax2.Driver"); - - // Set Default Android config - registerLocator("", AndroidLocator.class); - registerLocator("", ClasspathLocator.class); - - registerLoader(AndroidNativeImageLoader.class, "jpg", "jpeg", "bmp", "gif", "png"); - - if (JmeAndroidSystem.getAudioRendererType().equals(AppSettings.ANDROID_MEDIAPLAYER)) { - registerLoader(AndroidAudioLoader.class, "ogg", "mp3", "wav"); - } else if (JmeAndroidSystem.getAudioRendererType().equals(AppSettings.ANDROID_OPENAL_SOFT)) { - registerLoader(WAVLoader.class, "wav"); - registerLoader(NativeVorbisLoader.class, "ogg"); - } else { - throw new IllegalStateException("No Audio Renderer Type defined!"); - } - - registerLoader(com.jme3.material.plugins.J3MLoader.class, "j3m"); - registerLoader(com.jme3.material.plugins.J3MLoader.class, "j3md"); - registerLoader(com.jme3.material.plugins.ShaderNodeDefinitionLoader.class, "j3sn"); - registerLoader(com.jme3.shader.plugins.GLSLLoader.class, "vert", "frag", "glsl", "glsllib"); - registerLoader(com.jme3.export.binary.BinaryImporter.class, "j3o"); - registerLoader(com.jme3.font.plugins.BitmapFontLoader.class, "fnt"); - - // Less common loaders (especially on Android) - registerLoaderSafe("com.jme3.texture.plugins.DDSLoader", "dds"); - registerLoaderSafe("com.jme3.texture.plugins.PFMLoader", "pfm"); - registerLoaderSafe("com.jme3.texture.plugins.HDRLoader", "hdr"); - registerLoaderSafe("com.jme3.texture.plugins.TGALoader", "tga"); - registerLoaderSafe("com.jme3.scene.plugins.OBJLoader", "obj"); - registerLoaderSafe("com.jme3.scene.plugins.MTLLoader", "mtl"); - registerLoaderSafe("com.jme3.scene.plugins.ogre.MeshLoader", "mesh.xml"); - registerLoaderSafe("com.jme3.scene.plugins.ogre.SkeletonLoader", "skeleton.xml"); - registerLoaderSafe("com.jme3.scene.plugins.ogre.MaterialLoader", "material"); - registerLoaderSafe("com.jme3.scene.plugins.ogre.SceneLoader", "scene"); - - - logger.fine("AndroidAssetManager created."); - } - -} diff --git a/jme3-android/src/main/java/com/jme3/asset/AndroidImageInfo.java b/jme3-android/src/main/java/com/jme3/asset/AndroidImageInfo.java index b509f9f4d..8d064f5fe 100644 --- a/jme3-android/src/main/java/com/jme3/asset/AndroidImageInfo.java +++ b/jme3-android/src/main/java/com/jme3/asset/AndroidImageInfo.java @@ -20,6 +20,7 @@ import java.util.logging.Logger; * * @author Kirill Vainer */ +@Deprecated public class AndroidImageInfo extends ImageRaster { private static final Logger logger = Logger.getLogger(AndroidImageInfo.class.getName()); diff --git a/jme3-android/src/main/java/com/jme3/system/android/JmeAndroidSystem.java b/jme3-android/src/main/java/com/jme3/system/android/JmeAndroidSystem.java index c2dfa7b17..fc6ef7683 100644 --- a/jme3-android/src/main/java/com/jme3/system/android/JmeAndroidSystem.java +++ b/jme3-android/src/main/java/com/jme3/system/android/JmeAndroidSystem.java @@ -6,9 +6,6 @@ import android.graphics.Bitmap; import android.os.Environment; import android.view.View; import android.view.inputmethod.InputMethodManager; -import com.jme3.asset.AndroidAssetManager; -import com.jme3.asset.AndroidImageInfo; -import com.jme3.asset.AssetManager; import com.jme3.audio.AudioRenderer; import com.jme3.audio.android.AndroidAL; import com.jme3.audio.android.AndroidALC; @@ -19,14 +16,10 @@ import com.jme3.audio.openal.ALC; import com.jme3.audio.openal.EFX; import com.jme3.system.*; import com.jme3.system.JmeContext.Type; -import com.jme3.texture.Image; -import com.jme3.texture.image.DefaultImageRaster; -import com.jme3.texture.image.ImageRaster; import com.jme3.util.AndroidScreenshots; import java.io.File; import java.io.IOException; import java.io.OutputStream; -import java.net.URL; import java.nio.ByteBuffer; import java.util.logging.Level; @@ -41,6 +34,11 @@ public class JmeAndroidSystem extends JmeSystemDelegate { } catch (UnsatisfiedLinkError e) { } } + + @Override + public String getPlatformAssetConfigPath() { + return "com/jme3/asset/Android.cfg"; + } @Override public void writeImageFile(OutputStream outStream, String format, ByteBuffer imageData, int width, int height) throws IOException { @@ -58,27 +56,6 @@ public class JmeAndroidSystem extends JmeSystemDelegate { bitmapImage.recycle(); } - @Override - public ImageRaster createImageRaster(Image image, int slice) { - if (image.getEfficentData() != null) { - return (AndroidImageInfo) image.getEfficentData(); - } else { - return new DefaultImageRaster(image, slice); - } - } - - @Override - public AssetManager newAssetManager(URL configFile) { - logger.log(Level.FINE, "Creating asset manager with config {0}", configFile); - return new AndroidAssetManager(configFile); - } - - @Override - public AssetManager newAssetManager() { - logger.log(Level.FINE, "Creating asset manager with default config"); - return new AndroidAssetManager(null); - } - @Override public void showErrorDialog(String message) { final String finalMsg = message; @@ -122,21 +99,6 @@ public class JmeAndroidSystem extends JmeSystemDelegate { AL al = new AndroidAL(); EFX efx = new AndroidEFX(); return new ALAudioRenderer(al, alc, efx); -/* - if (settings.getAudioRenderer().equals(AppSettings.ANDROID_MEDIAPLAYER)) { - logger.log(Level.INFO, "newAudioRenderer settings set to Android MediaPlayer / SoundPool"); - audioRendererType = AppSettings.ANDROID_MEDIAPLAYER; - return new AndroidMediaPlayerAudioRenderer(activity); - } else if (settings.getAudioRenderer().equals(AppSettings.ANDROID_OPENAL_SOFT)) { - logger.log(Level.INFO, "newAudioRenderer settings set to Android OpenAL Soft"); - audioRendererType = AppSettings.ANDROID_OPENAL_SOFT; - return new AndroidMediaPlayerAudioRenderer(activity); - } else { - logger.log(Level.INFO, "AudioRenderer not set. Defaulting to Android MediaPlayer / SoundPool"); - audioRendererType = AppSettings.ANDROID_MEDIAPLAYER; - return new AndroidMediaPlayerAudioRenderer(activity); - } -*/ } @Override @@ -145,6 +107,7 @@ public class JmeAndroidSystem extends JmeSystemDelegate { return; } initialized = true; + System.setProperty("org.xml.sax.driver", "org.xmlpull.v1.sax2.Driver"); logger.log(Level.INFO, getBuildInfo()); } diff --git a/jme3-android/src/main/java/com/jme3/texture/plugins/AndroidBufferImageLoader.java b/jme3-android/src/main/java/com/jme3/texture/plugins/AndroidBufferImageLoader.java index 33bcb369e..bf2abb7a4 100644 --- a/jme3-android/src/main/java/com/jme3/texture/plugins/AndroidBufferImageLoader.java +++ b/jme3-android/src/main/java/com/jme3/texture/plugins/AndroidBufferImageLoader.java @@ -50,6 +50,7 @@ import java.nio.ByteBuffer; * * @author Kirill Vainer */ +@Deprecated public class AndroidBufferImageLoader implements AssetLoader { private final byte[] tempData = new byte[16 * 1024]; diff --git a/jme3-android/src/main/java/com/jme3/texture/plugins/AndroidImageLoader.java b/jme3-android/src/main/java/com/jme3/texture/plugins/AndroidImageLoader.java index 739e031de..f3c1464a2 100644 --- a/jme3-android/src/main/java/com/jme3/texture/plugins/AndroidImageLoader.java +++ b/jme3-android/src/main/java/com/jme3/texture/plugins/AndroidImageLoader.java @@ -8,6 +8,7 @@ import com.jme3.texture.Image; import com.jme3.texture.image.ColorSpace; import java.io.IOException; +@Deprecated public class AndroidImageLoader implements AssetLoader { public Object load(AssetInfo info) throws IOException { diff --git a/jme3-android/src/main/resources/com/jme3/asset/Android.cfg b/jme3-android/src/main/resources/com/jme3/asset/Android.cfg new file mode 100644 index 000000000..b793e9f0f --- /dev/null +++ b/jme3-android/src/main/resources/com/jme3/asset/Android.cfg @@ -0,0 +1,8 @@ +INCLUDE com/jme3/asset/General.cfg + +# Android specific locators +LOCATOR / com.jme3.asset.plugins.AndroidLocator + +# Android specific loaders +LOADER com.jme3.texture.plugins.AndroidNativeImageLoader : jpg, bmp, gif, png, jpeg +LOADER com.jme3.audio.plugins.NativeVorbisLoader : ogg diff --git a/jme3-core/src/main/java/com/jme3/animation/AnimControl.java b/jme3-core/src/main/java/com/jme3/animation/AnimControl.java index 615fe2fd8..13328cddf 100644 --- a/jme3-core/src/main/java/com/jme3/animation/AnimControl.java +++ b/jme3-core/src/main/java/com/jme3/animation/AnimControl.java @@ -56,12 +56,12 @@ import java.util.Map.Entry; * 4) Animation event listeners * 5) Animated model cloning * 6) Animated model binary import/export + * 7) Hardware skinning + * 8) Attachments + * 9) Add/remove skins * * Planned: - * 1) Hardware skinning - * 2) Morph/Pose animation - * 3) Attachments - * 4) Add/remove skins + * 1) Morph/Pose animation * * @author Kirill Vainer */ diff --git a/jme3-core/src/main/java/com/jme3/app/Application.java b/jme3-core/src/main/java/com/jme3/app/Application.java index 8c05f2b18..2bcd6a4d9 100644 --- a/jme3-core/src/main/java/com/jme3/app/Application.java +++ b/jme3-core/src/main/java/com/jme3/app/Application.java @@ -174,28 +174,30 @@ public class Application implements SystemListener { } private void initAssetManager(){ + URL assetCfgUrl = null; + if (settings != null){ String assetCfg = settings.getString("AssetConfigURL"); if (assetCfg != null){ - URL url = null; try { - url = new URL(assetCfg); + assetCfgUrl = new URL(assetCfg); } catch (MalformedURLException ex) { } - if (url == null) { - url = Application.class.getClassLoader().getResource(assetCfg); - if (url == null) { + if (assetCfgUrl == null) { + assetCfgUrl = Application.class.getClassLoader().getResource(assetCfg); + if (assetCfgUrl == null) { logger.log(Level.SEVERE, "Unable to access AssetConfigURL in asset config:{0}", assetCfg); return; } } - assetManager = JmeSystem.newAssetManager(url); } } + if (assetCfgUrl == null) { + String assetCfg = JmeSystem.getPlatformAssetConfigPath(); + assetCfgUrl = Thread.currentThread().getContextClassLoader().getResource(assetCfg); + } if (assetManager == null){ - assetManager = JmeSystem.newAssetManager( - Thread.currentThread().getContextClassLoader() - .getResource("com/jme3/asset/Desktop.cfg")); + assetManager = JmeSystem.newAssetManager(assetCfgUrl); } } diff --git a/jme3-core/src/main/java/com/jme3/asset/AssetConfig.java b/jme3-core/src/main/java/com/jme3/asset/AssetConfig.java index 735a57be8..50b6e38af 100644 --- a/jme3-core/src/main/java/com/jme3/asset/AssetConfig.java +++ b/jme3-core/src/main/java/com/jme3/asset/AssetConfig.java @@ -33,6 +33,9 @@ package com.jme3.asset; import java.io.IOException; import java.io.InputStream; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Locale; import java.util.Scanner; import java.util.logging.Level; import java.util.logging.Logger; @@ -42,97 +45,77 @@ import java.util.logging.Logger; *

* The config file is specified with the following format: * + * "INCLUDE" * "LOADER" : ( ",")* - * "LOCATOR" : ( ",")* + * "LOCATOR" * * * @author Kirill Vainer */ -public class AssetConfig { +public final class AssetConfig { - private AssetManager manager; - - public AssetConfig(AssetManager manager){ - this.manager = manager; - } - - public void loadText(InputStream in) throws IOException{ - Scanner scan = new Scanner(in); - while (scan.hasNext()){ - String cmd = scan.next(); - if (cmd.equals("LOADER")){ - String loaderClass = scan.next(); - String colon = scan.next(); - if (!colon.equals(":")){ - throw new IOException("Expected ':', got '"+colon+"'"); - } - String extensionsList = scan.nextLine(); - String[] extensions = extensionsList.split(","); - for (int i = 0; i < extensions.length; i++){ - extensions[i] = extensions[i].trim(); - } - Class clazz = acquireClass(loaderClass); - if (clazz != null) { - manager.registerLoader(clazz, extensions); - } else { - Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "Cannot find loader {0}", loaderClass); - } - } else if (cmd.equals("LOCATOR")) { - String rootPath = scan.next(); - String locatorClass = scan.nextLine().trim(); - Class clazz = acquireClass(locatorClass); - if (clazz != null) { - manager.registerLocator(rootPath, clazz); - } else { - Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "Cannot find locator {0}", locatorClass); - } - } else { - throw new IOException("Expected command, got '" + cmd + "'"); - } - } - } + private static final Logger logger = Logger.getLogger(AssetConfig.class.getName()); - private Class acquireClass(String name) { + private AssetConfig() { } + + private static Class acquireClass(String name) { try { - Class clazz = Class.forName(name); - return clazz; + return Class.forName(name); } catch (ClassNotFoundException ex) { return null; } } - /* - private static String readString(DataInput dataIn) throws IOException{ - int length = dataIn.readUnsignedShort(); - char[] chrs = new char[length]; - for (int i = 0; i < length; i++){ - chrs[i] = (char) dataIn.readUnsignedByte(); - } - return String.valueOf(chrs); - } - - public void loadBinary(DataInput dataIn) throws IOException{ - // read signature and version - - // how many locator entries? - int locatorEntries = dataIn.readUnsignedShort(); - for (int i = 0; i < locatorEntries; i++){ - String locatorClazz = readString(dataIn); - String rootPath = readString(dataIn); - manager.registerLocator(rootPath, locatorClazz); - } - - int loaderEntries = dataIn.readUnsignedShort(); - for (int i = 0; i < loaderEntries; i++){ - String loaderClazz = readString(dataIn); - int numExtensions = dataIn.readUnsignedByte(); - String[] extensions = new String[numExtensions]; - for (int j = 0; j < numExtensions; j++){ - extensions[j] = readString(dataIn); + public static void loadText(AssetManager assetManager, URL configUrl) throws IOException{ + InputStream in = configUrl.openStream(); + try { + Scanner scan = new Scanner(in); + scan.useLocale(Locale.US); // Fix commas / periods ?? + while (scan.hasNext()){ + String cmd = scan.next(); + if (cmd.equals("LOADER")){ + String loaderClass = scan.next(); + String colon = scan.next(); + if (!colon.equals(":")){ + throw new IOException("Expected ':', got '"+colon+"'"); + } + String extensionsList = scan.nextLine(); + String[] extensions = extensionsList.split(","); + for (int i = 0; i < extensions.length; i++){ + extensions[i] = extensions[i].trim(); + } + Class clazz = acquireClass(loaderClass); + if (clazz != null) { + assetManager.registerLoader(clazz, extensions); + } else { + logger.log(Level.WARNING, "Cannot find loader {0}", loaderClass); + } + } else if (cmd.equals("LOCATOR")) { + String rootPath = scan.next(); + String locatorClass = scan.nextLine().trim(); + Class clazz = acquireClass(locatorClass); + if (clazz != null) { + assetManager.registerLocator(rootPath, clazz); + } else { + logger.log(Level.WARNING, "Cannot find locator {0}", locatorClass); + } + } else if (cmd.equals("INCLUDE")) { + String includedCfg = scan.nextLine().trim(); + URL includedCfgUrl = Thread.currentThread().getContextClassLoader().getResource(includedCfg); + if (includedCfgUrl != null) { + loadText(assetManager, includedCfgUrl); + } else { + logger.log(Level.WARNING, "Cannot find config include {0}", includedCfg); + } + } else if (cmd.trim().startsWith("#")) { + scan.nextLine(); + continue; + } else { + throw new IOException("Expected command, got '" + cmd + "'"); + } } - - manager.registerLoader(loaderClazz, extensions); + } finally { + if (in != null) in.close(); } } - */ } diff --git a/jme3-core/src/main/java/com/jme3/asset/AssetManager.java b/jme3-core/src/main/java/com/jme3/asset/AssetManager.java index b1d623070..a077512ef 100644 --- a/jme3-core/src/main/java/com/jme3/asset/AssetManager.java +++ b/jme3-core/src/main/java/com/jme3/asset/AssetManager.java @@ -46,6 +46,8 @@ import com.jme3.shader.ShaderGenerator; import com.jme3.shader.ShaderKey; import com.jme3.texture.Texture; import com.jme3.texture.plugins.TGALoader; +import java.io.IOException; +import java.io.InputStream; import java.util.EnumSet; import java.util.List; @@ -75,7 +77,15 @@ import java.util.List; *
  • {@link TGALoader} - Used to load Targa image files
  • * *

    - * Once the asset has been loaded, + * Once the asset has been loaded, it will be + * {@link AssetProcessor#postProcess(com.jme3.asset.AssetKey, java.lang.Object) + * post-processed} by the {@link AssetKey#getProcessorType() key's processor}. + * If the key specifies a {@link AssetKey#getCacheType() cache type}, the asset + * will be cached in the specified cache. Next, the {@link AssetProcessor} + * will be requested to {@link AssetProcessor#createClone(java.lang.Object) } + * generate a clone for the asset. Some assets do not require cloning, + * such as immutable or shared assets. Others, like models, must be cloned + * so that modifications to one instance do not leak onto others. */ public interface AssetManager { @@ -100,46 +110,13 @@ public interface AssetManager { */ public List getClassLoaders(); - /** - * Registers a loader for the given extensions. - * - * @param loaderClassName - * @param extensions - * - * @deprecated Please use {@link #registerLoader(java.lang.Class, java.lang.String[]) } - * together with {@link Class#forName(java.lang.String) } to find a class - * and then register it. - * - * @deprecated Please use {@link #registerLoader(java.lang.Class, java.lang.String[]) } - * with {@link Class#forName(java.lang.String) } instead. - */ - @Deprecated - public void registerLoader(String loaderClassName, String ... extensions); - - /** - * Registers an {@link AssetLocator} by using a class name. - * See the {@link AssetManager#registerLocator(java.lang.String, java.lang.Class) } - * method for more information. - * - * @param rootPath The root path from which to locate assets, this - * depends on the implementation of the asset locator. - * A URL based locator will expect a url folder such as "http://www.example.com/" - * while a File based locator will expect a file path (OS dependent). - * @param locatorClassName The full class name of the {@link AssetLocator} - * implementation. - * - * @deprecated Please use {@link #registerLocator(java.lang.String, java.lang.Class) } - * together with {@link Class#forName(java.lang.String) } to find a class - * and then register it. - */ - @Deprecated - public void registerLocator(String rootPath, String locatorClassName); - /** * Register an {@link AssetLoader} by using a class object. * - * @param loaderClass - * @param extensions + * @param loaderClass The loader class to register. + * @param extensions Which extensions this loader is responsible for loading, + * if there are already other loaders registered for that extension, they + * will be overridden - there should only be one loader for each extension. */ public void registerLoader(Class loaderClass, String ... extensions); @@ -161,7 +138,7 @@ public interface AssetManager { * to the {@link AssetLoader} to load the asset. * Once a locator is registered, it can be removed via * {@link #unregisterLocator(java.lang.String, java.lang.Class) }. - * + * * @param rootPath Specifies the root path from which to locate assets * for the given {@link AssetLocator}. The purpose of this parameter * depends on the type of the {@link AssetLocator}. @@ -206,18 +183,6 @@ public interface AssetManager { */ public void clearAssetEventListeners(); - /** - * Set an {@link AssetEventListener} to receive events from this - * AssetManager. Any currently added listeners are - * cleared and then the given listener is added. - * - * @param listener The listener to set - * @deprecated Please use {@link #addAssetEventListener(com.jme3.asset.AssetEventListener) } - * to listen for asset events. - */ - @Deprecated - public void setAssetEventListener(AssetEventListener listener); - /** * Manually locates an asset with the given {@link AssetKey}. * This method should be used for debugging or internal uses. @@ -233,6 +198,23 @@ public interface AssetManager { */ public AssetInfo locateAsset(AssetKey key); + /** + * Load an asset from an {@link InputStream}. + * In some cases it may be required to load an asset from memory + * or arbitrary streams so that registering a custom locator and key + * type is not necessary. + * + * @param The object type that will be loaded from the AssetKey instance. + * @param key The AssetKey. Note that the asset will not be cached - + * following the same behavior as if {@link AssetKey#getCacheType()} returned null. + * @param inputStream The input stream from which the asset shall be loaded. + * @return The loaded asset. + * + * @throws AssetLoadException If the {@link AssetLoader} has failed + * to load the asset due to an {@link IOException} or another error. + */ + public T loadAssetFromStream(AssetKey key, InputStream inputStream); + /** * Load an asset from a key, the asset will be located * by one of the {@link AssetLocator} implementations provided in the @@ -244,17 +226,18 @@ public interface AssetManager { * * @param The object type that will be loaded from the AssetKey instance. * @param key The AssetKey - * @return The loaded asset, or null if it was failed to be located - * or loaded. + * @return The loaded asset. + * + * @throws AssetNotFoundException If all registered locators have failed + * to locate the asset. + * @throws AssetLoadException If the {@link AssetLoader} has failed + * to load the asset due to an {@link IOException} or another error. */ public T loadAsset(AssetKey key); /** - * Load an asset by name, calling this method - * is the same as calling - * - * loadAsset(new AssetKey(name)). - * + * Load an asset by name, calling this method is the same as calling + * loadAsset(new AssetKey(name)). * * @param name The name of the asset to load. * @return The loaded asset, or null if failed to be loaded. @@ -265,7 +248,7 @@ public interface AssetManager { /** * Loads texture file, supported types are BMP, JPG, PNG, GIF, - * TGA and DDS. + * TGA, DDS, PFM, and HDR. * * @param key The {@link TextureKey} to use for loading. * @return The loaded texture, or null if failed to be loaded. @@ -276,8 +259,10 @@ public interface AssetManager { /** * Loads texture file, supported types are BMP, JPG, PNG, GIF, - * TGA and DDS. + * TGA, DDS, PFM, and HDR. * + * The texture will be loaded with mip-mapping enabled. + * * @param name The name of the texture to load. * @return The texture that was loaded * @@ -306,7 +291,8 @@ public interface AssetManager { /** * Loads a 3D model with a ModelKey. - * Models can be jME3 object files (J3O) or OgreXML/OBJ files. + * Models can be jME3 object files (J3O), OgreXML (mesh.xml), BLEND, FBX + * and OBJ files. * @param key Asset key of the model to load * @return The model that was loaded * @@ -315,8 +301,9 @@ public interface AssetManager { public Spatial loadModel(ModelKey key); /** - * Loads a 3D model. Models can be jME3 object files (J3O) or - * OgreXML/OBJ files. + * Loads a 3D model. Models can be jME3 object files (J3O), + * OgreXML (mesh.xml), BLEND, FBX and OBJ files. + * * @param name Asset name of the model to load * @return The model that was loaded * @@ -381,4 +368,53 @@ public interface AssetManager { */ public ShaderGenerator getShaderGenerator(EnumSet caps); + /** + * Retrieve an asset from the asset cache. + * + * NOTE: Do not modify the returned asset! + * It is the same reference as what is stored in the cache, therefore any + * modifications to it will leak onto assets loaded from the same key in the future. + * + * @param The object type that will be retrieved from the AssetKey instance. + * @param key The AssetKey to get from the cache. + * @return The cached asset, if found. Otherwise, null. + * + * @throws IllegalArgumentException If {@link AssetKey#getCacheType() caching} + * is disabled for the key. + */ + public T getFromCache(AssetKey key); + + /** + * Inject an asset into the asset cache. + * + * NOTE: Do not modify the cached asset after storing! + * It is the same reference as what is stored in the cache, therefore any + * modifications to it will leak onto assets loaded from the same key in the future. + * + * @param The object type of the asset. + * @param key The key where the asset shall be stored. + * @param asset The asset to inject into the cache. + * + * @throws IllegalArgumentException If {@link AssetKey#getCacheType() caching} + * is disabled for the key. + */ + public void addToCache(AssetKey key, T asset); + + /** + * Delete an asset from the asset cache. + * + * @param The object type of the AssetKey instance. + * @param key The asset key to remove from the cache. + * @return True if the asset key was found in the cache and was removed + * successfully. False if the asset key was not present in the cache. + * + * @throws IllegalArgumentException If {@link AssetKey#getCacheType() caching} + * is disabled for the key. + */ + public boolean deleteFromCache(AssetKey key); + + /** + * Clears the asset cache. + */ + public void clearCache(); } diff --git a/jme3-core/src/main/java/com/jme3/asset/DesktopAssetManager.java b/jme3-core/src/main/java/com/jme3/asset/DesktopAssetManager.java index 65d8d9a7b..0b4d50b98 100644 --- a/jme3-core/src/main/java/com/jme3/asset/DesktopAssetManager.java +++ b/jme3-core/src/main/java/com/jme3/asset/DesktopAssetManager.java @@ -81,11 +81,6 @@ public class DesktopAssetManager implements AssetManager { this(null); } - @Deprecated - public DesktopAssetManager(boolean loadDefaults){ - this(Thread.currentThread().getContextClassLoader().getResource("com/jme3/asset/Desktop.cfg")); - } - public DesktopAssetManager(URL configFile){ if (configFile != null){ loadConfigFile(configFile); @@ -93,20 +88,11 @@ public class DesktopAssetManager implements AssetManager { logger.fine("DesktopAssetManager created."); } - private void loadConfigFile(URL configFile){ - InputStream stream = null; - try{ - AssetConfig cfg = new AssetConfig(this); - stream = configFile.openStream(); - cfg.loadText(stream); - }catch (IOException ex){ + private void loadConfigFile(URL configFile) { + try { + AssetConfig.loadText(this, configFile); + } catch (IOException ex) { logger.log(Level.SEVERE, "Failed to load asset config", ex); - }finally{ - if (stream != null) - try{ - stream.close(); - }catch (IOException ex){ - } } } @@ -207,6 +193,7 @@ public class DesktopAssetManager implements AssetManager { return info; } + @Override public T getFromCache(AssetKey key) { AssetCache cache = handler.getCache(key.getCacheType()); if (cache != null) { @@ -221,6 +208,7 @@ public class DesktopAssetManager implements AssetManager { } } + @Override public void addToCache(AssetKey key, T asset) { AssetCache cache = handler.getCache(key.getCacheType()); if (cache != null) { @@ -231,6 +219,7 @@ public class DesktopAssetManager implements AssetManager { } } + @Override public boolean deleteFromCache(AssetKey key) { AssetCache cache = handler.getCache(key.getCacheType()); if (cache != null) { @@ -240,6 +229,7 @@ public class DesktopAssetManager implements AssetManager { } } + @Override public void clearCache(){ handler.clearCache(); if (logger.isLoggable(Level.FINER)){ @@ -248,13 +238,110 @@ public class DesktopAssetManager implements AssetManager { } /** - * Thread-safe. - * - * @param - * @param key - * @return the loaded asset + * Loads an asset that has already been located. + * @param The asset type + * @param key The asset key + * @param info The AssetInfo from the locator + * @param proc AssetProcessor to use, or null to disable processing + * @param cache The cache to store the asset in, or null to disable caching + * @return The loaded asset + * + * @throws AssetLoadException If failed to load asset due to exception or + * other error. + */ + protected T loadLocatedAsset(AssetKey key, AssetInfo info, AssetProcessor proc, AssetCache cache) { + AssetLoader loader = handler.aquireLoader(key); + Object obj; + try { + handler.establishParentKey(key); + obj = loader.load(info); + } catch (IOException ex) { + throw new AssetLoadException("An exception has occured while loading asset: " + key, ex); + } finally { + handler.releaseParentKey(key); + } + if (obj == null) { + throw new AssetLoadException("Error occured while loading asset \"" + + key + "\" using " + loader.getClass().getSimpleName()); + } else { + if (logger.isLoggable(Level.FINER)) { + logger.log(Level.FINER, "Loaded {0} with {1}", + new Object[]{key, loader.getClass().getSimpleName()}); + } + + if (proc != null) { + // do processing on asset before caching + obj = proc.postProcess(key, obj); + } + + if (cache != null) { + // At this point, obj should be of type T + cache.addToCache(key, (T) obj); + } + + for (AssetEventListener listener : eventListeners) { + listener.assetLoaded(key); + } + + return (T) obj; + } + } + + /** + * Clones the asset using the given processor and registers the clone + * with the cache. + * + * @param The asset type + * @param key The asset key + * @param obj The asset to clone / register, must implement + * {@link CloneableSmartAsset}. + * @param proc The processor which will generate the clone, cannot be null + * @param cache The cache to register the clone with, cannot be null. + * @return The cloned asset, cannot be the same as the given asset since + * it is a clone. + * + * @throws IllegalStateException If asset does not implement + * {@link CloneableSmartAsset}, if the cache is null, or if the + * processor did not clone the asset. */ - public T loadAsset(AssetKey key){ + protected T registerAndCloneSmartAsset(AssetKey key, T obj, AssetProcessor proc, AssetCache cache) { + // object obj is the original asset + // create an instance for user + T clone = (T) obj; + if (proc == null) { + throw new IllegalStateException("Asset implements " + + "CloneableSmartAsset but doesn't " + + "have processor to handle cloning"); + } else { + clone = (T) proc.createClone(obj); + if (cache != null && clone != obj) { + cache.registerAssetClone(key, clone); + } else { + throw new IllegalStateException("Asset implements " + + "CloneableSmartAsset but doesn't have cache or " + + "was not cloned"); + } + } + return clone; + } + + @Override + public T loadAssetFromStream(AssetKey key, InputStream inputStream) { + if (key == null) { + throw new IllegalArgumentException("key cannot be null"); + } + + for (AssetEventListener listener : eventListeners){ + listener.assetRequested(key); + } + + AssetProcessor proc = handler.getProcessor(key.getProcessorType()); + StreamAssetInfo info = new StreamAssetInfo(this, key, inputStream); + return loadLocatedAsset(key, info, proc, null); + } + + @Override + public T loadAsset(AssetKey key){ if (key == null) throw new IllegalArgumentException("key cannot be null"); @@ -268,7 +355,6 @@ public class DesktopAssetManager implements AssetManager { Object obj = cache != null ? cache.getFromCache(key) : null; if (obj == null){ // Asset not in cache, load it from file system. - AssetLoader loader = handler.aquireLoader(key); AssetInfo info = handler.tryLocate(key); if (info == null){ if (handler.getParentKey() != null){ @@ -282,59 +368,16 @@ public class DesktopAssetManager implements AssetManager { } throw new AssetNotFoundException(key.toString()); } - - try { - handler.establishParentKey(key); - obj = loader.load(info); - } catch (IOException ex) { - throw new AssetLoadException("An exception has occured while loading asset: " + key, ex); - } finally { - handler.releaseParentKey(key); - } - if (obj == null){ - throw new AssetLoadException("Error occured while loading asset \"" + key + "\" using " + loader.getClass().getSimpleName()); - }else{ - if (logger.isLoggable(Level.FINER)){ - logger.log(Level.FINER, "Loaded {0} with {1}", - new Object[]{key, loader.getClass().getSimpleName()}); - } - - if (proc != null){ - // do processing on asset before caching - obj = proc.postProcess(key, obj); - } - - if (cache != null){ - // At this point, obj should be of type T - cache.addToCache(key, (T) obj); - } - - for (AssetEventListener listener : eventListeners){ - listener.assetLoaded(key); - } - } + + obj = loadLocatedAsset(key, info, proc, cache); } - // object obj is the original asset - // create an instance for user T clone = (T) obj; - if (clone instanceof CloneableSmartAsset){ - if (proc == null){ - throw new IllegalStateException("Asset implements " - + "CloneableSmartAsset but doesn't " - + "have processor to handle cloning"); - }else{ - clone = (T) proc.createClone(obj); - if (cache != null && clone != obj){ - cache.registerAssetClone(key, clone); - } else{ - throw new IllegalStateException("Asset implements " - + "CloneableSmartAsset but doesn't have cache or " - + "was not cloned"); - } - } + + if (obj instanceof CloneableSmartAsset) { + clone = registerAndCloneSmartAsset(key, clone, proc, cache); } - + return clone; } diff --git a/jme3-core/src/main/java/com/jme3/asset/ImplHandler.java b/jme3-core/src/main/java/com/jme3/asset/ImplHandler.java index a68e46927..571be53c3 100644 --- a/jme3-core/src/main/java/com/jme3/asset/ImplHandler.java +++ b/jme3-core/src/main/java/com/jme3/asset/ImplHandler.java @@ -204,8 +204,10 @@ public class ImplHandler { public void clearCache(){ // The iterator of the values collection is thread safe - for (AssetCache cache : classToCacheMap.values()){ - cache.clearCache(); + synchronized (classToCacheMap) { + for (AssetCache cache : classToCacheMap.values()){ + cache.clearCache(); + } } } diff --git a/jme3-core/src/tools/java/jme3tools/converters/Converter.java b/jme3-core/src/main/java/com/jme3/asset/StreamAssetInfo.java similarity index 67% rename from jme3-core/src/tools/java/jme3tools/converters/Converter.java rename to jme3-core/src/main/java/com/jme3/asset/StreamAssetInfo.java index 4b3f5cd94..9e1f7c8a3 100644 --- a/jme3-core/src/tools/java/jme3tools/converters/Converter.java +++ b/jme3-core/src/main/java/com/jme3/asset/StreamAssetInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2012 jMonkeyEngine + * Copyright (c) 2009-2015 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,11 +29,32 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +package com.jme3.asset; -package jme3tools.converters; +import java.io.InputStream; -import java.util.Map; +/** + * An {@link AssetInfo} wrapper for {@link InputStream InputStreams}. + * + * @author Kirill Vainer + */ +public class StreamAssetInfo extends AssetInfo { -public interface Converter { - public T convert(T input, Map params); + private boolean alreadyOpened; + private final InputStream inputStream; + + public StreamAssetInfo(AssetManager assetManager, AssetKey assetKey, InputStream inputStream) { + super(assetManager, assetKey); + this.inputStream = inputStream; + } + + @Override + public InputStream openStream() { + if (alreadyOpened) { + throw new IllegalStateException("Stream already opened"); + } + alreadyOpened = true; + return inputStream; + } + } diff --git a/jme3-core/src/main/java/com/jme3/asset/cache/WeakRefAssetCache.java b/jme3-core/src/main/java/com/jme3/asset/cache/WeakRefAssetCache.java index 672412870..42f73f4a5 100644 --- a/jme3-core/src/main/java/com/jme3/asset/cache/WeakRefAssetCache.java +++ b/jme3-core/src/main/java/com/jme3/asset/cache/WeakRefAssetCache.java @@ -77,7 +77,6 @@ public class WeakRefAssetCache implements AssetCache { // might not even have this asset anymore, it is OK. if (assetCache.remove(ref.assetKey) != null){ removedAssets ++; - //System.out.println("WeakRefAssetCache: The asset " + ref.assetKey + " was purged from the cache"); } } if (removedAssets >= 1) { @@ -92,10 +91,6 @@ public class WeakRefAssetCache implements AssetCache { // thread is loading an asset with the same key .. AssetRef ref = new AssetRef(key, obj, refQueue); assetCache.put(key, ref); - -// Texture t = (Texture) obj; -// Image i = t.getImage(); -// System.out.println("add to cache " + System.identityHashCode(i)); } public T getFromCache(AssetKey key) { diff --git a/jme3-core/src/main/java/com/jme3/asset/cache/WeakRefCloneAssetCache.java b/jme3-core/src/main/java/com/jme3/asset/cache/WeakRefCloneAssetCache.java index 46ddfd199..e3566d22c 100644 --- a/jme3-core/src/main/java/com/jme3/asset/cache/WeakRefCloneAssetCache.java +++ b/jme3-core/src/main/java/com/jme3/asset/cache/WeakRefCloneAssetCache.java @@ -42,7 +42,7 @@ import java.util.logging.Level; import java.util.logging.Logger; /** - * caches cloneable assets in a weak-key + * WeakRefCloneAssetCache caches cloneable assets in a weak-key * cache, allowing them to be collected when memory is low. * The cache stores weak references to the asset keys, so that * when all clones of the original asset are collected, will cause the diff --git a/jme3-core/src/main/java/com/jme3/asset/cache/package.html b/jme3-core/src/main/java/com/jme3/asset/cache/package.html new file mode 100644 index 000000000..4aca0c878 --- /dev/null +++ b/jme3-core/src/main/java/com/jme3/asset/cache/package.html @@ -0,0 +1,30 @@ + + + + + + + + + +com.jme3.asset.cache contains the {@link com.jme3.asset.cache.AssetCache} +interface as well as its implementations.
    + +

    + +

    AssetCaches

    +The asset cache implementations are used by {@link com.jme3.asset.AssetManager} +to cache loaded assets for faster access if they are requested again. +

    +Assets in jME3 are cached in such a way that if there are no instances of +that asset anymore in memory, then jME3 is likely to reclaim them. +Some asset types must be cloned prior to being used, for example, 3D models +cannot be stored in the cache as-is, because the user is likely to modify them +after loading them. To handle this, a copy of the asset is stored in the +cache instead. The asset cache that implements these rules is the +{@link com.jme3.asset.cache.WeakRefCloneAssetCache} and it is used +for caching most asset types. + + + + diff --git a/jme3-core/src/main/java/com/jme3/renderer/RenderManager.java b/jme3-core/src/main/java/com/jme3/renderer/RenderManager.java index 311a3bcfc..b6ad6ace4 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/RenderManager.java +++ b/jme3-core/src/main/java/com/jme3/renderer/RenderManager.java @@ -863,10 +863,12 @@ public class RenderManager { private void setViewPort(Camera cam) { // this will make sure to update viewport only if needed if (cam != prevCam || cam.isViewportChanged()) { - viewX = (int) (cam.getViewPortLeft() * cam.getWidth()); - viewY = (int) (cam.getViewPortBottom() * cam.getHeight()); - viewWidth = ((int)(cam.getViewPortRight() * cam.getWidth())) - ((int)(cam.getViewPortLeft() * cam.getWidth())); - viewHeight = ((int)(cam.getViewPortTop() * cam.getHeight())) - ((int)(cam.getViewPortBottom() * cam.getHeight())); + viewX = (int) (cam.getViewPortLeft() * cam.getWidth()); + viewY = (int) (cam.getViewPortBottom() * cam.getHeight()); + int viewX2 = (int) (cam.getViewPortRight() * cam.getWidth()); + int viewY2 = (int) (cam.getViewPortTop() * cam.getHeight()); + viewWidth = viewX2 - viewX; + viewHeight = viewY2 - viewY; uniformBindingManager.setViewPort(viewX, viewY, viewWidth, viewHeight); renderer.setViewPort(viewX, viewY, viewWidth, viewHeight); renderer.setClipRect(viewX, viewY, viewWidth, viewHeight); diff --git a/jme3-core/src/main/java/com/jme3/system/JmeSystem.java b/jme3-core/src/main/java/com/jme3/system/JmeSystem.java index 637b24304..a29262726 100644 --- a/jme3-core/src/main/java/com/jme3/system/JmeSystem.java +++ b/jme3-core/src/main/java/com/jme3/system/JmeSystem.java @@ -35,6 +35,7 @@ import com.jme3.asset.AssetManager; import com.jme3.audio.AudioRenderer; import com.jme3.input.SoftTextDialogInput; import com.jme3.texture.Image; +import com.jme3.texture.image.DefaultImageRaster; import com.jme3.texture.image.ImageRaster; import java.io.File; import java.io.IOException; @@ -166,6 +167,15 @@ public class JmeSystem { return systemDelegate.newAudioRenderer(settings); } + public static String getPlatformAssetConfigPath() { + checkDelegate(); + return systemDelegate.getPlatformAssetConfigPath(); + } + + /** + * @deprecated Directly create an image raster via {@link DefaultImageRaster}. + */ + @Deprecated public static ImageRaster createImageRaster(Image image, int slice) { checkDelegate(); return systemDelegate.createImageRaster(image, slice); diff --git a/jme3-core/src/main/java/com/jme3/system/JmeSystemDelegate.java b/jme3-core/src/main/java/com/jme3/system/JmeSystemDelegate.java index 6b204456b..a129f6423 100644 --- a/jme3-core/src/main/java/com/jme3/system/JmeSystemDelegate.java +++ b/jme3-core/src/main/java/com/jme3/system/JmeSystemDelegate.java @@ -32,9 +32,11 @@ package com.jme3.system; import com.jme3.asset.AssetManager; +import com.jme3.asset.DesktopAssetManager; import com.jme3.audio.AudioRenderer; import com.jme3.input.SoftTextDialogInput; import com.jme3.texture.Image; +import com.jme3.texture.image.DefaultImageRaster; import com.jme3.texture.image.ImageRaster; import java.io.File; import java.io.IOException; @@ -117,15 +119,25 @@ public abstract class JmeSystemDelegate { public void setSoftTextDialogInput(SoftTextDialogInput input) { softTextDialogInput = input; } + public SoftTextDialogInput getSoftTextDialogInput() { return softTextDialogInput; } - public abstract void writeImageFile(OutputStream outStream, String format, ByteBuffer imageData, int width, int height) throws IOException; - - public abstract AssetManager newAssetManager(URL configFile); + public final AssetManager newAssetManager(URL configFile) { + return new DesktopAssetManager(configFile); + } - public abstract AssetManager newAssetManager(); + public final AssetManager newAssetManager() { + return new DesktopAssetManager(null); + } + + @Deprecated + public final ImageRaster createImageRaster(Image image, int slice) { + return new DefaultImageRaster(image, slice); + } + + public abstract void writeImageFile(OutputStream outStream, String format, ByteBuffer imageData, int width, int height) throws IOException; public abstract void showErrorDialog(String message); @@ -181,13 +193,13 @@ public abstract class JmeSystemDelegate { return sb.toString(); } + public abstract String getPlatformAssetConfigPath(); + public abstract JmeContext newContext(AppSettings settings, JmeContext.Type contextType); public abstract AudioRenderer newAudioRenderer(AppSettings settings); public abstract void initialize(AppSettings settings); - public abstract ImageRaster createImageRaster(Image image, int slice); - public abstract void showSoftKeyboard(boolean show); } diff --git a/jme3-core/src/main/resources/com/jme3/asset/Desktop.cfg b/jme3-core/src/main/resources/com/jme3/asset/Desktop.cfg index 08e6492f5..df72654a1 100644 --- a/jme3-core/src/main/resources/com/jme3/asset/Desktop.cfg +++ b/jme3-core/src/main/resources/com/jme3/asset/Desktop.cfg @@ -1,7 +1,8 @@ -LOCATOR / com.jme3.asset.plugins.ClasspathLocator +INCLUDE com/jme3/asset/General.cfg +# Desktop-specific loaders LOADER com.jme3.texture.plugins.AWTLoader : jpg, bmp, gif, png, jpeg -LOADER com.jme3.audio.plugins.WAVLoader : wav +LOADER com.jme3.audio.plugins.OGGLoader : oggLOADER com.jme3.audio.plugins.WAVLoader : wav LOADER com.jme3.audio.plugins.OGGLoader : ogg LOADER com.jme3.cursors.plugins.CursorLoader : ani, cur, ico LOADER com.jme3.material.plugins.J3MLoader : j3m diff --git a/jme3-core/src/main/resources/com/jme3/asset/General.cfg b/jme3-core/src/main/resources/com/jme3/asset/General.cfg new file mode 100644 index 000000000..c0098ffe5 --- /dev/null +++ b/jme3-core/src/main/resources/com/jme3/asset/General.cfg @@ -0,0 +1,26 @@ +# Generic locators that should be supported on all platforms. +LOCATOR / com.jme3.asset.plugins.ClasspathLocator + +# Generic loaders that should be supported on all platforms. +LOADER com.jme3.audio.plugins.WAVLoader : wav +LOADER com.jme3.cursors.plugins.CursorLoader : ani, cur, ico +LOADER com.jme3.material.plugins.J3MLoader : j3m +LOADER com.jme3.material.plugins.J3MLoader : j3md +LOADER com.jme3.material.plugins.ShaderNodeDefinitionLoader : j3sn +LOADER com.jme3.font.plugins.BitmapFontLoader : fnt +LOADER com.jme3.texture.plugins.DDSLoader : dds +LOADER com.jme3.texture.plugins.PFMLoader : pfm +LOADER com.jme3.texture.plugins.HDRLoader : hdr +LOADER com.jme3.texture.plugins.TGALoader : tga +LOADER com.jme3.export.binary.BinaryImporter : j3o +LOADER com.jme3.export.binary.BinaryImporter : j3f +LOADER com.jme3.scene.plugins.OBJLoader : obj +LOADER com.jme3.scene.plugins.MTLLoader : mtl +LOADER com.jme3.scene.plugins.ogre.MeshLoader : meshxml, mesh.xml +LOADER com.jme3.scene.plugins.ogre.SkeletonLoader : skeletonxml, skeleton.xml +LOADER com.jme3.scene.plugins.ogre.MaterialLoader : material +LOADER com.jme3.scene.plugins.ogre.SceneLoader : scene +LOADER com.jme3.scene.plugins.blender.BlenderModelLoader : blend +LOADER com.jme3.shader.plugins.GLSLLoader : vert, frag, glsl, glsllib +LOADER com.jme3.scene.plugins.fbx.SceneLoader : fbx +LOADER com.jme3.scene.plugins.fbx.SceneWithAnimationLoader : fba diff --git a/jme3-core/src/plugins/java/com/jme3/asset/plugins/ClasspathLocator.java b/jme3-core/src/plugins/java/com/jme3/asset/plugins/ClasspathLocator.java index 43feaa113..dbeff428a 100644 --- a/jme3-core/src/plugins/java/com/jme3/asset/plugins/ClasspathLocator.java +++ b/jme3-core/src/plugins/java/com/jme3/asset/plugins/ClasspathLocator.java @@ -41,6 +41,16 @@ import java.util.logging.Logger; /** * The ClasspathLocator looks up an asset in the classpath. + * + * This locator is used by default in all jME3 projects (unless + * {@link AssetManager#unregisterLocator(java.lang.String, java.lang.Class) unregistered} + * ). + * Unlike Java's default resource loading mechanism, the ClasspathLocator + * enforces case-sensitivity on platforms which do not have it such as Windows. + * Therefore, it is critical to provide a path matching the case of the file on + * the filesystem. This also ensures that the file can be loaded if it was + * later included in a .JAR file instead of a folder. + * * @author Kirill Vainer */ public class ClasspathLocator implements AssetLocator { diff --git a/jme3-core/src/plugins/java/com/jme3/asset/plugins/FileLocator.java b/jme3-core/src/plugins/java/com/jme3/asset/plugins/FileLocator.java index 88d4d3ee0..f46a97516 100644 --- a/jme3-core/src/plugins/java/com/jme3/asset/plugins/FileLocator.java +++ b/jme3-core/src/plugins/java/com/jme3/asset/plugins/FileLocator.java @@ -37,6 +37,7 @@ import java.io.*; /** * FileLocator allows you to specify a folder where to * look for assets. + * * @author Kirill Vainer */ public class FileLocator implements AssetLocator { diff --git a/jme3-core/src/plugins/java/com/jme3/asset/plugins/HttpZipLocator.java b/jme3-core/src/plugins/java/com/jme3/asset/plugins/HttpZipLocator.java index af7026206..7edda53e4 100644 --- a/jme3-core/src/plugins/java/com/jme3/asset/plugins/HttpZipLocator.java +++ b/jme3-core/src/plugins/java/com/jme3/asset/plugins/HttpZipLocator.java @@ -52,6 +52,23 @@ import java.util.zip.Inflater; import java.util.zip.InflaterInputStream; import java.util.zip.ZipEntry; +/** + * HttpZipLocator is similar to {@link ZipLocator}, except + * it allows loading assets from a .ZIP file on the web instead of + * on the local filesystem. + *

    + * The root path must be a valid HTTP(S) {@link URL} pointing to ZIP or + * ZIP-like file (such as a JAR). For example,
    + * https://www.example.com/my/sub/path/assets.zip. + *

    + * The locator is designed in such a way that it does not require downloading + * the entire .ZIP file from the web in order to load + * assets from it. Instead, the ZIP header is extracted first, and then + * is used to lookup assets from within the ZIP file and download them + * as requested by the user. + * + * @author Kirill Vainer + */ public class HttpZipLocator implements AssetLocator { private static final Logger logger = Logger.getLogger(HttpZipLocator.class.getName()); diff --git a/jme3-core/src/plugins/java/com/jme3/asset/plugins/UrlLocator.java b/jme3-core/src/plugins/java/com/jme3/asset/plugins/UrlLocator.java index 1de7008d8..31cfe0f2c 100644 --- a/jme3-core/src/plugins/java/com/jme3/asset/plugins/UrlLocator.java +++ b/jme3-core/src/plugins/java/com/jme3/asset/plugins/UrlLocator.java @@ -46,6 +46,10 @@ import java.util.logging.Logger; * UrlLocator is a locator that combines a root URL * and the given path in the AssetKey to construct a new URL * that allows locating the asset. + *

    + * The root path must be a valid {@link URL}, for example,
    + * https://www.example.com/assets/ + * * @author Kirill Vainer */ public class UrlLocator implements AssetLocator { diff --git a/jme3-core/src/plugins/java/com/jme3/asset/plugins/ZipLocator.java b/jme3-core/src/plugins/java/com/jme3/asset/plugins/ZipLocator.java index 9f1508f44..d20816f34 100644 --- a/jme3-core/src/plugins/java/com/jme3/asset/plugins/ZipLocator.java +++ b/jme3-core/src/plugins/java/com/jme3/asset/plugins/ZipLocator.java @@ -40,7 +40,13 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipFile; /** - * ZipLocator is a locator that looks up resources in a .ZIP file. + * ZipLocator is a locator that looks up resources in a + * .ZIP file. + * + * The root path must be a valid ZIP or ZIP-like {@link File file}, + * for example,
    + * C:\My App\data.zip + * * @author Kirill Vainer */ public class ZipLocator implements AssetLocator { diff --git a/jme3-core/src/tools/java/jme3tools/converters/FolderConverter.java b/jme3-core/src/tools/java/jme3tools/converters/FolderConverter.java deleted file mode 100644 index a2edda488..000000000 --- a/jme3-core/src/tools/java/jme3tools/converters/FolderConverter.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2009-2012 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package jme3tools.converters; - -import com.jme3.asset.AssetManager; -import com.jme3.system.JmeSystem; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.jar.JarEntry; -import java.util.jar.JarOutputStream; - -public class FolderConverter { - - private static AssetManager assetManager; - private static File sourceRoot; - private static JarOutputStream jarOut; - private static long time; - - private static void process(File file) throws IOException{ - String name = file.getName().replaceAll("[\\/\\.]", "_"); - JarEntry entry = new JarEntry(name); - entry.setTime(time); - - jarOut.putNextEntry(entry); - } - - public static void main(String[] args) throws IOException{ - if (args.length == 0){ - System.out.println("Usage: java -jar FolderConverter "); - System.out.println(); - System.out.println(" Converts files from input to output"); - System.exit(1); - } - - sourceRoot = new File(args[0]); - - File jarFile = new File(sourceRoot.getParent(), sourceRoot.getName()+".jar"); - FileOutputStream out = new FileOutputStream(jarFile); - jarOut = new JarOutputStream(out); - - assetManager = JmeSystem.newAssetManager(); - assetManager.registerLocator(sourceRoot.toString(), - "com.jme3.asset.plugins.FileSystemLocator"); - for (File f : sourceRoot.listFiles()){ - process(f); - } - } - -} diff --git a/jme3-core/src/tools/java/jme3tools/converters/model/FloatToFixed.java b/jme3-core/src/tools/java/jme3tools/converters/model/FloatToFixed.java deleted file mode 100644 index 7e2b83e14..000000000 --- a/jme3-core/src/tools/java/jme3tools/converters/model/FloatToFixed.java +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright (c) 2009-2012 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package jme3tools.converters.model; - -import com.jme3.bounding.BoundingBox; -import com.jme3.math.Transform; -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Mesh; -import com.jme3.scene.VertexBuffer; -import com.jme3.scene.VertexBuffer.Format; -import com.jme3.scene.VertexBuffer.Type; -import com.jme3.scene.VertexBuffer.Usage; -import com.jme3.scene.mesh.IndexBuffer; -import com.jme3.util.BufferUtils; -import java.nio.*; - -@Deprecated -public class FloatToFixed { - - private static final float shortSize = Short.MAX_VALUE - Short.MIN_VALUE; - private static final float shortOff = (Short.MAX_VALUE + Short.MIN_VALUE) * 0.5f; - - private static final float byteSize = Byte.MAX_VALUE - Byte.MIN_VALUE; - private static final float byteOff = (Byte.MAX_VALUE + Byte.MIN_VALUE) * 0.5f; - - @Deprecated - public static void convertToFixed(Geometry geom, Format posFmt, Format nmFmt, Format tcFmt){ - geom.updateModelBound(); - BoundingBox bbox = (BoundingBox) geom.getModelBound(); - Mesh mesh = geom.getMesh(); - - VertexBuffer positions = mesh.getBuffer(Type.Position); - VertexBuffer normals = mesh.getBuffer(Type.Normal); - VertexBuffer texcoords = mesh.getBuffer(Type.TexCoord); - VertexBuffer indices = mesh.getBuffer(Type.Index); - - // positions - FloatBuffer fb = (FloatBuffer) positions.getData(); - if (posFmt != Format.Float){ - Buffer newBuf = VertexBuffer.createBuffer(posFmt, positions.getNumComponents(), - mesh.getVertexCount()); - Transform t = convertPositions(fb, bbox, newBuf); - t.combineWithParent(geom.getLocalTransform()); - geom.setLocalTransform(t); - - VertexBuffer newPosVb = new VertexBuffer(Type.Position); - newPosVb.setupData(positions.getUsage(), - positions.getNumComponents(), - posFmt, - newBuf); - mesh.clearBuffer(Type.Position); - mesh.setBuffer(newPosVb); - } - - // normals, automatically convert to signed byte - fb = (FloatBuffer) normals.getData(); - - ByteBuffer bb = BufferUtils.createByteBuffer(fb.capacity()); - convertNormals(fb, bb); - - normals = new VertexBuffer(Type.Normal); - normals.setupData(Usage.Static, 3, Format.Byte, bb); - normals.setNormalized(true); - mesh.clearBuffer(Type.Normal); - mesh.setBuffer(normals); - - // texcoords - fb = (FloatBuffer) texcoords.getData(); - if (tcFmt != Format.Float){ - Buffer newBuf = VertexBuffer.createBuffer(tcFmt, - texcoords.getNumComponents(), - mesh.getVertexCount()); - convertTexCoords2D(fb, newBuf); - - VertexBuffer newTcVb = new VertexBuffer(Type.TexCoord); - newTcVb.setupData(texcoords.getUsage(), - texcoords.getNumComponents(), - tcFmt, - newBuf); - mesh.clearBuffer(Type.TexCoord); - mesh.setBuffer(newTcVb); - } - } - - public static void compressIndexBuffer(Mesh mesh){ - int vertCount = mesh.getVertexCount(); - VertexBuffer vb = mesh.getBuffer(Type.Index); - Format targetFmt; - if (vb.getFormat() == Format.UnsignedInt && vertCount <= 0xffff){ - if (vertCount <= 256) - targetFmt = Format.UnsignedByte; - else - targetFmt = Format.UnsignedShort; - }else if (vb.getFormat() == Format.UnsignedShort && vertCount <= 0xff){ - targetFmt = Format.UnsignedByte; - }else{ - return; - } - - IndexBuffer src = mesh.getIndexBuffer(); - Buffer newBuf = VertexBuffer.createBuffer(targetFmt, vb.getNumComponents(), src.size()); - - VertexBuffer newVb = new VertexBuffer(Type.Index); - newVb.setupData(vb.getUsage(), vb.getNumComponents(), targetFmt, newBuf); - mesh.clearBuffer(Type.Index); - mesh.setBuffer(newVb); - - IndexBuffer dst = mesh.getIndexBuffer(); - for (int i = 0; i < src.size(); i++){ - dst.put(i, src.get(i)); - } - } - - private static void convertToFixed(FloatBuffer input, IntBuffer output){ - if (output.capacity() < input.capacity()) - throw new RuntimeException("Output must be at least as large as input!"); - - input.clear(); - output.clear(); - for (int i = 0; i < input.capacity(); i++){ - output.put( (int) (input.get() * (float)(1<<16)) ); - } - output.flip(); - } - - private static void convertToFloat(IntBuffer input, FloatBuffer output){ - if (output.capacity() < input.capacity()) - throw new RuntimeException("Output must be at least as large as input!"); - - input.clear(); - output.clear(); - for (int i = 0; i < input.capacity(); i++){ - output.put( ((float)input.get() / (float)(1<<16)) ); - } - output.flip(); - } - - private static void convertToUByte(FloatBuffer input, ByteBuffer output){ - if (output.capacity() < input.capacity()) - throw new RuntimeException("Output must be at least as large as input!"); - - input.clear(); - output.clear(); - for (int i = 0; i < input.capacity(); i++){ - output.put( (byte) (input.get() * 255f) ); - } - output.flip(); - } - - - public static VertexBuffer convertToUByte(VertexBuffer vb){ - FloatBuffer fb = (FloatBuffer) vb.getData(); - ByteBuffer bb = BufferUtils.createByteBuffer(fb.capacity()); - convertToUByte(fb, bb); - - VertexBuffer newVb = new VertexBuffer(vb.getBufferType()); - newVb.setupData(vb.getUsage(), - vb.getNumComponents(), - Format.UnsignedByte, - bb); - newVb.setNormalized(true); - return newVb; - } - - public static VertexBuffer convertToFixed(VertexBuffer vb){ - if (vb.getFormat() == Format.Int) - return vb; - - FloatBuffer fb = (FloatBuffer) vb.getData(); - IntBuffer ib = BufferUtils.createIntBuffer(fb.capacity()); - convertToFixed(fb, ib); - - VertexBuffer newVb = new VertexBuffer(vb.getBufferType()); - newVb.setupData(vb.getUsage(), - vb.getNumComponents(), - Format.Int, - ib); - return newVb; - } - - public static VertexBuffer convertToFloat(VertexBuffer vb){ - if (vb.getFormat() == Format.Float) - return vb; - - IntBuffer ib = (IntBuffer) vb.getData(); - FloatBuffer fb = BufferUtils.createFloatBuffer(ib.capacity()); - convertToFloat(ib, fb); - - VertexBuffer newVb = new VertexBuffer(vb.getBufferType()); - newVb.setupData(vb.getUsage(), - vb.getNumComponents(), - Format.Float, - fb); - return newVb; - } - - private static void convertNormals(FloatBuffer input, ByteBuffer output){ - if (output.capacity() < input.capacity()) - throw new RuntimeException("Output must be at least as large as input!"); - - input.clear(); - output.clear(); - Vector3f temp = new Vector3f(); - int vertexCount = input.capacity() / 3; - for (int i = 0; i < vertexCount; i++){ - BufferUtils.populateFromBuffer(temp, input, i); - - // offset and scale vector into -128 ... 127 - temp.multLocal(127).addLocal(0.5f, 0.5f, 0.5f); - - // quantize - byte v1 = (byte) temp.getX(); - byte v2 = (byte) temp.getY(); - byte v3 = (byte) temp.getZ(); - - // store - output.put(v1).put(v2).put(v3); - } - } - - private static void convertTexCoords2D(FloatBuffer input, Buffer output){ - if (output.capacity() < input.capacity()) - throw new RuntimeException("Output must be at least as large as input!"); - - input.clear(); - output.clear(); - Vector2f temp = new Vector2f(); - int vertexCount = input.capacity() / 2; - - ShortBuffer sb = null; - IntBuffer ib = null; - - if (output instanceof ShortBuffer) - sb = (ShortBuffer) output; - else if (output instanceof IntBuffer) - ib = (IntBuffer) output; - else - throw new UnsupportedOperationException(); - - for (int i = 0; i < vertexCount; i++){ - BufferUtils.populateFromBuffer(temp, input, i); - - if (sb != null){ - sb.put( (short) (temp.getX()*Short.MAX_VALUE) ); - sb.put( (short) (temp.getY()*Short.MAX_VALUE) ); - }else{ - int v1 = (int) (temp.getX() * ((float)(1 << 16))); - int v2 = (int) (temp.getY() * ((float)(1 << 16))); - ib.put(v1).put(v2); - } - } - } - - private static Transform convertPositions(FloatBuffer input, BoundingBox bbox, Buffer output){ - if (output.capacity() < input.capacity()) - throw new RuntimeException("Output must be at least as large as input!"); - - Vector3f offset = bbox.getCenter().negate(); - Vector3f size = new Vector3f(bbox.getXExtent(), bbox.getYExtent(), bbox.getZExtent()); - size.multLocal(2); - - ShortBuffer sb = null; - ByteBuffer bb = null; - float dataTypeSize; - float dataTypeOffset; - if (output instanceof ShortBuffer){ - sb = (ShortBuffer) output; - dataTypeOffset = shortOff; - dataTypeSize = shortSize; - }else{ - bb = (ByteBuffer) output; - dataTypeOffset = byteOff; - dataTypeSize = byteSize; - } - Vector3f scale = new Vector3f(); - scale.set(dataTypeSize, dataTypeSize, dataTypeSize).divideLocal(size); - - Vector3f invScale = new Vector3f(); - invScale.set(size).divideLocal(dataTypeSize); - - offset.multLocal(scale); - offset.addLocal(dataTypeOffset, dataTypeOffset, dataTypeOffset); - - // offset = (-modelOffset * shortSize)/modelSize + shortOff - // scale = shortSize / modelSize - - input.clear(); - output.clear(); - Vector3f temp = new Vector3f(); - int vertexCount = input.capacity() / 3; - for (int i = 0; i < vertexCount; i++){ - BufferUtils.populateFromBuffer(temp, input, i); - - // offset and scale vector into -32768 ... 32767 - // or into -128 ... 127 if using bytes - temp.multLocal(scale); - temp.addLocal(offset); - - // quantize and store - if (sb != null){ - short v1 = (short) temp.getX(); - short v2 = (short) temp.getY(); - short v3 = (short) temp.getZ(); - sb.put(v1).put(v2).put(v3); - }else{ - byte v1 = (byte) temp.getX(); - byte v2 = (byte) temp.getY(); - byte v3 = (byte) temp.getZ(); - bb.put(v1).put(v2).put(v3); - } - } - - Transform transform = new Transform(); - transform.setTranslation(offset.negate().multLocal(invScale)); - transform.setScale(invScale); - return transform; - } - -} diff --git a/jme3-desktop/src/main/java/com/jme3/system/JmeDesktopSystem.java b/jme3-desktop/src/main/java/com/jme3/system/JmeDesktopSystem.java index 5697b713b..f719a04ef 100644 --- a/jme3-desktop/src/main/java/com/jme3/system/JmeDesktopSystem.java +++ b/jme3-desktop/src/main/java/com/jme3/system/JmeDesktopSystem.java @@ -75,10 +75,10 @@ import javax.swing.SwingUtilities; public class JmeDesktopSystem extends JmeSystemDelegate { @Override - public AssetManager newAssetManager(URL configFile) { - return new DesktopAssetManager(configFile); + public String getPlatformAssetConfigPath() { + return "com/jme3/asset/Desktop.cfg"; } - + private static BufferedImage verticalFlip(BufferedImage original) { AffineTransform tx = AffineTransform.getScaleInstance(1, -1); tx.translate(0, -original.getHeight()); @@ -119,17 +119,6 @@ public class JmeDesktopSystem extends JmeSystemDelegate { } } - @Override - public ImageRaster createImageRaster(Image image, int slice) { - assert image.getEfficentData() == null; - return new DefaultImageRaster(image, slice); - } - - @Override - public AssetManager newAssetManager() { - return new DesktopAssetManager(null); - } - @Override public void showErrorDialog(String message) { final String msg = message; diff --git a/jme3-ios/src/main/java/com/jme3/asset/IOS.cfg b/jme3-ios/src/main/java/com/jme3/asset/IOS.cfg new file mode 100644 index 000000000..715eab985 --- /dev/null +++ b/jme3-ios/src/main/java/com/jme3/asset/IOS.cfg @@ -0,0 +1,4 @@ +INCLUDE com/jme3/asset/General.cfg + +# IOS specific loaders +LOADER com.jme3.system.ios.IosImageLoader : jpg, bmp, gif, png, jpeg diff --git a/jme3-ios/src/main/java/com/jme3/system/ios/IosAssetManager.java b/jme3-ios/src/main/java/com/jme3/system/ios/IosAssetManager.java deleted file mode 100644 index 7a8b22067..000000000 --- a/jme3-ios/src/main/java/com/jme3/system/ios/IosAssetManager.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2009-2012 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.jme3.system.ios; - -import com.jme3.asset.AssetLoader; -import com.jme3.asset.DesktopAssetManager; -import com.jme3.asset.TextureKey; -import com.jme3.asset.plugins.ClasspathLocator; -import com.jme3.audio.plugins.WAVLoader; -import com.jme3.texture.Texture; -import java.io.InputStream; -import java.net.URL; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * - * @author normenhansen - */ -public class IosAssetManager extends DesktopAssetManager { - - private static final Logger logger = Logger.getLogger(IosAssetManager.class.getName()); - - public IosAssetManager() { - this(null); - } - - @Deprecated - public IosAssetManager(boolean loadDefaults) { - //this(Thread.currentThread().getContextClassLoader().getResource("com/jme3/asset/Android.cfg")); - this(null); - } - - private void registerLoaderSafe(String loaderClass, String ... extensions) { - try { - Class loader = (Class) Class.forName(loaderClass); - registerLoader(loader, extensions); - } catch (Exception e){ - logger.log(Level.WARNING, "Failed to load AssetLoader", e); - } - } - - /** - * AndroidAssetManager constructor - * If URL == null then a default list of locators and loaders for android is set - * @param configFile - */ - public IosAssetManager(URL configFile) { - System.setProperty("org.xml.sax.driver", "org.xmlpull.v1.sax2.Driver"); - - // Set Default iOS config - registerLocator("", ClasspathLocator.class); - - registerLoader(IosImageLoader.class, "jpg", "bmp", "gif", "png", "jpeg"); - //registerLoader(AndroidImageLoader.class, "jpg", "bmp", "gif", "png", "jpeg"); - //registerLoader(AndroidAudioLoader.class, "ogg", "mp3", "wav"); - registerLoader(com.jme3.material.plugins.J3MLoader.class, "j3m"); - registerLoader(com.jme3.material.plugins.J3MLoader.class, "j3md"); - registerLoader(com.jme3.shader.plugins.GLSLLoader.class, "vert", "frag", "glsl", "glsllib"); - registerLoader(com.jme3.export.binary.BinaryImporter.class, "j3o"); - registerLoader(com.jme3.font.plugins.BitmapFontLoader.class, "fnt"); - registerLoader(WAVLoader.class, "wav"); - - // Less common loaders (especially on iOS) - registerLoaderSafe("com.jme3.audio.plugins.OGGLoader", "ogg"); - registerLoaderSafe("com.jme3.texture.plugins.DDSLoader", "dds"); - registerLoaderSafe("com.jme3.texture.plugins.PFMLoader", "pfm"); - registerLoaderSafe("com.jme3.texture.plugins.HDRLoader", "hdr"); - registerLoaderSafe("com.jme3.texture.plugins.TGALoader", "tga"); - registerLoaderSafe("com.jme3.scene.plugins.OBJLoader", "obj"); - registerLoaderSafe("com.jme3.scene.plugins.MTLLoader", "mtl"); - registerLoaderSafe("com.jme3.scene.plugins.ogre.MeshLoader", "mesh.xml"); - registerLoaderSafe("com.jme3.scene.plugins.ogre.SkeletonLoader", "skeleton.xml"); - registerLoaderSafe("com.jme3.scene.plugins.ogre.MaterialLoader", "material"); - registerLoaderSafe("com.jme3.scene.plugins.ogre.SceneLoader", "scene"); - - - logger.fine("IosAssetManager created."); - } -} diff --git a/jme3-ios/src/main/java/com/jme3/system/ios/JmeIosSystem.java b/jme3-ios/src/main/java/com/jme3/system/ios/JmeIosSystem.java index b4b7906e1..1ffb097f7 100644 --- a/jme3-ios/src/main/java/com/jme3/system/ios/JmeIosSystem.java +++ b/jme3-ios/src/main/java/com/jme3/system/ios/JmeIosSystem.java @@ -31,17 +31,13 @@ */ package com.jme3.system.ios; -import com.jme3.asset.AssetManager; import com.jme3.audio.AudioRenderer; import com.jme3.system.AppSettings; import com.jme3.system.JmeContext; import com.jme3.system.JmeSystemDelegate; import com.jme3.system.NullContext; -import com.jme3.texture.Image; -import com.jme3.texture.image.ImageRaster; import java.io.IOException; import java.io.OutputStream; -import java.net.URL; import java.nio.ByteBuffer; import java.util.logging.Logger; @@ -52,18 +48,13 @@ import java.util.logging.Logger; public class JmeIosSystem extends JmeSystemDelegate { @Override - public void writeImageFile(OutputStream outStream, String format, ByteBuffer imageData, int width, int height) throws IOException { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public AssetManager newAssetManager(URL configFile) { - return new IosAssetManager(configFile); + public String getPlatformAssetConfigPath() { + return "com/jme3/asset/IOS.cfg"; } - + @Override - public AssetManager newAssetManager() { - return new IosAssetManager(); + public void writeImageFile(OutputStream outStream, String format, ByteBuffer imageData, int width, int height) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); } @Override @@ -106,11 +97,6 @@ public class JmeIosSystem extends JmeSystemDelegate { // throw new UnsupportedOperationException("Not supported yet."); } - @Override - public ImageRaster createImageRaster(Image image, int slice) { - throw new UnsupportedOperationException("Not supported yet."); - } - @Override public void showSoftKeyboard(boolean show) { throw new UnsupportedOperationException("Not supported yet."); diff --git a/jme3-plugins/src/fbx/java/com/jme3/scene/plugins/fbx/file/FBXDump.java b/jme3-plugins/src/fbx/java/com/jme3/scene/plugins/fbx/file/FBXDump.java new file mode 100644 index 000000000..f309a5052 --- /dev/null +++ b/jme3-plugins/src/fbx/java/com/jme3/scene/plugins/fbx/file/FBXDump.java @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2009-2015 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.jme3.scene.plugins.fbx.file; + +import java.io.OutputStream; +import java.io.PrintStream; +import java.lang.reflect.Array; +import java.text.DecimalFormat; +import java.util.HashMap; +import java.util.Map; +import static org.omg.IOP.IORHelper.id; + +/** + * Quick n' dirty dumper of FBX binary files. + * + * Outputs a format similar to an ASCII FBX file. + * + * @author Kirill Vainer + */ +public final class FBXDump { + + private static final DecimalFormat DECIMAL_FORMAT + = new DecimalFormat("0.0000000000"); + + private FBXDump() { } + + /** + * Creates a map between object UIDs and the objects themselves. + * + * @param file The file to create the mappings for. + * @return The UID to object map. + */ + private static Map createUidToObjectMap(FBXFile file) { + Map uidToObjectMap = new HashMap(); + for (FBXElement rootElement : file.rootElements) { + if (rootElement.id.equals("Objects")) { + for (FBXElement fbxObj : rootElement.children) { + if (fbxObj.propertiesTypes[0] != 'L') { + continue; // error + } + Long uid = (Long) fbxObj.properties.get(0); + uidToObjectMap.put(uid, fbxObj); + } + } + } + return uidToObjectMap; + } + + /** + * Dump FBX to standard output. + * + * @param file the file to dump. + */ + public static void dumpFBX(FBXFile file) { + dumpFBX(file, System.out); + } + + /** + * Dump FBX to the given output stream. + * + * @param file the file to dump. + * @param out the output stream where to output. + */ + public static void dumpFBX(FBXFile file, OutputStream out) { + Map uidToObjectMap = createUidToObjectMap(file); + PrintStream ps = new PrintStream(out); + for (FBXElement rootElement : file.rootElements) { + dumpFBXElement(rootElement, ps, 0, uidToObjectMap); + } + } + + private static String indent(int amount) { + return " ".substring(0, amount); + } + + /** + * Convert FBX string - this replaces all instances of + * \x00\x01 to "::". + * + * @param string The string to convert + * @return + */ + private static String convertFBXString(String string) { + return string.replaceAll("\u0000\u0001", "::"); + } + + protected static void dumpFBXProperty(String id, char propertyType, + Object property, PrintStream ps, + Map uidToObjectMap) { + switch (propertyType) { + case 'S': + // String + String str = (String) property; + ps.print("\"" + convertFBXString(str) + "\""); + break; + case 'R': + // RAW data. + byte[] bytes = (byte[]) property; + ps.print("["); + for (int j = 0; j < bytes.length; j++) { + ps.print(String.format("%02X", bytes[j] & 0xff)); + if (j != bytes.length - 1) { + ps.print(" "); + } + } + ps.print("]"); + break; + case 'D': + case 'F': + // Double, Float. + if (property instanceof Double) { + ps.print(DECIMAL_FORMAT.format((Double)property)); + } else if (property instanceof Float) { + ps.print(DECIMAL_FORMAT.format((Float)property)); + } else { + ps.print(property); + } + break; + case 'I': + case 'Y': + // Integer, Signed Short. + ps.print(property); + break; + case 'C': + // Boolean + ps.print((Boolean)property ? "1" : "0"); + break; + case 'L': + // Long + // If this is a connection, decode UID into object name. + if (id.equals("C")) { + Long uid = (Long) property; + FBXElement element = uidToObjectMap.get(uid); + if (element != null) { + String name = (String) element.properties.get(1); + ps.print("\"" + convertFBXString(name) + "\""); + } else { + ps.print(property); + } + } else { + ps.print(property); + } + break; + case 'd': + case 'i': + case 'l': + case 'f': + // Arrays of things.. + int length = Array.getLength(property); + for (int j = 0; j < length; j++) { + Object arrayEntry = Array.get(property, j); + dumpFBXProperty(id, Character.toUpperCase(propertyType), arrayEntry, ps, uidToObjectMap); + if (j != length - 1) { + ps.print(","); + } + } + break; + default: + throw new UnsupportedOperationException("" + propertyType); + } + } + + protected static void dumpFBXElement(FBXElement el, PrintStream ps, + int indent, Map uidToObjectMap) { + // 4 spaces per tab should be OK. + String indentStr = indent(indent * 4); + String textId = el.id; + + // Properties are called 'P' and connections are called 'C'. + if (el.id.equals("P")) { + textId = "Property"; + } else if (el.id.equals("C")) { + textId = "Connect"; + } + + ps.print(indentStr + textId + ": "); + for (int i = 0; i < el.properties.size(); i++) { + Object property = el.properties.get(i); + char propertyType = el.propertiesTypes[i]; + dumpFBXProperty(el.id, propertyType, property, ps, uidToObjectMap); + if (i != el.properties.size() - 1) { + ps.print(", "); + } + } + if (el.children.isEmpty()) { + ps.println(); + } else { + ps.println(" {"); + for (FBXElement childElement : el.children) { + dumpFBXElement(childElement, ps, indent + 1, uidToObjectMap); + } + ps.println(indentStr + "}"); + } + } +} diff --git a/jme3-plugins/src/xml/java/com/jme3/export/xml/XMLImporter.java b/jme3-plugins/src/xml/java/com/jme3/export/xml/XMLImporter.java index 3e947e2b1..d531a0840 100644 --- a/jme3-plugins/src/xml/java/com/jme3/export/xml/XMLImporter.java +++ b/jme3-plugins/src/xml/java/com/jme3/export/xml/XMLImporter.java @@ -71,12 +71,15 @@ public class XMLImporter implements JmeImporter { this.assetManager = assetManager; } - public Object load(AssetInfo info) throws IOException{ + public Object load(AssetInfo info) throws IOException { assetManager = info.getManager(); InputStream in = info.openStream(); - Savable obj = load(in); - in.close(); - return obj; + try { + return load(in); + } finally { + if (in != null) + in.close(); + } } public Savable load(File f) throws IOException {