// // Created by martin on 12.11.21. // #ifndef ANIMTESTBED_SKINNEDMESH_H #define ANIMTESTBED_SKINNEDMESH_H // ozz-animation headers #include // fmodf #include // std::unique_ptr, std::make_unique #include "ozz/animation/runtime/animation.h" #include "ozz/animation/runtime/local_to_model_job.h" #include "ozz/animation/runtime/sampling_job.h" #include "ozz/animation/runtime/skeleton.h" #include "ozz/base/containers/vector.h" #include "ozz/base/io/archive.h" #include "ozz/base/io/stream.h" #include "ozz/base/log.h" #include "ozz/base/maths/soa_transform.h" #include "ozz/base/maths/vec_float.h" constexpr int cSyncTrackMaxIntervals = 8; struct SyncTrack { float m_duration; int m_num_intervals; float m_interval_durations[cSyncTrackMaxIntervals]; float CalcSyncFromAbsTime (float abs_time) { float sync_time = fmodf (abs_time, m_duration) / m_duration; int interval_index = 0; while (sync_time >= m_interval_durations[interval_index]) { sync_time -= m_interval_durations[interval_index]; interval_index ++; } return float(interval_index) + sync_time / m_interval_durations[interval_index]; } float CalcRatioFromSyncTime (float sync_time) { float interval_ratio = fmodf(sync_time, 1.0f); int interval = int(sync_time - interval_ratio); float result = 0.f; int i = 0; while (i < interval) { result += m_interval_durations[i]; i++; } result += m_interval_durations[i] * interval_ratio; return result; } static SyncTrack Blend(float weight, const SyncTrack& track_A, const SyncTrack& track_B) { SyncTrack result; assert (track_A.m_num_intervals == track_B.m_num_intervals); result.m_num_intervals = track_A.m_num_intervals; result.m_duration = (1.0f - weight) * track_A.m_duration + weight * track_B.m_duration; for (int i = 0; i < result.m_num_intervals; i++) { result.m_interval_durations[i] = (1.0f - weight) * track_A.m_interval_durations[i] + weight * track_B.m_interval_durations[i]; } return result; } }; struct SkinnedMesh { virtual ~SkinnedMesh(); bool LoadSkeleton(const char* filename); bool LoadAnimation(const char* filename); //bool LoadMesh (const char* filename); void SetCurrentAnimation(int index); const ozz::animation::Animation* GetCurrentAnimation() {return m_current_animation; }; float GetCurrentAnimationDuration() {return m_current_animation->duration(); }; void EvalAnimation(float in_time); void DrawSkeleton(); void DrawJoint(int joint_index, int parent_joint_index); void DrawDebugUi(); // void DrawSkinnedMesh(); ozz::vector m_animations; std::vector m_animation_names; std::vector m_animation_sync_track; ozz::animation::Skeleton m_skeleton; ozz::animation::Animation* m_current_animation; ozz::animation::SamplingCache m_cache; ozz::vector m_local_matrices; ozz::vector m_model_matrices; }; #endif //ANIMTESTBED_SKINNEDMESH_H