You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#lockdown Nick.Penwarden ========================== MAJOR FEATURES + CHANGES ========================== Change 2945310 on 2016/04/15 by Jon.Nabozny Fix UI locking Angular Rotation Offset for PhysicsConstraintComponents when the motion is for axes is Free or Locked. #JIRA UE-29368 Change 2945490 on 2016/04/15 by Jon.Nabozny Remove extraneous changes introduced in CL-2945310. Change 2946706 on 2016/04/18 by James.Golding Checkin of slice test assets Change 2947895 on 2016/04/19 by Benn.Gallagher PR #2292: Use ref instead of copy in FAnimNode_ModifyBone::EvaluateBoneTransforms (Contributed by MiKom) #jira UE-29567 Change 2947944 on 2016/04/19 by Benn.Gallagher Fixed a few extra needless bone container copies Change 2948279 on 2016/04/19 by Marc.Audy Add well defined Map and Set Property names Change 2948280 on 2016/04/19 by Marc.Audy Properly name parameters Change 2948792 on 2016/04/19 by Marc.Audy Remove unused ini class name settings Change 2948917 on 2016/04/19 by Aaron.McLeran UE-29654 FadeIn invalidates Audio Components in 4.11 Change 2949567 on 2016/04/20 by James.Golding - Add SliceProceduralMesh utility to UKismetProceduralMeshLibrary. It will slice the ProcMeshComp with a plan, including simple collision geom, and optionally create cap geometry, and create an addition ProceduralMeshComponent for the other half - Add support for simple collision on ProceduralMeshComponent, and added bUseComplexAsSimpleCollision to allow it to be used - Move GeomTools.h and .cpp from Editor to Engine module, so it can be used at runtime. Also move utils into an FGeomTools namespace. - Add GetSectionFromStaticMesh and CopyProceduralMeshFromStaticMeshComponent utilities to UKismetProceduralMeshLibrary - Expose UStaticMesh::GetNumLODs to BP, and add BP exposed UStaticMesh:: GetNumSections function Change 2950482 on 2016/04/20 by Aaron.McLeran FORT-22973 SoundMix Fade Time not fading audio properly - Bug was due to bApplyToChildren case where the FSoundClassAdjuster wasn't getting the interpolated value before calling RecursiveApplyAdjuster in the case of non-overriden sound mixes. Change 2951102 on 2016/04/21 by Thomas.Sarkanen Un-deprecated blueprint functions for attachment/detachment Renamed functions to <FuncName> (Deprecated). Hid functions in the BP context menu so new ones cant be added. #jira UE-23216 - "Snap to Target, Keep World Scale" when attaching doesn't work properly if parent is scaled. Change 2951173 on 2016/04/21 by James.Golding Fix cap geom generation when more than one polygon is generated Fix CIS warning in KismetProceduralMeshLibrary.cpp Change 2951334 on 2016/04/21 by Osman.Tsjardiwal Add CapMaterial param to SliceProceduralMesh util Change 2951528 on 2016/04/21 by Marc.Audy Fix spelling errors in comments Change 2952933 on 2016/04/22 by Lukasz.Furman fixed behavior tree getting stuck on instantly finished gameplay tasks copy of CL# 2952930 Change 2953948 on 2016/04/24 by James.Golding Put #if WITH_EDITOR back into FPoly::Triangulate to fix non-editor builds (FPoly::Finalize not available in non-editor) Change 2954558 on 2016/04/25 by Marc.Audy Make USceneComponent::Attach* members private and remove deprecation messages and pragmas disabling/enabling deprecation throughout SceneComponent.h/cpp #jira UE-29038 Change 2954865 on 2016/04/25 by Aaron.McLeran UE-29763 Use HMD audio device only in VR preview mode, not for other PIE session types. Change 2955009 on 2016/04/25 by Zak.Middleton #ue4 - Wrap call from UCharacterMovementComponent::PostPhysicsTickComponent() to UpdateBasedMovement() in a FScopedMovementUpdate to accumulate moves with better perf. Change 2955878 on 2016/04/26 by Benn.Gallagher [Epic Friday] - Added spherical constraints to anim dynamics Change 2956380 on 2016/04/26 by Lina.Halper PR #2298: Step interpolation for UAnimSequence (Contributed by douglaslassance) Change 2956383 on 2016/04/26 by Lina.Halper Fixed to match coding standard Change2957866on 2016/04/27 by Zak.Middleton #ue4 - Add max depenetration distance settings for CharacterMovementComponent. Add controls to throttle logging when character is stuck in geometry so it doesn't spam the log. - Depenetration settings are separated based on whether overlapping a Pawn versus other geometry, and furthermore by whether the Character is a proxy or not. Simulated proxies typically should not depenetrate a large amount because that effectively ignores the server authoritative location update. - "Stuck" logging is controlled by the console var "p.CharacterStuckWarningPeriod". Set to number of seconds between logged events, or less than zero to disable logging. #tests QA-Surfaces multiplayer, walking in to moving objects and pawns. Change 2957953 on 2016/04/27 by Aaron.McLeran UE-30018 Fixing up audio component ref-counting to prevent triggering notifications when an audio component is still active after a sound finishes playing. Change 2958011 on 2016/04/27 by Jon.Nabozny CalcAABB wasn't properly accounting for current transform on Convex elements, causing bad results. #JIRA UE-29525 Change 2958321 on 2016/04/27 by Lukasz.Furman path following update pass, added flags to request result, fixed AITask stacking vs scripted/BP move requests Change 2959506 on 2016/04/28 by Aaron.McLeran PR #2330: Fix for ambient sounds not stopping when active and told to play again (Contributed by hgamiel) Change 2959686 on 2016/04/28 by Marc.Audy Correctly handle multiple viewpoints when significance is being sorted descending Change 2959773 on 2016/04/28 by Marc.Audy Fix shadowing warning Change 2959785 on 2016/04/28 by Aaron.McLeran UE-30083 Sound concatenator node doesn't progress if child nodes don't produce wave instances Change 2960852 on 2016/04/29 by Marc.Audy Merging //UE4/Dev-Main to Dev-Framework (//UE4/Dev-Framework) @ 2960738 Change 2960946 on 2016/04/29 by Marc.Audy Fix post merge compile error Change 2962501 on 2016/05/02 by Marc.Audy Remove interim GetMutableAttach accessors and use the variables directly now that they are private Change 2962535 on 2016/05/02 by Marc.Audy Merging //UE4/Dev-Main to Dev-Framework (//UE4/Dev-Framework) @ 2962478 Change 2962578 on 2016/05/02 by Marc.Audy Switch ObjectGraphMove to using UserFlags instead of custom move data Change 2962651 on 2016/05/02 by Marc.Audy VS2015 shadow variable fixes Change 2962662 on 2016/05/02 by Lukasz.Furman deprecated old implementation of gameplay debugger #jira UE-30011 Change 2962919 on 2016/05/02 by Marc.Audy VS2015 shadow variable fixes Change 2963475 on 2016/05/02 by Mieszko.Zielinski Made SimpleMoveToLocation/Actor not reset velocity if agent not already at goal #UE4 #jira UE-30176 Change2964098on 2016/05/03 by Marc.Audy Spelling fix Change 2964099 on 2016/05/03 by Marc.Audy VS2015 shadow variable fixes Change 2964156 on 2016/05/03 by Marc.Audy VS2015 shadow variable fixes Change 2964272 on 2016/05/03 by Marc.Audy VS2015 Shadow Variable fixes Change 2964395 on 2016/05/03 by Marc.Audy VS2015 Shadow Variable Fixes Change 2964460 on 2016/05/03 by Marc.Audy Reschedule coolingdown tick functions during pause frames. #jira UE-30221 Change 2964666 on 2016/05/03 by Marc.Audy Fix shipping compile error [CL 2964775 by Marc Audy in Main branch]
226 lines
7.1 KiB
C++
226 lines
7.1 KiB
C++
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "AnimGraphRuntimePrivatePCH.h"
|
|
#include "BoneControllers/AnimNode_SpringBone.h"
|
|
#include "Animation/AnimInstanceProxy.h"
|
|
|
|
/////////////////////////////////////////////////////
|
|
// FAnimNode_SpringBone
|
|
|
|
FAnimNode_SpringBone::FAnimNode_SpringBone()
|
|
: bLimitDisplacement(false)
|
|
, MaxDisplacement(0.0f)
|
|
, SpringStiffness(50.0f)
|
|
, SpringDamping(4.0f)
|
|
, ErrorResetThresh(256.0f)
|
|
, bNoZSpring_DEPRECATED(false)
|
|
, bTranslateX(true)
|
|
, bTranslateY(true)
|
|
, bTranslateZ(true)
|
|
, bRotateX(false)
|
|
, bRotateY(false)
|
|
, bRotateZ(false)
|
|
, RemainingTime(0.f)
|
|
, bHadValidStrength(false)
|
|
, BoneLocation(FVector::ZeroVector)
|
|
, BoneVelocity(FVector::ZeroVector)
|
|
{
|
|
}
|
|
|
|
void FAnimNode_SpringBone::Initialize(const FAnimationInitializeContext& Context)
|
|
{
|
|
FAnimNode_SkeletalControlBase::Initialize(Context);
|
|
|
|
RemainingTime = 0.0f;
|
|
}
|
|
|
|
void FAnimNode_SpringBone::CacheBones(const FAnimationCacheBonesContext& Context)
|
|
{
|
|
FAnimNode_SkeletalControlBase::CacheBones(Context);
|
|
}
|
|
|
|
void FAnimNode_SpringBone::UpdateInternal(const FAnimationUpdateContext& Context)
|
|
{
|
|
FAnimNode_SkeletalControlBase::UpdateInternal(Context);
|
|
|
|
RemainingTime += Context.GetDeltaTime();
|
|
|
|
// Fixed step simulation at 120hz
|
|
FixedTimeStep = (1.f / 120.f) * TimeDilation;
|
|
}
|
|
|
|
void FAnimNode_SpringBone::GatherDebugData(FNodeDebugData& DebugData)
|
|
{
|
|
const float ActualBiasedAlpha = AlphaScaleBias.ApplyTo(Alpha);
|
|
|
|
//MDW_TODO Add more output info?
|
|
FString DebugLine = DebugData.GetNodeName(this);
|
|
DebugLine += FString::Printf(TEXT("(Alpha: %.1f%% RemainingTime: %.3f)"), ActualBiasedAlpha*100.f, RemainingTime);
|
|
|
|
DebugData.AddDebugItem(DebugLine);
|
|
ComponentPose.GatherDebugData(DebugData);
|
|
}
|
|
|
|
FORCEINLINE void CopyToVectorByFlags(FVector& DestVec, const FVector& SrcVec, bool bX, bool bY, bool bZ)
|
|
{
|
|
if (bX)
|
|
{
|
|
DestVec.X = SrcVec.X;
|
|
}
|
|
if (bY)
|
|
{
|
|
DestVec.Y = SrcVec.Y;
|
|
}
|
|
if (bZ)
|
|
{
|
|
DestVec.Z = SrcVec.Z;
|
|
}
|
|
}
|
|
|
|
void FAnimNode_SpringBone::EvaluateBoneTransforms(USkeletalMeshComponent* SkelComp, FCSPose<FCompactPose>& MeshBases, TArray<FBoneTransform>& OutBoneTransforms)
|
|
{
|
|
check(OutBoneTransforms.Num() == 0);
|
|
|
|
const bool bNoOffset = !bTranslateX && !bTranslateY && !bTranslateZ;
|
|
if (bNoOffset)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Location of our bone in world space
|
|
const FBoneContainer& BoneContainer = MeshBases.GetPose().GetBoneContainer();
|
|
|
|
const FCompactPoseBoneIndex SpringBoneIndex = SpringBone.GetCompactPoseIndex(BoneContainer);
|
|
const FTransform& SpaceBase = MeshBases.GetComponentSpaceTransform(SpringBoneIndex);
|
|
FTransform BoneTransformInWorldSpace = (SkelComp != NULL) ? SpaceBase * SkelComp->GetComponentToWorld() : SpaceBase;
|
|
|
|
FVector const TargetPos = BoneTransformInWorldSpace.GetLocation();
|
|
|
|
AActor* SkelOwner = (SkelComp != NULL) ? SkelComp->GetOwner() : NULL;
|
|
if ((SkelComp != NULL) && (SkelComp->GetAttachParent() != NULL) && (SkelOwner == NULL))
|
|
{
|
|
SkelOwner = SkelComp->GetAttachParent()->GetOwner();
|
|
}
|
|
|
|
// Init values first time
|
|
if (RemainingTime == 0.0f)
|
|
{
|
|
BoneLocation = TargetPos;
|
|
BoneVelocity = FVector::ZeroVector;
|
|
}
|
|
|
|
while (RemainingTime > FixedTimeStep)
|
|
{
|
|
// Update location of our base by how much our base moved this frame.
|
|
FVector const BaseTranslation = SkelOwner ? (SkelOwner->GetVelocity() * FixedTimeStep) : FVector::ZeroVector;
|
|
BoneLocation += BaseTranslation;
|
|
|
|
// Reinit values if outside reset threshold
|
|
if (((TargetPos - BoneLocation).SizeSquared() > (ErrorResetThresh*ErrorResetThresh)))
|
|
{
|
|
BoneLocation = TargetPos;
|
|
BoneVelocity = FVector::ZeroVector;
|
|
}
|
|
|
|
// Calculate error vector.
|
|
FVector const Error = (TargetPos - BoneLocation);
|
|
FVector const DampingForce = SpringDamping * BoneVelocity;
|
|
FVector const SpringForce = SpringStiffness * Error;
|
|
|
|
// Calculate force based on error and vel
|
|
FVector const Acceleration = SpringForce - DampingForce;
|
|
|
|
// Integrate velocity
|
|
// Make sure damping with variable frame rate actually dampens velocity. Otherwise Spring will go nuts.
|
|
float const CutOffDampingValue = 1.f/FixedTimeStep;
|
|
if (SpringDamping > CutOffDampingValue)
|
|
{
|
|
float const SafetyScale = CutOffDampingValue / SpringDamping;
|
|
BoneVelocity += SafetyScale * (Acceleration * FixedTimeStep);
|
|
}
|
|
else
|
|
{
|
|
BoneVelocity += (Acceleration * FixedTimeStep);
|
|
}
|
|
|
|
// Clamp velocity to something sane (|dX/dt| <= ErrorResetThresh)
|
|
float const BoneVelocityMagnitude = BoneVelocity.Size();
|
|
if (BoneVelocityMagnitude * FixedTimeStep > ErrorResetThresh)
|
|
{
|
|
BoneVelocity *= (ErrorResetThresh / (BoneVelocityMagnitude * FixedTimeStep));
|
|
}
|
|
|
|
// Integrate position
|
|
FVector const OldBoneLocation = BoneLocation;
|
|
FVector const DeltaMove = (BoneVelocity * FixedTimeStep);
|
|
BoneLocation += DeltaMove;
|
|
|
|
// Filter out spring translation based on our filter properties
|
|
CopyToVectorByFlags(BoneLocation, TargetPos, !bTranslateX, !bTranslateY, !bTranslateZ);
|
|
|
|
|
|
// If desired, limit error
|
|
if (bLimitDisplacement)
|
|
{
|
|
FVector CurrentDisp = BoneLocation - TargetPos;
|
|
// Too far away - project back onto sphere around target.
|
|
if (CurrentDisp.SizeSquared() > FMath::Square(MaxDisplacement))
|
|
{
|
|
FVector DispDir = CurrentDisp.GetSafeNormal();
|
|
BoneLocation = TargetPos + (MaxDisplacement * DispDir);
|
|
}
|
|
}
|
|
|
|
// Update velocity to reflect post processing done to bone location.
|
|
BoneVelocity = (BoneLocation - OldBoneLocation) / FixedTimeStep;
|
|
|
|
check( !BoneLocation.ContainsNaN() );
|
|
check( !BoneVelocity.ContainsNaN() );
|
|
|
|
RemainingTime -= FixedTimeStep;
|
|
}
|
|
|
|
// Now convert back into component space and output - rotation is unchanged.
|
|
FTransform OutBoneTM = SpaceBase;
|
|
OutBoneTM.SetLocation( SkelComp->GetComponentToWorld().InverseTransformPosition(BoneLocation) );
|
|
|
|
const bool bUseRotation = bRotateX || bRotateY || bRotateZ;
|
|
if (bUseRotation)
|
|
{
|
|
FCompactPoseBoneIndex ParentBoneIndex = MeshBases.GetPose().GetParentBoneIndex(SpringBoneIndex);
|
|
const FTransform& ParentSpaceBase = MeshBases.GetComponentSpaceTransform(ParentBoneIndex);
|
|
|
|
FVector ParentToTarget = (TargetPos - ParentSpaceBase.GetLocation()).GetSafeNormal();
|
|
FVector ParentToCurrent = (BoneLocation - ParentSpaceBase.GetLocation()).GetSafeNormal();
|
|
|
|
FQuat AdditionalRotation = FQuat::FindBetweenNormals(ParentToTarget, ParentToCurrent);
|
|
|
|
// Filter rotation based on our filter properties
|
|
FVector EularRot = AdditionalRotation.Euler();
|
|
CopyToVectorByFlags(EularRot, FVector::ZeroVector, !bRotateX, !bRotateY, !bRotateZ);
|
|
|
|
OutBoneTM.SetRotation(FQuat::MakeFromEuler(EularRot) * OutBoneTM.GetRotation());
|
|
}
|
|
|
|
// Output new transform for current bone.
|
|
OutBoneTransforms.Add(FBoneTransform(SpringBoneIndex, OutBoneTM));
|
|
}
|
|
|
|
|
|
bool FAnimNode_SpringBone::IsValidToEvaluate(const USkeleton* Skeleton, const FBoneContainer& RequiredBones)
|
|
{
|
|
return (SpringBone.IsValid(RequiredBones));
|
|
}
|
|
|
|
void FAnimNode_SpringBone::InitializeBoneReferences(const FBoneContainer& RequiredBones)
|
|
{
|
|
SpringBone.Initialize(RequiredBones);
|
|
}
|
|
|
|
void FAnimNode_SpringBone::PreUpdate(const UAnimInstance* InAnimInstance)
|
|
{
|
|
const USkeletalMeshComponent* SkelComp = InAnimInstance->GetSkelMeshComponent();
|
|
const UWorld* World = SkelComp->GetWorld();
|
|
check(World->GetWorldSettings());
|
|
TimeDilation = World->GetWorldSettings()->GetEffectiveTimeDilation();
|
|
} |