-
originally posted to Discord under "Lerping a Quat is giving me headaches" Hey y'all! 👋 I'm making a Pinball game and working on my flipper mechanics, specifically rotating the flipper. In a match flipper.state {
State::Stationary => {
if flipper.engaged {
flipper.timer.reset();
flipper.state = State::Ascending;
info!("\n*** ASCENDING ***\n");
}
},
State::Ascending => {
if !flipper.engaged {
flipper.timer.reset();
flipper.state = State::Descending;
info!("\n*** DESCENDING ***\n");
break;
}
if flipper.timer.finished() {
break;
}
let lerp = flipper.lerp(step_amount);
let delta_angle = transform.rotation.angle_between(lerp);
// delta rotation to get us to our lerped angle
let delta = Quat::from_rotation_z(delta_angle);
// rotate our pivot point to match the current rotation
let rotated_pivot_point = transform.rotation.mul_vec3(flipper.pivot_point);
// put our pivot point in the right spot
let applied_pivot_point = transform.translation + rotated_pivot_point;
transform.rotate_around(applied_pivot_point, delta);
},
State::Descending => {
if flipper.engaged {
flipper.timer.reset();
flipper.state = State::Ascending;
break;
}
if flipper.timer.finished() {
flipper.state = State::Stationary;
break;
}
let lerp = flipper.lerp(step_amount);
let delta_angle = transform.rotation.angle_between(lerp);
let delta = Quat::from_rotation_z(delta_angle);
let rotated_pivot_point = transform.rotation.mul_vec3(flipper.pivot_point);
let applied_pivot_point = transform.translation + rotated_pivot_point;
transform.rotate_around(applied_pivot_point, delta);
}
} This flips a left-side flipper between -30 degrees to 30 degrees (on creation, it's set at -30 degrees). In the The lerping logic in 2023-02-21T16:29:31.735230Z INFO pinball::systems:
*** ASCENDING ***
2023-02-21T16:29:31.836666Z INFO pinball::prefab::flipper: lerped rotation Quat(0.0, 0.0, -0.20959795, 0.9777877)
2023-02-21T16:29:31.934630Z INFO pinball::prefab::flipper: lerped rotation Quat(0.0, 0.0, -0.15873125, 0.98732185)
2023-02-21T16:29:32.035035Z INFO pinball::prefab::flipper: lerped rotation Quat(0.0, 0.0, -0.106569305, 0.99430525)
2023-02-21T16:29:32.133983Z INFO pinball::prefab::flipper: lerped rotation Quat(0.0, 0.0, -0.053513046, 0.99856716)
2023-02-21T16:29:32.234395Z INFO pinball::prefab::flipper: lerped rotation Quat(0.0, 0.0, 0.0, 1.0)
2023-02-21T16:29:32.334354Z INFO pinball::prefab::flipper: lerped rotation Quat(0.0, 0.0, 0.05351308, 0.99856716)
2023-02-21T16:29:32.433604Z INFO pinball::prefab::flipper: lerped rotation Quat(0.0, 0.0, 0.106569305, 0.99430525)
2023-02-21T16:29:32.533762Z INFO pinball::prefab::flipper: lerped rotation Quat(0.0, 0.0, 0.15873127, 0.98732185)
2023-02-21T16:29:32.634693Z INFO pinball::prefab::flipper: lerped rotation Quat(0.0, 0.0, 0.20959792, 0.9777877)
2023-02-21T16:29:32.736848Z INFO pinball::prefab::flipper: lerped rotation Quat(0.0, 0.0, 0.25881907, 0.9659259)
2023-02-21T16:29:38.931028Z INFO pinball::systems:
...
*** DESCENDING ***
2023-02-21T16:29:39.036703Z INFO pinball::prefab::flipper: lerped rotation Quat(0.0, 0.0, 0.20959795, 0.9777877)
2023-02-21T16:29:39.138400Z INFO pinball::prefab::flipper: lerped rotation Quat(0.0, 0.0, 0.15873125, 0.98732185)
2023-02-21T16:29:39.230040Z INFO pinball::prefab::flipper: lerped rotation Quat(0.0, 0.0, 0.106569305, 0.99430525)
2023-02-21T16:29:39.339916Z INFO pinball::prefab::flipper: lerped rotation Quat(0.0, 0.0, 0.053513046, 0.99856716)
2023-02-21T16:29:39.431818Z INFO pinball::prefab::flipper: lerped rotation Quat(0.0, 0.0, 0.0, 1.0)
2023-02-21T16:29:39.536554Z INFO pinball::prefab::flipper: lerped rotation Quat(0.0, 0.0, -0.05351308, 0.99856716)
2023-02-21T16:29:39.638469Z INFO pinball::prefab::flipper: lerped rotation Quat(0.0, 0.0, -0.106569305, 0.99430525)
2023-02-21T16:29:39.737296Z INFO pinball::prefab::flipper: lerped rotation Quat(0.0, 0.0, -0.15873127, 0.98732185)
2023-02-21T16:29:39.837242Z INFO pinball::prefab::flipper: lerped rotation Quat(0.0, 0.0, -0.20959792, 0.9777877)
2023-02-21T16:29:39.936637Z INFO pinball::prefab::flipper: lerped rotation Quat(0.0, 0.0, -0.25881907, 0.9659259) And the delta angle (calcuated by
But when "descending" from 30 degrees to -30 degrees, the values calculated by
It does a full rotation counter-clockwise to get to the rotation I want. Based on the API docs, I thought it would find the shortest angle (regardless if it's a clockwise motion or counter-clockwise motion):
Am I interpreting this incorrectly? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
I've simplified the system to just do everything in place (specifically, the lerping logic): pub fn flipv3(
fixed_timesteps: Res<FixedTimesteps>,
mut flippers: Query<(&mut Flipper, &mut Transform)>,
) {
let state = fixed_timesteps.get(crate::LABEL).unwrap();
let step_amount = state.step();
for (
mut flipper,
mut transform,
) in flippers.iter_mut() {
let (from_rotation, to_rotation) = match flipper.engaged {
true => (flipper.initial_rotation, flipper.final_rotation),
false => (flipper.final_rotation, flipper.initial_rotation),
};
match flipper.state {
State::Stationary => {
if flipper.engaged {
flipper.timer.reset();
flipper.state = State::Ascending;
}
},
State::Ascending => {
if !flipper.engaged {
if flipper.timer.finished() {
flipper.timer.reset();
} else {
let remaining = flipper.timer.remaining();
flipper.timer.set_elapsed(remaining);
}
flipper.state = State::Descending;
break;
}
if flipper.timer.finished() {
break;
}
let completed = flipper.timer
.tick(Duration::from_secs_f64(step_amount))
.percent();
let lerped_rotation = from_rotation.lerp(to_rotation, completed);
let delta_angle = transform.rotation.angle_between(lerped_rotation);
// delta rotation to get us to our lerped rotation
let delta_rotation = Quat::from_rotation_z(delta_angle);
// rotate our pivot point to match the current rotation
let rotated_pivot_point = transform.rotation.mul_vec3(flipper.pivot_point);
// put our pivot point in the right spot
let applied_pivot_point = transform.translation + rotated_pivot_point;
transform.rotate_around(applied_pivot_point, delta_rotation);
},
State::Descending => {
if flipper.engaged {
if flipper.timer.finished() {
flipper.timer.reset();
} else {
let remaining = flipper.timer.remaining();
flipper.timer.set_elapsed(remaining);
}
flipper.state = State::Ascending;
break;
}
if flipper.timer.finished() {
flipper.state = State::Stationary;
break;
}
let completed = flipper.timer
.tick(Duration::from_secs_f64(step_amount))
.percent();
let lerped_rotation = from_rotation.lerp(to_rotation, completed);
let delta_angle = transform.rotation.angle_between(lerped_rotation);
let delta_rotation = Quat::from_rotation_z(delta_angle);
let rotated_pivot_point = transform.rotation.mul_vec3(flipper.pivot_point);
let applied_pivot_point = transform.translation + rotated_pivot_point;
transform.rotate_around(applied_pivot_point, delta_rotation);
}
}
}
} |
Beta Was this translation helpful? Give feedback.
-
Nevermind: I literally just needed to put a negative in front of my let delta_angle = -transform.rotation.angle_between(lerped_rotation); |
Beta Was this translation helpful? Give feedback.
Nevermind:
I literally just needed to put a negative in front of my
angle_between
call: