Ejemplo n.º 1
0
bool CTransformationPinning::Execute(const SAnimationPoseModifierParams& params)
{
    if (m_factor == 0.0f)
        return false;

    CRY_ASSERT(m_source && (m_jointID > 0.0f));

    if (!m_jointsInitialised)
        {
            Init(params);
        }

    ISkeletonPose* pSkeletonPose = params.pCharacterInstance->GetISkeletonPose();
    int sourceJoints = m_source->GetJointCount();
    CRY_ASSERT(sourceJoints == pSkeletonPose->GetJointCount());

    for (int i=0; i<sourceJoints; i++)
        {
            const QuatT &sourceJoint = m_source->GetAbsJointByID(i);
            const QuatT &relSourceJoint	 = m_source->GetRelJointByID(i);

            CRY_ASSERT(params.pPoseData->GetJointAbsolute(i).IsValid());
            CRY_ASSERT(sourceJoint.IsValid());

            switch (m_jointTypes[i])
                {
                case TransformationPinJoint::Copy:
                    if (m_factor < 1.0f)
                        {
                            QuatT diff = params.pPoseData->GetJointAbsolute(i).GetInverted() * sourceJoint;
                            params.pPoseData->SetJointAbsolute(i,
                                                               params.pPoseData->GetJointAbsolute(i) * diff.GetScaled(m_factor));

                            diff = params.pPoseData->GetJointRelative(i).GetInverted() * relSourceJoint;
                            params.pPoseData->SetJointRelative(i, params.pPoseData->GetJointRelative(i) * diff.GetScaled(m_factor));
                        }
                    else
                        {
                            params.pPoseData->SetJointAbsolute(i, sourceJoint);
                            params.pPoseData->SetJointRelative(i, relSourceJoint);
                        }
                    break;
                case TransformationPinJoint::Feather:
                {
                    int16 parent = m_source->GetParentIDByID(i);
                    QuatT invParent = params.pPoseData->GetJointAbsolute(parent).GetInverted();
                    params.pPoseData->SetJointRelative(i, invParent * params.pPoseData->GetJointAbsolute(i));
                    QuatT thisJnt = params.pPoseData->GetJointAbsolute(parent) * params.pPoseData->GetJointRelative(i);

                    CRY_ASSERT(params.pPoseData->GetJointRelative(i).IsValid());
                    CRY_ASSERT(thisJnt.IsValid());
                }
                break;
                case TransformationPinJoint::Inherit:
                    break;
                }
        }

    return true;
}
QuatT GetWorldOffset(const QuatT& origin, const QuatT& destination)
{
	CRY_ASSERT(origin.IsValid());
	CRY_ASSERT(destination.IsValid());
	QuatT offset(destination.t - origin.t, origin.q.GetInverted() * destination.q);
	offset.q.Normalize();
	CRY_ASSERT(offset.IsValid());
	return offset;
}
QuatT ApplyWorldOffset(const QuatT& origin, const QuatT& offset)
{
	CRY_ASSERT(origin.IsValid());
	CRY_ASSERT(offset.IsValid());
	QuatT destination(origin.q * offset.q, origin.t + offset.t);
	destination.q.Normalize();
	CRY_ASSERT(destination.IsValid());
	return destination;
}
QuatT CombineHVComponents2D(const QuatT& cmpH, const QuatT& cmpV)
{
	ANIMCHAR_PROFILE_DETAILED;

	// NOTE: This function assumes there is no pitch/bank and totally ignores XY rotations.

	CRY_ASSERT(cmpH.IsValid());
	CRY_ASSERT(cmpV.IsValid());

	QuatT cmb;
	cmb.t.x = cmpH.t.x;
	cmb.t.y = cmpH.t.y;
	cmb.t.z = cmpV.t.z;
	cmb.q.SetRotationZ(cmpH.q.GetRotZ());

	CRY_ASSERT(cmb.IsValid());

	return cmb;
}
void CLocalPlayerComponent::GetFPTotalTorsoOffset(QuatT &offset, IItem * pCurrentItem) const
{
	CItem *pItem = (CItem *)pCurrentItem;
	if (pItem)
	{
		pItem->GetFPOffset(offset);
	}
	else
	{
		offset.SetIdentity();
	}
}
QuatT /*CAnimatedCharacter::*/ExtractVComponent(const QuatT& m) /*const*/
{
	ANIMCHAR_PROFILE_DETAILED;

	// NOTE: This function assumes there is no pitch/bank and totally ignores XY rotations.

	CRY_ASSERT(m.IsValid());

	QuatT ext;//(IDENTITY);
	ext.t.z = m.t.z;
	ext.t.x = 0.0f;
	ext.t.y = 0.0f;

/*
	Ang3 a(m.q);
	a.z = 0.0f;
	ext.q.SetRotationXYZ(a);
*/
	ext.q.SetIdentity();

	CRY_ASSERT(ext.IsValid());
	return ext;
}
QuatT CombineHVComponents3D(const QuatT& cmpH, const QuatT& cmpV)
{
	ANIMCHAR_PROFILE_DETAILED;

	//return CombineHVComponents2D(cmpH, cmpV);

	CRY_ASSERT(cmpH.IsValid());
	CRY_ASSERT(cmpV.IsValid());

	QuatT cmb;
	cmb.t.x = cmpH.t.x;
	cmb.t.y = cmpH.t.y;
	cmb.t.z = cmpV.t.z;

	// TODO: This should be optimized!
	Ang3 ah(cmpH.q);
	Ang3 av(cmpV.q);
	Ang3 a(av.x, av.y, ah.z);
	cmb.q.SetRotationXYZ(a);

	CRY_ASSERT(cmb.IsValid());

	return cmb;
}
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);
}
Ejemplo n.º 9
0
//------------------------------------------------------------------------
EntityEffects::TAttachedEffectId CItem::AttachEffect(int slot, bool attachToAccessory, const char *effectName, const char *helper, const Vec3 &offset, const Vec3 &dir, float scale, bool prime)
{
	if(!g_pGameCVars->i_particleeffects)
	{
		return 0;
	}
	
	Vec3 finalOffset(offset);
	string helperName(helper);

	if(attachToAccessory)
	{
		SEntitySlotInfo slotInfo;
		QuatT accessoryOffset;

		accessoryOffset.SetIdentity();
		const char* accessoryHelper = "";
		const char* accessoryName = NULL;

		const int numAccessories = m_accessories.size();

		for (int curIndex = 0; curIndex < numAccessories; curIndex++)
		{
			IEntity* pAccessory = gEnv->pEntitySystem->GetEntity(m_accessories[curIndex].accessoryId);

			if(pAccessory && pAccessory->GetSlotInfo(slot, slotInfo))
			{
				if(slotInfo.pStatObj)
				{
					accessoryOffset.t = slotInfo.pStatObj->GetHelperPos(helper);

					if(!accessoryOffset.t.IsZero())
					{
						accessoryOffset.q = pAccessory->GetRotation();
						accessoryOffset.t += pAccessory->GetPos();

						accessoryName = m_accessories[curIndex].pClass->GetName();
						break;
					}
				}

				if(slotInfo.pCharacter)
				{
					IAttachmentManager *pAttachmentManager = slotInfo.pCharacter->GetIAttachmentManager();
					IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(helper);

					if(pAttachment)
					{
						accessoryHelper = GetAccessoryParams(m_accessories[curIndex].pClass)->attach_helper.c_str();
						accessoryName = m_accessories[curIndex].pClass->GetName();

						accessoryOffset = pAttachment->GetAttAbsoluteDefault();

						break;
					}
				}
			}
		}

		if(accessoryName)
		{
			bool validSlot = GetEntity()->GetSlotInfo(slot, slotInfo) && (slotInfo.pCharacter || slotInfo.pStatObj);

			if (!validSlot || slotInfo.pStatObj)
			{
				if (validSlot)
				{
					Matrix34 mtx = GetEntity()->GetSlotLocalTM(slot, false) * Matrix34(accessoryOffset);
					finalOffset += mtx.GetTranslation();				
				}
			
				EntityEffects::SEffectAttachParams attachParams(finalOffset, dir, scale, prime, eIGS_Last);

				return m_effectsController.AttachParticleEffect(effectName, attachParams);
			}
			else if (slotInfo.pCharacter)	// bone attachment
			{
				ICharacterInstance *pCharacter = slotInfo.pCharacter;
				IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager();
				IAttachment *pAttachment = NULL; 

				helperName = string().Format("%s_%s", helper, accessoryName);
				pAttachment = pAttachmentManager->GetInterfaceByName(helperName.c_str());

				if(!pAttachment)
				{
					IAttachment* pAccessoryAttachment = pAttachmentManager->GetInterfaceByName(accessoryHelper);

					if(pAccessoryAttachment)
					{
						const char* bone = pCharacter->GetIDefaultSkeleton().GetJointNameByID(pAccessoryAttachment->GetJointID());
						pAttachment = pAttachmentManager->CreateAttachment(helperName.c_str(), CA_BONE, bone);
						if (pAttachment)
						{
							QuatT relative = pAccessoryAttachment->GetAttRelativeDefault();
							relative = relative * accessoryOffset;
							relative.t = relative * finalOffset;

							finalOffset.zero();

							pAttachment->SetAttRelativeDefault(relative);
						}
					}
				}
			}
		}
	}

	EntityEffects::SEffectAttachParams attachParams(finalOffset, dir, scale, prime, eIGS_Last);
	return m_effectsController.AttachParticleEffect(effectName, slot, helperName, attachParams);
}
bool CStickyProjectile::StickToEntity( const SStickParams& stickParams, IEntity* pTargetEntity )
{
	IEntity* pProjectileEntity = stickParams.m_pProjectile->GetEntity();
	ICharacterInstance* pCharInstance = pTargetEntity->GetCharacter(0);
	if( pCharInstance)	
	{
		IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pTargetEntity->GetId());
		if (!pActor || (stickParams.m_bStickToFriendlies || !pActor->IsFriendlyEntity(stickParams.m_ownerId)) && (gEnv->bMultiplayer || !pActor->IsDead()))
		{
			m_stuckJoint = GetJointIdFromPartId(*pTargetEntity, stickParams.m_targetPartId);
			m_stuckNormal = stickParams.m_stickNormal;
			m_stuckPartId = stickParams.m_targetPartId;

			ICharacterModelSkeleton* pICharacterModelSkeleton = pCharInstance->GetICharacterModel()->GetICharacterModelSkeleton();
			ISkeletonPose* pSkeleton = pCharInstance->GetISkeletonPose();
			const char* boneName = pICharacterModelSkeleton->GetJointNameByID(m_stuckJoint);
			const QuatT jointWorld = QuatT(pTargetEntity->GetWorldTM()) * pSkeleton->GetAbsJointByID(m_stuckJoint);
			QuatT loc;
			CalculateLocationForStick( *pProjectileEntity, stickParams.m_stickPosition, stickParams.m_stickNormal, loc );
			pProjectileEntity->SetWorldTM(Matrix34(loc));

			// Get the local pos and rot.
			loc = jointWorld.GetInverted() * loc;
			m_stuckPos = loc.t;
			m_stuckRot = loc.q;

			// Attach.
			if(AttachToCharacter( stickParams.m_pProjectile, *pTargetEntity, *pCharInstance, boneName))
			{
				m_flags |= eSF_IsStuck;
				m_flags |= pActor ? pActor->IsPlayer() ? eSF_StuckToPlayer : eSF_StuckToAI : 0;
				SetParentId(pTargetEntity->GetId());
				m_childId = pProjectileEntity->GetId();
				return true;
			}
		}
	}
	else
	{
		m_stuckNormal = stickParams.m_stickNormal;
		m_stuckPartId = stickParams.m_targetPartId;

		QuatT loc;
		CalculateLocationForStick( *pProjectileEntity, stickParams.m_stickPosition, stickParams.m_stickNormal, loc );

		AttachTo(stickParams.m_pProjectile, pTargetEntity);

		pProjectileEntity->SetWorldTM(Matrix34(loc));

		// Set as Stuck.
		SetParentId(pTargetEntity->GetId());
		m_childId = pProjectileEntity->GetId();
		m_flags |= eSF_IsStuck;

		//Store position and rotation relative to parent entity
		m_stuckPos = pProjectileEntity->GetPos();
		m_stuckRot = pProjectileEntity->GetRotation();
		return true;
	}

	return false;
}
QuatT CAnimatedCharacter::MergeMCM(const QuatT& ent, const QuatT& anim, bool flat) const
{
	ANIMCHAR_PROFILE_DETAILED;

	CRY_ASSERT(ent.IsValid());
	CRY_ASSERT(anim.IsValid());

	EMovementControlMethod mcmh = GetMCMH();
	EMovementControlMethod mcmv = GetMCMV();

	CRY_ASSERT(mcmh >= 0 && mcmh < eMCM_COUNT);
	CRY_ASSERT(mcmv >= 0 && mcmv < eMCM_COUNT);

	if (mcmh == mcmv)
	{
		switch (mcmh /*or mcmv*/)
		{
		case eMCM_Entity:
		case eMCM_ClampedEntity:
		case eMCM_SmoothedEntity:
			return ent;
		case eMCM_DecoupledCatchUp:
		case eMCM_Animation:
		case eMCM_AnimationHCollision:
			return anim;
		default:
			GameWarning("CAnimatedCharacter::MergeMCM() - Horizontal & Vertical MCM %s not implemented!", g_szMCMString[mcmh]);
			return ent;
		}
	}

	QuatT mergedH, mergedV;
	switch (mcmh)
	{
		case eMCM_Entity:
		case eMCM_ClampedEntity:
		case eMCM_SmoothedEntity: 
			mergedH = ent; break;
		case eMCM_DecoupledCatchUp: 
		case eMCM_Animation:
		case eMCM_AnimationHCollision:
			mergedH = anim; break;
		default:
			mergedH = ent;
			GameWarning("CAnimatedCharacter::MergeMCM() - Horizontal MCM %s not implemented!", g_szMCMString[mcmh]);
			break;
	}

	switch (mcmv)
	{
		case eMCM_Entity: 
		case eMCM_ClampedEntity: 
		case eMCM_SmoothedEntity: 
			mergedV = ent; break;
		case eMCM_DecoupledCatchUp: 
		case eMCM_Animation: 
			mergedV = anim; break;
		default:
			mergedV = ent;
			GameWarning("CAnimatedCharacter::MergeMCM() - Vertical MCM %s not implemented!", g_szMCMString[mcmv]);
			break;
	}

	QuatT merged;
	if (flat)
		merged = CombineHVComponents2D(mergedH, mergedV);
	else
		merged = CombineHVComponents3D(mergedH, mergedV);

	CRY_ASSERT(merged.IsValid());
	return merged;
}