From Brede Johansen, "I have made some changes to support light sources in the new
OpenFlight loader."
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -26,6 +26,7 @@ Document::Document() :
|
||||
_colorPoolParent(false),
|
||||
_texturePoolParent(false),
|
||||
_materialPoolParent(false),
|
||||
_lightSourcePoolParent(false),
|
||||
_lightPointAppearancePoolParent(false),
|
||||
_shaderPoolParent(false)
|
||||
{
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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())
|
||||
|
||||
Reference in New Issue
Block a user