2017-04-19 2 views
0

현재 LWJGL 및 OpenGL을 사용하는 ThinMatrix의 3D 게임 개발 자습서를 따르고 있습니다. 내 게임에서 충돌 감지를 구현하려고합니다. AABB 대 AABB 충돌을 감지 할 준비가되었지만 엔티티 주변의 경계 상자 크기를 얻는 방법을 파악할 수는 없습니다. 누군가 나를 안내하여 AABB의 크기를 계산할 수 있습니까? 이것은 OBJFileLoader 클래스입니다. -축 정렬 경계 상자의 크기 계산

package objConverter; 

import models.RawModel; 
import org.lwjgl.util.vector.*; 
import renderEngine.Loader; 

import java.io.*; 
import java.util.*; 

public class OBJFileLoader { 
    private static final String RES_LOC = "res/models/"; 

    public static RawModel loadOBJ(String objFileName, Loader loader) { 
     FileReader isr = null; 
     File objFile = new File(RES_LOC + objFileName + ".obj"); 
     try { 
      isr = new FileReader(objFile); 
     } catch (FileNotFoundException e) { 
      System.err.println("File not found in res; don't use any extension: " + e.getMessage()); 
     } 
     BufferedReader reader = new BufferedReader(isr); 
     String line; 
     List<Vertex> vertices = new ArrayList<>(); 
     List<Vector2f> textures = new ArrayList<>(); 
     List<Vector3f> normals = new ArrayList<>(); 
     List<Integer> indices = new ArrayList<>(); 
     try { 
      while (true) { 
       line = reader.readLine(); 
       if (line.startsWith("v ")) { 
        String[] currentLine = line.split(" "); 
        Vector3f vertex = new Vector3f(Float.valueOf(currentLine[1]), Float.valueOf(currentLine[2]), 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.valueOf(currentLine[1]), Float.valueOf(currentLine[2])); 
        textures.add(texture); 
       } else if (line.startsWith("vn ")) { 
        String[] currentLine = line.split(" "); 
        Vector3f normal = new Vector3f(Float.valueOf(currentLine[1]), Float.valueOf(currentLine[2]), 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); 
       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); 
     //  ModelData data = new ModelData(verticesArray, texturesArray, normalsArray, tangentsArray, indicesArray, furthest); 
     return loader.loadToVAO(verticesArray, texturesArray, normalsArray, indicesArray); 
    } 

    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 = new Vertex(vertices.size(), previousVertex.getPosition()); 
       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); 
      } 
     } 
    } 
} 
+0

메쉬의 정점의 각 축을 따라 최소 및 최대 위치를 찾습니다. – Vallentin

+0

죄송하지만, 그 예를 보여줄 수 있습니까? – amoametan

답변

0

이 튜토리얼을 오래 전부터 사용해 왔습니다. 최소 및 최대 x, y 및 z 구성 요소를 저장하면됩니다. 정점을 저장하는 경우이 작업을 수행하는 것이 좋습니다. 당신이 뭔가를 할 수 있습니다 :

float minX, minY, minZ, maxX, maxY, maxZ; 

try { 
    while(true) { 
     if ("v ") { 
      Vector3f ver = new Vector3f(Float.valueOf(curentLine[0]...); 
      if (ver.x < minX) minX = ver.x; 
      else if (ver.x > maxX) maxX = ver.x; 
      if (ver.y < minY) minY = ver.y; 
      ... 
     } 
    ... 
} 

이는 원유하지만, 기업의 최소 및 최대 x, y 및 z 경계를지고 가야하는 쉬운 방법입니다. 희망이 도움이됩니다.