diff --git a/include/osg/PositionAttitudeTransform b/include/osg/PositionAttitudeTransform index 38565847f..16303b67c 100644 --- a/include/osg/PositionAttitudeTransform +++ b/include/osg/PositionAttitudeTransform @@ -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; }; } diff --git a/src/Demos/osglight/osglight.cpp b/src/Demos/osglight/osglight.cpp index df6499743..542c7fb52 100644 --- a/src/Demos/osglight/osglight.cpp +++ b/src/Demos/osglight/osglight.cpp @@ -5,12 +5,14 @@ #include #include -#include #include #include #include #include +#include +#include + #include #include @@ -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(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); diff --git a/src/osg/PositionAttitudeTransform.cpp b/src/osg/PositionAttitudeTransform.cpp index b5c7e14b3..a7616fe14 100644 --- a/src/osg/PositionAttitudeTransform.cpp +++ b/src/osg/PositionAttitudeTransform.cpp @@ -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; }