Made improvements to osg::AnimationPath, added

osg::PositionAttitudeTransform::AnimationPathCallback which us an app callback
which uses an AnimationPath to specify the new positions of the transform.

Added AnimationPath code to osglight to animate the positional light.

Added CullVisitor::setCullingMode() code into SceneView so that SceneView's
CullingMode is now properly passed onto CullVisitor.  Note, this work
had been done before, but must has been lost in a merge. Umm...
This commit is contained in:
Robert Osfield 2002-08-13 13:22:46 +00:00
parent 983da4fb9c
commit 7c049360ff
5 changed files with 96 additions and 31 deletions

View File

@ -9,6 +9,7 @@
#include <osg/LightSource>
#include <osg/StateAttribute>
#include <osg/Geometry>
#include <osg/Point>
#include <osg/MatrixTransform>
#include <osg/PositionAttitudeTransform>
@ -95,7 +96,7 @@ osg::Node* createLights(osg::BoundingBox& bb,osg::StateSet* rootStateSet)
// create a local light.
osg::Light* myLight2 = new osg::Light;
myLight2->setLightNum(1);
myLight2->setPosition(osg::Vec4(bb.corner(1),1.0f));
myLight2->setPosition(osg::Vec4(0.0,0.0,0.0,1.0f));
myLight2->setAmbient(osg::Vec4(0.0f,1.0f,1.0f,1.0f));
myLight2->setDiffuse(osg::Vec4(0.0f,1.0f,1.0f,1.0f));
myLight2->setConstantAttenuation(1.0f);
@ -108,10 +109,43 @@ osg::Node* createLights(osg::BoundingBox& bb,osg::StateSet* rootStateSet)
lightS2->setStateSetModes(*rootStateSet,osg::StateAttribute::ON);
osg::PositionAttitudeTransform* pat = new osg::PositionAttitudeTransform();
{
// set up the animation path
osg::AnimationPath* animationPath = new osg::AnimationPath;
animationPath->insert(0.0,osg::AnimationPath::Key(bb.corner(0)));
animationPath->insert(1.0,osg::AnimationPath::Key(bb.corner(1)));
animationPath->insert(2.0,osg::AnimationPath::Key(bb.corner(2)));
animationPath->insert(3.0,osg::AnimationPath::Key(bb.corner(3)));
animationPath->insert(4.0,osg::AnimationPath::Key(bb.corner(4)));
animationPath->insert(5.0,osg::AnimationPath::Key(bb.corner(5)));
animationPath->insert(6.0,osg::AnimationPath::Key(bb.corner(6)));
animationPath->insert(7.0,osg::AnimationPath::Key(bb.corner(7)));
animationPath->insert(8.0,osg::AnimationPath::Key(bb.corner(0)));
// attach it to the transform as an app callback.
pat->setAppCallback(new osg::PositionAttitudeTransform::AnimationPathCallback(animationPath));
}
osg::Transform* pat = new osg::Transform();
// create marker for point light.
osg::Geometry* marker = new osg::Geometry;
osg::Vec3Array* vertices = new osg::Vec3Array;
vertices->push_back(osg::Vec3(0.0,0.0,0.0));
marker->setVertexArray(vertices);
marker->addPrimitive(new osg::DrawArrays(GL_POINTS,0,1));
osg::StateSet* stateset = new osg::StateSet;
osg::Point* point = new osg::Point;
point->setSize(4.0f);
stateset->setAttribute(point);
marker->setStateSet(stateset);
osg::Geode* markerGeode = new osg::Geode;
markerGeode->addDrawable(marker);
pat->addChild(lightS2);
pat->addChild(markerGeode);
lightGroup->addChild(lightS2);
@ -302,6 +336,14 @@ int main( int argc, char **argv )
// add a viewport to the viewer and attach the scene graph.
viewer.addViewport( rootnode );
osgUtil::SceneView* sv = viewer.getViewportSceneView(0);
if (sv)
{
// switch off small feature culling to prevent the light points from being culled.
sv->setCullingMode( sv->getCullingMode() & ~osg::CullStack::SMALL_FEATURE_CULLING);
sv->setCullingMode( 0);
}
// open the viewer window.
viewer.open();

View File

@ -82,35 +82,38 @@ bool AnimationPath::getInverse(double time,Matrix& matrix) const
return true;
}
const bool AnimationPath::computeLocalToWorldMatrix(Matrix& matrix,const Transform*, NodeVisitor* nv) const
{
if (nv)
{
const osg::FrameStamp* fs = nv->getFrameStamp();
if (fs)
{
osg::Matrix localMatrix;
getMatrix(fs->getReferenceTime(),localMatrix);
matrix.preMult(localMatrix);
return true;
}
}
return false;
}
/** Get the transformation matrix which moves from world coords to local coords.*/
const bool AnimationPath::computeWorldToLocalMatrix(Matrix& matrix,const Transform* , NodeVisitor* nv) const
bool AnimationPath::getKeyFrame(double time,Key& key) const
{
if (nv)
if (_timeKeyMap.empty()) return false;
TimeKeyMap::const_iterator second = _timeKeyMap.lower_bound(time);
if (second==_timeKeyMap.begin())
{
const osg::FrameStamp* fs = nv->getFrameStamp();
if (fs)
{
osg::Matrix localInverse;
getInverse(fs->getReferenceTime(),localInverse);
matrix.postMult(localInverse);
return true;
}
key = second->second;
}
return false;
else if (second!=_timeKeyMap.end())
{
TimeKeyMap::const_iterator first = second;
--first;
// we have both a lower bound and the next item.
// deta_time = second.time - first.time
double delta_time = second->first - first->first;
if (delta_time==0.0)
key = first->second;
else
{
key.interpolate((time - first->first)/delta_time,
first->second,
second->second);
}
}
else // (second==_timeKeyMap.end())
{
key = _timeKeyMap.rbegin().base()->second;
}
return true;
}

View File

@ -40,3 +40,22 @@ const bool PositionAttitudeTransform::computeWorldToLocalMatrix(Matrix& matrix,N
}
return true;
}
void PositionAttitudeTransform::AnimationPathCallback::operator()(Node* node, NodeVisitor* nv)
{
PositionAttitudeTransform* pat = dynamic_cast<PositionAttitudeTransform*>(node);
if (pat &&
_animationPath.valid() &&
nv->getVisitorType()==NodeVisitor::APP_VISITOR &&
nv->getFrameStamp())
{
double time = nv->getFrameStamp()->getReferenceTime();
if (_firstTime==0.0) _firstTime = time;
AnimationPath::Key key;
if (_animationPath->getKeyFrame(time-_firstTime,key))
{
pat->setPosition(key._position);
pat->setAttitude(key._rotation);
}
}
}

View File

@ -1074,7 +1074,7 @@ void Viewer::keyboard(unsigned char key, int x, int y)
case 'c' :
_smallFeatureCullingActive = !_smallFeatureCullingActive;
sceneView->getCullVisitor()->setCullingMode((osgUtil::CullVisitor::CullingMode)
sceneView->setCullingMode((osgUtil::CullVisitor::CullingMode)
((_smallFeatureCullingActive ? osgUtil::CullVisitor::SMALL_FEATURE_CULLING : osgUtil::CullVisitor::NO_CULLING) |
(_viewFrustumCullingActive ? osgUtil::CullVisitor::VIEW_FRUSTUM_CULLING : osgUtil::CullVisitor::NO_CULLING)));
if (_smallFeatureCullingActive)
@ -1097,7 +1097,7 @@ void Viewer::keyboard(unsigned char key, int x, int y)
{
osg::notify(osg::NOTICE) << "View frustum culling switched off "<< std::endl;
}
sceneView->getCullVisitor()->setCullingMode((osgUtil::CullVisitor::CullingMode)
sceneView->setCullingMode((osgUtil::CullVisitor::CullingMode)
((_smallFeatureCullingActive ? osgUtil::CullVisitor::SMALL_FEATURE_CULLING : osgUtil::CullVisitor::NO_CULLING) |
(_viewFrustumCullingActive ? osgUtil::CullVisitor::VIEW_FRUSTUM_CULLING : osgUtil::CullVisitor::NO_CULLING)));
break;

View File

@ -366,6 +366,7 @@ void SceneView::cullStage(osg::Matrix* projection,osg::Matrix* modelview,osgUtil
cullVisitor->setTraversalNumber(_frameStamp->getFrameNumber());
}
cullVisitor->setCullingMode(_cullingMode);
cullVisitor->setComputeNearFarMode(_computeNearFar);
cullVisitor->setLODBias(_LODBias);
cullVisitor->setSmallFeatureCullingPixelSize(_smallFeatureCullingPixelSize);