lua_vector3.cpp
Go to the documentation of this file.
1 
7 #include "lua_vector3.h"
8 
9 #include <argos3/core/utility/math/vector3.h>
10 #include <argos3/core/utility/math/quaternion.h>
11 
12 #include <argos3/core/wrappers/lua/lua_quaternion.h>
13 #include <argos3/core/wrappers/lua/lua_utility.h>
14 
15 namespace argos {
16 
17  /****************************************/
18  /****************************************/
19 
20  const std::string CLuaVector3::m_strTypeId("argos3.vector3");
21 
22  /****************************************/
23  /****************************************/
24 
25  void CLuaVector3::RegisterType(lua_State* pt_state) {
26  /* create a constructor as a global function */
27  lua_pushcfunction(pt_state, Create);
28  lua_setglobal(pt_state, "vector3");
29  /* create a metatable for vector3s */
30  luaL_newmetatable(pt_state, m_strTypeId.c_str());
31  /* register metamethods */
32  CLuaUtility::AddToTable(pt_state, "__index", Index);
33  CLuaUtility::AddToTable(pt_state, "__newindex", NewIndex);
34  CLuaUtility::AddToTable(pt_state, "__tostring", ToString);
35  CLuaUtility::AddToTable(pt_state, "__eq", Equal);
36  CLuaUtility::AddToTable(pt_state, "__add", Add);
37  CLuaUtility::AddToTable(pt_state, "__mul", Multiply);
38  CLuaUtility::AddToTable(pt_state, "__sub", Subtract);
39  CLuaUtility::AddToTable(pt_state, "__unm", UnaryMinus);
40  CLuaUtility::AddToTable(pt_state, "normalize", Normalize);
41  CLuaUtility::AddToTable(pt_state, "length", Length);
42  CLuaUtility::AddToTable(pt_state, "dot", DotProduct);
43  CLuaUtility::AddToTable(pt_state, "cross", CrossProduct);
44  CLuaUtility::AddToTable(pt_state, "rotate", Rotate);
45  }
46 
47  /****************************************/
48  /****************************************/
49 
50  int CLuaVector3::Create(lua_State* pt_state) {
51  /* parse arguments */
52  switch(lua_gettop(pt_state)) {
53  case 0:
54  /* default constructor */
55  PushVector3(pt_state);
56  break;
57  case 1:
58  /* copy constructor */
59  PushVector3(pt_state, ToVector3(pt_state, 1));
60  break;
61  case 3:
62  /* value constructor */
63  if(lua_isnumber(pt_state, 1) &&
64  lua_isnumber(pt_state, 2) &&
65  lua_isnumber(pt_state, 3)) {
66  PushVector3(pt_state,
67  lua_tonumber(pt_state, 1),
68  lua_tonumber(pt_state, 2),
69  lua_tonumber(pt_state, 3));
70  }
71  else {
72  lua_pushstring(pt_state, "invalid arguments to vector3");
73  lua_error(pt_state);
74  }
75  break;
76  default:
77  lua_pushstring(pt_state, "invalid arguments to vector3");
78  lua_error(pt_state);
79  break;
80  }
81  return 1;
82  }
83 
84  /****************************************/
85  /****************************************/
86 
87  CVector3& CLuaVector3::ToVector3(lua_State* pt_state,
88  int n_index) {
89  /* check type */
90  void* pvUserdatum =
91  luaL_checkudata(pt_state, n_index, m_strTypeId.c_str());
92  /* raise error if required */
93  if(pvUserdatum == nullptr) {
94  lua_pushstring(pt_state, "vector3 not found at requested index");
95  lua_error(pt_state);
96  }
97  /* return vector3 */
98  CVector3* pcVector3 = static_cast<CVector3*>(pvUserdatum);
99  return *pcVector3;
100  }
101 
102  /****************************************/
103  /****************************************/
104 
105  int CLuaVector3::Index(lua_State* pt_state) {
106  if(lua_isuserdata(pt_state, 1) &&
107  lua_isstring(pt_state, 2)) {
108  size_t unLength = 0;
109  const char* pchKey = lua_tolstring(pt_state, 2, &unLength);
110  if(unLength == 1) {
111  CVector3& cVector = ToVector3(pt_state, 1);
112  switch(pchKey[0]) {
113  case 'x':
114  lua_pushnumber(pt_state, cVector.GetX());
115  break;
116  case 'y':
117  lua_pushnumber(pt_state, cVector.GetY());
118  break;
119  case 'z':
120  lua_pushnumber(pt_state, cVector.GetZ());
121  break;
122  default:
123  lua_pushstring(pt_state, "invalid key for vector3");
124  lua_error(pt_state);
125  }
126  return 1;
127  }
128  else {
129  luaL_getmetatable(pt_state, m_strTypeId.c_str());
130  lua_pushvalue(pt_state, 2);
131  lua_gettable(pt_state, -2);
132  return 1;
133  }
134  }
135  lua_pushstring(pt_state, "invalid operation on vector3");
136  lua_error(pt_state);
137  return 0;
138  }
139 
140  /****************************************/
141  /****************************************/
142 
143  int CLuaVector3::NewIndex(lua_State* pt_state) {
144  if(lua_isuserdata(pt_state, 1) &&
145  lua_isstring(pt_state, 2) &&
146  lua_isnumber(pt_state, 3)) {
147  size_t unLength = 0;
148  const char* pchKey = lua_tolstring(pt_state, 2, &unLength);
149  if(unLength == 1) {
150  CVector3& cVector = ToVector3(pt_state, 1);
151  switch(pchKey[0]) {
152  case 'x':
153  cVector.SetX(lua_tonumber(pt_state, 3));
154  break;
155  case 'y':
156  cVector.SetY(lua_tonumber(pt_state, 3));
157  break;
158  case 'z':
159  cVector.SetZ(lua_tonumber(pt_state, 3));
160  break;
161  default:
162  lua_pushstring(pt_state, "invalid key for vector3");
163  lua_error(pt_state);
164  }
165  return 0;
166  }
167  }
168  lua_pushstring(pt_state, "invalid operation on vector3");
169  lua_error(pt_state);
170  return 0;
171  }
172 
173  /****************************************/
174  /****************************************/
175 
176  int CLuaVector3::Equal(lua_State* pt_state) {
177  bool bEqual =
178  (ToVector3(pt_state, 1) == ToVector3(pt_state, 2));
179  /* push the result onto the stack and return it */
180  lua_pushboolean(pt_state, bEqual);
181  return 1;
182  }
183 
184  /****************************************/
185  /****************************************/
186 
187  int CLuaVector3::Add(lua_State* pt_state) {
188  /* perform the addition */
189  PushVector3(pt_state,
190  ToVector3(pt_state, 1) +
191  ToVector3(pt_state, 2));
192  return 1;
193  }
194 
195  /****************************************/
196  /****************************************/
197 
198  int CLuaVector3::Multiply(lua_State* pt_state) {
199  if(lua_isuserdata(pt_state, 1) && lua_isnumber(pt_state, 2)) {
200  CVector3& cVector = ToVector3(pt_state, 1);
201  PushVector3(pt_state, cVector * lua_tonumber(pt_state, 2));
202  }
203  else if(lua_isuserdata(pt_state, 2) && lua_isnumber(pt_state, 1)) {
204  CVector3& cVector = ToVector3(pt_state, 2);
205  PushVector3(pt_state, cVector * lua_tonumber(pt_state, 1));
206  }
207  else {
208  lua_pushstring(pt_state, "invalid arguments for multiplication by scalar");
209  lua_error(pt_state);
210  }
211  return 1;
212  }
213 
214  /****************************************/
215  /****************************************/
216 
217  int CLuaVector3::Subtract(lua_State* pt_state) {
218  /* perform the subtraction */
219  PushVector3(pt_state,
220  ToVector3(pt_state, 1) -
221  ToVector3(pt_state, 2));
222  return 1;
223  }
224 
225  /****************************************/
226  /****************************************/
227 
228  int CLuaVector3::UnaryMinus(lua_State* pt_state) {
229  /* perform the negation */
230  PushVector3(pt_state, -ToVector3(pt_state, 1));
231  return 1;
232  }
233 
234  /****************************************/
235  /****************************************/
236 
237  int CLuaVector3::Normalize(lua_State* pt_state) {
238  ToVector3(pt_state, 1).Normalize();
239  /* result is already on the stack, return it */
240  return 1;
241  }
242 
243  /****************************************/
244  /****************************************/
245 
246  int CLuaVector3::Length(lua_State* pt_state) {
247  /* push the result onto the stack and return it */
248  lua_pushnumber(pt_state, ToVector3(pt_state, 1).Length());
249  return 1;
250  }
251 
252  /****************************************/
253  /****************************************/
254 
255  int CLuaVector3::CrossProduct(lua_State* pt_state) {
256  ToVector3(pt_state, 1).CrossProduct(ToVector3(pt_state, 2));
257  /* pop the second operand from the stack */
258  lua_pop(pt_state, 1);
259  /* return the first operand (modified) */
260  return 1;
261  }
262 
263  /****************************************/
264  /****************************************/
265 
266  int CLuaVector3::DotProduct(lua_State* pt_state) {
267  /* calculate the dot product */
268  Real fDotProduct =
269  ToVector3(pt_state, 1).DotProduct(ToVector3(pt_state, 2));
270  /* push the result onto the stack and return it */
271  lua_pushnumber(pt_state, fDotProduct);
272  return 1;
273  }
274 
275  /****************************************/
276  /****************************************/
277 
278  int CLuaVector3::Rotate(lua_State* pt_state) {
279  CVector3& cVector =
280  ToVector3(pt_state, 1);
281  CQuaternion& cQuaternion =
282  CLuaQuaternion::ToQuaternion(pt_state, 2);
283  /* rotate the first operand (the vector) by the second
284  operand (the quaternion) */
285  cVector.Rotate(cQuaternion);
286  /* pop the second operand (the quaternion) off the stack */
287  lua_pop(pt_state, 1);
288  /* return the first operand (the rotated vector) */
289  return 1;
290  }
291 
292  /****************************************/
293  /****************************************/
294 
295  int CLuaVector3::ToString(lua_State* pt_state) {
296  /* get a reference to the operand from the stack */
297  const CVector3& cVector = ToVector3(pt_state, 1);
298  /* convert it to a string */
299  std::ostringstream ossOutput;
300  ossOutput << cVector;
301  /* push the string onto the stack and return it */
302  lua_pushstring(pt_state, ossOutput.str().c_str());
303  return 1;
304  }
305 
306  /****************************************/
307  /****************************************/
308 
309 }
float Real
Collects all ARGoS code.
Definition: datatypes.h:39
The namespace containing all the ARGoS related code.
Definition: ci_actuator.h:12
A 3D vector class.
Definition: vector3.h:31
CVector3 & CrossProduct(const CVector3 &c_vector3)
Calculates the cross product between this vector and the passed one.
Definition: vector3.h:382
void SetY(const Real f_y)
Sets the y coordinate of this vector.
Definition: vector3.h:129
CVector3 & Rotate(const CQuaternion &c_quaternion)
Rotates this vector by the given quaternion.
Definition: vector3.cpp:23
Real GetX() const
Returns the x coordinate of this vector.
Definition: vector3.h:105
void SetX(const Real f_x)
Sets the x coordinate of this vector.
Definition: vector3.h:113
Real DotProduct(const CVector3 &c_vector3) const
Returns the dot product between this vector and the passed one.
Definition: vector3.h:369
CVector3 & Normalize()
Normalizes this vector.
Definition: vector3.h:237
void SetZ(const Real f_z)
Sets the z coordinate of this vector.
Definition: vector3.h:145
Real GetY() const
Returns the y coordinate of this vector.
Definition: vector3.h:121
Real GetZ() const
Returns the z coordinate of this vector.
Definition: vector3.h:137
static CQuaternion & ToQuaternion(lua_State *pt_state, int n_index)
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 int ToString(lua_State *pt_state)
static int Create(lua_State *pt_state)
Definition: lua_vector3.cpp:50
static int Multiply(lua_State *pt_state)
static int Normalize(lua_State *pt_state)
static void PushVector3(lua_State *pt_state, TArguments &&... t_arguments)
Definition: lua_vector3.h:37
static int DotProduct(lua_State *pt_state)
static void RegisterType(lua_State *pt_state)
Definition: lua_vector3.cpp:25
static int Equal(lua_State *pt_state)
static int UnaryMinus(lua_State *pt_state)
static int CrossProduct(lua_State *pt_state)
static CVector3 & ToVector3(lua_State *pt_state, int n_index)
Definition: lua_vector3.cpp:87
static int NewIndex(lua_State *pt_state)
static int Subtract(lua_State *pt_state)
static int Length(lua_State *pt_state)
static int Add(lua_State *pt_state)
static int Index(lua_State *pt_state)
static int Rotate(lua_State *pt_state)