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