Select Git revision
test_rad_pressure.py
Forked from
finesse / pykat
Source project has a limited visibility.
-
Daniel Brown authored
adding in more support for nodes. Can now access any node using kat.nodes.n1. Added in functions for Node object to set the gauss parameters. Only added gauss for w0 and z so far.
Daniel Brown authoredadding in more support for nodes. Can now access any node using kat.nodes.n1. Added in functions for Node object to set the gauss parameters. Only added gauss for w0 and z so far.
Starsphere.cpp 25.65 KiB
/***************************************************************************
* Copyright (C) 2004 David Hammer, Eric Myers, Bruce Allen *
* Copyright (C) 2008 Bernd Machenschalk *
* *
* Copyright (C) 2008 by Oliver Bock *
* oliver.bock[AT]aei.mpg.de *
* *
* This file is part of Einstein@Home. *
* *
* Einstein@Home 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, version 2 of the License. *
* *
* Einstein@Home is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with Einstein@Home. If not, see <http://www.gnu.org/licenses/>. *
* *
***************************************************************************/
#include "Starsphere.h"
Starsphere::Starsphere() : AbstractGraphicsEngine()
{
m_FontResource = 0;
m_FontLogo1 = 0;
m_FontLogo2 = 0;
m_FontHeader = 0;
m_FontText = 0;
Axes=0, Stars=0, Constellations=0, Pulsars=0;
LLOmarker=0, LHOmarker=0, GEOmarker=0, VIRGOmarker=0;
sphGrid=0, SNRs=0, SearchMarker=0;
/**
* Parameters and State info
*/
sphRadius = 5.5;
featureFlags = 0;
/**
* Viewpoint (can be changed with mouse)
*/
viewpt_azimuth = 30.0;
viewpt_elev = 23.6;
viewpt_radius = 7.6;
wobble_amp = 37.0;
wobble_period = 17.0;
zoom_amp = 0.00;
zoom_period = 29.0;
rotation_offset = 0.0;
rotation_speed = 180.0;
m_CurrentRightAscension = -1.0;
m_CurrentDeclination = -1.0;
m_RefreshSearchMarker = true;
}
Starsphere::~Starsphere()
{
if(m_FontLogo1) delete m_FontLogo1;
if(m_FontLogo2) delete m_FontLogo2;
if(m_FontHeader) delete m_FontHeader;
if(m_FontText) delete m_FontText;
}
/**
* sphVertex3D() creates a GL vertex in 3D sky sphere coordinates
* sphVertex() creates a GL vertex on the surface of the sky sphere.
* Use either like glVertex().
*/
void Starsphere::sphVertex3D(GLfloat RAdeg, GLfloat DEdeg, GLfloat radius)
{
GLfloat x, y, z;
x = radius * COS(DEdeg) * COS(RAdeg);
z = -radius * COS(DEdeg) * SIN(RAdeg);
y = radius * SIN(DEdeg);
glVertex3f(x, y, z);
return;
}
void Starsphere::sphVertex(GLfloat RAdeg, GLfloat DEdeg)
{
sphVertex3D(RAdeg, DEdeg, sphRadius);
}
/**
* Star Marker:
* Makes a marker for one star at a given position and angular size.
*/
void Starsphere::star_marker(float RAdeg, float DEdeg, float size)
{
glPointSize((GLfloat) size);
glBegin(GL_POINTS);
sphVertex((GLfloat) RAdeg, (GLfloat) DEdeg);
glEnd();
return;
}
/**
* Create Stars: markers for each star
*/
void Starsphere::make_stars()
{
GLfloat mag_size;
int i, j;
bool is_dupe;
int Ndupes=0;
// delete existing, create new (required for windoze)
if(Stars) glDeleteLists(Stars, 1);
Stars = glGenLists(1);
glNewList(Stars, GL_COMPILE);
glColor3f(1.0, 1.0, 1.0);
/**
* At some point in the future star_info[][] will also contain
* star magnitude and the marker size will vary with this.
*/
for (i=0; i < Nstars; i++) {
// same stars appear more than once in constallations so ignore dupes
is_dupe=false;
for (j=0; j< i; j++) {
if (star_info[j][0] == star_info[i][0] && star_info[j][0]
== star_info[i][0]) {
is_dupe=true;
Ndupes++;
break;
}
}
if (!is_dupe) {
// mag_size = 0.05 + 0.50*rand()/RAND_MAX;
mag_size = 4.0;
star_marker(star_info[i][0], star_info[i][1], mag_size);
}
}
glEndList();
}
/**
* Pulsar Markers:
*/
void Starsphere::make_pulsars()
{
GLfloat mag_size=3.0;
int i;
// delete existing, create new (required for windoze)
if(Pulsars) glDeleteLists(Pulsars, 1);
Pulsars = glGenLists(1);
glNewList(Pulsars, GL_COMPILE);
glColor3f(0.80, 0.0, 0.85); // _P_ulsars are _P_urple
for (i=0; i < Npulsars; i++) {
star_marker(pulsar_info[i][0], pulsar_info[i][1], mag_size);
}
glEndList();
}
/**
* Super Novae Remenants (SNRs):
*/
void Starsphere::make_snrs()
{
GLfloat mag_size=3.0;
int i;
// delete existing, create new (required for windoze)
if(SNRs) glDeleteLists(SNRs, 1);
SNRs = glGenLists(1);
glNewList(SNRs, GL_COMPILE);
glColor3f(0.7, 0.176, 0.0); // _S_NRs are _S_ienna
for (i=0; i < NSNRs; i++) {
star_marker(SNR_info[i][0], SNR_info[i][1], mag_size);
}
glEndList();
}
/**
* Create Constellations:
* draws line links between pairs of stars in the list.
*/
void Starsphere::make_constellations()
{
GLint star_num=0;
// delete existing, create new (required for windoze)
if(Constellations) glDeleteLists(Constellations, 1);
Constellations = glGenLists(1);
glNewList(Constellations, GL_COMPILE);
glLineWidth(1.0);
glColor3f(0.7, 0.7, 0.0); // light yellow
glBegin(GL_LINES); // draws lines between *pairs* of vertices
for (star_num=0; star_num < Nstars; ++star_num) {
sphVertex(star_info[star_num][0], star_info[star_num][1]);
star_num++;
sphVertex(star_info[star_num][0], star_info[star_num][1]);
}
glEnd();
glEndList();
}
/**
* Create markers on sky sphere for LLO, LHO, and GEO
* IFO corner positions are from Myers' personal GPS and are +/- 100m
*/
/**
* RAofZenith(time, longitude)
*
* Computes the Right Ascention of the zenith at a given time (from
* the Unix epoch, in seconds) at a given Longitude (in degrees). From
* 'The Cambridge Handbook of Physics Formulas', Graham Woan, 2003
* edition, CUP. (NOT the first edition), p177.
*/
GLfloat Starsphere::RAofZenith(double T, GLfloat LONdeg)
{
// unix epoch at 12h 1/1/2000
const double T_0 = 946728000.0;
// UT seconds of the day
double T_s = fmod(T, 24.0*3600.0);
// Julian centuries since 12h 1/1/2000 and 0h today
double T_c = (T - T_s - T_0)/3155760000.0;
// GMST at 0h today in seconds
double GMST0 = 6.0*3600.0 + 41.0*60.0 + 50.54841 + (8640184.812866
+ 0.093104*T_c)*T_c;
// GMST now in seconds
double GMST = GMST0 + 1.002738*T_s;
// longitude defined as west positive
GLfloat alpha = (GMST/(24.0*3600.0))*360.0 - LONdeg;
return alpha;
}
/**
* Draw the observatories at their zenith positions
*/
void Starsphere::make_obs()
{
GLfloat Lat, Lon; // Latitute/Longitude of IFO is
GLfloat RAdeg, DEdeg; // converted to RA/DEC of sky sphere position
GLfloat radius; // radius of sphere for obs
GLfloat arm_len_deg=3.000; // lenght of arms, in degrees (not to scale)
GLfloat h2=0.400; // slight offset for H2 arms
// get current time and UTC offset (for zenith position)
m_ObservatoryDrawTimeLocal = dtime();
time_t local = m_ObservatoryDrawTimeLocal;
tm *utc = gmtime(&local);
double utcOffset = difftime(local, mktime(utc));
double observatoryDrawTimeGMT = m_ObservatoryDrawTimeLocal - utcOffset;
radius = 1.0*sphRadius; // radius of sphere on which they are drawn
float lineSize = 4.0;
/**
* LIGO Livingston Observatory:
*/
Lat= 30.56377;
Lon= 90.77408;
RAdeg= RAofZenith(observatoryDrawTimeGMT, Lon);
DEdeg= Lat;
// delete existing, create new (required for windoze)
if(LLOmarker) glDeleteLists(LLOmarker, 1);
LLOmarker = glGenLists(1);
glNewList(LLOmarker, GL_COMPILE);
glColor3f(0.0, 1.0, 0.0);
glLineWidth(lineSize);
glBegin(GL_LINE_STRIP);
// North/South arm:
sphVertex3D(RAdeg, DEdeg-arm_len_deg, radius);
sphVertex3D(RAdeg, DEdeg, radius);
// East/West arm:
sphVertex3D(RAdeg-arm_len_deg, DEdeg, radius);
glEnd();
// arm joint H2
glPointSize((GLfloat) lineSize);
glBegin(GL_POINTS);
sphVertex3D(RAdeg, DEdeg, radius);
glEnd();
glEndList();
/**
* LIGO Hanford Observatory: H1 and H2
*/
Lat= 46.45510;
Lon= 119.40627;
RAdeg= RAofZenith(observatoryDrawTimeGMT, Lon);
DEdeg= Lat;
// delete existing, create new (required for windoze)
if(LHOmarker) glDeleteLists(LHOmarker, 1);
LHOmarker = glGenLists(1);
glNewList(LHOmarker, GL_COMPILE);
glColor3f(0.0, 0.0, 1.0);
glLineWidth(lineSize);
glBegin(GL_LINE_STRIP);
// North/South arm:
sphVertex3D(RAdeg, DEdeg+arm_len_deg, radius);
sphVertex3D(RAdeg, DEdeg, radius);
// East/West arm:
sphVertex3D(RAdeg-arm_len_deg, DEdeg, radius);
glEnd();
glBegin(GL_LINE_STRIP);
// North/South arm, H2:
sphVertex3D(RAdeg-h2, DEdeg+arm_len_deg/2.0+h2/2.0, radius);
sphVertex3D(RAdeg-h2, DEdeg+h2/2.0, radius);
// East/West arm, H2;
sphVertex3D(RAdeg-arm_len_deg/2.0-h2, DEdeg+h2/2.0, radius);
glEnd();
// arm joint H1
glPointSize((GLfloat) lineSize);
glBegin(GL_POINTS);
sphVertex3D(RAdeg, DEdeg, radius);
glEnd();
// arm joint H2
glPointSize((GLfloat) lineSize);
glBegin(GL_POINTS);
sphVertex3D(RAdeg-h2, DEdeg+h2/2.0, radius);
glEnd();
glEndList();
/**
* GEO600 Interferometer:
*/
Lat= 52.24452;
Lon= -9.80683;
arm_len_deg=1.50; // not to scale
RAdeg= RAofZenith(observatoryDrawTimeGMT, Lon);
DEdeg= Lat;
// delete existing, create new (required for windoze)
if(GEOmarker) glDeleteLists(GEOmarker, 1);
GEOmarker = glGenLists(1);
glNewList(GEOmarker, GL_COMPILE);
glColor3f(1.0, 0.0, 0.0);
glLineWidth(lineSize);
glBegin(GL_LINE_STRIP);
// North/South arm:
sphVertex3D(RAdeg, DEdeg+arm_len_deg, radius);
sphVertex3D(RAdeg, DEdeg, radius);
// West/East arm:
sphVertex3D(RAdeg+arm_len_deg, DEdeg, radius);
glEnd();
// arm joint
glPointSize((GLfloat) lineSize);
glBegin(GL_POINTS);
sphVertex3D(RAdeg, DEdeg, radius);
glEnd();
glEndList();
/**
* VIRGO Interferometer:
*/
Lat= 43.63139;
Lon= -10.505;
arm_len_deg=3.000; // not to scale
RAdeg= RAofZenith(observatoryDrawTimeGMT, Lon);
DEdeg= Lat;
// delete existing, create new (required for windoze)
if(VIRGOmarker) glDeleteLists(VIRGOmarker, 1);
VIRGOmarker = glGenLists(1);
glNewList(VIRGOmarker, GL_COMPILE);
glColor3f(1.0, 1.0, 1.0);
glLineWidth(lineSize);
glBegin(GL_LINE_STRIP);
// North/South arm:
sphVertex3D(RAdeg, DEdeg+arm_len_deg, radius);
sphVertex3D(RAdeg, DEdeg, radius);
// West/East arm:
sphVertex3D(RAdeg-arm_len_deg, DEdeg, radius);
glEnd();
// arm joint
glPointSize((GLfloat) lineSize);
glBegin(GL_POINTS);
sphVertex3D(RAdeg, DEdeg, radius);
glEnd();
glEndList();
return;
}
void Starsphere::make_search_marker(GLfloat RAdeg, GLfloat DEdeg, GLfloat size)
{
GLfloat x, y;
GLfloat r1, r2, r3;
float theta;
int i, Nstep=20;
// r1 is inner circle, r2 is outer circle, r3 is crosshairs
r1 = size, r2=3*size, r3=4*size;
// delete existing, create new (required for windoze)
if(SearchMarker) glDeleteLists(SearchMarker, 1);
SearchMarker = glGenLists(1);
glNewList(SearchMarker, GL_COMPILE);
// start gunsight drawing
glPushMatrix();
glLineWidth(3.0);
glColor3f(1.0, 0.5, 0.0); // Orange
// First rotate east to the RA position around y
glRotatef(RAdeg, 0.0, 1.0, 0.0);
// Then rotate up to DEC position around z (not x)
glRotatef(DEdeg, 0.0, 0.0, 1.0);
// Inner circle
glBegin(GL_LINE_LOOP);
for (i=0; i<Nstep; i++) {
theta = i*360.0/Nstep;
x = r1*COS(theta);
y = r1*SIN(theta);
sphVertex(x, y);
}
glEnd();
// Outer circle
glBegin(GL_LINE_LOOP);
for (i=0; i<Nstep; i++) {
theta = i*360.0/Nstep;
x = r2*COS(theta);
y = r2*SIN(theta);
sphVertex(x, y);
}
glEnd();
// Arms that form the gunsight
glBegin(GL_LINES);
// North arm:
sphVertex(0.0, +r1);
sphVertex(0.0, +r3);
// South arm:
sphVertex(0.0, -r1);
sphVertex(0.0, -r3);
// East arm:
sphVertex(-r1, 0.0);
sphVertex(-r3, 0.0);
// West arm:
sphVertex(+r1, 0.0);
sphVertex(+r3, 0.0);
glEnd();
glPopMatrix();
// searchlight line out to marker (OFF!)
if(false) {
glBegin(GL_LINES);
sphVertex3D(RAdeg, DEdeg, 0.50*sphRadius);
sphVertex3D(RAdeg, DEdeg, 0.95*sphRadius);
glEnd();
}
glEndList();
}
/**
* XYZ coordinate axes: (if we want them - most useful for testing)
*/
void Starsphere::make_axes()
{
GLfloat axl=10.0;
// delete existing, create new (required for windoze)
if(Axes) glDeleteLists(Axes, 1);
Axes = glGenLists(1);
glNewList(Axes, GL_COMPILE);
glBegin(GL_LINES);
glLineWidth(2.0);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(-axl, 0.0, 0.0);
glVertex3f(axl, 0.0, 0.0);
glColor3f(0.0, 1.0, 0.0);
glVertex3f(0.0, -axl, 0.0);
glVertex3f(0.0, axl, 0.0);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, -axl);
glVertex3f(0.0, 0.0, axl);
glEnd();
glEndList();
}
/**
* RA/DEC coordinate grid on the sphere
*/
void Starsphere::make_globe()
{
int hr, j, i, iMax=100;
GLfloat RAdeg, DEdeg;
// delete existing, create new (required for windoze)
if(sphGrid) glDeleteLists(sphGrid, 1);
sphGrid = glGenLists(1);
glNewList(sphGrid, GL_COMPILE);
glLineWidth(1.0);
// Lines of constant Right Ascencion (East Longitude)
for (hr=0; hr<24; hr++) {
RAdeg=hr*15.0;
glColor3f(0.25, 0.25, 0.25);
// mark median
if(hr==0) glColor3f(0.55, 0.55, 0.55);
glBegin(GL_LINE_STRIP);
for (i=0; i<=iMax; i++) {
DEdeg = i*180.0/iMax - 90.0;
sphVertex(RAdeg, DEdeg);
}
glEnd();
}
// Lines of constant Declination (Lattitude)
for (j=1; j<=12; j++) {
DEdeg = 90.0 - j*15.0;
glBegin(GL_LINE_STRIP);
for (i=0; i<=iMax; i++) {
RAdeg = i*360.0/iMax;
sphVertex(RAdeg, DEdeg);
}
glEnd();
}
glEndList();
}
/**
* Window resize/remap
*/
void Starsphere::resize(const int width, const int height)
{
// store current settings
m_CurrentWidth = width;
m_CurrentHeight = height;
aspect = (float)width / (float)height;
// adjust HUD config
m_YStartPosTop = height - 25;
// make sure the search marker is updated (conditional rendering!)
m_RefreshSearchMarker = true;
// adjust aspect ratio and projection
glViewport(0, 0, (GLsizei) width, (GLsizei) height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(95.0, aspect, 0.50, 25.0);
glMatrixMode(GL_MODELVIEW);
}
/**
* What to do when graphics are "initialized".
*/
void Starsphere::initialize(const int width, const int height, const Resource *font, const bool recycle)
{
// check whether we initialize the first time or have to recycle (required for windoze)
if(!recycle) {
// store the font resource
if(font) m_FontResource = font;
// initialize the BOINC client adapter
m_BoincAdapter.initialize("EinsteinHS");
// inital HUD offset setup
m_XStartPosLeft = 5;
m_YOffsetLarge = 18;
setFeature(STARS, true);
setFeature(CONSTELLATIONS, true);
setFeature(PULSARS, true);
setFeature(OBSERVATORIES, true);
setFeature(SNRS, true);
setFeature(GLOBE, true);
setFeature(SEARCHINFO, true);
setFeature(LOGO, true);
setFeature(MARKER, true);
}
else {
// seems that windoze also "resets" our OpenGL fonts
// let's clean up before reinitializing them
if(m_FontLogo1) delete m_FontLogo1;
if(m_FontLogo2) delete m_FontLogo2;
if(m_FontHeader)delete m_FontHeader;
if(m_FontText) delete m_FontText;
}
// we might be called to recycle even before initialization
if(!m_FontResource) {
// display a warning, this could be unintentionally
cerr << "Warning: font resource still unknown! You might want to recycle at a later stage..." << endl;
}
else {
// create large font instances using font resource (base address + size)
m_FontLogo1 = new OGLFT::TranslucentTexture(
&m_FontResource->data()->at(0),
m_FontResource->data()->size(),
24, 72 );
if ( m_FontLogo1 == 0 || !m_FontLogo1->isValid() ) {
cerr << "Could not construct logo1 font face from in memory resource!" << endl;
return;
}
m_FontLogo1->setForegroundColor(1.0, 1.0, 0.0, 1.0);
// create medium font instances using font resource (base address + size)
m_FontLogo2 = new OGLFT::TranslucentTexture(
&m_FontResource->data()->at(0),
m_FontResource->data()->size(),
13, 78 );
if ( m_FontLogo2 == 0 || !m_FontLogo2->isValid() ) {
cerr << "Could not construct logo2 font face from in memory resource!" << endl;
return;
}
m_FontLogo2->setForegroundColor(0.75, 0.75, 0.75, 1.0);
// create medium font instances using font resource (base address + size)
m_FontHeader = new OGLFT::TranslucentTexture(
&m_FontResource->data()->at(0),
m_FontResource->data()->size(),
13, 78 );
if ( m_FontHeader == 0 || !m_FontHeader->isValid() ) {
cerr << "Could not construct header font face from in memory resource!" << endl;
return;
}
m_FontHeader->setForegroundColor(1.0, 1.0, 0.0, 1.0);
// create small font instances using font resource (base address + size)
m_FontText = new OGLFT::TranslucentTexture(
&m_FontResource->data()->at(0),
m_FontResource->data()->size(),
11, 72 );
if ( m_FontText == 0 || !m_FontText->isValid() ) {
cerr << "Could not construct text font face from in memory resource!" << endl;
return;
}
m_FontText->setForegroundColor(0.75, 0.75, 0.75, 1.0);
}
// setup initial dimensions
resize(width, height);
// more font setup and optimizations
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
#if defined( GL_RASTER_POSITION_UNCLIPPED_IBM )
glEnable( GL_RASTER_POSITION_UNCLIPPED_IBM );
#endif
// drawing setup:
glClearColor(0.0, 0.0, 0.0, 0.0); // background is black
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
// some polishing
glShadeModel(GL_SMOOTH);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_LINE_SMOOTH);
// FSAA will be enabled explicitly when needed!
glDisable(GL_MULTISAMPLE_ARB);
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
glHint(GL_FOG_HINT, GL_DONT_CARE);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// enable depth buffering for 3D graphics
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
// fog aids depth perception
glEnable(GL_FOG);
glFogi(GL_FOG_MODE, GL_EXP2);
glFogf(GL_FOG_DENSITY, 0.085);
// create pre-drawn display lists
make_stars();
make_constellations();
make_pulsars();
make_snrs();
make_axes();
make_globe();
make_obs();
glDisable(GL_CLIP_PLANE0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glFlush();
}
/**
* Rendering routine: this is what does the drawing:
*/
void Starsphere::render(const double timeOfDay)
{
GLfloat xvp, yvp, zvp, vp_theta, vp_phi, vp_rad;
GLfloat Zrot = 0.0, Zobs=0.0;
double revs, t, dt = 0;
static double start_time=-1.0, last_time=-1.0;
// Calculate the real time t since we started (or reset) and the
// time dt since the last render() call. Both may be useful
// for timing animations. Note that time_of_day is dtime().
if (start_time < 0.0)
start_time = timeOfDay;
t = timeOfDay - start_time;
if (last_time < 0.0)
last_time = timeOfDay - 0.01;
dt = timeOfDay - last_time;
last_time = timeOfDay; // remember for next time
// Now determine the rotation angle based on the time since start
// It is negative to get the rotation direction correct (the sun
// rises in the East, so the sky sphere rotates E to W).
Zrot = t*rotation_speed/60.0;
revs = Zrot/360.0;
Zrot = -360.0 * (revs - (int)revs);
// and start drawing...
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// now draw the scene...
glLoadIdentity();
// Vary the viewpoint with both a long period wobble of the elevation
// of the view and a longer period zoom in/out that might even penetrate
// The starsphere for a brief time. Increase the power in pow(,) to
// make the visit inside briefer.
vp_theta = 90.0 - viewpt_elev + wobble_amp*sin(PI2*t/(wobble_period*60.0));
vp_phi = viewpt_azimuth;
vp_rad = viewpt_radius - zoom_amp*sin(PI2*t/(zoom_period*60.0));
if(vp_rad <0.0) vp_rad = 0.0; // cannot pass origin (confusing)
// TRIED THIS TOO: -zoom_amp*pow(fabs(sin(PI2*t/(zoom_period*60.0))),3);
xvp = vp_rad * SIN(vp_theta) * SIN(vp_phi);
zvp = vp_rad * SIN(vp_theta) * COS(vp_phi);
yvp = vp_rad * COS(vp_theta);
gluLookAt(xvp, yvp, zvp, // eyes position
0.0, 0.0, 0.0, // looking toward here
0.0, 1.0, 0.0); // which way is up? y axis!
// draw axes before any rotation so they stay put
if (isFeature(AXES)) glCallList(Axes);
// draw the sky sphere, with rotation:
glPushMatrix();
glRotatef(Zrot - rotation_offset, 0.0, 1.0, 0.0);
// stars, pulsars, supernovae, grid
if (isFeature(STARS)) glCallList(Stars);
if (isFeature(PULSARS)) glCallList(Pulsars);
if (isFeature(SNRS)) glCallList(SNRs);
if (isFeature(CONSTELLATIONS)) glCallList(Constellations);
if (isFeature(GLOBE)) glCallList(sphGrid);
// observatories move an extra 15 degrees/hr since they were drawn
if (isFeature(OBSERVATORIES)) {
glPushMatrix();
Zobs = (timeOfDay - m_ObservatoryDrawTimeLocal) * 15.0/3600.0;
glRotatef(Zobs, 0.0, 1.0, 0.0);
glCallList(LLOmarker);
glCallList(LHOmarker);
glCallList(GEOmarker);
glCallList(VIRGOmarker);
glPopMatrix();
}
// draw the search marker (gunsight)
if (isFeature(MARKER)) {
if(m_RefreshSearchMarker) {
make_search_marker(m_CurrentRightAscension, m_CurrentDeclination, 0.5);
m_RefreshSearchMarker = false;
}
else {
glCallList(SearchMarker);
}
}
glPopMatrix();
// draw 2D vectorized HUD
if(isFeature(LOGO) || isFeature(SEARCHINFO)) {
// disable depth testing since we're in 2D mode
glDisable(GL_DEPTH_TEST);
// enable textured fonts
glEnable(GL_TEXTURE_2D);
// save current state
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, m_CurrentWidth, 0, m_CurrentHeight, -1, 1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
if (isFeature(LOGO)) {
m_FontLogo1->draw(m_XStartPosLeft, m_YStartPosTop, "Einstein@Home");
m_FontLogo2->draw(m_XStartPosLeft, m_YStartPosTop - m_YOffsetLarge, "World Year of Physics 2005");
}
if (isFeature(SEARCHINFO)) renderSearchInformation();
// restore original state
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
// disable font textures
glDisable(GL_TEXTURE_2D);
// enable depth testing since we're leaving 2D mode
glEnable(GL_DEPTH_TEST);
}
glFlush();
SDL_GL_SwapBuffers();
}
void Starsphere::mouseButtonEvent(const int positionX, const int positionY,
const AbstractGraphicsEngine::MouseButton buttonPressed)
{
}
void Starsphere::mouseMoveEvent(const int deltaX, const int deltaY,
const AbstractGraphicsEngine::MouseButton buttonPressed)
{
switch(buttonPressed) {
case MouseButtonLeft:
rotateSphere(deltaX, deltaY);
break;
case MouseButtonRight:
zoomSphere(deltaY);
break;
default:
break;
}
}
void Starsphere::keyboardPressEvent(const AbstractGraphicsEngine::KeyBoardKey keyPressed)
{
switch(keyPressed) {
case KeyS:
setFeature(STARS, isFeature(STARS) ? false : true);
break;
case KeyC:
setFeature(CONSTELLATIONS, isFeature(CONSTELLATIONS) ? false : true);
break;
case KeyO:
setFeature(OBSERVATORIES, isFeature(OBSERVATORIES) ? false : true);
break;
case KeyX:
setFeature(XRAYS, isFeature(XRAYS) ? false : true);
break;
case KeyP:
setFeature(PULSARS, isFeature(PULSARS) ? false : true);
break;
case KeyR:
setFeature(SNRS, isFeature(SNRS) ? false : true);
break;
case KeyG:
setFeature(GLOBE, isFeature(GLOBE) ? false : true);
break;
case KeyA:
setFeature(AXES, isFeature(AXES) ? false : true);
break;
case KeyI:
setFeature(SEARCHINFO, isFeature(SEARCHINFO) ? false : true);
break;
case KeyL:
setFeature(LOGO, isFeature(LOGO) ? false : true);
break;
case KeyM:
setFeature(MARKER, isFeature(MARKER) ? false : true);
break;
default:
break;
}
}
/**
* View control
*/
void Starsphere::rotateSphere(const int relativeRotation,
const int relativeElevation)
{
// elevation
viewpt_elev += relativeElevation/10.0;
if (viewpt_elev > 89.0)
viewpt_elev = +89.0;
if (viewpt_elev < -89.0)
viewpt_elev = -89.0;
// rotation
rotation_offset -= relativeRotation/10.0;
}
void Starsphere::zoomSphere(const int relativeZoom)
{
// zoom
viewpt_radius -= relativeZoom/10.0;
if (viewpt_radius > 15.0)
viewpt_radius = 15.0;
if (viewpt_radius < 0.5)
viewpt_radius = 0.5;
}
/**
* Feature control
*/
void Starsphere::setFeature(const Features feature, const bool enable)
{
featureFlags = enable ? (featureFlags | feature) : (featureFlags & ~feature);
}
bool Starsphere::isFeature(const Features feature)
{
return ((featureFlags & feature) == feature ? true : false);
}
void Starsphere::refreshLocalBOINCInformation()
{
// call base class implementation
AbstractGraphicsEngine::refreshLocalBOINCInformation();
// prepare conversion buffer
stringstream buffer;
buffer.precision(2);
buffer.setf(ios::fixed, ios::floatfield);
buffer.fill('0');
buffer.setf(ios::right, ios::adjustfield);
// store content required for our HUD (user info)
m_UserName = "User: " + m_BoincAdapter.userName();
m_TeamName = "Team: " + m_BoincAdapter.teamName();
buffer << "Project Credit: " << fixed << m_BoincAdapter.userCredit() << ends;
m_UserCredit = buffer.str();
buffer.str("");
buffer << "Project RAC: " << fixed << m_BoincAdapter.userRACredit() << ends;
m_UserRACredit = buffer.str();
buffer.str("");
}