#Custom Made ObjLoader for JavaFX not working properly

1 messages · Page 1 of 1 (latest)

modest kettle
#

My custom made .obj file loader for javafx isn't properly importing the faces of the obj models correctly and i have no idea why.

ObjLoader: (also Ik this is ass, im a first year in college)
-see attached

What Im trying to load the obj file into: https://docs.oracle.com/javase/8/javafx/api/javafx/scene/shape/TriangleMesh.html

What it ends up looking like:
-see attached image

Obj File:
-see attached .obj file

Any help on why this is happening/how I should go about debugging this is greatly appreciated, if any more information is needed @ me.

sharp kiteBOT
#

<@&987246487241105418> please have a look, thanks.

sharp kiteBOT
high mango
# modest kettle My custom made .obj file loader for javafx isn't properly importing the faces of...

Hi @modest kettle, I think the issue might be in the order you're adding the face indices.
OBJ faces are stored as v/vt/vn, but when using VertexFormat.POINT_NORMAL_TEXCOORD, JavaFX expects them in the order: pointIndex, normalIndex, texCoordIndex.
In your current code, you're swapping the texture and normal indices when adding them to the faces array. Try adjusting the order so it matches what TriangleMesh expects.
Also double check whether your OBJ file contains quads instead of triangles, since TriangleMesh only supports triangles. If it's quads, you'll need to split each quad into two triangles.
You're definitely on the right track though. Writing a custom OBJ loader as a first year is solid work.

modest kettle
#

oh and on another note, when I try another obj mesh, the faces seem to be inside out

woven bane
#

that's easy

#

keep the first point fixed

#

So do 1,2,3 and 1,3,4

modest kettle
#

well I figured that out, thats how I got the cube to work, but ive seen obj files with faces w/ 5 vertices

#

and I have no idea how to approach that

high mango
# modest kettle You were right on the obj file containing quads instead of triangles! Although n...

nice, good catch on the quads👌 that's a big step already.
For triangulating faces, the common approach is called fan triangulation.
If you have a quad like:
f vo v1 v2 v3
You split it into:
(v0, v1, v2)
(V0, v2, b3)
Basically, you fix the first vertex and create triangles with the next pairs. THis works for any polygon with more than 3 vertices.
So in your parser, instead of assuming exactly 3 bertices per face, collect all vertices first, then loop like:
for(int i = 1; i < faceVertices.length - 1; i ++)
and build triangles (0, i, i + 1).

high mango
# modest kettle oh and on another note, when I try another obj mesh, the faces seem to be inside...

About the faces being inside out, that's usually a winding order issue.
If the vertex order is clock wise instead of counter-clockwise, the normal points the wrong way and the face gets culled.
you can test this by:

  • reversing the vertex order when building the triangle
  • or temporarily disabling baceface culling
    If reversing the order fixes it, then it's just winding direction.
    You're honestly doing really well here. Writing your own loader forces you to understand how 3D meshes actually work.
woven bane
#

1, 4, 5 then 1, 5, 6

#

Basically fan them out

#

There's better triangulation methods but that should give you a proper result already

#

What I'd do, (and apparently is called minimum-weight triangulation) is looking for the shortest distance between two vertices, add an edge between those two and keep going until all you have left is triangles

covert valve
#

I'll add the note that if you aren't sure how winding order works, you need to look up "right hand rule" and "left hand rule".

Many videos will be able to explain it pretty clearly. In all game engines(and math) right or left hand rule is how people actually figure out winding order, rather than saying clockwise/counterclockwise.

Afaik it's always centered on the first vertex pointing towards the next vertex, left hand or right hand based on where the third vertex is

woven bane
#

"well achshually" it depends on the sign of the tangents

#
String[] split = line.substring(2).trim().split(" +");
int[][] data = new int[split.length][];
boolean uvProvided = true;
boolean normalProvided = true;
for (int i = 0; i < split.length; i++) {
    String[] split2 = split[i].split("/");
    if (split2.length < 2) {
        uvProvided = false;
    }
    if (split2.length < 3) {
        normalProvided = false;
    }
    data[i] = new int[split2.length];
    for (int j = 0; j < split2.length; j++) {
        if (split2[j].length() == 0) {
            data[i][j] = 0;
            if (j == 1) {
                uvProvided = false;
            }
            if (j == 2) {
                normalProvided = false;
            }
        } else {
            data[i][j] = Integer.parseInt(split2[j]);
        }
    }
}
int v1 = vertexIndex(data[0][0]);
int uv1 = -1;
int n1 = -1;
if (uvProvided && !flatXZ) {
    uv1 = uvIndex(data[0][1]);
    if (uv1 < 0) {
        uvProvided = false;
    }
}
if (normalProvided) {
    n1 = normalIndex(data[0][2]);
    if (n1 < 0) {
        normalProvided = false;
    }
}
for (int i = 1; i < data.length - 1; i++) {
    int v2 = vertexIndex(data[i][0]);
    int v3 = vertexIndex(data[i + 1][0]);
    int uv2 = -1;
    int uv3 = -1;
    int n2 = -1;
    int n3 = -1;
    if (uvProvided && !flatXZ) {
        uv2 = uvIndex(data[i][1]);
        uv3 = uvIndex(data[i + 1][1]);
    }
    if (normalProvided) {
        n2 = normalIndex(data[i][2]);
        n3 = normalIndex(data[i + 1][2]);
    }

    //                    log("v1 = " + v1 + ", v2 = " + v2 + ", v3 = " + v3);
    //                    log("uv1 = " + uv1 + ", uv2 = " + uv2 + ", uv3 = " + uv3);

    faces.add(v1);
    faces.add(uv1);
    faces.add(v2);
    faces.add(uv2);
    faces.add(v3);
    faces.add(uv3);
    faceNormals.add(n1);
    faceNormals.add(n2);
    faceNormals.add(n3);

    smoothingGroups.add(currentSmoothGroup);
}
#

Found this code in some old java samples 😄

modest kettle
#

wow! thanks guys, i'll definitely be implementing all of ts when i have time

#

extremely helpful

covert valve