#pragma once #include "assets.hpp" #include "renderer.hpp" #include "physics.hpp" namespace TSR { class Skeleton : public Asset { std::vector m_bones; public: Skeleton(const std::string& name); const std::vector& Bones() const { return m_bones; } int GetBoneIdByName(const std::string& name) const; }; class SkAnim : public Asset { std::vector m_channels; size_t m_duration; float m_tps; public: SkAnim(const std::string& name); const std::vector& Channels() const { return m_channels; } size_t Duration() const { return m_duration; } float TPS() const { return m_tps; } }; struct Animation { AssetPtr skel; std::vector bone_ids; float duration; float tps; bool is_cyclic; /* events */ }; typedef int AnimationId; typedef int PartId; enum ModelShape { SHAPE_NONE, SHAPE_TRIANGLE_MESH, SHAPE_BOX, SHAPE_COUNT }; class Model : public Asset { AssetPtr m_skeleton; std::vector m_parts; std::map m_part_names; std::vector m_animations; std::map m_anim_names; ModelShape m_shape; AssetPtr m_trimesh; glm::vec3 m_shape_offset; glm::vec3 m_shape_size; public: Model(const std::string& name); Model(const Model&) = delete; Model(Model&&) = delete; void Draw(Renderer& renderer_ref, const DrawCtx* draw_context_ptr) const { for (const auto& part : m_parts) renderer_ref.Add(DrawRef(&part, draw_context_ptr)); } void DrawInstanced(Renderer& renderer_ref, const DrawCtx* draw_context_ptr) const { for (const auto& part : m_parts) renderer_ref.AddInstanced(DrawRef(&part, draw_context_ptr)); } const Skeleton& GetSkeleton() const { return *m_skeleton; } int GetAnimId(const std::string& name) { return m_anim_names.at(name); } const Animation& GetAnim(int id) { return m_animations[id]; } bool IsSkeletal() const { return m_skeleton.get() != nullptr; } bool HasAnimations() const { return m_animations.size() > 0; } ModelShape Shape() const { return m_shape; } const glm::vec3& ShapeOffset() const { return m_shape_offset; } const glm::vec3& ShapeSize() const { return m_shape_size; } const PhysicsTriangleMesh& TriMesh() const { return *m_trimesh; } }; }