// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Core/Math/Transform.h" #include "Engine/Core/Math/Matrix.h" #include "Engine/Core/Types/String.h" #include "Engine/Core/Types/StringView.h" #include "Engine/Core/Collections/Array.h" /// /// Describes a single skeleton node data. Used by the runtime. /// API_STRUCT() struct FLAXENGINE_API SkeletonNode { DECLARE_SCRIPTING_TYPE_MINIMAL(SkeletonNode); /// /// The parent node index. The root node uses value -1. /// API_FIELD() int32 ParentIndex; /// /// The local transformation of the node, relative to the parent node. /// API_FIELD() Transform LocalTransform; /// /// The name of this node. /// API_FIELD() String Name; }; /// /// Describes a single skeleton bone data. Used by the runtime. Skeleton bones are subset of the skeleton nodes collection that are actually used by the skinned model meshes. /// API_STRUCT() struct FLAXENGINE_API SkeletonBone { DECLARE_SCRIPTING_TYPE_MINIMAL(SkeletonBone); /// /// The parent bone index. The root bone uses value -1. /// API_FIELD() int32 ParentIndex; /// /// The index of the skeleton node where bone is 'attached'. Used as a animation transformation source. /// API_FIELD() int32 NodeIndex; /// /// The local transformation of the bone, relative to the parent bone (in bind pose). /// API_FIELD() Transform LocalTransform; /// /// The matrix that transforms from mesh space to bone space in bind pose (inverse bind pose). /// API_FIELD() Matrix OffsetMatrix; }; template<> struct TIsPODType { enum { Value = true }; }; /// /// Describes hierarchical bones in a flattened array. /// /// /// Bones are ordered so that parents always come first, allowing for hierarchical updates in a simple loop. /// class FLAXENGINE_API SkeletonData { public: /// /// The nodes in this hierarchy. The root node is always at the index 0. /// Array Nodes; /// /// The bones in this hierarchy. /// Array Bones; public: /// /// Gets the root node reference. /// FORCE_INLINE SkeletonNode& RootNode() { ASSERT(Nodes.HasItems()); return Nodes.Get()[0]; } /// /// Gets the root node reference. /// FORCE_INLINE const SkeletonNode& RootNode() const { ASSERT(Nodes.HasItems()); return Nodes.Get()[0]; } /// /// Swaps the contents of object with the other object without copy operation. Performs fast internal data exchange. /// void Swap(SkeletonData& other); Transform GetNodeTransform(int32 nodeIndex) const; void SetNodeTransform(int32 nodeIndex, const Transform& value); int32 FindNode(const StringView& name) const; int32 FindBone(int32 nodeIndex) const; uint64 GetMemoryUsage() const; /// /// Releases data. /// void Dispose(); };