Java .OBJ File Loader

1.2k views Asked by At

I have quite a long question that I hope someone can help me with. I'm having some trouble loading a obj file to the format i would like. I'm trying to load the file's vertices and texture coords into an array of the following:

public class Vertex {

private float x;
private float y;
private float z;

private float u;
private float v;

public Vertex(float x, float y, float z, float u, float v) {
    this.x = x;
    this.y = y;
    this.z = z;
    this.u = u;
    this.v = v;
}

public float getX() {
    return x;
}
public float getY() {
    return y;
}
public float getZ() {
    return z;
}

public float getU() {
    return u;
}

public float getV() {
    return v;
}
}

After this is done I would like the all the indices in an array of the following:

public class Index3 {

private int i1;
private int i2;
private int i3;

public Index3(int i1, int i2, int i3) {
    this.i1 = i1;
    this.i2 = i2;
    this.i3 = i3;
}

public int getI1() {
    return i1;
}

public int getI2() {
    return i2;
}

public int getI3() {
    return i3;
}
}

I have these two arrays being drawn to the screen just fine when I code the arrays myself, but my obj loader is clearly not correct.

public class OBJLoader {

public static Mesh loadModel(String fileName) {
    FileReader fr = null;
    try {
        fr = new FileReader(new File("res/models/" + fileName));
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

    BufferedReader reader = new BufferedReader(fr);
    String line = null;

    List<Index3> indices = new ArrayList<Index3>();

    List<OBJFace> objFaces = new ArrayList<OBJFace>();

    List<Vector3f> vs = new ArrayList<Vector3f>();
    List<Vector2f> vts = new ArrayList<Vector2f>();
    List<Vector3f> vns = new ArrayList<Vector3f>();

    try {
        while ((line = reader.readLine()) != null) {
            String[] split = line.split(" ");
            if (line.startsWith("v ")) {
                Vector3f v = new Vector3f();
                v.setX(Float.parseFloat(split[1]));
                v.setY(Float.parseFloat(split[2]));
                v.setZ(Float.parseFloat(split[3]));
                vs.add(v);
            } else if (line.startsWith("vt ")) {
                Vector2f vt = new Vector2f();
                vt.setX(Float.parseFloat(split[1]));
                vt.setY(Float.parseFloat(split[2]));
                vts.add(vt);
            } else if (line.startsWith("vn ")) {
                Vector3f vn = new Vector3f();
                vn.setX(Float.parseFloat(split[1]));
                vn.setY(Float.parseFloat(split[2]));
                vn.setZ(Float.parseFloat(split[3]));
                vns.add(vn);
            } else if (line.startsWith("f ")) {
                objFaces.add(parseFace(split[1]));
                objFaces.add(parseFace(split[2]));
                objFaces.add(parseFace(split[3]));
                String[] s1 = split[1].split("/");
                String[] s2 = split[2].split("/");
                String[] s3 = split[3].split("/");
                indices.add(new Index3(Integer.parseInt(s1[0]), Integer.parseInt(s2[0]), Integer.parseInt(s3[0])));
            }
        }
        reader.close();
    } catch (Exception e) {
        e.printStackTrace();
    }

    Vertex[] vertices = new Vertex[objFaces.size()];
    Index3[] finalIndices = new Index3[indices.size()];

    for (int i = 0; i < objFaces.size(); i++) {
        OBJFace current = objFaces.get(i);

        Vector3f currentPos;
        Vector2f currentTex;
        Vector3f currentNorm;

        //FIX AUTOGEN NORMALS AND TEX COORDS
        if (current.getVertex() != -1)
            currentPos = vs.get(current.getVertex());
        else
            currentPos = new Vector3f(0, 0, 0);
        if (current.getTexCoord() != -1)
            currentTex = vts.get(current.getTexCoord());
        else
            currentTex = new Vector2f(1, 1);
        if (current.getNormal() != -1)
            currentNorm = vns.get(current.getNormal());         
        else 
            currentNorm = new Vector3f(0, 1, 0);

        Vertex newVert = new Vertex(currentPos.getX(), currentPos.getY(), currentPos.getZ(), currentTex.getX(), currentTex.getY());

        vertices[i] = newVert;
    }

    for (int i = 0; i < indices.size(); i++) {
        finalIndices[i] = indices.get(i);
    }

    return new Mesh(vertices, finalIndices);
}

private static OBJFace parseFace(String face) {
    String[] split = face.split("/");

    int vi = -1;
    int vti = -1;
    int vni = -1;

    vi = Integer.parseInt(split[0]) - 1;

    if (split.length > 1) {
        if (!split[1].isEmpty()) {
            vti = Integer.parseInt(split[1]) - 1;
        }
    }

    if (split.length > 2) {
            vni = Integer.parseInt(split[2]) - 1;
    }

    return new OBJFace(vi, vti, vni);
}
}

When I draw a cube from a obj file using this loader a very distorted bunch of triangles are drawn randomly in the area of the cube.

Ultimately I'm asking were in the loader did I go wrong and how can I fix it.

Thanks for any help!!!

0

There are 0 answers