mirror of
https://github.com/aimrebirth/tools.git
synced 2026-04-14 17:33:25 +00:00
Initial mod converter.
This commit is contained in:
parent
0a67413c4b
commit
e1f8b3b260
5 changed files with 478 additions and 0 deletions
|
|
@ -13,3 +13,6 @@ add_executable(script2txt ${script2txt_src})
|
|||
|
||||
file(GLOB mmp_extractor_src "mmp_extractor/*")
|
||||
add_executable(mmp_extractor ${mmp_extractor_src})
|
||||
|
||||
file(GLOB mod_converter_src "mod_converter/*")
|
||||
add_executable(mod_converter ${mod_converter_src})
|
||||
|
|
|
|||
72
src/mod_converter/mod_converter.cpp
Normal file
72
src/mod_converter/mod_converter.cpp
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* AIM mod_converter
|
||||
* Copyright (C) 2015 lzwdgc
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "model.h"
|
||||
|
||||
model read_model(string fn)
|
||||
{
|
||||
model m;
|
||||
FILE *f = fopen(fn.c_str(), "rb");
|
||||
if (!f)
|
||||
return m;
|
||||
try
|
||||
{
|
||||
m.load(f);
|
||||
}
|
||||
catch (std::exception &e)
|
||||
{
|
||||
printf("error: %s\n", fn.c_str());
|
||||
printf("%s\n", e.what());
|
||||
return m;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#ifdef NDEBUG
|
||||
if (argc != 2)
|
||||
{
|
||||
cout << "Usage:\n" << argv[0] << " model_file" << "\n";
|
||||
return 1;
|
||||
}
|
||||
read_model(argv[1]);
|
||||
#else
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
24
src/mod_converter/mod_converter.py
Normal file
24
src/mod_converter/mod_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 models converter')
|
||||
parser.add_argument('--dir', dest='dir', help='path to directory with models')
|
||||
pargs = parser.parse_args()
|
||||
|
||||
if pargs.dir:
|
||||
run(pargs.dir)
|
||||
|
||||
def run(dir):
|
||||
for file in os.listdir(dir):
|
||||
if os.path.isdir(file):
|
||||
continue
|
||||
p = subprocess.Popen(['mod_converter.exe', file])
|
||||
p.communicate()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
191
src/mod_converter/model.cpp
Normal file
191
src/mod_converter/model.cpp
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
* AIM mod_converter
|
||||
* Copyright (C) 2015 lzwdgc
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "model.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#define FREAD(var) fread(&var, 1, sizeof(var), f)
|
||||
#define SREAD(var) s.read(&var, sizeof(var))
|
||||
#define SREAD_N(var, sz) s.read(&var, sz)
|
||||
|
||||
void vertex::load(s_file &s, uint32_t flags)
|
||||
{
|
||||
SREAD(vX);
|
||||
SREAD(vZ);
|
||||
SREAD(vY);
|
||||
|
||||
if (flags & F_WIND)
|
||||
SREAD(wind);
|
||||
|
||||
SREAD(nX);
|
||||
SREAD(nZ);
|
||||
SREAD(nY);
|
||||
|
||||
SREAD(t1);
|
||||
SREAD(t2);
|
||||
}
|
||||
|
||||
void fragment::load(FILE *f)
|
||||
{
|
||||
FREAD(type);
|
||||
FREAD(name0);
|
||||
FREAD(name1);
|
||||
FREAD(name2);
|
||||
FREAD(name3);
|
||||
FREAD(name4);
|
||||
FREAD(unk0);
|
||||
FREAD(unk1);
|
||||
FREAD(unk2);
|
||||
FREAD(unk3);
|
||||
FREAD(size);
|
||||
FREAD(unk4);
|
||||
data.resize(size);
|
||||
data_offset = ftell(f);
|
||||
fread(data.data(), 1, size, f);
|
||||
}
|
||||
|
||||
bool fragment::extract()
|
||||
{
|
||||
s_file s(data, data_offset);
|
||||
|
||||
SREAD(n_segments);
|
||||
segments.resize(n_segments);
|
||||
SREAD(header);
|
||||
SREAD(triangles_mult_7);
|
||||
SREAD(unk10);
|
||||
SREAD(flags);
|
||||
SREAD(n_vertex);
|
||||
vertices.resize(n_vertex);
|
||||
SREAD(n_triangles);
|
||||
if (triangles_mult_7)
|
||||
n_triangles *= 7;
|
||||
triangles.resize(n_triangles);
|
||||
for (auto &v : vertices)
|
||||
v.load(s, flags);
|
||||
for (auto &t : triangles)
|
||||
SREAD(t);
|
||||
|
||||
for (auto &seg : segments)
|
||||
{
|
||||
uint32_t type;
|
||||
SREAD(type);
|
||||
switch (type)
|
||||
{
|
||||
case 1:
|
||||
seg = new segment1;
|
||||
break;
|
||||
case 2:
|
||||
seg = new segment2;
|
||||
break;
|
||||
case 6:
|
||||
seg = new segment6;
|
||||
break;
|
||||
default:
|
||||
throw std::logic_error("unknown segment type " + std::to_string(type));
|
||||
}
|
||||
seg->type = type;
|
||||
seg->extract(s);
|
||||
}
|
||||
|
||||
return s.eof();
|
||||
}
|
||||
|
||||
void segment1::extract(s_file &s)
|
||||
{
|
||||
SREAD(name);
|
||||
SREAD(unk0);
|
||||
triangles.resize(unk0[0][0]);
|
||||
unk1.resize(unk0[0][0]);
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
for (auto &t : triangles)
|
||||
SREAD(t);
|
||||
for (auto &unk: unk1)
|
||||
SREAD(unk);
|
||||
}
|
||||
}
|
||||
|
||||
void segment2::extract(s_file &s)
|
||||
{
|
||||
SREAD(name);
|
||||
SREAD(unk0);
|
||||
triangles.resize(unk0[0][0]);
|
||||
unk1.resize(unk0[0][0]);
|
||||
unk1_1.resize(unk0[0][0]);
|
||||
for (auto &t : triangles)
|
||||
SREAD(t);
|
||||
for (auto &unk : unk1)
|
||||
SREAD(unk);
|
||||
for (auto &unk : unk1_1)
|
||||
SREAD(unk);
|
||||
while (!s.eof())
|
||||
{
|
||||
repeater r;
|
||||
r.extract(s);
|
||||
unk2.push_back(r);
|
||||
}
|
||||
}
|
||||
|
||||
void segment2::repeater::extract(s_file &s)
|
||||
{
|
||||
SREAD(unk2);
|
||||
triangles2.resize(unk2);
|
||||
SREAD(unk8);
|
||||
SREAD(unk3);
|
||||
for (auto &t : triangles2)
|
||||
SREAD(t);
|
||||
SREAD(unk6);
|
||||
SREAD(flags);
|
||||
SREAD(n_vertex);
|
||||
vertices.resize(n_vertex);
|
||||
SREAD(n_triangles);
|
||||
triangles.resize(n_triangles);
|
||||
for (auto &v : vertices)
|
||||
v.load(s, flags);
|
||||
for (auto &t : triangles)
|
||||
SREAD(t);
|
||||
}
|
||||
|
||||
void segment6::extract(s_file &s)
|
||||
{
|
||||
SREAD(name);
|
||||
SREAD(unk0);
|
||||
triangles.resize(unk0[0][0]);
|
||||
for (int i = 0; i < 1; i++)
|
||||
{
|
||||
for (auto &t : triangles)
|
||||
SREAD(t);
|
||||
char unk1[0x30]; // some 6 floats
|
||||
for (int i = 0; i < unk0[0][0]; i++)
|
||||
SREAD(unk1);
|
||||
}
|
||||
}
|
||||
|
||||
void model::load(FILE *f)
|
||||
{
|
||||
FREAD(n_fragments);
|
||||
FREAD(header);
|
||||
fragments.resize(n_fragments);
|
||||
for (int i = 0; i < fragments.size(); i++)
|
||||
{
|
||||
fragments[i].load(f);
|
||||
if (!fragments[i].extract())
|
||||
throw std::logic_error("extraction error: fragment #" + std::to_string(i));
|
||||
}
|
||||
}
|
||||
188
src/mod_converter/model.h
Normal file
188
src/mod_converter/model.h
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
* AIM mod_converter
|
||||
* Copyright (C) 2015 lzwdgc
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
struct s_file
|
||||
{
|
||||
uint32_t index = 0;
|
||||
const std::vector<uint8_t> &buf;
|
||||
uint8_t *ptr;
|
||||
uint32_t data_offset;
|
||||
|
||||
s_file(const std::vector<uint8_t> &buf, uint32_t data_offset)
|
||||
: buf(buf), data_offset(data_offset)
|
||||
{}
|
||||
uint32_t read(void *dst, uint32_t size)
|
||||
{
|
||||
if (index >= buf.size())
|
||||
throw std::logic_error("s_file: out of range");
|
||||
if (index + size > buf.size())
|
||||
size = buf.size() - index;
|
||||
memcpy(dst, buf.data() + index, size);
|
||||
skip(size);
|
||||
return size;
|
||||
}
|
||||
void skip(int n)
|
||||
{
|
||||
index += n;
|
||||
data_offset += n;
|
||||
ptr = (uint8_t *)buf.data() + index;
|
||||
}
|
||||
bool eof() const
|
||||
{
|
||||
return index == buf.size();
|
||||
}
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
F_WIND = 0x4,
|
||||
};
|
||||
|
||||
struct vertex
|
||||
{
|
||||
float vX;
|
||||
float vZ;
|
||||
float vY;
|
||||
|
||||
float wind;
|
||||
|
||||
float nX;
|
||||
float nZ;
|
||||
float nY;
|
||||
|
||||
float t1;
|
||||
float t2;
|
||||
|
||||
void load(s_file &s, uint32_t flags);
|
||||
};
|
||||
|
||||
typedef uint16_t triangle;
|
||||
|
||||
struct unk_float3x4
|
||||
{
|
||||
float unk[4][3];
|
||||
};
|
||||
|
||||
struct unk_float6
|
||||
{
|
||||
float unk[6];
|
||||
};
|
||||
|
||||
struct segment
|
||||
{
|
||||
uint32_t type;
|
||||
|
||||
virtual void extract(s_file &s) = 0;
|
||||
};
|
||||
|
||||
struct segment1 : public segment
|
||||
{
|
||||
char name[0xC];
|
||||
uint32_t unk0[4][3];
|
||||
std::vector<triangle> triangles;
|
||||
std::vector<unk_float3x4> unk1;
|
||||
|
||||
virtual void extract(s_file &s);
|
||||
};
|
||||
|
||||
struct segment2 : public segment
|
||||
{
|
||||
struct repeater
|
||||
{
|
||||
uint32_t unk2;
|
||||
float unk8[3];
|
||||
char unk3[0x3C];
|
||||
std::vector<uint16_t> triangles2;
|
||||
uint8_t unk6;
|
||||
uint32_t flags;
|
||||
uint32_t n_vertex;
|
||||
uint32_t n_triangles;
|
||||
std::vector<vertex> vertices;
|
||||
std::vector<uint16_t> triangles;
|
||||
|
||||
virtual void extract(s_file &s);
|
||||
};
|
||||
|
||||
char name[0xC];
|
||||
uint32_t unk0[4][3];
|
||||
std::vector<triangle> triangles;
|
||||
std::vector<unk_float6> unk1;
|
||||
std::vector<unk_float6> unk1_1;
|
||||
std::vector<repeater> unk2;
|
||||
|
||||
virtual void extract(s_file &s);
|
||||
};
|
||||
|
||||
struct segment6 : public segment1
|
||||
{
|
||||
virtual void extract(s_file &s);
|
||||
};
|
||||
|
||||
struct fragment
|
||||
{
|
||||
// main header
|
||||
uint32_t type;
|
||||
char name0[0x20];
|
||||
char name1[0x20];
|
||||
char name2[0x20];
|
||||
char name3[0x20];
|
||||
char name4[0x20];
|
||||
uint32_t unk0;
|
||||
uint32_t unk1;
|
||||
uint32_t unk2[2];
|
||||
uint32_t unk3;
|
||||
uint32_t size;
|
||||
uint32_t unk4[10];
|
||||
|
||||
// data buffer
|
||||
std::vector<uint8_t> data;
|
||||
|
||||
// main data
|
||||
uint32_t n_segments;
|
||||
char header[0x68];
|
||||
uint32_t triangles_mult_7;
|
||||
char unk10[0x20];
|
||||
uint32_t flags;
|
||||
uint32_t n_vertex;
|
||||
uint32_t n_triangles;
|
||||
std::vector<vertex> vertices;
|
||||
std::vector<uint16_t> triangles;
|
||||
|
||||
// segments
|
||||
std::vector<segment *> segments;
|
||||
|
||||
// internal vars
|
||||
uint32_t data_offset;
|
||||
|
||||
void load(FILE *f);
|
||||
bool extract();
|
||||
};
|
||||
|
||||
struct model
|
||||
{
|
||||
int n_fragments;
|
||||
char header[0x40];
|
||||
std::vector<fragment> fragments;
|
||||
|
||||
void load(FILE *f);
|
||||
};
|
||||
Loading…
Reference in a new issue