2015-01-18 6 views
0

Я пишу Java-движок Java LWJGL 3D. Я решил переписать мой класс mesh и загрузчик .obj. Класс сетки отлично работает при вводе в данных вручную, но wehn загрузки из .obj-файла он дает какие-то странные результаты: (он должен быть дракон, но lokks вроде 2D ... то)Загрузка файла .obj странные результаты

public static Mesh loadMesh(String fileName) throws IOException 
{ 
    String splitArray[] = fileName.split("\\."); 
    String ext = splitArray[splitArray.length-1]; 

    if(!ext.equals("obj")) 
     System.err.println("Error: Engine can only load .obj files, try converting the file: " + fileName); 

    ArrayList<Vector3f> vertices = new ArrayList<Vector3f>(); 
    ArrayList<Integer> vindices = new ArrayList<Integer>(); 
    ArrayList<Integer> tindices = new ArrayList<Integer>(); 
    ArrayList<Integer> nindices = new ArrayList<Integer>(); 
    ArrayList<Vector3f> normals = new ArrayList<Vector3f>(); 
    ArrayList<Vector2f> texCoords = new ArrayList<Vector2f>(); 



    BufferedReader reader = new BufferedReader(new FileReader("./res/models/"+fileName)); 
    String line = ""; 

    while((line=reader.readLine())!=null) 
    { 
     String[] p = line.split(" "); 
     if(line.startsWith("v")) 
     { 
      vertices.add(new Vector3f(Float.valueOf(p[1]), 
             Float.valueOf(p[2]), 
             Float.valueOf(p[3]))); 
     } 
     if(line.startsWith("vn")) 
     { 
      normals.add(new Vector3f(Float.valueOf(p[1]), 
             Float.valueOf(p[2]), 
             Float.valueOf(p[3]))); 
     } 
     if(line.startsWith("vt")) 
     { 
      texCoords.add(new Vector2f(Float.valueOf(p[1]), 
             Float.valueOf(p[2]))); 
     } 
     if(line.startsWith("f")) 
     { 
      String[] arg1 = p[1].split("/"); 
      String[] arg2 = p[2].split("/"); 
      String[] arg3 = p[3].split("/"); 
      vindices.add(Integer.parseInt(arg1[0])); 
      if(arg1.length>1) 
      tindices.add(Integer.parseInt(arg1[1])); 
      if(arg1.length>2) 
      nindices.add(Integer.parseInt(arg1[3])); 

      vindices.add(Integer.parseInt(arg2[0])); 
      if(arg1.length>1) 
      tindices.add(Integer.parseInt(arg2[1])); 
      if(arg2.length>2) 
      nindices.add(Integer.parseInt(arg2[3])); 

      vindices.add(Integer.parseInt(arg3[0])); 
      if(arg1.length>1) 
      tindices.add(Integer.parseInt(arg3[1])); 
      if(arg3.length>2) 
      nindices.add(Integer.parseInt(arg3[3])); 
     } 
    } 

    float[] vdata = new float[vertices.size() * 3]; 
    float[] tdata = new float[texCoords.size() * 2]; 
    float[] ndata = new float[normals.size() * 3]; 
    for(int i = 0; i < vdata.length; i++) 
    { 
     vdata[i] = vertices.get(Integer.valueOf(vindices.get(i))).getX(); 
     vdata[i++] = vertices.get(Integer.valueOf(vindices.get(i))).getY(); 
     vdata[i++] = vertices.get(Integer.valueOf(vindices.get(i))).getZ(); 
    } 
    for(int i = 0; i < ndata.length; i++) 
    { 
     ndata[i] = normals.get(Integer.valueOf(nindices.get(i))).getX(); 
     ndata[i++] = normals.get(Integer.valueOf(nindices.get(i))).getY(); 
     ndata[i++] = normals.get(Integer.valueOf(nindices.get(i))).getZ(); 
    } 
    for(int i = 0; i < tdata.length; i++) 
    { 
     tdata[i] = texCoords.get(Integer.valueOf(tindices.get(i))).getX(); 
     tdata[i++] = texCoords.get(Integer.valueOf(tindices.get(i))).getY(); 
    } 
    return new Mesh(vdata, tdata, ndata); 
} 

thats мой загрузчик .obj-файлов. Не могу видеть, что это неправильно ...

+0

Вы вмещать только для трех вершин в лицо. Является ли ваш объект экспортирован как «три только», т. Е. Не имеет квадроциклов? – Dawnkeeper

+0

только его треугольники, он отлично работал, прежде чем я изменил его ... – Addi

ответ

0

При ближайшем рассмотрении есть некоторые хорошие ошибки:

vindices.add(Integer.parseInt(arg1[0])); 
if(arg1.length>1) 
tindices.add(Integer.parseInt(arg1[1])); 
if(arg1.length>2) 
nindices.add(Integer.parseInt(arg1[3])); // this should be 2 for the normals 

и

for(int i = 0; i < vdata.length; i++) 
{ 
    vdata[i] = vertices.get(Integer.valueOf(vindices.get(i))).getX(); //i=0 
    vdata[i++] = vertices.get(Integer.valueOf(vindices.get(i))).getY(); //i=0 and counted up afterwards 
    vdata[i++] = vertices.get(Integer.valueOf(vindices.get(i))).getZ();//i=1 and counted up afterwards 
} 

Это то, что делает сетку двумерную.
я предложил бы использовать eigther ++i или

for(int i = 0; i < vdata.length; i+=3) 
{ 
    vdata[i] = vertices.get(Integer.valueOf(vindices.get(i))).getX(); 
    vdata[i+1] = vertices.get(Integer.valueOf(vindices.get(i))).getY(); 
    vdata[i+2] = vertices.get(Integer.valueOf(vindices.get(i))).getZ(); 
} 
+0

Вы совершенно правы. Теперь это 3D, но все еще выглядит не совсем правильно. Я, должно быть, испортил что-то с индексами ... – Addi