VR-Vantage 1.4.1 API Class Documentation
exampleDriver

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.

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

   DtScene& sceneDriver = myAgentManager.de().scene();

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

   // Create the entity
   myEntityDisplayName = "Entity From Facade";
   DtElementID elementId = myAgentManager.createNewUniqueId();
   myEntityFacade = new DtEntity3dFacade( myAgentManager, elementId, true );
   reportElementCreated( elementId, 0, DtElementEntry::Entity );
   reportElementAttribute( elementId, new DtElementAttributeDisplayName(myEntityDisplayName) );
   reportElementAttribute( elementId, new DtElementAttributeVisibility(true) );

   // Load the model
   myEntityFacade->setArticulatedModelDefinition("FixedWingF-16UnarmedGrey");

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.0, 350.0 );

   DtCoordinateConverter* coordConverter =
      myAgentManager.de().sharedState().coordinateSystem().converter();

   // Setup a topographic frame for coordinate system conversion.  setupTopoFrame() wants
   // the current position in local (database, also called CIG) coordinates
   if ( coordConverter->type() == DtCoordinateConverter::Geocentric )
   {
      // => Use this for MaklandGeocentric - not exact but close enough
      DtGeodeticCoord geod( DtDeg2Rad(10.0), DtDeg2Rad(60.0), 0.0 );
      coordConverter->setupTopoFrame( geod.geocentric() );
   }
   else
   {
      // Or this for Makland (UTM)
      coordConverter->setupTopoFrame( localPosition );
   }

   // Convert an East North Up (ENU) position to our local database (CIG) coordinate system
   coordConverter->enuToCig_coordTrans( localPosition, myPosition );

   // Convert an North East Down (NED) orientation to our local database (CIG) coordinate system
   DtTaitBryan nedTb( myHeading, myPitch, myRoll );
   myOrientation = coordConverter->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;
      objects.push_back( myEntityFacade->elementId() );

      DtObserver* currentObserver =
         myAgentManager.de().driverManager().inputDriver().currentObserver();
      currentObserver->setPrimaryAttachment( 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 )
   {
      if ( myEntityInfoWidget )
      {
         myEntityFacade->sceneObjectAgent().removeModel(
            myEntityInfoWidget->model() );
         delete myEntityInfoWidget;
         myEntityInfoWidget;
      }

      if ( myEntityIndicator )
      {
         setHoverSignalsActive( false );
         myEntityFacade->sceneObjectAgent().removeModel(
            myEntityIndicator->model() );
         delete myEntityIndicator;
         myEntityIndicator = 0;
      }

      reportElementDestroyed( myEntityFacade->elementId() );
      delete myEntityFacade;
      myEntityFacade = 0;
   }
   return true;

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

   DtExampleDriver* driver = new DtExampleDriver( application.de().agentManager() );

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/exampleDistributedObject.exe (on Windows) or ./bin/exampleDistributedObject (on Linux). For more information about running examples, please see Running Applications and Examples.

Example Source Files


exampleDriver.cxx

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


#include <vrvCore/DtDe.h>
#include <vrvCore/DtDriverManager.h>
#include <vrvCore/DtStealthConfiguration.h>
#include <vrvCore/DtStealthCommandLineProcessor.h>

#include "DtExampleDriver.h"

int main( int argc, char* argv[] )
{
   // Create the Application.
   makVrv::DtStealthConfiguration stealthConfig;
   makVrv::DtStealthCommandLineProcessor stealthParser;
   makVrv::DtVrvApplication application( stealthConfig );
   application.installCommandLineProcessor( &stealthParser );

   // This causes the plug-in manager to load plug-ins, cause a Display Configuration
   // to be realized, creates the default environment, etc.
   application.initialize( argc, argv );

   // Create DtExampleDriver.
   DtExampleDriver* driver = new DtExampleDriver( 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 the agent.
   application.de().driverManager().startDriver( driver );

   // Creates an event loop and begins running it, causing the creation of frames.
   application.run();
}

DtExampleDriver.h

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


#pragma once

#include <vrvCore/DtDriver.h>

#include <vrvCore/DtEntityIndicatorWidget.h>
#include <vrvCore/DtSelectionManager.h>
#include <vrvCore/DtEntityInfoWidget.h>

#include <vrvUtil/DtUnicode.h>

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

#include <string>

namespace makVrv
{
   class DtEntity3dFacade;
}

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

   DtExampleDriver( makVrv::DtAgentManager& am );

   virtual ~DtExampleDriver();


   virtual const std::string& className() const;

   virtual bool onStart();

   virtual bool onStop();

   virtual bool onTick();

   virtual void slot_displayEngineAdded( const makVrv::DtDeRecord& igRecord );


protected:

   virtual void slot_togglePinnedLabel(
      const makVrv::DtSelectionManager::IdSet& sel );

   virtual void slot_mouseHoverChanged( bool isHovering );

   virtual void setHoverSignalsActive( bool active );

   virtual void setEntityInfoWidgetActive( bool active );

   virtual makVrv::DtUnicode generateInfoString() const;

   virtual void updatePosition();

protected:

   makVrv::DtEntity3dFacade* myEntityFacade;
   makVrv::DtEntityIndicatorWidget* myEntityIndicator;
   makVrv::DtEntityInfoWidget* myEntityInfoWidget;

   DtVector myPosition;
   DtTaitBryan myOrientation;
   std::string myEntityDisplayName;
   bool myEntityInfoWidgetPinnedFlag;

   double myHeading;
   double myRoll;
   double myPitch;

};

DtExampleDriver.cxx

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


#include "DtExampleDriver.h"

#include <vrvCore/DtAgentManager.h>
#include <vrvCore/DtDe.h>
#include <vrvCore/DtDeSharedState.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 <vrvCore/DtStateVisualizer.h>
#include <vrvUtil/DtCoordinateConverter.h>
#include <vrvUtil/DtCoordinateSystem.h>

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

DtExampleDriver::DtExampleDriver( DtAgentManager& am )
   : makVrv::DtDriver( am, "DtExampleDriver" )
   , myEntityFacade( 0 )
   , myEntityIndicator( 0 )
   , myEntityInfoWidget( 0 )
   , myPosition()
   , myOrientation()
   , myEntityDisplayName( "" )
   , myEntityInfoWidgetPinnedFlag( false )
   , myHeading( 0.0 )
   , myPitch( 0.0 )
   , myRoll( 0.5 )
{
}

DtExampleDriver::~DtExampleDriver()
{
   DtExampleDriver::onStop();
}

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

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

   // Create the entity
   myEntityDisplayName = "Entity From Facade";
   DtElementID elementId = myAgentManager.createNewUniqueId();
   myEntityFacade = new DtEntity3dFacade( myAgentManager, elementId, true );
   reportElementCreated( elementId, 0, DtElementEntry::Entity );
   reportElementAttribute( elementId, new DtElementAttributeDisplayName(myEntityDisplayName) );
   reportElementAttribute( elementId, new DtElementAttributeVisibility(true) );

   // Load the model
   myEntityFacade->setArticulatedModelDefinition("FixedWingF-16UnarmedGrey");

   // Create the entity indicator
   myEntityIndicator =
      new DtEntityIndicatorWidget( myAgentManager, myEntityFacade->modelSet() );
   myEntityIndicator->setEventsEnabled( true );
   myEntityIndicator->setColor( 0, 0, 1, 1 );
   setHoverSignalsActive( true );

   // Attach the entity indicator to the entity
   myEntityFacade->sceneObjectAgent().addModel( myEntityIndicator->model(),
      DtStateVisualizer::EntityVisualizerType );

   // Listen for requests to pin/unpin the info label
   DtSelectionManager& selMgr(
      DtSelectionManager::instance(myAgentManager.de()) );
   selMgr.signal_entityInfoToggled.connect( boost::bind(
      &DtExampleDriver::slot_togglePinnedLabel, this, _1 ) );

   // Position on Makland
   DtVector localPosition = DtVector( 2000.0, 1400.0, 350.0 );

   DtCoordinateConverter* coordConverter =
      myAgentManager.de().sharedState().coordinateSystem().converter();

   // Setup a topographic frame for coordinate system conversion.  setupTopoFrame() wants
   // the current position in local (database, also called CIG) coordinates
   if ( coordConverter->type() == DtCoordinateConverter::Geocentric )
   {
      // => Use this for MaklandGeocentric - not exact but close enough
      DtGeodeticCoord geod( DtDeg2Rad(10.0), DtDeg2Rad(60.0), 0.0 );
      coordConverter->setupTopoFrame( geod.geocentric() );
   }
   else
   {
      // Or this for Makland (UTM)
      coordConverter->setupTopoFrame( localPosition );
   }

   // Convert an East North Up (ENU) position to our local database (CIG) coordinate system
   coordConverter->enuToCig_coordTrans( localPosition, myPosition );

   // Convert an North East Down (NED) orientation to our local database (CIG) coordinate system
   DtTaitBryan nedTb( myHeading, myPitch, myRoll );
   myOrientation = coordConverter->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;
}

bool DtExampleDriver::onStop()
{
   if ( myEntityFacade )
   {
      if ( myEntityInfoWidget )
      {
         myEntityFacade->sceneObjectAgent().removeModel(
            myEntityInfoWidget->model() );
         delete myEntityInfoWidget;
         myEntityInfoWidget;
      }

      if ( myEntityIndicator )
      {
         setHoverSignalsActive( false );
         myEntityFacade->sceneObjectAgent().removeModel(
            myEntityIndicator->model() );
         delete myEntityIndicator;
         myEntityIndicator = 0;
      }

      reportElementDestroyed( myEntityFacade->elementId() );
      delete myEntityFacade;
      myEntityFacade = 0;
   }
   return true;
}

bool DtExampleDriver::onTick()
{
   updatePosition();
   myEntityFacade->setPosition( myPosition );
   myEntityFacade->setOrientation( myOrientation );
   if ( myEntityInfoWidget )
   {
      myEntityInfoWidget->setText( generateInfoString() );
   }
   return true;
}

void DtExampleDriver::slot_displayEngineAdded( const DtDeRecord& igRecord )
{
   stop();
   start();
}

void DtExampleDriver::slot_togglePinnedLabel(
   const DtSelectionManager::IdSet& sel )
{
   DtSelectionManager::IdSet::const_iterator i = sel.begin();
   DtSelectionManager::IdSet::const_iterator e = sel.end();
   for ( ; i != e; ++i )
   {
      if ( (*i) == myEntityFacade->elementId() )
      {
         myEntityInfoWidgetPinnedFlag = ! myEntityInfoWidgetPinnedFlag;
         myEntityIndicator->setIndicatorActive( myEntityInfoWidgetPinnedFlag );
         setEntityInfoWidgetActive( myEntityInfoWidgetPinnedFlag );
         setHoverSignalsActive( ! myEntityInfoWidgetPinnedFlag );
      }
   }
}

void DtExampleDriver::slot_mouseHoverChanged( bool isHovering )
{
   setEntityInfoWidgetActive( isHovering );
}

void DtExampleDriver::setHoverSignalsActive( bool active )
{
   // Get the event signals for the entity indicator from the widget signaler.
   DtWidgetSignaler& widgetSignaler =
      DtWidgetSignaler::instance( myAgentManager.de().mainEventQueue() );
   DtWidgetEventSignals& signals = myEntityIndicator->eventSignals(
      widgetSignaler );

   // Connect to or disconnect from the signals.
   if ( active )
   {
      signals.signal_mouseEnter.connect( boost::bind(
         &DtExampleDriver::slot_mouseHoverChanged, this, true ) );
      signals.signal_mouseLeave.connect( boost::bind(
         &DtExampleDriver::slot_mouseHoverChanged, this, false ) );
   }
   else
   {
      signals.signal_mouseEnter.disconnect( boost::bind(
         &DtExampleDriver::slot_mouseHoverChanged, this, true ) );
      signals.signal_mouseLeave.disconnect( boost::bind(
         &DtExampleDriver::slot_mouseHoverChanged, this, false ) );
   }
}

void DtExampleDriver::setEntityInfoWidgetActive( bool active )
{
   if ( active && ! myEntityInfoWidget )
   {
      myEntityInfoWidget = new DtEntityInfoWidget( myAgentManager,
         myEntityFacade->modelSet(), "entityInfo" );
      myEntityInfoWidget->setColor( 0, 0, 1, 1 );
      myEntityInfoWidget->setGroup( 3 );

      myEntityFacade->sceneObjectAgent().addModel( myEntityInfoWidget->model(),
         DtStateVisualizer::EntityVisualizerType );

      DtUnicode infoString = generateInfoString();
      myEntityInfoWidget->setText( infoString );
   }
   else if ( ! active && myEntityInfoWidget )
   {
      myEntityFacade->sceneObjectAgent().removeModel(
         myEntityInfoWidget->model() );
      delete myEntityInfoWidget;
      myEntityInfoWidget = 0;
   }
}

DtUnicode DtExampleDriver::generateInfoString() const
{
   DtReferenceEllipsoid refEllip( DtWGS84 );
   DtGeodeticCoord geod( &refEllip );
   geod.setGeocentric( myPosition );

   DtVector localp;
   DtTaitBryan hpr;

   const DtCoordinateSystem& coordSys =
      myAgentManager.de().sharedState().coordinateSystem();
   coordSys.netToLocalPos( myPosition, localp );
   coordSys.netToLocalHpr( localp, myOrientation, hpr );

   const char* entityFormatString =
      "Marking :%s\n"            // Marking Text
      "Heading :%.2f Deg\n"      // Heading
      "Lat|Lon :%.2fN %.fE\n"    // Location
      "Alt.    :%.1f m above sea level";

   std::string buffer;
   buffer.resize( 1024, '0' );
   {
      int charsWritten = sprintf(
         const_cast<char*>(buffer.c_str()), entityFormatString,
         myEntityDisplayName.c_str(),  // Marking Text
         DtRad2Deg(myHeading),         // Heading
         DtRad2Deg(geod.lat()),        // Location (Lat)
         DtRad2Deg(geod.lon()),        // Location (Lon)
         myPosition[2]                 // Altitude
      );
      buffer.resize(charsWritten,'0');
   }

   return DtUnicode::fromUtf8(buffer);
}

void DtExampleDriver::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 );
}


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