Table of Contents
Overview
This example explains what an agent is and how to create and use one. The application creates a geometry (cube), adds the geometry to the scene and rotates it. Of particular interest in this tutorial is the use of agents to load and manage the geometry.
Example details
VR-Vantage uses agents to create and synchronize scene objects among all display engines in the configuration. The master creates and owns agents which causes scene objects to be created locally and simultainiously sends messages to the distributed systems to manage their own copies of the same scene object. Agents in VR-Vantage take the same name as the objects they manage with the added suffix 'Agent'. Because agents are used to send messages to distributed system (and not receive back replies), they are one-way communication objects. Their APIs expose the write-only interface of the objects they manage.
This example shows how to create an agent for an object and create an instance of the agent in a driver. DtDriver objects registered with the display engine have the benefit of being called when the simulation starts, when the simulation stops, and every simulation time-update at regular intervals.
The custom DtDriver in this application creates a new agent object, MyObjectAgent when the simulation starts (in its 'onStart()' function), and destroys the object when the simulation stops (in its 'onStop()' function). During the simulation time-updates, the custom DtDriver's onTick() function is called, where it updates the geometry. For more information on Drivers see The Driver Layer.
The agent classes are generated by the Distributed Code Generator(dcgen) using an ocdx file. An ocdx file specifies the object structure which is constructed on each system by the agent in a distributed simulation environment.
The setupTree script automatically finds the ocdx files and generates the agent classes for you during the build. However if you wish to generate these files manually, the following description gives more information on how to do it.
To generate the agent classes using dcgen interface as follows:
-
Run ./bin/dcgen.exe. The Distributed Code Generator opens.
-
Choose Files -> Open. An Open dialog box opens.
-
Select ./examples/exampleSimpleAgent/MyObject.ocdx.
-
Examine the object class definition and compare it to the object code to see how functions for the agent were chosen.
-
Choose Build -> Set Output Directory.
-
Specify a directory for the output files. Be careful not to overwrite the files shipped with VR-Vantage.
-
Choose Build -> Generate Files. (You can also generate files from the command line or from within your IDE. For details, please see VR-Vantage Developer's Guide.)
To generate the agent classes from command line as follows:
-
From command line, go to ../bin directory where dcgen.exe exists.
-
Then give the following command :
./dcgen.exe -a -S "path_to_source_file_directory" -H "path_to_header_output_directory" -A "path_to_relative_include_directory" "path_to_ocdx_file"
where
-a : Generate all of the classes.
-S : The directory to write source files to.
-H : The directory to write header files to.
-A : The root directory that generated include statements are relative to.
-
For more information on dcgen command, please use "dcgen.exe –help" command.
We create a distributed object, MyObject, that loads the geometry and rotates it using an agent.
The object is defined as follows:
#pragma once
#include <vrvCore/DtDe.h>
#include <vrvCore/DtUniqueID.h>
#include <osg/PositionAttitudeTransform>
#include <string>
{
public:
MyObject(makVrv::DtDe& de, makVrv::DtUniqueID
id);
Derived from a DtDriver is a custom driver used to load and manipulate the geometry.
When the custom DtDriver is notified that the simulation is starting it creates a new agent object and loads the geometry.
virtual bool onStart()
{
myAgent = MyObjectAgent::create(myAgentManager);
myAgent->createModel();
During the running simulation, drivers get ticked every frame. In our driver's tick method, we will tell the agent to rotate to a certain degree:
virtual bool onTick()
{
myAgent->setRotationAngle(myRotationDegree);
myRotationDegree += 0.15;
if(myRotationDegree > 360.0)
{
myRotationDegree = 0.0;
}
Building the Example
VR-Vantage includes pre-built versions of the example application. To build it yourself, follow the instructions at Building VR-Vantage Examples, Applications, and Plug-ins.
Running the Example
This example is an application. You can run it by running ./bin/exampleSimpleAgent.exe (on Windows) or ./bin/exampleSimpleAgent (on Linux). For more information about running examples, please see Running Applications and Examples.
Learn More
Example Source Files
MyObject.h
#pragma once
#include <vrvCore/DtDe.h>
#include <vrvCore/DtUniqueID.h>
#include <osg/PositionAttitudeTransform>
#include <string>
{
public:
MyObject(makVrv::DtDe& de, makVrv::DtUniqueID
id);
protected:
osg::ref_ptr<osg::PositionAttitudeTransform>
myPat;
};
MyObject.cxx
#include <vrvOsg/DtOsgRenderer.h>
#include <osg/Group>
#include <osg/Node>
#include <osgDB/ReadFile>
#include <osg/ShapeDrawable>
#include <osg/Geode>
#include <osg/Material>
using namespace makVrv;
: myDe(de)
, myPat(0)
{
}
{
}
{
osg::Group* root = new osg::Group();
osg::Box* cube = new osg::Box(osg::Vec3(0.0f, 0.0f, 0.0f), 5.0f);
osg::Drawable* draw = new osg::ShapeDrawable(cube);
osg::Geode* boxGeode = new osg::Geode();
boxGeode->addDrawable(draw);
osg::Material* mat = new osg::Material();
mat->setDiffuse( osg::Material::FRONT_AND_BACK, osg::Vec4(0.25,0.40,0.55,1.0) );
mat->setAmbient( osg::Material::FRONT_AND_BACK, osg::Vec4(0.5,0.8,0.35,1.0) );
boxGeode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::ON );
boxGeode->getOrCreateStateSet()->setAttributeAndModes( mat );
root->addChild(boxGeode);
myPat =
new osg::PositionAttitudeTransform();
myPat->setPosition(osg::Vec3(0,35,0));
DtOsgRenderer::visualizerTypeRoot( 0, 0 ) );
}
{
myPat->setAttitude(osg::Quat(
osg::DegreesToRadians(45.0), osg::Vec3d(1.0, 0.0, 0.0),
osg::DegreesToRadians(rotationAngleInDegrees), osg::Vec3d(0.0, 1.0, 0.0),
osg::DegreesToRadians(rotationAngleInDegrees), osg::Vec3d(0.0, 0.0, 1.0)));
}
ExampleSimpleAgent.cxx
#include <vrvCore/DtVrvApplication.h>
#include <vrvCore/DtDe.h>
#include <vrvCore/DtAgentManager.h>
#include <vrvCore/DtDriverManager.h>
#include <vrvCore/DtDriver.h>
#include "MyObjectAgent.hpp"
using namespace makVrv;
{
public:
MyExampleDriver(DtAgentManager& am)
, myAgent(0)
, myRotationDegree(0.0)
{
}
virtual ~MyExampleDriver()
{
if(myAgent)
delete myAgent;
myAgent = 0;
}
virtual const std::string& className() const
{
static std::string name = "MyExampleDriver";
return name;
}
virtual bool onStart()
{
myAgent = MyObjectAgent::create(myAgentManager);
myAgent->createModel();
return true;
}
virtual bool onStop()
{
if(myAgent)
delete myAgent;
myAgent = 0;
return true;
}
virtual bool onTick()
{
myAgent->setRotationAngle(myRotationDegree);
myRotationDegree += 0.15;
if(myRotationDegree > 360.0)
{
myRotationDegree = 0.0;
}
return true;
}
protected:
MyObjectAgent* myAgent;
double myRotationDegree;
};
int main(int argc,char** argv)
{
application.initialize(argc, argv);
MyExampleDriver* driver = new MyExampleDriver(
application.de().agentManager());
application.de().driverManager().addDriver(driver);
application.de().driverManager().startDriver(driver);
application.run();
}