//----------------------------------------------------------------------------- // Purpose: // Assignment // Input : src - //----------------------------------------------------------------------------- CChoreoChannel& CChoreoChannel::operator=( const CChoreoChannel& src ) { m_bActive = src.m_bActive; Q_strncpy( m_szName, src.m_szName, sizeof( m_szName ) ); for ( int i = 0; i < src.m_Events.Count(); i++ ) { CChoreoEvent *e = src.m_Events[ i ]; CChoreoEvent *newEvent = new CChoreoEvent( e->GetScene() ); *newEvent = *e; AddEvent( newEvent ); newEvent->SetChannel( this ); newEvent->SetActor( m_pActor ); } return *this; }
void CChoreoChannel::ReconcileGestureTimes() { // Sort gesture events within channel by starting time CUtlRBTree< CChoreoEvent * > sortedGestures( 0, 0, ChoreEventStartTimeLessFunc ); int i; // Sort items int c = GetNumEvents(); for ( i = 0; i < c; i++ ) { CChoreoEvent *e = GetEvent( i ); Assert( e ); if ( e->GetType() != CChoreoEvent::GESTURE ) continue; sortedGestures.Insert( e ); } // Now walk list of gestures if ( !sortedGestures.Count() ) return; CChoreoEvent *previous = NULL; for ( i = sortedGestures.FirstInorder(); i != sortedGestures.InvalidIndex(); i = sortedGestures.NextInorder( i ) ) { CChoreoEvent *event = sortedGestures[ i ]; if ( !previous ) { // event->SetStartTime( 0.0f ); } else if ( previous->GetSyncToFollowingGesture() ) { // TODO: ask the sequence for what tags to match CEventAbsoluteTag *pEntryTag = event->FindEntryTag( CChoreoEvent::PLAYBACK ); CEventAbsoluteTag *pExitTag = previous->FindExitTag( CChoreoEvent::PLAYBACK ); if (pEntryTag && pExitTag) { float entryTime = pEntryTag->GetAbsoluteTime( ); // get current decay rate of previous gesture float duration = previous->GetDuration(); float decayTime = (1.0 - pExitTag->GetPercentage()) * duration; // adjust the previous gestures end time to current apex + existing decay rate previous->RescaleGestureTimes( previous->GetStartTime(), entryTime + decayTime, true ); previous->SetEndTime( entryTime + decayTime ); // set the previous gestures end tag to the current apex pExitTag->SetAbsoluteTime( entryTime ); event->PreventTagOverlap( ); previous->PreventTagOverlap( ); } // BUG: Tracker 3298: ywb 1/31/04 // I think this fixes the issue with abutting past NULL gestures on paste: // Here's the bug report: // ------------------------- // When copying and pasteing posture and gesture clips in face poser the beginings of the clips stretch // to the begining of the scene even if there is a null gesture in place at the begining. // ------------------------- /* else if ( pEntryTag && !Q_stricmp( previous->GetName(), "NULL" ) ) { // If the previous was a null event, then do a bit of fixup event->SetStartTime( previous->GetEndTime() ); event->PreventTagOverlap( ); } */ // The previous event decays from it's end dispaly end time to the current event's display start time // The next event starts just after the display end time of the previous event } previous = event; } if ( previous ) { CChoreoScene *scene = previous->GetScene(); if ( scene ) { // HACK: Could probably do better by allowing user to drag the blue "end time" bar //float finish = scene->FindStopTime(); //previous->RescaleGestureTimes( previous->GetStartTime(), finish ); //previous->SetEndTime( finish ); } } /* c = 0; for ( i = sortedGestures.FirstInorder(); i != sortedGestures.InvalidIndex(); i = sortedGestures.NextInorder( i ) ) { CChoreoEvent *event = sortedGestures[ i ]; Msg( "event %i start %f disp %f dispend %f end %f\n", c + 1, event->GetStartTime( CChoreoEvent::SIMULATION ), event->GetStartTime( CChoreoEvent::DISPLAY ), event->GetEndTime( CChoreoEvent::DISPLAY ), event->GetEndTime( CChoreoEvent::SIMULATION ) ); c++; } */ }