TDME2  1.9.200
MiniScriptQuaternion.cpp
Go to the documentation of this file.
1 #include <span>
2 #include <string>
3 
4 #include <miniscript/miniscript/MiniScript.h>
5 
7 
8 #include <tdme/tdme.h>
9 #include <tdme/math/Quaternion.h>
10 #include <tdme/utilities/Console.h>
11 #include <tdme/utilities/Float.h>
14 
15 using std::span;
16 using std::string;
17 
18 using miniscript::miniscript::MiniScript;
19 
21 
27 
28 const string MiniScriptQuaternion::CLASS_NAME = "quaternion";
29 const string MiniScriptQuaternion::TYPE_NAME = "Quaternion";
30 
31 void MiniScriptQuaternion::registerMethods(MiniScript* miniScript) const {
32  const auto TYPE_QUATERNION = static_cast<MiniScript::ScriptVariableType>(getType());
33  const auto TYPE_VECTOR3 = static_cast<MiniScript::ScriptVariableType>(miniScript->getDataTypeByClassName("vec3")->getType());
34  const auto TYPE_MATRIX4x4 = static_cast<MiniScript::ScriptVariableType>(miniScript->getDataTypeByClassName("mat4")->getType());
35  {
36  //
37  class ScriptMethodQuaternionIdentity: public MiniScript::ScriptMethod {
38  private:
39  MiniScript* miniScript { nullptr };
40  MiniScript::ScriptVariableType TYPE_QUATERNION;
41  public:
42  ScriptMethodQuaternionIdentity(
43  MiniScript* miniScript,
44  MiniScript::ScriptVariableType TYPE_QUATERNION
45  ):
46  MiniScript::ScriptMethod({}, TYPE_QUATERNION),
47  miniScript(miniScript), TYPE_QUATERNION(TYPE_QUATERNION) {
48  //
49  }
50  const string getMethodName() override {
51  return "quaternion.identity";
52  }
53  void executeMethod(span<MiniScript::ScriptVariable>& argumentValues, MiniScript::ScriptVariable& returnValue, const MiniScript::ScriptStatement& statement) override {
54  auto result = Quaternion().identity();
55  returnValue.setType(TYPE_QUATERNION);
56  returnValue.setValue(&result);
57  }
58  };
59  miniScript->registerMethod(new ScriptMethodQuaternionIdentity(miniScript, TYPE_QUATERNION));
60  }
61  {
62  //
63  class ScriptMethodQuaternionInvert: public MiniScript::ScriptMethod {
64  private:
65  MiniScript* miniScript { nullptr };
66  MiniScript::ScriptVariableType TYPE_QUATERNION;
67  public:
68  ScriptMethodQuaternionInvert(
69  MiniScript* miniScript,
70  MiniScript::ScriptVariableType TYPE_QUATERNION
71  ):
72  MiniScript::ScriptMethod(
73  {
74  { .type = TYPE_QUATERNION, .name = "quaternion", .optional = false, .reference = false, .nullable = false },
75  },
76  TYPE_QUATERNION
77  ),
78  miniScript(miniScript), TYPE_QUATERNION(TYPE_QUATERNION) {
79  //
80  }
81  const string getMethodName() override {
82  return "quaternion.invert";
83  }
84  void executeMethod(span<MiniScript::ScriptVariable>& argumentValues, MiniScript::ScriptVariable& returnValue, const MiniScript::ScriptStatement& statement) override {
85  Quaternion quaternion;
86  if (MiniScriptQuaternion::getQuaternionValue(TYPE_QUATERNION, argumentValues, 0, quaternion, false) == true) {
87  auto result = quaternion.invert();
88  returnValue.setType(TYPE_QUATERNION);
89  returnValue.setValue(&result);
90  } else {
91  Console::println(getMethodName() + "(): " + miniScript->getStatementInformation(statement) + ": argument mismatch: expected arguments: " + miniScript->getArgumentInformation(getMethodName()));
92  miniScript->startErrorScript();
93  }
94  }
95  };
96  miniScript->registerMethod(new ScriptMethodQuaternionInvert(miniScript, TYPE_QUATERNION));
97  }
98  {
99  //
100  class ScriptMethodQuaternionRotate: public MiniScript::ScriptMethod {
101  private:
102  MiniScript* miniScript { nullptr };
103  MiniScript::ScriptVariableType TYPE_QUATERNION;
104  MiniScript::ScriptVariableType TYPE_VECTOR3;
105  public:
106  ScriptMethodQuaternionRotate(
107  MiniScript* miniScript,
108  MiniScript::ScriptVariableType TYPE_QUATERNION,
109  MiniScript::ScriptVariableType TYPE_VECTOR3
110  ):
111  MiniScript::ScriptMethod(
112  {
113  { .type = TYPE_VECTOR3, .name = "axis", .optional = false, .reference = false, .nullable = false },
114  { .type = MiniScript::ScriptVariableType::TYPE_FLOAT, .name = "angle", .optional = false, .reference = false, .nullable = false }
115  },
116  TYPE_QUATERNION
117  ),
118  miniScript(miniScript),
119  TYPE_QUATERNION(TYPE_QUATERNION),
120  TYPE_VECTOR3(TYPE_VECTOR3) {
121  //
122  }
123  const string getMethodName() override {
124  return "quaternion.rotate";
125  }
126  void executeMethod(span<MiniScript::ScriptVariable>& argumentValues, MiniScript::ScriptVariable& returnValue, const MiniScript::ScriptStatement& statement) override {
127  Vector3 axis;
128  float angle;
129  if (MiniScriptVector3::getVector3Value(TYPE_VECTOR3, argumentValues, 0, axis, false) == true &&
130  MiniScript::getFloatValue(argumentValues, 1, angle, false) == true) {
131  auto result = Quaternion().rotate(axis, angle);
132  returnValue.setType(TYPE_QUATERNION);
133  returnValue.setValue(&result);
134  } else {
135  Console::println(getMethodName() + "(): " + miniScript->getStatementInformation(statement) + ": argument mismatch: expected arguments: " + miniScript->getArgumentInformation(getMethodName()));
136  miniScript->startErrorScript();
137  }
138  }
139  };
140  miniScript->registerMethod(new ScriptMethodQuaternionRotate(miniScript, TYPE_QUATERNION, TYPE_VECTOR3));
141  }
142  {
143  //
144  class ScriptMethodQuaternionNormalize: public MiniScript::ScriptMethod {
145  private:
146  MiniScript* miniScript { nullptr };
147  MiniScript::ScriptVariableType TYPE_QUATERNION;
148  public:
149  ScriptMethodQuaternionNormalize(
150  MiniScript* miniScript,
151  MiniScript::ScriptVariableType TYPE_QUATERNION
152  ):
153  MiniScript::ScriptMethod(
154  {
155  { .type = TYPE_QUATERNION, .name = "quaternion", .optional = false, .reference = false, .nullable = false },
156  },
157  TYPE_QUATERNION
158  ),
159  miniScript(miniScript), TYPE_QUATERNION(TYPE_QUATERNION) {}
160  const string getMethodName() override {
161  return "quaternion.normalize";
162  }
163  void executeMethod(span<MiniScript::ScriptVariable>& argumentValues, MiniScript::ScriptVariable& returnValue, const MiniScript::ScriptStatement& statement) override {
164  Quaternion quaternion;
165  if (MiniScriptQuaternion::getQuaternionValue(TYPE_QUATERNION, argumentValues, 0, quaternion, false) == true) {
166  auto result = quaternion.normalize();
167  returnValue.setType(TYPE_QUATERNION);
168  returnValue.setValue(&result);
169  } else {
170  Console::println(getMethodName() + "(): " + miniScript->getStatementInformation(statement) + ": argument mismatch: expected arguments: " + miniScript->getArgumentInformation(getMethodName()));
171  miniScript->startErrorScript();
172  }
173  }
174  };
175  miniScript->registerMethod(new ScriptMethodQuaternionNormalize(miniScript, TYPE_QUATERNION));
176  }
177  {
178  //
179  class ScriptMethodQuaternionInvert: public MiniScript::ScriptMethod {
180  private:
181  MiniScript* miniScript { nullptr };
182  MiniScript::ScriptVariableType TYPE_QUATERNION;
183  MiniScript::ScriptVariableType TYPE_VECTOR3;
184  public:
185  ScriptMethodQuaternionInvert(
186  MiniScript* miniScript,
187  MiniScript::ScriptVariableType TYPE_QUATERNION,
188  MiniScript::ScriptVariableType TYPE_VECTOR3
189  ):
190  MiniScript::ScriptMethod(
191  {
192  { .type = TYPE_QUATERNION, .name = "quaternion", .optional = false, .reference = false, .nullable = false },
193  },
194  TYPE_VECTOR3
195  ),
196  miniScript(miniScript),
197  TYPE_QUATERNION(TYPE_QUATERNION),
198  TYPE_VECTOR3(TYPE_VECTOR3) {
199  //
200  }
201  const string getMethodName() override {
202  return "quaternion.computeEulerAngles";
203  }
204  void executeMethod(span<MiniScript::ScriptVariable>& argumentValues, MiniScript::ScriptVariable& returnValue, const MiniScript::ScriptStatement& statement) override {
205  Quaternion quaternion;
206  if (MiniScriptQuaternion::getQuaternionValue(TYPE_QUATERNION, argumentValues, 0, quaternion, false) == true) {
207  auto result = quaternion.computeEulerAngles();
208  returnValue.setType(TYPE_VECTOR3);
209  returnValue.setValue(&result);
210  } else {
211  Console::println(getMethodName() + "(): " + miniScript->getStatementInformation(statement) + ": argument mismatch: expected arguments: " + miniScript->getArgumentInformation(getMethodName()));
212  miniScript->startErrorScript();
213  }
214  }
215  };
216  miniScript->registerMethod(new ScriptMethodQuaternionInvert(miniScript, TYPE_QUATERNION, TYPE_VECTOR3));
217  }
218  {
219  //
220  class ScriptMethodQuaternionComputeMatrix: public MiniScript::ScriptMethod {
221  private:
222  MiniScript::ScriptVariableType TYPE_QUATERNION;
223  MiniScript::ScriptVariableType TYPE_MATRIX4x4;
224  MiniScript* miniScript { nullptr };
225  public:
226  ScriptMethodQuaternionComputeMatrix(
227  MiniScript* miniScript,
228  MiniScript::ScriptVariableType TYPE_QUATERNION,
229  MiniScript::ScriptVariableType TYPE_MATRIX4x4
230  ):
231  MiniScript::ScriptMethod(
232  {
233  { .type = TYPE_QUATERNION, .name = "quaternion", .optional = false, .reference = false, .nullable = false },
234  },
235  TYPE_MATRIX4x4
236  ),
237  miniScript(miniScript), TYPE_QUATERNION(TYPE_QUATERNION), TYPE_MATRIX4x4(TYPE_MATRIX4x4) {
238  //
239  }
240  const string getMethodName() override {
241  return "quaternion.computeMatrix";
242  }
243  void executeMethod(span<MiniScript::ScriptVariable>& argumentValues, MiniScript::ScriptVariable& returnValue, const MiniScript::ScriptStatement& statement) override {
244  Quaternion quaternion;
245  if (MiniScriptQuaternion::getQuaternionValue(TYPE_QUATERNION, argumentValues, 0, quaternion, false) == true) {
246  auto result = quaternion.computeMatrix();
247  returnValue.setType(TYPE_MATRIX4x4);
248  returnValue.setValue(&result);
249  } else {
250  Console::println(getMethodName() + "(): " + miniScript->getStatementInformation(statement) + ": argument mismatch: expected arguments: " + miniScript->getArgumentInformation(getMethodName()));
251  miniScript->startErrorScript();
252  }
253  }
254  };
255  miniScript->registerMethod(new ScriptMethodQuaternionComputeMatrix(miniScript, TYPE_QUATERNION, TYPE_MATRIX4x4));
256  }
257 }
258 
259 void MiniScriptQuaternion::unsetScriptVariableValue(MiniScript::ScriptVariable& variable) const {
260  if (variable.getType() != getType()) return;
261  if (variable.getValuePtr() == 0ll) return;
262  //
263  delete static_cast<Quaternion*>((void*)variable.getValuePtr());
264  variable.setValuePtr(0ll);
265 }
266 
267 void MiniScriptQuaternion::setScriptVariableValue(MiniScript::ScriptVariable& variable, const void* value) const {
268  if (variable.getType() != getType()) return;
269  //
270  Quaternion quaternionValue;
271  if (value != 0ll) {
272  quaternionValue = *static_cast<const Quaternion*>(value);
273  }
274  //
275  if (variable.getValuePtr() != 0ll) {
276  *static_cast<Quaternion*>((void*)variable.getValuePtr()) = quaternionValue;
277  return;
278  }
279  //
280  variable.setValuePtr((uint64_t)(new Quaternion(quaternionValue)));
281 }
282 
283 void MiniScriptQuaternion::copyScriptVariable(MiniScript::ScriptVariable& to, const MiniScript::ScriptVariable& from) const {
284  //
285  Quaternion quaternionValue;
286  if (from.getType() == getType() && from.getValuePtr() != 0ll) {
287  quaternionValue = *static_cast<Quaternion*>((void*)from.getValuePtr());
288  }
289  //
290  const auto TYPE_QUATERNION = static_cast<MiniScript::ScriptVariableType>(getType());
291  to.setType(TYPE_QUATERNION);
292  *static_cast<Quaternion*>((void*)to.getValuePtr()) = quaternionValue;
293 }
294 
295 bool MiniScriptQuaternion::mul(MiniScript* miniScript, const span<MiniScript::ScriptVariable>& argumentValues, MiniScript::ScriptVariable& returnValue, const MiniScript::ScriptStatement& statement) const {
296  const auto TYPE_QUATERNION = static_cast<MiniScript::ScriptVariableType>(getType());
297  const auto TYPE_VECTOR3 = static_cast<MiniScript::ScriptVariableType>(miniScript->getDataTypeByClassName("vec3")->getType());
298  // quaternion
299  if (MiniScript::hasType(argumentValues, TYPE_QUATERNION) == true) {
300  // quaternion * quaternion
301  if (argumentValues[0].getType() == TYPE_QUATERNION &&
302  argumentValues[1].getType() == TYPE_QUATERNION) {
303  Quaternion a;
304  Quaternion b;
305  MiniScriptQuaternion::getQuaternionValue(TYPE_QUATERNION, argumentValues, 0, a, false);
306  MiniScriptQuaternion::getQuaternionValue(TYPE_QUATERNION, argumentValues, 1, b, false);
307  //
308  auto result = a * b;
309  returnValue.setType(TYPE_QUATERNION);
310  returnValue.setValue(&result);
311  //
312  return true;
313  } else
314  // quaternion * vec3
315  if (argumentValues[0].getType() == TYPE_QUATERNION &&
316  argumentValues[1].getType() == TYPE_VECTOR3) {
317  Quaternion a;
318  Vector3 b;
319  MiniScriptQuaternion::getQuaternionValue(TYPE_QUATERNION, argumentValues, 0, a, false);
320  MiniScriptVector3::getVector3Value(TYPE_VECTOR3, argumentValues, 1, b, false);
321  //
322  auto result = a * b;
323  returnValue.setType(TYPE_VECTOR3);
324  returnValue.setValue(&result);
325  //
326  return true;
327  } else
328  // vec3 * quaternion
329  if (argumentValues[0].getType() == TYPE_VECTOR3 &&
330  argumentValues[1].getType() == TYPE_QUATERNION) {
331  Vector3 a;
332  Quaternion b;
333  MiniScriptVector3::getVector3Value(TYPE_VECTOR3, argumentValues, 0, a, false);
334  MiniScriptQuaternion::getQuaternionValue(TYPE_QUATERNION, argumentValues, 1, b, false);
335  //
336  auto result = b * a;
337  returnValue.setType(TYPE_VECTOR3);
338  returnValue.setValue(&result);
339  //
340  return true;
341  } else {
342  Console::println("mul(): " + miniScript->getStatementInformation(statement) + ": argument mismatch: expected arguments: " + miniScript->getArgumentInformation("mul"));
343  miniScript->startErrorScript();
344  //
345  return false;
346  }
347  }
348  //
349  return false;
350 }
351 
352 bool MiniScriptQuaternion::div(MiniScript* miniScript, const span<MiniScript::ScriptVariable>& argumentValues, MiniScript::ScriptVariable& returnValue, const MiniScript::ScriptStatement& statement) const {
353  return false;
354 }
355 
356 bool MiniScriptQuaternion::add(MiniScript* miniScript, const span<MiniScript::ScriptVariable>& argumentValues, MiniScript::ScriptVariable& returnValue, const MiniScript::ScriptStatement& statement) const {
357  const auto TYPE_QUATERNION = static_cast<MiniScript::ScriptVariableType>(getType());
358  //
359  if (MiniScript::hasType(argumentValues, TYPE_QUATERNION) == true) {
360  Quaternion a;
361  Quaternion b;
362  if (MiniScriptQuaternion::getQuaternionValue(TYPE_QUATERNION, argumentValues, 0, a, false) == true &&
363  MiniScriptQuaternion::getQuaternionValue(TYPE_QUATERNION, argumentValues, 1, b, false) == true) {
364  //
365  auto result = a.clone().add(b);
366  returnValue.setType(TYPE_QUATERNION);
367  returnValue.setValue(&result);
368  //
369  return true;
370  } else {
371  Console::println("add(): " + miniScript->getStatementInformation(statement) + ": argument mismatch: expected arguments: " + miniScript->getArgumentInformation("add"));
372  miniScript->startErrorScript();
373  //
374  return false;
375  }
376  }
377  //
378  return false;
379 }
380 
381 bool MiniScriptQuaternion::sub(MiniScript* miniScript, const span<MiniScript::ScriptVariable>& argumentValues, MiniScript::ScriptVariable& returnValue, const MiniScript::ScriptStatement& statement) const {
382  const auto TYPE_QUATERNION = static_cast<MiniScript::ScriptVariableType>(getType());
383  //
384  if (MiniScript::hasType(argumentValues, TYPE_QUATERNION) == true) {
385  Quaternion a;
386  Quaternion b;
387  if (MiniScriptQuaternion::getQuaternionValue(TYPE_QUATERNION, argumentValues, 0, a, false) == true &&
388  MiniScriptQuaternion::getQuaternionValue(TYPE_QUATERNION, argumentValues, 1, b, false) == true) {
389  //
390  auto result = a.clone().sub(b);
391  returnValue.setType(TYPE_QUATERNION);
392  returnValue.setValue(&result);
393  //
394  return true;
395  } else {
396  Console::println("sub(): " + miniScript->getStatementInformation(statement) + ": argument mismatch: expected arguments: " + miniScript->getArgumentInformation("sub"));
397  miniScript->startErrorScript();
398  //
399  return false;
400  }
401  }
402  //
403  return false;
404 }
405 
406 const string& MiniScriptQuaternion::getClassName() const {
407  return CLASS_NAME;
408 }
409 
411  return TYPE_NAME;
412 }
413 
414 const string MiniScriptQuaternion::getValueAsString(const MiniScript::ScriptVariable& variable) const {
415  //
416  Quaternion quaternionValue;
417  if (variable.getType() == getType() && variable.getValuePtr() != 0ll) {
418  quaternionValue = *static_cast<Quaternion*>((void*)variable.getValuePtr());
419  }
420  return
421  "Quaternion(" +
422  to_string(quaternionValue[0]) + ", " +
423  to_string(quaternionValue[1]) + ", " +
424  to_string(quaternionValue[2]) + ", " +
425  to_string(quaternionValue[3]) + ")";
426 
427 }
428 
Quaternion class representing quaternion mathematical structure and operations with x,...
Definition: Quaternion.h:24
Quaternion & identity()
Creates identity quaternion.
Definition: Quaternion.h:226
Quaternion & add(const Quaternion &quaternion)
Adds quaternion.
Definition: Quaternion.h:239
Vector3 computeEulerAngles() const
Compute Euler angles.
Definition: Quaternion.h:404
Matrix4x4 computeMatrix() const
Computes a rotation matrix4x4 from this quaternion.
Definition: Quaternion.h:379
Quaternion & rotate(const Vector3 &axis, float angle)
Creates rotation quaternion.
Definition: Quaternion.h:361
Quaternion & sub(const Quaternion &quaternion)
Subtracts quaternion.
Definition: Quaternion.h:252
Quaternion & invert()
Inverts this quaternion.
Definition: Quaternion.h:336
Quaternion clone() const
Clones this quaternion.
Definition: Quaternion.h:427
Quaternion & normalize()
Normalizes this quaternion.
Definition: Quaternion.h:346
Vector3 class representing vector3 mathematical structure and operations with x, y,...
Definition: Vector3.h:20
Console class.
Definition: Console.h:29
static void println()
Print new line to console.
Definition: Console.cpp:92
Float class.
Definition: Float.h:27
MiniScript Matrix4x4 data type.
MiniScript Quaternion data type.
const string & getTypeAsString() const override
bool add(MiniScript *miniScript, const span< MiniScript::ScriptVariable > &argumentValues, MiniScript::ScriptVariable &returnValue, const MiniScript::ScriptStatement &statement) const override
bool sub(MiniScript *miniScript, const span< MiniScript::ScriptVariable > &argumentValues, MiniScript::ScriptVariable &returnValue, const MiniScript::ScriptStatement &statement) const override
void copyScriptVariable(MiniScript::ScriptVariable &to, const MiniScript::ScriptVariable &from) const override
void unsetScriptVariableValue(MiniScript::ScriptVariable &variable) const override
static bool getQuaternionValue(MiniScript::ScriptVariableType TYPE_QUATERNION, const span< MiniScript::ScriptVariable > &arguments, int idx, Quaternion &value, bool optional=false)
Get quaternion value from given variable.
bool div(MiniScript *miniScript, const span< MiniScript::ScriptVariable > &argumentValues, MiniScript::ScriptVariable &returnValue, const MiniScript::ScriptStatement &statement) const override
const string & getClassName() const override
bool mul(MiniScript *miniScript, const span< MiniScript::ScriptVariable > &argumentValues, MiniScript::ScriptVariable &returnValue, const MiniScript::ScriptStatement &statement) const override
const string getValueAsString(const MiniScript::ScriptVariable &variable) const override
void setScriptVariableValue(MiniScript::ScriptVariable &variable, const void *value) const override
MiniScript Vector3 data type.
static bool getVector3Value(MiniScript::ScriptVariableType TYPE_VECTOR3, const span< MiniScript::ScriptVariable > &arguments, int idx, Vector3 &value, bool optional=false)
Get vector3 value from given variable.