1 //
2 //  MotionBlurSimWindow.cpp
3 //  dart
4 //
5 //  Created by Dong Xu on 1/22/17.
6 //
7 //
8 
9 /////////////////////////////////////////////////////////////////////////
10 // OpenGL Motion blur require the Accumulate function of OpenGL
11 // To intergrate this class into the engine
12 // Change line 86 of dart/gui/glut/Window.cpp
13 // From  glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA |
14 // GLUT_MULTISAMPLE); to    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE |
15 // GLUT_RGBA | GLUT_MULTISAMPLE | GLUT_ACCUM);
16 /////////////////////////////////////////////////////////////////////////
17 
18 #include "dart/gui/glut/MotionBlurSimWindow.hpp"
19 
20 #include "dart/constraint/ConstraintSolver.hpp"
21 #include "dart/gui/GLFuncs.hpp"
22 #include "dart/gui/glut/LoadGlut.hpp"
23 
24 namespace dart {
25 namespace gui {
26 namespace glut {
27 
28 //==============================================================================
MotionBlurSimWindow()29 MotionBlurSimWindow::MotionBlurSimWindow() : SimWindow()
30 {
31   mMotionBlurFrequency = 1;
32 }
33 
34 //==============================================================================
~MotionBlurSimWindow()35 MotionBlurSimWindow::~MotionBlurSimWindow()
36 {
37   // Do nothing
38 }
39 
40 //==============================================================================
setMotionBlurQuality(int _val)41 void MotionBlurSimWindow::setMotionBlurQuality(int _val)
42 {
43   int numIter = mDisplayTimeout / (mWorld->getTimeStep() * 1000);
44   if (_val < 0)
45   {
46     std::cout << "setMotionBlurQuality: input should be an int between 0-5, "
47                  "Regard as 0"
48               << std::endl;
49     std::cout << "0: No motion blur, 5: Motion blur with highest quality"
50               << std::endl;
51     mMotionBlurFrequency = numIter;
52   }
53   else if (_val > 5)
54   {
55     std::cout << "setMotionBlurQuality: input should be an int between 0-5, "
56                  "Regard as 5"
57               << std::endl;
58     std::cout << "0: No motion blur, 5: Motion blur with highest quality"
59               << std::endl;
60     mMotionBlurFrequency = 1;
61   }
62   else if (_val == 0)
63     mMotionBlurFrequency = mDisplayTimeout / (mWorld->getTimeStep() * 1000);
64   else if (_val == 1)
65     mMotionBlurFrequency = std::min(numIter, 16);
66   else if (_val == 2)
67     mMotionBlurFrequency = std::min(numIter, 8);
68   else if (_val == 3)
69     mMotionBlurFrequency = std::min(numIter, 4);
70   else if (_val == 4)
71     mMotionBlurFrequency = std::min(numIter, 2);
72   else // _val == 5
73     mMotionBlurFrequency = 1;
74 }
75 
76 //==============================================================================
render()77 void MotionBlurSimWindow::render()
78 {
79   int numIter = mDisplayTimeout / (mWorld->getTimeStep() * 1000);
80   int numMotionBlurFrames = ceil(
81       floor(mDisplayTimeout)
82       / (mWorld->getTimeStep() * 1000 * mMotionBlurFrequency));
83   if (!mPlay && mSimulating)
84   {
85     for (int i = 0; i < numIter; i += mMotionBlurFrequency)
86     {
87       for (int j = 0; j < mMotionBlurFrequency; j++)
88       {
89         if (i + j < numIter)
90         {
91           timeStepping();
92           mWorld->bake();
93         }
94       }
95 
96       // Update the camera position before every draw
97       glMatrixMode(GL_PROJECTION);
98       glLoadIdentity();
99       gluPerspective(
100           mPersp,
101           static_cast<double>(mWinWidth) / static_cast<double>(mWinHeight),
102           0.1,
103           10.0);
104 
105       glMatrixMode(GL_MODELVIEW);
106       glLoadIdentity();
107       gluLookAt(
108           mEye[0], mEye[1], mEye[2], 0.0, 0.0, -1.0, mUp[0], mUp[1], mUp[2]);
109       initGL();
110 
111       mTrackBall.applyGLRotation();
112 
113       // Draw world origin indicator
114       if (!mCapture)
115       {
116         glEnable(GL_DEPTH_TEST);
117         glDisable(GL_TEXTURE_2D);
118         glDisable(GL_LIGHTING);
119         glLineWidth(2.0);
120         if (mRotate || mTranslate || mZooming)
121         {
122           glColor3f(1.0f, 0.0f, 0.0f);
123           glBegin(GL_LINES);
124           glVertex3f(-0.1f, 0.0f, -0.0f);
125           glVertex3f(0.15f, 0.0f, -0.0f);
126           glEnd();
127 
128           glColor3f(0.0f, 1.0f, 0.0f);
129           glBegin(GL_LINES);
130           glVertex3f(0.0f, -0.1f, 0.0f);
131           glVertex3f(0.0f, 0.15f, 0.0f);
132           glEnd();
133 
134           glColor3f(0.0f, 0.0f, 1.0f);
135           glBegin(GL_LINES);
136           glVertex3f(0.0f, 0.0f, -0.1f);
137           glVertex3f(0.0f, 0.0f, 0.15f);
138           glEnd();
139         }
140       }
141 
142       glScalef(mZoom, mZoom, mZoom);
143       glTranslatef(mTrans[0] * 0.001, mTrans[1] * 0.001, mTrans[2] * 0.001);
144 
145       initLights();
146       draw();
147 
148       if (i == 0)
149       {
150         // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
151         glAccum(GL_LOAD, 1 / float(numMotionBlurFrames));
152       }
153       else
154       {
155         glAccum(GL_ACCUM, 1 / float(numMotionBlurFrames));
156       }
157     } // for loop
158   }   // if simulating
159   else if (mWorld->getRecording()->getNumFrames() == 0)
160   {
161     glMatrixMode(GL_PROJECTION);
162     glLoadIdentity();
163     gluPerspective(
164         mPersp,
165         static_cast<double>(mWinWidth) / static_cast<double>(mWinHeight),
166         0.1,
167         10.0);
168 
169     glMatrixMode(GL_MODELVIEW);
170     glLoadIdentity();
171     gluLookAt(
172         mEye[0], mEye[1], mEye[2], 0.0, 0.0, -1.0, mUp[0], mUp[1], mUp[2]);
173     initGL();
174 
175     mTrackBall.applyGLRotation();
176 
177     // Draw world origin indicator
178     if (!mCapture)
179     {
180       glEnable(GL_DEPTH_TEST);
181       glDisable(GL_TEXTURE_2D);
182       glDisable(GL_LIGHTING);
183       glLineWidth(2.0);
184       if (mRotate || mTranslate || mZooming)
185       {
186         glColor3f(1.0f, 0.0f, 0.0f);
187         glBegin(GL_LINES);
188         glVertex3f(-0.1f, 0.0f, -0.0f);
189         glVertex3f(0.15f, 0.0f, -0.0f);
190         glEnd();
191 
192         glColor3f(0.0f, 1.0f, 0.0f);
193         glBegin(GL_LINES);
194         glVertex3f(0.0f, -0.1f, 0.0f);
195         glVertex3f(0.0f, 0.15f, 0.0f);
196         glEnd();
197 
198         glColor3f(0.0f, 0.0f, 1.0f);
199         glBegin(GL_LINES);
200         glVertex3f(0.0f, 0.0f, -0.1f);
201         glVertex3f(0.0f, 0.0f, 0.15f);
202         glEnd();
203       }
204     }
205 
206     glScalef(mZoom, mZoom, mZoom);
207     glTranslatef(mTrans[0] * 0.001, mTrans[1] * 0.001, mTrans[2] * 0.001);
208 
209     initLights();
210     draw();
211 
212     glAccum(GL_LOAD, 1.0f);
213   }
214 
215   // Draw trackball indicator
216   // Currently, trackball is not counted into the motion blur
217   if (mRotate && !mCapture)
218     mTrackBall.draw(mWinWidth, mWinHeight);
219 
220   // Clear an return the buffer
221   glAccum(GL_RETURN, 1.0f);
222   glutSwapBuffers();
223 
224   if (mCapture)
225     screenshot();
226 }
227 
228 //==============================================================================
displayTimer(int _val)229 void MotionBlurSimWindow::displayTimer(int _val)
230 {
231   if (mPlay)
232   {
233     mPlayFrame += 16;
234     if (mPlayFrame >= mWorld->getRecording()->getNumFrames())
235       mPlayFrame = 0;
236   }
237   glutPostRedisplay();
238   glutTimerFunc(mDisplayTimeout, refreshTimer, _val);
239 }
240 
241 } // namespace glut
242 } // namespace gui
243 } // namespace dart
244