Added a AnimationPathCallback which can update both a MatrixTransform and a
PositionAttitudeTransform, removed the equivialnt callbacks once found in these transform classes. Changed the NodeCallback class so its derived from osg::Object instead of osg::Referenced to allow it to be saved out in the .osg format. Added support for Update and Cull callbacks into the .osg file format. Added support for AnimationPathCallback into the .osg file format.
This commit is contained in:
parent
6ee563ad55
commit
fe64942c54
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include <osg/Matrix>
|
#include <osg/Matrix>
|
||||||
#include <osg/Quat>
|
#include <osg/Quat>
|
||||||
|
#include <osg/NodeVisitor>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
@ -131,6 +132,61 @@ class SG_EXPORT AnimationPath : public virtual osg::Object
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class SG_EXPORT AnimationPathCallback : public NodeCallback, public NodeVisitor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
AnimationPathCallback():
|
||||||
|
_timeOffset(0.0),
|
||||||
|
_timeMultiplier(1.0),
|
||||||
|
_firstTime(0.0),
|
||||||
|
_animationTime(0.0) {}
|
||||||
|
|
||||||
|
|
||||||
|
AnimationPathCallback(const AnimationPathCallback& apc,const CopyOp& copyop):
|
||||||
|
NodeCallback(apc,copyop),
|
||||||
|
_animationPath(apc._animationPath),
|
||||||
|
_timeOffset(apc._timeOffset),
|
||||||
|
_timeMultiplier(apc._timeMultiplier),
|
||||||
|
_firstTime(apc._firstTime),
|
||||||
|
_animationTime(apc._animationTime) {}
|
||||||
|
|
||||||
|
|
||||||
|
META_Object(osg,AnimationPathCallback)
|
||||||
|
|
||||||
|
AnimationPathCallback(AnimationPath* ap,double timeOffset=0.0f,double timeMultiplier=1.0f):
|
||||||
|
_animationPath(ap),
|
||||||
|
_timeOffset(timeOffset),
|
||||||
|
_timeMultiplier(timeMultiplier),
|
||||||
|
_firstTime(0.0),
|
||||||
|
_animationTime(0.0) {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void setAnimationPath(AnimationPath* path) { _animationPath = path; }
|
||||||
|
|
||||||
|
AnimationPath* getAnimationPath() { return _animationPath.get(); }
|
||||||
|
|
||||||
|
const AnimationPath* getAnimationPath() const { return _animationPath.get(); }
|
||||||
|
|
||||||
|
|
||||||
|
/** implements the callback*/
|
||||||
|
virtual void operator()(Node* node, NodeVisitor* nv);
|
||||||
|
|
||||||
|
virtual void apply(MatrixTransform& mt);
|
||||||
|
|
||||||
|
virtual void apply(PositionAttitudeTransform& pat);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ref_ptr<AnimationPath> _animationPath;
|
||||||
|
double _timeOffset;
|
||||||
|
double _timeMultiplier;
|
||||||
|
double _firstTime;
|
||||||
|
mutable double _animationTime;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -28,8 +28,6 @@ class SG_EXPORT MatrixTransform : public Transform
|
|||||||
|
|
||||||
META_Node(osg, MatrixTransform);
|
META_Node(osg, MatrixTransform);
|
||||||
|
|
||||||
virtual void traverse(NodeVisitor& nv);
|
|
||||||
|
|
||||||
/** Set the transform's matrix.*/
|
/** Set the transform's matrix.*/
|
||||||
void setMatrix(const Matrix& mat) { (*_matrix) = mat; _inverseDirty=true; dirtyBound(); }
|
void setMatrix(const Matrix& mat) { (*_matrix) = mat; _inverseDirty=true; dirtyBound(); }
|
||||||
|
|
||||||
@ -53,68 +51,10 @@ class SG_EXPORT MatrixTransform : public Transform
|
|||||||
return *_inverse;
|
return *_inverse;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor*) const
|
virtual bool computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor*) const;
|
||||||
{
|
|
||||||
if (_referenceFrame==RELATIVE_TO_PARENTS)
|
|
||||||
{
|
|
||||||
matrix.preMult(*_matrix);
|
|
||||||
}
|
|
||||||
else // absolute
|
|
||||||
{
|
|
||||||
matrix = *_matrix;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor*) const
|
virtual bool computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor*) const;
|
||||||
{
|
|
||||||
const Matrix& inverse = getInverseMatrix();
|
|
||||||
|
|
||||||
if (_referenceFrame==RELATIVE_TO_PARENTS)
|
|
||||||
{
|
|
||||||
matrix.postMult(inverse);
|
|
||||||
}
|
|
||||||
else // absolute
|
|
||||||
{
|
|
||||||
matrix = inverse;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Set an optional animation path. */
|
|
||||||
void setAnimationPath(AnimationPath* ap) { _animationPath = ap; }
|
|
||||||
|
|
||||||
/** Get a read only version of the AnimationPath object*/
|
|
||||||
AnimationPath* getAnimationPath() { return _animationPath.get(); }
|
|
||||||
|
|
||||||
/** Get a read only version of the AnimationPath object*/
|
|
||||||
const AnimationPath* getAnimationPath() const { return _animationPath.get(); }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Callback which can be attached to a MatrixTransform as an app
|
|
||||||
* callback to allow it to follow the path defined by a AnimationPath.
|
|
||||||
* note, now deprecated by attaching an AnimationPath directly to MatrixTransform.*/
|
|
||||||
class SG_EXPORT AnimationPathCallback : public NodeCallback
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
AnimationPathCallback(AnimationPath* ap,double timeOffset=0.0f,double timeMultiplier=1.0f):
|
|
||||||
_animationPath(ap),
|
|
||||||
_timeOffset(timeOffset),
|
|
||||||
_timeMultiplier(timeMultiplier),
|
|
||||||
_firstTime(0.0) {}
|
|
||||||
|
|
||||||
/** implements the callback*/
|
|
||||||
virtual void operator()(Node* node, NodeVisitor* nv);
|
|
||||||
|
|
||||||
ref_ptr<AnimationPath> _animationPath;
|
|
||||||
double _timeOffset;
|
|
||||||
double _timeMultiplier;
|
|
||||||
double _firstTime;
|
|
||||||
};
|
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
|
|
||||||
@ -123,8 +63,6 @@ class SG_EXPORT MatrixTransform : public Transform
|
|||||||
ref_ptr<Matrix> _matrix;
|
ref_ptr<Matrix> _matrix;
|
||||||
mutable ref_ptr<Matrix> _inverse;
|
mutable ref_ptr<Matrix> _inverse;
|
||||||
mutable bool _inverseDirty;
|
mutable bool _inverseDirty;
|
||||||
|
|
||||||
osg::ref_ptr<AnimationPath> _animationPath;
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#ifndef OSG_NODECALLBACK
|
#ifndef OSG_NODECALLBACK
|
||||||
#define OSG_NODECALLBACK 1
|
#define OSG_NODECALLBACK 1
|
||||||
|
|
||||||
#include <osg/Referenced>
|
#include <osg/Object>
|
||||||
#include <osg/ref_ptr>
|
#include <osg/ref_ptr>
|
||||||
|
|
||||||
namespace osg {
|
namespace osg {
|
||||||
@ -13,13 +13,18 @@ namespace osg {
|
|||||||
class Node;
|
class Node;
|
||||||
class NodeVisitor;
|
class NodeVisitor;
|
||||||
|
|
||||||
class SG_EXPORT NodeCallback : public virtual Referenced {
|
class SG_EXPORT NodeCallback : public virtual Object {
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
|
|
||||||
NodeCallback(){}
|
NodeCallback(){}
|
||||||
virtual ~NodeCallback() {}
|
|
||||||
|
NodeCallback(const NodeCallback&,const CopyOp&):
|
||||||
|
_nestedCallback(_nestedCallback) {}
|
||||||
|
|
||||||
|
|
||||||
|
META_Object(osg,NodeCallback)
|
||||||
|
|
||||||
|
|
||||||
/** Callback method call by the NodeVisitor when visiting a node.*/
|
/** Callback method call by the NodeVisitor when visiting a node.*/
|
||||||
@ -71,6 +76,10 @@ class SG_EXPORT NodeCallback : public virtual Referenced {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
ref_ptr<NodeCallback> _nestedCallback;
|
ref_ptr<NodeCallback> _nestedCallback;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual ~NodeCallback() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -42,7 +42,7 @@ class Sequence;
|
|||||||
myVisitor.apply(*root). The later method will bypass the double
|
myVisitor.apply(*root). The later method will bypass the double
|
||||||
dispatch and the appropriate NodeVisitor::apply(..) method will
|
dispatch and the appropriate NodeVisitor::apply(..) method will
|
||||||
not be called. */
|
not be called. */
|
||||||
class SG_EXPORT NodeVisitor : public Referenced
|
class SG_EXPORT NodeVisitor : public virtual Referenced
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -51,8 +51,7 @@ class SG_EXPORT NodeVisitor : public Referenced
|
|||||||
TRAVERSE_NONE,
|
TRAVERSE_NONE,
|
||||||
TRAVERSE_PARENTS,
|
TRAVERSE_PARENTS,
|
||||||
TRAVERSE_ALL_CHILDREN,
|
TRAVERSE_ALL_CHILDREN,
|
||||||
TRAVERSE_ACTIVE_CHILDREN,
|
TRAVERSE_ACTIVE_CHILDREN
|
||||||
TRAVERSE_VISITOR
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum VisitorType
|
enum VisitorType
|
||||||
@ -137,26 +136,18 @@ class SG_EXPORT NodeVisitor : public Referenced
|
|||||||
NodeVisitor has been attached via setTraverseVisitor()
|
NodeVisitor has been attached via setTraverseVisitor()
|
||||||
and the new mode is not TRAVERSE_VISITOR then the attached
|
and the new mode is not TRAVERSE_VISITOR then the attached
|
||||||
visitor is detached. Default mode is TRAVERSE_NONE.*/
|
visitor is detached. Default mode is TRAVERSE_NONE.*/
|
||||||
void setTraversalMode(TraversalMode mode);
|
inline void setTraversalMode(TraversalMode mode) { _traversalMode = mode; }
|
||||||
|
|
||||||
/** Get the traversal mode.*/
|
/** Get the traversal mode.*/
|
||||||
inline TraversalMode getTraversalMode() const { return _traversalMode; }
|
inline TraversalMode getTraversalMode() const { return _traversalMode; }
|
||||||
|
|
||||||
/** Set a visitor to handle traversal.
|
|
||||||
Overrides the traverse mode setting it to TRAVERSAL_VISITOR.*/
|
|
||||||
void setTraversalVisitor(NodeVisitor* nv);
|
|
||||||
|
|
||||||
/** Get the traversal visitor, returns NULL if none is attached.*/
|
|
||||||
inline NodeVisitor* getTraversalVisitor() { return _traversalVisitor.get(); }
|
|
||||||
|
|
||||||
/** Method for handling traversal of a nodes.
|
/** Method for handling traversal of a nodes.
|
||||||
If you intend to use the visitor for actively traversing
|
If you intend to use the visitor for actively traversing
|
||||||
the scene graph then make sure the accept() methods call
|
the scene graph then make sure the accept() methods call
|
||||||
this method unless they handle traversal directly.*/
|
this method unless they handle traversal directly.*/
|
||||||
inline void traverse(Node& node)
|
inline void traverse(Node& node)
|
||||||
{
|
{
|
||||||
if (_traversalVisitor.valid()) node.accept(*_traversalVisitor);
|
if (_traversalMode==TRAVERSE_PARENTS) node.ascend(*this);
|
||||||
else if (_traversalMode==TRAVERSE_PARENTS) node.ascend(*this);
|
|
||||||
else if (_traversalMode!=TRAVERSE_NONE) node.traverse(*this);
|
else if (_traversalMode!=TRAVERSE_NONE) node.traverse(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,8 +225,6 @@ class SG_EXPORT NodeVisitor : public Referenced
|
|||||||
int _traversalNumber;
|
int _traversalNumber;
|
||||||
|
|
||||||
ref_ptr<FrameStamp> _frameStamp;
|
ref_ptr<FrameStamp> _frameStamp;
|
||||||
|
|
||||||
ref_ptr<NodeVisitor> _traversalVisitor;
|
|
||||||
|
|
||||||
TraversalMode _traversalMode;
|
TraversalMode _traversalMode;
|
||||||
Node::NodeMask _traversalMask;
|
Node::NodeMask _traversalMask;
|
||||||
|
@ -30,19 +30,19 @@ class SG_EXPORT PositionAttitudeTransform : public Transform
|
|||||||
META_Node(osg, PositionAttitudeTransform);
|
META_Node(osg, PositionAttitudeTransform);
|
||||||
|
|
||||||
|
|
||||||
void setPosition(const Vec3& pos) { _position = pos; dirtyBound(); }
|
inline void setPosition(const Vec3& pos) { _position = pos; dirtyBound(); }
|
||||||
|
|
||||||
const Vec3& getPosition() const { return _position; }
|
inline const Vec3& getPosition() const { return _position; }
|
||||||
|
|
||||||
|
|
||||||
void setAttitude(const Quat& quat) { _attitude = quat; dirtyBound(); }
|
inline void setAttitude(const Quat& quat) { _attitude = quat; dirtyBound(); }
|
||||||
|
|
||||||
const Quat& getAttitude() const { return _attitude; }
|
inline const Quat& getAttitude() const { return _attitude; }
|
||||||
|
|
||||||
|
|
||||||
void setPivotPoint(const Vec3& pivot) { _pivotPoint = pivot; dirtyBound(); }
|
inline void setPivotPoint(const Vec3& pivot) { _pivotPoint = pivot; dirtyBound(); }
|
||||||
|
|
||||||
const Vec3& getPivotPoint() const { return _pivotPoint; }
|
inline const Vec3& getPivotPoint() const { return _pivotPoint; }
|
||||||
|
|
||||||
|
|
||||||
virtual bool computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor* nv) const;
|
virtual bool computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor* nv) const;
|
||||||
@ -50,28 +50,6 @@ class SG_EXPORT PositionAttitudeTransform : public Transform
|
|||||||
virtual bool computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor* nv) const;
|
virtual bool computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor* nv) const;
|
||||||
|
|
||||||
|
|
||||||
/** Callback which can be attached to a PositionAttitudeTransform
|
|
||||||
* as an app callback to allow it to follow the path defined by a
|
|
||||||
* AnimationPath.*/
|
|
||||||
class SG_EXPORT AnimationPathCallback : public virtual NodeCallback
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
AnimationPathCallback(AnimationPath* ap,double timeOffset=0.0f,double timeMultiplier=1.0f):
|
|
||||||
_animationPath(ap),
|
|
||||||
_timeOffset(timeOffset),
|
|
||||||
_timeMultiplier(timeMultiplier),
|
|
||||||
_firstTime(0.0) {}
|
|
||||||
|
|
||||||
/** implements the callback*/
|
|
||||||
virtual void operator()(Node* node, NodeVisitor* nv);
|
|
||||||
|
|
||||||
ref_ptr<AnimationPath> _animationPath;
|
|
||||||
double _timeOffset;
|
|
||||||
double _timeMultiplier;
|
|
||||||
double _firstTime;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ osg::Node* createMovingModel(const osg::Vec3& center, float radius)
|
|||||||
positioned->addChild(glider);
|
positioned->addChild(glider);
|
||||||
|
|
||||||
osg::PositionAttitudeTransform* xform = new osg::PositionAttitudeTransform;
|
osg::PositionAttitudeTransform* xform = new osg::PositionAttitudeTransform;
|
||||||
xform->setUpdateCallback(new osg::PositionAttitudeTransform::AnimationPathCallback(animationPath,0.0,1.0));
|
xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0,1.0));
|
||||||
xform->addChild(positioned);
|
xform->addChild(positioned);
|
||||||
|
|
||||||
model->addChild(xform);
|
model->addChild(xform);
|
||||||
@ -164,7 +164,7 @@ osg::Node* createMovingModel(const osg::Vec3& center, float radius)
|
|||||||
positioned->addChild(cessna);
|
positioned->addChild(cessna);
|
||||||
|
|
||||||
osg::MatrixTransform* xform = new osg::MatrixTransform;
|
osg::MatrixTransform* xform = new osg::MatrixTransform;
|
||||||
xform->setUpdateCallback(new osg::MatrixTransform::AnimationPathCallback(animationPath,0.0f,2.0));
|
xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0f,2.0));
|
||||||
xform->addChild(positioned);
|
xform->addChild(positioned);
|
||||||
|
|
||||||
model->addChild(xform);
|
model->addChild(xform);
|
||||||
|
@ -124,7 +124,7 @@ osg::Node* createLights(osg::BoundingBox& bb,osg::StateSet* rootStateSet)
|
|||||||
animationPath->insert(8.0,osg::AnimationPath::ControlPoint(bb.corner(0)));
|
animationPath->insert(8.0,osg::AnimationPath::ControlPoint(bb.corner(0)));
|
||||||
animationPath->setLoopMode(osg::AnimationPath::SWING);
|
animationPath->setLoopMode(osg::AnimationPath::SWING);
|
||||||
|
|
||||||
mt->setUpdateCallback(new osg::MatrixTransform::AnimationPathCallback(animationPath));
|
mt->setUpdateCallback(new osg::AnimationPathCallback(animationPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
// create marker for point light.
|
// create marker for point light.
|
||||||
|
@ -248,7 +248,7 @@ class MyGeometryCallback :
|
|||||||
osg::Vec3* end = begin+count;
|
osg::Vec3* end = begin+count;
|
||||||
for (osg::Vec3* itr=begin;itr<end;++itr)
|
for (osg::Vec3* itr=begin;itr<end;++itr)
|
||||||
{
|
{
|
||||||
osg::Vec3 dv(*itr-_origin);
|
osg::Vepc3 dv(*itr-_origin);
|
||||||
osg::Vec3 local(dv*_xAxis,dv*_yAxis,dv*_zAxis);
|
osg::Vec3 local(dv*_xAxis,dv*_yAxis,dv*_zAxis);
|
||||||
|
|
||||||
local.z() = local.x()*_amplitude*
|
local.z() = local.x()*_amplitude*
|
||||||
|
@ -138,7 +138,7 @@ osg::Node* createMovingModel(const osg::Vec3& center, float radius)
|
|||||||
positioned->addChild(cessna);
|
positioned->addChild(cessna);
|
||||||
|
|
||||||
osg::MatrixTransform* xform = new osg::MatrixTransform;
|
osg::MatrixTransform* xform = new osg::MatrixTransform;
|
||||||
xform->setUpdateCallback(new osg::MatrixTransform::AnimationPathCallback(animationPath,0.0f,2.0));
|
xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0f,2.0));
|
||||||
xform->addChild(positioned);
|
xform->addChild(positioned);
|
||||||
|
|
||||||
model->addChild(xform);
|
model->addChild(xform);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <osg/AnimationPath>
|
#include <osg/AnimationPath>
|
||||||
#include <osg/NodeVisitor>
|
#include <osg/MatrixTransform>
|
||||||
|
#include <osg/PositionAttitudeTransform>
|
||||||
|
|
||||||
using namespace osg;
|
using namespace osg;
|
||||||
|
|
||||||
@ -67,3 +68,43 @@ bool AnimationPath::getInterpolatedControlPoint(double time,ControlPoint& contro
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AnimationPathCallback::operator()(Node* node, NodeVisitor* nv)
|
||||||
|
{
|
||||||
|
if (_animationPath.valid() &&
|
||||||
|
nv->getVisitorType()==NodeVisitor::UPDATE_VISITOR &&
|
||||||
|
nv->getFrameStamp())
|
||||||
|
{
|
||||||
|
double time = nv->getFrameStamp()->getReferenceTime();
|
||||||
|
if (_firstTime==0.0) _firstTime = time;
|
||||||
|
|
||||||
|
_animationTime = ((time-_firstTime)-_timeOffset)*_timeMultiplier;
|
||||||
|
|
||||||
|
node->accept(*this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// must call any nested node callbacks and continue subgraph traversal.
|
||||||
|
NodeCallback::traverse(node,nv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimationPathCallback::apply(MatrixTransform& mt)
|
||||||
|
{
|
||||||
|
Matrix matrix;
|
||||||
|
if (_animationPath->getMatrix(_animationTime,matrix))
|
||||||
|
{
|
||||||
|
mt.setMatrix(matrix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AnimationPathCallback::apply(PositionAttitudeTransform& pat)
|
||||||
|
{
|
||||||
|
AnimationPath::ControlPoint cp;
|
||||||
|
if (_animationPath->getInterpolatedControlPoint(_animationTime,cp))
|
||||||
|
{
|
||||||
|
pat.setPosition(cp._position);
|
||||||
|
pat.setAttitude(cp._rotation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -13,10 +13,8 @@ MatrixTransform::MatrixTransform(const MatrixTransform& transform,const CopyOp&
|
|||||||
Transform(transform,copyop),
|
Transform(transform,copyop),
|
||||||
_matrix(new Matrix(*transform._matrix)),
|
_matrix(new Matrix(*transform._matrix)),
|
||||||
_inverse(new Matrix(*transform._inverse)),
|
_inverse(new Matrix(*transform._inverse)),
|
||||||
_inverseDirty(transform._inverseDirty),
|
_inverseDirty(transform._inverseDirty)
|
||||||
_animationPath(dynamic_cast<AnimationPath*>(copyop(transform._animationPath.get())))
|
|
||||||
{
|
{
|
||||||
if (_animationPath.valid()) setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MatrixTransform::MatrixTransform(const Matrix& mat )
|
MatrixTransform::MatrixTransform(const Matrix& mat )
|
||||||
@ -33,38 +31,30 @@ MatrixTransform::~MatrixTransform()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MatrixTransform::computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor*) const
|
||||||
void MatrixTransform::traverse(NodeVisitor& nv)
|
|
||||||
{
|
{
|
||||||
// if app traversal update the frame count.
|
if (_referenceFrame==RELATIVE_TO_PARENTS)
|
||||||
if (_animationPath.valid() &&
|
|
||||||
nv.getVisitorType()==NodeVisitor::UPDATE_VISITOR &&
|
|
||||||
nv.getFrameStamp())
|
|
||||||
{
|
{
|
||||||
double time = nv.getFrameStamp()->getReferenceTime();
|
matrix.preMult(*_matrix);
|
||||||
_animationPath->getMatrix(time,*_matrix);
|
|
||||||
}
|
}
|
||||||
|
else // absolute
|
||||||
// must call any nested node callbacks and continue subgraph traversal.
|
{
|
||||||
Transform::traverse(nv);
|
matrix = *_matrix;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatrixTransform::AnimationPathCallback::operator()(Node* node, NodeVisitor* nv)
|
bool MatrixTransform::computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor*) const
|
||||||
{
|
{
|
||||||
MatrixTransform* mt = dynamic_cast<MatrixTransform*>(node);
|
const Matrix& inverse = getInverseMatrix();
|
||||||
if (mt &&
|
|
||||||
_animationPath.valid() &&
|
if (_referenceFrame==RELATIVE_TO_PARENTS)
|
||||||
nv->getVisitorType()==NodeVisitor::UPDATE_VISITOR &&
|
|
||||||
nv->getFrameStamp())
|
|
||||||
{
|
{
|
||||||
double time = nv->getFrameStamp()->getReferenceTime();
|
matrix.postMult(inverse);
|
||||||
if (_firstTime==0.0) _firstTime = time;
|
|
||||||
Matrix matrix;
|
|
||||||
if (_animationPath->getMatrix(((time-_firstTime)-_timeOffset)*_timeMultiplier,matrix))
|
|
||||||
{
|
|
||||||
mt->setMatrix(matrix);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// must call any nested node callbacks and continue subgraph traversal.
|
else // absolute
|
||||||
traverse(node,nv);
|
{
|
||||||
|
matrix = inverse;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ NodeVisitor::NodeVisitor(TraversalMode tm)
|
|||||||
_visitorType = NODE_VISITOR;
|
_visitorType = NODE_VISITOR;
|
||||||
_traversalNumber = -1;
|
_traversalNumber = -1;
|
||||||
|
|
||||||
_traversalVisitor = NULL;
|
|
||||||
_traversalMode = tm;
|
_traversalMode = tm;
|
||||||
_traversalMask = 0xffffffff;
|
_traversalMask = 0xffffffff;
|
||||||
_nodeMaskOverride = 0x0;
|
_nodeMaskOverride = 0x0;
|
||||||
@ -20,7 +19,6 @@ NodeVisitor::NodeVisitor(VisitorType type,TraversalMode tm)
|
|||||||
_visitorType = type;
|
_visitorType = type;
|
||||||
_traversalNumber = -1;
|
_traversalNumber = -1;
|
||||||
|
|
||||||
_traversalVisitor = NULL;
|
|
||||||
_traversalMode = tm;
|
_traversalMode = tm;
|
||||||
_traversalMask = 0xffffffff;
|
_traversalMask = 0xffffffff;
|
||||||
_nodeMaskOverride = 0x0;
|
_nodeMaskOverride = 0x0;
|
||||||
@ -32,32 +30,6 @@ NodeVisitor::~NodeVisitor()
|
|||||||
// if (_traversalVisitor) detach from _traversalVisitor;
|
// if (_traversalVisitor) detach from _traversalVisitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void NodeVisitor::setTraversalMode(TraversalMode mode)
|
|
||||||
{
|
|
||||||
if (_traversalMode==mode) return;
|
|
||||||
if (mode==TRAVERSE_VISITOR)
|
|
||||||
{
|
|
||||||
if (_traversalVisitor==NULL) _traversalMode = TRAVERSE_NONE;
|
|
||||||
else _traversalMode = TRAVERSE_VISITOR;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (_traversalVisitor.valid()) _traversalVisitor=NULL;
|
|
||||||
_traversalMode = mode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void NodeVisitor::setTraversalVisitor(NodeVisitor* nv)
|
|
||||||
{
|
|
||||||
if (_traversalVisitor==nv) return;
|
|
||||||
_traversalVisitor = nv;
|
|
||||||
if (_traversalVisitor.valid()) _traversalMode = TRAVERSE_VISITOR;
|
|
||||||
else _traversalMode = TRAVERSE_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class TransformVisitor : public NodeVisitor
|
class TransformVisitor : public NodeVisitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -40,24 +40,3 @@ bool PositionAttitudeTransform::computeWorldToLocalMatrix(Matrix& matrix,NodeVis
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PositionAttitudeTransform::AnimationPathCallback::operator()(Node* node, NodeVisitor* nv)
|
|
||||||
{
|
|
||||||
PositionAttitudeTransform* pat = dynamic_cast<PositionAttitudeTransform*>(node);
|
|
||||||
if (pat &&
|
|
||||||
_animationPath.valid() &&
|
|
||||||
nv->getVisitorType()==NodeVisitor::UPDATE_VISITOR &&
|
|
||||||
nv->getFrameStamp())
|
|
||||||
{
|
|
||||||
double time = nv->getFrameStamp()->getReferenceTime();
|
|
||||||
if (_firstTime==0.0) _firstTime = time;
|
|
||||||
AnimationPath::ControlPoint cp;
|
|
||||||
if (_animationPath->getInterpolatedControlPoint(((time-_firstTime)-_timeOffset)*_timeMultiplier,cp))
|
|
||||||
{
|
|
||||||
pat->setPosition(cp._position);
|
|
||||||
pat->setAttitude(cp._rotation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// must call any nested node callbacks and continue subgraph traversal.
|
|
||||||
traverse(node,nv);
|
|
||||||
}
|
|
||||||
|
@ -24,6 +24,8 @@ FltFile::FltFile(
|
|||||||
TexturePool* pTexturePool,
|
TexturePool* pTexturePool,
|
||||||
MaterialPool* pMaterialPool)
|
MaterialPool* pMaterialPool)
|
||||||
{
|
{
|
||||||
|
_useTextureAlphaForTransparancyBinning = true;
|
||||||
|
|
||||||
if (pColorPool)
|
if (pColorPool)
|
||||||
{
|
{
|
||||||
// use external color palette, ignore internal
|
// use external color palette, ignore internal
|
||||||
@ -91,6 +93,7 @@ osg::Node* FltFile::readNode(const std::string& fileName)
|
|||||||
osg::Group* FltFile::convert()
|
osg::Group* FltFile::convert()
|
||||||
{
|
{
|
||||||
ConvertFromFLT visit;
|
ConvertFromFLT visit;
|
||||||
|
visit.setUseTextureAlphaForTransparancyBinning(getUseTextureAlphaForTransparancyBinning());
|
||||||
return visit.convert(getHeaderRecord());
|
return visit.convert(getHeaderRecord());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +44,9 @@ class FltFile : public osg::Referenced
|
|||||||
inline const bool useInternalTexturePalette() const { return _useInternalTexturePalette; }
|
inline const bool useInternalTexturePalette() const { return _useInternalTexturePalette; }
|
||||||
inline const bool useInternalMaterialPalette() const { return _useInternalMaterialPalette; }
|
inline const bool useInternalMaterialPalette() const { return _useInternalMaterialPalette; }
|
||||||
|
|
||||||
|
void setUseTextureAlphaForTransparancyBinning(bool flag) { _useTextureAlphaForTransparancyBinning=flag; }
|
||||||
|
bool getUseTextureAlphaForTransparancyBinning() const { return _useTextureAlphaForTransparancyBinning; }
|
||||||
|
|
||||||
int getFlightVersion() const;
|
int getFlightVersion() const;
|
||||||
inline HeaderRecord* getHeaderRecord() { return _headerRecord.get(); }
|
inline HeaderRecord* getHeaderRecord() { return _headerRecord.get(); }
|
||||||
|
|
||||||
@ -61,6 +64,7 @@ class FltFile : public osg::Referenced
|
|||||||
bool _useInternalColorPalette;
|
bool _useInternalColorPalette;
|
||||||
bool _useInternalTexturePalette;
|
bool _useInternalTexturePalette;
|
||||||
bool _useInternalMaterialPalette;
|
bool _useInternalMaterialPalette;
|
||||||
|
bool _useTextureAlphaForTransparancyBinning;
|
||||||
|
|
||||||
std::string _directory;
|
std::string _directory;
|
||||||
|
|
||||||
|
@ -20,14 +20,19 @@ osgDB::ReaderWriter::ReadResult ReaderWriterFLT::readObject(const std::string& f
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
osgDB::ReaderWriter::ReadResult ReaderWriterFLT::readNode(const std::string& fileName, const osgDB::ReaderWriter::Options*)
|
osgDB::ReaderWriter::ReadResult ReaderWriterFLT::readNode(const std::string& fileName, const osgDB::ReaderWriter::Options* options)
|
||||||
{
|
{
|
||||||
if( !acceptsExtension(osgDB::getFileExtension(fileName) ))
|
if( !acceptsExtension(osgDB::getFileExtension(fileName) ))
|
||||||
return ReadResult::FILE_NOT_HANDLED;
|
return ReadResult::FILE_NOT_HANDLED;
|
||||||
|
|
||||||
osg::ref_ptr<FltFile> read = new FltFile;
|
osg::ref_ptr<FltFile> read = new FltFile;
|
||||||
|
|
||||||
|
if (options)
|
||||||
|
{
|
||||||
|
read->setUseTextureAlphaForTransparancyBinning(options->getOptionString().find("noTextureAlphaForTransparancyBinning")!=std::string::npos);
|
||||||
|
}
|
||||||
|
|
||||||
osg::Node* node = read.get()->readNode(fileName);
|
osg::Node* node = read->readNode(fileName);
|
||||||
if (node) return node;
|
if (node) return node;
|
||||||
else return ReadResult::FILE_NOT_HANDLED;
|
else return ReadResult::FILE_NOT_HANDLED;
|
||||||
}
|
}
|
||||||
|
@ -77,6 +77,7 @@ ConvertFromFLT::ConvertFromFLT() :
|
|||||||
_wObjTransparency = 0;
|
_wObjTransparency = 0;
|
||||||
_nSubfaceLevel = 0;
|
_nSubfaceLevel = 0;
|
||||||
_unitScale = 1.0;
|
_unitScale = 1.0;
|
||||||
|
_useTextureAlphaForTranspancyBinning = true;
|
||||||
_bHdrRgbMode = false;
|
_bHdrRgbMode = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1180,7 +1181,7 @@ void ConvertFromFLT::setTexture ( FaceRecord *rec, SFace *pSFace, osg::StateSet
|
|||||||
if (osgTexture)
|
if (osgTexture)
|
||||||
{
|
{
|
||||||
osg::Image* osgImage = osgTexture->getImage();
|
osg::Image* osgImage = osgTexture->getImage();
|
||||||
if (osgImage->isImageTranslucent()) bBlend = true;
|
if (getUseTextureAlphaForTransparancyBinning() && osgImage->isImageTranslucent()) bBlend = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,6 +153,10 @@ class ConvertFromFLT
|
|||||||
int visitVertexList(GeoSetBuilder* pParent, VertexListRecord* rec);
|
int visitVertexList(GeoSetBuilder* pParent, VertexListRecord* rec);
|
||||||
int visitLocalVertexPool(GeoSetBuilder* pBuilder, LocalVertexPoolRecord* rec);
|
int visitLocalVertexPool(GeoSetBuilder* pBuilder, LocalVertexPoolRecord* rec);
|
||||||
|
|
||||||
|
|
||||||
|
void setUseTextureAlphaForTransparancyBinning(bool flag) { _useTextureAlphaForTranspancyBinning=flag; }
|
||||||
|
bool getUseTextureAlphaForTransparancyBinning() const { return _useTextureAlphaForTranspancyBinning; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
int addMeshPrimitives ( osg::Group &osgParent, GeoSetBuilder *pBuilder, MeshRecord *rec );
|
int addMeshPrimitives ( osg::Group &osgParent, GeoSetBuilder *pBuilder, MeshRecord *rec );
|
||||||
@ -188,6 +192,7 @@ class ConvertFromFLT
|
|||||||
double _unitScale;
|
double _unitScale;
|
||||||
bool _bHdrRgbMode;
|
bool _bHdrRgbMode;
|
||||||
osg::Vec4 _faceColor;
|
osg::Vec4 _faceColor;
|
||||||
|
bool _useTextureAlphaForTranspancyBinning;
|
||||||
|
|
||||||
osg::Group* _osgParent;
|
osg::Group* _osgParent;
|
||||||
};
|
};
|
||||||
|
@ -61,85 +61,45 @@ bool AnimationPath_readLocalData(osg::Object &obj, osgDB::Input &fr)
|
|||||||
|
|
||||||
if (fr.matchSequence("ControlPoints {"))
|
if (fr.matchSequence("ControlPoints {"))
|
||||||
{
|
{
|
||||||
int entry = fr[1].getNoNestedBrackets();
|
int entry = fr[0].getNoNestedBrackets();
|
||||||
|
|
||||||
fr += 2;
|
fr += 2;
|
||||||
|
|
||||||
float fTime = -1;
|
|
||||||
|
|
||||||
osg::AnimationPath::ControlPoint CtrlPoint;
|
|
||||||
bool bPosParsed = false;
|
|
||||||
bool bRotParsed = false;
|
|
||||||
bool bScaleParsed = false;
|
|
||||||
|
|
||||||
|
float time;
|
||||||
|
Vec3 position,scale;
|
||||||
|
Quat rotation;
|
||||||
|
|
||||||
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
||||||
{
|
{
|
||||||
bool handled=false;
|
if (fr[0].getFloat(time) &&
|
||||||
|
fr[1].getFloat(position[0]) &&
|
||||||
if (fr[0].matchWord("Time") &&
|
fr[2].getFloat(position[1]) &&
|
||||||
fr[1].isFloat())
|
fr[3].getFloat(position[2]) &&
|
||||||
|
fr[4].getFloat(rotation[0]) &&
|
||||||
|
fr[5].getFloat(rotation[1]) &&
|
||||||
|
fr[6].getFloat(rotation[2]) &&
|
||||||
|
fr[7].getFloat(rotation[3]) &&
|
||||||
|
fr[8].getFloat(scale[0]) &&
|
||||||
|
fr[9].getFloat(scale[1]) &&
|
||||||
|
fr[10].getFloat(scale[2]))
|
||||||
{
|
{
|
||||||
if (bPosParsed || bRotParsed || bScaleParsed)
|
|
||||||
{
|
|
||||||
ap->insert(fTime, CtrlPoint);
|
|
||||||
|
|
||||||
bPosParsed = false;
|
|
||||||
bRotParsed = false;
|
|
||||||
bScaleParsed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fr[1].getFloat(fTime);
|
|
||||||
fr+=2;
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec3 vec3;
|
osg::AnimationPath::ControlPoint ctrlPoint;
|
||||||
if (fr[0].matchWord("Position") &&
|
ctrlPoint._position = position;
|
||||||
fr[1].getFloat(vec3[0]) &&
|
ctrlPoint._rotation = rotation;
|
||||||
fr[2].getFloat(vec3[1]) &&
|
ctrlPoint._scale = scale;
|
||||||
fr[3].getFloat(vec3[2]))
|
|
||||||
{
|
ap->insert(time, ctrlPoint);
|
||||||
CtrlPoint._position = vec3;
|
|
||||||
fr+=4;
|
fr+=11;
|
||||||
bPosParsed = true;
|
|
||||||
handled = true;
|
|
||||||
}
|
}
|
||||||
|
else fr.advanceOverCurrentFieldOrBlock();
|
||||||
|
|
||||||
Vec4 vec4;
|
|
||||||
if (fr[0].matchWord("Rotation") &&
|
|
||||||
fr[1].getFloat(vec4[0]) &&
|
|
||||||
fr[2].getFloat(vec4[1]) &&
|
|
||||||
fr[3].getFloat(vec4[2]) &&
|
|
||||||
fr[4].getFloat(vec4[3]))
|
|
||||||
{
|
|
||||||
CtrlPoint._rotation.makeRotate(vec4[0], vec4[1], vec4[2], vec4[3]);
|
|
||||||
fr+=5;
|
|
||||||
bRotParsed = true;
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (fr[0].matchWord("Scale") &&
|
|
||||||
fr[1].getFloat(vec3[0]) &&
|
|
||||||
fr[2].getFloat(vec3[1]) &&
|
|
||||||
fr[3].getFloat(vec3[2]))
|
|
||||||
{
|
|
||||||
CtrlPoint._scale = vec3;
|
|
||||||
fr+=4;
|
|
||||||
bScaleParsed = true;
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!handled) fr.advanceOverCurrentFieldOrBlock();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If all values have been parsed in
|
itAdvanced = true;
|
||||||
if (bPosParsed && bRotParsed && bScaleParsed)
|
|
||||||
{
|
|
||||||
ap->insert(fTime, CtrlPoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,43 +131,11 @@ bool AnimationPath_writeLocalData(const osg::Object &obj, osgDB::Output &fw)
|
|||||||
fw.indent() << "ControlPoints {"<< std::endl;
|
fw.indent() << "ControlPoints {"<< std::endl;
|
||||||
fw.moveIn();
|
fw.moveIn();
|
||||||
|
|
||||||
bool bPosSet = false;
|
for (AnimationPath::TimeControlPointMap::const_iterator itr=tcpm.begin();
|
||||||
bool bRotSet = false;
|
|
||||||
bool bScaleSet = false;
|
|
||||||
AnimationPath::TimeControlPointMap::const_iterator itr;
|
|
||||||
for (itr=tcpm.begin();
|
|
||||||
itr!=tcpm.end();
|
itr!=tcpm.end();
|
||||||
++itr)
|
++itr)
|
||||||
{
|
{
|
||||||
if (itr->second._position != Vec3(0,0,0))
|
fw.indent() << itr->first << " " << itr->second._position << " " << itr->second._rotation << " " << itr->second._scale << std::endl;
|
||||||
bPosSet = true;
|
|
||||||
if (itr->second._rotation.asVec4() != Vec4(0,0,0,1))
|
|
||||||
bRotSet = true;
|
|
||||||
if (itr->second._scale != Vec3(1,1,1))
|
|
||||||
bScaleSet = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (itr=tcpm.begin();
|
|
||||||
itr!=tcpm.end();
|
|
||||||
++itr)
|
|
||||||
{
|
|
||||||
Vec4 Rot;
|
|
||||||
|
|
||||||
fw.indent() << "Time " << itr->first;
|
|
||||||
|
|
||||||
if (bPosSet)
|
|
||||||
fw << " Position " << itr->second._position;
|
|
||||||
|
|
||||||
if (bRotSet)
|
|
||||||
{
|
|
||||||
itr->second._rotation.getRotate (Rot[0], Rot[1], Rot[2], Rot[3]);
|
|
||||||
fw << " Rotation " << Rot;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bScaleSet)
|
|
||||||
fw << " Scale " << itr->second._scale;
|
|
||||||
|
|
||||||
fw << std::endl;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,3 +144,51 @@ bool AnimationPath_writeLocalData(const osg::Object &obj, osgDB::Output &fw)
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// forward declare functions to use later.
|
||||||
|
bool AnimationPathCallback_readLocalData(osg::Object &obj, osgDB::Input &fr);
|
||||||
|
bool AnimationPathCallback_writeLocalData(const osg::Object &obj, osgDB::Output &fw);
|
||||||
|
|
||||||
|
|
||||||
|
// register the read and write functions with the osgDB::Registry.
|
||||||
|
osgDB::RegisterDotOsgWrapperProxy AnimationPathCallback_Proxy
|
||||||
|
(
|
||||||
|
new osg::AnimationPathCallback,
|
||||||
|
"AnimationPathCallback",
|
||||||
|
"Object AnimationPathCallback",
|
||||||
|
AnimationPathCallback_readLocalData,
|
||||||
|
AnimationPathCallback_writeLocalData,
|
||||||
|
DotOsgWrapper::READ_AND_WRITE
|
||||||
|
);
|
||||||
|
|
||||||
|
bool AnimationPathCallback_readLocalData(osg::Object &obj, osgDB::Input &fr)
|
||||||
|
{
|
||||||
|
osg::AnimationPathCallback *apc = dynamic_cast<osg::AnimationPathCallback*>(&obj);
|
||||||
|
if (!apc) return false;
|
||||||
|
|
||||||
|
static osg::ref_ptr<osg::AnimationPath> s_path = new osg::AnimationPath;
|
||||||
|
ref_ptr<osg::Object> object = fr.readObjectOfType(*s_path);
|
||||||
|
osg::AnimationPath* animpath = dynamic_cast<osg::AnimationPath*>(object.get());
|
||||||
|
if (animpath) apc->setAnimationPath(animpath);
|
||||||
|
|
||||||
|
bool itrAdvanced = object.valid();
|
||||||
|
|
||||||
|
return itrAdvanced;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool AnimationPathCallback_writeLocalData(const osg::Object &obj, osgDB::Output &fw)
|
||||||
|
{
|
||||||
|
const osg::AnimationPathCallback* apc = dynamic_cast<const osg::AnimationPathCallback*>(&obj);
|
||||||
|
if (!apc) return false;
|
||||||
|
|
||||||
|
if (apc->getAnimationPath())
|
||||||
|
{
|
||||||
|
fw.writeObject(*(apc->getAnimationPath()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#include "osg/MatrixTransform"
|
#include <osg/MatrixTransform>
|
||||||
|
|
||||||
#include "osgDB/Registry"
|
#include <osgDB/Registry>
|
||||||
#include "osgDB/Input"
|
#include <osgDB/Input>
|
||||||
#include "osgDB/Output"
|
#include <osgDB/Output>
|
||||||
|
|
||||||
using namespace osg;
|
using namespace osg;
|
||||||
using namespace osgDB;
|
using namespace osgDB;
|
||||||
@ -68,22 +68,6 @@ bool MatrixTransform_readLocalData(Object& obj, Input& fr)
|
|||||||
iteratorAdvanced = true;
|
iteratorAdvanced = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fr[0].matchWord("AnimationPath"))
|
|
||||||
{
|
|
||||||
static osg::ref_ptr<osg::AnimationPath> prototype = new osg::AnimationPath;
|
|
||||||
osg::ref_ptr<osg::Object> object = fr.readObjectOfType(*prototype);
|
|
||||||
osg::AnimationPath* path = dynamic_cast<osg::AnimationPath*>(object.get());
|
|
||||||
if (path)
|
|
||||||
{
|
|
||||||
transform.setAnimationPath(path);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
osg::Node* node = dynamic_cast<osg::Node*>(object.get());
|
|
||||||
if (node) transform.addChild(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return iteratorAdvanced;
|
return iteratorAdvanced;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,10 +78,5 @@ bool MatrixTransform_writeLocalData(const Object& obj, Output& fw)
|
|||||||
|
|
||||||
fw.writeObject(transform.getMatrix());
|
fw.writeObject(transform.getMatrix());
|
||||||
|
|
||||||
if (transform.getAnimationPath())
|
|
||||||
{
|
|
||||||
fw.writeObject(*transform.getAnimationPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -95,6 +95,37 @@ bool Node_readLocalData(Object& obj, Input& fr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ref_ptr<NodeCallback> s_nodecallback = new osg::NodeCallback;
|
||||||
|
while (fr.matchSequence("UpdateCallback {"))
|
||||||
|
{
|
||||||
|
int entry = fr[0].getNoNestedBrackets();
|
||||||
|
fr += 2;
|
||||||
|
|
||||||
|
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
||||||
|
{
|
||||||
|
NodeCallback* nodecallback = dynamic_cast<NodeCallback*>(fr.readObjectOfType(*s_nodecallback));
|
||||||
|
if (nodecallback) node.setUpdateCallback(nodecallback);
|
||||||
|
else ++fr;
|
||||||
|
}
|
||||||
|
iteratorAdvanced = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
while (fr.matchSequence("CullCallback {"))
|
||||||
|
{
|
||||||
|
int entry = fr[0].getNoNestedBrackets();
|
||||||
|
fr += 2;
|
||||||
|
|
||||||
|
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
||||||
|
{
|
||||||
|
NodeCallback* nodecallback = dynamic_cast<NodeCallback*>(fr.readObjectOfType(*s_nodecallback));
|
||||||
|
if (nodecallback) node.setUpdateCallback(nodecallback);
|
||||||
|
else ++fr;
|
||||||
|
}
|
||||||
|
iteratorAdvanced = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return iteratorAdvanced;
|
return iteratorAdvanced;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,6 +178,24 @@ bool Node_writeLocalData(const Object& obj, Output& fw)
|
|||||||
{
|
{
|
||||||
fw.writeObject(*node.getStateSet());
|
fw.writeObject(*node.getStateSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (node.getUpdateCallback())
|
||||||
|
{
|
||||||
|
fw.indent() << "UpdateCallbacks {" << std::endl;
|
||||||
|
fw.moveIn();
|
||||||
|
fw.writeObject(*node.getUpdateCallback());
|
||||||
|
fw.moveOut();
|
||||||
|
fw.indent() << "}" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.getCullCallback())
|
||||||
|
{
|
||||||
|
fw.indent() << "CullCallbacks {" << std::endl;
|
||||||
|
fw.moveIn();
|
||||||
|
fw.writeObject(*node.getCullCallback());
|
||||||
|
fw.moveOut();
|
||||||
|
fw.indent() << "}" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user