Implemented phase lock and sync follow modes for stars.
parent
91caabf6df
commit
252182a102
|
@ -27,7 +27,7 @@ RigidTransform FrameOfReference::toUniversal(const RigidTransform& xform,
|
|||
rotation = refObject.body()->getEclipticalToGeographic(t);
|
||||
break;
|
||||
case Selection::Type_Star:
|
||||
rotation = Quatd(1, 0, 0, 0);
|
||||
rotation = refObject.star()->getRotationElements().eclipticalToPlanetographic(t);
|
||||
break;
|
||||
case Selection::Type_Location:
|
||||
if (refObject.location()->getParentBody() != NULL)
|
||||
|
@ -44,22 +44,30 @@ RigidTransform FrameOfReference::toUniversal(const RigidTransform& xform,
|
|||
else if (coordSys == astro::PhaseLock)
|
||||
{
|
||||
Mat3d m;
|
||||
Vec3d lookDir = refObject.getPosition(t) - targetObject.getPosition(t);
|
||||
lookDir.normalize();
|
||||
|
||||
switch (refObject.getType())
|
||||
{
|
||||
case Selection::Type_Body:
|
||||
{
|
||||
Body* body = refObject.body();
|
||||
Vec3d lookDir = refObject.getPosition(t) -
|
||||
targetObject.getPosition(t);
|
||||
Vec3d axisDir = Vec3d(0, 1, 0) * body->getEclipticalToEquatorial(t).toMatrix3();
|
||||
lookDir.normalize();
|
||||
Vec3d v = axisDir ^ lookDir;
|
||||
v.normalize();
|
||||
Vec3d u = lookDir ^ v;
|
||||
m = Mat3d(v, u, lookDir);
|
||||
}
|
||||
break;
|
||||
case Selection::Type_Star:
|
||||
{
|
||||
Star* star = refObject.star();
|
||||
Vec3d axisDir = Vec3d(0, 1, 0) * star->getRotationElements().eclipticalToEquatorial(t).toMatrix3();
|
||||
Vec3d v = axisDir ^ lookDir;
|
||||
v.normalize();
|
||||
Vec3d u = lookDir ^ v;
|
||||
m = Mat3d(v, u, lookDir);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -121,7 +129,7 @@ RigidTransform FrameOfReference::fromUniversal(const RigidTransform& xform,
|
|||
rotation = refObject.body()->getEclipticalToGeographic(t);
|
||||
break;
|
||||
case Selection::Type_Star:
|
||||
rotation = Quatd(1, 0, 0, 0);
|
||||
rotation = refObject.star()->getRotationElements().eclipticalToPlanetographic(t);
|
||||
break;
|
||||
case Selection::Type_Location:
|
||||
if (refObject.location()->getParentBody() != NULL)
|
||||
|
@ -138,16 +146,15 @@ RigidTransform FrameOfReference::fromUniversal(const RigidTransform& xform,
|
|||
else if (coordSys == astro::PhaseLock)
|
||||
{
|
||||
Mat3d m;
|
||||
Vec3d lookDir = refObject.getPosition(t) - targetObject.getPosition(t);
|
||||
lookDir.normalize();
|
||||
|
||||
switch (refObject.getType())
|
||||
{
|
||||
case Selection::Type_Body:
|
||||
{
|
||||
Body* body = refObject.body();
|
||||
Vec3d lookDir = refObject.getPosition(t) -
|
||||
targetObject.getPosition(t);
|
||||
Vec3d axisDir = Vec3d(0, 1, 0) * body->getEclipticalToEquatorial(t).toMatrix3();
|
||||
lookDir.normalize();
|
||||
Vec3d v = axisDir ^ lookDir;
|
||||
v.normalize();
|
||||
Vec3d u = lookDir ^ v;
|
||||
|
@ -155,6 +162,16 @@ RigidTransform FrameOfReference::fromUniversal(const RigidTransform& xform,
|
|||
}
|
||||
break;
|
||||
|
||||
case Selection::Type_Star:
|
||||
{
|
||||
Star* star = refObject.star();
|
||||
Vec3d axisDir = Vec3d(0, 1, 0) * star->getRotationElements().eclipticalToEquatorial(t).toMatrix3();
|
||||
Vec3d v = axisDir ^ lookDir;
|
||||
v.normalize();
|
||||
Vec3d u = lookDir ^ v;
|
||||
m = Mat3d(v, u, lookDir);
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1251,12 +1251,14 @@ void Observer::follow(const Selection& selection)
|
|||
void Observer::geosynchronousFollow(const Selection& selection)
|
||||
{
|
||||
if (selection.body() != NULL ||
|
||||
selection.location() != NULL)
|
||||
selection.location() != NULL ||
|
||||
selection.star() != NULL)
|
||||
{
|
||||
setFrame(FrameOfReference(astro::Geographic, selection));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Observer::phaseLock(const Selection& selection)
|
||||
{
|
||||
if (frame.refObject.body() != NULL)
|
||||
|
@ -1271,6 +1273,13 @@ void Observer::phaseLock(const Selection& selection)
|
|||
setFrame(FrameOfReference(astro::PhaseLock, frame.refObject, selection));
|
||||
}
|
||||
}
|
||||
else if (frame.refObject.star() != NULL)
|
||||
{
|
||||
if (selection != frame.refObject)
|
||||
{
|
||||
setFrame(FrameOfReference(astro::PhaseLock, frame.refObject, selection));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Observer::chase(const Selection& selection)
|
||||
|
@ -1279,6 +1288,10 @@ void Observer::chase(const Selection& selection)
|
|||
{
|
||||
setFrame(FrameOfReference(astro::Chase, selection));
|
||||
}
|
||||
else if (selection.star() != NULL)
|
||||
{
|
||||
setFrame(FrameOfReference(astro::Chase, selection));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -4504,52 +4504,6 @@ renderEclipseShadows_Shaders(Model* model,
|
|||
ri.pixWidth, NULL);
|
||||
|
||||
vproc->disable();
|
||||
|
||||
#if 0
|
||||
float R2 = 0.25f;
|
||||
float umbra = shadow.umbraRadius / shadow.penumbraRadius;
|
||||
umbra = umbra * umbra;
|
||||
if (umbra < 0.0001f)
|
||||
umbra = 0.0001f;
|
||||
else if (umbra > 0.99f)
|
||||
umbra = 0.99f;
|
||||
|
||||
float umbraRadius = R2 * umbra;
|
||||
float penumbraRadius = R2;
|
||||
float shadowBias = 1.0f / (1.0f - penumbraRadius / umbraRadius);
|
||||
float shadowScale = -shadowBias / umbraRadius;
|
||||
|
||||
fproc->parameter(fp::ShadowParams0,
|
||||
shadowScale, shadowBias, 0.0f, 0.0f);
|
||||
fproc->parameter(fp::AmbientColor, ri.ambientColor * ri.color);
|
||||
|
||||
// Compute the transformation to use for generating texture
|
||||
// coordinates from the object vertices.
|
||||
Point3f origin = shadow.origin * planetMat;
|
||||
Vec3f dir = shadow.direction * planetMat;
|
||||
float scale = planetRadius / shadow.penumbraRadius;
|
||||
Vec3f axis = Vec3f(0, 1, 0) ^ dir;
|
||||
float angle = (float) acos(Vec3f(0, 1, 0) * dir);
|
||||
axis.normalize();
|
||||
Mat4f mat = Mat4f::rotation(axis, -angle);
|
||||
Vec3f sAxis = Vec3f(0.5f * scale, 0, 0) * mat;
|
||||
Vec3f tAxis = Vec3f(0, 0, 0.5f * scale) * mat;
|
||||
|
||||
float sPlane[4] = { 0, 0, 0, 0 };
|
||||
float tPlane[4] = { 0, 0, 0, 0 };
|
||||
sPlane[0] = sAxis.x; sPlane[1] = sAxis.y; sPlane[2] = sAxis.z;
|
||||
tPlane[0] = tAxis.x; tPlane[1] = tAxis.y; tPlane[2] = tAxis.z;
|
||||
sPlane[3] = (Point3f(0, 0, 0) - origin) * sAxis / planetRadius + 0.5f;
|
||||
tPlane[3] = (Point3f(0, 0, 0) - origin) * tAxis / planetRadius + 0.5f;
|
||||
|
||||
renderShadowedModelVertexShader(ri, viewFrustum,
|
||||
sPlane, tPlane,
|
||||
dir,
|
||||
context);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
fproc->disable();
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
|
@ -5654,11 +5608,7 @@ void Renderer::renderStar(const Star& star,
|
|||
rp.atmosphere = NULL;
|
||||
|
||||
const RotationElements& re = star.getRotationElements();
|
||||
double ascendingNode = (double) re.ascendingNode +
|
||||
re.precessionRate * (now - astro::J2000);
|
||||
Quatd q =
|
||||
Quatd::xrotation(-re.obliquity) *
|
||||
Quatd::yrotation(-ascendingNode);
|
||||
Quatd q = re.eclipticalToEquatorial(now);
|
||||
|
||||
double rotation = 0.0;
|
||||
// Watch out for the precision limits of floats when computing
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#ifndef _CELENGINE_ROTATION_H_
|
||||
#define _CELENGINE_ROTATION_H_
|
||||
|
||||
#include <celmath/quaternion.h>
|
||||
#include <celengine/astro.h>
|
||||
|
||||
|
||||
|
@ -18,6 +19,10 @@ class RotationElements
|
|||
public:
|
||||
inline RotationElements();
|
||||
|
||||
inline Quatd eclipticalToEquatorial(double t) const;
|
||||
inline Quatd eclipticalToPlanetographic(double t) const;
|
||||
inline Quatd equatorialToPlanetographic(double t) const;
|
||||
|
||||
float period; // sidereal rotation period
|
||||
float offset; // rotation at epoch
|
||||
double epoch;
|
||||
|
@ -48,4 +53,36 @@ inline bool operator==(const RotationElements& re0, const RotationElements& re1)
|
|||
re0.precessionRate == re1.precessionRate);
|
||||
}
|
||||
|
||||
|
||||
Quatd RotationElements::eclipticalToEquatorial(double t) const
|
||||
{
|
||||
double Omega = (double) ascendingNode + precessionRate * (t - astro::J2000);
|
||||
|
||||
return (Quatd::xrotation(-obliquity) * Quatd::yrotation(-Omega));
|
||||
}
|
||||
|
||||
|
||||
Quatd RotationElements::eclipticalToPlanetographic(double t) const
|
||||
{
|
||||
return equatorialToPlanetographic(t) * eclipticalToEquatorial(t);
|
||||
}
|
||||
|
||||
|
||||
Quatd RotationElements::equatorialToPlanetographic(double t) const
|
||||
{
|
||||
double rotations = (t - epoch) / (double) period;
|
||||
double wholeRotations = floor(rotations);
|
||||
double remainder = rotations - wholeRotations;
|
||||
|
||||
// Add an extra half rotation because of the convention in all
|
||||
// planet texture maps where zero deg long. is in the middle of
|
||||
// the texture.
|
||||
remainder += 0.5;
|
||||
|
||||
Quatd q(1);
|
||||
q.yrotate(-remainder * 2 * PI - offset);
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
#endif // _CELENGINE_ROTATION_H_
|
||||
|
|
Loading…
Reference in New Issue