Ejemplo n.º 1
0
//------------------------------------------------------------------------
bool CItem::PlayFragment(IAction* pAction, float speedOverride, float timeOverride, float animWeight, float ffeedbackWeight, bool concentratedFire)
{
    _smart_ptr<IAction> pActionPtr(pAction);

    CRY_ASSERT(pAction);
    if(!pAction)
        {
            return false;
        }

    CWeapon *pWeapon = static_cast<CWeapon*>(GetIWeapon());
    if (pWeapon && pWeapon->IsProxyWeapon())
        {
            return false;
        }

    bool success = false;

    float speed = (float)__fsel(-speedOverride, 1.0f, speedOverride);
    FragmentID fragID = pAction->GetFragmentID();
    pAction->SetSubContext(m_subContext);
    IActionController *pActionController = GetActionController();
    if ((fragID != FRAGMENT_ID_INVALID) && pActionController)
        {
            float fragmentDuration, transitionDuration;
            if (pActionController->QueryDuration(*pAction, fragmentDuration, transitionDuration))
                {
                    float duration = fragmentDuration+transitionDuration;
                    if ((duration > 0.0f) && (timeOverride > 0.0f))
                        {
                            speed = (duration / timeOverride);
                            CRY_ASSERT((speed > 0.0f) && (speed < 99999.0f));
                        }

                    if(duration > 0.f)
                        {
                            m_animationTime[eIGS_Owner] = (uint32) MAX((duration*1000.0f/speed) - 20, 0.0f);
                        }

                    pAction->SetSpeedBias(speed);
                    pAction->SetAnimWeight(animWeight);

                    if(concentratedFire)
                        {
                            pAction->SetParam(CItem::sActionParamCRCs.concentratedFire, 1.f);
                        }

                    if(ffeedbackWeight != 1.f)
                        {
                            pAction->SetParam(CItem::sActionParamCRCs.ffeedbackScale, ffeedbackWeight);
                        }

                    pActionController->Queue(pAction);

                    success = true;
                }
        }

    return success;
}
Ejemplo n.º 2
0
// ----------------------------------------------------------------------------
void CMannequinAGState::Hurry()
{
	// first check whether we have anything that is still pending, if not, we have nothing to hurry
	const bool oneShotActionIsPending = (m_pOneShotAction && (m_pOneShotAction->GetStatus() == IAction::Pending));
	const bool loopingActionIsPending = (m_pLoopingAction && (m_pLoopingAction->GetStatus() == IAction::Pending));

	if (!oneShotActionIsPending && !loopingActionIsPending)
		return;

	IActionController* pActionController = GetActionController();
	if (!pActionController)
		return;

	// TODO: How do we mimic Hurry?  Somehow we need to, in a clean way, end all actions on all scopes
	//   (without screwing up the pending ones, properly moving interruptable ones to the queue,
	//    calling Exit() when needed, etc)
}
Ejemplo n.º 3
0
//------------------------------------------------------------------------
int CItem::GetFragmentID(const char* actionName, const CTagDefinition** tagDef)
{
    int fragmentID = FRAGMENT_ID_INVALID;

    IActionController *pActionController = GetActionController();
    if (pActionController)
        {
            SAnimationContext &animContext = pActionController->GetContext();
            fragmentID = animContext.controllerDef.m_fragmentIDs.Find(actionName);

            if(tagDef && fragmentID != FRAGMENT_ID_INVALID)
                {
                    *tagDef = animContext.controllerDef.GetFragmentTagDef(fragmentID);
                }
        }

    return fragmentID;
}
Ejemplo n.º 4
0
// ----------------------------------------------------------------------------
const char* CMannequinAGState::GetCurrentStateName()
{
	const char* result = "<unknown>";

	// Figure out something which could pose as a 'state name'
	// Currently it's the name of the first fragmentID I can find on the scopes
	IActionController* pActionController = GetActionController();
	if (!pActionController)
		return result;

	for(int scopeIndex = 0; scopeIndex < pActionController->GetTotalScopes(); ++scopeIndex)
	{
		IScope* pScope = pActionController->GetScope(scopeIndex);
		FragmentID fragmentID = pScope->GetLastFragmentID();
		if (fragmentID != FRAGMENT_ID_INVALID)
		{
			result = pActionController->GetContext().controllerDef.m_fragmentIDs.GetTagName(fragmentID);
			break;
		}
	}

	return result ;
}
Ejemplo n.º 5
0
//------------------------------------------------------------------------
_smart_ptr<IAction> CItem::PlayAction(FragmentID action, int layer, bool loop, uint32 flags, float speedOverride, float animWeigth, float ffeedbackWeight)
{
    _smart_ptr<IAction> pAction;

    const CWeapon* pWeapon = static_cast<CWeapon*>(GetIWeapon());
    if (pWeapon && pWeapon->IsProxyWeapon())
        {
            return pAction;
        }

    IActionController* pActionController = GetActionController();

    if (pActionController && action != FRAGMENT_ID_INVALID)
        {
            SAnimationContext& animContext = pActionController->GetContext();
            const CTagDefinition* pTagDefinition = animContext.controllerDef.GetFragmentTagDef(action);
            float timeOverride = -1.0f;

            bool concentratedFire = (flags&eIPAF_ConcentratedFire) != 0;

            TagState actionTags = TAG_STATE_EMPTY;

            if (pTagDefinition)
                {
                    CTagState fragTags(*pTagDefinition);

                    SetFragmentTags(fragTags);
                    actionTags = fragTags.GetMask();
                }

            pAction = new CItemAction(PP_PlayerAction, action, actionTags);

            PlayFragment(pAction, speedOverride, timeOverride, animWeigth, ffeedbackWeight, concentratedFire);
        }

    return pAction;
}
Ejemplo n.º 6
0
// ----------------------------------------------------------------------------
bool CMannequinAGState::SetActionOrSignalInput(_smart_ptr<CAnimActionAGAction>& pAction, TKeyValue& currentValue, InputID inputID, EAIActionType actionType, const char* defaultValue, uint32 defaultValueCRC, const char* value, TAnimationGraphQueryID* pQueryID, bool optional)
{
	IActionController* pActionController = GetActionController();
	if (!pActionController)
		return false;

	// TODO Where to get the priorities from?
	const int MANNEQUIN_PRIORITY = 2; // currently equal to PP_Action, just above movement, but underneath urgent actions, hit death, etc.

	TAnimationGraphQueryID queryID = 0;
	if (pQueryID)
		queryID = *pQueryID = GenerateQueryID();

	const uint32 valueCRC = CCrc32::ComputeLowercase(value);

	static uint32 idleCRC = CCrc32::ComputeLowercase("idle");
	static uint32 noneCRC = CCrc32::ComputeLowercase("none");
	const bool isUnsupportedFragmentID = ((valueCRC == idleCRC) || (valueCRC == noneCRC));
	const FragmentID fragmentID = isUnsupportedFragmentID ? FRAGMENT_ID_INVALID : pActionController->GetContext().controllerDef.m_fragmentIDs.Find(valueCRC);

	const bool isDefaultValue = (valueCRC == defaultValueCRC);

	const bool somethingIsPendingOrInstalled = pAction && pAction->IsPendingOrInstalled();

	if (isDefaultValue)
	{
		if ( actionType == EAT_Looping )
		{
			StopAnyLoopingExactPositioningAction();
		}

		const bool isPendingOrInstalled = !somethingIsPendingOrInstalled; // the fake action 'idle' isPendingOrInstalled if something else is NOT pending or installed
		if (isPendingOrInstalled)
		{
			// In the old sense: the current requested 'value' did not change, we were already 'idle'
			SendEvent_Entered(NULL, queryID, true);
		}
		else
		{
			currentValue = defaultValue;

			if (pAction)
			{
				pAction->Stop(); // this will eventually call Entered(..,false) of the user that was waiting on Entered()
				pAction = NULL;
			}

			// TODO: This is not entirely correct. The Entered() event for the idle action should only
			//   be called when you exactly "go back to idle". But this is not well defined in mannequin,
			//   so I just send it right away...
			SendEvent_Entered(NULL, queryID, true);

			SendEvent_ChangedInput(inputID, true); // tell whoever is listening to the input that it changed
		}

		return true;
	}
	else if (fragmentID != FRAGMENT_ID_INVALID)
	{
		const bool isPendingOrInstalled = 
			somethingIsPendingOrInstalled &&
			(pAction->GetValueCRC() == valueCRC);
		if (isPendingOrInstalled)
		{
			// In the old sense: the current requested 'value' did not change
			
			// reuse the old queryid, if there is one, otherwise set the new one
			if (pAction->GetQueryID())
			{
				queryID = pAction->GetQueryID();
				if (pQueryID)
					*pQueryID = queryID;
			}
			else
			{
				if (queryID)
					pAction->SetQueryID(queryID);
			}

			if (pAction->GetStatus() == IAction::Installed)
			{
				// The other system is already playing the same action.
				// Send the 'entered' event immediately
				// (afai can see the AG only did this for signals for some reason??)
				SendEvent_Entered(pAction, pAction->GetQueryID(), true);
			}
		}
		else
		{
			currentValue = value;

			pAction = new CAnimActionAGAction(MANNEQUIN_PRIORITY, fragmentID, *this, actionType, value, valueCRC, queryID);
			pActionController->Queue(*pAction.get());

			SendEvent_ChangedInput(inputID, true); // tell whoever is listening the input that it changed
		}

		return true;
	}
	else if (!optional)
	{
		// 'not optional' means invalid values get translated into the default value
		// (so we always set a value, hence the setting of values is 'not optional')
		// Recurse and pass the defaultValue as value:
		return SetActionOrSignalInput(pAction, currentValue, inputID, actionType, defaultValue, defaultValueCRC, defaultValue, NULL, true);
	}
	else
	{
#ifndef _RELEASE
		if(!isUnsupportedFragmentID)
		{
			CryWarning( VALIDATOR_MODULE_GAME, VALIDATOR_WARNING, "CMannequinAGState::SetInput: Unable to find animation '%s'", value);
		}
#endif //#ifndef _RELEASE
		return false;
	}
}
Ejemplo n.º 7
0
//------------------------------------------------------------------------
bool CItem::SetGeometry(int slot, const ItemString& name, const ItemString& material, bool useParentMaterial, const Vec3& poffset, const Ang3& aoffset, float scale, bool forceReload)
{
    assert(slot >= 0 && slot < eIGS_Last);

    bool changedfp=false;
    switch(slot)
        {
        case eIGS_Owner:
            break;
        case eIGS_FirstPerson:
        case eIGS_ThirdPerson:
        default:
        {
            if (name.empty() || forceReload)
                {
                    GetEntity()->FreeSlot(slot);
#ifndef ITEM_USE_SHAREDSTRING
                    m_geometry[slot].resize(0);
#else
                    m_geometry[slot].reset();
#endif
                }

            DestroyAttachmentHelpers(slot);

            if (!name.empty())
                {
                    if (m_geometry[slot] != name)
                        {
                            const char* ext = PathUtil::GetExt(name.c_str());
                            if ((stricmp(ext, "chr") == 0) || (stricmp(ext, "cdf") == 0) || (stricmp(ext, "cga") == 0) )
                                GetEntity()->LoadCharacter(slot, name.c_str(), 0);
                            else
                                GetEntity()->LoadGeometry(slot, name.c_str(), 0, 0);

                            changedfp=slot==eIGS_FirstPerson;
                        }

                    CreateAttachmentHelpers(slot);
                }

            /*			if (slot == eIGS_FirstPerson)
            			{
            				ICharacterInstance *pCharacter = GetEntity()->GetCharacter(eIGS_FirstPerson);
            				if (pCharacter)
            				{
            					pCharacter->SetFlags(pCharacter->GetFlags()&(~CS_FLAG_UPDATE));
            				}
            			}
                  else */if (slot == eIGS_Destroyed)
                DrawSlot(eIGS_Destroyed, false);
        }
        break;
        }

    Matrix34 slotTM;
    slotTM = Matrix34::CreateRotationXYZ(aoffset);
    slotTM.ScaleColumn(Vec3(scale, scale, scale));
    slotTM.SetTranslation(poffset);
    GetEntity()->SetSlotLocalTM(slot, slotTM);

    if (changedfp && m_stats.mounted)
        {
            if (m_sharedparams->pMountParams && !m_sharedparams->pMountParams->pivot.empty())
                {
                    Matrix34 tm=GetEntity()->GetSlotLocalTM(eIGS_FirstPerson, false);
                    Vec3 pivot = GetSlotHelperPos(eIGS_FirstPerson, m_sharedparams->pMountParams->pivot.c_str(), false);
                    tm.AddTranslation(pivot);

                    GetEntity()->SetSlotLocalTM(eIGS_FirstPerson, tm);
                }

            GetEntity()->InvalidateTM();
        }

    m_geometry[slot] = name ? name : ItemString();

    ReAttachAccessories();

    IEntity* pParentEntity = gEnv->pEntitySystem->GetEntity(GetParentId());
    IMaterial* pOverrideMaterial = 0;
    if (!material.empty())
        {
            pOverrideMaterial = gEnv->p3DEngine->GetMaterialManager()->LoadMaterial(material.c_str());
        }
    else if (useParentMaterial && pParentEntity)
        {
            ICharacterInstance* pParentCharacter = pParentEntity->GetCharacter(slot);
            IEntityRenderProxy* pParentRenderProxy = static_cast<IEntityRenderProxy*>(pParentEntity->GetProxy(ENTITY_PROXY_RENDER));
            if (pParentCharacter)
                pOverrideMaterial = pParentCharacter->GetIMaterial();
            else if (pParentRenderProxy)
                pOverrideMaterial = pParentRenderProxy->GetSlotMaterial(slot);
        }
    if (pOverrideMaterial)
        {
            ICharacterInstance* pCharacter = GetEntity()->GetCharacter(slot);
            IEntityRenderProxy* pRenderProxy = static_cast<IEntityRenderProxy*>(GetEntity()->GetProxy(ENTITY_PROXY_RENDER));
            OverrideAttachmentMaterial(pOverrideMaterial, this, slot);
            if (pCharacter)
                pCharacter->SetIMaterial_Instance(pOverrideMaterial);
            else if (pRenderProxy)
                pRenderProxy->SetSlotMaterial(slot, pOverrideMaterial);
        }

    if(slot == eIGS_FirstPerson && IsSelected())
        {
            CActor* pOwnerActor = GetOwnerActor();
            IActionController *pActionController = GetActionController();
            if(pActionController && pOwnerActor && pOwnerActor->IsClient())
                {
                    UpdateScopeContexts(pActionController);
                }
        }

    return true;
}
Ejemplo n.º 8
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;
}