Jim Wilson:

This patch adds support to the model animation system for modifying emissive
states on the fly so that it is possible to make "lights" appear to dimm.

This is an example of a configuration entry which should explain how it is used:


 <animation>
  <type>material-emission</type>
  <object-name>Face</object-name>
  <property>/controls/lighting/instruments-norm</property>
  <emiss-red>1.0</emiss-red>
  <emiss-green>0.8</emiss-green>
  <emiss-blue>0.5</emiss-blue>
 </animation>

Note the color entries are the emissive colors when the "property" value is
1.0.  They are useful for tinting the light.   The "property" itself must be
float or double and is clamped to values between 0 ~ 1.0 inclusively.   The
"property" value is multiplied against the colors to get the actual material
properties.  Thus property value 0.0 = darkest, and 1.0 = brightest.
This commit is contained in:
ehofman 2005-01-29 10:31:25 +00:00
parent 207c7ab1e0
commit 7795eb8239
3 changed files with 116 additions and 0 deletions

View File

@ -1111,6 +1111,97 @@ void SGAlphaTestAnimation::setAlphaClampToBranch(ssgBranch *b, float clamp)
////////////////////////////////////////////////////////////////////////
// Implementation of SGEmissionAnimation
////////////////////////////////////////////////////////////////////////
SGEmissionAnimation::SGEmissionAnimation( SGPropertyNode *prop_root, SGPropertyNode_ptr props)
: SGAnimation(props, new ssgBranch),
_prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true))
{
_color0 = props->getFloatValue("emiss-red", 0.0);
_color1 = props->getFloatValue("emiss-green", 0.0);
_color2 = props->getFloatValue("emiss-blue", 0.0);
_old_brightness = 0;
ssgSimpleState* _cached_material;
ssgSimpleState* _cloned_material;
}
SGEmissionAnimation::~SGEmissionAnimation ()
{
}
void SGEmissionAnimation::init()
{
// clone material state(s) for this branch
cloneMaterials(_branch);
}
void SGEmissionAnimation::cloneMaterials(ssgBranch *b)
{
// clone material state(s) for this branch
int nb = b->getNumKids();
// Traverse the branch(es) and make clones of material settings for the leaves on
// this branch (ssgSimpleState objects).
// Try to be efficient (only make a new clone if the original is different
// than the previous).
for (int i = 0; i<nb; i++) {
ssgEntity *e = b->getKid(i);
if (e->isAKindOf(ssgTypeLeaf())) {
ssgSimpleState*s = (ssgSimpleState*)((ssgLeaf*)e)->getState();
// if this is a new material state, then make a copy of it...
if (!_cached_material || _cached_material != s) {
_cached_material = s;
_cloned_material = (ssgSimpleState*)s->clone(SSG_CLONE_STATE);
}
// set the material to the clone...
((ssgLeaf*)e)->setState( _cloned_material );
} else if (e->isAKindOf(ssgTypeBranch())) {
cloneMaterials( (ssgBranch*)e );
}
}
}
int SGEmissionAnimation::update()
{
float brightness = _prop->getFloatValue();
// clamp brightness 0 ~ 1
if (brightness < 0.00) brightness = 0.00;
if (brightness > 1.00) brightness = 1.00;
// no need to update states unless something changes...
if (brightness != _old_brightness) {
_old_brightness = brightness; // save it
float rd,gr,bl;
rd = _color0 * brightness;
gr = _color1 * brightness;
bl = _color2 * brightness;
setEmissionBranch(_branch, rd, gr, bl);
}
return 1;
}
void SGEmissionAnimation::setEmissionBranch(ssgBranch *b, float color0, float color1, float color2)
{
int nb = b->getNumKids();
for (int i = 0; i<nb; i++) {
ssgEntity *e = b->getKid(i);
if (e->isAKindOf(ssgTypeLeaf())) {
ssgSimpleState*s = (ssgSimpleState*)((ssgLeaf*)e)->getState();
s->enable( GL_ALPHA_TEST );
s->setMaterial( GL_EMISSION, color0, color1, color2, 0.0 );
} else if (e->isAKindOf(ssgTypeBranch())) {
setEmissionBranch((ssgBranch*)e, color0, color1, color2);
}
}
}
////////////////////////////////////////////////////////////////////////
// Implementation of SGFlashAnimation
////////////////////////////////////////////////////////////////////////

View File

@ -433,6 +433,29 @@ private:
};
/**
* An "animation" to modify emissive values on leaf nodes
*/
class SGEmissionAnimation : public SGAnimation
{
public:
SGEmissionAnimation(SGPropertyNode *prop_root, SGPropertyNode_ptr props);
virtual ~SGEmissionAnimation ();
virtual void init();
virtual int update();
private:
SGPropertyNode_ptr _prop;
ssgSimpleState* _cached_material;
ssgSimpleState* _cloned_material;
void cloneMaterials(ssgBranch *b);
void setEmissionBranch(ssgBranch *b, float color0, float color1, float color2);
float _color0;
float _color1;
float _color2;
float _old_brightness;
};
/**
* An "animation" that compute a scale according to
* the angle between an axis and the view direction

View File

@ -159,6 +159,8 @@ sgMakeAnimation( ssgBranch * model,
ignore = true;
} else if (!strcmp("alpha-test", type)) {
animation = new SGAlphaTestAnimation(node);
} else if (!strcmp("material-emission", type)) {
animation = new SGEmissionAnimation(prop_root, node);
} else if (!strcmp("flash", type)) {
animation = new SGFlashAnimation(node);
} else if (!strcmp("dist-scale", type)) {