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
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 ***********************************************************************/
26 #include <Misc/StandardValueCoders.h>
27 #include <Misc/ConfigurationFile.h>
28 #include <Geometry/GeometryValueCoders.h>
29 #include <Vrui/OpenFile.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);
44 /* Insert class into class hierarchy: */
45 ToolFactory
* toolFactory
= toolManager
.loadClass("Tool");
46 toolFactory
->addChildClass(this);
47 addParentClass(toolFactory
);
50 /* Set tool class' factory pointer: */
51 DEMTool::factory
= this;
54 DEMToolFactory::~DEMToolFactory(void) {
55 /* Reset tool class' factory pointer: */
59 const char* DEMToolFactory::getName(void) const {
63 const char* DEMToolFactory::getButtonFunction(int) const {
67 Vrui::Tool
* DEMToolFactory::createTool(const Vrui::ToolInputAssignment
& inputAssignment
) const {
68 return new DEMTool(this, inputAssignment
);
71 void DEMToolFactory::destroyTool(Vrui::Tool
* tool
) const {
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: */
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: */
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))));
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
);
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
);
172 /* Load the configured DEM file: */
173 loadDEMFile(demFileName
.c_str());
177 const Vrui::ToolFactory
* DEMTool::getFactory(void) const {
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);