Skip to content

Commit 449c4d7

Browse files
Refac obj file parsing
1 parent 852c394 commit 449c4d7

File tree

2 files changed

+53
-62
lines changed

2 files changed

+53
-62
lines changed

pacman-ui-lib/src/main/java/de/amr/pacmanfx/uilib/objimport/ObjFileData.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class ObjFileData {
1919
List<Map<String, Material>> materialMapsList = new ArrayList<>();
2020
ObservableFloatArray vertexArray = FXCollections.observableFloatArray();
2121
ObservableFloatArray uvArray = FXCollections.observableFloatArray();
22-
ArrayList<Integer> faceList = new ArrayList<>();
22+
ArrayList<Integer> facesList = new ArrayList<>();
2323
ArrayList<Integer> smoothingGroupList = new ArrayList<>();
2424
ObservableFloatArray normalsArray = FXCollections.observableFloatArray();
2525
ArrayList<Integer> faceNormalsList = new ArrayList<>();

pacman-ui-lib/src/main/java/de/amr/pacmanfx/uilib/objimport/ObjFileImporter.java

Lines changed: 52 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ else if (line.startsWith("vt ")) {
193193
}
194194
commitCurrentMesh();
195195
Logger.info("OBJ file parsed: {} vertices, {} uvs, {} faces, {} smoothing groups",
196-
data.vertexArray.size() / 3, data.uvArray.size() / 2, data.faceList.size() / 6, data.smoothingGroupList.size());
196+
data.vertexArray.size() / 3, data.uvArray.size() / 2, data.facesList.size() / 6, data.smoothingGroupList.size());
197197
}
198198

199199
/**
@@ -258,7 +258,7 @@ private void parseFace(String argText) {
258258
n2 = data.normalIndex(triplets[i][2]);
259259
n3 = data.normalIndex(triplets[i + 1][2]);
260260
}
261-
data.faceList.addAll(List.of(v1, uv1, v2, uv2, v3, uv3));
261+
data.facesList.addAll(List.of(v1, uv1, v2, uv2, v3, uv3));
262262
data.faceNormalsList.addAll(List.of(n1, n2, n3));
263263
data.smoothingGroupList.add(currentSmoothingGroup);
264264
}
@@ -331,91 +331,82 @@ private void parseVertexNormal(String argsText) {
331331
}
332332

333333
private void commitCurrentMesh() {
334-
if (facesStart >= data.faceList.size()) {
334+
if (facesStart >= data.facesList.size()) {
335335
// we're only interested in faces
336336
smoothingGroupsStart = data.smoothingGroupList.size();
337337
return;
338338
}
339339
var vertexMap = new HashMap<Integer, Integer>(data.vertexArray.size() / 2);
340340
var uvMap = new HashMap<Integer, Integer>(data.uvArray.size() / 2);
341-
var normalMap = new HashMap<Integer, Integer>(data.normalsArray.size() / 2);
341+
var normalsMap = new HashMap<Integer, Integer>(data.normalsArray.size() / 2);
342342

343-
var newVertexArray = FXCollections.observableFloatArray();
344-
var newUVArray = FXCollections.observableFloatArray();
345-
var newNormalArray = FXCollections.observableFloatArray();
343+
var verticesArray = FXCollections.observableFloatArray();
344+
var texCoordsArray = FXCollections.observableFloatArray();
345+
var normalsArray = FXCollections.observableFloatArray();
346346

347347
boolean useNormals = true;
348348

349-
for (int i = facesStart; i < data.faceList.size(); i += 2) {
350-
int vi = data.faceList.get(i);
351-
Integer nvi = vertexMap.get(vi);
352-
if (nvi == null) {
353-
nvi = newVertexArray.size() / 3;
354-
vertexMap.put(vi, nvi);
355-
newVertexArray.addAll(
356-
data.vertexArray.get(vi * 3),
357-
data.vertexArray.get(vi * 3 + 1),
358-
data.vertexArray.get(vi * 3 + 2)
349+
for (int facesIndex = facesStart; facesIndex < data.facesList.size(); facesIndex += 2) {
350+
351+
// First comes vertex index
352+
final int vertexIndex = data.facesList.get(facesIndex);
353+
if (!vertexMap.containsKey(vertexIndex)) {
354+
vertexMap.put(vertexIndex, verticesArray.size() / 3);
355+
verticesArray.addAll(
356+
data.vertexArray.get(vertexIndex * 3),
357+
data.vertexArray.get(vertexIndex * 3 + 1),
358+
data.vertexArray.get(vertexIndex * 3 + 2)
359359
);
360360
}
361-
data.faceList.set(i, nvi);
362-
363-
int uvi = data.faceList.get(i + 1);
364-
Integer nuvi = uvMap.get(uvi);
365-
if (nuvi == null) {
366-
nuvi = newUVArray.size() / 2;
367-
uvMap.put(uvi, nuvi);
368-
if (uvi >= 0) {
369-
newUVArray.addAll(
370-
data.uvArray.get(uvi * 2),
371-
data.uvArray.get(uvi * 2 + 1)
361+
data.facesList.set(facesIndex, vertexMap.get(vertexIndex));
362+
363+
// Second comes texture coordinate index
364+
final int texCoordIndex = data.facesList.get(facesIndex + 1);
365+
if (!uvMap.containsKey(texCoordIndex)) {
366+
uvMap.put(texCoordIndex, texCoordsArray.size() / 2);
367+
if (texCoordIndex >= 0) {
368+
texCoordsArray.addAll(
369+
data.uvArray.get(texCoordIndex * 2),
370+
data.uvArray.get(texCoordIndex * 2 + 1)
372371
);
373372
} else {
374-
newUVArray.addAll(0f, 0f);
373+
texCoordsArray.addAll(0f, 0f);
375374
}
376375
}
377-
data.faceList.set(i + 1, nuvi);
376+
data.facesList.set(facesIndex + 1, uvMap.get(texCoordIndex));
378377

379378
if (useNormals) {
380-
int ni = data.faceNormalsList.get(i / 2);
381-
Integer nni = normalMap.get(ni);
382-
if (nni == null) {
383-
nni = newNormalArray.size() / 3;
384-
normalMap.put(ni, nni);
385-
if (ni >= 0 && data.normalsArray.size() >= (ni + 1) * 3) {
386-
newNormalArray.addAll(
387-
data.normalsArray.get(ni * 3),
388-
data.normalsArray.get(ni * 3 + 1),
389-
data.normalsArray.get(ni * 3 + 2)
379+
int normalsIndex = data.faceNormalsList.get(facesIndex / 2);
380+
if (!normalsMap.containsKey(normalsIndex)) {
381+
normalsMap.put(normalsIndex, normalsArray.size() / 3);
382+
if (normalsIndex >= 0 && data.normalsArray.size() >= (normalsIndex + 1) * 3) {
383+
normalsArray.addAll(
384+
data.normalsArray.get(normalsIndex * 3),
385+
data.normalsArray.get(normalsIndex * 3 + 1),
386+
data.normalsArray.get(normalsIndex * 3 + 2)
390387
);
391388
} else {
392389
useNormals = false;
393-
newNormalArray.addAll(0f, 0f, 0f);
390+
normalsArray.addAll(0f, 0f, 0f);
394391
}
395392
}
396-
data.faceNormalsList.set(i / 2, nni);
393+
data.faceNormalsList.set(facesIndex / 2, normalsMap.get(normalsIndex));
397394
}
398395
}
399396

397+
// Now build the triangle mesh from the parsed data:
398+
400399
final var mesh = new TriangleMesh();
401-
mesh.getPoints().setAll(newVertexArray);
402-
mesh.getTexCoords().setAll(newUVArray);
403-
404-
int[] facesRest = toIntArray(restOf(data.faceList, facesStart));
405-
mesh.getFaces().setAll(facesRest);
406-
// Use normals if they are provided
407-
if (useNormals) {
408-
int[] smoothingGroups = computeSmoothingGroups(
409-
mesh,
410-
facesRest,
411-
toIntArray(restOf(data.faceNormalsList, facesNormalStart)),
412-
toFloatArray(newNormalArray)
413-
);
414-
mesh.getFaceSmoothingGroups().setAll(smoothingGroups);
415-
} else {
416-
int[] smoothingGroupsRest = toIntArray(restOf(data.smoothingGroupList, smoothingGroupsStart));
417-
mesh.getFaceSmoothingGroups().setAll(smoothingGroupsRest);
418-
}
400+
mesh.getPoints().setAll(verticesArray);
401+
mesh.getTexCoords().setAll(texCoordsArray);
402+
403+
int[] faces = toIntArray(restOf(data.facesList, facesStart));
404+
mesh.getFaces().setAll(faces);
405+
406+
int[] smoothingGroups = useNormals
407+
? computeSmoothingGroups(mesh, faces, toIntArray(restOf(data.faceNormalsList, facesNormalStart)), toFloatArray(normalsArray))
408+
: toIntArray(restOf(data.smoothingGroupList, smoothingGroupsStart));
409+
mesh.getFaceSmoothingGroups().setAll(smoothingGroups);
419410

420411
// try specified name, if already used, make unique name using serial number e.g. "my_mesh (3)"
421412
int serialNumber = 2;
@@ -434,7 +425,7 @@ private void commitCurrentMesh() {
434425
mesh.getFaces().size() / mesh.getFaceElementSize(),
435426
mesh.getFaceSmoothingGroups().size());
436427

437-
facesStart = data.faceList.size();
428+
facesStart = data.facesList.size();
438429
facesNormalStart = data.faceNormalsList.size();
439430
smoothingGroupsStart = data.smoothingGroupList.size();
440431
}

0 commit comments

Comments
 (0)