/
VirtualTrackballCamera.cpp
55 lines (43 loc) · 1.65 KB
/
VirtualTrackballCamera.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include "src/base/VirtualTrackballCamera.h"
#include "src/base/utility.hpp"
#include <iostream>
#define M_PI 3.14159
VirtualTrackballCamera::VirtualTrackballCamera()
{
}
VirtualTrackballCamera::VirtualTrackballCamera(Hemisphere h, FW::Vec2f mouse_pose) :
h_(h),
camera_transformation_(FW::Mat4f())
{
ResetCamera(mouse_pose);
}
const FW::Mat4f& VirtualTrackballCamera::GetCameraTransform()
{
return camera_transformation_;
}
void VirtualTrackballCamera::UpdateCamera(FW::Vec2f new_mouse_pose)
{
const FW::Vec3f new_projected_position = ProjectToHemisphere(new_mouse_pose);
const FW::Vec3f delta_pos = new_projected_position - last_projected_position_;
if(delta_pos.x || delta_pos.y || delta_pos.z) //todo ?????
{
float angle = 90 * FW::length(delta_pos);
FW::Vec3f axis = FW::cross(last_projected_position_, new_projected_position);
camera_transformation_ = CustomMath::ToMat4(FW::Mat3f::rotation(axis.normalized(), angle * M_PI / 180.f)) * camera_transformation_;
last_projected_position_ = new_projected_position;
}
}
void VirtualTrackballCamera::ResetCamera(FW::Vec2f mouse_pose)
{
last_projected_position_ = ProjectToHemisphere(mouse_pose);
}
FW::Vec3f VirtualTrackballCamera::ProjectToHemisphere(FW::Vec2f mouse_pos)
{
float d; //, a;
FW::Vec3f projected_point;
projected_point.x = (2.0f * mouse_pos.x - h_.width) / h_.width;
projected_point.y = (h_.height - 2.0F * mouse_pos.y)/ h_.height;
d = FW::sqrt((projected_point.x * projected_point.x) + (projected_point.y * projected_point.y));
projected_point.z = cos((M_PI / 2.0f) * ((d < 1.0f) ? d : 1.0f));
return projected_point.normalized();
}