diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7f590f4..23818ce 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -57,6 +57,7 @@ if (DEFINED FBX_SDK_ROOT) common model #pvt.cppan.demo.eigen + pvt.cppan.demo.taywee.args debug "${FBX_SDK_ROOT}/lib/vs2015/x86/debug/libfbxsdk-md.lib" optimized "${FBX_SDK_ROOT}/lib/vs2015/x86/release/libfbxsdk-md.lib" ) diff --git a/src/common/types.h b/src/common/types.h index ba818be..f063422 100644 --- a/src/common/types.h +++ b/src/common/types.h @@ -26,18 +26,22 @@ enum class GameType { Aim1, - Aim2 + Aim2, + AimR, }; inline GameType gameType = GameType::Aim2; +template struct vector3 { - float x = 0; - float y = 0; - float z = 0; + T x; + T y; + T z; }; +using vector3f = vector3; + struct vector4 { float x = 0; @@ -65,7 +69,7 @@ struct weather { struct atmospheric_effects { - vector3 wind; + vector3f wind; WeatherType weatherType; float strength; float duration; @@ -83,8 +87,8 @@ struct weather std::string cloud_layer2; float cloud_layer1_speed; float cloud_layer2_speed; - vector3 cloud_layer1_direction; - vector3 cloud_layer2_direction; + vector3f cloud_layer1_direction; + vector3f cloud_layer2_direction; std::string sun; color general_color; color sun_color; diff --git a/src/mmp_extractor/mmp.h b/src/mmp_extractor/mmp.h index 47f0bf6..fe34280 100644 --- a/src/mmp_extractor/mmp.h +++ b/src/mmp_extractor/mmp.h @@ -86,8 +86,8 @@ struct segment struct description { - vector3 min; - vector3 max; + vector3f min; + vector3f max; float unk0[5]; uint32_t unk1[7]; }; diff --git a/src/mod_converter/fbx.cpp b/src/mod_converter/fbx.cpp index 2d28554..6d6ef39 100644 --- a/src/mod_converter/fbx.cpp +++ b/src/mod_converter/fbx.cpp @@ -407,7 +407,7 @@ bool CreateScene(model &model, const std::string &name, FbxManager* pSdkManager, // Set texture properties. lTexture = FbxFileTexture::Create(pScene, "Diffuse Texture"); - lTexture->SetFileName((b.h.tex_mask + texture_extension).c_str()); // Resource file is in current directory. + lTexture->SetFileName((b.h.mask.name + texture_extension).c_str()); // Resource file is in current directory. lTexture->SetTextureUse(FbxTexture::eStandard); lTexture->SetMappingType(FbxTexture::eUV); lTexture->SetMaterialUse(FbxFileTexture::eModelMaterial); @@ -417,7 +417,7 @@ bool CreateScene(model &model, const std::string &name, FbxManager* pSdkManager, // Set texture properties. lTexture = FbxFileTexture::Create(pScene, "Ambient Texture"); - lTexture->SetFileName((b.h.tex_mask + texture_extension).c_str()); // Resource file is in current directory. + lTexture->SetFileName((b.h.mask.name + texture_extension).c_str()); // Resource file is in current directory. lTexture->SetTextureUse(FbxTexture::eStandard); lTexture->SetMappingType(FbxTexture::eUV); lTexture->SetMaterialUse(FbxFileTexture::eModelMaterial); @@ -427,7 +427,7 @@ bool CreateScene(model &model, const std::string &name, FbxManager* pSdkManager, // Set texture properties. lTexture = FbxFileTexture::Create(pScene, "Specular Texture"); - lTexture->SetFileName((b.h.tex_spec + texture_extension).c_str()); // Resource file is in current directory. + lTexture->SetFileName((b.h.spec.name + texture_extension).c_str()); // Resource file is in current directory. lTexture->SetTextureUse(FbxTexture::eStandard); lTexture->SetMappingType(FbxTexture::eUV); lTexture->SetMaterialUse(FbxFileTexture::eModelMaterial); diff --git a/src/mod_converter/mod_converter.cpp b/src/mod_converter/mod_converter.cpp index 36f5ed0..0a137b8 100644 --- a/src/mod_converter/mod_converter.cpp +++ b/src/mod_converter/mod_converter.cpp @@ -16,6 +16,13 @@ * along with this program. If not, see . */ +#include +#include "fbx.h" +#include "model.h" + +#include +#include + #include #include #include @@ -24,12 +31,6 @@ #include #include -#include -#include "model.h" -#include "fbx.h" - -#include - using namespace std; // options @@ -61,11 +62,18 @@ void convert_model(const path &fn) int main(int argc, char *argv[]) try { - if (argc < 2 || !parse_cmd(argc, argv)) - { - printf("Usage: %s [OPTIONS] {model_file,model_dir}\n", argv[0]); - return 1; - } + args::ArgumentParser parser("mmo extractor"); + args::HelpFlag help(parser, "help", "Display this help menu", { 'h', "help" }); + args::Flag mr(parser, "mr", "AIM Racing MOD file", { "mr" }); + args::Positional file_path(parser, "file or directory", "MOD_ file or directory with MOD_ files"); + parser.Prog(argv[0]); + + parser.ParseCLI(argc, argv); + + if (mr) + gameType = GameType::AimR; + + p = file_path.Get(); if (fs::is_regular_file(p)) convert_model(p); else if (fs::is_directory(p)) diff --git a/src/model/model.cpp b/src/model/model.cpp index 09eb9b0..2e291d3 100644 --- a/src/model/model.cpp +++ b/src/model/model.cpp @@ -259,14 +259,14 @@ std::string block::printMtl() const // d 1.0 // illum s += "\n"; - if (h.tex_mask != "_DEFAULT_") - s += "map_Ka " + h.tex_mask + texture_extension + "\n"; - if (h.tex_mask != "_DEFAULT_") - s += "map_Kd " + h.tex_mask + texture_extension + "\n"; - if (h.tex_spec != "_DEFAULT_") - s += "map_Ks " + h.tex_spec + texture_extension + "\n"; - if (h.tex_spec != "_DEFAULT_") - s += "map_Ns " + h.tex_spec + texture_extension + "\n"; + if (h.mask.name != "_DEFAULT_") + s += "map_Ka " + h.mask.name + texture_extension + "\n"; + if (h.mask.name != "_DEFAULT_") + s += "map_Kd " + h.mask.name + texture_extension + "\n"; + if (h.spec.name != "_DEFAULT_") + s += "map_Ks " + h.spec.name + texture_extension + "\n"; + if (h.spec.name != "_DEFAULT_") + s += "map_Ns " + h.spec.name + texture_extension + "\n"; s += "\n"; return s; } @@ -306,19 +306,36 @@ std::string block::printObj(int group_offset, bool rotate_x_90) const return s; } +void block::header::texture::load(const buffer &b) +{ + READ_STRING(b, name); + if (gameType == GameType::AimR) + READ(b, number); +} + void block::header::load(const buffer &b) { READ(b, type); READ_STRING(b, name); name = translate(name); - READ_STRING(b, tex_mask); - READ_STRING(b, tex_spec); - READ_STRING(b, tex3); - READ_STRING(b, tex4); + mask.load(b); + spec.load(b); + tex3.load(b); + tex4.load(b); READ(b, all_lods); - READ(b, unk2); + if (gameType == GameType::AimR) + { + READ(b, unk2[0]); + READ(b, unk2[1]); + READ(b, size); + } + else + READ(b, unk2); READ(b, unk3); - READ(b, size); + if (gameType != GameType::AimR) + READ(b, size); + else + READ(b, unk2[2]); // unk4_0 - related to unk4 - some vector3f READ(b, unk4); } diff --git a/src/model/model.h b/src/model/model.h index ec1fa62..6711336 100644 --- a/src/model/model.h +++ b/src/model/model.h @@ -18,6 +18,8 @@ #pragma once +#include "types.h" + #include #include #include @@ -75,14 +77,6 @@ enum class MaterialType : uint32_t Fire2 = 0x3D, }; -template -struct vector3 -{ - T x; - T y; - T z; -}; - template struct aim_vector3 : vector3 { @@ -199,12 +193,20 @@ struct block { struct header { + struct texture + { + std::string name; + uint32_t number; // AimR + + void load(const buffer &b); + }; + BlockType type; std::string name; - std::string tex_mask; - std::string tex_spec; - std::string tex3; - std::string tex4; + texture mask; + texture spec; + texture tex3; + texture tex4; union // LODs { struct @@ -224,7 +226,7 @@ struct block // unk uint32_t unk2[3]; uint32_t unk3; - uint32_t unk4[10]; + float unk4[10]; void load(const buffer &b); }; diff --git a/src/save_loader/save.h b/src/save_loader/save.h index 0d20b35..0c75594 100644 --- a/src/save_loader/save.h +++ b/src/save_loader/save.h @@ -124,7 +124,7 @@ struct header_segment : public segment { uint32_t unk1[3]; std::string save_name; - vector3 position; + vector3f position; std::string mmp_file; std::string location_name; Common camera; @@ -710,7 +710,7 @@ struct groups_segment : public segment struct group { - vector3 pos; + vector3f pos; std::string org; std::string base; float unk0[4];