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/BsIReflectable.h" |
7 | #include "Math/BsVector3.h" |
8 | |
9 | namespace bs |
10 | { |
11 | /** @addtogroup Animation-Internal |
12 | * @{ |
13 | */ |
14 | |
15 | /** A single vertex used for morph target animation. Contains a difference between base and target shape. */ |
16 | struct BS_CORE_EXPORT MorphVertex |
17 | { |
18 | MorphVertex() = default; |
19 | MorphVertex(const Vector3& deltaPosition, const Vector3& deltaNormal, UINT32 sourceIdx) |
20 | :deltaPosition(deltaPosition), deltaNormal(deltaNormal), sourceIdx(sourceIdx) |
21 | { } |
22 | |
23 | Vector3 deltaPosition; |
24 | Vector3 deltaNormal; |
25 | UINT32 sourceIdx; |
26 | }; |
27 | |
28 | /** |
29 | * @native |
30 | * A set of vertices representing a single shape in a morph target animation. Vertices are represented as a difference |
31 | * between base and target shape. |
32 | * @endnative |
33 | * @script |
34 | * Name and weight of a single shape in a morph target animation. Each shape internally represents a set of vertices |
35 | * that describe the morph shape. |
36 | * @endscript |
37 | */ |
38 | class BS_CORE_EXPORT BS_SCRIPT_EXPORT(m:Animation) MorphShape : public IReflectable |
39 | { |
40 | public: |
41 | MorphShape(const String& name, float weight, const Vector<MorphVertex>& vertices); |
42 | |
43 | /** Returns the name of the shape. */ |
44 | BS_SCRIPT_EXPORT(pr:getter,n:Name) |
45 | const String& getName() const { return mName; } |
46 | |
47 | /** Returns the weight of the shape, determining how are different shapes within a channel blended. */ |
48 | BS_SCRIPT_EXPORT(pr:getter,n:Weight) |
49 | float getWeight() const { return mWeight; } |
50 | |
51 | /** Returns a reference to all of the shape's vertices. Contains only vertices that differ from the base. */ |
52 | const Vector<MorphVertex>& getVertices() const { return mVertices; } |
53 | |
54 | /** |
55 | * Creates a new morph shape from the provided set of vertices. |
56 | * |
57 | * @param[in] name Name of the frame. Must be unique within a morph channel. |
58 | * @param[in] weight Weight in range [0, 1]. Determines how are sequential shapes animated between within a |
59 | * morph channel. e.g. if there is a shape A with weight 0.3 and shape B with weight 0.8 |
60 | * then shape A will be displayed first and then be blended towards shape B as time passes. |
61 | * @param[in] vertices Vertices of the base mesh modified by the shape. |
62 | */ |
63 | static SPtr<MorphShape> create(const String& name, float weight, const Vector<MorphVertex>& vertices); |
64 | |
65 | private: |
66 | String mName; |
67 | float mWeight; |
68 | Vector<MorphVertex> mVertices; |
69 | |
70 | /************************************************************************/ |
71 | /* SERIALIZATION */ |
72 | /************************************************************************/ |
73 | public: |
74 | friend class MorphShapeRTTI; |
75 | static RTTITypeBase* getRTTIStatic(); |
76 | RTTITypeBase* getRTTI() const override; |
77 | |
78 | MorphShape() = default; // Serialization only |
79 | }; |
80 | |
81 | /** |
82 | * A collection of morph shapes that are sequentially blended together. Each shape has a weight in range [0, 1] which |
83 | * determines at what point is that shape blended. As the channel percent moves from 0 to 1, different shapes will be |
84 | * blended with those before or after them, depending on their weight. |
85 | */ |
86 | class BS_CORE_EXPORT BS_SCRIPT_EXPORT(m:Animation) MorphChannel : public IReflectable |
87 | { |
88 | public: |
89 | /** Returns the unique name of the channel. */ |
90 | BS_SCRIPT_EXPORT(pr:getter,n:Name) |
91 | const String& getName() const { return mName; } |
92 | |
93 | /** Returns the number of available morph shapes. */ |
94 | UINT32 getNumShapes() const { return (UINT32)mShapes.size(); } |
95 | |
96 | /** Returns the morph shape at the specified index. */ |
97 | SPtr<MorphShape> getShape(UINT32 idx) const { return mShapes[idx]; } |
98 | |
99 | /** Returns all morph shapes within this channel, in order from lowest to highest. */ |
100 | BS_SCRIPT_EXPORT(pr:getter,n:Shapes) |
101 | const Vector<SPtr<MorphShape>>& getShapes() const { return mShapes; } |
102 | |
103 | /** Creates a new channel from a set of morph shapes. */ |
104 | static SPtr<MorphChannel> create(const String& name, const Vector<SPtr<MorphShape>>& shapes); |
105 | |
106 | private: |
107 | MorphChannel() = default; |
108 | MorphChannel(const String& name, const Vector<SPtr<MorphShape>>& shapes); |
109 | |
110 | String mName; |
111 | Vector<SPtr<MorphShape>> mShapes; |
112 | |
113 | /************************************************************************/ |
114 | /* SERIALIZATION */ |
115 | /************************************************************************/ |
116 | public: |
117 | friend class MorphChannelRTTI; |
118 | static RTTITypeBase* getRTTIStatic(); |
119 | RTTITypeBase* getRTTI() const override; |
120 | |
121 | /** |
122 | * Creates MorphShapes with no data. You must populate its data manually. |
123 | * |
124 | * @note For serialization use only. |
125 | */ |
126 | static SPtr<MorphChannel> createEmpty(); |
127 | }; |
128 | |
129 | /** |
130 | * Contains a set of morph channels used for morph target animation. Each morph channel contains one or multiple shapes |
131 | * which are blended together depending on frame animation. Each channel is then additively blended together depending |
132 | * on some weight. |
133 | */ |
134 | class BS_CORE_EXPORT BS_SCRIPT_EXPORT(m:Animation) MorphShapes : public IReflectable // Note: Must be immutable in order to be usable on multiple threads |
135 | { |
136 | public: |
137 | /** Returns the number of available morph channels. */ |
138 | UINT32 getNumChannels() const { return (UINT32)mChannels.size(); } |
139 | |
140 | /** Returns the morph channel at the specified index. */ |
141 | SPtr<MorphChannel> getChannel(UINT32 idx) const { return mChannels[idx]; } |
142 | |
143 | /** Returns a list of all morph channels in the morph animation. */ |
144 | BS_SCRIPT_EXPORT(pr:getter,n:Channels) |
145 | const Vector<SPtr<MorphChannel>>& getChannels() const { return mChannels; } |
146 | |
147 | /** Returns the number of vertices per morph shape. */ |
148 | UINT32 getNumVertices() const { return mNumVertices; } |
149 | |
150 | /** Creates a new set of morph shapes. */ |
151 | static SPtr<MorphShapes> create(const Vector<SPtr<MorphChannel>>& channels, UINT32 numVertices); |
152 | |
153 | private: |
154 | MorphShapes() = default; |
155 | MorphShapes(const Vector<SPtr<MorphChannel>>& channels, UINT32 numVertices); |
156 | |
157 | Vector<SPtr<MorphChannel>> mChannels; |
158 | UINT32 mNumVertices; |
159 | |
160 | /************************************************************************/ |
161 | /* SERIALIZATION */ |
162 | /************************************************************************/ |
163 | public: |
164 | friend class MorphShapesRTTI; |
165 | static RTTITypeBase* getRTTIStatic(); |
166 | RTTITypeBase* getRTTI() const override; |
167 | |
168 | /** |
169 | * Creates MorphShapes with no data. You must populate its data manually. |
170 | * |
171 | * @note For serialization use only. |
172 | */ |
173 | static SPtr<MorphShapes> createEmpty(); |
174 | }; |
175 | |
176 | /** @} */ |
177 | } |