TuttleOFX
1
|
00001 #include <tuttle/common/system/windows/windows.h> 00002 00003 #include <GL/glew.h> 00004 #include <tuttle/plugin/opengl/gl.h> 00005 00006 00007 #include "ColorCubeViewerOverlay.hpp" 00008 00009 00010 namespace tuttle { 00011 namespace plugin { 00012 namespace colorCubeViewer { 00013 00014 /* 00015 * Constructor 00016 * @param handle 00017 * @param effect 00018 */ 00019 ColorCubeViewerOverlay::ColorCubeViewerOverlay(OfxInteractHandle handle,OFX::ImageEffect* effect) 00020 : OFX::OverlayInteract(handle) 00021 , _infos(effect) 00022 { 00023 _plugin = static_cast<ColorCubeViewerPlugin*>(_effect); //get plugin 00024 _plugin->addRefCloudPointData(); //create pointer to overlay data 00025 00026 _isPenDown = false; //mouse is not under control by default 00027 _isCtrlKeyDown = false; //Ctrl key is not pressed by default 00028 _rotateX = _rotateY = 0.0; //initialize rotation to 0 00029 _rotateXForm = _rotateYForm = 0.0; //initialize rotation centered to geodesic form to 0 00030 _origin.x = _origin.y = _end.x = _end.y = 0; //initialize mouse positions to 0 00031 00032 setToIdentity(_modelViewMatrix); //set model view matrix to identity 00033 00034 ///HACK : to initialize correctly overlay display data 00035 OFX::InstanceChangedArgs args; //create instance changed arguments 00036 _plugin->changedParam(args,kPointCloudDisplay); //call changed parameters function to initialize overlay data 00037 } 00038 00039 /* 00040 * Destructor 00041 */ 00042 ColorCubeViewerOverlay::~ColorCubeViewerOverlay() 00043 { 00044 _plugin->releaseCloudPointData(); //release Overlay data 00045 } 00046 00047 /* 00048 * Prepare the OpenGL scene for drawing (projection and frustrum settings) 00049 */ 00050 void ColorCubeViewerOverlay::prepareOpenGLScene(const OFX::DrawArgs& args) 00051 { 00052 //reset OpenGL scene (remove previous image) 00053 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 00054 //change background color to gray 00055 glClearColor(0.5f, 0.5f, 0.5f, 1.0f); 00056 00057 //get projection matrix 00058 GLdouble proj_matrix[16]; 00059 glGetDoublev(GL_PROJECTION_MATRIX, proj_matrix); 00060 //initialize model-view and projection matrixes to identity 00061 glMatrixMode( GL_PROJECTION ); // load standard mode 00062 glLoadIdentity(); // projection to identity 00063 glMatrixMode( GL_MODELVIEW ); // load standard mode 00064 glLoadIdentity(); // model-view to identity 00065 00066 //get current viewport size 00067 GLint viewport[4] = { 0, 0, 0, 0 }; // define result array 00068 glGetIntegerv(GL_VIEWPORT,viewport); // get current viewport size 00069 const double ratio = (viewport[2]-viewport[0]) / (double)(viewport[3]-viewport[1]); // compute ratio 00070 //define new coordinates 00071 glOrtho( 0.0, 1.0, 0.0, 1.0, -1.0, 1.0 ); // set coordinates to 0-1 00072 00073 if(args.time != getData()._time || args.time != getData()._averageColor._time) // if current overlay has not been updated 00074 { 00075 //display warning sign on screen 00076 Ofx3DPointD warningPoint; // initialize warning drawing point 00077 warningPoint.x = 0.15; // x == viewport width/7; 00078 warningPoint.y = 0.2; // y == viewport height/5; 00079 drawWarning(warningPoint, ratio); // draw warning sign 00080 } 00081 00082 //define openGL scene frustrum 00083 glMatrixMode( GL_PROJECTION ); // load standard mode 00084 glLoadMatrixd( proj_matrix ); // reload previous projection matrix 00085 00086 const GLdouble vleft = - 0.5; //frustrum left 00087 const GLdouble vright = 1.5; //frustrum right 00088 const GLdouble vbottom = - 0.5; //frustrum bottom 00089 const GLdouble vtop = 1.5; //frustrum top 00090 const GLdouble vnear = 10.0; //frustrum near 00091 const GLdouble vfar = -10.0; //frustrum far 00092 glOrtho( vleft, vright, vbottom, vtop, vnear, vfar); //define new frustrum for overlay data 00093 00094 glMatrixMode( GL_MODELVIEW ); //load standard mode 00095 //initialize double* modelViewMatrix 00096 double modelViewMatrix[16]; //initialize 00097 for(unsigned int i=0; i<16; ++i) 00098 modelViewMatrix[i] = _modelViewMatrix[i]; //recopy Matrix4 into double* 00099 glLoadMatrixd(modelViewMatrix);//load modelView matrix (first time is equal to identity) 00100 } 00101 00102 /* 00103 * Draw the x,Y and Z axes into the OpenGL scene 00104 */ 00105 void ColorCubeViewerOverlay::drawAxes() 00106 { 00107 glBegin(GL_LINES); 00108 //X axis (black => red) 00109 glColor3f(0.0f,0.0f,0.0f); glVertex2i(0,0); //color and direction (0,0,0) 00110 glColor3f(1.0f,0.0f,0.0f); glVertex2i(1,0); //color and direction (1,0,0) 00111 //Y axis (black => green) 00112 glColor3f(0.0f,0.0f,0.0f); glVertex2i(0,0); //color and direction (0,0,0) 00113 glColor3f(0.0f,1.0f,0.0f); glVertex2i(0,1); //color and direction (0,1,0) 00114 //Z axis (black => blue) 00115 glColor3f(0.0f,0.0f,0.0f); glVertex2i(0,0); //color and direction (0,0,0) 00116 glColor3f(0.0f,0.0f,1.0f); glVertex3i(0,0,1); //color and direction (0,0,1) 00117 //axis (red => yellow) 00118 glColor3f(1.0f,0.0f,0.0f); glVertex2i(1,0); //red 00119 glColor3f(1.0f,1.0f,0.0f); glVertex2i(1,1); //yellow 00120 //axis (red => yellow) 00121 glColor3f(0.0f,1.0f,0.0f); glVertex2i(0,1); //green 00122 glColor3f(1.0f,1.0f,0.0f); glVertex2i(1,1); //yellow 00123 //axis (green => cyan) 00124 glColor3f(0.0f,1.0f,0.0f); glVertex2i(0,1); //green 00125 glColor3f(0.0f,1.0f,1.0f); glVertex3i(0,1,1); //cyan 00126 //axis (blue => cyan) 00127 glColor3f(0.0f,0.0f,1.0f); glVertex3i(0,0,1); //blue 00128 glColor3f(0.0f,1.0f,1.0f); glVertex3i(0,1,1); //cyan 00129 //axis (cyan => white) 00130 glColor3f(1.0f,1.0f,1.0f); glVertex3i(1,1,1); //white 00131 glColor3f(0.0f,1.0f,1.0f); glVertex3i(0,1,1); //cyan 00132 //axis (yellow => white) 00133 glColor3f(1.0f,1.0f,1.0f); glVertex3i(1,1,1); //white 00134 glColor3f(1.0f,1.0f,0.0f); glVertex2i(1,1); //yellow 00135 //axis (magenta => white) 00136 glColor3f(1.0f,1.0f,1.0f); glVertex3i(1,1,1); //white 00137 glColor3f(1.0f,0.0f,1.0f); glVertex3i(1,0,1); //magenta 00138 //axis (magenta => blue) 00139 glColor3f(0.0f,0.0f,1.0f); glVertex3i(0,0,1); //blue 00140 glColor3f(1.0f,0.0f,1.0f); glVertex3i(1,0,1); //magenta 00141 //axis (magenta => red) 00142 glColor3f(1.0f,0.0f,0.0f); glVertex2i(1,0); //red 00143 glColor3f(1.0f,0.0f,1.0f); glVertex3i(1,0,1); //magenta 00144 //axis (white => black) 00145 glColor3f(1.0f,1.0f,1.0f); glVertex3i(1,1,1); //white 00146 glColor3f(0.0f,0.0f,0.0f); glVertex2i(0,0); //black 00147 glEnd(); 00148 00149 glPointSize(6.0f); 00150 glBegin(GL_POINTS); 00151 glColor3f(0.0f,0.0f,0.0f); glVertex2i(0,0); //black 00152 glColor3f(1.0f,0.0f,0.0f); glVertex2i(1,0); //red 00153 glColor3f(0.0f,1.0f,0.0f); glVertex2i(0,1); //green 00154 glColor3f(0.0f,0.0f,1.0f); glVertex3i(0,0,1); //blue 00155 glColor3f(1.0f,1.0f,1.0f); glVertex3i(1,1,1); //white 00156 glColor3f(1.0f,0.0f,1.0f); glVertex3i(1,0,1); //magenta 00157 glColor3f(0.0f,1.0f,1.0f); glVertex3i(0,1,1); //cyan 00158 glColor3f(1.0f,1.0f,0.0f); glVertex2i(1,1); //yellow 00159 00160 glPointSize(1.0f); 00161 glEnd(); 00162 } 00163 00164 /* 00165 * Main display of the ColorCubeViewerOverlay class 00166 * @param args current arg (time/renderScale/pixelScale.... 00167 * @return if there is something drawed by the function (y or n) 00168 */ 00169 bool ColorCubeViewerOverlay::draw( const OFX::DrawArgs& args ) 00170 { 00171 bool displaySomethings = false; 00172 if( _plugin->_paramBoolPointCloudDisplay->getValue() ) //Is CloudPointData displayed ? (GUI) 00173 { 00174 glPushMatrix(); //new transformation 00175 prepareOpenGLScene(args); //prepare frustum and projection settings 00176 if(_plugin->_updateVBO ) //VBO need to be updated 00177 { 00178 //update VBO 00179 getData().updateVBO(); //update VBO from VBO data (already computed) 00180 _plugin->_updateVBO = false; //VBO has been recomputed 00181 } 00182 if(_plugin->_resetViewParameters) //View parameters need to be reseted 00183 { 00184 _rotateX = _rotateY = 0; //reset parameters 00185 _rotateXForm = _rotateYForm = 0; //reset geodesic form center rotation parameters 00186 _plugin->_resetViewParameters = false; //view parameters has been changed 00187 setToIdentity(_modelViewMatrix); //reset model-view matrix to identity 00188 } 00189 //OpenGL parameters 00190 glEnable(GL_DEPTH_TEST); //active depth (better for understand results) 00191 00192 //drawing Axes 00193 drawAxes(); //draw the X, Y and Z axes 00194 //drawing VBO 00195 if(getData()._isVBOBuilt) //if VBO has already been built 00196 getData()._imgVBO.draw(); //draw VBO 00197 00198 //drawing color selection VBO 00199 if(getData()._isSelectionVBOBuilt && _plugin->_paramBoolSeeSelection->getValue()) //color selection VBO data is built 00200 { 00201 glColor3f(1.0f,1.0f,1.0f); //color is white 00202 getData()._selectionColorVBO.draw(); //draw selection VBO 00203 } 00204 //drawing spill selection VBO 00205 if(getData()._isSpillSelectionVBOBuilt && _plugin->_paramBoolSeeSpillSelection->getValue()) //spill selection VBO data is built 00206 { 00207 glColor3f(.3f,.3f,.3f); //color is white 00208 getData()._selectionSpillVBO.draw(); //draw selection VBO 00209 } 00210 00211 //drawing average 00212 getData()._averageColor.draw(); //draw average (cross) 00213 //drawing geodesic form 00214 if(_plugin->_paramBoolDisplayGeodesicForm->getValue()) //does user want to display color geodesic form 00215 getData()._geodesicFormColor.draw(false); //draw geodesic form on screen without alpha 00216 if(_plugin->_paramBoolDisplaySpillGF->getValue()) //does user want to display spill geodesic form 00217 getData()._geodesicFormSpill.draw(true); //draw spill geodesic form on screen with alpha 00218 00219 //OpenGL end of parameters 00220 glDisable(GL_DEPTH_TEST); //disable deep 00221 glPopMatrix(); //pop matrix 00222 displaySomethings = true; //something has been drown on screen 00223 } 00224 return displaySomethings; //return if overlay has displayed something (y or n) 00225 } 00226 00227 /* 00228 * Capture and treat click down event 00229 * @param args current argument (time/renderScale/pixelScale.... 00230 * @return if the event has been treated (y or n) 00231 */ 00232 bool ColorCubeViewerOverlay::penDown( const OFX::PenArgs& args ) 00233 { 00234 if(!_isPenDown) //is mouse is not already selected 00235 { 00236 _isPenDown = true; //active mouse operation (for penMotion) 00237 _origin.x = _end.x = args.penPosition.x; //capture x position of current click 00238 _origin.y = _end.y = args.penPosition.y; //capture y position of current click 00239 return true; //event has been captured 00240 } 00241 return false; //event has not been captured 00242 } 00243 00244 /* 00245 * Capture and treat click up event (release mouse) 00246 * @param args current argument (time/renderScale/pixelScale.... 00247 * @return if the event has been treated (y or n) 00248 */ 00249 bool ColorCubeViewerOverlay::penUp( const OFX::PenArgs& args ) 00250 { 00251 if(_isPenDown) //is mouse is already selected 00252 { 00253 _isPenDown = false; //mouse is no more selected 00254 _end.x = args.penPosition.x; //capture mouse current position x 00255 _end.y = args.penPosition.y; //capture mouse current position y 00256 00257 if(_origin.x == _end.x && _origin.y == _end.y) 00258 return false; //basic click (there is nothing to do in this case) 00259 return true; //event has been captured 00260 } 00261 return false; //event has not been captured 00262 } 00263 00264 /* 00265 * Treat if mouse/pen is under motion (drawing on screen for example) 00266 * @param args current arg (time/renderScale/pixelScale.... 00267 * @return if the event has been treated (y or n) 00268 */ 00269 bool ColorCubeViewerOverlay::penMotion( const OFX::PenArgs& args ) 00270 { 00271 if(_isPenDown) //if mouse is already selected 00272 { 00273 _end.x = args.penPosition.x; //capture mouse current position x 00274 _end.y = args.penPosition.y; //capture mouse current position y 00275 00276 int deltaX = _end.x - _origin.x; //compute delta for rotation on Y axis (horizontal) 00277 int deltaY = _end.y - _origin.y; //compute delta for rotation on X axis (vertical) 00278 if(_isCtrlKeyDown) //rotation center is current color selection average 00279 { 00280 _rotateXForm = (deltaX/args.pixelScale.x)/kRotationSpeed; //add delta to geodesic center rotation (X axis) 00281 _rotateYForm = (deltaY/args.pixelScale.y)/kRotationSpeed; //add delta to geodesic center rotation (Y axis) 00282 00283 //update model-View matrix 00284 Ofx3DPointD rotationCenter = getData()._geodesicFormColor._center; //get current rotation center 00285 updateModelView(rotationCenter); //update model-view 00286 } 00287 else //rotation center is reference center (0.5,0.5,0.5 in cube reference) 00288 { 00289 _rotateX = (deltaX/args.pixelScale.x)/kRotationSpeed; //add delta to cube rotation (X axis) 00290 _rotateY = (deltaY/args.pixelScale.y)/kRotationSpeed; //add delta to cube rotation (Y axis) 00291 00292 //update model-View matrix 00293 Ofx3DPointD rotationCenter; //create rotation center 00294 rotationCenter.x = 0.5; //set rotation center X value 0 by default 00295 rotationCenter.y = 0.5; //set rotation center Y value 00296 rotationCenter.z = 0.5; //set rotation center Z value 00297 updateModelView(rotationCenter); //update model-view 00298 } 00299 _origin.x = args.penPosition.x; //change origin X (prepare next penMotion) 00300 _origin.y = args.penPosition.y; //change origin Y (prepare next penMotion) 00301 00302 return true; //event has been captured 00303 } 00304 return false; 00305 } 00306 00307 /* 00308 * Treat the Ctrl key pressed (down) 00309 * @param args current arg (time/rendeerScale/...) 00310 * @return if the event has been treated (y or n) 00311 */ 00312 bool ColorCubeViewerOverlay::keyDown( const OFX::KeyArgs& args ) 00313 { 00314 if(args.keySymbol==kOfxKey_Control_L||args.keySymbol==kOfxKey_Control_R) //if the pressed key is Ctrl key (left or right) 00315 { 00316 _isCtrlKeyDown = true; //Ctrl key is pressed 00317 return true; //event has been treated 00318 } 00319 return false; //event has not been treated (key pressed is not Ctrl) 00320 } 00321 00322 /* 00323 * Treat the Ctrl key pressed (up) 00324 * @param args current arg (time/rendeerScale/...) 00325 * @return if the event has been treated (y or n) 00326 */ 00327 bool ColorCubeViewerOverlay::keyUp( const OFX::KeyArgs& args ) 00328 { 00329 if(args.keySymbol==kOfxKey_Control_L||args.keySymbol==kOfxKey_Control_R) //if the pressed key is Ctrl key (left or right) 00330 { 00331 if(_isCtrlKeyDown) 00332 _isCtrlKeyDown = false; //Ctrl key is not pressed anymore 00333 return true; //event has been treated 00334 } 00335 return false; //event has not been treated (key pressed is not Ctrl) 00336 } 00337 00338 /* 00339 * Get cloud point data from ColorCubeViewerPlugin 00340 * @return 00341 */ 00342 CloudPointData& ColorCubeViewerOverlay::getData() 00343 { 00344 return _plugin->getCloudPointData(); //return CloudPointData initialized at constructor (by scoped pointer) 00345 } 00346 00347 00348 00349 /* 00350 * Update the average coordinates with center rotation 00351 */ 00352 void ColorCubeViewerOverlay::updateModelView(const Ofx3DPointD& rotationCenter) 00353 { 00354 //Define and create new transformation matrix 00355 Matrix4 newTransformationMatrix; //initialize new transformation matrix 00356 if(rotationCenter.x == 0.5 && rotationCenter.y == 0.5 && rotationCenter.z == 0.5) //if current rotation center is reference center 00357 newTransformationMatrix = constructRotationMatrix(rotationCenter,_rotateY,_rotateX,0); //construct new transformation matrix 00358 else //current rotation center is geodesic form center 00359 newTransformationMatrix = constructRotationMatrix(rotationCenter,_rotateYForm,_rotateXForm,0); //construct new transformation matrix 00360 //X and Y angles are inverted (better to control view) 00361 //Add current transformation to model-view matrix 00362 multMatrixBtoMatrixA(_modelViewMatrix,newTransformationMatrix); //add current transformation to model-view matrix 00363 } 00364 00365 /* 00366 * Draw a warning sign on the openGL scene 00367 */ 00368 void ColorCubeViewerOverlay::drawWarning(const Ofx3DPointD& centerPoint, const double ratio) 00369 { 00370 float size = 5.0f; //define size 00371 glColor3f(1.0f,.7f,0); //color orange 00372 glLineWidth(size); //change line width (bigger) 00373 //draw triangle 00374 glBegin(GL_LINE_STRIP); //draw exterior triangle 00375 glVertex2d((centerPoint.x - 0.025*ratio),centerPoint.y); //first point of triangle 00376 glVertex2d((centerPoint.x + 0.025*ratio),centerPoint.y); //second point of triangle 00377 glVertex2d(centerPoint.x,(centerPoint.y+0.085*ratio)); //third point of triangle 00378 glVertex2d((centerPoint.x - 0.025*ratio),centerPoint.y); //first point of triangle (boucle) 00379 glEnd(); //end of drawing 00380 //draw ! 00381 glBegin(GL_LINES); //draw ! sign 00382 glVertex2d(centerPoint.x, (centerPoint.y+0.07*ratio)); //first point 00383 glVertex2d(centerPoint.x, (centerPoint.y+0.03*ratio)); //second point 00384 glEnd(); //end of drawing 00385 glBegin(GL_POINTS); //draw ! point 00386 glPointSize(size); //change point size (bigger) 00387 glVertex2d(centerPoint.x, (centerPoint.y + 0.02*ratio)); //point of ! 00388 glEnd(); //end of drawing 00389 //reset basic parameters 00390 glLineWidth(1.0f); //reset line width (normal) 00391 glPointSize(1.0f); //reset point size (normal) 00392 } 00393 00394 00395 } 00396 } 00397 } 00398