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

    // initialize texture pointers
65
    m_beamTexture = 0;
66

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

192
193
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

344
    // draw source
345
    glPushMatrix();
346
    {
347
348
349
        glRotatef(-23.384, 0.0, 0.0, 1.0);
        glRotatef(41.093, 0.0, 1.0, 0.0);

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

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

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

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

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

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

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

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

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

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

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

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

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

455
456
void PulsarAnimationWidget::mouseMoveEvent(QMouseEvent *event)
{
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
482
483
    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);
484
485
486
487
}

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

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

494
    updateGL();
495
496
}

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

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

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

511
    updatePulseProfile();
512

513
    updateGL();
514
515
}

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

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

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

529
    updateGL();
530
531
}

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

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

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

545
    updateGL();
546
547
}

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

553
    updateGL();
554
}
555

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

572
573
void PulsarAnimationWidget::updatePulseProfile()
{
574
    for(int x = 0; x < 360; ++x) {
Oliver Bock's avatar
Oliver Bock committed
575
        m_pulseProfile[x] = 0;
576
577
578
579
    }

    // propagate new profile
    emit pulseProfileUpdated(m_pulseProfile);
580
}