Index: celengine/observer.h =================================================================== --- celengine/observer.h (revision 4137) +++ celengine/observer.h (working copy) @@ -52,6 +52,7 @@ const Selection& _refObject, const Selection& _targetObj = Selection()); ObserverFrame(const ObserverFrame&); + ObserverFrame(const ReferenceFrame& f); ~ObserverFrame(); @@ -84,7 +85,7 @@ private: CoordinateSystem coordSys; - ReferenceFrame* frame; + const ReferenceFrame* frame; Selection targetObject; }; Index: celengine/observer.cpp =================================================================== --- celengine/observer.cpp (revision 4137) +++ celengine/observer.cpp (working copy) @@ -1416,6 +1416,10 @@ } +/*! Create a new frame with the specified coordinate system and + * reference object. The targetObject is only needed for phase + * lock frames; the argument is ignored for other frames. + */ ObserverFrame::ObserverFrame(CoordinateSystem _coordSys, const Selection& _refObject, const Selection& _targetObject) : @@ -1428,6 +1432,18 @@ } +/*! Create a new ObserverFrame with the specified reference frame. + * The coordinate system of this frame will be marked as unknown. + */ +ObserverFrame::ObserverFrame(const ReferenceFrame &f) : + coordSys(Unknown), + frame(&f) +{ + frame->addRef(); +} + + +/*! Copy constructor. */ ObserverFrame::ObserverFrame(const ObserverFrame& f) : coordSys(f.coordSys), frame(f.frame), Index: celestia/celx.cpp =================================================================== --- celestia/celx.cpp (revision 4137) +++ celestia/celx.cpp (working copy) @@ -3135,6 +3135,125 @@ } +/*! object:bodyfixedframe() + * + * Return the body-fixed frame for this object. + * + * Example: get the body-fixed frame of the Earth + * -- + * earth = celestia:find("Sol/Earth") + * ebf = earth:bodyfixedframe() + * + */ +static int object_bodyfixedframe(lua_State* l) +{ + checkArgs(l, 1, 1, "No arguments allowed for to object:bodyfixedframe"); + + Selection* sel = this_object(l); + frame_new(l, ObserverFrame(ObserverFrame::BodyFixed, *sel)); + + return 1; +} + + +/*! object:equatorialframe() + * + * Return the mean equatorial frame for this object. + * + * Example: get the equatorial frame of the Earth + * -- + * earth = celestia:find("Sol/Earth") + * eme = earth:equatorialframe() + * + */ +static int object_equatorialframe(lua_State* l) +{ + // TODO: allow one argument specifying a freeze time + checkArgs(l, 1, 1, "No arguments allowed for to object:equatorialframe"); + + Selection* sel = this_object(l); + frame_new(l, ObserverFrame(ObserverFrame::Equatorial, *sel)); + + return 1; +} + + +/*! object:orbitframe(time: t) + * + * Return the frame in which the orbit for an object is defined at a particular + * time. If time isn't specified, the current simulation time is assumed. The + * positions of stars and deep sky objects are always defined in the universal + * frame. + * + * Example: get the orbital frame for the Earth at the current time. + * -- + * earth = celestia:find("Sol/Earth") + * eof = earth:orbitframe() + * + */ +static int object_orbitframe(lua_State* l) +{ + checkArgs(l, 1, 2, "One or no arguments allowed for to object:orbitframe"); + + Selection* sel = this_object(l); + CelestiaCore* appCore = getAppCore(l, AllErrors); + + double t = safeGetNumber(l, 2, WrongType, "Time expected as argument to object:orbitframe", + appCore->getSimulation()->getTime()); + + if (sel->body() == NULL) + { + // The default universal frame + frame_new(l, ObserverFrame()); + } + else + { + const ReferenceFrame* f = sel->body()->getOrbitFrame(t); + frame_new(l, ObserverFrame(*f)); + } + + return 1; +} + + +/*! object:bodyframe(time: t) +* +* Return the frame in which the orientation for an object is defined at a +* particular time. If time isn't specified, the current simulation time is +* assumed. The positions of stars and deep sky objects are always defined +* in the universal frame. +* +* Example: get the curren body frame for the International Space Station. +* -- +* iss = celestia:find("Sol/Earth/ISS") +* f = iss:bodyframe() +* +*/ +static int object_bodyframe(lua_State* l) +{ + checkArgs(l, 1, 2, "One or no arguments allowed for to object:bodyframe"); + + Selection* sel = this_object(l); + CelestiaCore* appCore = getAppCore(l, AllErrors); + + double t = safeGetNumber(l, 2, WrongType, "Time expected as argument to object:orbitframe", + appCore->getSimulation()->getTime()); + + if (sel->body() == NULL) + { + // The default universal frame + frame_new(l, ObserverFrame()); + } + else + { + const ReferenceFrame* f = sel->body()->getBodyFrame(t); + frame_new(l, ObserverFrame(*f)); + } + + return 1; +} + + static void CreateObjectMetaTable(lua_State* l) { CreateClassMetatable(l, _Object); @@ -3152,7 +3271,7 @@ RegisterMethod(l, "type", object_type); RegisterMethod(l, "spectraltype", object_spectraltype); RegisterMethod(l, "getinfo", object_getinfo); - RegisterMethod(l, "catalognumber", object_catalognumber); + RegisterMethod(l, "catalognumber", object_catalognumber); RegisterMethod(l, "absmag", object_absmag); RegisterMethod(l, "name", object_name); RegisterMethod(l, "localname", object_localname); @@ -3161,6 +3280,10 @@ RegisterMethod(l, "getposition", object_getposition); RegisterMethod(l, "getchildren", object_getchildren); RegisterMethod(l, "locations", object_locations); + RegisterMethod(l, "bodyfixedframe", object_bodyfixedframe); + RegisterMethod(l, "equatorialframe", object_equatorialframe); + RegisterMethod(l, "orbitframe", object_orbitframe); + RegisterMethod(l, "bodyframe", object_bodyframe); RegisterMethod(l, "preloadtexture", object_preloadtexture); lua_pop(l, 1); // pop metatable off the stack