VR-Vantage 1.4.1 API Class Documentation
exampleSendDrawControl

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

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. You can run it by running ./bin/exampleSendDrawControl<protocol>.exe (on Windows) or ./bin/exampleSendDrawControl<protocol> (on Linux). For more information about running examples, please see Running Applications and Examples.

Example Source Files


sendDrawControl.cxx

/*********************************************************************
** Copyright (c) 2010 MaK Technologies, Inc.
** All rights reserved.
*********************************************************************/
/*********************************************************************
** $RCSfile: sendDrawControl.cxx,v $ $Revision: 1.1 $ $State: Exp $
*********************************************************************/
#include <vrvDrawControl/DtEllipsoidObject.h>
#include <vrvDrawControl/DtCuboidObject.h>

#include <vl/exerciseConn.h>
#include <vl/exConnInit.h>

#include <matrix/geodCoord.h>

#include <vlutil/vlKeyboard.h>

#include <vrvDrawControl/DtCylinderObject.h>
#include <vrvDrawControl/DtAttributeGroupTemplateObject.h>
#include <vrvDrawControl/DtAttributeGroupObject.h>

#include <vl/entityPub.h>
#include <vl/entitySR.h>

#include <vl/topoView.h>

#include <vl/dataInter.h>
#include <vrvControl/DtVrlinkDataInterMarshaller.h>
#include <vrvControl/vrvControlToolkitDataTypes.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);

   DtVrlinkDataInterMarshaller<DtDataInteraction> marshaller;

   // 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.setColor(DtVdcColor::DtVdcGreen);
   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.setColor(DtVdcColor::DtVdcRed);
   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.setColor(DtVdcColor::DtVdcYellow);
   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
         DtRemoteGraphicSet_v1 rgCommand;
         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
         DtRemoteGraphicSet_v1 rgCommand;
         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(velocity);
      topoView.setAcceleration(acceleration);
      topoView.setOrientation(euler);
      topoView.setRotationalVelocity(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
   }
}


Copyright © 2005-2012 VT MÄK Inc. All Rights Reserved (www.mak.com)