VR-Vantage 1.4.1 API Class Documentation
The Distributed Simulation Tutorial - Add an Entity Using an Existing VR-Vantage Agent

Introduction to Project 4B

Project 4B in the Distributed Simulation tutorial takes a look at how to add an entity to the scene using an existing VR-Vantage agent. As with Project 4A, 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

In this case, to add an entity to the scene, we will need to add pointers to both a scene object agent and a model agent, along with a double for use in image rotation, to the driver header file.

   DtSceneObjectAgent* mySceneObjectAgent;
   DtModelAgent* mySimpleModel;
   double myRotationDegree;

The new onStart() function looks as follows:

bool DistributedSimulationDriver::onStart()
{
   std::cout << "DistributedSimulationDriver::onStart(): " << std::endl;

   DtExerciseConnInitializer init;
   init.setPort(3152);
   init.setExerciseId(1);
   init.setSiteId(2);
   init.setApplicationNumber(1);    
   // VR-Link default buffer is to small for this application; set it to 1 MB.
   init.setReceiveBufferSize(0x100000);

   DtExerciseConn::InitializationStatus status = DtExerciseConn::DtINIT_SUCCESS;

   try
   {         
      myConnection = new DtExerciseConn(init, &status);
   }
   catch(...)
   {
      return false;
   }
   myConnectionState = (status == DtExerciseConn::DtINIT_SUCCESS);

   // Add a cow to the root node by creating an existing model and agent
   // and setting the cow model definition into it.
   mySimpleModel = DtModelAgent::create(myAgentManager);
   mySceneObjectAgent = DtSceneObjectAgent::create(myAgentManager);
   const DtVector origin(0, 100, 0);
   mySceneObjectAgent->setPosition(0, origin);
   mySceneObjectAgent->setModelSet(0);
   mySceneObjectAgent->addModel(mySimpleModel, 0);
   mySimpleModel->setModelDefinition("LifeformsAnimalsCow");

   return myConnectionState;
}

Here, instead of reading the file directly into an OSG node and rendering directly to the scene root, we first instantiate a VR-Vantage DtModelAgent, giving it the agent manager that was passed at construction of the simulation driver object. We then instantiate a scene object agent, also passing the agent manager. Next we set the position and model set for the scene object agent and associate it wht the model agent that we just created. Finally we set the model definition string for the model agent.

   // Add a cow to the root node by creating an existing model and agent
   // and setting the cow model definition into it.
   mySimpleModel = DtModelAgent::create(myAgentManager);
   mySceneObjectAgent = DtSceneObjectAgent::create(myAgentManager);
   const DtVector origin(0, 100, 0);
   mySceneObjectAgent->setPosition(0, origin);
   mySceneObjectAgent->setModelSet(0);
   mySceneObjectAgent->addModel(mySimpleModel, 0);
   mySimpleModel->setModelDefinition("LifeformsAnimalsCow");

Note that the set of possible strings that can be used as model definition strings can be found by starting VR-Vantage, and selecting Settings > Visual Model Editors. Go to the second tab, which is the Model Definition Editor, and look through the list of definitions for "LifeformsAnimalsCow", which is the string we have used to render a cow on the scene. You can use any of the strings defined in this list. Read more in the documentation on the use of the Visual Model Editors window, and on how to define your own models.

The new onStop() function then removes the model from the scene, given a pointer to the model in question, and deletes both the scene object agent and the model agent:

bool DistributedSimulationDriver::onStop()
{
   // NOTE: breakdown code goes here.  Return false on bad status.
   std::cout << "DistributedSimulationDriver::onStop(): " << std::endl;

   delete myConnection;
   myConnection = 0;

   // Remove the cow from the scene and delete the agent and model.
   if (mySceneObjectAgent)
   {
      mySceneObjectAgent->removeModel(mySimpleModel);
      delete mySceneObjectAgent;
      delete mySimpleModel;
   }
   mySceneObjectAgent = 0;
   mySimpleModel = 0;

   return true;
}

The new onTick() function now implements the rotational code:

bool DistributedSimulationDriver::onTick()
{
   // printout to show whether or not connected at the tick level
   if (myConnectionState)
   {
      int numread = myConnection->drainInput();
      std::cout << "." << numread;
   }
   else
      std::cout << "x";

   // rotate the model to the left.
   const DtTaitBryan orient(myRotationDegree, 0, 0);
   mySceneObjectAgent->setOrientation(0, orient);
   myRotationDegree -= 0.005;
   if(myRotationDegree < 0.0)
   {
      myRotationDegree = 360.0;
   }

   return myConnectionState;
}

Testing the plugin

Invoke either the tutorialDistributedSimulation4Bd.bat or tutorialDistributedSimulation4B.sh script file to start the VR-Vantage Stealth application. Follow these instructions to test the plugin:

  1. Choose File > View > Drivers Panel.
  2. Select the driver named "DistributedSimulationDriver4B".
  3. Click on the Start button.
  4. In the Stealth window, you will see that a cow image has been added to the center of the scene, and 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.
  5. In Stealth, make sure the same driver is selected in the Drivers Panel, and click the Stop button.
  6. You will notice that the image of the cow is no longer present in the center of the Stealth window.
  7. 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 a Custom Agent >>]


Project Files

DistributedSimulationDriver4B.h

/****************************************************************************** 
** Copyright (c) 2011 MAK Technologies, Inc. 
** All rights reserved. 
******************************************************************************/ 


#pragma once

#include <vrvCore/DtDriver.h>

class DtExerciseConn;

namespace makVrv
{

class DtSceneObjectAgent;
class DtModelAgent;

namespace tutorialDistributedSimulation4B
{

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();

protected:

   DtExerciseConn* myConnection;
   bool myConnectionState;
   DtSceneObjectAgent* mySceneObjectAgent;
   DtModelAgent* mySimpleModel;
   double myRotationDegree;
};

}
}

DistributedSimulationDriver4B.cxx

/****************************************************************************** 
** Copyright (c) 2011 MAK Technologies, Inc. 
** All rights reserved. 
******************************************************************************/ 


#define DtDIS 1

#include "DistributedSimulationDriver4B.h"
#include <vrvCore/DtDe.h>
#include <vl/exConnInit.h>
#include <vl/exerciseConn.h>
#include <vrvCore/DtAgentManager.h>
#include <vrvCore/DtSceneObjectAgent.hpp>
#include <vrvCore/DtModelAgent.hpp>

#include <iostream>

namespace makVrv
{
namespace tutorialDistributedSimulation4B
{

DistributedSimulationDriver::DistributedSimulationDriver(DtAgentManager& agentManager,
                                               const std::string& instanceName)
: DtDriver(agentManager, instanceName)
, myConnection(0)
, myConnectionState(0)
, mySceneObjectAgent(0)
, mySimpleModel(0)
, myRotationDegree(0)
{
}

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()
{
   std::cout << "DistributedSimulationDriver::onStart(): " << std::endl;

   DtExerciseConnInitializer init;
   init.setPort(3152);
   init.setExerciseId(1);
   init.setSiteId(2);
   init.setApplicationNumber(1);    
   // VR-Link default buffer is to small for this application; set it to 1 MB.
   init.setReceiveBufferSize(0x100000);

   DtExerciseConn::InitializationStatus status = DtExerciseConn::DtINIT_SUCCESS;

   try
   {         
      myConnection = new DtExerciseConn(init, &status);
   }
   catch(...)
   {
      return false;
   }
   myConnectionState = (status == DtExerciseConn::DtINIT_SUCCESS);

   // Add a cow to the root node by creating an existing model and agent
   // and setting the cow model definition into it.
   mySimpleModel = DtModelAgent::create(myAgentManager);
   mySceneObjectAgent = DtSceneObjectAgent::create(myAgentManager);
   const DtVector origin(0, 100, 0);
   mySceneObjectAgent->setPosition(0, origin);
   mySceneObjectAgent->setModelSet(0);
   mySceneObjectAgent->addModel(mySimpleModel, 0);
   mySimpleModel->setModelDefinition("LifeformsAnimalsCow");

   return myConnectionState;
}

bool DistributedSimulationDriver::onStop()
{
   // NOTE: breakdown code goes here.  Return false on bad status.
   std::cout << "DistributedSimulationDriver::onStop(): " << std::endl;

   delete myConnection;
   myConnection = 0;

   // Remove the cow from the scene and delete the agent and model.
   if (mySceneObjectAgent)
   {
      mySceneObjectAgent->removeModel(mySimpleModel);
      delete mySceneObjectAgent;
      delete mySimpleModel;
   }
   mySceneObjectAgent = 0;
   mySimpleModel = 0;

   return true;
}

bool DistributedSimulationDriver::onTick()
{
   // printout to show whether or not connected at the tick level
   if (myConnectionState)
   {
      int numread = myConnection->drainInput();
      std::cout << "." << numread;
   }
   else
      std::cout << "x";

   // rotate the model to the left.
   const DtTaitBryan orient(myRotationDegree, 0, 0);
   mySceneObjectAgent->setOrientation(0, orient);
   myRotationDegree -= 0.005;
   if(myRotationDegree < 0.0)
   {
      myRotationDegree = 360.0;
   }

   return myConnectionState;
}

}
}

DistributedSimulationPlugin4B.h

/******************************************************************************
** 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);


DistributedSimulationPlugin4B.cxx

/******************************************************************************
** Copyright (c) 2011 MAK Technologies, Inc.
** All rights reserved.
******************************************************************************/


#include "DistributedSimulationPlugin4B.h"
#include "DistributedSimulationDriver4B.h"

#include <vrvCore/DtDe.h>
#include <vrvCore/DtDriverManager.h>
#include <vrvCore/DtModelDefinition.h>
#include <vrvCore/DtDeSharedState.h>
#include <vrvCore/DtModelDefinitionManager.h>

#include <boost/bind.hpp>

using namespace makVrv;
using namespace makVrv::tutorialDistributedSimulation4B;

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(), "DistributedSimulationDriver4B");

   // After the driver is added to the display engine below, the DE will manage
   // its memory.  This driver will add itself to the connection list.  Start
   // it from the connection panel.
   de->driverManager().addDriver(driver);
}

void init(DtDe& de)
{
   // Ensure that init only gets called once
   // (not strictly necessary here, but this is good practice in general)
   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;
}


Copyright © 2005-2012 VT MÄK Inc. All Rights Reserved (www.mak.com)