TuttleOFX
1
|
00001 #include "InteractScene.hpp" 00002 #include "overlay.hpp" 00003 00004 #include <tuttle/plugin/ofxToGil/point.hpp> 00005 #include <tuttle/plugin/global.hpp> 00006 00007 namespace tuttle { 00008 namespace plugin { 00009 namespace interact { 00010 00011 00012 InteractScene::InteractScene( OFX::ParamSet& params, const InteractInfos& infos ) 00013 : _params( params ) 00014 , _infos( infos ) 00015 , _mouseDown( false ) 00016 , _multiSelectionEnabled( true ) 00017 , _creatingSelection( false ) 00018 , _manipulator( NULL ) 00019 , _manipulatorColor( NULL ) 00020 { 00021 } 00022 00023 InteractScene::~InteractScene() 00024 {} 00025 00026 bool InteractScene::draw( const OFX::DrawArgs& args ) 00027 { 00028 bool result = false; 00029 00030 result |= drawSelection( args ); 00031 00032 IsActiveFunctorVector::iterator itActive = _isActive.begin(); 00033 ColorVector::iterator itColor = _colors.begin(); 00034 00035 for( InteractObjectsVector::iterator it = _objects.begin(), itEnd = _objects.end(); 00036 it != itEnd; 00037 ++it, ++itActive, ++itColor ) 00038 { 00039 if( itActive->active() ) 00040 { 00041 OfxRGBAColourD color = itColor->getColor( args.time ); 00042 glColor4d( color.r, color.g, color.b, color.a ); 00043 result |= it->draw( args ); 00044 } 00045 } 00046 return result; 00047 } 00048 00049 bool InteractScene::penMotion( const OFX::PenArgs& args ) 00050 { 00051 if( !_mouseDown ) 00052 return false; 00053 00054 if( _creatingSelection ) 00055 { 00056 // create selection 00057 00058 TUTTLE_TLOG( TUTTLE_TRACE, "create a selection" ); 00059 _selectionRect.x2 = args.penPosition.x; 00060 _selectionRect.y2 = args.penPosition.y; 00061 _hasSelection = false; 00062 00063 IsActiveFunctorVector::iterator itActive = _isActive.begin(); 00064 for( InteractObjectsVector::iterator it = _objects.begin(), itEnd = _objects.end(); 00065 it != itEnd; 00066 ++it, ++itActive ) 00067 { 00068 if( ! itActive->active() ) 00069 continue; 00070 if( it->isIn( _selectionRect ) ) 00071 { 00072 it->setSelected(true); 00073 _hasSelection = true; 00074 } 00075 else 00076 { 00077 it->setSelected(false); 00078 } 00079 } 00080 return true; 00081 } 00082 00083 if( _selected.size() == 0 ) 00084 { 00085 TUTTLE_LOG_INFOS; 00086 return false; 00087 } 00088 00089 const Point2 penPosition = ofxToGil( args.penPosition ); 00090 switch( _motionType._mode ) 00091 { 00092 case eMotionTranslate: 00093 { 00094 translate( penPosition - _beginPenPosition ); 00095 break; 00096 } 00097 case eMotionRotate: 00098 { 00099 if( _manipulator ) 00100 { 00101 rotate( _manipulator->getPosition(), penPosition, penPosition - _beginPenPosition ); 00102 } 00103 break; 00104 } 00105 case eMotionScale: 00106 { 00107 if( _manipulator ) 00108 scale( _manipulator->getPosition(), penPosition - _beginPenPosition ); 00109 break; 00110 } 00111 case eMotionNone: 00112 { 00113 TUTTLE_LOG_INFOS; 00114 break; 00115 } 00116 } 00117 return true; 00118 } 00119 00120 bool InteractScene::penDown( const OFX::PenArgs& args ) 00121 { 00122 //TUTTLE_LOG_TRACE("penDown"); 00123 const Point2 penPosition = ofxToGil( args.penPosition ); 00124 _mouseDown = true; 00125 _beginPenPosition = penPosition; 00126 _selectionRect.x1 = args.penPosition.x; 00127 _selectionRect.y1 = args.penPosition.y; 00128 _selectionRect.x2 = args.penPosition.x; 00129 _selectionRect.y2 = args.penPosition.y; 00130 _motionType._mode = eMotionNone; 00131 _motionType._axis = eAxisNone; 00132 00133 bool result = false; 00134 SelectedObject oneSelectedObj; 00135 00136 if( _hasSelection && _manipulator ) 00137 { 00138 _motionType = _manipulator->intersect( args ); 00139 if( _motionType._mode != eMotionNone ) 00140 { 00141 result = true; 00142 } 00143 } 00144 if( !result ) 00145 { 00146 IsActiveFunctorVector::iterator itActive = _isActive.begin(); 00147 for( InteractObjectsVector::iterator it = _objects.begin(), itEnd = _objects.end(); 00148 it != itEnd; 00149 ++it, ++itActive ) 00150 { 00151 if( ! itActive->active() ) 00152 continue; 00153 MotionType m = it->intersect( args ); 00154 if( m._axis != eAxisNone ) 00155 { 00156 // first time 00157 if( _motionType._axis == eAxisNone ) 00158 { 00159 oneSelectedObj = SelectedObject( &(*it), it->getPosition() ); 00160 _motionType = m; 00161 } 00162 else if( m._axis == eAxisXY ) // if we already register an object X or Y and we found an XY intersection 00163 { 00164 oneSelectedObj = SelectedObject( &(*it), it->getPosition() ); 00165 _motionType = m; 00166 } 00167 result = true; 00168 if( m._axis == eAxisXY ) 00169 break; 00170 } 00171 } 00172 } 00173 00174 if( _hasSelection ) 00175 { 00176 if( result ) 00177 { 00178 bool objInSelection = false; 00179 // compute the offset for each object 00180 for( SelectedObjectVector::iterator it = _selected.begin(), itEnd = _selected.end(); 00181 it != itEnd; 00182 ++it ) 00183 { 00184 it->second = it->first->getPosition(); 00185 if( it->first == oneSelectedObj.first ) 00186 { 00187 objInSelection = true; 00188 } 00189 } 00190 if( !objInSelection ) 00191 { 00192 _hasSelection = false; 00193 } 00194 } 00195 else 00196 { 00197 _hasSelection = false; 00198 } 00199 } 00200 if( ! _hasSelection ) 00201 { 00202 for( InteractObjectsVector::iterator it = _objects.begin(), itEnd = _objects.end(); 00203 it != itEnd; 00204 ++it ) 00205 { 00206 it->setSelected(false); 00207 } 00208 _selected.clear(); 00209 if( result ) 00210 { 00211 _selected.push_back( oneSelectedObj ); 00212 } 00213 } 00214 00215 if( _multiSelectionEnabled ) 00216 { 00217 if( !result ) 00218 { 00219 _hasSelection = false; 00220 _creatingSelection = true; 00221 } 00222 } 00223 00224 if( _multiSelectionEnabled || result ) 00225 { 00226 _params.beginEditBlock( "InteractObjectsGroup" ); 00227 return true; 00228 } 00229 return false; 00230 } 00231 00232 00233 bool InteractScene::penUp( const OFX::PenArgs& args ) 00234 { 00235 //TUTTLE_LOG_TRACE("penUp"); 00236 bool result = false; 00237 00238 if( _creatingSelection ) 00239 { 00240 _selectionRect.x2 = args.penPosition.x; 00241 _selectionRect.y2 = args.penPosition.y; 00242 00243 _selected.clear(); 00244 //TUTTLE_LOG_VAR4( TUTTLE_TRACE, _selectionRect.x1, _selectionRect.y1, _selectionRect.x2, _selectionRect.y2 ); 00245 IsActiveFunctorVector::iterator itActive = _isActive.begin(); 00246 for( InteractObjectsVector::iterator it = _objects.begin(), itEnd = _objects.end(); 00247 it != itEnd; 00248 ++it, ++itActive ) 00249 { 00250 if( ! itActive->active() ) 00251 continue; 00252 if( it->isIn( _selectionRect ) ) 00253 { 00254 it->setSelected(true); 00255 _selected.push_back( SelectedObject( &(*it), it->getPosition() ) ); 00256 _hasSelection = true; 00257 result = true; 00258 } 00259 else 00260 { 00261 it->setSelected(false); 00262 } 00263 } 00264 //TUTTLE_LOG_VAR( TUTTLE_TRACE, _selected.size() ); 00265 _creatingSelection = false; 00266 } 00267 00268 _mouseDown = false; 00269 _creatingSelection = false; 00270 00271 _params.endEditBlock(); 00272 00273 return result; 00274 } 00275 00276 bool InteractScene::drawSelection( const OFX::DrawArgs& args ) 00277 { 00278 bool result = false; 00279 if( _creatingSelection ) 00280 { 00281 glColor4d( 1.0, 1.0, 1.0, 0.5 ); 00282 overlay::displayRect( _selectionRect ); 00283 glColor4d( 1.0, 1.0, 1.0, 1.0 ); 00284 result = true; 00285 } 00286 else if( _hasSelection && _manipulator ) 00287 { 00288 if( _manipulatorColor ) 00289 { 00290 OfxRGBAColourD color = _manipulatorColor->getColor( args.time ); 00291 glColor4d( color.r, color.g, color.b, color.a ); 00292 } 00293 result |= _manipulator->draw( args ); 00294 } 00295 return result; 00296 } 00297 00298 void InteractScene::translate( const Point2& vec ) 00299 { 00300 //TUTTLE_LOG_VAR2( TUTTLE_TRACE, vec.x, vec.y ); 00301 Point2 newVec = vec; 00302 switch( _motionType._axis ) 00303 { 00304 case eAxisXY: 00305 { 00306 break; 00307 } 00308 case eAxisX: 00309 { 00310 newVec.y = 0; 00311 break; 00312 } 00313 case eAxisY: 00314 { 00315 newVec.x = 0; 00316 break; 00317 } 00318 case eAxisNone: 00319 { 00320 break; 00321 } 00322 } 00323 for( SelectedObjectVector::iterator it = _selected.begin(), itEnd = _selected.end(); 00324 it != itEnd; 00325 ++it ) 00326 { 00327 it->first->translate( it->second, newVec ); 00328 } 00329 } 00330 00331 void InteractScene::rotate( const Point2& center, const Point2& from, const Point2& vec ) 00332 { 00333 for( SelectedObjectVector::iterator it = _selected.begin(), itEnd = _selected.end(); 00334 it != itEnd; 00335 ++it ) 00336 { 00337 it->first->rotate( it->second, center, from, vec ); 00338 } 00339 } 00340 00341 void InteractScene::scale( const Point2& center, const Point2& factor ) 00342 { 00343 Point2 newFactor = factor; 00344 switch( _motionType._axis ) 00345 { 00346 case eAxisXY: 00347 { 00348 break; 00349 } 00350 case eAxisX: 00351 { 00352 newFactor.y = 0; 00353 break; 00354 } 00355 case eAxisY: 00356 { 00357 newFactor.x = 0; 00358 break; 00359 } 00360 case eAxisNone: 00361 { 00362 break; 00363 } 00364 } 00365 for( SelectedObjectVector::iterator it = _selected.begin(), itEnd = _selected.end(); 00366 it != itEnd; 00367 ++it ) 00368 { 00369 it->first->scale( it->second, center, factor ); 00370 } 00371 } 00372 00373 } 00374 } 00375 }