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 mat4 m = actors.at(i)->transform()->worldMatrix();
00234 actors.at(i)->transform()->computeWorldMatrix();
00235 }
00236 actors.at(i)->computeBounds();
00237 aabb += actors.at(i)->boundingBox();
00238 }
00239 adjustView(aabb, dir, up, bias);
00240 }
00241
00242 void TrackballManipulator::adjustView(SceneManager* scene, const vec3& dir, const vec3& up, real bias)
00243 {
00244 ActorCollection actors;
00245 scene->extractActors(actors);
00246 adjustView(actors, dir, up, bias);
00247 }
00248
00249 void TrackballManipulator::adjustView(Rendering* rendering, const vec3& dir, const vec3& up, real bias)
00250 {
00251 ActorCollection actors;
00252 for(int i=0; i<rendering->sceneManagers()->size(); ++i)
00253 rendering->sceneManagers()->at(i)->extractActors(actors);
00254 adjustView(actors, dir, up, bias);
00255 }
00256
00257 void TrackballManipulator::enableEvent(bool enabled)
00258 {
00259 if (enabled)
00260 {
00261 mMode = NoMode;
00262 if ( openglContext() )
00263 {
00264 openglContext()->setMouseVisible(true);
00265 openglContext()->setContinuousUpdate(false);
00266 }
00267 }
00268 }
00269