#pragma once #include #include #include #include #include "Runtime/CToken.hpp" #include "Runtime/Character/CSkinRules.hpp" #include "Runtime/Graphics/CModel.hpp" #include namespace metaforce { class CCharLayoutInfo; class CModel; class CPoseAsTransforms; class CVertexMorphEffect; class IObjectStore; // Lambda instead of userdata pointer using FCustomDraw = std::function; class CSkinnedModel { TLockedToken x4_model; TLockedToken x10_skinRules; TLockedToken x1c_layoutInfo; std::vector x24_vertWorkspace; // was rstl::auto_ptr std::vector x2c_normalWorkspace; // was rstl::auto_ptr bool x34_owned = true; bool x35_disableWorkspaces = false; public: enum class EDataOwnership { Unowned, Owned }; CSkinnedModel(const TLockedToken& model, const TLockedToken& skinRules, const TLockedToken& layoutInfo /*, EDataOwnership ownership*/); CSkinnedModel(IObjectStore& store, CAssetId model, CAssetId skinRules, CAssetId layoutInfo); TLockedToken& GetModel() { return x4_model; } const TLockedToken& GetModel() const { return x4_model; } const TLockedToken& GetSkinRules() const { return x10_skinRules; } void SetLayoutInfo(const TLockedToken& inf) { x1c_layoutInfo = inf; } const TLockedToken& GetLayoutInfo() const { return x1c_layoutInfo; } void Calculate(const CPoseAsTransforms& pose, const CModelFlags& drawFlags, const std::optional& morphEffect, const float* morphMagnitudes); void Draw(TVectorRef verts, TVectorRef normals, const CModelFlags& drawFlags); void Draw(const CModelFlags& drawFlags); void DoDrawCallback(const FCustomDraw& func) const; using FPointGenerator = void (*)(void* item, const std::vector>& vn); static void SetPointGeneratorFunc(void* ctx, FPointGenerator func) { g_PointGenFunc = func; g_PointGenCtx = ctx; } static void ClearPointGeneratorFunc() { g_PointGenFunc = nullptr; } static FPointGenerator g_PointGenFunc; static void* g_PointGenCtx; }; class CMorphableSkinnedModel : public CSkinnedModel { std::unique_ptr x40_morphMagnitudes; public: CMorphableSkinnedModel(IObjectStore& store, CAssetId model, CAssetId skinRules, CAssetId layoutInfo); const float* GetMorphMagnitudes() const { return x40_morphMagnitudes.get(); } }; } // namespace metaforce