-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathObjLoader.java
More file actions
132 lines (114 loc) · 3.2 KB
/
Copy pathObjLoader.java
File metadata and controls
132 lines (114 loc) · 3.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
ahbejarano
.obj mesh loader class.
*/
package geetransit.minecraft05.engine;
import java.util.*;
import org.joml.*;
public class ObjLoader {
public static Mesh loadMesh(String file) throws Exception {
List<Vector3f> vertices = new ArrayList<>();
List<Vector2f> textures = new ArrayList<>();
List<Face> faces = new ArrayList<>();
Utils.loadLinesStream(file).forEach(line -> {
String[] tokens = line.split("\\s+");
switch (tokens[0]) {
case "v":
// Geometric vertex
vertices.add(new Vector3f(
Float.parseFloat(tokens[1]),
Float.parseFloat(tokens[2]),
Float.parseFloat(tokens[3])
));
break;
case "vt":
// Texture coordinate
textures.add(new Vector2f(
Float.parseFloat(tokens[1]),
Float.parseFloat(tokens[2])
));
break;
case "f":
Face face = new Face(tokens[1], tokens[2], tokens[3]);
faces.add(face);
break;
default:
// Ignore other lines
break;
}
});
return reorderLists(vertices, textures, faces);
}
private static Mesh reorderLists(
List<Vector3f> vertexList,
List<Vector2f> coordList,
List<Face> faceList
) {
List<Integer> posList = new ArrayList<>();
// Create position array in the order it has been declared
float[] posArray = new float[vertexList.size() * 3];
for (int i = 0; i < vertexList.size(); i++) {
Vector3f pos = vertexList.get(i);
posArray[i*3 + 0] = pos.x;
posArray[i*3 + 1] = pos.y;
posArray[i*3 + 2] = pos.z;
}
float[] coordArray = new float[vertexList.size() * 2];
for (Face face : faceList)
for (IndexGroup group : face.groups)
processFaceVertex(group, coordList, posList, coordArray);
// int[] indexArray = new int[indices.size()];
int[] indexArray = Utils.intListToArray(posList);
return new Mesh(posArray, indexArray, coordArray);
}
private static void processFaceVertex(
IndexGroup group,
List<Vector2f> coordList,
List<Integer> posList,
float[] coordArray
) {
// Set pos for vertex coordinates
int pos = group.pos;
posList.add(pos);
// Reorder texture coordinates
if (group.coord != IndexGroup.NO_VALUE) {
Vector2f coord = coordList.get(group.coord);
coordArray[pos*2 + 0] = coord.x;
coordArray[pos*2 + 1] = 1 - coord.y;
}
}
protected static class IndexGroup {
public static final int NO_VALUE = -1;
public int pos;
public int coord;
public IndexGroup() {
this.pos = NO_VALUE;
this.coord = NO_VALUE;
}
}
protected static class Face {
// List of pos groups for a face triangle (3 vertices per face).
public final IndexGroup[] groups;
public Face(String v1, String v2, String v3) {
this.groups = new IndexGroup[3];
// Parse the lines
this.groups[0] = parseLine(v1);
this.groups[1] = parseLine(v2);
this.groups[2] = parseLine(v3);
}
private IndexGroup parseLine(String line) {
IndexGroup group = new IndexGroup();
String[] tokens = line.split("/");
int length = tokens.length;
group.pos = Integer.parseInt(tokens[0]) - 1;
if (length <= 1)
return group;
// It can be empty if the obj does not define text coords
if (tokens[1].length() != 0)
group.coord = Integer.parseInt(tokens[1]) - 1;
if (length <= 2)
return group;
return group;
}
}
}