121 lines
3.2 KiB
Java
121 lines
3.2 KiB
Java
package com.github.hydos.ginger.engine.vulkan.model;
|
|
|
|
import static java.util.Objects.requireNonNull;
|
|
import static org.lwjgl.assimp.Assimp.*;
|
|
|
|
import java.io.File;
|
|
import java.nio.IntBuffer;
|
|
import java.util.*;
|
|
|
|
import org.joml.*;
|
|
import org.lwjgl.PointerBuffer;
|
|
import org.lwjgl.assimp.*;
|
|
|
|
public class VKModelLoader {
|
|
|
|
public static VKMesh loadModel(File file, int flags) {
|
|
|
|
try(AIScene scene = aiImportFile(file.getAbsolutePath(), flags)) {
|
|
|
|
if(scene == null || scene.mRootNode() == null) {
|
|
throw new RuntimeException("Could not load model: " + aiGetErrorString());
|
|
}
|
|
|
|
VKMesh model = new VKMesh();
|
|
|
|
processNode(scene.mRootNode(), scene, model);
|
|
|
|
return model;
|
|
}
|
|
}
|
|
|
|
private static void processNode(AINode node, AIScene scene, VKMesh 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, VKMesh 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, VKMesh 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 VKMesh {
|
|
|
|
public final List<Vector3fc> positions;
|
|
public final List<Vector2fc> texCoords;
|
|
public final List<Integer> indices;
|
|
|
|
public VKMesh() {
|
|
this.positions = new ArrayList<>();
|
|
this.texCoords = new ArrayList<>();
|
|
this.indices = new ArrayList<>();
|
|
}
|
|
}
|
|
|
|
|
|
}
|