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