![]() |
VR-Forces 4.0.4 Class Documentation
|
The Distributed Simulation Tutorial takes you step-by-step through the process of creating a simple VR-Vantage plugin that implements a simulation driver.
We will look at using either threaded or non-threaded connections to listen for simulation data, and then according to the data received, adding agents to the scene graph. The first ten projects in this tutorial deal with small parts of this process, and the final project will tie these parts together by listening for data interactions and accordingly making changes to the scene.
Project 1 in the Distributed Simulation tutorial takes a look at how to create a VR-Vantage plugin which instantiates a driver class to interact with the application. The code is minimal, and simple to understand. All subsequent projects will be built using this project as a template.
Creating a VR-Vantage plugin
To create a plugin for VR-Vantage, we will need code that can be called by the Vantage application to initialize the plugin. The initDeModule() function is exported as the point of entry for plugin initialization, and when invoked, is passed a pointer to the display engine (DE). Note that the driver which is to be created by the plugin cannot be correctly instantiated until the display engine (DE) has been initialized. Therefore, the initDeModule() calls a local init() function which registers a callback with the post initialize signal of the display engine. When the display engine emits that signal, the callback disconnects itself from the signal and then instantiates an object of the desired driver class. This object is then added to the driver manager so that it will appear in the list of drivers in the application's Drivers Panel.
The files which define this functionality are as follows:
Creating a custom VR-Vantage driver class
A custom VR-Vantage driver class is derived from the DtDriver class, and is responsible for defining three pure virtual functions: onStart(), onTick(), and onStop(). onStart() is called each time the driver is started in the VR-Vantage application and onStop() is called each time the driver is stopped. onTick() is called after the driver has been started each time the simulation loop gives the driver a chance to do something.
For this project, we have made it so that both onStart() and onStop() print a message to the console window (monitor window) to indicate that they have been called. Whereas these messages are printed on their own separate lines, onTick() prints out only a dot with no newline added. Therefore, a running driver will continually print dots to the console window until the driver has been stopped.
The files which define this functionality are as follows:
The bin directory for the VR-Vantage installation contains both *.bat (for Windows) and *.sh (For Linux) script files which can be used to start the application with the given plugin. Each of these files contains a one-line command, which instantiates the application, and passes it a --plugin option, followed by the path to the plugin library file.
Running either the tutorialDistributedSimulation1d.bat or tutorialDistributedSimulation1.sh script file will start the VR-Vantage Stealth application, passing it the path to the correct plugin library file. For the former script, the file will be examples/plugins/debug/tutorialDistributedSimulation1d.dll, whereas for the latter, the file will be examples/plugins/release/tutorialDistributedSimulation1.so. Note that, for Windows, we are choosing to run the script file with the character 'd' at the end of the name. This will start a debug version which will ensure that the printouts to console will be seen, whereas, to run the release version on Windows will not show these printouts.
Invoke the script file to start the application. Stealth startup will be completed when you see the "Choose a Terrain" dialog window. Follow these instructions to test the plugin:
[Create a Non-Threaded Connection >>]
// /****************************************************************************** // ** Copyright (c) 2011 MAK Technologies, Inc. // ** All rights reserved. // ******************************************************************************/ #pragma once #include <vrvCore/DtDriver.h> using namespace makVrv; namespace makVrv { namespace tutorialDistributedSimulation1 { class DistributedSimulationDriver : public DtDriver { public: DistributedSimulationDriver(DtAgentManager& agentManager, const std::string& instanceName); virtual ~DistributedSimulationDriver(); virtual const std::string& className() const; protected: virtual bool onStart(); virtual bool onStop(); virtual bool onTick(); }; } }
// /****************************************************************************** // ** Copyright (c) 2011 MAK Technologies, Inc. // ** All rights reserved. // ******************************************************************************/ #include "DistributedSimulationDriver1.h" #include <vrvCore/DtAgentManager.h> #include <iostream> namespace makVrv { namespace tutorialDistributedSimulation1 { DistributedSimulationDriver::DistributedSimulationDriver( DtAgentManager& agentManager, const std::string& instanceName) : DtDriver(agentManager, instanceName) { } DistributedSimulationDriver::~DistributedSimulationDriver(void) { } const std::string& DistributedSimulationDriver::className() const { // name must be static, since it's returned by reference static std::string name("DistributedSimulationDriver"); return name; } bool DistributedSimulationDriver::onStart() { // Driver startup code goes here. Return false on bad status. std::cout << "DistributedSimulationDriver::onStart(): " << std::endl; return true; } bool DistributedSimulationDriver::onStop() { // Driver teardown code goes here. Return false on bad status. std::cout << "DistributedSimulationDriver::onStop(): " << std::endl; return true; } bool DistributedSimulationDriver::onTick() { // Code to perform activity per simulation tick goes here. Return false on bad status. std::cout << "."; return true; } } }
/****************************************************************************** ** Copyright (c) 2011 MAK Technologies, Inc. ** All rights reserved. ******************************************************************************/ #pragma once // Setup proper plugin export symbol #ifdef WIN32 #define DT_DE_PLUGIN_EXPORT_MACRO __declspec ( dllexport ) #else #define DT_DE_PLUGIN_EXPORT_MACRO #endif // Declare & export the plugin initialization function (bool initDeModule(DtDe* de)) #include <vrvCore/exportPlugin.h> namespace makVrv { class DtDe; } // Work function for the plugin initialization void init(makVrv::DtDe& de); // Callback to create the stateViewDriver void createDistributedSimDriver(makVrv::DtDe* de);
/****************************************************************************** ** Copyright (c) 2011 MAK Technologies, Inc. ** All rights reserved. ******************************************************************************/ #include "DistributedSimulationPlugin1.h" #include "DistributedSimulationDriver1.h" #include <vrvCore/DtDe.h> #include <vrvCore/DtDriverManager.h> #include <boost/bind.hpp> using namespace makVrv; using namespace tutorialDistributedSimulation1; void createDistributedSimDriver(DtDe* de) { // We're done with the signal, so disconnect from it de->signal_postInitialize.disconnect(boost::bind( &createDistributedSimDriver, de)); // Create the driver that will implement a distributed simulation DistributedSimulationDriver* driver = new DistributedSimulationDriver( de->agentManager(), "DistributedSimulationDriver1"); // After the driver is added to the display engine below, the DE will manage // its memory. The driver will be started automatically when added since we // set the autoStart property in its CTOR de->driverManager().addDriver(driver); } void init(DtDe& de) { // Ensure that init only gets called once DT_DE_INIT_ONCE(de); // We only want to create the driver if we're running in master mode: if (de.isInMasterMode()) { // The driver must be created after the DE's initialization is // finished, to make sure all the objects it uses exist. de.signal_postInitialize.connect(boost::bind( &createDistributedSimDriver, &de)); } } bool initDeModule(makVrv::DtDe* de) { // Setup the plugin. Normally, the init function and functionality // should be in its own library. init(*de); return true; }