Struct Vec3

Source
#[repr(C)]
pub struct Vec3 { pub x: f32, pub y: f32, pub z: f32, }
Expand description

A 3-dimensional vector.

Fields§

§x: f32§y: f32§z: f32

Implementations§

Source§

impl Vec3

Source

pub const ZERO: Vec3

All zeroes.

Source

pub const ONE: Vec3

All ones.

Source

pub const NEG_ONE: Vec3

All negative ones.

Source

pub const MIN: Vec3

All f32::MIN.

Source

pub const MAX: Vec3

All f32::MAX.

Source

pub const NAN: Vec3

All f32::NAN.

Source

pub const INFINITY: Vec3

All f32::INFINITY.

Source

pub const NEG_INFINITY: Vec3

All f32::NEG_INFINITY.

Source

pub const X: Vec3

A unit vector pointing along the positive X axis.

Source

pub const Y: Vec3

A unit vector pointing along the positive Y axis.

Source

pub const Z: Vec3

A unit vector pointing along the positive Z axis.

Source

pub const NEG_X: Vec3

A unit vector pointing along the negative X axis.

Source

pub const NEG_Y: Vec3

A unit vector pointing along the negative Y axis.

Source

pub const NEG_Z: Vec3

A unit vector pointing along the negative Z axis.

Source

pub const AXES: [Vec3; 3]

The unit axes.

Source

pub const fn new(x: f32, y: f32, z: f32) -> Vec3

Creates a new vector.

Examples found in repository?
examples/math/sampling_primitives.rs (line 46)
46const DISTANCE_BETWEEN_SHAPES: Vec3 = Vec3::new(2.0, 0.0, 0.0);
47
48/// Maximum amount of points allowed to be present.
49/// Should be set such that it does not cause large amounts of lag when reached.
50const MAX_POINTS: usize = 3000; // TODO: Test wasm and add a wasm-specific-bound
51
52/// How many points should be spawned each frame
53const POINTS_PER_FRAME: usize = 3;
54
55/// Color used for the inside points
56const INSIDE_POINT_COLOR: LinearRgba = LinearRgba::rgb(0.855, 1.1, 0.01);
57/// Color used for the points on the boundary
58const BOUNDARY_POINT_COLOR: LinearRgba = LinearRgba::rgb(0.08, 0.2, 0.90);
59
60/// Time (in seconds) for the spawning/despawning animation
61const ANIMATION_TIME: f32 = 1.0;
62
63/// Color for the sky and the sky-light
64const SKY_COLOR: Color = Color::srgb(0.02, 0.06, 0.15);
65
66const SMALL_3D: f32 = 0.5;
67const BIG_3D: f32 = 1.0;
68
69// primitives
70
71const CUBOID: Cuboid = Cuboid {
72    half_size: Vec3::new(SMALL_3D, BIG_3D, SMALL_3D),
73};
74
75const SPHERE: Sphere = Sphere {
76    radius: 1.5 * SMALL_3D,
77};
78
79const TRIANGLE_3D: Triangle3d = Triangle3d {
80    vertices: [
81        Vec3::new(BIG_3D, -BIG_3D * 0.5, 0.0),
82        Vec3::new(0.0, BIG_3D, 0.0),
83        Vec3::new(-BIG_3D, -BIG_3D * 0.5, 0.0),
84    ],
85};
86
87const CAPSULE_3D: Capsule3d = Capsule3d {
88    radius: SMALL_3D,
89    half_length: SMALL_3D,
90};
91
92const CYLINDER: Cylinder = Cylinder {
93    radius: SMALL_3D,
94    half_height: SMALL_3D,
95};
96
97const TETRAHEDRON: Tetrahedron = Tetrahedron {
98    vertices: [
99        Vec3::new(-BIG_3D, -BIG_3D * 0.67, BIG_3D * 0.5),
100        Vec3::new(BIG_3D, -BIG_3D * 0.67, BIG_3D * 0.5),
101        Vec3::new(0.0, -BIG_3D * 0.67, -BIG_3D * 1.17),
102        Vec3::new(0.0, BIG_3D, 0.0),
103    ],
104};
More examples
Hide additional examples
examples/games/breakout.rs (line 21)
21const BALL_STARTING_POSITION: Vec3 = Vec3::new(0.0, -50.0, 1.0);
22const BALL_DIAMETER: f32 = 30.;
23const BALL_SPEED: f32 = 400.0;
24const INITIAL_BALL_DIRECTION: Vec2 = Vec2::new(0.5, -0.5);
25
26const WALL_THICKNESS: f32 = 10.0;
27// x coordinates
28const LEFT_WALL: f32 = -450.;
29const RIGHT_WALL: f32 = 450.;
30// y coordinates
31const BOTTOM_WALL: f32 = -300.;
32const TOP_WALL: f32 = 300.;
33
34const BRICK_SIZE: Vec2 = Vec2::new(100., 30.);
35// These values are exact
36const GAP_BETWEEN_PADDLE_AND_BRICKS: f32 = 270.0;
37const GAP_BETWEEN_BRICKS: f32 = 5.0;
38// These values are lower bounds, as the number of bricks is computed
39const GAP_BETWEEN_BRICKS_AND_CEILING: f32 = 20.0;
40const GAP_BETWEEN_BRICKS_AND_SIDES: f32 = 20.0;
41
42const SCOREBOARD_FONT_SIZE: f32 = 33.0;
43const SCOREBOARD_TEXT_PADDING: Val = Val::Px(5.0);
44
45const BACKGROUND_COLOR: Color = Color::srgb(0.9, 0.9, 0.9);
46const PADDLE_COLOR: Color = Color::srgb(0.3, 0.3, 0.7);
47const BALL_COLOR: Color = Color::srgb(1.0, 0.5, 0.5);
48const BRICK_COLOR: Color = Color::srgb(0.5, 0.5, 1.0);
49const WALL_COLOR: Color = Color::srgb(0.8, 0.8, 0.8);
50const TEXT_COLOR: Color = Color::srgb(0.5, 0.5, 1.0);
51const SCORE_COLOR: Color = Color::srgb(1.0, 0.5, 0.5);
52
53fn main() {
54    App::new()
55        .add_plugins(DefaultPlugins)
56        .add_plugins(
57            stepping::SteppingPlugin::default()
58                .add_schedule(Update)
59                .add_schedule(FixedUpdate)
60                .at(Val::Percent(35.0), Val::Percent(50.0)),
61        )
62        .insert_resource(Score(0))
63        .insert_resource(ClearColor(BACKGROUND_COLOR))
64        .add_event::<CollisionEvent>()
65        .add_systems(Startup, setup)
66        // Add our gameplay simulation systems to the fixed timestep schedule
67        // which runs at 64 Hz by default
68        .add_systems(
69            FixedUpdate,
70            (
71                apply_velocity,
72                move_paddle,
73                check_for_collisions,
74                play_collision_sound,
75            )
76                // `chain`ing systems together runs them in order
77                .chain(),
78        )
79        .add_systems(Update, update_scoreboard)
80        .run();
81}
82
83#[derive(Component)]
84struct Paddle;
85
86#[derive(Component)]
87struct Ball;
88
89#[derive(Component, Deref, DerefMut)]
90struct Velocity(Vec2);
91
92#[derive(Event, Default)]
93struct CollisionEvent;
94
95#[derive(Component)]
96struct Brick;
97
98#[derive(Resource, Deref)]
99struct CollisionSound(Handle<AudioSource>);
100
101// Default must be implemented to define this as a required component for the Wall component below
102#[derive(Component, Default)]
103struct Collider;
104
105// This is a collection of the components that define a "Wall" in our game
106#[derive(Component)]
107#[require(Sprite, Transform, Collider)]
108struct Wall;
109
110/// Which side of the arena is this wall located on?
111enum WallLocation {
112    Left,
113    Right,
114    Bottom,
115    Top,
116}
117
118impl WallLocation {
119    /// Location of the *center* of the wall, used in `transform.translation()`
120    fn position(&self) -> Vec2 {
121        match self {
122            WallLocation::Left => Vec2::new(LEFT_WALL, 0.),
123            WallLocation::Right => Vec2::new(RIGHT_WALL, 0.),
124            WallLocation::Bottom => Vec2::new(0., BOTTOM_WALL),
125            WallLocation::Top => Vec2::new(0., TOP_WALL),
126        }
127    }
128
129    /// (x, y) dimensions of the wall, used in `transform.scale()`
130    fn size(&self) -> Vec2 {
131        let arena_height = TOP_WALL - BOTTOM_WALL;
132        let arena_width = RIGHT_WALL - LEFT_WALL;
133        // Make sure we haven't messed up our constants
134        assert!(arena_height > 0.0);
135        assert!(arena_width > 0.0);
136
137        match self {
138            WallLocation::Left | WallLocation::Right => {
139                Vec2::new(WALL_THICKNESS, arena_height + WALL_THICKNESS)
140            }
141            WallLocation::Bottom | WallLocation::Top => {
142                Vec2::new(arena_width + WALL_THICKNESS, WALL_THICKNESS)
143            }
144        }
145    }
146}
147
148impl Wall {
149    // This "builder method" allows us to reuse logic across our wall entities,
150    // making our code easier to read and less prone to bugs when we change the logic
151    // Notice the use of Sprite and Transform alongside Wall, overwriting the default values defined for the required components
152    fn new(location: WallLocation) -> (Wall, Sprite, Transform) {
153        (
154            Wall,
155            Sprite::from_color(WALL_COLOR, Vec2::ONE),
156            Transform {
157                // We need to convert our Vec2 into a Vec3, by giving it a z-coordinate
158                // This is used to determine the order of our sprites
159                translation: location.position().extend(0.0),
160                // The z-scale of 2D objects must always be 1.0,
161                // or their ordering will be affected in surprising ways.
162                // See https://github.com/bevyengine/bevy/issues/4149
163                scale: location.size().extend(1.0),
164                ..default()
165            },
166        )
167    }
168}
169
170// This resource tracks the game's score
171#[derive(Resource, Deref, DerefMut)]
172struct Score(usize);
173
174#[derive(Component)]
175struct ScoreboardUi;
176
177// Add the game's entities to our world
178fn setup(
179    mut commands: Commands,
180    mut meshes: ResMut<Assets<Mesh>>,
181    mut materials: ResMut<Assets<ColorMaterial>>,
182    asset_server: Res<AssetServer>,
183) {
184    // Camera
185    commands.spawn(Camera2d);
186
187    // Sound
188    let ball_collision_sound = asset_server.load("sounds/breakout_collision.ogg");
189    commands.insert_resource(CollisionSound(ball_collision_sound));
190
191    // Paddle
192    let paddle_y = BOTTOM_WALL + GAP_BETWEEN_PADDLE_AND_FLOOR;
193
194    commands.spawn((
195        Sprite::from_color(PADDLE_COLOR, Vec2::ONE),
196        Transform {
197            translation: Vec3::new(0.0, paddle_y, 0.0),
198            scale: PADDLE_SIZE.extend(1.0),
199            ..default()
200        },
201        Paddle,
202        Collider,
203    ));
204
205    // Ball
206    commands.spawn((
207        Mesh2d(meshes.add(Circle::default())),
208        MeshMaterial2d(materials.add(BALL_COLOR)),
209        Transform::from_translation(BALL_STARTING_POSITION)
210            .with_scale(Vec2::splat(BALL_DIAMETER).extend(1.)),
211        Ball,
212        Velocity(INITIAL_BALL_DIRECTION.normalize() * BALL_SPEED),
213    ));
214
215    // Scoreboard
216    commands.spawn((
217        Text::new("Score: "),
218        TextFont {
219            font_size: SCOREBOARD_FONT_SIZE,
220            ..default()
221        },
222        TextColor(TEXT_COLOR),
223        ScoreboardUi,
224        Node {
225            position_type: PositionType::Absolute,
226            top: SCOREBOARD_TEXT_PADDING,
227            left: SCOREBOARD_TEXT_PADDING,
228            ..default()
229        },
230        children![(
231            TextSpan::default(),
232            TextFont {
233                font_size: SCOREBOARD_FONT_SIZE,
234                ..default()
235            },
236            TextColor(SCORE_COLOR),
237        )],
238    ));
239
240    // Walls
241    commands.spawn(Wall::new(WallLocation::Left));
242    commands.spawn(Wall::new(WallLocation::Right));
243    commands.spawn(Wall::new(WallLocation::Bottom));
244    commands.spawn(Wall::new(WallLocation::Top));
245
246    // Bricks
247    let total_width_of_bricks = (RIGHT_WALL - LEFT_WALL) - 2. * GAP_BETWEEN_BRICKS_AND_SIDES;
248    let bottom_edge_of_bricks = paddle_y + GAP_BETWEEN_PADDLE_AND_BRICKS;
249    let total_height_of_bricks = TOP_WALL - bottom_edge_of_bricks - GAP_BETWEEN_BRICKS_AND_CEILING;
250
251    assert!(total_width_of_bricks > 0.0);
252    assert!(total_height_of_bricks > 0.0);
253
254    // Given the space available, compute how many rows and columns of bricks we can fit
255    let n_columns = (total_width_of_bricks / (BRICK_SIZE.x + GAP_BETWEEN_BRICKS)).floor() as usize;
256    let n_rows = (total_height_of_bricks / (BRICK_SIZE.y + GAP_BETWEEN_BRICKS)).floor() as usize;
257    let n_vertical_gaps = n_columns - 1;
258
259    // Because we need to round the number of columns,
260    // the space on the top and sides of the bricks only captures a lower bound, not an exact value
261    let center_of_bricks = (LEFT_WALL + RIGHT_WALL) / 2.0;
262    let left_edge_of_bricks = center_of_bricks
263        // Space taken up by the bricks
264        - (n_columns as f32 / 2.0 * BRICK_SIZE.x)
265        // Space taken up by the gaps
266        - n_vertical_gaps as f32 / 2.0 * GAP_BETWEEN_BRICKS;
267
268    // In Bevy, the `translation` of an entity describes the center point,
269    // not its bottom-left corner
270    let offset_x = left_edge_of_bricks + BRICK_SIZE.x / 2.;
271    let offset_y = bottom_edge_of_bricks + BRICK_SIZE.y / 2.;
272
273    for row in 0..n_rows {
274        for column in 0..n_columns {
275            let brick_position = Vec2::new(
276                offset_x + column as f32 * (BRICK_SIZE.x + GAP_BETWEEN_BRICKS),
277                offset_y + row as f32 * (BRICK_SIZE.y + GAP_BETWEEN_BRICKS),
278            );
279
280            // brick
281            commands.spawn((
282                Sprite {
283                    color: BRICK_COLOR,
284                    ..default()
285                },
286                Transform {
287                    translation: brick_position.extend(0.0),
288                    scale: Vec3::new(BRICK_SIZE.x, BRICK_SIZE.y, 1.0),
289                    ..default()
290                },
291                Brick,
292                Collider,
293            ));
294        }
295    }
296}
examples/math/render_primitives.rs (line 154)
153const CUBOID: Cuboid = Cuboid {
154    half_size: Vec3::new(BIG_3D, SMALL_3D, BIG_3D),
155};
156
157const CIRCLE: Circle = Circle { radius: BIG_2D };
158const SPHERE: Sphere = Sphere { radius: BIG_3D };
159
160const ELLIPSE: Ellipse = Ellipse {
161    half_size: Vec2::new(BIG_2D, SMALL_2D),
162};
163
164const TRIANGLE_2D: Triangle2d = Triangle2d {
165    vertices: [
166        Vec2::new(BIG_2D, 0.0),
167        Vec2::new(0.0, BIG_2D),
168        Vec2::new(-BIG_2D, 0.0),
169    ],
170};
171
172const TRIANGLE_3D: Triangle3d = Triangle3d {
173    vertices: [
174        Vec3::new(BIG_3D, 0.0, 0.0),
175        Vec3::new(0.0, BIG_3D, 0.0),
176        Vec3::new(-BIG_3D, 0.0, 0.0),
177    ],
178};
179
180const PLANE_2D: Plane2d = Plane2d { normal: Dir2::Y };
181const PLANE_3D: Plane3d = Plane3d {
182    normal: Dir3::Y,
183    half_size: Vec2::new(BIG_3D, BIG_3D),
184};
185
186const LINE2D: Line2d = Line2d { direction: Dir2::X };
187const LINE3D: Line3d = Line3d { direction: Dir3::X };
188
189const SEGMENT_2D: Segment2d = Segment2d {
190    vertices: [Vec2::new(-BIG_2D / 2., 0.), Vec2::new(BIG_2D / 2., 0.)],
191};
192
193const SEGMENT_3D: Segment3d = Segment3d {
194    vertices: [
195        Vec3::new(-BIG_3D / 2., 0., 0.),
196        Vec3::new(BIG_3D / 2., 0., 0.),
197    ],
198};
199
200const POLYLINE_2D: Polyline2d<4> = Polyline2d {
201    vertices: [
202        Vec2::new(-BIG_2D, -SMALL_2D),
203        Vec2::new(-SMALL_2D, SMALL_2D),
204        Vec2::new(SMALL_2D, -SMALL_2D),
205        Vec2::new(BIG_2D, SMALL_2D),
206    ],
207};
208const POLYLINE_3D: Polyline3d<4> = Polyline3d {
209    vertices: [
210        Vec3::new(-BIG_3D, -SMALL_3D, -SMALL_3D),
211        Vec3::new(SMALL_3D, SMALL_3D, 0.0),
212        Vec3::new(-SMALL_3D, -SMALL_3D, 0.0),
213        Vec3::new(BIG_3D, SMALL_3D, SMALL_3D),
214    ],
215};
216
217const POLYGON_2D: Polygon<5> = Polygon {
218    vertices: [
219        Vec2::new(-BIG_2D, -SMALL_2D),
220        Vec2::new(BIG_2D, -SMALL_2D),
221        Vec2::new(BIG_2D, SMALL_2D),
222        Vec2::new(0.0, 0.0),
223        Vec2::new(-BIG_2D, SMALL_2D),
224    ],
225};
226
227const REGULAR_POLYGON: RegularPolygon = RegularPolygon {
228    circumcircle: Circle { radius: BIG_2D },
229    sides: 5,
230};
231
232const CAPSULE_2D: Capsule2d = Capsule2d {
233    radius: SMALL_2D,
234    half_length: SMALL_2D,
235};
236const CAPSULE_3D: Capsule3d = Capsule3d {
237    radius: SMALL_3D,
238    half_length: SMALL_3D,
239};
240
241const CYLINDER: Cylinder = Cylinder {
242    radius: SMALL_3D,
243    half_height: SMALL_3D,
244};
245
246const CONE: Cone = Cone {
247    radius: BIG_3D,
248    height: BIG_3D,
249};
250
251const CONICAL_FRUSTUM: ConicalFrustum = ConicalFrustum {
252    radius_top: BIG_3D,
253    radius_bottom: SMALL_3D,
254    height: BIG_3D,
255};
256
257const ANNULUS: Annulus = Annulus {
258    inner_circle: Circle { radius: SMALL_2D },
259    outer_circle: Circle { radius: BIG_2D },
260};
261
262const TORUS: Torus = Torus {
263    minor_radius: SMALL_3D / 2.0,
264    major_radius: SMALL_3D * 1.5,
265};
266
267const TETRAHEDRON: Tetrahedron = Tetrahedron {
268    vertices: [
269        Vec3::new(-BIG_3D, 0.0, 0.0),
270        Vec3::new(BIG_3D, 0.0, 0.0),
271        Vec3::new(0.0, 0.0, -BIG_3D * 1.67),
272        Vec3::new(0.0, BIG_3D * 1.67, -BIG_3D * 0.5),
273    ],
274};
275
276const ARC: Arc2d = Arc2d {
277    radius: BIG_2D,
278    half_angle: std::f32::consts::FRAC_PI_4,
279};
280
281const CIRCULAR_SECTOR: CircularSector = CircularSector {
282    arc: Arc2d {
283        radius: BIG_2D,
284        half_angle: std::f32::consts::FRAC_PI_4,
285    },
286};
287
288const CIRCULAR_SEGMENT: CircularSegment = CircularSegment {
289    arc: Arc2d {
290        radius: BIG_2D,
291        half_angle: std::f32::consts::FRAC_PI_4,
292    },
293};
294
295fn setup_cameras(mut commands: Commands) {
296    let start_in_2d = true;
297    let make_camera = |is_active| Camera {
298        is_active,
299        ..Default::default()
300    };
301
302    commands.spawn((Camera2d, make_camera(start_in_2d)));
303
304    commands.spawn((
305        Camera3d::default(),
306        make_camera(!start_in_2d),
307        Transform::from_xyz(0.0, 10.0, 0.0).looking_at(Vec3::ZERO, Vec3::Z),
308    ));
309}
310
311fn setup_ambient_light(mut ambient_light: ResMut<AmbientLight>) {
312    ambient_light.brightness = 50.0;
313}
314
315fn setup_lights(mut commands: Commands) {
316    commands.spawn((
317        PointLight {
318            intensity: 5000.0,
319            ..default()
320        },
321        Transform::from_translation(Vec3::new(-LEFT_RIGHT_OFFSET_3D, 2.0, 0.0))
322            .looking_at(Vec3::new(-LEFT_RIGHT_OFFSET_3D, 0.0, 0.0), Vec3::Y),
323    ));
324}
325
326/// Marker component for header text
327#[derive(Debug, Clone, Component, Default, Reflect)]
328pub struct HeaderText;
329
330/// Marker component for header node
331#[derive(Debug, Clone, Component, Default, Reflect)]
332pub struct HeaderNode;
333
334fn update_active_cameras(
335    state: Res<State<CameraActive>>,
336    camera_2d: Single<(Entity, &mut Camera), With<Camera2d>>,
337    camera_3d: Single<(Entity, &mut Camera), (With<Camera3d>, Without<Camera2d>)>,
338    mut text: Query<&mut UiTargetCamera, With<HeaderNode>>,
339) {
340    let (entity_2d, mut cam_2d) = camera_2d.into_inner();
341    let (entity_3d, mut cam_3d) = camera_3d.into_inner();
342    let is_camera_2d_active = matches!(*state.get(), CameraActive::Dim2);
343
344    cam_2d.is_active = is_camera_2d_active;
345    cam_3d.is_active = !is_camera_2d_active;
346
347    let active_camera = if is_camera_2d_active {
348        entity_2d
349    } else {
350        entity_3d
351    };
352
353    text.iter_mut().for_each(|mut target_camera| {
354        *target_camera = UiTargetCamera(active_camera);
355    });
356}
357
358fn switch_cameras(current: Res<State<CameraActive>>, mut next: ResMut<NextState<CameraActive>>) {
359    let next_state = match current.get() {
360        CameraActive::Dim2 => CameraActive::Dim3,
361        CameraActive::Dim3 => CameraActive::Dim2,
362    };
363    next.set(next_state);
364}
365
366fn setup_text(mut commands: Commands, cameras: Query<(Entity, &Camera)>) {
367    let active_camera = cameras
368        .iter()
369        .find_map(|(entity, camera)| camera.is_active.then_some(entity))
370        .expect("run condition ensures existence");
371    commands.spawn((
372        HeaderNode,
373        Node {
374            justify_self: JustifySelf::Center,
375            top: Val::Px(5.0),
376            ..Default::default()
377        },
378        UiTargetCamera(active_camera),
379        children![(
380            Text::default(),
381            HeaderText,
382            TextLayout::new_with_justify(JustifyText::Center),
383            children![
384                TextSpan::new("Primitive: "),
385                TextSpan(format!("{text}", text = PrimitiveSelected::default())),
386                TextSpan::new("\n\n"),
387                TextSpan::new(
388                    "Press 'C' to switch between 2D and 3D mode\n\
389                    Press 'Up' or 'Down' to switch to the next/previous primitive",
390                ),
391                TextSpan::new("\n\n"),
392                TextSpan::new("(If nothing is displayed, there's no rendering support yet)",),
393            ]
394        )],
395    ));
396}
397
398fn update_text(
399    primitive_state: Res<State<PrimitiveSelected>>,
400    header: Query<Entity, With<HeaderText>>,
401    mut writer: TextUiWriter,
402) {
403    let new_text = format!("{text}", text = primitive_state.get());
404    header.iter().for_each(|header_text| {
405        if let Some(mut text) = writer.get_text(header_text, 2) {
406            (*text).clone_from(&new_text);
407        };
408    });
409}
410
411fn switch_to_next_primitive(
412    current: Res<State<PrimitiveSelected>>,
413    mut next: ResMut<NextState<PrimitiveSelected>>,
414) {
415    let next_state = current.get().next();
416    next.set(next_state);
417}
418
419fn switch_to_previous_primitive(
420    current: Res<State<PrimitiveSelected>>,
421    mut next: ResMut<NextState<PrimitiveSelected>>,
422) {
423    let next_state = current.get().previous();
424    next.set(next_state);
425}
426
427fn in_mode(active: CameraActive) -> impl Fn(Res<State<CameraActive>>) -> bool {
428    move |state| *state.get() == active
429}
430
431fn draw_gizmos_2d(mut gizmos: Gizmos, state: Res<State<PrimitiveSelected>>, time: Res<Time>) {
432    const POSITION: Vec2 = Vec2::new(-LEFT_RIGHT_OFFSET_2D, 0.0);
433    let angle = time.elapsed_secs();
434    let isometry = Isometry2d::new(POSITION, Rot2::radians(angle));
435    let color = Color::WHITE;
436
437    #[expect(
438        clippy::match_same_arms,
439        reason = "Certain primitives don't have any 2D rendering support yet."
440    )]
441    match state.get() {
442        PrimitiveSelected::RectangleAndCuboid => {
443            gizmos.primitive_2d(&RECTANGLE, isometry, color);
444        }
445        PrimitiveSelected::CircleAndSphere => {
446            gizmos.primitive_2d(&CIRCLE, isometry, color);
447        }
448        PrimitiveSelected::Ellipse => drop(gizmos.primitive_2d(&ELLIPSE, isometry, color)),
449        PrimitiveSelected::Triangle => gizmos.primitive_2d(&TRIANGLE_2D, isometry, color),
450        PrimitiveSelected::Plane => gizmos.primitive_2d(&PLANE_2D, isometry, color),
451        PrimitiveSelected::Line => drop(gizmos.primitive_2d(&LINE2D, isometry, color)),
452        PrimitiveSelected::Segment => {
453            drop(gizmos.primitive_2d(&SEGMENT_2D, isometry, color));
454        }
455        PrimitiveSelected::Polyline => gizmos.primitive_2d(&POLYLINE_2D, isometry, color),
456        PrimitiveSelected::Polygon => gizmos.primitive_2d(&POLYGON_2D, isometry, color),
457        PrimitiveSelected::RegularPolygon => {
458            gizmos.primitive_2d(&REGULAR_POLYGON, isometry, color);
459        }
460        PrimitiveSelected::Capsule => gizmos.primitive_2d(&CAPSULE_2D, isometry, color),
461        PrimitiveSelected::Cylinder => {}
462        PrimitiveSelected::Cone => {}
463        PrimitiveSelected::ConicalFrustum => {}
464        PrimitiveSelected::Torus => drop(gizmos.primitive_2d(&ANNULUS, isometry, color)),
465        PrimitiveSelected::Tetrahedron => {}
466        PrimitiveSelected::Arc => gizmos.primitive_2d(&ARC, isometry, color),
467        PrimitiveSelected::CircularSector => {
468            gizmos.primitive_2d(&CIRCULAR_SECTOR, isometry, color);
469        }
470        PrimitiveSelected::CircularSegment => {
471            gizmos.primitive_2d(&CIRCULAR_SEGMENT, isometry, color);
472        }
473    }
474}
475
476/// Marker for primitive meshes to record in which state they should be visible in
477#[derive(Debug, Clone, Component, Default, Reflect)]
478pub struct PrimitiveData {
479    camera_mode: CameraActive,
480    primitive_state: PrimitiveSelected,
481}
482
483/// Marker for meshes of 2D primitives
484#[derive(Debug, Clone, Component, Default)]
485pub struct MeshDim2;
486
487/// Marker for meshes of 3D primitives
488#[derive(Debug, Clone, Component, Default)]
489pub struct MeshDim3;
490
491fn spawn_primitive_2d(
492    mut commands: Commands,
493    mut materials: ResMut<Assets<ColorMaterial>>,
494    mut meshes: ResMut<Assets<Mesh>>,
495) {
496    const POSITION: Vec3 = Vec3::new(LEFT_RIGHT_OFFSET_2D, 0.0, 0.0);
497    let material: Handle<ColorMaterial> = materials.add(Color::WHITE);
498    let camera_mode = CameraActive::Dim2;
499    [
500        Some(RECTANGLE.mesh().build()),
501        Some(CIRCLE.mesh().build()),
502        Some(ELLIPSE.mesh().build()),
503        Some(TRIANGLE_2D.mesh().build()),
504        None, // plane
505        None, // line
506        None, // segment
507        None, // polyline
508        None, // polygon
509        Some(REGULAR_POLYGON.mesh().build()),
510        Some(CAPSULE_2D.mesh().build()),
511        None, // cylinder
512        None, // cone
513        None, // conical frustum
514        Some(ANNULUS.mesh().build()),
515        None, // tetrahedron
516    ]
517    .into_iter()
518    .zip(PrimitiveSelected::ALL)
519    .for_each(|(maybe_mesh, state)| {
520        if let Some(mesh) = maybe_mesh {
521            commands.spawn((
522                MeshDim2,
523                PrimitiveData {
524                    camera_mode,
525                    primitive_state: state,
526                },
527                Mesh2d(meshes.add(mesh)),
528                MeshMaterial2d(material.clone()),
529                Transform::from_translation(POSITION),
530            ));
531        }
532    });
533}
534
535fn spawn_primitive_3d(
536    mut commands: Commands,
537    mut materials: ResMut<Assets<StandardMaterial>>,
538    mut meshes: ResMut<Assets<Mesh>>,
539) {
540    const POSITION: Vec3 = Vec3::new(-LEFT_RIGHT_OFFSET_3D, 0.0, 0.0);
541    let material: Handle<StandardMaterial> = materials.add(Color::WHITE);
542    let camera_mode = CameraActive::Dim3;
543    [
544        Some(CUBOID.mesh().build()),
545        Some(SPHERE.mesh().build()),
546        None, // ellipse
547        Some(TRIANGLE_3D.mesh().build()),
548        Some(PLANE_3D.mesh().build()),
549        None, // line
550        None, // segment
551        None, // polyline
552        None, // polygon
553        None, // regular polygon
554        Some(CAPSULE_3D.mesh().build()),
555        Some(CYLINDER.mesh().build()),
556        None, // cone
557        None, // conical frustum
558        Some(TORUS.mesh().build()),
559        Some(TETRAHEDRON.mesh().build()),
560    ]
561    .into_iter()
562    .zip(PrimitiveSelected::ALL)
563    .for_each(|(maybe_mesh, state)| {
564        if let Some(mesh) = maybe_mesh {
565            commands.spawn((
566                MeshDim3,
567                PrimitiveData {
568                    camera_mode,
569                    primitive_state: state,
570                },
571                Mesh3d(meshes.add(mesh)),
572                MeshMaterial3d(material.clone()),
573                Transform::from_translation(POSITION),
574            ));
575        }
576    });
577}
578
579fn update_primitive_meshes(
580    camera_state: Res<State<CameraActive>>,
581    primitive_state: Res<State<PrimitiveSelected>>,
582    mut primitives: Query<(&mut Visibility, &PrimitiveData)>,
583) {
584    primitives.iter_mut().for_each(|(mut vis, primitive)| {
585        let visible = primitive.camera_mode == *camera_state.get()
586            && primitive.primitive_state == *primitive_state.get();
587        *vis = if visible {
588            Visibility::Inherited
589        } else {
590            Visibility::Hidden
591        };
592    });
593}
594
595fn rotate_primitive_2d_meshes(
596    mut primitives_2d: Query<
597        (&mut Transform, &ViewVisibility),
598        (With<PrimitiveData>, With<MeshDim2>),
599    >,
600    time: Res<Time>,
601) {
602    let rotation_2d = Quat::from_mat3(&Mat3::from_angle(time.elapsed_secs()));
603    primitives_2d
604        .iter_mut()
605        .filter(|(_, vis)| vis.get())
606        .for_each(|(mut transform, _)| {
607            transform.rotation = rotation_2d;
608        });
609}
610
611fn rotate_primitive_3d_meshes(
612    mut primitives_3d: Query<
613        (&mut Transform, &ViewVisibility),
614        (With<PrimitiveData>, With<MeshDim3>),
615    >,
616    time: Res<Time>,
617) {
618    let rotation_3d = Quat::from_rotation_arc(
619        Vec3::Z,
620        Vec3::new(
621            ops::sin(time.elapsed_secs()),
622            ops::cos(time.elapsed_secs()),
623            ops::sin(time.elapsed_secs()) * 0.5,
624        )
625        .try_normalize()
626        .unwrap_or(Vec3::Z),
627    );
628    primitives_3d
629        .iter_mut()
630        .filter(|(_, vis)| vis.get())
631        .for_each(|(mut transform, _)| {
632            transform.rotation = rotation_3d;
633        });
634}
635
636fn draw_gizmos_3d(mut gizmos: Gizmos, state: Res<State<PrimitiveSelected>>, time: Res<Time>) {
637    const POSITION: Vec3 = Vec3::new(LEFT_RIGHT_OFFSET_3D, 0.0, 0.0);
638    let rotation = Quat::from_rotation_arc(
639        Vec3::Z,
640        Vec3::new(
641            ops::sin(time.elapsed_secs()),
642            ops::cos(time.elapsed_secs()),
643            ops::sin(time.elapsed_secs()) * 0.5,
644        )
645        .try_normalize()
646        .unwrap_or(Vec3::Z),
647    );
648    let isometry = Isometry3d::new(POSITION, rotation);
649    let color = Color::WHITE;
650    let resolution = 10;
651
652    #[expect(
653        clippy::match_same_arms,
654        reason = "Certain primitives don't have any 3D rendering support yet."
655    )]
656    match state.get() {
657        PrimitiveSelected::RectangleAndCuboid => {
658            gizmos.primitive_3d(&CUBOID, isometry, color);
659        }
660        PrimitiveSelected::CircleAndSphere => drop(
661            gizmos
662                .primitive_3d(&SPHERE, isometry, color)
663                .resolution(resolution),
664        ),
665        PrimitiveSelected::Ellipse => {}
666        PrimitiveSelected::Triangle => gizmos.primitive_3d(&TRIANGLE_3D, isometry, color),
667        PrimitiveSelected::Plane => drop(gizmos.primitive_3d(&PLANE_3D, isometry, color)),
668        PrimitiveSelected::Line => gizmos.primitive_3d(&LINE3D, isometry, color),
669        PrimitiveSelected::Segment => gizmos.primitive_3d(&SEGMENT_3D, isometry, color),
670        PrimitiveSelected::Polyline => gizmos.primitive_3d(&POLYLINE_3D, isometry, color),
671        PrimitiveSelected::Polygon => {}
672        PrimitiveSelected::RegularPolygon => {}
673        PrimitiveSelected::Capsule => drop(
674            gizmos
675                .primitive_3d(&CAPSULE_3D, isometry, color)
676                .resolution(resolution),
677        ),
678        PrimitiveSelected::Cylinder => drop(
679            gizmos
680                .primitive_3d(&CYLINDER, isometry, color)
681                .resolution(resolution),
682        ),
683        PrimitiveSelected::Cone => drop(
684            gizmos
685                .primitive_3d(&CONE, isometry, color)
686                .resolution(resolution),
687        ),
688        PrimitiveSelected::ConicalFrustum => {
689            gizmos.primitive_3d(&CONICAL_FRUSTUM, isometry, color);
690        }
691
692        PrimitiveSelected::Torus => drop(
693            gizmos
694                .primitive_3d(&TORUS, isometry, color)
695                .minor_resolution(resolution)
696                .major_resolution(resolution),
697        ),
698        PrimitiveSelected::Tetrahedron => {
699            gizmos.primitive_3d(&TETRAHEDRON, isometry, color);
700        }
701
702        PrimitiveSelected::Arc => {}
703        PrimitiveSelected::CircularSector => {}
704        PrimitiveSelected::CircularSegment => {}
705    }
706}
examples/async_tasks/external_source_external_thread.rs (line 69)
63fn move_text(
64    mut commands: Commands,
65    mut texts: Query<(Entity, &mut Transform), With<Text2d>>,
66    time: Res<Time>,
67) {
68    for (entity, mut position) in &mut texts {
69        position.translation -= Vec3::new(0.0, 100.0 * time.delta_secs(), 0.0);
70        if position.translation.y < -300.0 {
71            commands.entity(entity).despawn();
72        }
73    }
74}
examples/animation/gltf_skinned_mesh.rs (line 24)
20fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
21    // Create a camera
22    commands.spawn((
23        Camera3d::default(),
24        Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::new(0.0, 1.0, 0.0), Vec3::Y),
25    ));
26
27    // Spawn the first scene in `models/SimpleSkin/SimpleSkin.gltf`
28    commands.spawn(SceneRoot(asset_server.load(
29        GltfAssetLabel::Scene(0).from_asset("models/SimpleSkin/SimpleSkin.gltf"),
30    )));
31}
examples/async_tasks/async_compute.rs (line 136)
121fn setup_env(mut commands: Commands) {
122    // Used to center camera on spawned cubes
123    let offset = if NUM_CUBES % 2 == 0 {
124        (NUM_CUBES / 2) as f32 - 0.5
125    } else {
126        (NUM_CUBES / 2) as f32
127    };
128
129    // lights
130    commands.spawn((PointLight::default(), Transform::from_xyz(4.0, 12.0, 15.0)));
131
132    // camera
133    commands.spawn((
134        Camera3d::default(),
135        Transform::from_xyz(offset, offset, 15.0)
136            .looking_at(Vec3::new(offset, offset, 0.0), Vec3::Y),
137    ));
138}
Source

pub const fn splat(v: f32) -> Vec3

Creates a vector with all elements set to v.

Examples found in repository?
examples/testbed/3d.rs (line 319)
317    pub fn draw_gizmos(mut gizmos: Gizmos) {
318        gizmos.cuboid(
319            Transform::from_translation(Vec3::X * 2.0).with_scale(Vec3::splat(2.0)),
320            RED,
321        );
322        gizmos
323            .sphere(Isometry3d::from_translation(Vec3::X * -2.0), 1.0, GREEN)
324            .resolution(30_000 / 3);
325    }
More examples
Hide additional examples
examples/3d/irradiance_volumes.rs (line 274)
269fn spawn_sphere(commands: &mut Commands, assets: &ExampleAssets) {
270    commands
271        .spawn((
272            Mesh3d(assets.main_sphere.clone()),
273            MeshMaterial3d(assets.main_sphere_material.clone()),
274            Transform::from_xyz(0.0, SPHERE_SCALE, 0.0).with_scale(Vec3::splat(SPHERE_SCALE)),
275        ))
276        .insert(MainObject);
277}
278
279fn spawn_voxel_cube_parent(commands: &mut Commands) {
280    commands.spawn((Visibility::Hidden, Transform::default(), VoxelCubeParent));
281}
282
283fn spawn_fox(commands: &mut Commands, assets: &ExampleAssets) {
284    commands.spawn((
285        SceneRoot(assets.fox.clone()),
286        Visibility::Hidden,
287        Transform::from_scale(Vec3::splat(FOX_SCALE)),
288        MainObject,
289    ));
290}
291
292fn spawn_text(commands: &mut Commands, app_status: &AppStatus) {
293    commands.spawn((
294        app_status.create_text(),
295        Node {
296            position_type: PositionType::Absolute,
297            bottom: Val::Px(12.0),
298            left: Val::Px(12.0),
299            ..default()
300        },
301    ));
302}
303
304// A system that updates the help text.
305fn update_text(mut text_query: Query<&mut Text>, app_status: Res<AppStatus>) {
306    for mut text in text_query.iter_mut() {
307        *text = app_status.create_text();
308    }
309}
310
311impl AppStatus {
312    // Constructs the help text at the bottom of the screen based on the
313    // application status.
314    fn create_text(&self) -> Text {
315        let irradiance_volume_help_text = if self.irradiance_volume_present {
316            DISABLE_IRRADIANCE_VOLUME_HELP_TEXT
317        } else {
318            ENABLE_IRRADIANCE_VOLUME_HELP_TEXT
319        };
320
321        let voxels_help_text = if self.voxels_visible {
322            HIDE_VOXELS_HELP_TEXT
323        } else {
324            SHOW_VOXELS_HELP_TEXT
325        };
326
327        let rotation_help_text = if self.rotating {
328            STOP_ROTATION_HELP_TEXT
329        } else {
330            START_ROTATION_HELP_TEXT
331        };
332
333        let switch_mesh_help_text = match self.model {
334            ExampleModel::Sphere => SWITCH_TO_FOX_HELP_TEXT,
335            ExampleModel::Fox => SWITCH_TO_SPHERE_HELP_TEXT,
336        };
337
338        format!(
339            "{CLICK_TO_MOVE_HELP_TEXT}\n\
340            {voxels_help_text}\n\
341            {irradiance_volume_help_text}\n\
342            {rotation_help_text}\n\
343            {switch_mesh_help_text}"
344        )
345        .into()
346    }
347}
348
349// Rotates the camera a bit every frame.
350fn rotate_camera(
351    mut camera_query: Query<&mut Transform, With<Camera3d>>,
352    time: Res<Time>,
353    app_status: Res<AppStatus>,
354) {
355    if !app_status.rotating {
356        return;
357    }
358
359    for mut transform in camera_query.iter_mut() {
360        transform.translation = Vec2::from_angle(ROTATION_SPEED * time.delta_secs())
361            .rotate(transform.translation.xz())
362            .extend(transform.translation.y)
363            .xzy();
364        transform.look_at(Vec3::ZERO, Vec3::Y);
365    }
366}
367
368// Toggles between the unskinned sphere model and the skinned fox model if the
369// user requests it.
370fn change_main_object(
371    keyboard: Res<ButtonInput<KeyCode>>,
372    mut app_status: ResMut<AppStatus>,
373    mut sphere_query: Query<&mut Visibility, (With<MainObject>, With<Mesh3d>, Without<SceneRoot>)>,
374    mut fox_query: Query<&mut Visibility, (With<MainObject>, With<SceneRoot>)>,
375) {
376    if !keyboard.just_pressed(KeyCode::Tab) {
377        return;
378    }
379    let Some(mut sphere_visibility) = sphere_query.iter_mut().next() else {
380        return;
381    };
382    let Some(mut fox_visibility) = fox_query.iter_mut().next() else {
383        return;
384    };
385
386    match app_status.model {
387        ExampleModel::Sphere => {
388            *sphere_visibility = Visibility::Hidden;
389            *fox_visibility = Visibility::Visible;
390            app_status.model = ExampleModel::Fox;
391        }
392        ExampleModel::Fox => {
393            *sphere_visibility = Visibility::Visible;
394            *fox_visibility = Visibility::Hidden;
395            app_status.model = ExampleModel::Sphere;
396        }
397    }
398}
399
400impl Default for AppStatus {
401    fn default() -> Self {
402        Self {
403            irradiance_volume_present: true,
404            rotating: true,
405            model: ExampleModel::Sphere,
406            voxels_visible: false,
407        }
408    }
409}
410
411// Turns on and off the irradiance volume as requested by the user.
412fn toggle_irradiance_volumes(
413    mut commands: Commands,
414    keyboard: Res<ButtonInput<KeyCode>>,
415    light_probe_query: Query<Entity, With<LightProbe>>,
416    mut app_status: ResMut<AppStatus>,
417    assets: Res<ExampleAssets>,
418    mut ambient_light: ResMut<AmbientLight>,
419) {
420    if !keyboard.just_pressed(KeyCode::Space) {
421        return;
422    };
423
424    let Some(light_probe) = light_probe_query.iter().next() else {
425        return;
426    };
427
428    if app_status.irradiance_volume_present {
429        commands.entity(light_probe).remove::<IrradianceVolume>();
430        ambient_light.brightness = AMBIENT_LIGHT_BRIGHTNESS * IRRADIANCE_VOLUME_INTENSITY;
431        app_status.irradiance_volume_present = false;
432    } else {
433        commands.entity(light_probe).insert(IrradianceVolume {
434            voxels: assets.irradiance_volume.clone(),
435            intensity: IRRADIANCE_VOLUME_INTENSITY,
436            ..default()
437        });
438        ambient_light.brightness = 0.0;
439        app_status.irradiance_volume_present = true;
440    }
441}
442
443fn toggle_rotation(keyboard: Res<ButtonInput<KeyCode>>, mut app_status: ResMut<AppStatus>) {
444    if keyboard.just_pressed(KeyCode::Enter) {
445        app_status.rotating = !app_status.rotating;
446    }
447}
448
449// Handles clicks on the plane that reposition the object.
450fn handle_mouse_clicks(
451    buttons: Res<ButtonInput<MouseButton>>,
452    windows: Query<&Window, With<PrimaryWindow>>,
453    cameras: Query<(&Camera, &GlobalTransform)>,
454    mut main_objects: Query<&mut Transform, With<MainObject>>,
455) {
456    if !buttons.pressed(MouseButton::Left) {
457        return;
458    }
459    let Some(mouse_position) = windows.iter().next().and_then(Window::cursor_position) else {
460        return;
461    };
462    let Some((camera, camera_transform)) = cameras.iter().next() else {
463        return;
464    };
465
466    // Figure out where the user clicked on the plane.
467    let Ok(ray) = camera.viewport_to_world(camera_transform, mouse_position) else {
468        return;
469    };
470    let Some(ray_distance) = ray.intersect_plane(Vec3::ZERO, InfinitePlane3d::new(Vec3::Y)) else {
471        return;
472    };
473    let plane_intersection = ray.origin + ray.direction.normalize() * ray_distance;
474
475    // Move all the main objects.
476    for mut transform in main_objects.iter_mut() {
477        transform.translation = vec3(
478            plane_intersection.x,
479            transform.translation.y,
480            plane_intersection.z,
481        );
482    }
483}
484
485impl FromWorld for ExampleAssets {
486    fn from_world(world: &mut World) -> Self {
487        let fox_animation =
488            world.load_asset(GltfAssetLabel::Animation(1).from_asset("models/animated/Fox.glb"));
489        let (fox_animation_graph, fox_animation_node) =
490            AnimationGraph::from_clip(fox_animation.clone());
491
492        ExampleAssets {
493            main_sphere: world.add_asset(Sphere::default().mesh().uv(32, 18)),
494            fox: world.load_asset(GltfAssetLabel::Scene(0).from_asset("models/animated/Fox.glb")),
495            main_sphere_material: world.add_asset(Color::from(SILVER)),
496            main_scene: world.load_asset(
497                GltfAssetLabel::Scene(0)
498                    .from_asset("models/IrradianceVolumeExample/IrradianceVolumeExample.glb"),
499            ),
500            irradiance_volume: world.load_asset("irradiance_volumes/Example.vxgi.ktx2"),
501            fox_animation_graph: world.add_asset(fox_animation_graph),
502            fox_animation_node,
503            voxel_cube: world.add_asset(Cuboid::default()),
504            // Just use a specular map for the skybox since it's not too blurry.
505            // In reality you wouldn't do this--you'd use a real skybox texture--but
506            // reusing the textures like this saves space in the Bevy repository.
507            skybox: world.load_asset("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
508        }
509    }
510}
511
512// Plays the animation on the fox.
513fn play_animations(
514    mut commands: Commands,
515    assets: Res<ExampleAssets>,
516    mut players: Query<(Entity, &mut AnimationPlayer), Without<AnimationGraphHandle>>,
517) {
518    for (entity, mut player) in players.iter_mut() {
519        commands
520            .entity(entity)
521            .insert(AnimationGraphHandle(assets.fox_animation_graph.clone()));
522        player.play(assets.fox_animation_node).repeat();
523    }
524}
525
526fn create_cubes(
527    image_assets: Res<Assets<Image>>,
528    mut commands: Commands,
529    irradiance_volumes: Query<(&IrradianceVolume, &GlobalTransform)>,
530    voxel_cube_parents: Query<Entity, With<VoxelCubeParent>>,
531    voxel_cubes: Query<Entity, With<VoxelCube>>,
532    example_assets: Res<ExampleAssets>,
533    mut voxel_visualization_material_assets: ResMut<Assets<VoxelVisualizationMaterial>>,
534) {
535    // If voxel cubes have already been spawned, don't do anything.
536    if !voxel_cubes.is_empty() {
537        return;
538    }
539
540    let Some(voxel_cube_parent) = voxel_cube_parents.iter().next() else {
541        return;
542    };
543
544    for (irradiance_volume, global_transform) in irradiance_volumes.iter() {
545        let Some(image) = image_assets.get(&irradiance_volume.voxels) else {
546            continue;
547        };
548
549        let resolution = image.texture_descriptor.size;
550
551        let voxel_cube_material = voxel_visualization_material_assets.add(ExtendedMaterial {
552            base: StandardMaterial::from(Color::from(RED)),
553            extension: VoxelVisualizationExtension {
554                irradiance_volume_info: VoxelVisualizationIrradianceVolumeInfo {
555                    world_from_voxel: VOXEL_FROM_WORLD.inverse(),
556                    voxel_from_world: VOXEL_FROM_WORLD,
557                    resolution: uvec3(
558                        resolution.width,
559                        resolution.height,
560                        resolution.depth_or_array_layers,
561                    ),
562                    intensity: IRRADIANCE_VOLUME_INTENSITY,
563                },
564            },
565        });
566
567        let scale = vec3(
568            1.0 / resolution.width as f32,
569            1.0 / resolution.height as f32,
570            1.0 / resolution.depth_or_array_layers as f32,
571        );
572
573        // Spawn a cube for each voxel.
574        for z in 0..resolution.depth_or_array_layers {
575            for y in 0..resolution.height {
576                for x in 0..resolution.width {
577                    let uvw = (uvec3(x, y, z).as_vec3() + 0.5) * scale - 0.5;
578                    let pos = global_transform.transform_point(uvw);
579                    let voxel_cube = commands
580                        .spawn((
581                            Mesh3d(example_assets.voxel_cube.clone()),
582                            MeshMaterial3d(voxel_cube_material.clone()),
583                            Transform::from_scale(Vec3::splat(VOXEL_CUBE_SCALE))
584                                .with_translation(pos),
585                        ))
586                        .insert(VoxelCube)
587                        .insert(NotShadowCaster)
588                        .id();
589
590                    commands.entity(voxel_cube_parent).add_child(voxel_cube);
591                }
592            }
593        }
594    }
595}
examples/2d/mesh2d.rs (line 22)
12fn setup(
13    mut commands: Commands,
14    mut meshes: ResMut<Assets<Mesh>>,
15    mut materials: ResMut<Assets<ColorMaterial>>,
16) {
17    commands.spawn(Camera2d);
18
19    commands.spawn((
20        Mesh2d(meshes.add(Rectangle::default())),
21        MeshMaterial2d(materials.add(Color::from(PURPLE))),
22        Transform::default().with_scale(Vec3::splat(128.)),
23    ));
24}
examples/3d/ssr.rs (line 168)
162fn spawn_flight_helmet(commands: &mut Commands, asset_server: &AssetServer) {
163    commands.spawn((
164        SceneRoot(
165            asset_server
166                .load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
167        ),
168        Transform::from_scale(Vec3::splat(2.5)),
169        FlightHelmetModel,
170        Visibility::Hidden,
171    ));
172}
173
174// Spawns the water plane.
175fn spawn_water(
176    commands: &mut Commands,
177    asset_server: &AssetServer,
178    meshes: &mut Assets<Mesh>,
179    water_materials: &mut Assets<ExtendedMaterial<StandardMaterial, Water>>,
180) {
181    commands.spawn((
182        Mesh3d(meshes.add(Plane3d::new(Vec3::Y, Vec2::splat(1.0)))),
183        MeshMaterial3d(water_materials.add(ExtendedMaterial {
184            base: StandardMaterial {
185                base_color: BLACK.into(),
186                perceptual_roughness: 0.0,
187                ..default()
188            },
189            extension: Water {
190                normals: asset_server.load_with_settings::<Image, ImageLoaderSettings>(
191                    "textures/water_normals.png",
192                    |settings| {
193                        settings.is_srgb = false;
194                        settings.sampler = ImageSampler::Descriptor(ImageSamplerDescriptor {
195                            address_mode_u: ImageAddressMode::Repeat,
196                            address_mode_v: ImageAddressMode::Repeat,
197                            mag_filter: ImageFilterMode::Linear,
198                            min_filter: ImageFilterMode::Linear,
199                            ..default()
200                        });
201                    },
202                ),
203                // These water settings are just random values to create some
204                // variety.
205                settings: WaterSettings {
206                    octave_vectors: [
207                        vec4(0.080, 0.059, 0.073, -0.062),
208                        vec4(0.153, 0.138, -0.149, -0.195),
209                    ],
210                    octave_scales: vec4(1.0, 2.1, 7.9, 14.9) * 5.0,
211                    octave_strengths: vec4(0.16, 0.18, 0.093, 0.044),
212                },
213            },
214        })),
215        Transform::from_scale(Vec3::splat(100.0)),
216    ));
217}
examples/2d/pixel_grid_snap.rs (line 80)
72fn setup_mesh(
73    mut commands: Commands,
74    mut meshes: ResMut<Assets<Mesh>>,
75    mut materials: ResMut<Assets<ColorMaterial>>,
76) {
77    commands.spawn((
78        Mesh2d(meshes.add(Capsule2d::default())),
79        MeshMaterial2d(materials.add(Color::BLACK)),
80        Transform::from_xyz(25., 0., 2.).with_scale(Vec3::splat(32.)),
81        Rotate,
82        PIXEL_PERFECT_LAYERS,
83    ));
84}
examples/games/alien_cake_addict.rs (line 370)
365fn rotate_bonus(game: Res<Game>, time: Res<Time>, mut transforms: Query<&mut Transform>) {
366    if let Some(entity) = game.bonus.entity {
367        if let Ok(mut cake_transform) = transforms.get_mut(entity) {
368            cake_transform.rotate_y(time.delta_secs());
369            cake_transform.scale =
370                Vec3::splat(1.0 + (game.score as f32 / 10.0 * ops::sin(time.elapsed_secs())).abs());
371        }
372    }
373}
Source

pub fn map<F>(self, f: F) -> Vec3
where F: Fn(f32) -> f32,

Returns a vector containing each element of self modified by a mapping function f.

Source

pub fn select(mask: BVec3, if_true: Vec3, if_false: Vec3) -> Vec3

Creates a vector from the elements in if_true and if_false, selecting which to use for each element of self.

A true element in the mask uses the corresponding element from if_true, and false uses the element from if_false.

Source

pub const fn from_array(a: [f32; 3]) -> Vec3

Creates a new vector from an array.

Source

pub const fn to_array(&self) -> [f32; 3]

[x, y, z]

Source

pub const fn from_slice(slice: &[f32]) -> Vec3

Creates a vector from the first 3 values in slice.

§Panics

Panics if slice is less than 3 elements long.

Examples found in repository?
examples/3d/occlusion_culling.rs (line 325)
284fn spawn_small_cubes(
285    commands: &mut Commands,
286    meshes: &mut Assets<Mesh>,
287    materials: &mut Assets<StandardMaterial>,
288) {
289    // Add the cube mesh.
290    let small_cube = meshes.add(Cuboid::new(
291        SMALL_CUBE_SIZE,
292        SMALL_CUBE_SIZE,
293        SMALL_CUBE_SIZE,
294    ));
295
296    // Add the cube material.
297    let small_cube_material = materials.add(StandardMaterial {
298        base_color: SILVER.into(),
299        ..default()
300    });
301
302    // Create the entity that the small cubes will be parented to. This is the
303    // entity that we rotate.
304    let sphere_parent = commands
305        .spawn(Transform::from_translation(Vec3::ZERO))
306        .insert(Visibility::default())
307        .insert(SphereParent)
308        .id();
309
310    // Now we have to figure out where to place the cubes. To do that, we create
311    // a sphere mesh, but we don't add it to the scene. Instead, we inspect the
312    // sphere mesh to find the positions of its vertices, and spawn a small cube
313    // at each one. That way, we end up with a bunch of cubes arranged in a
314    // spherical shape.
315
316    // Create the sphere mesh, and extract the positions of its vertices.
317    let sphere = Sphere::new(OUTER_RADIUS)
318        .mesh()
319        .ico(OUTER_SUBDIVISION_COUNT)
320        .unwrap();
321    let sphere_positions = sphere.attribute(Mesh::ATTRIBUTE_POSITION).unwrap();
322
323    // At each vertex, create a small cube.
324    for sphere_position in sphere_positions.as_float3().unwrap() {
325        let sphere_position = Vec3::from_slice(sphere_position);
326        let small_cube = commands
327            .spawn(Mesh3d(small_cube.clone()))
328            .insert(MeshMaterial3d(small_cube_material.clone()))
329            .insert(Transform::from_translation(sphere_position))
330            .id();
331        commands.entity(sphere_parent).add_child(small_cube);
332    }
333}
Source

pub fn write_to_slice(self, slice: &mut [f32])

Writes the elements of self to the first 3 elements in slice.

§Panics

Panics if slice is less than 3 elements long.

Source

pub fn extend(self, w: f32) -> Vec4

Creates a 4D vector from self and the given w value.

Source

pub fn truncate(self) -> Vec2

Creates a 2D vector from the x and y elements of self, discarding z.

Truncation may also be performed by using self.xy().

Examples found in repository?
examples/ecs/observers.rs (line 186)
172fn handle_click(
173    mouse_button_input: Res<ButtonInput<MouseButton>>,
174    camera: Single<(&Camera, &GlobalTransform)>,
175    windows: Query<&Window>,
176    mut commands: Commands,
177) {
178    let Ok(windows) = windows.single() else {
179        return;
180    };
181
182    let (camera, camera_transform) = *camera;
183    if let Some(pos) = windows
184        .cursor_position()
185        .and_then(|cursor| camera.viewport_to_world(camera_transform, cursor).ok())
186        .map(|ray| ray.origin.truncate())
187    {
188        if mouse_button_input.just_pressed(MouseButton::Left) {
189            commands.trigger(ExplodeMines { pos, radius: 1.0 });
190        }
191    }
192}
More examples
Hide additional examples
examples/2d/mesh2d_arcs.rs (line 110)
104fn draw_bounds<Shape: Bounded2d + Send + Sync + 'static>(
105    q: Query<(&DrawBounds<Shape>, &GlobalTransform)>,
106    mut gizmos: Gizmos,
107) {
108    for (shape, transform) in &q {
109        let (_, rotation, translation) = transform.to_scale_rotation_translation();
110        let translation = translation.truncate();
111        let rotation = rotation.to_euler(EulerRot::XYZ).2;
112        let isometry = Isometry2d::new(translation, Rot2::radians(rotation));
113
114        let aabb = shape.0.aabb_2d(isometry);
115        gizmos.rect_2d(aabb.center(), aabb.half_size() * 2.0, RED);
116
117        let bounding_circle = shape.0.bounding_circle(isometry);
118        gizmos.circle_2d(bounding_circle.center, bounding_circle.radius(), BLUE);
119    }
120}
examples/games/desk_toy.rs (line 239)
220fn update_cursor_hit_test(
221    cursor_world_pos: Res<CursorWorldPos>,
222    mut primary_window: Single<&mut Window, With<PrimaryWindow>>,
223    bevy_logo_transform: Single<&Transform, With<BevyLogo>>,
224) {
225    // If the window has decorations (e.g. a border) then it should be clickable
226    if primary_window.decorations {
227        primary_window.cursor_options.hit_test = true;
228        return;
229    }
230
231    // If the cursor is not within the window we don't need to update whether the window is clickable or not
232    let Some(cursor_world_pos) = cursor_world_pos.0 else {
233        return;
234    };
235
236    // If the cursor is within the radius of the Bevy logo make the window clickable otherwise the window is not clickable
237    primary_window.cursor_options.hit_test = bevy_logo_transform
238        .translation
239        .truncate()
240        .distance(cursor_world_pos)
241        < BEVY_LOGO_RADIUS;
242}
243
244/// Start the drag operation and record the offset we started dragging from
245fn start_drag(
246    mut commands: Commands,
247    cursor_world_pos: Res<CursorWorldPos>,
248    bevy_logo_transform: Single<&Transform, With<BevyLogo>>,
249) {
250    // If the cursor is not within the primary window skip this system
251    let Some(cursor_world_pos) = cursor_world_pos.0 else {
252        return;
253    };
254
255    // Get the offset from the cursor to the Bevy logo sprite
256    let drag_offset = bevy_logo_transform.translation.truncate() - cursor_world_pos;
257
258    // If the cursor is within the Bevy logo radius start the drag operation and remember the offset of the cursor from the origin
259    if drag_offset.length() < BEVY_LOGO_RADIUS {
260        commands.insert_resource(DragOperation(drag_offset));
261    }
262}
263
264/// Stop the current drag operation
265fn end_drag(mut commands: Commands) {
266    commands.remove_resource::<DragOperation>();
267}
268
269/// Drag the Bevy logo
270fn drag(
271    drag_offset: Res<DragOperation>,
272    cursor_world_pos: Res<CursorWorldPos>,
273    time: Res<Time>,
274    mut bevy_transform: Single<&mut Transform, With<BevyLogo>>,
275    mut q_pupils: Query<&mut Pupil>,
276) {
277    // If the cursor is not within the primary window skip this system
278    let Some(cursor_world_pos) = cursor_world_pos.0 else {
279        return;
280    };
281
282    // Calculate the new translation of the Bevy logo based on cursor and drag offset
283    let new_translation = cursor_world_pos + drag_offset.0;
284
285    // Calculate how fast we are dragging the Bevy logo (unit/second)
286    let drag_velocity =
287        (new_translation - bevy_transform.translation.truncate()) / time.delta_secs();
288
289    // Update the translation of Bevy logo transform to new translation
290    bevy_transform.translation = new_translation.extend(bevy_transform.translation.z);
291
292    // Add the cursor drag velocity in the opposite direction to each pupil.
293    // Remember pupils are using local coordinates to move. So when the Bevy logo moves right they need to move left to
294    // simulate inertia, otherwise they will move fixed to the parent.
295    for mut pupil in &mut q_pupils {
296        pupil.velocity -= drag_velocity;
297    }
298}
299
300/// Quit when the user right clicks the Bevy logo
301fn quit(
302    cursor_world_pos: Res<CursorWorldPos>,
303    mut app_exit: EventWriter<AppExit>,
304    bevy_logo_transform: Single<&Transform, With<BevyLogo>>,
305) {
306    // If the cursor is not within the primary window skip this system
307    let Some(cursor_world_pos) = cursor_world_pos.0 else {
308        return;
309    };
310
311    // If the cursor is within the Bevy logo radius send the [`AppExit`] event to quit the app
312    if bevy_logo_transform
313        .translation
314        .truncate()
315        .distance(cursor_world_pos)
316        < BEVY_LOGO_RADIUS
317    {
318        app_exit.write(AppExit::Success);
319    }
320}
321
322/// Enable transparency for the window and make it on top
323fn toggle_transparency(
324    mut commands: Commands,
325    mut window_transparency: ResMut<WindowTransparency>,
326    mut q_instructions_text: Query<&mut Visibility, With<InstructionsText>>,
327    mut primary_window: Single<&mut Window, With<PrimaryWindow>>,
328) {
329    // Toggle the window transparency resource
330    window_transparency.0 = !window_transparency.0;
331
332    // Show or hide the instructions text
333    for mut visibility in &mut q_instructions_text {
334        *visibility = if window_transparency.0 {
335            Visibility::Hidden
336        } else {
337            Visibility::Visible
338        };
339    }
340
341    // Remove the primary window's decorations (e.g. borders), make it always on top of other desktop windows, and set the clear color to transparent
342    // only if window transparency is enabled
343    let clear_color;
344    (
345        primary_window.decorations,
346        primary_window.window_level,
347        clear_color,
348    ) = if window_transparency.0 {
349        (false, WindowLevel::AlwaysOnTop, Color::NONE)
350    } else {
351        (true, WindowLevel::Normal, WINDOW_CLEAR_COLOR)
352    };
353
354    // Set the clear color
355    commands.insert_resource(ClearColor(clear_color));
356}
357
358/// Move the pupils and bounce them around
359fn move_pupils(time: Res<Time>, mut q_pupils: Query<(&mut Pupil, &mut Transform)>) {
360    for (mut pupil, mut transform) in &mut q_pupils {
361        // The wiggle radius is how much the pupil can move within the eye
362        let wiggle_radius = pupil.eye_radius - pupil.pupil_radius;
363        // Store the Z component
364        let z = transform.translation.z;
365        // Truncate the Z component to make the calculations be on [`Vec2`]
366        let mut translation = transform.translation.truncate();
367        // Decay the pupil velocity
368        pupil.velocity *= ops::powf(0.04f32, time.delta_secs());
369        // Move the pupil
370        translation += pupil.velocity * time.delta_secs();
371        // If the pupil hit the outside border of the eye, limit the translation to be within the wiggle radius and invert the velocity.
372        // This is not physically accurate but it's good enough for the googly eyes effect.
373        if translation.length() > wiggle_radius {
374            translation = translation.normalize() * wiggle_radius;
375            // Invert and decrease the velocity of the pupil when it bounces
376            pupil.velocity *= -0.75;
377        }
378        // Update the entity transform with the new translation after reading the Z component
379        transform.translation = translation.extend(z);
380    }
381}
examples/games/breakout.rs (line 351)
340fn check_for_collisions(
341    mut commands: Commands,
342    mut score: ResMut<Score>,
343    ball_query: Single<(&mut Velocity, &Transform), With<Ball>>,
344    collider_query: Query<(Entity, &Transform, Option<&Brick>), With<Collider>>,
345    mut collision_events: EventWriter<CollisionEvent>,
346) {
347    let (mut ball_velocity, ball_transform) = ball_query.into_inner();
348
349    for (collider_entity, collider_transform, maybe_brick) in &collider_query {
350        let collision = ball_collision(
351            BoundingCircle::new(ball_transform.translation.truncate(), BALL_DIAMETER / 2.),
352            Aabb2d::new(
353                collider_transform.translation.truncate(),
354                collider_transform.scale.truncate() / 2.,
355            ),
356        );
357
358        if let Some(collision) = collision {
359            // Writes a collision event so that other systems can react to the collision
360            collision_events.write_default();
361
362            // Bricks should be despawned and increment the scoreboard on collision
363            if maybe_brick.is_some() {
364                commands.entity(collider_entity).despawn();
365                **score += 1;
366            }
367
368            // Reflect the ball's velocity when it collides
369            let mut reflect_x = false;
370            let mut reflect_y = false;
371
372            // Reflect only if the velocity is in the opposite direction of the collision
373            // This prevents the ball from getting stuck inside the bar
374            match collision {
375                Collision::Left => reflect_x = ball_velocity.x > 0.0,
376                Collision::Right => reflect_x = ball_velocity.x < 0.0,
377                Collision::Top => reflect_y = ball_velocity.y < 0.0,
378                Collision::Bottom => reflect_y = ball_velocity.y > 0.0,
379            }
380
381            // Reflect velocity on the x-axis if we hit something on the x-axis
382            if reflect_x {
383                ball_velocity.x = -ball_velocity.x;
384            }
385
386            // Reflect velocity on the y-axis if we hit something on the y-axis
387            if reflect_y {
388                ball_velocity.y = -ball_velocity.y;
389            }
390        }
391    }
392}
Source

pub fn with_x(self, x: f32) -> Vec3

Creates a 3D vector from self with the given value of x.

Source

pub fn with_y(self, y: f32) -> Vec3

Creates a 3D vector from self with the given value of y.

Source

pub fn with_z(self, z: f32) -> Vec3

Creates a 3D vector from self with the given value of z.

Source

pub fn dot(self, rhs: Vec3) -> f32

Computes the dot product of self and rhs.

Source

pub fn dot_into_vec(self, rhs: Vec3) -> Vec3

Returns a vector where every component is the dot product of self and rhs.

Source

pub fn cross(self, rhs: Vec3) -> Vec3

Computes the cross product of self and rhs.

Examples found in repository?
examples/ecs/fallible_params.rs (line 151)
137fn track_targets(
138    // `Single` ensures the system runs ONLY when exactly one matching entity exists.
139    mut player: Single<(&mut Transform, &Player)>,
140    // `Option<Single>` ensures that the system runs ONLY when zero or one matching entity exists.
141    enemy: Option<Single<&Transform, (With<Enemy>, Without<Player>)>>,
142    time: Res<Time>,
143) {
144    let (player_transform, player) = &mut *player;
145    if let Some(enemy_transform) = enemy {
146        // Enemy found, rotate and move towards it.
147        let delta = enemy_transform.translation - player_transform.translation;
148        let distance = delta.length();
149        let front = delta / distance;
150        let up = Vec3::Z;
151        let side = front.cross(up);
152        player_transform.rotation = Quat::from_mat3(&Mat3::from_cols(side, front, up));
153        let max_step = distance - player.min_follow_radius;
154        if 0.0 < max_step {
155            let velocity = (player.speed * time.delta_secs()).min(max_step);
156            player_transform.translation += front * velocity;
157        }
158    } else {
159        // 0 or multiple enemies found, keep searching.
160        player_transform.rotate_axis(Dir3::Z, player.rotation_speed * time.delta_secs());
161    }
162}
Source

pub fn min(self, rhs: Vec3) -> Vec3

Returns a vector containing the minimum values for each element of self and rhs.

In other words this computes [self.x.min(rhs.x), self.y.min(rhs.y), ..].

Examples found in repository?
examples/2d/rotation.rs (line 150)
112fn player_movement_system(
113    time: Res<Time>,
114    keyboard_input: Res<ButtonInput<KeyCode>>,
115    query: Single<(&Player, &mut Transform)>,
116) {
117    let (ship, mut transform) = query.into_inner();
118
119    let mut rotation_factor = 0.0;
120    let mut movement_factor = 0.0;
121
122    if keyboard_input.pressed(KeyCode::ArrowLeft) {
123        rotation_factor += 1.0;
124    }
125
126    if keyboard_input.pressed(KeyCode::ArrowRight) {
127        rotation_factor -= 1.0;
128    }
129
130    if keyboard_input.pressed(KeyCode::ArrowUp) {
131        movement_factor += 1.0;
132    }
133
134    // Update the ship rotation around the Z axis (perpendicular to the 2D plane of the screen)
135    transform.rotate_z(rotation_factor * ship.rotation_speed * time.delta_secs());
136
137    // Get the ship's forward vector by applying the current rotation to the ships initial facing
138    // vector
139    let movement_direction = transform.rotation * Vec3::Y;
140    // Get the distance the ship will move based on direction, the ship's movement speed and delta
141    // time
142    let movement_distance = movement_factor * ship.movement_speed * time.delta_secs();
143    // Create the change in translation using the new movement direction and distance
144    let translation_delta = movement_direction * movement_distance;
145    // Update the ship translation with our new translation delta
146    transform.translation += translation_delta;
147
148    // Bound the ship within the invisible level bounds
149    let extents = Vec3::from((BOUNDS / 2.0, 0.0));
150    transform.translation = transform.translation.min(extents).max(-extents);
151}
Source

pub fn max(self, rhs: Vec3) -> Vec3

Returns a vector containing the maximum values for each element of self and rhs.

In other words this computes [self.x.max(rhs.x), self.y.max(rhs.y), ..].

Examples found in repository?
examples/2d/rotation.rs (line 150)
112fn player_movement_system(
113    time: Res<Time>,
114    keyboard_input: Res<ButtonInput<KeyCode>>,
115    query: Single<(&Player, &mut Transform)>,
116) {
117    let (ship, mut transform) = query.into_inner();
118
119    let mut rotation_factor = 0.0;
120    let mut movement_factor = 0.0;
121
122    if keyboard_input.pressed(KeyCode::ArrowLeft) {
123        rotation_factor += 1.0;
124    }
125
126    if keyboard_input.pressed(KeyCode::ArrowRight) {
127        rotation_factor -= 1.0;
128    }
129
130    if keyboard_input.pressed(KeyCode::ArrowUp) {
131        movement_factor += 1.0;
132    }
133
134    // Update the ship rotation around the Z axis (perpendicular to the 2D plane of the screen)
135    transform.rotate_z(rotation_factor * ship.rotation_speed * time.delta_secs());
136
137    // Get the ship's forward vector by applying the current rotation to the ships initial facing
138    // vector
139    let movement_direction = transform.rotation * Vec3::Y;
140    // Get the distance the ship will move based on direction, the ship's movement speed and delta
141    // time
142    let movement_distance = movement_factor * ship.movement_speed * time.delta_secs();
143    // Create the change in translation using the new movement direction and distance
144    let translation_delta = movement_direction * movement_distance;
145    // Update the ship translation with our new translation delta
146    transform.translation += translation_delta;
147
148    // Bound the ship within the invisible level bounds
149    let extents = Vec3::from((BOUNDS / 2.0, 0.0));
150    transform.translation = transform.translation.min(extents).max(-extents);
151}
Source

pub fn clamp(self, min: Vec3, max: Vec3) -> Vec3

Component-wise clamping of values, similar to f32::clamp.

Each element in min must be less-or-equal to the corresponding element in max.

§Panics

Will panic if min is greater than max when glam_assert is enabled.

Source

pub fn min_element(self) -> f32

Returns the horizontal minimum of self.

In other words this computes min(x, y, ..).

Examples found in repository?
examples/transforms/scale.rs (line 81)
65fn change_scale_direction(mut cubes: Query<(&mut Transform, &mut Scaling)>) {
66    for (mut transform, mut cube) in &mut cubes {
67        // If an entity scaled beyond the maximum of its size in any dimension
68        // the scaling vector is flipped so the scaling is gradually reverted.
69        // Additionally, to ensure the condition does not trigger again we floor the elements to
70        // their next full value, which should be max_element_size at max.
71        if transform.scale.max_element() > cube.max_element_size {
72            cube.scale_direction *= -1.0;
73            transform.scale = transform.scale.floor();
74        }
75        // If an entity scaled beyond the minimum of its size in any dimension
76        // the scaling vector is also flipped.
77        // Additionally the Values are ceiled to be min_element_size at least
78        // and the scale direction is flipped.
79        // This way the entity will change the dimension in which it is scaled any time it
80        // reaches its min_element_size.
81        if transform.scale.min_element() < cube.min_element_size {
82            cube.scale_direction *= -1.0;
83            transform.scale = transform.scale.ceil();
84            cube.scale_direction = cube.scale_direction.zxy();
85        }
86    }
87}
Source

pub fn max_element(self) -> f32

Returns the horizontal maximum of self.

In other words this computes max(x, y, ..).

Examples found in repository?
examples/transforms/scale.rs (line 71)
65fn change_scale_direction(mut cubes: Query<(&mut Transform, &mut Scaling)>) {
66    for (mut transform, mut cube) in &mut cubes {
67        // If an entity scaled beyond the maximum of its size in any dimension
68        // the scaling vector is flipped so the scaling is gradually reverted.
69        // Additionally, to ensure the condition does not trigger again we floor the elements to
70        // their next full value, which should be max_element_size at max.
71        if transform.scale.max_element() > cube.max_element_size {
72            cube.scale_direction *= -1.0;
73            transform.scale = transform.scale.floor();
74        }
75        // If an entity scaled beyond the minimum of its size in any dimension
76        // the scaling vector is also flipped.
77        // Additionally the Values are ceiled to be min_element_size at least
78        // and the scale direction is flipped.
79        // This way the entity will change the dimension in which it is scaled any time it
80        // reaches its min_element_size.
81        if transform.scale.min_element() < cube.min_element_size {
82            cube.scale_direction *= -1.0;
83            transform.scale = transform.scale.ceil();
84            cube.scale_direction = cube.scale_direction.zxy();
85        }
86    }
87}
Source

pub fn element_sum(self) -> f32

Returns the sum of all elements of self.

In other words, this computes self.x + self.y + ...

Source

pub fn element_product(self) -> f32

Returns the product of all elements of self.

In other words, this computes self.x * self.y * ...

Source

pub fn cmpeq(self, rhs: Vec3) -> BVec3

Returns a vector mask containing the result of a == comparison for each element of self and rhs.

In other words, this computes [self.x == rhs.x, self.y == rhs.y, ..] for all elements.

Source

pub fn cmpne(self, rhs: Vec3) -> BVec3

Returns a vector mask containing the result of a != comparison for each element of self and rhs.

In other words this computes [self.x != rhs.x, self.y != rhs.y, ..] for all elements.

Source

pub fn cmpge(self, rhs: Vec3) -> BVec3

Returns a vector mask containing the result of a >= comparison for each element of self and rhs.

In other words this computes [self.x >= rhs.x, self.y >= rhs.y, ..] for all elements.

Source

pub fn cmpgt(self, rhs: Vec3) -> BVec3

Returns a vector mask containing the result of a > comparison for each element of self and rhs.

In other words this computes [self.x > rhs.x, self.y > rhs.y, ..] for all elements.

Source

pub fn cmple(self, rhs: Vec3) -> BVec3

Returns a vector mask containing the result of a <= comparison for each element of self and rhs.

In other words this computes [self.x <= rhs.x, self.y <= rhs.y, ..] for all elements.

Source

pub fn cmplt(self, rhs: Vec3) -> BVec3

Returns a vector mask containing the result of a < comparison for each element of self and rhs.

In other words this computes [self.x < rhs.x, self.y < rhs.y, ..] for all elements.

Source

pub fn abs(self) -> Vec3

Returns a vector containing the absolute value of each element of self.

Examples found in repository?
examples/stress_tests/many_cubes.rs (line 498)
497fn fast_hue_to_rgb(hue: f32) -> Vec3 {
498    (hue * 6.0 - vec3(3.0, 2.0, 4.0)).abs() * vec3(1.0, -1.0, -1.0) + vec3(-1.0, 2.0, 2.0)
499}
Source

pub fn signum(self) -> Vec3

Returns a vector with elements representing the sign of self.

  • 1.0 if the number is positive, +0.0 or INFINITY
  • -1.0 if the number is negative, -0.0 or NEG_INFINITY
  • NAN if the number is NAN
Source

pub fn copysign(self, rhs: Vec3) -> Vec3

Returns a vector with signs of rhs and the magnitudes of self.

Source

pub fn is_negative_bitmask(self) -> u32

Returns a bitmask with the lowest 3 bits set to the sign bits from the elements of self.

A negative element results in a 1 bit and a positive element in a 0 bit. Element x goes into the first lowest bit, element y into the second, etc.

Source

pub fn is_finite(self) -> bool

Returns true if, and only if, all elements are finite. If any element is either NaN, positive or negative infinity, this will return false.

Source

pub fn is_finite_mask(self) -> BVec3

Performs is_finite on each element of self, returning a vector mask of the results.

In other words, this computes [x.is_finite(), y.is_finite(), ...].

Source

pub fn is_nan(self) -> bool

Returns true if any elements are NaN.

Source

pub fn is_nan_mask(self) -> BVec3

Performs is_nan on each element of self, returning a vector mask of the results.

In other words, this computes [x.is_nan(), y.is_nan(), ...].

Source

pub fn length(self) -> f32

Computes the length of self.

Examples found in repository?
examples/3d/clustered_decals.rs (line 350)
346fn calculate_initial_decal_transform(start: Vec3, looking_at: Vec3, size: Vec2) -> Transform {
347    let direction = looking_at - start;
348    let center = start + direction * 0.5;
349    Transform::from_translation(center)
350        .with_scale((size * 0.5).extend(direction.length()))
351        .looking_to(direction, Vec3::Y)
352}
353
354/// Rotates the cube a bit every frame.
355fn rotate_cube(mut meshes: Query<&mut Transform, With<Mesh3d>>) {
356    for mut transform in &mut meshes {
357        transform.rotate_y(CUBE_ROTATION_SPEED);
358    }
359}
360
361/// Updates the state of the radio buttons when the user clicks on one.
362fn update_radio_buttons(
363    mut widgets: Query<(
364        Entity,
365        Option<&mut BackgroundColor>,
366        Has<Text>,
367        &WidgetClickSender<Selection>,
368    )>,
369    app_status: Res<AppStatus>,
370    mut writer: TextUiWriter,
371) {
372    for (entity, maybe_bg_color, has_text, sender) in &mut widgets {
373        let selected = app_status.selection == **sender;
374        if let Some(mut bg_color) = maybe_bg_color {
375            widgets::update_ui_radio_button(&mut bg_color, selected);
376        }
377        if has_text {
378            widgets::update_ui_radio_button_text(entity, &mut writer, selected);
379        }
380    }
381}
382
383/// Changes the selection when the user clicks a radio button.
384fn handle_selection_change(
385    mut events: EventReader<WidgetClickEvent<Selection>>,
386    mut app_status: ResMut<AppStatus>,
387) {
388    for event in events.read() {
389        app_status.selection = **event;
390    }
391}
392
393/// Process a drag event that moves the selected object.
394fn process_move_input(
395    mut selections: Query<(&mut Transform, &Selection)>,
396    mouse_buttons: Res<ButtonInput<MouseButton>>,
397    mouse_motion: Res<AccumulatedMouseMotion>,
398    app_status: Res<AppStatus>,
399) {
400    // Only process drags when movement is selected.
401    if !mouse_buttons.pressed(MouseButton::Left) || app_status.drag_mode != DragMode::Move {
402        return;
403    }
404
405    for (mut transform, selection) in &mut selections {
406        if app_status.selection != *selection {
407            continue;
408        }
409
410        let position = transform.translation;
411
412        // Convert to spherical coordinates.
413        let radius = position.length();
414        let mut theta = acos(position.y / radius);
415        let mut phi = position.z.signum() * acos(position.x * position.xz().length_recip());
416
417        // Camera movement is the inverse of object movement.
418        let (phi_factor, theta_factor) = match *selection {
419            Selection::Camera => (1.0, -1.0),
420            Selection::DecalA | Selection::DecalB => (-1.0, 1.0),
421        };
422
423        // Adjust the spherical coordinates. Clamp the inclination to (0, π).
424        phi += phi_factor * mouse_motion.delta.x * MOVE_SPEED;
425        theta = f32::clamp(
426            theta + theta_factor * mouse_motion.delta.y * MOVE_SPEED,
427            0.001,
428            PI - 0.001,
429        );
430
431        // Convert spherical coordinates back to Cartesian coordinates.
432        transform.translation =
433            radius * vec3(sin(theta) * cos(phi), cos(theta), sin(theta) * sin(phi));
434
435        // Look at the center, but preserve the previous roll angle.
436        let roll = transform.rotation.to_euler(EulerRot::YXZ).2;
437        transform.look_at(Vec3::ZERO, Vec3::Y);
438        let (yaw, pitch, _) = transform.rotation.to_euler(EulerRot::YXZ);
439        transform.rotation = Quat::from_euler(EulerRot::YXZ, yaw, pitch, roll);
440    }
441}
More examples
Hide additional examples
examples/transforms/translation.rs (line 65)
62fn move_cube(mut cubes: Query<(&mut Transform, &mut Movable)>, timer: Res<Time>) {
63    for (mut transform, mut cube) in &mut cubes {
64        // Check if the entity moved too far from its spawn, if so invert the moving direction.
65        if (cube.spawn - transform.translation).length() > cube.max_distance {
66            cube.speed *= -1.0;
67        }
68        let direction = transform.local_x();
69        transform.translation += direction * cube.speed * timer.delta_secs();
70    }
71}
examples/3d/motion_blur.rs (line 324)
300fn move_cars(
301    time: Res<Time>,
302    mut movables: Query<(&mut Transform, &Moves, &Children)>,
303    mut spins: Query<&mut Transform, (Without<Moves>, With<Rotates>)>,
304) {
305    for (mut transform, moves, children) in &mut movables {
306        let time = time.elapsed_secs() * 0.25;
307        let t = time + 0.5 * moves.0;
308        let dx = ops::cos(t);
309        let dz = -ops::sin(3.0 * t);
310        let speed_variation = (dx * dx + dz * dz).sqrt() * 0.15;
311        let t = t + speed_variation;
312        let prev = transform.translation;
313        transform.translation.x = race_track_pos(0.0, t).x;
314        transform.translation.z = race_track_pos(0.0, t).y;
315        transform.translation.y = -0.59;
316        let delta = transform.translation - prev;
317        transform.look_to(delta, Vec3::Y);
318        for child in children.iter() {
319            let Ok(mut wheel) = spins.get_mut(child) else {
320                continue;
321            };
322            let radius = wheel.scale.x;
323            let circumference = 2.0 * std::f32::consts::PI * radius;
324            let angle = delta.length() / circumference * std::f32::consts::PI * 2.0;
325            wheel.rotate_local_y(angle);
326        }
327    }
328}
examples/ecs/fallible_params.rs (line 148)
137fn track_targets(
138    // `Single` ensures the system runs ONLY when exactly one matching entity exists.
139    mut player: Single<(&mut Transform, &Player)>,
140    // `Option<Single>` ensures that the system runs ONLY when zero or one matching entity exists.
141    enemy: Option<Single<&Transform, (With<Enemy>, Without<Player>)>>,
142    time: Res<Time>,
143) {
144    let (player_transform, player) = &mut *player;
145    if let Some(enemy_transform) = enemy {
146        // Enemy found, rotate and move towards it.
147        let delta = enemy_transform.translation - player_transform.translation;
148        let distance = delta.length();
149        let front = delta / distance;
150        let up = Vec3::Z;
151        let side = front.cross(up);
152        player_transform.rotation = Quat::from_mat3(&Mat3::from_cols(side, front, up));
153        let max_step = distance - player.min_follow_radius;
154        if 0.0 < max_step {
155            let velocity = (player.speed * time.delta_secs()).min(max_step);
156            player_transform.translation += front * velocity;
157        }
158    } else {
159        // 0 or multiple enemies found, keep searching.
160        player_transform.rotate_axis(Dir3::Z, player.rotation_speed * time.delta_secs());
161    }
162}
examples/transforms/transform.rs (line 134)
126fn scale_down_sphere_proportional_to_cube_travel_distance(
127    cubes: Query<(&Transform, &CubeState), Without<Center>>,
128    mut centers: Query<(&mut Transform, &Center)>,
129) {
130    // First we need to calculate the length of between
131    // the current position of the orbiting cube and the spawn position.
132    let mut distances = 0.0;
133    for (cube_transform, cube_state) in &cubes {
134        distances += (cube_state.start_pos - cube_transform.translation).length();
135    }
136    // Now we use the calculated value to scale the sphere in the center accordingly.
137    for (mut transform, center) in &mut centers {
138        // Calculate the new size from the calculated distances and the centers scale_factor.
139        // Since we want to have the sphere at its max_size at the cubes spawn location we start by
140        // using the max_size as start value and subtract the distances scaled by a scaling factor.
141        let mut new_size: f32 = center.max_size - center.scale_factor * distances;
142
143        // The new size should also not be smaller than the centers min_size.
144        // Therefore the max value out of (new_size, center.min_size) is used.
145        new_size = new_size.max(center.min_size);
146
147        // Now scale the sphere uniformly in all directions using new_size.
148        // Here Vec3:splat is used to create a vector with new_size in x, y and z direction.
149        transform.scale = Vec3::splat(new_size);
150    }
151}
examples/3d/ssr.rs (line 328)
298fn move_camera(
299    keyboard_input: Res<ButtonInput<KeyCode>>,
300    mut mouse_wheel_input: EventReader<MouseWheel>,
301    mut cameras: Query<&mut Transform, With<Camera>>,
302) {
303    let (mut distance_delta, mut theta_delta) = (0.0, 0.0);
304
305    // Handle keyboard events.
306    if keyboard_input.pressed(KeyCode::KeyW) {
307        distance_delta -= CAMERA_KEYBOARD_ZOOM_SPEED;
308    }
309    if keyboard_input.pressed(KeyCode::KeyS) {
310        distance_delta += CAMERA_KEYBOARD_ZOOM_SPEED;
311    }
312    if keyboard_input.pressed(KeyCode::KeyA) {
313        theta_delta += CAMERA_KEYBOARD_ORBIT_SPEED;
314    }
315    if keyboard_input.pressed(KeyCode::KeyD) {
316        theta_delta -= CAMERA_KEYBOARD_ORBIT_SPEED;
317    }
318
319    // Handle mouse events.
320    for mouse_wheel_event in mouse_wheel_input.read() {
321        distance_delta -= mouse_wheel_event.y * CAMERA_MOUSE_WHEEL_ZOOM_SPEED;
322    }
323
324    // Update transforms.
325    for mut camera_transform in cameras.iter_mut() {
326        let local_z = camera_transform.local_z().as_vec3().normalize_or_zero();
327        if distance_delta != 0.0 {
328            camera_transform.translation = (camera_transform.translation.length() + distance_delta)
329                .clamp(CAMERA_ZOOM_RANGE.start, CAMERA_ZOOM_RANGE.end)
330                * local_z;
331        }
332        if theta_delta != 0.0 {
333            camera_transform
334                .translate_around(Vec3::ZERO, Quat::from_axis_angle(Vec3::Y, theta_delta));
335            camera_transform.look_at(Vec3::ZERO, Vec3::Y);
336        }
337    }
338}
Source

pub fn length_squared(self) -> f32

Computes the squared length of self.

This is faster than length() as it avoids a square root operation.

Examples found in repository?
examples/ecs/iter_combinations.rs (line 128)
122fn interact_bodies(mut query: Query<(&Mass, &GlobalTransform, &mut Acceleration)>) {
123    let mut iter = query.iter_combinations_mut();
124    while let Some([(Mass(m1), transform1, mut acc1), (Mass(m2), transform2, mut acc2)]) =
125        iter.fetch_next()
126    {
127        let delta = transform2.translation() - transform1.translation();
128        let distance_sq: f32 = delta.length_squared();
129
130        let f = GRAVITY_CONSTANT / distance_sq;
131        let force_unit_mass = delta * f;
132        acc1.0 += force_unit_mass * *m2;
133        acc2.0 -= force_unit_mass * *m1;
134    }
135}
More examples
Hide additional examples
examples/3d/../helpers/camera_controller.rs (line 212)
127fn run_camera_controller(
128    time: Res<Time>,
129    mut windows: Query<&mut Window>,
130    accumulated_mouse_motion: Res<AccumulatedMouseMotion>,
131    accumulated_mouse_scroll: Res<AccumulatedMouseScroll>,
132    mouse_button_input: Res<ButtonInput<MouseButton>>,
133    key_input: Res<ButtonInput<KeyCode>>,
134    mut toggle_cursor_grab: Local<bool>,
135    mut mouse_cursor_grab: Local<bool>,
136    mut query: Query<(&mut Transform, &mut CameraController), With<Camera>>,
137) {
138    let dt = time.delta_secs();
139
140    let Ok((mut transform, mut controller)) = query.single_mut() else {
141        return;
142    };
143
144    if !controller.initialized {
145        let (yaw, pitch, _roll) = transform.rotation.to_euler(EulerRot::YXZ);
146        controller.yaw = yaw;
147        controller.pitch = pitch;
148        controller.initialized = true;
149        info!("{}", *controller);
150    }
151    if !controller.enabled {
152        return;
153    }
154
155    let mut scroll = 0.0;
156
157    let amount = match accumulated_mouse_scroll.unit {
158        MouseScrollUnit::Line => accumulated_mouse_scroll.delta.y,
159        MouseScrollUnit::Pixel => accumulated_mouse_scroll.delta.y / 16.0,
160    };
161    scroll += amount;
162    controller.walk_speed += scroll * controller.scroll_factor * controller.walk_speed;
163    controller.run_speed = controller.walk_speed * 3.0;
164
165    // Handle key input
166    let mut axis_input = Vec3::ZERO;
167    if key_input.pressed(controller.key_forward) {
168        axis_input.z += 1.0;
169    }
170    if key_input.pressed(controller.key_back) {
171        axis_input.z -= 1.0;
172    }
173    if key_input.pressed(controller.key_right) {
174        axis_input.x += 1.0;
175    }
176    if key_input.pressed(controller.key_left) {
177        axis_input.x -= 1.0;
178    }
179    if key_input.pressed(controller.key_up) {
180        axis_input.y += 1.0;
181    }
182    if key_input.pressed(controller.key_down) {
183        axis_input.y -= 1.0;
184    }
185
186    let mut cursor_grab_change = false;
187    if key_input.just_pressed(controller.keyboard_key_toggle_cursor_grab) {
188        *toggle_cursor_grab = !*toggle_cursor_grab;
189        cursor_grab_change = true;
190    }
191    if mouse_button_input.just_pressed(controller.mouse_key_cursor_grab) {
192        *mouse_cursor_grab = true;
193        cursor_grab_change = true;
194    }
195    if mouse_button_input.just_released(controller.mouse_key_cursor_grab) {
196        *mouse_cursor_grab = false;
197        cursor_grab_change = true;
198    }
199    let cursor_grab = *mouse_cursor_grab || *toggle_cursor_grab;
200
201    // Apply movement update
202    if axis_input != Vec3::ZERO {
203        let max_speed = if key_input.pressed(controller.key_run) {
204            controller.run_speed
205        } else {
206            controller.walk_speed
207        };
208        controller.velocity = axis_input.normalize() * max_speed;
209    } else {
210        let friction = controller.friction.clamp(0.0, 1.0);
211        controller.velocity *= 1.0 - friction;
212        if controller.velocity.length_squared() < 1e-6 {
213            controller.velocity = Vec3::ZERO;
214        }
215    }
216    let forward = *transform.forward();
217    let right = *transform.right();
218    transform.translation += controller.velocity.x * dt * right
219        + controller.velocity.y * dt * Vec3::Y
220        + controller.velocity.z * dt * forward;
221
222    // Handle cursor grab
223    if cursor_grab_change {
224        if cursor_grab {
225            for mut window in &mut windows {
226                if !window.focused {
227                    continue;
228                }
229
230                window.cursor_options.grab_mode = CursorGrabMode::Locked;
231                window.cursor_options.visible = false;
232            }
233        } else {
234            for mut window in &mut windows {
235                window.cursor_options.grab_mode = CursorGrabMode::None;
236                window.cursor_options.visible = true;
237            }
238        }
239    }
240
241    // Handle mouse input
242    if accumulated_mouse_motion.delta != Vec2::ZERO && cursor_grab {
243        // Apply look update
244        controller.pitch = (controller.pitch
245            - accumulated_mouse_motion.delta.y * RADIANS_PER_DOT * controller.sensitivity)
246            .clamp(-PI / 2., PI / 2.);
247        controller.yaw -=
248            accumulated_mouse_motion.delta.x * RADIANS_PER_DOT * controller.sensitivity;
249        transform.rotation = Quat::from_euler(EulerRot::ZYX, 0.0, controller.yaw, controller.pitch);
250    }
251}
Source

pub fn length_recip(self) -> f32

Computes 1.0 / length().

For valid results, self must not be of length zero.

Source

pub fn distance(self, rhs: Vec3) -> f32

Computes the Euclidean distance between two points in space.

Examples found in repository?
examples/math/sampling_primitives.rs (line 496)
416fn handle_keypress(
417    mut commands: Commands,
418    keyboard: Res<ButtonInput<KeyCode>>,
419    mut mode: ResMut<SamplingMode>,
420    mut spawn_mode: ResMut<SpawningMode>,
421    samples: Query<Entity, With<SamplePoint>>,
422    shapes: Res<SampledShapes>,
423    mut spawn_queue: ResMut<SpawnQueue>,
424    mut counter: ResMut<PointCounter>,
425    mut text_menus: Query<&mut Visibility, With<Text>>,
426    mut camera_rig: Single<&mut CameraRig>,
427) {
428    // R => restart, deleting all samples
429    if keyboard.just_pressed(KeyCode::KeyR) {
430        // Don't forget to zero out the counter!
431        counter.0 = 0;
432        for entity in &samples {
433            commands.entity(entity).despawn();
434        }
435    }
436
437    // S => sample once
438    if keyboard.just_pressed(KeyCode::KeyS) {
439        spawn_queue.0 += 1;
440    }
441
442    // D => sample a hundred
443    if keyboard.just_pressed(KeyCode::KeyD) {
444        spawn_queue.0 += 100;
445    }
446
447    // M => toggle mode between interior and boundary.
448    if keyboard.just_pressed(KeyCode::KeyM) {
449        match *mode {
450            SamplingMode::Interior => *mode = SamplingMode::Boundary,
451            SamplingMode::Boundary => *mode = SamplingMode::Interior,
452        }
453    }
454
455    // A => toggle spawning mode between automatic and manual.
456    if keyboard.just_pressed(KeyCode::KeyA) {
457        match *spawn_mode {
458            SpawningMode::Manual => *spawn_mode = SpawningMode::Automatic,
459            SpawningMode::Automatic => *spawn_mode = SpawningMode::Manual,
460        }
461    }
462
463    // Tab => toggle help menu.
464    if keyboard.just_pressed(KeyCode::Tab) {
465        for mut visibility in text_menus.iter_mut() {
466            *visibility = match *visibility {
467                Visibility::Hidden => Visibility::Visible,
468                _ => Visibility::Hidden,
469            };
470        }
471    }
472
473    // +/- => zoom camera.
474    if keyboard.just_pressed(KeyCode::NumpadSubtract) || keyboard.just_pressed(KeyCode::Minus) {
475        camera_rig.distance += MAX_CAMERA_DISTANCE / 15.0;
476        camera_rig.distance = camera_rig
477            .distance
478            .clamp(MIN_CAMERA_DISTANCE, MAX_CAMERA_DISTANCE);
479    }
480
481    if keyboard.just_pressed(KeyCode::NumpadAdd) {
482        camera_rig.distance -= MAX_CAMERA_DISTANCE / 15.0;
483        camera_rig.distance = camera_rig
484            .distance
485            .clamp(MIN_CAMERA_DISTANCE, MAX_CAMERA_DISTANCE);
486    }
487
488    // Arrows => Move camera focus
489    let left = keyboard.just_pressed(KeyCode::ArrowLeft);
490    let right = keyboard.just_pressed(KeyCode::ArrowRight);
491
492    if left || right {
493        let mut closest = 0;
494        let mut closest_distance = f32::MAX;
495        for (i, (_, position)) in shapes.0.iter().enumerate() {
496            let distance = camera_rig.target.distance(*position);
497            if distance < closest_distance {
498                closest = i;
499                closest_distance = distance;
500            }
501        }
502        if closest > 0 && left {
503            camera_rig.target = shapes.0[closest - 1].1;
504        }
505        if closest < shapes.0.len() - 1 && right {
506            camera_rig.target = shapes.0[closest + 1].1;
507        }
508    }
509}
Source

pub fn distance_squared(self, rhs: Vec3) -> f32

Compute the squared euclidean distance between two points in space.

Source

pub fn div_euclid(self, rhs: Vec3) -> Vec3

Returns the element-wise quotient of [Euclidean division] of self by rhs.

Source

pub fn rem_euclid(self, rhs: Vec3) -> Vec3

Returns the element-wise remainder of Euclidean division of self by rhs.

Source

pub fn normalize(self) -> Vec3

Returns self normalized to length 1.0.

For valid results, self must be finite and not of length zero, nor very close to zero.

See also Self::try_normalize() and Self::normalize_or_zero().

Panics

Will panic if the resulting normalized vector is not finite when glam_assert is enabled.

Examples found in repository?
examples/picking/mesh_picking.rs (line 181)
174fn draw_mesh_intersections(pointers: Query<&PointerInteraction>, mut gizmos: Gizmos) {
175    for (point, normal) in pointers
176        .iter()
177        .filter_map(|interaction| interaction.get_nearest_hit())
178        .filter_map(|(_entity, hit)| hit.position.zip(hit.normal))
179    {
180        gizmos.sphere(point, 0.05, RED_500);
181        gizmos.arrow(point, point + normal.normalize() * 0.5, PINK_100);
182    }
183}
More examples
Hide additional examples
examples/state/custom_transitions.rs (line 191)
170fn movement(
171    time: Res<Time>,
172    input: Res<ButtonInput<KeyCode>>,
173    mut query: Query<&mut Transform, With<Sprite>>,
174) {
175    for mut transform in &mut query {
176        let mut direction = Vec3::ZERO;
177        if input.pressed(KeyCode::ArrowLeft) {
178            direction.x -= 1.0;
179        }
180        if input.pressed(KeyCode::ArrowRight) {
181            direction.x += 1.0;
182        }
183        if input.pressed(KeyCode::ArrowUp) {
184            direction.y += 1.0;
185        }
186        if input.pressed(KeyCode::ArrowDown) {
187            direction.y -= 1.0;
188        }
189
190        if direction != Vec3::ZERO {
191            transform.translation += direction.normalize() * SPEED * time.delta_secs();
192        }
193    }
194}
examples/state/states.rs (line 142)
121fn movement(
122    time: Res<Time>,
123    input: Res<ButtonInput<KeyCode>>,
124    mut query: Query<&mut Transform, With<Sprite>>,
125) {
126    for mut transform in &mut query {
127        let mut direction = Vec3::ZERO;
128        if input.pressed(KeyCode::ArrowLeft) {
129            direction.x -= 1.0;
130        }
131        if input.pressed(KeyCode::ArrowRight) {
132            direction.x += 1.0;
133        }
134        if input.pressed(KeyCode::ArrowUp) {
135            direction.y += 1.0;
136        }
137        if input.pressed(KeyCode::ArrowDown) {
138            direction.y -= 1.0;
139        }
140
141        if direction != Vec3::ZERO {
142            transform.translation += direction.normalize() * SPEED * time.delta_secs();
143        }
144    }
145}
examples/state/sub_states.rs (line 112)
91fn movement(
92    time: Res<Time>,
93    input: Res<ButtonInput<KeyCode>>,
94    mut query: Query<&mut Transform, With<Sprite>>,
95) {
96    for mut transform in &mut query {
97        let mut direction = Vec3::ZERO;
98        if input.pressed(KeyCode::ArrowLeft) {
99            direction.x -= 1.0;
100        }
101        if input.pressed(KeyCode::ArrowRight) {
102            direction.x += 1.0;
103        }
104        if input.pressed(KeyCode::ArrowUp) {
105            direction.y += 1.0;
106        }
107        if input.pressed(KeyCode::ArrowDown) {
108            direction.y -= 1.0;
109        }
110
111        if direction != Vec3::ZERO {
112            transform.translation += direction.normalize() * SPEED * time.delta_secs();
113        }
114    }
115}
examples/state/computed_states.rs (line 442)
420    pub fn movement(
421        time: Res<Time>,
422        input: Res<ButtonInput<KeyCode>>,
423        turbo: Option<Res<State<TurboMode>>>,
424        mut query: Query<&mut Transform, With<Sprite>>,
425    ) {
426        for mut transform in &mut query {
427            let mut direction = Vec3::ZERO;
428            if input.pressed(KeyCode::ArrowLeft) {
429                direction.x -= 1.0;
430            }
431            if input.pressed(KeyCode::ArrowRight) {
432                direction.x += 1.0;
433            }
434            if input.pressed(KeyCode::ArrowUp) {
435                direction.y += 1.0;
436            }
437            if input.pressed(KeyCode::ArrowDown) {
438                direction.y -= 1.0;
439            }
440
441            if direction != Vec3::ZERO {
442                transform.translation += direction.normalize()
443                    * if turbo.is_some() { TURBO_SPEED } else { SPEED }
444                    * time.delta_secs();
445            }
446        }
447    }
examples/3d/irradiance_volumes.rs (line 473)
450fn handle_mouse_clicks(
451    buttons: Res<ButtonInput<MouseButton>>,
452    windows: Query<&Window, With<PrimaryWindow>>,
453    cameras: Query<(&Camera, &GlobalTransform)>,
454    mut main_objects: Query<&mut Transform, With<MainObject>>,
455) {
456    if !buttons.pressed(MouseButton::Left) {
457        return;
458    }
459    let Some(mouse_position) = windows.iter().next().and_then(Window::cursor_position) else {
460        return;
461    };
462    let Some((camera, camera_transform)) = cameras.iter().next() else {
463        return;
464    };
465
466    // Figure out where the user clicked on the plane.
467    let Ok(ray) = camera.viewport_to_world(camera_transform, mouse_position) else {
468        return;
469    };
470    let Some(ray_distance) = ray.intersect_plane(Vec3::ZERO, InfinitePlane3d::new(Vec3::Y)) else {
471        return;
472    };
473    let plane_intersection = ray.origin + ray.direction.normalize() * ray_distance;
474
475    // Move all the main objects.
476    for mut transform in main_objects.iter_mut() {
477        transform.translation = vec3(
478            plane_intersection.x,
479            transform.translation.y,
480            plane_intersection.z,
481        );
482    }
483}
Source

pub fn try_normalize(self) -> Option<Vec3>

Returns self normalized to length 1.0 if possible, else returns None.

In particular, if the input is zero (or very close to zero), or non-finite, the result of this operation will be None.

See also Self::normalize_or_zero().

Examples found in repository?
examples/math/render_primitives.rs (line 625)
611fn rotate_primitive_3d_meshes(
612    mut primitives_3d: Query<
613        (&mut Transform, &ViewVisibility),
614        (With<PrimitiveData>, With<MeshDim3>),
615    >,
616    time: Res<Time>,
617) {
618    let rotation_3d = Quat::from_rotation_arc(
619        Vec3::Z,
620        Vec3::new(
621            ops::sin(time.elapsed_secs()),
622            ops::cos(time.elapsed_secs()),
623            ops::sin(time.elapsed_secs()) * 0.5,
624        )
625        .try_normalize()
626        .unwrap_or(Vec3::Z),
627    );
628    primitives_3d
629        .iter_mut()
630        .filter(|(_, vis)| vis.get())
631        .for_each(|(mut transform, _)| {
632            transform.rotation = rotation_3d;
633        });
634}
635
636fn draw_gizmos_3d(mut gizmos: Gizmos, state: Res<State<PrimitiveSelected>>, time: Res<Time>) {
637    const POSITION: Vec3 = Vec3::new(LEFT_RIGHT_OFFSET_3D, 0.0, 0.0);
638    let rotation = Quat::from_rotation_arc(
639        Vec3::Z,
640        Vec3::new(
641            ops::sin(time.elapsed_secs()),
642            ops::cos(time.elapsed_secs()),
643            ops::sin(time.elapsed_secs()) * 0.5,
644        )
645        .try_normalize()
646        .unwrap_or(Vec3::Z),
647    );
648    let isometry = Isometry3d::new(POSITION, rotation);
649    let color = Color::WHITE;
650    let resolution = 10;
651
652    #[expect(
653        clippy::match_same_arms,
654        reason = "Certain primitives don't have any 3D rendering support yet."
655    )]
656    match state.get() {
657        PrimitiveSelected::RectangleAndCuboid => {
658            gizmos.primitive_3d(&CUBOID, isometry, color);
659        }
660        PrimitiveSelected::CircleAndSphere => drop(
661            gizmos
662                .primitive_3d(&SPHERE, isometry, color)
663                .resolution(resolution),
664        ),
665        PrimitiveSelected::Ellipse => {}
666        PrimitiveSelected::Triangle => gizmos.primitive_3d(&TRIANGLE_3D, isometry, color),
667        PrimitiveSelected::Plane => drop(gizmos.primitive_3d(&PLANE_3D, isometry, color)),
668        PrimitiveSelected::Line => gizmos.primitive_3d(&LINE3D, isometry, color),
669        PrimitiveSelected::Segment => gizmos.primitive_3d(&SEGMENT_3D, isometry, color),
670        PrimitiveSelected::Polyline => gizmos.primitive_3d(&POLYLINE_3D, isometry, color),
671        PrimitiveSelected::Polygon => {}
672        PrimitiveSelected::RegularPolygon => {}
673        PrimitiveSelected::Capsule => drop(
674            gizmos
675                .primitive_3d(&CAPSULE_3D, isometry, color)
676                .resolution(resolution),
677        ),
678        PrimitiveSelected::Cylinder => drop(
679            gizmos
680                .primitive_3d(&CYLINDER, isometry, color)
681                .resolution(resolution),
682        ),
683        PrimitiveSelected::Cone => drop(
684            gizmos
685                .primitive_3d(&CONE, isometry, color)
686                .resolution(resolution),
687        ),
688        PrimitiveSelected::ConicalFrustum => {
689            gizmos.primitive_3d(&CONICAL_FRUSTUM, isometry, color);
690        }
691
692        PrimitiveSelected::Torus => drop(
693            gizmos
694                .primitive_3d(&TORUS, isometry, color)
695                .minor_resolution(resolution)
696                .major_resolution(resolution),
697        ),
698        PrimitiveSelected::Tetrahedron => {
699            gizmos.primitive_3d(&TETRAHEDRON, isometry, color);
700        }
701
702        PrimitiveSelected::Arc => {}
703        PrimitiveSelected::CircularSector => {}
704        PrimitiveSelected::CircularSegment => {}
705    }
706}
Source

pub fn normalize_or(self, fallback: Vec3) -> Vec3

Returns self normalized to length 1.0 if possible, else returns a fallback value.

In particular, if the input is zero (or very close to zero), or non-finite, the result of this operation will be the fallback value.

See also Self::try_normalize().

Source

pub fn normalize_or_zero(self) -> Vec3

Returns self normalized to length 1.0 if possible, else returns zero.

In particular, if the input is zero (or very close to zero), or non-finite, the result of this operation will be zero.

See also Self::try_normalize().

Examples found in repository?
examples/movement/physics_in_fixed_timestep.rs (line 192)
167fn handle_input(
168    keyboard_input: Res<ButtonInput<KeyCode>>,
169    mut query: Query<(&mut AccumulatedInput, &mut Velocity)>,
170) {
171    /// Since Bevy's default 2D camera setup is scaled such that
172    /// one unit is one pixel, you can think of this as
173    /// "How many pixels per second should the player move?"
174    const SPEED: f32 = 210.0;
175    for (mut input, mut velocity) in query.iter_mut() {
176        if keyboard_input.pressed(KeyCode::KeyW) {
177            input.y += 1.0;
178        }
179        if keyboard_input.pressed(KeyCode::KeyS) {
180            input.y -= 1.0;
181        }
182        if keyboard_input.pressed(KeyCode::KeyA) {
183            input.x -= 1.0;
184        }
185        if keyboard_input.pressed(KeyCode::KeyD) {
186            input.x += 1.0;
187        }
188
189        // Need to normalize and scale because otherwise
190        // diagonal movement would be faster than horizontal or vertical movement.
191        // This effectively averages the accumulated input.
192        velocity.0 = input.extend(0.0).normalize_or_zero() * SPEED;
193    }
194}
More examples
Hide additional examples
examples/3d/ssr.rs (line 326)
298fn move_camera(
299    keyboard_input: Res<ButtonInput<KeyCode>>,
300    mut mouse_wheel_input: EventReader<MouseWheel>,
301    mut cameras: Query<&mut Transform, With<Camera>>,
302) {
303    let (mut distance_delta, mut theta_delta) = (0.0, 0.0);
304
305    // Handle keyboard events.
306    if keyboard_input.pressed(KeyCode::KeyW) {
307        distance_delta -= CAMERA_KEYBOARD_ZOOM_SPEED;
308    }
309    if keyboard_input.pressed(KeyCode::KeyS) {
310        distance_delta += CAMERA_KEYBOARD_ZOOM_SPEED;
311    }
312    if keyboard_input.pressed(KeyCode::KeyA) {
313        theta_delta += CAMERA_KEYBOARD_ORBIT_SPEED;
314    }
315    if keyboard_input.pressed(KeyCode::KeyD) {
316        theta_delta -= CAMERA_KEYBOARD_ORBIT_SPEED;
317    }
318
319    // Handle mouse events.
320    for mouse_wheel_event in mouse_wheel_input.read() {
321        distance_delta -= mouse_wheel_event.y * CAMERA_MOUSE_WHEEL_ZOOM_SPEED;
322    }
323
324    // Update transforms.
325    for mut camera_transform in cameras.iter_mut() {
326        let local_z = camera_transform.local_z().as_vec3().normalize_or_zero();
327        if distance_delta != 0.0 {
328            camera_transform.translation = (camera_transform.translation.length() + distance_delta)
329                .clamp(CAMERA_ZOOM_RANGE.start, CAMERA_ZOOM_RANGE.end)
330                * local_z;
331        }
332        if theta_delta != 0.0 {
333            camera_transform
334                .translate_around(Vec3::ZERO, Quat::from_axis_angle(Vec3::Y, theta_delta));
335            camera_transform.look_at(Vec3::ZERO, Vec3::Y);
336        }
337    }
338}
examples/3d/visibility_range.rs (line 245)
215fn move_camera(
216    keyboard_input: Res<ButtonInput<KeyCode>>,
217    mut mouse_wheel_events: EventReader<MouseWheel>,
218    mut cameras: Query<&mut Transform, With<Camera3d>>,
219) {
220    let (mut zoom_delta, mut theta_delta) = (0.0, 0.0);
221
222    // Process zoom in and out via the keyboard.
223    if keyboard_input.pressed(KeyCode::KeyW) || keyboard_input.pressed(KeyCode::ArrowUp) {
224        zoom_delta -= CAMERA_KEYBOARD_ZOOM_SPEED;
225    } else if keyboard_input.pressed(KeyCode::KeyS) || keyboard_input.pressed(KeyCode::ArrowDown) {
226        zoom_delta += CAMERA_KEYBOARD_ZOOM_SPEED;
227    }
228
229    // Process left and right pan via the keyboard.
230    if keyboard_input.pressed(KeyCode::KeyA) || keyboard_input.pressed(KeyCode::ArrowLeft) {
231        theta_delta -= CAMERA_KEYBOARD_PAN_SPEED;
232    } else if keyboard_input.pressed(KeyCode::KeyD) || keyboard_input.pressed(KeyCode::ArrowRight) {
233        theta_delta += CAMERA_KEYBOARD_PAN_SPEED;
234    }
235
236    // Process zoom in and out via the mouse wheel.
237    for event in mouse_wheel_events.read() {
238        zoom_delta -= event.y * CAMERA_MOUSE_MOVEMENT_SPEED;
239    }
240
241    // Update the camera transform.
242    for transform in cameras.iter_mut() {
243        let transform = transform.into_inner();
244
245        let direction = transform.translation.normalize_or_zero();
246        let magnitude = transform.translation.length();
247
248        let new_direction = Mat3::from_rotation_y(theta_delta) * direction;
249        let new_magnitude = (magnitude + zoom_delta).max(MIN_ZOOM_DISTANCE);
250
251        transform.translation = new_direction * new_magnitude;
252        transform.look_at(CAMERA_FOCAL_POINT, Vec3::Y);
253    }
254}
examples/3d/decal.rs (line 76)
22fn setup(
23    mut commands: Commands,
24    mut meshes: ResMut<Assets<Mesh>>,
25    mut standard_materials: ResMut<Assets<StandardMaterial>>,
26    mut decal_standard_materials: ResMut<Assets<ForwardDecalMaterial<StandardMaterial>>>,
27    asset_server: Res<AssetServer>,
28) {
29    // Spawn the forward decal
30    commands.spawn((
31        Name::new("Decal"),
32        ForwardDecal,
33        MeshMaterial3d(decal_standard_materials.add(ForwardDecalMaterial {
34            base: StandardMaterial {
35                base_color_texture: Some(asset_server.load("textures/uv_checker_bw.png")),
36                ..default()
37            },
38            extension: ForwardDecalMaterialExt {
39                depth_fade_factor: 1.0,
40            },
41        })),
42        Transform::from_scale(Vec3::splat(4.0)),
43    ));
44
45    commands.spawn((
46        Name::new("Camera"),
47        Camera3d::default(),
48        CameraController::default(),
49        DepthPrepass, // Must enable the depth prepass to render forward decals
50        Transform::from_xyz(2.0, 9.5, 2.5).looking_at(Vec3::ZERO, Vec3::Y),
51    ));
52
53    let white_material = standard_materials.add(Color::WHITE);
54
55    commands.spawn((
56        Name::new("Floor"),
57        Mesh3d(meshes.add(Rectangle::from_length(10.0))),
58        MeshMaterial3d(white_material.clone()),
59        Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)),
60    ));
61
62    // Spawn a few cube with random rotations to showcase how the decals behave with non-flat geometry
63    let num_obs = 10;
64    let mut rng = ChaCha8Rng::seed_from_u64(19878367467713);
65    for i in 0..num_obs {
66        for j in 0..num_obs {
67            let rotation_axis: [f32; 3] = rng.r#gen();
68            let rotation_vec: Vec3 = rotation_axis.into();
69            let rotation: u32 = rng.gen_range(0..360);
70            let transform = Transform::from_xyz(
71                (-num_obs + 1) as f32 / 2.0 + i as f32,
72                -0.2,
73                (-num_obs + 1) as f32 / 2.0 + j as f32,
74            )
75            .with_rotation(Quat::from_axis_angle(
76                rotation_vec.normalize_or_zero(),
77                (rotation as f32).to_radians(),
78            ));
79
80            commands.spawn((
81                Mesh3d(meshes.add(Cuboid::from_length(0.6))),
82                MeshMaterial3d(white_material.clone()),
83                transform,
84            ));
85        }
86    }
87
88    commands.spawn((
89        Name::new("Light"),
90        PointLight {
91            shadows_enabled: true,
92            ..default()
93        },
94        Transform::from_xyz(4.0, 8.0, 4.0),
95    ));
96}
Source

pub fn is_normalized(self) -> bool

Returns whether self is length 1.0 or not.

Uses a precision threshold of approximately 1e-4.

Source

pub fn project_onto(self, rhs: Vec3) -> Vec3

Returns the vector projection of self onto rhs.

rhs must be of non-zero length.

§Panics

Will panic if rhs is zero length when glam_assert is enabled.

Source

pub fn reject_from(self, rhs: Vec3) -> Vec3

Returns the vector rejection of self from rhs.

The vector rejection is the vector perpendicular to the projection of self onto rhs, in rhs words the result of self - self.project_onto(rhs).

rhs must be of non-zero length.

§Panics

Will panic if rhs has a length of zero when glam_assert is enabled.

Source

pub fn project_onto_normalized(self, rhs: Vec3) -> Vec3

Returns the vector projection of self onto rhs.

rhs must be normalized.

§Panics

Will panic if rhs is not normalized when glam_assert is enabled.

Source

pub fn reject_from_normalized(self, rhs: Vec3) -> Vec3

Returns the vector rejection of self from rhs.

The vector rejection is the vector perpendicular to the projection of self onto rhs, in rhs words the result of self - self.project_onto(rhs).

rhs must be normalized.

§Panics

Will panic if rhs is not normalized when glam_assert is enabled.

Source

pub fn round(self) -> Vec3

Returns a vector containing the nearest integer to a number for each element of self. Round half-way cases away from 0.0.

Source

pub fn floor(self) -> Vec3

Returns a vector containing the largest integer less than or equal to a number for each element of self.

Examples found in repository?
examples/transforms/scale.rs (line 73)
65fn change_scale_direction(mut cubes: Query<(&mut Transform, &mut Scaling)>) {
66    for (mut transform, mut cube) in &mut cubes {
67        // If an entity scaled beyond the maximum of its size in any dimension
68        // the scaling vector is flipped so the scaling is gradually reverted.
69        // Additionally, to ensure the condition does not trigger again we floor the elements to
70        // their next full value, which should be max_element_size at max.
71        if transform.scale.max_element() > cube.max_element_size {
72            cube.scale_direction *= -1.0;
73            transform.scale = transform.scale.floor();
74        }
75        // If an entity scaled beyond the minimum of its size in any dimension
76        // the scaling vector is also flipped.
77        // Additionally the Values are ceiled to be min_element_size at least
78        // and the scale direction is flipped.
79        // This way the entity will change the dimension in which it is scaled any time it
80        // reaches its min_element_size.
81        if transform.scale.min_element() < cube.min_element_size {
82            cube.scale_direction *= -1.0;
83            transform.scale = transform.scale.ceil();
84            cube.scale_direction = cube.scale_direction.zxy();
85        }
86    }
87}
Source

pub fn ceil(self) -> Vec3

Returns a vector containing the smallest integer greater than or equal to a number for each element of self.

Examples found in repository?
examples/transforms/scale.rs (line 83)
65fn change_scale_direction(mut cubes: Query<(&mut Transform, &mut Scaling)>) {
66    for (mut transform, mut cube) in &mut cubes {
67        // If an entity scaled beyond the maximum of its size in any dimension
68        // the scaling vector is flipped so the scaling is gradually reverted.
69        // Additionally, to ensure the condition does not trigger again we floor the elements to
70        // their next full value, which should be max_element_size at max.
71        if transform.scale.max_element() > cube.max_element_size {
72            cube.scale_direction *= -1.0;
73            transform.scale = transform.scale.floor();
74        }
75        // If an entity scaled beyond the minimum of its size in any dimension
76        // the scaling vector is also flipped.
77        // Additionally the Values are ceiled to be min_element_size at least
78        // and the scale direction is flipped.
79        // This way the entity will change the dimension in which it is scaled any time it
80        // reaches its min_element_size.
81        if transform.scale.min_element() < cube.min_element_size {
82            cube.scale_direction *= -1.0;
83            transform.scale = transform.scale.ceil();
84            cube.scale_direction = cube.scale_direction.zxy();
85        }
86    }
87}
Source

pub fn trunc(self) -> Vec3

Returns a vector containing the integer part each element of self. This means numbers are always truncated towards zero.

Source

pub fn fract(self) -> Vec3

Returns a vector containing the fractional part of the vector as self - self.trunc().

Note that this differs from the GLSL implementation of fract which returns self - self.floor().

Note that this is fast but not precise for large numbers.

Source

pub fn fract_gl(self) -> Vec3

Returns a vector containing the fractional part of the vector as self - self.floor().

Note that this differs from the Rust implementation of fract which returns self - self.trunc().

Note that this is fast but not precise for large numbers.

Source

pub fn exp(self) -> Vec3

Returns a vector containing e^self (the exponential function) for each element of self.

Source

pub fn powf(self, n: f32) -> Vec3

Returns a vector containing each element of self raised to the power of n.

Source

pub fn recip(self) -> Vec3

Returns a vector containing the reciprocal 1.0/n of each element of self.

Source

pub fn lerp(self, rhs: Vec3, s: f32) -> Vec3

Performs a linear interpolation between self and rhs based on the value s.

When s is 0.0, the result will be equal to self. When s is 1.0, the result will be equal to rhs. When s is outside of range [0, 1], the result is linearly extrapolated.

Examples found in repository?
examples/gizmos/axes.rs (line 211)
210fn interpolate_transforms(t1: Transform, t2: Transform, t: f32) -> Transform {
211    let translation = t1.translation.lerp(t2.translation, t);
212    let rotation = t1.rotation.slerp(t2.rotation, t);
213    let scale = elerp(t1.scale, t2.scale, t);
214
215    Transform {
216        translation,
217        rotation,
218        scale,
219    }
220}
More examples
Hide additional examples
examples/3d/parallax_mapping.rs (line 194)
185fn move_camera(
186    mut camera: Single<&mut Transform, With<CameraController>>,
187    mut current_view: Local<usize>,
188    button: Res<ButtonInput<MouseButton>>,
189) {
190    if button.just_pressed(MouseButton::Left) {
191        *current_view = (*current_view + 1) % CAMERA_POSITIONS.len();
192    }
193    let target = CAMERA_POSITIONS[*current_view];
194    camera.translation = camera.translation.lerp(target.translation, 0.2);
195    camera.rotation = camera.rotation.slerp(target.rotation, 0.2);
196}
examples/movement/physics_in_fixed_timestep.rs (line 240)
224fn interpolate_rendered_transform(
225    fixed_time: Res<Time<Fixed>>,
226    mut query: Query<(
227        &mut Transform,
228        &PhysicalTranslation,
229        &PreviousPhysicalTranslation,
230    )>,
231) {
232    for (mut transform, current_physical_translation, previous_physical_translation) in
233        query.iter_mut()
234    {
235        let previous = previous_physical_translation.0;
236        let current = current_physical_translation.0;
237        // The overstep fraction is a value between 0 and 1 that tells us how far we are between two fixed timesteps.
238        let alpha = fixed_time.overstep_fraction();
239
240        let rendered_translation = previous.lerp(current, alpha);
241        transform.translation = rendered_translation;
242    }
243}
examples/games/alien_cake_addict.rs (line 282)
267fn focus_camera(
268    time: Res<Time>,
269    mut game: ResMut<Game>,
270    mut transforms: ParamSet<(Query<&mut Transform, With<Camera3d>>, Query<&Transform>)>,
271) {
272    const SPEED: f32 = 2.0;
273    // if there is both a player and a bonus, target the mid-point of them
274    if let (Some(player_entity), Some(bonus_entity)) = (game.player.entity, game.bonus.entity) {
275        let transform_query = transforms.p1();
276        if let (Ok(player_transform), Ok(bonus_transform)) = (
277            transform_query.get(player_entity),
278            transform_query.get(bonus_entity),
279        ) {
280            game.camera_should_focus = player_transform
281                .translation
282                .lerp(bonus_transform.translation, 0.5);
283        }
284        // otherwise, if there is only a player, target the player
285    } else if let Some(player_entity) = game.player.entity {
286        if let Ok(player_transform) = transforms.p1().get(player_entity) {
287            game.camera_should_focus = player_transform.translation;
288        }
289        // otherwise, target the middle
290    } else {
291        game.camera_should_focus = Vec3::from(RESET_FOCUS);
292    }
293    // calculate the camera motion based on the difference between where the camera is looking
294    // and where it should be looking; the greater the distance, the faster the motion;
295    // smooth out the camera movement using the frame time
296    let mut camera_motion = game.camera_should_focus - game.camera_is_focus;
297    if camera_motion.length() > 0.2 {
298        camera_motion *= SPEED * time.delta_secs();
299        // set the new camera's actual focus
300        game.camera_is_focus += camera_motion;
301    }
302    // look at that new camera's actual focus
303    for mut transform in transforms.p0().iter_mut() {
304        *transform = transform.looking_at(game.camera_is_focus, Vec3::Y);
305    }
306}
Source

pub fn move_towards(&self, rhs: Vec3, d: f32) -> Vec3

Moves towards rhs based on the value d.

When d is 0.0, the result will be equal to self. When d is equal to self.distance(rhs), the result will be equal to rhs. Will not go past rhs.

Source

pub fn midpoint(self, rhs: Vec3) -> Vec3

Calculates the midpoint between self and rhs.

The midpoint is the average of, or halfway point between, two vectors. a.midpoint(b) should yield the same result as a.lerp(b, 0.5) while being slightly cheaper to compute.

Source

pub fn abs_diff_eq(self, rhs: Vec3, max_abs_diff: f32) -> bool

Returns true if the absolute difference of all elements between self and rhs is less than or equal to max_abs_diff.

This can be used to compare if two vectors contain similar elements. It works best when comparing with a known value. The max_abs_diff that should be used used depends on the values being compared against.

For more see comparing floating point numbers.

Source

pub fn clamp_length(self, min: f32, max: f32) -> Vec3

Returns a vector with a length no less than min and no more than max.

§Panics

Will panic if min is greater than max, or if either min or max is negative, when glam_assert is enabled.

Source

pub fn clamp_length_max(self, max: f32) -> Vec3

Returns a vector with a length no more than max.

§Panics

Will panic if max is negative when glam_assert is enabled.

Source

pub fn clamp_length_min(self, min: f32) -> Vec3

Returns a vector with a length no less than min.

§Panics

Will panic if min is negative when glam_assert is enabled.

Source

pub fn mul_add(self, a: Vec3, b: Vec3) -> Vec3

Fused multiply-add. Computes (self * a) + b element-wise with only one rounding error, yielding a more accurate result than an unfused multiply-add.

Using mul_add may be more performant than an unfused multiply-add if the target architecture has a dedicated fma CPU instruction. However, this is not always true, and will be heavily dependant on designing algorithms with specific target hardware in mind.

Source

pub fn reflect(self, normal: Vec3) -> Vec3

Returns the reflection vector for a given incident vector self and surface normal normal.

normal must be normalized.

§Panics

Will panic if normal is not normalized when glam_assert is enabled.

Examples found in repository?
examples/3d/mesh_ray_cast.rs (line 67)
48fn bounce_ray(mut ray: Ray3d, ray_cast: &mut MeshRayCast, gizmos: &mut Gizmos, color: Color) {
49    let mut intersections = Vec::with_capacity(MAX_BOUNCES + 1);
50    intersections.push((ray.origin, Color::srgb(30.0, 0.0, 0.0)));
51
52    for i in 0..MAX_BOUNCES {
53        // Cast the ray and get the first hit
54        let Some((_, hit)) = ray_cast
55            .cast_ray(ray, &MeshRayCastSettings::default())
56            .first()
57        else {
58            break;
59        };
60
61        // Draw the point of intersection and add it to the list
62        let brightness = 1.0 + 10.0 * (1.0 - i as f32 / MAX_BOUNCES as f32);
63        intersections.push((hit.point, Color::BLACK.mix(&color, brightness)));
64        gizmos.sphere(hit.point, 0.005, Color::BLACK.mix(&color, brightness * 2.0));
65
66        // Reflect the ray off of the surface
67        ray.direction = Dir3::new(ray.direction.reflect(hit.normal)).unwrap();
68        ray.origin = hit.point + ray.direction * 1e-6;
69    }
70    gizmos.linestrip_gradient(intersections);
71}
Source

pub fn refract(self, normal: Vec3, eta: f32) -> Vec3

Returns the refraction direction for a given incident vector self, surface normal normal and ratio of indices of refraction, eta. When total internal reflection occurs, a zero vector will be returned.

self and normal must be normalized.

§Panics

Will panic if self or normal is not normalized when glam_assert is enabled.

Source

pub fn angle_between(self, rhs: Vec3) -> f32

Returns the angle (in radians) between two vectors in the range [0, +π].

The inputs do not need to be unit vectors however they must be non-zero.

Source

pub fn any_orthogonal_vector(&self) -> Vec3

Returns some vector that is orthogonal to the given one.

The input vector must be finite and non-zero.

The output vector is not necessarily unit length. For that use Self::any_orthonormal_vector() instead.

Source

pub fn any_orthonormal_vector(&self) -> Vec3

Returns any unit vector that is orthogonal to the given one.

The input vector must be unit length.

§Panics

Will panic if self is not normalized when glam_assert is enabled.

Source

pub fn any_orthonormal_pair(&self) -> (Vec3, Vec3)

Given a unit vector return two other vectors that together form an orthonormal basis. That is, all three vectors are orthogonal to each other and are normalized.

§Panics

Will panic if self is not normalized when glam_assert is enabled.

Source

pub fn as_dvec3(&self) -> DVec3

Casts all elements of self to f64.

Source

pub fn as_i8vec3(&self) -> I8Vec3

Casts all elements of self to i8.

Source

pub fn as_u8vec3(&self) -> U8Vec3

Casts all elements of self to u8.

Source

pub fn as_i16vec3(&self) -> I16Vec3

Casts all elements of self to i16.

Source

pub fn as_u16vec3(&self) -> U16Vec3

Casts all elements of self to u16.

Source

pub fn as_ivec3(&self) -> IVec3

Casts all elements of self to i32.

Source

pub fn as_uvec3(&self) -> UVec3

Casts all elements of self to u32.

Source

pub fn as_i64vec3(&self) -> I64Vec3

Casts all elements of self to i64.

Source

pub fn as_u64vec3(&self) -> U64Vec3

Casts all elements of self to u64.

Trait Implementations§

Source§

impl Add<&Vec3> for &Vec3

Source§

type Output = Vec3

The resulting type after applying the + operator.
Source§

fn add(self, rhs: &Vec3) -> Vec3

Performs the + operation. Read more
Source§

impl Add<&Vec3> for &f32

Source§

type Output = Vec3

The resulting type after applying the + operator.
Source§

fn add(self, rhs: &Vec3) -> Vec3

Performs the + operation. Read more
Source§

impl Add<&Vec3> for Vec3

Source§

type Output = Vec3

The resulting type after applying the + operator.
Source§

fn add(self, rhs: &Vec3) -> Vec3

Performs the + operation. Read more
Source§

impl Add<&Vec3> for f32

Source§

type Output = Vec3

The resulting type after applying the + operator.
Source§

fn add(self, rhs: &Vec3) -> Vec3

Performs the + operation. Read more
Source§

impl Add<&f32> for &Vec3

Source§

type Output = Vec3

The resulting type after applying the + operator.
Source§

fn add(self, rhs: &f32) -> Vec3

Performs the + operation. Read more
Source§

impl Add<&f32> for Vec3

Source§

type Output = Vec3

The resulting type after applying the + operator.
Source§

fn add(self, rhs: &f32) -> Vec3

Performs the + operation. Read more
Source§

impl Add<Vec3> for &Vec3

Source§

type Output = Vec3

The resulting type after applying the + operator.
Source§

fn add(self, rhs: Vec3) -> Vec3

Performs the + operation. Read more
Source§

impl Add<Vec3> for &f32

Source§

type Output = Vec3

The resulting type after applying the + operator.
Source§

fn add(self, rhs: Vec3) -> Vec3

Performs the + operation. Read more
Source§

impl Add<Vec3> for f32

Source§

type Output = Vec3

The resulting type after applying the + operator.
Source§

fn add(self, rhs: Vec3) -> Vec3

Performs the + operation. Read more
Source§

impl Add<f32> for &Vec3

Source§

type Output = Vec3

The resulting type after applying the + operator.
Source§

fn add(self, rhs: f32) -> Vec3

Performs the + operation. Read more
Source§

impl Add<f32> for Vec3

Source§

type Output = Vec3

The resulting type after applying the + operator.
Source§

fn add(self, rhs: f32) -> Vec3

Performs the + operation. Read more
Source§

impl Add for Vec3

Source§

type Output = Vec3

The resulting type after applying the + operator.
Source§

fn add(self, rhs: Vec3) -> Vec3

Performs the + operation. Read more
Source§

impl AddAssign<&Vec3> for Vec3

Source§

fn add_assign(&mut self, rhs: &Vec3)

Performs the += operation. Read more
Source§

impl AddAssign<&f32> for Vec3

Source§

fn add_assign(&mut self, rhs: &f32)

Performs the += operation. Read more
Source§

impl AddAssign<f32> for Vec3

Source§

fn add_assign(&mut self, rhs: f32)

Performs the += operation. Read more
Source§

impl AddAssign for Vec3

Source§

fn add_assign(&mut self, rhs: Vec3)

Performs the += operation. Read more
Source§

impl Animatable for Vec3

Source§

fn interpolate(a: &Vec3, b: &Vec3, t: f32) -> Vec3

Interpolates between a and b with an interpolation factor of time. Read more
Source§

fn blend(inputs: impl Iterator<Item = BlendInput<Vec3>>) -> Vec3

Blends one or more values together. Read more
Source§

impl AsMut<[f32; 3]> for Vec3

Source§

fn as_mut(&mut self) -> &mut [f32; 3]

Converts this type into a mutable reference of the (usually inferred) input type.
Source§

impl AsMutVectorParts<f32, 3> for Vec3
where Vec3: AsMut<[f32; 3]>, f32: VectorScalar,

Source§

fn as_mut_parts(&mut self) -> &mut [f32; 3]

Source§

impl AsRef<[f32; 3]> for Vec3

Source§

fn as_ref(&self) -> &[f32; 3]

Converts this type into a shared reference of the (usually inferred) input type.
Source§

impl AsRefVectorParts<f32, 3> for Vec3
where Vec3: AsRef<[f32; 3]>, f32: VectorScalar,

Source§

fn as_ref_parts(&self) -> &[f32; 3]

Source§

impl Clone for Vec3

Source§

fn clone(&self) -> Vec3

Returns a copy of the value. Read more
1.0.0 · Source§

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

Performs copy-assignment from source. Read more
Source§

impl CreateFrom for Vec3

Source§

fn create_from<B>(reader: &mut Reader<B>) -> Vec3
where B: BufferRef,

Source§

impl Debug for Vec3

Source§

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

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

impl Default for Vec3

Source§

fn default() -> Vec3

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

impl<'de> Deserialize<'de> for Vec3

Deserialize expects a sequence of 3 values.

Source§

fn deserialize<D>( deserializer: D, ) -> Result<Vec3, <D as Deserializer<'de>>::Error>
where D: Deserializer<'de>,

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

impl Display for Vec3

Source§

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

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

impl Distribution<Vec3> for UniformMeshSampler

Source§

fn sample<R>(&self, rng: &mut R) -> Vec3
where R: Rng + ?Sized,

Generate a random value of T, using rng as the source of randomness.
Source§

fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T>
where R: Rng, Self: Sized,

Create an iterator that generates random values of T, using rng as the source of randomness. Read more
Source§

fn map<F, S>(self, func: F) -> DistMap<Self, F, T, S>
where F: Fn(T) -> S, Self: Sized,

Create a distribution of values of ‘S’ by mapping the output of Self through the closure F Read more
Source§

impl Div<&Vec3> for &Vec3

Source§

type Output = Vec3

The resulting type after applying the / operator.
Source§

fn div(self, rhs: &Vec3) -> Vec3

Performs the / operation. Read more
Source§

impl Div<&Vec3> for &f32

Source§

type Output = Vec3

The resulting type after applying the / operator.
Source§

fn div(self, rhs: &Vec3) -> Vec3

Performs the / operation. Read more
Source§

impl Div<&Vec3> for Vec3

Source§

type Output = Vec3

The resulting type after applying the / operator.
Source§

fn div(self, rhs: &Vec3) -> Vec3

Performs the / operation. Read more
Source§

impl Div<&Vec3> for f32

Source§

type Output = Vec3

The resulting type after applying the / operator.
Source§

fn div(self, rhs: &Vec3) -> Vec3

Performs the / operation. Read more
Source§

impl Div<&f32> for &Vec3

Source§

type Output = Vec3

The resulting type after applying the / operator.
Source§

fn div(self, rhs: &f32) -> Vec3

Performs the / operation. Read more
Source§

impl Div<&f32> for Vec3

Source§

type Output = Vec3

The resulting type after applying the / operator.
Source§

fn div(self, rhs: &f32) -> Vec3

Performs the / operation. Read more
Source§

impl Div<Vec3> for &Vec3

Source§

type Output = Vec3

The resulting type after applying the / operator.
Source§

fn div(self, rhs: Vec3) -> Vec3

Performs the / operation. Read more
Source§

impl Div<Vec3> for &f32

Source§

type Output = Vec3

The resulting type after applying the / operator.
Source§

fn div(self, rhs: Vec3) -> Vec3

Performs the / operation. Read more
Source§

impl Div<Vec3> for f32

Source§

type Output = Vec3

The resulting type after applying the / operator.
Source§

fn div(self, rhs: Vec3) -> Vec3

Performs the / operation. Read more
Source§

impl Div<f32> for &Vec3

Source§

type Output = Vec3

The resulting type after applying the / operator.
Source§

fn div(self, rhs: f32) -> Vec3

Performs the / operation. Read more
Source§

impl Div<f32> for Vec3

Source§

type Output = Vec3

The resulting type after applying the / operator.
Source§

fn div(self, rhs: f32) -> Vec3

Performs the / operation. Read more
Source§

impl Div for Vec3

Source§

type Output = Vec3

The resulting type after applying the / operator.
Source§

fn div(self, rhs: Vec3) -> Vec3

Performs the / operation. Read more
Source§

impl DivAssign<&Vec3> for Vec3

Source§

fn div_assign(&mut self, rhs: &Vec3)

Performs the /= operation. Read more
Source§

impl DivAssign<&f32> for Vec3

Source§

fn div_assign(&mut self, rhs: &f32)

Performs the /= operation. Read more
Source§

impl DivAssign<f32> for Vec3

Source§

fn div_assign(&mut self, rhs: f32)

Performs the /= operation. Read more
Source§

impl DivAssign for Vec3

Source§

fn div_assign(&mut self, rhs: Vec3)

Performs the /= operation. Read more
Source§

impl From<[f32; 3]> for Vec3

Source§

fn from(a: [f32; 3]) -> Vec3

Converts to this type from the input type.
Source§

impl From<(Vec2, f32)> for Vec3

Source§

fn from(_: (Vec2, f32)) -> Vec3

Converts to this type from the input type.
Source§

impl From<(f32, f32, f32)> for Vec3

Source§

fn from(t: (f32, f32, f32)) -> Vec3

Converts to this type from the input type.
Source§

impl From<BVec3> for Vec3

Source§

fn from(v: BVec3) -> Vec3

Converts to this type from the input type.
Source§

impl From<BVec3A> for Vec3

Source§

fn from(v: BVec3A) -> Vec3

Converts to this type from the input type.
Source§

impl From<Dir3> for Vec3

Source§

fn from(value: Dir3) -> Vec3

Converts to this type from the input type.
Source§

impl From<Vec3> for [f32; 3]

Source§

fn from(v: Vec3) -> [f32; 3]

Converts to this type from the input type.
Source§

impl From<Vec3> for (f32, f32, f32)

Source§

fn from(v: Vec3) -> (f32, f32, f32)

Converts to this type from the input type.
Source§

impl From<Vec3> for DVec3

Source§

fn from(v: Vec3) -> DVec3

Converts to this type from the input type.
Source§

impl From<Vec3> for Isometry3d

Source§

fn from(translation: Vec3) -> Isometry3d

Converts to this type from the input type.
Source§

impl From<Vec3> for Vec3A

Source§

fn from(v: Vec3) -> Vec3A

Converts to this type from the input type.
Source§

impl From<Vec3A> for Vec3

Source§

fn from(v: Vec3A) -> Vec3

Converts to this type from the input type.
Source§

impl FromArg for &'static Vec3
where Vec3: Any + Send + Sync, f32: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

type This<'from_arg> = &'from_arg Vec3

The type to convert into. Read more
Source§

fn from_arg( arg: Arg<'_>, ) -> Result<<&'static Vec3 as FromArg>::This<'_>, ArgError>

Creates an item from an argument. Read more
Source§

impl FromArg for &'static mut Vec3
where Vec3: Any + Send + Sync, f32: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

type This<'from_arg> = &'from_arg mut Vec3

The type to convert into. Read more
Source§

fn from_arg( arg: Arg<'_>, ) -> Result<<&'static mut Vec3 as FromArg>::This<'_>, ArgError>

Creates an item from an argument. Read more
Source§

impl FromArg for Vec3
where Vec3: Any + Send + Sync, f32: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

type This<'from_arg> = Vec3

The type to convert into. Read more
Source§

fn from_arg(arg: Arg<'_>) -> Result<<Vec3 as FromArg>::This<'_>, ArgError>

Creates an item from an argument. Read more
Source§

impl FromIterator<Vec3> for BoxedPolyline3d

Source§

fn from_iter<I>(iter: I) -> BoxedPolyline3d
where I: IntoIterator<Item = Vec3>,

Creates a value from an iterator. Read more
Source§

impl<const N: usize> FromIterator<Vec3> for Polyline3d<N>

Source§

fn from_iter<I>(iter: I) -> Polyline3d<N>
where I: IntoIterator<Item = Vec3>,

Creates a value from an iterator. Read more
Source§

impl FromReflect for Vec3
where Vec3: Any + Send + Sync, f32: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

fn from_reflect(reflect: &(dyn PartialReflect + 'static)) -> Option<Vec3>

Constructs a concrete instance of Self from a reflected value.
Source§

fn take_from_reflect( reflect: Box<dyn PartialReflect>, ) -> Result<Self, Box<dyn PartialReflect>>

Attempts to downcast the given value to Self using, constructing the value using from_reflect if that fails. Read more
Source§

impl FromVectorParts<f32, 3> for Vec3
where Vec3: From<[f32; 3]>, f32: VectorScalar,

Source§

fn from_parts(parts: [f32; 3]) -> Vec3

Source§

impl GetOwnership for &Vec3
where Vec3: Any + Send + Sync, f32: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

fn ownership() -> Ownership

Returns the ownership of Self.
Source§

impl GetOwnership for &mut Vec3
where Vec3: Any + Send + Sync, f32: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

fn ownership() -> Ownership

Returns the ownership of Self.
Source§

impl GetOwnership for Vec3
where Vec3: Any + Send + Sync, f32: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

fn ownership() -> Ownership

Returns the ownership of Self.
Source§

impl GetTypeRegistration for Vec3
where Vec3: Any + Send + Sync, f32: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

fn get_type_registration() -> TypeRegistration

Returns the default TypeRegistration for this type.
Source§

fn register_type_dependencies(registry: &mut TypeRegistry)

Registers other types needed by this type. Read more
Source§

impl Index<usize> for Vec3

Source§

type Output = f32

The returned type after indexing.
Source§

fn index(&self, index: usize) -> &<Vec3 as Index<usize>>::Output

Performs the indexing (container[index]) operation. Read more
Source§

impl IndexMut<usize> for Vec3

Source§

fn index_mut(&mut self, index: usize) -> &mut <Vec3 as Index<usize>>::Output

Performs the mutable indexing (container[index]) operation. Read more
Source§

impl IntoReturn for &Vec3
where Vec3: Any + Send + Sync, f32: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

fn into_return<'into_return>(self) -> Return<'into_return>
where &Vec3: 'into_return,

Converts Self into a Return value.
Source§

impl IntoReturn for &mut Vec3
where Vec3: Any + Send + Sync, f32: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

fn into_return<'into_return>(self) -> Return<'into_return>
where &mut Vec3: 'into_return,

Converts Self into a Return value.
Source§

impl IntoReturn for Vec3
where Vec3: Any + Send + Sync, f32: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

fn into_return<'into_return>(self) -> Return<'into_return>
where Vec3: 'into_return,

Converts Self into a Return value.
Source§

impl Mul<&Vec3> for &Vec3

Source§

type Output = Vec3

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: &Vec3) -> Vec3

Performs the * operation. Read more
Source§

impl Mul<&Vec3> for &f32

Source§

type Output = Vec3

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: &Vec3) -> Vec3

Performs the * operation. Read more
Source§

impl Mul<&Vec3> for Vec3

Source§

type Output = Vec3

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: &Vec3) -> Vec3

Performs the * operation. Read more
Source§

impl Mul<&Vec3> for f32

Source§

type Output = Vec3

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: &Vec3) -> Vec3

Performs the * operation. Read more
Source§

impl Mul<&f32> for &Vec3

Source§

type Output = Vec3

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: &f32) -> Vec3

Performs the * operation. Read more
Source§

impl Mul<&f32> for Vec3

Source§

type Output = Vec3

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: &f32) -> Vec3

Performs the * operation. Read more
Source§

impl Mul<Vec3> for &Vec3

Source§

type Output = Vec3

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: Vec3) -> Vec3

Performs the * operation. Read more
Source§

impl Mul<Vec3> for &f32

Source§

type Output = Vec3

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: Vec3) -> Vec3

Performs the * operation. Read more
Source§

impl Mul<Vec3> for GlobalTransform

Source§

type Output = Vec3

The resulting type after applying the * operator.
Source§

fn mul(self, value: Vec3) -> <GlobalTransform as Mul<Vec3>>::Output

Performs the * operation. Read more
Source§

impl Mul<Vec3> for Isometry3d

Source§

type Output = Vec3

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: Vec3) -> <Isometry3d as Mul<Vec3>>::Output

Performs the * operation. Read more
Source§

impl Mul<Vec3> for Mat3

Source§

type Output = Vec3

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: Vec3) -> <Mat3 as Mul<Vec3>>::Output

Performs the * operation. Read more
Source§

impl Mul<Vec3> for Mat3A

Source§

type Output = Vec3

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: Vec3) -> Vec3

Performs the * operation. Read more
Source§

impl Mul<Vec3> for Quat

Source§

fn mul(self, rhs: Vec3) -> <Quat as Mul<Vec3>>::Output

Multiplies a quaternion and a 3D vector, returning the rotated vector.

§Panics

Will panic if self is not normalized when glam_assert is enabled.

Source§

type Output = Vec3

The resulting type after applying the * operator.
Source§

impl Mul<Vec3> for Transform

Source§

type Output = Vec3

The resulting type after applying the * operator.
Source§

fn mul(self, value: Vec3) -> <Transform as Mul<Vec3>>::Output

Performs the * operation. Read more
Source§

impl Mul<Vec3> for f32

Source§

type Output = Vec3

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: Vec3) -> Vec3

Performs the * operation. Read more
Source§

impl Mul<f32> for &Vec3

Source§

type Output = Vec3

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: f32) -> Vec3

Performs the * operation. Read more
Source§

impl Mul<f32> for Vec3

Source§

type Output = Vec3

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: f32) -> Vec3

Performs the * operation. Read more
Source§

impl Mul for Vec3

Source§

type Output = Vec3

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: Vec3) -> Vec3

Performs the * operation. Read more
Source§

impl MulAssign<&Vec3> for Vec3

Source§

fn mul_assign(&mut self, rhs: &Vec3)

Performs the *= operation. Read more
Source§

impl MulAssign<&f32> for Vec3

Source§

fn mul_assign(&mut self, rhs: &f32)

Performs the *= operation. Read more
Source§

impl MulAssign<f32> for Vec3

Source§

fn mul_assign(&mut self, rhs: f32)

Performs the *= operation. Read more
Source§

impl MulAssign for Vec3

Source§

fn mul_assign(&mut self, rhs: Vec3)

Performs the *= operation. Read more
Source§

impl Neg for &Vec3

Source§

type Output = Vec3

The resulting type after applying the - operator.
Source§

fn neg(self) -> Vec3

Performs the unary - operation. Read more
Source§

impl Neg for Vec3

Source§

type Output = Vec3

The resulting type after applying the - operator.
Source§

fn neg(self) -> Vec3

Performs the unary - operation. Read more
Source§

impl NormedVectorSpace for Vec3

Source§

fn norm(self) -> f32

The size of this element. The return value should always be nonnegative.
Source§

fn norm_squared(self) -> f32

The squared norm of this element. Computing this is often faster than computing NormedVectorSpace::norm.
Source§

fn distance(self, rhs: Self) -> f32

The distance between this element and another, as determined by the norm.
Source§

fn distance_squared(self, rhs: Self) -> f32

The squared distance between this element and another, as determined by the norm. Note that this is often faster to compute in practice than NormedVectorSpace::distance.
Source§

impl PartialEq for Vec3

Source§

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

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

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

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl PartialReflect for Vec3
where Vec3: Any + Send + Sync, f32: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

fn get_represented_type_info(&self) -> Option<&'static TypeInfo>

Returns the TypeInfo of the type represented by this value. Read more
Source§

fn try_apply( &mut self, value: &(dyn PartialReflect + 'static), ) -> Result<(), ApplyError>

Tries to apply a reflected value to this value. Read more
Source§

fn reflect_kind(&self) -> ReflectKind

Returns a zero-sized enumeration of “kinds” of type. Read more
Source§

fn reflect_ref(&self) -> ReflectRef<'_>

Returns an immutable enumeration of “kinds” of type. Read more
Source§

fn reflect_mut(&mut self) -> ReflectMut<'_>

Returns a mutable enumeration of “kinds” of type. Read more
Source§

fn reflect_owned(self: Box<Vec3>) -> ReflectOwned

Returns an owned enumeration of “kinds” of type. Read more
Source§

fn try_into_reflect( self: Box<Vec3>, ) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>>

Attempts to cast this type to a boxed, fully-reflected value.
Source§

fn try_as_reflect(&self) -> Option<&(dyn Reflect + 'static)>

Attempts to cast this type to a fully-reflected value.
Source§

fn try_as_reflect_mut(&mut self) -> Option<&mut (dyn Reflect + 'static)>

Attempts to cast this type to a mutable, fully-reflected value.
Source§

fn into_partial_reflect(self: Box<Vec3>) -> Box<dyn PartialReflect>

Casts this type to a boxed, reflected value. Read more
Source§

fn as_partial_reflect(&self) -> &(dyn PartialReflect + 'static)

Casts this type to a reflected value. Read more
Source§

fn as_partial_reflect_mut(&mut self) -> &mut (dyn PartialReflect + 'static)

Casts this type to a mutable, reflected value. Read more
Source§

fn reflect_partial_eq( &self, value: &(dyn PartialReflect + 'static), ) -> Option<bool>

Returns a “partial equality” comparison result. Read more
Source§

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

Debug formatter for the value. Read more
Source§

fn reflect_clone(&self) -> Result<Box<dyn Reflect>, ReflectCloneError>

Attempts to clone Self using reflection. Read more
Source§

fn apply(&mut self, value: &(dyn PartialReflect + 'static))

Applies a reflected value to this value. Read more
Source§

fn clone_value(&self) -> Box<dyn PartialReflect>

👎Deprecated since 0.16.0: to clone reflected values, prefer using reflect_clone. To convert reflected values to dynamic ones, use to_dynamic.
Clones Self into its dynamic representation. Read more
Source§

fn to_dynamic(&self) -> Box<dyn PartialReflect>

Converts this reflected value into its dynamic representation based on its kind. Read more
Source§

fn reflect_hash(&self) -> Option<u64>

Returns a hash of the value (which includes the type). Read more
Source§

fn is_dynamic(&self) -> bool

Indicates whether or not this type is a dynamic type. Read more
Source§

impl<'a> Product<&'a Vec3> for Vec3

Source§

fn product<I>(iter: I) -> Vec3
where I: Iterator<Item = &'a Vec3>,

Takes an iterator and generates Self from the elements by multiplying the items.
Source§

impl Product for Vec3

Source§

fn product<I>(iter: I) -> Vec3
where I: Iterator<Item = Vec3>,

Takes an iterator and generates Self from the elements by multiplying the items.
Source§

impl ReadFrom for Vec3

Source§

fn read_from<B>(&mut self, reader: &mut Reader<B>)
where B: BufferRef,

Source§

impl Reflect for Vec3
where Vec3: Any + Send + Sync, f32: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

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

Returns the value as a Box<dyn Any>. Read more
Source§

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

Returns the value as a &dyn Any. Read more
Source§

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

Returns the value as a &mut dyn Any. Read more
Source§

fn into_reflect(self: Box<Vec3>) -> Box<dyn Reflect>

Casts this type to a boxed, fully-reflected value.
Source§

fn as_reflect(&self) -> &(dyn Reflect + 'static)

Casts this type to a fully-reflected value.
Source§

fn as_reflect_mut(&mut self) -> &mut (dyn Reflect + 'static)

Casts this type to a mutable, fully-reflected value.
Source§

fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>>

Performs a type-checked assignment of a reflected value to this value. Read more
Source§

impl Rem<&Vec3> for &Vec3

Source§

type Output = Vec3

The resulting type after applying the % operator.
Source§

fn rem(self, rhs: &Vec3) -> Vec3

Performs the % operation. Read more
Source§

impl Rem<&Vec3> for &f32

Source§

type Output = Vec3

The resulting type after applying the % operator.
Source§

fn rem(self, rhs: &Vec3) -> Vec3

Performs the % operation. Read more
Source§

impl Rem<&Vec3> for Vec3

Source§

type Output = Vec3

The resulting type after applying the % operator.
Source§

fn rem(self, rhs: &Vec3) -> Vec3

Performs the % operation. Read more
Source§

impl Rem<&Vec3> for f32

Source§

type Output = Vec3

The resulting type after applying the % operator.
Source§

fn rem(self, rhs: &Vec3) -> Vec3

Performs the % operation. Read more
Source§

impl Rem<&f32> for &Vec3

Source§

type Output = Vec3

The resulting type after applying the % operator.
Source§

fn rem(self, rhs: &f32) -> Vec3

Performs the % operation. Read more
Source§

impl Rem<&f32> for Vec3

Source§

type Output = Vec3

The resulting type after applying the % operator.
Source§

fn rem(self, rhs: &f32) -> Vec3

Performs the % operation. Read more
Source§

impl Rem<Vec3> for &Vec3

Source§

type Output = Vec3

The resulting type after applying the % operator.
Source§

fn rem(self, rhs: Vec3) -> Vec3

Performs the % operation. Read more
Source§

impl Rem<Vec3> for &f32

Source§

type Output = Vec3

The resulting type after applying the % operator.
Source§

fn rem(self, rhs: Vec3) -> Vec3

Performs the % operation. Read more
Source§

impl Rem<Vec3> for f32

Source§

type Output = Vec3

The resulting type after applying the % operator.
Source§

fn rem(self, rhs: Vec3) -> Vec3

Performs the % operation. Read more
Source§

impl Rem<f32> for &Vec3

Source§

type Output = Vec3

The resulting type after applying the % operator.
Source§

fn rem(self, rhs: f32) -> Vec3

Performs the % operation. Read more
Source§

impl Rem<f32> for Vec3

Source§

type Output = Vec3

The resulting type after applying the % operator.
Source§

fn rem(self, rhs: f32) -> Vec3

Performs the % operation. Read more
Source§

impl Rem for Vec3

Source§

type Output = Vec3

The resulting type after applying the % operator.
Source§

fn rem(self, rhs: Vec3) -> Vec3

Performs the % operation. Read more
Source§

impl RemAssign<&Vec3> for Vec3

Source§

fn rem_assign(&mut self, rhs: &Vec3)

Performs the %= operation. Read more
Source§

impl RemAssign<&f32> for Vec3

Source§

fn rem_assign(&mut self, rhs: &f32)

Performs the %= operation. Read more
Source§

impl RemAssign<f32> for Vec3

Source§

fn rem_assign(&mut self, rhs: f32)

Performs the %= operation. Read more
Source§

impl RemAssign for Vec3

Source§

fn rem_assign(&mut self, rhs: Vec3)

Performs the %= operation. Read more
Source§

impl Serialize for Vec3

Serialize as a sequence of 3 values.

Source§

fn serialize<S>( &self, serializer: S, ) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where S: Serializer,

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

impl ShaderSize for Vec3
where f32: ShaderSize,

Source§

const SHADER_SIZE: NonZero<u64> = _

Represents WGSL Size (equivalent to ShaderType::min_size)
Source§

impl ShaderType for Vec3
where f32: ShaderSize,

Source§

fn min_size() -> NonZero<u64>

Represents the minimum size of Self (equivalent to GPUBufferBindingLayout.minBindingSize) Read more
Source§

fn size(&self) -> NonZero<u64>

Returns the size of Self at runtime Read more
Source§

fn assert_uniform_compat()

Source§

impl Struct for Vec3
where Vec3: Any + Send + Sync, f32: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

fn field(&self, name: &str) -> Option<&(dyn PartialReflect + 'static)>

Returns a reference to the value of the field named name as a &dyn PartialReflect.
Source§

fn field_mut( &mut self, name: &str, ) -> Option<&mut (dyn PartialReflect + 'static)>

Returns a mutable reference to the value of the field named name as a &mut dyn PartialReflect.
Source§

fn field_at(&self, index: usize) -> Option<&(dyn PartialReflect + 'static)>

Returns a reference to the value of the field with index index as a &dyn PartialReflect.
Source§

fn field_at_mut( &mut self, index: usize, ) -> Option<&mut (dyn PartialReflect + 'static)>

Returns a mutable reference to the value of the field with index index as a &mut dyn PartialReflect.
Source§

fn name_at(&self, index: usize) -> Option<&str>

Returns the name of the field with index index.
Source§

fn field_len(&self) -> usize

Returns the number of fields in the struct.
Source§

fn iter_fields(&self) -> FieldIter<'_>

Returns an iterator over the values of the reflectable fields for this struct.
Source§

fn to_dynamic_struct(&self) -> DynamicStruct

Source§

fn clone_dynamic(&self) -> DynamicStruct

👎Deprecated since 0.16.0: use to_dynamic_struct instead
Clones the struct into a DynamicStruct.
Source§

fn get_represented_struct_info(&self) -> Option<&'static StructInfo>

Will return None if TypeInfo is not available.
Source§

impl Sub<&Vec3> for &Vec3

Source§

type Output = Vec3

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: &Vec3) -> Vec3

Performs the - operation. Read more
Source§

impl Sub<&Vec3> for &f32

Source§

type Output = Vec3

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: &Vec3) -> Vec3

Performs the - operation. Read more
Source§

impl Sub<&Vec3> for Vec3

Source§

type Output = Vec3

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: &Vec3) -> Vec3

Performs the - operation. Read more
Source§

impl Sub<&Vec3> for f32

Source§

type Output = Vec3

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: &Vec3) -> Vec3

Performs the - operation. Read more
Source§

impl Sub<&f32> for &Vec3

Source§

type Output = Vec3

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: &f32) -> Vec3

Performs the - operation. Read more
Source§

impl Sub<&f32> for Vec3

Source§

type Output = Vec3

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: &f32) -> Vec3

Performs the - operation. Read more
Source§

impl Sub<Vec3> for &Vec3

Source§

type Output = Vec3

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: Vec3) -> Vec3

Performs the - operation. Read more
Source§

impl Sub<Vec3> for &f32

Source§

type Output = Vec3

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: Vec3) -> Vec3

Performs the - operation. Read more
Source§

impl Sub<Vec3> for f32

Source§

type Output = Vec3

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: Vec3) -> Vec3

Performs the - operation. Read more
Source§

impl Sub<f32> for &Vec3

Source§

type Output = Vec3

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: f32) -> Vec3

Performs the - operation. Read more
Source§

impl Sub<f32> for Vec3

Source§

type Output = Vec3

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: f32) -> Vec3

Performs the - operation. Read more
Source§

impl Sub for Vec3

Source§

type Output = Vec3

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: Vec3) -> Vec3

Performs the - operation. Read more
Source§

impl SubAssign<&Vec3> for Vec3

Source§

fn sub_assign(&mut self, rhs: &Vec3)

Performs the -= operation. Read more
Source§

impl SubAssign<&f32> for Vec3

Source§

fn sub_assign(&mut self, rhs: &f32)

Performs the -= operation. Read more
Source§

impl SubAssign<f32> for Vec3

Source§

fn sub_assign(&mut self, rhs: f32)

Performs the -= operation. Read more
Source§

impl SubAssign for Vec3

Source§

fn sub_assign(&mut self, rhs: Vec3)

Performs the -= operation. Read more
Source§

impl<'a> Sum<&'a Vec3> for Vec3

Source§

fn sum<I>(iter: I) -> Vec3
where I: Iterator<Item = &'a Vec3>,

Takes an iterator and generates Self from the elements by “summing up” the items.
Source§

impl Sum for Vec3

Source§

fn sum<I>(iter: I) -> Vec3
where I: Iterator<Item = Vec3>,

Takes an iterator and generates Self from the elements by “summing up” the items.
Source§

impl TryFrom<Vec3> for Dir3

Source§

type Error = InvalidDirectionError

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

fn try_from(value: Vec3) -> Result<Dir3, <Dir3 as TryFrom<Vec3>>::Error>

Performs the conversion.
Source§

impl TypePath for Vec3
where Vec3: Any + Send + Sync,

Source§

fn type_path() -> &'static str

Returns the fully qualified path of the underlying type. Read more
Source§

fn short_type_path() -> &'static str

Returns a short, pretty-print enabled path to the type. Read more
Source§

fn type_ident() -> Option<&'static str>

Returns the name of the type, or None if it is anonymous. Read more
Source§

fn crate_name() -> Option<&'static str>

Returns the name of the crate the type is in, or None if it is anonymous. Read more
Source§

fn module_path() -> Option<&'static str>

Returns the path to the module the type is in, or None if it is anonymous. Read more
Source§

impl Typed for Vec3
where Vec3: Any + Send + Sync, f32: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

fn type_info() -> &'static TypeInfo

Returns the compile-time info for the underlying type.
Source§

impl Vec3Swizzles for Vec3

Source§

type Vec2 = Vec2

Source§

type Vec4 = Vec4

Source§

fn xx(self) -> Vec2

Source§

fn xy(self) -> Vec2

Source§

fn xz(self) -> Vec2

Source§

fn yx(self) -> Vec2

Source§

fn yy(self) -> Vec2

Source§

fn yz(self) -> Vec2

Source§

fn zx(self) -> Vec2

Source§

fn zy(self) -> Vec2

Source§

fn zz(self) -> Vec2

Source§

fn xxx(self) -> Vec3

Source§

fn xxy(self) -> Vec3

Source§

fn xxz(self) -> Vec3

Source§

fn xyx(self) -> Vec3

Source§

fn xyy(self) -> Vec3

Source§

fn xzx(self) -> Vec3

Source§

fn xzy(self) -> Vec3

Source§

fn xzz(self) -> Vec3

Source§

fn yxx(self) -> Vec3

Source§

fn yxy(self) -> Vec3

Source§

fn yxz(self) -> Vec3

Source§

fn yyx(self) -> Vec3

Source§

fn yyy(self) -> Vec3

Source§

fn yyz(self) -> Vec3

Source§

fn yzx(self) -> Vec3

Source§

fn yzy(self) -> Vec3

Source§

fn yzz(self) -> Vec3

Source§

fn zxx(self) -> Vec3

Source§

fn zxy(self) -> Vec3

Source§

fn zxz(self) -> Vec3

Source§

fn zyx(self) -> Vec3

Source§

fn zyy(self) -> Vec3

Source§

fn zyz(self) -> Vec3

Source§

fn zzx(self) -> Vec3

Source§

fn zzy(self) -> Vec3

Source§

fn zzz(self) -> Vec3

Source§

fn xxxx(self) -> Vec4

Source§

fn xxxy(self) -> Vec4

Source§

fn xxxz(self) -> Vec4

Source§

fn xxyx(self) -> Vec4

Source§

fn xxyy(self) -> Vec4

Source§

fn xxyz(self) -> Vec4

Source§

fn xxzx(self) -> Vec4

Source§

fn xxzy(self) -> Vec4

Source§

fn xxzz(self) -> Vec4

Source§

fn xyxx(self) -> Vec4

Source§

fn xyxy(self) -> Vec4

Source§

fn xyxz(self) -> Vec4

Source§

fn xyyx(self) -> Vec4

Source§

fn xyyy(self) -> Vec4

Source§

fn xyyz(self) -> Vec4

Source§

fn xyzx(self) -> Vec4

Source§

fn xyzy(self) -> Vec4

Source§

fn xyzz(self) -> Vec4

Source§

fn xzxx(self) -> Vec4

Source§

fn xzxy(self) -> Vec4

Source§

fn xzxz(self) -> Vec4

Source§

fn xzyx(self) -> Vec4

Source§

fn xzyy(self) -> Vec4

Source§

fn xzyz(self) -> Vec4

Source§

fn xzzx(self) -> Vec4

Source§

fn xzzy(self) -> Vec4

Source§

fn xzzz(self) -> Vec4

Source§

fn yxxx(self) -> Vec4

Source§

fn yxxy(self) -> Vec4

Source§

fn yxxz(self) -> Vec4

Source§

fn yxyx(self) -> Vec4

Source§

fn yxyy(self) -> Vec4

Source§

fn yxyz(self) -> Vec4

Source§

fn yxzx(self) -> Vec4

Source§

fn yxzy(self) -> Vec4

Source§

fn yxzz(self) -> Vec4

Source§

fn yyxx(self) -> Vec4

Source§

fn yyxy(self) -> Vec4

Source§

fn yyxz(self) -> Vec4

Source§

fn yyyx(self) -> Vec4

Source§

fn yyyy(self) -> Vec4

Source§

fn yyyz(self) -> Vec4

Source§

fn yyzx(self) -> Vec4

Source§

fn yyzy(self) -> Vec4

Source§

fn yyzz(self) -> Vec4

Source§

fn yzxx(self) -> Vec4

Source§

fn yzxy(self) -> Vec4

Source§

fn yzxz(self) -> Vec4

Source§

fn yzyx(self) -> Vec4

Source§

fn yzyy(self) -> Vec4

Source§

fn yzyz(self) -> Vec4

Source§

fn yzzx(self) -> Vec4

Source§

fn yzzy(self) -> Vec4

Source§

fn yzzz(self) -> Vec4

Source§

fn zxxx(self) -> Vec4

Source§

fn zxxy(self) -> Vec4

Source§

fn zxxz(self) -> Vec4

Source§

fn zxyx(self) -> Vec4

Source§

fn zxyy(self) -> Vec4

Source§

fn zxyz(self) -> Vec4

Source§

fn zxzx(self) -> Vec4

Source§

fn zxzy(self) -> Vec4

Source§

fn zxzz(self) -> Vec4

Source§

fn zyxx(self) -> Vec4

Source§

fn zyxy(self) -> Vec4

Source§

fn zyxz(self) -> Vec4

Source§

fn zyyx(self) -> Vec4

Source§

fn zyyy(self) -> Vec4

Source§

fn zyyz(self) -> Vec4

Source§

fn zyzx(self) -> Vec4

Source§

fn zyzy(self) -> Vec4

Source§

fn zyzz(self) -> Vec4

Source§

fn zzxx(self) -> Vec4

Source§

fn zzxy(self) -> Vec4

Source§

fn zzxz(self) -> Vec4

Source§

fn zzyx(self) -> Vec4

Source§

fn zzyy(self) -> Vec4

Source§

fn zzyz(self) -> Vec4

Source§

fn zzzx(self) -> Vec4

Source§

fn zzzy(self) -> Vec4

Source§

fn zzzz(self) -> Vec4

Source§

fn xyz(self) -> Self

Source§

impl VectorSpace for Vec3

Source§

const ZERO: Vec3 = Vec3::ZERO

The zero vector, which is the identity of addition for the vector space type.
Source§

fn lerp(self, rhs: Self, t: f32) -> Self

Perform vector space linear interpolation between this element and another, based on the parameter t. When t is 0, self is recovered. When t is 1, rhs is recovered. Read more
Source§

impl WriteInto for Vec3

Source§

fn write_into<B>(&self, writer: &mut Writer<B>)
where B: BufferMut,

Source§

impl Zeroable for Vec3

Source§

fn zeroed() -> Self

Source§

impl Copy for Vec3

Source§

impl Pod for Vec3

Source§

impl StructuralPartialEq for Vec3

Auto Trait Implementations§

§

impl Freeze for Vec3

§

impl RefUnwindSafe for Vec3

§

impl Send for Vec3

§

impl Sync for Vec3

§

impl Unpin for Vec3

§

impl UnwindSafe for Vec3

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, U> AsBindGroupShaderType<U> for T
where U: ShaderType, &'a T: for<'a> Into<U>,

Source§

fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U

Return the T ShaderType for self. When used in AsBindGroup derives, it is safe to assume that all images in self exist.
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<T> CheckedBitPattern for T
where T: AnyBitPattern,

Source§

type Bits = T

Self must have the same layout as the specified Bits except for the possible invalid bit patterns being checked during is_valid_bit_pattern.
Source§

fn is_valid_bit_pattern(_bits: &T) -> bool

If this function returns true, then it must be valid to reinterpret bits as &Self.
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> Conv for T

Source§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

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 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> 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 + Sync + Send>

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> DynamicTypePath for T
where T: TypePath,

Source§

impl<T> DynamicTyped for T
where T: Typed,

Source§

impl<V> Ease for V
where V: VectorSpace,

Source§

fn interpolating_curve_unbounded(start: V, end: V) -> impl Curve<V>

Given start and end values, produce a curve with unlimited domain that: Read more
Source§

impl<T> FmtForward for T

Source§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
Source§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
Source§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
Source§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
Source§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
Source§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
Source§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
Source§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
Source§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
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> FromWorld for T
where T: Default,

Source§

fn from_world(_world: &mut World) -> T

Creates Self using default().

Source§

impl<S> GetField for S
where S: Struct,

Source§

fn get_field<T>(&self, name: &str) -> Option<&T>
where T: Reflect,

Returns a reference to the value of the field named name, downcast to T.
Source§

fn get_field_mut<T>(&mut self, name: &str) -> Option<&mut T>
where T: Reflect,

Returns a mutable reference to the value of the field named name, downcast to T.
Source§

impl<T> GetPath for T
where T: Reflect + ?Sized,

Source§

fn reflect_path<'p>( &self, path: impl ReflectPath<'p>, ) -> Result<&(dyn PartialReflect + 'static), ReflectPathError<'p>>

Returns a reference to the value specified by path. Read more
Source§

fn reflect_path_mut<'p>( &mut self, path: impl ReflectPath<'p>, ) -> Result<&mut (dyn PartialReflect + 'static), ReflectPathError<'p>>

Returns a mutable reference to the value specified by path. Read more
Source§

fn path<'p, T>( &self, path: impl ReflectPath<'p>, ) -> Result<&T, ReflectPathError<'p>>
where T: Reflect,

Returns a statically typed reference to the value specified by path. Read more
Source§

fn path_mut<'p, T>( &mut self, path: impl ReflectPath<'p>, ) -> Result<&mut T, ReflectPathError<'p>>
where T: Reflect,

Returns a statically typed mutable reference to the value specified by path. Read more
Source§

impl<V> HasTangent for V
where V: VectorSpace,

Source§

type Tangent = V

The tangent type.
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> NoneValue for T
where T: Default,

Source§

type NoneType = T

Source§

fn null_value() -> T

The none-equivalent value.
Source§

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

Source§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
Source§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
Source§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
Source§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
Source§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
Source§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
Source§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
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<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> Serialize for T
where T: Serialize + ?Sized,

Source§

fn erased_serialize(&self, serializer: &mut dyn Serializer) -> Result<(), Error>

Source§

fn do_erased_serialize( &self, serializer: &mut dyn Serializer, ) -> Result<(), ErrorImpl>

Source§

impl<V> StableInterpolate for V

Source§

fn interpolate_stable(&self, other: &V, t: f32) -> V

Interpolate between this value and the other given value using the parameter t. At t = 0.0, a value equivalent to self is recovered, while t = 1.0 recovers a value equivalent to other, with intermediate values interpolating between the two. See the trait-level documentation for details.
Source§

fn interpolate_stable_assign(&mut self, other: &Self, t: f32)

A version of interpolate_stable that assigns the result to self for convenience.
Source§

fn smooth_nudge(&mut self, target: &Self, decay_rate: f32, delta: f32)

Smoothly nudge this value towards the target at a given decay rate. The decay_rate parameter controls how fast the distance between self and target decays relative to the units of delta; the intended usage is for decay_rate to generally remain fixed, while delta is something like delta_time from an updating system. This produces a smooth following of the target that is independent of framerate. Read more
Source§

impl<T> Tap for T

Source§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
Source§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
Source§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
Source§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
Source§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
Source§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
Source§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
Source§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
Source§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
Source§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
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> ToSmolStr for T
where T: Display + ?Sized,

Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T> TryConv for T

Source§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
Source§

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

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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> TypeData for T
where T: 'static + Send + Sync + Clone,

Source§

impl<T> Upcast<T> for T

Source§

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

Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

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

impl<T> AnyBitPattern for T
where T: Pod,

Source§

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

Source§

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

Source§

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

Source§

impl<T> GpuArrayBufferable for T

Source§

impl<T> NoUninit for T
where T: Pod,

Source§

impl<T, Rhs> NumAssignOps<Rhs> for T
where T: AddAssign<Rhs> + SubAssign<Rhs> + MulAssign<Rhs> + DivAssign<Rhs> + RemAssign<Rhs>,

Source§

impl<T, Rhs, Output> NumOps<Rhs, Output> for T
where T: Sub<Rhs, Output = Output> + Mul<Rhs, Output = Output> + Div<Rhs, Output = Output> + Add<Rhs, Output = Output> + Rem<Rhs, Output = Output>,

Source§

impl<T, Base> RefNum<Base> for T
where T: NumOps<Base, Base> + for<'r> NumOps<&'r Base, Base>,

Source§

impl<T> Reflectable for T

Source§

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

Source§

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

Source§

impl<T> WasmNotSendSync for T

Source§

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