![]() |
VR-Vantage 1.4.1 API Class Documentation
|
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.
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.
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.
/********************************************************************* ** 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 } }