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