/**
@mainpage OpenNI Documentation

This guide's target audience is software developers using OpenNI.
It includes the following chapters:
- @subpage introduction
- @subpage concepts
- @subpage recordings
- @subpage tutorials
- @subpage ref_page
- @subpage xmlscripts
- @subpage cmdutils
- @subpage samples
- @subpage additional
- @subpage legal
*/



/**
@page introduction Introduction

@section intro_motivation Motivation

OpenNI is intent to help develop applications that use 3D vision inputs (such as full body control),
by breaking the rigid connection between the application and the sensor and/or vision algorithms.
Its purpose is to shorten the time-to-market of such applications when wanting to port them to use
other algorithms, or another sensor.

@section intro_general_description General Description

OpenNI is a standard interface for 3D sensor data processing algorithms. It is open for all (published 
on web site) and open source. The purpose is to define data types (depth map, color map, user pose, etc.) 
and an interface to a module that can generate them (sensor, skeleton algorithm, etc.), for 3rd party developers.
- Applications / Games developers can write their applications regardless of the actual supplier that creates 
the 3D vision products (skeleton, hand points, etc.)
Middleware developers can write algorithms on top of raw data formats, regardless of the actual device 
producing them.
- Sensors Manufacturers can implement the device interface for their sensor, so that applications written 
on top of OpenNI can work with any sensor.

OpenNI main purpose is to provide an interface for applications that use
natural interface (gestures / poses) as their input. The application can
be written once, and then it can be run regardless of the vendor or version
of the natural interface provider.

OpenNI guarantees full backwards compatibility, so that drivers written for older
versions will still work in new versions. Each driver/application that installs itself
on a machine should also install the latest version of OpenNI.

@section intro_nodes Production Nodes

Creating a 3D vision product is usually more complex than simply getting the output of a specific
sensor. It usually starts with an actual device (the sensor) producing some sort of output (the most
common case is a depth map, where each pixel has its distance from the sensor). Some sort of middleware
is then used to process this output, and produce a higher-level output, like the location of a user,
or its current pose.

OpenNI defines "production units", where each such unit can receive data from other such units,
and, optionally, producing data that might be used by other units or by the application itself.
To support this flow, each such unit is called a Production Node, and all those nodes
are connected in a production graph.

In most cases, an application is only interested in the top-most product of such a graph. OpenNI
allows the application to use a single node, without knowing anything about the entire graph
behind this node. Of course, for advanced tweaking, there is an option to access that graph, and
configure each of the nodes.

Depending on the machine on which the application is running, and on the accessories attached to it
in a specific moment, different graphs can be created to generate the same type of data.
OpenNI provides an interface for enumerating possible production trees for receiving
a specific product. The application can then choose one of those graphs and create it.
It is entirely the application's responsibility of choosing one tree out of the possibilities
returned by OpenNI framework. It may do so by preferring specific vendors, components,
or versions.

@section intro_node_types Nodes Types

Each production node has a type. Current supported types are:

- @b Device - represents a physical device
- @b Depth - generates depth-maps
- @b Image - generates colored image-maps
- @b IR - generates IR image-maps
- @b Audio - generates an audio stream
- @b Gestures - generates callbacks when specific gestures are identified
- @b SceneAnalyzer - analyzes a scene (separates background from foreground, etc.)
- @b Hands - generates callbacks when hand points are created, their positions change, and are destroyed
- @b User - generates a representation of a user in the 3D space.

Also, for implementation, the following node types are supported:
- @b Recorder - implements a recording of data.
- @b Player - can read data from a recording and play it.
- @b Codec - used for compression and decompression of data in recordings.

Each type of production node provides different functionality for configuration. 
Some functions are common for all generators (to exclude physical device, which doesn't actually
produce anything). Some are common for all map generators (depth, image, IR), etc.

@section intro_caps Capabilities

OpenNI acknowledges that different providers might have different configuration options
for their production nodes. So, a set of common configurations was chosen to be mandatory
from all providers. In addition, some non-mandatory configuration options were defined, and each
provider can decide whether it wishes to implement them or not. These are called capabilities.

Each capability is composed of a set of functions which OpenNI exposes. A production node can 
be asked if it supports a specific capability. If it does, those functions can be called for
that specific node.

One may think of capabilities as extensions to the common interface.

Currently, all capabilities must be defined by OpenNI. In the future, vendors will be able to add
new capabilities, and supply them to applications.

@section intro_modules Modules

An OpenNI Module is a shared library (.DLL file on Windows, .SO file on Linux) which contains an 
implementation of one or more nodes. A module is actually a plug-in to the OpenNI framework. Once
a module is registered with OpenNI, it is part of the enumeration process, and, depending on the
application, can be used.

@section intro_bc Backwards Compatibility

OpenNI declares a full backwards compatibility. This means every application developed over version X
of OpenNI, will also work (without the need of recompilation) in every future version.
Each machine should have the latest OpenNI version (at least the latest of every OpenNI version needed
by every application installed on this machine). In order to achieve this, every application installation
should also install OpenNI.

@section intro_choosing_c Choosing C over C++

OpenNI's core interface is defined C. Supposedly, a native C++ interface would have been easier and prettier, but issues 
such as name mangling and class representation in memory are not standardized, so a C++ interface would have caused 
inter-compiler compatibility problems. This could cause a situation in which OpenNI would be compiled in one 
compiler and an application in another compiler, and when the application called OpenNI's API it would produce 
unexpected results. The advantage of a C interface is that all C compilers use the same naming scheme, and there are 
no memory representation issues (a struct is just a struct for all compilers, unlike a C++ class). An alternative to 
this approach could be providing seperate pre-compiled versions of the library for each compiler, but that could 
cause a situation in which a plugin that was built with OpenNI for compiler A would use OpenNI compiled for compiler A,
and that library's state would be affected, but an application that was compiled with compiler B would not be affected 
by that state change, because it sees a version of the OpenNI library compiled for compiler B. In addition, maintaining 
these seperate versions would add a lot of overhead, and it would block usage by unsupported compilers.

@section intro_cpp C++ Wrappers

Although OpenNI's interface is completely defines in C, OpenNI also supplies a set of C++ wrappers,
for developers preferring C++, providing better type-safety and better readability. Those C++ wrappers are 
defined solely in header files, and they take all OpenNI C functions, and separate them into classes. The reason 
these wrappers are all defined in header files is that each C++ compiler can choose to represent classes in memory 
in a different way, so we avoid the problem by letting each project that uses OpenNI compile the wrappers (See also 
@ref intro_choosing_c).
Every method in those classes is defines inline, so that performance is not affected.
Please note that most of the samples arriving with OpenNI are written using the C++ wrappers.
*/











/**
@page concepts Concepts

This page explains some of the concepts of OpenNI interface and framework:
- @subpage conc_context
- @subpage conc_node_handles
- @subpage conc_chains
- @subpage conc_enumeration
- @subpage conc_licenses
- @subpage conc_refcount
- @subpage conc_generation
- @subpage conc_read
- @subpage conc_meta_data
- @subpage conc_locks
- @subpage conc_global_mirror
- @subpage conc_error_state
- @subpage conc_mocks

*/

/**

@page conc_context Context

The main object in OpenNI is the Context. A context is an object keeping a complete state for applications
using OpenNI, including the entire production graph used by the application. The same application may 
create more than one context, but the contexes can not share information between them (for example, an
algorithm node can not use a device node from another context).
The context needs to be initialized once before starting to use it. In this point, all plug-ins are
loaded and analyzed. In order to free all memory used by the context, one should call the shutdown function.

@page conc_node_handles Node Handles

In C interface, each production node in the context is accessed using a node handle (@ref XnNodeHandle).
Every function on a specific node takes the node handle as its first argument. In C++, every class
inheriting from @ref xn::NodeWrapper holds the handle as a member, making it easier for applications
to use the methods.

@page conc_chains Production Chains

An application usually needs just one 3D vision product to be generated by OpenNI (human pose, gestures recognition, etc.).
However this generated product is usually produced using a production chain. This means the vision product can be 
generated in a number of ways - either by different algorithms or the same algorithm using different
raw data for processing.

When an application asks OpenNI for a specific generated product, OpenNI returns a list of all currently possible
ways of producing it. This depends on installed modules, currently attached devices, and available licenses. 

A production chain is represented using an object called Node Info (see @ref prdnodeinfo for C, or  @ref xn::NodeInfo
for C++). This object contains information about the current node, such as its vendor, name, version, and most importantly,
its type. The node info object can represent either an existing node that was already created, or an option for 
creating a node. For example, if an application enumerates for a node in the first time with @ref xnEnumerateProductionTrees, 
it will probably get a node info object which is not connected to an existing node. Once the application chooses
to create this node with @ref xnCreateProductionTree, a node will be created, and the node info object will also hold the 
node handle.

The application can choose a production chain according to some or all nodes in the chain. For example, suppose an application
asks for a User Generator. A User Generator requires a Depth Generator to operate, and suppose there are two types 
of Depth Generators installed on the machine. In this case the application would get two production chains for the 
User Generator: One for each option of the underlying Depth Generator. The application can then choose the preferred 
production chain according to its considerations, e.g. choosing a specific vendor, or choosing a depth node that 
provides certain capabilities.

Each Node Info object holds a list of needed nodes, thus creating a nodes graph. The list of needed nodes is accessed 
using an object called Node Info List (see @ref infolist for C, or @ref xn::NodeInfoList for C++).

@page conc_enumeration Enumeration Process

When OpenNI is initializing, it loads each registered module, and asks it for the types of nodes it
implements. Then, when an application asks for a specific generated product, OpenNI enumerates every module that
declared itself as generating that product, for currently possible production chains. Each module builds a list of 
production chains it can create right now (possible by enumerating for other node types), and returns it to OpenNI. 
OpenNI then appends all those lists together, and returns them to the application.
The application can then choose the specific node it wants to use right now, and asks OpenNI to create
it.

In most cases, the application will prefer (or even demand) certain constraints from those chains. For example,
an application might need the node to support a specific capability it needs. For this reason, the enumeration
functions can receive a Query object (see @ref queries for C, or @ref xn::Query for C++).

NOTE: OpenNI may also return existing nodes during enumeration, if they match the requested criterias.

As a shortcut, in case the application doesn't care about different chains, and just needs any node of the requested
type, it can do so using one of the following functions:
- @ref xnCreateDepthGenerator()
- @ref xnCreateImageGenerator()
- @ref xnCreateIRGenerator()
- @ref xnCreateAudioGenerator()
- @ref xnCreateGestureGenerator()
- @ref xnCreateSceneAnalyzer()
- @ref xnCreateHandsGenerator()
- @ref xnCreateUserGenerator()

In C++ this can be done using
- @ref xn::DepthGenerator::Create()
- @ref xn::ImageGenerator::Create()
- @ref xn::IRGenerator::Create(),
- @ref xn::AudioGenerator::Create()
- @ref xn::GestureGenerator::Create()
- @ref xn::SceneAnalyzer::Create()
- @ref xn::HandsGenerator::Create()
- @ref xn::UserGenerator::Create()

Note that just like in the full enumeration process, these functions also allow the application to specify certain constraints 
about the created nodes with a Query object, such as the vendor that supplies the generator, a version number, certain 
capabilities, and more (see @ref queries for the C functions, or @ref xn::Query for the C++ functions).

@page conc_licenses Licenses

OpenNI provides a simple licensing mechanism that can be used by modules and applications. An OpenNI context object 
holds a list of currently loaded licenses. At any point this list can be accessed to search for a specific license. 

A license is composed of a vendor name and a license key. Each vendor has its own proprietary format 
for the key.

Common usage of the license mechanism is by modules requiring licenses. The module can check the licenses
list whenever an enumeration request arrives, and, if the requested license isn't present, the module
may hide itself, by returning zero results.

OpenNI also provides a global registry for license keys. Those keys are loaded whenever a context is initialized.
Most modules might ask the user for a license key when installing themselves to a machine. The license provided
by the user can then be added to the global license registry. Adding or removing licenses from
the global registry can be done using the @ref nilicense command-line tool.

In addition, sometimes an application has a private license to a module. Meaning, this module can only
be activated via this application (preventing other applications from using it). Applications may add
additional licenses in run-time to the context using the @ref xnAddLicense() function (@ref xn::Context::AddLicense()).

@page conc_refcount Reference Counting

OpenNI uses reference counting for objects that might be shared between several components of the application.
Those objects include the context itself, all types of production nodes, and Node Info objects.
When a node is created, it has a reference count of 1, and the node handle is returned to the
creator. The creator can increase the ref count by calling @ref xnProductionNodeAddRef() or @ref xn::ProductionNode::AddRef().
Once someone holding a node does not need it anymore, it may call @ref xnProductionNodeRelease() or @ref xn::ProductionNode::Release().
If a node's reference count reaches 0, the node will be removed from context and destroyed.

<table>
	<tr><th>Note:</th></tr>
	<tr><td>
An application may not assume anything about the existence of a node once the node is unreferenced.
The node might be destroyed, but it also might still exist, if some other node is using it. <b>In any case
it is forbidden for an application to use the node handle once it was unreferenced.</b>
	</td></tr>
</table>

Initializing context from a script file (XML), using the @ref xnInitFromXmlFileEx() function, usually creates 
some nodes (depending on the script). The function returns a node which is the owner of all created nodes. 
Once this node is destroyed, all nodes created from the script will be release as well (unless the application 
holds another reference to them).

<table>
	<tr><th>Note:</th></tr>
	<tr><td>
There is also a deprecated function named @ref xnInitFromXmlFile(). This function lets the context own all
created nodes. The problem is there is no way of releasing those nodes except for calling @ref xnShutdown(), 
which destroys everything in the context. This method is obsolete and should not be used. It only exists
for backwards compatibility (this was the only API up to version 1.1).
	</td></tr>
</table>

Please note that referencing a <b>Node Info</b> object of an existing node also counts as a reference to this
node. For example, if the application called @ref xnEnumerateExistingNodes() (@ref xn::Context::EnumerateExistingNodes()),
and received a <i>Node Info List</i> that contains this node, then the node reference count was increased by 1.
The application must free the list in order to unref each node in that list. This can be done by calling
@ref xnNodeInfoListFree() (in C++, the destructor of @ref xn::NodeInfoList does this for you).

Object oriented wrappers, like C++ and .NET, perform all reference operations for the client (they add ref in
c`tor, copy c`tor, or assignment operator, and release ref in d`tor).

@page conc_generation Data Generation

Production nodes that are also producing data are called Generators. To ease configuration of such nodes,
it was decided that those nodes do not actually produce any data until specifically asked to do so.
This allows the application to configure any property it needs before actually starting to stream
data. Starting generation is done using @ref xnStartGenerating() or @ref xn::Generator::StartGenerating().
The application may also want sometimes to stop the generation without actually destroying the node (for example,
if it does not need this data in current state, but does not want to loose configuration changes, or wants
to have the option to continue data streaming faster (instead of initializing it again). To do so,
the application may call @ref xnStopGenerating() or @ref xn::Generator::StopGenerating.

In addition, for easier access, OpenNI supplies two functions that control all generators in the context:
@ref xnStartGeneratingAll() (@ref xn::Context::StartGeneratingAll()) and @ref xnStopGeneratingAll() 
(@ref xn::Context::StopGeneratingAll()).

@page conc_read Reading Data

Generators usually constantly receive new data. However, the application might still use the old (previous) data.
For this reason, any generator should keep the new data internally until explicitly asked to update its data
to the new one. This request is called Update Data. OpenNI gives the application the option to wait for new
data to be available, and then update it using @ref xnWaitAndUpdateData() (@ref xn::Generator::WaitAndUpdateData()).

In some cases, the application holds more than one node, and it usually wants all the nodes to be updated.
OpenNI supplies several functions to do so, depending on what the application wants to wait for before
updating takes place:

- @ref xnWaitAnyUpdateAll() (@ref xn::Context::WaitAnyUpdateAll()) - Waits for any node to have new data. Once
		new data is available from any node, all nodes are updated.
- @ref xnWaitOneUpdateAll() (@ref xn::Context::WaitOneUpdateAll()) - Waits for a specific node to have new data. Once
		new data is available from this node, all nodes are updated. This is especially useful when having
		several nodes producing data, but only one determines the progress of the application.
- @ref xnWaitNoneUpdateAll() (@ref xn::Context::WaitNoneUpdateAll()) - Does not wait for anything. All nodes are updated.
- @ref xnWaitAndUpdateAll() (@ref xn::Context::WaitAndUpdateAll()) - Waits for all nodes to have new data available, and 
		then updates them.

Unless needing to update only a specific node, it is highly advised to use one of the @e UpdateAll functions.
In addition for updating all the nodes they have some more benefits:
- If nodes are dependend in one another, it promises the needed node will be updated before the needing node.
- If playing a recording, it reads data from the recording until the condition is met.
- If a recorder exists, it records the data from all nodes added to it (without the need to call @ref xnRecord()).

@page conc_meta_data Meta Data Objects

OpenNI meta data objects are a way to hold the entire set of properties of a specific data alongside with the
data itself (for example, storing the resolution of a depth map with the depth map). Each generator that produces
data has its own kind of meta data object. This object can later be passed to functions processing this data,
preventing the need of sending multiple arguments each time.

In addition, the meta data objects are used to freeze the configuration of a node at the time this data
arrived. Sometimes an application changes configuration of a node while reading data from it. In such a case,
and until new data arrives, the data received from this node was produced using a different configuration.
For example, lets say a Depth Generator was configured to produce QVGA depth maps, and the application
constantly reads data from it. At some point, the application changed the node output mode to VGA. Until the moment
a new frame arrives, calling @ref xn::DepthGenerator::GetDepthMap() would return a QVGA map, but calling @ref xn::DepthGenerator::GetMapOutputMode() would
return VGA resolution. This might cause errors (or even access violation) in the application.

To solve this, each node has a meta data object, keeping the properties of the data when it was read. So, in the above
case, by calling @ref xn::DepthGenerator::GetMetaData() you would get a xn::DepthMetaData object. This object @ref xn::DepthMetaData::Data "Data()" method
would return a pointer to the QVGA depth map, and @ref xn::DepthMetaData::XRes "XRes()" and @ref xn::DepthMetaData::YRes "YRes()" functions would return QVGA resolution.

<i>Meta Data</i> objects holds const pointers to the data (as this is what's returned from the generators). C++ <i>Meta Data</i>
objects (all objects inheriting from @ref xn::OutputMetaData) also provide a way to replace the data buffer with
a self-allocated buffer, which can also be written to. Use the @ref xn::OutputMetaData::AllocateData() "AllocateData()"
function for allocating a clean buffer, or the @ref xn::OutputMetaData::MakeDataWritable() "MakeDataWritable()"
function for also copying data from the const buffer into the newly allocated writable buffer.

Also, C++ <i>Meta Data</i> objects support several types of copying: 
- All <i>InitFrom</i> functions actually perform the shallow copy made by C functions (@ref xnCopyDepthMetaData() 
  for example).
- All <i>CopyFrom</i> functions allocates a new buffer and copies data to it (so that destination object now
  points to a private copy of the data of the source object).
.
Currently this creates a situation in which the functionality supplied by C and C++ interfaces is not the same. This
will be fixed in future versions.  


@page conc_locks Sharing Devices Between Applications and Locking Nodes

In most cases, the data provided by OpenNI nodes comes from some sort of hardware device. A hardware device
usually has only one configuration, and so if several applications are running at the same time, all using the
same hardware device, they must agree on the configuration they'll use.

However, most of the time, when writing an application, one cannot know which other applications might be executed
simultaneously with it, and so can not agree on such a configuration. Sometimes it is crucial for an application
to use a specific configuration, and it cannot handle other configurations.

OpenNI has two modes allowing multiple applications to share a hardware device:

- <b>Full Sharing</b> (default) - In this mode, an application declares that it can handle any configuration
  of this node. OpenNI interface allows registrating callback functions to any configuration change, so the 
  application can be notified whenever a configuration was changed (by the same application or by another application
  using the same hardware device).
  
- <b>Locking Configuration</b> - In this mode, an application explicitly declares it wants to lock the specific
  node in its current configuration. OpenNI then, does not allow calling any @a set functions to this node. If the
  node represents a hardware device (or anything else that might be shared between processes), it should implement
  the <b>Lock Aware</b> capability (@ref XN_CAPABILITY_LOCK_AWARE), which allows locking across process boundary.

Note that when a node is locked for changed, the locking application receives a lock handle. Aside from using
this handle for unlocking the node, the handle can be used to change the node configuration without releasing 
that lock (so that it won't be "stolen" by another application). OpenNI provides a mechanism for allowing 
configuration changes only from a specific call-context (meaning from a specific thread in a specific process).
see @ref xnLockedNodeStartChanges() for additional details.

@page conc_global_mirror Global Mirror

One of the capabilities defined is the @b Mirror capability. This capability allows mirroring of the output
data. This is useful when the sensor is placed in front of the user (for example, by the TV), and the user
sees itself from behind in the application.

In most cases, once a specific node is mirrored, the application would probably want all nodes to be mirrored.
OpenNI supplies a mechanism called Global Mirror, which, when turned on, changes the mirror state of every
node that supports this capability. It will also set the mirror state of new nodes, once created.

@page conc_error_state Global Error State

The <b>Error State</b> capability allow a node implementation to notify OpenNI about being in an error state, meaning
it cannot function properly. An application may check each node error state, but most of the times it only needs
to know if any node is in an error state, and does not really care which one (except for user notification purposes).

OpenNI aggregates the error state of all the nodes together into a single error state, making it easier for
application to find out about current state. A global error state of XN_STATUS_OK means all the nodes are OK.
If only one node is in an error state, that error state will also become the global error state (for example,
if one sensor is disconnected, OpenNI global error state will be XN_STATUS_DEVICE_NOT_CONNECTED). If more than
one node is in an error state, the global error state will be XN_STATUS_MULTIPLE_NODES_ERROR. In such a case, if
needed, the application may go over all nodes and check which one is in an error state and why.

@page conc_mocks Mock Nodes

OpenNI provides a "mock" implementation for nodes. A "mock" implementation does not have any logic of its own. Instead,
it lets an outside component to feed configuration changes and data into it. For example, mock nodes are used by
Player nodes to simulate actual nodes when reading data from a recording.

Mock nodes can also be used when wanting to record something other than actual nodes. An application may create a
mock node, copy into it the state of another node (initial configuration), and then read data from the original
node and write it to the mock node. Then, the mock node can be recorded. See @ref nirecordsynthetic for such a sample.

*/



/**
@page recordings Recordings

Recordings are a powerful debug tool. It allows full capturing of the data and then later streaming it back
so that application can simulate the exact same state they were in.

OpenNI supports recordings of the <i>Production Nodes</i> graph - both the entire configuration of each node, 
and a capturing of all the data that streamed from the node. 

OpenNI has a framework for recording data and for playing it back (using @ref conc_mocks). It also comes 
with the @e nimRecorder module, which defines a new file format - .ONI - and implements a Recorder node 
and a Player node for this format.

@section record_rec Recording

To record, an application should create a Recorder node, and set its destination (the file name to write to).
Then, it needs to add to it every node it wants to record.
When adding a node to the recorder, the recorder reads its configuration and records it. It also registers
to every possible event of the node, so that when any configuration change takes place, it will also be recorded.

Once all required nodes were added, the application can then read data from the nodes and record it. Recording of 
data can be acheived either by explicitly calling the @ref xnRecord() function, or by using one of the <i>UpdateAll</i>
functions (see @ref conc_read).

Applications that init OpenNI using an XML file can easily record their session without any change to the code.
They simply need to create an additional node in the XML file for the recorder, add nodes to it, and when the application
calls one of the <i>UpdateAll</i> functions, recording will take place.

@section record_play Playing

To play a file recording, use the @ref xnContextOpenFileRecording() function (@ref xn::Context::OpenFileRecording()). OpenNI
will open the file, create a mock node for each node in the file, and fill it with the recorded configuration.

Next, an application may take the nodes it needs by calling @ref xnFindExistingNodeByType(), and use them normally.
Note that <b>nodes created by the player are locked for changes</b>, as the configuration must remain the recorded
configuration.

Applications that init OpenNI using an XML file can easily replace their input so instead of reading from a
real-time device they would read from a recording by simply replacing the nodes in the xml with a <b>Recording</b>
element (see @ref xmlrec).

@section record_lim Limitations

In current version some limitations apply to recordings:

- Not all node types are supported for recording. Supported types are:
  - Device
  - Depth
  - Image
  - IR
  - Audio

- Opening more than one recording can cause undetermined behavior and is not supported.

- Opening a recording and a real-time sensor can cause undetermined behavior is not supported.

*/









/**
@page tutorials Getting Started - A Tutorial

This chapter is intended to provide a user with the first steps needed to write OpenNI applications.

- @subpage build_and_run_sample
- @subpage new_app
- @subpage error_codes
- @subpage basic
- @subpage tut_enum
- @subpage tut_enumeration_errors
- @subpage tut_config
- @subpage tut_xml
- @subpage tut_playing
- @subpage tut_recording
*/




/**
@page build_and_run_sample Building and running a sample application

This step is needed to ensure that OpenNI was installed properly, and that the development environment 
is properly set up to enable you to build OpenNI-based applications.

To build and run a sample application:
-# Make sure you have the latest Microsoft Platform SDK installed (You
		can currently download this via the following hyperlink: 
		<a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=a55b6b43-e24f-4ea3-a93e-40c0ec4f68e5&DisplayLang=en">Microsoft's
		Platform SDK Web Install</a>).
-# Open Windows Explorer (or your favorite file navigator), and browse to OpenNI installation directory 
		(default: C:\\Program Files\\OpenNI)
-# In OpenNI directory browse to: Samples\\NiSimpleViewer.
-# Open the suitable project file, NiSimpleViewer_2008.vcproj, and build the application. If the build
		fails, contact Prime Sense support.
-# After successfully building the project, before trying to run it, please ensure that the 
		SamplesConfig.xml file is correctly configured:
		-# Browse to the 'Data' directory (the default location of this directory is C:\\Program Files\\OpenNI\\Data).
		-# Open the SamplesConfig.xml for editing using a text editor (additional information can under @ref xmlscripts).

<table>
		<tr>
			<th>Note:</th>
		</tr>
		<tr>
			<td>
Throughout the sample applications tutorial you will encounter use of relative paths in the sample 
application source files. Note that when your application is executed from within a debugging environment 
such as Microsoft Visual Studio, paths which are not absolute may not be resolved relatively to the 
output executable.

Therefore, in order for the sample application to execute correctly in Debug mode, you should modify 
the Working Directory to be the sub-folder into which the executable is located.
You can also use Visual Studio's macro \$(TargetDir) instead of setting an actual path.

Note: Use "Project Properties"->"Debugging"->"Working Directory" to set the value.
			</td>
		</tr>
</table>
*/




/**
@page new_app Creating an empty project that uses OpenNI

This chapter describes how to set the environment for developing your own applications using OpenNI.

@section create_new_app To Create a simple project using OpenNI:
-#	Open a new project or an existing one with which you want to use OpenNI.
-#	In the Visual Studio menu, open the Project menu and choose Project properties.
-#	In the C/C++ section, under the General node, find the "Additional Include Directories" and add 
		"$(OPEN_NI_INCLUDE)". This is an environment variable pointing to where OpenNI include directory
		is located (the default location will be: C:\\Program files\\OpenNI\\Include).
-#	In the Linker section, under the General node, find the "Additional Library Directories" and add 
		"$(OPEN_NI_LIB)". This is an environment variable pointing to where OpenNI include directory
		is located (the default location will be: C:\\Program files\\OpenNI\\Lib).
-#	In the Linker section, under the Input node, find the "Additional Dependencies" and add OpenNI.lib
-#	If you wish to use an XML file to configure OpenNI, you can start from a basic one found under OpenNI
		Data folder (the default location will be: C:\\Program files\\OpenNI\\Data).
		For additional information about OpenNI xml scripts, see @ref xmlscripts.
-#	Make sure to add the Additional Include and Library directories to both your Release and Debug configurations.
-#	Your code files should include XnOpenNI.h if using the C interface, or XnCppWrapper.h if using the C++ interface.
*/





/**
@page error_codes Error codes

OpenNI errors mechanism is error codes. Every function that might fail has a return value of type @ref XnStatus.
A value of XN_STATUS_OK means the function has succeeded. Any other value means some kind of failure
has occurred.

For additional error information, one may use the function @ref xnGetStatusString(), which returns a human
readable description of the error, in English.

Some basic error codes can be found in file XnStatusCodes.h.

A normal usage of the error mechanism is checking if an error has occurred, and if so, print a message
and close the application:
@code
xn::Context context;
XnStatus nRetVal = context.Init();
if (nRetVal != XN_STATUS_OK)
{
	printf("Failed to initialize OpenNI: %s\n", xnGetStatusString(nRetVal));
	exit(-1);
}
@endcode
*/





/**
@page basic Basic Functions: initialize, create a node and read data

The following code illustrates the basic functionality of OpenNI. It initializes a @ref context object,
creates a single Depth node, and reads data from it.

@code
XnStatus nRetVal = XN_STATUS_OK;

xn::Context context;

// Initialize context object
nRetVal = context.Init();
// TODO: check error code

// Create a DepthGenerator node
xn::DepthGenerator depth;
nRetVal = depth.Create(context);
// TODO: check error code

// Make it start generating data
nRetVal = context.StartGeneratingAll();
// TODO: check error code

// Main loop
while (bShouldRun)
{
	// Wait for new data to be available
	nRetVal = context.WaitOneUpdateAll(depth);
	if (nRetVal != XN_STATUS_OK)
	{
		printf("Failed updating data: %s\n", xnGetStatusString(nRetVal));
		continue;
	}

	// Take current depth map
	const XnDepthPixel* pDepthMap = depth.GetDepthMap();

	// TODO: process depth map
}

// Clean-up
context.Shutdown();
@endcode
*/







/**
@page tut_enum Enumerating possible production chains

The following code shows how to fine control the enumeration process. It enumerates Production Chains
for producing User output, reducing the options using a basic query, and then chooses the first one
from all possibilities.
@code
// Build a query object
xn::Query query;
nRetVal = query.SetVendor("MyVendor");
// TODO: check error code

query.AddSupportedCapability(XN_CAPABILITY_SKELETON);
// TODO: check error code

// Enumerate
xn::NodeInfoList possibleChains;
nRetVal = context.EnumerateProductionTrees(XN_NODE_TYPE_USER, &query, possibleChains, NULL);
// TODO: check error code

// No errors so far. This means list has at least one item. Take the first one
xn::NodeInfo selected = *possibleChains.Begin();

// Create it
nRetVal = context.CreateProductionTree(selected);
// TODO: check error code

// Take the node
xn::UserGenerator userGen;
nRetVal = selected.GetInstance(userGen);
// TODO: check error code

// Now we can start to use it
@endcode
*/



/**
@page tut_enumeration_errors Understnading why enumeration failed

Sometimes an application enumerates for a specific node, and gets zero results. Aside for the obvious reason
where no module implementing this node type is installed, other reasons may occur - a module might be installed
but have no license, or a needed hardware device is currently disconnected.

OpenNI enables the application to get a full list of modules that failed to enumerate, and why each one failed.
It is done using the @ref xn::EnumerationErrors object.

The following code tries to create a Hands Generator node, and if enumeration failed, checks all errors:
@code
xn::EnumerationErrors errors;
xn::HandsGenerator handsGen;
nRetVal = context.CreateAnyProductionTree(XN_NODE_TYPE_HANDS, NULL, handsGen, &errors);
if (nRetVal == XN_STATUS_NO_NODE_PRESENT)
{
	// Iterate over enumeration errors, and print each one
	for (xn::EnumerationErrors::Iterator it = errors.Begin(); it != errors.End(); ++it)
	{
		XnChar strDesc[512];
		xnProductionNodeDescriptionToString(&it.Description(), strDesc, 512);
		printf("%s failed to enumerate: %s\n", xnGetStatusString(it.Error()));
	}
	return (nRetVal);
}
else if (nRetVal != XN_STATUS_OK)
{
	printf("Create failed: %s\n", xnGetStatusString(nRetVal));
	return (nRetVal);
}
@endcode
*/



/**
@page tut_config Configuring nodes

An application would usually want to fully configure a node before it starts streaming data. For that reason,
OpenNI defines a flow in which configuration can take place, and once all configuration is set, the node
@ref xn::Generator::StartGenerating() method can be called to make it start streaming the data.

The following code creates a depth generator, configures it to VGA resolution, 30 FPS, and then starts it:
@code
// Create a DepthGenerator node
xn::DepthGenerator depth;
nRetVal = depth.Create(context);
// TODO: check error code

XnMapOutputMode outputMode;
outputMode.nXRes = 640;
outputMode.nYRes = 480;
outputMode.nFPS = 30;
nRetVal = depth.SetMapOutputMode(outputMode);
// TODO: check error code

// We're done configuring it. Make it start generating data
nRetVal = context.StartGeneratingAll();
// TODO: check error code

// Main loop
while (bShouldRun)
{
	// Wait for new data to be available
	nRetVal = context.WaitOneUpdateAll(depth);
	if (nRetVal != XN_STATUS_OK)
	{
		printf("Failed updating data: %s\n", xnGetStatusString(nRetVal));
		continue;
	}

	// Take current depth map
	const XnDepthPixel* pDepthMap = depth.GetDepthMap();

	// TODO: process depth map
}
@endcode

*/



/**
@page tut_xml Configuring OpenNI using an XML file

The following code configures OpenNI using an XML file, and then makes sure the nodes it needs exist:
@code
// Initialize OpenNI context using an XML file
xn::Context context;
nRetVal = context.InitFromXmlFile(".\\Config.xml", NULL);
// TODO: check error code

// Look for the depth node
xn::DepthGenerator depth;
nRetVal = context.FindExistingNode(XN_NODE_TYPE_DEPTH, depth);
if (nRetVal != XN_STATUS_OK)
{
	printf("Can't run - no depth generator is present!\n");
	exit(-1);
}

// TODO: mainloop - process data
@endcode
*/




/**
@page tut_playing Playing a file recording

The following code opens a file recording and reads data from it:
@code
// Initialize OpenNI
xn::Context context;
nRetVal = context.Init();
// TODO: check error code

// Open file recording
nRetVal = context.OpenFileRecording(".\\MyRecording.oni");
// TODO: check error code

// Look for the depth node
xn::DepthGenerator depth;
nRetVal = context.FindExistingNode(XN_NODE_TYPE_DEPTH, depth);
if (nRetVal != XN_STATUS_OK)
{
	printf("Can't run - no depth generator is present in recording!\n");
	exit(-1);
}

// TODO: mainloop - process data
@endcode
*/



/**
@page tut_recording Recording data

When an application wants to record data, it needs to create a recorder node, add the nodes that it wishes to
record to it, and then continuously read data and record it.

The following code creates a depth node and an audio node, and then records their data to a file:
@code
// Initialize context
xn::Context context;
nRetVal = context.Init();
// TODO: check error code

// Create depth generator
xn::DepthGenerator depth;
nRetVal = depth.Create(context);
// TODO: check error code

// Create audio generator
xn::AudioGenerator audio;
nRetVal = audio.Create(context);
// TODO: check error code

// Create recorder
xn::Recorder recorder;
nRetVal = recorder.Create(context);
// TODO: check error code

// Add depth node to recording
nRetVal = recorder.AddNodeToRecording(depth);
// TODO: check error code

// Add audio node to recording
nRetVal = recorder.AddNodeToRecording(audio);
// TODO: check error code

// Start generating
nRetVal = context.StartGeneratingAll();
// TODO: check error code

// Now read data and record it
while (TRUE)
{
	nRetVal = context.WaitAnyUpdateAll();
	// TODO: check error code
	
	nRetVal = recorder.Record();
	// TODO: check error code
}
@endcode
*/







/**
@page ref_page API Reference

For a detailed reference of the API, please refer to:
- @ref cref for C reference.
- @ref cppref for C++ reference.
*/



/**
@defgroup cref C Reference

This chapter contains a full API reference of OpenNI for C.
*/




/**
@defgroup cppref C++ Reference

This chapter contains a full API reference of OpenNI for C++.
*/



/**
@page xmlscripts Xml Scripts

OpenNI supports using XML as a configuration script. One can use such a script for creating nodes
and configuring them, and for configuring the context itself (adding license keys, etc.).
an XML script can be executed by calling @ref xnContextRunXmlScript() (@ref xn::Context::RunXmlScript()) and 
passing it a string representation of the XML script, or by calling @ref xnContextRunXmlScriptFromFile() 
(@ref xn::Context::RunXmlScriptFromFile()) and passing it an XML file to load.

@section xmlstruct Structure

The XML must have one (and only) root node named OpenNI. Under this node there can be 3 optional sections:
@ref xmllics, @ref xmllog and @ref xmlnodes. 

@section xmllics Licenses

This section can provide additional license keys to be registered. The element name should be "Licenses",
and it should contain a list of elements, each named "License" with two string attributes: "vendor" and "key".
Each such element actually calls @ref xnAddLicense() (@ref xn::Context::AddLicense()).
For example:
@code
<Licenses>
	<License vendor="vendor1" key="key1"/>
	<License vendor="vendor2" key="key2"/>
</Licenses>
@endcode

@section xmllog Log

This section can configure OpenNI log system. The element name should be "Log". It can contain the following
optional attributes:
- writeToConsole - "true" or "false" (default). Determines if log is written to the application console.
- writeToFile - "true" or "false" (default). Determines if log is written to a file. This file is located under 
		a Log folder that is created under working directory.
- writeLineInfo - "true" (default) or "false". Determines if every log entry also contains the file name
		and line info from which it was written.

In addition, it can contain the following elements:
- LogLevel with the attribute value set to 0 (verbose), 1 (info), 2 (warnings) or 3 (errors, default). This
		determines the minimum log severity that is written.
- Masks with a list of Mask elements, each determines if a specific mask is on or off.
- Dumps with a list of Dump elements, each determines if a specific dump is on or off.

For example:
@code
<Log writeToConsole="false" writeToFile="false" writeLineInfo="true">
	<LogLevel value="3"/>
	<Masks>
		<Mask name="ALL" on="true" />
	</Masks>
	<Dumps>
		<Dump name="SensorTimestamps" on="false" />
	</Dumps>
</Log>
@endcode

@section xmlnodes Production Nodes

This section allows creation and configuration of nodes. The element name should be "ProductionNodes",
and it can have several children performing various tasks:

@subsection xmlglobmirror Global Mirror

The "ProductionNodes" element may contain an element called "GlobalMirror" which sets the global mirror (@ref xnSetGlobalMirror(), 
@ref xn::Context::SetGlobalMirror()), according to the "on" attribute ("true" or "false").
For example:
@code
<ProductionNodes>
	<GlobalMirror on="true" />
</ProductionNodes>
@endcode

@subsection xmlrec Recordings

The "ProductionNodes" element may contain an element called "Recording" telling it to open a recording.
For now, OpenNI supports file recordings using the "file" attribute:
@code
<Recording file="c:\myfile.oni" />
@endcode

You can also set the playback speed using the "playbackSpeed" attribute if you wish to fast forward, or to slow
down the playback. Note that the special value 0.0 can be used to cause playing to be as fast as possible (no delay
between frames).
For example, to open a file and play it as twice as fast:
@code
<Recording file="c:\myfile.oni" playbackSpeed="2.0"/>
@endcode

@subsection xmlnode Nodes

The "ProductionNodes" element may contain one or more elements named "Node". Each such element asks OpenNI
to enumerate and create a node (similar to @ref xnCreateAnyProductionTree()). 
The "Node" element should have a string attribute named "type" which will have the type of the node to enumerate. 
The type can be one of the following:
- Device (@ref XN_NODE_TYPE_DEVICE)
- Depth (@ref XN_NODE_TYPE_DEPTH)
- Image (@ref XN_NODE_TYPE_IMAGE)
- IR (@ref XN_NODE_TYPE_IR)
- Audio (@ref XN_NODE_TYPE_AUDIO)
- Gesture (@ref XN_NODE_TYPE_GESTURE)
- User (@ref XN_NODE_TYPE_USER)
- Scene (@ref XN_NODE_TYPE_SCENE)
- Hands (@ref XN_NODE_TYPE_HANDS)
- Recorder (@ref XN_NODE_TYPE_RECORDER)

In addition the "Node" element can optionally have a "name" string attribute which will hold the requested
name of the created node.

@subsection xmlrecorder Recorder

The "ProductionNodes" element may contain an element called "Recorder" telling it to record data from other
nodes that were created in the xml script. Note that these nodes must be named explicitly.

For example, if two nodes were defined, named Image1 and Depth1, and we'd like to record their data into a 
file called MyFile.oni:

@code
    <Node type="Recorder">
      <Configuration>
        <RecorderDestination name="MyFile.oni"/>
        <AddNodeToRecording name="Image1" codec="JPEG"/>
        <AddNodeToRecording name="Depth1" codec="16zT"/>
      </Configuration>
    </Node>
@endcode

@subsubsection xmlquery Queries

The "Node" element can also declare a query that will be used when enumerating for this node. It is done
by adding a "Query" element to the "Node" element, which can have the following children:
- @b "Vendor", specifying the requested node vendor.
- @b "Name", specifying the requested node name.
- @b "MinVersion", specifying the requested node minimum version.
- @b "MaxVersion", specifying the requested node maximum version.
- @b "Capabilities", specifying a list of capabilities the node must support, each under a "Capability" sub-element.
- @b "MapOutputModes", specifying a list of map output mode that should be supported by the map generator, each
		under a "MapOutputMode" object, containing three attributes: "xRes", "yRes" and "fps".
- @b "MinUserPositions", specifying the minimum number of user positions supported by a depth generator that
		has the "UserPosition" capability.
- @b "ExistingNodeOnly", specifying that only existing nodes (e.g. nodes that were already created) will enumerate.
- @b "NonExistingNodeOnly", specifying that only non-existing nodes (e.g. nodes that were not created yet) will enumerate.
- @b "NeededNodes", specifying only production trees that contains specific nodes are valid. Those nodes are declared
		using a sub-element named "Node".

If more than one such element is present, all conditions are checked using the "AND" operator.

For example, the following will try to create a depth node, supplied by vendor1, named name1, from version
1.0.0.0 to 3.1.0.5, supporting the "UserPosition" and "Mirror" capabilities, supporting a VGA, 30 FPS output
mode, supporting at least 2 user positions, and one that uses the "MyDevice" node.
@code
<Node type="Depth" name="MyDepth">
	<Query>
		<Vendor>vendor1</Vendor>
		<Name>name1</Name>
		<MinVersion>1.0.0.0</MinVersion>
		<MaxVersion>3.1.0.5</MaxVersion>
		<Capabilities>
			<Capability>UserPosition</Capability>
			<Capability>Mirror</Capability>
		</Capabilities>
		<MapOutputModes>
			<MapOutputMode xRes="640" yRes="480" FPS="30"/>
		</MapOutputModes>
		<MinUserPositions>2</MinUserPositions>
		<NeededNodes>
			<Node>MyDevice</Node>
		</NeededNodes>
	</Query>
</Node>
@endcode

@subsubsection xmlconfig Configuration

Each "Node" element can also contain a list of configuration changes to be performed. This list
should be placed under a "Configuration" element. The sub-elements of the "Configuration" element
will be executed serially. Those commands can be:
- @b "Mirror", with an attribute "on" set to "true" or "false". Executes @ref xnSetMirror() (@ref xn::MirrorCapability::SetMirror()).
		Only relevant to generators supporting the "Mirror" capability.
- @b "MapOutputMode", with 3 attributes: "xRes", "yRes" and "fps". Executes @ref xnSetMapOutputMode() (@ref xn::MapGenerator::SetMapOutputMode()). 
		Only relevant to map generators (depth, image, IR and scene).
- @b "WaveOutputMode", with 3 attributes: "sampleRate", "bitsPerSample" and "channels". Executes @ref xnSetWaveOutputMode() (@ref xn::AudioGenerator::SetWaveOutputMode()).
		Only relevant to audio generators.
- @b "Cropping", with 5 attributes: "enabled", "xOffset", "yOffset", "xSize", "ySize". Executes
		@ref xnSetCropping() (@ref xn::CroppingCapability::SetCropping()). Only relevant to map generators (depth, image, IR and scene),
		which support the "Cropping" capability.
- @b "PixelFormat". Can have the one of the values: "RGB24", "YUV422", "Grayscale8" or "Grayscale16".
		Executes @ref xnSetPixelFormat() (@ref xn::ImageGenerator::SetPixelFormat()). Only relevant to image generators.
- @b "UserPosition", which has the attribute "index" and two sub-elements: "Min" and "Max", each has 3 attributes:
		"x", "y" and "z". Executes @ref xnSetUserPosition() (@ref xn::UserPositionCapability::SetUserPosition()).
		Only relevant to depth generators supporting the "UserPosition" capability.
- @b "FrameSync", which contains the name of the node to frame sync with. Executes @ref xnFrameSyncWith() (@ref xn::FrameSyncCapability::FrameSyncWith()).
		Only relevant to generators that support the "FrameSync" capability.
- @b "AlternativeViewPoint", which contains the name of the node to set view point to. Executes @ref xnSetViewPoint() (@ref xn::AlternativeViewPointCapability::SetViewPoint()).
		Only relevant to generators that support the "AlternativeViewPoint" capability.
- @b "RecorderDestination", which contains two attributes: "medium" (currently, only "File" is supported), and "name",
		which should hold the file name. Executes @ref xnSetRecorderDestination() (@ref xn::Recorder::SetDestination()).
		Only relevant to recorder nodes.
- @b "AddNodeToRecording", which contains two attributes: "name" and "codec". Executes @ref xnAddNodeToRecording() (@ref xn::Recorder::AddNodeToRecording()).
		Only relevant to recorder nodes.
- @b "Property", which contains 3 attributes: "type", "name" and "value". Type can be "int", "real", or "string",
		which executes @ref xnSetIntProperty() (@ref xn::ProductionNode::SetIntProperty()), @ref xnSetRealProperty() 
		(@ref xn::ProductionNode::SetRealProperty()) or @ref xnSetStringProperty() (@ref xn::ProductionNode::SetStringProperty()).

In addition, the application can request to lock this node for changes (preventing any configuration
change to this node once configuration is done) by using the "lock" attribute, and setting it to "true"
or "false" (default). This calls @ref xnLockNodeForChanges() (@ref xn::ProductionNode::LockForChanges()).

The following example create 3 nodes of types image, depth and audio. The image node to
use QVGA output on 60 FPS with RGB24 pixel format. It also sets a cropping area, and turning on mirror.
The Depth node is configured to VGA output on 30 FPS. It also sets the position of the user to a bounding
box located between (128, 128, 500) and (600, 400, 2000). The depth node also configures a special property,
proprietary to vendor "VendorX".
The audio is configured to be sampled at 44100 Hz, in stereo mode and 16-bit per sample.
Enumeration takes place only for nodes that support those configurations.
@code
<ProductionNodes>
	<Node type="Image">
		<Query>
			<MapOutputModes>
				<MapOutputMode xRes="320" yRes="240" FPS="60"/>
			</MapOutputModes>
			<Capabilities>
				<Capability>Cropping</Capability>
				<Capability>Mirror</Capability>
			</Capabilities>
		</Query>
		<Configuration>
			<MapOutputMode xRes="320" yRes="240" FPS="60"/>
			<PixelFormat>RGB24</PixelFormat>
			<Cropping enabled="true" xOffset="28" yOffset="28" xSize="200" ySize="160" />
			<Mirror on="true" />
		</Configuration>
	</Node>
	<Node type="Depth">
		<Query>
			<Vendor>VendorX</Vendor>
			<MapOutputModes>
				<MapOutputMode xRes="640" yRes="480" FPS="30"/>
			</MapOutputModes>
			<Capabilities>
				<Capability>UserPosition</Capability>
			</Capabilities>
		</Query>
		<Configuration>
			<MapOutputMode xRes="640" yRes="480" FPS="30"/>
			<UserPosition index="0">
				<Min x="128" y="128" z="500"/>
				<Max x="600" y="400" z="2000"/>
			</UserPosition>
			<Property type="int" name="VendorXDummyProp" value="3" />
		</Configuration>
	</Node>
	<Node type="Audio">
		<Configuration>
			<WaveOutputMode sampleRate="44100" bitsPerSample="16" channels="2" />
		</Configuration>
	</Node>
</ProductionNodes>
@endcode

@subsubsection xmlstartgen Start Generating

By default, when all nodes under the "ProductionNodes" element are created and configured, a call is
made to @ref xnStartGeneratingAll() (@ref xn::Context::StartGeneratingAll()). If the application
wants another behavior, it can place the "startGenerating" attribute containing "true" or "false",
on any node, and also on the "ProductionNodes" element (which defines whether or not to start generate all).
For example, the following will create two nodes: image and depth, but only start generate the depth one:
@code
<ProductionNodes startGenerating="false">
	<Node type="Image" />
	<Node type="Depth" startGenerating="true" />
</ProductionNodes>
@endcode

*/








/**
@page cmdutils Command-Line Utilities

OpenNI arrives with the following command-line utilities:
- @subpage nireg
- @subpage nilicense
*/







/**
@page nireg niReg

niReg allows registration and deregistration of modules from OpenNI. Registered modules participate in
the enumeration process.
This utility is commonly used by modules installations.

@section nireg_usage Usage

@code
niReg [options] <module_path> [config_dir]
@endcode

The following options can be used:
- @b -r	Registers a module to OpenNI.
- @b -u	Unregisters a module from OpenNI.

If no option is supplied, @c -r is assumed.

When registering a module, an optional configuration directory can be passed. This directory will be passed
to the module when loaded from OpenNI, allowing it to have custom configuration files.
*/








/**
@page nilicense niLicense

niLicense allows adding or removing licenses from the global license registry.
This utility is commonly used by modules installations.

@section nireg_usage Usage

@code
niLicense [options] <vendor> <key>
@endcode

The following options can be used:
- @b -r	Registers a license to the global registry.
- @b -u	Unregisters a module from the global registry.

If no option is supplied, @c -r is assumed.
*/





/**
@page samples Samples

OpenNI delivers with some samples. All samples are placed under the 'Samples' folder, and their binaries
can be found under 'Samples\\Bin\\Debug' or 'Samples\\Bin\\Release'.
Most samples use an XML file to configure OpenNI. This file can be found at '\%OPEN_NI_INSTALL_DIR\%\\Data\\SamplesConfig.xml'.
All samples, except for @ref nicread, are written using the C++ interface.

Here is a short description of each sample:

@section nisimpleread NiSimpleRead

NiSimpleRead is very basic. It configures OpenNI using the SamplesConfig XML file, and then takes the depth
generator node (it assumes there is one. If not, the sample will exit with an error).
It then loops, reading new frames from the depth generator, and prints out the depth value of the middle pixel.
The sample exists when the user presses 'ESC'.

@section nisimplecreate NiSimpleCreate

NiSimpleCreate is an example of creating a production node programmatically in code, rather than using the 
SamplesConfig XML file. After creating a depth node, it reads from it like NiSimpleRead does.

@section nicread NiCRead

NiCRead sample is exactly the same as @ref nisimpleread, except for the fact it demonstrates the use of the
C interface (instead of the C++ one).

@section nisimpleviewer NiSimpleViewer

NiSimpleViewer is a small OpenGL application which draws the depth maps and the image maps to the screen.
It configures OpenNI using the SamplesConfig XML, but requires both depth and image to be present, both with
the same resolution, and image node at RGB24 format.
The application creates a histogram of the depth map and draws the frame using it to allow better visibility
of the depth map.

The following keys can be used to control the application:
<table>
		<tr>
			<th>Key</th>	<th>Description</th>
		</tr>
		<tr>
			<td>1</td>
			<td>
				Converts to OVERLAY mode, drawing depth map on top of the image map. It also sets depth view point
				to image view point (using the Alternative view point capability).
			</td>
		</tr>
		<tr>
			<td>2</td>
			<td>Draws only depth. It also turns off alternative view point.</td>
		</tr>
		<tr>
			<td>3</td>
			<td>Draws only image. It also turns off alternative view point.</td>
		</tr>
		<tr>
			<td>Esc</td>
			<td>Closes the application</td>
		</tr>
</table>

@section nisamplemodule NiSampleModule

NiSampleModule is a sample for writing a module for OpenNI. It implements a depth node supporting the 
Mirror capability.
Before using it, one should register this module using the @ref nireg utility. It should also be deregistered
afterwards, or applications might get it when needing depth nodes.

@section niconvertxtooni NiConvertXToONI

NiConvertXToONI opens any recording, takes every node in this recording, and records it to a new ONI recording.
It receives both input file and output file from the command line.

@section nirecordsynthetic NiRecordSynthetic

NiRecordSynthetic shows how to open a recording, perform some sort of transformation on the data in it,
and re-record this data.

@section niviewer NiViewer

NiViewer aspires to be able to view any kind of data defined by OpenNI, and be able to configure any kind
of configuration OpenNI defines. Currently, is supports a reduced set. It can now display depth, image and IR
maps, play audio, and supplies a wide set of configuration (though not complete).
NiViewer has two modes: If passed a file name in command-line, it will open this file as a recording. Otherwise,
it will configure OpenNI using the SamplesConfig XML file.

NiViewer is automatically associated with the .ONI file extension, for opening OpenNI recordings.
The following keys can be used to control the application:
<table>
		<tr>
			<th>Key</th>	<th>Description</th>
		</tr>
		<tr>
			<td>1</td>
			<td>Showing depth only, in histogram mode</td>
		</tr>
		<tr>
			<td>2</td>
			<td>Showing depth only, in psychedelic mode (centimeters)</td>
		</tr>
		<tr>
			<td>3</td>
			<td>Showing depth only, in psychedelic mode (millimeters)</td>
		</tr>
		<tr>
			<td>4</td>
			<td>Showing depth only, in rainbow mode</td>
		</tr>
		<tr>
			<td>5</td>
			<td>Showing depth masked image, meaning image pixels that don't have depth values are blacked out.</td>
		</tr>
		<tr>
			<td>6</td>
			<td>Background removal mode</td>
		</tr>
		<tr>
			<td>7</td>
			<td>Showing depth and image (or IR), side by side.</td>
		</tr>
		<tr>
			<td>8</td>
			<td>Showing depth on top of image (or IR)</td>
		</tr>
		<tr>
			<td>9</td>
			<td>Showing transparent depth on top of image (or IR)</td>
		</tr>
		<tr>
			<td>0</td>
			<td>Showing rainbow depth on top of image (or IR)</td>
		</tr>
		<tr>
			<td>=</td>
			<td>Showing image (or IR) only</td>
		</tr>
		<tr>
			<td>`</td>
			<td>Showing depth standard deviation</td>
		</tr>
		<tr>
			<td>p</td>
			<td>Toggling pointer mode on/off. When on, additional depth info is displayed regarding currently pointed pixel.</td>
		</tr>
		<tr>
			<td>f</td>
			<td>Toggling Full Screen / Window mode</td>
		</tr>
		<tr>
			<td>?</td>
			<td>Toggling help screen on/off</td>
		</tr>
		<tr>
			<td>m</td>
			<td>Toggling mirror on/off</td>
		</tr>
		<tr>
			<td>/</td>
			<td>Resets all croppings</td>
		</tr>
		<tr>
			<td>s</td>
			<td>Start recording</td>
		</tr>
		<tr>
			<td>d</td>
			<td>Start recording in 5 seconds</td>
		</tr>
		<tr>
			<td>x</td>
			<td>Stop recording</td>
		</tr>
		<tr>
			<td>c</td>
			<td>Capture current frame to files</td>
		</tr>
		<tr>
			<td>z</td>
			<td>Start/Stop collecting statistics about depth pixels</td>
		</tr>
		<tr>
			<td>o</td>
			<td>Pause/Play</td>
		</tr>
		<tr>
			<td>l</td>
			<td>Seek one frame forward (recordings only)</td>
		</tr>
		<tr>
			<td>L</td>
			<td>Seek 10 frames forward (recordings only)</td>
		</tr>
		<tr>
			<td>k</td>
			<td>Seek one frame backwards (recordings only)</td>
		</tr>
		<tr>
			<td>K</td>
			<td>Seek 10 frames backwards (recordings only)</td>
		</tr>
		<tr>
			<td>;</td>
			<td>Read one single frame and pause</td>
		</tr>
		<tr>
			<td>Esc</td>
			<td>Closes the application</td>
		</tr>
</table>

In addition, the mouse can be used. Clicking the right-button of the mouse opens up a menu through which many configurations can be changed.
Block selecting using the left button (holding it down in one point, moving and releasing the key) over
a frame causes cropping of the node, if the Cropping capability is supported.

@section nibackrecorder NiBackRecorder

niBackRecorder is a command line tool, which stores frames in memory in a cyclic buffer,
and when requested (clicking 'd') dumps that cyclic buffer to an oni file.
In effect, it saves the last x seconds (configurable).

@subsection nibackrecorder_usage Usage

@code
niBackRecorder time <seconds> [depth [qvga|vga]] [image [qvga|vga]] [verbose] [mirror <on|off>] [registration] [framesync] [outdir <directory>]
@endcode

The following options are mandatory:
- @b time	Number of seconds to dump each time. 

The following options can be used:
- @b depth	Sets the resolution of the depth, to either QVGA or VGA. If not mentioned, depth is off. If no resolution is mentioned, QVGA is used.
- @b image	Sets the resolution of the image, to either QVGA or VGA. If not mentioned, image is off. If no resolution is mentioned, QVGA is used.
- @b verbose	Turns on the log
- @b mirror	Set the mirror mode. If not mentioned, uses whatever was configured. 
- @b registration	Change depth to match image.
- @b framesync	Syncronize between depth and image
- @b outdir	Where to create the oni files. Default is the execution directory.

Note: Keep in mind the memory used to store the frames.
<table>
 <tr>
  <th>Configuration</th>
  <th>Size</th>
 </tr>
 <tr>
  <td>1 second, QVGA depth</td>
  <td>30*320*240*2B = 4500KB</td>
 </tr>
 <tr>
  <td>1 second, QVGA image</td>
  <td>30*320*240*3B = 6750KB</td>
 </tr>
 <tr>
  <td>1 second, VGA depth</td>
  <td>30*640*480*2B = 18000KB</td>
 </tr>
 <tr>
  <td>1 second, VGA image</td>
  <td>30*640*480*3B = 27000KB</td>
 </tr>
</table>

*/




/**
@page additional Additional Utilities

OpenNI has a framework, allowing:
- Portability over various architectures and operating systems.
- A USB access abstraction layer (provided with a driver for Microsoft Windows)
- Some basic data types (like list, hash, etc.)
- Log and Dumps system
- Memory and Performance profiling
- Events (allowing callbacks to be registered to a specific event)
- Scheduling of tasks

Those utilities are also available to any application using OpenNI. OpenNI guarentees backwards compatibility
for this framework (up to a certain extent, as opposed to OpenNI actual API, which guarentees full backwards
compatibility).
*/



/**
@page legal Legal Stuff

"This software is based in part on the work of the Independent JPEG Group"
*/