2001-11-27 18:50:04 -07:00
|
|
|
// selection.cpp
|
2018-03-11 07:12:58 -06:00
|
|
|
//
|
2009-08-05 15:13:29 -06:00
|
|
|
// Copyright (C) 2001-2009, the Celestia Development Team
|
|
|
|
// Original version by Chris Laurel <claurel@gmail.com>
|
2001-11-27 18:50:04 -07:00
|
|
|
//
|
|
|
|
// 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.
|
|
|
|
|
2008-05-17 18:18:41 -06:00
|
|
|
#include <cassert>
|
2001-11-27 18:50:04 -07:00
|
|
|
#include "astro.h"
|
|
|
|
#include "selection.h"
|
2008-02-20 19:25:48 -07:00
|
|
|
#include "frametree.h"
|
2018-12-03 09:41:31 -07:00
|
|
|
#include <celengine/star.h>
|
|
|
|
#include <celengine/body.h>
|
|
|
|
#include <celengine/location.h>
|
|
|
|
#include <celengine/deepskyobj.h>
|
2021-10-24 06:40:14 -06:00
|
|
|
#include <fmt/printf.h>
|
2001-11-27 18:50:04 -07:00
|
|
|
|
2009-07-16 17:37:48 -06:00
|
|
|
using namespace Eigen;
|
2002-01-09 15:59:53 -07:00
|
|
|
using namespace std;
|
|
|
|
|
2001-11-27 18:50:04 -07:00
|
|
|
|
2008-02-20 19:25:48 -07:00
|
|
|
// Some velocities are computed by differentiation; units
|
|
|
|
// are Julian days.
|
|
|
|
static const double VELOCITY_DIFF_DELTA = 1.0 / 1440.0;
|
|
|
|
|
|
|
|
|
2001-11-27 18:50:04 -07:00
|
|
|
double Selection::radius() const
|
|
|
|
{
|
2003-06-25 11:40:24 -06:00
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case Type_Star:
|
|
|
|
return star()->getRadius();
|
|
|
|
case Type_Body:
|
|
|
|
return body()->getRadius();
|
|
|
|
case Type_DeepSky:
|
|
|
|
return astro::lightYearsToKilometers(deepsky()->getRadius());
|
|
|
|
case Type_Location:
|
|
|
|
// The size of a location is its diameter, so divide by 2.
|
|
|
|
return location()->getSize() / 2.0f;
|
|
|
|
default:
|
2001-11-27 18:50:04 -07:00
|
|
|
return 0.0;
|
2003-06-25 11:40:24 -06:00
|
|
|
}
|
2001-11-27 18:50:04 -07:00
|
|
|
}
|
2001-12-17 13:42:57 -07:00
|
|
|
|
|
|
|
|
|
|
|
UniversalCoord Selection::getPosition(double t) const
|
|
|
|
{
|
2003-06-25 11:40:24 -06:00
|
|
|
switch (type)
|
2001-12-17 13:42:57 -07:00
|
|
|
{
|
2003-06-25 11:40:24 -06:00
|
|
|
case Type_Body:
|
2008-02-20 19:25:48 -07:00
|
|
|
return body()->getPosition(t);
|
2018-03-11 07:12:58 -06:00
|
|
|
|
2003-06-25 11:40:24 -06:00
|
|
|
case Type_Star:
|
2004-09-27 22:44:26 -06:00
|
|
|
return star()->getPosition(t);
|
2003-06-25 11:40:24 -06:00
|
|
|
|
|
|
|
case Type_DeepSky:
|
|
|
|
{
|
2009-07-16 17:37:48 -06:00
|
|
|
// NOTE: cast to single precision is only present to maintain compatibility with
|
|
|
|
// Celestia 1.6.0.
|
2009-07-24 00:59:54 -06:00
|
|
|
Vector3f p = deepsky()->getPosition().cast<float>();
|
|
|
|
return UniversalCoord::CreateLy(p.cast<double>());
|
2003-06-25 11:40:24 -06:00
|
|
|
}
|
2018-03-11 07:12:58 -06:00
|
|
|
|
2003-06-25 11:40:24 -06:00
|
|
|
case Type_Location:
|
2003-06-29 10:26:08 -06:00
|
|
|
{
|
|
|
|
Body* body = location()->getParentBody();
|
2018-09-22 07:13:49 -06:00
|
|
|
if (body != nullptr)
|
2003-06-29 10:26:08 -06:00
|
|
|
{
|
2009-07-24 17:02:23 -06:00
|
|
|
return body->getPosition(t).offsetKm(location()->getPlanetocentricPosition(t));
|
2003-06-29 10:26:08 -06:00
|
|
|
}
|
2006-11-22 12:07:41 -07:00
|
|
|
else
|
2008-05-17 18:18:41 -06:00
|
|
|
{
|
|
|
|
// Bad location; all locations should have a parent.
|
|
|
|
assert(0);
|
2009-07-16 17:37:48 -06:00
|
|
|
return UniversalCoord::Zero();
|
2008-05-17 18:18:41 -06:00
|
|
|
}
|
2003-06-29 10:26:08 -06:00
|
|
|
}
|
2003-06-25 11:40:24 -06:00
|
|
|
|
|
|
|
default:
|
2009-07-16 17:37:48 -06:00
|
|
|
return UniversalCoord::Zero();
|
2001-12-17 13:42:57 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-01-09 15:59:53 -07:00
|
|
|
|
2009-07-16 17:37:48 -06:00
|
|
|
Vector3d Selection::getVelocity(double t) const
|
2008-02-20 19:25:48 -07:00
|
|
|
{
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case Type_Body:
|
2009-07-16 17:37:48 -06:00
|
|
|
return body()->getVelocity(t);
|
2018-03-11 07:12:58 -06:00
|
|
|
|
2008-02-20 19:25:48 -07:00
|
|
|
case Type_Star:
|
|
|
|
return star()->getVelocity(t);
|
|
|
|
|
|
|
|
case Type_DeepSky:
|
2009-07-16 17:37:48 -06:00
|
|
|
return Vector3d::Zero();
|
2008-02-20 19:25:48 -07:00
|
|
|
|
|
|
|
case Type_Location:
|
2018-03-11 07:12:58 -06:00
|
|
|
{
|
|
|
|
// For now, just use differentiation for location velocities.
|
2009-07-16 17:37:48 -06:00
|
|
|
return getPosition(t).offsetFromKm(getPosition(t - VELOCITY_DIFF_DELTA)) / VELOCITY_DIFF_DELTA;
|
2018-03-11 07:12:58 -06:00
|
|
|
}
|
2008-02-20 19:25:48 -07:00
|
|
|
|
|
|
|
default:
|
2009-07-16 17:37:48 -06:00
|
|
|
return Vector3d::Zero();
|
2008-02-20 19:25:48 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-08-19 16:22:44 -06:00
|
|
|
string Selection::getName(bool i18n) const
|
2002-01-09 15:59:53 -07:00
|
|
|
{
|
2003-06-25 11:40:24 -06:00
|
|
|
switch (type)
|
2002-01-09 15:59:53 -07:00
|
|
|
{
|
2003-06-25 11:40:24 -06:00
|
|
|
case Type_Star:
|
2020-03-06 00:39:25 -07:00
|
|
|
return fmt::sprintf("#%u", star()->getIndex());
|
2003-06-25 11:40:24 -06:00
|
|
|
|
|
|
|
case Type_DeepSky:
|
2020-03-06 00:39:25 -07:00
|
|
|
return fmt::sprintf("#%u", deepsky()->getIndex());
|
2018-03-11 07:12:58 -06:00
|
|
|
|
2003-06-25 11:40:24 -06:00
|
|
|
case Type_Body:
|
2002-01-09 15:59:53 -07:00
|
|
|
{
|
2006-08-19 16:22:44 -06:00
|
|
|
string name = body()->getName(i18n);
|
2003-06-25 11:40:24 -06:00
|
|
|
PlanetarySystem* system = body()->getSystem();
|
2018-09-22 07:13:49 -06:00
|
|
|
while (system != nullptr)
|
2002-01-09 15:59:53 -07:00
|
|
|
{
|
2003-06-25 11:40:24 -06:00
|
|
|
Body* parent = system->getPrimaryBody();
|
2018-09-22 07:13:49 -06:00
|
|
|
if (parent != nullptr)
|
2003-06-25 11:40:24 -06:00
|
|
|
{
|
2006-08-19 16:22:44 -06:00
|
|
|
name = parent->getName(i18n) + '/' + name;
|
2003-06-25 11:40:24 -06:00
|
|
|
system = parent->getSystem();
|
|
|
|
}
|
|
|
|
else
|
2002-01-09 15:59:53 -07:00
|
|
|
{
|
2003-06-25 11:40:24 -06:00
|
|
|
const Star* parentStar = system->getStar();
|
2018-09-22 07:13:49 -06:00
|
|
|
if (parentStar != nullptr)
|
2020-03-06 00:39:25 -07:00
|
|
|
name = fmt::sprintf("#%u/%s", parentStar->getIndex(), name);
|
2018-09-22 07:13:49 -06:00
|
|
|
system = nullptr;
|
2002-01-09 15:59:53 -07:00
|
|
|
}
|
|
|
|
}
|
2003-06-25 11:40:24 -06:00
|
|
|
return name;
|
2002-01-09 15:59:53 -07:00
|
|
|
}
|
2003-06-25 11:40:24 -06:00
|
|
|
|
|
|
|
case Type_Location:
|
2018-09-22 07:13:49 -06:00
|
|
|
if (location()->getParentBody() == nullptr)
|
2003-06-29 10:26:08 -06:00
|
|
|
{
|
2006-08-19 16:22:44 -06:00
|
|
|
return location()->getName(i18n);
|
2003-06-29 10:26:08 -06:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-08-19 16:22:44 -06:00
|
|
|
return Selection(location()->getParentBody()).getName(i18n) + '/' +
|
|
|
|
location()->getName(i18n);
|
2003-06-29 10:26:08 -06:00
|
|
|
}
|
2003-06-25 11:40:24 -06:00
|
|
|
|
|
|
|
default:
|
2002-01-09 15:59:53 -07:00
|
|
|
return "";
|
|
|
|
}
|
|
|
|
}
|
2003-08-07 10:40:47 -06:00
|
|
|
|
|
|
|
|
|
|
|
Selection Selection::parent() const
|
|
|
|
{
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case Type_Location:
|
|
|
|
return Selection(location()->getParentBody());
|
|
|
|
|
|
|
|
case Type_Body:
|
|
|
|
if (body()->getSystem())
|
|
|
|
{
|
2018-09-22 07:13:49 -06:00
|
|
|
if (body()->getSystem()->getPrimaryBody() != nullptr)
|
2003-08-07 10:40:47 -06:00
|
|
|
return Selection(body()->getSystem()->getPrimaryBody());
|
|
|
|
else
|
|
|
|
return Selection(body()->getSystem()->getStar());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return Selection();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Type_Star:
|
2008-02-07 21:13:51 -07:00
|
|
|
return Selection(star()->getOrbitBarycenter());
|
2018-03-11 07:12:58 -06:00
|
|
|
|
2003-08-07 10:40:47 -06:00
|
|
|
case Type_DeepSky:
|
|
|
|
// Currently no hierarchy for stars and deep sky objects.
|
|
|
|
return Selection();
|
|
|
|
|
|
|
|
default:
|
|
|
|
return Selection();
|
|
|
|
}
|
|
|
|
}
|
2008-02-03 17:17:35 -07:00
|
|
|
|
|
|
|
|
|
|
|
/*! Return true if the selection's visibility flag is set. */
|
|
|
|
bool Selection::isVisible() const
|
|
|
|
{
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case Type_Body:
|
|
|
|
return body()->isVisible();
|
|
|
|
case Type_Star:
|
|
|
|
return true;
|
2008-08-06 23:35:29 -06:00
|
|
|
case Type_DeepSky:
|
|
|
|
return deepsky()->isVisible();
|
2008-02-03 17:17:35 -07:00
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|