@@ -10,8 +10,17 @@ CameraController::CameraController(Type type, glm::vec3 camera_position)
1010 camera = std::make_unique<Camera>(camera_position, camera_position + direction);
1111}
1212
13- void CameraController::update (float delta_time, bool handle_scroll)
13+ void CameraController::update (float delta_time, bool handle_input, bool handle_scroll)
1414{
15+ if (m_animation.active ) {
16+ update_animation (delta_time);
17+ return ;
18+ }
19+
20+ if (!handle_input) {
21+ return ;
22+ }
23+
1524 switch (type) {
1625 case Type::FREECAM:
1726 update_freecam (delta_time, handle_scroll);
@@ -25,6 +34,71 @@ void CameraController::update(float delta_time, bool handle_scroll)
2534 }
2635}
2736
37+ void CameraController::animate_to (glm::vec3 position, glm::vec3 target, float duration)
38+ {
39+ m_animation.active = true ;
40+ m_animation.position = position;
41+ m_animation.target = target;
42+ m_animation.remaining_time = duration;
43+ }
44+
45+ void CameraController::focus_on (InstancedNode const & node)
46+ {
47+ auto const duration = 0 .3f ;
48+
49+ auto const world_center = glm::vec3{node.model_matrix * glm::vec4{0 .0f , 0 .0f , 0 .0f , 1 .0f }};
50+ auto radius = 0 .0f ;
51+ node.traverse ([&](glm::mat4 model_matrix, Node const & node) {
52+ for (auto const & mesh : node.meshes ) {
53+ auto const world_aabb_min = model_matrix * glm::vec4{mesh.aabb .min , 1 .0f };
54+ auto const world_aabb_max = model_matrix * glm::vec4{mesh.aabb .max , 1 .0f };
55+ radius = std::max (radius, std::abs (world_center.x - world_aabb_min.x ));
56+ radius = std::max (radius, std::abs (world_center.y - world_aabb_min.y ));
57+ radius = std::max (radius, std::abs (world_center.z - world_aabb_min.z ));
58+ radius = std::max (radius, std::abs (world_center.x - world_aabb_max.x ));
59+ radius = std::max (radius, std::abs (world_center.y - world_aabb_max.y ));
60+ radius = std::max (radius, std::abs (world_center.z - world_aabb_max.z ));
61+ }
62+ });
63+
64+ if (radius < 0 .1f ) {
65+ return ;
66+ }
67+
68+ auto const distance = radius * 1 .5f ;
69+
70+ auto const look_direction = glm::normalize (camera->target - camera->position );
71+
72+ switch (type) {
73+ case Type::FREECAM:
74+ case Type::UNITY: {
75+ auto const target_position = world_center - look_direction * distance;
76+ animate_to (target_position, target_position + look_direction, duration);
77+ break ;
78+ }
79+ case Type::BLENDER: {
80+ }
81+ animate_to (world_center - look_direction * distance, world_center, duration);
82+ }
83+ }
84+
85+ void CameraController::update_animation (float delta_time)
86+ {
87+ if (!m_animation.active ) {
88+ return ;
89+ }
90+
91+ auto factor = delta_time / m_animation.remaining_time ;
92+ m_animation.remaining_time -= delta_time;
93+ if (factor >= 1 .0f ) {
94+ factor = 1 .0f ;
95+ m_animation.active = false ;
96+ }
97+
98+ camera->target = factor * m_animation.target + (1 - factor) * camera->target ;
99+ camera->position = factor * m_animation.position + (1 - factor) * camera->position ;
100+ }
101+
28102std::pair<float , float > direction_to_yaw_pitch (glm::vec3 direction)
29103{
30104 float pitch = std::asin (direction.y );
0 commit comments