#[non_exhaustive]pub enum Shape {
Circle {
radius: f32,
},
Rect {
size: Vec2,
},
Capsule {
height: f32,
radius: f32,
},
Polygon {
points: [Vec2; 8],
count: u8,
},
}Expand description
A collider’s shape, in pixels, centered on the entity (plus
Collider::offset) and turned with it.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
Circle
A circle.
Rect
A rectangle size wide and high.
Capsule
A vertical capsule: height between the centers of its round ends.
Fields
Polygon
A convex polygon: the convex hull of its corners, in pixels around
the entity’s position. Make one with Collider::polygon; read the
corners with Shape::points.
Implementations§
Source§impl Shape
impl Shape
Sourcepub fn points(&self) -> &[Vec2]
pub fn points(&self) -> &[Vec2]
A polygon’s corners (empty for other shapes).
use ponko::*;
let wedge = Collider::polygon(&[vec2(0.0, 0.0), vec2(40.0, 0.0), vec2(0.0, -20.0)]);
assert_eq!(wedge.shape.points().len(), 3);
assert!(Collider::circle(5.0).shape.points().is_empty());Examples found in repository?
examples/physics.rs (line 178)
134fn draw(ctx: &mut Ctx) {
135 ctx.clear(Color::hex(0x1d2330));
136 let shapes: Vec<(Transform2D, Collider, bool, f32)> = ctx
137 .world
138 .query::<(&Transform2D, &Collider, &RigidBody, Option<&Bell>)>()
139 .iter()
140 .map(|(t, c, b, bell)| (*t, *c, b.kind == BodyKind::Fixed, bell.map_or(0.0, |b| b.rang)))
141 .collect();
142 for (t, c, fixed, rang) in shapes {
143 let color = if c.sensor {
144 Color::rgba(1.0, 0.3 + 0.7 * (1.0 - rang), 0.3, 0.35)
145 } else if fixed {
146 Color::hex(0x4a5568)
147 } else {
148 Color::hex(0xf6ad55)
149 };
150 match c.shape {
151 Shape::Circle { radius } => {
152 ctx.draw_circle(t.position, radius, color);
153 // A spoke shows the spin.
154 let spoke = t.position + Vec2::from_angle(t.rotation) * radius;
155 ctx.draw_line(t.position, spoke, 2.0, Color::hex(0x1d2330));
156 }
157 Shape::Rect { size } => {
158 // Four corners turned with the body, drawn as edges.
159 let (sin, cos) = t.rotation.sin_cos();
160 let turn = |v: Vec2| t.position + vec2(v.x * cos - v.y * sin, v.x * sin + v.y * cos);
161 let h = size / 2.0;
162 let corners = [vec2(-h.x, -h.y), vec2(h.x, -h.y), vec2(h.x, h.y), vec2(-h.x, h.y)].map(turn);
163 if fixed || c.sensor {
164 ctx.draw_rect(Rect::new(t.position.x - h.x, t.position.y - h.y, size.x, size.y), color);
165 } else {
166 for i in 0..4 {
167 ctx.draw_line(corners[i], corners[(i + 1) % 4], 3.0, color);
168 }
169 }
170 }
171 Shape::Capsule { height, radius } => {
172 let up = Vec2::from_angle(t.rotation + std::f32::consts::FRAC_PI_2) * height / 2.0;
173 ctx.draw_line(t.position - up, t.position + up, radius * 2.0, color);
174 }
175 Shape::Polygon { .. } => {
176 let (sin, cos) = t.rotation.sin_cos();
177 let turn = |v: Vec2| t.position + vec2(v.x * cos - v.y * sin, v.x * sin + v.y * cos);
178 let corners: Vec<Vec2> = c.shape.points().iter().map(|&p| turn(p + c.offset)).collect();
179 for i in 0..corners.len() {
180 ctx.draw_line(corners[i], corners[(i + 1) % corners.len()], 3.0, color);
181 }
182 }
183 _ => {} // shapes added in later versions
184 }
185 }
186 if let Some(hit) = laser(ctx) {
187 ctx.draw_line(ctx.mouse_world(), hit.point, 1.0, Color::rgba(1.0, 0.2, 0.2, 0.8));
188 ctx.draw_circle(hit.point, 4.0, Color::rgb(1.0, 0.2, 0.2));
189 }
190 let bodies = ctx.physics.body_count();
191 ctx.draw_text(
192 &format!(
193 "{bodies} bodies | left click: crate right click: ball middle click: rock space: blast R: reset"
194 ),
195 vec2(30.0, 30.0),
196 18.0,
197 Color::WHITE,
198 );
199}Trait Implementations§
impl Copy for Shape
Source§impl<'de> Deserialize<'de> for Shape
impl<'de> Deserialize<'de> for Shape
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Deserialize this value from the given Serde deserializer. Read more
impl StructuralPartialEq for Shape
Auto Trait Implementations§
impl Forget for Shape
impl Freeze for Shape
impl RefUnwindSafe for Shape
impl Send for Shape
impl Sync for Shape
impl Unpin for Shape
impl UnsafeUnpin for Shape
impl UnwindSafe for Shape
Blanket Implementations§
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
Mutably borrows from an owned value. Read more
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> Component for T
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
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>
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>
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)
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)
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 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>
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>
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)
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)
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> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
impl<S, T> Duplex<S> for Twhere
T: FromSample<S> + ToSample<S>,
Source§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
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> ⓘ
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 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> ⓘ
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 moreSource§impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
fn into_sample(self) -> T
impl<T> MaybeSync for T
impl<T> MaybeSync for T
Source§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
impl<T> Scalar for T
impl<T> SerializableAny for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
The inverse inclusion map: attempts to construct
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
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
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
fn from_subset(element: &SS) -> SP
The inclusion map: converts
self to the equivalent element of its superset.