123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- package eu.tankernn.gameEngine.loader.models.obj;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.List;
- import org.lwjgl.util.vector.Vector2f;
- import org.lwjgl.util.vector.Vector3f;
- import eu.tankernn.gameEngine.util.InternalFile;
- public class ObjLoader {
- public static ModelData loadOBJ(InternalFile objFile) {
- BufferedReader reader;
- try {
- reader = objFile.getReader();
- } catch (Exception e1) {
- e1.printStackTrace();
- return null;
- }
- String line;
- List<Vertex> vertices = new ArrayList<Vertex>();
- List<Vector2f> textures = new ArrayList<Vector2f>();
- List<Vector3f> normals = new ArrayList<Vector3f>();
- List<Integer> indices = new ArrayList<Integer>();
- try {
- while (true) {
- line = reader.readLine();
- if (line.startsWith("v ")) {
- String[] currentLine = line.split(" ");
- Vector3f vertex = new Vector3f((float) Float.valueOf(currentLine[1]),
- (float) Float.valueOf(currentLine[2]),
- (float) Float.valueOf(currentLine[3]));
- Vertex newVertex = new Vertex(vertices.size(), vertex);
- vertices.add(newVertex);
- } else if (line.startsWith("vt ")) {
- String[] currentLine = line.split(" ");
- Vector2f texture = new Vector2f((float) Float.valueOf(currentLine[1]),
- (float) Float.valueOf(currentLine[2]));
- textures.add(texture);
- } else if (line.startsWith("vn ")) {
- String[] currentLine = line.split(" ");
- Vector3f normal = new Vector3f((float) Float.valueOf(currentLine[1]),
- (float) Float.valueOf(currentLine[2]),
- (float) Float.valueOf(currentLine[3]));
- normals.add(normal);
- } else if (line.startsWith("f ")) {
- break;
- }
- }
- while (line != null && line.startsWith("f ")) {
- String[] currentLine = line.split(" ");
- String[] vertex1 = currentLine[1].split("/");
- String[] vertex2 = currentLine[2].split("/");
- String[] vertex3 = currentLine[3].split("/");
- Vertex v0 = processVertex(vertex1, vertices, indices);
- Vertex v1 = processVertex(vertex2, vertices, indices);
- Vertex v2 = processVertex(vertex3, vertices, indices);
- calculateTangents(v0, v1, v2, textures);//NEW
- line = reader.readLine();
- }
- reader.close();
- } catch (IOException e) {
- System.err.println("Error reading the file");
- }
- removeUnusedVertices(vertices);
- float[] verticesArray = new float[vertices.size() * 3];
- float[] texturesArray = new float[vertices.size() * 2];
- float[] normalsArray = new float[vertices.size() * 3];
- float[] tangentsArray = new float[vertices.size() * 3];
- float furthest = convertDataToArrays(vertices, textures, normals, verticesArray,
- texturesArray, normalsArray, tangentsArray);
- int[] indicesArray = convertIndicesListToArray(indices);
-
- return new ModelData(verticesArray, texturesArray, normalsArray, tangentsArray, indicesArray, furthest);
- }
- //NEW
- private static void calculateTangents(Vertex v0, Vertex v1, Vertex v2,
- List<Vector2f> textures) {
- Vector3f delatPos1 = Vector3f.sub(v1.getPosition(), v0.getPosition(), null);
- Vector3f delatPos2 = Vector3f.sub(v2.getPosition(), v0.getPosition(), null);
- Vector2f uv0 = textures.get(v0.getTextureIndex());
- Vector2f uv1 = textures.get(v1.getTextureIndex());
- Vector2f uv2 = textures.get(v2.getTextureIndex());
- Vector2f deltaUv1 = Vector2f.sub(uv1, uv0, null);
- Vector2f deltaUv2 = Vector2f.sub(uv2, uv0, null);
- float r = 1.0f / (deltaUv1.x * deltaUv2.y - deltaUv1.y * deltaUv2.x);
- delatPos1.scale(deltaUv2.y);
- delatPos2.scale(deltaUv1.y);
- Vector3f tangent = Vector3f.sub(delatPos1, delatPos2, null);
- tangent.scale(r);
- v0.addTangent(tangent);
- v1.addTangent(tangent);
- v2.addTangent(tangent);
- }
- private static Vertex processVertex(String[] vertex, List<Vertex> vertices,
- List<Integer> indices) {
- int index = Integer.parseInt(vertex[0]) - 1;
- Vertex currentVertex = vertices.get(index);
- int textureIndex = Integer.parseInt(vertex[1]) - 1;
- int normalIndex = Integer.parseInt(vertex[2]) - 1;
- if (!currentVertex.isSet()) {
- currentVertex.setTextureIndex(textureIndex);
- currentVertex.setNormalIndex(normalIndex);
- indices.add(index);
- return currentVertex;
- } else {
- return dealWithAlreadyProcessedVertex(currentVertex, textureIndex, normalIndex, indices,
- vertices);
- }
- }
- private static int[] convertIndicesListToArray(List<Integer> indices) {
- int[] indicesArray = new int[indices.size()];
- for (int i = 0; i < indicesArray.length; i++) {
- indicesArray[i] = indices.get(i);
- }
- return indicesArray;
- }
- private static float convertDataToArrays(List<Vertex> vertices, List<Vector2f> textures,
- List<Vector3f> normals, float[] verticesArray, float[] texturesArray,
- float[] normalsArray, float[] tangentsArray) {
- float furthestPoint = 0;
- for (int i = 0; i < vertices.size(); i++) {
- Vertex currentVertex = vertices.get(i);
- if (currentVertex.getLength() > furthestPoint) {
- furthestPoint = currentVertex.getLength();
- }
- Vector3f position = currentVertex.getPosition();
- Vector2f textureCoord = textures.get(currentVertex.getTextureIndex());
- Vector3f normalVector = normals.get(currentVertex.getNormalIndex());
- Vector3f tangent = currentVertex.getAverageTangent();
- verticesArray[i * 3] = position.x;
- verticesArray[i * 3 + 1] = position.y;
- verticesArray[i * 3 + 2] = position.z;
- texturesArray[i * 2] = textureCoord.x;
- texturesArray[i * 2 + 1] = 1 - textureCoord.y;
- normalsArray[i * 3] = normalVector.x;
- normalsArray[i * 3 + 1] = normalVector.y;
- normalsArray[i * 3 + 2] = normalVector.z;
- tangentsArray[i * 3] = tangent.x;
- tangentsArray[i * 3 + 1] = tangent.y;
- tangentsArray[i * 3 + 2] = tangent.z;
- }
- return furthestPoint;
- }
- private static Vertex dealWithAlreadyProcessedVertex(Vertex previousVertex, int newTextureIndex,
- int newNormalIndex, List<Integer> indices, List<Vertex> vertices) {
- if (previousVertex.hasSameTextureAndNormal(newTextureIndex, newNormalIndex)) {
- indices.add(previousVertex.getIndex());
- return previousVertex;
- } else {
- Vertex anotherVertex = previousVertex.getDuplicateVertex();
- if (anotherVertex != null) {
- return dealWithAlreadyProcessedVertex(anotherVertex, newTextureIndex,
- newNormalIndex, indices, vertices);
- } else {
- Vertex duplicateVertex = previousVertex.duplicate(vertices.size());//NEW
- duplicateVertex.setTextureIndex(newTextureIndex);
- duplicateVertex.setNormalIndex(newNormalIndex);
- previousVertex.setDuplicateVertex(duplicateVertex);
- vertices.add(duplicateVertex);
- indices.add(duplicateVertex.getIndex());
- return duplicateVertex;
- }
- }
- }
- private static void removeUnusedVertices(List<Vertex> vertices) {
- for (Vertex vertex : vertices) {
- vertex.averageTangents();
- if (!vertex.isSet()) {
- vertex.setTextureIndex(0);
- vertex.setNormalIndex(0);
- }
- }
- }
- }
|