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