diff --git a/Content/MoCapMap.umap b/Content/MoCapMap.umap index b73e7d46d01bc066d818fdb7250544878bf02e66..6af5fe79f4e0420a7f37d853e434535ce6c86216 100644 --- a/Content/MoCapMap.umap +++ b/Content/MoCapMap.umap @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:447434a35a182e65441c7059ea90d3ad5fa1d6de4df788832979e768fbaeb2d1 -size 91652 +oid sha256:2d95074fcf135c44a169ad0e3686dec1a1a526af97dea8f05b59d5c0d63268f9 +size 88607 diff --git a/Content/SaveSequenceAnimBP.uasset b/Content/SaveSequenceAnimBP.uasset index 125dd9c23ba9520586e5db5ca60f3dbf820c99aa..713af97aac058a0f715dd102d440efea48190d00 100644 --- a/Content/SaveSequenceAnimBP.uasset +++ b/Content/SaveSequenceAnimBP.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:07a0bd4ccf76fb7f3b385120dbcb1328dad7b6ed67a12963d0bb8a05567e4806 -size 273024 +oid sha256:2a895522e77ef964af43e6d1bb3b5542ecbd84c02e91e6a87dadac1e170affe4 +size 296647 diff --git a/Content/SaveSequenceRig.uasset b/Content/SaveSequenceRig.uasset index cc62a6754b96431b828120ab7bee100223780218..acfce8e0b890adee4e1c2914081fce52a90164b3 100644 --- a/Content/SaveSequenceRig.uasset +++ b/Content/SaveSequenceRig.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4e140be55357a682f3c7ac027bc8bfa52cdc6458d4442d75231e022321eb320c -size 5131100 +oid sha256:f2d05eecbb0c886ea1ff1a79295a847ba9faca9b45580d48d3334b3f5712cec6 +size 5003356 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..c2eb444a7edecc06466b760dd3e0d2f287541903 --- /dev/null +++ b/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2020, Virtual Reality & Immersive Visualization Group at RWTH Aachen University +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/Source/MoCapPlugin/MoCapPlugin.Build.cs b/Source/MoCapPlugin/MoCapPlugin.Build.cs index 617f2fa11e737c6a5e1fa3f5e4959ffbf2511be8..fdc968b39f41982372c7daf53bad88ceab4e1196 100644 --- a/Source/MoCapPlugin/MoCapPlugin.Build.cs +++ b/Source/MoCapPlugin/MoCapPlugin.Build.cs @@ -19,7 +19,6 @@ public class MoCapPlugin : ModuleRules { "Core", "UMG", - "NDisplayLaunchButton", "RWTHVRToolkit", "SteamVR", "SteamVRInputDevice", @@ -48,8 +47,13 @@ public class MoCapPlugin : ModuleRules } ); + if (Target.Type == TargetRules.TargetType.Editor) + { + PrivateDependencyModuleNames.AddRange(new string[] { "NDisplayLaunchButton" }); + } - DynamicallyLoadedModuleNames.AddRange( + + DynamicallyLoadedModuleNames.AddRange( new string[] { // ... add any modules that your module loads dynamically here ... diff --git a/Source/MoCapPlugin/Private/MCAnimInstance.cpp b/Source/MoCapPlugin/Private/MCAnimInstance.cpp index 5cab788e4bcd63ac7b00d3f768e3c08ed2542936..4070dab72b574e4aaa2c930ecd94e3fcb7f0b41f 100644 --- a/Source/MoCapPlugin/Private/MCAnimInstance.cpp +++ b/Source/MoCapPlugin/Private/MCAnimInstance.cpp @@ -52,22 +52,10 @@ const FSensorDataEntry& UMCAnimInstance::GetSensorData(TEnumAsByte<EBodyPart> Bo return SensorData.HandL; case EBodyPart::HandR: return SensorData.HandR; - case EBodyPart::FootL: - return SensorData.FootL; - case EBodyPart::FootR: - return SensorData.FootR; - case EBodyPart::UpperArmL: - return SensorData.UpperArmL; - case EBodyPart::UpperArmR: - return SensorData.UpperArmR; case EBodyPart::LowerArmL: return SensorData.LowerArmL; case EBodyPart::LowerArmR: return SensorData.LowerArmR; - case EBodyPart::UpperLegL: - return SensorData.UpperLegL; - case EBodyPart::UpperLegR: - return SensorData.UpperLegR; case EBodyPart::LowerLegL: return SensorData.LowerLegL; case EBodyPart::LowerLegR: @@ -97,30 +85,12 @@ void UMCAnimInstance::SetSensorData(EBodyPart BodyPart, const FVector& Pos, cons case EBodyPart::HandR: entry = &SensorData.HandR; break; - case EBodyPart::FootL: - entry = &SensorData.FootL; - break; - case EBodyPart::FootR: - entry = &SensorData.FootR; - break; - case EBodyPart::UpperArmL: - entry = &SensorData.UpperArmL; - break; - case EBodyPart::UpperArmR: - entry = &SensorData.UpperArmR; - break; case EBodyPart::LowerArmL: entry = &SensorData.LowerArmL; break; case EBodyPart::LowerArmR: entry = &SensorData.LowerArmR; break; - case EBodyPart::UpperLegL: - entry = &SensorData.UpperLegL; - break; - case EBodyPart::UpperLegR: - entry = &SensorData.UpperLegR; - break; case EBodyPart::LowerLegL: entry = &SensorData.LowerLegL; break; @@ -157,30 +127,12 @@ void UMCAnimInstance::SetSensorData(EBodyPart BodyPart, const FQuat& Rot) { case EBodyPart::HandR: entry = &SensorData.HandR; break; - case EBodyPart::FootL: - entry = &SensorData.FootL; - break; - case EBodyPart::FootR: - entry = &SensorData.FootR; - break; - case EBodyPart::UpperArmL: - entry = &SensorData.UpperArmL; - break; - case EBodyPart::UpperArmR: - entry = &SensorData.UpperArmR; - break; case EBodyPart::LowerArmL: entry = &SensorData.LowerArmL; break; case EBodyPart::LowerArmR: entry = &SensorData.LowerArmR; break; - case EBodyPart::UpperLegL: - entry = &SensorData.UpperLegL; - break; - case EBodyPart::UpperLegR: - entry = &SensorData.UpperLegR; - break; case EBodyPart::LowerLegL: entry = &SensorData.LowerLegL; break; diff --git a/Source/MoCapPlugin/Private/MCController.cpp b/Source/MoCapPlugin/Private/MCController.cpp index 6401f82ed22e4655f538d10bb3986c731dfdf724..2a17a71bdd326e2d85e191291ac09073647dad20 100644 --- a/Source/MoCapPlugin/Private/MCController.cpp +++ b/Source/MoCapPlugin/Private/MCController.cpp @@ -59,6 +59,9 @@ void AMCController::BeginPlay() { Pawn->LoadMeasurementFile(MeasurementPath); Pawn->GetAnimInstance()->PawnOwner = Pawn; + if (Scale > 0.f) { + Pawn->GetAnimInstance()->Scale = FVector(Scale, Scale, Scale); + } if (LeftFootPlane && RightFootPlane) { Pawn->GetAnimInstance()->LeftFootPlane = LeftFootPlane->GetActorTransform(); Pawn->GetAnimInstance()->RightFootPlane = RightFootPlane->GetActorTransform(); @@ -171,7 +174,7 @@ void AMCController::SaveToAnimMode() { InstructionWidget->FeedbackText->SetText(FText::FromString("Saved!")); InstructionWidget->WidgetSwitcher->SetActiveWidgetIndex(InstructionWidget->StartIndex); } - if (GEngine) { + if (GEngine && OutputMsgOnScreen) { GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Green, FString::Printf(TEXT("Animation Saved!"))); } } @@ -318,7 +321,7 @@ bool AMCController::PreprocessRecording(float StartHaltingPoint, float EndHaltin for (int i = 0; i < AnimSaveState.StringData.Num(); i++) { - auto Entry = AnimSaveState.StringData[i]; + FString Entry = AnimSaveState.StringData[i]; FString TimeString, JsonString; Entry.Split(" ", &TimeString, &JsonString); @@ -487,7 +490,7 @@ bool AMCController::PreprocessRecording(float StartHaltingPoint, float EndHaltin continue; } - TArray<EBodyPart> BodyParts = { EBodyPart::LowerBody, EBodyPart::FootL, EBodyPart::FootR }; + TArray<EBodyPart> BodyParts = { EBodyPart::LowerBody/*, EBodyPart::LowerLegL, EBodyPart::LowerLegR*/}; for (EBodyPart BodyPart : BodyParts) { FVector PosRes; @@ -543,197 +546,6 @@ bool AMCController::PreprocessRecording(float StartHaltingPoint, float EndHaltin } } - //---Reducing Hip Movement--- - if (HipReducingFactor > 0.f) { - for (int i = 0; i < AnimSaveState.AnimData.Num(); i++) { - - FProcessedAnimData& AnimData = AnimSaveState.AnimData[i]; - - if (AnimData.IsMarker || AnimData.IsEnd) { - continue; - } - - FSensorData& SensorData = AnimData.SensorData; - - //reduce hip - FSensorDataEntry* HipEntry = SensorData.GetEntry(EBodyPart::LowerBody); - FVector DistToCenter = HipReducingCenter - HipEntry->Pos; - FVector HipMoved = HipReducingFactor * DistToCenter; - HipMoved.Z = 0.f; - HipEntry->Pos = HipEntry->Pos + HipMoved; - - //move upper body parts to fit hip - for (int j = 0; j < EBodyPart::LAST; j++) { - - EBodyPart Type = EBodyPart(j); - if (Type == EBodyPart::LowerBody || Type == EBodyPart::FootL || Type == EBodyPart::FootR) { - continue; - } - - FSensorDataEntry* Entry = SensorData.GetEntry(Type); - Entry->Pos += HipMoved; - - } - - } - } - - //---Controlling Chest Position--- - if (ChestControlFactor > 0.f) { - - FVector AvgChestPos; - FVector AvgHipPos; - FVector MoveChest; - for (int i = 0; i < AnimSaveState.AnimData.Num(); i++) { - - FProcessedAnimData& AnimData = AnimSaveState.AnimData[i]; - - if (AnimData.IsMarker || AnimData.IsEnd) { - //average chest position - AvgChestPos = FVector::ZeroVector; - int Num = 0; - for (int j = i + 1; j < AnimSaveState.AnimData.Num(); j++) { - if (AnimSaveState.AnimData[j].IsMarker || AnimSaveState.AnimData[j].IsEnd) { - break; - } - Num++; - } - for (int j = i + 1; j <= i + Num; j++) { - AvgChestPos += AnimSaveState.AnimData[j].SensorData.GetEntry(EBodyPart::UpperBody)->Pos / (float)Num; - } - //average hip position - AvgHipPos = FVector::ZeroVector; - for (int j = i + 1; j <= i + Num; j++) { - AvgHipPos += AnimSaveState.AnimData[j].SensorData.GetEntry(EBodyPart::LowerBody)->Pos / (float)Num; - } - MoveChest = ChestControlFactor * (AvgHipPos + ChestControlCenter - AvgChestPos); - MoveChest.X = 0.f; - MoveChest.Z = 0.f; - continue; - } - - FSensorData& SensorData = AnimData.SensorData; - - //move chest - FSensorDataEntry* ChestEntry = SensorData.GetEntry(EBodyPart::UpperBody); - ChestEntry->Pos += MoveChest; - if (ChestKeepLength) { - FSensorDataEntry* HipEntry = SensorData.GetEntry(EBodyPart::LowerBody); - FVector OldPos = ChestEntry->Pos; - ChestEntry->Pos = HipEntry->Pos + (AvgHipPos - AvgChestPos).Size() * (ChestEntry->Pos - HipEntry->Pos).Normalize(); - MoveChest += ChestEntry->Pos - OldPos; - } - - //move upper body parts to fit chest - for (int j = 0; j < EBodyPart::LAST; j++) { - - EBodyPart Type = EBodyPart(j); - if (Type == EBodyPart::UpperBody || Type == EBodyPart::LowerBody || Type == EBodyPart::FootL || Type == EBodyPart::FootR) { - continue; - } - - FSensorDataEntry* Entry = SensorData.GetEntry(Type); - Entry->Pos += MoveChest; - - } - - } - } - - //---return to default pose at start and end--- - FSensorData DefaultPose; - if (ReturnToDefaultPose) { - - //Take default pose from time or file - int CurAnimPart = 0; - double CurAnimStartTime; - if (TakeDefaultPoseFromTime >= 0.f && TakeDefaultPoseFromAnimPart > 0) { - for (int i = 0; i < AnimSaveState.AnimData.Num(); i++) { - FProcessedAnimData& AnimData = AnimSaveState.AnimData[i]; - if (AnimData.IsMarker || AnimData.IsEnd) { - CurAnimPart++; - CurAnimStartTime = AnimData.Timestamp.GetTotalSeconds(); - continue; - } - if (CurAnimPart == TakeDefaultPoseFromAnimPart) { - double CurAnimTime = AnimData.Timestamp.GetTotalSeconds() - CurAnimStartTime; - if (FMath::IsNearlyEqual(CurAnimTime, TakeDefaultPoseFromTime, 0.05)) { - DefaultPose = AnimData.SensorData; - FString SaveContent; - for (int j = 0; j < EBodyPart::LAST; j++) { - EBodyPart Type = EBodyPart(j); - FSensorDataEntry* Entry = AnimData.SensorData.GetEntry(Type); - SaveContent += FString::SanitizeFloat(Entry->Pos.X) + "," + FString::SanitizeFloat(Entry->Pos.Y) + "," + FString::SanitizeFloat(Entry->Pos.Z) + "," + - FString::SanitizeFloat(Entry->Rot.X) + "," + FString::SanitizeFloat(Entry->Rot.Y) + "," + FString::SanitizeFloat(Entry->Rot.Z) + "," + FString::SanitizeFloat(Entry->Rot.W) + "\n"; - } - FString SavePath = FPaths::ProjectContentDir() + "LastDefaultPose.txt"; - FFileHelper::SaveStringToFile(SaveContent, *SavePath); - break; - } - } - } - } - else if(FPaths::FileExists(FPaths::ProjectContentDir() + TakeDefaultPoseFromFile)) { - TArray<FString> SaveContent; - FString SavePath = FPaths::ProjectContentDir() + TakeDefaultPoseFromFile; - FFileHelper::LoadFileToStringArray(SaveContent, *SavePath); - for (int i = 0; i < SaveContent.Num(); i++) { - EBodyPart Type = EBodyPart(i); - FSensorDataEntry* Entry = DefaultPose.GetEntry(Type); - TArray<FString> Numbers; - SaveContent[i].ParseIntoArray(Numbers, TEXT(",")); - Entry->Pos = FVector(FCString::Atof(*Numbers[0]), FCString::Atof(*Numbers[1]), FCString::Atof(*Numbers[2])); - Entry->Rot = FQuat(FCString::Atof(*Numbers[3]), FCString::Atof(*Numbers[4]), FCString::Atof(*Numbers[5]), FCString::Atof(*Numbers[6])); - } - } - - //Gather time stamps for default poses - TArray<double> DefaultPoseTimes; - int DefaultPoseTimeIndex = 0; - for (int i = 0; i < AnimSaveState.AnimData.Num(); i++) { - FProcessedAnimData& AnimData = AnimSaveState.AnimData[i]; - if (AnimData.IsMarker || AnimData.IsEnd) { - DefaultPoseTimes.Add(AnimData.Timestamp.GetTotalSeconds()); - } - } - - //Do default poses - for (int i = 0; i < AnimSaveState.AnimData.Num(); i++) { - - FProcessedAnimData& AnimData = AnimSaveState.AnimData[i]; - - if (AnimData.IsMarker || AnimData.IsEnd) { - DefaultPoseTimeIndex++; - continue; - } - - FSensorData& SensorData = AnimData.SensorData; - - float DefaultPoseAlpha = 0.f; - float DiffTime = AnimData.Timestamp.GetTotalSeconds() - DefaultPoseTimes[DefaultPoseTimeIndex - 1]; - if (DiffTime < DefaultPoseTakingTime) { - DefaultPoseAlpha = 1.f - DiffTime / DefaultPoseTakingTime; - } - DiffTime = DefaultPoseTimes[DefaultPoseTimeIndex] - AnimData.Timestamp.GetTotalSeconds(); - if (DiffTime < DefaultPoseTakingTime) { - DefaultPoseAlpha = 1.f - DiffTime / DefaultPoseTakingTime; - } - - //move upper body parts to fit hip - for (int j = 0; j < EBodyPart::LAST; j++) { - - EBodyPart Type = EBodyPart(j); - FSensorDataEntry* Entry = SensorData.GetEntry(Type); - - Entry->Pos = (1.f - DefaultPoseAlpha) * Entry->Pos + DefaultPoseAlpha * DefaultPose.GetEntry(Type)->Pos; - Entry->Rot = FQuat::Slerp(Entry->Rot, DefaultPose.GetEntry(Type)->Rot, DefaultPoseAlpha);; - - } - - } - } - - //---find halting points and scale them up--- //end point @@ -865,29 +677,29 @@ bool AMCController::PreprocessRecording(float StartHaltingPoint, float EndHaltin } - //---adjust feet position so that they are located at the green foot indicators--- + //---shift whole body so that it is centered around the green foot indicators--- int amount = 0; int start = 0; for (int i = 0; i < AnimSaveState.AnimData.Num() && LockFeet && LeftFootPlane && RightFootPlane; i++) { - FProcessedAnimData& AnimData = AnimSaveState.AnimData[i]; - - if (AnimData.IsMarker || AnimData.IsEnd) { + if (AnimSaveState.AnimData[i].IsMarker || AnimSaveState.AnimData[i].IsEnd) { + //determine center of gravity from feet 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; + 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; + 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); + cog += (0.5f * (LPos + RPos)) / (float)amount; } + //shift anim center to cog, so that feet are near locking platforms FVector shiftAmount = 0.5f * (LeftFootPlane->GetActorLocation() + RightFootPlane->GetActorLocation()) - cog - FVector(0, 10, 0); shiftAmount.Z = 0; for (int j = start; j < i; j++) { @@ -899,88 +711,386 @@ bool AMCController::PreprocessRecording(float StartHaltingPoint, float EndHaltin } } - FVector LGoalPos = FVector(5, -5, 6) + LeftFootPlane->GetActorLocation(); + amount = 0; + start = i + 1; + continue; + } + + amount++; + + } + + //---Shift Hip To Reducing Center--- + + FVector HipReducingCenterAbsolute = HipReducingCenter + 0.5f * (LeftFootPlane->GetActorLocation() + RightFootPlane->GetActorLocation()); + + if (HipShiftToReducingCenter) { + + FVector AvgHipPos; + FVector MoveHip; + for (int i = 0; i < AnimSaveState.AnimData.Num(); i++) { + + FProcessedAnimData& AnimData = AnimSaveState.AnimData[i]; + + if (AnimData.IsMarker || AnimData.IsEnd) { + //average hip position + int Num = 0; + for (int j = i + 1; j < AnimSaveState.AnimData.Num(); j++) { + if (AnimSaveState.AnimData[j].IsMarker || AnimSaveState.AnimData[j].IsEnd) { + break; + } + Num++; + } + AvgHipPos = FVector::ZeroVector; + for (int j = i + 1; j <= i + Num; j++) { + FVector HipPos = AnimSaveState.AnimData[j].SensorData.GetEntry(EBodyPart::LowerBody)->Pos; + FQuat HipRot = AnimSaveState.AnimData[j].SensorData.GetEntry(EBodyPart::LowerBody)->Rot; + Pawn->OffsetSensorData(EBodyPart::LowerBody, HipPos, HipRot); + AvgHipPos += HipPos / (float)Num; + } + MoveHip = HipReducingCenterAbsolute - AvgHipPos; + MoveHip.Z = 0.f; + continue; + } + + //reduce hip + FSensorData& SensorData = AnimData.SensorData; + FSensorDataEntry* HipEntry = SensorData.GetEntry(EBodyPart::LowerBody); + HipEntry->Pos = HipEntry->Pos + MoveHip; + + //move upper body parts to fit hip + for (int j = 0; j < EBodyPart::LAST; j++) { + + EBodyPart Type = EBodyPart(j); + if (Type == EBodyPart::LowerBody || Type == EBodyPart::LowerLegL || Type == EBodyPart::LowerLegR) { + continue; + } + + FSensorDataEntry* Entry = SensorData.GetEntry(Type); + Entry->Pos += MoveHip; + + } + + } + + + } + + //---Reducing Hip Movement--- + + if (HipReducingFactor > 0.f) { + + for (int i = 0; i < AnimSaveState.AnimData.Num(); i++) { + + FProcessedAnimData& AnimData = AnimSaveState.AnimData[i]; + + if (AnimData.IsMarker || AnimData.IsEnd) { + continue; + } + + FSensorData& SensorData = AnimData.SensorData; + + //reduce hip + FSensorDataEntry* HipEntry = SensorData.GetEntry(EBodyPart::LowerBody); + FVector HipPos = HipEntry->Pos; + FQuat HipRot = HipEntry->Rot; + Pawn->OffsetSensorData(EBodyPart::LowerBody, HipPos, HipRot); + FVector DistToCenter = HipReducingCenterAbsolute - HipPos; + FVector HipMoved = HipReducingFactor * DistToCenter; + HipMoved.Z = 0.f; + HipEntry->Pos = HipEntry->Pos + HipMoved; + + //move upper body parts to fit hip + for (int j = 0; j < EBodyPart::LAST; j++) { + + EBodyPart Type = EBodyPart(j); + if (Type == EBodyPart::LowerBody || Type == EBodyPart::LowerLegL || Type == EBodyPart::LowerLegR) { + continue; + } + + FSensorDataEntry* Entry = SensorData.GetEntry(Type); + Entry->Pos += HipMoved; + + } + + } + + } + + //---Controlling Chest Position--- + if (ChestControlFactor > 0.f) { + + FVector AvgChestPos; + FVector AvgHipPos; + FVector MoveChest; + for (int i = 0; i < AnimSaveState.AnimData.Num(); i++) { + + FProcessedAnimData& AnimData = AnimSaveState.AnimData[i]; + + if (AnimData.IsMarker || AnimData.IsEnd) { + //average chest position + AvgChestPos = FVector::ZeroVector; + int Num = 0; + for (int j = i + 1; j < AnimSaveState.AnimData.Num(); j++) { + if (AnimSaveState.AnimData[j].IsMarker || AnimSaveState.AnimData[j].IsEnd) { + break; + } + Num++; + } + for (int j = i + 1; j <= i + Num; j++) { + AvgChestPos += AnimSaveState.AnimData[j].SensorData.GetEntry(EBodyPart::UpperBody)->Pos / (float)Num; + } + //average hip position + AvgHipPos = FVector::ZeroVector; + for (int j = i + 1; j <= i + Num; j++) { + AvgHipPos += AnimSaveState.AnimData[j].SensorData.GetEntry(EBodyPart::LowerBody)->Pos / (float)Num; + } + MoveChest = ChestControlFactor * (AvgHipPos + ChestControlCenter - AvgChestPos); + MoveChest.X = 0.f; + MoveChest.Z = 0.f; + continue; + } + + FSensorData& SensorData = AnimData.SensorData; + + //move chest + FSensorDataEntry* ChestEntry = SensorData.GetEntry(EBodyPart::UpperBody); + ChestEntry->Pos += MoveChest; + if (ChestKeepLength) { + FSensorDataEntry* HipEntry = SensorData.GetEntry(EBodyPart::LowerBody); + FVector OldPos = ChestEntry->Pos; + ChestEntry->Pos = HipEntry->Pos + (AvgHipPos - AvgChestPos).Size() * (ChestEntry->Pos - HipEntry->Pos).Normalize(); + MoveChest += ChestEntry->Pos - OldPos; + } + + //move upper body parts to fit chest + for (int j = 0; j < EBodyPart::LAST; j++) { + + EBodyPart Type = EBodyPart(j); + if (Type == EBodyPart::UpperBody || Type == EBodyPart::LowerBody || Type == EBodyPart::LowerLegL || Type == EBodyPart::LowerLegR) { + continue; + } + + FSensorDataEntry* Entry = SensorData.GetEntry(Type); + Entry->Pos += MoveChest; + + } + + } + } + + //---adjust feet position so that they are located at the green foot indicators--- + + amount = 0; + start = 0; + + for (int i = 0; i < AnimSaveState.AnimData.Num() && LockFeet && LeftFootPlane && RightFootPlane; i++) { + + if (AnimSaveState.AnimData[i].IsMarker || AnimSaveState.AnimData[i].IsEnd) { + + //offsets for feet goal data + FVector LGoalPos = FVector(5, -7, FootHeightTarget) + LeftFootPlane->GetActorLocation(); FQuat LGoalRot = FRotator(90, 0, 6).Quaternion() * LeftFootPlane->GetActorQuat(); - FVector RGoalPos = FVector(-5, -5, 6) + RightFootPlane->GetActorLocation(); + FVector RGoalPos = FVector(-5, -7, FootHeightTarget) + RightFootPlane->GetActorLocation(); FQuat RGoalRot = FRotator(-90, 0, 186).Quaternion() * RightFootPlane->GetActorQuat(); - //float maxDist = - 5.0 + FVector::Dist(Pawn->SkeletalMesh->GetSocketLocation("pelvis"), Pawn->SkeletalMesh->GetSocketLocation("foot_l")); - float maxDist = InitialPelvisFootDist; - //maxDist = Pawn->GetAnimInstance()->Measurements.LowerLeg + Pawn->GetAnimInstance()->Measurements.UpperLeg; - float moveDown = 0.f; + //old way of moving down body so that feet are reachable + if (false) { + //determine body move down amount, so that feet do not glitch and legs are not too stretched + //float maxDist = - 5.0 + FVector::Dist(Pawn->SkeletalMesh->GetSocketLocation("pelvis"), Pawn->SkeletalMesh->GetSocketLocation("foot_l")); + float maxDist = InitialPelvisFootDist; + //maxDist = Pawn->GetAnimInstance()->Measurements.LowerLeg + Pawn->GetAnimInstance()->Measurements.UpperLeg; + float moveDown = 0.f; + for (int j = start; j < i; j++) { + FSensorData& SensorData = AnimSaveState.AnimData[j].SensorData; + + FVector BPos = SensorData.GetEntry(EBodyPart::LowerBody)->Pos; + FQuat BRot = SensorData.GetEntry(EBodyPart::LowerBody)->Rot; + Pawn->OffsetSensorData(EBodyPart::LowerBody, BPos, BRot); + + float dist1 = FVector::Dist(BPos, LGoalPos); + float dist2 = FVector::Dist(BPos, RGoalPos); + dist1 = FMath::Abs(BPos.Z - LGoalPos.Z); + dist2 = FMath::Abs(BPos.Z - RGoalPos.Z); + float maxDistTmp = 0.f; + if (dist1 > dist2 && std::_Is_finite(dist1)) { + maxDistTmp = dist1; + } + else if (std::_Is_finite(dist2)) { + maxDistTmp = dist2; + } + if (maxDistTmp > maxDist && maxDistTmp - maxDist > moveDown) { + moveDown = maxDistTmp - maxDist; + } + } + + if (moveDown > MaxLegLength) { + moveDown = MaxLegLength; + } + + //move down body + 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 += FVector(0, 0, -moveDown); + } + } + } + + //move down body so that feet are reachable frame by frame + float maxDist = MaxLegLength; for (int j = start; j < i; j++) { + + float moveDown = 0.f; + FSensorData& SensorData = AnimSaveState.AnimData[j].SensorData; FVector BPos = SensorData.GetEntry(EBodyPart::LowerBody)->Pos; FQuat BRot = SensorData.GetEntry(EBodyPart::LowerBody)->Rot; Pawn->OffsetSensorData(EBodyPart::LowerBody, BPos, BRot); - float dist1 = FVector::Dist(BPos, LGoalPos); - float dist2 = FVector::Dist(BPos, RGoalPos); - dist1 = FMath::Abs(BPos.Z - LGoalPos.Z); - dist2 = FMath::Abs(BPos.Z - RGoalPos.Z); - float maxDistTmp = 0.f; - if (dist1 > dist2 && std::_Is_finite(dist1)) { - maxDistTmp = dist1; - } - else if (std::_Is_finite(dist2)) { - maxDistTmp = dist2; + FVector LDiff = LGoalPos - BPos; + if (LDiff.Size() > maxDist) { + /* + * Sqrt((Gx-Bx)^2 + (Gy-By)^2 + (Gz-Bz)^2) = maxD + * Bz = Gz - Sqrt(maxD^2 - (Gx-Bx)^2 - (Gy-By)^2) + */ + float XDiff = LGoalPos.X - BPos.X; + float YDiff = LGoalPos.Y - BPos.Y; + float GoalZ = LGoalPos.Z + FMath::Sqrt(maxDist * maxDist - XDiff * XDiff - YDiff * YDiff); + moveDown = GoalZ - BPos.Z; } - if (maxDistTmp > maxDist && maxDistTmp - maxDist > moveDown){ - moveDown = maxDistTmp - maxDist; - } - } - if (moveDown > MoveDownCap) { - moveDown = MoveDownCap; - } + FVector RDiff = RGoalPos - BPos; + if (RDiff.Size() > maxDist) { + float XDiff = RGoalPos.X - BPos.X; + float YDiff = RGoalPos.Y - BPos.Y; + float GoalZ = RGoalPos.Z + FMath::Sqrt(maxDist * maxDist - XDiff * XDiff - YDiff * YDiff); + float tmpMoveDown = GoalZ - BPos.Z; + if (tmpMoveDown < moveDown) { + moveDown = tmpMoveDown; + } + } - 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 += FVector(0, 0, -moveDown); + Entry->Pos += FVector(0, 0, moveDown); } + } + //set feet to goal positions 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; - - FVector LGoal = LeftFootPlane->GetActorLocation() - FVector(-4, 10, 0); - FQuat LRot = SensorData.GetEntry(EBodyPart::LowerLegL)->Rot; - Pawn->OffsetSensorData(EBodyPart::LowerLegL, LGoal, LRot, true); - SensorData.GetEntry(EBodyPart::LowerLegL)->Pos = LGoal; - UE_LOG(LogTemp, Warning, TEXT("MIMI %f %f %f"), SensorData.GetEntry(EBodyPart::LowerLegL)->Pos.X, SensorData.GetEntry(EBodyPart::LowerLegL)->Pos.Y, SensorData.GetEntry(EBodyPart::LowerLegL)->Pos.Z); - */ SensorData.GetEntry(EBodyPart::LowerLegL)->Pos = LGoalPos; SensorData.GetEntry(EBodyPart::LowerLegL)->Rot = LGoalRot; SensorData.GetEntry(EBodyPart::LowerLegR)->Pos = RGoalPos; SensorData.GetEntry(EBodyPart::LowerLegR)->Rot = RGoalRot; - } - amount = 0; start = i + 1; continue; } amount++; - + + } + + //---return to default pose at start and end--- + FSensorData DefaultPose; + if (ReturnToDefaultPose) { + + //Take default pose from time or file + int CurAnimPart = 0; + double CurAnimStartTime; + if (TakeDefaultPoseFromTime >= 0.f && TakeDefaultPoseFromAnimPart > 0) { + for (int i = 0; i < AnimSaveState.AnimData.Num(); i++) { + FProcessedAnimData& AnimData = AnimSaveState.AnimData[i]; + if (AnimData.IsMarker || AnimData.IsEnd) { + CurAnimPart++; + CurAnimStartTime = AnimData.Timestamp.GetTotalSeconds(); + continue; + } + if (CurAnimPart == TakeDefaultPoseFromAnimPart) { + double CurAnimTime = AnimData.Timestamp.GetTotalSeconds() - CurAnimStartTime; + if (FMath::IsNearlyEqual(CurAnimTime, TakeDefaultPoseFromTime, 0.05)) { + DefaultPose = AnimData.SensorData; + FString SaveContent; + for (int j = 0; j < EBodyPart::LAST; j++) { + EBodyPart Type = EBodyPart(j); + FSensorDataEntry* Entry = AnimData.SensorData.GetEntry(Type); + SaveContent += FString::SanitizeFloat(Entry->Pos.X) + "," + FString::SanitizeFloat(Entry->Pos.Y) + "," + FString::SanitizeFloat(Entry->Pos.Z) + "," + + FString::SanitizeFloat(Entry->Rot.X) + "," + FString::SanitizeFloat(Entry->Rot.Y) + "," + FString::SanitizeFloat(Entry->Rot.Z) + "," + FString::SanitizeFloat(Entry->Rot.W) + "\n"; + } + FString SavePath = FPaths::ProjectContentDir() + "/LastDefaultPose.txt"; + FFileHelper::SaveStringToFile(SaveContent, *SavePath); + break; + } + } + } + } + else if (FPaths::FileExists(FPaths::ProjectContentDir() + "/" + TakeDefaultPoseFromFile)) { + TArray<FString> SaveContent; + FString SavePath = FPaths::ProjectContentDir() + "/" + TakeDefaultPoseFromFile; + FFileHelper::LoadFileToStringArray(SaveContent, *SavePath); + for (int i = 0; i < SaveContent.Num(); i++) { + EBodyPart Type = EBodyPart(i); + FSensorDataEntry* Entry = DefaultPose.GetEntry(Type); + TArray<FString> Numbers; + SaveContent[i].ParseIntoArray(Numbers, TEXT(",")); + Entry->Pos = FVector(FCString::Atof(*Numbers[0]), FCString::Atof(*Numbers[1]), FCString::Atof(*Numbers[2])); + Entry->Rot = FQuat(FCString::Atof(*Numbers[3]), FCString::Atof(*Numbers[4]), FCString::Atof(*Numbers[5]), FCString::Atof(*Numbers[6])); + } + } + + //Gather time stamps for default poses + TArray<double> DefaultPoseTimes; + int DefaultPoseTimeIndex = 0; + for (int i = 0; i < AnimSaveState.AnimData.Num(); i++) { + FProcessedAnimData& AnimData = AnimSaveState.AnimData[i]; + if (AnimData.IsMarker || AnimData.IsEnd) { + DefaultPoseTimes.Add(AnimData.Timestamp.GetTotalSeconds()); + } + } + + //Do default poses + for (int i = 0; i < AnimSaveState.AnimData.Num(); i++) { + + FProcessedAnimData& AnimData = AnimSaveState.AnimData[i]; + + if (AnimData.IsMarker || AnimData.IsEnd) { + DefaultPoseTimeIndex++; + continue; + } + + FSensorData& SensorData = AnimData.SensorData; + + float DefaultPoseAlpha = 0.f; + float DiffTime = AnimData.Timestamp.GetTotalSeconds() - DefaultPoseTimes[DefaultPoseTimeIndex - 1]; + if (DiffTime < DefaultPoseTakingTime) { + DefaultPoseAlpha = 1.f - DiffTime / DefaultPoseTakingTime; + } + DiffTime = DefaultPoseTimes[DefaultPoseTimeIndex] - AnimData.Timestamp.GetTotalSeconds(); + if (DiffTime < DefaultPoseTakingTime) { + DefaultPoseAlpha = 1.f - DiffTime / DefaultPoseTakingTime; + } + + //move upper body parts to fit hip + for (int j = 0; j < EBodyPart::LAST; j++) { + + EBodyPart Type = EBodyPart(j); + FSensorDataEntry* Entry = SensorData.GetEntry(Type); + + Entry->Pos = (1.f - DefaultPoseAlpha) * Entry->Pos + DefaultPoseAlpha * DefaultPose.GetEntry(Type)->Pos; + Entry->Rot = FQuat::Slerp(Entry->Rot, DefaultPose.GetEntry(Type)->Rot, DefaultPoseAlpha);; + + } + + } } AnimSaveState.NextFrame = FTimespan(); @@ -1404,6 +1514,11 @@ void AMCController::ToggleRecording() { } if (!IsRecording) { + FString LogFolderName = LogHandler.GetSessionIdentifier(); + FString LogPathString = FPaths::ProjectSavedDir() + "OwnLogs/" + LogFolderName + "/DataLog"; + while (FPaths::FileExists(LogPathString + FString::FromInt(CurRecordingInSession) + ".log")) { + CurRecordingInSession++; + } LogHandler.NewLog("DataLog" + FString::FromInt(CurRecordingInSession)); LogHandler.StartRecording(); Pawn->CalcSensorOffsets(LogHandler, UseLastOffsets, DebugMode); @@ -1546,7 +1661,7 @@ void AMCController::SaveAnimation(float StartHaltingPoint, float EndHaltingPoint if (InstructionWidget) { InstructionWidget->WidgetSwitcher->SetActiveWidgetIndex(InstructionWidget->SavingIndex); } - if (GEngine) { + if (GEngine && OutputMsgOnScreen) { GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Green, FString::Printf(TEXT("Saving Animation..."))); } @@ -1566,7 +1681,12 @@ void AMCController::SaveAnimation(float StartHaltingPoint, float EndHaltingPoint AnimSaveState.Pawn->GetAnimInstance()->LockFeet = LockFeet; AnimSaveState.Pawn->GetAnimInstance()->UseHandPos = UseHandPosition; AnimSaveState.Pawn->GetAnimInstance()->LimitHandRot = LimitHandRotation; + AnimSaveState.Pawn->GetAnimInstance()->FingerAngleScale = FingerAngleScale; AnimSaveState.Pawn->GetAnimInstance()->SnapshotAnimations.Empty(); + if (Scale > 0.f) { + AnimSaveState.Pawn->GetAnimInstance()->Scale = FVector(Scale, Scale, Scale); + } + AnimSaveState.Pawn->GetAnimInstance()->FixChest = FixChest; AnimSaveState.FPS = FramesPerSecond; AnimSaveState.SPF = 1.f / ((float)AnimSaveState.FPS); diff --git a/Source/MoCapPlugin/Private/MCDefines.cpp b/Source/MoCapPlugin/Private/MCDefines.cpp index df56a0edb0767d6e7a530003a3dc2371cd48100a..100b2ff890f3a42a8b5d14e07e6c4e44f3c96743 100644 --- a/Source/MoCapPlugin/Private/MCDefines.cpp +++ b/Source/MoCapPlugin/Private/MCDefines.cpp @@ -8,22 +8,10 @@ FSensorDataEntry* FSensorData::GetEntry(EBodyPart BodyPart) { return &HandL; case EBodyPart::HandR: return &HandR; - case EBodyPart::FootL: - return &FootL; - case EBodyPart::FootR: - return &FootR; - case EBodyPart::UpperArmL: - return &UpperArmL; - case EBodyPart::UpperArmR: - return &UpperArmR; case EBodyPart::LowerArmL: return &LowerArmL; case EBodyPart::LowerArmR: return &LowerArmR; - case EBodyPart::UpperLegL: - return &UpperLegL; - case EBodyPart::UpperLegR: - return &UpperLegR; case EBodyPart::LowerLegL: return &LowerLegL; case EBodyPart::LowerLegR: diff --git a/Source/MoCapPlugin/Private/MCLogHandler.cpp b/Source/MoCapPlugin/Private/MCLogHandler.cpp index 7a4d9ac3ec26d0561714313a564470f8def6a704..3934db799446e30f973583525c9b945a90c78307 100644 --- a/Source/MoCapPlugin/Private/MCLogHandler.cpp +++ b/Source/MoCapPlugin/Private/MCLogHandler.cpp @@ -11,6 +11,10 @@ #include "JsonUtilities/Public/JsonUtilities.h" +FString UMCLogHandler::GetSessionIdentifier() { + return UniLog.GetSessionIdentifier(); +} + void UMCLogHandler::NewLog(const FString& Name) { UniLog.NewLogStream(Name, "Saved/OwnLogs/", Name + ".log", true); CurLog = Name; @@ -75,7 +79,7 @@ void UMCLogHandler::CopyLogToRecordings(FString& Name) { Name = FolderName; const FString Path = FPaths::ProjectSavedDir() + "Recordings/" + Name + "/"; - const FString PathLog = FPaths::ProjectSavedDir() + "OwnLogs"; + const FString PathLog = FPaths::ConvertRelativePathToFull(FPaths::ProjectDir() + "Saved/OwnLogs"); DirectoryVisitor Visitor; IFileManager::Get().IterateDirectory(*PathLog, Visitor); @@ -104,7 +108,7 @@ void UMCLogHandler::CopyLogToRecordings(FString& Name) { FString PathStopped = Visitor.Files[MaxIndex]; LastSubIndex = PathStopped.Find("/", ESearchCase::CaseSensitive, ESearchDir::FromEnd); PathStopped = PathStopped.RightChop(LastSubIndex + 1); - PathStopped = PathStopped + "/" + CurLog + ".log"; //TODO CurLog oder 0? + PathStopped = PathStopped + "/" + CurLog + ".log"; PathMostRecent += "\n" + PathStopped; } FFileHelper::SaveStringToFile(PathMostRecent, *(Path + "LogSourcePath.txt")); diff --git a/Source/MoCapPlugin/Private/MCPawn.cpp b/Source/MoCapPlugin/Private/MCPawn.cpp index f7106573e5ca1cb9659a5c58f582cca1697b3c74..c4b585d5184ba1d43579dcc2c7358cbda4891c81 100644 --- a/Source/MoCapPlugin/Private/MCPawn.cpp +++ b/Source/MoCapPlugin/Private/MCPawn.cpp @@ -82,14 +82,7 @@ AMCPawn::AMCPawn(const FObjectInitializer& ObjectInitializer) void AMCPawn::BeginPlay() { Super::BeginPlay(); - if (ShowDeviceModels) { - SensorSetup.HandL.ControllerComponent->SetShowDeviceModel(true); - SensorSetup.HandR.ControllerComponent->SetShowDeviceModel(true); - for (FSensor& Tracker : SensorSetup.Trackers) { - Tracker.ControllerComponent->SetShowDeviceModel(true); - Tracker.DebugMesh->SetVisibility(true); - } - } + SetShowDeviceModels(ShowDeviceModels); } @@ -152,43 +145,6 @@ USkeleton* AMCPawn::GetSkeleton() { return SkeletalMesh->SkeletalMesh->Skeleton; } -FName AMCPawn::GetBoneNameFromBodyPart(EBodyPart BodyPart) { - switch (BodyPart) { - case EBodyPart::Head: - return BoneNames.head; - case EBodyPart::HandL: - return BoneNames.hand_l; - case EBodyPart::HandR: - return BoneNames.hand_r; - case EBodyPart::FootL: - return BoneNames.foot_l; - case EBodyPart::FootR: - return BoneNames.foot_r; - case EBodyPart::UpperArmL: - return BoneNames.upperarm_l; - case EBodyPart::UpperArmR: - return BoneNames.upperarm_r; - case EBodyPart::LowerArmL: - return BoneNames.lowerarm_l; - case EBodyPart::LowerArmR: - return BoneNames.lowerarm_r; - case EBodyPart::UpperLegL: - return BoneNames.thigh_l; - case EBodyPart::UpperLegR: - return BoneNames.thigh_r; - case EBodyPart::LowerLegL: - return BoneNames.calf_l; - case EBodyPart::LowerLegR: - return BoneNames.calf_r; - case EBodyPart::UpperBody: - return BoneNames.spine03; - case EBodyPart::LowerBody: - return BoneNames.pelvis; - default: - return ""; - } -} - void AMCPawn::SetMeshVisibility(bool visible) { SkeletalMesh->SetVisibility(visible, true); } @@ -271,11 +227,9 @@ void AMCPawn::CalcSensorOffsets(UMCLogHandler& LogHandler, bool UseLastOffsets, switch (Tracker.BodyPart) { case EBodyPart::LowerLegL: - case EBodyPart::FootL: Offset = &LastOffsets.LowerLegL; break; case EBodyPart::LowerLegR: - case EBodyPart::FootR: Offset = &LastOffsets.LowerLegR; break; case EBodyPart::HandL: @@ -545,11 +499,9 @@ void AMCPawn::OffsetSensorData(EBodyPart part, FVector & Pos, FQuat & Rot, bool Offset = &AI->SensorOffsets.HandR; break; case EBodyPart::LowerLegL: - case EBodyPart::FootL: Offset = &AI->SensorOffsets.LowerLegL; break; case EBodyPart::LowerLegR: - case EBodyPart::FootR: Offset = &AI->SensorOffsets.LowerLegR; break; case EBodyPart::LowerArmL: @@ -579,6 +531,16 @@ void AMCPawn::OffsetSensorData(EBodyPart part, FVector & Pos, FQuat & Rot, bool } +void AMCPawn::SetShowDeviceModels(bool show) { + ShowDeviceModels = show; + SensorSetup.HandL.ControllerComponent->SetShowDeviceModel(show); + SensorSetup.HandR.ControllerComponent->SetShowDeviceModel(show); + for (FSensor& Tracker : SensorSetup.Trackers) { + Tracker.ControllerComponent->SetShowDeviceModel(show); + Tracker.DebugMesh->SetVisibility(show); + } +} + void AMCPawn::AddSensorDataToJson(TSharedPtr<FJsonObject> JsonObjectFull, const FSensor& Sensor) { TSharedPtr<FJsonObject> JsonObject = MAKE_JSON; diff --git a/Source/MoCapPlugin/Private/MCRigUnits.cpp b/Source/MoCapPlugin/Private/MCRigUnits.cpp index 1b2b6b22426b71c13b189806df4a2fa1d1d574ba..3212cfb4d2a8e9d965395e1f513f779130bd788a 100644 --- a/Source/MoCapPlugin/Private/MCRigUnits.cpp +++ b/Source/MoCapPlugin/Private/MCRigUnits.cpp @@ -45,11 +45,16 @@ FRigUnit_ApplyFingerData_Execute() { Scale = FVector(1.f, 1.f, 1.f); ThumbScale = FVector(1.f, 1.f, 1.f); } - FVector ThumbAngles_N = ThumbScale * ThumbAngles; - FVector IndexAngles_N = Scale * IndexAngles; - FVector MiddleAngles_N = Scale * MiddleAngles; - FVector RingAngles_N = Scale * RingAngles; - FVector PinkyAngles_N = Scale * PinkyAngles; + FVector ThumbAnglesClosed_N = ThumbScale * ThumbAnglesClosed; + FVector IndexAnglesClosed_N = Scale * IndexAnglesClosed; + FVector MiddleAnglesClosed_N = Scale * MiddleAnglesClosed; + FVector RingAnglesClosed_N = Scale * RingAnglesClosed; + FVector PinkyAnglesClosed_N = Scale * PinkyAnglesClosed; + FVector ThumbAnglesOpen_N = ThumbAnglesOpen; + FVector IndexAnglesOpen_N = IndexAnglesOpen; + FVector MiddleAnglesOpen_N = MiddleAnglesOpen; + FVector RingAnglesOpen_N = RingAnglesOpen; + FVector PinkyAnglesOpen_N = PinkyAnglesOpen; float Thumb_Index_Angle_N = Thumb_Index_Angle; float Index_Middle_Angle_N = Index_Middle_Angle; @@ -57,59 +62,144 @@ FRigUnit_ApplyFingerData_Execute() { float Ring_Pinky_Angle_N = Ring_Pinky_Angle; URigHierarchy* Hierarchy = ExecuteContext.Hierarchy; + + float ReverseFactor = 0.5f; + FFingerData FingerDataTransformed = FingerData; + FingerDataTransformed.LeftHand.Thumb = FingerDataTransformed.LeftHand.Thumb * (1.f + ReverseFactor) - ReverseFactor; + FingerDataTransformed.LeftHand.Index = FingerDataTransformed.LeftHand.Index * (1.f + ReverseFactor) - ReverseFactor; + FingerDataTransformed.LeftHand.Middle = FingerDataTransformed.LeftHand.Middle * (1.f + ReverseFactor) - ReverseFactor; + FingerDataTransformed.LeftHand.Ring = FingerDataTransformed.LeftHand.Ring * (1.f + ReverseFactor) - ReverseFactor; + FingerDataTransformed.LeftHand.Pinky = FingerDataTransformed.LeftHand.Pinky * (1.f + ReverseFactor) - ReverseFactor; + FingerDataTransformed.RightHand.Thumb = FingerDataTransformed.RightHand.Thumb * (1.f + ReverseFactor) - ReverseFactor; + FingerDataTransformed.RightHand.Index = FingerDataTransformed.RightHand.Index * (1.f + ReverseFactor) - ReverseFactor; + FingerDataTransformed.RightHand.Middle = FingerDataTransformed.RightHand.Middle * (1.f + ReverseFactor) - ReverseFactor; + FingerDataTransformed.RightHand.Ring = FingerDataTransformed.RightHand.Ring * (1.f + ReverseFactor) - ReverseFactor; + FingerDataTransformed.RightHand.Pinky = FingerDataTransformed.RightHand.Pinky * (1.f + ReverseFactor) - ReverseFactor; if (Hierarchy) { //CURLS - float Thumb01YAngle = ThumbAngles_N.X; + float Thumb01YAngleClosed = ThumbAnglesClosed_N.X; if (AngleScale >= 1.f) { - Thumb01YAngle = -15.f; + Thumb01YAngleClosed = -15.f; } - AddRotation("thumb_01_l", FingerData.LeftHand.Thumb * Thumb01YAngle, Hierarchy); - AddRotation("thumb_01_l", FingerData.LeftHand.Thumb * ThumbAngles_N.X, Hierarchy, "Z"); - AddRotation("thumb_02_l", FingerData.LeftHand.Thumb * ThumbAngles_N.Y, Hierarchy); - AddRotation("thumb_03_l", FingerData.LeftHand.Thumb * ThumbAngles_N.Z, Hierarchy); - - AddRotation("index_01_l", FingerData.LeftHand.Index * IndexAngles_N.X, Hierarchy); - AddRotation("index_02_l", FingerData.LeftHand.Index * IndexAngles_N.Y, Hierarchy); - AddRotation("index_03_l", FingerData.LeftHand.Index * IndexAngles_N.Z, Hierarchy); - - AddRotation("middle_01_l", FingerData.LeftHand.Middle * MiddleAngles_N.X, Hierarchy); - AddRotation("middle_02_l", FingerData.LeftHand.Middle * MiddleAngles_N.Y, Hierarchy); - AddRotation("middle_03_l", FingerData.LeftHand.Middle * MiddleAngles_N.Z, Hierarchy); + if (FingerDataTransformed.LeftHand.Thumb >= 0.f) { + AddRotation("thumb_01_l", FingerDataTransformed.LeftHand.Thumb * Thumb01YAngleClosed, Hierarchy); + AddRotation("thumb_01_l", FingerDataTransformed.LeftHand.Thumb * ThumbAnglesClosed_N.X, Hierarchy, "Z"); + AddRotation("thumb_02_l", FingerDataTransformed.LeftHand.Thumb * ThumbAnglesClosed_N.Y, Hierarchy); + AddRotation("thumb_03_l", FingerDataTransformed.LeftHand.Thumb * ThumbAnglesClosed_N.Z, Hierarchy); + } + else { + //AddRotation("thumb_01_l", FingerDataTransformed.LeftHand.Thumb * Thumb01YAngleClosed, Hierarchy); + //AddRotation("thumb_01_l", (FingerDataTransformed.LeftHand.Thumb / ReverseFactor) * -ThumbAnglesOpen_N.X, Hierarchy, "X"); + AddRotation("thumb_01_l", (FingerDataTransformed.LeftHand.Thumb / ReverseFactor) * -ThumbAnglesOpen_N.X, Hierarchy); + AddRotation("thumb_01_l", (FingerDataTransformed.LeftHand.Thumb / ReverseFactor) * ThumbAnglesOpen_N.X, Hierarchy, "Z"); + AddRotation("thumb_02_l", (FingerDataTransformed.LeftHand.Thumb / ReverseFactor) * ThumbAnglesOpen_N.Y, Hierarchy); + AddRotation("thumb_03_l", (FingerDataTransformed.LeftHand.Thumb / ReverseFactor) * ThumbAnglesOpen_N.Z, Hierarchy); + } - AddRotation("ring_01_l", FingerData.LeftHand.Ring * RingAngles_N.X, Hierarchy); - AddRotation("ring_02_l", FingerData.LeftHand.Ring * RingAngles_N.Y, Hierarchy); - AddRotation("ring_03_l", FingerData.LeftHand.Ring * RingAngles_N.Z, Hierarchy); + if (FingerDataTransformed.LeftHand.Index >= 0.f) { + AddRotation("index_01_l", FingerDataTransformed.LeftHand.Index * IndexAnglesClosed_N.X, Hierarchy); + AddRotation("index_02_l", FingerDataTransformed.LeftHand.Index * IndexAnglesClosed_N.Y, Hierarchy); + AddRotation("index_03_l", FingerDataTransformed.LeftHand.Index * IndexAnglesClosed_N.Z, Hierarchy); + } + else { + AddRotation("index_01_l", FingerDataTransformed.LeftHand.Index * IndexAnglesOpen_N.X / ReverseFactor, Hierarchy); + AddRotation("index_02_l", FingerDataTransformed.LeftHand.Index * IndexAnglesOpen_N.Y / ReverseFactor, Hierarchy); + AddRotation("index_03_l", FingerDataTransformed.LeftHand.Index * IndexAnglesOpen_N.Z / ReverseFactor, Hierarchy); + } - AddRotation("pinky_01_l", FingerData.LeftHand.Pinky * PinkyAngles_N.X, Hierarchy); - AddRotation("pinky_02_l", FingerData.LeftHand.Pinky * PinkyAngles_N.Y, Hierarchy); - AddRotation("pinky_03_l", FingerData.LeftHand.Pinky * PinkyAngles_N.Z, Hierarchy); + if (FingerDataTransformed.LeftHand.Middle >= 0.f) { + AddRotation("middle_01_l", FingerDataTransformed.LeftHand.Middle * MiddleAnglesClosed_N.X, Hierarchy); + AddRotation("middle_02_l", FingerDataTransformed.LeftHand.Middle * MiddleAnglesClosed_N.Y, Hierarchy); + AddRotation("middle_03_l", FingerDataTransformed.LeftHand.Middle * MiddleAnglesClosed_N.Z, Hierarchy); + } + else { + AddRotation("middle_01_l", FingerDataTransformed.LeftHand.Middle * MiddleAnglesOpen_N.X / ReverseFactor, Hierarchy); + AddRotation("middle_02_l", FingerDataTransformed.LeftHand.Middle * MiddleAnglesOpen_N.Y / ReverseFactor, Hierarchy); + AddRotation("middle_03_l", FingerDataTransformed.LeftHand.Middle * MiddleAnglesOpen_N.Z / ReverseFactor, Hierarchy); + } + if (FingerDataTransformed.LeftHand.Ring >= 0.f) { + AddRotation("ring_01_l", FingerDataTransformed.LeftHand.Ring * RingAnglesClosed_N.X, Hierarchy); + AddRotation("ring_02_l", FingerDataTransformed.LeftHand.Ring * RingAnglesClosed_N.Y, Hierarchy); + AddRotation("ring_03_l", FingerDataTransformed.LeftHand.Ring * RingAnglesClosed_N.Z, Hierarchy); + } + else { + AddRotation("ring_01_l", FingerDataTransformed.LeftHand.Ring * RingAnglesOpen_N.X / ReverseFactor, Hierarchy); + AddRotation("ring_02_l", FingerDataTransformed.LeftHand.Ring * RingAnglesOpen_N.Y / ReverseFactor, Hierarchy); + AddRotation("ring_03_l", FingerDataTransformed.LeftHand.Ring * RingAnglesOpen_N.Z / ReverseFactor, Hierarchy); + } - AddRotation("thumb_01_r", FingerData.RightHand.Thumb * Thumb01YAngle, Hierarchy); - AddRotation("thumb_01_r", FingerData.RightHand.Thumb * ThumbAngles_N.X, Hierarchy, "Z"); - AddRotation("thumb_02_r", FingerData.RightHand.Thumb * ThumbAngles_N.Y, Hierarchy); - AddRotation("thumb_03_r", FingerData.RightHand.Thumb * ThumbAngles_N.Z, Hierarchy); + if (FingerDataTransformed.LeftHand.Pinky >= 0.f) { + AddRotation("pinky_01_l", FingerDataTransformed.LeftHand.Pinky * PinkyAnglesClosed_N.X, Hierarchy); + AddRotation("pinky_02_l", FingerDataTransformed.LeftHand.Pinky * PinkyAnglesClosed_N.Y, Hierarchy); + AddRotation("pinky_03_l", FingerDataTransformed.LeftHand.Pinky * PinkyAnglesClosed_N.Z, Hierarchy); + } + else { + AddRotation("pinky_01_l", FingerDataTransformed.LeftHand.Pinky * PinkyAnglesOpen_N.X / ReverseFactor, Hierarchy); + AddRotation("pinky_02_l", FingerDataTransformed.LeftHand.Pinky * PinkyAnglesOpen_N.Y / ReverseFactor, Hierarchy); + AddRotation("pinky_03_l", FingerDataTransformed.LeftHand.Pinky * PinkyAnglesOpen_N.Z / ReverseFactor, Hierarchy); + } - AddRotation("index_01_r", FingerData.RightHand.Index * IndexAngles_N.X, Hierarchy); - AddRotation("index_02_r", FingerData.RightHand.Index * IndexAngles_N.Y, Hierarchy); - AddRotation("index_03_r", FingerData.RightHand.Index * IndexAngles_N.Z, Hierarchy); + if (FingerDataTransformed.RightHand.Thumb >= 0.f) { + AddRotation("thumb_01_r", FingerDataTransformed.RightHand.Thumb * Thumb01YAngleClosed, Hierarchy); + AddRotation("thumb_01_r", FingerDataTransformed.RightHand.Thumb * ThumbAnglesClosed_N.X, Hierarchy, "Z"); + AddRotation("thumb_02_r", FingerDataTransformed.RightHand.Thumb * ThumbAnglesClosed_N.Y, Hierarchy); + AddRotation("thumb_03_r", FingerDataTransformed.RightHand.Thumb * ThumbAnglesClosed_N.Z, Hierarchy); + } + else { + AddRotation("thumb_01_r", FingerDataTransformed.RightHand.Thumb * Thumb01YAngleClosed, Hierarchy); + AddRotation("thumb_01_r", FingerDataTransformed.RightHand.Thumb * ThumbAnglesOpen_N.X / ReverseFactor, Hierarchy, "Z"); + AddRotation("thumb_02_r", FingerDataTransformed.RightHand.Thumb * ThumbAnglesOpen_N.Y / ReverseFactor, Hierarchy); + AddRotation("thumb_03_r", FingerDataTransformed.RightHand.Thumb * ThumbAnglesOpen_N.Z / ReverseFactor, Hierarchy); + } - AddRotation("middle_01_r", FingerData.RightHand.Middle * MiddleAngles_N.X, Hierarchy); - AddRotation("middle_02_r", FingerData.RightHand.Middle * MiddleAngles_N.Y, Hierarchy); - AddRotation("middle_03_r", FingerData.RightHand.Middle * MiddleAngles_N.Z, Hierarchy); + if (FingerDataTransformed.RightHand.Index >= 0.f) { + AddRotation("index_01_r", FingerDataTransformed.RightHand.Index * IndexAnglesClosed_N.X, Hierarchy); + AddRotation("index_02_r", FingerDataTransformed.RightHand.Index * IndexAnglesClosed_N.Y, Hierarchy); + AddRotation("index_03_r", FingerDataTransformed.RightHand.Index * IndexAnglesClosed_N.Z, Hierarchy); + } + else { + AddRotation("index_01_r", FingerDataTransformed.RightHand.Index * IndexAnglesOpen_N.X / ReverseFactor, Hierarchy); + AddRotation("index_02_r", FingerDataTransformed.RightHand.Index * IndexAnglesOpen_N.Y / ReverseFactor, Hierarchy); + AddRotation("index_03_r", FingerDataTransformed.RightHand.Index * IndexAnglesOpen_N.Z / ReverseFactor, Hierarchy); + } - AddRotation("ring_01_r", FingerData.RightHand.Ring * RingAngles_N.X, Hierarchy); - AddRotation("ring_02_r", FingerData.RightHand.Ring * RingAngles_N.Y, Hierarchy); - AddRotation("ring_03_r", FingerData.RightHand.Ring * RingAngles_N.Z, Hierarchy); + if (FingerDataTransformed.RightHand.Middle >= 0.f) { + AddRotation("middle_01_r", FingerDataTransformed.RightHand.Middle * MiddleAnglesClosed_N.X, Hierarchy); + AddRotation("middle_02_r", FingerDataTransformed.RightHand.Middle * MiddleAnglesClosed_N.Y, Hierarchy); + AddRotation("middle_03_r", FingerDataTransformed.RightHand.Middle * MiddleAnglesClosed_N.Z, Hierarchy); + } + else { + AddRotation("middle_01_r", FingerDataTransformed.RightHand.Middle * MiddleAnglesOpen_N.X / ReverseFactor, Hierarchy); + AddRotation("middle_02_r", FingerDataTransformed.RightHand.Middle * MiddleAnglesOpen_N.Y / ReverseFactor, Hierarchy); + AddRotation("middle_03_r", FingerDataTransformed.RightHand.Middle * MiddleAnglesOpen_N.Z / ReverseFactor, Hierarchy); + } - AddRotation("pinky_01_r", FingerData.RightHand.Pinky * PinkyAngles_N.X, Hierarchy); - AddRotation("pinky_02_r", FingerData.RightHand.Pinky * PinkyAngles_N.Y, Hierarchy); - AddRotation("pinky_03_r", FingerData.RightHand.Pinky * PinkyAngles_N.Z, Hierarchy); + if (FingerDataTransformed.RightHand.Ring >= 0.f) { + AddRotation("ring_01_r", FingerDataTransformed.RightHand.Ring * RingAnglesClosed_N.X, Hierarchy); + AddRotation("ring_02_r", FingerDataTransformed.RightHand.Ring * RingAnglesClosed_N.Y, Hierarchy); + AddRotation("ring_03_r", FingerDataTransformed.RightHand.Ring * RingAnglesClosed_N.Z, Hierarchy); + } + else { + AddRotation("ring_01_r", FingerDataTransformed.RightHand.Ring* RingAnglesOpen_N.X / ReverseFactor, Hierarchy); + AddRotation("ring_02_r", FingerDataTransformed.RightHand.Ring* RingAnglesOpen_N.Y / ReverseFactor, Hierarchy); + AddRotation("ring_03_r", FingerDataTransformed.RightHand.Ring* RingAnglesOpen_N.Z / ReverseFactor, Hierarchy); + } + if (FingerDataTransformed.RightHand.Pinky >= 0.f) { + AddRotation("pinky_01_r", FingerDataTransformed.RightHand.Pinky * PinkyAnglesClosed_N.X, Hierarchy); + AddRotation("pinky_02_r", FingerDataTransformed.RightHand.Pinky * PinkyAnglesClosed_N.Y, Hierarchy); + AddRotation("pinky_03_r", FingerDataTransformed.RightHand.Pinky * PinkyAnglesClosed_N.Z, Hierarchy); + } + else { + AddRotation("pinky_01_r", FingerDataTransformed.RightHand.Pinky* PinkyAnglesOpen_N.X / ReverseFactor, Hierarchy); + AddRotation("pinky_02_r", FingerDataTransformed.RightHand.Pinky* PinkyAnglesOpen_N.Y / ReverseFactor, Hierarchy); + AddRotation("pinky_03_r", FingerDataTransformed.RightHand.Pinky* PinkyAnglesOpen_N.Z / ReverseFactor, Hierarchy); + } //SPLAYS diff --git a/Source/MoCapPlugin/Public/MCAnimInstance.h b/Source/MoCapPlugin/Public/MCAnimInstance.h index 8166dd0efb3b4a24c3535998e7e39383baf2d344..b0425c8acb3ce2f5297160edfee6da5a55c3ffa7 100644 --- a/Source/MoCapPlugin/Public/MCAnimInstance.h +++ b/Source/MoCapPlugin/Public/MCAnimInstance.h @@ -59,6 +59,12 @@ public: UPROPERTY(BlueprintReadWrite) bool UseHandPos; + UPROPERTY(BlueprintReadWrite) + bool FixChest; + + UPROPERTY(BlueprintReadWrite) + bool FixHead; + UPROPERTY(BlueprintReadWrite) bool SkipCalibration; @@ -74,6 +80,9 @@ public: UPROPERTY(BlueprintReadWrite) FVector Scale; + UPROPERTY(BlueprintReadWrite) + float FingerAngleScale = 1.f; + 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 473eb4c723e6c2891be8d95ae627b125ef842ed8..8404e8eaa73fc433309ebdbfdcca1eafc38552b2 100644 --- a/Source/MoCapPlugin/Public/MCController.h +++ b/Source/MoCapPlugin/Public/MCController.h @@ -145,6 +145,9 @@ public: /*------------GENERAL PROPERTIES-------------*/ + UPROPERTY(EditAnywhere, meta = (DisplayName = "Scale Mesh", Category = "MotionCapture")) + float Scale = -1.f; + UPROPERTY(EditAnywhere, meta = (DisplayName = "Path to Measurement File", Category = "MotionCapture")) FString MeasurementPath = "Plugins/MocapPlugin/Content/Measurements.txt"; @@ -233,6 +236,12 @@ public: //UPROPERTY(EditAnywhere, meta = (DisplayName = "Chest Control Keep Length", Category = "MotionCapture Anim")) bool ChestKeepLength = false; + UPROPERTY(EditAnywhere, meta = (DisplayName = "Set Chest Transform After Arm IK", Category = "MotionCapture Anim")) + bool FixChest = true; + + UPROPERTY(EditAnywhere, meta = (DisplayName = "Hip Shift To Reducing Center", Category = "MotionCapture Anim")) + bool HipShiftToReducingCenter = false; + UPROPERTY(EditAnywhere, meta = (DisplayName = "Hip Reducing Center", Category = "MotionCapture Anim")) FVector HipReducingCenter; @@ -248,8 +257,11 @@ public: UPROPERTY(EditAnywhere, meta = (DisplayName = "Lock Feet To Green Foot Indicators", Category = "MotionCapture Anim")) bool LockFeet = true; - UPROPERTY(EditAnywhere, meta = (DisplayName = "Cap On Pulling Down Body For Foot Stability", Category = "MotionCapture Anim")) - float MoveDownCap = 8.0f; + UPROPERTY(EditAnywhere, meta = (DisplayName = "Foot Height Target", Category = "MotionCapture Anim")) + float FootHeightTarget = 0.f; + + UPROPERTY(EditAnywhere, meta = (DisplayName = "Max Leg Length", Category = "MotionCapture Anim")) + float MaxLegLength = 96.f; UPROPERTY(EditAnywhere, meta = (DisplayName = "Use Captured Hand Position", Category = "MotionCapture Anim")) bool UseHandPosition = true; @@ -257,6 +269,10 @@ public: UPROPERTY(EditAnywhere, meta = (DisplayName = "Limit Hand Rotation (can cause rotational jumping)", Category = "MotionCapture Anim")) bool LimitHandRotation = false; + UPROPERTY(EditAnywhere, meta = (DisplayName = "Finger Angle Scale", Category = "MotionCapture Anim")) + float FingerAngleScale = 1.f; + + //UPROPERTY(EditAnywhere, meta = (DisplayName = "Edit Offsets Mode", Category = "MotionCapture Anim")) bool EditOffsetMode = false; diff --git a/Source/MoCapPlugin/Public/MCDefines.h b/Source/MoCapPlugin/Public/MCDefines.h index 49400bf80a8135f10e0f4e2aa4052aab9cfacf47..69c681028898d5a17c37f7d3759e88a9bb32d74a 100644 --- a/Source/MoCapPlugin/Public/MCDefines.h +++ b/Source/MoCapPlugin/Public/MCDefines.h @@ -20,19 +20,13 @@ enum EBodyPart { Head = 0 UMETA(DisplayName = "Head"), HandL = 1 UMETA(DisplayName = "HandL"), HandR = 2 UMETA(DisplayName = "HandR"), - FootL = 3 UMETA(DisplayName = "FootL"), - FootR = 4 UMETA(DisplayName = "FootR"), - UpperArmL = 5 UMETA(DisplayName = "UpperArmL"), - UpperArmR = 6 UMETA(DisplayName = "UpperArmR"), - LowerArmL = 7 UMETA(DisplayName = "LowerArmL"), - LowerArmR = 8 UMETA(DisplayName = "LowerArmR"), - UpperLegL = 9 UMETA(DisplayName = "UpperLegL"), - UpperLegR = 10 UMETA(DisplayName = "UpperLegR"), - LowerLegL = 11 UMETA(DisplayName = "LowerLegL"), - LowerLegR = 12 UMETA(DisplayName = "LowerLegR"), - UpperBody = 13 UMETA(DisplayName = "UpperBody"), - LowerBody = 14 UMETA(DisplayName = "LowerBody"), - LAST = 15 + LowerArmL = 3 UMETA(DisplayName = "LowerArmL"), + LowerArmR = 4 UMETA(DisplayName = "LowerArmR"), + LowerLegL = 5 UMETA(DisplayName = "LowerLegL"), + LowerLegR = 6 UMETA(DisplayName = "LowerLegR"), + UpperBody = 7 UMETA(DisplayName = "UpperBody"), + LowerBody = 8 UMETA(DisplayName = "LowerBody"), + LAST = 9 }; USTRUCT(BlueprintType) @@ -135,30 +129,12 @@ struct FSensorData { UPROPERTY(BlueprintReadOnly) FSensorDataEntry HandR; - UPROPERTY(BlueprintReadOnly) - FSensorDataEntry FootL; - - UPROPERTY(BlueprintReadOnly) - FSensorDataEntry FootR; - - UPROPERTY(BlueprintReadOnly) - FSensorDataEntry UpperArmL; - - UPROPERTY(BlueprintReadOnly) - FSensorDataEntry UpperArmR; - UPROPERTY(BlueprintReadOnly) FSensorDataEntry LowerArmL; UPROPERTY(BlueprintReadOnly) FSensorDataEntry LowerArmR; - UPROPERTY(BlueprintReadOnly) - FSensorDataEntry UpperLegL; - - UPROPERTY(BlueprintReadOnly) - FSensorDataEntry UpperLegR; - UPROPERTY(BlueprintReadOnly) FSensorDataEntry LowerLegL; @@ -374,4 +350,39 @@ public: UPROPERTY(BlueprintReadWrite) bool loaded = false; +}; + +USTRUCT(BlueprintType) +struct FFingerAngles { + GENERATED_BODY() + +public: + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FVector Thumb; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FVector Index; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FVector Middle; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FVector Ring; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FVector Pinky; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + float Thumb_Index; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + float Index_Middle; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + float Middle_Ring; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + float Ring_Pinky; + }; \ No newline at end of file diff --git a/Source/MoCapPlugin/Public/MCLogHandler.h b/Source/MoCapPlugin/Public/MCLogHandler.h index 0e9e6fbe1f8f536de9d2a9b758ba472e2fbc02c5..7241cc62d3fbc74a18c9398714aba1179412103f 100644 --- a/Source/MoCapPlugin/Public/MCLogHandler.h +++ b/Source/MoCapPlugin/Public/MCLogHandler.h @@ -16,6 +16,7 @@ public: FString CurLog; + FString GetSessionIdentifier(); void NewLog(const FString& Name); void LogData(const FString& Message); diff --git a/Source/MoCapPlugin/Public/MCPawn.h b/Source/MoCapPlugin/Public/MCPawn.h index 588b0eb2ec3ab7377f9a467a711eed7ae8f8523d..c5cabe56c6a60721e7d64b2089f3f07f60fca5d5 100644 --- a/Source/MoCapPlugin/Public/MCPawn.h +++ b/Source/MoCapPlugin/Public/MCPawn.h @@ -28,6 +28,7 @@ public: bool UseKneeAsFoot; + UPROPERTY(EditAnywhere) bool ShowDeviceModels = true; UPROPERTY(BlueprintReadOnly) @@ -58,7 +59,6 @@ public: UFUNCTION(BlueprintCallable) UMCAnimInstance* GetAnimInstance(); USkeleton* GetSkeleton(); - FName GetBoneNameFromBodyPart(EBodyPart BodyPart); void SetMeshVisibility(bool visible); void LoadMeasurementFile(const FString& Filepath); @@ -72,6 +72,8 @@ public: void OffsetSensorData(EBodyPart part, FVector& Pos, FQuat& Rot, bool inverse = false); + void SetShowDeviceModels(bool show); + private: void AddSensorDataToJson(TSharedPtr<FJsonObject> JsonObjectFull, const FSensor& Sensor); diff --git a/Source/MoCapPlugin/Public/MCRigUnits.h b/Source/MoCapPlugin/Public/MCRigUnits.h index 80edb1031f3ee31b25dbde7fb66ece2b54e7fb17..06b49ad4118d2f52733c3951f825142e9ae2c619 100644 --- a/Source/MoCapPlugin/Public/MCRigUnits.h +++ b/Source/MoCapPlugin/Public/MCRigUnits.h @@ -45,19 +45,34 @@ struct FRigUnit_ApplyFingerData : public FRigUnitMutable FFingerData FingerData; UPROPERTY(meta = (Input)) - FVector ThumbAngles; + FVector ThumbAnglesOpen; UPROPERTY(meta = (Input)) - FVector IndexAngles; + FVector IndexAnglesOpen; UPROPERTY(meta = (Input)) - FVector MiddleAngles; + FVector MiddleAnglesOpen; UPROPERTY(meta = (Input)) - FVector RingAngles; + FVector RingAnglesOpen; UPROPERTY(meta = (Input)) - FVector PinkyAngles; + FVector PinkyAnglesOpen; + + UPROPERTY(meta = (Input)) + FVector ThumbAnglesClosed; + + UPROPERTY(meta = (Input)) + FVector IndexAnglesClosed; + + UPROPERTY(meta = (Input)) + FVector MiddleAnglesClosed; + + UPROPERTY(meta = (Input)) + FVector RingAnglesClosed; + + UPROPERTY(meta = (Input)) + FVector PinkyAnglesClosed; UPROPERTY(meta = (Input)) float Thumb_Index_Angle; diff --git a/Source/MoCapPluginEditor/MoCapPluginEditor.Build.cs b/Source/MoCapPluginEditor/MoCapPluginEditor.Build.cs index 85cb84c6201f55ab630da5267874726730373a9f..35abc5b04ec65947ffec3a41016f71c55083452b 100644 --- a/Source/MoCapPluginEditor/MoCapPluginEditor.Build.cs +++ b/Source/MoCapPluginEditor/MoCapPluginEditor.Build.cs @@ -11,7 +11,7 @@ public class MoCapPluginEditor : ModuleRules PrivateIncludePaths.AddRange(new string[] { }); PublicIncludePaths.AddRange(new string[] { }); - PublicDependencyModuleNames.AddRange(new string[] { "CoreUObject", "Engine", "Core", "AnimGraph", "AnimGraphRunTime", "BlueprintGraph", "MoCapPlugin" }); + PublicDependencyModuleNames.AddRange(new string[] { "CoreUObject", "Engine", "Core", "AnimGraph", "AnimGraphRuntime", "BlueprintGraph", "MoCapPlugin" }); } } \ No newline at end of file