temp commit
[SARndbox.git] / DEMTool.cpp
blob571f5dafdf2b8faacda845d1afaffa4f52982dc4
1 /***********************************************************************
2 DEMTool - Tool class to load a digital elevation model into an augmented
3 reality sandbox to colorize the sand surface based on distance to the
4 DEM.
5 Copyright (c) 2013-2015 Oliver Kreylos
7 This file is part of the Augmented Reality Sandbox (SARndbox).
9 The Augmented Reality Sandbox is free software; you can redistribute it
10 and/or modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version.
14 The Augmented Reality Sandbox is distributed in the hope that it will be
15 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
19 You should have received a copy of the GNU General Public License along
20 with the Augmented Reality Sandbox; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 ***********************************************************************/
24 #include "DEMTool.h"
26 #include <Misc/StandardValueCoders.h>
27 #include <Misc/ConfigurationFile.h>
28 #include <Geometry/GeometryValueCoders.h>
29 #include <Vrui/OpenFile.h>
31 #include "Sandbox.h"
33 /*******************************
34 Methods of class DEMToolFactory:
35 *******************************/
37 DEMToolFactory::DEMToolFactory(Vrui::ToolManager& toolManager)
38 : ToolFactory("DEMTool", toolManager),
39 demSelectionHelper(Vrui::getWidgetManager(), "", ".grid", Vrui::openDirectory(".")) {
40 /* Initialize tool layout: */
41 layout.setNumButtons(1);
43 #if 0
44 /* Insert class into class hierarchy: */
45 ToolFactory* toolFactory = toolManager.loadClass("Tool");
46 toolFactory->addChildClass(this);
47 addParentClass(toolFactory);
48 #endif
50 /* Set tool class' factory pointer: */
51 DEMTool::factory = this;
54 DEMToolFactory::~DEMToolFactory(void) {
55 /* Reset tool class' factory pointer: */
56 DEMTool::factory = 0;
59 const char* DEMToolFactory::getName(void) const {
60 return "Show DEM";
63 const char* DEMToolFactory::getButtonFunction(int) const {
64 return "Toggle DEM";
67 Vrui::Tool* DEMToolFactory::createTool(const Vrui::ToolInputAssignment& inputAssignment) const {
68 return new DEMTool(this, inputAssignment);
71 void DEMToolFactory::destroyTool(Vrui::Tool* tool) const {
72 delete tool;
75 /********************************
76 Static elements of class DEMTool:
77 ********************************/
79 DEMToolFactory* DEMTool::factory = 0;
81 /************************
82 Methods of class DEMTool:
83 ************************/
85 void DEMTool::loadDEMFile(const char* demFileName) {
86 /* Load the selected DEM file: */
87 load(demFileName);
89 OGTransform demT;
90 if(haveDemTransform)
91 demT = demTransform;
92 else {
93 /* Calculate an appropriate DEM transformation to fit the DEM into the sandbox's domain: */
94 const Scalar* demBox = getDemBox();
95 Scalar demSx = demBox[2] - demBox[0];
96 Scalar demSy = demBox[3] - demBox[1];
97 Scalar boxSx = application->bbox.getSize(0);
98 Scalar boxSy = application->bbox.getSize(1);
100 /* Shift the DEM's center to the box's center: */
101 Point demCenter;
102 demCenter[0] = Math::mid(demBox[0], demBox[2]);
103 demCenter[1] = Math::mid(demBox[1], demBox[3]);
104 demCenter[2] = Scalar(calcAverageElevation());
105 demT = OGTransform::translateFromOriginTo(demCenter);
107 /* Determine whether the DEM should be rotated: */
108 Scalar scale = Math::min(demSx / boxSx, demSy / boxSy);
109 Scalar scaleRot = Math::min(demSx / boxSy, demSy / boxSx);
111 if(scale < scaleRot) {
112 /* Scale and rotate DEM: */
113 demT *= OGTransform::rotate(OGTransform::Rotation::rotateZ(Math::rad(Scalar(90))));
114 scale = scaleRot;
117 /* Scale DEM without rotation: */
118 demT *= OGTransform::scale(scale);
121 /* Shift the DEM vertically: */
122 demT *= OGTransform::translate(Vector(0, 0, demVerticalShift / demVerticalScale));
124 /* Set the DEM transformation: */
125 setTransform(demT * OGTransform(application->boxTransform), demVerticalScale, demT.getOrigin()[2]);
128 void DEMTool::loadDEMFileCallback(GLMotif::FileSelectionDialog::OKCallbackData* cbData) {
129 /* Load the selected DEM file: */
130 loadDEMFile(cbData->selectedDirectory->getPath(cbData->selectedFileName).c_str());
133 DEMToolFactory* DEMTool::initClass(Vrui::ToolManager& toolManager) {
134 /* Create the tool factory: */
135 factory = new DEMToolFactory(toolManager);
137 /* Register and return the class: */
138 toolManager.addClass(factory, Vrui::ToolManager::defaultToolFactoryDestructor);
139 return factory;
142 DEMTool::DEMTool(const Vrui::ToolFactory* factory,
143 const Vrui::ToolInputAssignment& inputAssignment)
144 : Vrui::Tool(factory, inputAssignment),
145 haveDemTransform(false), demTransform(OGTransform::identity),
146 demVerticalShift(0), demVerticalScale(1) {
149 DEMTool::~DEMTool(void) {
152 void DEMTool::configure(const Misc::ConfigurationFileSection& configFileSection) {
153 /* Query DEM file name: */
154 demFileName = configFileSection.retrieveString("./demFileName", demFileName);
156 /* Read the DEM transformation: */
157 if(configFileSection.hasTag("./demTransform")) {
158 haveDemTransform = true;
159 demTransform = configFileSection.retrieveValue<OGTransform>("./demTransform", demTransform);
162 demVerticalShift = configFileSection.retrieveValue<Scalar>("./demVerticalShift", demVerticalShift);
163 demVerticalScale = configFileSection.retrieveValue<Scalar>("./demVerticalScale", demVerticalScale);
166 void DEMTool::initialize(void) {
167 /* Bring up a file selection dialog if there is no pre-configured DEM file: */
168 if(demFileName.empty()) {
169 /* Load a DEM file: */
170 factory->demSelectionHelper.loadFile("Load DEM File...", this, &DEMTool::loadDEMFileCallback);
171 } else {
172 /* Load the configured DEM file: */
173 loadDEMFile(demFileName.c_str());
177 const Vrui::ToolFactory* DEMTool::getFactory(void) const {
178 return factory;
181 void DEMTool::buttonCallback(int buttonSlotIndex, Vrui::InputDevice::ButtonCallbackData* cbData) {
182 if(cbData->newButtonState) {
183 /* Toggle this DEM tool as the active one: */
184 application->toggleDEM(this);