mirror of
https://github.com/danule222/xrbDS.git
synced 2025-06-18 14:25:33 -04:00
Implement .obj load & rendering
This commit is contained in:
parent
f7da063cfe
commit
6e0d5f92ea
2
.gitignore
vendored
2
.gitignore
vendored
@ -9,7 +9,7 @@
|
|||||||
*.slo
|
*.slo
|
||||||
*.lo
|
*.lo
|
||||||
*.o
|
*.o
|
||||||
*.obj
|
build/*.obj
|
||||||
*.elf
|
*.elf
|
||||||
*.lst
|
*.lst
|
||||||
*.nds
|
*.nds
|
||||||
|
@ -5,6 +5,7 @@ project(xrbDS)
|
|||||||
include_directories(
|
include_directories(
|
||||||
engine
|
engine
|
||||||
include/xrbds
|
include/xrbds
|
||||||
|
include/tinyobjloader
|
||||||
)
|
)
|
||||||
|
|
||||||
file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS
|
file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS
|
||||||
|
5
engine/components/component.cpp
Normal file
5
engine/components/component.cpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include "components/component.h"
|
||||||
|
|
||||||
|
PtrUnq<Component> Component::Initialize() {
|
||||||
|
return PtrUnq<Component>(new Component());
|
||||||
|
}
|
15
engine/components/mesh_filter.cpp
Normal file
15
engine/components/mesh_filter.cpp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include "components/mesh_filter.h"
|
||||||
|
|
||||||
|
#include "resources/resource.h"
|
||||||
|
#include "utils/file.h"
|
||||||
|
|
||||||
|
MeshFilter::MeshFilter(const FString &path) {
|
||||||
|
// Load the mesh from the file
|
||||||
|
auto vertices = Utils::File::ReadObjFile(path);
|
||||||
|
|
||||||
|
mesh = LoadResource<Mesh>(vertices);
|
||||||
|
}
|
||||||
|
|
||||||
|
PtrUnq<MeshFilter> MeshFilter::Initialize(const FString &path) {
|
||||||
|
return PtrUnq<MeshFilter>(new MeshFilter(path));
|
||||||
|
}
|
@ -12,6 +12,7 @@
|
|||||||
#include "graphics/renderer.h"
|
#include "graphics/renderer.h"
|
||||||
#include "scene/3d/node_3d.h"
|
#include "scene/3d/node_3d.h"
|
||||||
#include "utils/file.h"
|
#include "utils/file.h"
|
||||||
|
#include "scene/3d/mesh_instance_3d.h"
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////
|
||||||
// Main function
|
// Main function
|
||||||
@ -43,24 +44,18 @@ PtrUnq<Engine> &Engine::GetInstance() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Engine::run() {
|
void Engine::run() {
|
||||||
// Initialize the main loop
|
|
||||||
// - VBlank IRQ
|
|
||||||
irqSet(IRQ_VBLANK, Engine::VblankCallback);
|
|
||||||
VblankCallback();
|
|
||||||
|
|
||||||
// TEST ------------------------
|
// TEST ------------------------
|
||||||
|
|
||||||
PtrShr<Node3D> node = NewNode<Node3D>();
|
// Create a MeshInstance3D
|
||||||
node->getComponent<Transform>()->position = {1.0f, 2.0f, 3.0f};
|
PtrShr<MeshInstance3D> meshInstance =
|
||||||
|
NewNode<MeshInstance3D>("meshes/mococo/mococo.obj");
|
||||||
FString ahuevo = Utils::File::ReadTextFile("hola.txt");
|
|
||||||
iprintf("ahuevo: %s\n", ahuevo.c_str());
|
|
||||||
|
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
|
|
||||||
while (pmMainLoop()) {
|
while (pmMainLoop()) {
|
||||||
processInput();
|
processInput();
|
||||||
update();
|
update();
|
||||||
|
render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,9 +65,22 @@ void Engine::update() {
|
|||||||
// Update
|
// Update
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::render() { Renderer::GetInstance()->render(); }
|
void Engine::render() {
|
||||||
|
if (!ComponentManager::GetInstance())
|
||||||
|
return;
|
||||||
|
PtrUnq<Renderer> &renderer = Renderer::GetInstance();
|
||||||
|
|
||||||
void Engine::VblankCallback() { Engine::GetInstance()->render(); }
|
renderer->beginFrame();
|
||||||
|
|
||||||
|
auto view = ComponentManager::GetInstance()->view<Transform, MeshFilter>();
|
||||||
|
for (auto &[entity, transform, meshFilter] : view) {
|
||||||
|
renderer->render(*transform, *meshFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer->endFrame();
|
||||||
|
|
||||||
|
swiWaitForVBlank();
|
||||||
|
}
|
||||||
|
|
||||||
Engine::Engine() {
|
Engine::Engine() {
|
||||||
// Initialize nitroFS
|
// Initialize nitroFS
|
||||||
|
@ -1,30 +1,21 @@
|
|||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
|
|
||||||
|
#include "core/types.h"
|
||||||
|
#include "components/mesh_filter.h"
|
||||||
|
#include "components/transform.h"
|
||||||
|
#include "resources/mesh.h"
|
||||||
#include <nds.h>
|
#include <nds.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
std::unique_ptr<Renderer> Renderer::Instance;
|
PtrUnq<Renderer> Renderer::Instance;
|
||||||
|
|
||||||
std::unique_ptr<Renderer> &Renderer::GetInstance() {
|
PtrUnq<Renderer> &Renderer::GetInstance() {
|
||||||
if (!Instance)
|
if (!Instance)
|
||||||
Instance = std::unique_ptr<Renderer>(new Renderer());
|
Instance = PtrUnq<Renderer>(new Renderer());
|
||||||
|
|
||||||
return Instance;
|
return Instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::render() {
|
|
||||||
clearScreen(); // Clear the screen
|
|
||||||
beginFrame(); // Prepare for rendering
|
|
||||||
glLoadIdentity(); // Load the identity matrix
|
|
||||||
|
|
||||||
// Render scene
|
|
||||||
glTranslatef(0.f, 0.f, -4.f); // Move the camera back
|
|
||||||
glRotatef(45, 1, 1, 0); // Rotation
|
|
||||||
drawCube(1.0f); // Draw a cube
|
|
||||||
|
|
||||||
endFrame(); // Finish rendering
|
|
||||||
}
|
|
||||||
|
|
||||||
void Renderer::beginFrame() {
|
void Renderer::beginFrame() {
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
@ -34,6 +25,30 @@ void Renderer::beginFrame() {
|
|||||||
glPushMatrix(); // Save the current matrix state
|
glPushMatrix(); // Save the current matrix state
|
||||||
|
|
||||||
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_BACK);
|
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_BACK);
|
||||||
|
|
||||||
|
glLoadIdentity(); // Load the identity matrix
|
||||||
|
|
||||||
|
// Render scene
|
||||||
|
glTranslatef(0.f, 0.f, -4.f); // Move the camera back
|
||||||
|
glRotatef(45, 1, 1, 0); // Rotation
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::render(const Transform &transform,
|
||||||
|
const MeshFilter &meshFilter) {
|
||||||
|
// drawCube(1.0f); // Draw a cube
|
||||||
|
glBegin(GL_TRIANGLES);
|
||||||
|
|
||||||
|
for (const auto &shapes : meshFilter.getMesh()->getVertices()) {
|
||||||
|
for (const auto &vertex : shapes) {
|
||||||
|
glColor3f(1.0, 0.0, 0.0); // Red
|
||||||
|
glVertex3f(vertex.position.x, vertex.position.y, vertex.position.z);
|
||||||
|
glNormal3f(vertex.normal.x, vertex.normal.y, vertex.normal.z);
|
||||||
|
glTexCoord2f(vertex.texCoords.x, vertex.texCoords.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glEnd();
|
||||||
|
glPopMatrix(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::endFrame() {
|
void Renderer::endFrame() {
|
||||||
|
@ -23,8 +23,12 @@
|
|||||||
#ifndef RENDERER_H
|
#ifndef RENDERER_H
|
||||||
#define RENDERER_H
|
#define RENDERER_H
|
||||||
|
|
||||||
|
#include "core/types.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
struct Transform;
|
||||||
|
struct MeshFilter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class Renderer
|
* @class Renderer
|
||||||
* @brief A base class for rendering operations.
|
* @brief A base class for rendering operations.
|
||||||
@ -46,7 +50,14 @@ public:
|
|||||||
*
|
*
|
||||||
* @return A unique pointer to a Renderer instance.
|
* @return A unique pointer to a Renderer instance.
|
||||||
*/
|
*/
|
||||||
static std::unique_ptr<Renderer> &GetInstance();
|
static PtrUnq<Renderer> &GetInstance();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prepares the renderer for a new frame.
|
||||||
|
*
|
||||||
|
* This method is called at the beginning of the rendering process.
|
||||||
|
*/
|
||||||
|
void beginFrame();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Renders the current frame.
|
* @brief Renders the current frame.
|
||||||
@ -54,15 +65,7 @@ public:
|
|||||||
* This method handles the rendering process, including frame management
|
* This method handles the rendering process, including frame management
|
||||||
* and drawing operations.
|
* and drawing operations.
|
||||||
*/
|
*/
|
||||||
void render();
|
void render(const Transform &transform, const MeshFilter &meshFilter);
|
||||||
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* @brief Prepares the renderer for a new frame.
|
|
||||||
*
|
|
||||||
* This method is called at the beginning of the rendering process.
|
|
||||||
*/
|
|
||||||
void beginFrame();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Finalizes the rendering of the current frame.
|
* @brief Finalizes the rendering of the current frame.
|
||||||
@ -71,14 +74,6 @@ private:
|
|||||||
*/
|
*/
|
||||||
void endFrame();
|
void endFrame();
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Clears the screen to prepare for rendering.
|
|
||||||
*
|
|
||||||
* This method resets the screen to a default state, typically clearing
|
|
||||||
* any previous drawings.
|
|
||||||
*/
|
|
||||||
void clearScreen();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Draws a cube of the specified size.
|
* @brief Draws a cube of the specified size.
|
||||||
*
|
*
|
||||||
@ -86,7 +81,16 @@ private:
|
|||||||
*/
|
*/
|
||||||
void drawCube(float size);
|
void drawCube(float size);
|
||||||
|
|
||||||
static std::unique_ptr<Renderer> Instance;
|
private:
|
||||||
|
static PtrUnq<Renderer> Instance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clears the screen to prepare for rendering.
|
||||||
|
*
|
||||||
|
* This method resets the screen to a default state, typically clearing
|
||||||
|
* any previous drawings.
|
||||||
|
*/
|
||||||
|
void clearScreen();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constructor for the Renderer class.
|
* @brief Constructor for the Renderer class.
|
||||||
|
@ -1 +1,8 @@
|
|||||||
#include "resources/mesh.h"
|
#include "resources/mesh.h"
|
||||||
|
|
||||||
|
Mesh Mesh::Load(const TVector<TVector<FVertex>> &vertices) {
|
||||||
|
return std::move(Mesh(vertices));
|
||||||
|
}
|
||||||
|
|
||||||
|
Mesh::Mesh(const TVector<TVector<FVertex>> &vertices)
|
||||||
|
: Super(), vertices(vertices) {}
|
@ -1,6 +1,3 @@
|
|||||||
#include "resources/resource.h"
|
#include "resources/resource.h"
|
||||||
|
|
||||||
Resource::Resource(const FString &name, const FString &path)
|
Resource Resource::Load() { return std::move(Resource()); }
|
||||||
: name(name), path(path) {
|
|
||||||
// Constructor implementation
|
|
||||||
}
|
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "components/mesh_filter.h"
|
#include "components/mesh_filter.h"
|
||||||
|
|
||||||
MeshInstance3D::MeshInstance3D() {
|
MeshInstance3D::MeshInstance3D(const FString &path) {
|
||||||
ComponentManager::GetInstance()->addComponent<MeshFilter>(id,
|
ComponentManager::GetInstance()->addComponent<MeshFilter>(
|
||||||
MeshFilter("test"));
|
id, *MeshFilter::Initialize(path));
|
||||||
}
|
}
|
@ -1,5 +1,8 @@
|
|||||||
#include "utils/file.h"
|
#include "utils/file.h"
|
||||||
|
|
||||||
|
#define TINYOBJLOADER_IMPLEMENTATION
|
||||||
|
#include "tiny_obj_loader.h"
|
||||||
|
|
||||||
namespace Utils::File {
|
namespace Utils::File {
|
||||||
|
|
||||||
FString AssetPath(const FString &path) { return "nitro:/" + path; }
|
FString AssetPath(const FString &path) { return "nitro:/" + path; }
|
||||||
@ -27,4 +30,78 @@ FString ReadTextFile(const FString &path) {
|
|||||||
return std::move(result);
|
return std::move(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TVector<TVector<FVertex>> ReadObjFile(const FString &path) {
|
||||||
|
tinyobj::attrib_t attrib;
|
||||||
|
TVector<tinyobj::shape_t> shapes;
|
||||||
|
TVector<tinyobj::material_t> materials;
|
||||||
|
FString err;
|
||||||
|
|
||||||
|
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &err,
|
||||||
|
AssetPath(path).c_str(),
|
||||||
|
AssetPath(path + "/..").c_str(), true);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
iprintf("Cargado correctamente\n");
|
||||||
|
else
|
||||||
|
iprintf("Error al cargar el archivo: %s\n", err.c_str());
|
||||||
|
|
||||||
|
iprintf("Numero de materiales: %d\n", materials.size());
|
||||||
|
|
||||||
|
TVector<TVector<FVertex>> vertices;
|
||||||
|
|
||||||
|
// Loop over shapes
|
||||||
|
for (size_t s = 0; s < shapes.size(); s++) {
|
||||||
|
vertices.push_back({});
|
||||||
|
// Loop over faces(polygon)
|
||||||
|
size_t index_offset = 0;
|
||||||
|
for (size_t f = 0; f < shapes[s].mesh.num_face_vertices.size(); f++) {
|
||||||
|
size_t fv = size_t(shapes[s].mesh.num_face_vertices[f]);
|
||||||
|
|
||||||
|
// Loop over vertices in the face.
|
||||||
|
for (size_t v = 0; v < fv; v++) {
|
||||||
|
// access to vertex
|
||||||
|
tinyobj::index_t idx = shapes[s].mesh.indices[index_offset + v];
|
||||||
|
|
||||||
|
tinyobj::real_t vx = attrib.vertices[3 * size_t(idx.vertex_index) + 0];
|
||||||
|
tinyobj::real_t vy = attrib.vertices[3 * size_t(idx.vertex_index) + 1];
|
||||||
|
tinyobj::real_t vz = attrib.vertices[3 * size_t(idx.vertex_index) + 2];
|
||||||
|
|
||||||
|
FVector3 positions(vx, vy, vz);
|
||||||
|
|
||||||
|
// Check if `normal_index` is zero or positive. negative = no normal
|
||||||
|
// data
|
||||||
|
FVector3 normals(0, 0, 0);
|
||||||
|
if (idx.normal_index >= 0) {
|
||||||
|
tinyobj::real_t nx = attrib.normals[3 * size_t(idx.normal_index) + 0];
|
||||||
|
tinyobj::real_t ny = attrib.normals[3 * size_t(idx.normal_index) + 1];
|
||||||
|
tinyobj::real_t nz = attrib.normals[3 * size_t(idx.normal_index) + 2];
|
||||||
|
|
||||||
|
normals = FVector3(nx, ny, nz);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if `texcoord_index` is zero or positive. negative = no texcoord
|
||||||
|
// data
|
||||||
|
FVector2 texCoords(0, 0);
|
||||||
|
if (idx.texcoord_index >= 0) {
|
||||||
|
tinyobj::real_t tx =
|
||||||
|
attrib.texcoords[2 * size_t(idx.texcoord_index) + 0];
|
||||||
|
tinyobj::real_t ty =
|
||||||
|
attrib.texcoords[2 * size_t(idx.texcoord_index) + 1];
|
||||||
|
|
||||||
|
texCoords = FVector2(tx, ty);
|
||||||
|
}
|
||||||
|
|
||||||
|
vertices[s].push_back(FVertex(positions, normals, texCoords));
|
||||||
|
}
|
||||||
|
|
||||||
|
index_offset += fv;
|
||||||
|
|
||||||
|
// per-face material
|
||||||
|
// shapes[s].mesh.material_ids[f];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::move(vertices);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Utils::File
|
} // namespace Utils::File
|
||||||
|
2029
include/tinyobjloader/tiny_obj_loader.h
Normal file
2029
include/tinyobjloader/tiny_obj_loader.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,11 @@
|
|||||||
#ifndef COMPONENT_H
|
#ifndef COMPONENT_H
|
||||||
#define COMPONENT_H
|
#define COMPONENT_H
|
||||||
|
|
||||||
|
#include "core/types.h"
|
||||||
|
|
||||||
struct Component {
|
struct Component {
|
||||||
virtual ~Component() = default;
|
public:
|
||||||
|
static PtrUnq<Component> Initialize();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // COMPONENT_H
|
#endif // COMPONENT_H
|
@ -1,7 +0,0 @@
|
|||||||
#include "mesh_filter.h"
|
|
||||||
|
|
||||||
#include "resources/resource.h"
|
|
||||||
|
|
||||||
MeshFilter::MeshFilter(const FString &name) : meshName(name) {
|
|
||||||
mesh = LoadResource<Mesh>(name);
|
|
||||||
}
|
|
@ -8,11 +8,14 @@ class Mesh;
|
|||||||
|
|
||||||
struct MeshFilter : public Component {
|
struct MeshFilter : public Component {
|
||||||
public:
|
public:
|
||||||
MeshFilter(const FString &name);
|
static PtrUnq<MeshFilter> Initialize(const FString &path);
|
||||||
|
|
||||||
|
PtrShr<Mesh> getMesh() const { return mesh; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FString meshName;
|
|
||||||
PtrShr<Mesh> mesh;
|
PtrShr<Mesh> mesh;
|
||||||
|
|
||||||
|
MeshFilter(const FString &path);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MESH_FILTER_H
|
#endif // MESH_FILTER_H
|
@ -6,32 +6,28 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
struct Vertex {
|
struct FVertex {
|
||||||
FVector3 position;
|
FVector3 position;
|
||||||
FVector3 normal;
|
FVector3 normal;
|
||||||
FVector2 texCoords;
|
FVector2 texCoords;
|
||||||
|
|
||||||
Vertex(const FVector3 &pos, const FVector3 &norm, const FVector2 &tex)
|
FVertex(const FVector3 &pos, const FVector3 &norm, const FVector2 &tex)
|
||||||
: position(pos), normal(norm), texCoords(tex) {}
|
: position(pos), normal(norm), texCoords(tex) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Mesh : public Resource {
|
class Mesh : public Resource {
|
||||||
|
using Super = Resource;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static PtrShr<Mesh> Load(FString path);
|
static Mesh Load(const TVector<TVector<FVertex>> &vertices);
|
||||||
|
|
||||||
const TVector<Vertex> &getVertices() const;
|
TVector<TVector<FVertex>> getVertices() const { return vertices; }
|
||||||
const TVector<unsigned int> &getIndices() const;
|
|
||||||
|
|
||||||
void setVertices(const TVector<Vertex> &vertices);
|
|
||||||
void setIndices(const TVector<unsigned int> &indices);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TVector<Vertex> m_vertices;
|
TVector<TVector<FVertex>> vertices;
|
||||||
TVector<unsigned int> m_indices;
|
|
||||||
|
|
||||||
Mesh() = delete;
|
Mesh() = default;
|
||||||
Mesh(const Mesh &) = delete;
|
Mesh(const TVector<TVector<FVertex>> &vertices);
|
||||||
Mesh(const TVector<Vertex> &vertices, const TVector<unsigned int> &indices);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // XRBDS_RESOURCES_MESH_H
|
#endif // XRBDS_RESOURCES_MESH_H
|
@ -4,19 +4,80 @@
|
|||||||
#include "core/types.h"
|
#include "core/types.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
template <typename T, typename... Args> PtrShr<T> LoadResource(Args &&...args) {
|
/**
|
||||||
auto ptr = std::make_shared<T>(std::forward<Args>(args)...);
|
* @struct FResourceData
|
||||||
|
* @brief Represents resource data with a name and a file path.
|
||||||
|
*
|
||||||
|
* This structure is used to store information about a resource, including
|
||||||
|
* its name and the path to its location.
|
||||||
|
*
|
||||||
|
* @var FResourceData::name
|
||||||
|
* The name of the resource.
|
||||||
|
*
|
||||||
|
* @var FResourceData::path
|
||||||
|
* The file path to the resource.
|
||||||
|
*
|
||||||
|
* @param name The name of the resource.
|
||||||
|
* @param path The file path to the resource.
|
||||||
|
*/
|
||||||
|
struct FResourceData {
|
||||||
|
/**
|
||||||
|
* @brief Constructs an FResourceData object with the specified name and path.
|
||||||
|
*
|
||||||
|
* @param name The name of the resource.
|
||||||
|
* @param path The file path of the resource.
|
||||||
|
*/
|
||||||
|
FResourceData(const FString &name, const FString &path)
|
||||||
|
: name(name), path(path) {}
|
||||||
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
class Resource {
|
|
||||||
public:
|
|
||||||
Resource(const FString &name, const FString &path);
|
|
||||||
|
|
||||||
private:
|
|
||||||
FString name;
|
FString name;
|
||||||
FString path;
|
FString path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class Resource
|
||||||
|
* @brief Represents a resource that encapsulates data of type FResourceData.
|
||||||
|
*
|
||||||
|
* This class is used to manage and store resource data. It provides a
|
||||||
|
* constructor to initialize the resource with the given data.
|
||||||
|
*
|
||||||
|
* @note The class currently only stores the data and does not provide any
|
||||||
|
* additional functionality or accessors.
|
||||||
|
*/
|
||||||
|
class Resource {
|
||||||
|
public:
|
||||||
|
static Resource Load();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Resource() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Loads a resource by creating a shared pointer to an instance of the
|
||||||
|
* specified type.
|
||||||
|
*
|
||||||
|
* @tparam T The type of the resource to be loaded. Must be constructible
|
||||||
|
with
|
||||||
|
* the provided arguments.
|
||||||
|
* @tparam Args The types of the arguments to be forwarded to the constructor
|
||||||
|
of
|
||||||
|
* T.
|
||||||
|
* @param args The arguments to be forwarded to the constructor of T.
|
||||||
|
* @return PtrShr<T> A shared pointer to the newly created instance of T.
|
||||||
|
*
|
||||||
|
* @note This function uses perfect forwarding to pass the arguments to the
|
||||||
|
* constructor of T. Ensure that the type T is compatible with the provided
|
||||||
|
* arguments.
|
||||||
|
*/
|
||||||
|
template <typename T, typename... Args> PtrShr<T> LoadResource(Args &&...args) {
|
||||||
|
if constexpr (!std::is_base_of<Resource, T>::value) {
|
||||||
|
iprintf("Error: Type T must be derived from Resource.\n");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ptr = std::make_shared<T>(T::Load(std::forward<Args>(args)...));
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // RESOURCE_H
|
#endif // RESOURCE_H
|
@ -9,7 +9,7 @@ public:
|
|||||||
using Super = Node3D;
|
using Super = Node3D;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MeshInstance3D();
|
MeshInstance3D(const FString &path);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // XRBDS_SCENE_3D_MESH_INSTANCE_H
|
#endif // XRBDS_SCENE_3D_MESH_INSTANCE_H
|
@ -2,11 +2,32 @@
|
|||||||
#define XRBDS_UTILS_FILE_H
|
#define XRBDS_UTILS_FILE_H
|
||||||
|
|
||||||
#include "core/types.h"
|
#include "core/types.h"
|
||||||
|
#include "resources/mesh.h"
|
||||||
|
|
||||||
namespace Utils::File {
|
namespace Utils::File {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads the contents of a text file and returns it as a string.
|
||||||
|
*
|
||||||
|
* @param path The file path to the text file to be read.
|
||||||
|
* @return FString The contents of the file as a string.
|
||||||
|
* @throws std::runtime_error If the file cannot be opened or read.
|
||||||
|
*/
|
||||||
FString ReadTextFile(const FString &path);
|
FString ReadTextFile(const FString &path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads a Wavefront OBJ file and parses its contents into a nested
|
||||||
|
* vector of vertices.
|
||||||
|
*
|
||||||
|
* @param path The file path to the OBJ file as an FString.
|
||||||
|
* @return A TVector of TVector of FVertex, where each inner vector represents a
|
||||||
|
* group of vertices.
|
||||||
|
*
|
||||||
|
* @note Ensure the file at the specified path exists and is in a valid OBJ
|
||||||
|
* format.
|
||||||
|
*/
|
||||||
|
TVector<TVector<FVertex>> ReadObjFile(const FString &path);
|
||||||
|
|
||||||
} // namespace Utils::File
|
} // namespace Utils::File
|
||||||
|
|
||||||
#endif // XRBDS_UTILS_FILE_H
|
#endif // XRBDS_UTILS_FILE_H
|
46
samples/hello_world/assets/meshes/mococo/cube.obj
Normal file
46
samples/hello_world/assets/meshes/mococo/cube.obj
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# Blender v2.76 (sub 0) OBJ File: ''
|
||||||
|
# www.blender.org
|
||||||
|
mtllib cube.mtl
|
||||||
|
o Cube
|
||||||
|
v 1.000000 -1.000000 -1.000000
|
||||||
|
v 1.000000 -1.000000 1.000000
|
||||||
|
v -1.000000 -1.000000 1.000000
|
||||||
|
v -1.000000 -1.000000 -1.000000
|
||||||
|
v 1.000000 1.000000 -0.999999
|
||||||
|
v 0.999999 1.000000 1.000001
|
||||||
|
v -1.000000 1.000000 1.000000
|
||||||
|
v -1.000000 1.000000 -1.000000
|
||||||
|
vt 1.000000 0.333333
|
||||||
|
vt 1.000000 0.666667
|
||||||
|
vt 0.666667 0.666667
|
||||||
|
vt 0.666667 0.333333
|
||||||
|
vt 0.666667 0.000000
|
||||||
|
vt 0.000000 0.333333
|
||||||
|
vt 0.000000 0.000000
|
||||||
|
vt 0.333333 0.000000
|
||||||
|
vt 0.333333 1.000000
|
||||||
|
vt 0.000000 1.000000
|
||||||
|
vt 0.000000 0.666667
|
||||||
|
vt 0.333333 0.333333
|
||||||
|
vt 0.333333 0.666667
|
||||||
|
vt 1.000000 0.000000
|
||||||
|
vn 0.000000 -1.000000 0.000000
|
||||||
|
vn 0.000000 1.000000 0.000000
|
||||||
|
vn 1.000000 0.000000 0.000000
|
||||||
|
vn -0.000000 0.000000 1.000000
|
||||||
|
vn -1.000000 -0.000000 -0.000000
|
||||||
|
vn 0.000000 0.000000 -1.000000
|
||||||
|
usemtl Material
|
||||||
|
s off
|
||||||
|
f 2/1/1 3/2/1 4/3/1
|
||||||
|
f 8/1/2 7/4/2 6/5/2
|
||||||
|
f 5/6/3 6/7/3 2/8/3
|
||||||
|
f 6/8/4 7/5/4 3/4/4
|
||||||
|
f 3/9/5 7/10/5 8/11/5
|
||||||
|
f 1/12/6 4/13/6 8/11/6
|
||||||
|
f 1/4/1 2/1/1 4/3/1
|
||||||
|
f 5/14/2 8/1/2 6/5/2
|
||||||
|
f 1/12/3 5/6/3 2/8/3
|
||||||
|
f 2/12/4 6/8/4 3/4/4
|
||||||
|
f 4/13/5 3/9/5 8/11/5
|
||||||
|
f 5/6/6 1/12/6 8/11/6
|
12
samples/hello_world/assets/meshes/mococo/mococo.mtl
Normal file
12
samples/hello_world/assets/meshes/mococo/mococo.mtl
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# Blender 4.4.1 MTL File: 'mococo.blend'
|
||||||
|
# www.blender.org
|
||||||
|
|
||||||
|
newmtl mococo_mat
|
||||||
|
Ns 0.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.450000
|
||||||
|
illum 1
|
||||||
|
map_Kd mococotexture_face1.png
|
||||||
|
map_d mococotexture_face1.png
|
1890
samples/hello_world/assets/meshes/mococo/mococo.obj
Normal file
1890
samples/hello_world/assets/meshes/mococo/mococo.obj
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
Loading…
Reference in New Issue
Block a user