diff --git a/engine/inc/loaders/3d/obj_loader/obj_loader.hpp b/engine/inc/loaders/3d/obj_loader/obj_loader.hpp index 05baf26..06ce534 100644 --- a/engine/inc/loaders/3d/obj_loader/obj_loader.hpp +++ b/engine/inc/loaders/3d/obj_loader/obj_loader.hpp @@ -18,20 +18,28 @@ namespace Tyra { -/** Class responsible for loading & parsing custom Tyra obj files */ +struct ObjLoaderAnimationOptions { + u16 count = 1; + u16 startingIndex = 1; +}; + +struct ObjLoaderOptions { + bool flipUVs = false; + float scale = 1.0F; + ObjLoaderAnimationOptions animation; +}; + +/** Class responsible for loading & parsing obj files */ class ObjLoader : public Loader { public: ObjLoader(); ~ObjLoader(); - /** Load multiple obj files (dynamic) */ - MeshBuilderData* load(const char* fullpath, const u16& count, - const float& scale, const bool& invertT); - - inline MeshBuilderData* load(const std::string& fullpath, const u16& count, - const float& scale, const bool& invertT) { - return load(fullpath.c_str(), count, scale, invertT); - } + MeshBuilderData* load(const char* fullpath); + MeshBuilderData* load(const char* fullpath, const ObjLoaderOptions& options); + MeshBuilderData* load(const std::string& fullpath); + MeshBuilderData* load(const std::string& fullpath, + const ObjLoaderOptions& options); private: void addOutputMaterialsAndFrames( diff --git a/engine/src/loaders/3d/obj_loader/obj_loader.cpp b/engine/src/loaders/3d/obj_loader/obj_loader.cpp index f59ce7d..de0e142 100644 --- a/engine/src/loaders/3d/obj_loader/obj_loader.cpp +++ b/engine/src/loaders/3d/obj_loader/obj_loader.cpp @@ -28,8 +28,21 @@ ObjLoader::ObjLoader() {} ObjLoader::~ObjLoader() {} -MeshBuilderData* ObjLoader::load(const char* fullpath, const u16& count, - const float& scale, const bool& invertY) { +MeshBuilderData* ObjLoader::load(const char* fullpath) { + return load(fullpath, ObjLoaderOptions()); +} + +MeshBuilderData* ObjLoader::load(const std::string& fullpath) { + return load(fullpath.c_str(), ObjLoaderOptions()); +} + +MeshBuilderData* ObjLoader::load(const std::string& fullpath, + const ObjLoaderOptions& options) { + return load(fullpath.c_str(), options); +} + +MeshBuilderData* ObjLoader::load(const char* fullpath, + const ObjLoaderOptions& options) { std::string path = fullpath; std::string basePath = getPathFromFilename(path); @@ -41,13 +54,20 @@ MeshBuilderData* ObjLoader::load(const char* fullpath, const u16& count, auto* result = new MeshBuilderData(); tinyobj::ObjReaderConfig readerConfig; - readerConfig.triangulate = count == 1; - readerConfig.triangulation_method = count == 1 ? "earcut" : "simple"; + readerConfig.triangulate = options.animation.count == 1; + readerConfig.triangulation_method = + options.animation.count == 1 ? "earcut" : "simple"; readerConfig.mtl_search_path = basePath; - for (u16 i = 1; i <= count; i++) { - std::string filePath = rawFilename + std::to_string(i) + "." + extension; - if (count == 1) filePath = path; + for (auto i = 1; i <= options.animation.count; i++) { + int indexStringLength = std::to_string(i).length(); + auto numbersWithLeadingZeros = + std::string(6 - std::min(6, indexStringLength), '0') + + std::to_string(i); + + std::string filePath = + rawFilename + "_" + numbersWithLeadingZeros + "." + extension; + if (options.animation.count == 1) filePath = path; tinyobj::ObjReader reader; @@ -72,13 +92,14 @@ MeshBuilderData* ObjLoader::load(const char* fullpath, const u16& count, "mtlib in obj file"); if (i == 1) { - addOutputMaterialsAndFrames(result, attrib, shapes, materials, count); + addOutputMaterialsAndFrames(result, attrib, shapes, materials, + options.animation.count); } scan(result, attrib, shapes, materials, i - 1); - importFrame(result, attrib, shapes, materials, i - 1, scale, invertY, - count); + importFrame(result, attrib, shapes, materials, i - 1, options.scale, + options.flipUVs, options.animation.count); } return result; @@ -102,9 +123,9 @@ void ObjLoader::addOutputMaterialsAndFrames( material->name = materials[i].name; - material->ambient.set(materials[i].ambient[0] * 255.0F, - materials[i].ambient[1] * 255.0F, - materials[i].ambient[2] * 255.0F, 128.0F); + material->ambient.set(materials[i].ambient[0] * 128.0F, + materials[i].ambient[1] * 128.0F, + materials[i].ambient[2] * 128.0F, 128.0F); for (size_t j = 0; j < framesCount; j++) { auto* frame = new MeshBuilderMaterialFrameData(); diff --git a/tutorials/01-hello/src/tutorial_01.cpp b/tutorials/01-hello/src/tutorial_01.cpp index 90c6b79..bca23a9 100644 --- a/tutorials/01-hello/src/tutorial_01.cpp +++ b/tutorials/01-hello/src/tutorial_01.cpp @@ -203,8 +203,10 @@ StaticMesh* getStaticMesh(Renderer* renderer) { StaticMesh* getSkybox(Renderer* renderer) { ObjLoader loader; - auto* data = - loader.load(FileUtils::fromCwd("skybox/skybox.obj"), 1, 200.0F, true); + ObjLoaderOptions options; + options.flipUVs = true; + options.scale = 200.0F; + auto* data = loader.load(FileUtils::fromCwd("skybox/skybox.obj"), options); auto* result = new StaticMesh(*data); // result->translation.translateZ(-30.0F); delete data; @@ -233,7 +235,10 @@ DynamicMesh* getWarrior(Renderer* renderer) { DynamicMesh* getCube(Renderer* renderer) { ObjLoader loader; - auto* data = loader.load(FileUtils::fromCwd("untitled.obj"), 2, 3.0F, false); + ObjLoaderOptions options; + options.animation.count = 2; + options.scale = 3.0F; + auto* data = loader.load(FileUtils::fromCwd("untitled.obj"), options); auto* result = new DynamicMesh(*data); result->translation.translateZ(-30.0F);