/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. ***********************************************************************/
  18. package org.mt4j.util.modelImporter;
  19. import java.io.FileNotFoundException;
  20. import java.util.HashMap;
  21. import java.util.Iterator;
  22. import java.util.Set;
  23. import org.mt4j.components.visibleComponents.shapes.mesh.MTTriangleMesh;
  24. import org.mt4j.util.modelImporter.file3ds.Model3dsFileFactory;
  25. import org.mt4j.util.modelImporter.fileObj.ModelObjFileFactory;
  26. import processing.core.PApplet;
  27. /**
  28. * A factory for creating ModelImporter objects.
  29. * @author Christopher Ruff
  30. */
  31. public abstract class ModelImporterFactory {
  32. /** The suffix to factory. */
  33. private static HashMap<String, Class<? extends ModelImporterFactory>> suffixToFactory;
  34. static {
  35. suffixToFactory = new HashMap<String, Class<? extends ModelImporterFactory>>();
  36. //Add default factories for .3ds and for .obj files
  37. registerModelImporterFactory(".3ds", Model3dsFileFactory.class);
  38. registerModelImporterFactory(".obj", ModelObjFileFactory.class);
  39. }
  40. /**
  41. * Gets the appropriate class for suffix.
  42. *
  43. * @param fileSuffix the file suffix
  44. *
  45. * @return the appropriate class for suffix
  46. */
  47. private static Class<? extends ModelImporterFactory> getAppropriateClassForSuffix(String fileSuffix){
  48. return suffixToFactory.get(fileSuffix);
  49. }
  50. /**
  51. * Registers a ModelImporterFactory with this class.
  52. * The registered class has to extend the abstract ModelImporterFactory class!
  53. *
  54. * @param fileSuffix the suffix of the files to be loaded by this factory (e.g. ".obj" or ".3ds")
  55. * @param factory the factory to load the models with the specified suffix with. The factory has to be derived from ModelImporterFactory!
  56. */
  57. public static void registerModelImporterFactory(String fileSuffix, Class<? extends ModelImporterFactory> factory){
  58. suffixToFactory.put(fileSuffix, factory);
  59. }
  60. /**
  61. * Unregister a importer factory class for a file type.
  62. *
  63. * @param factory the factory to load the models with the specified suffix with. The factory has to be derived from ModelImporterFactory!
  64. */
  65. public static void unregisterModelImporterFactory(Class<? extends ModelImporterFactory> factory){
  66. Set<String> suffixesInHashMap = suffixToFactory.keySet();
  67. for (Iterator<String> iter = suffixesInHashMap.iterator(); iter.hasNext();) {
  68. String suffix = (String) iter.next();
  69. if (suffixToFactory.get(suffix).equals(factory)){
  70. suffixToFactory.remove(suffix);
  71. }
  72. }
  73. }
  74. /**
  75. * Loads a model from a file and creates an array of meshes.
  76. * <p>
  77. * Some models store the texture information flipped on the y-Axis.
  78. * This can be solved by setting <code>flipTextureY</code> to true.
  79. * <br>Vertex normals will be created for the geometry according to the crease angle.
  80. * <br>A crease angle of 180 will result in an all smoothed model, creating a vertex normal
  81. * that is interpolated from all neighbor faces normals.
  82. * <br>A crease angle of zero (0) will result in a flat shaded geometry. Only face normals will
  83. * be used then.
  84. * <br>A crease angle of 89 will create hard edges at 90 degree angle faces and smooth faces with
  85. * less then 90 degree normals. This would be ideal to generate normals for cubes and models with
  86. * many sharp 90 degree angles.
  87. * <br>The best crease angle for a model has to be found by testing different crease angles.
  88. *
  89. * @param pa the parent processing applet
  90. * @param pathToModel the absolute path of the model file
  91. * @param creaseAngle the crease angle, see method description for info
  92. * @param flipTextureY flag whether or not to flip the texture vertical
  93. * @param flipTextureX flag whether or not to flip the texture horizontal
  94. *
  95. * @return the MT triangle mesh[]
  96. *
  97. * @throws FileNotFoundException the file not found exception
  98. *
  99. * an array filled with the meshes created during the loading process
  100. */
  101. public static MTTriangleMesh[] loadModel(PApplet pa, String pathToModel, float creaseAngle, boolean flipTextureY, boolean flipTextureX){
  102. try {
  103. String suffix = getFileSuffix(pathToModel);
  104. ModelImporterFactory factory = getFactory(suffix);
  105. if (factory != null){
  106. return factory.loadModelImpl(pa, pathToModel, creaseAngle, flipTextureY, flipTextureX);
  107. }
  108. } catch (IllegalAccessException e) {
  109. e.printStackTrace();
  110. } catch (InstantiationException e) {
  111. e.printStackTrace();
  112. } catch (FileNotFoundException e) {
  113. e.printStackTrace();
  114. }
  115. return new MTTriangleMesh[]{};
  116. }
  117. /**
  118. * Gets the factory.
  119. *
  120. * @param fileSuffix the suffix of the file to be loaded by the factory (e.g. ".obj" or ".3ds")
  121. *
  122. * @return the factory
  123. *
  124. * @throws IllegalAccessException the illegal access exception
  125. * @throws InstantiationException the instantiation exception
  126. * @throws RuntimeException the runtime exception
  127. *
  128. * the factory to load the model with if a appropriate factory was found
  129. */
  130. private static ModelImporterFactory getFactory(String fileSuffix) throws IllegalAccessException, InstantiationException{
  131. Class<? extends ModelImporterFactory> modelFactoryClass = getAppropriateClassForSuffix(fileSuffix);
  132. //Get, create instance and return a appropriate factory object if found
  133. if (modelFactoryClass != null){
  134. try {
  135. ModelImporterFactory modelFactory = modelFactoryClass.newInstance();
  136. System.out.println("Found and created model factory for handling files: \"" + fileSuffix + "\"" + " Factory: " + modelFactory.getClass().getName());
  137. return modelFactory;
  138. }catch (InstantiationException e) {
  139. throw new InstantiationException("The ModelImporterFactory \"" + modelFactoryClass.getName() + "\" has to have a constructor without any parameters!");
  140. } catch (IllegalAccessException e) {
  141. throw new IllegalAccessException();
  142. }
  143. }else{
  144. throw new RuntimeException("No appropriate factory class was found for handling files: \"" + fileSuffix + "\"");
  145. }
  146. }
  147. /**
  148. * Gets the file suffix.
  149. *
  150. * @param pathToFile the path to file
  151. *
  152. * @return the file suffix
  153. */
  154. private static String getFileSuffix(String pathToFile){
  155. int indexOfPoint = pathToFile.lastIndexOf(".");
  156. String suffix;
  157. if (indexOfPoint != -1){
  158. suffix = pathToFile.substring(indexOfPoint, pathToFile.length());
  159. suffix = suffix.toLowerCase();
  160. }else{
  161. suffix = "";
  162. }
  163. return suffix;
  164. }
  165. /**
  166. * The model loading will put out debug information if set to true.
  167. *
  168. * @param debug the debug
  169. */
  170. public abstract void setDebug(boolean debug);
  171. /**
  172. * Loads a model from a file and creates an array of meshes.
  173. * <p>
  174. * Some models store the texture information flipped on the y-Axis.
  175. * This can be solved by setting <code>flipTextureY</code> to true.
  176. * <br>Vertex normals will be created for the geometry according to the crease angle.
  177. * <br>A crease angle of 180 will result in an all smoothed model, creating a vertex normal
  178. * that is interpolated from all neighbor faces normals.
  179. * <br>A crease angle of zero (0) will result in a flat shaded geometry. Only face normals will
  180. * be used then.
  181. * <br>A crease angle of 89 will create hard edges at 90 degree angle faces and smooth faces with
  182. * less then 90 degree normals. This would be ideal to generate normals for cubes and models with
  183. * many sharp 90 degree angles.
  184. * <br>The best crease angle for a model has to be found by testing different crease angles.
  185. *
  186. * @param pa the parent processing applet
  187. * @param pathToModel the absolute path of the model file
  188. * @param creaseAngle the crease angle, see method description for info
  189. * @param flipTextureY flag whether or not to flip the texture vertical
  190. * @param flipTextureX flag whether or not to flip the texture horizontal
  191. *
  192. * @return the MT triangle mesh[]
  193. *
  194. * @throws FileNotFoundException the file not found exception
  195. *
  196. * an array filled with the meshes created during the loading process
  197. */
  198. public abstract MTTriangleMesh[] loadModelImpl(PApplet pa, String pathToModel, float creaseAngle, boolean flipTextureY, boolean flipTextureX) throws FileNotFoundException;
  199. }