Futher improvements and fixes to osg::AnimationPath, and the osglight

demo to show it action.
This commit is contained in:
Robert Osfield
2002-08-13 15:31:10 +00:00
parent 7c049360ff
commit f9cc8783b3
10 changed files with 175 additions and 172 deletions

View File

@@ -113,19 +113,6 @@ struct TransformCallback : public osg::Transform::ComputeTransformCallback
}
};
struct BillboardCallback : public osg::Billboard::ComputeBillboardCallback
{
/** Get the transformation matrix which moves from local coords to world coords.*/
virtual const bool computeMatrix(osg::Matrix& modelview, const osg::Billboard* billboard, const osg::Vec3& eye_local, const osg::Vec3& pos_local) const
{
std::cout<<"ComputeBillboardCallback - pre billboard->computeMatrix"<<std::endl;
bool result = billboard->computeMatrix(modelview,eye_local,pos_local);
std::cout<<"ComputeBillboardCallback - post billboard->computeMatrix"<<std::endl;
return result;
}
};
struct DrawableAppCallback : public osg::Drawable::AppCallback
{
virtual void app(osg::NodeVisitor*, osg::Drawable* drawable)
@@ -178,12 +165,6 @@ class InsertCallbacksVisitor : public osg::NodeVisitor
}
}
virtual void apply(osg::Billboard& node)
{
node.setComputeBillboardCallback(new BillboardCallback());
apply((osg::Geode&)node);
}
virtual void apply(osg::Transform& node)
{
node.setComputeTransformCallback(new TransformCallback());

View File

@@ -109,22 +109,22 @@ osg::Node* createLights(osg::BoundingBox& bb,osg::StateSet* rootStateSet)
lightS2->setStateSetModes(*rootStateSet,osg::StateAttribute::ON);
osg::PositionAttitudeTransform* pat = new osg::PositionAttitudeTransform();
osg::MatrixTransform* mt = new osg::MatrixTransform();
{
// 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)));
animationPath->insert(0.0,osg::AnimationPath::ControlPoint(bb.corner(0)));
animationPath->insert(1.0,osg::AnimationPath::ControlPoint(bb.corner(1)));
animationPath->insert(2.0,osg::AnimationPath::ControlPoint(bb.corner(2)));
animationPath->insert(3.0,osg::AnimationPath::ControlPoint(bb.corner(3)));
animationPath->insert(4.0,osg::AnimationPath::ControlPoint(bb.corner(4)));
animationPath->insert(5.0,osg::AnimationPath::ControlPoint(bb.corner(5)));
animationPath->insert(6.0,osg::AnimationPath::ControlPoint(bb.corner(6)));
animationPath->insert(7.0,osg::AnimationPath::ControlPoint(bb.corner(7)));
animationPath->insert(8.0,osg::AnimationPath::ControlPoint(bb.corner(0)));
animationPath->setLoopMode(osg::AnimationPath::SWING);
// attach it to the transform as an app callback.
pat->setAppCallback(new osg::PositionAttitudeTransform::AnimationPathCallback(animationPath));
mt->setAppCallback(new osg::MatrixTransform::AnimationPathCallback(animationPath));
}
// create marker for point light.
@@ -144,12 +144,12 @@ osg::Node* createLights(osg::BoundingBox& bb,osg::StateSet* rootStateSet)
osg::Geode* markerGeode = new osg::Geode;
markerGeode->addDrawable(marker);
pat->addChild(lightS2);
pat->addChild(markerGeode);
mt->addChild(lightS2);
mt->addChild(markerGeode);
lightGroup->addChild(lightS2);
lightGroup->addChild(pat);
lightGroup->addChild(mt);
return lightGroup;
}

View File

@@ -3,23 +3,50 @@
using namespace osg;
void AnimationPath::insert(double time,const Key& key)
void AnimationPath::insert(double time,const ControlPoint& ControlPoint)
{
_timeKeyMap[time] = key;
_timeControlPointMap[time] = ControlPoint;
}
bool AnimationPath::getMatrix(double time,Matrix& matrix) const
bool AnimationPath::getInterpolatedControlPoint(double time,ControlPoint& controlPoint) const
{
if (_timeKeyMap.empty()) return false;
TimeKeyMap::const_iterator second = _timeKeyMap.lower_bound(time);
if (second==_timeKeyMap.begin())
if (_timeControlPointMap.empty()) return false;
switch(_loopMode)
{
second->second.getMatrix(matrix);
case(SWING):
{
double modulated_time = (time - getFirstTime())/(getPeriod()*2.0);
double fraction_part = modulated_time - floor(modulated_time);
if (fraction_part>0.5) fraction_part = 1.0-fraction_part;
time = (fraction_part*2.0) * getPeriod();
break;
}
case(LOOP):
{
double modulated_time = (time - getFirstTime())/getPeriod();
double fraction_part = modulated_time - floor(modulated_time);
time = fraction_part * getPeriod();
break;
}
case(NO_LOOPING):
// no need to modulate the time.
break;
}
else if (second!=_timeKeyMap.end())
TimeControlPointMap::const_iterator second = _timeControlPointMap.lower_bound(time);
if (second==_timeControlPointMap.begin())
{
TimeKeyMap::const_iterator first = second;
controlPoint = second->second;
}
else if (second!=_timeControlPointMap.end())
{
TimeControlPointMap::const_iterator first = second;
--first;
// we have both a lower bound and the next item.
@@ -28,92 +55,17 @@ bool AnimationPath::getMatrix(double time,Matrix& matrix) const
double delta_time = second->first - first->first;
if (delta_time==0.0)
first->second.getMatrix(matrix);
controlPoint = first->second;
else
{
Key key;
key.interpolate((time - first->first)/delta_time,
first->second,
second->second);
key.getMatrix(matrix);
}
}
else // (second==_timeKeyMap.end())
{
_timeKeyMap.rbegin().base()->second.getMatrix(matrix);
}
return true;
}
bool AnimationPath::getInverse(double time,Matrix& matrix) const
{
if (_timeKeyMap.empty()) return false;
TimeKeyMap::const_iterator second = _timeKeyMap.lower_bound(time);
if (second==_timeKeyMap.begin())
{
second->second.getInverse(matrix);
}
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)
first->second.getInverse(matrix);
else
{
Key key;
key.interpolate((time - first->first)/delta_time,
first->second,
second->second);
key.getInverse(matrix);
}
}
else // (second==_timeKeyMap.end())
{
_timeKeyMap.rbegin().base()->second.getInverse(matrix);
}
return true;
}
bool AnimationPath::getKeyFrame(double time,Key& key) const
{
if (_timeKeyMap.empty()) return false;
TimeKeyMap::const_iterator second = _timeKeyMap.lower_bound(time);
if (second==_timeKeyMap.begin())
{
key = second->second;
}
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,
controlPoint.interpolate((time - first->first)/delta_time,
first->second,
second->second);
}
}
else // (second==_timeKeyMap.end())
else // (second==_timeControlPointMap.end())
{
key = _timeKeyMap.rbegin().base()->second;
controlPoint = _timeControlPointMap.rbegin()->second;
}
return true;
}

View File

@@ -21,7 +21,6 @@ Billboard::Billboard(const Billboard& billboard,const CopyOp& copyop):
_axis(billboard._axis),
_normal(billboard._normal),
_positionList(billboard._positionList),
_computeBillboardCallback(_computeBillboardCallback),
_cachedMode(billboard._cachedMode),
_side(billboard._side) {}

View File

@@ -30,3 +30,21 @@ MatrixTransform::MatrixTransform(const Matrix& mat )
MatrixTransform::~MatrixTransform()
{
}
void MatrixTransform::AnimationPathCallback::operator()(Node* node, NodeVisitor* nv)
{
MatrixTransform* mt = dynamic_cast<MatrixTransform*>(node);
if (mt &&
_animationPath.valid() &&
nv->getVisitorType()==NodeVisitor::APP_VISITOR &&
nv->getFrameStamp())
{
double time = nv->getFrameStamp()->getReferenceTime();
if (_firstTime==0.0) _firstTime = time;
Matrix matrix;
if (_animationPath->getMatrix(time-_firstTime,matrix))
{
mt->setMatrix(matrix);
}
}
}

View File

@@ -51,11 +51,11 @@ void PositionAttitudeTransform::AnimationPathCallback::operator()(Node* node, No
{
double time = nv->getFrameStamp()->getReferenceTime();
if (_firstTime==0.0) _firstTime = time;
AnimationPath::Key key;
if (_animationPath->getKeyFrame(time-_firstTime,key))
AnimationPath::ControlPoint cp;
if (_animationPath->getInterpolatedControlPoint(time-_firstTime,cp))
{
pat->setPosition(key._position);
pat->setAttitude(key._rotation);
pat->setPosition(cp._position);
pat->setAttitude(cp._rotation);
}
}
}