init
This commit is contained in:
+32
@@ -0,0 +1,32 @@
|
||||
#if defined(TARGET_HAS_ThirdPartyOgre3D)
|
||||
|
||||
#include "ovassvepCCommandShipControl.h"
|
||||
#include "ovassvepCShooterApplication.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
|
||||
CCommandShipControl::CCommandShipControl(CShooterApplication* application) : ICommandVRPNButton(application, "SSVEP_VRPN_ShipControl") {}
|
||||
|
||||
void CCommandShipControl::execute(const int button, const int /*state*/)
|
||||
{
|
||||
CShooterApplication* shooterApplication = dynamic_cast<CShooterApplication*>(m_application);
|
||||
|
||||
switch (button)
|
||||
{
|
||||
case 0:
|
||||
shooterApplication->getShip()->shoot();
|
||||
break;
|
||||
case 1:
|
||||
shooterApplication->getShip()->rotate(-6);
|
||||
break;
|
||||
case 2:
|
||||
shooterApplication->getShip()->rotate(6);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
#endif
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "../ovassvepICommandVRPNButton.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
class CShooterApplication;
|
||||
|
||||
class CCommandShipControl final : public ICommandVRPNButton
|
||||
{
|
||||
public:
|
||||
explicit CCommandShipControl(CShooterApplication* application);
|
||||
~CCommandShipControl() override {}
|
||||
|
||||
void execute(const int button, const int state) override;
|
||||
};
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
#if defined(TARGET_HAS_ThirdPartyOgre3D)
|
||||
|
||||
#include "ovassvepCCommandTargetControl.h"
|
||||
#include "ovassvepCShooterApplication.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
|
||||
CCommandTargetControl::CCommandTargetControl(CShooterApplication* application)
|
||||
: ICommandVRPNButton(application, "SSVEP_VRPN_ShooterTarget")
|
||||
{
|
||||
m_vrpnServer = CVRPNServer::getInstance(application);
|
||||
m_vrpnServer->addButton("SSVEP_VRPN_TargetRequest", 1);
|
||||
}
|
||||
|
||||
void CCommandTargetControl::processFrame()
|
||||
{
|
||||
CShooterApplication* application = dynamic_cast<CShooterApplication*>(m_application);
|
||||
|
||||
ICommandVRPNButton::processFrame();
|
||||
|
||||
if (application->m_TargetRequest)
|
||||
{
|
||||
m_application->getLogManager() << Kernel::LogLevel_Info << "Requesting target\n";
|
||||
m_vrpnServer->changeButtonState("SSVEP_VRPN_TargetRequest", 0, 1);
|
||||
application->m_TargetRequest = false;
|
||||
}
|
||||
else { m_vrpnServer->changeButtonState("SSVEP_VRPN_TargetRequest", 0, 0); }
|
||||
|
||||
m_vrpnServer->processFrame();
|
||||
}
|
||||
|
||||
void CCommandTargetControl::execute(const int button, const int state)
|
||||
{
|
||||
if (state == 1)
|
||||
{
|
||||
m_application->getLogManager() << Kernel::LogLevel_Info << "Target created at position " << button << "\n";
|
||||
dynamic_cast<CShooterApplication*>(m_application)->addTarget(button);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
#endif
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "../ovassvepICommandVRPNButton.h"
|
||||
#include "../ovassvepCVRPNServer.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
class CShooterApplication;
|
||||
|
||||
class CCommandTargetControl final : public ICommandVRPNButton
|
||||
{
|
||||
public:
|
||||
explicit CCommandTargetControl(CShooterApplication* application);
|
||||
~CCommandTargetControl() override {}
|
||||
|
||||
void execute(const int button, const int state) override;
|
||||
void processFrame() override;
|
||||
|
||||
private:
|
||||
CVRPNServer* m_vrpnServer = nullptr;
|
||||
};
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
#if defined(TARGET_HAS_ThirdPartyOgre3D)
|
||||
|
||||
#include "ovassvepCShooterApplication.h"
|
||||
|
||||
#include "../ovassvepCCommandStartStop.h"
|
||||
#include "../ovassvepCCommandStimulatorControl.h"
|
||||
#include "ovassvepCCommandTargetControl.h"
|
||||
#include "ovassvepCCommandShipControl.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
|
||||
#if !((CEGUI_VERSION_MAJOR > 0) || (CEGUI_VERSION_MINOR >= 8))
|
||||
namespace CEGUI
|
||||
{
|
||||
typedef CEGUI::UVector2 USize;
|
||||
};
|
||||
#endif
|
||||
|
||||
CShooterApplication::~CShooterApplication()
|
||||
{
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << "- m_ship\n";
|
||||
delete m_ship;
|
||||
}
|
||||
|
||||
bool CShooterApplication::setup(Kernel::IKernelContext* kernelCtx)
|
||||
{
|
||||
if (!CApplication::setup(kernelCtx))
|
||||
{
|
||||
// If setup failed, logmanager may be in an unusable state, use cout
|
||||
std::cout << "Error: Base application setup failed\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the StarShip object
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << "+ m_ship = new CStarShip(...)\n";
|
||||
m_ship = new CStarShip(this, m_sceneNode, 0.3F, &m_oFrequencies);
|
||||
|
||||
// Initialize the Target class
|
||||
|
||||
CShooterTarget::initialize(m_painter, m_sceneNode);
|
||||
|
||||
// draw the initial text
|
||||
|
||||
m_instructionsReady = m_guiManager->createWindow("TaharezLook/StaticImage", "InstructionsReady");
|
||||
m_instructionsReady->setPosition(CEGUI::UVector2(cegui_reldim(0.0F), cegui_reldim(0.0F)));
|
||||
m_instructionsReady->setSize(CEGUI::USize(CEGUI::UDim(0.0F, 640.F), CEGUI::UDim(0.0F, 32.F)));
|
||||
|
||||
#if (CEGUI_VERSION_MAJOR > 0) || (CEGUI_VERSION_MINOR >= 8)
|
||||
m_sheet->addChild(m_instructionsReady);
|
||||
CEGUI::ImageManager::getSingleton().addFromImageFile("InstructionsReady", "InstructionText-Start.png");
|
||||
m_instructionsReady->setProperty("Image", "InstructionsReady");
|
||||
#else
|
||||
m_sheet->addChildWindow(m_instructionsReady);
|
||||
CEGUI::ImagesetManager::getSingleton().createFromImageFile("InstructionsReady", "InstructionText-Start.png");
|
||||
m_instructionsReady->setProperty("Image", "set:InstructionsReady image:full_image");
|
||||
#endif
|
||||
|
||||
m_instructionsReady->setProperty("FrameEnabled", "False");
|
||||
m_instructionsReady->setProperty("BackgroundEnabled", "False");
|
||||
m_instructionsReady->setVisible(true);
|
||||
|
||||
// Create commands
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << "+ addCommand(new CCommandStartStop(...)\n";
|
||||
this->addCommand(new CCommandStartStop(this));
|
||||
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << "+ addCommand(new CCommandStimulatorControl(...))\n";
|
||||
this->addCommand(new CCommandStimulatorControl(this));
|
||||
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << "+ addCommand(new CCommandTargetControl(...)\n";
|
||||
this->addCommand(new CCommandTargetControl(this));
|
||||
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << "+ addCommand(new CCommandShipControl(...))\n";
|
||||
this->addCommand(new CCommandShipControl(this));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CShooterApplication::processFrame(const size_t frame)
|
||||
{
|
||||
CApplication::processFrame(frame);
|
||||
m_ship->processFrame(frame);
|
||||
|
||||
if (m_ship->isShooting())
|
||||
{
|
||||
for (auto it = m_targets.begin(); it != m_targets.end(); ++it)
|
||||
{
|
||||
if ((*it)->collidesWith(m_ship->getShotCoordinates()))
|
||||
{
|
||||
delete *it;
|
||||
m_targets.erase(it);
|
||||
m_TargetRequest = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CShooterApplication::addTarget(const size_t targetPosition)
|
||||
{
|
||||
m_targets.push_back(CShooterTarget::createTarget(Ogre::Radian(Ogre::Math::PI * 2 / 360 * 45 * targetPosition)));
|
||||
}
|
||||
|
||||
void CShooterApplication::startExperiment()
|
||||
{
|
||||
m_TargetRequest = true;
|
||||
CApplication::startExperiment();
|
||||
|
||||
m_instructionsReady->setVisible(false);
|
||||
}
|
||||
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
#endif
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <openvibe/ov_all.h>
|
||||
#include <toolkit/ovtk_all.h>
|
||||
|
||||
#include "../ovassvepCApplication.h"
|
||||
#include "ovassvepCShooterTarget.h"
|
||||
#include "ovassvepCStarShip.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
class CShooterApplication final : public CApplication
|
||||
{
|
||||
public:
|
||||
CShooterApplication() : CApplication() {}
|
||||
~CShooterApplication() override;
|
||||
|
||||
bool setup(Kernel::IKernelContext* kernelCtx) override;
|
||||
CStarShip* getShip() const { return m_ship; }
|
||||
void startExperiment() override;
|
||||
void addTarget(size_t targetPosition);
|
||||
|
||||
bool m_TargetRequest = false;
|
||||
|
||||
private:
|
||||
void processFrame(const size_t frame) override;
|
||||
|
||||
CEGUI::Window* m_instructionsReady = nullptr;
|
||||
CStarShip* m_ship = nullptr;
|
||||
std::vector<CShooterTarget*> m_targets;
|
||||
};
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
#if defined(TARGET_HAS_ThirdPartyOgre3D)
|
||||
|
||||
#include "ovassvepCShooterTarget.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
|
||||
Ogre::SceneNode* CShooterTarget::m_parentNode = nullptr;
|
||||
CBasicPainter* CShooterTarget::m_painter = nullptr;
|
||||
|
||||
void CShooterTarget::initialize(CBasicPainter* painter, Ogre::SceneNode* parentNode)
|
||||
{
|
||||
m_painter = painter;
|
||||
m_parentNode = parentNode;
|
||||
}
|
||||
|
||||
CShooterTarget* CShooterTarget::createTarget(const Ogre::Radian angle)
|
||||
{
|
||||
if (m_painter == nullptr)
|
||||
{
|
||||
std::cerr << "The CShooterTarget was not initialized" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new CShooterTarget(angle);
|
||||
}
|
||||
|
||||
CShooterTarget::CShooterTarget(const Ogre::Radian angle)
|
||||
{
|
||||
m_targetNode = m_parentNode->createChildSceneNode();
|
||||
|
||||
|
||||
Ogre::MovableObject* targetObject = m_painter->paintCircle(0.0F, 1.0F - 1.0F * SSVEP_SHOOTER_TARGET_SIZE, SSVEP_SHOOTER_TARGET_SIZE,
|
||||
Ogre::ColourValue(1.0F, 1.0F, 1.0F));
|
||||
targetObject->setVisible(true);
|
||||
m_targetNode->attachObject(targetObject);
|
||||
|
||||
m_targetNode->roll(angle);
|
||||
}
|
||||
|
||||
CShooterTarget::~CShooterTarget()
|
||||
{
|
||||
m_targetNode->removeAndDestroyAllChildren();
|
||||
m_targetNode->getCreator()->destroySceneNode(m_targetNode);
|
||||
}
|
||||
|
||||
bool CShooterTarget::collidesWith(const std::pair<Ogre::Real, Ogre::Real> point) const
|
||||
{
|
||||
const Ogre::Radian theta = (m_targetNode->getOrientation()).getRoll();
|
||||
const Ogre::Real targetDist = 1.0F - 2 * SSVEP_SHOOTER_TARGET_SIZE;
|
||||
const Ogre::Real dist = sqrt(pow(point.first + Ogre::Math::Sin(theta) * targetDist, 2) + pow(point.second - Ogre::Math::Cos(theta) * targetDist, 2));
|
||||
return dist <= SSVEP_SHOOTER_TARGET_SIZE;
|
||||
}
|
||||
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
#endif
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <Ogre.h>
|
||||
|
||||
#include "../ovassvepCBasicPainter.h"
|
||||
|
||||
#define SSVEP_SHOOTER_TARGET_SIZE 0.15f
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
class CShooterTarget
|
||||
{
|
||||
public:
|
||||
static CShooterTarget* createTarget(Ogre::Radian angle);
|
||||
static void initialize(CBasicPainter* painter, Ogre::SceneNode* parentNode);
|
||||
~CShooterTarget();
|
||||
|
||||
bool collidesWith(std::pair<Ogre::Real, Ogre::Real> point) const;
|
||||
|
||||
private:
|
||||
static Ogre::SceneNode* m_parentNode;
|
||||
static CBasicPainter* m_painter;
|
||||
|
||||
Ogre::SceneNode* m_targetNode = nullptr;
|
||||
|
||||
explicit CShooterTarget(Ogre::Radian angle);
|
||||
};
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
#if defined(TARGET_HAS_ThirdPartyOgre3D)
|
||||
|
||||
#include "ovassvepCStarShip.h"
|
||||
|
||||
#include "../ovassvepCApplication.h"
|
||||
#include "../ovassvepCSSVEPFlickeringObject.h"
|
||||
|
||||
#define SSVEP_SHIP_HULL_COLOUR Ogre::ColourValue(0.0F, 0.5F, 0.5F)
|
||||
#define SIGN(x) ( (x) < 0 ? -1 : 1 )
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
|
||||
CStarShip::CStarShip(CApplication* application, Ogre::SceneNode* parentNode, const Ogre::Real radius, std::vector<std::pair<size_t, size_t>>* frequencies)
|
||||
{
|
||||
// get configuration and controlling objects
|
||||
Kernel::IConfigurationManager* configManager = application->getConfigurationManager();
|
||||
CBasicPainter* painter = application->getPainter();
|
||||
m_angularSpeed = Ogre::Real(configManager->expandAsFloat(
|
||||
"${SSVEP_ShipAngularSpeed}", Ogre::Math::PI / 60.0F));
|
||||
application->getLogManager() << Kernel::LogLevel_Info << "Ship Angluar Speed : " << m_angularSpeed << "\n";
|
||||
|
||||
const Ogre::ColourValue lightColor = Ogre::ColourValue(float(configManager->expandAsFloat("${SSVEP_TargetLightColourRed}", 1.0F)),
|
||||
float(configManager->expandAsFloat("${SSVEP_TargetLightColourGreen}", 1.0F)),
|
||||
float(configManager->expandAsFloat("${SSVEP_TargetLightColourBlue}", 1.0F)));
|
||||
|
||||
const Ogre::ColourValue darkColor = Ogre::ColourValue(float(configManager->expandAsFloat("${SSVEP_TargetDarkColourRed}", 0.0F)),
|
||||
float(configManager->expandAsFloat("${SSVEP_TargetDarkColourGreen}", 0.0F)),
|
||||
float(configManager->expandAsFloat("${SSVEP_TargetDarkColourBlue}", 0.0F)));
|
||||
|
||||
|
||||
// draw the ship scene objects
|
||||
m_shipNode = parentNode->createChildSceneNode();
|
||||
m_shotNode = m_shipNode->createChildSceneNode();
|
||||
|
||||
Ogre::MovableObject* shipHull = painter->paintCircle(0.0F, 0.0F, radius, SSVEP_SHIP_HULL_COLOUR, false, 2);
|
||||
m_shipNode->attachObject(shipHull);
|
||||
shipHull->setVisible(true);
|
||||
|
||||
|
||||
// Ogre::RealRect wingRectangle = { - radius * 0.4f, radius * 0.4f, radius * 0.4f, -radius * 0.4f };
|
||||
const Ogre::RealRect wingRectangle(-radius * 0.4F, radius * 0.4F, radius * 0.4F, -radius * 0.4F);
|
||||
|
||||
// paint the cannon
|
||||
|
||||
Ogre::SceneNode* drawnObjectNode = m_shipNode->createChildSceneNode();
|
||||
|
||||
Ogre::MovableObject* drawnObject = painter->paintTriangle(Point(0.0F, radius * 0.4F), Point(- radius * 0.4F, -radius * 0.4F),
|
||||
Point(radius * 0.4F, -radius * 0.4F), lightColor);
|
||||
drawnObject->setVisible(true);
|
||||
drawnObjectNode->attachObject(drawnObject);
|
||||
|
||||
drawnObject = painter->paintTriangle(Point(0.0F, radius * 0.4F), Point(- radius * 0.4F, -radius * 0.4F), Point(radius * 0.4F, -radius * 0.4F), darkColor);
|
||||
drawnObject->setVisible(false);
|
||||
drawnObjectNode->attachObject(drawnObject);
|
||||
|
||||
drawnObjectNode->setPosition(0.0, radius, 0.0);
|
||||
|
||||
m_shipCannon = new CSSVEPFlickeringObject(drawnObjectNode, (*frequencies)[1].first, (*frequencies)[1].second);
|
||||
|
||||
// paint the left wing
|
||||
|
||||
drawnObjectNode = m_shipNode->createChildSceneNode();
|
||||
|
||||
drawnObject = painter->paintRectangle(wingRectangle, lightColor);
|
||||
drawnObject->setVisible(true);
|
||||
drawnObjectNode->attachObject(drawnObject);
|
||||
|
||||
drawnObject = painter->paintRectangle(wingRectangle, darkColor);
|
||||
drawnObject->setVisible(false);
|
||||
drawnObjectNode->attachObject(drawnObject);
|
||||
|
||||
drawnObjectNode->setPosition(-radius * 0.875F, -radius * 0.875F, 0.0);
|
||||
|
||||
m_shipLeftWing = new CSSVEPFlickeringObject(drawnObjectNode, (*frequencies)[2].first, (*frequencies)[2].second);
|
||||
|
||||
// paint the right wing
|
||||
|
||||
drawnObjectNode = m_shipNode->createChildSceneNode();
|
||||
|
||||
drawnObject = painter->paintRectangle(wingRectangle, lightColor);
|
||||
drawnObject->setVisible(true);
|
||||
drawnObjectNode->attachObject(drawnObject);
|
||||
|
||||
drawnObject = painter->paintRectangle(wingRectangle, darkColor);
|
||||
drawnObject->setVisible(false);
|
||||
drawnObjectNode->attachObject(drawnObject);
|
||||
|
||||
drawnObjectNode->setPosition(radius * 0.875F, -radius * 0.875F, 0.0F);
|
||||
|
||||
m_shipRightWing = new CSSVEPFlickeringObject(drawnObjectNode, (*frequencies)[3].first, (*frequencies)[3].second);
|
||||
|
||||
// create the shot
|
||||
|
||||
drawnObject = painter->paintTriangle(Point(0.0F, radius * 0.25F), Point(-radius * 0.125F, 0.0F), Point(radius * 0.125F, 0.0F),
|
||||
Ogre::ColourValue(1.0F, 1.0F, 0.0F));
|
||||
drawnObject->setVisible(false);
|
||||
|
||||
m_shotNode->attachObject(drawnObject);
|
||||
|
||||
drawnObject = painter->paintTriangle(Point(-radius * 0.125F, 0.0F), Point(0.0F, -radius * 0.75F), Point(radius * 0.125F, 0.0F),
|
||||
Ogre::ColourValue(1.0F, 1.0F, 0.0F));
|
||||
drawnObject->setVisible(false);
|
||||
|
||||
m_shotNode->attachObject(drawnObject);
|
||||
}
|
||||
|
||||
void CStarShip::processFrame(const size_t /*currentFrame*/)
|
||||
{
|
||||
m_shipCannon->processFrame();
|
||||
m_shipLeftWing->processFrame();
|
||||
m_shipRightWing->processFrame();
|
||||
|
||||
if (m_nCurrentRotation != 0)
|
||||
{
|
||||
m_shipNode->roll(Ogre::Radian(m_angularSpeed * SIGN(m_nCurrentRotation)));
|
||||
m_currentAngle += Ogre::Radian(m_angularSpeed * SIGN(m_nCurrentRotation));
|
||||
m_nCurrentRotation -= SIGN(m_nCurrentRotation);
|
||||
}
|
||||
|
||||
if (m_isShooting)
|
||||
{
|
||||
m_shotDistance += 0.07F;
|
||||
m_shotNode->setPosition(0.0, m_shotDistance, 0.0);
|
||||
|
||||
if (m_shotDistance > 1.5F)
|
||||
{
|
||||
m_isShooting = false;
|
||||
m_shotNode->setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CStarShip::shoot()
|
||||
{
|
||||
if (m_isShooting) { return; }
|
||||
|
||||
m_isShooting = true;
|
||||
m_shotDistance = 0.0F;
|
||||
|
||||
m_shotNode->setPosition(0.0F, 0.0F, 0.0F);
|
||||
m_shotNode->setVisible(true);
|
||||
}
|
||||
|
||||
std::pair<Ogre::Real, Ogre::Real> CStarShip::getShotCoordinates() const
|
||||
{
|
||||
return std::make_pair(-Ogre::Math::Sin(m_currentAngle) * m_shotDistance, Ogre::Math::Cos(m_currentAngle) * m_shotDistance);
|
||||
}
|
||||
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
#endif
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include <Ogre.h>
|
||||
|
||||
#include <openvibe/ov_all.h>
|
||||
#include <toolkit/ovtk_all.h>
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
class CApplication;
|
||||
class CSSVEPFlickeringObject;
|
||||
|
||||
class CStarShip
|
||||
{
|
||||
public:
|
||||
CStarShip(CApplication* application, Ogre::SceneNode* parentNode, Ogre::Real radius, std::vector<std::pair<size_t, size_t>>* frequencies);
|
||||
void processFrame(const size_t currentFrame);
|
||||
void rotate(const int nRotation) { m_nCurrentRotation += nRotation; }
|
||||
bool isShooting() const { return m_isShooting; }
|
||||
void shoot();
|
||||
std::pair<Ogre::Real, Ogre::Real> getShotCoordinates() const;
|
||||
|
||||
private:
|
||||
Ogre::SceneNode* m_shipNode = nullptr;
|
||||
|
||||
CSSVEPFlickeringObject* m_shipCannon = nullptr;
|
||||
CSSVEPFlickeringObject* m_shipLeftWing = nullptr;
|
||||
CSSVEPFlickeringObject* m_shipRightWing = nullptr;
|
||||
|
||||
Ogre::Real m_angularSpeed;
|
||||
Ogre::Radian m_currentAngle;
|
||||
int m_nCurrentRotation = 0;
|
||||
|
||||
Ogre::SceneNode* m_shotNode = nullptr;
|
||||
bool m_isShooting = false;
|
||||
Ogre::Real m_shotDistance = 0.0F;
|
||||
};
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "../ovassvepICommandVRPNButton.h"
|
||||
#include "ovassvepCTrainerApplication.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
class CTrainerApplication;
|
||||
|
||||
class CCommandReceiveTarget final : public ICommandVRPNButton
|
||||
{
|
||||
public:
|
||||
explicit CCommandReceiveTarget(CApplication* application) : ICommandVRPNButton(application, "SSVEP_VRPN_Target") {}
|
||||
~CCommandReceiveTarget() override { }
|
||||
|
||||
void execute(const int button, const int state) override { dynamic_cast<CTrainerApplication*>(m_application)->setTarget(button); }
|
||||
};
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
#if defined(TARGET_HAS_ThirdPartyOgre3D)
|
||||
|
||||
#include "ovassvepCTrainerApplication.h"
|
||||
|
||||
#include "../ovassvepCCommandStartStop.h"
|
||||
#include "../ovassvepCCommandStimulatorControl.h"
|
||||
#include "ovassvepCCommandReceiveTarget.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
|
||||
#if !((CEGUI_VERSION_MAJOR > 0) || (CEGUI_VERSION_MINOR >= 8))
|
||||
namespace CEGUI
|
||||
{
|
||||
typedef CEGUI::UVector2 USize;
|
||||
};
|
||||
#endif
|
||||
|
||||
bool CTrainerApplication::setup(Kernel::IKernelContext* kernelCtx)
|
||||
{
|
||||
if (!CApplication::setup(kernelCtx)) { return false; }
|
||||
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << " * CTrainerApplication::setup()\n";
|
||||
|
||||
Kernel::IConfigurationManager* configManager = &(m_kernelCtx->getConfigurationManager());
|
||||
|
||||
CTrainerFlickeringObject::initialize(this);
|
||||
|
||||
// paint targets
|
||||
|
||||
const size_t nTarget = size_t(configManager->expandAsUInteger("${SSVEP_TargetCount}"));
|
||||
|
||||
for (size_t i = 0; i < nTarget; ++i) { this->addObject(CTrainerFlickeringObject::createTrainerFlickeringObject(i)); }
|
||||
|
||||
// draw the initial text
|
||||
m_instructionsReady = m_guiManager->createWindow("TaharezLook/StaticImage", "InstructionsReady");
|
||||
m_instructionsReady->setPosition(CEGUI::UVector2(cegui_reldim(0.0F), cegui_reldim(0.0F)));
|
||||
m_instructionsReady->setSize(CEGUI::USize(CEGUI::UDim(0.0F, 640.F), CEGUI::UDim(0.0F, 32.F)));
|
||||
|
||||
#if (CEGUI_VERSION_MAJOR > 0) || (CEGUI_VERSION_MINOR >= 8)
|
||||
m_sheet->addChild(m_instructionsReady);
|
||||
CEGUI::ImageManager::getSingleton().addFromImageFile("InstructionsReady", "InstructionText-Start.png");
|
||||
m_instructionsReady->setProperty("Image", "InstructionsReady");
|
||||
#else
|
||||
m_sheet->addChildWindow(m_instructionsReady);
|
||||
CEGUI::ImagesetManager::getSingleton().createFromImageFile("InstructionsReady", "InstructionText-Start.png");
|
||||
m_instructionsReady->setProperty("Image", "set:InstructionsReady image:full_image");
|
||||
#endif
|
||||
|
||||
|
||||
m_instructionsReady->setProperty("FrameEnabled", "False");
|
||||
m_instructionsReady->setProperty("BackgroundEnabled", "False");
|
||||
m_instructionsReady->setVisible(true);
|
||||
|
||||
|
||||
// initialize commands
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << "+ addCommand(new CCommandStartStop(...)\n";
|
||||
this->addCommand(new CCommandStartStop(this));
|
||||
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << "+ addCommand(new CCommandStimulatorControl(...))\n";
|
||||
this->addCommand(new CCommandStimulatorControl(this));
|
||||
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << "+ addCommand(new CC(...))\n";
|
||||
this->addCommand(new CCommandReceiveTarget(this));
|
||||
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << " * CTrainerApplication::setup() completed successfully\n";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CTrainerApplication::processFrame(const size_t frame)
|
||||
{
|
||||
CApplication::processFrame(frame);
|
||||
|
||||
if (!m_active) { return; }
|
||||
|
||||
for (size_t i = 0; i < m_oObjects.size(); ++i) { m_oObjects[i]->processFrame(); }
|
||||
}
|
||||
|
||||
void CTrainerApplication::addObject(CTrainerFlickeringObject* obj)
|
||||
{
|
||||
m_oObjects.push_back(obj);
|
||||
obj->setVisible(true);
|
||||
}
|
||||
|
||||
void CTrainerApplication::setTarget(const int target)
|
||||
{
|
||||
const size_t currentTime = int(time(nullptr) - m_ttStartTime);
|
||||
(*m_logManager) << Kernel::LogLevel_Info << currentTime << " > Target set to " << target << "\n";
|
||||
|
||||
for (int i = 0; i < int(m_oObjects.size()); ++i) { m_oObjects[i]->setTarget(target == i); }
|
||||
}
|
||||
|
||||
void CTrainerApplication::startExperiment()
|
||||
{
|
||||
CApplication::startExperiment();
|
||||
|
||||
m_ttStartTime = time(nullptr);
|
||||
|
||||
this->stopFlickering();
|
||||
m_instructionsReady->setVisible(false);
|
||||
}
|
||||
|
||||
void CTrainerApplication::startFlickering()
|
||||
{
|
||||
const size_t currentTime = size_t(time(nullptr) - m_ttStartTime);
|
||||
(*m_logManager) << Kernel::LogLevel_Info << currentTime << " > Starting Visual Stimulation\n";
|
||||
m_active = true;
|
||||
}
|
||||
|
||||
void CTrainerApplication::stopFlickering()
|
||||
{
|
||||
const size_t currentTime = size_t(time(nullptr) - m_ttStartTime);
|
||||
(*m_logManager) << Kernel::LogLevel_Info << currentTime << " > Stopping Visual Stimulation\n";
|
||||
m_active = false;
|
||||
|
||||
for (size_t i = 0; i < m_oObjects.size(); ++i) { m_oObjects[i]->setVisible(true); }
|
||||
|
||||
this->setTarget(-1);
|
||||
}
|
||||
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
#endif
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <CEGUI.h>
|
||||
|
||||
#include "../ovassvepCApplication.h"
|
||||
#include "ovassvepCTrainerFlickeringObject.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
class CTrainerApplication final : public CApplication
|
||||
{
|
||||
public:
|
||||
CTrainerApplication() : CApplication() {}
|
||||
~CTrainerApplication() override {}
|
||||
|
||||
bool setup(Kernel::IKernelContext* kernelCtx) override;
|
||||
void setTarget(int target);
|
||||
|
||||
void startExperiment() override;
|
||||
void startFlickering() override;
|
||||
void stopFlickering() override;
|
||||
|
||||
|
||||
private:
|
||||
bool m_active = false;
|
||||
void processFrame(const size_t frame) override;
|
||||
void addObject(CTrainerFlickeringObject* obj);
|
||||
|
||||
std::vector<CTrainerFlickeringObject*> m_oObjects;
|
||||
|
||||
time_t m_ttStartTime = 0;
|
||||
|
||||
CEGUI::Window* m_instructionsReady = nullptr;
|
||||
};
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
#if defined(TARGET_HAS_ThirdPartyOgre3D)
|
||||
|
||||
#include "ovassvepCTrainerFlickeringObject.h"
|
||||
#include "ovassvepCTrainerApplication.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
|
||||
Ogre::SceneNode* CTrainerFlickeringObject::m_parentNode = nullptr;
|
||||
CBasicPainter* CTrainerFlickeringObject::m_painter = nullptr;
|
||||
Ogre::ColourValue CTrainerFlickeringObject::m_lightColor = Ogre::ColourValue(1.0F, 1.0F, 1.0F);
|
||||
Ogre::ColourValue CTrainerFlickeringObject::m_darkColor = Ogre::ColourValue(0.0F, 0.0F, 0.0F);
|
||||
float CTrainerFlickeringObject::m_targetWidth = 0.2F;
|
||||
float CTrainerFlickeringObject::m_targetHeight = 0.2F;
|
||||
CTrainerApplication* CTrainerFlickeringObject::m_application = nullptr;
|
||||
|
||||
void CTrainerFlickeringObject::initialize(CTrainerApplication* application)
|
||||
{
|
||||
m_application = application;
|
||||
Kernel::IConfigurationManager* configManager = application->getConfigurationManager();
|
||||
|
||||
m_painter = application->getPainter();
|
||||
m_parentNode = application->getSceneNode();
|
||||
|
||||
m_targetWidth = float(configManager->expandAsFloat("${SSVEP_TargetWidth}"));
|
||||
m_targetHeight = float(configManager->expandAsFloat("${SSVEP_TargetHeight}"));
|
||||
|
||||
m_lightColor = Ogre::ColourValue(float(configManager->expandAsFloat("${SSVEP_TargetLightColourRed}")),
|
||||
float(configManager->expandAsFloat("${SSVEP_TargetLightColourGreen}")),
|
||||
float(configManager->expandAsFloat("${SSVEP_TargetLightColourBlue}")));
|
||||
|
||||
m_darkColor = Ogre::ColourValue(float(configManager->expandAsFloat("${SSVEP_TargetDarkColourRed}")),
|
||||
float(configManager->expandAsFloat("${SSVEP_TargetDarkColourGreen}")),
|
||||
float(configManager->expandAsFloat("${SSVEP_TargetDarkColourBlue}")));
|
||||
}
|
||||
|
||||
CTrainerFlickeringObject* CTrainerFlickeringObject::createTrainerFlickeringObject(const size_t targetId)
|
||||
{
|
||||
Kernel::IConfigurationManager* configManager = m_application->getConfigurationManager();
|
||||
|
||||
if (m_painter != nullptr)
|
||||
{
|
||||
const Ogre::ColourValue currentTargetColour = (targetId == 0) ? m_darkColor : m_lightColor;
|
||||
|
||||
const CIdentifier id = configManager->createConfigurationToken("SSVEPTarget_Id", std::to_string(targetId).c_str());
|
||||
|
||||
const float targetX = float(configManager->expandAsFloat("${SSVEP_Target_X_${SSVEPTarget_Id}}"));
|
||||
const float targetY = float(configManager->expandAsFloat("${SSVEP_Target_Y_${SSVEPTarget_Id}}"));
|
||||
const size_t framesL = (*(m_application->getFrequencies()))[targetId].first;
|
||||
const size_t framesD = (*(m_application->getFrequencies()))[targetId].second;
|
||||
|
||||
m_application->getLogManager() << Kernel::LogLevel_Info << "New trainer object : id=" << targetId << " litFrames=" << framesL <<
|
||||
" darkFrames=" << framesD << "\n";
|
||||
|
||||
configManager->releaseConfigurationToken(id);
|
||||
|
||||
return new CTrainerFlickeringObject(targetX, targetY, currentTargetColour, uint8_t(framesL), uint8_t(framesD));
|
||||
}
|
||||
m_application->getLogManager() << Kernel::LogLevel_Fatal << "TrainerTarget object was not properly initialized\n";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CTrainerFlickeringObject::CTrainerFlickeringObject(const float posX, const float posY, const Ogre::ColourValue colour, const uint8_t litFrames,
|
||||
const uint8_t darkFrames)
|
||||
: CSSVEPFlickeringObject(nullptr, litFrames, darkFrames)
|
||||
{
|
||||
m_elementNode = m_parentNode->createChildSceneNode();
|
||||
m_objectNode = m_elementNode->createChildSceneNode();
|
||||
Ogre::SceneNode* pointerNode = m_elementNode->createChildSceneNode();
|
||||
|
||||
const Ogre::RealRect rectangle(posX - m_targetWidth / 2, posY + m_targetHeight / 2, posX + m_targetWidth / 2, posY - m_targetHeight / 2);
|
||||
|
||||
Ogre::MovableObject* litObject = m_painter->paintRectangle(rectangle, colour);
|
||||
|
||||
m_objectNode->attachObject(litObject);
|
||||
litObject->setVisible(true);
|
||||
|
||||
Ogre::MovableObject* darkObject = m_painter->paintRectangle(rectangle, m_darkColor);
|
||||
m_objectNode->attachObject(darkObject);
|
||||
darkObject->setVisible(false);
|
||||
|
||||
m_pointer = m_painter->paintTriangle(Point(posX - 0.05F, posY + m_targetHeight), Point(posX, posY + m_targetHeight - 0.05F),
|
||||
Point(posX + 0.05F, posY + m_targetHeight), Ogre::ColourValue(1, 1, 0));
|
||||
|
||||
pointerNode->attachObject(m_pointer);
|
||||
m_pointer->setVisible(false);
|
||||
}
|
||||
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
#endif
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <openvibe/ov_all.h>
|
||||
#include <toolkit/ovtk_all.h>
|
||||
#include <Ogre.h>
|
||||
|
||||
#include "../ovassvepCSSVEPFlickeringObject.h"
|
||||
#include "../ovassvepCBasicPainter.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
class CTrainerApplication;
|
||||
|
||||
class CTrainerFlickeringObject final : public CSSVEPFlickeringObject
|
||||
{
|
||||
public:
|
||||
static CTrainerFlickeringObject* createTrainerFlickeringObject(size_t targetId);
|
||||
static void initialize(CTrainerApplication* application);
|
||||
|
||||
static void connectToNode(Ogre::SceneNode* /*sceneNode*/) { }
|
||||
void setTarget(const bool isTarget) const { m_pointer->setVisible(isTarget); }
|
||||
bool isTarget() const { return m_pointer->getVisible(); }
|
||||
|
||||
private:
|
||||
static CTrainerApplication* m_application;
|
||||
static Ogre::SceneNode* m_parentNode;
|
||||
static CBasicPainter* m_painter;
|
||||
static float m_targetWidth;
|
||||
static float m_targetHeight;
|
||||
static Ogre::ColourValue m_lightColor;
|
||||
static Ogre::ColourValue m_darkColor;
|
||||
|
||||
CTrainerFlickeringObject(float posX, float posY, Ogre::ColourValue colour, uint8_t litFrames, uint8_t darkFrames);
|
||||
|
||||
|
||||
Ogre::SceneNode* m_elementNode = nullptr;
|
||||
Ogre::MovableObject* m_pointer = nullptr;
|
||||
};
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
+286
@@ -0,0 +1,286 @@
|
||||
#if defined(TARGET_HAS_ThirdPartyOgre3D)
|
||||
|
||||
#include "ovassvepCApplication.h"
|
||||
#include <cmath>
|
||||
|
||||
#include "fs/Files.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
|
||||
#define MIN(a,b) ( (a) < (b) ? (a) : (b) )
|
||||
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
CApplication::~CApplication()
|
||||
{
|
||||
if (m_painter != nullptr)
|
||||
{
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << "- m_painter\n";
|
||||
delete m_painter;
|
||||
m_painter = nullptr;
|
||||
}
|
||||
|
||||
for (auto it = m_oCommands.begin();
|
||||
it != m_oCommands.end(); ++it)
|
||||
{
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << "- ICommand\n";
|
||||
if (*it != nullptr)
|
||||
{
|
||||
delete *it;
|
||||
*it = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << "- m_root\n";
|
||||
if (m_root != nullptr)
|
||||
{
|
||||
delete m_root;
|
||||
m_root = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
bool CApplication::setup(Kernel::IKernelContext* poKernelContext)
|
||||
{
|
||||
m_kernelCtx = poKernelContext;
|
||||
m_logManager = &(m_kernelCtx->getLogManager());
|
||||
|
||||
Kernel::IConfigurationManager* configurationManager = &(m_kernelCtx->getConfigurationManager());
|
||||
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << " * CApplication::setup()\n";
|
||||
|
||||
// Plugin config path setup
|
||||
const CString pluginsPath = configurationManager->expand("${Kernel_3DVisualizationOgrePlugins}");
|
||||
|
||||
// Create LogManager to stop Ogre flooding the console and creating random files
|
||||
(*m_logManager) << Kernel::LogLevel_Info << "Ogre plugins path is " << pluginsPath << "\n";
|
||||
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << "+ Creating Ogre logmanager\n";
|
||||
Ogre::LogManager* logManager = new Ogre::LogManager();
|
||||
(*m_logManager) << Kernel::LogLevel_Info << "Ogre log to console : " << configurationManager->expandAsBoolean("${SSVEP_Ogre_LogToConsole}", false)
|
||||
<< "\n";
|
||||
const CString ogreLog = configurationManager->expand("${Path_Log}") + "/openvibe-ssvep-demo-ogre.log";
|
||||
(*m_logManager) << Kernel::LogLevel_Info << "Ogre log file : " << ogreLog << "\n";
|
||||
FS::Files::createParentPath(ogreLog);
|
||||
logManager->createLog(ogreLog.toASCIIString(), true, configurationManager->expandAsBoolean("${SSVEP_Ogre_LogToConsole}", false), false);
|
||||
|
||||
// Root creation
|
||||
const CString ogreCfg = configurationManager->expand("${Path_UserData}") + "/openvibe-ssvep-demo-ogre.cfg";
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << "+ m_root = new Ogre::Root(...)\n";
|
||||
(*m_logManager) << Kernel::LogLevel_Info << "Ogre cfg file : " << ogreCfg << "\n";
|
||||
m_root = new Ogre::Root(pluginsPath.toASCIIString(), ogreCfg.toASCIIString(), ogreLog.toASCIIString());
|
||||
|
||||
// Resource handling
|
||||
setupResources();
|
||||
|
||||
// Configuration from file or dialog window if needed
|
||||
if (!configure())
|
||||
{
|
||||
(*m_logManager) << Kernel::LogLevel_Fatal << "The configuration process ended unexpectedly.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// m_window = m_root->initialise(true);
|
||||
|
||||
|
||||
Ogre::NameValuePairList optionList;
|
||||
m_root->initialise(false);
|
||||
|
||||
optionList["vsync"] = "1";
|
||||
|
||||
m_window = m_root->createRenderWindow("SSVEP Stimulator", 640, 480, configurationManager->expandAsBoolean("${SSVEP_Ogre_FullScreen}", false), &optionList);
|
||||
m_windowWidth = m_window->getWidth();
|
||||
m_windowHeight = m_window->getHeight();
|
||||
|
||||
m_sceneManager = m_root->createSceneManager(Ogre::ST_GENERIC);
|
||||
m_camera = m_sceneManager->createCamera("SSVEPApplicationCamera");
|
||||
|
||||
Ogre::SceneManager* fillSceneManager = m_root->createSceneManager(Ogre::ST_GENERIC);
|
||||
Ogre::Camera* fillCamera = fillSceneManager->createCamera("SSVEPFillCamera");
|
||||
m_window->addViewport(fillCamera, 0);
|
||||
|
||||
m_viewport = m_window->addViewport(m_camera, 1);
|
||||
this->resizeViewport();
|
||||
// m_viewport->setBackgroundColour(Ogre::ColourValue(0.0, 0.5, 0.5));
|
||||
|
||||
m_camera->setAspectRatio(Ogre::Real(m_viewport->getActualWidth()) / Ogre::Real(m_viewport->getActualHeight()));
|
||||
|
||||
m_sceneNode = m_sceneManager->getRootSceneNode()->createChildSceneNode("SSVEPApplicationNode");
|
||||
|
||||
// initialize the painter object
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << "+ m_painter = new CBasicPainter(...)\n";
|
||||
m_painter = new CBasicPainter(this);
|
||||
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << " * initializing CEGUI\n";
|
||||
this->initCEGUI(configurationManager->expand("${Path_Log}") + "/openvibe-ssvep-demo-cegui.log");
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << " * CEGUI initialized\n";
|
||||
|
||||
// create the vector of stimulation frequencies
|
||||
|
||||
m_ScreenRefreshRate = double(configurationManager->expandAsUInteger("${SSVEP_ScreenRefreshRate}"));
|
||||
|
||||
(*m_logManager) << Kernel::LogLevel_Info << "Specified screen refresh rate :" << m_ScreenRefreshRate << "Hz\n";
|
||||
|
||||
size_t i = 1;
|
||||
|
||||
CIdentifier frequencyId = configurationManager->createConfigurationToken("SSVEP_FrequencyId", "1");
|
||||
|
||||
m_oFrequencies.push_back(std::pair<size_t, size_t>(30, 30));
|
||||
|
||||
while (configurationManager->lookUpConfigurationTokenIdentifier(configurationManager->expand("SSVEP_Frequency_${SSVEP_FrequencyId}"))
|
||||
!= CIdentifier::undefined())
|
||||
{
|
||||
std::pair<size_t, size_t> frequency;
|
||||
|
||||
double currentFrequency;
|
||||
|
||||
currentFrequency = double(configurationManager->expandAsFloat("${SSVEP_Frequency_${SSVEP_FrequencyId}}"));
|
||||
|
||||
const double approximatedFrameCount = m_ScreenRefreshRate / currentFrequency;
|
||||
|
||||
if (fabs(approximatedFrameCount - floor(approximatedFrameCount + 0.5)) < 0.003)
|
||||
{
|
||||
frequency.first = int(floor(approximatedFrameCount + 0.5)) / 2 + int(floor(approximatedFrameCount + 0.5)) % 2;
|
||||
frequency.second = int(floor(approximatedFrameCount + 0.5)) / 2;
|
||||
|
||||
(*m_logManager) << Kernel::LogLevel_Info << "Frequency number " << i << ": " << currentFrequency << "Hz / " << floor(approximatedFrameCount + 0.5)
|
||||
<< " ( " << frequency.first << ", " << frequency.second << ") frames @ " << m_ScreenRefreshRate << "fps\n";
|
||||
|
||||
m_oFrequencies.push_back(frequency);
|
||||
}
|
||||
else { (*m_logManager) << Kernel::LogLevel_Error << "The selected frequency (" << currentFrequency << "Hz) is not supported by your screen.\n"; }
|
||||
|
||||
configurationManager->releaseConfigurationToken(frequencyId);
|
||||
|
||||
frequencyId = configurationManager->createConfigurationToken("SSVEP_FrequencyId", std::to_string(++i).c_str());
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
bool CApplication::configure() const
|
||||
{
|
||||
if (! m_root->restoreConfig())
|
||||
{
|
||||
if (! m_root->showConfigDialog())
|
||||
{
|
||||
(*m_logManager) << Kernel::LogLevel_Error << "No configuration created from the dialog window.\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Set hard-coded parameters, VSync in particular
|
||||
m_root->getRenderSystem()->setConfigOption("VSync", "True");
|
||||
// m_root->getRenderSystem()->setConfigOption("Full Screen", "Yes");
|
||||
m_root->getRenderSystem()->setConfigOption("Video Mode", "640 x 480 @ 16-bit colour");
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
void CApplication::initCEGUI(const char* logFilename)
|
||||
{
|
||||
// Instantiate logger before bootstrapping the system, this way we will be able to get the log redirected
|
||||
if (!CEGUI::Logger::getSingletonPtr()) { new CEGUI::DefaultLogger(); } // singleton; instantiate only, no delete
|
||||
(*m_logManager) << Kernel::LogLevel_Info << "+ CEGUI log will be in '" << logFilename << "'\n";
|
||||
FS::Files::createParentPath(logFilename);
|
||||
CEGUI::Logger::getSingleton().setLogFilename(logFilename, false);
|
||||
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << "+ Creating CEGUI Ogre bootstrap\n";
|
||||
m_roGUIRenderer = &(CEGUI::OgreRenderer::bootstrapSystem(*m_window));
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << "+ Creating CEGUI Scheme Manager\n";
|
||||
|
||||
#if (CEGUI_VERSION_MAJOR > 0) || (CEGUI_VERSION_MINOR >= 8)
|
||||
CEGUI::SchemeManager::getSingleton().createFromFile(const_cast<CEGUI::utf8*>(reinterpret_cast<const CEGUI::utf8*>("TaharezLook-ov-0.8.scheme")));
|
||||
#else
|
||||
CEGUI::SchemeManager::getSingleton().create(reinterpret_cast<CEGUI::utf8*>("TaharezLook-ov.scheme"));
|
||||
#endif
|
||||
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << "+ Creating CEGUI WindowManager\n";
|
||||
m_guiManager = CEGUI::WindowManager::getSingletonPtr();
|
||||
m_sheet = m_guiManager->createWindow("DefaultWindow", "Sheet");
|
||||
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << "+ Setting CEGUI StyleSheet\n";
|
||||
|
||||
#if (CEGUI_VERSION_MAJOR > 0) || (CEGUI_VERSION_MINOR >= 8)
|
||||
CEGUI::System::getSingleton().getDefaultGUIContext().setRootWindow(m_sheet);
|
||||
#else
|
||||
CEGUI::System::getSingleton().setGUISheet(m_sheet);
|
||||
#endif
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
void CApplication::resizeViewport()
|
||||
{
|
||||
(*m_logManager) << Kernel::LogLevel_Trace << "Creating a new viewport\n";
|
||||
|
||||
const Ogre::uint32 size = MIN(m_windowWidth, m_windowHeight);
|
||||
(*m_logManager) << Kernel::LogLevel_Info << "New viewport size : " << size << "\n";
|
||||
|
||||
m_viewport->setDimensions(Ogre::Real(m_windowWidth - size) / Ogre::Real(m_windowWidth) / 2,
|
||||
Ogre::Real(m_windowHeight - size) / Ogre::Real(m_windowHeight) / 2,
|
||||
Ogre::Real(size) / Ogre::Real(m_windowWidth), Ogre::Real(size) / Ogre::Real(m_windowHeight));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
void CApplication::processFrame(const size_t /*currentFrame*/)
|
||||
{
|
||||
if (m_windowWidth != m_window->getWidth() || m_windowHeight != m_window->getHeight())
|
||||
{
|
||||
m_windowWidth = m_window->getWidth();
|
||||
m_windowHeight = m_window->getHeight();
|
||||
this->resizeViewport();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
void CApplication::setupResources()
|
||||
{
|
||||
Ogre::ResourceGroupManager::getSingleton().createResourceGroup("SSVEP");
|
||||
Ogre::ResourceGroupManager::getSingleton().addResourceLocation((Directories::getDataDir() + "/applications/ssvep-demo/resources").toASCIIString(),
|
||||
"FileSystem", "SSVEP");
|
||||
Ogre::ResourceGroupManager::getSingleton().addResourceLocation((Directories::getDataDir() + "/applications/ssvep-demo/resources/trainer").toASCIIString(),
|
||||
"FileSystem", "SSVEPTrainer");
|
||||
Ogre::ResourceGroupManager::getSingleton().addResourceLocation((Directories::getDataDir() + "/applications/ssvep-demo/resources/gui").toASCIIString(),
|
||||
"FileSystem", "CEGUI");
|
||||
Ogre::ResourceGroupManager::getSingleton().initialiseResourceGroup("SSVEP");
|
||||
Ogre::ResourceGroupManager::getSingleton().initialiseResourceGroup("SSVEPTrainer");
|
||||
Ogre::ResourceGroupManager::getSingleton().initialiseResourceGroup("CEGUI");
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
bool CApplication::frameStarted(const Ogre::FrameEvent& /*evt*/)
|
||||
{
|
||||
++m_currFrame;
|
||||
m_currFrame = m_currFrame % int(m_ScreenRefreshRate);
|
||||
this->processFrame(m_currFrame);
|
||||
for (size_t i = 0; i < m_oCommands.size(); ++i) { m_oCommands[i]->processFrame(); }
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
void CApplication::go()
|
||||
{
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << "Associating application as Ogre frame listener\n";
|
||||
|
||||
m_root->addFrameListener(this);
|
||||
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << "Entering Ogre rendering loop\n";
|
||||
m_root->startRendering();
|
||||
(*m_logManager) << Kernel::LogLevel_Debug << "Ogre rendering loop finished ... exiting\n";
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
void CApplication::stopExperiment()
|
||||
{
|
||||
(*m_logManager) << Kernel::LogLevel_Info << "[!] Experiment halting\n";
|
||||
this->exit();
|
||||
}
|
||||
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
#endif // TARGET_HAS_ThirdPartyOgre3D
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
#pragma once
|
||||
|
||||
#include "ovassvep_defines.h"
|
||||
|
||||
#include <openvibe/ov_all.h>
|
||||
#include <toolkit/ovtk_all.h>
|
||||
|
||||
#include <Ogre.h>
|
||||
#include <vector>
|
||||
#include <CEGUI.h>
|
||||
#if (CEGUI_VERSION_MAJOR > 0) || (CEGUI_VERSION_MINOR >= 8)
|
||||
#include <CEGUI/RendererModules/Ogre/Renderer.h>
|
||||
#else
|
||||
#include <RendererModules/Ogre/CEGUIOgreRenderer.h>
|
||||
#endif
|
||||
|
||||
#include "ovassvepICommand.h"
|
||||
#include "ovassvepCBasicPainter.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
class CApplication : public Ogre::FrameListener, public Ogre::WindowEventListener
|
||||
{
|
||||
public:
|
||||
CApplication() {}
|
||||
~CApplication() override;
|
||||
|
||||
void addCommand(ICommand* command) { m_oCommands.push_back(command); }
|
||||
virtual bool setup(Kernel::IKernelContext* poKernelContext);
|
||||
void go();
|
||||
|
||||
virtual void startExperiment() { (*m_logManager) << Kernel::LogLevel_Info << "[!] Experiment starting\n"; }
|
||||
virtual void stopExperiment();
|
||||
virtual void startFlickering() {}
|
||||
virtual void stopFlickering() {}
|
||||
|
||||
Ogre::RenderWindow* getWindow() const { return m_window; }
|
||||
Ogre::SceneManager* getSceneManager() const { return m_sceneManager; }
|
||||
Ogre::SceneNode* getSceneNode() const { return m_sceneNode; }
|
||||
CBasicPainter* getPainter() const { return m_painter; }
|
||||
void exit() { m_bContinueRendering = false; }
|
||||
Kernel::ILogManager& getLogManager() const { return (*m_logManager); }
|
||||
Kernel::IConfigurationManager* getConfigurationManager() const { return &(m_kernelCtx->getConfigurationManager()); }
|
||||
std::vector<std::pair<size_t, size_t>>* getFrequencies() { return &m_oFrequencies; }
|
||||
void resizeViewport();
|
||||
|
||||
protected:
|
||||
Kernel::IKernelContext* m_kernelCtx = nullptr;
|
||||
Kernel::ILogManager* m_logManager = nullptr;
|
||||
|
||||
double m_ScreenRefreshRate = 0;
|
||||
CBasicPainter* m_painter = nullptr;
|
||||
|
||||
bool m_bContinueRendering = true;
|
||||
size_t m_currFrame = 0;
|
||||
|
||||
Ogre::Root* m_root = nullptr;
|
||||
Ogre::SceneManager* m_sceneManager = nullptr;
|
||||
Ogre::Camera* m_camera = nullptr;
|
||||
Ogre::RenderWindow* m_window = nullptr;
|
||||
Ogre::Viewport* m_viewport = nullptr;
|
||||
Ogre::SceneNode* m_sceneNode = nullptr;
|
||||
|
||||
CEGUI::OgreRenderer* m_roGUIRenderer = nullptr;
|
||||
CEGUI::WindowManager* m_guiManager = nullptr;
|
||||
CEGUI::Window* m_sheet = nullptr;
|
||||
|
||||
std::vector<std::pair<size_t, size_t>> m_oFrequencies;
|
||||
|
||||
std::vector<ICommand*> m_oCommands;
|
||||
|
||||
virtual void processFrame(const size_t currentFrame);
|
||||
|
||||
bool frameRenderingQueued(const Ogre::FrameEvent& evt) override { return (m_bContinueRendering && !m_window->isClosed()); }
|
||||
bool frameStarted(const Ogre::FrameEvent& evt) override;
|
||||
|
||||
bool configure() const;
|
||||
static void setupResources();
|
||||
|
||||
|
||||
private:
|
||||
void initCEGUI(const char* logFilename);
|
||||
Ogre::uint32 m_windowWidth = 0;
|
||||
Ogre::uint32 m_windowHeight = 0;
|
||||
};
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
+162
@@ -0,0 +1,162 @@
|
||||
#if defined(TARGET_HAS_ThirdPartyOgre3D)
|
||||
|
||||
#include "ovassvepCBasicPainter.h"
|
||||
#include "ovassvepCApplication.h"
|
||||
|
||||
#if (OGRE_VERSION_MAJOR > 1) || ((OGRE_VERSION_MAJOR == 1) && (OGRE_VERSION_MINOR >= 9))
|
||||
#include "Overlay/OgreOverlayManager.h"
|
||||
#include "Overlay/OgreOverlaySystem.h"
|
||||
#endif
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
CBasicPainter::CBasicPainter(CApplication* application)
|
||||
: m_application(application), m_sceneManager(application->getSceneManager())
|
||||
{
|
||||
m_aabInf.setInfinite();
|
||||
|
||||
#if (OGRE_VERSION_MAJOR > 1) || ((OGRE_VERSION_MAJOR == 1) && (OGRE_VERSION_MINOR >= 9))
|
||||
// on Ogre 1.9, overlay system needs to be manually created
|
||||
Ogre::OverlaySystem* pOverlaySystem = OGRE_NEW Ogre::OverlaySystem();
|
||||
m_sceneManager->addRenderQueueListener(pOverlaySystem);
|
||||
#endif
|
||||
|
||||
m_overlayManager = Ogre::OverlayManager::getSingletonPtr();
|
||||
|
||||
(m_application->getLogManager()) << Kernel::LogLevel_Debug << " + Creating OverlayManager\n";
|
||||
Ogre::Overlay* overlay = m_overlayManager->create("TextOverlay");
|
||||
|
||||
|
||||
m_overlayContainer = dynamic_cast<Ogre::OverlayContainer*>(m_overlayManager->createOverlayElement("Panel", "TextContainer"));
|
||||
m_overlayContainer->setDimensions(1, 1);
|
||||
m_overlayContainer->setPosition(0, 0);
|
||||
|
||||
overlay->add2D(m_overlayContainer);
|
||||
overlay->show();
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
Ogre::ManualObject* CBasicPainter::paintRectangle(const Ogre::RealRect& oRectangle, const Ogre::ColourValue color, const int plane) const
|
||||
{
|
||||
Ogre::ManualObject* object = m_sceneManager->createManualObject();
|
||||
object->begin("BasicSurface/Diffuse", Ogre::RenderOperation::OT_TRIANGLE_FAN);
|
||||
object->setUseIdentityProjection(true);
|
||||
object->setUseIdentityView(true);
|
||||
|
||||
object->position(oRectangle.right, oRectangle.top, 0.0);
|
||||
object->colour(color);
|
||||
object->index(0);
|
||||
|
||||
object->position(oRectangle.left, oRectangle.top, 0.0);
|
||||
object->colour(color);
|
||||
object->index(1);
|
||||
|
||||
object->position(oRectangle.left, oRectangle.bottom, 0.0);
|
||||
object->colour(color);
|
||||
object->index(2);
|
||||
|
||||
object->position(oRectangle.right, oRectangle.bottom, 0.0);
|
||||
object->colour(color);
|
||||
object->index(3);
|
||||
|
||||
object->index(0);
|
||||
|
||||
object->end();
|
||||
|
||||
object->setBoundingBox(m_aabInf);
|
||||
object->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY - plane);
|
||||
|
||||
object->setVisible(true);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
Ogre::ManualObject* CBasicPainter::paintTriangle(const Point p1, const Point p2, const Point p3, const Ogre::ColourValue color, const int plane) const
|
||||
{
|
||||
Ogre::ManualObject* object = m_sceneManager->createManualObject();
|
||||
object->begin("BasicSurface/Diffuse", Ogre::RenderOperation::OT_TRIANGLE_FAN);
|
||||
object->setUseIdentityProjection(true);
|
||||
object->setUseIdentityView(true);
|
||||
|
||||
object->position(p1.m_X, p1.m_Y, 0.0);
|
||||
object->colour(color);
|
||||
object->index(0);
|
||||
|
||||
object->position(p2.m_X, p2.m_Y, 0.0);
|
||||
object->colour(color);
|
||||
object->index(1);
|
||||
|
||||
object->position(p3.m_X, p3.m_Y, 0.0);
|
||||
object->colour(color);
|
||||
object->index(2);
|
||||
|
||||
object->index(0);
|
||||
|
||||
object->end();
|
||||
|
||||
object->setBoundingBox(m_aabInf);
|
||||
object->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY - plane);
|
||||
|
||||
object->setVisible(true);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
Ogre::ManualObject* CBasicPainter::paintCircle(const Ogre::Real rX, const Ogre::Real rY, const Ogre::Real rR, const Ogre::ColourValue color,
|
||||
const bool bFilled, const int plane) const
|
||||
{
|
||||
Ogre::ManualObject* object = m_sceneManager->createManualObject();
|
||||
|
||||
if (bFilled) { object->begin("BasicSurface/Diffuse", Ogre::RenderOperation::OT_TRIANGLE_FAN); }
|
||||
else { object->begin("BasicSurface/Diffuse", Ogre::RenderOperation::OT_LINE_STRIP); }
|
||||
|
||||
object->setUseIdentityProjection(true);
|
||||
object->setUseIdentityView(true);
|
||||
|
||||
float const fAccuracy = 16;
|
||||
unsigned uiIndex = 0;
|
||||
|
||||
for (float theta = 0; theta <= 2 * Ogre::Math::PI; theta += Ogre::Math::PI / fAccuracy)
|
||||
{
|
||||
object->position(rX + rR * cos(theta), rY + rR * sin(theta), 0);
|
||||
object->colour(color);
|
||||
object->index(uiIndex++);
|
||||
}
|
||||
|
||||
object->index(0);
|
||||
|
||||
object->end();
|
||||
|
||||
object->setBoundingBox(m_aabInf);
|
||||
object->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY - plane);
|
||||
|
||||
object->setVisible(true);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
void CBasicPainter::paintText(const std::string& sID, const std::string& sText, const Ogre::Real rX, const Ogre::Real rY,
|
||||
const Ogre::Real rWidth, const Ogre::Real rHeight, const Ogre::ColourValue& color) const
|
||||
{
|
||||
Ogre::OverlayElement* text = m_overlayManager->createOverlayElement("TextArea", sID);
|
||||
text->setDimensions(rWidth, rHeight);
|
||||
text->setMetricsMode(Ogre::GMM_PIXELS);
|
||||
text->setPosition(rX, rY);
|
||||
text->setParameter("font_name", "DejaVu");
|
||||
text->setColour(color);
|
||||
text->setCaption(sText);
|
||||
m_overlayContainer->addChild(text);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include <Ogre.h>
|
||||
|
||||
#if (OGRE_VERSION_MAJOR > 1) || ((OGRE_VERSION_MAJOR == 1) && (OGRE_VERSION_MINOR >= 9))
|
||||
#include "Overlay/OgreOverlayContainer.h"
|
||||
#endif
|
||||
|
||||
#define SSVEP_DEFAULT_COLOUR Ogre::ColourValue(1.0f, 1.0f, 1.0f)
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
class CApplication;
|
||||
|
||||
class Point
|
||||
{
|
||||
public:
|
||||
Point(const float x, const float y) : m_X(x), m_Y(y) {}
|
||||
|
||||
float m_X = 0.0F, m_Y = 0.0F;
|
||||
};
|
||||
|
||||
class CBasicPainter
|
||||
{
|
||||
public:
|
||||
explicit CBasicPainter(CApplication* application);
|
||||
~CBasicPainter() {}
|
||||
|
||||
Ogre::ManualObject* paintRectangle(const Ogre::RealRect& oRectangle, const Ogre::ColourValue color = SSVEP_DEFAULT_COLOUR, const int plane = 1) const;
|
||||
Ogre::ManualObject* paintTriangle(const Point p1, const Point p2, const Point p3, const Ogre::ColourValue color = SSVEP_DEFAULT_COLOUR,
|
||||
const int plane = 1) const;
|
||||
Ogre::ManualObject* paintCircle(const Ogre::Real rX, const Ogre::Real rY, const Ogre::Real rR, const Ogre::ColourValue color = SSVEP_DEFAULT_COLOUR,
|
||||
const bool bFilled = true,
|
||||
const int plane = 1) const;
|
||||
|
||||
void paintText(const std::string& sID, const std::string& sText, const Ogre::Real rX, const Ogre::Real rY,
|
||||
const Ogre::Real rWidth, const Ogre::Real rHeight, const Ogre::ColourValue& color) const;
|
||||
|
||||
protected:
|
||||
CApplication* m_application = nullptr;
|
||||
Ogre::OverlayManager* m_overlayManager = nullptr;
|
||||
Ogre::OverlayContainer* m_overlayContainer = nullptr;
|
||||
Ogre::SceneManager* m_sceneManager = nullptr;
|
||||
Ogre::AxisAlignedBox m_aabInf;
|
||||
};
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
#if defined(TARGET_HAS_ThirdPartyOgre3D)
|
||||
|
||||
#include "ovassvepCCommandStartStop.h"
|
||||
#include "ovassvepCApplication.h"
|
||||
#include "ovassvepCVRPNServer.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
CCommandStartStop::CCommandStartStop(CApplication* application)
|
||||
: ICommandOIS(application)
|
||||
{
|
||||
m_vrpnServer = CVRPNServer::getInstance(application);
|
||||
m_vrpnServer->addButton("SSVEP_VRPN_StartStop", 2);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
CCommandStartStop::~CCommandStartStop()
|
||||
{
|
||||
m_application->getLogManager() << Kernel::LogLevel_Info << "End message sent\n";
|
||||
m_vrpnServer->changeButtonState("SSVEP_VRPN_StartStop", 1, 1);
|
||||
m_vrpnServer->processFrame();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
void CCommandStartStop::processFrame()
|
||||
{
|
||||
ICommandOIS::processFrame();
|
||||
m_vrpnServer->processFrame();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
void CCommandStartStop::receiveKeyPressedEvent(const OIS::KeyCode key)
|
||||
{
|
||||
if (key == OIS::KC_SPACE)
|
||||
{
|
||||
m_application->getLogManager() << Kernel::LogLevel_Info << "Start message sent\n";
|
||||
|
||||
m_vrpnServer->changeButtonState("SSVEP_VRPN_StartStop", 0, 1);
|
||||
}
|
||||
|
||||
if (key == OIS::KC_ESCAPE) { m_application->exit(); }
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
void CCommandStartStop::receiveKeyReleasedEvent(const OIS::KeyCode key)
|
||||
{
|
||||
if (key == OIS::KC_SPACE) { m_vrpnServer->changeButtonState("SSVEP_VRPN_StartStop", 0, 0); }
|
||||
}
|
||||
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
|
||||
#endif
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include "ovassvepICommandOIS.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
class CVRPNServer;
|
||||
|
||||
class CCommandStartStop final : public ICommandOIS
|
||||
{
|
||||
public:
|
||||
explicit CCommandStartStop(CApplication* application);
|
||||
~CCommandStartStop() override;
|
||||
|
||||
void processFrame() override;
|
||||
|
||||
void receiveKeyPressedEvent(OIS::KeyCode key) override;
|
||||
void receiveKeyReleasedEvent(OIS::KeyCode key) override;
|
||||
|
||||
private:
|
||||
CVRPNServer* m_vrpnServer = nullptr;
|
||||
};
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
#if defined(TARGET_HAS_ThirdPartyOgre3D)
|
||||
|
||||
#include "ovassvepCCommandStimulatorControl.h"
|
||||
#include "ovassvepCApplication.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
CCommandStimulatorControl::CCommandStimulatorControl(CApplication* application)
|
||||
: ICommandVRPNButton(application, "SSVEP_VRPN_StimulatorControl") {}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
void CCommandStimulatorControl::execute(const int button, const int /*state*/)
|
||||
{
|
||||
// only run the commands once, skip
|
||||
|
||||
switch (button)
|
||||
{
|
||||
case 0:
|
||||
m_application->startExperiment();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
m_application->stopExperiment();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
m_application->startFlickering();
|
||||
break;
|
||||
|
||||
case 3:
|
||||
m_application->stopFlickering();
|
||||
break;
|
||||
|
||||
default:
|
||||
m_application->getLogManager() << Kernel::LogLevel_Error << "[ERROR] Unknown command\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
#endif
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "ovassvepICommandVRPNButton.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
class CCommandStimulatorControl final : public ICommandVRPNButton
|
||||
{
|
||||
public:
|
||||
explicit CCommandStimulatorControl(CApplication* application);
|
||||
~CCommandStimulatorControl() override { }
|
||||
|
||||
void execute(const int button, const int state) override;
|
||||
};
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
#if defined(TARGET_HAS_ThirdPartyOgre3D)
|
||||
|
||||
#include "ovassvepCSSVEPFlickeringObject.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
|
||||
void CSSVEPFlickeringObject::setVisible(const bool visibility)
|
||||
{
|
||||
if ((!m_visible && visibility) || (m_visible && !visibility)) { m_objectNode->flipVisibility(); }
|
||||
m_visible = visibility;
|
||||
}
|
||||
|
||||
void CSSVEPFlickeringObject::processFrame()
|
||||
{
|
||||
if (m_currentFrame < m_litFrames) { this->setVisible(true); }
|
||||
else { this->setVisible(false); }
|
||||
|
||||
m_currentFrame++;
|
||||
|
||||
if (m_currentFrame == m_litFrames + m_darkFrames) { m_currentFrame = 0; }
|
||||
}
|
||||
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
#endif
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <openvibe/ov_all.h>
|
||||
#include <toolkit/ovtk_all.h>
|
||||
#include <Ogre.h>
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
class CSSVEPFlickeringObject
|
||||
{
|
||||
public:
|
||||
CSSVEPFlickeringObject(Ogre::SceneNode* objectNode, size_t litFrames, size_t darkFrames)
|
||||
: m_objectNode(objectNode), m_litFrames(litFrames), m_darkFrames(darkFrames) {}
|
||||
virtual ~CSSVEPFlickeringObject() {}
|
||||
|
||||
virtual void setVisible(bool visibility);
|
||||
virtual void processFrame();
|
||||
|
||||
protected:
|
||||
Ogre::SceneNode* m_objectNode = nullptr;
|
||||
size_t m_currentFrame = 0;
|
||||
size_t m_litFrames = 0;
|
||||
size_t m_darkFrames = 0;
|
||||
|
||||
private:
|
||||
|
||||
bool m_visible = true;
|
||||
};
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
#if defined(TARGET_HAS_ThirdPartyOgre3D)
|
||||
|
||||
#include "ovassvepCVRPNServer.h"
|
||||
#include "ovassvepCApplication.h"
|
||||
|
||||
#include <vrpn_Connection.h>
|
||||
#include <vrpn_Button.h>
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
|
||||
CVRPNServer* CVRPNServer::m_vrpnServerInstance = nullptr;
|
||||
CApplication* CVRPNServer::m_application = nullptr;
|
||||
|
||||
CVRPNServer::CVRPNServer(CApplication* application)
|
||||
{
|
||||
m_application = application;
|
||||
|
||||
const int port = int(m_application->getConfigurationManager()->expandAsInteger("${VRPN_ExternalServerPort}"));
|
||||
|
||||
m_application->getLogManager() << Kernel::LogLevel_Debug << "VRPN SERVER PORT :" << port << "\n";
|
||||
m_connection = vrpn_create_server_connection(port);
|
||||
}
|
||||
|
||||
CVRPNServer* CVRPNServer::getInstance(CApplication* application)
|
||||
{
|
||||
if (m_vrpnServerInstance == nullptr) { m_vrpnServerInstance = new CVRPNServer(application); }
|
||||
return m_vrpnServerInstance;
|
||||
}
|
||||
|
||||
void CVRPNServer::addButton(const CString& name, const int buttonCount)
|
||||
{
|
||||
m_buttonServer.insert(
|
||||
std::pair<std::string, vrpn_Button_Server*>(name.toASCIIString(), new vrpn_Button_Server(name.toASCIIString(), m_connection, buttonCount)));
|
||||
m_buttonCache[name.toASCIIString()].clear();
|
||||
m_buttonCache[name.toASCIIString()].resize(buttonCount);
|
||||
}
|
||||
|
||||
void CVRPNServer::processFrame()
|
||||
{
|
||||
for (auto& it : m_buttonServer) { it.second->mainloop(); }
|
||||
m_connection->mainloop();
|
||||
}
|
||||
|
||||
void CVRPNServer::changeButtonState(const std::string& name, const int index, const int state)
|
||||
{
|
||||
m_buttonServer[name]->set_button(index, state);
|
||||
m_buttonCache[name][index] = state;
|
||||
}
|
||||
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
#endif
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include <openvibe/ov_all.h>
|
||||
#include <toolkit/ovtk_all.h>
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
class vrpn_Connection;
|
||||
class vrpn_Button_Server;
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
class CApplication;
|
||||
|
||||
class CVRPNServer
|
||||
{
|
||||
public:
|
||||
static CVRPNServer* getInstance(CApplication* application);
|
||||
~CVRPNServer() = default;
|
||||
void processFrame();
|
||||
|
||||
void addButton(const CString& name, int buttonCount);
|
||||
void changeButtonState(const std::string& name, int index, int state);
|
||||
int getButtonState(const std::string& name, const int index) { return m_buttonCache[name][index]; }
|
||||
|
||||
private:
|
||||
static CVRPNServer* m_vrpnServerInstance;
|
||||
static CApplication* m_application;
|
||||
|
||||
explicit CVRPNServer(CApplication* application);
|
||||
|
||||
vrpn_Connection* m_connection = nullptr;
|
||||
std::map<std::string, vrpn_Button_Server*> m_buttonServer;
|
||||
std::map<std::string, std::vector<int>> m_buttonCache;
|
||||
};
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <openvibe/ov_all.h>
|
||||
#include <toolkit/ovtk_all.h>
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
class CApplication;
|
||||
|
||||
class ICommand
|
||||
{
|
||||
public:
|
||||
explicit ICommand(CApplication* application) : m_application(application) {}
|
||||
virtual ~ICommand() { }
|
||||
virtual void processFrame() = 0;
|
||||
|
||||
protected:
|
||||
CApplication* m_application = nullptr;
|
||||
};
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
#if defined(TARGET_HAS_ThirdPartyOgre3D)
|
||||
|
||||
#include "ovassvepICommandOIS.h"
|
||||
#include "ovassvepCApplication.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
|
||||
OIS::InputManager* ICommandOIS::m_inputManager = nullptr;
|
||||
OIS::Keyboard* ICommandOIS::m_keyboard = nullptr;
|
||||
|
||||
int ICommandOIS::m_nInstance = 0;
|
||||
std::vector<ICommandOIS*> ICommandOIS::m_instances;
|
||||
|
||||
|
||||
ICommandOIS::ICommandOIS(CApplication* application) : ICommand(application)
|
||||
{
|
||||
if (m_keyboard == nullptr)
|
||||
{
|
||||
OIS::ParamList paramList;
|
||||
std::ostringstream windowHandleString;
|
||||
size_t windowHandle;
|
||||
|
||||
|
||||
m_application->getWindow()->getCustomAttribute("WINDOW", &windowHandle);
|
||||
|
||||
windowHandleString << windowHandle;
|
||||
|
||||
paramList.insert(std::make_pair(std::string("WINDOW"), windowHandleString.str()));
|
||||
paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), "false"));
|
||||
|
||||
m_inputManager = OIS::InputManager::createInputSystem(paramList);
|
||||
|
||||
m_keyboard = dynamic_cast<OIS::Keyboard*>(m_inputManager->createInputObject(OIS::OISKeyboard, true));
|
||||
|
||||
m_keyboard->setEventCallback(this);
|
||||
}
|
||||
|
||||
m_nInstance++;
|
||||
m_instances.push_back(this);
|
||||
}
|
||||
|
||||
ICommandOIS::~ICommandOIS()
|
||||
{
|
||||
--m_nInstance;
|
||||
|
||||
if (m_nInstance == 0)
|
||||
{
|
||||
if (m_inputManager != nullptr)
|
||||
{
|
||||
if (m_keyboard != nullptr)
|
||||
{
|
||||
m_application->getLogManager() << Kernel::LogLevel_Debug << "- destroy m_keyboard\n";
|
||||
m_inputManager->destroyInputObject(m_keyboard);
|
||||
m_keyboard = nullptr;
|
||||
}
|
||||
|
||||
m_inputManager->destroyInputSystem(m_inputManager);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ICommandOIS::keyPressed(const OIS::KeyEvent& event)
|
||||
{
|
||||
for (size_t i = 0; i < m_instances.size(); ++i) { m_instances[i]->receiveKeyPressedEvent(event.key); }
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ICommandOIS::keyReleased(const OIS::KeyEvent& event)
|
||||
{
|
||||
for (size_t i = 0; i < m_instances.size(); ++i) { m_instances[i]->receiveKeyReleasedEvent(event.key); }
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
#endif
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <OIS.h>
|
||||
#include <OISKeyboard.h>
|
||||
#include "ovassvepICommand.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
class ICommandOIS : public ICommand, OIS::KeyListener
|
||||
{
|
||||
static std::vector<ICommandOIS*> m_instances;
|
||||
static int m_nInstance;
|
||||
|
||||
protected:
|
||||
static OIS::InputManager* m_inputManager;
|
||||
static OIS::Keyboard* m_keyboard;
|
||||
|
||||
public:
|
||||
explicit ICommandOIS(CApplication* application);
|
||||
~ICommandOIS() override;
|
||||
|
||||
void processFrame() override { m_keyboard->capture(); }
|
||||
|
||||
protected:
|
||||
virtual void receiveKeyPressedEvent(OIS::KeyCode key) = 0;
|
||||
virtual void receiveKeyReleasedEvent(OIS::KeyCode key) = 0;
|
||||
|
||||
private:
|
||||
bool keyPressed(const OIS::KeyEvent& event) override;
|
||||
bool keyReleased(const OIS::KeyEvent& event) override;
|
||||
};
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
#if defined(TARGET_HAS_ThirdPartyOgre3D)
|
||||
|
||||
#include "ovassvepICommandVRPNButton.h"
|
||||
#include "ovassvepCApplication.h"
|
||||
|
||||
#include <vrpn_Connection.h>
|
||||
#include <vrpn_Button.h>
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
|
||||
static void VRPN_CALLBACK ssvep_vrpn_callback_button(void* command, const vrpn_BUTTONCB button)
|
||||
{
|
||||
static_cast<ICommandVRPNButton*>(command)->execute(button.button, button.state);
|
||||
}
|
||||
|
||||
ICommandVRPNButton::ICommandVRPNButton(CApplication* application, const CString& name)
|
||||
: ICommand(application)
|
||||
{
|
||||
Kernel::IConfigurationManager* configManager = application->getConfigurationManager();
|
||||
const std::string buttonName = std::string(name.toASCIIString()) + "@" + (configManager->expand("${SSVEP_VRPNHost}")).toASCIIString();
|
||||
m_application->getLogManager() << Kernel::LogLevel_Debug << "+ m_vrpnButton = new vrpn_Button_Remote(" << buttonName << ")\n";
|
||||
|
||||
m_vrpnButton = new vrpn_Button_Remote(buttonName.c_str());
|
||||
m_vrpnButton->register_change_handler(static_cast<void*>(this), ssvep_vrpn_callback_button);
|
||||
}
|
||||
|
||||
ICommandVRPNButton::~ICommandVRPNButton()
|
||||
{
|
||||
m_application->getLogManager() << Kernel::LogLevel_Debug << "- delete m_vrpnButton\n";
|
||||
delete m_vrpnButton;
|
||||
}
|
||||
|
||||
void ICommandVRPNButton::processFrame() { m_vrpnButton->mainloop(); }
|
||||
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
|
||||
#endif
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "ovassvepICommand.h"
|
||||
|
||||
class vrpn_Button_Remote;
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace SSVEP {
|
||||
class ICommandVRPNButton : public ICommand
|
||||
{
|
||||
public:
|
||||
ICommandVRPNButton(CApplication* application, const CString& name);
|
||||
~ICommandVRPNButton() override;
|
||||
|
||||
void processFrame() override;
|
||||
virtual void execute(const int button, const int state) = 0;
|
||||
|
||||
protected:
|
||||
vrpn_Button_Remote* m_vrpnButton = nullptr;
|
||||
};
|
||||
} // namespace SSVEP
|
||||
} // namespace OpenViBE
|
||||
+1
@@ -0,0 +1 @@
|
||||
#pragma once
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
#if defined(TARGET_HAS_ThirdPartyOgre3D)
|
||||
|
||||
#include "ovassvep_defines.h"
|
||||
#include <openvibe/ov_all.h>
|
||||
#include <toolkit/ovtk_all.h>
|
||||
|
||||
#include "ovassvepCApplication.h"
|
||||
#include "Trainer/ovassvepCTrainerApplication.h"
|
||||
#include "Shooter/ovassvepCShooterApplication.h"
|
||||
|
||||
int main(const int argc, char** argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
std::cout << "Usage: " << argv[0] << " [trainer|shooter]\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// initialize the OpenViBE kernel
|
||||
|
||||
OpenViBE::CKernelLoader kernelLoader;
|
||||
OpenViBE::Kernel::IKernelDesc* kernelDesc = nullptr;
|
||||
|
||||
OpenViBE::CString error;
|
||||
#if defined TARGET_OS_Windows
|
||||
const OpenViBE::CString kernelFile = OpenViBE::Directories::getLibDir() + "/openvibe-kernel.dll";
|
||||
#else
|
||||
const OpenViBE::CString kernelFile = OpenViBE::Directories::getLibDir() + "/libopenvibe-kernel.so";
|
||||
#endif
|
||||
if (!kernelLoader.load(kernelFile, &error))
|
||||
{
|
||||
std::cout << "[ FAILED ] Error loading kernel (" << error << ")" << " from [" << kernelFile << "]\n";
|
||||
return (1);
|
||||
}
|
||||
std::cout << "[ INF ] Kernel module loaded, trying to get kernel descriptor\n";
|
||||
|
||||
kernelLoader.initialize();
|
||||
kernelLoader.getKernelDesc(kernelDesc);
|
||||
|
||||
if (!kernelDesc)
|
||||
{
|
||||
std::cout << "[ FAILED ] No kernel descriptor\n";
|
||||
return (1);
|
||||
}
|
||||
std::cout << "[ INF ] Got kernel descriptor, trying to create kernel\n";
|
||||
|
||||
OpenViBE::Kernel::IKernelContext* kernelContext = kernelDesc->createKernel("ssvep-demo", OpenViBE::Directories::getDataDir() + "/kernel/openvibe.conf");
|
||||
|
||||
if (!kernelContext)
|
||||
{
|
||||
std::cout << "[ FAILED ] No kernel created by kernel descriptor\n";
|
||||
return (1);
|
||||
}
|
||||
kernelContext->initialize();
|
||||
|
||||
OpenViBE::Toolkit::initialize(*kernelContext);
|
||||
|
||||
OpenViBE::Kernel::IConfigurationManager* configManager = &(kernelContext->getConfigurationManager());
|
||||
configManager->createConfigurationToken("SSVEP_ApplicationDescriptor", OpenViBE::CString(argv[1]));
|
||||
|
||||
const OpenViBE::CString configFile = configManager->expand("${Path_Data}/applications/ssvep-demo/openvibe-ssvep-demo.conf");
|
||||
configManager->addConfigurationFromFile(configFile);
|
||||
|
||||
OpenViBE::Kernel::ILogManager* logManager = &(kernelContext->getLogManager());
|
||||
|
||||
if (configManager->expand("$Env{OGRE_HOME}").length() == 0)
|
||||
{
|
||||
std::cout << "Error: OGRE_HOME environment variable is not set, this likely will not work.\n";
|
||||
// Don't exit as we don't have any way to get the return value seen in designer
|
||||
}
|
||||
|
||||
// We need this to address BuildType no longer in SDK 2.0
|
||||
#if defined(DEBUG)
|
||||
configManager->addOrReplaceConfigurationToken("BuildType", "Debug");
|
||||
#else
|
||||
configManager->addOrReplaceConfigurationToken("BuildType", "Release");
|
||||
#endif
|
||||
|
||||
OpenViBE::SSVEP::CApplication* app;
|
||||
|
||||
const OpenViBE::CString applicationType = configManager->expand("${SSVEP_ApplicationType}");
|
||||
|
||||
(*logManager) << OpenViBE::Kernel::LogLevel_Info << "Selected Application : '" << applicationType.toASCIIString() << "'\n";
|
||||
|
||||
|
||||
if (applicationType == OpenViBE::CString("trainer"))
|
||||
{
|
||||
(*logManager) << OpenViBE::Kernel::LogLevel_Debug << "+ app = new SSVEP::CTrainerApplication(...)\n";
|
||||
app = new OpenViBE::SSVEP::CTrainerApplication();
|
||||
}
|
||||
else if (applicationType == OpenViBE::CString("shooter"))
|
||||
{
|
||||
(*logManager) << OpenViBE::Kernel::LogLevel_Debug << "+ app = new SSVEP::CShooterApplication(...)\n";
|
||||
app = new OpenViBE::SSVEP::CShooterApplication();
|
||||
}
|
||||
else
|
||||
{
|
||||
(*logManager) << OpenViBE::Kernel::LogLevel_Error << "Wrong application identifier specified: '" << applicationType << "'\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!app->setup(kernelContext))
|
||||
{
|
||||
std::cout << "Aborting\n";
|
||||
delete app;
|
||||
return -1;
|
||||
}
|
||||
|
||||
app->go();
|
||||
|
||||
(*logManager) << OpenViBE::Kernel::LogLevel_Debug << "- app\n";
|
||||
delete app;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
std::cout << "SSVEP demo has not been compiled as it depends on Ogre (missing/disabled)\n";
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user