lua_quaternion.cpp
Go to the documentation of this file.
1 
7 #include "lua_quaternion.h"
8 
9 #include <argos3/core/utility/math/angles.h>
10 #include <argos3/core/utility/math/vector3.h>
11 #include <argos3/core/utility/math/quaternion.h>
12 
13 #include <argos3/core/wrappers/lua/lua_vector3.h>
14 #include <argos3/core/wrappers/lua/lua_utility.h>
15 
16 namespace argos {
17 
18  /****************************************/
19  /****************************************/
20 
21  const std::string CLuaQuaternion::m_strTypeId("argos3.quaternion");
22 
23  /****************************************/
24  /****************************************/
25 
26  void CLuaQuaternion::RegisterType(lua_State* pt_state) {
27  /* create a constructor as a global function */
28  lua_pushcfunction(pt_state, Create);
29  lua_setglobal(pt_state, "quaternion");
30  /* create a metatable for quaternions */
31  luaL_newmetatable(pt_state, m_strTypeId.c_str());
32  /* register metamethods */
33  CLuaUtility::AddToTable(pt_state, "__index", Index);
34  CLuaUtility::AddToTable(pt_state, "__newindex", NewIndex);
35  CLuaUtility::AddToTable(pt_state, "__tostring", ToString);
36  CLuaUtility::AddToTable(pt_state, "__eq", Equal);
37  CLuaUtility::AddToTable(pt_state, "__mul", Multiply);
38  CLuaUtility::AddToTable(pt_state, "normalize", Normalize);
39  CLuaUtility::AddToTable(pt_state, "toangleaxis", ToAngleAxis);
40  CLuaUtility::AddToTable(pt_state, "toeulerangles", ToEulerAngles);
41  CLuaUtility::AddToTable(pt_state, "inverse", Inverse);
42  }
43 
44  /****************************************/
45  /****************************************/
46 
47  int CLuaQuaternion::Create(lua_State* pt_state) {
48  /* parse arguments */
49  switch(lua_gettop(pt_state)) {
50  case 0:
51  PushQuaternion(pt_state);
52  /* default values */
53  break;
54  case 1:
55  /* copy constructor */
56  PushQuaternion(pt_state, ToQuaternion(pt_state, 1));
57  break;
58  case 2:
59  /* angle-axis constructor */
60  if(lua_isnumber(pt_state, 1)) {
61  CRadians cAngle(lua_tonumber(pt_state, 1));
62  const CVector3& cAxis = CLuaVector3::ToVector3(pt_state, 2);
63  PushQuaternion(pt_state, cAngle, cAxis);
64  }
65  else {
66  lua_pushstring(pt_state, "invalid arguments to quaternion");
67  lua_error(pt_state);
68  }
69  break;
70  case 4:
71  /* value constructor */
72  if(lua_isnumber(pt_state, 1) &&
73  lua_isnumber(pt_state, 2) &&
74  lua_isnumber(pt_state, 3) &&
75  lua_isnumber(pt_state, 4)) {
76  PushQuaternion(pt_state,
77  lua_tonumber(pt_state, 1),
78  lua_tonumber(pt_state, 2),
79  lua_tonumber(pt_state, 3),
80  lua_tonumber(pt_state, 4));
81  }
82  else {
83  lua_pushstring(pt_state, "invalid arguments to quaternion");
84  lua_error(pt_state);
85  }
86  break;
87  default:
88  lua_pushstring(pt_state, "invalid arguments to quaternion");
89  lua_error(pt_state);
90  break;
91  }
92  return 1;
93  }
94 
95  /****************************************/
96  /****************************************/
97 
99  int n_index) {
100  /* check type */
101  void* pvUserdatum =
102  luaL_checkudata(pt_state, n_index, m_strTypeId.c_str());
103  /* raise error if required */
104  if(pvUserdatum == nullptr) {
105  lua_pushstring(pt_state, "quaternion not found at requested index");
106  lua_error(pt_state);
107  }
108  /* return quaternion */
109  CQuaternion* pcQuaternion = static_cast<CQuaternion*>(pvUserdatum);
110  return *pcQuaternion;
111  }
112 
113  /****************************************/
114  /****************************************/
115 
116  int CLuaQuaternion::Index(lua_State* pt_state) {
117  if(lua_isuserdata(pt_state, 1) &&
118  lua_isstring(pt_state, 2)) {
119  size_t unLength = 0;
120  const char* pchKey = lua_tolstring(pt_state, 2, &unLength);
121  if(unLength == 1) {
122  CQuaternion& cQuaternion = ToQuaternion(pt_state, 1);
123  switch(pchKey[0]) {
124  case 'w':
125  lua_pushnumber(pt_state, cQuaternion.GetW());
126  break;
127  case 'x':
128  lua_pushnumber(pt_state, cQuaternion.GetX());
129  break;
130  case 'y':
131  lua_pushnumber(pt_state, cQuaternion.GetY());
132  break;
133  case 'z':
134  lua_pushnumber(pt_state, cQuaternion.GetZ());
135  break;
136  default:
137  lua_pushstring(pt_state, "invalid key for quaternion");
138  lua_error(pt_state);
139  }
140  return 1;
141  }
142  else {
143  luaL_getmetatable(pt_state, m_strTypeId.c_str());
144  lua_pushvalue(pt_state, 2);
145  lua_gettable(pt_state, -2);
146  return 1;
147  }
148  }
149  lua_pushstring(pt_state, "invalid operation on quaternion");
150  lua_error(pt_state);
151  return 0;
152  }
153 
154  /****************************************/
155  /****************************************/
156 
157  int CLuaQuaternion::NewIndex(lua_State* pt_state) {
158  if(lua_isuserdata(pt_state, 1) &&
159  lua_isstring(pt_state, 2) &&
160  lua_isnumber(pt_state, 3)) {
161  size_t unLength = 0;
162  const char* pchKey = lua_tolstring(pt_state, 2, &unLength);
163  if(unLength == 1) {
164  CQuaternion& cQuaternion = ToQuaternion(pt_state, 1);
165  switch(pchKey[0]) {
166  case 'w':
167  cQuaternion.SetW(lua_tonumber(pt_state, 3));
168  break;
169  case 'x':
170  cQuaternion.SetX(lua_tonumber(pt_state, 3));
171  break;
172  case 'y':
173  cQuaternion.SetY(lua_tonumber(pt_state, 3));
174  break;
175  case 'z':
176  cQuaternion.SetZ(lua_tonumber(pt_state, 3));
177  break;
178  default:
179  lua_pushstring(pt_state, "invalid key for quaternion");
180  lua_error(pt_state);
181  }
182  return 0;
183  }
184  }
185  lua_pushstring(pt_state, "invalid operation on quaternion");
186  lua_error(pt_state);
187  return 0;
188  }
189 
190  /****************************************/
191  /****************************************/
192 
193  int CLuaQuaternion::Equal(lua_State* pt_state) {
194  bool bEqual =
195  (ToQuaternion(pt_state, 1) == ToQuaternion(pt_state, 2));
196  /* push the result onto the stack and return it */
197  lua_pushboolean(pt_state, bEqual);
198  return 1;
199  }
200 
201  /****************************************/
202  /****************************************/
203 
204  int CLuaQuaternion::Multiply(lua_State* pt_state) {
205  /* perform the multiplication */
206  PushQuaternion(pt_state,
207  ToQuaternion(pt_state, 1) *
208  ToQuaternion(pt_state, 2));
209  return 1;
210  }
211 
212  /****************************************/
213  /****************************************/
214 
215  int CLuaQuaternion::Normalize(lua_State* pt_state) {
216  ToQuaternion(pt_state, 1).Normalize();
217  /* result is already on the stack, return it */
218  return 1;
219  }
220 
221  /****************************************/
222  /****************************************/
223 
224  int CLuaQuaternion::Inverse(lua_State* pt_state) {
225  /* push the result onto the stack and return it */
226  PushQuaternion(pt_state, ToQuaternion(pt_state, 1).Inverse());
227  return 1;
228  }
229 
230  /****************************************/
231  /****************************************/
232 
233  int CLuaQuaternion::ToAngleAxis(lua_State* pt_state) {
234  CRadians cAngle;
235  CVector3 cAxis;
236  /* get a reference to the operand from the stack */
237  const CQuaternion& cQuaternion = ToQuaternion(pt_state, 1);
238  /* do conversion */
239  cQuaternion.ToAngleAxis(cAngle, cAxis);
240  /* push the results onto the stack and return them */
241  lua_pushnumber(pt_state, cAngle.GetValue());
242  CLuaVector3::PushVector3(pt_state, cAxis);
243  return 2;
244  }
245 
246  /****************************************/
247  /****************************************/
248 
249  int CLuaQuaternion::ToEulerAngles(lua_State* pt_state) {
250  CRadians cZ, cY, cX;
251  /* get a reference to the operand from the stack */
252  const CQuaternion& cQuaternion = ToQuaternion(pt_state, 1);
253  /* do conversion */
254  cQuaternion.ToEulerAngles(cZ, cY, cX);
255  /* push the results onto the stack and return them */
256  lua_pushnumber(pt_state, cZ.GetValue());
257  lua_pushnumber(pt_state, cY.GetValue());
258  lua_pushnumber(pt_state, cX.GetValue());
259  return 3;
260  }
261 
262  /****************************************/
263  /****************************************/
264 
265  int CLuaQuaternion::ToString(lua_State* pt_state) {
266  /* get a reference to the operand from the stack */
267  const CQuaternion& cQuaternion = ToQuaternion(pt_state, 1);
268  /* convert it to a string */
269  std::ostringstream ossOutput;
270  ossOutput << cQuaternion;
271  /* push the string onto the stack and return it */
272  lua_pushstring(pt_state, ossOutput.str().c_str());
273  return 1;
274  }
275 
276  /****************************************/
277  /****************************************/
278 
279 }
The namespace containing all the ARGoS related code.
Definition: ci_actuator.h:12
It defines the basic type CRadians, used to store an angle value in radians.
Definition: angles.h:42
Real GetValue() const
Returns the value in radians.
Definition: angles.h:111
void SetX(Real f_x)
Definition: quaternion.h:69
Real GetW() const
Definition: quaternion.h:49
void ToAngleAxis(CRadians &c_angle, CVector3 &c_vector) const
Definition: quaternion.h:143
Real GetX() const
Definition: quaternion.h:53
void ToEulerAngles(CRadians &c_z_angle, CRadians &c_y_angle, CRadians &c_x_angle) const
Definition: quaternion.h:172
void SetZ(Real f_z)
Definition: quaternion.h:77
CQuaternion & Normalize()
Definition: quaternion.h:117
Real GetZ() const
Definition: quaternion.h:61
Real GetY() const
Definition: quaternion.h:57
void SetW(Real f_w)
Definition: quaternion.h:65
void SetY(Real f_y)
Definition: quaternion.h:73
A 3D vector class.
Definition: vector3.h:31
static CQuaternion & ToQuaternion(lua_State *pt_state, int n_index)
static int Normalize(lua_State *pt_state)
static int Inverse(lua_State *pt_state)
static int ToAngleAxis(lua_State *pt_state)
static void RegisterType(lua_State *pt_state)
static int ToEulerAngles(lua_State *pt_state)
static void PushQuaternion(lua_State *pt_state, TArguments &&... t_arguments)
static int NewIndex(lua_State *pt_state)
static int Equal(lua_State *pt_state)
static int ToString(lua_State *pt_state)
static int Create(lua_State *pt_state)
static int Multiply(lua_State *pt_state)
static int Index(lua_State *pt_state)
static void AddToTable(lua_State *pt_state, const std::string &str_key, void *pt_data)
Adds a pointer to a chunk of data with the given string key to the table located at the top of the st...
static void PushVector3(lua_State *pt_state, TArguments &&... t_arguments)
Definition: lua_vector3.h:37
static CVector3 & ToVector3(lua_State *pt_state, int n_index)
Definition: lua_vector3.cpp:87