VR-Forces 4.5 Class Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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();

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.

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

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

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


exampleGLDrawingPlugin.cxx

/*****************************************************************************
* Copyright (c) 2017 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/DtDe.h>
#include <vrvCore/DtSceneObjectAgent.hpp>
#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.
{
public:
: makVrv::DtDriver( am, "DtExampleDriver" )
, myEntityFacade( 0 )
, myEntityHATLineFacade( 0 )
, myOrbitCenter( 2000.0, 1400.0, 350.0 )
, myAngularVelocity( 0.1 )
, myLastUpdateTime( 0.0 )
, myClockAngle( 0.0 )
, myRadius( 1000.0 )
, myRoll( 0.0 )
, myLastCommLineTime( 0.0 )
{
}
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
myAgentManager.de().sharedState().modelSetRealizationManager().modelSetRealizations();
int parentElementId = 0;
DtElementID elementId = myAgentManager.createNewUniqueId();
myEntityFacade = new DtEntityFacade( myAgentManager,
DtSharedSettingsManager::instance( myAgentManager.de() ), elementId,
setsToRealize, false );
reportElementCreated( elementId, parentElementId, DtElementEntry::Entity );
reportElementAttribute( elementId, new DtElementAttributeDisplayName("Entity From Facade") );
reportElementAttribute( elementId, new DtElementAttributeVisibility(true) );
// Load the 3D model
if(myEntityFacade->findFacadeFor3d())
{
myEntityFacade->findFacadeFor3d()->setArticulatedModelDefinition("FixedWingRQ-1Predator");
}
// 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));
}
// Add a HAT line
if(myEntityFacade->findFacadeFor3d())
{
myEntityHATLineFacade = new DtEntityHATLineFacade( myAgentManager, myEntityFacade->findFacadeFor3d()->modelSet(),
myEntityFacade->findFacadeFor3d()->sceneObjectAgent().uniqueId() );
}
// Initialize the position.
myLastUpdateTime = myAgentManager.de().simulationTime();
updatePosition();
{ // 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();
return true;
}
protected:
virtual void updatePosition()
{
// Get current time and compute time since last update.
double now = myAgentManager.de().simulationTime();
double dt = now - myLastUpdateTime;
// Update clock angle.
myClockAngle += myAngularVelocity * dt;
// Compute offset using clock angle.
DtVector offset( myRadius*sin(myClockAngle), myRadius*cos(myClockAngle), 0 );
// Compute orientation based on heading/roll.
double heading = myClockAngle + M_PI_2;
DtTaitBryan ori( heading, 0, myRoll );
// Update the aircraft's position/orientation with the new parameters.
repositionAircraft( myOrbitCenter+offset, ori );
// Store as last update time.
myLastUpdateTime = now;
}
void repositionAircraft( DtVector position, DtTaitBryan ori )
{
// Get the coordinate converter and initialize.
DtCoordinateConverter* coordConverter;
coordConverter = myAgentManager.de().sharedState().coordinateSystem().converter();
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( position );
}
// Convert the position (from ENU) to local database (CIG) coords.
coordConverter->enuToCig_coordTrans( position, position );
// Convert the orientation (from NED) to local database (CIG) ori.
ori = coordConverter->nedToCig_EulerTrans( ori );
// Set the Position and Orientation on the aircraft.
myEntityFacade->setPosition( position );
myEntityFacade->setOrientation( ori );
}
protected:
DtEntityFacade* myEntityFacade;
DtEntityHATLineFacade* myEntityHATLineFacade;
double myAngularVelocity;
DtVector myOrbitCenter;
double myLastCommLineTime;
double myLastUpdateTime;
double myClockAngle;
double myRadius;
double myRoll;
};
{
// Create DtExampleDriver.
// 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)
// 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.
&installDriver, boost::ref(de) ));
}
}
{
// Setup the plug-in. Normally, the init function and functionality
// should be in its own library.
init(*de);
return true;
}

Document ID: Generated on Thu Mar 23 18:54:12 EDT 2017 from SVN revision 174804
Copyright © 2005-2017 VT MÄK. All Rights Reserved (www.mak.com)