From 6c6c13145247eb45eaf144d553cb3bb7d9e479d3 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 4 Jul 2006 19:54:29 +0000 Subject: [PATCH] From Paul Martz, "Previously, the new OpenFlight plugin only allowed ext ref models to use their own palettes. With this change, parent models can override child model palettes with the parent palettes. These changes are made against very current CVS (just updated about 1/2 hour ago, eliminated conflicts, and retested before this posting). To regurgitate what I did: A new class, ParentPools (public osg::Referenced), is created when an ext ref record is parsed, and it is populated with any parent model pools that should override the child model pools (according to bits in the ext ref record). The ParentPools object is then set as UserData on the ProxyNode corresponding to the ext ref. When the ReadExternalsVisitor hits the ProxyNode, it takes its UserData and sets it as UserData in the Options parameter to the osgDB::ReadNode call, which then read the ext ref model. In the course of parsing the Options string, ReaderWriterFLT also looks at the Options UserData and sets the parent pools in the Document class accordingly. When palette records are encountered while loading a file, they are ignored if the corresponding pool was set by the parent. Thanks to Brede for consulting with me on the implementation. " --- src/osgPlugins/OpenFlight/Document.cpp | 7 +++- src/osgPlugins/OpenFlight/Document.h | 20 ++++++++- src/osgPlugins/OpenFlight/PaletteRecords.cpp | 24 +++++++++++ src/osgPlugins/OpenFlight/Pools.h | 42 +++++++++++++++++++ src/osgPlugins/OpenFlight/PrimaryRecords.cpp | 23 +++++++++- src/osgPlugins/OpenFlight/ReaderWriterFLT.cpp | 21 +++++++++- 6 files changed, 133 insertions(+), 4 deletions(-) diff --git a/src/osgPlugins/OpenFlight/Document.cpp b/src/osgPlugins/OpenFlight/Document.cpp index 3340de316..2bb48c372 100644 --- a/src/osgPlugins/OpenFlight/Document.cpp +++ b/src/osgPlugins/OpenFlight/Document.cpp @@ -19,7 +19,12 @@ Document::Document() : _level(0), _subfaceLevel(0), _unitScale(1.0), - _version(0) + _version(0), + _colorPoolParent(false), + _texturePoolParent(false), + _materialPoolParent(false), + _lightPointAppearancePoolParent(false), + _shaderPoolParent(false) { } diff --git a/src/osgPlugins/OpenFlight/Document.h b/src/osgPlugins/OpenFlight/Document.h index 3323b1aa7..820f55235 100644 --- a/src/osgPlugins/OpenFlight/Document.h +++ b/src/osgPlugins/OpenFlight/Document.h @@ -119,14 +119,27 @@ class Document VertexPool* getVertexPool() { return _vertexPool.get(); } const VertexPool* getVertexPool() const { return _vertexPool.get(); } - void setColorPool(ColorPool* cp) { _colorPool = cp; } + void setColorPool(ColorPool* cp, bool parent=false) { _colorPool = cp; _colorPoolParent=parent; } ColorPool* getColorPool() { return _colorPool.get(); } const ColorPool* getColorPool() const { return _colorPool.get(); } + bool getColorPoolParent() const { return _colorPoolParent; } + void setTexturePool(TexturePool* tp, bool parent=false) { _texturePool = tp; _texturePoolParent=parent; } TexturePool* getOrCreateTexturePool(); + bool getTexturePoolParent() const { return _texturePoolParent; } + + void setMaterialPool(MaterialPool* mp, bool parent=false) { _materialPool = mp; _materialPoolParent=parent; } MaterialPool* getOrCreateMaterialPool(); + bool getMaterialPoolParent() const { return _materialPoolParent; } + + void setLightPointAppearancePool(LightPointAppearancePool* lpap, bool parent=false) { _lightPointAppearancePool = lpap; _lightPointAppearancePoolParent=parent; } LightPointAppearancePool* getOrCreateLightPointAppearancePool(); + bool getLightPointAppearancePoolParent() const { return _lightPointAppearancePoolParent; } + + void setShaderPool(ShaderPool* cp, bool parent=false) { _shaderPool = cp; _shaderPoolParent=parent; } ShaderPool* getOrCreateShaderPool(); + bool getShaderPoolParent() const { return _shaderPoolParent; } + // Options void setPreserveFace(bool flag) { _preserveFace = flag; } @@ -166,6 +179,11 @@ class Document osg::ref_ptr _materialPool; osg::ref_ptr _lightPointAppearancePool; osg::ref_ptr _shaderPool; + bool _colorPoolParent; + bool _texturePoolParent; + bool _materialPoolParent; + bool _lightPointAppearancePoolParent; + bool _shaderPoolParent; osg::ref_ptr _currentPrimaryRecord; diff --git a/src/osgPlugins/OpenFlight/PaletteRecords.cpp b/src/osgPlugins/OpenFlight/PaletteRecords.cpp index bf9e6145b..3d73184c9 100644 --- a/src/osgPlugins/OpenFlight/PaletteRecords.cpp +++ b/src/osgPlugins/OpenFlight/PaletteRecords.cpp @@ -58,6 +58,10 @@ protected: virtual void readRecord(RecordInputStream& in, Document& document) { + if (document.getColorPoolParent()) + // Using parent's color pool -- ignore this record. + return; + if (document.version() > VERSION_13) { bool oldVersion = false; @@ -154,6 +158,10 @@ protected: virtual void readRecord(RecordInputStream& in, Document& document) { + if (document.getMaterialPoolParent()) + // Using parent's material pool -- ignore this record. + return; + int32 index = in.readInt32(); std::string name = in.readString(12); /*uint32 flags =*/ in.readUInt32(); @@ -193,6 +201,10 @@ protected: virtual void readRecord(RecordInputStream& in, Document& document) { + if (document.getMaterialPoolParent()) + // Using parent's material pool -- ignore this record. + return; + for (int i=0; i < 64; i++) { osg::Vec3f ambient = in.readVec3f(); @@ -254,6 +266,10 @@ protected: virtual void readRecord(RecordInputStream& in, Document& document) { + if (document.getTexturePoolParent()) + // Using parent's texture pool -- ignore this record. + return; + int maxLength = (document.version() < VERSION_14) ? 80 : 200; std::string filename = in.readString(maxLength); int32 index = in.readInt32(-1); @@ -457,6 +473,10 @@ protected: virtual void readRecord(RecordInputStream& in, Document& document) { + if (document.getLightPointAppearancePoolParent()) + // Using parent's light point appearance pool -- ignore this record. + return; + osg::ref_ptr appearance = new LPAppearance; in.forward(4); @@ -612,6 +632,10 @@ protected: virtual void readRecord(RecordInputStream& in, Document& document) { + if (document.getShaderPoolParent()) + // Using parent's shader pool -- ignore this record. + return; + int32 index = in.readInt32(); int32 type = in.readInt32(); std::string name = in.readString(1024); diff --git a/src/osgPlugins/OpenFlight/Pools.h b/src/osgPlugins/OpenFlight/Pools.h index af2c4dc81..7d153bdba 100644 --- a/src/osgPlugins/OpenFlight/Pools.h +++ b/src/osgPlugins/OpenFlight/Pools.h @@ -201,6 +201,48 @@ protected: virtual ~ShaderPool() {} }; + +// This object records parent palettes for external record support. +// When an external record is parsed, this object is instatiated and populated with +// the parent model's paettes, then stored as UserData on the ProxyNode. +// When the ReadExternalsVisitor hits the ProcyNode, it moves this object +// into the ReaderWriter Options' UserData before calling osgDB::ReadNode, +// enabling access to the parent palattes during load of the ext ref model. +class ParentPools : public osg::Referenced +{ +public: + + ParentPools( + ColorPool* color, + MaterialPool* material, + TexturePool* texture, + LightPointAppearancePool* lpAppearance, + ShaderPool* shader ) + : Referenced(), + _colorPool( color ), + _materialPool( material ), + _texturePool( texture ), + _lpAppearancePool( lpAppearance ), + _shaderPool( shader ) {} + + ColorPool* getColorPool() const { return _colorPool.get(); } + TexturePool* getTexturePool() const { return _texturePool.get(); } + MaterialPool* getMaterialPool() const { return _materialPool.get(); } + LightPointAppearancePool* getLPAppearancePool() const { return _lpAppearancePool.get(); } + ShaderPool* getShaderPool() const { return _shaderPool.get(); } + +protected: + + virtual ~ParentPools() {} + + osg::ref_ptr _colorPool; + osg::ref_ptr _materialPool; + osg::ref_ptr _texturePool; + osg::ref_ptr _lpAppearancePool; + osg::ref_ptr _shaderPool; +}; + + } // end namespace #endif diff --git a/src/osgPlugins/OpenFlight/PrimaryRecords.cpp b/src/osgPlugins/OpenFlight/PrimaryRecords.cpp index c40b2e980..c1a5128f7 100644 --- a/src/osgPlugins/OpenFlight/PrimaryRecords.cpp +++ b/src/osgPlugins/OpenFlight/PrimaryRecords.cpp @@ -16,6 +16,7 @@ #include "Registry.h" #include "Document.h" #include "RecordInputStream.h" +#include namespace flt { @@ -590,6 +591,16 @@ class ExternalReference : public PrimaryRecord { osg::ref_ptr _external; + // Parent pool override flags + static const unsigned long COLOR_PALETTE_OVERRIDE = 0x80000000u >> 0; + static const unsigned long MATERIAL_PALETTE_OVERRIDE = 0x80000000u >> 1; + static const unsigned long TEXTURE_PALETTE_OVERRIDE = 0x80000000u >> 2; + static const unsigned long LINE_STYLE_PALETTE_OVERRIDE = 0x80000000u >> 3; + static const unsigned long SOUND_PALETTE_OVERRIDE = 0x80000000u >> 4; + static const unsigned long LIGHT_SOURCE_PALETTE_OVERRIDE = 0x80000000u >> 5; + static const unsigned long LIGHT_POINT_PALETTE_OVERRIDE = 0x80000000u >> 6; + static const unsigned long SHADER_PALETTE_OVERRIDE = 0x80000000u >> 7; + public: ExternalReference() {} @@ -606,7 +617,7 @@ protected: virtual ~ExternalReference() {} - virtual void readRecord(RecordInputStream& in, Document& /*document*/) + virtual void readRecord(RecordInputStream& in, Document& document) { std::string strFile = in.readString(200); @@ -614,6 +625,16 @@ protected: _external->setCenterMode(osg::ProxyNode::USE_BOUNDING_SPHERE_CENTER); _external->setFileName(0,strFile); + // Set parent pools as user data + in.forward(4); + unsigned int mask = in.readUInt32(); + _external->setUserData( static_cast( new ParentPools( + ((mask & COLOR_PALETTE_OVERRIDE) ? NULL : document.getColorPool()), + ((mask & MATERIAL_PALETTE_OVERRIDE) ? NULL : document.getOrCreateMaterialPool()), + ((mask & TEXTURE_PALETTE_OVERRIDE) ? NULL : document.getOrCreateTexturePool()), + ((mask & LIGHT_POINT_PALETTE_OVERRIDE) ? NULL : document.getOrCreateLightPointAppearancePool()), + ((mask & SHADER_PALETTE_OVERRIDE) ? NULL : document.getOrCreateShaderPool()) ))); + // Add this implementation to parent implementation. if (_parent.valid()) _parent->addChild(*_external); diff --git a/src/osgPlugins/OpenFlight/ReaderWriterFLT.cpp b/src/osgPlugins/OpenFlight/ReaderWriterFLT.cpp index faed2217c..2c6101d67 100644 --- a/src/osgPlugins/OpenFlight/ReaderWriterFLT.cpp +++ b/src/osgPlugins/OpenFlight/ReaderWriterFLT.cpp @@ -41,6 +41,8 @@ public: virtual void apply(ProxyNode& node) { + _options->setUserData( node.getUserData() ); + for (unsigned int pos=0; posgetOptionString().find("convertToNauticalMiles")!=std::string::npos) document.setDesiredUnits(NAUTICAL_MILES); } + + const ParentPools* pools = dynamic_cast( options->getUserData() ); + if (pools) + { + // This file is an external reference. The individual pools will + // be non-NULL if the parent is overriding the ext ref model's pools. + if (pools->getColorPool()) + document.setColorPool( pools->getColorPool(), true ); + if (pools->getTexturePool()) + document.setTexturePool( pools->getTexturePool(), true ); + if (pools->getMaterialPool()) + document.setMaterialPool( pools->getMaterialPool(), true ); + if (pools->getLPAppearancePool()) + document.setLightPointAppearancePool( pools->getLPAppearancePool(), true ); + if (pools->getShaderPool()) + document.setShaderPool( pools->getShaderPool(), true ); + } } {