Added new s/getPivotPoint() support to osg::PositionAttitudeTransform.
Modified the osglight demo to use an AppCallback and a PositionAttitudeTransform to animate the loaded model.
This commit is contained in:
@@ -22,20 +22,28 @@ class SG_EXPORT PositionAttitudeTransform : public Transform
|
||||
PositionAttitudeTransform(const PositionAttitudeTransform& pat,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
|
||||
Transform(pat,copyop),
|
||||
_position(pat._position),
|
||||
_attitude(pat._attitude) {}
|
||||
_attitude(pat._attitude),
|
||||
_pivotPoint(pat._pivotPoint) {}
|
||||
|
||||
|
||||
META_Node(osg, PositionAttitudeTransform);
|
||||
|
||||
|
||||
void setPosition(const Vec3& pos) { _position = pos; }
|
||||
void setPosition(const Vec3& pos) { _position = pos; dirtyBound(); }
|
||||
|
||||
const Vec3& getPosition() const { return _position; }
|
||||
|
||||
void setAttitude(const Quat& quat) { _attitude = quat; }
|
||||
|
||||
void setAttitude(const Quat& quat) { _attitude = quat; dirtyBound(); }
|
||||
|
||||
const Quat& getAttitude() const { return _attitude; }
|
||||
|
||||
|
||||
void setPivotPoint(const Vec3& pivot) { _pivotPoint = pivot; dirtyBound(); }
|
||||
|
||||
const Vec3& setPivotPoint() const { return _pivotPoint; }
|
||||
|
||||
|
||||
virtual const bool computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor* nv) const;
|
||||
|
||||
virtual const bool computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor* nv) const;
|
||||
@@ -45,7 +53,7 @@ class SG_EXPORT PositionAttitudeTransform : public Transform
|
||||
|
||||
Vec3 _position;
|
||||
Quat _attitude;
|
||||
|
||||
Vec3 _pivotPoint;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -5,12 +5,14 @@
|
||||
#include <osg/Group>
|
||||
#include <osg/Node>
|
||||
|
||||
#include <osg/Transform>
|
||||
#include <osg/Light>
|
||||
#include <osg/LightSource>
|
||||
#include <osg/StateAttribute>
|
||||
#include <osg/Geometry>
|
||||
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osg/PositionAttitudeTransform>
|
||||
|
||||
#include <osgDB/Registry>
|
||||
#include <osgDB/ReadFile>
|
||||
|
||||
@@ -20,6 +22,51 @@
|
||||
#include "stdio.h"
|
||||
|
||||
|
||||
// callback to make the loaded model oscilate up and down.
|
||||
class ModelTransformCallback : public osg::NodeCallback
|
||||
{
|
||||
public:
|
||||
|
||||
ModelTransformCallback(const osg::BoundingSphere& bs)
|
||||
{
|
||||
_firstTime = 0.0;
|
||||
_period = 4.0f;
|
||||
_range = bs.radius()*0.5f;
|
||||
}
|
||||
|
||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
osg::PositionAttitudeTransform* pat = dynamic_cast<osg::PositionAttitudeTransform*>(node);
|
||||
const osg::FrameStamp* frameStamp = nv->getFrameStamp();
|
||||
if (pat && frameStamp)
|
||||
{
|
||||
if (_firstTime==0.0)
|
||||
{
|
||||
_firstTime = frameStamp->getReferenceTime();
|
||||
}
|
||||
|
||||
double phase = (frameStamp->getReferenceTime()-_firstTime)/_period;
|
||||
phase -= floor(phase);
|
||||
phase *= (2.0 * osg::PI);
|
||||
|
||||
osg::Quat rotation;
|
||||
rotation.makeRotate(phase,1.0f,1.0f,1.0f);
|
||||
|
||||
pat->setAttitude(rotation);
|
||||
|
||||
pat->setPosition(osg::Vec3(0.0f,0.0f,sin(phase))*_range);
|
||||
}
|
||||
|
||||
// must traverse the Node's subgraph
|
||||
traverse(node,nv);
|
||||
}
|
||||
|
||||
double _firstTime;
|
||||
double _period;
|
||||
double _range;
|
||||
|
||||
};
|
||||
|
||||
|
||||
osg::Node* createLights(osg::BoundingBox& bb,osg::StateSet* rootStateSet)
|
||||
{
|
||||
@@ -60,8 +107,15 @@ osg::Node* createLights(osg::BoundingBox& bb,osg::StateSet* rootStateSet)
|
||||
lightS2->setLocalStateSetModes(osg::StateAttribute::ON);
|
||||
|
||||
lightS2->setStateSetModes(*rootStateSet,osg::StateAttribute::ON);
|
||||
|
||||
|
||||
osg::Transform* pat = new osg::Transform();
|
||||
|
||||
pat->addChild(lightS2);
|
||||
|
||||
lightGroup->addChild(lightS2);
|
||||
|
||||
lightGroup->addChild(pat);
|
||||
|
||||
return lightGroup;
|
||||
}
|
||||
@@ -134,10 +188,22 @@ osg::Node* createRoom(osg::Node* loadedModel)
|
||||
|
||||
if (loadedModel)
|
||||
{
|
||||
root->addChild(loadedModel);
|
||||
bs = loadedModel->getBound();
|
||||
const osg::BoundingSphere& loaded_bs = loadedModel->getBound();
|
||||
|
||||
osg::PositionAttitudeTransform* pat = new osg::PositionAttitudeTransform();
|
||||
pat->setPivotPoint(loaded_bs.center());
|
||||
|
||||
pat->setAppCallback(new ModelTransformCallback(loaded_bs));
|
||||
pat->addChild(loadedModel);
|
||||
|
||||
bs = pat->getBound();
|
||||
|
||||
root->addChild(pat);
|
||||
|
||||
}
|
||||
|
||||
bs.radius()*=1.5f;
|
||||
|
||||
// create a bounding box, which we'll use to size the room.
|
||||
osg::BoundingBox bb;
|
||||
bb.expandBy(bs);
|
||||
|
||||
@@ -10,16 +10,15 @@ const bool PositionAttitudeTransform::computeLocalToWorldMatrix(Matrix& matrix,N
|
||||
{
|
||||
if (_referenceFrame==RELATIVE_TO_PARENTS)
|
||||
{
|
||||
osg::Matrix tmp;
|
||||
tmp.makeRotate(_attitude);
|
||||
tmp.setTrans(_position);
|
||||
|
||||
matrix.preMult(tmp);
|
||||
matrix.preMult(osg::Matrix::translate(-_pivotPoint)*
|
||||
osg::Matrix::rotate(_attitude)*
|
||||
osg::Matrix::translate(_position));
|
||||
}
|
||||
else // absolute
|
||||
{
|
||||
matrix.makeRotate(_attitude);
|
||||
matrix.setTrans(_position);
|
||||
matrix = osg::Matrix::translate(-_pivotPoint)*
|
||||
osg::Matrix::rotate(_attitude)*
|
||||
osg::Matrix::translate(_position);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -29,15 +28,15 @@ const bool PositionAttitudeTransform::computeWorldToLocalMatrix(Matrix& matrix,N
|
||||
{
|
||||
if (_referenceFrame==RELATIVE_TO_PARENTS)
|
||||
{
|
||||
osg::Matrix tmp;
|
||||
tmp.makeTranslate(-_position);
|
||||
tmp.postMult(osg::Matrix::rotate(_attitude.inverse()));
|
||||
matrix.postMult(tmp);
|
||||
matrix.postMult(osg::Matrix::translate(-_position)*
|
||||
osg::Matrix::rotate(_attitude.inverse())*
|
||||
osg::Matrix::translate(_pivotPoint));
|
||||
}
|
||||
else // absolute
|
||||
{
|
||||
matrix.makeTranslate(-_position);
|
||||
matrix.postMult(osg::Matrix::rotate(_attitude.inverse()));
|
||||
matrix = osg::Matrix::translate(-_position)*
|
||||
osg::Matrix::rotate(_attitude.inverse())*
|
||||
osg::Matrix::translate(_pivotPoint);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user