Загрузка файла .obj странные результаты

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

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);
}

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


person Addi    schedule 18.01.2015    source источник
comment
Вы размещаете только по три вершины на грани. Ваш объект экспортируется только как три, т.е. не имеет четырехугольников?   -  person Dawnkeeper    schedule 23.01.2015
comment
только его треугольники, он отлично работал, прежде чем я его изменил ...   -  person Addi    schedule 23.01.2015


Ответы (1)


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

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
}

Именно это делает сетку двумерной.
Я бы предложил использовать либо ++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();
}
person Dawnkeeper    schedule 23.01.2015
comment
Вы совершенно правы. Теперь это 3D, но все еще выглядит не совсем правильно. Я наверное что-то напутал с индексами... - person Addi; 24.01.2015