OpenWalnut 1.3.1
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      */
00054     WGELinearTranslationCallback( osg::Vec3 axe, T property, osg::ref_ptr< osg::TexMat > texMatrix );
00055 
00056     /**
00057      * Constructor. Creates the callback. You still need to add it to the desired node.
00058      *
00059      * \param axe the axe to translate along. Should be normalized. If not, it scales the translation.
00060      * \param property the property containing the value
00061      * \param uniform optional pointer to a uniform that will contain the matrix. Useful if no tex-matrix is available anymore. The matrix is the
00062      *                matrix that is NOT scaled to be in texture space.
00063      */
00064     WGELinearTranslationCallback( osg::Vec3 axe, T property, osg::ref_ptr< osg::Uniform > uniform );
00065 
00066     /**
00067      * Constructor. Creates the callback. You still need to add it to the desired node.
00068      *
00069      * \param axe the axe to translate along. Should be normalized. If not, it scales the translation.
00070      * \param property the property containing the value
00071      */
00072     WGELinearTranslationCallback( osg::Vec3 axe, T property );
00073 
00074     /**
00075      * Destructor.
00076      */
00077     virtual ~WGELinearTranslationCallback();
00078 
00079     /**
00080      * This operator gets called by OSG every update cycle. It moves the underlying MatrixTransform according to the specified axis and value.
00081      *
00082      * \param node the osg node
00083      * \param nv the node visitor
00084      */
00085     virtual void operator()( osg::Node* node, osg::NodeVisitor* nv );
00086 
00087 protected:
00088     /**
00089      * The axis to transform along.
00090      */
00091     osg::Vec3 m_axe;
00092 
00093     /**
00094      * The position
00095      */
00096     T m_pos;
00097 
00098     /**
00099      * Cache the old position for proper update
00100      */
00101     double m_oldPos;
00102 
00103     /**
00104      * Texture matrix that contains normalized translation.
00105      */
00106     osg::ref_ptr< osg::TexMat > m_texMat;
00107 
00108     /**
00109      * The uniform to set the matrix to.
00110      */
00111     osg::ref_ptr< osg::Uniform > m_uniform;
00112 private:
00113 };
00114 
00115 template< typename T >
00116 WGELinearTranslationCallback< T >::WGELinearTranslationCallback( osg::Vec3 axe, T property, osg::ref_ptr< osg::TexMat > texMatrix ):
00117     osg::NodeCallback(),
00118     m_axe( axe ),
00119     m_pos( property ),
00120     m_oldPos( -1.0 ),
00121     m_texMat( texMatrix )
00122 {
00123     // initialize members
00124 }
00125 
00126 template< typename T >
00127 WGELinearTranslationCallback< T >::WGELinearTranslationCallback( osg::Vec3 axe, T property, osg::ref_ptr< osg::Uniform > uniform ):
00128     osg::NodeCallback(),
00129     m_axe( axe ),
00130     m_pos( property ),
00131     m_oldPos( -1.0 ),
00132     m_uniform( uniform )
00133 {
00134     // initialize members
00135 }
00136 
00137 template< typename T >
00138 WGELinearTranslationCallback< T >::WGELinearTranslationCallback( osg::Vec3 axe, T property ):
00139     osg::NodeCallback(),
00140     m_axe( axe ),
00141     m_pos( property ),
00142     m_oldPos( -1.0 )
00143 {
00144     // initialize members
00145 }
00146 
00147 template< typename T >
00148 WGELinearTranslationCallback< T >::~WGELinearTranslationCallback()
00149 {
00150     // cleanup
00151 }
00152 
00153 template< typename T >
00154 void WGELinearTranslationCallback< T >::operator()( osg::Node* node, osg::NodeVisitor* nv )
00155 {
00156     // this node is a MatrixTransform
00157     float newPos = m_pos->get();
00158     if( newPos != m_oldPos )
00159     {
00160         m_oldPos = newPos;
00161         osg::MatrixTransform* m = static_cast< osg::MatrixTransform* >( node );
00162         if( m )
00163         {
00164             float max = m_pos->getMax()->getMax();
00165             float min = m_pos->getMin()->getMin();
00166             float size = max - min;
00167             float axeLen = m_axe.length();
00168 
00169             osg::Vec3 translation = m_axe * static_cast< float >( m_oldPos - min );
00170 
00171             // set both matrices
00172             if( m_texMat )
00173             {
00174                 m_texMat->setMatrix( osg::Matrix::translate( translation / size / axeLen ) );
00175             }
00176             if( m_uniform )
00177             {
00178                 m_uniform->set( osg::Matrix::translate( translation ) );
00179             }
00180 
00181             m->setMatrix( osg::Matrix::translate( translation ) );
00182         }
00183     }
00184 
00185     traverse( node, nv );
00186 }
00187 
00188 #endif  // WGELINEARTRANSLATIONCALLBACK_H
00189