fshake3d  0.0.1
FreeformDensity3DSurfaceEditor
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines
ui_SceneView.cpp
Go to the documentation of this file.
00001 #include "ui_SceneView.hpp"
00002 #include "Scene.hpp"
00003 #include <iostream>
00004 
00005 static double sDefaultZoom;
00006 
00007 SceneView::SceneView(ProjectionType pt) 
00008 : mProjection(pt)
00009 , mLookAt()
00010 , mpScene(0)
00011 , mDragButton(-1)
00012 , mDragBase(-1,-1) 
00013 , mDirection(0,0,-1)
00014 , mpCaptureRayMotionTarget(0)
00015 , mpZoom(&sDefaultZoom)
00016 , mCameraOffset( Point3d(0,0,0) )
00017 { 
00018 }
00019 
00020 void SceneView::setViewport(const Vec4i& vp)
00021 {
00022   View::setViewport(vp);
00023   mProjection.setAspect( double( width() ) / double( height() ) );  
00024 }
00025 
00026   void SceneView::setProjectionViewWidth(double w) 
00027   { 
00028     setProjectionViewSize( Vec2d(w,w/mProjection.getAspect() ) ); 
00029   }
00030 
00031   void SceneView::setProjectionViewHeight(double h) 
00032   { 
00033     setProjectionViewSize( Vec2d(h*mProjection.getAspect(),h) ); 
00034   }
00035 
00036 
00037 void SceneView::setupLights()
00038 {
00039   glMatrixMode(GL_MODELVIEW);
00040   GLfloat position[4] = { 0.0,0.0,10.0,1.0 };
00041   glLightfv(GL_LIGHT0, GL_POSITION, position);
00042   GLfloat ambient[4] = { 1.0,1.0,1.0,1.0 };
00043   glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
00044 }
00045 
00046 void SceneView::display()
00047 {
00048   if ( (width() <= 0) || (height() <= 0) ) return;
00049 
00050   View::display();
00051 
00052   if (mpScene)
00053   {
00054     mProjection.computeTransform();
00055     glMatrixMode(GL_PROJECTION);
00056     glLoadMatrixd( mProjection.getTransformMatrix().getData() );
00057 
00058     glMatrixMode(GL_TEXTURE);
00059     glLoadIdentity();
00060     double a = 1.0/(*mpZoom);
00061     glScaled( a, a, a );
00062 
00063     glMatrixMode(GL_MODELVIEW);
00064     glLoadIdentity();    
00065 
00066     setupLights();
00067 
00068     if (mpFocusPoint)
00069       setCenter( *mpFocusPoint );
00070   
00071     mLookAt.computeTransform();
00072     mLookAt.computeInverse();
00073     glLoadMatrixd( mLookAt.getTransformMatrix().getData() );   
00074 
00075 
00076     mpScene->display();
00077   }
00078 }
00079 
00080 Point3d SceneView::unprojectPoint(const Point3d& p)
00081 {
00082   Point3d result;
00083   int success = 0;
00084 
00085   success = gluUnProject(
00086     p[0],p[1], p[2]
00087   , mLookAt.getTransformMatrix().getData()
00088   , mProjection.getTransformMatrix().getData()
00089   , &mViewport[0]
00090   , &result[0], &result[1], &result[2]
00091   );
00092 
00093   if (!success)
00094   {
00095     std::cerr << "error: SceneView::unprojectPoint : gluUnProject failed\n";
00096   }
00097 
00098   return result;
00099 }
00100 
00101 Rayd SceneView::makeRay(int x, int y)
00102 {
00103   Point3d p1 = unprojectPoint( Point3d(x,y,0) );
00104   Point3d p2 = unprojectPoint( Point3d(x,y,1) );
00105   Vec3d d(p2-p1);
00106   return Rayd(p1, makeNormal(d) );
00107 }
00108 
00109 Rayd SceneView::makeRay(Point2i sp)
00110 {
00111   return makeRay(sp[0],sp[1]);
00112 }
00113 
00114 // --- user-input ----------------------------------------------------------
00115 
00116 
00117 void SceneView::mouse(int button, int state, int x, int y)
00118 {   
00119   if (state == GLUT_DOWN)
00120   {
00121     mDragButton = button;
00122     mDragBase   = Vec2i(x,y);
00123     dragBegin();
00124     if (button == GLUT_LEFT_BUTTON)
00125     {
00126       mpScene->select( makeRay(x,y), *this );
00127     }
00128   } 
00129   else
00130   {
00131     dragEnd();
00132     mDragButton = -1;      
00133     mDragBase[0] = -1;
00134   }
00135 }
00136 
00137 void SceneView::motion(int x, int y)
00138 {
00139   if (mDragBase[0] > 0)
00140   {
00141     Vec2i d = Vec2i(x,y) - mDragBase;
00142     dragUpdate(d);
00143     if (mDragButton == GLUT_LEFT_BUTTON)
00144     {
00145       mpScene->drag( makeRay(x,y), *this );
00146     }
00147   }
00148 }
00149 
00150 void SceneView::updateEye()
00151 {
00152   // Vec3d eye = mLookAt.getCenter() - mDirection * ( mProjection.getZNear() ) + mCameraOffset;
00153   Vec3d eye = mLookAt.getCenter() - mDirection * 50.0 + mCameraOffset;
00154   mLookAt.setEye(eye);
00155 }
00156 
00157 void SceneView::setDirection(const Vec3d& direction)
00158 {
00159   mDirection = direction;
00160   updateEye();
00161 }
00162 
00163 void SceneView::setUp(const Vec3d& up)
00164 {
00165   mLookAt.setUp(up);
00166 }
00167 
00168 void SceneView::setCenter(const Vec3d& center)
00169 {
00170   mLookAt.setCenter(center);
00171   updateEye();
00172 }
00173 
00174 void SceneView::setProjectionViewSize(const Vec2d& size)
00175 { 
00176   mProjection.setViewSize(size); 
00177 }
00178 
00179 
00180 // --- future ----------------------------------------------------------------
00181 
00182 void SceneView::captureRayMotion(EventTarget* pTarget)
00183 {
00184   mpCaptureRayMotionTarget = pTarget;
00185 }
00186 
00187 void SceneView::releaseRayMotion()
00188 {
00189   mpCaptureRayMotionTarget = 0;
00190 }
00191 
00192 
00193 void SceneView::onEvent(Event& e)
00194 {
00195 #if 0
00196   switch(e.getType())
00197   {
00198   case EVENT_BUTTONDOWN:
00199     if (mDragButton == -1)
00200     {
00201       mDragButton = e.getButton();
00202       e.getSource().captureMouseMotion(*this);
00203       switch(e.getButton())
00204       {
00205       case BUTTON_LEFT:
00206         // mpScene->onEvent( makeSelectEvent( makeRay( Point2i(e.getMouseX(),e.getMouseY()) ) ) );
00207         break;
00208       case BUTTON_RIGHT:
00209         e.getSource().captureMouseMotion(*this);
00210         mDragButton = e.getButton();
00211         mDragBase   = Point2i(e.getMouseX(),e.getMouseY());
00212         mCenterBase = mpScene->getViewPoint().getFocusPoint();
00213         break;
00214       }
00215       break;
00216     }
00217   case EVENT_MOUSEMOTION:
00218     switch(mDragButton)
00219     {
00220     case BUTTON_LEFT:
00221       // mpScene->onEvent( makeDragEvent( makeRay( Point2i(e.getMouseX(), e.getMouseY() ) ) ) );
00222       break;
00223     case BUTTON_RIGHT:
00224       {
00225         Vec2i d = Vec2i( e.getMouseX(), e.getMouseY()) - mDragBase;
00226         Vec3d& focus = mpScene->getViewPoint().getFocusPoint();
00227         Vec2d size = mpProjection->getViewRect();
00228         Vec2d unit( size[0]/width() , size[1]/height() );
00229         focus = mCenterBase - ( mDirectionX*double(d[0])*unit[0] ) - ( mDirectionY*double(d[1])*unit[1] );                
00230       }
00231       break;
00232     }
00233     break;
00234   case EVENT_BUTTONUP:
00235     if (e.getButton() == mDragButton)
00236     {
00237       mDragButton = -1;
00238       e.getSource().releaseMouseMotion(*this);
00239     }
00240     break;
00241   }
00242 #endif
00243 }