bool CAnimationProxyDualCharacterUpper::RemoveAnimationInLayer(IEntity *entity, int32 nLayer, uint32 token) { ICharacterInstance* pIShadowCharacter = m_firstPersonMode ? entity->GetCharacter(m_characterShadow) : NULL; ICharacterInstance* pICharacter = pIShadowCharacter ? pIShadowCharacter : entity->GetCharacter(m_characterMain); if (pICharacter) { ISkeletonAnim* pISkeletonAnim = pICharacter->GetISkeletonAnim(); if (pIShadowCharacter) { ISkeletonAnim* pIShadowSkeletonAnim = pIShadowCharacter->GetISkeletonAnim(); int nAnimsInFIFO = pIShadowSkeletonAnim->GetNumAnimsInFIFO(nLayer); for (int i=0; i<nAnimsInFIFO; ++i) { const CAnimation& anim = pIShadowSkeletonAnim->GetAnimFromFIFO(nLayer, i); if (anim.HasUserToken(token)) { pIShadowSkeletonAnim->RemoveAnimFromFIFO(nLayer, i); } } } int nAnimsInFIFO = pISkeletonAnim->GetNumAnimsInFIFO(nLayer); for (int i=0; i<nAnimsInFIFO; ++i) { const CAnimation& anim = pISkeletonAnim->GetAnimFromFIFO(nLayer, i); if (anim.HasUserToken(token)) { return pISkeletonAnim->RemoveAnimFromFIFO(nLayer, i); } } } return false; }
void CActionScope::Pause() { if (!m_scopeContext.charInst) { return; } ISkeletonAnim *pSkeletonAnim = m_scopeContext.charInst->GetISkeletonAnim(); if (!pSkeletonAnim) { return; } for (int i = 0; i < m_numLayers; ++i) { SSequencer &sequencer = m_layerSequencers[i]; const int animationLayer = m_layer + i; const int animationsInLayer = pSkeletonAnim->GetNumAnimsInFIFO(animationLayer); if (animationsInLayer == 0) { sequencer.savedAnimNormalisedTime = -1; } else { const int lastAnimationIndex = animationsInLayer - 1; const CAnimation &animation = pSkeletonAnim->GetAnimFromFIFO(animationLayer, lastAnimationIndex); sequencer.savedAnimNormalisedTime = pSkeletonAnim->GetAnimationNormalizedTime(&animation); } } }
void CMountedGunController::ReplayUpdateThirdPersonAnimations( ICharacterInstance* pCharacter, float aimRad, float aimUp, float aimDown, bool firstPerson /*= false*/) { if (pCharacter) { ISkeletonAnim *pSkeletonAnim = pCharacter->GetISkeletonAnim(); assert(pSkeletonAnim); //Update manually animation time, to match current weapon orientation uint32 numAnimsLayer = pSkeletonAnim->GetNumAnimsInFIFO(REPLAY_PLAYER_ANIMATION_LAYER_BASE); for(uint32 i=0; i<numAnimsLayer; i++) { CAnimation &animation = pSkeletonAnim->GetAnimFromFIFO(REPLAY_PLAYER_ANIMATION_LAYER_BASE, i); if (animation.HasStaticFlag(CA_MANUAL_UPDATE)) { float time = CalculateAnimationTime(aimRad); pSkeletonAnim->SetAnimationNormalizedTime(&animation, time); animation.ClearStaticFlag( CA_DISABLE_MULTILAYER ); } } if (firstPerson) return; //Update additive weights for aiming up/down pSkeletonAnim->SetLayerBlendWeight(REPLAY_PLAYER_ANIMATION_LAYER_AIM_UP, aimUp); pSkeletonAnim->SetLayerBlendWeight(REPLAY_PLAYER_ANIMATION_LAYER_AIM_DOWN, aimDown); } }
CAnimation *CAnimationProxyDualCharacter::GetAnimation(IEntity *entity, int32 layer, uint32 token) { ICharacterInstance* pIShadowCharacter = m_firstPersonMode ? entity->GetCharacter(m_characterShadow) : NULL; ICharacterInstance* pICharacter = pIShadowCharacter ? pIShadowCharacter : entity->GetCharacter(m_characterMain); if (pICharacter) { ISkeletonAnim* pISkeletonAnim = pICharacter->GetISkeletonAnim(); int nAnimsInFIFO = pISkeletonAnim->GetNumAnimsInFIFO(layer); if (nAnimsInFIFO == 0) { return NULL; } if (token == INVALID_ANIMATION_TOKEN) { return &pISkeletonAnim->GetAnimFromFIFO(layer, 0); } else { return pISkeletonAnim->FindAnimInFIFO(token, layer); } } return NULL; }
CAnimation *CActionScope::GetTopAnim(int layer) { CAnimation *anim = NULL; if (m_scopeContext.charInst) { ISkeletonAnim *pISkeletonAnim = m_scopeContext.charInst->GetISkeletonAnim(); int nAnimsInFIFO = pISkeletonAnim->GetNumAnimsInFIFO(m_layer + layer); if (nAnimsInFIFO > 0) { anim = &pISkeletonAnim->GetAnimFromFIFO(m_layer + layer, nAnimsInFIFO-1); } } return anim; }
const CAnimation *CAnimationProxyDualCharacter::GetAnimation(IEntity *entity, int32 layer) { ICharacterInstance* pIShadowCharacter = m_firstPersonMode ? entity->GetCharacter(m_characterShadow) : NULL; ICharacterInstance* pICharacter = pIShadowCharacter ? pIShadowCharacter : entity->GetCharacter(m_characterMain); if (pICharacter) { ISkeletonAnim* pISkeletonAnim = pICharacter->GetISkeletonAnim(); int nAnimsInFIFO = pISkeletonAnim->GetNumAnimsInFIFO(layer); if (nAnimsInFIFO > 0) { return &pISkeletonAnim->GetAnimFromFIFO(layer, nAnimsInFIFO-1); } } return NULL; }
//------------------------------------------------------------------------ void CVehicleSeatActionPassengerIK::Update(float frameTime) { if (!m_passengerId) return; IActor* pActor = CCryAction::GetCryAction()->GetIActorSystem()->GetActor(m_passengerId); if (!pActor) { CRY_ASSERT(!"Invalid entity id for the actor id, Actor System didn't know it"); return; } if (ICharacterInstance* pCharInstance = pActor->GetEntity()->GetCharacter(0)) { ISkeletonAnim* pSkeletonAnim = pCharInstance->GetISkeletonAnim(); CRY_ASSERT(pSkeletonAnim); if (pSkeletonAnim->GetNumAnimsInFIFO(0) >= 1) { const CAnimation& anim = pSkeletonAnim->GetAnimFromFIFO(0, 0); const uint16 loopCount = anim.GetLoop(); const f32 animationTime = pSkeletonAnim->GetAnimationNormalizedTime( &anim ); if (!m_waitShortlyBeforeStarting || (loopCount > 0 || animationTime > 0.9f)) { for (TIKLimbVector::iterator ite = m_ikLimbs.begin(); ite != m_ikLimbs.end(); ++ite) { const SIKLimb& limb = *ite; Vec3 helperPos = limb.pHelper->GetWorldSpaceTranslation(); pActor->SetIKPos(limb.limbName.c_str(), helperPos, 1); } } } } }
void CActionScope::UpdateSequencers(float timePassed) { ISkeletonAnim *pSkelAnim = m_scopeContext.charInst ? m_scopeContext.charInst->GetISkeletonAnim() : NULL; const bool hasIncrement = (m_timeIncrement != 0.0f); timePassed += m_timeIncrement; m_timeIncrement = 0.0f; const int k_MAX_INCREMENTS = 5; float queuedIncrements[k_MAX_INCREMENTS]; int numQueued = 0; if(pSkelAnim) { const CAnimation *pRootAnim = GetTopAnim(0); if (pRootAnim) { m_lastNormalisedTime = m_normalisedTime; m_normalisedTime = pRootAnim->GetCurrentSegmentNormalizedTime(); } for (uint32 i=0; i<m_numLayers; i++) { SSequencer &sequencer = m_layerSequencers[i]; float timeLeft = timePassed; while ((sequencer.flags & eSF_Queued) != 0) { const float timeTillInstall = sequencer.installTime; if (timeLeft >= timeTillInstall) { if (PlayPendingAnim(i, timeLeft - timeTillInstall)) { timeLeft -= timeTillInstall; if (numQueued < k_MAX_INCREMENTS) { queuedIncrements[numQueued++] = timeLeft; } if (sequencer.pos >= sequencer.sequence.size()) break; } } else { sequencer.installTime -= timeLeft; break; } } if (hasIncrement) { uint32 layer = m_layer + i; uint32 numAnims = pSkelAnim->GetNumAnimsInFIFO(layer); if (numAnims > 0) { for (uint32 anm=0; anm<numAnims; anm++) { int timeIncID = (anm + numQueued) - numAnims; float timeIncrement = (timeIncID >= 0) ? queuedIncrements[timeIncID] : timePassed; if (timeIncrement > 0.0f) { CAnimation &anim = pSkelAnim->GetAnimFromFIFO(layer, anm); float segDuration = m_scopeContext.charInst->GetIAnimationSet()->GetDuration_sec(anim.GetAnimationId()); if (segDuration > 0.0f) { const float segNormTime = anim.GetCurrentSegmentNormalizedTime(); const float newTime = (segNormTime * segDuration) + (timeIncrement * anim.GetPlaybackScale()); float newSegNormTime = newTime / segDuration; if (!anim.HasStaticFlag(CA_LOOP_ANIMATION)) { newSegNormTime = min(newSegNormTime, 1.0f); } else { newSegNormTime = newSegNormTime - (float)((int)(newSegNormTime)); } anim.SetCurrentSegmentNormalizedTime(newSegNormTime); } float transitionPriority = 0.0f; const float transitionTime = anim.GetTransitionTime(); if ((transitionTime == 0.0f) || (anm < numAnims-1)) { transitionPriority = 1.0f; } else { transitionPriority = min(anim.GetTransitionPriority() + (timeIncrement / transitionTime), 1.0f); } anim.SetTransitionPriority(transitionPriority); } } } } } } const uint32 numProcSequencers = m_procSequencers.size(); for (uint32 i=0; i<numProcSequencers; i++) { SProcSequencer &sequencer = m_procSequencers[i]; float timeLeft = timePassed; while ((sequencer.flags & eSF_Queued) != 0) { if (timeLeft >= sequencer.installTime) { timeLeft -= sequencer.installTime; sequencer.installTime = -1.0f; PlayPendingProc(i); } else { sequencer.installTime -= timeLeft; break; } } if (sequencer.proceduralClip) { sequencer.proceduralClip->Update(timeLeft); } } }
void CActionScope::Resume(float forcedBlendTime, uint32 resumeFlags) { if (!m_scopeContext.charInst) { return; } IAnimationSet *pAnimSet = m_scopeContext.charInst->GetIAnimationSet(); if (!pAnimSet) { return; } ISkeletonAnim *pSkeletonAnim = m_scopeContext.charInst->GetISkeletonAnim(); if (!pSkeletonAnim) { return; } const bool useDefaultBlendTime = (forcedBlendTime < 0); for (int i = 0; i < m_numLayers; ++i) { SSequencer &sequencer = m_layerSequencers[i]; const int animationLayer = m_layer + i; const float blendTime = useDefaultBlendTime ? sequencer.blend.duration : forcedBlendTime; if (sequencer.savedAnimNormalisedTime < 0) { pSkeletonAnim->StopAnimationInLayer(animationLayer, blendTime); } else { const uint32 pos = sequencer.pos - 1; if (pos < sequencer.sequence.size()) { SAnimClip& clip = sequencer.sequence[pos]; const int animID = pAnimSet->GetAnimIDByCRC(clip.animation.animRef.crc); if (0 <= animID) { CryCharAnimationParams params; InitAnimationParams(clip.animation, i, clip.blend, params); const bool installAnimationSuccess = InstallAnimation(animID, params); if (installAnimationSuccess) { const int animationsInLayer = pSkeletonAnim->GetNumAnimsInFIFO(animationLayer); CRY_ASSERT(1 <= animationsInLayer); const bool loopingAnimation = ((clip.animation.flags & CA_LOOP_ANIMATION) != 0); const uint32 restoreAnimationTimeFlagToCheck = loopingAnimation ? IActionController::ERF_RestoreLoopingAnimationTime : IActionController::ERF_RestoreNonLoopingAnimationTime; const bool restoreAnimationTime = ((restoreAnimationTimeFlagToCheck & resumeFlags) != 0); if (restoreAnimationTime) { const int lastAnimationIndex = animationsInLayer - 1; CAnimation &animation = pSkeletonAnim->GetAnimFromFIFO(animationLayer, lastAnimationIndex); pSkeletonAnim->SetAnimationNormalizedTime(&animation, sequencer.savedAnimNormalisedTime); } } } } } } }
void CVehicleWeaponControlled::Update3PAnim(CPlayer *player, float goalTime, float frameTime, const Matrix34 &mat) { if (player) { if (IEntity *entity = player->GetEntity()) { const float ANIM_ANGLE_RANGE = gf_PI*0.25f; static float dir = 0.05f; static float pos = 0.5f; pos += dir; if (pos > 1.0f) { pos = 1.0f; dir = -dir; } else if (pos < 0.0f) { pos = 0.0f; dir = -dir; } m_CurrentTime = LERP(m_CurrentTime, goalTime, frameTime); if (ICharacterInstance *character = entity->GetCharacter(0)) { ISkeletonAnim *pSkeletonAnim = character->GetISkeletonAnim(); assert(pSkeletonAnim); //Update manually animation time, to match current weapon orientation uint32 numAnimsLayer = pSkeletonAnim->GetNumAnimsInFIFO(0); for(uint32 i=0; i<numAnimsLayer; i++) { CAnimation &animation = pSkeletonAnim->GetAnimFromFIFO(0, i); if (animation.HasStaticFlag( CA_MANUAL_UPDATE )) { float time = m_CurrentTime; //pos; //fmod_tpl(aimRad / ANIM_ANGLE_RANGE, 1.0f); time = (float)__fsel(time, time, 1.0f + time); pSkeletonAnim->SetAnimationNormalizedTime(&animation, time); animation.ClearStaticFlag( CA_DISABLE_MULTILAYER ); } } } const SMountParams* pMountParams = GetMountedParams(); SEntitySlotInfo info; if (GetEntity()->GetSlotInfo(eIGS_ThirdPerson, info)) { if (info.pStatObj) { IStatObj *pStatsObj = info.pStatObj; const Vec3 &leftHandPos = pStatsObj->GetHelperPos(pMountParams->left_hand_helper.c_str()); const Vec3 &rightHandPos = pStatsObj->GetHelperPos(pMountParams->right_hand_helper.c_str()); const Vec3 leftIKPos = mat.TransformPoint(leftHandPos); const Vec3 rightIKPos = mat.TransformPoint(rightHandPos); player->SetIKPos("leftArm", leftIKPos, 1); player->SetIKPos("rightArm", rightIKPos, 1); } } } } }
//------------------------------------------------------------------------ void CItem::UpdateMounted(float frameTime) { IRenderAuxGeom* pAuxGeom = gEnv->pRenderer->GetIRenderAuxGeom(); if (!m_ownerId || !m_stats.mounted) return; CActor *pActor = GetOwnerActor(); if (!pActor) return; CheckViewChange(); if (true) { if (IsClient()) { ICharacterInstance *pCharacter = GetEntity()->GetCharacter(eIGS_FirstPerson); if (pCharacter && !m_idleAnimation[eIGS_FirstPerson].empty() && pCharacter->GetISkeletonAnim()->GetNumAnimsInFIFO(0)<1) PlayAction(m_idleAnimation[eIGS_FirstPerson], 0, true); } // need to explicitly update characters at this point // cause the entity system update occered earlier, with the last position for (int i=0; i<eIGS_Last; i++) { if (GetEntity()->GetSlotFlags(i)&ENTITY_SLOT_RENDER) { ICharacterInstance *pCharacter = GetEntity()->GetCharacter(i); if (pCharacter) { Matrix34 mloc = GetEntity()->GetSlotLocalTM(i,false); Matrix34 m34 = GetEntity()->GetWorldTM()*mloc; QuatT renderLocation = QuatT(m34); pCharacter->GetISkeletonPose()->SetForceSkeletonUpdate(9); pCharacter->SkeletonPreProcess(renderLocation, renderLocation, GetISystem()->GetViewCamera(),0x55 ); pCharacter->SetPostProcessParameter(renderLocation, renderLocation, 0, 0.0f, 0x55 ); } } } // f32 fColor[4] = {1,1,0,1}; // f32 g_YLine=60.0f; // gEnv->pRenderer->Draw2dLabel( 1,g_YLine, 1.3f, fColor, false, "Mounted Gun Code" ); //adjust the orientation of the gun based on the aim-direction SMovementState info; IMovementController* pMC = pActor->GetMovementController(); pMC->GetMovementState(info); Vec3 dir = info.aimDirection.GetNormalized(); Matrix34 tm = Matrix33::CreateRotationVDir(dir); Vec3 vGunXAxis=tm.GetColumn0(); if (pActor->GetLinkedVehicle()==0) { if (pMC) { if(!pActor->IsPlayer()) { // prevent snapping direction Vec3 currentDir = GetEntity()->GetWorldRotation().GetColumn1(); float dot = currentDir.Dot(dir); dot = CLAMP(dot,-1,1); float reqAngle = cry_acosf(dot); const float maxRotSpeed = 2.0f; float maxAngle = frameTime * maxRotSpeed; if(fabs(reqAngle) > maxAngle) { Vec3 axis = currentDir.Cross(dir); if(axis.GetLengthSquared()>0.001f) // current dir and new dir are enough different dir = currentDir.GetRotated(axis.GetNormalized(),sgn(reqAngle)*maxAngle); } } //adjust the orientation of the gun based on the aim-direction tm = Matrix33::CreateRotationVDir(dir); Vec3 vWPos=GetEntity()->GetWorldPos(); tm.SetTranslation(vWPos); GetEntity()->SetWorldTM(tm); //set the new orientation of the mounted gun vGunXAxis=tm.GetColumn0(); Vec3 vInitialAimDirection = m_stats.mount_dir; Matrix33 vInitialPlayerOrientation = Matrix33::CreateRotationVDir(vInitialAimDirection); assert( vInitialAimDirection.IsUnit() ); Vec3 newp; if (pActor->IsThirdPerson()) { //third person f32 dist = m_mountparams.body_distance*1.3f; Vec3 oldp = pActor->GetEntity()->GetWorldPos(); newp = GetEntity()->GetWorldPos()-vInitialAimDirection*dist; //mounted gun newp.z = oldp.z; } else { //first person f32 fMoveBack = (1.0f+(dir.z*dir.z*dir.z*dir.z*4.0f))*0.75f; f32 dist = m_mountparams.eye_distance*fMoveBack; Vec3 oldp = pActor->GetEntity()->GetWorldPos(); newp = GetEntity()->GetWorldPos()-dir*dist; //mounted gun //newp.z -= 0.75f; newp.z = oldp.z; } Matrix34 actortm(pActor->GetEntity()->GetWorldTM()); //if (pActor->IsThirdPerson()) actortm=vInitialPlayerOrientation; actortm.SetTranslation(newp); pActor->GetEntity()->SetWorldTM(actortm, ENTITY_XFORM_USER); pActor->GetAnimationGraphState()->SetInput("Action","gunnerMounted"); //f32 g_YLine=80.0f; //gEnv->pRenderer->Draw2dLabel( 1,g_YLine, 1.3f, fColor, false, "Mounted Gun Active for FP and AI" ); if (ICharacterInstance *pCharacter = pActor->GetEntity()->GetCharacter(0)) { ISkeletonAnim *pSkeletonAnim = pCharacter->GetISkeletonAnim(); assert(pSkeletonAnim); uint32 numAnimsLayer = pSkeletonAnim->GetNumAnimsInFIFO(0); for(uint32 i=0; i<numAnimsLayer; i++) { CAnimation &animation = pSkeletonAnim->GetAnimFromFIFO(0, i); if (animation.m_AnimParams.m_nFlags & CA_MANUAL_UPDATE) { f32 aimrad = Ang3::CreateRadZ(Vec2(vInitialAimDirection),Vec2(dir)); animation.m_fAnimTime = clamp_tpl(aimrad/gf_PI,-1.0f,+1.0f)*0.5f+0.5f; //if (pActor->IsThirdPerson()==0) //animation.m_fAnimTime=0.6f; //Ivo & Benito: high advanced future code. don't ask what it is //Benito - Not needed any more ;) //f32 g_YLine=100.0f; //gEnv->pRenderer->Draw2dLabel( 1,g_YLine, 1.3f, fColor, false, "AnimTime: %f MyAimAngle: %f deg:% distance:%f", animation.m_fAnimTime, aimrad, RAD2DEG(aimrad),m_mountparams.body_distance ); } } } m_stats.mount_last_aimdir = dir; } } if (ICharacterInstance* pCharInstance = pActor->GetEntity()->GetCharacter(0)) { if (ISkeletonAnim* pSkeletonAnim = pCharInstance->GetISkeletonAnim()) { OldBlendSpace ap; if (GetAimBlending(ap)) { pSkeletonAnim->SetBlendSpaceOverride(eMotionParamID_TurnSpeed, 0.5f + 0.5f * ap.m_turn, true); } } } UpdateIKMounted(pActor, vGunXAxis*0.1f); RequireUpdate(eIUS_General); } }