diff --git a/Content/MoCapMap.umap b/Content/MoCapMap.umap
index 6d1167a429a009283c14e872c6b57332534dd6c3..3a130633790a52cf2098f82ea526f22a54d7b645 100644
--- a/Content/MoCapMap.umap
+++ b/Content/MoCapMap.umap
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:92a5fa84a7731e65598ce589a146da254ef412238115d8187d6ec7ab5c455170
-size 39985
+oid sha256:9a1540b30dea1f08211b890e124aba4d3bef862ea82618770c9118f567cb2e8d
+size 35280
diff --git a/Content/SaveSequenceAnimBP.uasset b/Content/SaveSequenceAnimBP.uasset
index ef9d83bcc65dc6074fee20abbed04b2f4d3d7c63..7bc7422aa8cfdec64e066f412aec4ee49d20e50b 100644
--- a/Content/SaveSequenceAnimBP.uasset
+++ b/Content/SaveSequenceAnimBP.uasset
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:5de4bf55a201aed7ed8fc6a0c49455b41256b41f52e787ad1e3baa000fdeb2bf
-size 204376
+oid sha256:05c883fe924dd31377fef6dec79b577739c1f2e050048659540953e6f30d2851
+size 206275
diff --git a/Content/SaveSequenceRig.uasset b/Content/SaveSequenceRig.uasset
index dc8dfa13b8ecce370210974707fb42f4cc267afb..3f03ff9082ba6b67cd90341f5a2efe2199fed8ee 100644
--- a/Content/SaveSequenceRig.uasset
+++ b/Content/SaveSequenceRig.uasset
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:62d3c42edf0f9d2db2d91756dcc93681e4c7f7d801973e757ae9840ae0efbc4a
-size 4560157
+oid sha256:ccbeedce4980c6a425a2500298b6f7424dfe0fc1ebe811591bf064c85d62981c
+size 4552248
diff --git a/Source/MoCapPlugin/Private/MCAnimInstance.cpp b/Source/MoCapPlugin/Private/MCAnimInstance.cpp
index aa31c1d4dbb465ed8238ca540c880c7f0a7d14c9..e2c7ba17ef292e880560947a76ff153f73cfad92 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) {
+void UMCAnimInstance::SetSensorOffset(EBodyPart BodyPart, float Dist, const FQuat& Rot, const FQuat& AxisRotDiff, const FTransform& DeltaTransform) {
FSensorOffset* entry = nullptr;
@@ -237,5 +237,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/MCController.cpp b/Source/MoCapPlugin/Private/MCController.cpp
index d2a6025b8913918f2af4e9784ff09c0315d89c91..5da59f83dd55f46f708b0f9dcee63bd267db1158 100644
--- a/Source/MoCapPlugin/Private/MCController.cpp
+++ b/Source/MoCapPlugin/Private/MCController.cpp
@@ -346,7 +346,7 @@ void AMCController::PreprocessRecording() {
float diff = OffsetPos.Z;
FQuat OffsetRot = AnimSaveState.AnimData[0].SensorData.LowerBody.Rot;
OffsetRot = OffsetRot * FQuat(FVector(0, 0, 1), FMath::DegreesToRadians(180));
- AnimSaveState.Pawn->OffsetSensorData(EBodyPart::LowerBody, OffsetPos, OffsetRot);
+ AnimSaveState.Pawn->OffsetSensorData(EBodyPart::LowerBody, OffsetPos, OffsetRot);
diff = OffsetPos.Z - diff;
PullDownHip = diff;
}
@@ -962,7 +962,6 @@ void AMCController::SaveAnimation() {
AnimSaveState.CurrentMarker = 0;
AnimSaveState.Pawn = Pawn;
- AnimSaveState.Pawn->GetAnimInstance()->DoRig = true;
AnimSaveState.Pawn->GetAnimInstance()->DoFingers = bFingerTrackingEnabled;
AnimSaveState.Pawn->GetAnimInstance()->SnapshotAnimations.Empty();
@@ -974,6 +973,8 @@ void AMCController::SaveAnimation() {
PreprocessRecording();
+ AnimSaveState.Pawn->GetAnimInstance()->DoRig = true;
+
InputNextFrame();
}
diff --git a/Source/MoCapPlugin/Private/MCPawn.cpp b/Source/MoCapPlugin/Private/MCPawn.cpp
index b8a645420fe38842869597e44b73aa3467ef08a2..8c2dcaea9930e97f10bb6d8755e1c0575f18d970 100644
--- a/Source/MoCapPlugin/Private/MCPawn.cpp
+++ b/Source/MoCapPlugin/Private/MCPawn.cpp
@@ -153,6 +153,43 @@ 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);
}
@@ -433,6 +470,7 @@ void AMCPawn::InputViveOffsetsToAnimInstance(TSharedPtr<FJsonObject> Data) {
for (int i = 0; i < EBodyPart::LAST; i++) {
+ EBodyPart BodyPart = (EBodyPart)i;
FString Type = UEnum::GetDisplayValueAsText(EBodyPart(i)).ToString();
if (Data->HasField(Type)) {
@@ -443,15 +481,34 @@ void AMCPawn::InputViveOffsetsToAnimInstance(TSharedPtr<FJsonObject> Data) {
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);
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 Dist = FCString::Atof(*JsonObj->GetStringField("Dist1"));
- AI->SetSensorOffset((EBodyPart)i, Dist, FQuat(RotX, RotY, RotZ, RotW), FQuat(AxisRotX, AxisRotY, AxisRotZ, AxisRotW));
+ 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);
+
+ FTransform DataTransform(OffsetRot, OffsetPos);
+ FTransform FootTransform(SkeletalMesh->GetSocketRotation(BoneName), SkeletalMesh->GetSocketLocation(BoneName));
+ FTransform DeltaTransform = FootTransform.GetRelativeTransform(DataTransform);
+ AI->SetSensorOffset(BodyPart, Dist, Rot, AxisRot, DeltaTransform);
}
}
@@ -487,7 +544,7 @@ void AMCPawn::InputFingerDataToAnimInstance(TSharedPtr<FJsonObject> Data) {
}
-void AMCPawn::OffsetSensorData(EBodyPart part, FVector & Pos, FQuat & Rot) {
+void AMCPawn::OffsetSensorData(EBodyPart part, FVector & Pos, FQuat & Rot, bool Inverse) {
FSensorOffset* Offset = nullptr;
UMCAnimInstance* AI = GetAnimInstance();
@@ -526,8 +583,24 @@ void AMCPawn::OffsetSensorData(EBodyPart part, FVector & Pos, FQuat & Rot) {
FQuat RotTmp = Rot;
- Rot = Rot * Offset->Rot;
- Pos = Pos - Offset->Distance * (Offset->AxisRotDiff * RotTmp).GetAxisX();
+ /*
+ * 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();
+ }
}
diff --git a/Source/MoCapPlugin/Private/MCRigUnits.cpp b/Source/MoCapPlugin/Private/MCRigUnits.cpp
index 950e55bb1f3d1308c573e07be4b8e8991d200f76..0da6b573f737c8045f0c1476a324d1cff0a6c90c 100644
--- a/Source/MoCapPlugin/Private/MCRigUnits.cpp
+++ b/Source/MoCapPlugin/Private/MCRigUnits.cpp
@@ -16,8 +16,39 @@ FRigUnit_SensorOffsets_Execute() {
OutTrans.SetRotation(ControlTrans.GetRotation() * SensorOffset.Rot);
- OutTrans.SetTranslation(ControlTrans.GetTranslation() - SensorOffset.Distance * (SensorOffset.AxisRotDiff * ControlTrans.GetRotation()).GetAxisX());
+ 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() {
@@ -224,4 +255,21 @@ FRigUnit_FootLocking_Execute() {
}
}
+}
+
+FRigUnit_FromXYZW::FRigUnit_FromXYZW() {
+
+ X = 0.f;
+ Y = 0.f;
+ Z = 0.f;
+ W = 0.f;
+ Quat = FQuat::Identity;
+
+}
+
+FRigUnit_FromXYZW_Execute() {
+ DECLARE_SCOPE_HIERARCHICAL_COUNTER_RIGUNIT()
+
+ Quat = FQuat(X, Y, Z, W);
+
}
\ No newline at end of file
diff --git a/Source/MoCapPlugin/Public/MCAnimInstance.h b/Source/MoCapPlugin/Public/MCAnimInstance.h
index 6e3bac1c75f42b3d612faf5fa575d495576d29f4..c32b741d3363daed5a9f4b09a58404b52a8a9e7a 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);
+ void SetSensorOffset(EBodyPart BodyPart, float Dist, const FQuat& Rot, const FQuat& AxisRotDiff, const FTransform& DeltaTransform);
};
diff --git a/Source/MoCapPlugin/Public/MCDefines.h b/Source/MoCapPlugin/Public/MCDefines.h
index 335a5ab6f267d37f2b030acfcc286e702caab933..f3ec181792a1b5900207955519b7dc9b38702d39 100644
--- a/Source/MoCapPlugin/Public/MCDefines.h
+++ b/Source/MoCapPlugin/Public/MCDefines.h
@@ -230,6 +230,8 @@ struct FSensorOffset {
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 47acc9b03763375e07339678a44e6b85b151d8b5..2a83c6f68bd31e5719a1243fcb2a1e17289f7aa1 100644
--- a/Source/MoCapPlugin/Public/MCPawn.h
+++ b/Source/MoCapPlugin/Public/MCPawn.h
@@ -53,8 +53,10 @@ protected:
public:
+ UFUNCTION(BlueprintCallable)
UMCAnimInstance* GetAnimInstance();
USkeleton* GetSkeleton();
+ FName GetBoneNameFromBodyPart(EBodyPart BodyPart);
void SetMeshVisibility(bool visible);
void LoadMeasurementFile(const FString& Filepath);
@@ -66,7 +68,7 @@ public:
void InputViveOffsetsToAnimInstance(TSharedPtr<FJsonObject> Data);
void InputFingerDataToAnimInstance(TSharedPtr<FJsonObject> Data);
- void OffsetSensorData(EBodyPart part, FVector& Pos, FQuat& Rot);
+ void OffsetSensorData(EBodyPart part, FVector& Pos, FQuat& Rot, bool Inverse = false);
private:
diff --git a/Source/MoCapPlugin/Public/MCRigUnits.h b/Source/MoCapPlugin/Public/MCRigUnits.h
index a6668e4cf395e6d9a7bce10bd2e370d73339a564..0e803b94157ea63a4d19217117f198e4d24cac6a 100644
--- a/Source/MoCapPlugin/Public/MCRigUnits.h
+++ b/Source/MoCapPlugin/Public/MCRigUnits.h
@@ -104,4 +104,31 @@ struct FRigUnit_FootLocking : public FRigUnitMutable
UPROPERTY()
FTransform LockedTransRight;
+};
+
+USTRUCT(meta = (DisplayName = "FromXYZW", PrototypeName = "FromXYZW", Category = "Math|Quaternion", NodeColor = "0.05 0.25 0.05"))
+struct FRigUnit_FromXYZW : public FRigUnit
+{
+ GENERATED_BODY()
+
+ FRigUnit_FromXYZW();
+
+ RIGVM_METHOD()
+ virtual void Execute(const FRigUnitContext& Context) override;
+
+ UPROPERTY(meta = (Input))
+ float X;
+
+ UPROPERTY(meta = (Input))
+ float Y;
+
+ UPROPERTY(meta = (Input))
+ float Z;
+
+ UPROPERTY(meta = (Input))
+ float W;
+
+ UPROPERTY(meta = (Output))
+ FQuat Quat;
+
};
\ No newline at end of file