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
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 #include <osg/Notify>
00083 #include "cameramanipulator.h"
00084 #include "mathutils.h"
00085 #include "pos.h"
00086
00087 #include <vector>
00088 #include <iterator>
00089
00090 namespace lpzrobots {
00091
00092 using namespace osg;
00093 using namespace osgGA;
00094
00095
00096 osg::Vec3 CameraManipulator::eye(0,0,0);
00097 osg::Vec3 CameraManipulator::view(0,0,0);
00098 osg::Vec3 CameraManipulator::home_eye;
00099 osg::Vec3 CameraManipulator::home_view;
00100 osg::Vec3 CameraManipulator::desiredEye;
00101 osg::Vec3 CameraManipulator::desiredView;
00102 bool CameraManipulator::home_externally_set=false;
00103 OdeAgent* CameraManipulator::watchingAgent;
00104 bool CameraManipulator::watchingAgentDefined=false;
00105 Position CameraManipulator::oldPositionOfAgent;
00106 bool CameraManipulator::oldPositionOfAgentDefined=false;
00107
00108
00109 CameraManipulator::CameraManipulator(osg::Node* node, GlobalData& global)
00110 : node(node), globalData(global) {
00111 if (this->node.get()) {
00112 const BoundingSphere& boundingSphere=this->node->getBound();
00113 modelScale = boundingSphere._radius;
00114 }else
00115 modelScale = 0.01f;
00116 desiredEye=eye;
00117 desiredView=view;
00118
00119
00120 degreeSmoothness=0.03;
00121 lengthSmoothness=0.03;
00122 lengthAccuracy=0.02;
00123 degreeAccuracy=0.03;
00124 }
00125
00126 CameraManipulator::~CameraManipulator(){
00127 }
00128
00129 void CameraManipulator::setNode(Node* node){
00130
00131 }
00132 const Node* CameraManipulator::getNode() const{
00133 return node.get();
00134 }
00135
00136 Node* CameraManipulator::getNode(){
00137 return node.get();
00138 }
00139
00140
00141 void CameraManipulator::setHome(const osg::Vec3& _eye, const osg::Vec3& _view){
00142 home_eye = _eye;
00143 home_view = _view;
00144 home_externally_set=true;
00145 eye = home_eye;
00146 view = home_view;
00147 desiredEye=_eye;
00148 desiredView=_view;
00149 computeMatrix();
00150 }
00151
00152
00153 void CameraManipulator::home(const GUIEventAdapter& ea,GUIActionAdapter& us){
00154 if(node.get() && !home_externally_set) {
00155 const BoundingSphere& boundingSphere=node->getBound();
00156
00157 home_eye = boundingSphere._center+
00158 Vec3(-boundingSphere._radius*1.2f,0, boundingSphere._radius*0.2f);
00159
00160 home_view = Vec3(-90,-10,0);
00161 }
00162
00163
00164 desiredEye=home_eye;
00165 desiredView=home_view;
00166 computeMatrix();
00167
00168 us.requestRedraw();
00169
00170 us.requestWarpPointer((ea.getXmin()+ea.getXmax())/2.0f,(ea.getYmin()+ea.getYmax())/2.0f);
00171
00172 flushMouseEventStack();
00173
00174 }
00175
00176 void CameraManipulator::init(const GUIEventAdapter& ea,GUIActionAdapter& us){
00177 flushMouseEventStack();
00178
00179 us.requestContinuousUpdate(false);
00180
00181 if (ea.getEventType()!=GUIEventAdapter::RESIZE)
00182 {
00183 us.requestWarpPointer((ea.getXmin()+ea.getXmax())/2.0f,(ea.getYmin()+ea.getYmax())/2.0f);
00184 }
00185 }
00186
00187 bool CameraManipulator::handle(const GUIEventAdapter& ea,GUIActionAdapter& us){
00188 int key=0;
00189 switch(ea.getEventType())
00190 {
00191 case(GUIEventAdapter::PUSH):
00192 {
00193 flushMouseEventStack();
00194 return true;
00195 }
00196
00197 case(GUIEventAdapter::RELEASE):
00198 {
00199 flushMouseEventStack();
00200 return true;
00201 }
00202
00203 case(GUIEventAdapter::DRAG):
00204 {
00205 addMouseEvent(ea);
00206 us.requestContinuousUpdate(true);
00207 if (calcMovement()) us.requestRedraw();
00208 return true;
00209 }
00210
00211 case(GUIEventAdapter::KEYDOWN):
00212 key=ea.getKey();
00213
00214 if ((65470<=key)&&(key<=65481)) {
00215 manageAgents(key-65469);
00216 return true;
00217 }
00218 switch(key) {
00219 case ' ':
00220 {
00221 flushMouseEventStack();
00222 home(ea,us);
00223 us.requestRedraw();
00224 us.requestContinuousUpdate(false);
00225 break;
00226 }
00227 case 'p':
00228 {
00229 printf("Camera Position/View: (Pos(%g, %g, %g), ", eye.x(), eye.y(), eye.z());
00230 printf(" Pos(%g, %g, %g));\n", view.x(), view.y(), view.z());
00231 break;
00232 }
00233
00234
00235 default:
00236 return false;
00237 }
00238 case(GUIEventAdapter::RESIZE):
00239 init(ea,us);
00240 us.requestRedraw();
00241 return true;
00242
00243 default:
00244 return false;
00245 }
00246 return true;
00247 }
00248
00249 void CameraManipulator::getUsage(ApplicationUsage& usage) const{
00250 usage.addKeyboardMouseBinding("Camera: Space","Reset the viewing position to home");
00251 usage.addKeyboardMouseBinding("Camera: p","Print position of the camera");
00252 usage.addKeyboardMouseBinding("Camera: F1-F12","switch the Agent to be watched");
00253 }
00254
00255 void CameraManipulator::flushMouseEventStack(){
00256 event_old = NULL;
00257 event = NULL;
00258 }
00259 void CameraManipulator::addMouseEvent(const GUIEventAdapter& ea){
00260 event_old = event;
00261 event = &ea;
00262 }
00263
00264
00265
00266 void CameraManipulator::setByMatrix(const Matrixd& matrix){
00267
00268 eye = matrix.getTrans();
00269 Vec3 xaxis(1,0,0);
00270 Pos head = Matrix::transform3x3(xaxis, matrix);
00271 view.x() = RadiansToDegrees(getAngle(xaxis, head)) *
00272 sign(head.y());
00273
00274 Pos tilt = Matrix::transform3x3(Vec3(0,0,1), matrix);
00275
00276
00277 std::cout << "Manipulator choosed: " << className() << std::endl;
00278 view.y() = RadiansToDegrees(getAngle(Vec3(0,0,1), tilt)-M_PI/2);
00279 desiredEye=eye;
00280 desiredView=view;
00281 computeMatrix();
00282 }
00283
00284
00285
00286
00287 Matrixd CameraManipulator::getMatrix() const {
00288 return pose;
00289 }
00290
00291 void CameraManipulator::update() {
00292
00293
00294
00295
00296 calcMovementByAgent();
00297
00298
00299 float updateFactor;
00300 updateFactor = globalData.odeConfig.drawInterval * globalData.odeConfig.simStepSize * globalData.odeConfig.cameraSpeed;
00301
00302
00303
00304 for (int i=0;i<=2;i++) {
00305
00306 if ((desiredView[i]-view[i])>180)
00307 view[i]+=360;
00308 else if ((view[i]-desiredView[i])>180)
00309 desiredView[i]+=360;
00310 if (abs(desiredView[i]-view[i])>degreeAccuracy)
00311 view[i]= normalize360(degreeSmoothness * updateFactor * desiredView[i] +
00312 (1.0 - degreeSmoothness * updateFactor) * view[i]);
00313 if (abs(desiredEye[i]-eye[i])>lengthAccuracy)
00314 eye[i]= lengthSmoothness * updateFactor * desiredEye[i]
00315 + (1.0 - lengthSmoothness * updateFactor) * eye[i];
00316 }
00317
00318
00319 if (watchingAgentDefined) {
00320 oldPositionOfAgent = watchingAgent->getRobot()->getPosition();
00321 oldPositionOfAgentDefined=true;
00322 }
00323 computeMatrix();
00324 }
00325
00326
00327
00328
00329
00330 Matrixd CameraManipulator::getInverseMatrix() const {
00331 return Matrixd::inverse(pose);
00332 }
00333
00334 void CameraManipulator::computeMatrix(){
00335 for (int i=0; i<3; i++) {
00336 while (view[i] > 180) view[i] -= 360;
00337 while (view[i] < -180) view[i] += 360;
00338 }
00339 osg::Matrix rot;
00340 rot.makeRotate( M_PI/2, osg::Vec3(1, 0, 0),
00341 osg::DegreesToRadians(view.x()), osg::Vec3(0, 0, 1),
00342 osg::DegreesToRadians(view.y()), osg::Vec3(cos(osg::DegreesToRadians(view.x())),
00343 sin(osg::DegreesToRadians(view.x())),
00344 0)
00345 );
00346
00347 pose = rot * Matrix::translate(eye);
00348 }
00349
00350 bool CameraManipulator::calcMovement(){
00351
00352
00353
00354
00355 if (event.get()==NULL || event_old.get()==NULL) return false;
00356
00357
00358 double dx = 10.0*(event->getXnormalized() - event_old->getXnormalized());
00359 double dy = 10.0*(event->getYnormalized() - event_old->getYnormalized());
00360 double s = sin(osg::DegreesToRadians(view.x()));
00361 double c = cos(osg::DegreesToRadians(view.x()));
00362
00363 unsigned int buttonMask = event_old->getButtonMask();
00364 if (buttonMask==GUIEventAdapter::LEFT_MOUSE_BUTTON) {
00365 desiredView.x() += dx*3.0f;
00366 desiredView.y() -= dy*3.0f;
00367 } else if (buttonMask==GUIEventAdapter::MIDDLE_MOUSE_BUTTON ||
00368 buttonMask==(GUIEventAdapter::LEFT_MOUSE_BUTTON | GUIEventAdapter::RIGHT_MOUSE_BUTTON)) {
00369 desiredEye.z() += -dy;
00370 desiredEye.x() += - c*dx;
00371 desiredEye.y() += - s*dx;
00372 } else if (buttonMask==GUIEventAdapter::RIGHT_MOUSE_BUTTON) {
00373 desiredEye.x() += s*dy - c*dx;
00374 desiredEye.y() += -c*dy - s*dx;
00375 } else return false;
00376 return true;
00377 }
00378
00379
00380
00381 void CameraManipulator::manageAgents(const int& fkey) {
00382
00383 watchingAgentDefined=false;
00384 oldPositionOfAgentDefined=false;
00385 int i=1;
00386
00387 for(OdeAgentList::iterator it=globalData.agents.begin(); it != globalData.agents.end(); it++){
00388 if (fkey==i++) {
00389 watchingAgent=(*it);
00390 watchingAgentDefined=true;
00391 break;
00392 }
00393 }
00394 if (!watchingAgentDefined)
00395 std::cout << "no agent was choosed!\n";
00396 else {
00397 std::cout << "the agent was choosed: " << i-1 << "\n";
00398 setHomeViewByAgent();
00399 setHomeEyeByAgent();
00400 }
00401 }
00402
00403 void CameraManipulator::calcMovementByAgent() {
00404 if (watchingAgentDefined && oldPositionOfAgentDefined) {
00405
00406
00407 }
00408 }
00409
00410 void CameraManipulator::setHomeViewByAgent() {
00411
00412
00413 }
00414
00415 void CameraManipulator::setHomeEyeByAgent() {
00416
00417
00418 }
00419
00420 }
00421