Skip to content

Commit 7fee906

Browse files
committed
手首回転補正の補正値をUIから設定できるように
1 parent 2f880d5 commit 7fee906

10 files changed

Lines changed: 273 additions & 15 deletions

File tree

Assets/Scenes/VirtualMotionCapture.unity

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2536,7 +2536,7 @@ MonoBehaviour:
25362536
m_EditorClassIdentifier:
25372537
IsBeta: 0
25382538
IsPreRelease: 0
2539-
VersionString: v0.60f1r1b1
2539+
VersionString: v0.60f1r1b3
25402540
LeftWristTransform: {fileID: 0}
25412541
RightWristTransform: {fileID: 0}
25422542
BackgroundRenderer: {fileID: 892957809}
@@ -3581,6 +3581,7 @@ MonoBehaviour:
35813581
m_Name:
35823582
m_EditorClassIdentifier:
35833583
ik: {fileID: 0}
3584+
controlWPFWindow: {fileID: 0}
35843585
UpperArmWeight: 0.05
35853586
ForearmWeight: 0.45
35863587
smoothingTime: 0.05

Assets/Scripts/Avatar/WristRotationFix.cs

Lines changed: 103 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using RootMotion.FinalIK;
22
using System;
33
using UnityEngine;
4+
using UnityMemoryMappedFile;
45

56
namespace VMC
67
{
@@ -9,6 +10,10 @@ public class WristRotationFix : MonoBehaviour
910

1011
public VRIK ik;
1112

13+
// ControlWPFWindowの参照を保持
14+
[SerializeField]
15+
private ControlWPFWindow controlWPFWindow;
16+
1217
private ArmFixItem LeftArmFixItem;
1318
private ArmFixItem RightArmFixItem;
1419
// VRIKで元から回ってる分があるので上腕は特に弱くて良い
@@ -27,6 +32,101 @@ public class WristRotationFix : MonoBehaviour
2732
[Range(180f, 720f)]
2833
public float maxAccumulatedTwist = 300f;
2934

35+
private System.Threading.SynchronizationContext context = null;
36+
37+
void Start()
38+
{
39+
context = System.Threading.SynchronizationContext.Current;
40+
41+
// ControlWPFWindowの参照取得(SerializeFieldで設定されていない場合のみ)
42+
if (controlWPFWindow == null)
43+
{
44+
controlWPFWindow = GameObject.Find("ControlWPFWindow")?.GetComponent<ControlWPFWindow>();
45+
}
46+
47+
// 設定からパラメータを読み込み
48+
LoadSettingsValues();
49+
50+
// UIとの通信を設定
51+
if (controlWPFWindow != null)
52+
{
53+
controlWPFWindow.server.ReceivedEvent += Server_Received;
54+
// AdditionalSettingActionに登録して設定読み込み時に自動実行されるようにする
55+
controlWPFWindow.AdditionalSettingAction += ApplySettings;
56+
}
57+
}
58+
59+
void OnDestroy()
60+
{
61+
if (eventId != null) IKManager.Instance.RemoveOnPostUpdate(eventId.Value);
62+
63+
// 通信ハンドラの登録解除
64+
if (controlWPFWindow != null)
65+
{
66+
controlWPFWindow.server.ReceivedEvent -= Server_Received;
67+
controlWPFWindow.AdditionalSettingAction -= ApplySettings;
68+
}
69+
}
70+
71+
// 設定読み込み時に呼ばれるメソッド(IKManager.SetHandFreeOffsetと同様)
72+
private void ApplySettings(GameObject gameObject)
73+
{
74+
LoadSettingsValues();
75+
}
76+
77+
private void Server_Received(object sender, DataReceivedEventArgs e)
78+
{
79+
context.Post(async s =>
80+
{
81+
if (e.CommandType == typeof(PipeCommands.GetWristRotationFixSetting))
82+
{
83+
if (controlWPFWindow != null)
84+
{
85+
await controlWPFWindow.server.SendCommandAsync(new PipeCommands.SetWristRotationFixSetting
86+
{
87+
UpperArmWeight = (int)(UpperArmWeight * 1000),
88+
ForearmWeight = (int)(ForearmWeight * 1000),
89+
SmoothingTime = (int)(smoothingTime * 1000),
90+
MaxAccumulatedTwist = (int)maxAccumulatedTwist,
91+
}, e.RequestId);
92+
}
93+
}
94+
else if (e.CommandType == typeof(PipeCommands.SetWristRotationFixSetting))
95+
{
96+
var d = (PipeCommands.SetWristRotationFixSetting)e.Data;
97+
UpperArmWeight = d.UpperArmWeight / 1000f;
98+
ForearmWeight = d.ForearmWeight / 1000f;
99+
smoothingTime = d.SmoothingTime / 1000f;
100+
maxAccumulatedTwist = d.MaxAccumulatedTwist;
101+
102+
// 設定を保存
103+
SaveSettingsValues();
104+
}
105+
}, null);
106+
}
107+
108+
private void LoadSettingsValues()
109+
{
110+
if (Settings.Current != null)
111+
{
112+
UpperArmWeight = Settings.Current.WristRotationFix_UpperArmWeight;
113+
ForearmWeight = Settings.Current.WristRotationFix_ForearmWeight;
114+
smoothingTime = Settings.Current.WristRotationFix_SmoothingTime;
115+
maxAccumulatedTwist = Settings.Current.WristRotationFix_MaxAccumulatedTwist;
116+
}
117+
}
118+
119+
private void SaveSettingsValues()
120+
{
121+
if (Settings.Current != null)
122+
{
123+
Settings.Current.WristRotationFix_UpperArmWeight = UpperArmWeight;
124+
Settings.Current.WristRotationFix_ForearmWeight = ForearmWeight;
125+
Settings.Current.WristRotationFix_SmoothingTime = smoothingTime;
126+
Settings.Current.WristRotationFix_MaxAccumulatedTwist = maxAccumulatedTwist;
127+
}
128+
}
129+
30130
public void SetVRIK(VRIK setIK)
31131
{
32132
if (eventId != null) IKManager.Instance.RemoveOnPostUpdate(eventId.Value);
@@ -35,12 +135,10 @@ public void SetVRIK(VRIK setIK)
35135
LeftArmFixItem = new ArmFixItem(ik.references.leftShoulder, ik.references.leftUpperArm, ik.references.leftForearm, ik.references.leftHand);
36136
RightArmFixItem = new ArmFixItem(ik.references.rightShoulder, ik.references.rightUpperArm, ik.references.rightForearm, ik.references.rightHand);
37137

38-
eventId = IKManager.Instance.AddOnPostUpdate(10, OnPostUpdate);
39-
}
138+
// 設定を再読み込み
139+
LoadSettingsValues();
40140

41-
void OnDestroy()
42-
{
43-
if (eventId != null) IKManager.Instance.RemoveOnPostUpdate(eventId.Value);
141+
eventId = IKManager.Instance.AddOnPostUpdate(10, OnPostUpdate);
44142
}
45143

46144
private void OnPostUpdate()

Assets/Scripts/Setting/Settings.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,15 @@ public class Settings
690690
[OptionalField]
691691
public float PelvisOffsetAdjustZ;
692692

693+
[OptionalField]
694+
public float WristRotationFix_UpperArmWeight = 0.05f;
695+
[OptionalField]
696+
public float WristRotationFix_ForearmWeight = 0.45f;
697+
[OptionalField]
698+
public float WristRotationFix_SmoothingTime = 0.05f;
699+
[OptionalField]
700+
public float WristRotationFix_MaxAccumulatedTwist = 300f;
701+
693702

694703
//初期値
695704
[OnDeserializing()]
@@ -862,6 +871,11 @@ internal void OnDeserializingMethod(StreamingContext context)
862871
OverrideBodyHeight = 1.7f;
863872
PelvisOffsetAdjustY = 0;
864873
PelvisOffsetAdjustZ = 0;
874+
875+
WristRotationFix_UpperArmWeight = 0.05f;
876+
WristRotationFix_ForearmWeight = 0.45f;
877+
WristRotationFix_SmoothingTime = 0.05f;
878+
WristRotationFix_MaxAccumulatedTwist = 300f;
865879
}
866880

867881
/// <summary>

ControlWindowWPF/ControlWindowWPF/CalibrationSettingWindow.xaml

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
mc:Ignorable="d"
88
Title="{DynamicResource SettingWindow_CalibrationSetting}" SizeToContent="Height" Width="400" Loaded="Window_Loaded" Unloaded="Window_Unloaded">
99
<DockPanel>
10-
<GroupBox DockPanel.Dock="Top" Margin="10,10,10,0">
10+
<GroupBox DockPanel.Dock="Top" Margin="10,10,10,0" Name="OverrideBodyHeightGroupBox">
1111
<GroupBox.Header>
1212
<TextBlock Text="{DynamicResource CalibrationSettingWindow_BodyHeight}"/>
1313
</GroupBox.Header>
@@ -23,7 +23,7 @@
2323
</DockPanel>
2424
</StackPanel>
2525
</GroupBox>
26-
<GroupBox DockPanel.Dock="Top" Margin="10,10,10,0">
26+
<GroupBox DockPanel.Dock="Top" Margin="10,10,10,0" Name="PelvisOffsetGroupBox">
2727
<GroupBox.Header>
2828
<TextBlock Text="{DynamicResource CalibrationSettingWindow_Pelvis}"/>
2929
</GroupBox.Header>
@@ -42,6 +42,37 @@
4242
</DockPanel>
4343
</StackPanel>
4444
</GroupBox>
45+
<GroupBox DockPanel.Dock="Top" Margin="10,10,10,0" Name="WristRotationFixSettingGroupBox">
46+
<GroupBox.Header>
47+
<TextBlock Text="{DynamicResource CalibrationSettingWindow_WristRotationFix}"/>
48+
</GroupBox.Header>
49+
<StackPanel Orientation="Vertical">
50+
<DockPanel DockPanel.Dock="Top" Margin="10,5,10,0">
51+
<TextBlock Text="{DynamicResource CalibrationSettingWindow_UpperArmWeight}" VerticalAlignment="Center" DockPanel.Dock="Left" Width="120"/>
52+
<TextBlock Text="%" VerticalAlignment="Center" DockPanel.Dock="Right" Width="20"/>
53+
<TextBlock Text="{Binding UpperArmWeightPercent}" Width="30" TextAlignment="Right" FontWeight="Bold" VerticalAlignment="Center" DockPanel.Dock="Right"/>
54+
<Slider Value="{Binding UpperArmWeightPercent}" Minimum="0" Maximum="100" IsSnapToTickEnabled="True" TickFrequency="0.1" LargeChange="0.1" SmallChange="0.1" TickPlacement="None"/>
55+
</DockPanel>
56+
<DockPanel DockPanel.Dock="Top" Margin="10,5,10,0">
57+
<TextBlock Text="{DynamicResource CalibrationSettingWindow_ForearmWeight}" VerticalAlignment="Center" DockPanel.Dock="Left" Width="120"/>
58+
<TextBlock Text="%" VerticalAlignment="Center" DockPanel.Dock="Right" Width="20"/>
59+
<TextBlock Text="{Binding ForearmWeightPercent}" Width="30" TextAlignment="Right" FontWeight="Bold" VerticalAlignment="Center" DockPanel.Dock="Right"/>
60+
<Slider Value="{Binding ForearmWeightPercent}" Minimum="0" Maximum="100" IsSnapToTickEnabled="True" TickFrequency="0.1" LargeChange="0.1" SmallChange="0.1" TickPlacement="None"/>
61+
</DockPanel>
62+
<DockPanel DockPanel.Dock="Top" Margin="10,5,10,0">
63+
<TextBlock Text="{DynamicResource CalibrationSettingWindow_SmoothingTime}" VerticalAlignment="Center" DockPanel.Dock="Left" Width="120"/>
64+
<TextBlock Text="s" VerticalAlignment="Center" DockPanel.Dock="Right" Width="20"/>
65+
<TextBlock Text="{Binding SmoothingTimeSeconds}" Width="30" TextAlignment="Right" FontWeight="Bold" VerticalAlignment="Center" DockPanel.Dock="Right"/>
66+
<Slider Value="{Binding SmoothingTimeSeconds}" Minimum="0" Maximum="0.2" IsSnapToTickEnabled="True" TickFrequency="0.001" LargeChange="0.001" SmallChange="0.001" TickPlacement="None"/>
67+
</DockPanel>
68+
<DockPanel DockPanel.Dock="Top" Margin="10,5,10,5">
69+
<TextBlock Text="{DynamicResource CalibrationSettingWindow_MaxAccumulatedTwist}" VerticalAlignment="Center" DockPanel.Dock="Left" Width="120"/>
70+
<TextBlock Text="°" VerticalAlignment="Center" DockPanel.Dock="Right" Width="20"/>
71+
<TextBlock Text="{Binding MaxAccumulatedTwist}" Width="30" TextAlignment="Right" FontWeight="Bold" VerticalAlignment="Center" DockPanel.Dock="Right"/>
72+
<Slider Value="{Binding MaxAccumulatedTwist}" Minimum="180" Maximum="720" IsSnapToTickEnabled="True" TickFrequency="1" LargeChange="1" SmallChange="1" TickPlacement="None"/>
73+
</DockPanel>
74+
</StackPanel>
75+
</GroupBox>
4576
<TextBlock Text="{DynamicResource CalibrationSettingWindow_Notice}" Margin="15,0,15,10"/>
4677
</DockPanel>
4778
</Window>

ControlWindowWPF/ControlWindowWPF/CalibrationSettingWindow.xaml.cs

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,33 @@ public partial class CalibrationSettingWindow : Window
2222
{
2323

2424
private CalibrationSettingItem CalibrationSetting = new CalibrationSettingItem();
25+
private WristRotationFixSettingItem WristRotationFixSetting = new WristRotationFixSettingItem();
2526

2627
public CalibrationSettingWindow()
2728
{
2829
InitializeComponent();
29-
DataContext = CalibrationSetting;
30+
31+
OverrideBodyHeightGroupBox.DataContext = CalibrationSetting;
32+
PelvisOffsetGroupBox.DataContext = CalibrationSetting;
33+
WristRotationFixSettingGroupBox.DataContext = WristRotationFixSetting;
3034
}
3135

3236
bool disablePropertyChanged = false;
33-
private async void FreeOffset_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
37+
private async void CalibrationSetting_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
3438
{
3539
if (disablePropertyChanged) return;
3640
await Globals.Client?.SendCommandAsync(CalibrationSetting.ConvertToPipeCommands());
3741
}
3842

43+
private async void WristRotationFixSetting_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
44+
{
45+
if (disablePropertyChanged) return;
46+
await Globals.Client?.SendCommandAsync(WristRotationFixSetting.ConvertToPipeCommands());
47+
}
48+
3949
private async void Window_Loaded(object sender, RoutedEventArgs e)
4050
{
51+
// CalibrationSetting読み込み
4152
await Globals.Client.SendCommandWaitAsync(new PipeCommands.GetCalibrationSetting(), d =>
4253
{
4354
var ret = (PipeCommands.SetCalibrationSetting)d;
@@ -47,14 +58,29 @@ await Globals.Client.SendCommandWaitAsync(new PipeCommands.GetCalibrationSetting
4758
disablePropertyChanged = false;
4859
});
4960
});
50-
CalibrationSetting.PropertyChanged += FreeOffset_PropertyChanged;
61+
62+
// WristRotationFixSetting読み込み
63+
await Globals.Client.SendCommandWaitAsync(new PipeCommands.GetWristRotationFixSetting(), d =>
64+
{
65+
var ret = (PipeCommands.SetWristRotationFixSetting)d;
66+
Dispatcher.Invoke(() => {
67+
disablePropertyChanged = true;
68+
WristRotationFixSetting.SetFromPipeCommands(ret);
69+
disablePropertyChanged = false;
70+
});
71+
});
72+
73+
CalibrationSetting.PropertyChanged += CalibrationSetting_PropertyChanged;
74+
WristRotationFixSetting.PropertyChanged += WristRotationFixSetting_PropertyChanged;
5175
}
5276

5377
private void Window_Unloaded(object sender, RoutedEventArgs e)
5478
{
55-
CalibrationSetting.PropertyChanged -= FreeOffset_PropertyChanged;
79+
CalibrationSetting.PropertyChanged -= CalibrationSetting_PropertyChanged;
80+
WristRotationFixSetting.PropertyChanged -= WristRotationFixSetting_PropertyChanged;
5681
}
5782
}
83+
5884
public class CalibrationSettingItem : ViewModelBase
5985
{
6086
public bool EnableOverrideBodyHeight { get => Getter<bool>(); set => Setter(value); }
@@ -88,4 +114,50 @@ public void SetFromPipeCommands(PipeCommands.SetCalibrationSetting CalibrationSe
88114
PelvisOffsetAdjustZ = CalibrationSetting.PelvisOffsetAdjustZ;
89115
}
90116
}
117+
118+
public class WristRotationFixSettingItem : ViewModelBase
119+
{
120+
public int UpperArmWeight { get => Getter<int>(); set => Setter(value); }
121+
public int ForearmWeight { get => Getter<int>(); set => Setter(value); }
122+
public int SmoothingTime { get => Getter<int>(); set => Setter(value); }
123+
public int MaxAccumulatedTwist { get => Getter<int>(); set => Setter(value); }
124+
125+
public float UpperArmWeightPercent
126+
{
127+
get => Getter<float>();
128+
set { UpperArmWeight = Convert.ToInt32(value * 10); Setter(value); }
129+
}
130+
public float ForearmWeightPercent
131+
{
132+
get => Getter<float>();
133+
set { ForearmWeight = Convert.ToInt32(value * 10); Setter(value); }
134+
}
135+
public float SmoothingTimeSeconds
136+
{
137+
get => Getter<float>();
138+
set { SmoothingTime = Convert.ToInt32(value * 1000); Setter(value); }
139+
}
140+
141+
public PipeCommands.SetWristRotationFixSetting ConvertToPipeCommands()
142+
{
143+
return new PipeCommands.SetWristRotationFixSetting
144+
{
145+
UpperArmWeight = UpperArmWeight,
146+
ForearmWeight = ForearmWeight,
147+
SmoothingTime = SmoothingTime,
148+
MaxAccumulatedTwist = MaxAccumulatedTwist,
149+
};
150+
}
151+
152+
public void SetFromPipeCommands(PipeCommands.SetWristRotationFixSetting WristRotationFixSetting)
153+
{
154+
UpperArmWeightPercent = WristRotationFixSetting.UpperArmWeight / 10f;
155+
ForearmWeightPercent = WristRotationFixSetting.ForearmWeight / 10f;
156+
SmoothingTimeSeconds = WristRotationFixSetting.SmoothingTime / 1000f;
157+
MaxAccumulatedTwist = WristRotationFixSetting.MaxAccumulatedTwist;
158+
UpperArmWeight = WristRotationFixSetting.UpperArmWeight;
159+
ForearmWeight = WristRotationFixSetting.ForearmWeight;
160+
SmoothingTime = WristRotationFixSetting.SmoothingTime;
161+
}
162+
}
91163
}

ControlWindowWPF/ControlWindowWPF/Resources/Chinese.xaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,14 @@
291291
<system:String x:Key="CalibrationSettingWindow_OffsetY">Y 偏移:</system:String>
292292
<system:String x:Key="CalibrationSettingWindow_OffsetZ">Z 偏移:</system:String>
293293
<system:String x:Key="CalibrationSettingWindow_Notice">修改后请重新校准</system:String>
294+
295+
<!-- CalibrationSettingWindow - WristRotationFix -->
296+
<system:String x:Key="CalibrationSettingWindow_WristRotationFix">手腕旋转修正</system:String>
297+
<system:String x:Key="CalibrationSettingWindow_UpperArmWeight">上臂权重 :</system:String>
298+
<system:String x:Key="CalibrationSettingWindow_ForearmWeight">前臂权重 :</system:String>
299+
<system:String x:Key="CalibrationSettingWindow_SmoothingTime">平滑时间 :</system:String>
300+
<system:String x:Key="CalibrationSettingWindow_MaxAccumulatedTwist">最大累积扭转 :</system:String>
301+
294302

295303
<!-- TrackerConfigWindow -->
296304
<system:String x:Key="TrackerConfigWindowTitle">追踪器分配设置</system:String>
@@ -397,6 +405,7 @@
397405
<system:String x:Key="HandGestureControlKeyAddWindow_Save">保存</system:String>
398406
<system:String x:Key="HandGestureControlKeyAddWindow_Register">注册</system:String>
399407
<system:String x:Key="HandGestureControlKeyAddWindow_Cancel">取消</system:String>
408+
<system:String x:Key="HandGestureControlKeyAddWindow_ClearAll">清除所有手势</system:String>
400409

401410

402411
<!-- FaceControlKeyAddWindow -->

0 commit comments

Comments
 (0)