#pragma once #include #include "Runtime/CFactoryMgr.hpp" #include "Runtime/Character/CSegId.hpp" #include "Runtime/Graphics/CCubeModel.hpp" #include "Runtime/RetroTypes.hpp" #include namespace metaforce { class CCharLayoutInfo; class CPoseAsTransforms; class CModel; struct SSkinWeighting { CSegId x0_id; float x4_weight; explicit SSkinWeighting(CInputStream& in) : x0_id(in), x4_weight(in.ReadFloat()) {} }; class CVirtualBone { friend class CSkinnedModel; rstl::reserved_vector x0_weights; u32 x1c_vertexCount; zeus::CTransform x20_xf; zeus::CMatrix3f x50_rotation; public: explicit CVirtualBone(CInputStream& in); void BuildPoints(const zeus::CVector3f* in, TVectorRef out, u32 count) const; void BuildNormals(const zeus::CVector3f* in, TVectorRef out, u32 count) const; void BuildAccumulatedTransform(const CPoseAsTransforms& pose, const zeus::CVector3f* points); [[nodiscard]] const auto& GetWeights() const { return x0_weights; } [[nodiscard]] u32 GetVertexCount() const { return x1c_vertexCount; } private: void BuildFinalPosMatrix(const CPoseAsTransforms& pose, const zeus::CVector3f* points); }; class CSkinRules { friend class CSkinnedModel; std::vector x0_bones; u32 x10_vertexCount = 0; u32 x14_normalCount = 0; public: explicit CSkinRules(CInputStream& in); void BuildPoints(TConstVectorRef positions, TVectorRef out); void BuildNormals(TConstVectorRef normals, TVectorRef out); void BuildAccumulatedTransforms(const CPoseAsTransforms& pose, const CCharLayoutInfo& info); [[nodiscard]] u32 GetVertexCount() const { return x10_vertexCount; } [[nodiscard]] u32 GetNormalCount() const { return x14_normalCount; } }; CFactoryFnReturn FSkinRulesFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& params, CObjectReference* selfRef); } // namespace metaforce