示例#1
0
bool CActionScope::CanInstall(EPriorityComparison priorityComp, FragmentID fragID, const SFragTagState &fragTagState, bool isRequeue, float &timeRemaining) const
{
    IAction* const pCompareAction = m_pAction ? m_pAction.get() : m_pExitingAction.get();
    if (isRequeue || (pCompareAction && pCompareAction->CanBlendOut(priorityComp)) || (!pCompareAction))
    {
        const float totalDuration = m_fragmentDuration + m_transitionDuration + m_transitionOutroDuration;

        if ((priorityComp == Higher)
                || !pCompareAction
                || (pCompareAction->m_eStatus == IAction::Finished)
                || (pCompareAction->m_eStatus == IAction::Exiting))
        {
            timeRemaining = 0.0f;
        }
        else if (m_fragmentTime <= 0.0f)
        {
            return false;
        }
        else if (m_scopeContext.database == NULL)
        {
            timeRemaining = totalDuration - m_fragmentTime;
        }
        else
        {
            SBlendQuery query;
            float loopDuration;
            FillBlendQuery(query, fragID, fragTagState, false, &loopDuration);

            SBlendQueryResult queryRes1, queryRes2;
            m_scopeContext.database->FindBestBlends(query, queryRes1, queryRes2);
            if (queryRes1.pFragmentBlend)
            {
                float startTime	= queryRes1.pFragmentBlend->startTime;

                if (queryRes1.pFragmentBlend->flags & SFragmentBlend::Cyclic)
                {
                    if (queryRes1.pFragmentBlend->flags & SFragmentBlend::CycleLocked)
                    {
                        float cycleDiff = startTime - m_normalisedTime;
                        if ((m_lastNormalisedTime < startTime) || (m_lastNormalisedTime > m_normalisedTime))
                        {
                            cycleDiff = max(cycleDiff, 0.0f);
                        }
                        else
                        {
                            cycleDiff = (float)__fsel(cycleDiff, cycleDiff, 1.0f + cycleDiff);
                        }

                        timeRemaining = loopDuration * cycleDiff;
                    }
                    else
                    {
                        timeRemaining = 0.0f;
                    }
                }
                else
                {
                    timeRemaining = CalculateFragmentTimeRemaining() + startTime;
                }
            }
            else
            {
                timeRemaining = CalculateFragmentTimeRemaining();
            }
        }

        if (pCompareAction)
        {
            pCompareAction->m_flags |= IAction::TransitionPending;
        }

        return true;
    }
    else
    {
        return false;
    }
}
示例#2
0
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;
}
示例#3
0
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;
}