]> git.mxchange.org Git - flightgear.git/blob - utils/fgai/AIBVHPager.cxx
ATC/Traffic doesn’t crash reset.
[flightgear.git] / utils / fgai / AIBVHPager.cxx
1 // Copyright (C) 2009 - 2012  Mathias Froehlich - Mathias.Froehlich@web.de
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Library General Public
5 // License as published by the Free Software Foundation; either
6 // version 2 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Library General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
16 //
17
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
21 #include <osg/Referenced>
22
23 #include "AIBVHPager.hxx"
24
25 #include <simgear/bvh/BVHPageNode.hxx>
26 #include <simgear/bvh/BVHSubTreeCollector.hxx>
27 #include <simgear/misc/sg_path.hxx>
28 #include <simgear/misc/ResourceManager.hxx>
29 #include <simgear/props/props.hxx>
30 #include <simgear/props/props_io.hxx>
31 #include <simgear/scene/material/matlib.hxx>
32 #include <simgear/scene/model/BVHPageNodeOSG.hxx>
33 #include <simgear/scene/model/ModelRegistry.hxx>
34 #include <simgear/scene/util/SGReaderWriterOptions.hxx>
35 #include <simgear/scene/util/OptionsReadFileCallback.hxx>
36 #include <simgear/scene/tgdb/userdata.hxx>
37
38 namespace fgai {
39
40 // Short circuit reading image files.
41 class AIBVHPager::ReadFileCallback : public simgear::OptionsReadFileCallback {
42 public:
43     virtual ~ReadFileCallback()
44     { }
45         
46     virtual osgDB::ReaderWriter::ReadResult readImage(const std::string& name, const osgDB::Options*)
47     { return new osg::Image; }
48 };
49     
50 // A sub tree collector that pages in the nodes that it needs
51 class AIBVHPager::SubTreeCollector : public simgear::BVHSubTreeCollector {
52 public:
53     SubTreeCollector(simgear::BVHPager& pager, const SGSphered& sphere) :
54         BVHSubTreeCollector(sphere),
55         _pager(pager),
56         _complete(true)
57     { }
58     virtual ~SubTreeCollector()
59     { }
60     
61     virtual void apply(simgear::BVHPageNode& pageNode)
62     {
63         _pager.use(pageNode);
64         BVHSubTreeCollector::apply(pageNode);
65         _complete = _complete && 0 != pageNode.getNumChildren();
66     }
67     bool complete() const
68     { return _complete; }
69     
70 private:
71     simgear::BVHPager& _pager;
72     bool _complete;
73 };
74
75 AIBVHPager::AIBVHPager()
76 {
77 }
78
79 AIBVHPager::~AIBVHPager()
80 {
81 }
82     
83 void
84 AIBVHPager::setScenery(const std::string& fg_root, const std::string& fg_scenery)
85 {
86     SGSharedPtr<SGPropertyNode> props = new SGPropertyNode;
87     try {
88         SGPath preferencesFile = fg_root;
89         preferencesFile.append("preferences.xml");
90         readProperties(preferencesFile.str(), props);
91     } catch (...) {
92         // In case of an error, at least make summer :)
93         props->getNode("sim/startup/season", true)->setStringValue("summer");
94         
95         SG_LOG(SG_GENERAL, SG_ALERT, "Problems loading FlightGear preferences.\n"
96                << "Probably FG_ROOT is not properly set.");
97     }
98     
99     /// now set up the simgears required model stuff
100     
101     simgear::ResourceManager::instance()->addBasePath(fg_root, simgear::ResourceManager::PRIORITY_DEFAULT);
102     // Just reference simgears reader writer stuff so that the globals get
103     // pulled in by the linker ...
104     simgear::ModelRegistry::instance();
105     
106     sgUserDataInit(props.get());
107     SGMaterialLib* ml = new SGMaterialLib;
108     SGPath mpath(fg_root);
109     mpath.append("Materials/default/materials.xml");
110     try {
111         ml->load(fg_root, mpath.str(), props);
112     } catch (...) {
113         SG_LOG(SG_GENERAL, SG_ALERT, "Problems loading FlightGear materials.\n"
114                << "Probably FG_ROOT is not properly set.");
115     }
116     simgear::SGModelLib::init(fg_root, props);
117     
118     // Set up the reader/writer options
119     osg::ref_ptr<simgear::SGReaderWriterOptions> options;
120     if (osgDB::Options* ropt = osgDB::Registry::instance()->getOptions())
121         options = new simgear::SGReaderWriterOptions(*ropt);
122     else
123         options = new simgear::SGReaderWriterOptions;
124     osgDB::convertStringPathIntoFilePathList(fg_scenery,
125                                              options->getDatabasePathList());
126     options->setMaterialLib(ml);
127     options->setPropertyNode(props);
128     options->setReadFileCallback(new ReadFileCallback);
129     options->setPluginStringData("SimGear::FG_ROOT", fg_root);
130     // we do not need the builtin boundingvolumes
131     options->setPluginStringData("SimGear::BOUNDINGVOLUMES", "OFF");
132     // And we only want terrain, no objects on top.
133     options->setPluginStringData("SimGear::FG_ONLY_TERRAIN", "ON");
134     // Hmm, ??!!
135     options->setPluginStringData("SimGear::FG_ONLY_AIRPORTS", "ON");
136     props->getNode("sim/rendering/random-objects", true)->setBoolValue(false);
137     props->getNode("sim/rendering/random-vegetation", true)->setBoolValue(false);
138     
139     // Get the whole world bvh tree
140     _node = simgear::BVHPageNodeOSG::load("w180s90-360x180.spt", options);
141 }
142
143 SGSharedPtr<simgear::BVHNode>
144 AIBVHPager::getBoundingVolumes(const SGSphered& sphere)
145 {
146     if (!_node.valid())
147         return SGSharedPtr<simgear::BVHNode>();
148     SubTreeCollector subTreeCollector(*this, sphere);
149     _node->accept(subTreeCollector);
150     return subTreeCollector.getNode();
151 }
152
153 } // namespace fgai