This commit is contained in:
2021-10-14 13:47:35 +02:00
commit 6625a8dfaa
4026 changed files with 844291 additions and 0 deletions
@@ -0,0 +1,42 @@
PROJECT(openvibe-examples-vrpn-to-openvibe)
SET(PROJECT_VERSION_MAJOR ${OV_GLOBAL_VERSION_MAJOR})
SET(PROJECT_VERSION ${OV_GLOBAL_VERSION_STRING})
INCLUDE("FindThirdPartyVRPN_Check")
IF(NOT PATH_VRPN)
MESSAGE(STATUS " --> Not building ${PROJECT_NAME}")
RETURN()
ENDIF(NOT PATH_VRPN)
FILE(GLOB_RECURSE SRC_FILES src/*.cpp src/*.h src/*.hpp src/*.inl include/*.h)
INCLUDE_DIRECTORIES(include)
ADD_EXECUTABLE(${PROJECT_NAME} ${SRC_FILES})
SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY FOLDER ${APP_FOLDER})
INCLUDE("FindThirdPartyVRPN")
INCLUDE("FindThirdPartyPThread") # needed on Linux for VRPN
# ---------------------------------
# ---------------------------------
# ----------------------
# Generate launch script
# ----------------------
OV_INSTALL_LAUNCH_SCRIPT(SCRIPT_PREFIX "${PROJECT_NAME}" EXECUTABLE_NAME "${PROJECT_NAME}")
# -----------------------------
# Install files
# -----------------------------
INSTALL(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION ${DIST_BINDIR}
LIBRARY DESTINATION ${DIST_LIBDIR}
ARCHIVE DESTINATION ${DIST_LIBDIR})
INSTALL(DIRECTORY box-tutorials/ DESTINATION ${DIST_DATADIR}/openvibe/scenarios/box-tutorials)
@@ -0,0 +1,385 @@
<OpenViBE-Scenario>
<FormatVersion>1</FormatVersion>
<Creator>openvibe</Creator>
<CreatorVersion>2.0</CreatorVersion>
<Boxes>
<Box>
<Identifier>(0x00000f15, 0x00007fd2)</Identifier>
<Name>Button VRPN Client</Name>
<AlgorithmClassIdentifier>(0x40714327, 0x458877d2)</AlgorithmClassIdentifier>
<Outputs>
<Output>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Output</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>Peripheral name</Name>
<DefaultValue>openvibe-vrpn@localhost</DefaultValue>
<Value>button_test@localhost:50555</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2c132d6e, 0x44ab0d97)</TypeIdentifier>
<Name>Button 1 ON</Name>
<DefaultValue>OVTK_GDF_Feedback_Continuous</DefaultValue>
<Value>OVTK_StimulationId_Label_00</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2c132d6e, 0x44ab0d97)</TypeIdentifier>
<Name>Button 1 OFF</Name>
<DefaultValue>OVTK_GDF_End_Of_Trial</DefaultValue>
<Value>OVTK_StimulationId_Label_01</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x17ee7c08, 0x94c14893)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>208</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>38</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>400</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x09fd9ef3, 0xeb8c3069)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>152</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>3</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x0000142f, 0x00005e51)</Identifier>
<Name>Analog VRPN Client</Name>
<AlgorithmClassIdentifier>(0x7cf4a95e, 0x7270d07b)</AlgorithmClassIdentifier>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Output</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>Peripheral name</Name>
<DefaultValue>openvibe-vrpn@localhost</DefaultValue>
<Value>analog_test@localhost:50555</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Sampling Rate</Name>
<DefaultValue>512</DefaultValue>
<Value>100</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Number of Channels</Name>
<DefaultValue>16</DefaultValue>
<Value>2</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Sample Count per Sent Block</Name>
<DefaultValue>32</DefaultValue>
<Value>1</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>208</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>25</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>240</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x8888a3e2, 0xedc76707)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>154</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>4</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x0000322d, 0x00004eed)</Identifier>
<Name>Signal display</Name>
<AlgorithmClassIdentifier>(0x0055be5f, 0x087bdd12)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Data</Name>
</Input>
<Input>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Stimulations</Name>
</Input>
<Input>
<TypeIdentifier>(0x6ab26b81, 0x0f8c02f3)</TypeIdentifier>
<Name>Channel Units</Name>
</Input>
</Inputs>
<Settings>
<Setting>
<TypeIdentifier>(0x5de046a6, 0x086340aa)</TypeIdentifier>
<Name>Display Mode</Name>
<DefaultValue>Scan</DefaultValue>
<Value>Scan</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x33a30739, 0x00d5299b)</TypeIdentifier>
<Name>Auto vertical scale</Name>
<DefaultValue>Per channel</DefaultValue>
<Value>Per channel</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Scale refresh interval (secs)</Name>
<DefaultValue>5</DefaultValue>
<Value>5</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Vertical Scale</Name>
<DefaultValue>100</DefaultValue>
<Value>100</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Vertical Offset</Name>
<DefaultValue>0</DefaultValue>
<Value>0</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Time Scale</Name>
<DefaultValue>10</DefaultValue>
<Value>10</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Horizontal ruler</Name>
<DefaultValue>true</DefaultValue>
<Value>true</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Vertical ruler</Name>
<DefaultValue>false</DefaultValue>
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Multiview</Name>
<DefaultValue>false</DefaultValue>
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>352.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>38</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>304.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x92c056a7, 0x2dc71aff)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>113</Value>
</Attribute>
<Attribute>
<Identifier>(0xc67a01dc, 0x28ce06c1)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>9</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>3</Value>
</Attribute>
</Attributes>
</Box>
</Boxes>
<Links>
<Link>
<Identifier>(0x00001f38, 0x00000a57)</Identifier>
<Source>
<BoxIdentifier>(0x00000f15, 0x00007fd2)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x0000322d, 0x00004eed)</BoxIdentifier>
<BoxInputIndex>1</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>233</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>400</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>328</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>304</Value>
</Attribute>
</Attributes>
</Link>
<Link>
<Identifier>(0x00003ce7, 0x00000907)</Identifier>
<Source>
<BoxIdentifier>(0x0000142f, 0x00005e51)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x0000322d, 0x00004eed)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>227</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>240</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>328</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>289</Value>
</Attribute>
</Attributes>
</Link>
</Links>
<Comments>
<Comment>
<Identifier>(0x0000796e, 0x00004e00)</Identifier>
<Text>This scenario is described in
http://openvibe.inria.fr/vrpn-tutorial-sending-data-from-an-external-application-to-openvibe/
Its used together with &lt;b&gt;openvibe-examples-vrpn-to-openvibe&lt;/b&gt; application.</Text>
<Attributes>
<Attribute>
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
<Value>336</Value>
</Attribute>
<Attribute>
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
<Value>32</Value>
</Attribute>
</Attributes>
</Comment>
</Comments>
<Metadata>
<Entry>
<Identifier>(0x0000775c, 0x000078ff)</Identifier>
<Type>(0x3bcce5d2, 0x43f2d968)</Type>
<Data>[{"boxIdentifier":"(0x0000322d, 0x00004eed)","childCount":0,"identifier":"(0x0000007b, 0x0000045c)","index":0,"parentIdentifier":"(0xffffffff, 0xffffffff)","type":3},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"height":320,"identifier":"(0x00007e32, 0x0000369d)","index":0,"name":"Default window","parentIdentifier":"(0xffffffff, 0xffffffff)","type":1,"width":480},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"identifier":"(0x00004cc4, 0x00004f75)","index":0,"name":"Default tab","parentIdentifier":"(0x00007e32, 0x0000369d)","type":2},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":0,"identifier":"(0x00000f17, 0x00002485)","index":0,"name":"Empty","parentIdentifier":"(0x00004cc4, 0x00004f75)","type":0}]</Data>
</Entry>
</Metadata>
<Attributes>
<Attribute>
<Identifier>(0x790d75b8, 0x3bb90c33)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x8c1fc55b, 0x7b433dc2)</Identifier>
<Value>1.0</Value>
</Attribute>
<Attribute>
<Identifier>(0x9f5c4075, 0x4a0d3666)</Identifier>
<Value>VRPN to OpenViBE tutorial</Value>
</Attribute>
<Attribute>
<Identifier>(0xf36a1567, 0xd13c53da)</Identifier>
<Value>http://openvibe.inria.fr/vrpn-tutorial-sending-data-from-an-external-application-to-openvibe/</Value>
</Attribute>
<Attribute>
<Identifier>(0xf6b2e3fa, 0x7bd43926)</Identifier>
<Value>Examples</Value>
</Attribute>
<Attribute>
<Identifier>(0xf8034a49, 0x8b3f37cc)</Identifier>
<Value>Inria</Value>
</Attribute>
</Attributes>
</OpenViBE-Scenario>
@@ -0,0 +1,87 @@
#include "GenericVRPNServer.h"
#include <vrpn_Connection.h>
#include <vrpn_Button.h>
#include <vrpn_Analog.h>
#include <cstdarg>
CGenericVrpnServer* CGenericVrpnServer::m_serverInstance = nullptr;
CGenericVrpnServer::CGenericVrpnServer(const int port) { m_connection = vrpn_create_server_connection(port); }
CGenericVrpnServer::~CGenericVrpnServer() { deleteInstance(); }
CGenericVrpnServer* CGenericVrpnServer::getInstance(const int port)
{
if (m_serverInstance == nullptr) { m_serverInstance = new CGenericVrpnServer(port); }
return m_serverInstance;
}
void CGenericVrpnServer::deleteInstance()
{
for (auto it = m_serverInstance->m_buttonServer.begin(); it != m_serverInstance->m_buttonServer.end(); ++it) { delete it->second.server; }
m_serverInstance->m_buttonServer.clear();
for (auto it = m_serverInstance->m_analogServer.begin(); it != m_serverInstance->m_analogServer.end(); ++it) { delete it->second.server; }
m_serverInstance->m_analogServer.clear();
delete m_serverInstance;
m_serverInstance = nullptr;
}
void CGenericVrpnServer::loop()
{
for (auto it = m_buttonServer.begin(); it != m_buttonServer.end(); ++it) { it->second.server->mainloop(); }
for (auto it = m_analogServer.begin(); it != m_analogServer.end(); ++it) { it->second.server->mainloop(); }
m_connection->mainloop();
}
void CGenericVrpnServer::addButton(const std::string& name, const int buttonCount)
{
SButtonServer serverObject;
serverObject.server = new vrpn_Button_Server(name.c_str(), m_connection, buttonCount);
serverObject.nButton = buttonCount;
m_buttonServer.insert(std::pair<std::string, SButtonServer>(name, serverObject));
m_buttonServer[name].cache.clear();
m_buttonServer[name].cache.resize(buttonCount);
}
void CGenericVrpnServer::changeButtonState(const std::string& name, const int index, const int state)
{
m_buttonServer[name].server->set_button(index, state);
m_buttonServer[name].cache[index] = state;
}
int CGenericVrpnServer::getButtonState(const std::string& name, const int index) { return m_buttonServer[name].cache[index]; }
void CGenericVrpnServer::addAnalog(const std::string& name, const int nChannel)
{
SAnalogServer serverObject;
serverObject.server = new vrpn_Analog_Server(name.c_str(), m_connection, nChannel);
serverObject.nChannel = nChannel;
m_analogServer.insert(std::pair<std::string, SAnalogServer>(name, serverObject));
}
void CGenericVrpnServer::changeAnalogState(const std::string& name, ...)
{
double* channels = m_analogServer[name].server->channels();
va_list list;
va_start(list, name);
for (int i = 0; i < m_analogServer[name].nChannel; ++i) { channels[i] = va_arg(list, double); }
va_end(list);
m_analogServer[name].server->report();
}
double* CGenericVrpnServer::getAnalogChannels(const std::string& name) { return m_analogServer[name].server->channels(); }
void CGenericVrpnServer::reportAnalogChanges(const std::string& name) { m_analogServer[name].server->report(); }
@@ -0,0 +1,103 @@
/**
* \file GenericVRPNServer.h
* \author Jozef Legény
*
* Copyright : Inria (2012)
* License : LGPLv2 -> AGPL3
*/
#pragma once
#include <map>
#include <vector>
#include <string>
class vrpn_Connection;
class vrpn_Button_Server;
class vrpn_Analog_Server;
/**
* \class CGenericVrpnServer
* \brief A class providing a very simple generic VRPN server capable of creating Analog and Button controls.
*/
class CGenericVrpnServer
{
public:
struct SButtonServer
{
vrpn_Button_Server* server;
int nButton;
std::vector<int> cache;
};
struct SAnalogServer
{
vrpn_Analog_Server* server;
int nChannel;
};
/// Public singleton factory
static CGenericVrpnServer* getInstance(const int port);
static void deleteInstance();
/// Public destructor
~CGenericVrpnServer();
/// The loop() method has to be called periodically in order for vrpn to work
void loop();
/** Creates a new button object within the VRPN server
* \param name name of the vrpn peripheral
* \param buttonCount number of virtual buttons in the peripeheral
*/
void addButton(const std::string& name, const int buttonCount);
/** Change the button state of a button inside a created VRPN peripheral
* \param name name of the vrpn peripheral containing the button
* \param index index of the button (beginning by 0)
* \param state new state of the button 0 = off, 1 = on
*/
void changeButtonState(const std::string& name, const int index, const int state);
/** Get the state of a button
* \param name name of the vrpn peripheral containing the button
* \param index index of the button (beginning by 0)
* \return the state of the button
*/
int getButtonState(const std::string& name, const int index);
/** Creates a new analog object within the VRPN server
* \param name name of the vrpn peripheral
* \param nChannel number of channels in the peripeheral
*/
void addAnalog(const std::string& name, const int nChannel);
/** Change the state of channels of an analog VRPN peripheral
* \param name name of the vrpn peripheral containing the analog control
* \param ... : list of the values (double)
*/
void changeAnalogState(const std::string& name, ...);
/** Gets a pointer to the channel array
* \param name name of the vrpn peripheral containing the analog control
* \return pointer to the array containing the channels
*/
double* getAnalogChannels(const std::string& name);
/** Marks the selected analog server channels as modified so the values are sent in the next loop
* \param name name of the vrpn peripheral containing the analog control
*/
void reportAnalogChanges(const std::string& name);
protected:
static CGenericVrpnServer* m_serverInstance;
explicit CGenericVrpnServer(const int port);
vrpn_Connection* m_connection = nullptr;
std::map<std::string, SButtonServer> m_buttonServer;
std::map<std::string, SAnalogServer> m_analogServer;
};
@@ -0,0 +1,50 @@
#if !defined(WIN32)
#include "GenericVRPNServer.h"
#include <iostream>
#include <cmath>
#include <unistd.h>
#define DEFAULT_PORT 50555
int main(int argc, char** argv)
{
CGenericVrpnServer* vrpnServer = CGenericVrpnServer::getInstance(DEFAULT_PORT);
const char* buttonDevice = "button_test";
const char* analogDevice = "analog_test";
std::cout << "Creating devices [" << buttonDevice << "] and [" << analogDevice << "] using port [" << DEFAULT_PORT << "]\n";
vrpnServer->addButton(buttonDevice, 1);
vrpnServer->addAnalog(analogDevice, 2);
double time = 0;
double period = 0;
while (true)
{
if (period >= 2 * M_PI)
{
vrpnServer->changeButtonState(buttonDevice, 0, 1 - vrpnServer->getButtonState(buttonDevice, 0));
period = 0;
}
vrpnServer->changeAnalogState(analogDevice, sin(time), cos(time));
time = time + 0.01;
period = period + 0.01;
vrpnServer->loop();
// sleep for 10 miliseconds (on Unix)
usleep(10000);
}
CGenericVrpnServer::deleteInstance();
vrpnServer = nullptr;
return 0;
}
#endif // !WIN32
@@ -0,0 +1,51 @@
#if defined(WIN32)
#include "GenericVRPNServer.h"
#include <iostream>
#define _USE_MATH_DEFINES
#include <math.h>
#include <windows.h>
#define DEFAULT_PORT 50555
int main(int /*argc*/, char** /*argv*/)
{
CGenericVrpnServer* vrpnServer = CGenericVrpnServer::getInstance(DEFAULT_PORT);
const char* buttonDevice = "button_test";
const char* analogDevice = "analog_test";
std::cout << "Creating devices [" << buttonDevice << "] and [" << analogDevice << "] using port [" << DEFAULT_PORT << "]\n";
vrpnServer->addButton(buttonDevice, 1);
vrpnServer->addAnalog(analogDevice, 2);
double time = 0;
double period = 0;
while (true)
{
if (period >= 2 * M_PI)
{
vrpnServer->changeButtonState(buttonDevice, 0, 1 - vrpnServer->getButtonState(buttonDevice, 0));
period = 0;
}
vrpnServer->changeAnalogState(analogDevice, sin(time), cos(time));
time = time + 0.01;
period = period + 0.01;
vrpnServer->loop();
// sleep for 10 miliseconds
Sleep(10);
}
CGenericVrpnServer::deleteInstance();
vrpnServer = nullptr;
return 0;
}
#endif // WIN32