Initial fastgltf integration

This commit is contained in:
Erris
2026-03-08 11:38:46 +01:00
parent 48d2905695
commit ac18bb6f00
7 changed files with 137 additions and 22 deletions

View File

@@ -4,6 +4,7 @@ spdlog/1.16.0
entt/3.16.0
yaml-cpp/0.8.0
joltphysics/5.2.0
fastgltf/0.9.0
[generators]
CMakeDeps

View File

@@ -4,6 +4,9 @@
#include <X11/X.h>
#include <open_engine.hpp>
#include "open_engine/fastgltf.hpp"
#include "open_engine/logging.hpp"
#include "open_engine/ref_scope.hpp"
#include "open_engine/renderer/renderer3d.hpp"
#include "open_engine/scene/components.hpp"
#include "panels/content_browser.hpp"
@@ -129,6 +132,15 @@ namespace OpenEngine {
auto& mc2 = cube2.AddComponent<MeshComponent>(mesh2);
mc2.primitive_type = PrimitiveType::Cube;
// ============================================================
Entity cube3 = scene->CreateEntity("glb");
cube3.AddComponent<TransformComponent>();
Ref<Mesh> test = TestGLTF();
cube3.AddComponent<MeshComponent>(CreateMesh(test->vertices, test->indices, (uint32_t)cube3));
/*
auto view = scene->GetRegistry().view<TagComponent>();

View File

@@ -0,0 +1,13 @@
#ifndef FASTGLTF_HPP
#define FASTGLTF_HPP
#include "renderer/renderer3d.hpp"
#include "open_engine/ref_scope.hpp"
namespace OpenEngine {
Ref<Mesh> TestGLTF();
}
#endif // FASTGLTF_HPP

View File

@@ -48,7 +48,8 @@ namespace OpenEngine {
};
Ref<Mesh> CreateMesh(const std::vector<MeshVertex>& vertices,
const std::vector<uint32_t>& indices);
const std::vector<uint32_t>& indices,
uint32_t id);
Ref<Mesh> CreateCube(uint32_t id = -1);
Ref<Mesh> CreateQuad(uint32_t id = -1, bool back_face = false);
// ==================================================

View File

@@ -0,0 +1,89 @@
#include <pch.hpp>
#include "logging.hpp"
#include <fastgltf.hpp>
#include "ref_scope.hpp"
#include "renderer/renderer3d.hpp"
#include <cstddef>
#include <cstdint>
#include <glm/fwd.hpp>
#include <fastgltf/core.hpp>
#include <fastgltf/types.hpp>
#include <fastgltf/tools.hpp>
#include <fastgltf/glm_element_traits.hpp>
#include <vector>
namespace OpenEngine {
void loadPrimitive(fastgltf::Asset& asset,
fastgltf::Primitive& primitive,
Mesh& out)
{
if (primitive.indicesAccessor.has_value()) {
auto& accessor = asset.accessors[primitive.indicesAccessor.value()];
out.indices.resize(accessor.count);
fastgltf::iterateAccessorWithIndex<uint32_t>(asset, accessor,
[&](uint32_t index, size_t i) {
out.indices[i] = index;
});
}
{
auto* position_iterator = primitive.findAttribute("POSITION");
auto& accessor = asset.accessors[position_iterator->accessorIndex];
out.vertices.resize(accessor.count);
fastgltf::iterateAccessorWithIndex<glm::vec3>(asset, accessor,
[&](glm::vec3 pos, size_t i) {
out.vertices[i].position = pos;
});
}
if (auto* normal_iterator = primitive.findAttribute("NORMAL");
normal_iterator != primitive.attributes.end()) {
auto& accessor = asset.accessors[normal_iterator->accessorIndex];
fastgltf::iterateAccessorWithIndex<glm::vec3>(asset, accessor,
[&](glm::vec3 norm, size_t i) {
out.vertices[i].normal = norm;
});
}
{
if (primitive.materialIndex.has_value()) {
auto& material = asset.materials[primitive.materialIndex.value()];
auto& pbr = material.pbrData;
auto& c = pbr.baseColorFactor;
for (auto& vert : out.vertices)
vert.color = glm::vec4(c[0], c[1], c[2], c[3]);
}
}
}
Ref<Mesh> TestGLTF()
{
fastgltf::Parser parser;
Ref<Mesh> new_mesh = CreateRef<Mesh>();
auto data = fastgltf::GltfDataBuffer::FromPath("assets/models/cube.glb");
if (data.error() != fastgltf::Error::None)
OE_CORE_ERROR("Could not parse model");
auto asset = parser.loadGltfBinary(data.get(), ".",
fastgltf::Options::LoadExternalBuffers
);
if (asset.error() != fastgltf::Error::None)
OE_CORE_ERROR("Could not optain asset");
for (auto& mesh : asset->meshes)
for (auto& primitive : mesh.primitives)
loadPrimitive(asset.get(), primitive, *new_mesh);
return new_mesh;
}
}

View File

@@ -24,16 +24,22 @@ namespace OpenEngine {
// SHOULD BE MOVED ==================================
Ref<Mesh> CreateMesh(const std::vector<MeshVertex>& vertices,
const std::vector<uint32_t>& indices)
const std::vector<uint32_t>& indices,
uint32_t id)
{
Ref<Mesh> mesh = CreateRef<Mesh>();
mesh->vertices = vertices;
std::vector<MeshVertex> verts = vertices;
for (auto& vertex : verts)
vertex.id = id;
mesh->vertices = verts;
mesh->indices = indices;
mesh->vertex_array = VertexArray::Create();
mesh->vertex_buffer = VertexBuffer::Create(vertices.size() * sizeof(MeshVertex));
mesh->vertex_buffer->SetData(vertices.data(), vertices.size() * sizeof(MeshVertex));
mesh->vertex_buffer->SetData(mesh->vertices.data(), vertices.size() * sizeof(MeshVertex));
BufferLayout layout = {
{ ShaderDataType::Float3, "a_Position" },
@@ -94,7 +100,7 @@ namespace OpenEngine {
};
}
return CreateMesh(vertices, indices);
return CreateMesh(vertices, indices, id);
}
Ref<Mesh> CreateCube(uint32_t id)
@@ -154,7 +160,7 @@ namespace OpenEngine {
20, 22, 21, 20, 23, 22
};
return CreateMesh(vertices, indices);
return CreateMesh(vertices, indices, id);
}
// ==================================================

View File

@@ -93,8 +93,7 @@ namespace OpenEngine {
out << YAML::BeginMap;
out << YAML::Key << "Entity" << YAML::Value << entity.GetUUID(); // Needs random
if (entity.HasComponent<TagComponent>())
{
if (entity.HasComponent<TagComponent>()) {
out << YAML::Key << "TagComponent";
out << YAML::BeginMap; // TagComponent
@@ -104,8 +103,7 @@ namespace OpenEngine {
out << YAML::EndMap; // TagComponent
}
if (entity.HasComponent<TransformComponent>())
{
if (entity.HasComponent<TransformComponent>()) {
out << YAML::Key << "TransformComponent";
out << YAML::BeginMap; // TransformComponent
@@ -141,8 +139,7 @@ namespace OpenEngine {
out << YAML::EndMap; // CameraComponent
}
if (entity.HasComponent<SpriteRendererComponent>())
{
if (entity.HasComponent<SpriteRendererComponent>()) {
out << YAML::Key << "SpriteRendererComponent";
out << YAML::BeginMap; // SpriteRendererComponent
@@ -266,8 +263,7 @@ namespace OpenEngine {
OE_CORE_TRACE("Deserializing scene '{0}'", sceneName);
auto entities = data["Entities"];
if (entities)
{
if (entities) {
for (auto entity : entities)
{
uint64_t uuid = entity["Entity"].as<uint64_t>();
@@ -282,8 +278,7 @@ namespace OpenEngine {
Entity deserializedEntity = context->CreateEntityWithUUID(uuid, name);
auto transformComponent = entity["TransformComponent"];
if (transformComponent)
{
if (transformComponent) {
auto& tc = deserializedEntity.AddComponent<TransformComponent>();
tc.translation = transformComponent["Translation"].as<glm::vec3>();
tc.rotation = transformComponent["Rotation"].as<glm::vec3>();
@@ -291,8 +286,7 @@ namespace OpenEngine {
}
auto cameraComponent = entity["CameraComponent"];
if (cameraComponent)
{
if (cameraComponent) {
auto& cc = deserializedEntity.AddComponent<CameraComponent>();
auto camera_props = cameraComponent["Camera"];
@@ -311,15 +305,13 @@ namespace OpenEngine {
}
auto spriteRendererComponent = entity["SpriteRendererComponent"];
if (spriteRendererComponent)
{
if (spriteRendererComponent) {
auto& src = deserializedEntity.AddComponent<SpriteRendererComponent>();
src.color = spriteRendererComponent["Color"].as<glm::vec4>();
}
auto mesh_component = entity["MeshComponent"];
if (mesh_component)
{
if (mesh_component) {
auto& mesh = deserializedEntity.AddComponent<MeshComponent>();
mesh.primitive_type = (PrimitiveType)mesh_component["MeshType"].as<int>();
switch (mesh.primitive_type) {
@@ -388,6 +380,7 @@ namespace OpenEngine {
return true;
}
bool SceneSerializer::DeserializeRuntime(const std::string& file_path)
{
OE_CORE_ASSERT(false, "Not implemented yet");