ObjLoader.java 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. package eu.tankernn.gameEngine.loader.models.obj;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6. import org.lwjgl.util.vector.Vector2f;
  7. import org.lwjgl.util.vector.Vector3f;
  8. import eu.tankernn.gameEngine.util.InternalFile;
  9. public class ObjLoader {
  10. public static ModelData loadOBJ(InternalFile objFile) {
  11. BufferedReader reader;
  12. try {
  13. reader = objFile.getReader();
  14. } catch (Exception e1) {
  15. e1.printStackTrace();
  16. return null;
  17. }
  18. String line;
  19. List<Vertex> vertices = new ArrayList<Vertex>();
  20. List<Vector2f> textures = new ArrayList<Vector2f>();
  21. List<Vector3f> normals = new ArrayList<Vector3f>();
  22. List<Integer> indices = new ArrayList<Integer>();
  23. try {
  24. while (true) {
  25. line = reader.readLine();
  26. if (line.startsWith("v ")) {
  27. String[] currentLine = line.split(" ");
  28. Vector3f vertex = new Vector3f((float) Float.valueOf(currentLine[1]),
  29. (float) Float.valueOf(currentLine[2]),
  30. (float) Float.valueOf(currentLine[3]));
  31. Vertex newVertex = new Vertex(vertices.size(), vertex);
  32. vertices.add(newVertex);
  33. } else if (line.startsWith("vt ")) {
  34. String[] currentLine = line.split(" ");
  35. Vector2f texture = new Vector2f((float) Float.valueOf(currentLine[1]),
  36. (float) Float.valueOf(currentLine[2]));
  37. textures.add(texture);
  38. } else if (line.startsWith("vn ")) {
  39. String[] currentLine = line.split(" ");
  40. Vector3f normal = new Vector3f((float) Float.valueOf(currentLine[1]),
  41. (float) Float.valueOf(currentLine[2]),
  42. (float) Float.valueOf(currentLine[3]));
  43. normals.add(normal);
  44. } else if (line.startsWith("f ")) {
  45. break;
  46. }
  47. }
  48. while (line != null && line.startsWith("f ")) {
  49. String[] currentLine = line.split(" ");
  50. String[] vertex1 = currentLine[1].split("/");
  51. String[] vertex2 = currentLine[2].split("/");
  52. String[] vertex3 = currentLine[3].split("/");
  53. Vertex v0 = processVertex(vertex1, vertices, indices);
  54. Vertex v1 = processVertex(vertex2, vertices, indices);
  55. Vertex v2 = processVertex(vertex3, vertices, indices);
  56. calculateTangents(v0, v1, v2, textures);//NEW
  57. line = reader.readLine();
  58. }
  59. reader.close();
  60. } catch (IOException e) {
  61. System.err.println("Error reading the file");
  62. }
  63. removeUnusedVertices(vertices);
  64. float[] verticesArray = new float[vertices.size() * 3];
  65. float[] texturesArray = new float[vertices.size() * 2];
  66. float[] normalsArray = new float[vertices.size() * 3];
  67. float[] tangentsArray = new float[vertices.size() * 3];
  68. float furthest = convertDataToArrays(vertices, textures, normals, verticesArray,
  69. texturesArray, normalsArray, tangentsArray);
  70. int[] indicesArray = convertIndicesListToArray(indices);
  71. return new ModelData(verticesArray, texturesArray, normalsArray, tangentsArray, indicesArray, furthest);
  72. }
  73. //NEW
  74. private static void calculateTangents(Vertex v0, Vertex v1, Vertex v2,
  75. List<Vector2f> textures) {
  76. Vector3f delatPos1 = Vector3f.sub(v1.getPosition(), v0.getPosition(), null);
  77. Vector3f delatPos2 = Vector3f.sub(v2.getPosition(), v0.getPosition(), null);
  78. Vector2f uv0 = textures.get(v0.getTextureIndex());
  79. Vector2f uv1 = textures.get(v1.getTextureIndex());
  80. Vector2f uv2 = textures.get(v2.getTextureIndex());
  81. Vector2f deltaUv1 = Vector2f.sub(uv1, uv0, null);
  82. Vector2f deltaUv2 = Vector2f.sub(uv2, uv0, null);
  83. float r = 1.0f / (deltaUv1.x * deltaUv2.y - deltaUv1.y * deltaUv2.x);
  84. delatPos1.scale(deltaUv2.y);
  85. delatPos2.scale(deltaUv1.y);
  86. Vector3f tangent = Vector3f.sub(delatPos1, delatPos2, null);
  87. tangent.scale(r);
  88. v0.addTangent(tangent);
  89. v1.addTangent(tangent);
  90. v2.addTangent(tangent);
  91. }
  92. private static Vertex processVertex(String[] vertex, List<Vertex> vertices,
  93. List<Integer> indices) {
  94. int index = Integer.parseInt(vertex[0]) - 1;
  95. Vertex currentVertex = vertices.get(index);
  96. int textureIndex = Integer.parseInt(vertex[1]) - 1;
  97. int normalIndex = Integer.parseInt(vertex[2]) - 1;
  98. if (!currentVertex.isSet()) {
  99. currentVertex.setTextureIndex(textureIndex);
  100. currentVertex.setNormalIndex(normalIndex);
  101. indices.add(index);
  102. return currentVertex;
  103. } else {
  104. return dealWithAlreadyProcessedVertex(currentVertex, textureIndex, normalIndex, indices,
  105. vertices);
  106. }
  107. }
  108. private static int[] convertIndicesListToArray(List<Integer> indices) {
  109. int[] indicesArray = new int[indices.size()];
  110. for (int i = 0; i < indicesArray.length; i++) {
  111. indicesArray[i] = indices.get(i);
  112. }
  113. return indicesArray;
  114. }
  115. private static float convertDataToArrays(List<Vertex> vertices, List<Vector2f> textures,
  116. List<Vector3f> normals, float[] verticesArray, float[] texturesArray,
  117. float[] normalsArray, float[] tangentsArray) {
  118. float furthestPoint = 0;
  119. for (int i = 0; i < vertices.size(); i++) {
  120. Vertex currentVertex = vertices.get(i);
  121. if (currentVertex.getLength() > furthestPoint) {
  122. furthestPoint = currentVertex.getLength();
  123. }
  124. Vector3f position = currentVertex.getPosition();
  125. Vector2f textureCoord = textures.get(currentVertex.getTextureIndex());
  126. Vector3f normalVector = normals.get(currentVertex.getNormalIndex());
  127. Vector3f tangent = currentVertex.getAverageTangent();
  128. verticesArray[i * 3] = position.x;
  129. verticesArray[i * 3 + 1] = position.y;
  130. verticesArray[i * 3 + 2] = position.z;
  131. texturesArray[i * 2] = textureCoord.x;
  132. texturesArray[i * 2 + 1] = 1 - textureCoord.y;
  133. normalsArray[i * 3] = normalVector.x;
  134. normalsArray[i * 3 + 1] = normalVector.y;
  135. normalsArray[i * 3 + 2] = normalVector.z;
  136. tangentsArray[i * 3] = tangent.x;
  137. tangentsArray[i * 3 + 1] = tangent.y;
  138. tangentsArray[i * 3 + 2] = tangent.z;
  139. }
  140. return furthestPoint;
  141. }
  142. private static Vertex dealWithAlreadyProcessedVertex(Vertex previousVertex, int newTextureIndex,
  143. int newNormalIndex, List<Integer> indices, List<Vertex> vertices) {
  144. if (previousVertex.hasSameTextureAndNormal(newTextureIndex, newNormalIndex)) {
  145. indices.add(previousVertex.getIndex());
  146. return previousVertex;
  147. } else {
  148. Vertex anotherVertex = previousVertex.getDuplicateVertex();
  149. if (anotherVertex != null) {
  150. return dealWithAlreadyProcessedVertex(anotherVertex, newTextureIndex,
  151. newNormalIndex, indices, vertices);
  152. } else {
  153. Vertex duplicateVertex = previousVertex.duplicate(vertices.size());//NEW
  154. duplicateVertex.setTextureIndex(newTextureIndex);
  155. duplicateVertex.setNormalIndex(newNormalIndex);
  156. previousVertex.setDuplicateVertex(duplicateVertex);
  157. vertices.add(duplicateVertex);
  158. indices.add(duplicateVertex.getIndex());
  159. return duplicateVertex;
  160. }
  161. }
  162. }
  163. private static void removeUnusedVertices(List<Vertex> vertices) {
  164. for (Vertex vertex : vertices) {
  165. vertex.averageTangents();
  166. if (!vertex.isSet()) {
  167. vertex.setTextureIndex(0);
  168. vertex.setNormalIndex(0);
  169. }
  170. }
  171. }
  172. }