1 // Copyright (C) 2008 Till Busch buti@bux.at
2 //
3 // This program is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU General Public License as
5 // published by the Free Software Foundation; either version 2 of the
6 // License, or (at your option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful, but
9 // WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // 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 #ifndef _SG_MODEL_LIB_HXX
19 #define _SG_MODEL_LIB_HXX 1
20
21 #include <simgear/compiler.h> // for SG_USING_STD
22
23 #include <map>
24 #include <string>
25
26 #include <osg/Node>
27 #include <osgDB/ReaderWriter>
28
29 #include <simgear/props/props.hxx>
30 #include <simgear/misc/sg_path.hxx>
31
32 namespace osg {
33 class PagedLOD;
34 }
35
36 namespace simgear {
37
38 class SGModelData; // defined below
39 class SGModelLOD; // defined below
40
41 /**
42 * Class for loading and managing models with XML wrappers.
43 */
44 class SGModelLib
45 {
46 public:
47 typedef osg::Node *(*panel_func)(SGPropertyNode *);
48
49 static void init(const std::string &root_dir, SGPropertyNode* root);
50
51 static void resetPropertyRoot();
52
53 static void setPanelFunc(panel_func pf);
54
55 // Load a 3D model (any format)
56 // data->modelLoaded() will be called after the model is loaded
57 static osg::Node* loadModel(const std::string &path,
58 SGPropertyNode *prop_root = NULL,
59 SGModelData *data=0, bool load2DPanels=false);
60
61 // Load a 3D model (any format) through the DatabasePager.
62 // This function initially just returns a proxy node that refers to
63 // the model file. Once the viewer steps onto that node the
64 // model will be loaded.
65 static osg::Node* loadDeferredModel(const std::string &path,
66 SGPropertyNode *prop_root = NULL,
67 SGModelData *data=0);
68 // Load a 3D model (any format) through the DatabasePager.
69 // This function initially just returns a PagedLOD node that refers to
70 // the model file. Once the viewer steps onto that node the
71 // model will be loaded. When the viewer does no longer reference this
72 // node for a long time the node is unloaded again.
73 static osg::PagedLOD* loadPagedModel(SGPropertyNode *prop_root,
74 SGModelData *data,
75 SGModelLOD model_lods);
76 static osg::PagedLOD* loadPagedModel(const std::string &path,
77 SGPropertyNode *prop_root = NULL,
78 SGModelData *data=0);
79
80 static osg::PagedLOD* loadPagedModel(std::vector<string> paths,
81 SGPropertyNode *prop_root = NULL,
82 SGModelData *data=0);
83
84 static std::string findDataFile(const std::string& file,
85 const osgDB::Options* opts = nullptr,
86 SGPath currentDir = SGPath());
87
88 static std::string findDataFile(const SGPath& file,
89 const osgDB::Options* opts = nullptr,
90 SGPath currentDir = SGPath());
91 protected:
92 SGModelLib();
93 ~SGModelLib ();
94
95 private:
96 static SGPropertyNode_ptr static_propRoot;
97 static panel_func static_panelFunc;
98 };
99
100
101 /**
102 * Abstract class for adding data to the scene graph. modelLoaded() is
103 * called after the model was loaded, and the destructor when the branch
104 * is removed from the scene graph.
105 */
106 class SGModelData : public osg::Referenced {
107 public:
~SGModelData()108 virtual ~SGModelData() {}
109 virtual void modelLoaded(const std::string& path, SGPropertyNode *prop,
110 osg::Node* branch) = 0;
111 virtual SGModelData* clone() const = 0;
112
113 using ErrorContext = std::map<std::string, std::string>;
114
115 virtual ErrorContext getErrorContext() const = 0;
116 };
117
118 /*
119 * Data for a model with multiple LoD versions
120 */
121
122 class SGModelLOD {
123 public:
124 struct ModelLOD {
ModelLODsimgear::SGModelLOD::ModelLOD125 ModelLOD(const string &p, float minrange, float maxrange) :
126 path(p), min_range(minrange), max_range(maxrange)
127 { }
128 const string &path;
129 float min_range;
130 float max_range;
131 };
132 typedef std::vector<ModelLOD> ModelLODList;
133
insert(const ModelLOD & model)134 void insert(const ModelLOD& model)
135 {
136 _models.push_back(model);
137 }
138
insert(const string & p,float minrange,float maxrange)139 void insert(const string &p, float minrange, float maxrange)
140 {
141 insert(ModelLOD(p, minrange, maxrange));
142 }
143
getNumLODs() const144 unsigned getNumLODs() const { return _models.size(); }
getModelLOD(unsigned i) const145 const ModelLOD& getModelLOD(unsigned i) const { return _models[i]; }
146
147 private:
148 ModelLODList _models;
149 };
150
151 }
152
153 #endif // _SG_MODEL_LIB_HXX
154