]> git.mxchange.org Git - flightgear.git/blob - src/Model/acmodel.cxx
Code cleanups, code updates and fix at least on (possible) devide-by-zero
[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/view.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     FGScenery* scenery = globals->get_scenery();
143
144     if (_aircraft.get()) {
145         if (scenery && scenery->get_aircraft_branch()) {
146             scenery->get_aircraft_branch()->removeChild(_aircraft->getSceneGraph());
147         }
148     }
149
150     if (_interior.get()) {
151         if (scenery && scenery->get_interior_branch()) {
152             scenery->get_interior_branch()->removeChild(_interior->getSceneGraph());
153         }
154     }
155
156     _aircraft.reset();
157     _interior.reset();
158 }
159
160 void
161 FGAircraftModel::bind ()
162 {
163    _speed_n = fgGetNode("velocities/speed-north-fps", true);
164    _speed_e = fgGetNode("velocities/speed-east-fps", true);
165    _speed_d = fgGetNode("velocities/speed-down-fps", true);
166 }
167
168 void
169 FGAircraftModel::unbind ()
170 {
171   _fx->unbind();
172 }
173
174 void
175 FGAircraftModel::update (double dt)
176 {
177   int view_number = globals->get_viewmgr()->get_current();
178   int is_internal = fgGetBool("/sim/current-view/internal");
179
180   if (view_number == 0 && !is_internal) {
181     _aircraft->setVisible(false);
182   } else {
183     _aircraft->setVisible(true);
184   }
185     
186     double heading, pitch, roll;
187     globals->get_aircraft_orientation(heading, pitch, roll);
188     SGQuatd orient = SGQuatd::fromYawPitchRollDeg(heading, pitch, roll);
189     
190     SGGeod pos = globals->get_aircraft_position();
191     
192     _aircraft->setPosition(pos);
193     _aircraft->setOrientation(orient);
194     _aircraft->update();
195
196     if (_interior.get()) {
197         _interior->setPosition(pos);
198         _interior->setOrientation(orient);
199         _interior->update();
200     }
201     
202   // update model's audio sample values
203   _fx->set_position_geod( pos );
204   _fx->set_orientation( orient );
205  
206   _velocity = SGVec3d( _speed_n->getDoubleValue(),
207                        _speed_e->getDoubleValue(),
208                        _speed_d->getDoubleValue() );
209   _fx->set_velocity( _velocity );
210 }
211
212
213 // end of model.cxx