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

OpenGL

开发平台:

Visual C++

  1. // celx_phase.cpp
  2. //
  3. // Copyright (C) 2003-2008, the Celestia Development Team
  4. //
  5. // Lua script extensions for Celestia: phase 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_phase.h"
  14. #include <celengine/timelinephase.h>
  15. // We want to avoid copying TimelinePhase objects, so we can't make them
  16. // userdata. But, they can't be lightuserdata either because they need to
  17. // be reference counted, and Lua doesn't garbage collect lightuserdata. The
  18. // solution is the PhaseReference object, which just wraps a TimelinePhase
  19. // pointer.
  20. class PhaseReference
  21. {
  22. public:
  23.     PhaseReference(const TimelinePhase& _phase) :
  24.     phase(&_phase)
  25. {
  26.         phase->addRef();
  27. }
  28. ~PhaseReference()
  29. {
  30.     phase->release();
  31. }
  32. const TimelinePhase* phase;
  33. };
  34. int phase_new(lua_State* l, const TimelinePhase& phase)
  35. {
  36.     CelxLua celx(l);
  37.     
  38.     // Use placement new to put the new phase reference in the userdata block.
  39.     void* block = lua_newuserdata(l, sizeof(PhaseReference));
  40.     new (block) PhaseReference(phase);
  41.     celx.setClass(Celx_Phase);
  42.     return 1;
  43. }
  44. static const TimelinePhase* to_phase(lua_State* l, int index)
  45. {
  46.     CelxLua celx(l);
  47.     
  48.     PhaseReference* ref = static_cast<PhaseReference*>(celx.checkUserData(index, Celx_Phase));
  49.     return ref == NULL ? NULL : ref->phase;
  50. }
  51. static const TimelinePhase* this_phase(lua_State* l)
  52. {
  53.     CelxLua celx(l);
  54.     
  55.     const TimelinePhase* phase = to_phase(l, 1);
  56.     if (phase == NULL)
  57.     {
  58.         celx.doError("Bad phase object!");
  59.     }
  60.     return phase;
  61. }
  62. /*! phase:timespan()
  63.  *
  64.  * Return the start and end times for this timeline phase.
  65.  *
  66.  * verbatim
  67.  * -- Example: retrieve the start and end times of the first phase
  68.  * -- of Cassini's timeline:
  69.  * --
  70.  * cassini = celestia:find("Sol/Cassini")
  71.  * phases = cassini:timeline()
  72.  * begintime, endtime = phases[1]:timespan()
  73.  *
  74.  * endverbatim
  75.  */
  76. static int phase_timespan(lua_State* l)
  77. {
  78.     CelxLua celx(l);
  79.     
  80.     celx.checkArgs(1, 1, "No arguments allowed for to phase:timespan");
  81.         
  82. const TimelinePhase* phase = this_phase(l);
  83.     celx.push(phase->startTime(), phase->endTime());
  84.     //lua_pushnumber(l, phase->startTime());
  85.     //lua_pushnumber(l, phase->endTime());
  86.     return 2;
  87. }
  88. /*! frame phase:orbitframe()
  89.  *
  90.  * Return the orbit frame for this timeline phase.
  91.  */
  92. static int phase_orbitframe(lua_State* l)
  93. {
  94.     CelxLua celx(l);
  95.     
  96.     celx.checkArgs(1, 1, "No arguments allowed for to phase:orbitframe");
  97.         
  98. const TimelinePhase* phase = this_phase(l);
  99.     const ReferenceFrame* f = phase->orbitFrame();
  100.     celx.newFrame(ObserverFrame(*f));
  101.     
  102.     return 1;
  103. }
  104. /*! frame phase:bodyframe()
  105.  *
  106.  * Return the body frame for this timeline phase.
  107.  */
  108. static int phase_bodyframe(lua_State* l)
  109. {
  110.     CelxLua celx(l);
  111.     
  112.     celx.checkArgs(1, 1, "No arguments allowed for to phase:bodyframe");
  113.         
  114. const TimelinePhase* phase = this_phase(l);
  115.     const ReferenceFrame* f = phase->bodyFrame();
  116.     celx.newFrame(ObserverFrame(*f));
  117.     
  118.     return 1;
  119. }
  120. /*! position phase:getposition(time: t)
  121.  *
  122.  * Return the position in frame coordinates at the specified time.
  123.  * Times outside the span covered by the phase are automatically clamped
  124.  * to either the beginning or ending of the span.
  125.  */
  126. static int phase_getposition(lua_State* l)
  127. {
  128.     CelxLua celx(l);
  129.     
  130.     celx.checkArgs(2, 2, "One argument required for phase:getposition");
  131.     const TimelinePhase* phase = this_phase(l);
  132.     double tdb = celx.safeGetNumber(2, WrongType, "Argument to phase:getposition() must be number", 0.0);
  133.     if (tdb < phase->startTime())
  134.         tdb = phase->startTime();
  135.     else if (tdb > phase->endTime())
  136.         tdb = phase->endTime();
  137.     celx.newPosition(UniversalCoord(phase->orbit()->positionAtTime(tdb) * astro::kilometersToMicroLightYears(1.0)));
  138.     return 1;
  139. }
  140. /*! rotation phase:getorientation(time: t)
  141.  *
  142.  * Return the orientation in frame coordinates at the specified time.
  143.  * Times outside the span covered by the phase are automatically clamped
  144.  * to either the beginning or ending of the span.
  145.  */
  146. static int phase_getorientation(lua_State* l)
  147. {
  148.     CelxLua celx(l);
  149.     
  150.     celx.checkArgs(2, 2, "One argument required for phase:getorientation");
  151.     const TimelinePhase* phase = this_phase(l);
  152.     double tdb = celx.safeGetNumber(2, WrongType, "Argument to phase:getorientation() must be number", 0.0);
  153.     if (tdb < phase->startTime())
  154.         tdb = phase->startTime();
  155.     else if (tdb > phase->endTime())
  156.         tdb = phase->endTime();
  157.     celx.newRotation(phase->rotationModel()->orientationAtTime(tdb));
  158.     return 1;
  159. }
  160. /*! __tostring metamethod
  161.  * Convert a phase to a string (currently just "[Phase]")
  162.  */
  163. static int phase_tostring(lua_State* l)
  164. {
  165.     lua_pushstring(l, "[Phase]");
  166.     return 1;
  167. }
  168. /*! __gc metamethod 
  169.  * Garbage collection for phases.
  170.  */
  171. static int phase_gc(lua_State* l)
  172. {
  173.     CelxLua celx(l);
  174.     
  175.     PhaseReference* ref = static_cast<PhaseReference*>(celx.checkUserData(1, Celx_Phase));
  176.     if (ref == NULL)
  177.     {
  178.         celx.doError("Bad phase object during garbage collection!");
  179.     }
  180.     else
  181.     {
  182.         // Explicitly call the destructor since the object was created with placement new
  183.         ref->~PhaseReference();
  184.     }
  185.     return 0;
  186. }
  187. void CreatePhaseMetaTable(lua_State* l)
  188. {
  189.     CelxLua celx(l);
  190.     
  191.     celx.createClassMetatable(Celx_Phase);
  192.     celx.registerMethod("__tostring", phase_tostring);
  193.     celx.registerMethod("__gc", phase_gc);
  194.     celx.registerMethod("timespan", phase_timespan);
  195.     celx.registerMethod("orbitframe", phase_orbitframe);
  196.     celx.registerMethod("bodyframe", phase_bodyframe);
  197.     celx.registerMethod("getposition", phase_getposition);
  198.     celx.registerMethod("getorientation", phase_getorientation);
  199.     lua_pop(l, 1); // remove metatable from stack
  200. }