pulsaranimationwidget.cpp 17.9 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),
27
28
29
    m_curveLHO(360*PERIODS, 0.0),
    m_curveLLO(360*PERIODS, 0.0),
    m_curveVirgo(360*PERIODS, 0.0)
Oliver Bock's avatar
Oliver Bock committed
30
{
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
    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
53
    // initialize quadric pointers
Oliver Bock's avatar
Oliver Bock committed
54
55
    m_quadricVirgoh = NULL;
    m_quadricVirgov = NULL;
Oliver Bock's avatar
Oliver Bock committed
56
    m_quadricEarth = NULL;
Oliver Bock's avatar
Oliver Bock committed
57
58
    m_quadricLLOh = NULL;
    m_quadricLLOv = NULL;
Oliver Bock's avatar
Oliver Bock committed
59
60
61
    m_quadricSourcePlane = NULL;
    m_quadricSourcePlaneNormal = NULL;
    m_quadricSourcePlaneNormalCap = NULL;
62
63
    m_quadricLHOv = NULL;
    m_quadricLHOh = NULL;
64
65

    // initialize texture pointers
66
    m_beamTexture = 0;
67

68
69
    // initial parameters (have to match GUI!)
    m_LHOAngle = 180;
Oliver Bock's avatar
Oliver Bock committed
70
    m_LLOAngle = -90;
Oliver Bock's avatar
Oliver Bock committed
71
    m_VirgoAngle = 165;
Oliver Bock's avatar
Oliver Bock committed
72
    m_sourceIota = 0.0;
73
    m_sourceInclination = 0;
74

Oliver Bock's avatar
Oliver Bock committed
75
    m_earthRadius = 3.0;
76

77
78
79
80
    // initial view features
    m_cameraInteraction = false;

    // initial view settings
81
82
    m_mouseAngleH = 0.0;
    m_mouseAngleV = 0.0;
83
    m_cameraZoom = 100.0;
84
85
86
87
88
89
90
    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
91
92
93
94
}

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

106
    if(m_beamTexture) deleteTexture(m_beamTexture);
Oliver Bock's avatar
Oliver Bock committed
107
108
109
110
}

void PulsarAnimationWidget::initializeGL()
{
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
136
137
138
    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
139
140
    m_quadricVirgoh = gluNewQuadric();
    m_quadricVirgov = gluNewQuadric();
Oliver Bock's avatar
Oliver Bock committed
141
    m_quadricEarth = gluNewQuadric();
Oliver Bock's avatar
Oliver Bock committed
142
143
    m_quadricLLOh = gluNewQuadric();
    m_quadricLLOv = gluNewQuadric();
Oliver Bock's avatar
Oliver Bock committed
144
145
146
    m_quadricSourcePlane = gluNewQuadric();
    m_quadricSourcePlaneNormal = gluNewQuadric();
    m_quadricSourcePlaneNormalCap = gluNewQuadric();
147
148
    m_quadricLHOv = gluNewQuadric();
    m_quadricLHOh = gluNewQuadric();
149

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

Oliver Bock's avatar
Oliver Bock committed
161
162
163
164
    // query max texture size (estimate)
    GLint maxTextureSize;
    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);

165
    // prepare and check beam texture
166
    QImage beamTexture(":/textures/resources/World-Map-7.jpg");
167

Oliver Bock's avatar
Oliver Bock committed
168
    // bind textures
169
    m_beamTexture = bindTexture(beamTexture, GL_TEXTURE_2D, GL_RGBA);
170

171
    // use mipmapped textures
172
173
    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
174
175
176
177
}

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

180
181
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
Oliver Bock's avatar
Oliver Bock committed
182

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

185
186
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
Oliver Bock's avatar
Oliver Bock committed
187
188
189
190
}

void PulsarAnimationWidget::paintGL()
{
191
192
    GLfloat x,y,angle;

193
194
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

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

208
209
210
211
212
213
214
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

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

215
216
217
218
219
220
221
222
223
224
225
226
    // 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)
227
            glColor3f(1.0, 1.0, 1.0f);
228
229
230
231
232
233
234
235
236
237
            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
238
    // draw earth
239
    glPushMatrix();
240
    {
241
        glRotatef(90, 0.0, 1.0, 0.0);
242
        glPushMatrix();
243
244
        {
            glRotatef(90, 1.0, 0.0, 0.0);
245
246
247
            glRotatef(180, 1.0, 1.0, 0.0);

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

Oliver Bock's avatar
Oliver Bock committed
252
            gluSphere(m_quadricEarth, m_earthRadius, 32, 32);
253
254
        }
        glPopMatrix();
255
256
    }
    glPopMatrix();
257

258
259
260
261
262
    // draw LHO
    glPushMatrix();
    {
        glColor3f(1.0f, 1.0f, 1.0f);

263
264
265
        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
266
        glTranslatef(0.0, 0.0, m_earthRadius);
267

268
        glRotatef(m_LHOAngle, 0.0, 0.0, 1.0);
269
270
271
        glPushMatrix();
        {
            glRotatef(90, 0.0, 1.0, 0.0);
272
            gluCylinder(m_quadricLHOh, 0.020, 0.020, 0.40, 32, 1);
273
274
275
276
277
278
279
        }
        glPopMatrix();

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

Oliver Bock's avatar
Oliver Bock committed
287
288
289
290
291
    // draw LLO
    glPushMatrix();
    {
        glColor3f(1.0f, 1.0f, 1.0f);

292
293
294
        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
295
        glTranslatef(0.0, 0.0, m_earthRadius);
296

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

        glPushMatrix();
        {
            glRotatef(90, 0.0, 1.0, 0.0);
            glRotatef(90, 1.0, 0.0, 0.0);
309
310
            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
311
312
313
314
315
        }
        glPopMatrix();
    }
    glPopMatrix();

Oliver Bock's avatar
Oliver Bock committed
316
317
318
319
320
    // draw Virgo
    glPushMatrix();
    {
        glColor3f(1.0f, 1.0f, 1.0f);

321
322
323
        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
324
        glTranslatef(0.0, 0.0, m_earthRadius);
325

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

        glPushMatrix();
        {
            glRotatef(90, 0.0, 1.0, 0.0);
            glRotatef(90, 1.0, 0.0, 0.0);
338
339
            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
340
341
342
343
344
        }
        glPopMatrix();
    }
    glPopMatrix();

345
    // draw source
346
    glPushMatrix();
347
    {
348
349
        glRotatef(-31.384, 0.0, 0.0, 1.0);
        glRotatef(45.093, 0.0, 1.0, 0.0);
350

Oliver Bock's avatar
Oliver Bock committed
351
        glTranslatef(0.0, 0.0, m_earthRadius + 2.0);
352

353
        glRotatef(m_sourceInclination, 0.0, 1.0, 0.0);
354
        glRotatef(180, 0.0, 1.0, 0.0);
355
356

        glPushMatrix();
357
        {
Oliver Bock's avatar
Oliver Bock committed
358
            glRotatef(m_sourceIota, 1.0, 0.0, 0.0);
359

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

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

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

399
400
            // draw disc
            glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, translucent);
401
402
            glEnable(GL_LIGHTING);

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

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

    // 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
436
            renderText(10, 25, -100, QString("Copyright %1 2017").arg(QChar(0x00A9)), font);
437
            renderText(10, 10, -100, tr("Max Planck Institute for Gravitational Physics"), font);
Oliver Bock's avatar
Oliver Bock committed
438
439
440
441
442
443
444
445

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

448
449
void PulsarAnimationWidget::mousePressEvent(QMouseEvent *event)
{
450
    Q_UNUSED(event);
451

452
453
    m_cameraInteraction = true;
    updateGL();
454
455
}

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

void PulsarAnimationWidget::mouseReleaseEvent(QMouseEvent *event)
{
489
    Q_UNUSED(event);
490

491
492
493
    m_mouseLastX = 0;
    m_mouseLastY = 0;
    m_cameraInteraction = false;
494

495
    updateGL();
496
497
}

Oliver Bock's avatar
Oliver Bock committed
498
499
void PulsarAnimationWidget::showEvent(QShowEvent *event)
{
500
    Q_UNUSED(event);
Oliver Bock's avatar
Oliver Bock committed
501

502
503
    // update and propagate pulse profile
    updatePulseProfile();
Oliver Bock's avatar
Oliver Bock committed
504
505
}

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

512
    updatePulseProfile();
513

514
    updateGL();
515
516
}

517
void PulsarAnimationWidget::setSourceInclination(const double degrees)
Oliver Bock's avatar
Oliver Bock committed
518
{
519
    m_sourceInclination = degrees;
520
    updatePulseProfile();
Oliver Bock's avatar
Oliver Bock committed
521

522
    updateGL();
Oliver Bock's avatar
Oliver Bock committed
523
}
524

Oliver Bock's avatar
Oliver Bock committed
525
void PulsarAnimationWidget::setLHOAngle(const double degrees)
526
{
527
    m_LHOAngle = degrees + 180;
528
    updatePulseProfile();
Oliver Bock's avatar
Oliver Bock committed
529

530
    updateGL();
531
532
}

533
void PulsarAnimationWidget::setLLOAngle(const double degrees)
534
{
Oliver Bock's avatar
Oliver Bock committed
535
    m_LLOAngle = degrees - 90;
536
    updatePulseProfile();
Oliver Bock's avatar
Oliver Bock committed
537
538

    updateGL();
Oliver Bock's avatar
Oliver Bock committed
539
540
}

541
void PulsarAnimationWidget::setVirgoAngle(const int degrees)
Oliver Bock's avatar
Oliver Bock committed
542
{
Oliver Bock's avatar
Oliver Bock committed
543
    m_VirgoAngle = degrees + 165;
544
    updatePulseProfile();
545

546
    updateGL();
547
548
}

Oliver Bock's avatar
Oliver Bock committed
549
void PulsarAnimationWidget::setSourceIota(const int degrees)
550
{
Oliver Bock's avatar
Oliver Bock committed
551
    m_sourceIota = degrees;
552
    updatePulseProfile();
553

554
    updateGL();
555
}
556

557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
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);
}

573
574
void PulsarAnimationWidget::updatePulseProfile()
{
575
    for(int x = 0; x < 360*PERIODS; ++x) {
576
577
578
        m_curveLHO[x] = 2.960124 * sin(x*deg2rad) + -0.494787 * cos(x*deg2rad);
        m_curveLLO[x] = -3.533299 * sin(x*deg2rad) + -0.414445 * cos(x*deg2rad);
        m_curveVirgo[x] = -0.984298 * sin(x*deg2rad) + 0.695593 * cos(x*deg2rad);
579
580
581
    }

    // propagate new profile
582
    emit pulseProfileUpdated(m_curveLHO, m_curveLLO, m_curveVirgo);
583
}