@@ -123,7 +123,6 @@ void FreeCam::on_update_transform(RETransform* transform) {
123123 return ;
124124 }
125125
126-
127126#if defined(RE2) || defined(RE3)
128127 static auto get_player_condition_method = sdk::find_method_definition (game_namespace (" SurvivorManager" ), " get_Player" );
129128 static auto get_action_orderer_method = sdk::find_method_definition (game_namespace (" survivor.SurvivorCondition" ), " get_ActionOrderer" );
@@ -167,7 +166,8 @@ void FreeCam::on_update_transform(RETransform* transform) {
167166
168167 m_first_time = false ;
169168
170- m_custom_angles = math::euler_angles (glm::extractMatrixRotation (m_last_camera_matrix));
169+ m_custom_rotation = glm::extractMatrixRotation (m_last_camera_matrix);
170+ m_custom_angles = {}; // per-frame rotation gets reset.
171171 // m_custom_angles[1] *= -1.0f;
172172 // m_custom_angles[1] += glm::radians(180.0f);
173173
@@ -213,17 +213,63 @@ void FreeCam::on_update_transform(RETransform* transform) {
213213
214214 // Controller support
215215 if (pad != nullptr ) {
216+ static const auto gamepad_device_t = sdk::find_type_definition (" via.hid.GamePadDevice" );
217+ static const auto is_down = gamepad_device_t != nullptr ? gamepad_device_t ->get_method (" isDown(via.hid.GamePadButton)" ) : nullptr ;
218+
216219 // Move direction
217220 // It's not a Vector2f because via.vec2 is not actually 8 bytes, we don't want stack corruption to occur.
218221 const auto axis_l = *re_managed_object::get_field<Vector3f*>(pad, " AxisL" );
219222 const auto axis_r = *re_managed_object::get_field<Vector3f*>(pad, " AxisR" );
220223
221- m_custom_angles[0 ] += axis_r.y * rotation_speed * delta * timescale_mult;
222- m_custom_angles[1 ] -= axis_r.x * rotation_speed * delta * timescale_mult;
223- m_custom_angles[2 ] = 0 .0f ;
224+ bool is_using_up_down_modifier = false ;
225+ bool is_using_twist_modifier = false ;
226+
227+ if (is_down != nullptr ) {
228+ const auto dpad_up_is_down = is_down->call_safe <bool >(sdk::get_thread_context (), pad, via::hid::GamePadButton::LUp);
229+ const auto dpad_down_is_down = is_down->call_safe <bool >(sdk::get_thread_context (), pad, via::hid::GamePadButton::LDown);
230+
231+ if (dpad_up_is_down) {
232+ dir.y = 1 .0f ;
233+ } else if (dpad_down_is_down) {
234+ dir.y = -1 .0f ;
235+ }
236+
237+ const auto dpad_left_is_down = is_down->call_safe <bool >(sdk::get_thread_context (), pad, via::hid::GamePadButton::LLeft);
238+ const auto dpad_right_is_down = is_down->call_safe <bool >(sdk::get_thread_context (), pad, via::hid::GamePadButton::LRight);
239+
240+ if (dpad_left_is_down) {
241+ dir.x -= 1 .0f ;
242+ } else if (dpad_right_is_down) {
243+ dir.x += 1 .0f ;
244+ }
245+
246+ const auto l_trigger_is_down = is_down->call_safe <bool >(sdk::get_thread_context (), pad, via::hid::GamePadButton::LTrigBottom);
247+
248+ if (l_trigger_is_down) {
249+ if (glm::length (axis_r) > 0 .0f ) {
250+ dir += Vector4f{ 0.0 , axis_r.y , 0.0 , 0 .0f };
251+ is_using_up_down_modifier = true ;
252+ }
253+ }
254+
255+ const auto r_trigger_is_down = is_down->call_safe <bool >(sdk::get_thread_context (), pad, via::hid::GamePadButton::RTrigBottom);
256+
257+ if (r_trigger_is_down) {
258+ if (glm::length (axis_r) > 0 .0f ) {
259+ m_custom_angles[2 ] -= axis_r.x * rotation_speed * delta * timescale_mult;
260+ is_using_twist_modifier = true ;
261+ }
262+ }
263+ }
264+
265+ if (!is_using_up_down_modifier && !is_using_twist_modifier) {
266+ m_custom_angles[0 ] += axis_r.y * rotation_speed * delta * timescale_mult;
267+ m_custom_angles[1 ] -= axis_r.x * rotation_speed * delta * timescale_mult;
268+ // m_custom_angles[2] = 0.0f;
269+ }
224270
225271 if (glm::length (axis_l) > 0 .0f ) {
226- dir = Vector4f{ axis_l.x , 0 .0f , axis_l.y * -1 .0f , 0 .0f };
272+ dir + = Vector4f{ axis_l.x , 0 .0f , axis_l.y * -1 .0f , 0 .0f };
227273 }
228274 }
229275
@@ -252,19 +298,28 @@ void FreeCam::on_update_transform(RETransform* transform) {
252298 dir_speed *= dir_speed_mod_slow;
253299 }
254300
255- const auto & mouse_delta = g_framework->get_mouse_delta ();
301+ if (!g_framework->is_ui_focused ()) {
302+ const auto & mouse_delta = g_framework->get_mouse_delta ();
256303
257- m_custom_angles[0 ] -= mouse_delta[1 ] * rotation_speed_kbm * delta * timescale_mult;
258- m_custom_angles[1 ] -= mouse_delta[0 ] * rotation_speed_kbm * delta * timescale_mult;
259- m_custom_angles[2 ] = 0 .0f ;
304+ if (keyboard_state[VK_RBUTTON ]) {
305+ m_custom_angles[2 ] -= mouse_delta[0 ] * rotation_speed_kbm * delta * timescale_mult;
306+ } else {
307+ m_custom_angles[0 ] -= mouse_delta[1 ] * rotation_speed_kbm * delta * timescale_mult;
308+ m_custom_angles[1 ] -= mouse_delta[0 ] * rotation_speed_kbm * delta * timescale_mult;
309+ }
310+ }
260311
261312 math::fix_angles (m_custom_angles);
262313
263- const auto new_rotation = Matrix4x4f{ glm::quat{ m_custom_angles } };
264- const auto new_pos = m_last_camera_matrix[3 ] + new_rotation * dir * (dir_speed * delta * timescale_mult);
314+ if (glm::length (m_custom_angles) > 0 .0f ) {
315+ m_custom_rotation *= glm::quat{ m_custom_angles };
316+ m_custom_angles = {};
317+ }
318+
319+ const auto new_pos = m_last_camera_matrix[3 ] + m_custom_rotation * dir * (dir_speed * delta * timescale_mult);
265320
266321 // Keep track of the rotation if we want to lock the camera
267- m_last_camera_matrix = new_rotation ;
322+ m_last_camera_matrix = glm::mat4{m_custom_rotation} ;
268323 m_last_camera_matrix[3 ] = new_pos;
269324 }
270325
0 commit comments