Head Tracking

From Valve Developer Community
Revision as of 17:42, 14 June 2009 by Xteven.xenderson (talk | contribs) (New page: = Head Tracking = This tutorial shows how to interface an external 6 DOF tracking or 6 DOF input device to your Valve Source SDK Mod so you can control the player with the device instead ...)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Head Tracking

This tutorial shows how to interface an external 6 DOF tracking or 6 DOF input device to your Valve Source SDK Mod so you can control the player with the device instead of the mouse and keyboard.

Note, for many 3 DOF (orientation only) input devices (e.g., trackball) you can simply use your device's driver to masquerade as a mouse. But with 6 DOF devices (position and orientation) you have to something more. This tutorial supports external tracking devices (6DOF or less) that can't masquerade as a mouse and possible involve position and orientation

Step 1: Create an Interface to your Tracker

The first step is to create a helper interface that will be used to access your tracker. This class will have interface methods that Valve will call when it needs position and orientation information. This is a software engineering drill, but will be very useful when you want to use more than one type of tracker.


Step 1A: Create the file CPPInterfaces2.h

Put this code inside:

//
// CppInterfaces2.h
//

#define Interface class

#define implements public

#define DeclareInterface(name) __interface actual_##name {

#define DeclareBasedInterface(name, base) __interface actual_##name \
     : public actual_##base {

#define EndInterface(name) };                \
     Interface name : public actual_##name { \
     public:                                 \
        virtual ~name() {}                   \
     };

This is just a bunch of compiler macros that will enforce interface constraints on your code. C++ doesn't provide native interface objects, so this is a way to enforce it so yuo can have the idea of an interface object. If you want the full details, check out this article by Jose Rios

Step 1B: Create the file cl_dll\IMovementController.h.

Put this code inside:


//Include interface enforement directives
#include "CPPInterfaces2.h"

/****************************************************
*  This interface is used to integrate all 
*  Valve movement controllers
*
*
*  Each movement controller provides 6-DOF on
*  a particular object (body part, other tracked object
*
*  This interface assumes that any implementing class
*  will perform any required post processing to transform
*  tracking results into a right handed coordinate system
*  with +Z up -- with units in inches.
*
*****************************************************/
DeclareInterface(IMovementController)
	/**
	*  Returns the orientation from the tracker.  Assumes angles are relative to a right handed coord system with +Z up.
	*  Assumes update() has been called.
	*/
	int		getOrientation(float &pitch, float &yaw, float &roll);

	/**
	*  Returns the position from the tracker.  Assumes coordinates are relative to a right handed coord system with +Z up.
	*  Assumes update() has been called.
	*/
	int		getPosition(float &x, float &y, float &z);
	int		calibrateLocation(float x, float y, float z);
	int		calibrateOrientation(float pitch, float yaw, float roll);
	bool	isTrackerInitialized();

	/**
	*  Reads the hardware and updates local state variables for later read by accessors.
	*/
	void	update();
	void	report();
	bool	hasPositionTracking();
	bool	hasOrientationTracking();
EndInterface(IMovementController)

= Step 1C: Create an Instance of the Interface for Your Tracker

The class will also have any tracker specific API calls and code that deals with the nuances of your particular tracker SDK (e.g., FACE API, Intersense API, etc). Here is an example shell of what this might look like: