#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(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(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 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(); 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(stream_); next->axis_direction = ace::vector3(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(stream_, lod, version)); //} } } model::~model() { if(useFaceDefaults) delete[] useFaceDefaults; } } }