/// <summary> /// Called when the heart beat timer expires. Sends a "blank" packet with player /// count and Joystick data set to 0. /// </summary> /// <param name="stateInfo"></param> private void HeartBeatExpired(Object stateInfo) { sbyte[] nullAxis = new sbyte[6]; m_version1Packet.PlayerCount.Set(0); m_version1Packet.Joystick1.Set(nullAxis, 0); m_version1Packet.Joystick2.Set(nullAxis, 0); Send(); NTKinect.UpdateJoysticks(0.0, 0.0, 0.0, 0.0); }
/// <summary> /// Processes a skeleton into joystick data using the default FIRST gestures. /// </summary> /// <param name="joy">Vector of Joysticks to put the result in</param> /// <param name="skeleton">The skeleton to process</param> public void ProcessGestures(Networking.WritableElements.WritableJoystick[] joy, Microsoft.Kinect.Skeleton skeleton) { // Check edge cases if (joy == null || joy.Length < 2 || joy[0] == null || joy[1] == null) { return; } sbyte[] leftAxis = new sbyte[6]; sbyte[] rightAxis = new sbyte[6]; sbyte[] nullAxis = new sbyte[6]; bool dataWithinExpectedRange; ushort buttons = 0; double leftAngle = RadToDeg(AngleXY(skeleton.Joints[JointType.ShoulderLeft].Position, skeleton.Joints[JointType.WristLeft].Position, true)); double rightAngle = RadToDeg(AngleXY(skeleton.Joints[JointType.ShoulderRight].Position, skeleton.Joints[JointType.WristRight].Position)); dataWithinExpectedRange = leftAngle <ARM_MAX_ANGLE && leftAngle> ARM_MIN_ANGLE && rightAngle <ARM_MAX_ANGLE && rightAngle> ARM_MIN_ANGLE; double leftYAxis = CoerceToRange(leftAngle, -70, 70, -127, 128); double rightYAxis = CoerceToRange(rightAngle, -70, 70, -127, 128); dataWithinExpectedRange = dataWithinExpectedRange && InSameZPlane(skeleton.Joints[JointType.ShoulderLeft].Position, skeleton.Joints[JointType.WristLeft].Position, Z_PLANE_TOLERANCE) && InSameZPlane(skeleton.Joints[JointType.ShoulderRight].Position, skeleton.Joints[JointType.WristRight].Position, Z_PLANE_TOLERANCE); // Head buttons double headAngle = RadToDeg(AngleXY(skeleton.Joints[JointType.ShoulderCenter].Position, skeleton.Joints[JointType.Head].Position)); if (IsHeadRight(headAngle)) { buttons |= (ushort)WritableJoystick.Buttons.Btn1; } if (IsHeadLeft(headAngle)) { buttons |= (ushort)WritableJoystick.Buttons.Btn2; } // Right Leg XY Button double rightLegAngle = RadToDeg(AngleXY(skeleton.Joints[JointType.HipRight].Position, skeleton.Joints[JointType.AnkleRight].Position)); if (IsLegOut(rightLegAngle)) { buttons |= (ushort)WritableJoystick.Buttons.Btn3; } // Left Leg XY Button double leftLegAngle = RadToDeg(AngleXY(skeleton.Joints[JointType.HipLeft].Position, skeleton.Joints[JointType.AnkleLeft].Position, true)); if (IsLegOut(leftLegAngle)) { buttons |= (ushort)WritableJoystick.Buttons.Btn4; } // Right Leg YZ Buttons double rightLegYZ = RadToDeg(AngleYZ(skeleton.Joints[JointType.HipRight].Position, skeleton.Joints[JointType.AnkleRight].Position)); if (IsLegForward(rightLegYZ)) { buttons |= (ushort)WritableJoystick.Buttons.Btn5; } if (IsLegBackward(rightLegYZ)) { buttons |= (ushort)WritableJoystick.Buttons.Btn6; } // Left Leg YZ Buttons double leftLegYZ = RadToDeg(AngleYZ(skeleton.Joints[JointType.HipLeft].Position, skeleton.Joints[JointType.AnkleLeft].Position)); if (IsLegForward(leftLegYZ)) { buttons |= (ushort)WritableJoystick.Buttons.Btn7; } if (IsLegBackward(leftLegYZ)) { buttons |= (ushort)WritableJoystick.Buttons.Btn8; } if (dataWithinExpectedRange) { // Invert joystick axis to match a real joystick // (pushing away creates negative values) leftAxis[(uint)WritableJoystick.Axis.Y] = (sbyte)-leftYAxis; rightAxis[(uint)WritableJoystick.Axis.Y] = (sbyte)-rightYAxis; //Use "Button 9" as Kinect control enabled signal buttons |= (ushort)WritableJoystick.Buttons.Btn9; joy[0].Set(leftAxis, buttons); joy[1].Set(rightAxis, buttons); NTKinect.UpdateJoysticks(0.0, leftYAxis, 0.0, rightYAxis); } else { joy[0].Set(nullAxis, 0); joy[1].Set(nullAxis, 0); NTKinect.UpdateJoysticks(0.0, 0.0, 0.0, 0.0); } }