mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
117 lines
5.0 KiB
C++
117 lines
5.0 KiB
C++
#include "p3d/model.hpp"
|
|
|
|
#include "read_helpers.hpp"
|
|
|
|
namespace ace {
|
|
namespace p3d {
|
|
model::model() : skeleton(nullptr), info(nullptr), useFaceDefaults(nullptr) {}
|
|
model::model(std::istream &stream_, const std::string &filename_) {
|
|
filename = filename_;
|
|
|
|
// get the full file size
|
|
stream_.seekg(0, std::ios::end);
|
|
size = stream_.tellg();
|
|
stream_.seekg(0, std::ios::beg);
|
|
|
|
// Parse header here
|
|
stream_.read((char *)&filetype, sizeof(uint32_t));
|
|
stream_.read((char *)&version, sizeof(uint64_t));
|
|
if (version >= 48) {
|
|
READ_STRING(prefix_name);
|
|
}
|
|
|
|
stream_.read((char *)&lod_count, sizeof(uint32_t));
|
|
|
|
// parse model info here
|
|
info = std::make_shared<model_info>(stream_, lod_count);
|
|
skeleton = info->skeleton;
|
|
|
|
READ_BOOL(has_animations);
|
|
if (has_animations) {
|
|
uint32_t animation_count = 0;
|
|
stream_.read((char *)&animation_count, sizeof(uint32_t));
|
|
for (int x = 0; x < animation_count; x++) {
|
|
animations.push_back(std::make_shared<animation>(stream_, version));
|
|
}
|
|
|
|
|
|
// Now we re-walk, and association animations and bones
|
|
uint32_t bone_count, local_lod_count;
|
|
stream_.read((char *)&local_lod_count, sizeof(uint32_t));
|
|
for (int lod = 0; lod < local_lod_count; lod++) {
|
|
stream_.read((char *)&bone_count, sizeof(uint32_t));
|
|
std::vector<uint32_t> lod_bone2anim;
|
|
for (int x = 0; x < bone_count; x++) {
|
|
uint32_t anim_count;
|
|
stream_.read((char *)&anim_count, sizeof(uint32_t));
|
|
|
|
for (int anim = 0; anim < anim_count; anim++) {
|
|
uint32_t anim_index;
|
|
stream_.read((char *)&anim_index, sizeof(uint32_t));
|
|
if(std::find(skeleton->all_bones[x]->animations.begin(), skeleton->all_bones[x]->animations.end(), anim_index) == skeleton->all_bones[x]->animations.end()) {
|
|
skeleton->all_bones[x]->animations.push_back(anim_index);
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
// Anims2Bones
|
|
for (int lod = 0; lod < lod_count; lod++) {
|
|
for (animation_p & anim : animations) {
|
|
animate_bone_p next = std::make_shared<animate_bone>();
|
|
next->lod = lod;
|
|
stream_.read((char *)&next->index, sizeof(int32_t));
|
|
if (next->index != -1 && anim->type != 8 && anim->type != 9) {
|
|
next->axis_position = ace::vector3<float>(stream_);
|
|
next->axis_direction = ace::vector3<float>(stream_);
|
|
}
|
|
anim->bones.push_back(next);
|
|
}
|
|
}
|
|
}
|
|
// LOD indexes
|
|
for (int lod = 0; lod < lod_count; lod++) {
|
|
uint32_t offset;
|
|
stream_.read((char *)&offset, sizeof(uint32_t));
|
|
start_lod.push_back(offset);
|
|
LOG(DEBUG) << "LOD Offset: #" << lod << " : " << offset;
|
|
}
|
|
for (int lod = 0; lod < lod_count; lod++) {
|
|
uint32_t offset;
|
|
stream_.read((char *)&offset, sizeof(uint32_t));
|
|
end_lod.push_back(offset);
|
|
LOG(DEBUG) << "LOD Offset: #" << lod << " : " << offset;
|
|
}
|
|
|
|
// Attempt to read the faces?
|
|
useFaceDefaults = new bool[lod_count];
|
|
for (int lod = 0; lod < lod_count; lod++) {
|
|
READ_BOOL(useFaceDefaults[lod]);
|
|
}
|
|
for (int x = 0; x < lod_count; x++) {
|
|
if (!useFaceDefaults[x]) {
|
|
face_settings tface(stream_); // @TODO: we dont save these because WHY!?
|
|
}
|
|
}
|
|
|
|
for (int lod = 0; lod < lod_count; lod++) {
|
|
char buffer[64];
|
|
#ifdef _DEBUG
|
|
sprintf_s(buffer, "\t\t%08X", info->resolutions[lod]);
|
|
LOG(DEBUG) << "LOD #" << lod << ", type: " << buffer;
|
|
#endif
|
|
//if (info->resolutions[lod] == LOD_TYPE_GEOMETRY_FIRE) {
|
|
// LOG(DEBUG) << "Found a desired geometry";
|
|
stream_.clear();
|
|
stream_.seekg(start_lod[lod], stream_.beg);
|
|
lods.push_back(std::make_shared<ace::p3d::lod>(stream_, lod, version));
|
|
//}
|
|
}
|
|
}
|
|
model::~model() {
|
|
if(useFaceDefaults)
|
|
delete[] useFaceDefaults;
|
|
}
|
|
}
|
|
}
|