void CActionScope::FillBlendQuery(SBlendQuery &query, FragmentID fragID, const SFragTagState &fragTagState, bool isHigherPriority, float *pLoopDuration) const { query.fragmentFrom = m_lastFragmentID; query.fragmentTo = fragID; query.fragmentTime = m_fragmentTime; query.tagStateFrom = m_lastQueueTagState; query.tagStateTo.globalTags = m_context.controllerDef.m_tags.GetUnion(fragTagState.globalTags, m_additionalTags); query.tagStateTo.fragmentTags = fragTagState.fragmentTags; query.additionalTags = m_additionalTags; query.prevNormalisedTime = m_lastNormalisedTime; query.normalisedTime = m_normalisedTime; query.SetFlag(SBlendQuery::higherPriority, isHigherPriority); query.SetFlag(SBlendQuery::fromInstalled, m_fragmentInstalled); query.SetFlag(SBlendQuery::toInstalled, true); query.SetFlag(SBlendQuery::noTransitions, m_actionController.GetFlag(AC_NoTransitions)); const CAnimation *pAnim = GetTopAnim(0); if (pAnim) { if (pLoopDuration) { *pLoopDuration = pAnim->GetCurrentSegmentExpectedDurationSeconds(); } } }
bool CActionScope::QueueFragment(FragmentID fragID, const SFragTagState &fragTagState, uint32 optionIdx, float startTime, uint32 userToken, bool isRootScope, bool isHigherPriority, bool principleContext) { if (m_scopeContext.database == NULL) { return false; } SBlendQuery query; FillBlendQuery(query, fragID, fragTagState, isHigherPriority, NULL); query.SetFlag(SBlendQuery::toInstalled, principleContext); SFragmentData fragData; IAnimationSet* pAnimSet = m_scopeContext.charInst ? m_scopeContext.charInst->GetIAnimationSet() : NULL; m_sequenceFlags = m_scopeContext.database->Query(fragData, query, optionIdx, pAnimSet, &m_lastFragSelection); m_lastQueueTagState = query.tagStateTo; m_lastNormalisedTime = m_normalisedTime = 0.0f; m_isOneShot = fragData.isOneShot && ((fragID == FRAGMENT_ID_INVALID) || ((m_context.controllerDef.GetFragmentDef(fragID).flags & SFragmentDef::PERSISTENT) == 0)); m_fragmentInstalled = principleContext; const bool fragmentInstalled = HasFragment(); #ifndef _RELEASE if (m_actionController.DebugFragments(isRootScope)) { char tagList[128] = "No Match"; char fragTagList[128] = ""; if (HasFragment()) { m_context.controllerDef.m_tags.FlagsToTagList(m_lastFragSelection.tagState.globalTags, tagList, 128); const CTagDefinition *pFragTagDef = m_context.controllerDef.GetFragmentTagDef(fragID); if (pFragTagDef) { pFragTagDef->FlagsToTagList(m_lastFragSelection.tagState.fragmentTags, fragTagList, 128); } } const int frameId = gEnv->pRenderer->GetFrameID(false); CryLog("[%6d] Fragment %s (%s,%s) queued on scope %s for action %s", frameId, fragID != FRAGMENT_ID_INVALID ? m_context.controllerDef.m_fragmentIDs.GetTagName(fragID) : "None", tagList, fragTagList, m_name.c_str(), m_pAction ? m_pAction->GetName() : "None"); } #endif //_RELEASE m_fragmentDuration = m_transitionOutroDuration = m_transitionDuration = 0.0f; for (uint32 i=0; i<SFragmentData::PART_TOTAL; i++) { m_partTypes[i] = fragData.transitionType[i]; switch (fragData.transitionType[i]) { case eCT_Normal: m_fragmentDuration += fragData.duration[i]; break; case eCT_Transition: m_transitionDuration += fragData.duration[i]; break; case eCT_TransitionOutro: m_transitionOutroDuration += fragData.duration[i]; break; } } if (!isRootScope) { if ((m_sequenceFlags & (eCT_Transition|eCT_TransitionOutro)) != 0) { startTime = 0.0f; } else { startTime = max(startTime - (m_transitionOutroDuration + m_transitionDuration), 0.0f); } } m_lastFragmentID = fragID; m_fragmentTime = -startTime; const uint32 numAnimLayers = fragData.animLayers.size(); const uint32 numScopeLayers = m_numLayers; const uint32 numLayers = min(numAnimLayers, numScopeLayers); CRY_ASSERT_MESSAGE(numLayers <= m_numLayers, "Invalid layer count"); m_userToken = userToken; uint32 nLayer = 0; for (nLayer=0; nLayer<numLayers; nLayer++) { const bool hasClips = fragData.animLayers[nLayer].size() > 0; SSequencer &sequencer = m_layerSequencers[nLayer]; sequencer.pos = 0; sequencer.referenceTime = -1.0f; if (hasClips) { sequencer.sequence = fragData.animLayers[nLayer]; sequencer.blend = sequencer.sequence[0].blend; sequencer.installTime = startTime + sequencer.blend.exitTime; sequencer.flags = eSF_Queued; } else { sequencer.sequence.resize(0); sequencer.blend = SAnimBlend(); sequencer.installTime = startTime; sequencer.flags = eSF_Queued|eSF_BlendingOut; } } for ( ; nLayer < numScopeLayers; nLayer++) { //--- Layers that are not touched by the new fragment blend out using default blends SSequencer &sequencer = m_layerSequencers[nLayer]; sequencer.sequence.resize(0); sequencer.pos = 0; sequencer.blend = SAnimBlend(); sequencer.installTime = startTime; sequencer.flags = eSF_Queued|eSF_BlendingOut; } const size_t numProcSequencers = fragData.procLayers.size(); const size_t totNumProcSequencers = max(numProcSequencers, m_procSequencers.size()); m_procSequencers.resize(totNumProcSequencers); for (nLayer=0; nLayer<numProcSequencers; nLayer++) { const bool hasClips = fragData.procLayers[nLayer].size() > 0; SProcSequencer &sequencerPush = m_procSequencers[nLayer]; sequencerPush.pos = 0; if (hasClips) { sequencerPush.sequence = fragData.procLayers[nLayer]; const float layerBlendTime = sequencerPush.sequence[0].blend.exitTime; sequencerPush.installTime = startTime; sequencerPush.blend = sequencerPush.sequence[0].blend; sequencerPush.flags = eSF_Queued; if (layerBlendTime > 0.0f) { sequencerPush.blend = SAnimBlend(); sequencerPush.flags |= eSF_BlendingOut; } } else { sequencerPush.sequence.resize(0); sequencerPush.blend = SAnimBlend(); sequencerPush.installTime = startTime; sequencerPush.flags = eSF_Queued|eSF_BlendingOut; } } for ( ; nLayer < totNumProcSequencers; nLayer++) { SProcSequencer &sequencerPush = m_procSequencers[nLayer]; sequencerPush.sequence.resize(0); sequencerPush.pos = 0; sequencerPush.blend = SAnimBlend(); sequencerPush.installTime = startTime; sequencerPush.flags = eSF_Queued|eSF_BlendingOut; } return fragmentInstalled; }
bool CActionScope::QueueFragment(FragmentID fragID, const SFragTagState &fragTagState, uint32 optionIdx, float startTime, uint32 userToken, bool isRootScope, bool isHigherPriority, bool principleContext) { if (m_scopeContext.pDatabase == NULL) { return false; } SBlendQuery query; FillBlendQuery(query, fragID, fragTagState, isHigherPriority, NULL); query.SetFlag(SBlendQuery::toInstalled, principleContext); SFragmentData fragData; IAnimationSet* pAnimSet = m_scopeContext.pCharInst ? m_scopeContext.pCharInst->GetIAnimationSet() : NULL; m_sequenceFlags = m_scopeContext.pDatabase->Query(fragData, query, optionIdx, pAnimSet, &m_lastFragSelection); m_lastQueueTagState = query.tagStateTo; m_lastNormalisedTime = m_normalisedTime = 0.0f; m_isOneShot = fragData.isOneShot && ((fragID == FRAGMENT_ID_INVALID) || ((m_context.controllerDef.GetFragmentDef(fragID).flags & SFragmentDef::PERSISTENT) == 0)); m_blendOutDuration = fragData.blendOutDuration; m_fragmentInstalled = principleContext; const bool fragmentInstalled = HasFragment(); #if MANNEQUIN_DEBUGGING_ENABLED CryStackStringT<char,128> sTagList = "No Match"; CryStackStringT<char,128> sFragTagList; if (!fragmentInstalled && (m_layer == 0) && (m_numLayers > 0)) { const char* fragmentName = fragID != FRAGMENT_ID_INVALID ? m_context.controllerDef.m_fragmentIDs.GetTagName(fragID) : "None"; m_context.controllerDef.m_tags.FlagsToTagList(fragTagState.globalTags, sTagList); const CTagDefinition* pFragTagDef = (fragID != FRAGMENT_ID_INVALID) ? m_context.controllerDef.GetFragmentTagDef(fragID) : NULL; if (pFragTagDef) { pFragTagDef->FlagsToTagList(fragTagState.fragmentTags, sFragTagList); } MannLog(GetActionController(), "Warning - Missing root level fragment %s(%s)", fragmentName, sTagList.c_str()); } if (m_actionController.DebugFragments(principleContext) && fragmentInstalled) { if (HasFragment()) { m_context.controllerDef.m_tags.FlagsToTagList(m_lastFragSelection.tagState.globalTags, sTagList); const CTagDefinition* pFragTagDef = m_context.controllerDef.GetFragmentTagDef(fragID); if (pFragTagDef) { pFragTagDef->FlagsToTagList(m_lastFragSelection.tagState.fragmentTags, sFragTagList); } } const char* fragmentName = fragID != FRAGMENT_ID_INVALID ? m_context.controllerDef.m_fragmentIDs.GetTagName(fragID) : "None"; const char* prevFragmentName = query.fragmentFrom != FRAGMENT_ID_INVALID ? m_context.controllerDef.m_fragmentIDs.GetTagName(query.fragmentFrom) : "None"; MannLog(GetActionController(), "Frag %s (%s,%s) queued on %s for action %s", fragmentName, sTagList.c_str(), sFragTagList.c_str(), m_name.c_str(), m_pAction ? m_pAction->GetName() : "None"); CryStackStringT<char,128> sTagStateFrom; CryStackStringT<char,128> sTagStateTo; SBlendQueryResult queryRes1, queryRes2; m_scopeContext.pDatabase->FindBestBlends(query, queryRes1, queryRes2); if (queryRes1.pFragmentBlend) { MannLog(GetActionController(), "Transition from (%s -> %s) %s", (queryRes1.fragmentFrom != FRAGMENT_ID_INVALID) ? prevFragmentName : "Any", (queryRes1.fragmentTo != FRAGMENT_ID_INVALID) ? fragmentName : "Any", queryRes1.pFragmentBlend->IsExitTransition() ? "Exit" : ""); m_actionController.GetContext().controllerDef.m_tags.FlagsToTagList(queryRes1.tagStateFrom.globalTags, sTagStateFrom); m_actionController.GetContext().controllerDef.m_tags.FlagsToTagList(queryRes1.tagStateTo.globalTags, sTagStateTo); MannLog(GetActionController(), "Transition tags (%s -> %s)", sTagStateFrom.c_str(), sTagStateTo.c_str()); } if (queryRes2.pFragmentBlend) { MannLog(GetActionController(), "And Transition from (%s -> %s) %s", (queryRes2.fragmentFrom != FRAGMENT_ID_INVALID) ? prevFragmentName : "Any", (queryRes2.fragmentTo != FRAGMENT_ID_INVALID) ? fragmentName : "Any", queryRes2.pFragmentBlend->IsExitTransition() ? "Exit" : ""); m_actionController.GetContext().controllerDef.m_tags.FlagsToTagList(queryRes2.tagStateFrom.globalTags, sTagStateFrom); m_actionController.GetContext().controllerDef.m_tags.FlagsToTagList(queryRes2.tagStateTo.globalTags, sTagStateTo); MannLog(GetActionController(), "Transition tags (%s -> %s)", sTagStateFrom.c_str(), sTagStateTo.c_str()); } } #endif //MANNEQUIN_DEBUGGING_ENABLED m_fragmentDuration = m_transitionOutroDuration = m_transitionDuration = 0.0f; for (uint32 i = 0; i < SFragmentData::PART_TOTAL; i++) { m_partTypes[i] = fragData.transitionType[i]; switch (fragData.transitionType[i]) { case eCT_Normal: m_fragmentDuration += fragData.duration[i]; break; case eCT_Transition: m_transitionDuration += fragData.duration[i]; break; case eCT_TransitionOutro: m_transitionOutroDuration += fragData.duration[i]; break; } } if (!isRootScope) { if (m_sequenceFlags & (eSF_Transition | eSF_TransitionOutro)) { startTime = 0.0f; } else { startTime = max(startTime - (m_transitionOutroDuration + m_transitionDuration), 0.0f); } } m_lastFragmentID = fragID; m_fragmentTime = -startTime; const uint32 numAnimLayers = fragData.animLayers.size(); const uint32 numScopeLayers = m_numLayers; const uint32 numLayers = min(numAnimLayers, numScopeLayers); CRY_ASSERT_MESSAGE(numLayers <= m_numLayers, "Invalid layer count"); m_userToken = userToken; uint32 nLayer = 0; for (nLayer = 0; nLayer < numLayers; nLayer++) { const bool hasClips = fragData.animLayers[nLayer].size() > 0; SSequencer &sequencer = m_layerSequencers[nLayer]; sequencer.pos = 0; sequencer.referenceTime = -1.0f; if (hasClips) { sequencer.sequence = fragData.animLayers[nLayer]; sequencer.blend = sequencer.sequence[0].blend; sequencer.installTime = startTime + sequencer.blend.exitTime; sequencer.flags = eSF_Queued; } else { sequencer.sequence.resize(0); sequencer.blend = SAnimBlend(); sequencer.installTime = startTime; sequencer.flags = eSF_Queued | eSF_BlendingOut; } } for (; nLayer < numScopeLayers; nLayer++) { //--- Layers that are not touched by the new fragment blend out using default blends SSequencer &sequencer = m_layerSequencers[nLayer]; sequencer.sequence.resize(0); sequencer.pos = 0; sequencer.blend = SAnimBlend(); sequencer.installTime = startTime; sequencer.flags = eSF_Queued | eSF_BlendingOut; } const size_t numProcSequencers = fragData.procLayers.size(); const size_t totNumProcSequencers = max(numProcSequencers, m_procSequencers.size()); m_procSequencers.resize(totNumProcSequencers); for (nLayer = 0; nLayer < numProcSequencers; nLayer++) { const bool hasClips = fragData.procLayers[nLayer].size() > 0; SProcSequencer &sequencerPush = m_procSequencers[nLayer]; sequencerPush.pos = 0; if (hasClips) { sequencerPush.sequence = fragData.procLayers[nLayer]; const float layerBlendTime = sequencerPush.sequence[0].blend.exitTime; sequencerPush.installTime = startTime; sequencerPush.blend = sequencerPush.sequence[0].blend; sequencerPush.flags = eSF_Queued; if (layerBlendTime > 0.0f) { sequencerPush.blend = SAnimBlend(); sequencerPush.flags |= eSF_BlendingOut; } } else { sequencerPush.sequence.resize(0); sequencerPush.blend = SAnimBlend(); sequencerPush.installTime = startTime; sequencerPush.flags = eSF_Queued | eSF_BlendingOut; } } for (; nLayer < totNumProcSequencers; nLayer++) { SProcSequencer &sequencerPush = m_procSequencers[nLayer]; sequencerPush.sequence.resize(0); sequencerPush.pos = 0; sequencerPush.blend = SAnimBlend(); sequencerPush.installTime = startTime; sequencerPush.flags = eSF_Queued | eSF_BlendingOut; } return fragmentInstalled; }