From Brede Johansen, "I have made some changes to support light sources in the new

OpenFlight loader."
This commit is contained in:
Robert Osfield
2007-02-05 11:14:23 +00:00
parent 98b0eb889a
commit 3c5c4ae242
8 changed files with 243 additions and 28 deletions

View File

@@ -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();

View File

@@ -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);

View File

@@ -26,6 +26,7 @@ Document::Document() :
_colorPoolParent(false),
_texturePoolParent(false),
_materialPoolParent(false),
_lightSourcePoolParent(false),
_lightPointAppearancePoolParent(false),
_shaderPoolParent(false)
{

View File

@@ -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> _colorPool;
osg::ref_ptr<TexturePool> _texturePool;
osg::ref_ptr<MaterialPool> _materialPool;
osg::ref_ptr<LightSourcePool> _lightSourcePool;
osg::ref_ptr<LightPointAppearancePool> _lightPointAppearancePool;
osg::ref_ptr<ShaderPool> _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())

View File

@@ -5,6 +5,7 @@
//
#include <assert.h>
#include <osg/Light>
#include <osg/Texture2D>
#include <osg/TexEnv>
#include <osg/BlendFunc>
@@ -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<osg::Light> 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<LightSourcePalette> g_LightSourcePalette(LIGHT_SOURCE_PALETTE_OP);

View File

@@ -13,6 +13,7 @@
#include <osg/Vec4>
#include <osg/StateSet>
#include <osg/Material>
#include <osg/Light>
#include <osg/Program>
#include "types.h"
@@ -117,6 +118,26 @@ protected:
};
class LightSourcePool : public osg::Referenced , public std::map<int,osg::ref_ptr<osg::Light> >
{
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> _colorPool;
osg::ref_ptr<MaterialPool> _materialPool;
osg::ref_ptr<TexturePool> _texturePool;
osg::ref_ptr<LightSourcePool> _lightSourcePool;
osg::ref_ptr<LightPointAppearancePool> _lpAppearancePool;
osg::ref_ptr<ShaderPool> _shaderPool;
};

View File

@@ -12,6 +12,7 @@
#include <osg/Sequence>
#include <osg/LOD>
#include <osg/ProxyNode>
#include <osg/LightSource>
#include <osgDB/FileUtils>
#include <osgSim/DOFTransform>
#include <osgSim/MultiSwitch>
@@ -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<Object> 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<osg::LightSource> _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<LightSource> g_LightSource(LIGHT_SOURCE_OP);
} // end namespace

View File

@@ -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())