From fffd005178a59877a0072be6c1f4ed50f1e888a7 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sun, 18 Oct 2020 14:32:13 -0500 Subject: [PATCH 1/2] WiimoteEmu: Allow tilt to wrap around and simulate full 360 degree rotations. --- Source/Core/Core/HW/WiimoteEmu/Dynamics.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Source/Core/Core/HW/WiimoteEmu/Dynamics.cpp b/Source/Core/Core/HW/WiimoteEmu/Dynamics.cpp index 0f5532d58a..43bf5e0ce9 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Dynamics.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Dynamics.cpp @@ -120,9 +120,19 @@ void EmulateTilt(RotationalState* state, ControllerEmu::Tilt* const tilt_group, const ControlState roll = target.x * MathUtil::PI; const ControlState pitch = target.y * MathUtil::PI; + const auto target_angle = Common::Vec3(pitch, -roll, 0); + + // For each axis, wrap around current angle if target is farther than 180 degrees. + for (std::size_t i = 0; i != target_angle.data.size(); ++i) + { + auto& angle = state->angle.data[i]; + if (std::abs(angle - target_angle.data[i]) > float(MathUtil::PI)) + angle -= std::copysign(MathUtil::TAU, angle); + } + const auto max_accel = std::pow(tilt_group->GetMaxRotationalVelocity(), 2) / MathUtil::TAU; - ApproachAngleWithAccel(state, Common::Vec3(pitch, -roll, 0), max_accel, time_elapsed); + ApproachAngleWithAccel(state, target_angle, max_accel, time_elapsed); } void EmulateSwing(MotionState* state, ControllerEmu::Force* swing_group, float time_elapsed) From 4bb0a885d0e61b069f4129f8358dcbe3a4db34b1 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sun, 18 Oct 2020 15:16:08 -0500 Subject: [PATCH 2/2] WiimoteEmu/DolphinQt: Fix tilt indicator for wrapped around angles. --- .../DolphinQt/Config/Mapping/MappingIndicator.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp index fa47c36630..b44c8c803e 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp @@ -415,8 +415,18 @@ void TiltIndicator::Draw() { WiimoteEmu::EmulateTilt(&m_motion_state, &m_group, 1.f / INDICATOR_UPDATE_FREQ); - const auto adj_coord = - Common::DVec2{-m_motion_state.angle.y, m_motion_state.angle.x} / MathUtil::PI; + auto adj_coord = Common::DVec2{-m_motion_state.angle.y, m_motion_state.angle.x} / MathUtil::PI; + + // Angle values after dividing by pi. + constexpr auto norm_180_deg = 1; + constexpr auto norm_360_deg = 2; + + // Angle may extend beyond 180 degrees when wrapping around. + // Apply modulo to draw within the indicator. + // Scale down the value a bit so +1 does not become -1. + adj_coord *= 0.9999f; + adj_coord.x = std::fmod(adj_coord.x + norm_360_deg + norm_180_deg, norm_360_deg) - norm_180_deg; + adj_coord.y = std::fmod(adj_coord.y + norm_360_deg + norm_180_deg, norm_360_deg) - norm_180_deg; DrawReshapableInput(m_group, TILT_GATE_COLOR, (adj_coord.x || adj_coord.y) ? std::make_optional(adj_coord) : std::nullopt);