pulsaranimationwidget.cpp 17.8 KB
Newer Older
Oliver Bock's avatar
Oliver Bock committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/******************************************************************************
 *   Copyright (C) 2008 by Oliver Bock                                        *
 *   oliver.bock[AT]aei.mpg.de                                                *
 *                                                                            *
 *   This file is part of PulsatingScience.                                   *
 *                                                                            *
 *   PulsatingScience 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 3 of the License.               *
 *                                                                            *
 *   PulsatingScience 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 PulsatingScience. If not, see <http://www.gnu.org/licenses/>. *
 *                                                                            *
 ******************************************************************************/

#include "pulsaranimationwidget.h"

Oliver Bock's avatar
Oliver Bock committed
23
const double PulsarAnimationWidget::deg2rad = PI/180.0;
24

Oliver Bock's avatar
Oliver Bock committed
25
PulsarAnimationWidget::PulsarAnimationWidget(QWidget *parent) :
26
    QGLWidget(QGLFormat(QGL::AlphaChannel | QGL::SampleBuffers), parent)
Oliver Bock's avatar
Oliver Bock committed
27
{
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
    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);
    }

Oliver Bock's avatar
Oliver Bock committed
50
    // initialize quadric pointers
Oliver Bock's avatar
Oliver Bock committed
51
52
    m_quadricVirgoh = NULL;
    m_quadricVirgov = NULL;
Oliver Bock's avatar
Oliver Bock committed
53
    m_quadricEarth = NULL;
Oliver Bock's avatar
Oliver Bock committed
54
55
    m_quadricLLOh = NULL;
    m_quadricLLOv = NULL;
Oliver Bock's avatar
Oliver Bock committed
56
57
58
    m_quadricSourcePlane = NULL;
    m_quadricSourcePlaneNormal = NULL;
    m_quadricSourcePlaneNormalCap = NULL;
59
60
    m_quadricLHOv = NULL;
    m_quadricLHOh = NULL;
61
62

    // initialize texture pointers
63
    m_beamTexture = 0;
64

65
    // initial parameters (have to match GUI!)
66
67
68
    m_LHOAngle = 0;
    m_LLOAngle = 0;
    m_VirgoAngle = 0;
Oliver Bock's avatar
Oliver Bock committed
69
    m_sourceIota = 0.0;
70
    m_sourceInclination = 0;
71

Oliver Bock's avatar
Oliver Bock committed
72
    m_earthRadius = 3.0;
73

74
75
76
77
    // initial view features
    m_cameraInteraction = false;

    // initial view settings
78
79
    m_mouseAngleH = 0.0;
    m_mouseAngleV = 0.0;
80
    m_cameraZoom = 100.0;
81
82
83
84
85
86
87
    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);
Oliver Bock's avatar
Oliver Bock committed
88
89
90
91
}

PulsarAnimationWidget::~PulsarAnimationWidget()
{
Oliver Bock's avatar
Oliver Bock committed
92
93
    if(m_quadricVirgoh) gluDeleteQuadric(m_quadricVirgoh);
    if(m_quadricVirgov) gluDeleteQuadric(m_quadricVirgov);
Oliver Bock's avatar
Oliver Bock committed
94
    if(m_quadricEarth) gluDeleteQuadric(m_quadricEarth);
Oliver Bock's avatar
Oliver Bock committed
95
96
    if(m_quadricLLOh) gluDeleteQuadric(m_quadricLLOh);
    if(m_quadricLLOv) gluDeleteQuadric(m_quadricLLOv);
Oliver Bock's avatar
Oliver Bock committed
97
98
99
    if(m_quadricSourcePlane) gluDeleteQuadric(m_quadricSourcePlane);
    if(m_quadricSourcePlaneNormal) gluDeleteQuadric(m_quadricSourcePlaneNormal);
    if(m_quadricSourcePlaneNormalCap) gluDeleteQuadric(m_quadricSourcePlaneNormalCap);
100
101
    if(m_quadricLHOv) gluDeleteQuadric(m_quadricLHOv);
    if(m_quadricLHOh) gluDeleteQuadric(m_quadricLHOh);
102

103
    if(m_beamTexture) deleteTexture(m_beamTexture);
Oliver Bock's avatar
Oliver Bock committed
104
105
106
107
}

void PulsarAnimationWidget::initializeGL()
{
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
    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, 3.0, 1.0};
    GLfloat spot_direction[] = {0.0, 0.0, -1.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);

    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);

Oliver Bock's avatar
Oliver Bock committed
136
137
    m_quadricVirgoh = gluNewQuadric();
    m_quadricVirgov = gluNewQuadric();
Oliver Bock's avatar
Oliver Bock committed
138
    m_quadricEarth = gluNewQuadric();
Oliver Bock's avatar
Oliver Bock committed
139
140
    m_quadricLLOh = gluNewQuadric();
    m_quadricLLOv = gluNewQuadric();
Oliver Bock's avatar
Oliver Bock committed
141
142
143
    m_quadricSourcePlane = gluNewQuadric();
    m_quadricSourcePlaneNormal = gluNewQuadric();
    m_quadricSourcePlaneNormalCap = gluNewQuadric();
144
145
    m_quadricLHOv = gluNewQuadric();
    m_quadricLHOh = gluNewQuadric();
146

Oliver Bock's avatar
Oliver Bock committed
147
148
    gluQuadricNormals(m_quadricVirgoh, GLU_SMOOTH);
    gluQuadricNormals(m_quadricVirgov, GLU_SMOOTH);
Oliver Bock's avatar
Oliver Bock committed
149
    gluQuadricNormals(m_quadricEarth, GLU_SMOOTH);
Oliver Bock's avatar
Oliver Bock committed
150
151
    gluQuadricNormals(m_quadricLLOh, GLU_SMOOTH);
    gluQuadricNormals(m_quadricLLOv, GLU_SMOOTH);
Oliver Bock's avatar
Oliver Bock committed
152
153
154
    gluQuadricNormals(m_quadricSourcePlane, GLU_SMOOTH);
    gluQuadricNormals(m_quadricSourcePlaneNormal, GLU_SMOOTH);
    gluQuadricNormals(m_quadricSourcePlaneNormalCap, GLU_SMOOTH);
155
156
    gluQuadricNormals(m_quadricLHOv, GLU_SMOOTH);
    gluQuadricNormals(m_quadricLHOh, GLU_SMOOTH);
157

Oliver Bock's avatar
Oliver Bock committed
158
159
160
161
    // query max texture size (estimate)
    GLint maxTextureSize;
    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);

162
    // prepare and check beam texture
163
    QImage beamTexture(":/textures/resources/World-Map-7.jpg");
164

Oliver Bock's avatar
Oliver Bock committed
165
    // bind textures
166
    m_beamTexture = bindTexture(beamTexture, GL_TEXTURE_2D, GL_RGBA);
167

168
    // use mipmapped textures
169
170
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
Oliver Bock's avatar
Oliver Bock committed
171
172
173
174
}

void PulsarAnimationWidget::resizeGL(int w, int h)
{
175
    glViewport(0, 0, w, h);
Oliver Bock's avatar
Oliver Bock committed
176

177
178
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
Oliver Bock's avatar
Oliver Bock committed
179

180
    gluPerspective(4.5, (GLfloat)w / (GLfloat)h, 0.1, 5000.0);
Oliver Bock's avatar
Oliver Bock committed
181

182
183
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
Oliver Bock's avatar
Oliver Bock committed
184
185
186
187
}

void PulsarAnimationWidget::paintGL()
{
188
189
    GLfloat x,y,angle;

190
191
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

192
193
    // TODO: should be located elsewhere
    static GLfloat no_mat[] = {0.0, 0.0, 0.0, 1.0};
194
    static GLfloat mat_diffuse[] = {0.0, 0.0, 0.5, 1.0};
195
196
197
198
199
200
201
202
203
204
    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);

205
206
207
208
209
210
211
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    gluLookAt(m_cameraPosX, m_cameraPosY, m_cameraPosZ,
              0.0, 0.0, 0.0,
              0.0, 1.0, 0.0);

212
213
214
215
216
217
218
219
220
221
222
223
    // save current state (the following is using parallel projection)
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    {
        glLoadIdentity();
        glOrtho(0, width(), 0, height(), 0.1, 501.0);
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
        {
            glLoadIdentity();

            // draw backdrop (independent parallel projection)
224
            glColor3f(1.0, 1.0, 1.0f);
225
226
227
228
229
230
231
232
233
234
            glTranslatef(0.0, 0.0, -501.0);

            // restore original state
            glMatrixMode(GL_PROJECTION);
        }
        glPopMatrix();
        glMatrixMode(GL_MODELVIEW);
    }
    glPopMatrix();

Oliver Bock's avatar
Oliver Bock committed
235
    // draw earth
236
    glPushMatrix();
237
    {
238
        glRotatef(90, 0.0, 1.0, 0.0);
239
        glPushMatrix();
240
241
        {
            glRotatef(90, 1.0, 0.0, 0.0);
242
243
244
            glRotatef(180, 1.0, 1.0, 0.0);

            // create texture coordinates and enable texturing
Oliver Bock's avatar
Oliver Bock committed
245
            gluQuadricTexture(m_quadricEarth, GL_TRUE);
246
247
            glBindTexture(GL_TEXTURE_2D, m_beamTexture);
            glEnable(GL_TEXTURE_2D);
248

Oliver Bock's avatar
Oliver Bock committed
249
            gluSphere(m_quadricEarth, m_earthRadius, 32, 32);
250
251
        }
        glPopMatrix();
252
253
    }
    glPopMatrix();
254

255
256
257
258
259
    // draw LHO
    glPushMatrix();
    {
        glColor3f(1.0f, 1.0f, 1.0f);

260
261
262
        glRotatef(-48.455144, 0.0, 0.0, 1.0);
        glRotatef(-110.407656, 0.0, 1.0, 0.0);

Oliver Bock's avatar
Oliver Bock committed
263
        glTranslatef(0.0, 0.0, m_earthRadius);
264

265
        glRotatef(m_LHOAngle+180, 0.0, 0.0, 1.0);
266
267
268
        glPushMatrix();
        {
            glRotatef(90, 0.0, 1.0, 0.0);
269
            gluCylinder(m_quadricLHOh, 0.020, 0.020, 0.40, 32, 1);
270
271
272
273
274
275
276
        }
        glPopMatrix();

        glPushMatrix();
        {
            glRotatef(90, 0.0, 1.0, 0.0);
            glRotatef(90, 1.0, 0.0, 0.0);
277
278
            glColor3f(0.0f, 0.0f, 1.0f);
            gluCylinder(m_quadricLHOv, 0.020, 0.020, 0.40, 32, 1);
279
280
281
282
283
        }
        glPopMatrix();
    }
    glPopMatrix();

Oliver Bock's avatar
Oliver Bock committed
284
285
286
287
288
    // draw LLO
    glPushMatrix();
    {
        glColor3f(1.0f, 1.0f, 1.0f);

289
290
291
        glRotatef(-30.562894, 0.0, 0.0, 1.0);
        glRotatef(-90.774242, 0.0, 1.0, 0.0);

Oliver Bock's avatar
Oliver Bock committed
292
        glTranslatef(0.0, 0.0, m_earthRadius);
293

294
        glRotatef(m_LLOAngle-90, 0.0, 0.0, 1.0);
Oliver Bock's avatar
Oliver Bock committed
295
296
297
        glPushMatrix();
        {
            glRotatef(90, 0.0, 1.0, 0.0);
298
            gluCylinder(m_quadricLLOh, 0.020, 0.020, 0.40, 32, 1);
Oliver Bock's avatar
Oliver Bock committed
299
300
301
302
303
304
305
        }
        glPopMatrix();

        glPushMatrix();
        {
            glRotatef(90, 0.0, 1.0, 0.0);
            glRotatef(90, 1.0, 0.0, 0.0);
306
307
            glColor3f(1.0f, 0.0f, 0.0f);
            gluCylinder(m_quadricLLOv, 0.020, 0.020, 0.40, 32, 1);
Oliver Bock's avatar
Oliver Bock committed
308
309
310
311
312
        }
        glPopMatrix();
    }
    glPopMatrix();

Oliver Bock's avatar
Oliver Bock committed
313
314
315
316
317
    // draw Virgo
    glPushMatrix();
    {
        glColor3f(1.0f, 1.0f, 1.0f);

318
319
320
        glRotatef(-45.6305, 1.0, 0.0, 0.0);
        glRotatef(7.5021, 0.0, 1.0, 0.0);

Oliver Bock's avatar
Oliver Bock committed
321
        glTranslatef(0.0, 0.0, m_earthRadius);
322

323
        glRotatef(m_VirgoAngle+165, 0.0, 0.0, 1.0);
Oliver Bock's avatar
Oliver Bock committed
324
325
326
        glPushMatrix();
        {
            glRotatef(90, 0.0, 1.0, 0.0);
327
            gluCylinder(m_quadricVirgoh, 0.020, 0.020, 0.40, 32, 1);
Oliver Bock's avatar
Oliver Bock committed
328
329
330
331
332
333
334
        }
        glPopMatrix();

        glPushMatrix();
        {
            glRotatef(90, 0.0, 1.0, 0.0);
            glRotatef(90, 1.0, 0.0, 0.0);
335
336
            glColor3f(0.0f, 1.0f, 0.0f);
            gluCylinder(m_quadricVirgov, 0.020, 0.020, 0.40, 32, 1);
Oliver Bock's avatar
Oliver Bock committed
337
338
339
340
341
        }
        glPopMatrix();
    }
    glPopMatrix();

342
    // draw source
343
    glPushMatrix();
344
    {
345
346
        glRotatef(-31.384, 0.0, 0.0, 1.0);
        glRotatef(45.093, 0.0, 1.0, 0.0);
347

Oliver Bock's avatar
Oliver Bock committed
348
        glTranslatef(0.0, 0.0, m_earthRadius + 2.0);
349

350
        glRotatef(m_sourceInclination, 0.0, 1.0, 0.0);
351
        glRotatef(180, 0.0, 1.0, 0.0);
352
353

        glPushMatrix();
354
        {
Oliver Bock's avatar
Oliver Bock committed
355
            glRotatef(m_sourceIota, 1.0, 0.0, 0.0);
356

Oliver Bock's avatar
Oliver Bock committed
357
358
359
360
            // draw source plane normal
            glColor3f(1.0f, 0.0f, 0.0f);
            glPushMatrix();
            {
361
                glTranslatef(0.0, 0.0, -1.0);
Oliver Bock's avatar
Oliver Bock committed
362
                gluCylinder(m_quadricSourcePlaneNormal, 0.020, 0.020, 1.5, 32, 1);
Oliver Bock's avatar
Oliver Bock committed
363
364
365
366
            }
            glPopMatrix();
            glPushMatrix();
            {
367
                glTranslatef(0.0, 0.0, -1.0);
Oliver Bock's avatar
Oliver Bock committed
368
                gluDisk(m_quadricSourcePlaneNormalCap, 0, 0.020, 32, 8);
Oliver Bock's avatar
Oliver Bock committed
369
370
371
372
            }
            glPopMatrix();
            glPushMatrix();
            {
373
                glTranslatef(0.0, 0.0, 0.5f);
Oliver Bock's avatar
Oliver Bock committed
374
                glBegin(GL_TRIANGLE_FAN);
Oliver Bock's avatar
Oliver Bock committed
375
                {
Oliver Bock's avatar
Oliver Bock committed
376
377
                    // Pinnacle of cone is shared vertex for fan, moved up z-axis
                    // to produce a cone instead of a circle
378
                    glVertex3f(0.0f, 0.0f, 0.5f);
Oliver Bock's avatar
Oliver Bock committed
379
380
381
382

                    // 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*PI); angle += (PI/32.0f))
Oliver Bock's avatar
Oliver Bock committed
383
                    {
Oliver Bock's avatar
Oliver Bock committed
384
                        // Calculate x and y position of the next vertex
385
386
                        x = 0.1f * sin(angle);
                        y = 0.1f * cos(angle);
Oliver Bock's avatar
Oliver Bock committed
387
388
389

                        // Specify the next vertex for the triangle fan
                        glVertex2f(x, y);
Oliver Bock's avatar
Oliver Bock committed
390
391
                    }
                }
Oliver Bock's avatar
Oliver Bock committed
392
                glEnd();
393
            }
Oliver Bock's avatar
Oliver Bock committed
394
            glPopMatrix();
395

396
397
            // draw disc
            glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, translucent);
398
399
            glEnable(GL_LIGHTING);

400
            glPushMatrix();
401
            {
Oliver Bock's avatar
Oliver Bock committed
402
                gluDisk(m_quadricSourcePlane,
403
                        0,
404
                        1.0,
405
                        64, 1);
406
407
408
            }
            glPopMatrix();

409
            glDisable(GL_LIGHTING);
410
        }
411
412
        glPopMatrix();
    }
413
    glPopMatrix();
Oliver Bock's avatar
Oliver Bock committed
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432

    // save current state (the following is using parallel projection)
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    {
        glLoadIdentity();
        glOrtho(0, width(), 0, height(), 0.1, 501.0);
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
        {
            glLoadIdentity();

            // draw copyright info last (appears in front of everything)
            glColor4f(1.0f, 1.0f, 1.0f, 0.5f);
            QFont font;
            font.setPointSize(11);
            font.setBold(true);
            font.setFamily("Arial");
            font.setStyleStrategy((QFont::StyleStrategy) (QFont::OpenGLCompatible | QFont::PreferQuality));
Oliver Bock's avatar
Oliver Bock committed
433
            renderText(10, 25, -100, QString("Copyright %1 2017").arg(QChar(0x00A9)), font);
434
            renderText(10, 10, -100, tr("Max Planck Institute for Gravitational Physics"), font);
Oliver Bock's avatar
Oliver Bock committed
435
436
437
438
439
440
441
442

            // restore original state
            glMatrixMode(GL_PROJECTION);
        }
        glPopMatrix();
        glMatrixMode(GL_MODELVIEW);
    }
    glPopMatrix();
Oliver Bock's avatar
Oliver Bock committed
443
444
}

445
446
void PulsarAnimationWidget::mousePressEvent(QMouseEvent *event)
{
447
    Q_UNUSED(event);
448

449
450
    m_cameraInteraction = true;
    updateGL();
451
452
}

453
454
void PulsarAnimationWidget::mouseMoveEvent(QMouseEvent *event)
{
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
    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);
482
483
484
485
}

void PulsarAnimationWidget::mouseReleaseEvent(QMouseEvent *event)
{
486
    Q_UNUSED(event);
487

488
489
490
    m_mouseLastX = 0;
    m_mouseLastY = 0;
    m_cameraInteraction = false;
491

492
    updateGL();
493
494
}

Oliver Bock's avatar
Oliver Bock committed
495
496
void PulsarAnimationWidget::showEvent(QShowEvent *event)
{
497
    Q_UNUSED(event);
Oliver Bock's avatar
Oliver Bock committed
498

499
500
    // update and propagate pulse profile
    updatePulseProfile();
Oliver Bock's avatar
Oliver Bock committed
501
502
}

Oliver Bock's avatar
Oliver Bock committed
503
void PulsarAnimationWidget::updateCameraPosition(const double angleH, const double angleV, const double zoom)
504
{
505
506
507
    m_cameraPosX = sin(angleH * deg2rad) * cos(angleV * deg2rad) * zoom;
    m_cameraPosY = sin(angleV * deg2rad) * zoom;
    m_cameraPosZ = cos(angleH * deg2rad) * cos(angleV * deg2rad) * zoom;
508

509
    updateGL();
510
511
}

512
void PulsarAnimationWidget::setSourceInclination(const double degrees)
Oliver Bock's avatar
Oliver Bock committed
513
{
514
    m_sourceInclination = degrees;
515
    updatePulseProfile();
Oliver Bock's avatar
Oliver Bock committed
516

517
    updateGL();
Oliver Bock's avatar
Oliver Bock committed
518
}
519

Oliver Bock's avatar
Oliver Bock committed
520
void PulsarAnimationWidget::setLHOAngle(const double degrees)
521
{
522
    m_LHOAngle = degrees;
523
    updatePulseProfile();
Oliver Bock's avatar
Oliver Bock committed
524

525
    updateGL();
526
527
}

528
void PulsarAnimationWidget::setLLOAngle(const double degrees)
529
{
530
    m_LLOAngle = degrees;
531
    updatePulseProfile();
Oliver Bock's avatar
Oliver Bock committed
532
533

    updateGL();
Oliver Bock's avatar
Oliver Bock committed
534
535
}

536
void PulsarAnimationWidget::setVirgoAngle(const int degrees)
Oliver Bock's avatar
Oliver Bock committed
537
{
538
    m_VirgoAngle = degrees;
539
    updatePulseProfile();
540

541
    updateGL();
542
543
}

Oliver Bock's avatar
Oliver Bock committed
544
void PulsarAnimationWidget::setSourceIota(const int degrees)
545
{
Oliver Bock's avatar
Oliver Bock committed
546
    m_sourceIota = degrees;
547
    updatePulseProfile();
548

549
    updateGL();
550
}
551

552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
void PulsarAnimationWidget::getCameraPosition(double& cameraAngleH, double& cameraAngleV, double& cameraZoom)
{
    cameraAngleH = m_mouseAngleH;
    cameraAngleV = m_mouseAngleV;
    cameraZoom = m_cameraZoom;
}

void PulsarAnimationWidget::resetCameraPosition(const double angleH, const double angleV, const double zoom)
{
    m_mouseAngleH = angleH;
    m_mouseAngleV = angleV;
    m_cameraZoom = zoom;

    updateCameraPosition(m_mouseAngleH, m_mouseAngleV, m_cameraZoom);
}

568
569
void PulsarAnimationWidget::updatePulseProfile()
{
570
    for(int x = 0; x < 360*PERIODS; ++x) {
571
572
573
        m_plotData.m_dataLHO[x] = 2.960124 * sin(x*deg2rad) + -0.494787 * cos(x*deg2rad);
        m_plotData.m_dataLLO[x] = -3.533299 * sin(x*deg2rad) + -0.414445 * cos(x*deg2rad);
        m_plotData.m_dataVirgo[x] = -0.984298 * sin(x*deg2rad) + 0.695593 * cos(x*deg2rad);
574
575
576
    }

    // propagate new profile
577
    emit pulseProfileUpdated(m_plotData);
578
}