/* * 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. #ifndef CRYINCLUDE_CRYACTION_ANIMATION_POSEALIGNER_POSEALIGNER_H #define CRYINCLUDE_CRYACTION_ANIMATION_POSEALIGNER_POSEALIGNER_H #pragma once #include "ICryAnimation.h" #include #include namespace PoseAligner { class CChain; class CPose; class CVars { public: static const CVars& GetInstance() { static CVars instance; return instance; } public: CVars(); public: int m_enable; int m_debugDraw; int m_forceTargetSmoothing; int m_forceNoRootOffset; int m_forceNoIntersections; int m_forceWeightOne; int m_forceLock; }; #if ENABLE_CRY_PHYSICS class CContactReporter : public _i_reference_target { public: virtual bool Update(IPhysicalEntity* physicalEntity, Vec3& position, Vec3& normal) = 0; }; typedef _smart_ptr CContactReporterPtr; class CContactRaycast : public CContactReporter { public: CContactRaycast(IEntity* entity); public: void SetLength(float length) { m_length = length; } // CContactReporter public: bool Update(IPhysicalEntity* physicalEntity, Vec3& position, Vec3& normal) override; private: IEntity* m_pEntity; float m_length; }; typedef _smart_ptr CContactRaycastPtr; #endif // ENABLE_CRY_PHYSICS struct SChainDesc { public: const char* name; IAnimationPoseAlignerChain::EType eType; LimbIKDefinitionHandle solver; int targetBlendJointIndex; Vec3 offsetMin; Vec3 offsetMax; bool bBlendProcedural; bool bForceNoIntersection; bool bTargetSmoothing; #if ENABLE_CRY_PHYSICS CContactReporterPtr pContactReporter; #endif int contactJointIndex; public: SChainDesc() : name(NULL) , eType(IAnimationPoseAlignerChain::eType_Limb) , solver(0) , targetBlendJointIndex(-1) , offsetMin(ZERO) , offsetMax(ZERO) , bBlendProcedural(false) , bForceNoIntersection(false) , bTargetSmoothing(false) , contactJointIndex(-1) { } public: ILINE bool IsValid() const { #if ENABLE_CRY_PHYSICS if (!solver) { return false; } if (!pContactReporter) { return false; } if (contactJointIndex < 0) { return false; } return true; #else return false; #endif // ENABLE_CRY_PHYSICS } }; typedef _smart_ptr CChainPtr; class CChain : public _i_reference_target { public: static CChainPtr Create(const SChainDesc& desc); private: CChain(); public: void Reset(); void SetTargetForceWeightOne(bool bForce) { m_bTargetForceWeightOne = bForce; } const Vec3& GetTargetPosition() const { return m_targetPosition; } const Vec3& GetTargetPositionFiltered() const { return m_targetPositionFiltered; } void UpdateFromAnimations(ICharacterInstance& character, const QuatT& location, const float time); #if ENABLE_CRY_PHYSICS void FindContact(const QuatT& location, IPhysicalEntity* physicalEntity); #endif void FilterTargetLocation(const float time); float ComputeTargetBlendValue(ISkeletonPose& skeletonPose, const float time, const float weight); bool ComputeRootOffsetExtents(float& offsetMin, float& offsetMax); bool SetupStoreOperators(IAnimationOperatorQueue& operatorQueue); bool SetupTargetPoseModifiers(const QuatT& location, const Vec3& limitOffset, ISkeletonAnim& skeletonAnim); void DrawDebug(const QuatT& location); private: SChainDesc m_desc; Vec3 m_targetPosition; Vec3 m_targetPositionFiltered; Vec3 m_targetPositionFilteredSmoothRate; Vec3 m_targetNormal; Vec3 m_targetNormalFiltered; Vec3 m_targetNormalFilteredSmoothRate; float m_targetBlendWeight; float m_targetBlendWeightAnimated; float m_targetBlendWeightFiltered; float m_targetBlendWeightFilteredSmoothRate; Vec3 m_targetDelta; bool m_bTargetIntersecting; bool m_bTargetLock; bool m_bTargetForceWeightOne; IAnimationPoseAlignerChainPtr m_pPoseAlignerChain; IAnimationPoseModifierPtr m_pTargetLocation; QuatT m_targetPositionAnimation; Vec3 m_animationSlopeNormal; Vec3 m_animationSlopeNormalFiltered; Vec3 m_animationSlopeNormalFilteredSmoothRate; }; class CPose : public IAnimationPoseAligner { public: CRYINTERFACE_BEGIN() CRYINTERFACE_ADD(IAnimationPoseAligner) CRYINTERFACE_END() public: CPose(); virtual ~CPose(); public: bool Initialize(IEntity* entity, AZ::EntityId entityId, ICharacterInstance& character, int rootJointIndex); virtual bool Initialize(IEntity& entity) { return false; } virtual bool Initialize(AZ::EntityId id, ICharacterInstance& character) { return false; } void Reset(); void Clear(); CChainPtr CreateChain(const SChainDesc& desc); const uint GetChainCount() const { return uint(m_chains.size()); } CChainPtr GetChain(uint index) { return m_chains[index]; } void RemoveAllChains(); void SetRootOffsetEnable(bool bEnable) { m_bRootOffset = bEnable; } void SetRootOffsetMinMax(float offsetMin, float offsetMax) { m_rootOffsetMin = offsetMin; m_rootOffsetMax = offsetMax; } void SetRootOffsetAdditional(const Vec3& offset) { m_rootOffsetAdditional = offset; } void SetRootOffsetAverage(bool bRootOffsetAverage) { m_bRootOffsetAverage = bRootOffsetAverage; } void SetBlendWeight(float weight) { m_blendWeight = weight; } void Update(const QuatT& location, const float time); private: void SetupPoseModifiers(const QuatT& location); void DrawDebug(const QuatT& location, const Vec3& groundNormal); public: IEntity* m_pEntity; AZ::EntityId m_entityId; ICharacterInstance* m_pCharacter; ISkeletonAnim* m_pSkeletonAnim; ISkeletonPose* m_pSkeletonPose; IAnimationOperatorQueuePtr m_operatorQueue; int m_rootJointIndex; bool m_bRootOffset; bool m_bRootOffsetAverage; Vec3 m_rootOffsetDirection; Vec3 m_rootOffsetAdditional; float m_rootOffsetMin; float m_rootOffsetMax; float m_rootOffsetSmoothed; float m_rootOffsetSmoothedRate; DynArray m_chains; float m_blendWeight; // TEMP bool m_bInitialized; }; } // namespace PoseAligner #endif // CRYINCLUDE_CRYACTION_ANIMATION_POSEALIGNER_POSEALIGNER_H