VTrack.cpp
Engine/source/Verve/Core/VTrack.cpp
Public Functions
Detailed Description
Public Functions
IMPLEMENT_CONOBJECT(VTrack )
1 2//----------------------------------------------------------------------------- 3// Verve 4// Copyright (C) 2014 - Violent Tulip 5// 6// Permission is hereby granted, free of charge, to any person obtaining a copy 7// of this software and associated documentation files (the "Software"), to 8// deal in the Software without restriction, including without limitation the 9// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10// sell copies of the Software, and to permit persons to whom the Software is 11// furnished to do so, subject to the following conditions: 12// 13// The above copyright notice and this permission notice shall be included in 14// all copies or substantial portions of the Software. 15// 16// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22// IN THE SOFTWARE. 23//----------------------------------------------------------------------------- 24#include "Verve/Core/VTrack.h" 25#include "Verve/Core/VGroup.h" 26#include "Verve/Core/VController.h" 27#include "math/mMath.h" 28 29//----------------------------------------------------------------------------- 30IMPLEMENT_CONOBJECT( VTrack ); 31//----------------------------------------------------------------------------- 32 33VTrack::VTrack( void ) : 34 mNextEvent( NULL ) 35{ 36 setLabel( "DefaultTrack" ); 37} 38 39//----------------------------------------------------------------------------- 40// 41// Tree Methods. 42// 43//----------------------------------------------------------------------------- 44 45//----------------------------------------------------------------------------- 46// 47// VTrack::onAttach(); 48// 49// This callback subscribes this object to the controller's event signal. 50// 51//----------------------------------------------------------------------------- 52void VTrack::onAttach( void ) 53{ 54 Parent::onAttach(); 55 56 // Valid Controller? 57 if ( getController() ) 58 { 59 // Subscribe to Updates. 60 getController()->getControllerUpdateSignal().notify( this, &VTrack::onControllerUpdate ); 61 62 // Subscribe to Events. 63 getController()->getControllerEventSignal().notify( this, &VTrack::onControllerEvent ); 64 } 65} 66 67//----------------------------------------------------------------------------- 68// 69// VTrack::onAttach(); 70// 71// This callback removes this object from the controller's event signal 72// notification list. 73// 74//----------------------------------------------------------------------------- 75void VTrack::onDetach( void ) 76{ 77 // Valid Controller? 78 if ( getController() ) 79 { 80 // Remove Update Notification. 81 getController()->getControllerUpdateSignal().remove( this, &VTrack::onControllerUpdate ); 82 83 // Remove Event Notification. 84 getController()->getControllerEventSignal().remove( this, &VTrack::onControllerEvent ); 85 } 86 87 Parent::onDetach(); 88} 89 90//----------------------------------------------------------------------------- 91// 92// Controller Methods. 93// 94//----------------------------------------------------------------------------- 95 96//----------------------------------------------------------------------------- 97// 98// VTrack::onControllerUpdate( pTime, pDelta ); 99// 100// The Next Event is integrated until has finished its execution. Once it has 101// finished, the next event to be triggered becomes the Current Event. Doing 102// this means that only one event is ever checked to see if it should be 103// triggered. 104// 105//----------------------------------------------------------------------------- 106void VTrack::onControllerUpdate( const S32 &pTime, const S32 &pDelta ) 107{ 108 if ( !isEnabled() || !mNextEvent ) 109 { 110 // Don't Update. 111 return; 112 } 113 114 // Update Next Event. 115 while ( !mNextEvent->onControllerUpdate( pTime, pDelta ) ) 116 { 117 // Next Event? 118 if ( !updateNextEvent() ) 119 { 120 // No Valid Events. 121 mNextEvent = NULL; 122 break; 123 } 124 } 125} 126 127//----------------------------------------------------------------------------- 128// 129// VTrack::onControllerEvent( pEvent ); 130// 131// When the controller's state changes, this method is called. If the 132// controller is reset the virtual method, onControllerReset is called. 133// 134// For a full list of possible events, see the 'eControllerEventType' 135// declaration in VController.h. 136// 137//----------------------------------------------------------------------------- 138bool VTrack::onControllerEvent( VController::eControllerEventType pEvent ) 139{ 140 if ( !getController() ) 141 { 142 AssertFatal( false, "VTrack::onControllerEvent() - Invalid Controller." ); 143 return false; 144 } 145 146 // Enabled? 147 if ( !isEnabled() ) 148 { 149 // Continue Processing Events. 150 return true; 151 } 152 153 switch( pEvent ) 154 { 155 case VController::k_EventReset : 156 { 157 158 // Reset. 159 onControllerReset( getControllerTime(), isControllerPlayingForward() ); 160 161 } break; 162 } 163 164 // Continue Processing Events. 165 return true; 166} 167 168//----------------------------------------------------------------------------- 169// 170// VTrack::onControllerReset( pTime, pForward ); 171// 172// Reset the status of the track. The Next Event is allocated here. 173// 174//----------------------------------------------------------------------------- 175void VTrack::onControllerReset( const S32 &pTime, const bool &pForward ) 176{ 177 // Clear Next Event. 178 mNextEvent = NULL; 179 180 for ( ITreeNode *node = mChildNode; node != NULL; node = node->mSiblingNextNode ) 181 { 182 VEvent *event = ( VEvent* )node; 183 184 // Reset Event. 185 event->onControllerReset( pTime, pForward ); 186 187 if ( ( event->isPlaying() ) 188 || ( pForward && event->getTriggerTime() >= pTime ) ) 189 { 190 if ( !mNextEvent ) 191 { 192 // Use as Next Event. 193 mNextEvent = event; 194 } 195 } 196 else if ( !pForward && pTime >= event->getTriggerTime() ) 197 { 198 VEvent *nextEvent = ( VEvent* )node->mSiblingNextNode; 199 if ( !nextEvent || pTime < nextEvent->getTriggerTime() ) 200 { 201 // Use as Next Event. 202 mNextEvent = event; 203 } 204 } 205 } 206} 207 208//----------------------------------------------------------------------------- 209// 210// Reference Methods. 211// 212//----------------------------------------------------------------------------- 213 214//----------------------------------------------------------------------------- 215// 216// VTrack::sort(); 217// 218// Sort the track's events by the event's trigger time. 219// 220//----------------------------------------------------------------------------- 221void VTrack::sort( void ) 222{ 223 const S32 count = size(); 224 for ( S32 j = 0; j < count; j++ ) 225 { 226 for ( ITreeNode *node = mChildNode; node != NULL; node = node->mSiblingNextNode ) 227 { 228 VEvent *eventA = ( VEvent* )node; 229 VEvent *eventB = ( VEvent* )node->mSiblingNextNode; 230 if ( !eventB ) 231 { 232 // No Node. 233 break; 234 } 235 236 // Swap? 237 if ( eventA->getTriggerTime() > eventB->getTriggerTime() ) 238 { 239 // Get Outer Siblings. 240 ITreeNode *prevNode = eventA->mSiblingPrevNode; 241 ITreeNode *nextNode = eventB->mSiblingNextNode; 242 243 if ( eventA->mParentNode && eventA->mParentNode->mChildNode == eventA ) 244 { 245 // New Child Node. 246 eventA->mParentNode->mChildNode = eventB; 247 } 248 249 // 250 // Move A. 251 eventA->mSiblingPrevNode = eventB; 252 eventA->mSiblingNextNode = nextNode; 253 254 if ( nextNode ) 255 { 256 // Update Outer Sibling. 257 nextNode->mSiblingPrevNode = eventA; 258 } 259 260 // 261 // Move B. 262 263 eventB->mSiblingPrevNode = prevNode; 264 eventB->mSiblingNextNode = eventA; 265 266 if ( prevNode ) 267 { 268 // Update Outer Sibling. 269 prevNode->mSiblingNextNode = eventB; 270 } 271 } 272 } 273 } 274} 275 276//----------------------------------------------------------------------------- 277// 278// VTrack::updateNextEvent( pForward ); 279// 280// Point mNextEvent to the next valid event in the track's sequence. 281// 282//----------------------------------------------------------------------------- 283bool VTrack::updateNextEvent( void ) 284{ 285 if ( !mNextEvent ) 286 { 287 // Invalid Event. 288 return false; 289 } 290 291 while ( ( mNextEvent = mNextEvent->getNextEvent() ) != NULL ) 292 { 293 if ( mNextEvent->isEnabled() ) 294 { 295 // Valid Event. 296 return true; 297 } 298 } 299 300 // Invalid Event. 301 return false; 302} 303 304//----------------------------------------------------------------------------- 305// 306// Property Methods. 307// 308//----------------------------------------------------------------------------- 309 310//----------------------------------------------------------------------------- 311// 312// VTrack::getGroup(); 313// 314// Returns the Track's parent group. 315// 316//----------------------------------------------------------------------------- 317VGroup *VTrack::getGroup( void ) 318{ 319 return dynamic_cast<VGroup*>( mParentNode ); 320} 321 322//----------------------------------------------------------------------------- 323// 324// VTrack::getNextEvent(); 325// 326// Returns the Event that the Track is currently observing. 327// 328//----------------------------------------------------------------------------- 329VEvent *VTrack::getNextEvent( void ) 330{ 331 return mNextEvent; 332} 333 334//----------------------------------------------------------------------------- 335// 336// VTrack::getCurrentEvent(); 337// 338// Returns the Event that the Track is currently observing and playing. This 339// will only ever be non-null when the track is observing an Event that has a 340// non-zero duration and has been triggered. 341// 342//----------------------------------------------------------------------------- 343VEvent *VTrack::getCurrentEvent( void ) 344{ 345 if ( mNextEvent && mNextEvent->isPlaying() ) 346 { 347 return mNextEvent; 348 } 349 350 return NULL; 351} 352 353//----------------------------------------------------------------------------- 354// 355// VTrack::getPreviousEvent(); 356// 357// Returns the Event that the Track was last intergrating. 358// 359//----------------------------------------------------------------------------- 360VEvent *VTrack::getPreviousEvent( void ) 361{ 362 if ( mNextEvent ) 363 { 364 return mNextEvent->getPreviousEvent(); 365 } 366 367 if ( !isControllerPlayingForward() ) 368 { 369 return dynamic_cast<VEvent*>( getChild() ); 370 } 371 372 return dynamic_cast<VEvent*>( getLastChild() ); 373} 374 375//----------------------------------------------------------------------------- 376// 377// VTrack::calclateInterp( pTime ); 378// 379// This method returns the interp time between or within events. If the given 380// time is between two events, the return time is: 381// 382// ( pTime - last_event_finish_time ) 383// / ( next_event_start_time - last_event_finish_time ) 384// 385// If the given time is within an event, the return time is: 386// 387// ( pTime - event_start_time ) / ( event_duration ) 388// 389// The value returned here is between 0.0 and 1.0. 390// 391//----------------------------------------------------------------------------- 392F32 VTrack::calculateInterp( S32 pTime ) 393{ 394 if ( !isControllerPlayingForward() ) 395 { 396 return ( 1.f - _calculateInterp( pTime ) ); 397 } 398 399 return _calculateInterp( pTime ); 400} 401 402F32 VTrack::_calculateInterp( S32 pTime ) 403{ 404 // Fetch Duration. 405 const S32 sequenceDuration = getControllerDuration(); 406 if ( sequenceDuration == 0 || pTime == sequenceDuration ) 407 { 408 // Sanity! 409 return 1.f; 410 } 411 412 if ( !mChildNode ) 413 { 414 // Quick Interp. 415 return F32( pTime / sequenceDuration ); 416 } 417 418 // Last Time. 419 S32 lastTime = 0; 420 421 VEvent *walk = ( VEvent* )mChildNode; 422 while ( walk ) 423 { 424 const S32 startTime = walk->getStartTime(); 425 const S32 finishTime = walk->getFinishTime(); 426 427 if ( pTime < startTime ) 428 { 429 return ( F32( pTime - lastTime ) / F32( startTime - lastTime ) ); 430 } 431 432 // Update Last Time. 433 lastTime = startTime; 434 435 if ( pTime < finishTime ) 436 { 437 return ( F32( pTime - lastTime ) / F32( finishTime - lastTime ) ); 438 } 439 440 // Update Last Time. 441 lastTime = finishTime; 442 443 // Fetch Next Node. 444 walk = ( VEvent* )walk->mSiblingNextNode; 445 } 446 447 // Return. 448 return ( F32( pTime - lastTime ) / F32( sequenceDuration - lastTime ) ); 449} 450