1 // acmodel.cxx - manage a 3D aircraft model.
2 // Written by David Megginson, started 2002.
4 // This file is in the Public Domain, and comes with no warranty.
10 #include <string.h> // for strcmp()
12 #include <simgear/compiler.h>
13 #include <simgear/debug/logstream.hxx>
14 #include <simgear/structure/exception.hxx>
15 #include <simgear/misc/sg_path.hxx>
16 #include <simgear/scene/model/placement.hxx>
17 #include <simgear/scene/util/SGNodeMasks.hxx>
19 #include <Main/globals.hxx>
20 #include <Main/fg_props.hxx>
21 #include <Viewer/renderer.hxx>
22 #include <Viewer/viewmgr.hxx>
23 #include <Viewer/viewer.hxx>
24 #include <Scenery/scenery.hxx>
25 #include <Sound/fg_fx.hxx>
27 #include "model_panel.hxx"
29 #include "acmodel.hxx"
33 ////////////////////////////////////////////////////////////////////////
34 // Implementation of FGAircraftModel
35 ////////////////////////////////////////////////////////////////////////
37 FGAircraftModel::FGAircraftModel ()
39 _velocity(SGVec3d::zeros()),
51 SGSoundMgr *smgr = globals->get_soundmgr();
52 _fx = new FGFX(smgr, "fx");
56 FGAircraftModel::~FGAircraftModel ()
64 FGAircraftModel::init ()
66 osg::Node *model = NULL;
68 _aircraft = new SGModelPlacement;
69 string path = fgGetString("/sim/model/path", "Models/Geometry/glider.ac");
71 SGPath resolvedPath = globals->resolve_aircraft_path(path);
72 if (resolvedPath.isNull())
74 SG_LOG(SG_AIRCRAFT, SG_ALERT, "Failed to load aircraft from " << path << ':');
79 model = fgLoad3DModelPanel( resolvedPath.str(), globals->get_props());
80 } catch (const sg_exception &ex) {
81 SG_LOG(SG_AIRCRAFT, SG_ALERT, "Failed to load aircraft from " << path << ':');
82 SG_LOG(SG_AIRCRAFT, SG_ALERT, " " << ex.getFormattedMessage());
88 SG_LOG(SG_AIRCRAFT, SG_ALERT, "(Falling back to glider.ac.)");
89 model = fgLoad3DModelPanel( "Models/Geometry/glider.ac",
90 globals->get_props());
92 _aircraft->init( model );
94 osg::Node* node = _aircraft->getSceneGraph();
95 // Do not do altitude computations with that model
96 node->setNodeMask(~SG_NODEMASK_TERRAIN_BIT);
97 globals->get_scenery()->get_aircraft_branch()->addChild(node);
101 FGAircraftModel::reinit()
109 FGAircraftModel::deinit()
115 osg::Node* node = _aircraft->getSceneGraph();
116 globals->get_scenery()->get_aircraft_branch()->removeChild(node);
123 FGAircraftModel::bind ()
125 _lon = fgGetNode("position/longitude-deg", true);
126 _lat = fgGetNode("position/latitude-deg", true);
127 _alt = fgGetNode("position/altitude-ft", true);
128 _pitch = fgGetNode("orientation/pitch-deg", true);
129 _roll = fgGetNode("orientation/roll-deg", true);
130 _heading = fgGetNode("orientation/heading-deg", true);
131 _speed_n = fgGetNode("velocities/speed-north-fps", true);
132 _speed_e = fgGetNode("velocities/speed-east-fps", true);
133 _speed_d = fgGetNode("velocities/speed-down-fps", true);
137 FGAircraftModel::unbind ()
143 FGAircraftModel::update (double dt)
145 int view_number = globals->get_viewmgr()->get_current();
146 int is_internal = fgGetBool("/sim/current-view/internal");
148 if (view_number == 0 && !is_internal) {
149 _aircraft->setVisible(false);
151 _aircraft->setVisible(true);
154 _aircraft->setPosition(_lon->getDoubleValue(),
155 _lat->getDoubleValue(),
156 _alt->getDoubleValue());
157 _aircraft->setOrientation(_roll->getDoubleValue(),
158 _pitch->getDoubleValue(),
159 _heading->getDoubleValue());
162 // update model's audio sample values
163 SGGeod position = _aircraft->getPosition();
164 _fx->set_position_geod( position );
166 SGQuatd orient = SGQuatd::fromYawPitchRollDeg(_heading->getDoubleValue(),
167 _pitch->getDoubleValue(),
168 _roll->getDoubleValue());
169 _fx->set_orientation( orient );
171 _velocity = SGVec3d( _speed_n->getDoubleValue(),
172 _speed_e->getDoubleValue(),
173 _speed_d->getDoubleValue() );
174 _fx->set_velocity( _velocity );