VR-Vantage 1.4.1 API Class Documentation
exampleDriverPlugin

This example creates a new driver.

This driver will load the Makland terrain database and create an F-16 entity on start, attach the main observer to it, and then move the F16 a small amount each time that it's ticked. This example adds a driver via a plugin.

The example driver's onStart() method loads the database first.

      DtScene& sceneDriver = myAgentManager.de().scene();
      std::string maklandPath = myAgentManager.de().dePathConfiguration().userPath();
      maklandPath += "//terrains//Makland.mtf";
      sceneDriver.loadTerrain(maklandPath);

It then creates a new entity facade and tells it to use the f-16_Falcon Visual Definition.

      // Create the entity      

Using the coordinate system information provided by the loaded terrain database, the driver provides an initial position and orientation in the coordinate system of the database.

      // Position on Makland 
      DtVector localPosition = DtVector( 2000.0, 1400., 350. );

      // Setup a topographic frame for coordinate system conversion.  setupTopoFrame() wants
      // the current position in local (database, also called CIG) coordinates
      if ( myAgentManager.de().sharedState().coordinateSystem().converter()->type() ==
         DtCoordinateConverter::Geocentric )
      {
         // => Use this for MaklandGeocentric - not exact but close enough
         DtGeodeticCoord geod( DtDeg2Rad( 10. ), DtDeg2Rad(60.), 0. );
         myAgentManager.de().sharedState().coordinateSystem().converter()->setupTopoFrame( geod.geocentric() );
      }
      else
      {
         // Or this for Makland (UTM)
         myAgentManager.de().sharedState().coordinateSystem().converter()->setupTopoFrame( localPosition );
      }
      
      // Convert an East North Up (ENU) position to our local database (CIG) coordinate system
      myAgentManager.de().sharedState().coordinateSystem().converter()->
         enuToCig_coordTrans( localPosition, myPosition );
     
      // Convert an North East Down (NED) orientation to our local database (CIG) coordinate system
      DtTaitBryan nedTb( myHeading, myPitch, myRoll );
      myOrientation = myAgentManager.de().sharedState().coordinateSystem().converter()->
         nedToCig_EulerTrans( nedTb );

The current observer is then attached to the newly created entity, and reset to provide a perspective view.

      std::vector<DtUniqueID> objects;

The driver manager ticks the example driver by calling its onTick() method. The onTick() method updates the driver's local kinematic member variables and then passes them on to the entity facade.

      updatePosition();
      myEntityFacade->setPosition(myPosition);    
      myEntityFacade->setOrientation(myOrientation);

The driver is stopped by the driver manager callings its onStop() method. This cleans up the entity facade allocated on the heap.

      if(myEntityFacade)
         delete myEntityFacade;
      myEntityFacade = 0;

The example driver is created, added to the driver manager, and started in the main program.

void installDriver(DtDe& de)
{
   // Create DtExampleDriver.
   DtExampleDriver* driver = new DtExampleDriver( de.agentManager());

   // The driver is now owned by the display engine. Do not delete it.
   de.driverManager().addDriver(driver);

   // Start the driver, creating the agent.
   de.driverManager().startDriver(driver);

The plugin registers the install function to be called after the DtDe has been initialized.

   if (de.isInMasterMode())
   {
      // The accessory 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(
         &installDriver, boost::ref(de) ));

Building the Example

VR-Vantage includes pre-built versions of the example plug-in. To build it yourself, follow the instructions at Building VR-Vantage Examples, Applications, and Plug-ins.

Running the Example

This example is a plug-in. You can run it by running ./bin/exampleDriverPlugin_stealth.bat (on Windows) or ./bin/exampleDriverPlugin_stealth.sh (on Linux). For more information about running examples, please see Running Applications and Examples.

Example Source Files


exampleDriverPlugin.cxx

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

#ifdef _WIN32
#ifdef EXAMPLEDRIVERPLUGIN_EXPORTS
#define DT_DLL_EXAMPLEDRIVERPLUGIN __declspec ( dllexport )
#else
#define DT_DLL_EXAMPLEDRIVERPLUGIN __declspec ( dllimport )
#endif
#else
#define DT_DLL_EXAMPLEDRIVERPLUGIN
#endif

#define DT_DE_PLUGIN_EXPORT_MACRO DT_DLL_EXAMPLEDRIVERPLUGIN
// Declare & export the plugin initialization function (bool initDeModule(DtDe* de))
#include <vrvCore/exportPlugin.h>

#include <vrvCore/DtAgentManager.h>
#include <vrvCore/DtAttachManager.h>
#include <vrvCore/DtDe.h>
#include <vrvCore/DtDeSharedState.h>
#include <vrvCore/DtDriver.h>
#include <vrvCore/DtDriverManager.h>
#include <vrvCore/DtElementAttributes.h>
#include <vrvCore/DtEntityFacade.h>
#include <vrvCore/DtInputDriver.h>
#include <vrvCore/DtObserver.h>
#include <vrvCore/DtScene.h>
#include <vrvUtil/DtCoordinateConverter.h>
#include <vrvUtil/DtCoordinateSystem.h>


#include <matrix/vlVector.h>
#include <math.h>

#include <boost/bind.hpp>

// Use the VR-Vantage namespace. All classes in VR-Vantage are in this namespace.
using namespace makVrv;

// This driver creates and owns the example driver.
class DtExampleDriver : public makVrv::DtDriver
{
public:

   DtExampleDriver(DtAgentManager& am)
      : makVrv::DtDriver(am,"DtExampleDriver")
      , myEntityFacade(0)
      , myPosition()
      , myOrientation()
      , myHeading( 0. )
      , myPitch( 0. )
      , myRoll( 0.5 )
   {
   }

   virtual ~DtExampleDriver()
   {
      if(myEntityFacade)
         delete myEntityFacade;
      myEntityFacade = 0;
   }

   virtual const std::string& className() const
   {
      static std::string name = "DtExampleDriver";
      return name;
   }

   virtual bool onStart()
   {      
      // Load the Makland programatically.
      DtScene& sceneDriver = myAgentManager.de().scene();
      std::string maklandPath = myAgentManager.de().dePathConfiguration().userPath();
      maklandPath += "//terrains//Makland.mtf";
      sceneDriver.loadTerrain(maklandPath);

      // Create the entity      
      const DtModelSetRealizationManager::ModelSetRealizations& setsToRealize =
         myAgentManager.de().sharedState().modelSetRealizationManager().modelSetRealizations();     

      DtElementID elementId = myAgentManager.createNewUniqueId();
      myEntityFacade = new DtEntityFacade(myAgentManager, elementId,setsToRealize,false);
      reportElementCreated(elementId,0,DtElementEntry::Entity);
      reportElementAttribute(elementId,new DtElementAttributeDisplayName("Entity From Facade"));
      reportElementAttribute(elementId,new DtElementAttributeVisibility(true));

      // Load the 3D model
      if(myEntityFacade->findFacadeFor3d())
      {
         myEntityFacade->findFacadeFor3d()->setArticulatedModelDefinition("FixedWingF-16UnarmedGrey");
      }

      // Load the Colorized model
      if(myEntityFacade->findFacadeForColorized())
      {
         myEntityFacade->findFacadeForColorized()->setArticulatedModelDefinition("FixedWingAttackNotional");
         myEntityFacade->findFacadeForColorized()->setModelScalingEnabled(true);
      }

      // Load the model
      if(myEntityFacade->findFacadeFor2d())
      {
         myEntityFacade->findFacadeFor2d()->setIconModelDefinition("2525bIcons");

         //Glyphs from the MAK 2525b font.
         myEntityFacade->findFacadeFor2d()->setFillGlyph(DtUnicodeChar((wchar_t)0x0022));
         myEntityFacade->findFacadeFor2d()->setOutlineGlyph(DtUnicodeChar((wchar_t)0x40C6));
         myEntityFacade->findFacadeFor2d()->setDamageGlyph(DtUnicodeChar((wchar_t)0x0061));
      }
      
      // Position on Makland 
      DtVector localPosition = DtVector( 2000.0, 1400., 350. );

      // Setup a topographic frame for coordinate system conversion.  setupTopoFrame() wants
      // the current position in local (database, also called CIG) coordinates
      if ( myAgentManager.de().sharedState().coordinateSystem().converter()->type() ==
         DtCoordinateConverter::Geocentric )
      {
         // => Use this for MaklandGeocentric - not exact but close enough
         DtGeodeticCoord geod( DtDeg2Rad( 10. ), DtDeg2Rad(60.), 0. );
         myAgentManager.de().sharedState().coordinateSystem().converter()->setupTopoFrame( geod.geocentric() );
      }
      else
      {
         // Or this for Makland (UTM)
         myAgentManager.de().sharedState().coordinateSystem().converter()->setupTopoFrame( localPosition );
      }
      
      // Convert an East North Up (ENU) position to our local database (CIG) coordinate system
      myAgentManager.de().sharedState().coordinateSystem().converter()->
         enuToCig_coordTrans( localPosition, myPosition );
     
      // Convert an North East Down (NED) orientation to our local database (CIG) coordinate system
      DtTaitBryan nedTb( myHeading, myPitch, myRoll );
      myOrientation = myAgentManager.de().sharedState().coordinateSystem().converter()->
         nedToCig_EulerTrans( nedTb );
 
      // Attach to entity.
      std::vector<DtUniqueID> objects;
      objects.push_back(myEntityFacade->elementId());
      DtObserver* currentObserver = myAgentManager.de().driverManager().inputDriver().currentObserver();
      currentObserver->setPrimaryAttachment(objects);
      return true;
   }

   virtual bool onStop()
   {
      if(myEntityFacade)
         delete myEntityFacade;
      myEntityFacade = 0;
      return true;
   }

   virtual bool onTick()
   {    
      updatePosition();
      myEntityFacade->setPosition(myPosition);    
      myEntityFacade->setOrientation(myOrientation);
      return true;
   }

protected:  

   virtual void updatePosition()
   {
      // Increment heading by a small amount
      myHeading = myHeading + .005;
      if ( myHeading >= 6.28318 )
      {
         myHeading = 0;
      }

      DtTaitBryan nedTb( myHeading, myPitch, myRoll );
      myOrientation = myAgentManager.de().sharedState().coordinateSystem().converter()->
         nedToCig_EulerTrans( nedTb );
   }

protected:

   DtEntityFacade* myEntityFacade;
   DtVector myPosition;   
   DtTaitBryan myOrientation;
   double myHeading;
   double myRoll;
   double myPitch;
};

void installDriver(DtDe& de)
{
   // Create DtExampleDriver.
   DtExampleDriver* driver = new DtExampleDriver( de.agentManager());

   // The driver is now owned by the display engine. Do not delete it.
   de.driverManager().addDriver(driver);

   // Start the driver, creating the agent.
   de.driverManager().startDriver(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 are running in master mode.
   if (de.isInMasterMode())
   {
      // The accessory 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(
         &installDriver, boost::ref(de) ));
   }
}


bool initDeModule(makVrv::DtDe* de)
{
   // Setup the plug-in. 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)