Commit aa6ceaf7 authored by Alexander Krause's avatar Alexander Krause

last content update before evaluation

parent 57d7ad0f
......@@ -27,19 +27,26 @@ namespace ExplorVizGestureControl.Gestures
private const int MOUSEEVENTF_RIGHTUP = 0x10;
private const int MOUSEEVENTF_WHEEL = 0x0800;
private GestureTimer scrollTimer;
private GestureTimer zoomDelayTimer;
private GestureTimer zoomActivationTimer;
private GestureTimer rotationActivationTimer;
internal static GestureTimer delayTimer;
private Boolean rotationActive = false;
private Boolean gripActive = false;
private Boolean zoomingActive = false;
private Boolean rotAnchorSet = false;
private Dictionary<string, double> dynamicValues = new Dictionary<string, double>();
private float rightHandAnchorLength;
private float leftHandAnchorLength;
private float leftHandAnchorY;
private float selectionAnchorLength;
private float rotationAnchorLength;
private float rotationAnchorY;
private float zoomAnchorZ;
private int selectionStatus = 0;
private int zoomStatus = 0;
private int zoomFrameCounter = 0;
#endregion
......@@ -49,16 +56,15 @@ namespace ExplorVizGestureControl.Gestures
KinectSensor kinect = KinectSensor.GetDefault();
// dynamic values initialization, based on gui
dynamicValues.Add("scrollAccelerationFactor", 20000);
dynamicValues.Add("scrollActivation", 0.05);
dynamicValues.Add("zoomVelocity", 700);
dynamicValues.Add("zoomAccelerationFactor", 5);
dynamicValues.Add("rotationVelocityX", 2000);
dynamicValues.Add("rotationVelocityY", 1000);
dynamicValues.Add("rotationYActivation", 0.04);
scrollTimer = new GestureTimer(dynamicValues["zoomVelocity"]);
delayTimer = new GestureTimer(2000);
zoomDelayTimer = new GestureTimer(700);
delayTimer = new GestureTimer(2000);
rotationActivationTimer = new GestureTimer(500);
zoomActivationTimer = new GestureTimer(500);
}
#endregion
......@@ -67,13 +73,12 @@ namespace ExplorVizGestureControl.Gestures
{
if (delayTimer.busy) return;
HandleZoom();
HandleRotation();
Zoom();
Rotation();
if (IntersectWithPhIZ() || gripActive) HandleGripAndSelection();
if (IntersectWithPhIZ() || gripActive) GripAndSelection();
}
private bool IntersectWithPhIZ()
{
double maxX = GestureDatabase.Phiz.botRightCorner.X;
......@@ -85,57 +90,54 @@ namespace ExplorVizGestureControl.Gestures
(GestureDatabase.Joints[(int)JointType.HandRight].Y <= maxY && GestureDatabase.Joints[(int)JointType.HandRight].Y >= minY) ? true : false;
}
public void updateDynamicValues(string key, double value)
{
dynamicValues[key] = value;
if (key.Equals("zoomVelocity")) scrollTimer.changeTimerCycle(value);
dynamicValues[key] = value;
}
private bool anchorSet = false;
private void HandleRotation()
#region Gestures
private void Rotation()
{
if (gripActive || zoomingActive) return;
if (GestureDatabase.LeftHandClosed())
{
if (!rotationActivationTimer.busy && !anchorSet)
if (!rotationActivationTimer.busy && !rotAnchorSet)
{
rotationActivationTimer.startTimer();
}
if (!anchorSet)
if (!rotAnchorSet)
{
if (GestureDatabase.HandsAboveSpineBase("left"))
if (GestureDatabase.HandsAboveSpineBase("left") &&
GestureDatabase.Joints[(int)JointType.HandLeft].X <= GestureDatabase.Joints[(int)JointType.ShoulderLeft].X - 0.07f)
{
leftHandAnchorY = Math.Abs(GestureDatabase.Joints[(int)JointType.HandLeft].Y);
leftHandAnchorLength = GestureDatabase.CalculateVectorLength(GestureDatabase.Joints[(int)JointType.HandLeft]);
anchorSet = true;
rotationAnchorY = Math.Abs(GestureDatabase.Joints[(int)JointType.HandLeft].Y);
rotationAnchorLength = GestureDatabase.CalculateVectorLength(GestureDatabase.Joints[(int)JointType.HandLeft]);
rotAnchorSet = true;
}
else return;
}
float vLength = GestureDatabase.CalculateVectorLength(GestureDatabase.Joints[(int)JointType.HandLeft]);
// Check for intentional / non-intentional rotation
if (!rotationActivationTimer.busy && !rotationActive)
{
if (Math.Abs(leftHandAnchorLength - vLength) < 0.015f)
if (Math.Abs(rotationAnchorLength - vLength) < 0.015f)
{
mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0);
rotationActive = true;
}
else
{
anchorSet = false;
rotAnchorSet = false;
return;
}
}
if (rotationActive)
{
float distanceXHands = GestureDatabase.Joints[(int)JointType.HandLeft].X - GestureDatabase.PreviousFrameJoints[(int)JointType.HandLeft].X;
......@@ -144,7 +146,7 @@ namespace ExplorVizGestureControl.Gestures
int yDetection = 0;
float currentlyHandLeftY = Math.Abs(GestureDatabase.Joints[(int)JointType.HandLeft].Y);
if (Math.Abs(currentlyHandLeftY - leftHandAnchorY) > (float)dynamicValues["rotationYActivation"]) yDetection = (int)dynamicValues["rotationVelocityY"];
if (Math.Abs(currentlyHandLeftY - rotationAnchorY) > (float)dynamicValues["rotationYActivation"]) yDetection = (int)dynamicValues["rotationVelocityY"];
int moveX = (int)(distanceXHands * dynamicValues["rotationVelocityX"]);
int moveY = (int)(distanceYHands * yDetection);
......@@ -157,62 +159,74 @@ namespace ExplorVizGestureControl.Gestures
{
rotationActivationTimer.startTimer();
rotationActive = false;
anchorSet = false;
rotAnchorSet = false;
mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
}
}
private Boolean zoomingActive = false;
private int zoomStatus = 0;
private int counter = 0;
private void HandleZoom()
private void Zoom()
{
if (rotationActive || gripActive || scrollTimer.busy) return;
float distance = GestureDatabase.Joints[(int)JointType.HandRight].Z -
GestureDatabase.PreviousFrameJoints[(int)JointType.HandRight].Z;
if (rotationActive || gripActive || zoomDelayTimer.busy) return;
if (GestureDatabase.ZoomingInitialized())
if (GestureDatabase.ZoomRecognized())
{
counter = ++counter % 3;
zoomFrameCounter = ++zoomFrameCounter % (int)dynamicValues["zoomAccelerationFactor"];
if (counter != 0) return;
// process after every n-th frame (standard: 5th)
if (zoomFrameCounter != 0) return;
zoomingActive = true;
if (distance >= 0f && GestureDatabase.BothHandsClosed())
{
if (zoomStatus == 0)
{
zoomStatus = 1;
zoomActivationTimer.startTimer();
zoomAnchorZ = GestureDatabase.Joints[(int)JointType.HandRight].Z;
}
else if (distance < 0f && GestureDatabase.BothHandsClosed()) { return; }
if (distance < 0 && GestureDatabase.BothHandsOpen())
{
if (zoomStatus == 1)
float currentZ = GestureDatabase.Joints[(int)JointType.HandRight].Z;
if (zoomingActive || (!zoomActivationTimer.busy && (currentZ < zoomAnchorZ + 0.015f) &&
(currentZ < zoomAnchorZ + 0.015f)))
{
zoomingActive = true;
float distance = GestureDatabase.Joints[(int)JointType.HandRight].Z -
GestureDatabase.PreviousFrameJoints[(int)JointType.HandRight].Z;
if (distance >= 0f && GestureDatabase.BothHandsClosed())
{
zoomStatus = 2;
scrollTimer.startTimer();
return;
}
zoomStatus = 2;
else if (distance < 0f && GestureDatabase.BothHandsClosed()) { return; }
if (distance < 0 && GestureDatabase.BothHandsOpen())
{
if (zoomStatus == 2)
{
zoomStatus = 3;
zoomDelayTimer.startTimer();
return;
}
zoomStatus = 3;
}
else if (distance >= 0 && GestureDatabase.BothHandsOpen()) { return; }
// For small changes between frames, we need a high multiplicator,
// because of the cast.
int scrollValue = (int)(distance * 20000);
mouse_event(MOUSEEVENTF_WHEEL, 0, 0, scrollValue, 0);
}
else if (distance >= 0 && GestureDatabase.BothHandsOpen()) { return; }
int scrollValue = (int)(distance * dynamicValues["scrollAccelerationFactor"]);
mouse_event(MOUSEEVENTF_WHEEL, 0, 0, scrollValue, 0);
}
else
{
zoomingActive = false;
zoomStatus = 0;
scrollTimer.startTimer();
zoomDelayTimer.startTimer();
}
}
private void HandleGripAndSelection()
private void GripAndSelection()
{
if (rotationActive || zoomingActive) return;
......@@ -230,9 +244,9 @@ namespace ExplorVizGestureControl.Gestures
if (GestureDatabase.RightHandClosed())
{
if (selectionStatus == 0)
{
rightHandAnchorLength = GestureDatabase.CalculateVectorLength(GestureDatabase.Joints[(int)JointType.HandRight]);
selectionStatus = 1;
{
selectionAnchorLength = GestureDatabase.CalculateVectorLength(GestureDatabase.Joints[(int)JointType.HandRight]);
selectionStatus = 1;
}
float vLength = GestureDatabase.CalculateVectorLength(GestureDatabase.Joints[(int)JointType.HandRight]);
......@@ -241,20 +255,20 @@ namespace ExplorVizGestureControl.Gestures
if (!gripActive)
{
// If hand position changed at least 1.5 cm (vector length!), activate dragging
if (Math.Abs(rightHandAnchorLength - vLength) > 0.015f)
{
if (Math.Abs(selectionAnchorLength - vLength) > 0.015f)
{
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
gripActive = true;
}
else
{
{
return;
}
}
// Else handle grip processing
if (gripActive)
{
{
double distanceX = GestureDatabase.Joints[(int)JointType.HandRight].X -
GestureDatabase.PreviousFrameJoints[(int)JointType.HandRight].X;
double distanceY = GestureDatabase.Joints[(int)JointType.HandRight].Y -
......@@ -268,15 +282,15 @@ namespace ExplorVizGestureControl.Gestures
else return;
}
else if (gripActive)
{
{
selectionStatus = 0;
gripActive = false;
gripActive = false;
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
}
}
#endregion
}
......
......@@ -47,7 +47,7 @@ namespace ExplorVizGestureControl.Gestures
if (entry.Value.Invoke() && !this.timerForNextGesture.busy)
{
// again, start a gesture timer for mistake avoidance
// start a gesture timer for mistake avoidance
timerForNextGesture.startTimer();
switch (entry.Key)
......@@ -56,8 +56,6 @@ namespace ExplorVizGestureControl.Gestures
if (contDetStartReset.busy) return;
contDetStartReset.startTimer();
Console.WriteLine("key sent");
keybd_event(UP, 0, KEYEVENTF_EXTENDEDKEY, 0);
keybd_event(UP, 0, KEYEVENTF_KEYUP, 0);
......
......@@ -185,11 +185,16 @@ namespace ExplorVizGestureControl.Gestures
return joints[(int)JointType.ElbowLeft].Y < joints[(int)JointType.ShoulderLeft].Y;
}
public static Boolean BothHandsParallel(float maxDistanceInX = 0.30f, float maxDistanceInY = 0.10f, float maxDistanceInZ = 0.10f)
{
return (Math.Abs(Math.Abs(joints[(int)JointType.HandRight].X) - Math.Abs(joints[(int)JointType.HandLeft].X)) < maxDistanceInX &&
Math.Abs(Math.Abs(joints[(int)JointType.HandRight].Y) - Math.Abs(joints[(int)JointType.HandLeft].Y)) < maxDistanceInY) &&
Math.Abs(Math.Abs(joints[(int)JointType.HandRight].Z) - Math.Abs(joints[(int)JointType.HandLeft].Z)) < maxDistanceInZ;
public static Boolean BothHandsInLine(float maxDistanceInY = 0.10f, float maxDistanceInZ = 0.10f)
{
Boolean parallelInY = joints[(int)JointType.HandRight].Y < joints[(int)JointType.HandLeft].Y + maxDistanceInY &&
joints[(int)JointType.HandRight].Y > joints[(int)JointType.HandLeft].Y - maxDistanceInY;
Boolean parallelInZ = joints[(int)JointType.HandRight].Z < joints[(int)JointType.HandLeft].Z + maxDistanceInZ &&
joints[(int)JointType.HandRight].Z > joints[(int)JointType.HandLeft].Z - maxDistanceInZ;
return parallelInY && parallelInZ;
}
public static Boolean BothHandsAboveHead()
......@@ -231,49 +236,19 @@ namespace ExplorVizGestureControl.Gestures
public static Boolean HandsHaveMinDistance(float distance, char axis = 'x')
{
if (axis.Equals('x')) return joints[(int)JointType.HandRight].X >= joints[(int)JointType.HandLeft].X + distance;
if (axis.Equals('y')) return joints[(int)JointType.HandRight].Y >= joints[(int)JointType.HandLeft].Y + distance;
if (axis.Equals('x')) return Math.Abs(Math.Abs(joints[(int)JointType.HandRight].X) -
Math.Abs(joints[(int)JointType.HandLeft].X)) > distance;
if (axis.Equals('y')) return Math.Abs(Math.Abs(joints[(int)JointType.HandRight].Y) -
Math.Abs(joints[(int)JointType.HandLeft].Y)) > distance;
if (axis.Equals('z')) return Math.Abs(Math.Abs(joints[(int)JointType.HandRight].Z) -
Math.Abs(joints[(int)JointType.HandLeft].Z)) > distance;
return false;
}
public static Boolean HandsHaveAcceptableDistance(float offset = 0.0f, char axis = 'x')
{
if (axis.Equals('x')) return Math.Abs(Math.Abs(joints[(int)JointType.HandLeft].X) -
Math.Abs(joints[(int)JointType.HandRight].X)) >
Math.Abs(Math.Abs(joints[(int)JointType.ShoulderLeft].X) -
Math.Abs(joints[(int)JointType.ShoulderRight].X)) + offset;
if (axis.Equals('y')) return Math.Abs(Math.Abs(joints[(int)JointType.HandLeft].Y) -
Math.Abs(joints[(int)JointType.HandRight].Y)) >
Math.Abs(Math.Abs(joints[(int)JointType.ShoulderLeft].Y) -
Math.Abs(joints[(int)JointType.ShoulderRight].Y)) + offset;
if (axis.Equals('z')) return Math.Abs(Math.Abs(joints[(int)JointType.HandLeft].Z) -
Math.Abs(joints[(int)JointType.HandRight].Z)) >
Math.Abs(Math.Abs(joints[(int)JointType.ShoulderLeft].Z) -
Math.Abs(joints[(int)JointType.ShoulderRight].Z)) + offset;
if (axis.Equals('z')) return joints[(int)JointType.HandRight].Z >= joints[(int)JointType.HandLeft].Z + distance;
return false;
}
}
#endregion
#region Gestures
public static Boolean OpenObject()
{
return LeftHandBelowLeftShoulder() && LeftHandClosed() && RightHandClosed();
}
public static Boolean StartOrReset()
{
Boolean[] confidenceArray = new Boolean[maxCapacity];
......@@ -301,10 +276,9 @@ namespace ExplorVizGestureControl.Gestures
return confidence > 6 ? true : false;
}
public static Boolean ZoomingInitialized()
public static Boolean ZoomRecognized()
{
return BothHandsParallel(1f) && HandsAboveSpineBase("both", 0.1f) && LeftHandBelowLeftShoulder() &&
RightHandBelowRightShoulder();
return BothHandsInLine() && HandsAboveSpineBase("both", 0.1f) && HandsHaveMinDistance(0.1f, 'x');
}
#endregion
......
......@@ -68,49 +68,34 @@
<StackPanel
Grid.Column="0"
Grid.Row="2">
<TextBox
Style="{StaticResource DynamicValues}"
Name="scrollActivation"
Text="0,05"
Name="zoomAccelerationFactor"
Text="5"
KeyDown="OnKeyDownHandler">
<TextBox.ToolTip>
<ToolTip>
<StackPanel>
<Label FontWeight="Bold" Content="Value for recognition of scrolling"/>
<Label FontWeight="Thin" Content="Smaller values lead to quicker response."/>
<Label Content="This value might need to be changed due to different bodies and distances."/>
</StackPanel>
</ToolTip>
</TextBox.ToolTip>
</TextBox>
<TextBox
Style="{StaticResource DynamicValues}"
Name="zoomVelocity"
Text="250"
KeyDown="OnKeyDownHandler">
<TextBox.ToolTip>
<ToolTip>
<StackPanel>
<Label FontWeight="Bold" Content="Velocity for zooming"/>
<Label FontWeight="Thin" Content="Smaller values lead to faster zooming."/>
<Label Content="Standard value: 250"/>
<Label FontWeight="Bold" Content="Acceleration factor for zooming."/>
<Label FontWeight="Thin" Content="Smaller (integer) values lead to a faster zoom."/>
<Label Content="Standard value: 5"/>
</StackPanel>
</ToolTip>
</TextBox.ToolTip>
</TextBox>
</TextBox>
<TextBox
Style="{StaticResource DynamicValues}"
Name="rotationVelocityX"
Text="1000"
Text="2000"
KeyDown="OnKeyDownHandler">
<TextBox.ToolTip>
<ToolTip>
<StackPanel>
<Label FontWeight="Bold" Content="Velocity for rotation (x-axis)"/>
<Label Content="Standard value: 1000"/>
<Label FontWeight="Bold" Content="Velocity factor for rotation (x-axis)"/>
<Label FontWeight="Thin" Content="Smaller (integer) values lead to a slower rotation."/>
<Label Content="Standard value: 2000"/>
</StackPanel>
</ToolTip>
</TextBox.ToolTip>
......@@ -119,13 +104,14 @@
<TextBox
Style="{StaticResource DynamicValues}"
Name="rotationVelocityY"
Text="500"
Text="1000"
KeyDown="OnKeyDownHandler">
<TextBox.ToolTip>
<ToolTip>
<StackPanel>
<Label FontWeight="Bold" Content="Velocity for rotation (y-axis)"/>
<Label Content="Standard value: 500"/>
<Label FontWeight="Bold" Content="Velocity factor for rotation (y-axis)"/>
<Label FontWeight="Thin" Content="Smaller (integer) values lead to a slower rotation."/>
<Label Content="Standard value: 1000"/>
</StackPanel>
</ToolTip>
</TextBox.ToolTip>
......
......@@ -237,7 +237,7 @@ namespace ExplorVizGestureControl
{
if (e.Key == Key.Return)
{
TextBox textBox = sender as TextBox;
TextBox textBox = sender as TextBox;
continuousGestureDetector.updateDynamicValues(textBox.Name, Convert.ToDouble(textBox.Text));
}
}
......
#pragma checksum "..\..\MainWindow.xaml" "{406ea660-64cf-4c82-b6f0-42d48172a799}" "9A4B827C61A655BE277A868D4DBD1233"
#pragma checksum "..\..\MainWindow.xaml" "{406ea660-64cf-4c82-b6f0-42d48172a799}" "7BBE422925CC01126EB01D83E39C1F40"
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
......@@ -82,7 +82,7 @@ namespace ExplorVizGestureControl {
#line 74 "..\..\MainWindow.xaml"
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
internal System.Windows.Controls.TextBox scrollActivation;
internal System.Windows.Controls.TextBox zoomAccelerationFactor;
#line default
#line hidden
......@@ -90,21 +90,13 @@ namespace ExplorVizGestureControl {
#line 90 "..\..\MainWindow.xaml"
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
internal System.Windows.Controls.TextBox zoomVelocity;
#line default
#line hidden
#line 106 "..\..\MainWindow.xaml"
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
internal System.Windows.Controls.TextBox rotationVelocityX;
#line default
#line hidden
#line 121 "..\..\MainWindow.xaml"
#line 106 "..\..\MainWindow.xaml"
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
internal System.Windows.Controls.TextBox rotationVelocityY;
......@@ -112,7 +104,7 @@ namespace ExplorVizGestureControl {
#line hidden
#line 136 "..\..\MainWindow.xaml"
#line 122 "..\..\MainWindow.xaml"
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
internal System.Windows.Controls.TextBox rotationYActivation;
......@@ -185,45 +177,36 @@ namespace ExplorVizGestureControl {
#line hidden
return;
case 7:
this.scrollActivation = ((System.Windows.Controls.TextBox)(target));
this.zoomAccelerationFactor = ((System.Windows.Controls.TextBox)(target));
#line 76 "..\..\MainWindow.xaml"
this.scrollActivation.KeyDown += new System.Windows.Input.KeyEventHandler(this.OnKeyDownHandler);
this.zoomAccelerationFactor.KeyDown += new System.Windows.Input.KeyEventHandler(this.OnKeyDownHandler);
#line default
#line hidden
return;
case 8:
this.zoomVelocity = ((System.Windows.Controls.TextBox)(target));
#line 92 "..\..\MainWindow.xaml"
this.zoomVelocity.KeyDown += new System.Windows.Input.KeyEventHandler(this.OnKeyDownHandler);
#line default
#line hidden
return;
case 9:
this.rotationVelocityX = ((System.Windows.Controls.TextBox)(target));
#line 108 "..\..\MainWindow.xaml"
#line 92 "..\..\MainWindow.xaml"
this.rotationVelocityX.KeyDown += new System.Windows.Input.KeyEventHandler(this.OnKeyDownHandler);
#line default
#line hidden
return;
case 10:
case 9:
this.rotationVelocityY = ((System.Windows.Controls.TextBox)(target));
#line 123 "..\..\MainWindow.xaml"
#line 108 "..\..\MainWindow.xaml"
this.rotationVelocityY.KeyDown += new System.Windows.Input.KeyEventHandler(this.OnKeyDownHandler);
#line default
#line hidden
return;
case 11:
case 10:
this.rotationYActivation = ((System.Windows.Controls.TextBox)(target));
#line 138 "..\..\MainWindow.xaml"