/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. #include "CryLegacy_precompiled.h" #include "ICryMannequin.h" #include struct SAimAroundParams : public IProceduralParams { SAimAroundParams() : smoothTime(1.f) , scopeLayer(0) , yawMin(-1.f) , yawMax(1.f) , pitchMin(0.f) , pitchMax(0.5f) , timeMin(1.0f) , timeMax(2.0f) { } virtual void Serialize(Serialization::IArchive& ar) { ar(Serialization::Decorators::AnimationName(animRef), "Animation"); ar(smoothTime, "SmoothTime", "Smooth Time"); ar(Serialization::Decorators::Range(scopeLayer, 0, 15), "ScopeLayer", "Scope Layer"); ar(yawMin, "YawMin", "Yaw Min"); ar(yawMax, "YawMax", "Yaw Max"); ar(pitchMin, "PitchMin", "Pitch Min"); ar(pitchMax, "PitchMax", "Pitch Max"); ar(timeMin, "TimeMin", "Time Min"); ar(timeMax, "TimeMax", "Time Max"); } virtual void GetExtraDebugInfo(StringWrapper& extraInfoOut) const override { extraInfoOut = animRef.c_str(); } SAnimRef animRef; float smoothTime; uint32 scopeLayer; float yawMin; float yawMax; float pitchMin; float pitchMax; float timeMin; float timeMax; }; class CProceduralClipAimAround : public TProceduralClip { public: CProceduralClipAimAround(); virtual void OnEnter(float blendTime, float duration, const SAimAroundParams& params) { UpdateLookTarget(); Vec3 lookPos = m_entity->GetWorldPos(); lookPos += m_entity->GetRotation() * (m_lookOffset * 10.0f); const float smoothTime = params.smoothTime; const uint32 ikLayer = m_scope->GetBaseLayer() + params.scopeLayer; if (!params.animRef.IsEmpty()) { CryCharAnimationParams animParams; animParams.m_fTransTime = blendTime; animParams.m_nLayerID = ikLayer; animParams.m_nFlags = CA_LOOP_ANIMATION | CA_ALLOW_ANIM_RESTART; int animID = m_charInstance->GetIAnimationSet()->GetAnimIDByCRC(params.animRef.crc); m_charInstance->GetISkeletonAnim()->StartAnimationById(animID, animParams); } IAnimationPoseBlenderDir* poseBlenderAim = m_charInstance->GetISkeletonPose()->GetIPoseBlenderAim(); if (poseBlenderAim) { poseBlenderAim->SetState(true); poseBlenderAim->SetTarget(lookPos); poseBlenderAim->SetPolarCoordinatesSmoothTimeSeconds(smoothTime); poseBlenderAim->SetLayer(ikLayer); poseBlenderAim->SetFadeInSpeed(blendTime); } } virtual void OnExit(float blendTime) { IAnimationPoseBlenderDir* poseBlenderAim = m_charInstance->GetISkeletonPose()->GetIPoseBlenderAim(); if (poseBlenderAim) { poseBlenderAim->SetState(false); poseBlenderAim->SetFadeOutSpeed(blendTime); } } virtual void Update(float timePassed) { m_lookAroundTime -= timePassed; if (m_lookAroundTime < 0.0f) { UpdateLookTarget(); } Vec3 lookPos = m_entity->GetWorldPos(); lookPos += m_entity->GetRotation() * (m_lookOffset * 10.0f); IAnimationPoseBlenderDir* poseBlenderAim = m_charInstance->GetISkeletonPose()->GetIPoseBlenderAim(); if (poseBlenderAim) { poseBlenderAim->SetState(true); poseBlenderAim->SetTarget(lookPos); } } void UpdateLookTarget() { const SAimAroundParams& params = GetParams(); //--- TODO! Context use of random number generator! float yaw = cry_random(params.yawMin, params.yawMax); float pitch = cry_random(params.pitchMin, params.pitchMax); m_lookOffset.Set(sin_tpl(yaw), 0.0f, sin_tpl(pitch)); m_lookAroundTime = cry_random(params.timeMin, params.timeMax); } public: float m_lookAroundTime; Vec3 m_lookOffset; }; CProceduralClipAimAround::CProceduralClipAimAround() : m_lookAroundTime(0) , m_lookOffset(ZERO) { } REGISTER_PROCEDURAL_CLIP(CProceduralClipAimAround, "RandomAimAround");