diff --git a/Content/MatFootRest1.uasset b/Content/MatFootRest1.uasset new file mode 100644 index 0000000000000000000000000000000000000000..be5a593e3339d95ec5c6f8be66e535beab3437ec --- /dev/null +++ b/Content/MatFootRest1.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9a68c2e371cad7f2e07cf025dc20583cd3ab565e40016a1de85c59c3bc1153f6 +size 84063 diff --git a/Content/MoCapMap.umap b/Content/MoCapMap.umap index 80948ac3806f02060b776ea40b45621104e6ac1d..0ba0792297bde7d6ed45a31d8c80185596d47ccb 100644 --- a/Content/MoCapMap.umap +++ b/Content/MoCapMap.umap @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ad2b88803d2034732601fe2e6868c8f8599ecb347bf41b58e7a86ce6dbd739a4 -size 35369 +oid sha256:0c680860cf807bd176a7dc19790bb4494101f8716f9da7f7ed80130a29b409a6 +size 87739 diff --git a/Content/SaveSequenceAnimBP.uasset b/Content/SaveSequenceAnimBP.uasset index a0fd833ee3dee7011f0ebccb37372b340ecf274a..61831980797268f6b948a5cdffe58b68900da190 100644 --- a/Content/SaveSequenceAnimBP.uasset +++ b/Content/SaveSequenceAnimBP.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1cc6fe736ef960476d55b66fb8dec90628b3c630dc384c80409c6d0dd4649058 -size 210290 +oid sha256:2e9b9d5004c4aba2a80268adc506064048a197bf49d93d5a793f4c03797d0e68 +size 213709 diff --git a/Content/SaveSequenceRig.uasset b/Content/SaveSequenceRig.uasset index f4f8ac454bc254e0e239bbc86f176ff176fa91f4..f6c4fd2acfa997071dd195658ebd86c76452a519 100644 --- a/Content/SaveSequenceRig.uasset +++ b/Content/SaveSequenceRig.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f9dbb0d293961c9daa5bd3a30d51d058e9590892fd0b1f60b4ecae1f23492c69 -size 4927211 +oid sha256:a6af6dbc0b03a74a19035c95d8de6dc8fe6d5ab175a8ca6c942ca75b88af1571 +size 5000395 diff --git a/Source/MoCapPlugin/Private/MCController.cpp b/Source/MoCapPlugin/Private/MCController.cpp index 0992e414e6ce5cc809d041a4e1e49bfc16e5a6d8..470562bec3f20e25052611e7b83cb19916fb36b1 100644 --- a/Source/MoCapPlugin/Private/MCController.cpp +++ b/Source/MoCapPlugin/Private/MCController.cpp @@ -37,12 +37,18 @@ void AMCController::BeginPlay() { APlayerController* Controller = UGameplayStatics::GetPlayerController(GetWorld(), 0); EnableInput(Controller); - if (InputComponent != nullptr) { + if (SetControls && InputComponent != nullptr) { InputComponent->BindAction("ToggleRecording", EInputEvent::IE_Pressed, this, &AMCController::ToggleRecording); InputComponent->BindAction("SetMarker", EInputEvent::IE_Pressed, this, &AMCController::SetMarker); + InputComponent->BindAction("StartRecording", EInputEvent::IE_Pressed, this, &AMCController::ToggleRecording); + InputComponent->BindAction("NextSentence", EInputEvent::IE_Pressed, this, &AMCController::SetMarker); InputComponent->BindAction("SaveAnimation", EInputEvent::IE_Pressed, this, &AMCController::SaveAnimation); } + if (!Pawn || !Pawn->GetActorLocation().Equals(FVector(0, 0, 0)) || !Pawn->GetActorRotation().Equals(FRotator(0, 0, 0))) { + GEngine->AddOnScreenDebugMessage(-1, 30.0f, FColor::Red, FString::Printf(TEXT("Pawn for Recording in MCController is not positioned at 0, 0, 0 with rotation 0, 0, 0. This can lead to unwanted offsets."), *NameOfRecording)); + } + Pawn->LoadMeasurementFile(MeasurementPath); Pawn->GetAnimInstance()->PawnOwner = Pawn; if (bFingerTrackingEnabled) { @@ -54,6 +60,8 @@ void AMCController::BeginPlay() { Pawn->VRCamera->SetWorldRotation(SpectatorCam->GetActorRotation()); } + LastAddOffsets = AdditionalOffsets; + } void AMCController::Tick(float DeltaTime) { @@ -94,7 +102,7 @@ void AMCController::Tick(float DeltaTime) { } } - if (IsSavingToAnim) { + if (!EditOffsetMode && IsSavingToAnim) { SaveToAnimMode(); } @@ -155,6 +163,23 @@ void AMCController::SaveToAnimMode() { } +void AMCController::NextEditFrame() { + InputNextFrame(); +} + +void AMCController::PrevEditFrame() { + AnimSaveState.CurrentEntryIndex -= 2; + if (AnimSaveState.CurrentEntryIndex < 0) { + AnimSaveState.CurrentEntryIndex = 0; + } + InputNextFrame(); +} + +void AMCController::FinishEditAnim() { + IsSavingToAnim = false; + AnimSaveState = FAnimSaveState(); +} + void AMCController::ScaleAnimDataInterval(int start, int end, float DeltaTime) { FTimespan StartTime = AnimSaveState.AnimData[start].Timestamp; @@ -591,6 +616,67 @@ void AMCController::PreprocessRecording() { } + //---adjust feet position so that they are located at the green foot indicators--- + + int amount = 0; + int start = 0; + + for (int i = 0; i < AnimSaveState.AnimData.Num() && LockFeet; i++) { + + FProcessedAnimData& AnimData = AnimSaveState.AnimData[i]; + + if (AnimData.IsMarker || AnimData.IsEnd) { + + FVector cog(0, 0, 0); + for (int j = start; j < i; j++) { + FSensorData& SensorData = AnimSaveState.AnimData[j].SensorData; + FVector LPos = SensorData.GetEntry(EBodyPart::LowerLegL)->Pos; + FQuat LRot = SensorData.GetEntry(EBodyPart::LowerLegL)->Rot; + Pawn->OffsetSensorData(EBodyPart::LowerLegL, LPos, LRot); + FVector RPos = SensorData.GetEntry(EBodyPart::LowerLegR)->Pos; + FQuat RRot = SensorData.GetEntry(EBodyPart::LowerLegR)->Rot; + Pawn->OffsetSensorData(EBodyPart::LowerLegR, RPos, RRot); + cog += 0.5f * (LPos + RPos) * (1.f / amount); + } + + FVector shiftAmount = 0.5f * (LeftFootPlane->GetActorLocation() + RightFootPlane->GetActorLocation()) - cog - FVector(0, 10, 0); + shiftAmount.Z = 0; + for (int j = start; j < i; j++) { + FSensorData& SensorData = AnimSaveState.AnimData[j].SensorData; + for (int k = 0; k < EBodyPart::LAST; k++) { + EBodyPart Type = EBodyPart(k); + FSensorDataEntry* Entry = SensorData.GetEntry(Type); + Entry->Pos += shiftAmount; + } + } + + for (int j = start; j < i; j++) { + FSensorData& SensorData = AnimSaveState.AnimData[j].SensorData; + FVector LPos = SensorData.GetEntry(EBodyPart::LowerLegL)->Pos; + FQuat LRot = SensorData.GetEntry(EBodyPart::LowerLegL)->Rot; + Pawn->OffsetSensorData(EBodyPart::LowerLegL, LPos, LRot); + FVector RPos = SensorData.GetEntry(EBodyPart::LowerLegR)->Pos; + FQuat RRot = SensorData.GetEntry(EBodyPart::LowerLegR)->Rot; + Pawn->OffsetSensorData(EBodyPart::LowerLegR, RPos, RRot); + + shiftAmount = LeftFootPlane->GetActorLocation() - LPos - FVector(-4, 10, 0); + SensorData.GetEntry(EBodyPart::LowerLegL)->Pos.X += shiftAmount.X; + SensorData.GetEntry(EBodyPart::LowerLegL)->Pos.Y += shiftAmount.Y; + shiftAmount = RightFootPlane->GetActorLocation() - RPos - FVector(4, 10, 0); + SensorData.GetEntry(EBodyPart::LowerLegR)->Pos.X += shiftAmount.X; + SensorData.GetEntry(EBodyPart::LowerLegR)->Pos.Y += shiftAmount.Y; + } + + + amount = 0; + start = i + 1; + continue; + } + + amount++; + + } + AnimSaveState.NextFrame = FTimespan(); @@ -647,7 +733,9 @@ void AMCController::InputNextFrame() { AnimSaveState.Pawn->AICalcFrame(); stop = true; - AnimSaveState.WaitForAnimInstance = true; + if (!EditOffsetMode) { + AnimSaveState.WaitForAnimInstance = true; + } FeedbackWidget->ProgBar->SetPercent((float)AnimSaveState.CurrentEntryIndex / (float)AnimSaveState.AnimData.Num()); @@ -790,6 +878,199 @@ void AMCController::SetBonesAnimationInAnimSeq(const FSnapshotAnimations& Record } +#if WITH_EDITOR +void AMCController::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) { + Super::PostEditChangeProperty(PropertyChangedEvent); + + FProperty* prop = PropertyChangedEvent.Property; + FFloatProperty* fprop = CastField<FFloatProperty>(prop); + if (fprop != nullptr) { + + float* val = nullptr; + { + if (LastAddOffsets.HeadRotOffset.Roll != AdditionalOffsets.HeadRotOffset.Roll) { + val = &AdditionalOffsets.HeadRotOffset.Roll; + } + if (LastAddOffsets.HeadRotOffset.Yaw != AdditionalOffsets.HeadRotOffset.Yaw) { + val = &AdditionalOffsets.HeadRotOffset.Yaw; + } + if (LastAddOffsets.HeadRotOffset.Pitch != AdditionalOffsets.HeadRotOffset.Pitch) { + val = &AdditionalOffsets.HeadRotOffset.Pitch; + } + if (LastAddOffsets.HeadPosOffset.X != AdditionalOffsets.HeadPosOffset.X) { + val = &AdditionalOffsets.HeadPosOffset.X; + } + if (LastAddOffsets.HeadPosOffset.Y != AdditionalOffsets.HeadPosOffset.Y) { + val = &AdditionalOffsets.HeadPosOffset.Y; + } + if (LastAddOffsets.HeadPosOffset.Z != AdditionalOffsets.HeadPosOffset.Z) { + val = &AdditionalOffsets.HeadPosOffset.Z; + } + + if (LastAddOffsets.HandLRotOffset.Roll != AdditionalOffsets.HandLRotOffset.Roll) { + val = &AdditionalOffsets.HandLRotOffset.Roll; + } + if (LastAddOffsets.HandLRotOffset.Yaw != AdditionalOffsets.HandLRotOffset.Yaw) { + val = &AdditionalOffsets.HandLRotOffset.Yaw; + } + if (LastAddOffsets.HandLRotOffset.Pitch != AdditionalOffsets.HandLRotOffset.Pitch) { + val = &AdditionalOffsets.HandLRotOffset.Pitch; + } + if (LastAddOffsets.HandLPosOffset.X != AdditionalOffsets.HandLPosOffset.X) { + val = &AdditionalOffsets.HandLPosOffset.X; + } + if (LastAddOffsets.HandLPosOffset.Y != AdditionalOffsets.HandLPosOffset.Y) { + val = &AdditionalOffsets.HandLPosOffset.Y; + } + if (LastAddOffsets.HandLPosOffset.Z != AdditionalOffsets.HandLPosOffset.Z) { + val = &AdditionalOffsets.HandLPosOffset.Z; + } + + if (LastAddOffsets.HandRRotOffset.Roll != AdditionalOffsets.HandRRotOffset.Roll) { + val = &AdditionalOffsets.HandRRotOffset.Roll; + } + if (LastAddOffsets.HandRRotOffset.Yaw != AdditionalOffsets.HandRRotOffset.Yaw) { + val = &AdditionalOffsets.HandRRotOffset.Yaw; + } + if (LastAddOffsets.HandRRotOffset.Pitch != AdditionalOffsets.HandRRotOffset.Pitch) { + val = &AdditionalOffsets.HandRRotOffset.Pitch; + } + if (LastAddOffsets.HandRPosOffset.X != AdditionalOffsets.HandRPosOffset.X) { + val = &AdditionalOffsets.HandRPosOffset.X; + } + if (LastAddOffsets.HandRPosOffset.Y != AdditionalOffsets.HandRPosOffset.Y) { + val = &AdditionalOffsets.HandRPosOffset.Y; + } + if (LastAddOffsets.HandRPosOffset.Z != AdditionalOffsets.HandRPosOffset.Z) { + val = &AdditionalOffsets.HandRPosOffset.Z; + } + + if (LastAddOffsets.LowerLegRRotOffset.Roll != AdditionalOffsets.LowerLegRRotOffset.Roll) { + val = &AdditionalOffsets.LowerLegRRotOffset.Roll; + } + if (LastAddOffsets.LowerLegRRotOffset.Yaw != AdditionalOffsets.LowerLegRRotOffset.Yaw) { + val = &AdditionalOffsets.LowerLegRRotOffset.Yaw; + } + if (LastAddOffsets.LowerLegRRotOffset.Pitch != AdditionalOffsets.LowerLegRRotOffset.Pitch) { + val = &AdditionalOffsets.LowerLegRRotOffset.Pitch; + } + if (LastAddOffsets.LowerLegRPosOffset.X != AdditionalOffsets.LowerLegRPosOffset.X) { + val = &AdditionalOffsets.LowerLegRPosOffset.X; + } + if (LastAddOffsets.LowerLegRPosOffset.Y != AdditionalOffsets.LowerLegRPosOffset.Y) { + val = &AdditionalOffsets.LowerLegRPosOffset.Y; + } + if (LastAddOffsets.LowerLegRPosOffset.Z != AdditionalOffsets.LowerLegRPosOffset.Z) { + val = &AdditionalOffsets.LowerLegRPosOffset.Z; + } + + if (LastAddOffsets.LowerLegLRotOffset.Roll != AdditionalOffsets.LowerLegLRotOffset.Roll) { + val = &AdditionalOffsets.LowerLegLRotOffset.Roll; + } + if (LastAddOffsets.LowerLegLRotOffset.Yaw != AdditionalOffsets.LowerLegLRotOffset.Yaw) { + val = &AdditionalOffsets.LowerLegLRotOffset.Yaw; + } + if (LastAddOffsets.LowerLegLRotOffset.Pitch != AdditionalOffsets.LowerLegLRotOffset.Pitch) { + val = &AdditionalOffsets.LowerLegLRotOffset.Pitch; + } + if (LastAddOffsets.LowerLegLPosOffset.X != AdditionalOffsets.LowerLegLPosOffset.X) { + val = &AdditionalOffsets.LowerLegLPosOffset.X; + } + if (LastAddOffsets.LowerLegLPosOffset.Y != AdditionalOffsets.LowerLegLPosOffset.Y) { + val = &AdditionalOffsets.LowerLegLPosOffset.Y; + } + if (LastAddOffsets.LowerLegLPosOffset.Z != AdditionalOffsets.LowerLegLPosOffset.Z) { + val = &AdditionalOffsets.LowerLegLPosOffset.Z; + } + + if (LastAddOffsets.LowerArmLRotOffset.Roll != AdditionalOffsets.LowerArmLRotOffset.Roll) { + val = &AdditionalOffsets.LowerArmLRotOffset.Roll; + } + if (LastAddOffsets.LowerArmLRotOffset.Yaw != AdditionalOffsets.LowerArmLRotOffset.Yaw) { + val = &AdditionalOffsets.LowerArmLRotOffset.Yaw; + } + if (LastAddOffsets.LowerArmLRotOffset.Pitch != AdditionalOffsets.LowerArmLRotOffset.Pitch) { + val = &AdditionalOffsets.LowerArmLRotOffset.Pitch; + } + if (LastAddOffsets.LowerArmLPosOffset.X != AdditionalOffsets.LowerArmLPosOffset.X) { + val = &AdditionalOffsets.LowerArmLPosOffset.X; + } + if (LastAddOffsets.LowerArmLPosOffset.Y != AdditionalOffsets.LowerArmLPosOffset.Y) { + val = &AdditionalOffsets.LowerArmLPosOffset.Y; + } + if (LastAddOffsets.LowerArmLPosOffset.Z != AdditionalOffsets.LowerArmLPosOffset.Z) { + val = &AdditionalOffsets.LowerArmLPosOffset.Z; + } + + if (LastAddOffsets.LowerArmRRotOffset.Roll != AdditionalOffsets.LowerArmRRotOffset.Roll) { + val = &AdditionalOffsets.LowerArmRRotOffset.Roll; + } + if (LastAddOffsets.LowerArmRRotOffset.Yaw != AdditionalOffsets.LowerArmRRotOffset.Yaw) { + val = &AdditionalOffsets.LowerArmRRotOffset.Yaw; + } + if (LastAddOffsets.LowerArmRRotOffset.Pitch != AdditionalOffsets.LowerArmRRotOffset.Pitch) { + val = &AdditionalOffsets.LowerArmRRotOffset.Pitch; + } + if (LastAddOffsets.LowerArmRPosOffset.X != AdditionalOffsets.LowerArmRPosOffset.X) { + val = &AdditionalOffsets.LowerArmRPosOffset.X; + } + if (LastAddOffsets.LowerArmRPosOffset.Y != AdditionalOffsets.LowerArmRPosOffset.Y) { + val = &AdditionalOffsets.LowerArmRPosOffset.Y; + } + if (LastAddOffsets.LowerArmRPosOffset.Z != AdditionalOffsets.LowerArmRPosOffset.Z) { + val = &AdditionalOffsets.LowerArmRPosOffset.Z; + } + + if (LastAddOffsets.LowerBodyRotOffset.Roll != AdditionalOffsets.LowerBodyRotOffset.Roll) { + val = &AdditionalOffsets.LowerBodyRotOffset.Roll; + } + if (LastAddOffsets.LowerBodyRotOffset.Yaw != AdditionalOffsets.LowerBodyRotOffset.Yaw) { + val = &AdditionalOffsets.LowerBodyRotOffset.Yaw; + } + if (LastAddOffsets.LowerBodyRotOffset.Pitch != AdditionalOffsets.LowerBodyRotOffset.Pitch) { + val = &AdditionalOffsets.LowerBodyRotOffset.Pitch; + } + if (LastAddOffsets.LowerBodyPosOffset.X != AdditionalOffsets.LowerBodyPosOffset.X) { + val = &AdditionalOffsets.LowerBodyPosOffset.X; + } + if (LastAddOffsets.LowerBodyPosOffset.Y != AdditionalOffsets.LowerBodyPosOffset.Y) { + val = &AdditionalOffsets.LowerBodyPosOffset.Y; + } + if (LastAddOffsets.LowerBodyPosOffset.Z != AdditionalOffsets.LowerBodyPosOffset.Z) { + val = &AdditionalOffsets.LowerBodyPosOffset.Z; + } + + if (LastAddOffsets.UpperBodyRotOffset.Roll != AdditionalOffsets.UpperBodyRotOffset.Roll) { + val = &AdditionalOffsets.UpperBodyRotOffset.Roll; + } + if (LastAddOffsets.UpperBodyRotOffset.Yaw != AdditionalOffsets.UpperBodyRotOffset.Yaw) { + val = &AdditionalOffsets.UpperBodyRotOffset.Yaw; + } + if (LastAddOffsets.UpperBodyRotOffset.Pitch != AdditionalOffsets.UpperBodyRotOffset.Pitch) { + val = &AdditionalOffsets.UpperBodyRotOffset.Pitch; + } + if (LastAddOffsets.UpperBodyPosOffset.X != AdditionalOffsets.UpperBodyPosOffset.X) { + val = &AdditionalOffsets.UpperBodyPosOffset.X; + } + if (LastAddOffsets.UpperBodyPosOffset.Y != AdditionalOffsets.UpperBodyPosOffset.Y) { + val = &AdditionalOffsets.UpperBodyPosOffset.Y; + } + if (LastAddOffsets.UpperBodyPosOffset.Z != AdditionalOffsets.UpperBodyPosOffset.Z) { + val = &AdditionalOffsets.UpperBodyPosOffset.Z; + } + } + + if (val != nullptr) { + UObject* DefaultObject = GetClass()->GetDefaultObject(); + //fprop->SetPropertyValue_InContainer(DefaultObject, *val); + LastAddOffsets = AdditionalOffsets; + } + } + + +} +#endif + void AMCController::ToggleRecording() { if (IsSavingToAnim) { return; @@ -816,7 +1097,9 @@ void AMCController::ToggleRecording() { FeedbackWidget->ProgBar->SetVisibility(ESlateVisibility::Hidden); } else { - Pawn->SetMeshVisibility(true); + if (!KeepPawnInvisible) { + Pawn->SetMeshVisibility(true); + } LogHandler.StopRecording(); LogHandler.WriteToLogFile(); FString OldName = NameOfRecording; @@ -824,7 +1107,9 @@ void AMCController::ToggleRecording() { if (OldName != NameOfRecording) { InstructionWidget->FeedbackText->SetText(FText::FromString("Recording Done!\nNameOfRecording changed to " + NameOfRecording)); - GEngine->AddOnScreenDebugMessage(-1, 30.0f, FColor::Yellow, FString::Printf(TEXT("NameOfRecording changed to %s. If you want to use this recording in future play sessions, please update the property on MCController."), *NameOfRecording)); + if (OutputMsgOnScreen) { + GEngine->AddOnScreenDebugMessage(-1, 30.0f, FColor::Yellow, FString::Printf(TEXT("NameOfRecording changed to %s. If you want to use this recording in future play sessions, please update the property on MCController."), *NameOfRecording)); + } } InstructionWidget->FeedbackText->SetText(FText::FromString("Recording Done!")); @@ -915,13 +1200,16 @@ void AMCController::SaveAnimation() { AnimSaveState.Pawn = Pawn; AnimSaveState.Pawn->GetAnimInstance()->DoFingers = bFingerTrackingEnabled; + AnimSaveState.Pawn->GetAnimInstance()->LockFeet = LockFeet; AnimSaveState.Pawn->GetAnimInstance()->SnapshotAnimations.Empty(); AnimSaveState.FPS = FramesPerSecond; AnimSaveState.SPF = 1.f / ((float)AnimSaveState.FPS); IsSavingToAnim = true; - AnimSaveState.WaitForAnimInstance = true; + if (!EditOffsetMode) { + AnimSaveState.WaitForAnimInstance = true; + } AnimSaveState.Pawn->GetAnimInstance()->AdditionalOffsets = AdditionalOffsets; diff --git a/Source/MoCapPlugin/Public/MCAnimInstance.h b/Source/MoCapPlugin/Public/MCAnimInstance.h index afd444d25ab8fb167cdcc8f632db63e3233dac46..7531b1ec87d3973ba42d0c745057b365647d2c8c 100644 --- a/Source/MoCapPlugin/Public/MCAnimInstance.h +++ b/Source/MoCapPlugin/Public/MCAnimInstance.h @@ -50,6 +50,9 @@ public: UPROPERTY(BlueprintReadWrite) bool DoRig; + UPROPERTY(BlueprintReadWrite) + bool LockFeet; + virtual void NativeInitializeAnimation() override; virtual void NativeUpdateAnimation(float DeltaSeconds) override; diff --git a/Source/MoCapPlugin/Public/MCController.h b/Source/MoCapPlugin/Public/MCController.h index 792b3ec37ed8be667dbd9be1daa0b3563015ca80..4fd06c896e13d81003a052e30455e6a91c0e9d74 100644 --- a/Source/MoCapPlugin/Public/MCController.h +++ b/Source/MoCapPlugin/Public/MCController.h @@ -56,6 +56,9 @@ protected: bool DebugMode = false; bool UseLastOffsets = false; + bool SetControls = true; + bool KeepPawnInvisible = false; + bool OutputMsgOnScreen = true; public: @@ -82,6 +85,15 @@ protected: UFUNCTION(BlueprintCallable) void SaveAnimation(); + UFUNCTION(BlueprintCallable) + void NextEditFrame(); + + UFUNCTION(BlueprintCallable) + void PrevEditFrame(); + + UFUNCTION(BlueprintCallable) + void FinishEditAnim(); + void RecordMode(); void SaveToAnimMode(); @@ -92,6 +104,10 @@ protected: void SaveAnimSnapshots(); UAnimSequence* SaveAsAnimSequence(const FSnapshotAnimations& Recording, const FString& AnimName, const FString& FolderName); void SetBonesAnimationInAnimSeq(const FSnapshotAnimations& Recording, UAnimSequence* AnimSequence); + +#if WITH_EDITOR + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override; +#endif TSubclassOf<AActor> InstructionWidgetObjClass; AActor* InstructionWidgetObj; @@ -145,7 +161,21 @@ public: UPROPERTY(EditAnywhere, meta = (DisplayName = "Leg Smoothing Neighbor Window", Category = "MotionCapture")) int LegSmoothWindow = 3; + UPROPERTY(EditAnywhere, meta = (DisplayName = "Left Foot Plane", Category = "MotionCapture")) + AActor* LeftFootPlane; + + UPROPERTY(EditAnywhere, meta = (DisplayName = "Right Foot Plane", Category = "MotionCapture")) + AActor* RightFootPlane; + + UPROPERTY(EditAnywhere, meta = (DisplayName = "Edit Offsets Mode", Category = "MotionCapture")) + bool EditOffsetMode = false; + + UPROPERTY(EditAnywhere, meta = (DisplayName = "Lock Feet To Green Foot Indicators", Category = "MotionCapture")) + bool LockFeet = true; + UPROPERTY(EditAnywhere, meta = (DisplayName = "Additional Post Processing Offsets", Category = "MotionCapture")) FAdditionalOffsets AdditionalOffsets; + FAdditionalOffsets LastAddOffsets; + };