Пример #1
0
//-----------------------------------------------------------------------
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;
}
Пример #2
0
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 );
}
Пример #3
0
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();
}
Пример #4
0
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;
}
Пример #5
0
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));
}
Пример #6
0
	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;
	}
Пример #7
0
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);
}