258 lines
5.9 KiB
C++
258 lines
5.9 KiB
C++
// celx_frame.cpp
|
|
//
|
|
// Copyright (C) 2003-2008, the Celestia Development Team
|
|
//
|
|
// Lua script extensions for Celestia: frame object
|
|
//
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License
|
|
// as published by the Free Software Foundation; either version 2
|
|
// of the License, or (at your option) any later version.
|
|
|
|
#include "celx.h"
|
|
#include "celx_internal.h"
|
|
#include "celx_frame.h"
|
|
#include <celestia/celestiacore.h>
|
|
#include <celengine/observer.h>
|
|
#include <Eigen/Geometry>
|
|
|
|
using namespace Eigen;
|
|
|
|
|
|
int frame_new(lua_State* l, const ObserverFrame& f)
|
|
{
|
|
CelxLua celx(l);
|
|
|
|
// Use placement new to put the new frame in the userdata block.
|
|
void* block = lua_newuserdata(l, sizeof(ObserverFrame));
|
|
new (block) ObserverFrame(f);
|
|
|
|
celx.setClass(Celx_Frame);
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
ObserverFrame* to_frame(lua_State* l, int index)
|
|
{
|
|
CelxLua celx(l);
|
|
|
|
return static_cast<ObserverFrame*>(celx.checkUserData(index, Celx_Frame));
|
|
}
|
|
|
|
|
|
static ObserverFrame* this_frame(lua_State* l)
|
|
{
|
|
CelxLua celx(l);
|
|
|
|
ObserverFrame* f = to_frame(l, 1);
|
|
if (f == nullptr)
|
|
{
|
|
celx.doError("Bad frame object!");
|
|
}
|
|
|
|
return f;
|
|
}
|
|
|
|
|
|
// Convert from frame coordinates to universal.
|
|
static int frame_from(lua_State* l)
|
|
{
|
|
CelxLua celx(l);
|
|
|
|
celx.checkArgs(2, 3, "Two or three arguments required for frame:from");
|
|
|
|
ObserverFrame* frame = this_frame(l);
|
|
CelestiaCore* appCore = celx.appCore(AllErrors);
|
|
|
|
UniversalCoord* uc = nullptr;
|
|
Quaterniond* q = nullptr;
|
|
double jd = 0.0;
|
|
|
|
if (celx.isType(2, Celx_Position))
|
|
{
|
|
uc = celx.toPosition(2);
|
|
}
|
|
else if (celx.isType(2, Celx_Rotation))
|
|
{
|
|
q = celx.toRotation(2);
|
|
}
|
|
if (uc == nullptr && q == nullptr)
|
|
{
|
|
celx.doError("Position or rotation expected as second argument to frame:from()");
|
|
return 0;
|
|
}
|
|
|
|
jd = celx.safeGetNumber(3, WrongType, "Second arg to frame:from must be a number", appCore->getSimulation()->getTime());
|
|
|
|
if (uc != nullptr)
|
|
{
|
|
UniversalCoord uc1 = frame->convertToUniversal(*uc, jd);
|
|
celx.newPosition(uc1);
|
|
}
|
|
else
|
|
{
|
|
Quaterniond q1 = frame->convertToUniversal(*q, jd);
|
|
celx.newRotation(q1);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
// Convert from universal to frame coordinates.
|
|
static int frame_to(lua_State* l)
|
|
{
|
|
CelxLua celx(l);
|
|
|
|
celx.checkArgs(2, 3, "Two or three arguments required for frame:to");
|
|
|
|
ObserverFrame* frame = this_frame(l);
|
|
CelestiaCore* appCore = celx.appCore(AllErrors);
|
|
|
|
UniversalCoord* uc = nullptr;
|
|
Quaterniond* q = nullptr;
|
|
double jd = 0.0;
|
|
|
|
if (celx.isType(2, Celx_Position))
|
|
{
|
|
uc = celx.toPosition(2);
|
|
}
|
|
else if (celx.isType(2, Celx_Rotation))
|
|
{
|
|
q = celx.toRotation(2);
|
|
}
|
|
|
|
if (uc == nullptr && q == nullptr)
|
|
{
|
|
celx.doError("Position or rotation expected as second argument to frame:to()");
|
|
return 0;
|
|
}
|
|
|
|
jd = celx.safeGetNumber(3, WrongType, "Second arg to frame:to must be a number", appCore->getSimulation()->getTime());
|
|
|
|
if (uc != nullptr)
|
|
{
|
|
UniversalCoord uc1 = frame->convertFromUniversal(*uc, jd);
|
|
celx.newPosition(uc1);
|
|
}
|
|
else
|
|
{
|
|
Quaterniond q1 = frame->convertFromUniversal(*q, jd);
|
|
celx.newRotation(q1);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int frame_getrefobject(lua_State* l)
|
|
{
|
|
CelxLua celx(l);
|
|
|
|
celx.checkArgs(1, 1, "No arguments expected for frame:getrefobject()");
|
|
|
|
ObserverFrame* frame = this_frame(l);
|
|
if (frame->getRefObject().getType() == Selection::Type_Nil)
|
|
{
|
|
celx.push(CelxValue());
|
|
}
|
|
else
|
|
{
|
|
celx.newObject(frame->getRefObject());
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int frame_gettargetobject(lua_State* l)
|
|
{
|
|
CelxLua celx(l);
|
|
|
|
celx.checkArgs(1, 1, "No arguments expected for frame:gettarget()");
|
|
|
|
ObserverFrame* frame = this_frame(l);
|
|
if (frame->getTargetObject().getType() == Selection::Type_Nil)
|
|
{
|
|
lua_pushnil(l);
|
|
}
|
|
else
|
|
{
|
|
celx.newObject(frame->getTargetObject());
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static int frame_getcoordinatesystem(lua_State* l)
|
|
{
|
|
CelxLua celx(l);
|
|
|
|
celx.checkArgs(1, 1, "No arguments expected for frame:getcoordinatesystem()");
|
|
|
|
ObserverFrame* frame = this_frame(l);
|
|
string coordsys;
|
|
switch (frame->getCoordinateSystem())
|
|
{
|
|
case ObserverFrame::Universal:
|
|
coordsys = "universal"; break;
|
|
case ObserverFrame::Ecliptical:
|
|
coordsys = "ecliptic"; break;
|
|
case ObserverFrame::Equatorial:
|
|
coordsys = "equatorial"; break;
|
|
case ObserverFrame::BodyFixed:
|
|
coordsys = "bodyfixed"; break;
|
|
case ObserverFrame::ObserverLocal:
|
|
coordsys = "observer"; break;
|
|
case ObserverFrame::PhaseLock:
|
|
coordsys = "lock"; break;
|
|
case ObserverFrame::Chase:
|
|
coordsys = "chase"; break;
|
|
default:
|
|
coordsys = "invalid";
|
|
}
|
|
|
|
celx.push(coordsys.c_str());
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int frame_tostring(lua_State* l)
|
|
{
|
|
CelxLua celx(l);
|
|
|
|
// TODO: print out the actual information about the frame
|
|
celx.push("[Frame]");
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
/*! Garbage collection metamethod frame objects.
|
|
*/
|
|
static int frame_gc(lua_State* l)
|
|
{
|
|
ObserverFrame* frame = this_frame(l);
|
|
|
|
// Explicitly call the destructor since the object was created with placement new
|
|
frame->~ObserverFrame();
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
void CreateFrameMetaTable(lua_State* l)
|
|
{
|
|
CelxLua celx(l);
|
|
|
|
celx.createClassMetatable(Celx_Frame);
|
|
|
|
celx.registerMethod("__tostring", frame_tostring);
|
|
celx.registerMethod("__gc", frame_gc);
|
|
celx.registerMethod("to", frame_to);
|
|
celx.registerMethod("from", frame_from);
|
|
celx.registerMethod("getcoordinatesystem", frame_getcoordinatesystem);
|
|
celx.registerMethod("getrefobject", frame_getrefobject);
|
|
celx.registerMethod("gettargetobject", frame_gettargetobject);
|
|
|
|
lua_pop(l, 1); // remove metatable from stack
|
|
}
|
|
|