fshake3d
0.0.1
FreeformDensity3DSurfaceEditor
|
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 }