![]() |
VR-Vantage 1.4.1 API Class Documentation
|
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() );
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.
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.
/***************************************************************************** * 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(); }
/***************************************************************************** * 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; };
/***************************************************************************** * 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 ); }