13 #ifndef hifi_AnimVariant_h
14 #define hifi_AnimVariant_h
18 #include <glm/glm.hpp>
19 #include <glm/gtx/quaternion.hpp>
22 #include <StreamUtils.h>
23 #include <GLMHelpers.h>
24 #include "AnimationLogging.h"
25 #include <ScriptValue.h>
41 static const AnimVariant False;
43 AnimVariant() : _type(Type::Bool) { memset(&_val, 0,
sizeof(_val)); }
44 explicit AnimVariant(
bool value) : _type(Type::Bool) { _val.boolVal = value; }
45 explicit AnimVariant(
int value) : _type(Type::Int) { _val.intVal = value; }
46 explicit AnimVariant(
float value) : _type(Type::Float) { _val.floats[0] = value; }
47 explicit AnimVariant(
const glm::vec3& value) : _type(Type::
Vec3) { *
reinterpret_cast<glm::vec3*
>(&_val) = value; }
48 explicit AnimVariant(
const glm::quat& value) : _type(Type::
Quat) { *
reinterpret_cast<glm::quat*
>(&_val) = value; }
49 explicit AnimVariant(
const QString& value) : _type(Type::String) { _stringVal = value; }
51 bool isBool()
const {
return _type == Type::Bool; }
52 bool isInt()
const {
return _type == Type::Int; }
53 bool isFloat()
const {
return _type == Type::Float; }
54 bool isVec3()
const {
return _type == Type::Vec3; }
55 bool isQuat()
const {
return _type == Type::Quat; }
56 bool isString()
const {
return _type == Type::String; }
57 Type getType()
const {
return _type; }
59 void setBool(
bool value) { assert(_type == Type::Bool); _val.boolVal = value; }
60 void setInt(
int value) { assert(_type == Type::Int); _val.intVal = value; }
61 void setFloat(
float value) { assert(_type == Type::Float); _val.floats[0] = value; }
62 void setVec3(
const glm::vec3& value) { assert(_type == Type::Vec3); *
reinterpret_cast<glm::vec3*
>(&_val) = value; }
63 void setQuat(
const glm::quat& value) { assert(_type == Type::Quat); *
reinterpret_cast<glm::quat*
>(&_val) = value; }
64 void setString(
const QString& value) { assert(_type == Type::String); _stringVal = value; }
66 bool getBool()
const {
67 if (_type == Type::Bool) {
69 }
else if (_type == Type::Int) {
70 return _val.intVal != 0;
76 if (_type == Type::Int) {
78 }
else if (_type == Type::Float) {
79 return (
int)_val.floats[0];
84 float getFloat()
const {
85 if (_type == Type::Float) {
86 return _val.floats[0];
87 }
else if (_type == Type::Int) {
88 return (
float)_val.intVal;
93 const glm::vec3& getVec3()
const {
94 if (_type == Type::Vec3) {
95 return *
reinterpret_cast<const glm::vec3*
>(&_val);
100 const glm::quat& getQuat()
const {
101 if (_type == Type::Quat) {
102 return *
reinterpret_cast<const glm::quat*
>(&_val);
104 return Quaternions::IDENTITY;
107 const QString& getString()
const {
121 class AnimVariantMap {
124 bool lookup(
const QString& key,
bool defaultValue)
const {
128 }
else if (_triggers.find(key) != _triggers.end()) {
131 auto iter = _map.find(key);
132 return iter != _map.end() ? iter->second.getBool() : defaultValue;
136 int lookup(
const QString& key,
int defaultValue)
const {
140 auto iter = _map.find(key);
141 return iter != _map.end() ? iter->second.getInt() : defaultValue;
145 float lookup(
const QString& key,
float defaultValue)
const {
149 auto iter = _map.find(key);
150 return iter != _map.end() ? iter->second.getFloat() : defaultValue;
154 const glm::vec3& lookupRaw(
const QString& key,
const glm::vec3& defaultValue)
const {
158 auto iter = _map.find(key);
159 return iter != _map.end() ? iter->second.getVec3() : defaultValue;
163 glm::vec3 lookupRigToGeometry(
const QString& key,
const glm::vec3& defaultValue)
const {
167 auto iter = _map.find(key);
168 return iter != _map.end() ? transformPoint(_rigToGeometryMat, iter->second.getVec3()) : defaultValue;
172 glm::vec3 lookupRigToGeometryVector(
const QString& key,
const glm::vec3& defaultValue)
const {
176 auto iter = _map.find(key);
177 return iter != _map.end() ? transformVectorFast(_rigToGeometryMat, iter->second.getVec3()) : defaultValue;
181 const glm::quat& lookupRaw(
const QString& key,
const glm::quat& defaultValue)
const {
185 auto iter = _map.find(key);
186 return iter != _map.end() ? iter->second.getQuat() : defaultValue;
190 glm::quat lookupRigToGeometry(
const QString& key,
const glm::quat& defaultValue)
const {
194 auto iter = _map.find(key);
195 return iter != _map.end() ? _rigToGeometryRot * iter->second.getQuat() : defaultValue;
199 const QString& lookup(
const QString& key,
const QString& defaultValue)
const {
203 auto iter = _map.find(key);
204 return iter != _map.end() ? iter->second.getString() : defaultValue;
208 void set(
const QString& key,
bool value) { _map[key] = AnimVariant(value); }
209 void set(
const QString& key,
int value) { _map[key] = AnimVariant(value); }
210 void set(
const QString& key,
float value) { _map[key] = AnimVariant(value); }
211 void set(
const QString& key,
const glm::vec3& value) { _map[key] = AnimVariant(value); }
212 void set(
const QString& key,
const glm::quat& value) { _map[key] = AnimVariant(value); }
213 void set(
const QString& key,
const QString& value) { _map[key] = AnimVariant(value); }
214 void unset(
const QString& key) { _map.erase(key); }
216 void setTrigger(
const QString& key) { _map[key] = AnimVariant(
true); }
218 void setRigToGeometryTransform(
const glm::mat4& rigToGeometry) {
219 _rigToGeometryMat = rigToGeometry;
220 _rigToGeometryRot = glmExtractRotation(rigToGeometry);
223 void clearMap() { _map.clear(); _triggers.clear(); }
224 bool hasKey(
const QString& key)
const {
return _map.find(key) != _map.end(); }
226 const AnimVariant& get(
const QString& key)
const {
227 auto iter = _map.find(key);
228 if (iter != _map.end()) {
231 return AnimVariant::False;
238 void animVariantMapFromScriptValue(
const ScriptValue&
object);
239 void copyVariantsFrom(
const AnimVariantMap& other);
242 std::map<QString, QString> toDebugMap()
const;
246 qCDebug(animation) <<
"AnimVariantMap =";
247 for (
auto& pair : _map) {
248 switch (pair.second.getType()) {
249 case AnimVariant::Type::Bool:
250 qCDebug(animation) <<
" " << pair.first <<
"=" << pair.second.getBool();
252 case AnimVariant::Type::Int:
253 qCDebug(animation) <<
" " << pair.first <<
"=" << pair.second.getInt();
255 case AnimVariant::Type::Float:
256 qCDebug(animation) <<
" " << pair.first <<
"=" << pair.second.getFloat();
258 case AnimVariant::Type::Vec3:
259 qCDebug(animation) <<
" " << pair.first <<
"=" << pair.second.getVec3();
261 case AnimVariant::Type::Quat:
262 qCDebug(animation) <<
" " << pair.first <<
"=" << pair.second.getQuat();
264 case AnimVariant::Type::String:
265 qCDebug(animation) <<
" " << pair.first <<
"=" << pair.second.getString();
275 std::map<QString, AnimVariant> _map;
276 std::set<QString> _triggers;
277 glm::mat4 _rigToGeometryMat;
278 glm::quat _rigToGeometryRot;
281 typedef std::function<void(
ScriptValue)> AnimVariantResultHandler;
282 Q_DECLARE_METATYPE(AnimVariantResultHandler);
283 Q_DECLARE_METATYPE(AnimVariantMap)
Provides the Quat scripting interface.
Definition: Quat.h:61
Provides an engine-independent interface for a scripting engine.
Definition: ScriptEngine.h:93
[ScriptInterface] Provides an engine-independent interface for QScriptValue
Definition: ScriptValue.h:40
Provides the Vec3 scripting interface.
Definition: Vec3.h:80