Introduction to Project 4A
Project 4A in the Distributed Simulation tutorial takes a look at how to add an entity to the scene directly using VR-Link. We will add an image of a cow to the scene when the driver is started, and remove the image when the driver is stopped. The cow will be made to rotate to the left when it is visible on the screen.
Examining the files that make up the project
For this project, all files from Project 2A will be reused. No new files will be needed. All changes, other than filenames, will be made in the DistributedSimulationDriver class files.
Adding an Entity to the Scene
To add an entity to the scene, we will need to add both an OSG reference pointer of type osg::PositionAttitudeTransform and the necessary header for that type to the top of the driver header file.
#include <osg/PositionAttitudeTransform>
osg::ref_ptr<osg::PositionAttitudeTransform> myPat;
The class definition file will also need some headers included to handle the reading of a file into an OSG node as well as the rendering of that node into the scene.
#include <osg/Group>
#include <osg/Node>
#include <osgDB/ReadFile>
The new onStart() function looks as follows:
{
std::cout << "DistributedSimulationDriver::onStart(): " << std::endl;
DtExerciseConnInitializer
init;
init.setPort(3152);
init.setExerciseId(1);
init.setSiteId(2);
init.setApplicationNumber(1);
init.setReceiveBufferSize(0x100000);
DtExerciseConn::InitializationStatus status = DtExerciseConn::DtINIT_SUCCESS;
try
{
myConnection = new DtExerciseConn(init, &status);
}
catch(...)
{
return false;
}
myConnectionState = (status == DtExerciseConn::DtINIT_SUCCESS);
osg::ref_ptr<osg::Node> cowNode = osgDB::readNodeFile("../data/Lifeforms/Animals/cow.osg");
if (!myPat)
{
myPat = new osg::PositionAttitudeTransform();
myPat->addChild(cowNode.get());
myPat->setPosition(osg::Vec3(0,100,0));
}
((DtOsgRenderer&)agentManager().de().renderer()).addNodeToRoot( myPat.get(),
((DtOsgRenderer&)agentManager().de().renderer()).environmentRoot());
return myConnectionState;
}
The difference here is that we add code to read in and set the scene position for an image of a cow. We use an osg::PositionAttitudeTransform object to handle the storing of the image data.
osg::ref_ptr<osg::Node> cowNode = osgDB::readNodeFile("../data/Lifeforms/Animals/cow.osg");
if (!myPat)
{
myPat = new osg::PositionAttitudeTransform();
myPat->addChild(cowNode.get());
myPat->setPosition(osg::Vec3(0,100,0));
}
We then use the agent manager object, which was passed in when the simulation driver was constructed, in order to get access to the display engine's renderer and add this new node to the root of the scene.
((DtOsgRenderer&)agentManager().de().renderer()).addNodeToRoot( myPat.get(),
((DtOsgRenderer&)agentManager().de().renderer()).environmentRoot());
The new onStop() function now needs to remove the node from the scene. Otherwise, if the driver is stopped, the node will continue to be an inactive part of the scene.
{
std::cout << "DistributedSimulationDriver::onStop(): " << std::endl;
((DtOsgRenderer&)agentManager().de().renderer()).removeNodeFromRoot( myPat.get(),
((DtOsgRenderer&)agentManager().de().renderer()).environmentRoot());
delete myConnection;
myConnection = 0;
return true;
}
Testing the plugin
Invoke either the tutorialDistributedSimulation4Ad.bat or tutorialDistributedSimulation4A.sh script file to start the VR-Vantage Stealth application. Follow these instructions to test the plugin:
-
Choose File > View > Drivers Panel.
-
Select the driver named "DistributedSimulationDriver4A".
-
Click on the Start button.
-
For this and all subsequent projects the output to the console window is not important. But if you look you will see in the console window that the text "DistributedSimulationDriver::onStart():" has printed, and on the subsequent line, a series of dots is now continually being printed. More importantly, going back to Stealth, you will see that a cow image has been added in the center of the scene, and it is rotating to the left. You may need to dismiss the "Choose a Terrain" dialog in order to see this, but make sure to do so by clicking on the X at the top right, rather than on the OK, or just choose "Do not load any terrain" and then click OK.
-
In Stealth, make sure the same driver is selected in the Drivers Panel, and click the Stop button.
-
Again, less importantly, you will see in the console window that the dots, byte counts, and detonations are no longer being printed, and that the text "DistributedSimulationDriver::onStop():" has been printed on the subsequent line. More importantly, you will notice that the image of the cow is no longer present in the center of the Stealth window.
-
Continually clicking the Start and Stop button will keep starting and stopping the driver, giving these same results in the console window.
[<< Add an Entity Existence Listener] [Add an Entity Using an Existing VR-Vantage Agent >>]
Project Files
DistributedSimulationDriver4A.h
#pragma once
#include <osg/PositionAttitudeTransform>
class DtExerciseConn;
namespace makVrv
{
namespace tutorialDistributedSimulation4A
{
class DistributedSimulationDriver : public DtDriver
{
public:
virtual const std::string&
className()
const;
protected:
protected:
osg::ref_ptr<osg::PositionAttitudeTransform>
myPat;
};
}
}
DistributedSimulationDriver4A.cxx
#define DtDIS 1
#include <vl/exConnInit.h>
#include <vl/exerciseConn.h>
#include <osg/Group>
#include <osg/Node>
#include <osgDB/ReadFile>
#include <iostream>
namespace makVrv
{
namespace tutorialDistributedSimulation4A
{
DtAgentManager& agentManager, const std::string& instanceName)
: DtDriver(agentManager, instanceName)
, myConnection(0)
, myConnectionState(0)
, myPat(0)
, myRotationDegree(0)
{
}
DistributedSimulationDriver::~DistributedSimulationDriver(void)
{
}
const std::string& DistributedSimulationDriver::className() const
{
static std::string name("DistributedSimulationDriver");
return name;
}
bool DistributedSimulationDriver::onStart()
{
std::cout << "DistributedSimulationDriver::onStart(): " << std::endl;
DtExerciseConnInitializer
init;
init.setPort(3152);
init.setExerciseId(1);
init.setSiteId(2);
init.setApplicationNumber(1);
init.setReceiveBufferSize(0x100000);
DtExerciseConn::InitializationStatus status = DtExerciseConn::DtINIT_SUCCESS;
try
{
myConnection = new DtExerciseConn(init, &status);
}
catch(...)
{
return false;
}
myConnectionState = (status == DtExerciseConn::DtINIT_SUCCESS);
osg::ref_ptr<osg::Node> cowNode = osgDB::readNodeFile("../data/Lifeforms/Animals/cow.osg");
if (!myPat)
{
myPat = new osg::PositionAttitudeTransform();
myPat->addChild(cowNode.get());
myPat->setPosition(osg::Vec3(0,100,0));
}
((DtOsgRenderer&)agentManager().de().renderer()).addNodeToRoot( myPat.get(),
((DtOsgRenderer&)agentManager().de().renderer()).environmentRoot());
return myConnectionState;
}
bool DistributedSimulationDriver::onStop()
{
std::cout << "DistributedSimulationDriver::onStop(): " << std::endl;
((DtOsgRenderer&)agentManager().de().renderer()).removeNodeFromRoot( myPat.get(),
((DtOsgRenderer&)agentManager().de().renderer()).environmentRoot());
delete myConnection;
myConnection = 0;
return true;
}
bool DistributedSimulationDriver::onTick()
{
if (myConnectionState)
{
int numread = myConnection->drainInput();
std::cout << "." << numread;
}
else
std::cout << "x";
if (myPat)
{
myPat->setAttitude(osg::Quat(
osg::DegreesToRadians(0.0), osg::Vec3d(1.0, 0.0, 0.0),
osg::DegreesToRadians(0.0), osg::Vec3d(0.0, 1.0, 0.0),
osg::DegreesToRadians(myRotationDegree), osg::Vec3d(0.0, 0.0, 1.0)));
myRotationDegree += 0.15;
if(myRotationDegree > 360.0)
{
myRotationDegree = 0.0;
}
}
return myConnectionState;
}
}
}
DistributedSimulationPlugin4A.h
#pragma once
#ifdef WIN32
#define DT_DE_PLUGIN_EXPORT_MACRO __declspec ( dllexport )
#else
#define DT_DE_PLUGIN_EXPORT_MACRO
#endif
namespace makVrv { class DtDe; }
DistributedSimulationPlugin4A.cxx
#include <boost/bind.hpp>
using namespace makVrv;
using namespace makVrv::tutorialDistributedSimulation4A;
{
DistributedSimulationDriver* driver = new DistributedSimulationDriver(
}
{
{
}
}
{
return true;
}