private void SkeletonsReady(object sender, SkeletonFrameReadyEventArgs e) { if (closing == true) { return; } // Lets open up the skeleton frame and see how many we have using (SkeletonFrame skeleTors = e.OpenSkeletonFrame()) { if (skeleTors != null) { // If this is the very first run or we had no players and now have players, initialize // our global skeletons if ((this.allSkeletons == null) || (this.allSkeletons.Length != skeleTors.SkeletonArrayLength)) { this.allSkeletons = new Skeleton[skeleTors.SkeletonArrayLength]; } // Copy the skeleton data into our local copy skeleTors.CopySkeletonDataTo(this.allSkeletons); int skeletonSlot = 0; // Loop through each available skelleton foreach (Skeleton oneSkeleton in this.allSkeletons) { // Its an active player - and it isnt beyond the depth threshold - depth is in meters here...0.9..1.345..etc if (oneSkeleton.TrackingState == SkeletonTrackingState.Tracked && (oneSkeleton.Position.Z <= GlobalConfiguration.kinectDepthThresholdMeters)) { // If we have no players and this is the first one and we are in the attract mode // but the question is not visible, show it if (this.players.Count == 0) { if (sec_attract != null && sec_attract.destroyed == false) { if (sec_attract.initialYNPrompt.Opacity == 0) { sec_attract.hideShowInitialQuestion(true); } } } // Do we have cursors on screen for it yet? if (!players.ContainsKey(skeletonSlot)) { InteractivePlayer newPlayer = new InteractivePlayer(skeletonSlot, false); this.players.Add(skeletonSlot, newPlayer); // Listen to events on the cursor this.players[skeletonSlot].playerCursors[ApplicationModel.CURSOR_TYPE_L].cursorActivationUpdate += handleControlActivation; masterParent.Children.Add(this.players[skeletonSlot].playerCursors[ApplicationModel.CURSOR_TYPE_L]); masterParent.Children.Add(this.players[skeletonSlot].playerCursors[ApplicationModel.CURSOR_TYPE_R]); this.players[skeletonSlot].playerCursors[ApplicationModel.CURSOR_TYPE_R].cursorActivationUpdate += handleControlActivation; } this.players[skeletonSlot].lastUpdated = DateTime.Now; // Establish the normalization rectangle based on the players head. We increase sensitivity per player // by establishing a small rectangle around them representing their hand mobility then transform cursors to that // 0 and 1 are set on intialization from the global configuration they are the W and H ColorImagePoint headP = this._sensor.CoordinateMapper.MapSkeletonPointToColorPoint(oneSkeleton.Joints[JointType.Head].Position, ColorImageFormat.RgbResolution640x480Fps30); // 2 and 3 are the real x and y positions this.players[skeletonSlot].playerBounds[2] = headP.X - (this.players[skeletonSlot].playerBounds[0] * (float)0.5); this.players[skeletonSlot].playerBounds[3] = headP.Y; //System.Diagnostics.Debug.WriteLine("Head x: " + headP.X + " y: " + headP.Y + " boundsX: " + this.players[skeletonSlot].playerBounds[2] + " boundsY: " + this.players[skeletonSlot].playerBounds[3]); // Update the L and R hand //Point pt = new Point(oneSkeleton.Joints[JointType.HandRight].Position.X, oneSkeleton.Joints[JointType.HandRight].Position.Y); // ---- RIGHT HAND ColorImagePoint colP = this._sensor.CoordinateMapper.MapSkeletonPointToColorPoint(oneSkeleton.Joints[JointType.HandRight].Position, ColorImageFormat.RgbResolution640x480Fps30); //System.Diagnostics.Debug.WriteLine("O Hand x: " + colP.X + " y: " + colP.Y); // ---- Translate the right hand to player bounds ------ colP = translateFullScreenPointToPlayerBounds(colP, skeletonSlot); // ----- STEP 3 ---- Translate our final coordinates to the UI size -----| colP = normalizePointToRes(colP, GlobalConfiguration.currentKinectScreenW, GlobalConfiguration.currentKinectScreenH, (int)this.players[skeletonSlot].playerBounds[0], (int)this.players[skeletonSlot].playerBounds[1]); // Now these need to be transformed into the real UI Res players[skeletonSlot].playerCursors[ApplicationModel.CURSOR_TYPE_R].Margin = new Thickness(colP.X - 111 * .5, colP.Y - 116 * .5, 0, 0); // Hit test KinectGreenScreen.com.transcendingdigital.ui.Cursors targR = players[skeletonSlot].playerCursors[ApplicationModel.CURSOR_TYPE_R]; doHitTesting(new Point(colP.X, colP.Y), ref targR); // ---- LEFT HAND colP = this._sensor.CoordinateMapper.MapSkeletonPointToColorPoint(oneSkeleton.Joints[JointType.HandLeft].Position, ColorImageFormat.RgbResolution640x480Fps30); // ---- Translate the left hand to player bounds ------ colP = translateFullScreenPointToPlayerBounds(colP, skeletonSlot); // ----- STEP 3 ---- Translate our final coordinates to the UI size -----| colP = normalizePointToRes(colP, GlobalConfiguration.currentKinectScreenW, GlobalConfiguration.currentKinectScreenH, (int)this.players[skeletonSlot].playerBounds[0], (int)this.players[skeletonSlot].playerBounds[1]); players[skeletonSlot].playerCursors[ApplicationModel.CURSOR_TYPE_L].Margin = new Thickness(colP.X - 111 * .5, colP.Y - 116 * .5, 0, 0); // Hit test left hand KinectGreenScreen.com.transcendingdigital.ui.Cursors targL = players[skeletonSlot].playerCursors[ApplicationModel.CURSOR_TYPE_L]; doHitTesting(new Point(colP.X, colP.Y), ref targL); } skeletonSlot++; } // Clean up any cursors for players no longer available // --- handled by inactivity timer } } }
/// <summary> /// Can only handle one kinect. Make sure to put these in try catch blocks /// in case the target system well doesnt have a kinect. /// </summary> private void setupKinect() { try { foreach (var potentialSensor in KinectSensor.KinectSensors) { if (potentialSensor.Status == KinectStatus.Connected) { _sensor = potentialSensor; break; } } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine("Exception trying to find Kinect " + ex.Message); } try { if (_sensor != null) { _sensor.ColorStream.Enable(ColorImageFormat.RgbResolution1280x960Fps12); _sensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30); // Settings for the color stream ColorCameraSettings colorSettings = _sensor.ColorStream.CameraSettings; // First reset everything in case they were not defaults to start colorSettings.ResetToDefault(); // Auto Exposure or Not //-------------------------------------- if (Properties.Settings.Default.kinectAutoExposure == true) { colorSettings.AutoExposure = true; // Gets or sets the brightness or lightness as distinct from hue or saturation. The range is [0.0, 1.0]; the default value is 0.2156. colorSettings.Brightness = Properties.Settings.Default.kinectAutoExposureBrightness; } else { colorSettings.AutoExposure = false; // Gets or sets the frame interval, in units of 1/10,000 of a second. The range is [0, 4000]; the default value is 0. colorSettings.FrameInterval = Properties.Settings.Default.kinectManualExposureFrameInterval; // Gets or sets the exposure time in increments of 1/10,000 of a second. The range is [0.0, 4000]; the default value is 0.0. // BZZZ WRONG - SDK 1.7 throws an exception if this is 0 when autoexposure is false colorSettings.ExposureTime = Properties.Settings.Default.kinectManualExposureTime; // Gets or sets the gain, which is a multiplier for the RGB color values. The range is [1.0, 16.0]; the default value is 1.0 colorSettings.Gain = Properties.Settings.Default.kinectGain; } //----------------------------------------- // Advanced Color Settings //----------------------------------------- if (Properties.Settings.Default.kinectAutoWhiteBalance == true) { colorSettings.AutoWhiteBalance = Properties.Settings.Default.kinectAutoWhiteBalance; } else { colorSettings.AutoWhiteBalance = Properties.Settings.Default.kinectAutoWhiteBalance; // Gets or sets the white balance, which is a color temperature in degrees Kelvin. The range is [2700, 6500]; the default value is 2700. colorSettings.WhiteBalance = Properties.Settings.Default.kinectManualWhiteBalanceValue; } // Gets or sets the contrast, which is the amount of difference between lights and darks. The range is [0.5, 2.0]; the default value is 1.0. colorSettings.Contrast = Properties.Settings.Default.kinectManualContrast; // Gets or sets gamma, which is a nonlinear operation for coding luminance data. The range is [1.0, 2.8]; the default value is 2.2. colorSettings.Gamma = Properties.Settings.Default.kinectManualGamma; // Gets or sets the hue, which describes the shade of a color. The range is [–22.0, 22.0]; the default value is 0.0. colorSettings.Hue = Properties.Settings.Default.kinectManualHue; // Gets or sets the saturation, which is the colorfulness of a color relative to its own brightness. The range is [0.0, 2.0]; the default value is 1.0. colorSettings.Saturation = Properties.Settings.Default.kinectManualSaturation; // Gets or sets the sharpness, which describes the amount of detail visible. The range is [0, 1.0]; the default value is 0.5. colorSettings.Sharpness = Properties.Settings.Default.kinectManualSharpness; //----------------------------------------- var parameters = new TransformSmoothParameters { Smoothing = 0.3f, Correction = 0.0f, Prediction = 0.0f, JitterRadius = 1.0f, MaxDeviationRadius = 0.5f }; // Seated mode if (Properties.Settings.Default.kinectSeatedModeEnabled == true) { _sensor.SkeletonStream.TrackingMode = SkeletonTrackingMode.Seated; } else { _sensor.SkeletonStream.TrackingMode = SkeletonTrackingMode.Default; } _sensor.SkeletonStream.Enable(parameters); _sensor.SkeletonFrameReady += SkeletonsReady; // Temporarily add only one kinect player with L and R hands //appState.AddInteractivePlayer(false, ref masterParent, this); try { _sensor.Start(); } catch (System.IO.IOException) { // Should throw an application conflict because something else is using it throw; } // Start the timeout timer // Checks for active players setupInactivityTimer(); } } catch (Exception ex2) { System.Diagnostics.Debug.WriteLine("Exception initializing kinect settings " + ex2.Message); } try { if (_sensor == null) { // We're in mouse mode! //mouseMode = true; // Add a listener mainWindow.MouseMove += Window_MouseMove; InteractivePlayer newPlayer = new InteractivePlayer(players.Count, true); this.players.Add(0, newPlayer); // Listen to events on the cursor this.players[0].playerCursors[ApplicationModel.CURSOR_TYPE_L].cursorActivationUpdate += handleControlActivation; masterParent.Children.Add(this.players[0].playerCursors[ApplicationModel.CURSOR_TYPE_L]); } } catch (Exception ex3) { System.Diagnostics.Debug.WriteLine("Exception initializing mouse settings " + ex3.Message); } }