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

OpenGL

开发平台:

Visual C++

  1. // celx_vector.cpp
  2. //
  3. // Copyright (C) 2003-2008, the Celestia Development Team
  4. //
  5. // Lua script extensions for Celestia: vector 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 vector_new(lua_State* l, const Vec3d& v)
  15. {
  16.     CelxLua celx(l);
  17.     Vec3d* v3 = reinterpret_cast<Vec3d*>(lua_newuserdata(l, sizeof(Vec3d)));
  18.     *v3 = v;
  19.     celx.setClass(Celx_Vec3);
  20.     
  21.     return 1;
  22. }
  23. Vec3d* to_vector(lua_State* l, int index)
  24. {
  25.     CelxLua celx(l);
  26.     return static_cast<Vec3d*>(celx.checkUserData(index, Celx_Vec3));
  27. }
  28. static Vec3d* this_vector(lua_State* l)
  29. {
  30.     CelxLua celx(l);
  31.     Vec3d* v3 = to_vector(l, 1);
  32.     if (v3 == NULL)
  33.     {
  34.         celx.doError("Bad vector object!");
  35.     }
  36.     
  37.     return v3;
  38. }
  39. static int vector_sub(lua_State* l)
  40. {
  41.     CelxLua celx(l);
  42.     celx.checkArgs(2, 2, "Need two operands for sub");
  43.     Vec3d* op1 = celx.toVector(1);
  44.     Vec3d* op2 = celx.toVector(2);
  45.     if (op1 == NULL || op2 == NULL)
  46.     {
  47.         celx.doError("Subtraction only defined for two vectors");
  48.     }
  49.     else
  50.     {
  51.         Vec3d result = *op1 - *op2;
  52.         celx.newVector(result);
  53.     }
  54.     return 1;
  55. }
  56. static int vector_get(lua_State* l)
  57. {
  58.     CelxLua celx(l);
  59.     celx.checkArgs(2, 2, "Invalid access of vector-component");
  60.     Vec3d* v3 = this_vector(l);
  61.     string key = celx.safeGetString(2, AllErrors, "Invalid key in vector-access");
  62.     double value = 0.0;
  63.     if (key == "x")
  64.         value = v3->x;
  65.     else if (key == "y")
  66.         value = v3->y;
  67.     else if (key == "z")
  68.         value = v3->z;
  69.     else
  70.     {
  71.         if (lua_getmetatable(l, 1))
  72.         {
  73.             lua_pushvalue(l, 2);
  74.             lua_rawget(l, -2);
  75.             return 1;
  76.         }
  77.         else
  78.         {
  79.             celx.doError("Internal error: couldn't get metatable");
  80.         }
  81.     }
  82.     lua_pushnumber(l, (lua_Number)value);
  83.     return 1;
  84. }
  85. static int vector_set(lua_State* l)
  86. {
  87.     CelxLua celx(l);
  88.     celx.checkArgs(3, 3, "Invalid access of vector-component");
  89.     Vec3d* v3 = this_vector(l);
  90.     string key = celx.safeGetString(2, AllErrors, "Invalid key in vector-access");
  91.     double value = celx.safeGetNumber(3, AllErrors, "Vector components must be numbers");
  92.     if (key == "x")
  93.         v3->x = value;
  94.     else if (key == "y")
  95.         v3->y = value;
  96.     else if (key == "z")
  97.         v3->z = value;
  98.     else
  99.     {
  100.         celx.doError("Invalid key in vector-access");
  101.     }
  102.     return 0;
  103. }
  104. static int vector_getx(lua_State* l)
  105. {
  106.     CelxLua celx(l);
  107.     celx.checkArgs(1, 1, "No arguments expected for vector:getx");
  108.     Vec3d* v3 = this_vector(l);
  109.     lua_Number x;
  110.     x = static_cast<lua_Number>(v3->x);
  111.     lua_pushnumber(l, x);
  112.     
  113.     return 1;
  114. }
  115. static int vector_gety(lua_State* l)
  116. {
  117.     CelxLua celx(l);
  118.     celx.checkArgs(1, 1, "No arguments expected for vector:gety");
  119.     Vec3d* v3 = this_vector(l);
  120.     lua_Number y;
  121.     y = static_cast<lua_Number>(v3->y);
  122.     lua_pushnumber(l, y);
  123.     
  124.     return 1;
  125. }
  126. static int vector_getz(lua_State* l)
  127. {
  128.     CelxLua celx(l);
  129.     celx.checkArgs(1, 1, "No arguments expected for vector:getz");
  130.     Vec3d* v3 = this_vector(l);
  131.     lua_Number z;
  132.     z = static_cast<lua_Number>(v3->z);
  133.     lua_pushnumber(l, z);
  134.     
  135.     return 1;
  136. }
  137. static int vector_normalize(lua_State* l)
  138. {
  139.     CelxLua celx(l);
  140.     celx.checkArgs(1, 1, "No arguments expected for vector:normalize");
  141.     Vec3d* v = this_vector(l);
  142.     Vec3d vn(*v);
  143.     vn.normalize();
  144.     celx.newVector(vn);
  145.     return 1;
  146. }
  147. static int vector_length(lua_State* l)
  148. {
  149.     CelxLua celx(l);
  150.     celx.checkArgs(1, 1, "No arguments expected for vector:length");
  151.     Vec3d* v = this_vector(l);
  152.     double length = v->length();
  153.     lua_pushnumber(l, (lua_Number)length);
  154.     return 1;
  155. }
  156. static int vector_add(lua_State* l)
  157. {
  158.     CelxLua celx(l);
  159.     celx.checkArgs(2, 2, "Need two operands for addition");
  160.     Vec3d* v1 = NULL;
  161.     Vec3d* v2 = NULL;
  162.     UniversalCoord* p = NULL;
  163.     
  164.     if (celx.isType(1, Celx_Vec3) && celx.isType(2, Celx_Vec3))
  165.     {
  166.         v1 = celx.toVector(1);
  167.         v2 = celx.toVector(2);
  168.         celx.newVector(*v1 + *v2);
  169.     }
  170.     else
  171.         if (celx.isType(1, Celx_Vec3) && celx.isType(2, Celx_Position))
  172.         {
  173.             v1 = celx.toVector(1);
  174.             p = celx.toPosition(2);
  175.             celx.newPosition(*p + *v1);
  176.         }
  177.     else
  178.     {
  179.         celx.doError("Bad vector addition!");
  180.     }
  181.     return 1;
  182. }
  183. static int vector_mult(lua_State* l)
  184. {
  185.     CelxLua celx(l);
  186.     celx.checkArgs(2, 2, "Need two operands for multiplication");
  187.     Vec3d* v1 = NULL;
  188.     Vec3d* v2 = NULL;
  189.     Quatd* q = NULL;
  190.     lua_Number s = 0.0;
  191.     if (celx.isType(1, Celx_Vec3) && celx.isType(2, Celx_Vec3))
  192.     {
  193.         v1 = celx.toVector(1);
  194.         v2 = celx.toVector(2);
  195.         lua_pushnumber(l, *v1 * *v2);
  196.     }
  197.     else
  198.         if (celx.isType(1, Celx_Vec3) && lua_isnumber(l, 2))
  199.         {
  200.             v1 = celx.toVector(1);
  201.             s = lua_tonumber(l, 2);
  202.             celx.newVector(*v1 * s);
  203.         }
  204.     else
  205.         if (celx.isType(1, Celx_Vec3) && celx.isType(2, Celx_Rotation))
  206.         {
  207.             v1 = celx.toVector(1);
  208.             q = celx.toRotation(2);
  209.             celx.newRotation(*v1 * *q);
  210.         }
  211.     else
  212.         if (lua_isnumber(l, 1) && celx.isType(2, Celx_Vec3))
  213.         {
  214.             s = lua_tonumber(l, 1);
  215.             v1 = celx.toVector(2);
  216.             celx.newVector(*v1 * s);
  217.         }
  218.     else
  219.     {
  220.         celx.doError("Bad vector multiplication!");
  221.     }
  222.     return 1;
  223. }
  224. static int vector_cross(lua_State* l)
  225. {
  226.     CelxLua celx(l);
  227.     celx.checkArgs(2, 2, "Need two operands for multiplication");
  228.     Vec3d* v1 = NULL;
  229.     Vec3d* v2 = NULL;
  230.     if (celx.isType(1, Celx_Vec3) && celx.isType(2, Celx_Vec3))
  231.     {
  232.         v1 = celx.toVector(1);
  233.         v2 = celx.toVector(2);
  234.         celx.newVector(*v1 ^ *v2);
  235.     }
  236.     else
  237.     {
  238.         celx.doError("Bad vector multiplication!");
  239.     }
  240.     return 1;
  241.     
  242. }
  243. static int vector_tostring(lua_State* l)
  244. {
  245.     lua_pushstring(l, "[Vector]");
  246.     return 1;
  247. }
  248. void CreateVectorMetaTable(lua_State* l)
  249. {
  250.     CelxLua celx(l);
  251.     celx.createClassMetatable(Celx_Vec3);
  252.     
  253.     celx.registerMethod("__tostring", vector_tostring);
  254.     celx.registerMethod("__add", vector_add);
  255.     celx.registerMethod("__sub", vector_sub);
  256.     celx.registerMethod("__mul", vector_mult);
  257.     celx.registerMethod("__pow", vector_cross);
  258.     celx.registerMethod("__index", vector_get);
  259.     celx.registerMethod("__newindex", vector_set);
  260.     celx.registerMethod("getx", vector_getx);
  261.     celx.registerMethod("gety", vector_gety);
  262.     celx.registerMethod("getz", vector_getz);
  263.     celx.registerMethod("normalize", vector_normalize);
  264.     celx.registerMethod("length", vector_length);
  265.     
  266.     lua_pop(l, 1); // remove metatable from stack
  267. }