00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "tango-gl/gesture_camera.h"
00018 #include "tango-gl/util.h"
00019
00020 namespace {
00021
00022 const float kThirdPersonCameraDist = 7.0f;
00023
00024
00025 const float kThirdPersonFollowCameraDist = 2.0f;
00026
00027
00028 const float kTopDownCameraDist = 5.0f;
00029
00030
00031 const float kZoomSpeed = 10.0f;
00032
00033
00034 const float kCamViewMinDist = 1.0f;
00035 const float kCamViewMaxDist = 100.f;
00036
00037
00038
00039
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
00115
00116
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 }