contrib/brl/bbas/bgui3d/bgui3d_examiner_slider_tableau.cxx
Go to the documentation of this file.
00001 // This is brl/bbas/bgui3d/bgui3d_examiner_slider_tableau.cxx
00002 #include "bgui3d_examiner_slider_tableau.h"
00003 //:
00004 // \file
00005 
00006 #include <vcl_algorithm.h>
00007 #include <vnl/vnl_math.h> // for vnl_math::pi_over_2
00008 
00009 #include <Inventor/nodes/SoSeparator.h>
00010 #include <Inventor/nodes/SoCone.h>
00011 #include <Inventor/nodes/SoBaseColor.h>
00012 #include <Inventor/nodes/SoSphere.h>
00013 #include <Inventor/nodes/SoDirectionalLight.h>
00014 #include <Inventor/sensors/SoTimerSensor.h>
00015 #include <Inventor/nodes/SoOrthographicCamera.h>
00016 
00017 
00018 bgui3d_examiner_slider_tableau::bgui3d_examiner_slider_tableau(SoNode * scene_root)
00019     : bgui3d_examiner_tableau(scene_root), last_viewport_sz_(-1, -1)
00020 {
00021    interaction_type_ = CAMERA;
00022 
00023    // COLOR BAR AND SLIDERS ROOT
00024    SoSeparator *slider_root_ = new SoSeparator;
00025    sliderCamera_ = new SoOrthographicCamera;
00026    sliderCamera_->position.setValue(SbVec3f(0.0, 0.0, 10.0));
00027    sliderCamera_->nearDistance = 8.0;
00028    sliderCamera_->farDistance = 12.0;
00029    sliderCamera_->focalDistance = 10.0;
00030    sliderCamera_->height.setValue(1.0) ;
00031 
00032    slider_transform = new SoTransform;
00033    SoDirectionalLight* slider_light = new SoDirectionalLight;
00034    slider_light->direction.setValue(SbVec3f(0., 0., 1.0));
00035    slider_light->color.setValue(SbVec3f(1.0, 1.0, 1.0));
00036 
00037    // COLOR BAR
00038    slider_height_ = 310;
00039    slider_width_ = 25;
00040    slider_image_ = new SoImage;
00041    slider_image_->vertAlignment = SoImage::TOP;
00042    slider_image_->horAlignment = SoImage::LEFT;
00043    slider_image_->height = slider_height_;
00044    slider_image_->width = slider_width_;
00045 
00046    ((SoGroup*)(scene_root_))->addChild(slider_root_);
00047    slider_root_->addChild(sliderCamera_);
00048    slider_root_->addChild(slider_light);
00049    slider_root_->addChild(slider_transform);
00050    slider_root_->addChild(slider_image_);
00051 
00052    // MIN SLIDER
00053    this->min = 0;
00054    SoSeparator *min_root = new SoSeparator;
00055    min_transform = new SoTransform;
00056    min_transform->rotation.setValue(SbVec3f(0.f, 0.f, 1.f), float(vnl_math::pi_over_2));
00057    min_transform->translation.setValue(SbVec3f(0.1f, 0.f, 0.f));
00058    min_mark_ = new SoCone;
00059    min_mark_ ->bottomRadius.setValue(0.05f);
00060    min_mark_ ->height.setValue(0.1f);
00061 
00062    ((SoGroup*)(slider_root_))->addChild(min_root);
00063    min_root->addChild(min_transform);
00064    min_root->addChild(min_mark_ );
00065 
00066    // MAX SLIDER
00067    this->max = 255;
00068    SoSeparator *max_root = new SoSeparator;
00069    max_transform = new SoTransform;
00070    max_transform->rotation.setValue(SbVec3f(0, 0, 1), float(vnl_math::pi_over_2));
00071    max_transform->translation.setValue(SbVec3f(0.1f, 0.f, 0.f));
00072    max_mark_ = new SoCone;
00073    max_mark_ ->bottomRadius.setValue(0.05f);
00074    max_mark_ ->height.setValue(0.1f);
00075 
00076    ((SoGroup*)(slider_root_))->addChild(max_root);
00077    max_root->addChild(max_transform);
00078    max_root->addChild(max_mark_ );
00079 
00080    // POSITION COLOR BAR AND LOAD PIXEL VALUES
00081    loadSliderImage();
00082 }
00083 
00084 //: Populate the colormap array and set the image
00085 void bgui3d_examiner_slider_tableau::loadSliderImage()
00086 {
00087     float slider_offset = 255.0f/slider_height_;
00088     unsigned char * img = new unsigned char[slider_width_*slider_height_*4];
00089     int k=0;
00090 
00091     float curr_offset = 0;
00092     for (int j=0; j < slider_height_; j++) {
00093         k = (int)curr_offset;
00094         for (int i=0; i<slider_width_*4; i+=4) {
00095             img[j*slider_width_*4+i] =
00096             img[j*slider_width_*4+i+1] =
00097             img[j*slider_width_*4+i+2] =
00098             img[j*slider_width_*4+i+3] = (unsigned char)(255 - k);
00099         }
00100         curr_offset += slider_offset;
00101     }
00102     slider_image_->image.setValue(SbVec2s(slider_width_,slider_height_), 4, img);
00103 }
00104 
00105 //: Position the color map bar in the top left corner of screen and scale it screen height.
00106 void
00107 bgui3d_examiner_slider_tableau::positionSlider()
00108 {
00109 #if 1
00110    // set up the view volume of the color map camera
00111    SbViewportRegion v = get_viewport_region();
00112    SbVec2s viewport = v.getViewportSizePixels();
00113 
00114    if (viewport != last_viewport_sz_)
00115    {
00116      float aspect = float(viewport[0]) / float(viewport[1]);
00117      float factor = 300.f / float(viewport[1]);
00118      float wsx =1, wsy = 1;
00119      if ( aspect > 1.0f )
00120        wsx *= aspect;
00121      else {
00122        wsy /= aspect;
00123        factor /= aspect;
00124      }
00125 
00126      slider_transform->translation.setValue(SbVec3f(-0.5f * wsx, 0.5f*wsy, .0f));
00127 
00128      float wslider_width = wsx * slider_width_ / float( viewport[0]);
00129      // unused variable: float wslider_height = wsy * slider_height_ / float(viewport[1]);
00130 
00131      float min_height = wsy * slider_height_ / viewport[1] * this->min / 255;
00132      min_transform->translation.setValue(SbVec3f(wslider_width, -min_height, 0.f));
00133      min_transform->scaleFactor.setValue( SbVec3f(factor, factor, 1.0f));
00134 
00135      float max_height = wsy * slider_height_ / float( viewport[1]) * this->max/255.0f;
00136      max_transform->translation.setValue(SbVec3f(wslider_width, -max_height, 0.f));
00137      max_transform->scaleFactor.setValue( SbVec3f(factor, factor, 1.0f));
00138     }
00139 #endif // 1
00140 }
00141 
00142 //: Render the scene graph (called on draw events)
00143 bool
00144 bgui3d_examiner_slider_tableau::render()
00145 {
00146   positionSlider();
00147 
00148   // call the super class method
00149   return bgui3d_examiner_tableau::render();
00150 }
00151 
00152 //: it only handles the slider events and leaves the rest to the parent class
00153 bool
00154 bgui3d_examiner_slider_tableau::handle(const vgui_event& e)
00155 {
00156   // MOUSE MOTION
00157   if ( e.type == vgui_MOUSE_MOTION )
00158   {
00159     const SbVec2s viewport_size(get_viewport_region().getViewportSizePixels());
00160     const SbVec2s viewport_origin(get_viewport_region().getViewportOriginPixels());
00161     const SbVec2s curr_pos = SbVec2s(e.wx, e.wy) - viewport_origin;
00162     const SbVec2f curr_pos_norm((float) curr_pos[0] / (float) vcl_max((int)(viewport_size[0] - 1), 1),
00163                               (float) curr_pos[1] / (float) vcl_max((int)(viewport_size[1] - 1), 1));
00164     const SbVec2f last_pos_norm = last_pos_;
00165     // unused variable: float aspect_ratio = get_viewport_region().getViewportAspectRatio();
00166 
00167     // MOUSE DOWN HANDLING
00168     // unused variable: float factor = slider_height_/255.f;
00169     switch (last_down_button_)
00170     {
00171       case vgui_LEFT:
00172         if (e.wx >= 0 && e.wx <= slider_width_*2) { // WON'T ROTATE WHEN YOUR MOUSE IS DOWN ON THE LEFT COLOR MAP REGION
00173           int mouse_pos = static_cast<int>((viewport_size[1] - e.wy)*255.0/slider_height_);
00174           if (mouse_pos >= this->min-10 && mouse_pos <= this->min + 10) {
00175             transfer_callback(true, mouse_pos, this->max);
00176             return true;
00177           }
00178           else if (mouse_pos >= this->max -10 && mouse_pos <= this->max + 10)
00179           {
00180             transfer_callback(true, this->min, mouse_pos);
00181             return true;
00182           }
00183         }
00184         else if ( e.modifier != vgui_CTRL ) {
00185           spin(curr_pos_norm, last_pos_norm);
00186           update_log( curr_pos_norm );
00187           last_process_ = DRAG;
00188         }
00189         break;
00190       default:
00191         break;
00192     }
00193 
00194     last_timestamp_ = e.timestamp;
00195   }
00196 
00197   set_clipping_planes();
00198   return bgui3d_examiner_tableau::handle(e);
00199 }
00200 
00201 //: Called by biov_transfer_function if a change is made
00202 void
00203 bgui3d_examiner_slider_tableau::transfer_callback(const bool & remap, const int & n_min,
00204                                                   const int & n_max)
00205 {
00206   if (remap && n_min<=n_max && n_min>=0 && n_max <=255) {
00207     this->min = n_min;
00208     this->max = n_max;
00209 
00210     if (this->min > this->max)
00211     {
00212       int tmp = this->min;
00213       this->min = this->max;
00214       this->max = tmp;
00215     }
00216 
00217     loadSliderImage();
00218   }
00219 }