Polyphase Game Engine
Loading...
Searching...
No Matches
SkeletalMesh3d.h
Go to the documentation of this file.
1#pragma once
2
3#include "Nodes/3D/Mesh3d.h"
4#include "AssetRef.h"
5#include "Vertex.h"
6// std::vector<Animation> mBoundExternalAnims below needs the full Animation
7// type, so we can't fall back on the forward declarations the file used to
8// rely on for AnimEvent / Channel / Animation.
10
11class BoneMaskAsset;
12
14{
15 One,
16 Four,
17 Num
18};
19
28
29// How a slot's animation contributes to the per-bone blend.
30// Replace : standard weighted lerp into the accumulator (default).
31// Additive: the slot's pose is interpreted as a delta from bind pose;
32// that delta is scaled by mWeight and composed on top of the
33// accumulator. Used for hit reactions, recoil, breathing,
34// lean-into-turn — anything you want to layer on a base anim.
35enum class AnimLayerMode
36{
37 Replace,
39
40 Count
41};
42
43class SkeletalMesh;
44struct AnimEvent;
45struct Channel;
46struct Animation;
47
49{
50 std::string mName;
51 float mTime = 0.0f;
52 float mSpeed = 1.0f;
53 float mWeight = 0.0f;
54 int32_t mSlot = 0;
55 bool mLoop = false;
56
57 // Optional bone mask. When valid, only bones marked in the mask's
58 // resolved bitset receive this slot's contribution; the rest stay at
59 // whatever the lower slots (or bind pose) provided.
61
62 // Weight fade. Engaged when mWeightFadeRate != 0; on each tick mWeight
63 // advances toward mWeightTarget by mWeightFadeRate * dt and clamps. When
64 // the target is 0 and reached, the slot self-removes.
65 float mWeightTarget = -1.0f;
66 float mWeightFadeRate = 0.0f;
67
69};
70
72{
73 std::string mName;
74 std::string mDependentAnim;
75 float mTime = 0.0f;
76 float mSpeed = 1.0f;;
77 float mWeight = 0.0f;
78 bool mLoop = false;
79 int32_t mSlot = -1;
80};
81
82typedef void(*AnimEventHandlerFP)(const AnimEvent& animEvent);
83
84// Local, decomposed (TRS) bone pose shared between SkeletalMesh3D's animation
85// blend loop and any registered ISkeletalPoseModifier. Kept in the public header
86// so native addons (e.g. the procedural-rig / jiggle-bones addon) can read and
87// mutate the animated local pose after blending and before it is composed into
88// bone matrices. Field layout must stay in sync with the file-local
89// DecompTransform alias in SkeletalMesh3d.cpp.
91{
92 glm::vec3 mPosition = { 0.0f, 0.0f, 0.0f };
93 glm::quat mRotation = { 0.0f, 0.0f, 0.0f, 1.0f };
94 glm::vec3 mScale = { 1.0f, 1.0f, 1.0f };
95 bool mValid = false;
96};
97
98// Hook for procedural pose layers (spring / jiggle bones, spline IK, ...) that
99// run AFTER animation blending / masking / additive layering and BEFORE the
100// local pose is finalized into bone matrices. Implementers modify the decomposed
101// local pose in place; they must never touch finalized skinning matrices.
102// Register/unregister on the target mesh via SkeletalMesh3D::RegisterPoseModifier.
104{
105public:
106 virtual ~ISkeletalPoseModifier() = default;
107
108 virtual void ModifySkeletalPose(
109 class SkeletalMesh3D* component,
110 class SkeletalMesh* mesh,
111 std::vector<SkeletalLocalPoseTransform>& localPose,
112 float deltaTime) = 0;
113};
114
116{
117public:
118
120
123
124 virtual const char* GetTypeName() const override;
125 virtual void GatherProperties(std::vector<Property>& outProps) override;
126
127 virtual void Create() override;
128 virtual void Destroy() override;
129 SkeletalMeshCompResource* GetResource();
130
131 virtual void Tick(float deltaTime) override;
132 virtual void EditorTick(float deltaTime) override;
133
134 virtual bool IsStaticMesh3D() const override;
135 virtual bool IsSkeletalMesh3D() const override;
136
137 void SetSkeletalMesh(SkeletalMesh* skeletalMesh);
138 SkeletalMesh* GetSkeletalMesh();
139
140 void PlayAnimation(const char* animName, bool loop, float speed = 1.0f, float weight = 1.0f, int32_t priority = -1);
141 // Start `animName` on `slot`, restricted to the bones marked by `mask`.
142 // mask=nullptr is equivalent to PlayAnimation (full body). The slot's
143 // weight is the maximum contribution against lower slots; weight=1 and
144 // mask=UpperBody means upper-body bones are 100% driven by this clip
145 // while lower bones stay on whatever slot 0 (or bind pose) provided.
146 void PlayAnimationMasked(const char* animName, int32_t slot, BoneMaskAsset* mask,
147 bool loop, float speed = 1.0f, float weight = 1.0f);
148 // Start `animName` on `slot` as an additive layer — the slot's pose is
149 // interpreted as a delta from bind pose and composed on top of lower
150 // slots. Mask gates which bones receive the delta. Use for hit reactions,
151 // recoil, breathing, lean-into-turn over a base run/idle.
152 void PlayAnimationAdditive(const char* animName, int32_t slot, BoneMaskAsset* mask,
153 bool loop, float speed = 1.0f, float weight = 1.0f);
154 // Replace the bone mask on an already-playing slot. Pass nullptr to clear.
155 void SetSlotMask(int32_t slot, BoneMaskAsset* mask);
156 void SetSlotLayerMode(int32_t slot, AnimLayerMode mode);
157 // Snap a slot's weight without easing. Clamped to [0, 1].
158 void SetSlotWeight(int32_t slot, float weight);
159 // Fade a slot's weight from its current value to `targetWeight` over
160 // `seconds` (linear). If targetWeight == 0 and the fade completes, the
161 // slot self-removes.
162 void FadeSlotWeight(int32_t slot, float targetWeight, float seconds);
163 void QueueAnimation(const char* animName, bool loop, const char* targetAnim = nullptr, float speed = 1.0f, float weight = 1.0f, int32_t priority = -1);
164 void StopAnimation(const char* animName, bool cancelQueued = false);
165 void StopAllAnimations(bool cancelQueued = false);
166 void CancelQueuedAnimation(const char* animName);
167 void CancelAllQueuedAnimations();
168 bool IsAnimationPlaying(const char* animName);
169 void ResetAnimation();
170 float GetAnimationSpeed() const;
171 void SetAnimationSpeed(float speed);
172
173 void SetAnimationPaused(bool paused);
174 bool IsAnimationPaused() const;
175
176 void SetInheritPose(bool inherit);
177 bool IsInheritPoseEnabled() const;
178
179 void SetBoundsRadiusOverride(float radius);
180 float GetBoundsRadiusOverride() const;
181
182 bool HasAnimatedThisFrame() const;
183
184 ActiveAnimation* FindActiveAnimation(const char* animName);
185 std::vector<ActiveAnimation>& GetActiveAnimations();
186
187 QueuedAnimation* FindQueuedAnimation(const char* animName, const char* dependName = nullptr);
188 std::vector<QueuedAnimation>& GetQueuedAnimations();
189
190 glm::mat4 GetBoneTransform(const std::string& name) const;
191 glm::vec3 GetBonePosition(const std::string& name) const;
192 glm::quat GetBoneRotationQuat(const std::string& name) const;
193 glm::vec3 GetBoneRotationEuler(const std::string& name) const;
194 glm::vec3 GetBoneScale(const std::string& name) const;
195
196 glm::mat4 GetBoneTransform(int32_t index) const;
197 glm::vec3 GetBonePosition(int32_t boneIndex) const;
198 glm::quat GetBoneRotationQuat(int32_t boneIndex) const;
199 glm::vec3 GetBoneRotationEuler(int32_t boneIndex) const;
200 glm::vec3 GetBoneScale(int32_t boneIndex) const;
201
202 void SetBoneTransform(int32_t boneIndex, const glm::mat4& transform);
203 void SetBonePosition(int32_t boneIndex, glm::vec3 position);
204 void SetBoneRotation(int32_t boneIndex, glm::vec3 rotation);
205 void SetBoneScale(int32_t boneIndex, glm::vec2 scale);
206
207 uint32_t GetNumBones() const;
208 BoneInfluenceMode GetBoneInfluenceMode() const;
209
210 AnimationUpdateMode GetAnimationUpdateMode() const;
211 void SetAnimationUpdateMode(AnimationUpdateMode mode);
212
213 Vertex* GetSkinnedVertices();
214 uint32_t GetNumSkinnedVertices();
215
216 virtual Material* GetMaterial() override;
217 virtual void Render() override;
218
219 // Per-section material slot accessors. A "slot" maps 1:1 onto
220 // SkeletalMesh::GetSection(i). Resolution order for a slot:
221 // 1. component override (mSectionMaterialOverrides[slot])
222 // 2. section's own material (SkeletalMesh::GetSection(slot).mMaterial)
223 // 3. legacy mMaterialOverride (whole-mesh override)
224 // 4. legacy mesh-default mMaterial
225 // 5. renderer default material
226 uint32_t GetNumMaterialSlots() const;
227 Material* GetMaterialSlot(uint32_t slot) const;
228 void SetMaterialSlot(uint32_t slot, Material* material);
229 int32_t FindMaterialSlot(const std::string& sectionName) const;
230
231 void UpdateAnimation(float deltaTime, bool updateBones);
232
233 virtual Bounds GetLocalBounds() const override;
234 virtual AABB GetLocalAABB() const override;
235
236 int32_t FindBoneIndex(const std::string& name) const;
237
238 void SetAnimEventHandler(AnimEventHandlerFP handler);
239 AnimEventHandlerFP GetAnimEventHandler();
240 void SetScriptAnimEventHandler(const ScriptFunc& func);
241
242 // Procedural pose modifiers (spring / jiggle bones, spline IK, ...).
243 // Registered modifiers run each animation update after blending and before
244 // the local decomposed pose is composed into bone matrices. Registration is
245 // idempotent; unregister on modifier destruction / addon hot-reload to avoid
246 // a dangling pointer. See ISkeletalPoseModifier.
247 void RegisterPoseModifier(ISkeletalPoseModifier* modifier);
248 void UnregisterPoseModifier(ISkeletalPoseModifier* modifier);
249
250protected:
251
252 static bool HandlePropChange(Datum* datum, uint32_t index, const void* newValue);
253
254 void TickCommon(float deltaTime);
255
256 glm::vec3 InterpolateScale(float time, const Channel& channel);
257 glm::quat InterpolateRotation(float time, const Channel& channel);
258 glm::vec3 InterpolatePosition(float time, const Channel& channel);
259 void DetectTriggeredAnimEvents(
260 const Animation& animation,
261 float prevTickTime,
262 float tickTime,
263 float animationSpeed,
264 std::vector<AnimEvent>& outEvents);
265
266 uint32_t FindScaleIndex(float time, const Channel& channel);
267 uint32_t FindRotationIndex(float time, const Channel& channel);
268 uint32_t FindPositionIndex(float time, const Channel& channel);
269
270 void UpdateAttachedChildren(float deltaTime);
271 void CpuSkinVertices();
272
273 // External SkeletalAnimationAsset references. Resolution order in
274 // FindAnimation: embedded mesh animations first (preserves existing
275 // PlayAnimation behaviour), then animation-lookup-mesh chain, then
276 // bound external assets. Channels in external assets are keyed by bone
277 // NAME and get resolved into target-mesh bone indices lazily into the
278 // mBoundExternalAnims cache below.
279 const std::vector<SkeletalAnimationRef>& GetAnimationAssets() const { return mAnimationAssets; }
280 std::vector<SkeletalAnimationRef>& GetAnimationAssetsMutable();
281 void AddAnimationAsset(class SkeletalAnimationAsset* asset);
282 void RemoveAnimationAsset(class SkeletalAnimationAsset* asset);
283
284 const Animation* FindAnimation(const char* animName);
285 void InvalidateAnimationBindings();
286
288 std::vector<glm::mat4> mBoneMatrices;
289 std::vector<ISkeletalPoseModifier*> mPoseModifiers;
290 std::vector<Vertex> mSkinnedVertices; // Used by CPU skinning only.
291 std::vector<MaterialRef> mSectionMaterialOverrides;
292 std::vector<SkeletalAnimationRef> mAnimationAssets;
293
294 // Lazy cache of external animation clips with channel bone indices
295 // resolved against the currently assigned target mesh. Rebuilt on
296 // first FindAnimation after the mesh or asset list changes.
297 std::vector<Animation> mBoundExternalAnims;
298 bool mAnimBindingsValid = false;
299
301 std::string mDefaultAnimation;
302 float mAnimationSpeed = 1.0f;
303 std::vector<ActiveAnimation> mActiveAnimations;
304 std::vector<QueuedAnimation> mQueuedAnimations;
305 float mBoundsRadiusOverride = 0.0f;
310
313
314 // Graphics Resource
316};
#define POLYPHASE_API
Definition PolyphaseAPI.h:31
AnimationUpdateMode
Definition SkeletalMesh3d.h:21
void(* AnimEventHandlerFP)(const AnimEvent &animEvent)
Definition SkeletalMesh3d.h:82
BoneInfluenceMode
Definition SkeletalMesh3d.h:14
AnimLayerMode
Definition SkeletalMesh3d.h:36
Definition AssetRef.h:18
Definition BoneMaskAsset.h:19
Definition Datum.h:169
Definition SkeletalMesh3d.h:104
virtual ~ISkeletalPoseModifier()=default
virtual void ModifySkeletalPose(class SkeletalMesh3D *component, class SkeletalMesh *mesh, std::vector< SkeletalLocalPoseTransform > &localPose, float deltaTime)=0
Definition Material.h:48
Definition Mesh3d.h:13
Definition ScriptFunc.h:10
Definition SkeletalAnimationAsset.h:26
Definition SkeletalMesh3d.h:116
std::vector< ActiveAnimation > mActiveAnimations
Definition SkeletalMesh3d.h:303
bool mInheritPose
Definition SkeletalMesh3d.h:308
std::vector< Vertex > mSkinnedVertices
Definition SkeletalMesh3d.h:290
ScriptableFP< AnimEventHandlerFP > mAnimEventHandler
Definition SkeletalMesh3d.h:300
std::vector< glm::mat4 > mBoneMatrices
Definition SkeletalMesh3d.h:288
BoneInfluenceMode mBoneInfluenceMode
Definition SkeletalMesh3d.h:311
std::vector< Animation > mBoundExternalAnims
Definition SkeletalMesh3d.h:297
std::string mDefaultAnimation
Definition SkeletalMesh3d.h:301
bool mHasAnimatedThisFrame
Definition SkeletalMesh3d.h:309
bool mRevertToBindPose
Definition SkeletalMesh3d.h:307
std::vector< QueuedAnimation > mQueuedAnimations
Definition SkeletalMesh3d.h:304
SkeletalMeshCompResource mResource
Definition SkeletalMesh3d.h:315
std::vector< SkeletalAnimationRef > mAnimationAssets
Definition SkeletalMesh3d.h:292
AnimationUpdateMode mAnimationUpdateMode
Definition SkeletalMesh3d.h:312
std::vector< ISkeletalPoseModifier * > mPoseModifiers
Definition SkeletalMesh3d.h:289
SkeletalMeshRef mSkeletalMesh
Definition SkeletalMesh3d.h:287
std::vector< MaterialRef > mSectionMaterialOverrides
Definition SkeletalMesh3d.h:291
const std::vector< SkeletalAnimationRef > & GetAnimationAssets() const
Definition SkeletalMesh3d.h:279
DECLARE_NODE(SkeletalMesh3D, Mesh3D)
bool mAnimationPaused
Definition SkeletalMesh3d.h:306
Definition SkeletalMesh.h:99
Definition EngineTypes.h:210
Definition SkeletalMesh3d.h:49
AssetRef mBoneMask
Definition SkeletalMesh3d.h:60
bool mLoop
Definition SkeletalMesh3d.h:55
float mWeightFadeRate
Definition SkeletalMesh3d.h:66
float mSpeed
Definition SkeletalMesh3d.h:52
int32_t mSlot
Definition SkeletalMesh3d.h:54
std::string mName
Definition SkeletalMesh3d.h:50
float mWeightTarget
Definition SkeletalMesh3d.h:65
float mTime
Definition SkeletalMesh3d.h:51
float mWeight
Definition SkeletalMesh3d.h:53
AnimLayerMode mLayerMode
Definition SkeletalMesh3d.h:68
Definition SkeletalMesh.h:60
Definition SkeletalMesh.h:77
Definition EngineTypes.h:201
Definition SkeletalMesh.h:69
Definition SkeletalMesh3d.h:72
bool mLoop
Definition SkeletalMesh3d.h:78
float mTime
Definition SkeletalMesh3d.h:75
std::string mName
Definition SkeletalMesh3d.h:73
std::string mDependentAnim
Definition SkeletalMesh3d.h:74
float mWeight
Definition SkeletalMesh3d.h:77
float mSpeed
Definition SkeletalMesh3d.h:76
int32_t mSlot
Definition SkeletalMesh3d.h:79
Definition ScriptFunc.h:43
Definition SkeletalMesh3d.h:91
bool mValid
Definition SkeletalMesh3d.h:95
glm::vec3 mPosition
Definition SkeletalMesh3d.h:92
glm::vec3 mScale
Definition SkeletalMesh3d.h:94
glm::quat mRotation
Definition SkeletalMesh3d.h:93
Definition GraphicsTypes.h:238
Definition Vertex.h:20