/*******************************************************************************
* Copyright 2011 See AUTHORS file.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package de.swagner.piratesbigsea.com.badlogic.gdx.graphics.g3d.loaders;
import java.util.HashMap;
import java.util.Map;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.GdxRuntimeException;
import de.swagner.piratesbigsea.com.badlogic.gdx.graphics.g3d.ModelLoaderHints;
import de.swagner.piratesbigsea.com.badlogic.gdx.graphics.g3d.loaders.g3d.G3dtLoader.G3dtStillModelLoader;
import de.swagner.piratesbigsea.com.badlogic.gdx.graphics.g3d.model.Model;
import de.swagner.piratesbigsea.com.badlogic.gdx.graphics.g3d.model.still.StillModel;
/**
* Simple "pluggable" class for loading models. Keeps a list of
* {@link ModelLoader} instances on a per file suffix basis. Use one of the
* static methods to load a {@link Model}. The registry will then try out all
* the registered loaders for that extension and eventually return a Model or
* throw a {@link GdxRuntimeException}. Per default all loaders of libgdx except
* the {@link OgreXmlLoader} which won't work on Android due to the JAXB
* dependency.
*
* @author mzechner
*/
public class ModelLoaderRegistry {
private static Map<String, Array<ModelLoader>> loaders = new HashMap<String, Array<ModelLoader>>();
private static Map<String, Array<ModelLoaderHints>> defaultHints = new HashMap<String, Array<ModelLoaderHints>>();
// registering the default loaders here
static {
registerLoader("g3dt", new G3dtStillModelLoader(),
new ModelLoaderHints(true));
}
/**
* Registers a new loader with the registry. The extension will be used to
* match the loader against a file to be loaded. The extension will be
* compared case insensitive. If multiple loaders are registered per
* extension they will be tried on a file in the sequence they have been
* registered until one succeeds or none succeed.
*
* @param extension
* the extension string, e.g. "dae" or "obj"
* @param loader
* the {@link ModelLoader}
* @param defaultHints
* the default {@link ModelLoaderHints} to be used with this
* loader.
*/
public static void registerLoader(String extension, ModelLoader loader,
ModelLoaderHints defaultHints) {
Array<ModelLoader> loaders = ModelLoaderRegistry.loaders.get(extension);
if (loaders == null) {
loaders = new Array<ModelLoader>();
ModelLoaderRegistry.loaders.put(extension.toLowerCase(), loaders);
}
loaders.add(loader);
Array<ModelLoaderHints> hints = ModelLoaderRegistry.defaultHints
.get(extension);
if (hints == null) {
hints = new Array<ModelLoaderHints>();
ModelLoaderRegistry.defaultHints
.put(extension.toLowerCase(), hints);
}
hints.add(defaultHints);
}
/**
* Loads the specified file with one of the loaders registered with this
* ModelLoaderRegistry. Uses the extension to determine which loader to use.
* The comparison of extensions is done case insensitive.
*
* @param file
* the file to be loaded
* @return the {@link Model}
* @throws GdxRuntimeException
* in case the model could not be loaded.
*/
public static Model load(FileHandle file) {
String name = file.name();
int dotIndex = name.lastIndexOf('.');
if (dotIndex == -1)
throw new GdxRuntimeException(
"file '"
+ file.name()
+ "' does not have an extension that can be matched to a ModelLoader");
String extension = name.substring(dotIndex + 1).toLowerCase();
Array<ModelLoader> loaders = ModelLoaderRegistry.loaders.get(extension);
Array<ModelLoaderHints> hints = ModelLoaderRegistry.defaultHints
.get(extension);
if (loaders == null)
throw new GdxRuntimeException("no loaders for extension '"
+ extension + "'");
if (hints == null)
throw new GdxRuntimeException("no default hints for extension '"
+ extension + "'");
Model model = null;
StringBuilder errors = new StringBuilder();
for (int i = 0; i < loaders.size; i++) {
ModelLoader loader = loaders.get(i);
ModelLoaderHints hint = hints.get(i);
model = loader.load(file, hint);
}
if (model == null)
throw new GdxRuntimeException(errors.toString());
else
return model;
}
/**
* Loads the specified file with one of the loaders registered with this
* ModelLoaderRegistry. Uses the extension to determine which loader to use.
* The comparison of extensions is done case insensitive.
*
* @param file
* the file to be loaded
* @param hints
* the {@link ModelLoaderHints} to use
* @return the {@link Model}
* @throws GdxRuntimeException
* in case the model could not be loaded.
*/
public static Model load(FileHandle file, ModelLoaderHints hints) {
String name = file.name();
int dotIndex = name.lastIndexOf('.');
if (dotIndex == -1)
throw new GdxRuntimeException(
"file '"
+ file.name()
+ "' does not have an extension that can be matched to a ModelLoader");
String extension = name.substring(dotIndex + 1).toLowerCase();
Array<ModelLoader> loaders = ModelLoaderRegistry.loaders.get(extension);
if (loaders == null)
throw new GdxRuntimeException("no loaders for extension '"
+ extension + "'");
Model model = null;
StringBuilder errors = new StringBuilder();
for (int i = 0; i < loaders.size; i++) {
ModelLoader loader = loaders.get(i);
model = loader.load(file, hints);
}
if (model == null)
throw new GdxRuntimeException(errors.toString());
else
return model;
}
/**
* Loads the specified file with one of the loaders registered with this
* ModelLoaderRegistry. Uses the extension to determine which loader to use.
* The comparison of extensions is done case insensitive. Uses only
* {@link StillModelLoader} instances.
*
* @param file
* the file to be loaded
* @return the {@link Model}
* @throws GdxRuntimeException
* in case the model could not be loaded.
*/
public static StillModel loadStillModel(FileHandle file) {
String name = file.name();
int dotIndex = name.lastIndexOf('.');
if (dotIndex == -1)
throw new GdxRuntimeException(
"file '"
+ file.name()
+ "' does not have an extension that can be matched to a ModelLoader");
String extension = name.substring(dotIndex + 1).toLowerCase();
Array<ModelLoader> loaders = ModelLoaderRegistry.loaders.get(extension);
Array<ModelLoaderHints> hints = ModelLoaderRegistry.defaultHints
.get(extension);
if (loaders == null)
throw new GdxRuntimeException("no loaders for extension '"
+ extension + "'");
if (hints == null)
throw new GdxRuntimeException("no default hints for extension '"
+ extension + "'");
StillModel model = null;
StringBuilder errors = new StringBuilder();
for (int i = 0; i < loaders.size; i++) {
ModelLoader loader = loaders.get(i);
ModelLoaderHints hint = hints.get(i);
model = ((StillModelLoader) loader).load(file, hint);
}
if (model == null)
throw new GdxRuntimeException("Couldn't load model '" + file.name()
+ "', " + errors.toString());
else
return model;
}
/**
* Loads the specified file with one of the loaders registered with this
* ModelLoaderRegistry. Uses the extension to determine which loader to use.
* The comparison of extensions is done case insensitive. Uses only
* {@link StillModelLoader} instances.
*
* @param file
* the file to be loaded
* @oaram hints the ModelLoaderHints to be used.
* @return the {@link Model}
* @throws GdxRuntimeException
* in case the model could not be loaded.
*/
public static StillModel loadStillModel(FileHandle file,
ModelLoaderHints hints) {
String name = file.name();
int dotIndex = name.lastIndexOf('.');
if (dotIndex == -1)
throw new GdxRuntimeException(
"file '"
+ file.name()
+ "' does not have an extension that can be matched to a ModelLoader");
String extension = name.substring(dotIndex + 1).toLowerCase();
Array<ModelLoader> loaders = ModelLoaderRegistry.loaders.get(extension);
if (loaders == null)
throw new GdxRuntimeException("no loaders for extension '"
+ extension + "'");
StillModel model = null;
StringBuilder errors = new StringBuilder();
for (int i = 0; i < loaders.size; i++) {
ModelLoader loader = loaders.get(i);
if (loader instanceof StillModelLoader) {
model = ((StillModelLoader) loader).load(file, hints);
}
}
if (model == null)
throw new GdxRuntimeException("Couldn't load model '" + file.name()
+ "', " + errors.toString());
else
return model;
}
}