mirror of
https://github.com/aimrebirth/tools.git
synced 2026-04-14 17:33:25 +00:00
Fix a lot of bugs. Add animations reading.
This commit is contained in:
parent
fb6aa75845
commit
e511c01359
5 changed files with 291 additions and 206 deletions
6
src/mod_converter/fragment_names.py
Normal file
6
src/mod_converter/fragment_names.py
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
print(sorted(set(open(sys.argv[1]).readlines())))
|
||||||
|
|
@ -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 <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
@ -28,8 +29,6 @@ using namespace std;
|
||||||
|
|
||||||
void convert_model(string fn)
|
void convert_model(string fn)
|
||||||
{
|
{
|
||||||
printf("%s\n", fn.c_str());
|
|
||||||
|
|
||||||
buffer b(readFile(fn));
|
buffer b(readFile(fn));
|
||||||
model m;
|
model m;
|
||||||
m.load(b);
|
m.load(b);
|
||||||
|
|
@ -41,44 +40,45 @@ void convert_model(string fn)
|
||||||
throw std::logic_error(ss.str());
|
throw std::logic_error(ss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
m.writeObj(fn + ".obj");
|
m.writeObj(fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
#ifdef NDEBUG
|
|
||||||
if (argc != 2)
|
if (argc != 2)
|
||||||
{
|
{
|
||||||
cout << "Usage:\n" << argv[0] << " model_file" << "\n";
|
printf("Usage: %s model_file \n", argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
read_model(argv[1]);
|
convert_model(argv[1]);
|
||||||
#else
|
|
||||||
convert_model("h:\\Games\\AIM\\data\\res0.pak.dir\\Data\\Models\\MOD_GL_M1_A_ATTACKER");
|
|
||||||
convert_model("h:\\Games\\AIM\\data\\res0.pak.dir\\Data\\Models\\MOD_GL_M1_B_BASE");
|
|
||||||
|
|
||||||
convert_model("h:\\Games\\AIM\\data\\res0.pak.dir\\Data\\Models\\MOD_BLD_BASE1");
|
|
||||||
convert_model("h:\\Games\\AIM\\data\\res0.pak.dir\\Data\\Models\\MOD_GL_S4_SINIGR");
|
|
||||||
|
|
||||||
convert_model("h:\\Games\\AIM\\data\\res0.pak.dir\\Data\\Models\\MOD_GL_FIRE");
|
|
||||||
convert_model("h:\\Games\\AIM\\data\\res0.pak.dir\\Data\\Models\\MOD_GL_FARA");
|
|
||||||
|
|
||||||
convert_model("h:\\Games\\AIM\\data\\res0.pak.dir\\Data\\Models\\MOD_FX_ANTI_MATER_GUN");
|
|
||||||
convert_model("h:\\Games\\AIM\\data\\res0.pak.dir\\Data\\Models\\MOD_UNFL_STONE01");
|
|
||||||
convert_model("h:\\Games\\AIM\\data\\res0.pak.dir\\Data\\Models\\MOD_L1_KUST");
|
|
||||||
convert_model("h:\\Games\\AIM\\data\\res0.pak.dir\\Data\\Models\\MOD_L6_KUST_12");
|
|
||||||
convert_model("h:\\Games\\AIM\\data\\res0.pak.dir\\Data\\Models\\MOD_GL_M1_A_ATTACKER_DAMAGED");
|
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
catch (std::runtime_error &e)
|
||||||
|
{
|
||||||
|
string error;
|
||||||
|
if (argv[1])
|
||||||
|
error += argv[1];
|
||||||
|
error += "\n";
|
||||||
|
error += "fatal error: ";
|
||||||
|
error += e.what();
|
||||||
|
error += "\n";
|
||||||
|
if (argv[1])
|
||||||
|
{
|
||||||
|
ofstream ofile(string(argv[1]) + ".error.txt");
|
||||||
|
ofile << error;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
catch (std::exception &e)
|
catch (std::exception &e)
|
||||||
{
|
{
|
||||||
|
printf("%s\n", argv[1]);
|
||||||
printf("error: %s\n", e.what());
|
printf("error: %s\n", e.what());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
|
printf("%s\n", argv[1]);
|
||||||
printf("error: unknown exception\n");
|
printf("error: unknown exception\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,11 @@ import argparse
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
banned_ext = [
|
||||||
|
'.obj',
|
||||||
|
'.txt'
|
||||||
|
]
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(description='Batch models converter')
|
parser = argparse.ArgumentParser(description='Batch models converter')
|
||||||
parser.add_argument('--dir', dest='dir', help='path to directory with models')
|
parser.add_argument('--dir', dest='dir', help='path to directory with models')
|
||||||
|
|
@ -14,10 +19,10 @@ def main():
|
||||||
run(pargs.dir)
|
run(pargs.dir)
|
||||||
|
|
||||||
def run(dir):
|
def run(dir):
|
||||||
for file in os.listdir(dir):
|
for file in sorted(os.listdir(dir)):
|
||||||
if os.path.isdir(file):
|
if os.path.isdir(file) or os.path.splitext(file)[1] in banned_ext:
|
||||||
continue
|
continue
|
||||||
p = subprocess.Popen(['mod_converter.exe', file])
|
p = subprocess.Popen(['mod_converter.exe', dir + '/' + file])
|
||||||
p.communicate()
|
p.communicate()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
#include "model.h"
|
#include "model.h"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
|
@ -33,8 +34,8 @@ void vertex::load(buffer &b, uint32_t flags)
|
||||||
READ(b, vZ);
|
READ(b, vZ);
|
||||||
READ(b, vY);
|
READ(b, vY);
|
||||||
|
|
||||||
if (flags & F_WIND)
|
if (flags & F_UNK0)
|
||||||
READ(b, wind);
|
READ(b, unk0);
|
||||||
|
|
||||||
READ(b, nX);
|
READ(b, nX);
|
||||||
READ(b, nZ);
|
READ(b, nZ);
|
||||||
|
|
@ -65,34 +66,58 @@ std::string vertex::printTex() const
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fragment::load(buffer &b)
|
void block::load(buffer &b)
|
||||||
{
|
{
|
||||||
// header
|
// header
|
||||||
READ(b, type);
|
READ(b, type);
|
||||||
READ(b, name0);
|
READ(b, name);
|
||||||
READ(b, name1);
|
READ(b, tex_mask);
|
||||||
READ(b, name2);
|
READ(b, tex_spec);
|
||||||
READ(b, name3);
|
READ(b, tex3);
|
||||||
READ(b, name4);
|
READ(b, tex4);
|
||||||
READ(b, unk0);
|
READ(b, LODs);
|
||||||
READ(b, unk1);
|
READ(b, unk1);
|
||||||
READ(b, unk2);
|
READ(b, unk2);
|
||||||
READ(b, unk3);
|
READ(b, unk3);
|
||||||
READ(b, size);
|
READ(b, size);
|
||||||
READ(b, unk4);
|
READ(b, unk4);
|
||||||
|
|
||||||
|
if (size == 0) // critical error!!! cannot survive
|
||||||
|
throw std::runtime_error("model file has bad block size field");
|
||||||
|
|
||||||
// data
|
// data
|
||||||
buffer data(b, size);
|
buffer data = buffer(b, size);
|
||||||
READ(data, n_segments);
|
|
||||||
segments.resize(n_segments);
|
// we cannot process this type at the moment
|
||||||
READ(data, header);
|
if (type == BlockType::ParticleEmitter)
|
||||||
READ(data, triangles_mult_7);
|
return;
|
||||||
|
|
||||||
|
READ(data, n_animations);
|
||||||
|
animations.resize(n_animations);
|
||||||
|
READ(data, material);
|
||||||
|
|
||||||
|
// unk
|
||||||
|
READ(data, unk_flags0);
|
||||||
|
READ(data, unk7);
|
||||||
|
READ(data, unk9);
|
||||||
READ(data, unk10);
|
READ(data, unk10);
|
||||||
|
READ(data, auto_animation);
|
||||||
|
READ(data, animation_cycle);
|
||||||
|
READ(data, unk8);
|
||||||
|
READ(data, unk11);
|
||||||
|
READ(data, unk12);
|
||||||
|
READ(data, triangles_mult_7);
|
||||||
|
//
|
||||||
|
|
||||||
|
READ(data, additional_params);
|
||||||
|
READ(data, n_damage_models);
|
||||||
|
damage_models.resize(n_damage_models);
|
||||||
|
READ(data, rot);
|
||||||
READ(data, flags);
|
READ(data, flags);
|
||||||
READ(data, n_vertex);
|
READ(data, n_vertex);
|
||||||
vertices.resize(n_vertex);
|
vertices.resize(n_vertex);
|
||||||
READ(data, n_triangles);
|
READ(data, n_triangles);
|
||||||
if (triangles_mult_7)
|
if (triangles_mult_7 && (flags & F_UNK0) && !unk11)
|
||||||
n_triangles *= 7;
|
n_triangles *= 7;
|
||||||
triangles.resize(n_triangles);
|
triangles.resize(n_triangles);
|
||||||
for (auto &v : vertices)
|
for (auto &v : vertices)
|
||||||
|
|
@ -100,76 +125,31 @@ void fragment::load(buffer &b)
|
||||||
for (auto &t : triangles)
|
for (auto &t : triangles)
|
||||||
READ(data, t);
|
READ(data, t);
|
||||||
|
|
||||||
// segments
|
// animations
|
||||||
for (auto &seg : segments)
|
for (auto &a : animations)
|
||||||
|
a.load(data);
|
||||||
|
for (auto &dm : damage_models)
|
||||||
|
dm.load(data);
|
||||||
|
|
||||||
|
if (!data.eof() && triangles_mult_7)
|
||||||
{
|
{
|
||||||
uint32_t type;
|
// unknown end of block
|
||||||
READ(data, type);
|
auto triangles2 = triangles;
|
||||||
switch (type)
|
triangles2.resize((data.getSize() - data.getIndex()) / sizeof(triangle));
|
||||||
{
|
for (auto &t : triangles2)
|
||||||
case 1:
|
READ(data, t);
|
||||||
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->load(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data.eof())
|
if (!data.eof())
|
||||||
throw std::logic_error("extraction error: fragment #" + std::string(name0));
|
throw std::logic_error("extraction error: block #" + std::string(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
void segment1::load(buffer &b)
|
void damage_model::load(buffer &b)
|
||||||
{
|
{
|
||||||
READ(b, name);
|
READ(b, n_polygons);
|
||||||
READ(b, unk0);
|
polygons.resize(n_polygons);
|
||||||
triangles.resize(unk0[0][0]);
|
|
||||||
unk1.resize(unk0[0][0]);
|
|
||||||
for (int i = 0; i < 2; i++)
|
|
||||||
{
|
|
||||||
for (auto &t : triangles)
|
|
||||||
READ(b, t);
|
|
||||||
for (auto &unk: unk1)
|
|
||||||
READ(b, unk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void segment2::load(buffer &b)
|
|
||||||
{
|
|
||||||
READ(b, name);
|
|
||||||
READ(b, unk0);
|
|
||||||
triangles.resize(unk0[0][0]);
|
|
||||||
unk1.resize(unk0[0][0]);
|
|
||||||
unk1_1.resize(unk0[0][0]);
|
|
||||||
for (auto &t : triangles)
|
|
||||||
READ(b, t);
|
|
||||||
for (auto &unk : unk1)
|
|
||||||
READ(b, unk);
|
|
||||||
for (auto &unk : unk1_1)
|
|
||||||
READ(b, unk);
|
|
||||||
while (!b.eof())
|
|
||||||
{
|
|
||||||
repeater r;
|
|
||||||
r.load(b);
|
|
||||||
unk2.push_back(r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void segment2::repeater::load(buffer &b)
|
|
||||||
{
|
|
||||||
READ(b, unk2);
|
|
||||||
triangles2.resize(unk2);
|
|
||||||
READ(b, unk8);
|
READ(b, unk8);
|
||||||
READ(b, unk3);
|
READ(b, name);
|
||||||
for (auto &t : triangles2)
|
for (auto &t : polygons)
|
||||||
READ(b, t);
|
READ(b, t);
|
||||||
READ(b, unk6);
|
READ(b, unk6);
|
||||||
READ(b, flags);
|
READ(b, flags);
|
||||||
|
|
@ -183,60 +163,87 @@ void segment2::repeater::load(buffer &b)
|
||||||
READ(b, t);
|
READ(b, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
void segment6::load(buffer &b)
|
void animation::load(buffer &b)
|
||||||
{
|
{
|
||||||
|
READ(b, type);
|
||||||
READ(b, name);
|
READ(b, name);
|
||||||
|
for (auto &s : segments)
|
||||||
|
s.loadHeader(b);
|
||||||
|
if (segments[0].n)
|
||||||
|
for (auto &s : segments)
|
||||||
|
s.loadData(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void animation::segment::loadHeader(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, n);
|
||||||
READ(b, unk0);
|
READ(b, unk0);
|
||||||
triangles.resize(unk0[0][0]);
|
READ(b, unk1);
|
||||||
for (int i = 0; i < 1; i++)
|
}
|
||||||
|
|
||||||
|
void animation::segment::loadData(buffer &b)
|
||||||
|
{
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
if (unk0)
|
||||||
{
|
{
|
||||||
|
triangles.resize(n);
|
||||||
for (auto &t : triangles)
|
for (auto &t : triangles)
|
||||||
READ(b, t);
|
READ(b, t);
|
||||||
char unk1[0x30]; // some 6 floats
|
|
||||||
for (int i = 0; i < unk0[0][0]; i++)
|
|
||||||
READ(b, unk1);
|
|
||||||
}
|
}
|
||||||
|
unk2.resize(n);
|
||||||
|
for (auto &unk : unk2)
|
||||||
|
READ(b, unk);
|
||||||
}
|
}
|
||||||
|
|
||||||
void model::load(buffer &b)
|
void model::load(buffer &b)
|
||||||
{
|
{
|
||||||
READ(b, n_fragments);
|
READ(b, n_blocks);
|
||||||
|
if (n_blocks > 1000) // probably bad file
|
||||||
|
throw std::runtime_error("Model file has bad block count (should be <= 1000). Probably not a model.");
|
||||||
READ(b, header);
|
READ(b, header);
|
||||||
fragments.resize(n_fragments);
|
blocks.resize(n_blocks);
|
||||||
for (auto &f : fragments)
|
for (auto &f : blocks)
|
||||||
f.load(b);
|
f.load(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void model::writeObj(std::string fn)
|
void model::writeObj(std::string fn)
|
||||||
{
|
{
|
||||||
ofstream o(fn);
|
for (auto &f : blocks)
|
||||||
o << "# " << "\n";
|
|
||||||
o << "# A.I.M. Model Converter (ver. " << version() << ")\n";
|
|
||||||
o << "# " << "\n";
|
|
||||||
o << "\n";
|
|
||||||
|
|
||||||
if (fragments.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
const auto &f = fragments[0];
|
|
||||||
for (auto &v : f.vertices)
|
|
||||||
o << v.printVertex() << "\n";
|
|
||||||
o << "\n";
|
|
||||||
for (auto &v : f.vertices)
|
|
||||||
o << v.printNormal() << "\n";
|
|
||||||
o << "\n";
|
|
||||||
for (auto &v : f.vertices)
|
|
||||||
o << v.printTex() << "\n";
|
|
||||||
o << "\n";
|
|
||||||
|
|
||||||
for (int i = 0; i <= f.n_triangles - 3; i += 3)
|
|
||||||
{
|
{
|
||||||
auto x = to_string(f.triangles[i] + 1);
|
ofstream o(fn + "." + f.name + ".obj");
|
||||||
auto y = to_string(f.triangles[i + 2] + 1);
|
o << "#" << "\n";
|
||||||
auto z = to_string(f.triangles[i + 1] + 1);
|
o << "# A.I.M. Model Converter (ver. " << version() << ")\n";
|
||||||
x += "/" + x;
|
o << "#" << "\n";
|
||||||
y += "/" + y;
|
o << "\n";
|
||||||
z += "/" + z;
|
o << "o " << f.name << "\n";
|
||||||
o << "f " << x << " " << y << " " << z << "\n";
|
o << "g " << f.name << "\n";
|
||||||
|
o << "s off\n";
|
||||||
|
o << "\n";
|
||||||
|
|
||||||
|
for (auto &v : f.vertices)
|
||||||
|
o << v.printVertex() << "\n";
|
||||||
|
o << "\n";
|
||||||
|
for (auto &v : f.vertices)
|
||||||
|
o << v.printNormal() << "\n";
|
||||||
|
o << "\n";
|
||||||
|
for (auto &v : f.vertices)
|
||||||
|
o << v.printTex() << "\n";
|
||||||
|
o << "\n";
|
||||||
|
|
||||||
|
if (f.n_triangles)
|
||||||
|
for (int i = 0; i <= f.n_triangles - 3; i += 3)
|
||||||
|
{
|
||||||
|
auto x = to_string(f.triangles[i] + 1);
|
||||||
|
auto y = to_string(f.triangles[i + 2] + 1);
|
||||||
|
auto z = to_string(f.triangles[i + 1] + 1);
|
||||||
|
x += "/" + x;
|
||||||
|
y += "/" + y;
|
||||||
|
z += "/" + z;
|
||||||
|
o << "f " << x << " " << y << " " << z << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
o << "\n";
|
||||||
|
o << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,38 @@ class buffer;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
F_WIND = 0x4,
|
F_UNK0 = 0x4,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class AdditionalParameter : uint32_t
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
DetalizationCoefficient
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ModelRotation : uint32_t
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Vertical,
|
||||||
|
Horizontal,
|
||||||
|
Other
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class BlockType : uint32_t
|
||||||
|
{
|
||||||
|
VisibleObject,
|
||||||
|
HelperObject,
|
||||||
|
BitmapAlpha,
|
||||||
|
BitmapGrass,
|
||||||
|
ParticleEmitter
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Vector4
|
||||||
|
{
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
float w;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vertex
|
struct vertex
|
||||||
|
|
@ -35,7 +66,7 @@ struct vertex
|
||||||
float vZ;
|
float vZ;
|
||||||
float vY;
|
float vY;
|
||||||
|
|
||||||
float wind;
|
float unk0;
|
||||||
|
|
||||||
float nX;
|
float nX;
|
||||||
float nZ;
|
float nZ;
|
||||||
|
|
@ -53,76 +84,96 @@ struct vertex
|
||||||
|
|
||||||
typedef uint16_t triangle;
|
typedef uint16_t triangle;
|
||||||
|
|
||||||
struct unk_float3x4
|
struct animation
|
||||||
{
|
{
|
||||||
float unk[4][3];
|
// +1 +0.5 -0.5 +1
|
||||||
};
|
struct segment
|
||||||
|
|
||||||
struct unk_float6
|
|
||||||
{
|
|
||||||
float unk[6];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct segment
|
|
||||||
{
|
|
||||||
uint32_t type;
|
|
||||||
|
|
||||||
virtual void load(buffer &b) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct segment1 : public segment
|
|
||||||
{
|
|
||||||
char name[0xC];
|
|
||||||
uint32_t unk0[4][3];
|
|
||||||
std::vector<triangle> triangles;
|
|
||||||
std::vector<unk_float3x4> unk1;
|
|
||||||
|
|
||||||
virtual void load(buffer &b);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct segment2 : public segment
|
|
||||||
{
|
|
||||||
struct repeater
|
|
||||||
{
|
{
|
||||||
uint32_t unk2;
|
struct unk_float6
|
||||||
float unk8[3];
|
{
|
||||||
char unk3[0x3C];
|
float unk[6];
|
||||||
std::vector<uint16_t> triangles2;
|
};
|
||||||
uint8_t unk6;
|
|
||||||
uint32_t flags;
|
uint32_t n;
|
||||||
uint32_t n_vertex;
|
uint32_t unk0;
|
||||||
uint32_t n_triangles;
|
uint32_t unk1;
|
||||||
std::vector<vertex> vertices;
|
|
||||||
std::vector<uint16_t> triangles;
|
std::vector<triangle> triangles;
|
||||||
|
std::vector<unk_float6> unk2;
|
||||||
virtual void load(buffer &b);
|
|
||||||
|
void loadHeader(buffer &b);
|
||||||
|
void loadData(buffer &b);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
uint32_t type;
|
||||||
char name[0xC];
|
char name[0xC];
|
||||||
uint32_t unk0[4][3];
|
segment segments[4];
|
||||||
std::vector<triangle> triangles;
|
|
||||||
std::vector<unk_float6> unk1;
|
|
||||||
std::vector<unk_float6> unk1_1;
|
|
||||||
std::vector<repeater> unk2;
|
|
||||||
|
|
||||||
virtual void load(buffer &b);
|
virtual void load(buffer &b);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct segment6 : public segment1
|
struct damage_model
|
||||||
{
|
{
|
||||||
|
uint32_t n_polygons;
|
||||||
|
float unk8[3];
|
||||||
|
char name[0x3C];
|
||||||
|
std::vector<uint16_t> polygons;
|
||||||
|
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 load(buffer &b);
|
virtual void load(buffer &b);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fragment
|
struct material
|
||||||
|
{
|
||||||
|
Vector4 ambient;
|
||||||
|
Vector4 diffuse;
|
||||||
|
Vector4 specular;
|
||||||
|
Vector4 emissive;
|
||||||
|
float power;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rotation
|
||||||
|
{
|
||||||
|
ModelRotation type;
|
||||||
|
float speed;
|
||||||
|
// center of rotating axis
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct additional_parameters
|
||||||
|
{
|
||||||
|
AdditionalParameter params;
|
||||||
|
float detalization_koef;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct block
|
||||||
{
|
{
|
||||||
// header
|
// header
|
||||||
uint32_t type;
|
BlockType type;
|
||||||
char name0[0x20];
|
char name[0x20];
|
||||||
char name1[0x20];
|
char tex_mask[0x20];
|
||||||
char name2[0x20];
|
char tex_spec[0x20];
|
||||||
char name3[0x20];
|
char tex3[0x20];
|
||||||
char name4[0x20];
|
char tex4[0x20];
|
||||||
uint32_t unk0;
|
union // LODs
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint8_t lod1 : 1;
|
||||||
|
uint8_t lod2 : 1;
|
||||||
|
uint8_t lod3 : 1;
|
||||||
|
uint8_t lod4 : 1;
|
||||||
|
uint8_t : 4;
|
||||||
|
} _;
|
||||||
|
uint32_t LODs;
|
||||||
|
};
|
||||||
uint32_t unk1;
|
uint32_t unk1;
|
||||||
uint32_t unk2[2];
|
uint32_t unk2[2];
|
||||||
uint32_t unk3;
|
uint32_t unk3;
|
||||||
|
|
@ -130,27 +181,43 @@ struct fragment
|
||||||
uint32_t unk4[10];
|
uint32_t unk4[10];
|
||||||
|
|
||||||
// data
|
// data
|
||||||
uint32_t n_segments;
|
uint32_t n_animations;
|
||||||
char header[0x68];
|
material material;
|
||||||
|
|
||||||
|
//unk (anim + transform settings?)
|
||||||
|
uint32_t unk_flags0;
|
||||||
|
uint32_t unk7;
|
||||||
|
float unk9;
|
||||||
|
uint32_t unk10;
|
||||||
|
uint32_t auto_animation;
|
||||||
|
float animation_cycle;
|
||||||
|
float unk8;
|
||||||
|
uint32_t unk11;
|
||||||
|
uint32_t unk12;
|
||||||
uint32_t triangles_mult_7;
|
uint32_t triangles_mult_7;
|
||||||
char unk10[0x20];
|
//
|
||||||
|
|
||||||
|
additional_parameters additional_params;
|
||||||
|
uint32_t n_damage_models;
|
||||||
|
rotation rot;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
uint32_t n_vertex;
|
uint32_t n_vertex;
|
||||||
uint32_t n_triangles;
|
uint32_t n_triangles;
|
||||||
std::vector<vertex> vertices;
|
std::vector<vertex> vertices;
|
||||||
std::vector<uint16_t> triangles;
|
std::vector<uint16_t> triangles;
|
||||||
|
|
||||||
// segments
|
// animations
|
||||||
std::vector<segment *> segments;
|
std::vector<animation> animations;
|
||||||
|
std::vector<damage_model> damage_models;
|
||||||
|
|
||||||
void load(buffer &b);
|
void load(buffer &b);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct model
|
struct model
|
||||||
{
|
{
|
||||||
int n_fragments;
|
int n_blocks;
|
||||||
char header[0x40];
|
char header[0x40];
|
||||||
std::vector<fragment> fragments;
|
std::vector<block> blocks;
|
||||||
|
|
||||||
void load(buffer &b);
|
void load(buffer &b);
|
||||||
void writeObj(std::string fn);
|
void writeObj(std::string fn);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue