Port left unported celx commands to eigen

pull/110/head
Hleb Valoshka 2018-07-31 00:44:31 +03:00
parent f09115b34c
commit 2c0e4dcf56
10 changed files with 415 additions and 40 deletions

View File

@ -39,7 +39,9 @@
#include "celx_celestia.h"
#include "celx_gl.h"
#ifdef __CELVEC__
#include <celengine/eigenport.h>
#endif
// Older gcc versions used <strstream> instead of <sstream>.
@ -3004,7 +3006,11 @@ static int celestia_newvector(lua_State* l)
double y = Celx_SafeGetNumber(l, 3, AllErrors, "Second arg to celestia:newvector must be a number");
double z = Celx_SafeGetNumber(l, 4, AllErrors, "Third arg to celestia:newvector must be a number");
#ifdef __CELVEC__
vector_new(l, Vec3d(x,y,z));
#else
vector_new(l, Vector3d(x,y,z));
#endif
return 1;
}
@ -3051,20 +3057,28 @@ static int celestia_newrotation(lua_State* l)
double x = Celx_SafeGetNumber(l, 3, AllErrors, "arguments to celestia:newrotation must either be (vec, number) or four numbers");
double y = Celx_SafeGetNumber(l, 4, AllErrors, "arguments to celestia:newrotation must either be (vec, number) or four numbers");
double z = Celx_SafeGetNumber(l, 5, AllErrors, "arguments to celestia:newrotation must either be (vec, number) or four numbers");
#ifdef __CELVEC__
Quatd q(w, x, y, z);
#else
Quaterniond q(w, x, y, z);
#endif
rotation_new(l, q);
}
else
{
Vec3d* v = to_vector(l, 2);
auto v = to_vector(l, 2);
if (v == nullptr)
{
Celx_DoError(l, "newrotation: first argument must be a vector");
return 0;
}
double angle = Celx_SafeGetNumber(l, 3, AllErrors, "second argument to celestia:newrotation must be a number");
#ifdef __CELVEC__
Quatd q;
q.setAxisAngle(*v, angle);
#else
Quaterniond q(AngleAxisd(angle, v->normalized()));
#endif
rotation_new(l, q);
}
return 1;
@ -4471,6 +4485,7 @@ bool CelxLua::safeGetBoolean(int index,
}
#ifdef __CELVEC__
void CelxLua::newVector(const Vec3d& v)
{
vector_new(m_lua, v);
@ -4481,7 +4496,12 @@ void CelxLua::newVector(const Vector3d& v)
{
vector_new(m_lua, fromEigen(v));
}
#else
void CelxLua::newVector(const Vector3d& v)
{
vector_new(m_lua, v);
}
#endif
void CelxLua::newPosition(const UniversalCoord& uc)
{
@ -4489,7 +4509,11 @@ void CelxLua::newPosition(const UniversalCoord& uc)
}
#ifdef __CELVEC__
void CelxLua::newRotation(const Quatd& q)
#else
void CelxLua::newRotation(const Quaterniond& q)
#endif
{
rotation_new(m_lua, q);
}
@ -4509,12 +4533,20 @@ void CelxLua::newPhase(const TimelinePhase& phase)
phase_new(m_lua, phase);
}
#ifdef __CELVEC__
Vec3d* CelxLua::toVector(int n)
#else
Vector3d* CelxLua::toVector(int n)
#endif
{
return to_vector(m_lua, n);
}
#ifdef __CELVEC__
Quatd* CelxLua::toRotation(int n)
#else
Quaterniond* CelxLua::toRotation(int n)
#endif
{
return to_rotation(m_lua, n);
}

View File

@ -14,7 +14,10 @@
#include "celx_frame.h"
#include "celestiacore.h"
#include <celengine/observer.h>
#include <Eigen/Geometry>
#ifdef __CELVEC__
#include <celengine/eigenport.h>
#endif
using namespace Eigen;
@ -66,7 +69,11 @@ static int frame_from(lua_State* l)
CelestiaCore* appCore = celx.appCore(AllErrors);
UniversalCoord* uc = nullptr;
#ifdef __CELVEC__
Quatd* q = nullptr;
#else
Quaterniond* q = nullptr;
#endif
double jd = 0.0;
if (celx.isType(2, Celx_Position))
@ -92,7 +99,11 @@ static int frame_from(lua_State* l)
}
else
{
#ifdef __CELVEC__
Quatd q1 = fromEigen(frame->convertToUniversal(toEigen(*q), jd));
#else
Quaterniond q1 = frame->convertToUniversal(*q, jd);
#endif
celx.newRotation(q1);
}
@ -110,7 +121,11 @@ static int frame_to(lua_State* l)
CelestiaCore* appCore = celx.appCore(AllErrors);
UniversalCoord* uc = nullptr;
#ifdef __CELVEC__
Quatd* q = nullptr;
#else
Quaterniond* q = nullptr;
#endif
double jd = 0.0;
if (celx.isType(2, Celx_Position))
@ -137,8 +152,13 @@ static int frame_to(lua_State* l)
}
else
{
#ifdef __CELVEC__
Quaterniond q1 = frame->convertFromUniversal(toEigen(*q), jd);
celx.newRotation(fromEigen(q1));
#else
Quaterniond q1 = frame->convertFromUniversal(*q, jd);
celx.newRotation(q1);
#endif
}
return 1;

View File

@ -116,8 +116,13 @@ public:
void newObject(const Selection& sel);
void newPhase(const TimelinePhase& phase);
#ifdef __CELVEC__
Vec3d* toVector(int n);
Quatd* toRotation(int n);
#else
Eigen::Vector3d* toVector(int n);
Eigen::Quaterniond* toRotation(int n);
#endif
UniversalCoord* toPosition(int n);
Selection* toObject(int n);
ObserverFrame* toFrame(int n);

View File

@ -15,7 +15,10 @@
//#include <celengine/body.h>
//#include <celengine/timelinephase.h>
#include "celestiacore.h"
#include <Eigen/Geometry>
#ifdef __CELVEC__
#include <celengine/eigenport.h>
#endif
using namespace Eigen;
@ -103,13 +106,17 @@ static int observer_setorientation(lua_State* l)
Observer* o = this_observer(l);
Quatd* q = celx.toRotation(2);
auto q = celx.toRotation(2);
if (q == nullptr)
{
celx.doError("Argument to observer:setorientation must be a rotation");
return 0;
}
#ifdef __CELVEC__
o->setOrientation(toEigen(*q));
#else
o->setOrientation(*q);
#endif
return 0;
}
@ -119,7 +126,11 @@ static int observer_getorientation(lua_State* l)
celx.checkArgs(1, 1, "No arguments expected to observer:getorientation()");
Observer* o = this_observer(l);
#ifdef __CELVEC__
celx.newRotation(fromEigen(o->getOrientation()));
#else
celx.newRotation(o->getOrientation());
#endif
return 1;
}
@ -131,14 +142,19 @@ static int observer_rotate(lua_State* l)
Observer* o = this_observer(l);
Quatd* q = celx.toRotation(2);
auto q = celx.toRotation(2);
if (q == nullptr)
{
celx.doError("Argument to observer:setpos must be a rotation");
return 0;
}
#ifdef __CELVEC__
Quatf qf((float) q->w, (float) q->x, (float) q->y, (float) q->z);
o->rotate(toEigen(qf));
#else
o->rotate(q->cast<float>());
#endif
return 0;
}
@ -149,14 +165,19 @@ static int observer_orbit(lua_State* l)
Observer* o = this_observer(l);
Quatd* q = celx.toRotation(2);
auto q = celx.toRotation(2);
if (q == nullptr)
{
celx.doError("Argument for observer:orbit must be a rotation");
return 0;
}
#ifdef __CELVEC__
Quatf qf((float) q->w, (float) q->x, (float) q->y, (float) q->z);
o->orbit(Selection(), toEigen(qf));
#else
o->orbit(Selection(), q->cast<float>());
#endif
return 0;
}
@ -170,7 +191,12 @@ static int observer_lookat(lua_State* l)
UniversalCoord* from = nullptr;
UniversalCoord* to = nullptr;
#ifdef __CELVEC__
Vec3d* upd = nullptr;
#else
Vector3d* upd = nullptr;
#endif
if (argc == 3)
{
to = celx.toPosition(2);
@ -211,6 +237,7 @@ static int observer_lookat(lua_State* l)
{
nd = to->offsetFromKm(*from);
}
#ifdef __CELVEC__
// need Vec3f instead:
Vec3f up = Vec3f((float) upd->x, (float) upd->y, (float) upd->z);
Vec3f n = fromEigen(nd.cast<float>());
@ -221,6 +248,17 @@ static int observer_lookat(lua_State* l)
Vec3f u = v ^ n;
Quatf qf = Quatf(Mat3f(v, u, -n));
o->setOrientation(toEigen(qf));
#else
Vector3f up = upd->cast<float>();
Vector3f n = nd.cast<float>().normalized();
Vector3f v = n.cross(up).normalized();
Vector3f u = v.cross(n);
Matrix3f m;
m.row(0) = v; m.row(1) = u; m.row(2) = n * (-1);
o->setOrientation(Quaternionf(m));
#endif
return 0;
}
@ -267,16 +305,24 @@ static int observer_gototable(lua_State* l)
lua_pushstring(l, "initialOrientation");
lua_gettable(l, 2);
Quatd* rot1 = celx.toRotation(3);
auto rot1 = celx.toRotation(3);
if (rot1 != nullptr)
#ifdef __CELVEC__
jparams.initialOrientation = toEigen(*rot1);
#else
jparams.initialOrientation = *rot1;
#endif
lua_settop(l, 2);
lua_pushstring(l, "finalOrientation");
lua_gettable(l, 2);
Quatd* rot2 = celx.toRotation(3);
auto rot2 = celx.toRotation(3);
if (rot2 != nullptr)
#ifdef __CELVEC__
jparams.finalOrientation = toEigen(*rot2);
#else
jparams.finalOrientation = *rot2;
#endif
lua_settop(l, 2);
lua_pushstring(l, "startInterpolation");
@ -374,13 +420,17 @@ static int observer_gotolonglat(lua_State* l)
Vector3f up = Vector3f::UnitY();
if (lua_gettop(l) >= 7)
{
Vec3d* uparg = celx.toVector(7);
auto uparg = celx.toVector(7);
if (uparg == nullptr)
{
celx.doError("Sixth argument to observer:gotolonglat must be a vector");
return 0;
}
#ifdef __CELVEC__
up = toEigen(*uparg).cast<float>();
#else
up = uparg->cast<float>();
#endif
}
o->gotoSelectionLongLat(*sel, travelTime, distance, (float)longitude, (float)latitude, up);
@ -431,14 +481,18 @@ static int observer_gotodistance(lua_State* l)
Vector3f up = Vector3f::UnitY();
if (lua_gettop(l) > 4)
{
Vec3d* up_arg = celx.toVector(5);
auto up_arg = celx.toVector(5);
if (up_arg == nullptr)
{
celx.doError("Fourth arg to observer:gotodistance must be a vector");
return 0;
}
#ifdef __CELVEC__
up = toEigen(*up_arg).cast<float>();
#else
up = up_arg->cast<float>();
#endif
}
o->gotoSelection(*sel, travelTime, distance, up, ObserverFrame::Universal);

View File

@ -13,7 +13,9 @@
#include "celx_internal.h"
#include "celx_phase.h"
#include <celengine/timelinephase.h>
#ifdef __CELVEC__
#include <celengine/eigenport.h>
#endif
// We want to avoid copying TimelinePhase objects, so we can't make them
@ -186,7 +188,11 @@ static int phase_getorientation(lua_State* l)
tdb = phase->startTime();
else if (tdb > phase->endTime())
tdb = phase->endTime();
#ifdef __CELVEC__
celx.newRotation(fromEigen(phase->rotationModel()->orientationAtTime(tdb)));
#else
celx.newRotation(phase->rotationModel()->orientationAtTime(tdb));
#endif
return 1;
}

View File

@ -12,9 +12,14 @@
#include "celx.h"
#include "celx_internal.h"
#include "celx_position.h"
#include <Eigen/Geometry>
#ifdef __CELVEC__
#include <celengine/eigenport.h>
#endif
using namespace Eigen;
// ==================== Position ====================
// a 128-bit per component universal coordinate
int position_new(lua_State* l, const UniversalCoord& uc)
@ -164,7 +169,11 @@ static int position_vectorto(lua_State* l)
return 0;
}
#ifdef __CELVEC__
celx.newVector(fromEigen(uc2->offsetFromUly(*uc)));
#else
celx.newVector(uc2->offsetFromUly(*uc));
#endif
return 1;
}
@ -185,19 +194,28 @@ static int position_orientationto(lua_State* l)
return 1;
}
Vec3d* upd = celx.toVector(3);
auto upd = celx.toVector(3);
if (upd == nullptr)
{
celx.doError("Second argument to position:orientationto must be a vector");
return 1;
}
#ifdef __CELVEC__
Vec3d src2target = fromEigen(target->offsetFromKm(*src));
src2target.normalize();
Vec3d v = src2target ^ *upd;
v.normalize();
Vec3d u = v ^ src2target;
Quatd qd = Quatd(Mat3d(v, u, -src2target));
#else
Vector3d src2target = target->offsetFromKm(*src).normalized();
Vector3d v = src2target.cross(*upd).normalized();
Vector3d u = v.cross(src2target);
Matrix3d m;
m.row(0) = v; m.row(1) = u; m.row(2) = src2target * (-1);
Quaterniond qd(m);
#endif
celx.newRotation(qd);
return 1;
@ -240,7 +258,11 @@ static int position_add(lua_State* l)
celx.checkArgs(2, 2, "Need two operands for addition");
UniversalCoord* p1 = nullptr;
UniversalCoord* p2 = nullptr;
#ifdef __CELVEC__
Vec3d* v2 = nullptr;
#else
Vector3d* v2 = nullptr;
#endif
if (celx.isType(1, Celx_Position) && celx.isType(2, Celx_Position))
{
@ -254,7 +276,11 @@ static int position_add(lua_State* l)
{
p1 = celx.toPosition(1);
v2 = celx.toVector(2);
#ifdef __CELVEC__
celx.newPosition(p1->offsetUly(toEigen(*v2)));
#else
celx.newPosition(p1->offsetUly(*v2));
#endif
}
else
{
@ -271,7 +297,11 @@ static int position_sub(lua_State* l)
celx.checkArgs(2, 2, "Need two operands for subtraction");
UniversalCoord* p1 = nullptr;
UniversalCoord* p2 = nullptr;
#ifdef __CELVEC__
Vec3d* v2 = nullptr;
#else
Vector3d* v2 = nullptr;
#endif
if (celx.isType(1, Celx_Position) && celx.isType(2, Celx_Position))
{
@ -284,7 +314,11 @@ static int position_sub(lua_State* l)
{
p1 = celx.toPosition(1);
v2 = celx.toVector(2);
#ifdef __CELVEC__
celx.newPosition(p1->offsetUly(toEigen(*v2)));
#else
celx.newPosition(p1->offsetUly(*v2));
#endif
}
else
{
@ -300,7 +334,7 @@ static int position_addvector(lua_State* l)
celx.checkArgs(2, 2, "One argument expected to position:addvector()");
UniversalCoord* uc = this_position(l);
Vec3d* v3d = celx.toVector(2);
auto v3d = celx.toVector(2);
if (v3d == nullptr)
{
celx.doError("Vector expected as argument to position:addvector");
@ -308,7 +342,11 @@ static int position_addvector(lua_State* l)
else
if (uc != nullptr && v3d != nullptr)
{
#ifdef __CELVEC__
UniversalCoord ucnew = uc->offsetUly(toEigen(*v3d));
#else
UniversalCoord ucnew = uc->offsetUly(*v3d);
#endif
position_new(l, ucnew);
}
return 1;

View File

@ -13,12 +13,24 @@
#include "celx_internal.h"
#include "celx_vector.h"
#ifndef __CELVEC__
using namespace Eigen;
#endif
#ifdef __CELVEC__
int rotation_new(lua_State* l, const Quatd& qd)
#else
int rotation_new(lua_State* l, const Quaterniond& qd)
#endif
{
CelxLua celx(l);
#ifdef __CELVEC__
Quatd* q = reinterpret_cast<Quatd*>(lua_newuserdata(l, sizeof(Quatd)));
#else
auto q = reinterpret_cast<Quaterniond*>(lua_newuserdata(l, sizeof(Quaterniond)));
#endif
*q = qd;
celx.setClass(Celx_Rotation);
@ -26,20 +38,31 @@ int rotation_new(lua_State* l, const Quatd& qd)
return 1;
}
#ifdef __CELVEC__
Quatd* to_rotation(lua_State* l, int index)
#else
Quaterniond* to_rotation(lua_State* l, int index)
#endif
{
CelxLua celx(l);
#ifdef __CELVEC__
return static_cast<Quatd*>(celx.checkUserData(index, Celx_Rotation));
#else
return static_cast<Quaterniond*>(celx.checkUserData(index, Celx_Rotation));
#endif
}
#ifdef __CELVEC__
static Quatd* this_rotation(lua_State* l)
#else
static Quaterniond* this_rotation(lua_State* l)
#endif
{
CelxLua celx(l);
Quatd* q = to_rotation(l, 1);
auto q = to_rotation(l, 1);
if (q == nullptr)
{
celx.doError("Bad rotation object!");
@ -54,15 +77,22 @@ static int rotation_add(lua_State* l)
CelxLua celx(l);
celx.checkArgs(2, 2, "Need two operands for add");
Quatd* q1 = to_rotation(l, 1);
Quatd* q2 = to_rotation(l, 2);
auto q1 = to_rotation(l, 1);
auto q2 = to_rotation(l, 2);
if (q1 == nullptr || q2 == nullptr)
{
celx.doError("Addition only defined for two rotations");
}
else
{
Quatd result = *q1 + *q2;
#ifdef __CELVEC__
auto result = *q1 + *q2;
#else
Quaterniond result(q1->w() + q2->w(),
q1->x() + q2->x(),
q1->y() + q2->y(),
q1->z() + q2->z());
#endif
rotation_new(l, result);
}
return 1;
@ -74,9 +104,13 @@ static int rotation_mult(lua_State* l)
CelxLua celx(l);
celx.checkArgs(2, 2, "Need two operands for multiplication");
#ifdef __CELVEC__
Quatd* r1 = nullptr;
Quatd* r2 = nullptr;
//Vec3d* v = nullptr;
#else
Quaterniond* r1 = nullptr;
Quaterniond* r2 = nullptr;
#endif
lua_Number s = 0.0;
if (celx.isType(1, Celx_Rotation) && celx.isType(2, Celx_Rotation))
{
@ -89,14 +123,24 @@ static int rotation_mult(lua_State* l)
{
r1 = to_rotation(l, 1);
s = lua_tonumber(l, 2);
#ifdef __CELVEC__
rotation_new(l, *r1 * s);
#else
Quaterniond r(r1->w() * s, r1->x() * s, r1->y() * s, r1->x() * s);
rotation_new(l, r);
#endif
}
else
if (lua_isnumber(l, 1) && celx.isType(2, Celx_Rotation))
{
s = lua_tonumber(l, 1);
r1 = to_rotation(l, 2);
#ifdef __CELVEC__
rotation_new(l, *r1 * s);
#else
Quaterniond r(r1->w() * s, r1->x() * s, r1->y() * s, r1->x() * s);
rotation_new(l, r);
#endif
}
else
{
@ -111,8 +155,12 @@ static int rotation_imag(lua_State* l)
CelxLua celx(l);
celx.checkArgs(1, 1, "No arguments expected for rotation_imag");
Quatd* q = this_rotation(l);
auto q = this_rotation(l);
#ifdef __CELVEC__
vector_new(l, imag(*q));
#else
vector_new(l, q->vec());
#endif
return 1;
}
@ -122,8 +170,12 @@ static int rotation_real(lua_State* l)
CelxLua celx(l);
celx.checkArgs(1, 1, "No arguments expected for rotation_real");
Quatd* q = this_rotation(l);
auto q = this_rotation(l);
#ifdef __CELVEC__
lua_pushnumber(l, real(*q));
#else
lua_pushnumber(l, q->w());
#endif
return 1;
}
@ -133,14 +185,19 @@ static int rotation_transform(lua_State* l)
CelxLua celx(l);
celx.checkArgs(2, 2, "One argument expected for rotation:transform()");
Quatd* q = this_rotation(l);
Vec3d* v = to_vector(l, 2);
auto q = this_rotation(l);
auto v = to_vector(l, 2);
if (v == nullptr)
{
celx.doError("Argument to rotation:transform() must be a vector");
return 0;
}
#ifdef __CELVEC__
vector_new(l, *v * q->toMatrix3());
#else
// XXX or transpose() instead of .adjoint()?
vector_new(l, q->toRotationMatrix().adjoint() * (*v));
#endif
return 1;
}
@ -150,15 +207,19 @@ static int rotation_setaxisangle(lua_State* l)
CelxLua celx(l);
celx.checkArgs(3, 3, "Two arguments expected for rotation:setaxisangle()");
Quatd* q = this_rotation(l);
Vec3d* v = to_vector(l, 2);
auto q = this_rotation(l);
auto v = to_vector(l, 2);
if (v == nullptr)
{
celx.doError("setaxisangle: first argument must be a vector");
return 0;
}
double angle = celx.safeGetNumber(3, AllErrors, "second argument to rotation:setaxisangle must be a number");
#ifdef __CELVEC__
q->setAxisAngle(*v, angle);
#else
*q = Quaterniond(AngleAxisd(angle, v->normalized()));
#endif
return 0;
}
@ -168,15 +229,19 @@ static int rotation_slerp(lua_State* l)
CelxLua celx(l);
celx.checkArgs(3, 3, "Two arguments expected for rotation:slerp()");
Quatd* q1 = this_rotation(l);
Quatd* q2 = to_rotation(l, 2);
auto q1 = this_rotation(l);
auto q2 = to_rotation(l, 2);
if (q2 == nullptr)
{
celx.doError("slerp: first argument must be a rotation");
return 0;
}
double t = celx.safeGetNumber(3, AllErrors, "second argument to rotation:slerp must be a number");
#ifdef __CELVEC__
rotation_new(l, Quatd::slerp(*q1, *q2, t));
#else
rotation_new(l, q1->slerp(t, *q2));
#endif
return 1;
}
@ -186,17 +251,33 @@ static int rotation_get(lua_State* l)
CelxLua celx(l);
celx.checkArgs(2, 2, "Invalid access of rotation-component");
Quatd* q3 = this_rotation(l);
auto q3 = this_rotation(l);
string key = celx.safeGetString(2, AllErrors, "Invalid key in rotation-access");
double value = 0.0;
if (key == "x")
#ifdef __CELVEC__
value = imag(*q3).x;
#else
value = q3->x();
#endif
else if (key == "y")
#ifdef __CELVEC__
value = imag(*q3).y;
#else
value = q3->y();
#endif
else if (key == "z")
#ifdef __CELVEC__
value = imag(*q3).z;
#else
value = q3->z();
#endif
else if (key == "w")
#ifdef __CELVEC__
value = real(*q3);
#else
value = q3->w();
#endif
else
{
if (!lua_getmetatable(l, 1))
@ -219,24 +300,45 @@ static int rotation_set(lua_State* l)
CelxLua celx(l);
celx.checkArgs(3, 3, "Invalid access of rotation-component");
Quatd* q3 = this_rotation(l);
auto q3 = this_rotation(l);
string key = celx.safeGetString(2, AllErrors, "Invalid key in rotation-access");
double value = celx.safeGetNumber(3, AllErrors, "Rotation components must be numbers");
#ifdef __CELVEC__
Vec3d v = imag(*q3);
double w = real(*q3);
#else
Vector3d v = q3->vec();
double w = q3->w();
#endif
if (key == "x")
#ifdef __CELVEC__
v.x = value;
#else
v.x() = value;
#endif
else if (key == "y")
#ifdef __CELVEC__
v.y = value;
#else
v.y() = value;
#endif
else if (key == "z")
#ifdef __CELVEC__
v.z = value;
#else
v.z() = value;
#endif
else if (key == "w")
w = value;
else
{
celx.doError("Invalid key in rotation-access");
}
#ifdef __CELVEC__
*q3 = Quatd(w, v);
#else
*q3 = Quaterniond(w, v.x(), v.y(), v.z());
#endif
return 0;
}

View File

@ -12,12 +12,21 @@
#ifndef _CELX_ROTATION_H_
#define _CELX_ROTATION_H_
#ifdef __CELVEC__
#include <celmath/quaternion.h>
#else
#include <Eigen/Geometry>
#endif
struct lua_State;
extern void CreateRotationMetaTable(lua_State* l);
#ifdef __CELVEC__
extern int rotation_new(lua_State* l, const Quatd& qd);
extern Quatd* to_rotation(lua_State* l, int index);
#else
extern int rotation_new(lua_State* l, const Eigen::Quaterniond& qd);
extern Eigen::Quaterniond* to_rotation(lua_State* l, int index);
#endif
#endif // _CELX_ROTATION_H_

View File

@ -12,32 +12,56 @@
#include "celx.h"
#include "celx_internal.h"
#include "celx_vector.h"
#ifdef __CELVEC__
#include <celengine/eigenport.h>
#else
#include <Eigen/Geometry>
using namespace Eigen;
#endif
#ifdef __CELVEC__
int vector_new(lua_State* l, const Vec3d& v)
#else
int vector_new(lua_State* l, const Vector3d& v)
#endif
{
CelxLua celx(l);
#ifdef __CELVEC__
Vec3d* v3 = reinterpret_cast<Vec3d*>(lua_newuserdata(l, sizeof(Vec3d)));
#else
auto v3 = reinterpret_cast<Vector3d*>(lua_newuserdata(l, sizeof(Vector3d)));
#endif
*v3 = v;
celx.setClass(Celx_Vec3);
return 1;
}
#ifdef __CELVEC__
Vec3d* to_vector(lua_State* l, int index)
#else
Vector3d* to_vector(lua_State* l, int index)
#endif
{
CelxLua celx(l);
#ifdef __CELVEC__
return static_cast<Vec3d*>(celx.checkUserData(index, Celx_Vec3));
#else
return static_cast<Vector3d*>(celx.checkUserData(index, Celx_Vec3));
#endif
}
#ifdef __CELVEC__
static Vec3d* this_vector(lua_State* l)
#else
static Vector3d* this_vector(lua_State* l)
#endif
{
CelxLua celx(l);
Vec3d* v3 = to_vector(l, 1);
auto v3 = to_vector(l, 1);
if (v3 == nullptr)
{
celx.doError("Bad vector object!");
@ -52,15 +76,15 @@ static int vector_sub(lua_State* l)
CelxLua celx(l);
celx.checkArgs(2, 2, "Need two operands for sub");
Vec3d* op1 = celx.toVector(1);
Vec3d* op2 = celx.toVector(2);
auto op1 = celx.toVector(1);
auto op2 = celx.toVector(2);
if (op1 == nullptr || op2 == nullptr)
{
celx.doError("Subtraction only defined for two vectors");
}
else
{
Vec3d result = *op1 - *op2;
auto result = *op1 - *op2;
celx.newVector(result);
}
return 1;
@ -71,15 +95,27 @@ static int vector_get(lua_State* l)
CelxLua celx(l);
celx.checkArgs(2, 2, "Invalid access of vector-component");
Vec3d* v3 = this_vector(l);
auto v3 = this_vector(l);
string key = celx.safeGetString(2, AllErrors, "Invalid key in vector-access");
double value = 0.0;
if (key == "x")
#ifdef __CELVEC__
value = v3->x;
#else
value = v3->x();
#endif
else if (key == "y")
#ifdef __CELVEC__
value = v3->y;
#else
value = v3->y();
#endif
else if (key == "z")
#ifdef __CELVEC__
value = v3->z;
#else
value = v3->z();
#endif
else
{
if (!lua_getmetatable(l, 1))
@ -101,15 +137,27 @@ static int vector_set(lua_State* l)
CelxLua celx(l);
celx.checkArgs(3, 3, "Invalid access of vector-component");
Vec3d* v3 = this_vector(l);
auto v3 = this_vector(l);
string key = celx.safeGetString(2, AllErrors, "Invalid key in vector-access");
double value = celx.safeGetNumber(3, AllErrors, "Vector components must be numbers");
if (key == "x")
#ifdef __CELVEC__
v3->x = value;
#else
v3->x() = value;
#endif
else if (key == "y")
#ifdef __CELVEC__
v3->y = value;
#else
v3->y() = value;
#endif
else if (key == "z")
#ifdef __CELVEC__
v3->z = value;
#else
v3->z() = value;
#endif
else
{
celx.doError("Invalid key in vector-access");
@ -122,9 +170,13 @@ static int vector_getx(lua_State* l)
CelxLua celx(l);
celx.checkArgs(1, 1, "No arguments expected for vector:getx");
Vec3d* v3 = this_vector(l);
auto v3 = this_vector(l);
lua_Number x;
#ifdef __CELVEC__
x = static_cast<lua_Number>(v3->x);
#else
x = static_cast<lua_Number>(v3->x());
#endif
lua_pushnumber(l, x);
return 1;
@ -135,9 +187,13 @@ static int vector_gety(lua_State* l)
CelxLua celx(l);
celx.checkArgs(1, 1, "No arguments expected for vector:gety");
Vec3d* v3 = this_vector(l);
auto v3 = this_vector(l);
lua_Number y;
#ifdef __CELVEC__
y = static_cast<lua_Number>(v3->y);
#else
y = static_cast<lua_Number>(v3->y());
#endif
lua_pushnumber(l, y);
return 1;
@ -148,9 +204,13 @@ static int vector_getz(lua_State* l)
CelxLua celx(l);
celx.checkArgs(1, 1, "No arguments expected for vector:getz");
Vec3d* v3 = this_vector(l);
auto v3 = this_vector(l);
lua_Number z;
#ifdef __CELVEC__
z = static_cast<lua_Number>(v3->z);
#else
z = static_cast<lua_Number>(v3->z());
#endif
lua_pushnumber(l, z);
return 1;
@ -161,10 +221,14 @@ static int vector_normalize(lua_State* l)
CelxLua celx(l);
celx.checkArgs(1, 1, "No arguments expected for vector:normalize");
Vec3d* v = this_vector(l);
auto v = this_vector(l);
#ifdef __CELVEC__
Vec3d vn(*v);
vn.normalize();
celx.newVector(vn);
#else
celx.newVector(v->normalized());
#endif
return 1;
}
@ -173,8 +237,12 @@ static int vector_length(lua_State* l)
CelxLua celx(l);
celx.checkArgs(1, 1, "No arguments expected for vector:length");
Vec3d* v = this_vector(l);
auto v = this_vector(l);
#ifdef __CELVEC__
double length = v->length();
#else
double length = v->norm();
#endif
lua_pushnumber(l, (lua_Number)length);
return 1;
}
@ -184,8 +252,13 @@ static int vector_add(lua_State* l)
CelxLua celx(l);
celx.checkArgs(2, 2, "Need two operands for addition");
#ifdef __CELVEC__
Vec3d* v1 = nullptr;
Vec3d* v2 = nullptr;
#else
Vector3d* v1 = nullptr;
Vector3d* v2 = nullptr;
#endif
UniversalCoord* p = nullptr;
if (celx.isType(1, Celx_Vec3) && celx.isType(2, Celx_Vec3))
@ -199,7 +272,11 @@ static int vector_add(lua_State* l)
{
v1 = celx.toVector(1);
p = celx.toPosition(2);
#ifdef __CELVEC__
celx.newPosition(p->offsetUly(toEigen(*v1)));
#else
celx.newPosition(p->offsetUly(*v1));
#endif
}
else
{
@ -213,15 +290,25 @@ static int vector_mult(lua_State* l)
CelxLua celx(l);
celx.checkArgs(2, 2, "Need two operands for multiplication");
#ifdef __CELVEC__
Vec3d* v1 = nullptr;
Vec3d* v2 = nullptr;
Quatd* q = nullptr;
#else
Vector3d* v1 = nullptr;
Vector3d* v2 = nullptr;
Quaterniond* q = nullptr;
#endif
lua_Number s = 0.0;
if (celx.isType(1, Celx_Vec3) && celx.isType(2, Celx_Vec3))
{
v1 = celx.toVector(1);
v2 = celx.toVector(2);
#ifdef __CELVEC__
lua_pushnumber(l, *v1 * *v2);
#else
lua_pushnumber(l, (lua_Number)v1->dot(*v2));
#endif
}
else
if (celx.isType(1, Celx_Vec3) && lua_isnumber(l, 2))
@ -235,7 +322,11 @@ static int vector_mult(lua_State* l)
{
v1 = celx.toVector(1);
q = celx.toRotation(2);
#ifdef __CELVEC__
celx.newRotation(*v1 * *q);
#else
celx.newRotation(Quaterniond(0, v1->x(), v1->y(), v1->z()) * *q);
#endif
}
else
if (lua_isnumber(l, 1) && celx.isType(2, Celx_Vec3))
@ -256,13 +347,22 @@ static int vector_cross(lua_State* l)
CelxLua celx(l);
celx.checkArgs(2, 2, "Need two operands for multiplication");
#ifdef __CELVEC__
Vec3d* v1 = nullptr;
Vec3d* v2 = nullptr;
#else
Vector3d* v1 = nullptr;
Vector3d* v2 = nullptr;
#endif
if (celx.isType(1, Celx_Vec3) && celx.isType(2, Celx_Vec3))
{
v1 = celx.toVector(1);
v2 = celx.toVector(2);
#ifdef __CELVEC__
celx.newVector(*v1 ^ *v2);
#else
celx.newVector(v1->cross(*v2));
#endif
}
else
{

View File

@ -12,10 +12,19 @@
#ifndef _CELX_VECTOR_H_
#define _CELX_VECTOR_H_
#ifndef __CELVEC__
#include <Eigen/Geometry>
#endif
struct lua_State;
extern void CreateVectorMetaTable(lua_State* l);
#ifdef __CELVEC__
extern int vector_new(lua_State* l, const Vec3d& v);
extern Vec3d* to_vector(lua_State* l, int index);
#else
extern int vector_new(lua_State* l, const Eigen::Vector3d& v);
extern Eigen::Vector3d* to_vector(lua_State* l, int index);
#endif
#endif // _CELX_VECTOR_H_