![]() |
VR-Forces 4.0.4 Class Documentation
|
The Add Terrain Features example demonstrates the following:
This example demonstrates how to programmatically modify an existing GDB (VR-Forces native format) terrain database. It adds vector features to a terrain database.
(in bin directory)
addTerrainFeatures
To run the example:
In step 1, a simple terrain database named data\terrain\simpleTerrain.gdb will be created. This database has no features. The addTerrainFeatures application //! adds several features to the terrain, including a stream, a tree, and a couple of buildings. Open the terrain database using TDBTool to view the new features.
/******************************************************************************* ** Copyright (c) 2003 MAK Technologies, Inc. ** All rights reserved. *******************************************************************************/ /******************************************************************************* ** $RCSfile: main.cxx,v $ $Revision: 1.18 $ $State: Exp $ *******************************************************************************/ #include "gdb/terrainDb.h" #include "geometry/point.h" #include "geometry/surface.h" #include "gdb/triInd.h" #include <vlutil/vlPrint.h> #include "gdb/vecNetwrk.h" #include "gdb/specification.h" #include "gdb/netwrkNode.h" #include "gdb/gdbNode.h" #include "gdb/netwrkSeg.h" #include "gdb/netwrkEdge.h" #include "terrainDbFactory/tdbManager.h" bool createTrees(DtVectorNetwork& vectorNetwork) { // Get a convenience reference to the vector network's specification manager DtSpecificationManager& specificationManager = vectorNetwork.specificationManager(); // Create a specification for a tree DtSpecification treeSpec; treeSpec.setColor(DtColor(0,200,0,0)); // r,g,b,a (0-255) treeSpec.setWidth(5.0); treeSpec.setLength(5.0); treeSpec.addIntegerAttribute("DtFidCode", 953); treeSpec.addIntegerAttribute("DtFacNumber", 0); treeSpec.addIntegerAttribute("DtFeatureType", 0); treeSpec.addStringAttribute("DtFeatureName","953 Evergreen Trees (including Mangrove and Nipa)"); treeSpec.addIntegerAttribute("DtSmc", 12); treeSpec.addStringAttribute("DtFeatureGroupName", "Vegetation"); treeSpec.addStringAttribute("DtFeatureGroup", "MAK040"); treeSpec.addStringAttribute("DtDescription","Trees"); treeSpec.addStringAttribute("ECC","EC030"); treeSpec.addIntegerAttribute("DtSedrisCodes", 1); treeSpec.addStringAttribute("SEDRISCODE1","TRE002"); treeSpec.addStringAttribute("TRE002","Evergreen"); treeSpec.addIntegerAttribute("DtOrientation", 0); treeSpec.addIntegerAttribute("DtHeight", 5); // Add the tree specification to the vector network's specification manager DtSpecificationID treeSpecID; if(!specificationManager.addSpecification(treeSpec, treeSpecID)) { DtWarn("Couldn't add tree specification to specification manager.\n"); return false; } // Create a tree DtNetworkNode* treeNode = vectorNetwork.newNode(); // Position it the upper right-hand quadrant of the terrain treeNode->setLocation(DtPoint(750, 750, 0)); treeNode->setSpecificationID(treeSpecID); // Add it to the database vectorNetwork.addOn(*treeNode); // Create another tree (using the same specification) treeNode = vectorNetwork.newNode(); // Position it the lower left-hand quadrant of the terrain treeNode->setLocation(DtPoint(250, 250, 0)); treeNode->setSpecificationID(treeSpecID); // Add it to the database vectorNetwork.addOn(*treeNode); return true; } bool createArealBuilding(DtVectorNetwork& vectorNetwork) { // Get a convenience reference to the vector network's specification manager DtSpecificationManager& specificationManager = vectorNetwork.specificationManager(); // Create a specification for an areal building feature DtSpecification arealBuildingSpec; arealBuildingSpec.setColor(DtColor(255,145,0,0)); // r,g,b,a (0-255) arealBuildingSpec.addIntegerAttribute("DtFidCode", 181); arealBuildingSpec.addIntegerAttribute("DtFacNumber", 1); arealBuildingSpec.addIntegerAttribute("DtFeatureType", 2); arealBuildingSpec.addStringAttribute("DtFeatureName","181 building"); arealBuildingSpec.addIntegerAttribute("DtSmc", 3); arealBuildingSpec.addStringAttribute("DtFeatureGroupName", "Feature"); arealBuildingSpec.addStringAttribute("DtFeatureGroup", "MAK000"); arealBuildingSpec.addStringAttribute("DtDescription","Building"); arealBuildingSpec.addStringAttribute("ECC","AL015"); arealBuildingSpec.addIntegerAttribute("DtSedrisCodes", 0); arealBuildingSpec.addStringAttribute("SEDRISCODE1","TRE002"); arealBuildingSpec.addStringAttribute("TRE002","Evergreen"); arealBuildingSpec.addIntegerAttribute("DtOrientation", 0); arealBuildingSpec.addIntegerAttribute("DtHeight", 100); // 100 meters long (centered at 650 meters along X-axis) arealBuildingSpec.addRealAttribute("DtXMin", 610); arealBuildingSpec.addRealAttribute("DtXMax", 710); // 50 meters wide (centered at 625 meters along Y-axis) arealBuildingSpec.addRealAttribute("DtYMin", 610.0); arealBuildingSpec.addRealAttribute("DtYMax", 660.0); arealBuildingSpec.addRealAttribute("DtZMin", 0.0); arealBuildingSpec.addRealAttribute("DtZMax", 100.0); DtSpecificationID arealBuildingSpecID; if(!specificationManager.addSpecification(arealBuildingSpec, arealBuildingSpecID)) { DtWarn("Couldn't add arealBuilding specification to the specification manager.\n"); return false; } // Create the areal buildings start/end node DtNetworkNode* arealBuildingStartNode = vectorNetwork.newNode(); assert(arealBuildingStartNode != NULL); arealBuildingStartNode->setLocation(DtPoint(710, 610, 0)); arealBuildingStartNode->setSpecificationID(arealBuildingSpecID); vectorNetwork.addOn(*arealBuildingStartNode); DtNetworkNode* arealBuildingEndNode = arealBuildingStartNode; // for areal features, end is start // Create the building's centroid node DtNetworkNode* arealBuildingCentroidNode = vectorNetwork.newNode(); assert(arealBuildingCentroidNode != NULL); arealBuildingCentroidNode->setLocation(DtPoint(660, 635, 0)); arealBuildingCentroidNode->setSpecificationID(arealBuildingSpecID); vectorNetwork.addOn(*arealBuildingCentroidNode); // Create the edges. Like the segments, there are 2 edges (one is the // reverse of the other). Configure it with endpoints and segments. // Set the specification to the river specification we made above. DtNetworkEdge* buildingPerimeter = vectorNetwork.newEdge(); assert(buildingPerimeter != NULL); buildingPerimeter->setSpecificationID(arealBuildingSpecID); buildingPerimeter->setStartNode(arealBuildingStartNode); buildingPerimeter->setEndNode(arealBuildingEndNode); // Add the edges that will make up the building // First create the segments. Create them two at a time to be consistent // with the topology. buildingPerimeter->addPoint(DtPoint(710, 610, 0)); buildingPerimeter->addPoint(DtPoint(710, 660, 0)); buildingPerimeter->addPoint(DtPoint(610, 660, 0)); buildingPerimeter->addPoint(DtPoint(610, 610, 0)); buildingPerimeter->addPoint(DtPoint(710, 610, 0)); return true; } bool createPointBuilding(DtVectorNetwork& vectorNetwork) { // Get a convenience reference to the vector network's specification manager DtSpecificationManager& specificationManager = vectorNetwork.specificationManager(); // Create a specification for a building DtSpecification buildingSpec; buildingSpec.setColor(DtColor(255,145,0,0)); // r,g,b,a (0-255) buildingSpec.setWidth(12.0); buildingSpec.setLength(15.0); buildingSpec.addIntegerAttribute("DtFidCode", 181); buildingSpec.addIntegerAttribute("DtFacNumber", 1); buildingSpec.addIntegerAttribute("DtFeatureType", 0); buildingSpec.addStringAttribute("DtFeatureName","181 building"); buildingSpec.addIntegerAttribute("DtSmc", 3); buildingSpec.addStringAttribute("DtFeatureGroupName", "Feature"); buildingSpec.addStringAttribute("DtFeatureGroup", "MAK000"); buildingSpec.addStringAttribute("DtDescription","Building"); buildingSpec.addStringAttribute("ECC","AL015"); buildingSpec.addIntegerAttribute("DtSedrisCodes", 0); buildingSpec.addStringAttribute("SEDRISCODE1","TRE002"); buildingSpec.addStringAttribute("TRE002","Evergreen"); buildingSpec.addIntegerAttribute("DtOrientation", 0); buildingSpec.addIntegerAttribute("DtHeight", 10); DtSpecificationID buildingSpecID; if(!specificationManager.addSpecification(buildingSpec, buildingSpecID)) { DtWarn("Couldn't add building specification to the specification manager.\n"); return false; } // Create a building DtNetworkNode* building = vectorNetwork.newNode(); // Position it near the center of the terrain building->setLocation(DtPoint(500, 550, 0)); building->setSpecificationID(buildingSpecID); // Add it to the database vectorNetwork.addOn(*building); return true; } bool createRiver(DtVectorNetwork& vectorNetwork) { // Get a convenience reference to the vector network's specification manager DtSpecificationManager& specificationManager = vectorNetwork.specificationManager(); // Create a river specification DtSpecification riverSpec; riverSpec.setColor(DtColor(0,0,200,0)); // r,g,b,a (0-255) riverSpec.addIntegerAttribute("DtFidCode", 945); riverSpec.addIntegerAttribute("DtFeatureType", 1); riverSpec.addStringAttribute("DtFeatureName","945 Non-perennial Stream"); riverSpec.addIntegerAttribute("DtSmc", 6); riverSpec.addStringAttribute("DtFeatureGroupName", "Waterway"); riverSpec.addStringAttribute("DtFeatureGroup", "MAK030"); riverSpec.addStringAttribute("DtDescription","River/Stream"); riverSpec.addStringAttribute("ECC","BH140"); riverSpec.addIntegerAttribute("DtSedrisCodes", 0); riverSpec.addIntegerAttribute("DtOrientation", 0); riverSpec.addIntegerAttribute("DtHeight", 0); riverSpec.setWidth(10); riverSpec.setLength(0); DtSpecificationID riverSpecID; if(!specificationManager.addSpecification(riverSpec, riverSpecID)) { DtWarn("Couldn't add river specification to the specification manager.\n"); return false; } // Create the edge that makes up the river. // Create the endpoints of our river, node1 and node2. Set the // specification to the river specification we made above. DtNetworkNode* riverStartNode = vectorNetwork.newNode(); riverStartNode->setLocation(DtPoint(0, 100, 0)); riverStartNode->setSpecificationID(riverSpecID); vectorNetwork.addOn(*riverStartNode); DtNetworkNode* riverEndNode = vectorNetwork.newNode(); riverEndNode->setLocation(DtPoint(300,1000,0)); riverEndNode->setSpecificationID(riverSpecID); vectorNetwork.addOn(*riverEndNode); // Create the edges. Like the segments, there are 2 edges (one is the // reverse of the other). Configure it with endpoints and segments. // Set the specification to the river specification we made above. DtNetworkEdge* edge = vectorNetwork.newEdge(); edge->addPoint(DtPoint(0, 100, 0)); edge->addPoint(DtPoint(300,1000,0)); edge->setSpecificationID(riverSpecID); edge->setStartNode(riverStartNode); edge->setEndNode(riverEndNode); return true; } // This example demonstrates how to use the terrain API to add terrain features // to an existing terrain database (in this case some trees, a building, and a // river). The modified terrain database is saved out to file in MAK gdb // format. // // It loads the ..\data\terrain\simpleTerrain.gdb database (created by the // createTerrainDb example), and saves out the modified terrain database to the // file ..\data\terrain\simpleFeatures.gdb. int main(int argc, char** argv) { DtTdbManager manager; // Load the simpleTerrain.gdb database (in the bin directory). It contains // terrain skin only (a 1000 x 1000 meter square plane comprised of 4 quadrants // of two triangles each). // // Load the terrain database using a terrain reader that knows how to load // MAK gdb terrain files. if(!manager.load("..\\data\\terrain\\simpleTerrain.gdb")) { DtWarn("Couldn't load terrain database file -- please run createTerrainDb to create simpleTerrain.gdb\n"); return 1; } // Get a convenience pointer to the terrain database's vector network DtVectorNetwork* vectorNetwork = manager.terrainDatabase()->vectorNetwork(); assert(vectorNetwork != NULL); if (!createTrees(*vectorNetwork)) { DtWarn("Couldn't create point tree features.\n"); return 1; } if (!createRiver(*vectorNetwork)) { DtWarn("Couldn't create linear river feature.\n"); return 1; } if (!createPointBuilding(*vectorNetwork)) { DtWarn("Couldn't create point building feature.\n"); return 1; } if (!createArealBuilding(*vectorNetwork)) { DtWarn("Couldn't create areal building feature.\n"); return 1; } if (! vectorNetwork->validity()) { DtWarn("Error - created invalid vector network.\n"); return 1; } // Save modified terrain database to file manager.save("..\\data\\terrain\\simpleFeatures.gdb"); return 0; }