diff --git a/conanfile.txt b/conanfile.txt index b7fcf28..d325039 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -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 diff --git a/editor/include/editor.hpp b/editor/include/editor.hpp index 3eef8ca..dbc69bc 100755 --- a/editor/include/editor.hpp +++ b/editor/include/editor.hpp @@ -4,6 +4,9 @@ #include #include +#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(mesh2); mc2.primitive_type = PrimitiveType::Cube; + // ============================================================ + + Entity cube3 = scene->CreateEntity("glb"); + cube3.AddComponent(); + + Ref test = TestGLTF(); + + cube3.AddComponent(CreateMesh(test->vertices, test->indices, (uint32_t)cube3)); + /* auto view = scene->GetRegistry().view(); diff --git a/open_engine/include/open_engine/fastgltf.hpp b/open_engine/include/open_engine/fastgltf.hpp new file mode 100644 index 0000000..77976f1 --- /dev/null +++ b/open_engine/include/open_engine/fastgltf.hpp @@ -0,0 +1,13 @@ +#ifndef FASTGLTF_HPP +#define FASTGLTF_HPP + +#include "renderer/renderer3d.hpp" +#include "open_engine/ref_scope.hpp" + +namespace OpenEngine { + + Ref TestGLTF(); + +} + +#endif // FASTGLTF_HPP diff --git a/open_engine/include/open_engine/renderer/renderer3d.hpp b/open_engine/include/open_engine/renderer/renderer3d.hpp index 2ee90df..61f127e 100644 --- a/open_engine/include/open_engine/renderer/renderer3d.hpp +++ b/open_engine/include/open_engine/renderer/renderer3d.hpp @@ -48,7 +48,8 @@ namespace OpenEngine { }; Ref CreateMesh(const std::vector& vertices, - const std::vector& indices); + const std::vector& indices, + uint32_t id); Ref CreateCube(uint32_t id = -1); Ref CreateQuad(uint32_t id = -1, bool back_face = false); // ================================================== diff --git a/open_engine/src/open_engine/fastgltf.cpp b/open_engine/src/open_engine/fastgltf.cpp new file mode 100644 index 0000000..8e591df --- /dev/null +++ b/open_engine/src/open_engine/fastgltf.cpp @@ -0,0 +1,89 @@ +#include + +#include "logging.hpp" +#include +#include "ref_scope.hpp" +#include "renderer/renderer3d.hpp" + +#include +#include +#include +#include +#include +#include +#include + +#include + +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(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(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(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 TestGLTF() + { + fastgltf::Parser parser; + Ref new_mesh = CreateRef(); + + 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; + } + +} diff --git a/open_engine/src/open_engine/renderer/renderer3d.cpp b/open_engine/src/open_engine/renderer/renderer3d.cpp index 291bfb7..7917134 100644 --- a/open_engine/src/open_engine/renderer/renderer3d.cpp +++ b/open_engine/src/open_engine/renderer/renderer3d.cpp @@ -24,16 +24,22 @@ namespace OpenEngine { // SHOULD BE MOVED ================================== Ref CreateMesh(const std::vector& vertices, - const std::vector& indices) + const std::vector& indices, + uint32_t id) { Ref mesh = CreateRef(); - mesh->vertices = vertices; + + std::vector 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 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); } // ================================================== diff --git a/open_engine/src/open_engine/scene/scene_serializer.cpp b/open_engine/src/open_engine/scene/scene_serializer.cpp index 6213720..502095a 100644 --- a/open_engine/src/open_engine/scene/scene_serializer.cpp +++ b/open_engine/src/open_engine/scene/scene_serializer.cpp @@ -93,8 +93,7 @@ namespace OpenEngine { out << YAML::BeginMap; out << YAML::Key << "Entity" << YAML::Value << entity.GetUUID(); // Needs random - if (entity.HasComponent()) - { + if (entity.HasComponent()) { out << YAML::Key << "TagComponent"; out << YAML::BeginMap; // TagComponent @@ -104,8 +103,7 @@ namespace OpenEngine { out << YAML::EndMap; // TagComponent } - if (entity.HasComponent()) - { + if (entity.HasComponent()) { out << YAML::Key << "TransformComponent"; out << YAML::BeginMap; // TransformComponent @@ -141,8 +139,7 @@ namespace OpenEngine { out << YAML::EndMap; // CameraComponent } - if (entity.HasComponent()) - { + if (entity.HasComponent()) { 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(); @@ -282,8 +278,7 @@ namespace OpenEngine { Entity deserializedEntity = context->CreateEntityWithUUID(uuid, name); auto transformComponent = entity["TransformComponent"]; - if (transformComponent) - { + if (transformComponent) { auto& tc = deserializedEntity.AddComponent(); tc.translation = transformComponent["Translation"].as(); tc.rotation = transformComponent["Rotation"].as(); @@ -291,8 +286,7 @@ namespace OpenEngine { } auto cameraComponent = entity["CameraComponent"]; - if (cameraComponent) - { + if (cameraComponent) { auto& cc = deserializedEntity.AddComponent(); auto camera_props = cameraComponent["Camera"]; @@ -311,15 +305,13 @@ namespace OpenEngine { } auto spriteRendererComponent = entity["SpriteRendererComponent"]; - if (spriteRendererComponent) - { + if (spriteRendererComponent) { auto& src = deserializedEntity.AddComponent(); src.color = spriteRendererComponent["Color"].as(); } auto mesh_component = entity["MeshComponent"]; - if (mesh_component) - { + if (mesh_component) { auto& mesh = deserializedEntity.AddComponent(); mesh.primitive_type = (PrimitiveType)mesh_component["MeshType"].as(); 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");