OpenWalnut  1.4.0
WGELinearTranslationCallback.h
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #ifndef WGELINEARTRANSLATIONCALLBACK_H
00026 #define WGELINEARTRANSLATIONCALLBACK_H
00027 
00028 #include <osg/Node>
00029 #include <osg/TexMat>
00030 #include <osg/Uniform>
00031 #include <osg/MatrixTransform>
00032 
00033 #include "../../common/WProperties.h"
00034 
00035 
00036 /**
00037  * This class is an OSG Callback which allows simple linear translation of a matrix transform node along a specified axis. It is controlled by a
00038  * WPropDouble. This way, one can simply implement movable slices and similar.
00039  *
00040  * \tparam T the type used as control mechanism. Typically, this should be an property whose type is cast-able to double. The type specified must
00041  * support access via T->get(). Specialize the class if you do not specify a pointer.
00042  */
00043 template< typename T >
00044 class WGELinearTranslationCallback: public osg::NodeCallback
00045 {
00046 public:
00047     /**
00048      * Constructor. Creates the callback. You still need to add it to the desired node.
00049      *
00050      * \param axe the axe to translate along. Should be normalized. If not, it scales the translation.
00051      * \param property the property containing the value
00052      * \param texMatrix optional pointer to a texture matrix which can be modified too to contain the normalized translation.
00053      * \param scaler scales the property by this value before creating the matrix.
00054      */
00055     WGELinearTranslationCallback( osg::Vec3 axe, T property, osg::ref_ptr< osg::TexMat > texMatrix, double scaler = 1.0 );
00056 
00057     /**
00058      * Constructor. Creates the callback. You still need to add it to the desired node.
00059      *
00060      * \param axe the axe to translate along. Should be normalized. If not, it scales the translation.
00061      * \param property the property containing the value
00062      * \param uniform optional pointer to a uniform that will contain the matrix. Useful if no tex-matrix is available anymore. The matrix is the
00063      *                matrix that is NOT scaled to be in texture space.
00064      * \param scaler scales the property by this value before creating the matrix.
00065      */
00066     WGELinearTranslationCallback( osg::Vec3 axe, T property, osg::ref_ptr< osg::Uniform > uniform, double scaler = 1.0 );
00067 
00068     /**
00069      * Constructor. Creates the callback. You still need to add it to the desired node.
00070      *
00071      * \param axe the axe to translate along. Should be normalized. If not, it scales the translation.
00072      * \param property the property containing the value
00073      * \param scaler scales the property by this value before creating the matrix.
00074      */
00075     WGELinearTranslationCallback( osg::Vec3 axe, T property, double scaler = 1.0 );
00076 
00077     /**
00078      * Destructor.
00079      */
00080     virtual ~WGELinearTranslationCallback();
00081 
00082     /**
00083      * This operator gets called by OSG every update cycle. It moves the underlying MatrixTransform according to the specified axis and value.
00084      *
00085      * \param node the osg node
00086      * \param nv the node visitor
00087      */
00088     virtual void operator()( osg::Node* node, osg::NodeVisitor* nv );
00089 
00090 protected:
00091     /**
00092      * The axis to transform along.
00093      */
00094     osg::Vec3 m_axe;
00095 
00096     /**
00097      * The position
00098      */
00099     T m_pos;
00100 
00101     /**
00102      * Cache the old position for proper update
00103      */
00104     double m_oldPos;
00105 
00106     /**
00107      * Texture matrix that contains normalized translation.
00108      */
00109     osg::ref_ptr< osg::TexMat > m_texMat;
00110 
00111     /**
00112      * The uniform to set the matrix to.
00113      */
00114     osg::ref_ptr< osg::Uniform > m_uniform;
00115 
00116     /**
00117      * Scale the property prior to creating the matrix.
00118      */
00119     double m_scaler;
00120 private:
00121 };
00122 
00123 template< typename T >
00124 WGELinearTranslationCallback< T >::WGELinearTranslationCallback( osg::Vec3 axe, T property, osg::ref_ptr< osg::TexMat > texMatrix, double scaler ):
00125     osg::NodeCallback(),
00126     m_axe( axe ),
00127     m_pos( property ),
00128     m_oldPos( -1.0 ),
00129     m_texMat( texMatrix ),
00130     m_scaler( scaler )
00131 {
00132     // initialize members
00133 }
00134 
00135 template< typename T >
00136 WGELinearTranslationCallback< T >::WGELinearTranslationCallback( osg::Vec3 axe, T property, osg::ref_ptr< osg::Uniform > uniform, double scaler ):
00137     osg::NodeCallback(),
00138     m_axe( axe ),
00139     m_pos( property ),
00140     m_oldPos( -1.0 ),
00141     m_uniform( uniform ),
00142     m_scaler( scaler )
00143 {
00144     // initialize members
00145 }
00146 
00147 template< typename T >
00148 WGELinearTranslationCallback< T >::WGELinearTranslationCallback( osg::Vec3 axe, T property, double scaler ):
00149     osg::NodeCallback(),
00150     m_axe( axe ),
00151     m_pos( property ),
00152     m_oldPos( -1.0 ),
00153     m_scaler( scaler )
00154 {
00155     // initialize members
00156 }
00157 
00158 template< typename T >
00159 WGELinearTranslationCallback< T >::~WGELinearTranslationCallback()
00160 {
00161     // cleanup
00162 }
00163 
00164 template< typename T >
00165 void WGELinearTranslationCallback< T >::operator()( osg::Node* node, osg::NodeVisitor* nv )
00166 {
00167     // this node is a MatrixTransform
00168     float newPos = m_pos->get();
00169     if( newPos != m_oldPos )
00170     {
00171         m_oldPos = newPos;
00172         osg::MatrixTransform* m = static_cast< osg::MatrixTransform* >( node );
00173         if( m )
00174         {
00175             float max = m_pos->getMax()->getMax();
00176             float min = m_pos->getMin()->getMin();
00177             float size = max - min;
00178             float axeLen = m_axe.length();
00179 
00180             osg::Vec3 translation = m_axe * m_scaler * static_cast< float >( m_oldPos - min );
00181 
00182             // set both matrices
00183             if( m_texMat )
00184             {
00185                 m_texMat->setMatrix( osg::Matrix::translate( translation / size / axeLen ) );
00186             }
00187             if( m_uniform )
00188             {
00189                 m_uniform->set( osg::Matrix::translate( translation ) );
00190             }
00191 
00192             m->setMatrix( osg::Matrix::translate( translation ) );
00193         }
00194     }
00195 
00196     traverse( node, nv );
00197 }
00198 
00199 #endif  // WGELINEARTRANSLATIONCALLBACK_H
00200