Skip to content

Commit

Permalink
Add quaternion constants in celmath, use sincos in rotation matrix fu…
Browse files Browse the repository at this point in the history
…nctions
  • Loading branch information
ajtribick committed Oct 25, 2023
1 parent 53e5508 commit db3e89c
Show file tree
Hide file tree
Showing 11 changed files with 70 additions and 39 deletions.
9 changes: 5 additions & 4 deletions src/celengine/axisarrow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <algorithm>
#include <vector>
#include <celcompat/numbers.h>
#include <celmath/geomutil.h>
#include <celmath/mathlib.h>
#include <celmath/vecgl.h>
#include <celrender/linerenderer.h>
Expand Down Expand Up @@ -308,19 +309,19 @@ AxesReferenceMark::render(Renderer* renderer,
Eigen::Matrix4f labelTransformMatrix = labelTransform.matrix();

// x-axis
Eigen::Matrix4f xModelView = modelView * celmath::rotate(Eigen::AngleAxisf(90.0_deg, Eigen::Vector3f::UnitY()));
Eigen::Matrix4f xModelView = modelView * celmath::rotate(celmath::YRot90<float>);
glVertexAttrib4f(CelestiaGLProgram::ColorAttributeIndex, 1.0f, 0.0f, 0.0f, opacity);
prog->setMVPMatrices(projection, xModelView);
GetArrowVAO().draw();

// y-axis
Eigen::Matrix4f yModelView = modelView * celmath::rotate(Eigen::AngleAxisf(180.0_deg, Eigen::Vector3f::UnitY()));
Eigen::Matrix4f yModelView = modelView * celmath::rotate(celmath::YRot180<float>);
glVertexAttrib4f(CelestiaGLProgram::ColorAttributeIndex, 0.0f, 1.0f, 0.0f, opacity);
prog->setMVPMatrices(projection, yModelView);
GetArrowVAO().draw();

// z-axis
Eigen::Matrix4f zModelView = modelView * celmath::rotate(Eigen::AngleAxisf(-90.0_deg, Eigen::Vector3f::UnitX()));
Eigen::Matrix4f zModelView = modelView * celmath::rotate(celmath::XRot90Conjugate<float>);
glVertexAttrib4f(CelestiaGLProgram::ColorAttributeIndex, 0.0f, 0.0f, 1.0f, opacity);
prog->setMVPMatrices(projection, zModelView);
GetArrowVAO().draw();
Expand Down Expand Up @@ -455,7 +456,7 @@ BodyAxisArrows::BodyAxisArrows(const Body& _body) :
Eigen::Quaterniond
BodyAxisArrows::getOrientation(double tdb) const
{
return (Eigen::Quaterniond(Eigen::AngleAxis<double>(celestia::numbers::pi, Eigen::Vector3d::UnitY())) * body.getEclipticToBodyFixed(tdb)).conjugate();
return (celmath::YRot180<double> * body.getEclipticToBodyFixed(tdb)).conjugate();
}


Expand Down
2 changes: 1 addition & 1 deletion src/celengine/observer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ void Observer::setLocationFilter(uint64_t _locationFilter)

void Observer::reverseOrientation()
{
setOrientation(getOrientation() * Quaterniond(AngleAxisd(celestia::numbers::pi, Vector3d::UnitY())));
setOrientation(getOrientation() * celmath::YRot180<double>);
reverseFlag = !reverseFlag;
}

Expand Down
4 changes: 2 additions & 2 deletions src/celengine/planetgrid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <Eigen/Geometry>
#include <fmt/format.h>
#include <celcompat/numbers.h>
#include <celmath/geomutil.h>
#include <celmath/intersect.h>
#include <celmath/vecgl.h>
#include <celrender/linerenderer.h>
Expand Down Expand Up @@ -99,8 +100,7 @@ PlanetographicGrid::render(Renderer* renderer,
InitializeGeometry(*renderer);

// Compatibility
Eigen::Quaterniond q(Eigen::AngleAxis(celestia::numbers::pi, Eigen::Vector3d::UnitY()));
q *= body.getEclipticToBodyFixed(tdb);
Eigen::Quaterniond q = celmath::YRot180<double> * body.getEclipticToBodyFixed(tdb);
Eigen::Quaternionf qf = q.cast<float>();

// The grid can't be rendered exactly on the planet sphere, or
Expand Down
18 changes: 11 additions & 7 deletions src/celengine/skygrid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,10 +335,6 @@ SkyGrid::render(Renderer& renderer,
int windowWidth,
int windowHeight)
{
// 90 degree rotation about the x-axis used to transform coordinates
// to Celestia's system.
Quaterniond xrot90 = XRotation(-celestia::numbers::pi / 2.0);

auto vfov = static_cast<double>(renderer.getProjectionMode()->getFOV(observer.getZoom()));
double viewAspectRatio = static_cast<double>(windowWidth) / static_cast<double>(windowHeight);

Expand Down Expand Up @@ -369,7 +365,13 @@ SkyGrid::render(Renderer& renderer,
Vector3d c3( w, h, -1.0);

Quaterniond cameraOrientation = renderer.getCameraOrientation();
Matrix3d r = (cameraOrientation * xrot90 * m_orientation.conjugate() * xrot90.conjugate()).toRotationMatrix().transpose();

// 90 degree rotation about the x-axis used to transform coordinates
// to Celestia's system.
Matrix3d r = (cameraOrientation *
celmath::XRot90Conjugate<double> *
m_orientation.conjugate() *
celmath::XRot90<double>).toRotationMatrix().transpose();

// Transform the frustum corners by the camera and grid
// rotations.
Expand Down Expand Up @@ -481,13 +483,15 @@ SkyGrid::render(Renderer& renderer,
int endDec = (int) std::floor(DEG_MIN_SEC_TOTAL * (maxDec / celestia::numbers::pi) / (double) decIncrement) * decIncrement;

// Get the orientation at single precision
Quaterniond q = xrot90 * m_orientation * xrot90.conjugate();
Quaterniond q = celmath::XRot90Conjugate<double> * m_orientation * celmath::XRot90<double>;
Quaternionf orientationf = q.cast<float>();

// Radius of sphere is arbitrary, with the constraint that it shouldn't
// intersect the near or far plane of the view frustum.
Matrix4f m = renderer.getModelViewMatrix() *
celmath::rotate((xrot90 * m_orientation.conjugate() * xrot90.conjugate()).cast<float>()) *
celmath::rotate((celmath::XRot90Conjugate<double> *
m_orientation.conjugate() *
celmath::XRot90<double>).cast<float>()) *
celmath::scale(1000.0f);
Matrices matrices = {&renderer.getProjectionMatrix(), &m};

Expand Down
4 changes: 2 additions & 2 deletions src/celephem/customorbit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1366,8 +1366,8 @@ class PhobosOrbit : public CachingOrbit

// Orientation of the orbital plane with respect to the Laplacian plane
Eigen::Matrix3d Rorbit = (celmath::YRotation(node) *
celmath::XRotation(celmath::degToRad(i)) *
celmath::YRotation(w)).toRotationMatrix();
celmath::XRotation(celmath::degToRad(i)) *
celmath::YRotation(w)).toRotationMatrix();

// Rotate to the Earth's equatorial plane
constexpr double N = celmath::degToRad(refplane_RA);
Expand Down
6 changes: 2 additions & 4 deletions src/celephem/customrotation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class IAURotationModel : public CachingRotationModel
double inclination = 90.0 - poleDec;

if (flipped)
return celmath::XRotation(celestia::numbers::pi) *
return celmath::XRot180<double> *
celmath::XRotation(celmath::degToRad(-inclination)) *
celmath::YRotation(celmath::degToRad(-node));
else
Expand Down Expand Up @@ -176,9 +176,7 @@ class EarthRotationModel : public CachingRotationModel
Eigen::Quaterniond q = celmath::XRotation(obliquity) * celmath::ZRotation(-precession) * eclRotation.conjugate();

// convert to Celestia's coordinate system
return celmath::XRotation(celestia::numbers::pi / 2.0) *
q *
celmath::XRotation(-celestia::numbers::pi / 2.0);
return celmath::XRot90<double> * q * celmath::XRot90Conjugate<double>;
}

double getPeriod() const override
Expand Down
8 changes: 3 additions & 5 deletions src/celephem/samporient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,12 @@ class SampledOrientation : public RotationModel
void
SampledOrientation::addSample(double t, const Eigen::Quaternionf& q)
{
// 90 degree rotation about x-axis to convert orientation to Celestia's
// coordinate system.
static const Eigen::Quaternionf coordSysCorrection = celmath::XRotation((float) (celestia::numbers::pi / 2.0));

// TODO: add a check for out of sequence samples
OrientationSample& samp = samples.emplace_back();
samp.t = t;
samp.q = q * coordSysCorrection;
// 90 degree rotation about x-axis to convert orientation to Celestia's
// coordinate system.
samp.q = q * celmath::XRot90<float>;
}


Expand Down
7 changes: 4 additions & 3 deletions src/celephem/spicerotation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,10 @@ SpiceRotation::computeSpin(double jd) const
Eigen::Quaterniond q = Eigen::Quaterniond(Eigen::Map<Eigen::Matrix3d>(matrixData)).conjugate();

// Transform into Celestia's coordinate system
static const Eigen::Quaterniond Rx90 = celmath::XRotation(celestia::numbers::pi / 2.0);
static const Eigen::Quaterniond Ry180 = celmath::YRotation(celestia::numbers::pi);
return Ry180 * Rx90.conjugate() * q.conjugate() * Rx90;
return celmath::YRot180<double> *
celmath::XRot90Conjugate<double> *
q.conjugate() *
celmath::XRot90<double>;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/celestia/gtk/dialog-eclipse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ static gint eclipseGoto(GtkButton*, EclipseData* ed)

double distance = target.radius() * 4.0;
sim->gotoLocation(UniversalCoord::Zero().offsetKm(Vector3d::UnitX() * distance),
(YRotation(-celestia::numbers::pi / 2) * XRotation(-celestia::numbers::pi / 2)), 2.5);
(celmath::YRot90Conjugate<double> * celmath::XRot90Conjugate<double>), 2.5);

return TRUE;
}
Expand Down
2 changes: 1 addition & 1 deletion src/celestia/win32/wineclipses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ BOOL APIENTRY EclipseFinderProc(HWND hDlg,

double distance = target.radius() * 4.0;
sim->gotoLocation(UniversalCoord::Zero().offsetKm(Vector3d::UnitX() * distance),
YRotation(-celestia::numbers::pi / 2) * XRotation(-celestia::numbers::pi / 2),
celmath::YRot90Conjugate<double> * celmath::XRot90Conjugate<double>,
2.5);
}
break;
Expand Down
47 changes: 38 additions & 9 deletions src/celmath/geomutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,35 +15,64 @@
#include <Eigen/Core>
#include <Eigen/Geometry>

#include <celcompat/numbers.h>
#include "mathlib.h"

namespace celmath
{

template<class T> const inline Eigen::Quaternion<T> XRot90{ celestia::numbers::sqrt2_v<T> * T{0.5},
celestia::numbers::sqrt2_v<T> * T{0.5},
T{0},
T{0} };

template<class T> const inline Eigen::Quaternion<T> XRot180{ 0, 1, 0, 0 };

// Conjugate of 90 degree rotation = -90 degree rotation
template<class T> const inline Eigen::Quaternion<T> XRot90Conjugate{ celestia::numbers::sqrt2_v<T> * T{0.5},
-(celestia::numbers::sqrt2_v<T> * T{0.5}),
T{0},
T{0} };

template<class T> const inline Eigen::Quaternion<T> YRot90{ celestia::numbers::sqrt2_v<T> * T{0.5},
T{0},
celestia::numbers::sqrt2_v<T> * T{0.5},
T{0} };

template<class T> const inline Eigen::Quaternion<T> YRot180{ 0, 0, 1, 0 };

template<class T> const inline Eigen::Quaternion<T> YRot90Conjugate{ celestia::numbers::sqrt2_v<T> * T{0.5},
T{0},
-(celestia::numbers::sqrt2_v<T> * T{0.5}),
T{0} };

template<class T> Eigen::Quaternion<T>
XRotation(T radians)
{
using std::cos, std::sin;
T halfAngle = radians * static_cast<T>(0.5);
return Eigen::Quaternion<T>(cos(halfAngle), sin(halfAngle), 0, 0);
T s;
T c;
sincos(radians * static_cast<T>(0.5), s, c);
return Eigen::Quaternion<T>(c, s, 0, 0);
}


template<class T> Eigen::Quaternion<T>
YRotation(T radians)
{
using std::cos, std::sin;
T halfAngle = radians * static_cast<T>(0.5);
return Eigen::Quaternion<T>(cos(halfAngle), 0, sin(halfAngle), 0);
T s;
T c;
sincos(radians * static_cast<T>(0.5), s, c);
return Eigen::Quaternion<T>(c, 0, s, 0);
}


template<class T> Eigen::Quaternion<T>
ZRotation(T radians)
{
using std::cos, std::sin;
T halfAngle = radians * static_cast<T>(0.5);
return Eigen::Quaternion<T>(cos(halfAngle), 0, 0, sin(halfAngle));
T s;
T c;
sincos(radians * static_cast<T>(0.5), s, c);
return Eigen::Quaternion<T>(c, 0, 0, s);
}


Expand Down

0 comments on commit db3e89c

Please sign in to comment.