CJMinecraft

OBJ Loader

Sep 22nd, 2017
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.78 KB | None | 0 0
  1. package cjminecraft.engine.loaders;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.File;
  5. import java.io.FileNotFoundException;
  6. import java.io.FileReader;
  7. import java.io.IOException;
  8. import java.util.ArrayList;
  9. import java.util.List;
  10.  
  11. import org.joml.Vector2f;
  12. import org.joml.Vector3f;
  13.  
  14. import cjminecraft.engine.Engine;
  15. import cjminecraft.engine.util.Vertex;
  16. import cjminecraft.engine.util.objects.RawObject;
  17.  
  18. public class OBJLoader {
  19.  
  20. public static RawObject loadOBJ(String fileName) {
  21. fileName = Engine.getOption("models.location") + "/" + fileName + ".obj";
  22. FileReader fr = null;
  23. File objFile = new File(fileName);
  24. try {
  25. fr = new FileReader(objFile);
  26. } catch (FileNotFoundException e) {
  27. System.err.println("File not found: " + fileName);
  28. System.exit(-1);
  29. }
  30. BufferedReader reader = new BufferedReader(fr);
  31. String line;
  32. List<Vertex> vertices = new ArrayList<Vertex>();
  33. List<Vector2f> textures = new ArrayList<Vector2f>();
  34. List<Vector3f> normals = new ArrayList<Vector3f>();
  35. List<Integer> indices = new ArrayList<Integer>();
  36. try {
  37. while (true) {
  38. line = reader.readLine();
  39. if (line.startsWith("v ")) {
  40. String[] currentLine = line.split(" ");
  41. Vector3f vertex = new Vector3f(Float.parseFloat(currentLine[1]), Float.parseFloat(currentLine[2]),
  42. Float.parseFloat(currentLine[3]));
  43. Vertex newVertex = new Vertex(vertices.size(), vertex);
  44. vertices.add(newVertex);
  45. } else if (line.startsWith("vt ")) {
  46. String[] currentLine = line.split(" ");
  47. Vector2f texture = new Vector2f(Float.parseFloat(currentLine[1]), Float.parseFloat(currentLine[2]));
  48. textures.add(texture);
  49. } else if (line.startsWith("vn ")) {
  50. String[] currentLine = line.split(" ");
  51. Vector3f normal = new Vector3f(Float.parseFloat(currentLine[1]), Float.parseFloat(currentLine[2]),
  52. Float.valueOf(currentLine[3]));
  53. normals.add(normal);
  54. } else if (line.startsWith("f ")) {
  55. break;
  56. }
  57. }
  58. while (line != null && line.startsWith("f ")) {
  59. String[] currentLine = line.split(" ");
  60. String[] vertex1 = currentLine[1].split("/");
  61. String[] vertex2 = currentLine[2].split("/");
  62. String[] vertex3 = currentLine[3].split("/");
  63. Vertex v0 = processVertex(vertex1, vertices, indices);
  64. Vertex v1 = processVertex(vertex2, vertices, indices);
  65. Vertex v2 = processVertex(vertex3, vertices, indices);
  66. calculateTangents(v0, v1, v2, textures);
  67. line = reader.readLine();
  68. }
  69. reader.close();
  70. } catch (IOException e) {
  71. System.err.println("Error reading file: " + fileName);
  72. System.exit(-1);
  73. }
  74. removeUnusedVertices(vertices);
  75. float[] verticesArray = new float[vertices.size() * 3];
  76. float[] texturesArray = new float[vertices.size() * 2];
  77. float[] normalsArray = new float[vertices.size() * 3];
  78. float[] tangentsArray = new float[vertices.size() * 3];
  79. int[] indicesArray = convertIndicesListToArray(indices);
  80. return VaoLoader.loadToVAO(verticesArray, texturesArray, normalsArray, tangentsArray, indicesArray);
  81. }
  82.  
  83. private static void calculateTangents(Vertex v0, Vertex v1, Vertex v2, List<Vector2f> textures) {
  84. Vector3f delatPos1 = v1.getPosition().sub(v0.getPosition());
  85. Vector3f delatPos2 = v2.getPosition().sub(v0.getPosition());
  86. Vector2f uv0 = textures.get(v0.getTextureIndex());
  87. Vector2f uv1 = textures.get(v1.getTextureIndex());
  88. Vector2f uv2 = textures.get(v2.getTextureIndex());
  89. Vector2f deltaUv1 = uv1.sub(uv0);
  90. Vector2f deltaUv2 = uv2.sub(uv0);
  91.  
  92. float r = 1.0f / (deltaUv1.x * deltaUv2.y - deltaUv1.y * deltaUv2.x);
  93. delatPos1.mul(deltaUv2.y);
  94. delatPos2.mul(deltaUv1.y);
  95. Vector3f tangent = delatPos1.sub(delatPos2);
  96. tangent.mul(r);
  97. v0.addTangent(tangent);
  98. v1.addTangent(tangent);
  99. v2.addTangent(tangent);
  100. }
  101.  
  102. private static Vertex processVertex(String[] vertex, List<Vertex> vertices, List<Integer> indices) {
  103. int index = Integer.parseInt(vertex[0]) - 1;
  104. Vertex currentVertex = vertices.get(index);
  105. int textureIndex = Integer.parseInt(vertex[1]) - 1;
  106. int normalIndex = Integer.parseInt(vertex[2]) - 1;
  107. if (!currentVertex.isSet()) {
  108. currentVertex.setTextureIndex(textureIndex);
  109. currentVertex.setNormalIndex(normalIndex);
  110. indices.add(index);
  111. return currentVertex;
  112. } else {
  113. return dealWithAlreadyProcessedVertex(currentVertex, textureIndex, normalIndex, indices, vertices);
  114. }
  115. }
  116.  
  117. private static int[] convertIndicesListToArray(List<Integer> indices) {
  118. int[] indicesArray = new int[indices.size()];
  119. for (int i = 0; i < indicesArray.length; i++) {
  120. indicesArray[i] = indices.get(i);
  121. }
  122. return indicesArray;
  123. }
  124.  
  125. private static Vertex dealWithAlreadyProcessedVertex(Vertex previousVertex, int newTextureIndex, int newNormalIndex,
  126. List<Integer> indices, List<Vertex> vertices) {
  127. if (previousVertex.hasSameTextureAndNormal(newTextureIndex, newNormalIndex)) {
  128. indices.add(previousVertex.getIndex());
  129. return previousVertex;
  130. } else {
  131. Vertex anotherVertex = previousVertex.getDuplicateVertex();
  132. if (anotherVertex != null) {
  133. return dealWithAlreadyProcessedVertex(anotherVertex, newTextureIndex, newNormalIndex, indices,
  134. vertices);
  135. } else {
  136. Vertex duplicateVertex = new Vertex(vertices.size(), previousVertex.getPosition());
  137. duplicateVertex.setTextureIndex(newTextureIndex);
  138. duplicateVertex.setNormalIndex(newNormalIndex);
  139. previousVertex.setDuplicateVertex(duplicateVertex);
  140. vertices.add(duplicateVertex);
  141. indices.add(duplicateVertex.getIndex());
  142. return duplicateVertex;
  143. }
  144.  
  145. }
  146. }
  147.  
  148. private static void removeUnusedVertices(List<Vertex> vertices) {
  149. for (Vertex vertex : vertices) {
  150. vertex.averageTangents();
  151. if (!vertex.isSet()) {
  152. vertex.setTextureIndex(0);
  153. vertex.setNormalIndex(0);
  154. }
  155. }
  156. }
  157.  
  158. }
Advertisement
Add Comment
Please, Sign In to add comment