control.cpp

Go to the documentation of this file.
00001 /*
00002     RenderStack  Support library for OpenGL 3+
00003     Copyright (C) 2010  Timo Suoranta
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Lesser General Public
00007     License as published by the Free Software Foundation; either
00008     version 2.1 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Lesser General Public License for more details.
00014 
00015     You should have received a copy of the GNU Lesser General Public
00016     License along with this library; if not, write to the Free Software
00017     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00018 */
00019 
00027 #include "renderstack/control.hpp"
00028 #include "renderstack/frame.hpp"
00029 
00030 namespace renderstack {
00031 
00032 void control::update()
00033 {
00034     if(
00035         ((m_options & bit_active ) == bit_active) &&
00036         ((m_options & bit_inhibit) == 0         )
00037     )
00038     {
00039         adjust(m_current_delta);
00040     }
00041     dampen();
00042 }
00043 
00044 void control::adjust(float delta)
00045 {
00046     m_current_value += delta;
00047 
00048     if(m_current_value > m_max_value)
00049     {
00050         m_current_value = m_max_value;
00051     }
00052     else if(m_current_value < m_min_value)
00053     {
00054         m_current_value = m_min_value;
00055     }
00056 }
00057 
00058 void control::dampen()
00059 {
00060     if(
00061         (m_options & bit_dampen_multiply) == bit_dampen_multiply
00062     )
00063     {
00064         float old_value = m_current_value;
00065         m_current_value = m_current_value * m_damp;
00066         if(m_current_value == old_value)
00067         {
00068             m_current_value = 0;
00069         }
00070     }
00071     else if(
00072         ((m_options & bit_dampen_linear) == bit_dampen_linear) &&
00073         ((m_options & bit_active       ) == 0                )
00074     )
00075 
00076     {
00077         if(m_current_value > m_max_delta)
00078         {
00079             m_current_value -= m_max_delta;
00080             if(m_current_value < m_max_delta)
00081             {
00082                 m_current_value = 0;
00083             }
00084         }
00085         else if(m_current_value < -m_max_delta)
00086         {
00087             m_current_value += m_max_delta;
00088             if(m_current_value > -m_max_delta)
00089             {
00090                 m_current_value = 0;
00091             }
00092         }
00093         else
00094         {
00095             m_current_value *= m_damp;
00096         }
00097     }
00098 }
00099 
00100 void control::more(bool apply)
00101 {
00102     if(apply)
00103     {
00104         m_options       |= bit_more | bit_active;
00105         m_current_delta  = m_max_delta;
00106     }
00107     else
00108     {
00109         m_options &= ~bit_more;
00110         if(
00111             (m_options & bit_less) == bit_less
00112         )
00113         {
00114             m_current_delta = -m_max_delta;
00115         }
00116         else
00117         {
00118             m_options       &= ~bit_active;
00119             m_current_delta  = 0;
00120         }
00121     }
00122 }
00123 
00124 void control::less(bool apply)
00125 {
00126     if(apply)
00127     {
00128         m_options       |= bit_less | bit_active;
00129         m_current_delta  = -m_max_delta;
00130     }
00131     else
00132     {
00133         m_options &= ~bit_less;
00134         if(
00135             (m_options & bit_more) == bit_more)
00136         {
00137             m_current_delta = m_max_delta;
00138         }
00139         else
00140         {
00141             m_options       &= ~bit_active;
00142             m_current_delta  = 0;
00143         }
00144     }
00145 }
00146 
00147 void control::inhibit(bool apply)
00148 {
00149     if(apply)
00150     {
00151         m_options |= bit_inhibit;
00152     }
00153     else
00154     {
00155         m_options &= ~bit_inhibit;
00156     }
00157 }
00158 
00159 void control::stop(bool apply)
00160 {
00161     if(apply)
00162     {
00163         m_options |= bit_stop;
00164         if(m_current_value > 0)
00165         {
00166             m_current_delta = -m_max_delta;
00167         }
00168         else if(m_current_value < 0)
00169         {
00170             m_current_delta = m_max_delta;
00171         }
00172     }
00173     else
00174     {
00175         m_options &= ~bit_stop;
00176         if(
00177             ((m_options & bit_less) == bit_less) &&
00178             ((m_options & bit_more) == 0       )
00179         )
00180         {
00181             m_current_delta = -m_max_delta;
00182         }
00183         else if(
00184             ((m_options & bit_less) == 0       ) &&
00185             ((m_options & bit_more) == bit_more)
00186         )
00187         {
00188             m_current_delta = m_max_delta;
00189         }
00190     }
00191 }
00192 
00193 control::control()
00194 {
00195     clear();
00196 }
00197 
00198 void control::clear()
00199 {
00200     m_damp           =  0.950f;
00201     m_max_delta      =  0.004f;
00202     m_max_value      =  1.000f;
00203     m_min_value      = -1.000f;
00204     m_current_delta  = 0;
00205     m_current_value  = 0;
00206     m_options       &= ~bitmask_clear;
00207     m_options       |=  bit_dampen_multiply;
00208 }
00209 
00210 
00211 frame_controls::frame_controls(frame &slave_frame)
00212 :   m_frame(slave_frame)
00213 {
00214     m_translate_x.clear();
00215     m_translate_y.clear();
00216     m_translate_z.clear();
00217     m_rotate_x.clear();
00218     m_rotate_y.clear();
00219     m_rotate_z.clear();
00220 
00221     m_rotate_x.set_damp     (0.900f);
00222     m_rotate_y.set_damp     (0.900f);
00223     m_rotate_y.set_max_delta(0.002f);
00224     m_rotate_z.set_damp     (0.900f);
00225     m_rotate_z.set_max_delta(0.001f);
00226 
00227     m_translate_x.set_damp     (0.9700f);
00228     m_translate_y.set_damp     (0.9700f);
00229     m_translate_z.set_damp     (0.9700f);
00230     m_translate_x.set_max_delta(0.0040f);
00231     m_translate_y.set_max_delta(0.0040f);
00232     m_translate_z.set_max_delta(0.0040f);
00233 
00234     m_rotation = quaternion(m_frame.local_to_world());
00235 
00236     m_position_in_world = m_frame.position_in_world();
00237 }
00238 
00239 
00240 void frame_controls::fixed_update()
00241 {
00242     float       rotation_delta;
00243     float       half_angle_sin;
00244     float       half_angle_cos;
00245     quaternion  rotq;
00246     vec3        axis;
00247 
00248     m_translate_x.update();
00249     m_translate_y.update();
00250     m_translate_z.update();
00251     m_rotate_x.update();
00252     m_rotate_y.update();
00253     m_rotate_z.update();
00254 
00255     if(m_translate_x.current_value() != 0.0f)
00256     {
00257         float value = m_translate_x.current_value();
00258 
00259         axis = m_rotation.right_axis();
00260         m_position_in_world += axis * value;
00261     }
00262 
00263     if(m_translate_z.current_value() != 0.0f)
00264     {
00265         float value = m_translate_z.current_value();
00266 
00267         axis = m_rotation.view_axis();
00268         m_position_in_world += axis * value;
00269     }
00270 
00271     if(m_translate_y.current_value() != 0.0f)
00272     {
00273         float value = m_translate_y.current_value();
00274 
00275         axis = m_rotation.up_axis();
00276         m_position_in_world += axis * value;
00277     }
00278 
00279     if(m_rotate_y.current_value() != 0.0f)
00280     {
00281         rotation_delta = radian_mod_2pi(m_rotate_y.current_value());
00282 
00283         half_angle_sin = sinf(rotation_delta);
00284         half_angle_cos = cosf(rotation_delta);
00285 
00286         axis = m_rotation.up_axis();
00287         rotq = quaternion(axis, half_angle_sin, half_angle_cos);
00288         m_rotation = rotq * m_rotation;
00289         m_rotation = normalize(m_rotation);
00290     }
00291 
00292     if(m_rotate_x.current_value() != 0.0f)
00293     {
00294         rotation_delta = radian_mod_2pi(m_rotate_x.current_value());
00295 
00296         half_angle_sin = sinf(rotation_delta);
00297         half_angle_cos = cosf(rotation_delta);
00298 
00299         axis = m_rotation.right_axis();
00300         rotq = quaternion(axis, half_angle_sin, half_angle_cos);
00301         m_rotation = rotq * m_rotation;
00302         m_rotation = normalize(m_rotation);
00303     }
00304 
00305     if(m_rotate_z.current_value() != 0.0f)
00306     {
00307         rotation_delta = radian_mod_2pi(m_rotate_z.current_value());
00308 
00309         half_angle_sin = sinf(rotation_delta);
00310         half_angle_cos = cosf(rotation_delta);
00311 
00312         axis = m_rotation.view_axis();
00313         rotq = quaternion(axis, half_angle_sin, half_angle_cos);
00314         //m_rotation *= rotq;
00315         m_rotation = rotq * m_rotation;
00316         m_rotation = normalize(m_rotation);
00317     }
00318 }
00319 
00320 void frame_controls::once_per_frame_update()
00321 {
00322     make_matrix_quaternion_xyz(
00323         m_frame.local_to_world(),
00324         m_frame.world_to_local(),
00325         m_rotation,
00326         m_position_in_world
00327     );
00328 }
00329 
00330 }
00331 
Generated on Sun Apr 11 12:23:08 2010 for RenderStack by  doxygen 1.6.3