/* * 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 . */ #include "model.h" #include #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)); } }