bool UAnimSingleNodeInstance::NativeEvaluateAnimation(FPoseContext& Output) { if (CurrentAsset != NULL) { //@TODO: animrefactor: Seems like more code duplication than we need if (UBlendSpaceBase* BlendSpace = Cast<UBlendSpaceBase>(CurrentAsset)) { InternalBlendSpaceEvaluatePose(BlendSpace, BlendSampleData, Output.Pose); } else if (UAnimSequence* Sequence = Cast<UAnimSequence>(CurrentAsset)) { if (Sequence->IsValidAdditive()) { FA2Pose BasePose; FA2Pose AdditivePose; BasePose.Bones.AddUninitialized(Output.Pose.Bones.Num()); AdditivePose.Bones.AddUninitialized(Output.Pose.Bones.Num()); FAnimExtractContext ExtractionContext(CurrentTime); Sequence->GetAdditiveBasePose(BasePose.Bones, RequiredBones, ExtractionContext); Sequence->GetAnimationPose(AdditivePose.Bones, RequiredBones, ExtractionContext); if (Sequence->AdditiveAnimType == AAT_LocalSpaceBase) { ApplyAdditiveSequence(BasePose, AdditivePose, 1.0f, Output.Pose); } else { BlendRotationOffset(BasePose, AdditivePose, 1.0f, Output.Pose); } } else { // if sekeltalmesh isn't there, we'll need to use skeleton FAnimationRuntime::GetPoseFromSequence(Sequence, RequiredBones, Output.Pose.Bones, FAnimExtractContext(CurrentTime, Sequence->bEnableRootMotion)); } } else if (UAnimComposite* Composite = Cast<UAnimComposite>(CurrentAsset)) { const FAnimTrack& AnimTrack = Composite->AnimationTrack; // find out if this is additive animation EAdditiveAnimationType AdditiveAnimType = AAT_None; if (AnimTrack.IsAdditive()) { FA2Pose AdditivePose; FA2Pose BasePose; BasePose.Bones.AddUninitialized(Output.Pose.Bones.Num()); AdditivePose.Bones.AddUninitialized(Output.Pose.Bones.Num()); AdditiveAnimType = AnimTrack.IsRotationOffsetAdditive()? AAT_RotationOffsetMeshSpace : AAT_LocalSpaceBase; // get base pose - for now we only support ref pose as base FAnimationRuntime::FillWithRefPose(BasePose.Bones, RequiredBones); //get the additive pose FAnimationRuntime::GetPoseFromAnimTrack(AnimTrack, RequiredBones, AdditivePose.Bones, FAnimExtractContext(CurrentTime, RootMotionMode == ERootMotionMode::RootMotionFromEverything)); // if additive, we should blend with source to make it fullbody if (AdditiveAnimType == AAT_LocalSpaceBase) { ApplyAdditiveSequence(BasePose,AdditivePose,1.f,Output.Pose); } else if (AdditiveAnimType == AAT_RotationOffsetMeshSpace) { BlendRotationOffset(BasePose,AdditivePose,1.f,Output.Pose); } } else { //doesn't handle additive yet FAnimationRuntime::GetPoseFromAnimTrack(AnimTrack, RequiredBones, Output.Pose.Bones, FAnimExtractContext(CurrentTime, RootMotionMode == ERootMotionMode::RootMotionFromEverything)); } } else if (UAnimMontage* Montage = Cast<UAnimMontage>(CurrentAsset)) { // for now only update first slot // in the future, add option to see which slot to see if (Montage->SlotAnimTracks.Num() > 0) { FA2Pose SourcePose; SourcePose.Bones.AddUninitialized(Output.Pose.Bones.Num()); if (Montage->IsValidAdditive()) { #if WITH_EDITORONLY_DATA // if montage is additive, we need to have base pose for the slot pose evaluate if (Montage->PreviewBasePose && Montage->SequenceLength > 0.f) { Montage->PreviewBasePose->GetBonePose(SourcePose.Bones, RequiredBones, FAnimExtractContext(CurrentTime)); } else #endif // WITH_EDITORONLY_DATA { FAnimationRuntime::FillWithRefPose(SourcePose.Bones, RequiredBones); } } else { FAnimationRuntime::FillWithRefPose(SourcePose.Bones, RequiredBones); } SlotEvaluatePose(Montage->SlotAnimTracks[0].SlotName, SourcePose, Output.Pose, 1.f); } } } if(CurrentVertexAnim != NULL) { VertexAnims.Add(FActiveVertexAnim(CurrentVertexAnim, 1.f, CurrentTime)); } return true; }
bool UAnimSingleNodeInstance::NativeEvaluateAnimation(FPoseContext& Output) { if (CurrentAsset != NULL) { //@TODO: animrefactor: Seems like more code duplication than we need if (UBlendSpaceBase* BlendSpace = Cast<UBlendSpaceBase>(CurrentAsset)) { InternalBlendSpaceEvaluatePose(BlendSpace, BlendSampleData, Output); } else if (UAnimSequence* Sequence = Cast<UAnimSequence>(CurrentAsset)) { if (Sequence->IsValidAdditive()) { FAnimExtractContext ExtractionContext(CurrentTime, Sequence->bEnableRootMotion); Sequence->GetAdditiveBasePose(Output.Pose, Output.Curve, ExtractionContext); FCompactPose AdditivePose; FBlendedCurve AdditiveCurve; AdditivePose.SetBoneContainer(&Output.Pose.GetBoneContainer()); AdditiveCurve.InitFrom(Output.Curve); Sequence->GetAnimationPose(AdditivePose, AdditiveCurve, ExtractionContext); FAnimationRuntime::AccumulateAdditivePose(Output.Pose, AdditivePose, Output.Curve, AdditiveCurve, 1.f, Sequence->AdditiveAnimType); Output.Pose.NormalizeRotations(); } else { // if SkeletalMesh isn't there, we'll need to use skeleton Sequence->GetAnimationPose(Output.Pose, Output.Curve, FAnimExtractContext(CurrentTime, Sequence->bEnableRootMotion)); } } else if (UAnimComposite* Composite = Cast<UAnimComposite>(CurrentAsset)) { FAnimExtractContext ExtractionContext(CurrentTime, ShouldExtractRootMotion()); const FAnimTrack& AnimTrack = Composite->AnimationTrack; // find out if this is additive animation if (AnimTrack.IsAdditive()) { #if WITH_EDITORONLY_DATA if (Composite->PreviewBasePose) { Composite->PreviewBasePose->GetAdditiveBasePose(Output.Pose, Output.Curve, ExtractionContext); } else #endif { // get base pose - for now we only support ref pose as base Output.Pose.ResetToRefPose(); } EAdditiveAnimationType AdditiveAnimType = AnimTrack.IsRotationOffsetAdditive()? AAT_RotationOffsetMeshSpace : AAT_LocalSpaceBase; FCompactPose AdditivePose; FBlendedCurve AdditiveCurve; AdditivePose.SetBoneContainer(&Output.Pose.GetBoneContainer()); AdditiveCurve.InitFrom(Output.Curve); Composite->GetAnimationPose(AdditivePose, AdditiveCurve, ExtractionContext); FAnimationRuntime::AccumulateAdditivePose(Output.Pose, AdditivePose, Output.Curve, AdditiveCurve, 1.f, AdditiveAnimType); } else { //doesn't handle additive yet Composite->GetAnimationPose(Output.Pose, Output.Curve, ExtractionContext); } } else if (UAnimMontage* Montage = Cast<UAnimMontage>(CurrentAsset)) { // for now only update first slot // in the future, add option to see which slot to see if (Montage->SlotAnimTracks.Num() > 0) { FCompactPose SourcePose; FBlendedCurve SourceCurve; SourcePose.SetBoneContainer(&Output.Pose.GetBoneContainer()); SourceCurve.InitFrom(Output.Curve); if (Montage->IsValidAdditive()) { #if WITH_EDITORONLY_DATA // if montage is additive, we need to have base pose for the slot pose evaluate if (Montage->PreviewBasePose && Montage->SequenceLength > 0.f) { Montage->PreviewBasePose->GetBonePose(SourcePose, SourceCurve, FAnimExtractContext(CurrentTime)); } else #endif // WITH_EDITORONLY_DATA { SourcePose.ResetToRefPose(); } } else { SourcePose.ResetToRefPose(); } SlotEvaluatePose(Montage->SlotAnimTracks[0].SlotName, SourcePose, SourceCurve, Output.Pose, Output.Curve, 1.f); } } } if(CurrentVertexAnim != NULL) { VertexAnims.Add(FActiveVertexAnim(CurrentVertexAnim, 1.f, CurrentTime)); } return true; }