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/*")
|
file(GLOB mmp_extractor_src "mmp_extractor/*")
|
||||||
add_executable(mmp_extractor ${mmp_extractor_src})
|
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