pulsaranimationwidget.cpp 15.2 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"

23 24
const float PulsarAnimationWidget::deg2rad = PI/180.0f;

Oliver Bock's avatar
Oliver Bock committed
25
PulsarAnimationWidget::PulsarAnimationWidget(QWidget *parent) :
Oliver Bock's avatar
Oliver Bock committed
26
	QGLWidget(QGLFormat(QGL::AlphaChannel | QGL::SampleBuffers), parent),
Oliver Bock's avatar
Oliver Bock committed
27
	m_frameTimer()
Oliver Bock's avatar
Oliver Bock committed
28
{
Oliver Bock's avatar
Oliver Bock committed
29 30 31 32 33 34
	if(!format().directRendering()) {
		qWarning("Sorry, no direct rendering support for animation...");
	}
	if(!format().doubleBuffer()) {
		qWarning("Sorry, no double buffering support for animation...");
	}
35
	if(!format().rgba()) {
Oliver Bock's avatar
Oliver Bock committed
36
		qWarning("Sorry, no RGBA support for animation...");
37 38
	}
	if(!format().alpha()) {
Oliver Bock's avatar
Oliver Bock committed
39
		qWarning("Sorry, no alpha channel support for animation...");
40
	}
Oliver Bock's avatar
Oliver Bock committed
41
	if(!format().sampleBuffers()) {
Oliver Bock's avatar
Oliver Bock committed
42
		qWarning("Sorry, no multisampling support for animation...");
Oliver Bock's avatar
Oliver Bock committed
43
	}
44

Oliver Bock's avatar
Oliver Bock committed
45
    connect(&m_frameTimer, SIGNAL(timeout()), this, SLOT(updateFrame()));
Oliver Bock's avatar
Oliver Bock committed
46

Oliver Bock's avatar
Oliver Bock committed
47 48
    m_quadricCompanionOrbitPlane = NULL;
    m_quadricCompanion = NULL;
49
    m_quadricPulsarOrbitPlane = NULL;
Oliver Bock's avatar
Oliver Bock committed
50
    m_quadricPulsar = NULL;
51 52
	m_quadricPulsarCone1 = NULL;
	m_quadricPulsarCone2 = NULL;
53
	m_quadricPulsarSpinAxis = NULL;
54
	m_quadricPulsarMagneticAxis = NULL;
Oliver Bock's avatar
Oliver Bock committed
55

56 57
	m_pulsarTexture = 0;
	m_backgroundTexture = 0;
58

Oliver Bock's avatar
Oliver Bock committed
59
	m_framesPerSecond = 25;
60

61
	resetParameters();
62

Oliver Bock's avatar
Oliver Bock committed
63 64 65
	m_pulsarMass = 1.4f;
	m_companionMass = 1.4f;

Oliver Bock's avatar
Oliver Bock committed
66
	m_showRotationAxes = false;
67
	m_cameraInteraction = false;
68 69
	m_mouseLastX = 0;
	m_mouseLastY = 0;
Oliver Bock's avatar
Oliver Bock committed
70 71
	m_mouseAngleH = 90.0f;
	m_mouseAngleV = 30.f;
72
	m_cameraZoom = 15.0f;
73 74 75
	m_cameraZoomLBound = 2.0f;

	updateCameraPosition(m_mouseAngleH, m_mouseAngleV, m_cameraZoom);
Oliver Bock's avatar
Oliver Bock committed
76 77 78 79
}

PulsarAnimationWidget::~PulsarAnimationWidget()
{
Oliver Bock's avatar
Oliver Bock committed
80 81
	if(m_quadricCompanionOrbitPlane) gluDeleteQuadric(m_quadricCompanionOrbitPlane);
	if(m_quadricCompanion) gluDeleteQuadric(m_quadricCompanion);
82
	if(m_quadricPulsarOrbitPlane) gluDeleteQuadric(m_quadricPulsarOrbitPlane);
Oliver Bock's avatar
Oliver Bock committed
83 84 85
	if(m_quadricPulsar) gluDeleteQuadric(m_quadricPulsar);
	if(m_quadricPulsarCone1) gluDeleteQuadric(m_quadricPulsarCone1);
	if(m_quadricPulsarCone2) gluDeleteQuadric(m_quadricPulsarCone2);
86
	if(m_quadricPulsarSpinAxis) gluDeleteQuadric(m_quadricPulsarSpinAxis);
87
	if(m_quadricPulsarMagneticAxis) gluDeleteQuadric(m_quadricPulsarMagneticAxis);
88 89 90

	if(m_pulsarTexture) deleteTexture(m_pulsarTexture);
	if(m_backgroundTexture) deleteTexture(m_backgroundTexture);
Oliver Bock's avatar
Oliver Bock committed
91 92 93 94
}

void PulsarAnimationWidget::initializeGL()
{
Oliver Bock's avatar
Oliver Bock committed
95 96 97
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glClearDepth(1.0f);
	glDepthFunc(GL_LEQUAL);
98 99 100
	glEnable(GL_DEPTH_TEST);

	glShadeModel(GL_SMOOTH);
Oliver Bock's avatar
Oliver Bock committed
101 102
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

103
	GLfloat LightAmbient[] = { 0.3f, 0.3f, 0.3f, 1.0f };
Oliver Bock's avatar
Oliver Bock committed
104 105 106 107 108 109 110 111 112
	GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
	GLfloat LightSpecular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
	GLfloat LightPosition[] = { 0.0f, 0.0f, 3.0f, 1.0f };
	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);
113
	glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 50.0);
Oliver Bock's avatar
Oliver Bock committed
114
	glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spot_direction);
115
	glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 10.0);
Oliver Bock's avatar
Oliver Bock committed
116 117 118 119

	glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
	glEnable(GL_LIGHT0);
	glEnable(GL_LIGHTING);
Oliver Bock's avatar
Oliver Bock committed
120

121
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
122
	glEnable(GL_BLEND);
123

Oliver Bock's avatar
Oliver Bock committed
124 125
	m_quadricCompanionOrbitPlane = gluNewQuadric();
	m_quadricCompanion = gluNewQuadric();
126
	m_quadricPulsarOrbitPlane = gluNewQuadric();
Oliver Bock's avatar
Oliver Bock committed
127 128 129
	m_quadricPulsar = gluNewQuadric();
    m_quadricPulsarCone1 = gluNewQuadric();
    m_quadricPulsarCone2 = gluNewQuadric();
130
    m_quadricPulsarSpinAxis = gluNewQuadric();
131
    m_quadricPulsarMagneticAxis = gluNewQuadric();
132

Oliver Bock's avatar
Oliver Bock committed
133 134
    gluQuadricNormals(m_quadricCompanionOrbitPlane, GLU_SMOOTH);
    gluQuadricNormals(m_quadricCompanion, GLU_SMOOTH);
135
    gluQuadricNormals(m_quadricPulsarOrbitPlane, GLU_SMOOTH);
Oliver Bock's avatar
Oliver Bock committed
136 137 138
    gluQuadricNormals(m_quadricPulsar, GLU_SMOOTH);
    gluQuadricNormals(m_quadricPulsarCone1, GLU_SMOOTH);
    gluQuadricNormals(m_quadricPulsarCone2, GLU_SMOOTH);
139
    gluQuadricNormals(m_quadricPulsarSpinAxis, GLU_SMOOTH);
140
    gluQuadricNormals(m_quadricPulsarMagneticAxis, GLU_SMOOTH);
141

142
    // load textures
143
    m_pulsarTexture = bindTexture(QImage(":/textures/resources/texture_pulsar.png"), GL_TEXTURE_2D, GL_RGBA);
144
    m_backgroundTexture = bindTexture(QImage(":/textures/resources/texture_background.png"), GL_TEXTURE_2D, GL_RGBA);
145

146
    // use mipmapped textures
147 148 149
    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
150 151 152
    // enable 2D mapping (s/t coordinates, sphere map won't rotate texture!)
    glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
    glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
Oliver Bock's avatar
Oliver Bock committed
153 154 155 156
}

void PulsarAnimationWidget::resizeGL(int w, int h)
{
Oliver Bock's avatar
Oliver Bock committed
157 158 159 160 161
	glViewport(0, 0, w, h);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

Oliver Bock's avatar
Oliver Bock committed
162
	gluPerspective(45.0f, (GLfloat)w / (GLfloat)h, 0.1f, 500.0f);
Oliver Bock's avatar
Oliver Bock committed
163 164 165 166 167 168 169 170 171 172 173 174

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

void PulsarAnimationWidget::paintGL()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

175 176
	gluLookAt(m_cameraPosX, m_cameraPosY, m_cameraPosZ,
			  0.0, 0.0, 0.0,
177
			  0.0, 1.0, 0.0);
Oliver Bock's avatar
Oliver Bock committed
178 179 180 181 182

	// TODO: should be located elsewhere
	static GLfloat no_mat[] = { 0.0, 0.0, 0.0, 1.0 };
	static GLfloat mat_diffuse[] = { 0.5, 0.5, 0.5, 1.0 };
	static GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
183
	static GLfloat low_shininess[] = { 2.5 };
184
	static GLfloat translucent[] = { 1.0, 1.0, 1.0, 0.33 };
185

Oliver Bock's avatar
Oliver Bock committed
186 187 188 189 190
	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);
Oliver Bock's avatar
Oliver Bock committed
191

192
	// draw companion
Oliver Bock's avatar
Oliver Bock committed
193
	glPushMatrix();
Oliver Bock's avatar
Oliver Bock committed
194
		glTranslatef(sin((m_orbitRotationAngle + 180) * deg2rad) * m_companionSemiMajorAxis,
195
					 0.0f,
Oliver Bock's avatar
Oliver Bock committed
196 197
					 cos((m_orbitRotationAngle + 180) * deg2rad) * m_companionSemiMajorAxis);
		gluSphere(m_quadricCompanion, 1.0f, 32, 32);
Oliver Bock's avatar
Oliver Bock committed
198 199
	glPopMatrix();

200
	// draw pulsar
Oliver Bock's avatar
Oliver Bock committed
201
	glPushMatrix();
Oliver Bock's avatar
Oliver Bock committed
202
		glTranslatef(sin(m_orbitRotationAngle * deg2rad) * m_pulsarSemiMajorAxis,
203
					 0.0f,
Oliver Bock's avatar
Oliver Bock committed
204
					 cos(m_orbitRotationAngle * deg2rad) * m_pulsarSemiMajorAxis);
205 206

		glPushMatrix();
207 208
			glRotatef(m_pulsarSpinAxisInclination, 0.0f, 0.0f, 1.0f);
			glRotatef(m_pulsarRotationAngle, 0.0f, 1.0f, 0.0f);
209

210
			// draw spin axis
Oliver Bock's avatar
Oliver Bock committed
211
			if(m_showRotationAxes) {
212 213
				glPushMatrix();
					glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, translucent);
214
					glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
215 216 217 218 219
					glTranslatef(0.0f, 0.0f, -5.0f);
					gluCylinder(m_quadricPulsarSpinAxis, 0.05f, 0.05f, 10.0f, 32, 1);
				glPopMatrix();
			}

220 221 222 223 224
			// create texture coordinates and enable texturing
	        glEnable(GL_TEXTURE_GEN_S);
	        glEnable(GL_TEXTURE_GEN_T);
	        glBindTexture(GL_TEXTURE_2D, m_pulsarTexture);
	        glEnable(GL_TEXTURE_2D);
225 226 227

			glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
			glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
228
			gluSphere(m_quadricPulsar, 1.0f, 32, 32);
229

230
			// disable texturing
231 232 233
	        glDisable(GL_TEXTURE_GEN_S);
	        glDisable(GL_TEXTURE_GEN_T);
	        glDisable(GL_TEXTURE_2D);
234 235
		glPopMatrix();

236 237 238 239 240 241 242
		// TODO: should be located elsewhere
		static GLfloat coneAmbient[] = { 1.0, 1.0, 0.0, 1.0 };
		static GLfloat coneDiffuse[] = { 1.0, 1.0, 0.0, 1.0 };
		static GLfloat coneSpecular[] = { 1.0, 1.0, 0.5, 1.0 };

		glMaterialfv(GL_FRONT, GL_SPECULAR, coneSpecular);

243
		// first cone
244
		glPushMatrix();
245 246 247 248 249
			glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
			glRotatef(m_pulsarSpinAxisInclination, 0.0f, 1.0f, 0.0f);

			glRotatef(-m_pulsarRotationAngle - 90.0f, 0.0f, 0.0f, 1.0f);
			glRotatef(-m_pulsarMagneticAxisInclination, 1.0f, 0.0f, 0.0f);
250

251
			// draw magnetic axis (for both cones)
Oliver Bock's avatar
Oliver Bock committed
252
			if(m_showRotationAxes) {
253 254 255 256 257
				glPushMatrix();
					glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, translucent);
					glTranslatef(0.0f, 0.0f, -5.0f);
					gluCylinder(m_quadricPulsarMagneticAxis, 0.05f, 0.05f, 10.0f, 32, 1);
				glPopMatrix();
258 259
			}

260
			glTranslatef(0.0f, 0.0f, -4.0f);
261 262 263

			glMaterialfv(GL_FRONT, GL_AMBIENT, coneAmbient);
			glMaterialfv(GL_FRONT, GL_DIFFUSE, coneDiffuse);
264 265 266
			gluCylinder(m_quadricPulsarCone1, 0.5f, 0.0f, 3.0f, 32, 32);
		glPopMatrix();

267
		// second cone
268
		glPushMatrix();
269 270
			glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
			glRotatef(-m_pulsarSpinAxisInclination, 0.0f, 1.0f, 0.0f);
271

272 273
			glRotatef(m_pulsarRotationAngle - 90.0f, 0.0f, 0.0f, 1.0f);
			glRotatef(m_pulsarMagneticAxisInclination, 1.0f, 0.0f, 0.0f);
274

275
			glTranslatef(0.0f, 0.0f, -4.0f);
276 277 278

			glMaterialfv(GL_FRONT, GL_AMBIENT, coneAmbient);
			glMaterialfv(GL_FRONT, GL_DIFFUSE, coneDiffuse);
279 280
			gluCylinder(m_quadricPulsarCone2, 0.5f, 0.0f, 3.0f, 32, 32);
		glPopMatrix();
Oliver Bock's avatar
Oliver Bock committed
281
	glPopMatrix();
282

283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
	// save current state
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	glOrtho(0, width(), 0, height(), 0.1f, 501.0f);
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();

	// draw backdrop (independent parallel projection)
	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_specular);
	glTranslatef(0.0f, 0.0f, -501.0f);
	drawTexture(QPointF(0.0f, 0.0f), m_backgroundTexture);

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

Oliver Bock's avatar
Oliver Bock committed
303
	// draw orbital planes
304
	if(m_cameraInteraction) {
305
		glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, translucent);
306

Oliver Bock's avatar
Oliver Bock committed
307 308 309 310 311 312 313
		// companion
		glPushMatrix();
			glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
			glTranslatef(0.0f, 0.0f, 0.0f);
			gluDisk(m_quadricCompanionOrbitPlane,
					m_companionSemiMajorAxis - 0.25f,
					m_companionSemiMajorAxis + 0.25f,
314 315
					64, 1);
		glPopMatrix();
316 317 318 319 320 321 322 323 324 325

		// pulsar
		glPushMatrix();
			glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
			glTranslatef(0.0f, 0.0f, 0.1f);
			gluDisk(m_quadricPulsarOrbitPlane,
					m_pulsarSemiMajorAxis - 0.25f,
					m_pulsarSemiMajorAxis + 0.25f,
					64, 1);
		glPopMatrix();
326
	}
Oliver Bock's avatar
Oliver Bock committed
327 328
}

Oliver Bock's avatar
Oliver Bock committed
329 330
void PulsarAnimationWidget::runAnimation()
{
Oliver Bock's avatar
Oliver Bock committed
331
	m_frameTimer.start(1000.0f / m_framesPerSecond);
Oliver Bock's avatar
Oliver Bock committed
332
}
Oliver Bock's avatar
Oliver Bock committed
333

Oliver Bock's avatar
Oliver Bock committed
334 335 336 337 338 339 340 341
void PulsarAnimationWidget::pauseAnimation()
{
	m_frameTimer.stop();
}

void PulsarAnimationWidget::stopAnimation()
{
	m_frameTimer.stop();
342
	resetParameters();
Oliver Bock's avatar
Oliver Bock committed
343 344 345 346

	updateGL();
}

Oliver Bock's avatar
Oliver Bock committed
347
void PulsarAnimationWidget::updateFrame()
Oliver Bock's avatar
Oliver Bock committed
348
{
Oliver Bock's avatar
Oliver Bock committed
349 350 351
	m_pulsarRotationAngle += m_pulsarRotationDelta;
	if(m_pulsarRotationAngle > 360) {
		m_pulsarRotationAngle = 0.0f;
Oliver Bock's avatar
Oliver Bock committed
352
	}
Oliver Bock's avatar
Oliver Bock committed
353 354 355
	m_orbitRotationAngle += m_orbitRotationDelta;
	if(m_orbitRotationAngle > 360) {
		m_orbitRotationAngle = 0.0f;
Oliver Bock's avatar
Oliver Bock committed
356 357
	}

Oliver Bock's avatar
Oliver Bock committed
358
	updateGL();
Oliver Bock's avatar
Oliver Bock committed
359 360

	emit pulsarAnimationStep(m_pulsarRotationDelta);
361 362
}

Oliver Bock's avatar
Oliver Bock committed
363 364 365 366 367 368 369
void PulsarAnimationWidget::showRotationAxes(bool enabled)
{
	m_showRotationAxes = enabled;

	updateGL();
}

370 371
void PulsarAnimationWidget::mousePressEvent(QMouseEvent *event)
{
372 373
	Q_UNUSED(event);

374 375 376 377
	m_cameraInteraction = true;
	updateGL();
}

378 379 380 381 382 383
void PulsarAnimationWidget::mouseMoveEvent(QMouseEvent *event)
{
	Qt::MouseButtons buttons = event->buttons();
	if((buttons & Qt::LeftButton) == Qt::LeftButton) {
		if(m_mouseLastX != 0) {
			m_mouseAngleH -= (m_mouseLastX - event->x()) / 2;
Oliver Bock's avatar
Oliver Bock committed
384
			m_mouseAngleH = m_mouseAngleH < 360 ? m_mouseAngleH : 0;
385 386 387 388

		}
		if(m_mouseLastY != 0) {
			m_mouseAngleV -= (m_mouseLastY - event->y()) / 2;
Oliver Bock's avatar
Oliver Bock committed
389 390
			m_mouseAngleV = m_mouseAngleV < 90 ? m_mouseAngleV : 90;
			m_mouseAngleV = m_mouseAngleV > -90 ? m_mouseAngleV : -90;
391 392 393 394 395 396 397 398
		}

		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()) / 2;
Oliver Bock's avatar
Oliver Bock committed
399
			m_cameraZoom = m_cameraZoom >= m_cameraZoomLBound ? m_cameraZoom : m_cameraZoomLBound;
400 401 402 403 404 405 406 407 408 409 410
			updateCameraPosition(m_mouseAngleH, m_mouseAngleV, m_cameraZoom);
		}

		m_mouseLastY = event->y();
	}

	updateCameraPosition(m_mouseAngleH, m_mouseAngleV, m_cameraZoom);
}

void PulsarAnimationWidget::mouseReleaseEvent(QMouseEvent *event)
{
411 412
	Q_UNUSED(event);

413 414
	m_mouseLastX = 0;
	m_mouseLastY = 0;
415 416
	m_cameraInteraction = false;
	updateGL();
417 418 419 420 421 422
}

void PulsarAnimationWidget::updateCameraPosition(const int angleH, const int angleV, const float zoom)
{
	m_cameraPosX = sin(angleH * deg2rad) * zoom;
	m_cameraPosY = sin(angleV * deg2rad) * zoom;
Oliver Bock's avatar
Oliver Bock committed
423
	m_cameraPosZ = cos(angleH * deg2rad) * cos(fabs(angleV * deg2rad)) * zoom;
424 425 426 427

	updateGL();
}

Oliver Bock's avatar
Oliver Bock committed
428 429 430 431 432
void PulsarAnimationWidget::setFramePerSecond(const unsigned int fps)
{
	m_framesPerSecond = fps;
}

Oliver Bock's avatar
Oliver Bock committed
433
void PulsarAnimationWidget::setPulsarSemiMajorAxis(const float length)
Oliver Bock's avatar
Oliver Bock committed
434
{
Oliver Bock's avatar
Oliver Bock committed
435 436 437 438 439
	m_pulsarSemiMajorAxis = length;
	m_companionSemiMajorAxis = (m_pulsarMass/m_companionMass) * m_pulsarSemiMajorAxis;
	updateOrbitPeriod();

	updateGL();
Oliver Bock's avatar
Oliver Bock committed
440
}
441

Oliver Bock's avatar
Oliver Bock committed
442
void PulsarAnimationWidget::setCompanionMass(const float mass)
443
{
Oliver Bock's avatar
Oliver Bock committed
444 445 446 447
	m_companionMass = mass;
	updateOrbitRadii();

	updateGL();
448 449
}

Oliver Bock's avatar
Oliver Bock committed
450
void PulsarAnimationWidget::setPulsarMass(const float mass)
451
{
Oliver Bock's avatar
Oliver Bock committed
452 453 454 455 456 457 458 459 460
	m_pulsarMass = mass;
	updateOrbitRadii();

	updateGL();
}

void PulsarAnimationWidget::setPulsarSpinFrequency(const float frequency)
{
	m_pulsarRotationDelta = (360.0f * frequency) / m_framesPerSecond;
461
}
462

463 464 465 466 467 468 469
void PulsarAnimationWidget::setPulsarSpinAxisInclination(const int degrees)
{
	m_pulsarSpinAxisInclination = degrees;

	updateGL();
}

470 471 472 473 474 475
void PulsarAnimationWidget::setPulsarMagneticAxisInclination(const int degrees)
{
	m_pulsarMagneticAxisInclination = degrees;

	updateGL();
}
476

Oliver Bock's avatar
Oliver Bock committed
477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502
void PulsarAnimationWidget::updateOrbitPeriod()
{
	m_orbitalPeriod = 3.1553e7 * sqrt(
						(pow(m_pulsarSemiMajorAxis,3) * pow(m_pulsarMass+m_companionMass,2)) /
						 pow(m_companionMass,3)
					  );

	// visual correction factor (increase orbital momentum)
	double visualCorrection = 1e-8;

	m_orbitRotationDelta  = (360.0 / (m_orbitalPeriod*visualCorrection)) / m_framesPerSecond;
}

void PulsarAnimationWidget::updateOrbitRadii()
{
	m_pulsarSemiMajorAxis = 1.0015e-5 * pow(
								(pow(m_orbitalPeriod,2) * pow(m_companionMass,3)) /
								 pow(m_pulsarMass+m_companionMass,2),
								 1.0/3.0
							);

	m_companionSemiMajorAxis = (m_pulsarMass/m_companionMass) * m_pulsarSemiMajorAxis;

	emit pulsarSemiMajorAxisUpdated(m_pulsarSemiMajorAxis);
}

503 504 505 506
void PulsarAnimationWidget::resetParameters()
{
	m_pulsarRotationAngle = 0.0f;
	m_orbitRotationAngle = 0.0f;
Oliver Bock's avatar
Oliver Bock committed
507 508

	emit pulsarAnimationReset();
509
}