OpenWalnut  1.4.0
WGELinearTranslationCallback.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WGELINEARTRANSLATIONCALLBACK_H
26 #define WGELINEARTRANSLATIONCALLBACK_H
27 
28 #include <osg/Node>
29 #include <osg/TexMat>
30 #include <osg/Uniform>
31 #include <osg/MatrixTransform>
32 
33 #include "../../common/WProperties.h"
34 
35 
36 /**
37  * 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
38  * WPropDouble. This way, one can simply implement movable slices and similar.
39  *
40  * \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
41  * support access via T->get(). Specialize the class if you do not specify a pointer.
42  */
43 template< typename T >
44 class WGELinearTranslationCallback: public osg::NodeCallback
45 {
46 public:
47  /**
48  * Constructor. Creates the callback. You still need to add it to the desired node.
49  *
50  * \param axe the axe to translate along. Should be normalized. If not, it scales the translation.
51  * \param property the property containing the value
52  * \param texMatrix optional pointer to a texture matrix which can be modified too to contain the normalized translation.
53  * \param scaler scales the property by this value before creating the matrix.
54  */
55  WGELinearTranslationCallback( osg::Vec3 axe, T property, osg::ref_ptr< osg::TexMat > texMatrix, double scaler = 1.0 );
56 
57  /**
58  * Constructor. Creates the callback. You still need to add it to the desired node.
59  *
60  * \param axe the axe to translate along. Should be normalized. If not, it scales the translation.
61  * \param property the property containing the value
62  * \param uniform optional pointer to a uniform that will contain the matrix. Useful if no tex-matrix is available anymore. The matrix is the
63  * matrix that is NOT scaled to be in texture space.
64  * \param scaler scales the property by this value before creating the matrix.
65  */
66  WGELinearTranslationCallback( osg::Vec3 axe, T property, osg::ref_ptr< osg::Uniform > uniform, double scaler = 1.0 );
67 
68  /**
69  * Constructor. Creates the callback. You still need to add it to the desired node.
70  *
71  * \param axe the axe to translate along. Should be normalized. If not, it scales the translation.
72  * \param property the property containing the value
73  * \param scaler scales the property by this value before creating the matrix.
74  */
75  WGELinearTranslationCallback( osg::Vec3 axe, T property, double scaler = 1.0 );
76 
77  /**
78  * Destructor.
79  */
81 
82  /**
83  * This operator gets called by OSG every update cycle. It moves the underlying MatrixTransform according to the specified axis and value.
84  *
85  * \param node the osg node
86  * \param nv the node visitor
87  */
88  virtual void operator()( osg::Node* node, osg::NodeVisitor* nv );
89 
90 protected:
91  /**
92  * The axis to transform along.
93  */
94  osg::Vec3 m_axe;
95 
96  /**
97  * The position
98  */
99  T m_pos;
100 
101  /**
102  * Cache the old position for proper update
103  */
104  double m_oldPos;
105 
106  /**
107  * Texture matrix that contains normalized translation.
108  */
109  osg::ref_ptr< osg::TexMat > m_texMat;
110 
111  /**
112  * The uniform to set the matrix to.
113  */
114  osg::ref_ptr< osg::Uniform > m_uniform;
115 
116  /**
117  * Scale the property prior to creating the matrix.
118  */
119  double m_scaler;
120 private:
121 };
122 
123 template< typename T >
124 WGELinearTranslationCallback< T >::WGELinearTranslationCallback( osg::Vec3 axe, T property, osg::ref_ptr< osg::TexMat > texMatrix, double scaler ):
125  osg::NodeCallback(),
126  m_axe( axe ),
127  m_pos( property ),
128  m_oldPos( -1.0 ),
129  m_texMat( texMatrix ),
130  m_scaler( scaler )
131 {
132  // initialize members
133 }
134 
135 template< typename T >
136 WGELinearTranslationCallback< T >::WGELinearTranslationCallback( osg::Vec3 axe, T property, osg::ref_ptr< osg::Uniform > uniform, double scaler ):
137  osg::NodeCallback(),
138  m_axe( axe ),
139  m_pos( property ),
140  m_oldPos( -1.0 ),
141  m_uniform( uniform ),
142  m_scaler( scaler )
143 {
144  // initialize members
145 }
146 
147 template< typename T >
148 WGELinearTranslationCallback< T >::WGELinearTranslationCallback( osg::Vec3 axe, T property, double scaler ):
149  osg::NodeCallback(),
150  m_axe( axe ),
151  m_pos( property ),
152  m_oldPos( -1.0 ),
153  m_scaler( scaler )
154 {
155  // initialize members
156 }
157 
158 template< typename T >
160 {
161  // cleanup
162 }
163 
164 template< typename T >
165 void WGELinearTranslationCallback< T >::operator()( osg::Node* node, osg::NodeVisitor* nv )
166 {
167  // this node is a MatrixTransform
168  float newPos = m_pos->get();
169  if( newPos != m_oldPos )
170  {
171  m_oldPos = newPos;
172  osg::MatrixTransform* m = static_cast< osg::MatrixTransform* >( node );
173  if( m )
174  {
175  float max = m_pos->getMax()->getMax();
176  float min = m_pos->getMin()->getMin();
177  float size = max - min;
178  float axeLen = m_axe.length();
179 
180  osg::Vec3 translation = m_axe * m_scaler * static_cast< float >( m_oldPos - min );
181 
182  // set both matrices
183  if( m_texMat )
184  {
185  m_texMat->setMatrix( osg::Matrix::translate( translation / size / axeLen ) );
186  }
187  if( m_uniform )
188  {
189  m_uniform->set( osg::Matrix::translate( translation ) );
190  }
191 
192  m->setMatrix( osg::Matrix::translate( translation ) );
193  }
194  }
195 
196  traverse( node, nv );
197 }
198 
199 #endif // WGELINEARTRANSLATIONCALLBACK_H
200