diff --git a/CMakeLists.txt b/CMakeLists.txt index 66aec6c..7609fff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,10 @@ set(output_dir ${CMAKE_BINARY_DIR}/bin) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${output_dir}) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${output_dir}) +# Use solution folders. +set_property(GLOBAL PROPERTY USE_FOLDERS ON) +set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "CMake Targets") + project(aim_tools) if (MSVC) @@ -18,4 +22,13 @@ endif(MSVC) include_directories(dep/dbmgr/include) add_subdirectory(dep/dbmgr) +add_custom_target(version ALL + COMMAND git rev-list HEAD --count > ${CMAKE_CURRENT_BINARY_DIR}/version.h_ + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/version.h_ ${CMAKE_CURRENT_BINARY_DIR}/version.h.in + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +) +set_target_properties(version PROPERTIES FOLDER Helpers) + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + add_subdirectory(src) \ No newline at end of file diff --git a/src/mod_converter/mod_converter.cpp b/src/mod_converter/mod_converter.cpp index 370e5cd..d8ead6c 100644 --- a/src/mod_converter/mod_converter.cpp +++ b/src/mod_converter/mod_converter.cpp @@ -16,11 +16,7 @@ * along with this program. If not, see . */ -#include -#include -#include -#include -#include +#include #include #include #include @@ -29,32 +25,51 @@ using namespace std; #include "model.h" -model read_model(string fn) +const int build_version = +#include +; + +std::string version() +{ + string s; + s = to_string(0) + "." + + to_string(1) + "." + + to_string(0) + "." + + to_string(build_version); + return s; +} + +void convert_model(string fn) { model m; FILE *f = fopen(fn.c_str(), "rb"); if (!f) - return m; + return; try { m.load(f); + + auto p = ftell(f); + fseek(f, 0, SEEK_END); + auto end = ftell(f); + fclose(f); + + if (p != end) + { + stringstream ss; + ss << hex << p << " != " << hex << end; + throw std::logic_error(ss.str()); + } } catch (std::exception &e) { printf("error: %s\n", fn.c_str()); printf("%s\n", e.what()); - return m; + fclose(f); + return; } - auto p = ftell(f); - fseek(f, 0, SEEK_END); - auto end = ftell(f); - if (p != ftell(f)) - { - printf("error: %s\n", fn.c_str()); - printf(" : %x != %x\n", p, end); - } - fclose(f); - return m; + + m.writeObj(fn + ".obj"); } int main(int argc, char *argv[]) @@ -67,6 +82,20 @@ int main(int argc, char *argv[]) } read_model(argv[1]); #else + convert_model("h:\\Games\\AIM\\data\\res0.pak.dir\\Data\\Models\\MOD_GL_M1_A_ATTACKER"); + convert_model("h:\\Games\\AIM\\data\\res0.pak.dir\\Data\\Models\\MOD_GL_M1_B_BASE"); + + convert_model("h:\\Games\\AIM\\data\\res0.pak.dir\\Data\\Models\\MOD_BLD_BASE1"); + convert_model("h:\\Games\\AIM\\data\\res0.pak.dir\\Data\\Models\\MOD_GL_S4_SINIGR"); + + convert_model("h:\\Games\\AIM\\data\\res0.pak.dir\\Data\\Models\\MOD_GL_FIRE"); + convert_model("h:\\Games\\AIM\\data\\res0.pak.dir\\Data\\Models\\MOD_GL_FARA"); + + convert_model("h:\\Games\\AIM\\data\\res0.pak.dir\\Data\\Models\\MOD_FX_ANTI_MATER_GUN"); + convert_model("h:\\Games\\AIM\\data\\res0.pak.dir\\Data\\Models\\MOD_UNFL_STONE01"); + convert_model("h:\\Games\\AIM\\data\\res0.pak.dir\\Data\\Models\\MOD_L1_KUST"); + convert_model("h:\\Games\\AIM\\data\\res0.pak.dir\\Data\\Models\\MOD_L6_KUST_12"); + convert_model("h:\\Games\\AIM\\data\\res0.pak.dir\\Data\\Models\\MOD_GL_M1_A_ATTACKER_DAMAGED"); #endif return 0; -} +} \ No newline at end of file diff --git a/src/mod_converter/model.cpp b/src/mod_converter/model.cpp index 10431c5..6c38bd6 100644 --- a/src/mod_converter/model.cpp +++ b/src/mod_converter/model.cpp @@ -18,7 +18,13 @@ #include "model.h" +#include #include +#include + +using namespace std; + +std::string version(); #define FREAD(var) fread(&var, 1, sizeof(var), f) #define SREAD(var) s.read(&var, sizeof(var)) @@ -41,6 +47,27 @@ void vertex::load(s_file &s, uint32_t flags) SREAD(t2); } +std::string vertex::printVertex() const +{ + string s; + s = "v " + to_string(-vX) + " " + to_string(vY) + " " + to_string(-vZ); + return s; +} + +std::string vertex::printNormal() const +{ + string s; + s = "vn " + to_string(-nX) + " " + to_string(nY) + " " + to_string(-nZ); + return s; +} + +std::string vertex::printTex() const +{ + string s; + s = "vt " + to_string(t1) + " " + to_string(1 - t2) + " " + to_string(0); + return s; +} + void fragment::load(FILE *f) { FREAD(type); @@ -189,3 +216,37 @@ void model::load(FILE *f) throw std::logic_error("extraction error: fragment #" + std::to_string(i)); } } + +void model::writeObj(std::string fn) +{ + ofstream o(fn); + o << "# " << "\n"; + o << "# A.I.M. Model Converter (ver. " << version() << ")\n"; + o << "# " << "\n"; + o << "\n"; + + if (fragments.empty()) + return; + + const auto &f = fragments[0]; + for (auto &v : f.vertices) + o << v.printVertex() << "\n"; + o << "\n"; + for (auto &v : f.vertices) + o << v.printNormal() << "\n"; + o << "\n"; + for (auto &v : f.vertices) + o << v.printTex() << "\n"; + o << "\n"; + + for (int i = 0; i <= f.n_triangles - 3; i += 3) + { + auto x = to_string(f.triangles[i] + 1); + auto y = to_string(f.triangles[i + 2] + 1); + auto z = to_string(f.triangles[i + 1] + 1); + x += "/" + x; + y += "/" + y; + z += "/" + z; + o << "f " << x << " " << y << " " << z << "\n"; + } +} diff --git a/src/mod_converter/model.h b/src/mod_converter/model.h index 48c736b..f920794 100644 --- a/src/mod_converter/model.h +++ b/src/mod_converter/model.h @@ -19,6 +19,7 @@ #pragma once #include +#include #include struct s_file @@ -74,6 +75,10 @@ struct vertex float t2; void load(s_file &s, uint32_t flags); + + std::string printVertex() const; + std::string printNormal() const; + std::string printTex() const; }; typedef uint16_t triangle; @@ -185,4 +190,5 @@ struct model std::vector fragments; void load(FILE *f); + void writeObj(std::string fn); };