加载.obj文件奇怪的结果

时间:2015-01-18 11:57:43

标签: java lwjgl loader .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文件加载器。看不出有什么问题......

1 个答案:

答案 0 :(得分: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
}

这是使网格二维的原因。
我建议使用++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();
}