Overview
Shows how to create and manipulate DtWindowObjects in VR-Vantage.
Example details
The VR-Vantage Control Toolkit lets you create 2D window objects such as lines, polygons and textboxes.
This example demonstrates an aircraft Head-Up Display (HUD), built using these window objects.
It gets the view orientation information from the observer to update a heading tape, pitch ladder, and horizon line.
The heading tape indicates the observer's heading from 0 to 360 degrees, and loops around when constantly moving in a circle.
The pitch ladder displays the observer pitch from -40 to + 40 degrees.
You can see the HUD moving by holding down the right mouse button and moving the observer view around. To roll the observer view, press 9 on the NUMPAD of the keyboard. To reset the view, press 5 on the NUMPAD of the keyboard.
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/exampleWindowObjectHud_stealth.bat (on Windows from cmd.exe) or ./bin64/exampleWindowObjectHud_stealth.sh (on Linux). For more information about running examples, please see Running Applications and Examples.
Example Source Files
DtWindowObjectHudDriver.h
#pragma once
#include <matrix/vlVector.h>
namespace makVrv
{
class DtWindowEllipseAgent;
class DtPitchLadder;
class DtHeadingTape;
class DtObserver;
class DtWindowObjectHudDriver : public DtDriver
{
public:
protected:
};
}
DtWindowObjectHudDriver.cxx
#include <matrix/vlQuaternion.h>
#include <iostream>
namespace makVrv
{
DtAgentManager& agentManager,
const std::string& instanceName )
: DtDriver( agentManager, instanceName )
, myPitchLadder(0)
, myHeadingTape(0)
, myCenterDot(0)
{
setAutoStart( true );
myUserControllableFlag = false;
}
DtWindowObjectHudDriver::~DtWindowObjectHudDriver()
{
}
const std::string& DtWindowObjectHudDriver::className()
const
{
}
bool DtWindowObjectHudDriver::onStart()
{
DtDisplayConfigurations::const_iterator displayCurIter = myAgentManager.de().deConfiguration().displayConfigurations().begin();
DtDisplayConfigurations::const_iterator displayEndIter = myAgentManager.de().deConfiguration().displayConfigurations().end();
for ( ; displayCurIter != displayEndIter; ++displayCurIter )
{
DtDisplayConfiguration* dec = *displayCurIter;
dName = dec->name();
DtWindowConfigurations::const_iterator viewCurIter = dec->windowConfigurations().begin();
DtWindowConfigurations::const_iterator viewEndIter = dec->windowConfigurations().end();
for ( ; viewCurIter != viewEndIter; ++viewCurIter )
{
DtWindowConfiguration* wc = *viewCurIter;
if ( wName == "Window 1" )
{
wc->setSize( 1000, 1000 );
if ( display )
{
if ( window )
{
display->modifyWindow( window, *wc );
}
}
}
}
}
myCenterDot = DtWindowEllipseAgent::create( myAgentManager );
myCenterDot->setPosition( 0.5, 0.5 );
myCenterDot->setNumVertices( 20 );
myCenterDot->setDimensions( 0.005, 0.005 );
DtObserver* observer = myAgentManager.de().driverManager().inputDriver().findObserverByName(
"Observer 1" );
if ( observer )
{
observer->agent().resetAttachment();
observer->agent().level();
myPitchLadder = new DtPitchLadder( myAgentManager.de(), *observer );
myHeadingTape = new DtHeadingTape( myAgentManager.de(), *observer );
myPitchLadder->init();
myHeadingTape->init();
}
return true ;
}
bool DtWindowObjectHudDriver::onStop()
{
if( myCenterDot )
{
delete myCenterDot;
myCenterDot = 0;
}
if( myPitchLadder )
{
delete myPitchLadder;
myPitchLadder = 0;
}
if( myHeadingTape )
{
delete myHeadingTape;
myHeadingTape = 0;
}
return true;
}
bool DtWindowObjectHudDriver::onTick()
{
if( myPitchLadder )
{
myPitchLadder->tick();
}
if( myHeadingTape )
{
myHeadingTape->tick();
}
return true;
}
}
exampleWindowObjectHudPluginInit.h
#pragma once
#define DT_DE_PLUGIN_EXPORT_MACRO DT_DLL_EXAMPLEWINDOWOBJECTHUD
namespace makVrv { class DtDe; }
exampleWindowObjectHudPluginInit.cxx
#include <boost/bind.hpp>
#include <string>
using namespace makVrv;
{
{
}
}
{
return true;
}
{
}
DtHeadingTape.h
#pragma once
#include <vector>
namespace makVrv
{
class DtDe;
class DtWindowObjectAgent;
class DtWindowSurfaceAgent;
class DtObserver;
class DtHeadingTape
{
public:
protected:
protected:
};
}
DtHeadingTape.cxx
#include <sstream>
namespace makVrv
{
: myDe(de)
, myWindowAgents()
, mySurface(0)
, myHeadingTapeLowObject( 0 )
, myheadingTapeHighObject( 0 )
, myObserver(observer)
{
}
DtHeadingTape::~DtHeadingTape()
{
DtWindowObjects::iterator iter = myWindowAgents.begin();
DtWindowObjects::iterator endIter = myWindowAgents.end();
for ( ; iter != endIter; ++iter )
{
DtWindowObjectAgent* toDelete = *iter;
delete toDelete;
toDelete = 0;
}
myWindowAgents.clear();
myHeadingTapeLowObject = 0;
myheadingTapeHighObject = 0;
mySurface = 0;
}
{
mySurface = DtWindowSurfaceAgent::create( myDe.agentManager() );
if ( mySurface )
{
mySurface->setPosition( 0.5, 0.85 );
mySurface->setScale( 1.0, 0.25 );
mySurface->setClipBox( 0.4, 0.805, 0.6, 0.95 );
myWindowAgents.push_back( mySurface );
}
else
{
return;
}
DtWindowPolygonAgent* headingArrow = DtWindowPolygonAgent::create( myDe.agentManager() );
headingArrow->setVertex( 0, 0.0, 0.075 );
headingArrow->setVertex( 1, 0.005, 0.045 );
headingArrow->setVertex( 2, 0.00, 0.095 );
headingArrow->setVertex( 3, -0.005, 0.045 );
headingArrow->setFill( true );
mySurface->addChild( headingArrow->uniqueId() );
myWindowAgents.push_back( headingArrow );
myHeadingTapeLowObject = DtWindowLineAgent::create( myDe.agentManager() );
myHeadingTapeLowObject->setPosition( 0.0, 0.0 );
myWindowAgents.push_back( myHeadingTapeLowObject );
mySurface->addChild( myHeadingTapeLowObject->uniqueId() );
myheadingTapeHighObject = DtWindowLineAgent::create( myDe.agentManager() );
myheadingTapeHighObject->setPosition( 0.0, 0.0 );
myWindowAgents.push_back( myheadingTapeHighObject );
mySurface->addChild( myheadingTapeHighObject->uniqueId() );
for ( int i = 0; i <= 36; ++i )
{
DtWindowLineAgent* lowHeadingLine = DtWindowLineAgent::create( myDe.agentManager() );
lowHeadingLine->setVertex( 0, 0.0, 0.1 );
lowHeadingLine->setVertex( 1, 0.0, 0.175 );
lowHeadingLine->setWidth( 3 );
lowHeadingLine->setPosition( xOffset, 0.0 );
myHeadingTapeLowObject->addChild( lowHeadingLine->uniqueId() );
myWindowAgents.push_back( lowHeadingLine );
DtWindowLineAgent* highHeadingLine = DtWindowLineAgent::create( myDe.agentManager() );
highHeadingLine->setVertex( 0, 0.0, 0.1 );
highHeadingLine->setVertex( 1, 0.0, 0.175 );
highHeadingLine->setWidth( 3 );
highHeadingLine->setPosition( -xOffset, 0.0 );
myheadingTapeHighObject->addChild( highHeadingLine->uniqueId() );
myWindowAgents.push_back( highHeadingLine );
if ( i % 2 == 0 )
{
float textXOffset = (float)-0.005;
float textYOffset = (float)0.05;
DtWindowTextAgent* lowHeadingText = DtWindowTextAgent::create( myDe.agentManager() );
lowHeadingText->setTopLeftCorner( (float)textXOffset, (float)textYOffset );
std::ostringstream ss;
ss << i / 2;
if ( i < 20 )
{
onScreenStr = "0" + onScreenStr;
}
lowHeadingText->setText( onScreenStr );
lowHeadingText->setFont(
"FreeMono.otf",
HudFontSize );
lowHeadingText->setVisible( true );
lowHeadingText->setAlignment( 0 );
lowHeadingLine->addChild( lowHeadingText->uniqueId() );
myWindowAgents.push_back( lowHeadingText );
DtWindowTextAgent* highHeadingText = DtWindowTextAgent::create( myDe.agentManager() );
highHeadingText->setTopLeftCorner( (float)textXOffset, (float)textYOffset );
if ( i == 0 )
{
onScreenStr = "00";
}
else
{
int headingOutput = (36 - (i / 2));
ss << headingOutput;
onScreenStr = ss.str();
}
highHeadingText->setText( onScreenStr );
highHeadingText->setFont(
"FreeMono.otf",
HudFontSize );
highHeadingText->setVisible( true );
highHeadingText->setAlignment( 0 );
highHeadingLine->addChild( highHeadingText->uniqueId() );
myWindowAgents.push_back( highHeadingText );
}
}
}
void DtHeadingTape::tick()
{
double curPhi, curTheta, curPsi;
myObserver.getTopographicOrientation( curPhi, curTheta, curPsi );
double xPos = 0.0;
double yPos = 0.0;
if ( myHeadingTapeLowObject )
{
DtWindowObject* lowHeadingTape = myHeadingTapeLowObject->findObject();
if ( lowHeadingTape )
{
lowHeadingTape->getPosition( xPos, yPos );
if ( DtDeg2Rad( -180.0 ) < curPhi && curPhi < DtDeg2Rad( -135.0 ) )
{
}
else
{
}
myHeadingTapeLowObject->setPosition( xPos, yPos );
}
}
if ( myheadingTapeHighObject )
{
DtWindowObject* highHeadingTape = myheadingTapeHighObject->findObject();
if ( highHeadingTape )
{
highHeadingTape->getPosition( xPos, yPos );
if ( DtDeg2Rad( 135.0 ) < curPhi && curPhi < DtDeg2Rad( 180.0 ) )
{
}
else
{
}
myheadingTapeHighObject->setPosition( xPos, yPos );
}
}
}
}
DtPitchLadder.h
#pragma once
#include <vector>
namespace makVrv
{
class DtDe;
class DtWindowObjectAgent;
class DtWindowSurfaceAgent;
class DtObserver;
class DtPitchLadder
{
public:
protected:
protected:
protected:
};
}
DtPitchLadder.cxx
namespace makVrv
{
: myDe(de)
, myWindowAgents()
, myPitchLadderRootObject(0)
, mySurface(0)
, lastPhi(0.0)
, lastTheta(0.0)
, lastPsi(0.0)
, myObserver( observer )
, myHorizonRootObject(0)
{
}
DtPitchLadder::~DtPitchLadder()
{
DtWindowObjects::iterator iter = myWindowAgents.begin();
DtWindowObjects::iterator endIter = myWindowAgents.end();
for ( ; iter != endIter; ++iter )
{
DtWindowObjectAgent* toDelete = *iter;
delete toDelete;
toDelete = 0;
}
myWindowAgents.clear();
myPitchLadderRootObject = 0;
mySurface = 0;
}
{
myObserver.getTopographicOrientation( lastPhi, lastTheta, lastPsi );
mySurface = DtWindowSurfaceAgent::create( myDe.agentManager() );
if ( mySurface )
{
mySurface->setClipBox( 0.25, 0.2, 0.75, 0.8 );
mySurface->setPosition( 0.5, 0.5 );
mySurface->setScale( 1.0, 1.0 );
mySurface->setScaleToClipBox( false );
myWindowAgents.push_back( mySurface );
}
drawPitchLadder();
drawHorizon();
}
void DtPitchLadder::tick()
{
double curPhi, curTheta, curPsi;
myObserver.getTopographicOrientation( curPhi, curTheta, curPsi );
double x = 0.0;
double y = 0.0;
if ( myPitchLadderRootObject )
{
DtWindowObject* pitchLadderRoot = myPitchLadderRootObject->findObject();
if ( pitchLadderRoot )
{
x = -std::sin( curPsi ) * pTranslatDist;
y = std::cos( curPsi ) * pTranslatDist;
myPitchLadderRootObject->setPosition( -x, -y );
myPitchLadderRootObject->setRotation( curPsi );
}
}
if ( myHorizonRootObject )
{
DtWindowObject* horizonRoot = myHorizonRootObject->findObject();
if ( horizonRoot )
{
double pTranslatDist = -DtRad2Deg( curTheta ) * ((0.5) / 22.5);
x = -std::sin( curPsi ) * pTranslatDist;
y = std::cos( curPsi ) * pTranslatDist;
myHorizonRootObject->setPosition( x, y );
}
if (curPsi != lastPsi)
{
myHorizonRootObject->setRotation(curPsi);
}
}
lastPsi = curPsi;
lastTheta = curTheta;
lastPhi = curPhi;
}
void DtPitchLadder::drawHorizon()
{
myHorizonRootObject = DtWindowLineAgent::create( myDe.agentManager() );
myHorizonRootObject->setPosition( 0.0, 0.0 );
myWindowAgents.push_back( myHorizonRootObject );
mySurface->addChild( myHorizonRootObject->uniqueId() );
DtWindowLineAgent* leftHorizon = DtWindowLineAgent::create( myDe.agentManager() );
leftHorizon->setVertex( 0, -0.13, 0.0 );
leftHorizon->setVertex( 1, -0.20, 0.0 );
leftHorizon->setVertex( 2, -0.20, -0.025 );
leftHorizon->setWidth( 3 );
myHorizonRootObject->addChild( leftHorizon->uniqueId() );
myWindowAgents.push_back( leftHorizon );
DtWindowLineAgent* rightHorizon = DtWindowLineAgent::create( myDe.agentManager() );
rightHorizon->setVertex( 0, 0.13, 0.0 );
rightHorizon->setVertex( 1, 0.20, 0.0 );
rightHorizon->setVertex( 2, 0.20, -0.025 );
rightHorizon->setWidth( 3 );
myHorizonRootObject->addChild( rightHorizon->uniqueId() );
myWindowAgents.push_back( rightHorizon );
}
void DtPitchLadder::drawPitchLadder()
{
myPitchLadderRootObject = DtWindowLineAgent::create( myDe.agentManager() );
myPitchLadderRootObject->setPosition( 0.0, 0.0 );
myWindowAgents.push_back( myPitchLadderRootObject );
mySurface->addChild( myPitchLadderRootObject->uniqueId() );
for ( int i = -8; i <= 8; i = i + 1 )
{
DtWindowLineAgent* pitchLine = DtWindowLineAgent::create( myDe.agentManager() );
double invertLine = 0.0;
if ( i < 0 )
{
invertLine = 0.015;
pitchLine->setSegmentStipplePattern( 2, 1, 0x00FF );
}
else if ( i == 0 )
{
invertLine = 0.0075;
}
pitchLine->setVertex( 0, -0.1, (invertLine - 0.0075) + totalOffset );
pitchLine->setVertex( 1, -0.1, 0.0 + totalOffset );
pitchLine->setVertex( 2, -0.1, 0.0 + totalOffset );
pitchLine->setVertex( 3, 0.1, 0.0 + totalOffset );
pitchLine->setVertex( 4, 0.1, (invertLine - 0.0075) + totalOffset );
pitchLine->setVertex( 5, 0.1, 0.0 + totalOffset );
pitchLine->setWidth( 3 );
myPitchLadderRootObject->addChild( pitchLine->uniqueId() );
myWindowAgents.push_back( pitchLine );
DtWindowTextAgent* pitchTextRight = DtWindowTextAgent::create( myDe.agentManager() );
pitchTextRight->setColor( 0.0, 1.0, 0.0, 1.0 );
pitchTextRight->setTopLeftCorner( (float)0.105, (float) -0.006 + totalOffset );
std::ostringstream ss;
ss << std::abs( 5 * i );
pitchTextRight->setText( ss.str() );
pitchTextRight->setFont(
"FreeMono.otf",
HudFontSize );
pitchTextRight->setVisible( true );
pitchTextRight->setAlignment( 0 );
myPitchLadderRootObject->addChild( pitchTextRight->uniqueId() );
myWindowAgents.push_back( pitchTextRight );
DtWindowTextAgent* pitchTextLeft = DtWindowTextAgent::create( myDe.agentManager() );
pitchTextLeft->setTopLeftCorner( (float) -0.135, (float) -0.006 + totalOffset );
pitchTextLeft->setText( ss.str() );
pitchTextLeft->setVisible( true );
pitchTextLeft->setAlignment( 2 );
pitchTextLeft->setTextBoxWidth( 28 );
myPitchLadderRootObject->addChild( pitchTextLeft->uniqueId() );
myWindowAgents.push_back( pitchTextLeft );
}
}
}
DtHudConstants.h
#pragma once
#define HudFontSize 16
#define HudColorG 1.0
#define HudColorB 0.0
#define HudColorR 0.0
#define HudColorA 1.0
#define PitchScreenUnitsPerDegree 0.05
#define HeadingScreenUnitsPerDegree 0.015
[<< Examples] [Home] [Top of Page]