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