Easiest place to hook into X,Y and Z values

May 29, 2011 at 6:37 PM

Hi Josh,

Could you please tell me where the best place I can hook into a realtime feed of x,y and z values being returned from the device?  

My goal is to have the user initiate the gestures by doing the standard wave gesture, and then look for them moving their hand along the x, y and z axis.  I will be feeding these values to properties in a view model that will drive triggers for a view that will produce visual state transitions. 

I'm simply dividing the screen up into three areas and will move a rectangle (represents a selector in the UI) along the x-axis.  The user will move their hand down when they want to select an item from the collection that the rectange is transitioning through.  Thanks.

Cheers,

Jeff

May 29, 2011 at 11:28 PM

I looked around the code and I think that the following line provides updated values of the x,y and z coordinates:

UpdateHandSession((

int

)user * 2 + 1, rightHand, rightShoulder);

The rightHand object has all three of these values updated when the skeleton file has been read and the user is engaged with the sensor.

Coordinator
May 30, 2011 at 12:21 AM

Jeff,

You can subscribe to MotionTracking events such as MotionTrackingStarted, MotionTrackingUpdated, and MotionTrackingLost. These will give you a MotionTrackingEventArgs, which has a MotionTrackingDevice property. The MotionTrackingDevice has a Session property that gives you a HandSession, which give you access to Point3D properties of Position, ShoulderPosition, and PositionProjective.

That sounds complex but it's actually pretty simple. It's just three new routed events that you can use in your visual tree. In code-behind you could use it like this:

UIElement element = GetUIElement();
MotionTracking.AddMotionTrackingUpdatedHandler(element, new MotionTrackingEventHandler(Element_MotionTrackingUpdated));

void Element_MotionTrackingUpdated(object sender, MotionTrackingEventArgs e)
{
    System.Windows.Media.Media3D.Point3D position = e.MotionTrackingDevice.Session.Position;
}

Or in XAML, make sure you have the MotionFx namespace mapped somewhere with:

xmlns:m="clr-namespace:InfoStrat.MotionFx;assembly=InfoStrat.MotionFx"

and then on any random element:

<Grid m:MotionTracking.MotionTrackingUpdated="Element_MotionTrackingUpdated">

Also you might be interested to know that these events are how the InputFilters such as PushMotionInputFilter work. They subscribe to these events then if the parameters are sufficient (such as the HandSession.Position.Z being far enough in front of HandSession.ShoulderPosition.Z) then it sets

e.MotionTrackingDevice.ShouldPromoteToTouch = true;


Then when the rounting for the respective MotionTracking event finishes, the MotionTracking class does some checks and promotes (or not) the MotionTracking event to a touch event.

For now, if you need to know which user the HandSession belongs to, you can do something like:

int userId = (int)Math.Floor(Session.Id / 2);

I know that is clunky, but that's what I had at the moment for v0.2. In my current private builds I have a lot more and better classes built out to make some of this more elegant.

Thanks,

Josh