Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <vlGraphics/TrackballManipulator.hpp>
00033 #include <vlGraphics/OpenGLContext.hpp>
00034 #include <vlGraphics/Actor.hpp>
00035 #include <vlGraphics/SceneManager.hpp>
00036 #include <vlGraphics/Rendering.hpp>
00037
00038 using namespace vl;
00039
00040
00041 void TrackballManipulator::mouseDownEvent(EMouseButton btn, int x, int y)
00042 {
00043 if ( camera() == NULL )
00044 return;
00045
00046
00047 if (mode() != NoMode)
00048 return;
00049
00050
00051 if (btn == rotationButton())
00052 mMode = RotationMode;
00053 else
00054 if (btn == translationButton())
00055 mMode = TranslationMode;
00056 else
00057 if (btn == zoomButton())
00058 mMode = ZoomMode;
00059
00060 VL_CHECK(openglContext()->framebuffer())
00061
00062
00063 x -= camera()->viewport()->x();
00064 y -= openglContext()->framebuffer()->height() - 1 - (camera()->viewport()->y() + camera()->viewport()->height() -1);
00065
00066
00067 int w = camera()->viewport()->width();
00068 int h = camera()->viewport()->height();
00069
00070 if (x<0 || y<0 || x>=w || y>=h)
00071 return;
00072
00073 mMouseStart.x() = x;
00074 mMouseStart.y() = y;
00075
00076 if (mTransform)
00077 {
00078 mStartMatrix = mTransform->localMatrix();
00079 mPivot = mStartMatrix.getT();
00080 }
00081 else
00082 mStartMatrix = camera()->modelingMatrix();
00083
00084 mStartCameraPos = camera()->modelingMatrix().getT();
00085 mStartPivot = mPivot;
00086 }
00087
00088 void TrackballManipulator::mouseUpEvent(EMouseButton btn, int , int )
00089 {
00090 if ( camera() == NULL )
00091 return;
00092
00093
00094 if (mode() == NoMode)
00095 return;
00096
00097
00098 if (btn == rotationButton() && mMode == RotationMode)
00099 mMode = NoMode;
00100 else
00101 if (btn == translationButton() && mMode == TranslationMode)
00102 mMode = NoMode;
00103 else
00104 if (btn == zoomButton() && mMode == ZoomMode)
00105 mMode = NoMode;
00106 }
00107
00108 void TrackballManipulator::mouseMoveEvent(int x, int y)
00109 {
00110 if ( camera() == NULL )
00111 return;
00112
00113
00114 if (mode() == NoMode)
00115 return;
00116
00117 VL_CHECK(openglContext()->framebuffer())
00118
00119 x -= camera()->viewport()->x();
00120 y -= openglContext()->framebuffer()->height() - 1 - (camera()->viewport()->y() + camera()->viewport()->height() -1);
00121
00122 if (mode() == RotationMode)
00123 {
00124 if (mTransform)
00125 {
00126 mTransform->setLocalMatrix( mat4::getTranslation(mPivot) * trackballRotation(x,y) * mat4::getTranslation(-mPivot) * mStartMatrix );
00127 mTransform->computeWorldMatrix();
00128 mStartMatrix = mTransform->localMatrix();
00129 }
00130 else
00131 {
00132 camera()->setModelingMatrix( mat4::getTranslation(mPivot) * trackballRotation(x,y) * mat4::getTranslation(-mPivot) * mStartMatrix );
00133 mStartMatrix = camera()->modelingMatrix();
00134 }
00135
00136 mMouseStart.x() = x;
00137 mMouseStart.y() = y;
00138 }
00139 else
00140 if (mode() == ZoomMode)
00141 {
00142 float t = (y-mMouseStart.y()) / 200.0f;
00143 t *= zoomSpeed();
00144 real distance = (mStartCameraPos - mPivot).length();
00145 vec3 camera_pos = mStartCameraPos - camera()->modelingMatrix().getZ()*t*distance;
00146 mat4 m = camera()->modelingMatrix();
00147 m.setT(camera_pos);
00148 camera()->setModelingMatrix(m);
00149 }
00150 else
00151 if (mode() == TranslationMode)
00152 {
00153 float tx = (mMouseStart.x() - x) / 400.0f;
00154 float ty = -(mMouseStart.y() - y) / 400.0f;
00155 tx *= translationSpeed();
00156 ty *= translationSpeed();
00157 real distance = (mStartCameraPos - mPivot).length();
00158 vec3 up = camera()->modelingMatrix().getY();
00159 vec3 right = camera()->modelingMatrix().getX();
00160 mat4 m = camera()->modelingMatrix();
00161 m.setT(mStartCameraPos + up*distance*ty + right*distance*tx);
00162 camera()->setModelingMatrix(m);
00163 mPivot = mStartPivot + up*distance*ty + right*distance*tx;
00164 }
00165
00166
00167 openglContext()->update();
00168 }
00169
00170 mat4 TrackballManipulator::trackballRotation(int x, int y)
00171 {
00172 if( x==mMouseStart.x() && y==mMouseStart.y() )
00173 return mat4();
00174
00175 VL_CHECK(camera())
00176 vec3 a = computeVector(mMouseStart.x(), mMouseStart.y());
00177 vec3 b = computeVector(x, y);
00178 vec3 n = cross(a, b);
00179 n.normalize();
00180 a.normalize();
00181 b.normalize();
00182 real dot_a_b = dot(a,b);
00183 dot_a_b = clamp(dot_a_b,(real)-1.0,(real)+1.0);
00184 real alpha = acos(dot_a_b) * (mTransform ? 1 : -1);
00185 alpha = alpha * rotationSpeed();
00186 vec3 nc = camera()->modelingMatrix().get3x3() * n;
00187 if (mTransform && mTransform->parent())
00188 nc = mTransform->parent()->getComputedWorldMatrix().getInverse() * nc;
00189 nc.normalize();
00190 return mat4::getRotation(alpha*(real)dRAD_TO_DEG, nc);
00191 }
00192
00193 vec3 TrackballManipulator::computeVector(int x, int y)
00194 {
00195 vec3 c(camera()->viewport()->width() / 2.0f, camera()->viewport()->height() / 2.0f, 0);
00196
00197 float sphere_x = camera()->viewport()->width() * 0.5f;
00198 float sphere_y = camera()->viewport()->height() * 0.5f;
00199
00200 VL_CHECK(camera())
00201 vec3 v((real)x,(real)y,0);
00202 v -= c;
00203 v.x() /= sphere_x;
00204 v.y() /= sphere_y;
00205 v.y() = -v.y();
00206
00207
00208
00209 real z2 = 1.0f - v.x()*v.x() - v.y()*v.y();
00210 if (z2 < 0)
00211 z2 = 0;
00212 v.z() = sqrt( z2 );
00213 v.normalize();
00214 return v;
00215 }
00216
00217 void TrackballManipulator::adjustView(const AABB& aabb, const vec3& dir, const vec3& up, real bias)
00218 {
00219 VL_CHECK(camera())
00220 VL_CHECK(!aabb.isNull())
00221
00222 setPivot( aabb.center() );
00223 camera()->adjustView(aabb, dir, up, bias);
00224 }
00225
00226 void TrackballManipulator::adjustView(ActorCollection& actors, const vec3& dir, const vec3& up, real bias)
00227 {
00228 AABB aabb;
00229 for(int i=0; i<actors.size(); ++i)
00230 {
00231 if (actors.at(i)->transform())
00232 {
00233 actors.at(i)->transform()->computeWorldMatrix();
00234 }
00235 actors.at(i)->computeBounds();
00236 aabb += actors.at(i)->boundingBox();
00237 }
00238 adjustView(aabb, dir, up, bias);
00239 }
00240
00241 void TrackballManipulator::adjustView(SceneManager* scene, const vec3& dir, const vec3& up, real bias)
00242 {
00243 ActorCollection actors;
00244 scene->extractActors(actors);
00245 adjustView(actors, dir, up, bias);
00246 }
00247
00248 void TrackballManipulator::adjustView(Rendering* rendering, const vec3& dir, const vec3& up, real bias)
00249 {
00250 ActorCollection actors;
00251 for(int i=0; i<rendering->sceneManagers()->size(); ++i)
00252 rendering->sceneManagers()->at(i)->extractActors(actors);
00253 adjustView(actors, dir, up, bias);
00254 }
00255
00256 void TrackballManipulator::enableEvent(bool enabled)
00257 {
00258 if (enabled)
00259 {
00260 mMode = NoMode;
00261 if ( openglContext() )
00262 {
00263 openglContext()->setMouseVisible(true);
00264 openglContext()->setContinuousUpdate(false);
00265 }
00266 }
00267 }
00268