|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378 |
- #if defined(TARGET_HAS_ThirdPartyOgre3DTerrain)
-
- #include "ovamsCApplication.h"
- #include <cmath>
- #include <algorithm>
-
- #include "fs/Files.h"
-
- namespace OpenViBE {
- namespace SSVEPMindShooter {
-
- CApplication::~CApplication()
- {
- delete m_StimulusSender;
-
- if (m_painter != nullptr)
- {
- (*m_logManager) << Kernel::LogLevel_Debug << "- m_painter\n";
- delete m_painter;
- m_painter = nullptr;
- }
-
- for (auto it = m_commands.begin();
- it != m_commands.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* configManager = &(m_kernelCtx->getConfigurationManager());
-
- (*m_logManager) << Kernel::LogLevel_Debug << " * CApplication::setup()\n";
-
- // Plugin config path setup
- Ogre::String pluginsPath;
-
- #if defined TARGET_OS_Windows
- #if defined TARGET_BUILDTYPE_Debug
- pluginsPath = std::string(getenv("OGRE_HOME")) + std::string("/bin/debug/plugins_d.cfg");
- #else
- pluginsPath = std::string(getenv("OGRE_HOME")) + std::string("/bin/release/plugins.cfg");
- #endif
- #elif defined TARGET_OS_Linux
- pluginsPath = std::string(configManager->expand("${Path_Data}/openvibe-ogre-plugins.cfg").toASCIIString());
- #else
- #error "No OS defined."
- #endif
-
- // Create LogManager to stop Ogre flooding the console and creating random files
-
-
- (*m_logManager) << Kernel::LogLevel_Debug << "+ Creating Ogre logmanager\n";
- Ogre::LogManager* logManager = new Ogre::LogManager();
- (*m_logManager) << Kernel::LogLevel_Info << "Log level: " << configManager->expand("${Kernel_ConsoleLogLevel}") << "\n";
- (*m_logManager) << Kernel::LogLevel_Info << "Application will output Ogre console log : " << configManager->expandAsBoolean(
- "${SSVEP_Ogre_LogToConsole}", false) << "\n";
- const CString ogreLog = configManager->expand("${SSVEP_UserDataFolder}/mind-shooter-[$core{date}-$core{time}]-ogre.log");
- (*m_logManager) << Kernel::LogLevel_Info << "Ogre log file : " << ogreLog << "\n";
- FS::Files::createParentPath(ogreLog);
- logManager->createLog(ogreLog.toASCIIString(), true, configManager->expandAsBoolean("${SSVEP_Ogre_LogToConsole}", false), false);
-
- // Root creation
- const CString ogreCfg = configManager->expand("${SSVEP_MindShooterScenarioPath}") + "/appconf/mind-shooter-ogre.conf";
- (*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, ogreCfg.toASCIIString(), ogreLog.toASCIIString());
-
- // Resource handling
- this->setupResources();
-
- // Configuration from file or dialog window if needed
- if (!this->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";
-
- const int width = int(configManager->expandAsInteger("${SSVEP_Ogre_ScreenWidth}", 800));
- const int height = int(configManager->expandAsInteger("${SSVEP_Ogre_ScreenHeight}", 600));
- const bool fullScreen = configManager->expandAsBoolean("${SSVEP_Ogre_FullScreen}", false);
-
- (*m_logManager) << Kernel::LogLevel_Info << "Width : " << width << " Height : " << height << " Fullscreen : " << fullScreen << "\n";
-
- //m_window = m_root->createRenderWindow("SSVEP Stimulator", 960, 600, false, &l_oOptionList);
- m_window = m_root->createRenderWindow("SSVEP Stimulator", width, height, fullScreen, &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");
- m_cameraNode = m_sceneManager->getRootSceneNode()->createChildSceneNode();
- m_cameraNode->attachObject(m_camera);
-
- 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(configManager->expand("${SSVEP_UserDataFolder}/mind-shooter-[$core{date}-$core{time}]-cegui.log"));
-
- (*m_logManager) << Kernel::LogLevel_Debug << " * CEGUI initialized\n";
-
- // create the vector of stimulation frequencies
-
- m_screenRefreshRate = double(configManager->expandAsUInteger("${SSVEP_ScreenRefreshRate}", 60));
- (*m_logManager) << Kernel::LogLevel_Info << "Specified screen refresh rate :" << m_screenRefreshRate << "Hz\n";
-
- if (m_screenRefreshRate > 64)
- {
- (*m_logManager) << Kernel::LogLevel_Error << "Screen refresh rate exceeds the max bit pattern length of 64\n";
- return false;
- }
-
- size_t i = 1;
-
- CIdentifier frequencyId = configManager->createConfigurationToken("SSVEP_FrequencyId", "1");
-
- m_frequencies.push_back(30);
-
- size_t patternsLoaded = 0;
-
- // TODO: Load patterns
-
- // Load pre-defined stimulation patterns (binary encoded dark/light frames inside a 64bit integer)
- while (configManager->lookUpConfigurationTokenIdentifier(configManager->expand("SSVEP_Pattern_${SSVEP_FrequencyId}")) !=
- CIdentifier::undefined())
- {
- size_t stimulationPattern = size_t(configManager->expandAsInteger("${SSVEP_Pattern_${SSVEP_FrequencyId}}"));
-
- (*m_logManager) << Kernel::LogLevel_Info << "Pattern number " << i << " pattern : " << stimulationPattern << "\n";
- m_frequencies[i] = stimulationPattern;
-
- configManager->releaseConfigurationToken(frequencyId);
-
- frequencyId = configManager->createConfigurationToken("SSVEP_FrequencyId", std::to_string(++i).c_str());
- patternsLoaded++;
- }
-
-
- // Generate patterns from frequencies
- if (patternsLoaded == 0)
- {
- // Load frequencies
- while (configManager->lookUpConfigurationTokenIdentifier(configManager->expand("SSVEP_Frequency_${SSVEP_FrequencyId}")) != CIdentifier::undefined())
- {
- const double currentFrequency = double(configManager->expandAsFloat("${SSVEP_Frequency_${SSVEP_FrequencyId}}"));
- const double approximatedFrameCount = m_screenRefreshRate / currentFrequency;
- const size_t nRoundedFrame = size_t(floor(approximatedFrameCount + 0.5));
-
- // test if the desired frequency can be reasonably created on the screen
- if (fabs(approximatedFrameCount - nRoundedFrame) < 0.003)
- {
- const size_t framesL = nRoundedFrame / 2 + nRoundedFrame % 2;
- const size_t framesD = nRoundedFrame / 2;
-
- // the pattern is procedurally generated and always starts by a 1,
- // following by as many 0s as there are Dark frames and finally as many 1s as there are Light frames.
- // The frame loop will consume one bit per frame from the right and then reset when the reset marker is hit.
-
- // Start with the reset marker
- uint64_t stimulationPattern = 1;
-
- // The dark zeroes
- stimulationPattern <<= framesD;
-
- // The light ones
- for (size_t j = 0; j < framesL; ++j)
- {
- stimulationPattern <<= 1;
- stimulationPattern += 1;
- }
-
- (*m_logManager) << Kernel::LogLevel_Info << "Frequency number " << i << ": " << currentFrequency << "Hz / " <<
- floor(approximatedFrameCount + 0.5) << " ( " << framesL << " light, " << framesD << " dark) frames @ " <<
- m_screenRefreshRate << "fps\n";
- (*m_logManager) << Kernel::LogLevel_Info << "Frequency number " << i << " pattern : " << stimulationPattern << "\n";
-
- std::stringstream binary;
- binary << std::bitset<64>(stimulationPattern);
- (*m_logManager) << Kernel::LogLevel_Info << "Frequency number " << i << " binary : " << binary.str() << "\n";
-
- m_frequencies.push_back(stimulationPattern);
- patternsLoaded++;
- }
- else { (*m_logManager) << Kernel::LogLevel_Error << "The selected frequency (" << currentFrequency << "Hz) is not supported by your screen.\n"; }
-
- configManager->releaseConfigurationToken(frequencyId);
-
- frequencyId = configManager->createConfigurationToken("SSVEP_FrequencyId", std::to_string(++i).c_str());
- }
- }
-
- if (!patternsLoaded)
- {
- (*m_logManager) << Kernel::LogLevel_Error << "No flashing frequencies loaded. Have you run the SSVEP Impact Shooter configuring scenario?\n";
- (*m_logManager) << Kernel::LogLevel_Error << "Are you running this app from the correct scenario with the previous stages run properly?\n";
- return false;
- }
-
- m_StimulusSender->connect("localhost", "15361");
-
- return true;
- }
-
- // Set hard-coded parameters, VSync in particular, for all known render systems
- void CApplication::setOgreParameters() const
- {
- const bool fullScreen = m_kernelCtx->getConfigurationManager().expandAsBoolean("${SSVEP_Ogre_FullScreen}", false);
- const Ogre::RenderSystemList& list = m_root->getAvailableRenderers();
- for (size_t i = 0; i < list.size(); ++i)
- {
- list[i]->setConfigOption("VSync", "Yes");
- list[i]->setConfigOption("Full Screen", (fullScreen ? "Yes" : "No"));
- }
- }
-
- bool CApplication::configure() const
- {
- if (! m_root->restoreConfig())
- {
- setOgreParameters();
-
- if (! m_root->showConfigDialog())
- {
- (*m_logManager) << Kernel::LogLevel_Error << "No configuration created from the dialog window.\n";
- return false;
- }
- }
-
- // Override 'unsuitable' user choices
- (*m_logManager) << Kernel::LogLevel_Info << "Forcing vsync and using fullscreen settings from configuration scenario.\n";
- setOgreParameters();
-
- // Save the config again after we have forced the params, otherwise the conf file looks misleading
- m_root->saveConfig();
-
- 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_guiRenderer = &(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((CEGUI::utf8*)"TaharezLook-ov.scheme");
- #endif
-
- (*m_logManager) << Kernel::LogLevel_Debug << "+ Creating CEGUI WindowManager\n";
- m_guiWindowManager = CEGUI::WindowManager::getSingletonPtr();
- m_sheet = m_guiWindowManager->createWindow("DefaultWindow", "RootSheet");
-
- (*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() const
- {
- (*m_logManager) << Kernel::LogLevel_Trace << "Creating a new viewport\n";
-
- const Ogre::uint32 viewportSize = std::min(m_windowWidth, m_windowHeight);
- (*m_logManager) << Kernel::LogLevel_Info << "New viewport size : " << viewportSize << "\n";
-
- m_viewport->setDimensions(Ogre::Real(m_windowWidth - viewportSize) / Ogre::Real(m_windowWidth) / 2,
- Ogre::Real(m_windowHeight - viewportSize) / Ogre::Real(m_windowHeight) / 2,
- Ogre::Real(viewportSize) / Ogre::Real(m_windowWidth),
- Ogre::Real(viewportSize) / Ogre::Real(m_windowHeight));
- }
-
- void CApplication::setupResources() const
- {
- Kernel::IConfigurationManager* configManager = &(m_kernelCtx->getConfigurationManager());
-
- Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
- configManager->expand("${Path_Data}/applications/${SSVEP_MindShooterFolderName}/resources").toASCIIString(), "FileSystem", "SSVEP");
- Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
- configManager->expand("${Path_Data}/applications/${SSVEP_MindShooterFolderName}/resources/generic").toASCIIString(), "FileSystem", "SSVEPGeneric");
- Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
- configManager->expand("${Path_Data}/applications/${SSVEP_MindShooterFolderName}/resources/generic/textures").toASCIIString(), "FileSystem",
- "SSVEPGeneric");
- Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
- configManager->expand("${Path_Data}/applications/${SSVEP_MindShooterFolderName}/resources/trainer").toASCIIString(), "FileSystem", "SSVEPTrainer");
- Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
- configManager->expand("${Path_Data}/applications/${SSVEP_MindShooterFolderName}/resources/gui").toASCIIString(), "FileSystem", "CEGUI");
- Ogre::ResourceGroupManager::getSingleton().addResourceLocation(CString(m_ScenarioDir + "/appconf/materials").toASCIIString(), "FileSystem", "CEGUI");
-
- Ogre::ResourceGroupManager::getSingleton().initialiseResourceGroup("SSVEP");
- Ogre::ResourceGroupManager::getSingleton().initialiseResourceGroup("SSVEPTrainer");
- Ogre::ResourceGroupManager::getSingleton().initialiseResourceGroup("SSVEPGeneric");
- Ogre::ResourceGroupManager::getSingleton().initialiseResourceGroup("CEGUI");
- }
-
- bool CApplication::frameStarted(const Ogre::FrameEvent& /*evt*/)
- {
- m_currentFrame++;
- m_currentFrame %= int(m_screenRefreshRate);
-
-
- for (size_t i = 0; i < m_commands.size(); ++i) { m_commands[i]->processFrame(); }
-
- this->processFrame(m_currentFrame);
-
- 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 SSVEPMindShooter
- } // namespace OpenViBE
- #endif
|