]> git.mxchange.org Git - flightgear.git/blob - src/Model/acmodel.cxx
MapWidget: silence compiler warning
[flightgear.git] / src / Model / acmodel.cxx
1 // acmodel.cxx - manage a 3D aircraft model.
2 // Written by David Megginson, started 2002.
3 //
4 // This file is in the Public Domain, and comes with no warranty.
5
6 #ifdef HAVE_CONFIG_H
7 #  include <config.h>
8 #endif
9
10 #include <cstring>              // for strcmp()
11 #include <boost/foreach.hpp>
12
13 #include <simgear/compiler.h>
14 #include <simgear/debug/logstream.hxx>
15 #include <simgear/structure/exception.hxx>
16 #include <simgear/misc/sg_path.hxx>
17 #include <simgear/scene/model/placement.hxx>
18 #include <simgear/scene/util/SGNodeMasks.hxx>
19 #include <simgear/scene/model/modellib.hxx>
20
21 #include <Main/globals.hxx>
22 #include <Main/fg_props.hxx>
23 #include <Viewer/renderer.hxx>
24 #include <Viewer/viewmgr.hxx>
25 #include <Viewer/viewer.hxx>
26 #include <Scenery/scenery.hxx>
27 #include <Sound/fg_fx.hxx>
28
29 #include "acmodel.hxx"
30
31
32 static osg::Node *
33 fgLoad3DModelPanel(const std::string &path, SGPropertyNode *prop_root)
34 {
35     bool loadPanels = true;
36     osg::Node* node = simgear::SGModelLib::loadModel(path, prop_root, NULL, loadPanels);
37     if (node)
38         node->setNodeMask(~SG_NODEMASK_TERRAIN_BIT);
39     return node;
40 }
41 \f
42 ////////////////////////////////////////////////////////////////////////
43 // Implementation of FGAircraftModel
44 ////////////////////////////////////////////////////////////////////////
45
46 FGAircraftModel::FGAircraftModel ()
47   : _velocity(SGVec3d::zeros()),
48     _fx(0),
49     _speed_n(0),
50     _speed_e(0),
51     _speed_d(0)
52 {
53     _fx = new FGFX("fx");
54     _fx->init();
55 }
56
57 FGAircraftModel::~FGAircraftModel ()
58 {
59   // drop reference
60   _fx = 0;
61   shutdown();
62 }
63
64 void 
65 FGAircraftModel::init ()
66 {
67     if (_aircraft.get()) {
68         SG_LOG(SG_AIRCRAFT, SG_ALERT, "FGAircraftModel::init: already inited");
69         return;
70     }
71     
72     SGPropertyNode_ptr sim = fgGetNode("/sim", true);
73     BOOST_FOREACH(SGPropertyNode_ptr model, sim->getChildren("model")) {
74         std::string path = model->getStringValue("path", "Models/Geometry/glider.ac");
75         std::string usage = model->getStringValue("usage", "external");
76         
77         SGPath resolvedPath = globals->resolve_aircraft_path(path);
78         if (resolvedPath.isNull()) {
79             SG_LOG(SG_AIRCRAFT, SG_ALERT, "Failed to find aircraft model: " << path);
80             continue;
81         }
82         
83         osg::Node* node = NULL;
84         try {
85             node = fgLoad3DModelPanel( resolvedPath.str(), globals->get_props());
86         } catch (const sg_exception &ex) {
87             SG_LOG(SG_AIRCRAFT, SG_ALERT, "Failed to load aircraft from " << path << ':');
88             SG_LOG(SG_AIRCRAFT, SG_ALERT, "  " << ex.getFormattedMessage());
89         }
90         
91         if (usage == "interior") {
92             // interior model
93             if (!_interior.get()) {
94                 _interior.reset(new SGModelPlacement);
95                 _interior->init(node);
96             } else {
97                 _interior->add(node);
98             }
99         } else {
100             // normal / exterior model
101             if (!_aircraft.get()) {
102                 _aircraft.reset(new SGModelPlacement);
103                 _aircraft->init(node);
104             } else {
105                 _aircraft->add(node);
106             }
107         } // of model usage switch
108     } // of models iteration
109     
110     // no models loaded, load the glider instead
111     if (!_aircraft.get()) {
112         SG_LOG(SG_AIRCRAFT, SG_ALERT, "(Falling back to glider.ac.)");
113         osg::Node* model = fgLoad3DModelPanel( "Models/Geometry/glider.ac",
114                                    globals->get_props());
115         _aircraft.reset(new SGModelPlacement);
116         _aircraft->init(model);
117
118     }
119
120   osg::Node* node = _aircraft->getSceneGraph();
121   globals->get_scenery()->get_aircraft_branch()->addChild(node);
122     
123     if (_interior.get()) {
124         node = _interior->getSceneGraph();
125         globals->get_scenery()->get_interior_branch()->addChild(node);
126     }
127 }
128
129 void
130 FGAircraftModel::reinit()
131 {
132   shutdown();
133   _fx->reinit();
134   init();
135   // TODO globally create signals for all subsystems (re)initialized
136   fgSetBool("/sim/signals/model-reinit", true);
137 }
138
139 void
140 FGAircraftModel::shutdown()
141 {
142   if (!_aircraft.get()) {
143     return;
144   }
145   
146   osg::Node* node = _aircraft->getSceneGraph();
147   globals->get_scenery()->get_aircraft_branch()->removeChild(node);
148
149     if (_interior.get()) {
150         globals->get_scenery()->get_interior_branch()->removeChild(_interior->getSceneGraph());
151     }
152     
153     _aircraft.reset();
154     _interior.reset();
155 }
156
157 void
158 FGAircraftModel::bind ()
159 {
160    _speed_n = fgGetNode("velocities/speed-north-fps", true);
161    _speed_e = fgGetNode("velocities/speed-east-fps", true);
162    _speed_d = fgGetNode("velocities/speed-down-fps", true);
163 }
164
165 void
166 FGAircraftModel::unbind ()
167 {
168   _fx->unbind();
169 }
170
171 void
172 FGAircraftModel::update (double dt)
173 {
174   int view_number = globals->get_viewmgr()->get_current();
175   int is_internal = fgGetBool("/sim/current-view/internal");
176
177   if (view_number == 0 && !is_internal) {
178     _aircraft->setVisible(false);
179   } else {
180     _aircraft->setVisible(true);
181   }
182     
183     double heading, pitch, roll;
184     globals->get_aircraft_orientation(heading, pitch, roll);
185     SGQuatd orient = SGQuatd::fromYawPitchRollDeg(heading, pitch, roll);
186     
187     SGGeod pos = globals->get_aircraft_position();
188     
189     _aircraft->setPosition(pos);
190     _aircraft->setOrientation(orient);
191     _aircraft->update();
192
193     if (_interior.get()) {
194         _interior->setPosition(pos);
195         _interior->setOrientation(orient);
196         _interior->update();
197     }
198     
199   // update model's audio sample values
200   _fx->set_position_geod( pos );
201   _fx->set_orientation( orient );
202  
203   _velocity = SGVec3d( _speed_n->getDoubleValue(),
204                        _speed_e->getDoubleValue(),
205                        _speed_d->getDoubleValue() );
206   _fx->set_velocity( _velocity );
207 }
208
209
210 // end of model.cxx