/src/org/mt4j/util/modelImporter/ModelImporterFactory.java
Java | 226 lines | 77 code | 27 blank | 122 comment | 8 complexity | acb396fc775ecf69c1fc554127edc711 MD5 | raw file
1/*********************************************************************** 2 * mt4j Copyright (c) 2008 - 2009 C.Ruff, Fraunhofer-Gesellschaft All rights reserved. 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 * 17 ***********************************************************************/ 18package org.mt4j.util.modelImporter; 19 20import java.io.FileNotFoundException; 21import java.util.HashMap; 22import java.util.Iterator; 23import java.util.Set; 24 25import org.mt4j.components.visibleComponents.shapes.mesh.MTTriangleMesh; 26import org.mt4j.util.modelImporter.file3ds.Model3dsFileFactory; 27import org.mt4j.util.modelImporter.fileObj.ModelObjFileFactory; 28 29import processing.core.PApplet; 30 31/** 32 * A factory for creating ModelImporter objects. 33 * @author Christopher Ruff 34 */ 35public abstract class ModelImporterFactory { 36 37 /** The suffix to factory. */ 38 private static HashMap<String, Class<? extends ModelImporterFactory>> suffixToFactory; 39 40 static { 41 suffixToFactory = new HashMap<String, Class<? extends ModelImporterFactory>>(); 42 //Add default factories for .3ds and for .obj files 43 registerModelImporterFactory(".3ds", Model3dsFileFactory.class); 44 registerModelImporterFactory(".obj", ModelObjFileFactory.class); 45 } 46 47 48 /** 49 * Gets the appropriate class for suffix. 50 * 51 * @param fileSuffix the file suffix 52 * 53 * @return the appropriate class for suffix 54 */ 55 private static Class<? extends ModelImporterFactory> getAppropriateClassForSuffix(String fileSuffix){ 56 return suffixToFactory.get(fileSuffix); 57 } 58 59 60 /** 61 * Registers a ModelImporterFactory with this class. 62 * The registered class has to extend the abstract ModelImporterFactory class! 63 * 64 * @param fileSuffix the suffix of the files to be loaded by this factory (e.g. ".obj" or ".3ds") 65 * @param factory the factory to load the models with the specified suffix with. The factory has to be derived from ModelImporterFactory! 66 */ 67 public static void registerModelImporterFactory(String fileSuffix, Class<? extends ModelImporterFactory> factory){ 68 suffixToFactory.put(fileSuffix, factory); 69 } 70 71 72 /** 73 * Unregister a importer factory class for a file type. 74 * 75 * @param factory the factory to load the models with the specified suffix with. The factory has to be derived from ModelImporterFactory! 76 */ 77 public static void unregisterModelImporterFactory(Class<? extends ModelImporterFactory> factory){ 78 Set<String> suffixesInHashMap = suffixToFactory.keySet(); 79 for (Iterator<String> iter = suffixesInHashMap.iterator(); iter.hasNext();) { 80 String suffix = (String) iter.next(); 81 if (suffixToFactory.get(suffix).equals(factory)){ 82 suffixToFactory.remove(suffix); 83 } 84 } 85 } 86 87 88 /** 89 * Loads a model from a file and creates an array of meshes. 90 * <p> 91 * Some models store the texture information flipped on the y-Axis. 92 * This can be solved by setting <code>flipTextureY</code> to true. 93 * <br>Vertex normals will be created for the geometry according to the crease angle. 94 * <br>A crease angle of 180 will result in an all smoothed model, creating a vertex normal 95 * that is interpolated from all neighbor faces normals. 96 * <br>A crease angle of zero (0) will result in a flat shaded geometry. Only face normals will 97 * be used then. 98 * <br>A crease angle of 89 will create hard edges at 90 degree angle faces and smooth faces with 99 * less then 90 degree normals. This would be ideal to generate normals for cubes and models with 100 * many sharp 90 degree angles. 101 * <br>The best crease angle for a model has to be found by testing different crease angles. 102 * 103 * @param pa the parent processing applet 104 * @param pathToModel the absolute path of the model file 105 * @param creaseAngle the crease angle, see method description for info 106 * @param flipTextureY flag whether or not to flip the texture vertical 107 * @param flipTextureX flag whether or not to flip the texture horizontal 108 * 109 * @return the MT triangle mesh[] 110 * 111 * @throws FileNotFoundException the file not found exception 112 * 113 * an array filled with the meshes created during the loading process 114 */ 115 public static MTTriangleMesh[] loadModel(PApplet pa, String pathToModel, float creaseAngle, boolean flipTextureY, boolean flipTextureX){ 116 try { 117 String suffix = getFileSuffix(pathToModel); 118 ModelImporterFactory factory = getFactory(suffix); 119 if (factory != null){ 120 return factory.loadModelImpl(pa, pathToModel, creaseAngle, flipTextureY, flipTextureX); 121 } 122 } catch (IllegalAccessException e) { 123 e.printStackTrace(); 124 } catch (InstantiationException e) { 125 e.printStackTrace(); 126 } catch (FileNotFoundException e) { 127 e.printStackTrace(); 128 } 129 return new MTTriangleMesh[]{}; 130 } 131 132 133 134 /** 135 * Gets the factory. 136 * 137 * @param fileSuffix the suffix of the file to be loaded by the factory (e.g. ".obj" or ".3ds") 138 * 139 * @return the factory 140 * 141 * @throws IllegalAccessException the illegal access exception 142 * @throws InstantiationException the instantiation exception 143 * @throws RuntimeException the runtime exception 144 * 145 * the factory to load the model with if a appropriate factory was found 146 */ 147 private static ModelImporterFactory getFactory(String fileSuffix) throws IllegalAccessException, InstantiationException{ 148 Class<? extends ModelImporterFactory> modelFactoryClass = getAppropriateClassForSuffix(fileSuffix); 149 //Get, create instance and return a appropriate factory object if found 150 if (modelFactoryClass != null){ 151 try { 152 ModelImporterFactory modelFactory = modelFactoryClass.newInstance(); 153 System.out.println("Found and created model factory for handling files: \"" + fileSuffix + "\"" + " Factory: " + modelFactory.getClass().getName()); 154 return modelFactory; 155 }catch (InstantiationException e) { 156 throw new InstantiationException("The ModelImporterFactory \"" + modelFactoryClass.getName() + "\" has to have a constructor without any parameters!"); 157 } catch (IllegalAccessException e) { 158 throw new IllegalAccessException(); 159 } 160 }else{ 161 throw new RuntimeException("No appropriate factory class was found for handling files: \"" + fileSuffix + "\""); 162 } 163 } 164 165 166 /** 167 * Gets the file suffix. 168 * 169 * @param pathToFile the path to file 170 * 171 * @return the file suffix 172 */ 173 private static String getFileSuffix(String pathToFile){ 174 int indexOfPoint = pathToFile.lastIndexOf("."); 175 String suffix; 176 if (indexOfPoint != -1){ 177 suffix = pathToFile.substring(indexOfPoint, pathToFile.length()); 178 suffix = suffix.toLowerCase(); 179 }else{ 180 suffix = ""; 181 } 182 return suffix; 183 } 184 185 186 187 /** 188 * The model loading will put out debug information if set to true. 189 * 190 * @param debug the debug 191 */ 192 public abstract void setDebug(boolean debug); 193 194 195 /** 196 * Loads a model from a file and creates an array of meshes. 197 * <p> 198 * Some models store the texture information flipped on the y-Axis. 199 * This can be solved by setting <code>flipTextureY</code> to true. 200 * <br>Vertex normals will be created for the geometry according to the crease angle. 201 * <br>A crease angle of 180 will result in an all smoothed model, creating a vertex normal 202 * that is interpolated from all neighbor faces normals. 203 * <br>A crease angle of zero (0) will result in a flat shaded geometry. Only face normals will 204 * be used then. 205 * <br>A crease angle of 89 will create hard edges at 90 degree angle faces and smooth faces with 206 * less then 90 degree normals. This would be ideal to generate normals for cubes and models with 207 * many sharp 90 degree angles. 208 * <br>The best crease angle for a model has to be found by testing different crease angles. 209 * 210 * @param pa the parent processing applet 211 * @param pathToModel the absolute path of the model file 212 * @param creaseAngle the crease angle, see method description for info 213 * @param flipTextureY flag whether or not to flip the texture vertical 214 * @param flipTextureX flag whether or not to flip the texture horizontal 215 * 216 * @return the MT triangle mesh[] 217 * 218 * @throws FileNotFoundException the file not found exception 219 * 220 * an array filled with the meshes created during the loading process 221 */ 222 public abstract MTTriangleMesh[] loadModelImpl(PApplet pa, String pathToModel, float creaseAngle, boolean flipTextureY, boolean flipTextureX) throws FileNotFoundException; 223 224 225 226}