VR-Forces 5.0.3 Developer's Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
exampleSendDrawControl

Table of Contents

Overview

This example demonstrates how to use the vrvControlToolkit to send both draw and view control messages to an instance of VR-Vantage.

Expected Result

exampleSendDrawControl.png
Send Draw Control Result

Example details

Upon running this example, an F-18 will appear in an orbit over Makland. A box is drawn to indicate the F-18's starting position, and a cylinder connects the F-18 to the box. A sphere is also drawn, bouncing between the F-18 and the box along the cylinder. When the example is running, you can press 'h' (and press enter) to hide the drawn objects (box/cylinder/sphere). Pressing 's' will show them again. Typing 'q' will shut down the example.

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. Start Vantage first, then load makland terrain and connect with the protocol you want to test. Then run ./bin64/exampleSendDrawControl<protocol>.exe (on Windows) or ./bin64/exampleSendDrawControl<protocol> (on Linux) and press 'h' to hide the object and 's' and to draw. For more information about running examples, please see Running Applications and Examples.


Example Source Files


sendDrawControl.cxx

/*********************************************************************
** Copyright (c) 2019 MaK Technologies, Inc.
** All rights reserved.
*********************************************************************/
#include <vl/exerciseConn.h>
#include <vl/exerciseConnInitializer.h>
#include <matrix/geodeticCoord.h>
#include <vlutil/vlKeyboard.h>
#include <vl/entityPublisher.h>
#include <vl/entityStateRepository.h>
#include <vl/topoView.h>
#include <vl/dataInteraction.h>
using namespace vrvControlToolkit;
DtVector position;
DtVector velocity;
DtVector acceleration;
DtTaitBryan euler;
DtVector rotationRate;
double scalerAcceleration = 0.0;
double speed = 0.0;
double turnRate = 0.0;
DtTime dt = 0.05;
int keyTick()
{
char *keyPtr = DtPollBlockingInputLine();
if (keyPtr && (*keyPtr == 'q' || *keyPtr == 'Q'))
{
return -1;
}
if (keyPtr && (*keyPtr == 's' || *keyPtr == 'S'))
{
return 1;
}
if (keyPtr && (*keyPtr == 'h' || *keyPtr == 'H'))
{
return 2;
}
return 0;
}
void initSpatial()
{
position.setZ(-1230);
speed = 40.0;
double turnRadius = -250.0;
turnRate = speed / turnRadius;
double roll = atan(5.0 * turnRate);
euler.setPsi(DtDeg2Rad(180));
euler.setPhi(roll);
double psi = euler.psi();
double cosPsi = cos( psi );
double sinPsi = sin( psi );
double phi = euler.phi();
double cosPhi = cos( phi );
double sinPhi = sin( phi );
velocity.setX(cosPsi * speed);
velocity.setY(sinPsi * speed);
velocity.setZ(0.0);
// force a constant rate turn
scalerAcceleration = speed * turnRate;
acceleration.setX(-scalerAcceleration * sinPsi);
acceleration.setY(scalerAcceleration * cosPsi);
acceleration.setZ(0.0);
rotationRate.setX(0.0);
rotationRate.setY(sinPhi * turnRate);
rotationRate.setZ(cosPhi * turnRate);
}
void updateSpatial()
{
double psi =
DtModPerZero( ( euler.psi() + ( turnRate * dt ) ), M_2PI );
euler.setPsi( psi );
for( int i=0; i<3; ++i )
{
position[i] += ( velocity[i] + 0.5 * acceleration[i] * dt ) * dt;
velocity[i] += acceleration[i] * dt;
}
acceleration[0] = -scalerAcceleration * sin( psi );
acceleration[1] = scalerAcceleration * cos( psi );
acceleration[2] = 0.0;
}
int main(int argc, char** argv)
{
// Initialize the application and connect
DtVrlApplicationInitializer appInit(argc, argv, "sendDrawControl");
appInit.parseCmdLine();
DtExerciseConn exConn(appInit);
exConn.setApplicationId(3, 5);
// Create an F-18, and initialize it's values
DtEntityType entType(1, 2, 225, 1, 9, 0, 0);
DtEntityPublisher f18(entType, &exConn, DtDrDrmRvw, DtForceFriendly,
DtEntityPublisher::guiseSameAsType());
DtTopoView topoView(f18.esr(), DtDeg2Rad(10.0), DtDeg2Rad(60.0));
initSpatial();
f18.esr()->setMarkingText("VR-Link F18");
// Create a cube at the point where the F18 starts
int startId = 12;
DtGeodeticCoord coord(DtDeg2Rad(10), DtDeg2Rad(60), 1230);
DtVector geocentricCoord;
coord.getGeocentric(geocentricCoord);
DtCuboidObject cube(&exConn, startId++,
geocentricCoord, 25, 25, 25);
cube.setRemoteGraphicSet("3D Graphics::Shapes");
// Create a cylinder that connects the cube to the F18
DtCylinderObject cylinder(&exConn, startId++,
cube.globalId(), f18.globalId(), DtVdcVector2D(5, 5));
cylinder.setRemoteGraphicSet("3D Graphics::Shapes");
// Create a sphere that's attached to the cylinder, at the first vertex.
// The position along the cylinder will change as the application runs.
double spherePosition = 0;
DtEllipsoidObject sphere(&exConn, startId++,
DtVdc3DAttachPoint(cylinder.globalId(), spherePosition), DtVector(
10, 10, 10));
sphere.setRemoteGraphicSet("3D Graphics::Shapes");
// The sphere will have a "Sphere" attribute placard, that has one attribute
// named "Position". This is a value bar attribute whose values can be between
// 0 and 100.
DtAttributeGroupTemplateObject sphereTemplate(&exConn, startId++,
"Sphere");
sphereTemplate.createAttributeTemplate("Position", 0.0, 100.0);
// Create a placard and attach it to the sphere
DtAttributeGroupObject spherePlacard(&exConn, startId++,
&sphereTemplate, sphere.globalId());
spherePlacard.setValueBarAttributeValue("Position", spherePosition);
spherePlacard.setColor(DtVdcColor::DtVdcYellow);
spherePlacard.setRemoteGraphicSet("3D Graphics::Placards");
// The entity will have an "Entity" attribute placard that has 2 attributes that
// are numeric values: "Heading" and "Speed".
DtAttributeGroupTemplateObject entityTemplate(&exConn, startId++,
"Entity");
entityTemplate.createAttributeTemplate("Heading", DtAttributeTemplateObject::DtVdcAttributeTypeValueNumeric);
entityTemplate.createAttributeTemplate("Speed", DtAttributeTemplateObject::DtVdcAttributeTypeValueNumeric);
// Create a placard and attach it to the entity
DtAttributeGroupObject entityPlacard(&exConn, startId++,
&entityTemplate, f18.globalId());
entityPlacard.setNumericAttributeValue("Heading", DtRad2Deg(topoView.orientation().psi()));
entityPlacard.setNumericAttributeValue("Speed", speed);
entityPlacard.setColor(DtVdcColor::DtVdcBlue);
entityPlacard.setRemoteGraphicSet("3D Graphics::Placards");
DtClock* clock = exConn.clock();
DtTime simTime = 0;
bool sphereIncreasing = true;
while (true)
{
int key = keyTick();
if (key == -1)
{
break;
}
else if (key == 1)
{
// Send a "show" PDU for the 3D Graphics set
sprintf(rgCommand.mySetName, "3D Graphics");
rgCommand.myState = true;
DtDataInteraction dataInter;
marshaller.encode(&rgCommand, &dataInter);
exConn.sendStamped(dataInter);
}
else if (key == 2)
{
// Send a "hide" PDU for the 3D Graphics set
sprintf(rgCommand.mySetName, "3D Graphics");
rgCommand.myState = false;
DtDataInteraction dataInter;
marshaller.encode(&rgCommand, &dataInter);
exConn.sendStamped(dataInter);
}
// Tell VR-Link the current value of simulation time.
clock->setSimTime(simTime);
// Process any incoming messages.
exConn.drainInput();
// Update the F18's spatial values.
updateSpatial();
// Now that we're done simulating, tell the entity publisher
// about our current state:
topoView.setLocation(position);
topoView.setVelocity(DtVector64To32(velocity));
topoView.setAcceleration(DtVector64To32(acceleration));
topoView.setOrientation(euler);
topoView.setRotationalVelocity(DtVector64To32(rotationRate));
// Update the percentage along the cylinder that the sphere lies on.
if (sphereIncreasing)
{
spherePosition += 1.0;
if (spherePosition >= 100.0)
{
sphereIncreasing = false;
}
}
else
{
spherePosition -= 1.0;
if (spherePosition <= 0)
{
sphereIncreasing = true;
}
}
// Change the position of the sphere
DtVdc3DAttachPoint sphereAttach(cylinder.globalId(), spherePosition);
sphere.setAttachment(sphereAttach);
// Update the Position on the sphere's placard
spherePlacard.setValueBarAttributeValue("Position", spherePosition);
// Update entity's placard
entityPlacard.setNumericAttributeValue("Heading", (int)DtRad2Deg(topoView.orientation().psi()));
entityPlacard.setNumericAttributeValue("Speed", speed);
// Update all of our objects
f18.tick();
cube.update();
cylinder.update();
sphere.update();
sphereTemplate.update();
spherePlacard.update();
entityTemplate.update();
entityPlacard.update();
DtTime sleeptime = ( simTime += dt ) - clock->elapsedRealTime();
DtSleep( sleeptime ); // returns immediately if negative
}
return 0;
}

Document ID: Generated on Thu Jun 1 17:58:13 EDT 2023 from SVN revision 255404
Copyright © 2005-2021 MAK Technologies. All Rights Reserved (www.mak.com)