104 lines
2.8 KiB
Java
104 lines
2.8 KiB
Java
package com.github.hydos.ginger.engine.vulkan.misc;
|
|
|
|
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<>();
|
|
}
|
|
}
|
|
}
|