PageRenderTime 16ms CodeModel.GetById 2ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/src/org/mt4j/util/modelImporter/ModelImporterFactory.java

http://mt4j.googlecode.com/
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}