]> git.mxchange.org Git - flightgear.git/blob - src/Model/acmodel.cxx
Don't restore initial screen geometry because there is nothing in fg_os* to resize...
[flightgear.git] / src / Model / acmodel.cxx
1 // model.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 <string.h>             // for strcmp()
11
12 #include <plib/sg.h>
13 #include <plib/ssg.h>
14
15 #include <simgear/compiler.h>
16 #include <simgear/debug/logstream.hxx>
17 #include <simgear/structure/exception.hxx>
18 #include <simgear/misc/sg_path.hxx>
19 #include <simgear/scene/model/placement.hxx>
20 #include <simgear/scene/model/shadowvolume.hxx>
21
22 #include <Main/globals.hxx>
23 #include <Main/fg_props.hxx>
24 #include <Main/renderer.hxx>
25 #include <Main/viewmgr.hxx>
26 #include <Main/viewer.hxx>
27 #include <Scenery/scenery.hxx>
28
29 #include "model_panel.hxx"
30
31 #include "acmodel.hxx"
32
33
34 class fgLoaderOptions : ssgLoaderOptions {
35
36 public:
37     virtual void makeTexturePath ( char* path, const char *fname ) const ;
38     string livery_path;
39
40 };
41
42 void fgLoaderOptions::makeTexturePath ( char *path, const char *fname ) const
43 {
44   /* Remove all leading path information. */
45   const char* seps = "\\/" ;
46   const char* fn = & fname [ strlen ( fname ) - 1 ] ;
47   for ( ; fn != fname && strchr(seps,*fn) == NULL ; fn-- )
48     /* Search back for a seperator */ ;
49   if ( strchr(seps,*fn) != NULL )
50     fn++ ;
51   fname = fn ;
52   // if we have a livery path and the texture is found there then we use that
53   // path in priority, if the texture was not found or we add no additional 
54   // livery path then we use the current model path or model/texture-path
55   if( livery_path.size() ) {
56       make_path( path, livery_path.c_str(), fname );
57       if( ulFileExists( path ) )
58           return;
59   }
60   make_path ( path, texture_dir, fname ) ;
61 }
62
63 static fgLoaderOptions _fgLoaderOptions;
64
65 \f
66 ////////////////////////////////////////////////////////////////////////
67 // Implementation of FGAircraftModel
68 ////////////////////////////////////////////////////////////////////////
69
70 FGAircraftModel::FGAircraftModel ()
71   : _aircraft(0),
72     _selector(new ssgSelector),
73     _scene(new ssgRoot),
74     _nearplane(0.10f),
75     _farplane(1000.0f)
76 {
77 }
78
79 FGAircraftModel::~FGAircraftModel ()
80 {
81   // Unregister that one at the scenery manager
82   if (_aircraft)
83     globals->get_scenery()->unregister_placement_transform(_aircraft->getTransform());
84
85   delete _aircraft;
86                                 // SSG will delete it
87   globals->get_scenery()->get_aircraft_branch()->removeKid(_selector);
88 }
89
90 void 
91 FGAircraftModel::init ()
92 {
93   ssgLoaderOptions *currLoaderOptions = ssgGetCurrentOptions();
94   ssgSetCurrentOptions( (ssgLoaderOptions*)&_fgLoaderOptions );
95   _aircraft = new SGModelPlacement;
96   string path = fgGetString("/sim/model/path", "Models/Geometry/glider.ac");
97   string texture_path = fgGetString("/sim/model/texture-path");
98   if( texture_path.size() ) {
99       SGPath temp_path;
100       if ( !ulIsAbsolutePathName( texture_path.c_str() ) ) {
101           temp_path = globals->get_fg_root();
102           temp_path.append( SGPath( path ).dir() );
103           temp_path.append( texture_path );
104           _fgLoaderOptions.livery_path = temp_path.str();
105       } else
106           _fgLoaderOptions.livery_path = texture_path;
107   }
108   try {
109     ssgBranch *model = fgLoad3DModelPanel( globals->get_fg_root(),
110                                            path,
111                                            globals->get_props(),
112                                            globals->get_sim_time_sec() );
113     _aircraft->init( model );
114   } catch (const sg_exception &ex) {
115     SG_LOG(SG_GENERAL, SG_ALERT, "Failed to load aircraft from " << path);
116     SG_LOG(SG_GENERAL, SG_ALERT, "(Falling back to glider.ac.)");
117     ssgBranch *model = fgLoad3DModelPanel( globals->get_fg_root(),
118                                            "Models/Geometry/glider.ac",
119                                            globals->get_props(),
120                                            globals->get_sim_time_sec() );
121     _aircraft->init( model );
122   }
123   _scene->addKid(_aircraft->getSceneGraph());
124   _selector->addKid(_aircraft->getSceneGraph());
125   globals->get_scenery()->get_aircraft_branch()->addKid(_selector);
126
127   // Register that one at the scenery manager
128   globals->get_scenery()->register_placement_transform(_aircraft->getTransform());
129   ssgSetCurrentOptions( currLoaderOptions );
130 }
131
132 void 
133 FGAircraftModel::bind ()
134 {
135   // No-op
136 }
137
138 void 
139 FGAircraftModel::unbind ()
140 {
141   // No-op
142 }
143
144 void
145 FGAircraftModel::update (double dt)
146 {
147   int view_number = globals->get_viewmgr()->get_current();
148   int is_internal = fgGetBool("/sim/current-view/internal");
149
150   if (view_number == 0 && !is_internal) {
151     _aircraft->setVisible(false);
152   } else {
153     _aircraft->setVisible(true);
154   }
155
156   _aircraft->setPosition(fgGetDouble("/position/longitude-deg"),
157                          fgGetDouble("/position/latitude-deg"),
158                          fgGetDouble("/position/altitude-ft"));
159   _aircraft->setOrientation(fgGetDouble("/orientation/roll-deg"),
160                             fgGetDouble("/orientation/pitch-deg"),
161                             fgGetDouble("/orientation/heading-deg"));
162   _aircraft->update();
163 }
164
165 void
166 FGAircraftModel::draw ()
167 {
168                                 // OK, now adjust the clip planes and draw
169                                 // FIXME: view number shouldn't be 
170                                 // hard-coded.
171   bool is_internal = globals->get_current_view()->getInternal();
172   if (_aircraft->getVisible() && is_internal) {
173     glClearDepth(1);
174     glClear(GL_DEPTH_BUFFER_BIT);
175     FGRenderer::setNearFar(_nearplane, _farplane);
176     ssgCullAndDraw(_scene);
177     _selector->select(0);
178   } else {
179     _selector->select(1);
180     // in external view the shadows are drawn before the transparent parts of the ac
181     _scene->setTravCallback( SSG_CALLBACK_POSTTRAV, SGShadowVolume::ACpostTravCB);
182     ssgCullAndDraw(_scene);
183     _scene->setTravCallback( SSG_CALLBACK_POSTTRAV, 0);
184   }
185
186 }
187
188 // end of model.cxx