mirror of
https://github.com/aimrebirth/tools.git
synced 2026-04-15 01:43:25 +00:00
Add more scripts.
This commit is contained in:
parent
d76c25bd7a
commit
a5989276a7
14 changed files with 277 additions and 111 deletions
|
|
@ -1 +1 @@
|
||||||
Subproject commit 2d884b843a057c25159833226a4e2c73443d91eb
|
Subproject commit a2768a05d85958cb52de967a1ef2ea20d9bba309
|
||||||
|
|
@ -40,7 +40,10 @@ std::vector<uint8_t> readFile(const std::string &fn)
|
||||||
{
|
{
|
||||||
FILE *f = fopen(fn.c_str(), "rb");
|
FILE *f = fopen(fn.c_str(), "rb");
|
||||||
if (!f)
|
if (!f)
|
||||||
|
{
|
||||||
|
printf("Cannot open file %s\n", fn.c_str());
|
||||||
throw std::runtime_error("Cannot open file " + fn);
|
throw std::runtime_error("Cannot open file " + fn);
|
||||||
|
}
|
||||||
fseek(f, 0, SEEK_END);
|
fseek(f, 0, SEEK_END);
|
||||||
auto sz = ftell(f);
|
auto sz = ftell(f);
|
||||||
fseek(f, 0, SEEK_SET);
|
fseek(f, 0, SEEK_SET);
|
||||||
|
|
@ -64,121 +67,141 @@ buffer::buffer()
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer::buffer(size_t size)
|
buffer::buffer(size_t size)
|
||||||
: buf(new std::vector<uint8_t>(size))
|
: buf_(new std::vector<uint8_t>(size))
|
||||||
{
|
{
|
||||||
this->size = buf->size();
|
size_ = buf_->size();
|
||||||
skip(0);
|
skip(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer::buffer(const std::vector<uint8_t> &buf, uint32_t data_offset)
|
buffer::buffer(const std::vector<uint8_t> &buf, uint32_t data_offset)
|
||||||
: buf(new std::vector<uint8_t>(buf)), data_offset(data_offset)
|
: buf_(new std::vector<uint8_t>(buf)), data_offset(data_offset)
|
||||||
{
|
{
|
||||||
skip(0);
|
skip(0);
|
||||||
size = this->buf->size();
|
size_ = buf_->size();
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer::buffer(buffer &rhs, uint32_t size)
|
buffer::buffer(buffer &rhs, uint32_t size)
|
||||||
: buf(rhs.buf)
|
: buf_(rhs.buf_)
|
||||||
{
|
{
|
||||||
index = rhs.index;
|
index_ = rhs.index_;
|
||||||
data_offset = rhs.data_offset;
|
data_offset = rhs.data_offset;
|
||||||
ptr = rhs.ptr;
|
ptr = rhs.ptr;
|
||||||
this->size = index + size;
|
size_ = index_ + size;
|
||||||
rhs.skip(size);
|
rhs.skip(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer::buffer(buffer &rhs, uint32_t size, uint32_t offset)
|
buffer::buffer(buffer &rhs, uint32_t size, uint32_t offset)
|
||||||
: buf(rhs.buf)
|
: buf_(rhs.buf_)
|
||||||
{
|
{
|
||||||
index = offset;
|
index_ = offset;
|
||||||
data_offset = offset;
|
data_offset = offset;
|
||||||
ptr = (uint8_t *)buf->data() + index;
|
ptr = (uint8_t *)buf_->data() + index_;
|
||||||
this->size = index + size;
|
size_ = index_ + size;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t buffer::read(void *dst, uint32_t size, bool nothrow) const
|
uint32_t buffer::read(void *dst, uint32_t size, bool nothrow) const
|
||||||
{
|
{
|
||||||
if (!buf)
|
if (!buf_)
|
||||||
throw std::logic_error("buffer: not initialized");
|
throw std::logic_error("buffer: not initialized");
|
||||||
if (index >= this->size)
|
if (index_ >= size_)
|
||||||
{
|
{
|
||||||
if (nothrow)
|
if (nothrow)
|
||||||
return 0;
|
return 0;
|
||||||
throw std::logic_error("buffer: out of range");
|
throw std::logic_error("buffer: out of range");
|
||||||
}
|
}
|
||||||
if (index + size > this->size)
|
if (index_ + size > size_)
|
||||||
{
|
{
|
||||||
if (!nothrow)
|
if (!nothrow)
|
||||||
throw std::logic_error("buffer: too much data");
|
throw std::logic_error("buffer: too much data");
|
||||||
size = this->size - index;
|
size = size_ - index_;
|
||||||
}
|
}
|
||||||
memcpy(dst, buf->data() + index, size);
|
memcpy(dst, buf_->data() + index_, size);
|
||||||
skip(size);
|
skip(size);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t buffer::readfrom(void *dst, uint32_t size, uint32_t offset, bool nothrow) const
|
||||||
|
{
|
||||||
|
if (!buf_)
|
||||||
|
throw std::logic_error("buffer: not initialized");
|
||||||
|
if (offset + size > size_)
|
||||||
|
{
|
||||||
|
if (!nothrow)
|
||||||
|
throw std::logic_error("buffer: too much data");
|
||||||
|
size = size_ - offset;
|
||||||
|
}
|
||||||
|
memcpy(dst, buf_->data() + offset, size);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t buffer::write(const void *src, uint32_t size, bool nothrow)
|
uint32_t buffer::write(const void *src, uint32_t size, bool nothrow)
|
||||||
{
|
{
|
||||||
if (!buf)
|
if (!buf_)
|
||||||
{
|
{
|
||||||
buf = std::make_shared<std::vector<uint8_t>>(size);
|
buf_ = std::make_shared<std::vector<uint8_t>>(size);
|
||||||
this->size = buf->size();
|
size_ = buf_->size();
|
||||||
}
|
}
|
||||||
if (index > this->size)
|
if (index_ > size_)
|
||||||
{
|
{
|
||||||
if (nothrow)
|
if (nothrow)
|
||||||
return 0;
|
return 0;
|
||||||
throw std::logic_error("buffer: out of range");
|
throw std::logic_error("buffer: out of range");
|
||||||
}
|
}
|
||||||
if (index + size > this->size)
|
if (index_ + size > size_)
|
||||||
{
|
{
|
||||||
buf->resize(index + size);
|
buf_->resize(index_ + size);
|
||||||
this->size = buf->size();
|
size_ = buf_->size();
|
||||||
}
|
}
|
||||||
memcpy((uint8_t *)buf->data() + index, src, size);
|
memcpy((uint8_t *)buf_->data() + index_, src, size);
|
||||||
skip(size);
|
skip(size);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void buffer::skip(int n) const
|
void buffer::skip(int n) const
|
||||||
{
|
{
|
||||||
if (!buf)
|
if (!buf_)
|
||||||
throw std::logic_error("buffer: not initialized");
|
throw std::logic_error("buffer: not initialized");
|
||||||
index += n;
|
index_ += n;
|
||||||
data_offset += n;
|
data_offset += n;
|
||||||
ptr = (uint8_t *)buf->data() + index;
|
ptr = (uint8_t *)buf_->data() + index_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void buffer::reset() const
|
void buffer::reset() const
|
||||||
{
|
{
|
||||||
index = 0;
|
index_ = 0;
|
||||||
data_offset = 0;
|
data_offset = 0;
|
||||||
ptr = (uint8_t *)buf->data();
|
ptr = (uint8_t *)buf_->data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void buffer::seek(uint32_t size) const
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
skip(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool buffer::check(int index) const
|
bool buffer::check(int index) const
|
||||||
{
|
{
|
||||||
return this->index == index;
|
return index_ == index;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool buffer::eof() const
|
bool buffer::eof() const
|
||||||
{
|
{
|
||||||
return check(this->size);
|
return check(size_);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t buffer::getIndex() const
|
uint32_t buffer::index() const
|
||||||
{
|
{
|
||||||
return index;
|
return index_;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t buffer::getSize() const
|
uint32_t buffer::size() const
|
||||||
{
|
{
|
||||||
return this->size;
|
return size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<uint8_t> &buffer::getBuf() const
|
const std::vector<uint8_t> &buffer::buf() const
|
||||||
{
|
{
|
||||||
if (!buf)
|
if (!buf_)
|
||||||
throw std::logic_error("buffer: not initialized");
|
throw std::logic_error("buffer: not initialized");
|
||||||
return *buf;
|
return *buf_;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,26 +42,28 @@ public:
|
||||||
buffer(buffer &rhs, uint32_t size, uint32_t offset);
|
buffer(buffer &rhs, uint32_t size, uint32_t offset);
|
||||||
|
|
||||||
uint32_t read(void *dst, uint32_t size, bool nothrow = false) const;
|
uint32_t read(void *dst, uint32_t size, bool nothrow = false) const;
|
||||||
|
uint32_t readfrom(void *dst, uint32_t size, uint32_t offset, bool nothrow = false) const;
|
||||||
uint32_t write(const void *src, uint32_t size, bool nothrow = false);
|
uint32_t write(const void *src, uint32_t size, bool nothrow = false);
|
||||||
template <typename T>
|
template <typename T>
|
||||||
uint32_t write(const T &src, bool nothrow = false)
|
uint32_t write(const T &src)
|
||||||
{
|
{
|
||||||
return write(&src, sizeof(src), nothrow);
|
return write(&src, sizeof(src));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void seek(uint32_t size) const;
|
||||||
void skip(int n) const;
|
void skip(int n) const;
|
||||||
bool eof() const;
|
bool eof() const;
|
||||||
bool check(int index) const;
|
bool check(int index) const;
|
||||||
void reset() const;
|
void reset() const;
|
||||||
|
|
||||||
uint32_t getIndex() const;
|
uint32_t index() const;
|
||||||
uint32_t getSize() const;
|
uint32_t size() const;
|
||||||
const std::vector<uint8_t> &getBuf() const;
|
const std::vector<uint8_t> &buf() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<std::vector<uint8_t>> buf;
|
std::shared_ptr<std::vector<uint8_t>> buf_;
|
||||||
mutable uint32_t index = 0;
|
mutable uint32_t index_ = 0;
|
||||||
mutable uint8_t *ptr = 0;
|
mutable uint8_t *ptr = 0;
|
||||||
mutable uint32_t data_offset = 0;
|
mutable uint32_t data_offset = 0;
|
||||||
mutable uint32_t size = 0;
|
mutable uint32_t size_ = 0;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
1
src/mod_converter/mod_converter.bat
Normal file
1
src/mod_converter/mod_converter.bat
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
python mod_converter.py --dir "h:\\Games\\Epic Games\\Projects\\AIM\\models1\\"
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
@ -27,6 +28,48 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
// options
|
||||||
|
bool silent = false;
|
||||||
|
bool printMaxPolygonBlock = false;
|
||||||
|
string filename;
|
||||||
|
|
||||||
|
bool parse_cmd(int argc, char *argv[]);
|
||||||
|
|
||||||
|
void print(const block &b, const std::string &fn)
|
||||||
|
{
|
||||||
|
if (b.type == BlockType::ParticleEmitter)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto obj_fn = fn;
|
||||||
|
if (!printMaxPolygonBlock)
|
||||||
|
obj_fn += string(".") + b.name;
|
||||||
|
obj_fn += ".obj";
|
||||||
|
ofstream o(obj_fn);
|
||||||
|
o << "#" << "\n";
|
||||||
|
o << "# A.I.M. Model Converter (ver. " << version() << ")\n";
|
||||||
|
o << "#" << "\n";
|
||||||
|
o << "\n";
|
||||||
|
int p1 = fn.rfind("\\");
|
||||||
|
int p2 = fn.rfind("/");
|
||||||
|
auto mtl = fn.substr(std::max(p1, p2) + 1);
|
||||||
|
if (!printMaxPolygonBlock)
|
||||||
|
mtl += string(".") + b.name;
|
||||||
|
o << "mtllib " << mtl << ".mtl\n";
|
||||||
|
o << "\n";
|
||||||
|
o << b.printObj(mtl);
|
||||||
|
|
||||||
|
auto mtl_fn = fn;
|
||||||
|
if (!printMaxPolygonBlock)
|
||||||
|
mtl_fn += string(".") + b.name;
|
||||||
|
mtl_fn += ".mtl";
|
||||||
|
ofstream m(mtl_fn);
|
||||||
|
m << "#" << "\n";
|
||||||
|
m << "# A.I.M. Model Converter (ver. " << version() << ")\n";
|
||||||
|
m << "#" << "\n";
|
||||||
|
m << "\n";
|
||||||
|
m << b.printMtl(mtl);
|
||||||
|
}
|
||||||
|
|
||||||
void convert_model(string fn)
|
void convert_model(string fn)
|
||||||
{
|
{
|
||||||
buffer b(readFile(fn));
|
buffer b(readFile(fn));
|
||||||
|
|
@ -36,26 +79,47 @@ void convert_model(string fn)
|
||||||
if (!b.eof())
|
if (!b.eof())
|
||||||
{
|
{
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
ss << hex << b.getIndex() << " != " << hex << b.getSize();
|
ss << hex << b.index() << " != " << hex << b.size();
|
||||||
throw std::logic_error(ss.str());
|
throw std::logic_error(ss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
m.writeObj(fn);
|
// write obj and mtl
|
||||||
|
if (printMaxPolygonBlock)
|
||||||
|
{
|
||||||
|
int max = 0;
|
||||||
|
int maxBlock = -1;
|
||||||
|
for (int i = 0; i < m.blocks.size(); i++)
|
||||||
|
{
|
||||||
|
if (m.blocks[i].n_vertex > max)
|
||||||
|
{
|
||||||
|
max = m.blocks[i].n_vertex;
|
||||||
|
maxBlock = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print(m.blocks[maxBlock], filename);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (auto &f : m.blocks)
|
||||||
|
print(f, filename);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (argc != 2)
|
if (argc < 2 || !parse_cmd(argc, argv))
|
||||||
{
|
{
|
||||||
printf("Usage: %s model_file\n", argv[0]);
|
printf("Usage: %s [OPTIONS] model_file\n", argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
convert_model(argv[1]);
|
convert_model(filename);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
catch (std::runtime_error &e)
|
catch (std::runtime_error &e)
|
||||||
{
|
{
|
||||||
|
if (silent)
|
||||||
|
return 1;
|
||||||
string error;
|
string error;
|
||||||
if (argv[1])
|
if (argv[1])
|
||||||
error += argv[1];
|
error += argv[1];
|
||||||
|
|
@ -72,13 +136,42 @@ catch (std::runtime_error &e)
|
||||||
}
|
}
|
||||||
catch (std::exception &e)
|
catch (std::exception &e)
|
||||||
{
|
{
|
||||||
|
if (silent)
|
||||||
|
return 1;
|
||||||
printf("%s\n", argv[1]);
|
printf("%s\n", argv[1]);
|
||||||
printf("error: %s\n", e.what());
|
printf("error: %s\n", e.what());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
|
if (silent)
|
||||||
|
return 1;
|
||||||
printf("%s\n", argv[1]);
|
printf("%s\n", argv[1]);
|
||||||
printf("error: unknown exception\n");
|
printf("error: unknown exception\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool parse_cmd(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
for (int i = 1; i < argc; i++)
|
||||||
|
{
|
||||||
|
auto arg = argv[i];
|
||||||
|
if (*arg != '-')
|
||||||
|
{
|
||||||
|
if (i != argc - 1)
|
||||||
|
return false;
|
||||||
|
filename = arg;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (arg[1])
|
||||||
|
{
|
||||||
|
case 's':
|
||||||
|
silent = true;
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
printMaxPolygonBlock = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -139,22 +139,28 @@ std::string block::printMtl(const std::string &mtl_name) const
|
||||||
// d 1.0
|
// d 1.0
|
||||||
// illum
|
// illum
|
||||||
s += "\n";
|
s += "\n";
|
||||||
s += "map_Ka " + string(tex_mask) + ".tga\n";
|
if (string(tex_mask) != "_DEFAULT_")
|
||||||
s += "map_Kd " + string(tex_mask) + ".tga\n";
|
s += "map_Ka " + string(tex_mask) + ".tga" + "\n";
|
||||||
s += "map_Ks " + string(tex_spec) + ".tga\n";
|
if (string(tex_mask) != "_DEFAULT_")
|
||||||
s += "map_Ns " + string(tex_spec) + ".tga\n";
|
s += "map_Kd " + string(tex_mask) + ".tga" + "\n";
|
||||||
|
if (string(tex_spec) != "_DEFAULT_")
|
||||||
|
s += "map_Ks " + string(tex_spec) + ".tga" + "\n";
|
||||||
|
if (string(tex_spec) != "_DEFAULT_")
|
||||||
|
s += "map_Ns " + string(tex_spec) + ".tga" + "\n";
|
||||||
s += "\n";
|
s += "\n";
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string block::printObj() const
|
std::string block::printObj(const std::string &mtl_name) const
|
||||||
{
|
{
|
||||||
string s;
|
string s;
|
||||||
s += string("o ") + name + "\n";
|
// UE does not recognize russian strings in .obj
|
||||||
s += string("g ") + name + "\n";
|
//s += string("o ") + name + "\n";
|
||||||
|
//s += string("g ") + name + "\n";
|
||||||
|
s += "g group1\n";
|
||||||
s += "s off\n";
|
s += "s off\n";
|
||||||
s += "\n";
|
s += "\n";
|
||||||
s += "usemtl main\n";
|
s += "usemtl " + mtl_name + "\n";
|
||||||
s += "\n";
|
s += "\n";
|
||||||
|
|
||||||
for (auto &v : vertices)
|
for (auto &v : vertices)
|
||||||
|
|
@ -201,7 +207,7 @@ void block::load(buffer &b)
|
||||||
READ(b, unk4);
|
READ(b, unk4);
|
||||||
|
|
||||||
if (size == 0) // critical error!!! cannot survive
|
if (size == 0) // critical error!!! cannot survive
|
||||||
throw std::runtime_error("model file has bad block size field");
|
throw std::runtime_error("model file has bad block size field (size == 0)");
|
||||||
|
|
||||||
// data
|
// data
|
||||||
buffer data = buffer(b, size);
|
buffer data = buffer(b, size);
|
||||||
|
|
@ -253,7 +259,7 @@ void block::load(buffer &b)
|
||||||
{
|
{
|
||||||
// unknown end of block
|
// unknown end of block
|
||||||
auto triangles2 = triangles;
|
auto triangles2 = triangles;
|
||||||
triangles2.resize((data.getSize() - data.getIndex()) / sizeof(triangle));
|
triangles2.resize((data.size() - data.index()) / sizeof(triangle));
|
||||||
for (auto &t : triangles2)
|
for (auto &t : triangles2)
|
||||||
READ(data, t);
|
READ(data, t);
|
||||||
}
|
}
|
||||||
|
|
@ -271,29 +277,3 @@ void model::load(buffer &b)
|
||||||
for (auto &f : blocks)
|
for (auto &f : blocks)
|
||||||
f.load(b);
|
f.load(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void model::writeObj(std::string fn)
|
|
||||||
{
|
|
||||||
for (auto &f : blocks)
|
|
||||||
{
|
|
||||||
ofstream o(fn + "." + f.name + ".obj");
|
|
||||||
o << "#" << "\n";
|
|
||||||
o << "# A.I.M. Model Converter (ver. " << version() << ")\n";
|
|
||||||
o << "#" << "\n";
|
|
||||||
o << "\n";
|
|
||||||
int p1 = fn.rfind("\\");
|
|
||||||
int p2 = fn.rfind("/");
|
|
||||||
auto mtl = fn.substr(std::max(p1, p2) + 1);
|
|
||||||
mtl += string(".") + f.name;
|
|
||||||
o << "mtllib " << mtl << ".mtl\n";
|
|
||||||
o << "\n";
|
|
||||||
o << f.printObj();
|
|
||||||
|
|
||||||
ofstream m(fn + "." + f.name + ".mtl");
|
|
||||||
m << "#" << "\n";
|
|
||||||
m << "# A.I.M. Model Converter (ver. " << version() << ")\n";
|
|
||||||
m << "#" << "\n";
|
|
||||||
m << "\n";
|
|
||||||
m << f.printMtl(mtl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,7 @@ struct block
|
||||||
|
|
||||||
void load(buffer &b);
|
void load(buffer &b);
|
||||||
std::string printMtl(const std::string &mtl_name) const;
|
std::string printMtl(const std::string &mtl_name) const;
|
||||||
std::string printObj() const;
|
std::string printObj(const std::string &mtl_name) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct model
|
struct model
|
||||||
|
|
@ -224,5 +224,4 @@ struct model
|
||||||
std::vector<block> blocks;
|
std::vector<block> blocks;
|
||||||
|
|
||||||
void load(buffer &b);
|
void load(buffer &b);
|
||||||
void writeObj(std::string fn);
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
1
src/obj_extractor/obj_extractor.bat
Normal file
1
src/obj_extractor/obj_extractor.bat
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
python obj_extractor.py --db "h:\Games\Epic Games\Projects\Polygon4\Mods\db.sqlite" --dir "h:\Games\AIM\data\maps.pak.dir"
|
||||||
|
|
@ -55,7 +55,7 @@ struct storage
|
||||||
if (!b.eof())
|
if (!b.eof())
|
||||||
{
|
{
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
ss << hex << b.getIndex() << " != " << hex << b.getSize();
|
ss << hex << b.index() << " != " << hex << b.size();
|
||||||
throw std::logic_error(ss.str());
|
throw std::logic_error(ss.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -99,7 +99,10 @@ void write_mmo(string db, const storage &s)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (map_id == 0)
|
if (map_id == 0)
|
||||||
|
{
|
||||||
|
printf("error: this map is not found in the database\n");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto this_map = storage->maps[map_id];
|
auto this_map = storage->maps[map_id];
|
||||||
|
|
||||||
|
|
@ -122,10 +125,10 @@ void write_mmo(string db, const storage &s)
|
||||||
{
|
{
|
||||||
auto bld = storage->addBuilding();
|
auto bld = storage->addBuilding();
|
||||||
bld->text_id = o;
|
bld->text_id = o;
|
||||||
bld_ids[o] = bld->id;
|
bld_ids[o] = bld->getId();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
bld_ids[o] = iter->second->id;
|
bld_ids[o] = iter->second->getId();
|
||||||
}
|
}
|
||||||
for (auto &object : segment->objects)
|
for (auto &object : segment->objects)
|
||||||
{
|
{
|
||||||
|
|
@ -146,7 +149,7 @@ void write_mmo(string db, const storage &s)
|
||||||
if (i == storage->mapBuildings.end())
|
if (i == storage->mapBuildings.end())
|
||||||
{
|
{
|
||||||
auto mb2 = storage->addMapBuilding(storage->maps[map_id].get());
|
auto mb2 = storage->addMapBuilding(storage->maps[map_id].get());
|
||||||
mb.id = mb2->id;
|
mb.setId(mb2->getId());
|
||||||
*mb2.get() = mb;
|
*mb2.get() = mb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -170,10 +173,10 @@ void write_mmo(string db, const storage &s)
|
||||||
{
|
{
|
||||||
auto bld = storage->addObject();
|
auto bld = storage->addObject();
|
||||||
bld->text_id = o;
|
bld->text_id = o;
|
||||||
bld_ids[o] = bld->id;
|
bld_ids[o] = bld->getId();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
bld_ids[o] = iter->second->id;
|
bld_ids[o] = iter->second->getId();
|
||||||
}
|
}
|
||||||
for (auto &object : segment->objects)
|
for (auto &object : segment->objects)
|
||||||
{
|
{
|
||||||
|
|
@ -194,7 +197,7 @@ void write_mmo(string db, const storage &s)
|
||||||
if (i == storage->mapObjects.end())
|
if (i == storage->mapObjects.end())
|
||||||
{
|
{
|
||||||
auto mb2 = storage->addMapObject(storage->maps[map_id].get());
|
auto mb2 = storage->addMapObject(storage->maps[map_id].get());
|
||||||
mb.id = mb2->id;
|
mb.setId(mb2->getId());
|
||||||
*mb2.get() = mb;
|
*mb2.get() = mb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
26
src/obj_extractor/obj_extractor.py
Normal file
26
src/obj_extractor/obj_extractor.py
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description='Batch models converter')
|
||||||
|
parser.add_argument('--dir', dest='dir', help='path to directory with maps')
|
||||||
|
parser.add_argument('--db', dest='db', help='path to db')
|
||||||
|
pargs = parser.parse_args()
|
||||||
|
|
||||||
|
if pargs.dir:
|
||||||
|
run(pargs.dir, pargs.db)
|
||||||
|
|
||||||
|
def run(dir, db):
|
||||||
|
for file in sorted(os.listdir(dir)):
|
||||||
|
if os.path.isdir(file) or os.path.splitext(file)[1] != ".mmo":
|
||||||
|
continue
|
||||||
|
print('loading: ' + file)
|
||||||
|
p = subprocess.Popen(['obj_extractor.exe', db, dir + '/' + file])
|
||||||
|
p.communicate()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
|
@ -171,7 +171,7 @@ KNOWN_OBJECT(Anomaly);
|
||||||
KNOWN_OBJECT(Boundary);
|
KNOWN_OBJECT(Boundary);
|
||||||
|
|
||||||
#define UNKNOWN_OBJECT(name) \
|
#define UNKNOWN_OBJECT(name) \
|
||||||
struct name : public MapObject { void load(buffer &b){ int pos = b.getIndex(); assert(false); } }
|
struct name : public MapObject { void load(buffer &b){ int pos = b.index(); assert(false); } }
|
||||||
|
|
||||||
UNKNOWN_OBJECT(Building);
|
UNKNOWN_OBJECT(Building);
|
||||||
UNKNOWN_OBJECT(Goods);
|
UNKNOWN_OBJECT(Goods);
|
||||||
|
|
|
||||||
1
src/tm_converter/tm_converter.bat
Normal file
1
src/tm_converter/tm_converter.bat
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
python tm_converter.py --dir "h:\\Games\\Epic Games\\Projects\\AIM\\models\\aim1\\"
|
||||||
|
|
@ -27,15 +27,31 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
void convert_simple(buffer &dst, buffer &src, int width, int height)
|
||||||
|
{
|
||||||
|
int size = width * height * 2;
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
uint8_t c;
|
||||||
|
READ(src, c);
|
||||||
|
uint8_t lo = c & 0x0F;
|
||||||
|
uint8_t hi = (c & 0xF0) >> 4;
|
||||||
|
dst.write(uint8_t((lo << 4) | lo));
|
||||||
|
dst.write(uint8_t((hi << 4) | hi));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void tm2tga(string fn)
|
void tm2tga(string fn)
|
||||||
{
|
{
|
||||||
int width, height;
|
int width, height;
|
||||||
|
int dxt5 = 0;
|
||||||
|
|
||||||
buffer src(readFile(fn));
|
buffer src(readFile(fn));
|
||||||
READ(src, width);
|
READ(src, width);
|
||||||
READ(src, height);
|
READ(src, height);
|
||||||
src.reset();
|
src.seek(0x10);
|
||||||
src.skip(0x4C);
|
src.read(&dxt5, 1);
|
||||||
|
src.seek(0x4C);
|
||||||
|
|
||||||
// http://paulbourke.net/dataformats/tga/
|
// http://paulbourke.net/dataformats/tga/
|
||||||
buffer dst;
|
buffer dst;
|
||||||
|
|
@ -53,22 +69,19 @@ void tm2tga(string fn)
|
||||||
dst.write(uint8_t(0x28)); // imagedescriptor
|
dst.write(uint8_t(0x28)); // imagedescriptor
|
||||||
|
|
||||||
const char *label = "AIMTMConverter";
|
const char *label = "AIMTMConverter";
|
||||||
dst.write(label, strlen(label), false);
|
dst.write(label, strlen(label));
|
||||||
|
|
||||||
int size = width * height * 2;
|
if (dxt5)
|
||||||
for (int i = 0; i < size; i++)
|
|
||||||
{
|
{
|
||||||
uint8_t c;
|
//convert_dxt5(dst, src, width, height);
|
||||||
READ(src, c);
|
throw std::logic_error("dxt5 converter is not implemented!");
|
||||||
uint8_t lo = c & 0x0F;
|
|
||||||
uint8_t hi = (c & 0xF0) >> 4;
|
|
||||||
dst.write(uint8_t((lo << 4) | lo));
|
|
||||||
dst.write(uint8_t((hi << 4) | hi));
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
convert_simple(dst, src, width, height);
|
||||||
|
|
||||||
transform(fn.begin(), fn.end(), fn.begin(), ::tolower);
|
transform(fn.begin(), fn.end(), fn.begin(), ::tolower);
|
||||||
fn = fn.substr(0, fn.rfind(".tm")) + ".tga";
|
fn = fn.substr(0, fn.rfind(".tm")) + ".tga";
|
||||||
writeFile(fn, dst.getBuf());
|
writeFile(fn, dst.buf());
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
|
|
|
||||||
24
src/tm_converter/tm_converter.py
Normal file
24
src/tm_converter/tm_converter.py
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description='Batch textures converter')
|
||||||
|
parser.add_argument('--dir', dest='dir', help='path to directory with textures')
|
||||||
|
pargs = parser.parse_args()
|
||||||
|
|
||||||
|
if pargs.dir:
|
||||||
|
run(pargs.dir)
|
||||||
|
|
||||||
|
def run(dir):
|
||||||
|
for file in sorted(os.listdir(dir)):
|
||||||
|
if os.path.isdir(file) or os.path.splitext(file)[1].lower() != ".tm":
|
||||||
|
continue
|
||||||
|
p = subprocess.Popen(['tm_converter.exe', dir + '/' + file])
|
||||||
|
p.communicate()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
Loading…
Reference in a new issue