Skip to main content

Wheel3D

Struct Wheel3D 

Source
#[repr(C, align(16))]
pub struct Wheel3D {
Show 26 fields pub position: Vec3, pub radius: f32, pub mass: f32, pub suspension_distance: f32, pub spring: f32, pub damper: f32, pub target_position: f32, pub force_app_point_distance: f32, pub damping_rate: f32, pub forward_friction: FrictionCurve, pub sideways_friction: FrictionCurve, pub motor_torque: f32, pub brake_torque: f32, pub steer_angle: f32, pub local_rotation: Quat, pub grounded: bool, pub contact_point: Vec3, pub contact_normal: Vec3, pub compression: f32, pub suspension_force: f32, pub sprung_mass: f32, pub angular_velocity: f32, pub forward_slip: f32, pub sideways_slip: f32, pub spin: f32, pub local_position: Vec3,
}
Expand description

One wheel of a Vehicle3D: where it’s mounted, its suspension and tyres (set these up once), what drives it this tick (yours to set), and what happened to it in the last physics step (read after the step).

The suspension hangs straight down from position along the chassis’s -Y: at full compression the wheel’s center is at position, fully extended it’s suspension_distance lower. Under the car’s weight it rests at target_position of that travel.

use ponko::*;
// Front left wheel of a car whose chassis faces -Z.
let mut wheel = Wheel3D::new(vec3(-0.8, -0.2, -1.3), 0.35);
wheel.spring = 40_000.0;
wheel.sideways_friction.stiffness = 1.2;
// Each tick:
wheel.motor_torque = 300.0;
wheel.steer_angle = 0.3; // right
assert!(!wheel.grounded);

Fields§

§position: Vec3

Where the wheel’s center is at full compression, in the chassis’s frame (relative to its Transform3D position).

§radius: f32

The wheel’s radius in meters. Default 0.5.

§mass: f32

The wheel’s mass in kg, which sets how fast torque spins it up. Default 20.

§suspension_distance: f32

How far the suspension travels, meters. Default 0.3.

§spring: f32

The suspension’s spring rate, N/m. Default 35 000.

§damper: f32

The suspension’s damper rate, N·s/m. Default 4 500.

§target_position: f32

Where the suspension rests under the car’s weight: 0 fully compressed, 1 fully extended. Default 0.5.

§force_app_point_distance: f32

Where the suspension and tyre forces act: this far up the suspension from the bottom of the resting wheel. 0 (the default) at the tyre’s contact; near the center of mass rolls less.

§damping_rate: f32

Slows the wheel’s spin by this many N·m per rad/s (rolling resistance, bearings). Default 0.25.

§forward_friction: FrictionCurve

Grip along the wheel’s rolling direction.

§sideways_friction: FrictionCurve

Grip across it.

§motor_torque: f32

Drive torque, N·m: positive rolls forward (the chassis’s -Z).

§brake_torque: f32

Brake torque, N·m (positive): slows the wheel’s spin to a stop.

§steer_angle: f32

Steering, radians around the chassis’s up axis: positive steers right (clockwise seen from above).

§local_rotation: Quat

The wheel’s turn relative to the chassis (steer, then spin): for drawing it, with local_position or pose.

§grounded: bool

Touches the ground.

§contact_point: Vec3

Where the tyre touches the ground (when grounded).

§contact_normal: Vec3

The ground’s outward direction there (when grounded).

§compression: f32

How far the suspension is pushed in from full extension, meters (0 in the air, suspension_distance bottomed out).

§suspension_force: f32

The suspension’s push, newtons: the load on the tyre.

§sprung_mass: f32

The share of the chassis’s mass this wheel carries, kg.

§angular_velocity: f32

How fast the wheel spins, rad/s: positive rolls forward. See rpm.

§forward_slip: f32

Forward slip (see FrictionCurve).

§sideways_slip: f32

Sideways slip, radians: positive slides to the wheel’s right.

§spin: f32

How far the wheel has turned, radians (0..2π), for drawing.

§local_position: Vec3

The wheel’s center in the chassis’s frame, suspension travel included: for drawing it.

Implementations§

Source§

impl Wheel3D

Source

pub fn new(position: Vec3, radius: f32) -> Self

A wheel of radius mounted at position (its center at full compression, in the chassis’s frame), with the usual suspension and tyres.

Examples found in repository?
examples/vehicle.rs (line 44)
41fn spawn_car(ctx: &mut Ctx, at: Vec3) -> Entity {
42    let mut car = Vehicle3D::new();
43    for (x, z) in [(-0.8, -1.3), (0.8, -1.3), (-0.8, 1.3), (0.8, 1.3)] {
44        let mut wheel = Wheel3D::new(vec3(x, -0.3, z), 0.35);
45        wheel.sideways_friction.stiffness = 1.3;
46        car = car.with_wheel(wheel);
47    }
48    ctx.world.spawn((
49        Transform3D::at(at),
50        RigidBody3D::dynamic()
51            .mass(1200.0)
52            .center_of_mass(vec3(0.0, -0.35, 0.0)),
53        Collider3D::cuboid(vec3(1.8, 0.6, 4.2)),
54        Velocity3D::default(),
55        car,
56    ))
57}
Source

pub fn rpm(&self) -> f32

How fast the wheel spins, in revolutions per minute.

use ponko::*;
let mut wheel = Wheel3D::new(Vec3::ZERO, 0.3);
wheel.angular_velocity = std::f32::consts::TAU; // one turn a second
assert!((wheel.rpm() - 60.0).abs() < 1e-3);
Source

pub fn pose(&self, chassis: &Transform3D) -> Transform3D

Where to draw the wheel for a chassis at chassis: its center, with steer, spin and suspension travel. Pass the chassis’s Transform3D in a frame system and the wheel moves as smoothly as the chassis does.

use ponko::*;
let wheel = Wheel3D::new(vec3(1.0, 0.0, 0.0), 0.4);
let pose = wheel.pose(&Transform3D::at(vec3(0.0, 2.0, 0.0)));
// Hanging fully extended: 0.3 m below its mount.
assert!((pose.position - vec3(1.0, 1.7, 0.0)).length() < 1e-5);
Examples found in repository?
examples/vehicle.rs (line 138)
130fn place_wheels(ctx: &mut Ctx) {
131    let player = ctx.world.resource::<Player>();
132    let car = player.car;
133    let (Some(&vehicle), Some(&chassis)) = (ctx.world.get::<Vehicle3D>(car), ctx.world.get::<Transform3D>(car)) else {
134        return;
135    };
136    for i in 0..player.wheels.len() {
137        let e = ctx.world.resource::<Player>().wheels[i];
138        let pose = vehicle.wheels()[i].pose(&chassis);
139        if let Some(t) = ctx.world.get_mut::<Transform3D>(e) {
140            *t = Transform3D { scale: t.scale, ..pose };
141        }
142    }
143}

Trait Implementations§

Source§

impl Clone for Wheel3D

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for Wheel3D

Source§

impl Debug for Wheel3D

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Wheel3D

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for Wheel3D

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl PartialEq for Wheel3D

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl Serialize for Wheel3D

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for Wheel3D

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Component for T
where T: Send + Sync + 'static,

Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert 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>

Convert 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)

Convert &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)

Convert &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> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &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)

Converts &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> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> DowncastSend for T
where T: Any + Send,

Source§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync> ⓘ

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_sync(self: Box<T>) -> Box<dyn Any + Send + Sync>

Converts Box<Trait> (where Trait: DowncastSync) to Box<dyn Any + Send + Sync>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync> ⓘ

Converts Arc<Trait> (where Trait: DowncastSync) to Arc<Any>, which can then be downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<S> FromSample<S> for S

Source§

fn from_sample_(s: S) -> S

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<F, T> IntoSample<T> for F
where T: FromSample<F>,

Source§

fn into_sample(self) -> T

Source§

impl<T> MaybeSync for T
where T: Sync + ?Sized,

Source§

impl<T> MaybeSync for T
where T: Sync + ?Sized,

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<R, P> ReadPrimitive<R> for P
where R: Read + ReadEndian<P>, P: Default,

Source§

fn read_from_little_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_little_endian().
Source§

fn read_from_big_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_big_endian().
Source§

fn read_from_native_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_native_endian().
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> Scalar for T
where T: 'static + Clone + PartialEq + Debug,

Source§

impl<T> SerializableAny for T
where T: 'static + Any + Clone + for<'a> Send + Sync,

Source§

impl<T, S> SimdFrom<T, S> for T
where S: Simd,

Source§

fn simd_from(_simd: S, value: T) -> T

Source§

impl<F, T, S> SimdInto<T, S> for F
where T: SimdFrom<F, S>, S: Simd,

Source§

fn simd_into(self, simd: S) -> T

Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

Source§

fn to_sample_(self) -> U

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WasmNotSendSync for T

Source§

impl<T> WasmNotSync for T
where T: Sync,

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more