]> git.mxchange.org Git - simgear.git/blob - simgear/scene/model/modellib.cxx
Mathias Fröhlich:
[simgear.git] / simgear / scene / model / modellib.cxx
1 // modellib.cxx - implement an SSG model library.
2
3 #include <simgear/compiler.h>
4 #include <simgear/props/props.hxx>
5
6 #include "model.hxx"
7 #include "animation.hxx"
8 #include "personality.hxx"
9
10 #include "modellib.hxx"
11
12
13 \f
14 ////////////////////////////////////////////////////////////////////////
15 // Implementation of SGModelLib.
16 ////////////////////////////////////////////////////////////////////////
17
18 SGModelLib::SGModelLib ()
19 {
20 }
21
22 SGModelLib::~SGModelLib ()
23 {
24     map<string, ssgBase *>::iterator it = _table.begin();
25     while (it != _table.end()) {
26         ssgDeRefDelete(it->second);
27         _table.erase(it);
28     }
29 }
30
31 void
32 SGModelLib::flush1()
33 {
34     // This routine is disabled because I believe I see multiple
35     // problems with it.
36     //
37     // 1. It blindly deletes all managed models that aren't used
38     //    elsewhere.  Is this what we really want????  In the one
39     //    FlightGear case that calls this method, this clearly is not the
40     //    intention.  I believe it makes more sense to simply leave items
41     //    in the lbrary, even if they are not currently used, they will be
42     //    there already when/if we want to use them later.
43     //
44     // 2. This routine only does a deRef() on the model.  This doesn't actually
45     //    delete the ssg tree so there is a memory leak.
46
47     SG_LOG( SG_GENERAL, SG_ALERT,
48             "WARNGING: a disabled/broken routine has been called.  This should be fixed!" );
49
50     return;
51
52     map<string, ssgBase *>::iterator it = _table.begin();
53     while (it != _table.end()) {
54         ssgBase *item = it->second;
55                                 // If there is only one reference, it's
56                                 // ours; no one else is using the item.
57         if (item->getRef() == 1) {
58             ssgDeRefDelete(item);
59             _table.erase(it);
60         }
61         it++;
62     }
63 }
64
65 static int
66 personality_pretrav_callback(ssgEntity * entity, int mask)
67 {
68     ((SGPersonalityBranch *)entity)->_old_current = SGAnimation::current_object;
69     SGAnimation::current_object = (SGPersonalityBranch *)entity;
70     return 1;
71 }
72
73 static int
74 personality_posttrav_callback(ssgEntity * entity, int mask)
75 {
76     SGAnimation::current_object = ((SGPersonalityBranch *)entity)->_old_current;
77     ((SGPersonalityBranch *)entity)->_old_current = 0;
78     return 1;
79 }
80
81 ssgEntity *
82 SGModelLib::load_model( const string &fg_root,
83                            const string &path,
84                            SGPropertyNode *prop_root,
85                            double sim_time_sec )
86 {
87     ssgBranch *personality_branch = new SGPersonalityBranch;
88     personality_branch->setTravCallback(SSG_CALLBACK_PRETRAV, personality_pretrav_callback);
89     personality_branch->setTravCallback(SSG_CALLBACK_POSTTRAV, personality_posttrav_callback);
90
91                                 // FIXME: normalize path to
92                                 // avoid duplicates.
93     map<string, ssgBase *>::iterator it = _table.find(path);
94     if (it == _table.end()) {
95         ssgEntity *model = sgLoad3DModel( fg_root, path, prop_root,
96                                           sim_time_sec );
97         model->ref();
98         _table[path] = model;      // add one reference to keep it around
99         personality_branch->addKid( model );
100     } else {
101         personality_branch->addKid( (ssgEntity *)it->second );
102     }
103     return personality_branch;
104 }
105
106
107 // end of modellib.cxx