OpenWalnut  1.3.1
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  */
54  WGELinearTranslationCallback( osg::Vec3 axe, T property, osg::ref_ptr< osg::TexMat > texMatrix );
55 
56  /**
57  * Constructor. Creates the callback. You still need to add it to the desired node.
58  *
59  * \param axe the axe to translate along. Should be normalized. If not, it scales the translation.
60  * \param property the property containing the value
61  * \param uniform optional pointer to a uniform that will contain the matrix. Useful if no tex-matrix is available anymore. The matrix is the
62  * matrix that is NOT scaled to be in texture space.
63  */
64  WGELinearTranslationCallback( osg::Vec3 axe, T property, osg::ref_ptr< osg::Uniform > uniform );
65 
66  /**
67  * Constructor. Creates the callback. You still need to add it to the desired node.
68  *
69  * \param axe the axe to translate along. Should be normalized. If not, it scales the translation.
70  * \param property the property containing the value
71  */
72  WGELinearTranslationCallback( osg::Vec3 axe, T property );
73 
74  /**
75  * Destructor.
76  */
78 
79  /**
80  * This operator gets called by OSG every update cycle. It moves the underlying MatrixTransform according to the specified axis and value.
81  *
82  * \param node the osg node
83  * \param nv the node visitor
84  */
85  virtual void operator()( osg::Node* node, osg::NodeVisitor* nv );
86 
87 protected:
88  /**
89  * The axis to transform along.
90  */
91  osg::Vec3 m_axe;
92 
93  /**
94  * The position
95  */
97 
98  /**
99  * Cache the old position for proper update
100  */
101  double m_oldPos;
102 
103  /**
104  * Texture matrix that contains normalized translation.
105  */
106  osg::ref_ptr< osg::TexMat > m_texMat;
107 
108  /**
109  * The uniform to set the matrix to.
110  */
111  osg::ref_ptr< osg::Uniform > m_uniform;
112 private:
113 };
114 
115 template< typename T >
116 WGELinearTranslationCallback< T >::WGELinearTranslationCallback( osg::Vec3 axe, T property, osg::ref_ptr< osg::TexMat > texMatrix ):
117  osg::NodeCallback(),
118  m_axe( axe ),
119  m_pos( property ),
120  m_oldPos( -1.0 ),
121  m_texMat( texMatrix )
122 {
123  // initialize members
124 }
125 
126 template< typename T >
127 WGELinearTranslationCallback< T >::WGELinearTranslationCallback( osg::Vec3 axe, T property, osg::ref_ptr< osg::Uniform > uniform ):
128  osg::NodeCallback(),
129  m_axe( axe ),
130  m_pos( property ),
131  m_oldPos( -1.0 ),
132  m_uniform( uniform )
133 {
134  // initialize members
135 }
136 
137 template< typename T >
139  osg::NodeCallback(),
140  m_axe( axe ),
141  m_pos( property ),
142  m_oldPos( -1.0 )
143 {
144  // initialize members
145 }
146 
147 template< typename T >
149 {
150  // cleanup
151 }
152 
153 template< typename T >
154 void WGELinearTranslationCallback< T >::operator()( osg::Node* node, osg::NodeVisitor* nv )
155 {
156  // this node is a MatrixTransform
157  float newPos = m_pos->get();
158  if( newPos != m_oldPos )
159  {
160  m_oldPos = newPos;
161  osg::MatrixTransform* m = static_cast< osg::MatrixTransform* >( node );
162  if( m )
163  {
164  float max = m_pos->getMax()->getMax();
165  float min = m_pos->getMin()->getMin();
166  float size = max - min;
167  float axeLen = m_axe.length();
168 
169  osg::Vec3 translation = m_axe * static_cast< float >( m_oldPos - min );
170 
171  // set both matrices
172  if( m_texMat )
173  {
174  m_texMat->setMatrix( osg::Matrix::translate( translation / size / axeLen ) );
175  }
176  if( m_uniform )
177  {
178  m_uniform->set( osg::Matrix::translate( translation ) );
179  }
180 
181  m->setMatrix( osg::Matrix::translate( translation ) );
182  }
183  }
184 
185  traverse( node, nv );
186 }
187 
188 #endif // WGELINEARTRANSLATIONCALLBACK_H
189