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 | |
9 | namespace 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 | |