diff --git a/src/osgPlugins/OpenFlight/DataInputStream.cpp b/src/osgPlugins/OpenFlight/DataInputStream.cpp index c0e2a71fc..c6172777f 100644 --- a/src/osgPlugins/OpenFlight/DataInputStream.cpp +++ b/src/osgPlugins/OpenFlight/DataInputStream.cpp @@ -147,6 +147,19 @@ osg::Vec3f DataInputStream::readVec3f() } +osg::Vec4f DataInputStream::readVec4f() +{ + float32 x = readFloat32(); + float32 y = readFloat32(); + float32 z = readFloat32(); + float32 w = readFloat32(); + + osg::Vec4f vec(x,y,z,w); + + return vec; +} + + osg::Vec3d DataInputStream::readVec3d() { float64 x = readFloat64(); diff --git a/src/osgPlugins/OpenFlight/DataInputStream.h b/src/osgPlugins/OpenFlight/DataInputStream.h index 4d3250138..c580f3ace 100644 --- a/src/osgPlugins/OpenFlight/DataInputStream.h +++ b/src/osgPlugins/OpenFlight/DataInputStream.h @@ -38,6 +38,7 @@ class DataInputStream : public std::istream osg::Vec4f readColor32(); osg::Vec2f readVec2f(); osg::Vec3f readVec3f(); + osg::Vec4f readVec4f(); osg::Vec3d readVec3d(); std::istream& forward(std::istream::off_type off); diff --git a/src/osgPlugins/OpenFlight/Document.cpp b/src/osgPlugins/OpenFlight/Document.cpp index 9a4d12140..a36d05c87 100644 --- a/src/osgPlugins/OpenFlight/Document.cpp +++ b/src/osgPlugins/OpenFlight/Document.cpp @@ -26,6 +26,7 @@ Document::Document() : _colorPoolParent(false), _texturePoolParent(false), _materialPoolParent(false), + _lightSourcePoolParent(false), _lightPointAppearancePoolParent(false), _shaderPoolParent(false) { diff --git a/src/osgPlugins/OpenFlight/Document.h b/src/osgPlugins/OpenFlight/Document.h index 13264e6b9..c8409141a 100644 --- a/src/osgPlugins/OpenFlight/Document.h +++ b/src/osgPlugins/OpenFlight/Document.h @@ -125,18 +125,27 @@ class Document bool getColorPoolParent() const { return _colorPoolParent; } void setTexturePool(TexturePool* tp, bool parent=false) { _texturePool = tp; _texturePoolParent=parent; } + TexturePool* getTexturePool() { return _texturePool.get(); } TexturePool* getOrCreateTexturePool(); bool getTexturePoolParent() const { return _texturePoolParent; } void setMaterialPool(MaterialPool* mp, bool parent=false) { _materialPool = mp; _materialPoolParent=parent; } + MaterialPool* getMaterialPool() { return _materialPool.get(); } MaterialPool* getOrCreateMaterialPool(); bool getMaterialPoolParent() const { return _materialPoolParent; } + void setLightSourcePool(LightSourcePool* lsp, bool parent=false) { _lightSourcePool = lsp; _lightSourcePoolParent=parent; } + LightSourcePool* getLightSourcePool() { return _lightSourcePool.get(); } + LightSourcePool* getOrCreateLightSourcePool(); + bool getLightSourcePoolParent() const { return _lightSourcePoolParent; } + void setLightPointAppearancePool(LightPointAppearancePool* lpap, bool parent=false) { _lightPointAppearancePool = lpap; _lightPointAppearancePoolParent=parent; } + LightPointAppearancePool* getLightPointAppearancePool() { return _lightPointAppearancePool.get(); } LightPointAppearancePool* getOrCreateLightPointAppearancePool(); bool getLightPointAppearancePoolParent() const { return _lightPointAppearancePoolParent; } void setShaderPool(ShaderPool* cp, bool parent=false) { _shaderPool = cp; _shaderPoolParent=parent; } + ShaderPool* getShaderPool() { return _shaderPool.get(); } ShaderPool* getOrCreateShaderPool(); bool getShaderPoolParent() const { return _shaderPoolParent; } @@ -191,11 +200,13 @@ class Document osg::ref_ptr _colorPool; osg::ref_ptr _texturePool; osg::ref_ptr _materialPool; + osg::ref_ptr _lightSourcePool; osg::ref_ptr _lightPointAppearancePool; osg::ref_ptr _shaderPool; bool _colorPoolParent; bool _texturePoolParent; bool _materialPoolParent; + bool _lightSourcePoolParent; bool _lightPointAppearancePoolParent; bool _shaderPoolParent; @@ -226,6 +237,14 @@ inline MaterialPool* Document::getOrCreateMaterialPool() } +inline LightSourcePool* Document::getOrCreateLightSourcePool() +{ + if (!_lightSourcePool.valid()) + _lightSourcePool = new LightSourcePool; + return _lightSourcePool.get(); +} + + inline LightPointAppearancePool* Document::getOrCreateLightPointAppearancePool() { if (!_lightPointAppearancePool.valid()) diff --git a/src/osgPlugins/OpenFlight/PaletteRecords.cpp b/src/osgPlugins/OpenFlight/PaletteRecords.cpp index 356cd049d..ee0170ca7 100644 --- a/src/osgPlugins/OpenFlight/PaletteRecords.cpp +++ b/src/osgPlugins/OpenFlight/PaletteRecords.cpp @@ -5,6 +5,7 @@ // #include +#include #include #include #include @@ -475,11 +476,72 @@ public: META_Record(LightSourcePalette) + enum LightType + { + INFINITE_LIGHT = 0, + LOCAL_LIGHT = 1, + SPOT_LIGHT = 2 + }; + protected: virtual ~LightSourcePalette() {} - virtual void readRecord(RecordInputStream& /*in*/, Document& /*document*/) {} + virtual void readRecord(RecordInputStream& in, Document& document) + { + if (document.getLightSourcePoolParent()) + // Using parent's texture pool -- ignore this record. + return; + + int32 index = in.readInt32(-1); + in.forward(2*4); + std::string name = in.readString(20); + in.forward(4); + osg::Vec4f ambient = in.readVec4f(); + osg::Vec4f diffuse = in.readVec4f(); + osg::Vec4f specular = in.readVec4f(); + int32 type = in.readInt32(); + in.forward(4*10); + float32 spotExponent = in.readFloat32(); + float32 spotCutoff = in.readFloat32(); + float32 yaw = in.readFloat32(); + float32 pitch = in.readFloat32(); + float32 constantAttenuation = in.readFloat32(); + float32 linearAttenuation = in.readFloat32(); + float32 quadraticAttenuation = in.readFloat32(); + int32 active = in.readInt32(); + + osg::ref_ptr light = new osg::Light; + light->setAmbient(ambient); + light->setDiffuse(diffuse); + light->setSpecular(specular); + + switch (type) + { + case INFINITE_LIGHT: + light->setPosition(osg::Vec4(0.0f,0.0f,1.0f,0.0f)); + break; + case LOCAL_LIGHT: + light->setPosition(osg::Vec4(0.0f,0.0f,0.0f,1.0f)); + light->setConstantAttenuation(constantAttenuation); + light->setLinearAttenuation(linearAttenuation); + light->setQuadraticAttenuation(quadraticAttenuation); + break; + case SPOT_LIGHT: + light->setPosition(osg::Vec4(0.0f,0.0f,0.0f,1.0f)); + light->setDirection(osg::Vec3(0.0f,1.0f,0.0f)); + light->setConstantAttenuation(constantAttenuation); + light->setLinearAttenuation(linearAttenuation); + light->setQuadraticAttenuation(quadraticAttenuation); + light->setSpotExponent(spotExponent); + light->setSpotCutoff(spotCutoff); + break; + } + + // Add to pool + LightSourcePool* pool = document.getOrCreateLightSourcePool(); + (*pool)[index] = light.get(); + } }; RegisterRecordProxy g_LightSourcePalette(LIGHT_SOURCE_PALETTE_OP); diff --git a/src/osgPlugins/OpenFlight/Pools.h b/src/osgPlugins/OpenFlight/Pools.h index f6ccaa0cb..691cdc762 100644 --- a/src/osgPlugins/OpenFlight/Pools.h +++ b/src/osgPlugins/OpenFlight/Pools.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "types.h" @@ -117,6 +118,26 @@ protected: }; +class LightSourcePool : public osg::Referenced , public std::map > +{ +public: + + LightSourcePool() {} + + osg::Light* get(int index) + { + iterator itr = find(index); + if (itr != end()) + return (*itr).second.get(); + return NULL; + } + +protected: + + virtual ~LightSourcePool() {} +}; + + struct LPAppearance : public osg::Referenced { std::string name; @@ -204,31 +225,32 @@ protected: // 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 +// the parent model's palettes, then stored as UserData on the ProxyNode. +// When the ReadExternalsVisitor hits the ProxyNode, 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. +// enabling access to the parent palettes during load of the ext ref model. class ParentPools : public osg::Referenced { public: - ParentPools( - ColorPool* color, - MaterialPool* material, - TexturePool* texture, - LightPointAppearancePool* lpAppearance, - ShaderPool* shader ) - : osg::Referenced(), - _colorPool( color ), - _materialPool( material ), - _texturePool( texture ), - _lpAppearancePool( lpAppearance ), - _shaderPool( shader ) {} + ParentPools() {} + void setColorPool(ColorPool* pool) { _colorPool=pool; } ColorPool* getColorPool() const { return _colorPool.get(); } + + void setTexturePool(TexturePool* pool) { _texturePool=pool; } TexturePool* getTexturePool() const { return _texturePool.get(); } + + void setMaterialPool(MaterialPool* pool) { _materialPool=pool; } MaterialPool* getMaterialPool() const { return _materialPool.get(); } + + void setLightSourcePool(LightSourcePool* pool) { _lightSourcePool=pool; } + LightSourcePool* getLightSourcePool() const { return _lightSourcePool.get(); } + + void setLPAppearancePool(LightPointAppearancePool* pool) { _lpAppearancePool=pool; } LightPointAppearancePool* getLPAppearancePool() const { return _lpAppearancePool.get(); } + + void setShaderPool(ShaderPool* pool) { _shaderPool=pool; } ShaderPool* getShaderPool() const { return _shaderPool.get(); } protected: @@ -238,6 +260,7 @@ protected: osg::ref_ptr _colorPool; osg::ref_ptr _materialPool; osg::ref_ptr _texturePool; + osg::ref_ptr _lightSourcePool; osg::ref_ptr _lpAppearancePool; osg::ref_ptr _shaderPool; }; diff --git a/src/osgPlugins/OpenFlight/PrimaryRecords.cpp b/src/osgPlugins/OpenFlight/PrimaryRecords.cpp index c77cd7abb..571409aa9 100644 --- a/src/osgPlugins/OpenFlight/PrimaryRecords.cpp +++ b/src/osgPlugins/OpenFlight/PrimaryRecords.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -640,18 +641,27 @@ protected: if (document.version() == 1541) mask = ~0; - // Only override light points and shader palettes if - // we are the correct version. - bool parentLightPoints( (document.version() >= VERSION_15_8) && - ((mask & LIGHT_POINT_PALETTE_OVERRIDE) == 0) ); - bool parentShaders( (document.version() >= VERSION_16_0) && - ((mask & SHADER_PALETTE_OVERRIDE) == 0) ); - _external->setUserData(new ParentPools( - ((mask & COLOR_PALETTE_OVERRIDE) ? NULL : document.getColorPool()), - ((mask & MATERIAL_PALETTE_OVERRIDE) ? NULL : document.getOrCreateMaterialPool()), - ((mask & TEXTURE_PALETTE_OVERRIDE) ? NULL : document.getOrCreateTexturePool()), - ((!parentLightPoints) ? NULL : document.getOrCreateLightPointAppearancePool()), - ((!parentShaders) ? NULL : document.getOrCreateShaderPool()) )); + ParentPools* parentPools = new ParentPools; + + if ((mask & COLOR_PALETTE_OVERRIDE) == 0) + parentPools->setColorPool(document.getColorPool()); + + if ((mask & MATERIAL_PALETTE_OVERRIDE) == 0) + parentPools->setMaterialPool(document.getMaterialPool()); + + if ((mask & TEXTURE_PALETTE_OVERRIDE) == 0) + parentPools->setTexturePool(document.getTexturePool()); + + if ((document.version() >= VERSION_15_1) && ((mask & LIGHT_SOURCE_PALETTE_OVERRIDE) == 0)) + parentPools->setLightSourcePool(document.getLightSourcePool()); + + if ((document.version() >= VERSION_15_8) && ((mask & LIGHT_POINT_PALETTE_OVERRIDE) == 0)) + parentPools->setLPAppearancePool(document.getLightPointAppearancePool()); + + if ((document.version() >= VERSION_16_0) && ((mask & SHADER_PALETTE_OVERRIDE) == 0)) + parentPools->setShaderPool(document.getShaderPool()); + + _external->setUserData(parentPools); } // Add this implementation to parent implementation. @@ -884,6 +894,90 @@ protected: RegisterRecordProxy g_Object(OBJECT_OP); + +/** LightSource +*/ +class LightSource : public PrimaryRecord +{ + static const unsigned int ENABLED = 0x80000000u >> 0; + static const unsigned int GLOBAL = 0x80000000u >> 1; + static const unsigned int EXPORT = 0x80000000u >> 3; + + osg::ref_ptr _lightSource; + +public: + + LightSource() {} + + META_Record(LightSource) + + META_setID(_lightSource) + META_setComment(_lightSource) + META_setMatrix(_lightSource) + +protected: + + virtual ~LightSource() {} + + virtual void readRecord(RecordInputStream& in, Document& document) + { + std::string id = in.readString(8); + in.forward(4); + int32 index = in.readInt32(); + in.forward(4); + uint32 flags = in.readUInt32(); + in.forward(4); + osg::Vec3d pos = in.readVec3d(); + float32 yaw = in.readFloat32(); + float32 pitch = in.readFloat32(); + + _lightSource = new osg::LightSource; + _lightSource->setName(id); + + LightSourcePool* pool = document.getOrCreateLightSourcePool(); + osg::Light* lightFromPool = pool->get(index); + if (lightFromPool) + { + // Make a clone of light in pool. + osg::Light* light = new osg::Light(*lightFromPool); + + // TODO: Find a better way to set light number. + light->setLightNum(1); + + // Position + float w = lightFromPool->getPosition().w(); + if (w > 0.0) // positional light? + light->setPosition(osg::Vec4(pos,w)); + + // Apply yaw and pitch for infinite and spot light. + if ((w==0.0) || (light->getSpotCutoff()<180.0)) + { + // TODO: What direction is zero yaw and pitch? + osg::Quat rotation( osg::Quat(osg::inDegrees(yaw),osg::Vec3(0.0,0.0,1.0)) * osg::Quat(osg::inDegrees(pitch),osg::Vec3(1.0,0.0,0.0)) ); + light->setDirection(rotation*osg::Vec3(0.0,1.0,0.0)); + } + + _lightSource->setLight(light); + _lightSource->setLocalStateSetModes((flags & ENABLED) ? osg::StateAttribute::ON : osg::StateAttribute::OFF); + + // Global light. + if (flags & GLOBAL) + { + // Apply light source to header node. + osg::Node* header = document.getHeaderNode(); + if (header) + _lightSource->setStateSetModes(*(header->getOrCreateStateSet()),osg::StateAttribute::ON); + } + } + + if (_parent.valid()) + _parent->addChild(*_lightSource); + } +}; + +RegisterRecordProxy g_LightSource(LIGHT_SOURCE_OP); + + } // end namespace diff --git a/src/osgPlugins/OpenFlight/ReaderWriterFLT.cpp b/src/osgPlugins/OpenFlight/ReaderWriterFLT.cpp index 1209ea240..2ae6a0e43 100644 --- a/src/osgPlugins/OpenFlight/ReaderWriterFLT.cpp +++ b/src/osgPlugins/OpenFlight/ReaderWriterFLT.cpp @@ -218,6 +218,8 @@ class FLTReaderWriter : public ReaderWriter document.setTexturePool( pools->getTexturePool(), true ); if (pools->getMaterialPool()) document.setMaterialPool( pools->getMaterialPool(), true ); + if (pools->getLightSourcePool()) + document.setLightSourcePool( pools->getLightSourcePool(), true ); if (pools->getLPAppearancePool()) document.setLightPointAppearancePool( pools->getLPAppearancePool(), true ); if (pools->getShaderPool())