Duplicate light effect when animation is requested. Make dimmed lights work in multiplayer
This commit is contained in:
@@ -46,32 +46,29 @@ static EffectMap lightEffectMap;
|
|||||||
|
|
||||||
class SGLightAnimation::UpdateCallback : public osg::NodeCallback {
|
class SGLightAnimation::UpdateCallback : public osg::NodeCallback {
|
||||||
public:
|
public:
|
||||||
UpdateCallback(string k, const SGExpressiond* v, SGVec4d a, SGVec4d d, SGVec4d s) :
|
UpdateCallback(const SGExpressiond* v, SGVec4d a, SGVec4d d, SGVec4d s) :
|
||||||
_key(k),
|
|
||||||
_ambient(a),
|
_ambient(a),
|
||||||
_diffuse(d),
|
_diffuse(d),
|
||||||
_specular(s),
|
_specular(s),
|
||||||
_animationValue(v)
|
_animationValue(v)
|
||||||
{
|
{
|
||||||
_prev_values[k] = -1;
|
_prev_value = -1;
|
||||||
}
|
}
|
||||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||||
{
|
{
|
||||||
double dim = _animationValue->getValue();
|
double dim = _animationValue->getValue();
|
||||||
if (dim != _prev_values[_key]) {
|
if (dim != _prev_value) {
|
||||||
_prev_values[_key] = dim;
|
_prev_value = dim;
|
||||||
|
simgear::EffectGeode* geode = dynamic_cast<simgear::EffectGeode*>( node );
|
||||||
|
if (geode != 0) {
|
||||||
|
osg::ref_ptr<simgear::Effect> effect = geode->getEffect();
|
||||||
|
|
||||||
osg::ref_ptr<simgear::Effect> effect;
|
|
||||||
EffectMap::iterator iter = lightEffectMap.find(_key);
|
|
||||||
if (iter != lightEffectMap.end() && iter->second.lock(effect)) {
|
|
||||||
SGPropertyNode* params = effect->parametersProp;
|
SGPropertyNode* params = effect->parametersProp;
|
||||||
params->getNode("ambient")->setValue(_ambient * dim);
|
params->getNode("ambient")->setValue(_ambient * dim);
|
||||||
params->getNode("diffuse")->setValue(_diffuse * dim);
|
params->getNode("diffuse")->setValue(_diffuse * dim);
|
||||||
params->getNode("specular")->setValue(_specular * dim);
|
params->getNode("specular")->setValue(_specular * dim);
|
||||||
BOOST_FOREACH(osg::ref_ptr<simgear::Technique>& technique, effect->techniques)
|
BOOST_FOREACH(osg::ref_ptr<simgear::Technique>& technique, effect->techniques) {
|
||||||
{
|
BOOST_FOREACH(osg::ref_ptr<simgear::Pass>& pass, technique->passes) {
|
||||||
BOOST_FOREACH(osg::ref_ptr<simgear::Pass>& pass, technique->passes)
|
|
||||||
{
|
|
||||||
osg::Uniform* amb = pass->getUniform("Ambient");
|
osg::Uniform* amb = pass->getUniform("Ambient");
|
||||||
if (amb)
|
if (amb)
|
||||||
amb->set(osg::Vec4f(_ambient.x() * dim, _ambient.y() * dim, _ambient.z() * dim, _ambient.w() * dim));
|
amb->set(osg::Vec4f(_ambient.x() * dim, _ambient.y() * dim, _ambient.z() * dim, _ambient.w() * dim));
|
||||||
@@ -88,16 +85,12 @@ public:
|
|||||||
traverse(node, nv);
|
traverse(node, nv);
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
string _key;
|
|
||||||
SGVec4d _ambient;
|
SGVec4d _ambient;
|
||||||
SGVec4d _diffuse;
|
SGVec4d _diffuse;
|
||||||
SGVec4d _specular;
|
SGVec4d _specular;
|
||||||
SGSharedPtr<SGExpressiond const> _animationValue;
|
SGSharedPtr<SGExpressiond const> _animationValue;
|
||||||
|
double _prev_value;
|
||||||
typedef std::map<string, double> PrevValueMap;
|
|
||||||
static PrevValueMap _prev_values;
|
|
||||||
};
|
};
|
||||||
SGLightAnimation::UpdateCallback::PrevValueMap SGLightAnimation::UpdateCallback::_prev_values;
|
|
||||||
|
|
||||||
SGLightAnimation::SGLightAnimation(const SGPropertyNode* configNode,
|
SGLightAnimation::SGLightAnimation(const SGPropertyNode* configNode,
|
||||||
SGPropertyNode* modelRoot,
|
SGPropertyNode* modelRoot,
|
||||||
@@ -130,8 +123,6 @@ SGLightAnimation::createAnimationGroup(osg::Group& parent)
|
|||||||
{
|
{
|
||||||
osg::Group* grp = new osg::Group;
|
osg::Group* grp = new osg::Group;
|
||||||
grp->setName("light animation node");
|
grp->setName("light animation node");
|
||||||
if (_animationValue.valid())
|
|
||||||
grp->setUpdateCallback(new UpdateCallback(_key, _animationValue, _ambient, _diffuse, _specular));
|
|
||||||
parent.addChild(grp);
|
parent.addChild(grp);
|
||||||
grp->setNodeMask( simgear::MODELLIGHT_BIT );
|
grp->setNodeMask( simgear::MODELLIGHT_BIT );
|
||||||
return grp;
|
return grp;
|
||||||
@@ -142,12 +133,17 @@ SGLightAnimation::install(osg::Node& node)
|
|||||||
{
|
{
|
||||||
SGAnimation::install(node);
|
SGAnimation::install(node);
|
||||||
|
|
||||||
if (_light_type == "spot") {
|
bool cacheEffect = false;
|
||||||
|
osg::ref_ptr<simgear::Effect> effect;
|
||||||
|
EffectMap::iterator iter = lightEffectMap.end();
|
||||||
|
if (!_animationValue.valid()) { // Effects with animated properties should be singletons
|
||||||
|
iter = lightEffectMap.find(_key);
|
||||||
|
cacheEffect = true;
|
||||||
|
}
|
||||||
|
|
||||||
osg::ref_ptr<simgear::Effect> effect;
|
if (iter == lightEffectMap.end() || !iter->second.lock(effect)) {
|
||||||
EffectMap::iterator iter = lightEffectMap.find(_key);
|
SGPropertyNode_ptr effectProp = new SGPropertyNode;
|
||||||
if (iter == lightEffectMap.end() || !iter->second.lock(effect)) {
|
if (_light_type == "spot") {
|
||||||
SGPropertyNode_ptr effectProp = new SGPropertyNode;
|
|
||||||
makeChild(effectProp, "name")->setStringValue(_key);
|
makeChild(effectProp, "name")->setStringValue(_key);
|
||||||
makeChild(effectProp, "inherits-from")->setStringValue("Effects/light-spot");
|
makeChild(effectProp, "inherits-from")->setStringValue("Effects/light-spot");
|
||||||
double dim = 1.0;
|
double dim = 1.0;
|
||||||
@@ -166,37 +162,8 @@ SGLightAnimation::install(osg::Node& node)
|
|||||||
params->getNode("cosCutoff",true)->setValue( cos(_cutoff*SG_DEGREES_TO_RADIANS) );
|
params->getNode("cosCutoff",true)->setValue( cos(_cutoff*SG_DEGREES_TO_RADIANS) );
|
||||||
params->getNode("near",true)->setValue(_near);
|
params->getNode("near",true)->setValue(_near);
|
||||||
params->getNode("far",true)->setValue(_far);
|
params->getNode("far",true)->setValue(_far);
|
||||||
|
|
||||||
effect = simgear::makeEffect(effectProp, true);
|
|
||||||
if (iter==lightEffectMap.end())
|
|
||||||
lightEffectMap.insert(EffectMap::value_type(_key, effect));
|
|
||||||
else
|
|
||||||
iter->second = effect;
|
|
||||||
} else {
|
|
||||||
effect = iter->second.get();
|
|
||||||
}
|
}
|
||||||
|
else if (_light_type == "point") {
|
||||||
node.setNodeMask( simgear::MODELLIGHT_BIT );
|
|
||||||
simgear::EffectGeode* geode = dynamic_cast<simgear::EffectGeode*>(&node);
|
|
||||||
if (geode == 0) {
|
|
||||||
osg::Group* grp = node.asGroup();
|
|
||||||
if (grp != 0) {
|
|
||||||
for (size_t i=0; i<grp->getNumChildren(); ++i) {
|
|
||||||
geode = dynamic_cast<simgear::EffectGeode*>(grp->getChild(i));
|
|
||||||
if (geode) {
|
|
||||||
geode->setNodeMask( simgear::MODELLIGHT_BIT );
|
|
||||||
geode->setEffect(effect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_light_type == "point") {
|
|
||||||
|
|
||||||
osg::ref_ptr<simgear::Effect> effect;
|
|
||||||
EffectMap::iterator iter = lightEffectMap.find(_key);
|
|
||||||
if (iter == lightEffectMap.end() || !iter->second.lock(effect)) {
|
|
||||||
SGPropertyNode_ptr effectProp = new SGPropertyNode;
|
|
||||||
makeChild(effectProp, "name")->setStringValue(_key);
|
makeChild(effectProp, "name")->setStringValue(_key);
|
||||||
makeChild(effectProp, "inherits-from")->setStringValue("Effects/light-point");
|
makeChild(effectProp, "inherits-from")->setStringValue("Effects/light-point");
|
||||||
double dim = 1.0;
|
double dim = 1.0;
|
||||||
@@ -211,29 +178,34 @@ SGLightAnimation::install(osg::Node& node)
|
|||||||
params->getNode("attenuation",true)->setValue(_attenuation);
|
params->getNode("attenuation",true)->setValue(_attenuation);
|
||||||
params->getNode("near",true)->setValue(_near);
|
params->getNode("near",true)->setValue(_near);
|
||||||
params->getNode("far",true)->setValue(_far);
|
params->getNode("far",true)->setValue(_far);
|
||||||
|
|
||||||
effect = simgear::makeEffect(effectProp, true);
|
|
||||||
if (iter==lightEffectMap.end())
|
|
||||||
lightEffectMap.insert(EffectMap::value_type(_key, effect));
|
|
||||||
else
|
|
||||||
iter->second = effect;
|
|
||||||
} else {
|
} else {
|
||||||
effect = iter->second.get();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
node.setNodeMask( simgear::MODELLIGHT_BIT );
|
effect = simgear::makeEffect(effectProp, true);
|
||||||
simgear::EffectGeode* geode = dynamic_cast<simgear::EffectGeode*>(&node);
|
if (iter == lightEffectMap.end() && cacheEffect)
|
||||||
if (geode == 0) {
|
lightEffectMap.insert(EffectMap::value_type(_key, effect));
|
||||||
osg::Group* grp = node.asGroup();
|
else if (cacheEffect)
|
||||||
if (grp != 0) {
|
iter->second = effect;
|
||||||
for (size_t i=0; i<grp->getNumChildren(); ++i) {
|
} else {
|
||||||
geode = dynamic_cast<simgear::EffectGeode*>(grp->getChild(i));
|
effect = iter->second.get();
|
||||||
if (geode) {
|
}
|
||||||
geode->setNodeMask( simgear::MODELLIGHT_BIT );
|
|
||||||
geode->setEffect(effect);
|
node.setNodeMask( simgear::MODELLIGHT_BIT );
|
||||||
}
|
simgear::EffectGeode* geode = dynamic_cast<simgear::EffectGeode*>(&node);
|
||||||
|
if (geode == 0) {
|
||||||
|
osg::Group* grp = node.asGroup();
|
||||||
|
if (grp != 0) {
|
||||||
|
for (size_t i=0; i<grp->getNumChildren(); ++i) {
|
||||||
|
geode = dynamic_cast<simgear::EffectGeode*>(grp->getChild(i));
|
||||||
|
if (geode) {
|
||||||
|
geode->setNodeMask( simgear::MODELLIGHT_BIT );
|
||||||
|
geode->setEffect(effect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (geode != 0 && _animationValue.valid())
|
||||||
|
geode->setUpdateCallback(new UpdateCallback(_animationValue, _ambient, _diffuse, _specular));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user