/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2009 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 OSGVOLUME_PROPERTY #define OSGVOLUME_PROPERTY 1 #include #include #include #include #include namespace osgVolume { // forward decarle class Property; class CompositeProperty; class SwitchProperty; class TransferFunctionProperty; class ScalarProperty; class IsoSurfaceProperty; class MaximumIntensityProjectionProperty; class LightingProperty; class AlphaFuncProperty; class SampleRatioProperty; class SampleRatioWhenMovingProperty; class SampleDensityProperty; class SampleDensityWhenMovingProperty; class TransparencyProperty; class ExteriorTransparencyFactorProperty; class VolumeSettings; class OSGVOLUME_EXPORT PropertyVisitor { public: PropertyVisitor(bool traverseOnlyActiveChildren=true); virtual ~PropertyVisitor() {} virtual void apply(Property&); virtual void apply(CompositeProperty&); virtual void apply(SwitchProperty&); virtual void apply(TransferFunctionProperty&); virtual void apply(ScalarProperty&); virtual void apply(IsoSurfaceProperty&); virtual void apply(AlphaFuncProperty&); virtual void apply(MaximumIntensityProjectionProperty&); virtual void apply(LightingProperty&); virtual void apply(SampleRatioProperty&); virtual void apply(SampleRatioWhenMovingProperty&); virtual void apply(SampleDensityProperty&); virtual void apply(SampleDensityWhenMovingProperty&); virtual void apply(TransparencyProperty&); virtual void apply(ExteriorTransparencyFactorProperty&); virtual void apply(VolumeSettings&); bool _traverseOnlyActiveChildren; }; class OSGVOLUME_EXPORT Property : public osg::Object { public: Property(); /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ Property(const Property&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); META_Object(osgVolume, Property); void dirty() { ++_modifiedCount; } void setModifiedCount(unsigned int c) { _modifiedCount = c; } unsigned int getModifiedCount() const { return _modifiedCount; } virtual void accept(PropertyVisitor& pv) { pv.apply(*this); } virtual void traverse(PropertyVisitor& pv) {} protected: virtual ~Property(); unsigned int _modifiedCount; }; class OSGVOLUME_EXPORT CompositeProperty : public Property { public: CompositeProperty(); /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ CompositeProperty(const CompositeProperty& compositeProperty,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); META_Object(osgVolume, CompositeProperty); virtual void accept(PropertyVisitor& pv) { pv.apply(*this); } virtual void traverse(PropertyVisitor& pv) { for(Properties::iterator itr = _properties.begin(); itr != _properties.end(); ++itr) { (*itr)->accept(pv); } } void clear(); typedef std::vector< osg::ref_ptr > Properties; void setProperty(unsigned int i, Property* property) { if (i>=_properties.size()) _properties.resize(i+1); _properties[i] = property; } template void setProperty(unsigned int i, const osg::ref_ptr& p) { setProperty(i, p.get()); } Property* getProperty(unsigned int i) { return i<_properties.size() ? _properties[i].get() : 0; } const Property* getProperty(unsigned int i) const { return i<_properties.size() ? _properties[i].get() : 0; } void addProperty(Property* property) { _properties.push_back(property); dirty(); } template void addProperty(const osg::ref_ptr& p) { addProperty(p.get()); } void removeProperty(unsigned int i) { _properties.erase(_properties.begin()+i); } unsigned int getNumProperties() const { return _properties.size(); } protected: virtual ~CompositeProperty() {} Properties _properties; }; class OSGVOLUME_EXPORT SwitchProperty : public CompositeProperty { public: SwitchProperty(); /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ SwitchProperty(const SwitchProperty& switchProperty,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); META_Object(osgVolume, SwitchProperty); virtual void accept(PropertyVisitor& pv) { pv.apply(*this); } virtual void traverse(PropertyVisitor& pv) { if (pv._traverseOnlyActiveChildren) { if (_activeProperty>=0 && static_cast(_activeProperty)<=getNumProperties()) { _properties[_activeProperty]->accept(pv); } } else { CompositeProperty::traverse(pv); } } /** Set which child property is active. * -1 disables all children.*/ void setActiveProperty(int i) { _activeProperty = i; dirty(); } /** Get the active property.*/ int getActiveProperty() const { return _activeProperty; } protected: virtual ~SwitchProperty() {} int _activeProperty; }; class OSGVOLUME_EXPORT TransferFunctionProperty : public Property { public: TransferFunctionProperty(osg::TransferFunction* tf = 0); /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ TransferFunctionProperty(const TransferFunctionProperty& tfp,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); META_Object(osgVolume, TransferFunctionProperty); virtual void accept(PropertyVisitor& pv) { pv.apply(*this); } /** Set the transfer function.*/ void setTransferFunction(osg::TransferFunction* tf) { _tf = tf; } /** Get the transfer function.*/ osg::TransferFunction* getTransferFunction() { return _tf.get(); } /** Get the const transfer function.*/ const osg::TransferFunction* getTransferFunction() const { return _tf.get(); } protected: virtual ~TransferFunctionProperty() {} osg::ref_ptr _tf; }; class OSGVOLUME_EXPORT ScalarProperty : public Property { public: ScalarProperty(const std::string& scaleName, float value); ScalarProperty(const ScalarProperty& scalarProperty,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); META_Object(osgVolume, ScalarProperty); virtual void accept(PropertyVisitor& pv) { pv.apply(*this); } /** Set the value.*/ virtual void setValue(float v) { _uniform->set(v); dirty(); } /** Get the value.*/ float getValue() const { float v; _uniform->get(v); return v; } /** Get the underlying uniform.*/ osg::Uniform* getUniform() { return _uniform.get(); } /** Get the underlying uniform.*/ const osg::Uniform* getUniform() const { return _uniform.get(); } protected: virtual ~ScalarProperty() {} ScalarProperty(); osg::ref_ptr _uniform; }; class OSGVOLUME_EXPORT IsoSurfaceProperty : public ScalarProperty { public: IsoSurfaceProperty(float value=1.0f); IsoSurfaceProperty(const IsoSurfaceProperty& isp,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); META_Object(osgVolume, IsoSurfaceProperty); virtual void accept(PropertyVisitor& pv) { pv.apply(*this); } protected: virtual ~IsoSurfaceProperty() {} }; class OSGVOLUME_EXPORT AlphaFuncProperty : public ScalarProperty { public: AlphaFuncProperty(float value=1.0f); AlphaFuncProperty(const AlphaFuncProperty& isp,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); META_Object(osgVolume, AlphaFuncProperty); virtual void accept(PropertyVisitor& pv) { pv.apply(*this); } virtual void setValue(float v); osg::AlphaFunc* getAlphaFunc() { return _alphaFunc.get(); } const osg::AlphaFunc* getAlphaFunc() const { return _alphaFunc.get(); } protected: virtual ~AlphaFuncProperty() {} osg::ref_ptr _alphaFunc; }; class OSGVOLUME_EXPORT MaximumIntensityProjectionProperty : public Property { public: MaximumIntensityProjectionProperty(); MaximumIntensityProjectionProperty(const MaximumIntensityProjectionProperty& mipp,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); META_Object(osgVolume, MaximumIntensityProjectionProperty); virtual void accept(PropertyVisitor& pv) { pv.apply(*this); } protected: virtual ~MaximumIntensityProjectionProperty() {} }; class OSGVOLUME_EXPORT LightingProperty : public Property { public: LightingProperty(); LightingProperty(const LightingProperty& mipp,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); META_Object(osgVolume, LightingProperty); virtual void accept(PropertyVisitor& pv) { pv.apply(*this); } protected: virtual ~LightingProperty() {} }; /** Sample density to use when the volume is static relative to the eye point or when moving if no SampleDensityWhenMovingProperty is assigned.*/ class OSGVOLUME_EXPORT SampleDensityProperty : public ScalarProperty { public: SampleDensityProperty(float value=1.0f); SampleDensityProperty(const SampleDensityProperty& isp,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); META_Object(osgVolume, SampleDensityProperty); virtual void accept(PropertyVisitor& pv) { pv.apply(*this); } protected: virtual ~SampleDensityProperty() {} }; /** Sample density to use when the volume is moving relative to the eye point.*/ class OSGVOLUME_EXPORT SampleDensityWhenMovingProperty : public ScalarProperty { public: SampleDensityWhenMovingProperty(float value=1.0f); SampleDensityWhenMovingProperty(const SampleDensityWhenMovingProperty& isp,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); META_Object(osgVolume, SampleDensityWhenMovingProperty); virtual void accept(PropertyVisitor& pv) { pv.apply(*this); } protected: virtual ~SampleDensityWhenMovingProperty() {} }; /** Sample ratioto use when the volume is static relative to the eye point or when moving if no SampleRatioWhenMovingProperty is assigned.*/ class OSGVOLUME_EXPORT SampleRatioProperty : public ScalarProperty { public: SampleRatioProperty(float value=1.0f); SampleRatioProperty(const SampleRatioProperty& isp,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); META_Object(osgVolume, SampleRatioProperty); virtual void accept(PropertyVisitor& pv) { pv.apply(*this); } protected: virtual ~SampleRatioProperty() {} }; /** Sample density to use when the volume is moving relative to the eye point.*/ class OSGVOLUME_EXPORT SampleRatioWhenMovingProperty : public ScalarProperty { public: SampleRatioWhenMovingProperty(float value=1.0f); SampleRatioWhenMovingProperty(const SampleRatioWhenMovingProperty& isp,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); META_Object(osgVolume, SampleRatioWhenMovingProperty); virtual void accept(PropertyVisitor& pv) { pv.apply(*this); } protected: virtual ~SampleRatioWhenMovingProperty() {} }; class OSGVOLUME_EXPORT TransparencyProperty : public ScalarProperty { public: TransparencyProperty(float value=1.0f); TransparencyProperty(const TransparencyProperty& isp,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); META_Object(osgVolume, TransparencyProperty); virtual void accept(PropertyVisitor& pv) { pv.apply(*this); } protected: virtual ~TransparencyProperty() {} }; class OSGVOLUME_EXPORT ExteriorTransparencyFactorProperty : public ScalarProperty { public: ExteriorTransparencyFactorProperty(float value=0.0f); ExteriorTransparencyFactorProperty(const ExteriorTransparencyFactorProperty& isp,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); META_Object(osgVolume, ExteriorTransparencyFactorProperty); virtual void accept(PropertyVisitor& pv) { pv.apply(*this); } protected: virtual ~ExteriorTransparencyFactorProperty() {} }; class OSGVOLUME_EXPORT CollectPropertiesVisitor : public osgVolume::PropertyVisitor { public: CollectPropertiesVisitor(bool traverseOnlyActiveChildren=true); virtual void apply(TransferFunctionProperty&); virtual void apply(ScalarProperty&); virtual void apply(IsoSurfaceProperty& iso); virtual void apply(AlphaFuncProperty& af); virtual void apply(MaximumIntensityProjectionProperty& mip); virtual void apply(LightingProperty& lp); virtual void apply(SampleDensityProperty& sdp); virtual void apply(SampleDensityWhenMovingProperty& sdp); virtual void apply(SampleRatioProperty& sdp); virtual void apply(SampleRatioWhenMovingProperty& sdp); virtual void apply(TransparencyProperty& tp); virtual void apply(ExteriorTransparencyFactorProperty& tp); osg::ref_ptr _tfProperty; osg::ref_ptr _isoProperty; osg::ref_ptr _afProperty; osg::ref_ptr _mipProperty; osg::ref_ptr _lightingProperty; osg::ref_ptr _sampleDensityProperty; osg::ref_ptr _sampleDensityWhenMovingProperty; osg::ref_ptr _sampleRatioProperty; osg::ref_ptr _sampleRatioWhenMovingProperty; osg::ref_ptr _transparencyProperty; osg::ref_ptr _exteriorTransparencyFactorProperty; }; class OSGVOLUME_EXPORT PropertyAdjustmentCallback : public osgGA::GUIEventHandler, public osg::StateSet::Callback { public: PropertyAdjustmentCallback(); PropertyAdjustmentCallback(const PropertyAdjustmentCallback&,const osg::CopyOp&); META_Object(osgVolume, PropertyAdjustmentCallback); virtual NodeCallback* asNodeCallback() { return osg::NodeCallback::asNodeCallback(); } virtual const NodeCallback* asNodeCallback() const { return osg::NodeCallback::asNodeCallback(); } virtual bool run(osg::Object* object, osg::Object* data) { return osgGA::GUIEventHandler::run(object, data); } void setKeyEventCycleForward(int key) { _cyleForwardKey = key; } int getKeyEventCycleForward() const { return _cyleForwardKey; } void setKeyEventCycleBackward(int key) { _cyleBackwardKey = key; } int getKeyEventCycleBackward() const { return _cyleBackwardKey; } void setKeyEventActivatesTransparencyAdjustment(int key) { _transparencyKey = key; } int getKeyEventActivatesTransparencyAdjustment() const { return _transparencyKey; } void setKeyEventActivatesExteriorTransparencyFactorAdjustment(int key) { _exteriorTransparencyFactorKey = key; } int getKeyEventActivatesExteriorTransparencyFactorAdjustment() const { return _exteriorTransparencyFactorKey; } void setKeyEventActivatesSampleDensityAdjustment(int key) { _sampleDensityKey = key; } int getKeyEventActivatesSampleDensityAdjustment() const { return _sampleDensityKey; } void setKeyEventActivatesAlphaFuncAdjustment(int key) { _alphaFuncKey = key; } int getKeyEventActivatesAlphaFuncAdjustment() const { return _alphaFuncKey; } virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&, osg::Object* object, osg::NodeVisitor*); int _cyleForwardKey; int _cyleBackwardKey; int _transparencyKey; int _exteriorTransparencyFactorKey; int _alphaFuncKey; int _sampleDensityKey; bool _updateTransparency; bool _updateExteriorTransparencyFactor; bool _updateAlphaCutOff; bool _updateSampleDensity; }; } #endif