package fileHandling;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import settings.Config;
import settings.GraphicSettings;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.Spatial.CullHint;
import com.jme.scene.state.MaterialState;
import com.jme.system.DisplaySystem;
import com.jme.util.CloneImportExport;
import com.jme.util.export.Savable;
import com.jme.util.export.binary.BinaryImporter;
import com.jme.util.resource.ResourceLocatorTool;
import com.jmex.model.converters.FormatConverter;
import com.jmex.model.converters.ObjToJme;
/**
* Provides static methods to load models.
* @author Wasserleiche
*/
public class ModelImporter {
/** This {@link HashMap} is used to store {@link CloneImportExport}-objects of loaded objects to faster load
* those objects again.*/
protected static HashMap<String, CloneImportExport> loadedObjects = new HashMap<String, CloneImportExport>();
/**
* Checks weather the given key is known.
* @param key The key to be looked up.
* @return true, if the key has a corresponding object in the loadedObjects-{@link HashMap}. false, else.
*/
protected static boolean objectIsLoaded(String key) {
if(!Config.get().getCloneLoading()) return false;
return loadedObjects.containsKey(key);
}
/**
* Returns the loaded model of the given model-path. This method shall only be called
* if there is a model stored in the {@link HashMap}!.
* @param modelPath The path of the model to be retrieved.
* @return A {@link Node} containing the model.
*/
protected static Node getLoadedNode(String modelPath) {
assert(modelPath != null && objectIsLoaded(modelPath));
return (Node)loadedObjects.get(modelPath).loadClone();
}
/**
* Creates a new {@link CloneImportExport}-object out of the given model-{@link Node}
* and stores it in the loadedModels-{@link HashMap} with the model-path.
* @param modelPath The model-path that will become the key in the {@link HashMap}.
* @param model The {@link Node} that has to be saved in a {@link CloneImportExport}-object.
*/
protected static void putLoadedNode(String modelPath, Node model) {
assert(modelPath != null && model != null);
CloneImportExport clone = new CloneImportExport();
clone.saveClone(model);
loadedObjects.put(modelPath, clone);
}
public static Node getModel(String modelPath, String quality) {
String path = modelPath + quality + "/";
URL modelFile = getURL(path + "model.obj", ResourceLocatorTool.TYPE_MODEL);
if(modelFile == null) return null;
URL modelFolder = getURL(path, ResourceLocatorTool.TYPE_SHADER);
if(modelFolder == null) return null;
FormatConverter converter = new ObjToJme();
converter.setProperty("mtllib", modelFolder);
ByteArrayOutputStream bo = new ByteArrayOutputStream();
Node model = null;
ByteArrayInputStream bai = null;
try {
converter.convert(modelFile.openStream(), bo);
bai = new ByteArrayInputStream(bo.toByteArray());
Savable savable = BinaryImporter.getInstance().load(bai);
if(savable instanceof Node) model = (Node)savable;
else {
model = new Node();
model.attachChild((Spatial)savable);
}
} catch(Exception e) {
e.printStackTrace();
return null;
} finally {
try {
bo.close();
if(bai != null) bai.close();
} catch(Exception e) { e.printStackTrace(); }
}
MaterialState ms = DisplaySystem.getDisplaySystem().getRenderer().createMaterialState();
ms.setAmbient(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
ms.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
ms.setSpecular(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
ms.setShininess(50.0f);
model.setRenderState(ms);
model.updateRenderState();
model.setCullHint(CullHint.Dynamic);
putLoadedNode(path, model);
model.setName(path);
return model;
}
public static Node getModelOfQuality(String modelPath, String quality) {
String path = modelPath + quality + "/";
if(objectIsLoaded(path)) {
Node node = getLoadedNode(path);
if(node != null) return node;
}
return getModel(modelPath, quality);
}
/**
* Creates a new model-Node with the given model-path.
* @param modelPath The relative path to the model.
* @return A new {@link Node} that contains the model.
* null, if any error occurs while loading the model.
*/
public static Node getModel(String modelPath) {
String quality = GraphicSettings.get().getGeometryQuality();
String path = modelPath + quality + "/";
if(objectIsLoaded(path)) {
Node node = getLoadedNode(path);
if(node != null) return node;
}
return getModel(modelPath, quality);
}
public static URL getURL(String urlPath, String type) {
URL modelFile = ResourceLocatorTool.locateResource(type, urlPath);
if(modelFile == null) {
try { modelFile = new URL("file:" + urlPath); }
catch(MalformedURLException e) {
e.printStackTrace();
return null;
}
}
return modelFile;
}
public static String nextLevel(String level, boolean lower) {
if(level.equals("high") && lower) return "medium";
if(level.equals("medium")) {
if(lower) return "low";
return "high";
}
if(level.equals("low")) {
if(lower) return "lod1";
return "medium";
}
if(level.equals("lod1")) {
if(lower) return "lod2";
return "low";
}
if(level.equals("lod2")) {
if(lower) return "lod3";
return "lod1";
}
if(level.equals("lod3") && !lower) return "lod2";
return null;
}
}
|