celx_rotation.cpp
上传用户:center1979
上传日期:2022-07-26
资源大小:50633k
文件大小:6k
源码类别:

OpenGL

开发平台:

Visual C++

  1. // celx_rotation.cpp
  2. //
  3. // Copyright (C) 2003-2008, the Celestia Development Team
  4. //
  5. // Lua script extensions for Celestia: rotation object
  6. //
  7. // This program is free software; you can redistribute it and/or
  8. // modify it under the terms of the GNU General Public License
  9. // as published by the Free Software Foundation; either version 2
  10. // of the License, or (at your option) any later version.
  11. #include "celx.h"
  12. #include "celx_internal.h"
  13. #include "celx_vector.h"
  14. int rotation_new(lua_State* l, const Quatd& qd)
  15. {
  16.     CelxLua celx(l);
  17.     
  18.     Quatd* q = reinterpret_cast<Quatd*>(lua_newuserdata(l, sizeof(Quatd)));
  19.     *q = qd;
  20.     
  21.     celx.setClass(Celx_Rotation);
  22.     
  23.     return 1;
  24. }
  25. Quatd* to_rotation(lua_State* l, int index)
  26. {
  27.     CelxLua celx(l);
  28.     return static_cast<Quatd*>(celx.checkUserData(index, Celx_Rotation));
  29. }
  30. static Quatd* this_rotation(lua_State* l)
  31. {
  32.     CelxLua celx(l);
  33.     Quatd* q = to_rotation(l, 1);
  34.     if (q == NULL)
  35.     {
  36.         celx.doError("Bad rotation object!");
  37.     }
  38.     
  39.     return q;
  40. }
  41. static int rotation_add(lua_State* l)
  42. {
  43.     CelxLua celx(l);
  44.     celx.checkArgs(2, 2, "Need two operands for add");
  45.     Quatd* q1 = to_rotation(l, 1);
  46.     Quatd* q2 = to_rotation(l, 2);
  47.     if (q1 == NULL || q2 == NULL)
  48.     {
  49.         celx.doError("Addition only defined for two rotations");
  50.     }
  51.     else
  52.     {
  53.         Quatd result = *q1 + *q2;
  54.         rotation_new(l, result);
  55.     }
  56.     return 1;
  57. }
  58. static int rotation_mult(lua_State* l)
  59. {
  60.     CelxLua celx(l);
  61.     celx.checkArgs(2, 2, "Need two operands for multiplication");
  62.     Quatd* r1 = NULL;
  63.     Quatd* r2 = NULL;
  64.     //Vec3d* v = NULL;
  65.     lua_Number s = 0.0;
  66.     if (celx.isType(1, Celx_Rotation) && celx.isType(2, Celx_Rotation))
  67.     {
  68.         r1 = to_rotation(l, 1);
  69.         r2 = to_rotation(l, 2);
  70.         rotation_new(l, *r1 * *r2);
  71.     }
  72.     else
  73.         if (celx.isType(1, Celx_Rotation) && lua_isnumber(l, 2))
  74.         {
  75.             r1 = to_rotation(l, 1);
  76.             s = lua_tonumber(l, 2);
  77.             rotation_new(l, *r1 * s);
  78.         }
  79.     else
  80.         if (lua_isnumber(l, 1) && celx.isType(2, Celx_Rotation))
  81.         {
  82.             s = lua_tonumber(l, 1);
  83.             r1 = to_rotation(l, 2);
  84.             rotation_new(l, *r1 * s);
  85.         }
  86.     else
  87.     {
  88.         celx.doError("Bad rotation multiplication!");
  89.     }
  90.     return 1;
  91. }
  92. static int rotation_imag(lua_State* l)
  93. {
  94.     CelxLua celx(l);
  95.     celx.checkArgs(1, 1, "No arguments expected for rotation_imag");
  96.     Quatd* q = this_rotation(l);
  97.     vector_new(l, imag(*q));
  98.     return 1;
  99. }
  100. static int rotation_real(lua_State* l)
  101. {
  102.     CelxLua celx(l);
  103.     celx.checkArgs(1, 1, "No arguments expected for rotation_real");
  104.     Quatd* q = this_rotation(l);
  105.     lua_pushnumber(l, real(*q));
  106.     return 1;
  107. }
  108. static int rotation_transform(lua_State* l)
  109. {
  110.     CelxLua celx(l);
  111.     celx.checkArgs(2, 2, "One argument expected for rotation:transform()");
  112.     Quatd* q = this_rotation(l);
  113.     Vec3d* v = to_vector(l, 2);
  114.     if (v == NULL)
  115.     {
  116.         celx.doError("Argument to rotation:transform() must be a vector");
  117.     }
  118.     vector_new(l, *v * q->toMatrix3());
  119.     return 1;
  120. }
  121. static int rotation_setaxisangle(lua_State* l)
  122. {
  123.     CelxLua celx(l);
  124.     celx.checkArgs(3, 3, "Two arguments expected for rotation:setaxisangle()");
  125.     Quatd* q = this_rotation(l);
  126.     Vec3d* v = to_vector(l, 2);
  127.     if (v == NULL)
  128.     {
  129.         celx.doError("setaxisangle: first argument must be a vector");
  130.     }
  131.     double angle = celx.safeGetNumber(3, AllErrors, "second argument to rotation:setaxisangle must be a number");
  132.     q->setAxisAngle(*v, angle);
  133.     return 0;
  134. }
  135. static int rotation_slerp(lua_State* l)
  136. {
  137.     CelxLua celx(l);
  138.     celx.checkArgs(3, 3, "Two arguments expected for rotation:slerp()");
  139.     Quatd* q1 = this_rotation(l);
  140.     Quatd* q2 = to_rotation(l, 2);
  141.     if (q2 == NULL)
  142.     {
  143.         celx.doError("slerp: first argument must be a rotation");
  144.     }
  145.     double t = celx.safeGetNumber(3, AllErrors, "second argument to rotation:slerp must be a number");
  146.     rotation_new(l, Quatd::slerp(*q1, *q2, t));
  147.     return 1;
  148. }
  149. static int rotation_get(lua_State* l)
  150. {
  151.     CelxLua celx(l);
  152.     celx.checkArgs(2, 2, "Invalid access of rotation-component");
  153.     Quatd* q3 = this_rotation(l);
  154.     string key = celx.safeGetString(2, AllErrors, "Invalid key in rotation-access");
  155.     double value = 0.0;
  156.     if (key == "x")
  157.         value = imag(*q3).x;
  158.     else if (key == "y")
  159.         value = imag(*q3).y;
  160.     else if (key == "z")
  161.         value = imag(*q3).z;
  162.     else if (key == "w")
  163.         value = real(*q3);
  164.     else
  165.     {
  166.         if (lua_getmetatable(l, 1))
  167.         {
  168.             lua_pushvalue(l, 2);
  169.             lua_rawget(l, -2);
  170.             return 1;
  171.         }
  172.         else
  173.         {
  174.             celx.doError("Internal error: couldn't get metatable");
  175.         }
  176.     }
  177.     lua_pushnumber(l, (lua_Number)value);
  178.     return 1;
  179. }
  180. static int rotation_set(lua_State* l)
  181. {
  182.     CelxLua celx(l);
  183.     celx.checkArgs(3, 3, "Invalid access of rotation-component");
  184.     Quatd* q3 = this_rotation(l);
  185.     string key = celx.safeGetString(2, AllErrors, "Invalid key in rotation-access");
  186.     double value = celx.safeGetNumber(3, AllErrors, "Rotation components must be numbers");
  187.     Vec3d v = imag(*q3);
  188.     double w = real(*q3);
  189.     if (key == "x")
  190.         v.x = value;
  191.     else if (key == "y")
  192.         v.y = value;
  193.     else if (key == "z")
  194.         v.z = value;
  195.     else if (key == "w")
  196.         w = value;
  197.     else
  198.     {
  199.         celx.doError("Invalid key in rotation-access");
  200.     }
  201.     *q3 = Quatd(w, v);
  202.     return 0;
  203. }
  204. static int rotation_tostring(lua_State* l)
  205. {
  206.     CelxLua celx(l);
  207.     lua_pushstring(l, "[Rotation]");
  208.     return 1;
  209. }
  210. void CreateRotationMetaTable(lua_State* l)
  211. {
  212.     CelxLua celx(l);
  213.     
  214.     celx.createClassMetatable(Celx_Rotation);
  215.     
  216.     celx.registerMethod("real", rotation_real);
  217.     celx.registerMethod("imag", rotation_imag);
  218.     celx.registerMethod("transform", rotation_transform);
  219.     celx.registerMethod("setaxisangle", rotation_setaxisangle);
  220.     celx.registerMethod("slerp", rotation_slerp);
  221.     celx.registerMethod("__tostring", rotation_tostring);
  222.     celx.registerMethod("__add", rotation_add);
  223.     celx.registerMethod("__mul", rotation_mult);
  224.     celx.registerMethod("__index", rotation_get);
  225.     celx.registerMethod("__newindex", rotation_set);
  226.     
  227.     lua_pop(l, 1); // remove metatable from stack
  228. }