void CMPTrackViewManager::Client_SynchAnimationTimes(const CGameRules::STrackViewParameters& params) { IMovieSystem *pMovieSystem = gEnv->pMovieSystem; int numTrackViews = params.m_NumberOfTrackViews + params.m_NumberOfFinishedTrackViews; CryLog("CMPTrackViewManager::Client_SynchAnimationTimes() numTrackViews=%d; numFinishedTrackViews=%d", params.m_NumberOfTrackViews, params.m_NumberOfFinishedTrackViews); for(int i = 0; i < numTrackViews; ++i) { int trackviewHashId = params.m_Ids[i]; if(trackviewHashId == 0) continue; for(int k = 0; k < pMovieSystem->GetNumSequences(); ++k) { IAnimSequence* pSequence = pMovieSystem->GetSequence(k); CryHashStringId id(pSequence->GetName()); if(id == trackviewHashId) { float timeValue = params.m_Times[i]; // even finished sequences include their time now, to handle aborted sequences float currentTimeValue = pMovieSystem->GetPlayingTime(pSequence); CryLog("CMPTrackViewManager::Client_SynchAnimationTimes() Sequence %d %s at time %f", i, pSequence->GetName(), timeValue); if(pMovieSystem->IsPlaying(pSequence)) { // always update finished anims if( i>=params.m_NumberOfTrackViews || fabs(currentTimeValue - timeValue) > s_TrackViewMinTimeDifferenceForSynch) //If we are close enough don't update - avoid unnecessary jerking { pMovieSystem->SetPlayingTime(pSequence, timeValue); } } else { pMovieSystem->PlaySequence(pSequence, NULL, true, false, timeValue); if(params.m_bInitialData && i>=params.m_NumberOfTrackViews && m_FinishedTrackViewCount < CGameRules::STrackViewParameters::sMaxTrackViews) { m_FinishedTrackViews[m_FinishedTrackViewCount++] = id.id; } } if (i>=params.m_NumberOfTrackViews) { // this is a finished trackview, so having setup the correct playtime above, lets actually stop it like it should be CryLog("CMPTrackViewManager::Client_SynchAnimationTimes() Sequence %d %s is a finished trackview, stopping it", i, pSequence->GetName()); pMovieSystem->StopSequence(pSequence); } } } } }
void CMPTrackViewManager::Update() { #ifndef _RELEASE if (g_pGameCVars->g_mptrackview_debug) { IMovieSystem *pMovieSystem = gEnv->pMovieSystem; int numSequences=pMovieSystem->GetNumSequences(); CryWatch("num finished trackviews=%d", m_FinishedTrackViewCount); for (int i=0; i<m_FinishedTrackViewCount; i++) { const char *foundName="NOT FOUND"; // SLOW IAnimSequence *foundSequence = FindTrackviewSequence(m_FinishedTrackViews[i]); if (foundSequence) { foundName = foundSequence->GetName(); } CryWatch("finished[%d] hash=%x; time=%f; foundName=%s", i, m_FinishedTrackViews[i], m_FinishedTrackViewTimes[i], foundName); } int numPlaying=pMovieSystem->GetNumPlayingSequences(); for(int i = 0; i < numPlaying; ++i) { IAnimSequence* pSequence = pMovieSystem->GetPlayingSequence(i); if( pSequence ) { const char *name=pSequence->GetName(); if (!name) { name = "[NULL]"; } CryHashStringId hash_id(pSequence->GetName()); float timeValue = pMovieSystem->GetPlayingTime(pSequence); CryWatch("Seq[%d]: name=%s; time=%f; hash=%x", i, name, timeValue, hash_id.id); } } } #endif }
void CMPTrackViewManager::Server_SynchAnimationTimes(CGameRules::STrackViewParameters& params) { IMovieSystem *pMovieSystem = gEnv->pMovieSystem; int count = 0; IAnimSequence* pSequence = NULL; CryLog("CMPTrackViewManager::Server_SynchAnimationTimes()"); for(int i = 0; i < CGameRules::STrackViewParameters::sMaxTrackViews; ++i) { if(i < pMovieSystem->GetNumPlayingSequences()) pSequence = pMovieSystem->GetPlayingSequence(i); else pSequence = NULL; if( pSequence ) { if (pSequence->GetFlags() & IAnimSequence::NO_MP_SYNCING_NEEDED) { CryLog("CMPTrackViewManager::Server_SynchAnimationTimes() skipping syncing of playing anim sequence %s (%s) as it has NO_MP_SYNCING_NEEDED flag set", pSequence->GetName(), pSequence->GetFullName()); continue; } CryHashStringId id(pSequence->GetName()); params.m_Ids[i] = id.id; float timeValue = pMovieSystem->GetPlayingTime(pSequence); params.m_Times[i] = timeValue; CryLog("CMPTrackViewManager::Server_SynchAnimationTimes() adding playing sequence %d %s at time %f", i, pSequence->GetName(), timeValue); ++count; } else { #ifndef _RELEASE if(count + m_FinishedTrackViewCount > CGameRules::STrackViewParameters::sMaxTrackViews) { CryWarning(VALIDATOR_MODULE_NETWORK, VALIDATOR_WARNING, "Trying to synch %i animations but system set to %i in GameRules.h", count + m_FinishedTrackViewCount, CGameRules::STrackViewParameters::sMaxTrackViews); } #endif params.m_NumberOfFinishedTrackViews = m_FinishedTrackViewCount; for(int j = 0; j < m_FinishedTrackViewCount && i < CGameRules::STrackViewParameters::sMaxTrackViews; ++j, ++i) { params.m_Ids[i] = m_FinishedTrackViews[j]; params.m_Times[i] = m_FinishedTrackViewTimes[j]; #ifndef _RELEASE IAnimSequence *pTrackviewSequence = FindTrackviewSequence(m_FinishedTrackViews[j]); CryLog("CMPTrackViewManager::Server_SynchAnimationTimes() adding finished sequence %d %s at time %f", i, pTrackviewSequence ? pTrackviewSequence->GetName() : "NULL", m_FinishedTrackViewTimes[j]); #endif } break; } } params.m_NumberOfTrackViews = count; params.m_bInitialData = true; }
void CMPTrackViewManager::OnMovieEvent(IMovieListener::EMovieEvent movieEvent, IAnimSequence* pAnimSequence) { switch(movieEvent) { case IMovieListener::MOVIE_EVENT_START: { if (pAnimSequence->GetFlags() & IAnimSequence::NO_MP_SYNCING_NEEDED) { CryLog("CMPTrackViewManager::OnMovieEvent MOVIE_EVENT_START() Skipping twelling clients about anim that does not need to be synced"); return; } IMovieSystem *pMovieSystem = gEnv->pMovieSystem; CryHashStringId sequenceId(pAnimSequence->GetName()); CGameRules::STrackViewParameters params; params.m_NumberOfTrackViews = 1; params.m_Ids[0] = sequenceId.id; params.m_Times[0] = pMovieSystem->GetPlayingTime(pAnimSequence); g_pGame->GetGameRules()->GetGameObject()->InvokeRMIWithDependentObject(CGameRules::ClTrackViewSynchAnimations(), params, eRMI_ToRemoteClients, 0); //Need to remove from finished list if present for(int i = 0; i < m_FinishedTrackViewCount; ++i) { if(sequenceId == m_FinishedTrackViews[i]) { if(i != m_FinishedTrackViewCount-1) //If not at end swap element with end element { m_FinishedTrackViews[i] = m_FinishedTrackViews[m_FinishedTrackViewCount-1]; m_FinishedTrackViewTimes[i] = m_FinishedTrackViewTimes[m_FinishedTrackViewCount-1]; } --m_FinishedTrackViewCount; } } } break; case IMovieListener::MOVIE_EVENT_STOP: case IMovieListener::MOVIE_EVENT_ABORTED: { if (pAnimSequence->GetFlags() & IAnimSequence::NO_MP_SYNCING_NEEDED) { CryLog("CMPTrackViewManager::Server_SynchAnimationTimes() skipping remembering of a completed playing anim sequence %s (%s) in the finishedTrackviews as it has NO_MP_SYNCING_NEEDED flag set", pAnimSequence->GetName(), pAnimSequence->GetFullName()); return; } //If a movie finishes we should store this fact so we can tell clients that join later that the animation has already been played IMovieSystem *pMovieSystem = gEnv->pMovieSystem; CryHashStringId sequenceId(pAnimSequence->GetName()); float timeValue = pMovieSystem->GetPlayingTime(pAnimSequence); // aborted movies will not be at the end, send the stopped movies endtime to save the client from playing to figure out its length if(m_FinishedTrackViewCount < CGameRules::STrackViewParameters::sMaxTrackViews) { m_FinishedTrackViews[m_FinishedTrackViewCount] = sequenceId.id; m_FinishedTrackViewTimes[m_FinishedTrackViewCount] = timeValue; m_FinishedTrackViewCount++; } #ifndef _RELEASE else { CryWarning(VALIDATOR_MODULE_NETWORK, VALIDATOR_WARNING, "Trying to store that animation %s is finished, but the array is full so ignoring", pAnimSequence->GetName()); } #endif CGameRules::STrackViewParameters params; params.m_NumberOfTrackViews = 0; params.m_NumberOfFinishedTrackViews = 1; params.m_Ids[0] = sequenceId.id; params.m_Times[0] = timeValue; g_pGame->GetGameRules()->GetGameObject()->InvokeRMIWithDependentObject(CGameRules::ClTrackViewSynchAnimations(), params, eRMI_ToRemoteClients, 0); } break; } }