pub struct SegmentedJumpInitialVelocityCalculator { /* private fields */ }
Expand description
Calculate the kinetic energy required to jump to a certain height when different gravity is applied in different segments of the jump.
MOTIVATION: Ballistically accurate jumps where the gravity is constant don’t feel good in
games. To improve the player experience, Tnua applies higher gravity in different segments of
the jump (e.g. to get faster takeoff or to reduce the airtime at the tip of the jump). Being
able to control the height of the jump is still vital though, and needs to be done by setting
the initial upward velocity of the jump. SegmentedJumpInitialVelocityCalculator
is a tool for
calculating the latter from the former.
let takeoff_upward_velocity = SegmentedJumpInitialVelocityCalculator::new(jump_height)
// When upward velocity is below 1.0, use an extra gravity of 20.0
.add_segment(GRAVITY + 20.0, 1.0)
// When upward velocity is between 1.0 and 2.0, use regular gravity
.add_segment(GRAVITY, 2.0)
// When upward velocity is higher than 2.0, use an extra gravity of 30.0
.add_final_segment(GRAVITY + 30.0)
// After adding all the segments, get the velocity required to make such a jump
.required_initial_velocity()
.expect("`add_final_segment` should have covered remaining height");
Note that:
- Only the part of the jump where the character goes up is relevant here. The part after the
peak where the character goes down may have its own varying gravity, but since that gravity
can not affect the height of the jump
SegmentedJumpInitialVelocityCalculator
does not need to care about it. - Segments are calculated from top to bottom. The very top - the peak of the jump - has, by
definition, zero upward velocity, so the
velocity_threshold
passed to it is the one at the bottom. The last segment should haveINFINITY
as its velocity. - The internal representation and calculation is with kinetic energy for a rigid body with a mass of 1.0 rather than with velocities.
Implementations§
Source§impl SegmentedJumpInitialVelocityCalculator
impl SegmentedJumpInitialVelocityCalculator
Sourcepub fn new(total_height: Float) -> Self
pub fn new(total_height: Float) -> Self
Create a SegmentedJumpInitialVelocityCalculator
ready to calculate the velocity required
for a jump of the specified height.
Sourcepub fn add_segment(
&mut self,
gravity: Float,
velocity_threshold: Float,
) -> &mut Self
pub fn add_segment( &mut self, gravity: Float, velocity_threshold: Float, ) -> &mut Self
Convert height to kinetic energy for segment under the given gravity.
The segment is specified by velocity. The bottom determined by the velocity_threshold
argument and the top is the bottom of the previous call to add_segment
- or the peak of
the jump, if this is the first call.
If there is no height left to convert, nothing will be changed.
Sourcepub fn add_final_segment(&mut self, gravity: Float) -> &mut Self
pub fn add_final_segment(&mut self, gravity: Float) -> &mut Self
Convert the remaining height to kinetic energy under the given gravity.
Sourcepub fn kinetic_energy(&self) -> Result<Float, LeftoverHeight>
pub fn kinetic_energy(&self) -> Result<Float, LeftoverHeight>
The kinetic energy required to make the jump.
This should only be called after all the height was converted - otherwise it’ll return a
LeftoverHeight
error.
Sourcepub fn kinetic_energy_to_velocity(kinetic_energy: Float) -> Float
pub fn kinetic_energy_to_velocity(kinetic_energy: Float) -> Float
Convert kinetic energy to velocity for a rigid body with a mass of 1.0.
Sourcepub fn required_initial_velocity(&self) -> Result<Float, LeftoverHeight>
pub fn required_initial_velocity(&self) -> Result<Float, LeftoverHeight>
The initial upward velocity required to make the jump.
This should only be called after all the height was converted - otherwise it’ll return a
LeftoverHeight
error.
Auto Trait Implementations§
impl Freeze for SegmentedJumpInitialVelocityCalculator
impl RefUnwindSafe for SegmentedJumpInitialVelocityCalculator
impl Send for SegmentedJumpInitialVelocityCalculator
impl Sync for SegmentedJumpInitialVelocityCalculator
impl Unpin for SegmentedJumpInitialVelocityCalculator
impl UnwindSafe for SegmentedJumpInitialVelocityCalculator
Blanket Implementations§
Source§impl<T, U> AsBindGroupShaderType<U> for T
impl<T, U> AsBindGroupShaderType<U> for T
Source§fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
T
ShaderType
for self
. When used in AsBindGroup
derives, it is safe to assume that all images in self
exist.Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
. Box<dyn Any>
can
then be further downcast
into Box<ConcreteType>
where ConcreteType
implements Trait
.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
. Rc<Any>
can then be
further downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more