From 2e06b700c2f985766445d8ea8782801079d0fc83 Mon Sep 17 00:00:00 2001 From: pnossol <patrick.nossol@gmail.com> Date: Tue, 31 May 2022 15:15:00 +0200 Subject: [PATCH] Created a more elegant and efficient fix. Yet to test --- Source/MoCapPlugin/Private/MCAnimInstance.cpp | 5 +- Source/MoCapPlugin/Private/MCPawn.cpp | 129 +++++++----------- Source/MoCapPlugin/Private/MCRigUnits.cpp | 36 +---- Source/MoCapPlugin/Public/MCAnimInstance.h | 2 +- Source/MoCapPlugin/Public/MCDefines.h | 6 - Source/MoCapPlugin/Public/MCPawn.h | 2 +- 6 files changed, 55 insertions(+), 125 deletions(-) diff --git a/Source/MoCapPlugin/Private/MCAnimInstance.cpp b/Source/MoCapPlugin/Private/MCAnimInstance.cpp index e2c7ba1..6e77594 100644 --- a/Source/MoCapPlugin/Private/MCAnimInstance.cpp +++ b/Source/MoCapPlugin/Private/MCAnimInstance.cpp @@ -199,7 +199,7 @@ void UMCAnimInstance::SetSensorData(EBodyPart BodyPart, const FQuat& Rot) { entry->valid = true; } -void UMCAnimInstance::SetSensorOffset(EBodyPart BodyPart, float Dist, const FQuat& Rot, const FQuat& AxisRotDiff, const FTransform& DeltaTransform) { +void UMCAnimInstance::SetSensorOffset(EBodyPart BodyPart, const FTransform& DeltaTransform) { FSensorOffset* entry = nullptr; @@ -234,9 +234,6 @@ void UMCAnimInstance::SetSensorOffset(EBodyPart BodyPart, float Dist, const FQua } - entry->Distance = Dist; - entry->Rot = Rot; - entry->AxisRotDiff = AxisRotDiff; entry->DeltaTransform = DeltaTransform; } diff --git a/Source/MoCapPlugin/Private/MCPawn.cpp b/Source/MoCapPlugin/Private/MCPawn.cpp index 8c2dcae..2422033 100644 --- a/Source/MoCapPlugin/Private/MCPawn.cpp +++ b/Source/MoCapPlugin/Private/MCPawn.cpp @@ -323,39 +323,43 @@ void AMCPawn::CalcSensorOffsets(UMCLogHandler& LogHandler, bool UseLastOffsets, RotInv = Rot.Inverse(); SocketName1 = Tracker.SocketName1; } - //TODO it matters where the pawn is located in the level for this offset capture! Should not be this way, but is it acceptable? + //TODO ?? Does it? Test! it matters where the pawn is located in the level for this offset capture! Should not be this way, but is it acceptable? if (Tracker.SocketName1 != "") { if (!UseLastOffsets) { - FVector PosOffset1 = SkeletalMesh->GetSocketLocation(SocketName1) - Loc; - JsonTracker->SetStringField("Dist1", FString::SanitizeFloat(PosOffset1.Size())); - FQuat AxisRotDiff = FQuat::FindBetween(-Rot.GetAxisX(), PosOffset1); - JsonTracker->SetStringField("AxisRot1X", FString::SanitizeFloat(AxisRotDiff.X)); - JsonTracker->SetStringField("AxisRot1Y", FString::SanitizeFloat(AxisRotDiff.Y)); - JsonTracker->SetStringField("AxisRot1Z", FString::SanitizeFloat(AxisRotDiff.Z)); - JsonTracker->SetStringField("AxisRot1W", FString::SanitizeFloat(AxisRotDiff.W)); - FQuat RotOffset1 = RotInv * SkeletalMesh->GetSocketQuaternion(SocketName1); - JsonTracker->SetStringField("Rot1X", FString::SanitizeFloat(RotOffset1.X)); - JsonTracker->SetStringField("Rot1Y", FString::SanitizeFloat(RotOffset1.Y)); - JsonTracker->SetStringField("Rot1Z", FString::SanitizeFloat(RotOffset1.Z)); - JsonTracker->SetStringField("Rot1W", FString::SanitizeFloat(RotOffset1.W)); - - Offset->AxisRotDiff = AxisRotDiff; - Offset->Rot = RotOffset1; - Offset->Distance = PosOffset1.Size(); + + FTransform DataTransform(Rot, Loc); + FTransform BoneTransform(SkeletalMesh->GetSocketQuaternion(SocketName1), SkeletalMesh->GetSocketLocation(SocketName1)); + FTransform DeltaTransform = BoneTransform.GetRelativeTransform(DataTransform); + + FVector DeltaPos = DeltaTransform.GetTranslation(); + FQuat DeltaRot = DeltaTransform.GetRotation(); + + JsonTracker->SetStringField("PosX", FString::SanitizeFloat(DeltaPos.X)); + JsonTracker->SetStringField("PosY", FString::SanitizeFloat(DeltaPos.X)); + JsonTracker->SetStringField("PosZ", FString::SanitizeFloat(DeltaPos.X)); + + JsonTracker->SetStringField("RotX", FString::SanitizeFloat(DeltaRot.X)); + JsonTracker->SetStringField("RotY", FString::SanitizeFloat(DeltaRot.Y)); + JsonTracker->SetStringField("RotZ", FString::SanitizeFloat(DeltaRot.Z)); + JsonTracker->SetStringField("RotW", FString::SanitizeFloat(DeltaRot.W)); + + Offset->DeltaTransform = DeltaTransform; + } else { - float Distance = Offset->Distance; - JsonTracker->SetStringField("Dist1", FString::SanitizeFloat(Distance)); - FQuat AxisRotDiff = Offset->AxisRotDiff; - JsonTracker->SetStringField("AxisRot1X", FString::SanitizeFloat(AxisRotDiff.X)); - JsonTracker->SetStringField("AxisRot1Y", FString::SanitizeFloat(AxisRotDiff.Y)); - JsonTracker->SetStringField("AxisRot1Z", FString::SanitizeFloat(AxisRotDiff.Z)); - JsonTracker->SetStringField("AxisRot1W", FString::SanitizeFloat(AxisRotDiff.W)); - FQuat RotOffset1 = Offset->Rot; - JsonTracker->SetStringField("Rot1X", FString::SanitizeFloat(RotOffset1.X)); - JsonTracker->SetStringField("Rot1Y", FString::SanitizeFloat(RotOffset1.Y)); - JsonTracker->SetStringField("Rot1Z", FString::SanitizeFloat(RotOffset1.Z)); - JsonTracker->SetStringField("Rot1W", FString::SanitizeFloat(RotOffset1.W)); + + FVector DeltaPos = Offset->DeltaTransform.GetTranslation(); + FQuat DeltaRot = Offset->DeltaTransform.GetRotation(); + + JsonTracker->SetStringField("PosX", FString::SanitizeFloat(DeltaPos.X)); + JsonTracker->SetStringField("PosY", FString::SanitizeFloat(DeltaPos.X)); + JsonTracker->SetStringField("PosZ", FString::SanitizeFloat(DeltaPos.X)); + + JsonTracker->SetStringField("RotX", FString::SanitizeFloat(DeltaRot.X)); + JsonTracker->SetStringField("RotY", FString::SanitizeFloat(DeltaRot.Y)); + JsonTracker->SetStringField("RotZ", FString::SanitizeFloat(DeltaRot.Z)); + JsonTracker->SetStringField("RotW", FString::SanitizeFloat(DeltaRot.W)); + } } @@ -476,39 +480,21 @@ void AMCPawn::InputViveOffsetsToAnimInstance(TSharedPtr<FJsonObject> Data) { TSharedPtr<FJsonObject> JsonObj = Data->GetObjectField(Type); - if (JsonObj->HasField("Dist1")) { - const float RotX = FCString::Atof(*JsonObj->GetStringField("Rot1X")); - const float RotY = FCString::Atof(*JsonObj->GetStringField("Rot1Y")); - const float RotZ = FCString::Atof(*JsonObj->GetStringField("Rot1Z")); - const float RotW = FCString::Atof(*JsonObj->GetStringField("Rot1W")); - FQuat Rot(RotX, RotY, RotZ, RotW); + if (JsonObj->HasField("RotX")) { - const float AxisRotX = FCString::Atof(*JsonObj->GetStringField("AxisRot1X")); - const float AxisRotY = FCString::Atof(*JsonObj->GetStringField("AxisRot1Y")); - const float AxisRotZ = FCString::Atof(*JsonObj->GetStringField("AxisRot1Z")); - const float AxisRotW = FCString::Atof(*JsonObj->GetStringField("AxisRot1W")); - FQuat AxisRot(AxisRotX, AxisRotY, AxisRotZ, AxisRotW); + const float RotX = FCString::Atof(*JsonObj->GetStringField("RotX")); + const float RotY = FCString::Atof(*JsonObj->GetStringField("RotY")); + const float RotZ = FCString::Atof(*JsonObj->GetStringField("RotZ")); + const float RotW = FCString::Atof(*JsonObj->GetStringField("RotW")); + FQuat Rot(RotX, RotY, RotZ, RotW); - const float Dist = FCString::Atof(*JsonObj->GetStringField("Dist1")); + const float PosX = FCString::Atof(*JsonObj->GetStringField("PosX")); + const float PosY = FCString::Atof(*JsonObj->GetStringField("PosY")); + const float PosZ = FCString::Atof(*JsonObj->GetStringField("PosZ")); + FVector Pos(PosX, PosY, PosZ); - AI->SetSensorOffset(BodyPart, Dist, Rot, AxisRot, FTransform::Identity); - - EBodyPart NamePart = BodyPart; - if (BodyPart == EBodyPart::LowerLegL) { - NamePart = EBodyPart::FootL; - } - if (BodyPart == EBodyPart::LowerLegR) { - NamePart = EBodyPart::FootR; - } - FName BoneName = GetBoneNameFromBodyPart(BodyPart); - FVector OffsetPos = SkeletalMesh->GetSocketLocation(BoneName); - FQuat OffsetRot = SkeletalMesh->GetSocketQuaternion(BoneName); - OffsetSensorData(BodyPart, OffsetPos, OffsetRot, true); + AI->SetSensorOffset(BodyPart, FTransform(Rot, Pos)); - FTransform DataTransform(OffsetRot, OffsetPos); - FTransform FootTransform(SkeletalMesh->GetSocketRotation(BoneName), SkeletalMesh->GetSocketLocation(BoneName)); - FTransform DeltaTransform = FootTransform.GetRelativeTransform(DataTransform); - AI->SetSensorOffset(BodyPart, Dist, Rot, AxisRot, DeltaTransform); } } @@ -544,7 +530,7 @@ void AMCPawn::InputFingerDataToAnimInstance(TSharedPtr<FJsonObject> Data) { } -void AMCPawn::OffsetSensorData(EBodyPart part, FVector & Pos, FQuat & Rot, bool Inverse) { +void AMCPawn::OffsetSensorData(EBodyPart part, FVector & Pos, FQuat & Rot) { FSensorOffset* Offset = nullptr; UMCAnimInstance* AI = GetAnimInstance(); @@ -581,26 +567,11 @@ void AMCPawn::OffsetSensorData(EBodyPart part, FVector & Pos, FQuat & Rot, bool break; } - FQuat RotTmp = Rot; - - /* - * ROT - * FootRot = DataRot * RotOffset - * DataRot = FootRot * Inv(RotOffset) - * - * POS - * FootPos = DataPos - DistOffset * (AxisRotOffset * DataRot).AxisX() - * DataPos = FootPos + DistOffset * (AxisRotOffset * DataRot).AxisX() - */ - - if (!Inverse) { - Rot = Rot * Offset->Rot; - Pos = Pos - Offset->Distance * (Offset->AxisRotDiff * RotTmp).GetAxisX(); - } - else { - Rot = Rot * Offset->Rot.Inverse(); - Pos = Pos + Offset->Distance * (Offset->AxisRotDiff * Rot).GetAxisX(); - } + FTransform Transform(Rot, Pos); + Transform = Offset->DeltaTransform * Transform; + + Rot = Transform.GetRotation(); + Pos = Transform.GetTranslation(); } diff --git a/Source/MoCapPlugin/Private/MCRigUnits.cpp b/Source/MoCapPlugin/Private/MCRigUnits.cpp index 0da6b57..29158ec 100644 --- a/Source/MoCapPlugin/Private/MCRigUnits.cpp +++ b/Source/MoCapPlugin/Private/MCRigUnits.cpp @@ -14,41 +14,9 @@ FRigUnit_SensorOffsets::FRigUnit_SensorOffsets() { FRigUnit_SensorOffsets_Execute() { DECLARE_SCOPE_HIERARCHICAL_COUNTER_RIGUNIT() - OutTrans.SetRotation(ControlTrans.GetRotation() * SensorOffset.Rot); + //NewControl = Bone * Control(-1) * NewControl + OutTrans = SensorOffset.DeltaTransform * ControlTrans; - int option = 2; - - //original - if (option == 0) { - OutTrans.SetTranslation(ControlTrans.GetTranslation() - SensorOffset.Distance * (SensorOffset.AxisRotDiff * ControlTrans.GetRotation()).GetAxisX()); - } - //no trans offset - else if (option == 1) { - - FQuat AxisRotDiff = SensorOffset.AxisRotDiff; - if (!AxisRotDiff.IsNormalized()) { - AxisRotDiff = AxisRotDiff.GetNormalized(); - } - - FQuat ControlRot = ControlTrans.GetRotation(); - if (!ControlRot.IsNormalized()) { - ControlRot = ControlRot.GetNormalized(); - } - - check(AxisRotDiff.IsNormalized()); - check(ControlRot.IsNormalized()); - FQuat OffsetDir = AxisRotDiff * ControlRot; - check(OffsetDir.IsNormalized()); - FVector OffsetVec = AxisRotDiff.RotateVector(ControlRot.GetAxisX()); - check(OffsetVec.IsUnit()); - OutTrans.SetTranslation(ControlTrans.GetTranslation() - SensorOffset.Distance * OffsetVec); - } - //use delta trans - else if (option == 2) { - //NewControl = Bone * Control(-1) * NewControl - OutTrans = SensorOffset.DeltaTransform * ControlTrans; - - } } FRigUnit_ApplyFingerData::FRigUnit_ApplyFingerData() { diff --git a/Source/MoCapPlugin/Public/MCAnimInstance.h b/Source/MoCapPlugin/Public/MCAnimInstance.h index c32b741..0fbe328 100644 --- a/Source/MoCapPlugin/Public/MCAnimInstance.h +++ b/Source/MoCapPlugin/Public/MCAnimInstance.h @@ -57,6 +57,6 @@ public: void SetSensorData(EBodyPart BodyPart, const FVector& Pos, const FQuat& Rot); void SetSensorData(EBodyPart BodyPart, const FQuat& Rot); - void SetSensorOffset(EBodyPart BodyPart, float Dist, const FQuat& Rot, const FQuat& AxisRotDiff, const FTransform& DeltaTransform); + void SetSensorOffset(EBodyPart BodyPart, const FTransform& DeltaTransform); }; diff --git a/Source/MoCapPlugin/Public/MCDefines.h b/Source/MoCapPlugin/Public/MCDefines.h index f3ec181..226ab52 100644 --- a/Source/MoCapPlugin/Public/MCDefines.h +++ b/Source/MoCapPlugin/Public/MCDefines.h @@ -224,12 +224,6 @@ USTRUCT(BlueprintType) struct FSensorOffset { GENERATED_BODY() - UPROPERTY(BlueprintReadOnly) - float Distance; - UPROPERTY(BlueprintReadOnly) - FQuat Rot; - UPROPERTY(BlueprintReadOnly) - FQuat AxisRotDiff; UPROPERTY(BlueprintReadOnly) FTransform DeltaTransform; diff --git a/Source/MoCapPlugin/Public/MCPawn.h b/Source/MoCapPlugin/Public/MCPawn.h index 2a83c6f..61f0944 100644 --- a/Source/MoCapPlugin/Public/MCPawn.h +++ b/Source/MoCapPlugin/Public/MCPawn.h @@ -68,7 +68,7 @@ public: void InputViveOffsetsToAnimInstance(TSharedPtr<FJsonObject> Data); void InputFingerDataToAnimInstance(TSharedPtr<FJsonObject> Data); - void OffsetSensorData(EBodyPart part, FVector& Pos, FQuat& Rot, bool Inverse = false); + void OffsetSensorData(EBodyPart part, FVector& Pos, FQuat& Rot); private: -- GitLab