Revert "Use fabs() for floats, not abs()".
[agianapa.git] / socg / controlDialog.cpp
blob3598d8c2325915dbb47669ef5e4a731688606faa
1 #include <iostream>
2 #include <QTextStream>
4 #include "controlDialog.h"
5 #include "myglwidget.h"
6 #include "workerthread.h"
8 #define min(a, b) ((a) < (b) ? (a) : (b))
10 ControlDialog::ControlDialog(QWidget *parent)
11 : QDialog(parent)
13 qDebug("ControlDialog::ControlDialog()");
15 // Worker thread populates the data pool with coordinations and angles.
16 // It automatically blocks once the pool has reached a maximum number
17 // of data and wakes up when data resource are low.
18 m_thread.start();
20 // Setup GUI
21 setupUi(this);
23 // Connect signals
24 connect(this, SIGNAL(glSceneNeedsUpdate()),
25 &m_GLScene, SLOT(updateGL()));
26 connect(fileNameEdit, SIGNAL(returnPressed()),
27 this, SLOT(on_fileNameChangedManually()));
28 connect(this, SIGNAL(fileNameChanged(QString)),
29 &m_thread, SLOT(setFileName(QString)));
31 // Timeline
32 connect(&m_timeLine, SIGNAL(valueChanged(qreal)),
33 this, SLOT(pullData(qreal)));
35 // Initialize axis, camera, sphere.
36 // XXX: axis
37 m_axisX.setColor(QColor(255, 0, 0));
38 m_axisY.setColor(QColor(0, 255, 0));
39 m_axisZ.setColor(QColor(0, 0, 255));
40 m_localAxisSystem = false;
42 // Camera
43 m_camera.setEyeX(eyeXEdit->text().toFloat());
44 m_camera.setEyeY(eyeYEdit->text().toFloat());
45 m_camera.setEyeZ(eyeZEdit->text().toFloat());
47 m_camera.setCenterX(centerXEdit->text().toFloat());
48 m_camera.setCenterY(centerYEdit->text().toFloat());
49 m_camera.setCenterZ(centerZEdit->text().toFloat());
51 m_camera.setUpX(upXEdit->text().toFloat());
52 m_camera.setUpY(upYEdit->text().toFloat());
53 m_camera.setUpZ(upZEdit->text().toFloat());
55 // Sphere
56 m_sphere.setRadius(radiusSpin->value());
57 m_sphere.setSlices(slicesSpin->value());
58 m_sphere.setStacks(stacksSpin->value());
59 m_sphere.setCulling(cullingCheck->checkState() == Qt::Checked ?
60 true : false);
62 // Pass objects to GL scene.
63 m_GLScene.setAxis(AXIS_X, &m_axisX);
64 m_GLScene.setAxis(AXIS_Y, &m_axisY);
65 m_GLScene.setAxis(AXIS_Z, &m_axisZ);
67 m_GLScene.setCamera(&m_camera);
68 m_GLScene.setSphere(&m_sphere);
69 m_GLScene.setCoordsAndAngles(&m_coordsAndAngles);
71 // Show scene
72 m_GLScene.setWindowTitle("GL Scene");
73 // Window manager might ignore the following line
74 m_GLScene.move(pos().x() + frameGeometry().width(), pos().y());
75 m_GLScene.show();
77 // At this point the animation isn't ready to begin.
78 // We still miss the following function calls:
79 // WorkerThread::setFileName()
80 // QTimeLine::setFrameRange()
81 // QTimeLine::setUpdateInterval()
82 // QTimeLine::setDuration()
84 // The value grows linearly (e.g., if the duration is 1000 ms,
85 // the value at time 500 ms is 0.5). This isn't the default,
86 // that's why we need to manually set it.
87 m_timeLine.setCurveShape(QTimeLine::LinearCurve);
90 ControlDialog::~ControlDialog()
92 qDebug("ControlDialog::~ControlDialog()");
95 void ControlDialog::on_startButton_clicked()
97 qDebug("ControlDialog::on_startButton_clicked()");
99 m_timeLine.start();
100 stopButton->setEnabled(true);
103 void ControlDialog::on_stopButton_clicked()
105 qDebug("ControlDialog::on_stopButton_clicked()");
107 m_timeLine.stop();
108 stopButton->setEnabled(false);
111 void ControlDialog::on_exitButton_clicked()
113 // qApp is a global pointer referring to the unique application object.
114 qApp->closeAllWindows();
117 void ControlDialog::on_xAxisVisibleCheck_stateChanged(int state)
119 qDebug("ControlDialog::on_xAxisVisibleCheck_stateChanged()\n"
120 "New state = %d", state);
122 m_axisX.setVisible(state == Qt::Checked ? true : false);
123 emit glSceneNeedsUpdate();
126 void ControlDialog::on_yAxisVisibleCheck_stateChanged(int state)
128 qDebug("ControlDialog::on_yAxisVisibleCheck_stateChanged()\n"
129 "New state = %d", state);
131 m_axisY.setVisible(state == Qt::Checked ? true : false);
132 emit glSceneNeedsUpdate();
135 void ControlDialog::on_zAxisVisibleCheck_stateChanged(int state)
137 qDebug("ControlDialog::on_zAxisVisibleCheck_stateChanged()\n"
138 "New state = %d", state);
140 m_axisZ.setVisible(state == Qt::Checked ? true : false);
141 emit glSceneNeedsUpdate();
144 void ControlDialog::on_localAxisCheck_stateChanged(int state)
146 qDebug("ControlDialog::on_localAxisCheck_stateChanged()\n"
147 "New state = %d", state);
149 m_axisX.setLocal(state == Qt::Checked ? true : false);
150 m_axisY.setLocal(state == Qt::Checked ? true : false);
151 m_axisZ.setLocal(state == Qt::Checked ? true : false);
152 emit glSceneNeedsUpdate();
155 void ControlDialog::on_stacksSpin_valueChanged(int i)
157 qDebug("ControlDialog::on_stacksSpin_valueChanged()\n"
158 "New value = %d", i);
160 m_sphere.setStacks(i);
161 emit glSceneNeedsUpdate();
164 void ControlDialog::on_slicesSpin_valueChanged(int i)
166 qDebug("ControlDialog::on_slicesSpin_valueChanged()\n"
167 "New value = %d", i);
169 m_sphere.setSlices(i);
170 emit glSceneNeedsUpdate();
173 void ControlDialog::on_radiusSpin_valueChanged(double d)
175 qDebug("ControlDialog::on_radiusSpin_valueChanged()\n"
176 "New value = %f", d);
178 m_sphere.setRadius(d);
179 emit glSceneNeedsUpdate();
182 void ControlDialog::on_cullingCheck_stateChanged(int state)
184 qDebug("ControlDialog::on_cullingCheck_stateChanged()\n"
185 "New state = %d", state);
187 m_sphere.setCulling(state == Qt::Checked ? true : false);
188 emit glSceneNeedsUpdate();
191 // Camera tab related slots
192 void ControlDialog::on_eyeXEdit_textChanged(const QString& text)
194 qDebug("ControlDialog::on_eyeXEdit_textChanged()\n"
195 "New eyeX = %f", text.toFloat());
197 m_camera.setEyeX(text.toFloat());
198 emit glSceneNeedsUpdate();
201 void ControlDialog::on_eyeYEdit_textChanged(const QString& text)
203 qDebug("ControlDialog::on_eyeYEdit_textChanged()\n"
204 "New eyeY = %f", text.toFloat());
206 m_camera.setEyeY(text.toFloat());
207 emit glSceneNeedsUpdate();
210 void ControlDialog::on_eyeZEdit_textChanged(const QString& text)
212 qDebug("ControlDialog::on_eyeZEdit_textChanged()\n"
213 "New eyeZ = %f", text.toFloat());
215 m_camera.setEyeZ(text.toFloat());
216 emit glSceneNeedsUpdate();
219 void ControlDialog::on_centerXEdit_textChanged(const QString& text)
221 qDebug("ControlDialog::on_centerXEdit_textChanged()\n"
222 "New centerX = %f", text.toFloat());
224 m_camera.setCenterX(text.toFloat());
225 emit glSceneNeedsUpdate();
228 void ControlDialog::on_centerYEdit_textChanged(const QString& text)
230 qDebug("ControlDialog::on_centerYEdit_textChanged()\n"
231 "New centerY = %f", text.toFloat());
233 m_camera.setCenterY(text.toFloat());
234 emit glSceneNeedsUpdate();
237 void ControlDialog::on_centerZEdit_textChanged(const QString& text)
239 qDebug("ControlDialog::on_centerZEdit_textChanged()\n"
240 "New centerZ = %f", text.toFloat());
242 m_camera.setCenterZ(text.toFloat());
243 emit glSceneNeedsUpdate();
246 void ControlDialog::on_upXEdit_textChanged(const QString& text)
248 qDebug("ControlDialog::on_upXEdit_textChanged()\n"
249 "New upX = %f", text.toFloat());
251 m_camera.setUpX(text.toFloat());
252 emit glSceneNeedsUpdate();
255 void ControlDialog::on_upYEdit_textChanged(const QString& text)
257 qDebug("ControlDialog::on_upYEdit_textChanged()\n"
258 "New upY = %f", text.toFloat());
260 m_camera.setUpY(text.toFloat());
261 emit glSceneNeedsUpdate();
264 void ControlDialog::on_upZEdit_textChanged(const QString& text)
266 qDebug("ControlDialog::on_upZEdit_textChanged()\n"
267 "New upZ = %f", text.toFloat());
269 m_camera.setUpZ(text.toFloat());
270 emit glSceneNeedsUpdate();
273 void ControlDialog::on_browseFileButton_clicked(void)
275 QString fileName;
276 float framesPerSec;
277 qDebug("ControlDialog::on_browseFileButton_clicked()");
279 // Get filename from open dialog
280 fileName = QFileDialog::getOpenFileName(this, tr("Open data file"),
281 "/home",
282 "Data files(*.dat);; All files(*)");
283 if (fileName == NULL) {
284 qDebug("QFileDialog::getOpenFileName() returned NULL"
285 "(user pressed cancel");
286 return;
289 // CAUTION: these lines must precede or else the
290 // WorkerThread::extractHeader() won't be called.
291 fileNameEdit->setText(fileName);
292 emit fileNameChanged(fileName);
294 // Update time line
295 m_timeLine.setFrameRange(0, m_thread.getNumOfRecords());
296 framesPerSec = min(fpsSpin->value(),
297 m_thread.getNumOfRecords() / m_thread.getDurationInSec());
298 m_timeLine.setUpdateInterval(1000 / framesPerSec);
299 m_timeLine.setDuration(m_thread.getDurationInSec() * 1000);
300 qDebug("End frame: %d\n", m_timeLine.endFrame());
302 // Construct strings based on the extracted header from the binary file
303 QString magicVersionStr = QString("0x%1")
304 .arg(m_thread.getMagicVersion(), 0, 16).toUpper();
305 QString protocolVersionStr = QString::number(m_thread.getProtocolVersion());
306 QString durationStr = QString::number(m_thread.getDurationInSec());
307 QString numberOfRecordsStr = QString::number(m_thread.getNumOfRecords());
309 // Update the labels in control dialog
310 magicVersionOutputLabel->setText(magicVersionStr);
311 protocolVersionOutputLabel->setText(protocolVersionStr);
312 durationOutputLabel->setText(durationStr);
313 numberOfRecordsOutputLabel->setText(numberOfRecordsStr);
315 if (!startButton->isEnabled())
316 startButton->setEnabled(true);
319 void ControlDialog::on_fileNameChangedManually(void)
321 qDebug("ControlDialog::on_fileNameChangedManually()");
323 QString fileName = fileNameEdit->text();
324 emit fileNameChanged(fileName);
327 void ControlDialog::pullData(qreal time)
329 float t, xp, yp, zp, xa, ya, za;
330 qDebug("ControlDialog::pullData()");
332 if (m_t > time * m_thread.getDurationInSec())
333 return;
335 // Acquire lock
336 m_thread.m_mutex.lock();
338 AGAIN:;
339 qDebug("Timeline[0, 1] = %f\tTarget time(sec) = %f\tCurrent time(sec) = %f",
340 time, time * m_thread.getDurationInSec(), m_t);
342 if (m_thread.m_data.size() >= 1000) {
343 qDebug("Queue size = %d", m_thread.m_data.size());
344 m_t = m_thread.m_data.dequeue();
345 xp = m_thread.m_data.dequeue();
346 yp = m_thread.m_data.dequeue();
347 zp = m_thread.m_data.dequeue();
348 xa = m_thread.m_data.dequeue();
349 ya = m_thread.m_data.dequeue();
350 za = m_thread.m_data.dequeue();
351 //qDebug("t = %f\txp = %f\typ = %f\tzp = %f\txa = %f\tya = %f\tza = %f",
352 // t, xp, yp, zp, xa, ya, za);
353 if (abs(m_t - m_thread.getDurationInSec() * time) < 0.01) {
354 m_coordsAndAngles.setCoordsAndAngles(xp, yp, zp, xa, ya, za);
355 goto OUT;
357 else {
358 goto AGAIN;
361 else {
362 m_thread.m_mutex.unlock();
363 qDebug("WAKING THREAD");
364 m_thread.condition.wakeOne();
365 return;
367 OUT:;
368 m_thread.m_mutex.unlock();
370 emit glSceneNeedsUpdate();
373 void ControlDialog::on_fpsSpin_valueChanged(int i)
375 float framesPerSec;
376 qDebug("ControlDialog::on_fpsSpin_valueChanged()\n"
377 "New value = %d", i);
379 // Stop time line if it's up
380 m_timeLine.stop();
383 framesPerSec = min(m_thread.getNumOfRecords() / m_thread.getDurationInSec(),
385 m_timeLine.setUpdateInterval(1000 / framesPerSec);
387 // Don't resume animation, unless it was running before.
388 if (stopButton->isEnabled())
389 m_timeLine.resume();