public double Update(IList <Body> skeletons, int bodyCount) { if (activeBody != null) { zoomRight = activeBody.Joints[JointType.HandRight].Position.X; // kinect units are in meters. Hence left - right is scaled from minHandDistance to maxHandDistance double handDistance = (zoomRightStart - zoomRight); bool zoomOut = (handDistance < 0); handDistance = Math.Abs(handDistance); handDistance = handDistance.Clamp(minHandDistance, maxHandDistance); double zoomFraction = calculateZoomFactor(handDistance, zoomOut); double returnValue = (zoomFraction / currentZoom); currentZoom = zoomFraction; if (!GestureUtils.IsZoomGestureActive(activeBody)) { activeBody = null; //Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("DEACTIVATED\n"); } return(returnValue); } return(1); }
// Finds the closest body from the sensor if any private static Microsoft.Kinect.Body FindClosestBody( BodyFrame bodyFrame ) { Microsoft.Kinect.Body result = null; double closestBodyDist = double.MaxValue; var bodies = new Microsoft.Kinect.Body[bodyFrame.BodyCount]; bodyFrame.GetAndRefreshBodyData(bodies); foreach (var body in bodies) { if (body.IsTracked) { var curLoc = body.Joints[JointType.SpineBase].Position; var curDist = VectorLength(curLoc); if (result == null || curDist < closestBodyDist) { result = body; closestBodyDist = curDist; } } } return(result); }
public override void Update(Microsoft.Kinect.Body body) { //check next gesture of the sequence GesturePartResult result = this.CheckGesturePart(body); //if result has been positive if (result == GesturePartResult.Succeded) { //increase counter and check whether the limit has been reached (--> fire event) this.CheckSuccededFlow(body); } //if result has been negative else { //check whether maximal amount of frames has been arrived if (++_frameCounter == MAX_WINDOW_SIZE) { //reset counter this.Reset(); //check this frame again, maybe it might be the start of a new gesture: //DO NOT USE RECURSITION since this might lead into a stack overflow! result = this.CheckGesturePart(body); if (result == GesturePartResult.Succeded) { CheckSuccededFlow(body); // it is not necessary to check the boundaries of the array since we know, that this array has more than 2 fields } } } }
public Vector3d Update(IList <Body> skeletons, int bodyCount) { Vector3d movement = new Vector3d(0.0, 0.0, 0.0); if (activeBody != null) { toolPosition = activeBody.Joints[JointType.HandRight].Position; double dX = (toolPosition.X - toolPreviousPosition.X); double dY = (toolPosition.Y - toolPreviousPosition.Y); double dZ = (toolPosition.Z - toolPreviousPosition.Z); double distance = Math.Sqrt(dX * dX + dY * dY + dZ * dZ); if (distance > ROTATION_COMMAND_THRESHOLD) { toolPreviousPosition = toolPosition; movement = new Vector3d(dX, dY, dZ); } if (activeBody.HandRightState != HandState.Closed) { activeBody = null; //Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("DEACTIVATED\n"); } } return(movement); }
void ProcessHandGesture(KBody user, J hand, HandState curState, HandState oldState) { var id = user.TrackingId; var uiInteracting = uiInterState != UIInterState.IDLE && uiInterUserId == id && uiInterHand == hand; var shoulderPos = user.Joints[J.SpineShoulder].Position; //filter on old state if (oldState == HandState.Closed) { if (uiInterState == UIInterState.GRABBING_MENU && uiInteracting) { uiInterState = UIInterState.IDLE; if (user.Joints[hand].Position.Y < shoulderPos.Y) { interCbWithIdleRefresh(id, InteractionType.RELEASE_MENU_SHOW, 0); } else { interCbWithIdleRefresh(id, InteractionType.RELEASE_MENU_CANCEL, 0); } } else { interCbWithIdleRefresh(id, InteractionType.RELEASE, hand); } } else if (oldState == HandState.Lasso) { interCbWithIdleRefresh(id, InteractionType.END_DRAW, hand); } //filter on current state if (curState == HandState.Closed) { if (uiInterState == UIInterState.PEEKING_MENU && uiInteracting) { uiInterState = UIInterState.GRABBING_MENU; interCbWithIdleRefresh(id, InteractionType.GRAB_MENU, hand); } else { interCbWithIdleRefresh(id, InteractionType.GRAB, hand); } } else if (curState == HandState.Lasso) { interCbWithIdleRefresh(id, InteractionType.BEGIN_DRAW, hand); } }
/// <summary> /// Constructs a body adapter from a kinect sdk body /// </summary> /// <param name="body">Body from Kinect SDK</param> public KinectBody(Microsoft.Kinect.Body body) { this.clippedEdges = body.ClippedEdges; this.handLeftConfidence = body.HandLeftConfidence; this.handLeftState = body.HandLeftState; this.handRightConfidence = body.HandRightConfidence; this.handRightState = body.HandRightState; this.isRestricted = body.IsRestricted; this.isTracked = body.IsTracked; this.jointOrientations = body.JointOrientations; this.joints = body.Joints; this.lean = body.Lean; this.leanTrackingState = body.LeanTrackingState; this.trackingId = body.TrackingId; }
// This event is fired when a tracking is lost for a // body tracked by HDFace Tracker private void HdFaceSource_TrackingIdLost( object sender, TrackingIdLostEventArgs e ) { var lostTrackingID = e.TrackingId; if (_currentTrackingId == lostTrackingID) { _currentTrackingId = 0; _currentTrackedBody = null; if (_faceModelBuilder != null) { _faceModelBuilder.Dispose(); _faceModelBuilder = null; } _hdFaceFrameSource.TrackingId = 0; } }
// This event fires when a BodyFrame is ready for consumption private void BodyReader_FrameArrived( object sender, BodyFrameArrivedEventArgs e ) { CheckOnBuilderStatus(); var frameReference = e.FrameReference; using (var frame = frameReference.AcquireFrame()) { if (frame == null) { // We might miss the chance to acquire the frame, // it will be null if it's missed return; } if (_currentTrackedBody != null) { _currentTrackedBody = FindBodyWithTrackingId(frame, _currentTrackingId); if (_currentTrackedBody != null) { return; } } var selectedBody = FindClosestBody(frame); if (selectedBody == null) { return; } _currentTrackedBody = selectedBody; _currentTrackingId = selectedBody.TrackingId; _hdFaceFrameSource.TrackingId = _currentTrackingId; } }
public bool IsActive(IList <Body> skeletons, int bodyCount) { if (activeBody == null && skeletons != null) { for (int i = 0; i < bodyCount; i++) { Microsoft.Kinect.Body body = skeletons[i]; if (GestureUtils.IsZoomGestureActive(body)) { activeBody = body; currentZoom = 1.0; zoomRightStart = activeBody.Joints[JointType.HandRight].Position.X; zoomRight = zoomRightStart; //Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("ZOOM\n"); break; } } } return(activeBody != null); }
public bool IsActive(IList <Body> skeletons, int bodyCount) { if (activeBody == null && skeletons != null) { for (int i = 0; i < bodyCount; ++i) { Microsoft.Kinect.Body body = skeletons[i]; if (GestureUtils.IsOrbitGestureActive(body)) { activeBody = body; //Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("ORBIT\n"); // Record right hand location toolStartPosition = activeBody.Joints[JointType.HandRight].Position; toolPreviousPosition = toolStartPosition; break; } } } return(activeBody != null); }
// Find if there is a body tracked with the given trackingId private static Microsoft.Kinect.Body FindBodyWithTrackingId( BodyFrame bodyFrame, ulong trackingId ) { Microsoft.Kinect.Body result = null; var bodies = new Microsoft.Kinect.Body[bodyFrame.BodyCount]; bodyFrame.GetAndRefreshBodyData(bodies); foreach (var body in bodies) { if (body.IsTracked) { if (body.TrackingId == trackingId) { result = body; break; } } } return(result); }
private void AddLinesForSkeleton( List <Line> lines, Microsoft.Kinect.Body sk, int idx ) { // Hard-code lists of connections between joints var links = new int[][] { // Head to left toe new int[] { 3, 2, 20, 1, 0, 12, 13, 14, 15 }, // Hips to right toe new int[] { 0, 16, 17, 18, 19 }, // Left hand to right hand new int[] { 21, 7, 6, 5, 4, 2, 8, 9, 10, 11, 23 }, // Left thumb to palm new int[] { 22, 7 }, // Right thumb to palm new int[] { 24, 11 } }; // Populate an array of joints var joints = new Point3dCollection(); for (int i = 0; i < sk.Joints.Count; i++) { joints.Add( PointFromVector( sk.Joints[(JointType)i].Position, false ) ); } // For each path of joints, create a sequence of lines int limit = sk.Joints.Count - 1; foreach (int[] link in links) { for (int i = 0; i < link.Length - 1; i++) { // Only add lines where links are within bounds // (check needed for seated mode) int first = link[i], second = link[i + 1]; if ( isValidJoint(first, limit) && isValidJoint(second, limit) ) { // Line from this vertex to the next var ln = new Line(joints[first], joints[second]); // Set the color to distinguish between skeletons ln.ColorIndex = idx; // Make tracked skeletons bolder ln.LineWeight = (sk.IsTracked? LineWeight.LineWeight050 : LineWeight.LineWeight000 ); lines.Add(ln); } } } }
void DetectEvent(KBody user) { var id = user.TrackingId; var oldHands = usersHands[id]; var now = DateTime.Now; var clippedEdges = (user.ClippedEdges & (FrameEdges.Right | FrameEdges.Left | FrameEdges.Top)) != 0; var lastLeftEventElapsed = now - oldHands.LeftChangeTime; var lastRightEventElapsed = now - oldHands.RightChangeTime; var topHeadPos = user.Joints[J.Head].Position; var spineMidPos = user.Joints[J.SpineMid].Position; var leftCoord = CameraPointToScreen(user.Joints[J.HandLeft].Position); var rightCoord = CameraPointToScreen(user.Joints[J.HandRight].Position); var leftWristPos = user.Joints[J.WristLeft].Position; var rightWristPos = user.Joints[J.WristRight].Position; var leftHandTracked = user.Joints[J.HandLeft].TrackingState == TrackingState.Tracked; var rightHandTracked = user.Joints[J.HandRight].TrackingState == TrackingState.Tracked; var leftEngaged = leftHandTracked && leftWristPos.Y > spineMidPos.Y + ENGAGED_SPINE_OFFSET; var rightEngaged = rightHandTracked && rightWristPos.Y > spineMidPos.Y + ENGAGED_SPINE_OFFSET; //Hand shape gestures: //both hands logic: if (lastLeftEventElapsed > ANTI_SPAM_SPAN || lastRightEventElapsed > ANTI_SPAM_SPAN) { var leftClosed = user.HandLeftState == HandState.Closed; var rightClosed = user.HandRightState == HandState.Closed; var oldLeftClosed = oldHands.LeftState == HandState.Closed; var oldRightClosed = oldHands.RightState == HandState.Closed; if (leftEngaged && rightEngaged && leftClosed && rightClosed && (!oldLeftClosed || !oldRightClosed)) { interCbWithIdleRefresh(id, InteractionType.BEGIN_CREATING_OBJECT, 0); } else if (oldLeftClosed && oldRightClosed && (!leftClosed || !rightClosed)) { interCbWithIdleRefresh(id, InteractionType.FINISH_CREATING_OBJECT, 0); } // old hand state is updated below } //left hand logic: if (lastLeftEventElapsed > ANTI_SPAM_SPAN) { if (user.HandLeftState == HandState.Unknown || user.HandLeftState == HandState.NotTracked) { //hand gesture expired if (oldHands.LeftState != HandState.Unknown && now - oldHands.LeftChangeTime > EXPIRE_STATE_SPAN) { ProcessHandGesture(user, J.HandLeft, user.HandLeftState, oldHands.LeftState); oldHands.LeftState = HandState.Unknown; } } else if (user.HandLeftState != oldHands.LeftState && (user.HandLeftState != HandState.Lasso || leftEngaged)) { ProcessHandGesture(user, J.HandLeft, user.HandLeftState, oldHands.LeftState); oldHands.LeftState = user.HandLeftState; oldHands.LeftChangeTime = now; } } //right hand logic: if (lastRightEventElapsed > ANTI_SPAM_SPAN) { if (user.HandRightState == HandState.Unknown || user.HandRightState == HandState.NotTracked) { //hand gesture expired if (oldHands.RightState != HandState.Unknown && now - oldHands.RightChangeTime > EXPIRE_STATE_SPAN) { ProcessHandGesture(user, J.HandRight, user.HandRightState, oldHands.RightState); oldHands.RightState = HandState.Unknown; } } else if (user.HandRightState != oldHands.RightState && (user.HandRightState != HandState.Lasso || rightEngaged)) { ProcessHandGesture(user, J.HandRight, user.HandRightState, oldHands.RightState); oldHands.RightState = user.HandRightState; oldHands.RightChangeTime = now; } } if (id == uiInterUserId) { // menu peeking gestures: //left hand logic: if (leftEngaged && !clippedEdges && leftWristPos.Y > topHeadPos.Y && user.HandLeftState == HandState.Open) { if (uiInterState == UIInterState.IDLE) { uiInterState = UIInterState.PEEKING_MENU; uiInterHand = J.HandLeft; interCbWithIdleRefresh(id, InteractionType.PEEK_MENU, J.HandLeft); } } else if (uiInterState == UIInterState.PEEKING_MENU && uiInterHand == J.HandLeft) { uiInterState = UIInterState.IDLE; interCbWithIdleRefresh(id, InteractionType.CANCEL_PEEK_MENU, J.HandLeft); } //right hand logic: if (rightEngaged && !clippedEdges && rightWristPos.Y > topHeadPos.Y && user.HandRightState == HandState.Open) { if (uiInterState == UIInterState.IDLE) { uiInterState = UIInterState.PEEKING_MENU; uiInterHand = J.HandRight; interCbWithIdleRefresh(id, InteractionType.PEEK_MENU, J.HandRight); } } else if (uiInterState == UIInterState.PEEKING_MENU && uiInterHand == J.HandRight) { uiInterState = UIInterState.IDLE; interCbWithIdleRefresh(id, InteractionType.CANCEL_PEEK_MENU, J.HandRight); } // Margin reaching logic: //left if (leftHandTracked && (leftCoord.X < gameSpace.Left || (user.ClippedEdges & FrameEdges.Left) != 0)) { if (leftEngaged && uiInterState == UIInterState.IDLE) // put in nested if to allow keeping margin interaction if hand is lowered { uiInterState = UIInterState.REACHING_MARGIN; uiInterHand = J.HandLeft; interCbWithIdleRefresh(id, InteractionType.BEGIN_REACH_MARGIN, J.HandLeft); } } else if (uiInterState == UIInterState.REACHING_MARGIN && uiInterHand == J.HandLeft) { uiInterState = UIInterState.IDLE; interCbWithIdleRefresh(id, InteractionType.END_REACH_MARGIN, J.HandLeft); } //right if (rightHandTracked && (rightCoord.X > gameSpace.Right || (user.ClippedEdges & FrameEdges.Right) != 0)) { if (rightEngaged && uiInterState == UIInterState.IDLE) { uiInterState = UIInterState.REACHING_MARGIN; uiInterHand = J.HandRight; interCbWithIdleRefresh(id, InteractionType.BEGIN_REACH_MARGIN, J.HandRight); } } else if (uiInterState == UIInterState.REACHING_MARGIN && uiInterHand == J.HandRight) { uiInterState = UIInterState.IDLE; interCbWithIdleRefresh(id, InteractionType.END_REACH_MARGIN, J.HandRight); } } }