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 #include "glm/gtx/quaternion.hpp"
00020 
00021 namespace {
00022 // Render camera observation distance in third person camera mode.
00023 const float kThirdPersonCameraDist = 7.0f;
00024 
00025 // Render camera observation distance in third person camera mode.
00026 const float kThirdPersonFollowCameraDist = 2.0f;
00027 
00028 // Render camera observation distance in top down camera mode.
00029 const float kTopDownCameraDist = 5.0f;
00030 
00031 // Zoom in speed.
00032 const float kZoomSpeed = 10.0f;
00033 
00034 // Move speed
00035 const float kMoveSpeed = 10.0f;
00036 
00037 // Rotation speed
00038 const float kRotationSpeed = 2.0f;
00039 
00040 // Min/max clamp value of camera observation distance.
00041 const float kCamViewMinDist = .1f;
00042 const float kCamViewMaxDist = 100.f;
00043 
00044 // FOV set up values.
00045 // Third and top down camera's FOV is 65 degrees.
00046 // First person camera's FOV is 45 degrees.
00047 const float kHighFov = 65.0f;
00048 const float kLowFov = 65.0f;
00049 }
00050 
00051 namespace tango_gl {
00052 
00053 GestureCamera::GestureCamera() :
00054                 cam_cur_target_rot_(1,0,0,0),
00055                 start_touch_dist_(0.0f),
00056                 cur_touch_dist_(0.0f)
00057 {
00058   cam_parent_transform_ = new Transform();
00059   SetParent(cam_parent_transform_);
00060 }
00061 
00062 GestureCamera::~GestureCamera() { delete cam_parent_transform_; }
00063 
00064 void GestureCamera::OnTouchEvent(int touch_count, TouchEvent event, float x0,
00065                 float y0, float x1, float y1) {
00066 
00067         if (camera_type_!=kFirstPerson && touch_count == 1) {
00068                 switch (event) {
00069                 case kTouch0Down: {
00070                         cam_start_angle_ = cam_cur_angle_;
00071 
00072                         touch0_start_position_.x = x0;
00073                         touch0_start_position_.y = y0;
00074                         break;
00075                 }
00076                 case kTouchMove: {
00077                         glm::vec2 offset;
00078 
00079                         float rotation_x = (touch0_start_position_.y - y0) * kRotationSpeed;
00080                         float rotation_y = (touch0_start_position_.x - x0) * kRotationSpeed;
00081 
00082                         if(camera_type_!=kTopOrtho)
00083                                 cam_cur_angle_.x = cam_start_angle_.x + rotation_x;
00084                         cam_cur_angle_.y = cam_start_angle_.y + rotation_y;
00085 
00086                         StartCameraToCurrentTransform();
00087 
00088                         break;
00089                 }
00090                 default: { break; }
00091                 }
00092         }
00093         if (touch_count == 2) {
00094                 switch (event) {
00095                 case kTouch1Down: {
00096                         float abs_x = x0 - x1;
00097                         float abs_y = y0 - y1;
00098                         start_touch_dist_ = std::sqrt(abs_x * abs_x + abs_y * abs_y);
00099                         cam_start_dist_ = GetPosition().z;
00100                         cam_start_fov_ = this->getFOV();
00101 
00102                         // center touch
00103                         touch0_start_position_.x = (x0+x1)/2.0f;
00104                         touch0_start_position_.y = (y0+y1)/2.0f;
00105                         break;
00106                 }
00107                 case kTouchMove: {
00108                         float abs_x = x0 - x1;
00109                         float abs_y = y0 - y1;
00110                         float dist = start_touch_dist_ - std::sqrt(abs_x * abs_x + abs_y * abs_y);
00111 
00112                         if(camera_type_ == kFirstPerson)
00113                         {
00114                                 this->SetFieldOfView(tango_gl::util::Clamp(cam_start_fov_ + dist * kZoomSpeed*10.0f, 45, 90));
00115                         }
00116                         else
00117                         {
00118                                 cam_cur_dist_ = tango_gl::util::Clamp(cam_start_dist_ + dist * kZoomSpeed,
00119                                                                 kCamViewMinDist, kCamViewMaxDist);
00120 
00121                                 this->SetOrthoMode(camera_type_ == kTopOrtho);
00122                                 if(camera_type_ == kTopOrtho)
00123                                 {
00124                                         this->SetOrthoScale(cam_cur_dist_);
00125                                 }
00126 
00127                                 glm::vec2 touch_center_position((x0+x1)/2.0f, (y0+y1)/2.0f);
00128                                 glm::vec2 offset;
00129                                 offset.x = (touch_center_position.x - touch0_start_position_.x) * kMoveSpeed;
00130                                 offset.y = (touch_center_position.y - touch0_start_position_.y) * kMoveSpeed;
00131                                 touch0_start_position_ = touch_center_position;
00132 
00133                                 StartCameraToCurrentTransform();
00134 
00135                                 anchor_offset_ += glm::rotate(cam_parent_transform_->GetRotation(), glm::vec3(-offset.x, offset.y, 0));
00136                         }
00137                         break;
00138                 }
00139                 default: { break; }
00140                 }
00141         }
00142 }
00143 
00144 Segment GestureCamera::GetSegmentFromTouch(float normalized_x,
00145                                            float normalized_y,
00146                                            float touch_range) {
00147   float screen_height = touch_range * (2.0f * glm::tan(field_of_view_ * 0.5f));
00148   float screen_width = screen_height * aspect_ratio_;
00149   // normalized_x and normalized_x are from OnTouchEvent, top-left corner of the
00150   // screen
00151   // is [0, 0], transform it to opengl frame.
00152   normalized_x = normalized_x - 0.5f;
00153   normalized_y = 0.5f - normalized_y;
00154   glm::vec3 start =
00155       util::ApplyTransform(GetTransformationMatrix(), glm::vec3(0, 0, 0));
00156   glm::vec3 end = util::ApplyTransform(GetTransformationMatrix(), 
00157       glm::vec3(normalized_x * screen_width, normalized_y * screen_height,
00158                 -touch_range));
00159   Segment segment(start, end);
00160   return segment;
00161 }
00162 
00163 void GestureCamera::SetAnchorPosition(const glm::vec3& pos, const glm::quat & rotation) {
00164         // Anchor position
00165         cam_parent_transform_->SetPosition(pos+anchor_offset_);
00166 
00167         // Anchor rotation
00168         if(camera_type_ == kThirdPersonFollow)
00169         {
00170                 cam_cur_target_rot_ = rotation;
00171                 cam_cur_target_rot_.x = 0;
00172                 cam_cur_target_rot_.z = 0;
00173                 cam_cur_target_rot_ = glm::normalize(cam_cur_target_rot_);
00174                 StartCameraToCurrentTransform();
00175         }
00176 }
00177 
00178 void GestureCamera::SetCameraType(CameraType camera_index) {
00179   camera_type_ = camera_index;
00180   switch (camera_index) {
00181     case kFirstPerson:
00182         SetOrthoMode(false);
00183       SetFieldOfView(kLowFov);
00184       SetPosition(glm::vec3(0.0f, 0.0f, 0.0f));
00185       SetRotation(glm::quat(1.0f, 0.0f, 0.0f, 0.0f));
00186       cam_cur_dist_ = 0.0f;
00187       anchor_offset_ = glm::vec3(0.0f,0.0f,0.0f);
00188       cam_cur_angle_.x = 0.0f;
00189       cam_cur_angle_.y = 0.0f;
00190       cam_cur_target_rot_ = glm::quat(1,0,0,0);
00191       cam_parent_transform_->SetPosition(glm::vec3(0.0f, 0.0f, 0.0f));
00192       StartCameraToCurrentTransform();
00193       break;
00194     case kThirdPerson:
00195     case kThirdPersonFollow:
00196         SetOrthoMode(false);
00197         SetFieldOfView(kHighFov);
00198       SetPosition(glm::vec3(0.0f, 0.0f, 0.0f));
00199       SetRotation(glm::quat(1.0f, 0.0f, 0.0f, 0.0f));
00200       cam_cur_dist_ = kThirdPersonFollow?kThirdPersonFollowCameraDist:kThirdPersonCameraDist;
00201       anchor_offset_ = glm::vec3(0.0f,0.0f,0.0f);
00202       cam_cur_angle_.x = -M_PI / 6.0f;
00203       cam_cur_angle_.y = kThirdPersonFollow?0:M_PI / 4.0f;
00204       cam_cur_target_rot_ = glm::quat(1,0,0,0);
00205       StartCameraToCurrentTransform();
00206       break;
00207     case kTopDown:
00208       SetPosition(glm::vec3(0.0f, 0.0f, 0.0f));
00209       SetRotation(glm::quat(1.0f, 0.0f, 0.0f, 0.0f));
00210       SetOrthoMode(false);
00211       SetFieldOfView(kHighFov);
00212       cam_cur_dist_ = kTopDownCameraDist;
00213       anchor_offset_ = glm::vec3(0.0f,0.0f,0.0f);
00214       cam_cur_angle_.x = -M_PI / 2.0f;
00215       cam_cur_angle_.y = 0.0f;
00216       cam_cur_target_rot_ = glm::quat(1,0,0,0);
00217       StartCameraToCurrentTransform();
00218       break;
00219     case kTopOrtho:
00220           SetPosition(glm::vec3(0.0f, 0.0f, 0.0f));
00221           SetRotation(glm::quat(1.0f, 0.0f, 0.0f, 0.0f));
00222           SetOrthoMode(true);
00223           SetOrthoScale(kTopDownCameraDist);
00224           SetOrthoCropFactor(-1.0f);
00225           cam_cur_dist_ = kTopDownCameraDist;
00226           anchor_offset_ = glm::vec3(0.0f,0.0f,0.0f);
00227           cam_cur_angle_.x = -M_PI / 2.0f;
00228           cam_cur_angle_.y = 0.0f;
00229           cam_cur_target_rot_ = glm::quat(1,0,0,0);
00230           StartCameraToCurrentTransform();
00231           break;
00232     default:
00233       break;
00234   }
00235 }
00236 
00237 void GestureCamera::StartCameraToCurrentTransform()
00238 {
00239   //Anchor rotation
00240   glm::quat parent_cam_rot = glm::rotate(cam_cur_target_rot_, cam_cur_angle_.y, glm::vec3(0, 1, 0));
00241   parent_cam_rot = glm::rotate(parent_cam_rot, cam_cur_angle_.x, glm::vec3(1, 0, 0));
00242   cam_parent_transform_->SetRotation(parent_cam_rot);
00243 
00244   //Camera position
00245   SetPosition(glm::vec3(0, 0, cam_cur_dist_));
00246 }
00247 }  // namespace tango_gl


rtabmap
Author(s): Mathieu Labbe
autogenerated on Thu Jun 6 2019 21:59:20