From 0efa83b097633a53c508ddd6c03bccce751137ae Mon Sep 17 00:00:00 2001 From: lzwdgc Date: Fri, 28 Jul 2017 04:40:27 +0300 Subject: [PATCH] Switch tm converter from tga to bmp as ue4 hardly understands transparent tga. Or they just was incorrectly converted. --- src/common/mat.h | 66 +++++++++++++++++++++++++++---- src/mod_converter/fbx.cpp | 6 +-- src/mod_converter/model.cpp | 11 +++--- src/mod_converter/model.h | 1 + src/tm_converter/tm_converter.cpp | 28 ++++++------- src/unpaker/pak.cpp | 8 +++- 6 files changed, 88 insertions(+), 32 deletions(-) diff --git a/src/common/mat.h b/src/common/mat.h index b6e9aab..01757a6 100644 --- a/src/common/mat.h +++ b/src/common/mat.h @@ -39,6 +39,15 @@ public: data.resize(width * height, T()); } + T &operator()(int i) + { + return data[i]; + } + const T &operator()(int i) const + { + return (*const_cast(this))(i); + } + T &operator()(int row, int col) { assert(!(row >= height || col >= width || row < 0 || col < 0)); @@ -62,28 +71,63 @@ public: const std::vector &getData() const { return data; } std::vector &getData() { return data; } + // left/right + mat mirror() + { + int cols = width; + int rows = height; + mat m(width, height); + for (int row = 0; row < rows; row++) + { + for (int col = 0; col < cols; col++) + { + auto &o = operator()(row * cols + col); + auto &n = m(row * cols + (cols - 1 - col)); + n = o; + } + } + return m; + } + + // up/down + mat flip() + { + int cols = width; + int rows = height; + mat m(width, height); + for (int row = 0; row < rows; row++) + { + for (int col = 0; col < cols; col++) + { + auto &o = operator()(row * cols + col); + auto &n = m((rows - 1 - row) * cols + col); + n = o; + } + } + return m; + } + private: std::vector data; int width; int height; }; -template -void write_mat_bmp(const std::string &filename, const mat &m) +inline void write_mat_bmp(const std::string &filename, int width, int height, int bits, const uint8_t *b, size_t s) { FILE *f = fopen(filename.c_str(), "wb"); if (f == nullptr) return; BITMAPFILEHEADER h = { 0 }; h.bfType = 0x4D42; - h.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + m.size() * sizeof(T); + h.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + s; h.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); BITMAPINFOHEADER i = { 0 }; i.biSize = sizeof(i); - i.biWidth = m.getWidth(); - i.biHeight = m.getHeight(); + i.biWidth = width; + i.biHeight = height; i.biPlanes = 1; - i.biBitCount = sizeof(T) * 8; + i.biBitCount = bits; i.biCompression = 0; i.biSizeImage = 0; i.biXPelsPerMeter = 0; @@ -92,12 +136,18 @@ void write_mat_bmp(const std::string &filename, const mat &m) i.biClrImportant = 0; fwrite(&h, sizeof(BITMAPFILEHEADER), 1, f); fwrite(&i, sizeof(BITMAPINFOHEADER), 1, f); - fwrite(&m(0, 0), m.size() * sizeof(T), 1, f); + fwrite(b, s, 1, f); fclose(f); } template -void write_mat_tga(const std::string &filename, const mat &m) +inline void write_mat_bmp(const std::string &filename, const mat &m) +{ + write_mat_bmp(filename, m.getWidth(), m.getHeight(), sizeof(T) * CHAR_BIT, (const uint8_t *)&m(0, 0), m.size() * sizeof(T)); +} + +template +inline void write_mat_tga(const std::string &filename, const mat &m) { FILE *f = fopen(filename.c_str(), "wb"); if (f == nullptr) diff --git a/src/mod_converter/fbx.cpp b/src/mod_converter/fbx.cpp index 4520608..868780c 100644 --- a/src/mod_converter/fbx.cpp +++ b/src/mod_converter/fbx.cpp @@ -344,7 +344,7 @@ bool CreateScene(model &model, const std::string &name, FbxManager* pSdkManager, // Set texture properties. lTexture = FbxFileTexture::Create(pScene, "Diffuse Texture"); - lTexture->SetFileName((b.tex_mask + ".TM.tga").c_str()); // Resource file is in current directory. + lTexture->SetFileName((b.tex_mask + texture_extension).c_str()); // Resource file is in current directory. lTexture->SetTextureUse(FbxTexture::eStandard); lTexture->SetMappingType(FbxTexture::eUV); lTexture->SetMaterialUse(FbxFileTexture::eModelMaterial); @@ -354,7 +354,7 @@ bool CreateScene(model &model, const std::string &name, FbxManager* pSdkManager, // Set texture properties. lTexture = FbxFileTexture::Create(pScene, "Ambient Texture"); - lTexture->SetFileName((b.tex_mask + ".TM.tga").c_str()); // Resource file is in current directory. + lTexture->SetFileName((b.tex_mask + texture_extension).c_str()); // Resource file is in current directory. lTexture->SetTextureUse(FbxTexture::eStandard); lTexture->SetMappingType(FbxTexture::eUV); lTexture->SetMaterialUse(FbxFileTexture::eModelMaterial); @@ -364,7 +364,7 @@ bool CreateScene(model &model, const std::string &name, FbxManager* pSdkManager, // Set texture properties. lTexture = FbxFileTexture::Create(pScene, "Specular Texture"); - lTexture->SetFileName((b.tex_spec + ".TM.tga").c_str()); // Resource file is in current directory. + lTexture->SetFileName((b.tex_spec + 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/model.cpp b/src/mod_converter/model.cpp index 5c4c61f..1f0d909 100644 --- a/src/mod_converter/model.cpp +++ b/src/mod_converter/model.cpp @@ -37,6 +37,7 @@ using namespace std; const float scale_mult = 30.0f; +const std::string texture_extension = ".TM.bmp"; const map transliteration = { @@ -290,8 +291,6 @@ void animation::segment::loadData(const buffer &b) std::string block::printMtl() const { - static const string ext = ".TM.tga"; - string s; s += "newmtl " + name + "\n"; s += "\n"; @@ -303,13 +302,13 @@ std::string block::printMtl() const // illum s += "\n"; if (string(tex_mask) != "_DEFAULT_") - s += "map_Ka " + string(tex_mask) + ext + "\n"; + s += "map_Ka " + string(tex_mask) + texture_extension + "\n"; if (string(tex_mask) != "_DEFAULT_") - s += "map_Kd " + string(tex_mask) + ext + "\n"; + s += "map_Kd " + string(tex_mask) + texture_extension + "\n"; if (string(tex_spec) != "_DEFAULT_") - s += "map_Ks " + string(tex_spec) + ext + "\n"; + s += "map_Ks " + string(tex_spec) + texture_extension + "\n"; if (string(tex_spec) != "_DEFAULT_") - s += "map_Ns " + string(tex_spec) + ext + "\n"; + s += "map_Ns " + string(tex_spec) + texture_extension + "\n"; s += "\n"; return s; } diff --git a/src/mod_converter/model.h b/src/mod_converter/model.h index b456ce3..e146bca 100644 --- a/src/mod_converter/model.h +++ b/src/mod_converter/model.h @@ -23,6 +23,7 @@ #include extern const float scale_mult; +extern const std::string texture_extension; class buffer; diff --git a/src/tm_converter/tm_converter.cpp b/src/tm_converter/tm_converter.cpp index 4c25bb0..6a0e117 100644 --- a/src/tm_converter/tm_converter.cpp +++ b/src/tm_converter/tm_converter.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -29,7 +30,7 @@ using namespace std; -void convert_simple(buffer &dst, buffer &src, int width, int height) +void convert_simple(buffer &dst, const buffer &src, int width, int height) { int size = width * height * 2; for (int i = 0; i < size; i++) @@ -43,7 +44,7 @@ void convert_simple(buffer &dst, buffer &src, int width, int height) } } -void tm2tga(string fn) +void convert(string fn) { int width, height; int dxt5_flag = 0; @@ -55,27 +56,26 @@ void tm2tga(string fn) src.read(&dxt5_flag, 1); src.seek(0x4C); + fn = fn + ".bmp"; + mat m(width, height); if (dxt5_flag) { dxt5 d; d.width = width; d.height = height; d.load_blocks(src); - write_mat_tga(fn + ".tga", d.unpack_tm()); + m = d.unpack_tm(); + write_mat_bmp(fn, m); } else { - buffer dst; - tga t; - t.width = width; - t.height = height; - t.write(dst); - - convert_simple(dst, src, width, height); - transform(fn.begin(), fn.end(), fn.begin(), ::tolower); - fn = fn.substr(0, fn.rfind(".tm")) + ".tga"; - writeFile(fn, dst.buf()); + buffer dst2; + convert_simple(dst2, src, width, height); + dst2.reset(); + memcpy(&m(0,0), dst2.getPtr(), dst2.size()); + m = m.flip(); // flip tga (normal) to bmp (inverse) } + write_mat_bmp(fn, m); } int main(int argc, char *argv[]) @@ -86,7 +86,7 @@ try printf("Usage: %s file.tm\n", argv[0]); return 1; } - tm2tga(argv[1]); + convert(argv[1]); return 0; } catch (std::exception &e) diff --git a/src/unpaker/pak.cpp b/src/unpaker/pak.cpp index ef452ae..5e3c055 100644 --- a/src/unpaker/pak.cpp +++ b/src/unpaker/pak.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include "decode.h" @@ -104,7 +105,12 @@ void segment::load_segment() auto f = file; fseek(f, offset, SEEK_SET); - assert(flags != 0); + if (flags == 0) + { + std::cerr << "Something is wrong. Maybe you trying to open aim2 files?\n"; + std::cerr << "They can be opened with SDK extractor.\n"; + throw std::runtime_error("error"); + } FREAD(size1); size2 = size1;