VR-Forces Developer's Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
exampleSimpleAgent

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:

  1. Run ./bin64/dcgen.exe. The Distributed Code Generator opens.
  2. Choose Files -> Open. An Open dialog box opens.
  3. Select ./examples/exampleSimpleAgent/MyObject.ocdx.
  4. Examine the object class definition and compare it to the object code to see how functions for the agent were chosen.
  5. Choose Build -> Set Output Directory.
  6. Specify a directory for the output files. Be careful not to overwrite the files shipped with VR-Vantage.
  7. 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:

  1. From command line, go to ../bin64 directory where dcgen.exe exists.
  2. 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.

  3. 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:

//! \brief Contains the MyObject class declaration.
#pragma once
#include <vrvCore/DtDe.h>
#include <osg/PositionAttitudeTransform>
#include <string>
class MyObject
{
public:
virtual ~MyObject();
void createModel();
void setRotationAngle(double rotationAngleInDegrees);

Derived from a DtDriver is a custom driver used to load and manipulate the geometry.

class MyExampleDriver : public DtDriver

When the custom DtDriver is notified that the simulation is starting it creates a new agent object and loads the geometry.

virtual bool onStart()
{
// Create the agent
myAgent = MyObjectAgent::create(myAgentManager);
// Create and load the geometry of cube
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()
{
// Rotate the object a little bit every frame.
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 ./bin64/exampleSimpleAgent.exe (on Windows) or ./bin64/exampleSimpleAgent (on Linux). For more information about running examples, please see Running Applications and Examples.

Learn More

Example Source Files


MyObject.h

/******************************************************************************
** Copyright (c) 2019 MAK Technologies, Inc.
** All rights reserved.
******************************************************************************/
#pragma once
#include <vrvCore/DtDe.h>
#include <osg/PositionAttitudeTransform>
#include <string>
class MyObject
{
public:
virtual ~MyObject();
void createModel();
void setRotationAngle(double rotationAngleInDegrees);
protected:
};

MyObject.cxx

/******************************************************************************
** Copyright (c) 2019 MAK Technologies, Inc.
** All rights reserved.
******************************************************************************/
#include "MyObject.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)
{
}
{
}
{
// Add a model...
// Create a root Node to hold the model.
// Groups are derived from Nodes and they are containers for other Nodes.
osg::Group* root = new osg::Group();
// Create the Drawable geometry for a cube.
// Drawables hold the geometry structures such as vertices, colors,
// normals, etc. Here we're using a utility that creates basic
// shapes to build a Drawable. This is a basic cube of size 5 units
// centered around the origin (0, 0, 0), its default color is white.
osg::Box* cube = new osg::Box(osg::Vec3(0.0f, 0.0f, 0.0f), 5.0f);
osg::Drawable* draw = new osg::ShapeDrawable(cube);
// The drawable geometry is held under a geode.
// Geodes are nodes which act as containers for drawables.
// Drawables are not derived from nodes, so geodes are used
// to link the scene graph node branches to drawable leaves.
osg::Geode* boxGeode = new osg::Geode();
// Associate the drawable geometry with the Geode.
boxGeode->addDrawable(draw);
// Setting up the diffuse and ambient material properties.
// We are setting up these properties to enable shading on the cube.
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) );
// Make sure that the lighting is ON.
boxGeode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::ON );
// Add material properties that are already setup to the cube.
boxGeode->getOrCreateStateSet()->setAttributeAndModes( mat );
// Add the Geode to the root Node of the scene graph.
root->addChild(boxGeode);
// Create a transform for the cube model.
myPat = new osg::PositionAttitudeTransform();
// Add the cube model to the transform.
myPat->addChild(root);
// The observer starts at 0,0,0. Since the observer and cube are centered at same position, we need to move the transform, 35 units away so that we can view
// the model from a distance.
myPat->setPosition(osg::Vec3(0,35,0));
// Add the cube to the root of the scene graph using modelSet 0.
((DtOsgRenderer&)myDe.renderer()).addNodeToRoot(myPat.get(),
DtOsgRenderer::visualizerTypeRoot( 0, 0 ) );
}
void MyObject::setRotationAngle( double rotationAngleInDegrees )
{
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

/******************************************************************************
** Copyright (c) 2019 MAK Technologies, Inc.
** All rights reserved.
******************************************************************************/
#include <vrvCore/DtDe.h>
#include "MyObjectAgent.hpp"
// Use the VR-Vantage namespace. All classes in VR-Vantage are in this namespace.
using namespace makVrv;
// This driver class is used to create and manage the model.
// This driver is registered with the driver-manager in order to
// get regular simulation 'ticks' during the run of the application.
// In each tick, this driver updates the model by applying the transformations accordingly.
class MyExampleDriver : public DtDriver
{
public:
MyExampleDriver(DtAgentManager& am)
: DtDriver(am,"MyExampleDriver")
, myAgent(0)
, myRotationDegree(0.0)
{
}
virtual ~MyExampleDriver()
{
if(myAgent)
delete myAgent;
myAgent = 0;
}
// Implement the base-class pure virtual function to return
// a class name. This name is used when registering this class.
virtual const std::string& className() const
{
static std::string name = "MyExampleDriver";
return name;
}
// When the simulation starts, the "MyExampleDriver" driver creates the model-agent
// and saves the starting time of the simulation.
// Restores state that existed the last time the driver was stopped.
virtual bool onStart()
{
// Create the agent
myAgent = MyObjectAgent::create(myAgentManager);
// Create and load the geometry of cube
myAgent->createModel();
return true;
}
// When the simulation stops, this driver destroys the model-agent and the
// scene-object-agent that it was managing.
virtual bool onStop()
{
if(myAgent)
delete myAgent;
myAgent = 0;
return true;
}
virtual bool onTick()
{
// Rotate the object a little bit every frame.
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)
{
// A DtVrvApplication wraps up all the components required to build a complete
// VR-Vantage application (DtDe, DtPluginManager, DtEventLoop, and a
// DtVrvApplicationConfiguration).
DtVrvApplication application;
// This causes the plugin manager to load plugins, cause a Display Configuration
// to be realized, creates the default environment, etc.
application.initialize(argc, argv);
// Create MyExampleDriver.
MyExampleDriver* driver = new MyExampleDriver(
application.de().agentManager());
// The driver is now owned by the display engine. Do not delete it.
application.de().driverManager().addDriver(driver);
// Start the driver, creating a driver.
application.de().driverManager().startDriver(driver);
// Creates an event loop and begins running it, causing the creation of frames.
application.run();
return 0;
}

[<< Examples] [Home] [Top of Page]


Document ID: Generated on Thu Oct 23 22:29:17 EDT 2025 from SVN revision 280951
Copyright © 2005-2024 MAK Technologies. All Rights Reserved (www.mak.com)