|
From: Tim M. <tim...@gm...> - 2010-12-22 08:00:17
|
On Thu, Dec 16, 2010 at 5:17 PM, Jacob Burbach <jmb...@gm...> wrote: > Ok then, trying to make sense of this whole model & effects loading code... > > Good luck; it goes with the territory :) > In `modellib.cxx' the `loadFile' and `loadModel' functions, which > check the file extensions for a `.ac' file and if so sets a flag for > instantiation of effects. This flags is only checked in the > 'ACOptimizePolicy::optimize' method in `ModelRegistry.cxx' and appears > it's only purpose is to make sure non xml wrapped `.ac' files get the > default model effect applied. This is done by calling an overloaded > `instantiateEffects' function in `model.hxx' that simply calls the > other version of the function with an empty effects property tree > causing default model effect to get used. Ok... > The support for "raw" .ac models exists for the random models associated with materials, which I think are the only use of non-wrapped models in FG. Perhaps you can include them directly in scenery too. ... > So here is the kicker...`instantiateEffects' does indeed seem to be > called for every single model wrapped in an xml regardless of whatever > format that might be. So then it seems the effect code is simply > failing silently on non ac3d formats. Perhaps in the > `MakeEffectVisitor' or further up the chain somewhere who > knows...deeper down the rabbit hole we go... > > So umm Tim...could you maybe explain the process of the whole model > loading, getting effects applied, what the effects system expects from > a model, the reasoning behind it and so on? There is a lot of static > local functions and classes and so on in this code that is completely > undocumented and not at all trivial to unwind and try and fit the > pieces together. Would be really, really helpful if you could lay out > the code flow here, what functions are involved and inter-dependent on > each other, what processing is needed for the effect system to work, > etc....in the mean time I'll keep digging. I'm not going to document the whole model loading process; it would be nice one day to have better comments in the code, but this code has accreted over many years, starting long before my involvement with FG. At a very high level, when a model is loaded, its OSG subgraph is copied, except for its textures and geometry. This is not-optimal, but it allows animation of all models without a complicated optimizer. In the monster function sgLoad3DModel_internal, effects mentioned in the .xml file are gathered, along with any created implicitly by animations. An effect is associated with named objects in the model. The .XML file can also specify a default effect for the whole file; by default that is Effects/model-default.eff. The model itself is transformed by instantiateEffects, which uses MakeEffectVisitor. For each named object in the model, this MakeEffectVisitor sets the appropriate effect as a "parent" effect, and then creates a new effect for any osg::StateSet found, inheriting from the parent. osg::Geode objects are replaced with simgear::EffectGeode objects that will apply the effect at runtime. There is quite a bit of hair to share effects and avoid creating new ones where possible. The dependency on .ac exists at this level in MakeEffectVisitor. The visitor expects to find osg::StateSet objects only in osg::Geode objects i.e., near the leaves of the scene graph. It only works with the simple attributes created by the .ac loader (see makeParametersFromStateSet): osg::Material properties, smooth vs. flat shading, polygon culling, blending (for transparency), and one texture binding. Any other attributes are ignored. If you want to apply effects to other kinds of models, you would need to generalize MakeEffectVisitor "in both directions." StateSet objects can appear in any scene graph node and also in the Geometry nodes that sit below osg::Geode. A more general effects visitor needs to track the graphics state as it traverses the scene graph and also needs to examine the geometry. Effects sit at the Geode level. Alternatively you could ignore any state attributes in the model and specify it all in the .xml file, but this would quickly get tiresome. I recommend you use the osgconv program to dump out the .osg representation of our .ac models and the models that interest you and get an idea of the differences you are up against. For .ac you should use our Optimizer options found in ModelRegistry.cxx; you can set them with the OSG_OPTIMIZER environment variable. I'll try to write more comments in the code over the next few weeks. In the mean time, keep hitting me with questions. I don't have the bandwidth to answer basic OSG questions, but I think you are beyond that and I'll do my best :) Tim |