pulsaranimationwidget.cpp 20.4 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
/******************************************************************************
 *   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"
22
#include "lib/antenna_lib.h"
Oliver Bock's avatar
Oliver Bock committed
23

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

Oliver Bock's avatar
Oliver Bock committed
26
PulsarAnimationWidget::PulsarAnimationWidget(QWidget *parent) :
27
    QGLWidget(QGLFormat(QGL::AlphaChannel | QGL::SampleBuffers), parent)
Oliver Bock's avatar
Oliver Bock committed
28
{
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
    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
51
    // initialize quadric pointers
Oliver Bock's avatar
Oliver Bock committed
52
53
    m_quadricVirgoh = NULL;
    m_quadricVirgov = NULL;
Oliver Bock's avatar
Oliver Bock committed
54
    m_quadricEarth = NULL;
Oliver Bock's avatar
Oliver Bock committed
55
56
    m_quadricLLOh = NULL;
    m_quadricLLOv = NULL;
Oliver Bock's avatar
Oliver Bock committed
57
58
59
    m_quadricSourcePlane = NULL;
    m_quadricSourcePlaneNormal = NULL;
    m_quadricSourcePlaneNormalCap = NULL;
60
    m_quadricSourcePlaneNormalCenter = NULL;
61
62
    m_quadricLHOv = NULL;
    m_quadricLHOh = NULL;
63
64

    // initialize texture pointers
65
    m_beamTexture = 0;
66

67
    // initial parameters (have to match GUI!)
68
69
70
    m_LHOAngle = 0;
    m_LLOAngle = 0;
    m_VirgoAngle = 0;
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 = -55.0;
    m_mouseAngleV = 20.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
    if(m_quadricSourcePlaneNormalCenter) gluDeleteQuadric(m_quadricSourcePlaneNormalCenter);
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
    m_quadricSourcePlaneNormalCenter = gluNewQuadric();
148
149
    m_quadricLHOv = gluNewQuadric();
    m_quadricLHOh = gluNewQuadric();
150

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

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

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

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

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

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

182
183
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
Oliver Bock's avatar
Oliver Bock committed
184

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

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

void PulsarAnimationWidget::paintGL()
{
193
194
    GLfloat x,y,angle;

195
196
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

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

210
211
212
213
214
215
216
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

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

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

249
250
251
252
            glDisable(GL_DEPTH_TEST);
            glEnable(GL_CULL_FACE);
            glColor4f(1.0, 1.0, 1.0f, 0.8f);

253
            // create texture coordinates and enable texturing
Oliver Bock's avatar
Oliver Bock committed
254
            gluQuadricTexture(m_quadricEarth, GL_TRUE);
255
256
            glBindTexture(GL_TEXTURE_2D, m_beamTexture);
            glEnable(GL_TEXTURE_2D);
257

258
259
260
            glCullFace(GL_FRONT);
            gluSphere(m_quadricEarth, m_earthRadius, 32, 32);
            glCullFace(GL_BACK);
Oliver Bock's avatar
Oliver Bock committed
261
            gluSphere(m_quadricEarth, m_earthRadius, 32, 32);
262
263
264

            glDisable(GL_CULL_FACE);
            glEnable(GL_DEPTH_TEST);
265
266
        }
        glPopMatrix();
267
268
    }
    glPopMatrix();
269

270
271
272
273
274
    // draw LHO
    glPushMatrix();
    {
        glColor3f(1.0f, 1.0f, 1.0f);

275
276
277
        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
278
        glTranslatef(0.0, 0.0, m_earthRadius);
279

280
        glRotatef(m_LHOAngle+180, 0.0, 0.0, 1.0);
281
282
283
        glPushMatrix();
        {
            glRotatef(90, 0.0, 1.0, 0.0);
284
            gluCylinder(m_quadricLHOh, 0.020, 0.020, 0.40, 32, 1);
285
286
287
288
289
290
291
        }
        glPopMatrix();

        glPushMatrix();
        {
            glRotatef(90, 0.0, 1.0, 0.0);
            glRotatef(90, 1.0, 0.0, 0.0);
292
293
            glColor3f(0.0f, 0.0f, 1.0f);
            gluCylinder(m_quadricLHOv, 0.020, 0.020, 0.40, 32, 1);
294
295
296
297
298
        }
        glPopMatrix();
    }
    glPopMatrix();

Oliver Bock's avatar
Oliver Bock committed
299
300
301
302
303
    // draw LLO
    glPushMatrix();
    {
        glColor3f(1.0f, 1.0f, 1.0f);

304
305
306
        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
307
        glTranslatef(0.0, 0.0, m_earthRadius);
308

309
        glRotatef(m_LLOAngle-90, 0.0, 0.0, 1.0);
Oliver Bock's avatar
Oliver Bock committed
310
311
312
        glPushMatrix();
        {
            glRotatef(90, 0.0, 1.0, 0.0);
313
            gluCylinder(m_quadricLLOh, 0.020, 0.020, 0.40, 32, 1);
Oliver Bock's avatar
Oliver Bock committed
314
315
316
317
318
319
320
        }
        glPopMatrix();

        glPushMatrix();
        {
            glRotatef(90, 0.0, 1.0, 0.0);
            glRotatef(90, 1.0, 0.0, 0.0);
321
322
            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
323
324
325
326
327
        }
        glPopMatrix();
    }
    glPopMatrix();

Oliver Bock's avatar
Oliver Bock committed
328
329
330
331
332
    // draw Virgo
    glPushMatrix();
    {
        glColor3f(1.0f, 1.0f, 1.0f);

333
334
335
        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
336
        glTranslatef(0.0, 0.0, m_earthRadius);
337

338
        glRotatef(m_VirgoAngle+165, 0.0, 0.0, 1.0);
Oliver Bock's avatar
Oliver Bock committed
339
340
341
        glPushMatrix();
        {
            glRotatef(90, 0.0, 1.0, 0.0);
342
            gluCylinder(m_quadricVirgoh, 0.020, 0.020, 0.40, 32, 1);
Oliver Bock's avatar
Oliver Bock committed
343
344
345
346
347
348
349
        }
        glPopMatrix();

        glPushMatrix();
        {
            glRotatef(90, 0.0, 1.0, 0.0);
            glRotatef(90, 1.0, 0.0, 0.0);
350
351
            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
352
353
354
355
356
        }
        glPopMatrix();
    }
    glPopMatrix();

357
    // draw source
358
    glPushMatrix();
359
    {
360
361
362
363
        // The second rotation isn't right:
        // -> should be around x-axis (not z) and not mess up source iota from below!
        // -> does the x-axis not rotate with its object (around the first y-rotation)?
        // -> putting them in their own matrix doesn't help either
364
365
        glRotatef(-31.384, 0.0, 0.0, 1.0);
        glRotatef(45.093, 0.0, 1.0, 0.0);
366

Oliver Bock's avatar
Oliver Bock committed
367
        glTranslatef(0.0, 0.0, m_earthRadius + 2.0);
368

369
        glPushMatrix();
370
        {
371
            glRotatef(-m_sourceInclination+23.5, 0.0, 0.0, 1.0);
372
            glRotatef(180, 0.0, 1.0, 0.0);
Oliver Bock's avatar
Oliver Bock committed
373
            glRotatef(m_sourceIota, 0.0, 1.0, 0.0);
374

Oliver Bock's avatar
Oliver Bock committed
375
376
377
378
            // draw source plane normal
            glColor3f(1.0f, 0.0f, 0.0f);
            glPushMatrix();
            {
379
                glTranslatef(0.0, 0.0, -1.0);
Oliver Bock's avatar
Oliver Bock committed
380
                gluCylinder(m_quadricSourcePlaneNormal, 0.020, 0.020, 1.5, 32, 1);
Oliver Bock's avatar
Oliver Bock committed
381
382
383
384
            }
            glPopMatrix();
            glPushMatrix();
            {
385
                glTranslatef(0.0, 0.0, -1.0);
Oliver Bock's avatar
Oliver Bock committed
386
                gluDisk(m_quadricSourcePlaneNormalCap, 0, 0.020, 32, 8);
Oliver Bock's avatar
Oliver Bock committed
387
388
389
390
            }
            glPopMatrix();
            glPushMatrix();
            {
391
                glTranslatef(0.0, 0.0, 0.5f);
Oliver Bock's avatar
Oliver Bock committed
392
                glBegin(GL_TRIANGLE_FAN);
Oliver Bock's avatar
Oliver Bock committed
393
                {
Oliver Bock's avatar
Oliver Bock committed
394
395
                    // Pinnacle of cone is shared vertex for fan, moved up z-axis
                    // to produce a cone instead of a circle
396
                    glVertex3f(0.0f, 0.0f, 0.5f);
Oliver Bock's avatar
Oliver Bock committed
397
398
399
400

                    // 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
401
                    {
Oliver Bock's avatar
Oliver Bock committed
402
                        // Calculate x and y position of the next vertex
403
404
                        x = 0.1f * sin(angle);
                        y = 0.1f * cos(angle);
Oliver Bock's avatar
Oliver Bock committed
405
406
407

                        // Specify the next vertex for the triangle fan
                        glVertex2f(x, y);
Oliver Bock's avatar
Oliver Bock committed
408
409
                    }
                }
Oliver Bock's avatar
Oliver Bock committed
410
                glEnd();
411
            }
Oliver Bock's avatar
Oliver Bock committed
412
            glPopMatrix();
413
414
415
416
417
418
            glColor3f(1.0f, 1.0f, 1.0f);
            glPushMatrix();
            {
                gluSphere(m_quadricSourcePlaneNormalCenter, 0.040, 32, 32);
            }
            glPopMatrix();
419

420
421
            // draw disc
            glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, translucent);
422
423
            glEnable(GL_LIGHTING);

424
            glPushMatrix();
425
            {
Oliver Bock's avatar
Oliver Bock committed
426
                gluDisk(m_quadricSourcePlane,
427
                        0,
428
                        1.0,
429
                        64, 1);
430
431
432
            }
            glPopMatrix();

433
            glDisable(GL_LIGHTING);
434
        }
435
436
        glPopMatrix();
    }
437
    glPopMatrix();
Oliver Bock's avatar
Oliver Bock committed
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456

    // 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
457
458
            renderText(10, 40, -100, QString("Copyright %1 2017").arg(QChar(0x00A9)), font);
            renderText(10, 25, -100, tr("O. Bock (UI/Graphics) and B. Allen (Physics)"), font);
459
            renderText(10, 10, -100, tr("Max Planck Institute for Gravitational Physics"), font);
Oliver Bock's avatar
Oliver Bock committed
460
461
462
463
464
465
466
467

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

470
471
void PulsarAnimationWidget::mousePressEvent(QMouseEvent *event)
{
472
    Q_UNUSED(event);
473

474
475
    m_cameraInteraction = true;
    updateGL();
476
477
}

478
479
void PulsarAnimationWidget::mouseMoveEvent(QMouseEvent *event)
{
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
    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);
507
508
509
510
}

void PulsarAnimationWidget::mouseReleaseEvent(QMouseEvent *event)
{
511
    Q_UNUSED(event);
512

513
514
515
    m_mouseLastX = 0;
    m_mouseLastY = 0;
    m_cameraInteraction = false;
516

517
    updateGL();
518
519
}

Oliver Bock's avatar
Oliver Bock committed
520
521
void PulsarAnimationWidget::showEvent(QShowEvent *event)
{
522
    Q_UNUSED(event);
Oliver Bock's avatar
Oliver Bock committed
523

524
525
    // update and propagate pulse profile
    updatePulseProfile();
Oliver Bock's avatar
Oliver Bock committed
526
527
}

Oliver Bock's avatar
Oliver Bock committed
528
void PulsarAnimationWidget::updateCameraPosition(const double angleH, const double angleV, const double zoom)
529
{
530
531
532
    m_cameraPosX = sin(angleH * deg2rad) * cos(angleV * deg2rad) * zoom;
    m_cameraPosY = sin(angleV * deg2rad) * zoom;
    m_cameraPosZ = cos(angleH * deg2rad) * cos(angleV * deg2rad) * zoom;
533

534
    updateGL();
535
536
}

537
void PulsarAnimationWidget::setSourceInclination(const double degrees)
Oliver Bock's avatar
Oliver Bock committed
538
{
539
    m_sourceInclination = degrees;
540
    updatePulseProfile();
Oliver Bock's avatar
Oliver Bock committed
541

542
    updateGL();
Oliver Bock's avatar
Oliver Bock committed
543
}
544

Oliver Bock's avatar
Oliver Bock committed
545
void PulsarAnimationWidget::setLHOAngle(const double degrees)
546
{
547
    m_LHOAngle = degrees;
548
    updatePulseProfile();
Oliver Bock's avatar
Oliver Bock committed
549

550
    updateGL();
551
552
}

553
void PulsarAnimationWidget::setLLOAngle(const double degrees)
554
{
555
    m_LLOAngle = degrees;
556
    updatePulseProfile();
Oliver Bock's avatar
Oliver Bock committed
557
558

    updateGL();
Oliver Bock's avatar
Oliver Bock committed
559
560
}

561
void PulsarAnimationWidget::setVirgoAngle(const int degrees)
Oliver Bock's avatar
Oliver Bock committed
562
{
563
    m_VirgoAngle = degrees;
564
    updatePulseProfile();
565

566
    updateGL();
567
568
}

Oliver Bock's avatar
Oliver Bock committed
569
void PulsarAnimationWidget::setSourceIota(const int degrees)
570
{
Oliver Bock's avatar
Oliver Bock committed
571
    m_sourceIota = degrees;
572
    updatePulseProfile();
573

574
    updateGL();
575
}
576

577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
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);
}

593
594
void PulsarAnimationWidget::updatePulseProfile()
{
595
596
597
598
599
600
601
602
603
    struct InputStruct in;
    struct OutputStruct out;

    in.iota = m_sourceIota;
    in.psi = m_sourceInclination;
    in.orientation[0] = m_LLOAngle;
    in.orientation[1] = m_LHOAngle;
    in.orientation[2] = m_VirgoAngle;

Oliver Bock's avatar
Oliver Bock committed
604
    // get actual detector data
605
606
    get_antenna(&out, &in);

Oliver Bock's avatar
Oliver Bock committed
607
    // populate plot data object
608
609
610
611
612
613
614
615
616
617
    
    // suppose that the initial frequency is 30 Hz and dx is the
    // amount of x range in one cycle.  That means that dx freq0= 360
    // => dx = 360/freq0 = 30ms.  Hence freq0 = 360/30ms.  The phase
    // delay in degrees caused by the offset in arrival time will then
    // be phase_delay_degrees = freq0 * out.dt = 360*out.dt/30ms.  The
    // x delay is then freq0*dx=360*out.dt/30ms => dx =
    // 360*out.dt/(freq0*30ms).

    double freq0 = 1.0/pow(1.1,0.375);
618
619
    double dx[3];
    
Bruce Allen's avatar
Bruce Allen committed
620
    for (int i=0; i<3; i++) dx[i]=360*out.dt[i]/(30.0*freq0);
621
    
622
    for(int x = 0; x < 360*PERIODS; ++x) {
623
624
       double t=x/(PERIODS*360.0);
       double freq = 1.0/pow(1.1-t,0.375);
Bruce Allen's avatar
Bruce Allen committed
625
626
627
       m_plotData.m_dataLLO[x]   = 0.8 * out.amp[0] * freq * freq * sin((freq*(x + dx[0]) + out.phase[0]) * deg2rad);
       m_plotData.m_dataLHO[x]   = 0.8 * out.amp[1] * freq * freq * sin((freq*(x + dx[1]) + out.phase[1]) * deg2rad);
       m_plotData.m_dataVirgo[x] = 0.8 * out.amp[2] * freq * freq * sin((freq*(x + dx[2]) + out.phase[2]) * deg2rad);
628
629
    }

Oliver Bock's avatar
Oliver Bock committed
630
631
632
633
634
635
636
637
638
639
640
641
642
    m_plotData.m_ampLLO   = out.amp[0];
    m_plotData.m_ampLHO   = out.amp[1];
    m_plotData.m_ampVirgo = out.amp[2];

    m_plotData.m_phiLLO   = out.phase[0];
    m_plotData.m_phiLHO   = out.phase[1];
    m_plotData.m_phiVirgo = out.phase[2];

    m_plotData.m_dtLLO   = out.dt[0];
    m_plotData.m_dtLHO   = out.dt[1];
    m_plotData.m_dtVirgo = out.dt[2];

    // propagate new plot data
643
    emit pulseProfileUpdated(m_plotData);
644
}