ACE3/extensions/common/p3d/model.cpp

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;
}
}
}