diff --git a/src/pulsaranimationwidget.cpp b/src/pulsaranimationwidget.cpp index c9c8aa935d2969ce30aadcd70d9e825473393a6c..afdffe3bd6e81a70f3e999462b54145645896652 100644 --- a/src/pulsaranimationwidget.cpp +++ b/src/pulsaranimationwidget.cpp @@ -24,54 +24,54 @@ const double PulsarAnimationWidget::deg2rad = PI/180.0; PulsarAnimationWidget::PulsarAnimationWidget(QWidget *parent) : - QGLWidget(QGLFormat(QGL::AlphaChannel | QGL::SampleBuffers), parent), - m_frameTimer(), - m_pulseProfile(360, 0.0) + QGLWidget(QGLFormat(QGL::AlphaChannel | QGL::SampleBuffers), parent), + m_frameTimer(), + m_pulseProfile(360, 0.0) { - QString msgThis = tr("3D animation"); - if(!format().directRendering()) { - QString msg = tr("Sorry, no direct rendering support for %1..."); - qWarning() << msg.arg(msgThis); - } - if(!format().doubleBuffer()) { - QString msg = tr("Sorry, no double buffering support for %1..."); - qWarning() << msg.arg(msgThis); - } - if(!format().rgba()) { - QString msg = tr("Sorry, no RGBA support for %1..."); - qWarning() << msg.arg(msgThis); - } - if(!format().alpha()) { - QString msg = tr("Sorry, no alpha channel support for %1..."); - qWarning() << msg.arg(msgThis); - } - if(!format().sampleBuffers()) { - QString msg = tr("Sorry, no multisampling support for %1..."); - qWarning() << msg.arg(msgThis); - } - - // connect primary rendering timer to local callback + QString msgThis = tr("3D animation"); + if(!format().directRendering()) { + QString msg = tr("Sorry, no direct rendering support for %1..."); + qWarning() << msg.arg(msgThis); + } + if(!format().doubleBuffer()) { + QString msg = tr("Sorry, no double buffering support for %1..."); + qWarning() << msg.arg(msgThis); + } + if(!format().rgba()) { + QString msg = tr("Sorry, no RGBA support for %1..."); + qWarning() << msg.arg(msgThis); + } + if(!format().alpha()) { + QString msg = tr("Sorry, no alpha channel support for %1..."); + qWarning() << msg.arg(msgThis); + } + if(!format().sampleBuffers()) { + QString msg = tr("Sorry, no multisampling support for %1..."); + qWarning() << msg.arg(msgThis); + } + + // connect primary rendering timer to local callback connect(&m_frameTimer, SIGNAL(timeout()), this, SLOT(updateFrame())); // initialize quadric pointers m_quadricPulsar = NULL; - m_quadricPulsarSpinAxis = NULL; + m_quadricPulsarSpinAxis = NULL; m_quadricPulsarSpinAxisTop1 = NULL; m_quadricPulsarSpinAxisTop2 = NULL; - m_quadricPulsarMagneticAxis = NULL; + m_quadricPulsarMagneticAxis = NULL; m_quadricPulsarConeRim1 = NULL; m_quadricPulsarConeRim2 = NULL; - // initialize texture pointers - m_pulsarTexture = 0; - m_backgroundTexture = 0; + // initialize texture pointers + m_pulsarTexture = 0; + m_backgroundTexture = 0; - // initial render timing settings - m_framesPerSecond = 25; - m_pulsarRotationDelta = 0.0; - m_pulsarRotationAngle = 0.0; + // initial render timing settings + m_framesPerSecond = 25; + m_pulsarRotationDelta = 0.0; + m_pulsarRotationAngle = 0.0; - m_pulsarSpinAxisInclination = 0.0; + m_pulsarSpinAxisInclination = 0.0; m_pulsarMagneticAxisInclination = 5.0; m_pulsarBeamLength = 3.0f; m_pulsarBeamRimSize = 0.1f; @@ -79,76 +79,76 @@ PulsarAnimationWidget::PulsarAnimationWidget(QWidget *parent) : // initial spin frequency of 0.5 Hz - m_pulsarRotationDelta = (360.0 * 0.5) / m_framesPerSecond; + m_pulsarRotationDelta = (360.0 * 0.5) / m_framesPerSecond; - // initial view features - m_showRotationAxes = false; - m_cameraInteraction = false; + // initial view features + m_showRotationAxes = false; + m_cameraInteraction = false; - // initial view settings + // initial view settings m_mouseAngleH = 0.0; m_mouseAngleV = 0.0; m_cameraZoom = 30.0; - m_cameraZoomLBound = 10.0; - m_cameraZoomUBound = 4500.0; - m_mouseLastX = 0; - m_mouseLastY = 0; + m_cameraZoomLBound = 10.0; + m_cameraZoomUBound = 4500.0; + m_mouseLastX = 0; + m_mouseLastY = 0; - // update camera based on settings above - updateCameraPosition(m_mouseAngleH, m_mouseAngleV, m_cameraZoom); + // update camera based on settings above + updateCameraPosition(m_mouseAngleH, m_mouseAngleV, m_cameraZoom); } PulsarAnimationWidget::~PulsarAnimationWidget() { - if(m_quadricPulsar) gluDeleteQuadric(m_quadricPulsar); - if(m_quadricPulsarConeRim1) gluDeleteQuadric(m_quadricPulsarConeRim1); - if(m_quadricPulsarConeRim2) gluDeleteQuadric(m_quadricPulsarConeRim2); - if(m_quadricPulsarSpinAxis) gluDeleteQuadric(m_quadricPulsarSpinAxis); - if(m_quadricPulsarSpinAxisTop1) gluDeleteQuadric(m_quadricPulsarSpinAxisTop1); - if(m_quadricPulsarSpinAxisTop2) gluDeleteQuadric(m_quadricPulsarSpinAxisTop2); - if(m_quadricPulsarMagneticAxis) gluDeleteQuadric(m_quadricPulsarMagneticAxis); - if(m_pulsarTexture) deleteTexture(m_pulsarTexture); - if(m_backgroundTexture) deleteTexture(m_backgroundTexture); + if(m_quadricPulsar) gluDeleteQuadric(m_quadricPulsar); + if(m_quadricPulsarConeRim1) gluDeleteQuadric(m_quadricPulsarConeRim1); + if(m_quadricPulsarConeRim2) gluDeleteQuadric(m_quadricPulsarConeRim2); + if(m_quadricPulsarSpinAxis) gluDeleteQuadric(m_quadricPulsarSpinAxis); + if(m_quadricPulsarSpinAxisTop1) gluDeleteQuadric(m_quadricPulsarSpinAxisTop1); + if(m_quadricPulsarSpinAxisTop2) gluDeleteQuadric(m_quadricPulsarSpinAxisTop2); + if(m_quadricPulsarMagneticAxis) gluDeleteQuadric(m_quadricPulsarMagneticAxis); + if(m_pulsarTexture) deleteTexture(m_pulsarTexture); + if(m_backgroundTexture) deleteTexture(m_backgroundTexture); } void PulsarAnimationWidget::initializeGL() { - glClearColor(0.0, 0.0, 0.0, 0.0); - glClearDepth(1.0); - glDepthFunc(GL_LEQUAL); - glEnable(GL_DEPTH_TEST); - - glShadeModel(GL_SMOOTH); - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); - - GLfloat LightAmbient[] = {0.3, 0.3, 0.3, 1.0}; - GLfloat LightDiffuse[] = {1.0, 1.0, 1.0, 1.0}; - GLfloat LightSpecular[] = {1.0, 1.0, 1.0, 1.0}; - GLfloat LightPosition[] = {0.0, 0.0, 0.0, 1.0}; - GLfloat spot_direction[] = {0.0, 0.0, 0.0}; - - glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient); - glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse); - glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpecular); - glLightfv(GL_LIGHT0, GL_POSITION, LightPosition); - glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 50.0); - glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spot_direction); - glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 10.0); - - glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); - glEnable(GL_LIGHT0); -// glEnable(GL_LIGHTING); - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - - m_quadricPulsar = gluNewQuadric(); - m_quadricPulsarConeRim1 = gluNewQuadric(); - m_quadricPulsarConeRim2 = gluNewQuadric(); - m_quadricPulsarSpinAxis = gluNewQuadric(); - m_quadricPulsarSpinAxisTop1 = gluNewQuadric(); - m_quadricPulsarSpinAxisTop2 = gluNewQuadric(); - m_quadricPulsarMagneticAxis = gluNewQuadric(); + glClearColor(0.0, 0.0, 0.0, 0.0); + glClearDepth(1.0); + glDepthFunc(GL_LEQUAL); + glEnable(GL_DEPTH_TEST); + + glShadeModel(GL_SMOOTH); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + + GLfloat LightAmbient[] = {0.3, 0.3, 0.3, 1.0}; + GLfloat LightDiffuse[] = {1.0, 1.0, 1.0, 1.0}; + GLfloat LightSpecular[] = {1.0, 1.0, 1.0, 1.0}; + GLfloat LightPosition[] = {0.0, 0.0, 0.0, 1.0}; + GLfloat spot_direction[] = {0.0, 0.0, 0.0}; + + glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient); + glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse); + glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpecular); + glLightfv(GL_LIGHT0, GL_POSITION, LightPosition); + glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 50.0); + glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spot_direction); + glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 10.0); + + glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); + glEnable(GL_LIGHT0); + // glEnable(GL_LIGHTING); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + m_quadricPulsar = gluNewQuadric(); + m_quadricPulsarConeRim1 = gluNewQuadric(); + m_quadricPulsarConeRim2 = gluNewQuadric(); + m_quadricPulsarSpinAxis = gluNewQuadric(); + m_quadricPulsarSpinAxisTop1 = gluNewQuadric(); + m_quadricPulsarSpinAxisTop2 = gluNewQuadric(); + m_quadricPulsarMagneticAxis = gluNewQuadric(); gluQuadricNormals(m_quadricPulsar, GLU_SMOOTH); gluQuadricNormals(m_quadricPulsarConeRim1, GLU_SMOOTH); @@ -171,37 +171,37 @@ void PulsarAnimationWidget::initializeGL() // prepare and check pulsar texture QImage pulsarTexture(":/textures/resources/texture_pulsar.png"); if(pulsarTexture.width() != pulsarTexture.height()) { - qWarning() << msgShape.arg(tr("Pulsar")); + qWarning() << msgShape.arg(tr("Pulsar")); } else { - double integer = 0.0; - double fraction = 0.0; - fraction = modf(log(pulsarTexture.width()) / log(2.0), &integer); - if(fraction > 0.0) { - qWarning() << msgPower.arg(tr("Pulsar")); - } + double integer = 0.0; + double fraction = 0.0; + fraction = modf(log(pulsarTexture.width()) / log(2.0), &integer); + if(fraction > 0.0) { + qWarning() << msgPower.arg(tr("Pulsar")); + } } if(pulsarTexture.width() > maxTextureSize) { - qWarning() << msgSize.arg(tr("pulsar").arg(maxTextureSize).arg(maxTextureSize)); - pulsarTexture = pulsarTexture.scaled(maxTextureSize, maxTextureSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + qWarning() << msgSize.arg(tr("pulsar").arg(maxTextureSize).arg(maxTextureSize)); + pulsarTexture = pulsarTexture.scaled(maxTextureSize, maxTextureSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); } // prepare and check background texture QImage backgroundTexture(":/textures/resources/texture_background_carina.png"); if(backgroundTexture.width() != backgroundTexture.height()) { - qWarning() << msgShape.arg(tr("Background")); + qWarning() << msgShape.arg(tr("Background")); } else { - double integer = 0.0; - double fraction = 0.0; - fraction = modf(log(backgroundTexture.width()) / log(2.0), &integer); - if(fraction > 0.0) { - qWarning() << msgPower.arg(tr("Background")); - } + double integer = 0.0; + double fraction = 0.0; + fraction = modf(log(backgroundTexture.width()) / log(2.0), &integer); + if(fraction > 0.0) { + qWarning() << msgPower.arg(tr("Background")); + } } if(backgroundTexture.width() > maxTextureSize) { - qWarning() << msgSize.arg(tr("background").arg(maxTextureSize).arg(maxTextureSize)); - backgroundTexture = backgroundTexture.scaled(maxTextureSize, maxTextureSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + qWarning() << msgSize.arg(tr("background").arg(maxTextureSize).arg(maxTextureSize)); + backgroundTexture = backgroundTexture.scaled(maxTextureSize, maxTextureSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); } // bind textures @@ -219,370 +219,396 @@ void PulsarAnimationWidget::initializeGL() void PulsarAnimationWidget::resizeGL(int w, int h) { - glViewport(0, 0, w, h); + glViewport(0, 0, w, h); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); - gluPerspective(4.5, (GLfloat)w / (GLfloat)h, 0.1, 5000.0); + gluPerspective(4.5, (GLfloat)w / (GLfloat)h, 0.1, 5000.0); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); } void PulsarAnimationWidget::paintGL() { - GLfloat x,y,angle; + GLfloat x,y,angle; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + gluLookAt(m_cameraPosX, m_cameraPosY, m_cameraPosZ, + 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0); + + // TODO: should be located elsewhere + static GLfloat no_mat[] = {0.0, 0.0, 0.0, 1.0}; + static GLfloat mat_diffuse[] = {0.5, 0.5, 0.5, 1.0}; + static GLfloat mat_specular[] = {1.0, 1.0, 1.0, 1.0}; + static GLfloat low_shininess[] = {2.5}; + static GLfloat translucent[] = {1.0, 1.0, 1.0, 0.33}; + + glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat); + glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); + glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); + glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess); + glMaterialfv(GL_FRONT, GL_EMISSION, no_mat); + + // let's draw everything as wireframe model + glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + + // draw scence + glPushMatrix(); + { + // draw pulsar + glPushMatrix(); + { + glRotatef(-m_pulsarSpinAxisInclination, 1.0, 0.0, 0.0); + glRotatef(m_pulsarRotationAngle, 0.0, 0.0, 1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + // draw spin axis + if(m_showRotationAxes) { + glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); + glColor3f(1.0f, 1.0f, 1.0f); + glPushMatrix(); + { + glTranslatef(0.0, 0.0, -5.0); + gluCylinder(m_quadricPulsarSpinAxis, 0.025, 0.025, 10.0, 32, 1); + } + glPopMatrix(); + glPushMatrix(); + { + glTranslatef(0.0, 0.0, -5.0); + gluDisk(m_quadricPulsarSpinAxisTop1, 0, 0.025, 32, 8); + } + glPopMatrix(); + glPushMatrix(); + { + glTranslatef(0.0, 0.0, 5.0); + gluDisk(m_quadricPulsarSpinAxisTop2, 0, 0.025, 32, 8); + } + glPopMatrix(); + glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + } - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + // gives pulsar spherical appearance + glEnable(GL_LIGHTING); - gluLookAt(m_cameraPosX, m_cameraPosY, m_cameraPosZ, - 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0); + glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat); + glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); + gluSphere(m_quadricPulsar, 1.0, 32, 32); - // TODO: should be located elsewhere - static GLfloat no_mat[] = {0.0, 0.0, 0.0, 1.0}; - static GLfloat mat_diffuse[] = {0.5, 0.5, 0.5, 1.0}; - static GLfloat mat_specular[] = {1.0, 1.0, 1.0, 1.0}; - static GLfloat low_shininess[] = {2.5}; - static GLfloat translucent[] = {1.0, 1.0, 1.0, 0.33}; + glDisable(GL_LIGHTING); + } + glPopMatrix(); - glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat); - glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); - glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); - glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess); - glMaterialfv(GL_FRONT, GL_EMISSION, no_mat); + // TODO: should be located elsewhere + static GLfloat coneAmbient[] = {1.0, 1.0, 0.0, 1.0}; + static GLfloat coneDiffuse[] = {1.0, 1.0, 0.0, 1.0}; + static GLfloat coneSpecular[] = {1.0, 1.0, 0.5, 1.0}; - // let's draw everything as wireframe model - glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + glMaterialfv(GL_FRONT, GL_SPECULAR, coneSpecular); - // draw pulsar - glPushMatrix(); - glPushMatrix(); - glRotatef(-m_pulsarSpinAxisInclination, 1.0, 0.0, 0.0); - glRotatef(m_pulsarRotationAngle, 0.0, 0.0, 1.0); - - // draw spin axis - if(m_showRotationAxes) { - glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - glColor3f(1.0f, 1.0f, 1.0f); - glPushMatrix(); - glTranslatef(0.0, 0.0, -5.0); - gluCylinder(m_quadricPulsarSpinAxis, 0.025, 0.025, 10.0, 32, 1); - glPopMatrix(); - glPushMatrix(); - glTranslatef(0.0, 0.0, -5.0); - gluDisk(m_quadricPulsarSpinAxisTop1, 0, 0.025, 32, 8); - glPopMatrix(); - glPushMatrix(); - glTranslatef(0.0, 0.0, 5.0); - gluDisk(m_quadricPulsarSpinAxisTop2, 0, 0.025, 32, 8); - glPopMatrix(); - glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - } - - // gives pulsar spherical appearance - glEnable(GL_LIGHTING); - - glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat); - glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); - gluSphere(m_quadricPulsar, 1.0, 32, 32); - - glDisable(GL_LIGHTING); - glPopMatrix(); - - // TODO: should be located elsewhere - static GLfloat coneAmbient[] = {1.0, 1.0, 0.0, 1.0}; - static GLfloat coneDiffuse[] = {1.0, 1.0, 0.0, 1.0}; - static GLfloat coneSpecular[] = {1.0, 1.0, 0.5, 1.0}; - - glMaterialfv(GL_FRONT, GL_SPECULAR, coneSpecular); - - // first cone - glPushMatrix(); - glRotatef(-m_pulsarSpinAxisInclination, 1.0, 0.0, 0.0); - - glRotatef(m_pulsarRotationAngle - 90.0, 0.0, 0.0, 1.0); - glRotatef(-m_pulsarMagneticAxisInclination, 0.0, 1.0, 0.0); - - // draw magnetic axis (for both cones) - if(m_showRotationAxes) { - glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - glColor3f(1.0f, 1.0f, 0.0f); - glPushMatrix(); - glTranslatef(0.0, 0.0, -5.0); - gluCylinder(m_quadricPulsarMagneticAxis, 0.025, 0.025, 10.0, 32, 1); - glPopMatrix(); - glPushMatrix(); - glTranslatef(0.0, 0.0, -5.0); - gluDisk(m_quadricPulsarSpinAxisTop1, 0, 0.025, 32, 8); - glPopMatrix(); - glPushMatrix(); - glTranslatef(0.0, 0.0, 5.0); - gluDisk(m_quadricPulsarSpinAxisTop2, 0, 0.025, 32, 8); - glPopMatrix(); - glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - } - - glTranslatef(0.0, 0.0, -4.0); - - glMaterialfv(GL_FRONT, GL_AMBIENT, coneAmbient); - glMaterialfv(GL_FRONT, GL_DIFFUSE, coneDiffuse); - - // draw first cone's outer layer - glBegin(GL_TRIANGLE_FAN); - - // Pinnacle of cone is shared vertex for fan, moved up z-axis - // to produce a cone instead of a circle - glColor3f(1.0f, 1.0f, 0.0f); - glVertex3f(0.0f, 0.0f, m_pulsarBeamLength); - - // Loop around in a circle and specify even points along the circle - // as the vertices of the triangle fan (32 sections) - for(angle = 0.0f; angle < (2.0f*GL_PI); angle += (GL_PI/32.0f)) - { - // Calculate x and y position of the next vertex - x = m_pulsarBeamOuterRadius * sin(angle); - y = m_pulsarBeamOuterRadius * cos(angle); - - // Specify the next vertex for the triangle fan - glVertex2f(x, y); - } - - glEnd(); - - // draw first cone's inner layer (do we need/want this?) - glBegin(GL_TRIANGLE_FAN); - glColor3f(0.66f, 0.66f, 0.0f); - glVertex3f(0.0f, 0.0f, m_pulsarBeamLength); - for(angle = 0.0f; angle < (2.0f*GL_PI); angle += (GL_PI/32.0f)) { - x = m_pulsarBeamInnerRadius * sin(angle); - y = m_pulsarBeamInnerRadius * cos(angle); - glVertex2f(x, y); - } - glEnd(); - - // draw first cone's "rim" (disk topping gap between both cones) - glColor3f(1.0f, 1.0f, 0.5f); - gluDisk(m_quadricPulsarConeRim1, m_pulsarBeamInnerRadius, m_pulsarBeamOuterRadius, 32, 8); - - glPopMatrix(); - - // second cone - glPushMatrix(); - glRotatef(180.0, 1.0, 0.0, 0.0); + // first cone + glPushMatrix(); + { glRotatef(-m_pulsarSpinAxisInclination, 1.0, 0.0, 0.0); - glRotatef(-m_pulsarRotationAngle - 90.0, 0.0, 0.0, 1.0); + glRotatef(m_pulsarRotationAngle - 90.0, 0.0, 0.0, 1.0); glRotatef(-m_pulsarMagneticAxisInclination, 0.0, 1.0, 0.0); - glTranslatef(0.0, 0.0, -4.0); - - glMaterialfv(GL_FRONT, GL_AMBIENT, coneAmbient); - glMaterialfv(GL_FRONT, GL_DIFFUSE, coneDiffuse); - - // draw first cone's outer layer - glBegin(GL_TRIANGLE_FAN); - - // Pinnacle of cone is shared vertex for fan, moved up z-axis - // to produce a cone instead of a circle - glColor3f(1.0f, 1.0f, 0.0f); - glVertex3f(0.0f, 0.0f, 3.0f); - - // Loop around in a circle and specify even points along the circle - // as the vertices of the triangle fan (32 sections) - for(angle = 0.0f; angle < (2.0f*GL_PI); angle += (GL_PI/32.0f)) - { - // Calculate x and y position of the next vertex - x = m_pulsarBeamOuterRadius * sin(angle); - y = m_pulsarBeamOuterRadius * cos(angle); - - // Specify the next vertex for the triangle fan - glVertex2f(x, y); - } - - glEnd(); - - // draw first cone's inner layer (do we need/want this?) - glBegin(GL_TRIANGLE_FAN); - glColor3f(0.66f, 0.66f, 0.0f); - glVertex3f(0.0f, 0.0f, 3.0f); - for(angle = 0.0f; angle < (2.0f*GL_PI); angle += (GL_PI/32.0f)) { - x = m_pulsarBeamInnerRadius * sin(angle); - y = m_pulsarBeamInnerRadius * cos(angle); - glVertex2f(x, y); - } - glEnd(); + // draw magnetic axis (for both cones) + if(m_showRotationAxes) { + glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); + glColor3f(1.0f, 1.0f, 0.0f); + glPushMatrix(); + { + glTranslatef(0.0, 0.0, -5.0); + gluCylinder(m_quadricPulsarMagneticAxis, 0.025, 0.025, 10.0, 32, 1); + } + glPopMatrix(); + glPushMatrix(); + { + glTranslatef(0.0, 0.0, -5.0); + gluDisk(m_quadricPulsarSpinAxisTop1, 0, 0.025, 32, 8); + } + glPopMatrix(); + glPushMatrix(); + { + glTranslatef(0.0, 0.0, 5.0); + gluDisk(m_quadricPulsarSpinAxisTop2, 0, 0.025, 32, 8); + } + glPopMatrix(); + glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + } + + glTranslatef(0.0, 0.0, -4.0); + + glMaterialfv(GL_FRONT, GL_AMBIENT, coneAmbient); + glMaterialfv(GL_FRONT, GL_DIFFUSE, coneDiffuse); + + // draw first cone's outer layer + glBegin(GL_TRIANGLE_FAN); + { + // Pinnacle of cone is shared vertex for fan, moved up z-axis + // to produce a cone instead of a circle + glColor3f(1.0f, 1.0f, 0.0f); + glVertex3f(0.0f, 0.0f, m_pulsarBeamLength); + + // Loop around in a circle and specify even points along the circle + // as the vertices of the triangle fan (32 sections) + for(angle = 0.0f; angle < (2.0f*GL_PI); angle += (GL_PI/32.0f)) + { + // Calculate x and y position of the next vertex + x = m_pulsarBeamOuterRadius * sin(angle); + y = m_pulsarBeamOuterRadius * cos(angle); + + // Specify the next vertex for the triangle fan + glVertex2f(x, y); + } + } + glEnd(); + + // draw first cone's inner layer (do we need/want this?) + glBegin(GL_TRIANGLE_FAN); + { + glColor3f(0.66f, 0.66f, 0.0f); + glVertex3f(0.0f, 0.0f, m_pulsarBeamLength); + for(angle = 0.0f; angle < (2.0f*GL_PI); angle += (GL_PI/32.0f)) { + x = m_pulsarBeamInnerRadius * sin(angle); + y = m_pulsarBeamInnerRadius * cos(angle); + glVertex2f(x, y); + } + } + glEnd(); + + // draw first cone's "rim" (disk topping gap between both cones) + glColor3f(1.0f, 1.0f, 0.5f); + gluDisk(m_quadricPulsarConeRim1, m_pulsarBeamInnerRadius, m_pulsarBeamOuterRadius, 32, 8); + } + glPopMatrix(); - // draw first cone's "rim" (disk topping gap between both cones) - glColor3f(1.0f, 1.0f, 0.5f); - gluDisk(m_quadricPulsarConeRim2, m_pulsarBeamInnerRadius, m_pulsarBeamOuterRadius, 32, 8); + // second cone + glPushMatrix(); + { + glRotatef(180.0, 1.0, 0.0, 0.0); + glRotatef(-m_pulsarSpinAxisInclination, 1.0, 0.0, 0.0); - glPopMatrix(); + glRotatef(-m_pulsarRotationAngle - 90.0, 0.0, 0.0, 1.0); + glRotatef(-m_pulsarMagneticAxisInclination, 0.0, 1.0, 0.0); + glTranslatef(0.0, 0.0, -4.0); + + glMaterialfv(GL_FRONT, GL_AMBIENT, coneAmbient); + glMaterialfv(GL_FRONT, GL_DIFFUSE, coneDiffuse); + + // draw first cone's outer layer + glBegin(GL_TRIANGLE_FAN); + { + // Pinnacle of cone is shared vertex for fan, moved up z-axis + // to produce a cone instead of a circle + glColor3f(1.0f, 1.0f, 0.0f); + glVertex3f(0.0f, 0.0f, 3.0f); + + // Loop around in a circle and specify even points along the circle + // as the vertices of the triangle fan (32 sections) + for(angle = 0.0f; angle < (2.0f*GL_PI); angle += (GL_PI/32.0f)) + { + // Calculate x and y position of the next vertex + x = m_pulsarBeamOuterRadius * sin(angle); + y = m_pulsarBeamOuterRadius * cos(angle); + + // Specify the next vertex for the triangle fan + glVertex2f(x, y); + } + } + glEnd(); + + // draw first cone's inner layer (do we need/want this?) + glBegin(GL_TRIANGLE_FAN); + { + glColor3f(0.66f, 0.66f, 0.0f); + glVertex3f(0.0f, 0.0f, 3.0f); + for(angle = 0.0f; angle < (2.0f*GL_PI); angle += (GL_PI/32.0f)) { + x = m_pulsarBeamInnerRadius * sin(angle); + y = m_pulsarBeamInnerRadius * cos(angle); + glVertex2f(x, y); + } + } + glEnd(); + + // draw first cone's "rim" (disk topping gap between both cones) + glColor3f(1.0f, 1.0f, 0.5f); + gluDisk(m_quadricPulsarConeRim2, m_pulsarBeamInnerRadius, m_pulsarBeamOuterRadius, 32, 8); + } glPopMatrix(); - - glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - - // save current state - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0, width(), 0, height(), 0.1, 501.0); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - // draw backdrop (independent parallel projection) - glColor3f(1.0f, 1.0f, 1.0f); - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_specular); - glTranslatef(0.0, 0.0, -501.0); - drawTexture(QPointF(0.0, 0.0), m_backgroundTexture); - - // restore original state - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); + } + glPopMatrix(); + + glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); + + // save current state + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + { + glLoadIdentity(); + glOrtho(0, width(), 0, height(), 0.1, 501.0); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + { + glLoadIdentity(); + + // draw backdrop (independent parallel projection) + glColor3f(1.0f, 1.0f, 1.0f); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_specular); + glTranslatef(0.0, 0.0, -501.0); + drawTexture(QPointF(0.0, 0.0), m_backgroundTexture); + + // restore original state + glMatrixMode(GL_PROJECTION); + } glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + } + glPopMatrix(); } void PulsarAnimationWidget::runAnimation() { - m_frameTimer.start(qRound(1000.0 / m_framesPerSecond)); + m_frameTimer.start(qRound(1000.0 / m_framesPerSecond)); } void PulsarAnimationWidget::pauseAnimation() { - m_frameTimer.stop(); + m_frameTimer.stop(); } void PulsarAnimationWidget::stopAnimation() { - m_frameTimer.stop(); - resetParameters(); + m_frameTimer.stop(); + resetParameters(); - updateGL(); + updateGL(); } void PulsarAnimationWidget::updateFrame() { - m_pulsarRotationAngle += m_pulsarRotationDelta; - if(m_pulsarRotationAngle > 360.0) { - m_pulsarRotationAngle -= 360.0; - updatePulseProfile(); - } + m_pulsarRotationAngle += m_pulsarRotationDelta; + if(m_pulsarRotationAngle > 360.0) { + m_pulsarRotationAngle -= 360.0; + updatePulseProfile(); + } - updateGL(); + updateGL(); - emit pulsarAnimationStep(m_pulsarRotationAngle); + emit pulsarAnimationStep(m_pulsarRotationAngle); } void PulsarAnimationWidget::showRotationAxes(bool enabled) { - m_showRotationAxes = enabled; + m_showRotationAxes = enabled; - updateGL(); + updateGL(); } void PulsarAnimationWidget::mousePressEvent(QMouseEvent *event) { - Q_UNUSED(event); + Q_UNUSED(event); - m_cameraInteraction = true; - updateGL(); + m_cameraInteraction = true; + updateGL(); } void PulsarAnimationWidget::mouseMoveEvent(QMouseEvent *event) { - Qt::MouseButtons buttons = event->buttons(); - if((buttons & Qt::LeftButton) == Qt::LeftButton) { - if(m_mouseLastX != 0) { - m_mouseAngleH += (m_mouseLastX - event->x()); - m_mouseAngleH = m_mouseAngleH < 360 ? m_mouseAngleH : 0; - m_mouseAngleH = m_mouseAngleH >= 0 ? m_mouseAngleH : 359; - } - if(m_mouseLastY != 0) { - m_mouseAngleV -= (m_mouseLastY - event->y()); - m_mouseAngleV = m_mouseAngleV < 90 ? m_mouseAngleV : 90; - m_mouseAngleV = m_mouseAngleV > -90 ? m_mouseAngleV : -90; - } - - m_mouseLastX = event->x(); - m_mouseLastY = event->y(); - } - else if((buttons & Qt::RightButton) == Qt::RightButton) { - if(m_mouseLastY != 0) { - m_cameraZoom -= (m_mouseLastY - event->y()); - m_cameraZoom = m_cameraZoom >= m_cameraZoomLBound ? m_cameraZoom : m_cameraZoomLBound; - m_cameraZoom = m_cameraZoom >= m_cameraZoomUBound ? m_cameraZoomUBound : m_cameraZoom; - } - - m_mouseLastY = event->y(); - } - - updateCameraPosition(m_mouseAngleH, m_mouseAngleV, m_cameraZoom); + Qt::MouseButtons buttons = event->buttons(); + if((buttons & Qt::LeftButton) == Qt::LeftButton) { + if(m_mouseLastX != 0) { + m_mouseAngleH += (m_mouseLastX - event->x()); + m_mouseAngleH = m_mouseAngleH < 360 ? m_mouseAngleH : 0; + m_mouseAngleH = m_mouseAngleH >= 0 ? m_mouseAngleH : 359; + } + if(m_mouseLastY != 0) { + m_mouseAngleV -= (m_mouseLastY - event->y()); + m_mouseAngleV = m_mouseAngleV < 90 ? m_mouseAngleV : 90; + m_mouseAngleV = m_mouseAngleV > -90 ? m_mouseAngleV : -90; + } + + m_mouseLastX = event->x(); + m_mouseLastY = event->y(); + } + else if((buttons & Qt::RightButton) == Qt::RightButton) { + if(m_mouseLastY != 0) { + m_cameraZoom -= (m_mouseLastY - event->y()); + m_cameraZoom = m_cameraZoom >= m_cameraZoomLBound ? m_cameraZoom : m_cameraZoomLBound; + m_cameraZoom = m_cameraZoom >= m_cameraZoomUBound ? m_cameraZoomUBound : m_cameraZoom; + } + + m_mouseLastY = event->y(); + } + + updateCameraPosition(m_mouseAngleH, m_mouseAngleV, m_cameraZoom); } void PulsarAnimationWidget::mouseReleaseEvent(QMouseEvent *event) { - Q_UNUSED(event); + Q_UNUSED(event); - m_mouseLastX = 0; - m_mouseLastY = 0; - m_cameraInteraction = false; + m_mouseLastX = 0; + m_mouseLastY = 0; + m_cameraInteraction = false; - updateGL(); + updateGL(); } void PulsarAnimationWidget::showEvent(QShowEvent *event) { - Q_UNUSED(event); + Q_UNUSED(event); - // update and propagate pulse profile - updatePulseProfile(); + // update and propagate pulse profile + updatePulseProfile(); } void PulsarAnimationWidget::updateCameraPosition(const double angleH, const double angleV, const double zoom) { m_cameraPosX = sin(angleH * deg2rad) * cos(angleV * deg2rad) * zoom; m_cameraPosY = sin(angleV * deg2rad) * zoom; - m_cameraPosZ = cos(angleH * deg2rad) * cos(angleV * deg2rad) * zoom; + m_cameraPosZ = cos(angleH * deg2rad) * cos(angleV * deg2rad) * zoom; - updatePulseProfile(); + updatePulseProfile(); - updateGL(); + updateGL(); -// qDebug("Camera (x,y,z,+,h,v): %f, %f, %f, %f, %f, %f", m_cameraPosX, m_cameraPosY, m_cameraPosZ, zoom, angleH, angleV); + // qDebug("Camera (x,y,z,+,h,v): %f, %f, %f, %f, %f, %f", m_cameraPosX, m_cameraPosY, m_cameraPosZ, zoom, angleH, angleV); } void PulsarAnimationWidget::setFramePerSecond(const unsigned int fps) { - m_framesPerSecond = fps; + m_framesPerSecond = fps; } void PulsarAnimationWidget::setPulsarSpinFrequency(const double frequency) { - m_pulsarRotationDelta = (360.0 * frequency) / m_framesPerSecond; - updatePulseProfile(); + m_pulsarRotationDelta = (360.0 * frequency) / m_framesPerSecond; + updatePulseProfile(); } void PulsarAnimationWidget::setPulsarSpinAxisInclination(const int degrees) { - m_pulsarSpinAxisInclination = degrees; - updatePulseProfile(); + m_pulsarSpinAxisInclination = degrees; + updatePulseProfile(); - updateGL(); + updateGL(); } void PulsarAnimationWidget::setPulsarMagneticAxisInclination(const int degrees) { - m_pulsarMagneticAxisInclination = degrees; - updatePulseProfile(); + m_pulsarMagneticAxisInclination = degrees; + updatePulseProfile(); - updateGL(); + updateGL(); } void PulsarAnimationWidget::setPulsarBeamAngle(const int degrees) @@ -596,44 +622,44 @@ void PulsarAnimationWidget::setPulsarBeamAngle(const int degrees) void PulsarAnimationWidget::resetParameters() { - m_pulsarRotationAngle = 0.0; - updatePulseProfile(); + m_pulsarRotationAngle = 0.0; + updatePulseProfile(); - emit pulsarAnimationStep(m_pulsarRotationAngle); + emit pulsarAnimationStep(m_pulsarRotationAngle); } void PulsarAnimationWidget::updatePulseProfile() { - // prepare parameters (e.g. convert to radians where necessary) - const double i = deg2rad * m_pulsarSpinAxisInclination; - const double y = deg2rad * m_pulsarMagneticAxisInclination; - double phiOrb = 0.0; - const double deltaPhiRot = deg2rad * 1.0; - const double deltaPhiOrb = deg2rad * deltaPhiRot; - const double rp = 0.0; - const double xk = -m_cameraPosZ; - const double yk = -m_cameraPosX; - const double zk = m_cameraPosY; - const double cam = pow(xk, 2.0) + pow(yk, 2.0) + pow(zk, 2.0); - const double alpha = deg2rad * (90.0 - m_mouseAngleH); - const double delta = deg2rad * m_mouseAngleV; - const double gaussProfile = 0.012337; - - for(int x = 0; x < 360; ++x) { - // determine angle between pulsar's magnetic axis and line of sight - phiOrb += deltaPhiOrb; - const double phiRot = x * deltaPhiRot; - - double a = -sin(y) * sin(phiRot) * (xk + rp * cos(phiOrb)) \ - + (cos(i) * sin(y) * cos(phiRot) + sin(i) * cos(y)) * (yk + rp * sin(phiOrb)) \ - - (sin(i) * sin(y) * cos(phiRot) - cos(i) * cos(y)) * zk; - - double b = sqrt(pow(rp,2.0) + cam - (2.0 * sqrt(cam) * rp * cos(delta) * sin(alpha + phiOrb))); - - // determine and store pulse amplitude - m_pulseProfile[x] = exp(-2.0 * (1.0 - fabs(a/b)) / gaussProfile); - } - - // propagate new profile - emit pulseProfileUpdated(m_pulseProfile); + // prepare parameters (e.g. convert to radians where necessary) + const double i = deg2rad * m_pulsarSpinAxisInclination; + const double y = deg2rad * m_pulsarMagneticAxisInclination; + double phiOrb = 0.0; + const double deltaPhiRot = deg2rad * 1.0; + const double deltaPhiOrb = deg2rad * deltaPhiRot; + const double rp = 0.0; + const double xk = -m_cameraPosZ; + const double yk = -m_cameraPosX; + const double zk = m_cameraPosY; + const double cam = pow(xk, 2.0) + pow(yk, 2.0) + pow(zk, 2.0); + const double alpha = deg2rad * (90.0 - m_mouseAngleH); + const double delta = deg2rad * m_mouseAngleV; + const double gaussProfile = 0.012337; + + for(int x = 0; x < 360; ++x) { + // determine angle between pulsar's magnetic axis and line of sight + phiOrb += deltaPhiOrb; + const double phiRot = x * deltaPhiRot; + + double a = -sin(y) * sin(phiRot) * (xk + rp * cos(phiOrb)) \ + + (cos(i) * sin(y) * cos(phiRot) + sin(i) * cos(y)) * (yk + rp * sin(phiOrb)) \ + - (sin(i) * sin(y) * cos(phiRot) - cos(i) * cos(y)) * zk; + + double b = sqrt(pow(rp,2.0) + cam - (2.0 * sqrt(cam) * rp * cos(delta) * sin(alpha + phiOrb))); + + // determine and store pulse amplitude + m_pulseProfile[x] = exp(-2.0 * (1.0 - fabs(a/b)) / gaussProfile); + } + + // propagate new profile + emit pulseProfileUpdated(m_pulseProfile); }