-
Notifications
You must be signed in to change notification settings - Fork 28
/
ModelLoader.java
133 lines (88 loc) · 3.63 KB
/
ModelLoader.java
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
133
package javavulkantutorial;
import org.joml.Vector2f;
import org.joml.Vector2fc;
import org.joml.Vector3f;
import org.joml.Vector3fc;
import org.lwjgl.PointerBuffer;
import org.lwjgl.assimp.*;
import java.io.File;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import static java.util.Objects.requireNonNull;
import static org.lwjgl.assimp.Assimp.*;
public class ModelLoader {
public static Model loadModel(File file, int flags) {
try(AIScene scene = aiImportFile(file.getAbsolutePath(), flags)) {
Logger logger = Logger.getLogger(ModelLoader.class.getSimpleName());
logger.info("Loading model " + file.getPath() + "...");
if(scene == null || scene.mRootNode() == null) {
throw new RuntimeException("Could not load model: " + aiGetErrorString());
}
Model model = new Model();
long startTime = System.nanoTime();
processNode(scene.mRootNode(), scene, model);
logger.info("Model loaded in " + ((System.nanoTime() - startTime) / 1e6) + "ms");
return model;
}
}
private static void processNode(AINode node, AIScene scene, Model model) {
if(node.mMeshes() != null) {
processNodeMeshes(scene, node, model);
}
if(node.mChildren() != null) {
PointerBuffer children = node.mChildren();
for(int i = 0;i < node.mNumChildren();i++) {
processNode(AINode.create(children.get(i)), scene, model);
}
}
}
private static void processNodeMeshes(AIScene scene, AINode node, Model model) {
PointerBuffer pMeshes = scene.mMeshes();
IntBuffer meshIndices = node.mMeshes();
for(int i = 0;i < meshIndices.capacity();i++) {
AIMesh mesh = AIMesh.create(pMeshes.get(meshIndices.get(i)));
processMesh(scene, mesh, model);
}
}
private static void processMesh(AIScene scene, AIMesh mesh, Model model) {
processPositions(mesh, model.positions);
processTexCoords(mesh, model.texCoords);
processIndices(mesh, model.indices);
}
private static void processPositions(AIMesh mesh, List<Vector3fc> positions) {
AIVector3D.Buffer vertices = requireNonNull(mesh.mVertices());
for(int i = 0;i < vertices.capacity();i++) {
AIVector3D position = vertices.get(i);
positions.add(new Vector3f(position.x(), position.y(), position.z()));
}
}
private static void processTexCoords(AIMesh mesh, List<Vector2fc> texCoords) {
AIVector3D.Buffer aiTexCoords = requireNonNull(mesh.mTextureCoords(0));
for(int i = 0;i < aiTexCoords.capacity();i++) {
final AIVector3D coords = aiTexCoords.get(i);
texCoords.add(new Vector2f(coords.x(), coords.y()));
}
}
private static void processIndices(AIMesh mesh, List<Integer> indices) {
AIFace.Buffer aiFaces = mesh.mFaces();
for(int i = 0;i < mesh.mNumFaces();i++) {
AIFace face = aiFaces.get(i);
IntBuffer pIndices = face.mIndices();
for(int j = 0;j < face.mNumIndices();j++) {
indices.add(pIndices.get(j));
}
}
}
public static class Model {
public final List<Vector3fc> positions;
public final List<Vector2fc> texCoords;
public final List<Integer> indices;
public Model() {
this.positions = new ArrayList<>();
this.texCoords = new ArrayList<>();
this.indices = new ArrayList<>();
}
}
}