Skip to content
Arthur Nishimoto edited this page Jun 9, 2017 · 5 revisions

Last revision: ver. 2.0 - 9 June 2017

if you want to use omicron-supported input devices in the easiest way possible, the following is the best solution:

  • You run the omicron input server executable (oinputserver) locally or on the machine where the input devices are physically attached
  • you add the omicronConnector header file to your c++ application ...and that's pretty much it. You won't need to add any dependencies to your original project, other than one single header file. This is by far the easiest solution, although it requires you to run the input server as a separate application you connect to.
  • this code is also available when building the omicron source code through CMake by enabling OMICRON_BUILD_EXAMPLES.

The following is an example of code using omicronConnector:

	#include <connector/omicronConnectorClient.h>

	using namespace omicronConnector;

	class ConnectorListener: public IOmicronConnectorClientListener
	{
	public:
		virtual void onEvent(const EventData& e)
		{ printf("event received\n"); }
	};

	int main(int argc, char** argv)
	{
		ConnectorListener listener;
		OmicronConnectorClient client(&listener);
		client.connect("127.0.0.1", 27000);
		while(true)
		{
			client.poll(); 
		}
	}

All you need to do is instantiate a copy of the OmicronConnectorClient class, passing it an object implementing the IOmicronConnectorClientListener interface. After connecting and running a polling loop, the onEvent method will be called for each event received from the input server.

Adding omicron to your application: direct integration

In this scenario, you want to integrate omicron directly inside your application, without running an external input server. This is a slightly more complex but supported alternative to using omicronConnector. We assume you use CMake to manager your application build. In the explanation, we assume omicronSource is the root directory of your omicron source installation.

Step 1: Create the directory structure

  • Create a new directory (say, myapp-source).
  • copy omicronSource/CMakeModules/FindOmicron.cmake to myapp-source

Step 2: Create the source and cmake file

In a new directory, create a source file (say, myapp.cpp). Also create a CMakeLists.txt file in the same directory, with the following content:

	cmake_minimum_required(VERSION 2.8.1) 
	project(myapp)

	include(${CMAKE_SOURCE_DIR}/FindOmicron.cmake)

	include_directories(${OMICRON_INCLUDE_DIRS})
	add_executable(myapp myapp.cpp)
	target_link_libraries(myapp ${OMICRON_LIB})

You should now be able to run cmake to configure and generate build files for your platform.

The contents of your source file could be something like this:

#include <connector/omicronConnectorClient.h>

using namespace omicronConnector;

///////////////////////////////////////////////////////////////////////////////////////////////////
class ConnectorListener : public IOmicronConnectorClientListener
{
public:
	virtual void onEvent(const EventData& e)
	{
		if (e.type == EventData::Update)
		{
			if (e.serviceType == EventData::ServiceTypeMocap)  // Mocap (head I guess
				fprintf(stderr, "MOCAP source %d type %d device %d type %d\n",
					e.sourceId, e.type, e.deviceTag);
			if (e.serviceType == EventData::ServiceTypeWand)  // Wand
				fprintf(stderr, "Wand source %d type %d device %d type %d\n",
					e.sourceId, e.type, e.deviceTag);
			fprintf(stderr, "      pos(%6.3f  %6.3f  %6.3f)\n", e.posx, e.posy, e.posz);
			fprintf(stderr, "      rot(%6.3f  %6.3f  %6.3f  %6.3f)\n", e.orx, e.ory, e.orz, e.orw);
			fprintf(stderr, "      flag: %d\n", e.flags);
			fprintf(stderr, "      extra type: %d\n", e.extraDataType);
			fprintf(stderr, "      extra items: %d\n", e.extraDataItems);
			fprintf(stderr, "      extra mask: %d\n", e.extraDataMask);
			if (e.extraDataItems) {
				if (e.extraDataType == EventData::ExtraDataFloatArray)
				{ //array of floats
					float *ptr = (float*)(e.extraData);
					for (int k = 0;k<e.extraDataItems;k++)
					{
						fprintf(stderr, "      val %2d: [%6.3f]\n", k, ptr[k]);
					}
				}
				else if (e.extraDataType == EventData::ExtraDataVector3Array)
				{ //array of floats
					float val[3];
					//float *ptr = (float*)(e.extraData);
					for (int k = 0; k < e.extraDataItems; k++)
					{
						e.getExtraDataVector3(k, val);
						fprintf(stderr, "      val %2d: [%6.3f, %6.3f, %6.3f]\n", k, val[0], val[1], val[2]);
					}
				}
			}
			fprintf(stderr, "-----------\n");
		}
		else if (e.type == EventData::Down) {
			//fprintf(stderr, "EVENT down: %d\n", mButton(e.flags));
		}
		else if (e.type == EventData::Up)
		{
			fprintf(stderr, "EVENT up: %d\n", e.sourceId, e.type);
			fprintf(stderr, "      flag: %d\n", e.flags);
			fprintf(stderr, "      extra: %d\n", e.extraDataType);
			fprintf(stderr, "      items: %d\n", e.extraDataItems);
			fprintf(stderr, "      mask: %d\n", e.extraDataMask);
			fprintf(stderr, "-----------\n");
		}
	}
};

///////////////////////////////////////////////////////////////////////////////////////////////////
int main(int argc, char** argv)
{
	ConnectorListener listener;
	OmicronConnectorClient client(&listener);
	client.connect("127.0.0.1", 27000);

	while (true)
	{
		client.poll();
	}
}

The code is slightly more complex than the omicronConnector example, but not that much. The main difference would be the need to add the input service libraries inside your application binary folder. Also, some input services only run on windows: check the input service reference page for more information.

Clone this wiki locally