//----------------------------------------------------------------------- bool gkObjectManager::checkSelected( uint8 type, f32 size, bool draging ) { // first of all, get the 3 axis end point at screenspace [8/25/2011 Kaiming-Desktop] Vec2 vCursor = GetIEditor()->getMainViewport()->getCursorOnClientScreen(); Vec3 vAxis3D; Vec3 vCenter3D; Vec3 vCenterReal = ms_pCurrentPick->getWorldPosition(); Vec3 vDirReal(0,0,0); vCenter3D = gEnv->pRenderer->ProjectScreenPos( vCenterReal ); switch(type) { case GKSTUDIO_AXIS_X: vDirReal = ms_pCurrentPick->getOrientation().GetColumn0(); break; case GKSTUDIO_AXIS_Y: vDirReal = ms_pCurrentPick->getOrientation().GetColumn1(); break; case GKSTUDIO_AXIS_Z: vDirReal = ms_pCurrentPick->getOrientation().GetColumn2(); break; } vAxis3D = gEnv->pRenderer->ProjectScreenPos( ms_pCurrentPick->getWorldPosition() + size * vDirReal ); // make two 2D vector Vec2 vCenter(vCenter3D.x, vCenter3D.y); Vec2 vAxis(vAxis3D.x, vAxis3D.y); Vec2 vPoint = vCursor - vCenter; Vec2 vAxisPoint = vAxis - vCenter; ms_dragInvertX = vAxisPoint.x > 0 ? 1 : -1; ms_dragInvertY = vAxisPoint.y > 0 ? 1 : -1; // judge this if (vPoint.GetLength() - vAxisPoint.GetLength() < size + 2.0f) { vPoint.Normalize(); vAxisPoint.Normalize(); if (vPoint.Dot(vAxisPoint) > 0.95f) return true; } return false; }
void CLivingEntitySample::UpdateAnimationParams( const float frameTime ) { IEntity* pEntity = GetEntity(); const int slot = 0; ICharacterInstance* pCharacterInstance = pEntity->GetCharacter( slot ); if ( pCharacterInstance == NULL ) { return; } ISkeletonAnim* pSkeletonAnim = pCharacterInstance->GetISkeletonAnim(); if ( pSkeletonAnim == NULL ) { return; } ISkeletonPose* pSkeletonPose = pCharacterInstance->GetISkeletonPose(); if ( pSkeletonPose == NULL ) { return; } const Vec2 localVelocity( m_localEntityVelocity.x, m_localEntityVelocity.y ); const float speed = localVelocity.GetLength(); const float angle = atan2f( -localVelocity.x, localVelocity.y ); pSkeletonAnim->SetDesiredMotionParam( eMotionParamID_TravelSpeed, speed, frameTime ); pSkeletonAnim->SetDesiredMotionParam( eMotionParamID_TravelAngle, angle, frameTime ); }
void CLivingEntitySample::UpdateAnimationState( const float frameTime ) { const Vec2 localVelocity( m_localEntityVelocity.x, m_localEntityVelocity.y ); const float speed = localVelocity.GetLength(); // Overly simplified selection between animation states for sample purposes: AnimationState newAnimationState = ( speed < 0.1f ) ? Idle : Walk; if ( newAnimationState == m_animationState ) { return; } m_animationState = newAnimationState; StartAnimationForCurrentAnimationState(); }
void CMouse::SmoothDeltas(float accel,float decel) { if (accel<0.0001f) { //do nothing ,just like it was before. return; } else if (accel<0.9999f)//mouse smooth, average the old and the actual delta by the delta ammount, less delta = more smooth speed. { Vec2 delta = m_deltas - m_oldDeltas; float len = delta.GetLength(); float amt = 1.0f - (min(10.0f,len)/10.0f*min(accel,0.9f)); m_deltas = m_oldDeltas + delta*amt; } else if (accel<1.0001f)//mouse smooth, just average the old and the actual delta. { m_deltas = (m_deltas + m_oldDeltas) * 0.5f; } else//mouse smooth with acceleration { float dt = min(gEnv->pTimer->GetFrameTime(),0.1f); Vec2 delta; float amt = 0.0; //if the input want to stop use twice of the acceleration. if (m_deltas.GetLength2()<0.0001f) if (decel>0.0001f)//there is a custom deceleration value? use it. amt = min(1.0f,dt*decel); else//otherwise acceleration * 2 is the default. amt = min(1.0f,dt*accel*2.0f); else amt = min(1.0f,dt*accel); delta = m_deltas - m_oldDeltas; m_deltas = m_oldDeltas + delta*amt; } m_oldDeltas = m_deltas; }
void Elastic::Resolve() { // Vecteur P1P2 Vec2 Vect = P2->GetPosition() - P1->GetPosition(); // Précalcul de la distance P1P2 - Peut être optimisée par une approximation float acLength = Vect.GetLength(); // Loi de Hooke float factor = mySpring*(acLength - myLength); // Rapport entre les masses : Si !=0.5, l'un des points sera moins enclin à bouger float MassFactor = P1->GetMass()/(P1->GetMass()+P2->GetMass()); // Normalisation du vecteur (pas besoin de GetNormalized(), on a déjà acLength) Vect = Vect/acLength; // Si l'un des points est fixe, toute la force est appliquée à l'autre P2->ApplyForce(-Vect*factor*(P1->IsFixe()?MassFactor*1:1)), P1->ApplyForce(Vect*factor*(P2->IsFixe()?(1-MassFactor):1)); }
bool operator() (const SSpectacularKillAnimation& killAnim) const { const SSpectacularKillCVars& skCVars = g_pGameCVars->g_spectacularKill; const CActor* pOwner = m_spectacularKill.m_pOwner; // 0. the anim shouldn't be redundant if (((gEnv->pTimer->GetFrameStartTime().GetSeconds() - s_lastKillInfo.timeStamp) <= skCVars.minTimeBetweenSameKills) && (killAnim.killerAnimation.compare(s_lastKillInfo.killerAnim))) { SK_DEBUG_LOG("GetValidAnim - %s is not valid: This animation was last played %.1f ago, a minimum time of %.1f is required", killAnim.killerAnimation.c_str(), (gEnv->pTimer->GetFrameStartTime().GetSeconds() - s_lastKillInfo.timeStamp), skCVars.minTimeBetweenSameKills); return true; } // 1. the killer needs to be within a certain distance from the target IEntity* pTargetEntity = m_pTarget->GetEntity(); IEntity* pKillerEntity = pOwner->GetEntity(); const QuatT& killerTransform = pOwner->GetAnimatedCharacter()->GetAnimLocation(); const QuatT& targetTransform = m_pTarget->GetAnimatedCharacter()->GetAnimLocation(); const Vec3& vKillerPos = killerTransform.t; const Vec3& vTargetPos = targetTransform.t; Vec2 vKillerToTarget = Vec2(vTargetPos) - Vec2(vKillerPos); float distance = vKillerToTarget.GetLength(); const float optimalDistance = killAnim.optimalDist; if ((optimalDistance > 0.0f) && (fabs_tpl(distance - optimalDistance) > skCVars.maxDistanceError)) { #ifndef _RELEASE if (g_pGameCVars->g_spectacularKill.debug > 1) { // visually shows why it failed IPersistantDebug* pPersistantDebug = m_spectacularKill.BeginPersistantDebug(); const float fConeHeight = killAnim.optimalDist + skCVars.maxDistanceError; pPersistantDebug->AddPlanarDisc(vTargetPos, killAnim.optimalDist - skCVars.maxDistanceError, killAnim.optimalDist + skCVars.maxDistanceError, Col_Coral, 6.0f); pPersistantDebug->AddLine(vKillerPos, vKillerPos + Vec3(0.f, 0.f, 5.0f), Col_Red, 6.f); } SK_DEBUG_LOG("GetValidAnim - %s is not valid: Distance between actors should be %.2f, is %.2f (max error is %f)", killAnim.killerAnimation.c_str(), optimalDistance, distance, skCVars.maxDistanceError); #endif return true; } // 2. The killer needs to be facing the target within cosLookToConeHalfAngleRadians angle Vec2 vKillerDir(killerTransform.GetColumn1()); // In decoupled catchup mode we need the animated character's orientation vKillerDir.Normalize(); if (vKillerToTarget.GetNormalizedSafe().Dot(vKillerDir) <= skCVars.minKillerToTargetDotProduct) { SK_DEBUG_LOG("GetValidAnim - %s is not valid: Killer is not looking within %.2f degrees towards the target", killAnim.killerAnimation.c_str(), RAD2DEG(acos_tpl(skCVars.minKillerToTargetDotProduct) * 2.0f)); return true; } // 3. If specified, the killer needs to be within a certain angle range from a given reference orientation from the target // e.g. Specifying referenceAngle 180 means using the back of the target as the center of the angle range // (imagine it as a cone) where the killer has to be for the kill to be valid if (killAnim.targetToKillerAngle >= 0.f) { const float referenceAngle = killAnim.targetToKillerAngle; // Find the reference vector which will be the center of the allowed angle range Vec2 vTargetDir(targetTransform.GetColumn1()); vTargetDir.Normalize(); // 2D rotation Vec2 vReferenceDir((vTargetDir.x * cosf(referenceAngle)) - (vTargetDir.y * sinf(referenceAngle)), (vTargetDir.y * cosf(referenceAngle)) + (vTargetDir.x * sinf(referenceAngle))); if (vKillerToTarget.GetNormalizedSafe().Dot(-vReferenceDir) <= killAnim.targetToKillerMinDot) { #ifndef _RELEASE if (g_pGameCVars->g_spectacularKill.debug > 1) { // visually shows why it failed IPersistantDebug* pPersistantDebug = m_spectacularKill.BeginPersistantDebug(); const float fConeHeight = killAnim.optimalDist + skCVars.maxDistanceError; pPersistantDebug->AddCone(vTargetPos + (vReferenceDir * fConeHeight), -vReferenceDir, killAnim.targetToKillerMinDot * fConeHeight * 2.0f, fConeHeight, Col_Coral, 6.f); pPersistantDebug->AddLine(vKillerPos, vKillerPos + Vec3(0.f, 0.f, 5.0f), Col_Red, 6.f); } float targetToKillerDot = vTargetDir.GetNormalizedSafe().Dot(-vKillerToTarget); SK_DEBUG_LOG("GetValidAnim - %s is not valid: Killer is not within a %.2f degrees cone centered on the target's %.2f degrees. Killer is at %.2f angles respect the target", killAnim.killerAnimation.c_str(), RAD2DEG(acos_tpl(killAnim.targetToKillerMinDot) * 2.0f), RAD2DEG(killAnim.targetToKillerAngle), RAD2DEG(acos_tpl(targetToKillerDot))); #endif return true; } } SK_DEBUG_LOG("GetValidAnim - %s is valid", killAnim.killerAnimation.c_str()); return false; }
void CHUD::AutoSnap() { const float fRadius = 25.0f; static Vec2 s_vCursor = Vec2(0,0); if(fabsf(m_fAutosnapCursorControllerX)>0.1 || fabsf(m_fAutosnapCursorControllerY)>0.1) { s_vCursor.x = m_fAutosnapCursorControllerX * 30.0f; s_vCursor.y = m_fAutosnapCursorControllerY * 30.0f; } else { s_vCursor.x = m_fAutosnapCursorRelativeX; s_vCursor.y = m_fAutosnapCursorRelativeY; } if(m_bOnCircle && s_vCursor.GetLength() < fRadius*0.5f) { m_fAutosnapCursorRelativeX = 0; m_fAutosnapCursorRelativeY = 0; m_bOnCircle = false; } if(s_vCursor.GetLength() > fRadius) { s_vCursor.NormalizeSafe(); m_fAutosnapCursorRelativeX = s_vCursor.x*fRadius; m_fAutosnapCursorRelativeY = s_vCursor.y*fRadius; m_bOnCircle = true; } const char* autosnapItem = "Center"; if(m_bOnCircle) { Vec2 vCursor = s_vCursor; vCursor.NormalizeSafe(); float fAngle; if(vCursor.y < 0) { fAngle = RAD2DEG(acos_tpl(vCursor.x)); } else { fAngle = RAD2DEG(gf_PI2-acos_tpl(vCursor.x)); } char szAngle[32]; sprintf(szAngle,"%f",-fAngle+90.0f); /* ColorB col(255,255,255,255); int iW=m_pRenderer->GetWidth(); int iH=m_pRenderer->GetHeight(); m_pRenderer->Set2DMode(true,iW,iH); m_pRenderer->GetIRenderAuxGeom()->DrawLine(Vec3(iW/2,iH/2,0),col,Vec3(iW/2+vCursor.x*100,iH/2+vCursor.y*100,0),col,5); m_pRenderer->Set2DMode(false,0,0); */ m_animQuickMenu.CheckedSetVariable("Root.QuickMenu.Circle.Indicator._rotation",szAngle); if(fAngle >= 342 || fAngle < 52) { autosnapItem = "Strength"; } else if(fAngle >= 52 && fAngle < 128) { autosnapItem = "Speed"; } else if(fAngle >= 128 && fAngle < 205) { autosnapItem = "Defense"; } else if(fAngle >= 205 && fAngle < 260) { autosnapItem = "Weapon"; } else if(fAngle >= 260 && fAngle < 342) { autosnapItem = "Cloak"; } } m_animQuickMenu.CheckedInvoke("Root.QuickMenu.setAutosnapItem", autosnapItem); }
void CAnimatedCharacter::SetDesiredLocalLocation( ISkeletonAnim* pSkeletonAnim, const QuatT& desiredLocalLocation, float fDeltaTime) { CRY_ASSERT(desiredLocalLocation.IsValid()); { uint32 NumAnimsInQueue = pSkeletonAnim->GetNumAnimsInFIFO(0); uint32 nMaxActiveInQueue=MAX_EXEC_QUEUE; if (nMaxActiveInQueue>NumAnimsInQueue) nMaxActiveInQueue=NumAnimsInQueue; if (NumAnimsInQueue>nMaxActiveInQueue) NumAnimsInQueue=nMaxActiveInQueue; uint32 active=0; for (uint32 a=0; a<NumAnimsInQueue; a++) { const CAnimation& anim = pSkeletonAnim->GetAnimFromFIFO(0,a); active += anim.IsActivated() ? 1 : 0; } if (active>nMaxActiveInQueue) active=nMaxActiveInQueue; nMaxActiveInQueue=active; const SParametricSampler *pLMG = NULL; for (int32 a=nMaxActiveInQueue-1; (a >= 0) && !pLMG; --a) { const CAnimation& anim = pSkeletonAnim->GetAnimFromFIFO(0,a); pLMG = anim.GetParametricSampler(); } } const Vec3 dir = desiredLocalLocation.GetColumn1(); float turnAngle = atan2f(-dir.x, dir.y); float turnSpeed = turnAngle / fDeltaTime; const Vec2 deltaVector(desiredLocalLocation.t.x, desiredLocalLocation.t.y); const float travelDist = deltaVector.GetLength(); const Vec2 deltaDir = (travelDist > 0.0f) ? (deltaVector / travelDist) : Vec2(0,0); float travelAngle = (deltaDir.x == 0.0f && deltaDir.y == 0.0f ? 0.0f : atan2f(-deltaDir.x, deltaDir.y)); float travelSpeed; if (gEnv->bMultiplayer) { travelSpeed = travelDist / fDeltaTime; } else { const float cosGroundSlope = fabsf(cosf(m_fGroundSlopeMoveDirSmooth)); travelSpeed = (cosGroundSlope > FLT_EPSILON) ? (travelDist / (fDeltaTime * cosGroundSlope)) : (travelDist / fDeltaTime); } // TravelAngle smoothing { const Vec2 newStrafe = Vec2(-sin_tpl(travelAngle), cos_tpl(travelAngle)); if (CAnimationGraphCVars::Get().m_enableTurnAngleSmoothing) { SmoothCD(m_fDesiredStrafeSmoothQTX, m_fDesiredStrafeSmoothRateQTX, fDeltaTime, newStrafe, 0.10f); } else { m_fDesiredStrafeSmoothQTX=newStrafe; m_fDesiredStrafeSmoothRateQTX.zero(); } travelAngle = Ang3::CreateRadZ(Vec2(0,1),m_fDesiredStrafeSmoothQTX); } const bool modulateTurnSpeedByTravelAngle = true; if (modulateTurnSpeedByTravelAngle) { static float minimum = DEG2RAD(10.0f); // do not change turnSpeed when travelAngle is below this static float maximum = DEG2RAD(40.0f); // force turnspeed to zero when travelAngle is above this const float turnSpeedScale = 1.0f - clamp_tpl( fabsf(travelAngle) - minimum, 0.0f, maximum - minimum ) / ( maximum - minimum ); turnSpeed *= turnSpeedScale; } // TurnSpeed smoothing { if (CAnimationGraphCVars::Get().m_enableTurnSpeedSmoothing) { SmoothCD(m_fDesiredTurnSpeedSmoothQTX, m_fDesiredTurnSpeedSmoothRateQTX, fDeltaTime, turnSpeed, 0.40f); } else { m_fDesiredTurnSpeedSmoothQTX = turnSpeed; m_fDesiredTurnSpeedSmoothRateQTX = 0.0f; } } // TravelSpeed smoothing { if (CAnimationGraphCVars::Get().m_enableTravelSpeedSmoothing) { SmoothCD(m_fDesiredMoveSpeedSmoothQTX, m_fDesiredMoveSpeedSmoothRateQTX, fDeltaTime, travelSpeed, 0.04f); } else { m_fDesiredMoveSpeedSmoothQTX = travelSpeed; m_fDesiredMoveSpeedSmoothRateQTX = 0.0f; } } SetMotionParam(pSkeletonAnim, eMotionParamID_TravelSpeed, m_fDesiredMoveSpeedSmoothQTX); SetMotionParam(pSkeletonAnim, eMotionParamID_TurnSpeed, m_fDesiredTurnSpeedSmoothQTX * CAnimationGraphCVars::Get().m_turnSpeedParamScale); SetMotionParam(pSkeletonAnim, eMotionParamID_TravelAngle, travelAngle); // eMotionParamID_TravelSlope SetMotionParam(pSkeletonAnim, eMotionParamID_TurnAngle, turnAngle); // eMotionParamID_TravelDist SetMotionParam(pSkeletonAnim, eMotionParamID_StopLeg, 0); }