1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "BsCorePrerequisites.h"
6#include "Reflection/BsRTTIType.h"
7#include "Animation/BsSkeleton.h"
8
9namespace bs
10{
11 /** @cond RTTI */
12 /** @addtogroup RTTI-Impl-Core
13 * @{
14 */
15
16 class BS_CORE_EXPORT SkeletonRTTI : public RTTIType <Skeleton, IReflectable, SkeletonRTTI>
17 {
18 private:
19 Matrix4& getBindPose(Skeleton* obj, UINT32 idx) { return obj->mInvBindPoses[idx]; }
20 void setBindPose(Skeleton* obj, UINT32 idx, Matrix4& value) { obj->mInvBindPoses[idx] = value; }
21
22 void setNumBindPoses(Skeleton* obj, UINT32 size)
23 {
24 obj->mNumBones = size;
25
26 assert(obj->mInvBindPoses == nullptr);
27 obj->mInvBindPoses = bs_newN<Matrix4>(size);
28 }
29
30 SkeletonBoneInfo& getBoneInfo(Skeleton* obj, UINT32 idx) { return obj->mBoneInfo[idx]; }
31 void setBoneInfo(Skeleton* obj, UINT32 idx, SkeletonBoneInfo& value) { obj->mBoneInfo[idx] = value; }
32
33 void setNumBoneInfos(Skeleton* obj, UINT32 size)
34 {
35 obj->mNumBones = size;
36
37 assert(obj->mBoneInfo == nullptr);
38 obj->mBoneInfo = bs_newN<SkeletonBoneInfo>(size);
39 }
40
41 Transform& getBoneTransform(Skeleton* obj, UINT32 idx) { return obj->mBoneTransforms[idx]; }
42 void setBoneTransform(Skeleton* obj, UINT32 idx, Transform& value) { obj->mBoneTransforms[idx] = value; }
43
44 void setNumBoneTransforms(Skeleton* obj, UINT32 size)
45 {
46 obj->mNumBones = size;
47
48 assert(obj->mBoneTransforms == nullptr);
49 obj->mBoneTransforms = bs_newN<Transform>(size);
50 }
51
52 UINT32 getNumBones(Skeleton* obj) { return obj->mNumBones; }
53 public:
54 SkeletonRTTI()
55 {
56 addPlainArrayField("bindPoses", 0, &SkeletonRTTI::getBindPose, &SkeletonRTTI::getNumBones,
57 &SkeletonRTTI::setBindPose, &SkeletonRTTI::setNumBindPoses);
58 addPlainArrayField("boneInfo", 1, &SkeletonRTTI::getBoneInfo, &SkeletonRTTI::getNumBones,
59 &SkeletonRTTI::setBoneInfo, &SkeletonRTTI::setNumBoneInfos);
60 addReflectableArrayField("boneTransforms", 3, &SkeletonRTTI::getBoneTransform, &SkeletonRTTI::getNumBones,
61 &SkeletonRTTI::setBoneTransform, &SkeletonRTTI::setNumBoneTransforms);
62 }
63
64 const String& getRTTIName() override
65 {
66 static String name = "Skeleton";
67 return name;
68 }
69
70 UINT32 getRTTIId() override
71 {
72 return TID_Skeleton;
73 }
74
75 SPtr<IReflectable> newRTTIObject() override
76 {
77 return Skeleton::createEmpty();
78 }
79 };
80
81 template<> struct RTTIPlainType<SkeletonBoneInfo>
82 {
83 enum { id = TID_SkeletonBoneInfo }; enum { hasDynamicSize = 1 };
84
85 /** @copydoc RTTIPlainType::toMemory */
86 static void toMemory(const SkeletonBoneInfo& data, char* memory)
87 {
88 UINT32 size = sizeof(UINT32);
89 char* memoryStart = memory;
90 memory += sizeof(UINT32);
91
92 memory = rttiWriteElem(data.name, memory, size);
93 memory = rttiWriteElem(data.parent, memory, size);
94
95 memcpy(memoryStart, &size, sizeof(UINT32));
96 }
97
98 /** @copydoc RTTIPlainType::fromMemory */
99 static UINT32 fromMemory(SkeletonBoneInfo& data, char* memory)
100 {
101 UINT32 size = 0;
102 memory = rttiReadElem(size, memory);
103
104 memory = rttiReadElem(data.name, memory);
105 rttiReadElem(data.parent, memory);
106
107 return size;
108 }
109
110 /** @copydoc RTTIPlainType::getDynamicSize */
111 static UINT32 getDynamicSize(const SkeletonBoneInfo& data)
112 {
113 UINT64 dataSize = sizeof(UINT32);
114 dataSize += rttiGetElemSize(data.name);
115 dataSize += rttiGetElemSize(data.parent);
116
117 assert(dataSize <= std::numeric_limits<UINT32>::max());
118
119 return (UINT32)dataSize;
120 }
121 };
122
123 /** @} */
124 /** @endcond */
125}
126