Merge branch 'master' of https://github.com/jMonkeyEngine/jmonkeyengine into GL4ShaderSupport
Conflicts: jme3-core/src/main/resources/com/jme3/asset/Desktop.cfg
This commit is contained in:
commit
5b58bda23f
@ -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;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <code>AndroidAssetManager</code> 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<? extends AssetLoader> loader = (Class<? extends AssetLoader>) 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.");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -20,6 +20,7 @@ import java.util.logging.Logger;
|
|||||||
*
|
*
|
||||||
* @author Kirill Vainer
|
* @author Kirill Vainer
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public class AndroidImageInfo extends ImageRaster {
|
public class AndroidImageInfo extends ImageRaster {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(AndroidImageInfo.class.getName());
|
private static final Logger logger = Logger.getLogger(AndroidImageInfo.class.getName());
|
||||||
|
@ -6,9 +6,6 @@ import android.graphics.Bitmap;
|
|||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
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.AudioRenderer;
|
||||||
import com.jme3.audio.android.AndroidAL;
|
import com.jme3.audio.android.AndroidAL;
|
||||||
import com.jme3.audio.android.AndroidALC;
|
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.audio.openal.EFX;
|
||||||
import com.jme3.system.*;
|
import com.jme3.system.*;
|
||||||
import com.jme3.system.JmeContext.Type;
|
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 com.jme3.util.AndroidScreenshots;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.URL;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
@ -42,6 +35,11 @@ public class JmeAndroidSystem extends JmeSystemDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPlatformAssetConfigPath() {
|
||||||
|
return "com/jme3/asset/Android.cfg";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeImageFile(OutputStream outStream, String format, ByteBuffer imageData, int width, int height) throws IOException {
|
public void writeImageFile(OutputStream outStream, String format, ByteBuffer imageData, int width, int height) throws IOException {
|
||||||
Bitmap bitmapImage = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
Bitmap bitmapImage = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||||
@ -58,27 +56,6 @@ public class JmeAndroidSystem extends JmeSystemDelegate {
|
|||||||
bitmapImage.recycle();
|
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
|
@Override
|
||||||
public void showErrorDialog(String message) {
|
public void showErrorDialog(String message) {
|
||||||
final String finalMsg = message;
|
final String finalMsg = message;
|
||||||
@ -122,21 +99,6 @@ public class JmeAndroidSystem extends JmeSystemDelegate {
|
|||||||
AL al = new AndroidAL();
|
AL al = new AndroidAL();
|
||||||
EFX efx = new AndroidEFX();
|
EFX efx = new AndroidEFX();
|
||||||
return new ALAudioRenderer(al, alc, efx);
|
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
|
@Override
|
||||||
@ -145,6 +107,7 @@ public class JmeAndroidSystem extends JmeSystemDelegate {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
System.setProperty("org.xml.sax.driver", "org.xmlpull.v1.sax2.Driver");
|
||||||
logger.log(Level.INFO, getBuildInfo());
|
logger.log(Level.INFO, getBuildInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@ import java.nio.ByteBuffer;
|
|||||||
*
|
*
|
||||||
* @author Kirill Vainer
|
* @author Kirill Vainer
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public class AndroidBufferImageLoader implements AssetLoader {
|
public class AndroidBufferImageLoader implements AssetLoader {
|
||||||
|
|
||||||
private final byte[] tempData = new byte[16 * 1024];
|
private final byte[] tempData = new byte[16 * 1024];
|
||||||
|
@ -8,6 +8,7 @@ import com.jme3.texture.Image;
|
|||||||
import com.jme3.texture.image.ColorSpace;
|
import com.jme3.texture.image.ColorSpace;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public class AndroidImageLoader implements AssetLoader {
|
public class AndroidImageLoader implements AssetLoader {
|
||||||
|
|
||||||
public Object load(AssetInfo info) throws IOException {
|
public Object load(AssetInfo info) throws IOException {
|
||||||
|
@ -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
|
@ -56,12 +56,12 @@ import java.util.Map.Entry;
|
|||||||
* 4) Animation event listeners
|
* 4) Animation event listeners
|
||||||
* 5) Animated model cloning
|
* 5) Animated model cloning
|
||||||
* 6) Animated model binary import/export
|
* 6) Animated model binary import/export
|
||||||
|
* 7) Hardware skinning
|
||||||
|
* 8) Attachments
|
||||||
|
* 9) Add/remove skins
|
||||||
*
|
*
|
||||||
* Planned:
|
* Planned:
|
||||||
* 1) Hardware skinning
|
* 1) Morph/Pose animation
|
||||||
* 2) Morph/Pose animation
|
|
||||||
* 3) Attachments
|
|
||||||
* 4) Add/remove skins
|
|
||||||
*
|
*
|
||||||
* @author Kirill Vainer
|
* @author Kirill Vainer
|
||||||
*/
|
*/
|
||||||
|
@ -174,28 +174,30 @@ public class Application implements SystemListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initAssetManager(){
|
private void initAssetManager(){
|
||||||
|
URL assetCfgUrl = null;
|
||||||
|
|
||||||
if (settings != null){
|
if (settings != null){
|
||||||
String assetCfg = settings.getString("AssetConfigURL");
|
String assetCfg = settings.getString("AssetConfigURL");
|
||||||
if (assetCfg != null){
|
if (assetCfg != null){
|
||||||
URL url = null;
|
|
||||||
try {
|
try {
|
||||||
url = new URL(assetCfg);
|
assetCfgUrl = new URL(assetCfg);
|
||||||
} catch (MalformedURLException ex) {
|
} catch (MalformedURLException ex) {
|
||||||
}
|
}
|
||||||
if (url == null) {
|
if (assetCfgUrl == null) {
|
||||||
url = Application.class.getClassLoader().getResource(assetCfg);
|
assetCfgUrl = Application.class.getClassLoader().getResource(assetCfg);
|
||||||
if (url == null) {
|
if (assetCfgUrl == null) {
|
||||||
logger.log(Level.SEVERE, "Unable to access AssetConfigURL in asset config:{0}", assetCfg);
|
logger.log(Level.SEVERE, "Unable to access AssetConfigURL in asset config:{0}", assetCfg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assetManager = JmeSystem.newAssetManager(url);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (assetCfgUrl == null) {
|
||||||
|
String assetCfg = JmeSystem.getPlatformAssetConfigPath();
|
||||||
|
assetCfgUrl = Thread.currentThread().getContextClassLoader().getResource(assetCfg);
|
||||||
|
}
|
||||||
if (assetManager == null){
|
if (assetManager == null){
|
||||||
assetManager = JmeSystem.newAssetManager(
|
assetManager = JmeSystem.newAssetManager(assetCfgUrl);
|
||||||
Thread.currentThread().getContextClassLoader()
|
|
||||||
.getResource("com/jme3/asset/Desktop.cfg"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,9 @@ package com.jme3.asset;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
@ -42,97 +45,77 @@ import java.util.logging.Logger;
|
|||||||
* <br/><br/>
|
* <br/><br/>
|
||||||
* The config file is specified with the following format:
|
* The config file is specified with the following format:
|
||||||
* <code>
|
* <code>
|
||||||
|
* "INCLUDE" <path>
|
||||||
* "LOADER" <class> : (<extension> ",")* <extension>
|
* "LOADER" <class> : (<extension> ",")* <extension>
|
||||||
* "LOCATOR" <path> <class> : (<extension> ",")* <extension>
|
* "LOCATOR" <path> <class>
|
||||||
* </code>
|
* </code>
|
||||||
*
|
*
|
||||||
* @author Kirill Vainer
|
* @author Kirill Vainer
|
||||||
*/
|
*/
|
||||||
public class AssetConfig {
|
public final class AssetConfig {
|
||||||
|
|
||||||
private AssetManager manager;
|
private static final Logger logger = Logger.getLogger(AssetConfig.class.getName());
|
||||||
|
|
||||||
public AssetConfig(AssetManager manager){
|
private AssetConfig() { }
|
||||||
this.manager = manager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void loadText(InputStream in) throws IOException{
|
private static Class acquireClass(String name) {
|
||||||
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 Class acquireClass(String name) {
|
|
||||||
try {
|
try {
|
||||||
Class clazz = Class.forName(name);
|
return Class.forName(name);
|
||||||
return clazz;
|
|
||||||
} catch (ClassNotFoundException ex) {
|
} catch (ClassNotFoundException ex) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
public static void loadText(AssetManager assetManager, URL configUrl) throws IOException{
|
||||||
private static String readString(DataInput dataIn) throws IOException{
|
InputStream in = configUrl.openStream();
|
||||||
int length = dataIn.readUnsignedShort();
|
try {
|
||||||
char[] chrs = new char[length];
|
Scanner scan = new Scanner(in);
|
||||||
for (int i = 0; i < length; i++){
|
scan.useLocale(Locale.US); // Fix commas / periods ??
|
||||||
chrs[i] = (char) dataIn.readUnsignedByte();
|
while (scan.hasNext()){
|
||||||
}
|
String cmd = scan.next();
|
||||||
return String.valueOf(chrs);
|
if (cmd.equals("LOADER")){
|
||||||
}
|
String loaderClass = scan.next();
|
||||||
|
String colon = scan.next();
|
||||||
public void loadBinary(DataInput dataIn) throws IOException{
|
if (!colon.equals(":")){
|
||||||
// read signature and version
|
throw new IOException("Expected ':', got '"+colon+"'");
|
||||||
|
}
|
||||||
// how many locator entries?
|
String extensionsList = scan.nextLine();
|
||||||
int locatorEntries = dataIn.readUnsignedShort();
|
String[] extensions = extensionsList.split(",");
|
||||||
for (int i = 0; i < locatorEntries; i++){
|
for (int i = 0; i < extensions.length; i++){
|
||||||
String locatorClazz = readString(dataIn);
|
extensions[i] = extensions[i].trim();
|
||||||
String rootPath = readString(dataIn);
|
}
|
||||||
manager.registerLocator(rootPath, locatorClazz);
|
Class clazz = acquireClass(loaderClass);
|
||||||
}
|
if (clazz != null) {
|
||||||
|
assetManager.registerLoader(clazz, extensions);
|
||||||
int loaderEntries = dataIn.readUnsignedShort();
|
} else {
|
||||||
for (int i = 0; i < loaderEntries; i++){
|
logger.log(Level.WARNING, "Cannot find loader {0}", loaderClass);
|
||||||
String loaderClazz = readString(dataIn);
|
}
|
||||||
int numExtensions = dataIn.readUnsignedByte();
|
} else if (cmd.equals("LOCATOR")) {
|
||||||
String[] extensions = new String[numExtensions];
|
String rootPath = scan.next();
|
||||||
for (int j = 0; j < numExtensions; j++){
|
String locatorClass = scan.nextLine().trim();
|
||||||
extensions[j] = readString(dataIn);
|
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 + "'");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
manager.registerLoader(loaderClazz, extensions);
|
if (in != null) in.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,8 @@ import com.jme3.shader.ShaderGenerator;
|
|||||||
import com.jme3.shader.ShaderKey;
|
import com.jme3.shader.ShaderKey;
|
||||||
import com.jme3.texture.Texture;
|
import com.jme3.texture.Texture;
|
||||||
import com.jme3.texture.plugins.TGALoader;
|
import com.jme3.texture.plugins.TGALoader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -75,7 +77,15 @@ import java.util.List;
|
|||||||
* <li>{@link TGALoader} - Used to load Targa image files</li>
|
* <li>{@link TGALoader} - Used to load Targa image files</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* <p>
|
* <p>
|
||||||
* 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 {
|
public interface AssetManager {
|
||||||
|
|
||||||
@ -100,46 +110,13 @@ public interface AssetManager {
|
|||||||
*/
|
*/
|
||||||
public List<ClassLoader> getClassLoaders();
|
public List<ClassLoader> 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.
|
* Register an {@link AssetLoader} by using a class object.
|
||||||
*
|
*
|
||||||
* @param loaderClass
|
* @param loaderClass The loader class to register.
|
||||||
* @param extensions
|
* @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<? extends AssetLoader> loaderClass, String ... extensions);
|
public void registerLoader(Class<? extends AssetLoader> loaderClass, String ... extensions);
|
||||||
|
|
||||||
@ -206,18 +183,6 @@ public interface AssetManager {
|
|||||||
*/
|
*/
|
||||||
public void clearAssetEventListeners();
|
public void clearAssetEventListeners();
|
||||||
|
|
||||||
/**
|
|
||||||
* Set an {@link AssetEventListener} to receive events from this
|
|
||||||
* <code>AssetManager</code>. 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}.
|
* Manually locates an asset with the given {@link AssetKey}.
|
||||||
* This method should be used for debugging or internal uses.
|
* This method should be used for debugging or internal uses.
|
||||||
@ -233,6 +198,23 @@ public interface AssetManager {
|
|||||||
*/
|
*/
|
||||||
public AssetInfo locateAsset(AssetKey<?> key);
|
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 <T> 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> T loadAssetFromStream(AssetKey<T> key, InputStream inputStream);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load an asset from a key, the asset will be located
|
* Load an asset from a key, the asset will be located
|
||||||
* by one of the {@link AssetLocator} implementations provided in the
|
* by one of the {@link AssetLocator} implementations provided in the
|
||||||
@ -244,17 +226,18 @@ public interface AssetManager {
|
|||||||
*
|
*
|
||||||
* @param <T> The object type that will be loaded from the AssetKey instance.
|
* @param <T> The object type that will be loaded from the AssetKey instance.
|
||||||
* @param key The AssetKey
|
* @param key The AssetKey
|
||||||
* @return The loaded asset, or null if it was failed to be located
|
* @return The loaded asset.
|
||||||
* or loaded.
|
*
|
||||||
|
* @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> T loadAsset(AssetKey<T> key);
|
public <T> T loadAsset(AssetKey<T> key);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load an asset by name, calling this method
|
* Load an asset by name, calling this method is the same as calling
|
||||||
* is the same as calling
|
* <code>loadAsset(new AssetKey(name))</code>.
|
||||||
* <code>
|
|
||||||
* loadAsset(new AssetKey(name)).
|
|
||||||
* </code>
|
|
||||||
*
|
*
|
||||||
* @param name The name of the asset to load.
|
* @param name The name of the asset to load.
|
||||||
* @return The loaded asset, or null if failed to be loaded.
|
* @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,
|
* 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.
|
* @param key The {@link TextureKey} to use for loading.
|
||||||
* @return The loaded texture, or null if failed to be loaded.
|
* @return The loaded texture, or null if failed to be loaded.
|
||||||
@ -276,7 +259,9 @@ public interface AssetManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads texture file, supported types are BMP, JPG, PNG, GIF,
|
* 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.
|
* @param name The name of the texture to load.
|
||||||
* @return The texture that was loaded
|
* @return The texture that was loaded
|
||||||
@ -306,7 +291,8 @@ public interface AssetManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads a 3D model with a ModelKey.
|
* 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
|
* @param key Asset key of the model to load
|
||||||
* @return The model that was loaded
|
* @return The model that was loaded
|
||||||
*
|
*
|
||||||
@ -315,8 +301,9 @@ public interface AssetManager {
|
|||||||
public Spatial loadModel(ModelKey key);
|
public Spatial loadModel(ModelKey key);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads a 3D model. Models can be jME3 object files (J3O) or
|
* Loads a 3D model. Models can be jME3 object files (J3O),
|
||||||
* OgreXML/OBJ files.
|
* OgreXML (mesh.xml), BLEND, FBX and OBJ files.
|
||||||
|
*
|
||||||
* @param name Asset name of the model to load
|
* @param name Asset name of the model to load
|
||||||
* @return The model that was loaded
|
* @return The model that was loaded
|
||||||
*
|
*
|
||||||
@ -381,4 +368,53 @@ public interface AssetManager {
|
|||||||
*/
|
*/
|
||||||
public ShaderGenerator getShaderGenerator(EnumSet<Caps> caps);
|
public ShaderGenerator getShaderGenerator(EnumSet<Caps> caps);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve an asset from the asset cache.
|
||||||
|
*
|
||||||
|
* <b>NOTE:</b> Do <em>not</em> 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 <T> 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, <code>null</code>.
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException If {@link AssetKey#getCacheType() caching}
|
||||||
|
* is disabled for the key.
|
||||||
|
*/
|
||||||
|
public <T> T getFromCache(AssetKey<T> key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject an asset into the asset cache.
|
||||||
|
*
|
||||||
|
* <b>NOTE:</b> Do <em>not</em> 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 <T> 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 <T> void addToCache(AssetKey<T> key, T asset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete an asset from the asset cache.
|
||||||
|
*
|
||||||
|
* @param <T> 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 <T> boolean deleteFromCache(AssetKey<T> key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the asset cache.
|
||||||
|
*/
|
||||||
|
public void clearCache();
|
||||||
}
|
}
|
||||||
|
@ -81,11 +81,6 @@ public class DesktopAssetManager implements AssetManager {
|
|||||||
this(null);
|
this(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public DesktopAssetManager(boolean loadDefaults){
|
|
||||||
this(Thread.currentThread().getContextClassLoader().getResource("com/jme3/asset/Desktop.cfg"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public DesktopAssetManager(URL configFile){
|
public DesktopAssetManager(URL configFile){
|
||||||
if (configFile != null){
|
if (configFile != null){
|
||||||
loadConfigFile(configFile);
|
loadConfigFile(configFile);
|
||||||
@ -93,20 +88,11 @@ public class DesktopAssetManager implements AssetManager {
|
|||||||
logger.fine("DesktopAssetManager created.");
|
logger.fine("DesktopAssetManager created.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadConfigFile(URL configFile){
|
private void loadConfigFile(URL configFile) {
|
||||||
InputStream stream = null;
|
try {
|
||||||
try{
|
AssetConfig.loadText(this, configFile);
|
||||||
AssetConfig cfg = new AssetConfig(this);
|
} catch (IOException ex) {
|
||||||
stream = configFile.openStream();
|
|
||||||
cfg.loadText(stream);
|
|
||||||
}catch (IOException ex){
|
|
||||||
logger.log(Level.SEVERE, "Failed to load asset config", 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;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public <T> T getFromCache(AssetKey<T> key) {
|
public <T> T getFromCache(AssetKey<T> key) {
|
||||||
AssetCache cache = handler.getCache(key.getCacheType());
|
AssetCache cache = handler.getCache(key.getCacheType());
|
||||||
if (cache != null) {
|
if (cache != null) {
|
||||||
@ -221,6 +208,7 @@ public class DesktopAssetManager implements AssetManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public <T> void addToCache(AssetKey<T> key, T asset) {
|
public <T> void addToCache(AssetKey<T> key, T asset) {
|
||||||
AssetCache cache = handler.getCache(key.getCacheType());
|
AssetCache cache = handler.getCache(key.getCacheType());
|
||||||
if (cache != null) {
|
if (cache != null) {
|
||||||
@ -231,6 +219,7 @@ public class DesktopAssetManager implements AssetManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public <T> boolean deleteFromCache(AssetKey<T> key) {
|
public <T> boolean deleteFromCache(AssetKey<T> key) {
|
||||||
AssetCache cache = handler.getCache(key.getCacheType());
|
AssetCache cache = handler.getCache(key.getCacheType());
|
||||||
if (cache != null) {
|
if (cache != null) {
|
||||||
@ -240,6 +229,7 @@ public class DesktopAssetManager implements AssetManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void clearCache(){
|
public void clearCache(){
|
||||||
handler.clearCache();
|
handler.clearCache();
|
||||||
if (logger.isLoggable(Level.FINER)){
|
if (logger.isLoggable(Level.FINER)){
|
||||||
@ -248,13 +238,110 @@ public class DesktopAssetManager implements AssetManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <font color="red">Thread-safe.</font>
|
* Loads an asset that has already been located.
|
||||||
|
* @param <T> 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
|
||||||
*
|
*
|
||||||
* @param <T>
|
* @throws AssetLoadException If failed to load asset due to exception or
|
||||||
* @param key
|
* other error.
|
||||||
* @return the loaded asset
|
|
||||||
*/
|
*/
|
||||||
public <T> T loadAsset(AssetKey<T> key){
|
protected <T> T loadLocatedAsset(AssetKey<T> 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 <T> 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.
|
||||||
|
*/
|
||||||
|
protected <T> T registerAndCloneSmartAsset(AssetKey<T> 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> T loadAssetFromStream(AssetKey<T> 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> T loadAsset(AssetKey<T> key){
|
||||||
if (key == null)
|
if (key == null)
|
||||||
throw new IllegalArgumentException("key cannot be 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;
|
Object obj = cache != null ? cache.getFromCache(key) : null;
|
||||||
if (obj == null){
|
if (obj == null){
|
||||||
// Asset not in cache, load it from file system.
|
// Asset not in cache, load it from file system.
|
||||||
AssetLoader loader = handler.aquireLoader(key);
|
|
||||||
AssetInfo info = handler.tryLocate(key);
|
AssetInfo info = handler.tryLocate(key);
|
||||||
if (info == null){
|
if (info == null){
|
||||||
if (handler.getParentKey() != null){
|
if (handler.getParentKey() != null){
|
||||||
@ -283,56 +369,13 @@ public class DesktopAssetManager implements AssetManager {
|
|||||||
throw new AssetNotFoundException(key.toString());
|
throw new AssetNotFoundException(key.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
obj = loadLocatedAsset(key, info, proc, cache);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// object obj is the original asset
|
|
||||||
// create an instance for user
|
|
||||||
T clone = (T) obj;
|
T clone = (T) obj;
|
||||||
if (clone instanceof CloneableSmartAsset){
|
|
||||||
if (proc == null){
|
if (obj instanceof CloneableSmartAsset) {
|
||||||
throw new IllegalStateException("Asset implements "
|
clone = registerAndCloneSmartAsset(key, clone, proc, cache);
|
||||||
+ "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;
|
return clone;
|
||||||
|
@ -204,8 +204,10 @@ public class ImplHandler {
|
|||||||
|
|
||||||
public void clearCache(){
|
public void clearCache(){
|
||||||
// The iterator of the values collection is thread safe
|
// The iterator of the values collection is thread safe
|
||||||
for (AssetCache cache : classToCacheMap.values()){
|
synchronized (classToCacheMap) {
|
||||||
cache.clearCache();
|
for (AssetCache cache : classToCacheMap.values()){
|
||||||
|
cache.clearCache();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
* Copyright (c) 2009-2015 jMonkeyEngine
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* 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 {
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
public interface Converter<T> {
|
|
||||||
public T convert(T input, Map<String, String> params);
|
|
||||||
}
|
}
|
@ -77,7 +77,6 @@ public class WeakRefAssetCache implements AssetCache {
|
|||||||
// might not even have this asset anymore, it is OK.
|
// might not even have this asset anymore, it is OK.
|
||||||
if (assetCache.remove(ref.assetKey) != null){
|
if (assetCache.remove(ref.assetKey) != null){
|
||||||
removedAssets ++;
|
removedAssets ++;
|
||||||
//System.out.println("WeakRefAssetCache: The asset " + ref.assetKey + " was purged from the cache");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (removedAssets >= 1) {
|
if (removedAssets >= 1) {
|
||||||
@ -92,10 +91,6 @@ public class WeakRefAssetCache implements AssetCache {
|
|||||||
// thread is loading an asset with the same key ..
|
// thread is loading an asset with the same key ..
|
||||||
AssetRef ref = new AssetRef(key, obj, refQueue);
|
AssetRef ref = new AssetRef(key, obj, refQueue);
|
||||||
assetCache.put(key, ref);
|
assetCache.put(key, ref);
|
||||||
|
|
||||||
// Texture t = (Texture) obj;
|
|
||||||
// Image i = t.getImage();
|
|
||||||
// System.out.println("add to cache " + System.identityHashCode(i));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T getFromCache(AssetKey<T> key) {
|
public <T> T getFromCache(AssetKey<T> key) {
|
||||||
|
@ -42,7 +42,7 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <codeWeakRefCloneAssetCache</code> caches cloneable assets in a weak-key
|
* <code>WeakRefCloneAssetCache</code> caches cloneable assets in a weak-key
|
||||||
* cache, allowing them to be collected when memory is low.
|
* cache, allowing them to be collected when memory is low.
|
||||||
* The cache stores weak references to the asset keys, so that
|
* The cache stores weak references to the asset keys, so that
|
||||||
* when all clones of the original asset are collected, will cause the
|
* when all clones of the original asset are collected, will cause the
|
||||||
|
30
jme3-core/src/main/java/com/jme3/asset/cache/package.html
vendored
Normal file
30
jme3-core/src/main/java/com/jme3/asset/cache/package.html
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title></title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<code>com.jme3.asset.cache</code> contains the {@link com.jme3.asset.cache.AssetCache}
|
||||||
|
interface as well as its implementations.<br>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
|
||||||
|
<h3>AssetCaches</h3>
|
||||||
|
The asset cache implementations are used by {@link com.jme3.asset.AssetManager}
|
||||||
|
to cache loaded assets for faster access if they are requested again.
|
||||||
|
<p>
|
||||||
|
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.
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -863,10 +863,12 @@ public class RenderManager {
|
|||||||
private void setViewPort(Camera cam) {
|
private void setViewPort(Camera cam) {
|
||||||
// this will make sure to update viewport only if needed
|
// this will make sure to update viewport only if needed
|
||||||
if (cam != prevCam || cam.isViewportChanged()) {
|
if (cam != prevCam || cam.isViewportChanged()) {
|
||||||
viewX = (int) (cam.getViewPortLeft() * cam.getWidth());
|
viewX = (int) (cam.getViewPortLeft() * cam.getWidth());
|
||||||
viewY = (int) (cam.getViewPortBottom() * cam.getHeight());
|
viewY = (int) (cam.getViewPortBottom() * cam.getHeight());
|
||||||
viewWidth = ((int)(cam.getViewPortRight() * cam.getWidth())) - ((int)(cam.getViewPortLeft() * cam.getWidth()));
|
int viewX2 = (int) (cam.getViewPortRight() * cam.getWidth());
|
||||||
viewHeight = ((int)(cam.getViewPortTop() * cam.getHeight())) - ((int)(cam.getViewPortBottom() * cam.getHeight()));
|
int viewY2 = (int) (cam.getViewPortTop() * cam.getHeight());
|
||||||
|
viewWidth = viewX2 - viewX;
|
||||||
|
viewHeight = viewY2 - viewY;
|
||||||
uniformBindingManager.setViewPort(viewX, viewY, viewWidth, viewHeight);
|
uniformBindingManager.setViewPort(viewX, viewY, viewWidth, viewHeight);
|
||||||
renderer.setViewPort(viewX, viewY, viewWidth, viewHeight);
|
renderer.setViewPort(viewX, viewY, viewWidth, viewHeight);
|
||||||
renderer.setClipRect(viewX, viewY, viewWidth, viewHeight);
|
renderer.setClipRect(viewX, viewY, viewWidth, viewHeight);
|
||||||
|
@ -35,6 +35,7 @@ import com.jme3.asset.AssetManager;
|
|||||||
import com.jme3.audio.AudioRenderer;
|
import com.jme3.audio.AudioRenderer;
|
||||||
import com.jme3.input.SoftTextDialogInput;
|
import com.jme3.input.SoftTextDialogInput;
|
||||||
import com.jme3.texture.Image;
|
import com.jme3.texture.Image;
|
||||||
|
import com.jme3.texture.image.DefaultImageRaster;
|
||||||
import com.jme3.texture.image.ImageRaster;
|
import com.jme3.texture.image.ImageRaster;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -166,6 +167,15 @@ public class JmeSystem {
|
|||||||
return systemDelegate.newAudioRenderer(settings);
|
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) {
|
public static ImageRaster createImageRaster(Image image, int slice) {
|
||||||
checkDelegate();
|
checkDelegate();
|
||||||
return systemDelegate.createImageRaster(image, slice);
|
return systemDelegate.createImageRaster(image, slice);
|
||||||
|
@ -32,9 +32,11 @@
|
|||||||
package com.jme3.system;
|
package com.jme3.system;
|
||||||
|
|
||||||
import com.jme3.asset.AssetManager;
|
import com.jme3.asset.AssetManager;
|
||||||
|
import com.jme3.asset.DesktopAssetManager;
|
||||||
import com.jme3.audio.AudioRenderer;
|
import com.jme3.audio.AudioRenderer;
|
||||||
import com.jme3.input.SoftTextDialogInput;
|
import com.jme3.input.SoftTextDialogInput;
|
||||||
import com.jme3.texture.Image;
|
import com.jme3.texture.Image;
|
||||||
|
import com.jme3.texture.image.DefaultImageRaster;
|
||||||
import com.jme3.texture.image.ImageRaster;
|
import com.jme3.texture.image.ImageRaster;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -117,16 +119,26 @@ public abstract class JmeSystemDelegate {
|
|||||||
public void setSoftTextDialogInput(SoftTextDialogInput input) {
|
public void setSoftTextDialogInput(SoftTextDialogInput input) {
|
||||||
softTextDialogInput = input;
|
softTextDialogInput = input;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SoftTextDialogInput getSoftTextDialogInput() {
|
public SoftTextDialogInput getSoftTextDialogInput() {
|
||||||
return softTextDialogInput;
|
return softTextDialogInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final AssetManager newAssetManager(URL configFile) {
|
||||||
|
return new DesktopAssetManager(configFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 writeImageFile(OutputStream outStream, String format, ByteBuffer imageData, int width, int height) throws IOException;
|
||||||
|
|
||||||
public abstract AssetManager newAssetManager(URL configFile);
|
|
||||||
|
|
||||||
public abstract AssetManager newAssetManager();
|
|
||||||
|
|
||||||
public abstract void showErrorDialog(String message);
|
public abstract void showErrorDialog(String message);
|
||||||
|
|
||||||
public abstract boolean showSettingsDialog(AppSettings sourceSettings, boolean loadFromRegistry);
|
public abstract boolean showSettingsDialog(AppSettings sourceSettings, boolean loadFromRegistry);
|
||||||
@ -181,13 +193,13 @@ public abstract class JmeSystemDelegate {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract String getPlatformAssetConfigPath();
|
||||||
|
|
||||||
public abstract JmeContext newContext(AppSettings settings, JmeContext.Type contextType);
|
public abstract JmeContext newContext(AppSettings settings, JmeContext.Type contextType);
|
||||||
|
|
||||||
public abstract AudioRenderer newAudioRenderer(AppSettings settings);
|
public abstract AudioRenderer newAudioRenderer(AppSettings settings);
|
||||||
|
|
||||||
public abstract void initialize(AppSettings settings);
|
public abstract void initialize(AppSettings settings);
|
||||||
|
|
||||||
public abstract ImageRaster createImageRaster(Image image, int slice);
|
|
||||||
|
|
||||||
public abstract void showSoftKeyboard(boolean show);
|
public abstract void showSoftKeyboard(boolean show);
|
||||||
}
|
}
|
||||||
|
@ -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.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.audio.plugins.OGGLoader : ogg
|
||||||
LOADER com.jme3.cursors.plugins.CursorLoader : ani, cur, ico
|
LOADER com.jme3.cursors.plugins.CursorLoader : ani, cur, ico
|
||||||
LOADER com.jme3.material.plugins.J3MLoader : j3m
|
LOADER com.jme3.material.plugins.J3MLoader : j3m
|
||||||
|
26
jme3-core/src/main/resources/com/jme3/asset/General.cfg
Normal file
26
jme3-core/src/main/resources/com/jme3/asset/General.cfg
Normal file
@ -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
|
@ -41,6 +41,16 @@ import java.util.logging.Logger;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The <code>ClasspathLocator</code> looks up an asset in the classpath.
|
* The <code>ClasspathLocator</code> 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 <code>ClasspathLocator</code>
|
||||||
|
* 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 <code>.JAR</code> file instead of a folder.
|
||||||
|
*
|
||||||
* @author Kirill Vainer
|
* @author Kirill Vainer
|
||||||
*/
|
*/
|
||||||
public class ClasspathLocator implements AssetLocator {
|
public class ClasspathLocator implements AssetLocator {
|
||||||
|
@ -37,6 +37,7 @@ import java.io.*;
|
|||||||
/**
|
/**
|
||||||
* <code>FileLocator</code> allows you to specify a folder where to
|
* <code>FileLocator</code> allows you to specify a folder where to
|
||||||
* look for assets.
|
* look for assets.
|
||||||
|
*
|
||||||
* @author Kirill Vainer
|
* @author Kirill Vainer
|
||||||
*/
|
*/
|
||||||
public class FileLocator implements AssetLocator {
|
public class FileLocator implements AssetLocator {
|
||||||
|
@ -52,6 +52,23 @@ import java.util.zip.Inflater;
|
|||||||
import java.util.zip.InflaterInputStream;
|
import java.util.zip.InflaterInputStream;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <code>HttpZipLocator</code> is similar to {@link ZipLocator}, except
|
||||||
|
* it allows loading assets from a <code>.ZIP</code> file on the web instead of
|
||||||
|
* on the local filesystem.
|
||||||
|
* <p>
|
||||||
|
* The root path must be a valid HTTP(S) {@link URL} pointing to ZIP or
|
||||||
|
* ZIP-like file (such as a JAR). For example,<br>
|
||||||
|
* <code>https://www.example.com/my/sub/path/assets.zip</code>.
|
||||||
|
* <p>
|
||||||
|
* The locator is designed in such a way that it does not require downloading
|
||||||
|
* the entire <code>.ZIP</code> 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 {
|
public class HttpZipLocator implements AssetLocator {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(HttpZipLocator.class.getName());
|
private static final Logger logger = Logger.getLogger(HttpZipLocator.class.getName());
|
||||||
|
@ -46,6 +46,10 @@ import java.util.logging.Logger;
|
|||||||
* <code>UrlLocator</code> is a locator that combines a root URL
|
* <code>UrlLocator</code> is a locator that combines a root URL
|
||||||
* and the given path in the AssetKey to construct a new URL
|
* and the given path in the AssetKey to construct a new URL
|
||||||
* that allows locating the asset.
|
* that allows locating the asset.
|
||||||
|
* <p>
|
||||||
|
* The root path must be a valid {@link URL}, for example, <br>
|
||||||
|
* <code>https://www.example.com/assets/</code>
|
||||||
|
*
|
||||||
* @author Kirill Vainer
|
* @author Kirill Vainer
|
||||||
*/
|
*/
|
||||||
public class UrlLocator implements AssetLocator {
|
public class UrlLocator implements AssetLocator {
|
||||||
|
@ -40,7 +40,13 @@ import java.util.zip.ZipEntry;
|
|||||||
import java.util.zip.ZipFile;
|
import java.util.zip.ZipFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>ZipLocator</code> is a locator that looks up resources in a .ZIP file.
|
* <code>ZipLocator</code> is a locator that looks up resources in a
|
||||||
|
* <code>.ZIP</code> file.
|
||||||
|
*
|
||||||
|
* The root path must be a valid ZIP or ZIP-like {@link File file},
|
||||||
|
* for example, <br>
|
||||||
|
* <code>C:\My App\data.zip</code>
|
||||||
|
*
|
||||||
* @author Kirill Vainer
|
* @author Kirill Vainer
|
||||||
*/
|
*/
|
||||||
public class ZipLocator implements AssetLocator {
|
public class ZipLocator implements AssetLocator {
|
||||||
|
@ -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 <input folder>");
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -75,8 +75,8 @@ import javax.swing.SwingUtilities;
|
|||||||
public class JmeDesktopSystem extends JmeSystemDelegate {
|
public class JmeDesktopSystem extends JmeSystemDelegate {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AssetManager newAssetManager(URL configFile) {
|
public String getPlatformAssetConfigPath() {
|
||||||
return new DesktopAssetManager(configFile);
|
return "com/jme3/asset/Desktop.cfg";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BufferedImage verticalFlip(BufferedImage original) {
|
private static BufferedImage verticalFlip(BufferedImage original) {
|
||||||
@ -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
|
@Override
|
||||||
public void showErrorDialog(String message) {
|
public void showErrorDialog(String message) {
|
||||||
final String msg = message;
|
final String msg = message;
|
||||||
|
4
jme3-ios/src/main/java/com/jme3/asset/IOS.cfg
Normal file
4
jme3-ios/src/main/java/com/jme3/asset/IOS.cfg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
INCLUDE com/jme3/asset/General.cfg
|
||||||
|
|
||||||
|
# IOS specific loaders
|
||||||
|
LOADER com.jme3.system.ios.IosImageLoader : jpg, bmp, gif, png, jpeg
|
@ -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<? extends AssetLoader> loader = (Class<? extends AssetLoader>) 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.");
|
|
||||||
}
|
|
||||||
}
|
|
@ -31,17 +31,13 @@
|
|||||||
*/
|
*/
|
||||||
package com.jme3.system.ios;
|
package com.jme3.system.ios;
|
||||||
|
|
||||||
import com.jme3.asset.AssetManager;
|
|
||||||
import com.jme3.audio.AudioRenderer;
|
import com.jme3.audio.AudioRenderer;
|
||||||
import com.jme3.system.AppSettings;
|
import com.jme3.system.AppSettings;
|
||||||
import com.jme3.system.JmeContext;
|
import com.jme3.system.JmeContext;
|
||||||
import com.jme3.system.JmeSystemDelegate;
|
import com.jme3.system.JmeSystemDelegate;
|
||||||
import com.jme3.system.NullContext;
|
import com.jme3.system.NullContext;
|
||||||
import com.jme3.texture.Image;
|
|
||||||
import com.jme3.texture.image.ImageRaster;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.URL;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@ -51,21 +47,16 @@ import java.util.logging.Logger;
|
|||||||
*/
|
*/
|
||||||
public class JmeIosSystem extends JmeSystemDelegate {
|
public class JmeIosSystem extends JmeSystemDelegate {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPlatformAssetConfigPath() {
|
||||||
|
return "com/jme3/asset/IOS.cfg";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeImageFile(OutputStream outStream, String format, ByteBuffer imageData, int width, int height) throws IOException {
|
public void writeImageFile(OutputStream outStream, String format, ByteBuffer imageData, int width, int height) throws IOException {
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
throw new UnsupportedOperationException("Not supported yet.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public AssetManager newAssetManager(URL configFile) {
|
|
||||||
return new IosAssetManager(configFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AssetManager newAssetManager() {
|
|
||||||
return new IosAssetManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void showErrorDialog(String message) {
|
public void showErrorDialog(String message) {
|
||||||
showDialog(message);
|
showDialog(message);
|
||||||
@ -106,11 +97,6 @@ public class JmeIosSystem extends JmeSystemDelegate {
|
|||||||
// throw new UnsupportedOperationException("Not supported yet.");
|
// throw new UnsupportedOperationException("Not supported yet.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ImageRaster createImageRaster(Image image, int slice) {
|
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void showSoftKeyboard(boolean show) {
|
public void showSoftKeyboard(boolean show) {
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
throw new UnsupportedOperationException("Not supported yet.");
|
||||||
|
@ -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<Long, FBXElement> createUidToObjectMap(FBXFile file) {
|
||||||
|
Map<Long, FBXElement> uidToObjectMap = new HashMap<Long, FBXElement>();
|
||||||
|
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<Long, FBXElement> 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
|
||||||
|
* <code>\x00\x01</code> 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<Long, FBXElement> 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<Long, FBXElement> 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 + "}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -71,12 +71,15 @@ public class XMLImporter implements JmeImporter {
|
|||||||
this.assetManager = assetManager;
|
this.assetManager = assetManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object load(AssetInfo info) throws IOException{
|
public Object load(AssetInfo info) throws IOException {
|
||||||
assetManager = info.getManager();
|
assetManager = info.getManager();
|
||||||
InputStream in = info.openStream();
|
InputStream in = info.openStream();
|
||||||
Savable obj = load(in);
|
try {
|
||||||
in.close();
|
return load(in);
|
||||||
return obj;
|
} finally {
|
||||||
|
if (in != null)
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Savable load(File f) throws IOException {
|
public Savable load(File f) throws IOException {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user