gesture_camera.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2014 Google Inc. All Rights Reserved.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *      http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "tango-gl/gesture_camera.h"
00018 #include "tango-gl/util.h"
00019 
00020 namespace {
00021 // Render camera observation distance in third person camera mode.
00022 const float kThirdPersonCameraDist = 7.0f;
00023 
00024 // Render camera observation distance in third person camera mode.
00025 const float kThirdPersonFollowCameraDist = 2.0f;
00026 
00027 // Render camera observation distance in top down camera mode.
00028 const float kTopDownCameraDist = 5.0f;
00029 
00030 // Zoom in speed.
00031 const float kZoomSpeed = 10.0f;
00032 
00033 // Min/max clamp value of camera observation distance.
00034 const float kCamViewMinDist = 1.0f;
00035 const float kCamViewMaxDist = 100.f;
00036 
00037 // FOV set up values.
00038 // Third and top down camera's FOV is 65 degrees.
00039 // First person camera's FOV is 45 degrees.
00040 const float kHighFov = 65.0f;
00041 const float kLowFov = 65.0f;
00042 }
00043 
00044 namespace tango_gl {
00045 
00046 GestureCamera::GestureCamera() :
00047                 cam_cur_target_rot_(1,0,0,0),
00048                 start_touch_dist_(0.0f),
00049                 cur_touch_dist_(0.0f)
00050 {
00051   cam_parent_transform_ = new Transform();
00052   SetParent(cam_parent_transform_);
00053 }
00054 
00055 GestureCamera::~GestureCamera() { delete cam_parent_transform_; }
00056 
00057 void GestureCamera::OnTouchEvent(int touch_count, TouchEvent event, float x0,
00058                                  float y0, float x1, float y1) {
00059   if (camera_type_ == kFirstPerson) {
00060     return;
00061   }
00062 
00063   if (touch_count == 1) {
00064     switch (event) {
00065       case kTouch0Down: {
00066         cam_start_angle_ = cam_cur_angle_;
00067 
00068         touch0_start_position_.x = x0;
00069         touch0_start_position_.y = y0;
00070         break;
00071       }
00072       case kTouchMove: {
00073         float rotation_x = touch0_start_position_.y - y0;
00074         float rotation_y = touch0_start_position_.x - x0;
00075 
00076         cam_cur_angle_.x = cam_start_angle_.x + rotation_x;
00077         cam_cur_angle_.y = cam_start_angle_.y + rotation_y;
00078         StartCameraToCurrentTransform();
00079         break;
00080       }
00081       default: { break; }
00082     }
00083   }
00084   if (touch_count == 2) {
00085     switch (event) {
00086       case kTouch1Down: {
00087         float abs_x = x0 - x1;
00088         float abs_y = y0 - y1;
00089         start_touch_dist_ = std::sqrt(abs_x * abs_x + abs_y * abs_y);
00090         cam_start_dist_ = GetPosition().z;
00091         break;
00092       }
00093       case kTouchMove: {
00094         float abs_x = x0 - x1;
00095         float abs_y = y0 - y1;
00096         float dist =
00097             start_touch_dist_ - std::sqrt(abs_x * abs_x + abs_y * abs_y);
00098         cam_cur_dist_ =
00099             tango_gl::util::Clamp(cam_start_dist_ + dist * kZoomSpeed,
00100                                   kCamViewMinDist, kCamViewMaxDist);
00101         StartCameraToCurrentTransform();
00102         break;
00103       }
00104       default: { break; }
00105     }
00106   }
00107 }
00108 
00109 Segment GestureCamera::GetSegmentFromTouch(float normalized_x,
00110                                            float normalized_y,
00111                                            float touch_range) {
00112   float screen_height = touch_range * (2.0f * glm::tan(field_of_view_ * 0.5f));
00113   float screen_width = screen_height * aspect_ratio_;
00114   // normalized_x and normalized_x are from OnTouchEvent, top-left corner of the
00115   // screen
00116   // is [0, 0], transform it to opengl frame.
00117   normalized_x = normalized_x - 0.5f;
00118   normalized_y = 0.5f - normalized_y;
00119   glm::vec3 start =
00120       util::ApplyTransform(GetTransformationMatrix(), glm::vec3(0, 0, 0));
00121   glm::vec3 end = util::ApplyTransform(GetTransformationMatrix(), 
00122       glm::vec3(normalized_x * screen_width, normalized_y * screen_height,
00123                 -touch_range));
00124   Segment segment(start, end);
00125   return segment;
00126 }
00127 
00128 void GestureCamera::SetAnchorPosition(const glm::vec3& pos, const glm::quat & rotation) {
00129         cam_parent_transform_->SetPosition(pos);
00130         if(camera_type_ == kThirdPersonFollow)
00131         {
00132                 cam_cur_target_rot_ = rotation;
00133                 cam_cur_target_rot_.x = 0;
00134                 cam_cur_target_rot_.z = 0;
00135                 cam_cur_target_rot_ = glm::normalize(cam_cur_target_rot_);
00136                 StartCameraToCurrentTransform();
00137         }
00138 }
00139 
00140 void GestureCamera::SetCameraType(CameraType camera_index) {
00141   camera_type_ = camera_index;
00142   switch (camera_index) {
00143     case kFirstPerson:
00144       SetFieldOfView(kLowFov);
00145       SetPosition(glm::vec3(0.0f, 0.0f, 0.0f));
00146       SetRotation(glm::quat(1.0f, 0.0f, 0.0f, 0.0f));
00147       cam_cur_dist_ = 0.0f;
00148       cam_cur_angle_.x = 0.0f;
00149       cam_cur_angle_.y = 0.0f;
00150       cam_cur_target_rot_ = glm::quat(1,0,0,0);
00151       cam_parent_transform_->SetPosition(glm::vec3(0.0f, 0.0f, 0.0f));
00152       StartCameraToCurrentTransform();
00153       break;
00154     case kThirdPerson:
00155     case kThirdPersonFollow:
00156       SetFieldOfView(kHighFov);
00157       SetPosition(glm::vec3(0.0f, 0.0f, 0.0f));
00158       SetRotation(glm::quat(1.0f, 0.0f, 0.0f, 0.0f));
00159       cam_cur_dist_ = kThirdPersonFollow?kThirdPersonFollowCameraDist:kThirdPersonCameraDist;
00160       cam_cur_angle_.x = -M_PI / 4.0f;
00161       cam_cur_angle_.y = kThirdPersonFollow?0:M_PI / 4.0f;
00162       cam_cur_target_rot_ = glm::quat(1,0,0,0);
00163       StartCameraToCurrentTransform();
00164       break;
00165     case kTopDown:
00166       SetFieldOfView(kHighFov);
00167       SetPosition(glm::vec3(0.0f, 0.0f, 0.0f));
00168       SetRotation(glm::quat(1.0f, 0.0f, 0.0f, 0.0f));
00169       cam_cur_dist_ = kTopDownCameraDist;
00170       cam_cur_angle_.x = -M_PI / 2.0f;
00171       cam_cur_angle_.y = 0.0f;
00172       cam_cur_target_rot_ = glm::quat(1,0,0,0);
00173       StartCameraToCurrentTransform();
00174       break;
00175     default:
00176       break;
00177   }
00178 }
00179 
00180 void GestureCamera::StartCameraToCurrentTransform()
00181 {
00182   glm::quat parent_cam_rot = glm::rotate(cam_cur_target_rot_, cam_cur_angle_.y, glm::vec3(0, 1, 0));
00183   parent_cam_rot = glm::rotate(parent_cam_rot, cam_cur_angle_.x, glm::vec3(1, 0, 0));
00184   SetPosition(glm::vec3(0.0f, 0.0f, cam_cur_dist_));
00185   cam_parent_transform_->SetRotation(parent_cam_rot);
00186 }
00187 }  // namespace tango_gl


rtabmap
Author(s): Mathieu Labbe
autogenerated on Sat Jul 23 2016 11:44:16