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

OpenGL

开发平台:

Visual C++

  1. // celx_position.cpp
  2. //
  3. // Copyright (C) 2003-2008, the Celestia Development Team
  4. //
  5. // Lua script extensions for Celestia: position 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_position.h"
  14. // ==================== Position ====================
  15. // a 128-bit per component universal coordinate
  16. int position_new(lua_State* l, const UniversalCoord& uc)
  17. {
  18.     CelxLua celx(l);
  19.     UniversalCoord* ud = reinterpret_cast<UniversalCoord*>(lua_newuserdata(l, sizeof(UniversalCoord)));
  20.     *ud = uc;
  21.     
  22.     celx.setClass(Celx_Position);
  23.     
  24.     return 1;
  25. }
  26. UniversalCoord* to_position(lua_State* l, int index)
  27. {
  28.     CelxLua celx(l);
  29.     return static_cast<UniversalCoord*>(celx.checkUserData(index, Celx_Position));
  30. }
  31. static UniversalCoord* this_position(lua_State* l)
  32. {
  33.     CelxLua celx(l);
  34.     UniversalCoord* uc = to_position(l, 1);
  35.     if (uc == NULL)
  36.     {
  37.         celx.doError("Bad position object!");
  38.     }
  39.     
  40.     return uc;
  41. }
  42. static int position_get(lua_State* l)
  43. {
  44.     CelxLua celx(l);
  45.     celx.checkArgs(2, 2, "Invalid access of position-component");
  46.     UniversalCoord* uc = this_position(l);
  47.     string key = celx.safeGetString(2, AllErrors, "Invalid key in position-access");
  48.     double value = 0.0;
  49.     if (key == "x")
  50.         value = uc->x;
  51.     else if (key == "y")
  52.         value = uc->y;
  53.     else if (key == "z")
  54.         value = uc->z;
  55.     else
  56.     {
  57.         if (lua_getmetatable(l, 1))
  58.         {
  59.             lua_pushvalue(l, 2);
  60.             lua_rawget(l, -2);
  61.             return 1;
  62.         }
  63.         else
  64.         {
  65.             celx.doError("Internal error: couldn't get metatable");
  66.         }
  67.     }
  68.     lua_pushnumber(l, (lua_Number)value);
  69.     return 1;
  70. }
  71. static int position_set(lua_State* l)
  72. {
  73.     CelxLua celx(l);
  74.     celx.checkArgs(3, 3, "Invalid access of position-component");
  75.     UniversalCoord* uc = this_position(l);
  76.     string key = celx.safeGetString(2, AllErrors, "Invalid key in position-access");
  77.     double value = celx.safeGetNumber(3, AllErrors, "Position components must be numbers");
  78.     if (key == "x")
  79.         uc->x = value;
  80.     else if (key == "y")
  81.         uc->y = value;
  82.     else if (key == "z")
  83.         uc->z = value;
  84.     else
  85.     {
  86.         celx.doError("Invalid key in position-access");
  87.     }
  88.     return 0;
  89. }
  90. static int position_getx(lua_State* l)
  91. {
  92.     CelxLua celx(l);
  93.     celx.checkArgs(1, 1, "No arguments expected for position:getx()");
  94.     
  95.     UniversalCoord* uc = this_position(l);
  96.     lua_Number x;
  97.     x = uc->x;
  98.     lua_pushnumber(l, x);
  99.     
  100.     return 1;
  101. }
  102. static int position_gety(lua_State* l)
  103. {
  104.     CelxLua celx(l);
  105.     celx.checkArgs(1, 1, "No arguments expected for position:gety()");
  106.     
  107.     UniversalCoord* uc = this_position(l);
  108.     lua_Number y;
  109.     y = uc->y;
  110.     lua_pushnumber(l, y);
  111.     
  112.     return 1;
  113. }
  114. static int position_getz(lua_State* l)
  115. {
  116.     CelxLua celx(l);
  117.     celx.checkArgs(1, 1, "No arguments expected for position:getz()");
  118.     
  119.     UniversalCoord* uc = this_position(l);
  120.     lua_Number z;
  121.     z = uc->z;
  122.     lua_pushnumber(l, z);
  123.     
  124.     return 1;
  125. }
  126. static int position_vectorto(lua_State* l)
  127. {
  128.     CelxLua celx(l);
  129.     celx.checkArgs(2, 2, "One argument expected to position:vectorto");
  130.     
  131.     UniversalCoord* uc = this_position(l);
  132.     UniversalCoord* uc2 = to_position(l, 2);
  133.     
  134.     if (uc2 == NULL)
  135.     {
  136.         celx.doError("Argument to position:vectorto must be a position");
  137.     }
  138.     celx.newVector(*uc2 - *uc);
  139.     return 1;
  140. }
  141. static int position_orientationto(lua_State* l)
  142. {
  143.     CelxLua celx(l);
  144.     celx.checkArgs(3, 3, "Two arguments expected for position:orientationto");
  145.     
  146.     UniversalCoord* src = this_position(l);
  147.     UniversalCoord* target = to_position(l, 2);
  148.     
  149.     if (target == NULL)
  150.     {
  151.         celx.doError("First argument to position:orientationto must be a position");
  152.     }
  153.     
  154.     Vec3d* upd = celx.toVector(3);
  155.     if (upd == NULL)
  156.     {
  157.         celx.doError("Second argument to position:orientationto must be a vector");
  158.     }
  159.     
  160.     Vec3d src2target = *target - *src;
  161.     src2target.normalize();
  162.     Vec3d v = src2target ^ *upd;
  163.     v.normalize();
  164.     Vec3d u = v ^ src2target;
  165.     Quatd qd = Quatd(Mat3d(v, u, -src2target));
  166.     celx.newRotation(qd);
  167.     
  168.     return 1;
  169. }
  170. static int position_tostring(lua_State* l)
  171. {
  172.     // TODO: print out the coordinate as it would appear in a cel:// URL
  173.     lua_pushstring(l, "[Position]");
  174.     
  175.     return 1;
  176. }
  177. static int position_distanceto(lua_State* l)
  178. {
  179.     CelxLua celx(l);
  180.     celx.checkArgs(2, 2, "One argument expected to position:distanceto()");
  181.     
  182.     UniversalCoord* uc = this_position(l);
  183.     UniversalCoord* uc2 = to_position(l, 2);
  184.     if (uc2 == NULL)
  185.     {
  186.         celx.doError("Position expected as argument to position:distanceto");
  187.     }
  188.     
  189.     Vec3d v = *uc2 - *uc;
  190.     lua_pushnumber(l, astro::microLightYearsToKilometers(v.length()));
  191.     
  192.     return 1;
  193. }
  194. static int position_add(lua_State* l)
  195. {
  196.     CelxLua celx(l);
  197.     celx.checkArgs(2, 2, "Need two operands for addition");
  198.     UniversalCoord* p1 = NULL;
  199.     UniversalCoord* p2 = NULL;
  200.     Vec3d* v2 = NULL;
  201.     
  202.     if (celx.isType(1, Celx_Position) && celx.isType(2, Celx_Position))
  203.     {
  204.         p1 = celx.toPosition(1);
  205.         p2 = celx.toPosition(2);
  206.         // this is not very intuitive, as p1-p2 is a vector
  207.         celx.newPosition(*p1 + *p2);
  208.     }
  209.     else
  210.         if (celx.isType(1, Celx_Position) && celx.isType(2, Celx_Vec3))
  211.         {
  212.             p1 = celx.toPosition(1);
  213.             v2 = celx.toVector(2);
  214.             celx.newPosition(*p1 + *v2);
  215.         }
  216.     else
  217.     {
  218.         celx.doError("Bad position addition!");
  219.     }
  220.     return 1;
  221. }
  222. static int position_sub(lua_State* l)
  223. {
  224.     CelxLua celx(l);
  225.     celx.checkArgs(2, 2, "Need two operands for subtraction");
  226.     UniversalCoord* p1 = NULL;
  227.     UniversalCoord* p2 = NULL;
  228.     Vec3d* v2 = NULL;
  229.     
  230.     if (celx.isType(1, Celx_Position) && celx.isType(2, Celx_Position))
  231.     {
  232.         p1 = celx.toPosition(1);
  233.         p2 = celx.toPosition(2);
  234.         celx.newVector(*p1 - *p2);
  235.     }
  236.     else
  237.         if (celx.isType(1, Celx_Position) && celx.isType(2, Celx_Vec3))
  238.         {
  239.             p1 = celx.toPosition(1);
  240.             v2 = celx.toVector(2);
  241.             celx.newPosition(*p1 - *v2);
  242.         }
  243.     else
  244.     {
  245.         celx.doError("Bad position subtraction!");
  246.     }
  247.     return 1;
  248. }
  249. static int position_addvector(lua_State* l)
  250. {
  251.     CelxLua celx(l);
  252.     celx.checkArgs(2, 2, "One argument expected to position:addvector()");
  253.     UniversalCoord* uc = this_position(l);
  254.     Vec3d* v3d = celx.toVector(2);
  255.     if (v3d == NULL)
  256.     {
  257.         celx.doError("Vector expected as argument to position:addvector");
  258.     }
  259.     else
  260.         if (uc != NULL && v3d != NULL)
  261.         {
  262.             UniversalCoord ucnew = *uc + *v3d;
  263.             position_new(l, ucnew);
  264.         }
  265.     return 1;
  266. }
  267. void CreatePositionMetaTable(lua_State* l)
  268. {
  269.     CelxLua celx(l);
  270.     celx.createClassMetatable(Celx_Position);
  271.     
  272.     celx.registerMethod("__tostring", position_tostring);
  273.     celx.registerMethod("distanceto", position_distanceto);
  274.     celx.registerMethod("vectorto", position_vectorto);
  275.     celx.registerMethod("orientationto", position_orientationto);
  276.     celx.registerMethod("addvector", position_addvector);
  277.     celx.registerMethod("__add", position_add);
  278.     celx.registerMethod("__sub", position_sub);
  279.     celx.registerMethod("__index", position_get);
  280.     celx.registerMethod("__newindex", position_set);
  281.     celx.registerMethod("getx", position_getx);
  282.     celx.registerMethod("gety", position_gety);
  283.     celx.registerMethod("getz", position_getz);
  284.     
  285.     lua_pop(l, 1); // remove metatable from stack
  286. }