This example shows how to create a plug-in that adds updaters for a GL Studio cockpit (HUD) display.
It adds two new updaters: one is VR-Link protocol-specific and is used in the network thread; one is used in the render thread and is considered to use the object protocol.
As seen in exampleHatchStateUpdater.h and exampleMetersPerSecondUpdater.h, all updaters return a string that is used by the GL Studio object to update the display.
virtual std::string value();
Each of the updaters also has a creator that is registered with the updater factory.
{
public:
DtGlStudioHatchStateUpdaterCreator();
virtual ~DtGlStudioHatchStateUpdaterCreator();
virtual DtGlStudioAttributeUpdater* create() const;
protected:
};
In exampleHudUpdaterPluginInit.cxx the Plugin loader needs to make sure that GL Studio plugin has been initialized and then register a post-initialize function with the display engine to add the new updaters to the updater factory.
try
{
}
DtCATCH_AND_PROPAGATE(DtCorruptedState)
In the post-initialize function the updater factory is populated with new updaters. The updater factory is owned by the DtSharedCockpitSettings object. Updater creators are registered with the factory. If an updater creator has the same protocol and name as an existing creator, it will replace the creator.
{
DtSharedCockpitSettingsManager::instance(*de);
{
DtWriteSettingsLock<DtSharedCockpitSettings> settings(DtSharedSettingsManager::instance(*de));
DtGlStudioAttributeUpdaterFactory& factory=settings->updaterFactory();
factory.registerUpdater(new vrvDis::DtGlStudioHatchStateUpdaterCreator());
factory.registerUpdater(new DtExampleMetersPerSecondUpdaterCreator());
}
All updater creators have a name and a protocol that are set in their constructor. The factory uses these to do lookups when a HUD object is created.
:DtGlStudioAttributeUpdaterCreator()
{
myName="MetersPerSecond";
myProtocol="Object";
}
TheDtExampleMetersPerSecondUpdater is derived from a DtGlStudioObjectAttributeUpdater since it is going to live on the object (GL Studio object) side, or in the render thread.
All updaters that are of the "object" protocol have access to a smoother object which is able to get the smoothed values for position, velocity and accelleration at the specific time called.
std::string DtExampleMetersPerSecondUpdater::value(double time)
{
if(mySmoother!=NULL)
{
myVelocity=mySmoother->approxVelocity(time);
std::stringstream ss;
double magnitude= sqrt(myVelocity.magnitudeSquared());
ss << magnitude;
return ss.str();
}
return "0.0";
The DtGlStudioHatchStateUpdater is a VR-Link protocol updater that is derived from the DtGlStudioVrlAttributeUpdater. This class uses the shared source technique common in VR-Vantage. The protocol specific updaters also return a string value and have a creator exactly like the object protocol updaters. VR-Link protocol updaters are placed in a protocol-specific namespace to keep from conflicting with the same updater for other protocols.
The VR-Link protocol updater is initialized with a DtVrlinkEntityStateListener. This listener provides access to the VR-Link entity state repository and allows for signals to be sent when attributes change.
{
myEntityConnections += listener->signal_appearanceBitSet.connect(
boost::bind(&DtGlStudioHatchStateUpdater::setAppearanceBit, this, _1, _2));
setAppearanceBit(0, listener->esr().appearance());
}
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/exampleHudUpdater_stealth.bat (on Windows) or ./bin/exampleHudUpdater_stealth.sh (on Linux). For more information about running examples, please see Running Applications and Examples.
Example Source Files
exampleHatchStateUpdater.h
#ifndef DT_PROTOCOL_NAMESPACE
#error Namespace Protocol Macro DT_PROTOCOL_NAMESPACE not defined.
#endif
#ifndef DtExampleHudUpdater_H_
#define DtExampleHudUpdater_H_
namespace makVrv
{
{
class DtGlStudioHatchStateUpdater : public DtGlStudioVrlAttributeUpdater
{
public:
virtual std::string
value();
protected:
};
{
public:
DtGlStudioHatchStateUpdaterCreator();
virtual ~DtGlStudioHatchStateUpdaterCreator();
virtual DtGlStudioAttributeUpdater* create() const;
protected:
};
}
}
#endif
exampleHatchStateUpdater.inl
#include <vl/entitySR.h>
#include <boost/bind.hpp>
namespace makVrv
{
{
:DtGlStudioVrlAttributeUpdater()
{
}
DtGlStudioHatchStateUpdater::~DtGlStudioHatchStateUpdater()
{
}
{
myEntityConnections += listener->signal_appearanceBitSet.connect(
boost::bind(&DtGlStudioHatchStateUpdater::setAppearanceBit, this, _1, _2));
setAppearanceBit(0, listener->esr().appearance());
}
std::string DtGlStudioHatchStateUpdater::value()
{
myIsDirty=false;
if(myHatchState==DtHatchOpenBitVal)
{
return "true";
}
return "false";
}
void DtGlStudioHatchStateUpdater::setAppearanceBit(unsigned int oldBits, unsigned int newBits)
{
unsigned oldHatch = oldBits & DtAppHatch;
unsigned newHatch = newBits & DtAppHatch;
if(oldHatch != newHatch)
{
myIsDirty=true;
myHatchState = newHatch;
}
}
DtGlStudioHatchStateUpdaterCreator::DtGlStudioHatchStateUpdaterCreator()
:DtGlStudioAttributeUpdaterCreator()
{
myName="HatchState";
#ifdef DtDIS
myProtocol="DtDis";
#else
#ifdef DtHLA_1516
#ifdef DtHLA_1516_EVOLVED
myProtocol="DtHla1516e";
#else
myProtocol="DtHla1516";
#endif
#else
myProtocol="DtHla13";
#endif
#endif
}
DtGlStudioHatchStateUpdaterCreator::~DtGlStudioHatchStateUpdaterCreator()
{
}
DtGlStudioAttributeUpdater* DtGlStudioHatchStateUpdaterCreator::create() const
{
return new DtGlStudioHatchStateUpdater();
}
}
}
exampleMetersPerSecondUpdater.cxx
#include <vlpi/smoother.h>
namespace makVrv
{
:DtGlStudioObjectAttributeUpdater()
{
}
DtExampleMetersPerSecondUpdater::~DtExampleMetersPerSecondUpdater()
{
}
std::string DtExampleMetersPerSecondUpdater::value(double time)
{
if(mySmoother!=NULL)
{
myVelocity=mySmoother->approxVelocity(time);
std::stringstream ss;
double magnitude= sqrt(myVelocity.magnitudeSquared());
ss << magnitude;
return ss.str();
}
return "0.0";
}
DtExampleMetersPerSecondUpdaterCreator::DtExampleMetersPerSecondUpdaterCreator()
:DtGlStudioAttributeUpdaterCreator()
{
myName="MetersPerSecond";
myProtocol="Object";
}
DtExampleMetersPerSecondUpdaterCreator::~DtExampleMetersPerSecondUpdaterCreator()
{
}
DtGlStudioAttributeUpdater* DtExampleMetersPerSecondUpdaterCreator::create() const
{
return new DtExampleMetersPerSecondUpdater();
}
}
exampleMetersPerSecondUpdater.h
#ifndef DtExampleMetersPerSecondUpdater_h
#define DtExampleMetersPerSecondUpdater_h
#include <matrix/vlVector.h>
namespace makVrv
{
class DtExampleMetersPerSecondUpdater : public DtGlStudioObjectAttributeUpdater
{
public:
virtual std::string
value(
double time);
protected:
};
{
public:
DtExampleMetersPerSecondUpdaterCreator();
virtual ~DtExampleMetersPerSecondUpdaterCreator();
virtual DtGlStudioAttributeUpdater* create() const;
protected:
};
}
#endif
exampleHudUpdaterPluginInit.cxx
#include <boost/bind.hpp>
#define DT_PROTOCOL_NAMESPACE vrvDis
#include <vl/globalObjDes.h>
#include <vl/entitySR.h>
#include <vlpi/entityIdentifier.h>
#undef DT_PROTOCOL_NAMESPACE
using namespace makVrv;
{
{
return true;
}
return false;
}
{
{
}
}
namespace makVrv
{
namespace vrvExampleHudUpdaterPlugin
{
{
try
{
}
DtCATCH_AND_PROPAGATE(DtCorruptedState)
}
}
}