void FAnimNode_HandIKRetargeting::EvaluateBoneTransforms(USkeletalMeshComponent* SkelComp, const FBoneContainer& RequiredBones, FA2CSPose& MeshBases, TArray<FBoneTransform>& OutBoneTransforms) { checkSlow(OutBoneTransforms.Num() == 0); // Get component space transforms for all of our IK and FK bones. FTransform const RightHandFKTM = MeshBases.GetComponentSpaceTransform(RightHandFK.BoneIndex); FTransform const LeftHandFKTM = MeshBases.GetComponentSpaceTransform(LeftHandFK.BoneIndex); FTransform const RightHandIKTM = MeshBases.GetComponentSpaceTransform(RightHandIK.BoneIndex); FTransform const LeftHandIKTM = MeshBases.GetComponentSpaceTransform(LeftHandIK.BoneIndex); // Compute weight FK and IK hand location. And translation from IK to FK. FVector const FKLocation = FMath::Lerp<FVector>(LeftHandFKTM.GetTranslation(), RightHandFKTM.GetTranslation(), HandFKWeight); FVector const IKLocation = FMath::Lerp<FVector>(LeftHandIKTM.GetTranslation(), RightHandIKTM.GetTranslation(), HandFKWeight); FVector const IK_To_FK_Translation = FKLocation - IKLocation; // If we're not translating, don't send any bones to update. if (!IK_To_FK_Translation.IsNearlyZero()) { // Move desired bones for (int32 BoneIndex = 0; BoneIndex < IKBonesToMove.Num(); BoneIndex++) { FBoneReference const & BoneReference = IKBonesToMove[BoneIndex]; if (BoneReference.IsValid(RequiredBones)) { FTransform BoneTransform = MeshBases.GetComponentSpaceTransform(BoneReference.BoneIndex); BoneTransform.AddToTranslation(IK_To_FK_Translation); OutBoneTransforms.Add(FBoneTransform(BoneReference.BoneIndex, BoneTransform)); } } } }
// Create a collision shape actor from a given shape name AActor* CreateCollisionShape( UWorld* World, const FString ShapeTypeName, FVector Location ) { AActor* TestRayCollisionActor = nullptr; FTransform CollisionTransform; CollisionTransform.AddToTranslation(Location); if (ShapeTypeName == TEXT("TriggerCapsule")) { TestRayCollisionActor = Cast<ATriggerCapsule>(GEditor->AddActor(World->GetCurrentLevel(), ATriggerCapsule::StaticClass(), CollisionTransform)); if (TestRayCollisionActor != nullptr) { UCapsuleComponent* Capsule = Cast<UCapsuleComponent>(TestRayCollisionActor->GetRootComponent()); if (Capsule != nullptr) { Capsule->SetCapsuleHalfHeight(100.0f); Capsule->SetCapsuleRadius(50.0f); } } } else if (ShapeTypeName == TEXT("TriggerBox")) { TestRayCollisionActor = Cast<ATriggerBox>(GEditor->AddActor(World->GetCurrentLevel(), ATriggerBox::StaticClass(), CollisionTransform)); } else if (ShapeTypeName == TEXT("TriggerSphere")) { TestRayCollisionActor = Cast<ATriggerSphere>(GEditor->AddActor(World->GetCurrentLevel(), ATriggerSphere::StaticClass(), CollisionTransform)); } TestBase->TestNotNull<AActor>(FString::Printf(TEXT("Failed to create Collision trigger%s."), *ShapeTypeName), TestRayCollisionActor); return TestRayCollisionActor; }
void FAnimNode_WheelHandler::EvaluateBoneTransforms(USkeletalMeshComponent* SkelComp, FCSPose<FCompactPose>& MeshBases, TArray<FBoneTransform>& OutBoneTransforms) { check(OutBoneTransforms.Num() == 0); const TArray<FWheelAnimData>& WheelAnimData = AnimInstanceProxy->GetWheelAnimData(); const FBoneContainer& BoneContainer = MeshBases.GetPose().GetBoneContainer(); for(const FWheelLookupData& Wheel : Wheels) { if (Wheel.BoneReference.IsValid(BoneContainer)) { FCompactPoseBoneIndex WheelSimBoneIndex = Wheel.BoneReference.GetCompactPoseIndex(BoneContainer); // the way we apply transform is same as FMatrix or FTransform // we apply scale first, and rotation, and translation // if you'd like to translate first, you'll need two nodes that first node does translate and second nodes to rotate. FTransform NewBoneTM = MeshBases.GetComponentSpaceTransform(WheelSimBoneIndex); FAnimationRuntime::ConvertCSTransformToBoneSpace(SkelComp, MeshBases, NewBoneTM, WheelSimBoneIndex, BCS_ComponentSpace); // Apply rotation offset const FQuat BoneQuat(WheelAnimData[Wheel.WheelIndex].RotOffset); NewBoneTM.SetRotation(BoneQuat * NewBoneTM.GetRotation()); // Apply loc offset NewBoneTM.AddToTranslation(WheelAnimData[Wheel.WheelIndex].LocOffset); // Convert back to Component Space. FAnimationRuntime::ConvertBoneSpaceTransformToCS(SkelComp, MeshBases, NewBoneTM, WheelSimBoneIndex, BCS_ComponentSpace); // add back to it OutBoneTransforms.Add(FBoneTransform(WheelSimBoneIndex, NewBoneTM)); } } }
void FAnimNode_WheelHandler::EvaluateBoneTransforms(USkeletalMeshComponent* SkelComp, const FBoneContainer& RequiredBones, FA2CSPose& MeshBases, TArray<FBoneTransform>& OutBoneTransforms) { check(OutBoneTransforms.Num() == 0); for(const auto & WheelSim : WheelSimulators) { if(WheelSim.BoneReference.IsValid(RequiredBones)) { // the way we apply transform is same as FMatrix or FTransform // we apply scale first, and rotation, and translation // if you'd like to translate first, you'll need two nodes that first node does translate and second nodes to rotate. FTransform NewBoneTM = MeshBases.GetComponentSpaceTransform(WheelSim.BoneReference.BoneIndex); FAnimationRuntime::ConvertCSTransformToBoneSpace(SkelComp, MeshBases, NewBoneTM, WheelSim.BoneReference.BoneIndex, BCS_ComponentSpace); // Apply rotation offset const FQuat BoneQuat(WheelSim.RotOffset); NewBoneTM.SetRotation(BoneQuat * NewBoneTM.GetRotation()); // Apply loc offset NewBoneTM.AddToTranslation(WheelSim.LocOffset); // Convert back to Component Space. FAnimationRuntime::ConvertBoneSpaceTransformToCS(SkelComp, MeshBases, NewBoneTM, WheelSim.BoneReference.BoneIndex, BCS_ComponentSpace); // add back to it OutBoneTransforms.Add( FBoneTransform(WheelSim.BoneReference.BoneIndex, NewBoneTM) ); } } }
void FAnimNode_HandIKRetargeting::EvaluateBoneTransforms(USkeletalMeshComponent* SkelComp, FCSPose<FCompactPose>& MeshBases, TArray<FBoneTransform>& OutBoneTransforms) { checkSlow(OutBoneTransforms.Num() == 0); const FBoneContainer& BoneContainer = MeshBases.GetPose().GetBoneContainer(); // Get component space transforms for all of our IK and FK bones. const FTransform& RightHandFKTM = MeshBases.GetComponentSpaceTransform(RightHandFK.GetCompactPoseIndex(BoneContainer)); const FTransform& LeftHandFKTM = MeshBases.GetComponentSpaceTransform(LeftHandFK.GetCompactPoseIndex(BoneContainer)); const FTransform& RightHandIKTM = MeshBases.GetComponentSpaceTransform(RightHandIK.GetCompactPoseIndex(BoneContainer)); const FTransform& LeftHandIKTM = MeshBases.GetComponentSpaceTransform(LeftHandIK.GetCompactPoseIndex(BoneContainer)); // Compute weight FK and IK hand location. And translation from IK to FK. FVector const FKLocation = FMath::Lerp<FVector>(LeftHandFKTM.GetTranslation(), RightHandFKTM.GetTranslation(), HandFKWeight); FVector const IKLocation = FMath::Lerp<FVector>(LeftHandIKTM.GetTranslation(), RightHandIKTM.GetTranslation(), HandFKWeight); FVector const IK_To_FK_Translation = FKLocation - IKLocation; // If we're not translating, don't send any bones to update. if (!IK_To_FK_Translation.IsNearlyZero()) { // Move desired bones for (const FBoneReference& BoneReference : IKBonesToMove) { if (BoneReference.IsValid(BoneContainer)) { FCompactPoseBoneIndex BoneIndex = BoneReference.GetCompactPoseIndex(BoneContainer); FTransform BoneTransform = MeshBases.GetComponentSpaceTransform(BoneIndex); BoneTransform.AddToTranslation(IK_To_FK_Translation); OutBoneTransforms.Add(FBoneTransform(BoneIndex, BoneTransform)); } } } }
void FAnimNode_ModifyFinger::EvaluateOneBoneTransforms(FBoneReference* BoneToModify, FRotator* Rotation, const FBoneContainer BoneContainer, FCSPose<FCompactPose> &MeshBases, USkeletalMeshComponent* SkelComp, TArray<FBoneTransform> &OutBoneTransforms) { FCompactPoseBoneIndex CompactPoseBoneToModify = BoneToModify->GetCompactPoseIndex(BoneContainer); FTransform NewBoneTM = MeshBases.GetComponentSpaceTransform(CompactPoseBoneToModify); if (RotationMode != BMM_Ignore) { // Convert to Bone Space. FAnimationRuntime::ConvertCSTransformToBoneSpace(SkelComp, MeshBases, NewBoneTM, CompactPoseBoneToModify, RotationSpace); const FQuat BoneQuat(*Rotation); if (RotationMode == BMM_Additive) { NewBoneTM.SetRotation(BoneQuat * NewBoneTM.GetRotation()); } else { NewBoneTM.SetRotation(BoneQuat); } // Convert back to Component Space. FAnimationRuntime::ConvertBoneSpaceTransformToCS(SkelComp, MeshBases, NewBoneTM, CompactPoseBoneToModify, RotationSpace); } if (ScaleMode != BMM_Ignore) { // Convert to Bone Space. FAnimationRuntime::ConvertCSTransformToBoneSpace(SkelComp, MeshBases, NewBoneTM, CompactPoseBoneToModify, ScaleSpace); if (ScaleMode == BMM_Additive) { NewBoneTM.SetScale3D(NewBoneTM.GetScale3D() * Scale); } else { NewBoneTM.SetScale3D(Scale); } // Convert back to Component Space. FAnimationRuntime::ConvertBoneSpaceTransformToCS(SkelComp, MeshBases, NewBoneTM, CompactPoseBoneToModify, ScaleSpace); } if (TranslationMode != BMM_Ignore) { // Convert to Bone Space. FAnimationRuntime::ConvertCSTransformToBoneSpace(SkelComp, MeshBases, NewBoneTM, CompactPoseBoneToModify, TranslationSpace); if (TranslationMode == BMM_Additive) { NewBoneTM.AddToTranslation(Translation1); } else { NewBoneTM.SetTranslation(Translation1); } // Convert back to Component Space. FAnimationRuntime::ConvertBoneSpaceTransformToCS(SkelComp, MeshBases, NewBoneTM, CompactPoseBoneToModify, TranslationSpace); } OutBoneTransforms.Add(FBoneTransform(BoneToModify->GetCompactPoseIndex(BoneContainer), NewBoneTM)); const float BlendWeight = FMath::Clamp<float>(Alpha, 0.f, 1.f); MeshBases.LocalBlendCSBoneTransforms(OutBoneTransforms, BlendWeight); OutBoneTransforms.Empty(); }
void FAnimNode_CopyBoneDelta::EvaluateBoneTransforms(USkeletalMeshComponent* SkelComp, FCSPose<FCompactPose>& MeshBases, TArray<FBoneTransform>& OutBoneTransforms) { if(!bCopyTranslation && !bCopyRotation && !bCopyScale) { return; } const FBoneContainer& BoneContainer = MeshBases.GetPose().GetBoneContainer(); FCompactPoseBoneIndex SourceBoneIndex = SourceBone.GetCompactPoseIndex(BoneContainer); FCompactPoseBoneIndex TargetBoneIndex = TargetBone.GetCompactPoseIndex(BoneContainer); FTransform SourceTM = MeshBases.GetComponentSpaceTransform(SourceBoneIndex); FTransform TargetTM = MeshBases.GetComponentSpaceTransform(TargetBoneIndex); // Convert to parent space FAnimationRuntime::ConvertCSTransformToBoneSpace(SkelComp, MeshBases, SourceTM, SourceBoneIndex, BCS_ParentBoneSpace); FAnimationRuntime::ConvertCSTransformToBoneSpace(SkelComp, MeshBases, TargetTM, TargetBoneIndex, BCS_ParentBoneSpace); // Ref pose transform FTransform RefLSTransform = SkelComp->SkeletalMesh->RefSkeleton.GetRefBonePose()[SourceBone.GetMeshPoseIndex().GetInt()]; // Get transform relative to ref pose SourceTM.SetToRelativeTransform(RefLSTransform); if(CopyMode == CopyBoneDeltaMode::Accumulate) { if(bCopyTranslation) { TargetTM.AddToTranslation(SourceTM.GetTranslation() * TranslationMultiplier); } if(bCopyRotation) { FVector Axis; float Angle; SourceTM.GetRotation().ToAxisAndAngle(Axis, Angle); TargetTM.SetRotation(FQuat(Axis, Angle * RotationMultiplier) * TargetTM.GetRotation()); } if(bCopyScale) { TargetTM.SetScale3D(TargetTM.GetScale3D() * (SourceTM.GetScale3D() * ScaleMultiplier)); } } else //CopyMode = CopyBoneDeltaMode::Copy { if(bCopyTranslation) { TargetTM.SetTranslation(SourceTM.GetTranslation() * TranslationMultiplier); } if(bCopyRotation) { FVector Axis; float Angle; SourceTM.GetRotation().ToAxisAndAngle(Axis, Angle); TargetTM.SetRotation(FQuat(Axis, Angle * RotationMultiplier)); } if(bCopyScale) { TargetTM.SetScale3D(SourceTM.GetScale3D() * ScaleMultiplier); } } // Back out to component space FAnimationRuntime::ConvertBoneSpaceTransformToCS(SkelComp, MeshBases, TargetTM, TargetBoneIndex, BCS_ParentBoneSpace); OutBoneTransforms.Add(FBoneTransform(TargetBoneIndex, TargetTM)); }
void FAnimNode_ModifyBone::EvaluateBoneTransforms(USkeletalMeshComponent* SkelComp, FCSPose<FCompactPose>& MeshBases, TArray<FBoneTransform>& OutBoneTransforms) { check(OutBoneTransforms.Num() == 0); // the way we apply transform is same as FMatrix or FTransform // we apply scale first, and rotation, and translation // if you'd like to translate first, you'll need two nodes that first node does translate and second nodes to rotate. const FBoneContainer BoneContainer = MeshBases.GetPose().GetBoneContainer(); FCompactPoseBoneIndex CompactPoseBoneToModify = BoneToModify.GetCompactPoseIndex(BoneContainer); FTransform NewBoneTM = MeshBases.GetComponentSpaceTransform(CompactPoseBoneToModify); if (ScaleMode != BMM_Ignore) { // Convert to Bone Space. FAnimationRuntime::ConvertCSTransformToBoneSpace(SkelComp, MeshBases, NewBoneTM, CompactPoseBoneToModify, ScaleSpace); if (ScaleMode == BMM_Additive) { NewBoneTM.SetScale3D(NewBoneTM.GetScale3D() * Scale); } else { NewBoneTM.SetScale3D(Scale); } // Convert back to Component Space. FAnimationRuntime::ConvertBoneSpaceTransformToCS(SkelComp, MeshBases, NewBoneTM, CompactPoseBoneToModify, ScaleSpace); } if (RotationMode != BMM_Ignore) { // Convert to Bone Space. FAnimationRuntime::ConvertCSTransformToBoneSpace(SkelComp, MeshBases, NewBoneTM, CompactPoseBoneToModify, RotationSpace); const FQuat BoneQuat(Rotation); if (RotationMode == BMM_Additive) { NewBoneTM.SetRotation(BoneQuat * NewBoneTM.GetRotation()); } else { NewBoneTM.SetRotation(BoneQuat); } // Convert back to Component Space. FAnimationRuntime::ConvertBoneSpaceTransformToCS(SkelComp, MeshBases, NewBoneTM, CompactPoseBoneToModify, RotationSpace); } if (TranslationMode != BMM_Ignore) { // Convert to Bone Space. FAnimationRuntime::ConvertCSTransformToBoneSpace(SkelComp, MeshBases, NewBoneTM, CompactPoseBoneToModify, TranslationSpace); if (TranslationMode == BMM_Additive) { NewBoneTM.AddToTranslation(Translation); } else { NewBoneTM.SetTranslation(Translation); } // Convert back to Component Space. FAnimationRuntime::ConvertBoneSpaceTransformToCS(SkelComp, MeshBases, NewBoneTM, CompactPoseBoneToModify, TranslationSpace); } OutBoneTransforms.Add( FBoneTransform(BoneToModify.GetCompactPoseIndex(BoneContainer), NewBoneTM) ); }