OpenSceneGraph/include/osg/Sequence

261 lines
8.2 KiB
Plaintext
Raw Normal View History

/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#ifndef OSG_SEQUENCE
#define OSG_SEQUENCE 1
#include <osg/Group>
namespace osg
{
/** Sequence is a Group node which allows automatic, time based
switching between children.
*/
class OSG_EXPORT Sequence : public Group
{
public :
Sequence();
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
Sequence(const Sequence&, const CopyOp& copyop=CopyOp::SHALLOW_COPY);
META_Node(osg, Sequence);
virtual void traverse(NodeVisitor& nv);
// the relationship between the _frameTime vector and the _children
// vector is a bit of a mess. This is how it was in previous versions,
// and there's no way out of it if upward compatibility needs to be
// maintained. New code should set defaultTime and use addChild, and
// not mess with the setTime method
Introduced CMake option OSG_PROVIDE_READFILE option that defaults to ON, but when switched to OFF disables the building of the osgDB::read*File() methods, forcing users to use osgDB::readRef*File() methods. The later is preferable as it closes a potential threading bug when using paging databases in conjunction with the osgDB::Registry Object Cache. This threading bug occurs when one thread gets an object from the Cache via an osgDB::read*File() call where only a pointer to the object is passed back, so taking a reference to the object is delayed till it gets reassigned to a ref_ptr<>, but at the same time another thread calls a flush of the Object Cache deleting this object as it's referenceCount is now zero. Using osgDB::readREf*File() makes sure the a ref_ptr<> is passed back and the referenceCount never goes to zero. To ensure the OSG builds when OSG_PROVIDE_READFILE is to OFF the many cases of osgDB::read*File() usage had to be replaced with a ref_ptr<> osgDB::readRef*File() usage. The avoid this change causing lots of other client code to be rewritten to handle the use of ref_ptr<> in place of C pointer I introduced a serious of templte methods in various class to adapt ref_ptr<> to the underly C pointer to be passed to old OSG API's, example of this is found in include/osg/Group: bool addChild(Node* child); // old method which can only be used with a Node* tempalte<class T> bool addChild(const osg::ref_ptr<T>& child) { return addChild(child.get()); } // adapter template method These changes together cover 149 modified files, so it's a large submission. This extent of changes are warrent to make use of the Object Cache and multi-threaded loaded more robust. git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/branches/OpenSceneGraph-3.4@15165 16af8721-9629-0410-8352-f15c8da7e697
2015-10-22 22:14:53 +08:00
using osg::Group::addChild;
using osg::Group::insertChild;
using osg::Group::removeChild;
virtual bool addChild( Node *child);
virtual bool addChild( Node *child, double t);
Introduced CMake option OSG_PROVIDE_READFILE option that defaults to ON, but when switched to OFF disables the building of the osgDB::read*File() methods, forcing users to use osgDB::readRef*File() methods. The later is preferable as it closes a potential threading bug when using paging databases in conjunction with the osgDB::Registry Object Cache. This threading bug occurs when one thread gets an object from the Cache via an osgDB::read*File() call where only a pointer to the object is passed back, so taking a reference to the object is delayed till it gets reassigned to a ref_ptr<>, but at the same time another thread calls a flush of the Object Cache deleting this object as it's referenceCount is now zero. Using osgDB::readREf*File() makes sure the a ref_ptr<> is passed back and the referenceCount never goes to zero. To ensure the OSG builds when OSG_PROVIDE_READFILE is to OFF the many cases of osgDB::read*File() usage had to be replaced with a ref_ptr<> osgDB::readRef*File() usage. The avoid this change causing lots of other client code to be rewritten to handle the use of ref_ptr<> in place of C pointer I introduced a serious of templte methods in various class to adapt ref_ptr<> to the underly C pointer to be passed to old OSG API's, example of this is found in include/osg/Group: bool addChild(Node* child); // old method which can only be used with a Node* tempalte<class T> bool addChild(const osg::ref_ptr<T>& child) { return addChild(child.get()); } // adapter template method These changes together cover 149 modified files, so it's a large submission. This extent of changes are warrent to make use of the Object Cache and multi-threaded loaded more robust. git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/branches/OpenSceneGraph-3.4@15165 16af8721-9629-0410-8352-f15c8da7e697
2015-10-22 22:14:53 +08:00
template<class T> bool addChild( const ref_ptr<T>& child, double t) { return addChild(child.get(), t); }
virtual bool insertChild( unsigned int index, Node *child);
virtual bool insertChild( unsigned int index, Node *child, double t);
Introduced CMake option OSG_PROVIDE_READFILE option that defaults to ON, but when switched to OFF disables the building of the osgDB::read*File() methods, forcing users to use osgDB::readRef*File() methods. The later is preferable as it closes a potential threading bug when using paging databases in conjunction with the osgDB::Registry Object Cache. This threading bug occurs when one thread gets an object from the Cache via an osgDB::read*File() call where only a pointer to the object is passed back, so taking a reference to the object is delayed till it gets reassigned to a ref_ptr<>, but at the same time another thread calls a flush of the Object Cache deleting this object as it's referenceCount is now zero. Using osgDB::readREf*File() makes sure the a ref_ptr<> is passed back and the referenceCount never goes to zero. To ensure the OSG builds when OSG_PROVIDE_READFILE is to OFF the many cases of osgDB::read*File() usage had to be replaced with a ref_ptr<> osgDB::readRef*File() usage. The avoid this change causing lots of other client code to be rewritten to handle the use of ref_ptr<> in place of C pointer I introduced a serious of templte methods in various class to adapt ref_ptr<> to the underly C pointer to be passed to old OSG API's, example of this is found in include/osg/Group: bool addChild(Node* child); // old method which can only be used with a Node* tempalte<class T> bool addChild(const osg::ref_ptr<T>& child) { return addChild(child.get()); } // adapter template method These changes together cover 149 modified files, so it's a large submission. This extent of changes are warrent to make use of the Object Cache and multi-threaded loaded more robust. git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/branches/OpenSceneGraph-3.4@15165 16af8721-9629-0410-8352-f15c8da7e697
2015-10-22 22:14:53 +08:00
template<class T> bool insertChild( unsigned int index, const ref_ptr<T>& child, double t) { return insertChild(index, child.get(), t); }
virtual bool removeChild( Node *child );
virtual bool removeChildren(unsigned int pos,unsigned int numChildrenToRemove);
/** value is which child node is to be displayed */
void setValue(int value) { _value = value ; }
int getValue() const { return _value; }
/** Set time in seconds for child. */
void setTime(unsigned int frame, double t);
/** Get time for child. */
double getTime(unsigned int frame) const;
/** Set the time list for children. */
void setTimeList(const std::vector<double>& timeList) { _frameTime = timeList; }
/** Get the time list for children. */
const std::vector<double>& getTimeList() const { return _frameTime; }
/** Set default time in seconds for new child.
if t<0, t=0 */
void setDefaultTime(double t) {_defaultTime = (t<0.?0.:t);}
/** Get default time in seconds for new child. */
double getDefaultTime(void) const {return _defaultTime;};
/** Set time of last frame of last loop, in seconds.
if t<= 0, then ignored */
void setLastFrameTime(double t) {_lastFrameTime = (t<0.?0.:t);}
/** Get last frame time in seconds */
double getLastFrameTime(void) const {return _lastFrameTime;};
/** Get number of frames */
inline unsigned int getNumFrames() const { return _frameTime.size(); }
/** Interval modes. 'Loop' repeats frames 1-N; 'swing' repeats 1->N, (N-1)->1. */
enum LoopMode
{
LOOP,
SWING
};
/** Set sequence mode. */
void setLoopMode(LoopMode mode) { _loopMode = mode; _value = -1; }
/** Get sequence mode. */
LoopMode getLoopMode() const { return _loopMode; }
/** Set interval beginning. */
void setBegin(int begin) { _begin = begin; _value = -1; }
/** Get interval beginning. */
int getBegin() const { return _begin; }
/** Set interval ending. */
void setEnd(int end) { _end = end; _value = -1; }
/** Get interval ending. */
int getEnd() const { return _end; }
/** Set sequence mode & interval (range of children to be displayed). */
void setInterval(LoopMode mode, int begin, int end);
/** Get sequence mode & interval. */
inline void getInterval(LoopMode& mode, int& begin, int& end) const
{
mode = _loopMode;
begin = _begin;
end = _end;
}
/** Set speed. */
void setSpeed(float speed) { _speed = speed; }
/** Get speed. */
float getSpeed() const { return _speed; }
/** Set number of repeats. */
void setNumRepeats(int nreps) { _nreps = (nreps<0?-1:nreps); _nrepsRemain = _nreps; }
/** Get number of repeats. */
int getNumRepeats() const { return _nreps; }
/** Set duration: speed-up & number of repeats */
void setDuration(float speed, int nreps = -1);
/** Get duration & number of repeats. */
inline void getDuration(float& speed, int& nreps) const
{
speed = _speed;
nreps = _nreps;
}
/** Sequence modes. */
enum SequenceMode
{
START,
STOP,
PAUSE,
RESUME
};
/** Set sequence mode. Start/stop & pause/resume. */
void setMode(SequenceMode mode);
/** Get sequence mode. */
inline SequenceMode getMode() const { return _mode; }
/** If false (default), frames will not be sync'd to frameTime. If
true, frames will be sync'd to frameTime. */
void setSync(bool sync) { _sync = sync; }
/** Get sync value */
bool getSync() const { return _sync; }
/** If true, show no child nodes after stopping */
void setClearOnStop(bool clearOnStop) { _clearOnStop = clearOnStop; }
/** Get whether to show no child nodes after stopping */
bool getClearOnStop() const { return _clearOnStop; }
protected :
virtual ~Sequence() {}
// get next _value in sequence
int _getNextValue(void) ;
// update local variables
void _update(void) ;
// init to -1 to mean "restart"
int _value;
// current time, set by traverse
double _now ;
// time this frame started. init to -1.0f- means get current time
double _start;
// a vector of frame times, one per value
std::vector<double> _frameTime;
// the total time for one sequence, from BEGIN to END
double _totalTime ;
// true if _totalTime needs to be recalculated because setTime or
// setInterval was invoked, or a new child was added
bool _resetTotalTime ;
// store "loop mde", either LOOP or SWING
// init to LOOP- set by setInterval
LoopMode _loopMode;
// first and last "values" to sequence through
// begin inits to 0
// end inits to -1- means to init to number of values
int _begin, _end;
// multiplier of real-time clock- set to N to go N times faster
// init to 0- going nowhere
float _speed;
// _nreps: how many times to repeat- default param is -1, repeat forever
// init to 0, no repetitions
// _nrepsRemain: set to nreps and counts down every traversal,
// stopping when it gets to zero. init to 0
int _nreps, _nrepsRemain;
// frame step (are we stepping forward or backward?)
int _step;
// default frame time for newly created frames or children- default is 1.
// set by setDefaultTime
double _defaultTime ;
// special time to display last frame of last loop
// <= zero means to not do anything special
double _lastFrameTime ;
// save the actual time of the last frame, and what value was stored
double _saveRealLastFrameTime ;
unsigned int _saveRealLastFrameValue ;
// the current mode
SequenceMode _mode;
// the current sync value
bool _sync ;
// the current clearOnStop value
bool _clearOnStop ;
};
}
#endif