Code: Select all
Index: render.h
===================================================================
RCS file: /cvsroot/celestia/celestia/src/celengine/render.h,v
retrieving revision 1.64
diff -u -r1.64 render.h
--- render.h 11 Feb 2005 05:09:37 -0000 1.64
+++ render.h 26 May 2005 06:15:20 -0000
@@ -170,6 +170,8 @@
void setFont(TextureFont*);
TextureFont* getFont() const;
+ void renderOrbitColor(const Body *, bool);
+ void transformOrbits(const PlanetarySystem*);
public:
// Internal types
@@ -366,10 +368,18 @@
double jd);
void renderOrbit(Body*, double);
- void renderOrbits(PlanetarySystem*, const Selection&, double,
+ void renderOrbits(const PlanetarySystem*, const Selection&, double,
const Point3d&, const Point3d&);
-
-
+ void renderOrbits(const Observer& observer,
+ const Universe& universe,
+ const Selection& sel,
+ double t);
+ void renderForegroundOrbits(const PlanetarySystem* system,
+ const Point3f ¢er,
+ float distance,
+ int discSizeInPixels,
+ const Selection& sel,
+ double t);
private:
GLContext* context;
--- render.cpp.20050523 2005-05-23 21:00:47.000000000 -0500
+++ render.cpp 2005-05-26 01:09:56.000000000 -0500
@@ -983,8 +983,38 @@
glEnd();
}
+void Renderer::renderOrbitColor(const Body* body, bool selected)
+{
+ if (selected)
+ {
+ // Highlight the orbit of the selected object in red
+ glColor4f(1, 0, 0, 1);
+ }
+ else
+ {
+ switch (body->getClassification())
+ {
+ case Body::Moon:
+ glColor4f(0.0f, 0.2f, 0.5f, 1.0f);
+ break;
+ case Body::Asteroid:
+ glColor4f(0.35f, 0.2f, 0.0f, 1.0f);
+ break;
+ case Body::Comet:
+ glColor4f(0.0f, 0.5f, 0.5f, 1.0f);
+ break;
+ case Body::Spacecraft:
+ glColor4f(0.4f, 0.4f, 0.4f, 1.0f);
+ break;
+ case Body::Planet:
+ default:
+ glColor4f(0.0f, 0.4f, 1.0f, 1.0f);
+ break;
+ }
+ }
+}
-void Renderer::renderOrbits(PlanetarySystem* planets,
+void Renderer::renderOrbits(const PlanetarySystem* planets,
const Selection& sel,
double t,
const Point3d& observerPos,
@@ -1001,75 +1031,52 @@
Body* body = planets->getBody(i);
// Only show orbits for major bodies or selected objects
- if ((body->getClassification() & orbitMask) != 0 || body == sel.body())
- {
- if (body == sel.body())
- {
- // Highlight the orbit of the selected object in red
- glColor4f(1, 0, 0, 1);
- }
- else
- {
- switch (body->getClassification())
- {
- case Body::Moon:
- glColor4f(0.0f, 0.2f, 0.5f, 1.0f);
- break;
- case Body::Asteroid:
- glColor4f(0.35f, 0.2f, 0.0f, 1.0f);
- break;
- case Body::Comet:
- glColor4f(0.0f, 0.5f, 0.5f, 1.0f);
- break;
- case Body::Spacecraft:
- glColor4f(0.4f, 0.4f, 0.4f, 1.0f);
- break;
- case Body::Planet:
- default:
- glColor4f(0.0f, 0.4f, 1.0f, 1.0f);
- break;
- }
- }
-
- float orbitRadiusInPixels =
- (float) (body->getOrbit()->getBoundingRadius() /
- (distance * pixelSize));
- if (orbitRadiusInPixels > minOrbitSize)
- {
- float farDistance =
- (float) (body->getOrbit()->getBoundingRadius() + distance);
- farDistance = astro::kilometersToAU(farDistance);
-
- // Set up the projection matrix so that the far plane is
- // distant enough that the orbit won't be clipped.
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(fov,
- (float) windowWidth / (float) windowHeight,
- max( farDistance * 1e-6f, (float)(1e-5/2./tan(fov*3.14159/360.0)) ),
- farDistance * 1.1f );
- glMatrixMode(GL_MODELVIEW);
- renderOrbit(body, t);
-
- if (body->getSatellites() != NULL)
- {
- Point3d localPos = body->getOrbit()->positionAtTime(t);
- Quatd rotation =
- Quatd::yrotation(body->getRotationElements().ascendingNode) *
- Quatd::xrotation(body->getRotationElements().obliquity);
- double scale = astro::kilometersToAU(1.0);
- glPushMatrix();
- glTranslated(localPos.x * scale,
- localPos.y * scale,
- localPos.z * scale);
- glRotate(rotation);
- renderOrbits(body->getSatellites(), sel, t,
- observerPos,
- body->getHeliocentricPosition(t));
- glPopMatrix();
- }
- }
- }
+ if ((body->getClassification() & orbitMask) == 0 && body != sel.body())
+ continue;
+ renderOrbitColor(body, body == sel.body());
+
+
+ float orbitRadiusInPixels =
+ (float) (body->getOrbit()->getBoundingRadius() /
+ (distance * pixelSize));
+ if (orbitRadiusInPixels <= minOrbitSize)
+ continue;
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+ float farDistance =
+ (float) (body->getOrbit()->getBoundingRadius() + distance);
+ farDistance = astro::kilometersToAU(farDistance);
+
+ // Set up the projection matrix so that the far plane is
+ // distant enough that the orbit won't be clipped.
+ gluPerspective(fov,
+ (float) windowWidth / (float) windowHeight,
+ max( farDistance * 1e-6f,
+ (float)(1e-5/2./tan(fov*3.14159/360.0)) ),
+ farDistance * 1.1f );
+
+ glMatrixMode(GL_MODELVIEW);
+ renderOrbit(body, t);
+
+ if (body->getSatellites() == NULL)
+ continue;
+
+ Point3d localPos = body->getOrbit()->positionAtTime(t);
+ Quatd rotation =
+ Quatd::yrotation(body->getRotationElements().ascendingNode) *
+ Quatd::xrotation(body->getRotationElements().obliquity);
+ double scale = astro::kilometersToAU(1.0);
+ glPushMatrix();
+ glTranslated(localPos.x * scale,
+ localPos.y * scale,
+ localPos.z * scale);
+ glRotate(rotation);
+ renderOrbits(body->getSatellites(), sel, t,
+ observerPos,
+ body->getHeliocentricPosition(t));
+ glPopMatrix();
}
}
@@ -1088,6 +1095,124 @@
astro::microLightYearsToKilometers(v.z));
}
+void Renderer::renderOrbits(const Observer& observer,
+ const Universe& universe,
+ const Selection& sel,
+ double t) {
+ // Render orbit paths
+ if ((renderFlags & ShowOrbits) != 0 && orbitMask != 0)
+ {
+ // Clear the keep flag for all orbits in the cache; if they're not
+ // used when rendering this frame, they'll get marked for
+ // recycling.
+ vector<CachedOrbit*>::const_iterator iter;
+ for (iter = orbitCache.begin(); iter != orbitCache.end(); iter++)
+ (*iter)->keep = false;
+
+ glDisable(GL_LIGHTING);
+ glDisable(GL_TEXTURE_2D);
+ if ((renderFlags & ShowSmoothLines) != 0)
+ enableSmoothLines();
+
+ for (vector<const Star*>::const_iterator starIter = nearStars.begin();
+ starIter != nearStars.end(); starIter++)
+ {
+ const Star* sun = *starIter;
+ SolarSystem* solarSystem = universe.getSolarSystem(sun);
+
+ if (solarSystem != NULL)
+ {
+ Point3d obsPos = astrocentricPosition(observer.getPosition(),
+ *sun, observer.getTime());
+ glPushMatrix();
+ glTranslatef((float) astro::kilometersToAU(-obsPos.x),
+ (float) astro::kilometersToAU(-obsPos.y),
+ (float) astro::kilometersToAU(-obsPos.z));
+ renderOrbits(solarSystem->getPlanets(), sel, t,
+ obsPos, Point3d(0.0, 0.0, 0.0));
+ glPopMatrix();
+ }
+ }
+
+ if ((renderFlags & ShowSmoothLines) != 0)
+ disableSmoothLines();
+
+ // Mark for recycling all unused orbits in the cache
+ for (iter = orbitCache.begin(); iter != orbitCache.end(); iter++)
+ {
+ if (!(*iter)->keep)
+ (*iter)->body = NULL;
+ }
+ }
+}
+
+void Renderer::transformOrbits(const PlanetarySystem *system) {
+ if (system->getPrimaryBody()) {
+ const Body *body = system->getPrimaryBody();
+ transformOrbits(body->getSystem());
+ Quatd rotation =
+ Quatd::yrotation(body->getRotationElements().ascendingNode) *
+ Quatd::xrotation(body->getRotationElements().obliquity);
+ glRotate(rotation);
+ }
+}
+
+void Renderer::renderForegroundOrbits(const PlanetarySystem* system,
+ const Point3f ¢er, // km
+ float distance, // km
+ int discSizeInPixels,
+ const Selection& sel,
+ double t) {
+ // Render orbit paths
+
+ if ((renderFlags & ShowOrbits) == 0 || orbitMask == 0)
+ return;
+ if (system == NULL)
+ return;
+ if (discSizeInPixels < minOrbitSize)
+ return;
+
+ distance = astro::kilometersToAU(distance);
+ double scale = astro::kilometersToAU(1.0);
+ glPushMatrix();
+ glTranslated(center.x * scale,
+ center.y * scale,
+ center.z * scale);
+
+ glDisable(GL_LIGHTING);
+ glDisable(GL_TEXTURE_2D);
+ if ((renderFlags & ShowSmoothLines) != 0)
+ enableSmoothLines();
+ transformOrbits(system);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluPerspective(fov,
+ (float) windowWidth / (float) windowHeight,
+ max( distance * 1e-6f,
+ (float)(1e-5/2./tan(fov*3.14159/360.0)) ),
+ distance);
+
+ glMatrixMode(GL_MODELVIEW);
+
+ int nBodies = system->getSystemSize();
+ for (int i = 0; i < nBodies; i++)
+ {
+ Body* body = system->getBody(i);
+
+ // Only show orbits for major bodies or selected objects
+ if ((body->getClassification() & orbitMask) == 0 &&
+ body != sel.body())
+ continue;
+ renderOrbitColor(body, body == sel.body());
+ renderOrbit(body, t);
+ }
+
+ if ((renderFlags & ShowSmoothLines) != 0)
+ disableSmoothLines();
+ glPopMatrix();
+}
+
void Renderer::autoMag(float& faintestMag)
{
@@ -1399,53 +1524,7 @@
labelConstellations(*universe.getAsterisms(), observer);
glPopMatrix();
-
- // Render orbit paths
- if ((renderFlags & ShowOrbits) != 0 && orbitMask != 0)
- {
- // Clear the keep flag for all orbits in the cache; if they're not
- // used when rendering this frame, they'll get marked for
- // recycling.
- vector<CachedOrbit*>::const_iterator iter;
- for (iter = orbitCache.begin(); iter != orbitCache.end(); iter++)
- (*iter)->keep = false;
-
- glDisable(GL_LIGHTING);
- glDisable(GL_TEXTURE_2D);
- if ((renderFlags & ShowSmoothLines) != 0)
- enableSmoothLines();
-
- for (vector<const Star*>::const_iterator starIter = nearStars.begin();
- starIter != nearStars.end(); starIter++)
- {
- const Star* sun = *starIter;
- SolarSystem* solarSystem = universe.getSolarSystem(sun);
-
- if (solarSystem != NULL)
- {
- Point3d obsPos = astrocentricPosition(observer.getPosition(),
- *sun, observer.getTime());
- glPushMatrix();
- glTranslatef((float) astro::kilometersToAU(-obsPos.x),
- (float) astro::kilometersToAU(-obsPos.y),
- (float) astro::kilometersToAU(-obsPos.z));
- renderOrbits(solarSystem->getPlanets(), sel, now,
- obsPos, Point3d(0.0, 0.0, 0.0));
- glPopMatrix();
- }
- }
-
- if ((renderFlags & ShowSmoothLines) != 0)
- disableSmoothLines();
-
- // Mark for recycling all unused orbits in the cache
- for (iter = orbitCache.begin(); iter != orbitCache.end(); iter++)
- {
- if (!(*iter)->keep)
- (*iter)->body = NULL;
- }
- }
-
+ renderOrbits(observer, universe, sel, now);
renderLabels();
glPolygonMode(GL_FRONT, (GLenum) renderMode);
@@ -1713,6 +1792,14 @@
observer.getOrientation(),
lightSourceLists[renderList[i].solarSysIndex],
nearPlaneDistance, farPlaneDistance);
+
+ renderForegroundOrbits(renderList[i].body->
+ getSatellites(),
+ renderList[i].position,
+ renderList[i].distance,
+ renderList[i].discSizeInPixels,
+ sel,
+ now);
}
}
else if (renderList[i].star != NULL)
@@ -1723,7 +1810,15 @@
renderList[i].appMag,
observer.getOrientation(),
now,
- nearPlaneDistance, farPlaneDistance);
+ nearPlaneDistance, farPlaneDistance);
+ SolarSystem *system =
+ universe.getSolarSystem(renderList[i].star);
+ renderForegroundOrbits(system->getPlanets(),
+ renderList[i].position,
+ renderList[i].distance,
+ renderList[i].discSizeInPixels,
+ sel,
+ now);
}
// If this body is larger than a pixel, we rendered it as a mesh