#include "anime_loader.hpp" using ::basalt::shared::math::FloatPoint; namespace basalt::shared::anime_loader { #pragma region Anime Loader IAnimeLoader::IAnimeLoader() : status(AnimeLoaderStatus::Ready), time(0), last_index(0) {} IAnimeLoader::~IAnimeLoader() {} void IAnimeLoader::load() { if (this->status != AnimeLoaderStatus::Ready) throw std::runtime_error("unexpected anime loader status"); // load by user internal_load(); // check empty if (this->frames.empty()) throw std::runtime_error("no anime key frames."); // Get last frame index auto last_pair = this->frames.end(); --last_pair; this->last_index = last_pair->first; // change status this->status = AnimeLoaderStatus::Loaded; } KeyFrameSpan IAnimeLoader::tick() { if (this->status != AnimeLoaderStatus::Loaded) throw std::runtime_error("unexpected anime loader status"); // Accumulate time ++this->time; if (this->time > this->last_index) { this->time = 0; } // 首先用lower_bound获取到不小于自身的项目(肯定能获取到) auto lower_bound = this->frames.lower_bound(this->time); // 获取下一帧,如果没有下一帧,就转换为自身 auto upper_bound = lower_bound; ++upper_bound; if (upper_bound == this->frames.end()) { upper_bound = lower_bound; } // 计算归一化时间 FloatPoint next_time = static_cast(this->time - lower_bound->first) / static_cast(upper_bound->first - lower_bound->first + 1); FloatPoint prev_time = static_cast(1) - next_time; // 返回结构 return KeyFrameSpan{ .prev_time = prev_time, .next_time = next_time, .prev_position = lower_bound->second.position, .next_position = upper_bound->second.position, .prev_rotation = lower_bound->second.rotation, .next_rotation = upper_bound->second.rotation, }; } void IAnimeLoader::internal_load() { throw std::logic_error("unimplemented function"); } #pragma endregion } // namespace basalt::shared::anime_loader