Added support for ReferenceFrame into osg::LightSource, modified the .osg

plugin and cull visitor to account for this change.
This commit is contained in:
Robert Osfield
2003-01-16 16:37:24 +00:00
parent a0e5b9b007
commit 4dd273de70
7 changed files with 118 additions and 31 deletions

View File

@@ -25,6 +25,26 @@ class SG_EXPORT LightSource : public Group
META_Node(osg, LightSource);
enum ReferenceFrame
{
RELATIVE_TO_PARENTS,
RELATIVE_TO_ABSOLUTE
};
/** Set the light sources's ReferenceFrame, either to be relative to its
* parent reference frame, or relative to an absolute coordinate
* frame. RELATIVE_TO_PARENTS is the default.
* Note: setting the ReferenceFrame to be RELATIVE_TO_ABSOLUTE will
* also set the CullingActive flag on the light source, and hence all
* of its parents, to false, thereby disabling culling of it and
* all its parents. This is neccessary to prevent inappropriate
* culling, but may impact cull times if the absolute light source is
* deep in the scene graph. It is therefore recommend to only use
* absolute light source at the top of the scene. */
void setReferenceFrame(ReferenceFrame rf);
ReferenceFrame getReferenceFrame() const { return _referenceFrame; }
/** Set the attached light.*/
void setLight(StateAttribute* light);
@@ -48,6 +68,8 @@ class SG_EXPORT LightSource : public Group
StateAttribute::GLModeValue _value;
ref_ptr<StateAttribute> _light;
ReferenceFrame _referenceFrame;
};
}

View File

@@ -64,7 +64,7 @@ class SG_EXPORT Transform : public Group
* culling, but may impact cull times if the absolute transform is
* deep in the scene graph. It is therefore recommend to only use
* absolute Transforms at the top of the scene, for such things as
* headlight LightSources or Heads up displays. */
* heads up displays. */
void setReferenceFrame(ReferenceFrame rf);
ReferenceFrame getReferenceFrame() const { return _referenceFrame; }

View File

@@ -124,12 +124,24 @@ int main( int argc, char **argv )
// set the globa state
// osg::StateSet* globalStateSet = new osg::StateSet;
// globalStateSet->setGlobalDefaults();
// cg->setGlobalStateSet(globalStateSet);
osg::StateSet* globalStateSet = new osg::StateSet;
globalStateSet->setGlobalDefaults();
cg->setGlobalStateSet(globalStateSet);
// add either a headlight or sun light to the scene.
osg::LightSource* lightsource = new osg::LightSource;
osg::Light* light = new osg::Light;
lightsource->setLight(light);
lightsource->setReferenceFrame(osg::LightSource::RELATIVE_TO_ABSOLUTE);
lightsource->setLocalStateSetModes(osg::StateAttribute::ON);
lightsource->addChild(scene.get());
// set the scene to render
cg->setSceneData(scene.get());
// cg->setSceneData(scene.get());
cg->setSceneData(lightsource);
// set up the pthread stack size to large enough to run into problems.
cg->setStackSize( 20*1024*1024);
@@ -153,18 +165,24 @@ int main( int argc, char **argv )
cg->sync();
// set the frame stamp for the new frame.
double time_since_start = timer.delta_s(timer.tick(),start_tick);
double time_since_start = timer.delta_s(start_tick,timer.tick());
frameStamp->setFrameNumber(frameNumber);
frameStamp->setReferenceTime(time_since_start);
// update the trackball
tb.input( kbmcb.mx(), kbmcb.my(), kbmcb.mbutton() );
// update the scene by traversing it with the the update visitor which will
// call all node update callbacks and animations.
scene->accept(update);
// update the main camera
cg->setView(tb.getMatrix().ptr());
// fire off the cull and draw traversals of the scene.
cg->frame();
// increment the frame number ready for the next frame
++frameNumber;
}
return 0;

View File

@@ -3,7 +3,8 @@
using namespace osg;
LightSource::LightSource():
_value(StateAttribute::ON)
_value(StateAttribute::ON),
_referenceFrame(RELATIVE_TO_PARENTS)
{
// switch off culling of light source nodes by default.
setCullingActive(false);
@@ -17,6 +18,11 @@ LightSource::~LightSource()
// ref_ptr<> automactially decrements the reference count of attached lights.
}
void LightSource::setReferenceFrame(ReferenceFrame rf)
{
_referenceFrame = rf;
setCullingActive(_referenceFrame==RELATIVE_TO_PARENTS);
}
void LightSource::setLight(StateAttribute* light)
{
@@ -44,7 +50,7 @@ bool LightSource::computeBound() const
{
Group::computeBound();
if (_light.valid())
if (_light.valid() && _referenceFrame==RELATIVE_TO_PARENTS)
{
const Light* light = dynamic_cast<const Light*>(_light.get());
if (light)

View File

@@ -27,6 +27,19 @@ bool LightSource_readLocalData(Object& obj, Input& fr)
LightSource& lightsource = static_cast<LightSource&>(obj);
if (fr[0].matchWord("referenceFrame")) {
if (fr[1].matchWord("RELATIVE_TO_ABSOLUTE")) {
lightsource.setReferenceFrame(LightSource::RELATIVE_TO_ABSOLUTE);
fr += 2;
iteratorAdvanced = true;
}
if (fr[1].matchWord("RELATIVE_TO_PARENTS")) {
lightsource.setReferenceFrame(LightSource::RELATIVE_TO_PARENTS);
fr += 2;
iteratorAdvanced = true;
}
}
StateAttribute* light=fr.readStateAttribute();
if (light)
{
@@ -42,6 +55,16 @@ bool LightSource_writeLocalData(const Object& obj, Output& fw)
{
const LightSource& lightsource = static_cast<const LightSource&>(obj);
fw.indent() << "referenceFrame ";
switch (lightsource.getReferenceFrame()) {
case LightSource::RELATIVE_TO_ABSOLUTE:
fw << "RELATIVE_TO_ABSOLUTE\n";
break;
case LightSource::RELATIVE_TO_PARENTS:
default:
fw << "RELATIVE_TO_PARENTS\n";
};
if (lightsource.getLight()) fw.writeObject(*lightsource.getLight());
return true;

View File

@@ -17,25 +17,35 @@ RegisterDotOsgWrapperProxy g_ShapeDrawableFuncProxy
new osg::ShapeDrawable,
"ShapeDrawable",
"Object Drawable ShapeDrawable",
&ShapeDrawable_readLocalData,
&ShapeDrawable_writeLocalData,
0,
0,
DotOsgWrapper::READ_AND_WRITE
);
bool ShapeDrawable_readLocalData(Object& obj, Input& fr)
{
bool iteratorAdvanced = false;
ShapeDrawable& geom = static_cast<ShapeDrawable&>(obj);
bool matchedFirst = false;
return iteratorAdvanced;
}
bool ShapeDrawable_writeLocalData(const Object& obj, Output& fw)
{
const ShapeDrawable& geom = static_cast<const ShapeDrawable&>(obj);
return true;
}
// RegisterDotOsgWrapperProxy g_ShapeDrawableFuncProxy
// (
// new osg::ShapeDrawable,
// "ShapeDrawable",
// "Object Drawable ShapeDrawable",
// &ShapeDrawable_readLocalData,
// &ShapeDrawable_writeLocalData,
// DotOsgWrapper::READ_AND_WRITE
// );
//
// bool ShapeDrawable_readLocalData(Object& obj, Input& fr)
// {
// bool iteratorAdvanced = false;
//
// ShapeDrawable& geom = static_cast<ShapeDrawable&>(obj);
//
// bool matchedFirst = false;
//
// return iteratorAdvanced;
// }
//
// bool ShapeDrawable_writeLocalData(const Object& obj, Output& fw)
// {
// const ShapeDrawable& geom = static_cast<const ShapeDrawable&>(obj);
//
// return true;
// }

View File

@@ -347,11 +347,19 @@ void CullVisitor::apply(LightSource& node)
StateSet* node_state = node.getStateSet();
if (node_state) pushStateSet(node_state);
RefMatrix& matrix = getModelViewMatrix();
StateAttribute* light = node.getLight();
if (light)
{
addPositionedAttribute(&matrix,light);
if (node.getReferenceFrame()==osg::LightSource::RELATIVE_TO_PARENTS)
{
RefMatrix& matrix = getModelViewMatrix();
addPositionedAttribute(&matrix,light);
}
else
{
// relative to absolute.
addPositionedAttribute(0,light);
}
}
handle_cull_callbacks_and_traverse(node);