diff --git a/include/osg/ClipPlane b/include/osg/ClipPlane index a08f5005f..39759c469 100644 --- a/include/osg/ClipPlane +++ b/include/osg/ClipPlane @@ -27,6 +27,7 @@ class OSG_EXPORT ClipPlane : public StateAttribute public : ClipPlane(); + inline ClipPlane(unsigned int no) { setClipPlaneNum(no); } inline ClipPlane(unsigned int no,const Vec4d& plane) { setClipPlaneNum(no); setClipPlane(plane); } inline ClipPlane(unsigned int no,const Plane& plane) { setClipPlaneNum(no); setClipPlane(plane); } inline ClipPlane(unsigned int no,double a,double b,double c,double d) { setClipPlaneNum(no); setClipPlane(a,b,c,d); } @@ -42,7 +43,12 @@ class OSG_EXPORT ClipPlane : public StateAttribute _clipPlaneNum=cp._clipPlaneNum; } - META_StateAttribute(osg, ClipPlane, CLIPPLANE); + virtual osg::Object* cloneType() const { return new ClipPlane( _clipPlaneNum ); } + virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new ClipPlane(*this,copyop); } + virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=NULL; } + virtual const char* libraryName() const { return "osg"; } + virtual const char* className() const { return "ClipPlane"; } + virtual Type getType() const { return CLIPPLANE; } /** Return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs. */ virtual int compare(const StateAttribute& sa) const diff --git a/include/osg/Hint b/include/osg/Hint index 3c236df94..cd9e7a88b 100644 --- a/include/osg/Hint +++ b/include/osg/Hint @@ -25,7 +25,7 @@ public: Hint(): _target(GL_NONE), - _mode(GL_NONE) {} + _mode(GL_DONT_CARE) {} Hint(GLenum target, GLenum mode): _target(target), @@ -37,13 +37,18 @@ public: _target(hint._target), _mode(hint._mode) {} - META_StateAttribute(osg, Hint, HINT); + virtual osg::Object* cloneType() const { return new Hint( _target, GL_DONT_CARE ); } + virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new Hint(*this,copyop); } + virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=NULL; } + virtual const char* libraryName() const { return "osg"; } + virtual const char* className() const { return "Light"; } + virtual Type getType() const { return HINT; } virtual int compare(const StateAttribute& sa) const { - // check the types are equal and then create the rhs variable - // used by the COMPARE_StateAttribute_Parameter macro's below. - COMPARE_StateAttribute_Types(Hint,sa) + // check the types are equal and then create the rhs variable + // used by the COMPARE_StateAttribute_Parameter macro's below. + COMPARE_StateAttribute_Types(Hint,sa) // compare each paramter in turn against the rhs. COMPARE_StateAttribute_Parameter(_target) @@ -55,7 +60,7 @@ public: /** Return the member identifier within the attribute's class type. Used for light number/clip plane number etc.*/ virtual unsigned int getMember() const { return static_cast(_target); } - inline void setTarget(GLenum target) { _target = target; } + inline void setTarget(GLenum target); inline GLenum getTarget() const { return _target; } inline void setMode(GLenum mode) { _mode = mode; } diff --git a/include/osg/Light b/include/osg/Light index 51e594a35..9fa2d0b8e 100644 --- a/include/osg/Light +++ b/include/osg/Light @@ -27,6 +27,8 @@ class OSG_EXPORT Light : public StateAttribute Light(); + Light(unsigned int lightnum); + /** Copy constructor using CopyOp to manage deep vs shallow copy. */ Light(const Light& light,const CopyOp& copyop=CopyOp::SHALLOW_COPY): StateAttribute(light,copyop), @@ -42,7 +44,12 @@ class OSG_EXPORT Light : public StateAttribute _spot_exponent(light._spot_exponent), _spot_cutoff(light._spot_cutoff) {} - META_StateAttribute(osg, Light, LIGHT); + virtual osg::Object* cloneType() const { return new Light(_lightnum); } + virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new Light(*this,copyop); } + virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=NULL; } + virtual const char* libraryName() const { return "osg"; } + virtual const char* className() const { return "Light"; } + virtual Type getType() const { return LIGHT; } /** Return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs. */ virtual int compare(const StateAttribute& sa) const @@ -78,7 +85,7 @@ class OSG_EXPORT Light : public StateAttribute /** Set which OpenGL light to operate on. */ - void setLightNum(int num) { _lightnum = num; } + void setLightNum(int num); /** Get which OpenGL light this osg::Light operates on. */ int getLightNum() const { return _lightnum; } diff --git a/src/osg/ClipPlane.cpp b/src/osg/ClipPlane.cpp index 3cd127a54..23928d889 100644 --- a/src/osg/ClipPlane.cpp +++ b/src/osg/ClipPlane.cpp @@ -11,6 +11,7 @@ * OpenSceneGraph Public License for more details. */ #include +#include #include using namespace osg; @@ -28,7 +29,43 @@ ClipPlane::~ClipPlane() void ClipPlane::setClipPlaneNum(unsigned int num) { + if (_clipPlaneNum==num) return; + + if (_parents.empty()) + { + _clipPlaneNum = num; + return; + } + + // take a reference to this clip plane to prevent it from going out of scope + // when we remove it temporarily from its parents. + osg::ref_ptr clipPlaneRef = this; + + // copy the parents as they _parents list will be changed by the subsequent removeAttributes. + ParentList parents = _parents; + + // remove this attribute from its parents as its position is being changed + // and would no longer be valid. + ParentList::iterator itr; + for(itr = parents.begin(); + itr != parents.end(); + ++itr) + { + osg::StateSet* stateset = *itr; + stateset->removeAttribute(this); + } + + // assign the clip plane number _clipPlaneNum = num; + + // add this attribute back into its original parents with its new position + for(itr = parents.begin(); + itr != parents.end(); + ++itr) + { + osg::StateSet* stateset = *itr; + stateset->setAttribute(this); + } } unsigned int ClipPlane::getClipPlaneNum() const diff --git a/src/osg/Hint.cpp b/src/osg/Hint.cpp index 043c8356e..0afbe2ee7 100644 --- a/src/osg/Hint.cpp +++ b/src/osg/Hint.cpp @@ -12,6 +12,7 @@ */ #include +#include using namespace osg; @@ -21,3 +22,45 @@ void Hint::apply(State& state) const glHint(_target, _mode); } + +void Hint::setTarget(GLenum target) +{ + if (_target==target) return; + + if (_parents.empty()) + { + _target = target; + return; + } + + // take a reference to this clip plane to prevent it from going out of scope + // when we remove it temporarily from its parents. + osg::ref_ptr hintRef = this; + + // copy the parents as they _parents list will be changed by the subsequent removeAttributes. + ParentList parents = _parents; + + // remove this attribute from its parents as its position is being changed + // and would no longer be valid. + ParentList::iterator itr; + for(itr = parents.begin(); + itr != parents.end(); + ++itr) + { + osg::StateSet* stateset = *itr; + stateset->removeAttribute(this); + } + + // assign the hint target + _target = target; + + // add this attribute back into its original parents with its new position + for(itr = parents.begin(); + itr != parents.end(); + ++itr) + { + osg::StateSet* stateset = *itr; + stateset->setAttribute(this); + } +} + diff --git a/src/osg/Light.cpp b/src/osg/Light.cpp index 78e3daa6c..9a25d3b73 100644 --- a/src/osg/Light.cpp +++ b/src/osg/Light.cpp @@ -11,6 +11,7 @@ * OpenSceneGraph Public License for more details. */ #include +#include #include using namespace osg; @@ -18,19 +19,13 @@ using namespace osg; Light::Light( void ) { init(); - - // notify(DEBUG) << "_ambient "<<_ambient< lightRef = this; + + // copy the parents as they _parents list will be changed by the subsequent removeAttributes. + ParentList parents = _parents; + + // remove this attribute from its parents as its position is being changed + // and would no longer be valid. + ParentList::iterator itr; + for(itr = parents.begin(); + itr != parents.end(); + ++itr) + { + osg::StateSet* stateset = *itr; + stateset->removeAttribute(this); + } + + // assign the hint target + _lightnum = num; + + // add this attribute back into its original parents with its new position + for(itr = parents.begin(); + itr != parents.end(); + ++itr) + { + osg::StateSet* stateset = *itr; + stateset->setAttribute(this); + } +} + + void Light::captureLightState() {