mirror of
https://github.com/aimrebirth/tools.git
synced 2026-04-14 17:33:25 +00:00
191 lines
4.1 KiB
C++
191 lines
4.1 KiB
C++
/*
|
|
* 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));
|
|
}
|
|
}
|