Struct Transform

Source
pub struct Transform {
    pub translation: Vec3,
    pub rotation: Quat,
    pub scale: Vec3,
}
Expand description

Describe the position of an entity. If the entity has a parent, the position is relative to its parent position.

§Transform and GlobalTransform

Transform is the position of an entity relative to its parent position, or the reference frame if it doesn’t have a ChildOf component.

GlobalTransform is the position of an entity relative to the reference frame.

GlobalTransform is updated from Transform by systems in the system set TransformPropagate.

This system runs during PostUpdate. If you update the Transform of an entity during this set or after, you will notice a 1 frame lag before the GlobalTransform is updated.

§Examples

Fields§

§translation: Vec3

Position of the entity. In 2d, the last value of the Vec3 is used for z-ordering.

See the translations example for usage.

§rotation: Quat

Rotation of the entity.

See the 3d_rotation example for usage.

§scale: Vec3

Scale of the entity.

See the scale example for usage.

Implementations§

Source§

impl Transform

Source

pub const IDENTITY: Transform

An identity Transform with no translation, rotation, and a scale of 1 on all axes.

Source

pub const fn from_xyz(x: f32, y: f32, z: f32) -> Transform

Creates a new Transform at the position (x, y, z). In 2d, the z component is used for z-ordering elements: higher z-value will be in front of lower z-value.

Examples found in repository?
examples/3d/clustered_decals.rs (line 207)
204fn spawn_light(commands: &mut Commands) {
205    commands.spawn((
206        DirectionalLight::default(),
207        Transform::from_xyz(4.0, 8.0, 4.0).looking_at(Vec3::ZERO, Vec3::Y),
208    ));
209}
210
211/// Spawns the camera.
212fn spawn_camera(commands: &mut Commands) {
213    commands
214        .spawn(Camera3d::default())
215        .insert(Transform::from_xyz(0.0, 2.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y))
216        // Tag the camera with `Selection::Camera`.
217        .insert(Selection::Camera);
218}
More examples
Hide additional examples
examples/3d/mixed_lighting.rs (line 159)
156fn spawn_camera(commands: &mut Commands) {
157    commands
158        .spawn(Camera3d::default())
159        .insert(Transform::from_xyz(-0.7, 0.7, 1.0).looking_at(vec3(0.0, 0.3, 0.0), Vec3::Y));
160}
examples/3d/occlusion_culling.rs (line 400)
397fn spawn_camera(commands: &mut Commands) {
398    commands
399        .spawn(Camera3d::default())
400        .insert(Transform::from_xyz(0.0, 0.0, 9.0).looking_at(Vec3::ZERO, Vec3::Y))
401        .insert(DepthPrepass)
402        .insert(OcclusionCulling);
403}
examples/3d/reflection_probes.rs (line 112)
105fn spawn_camera(commands: &mut Commands) {
106    commands.spawn((
107        Camera3d::default(),
108        Camera {
109            hdr: true,
110            ..default()
111        },
112        Transform::from_xyz(-6.483, 0.325, 4.381).looking_at(Vec3::ZERO, Vec3::Y),
113    ));
114}
examples/2d/move_sprite.rs (line 24)
19fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
20    commands.spawn(Camera2d);
21
22    commands.spawn((
23        Sprite::from_image(asset_server.load("branding/icon.png")),
24        Transform::from_xyz(0., 0., 0.),
25        Direction::Right,
26    ));
27}
examples/animation/color_animation.rs (line 74)
71fn spawn_curve_sprite<T: CurveColor>(commands: &mut Commands, y: f32, points: [T; 4]) {
72    commands.spawn((
73        Sprite::sized(Vec2::new(75., 75.)),
74        Transform::from_xyz(0., y, 0.),
75        Curve(CubicBezier::new([points]).to_curve().unwrap()),
76    ));
77}
78
79fn spawn_mixed_sprite<T: MixedColor>(commands: &mut Commands, y: f32, colors: [T; 4]) {
80    commands.spawn((
81        Transform::from_xyz(0., y, 0.),
82        Sprite::sized(Vec2::new(75., 75.)),
83        Mixed(colors),
84    ));
85}
Source

pub fn from_matrix(world_from_local: Mat4) -> Transform

Extracts the translation, rotation, and scale from matrix. It must be a 3d affine transformation matrix.

Examples found in repository?
examples/3d/irradiance_volumes.rs (line 248)
246fn spawn_irradiance_volume(commands: &mut Commands, assets: &ExampleAssets) {
247    commands.spawn((
248        Transform::from_matrix(VOXEL_FROM_WORLD),
249        IrradianceVolume {
250            voxels: assets.irradiance_volume.clone(),
251            intensity: IRRADIANCE_VOLUME_INTENSITY,
252            ..default()
253        },
254        LightProbe,
255    ));
256}
Source

pub const fn from_translation(translation: Vec3) -> Transform

Creates a new Transform, with translation. Rotation will be 0 and scale 1 on all axes.

Examples found in repository?
examples/stress_tests/many_sprites.rs (line 110)
107fn move_camera(time: Res<Time>, mut camera_transform: Single<&mut Transform, With<Camera>>) {
108    camera_transform.rotate_z(time.delta_secs() * 0.5);
109    **camera_transform = **camera_transform
110        * Transform::from_translation(Vec3::X * CAMERA_SPEED * time.delta_secs());
111}
More examples
Hide additional examples
examples/stress_tests/many_animated_sprites.rs (line 106)
103fn move_camera(time: Res<Time>, mut camera_transform: Single<&mut Transform, With<Camera>>) {
104    camera_transform.rotate(Quat::from_rotation_z(time.delta_secs() * 0.5));
105    **camera_transform = **camera_transform
106        * Transform::from_translation(Vec3::X * CAMERA_SPEED * time.delta_secs());
107}
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    }
examples/math/render_primitives.rs (line 321)
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}
examples/3d/fog_volumes.rs (line 79)
76fn rotate_camera(mut cameras: Query<&mut Transform, With<Camera3d>>) {
77    for mut camera_transform in cameras.iter_mut() {
78        *camera_transform =
79            Transform::from_translation(Quat::from_rotation_y(0.01) * camera_transform.translation)
80                .looking_at(vec3(0.0, 0.5, 0.0), Vec3::Y);
81    }
82}
examples/3d/clustered_decals.rs (line 349)
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}
Source

pub const fn from_rotation(rotation: Quat) -> Transform

Creates a new Transform, with rotation. Translation will be 0 and scale 1 on all axes.

Examples found in repository?
examples/3d/occlusion_culling.rs (lines 388-393)
385fn spawn_light(commands: &mut Commands) {
386    commands
387        .spawn(DirectionalLight::default())
388        .insert(Transform::from_rotation(Quat::from_euler(
389            EulerRot::ZYX,
390            0.0,
391            PI * -0.15,
392            PI * -0.15,
393        )));
394}
More examples
Hide additional examples
examples/3d/query_gltf_primitives.rs (line 62)
55fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
56    commands.spawn((
57        Camera3d::default(),
58        Transform::from_xyz(4.0, 4.0, 12.0).looking_at(Vec3::new(0.0, 0.0, 0.5), Vec3::Y),
59    ));
60
61    commands.spawn((
62        Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, 1.0, -PI / 4.)),
63        DirectionalLight::default(),
64    ));
65
66    commands.spawn(SceneRoot(asset_server.load(
67        GltfAssetLabel::Scene(0).from_asset("models/GltfPrimitives/gltf_primitives.glb"),
68    )));
69}
examples/asset/multi_asset_sync.rs (line 202)
185fn setup_scene(
186    mut commands: Commands,
187    mut meshes: ResMut<Assets<Mesh>>,
188    mut materials: ResMut<Assets<StandardMaterial>>,
189) {
190    // Camera
191    commands.spawn((
192        Camera3d::default(),
193        Transform::from_xyz(10.0, 10.0, 15.0).looking_at(Vec3::new(0.0, 0.0, 0.0), Vec3::Y),
194    ));
195
196    // Light
197    commands.spawn((
198        DirectionalLight {
199            shadows_enabled: true,
200            ..default()
201        },
202        Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, 1.0, -PI / 4.)),
203    ));
204
205    // Plane
206    commands.spawn((
207        Mesh3d(meshes.add(Plane3d::default().mesh().size(50000.0, 50000.0))),
208        MeshMaterial3d(materials.add(Color::srgb(0.7, 0.2, 0.2))),
209        Loading,
210    ));
211}
examples/transforms/scale.rs (line 46)
37fn setup(
38    mut commands: Commands,
39    mut meshes: ResMut<Assets<Mesh>>,
40    mut materials: ResMut<Assets<StandardMaterial>>,
41) {
42    // Spawn a cube to scale.
43    commands.spawn((
44        Mesh3d(meshes.add(Cuboid::default())),
45        MeshMaterial3d(materials.add(Color::WHITE)),
46        Transform::from_rotation(Quat::from_rotation_y(PI / 4.0)),
47        Scaling::new(),
48    ));
49
50    // Spawn a camera looking at the entities to show what's happening in this example.
51    commands.spawn((
52        Camera3d::default(),
53        Transform::from_xyz(0.0, 10.0, 20.0).looking_at(Vec3::ZERO, Vec3::Y),
54    ));
55
56    // Add a light source for better 3d visibility.
57    commands.spawn((
58        DirectionalLight::default(),
59        Transform::from_xyz(3.0, 3.0, 3.0).looking_at(Vec3::ZERO, Vec3::Y),
60    ));
61}
examples/animation/morph_targets.rs (line 54)
37fn setup(asset_server: Res<AssetServer>, mut commands: Commands) {
38    commands.insert_resource(MorphData {
39        the_wave: asset_server
40            .load(GltfAssetLabel::Animation(2).from_asset("models/animated/MorphStressTest.gltf")),
41        mesh: asset_server.load(
42            GltfAssetLabel::Primitive {
43                mesh: 0,
44                primitive: 0,
45            }
46            .from_asset("models/animated/MorphStressTest.gltf"),
47        ),
48    });
49    commands.spawn(SceneRoot(asset_server.load(
50        GltfAssetLabel::Scene(0).from_asset("models/animated/MorphStressTest.gltf"),
51    )));
52    commands.spawn((
53        DirectionalLight::default(),
54        Transform::from_rotation(Quat::from_rotation_z(PI / 2.0)),
55    ));
56    commands.spawn((
57        Camera3d::default(),
58        Transform::from_xyz(3.0, 2.1, 10.2).looking_at(Vec3::ZERO, Vec3::Y),
59    ));
60}
examples/3d/pcss.rs (lines 186-191)
179fn spawn_light(commands: &mut Commands, app_status: &AppStatus) {
180    // Because this light can become a directional light, point light, or spot
181    // light depending on the settings, we add the union of the components
182    // necessary for this light to behave as all three of those.
183    commands
184        .spawn((
185            create_directional_light(app_status),
186            Transform::from_rotation(Quat::from_array([
187                0.6539259,
188                -0.34646285,
189                0.36505926,
190                -0.5648683,
191            ]))
192            .with_translation(vec3(57.693, 34.334, -6.422)),
193        ))
194        // These two are needed for point lights.
195        .insert(CubemapVisibleEntities::default())
196        .insert(CubemapFrusta::default())
197        // These two are needed for spot lights.
198        .insert(VisibleMeshEntities::default())
199        .insert(Frustum::default());
200}
Source

pub const fn from_scale(scale: Vec3) -> Transform

Creates a new Transform, with scale. Translation will be 0 and rotation 0 on all axes.

Examples found in repository?
examples/3d/irradiance_volumes.rs (line 287)
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}
More examples
Hide additional examples
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/movement/physics_in_fixed_timestep.rs (line 137)
132fn spawn_player(mut commands: Commands, asset_server: Res<AssetServer>) {
133    commands.spawn(Camera2d);
134    commands.spawn((
135        Name::new("Player"),
136        Sprite::from_image(asset_server.load("branding/icon.png")),
137        Transform::from_scale(Vec3::splat(0.3)),
138        AccumulatedInput::default(),
139        Velocity::default(),
140        PhysicalTranslation::default(),
141        PreviousPhysicalTranslation::default(),
142    ));
143}
examples/3d/reflection_probes.rs (line 148)
138fn spawn_reflection_probe(commands: &mut Commands, cubemaps: &Cubemaps) {
139    commands.spawn((
140        LightProbe,
141        EnvironmentMapLight {
142            diffuse_map: cubemaps.diffuse.clone(),
143            specular_map: cubemaps.specular_reflection_probe.clone(),
144            intensity: 5000.0,
145            ..default()
146        },
147        // 2.0 because the sphere's radius is 1.0 and we want to fully enclose it.
148        Transform::from_scale(Vec3::splat(2.0)),
149    ));
150}
examples/2d/custom_gltf_vertex_attribute.rs (line 63)
47fn setup(
48    mut commands: Commands,
49    asset_server: Res<AssetServer>,
50    mut materials: ResMut<Assets<CustomMaterial>>,
51) {
52    // Add a mesh loaded from a glTF file. This mesh has data for `ATTRIBUTE_BARYCENTRIC`.
53    let mesh = asset_server.load(
54        GltfAssetLabel::Primitive {
55            mesh: 0,
56            primitive: 0,
57        }
58        .from_asset("models/barycentric/barycentric.gltf"),
59    );
60    commands.spawn((
61        Mesh2d(mesh),
62        MeshMaterial2d(materials.add(CustomMaterial {})),
63        Transform::from_scale(150.0 * Vec3::ONE),
64    ));
65
66    commands.spawn(Camera2d);
67}
examples/ecs/parallel_query.rs (line 20)
10fn spawn_system(mut commands: Commands, asset_server: Res<AssetServer>) {
11    commands.spawn(Camera2d);
12    let texture = asset_server.load("branding/icon.png");
13
14    // We're seeding the PRNG here to make this example deterministic for testing purposes.
15    // This isn't strictly required in practical use unless you need your app to be deterministic.
16    let mut rng = ChaCha8Rng::seed_from_u64(19878367467713);
17    for z in 0..128 {
18        commands.spawn((
19            Sprite::from_image(texture.clone()),
20            Transform::from_scale(Vec3::splat(0.1))
21                .with_translation(Vec2::splat(0.0).extend(z as f32)),
22            Velocity(20.0 * Vec2::new(rng.r#gen::<f32>() - 0.5, rng.r#gen::<f32>() - 0.5)),
23        ));
24    }
25}
Source

pub fn from_isometry(iso: Isometry3d) -> Transform

Creates a new Transform that is equivalent to the given isometry.

Source

pub fn looking_at(self, target: Vec3, up: impl TryInto<Dir3>) -> Transform

Returns this Transform with a new rotation so that Transform::forward points towards the target position and Transform::up points towards up.

In some cases it’s not possible to construct a rotation. Another axis will be picked in those cases:

  • if target is the same as the transform translation, Vec3::Z is used instead
  • if up fails converting to Dir3 (e.g if it is Vec3::ZERO), Dir3::Y is used instead
  • if the resulting forward direction is parallel with up, an orthogonal vector is used as the “right” direction
Examples found in repository?
examples/3d/clustered_decals.rs (line 207)
204fn spawn_light(commands: &mut Commands) {
205    commands.spawn((
206        DirectionalLight::default(),
207        Transform::from_xyz(4.0, 8.0, 4.0).looking_at(Vec3::ZERO, Vec3::Y),
208    ));
209}
210
211/// Spawns the camera.
212fn spawn_camera(commands: &mut Commands) {
213    commands
214        .spawn(Camera3d::default())
215        .insert(Transform::from_xyz(0.0, 2.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y))
216        // Tag the camera with `Selection::Camera`.
217        .insert(Selection::Camera);
218}
More examples
Hide additional examples
examples/3d/mixed_lighting.rs (line 159)
156fn spawn_camera(commands: &mut Commands) {
157    commands
158        .spawn(Camera3d::default())
159        .insert(Transform::from_xyz(-0.7, 0.7, 1.0).looking_at(vec3(0.0, 0.3, 0.0), Vec3::Y));
160}
examples/3d/occlusion_culling.rs (line 400)
397fn spawn_camera(commands: &mut Commands) {
398    commands
399        .spawn(Camera3d::default())
400        .insert(Transform::from_xyz(0.0, 0.0, 9.0).looking_at(Vec3::ZERO, Vec3::Y))
401        .insert(DepthPrepass)
402        .insert(OcclusionCulling);
403}
examples/3d/reflection_probes.rs (line 112)
105fn spawn_camera(commands: &mut Commands) {
106    commands.spawn((
107        Camera3d::default(),
108        Camera {
109            hdr: true,
110            ..default()
111        },
112        Transform::from_xyz(-6.483, 0.325, 4.381).looking_at(Vec3::ZERO, Vec3::Y),
113    ));
114}
examples/3d/irradiance_volumes.rs (line 237)
234fn spawn_camera(commands: &mut Commands, assets: &ExampleAssets) {
235    commands.spawn((
236        Camera3d::default(),
237        Transform::from_xyz(-10.012, 4.8605, 13.281).looking_at(Vec3::ZERO, Vec3::Y),
238        Skybox {
239            image: assets.skybox.clone(),
240            brightness: 150.0,
241            ..default()
242        },
243    ));
244}
examples/math/render_primitives.rs (line 307)
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}
Source

pub fn looking_to( self, direction: impl TryInto<Dir3>, up: impl TryInto<Dir3>, ) -> Transform

Returns this Transform with a new rotation so that Transform::forward points in the given direction and Transform::up points towards up.

In some cases it’s not possible to construct a rotation. Another axis will be picked in those cases:

  • if direction fails converting to Dir3 (e.g if it is Vec3::ZERO), Dir3::Z is used instead
  • if up fails converting to Dir3, Dir3::Y is used instead
  • if direction is parallel with up, an orthogonal vector is used as the “right” direction
Examples found in repository?
examples/3d/clustered_decals.rs (line 351)
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}
More examples
Hide additional examples
examples/3d/motion_blur.rs (line 72)
53fn setup_scene(
54    asset_server: Res<AssetServer>,
55    mut images: ResMut<Assets<Image>>,
56    mut commands: Commands,
57    mut meshes: ResMut<Assets<Mesh>>,
58    mut materials: ResMut<Assets<StandardMaterial>>,
59) {
60    commands.insert_resource(AmbientLight {
61        color: Color::WHITE,
62        brightness: 300.0,
63        ..default()
64    });
65    commands.insert_resource(CameraMode::Chase);
66    commands.spawn((
67        DirectionalLight {
68            illuminance: 3_000.0,
69            shadows_enabled: true,
70            ..default()
71        },
72        Transform::default().looking_to(Vec3::new(-1.0, -0.7, -1.0), Vec3::X),
73    ));
74    // Sky
75    commands.spawn((
76        Mesh3d(meshes.add(Sphere::default())),
77        MeshMaterial3d(materials.add(StandardMaterial {
78            unlit: true,
79            base_color: Color::linear_rgb(0.1, 0.6, 1.0),
80            ..default()
81        })),
82        Transform::default().with_scale(Vec3::splat(-4000.0)),
83    ));
84    // Ground
85    let mut plane: Mesh = Plane3d::default().into();
86    let uv_size = 4000.0;
87    let uvs = vec![[uv_size, 0.0], [0.0, 0.0], [0.0, uv_size], [uv_size; 2]];
88    plane.insert_attribute(Mesh::ATTRIBUTE_UV_0, uvs);
89    commands.spawn((
90        Mesh3d(meshes.add(plane)),
91        MeshMaterial3d(materials.add(StandardMaterial {
92            base_color: Color::WHITE,
93            perceptual_roughness: 1.0,
94            base_color_texture: Some(images.add(uv_debug_texture())),
95            ..default()
96        })),
97        Transform::from_xyz(0.0, -0.65, 0.0).with_scale(Vec3::splat(80.)),
98    ));
99
100    spawn_cars(&asset_server, &mut meshes, &mut materials, &mut commands);
101    spawn_trees(&mut meshes, &mut materials, &mut commands);
102    spawn_barriers(&mut meshes, &mut materials, &mut commands);
103}
Source

pub fn aligned_by( self, main_axis: impl TryInto<Dir3>, main_direction: impl TryInto<Dir3>, secondary_axis: impl TryInto<Dir3>, secondary_direction: impl TryInto<Dir3>, ) -> Transform

Rotates this Transform so that the main_axis vector, reinterpreted in local coordinates, points in the given main_direction, while secondary_axis points towards secondary_direction. For example, if a spaceship model has its nose pointing in the X-direction in its own local coordinates and its dorsal fin pointing in the Y-direction, then align(Dir3::X, v, Dir3::Y, w) will make the spaceship’s nose point in the direction of v, while the dorsal fin does its best to point in the direction w.

In some cases a rotation cannot be constructed. Another axis will be picked in those cases:

  • if main_axis or main_direction fail converting to Dir3 (e.g are zero), Dir3::X takes their place
  • if secondary_axis or secondary_direction fail converting, Dir3::Y takes their place
  • if main_axis is parallel with secondary_axis or main_direction is parallel with secondary_direction, a rotation is constructed which takes main_axis to main_direction along a great circle, ignoring the secondary counterparts

See Transform::align for additional details.

Examples found in repository?
examples/transforms/align.rs (line 226)
224fn random_axes_target_alignment(random_axes: &RandomAxes) -> Transform {
225    let RandomAxes(first, second) = random_axes;
226    Transform::IDENTITY.aligned_by(Vec3::NEG_Z, *first, Vec3::X, *second)
227}
Source

pub const fn with_translation(self, translation: Vec3) -> Transform

Returns this Transform with a new translation.

Examples found in repository?
examples/ecs/parallel_query.rs (line 21)
10fn spawn_system(mut commands: Commands, asset_server: Res<AssetServer>) {
11    commands.spawn(Camera2d);
12    let texture = asset_server.load("branding/icon.png");
13
14    // We're seeding the PRNG here to make this example deterministic for testing purposes.
15    // This isn't strictly required in practical use unless you need your app to be deterministic.
16    let mut rng = ChaCha8Rng::seed_from_u64(19878367467713);
17    for z in 0..128 {
18        commands.spawn((
19            Sprite::from_image(texture.clone()),
20            Transform::from_scale(Vec3::splat(0.1))
21                .with_translation(Vec2::splat(0.0).extend(z as f32)),
22            Velocity(20.0 * Vec2::new(rng.r#gen::<f32>() - 0.5, rng.r#gen::<f32>() - 0.5)),
23        ));
24    }
25}
More examples
Hide additional examples
examples/3d/pcss.rs (line 192)
179fn spawn_light(commands: &mut Commands, app_status: &AppStatus) {
180    // Because this light can become a directional light, point light, or spot
181    // light depending on the settings, we add the union of the components
182    // necessary for this light to behave as all three of those.
183    commands
184        .spawn((
185            create_directional_light(app_status),
186            Transform::from_rotation(Quat::from_array([
187                0.6539259,
188                -0.34646285,
189                0.36505926,
190                -0.5648683,
191            ]))
192            .with_translation(vec3(57.693, 34.334, -6.422)),
193        ))
194        // These two are needed for point lights.
195        .insert(CubemapVisibleEntities::default())
196        .insert(CubemapFrusta::default())
197        // These two are needed for spot lights.
198        .insert(VisibleMeshEntities::default())
199        .insert(Frustum::default());
200}
examples/3d/fog.rs (line 80)
49fn setup_pyramid_scene(
50    mut commands: Commands,
51    mut meshes: ResMut<Assets<Mesh>>,
52    mut materials: ResMut<Assets<StandardMaterial>>,
53) {
54    let stone = materials.add(StandardMaterial {
55        base_color: Srgba::hex("28221B").unwrap().into(),
56        perceptual_roughness: 1.0,
57        ..default()
58    });
59
60    // pillars
61    for (x, z) in &[(-1.5, -1.5), (1.5, -1.5), (1.5, 1.5), (-1.5, 1.5)] {
62        commands.spawn((
63            Mesh3d(meshes.add(Cuboid::new(1.0, 3.0, 1.0))),
64            MeshMaterial3d(stone.clone()),
65            Transform::from_xyz(*x, 1.5, *z),
66        ));
67    }
68
69    // orb
70    commands.spawn((
71        Mesh3d(meshes.add(Sphere::default())),
72        MeshMaterial3d(materials.add(StandardMaterial {
73            base_color: Srgba::hex("126212CC").unwrap().into(),
74            reflectance: 1.0,
75            perceptual_roughness: 0.0,
76            metallic: 0.5,
77            alpha_mode: AlphaMode::Blend,
78            ..default()
79        })),
80        Transform::from_scale(Vec3::splat(1.75)).with_translation(Vec3::new(0.0, 4.0, 0.0)),
81        NotShadowCaster,
82        NotShadowReceiver,
83    ));
84
85    // steps
86    for i in 0..50 {
87        let half_size = i as f32 / 2.0 + 3.0;
88        let y = -i as f32 / 2.0;
89        commands.spawn((
90            Mesh3d(meshes.add(Cuboid::new(2.0 * half_size, 0.5, 2.0 * half_size))),
91            MeshMaterial3d(stone.clone()),
92            Transform::from_xyz(0.0, y + 0.25, 0.0),
93        ));
94    }
95
96    // sky
97    commands.spawn((
98        Mesh3d(meshes.add(Cuboid::new(2.0, 1.0, 1.0))),
99        MeshMaterial3d(materials.add(StandardMaterial {
100            base_color: Srgba::hex("888888").unwrap().into(),
101            unlit: true,
102            cull_mode: None,
103            ..default()
104        })),
105        Transform::from_scale(Vec3::splat(1_000_000.0)),
106    ));
107
108    // light
109    commands.spawn((
110        PointLight {
111            shadows_enabled: true,
112            ..default()
113        },
114        Transform::from_xyz(0.0, 1.0, 0.0),
115    ));
116}
examples/2d/sprite_animation.rs (line 123)
85fn setup(
86    mut commands: Commands,
87    asset_server: Res<AssetServer>,
88    mut texture_atlas_layouts: ResMut<Assets<TextureAtlasLayout>>,
89) {
90    commands.spawn(Camera2d);
91
92    // Create a minimal UI explaining how to interact with the example
93    commands.spawn((
94        Text::new("Left Arrow: Animate Left Sprite\nRight Arrow: Animate Right Sprite"),
95        Node {
96            position_type: PositionType::Absolute,
97            top: Val::Px(12.0),
98            left: Val::Px(12.0),
99            ..default()
100        },
101    ));
102
103    // Load the sprite sheet using the `AssetServer`
104    let texture = asset_server.load("textures/rpg/chars/gabe/gabe-idle-run.png");
105
106    // The sprite sheet has 7 sprites arranged in a row, and they are all 24px x 24px
107    let layout = TextureAtlasLayout::from_grid(UVec2::splat(24), 7, 1, None, None);
108    let texture_atlas_layout = texture_atlas_layouts.add(layout);
109
110    // The first (left-hand) sprite runs at 10 FPS
111    let animation_config_1 = AnimationConfig::new(1, 6, 10);
112
113    // Create the first (left-hand) sprite
114    commands.spawn((
115        Sprite {
116            image: texture.clone(),
117            texture_atlas: Some(TextureAtlas {
118                layout: texture_atlas_layout.clone(),
119                index: animation_config_1.first_sprite_index,
120            }),
121            ..default()
122        },
123        Transform::from_scale(Vec3::splat(6.0)).with_translation(Vec3::new(-70.0, 0.0, 0.0)),
124        LeftSprite,
125        animation_config_1,
126    ));
127
128    // The second (right-hand) sprite runs at 20 FPS
129    let animation_config_2 = AnimationConfig::new(1, 6, 20);
130
131    // Create the second (right-hand) sprite
132    commands.spawn((
133        Sprite {
134            image: texture.clone(),
135            texture_atlas: Some(TextureAtlas {
136                layout: texture_atlas_layout.clone(),
137                index: animation_config_2.first_sprite_index,
138            }),
139            ..Default::default()
140        },
141        Transform::from_scale(Vec3::splat(6.0)).with_translation(Vec3::new(70.0, 0.0, 0.0)),
142        RightSprite,
143        animation_config_2,
144    ));
145}
examples/3d/irradiance_volumes.rs (line 584)
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/3d/meshlet.rs (line 103)
44fn setup(
45    mut commands: Commands,
46    asset_server: Res<AssetServer>,
47    mut standard_materials: ResMut<Assets<StandardMaterial>>,
48    mut debug_materials: ResMut<Assets<MeshletDebugMaterial>>,
49    mut meshes: ResMut<Assets<Mesh>>,
50) {
51    commands.spawn((
52        Camera3d::default(),
53        Transform::from_translation(Vec3::new(1.8, 0.4, -0.1)).looking_at(Vec3::ZERO, Vec3::Y),
54        Msaa::Off,
55        EnvironmentMapLight {
56            diffuse_map: asset_server.load("environment_maps/pisa_diffuse_rgb9e5_zstd.ktx2"),
57            specular_map: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
58            intensity: 150.0,
59            ..default()
60        },
61        CameraController::default(),
62    ));
63
64    commands.spawn((
65        DirectionalLight {
66            illuminance: light_consts::lux::FULL_DAYLIGHT,
67            shadows_enabled: true,
68            ..default()
69        },
70        CascadeShadowConfigBuilder {
71            num_cascades: 1,
72            maximum_distance: 15.0,
73            ..default()
74        }
75        .build(),
76        Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, PI * -0.15, PI * -0.15)),
77    ));
78
79    // A custom file format storing a [`bevy_render::mesh::Mesh`]
80    // that has been converted to a [`bevy_pbr::meshlet::MeshletMesh`]
81    // using [`bevy_pbr::meshlet::MeshletMesh::from_mesh`], which is
82    // a function only available when the `meshlet_processor` cargo feature is enabled.
83    let meshlet_mesh_handle = asset_server.load("external/models/bunny.meshlet_mesh");
84    let debug_material = debug_materials.add(MeshletDebugMaterial::default());
85
86    for x in -2..=2 {
87        commands.spawn((
88            MeshletMesh3d(meshlet_mesh_handle.clone()),
89            MeshMaterial3d(standard_materials.add(StandardMaterial {
90                base_color: match x {
91                    -2 => Srgba::hex("#dc2626").unwrap().into(),
92                    -1 => Srgba::hex("#ea580c").unwrap().into(),
93                    0 => Srgba::hex("#facc15").unwrap().into(),
94                    1 => Srgba::hex("#16a34a").unwrap().into(),
95                    2 => Srgba::hex("#0284c7").unwrap().into(),
96                    _ => unreachable!(),
97                },
98                perceptual_roughness: (x + 2) as f32 / 4.0,
99                ..default()
100            })),
101            Transform::default()
102                .with_scale(Vec3::splat(0.2))
103                .with_translation(Vec3::new(x as f32 / 2.0, 0.0, -0.3)),
104        ));
105    }
106    for x in -2..=2 {
107        commands.spawn((
108            MeshletMesh3d(meshlet_mesh_handle.clone()),
109            MeshMaterial3d(debug_material.clone()),
110            Transform::default()
111                .with_scale(Vec3::splat(0.2))
112                .with_rotation(Quat::from_rotation_y(PI))
113                .with_translation(Vec3::new(x as f32 / 2.0, 0.0, 0.3)),
114        ));
115    }
116
117    commands.spawn((
118        Mesh3d(meshes.add(Plane3d::default().mesh().size(5.0, 5.0))),
119        MeshMaterial3d(standard_materials.add(StandardMaterial {
120            base_color: Color::WHITE,
121            perceptual_roughness: 1.0,
122            ..default()
123        })),
124    ));
125}
Source

pub const fn with_rotation(self, rotation: Quat) -> Transform

Returns this Transform with a new rotation.

Examples found in repository?
examples/3d/post_processing.rs (line 103)
91fn spawn_scene(commands: &mut Commands, asset_server: &AssetServer) {
92    // Spawn the main scene.
93    commands.spawn(SceneRoot(asset_server.load(
94        GltfAssetLabel::Scene(0).from_asset("models/TonemappingTest/TonemappingTest.gltf"),
95    )));
96
97    // Spawn the flight helmet.
98    commands.spawn((
99        SceneRoot(
100            asset_server
101                .load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
102        ),
103        Transform::from_xyz(0.5, 0.0, -0.5).with_rotation(Quat::from_rotation_y(-0.15 * PI)),
104    ));
105
106    // Spawn the light.
107    commands.spawn((
108        DirectionalLight {
109            illuminance: 15000.0,
110            shadows_enabled: true,
111            ..default()
112        },
113        Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, PI * -0.15, PI * -0.15)),
114        CascadeShadowConfigBuilder {
115            maximum_distance: 3.0,
116            first_cascade_far_bound: 0.9,
117            ..default()
118        }
119        .build(),
120    ));
121}
More examples
Hide additional examples
examples/3d/pcss.rs (lines 156-158)
152fn spawn_camera(commands: &mut Commands, asset_server: &AssetServer) {
153    commands
154        .spawn((
155            Camera3d::default(),
156            Transform::from_xyz(-12.912 * 0.7, 4.466 * 0.7, -10.624 * 0.7).with_rotation(
157                Quat::from_euler(EulerRot::YXZ, -134.76 / 180.0 * PI, -0.175, 0.0),
158            ),
159        ))
160        .insert(ShadowFilteringMethod::Gaussian)
161        // `TemporalJitter` is needed for TAA. Note that it does nothing without
162        // `TemporalAntiAliasSettings`.
163        .insert(TemporalJitter::default())
164        // We want MSAA off for TAA to work properly.
165        .insert(Msaa::Off)
166        // The depth prepass is needed for TAA.
167        .insert(DepthPrepass)
168        // The motion vector prepass is needed for TAA.
169        .insert(MotionVectorPrepass)
170        // Add a nice skybox.
171        .insert(Skybox {
172            image: asset_server.load("environment_maps/sky_skybox.ktx2"),
173            brightness: 500.0,
174            rotation: Quat::IDENTITY,
175        });
176}
examples/3d/color_grading.rs (line 372)
360fn add_basic_scene(commands: &mut Commands, asset_server: &AssetServer) {
361    // Spawn the main scene.
362    commands.spawn(SceneRoot(asset_server.load(
363        GltfAssetLabel::Scene(0).from_asset("models/TonemappingTest/TonemappingTest.gltf"),
364    )));
365
366    // Spawn the flight helmet.
367    commands.spawn((
368        SceneRoot(
369            asset_server
370                .load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
371        ),
372        Transform::from_xyz(0.5, 0.0, -0.5).with_rotation(Quat::from_rotation_y(-0.15 * PI)),
373    ));
374
375    // Spawn the light.
376    commands.spawn((
377        DirectionalLight {
378            illuminance: 15000.0,
379            shadows_enabled: true,
380            ..default()
381        },
382        Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, PI * -0.15, PI * -0.15)),
383        CascadeShadowConfigBuilder {
384            maximum_distance: 3.0,
385            first_cascade_far_bound: 0.9,
386            ..default()
387        }
388        .build(),
389    ));
390}
examples/3d/tonemapping.rs (line 110)
95fn setup_basic_scene(mut commands: Commands, asset_server: Res<AssetServer>) {
96    // Main scene
97    commands.spawn((
98        SceneRoot(asset_server.load(
99            GltfAssetLabel::Scene(0).from_asset("models/TonemappingTest/TonemappingTest.gltf"),
100        )),
101        SceneNumber(1),
102    ));
103
104    // Flight Helmet
105    commands.spawn((
106        SceneRoot(
107            asset_server
108                .load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
109        ),
110        Transform::from_xyz(0.5, 0.0, -0.5).with_rotation(Quat::from_rotation_y(-0.15 * PI)),
111        SceneNumber(1),
112    ));
113
114    // light
115    commands.spawn((
116        DirectionalLight {
117            illuminance: 15_000.,
118            shadows_enabled: true,
119            ..default()
120        },
121        Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, PI * -0.15, PI * -0.15)),
122        CascadeShadowConfigBuilder {
123            maximum_distance: 3.0,
124            first_cascade_far_bound: 0.9,
125            ..default()
126        }
127        .build(),
128        SceneNumber(1),
129    ));
130}
examples/3d/skybox.rs (line 67)
60fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
61    // directional 'sun' light
62    commands.spawn((
63        DirectionalLight {
64            illuminance: 32000.0,
65            ..default()
66        },
67        Transform::from_xyz(0.0, 2.0, 0.0).with_rotation(Quat::from_rotation_x(-PI / 4.)),
68    ));
69
70    let skybox_handle = asset_server.load(CUBEMAPS[0].0);
71    // camera
72    commands.spawn((
73        Camera3d::default(),
74        Transform::from_xyz(0.0, 0.0, 8.0).looking_at(Vec3::ZERO, Vec3::Y),
75        CameraController::default(),
76        Skybox {
77            image: skybox_handle.clone(),
78            brightness: 1000.0,
79            ..default()
80        },
81    ));
82
83    // ambient light
84    // NOTE: The ambient light is used to scale how bright the environment map is so with a bright
85    // environment map, use an appropriate color and brightness to match
86    commands.insert_resource(AmbientLight {
87        color: Color::srgb_u8(210, 220, 240),
88        brightness: 1.0,
89        ..default()
90    });
91
92    commands.insert_resource(Cubemap {
93        is_loaded: false,
94        index: 0,
95        image_handle: skybox_handle,
96    });
97}
examples/3d/mesh_ray_cast.rs (line 85)
74fn setup(
75    mut commands: Commands,
76    mut meshes: ResMut<Assets<Mesh>>,
77    mut materials: ResMut<Assets<StandardMaterial>>,
78) {
79    // Make a box of planes facing inward so the laser gets trapped inside
80    let plane_mesh = meshes.add(Plane3d::default());
81    let plane_material = materials.add(Color::from(css::GRAY).with_alpha(0.01));
82    let create_plane = move |translation, rotation| {
83        (
84            Transform::from_translation(translation)
85                .with_rotation(Quat::from_scaled_axis(rotation)),
86            Mesh3d(plane_mesh.clone()),
87            MeshMaterial3d(plane_material.clone()),
88        )
89    };
90
91    commands.spawn(create_plane(vec3(0.0, 0.5, 0.0), Vec3::X * PI));
92    commands.spawn(create_plane(vec3(0.0, -0.5, 0.0), Vec3::ZERO));
93    commands.spawn(create_plane(vec3(0.5, 0.0, 0.0), Vec3::Z * FRAC_PI_2));
94    commands.spawn(create_plane(vec3(-0.5, 0.0, 0.0), Vec3::Z * -FRAC_PI_2));
95    commands.spawn(create_plane(vec3(0.0, 0.0, 0.5), Vec3::X * -FRAC_PI_2));
96    commands.spawn(create_plane(vec3(0.0, 0.0, -0.5), Vec3::X * FRAC_PI_2));
97
98    // Light
99    commands.spawn((
100        DirectionalLight::default(),
101        Transform::from_rotation(Quat::from_euler(EulerRot::XYZ, -0.1, 0.2, 0.0)),
102    ));
103
104    // Camera
105    commands.spawn((
106        Camera3d::default(),
107        Camera {
108            hdr: true,
109            ..default()
110        },
111        Transform::from_xyz(1.5, 1.5, 1.5).looking_at(Vec3::ZERO, Vec3::Y),
112        Tonemapping::TonyMcMapface,
113        Bloom::default(),
114    ));
115}
Source

pub const fn with_scale(self, scale: Vec3) -> Transform

Returns this Transform with a new scale.

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/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}
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}
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/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/shader/shader_material_2d.rs (line 40)
24fn setup(
25    mut commands: Commands,
26    mut meshes: ResMut<Assets<Mesh>>,
27    mut materials: ResMut<Assets<CustomMaterial>>,
28    asset_server: Res<AssetServer>,
29) {
30    // camera
31    commands.spawn(Camera2d);
32
33    // quad
34    commands.spawn((
35        Mesh2d(meshes.add(Rectangle::default())),
36        MeshMaterial2d(materials.add(CustomMaterial {
37            color: LinearRgba::BLUE,
38            color_texture: Some(asset_server.load("branding/icon.png")),
39        })),
40        Transform::default().with_scale(Vec3::splat(128.)),
41    ));
42}
Source

pub fn compute_matrix(&self) -> Mat4

Returns the 3d affine transformation matrix from this transforms translation, rotation, and scale.

Source

pub fn compute_affine(&self) -> Affine3A

Returns the 3d affine transformation matrix from this transforms translation, rotation, and scale.

Source

pub fn local_x(&self) -> Dir3

Get the unit vector in the local X direction.

Examples found in repository?
examples/transforms/translation.rs (line 68)
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}
Source

pub fn left(&self) -> Dir3

Equivalent to -local_x()

Source

pub fn right(&self) -> Dir3

Equivalent to local_x()

Examples found in repository?
examples/ecs/fallible_params.rs (line 128)
124fn move_targets(mut enemies: Populated<(&mut Transform, &mut Enemy)>, time: Res<Time>) {
125    for (mut transform, mut target) in &mut *enemies {
126        target.rotation += target.rotation_speed * time.delta_secs();
127        transform.rotation = Quat::from_rotation_z(target.rotation);
128        let offset = transform.right() * target.radius;
129        transform.translation = target.origin.extend(0.0) + offset;
130    }
131}
More examples
Hide additional examples
examples/3d/../helpers/camera_controller.rs (line 217)
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 local_y(&self) -> Dir3

Get the unit vector in the local Y direction.

Examples found in repository?
examples/transforms/transform.rs (line 114)
101fn rotate_cube(
102    mut cubes: Query<(&mut Transform, &mut CubeState), Without<Center>>,
103    center_spheres: Query<&Transform, With<Center>>,
104    timer: Res<Time>,
105) {
106    // Calculate the point to circle around. (The position of the center_sphere)
107    let mut center: Vec3 = Vec3::ZERO;
108    for sphere in &center_spheres {
109        center += sphere.translation;
110    }
111    // Update the rotation of the cube(s).
112    for (mut transform, cube) in &mut cubes {
113        // Calculate the rotation of the cube if it would be looking at the sphere in the center.
114        let look_at_sphere = transform.looking_at(center, *transform.local_y());
115        // Interpolate between the current rotation and the fully turned rotation
116        // when looking a the sphere,  with a given turn speed to get a smooth motion.
117        // With higher speed the curvature of the orbit would be smaller.
118        let incremental_turn_weight = cube.turn_speed * timer.delta_secs();
119        let old_rotation = transform.rotation;
120        transform.rotation = old_rotation.lerp(look_at_sphere.rotation, incremental_turn_weight);
121    }
122}
Source

pub fn up(&self) -> Dir3

Equivalent to local_y()

Source

pub fn down(&self) -> Dir3

Equivalent to -local_y()

Source

pub fn local_z(&self) -> Dir3

Get the unit vector in the local Z direction.

Examples found in repository?
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}
Source

pub fn forward(&self) -> Dir3

Equivalent to -local_z()

Examples found in repository?
examples/transforms/transform.rs (line 93)
90fn move_cube(mut cubes: Query<(&mut Transform, &mut CubeState)>, timer: Res<Time>) {
91    for (mut transform, cube) in &mut cubes {
92        // Move the cube forward smoothly at a given move_speed.
93        let forward = transform.forward();
94        transform.translation += forward * cube.move_speed * timer.delta_secs();
95    }
96}
More examples
Hide additional examples
examples/3d/tonemapping.rs (line 139)
132fn setup_color_gradient_scene(
133    mut commands: Commands,
134    mut meshes: ResMut<Assets<Mesh>>,
135    mut materials: ResMut<Assets<ColorGradientMaterial>>,
136    camera_transform: Res<CameraTransform>,
137) {
138    let mut transform = camera_transform.0;
139    transform.translation += *transform.forward();
140
141    commands.spawn((
142        Mesh3d(meshes.add(Rectangle::new(0.7, 0.7))),
143        MeshMaterial3d(materials.add(ColorGradientMaterial {})),
144        transform,
145        Visibility::Hidden,
146        SceneNumber(2),
147    ));
148}
149
150fn setup_image_viewer_scene(
151    mut commands: Commands,
152    mut meshes: ResMut<Assets<Mesh>>,
153    mut materials: ResMut<Assets<StandardMaterial>>,
154    camera_transform: Res<CameraTransform>,
155) {
156    let mut transform = camera_transform.0;
157    transform.translation += *transform.forward();
158
159    // exr/hdr viewer (exr requires enabling bevy feature)
160    commands.spawn((
161        Mesh3d(meshes.add(Rectangle::default())),
162        MeshMaterial3d(materials.add(StandardMaterial {
163            base_color_texture: None,
164            unlit: true,
165            ..default()
166        })),
167        transform,
168        Visibility::Hidden,
169        SceneNumber(3),
170        HDRViewer,
171    ));
172
173    commands.spawn((
174        Text::new("Drag and drop an HDR or EXR file"),
175        TextFont {
176            font_size: 36.0,
177            ..default()
178        },
179        TextColor(Color::BLACK),
180        TextLayout::new_with_justify(JustifyText::Center),
181        Node {
182            align_self: AlignSelf::Center,
183            margin: UiRect::all(Val::Auto),
184            ..default()
185        },
186        SceneNumber(3),
187        Visibility::Hidden,
188    ));
189}
examples/3d/motion_blur.rs (line 347)
330fn move_camera(
331    camera: Single<(&mut Transform, &mut Projection), Without<CameraTracked>>,
332    tracked: Single<&Transform, With<CameraTracked>>,
333    mode: Res<CameraMode>,
334) {
335    let (mut transform, mut projection) = camera.into_inner();
336    match *mode {
337        CameraMode::Track => {
338            transform.look_at(tracked.translation, Vec3::Y);
339            transform.translation = Vec3::new(15.0, -0.5, 0.0);
340            if let Projection::Perspective(perspective) = &mut *projection {
341                perspective.fov = 0.05;
342            }
343        }
344        CameraMode::Chase => {
345            transform.translation =
346                tracked.translation + Vec3::new(0.0, 0.15, 0.0) + tracked.back() * 0.6;
347            transform.look_to(tracked.forward(), Vec3::Y);
348            if let Projection::Perspective(perspective) = &mut *projection {
349                perspective.fov = 1.0;
350            }
351        }
352    }
353}
examples/camera/camera_orbit.rs (line 140)
99fn orbit(
100    mut camera: Single<&mut Transform, With<Camera>>,
101    camera_settings: Res<CameraSettings>,
102    mouse_buttons: Res<ButtonInput<MouseButton>>,
103    mouse_motion: Res<AccumulatedMouseMotion>,
104    time: Res<Time>,
105) {
106    let delta = mouse_motion.delta;
107    let mut delta_roll = 0.0;
108
109    if mouse_buttons.pressed(MouseButton::Left) {
110        delta_roll -= 1.0;
111    }
112    if mouse_buttons.pressed(MouseButton::Right) {
113        delta_roll += 1.0;
114    }
115
116    // Mouse motion is one of the few inputs that should not be multiplied by delta time,
117    // as we are already receiving the full movement since the last frame was rendered. Multiplying
118    // by delta time here would make the movement slower that it should be.
119    let delta_pitch = delta.y * camera_settings.pitch_speed;
120    let delta_yaw = delta.x * camera_settings.yaw_speed;
121
122    // Conversely, we DO need to factor in delta time for mouse button inputs.
123    delta_roll *= camera_settings.roll_speed * time.delta_secs();
124
125    // Obtain the existing pitch, yaw, and roll values from the transform.
126    let (yaw, pitch, roll) = camera.rotation.to_euler(EulerRot::YXZ);
127
128    // Establish the new yaw and pitch, preventing the pitch value from exceeding our limits.
129    let pitch = (pitch + delta_pitch).clamp(
130        camera_settings.pitch_range.start,
131        camera_settings.pitch_range.end,
132    );
133    let roll = roll + delta_roll;
134    let yaw = yaw + delta_yaw;
135    camera.rotation = Quat::from_euler(EulerRot::YXZ, yaw, pitch, roll);
136
137    // Adjust the translation to maintain the correct orientation toward the orbit target.
138    // In our example it's a static target, but this could easily be customized.
139    let target = Vec3::ZERO;
140    camera.translation = target - camera.forward() * camera_settings.orbit_distance;
141}
examples/3d/../helpers/camera_controller.rs (line 216)
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 back(&self) -> Dir3

Equivalent to local_z()

Examples found in repository?
examples/3d/motion_blur.rs (line 346)
330fn move_camera(
331    camera: Single<(&mut Transform, &mut Projection), Without<CameraTracked>>,
332    tracked: Single<&Transform, With<CameraTracked>>,
333    mode: Res<CameraMode>,
334) {
335    let (mut transform, mut projection) = camera.into_inner();
336    match *mode {
337        CameraMode::Track => {
338            transform.look_at(tracked.translation, Vec3::Y);
339            transform.translation = Vec3::new(15.0, -0.5, 0.0);
340            if let Projection::Perspective(perspective) = &mut *projection {
341                perspective.fov = 0.05;
342            }
343        }
344        CameraMode::Chase => {
345            transform.translation =
346                tracked.translation + Vec3::new(0.0, 0.15, 0.0) + tracked.back() * 0.6;
347            transform.look_to(tracked.forward(), Vec3::Y);
348            if let Projection::Perspective(perspective) = &mut *projection {
349                perspective.fov = 1.0;
350            }
351        }
352    }
353}
Source

pub fn rotate(&mut self, rotation: Quat)

Rotates this Transform by the given rotation.

If this Transform has a parent, the rotation is relative to the rotation of the parent.

§Examples
Examples found in repository?
examples/stress_tests/many_animated_sprites.rs (line 104)
103fn move_camera(time: Res<Time>, mut camera_transform: Single<&mut Transform, With<Camera>>) {
104    camera_transform.rotate(Quat::from_rotation_z(time.delta_secs() * 0.5));
105    **camera_transform = **camera_transform
106        * Transform::from_translation(Vec3::X * CAMERA_SPEED * time.delta_secs());
107}
More examples
Hide additional examples
examples/3d/occlusion_culling.rs (lines 375-380)
373fn spin_large_cube(mut large_cubes: Query<&mut Transform, With<LargeCube>>) {
374    for mut transform in &mut large_cubes {
375        transform.rotate(Quat::from_euler(
376            EulerRot::XYZ,
377            0.13 * ROTATION_SPEED,
378            0.29 * ROTATION_SPEED,
379            0.35 * ROTATION_SPEED,
380        ));
381    }
382}
examples/shader/shader_material_wesl.rs (line 89)
75fn update(
76    time: Res<Time>,
77    mut query: Query<(&MeshMaterial3d<CustomMaterial>, &mut Transform)>,
78    mut materials: ResMut<Assets<CustomMaterial>>,
79    keys: Res<ButtonInput<KeyCode>>,
80) {
81    for (material, mut transform) in query.iter_mut() {
82        let material = materials.get_mut(material).unwrap();
83        material.time.x = time.elapsed_secs();
84        if keys.just_pressed(KeyCode::Space) {
85            material.party_mode = !material.party_mode;
86        }
87
88        if material.party_mode {
89            transform.rotate(Quat::from_rotation_y(0.005));
90        }
91    }
92}
examples/3d/transmission.rs (line 613)
600fn flicker_system(
601    mut flame: Single<&mut Transform, (With<Flicker>, With<Mesh3d>)>,
602    light: Single<(&mut PointLight, &mut Transform), (With<Flicker>, Without<Mesh3d>)>,
603    time: Res<Time>,
604) {
605    let s = time.elapsed_secs();
606    let a = ops::cos(s * 6.0) * 0.0125 + ops::cos(s * 4.0) * 0.025;
607    let b = ops::cos(s * 5.0) * 0.0125 + ops::cos(s * 3.0) * 0.025;
608    let c = ops::cos(s * 7.0) * 0.0125 + ops::cos(s * 2.0) * 0.025;
609    let (mut light, mut light_transform) = light.into_inner();
610    light.intensity = 4_000.0 + 3000.0 * (a + b + c);
611    flame.translation = Vec3::new(-1.0, 1.23, 0.0);
612    flame.look_at(Vec3::new(-1.0 - c, 1.7 - b, 0.0 - a), Vec3::X);
613    flame.rotate(Quat::from_euler(EulerRot::XYZ, 0.0, 0.0, PI / 2.0));
614    light_transform.translation = Vec3::new(-1.0 - c, 1.7, 0.0 - a);
615    flame.translation = Vec3::new(-1.0 - c, 1.23, 0.0 - a);
616}
examples/3d/volumetric_fog.rs (line 193)
169fn move_directional_light(
170    input: Res<ButtonInput<KeyCode>>,
171    mut directional_lights: Query<&mut Transform, With<DirectionalLight>>,
172) {
173    let mut delta_theta = Vec2::ZERO;
174    if input.pressed(KeyCode::KeyW) || input.pressed(KeyCode::ArrowUp) {
175        delta_theta.y += DIRECTIONAL_LIGHT_MOVEMENT_SPEED;
176    }
177    if input.pressed(KeyCode::KeyS) || input.pressed(KeyCode::ArrowDown) {
178        delta_theta.y -= DIRECTIONAL_LIGHT_MOVEMENT_SPEED;
179    }
180    if input.pressed(KeyCode::KeyA) || input.pressed(KeyCode::ArrowLeft) {
181        delta_theta.x += DIRECTIONAL_LIGHT_MOVEMENT_SPEED;
182    }
183    if input.pressed(KeyCode::KeyD) || input.pressed(KeyCode::ArrowRight) {
184        delta_theta.x -= DIRECTIONAL_LIGHT_MOVEMENT_SPEED;
185    }
186
187    if delta_theta == Vec2::ZERO {
188        return;
189    }
190
191    let delta_quat = Quat::from_euler(EulerRot::XZY, delta_theta.y, 0.0, delta_theta.x);
192    for mut transform in directional_lights.iter_mut() {
193        transform.rotate(delta_quat);
194    }
195}
Source

pub fn rotate_axis(&mut self, axis: Dir3, angle: f32)

Rotates this Transform around the given axis by angle (in radians).

If this Transform has a parent, the axis is relative to the rotation of the parent.

§Warning

If you pass in an axis based on the current rotation (e.g. obtained via Transform::local_x), floating point errors can accumulate exponentially when applying rotations repeatedly this way. This will result in a denormalized rotation. In this case, it is recommended to normalize the Transform::rotation after each call to this method.

Examples found in repository?
examples/ecs/fallible_params.rs (line 160)
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 rotate_x(&mut self, angle: f32)

Rotates this Transform around the X axis by angle (in radians).

If this Transform has a parent, the axis is relative to the rotation of the parent.

Examples found in repository?
examples/3d/parenting.rs (line 21)
19fn rotator_system(time: Res<Time>, mut query: Query<&mut Transform, With<Rotator>>) {
20    for mut transform in &mut query {
21        transform.rotate_x(3.0 * time.delta_secs());
22    }
23}
More examples
Hide additional examples
examples/3d/atmosphere.rs (line 124)
122fn dynamic_scene(mut suns: Query<&mut Transform, With<DirectionalLight>>, time: Res<Time>) {
123    suns.iter_mut()
124        .for_each(|mut tf| tf.rotate_x(-time.delta_secs() * PI / 10.0));
125}
examples/stress_tests/many_lights.rs (line 141)
138fn move_camera(time: Res<Time>, mut camera_transform: Single<&mut Transform, With<Camera>>) {
139    let delta = time.delta_secs() * 0.15;
140    camera_transform.rotate_z(delta);
141    camera_transform.rotate_x(delta);
142}
examples/shader/custom_post_processing.rs (line 351)
349fn rotate(time: Res<Time>, mut query: Query<&mut Transform, With<Rotates>>) {
350    for mut transform in &mut query {
351        transform.rotate_x(0.55 * time.delta_secs());
352        transform.rotate_z(0.15 * time.delta_secs());
353    }
354}
examples/3d/render_to_texture.rs (line 126)
124fn rotator_system(time: Res<Time>, mut query: Query<&mut Transform, With<FirstPassCube>>) {
125    for mut transform in &mut query {
126        transform.rotate_x(1.5 * time.delta_secs());
127        transform.rotate_z(1.3 * time.delta_secs());
128    }
129}
130
131/// Rotates the outer cube (main pass)
132fn cube_rotator_system(time: Res<Time>, mut query: Query<&mut Transform, With<MainPassCube>>) {
133    for mut transform in &mut query {
134        transform.rotate_x(1.0 * time.delta_secs());
135        transform.rotate_y(0.7 * time.delta_secs());
136    }
137}
examples/picking/mesh_picking.rs (line 196)
193fn rotate_on_drag(drag: Trigger<Pointer<Drag>>, mut transforms: Query<&mut Transform>) {
194    let mut transform = transforms.get_mut(drag.target()).unwrap();
195    transform.rotate_y(drag.delta.x * 0.02);
196    transform.rotate_x(drag.delta.y * 0.02);
197}
Source

pub fn rotate_y(&mut self, angle: f32)

Rotates this Transform around the Y axis by angle (in radians).

If this Transform has a parent, the axis is relative to the rotation of the parent.

Examples found in repository?
examples/shader/extended_material.rs (line 68)
66fn rotate_things(mut q: Query<&mut Transform, With<Rotate>>, time: Res<Time>) {
67    for mut t in &mut q {
68        t.rotate_y(time.delta_secs());
69    }
70}
More examples
Hide additional examples
examples/3d/3d_shapes.rs (line 149)
147fn rotate(mut query: Query<&mut Transform, With<Shape>>, time: Res<Time>) {
148    for mut transform in &mut query {
149        transform.rotate_y(time.delta_secs() / 2.);
150    }
151}
examples/picking/mesh_picking.rs (line 188)
186fn rotate(mut query: Query<&mut Transform, With<Shape>>, time: Res<Time>) {
187    for mut transform in &mut query {
188        transform.rotate_y(time.delta_secs() / 2.);
189    }
190}
191
192/// An observer to rotate an entity when it is dragged
193fn rotate_on_drag(drag: Trigger<Pointer<Drag>>, mut transforms: Query<&mut Transform>) {
194    let mut transform = transforms.get_mut(drag.target()).unwrap();
195    transform.rotate_y(drag.delta.x * 0.02);
196    transform.rotate_x(drag.delta.y * 0.02);
197}
examples/3d/occlusion_culling.rs (line 365)
363fn spin_small_cubes(mut sphere_parents: Query<&mut Transform, With<SphereParent>>) {
364    for mut sphere_parent_transform in &mut sphere_parents {
365        sphere_parent_transform.rotate_y(ROTATION_SPEED);
366    }
367}
examples/3d/skybox.rs (line 175)
170fn animate_light_direction(
171    time: Res<Time>,
172    mut query: Query<&mut Transform, With<DirectionalLight>>,
173) {
174    for mut transform in &mut query {
175        transform.rotate_y(time.delta_secs() * 0.5);
176    }
177}
examples/math/custom_primitives.rs (line 216)
212fn rotate_3d_shapes(mut shapes: Query<&mut Transform, With<Shape3d>>, time: Res<Time>) {
213    let delta_seconds = time.delta_secs();
214
215    for mut transform in shapes.iter_mut() {
216        transform.rotate_y(delta_seconds);
217    }
218}
Source

pub fn rotate_z(&mut self, angle: f32)

Rotates this Transform around the Z axis by angle (in radians).

If this Transform has a parent, the axis is relative to the rotation of the parent.

Examples found in repository?
examples/2d/pixel_grid_snap.rs (line 142)
139fn rotate(time: Res<Time>, mut transforms: Query<&mut Transform, With<Rotate>>) {
140    for mut transform in &mut transforms {
141        let dt = time.delta_secs();
142        transform.rotate_z(dt);
143    }
144}
More examples
Hide additional examples
examples/stress_tests/many_lights.rs (line 140)
138fn move_camera(time: Res<Time>, mut camera_transform: Single<&mut Transform, With<Camera>>) {
139    let delta = time.delta_secs() * 0.15;
140    camera_transform.rotate_z(delta);
141    camera_transform.rotate_x(delta);
142}
examples/shader/custom_post_processing.rs (line 352)
349fn rotate(time: Res<Time>, mut query: Query<&mut Transform, With<Rotates>>) {
350    for mut transform in &mut query {
351        transform.rotate_x(0.55 * time.delta_secs());
352        transform.rotate_z(0.15 * time.delta_secs());
353    }
354}
examples/3d/render_to_texture.rs (line 127)
124fn rotator_system(time: Res<Time>, mut query: Query<&mut Transform, With<FirstPassCube>>) {
125    for mut transform in &mut query {
126        transform.rotate_x(1.5 * time.delta_secs());
127        transform.rotate_z(1.3 * time.delta_secs());
128    }
129}
examples/stress_tests/many_sprites.rs (line 108)
107fn move_camera(time: Res<Time>, mut camera_transform: Single<&mut Transform, With<Camera>>) {
108    camera_transform.rotate_z(time.delta_secs() * 0.5);
109    **camera_transform = **camera_transform
110        * Transform::from_translation(Vec3::X * CAMERA_SPEED * time.delta_secs());
111}
examples/games/contributors.rs (line 310)
305fn movement(time: Res<Time>, mut query: Query<(&Velocity, &mut Transform)>) {
306    let delta = time.delta_secs();
307
308    for (velocity, mut transform) in &mut query {
309        transform.translation += delta * velocity.translation;
310        transform.rotate_z(velocity.rotation * delta);
311    }
312}
Source

pub fn rotate_local(&mut self, rotation: Quat)

Rotates this Transform by the given rotation.

The rotation is relative to this Transform’s current rotation.

Source

pub fn rotate_local_axis(&mut self, axis: Dir3, angle: f32)

Rotates this Transform around its local axis by angle (in radians).

§Warning

If you pass in an axis based on the current rotation (e.g. obtained via Transform::local_x), floating point errors can accumulate exponentially when applying rotations repeatedly this way. This will result in a denormalized rotation. In this case, it is recommended to normalize the Transform::rotation after each call to this method.

Source

pub fn rotate_local_x(&mut self, angle: f32)

Rotates this Transform around its local X axis by angle (in radians).

Examples found in repository?
examples/3d/parallax_mapping.rs (line 156)
153fn spin(time: Res<Time>, mut query: Query<(&mut Transform, &Spin)>) {
154    for (mut transform, spin) in query.iter_mut() {
155        transform.rotate_local_y(spin.speed * time.delta_secs());
156        transform.rotate_local_x(spin.speed * time.delta_secs());
157        transform.rotate_local_z(-spin.speed * time.delta_secs());
158    }
159}
More examples
Hide additional examples
examples/3d/deferred_rendering.rs (line 270)
264fn spin(time: Res<Time>, mut query: Query<(&mut Transform, &Spin)>, pause: Res<Pause>) {
265    if pause.0 {
266        return;
267    }
268    for (mut transform, spin) in query.iter_mut() {
269        transform.rotate_local_y(spin.speed * time.delta_secs());
270        transform.rotate_local_x(spin.speed * time.delta_secs());
271        transform.rotate_local_z(-spin.speed * time.delta_secs());
272    }
273}
Source

pub fn rotate_local_y(&mut self, angle: f32)

Rotates this Transform around its local Y axis by angle (in radians).

Examples found in repository?
examples/window/low_power.rs (line 140)
134    pub(crate) fn rotate_cube(
135        time: Res<Time>,
136        mut cube_transform: Query<&mut Transform, With<Rotator>>,
137    ) {
138        for mut transform in &mut cube_transform {
139            transform.rotate_x(time.delta_secs());
140            transform.rotate_local_y(time.delta_secs());
141        }
142    }
More examples
Hide additional examples
examples/3d/parallax_mapping.rs (line 155)
153fn spin(time: Res<Time>, mut query: Query<(&mut Transform, &Spin)>) {
154    for (mut transform, spin) in query.iter_mut() {
155        transform.rotate_local_y(spin.speed * time.delta_secs());
156        transform.rotate_local_x(spin.speed * time.delta_secs());
157        transform.rotate_local_z(-spin.speed * time.delta_secs());
158    }
159}
examples/3d/deferred_rendering.rs (line 269)
264fn spin(time: Res<Time>, mut query: Query<(&mut Transform, &Spin)>, pause: Res<Pause>) {
265    if pause.0 {
266        return;
267    }
268    for (mut transform, spin) in query.iter_mut() {
269        transform.rotate_local_y(spin.speed * time.delta_secs());
270        transform.rotate_local_x(spin.speed * time.delta_secs());
271        transform.rotate_local_z(-spin.speed * time.delta_secs());
272    }
273}
examples/3d/motion_blur.rs (line 325)
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}
Source

pub fn rotate_local_z(&mut self, angle: f32)

Rotates this Transform around its local Z axis by angle (in radians).

Examples found in repository?
examples/3d/parallax_mapping.rs (line 157)
153fn spin(time: Res<Time>, mut query: Query<(&mut Transform, &Spin)>) {
154    for (mut transform, spin) in query.iter_mut() {
155        transform.rotate_local_y(spin.speed * time.delta_secs());
156        transform.rotate_local_x(spin.speed * time.delta_secs());
157        transform.rotate_local_z(-spin.speed * time.delta_secs());
158    }
159}
More examples
Hide additional examples
examples/3d/deferred_rendering.rs (line 271)
264fn spin(time: Res<Time>, mut query: Query<(&mut Transform, &Spin)>, pause: Res<Pause>) {
265    if pause.0 {
266        return;
267    }
268    for (mut transform, spin) in query.iter_mut() {
269        transform.rotate_local_y(spin.speed * time.delta_secs());
270        transform.rotate_local_x(spin.speed * time.delta_secs());
271        transform.rotate_local_z(-spin.speed * time.delta_secs());
272    }
273}
Source

pub fn translate_around(&mut self, point: Vec3, rotation: Quat)

Translates this Transform around a point in space.

If this Transform has a parent, the point is relative to the Transform of the parent.

Examples found in repository?
examples/3d/ssr.rs (line 334)
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 rotate_around(&mut self, point: Vec3, rotation: Quat)

Rotates this Transform around a point in space.

If this Transform has a parent, the point is relative to the Transform of the parent.

Examples found in repository?
examples/gizmos/light_gizmos.rs (line 140)
139fn rotate_camera(mut transform: Single<&mut Transform, With<Camera>>, time: Res<Time>) {
140    transform.rotate_around(Vec3::ZERO, Quat::from_rotation_y(time.delta_secs() / 2.));
141}
More examples
Hide additional examples
examples/stress_tests/many_cameras_lights.rs (line 91)
89fn rotate_cameras(time: Res<Time>, mut query: Query<&mut Transform, With<Camera>>) {
90    for mut transform in query.iter_mut() {
91        transform.rotate_around(Vec3::ZERO, Quat::from_rotation_y(time.delta_secs()));
92    }
93}
examples/shader/shader_material_screenspace_texture.rs (lines 55-58)
54fn rotate_camera(mut cam_transform: Single<&mut Transform, With<MainCamera>>, time: Res<Time>) {
55    cam_transform.rotate_around(
56        Vec3::ZERO,
57        Quat::from_axis_angle(Vec3::Y, 45f32.to_radians() * time.delta_secs()),
58    );
59    cam_transform.look_at(Vec3::ZERO, Vec3::Y);
60}
examples/3d/spotlight.rs (line 199)
191fn rotation(
192    mut transform: Single<&mut Transform, With<Camera>>,
193    input: Res<ButtonInput<KeyCode>>,
194    time: Res<Time>,
195) {
196    let delta = time.delta_secs();
197
198    if input.pressed(KeyCode::ArrowLeft) {
199        transform.rotate_around(Vec3::ZERO, Quat::from_rotation_y(delta));
200    } else if input.pressed(KeyCode::ArrowRight) {
201        transform.rotate_around(Vec3::ZERO, Quat::from_rotation_y(-delta));
202    }
203}
examples/transforms/align.rs (line 211)
191fn handle_mouse(
192    accumulated_mouse_motion: Res<AccumulatedMouseMotion>,
193    mut button_events: EventReader<MouseButtonInput>,
194    mut camera_transform: Single<&mut Transform, With<Camera>>,
195    mut mouse_pressed: ResMut<MousePressed>,
196) {
197    // Store left-pressed state in the MousePressed resource
198    for button_event in button_events.read() {
199        if button_event.button != MouseButton::Left {
200            continue;
201        }
202        *mouse_pressed = MousePressed(button_event.state.is_pressed());
203    }
204
205    // If the mouse is not pressed, just ignore motion events
206    if !mouse_pressed.0 {
207        return;
208    }
209    if accumulated_mouse_motion.delta != Vec2::ZERO {
210        let displacement = accumulated_mouse_motion.delta.x;
211        camera_transform.rotate_around(Vec3::ZERO, Quat::from_rotation_y(-displacement / 75.));
212    }
213}
examples/math/random_sampling.rs (line 241)
221fn handle_mouse(
222    accumulated_mouse_motion: Res<AccumulatedMouseMotion>,
223    mut button_events: EventReader<MouseButtonInput>,
224    mut camera_transform: Single<&mut Transform, With<Camera>>,
225    mut mouse_pressed: ResMut<MousePressed>,
226) {
227    // Store left-pressed state in the MousePressed resource
228    for button_event in button_events.read() {
229        if button_event.button != MouseButton::Left {
230            continue;
231        }
232        *mouse_pressed = MousePressed(button_event.state.is_pressed());
233    }
234
235    // If the mouse is not pressed, just ignore motion events
236    if !mouse_pressed.0 {
237        return;
238    }
239    if accumulated_mouse_motion.delta != Vec2::ZERO {
240        let displacement = accumulated_mouse_motion.delta.x;
241        camera_transform.rotate_around(Vec3::ZERO, Quat::from_rotation_y(-displacement / 150.));
242    }
243}
Source

pub fn look_at(&mut self, target: Vec3, up: impl TryInto<Dir3>)

Rotates this Transform so that Transform::forward points towards the target position, and Transform::up points towards up.

In some cases it’s not possible to construct a rotation. Another axis will be picked in those cases:

  • if target is the same as the transform translation, Vec3::Z is used instead
  • if up fails converting to Dir3 (e.g if it is Vec3::ZERO), Dir3::Y is used instead
  • if the resulting forward direction is parallel with up, an orthogonal vector is used as the “right” direction
Examples found in repository?
examples/shader/shader_material_screenspace_texture.rs (line 59)
54fn rotate_camera(mut cam_transform: Single<&mut Transform, With<MainCamera>>, time: Res<Time>) {
55    cam_transform.rotate_around(
56        Vec3::ZERO,
57        Quat::from_axis_angle(Vec3::Y, 45f32.to_radians() * time.delta_secs()),
58    );
59    cam_transform.look_at(Vec3::ZERO, Vec3::Y);
60}
More examples
Hide additional examples
examples/3d/specular_tint.rs (line 142)
138fn rotate_camera(mut cameras: Query<&mut Transform, With<Camera3d>>) {
139    for mut camera_transform in cameras.iter_mut() {
140        camera_transform.translation =
141            Quat::from_rotation_y(ROTATION_SPEED) * camera_transform.translation;
142        camera_transform.look_at(Vec3::ZERO, Vec3::Y);
143    }
144}
examples/3d/anisotropy.rs (line 187)
180fn animate_light(
181    mut lights: Query<&mut Transform, Or<(With<DirectionalLight>, With<PointLight>)>>,
182    time: Res<Time>,
183) {
184    let now = time.elapsed_secs();
185    for mut transform in lights.iter_mut() {
186        transform.translation = vec3(ops::cos(now), 1.0, ops::sin(now)) * vec3(3.0, 4.0, 3.0);
187        transform.look_at(Vec3::ZERO, Vec3::Y);
188    }
189}
examples/math/sampling_primitives.rs (line 673)
668fn update_camera(mut camera: Query<(&mut Transform, &CameraRig), Changed<CameraRig>>) {
669    for (mut transform, rig) in camera.iter_mut() {
670        let looking_direction =
671            Quat::from_rotation_y(-rig.yaw) * Quat::from_rotation_x(rig.pitch) * Vec3::Z;
672        transform.translation = rig.target - rig.distance * looking_direction;
673        transform.look_at(rig.target, Dir3::Y);
674    }
675}
examples/3d/clearcoat.rs (line 243)
232fn animate_light(
233    mut lights: Query<&mut Transform, Or<(With<PointLight>, With<DirectionalLight>)>>,
234    time: Res<Time>,
235) {
236    let now = time.elapsed_secs();
237    for mut transform in lights.iter_mut() {
238        transform.translation = vec3(
239            ops::sin(now * 1.4),
240            ops::cos(now * 1.0),
241            ops::cos(now * 0.6),
242        ) * vec3(3.0, 4.0, 3.0);
243        transform.look_at(Vec3::ZERO, Vec3::Y);
244    }
245}
examples/3d/reflection_probes.rs (line 310)
296fn rotate_camera(
297    time: Res<Time>,
298    mut camera_query: Query<&mut Transform, With<Camera3d>>,
299    app_status: Res<AppStatus>,
300) {
301    if !app_status.rotating {
302        return;
303    }
304
305    for mut transform in camera_query.iter_mut() {
306        transform.translation = Vec2::from_angle(time.delta_secs() * PI / 5.0)
307            .rotate(transform.translation.xz())
308            .extend(transform.translation.y)
309            .xzy();
310        transform.look_at(Vec3::ZERO, Vec3::Y);
311    }
312}
Source

pub fn look_to(&mut self, direction: impl TryInto<Dir3>, up: impl TryInto<Dir3>)

Rotates this Transform so that Transform::forward points in the given direction and Transform::up points towards up.

In some cases it’s not possible to construct a rotation. Another axis will be picked in those cases:

  • if direction fails converting to Dir3 (e.g if it is Vec3::ZERO), Dir3::NEG_Z is used instead
  • if up fails converting to Dir3, Dir3::Y is used instead
  • if direction is parallel with up, an orthogonal vector is used as the “right” direction
Examples found in repository?
examples/3d/generate_custom_mesh.rs (line 102)
73fn input_handler(
74    keyboard_input: Res<ButtonInput<KeyCode>>,
75    mesh_query: Query<&Mesh3d, With<CustomUV>>,
76    mut meshes: ResMut<Assets<Mesh>>,
77    mut query: Query<&mut Transform, With<CustomUV>>,
78    time: Res<Time>,
79) {
80    if keyboard_input.just_pressed(KeyCode::Space) {
81        let mesh_handle = mesh_query.single().expect("Query not successful");
82        let mesh = meshes.get_mut(mesh_handle).unwrap();
83        toggle_texture(mesh);
84    }
85    if keyboard_input.pressed(KeyCode::KeyX) {
86        for mut transform in &mut query {
87            transform.rotate_x(time.delta_secs() / 1.2);
88        }
89    }
90    if keyboard_input.pressed(KeyCode::KeyY) {
91        for mut transform in &mut query {
92            transform.rotate_y(time.delta_secs() / 1.2);
93        }
94    }
95    if keyboard_input.pressed(KeyCode::KeyZ) {
96        for mut transform in &mut query {
97            transform.rotate_z(time.delta_secs() / 1.2);
98        }
99    }
100    if keyboard_input.pressed(KeyCode::KeyR) {
101        for mut transform in &mut query {
102            transform.look_to(Vec3::NEG_Z, Vec3::Y);
103        }
104    }
105}
More examples
Hide additional examples
examples/3d/motion_blur.rs (line 317)
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}
329
330fn move_camera(
331    camera: Single<(&mut Transform, &mut Projection), Without<CameraTracked>>,
332    tracked: Single<&Transform, With<CameraTracked>>,
333    mode: Res<CameraMode>,
334) {
335    let (mut transform, mut projection) = camera.into_inner();
336    match *mode {
337        CameraMode::Track => {
338            transform.look_at(tracked.translation, Vec3::Y);
339            transform.translation = Vec3::new(15.0, -0.5, 0.0);
340            if let Projection::Perspective(perspective) = &mut *projection {
341                perspective.fov = 0.05;
342            }
343        }
344        CameraMode::Chase => {
345            transform.translation =
346                tracked.translation + Vec3::new(0.0, 0.15, 0.0) + tracked.back() * 0.6;
347            transform.look_to(tracked.forward(), Vec3::Y);
348            if let Projection::Perspective(perspective) = &mut *projection {
349                perspective.fov = 1.0;
350            }
351        }
352    }
353}
Source

pub fn align( &mut self, main_axis: impl TryInto<Dir3>, main_direction: impl TryInto<Dir3>, secondary_axis: impl TryInto<Dir3>, secondary_direction: impl TryInto<Dir3>, )

Rotates this Transform so that the main_axis vector, reinterpreted in local coordinates, points in the given main_direction, while secondary_axis points towards secondary_direction.

For example, if a spaceship model has its nose pointing in the X-direction in its own local coordinates and its dorsal fin pointing in the Y-direction, then align(Dir3::X, v, Dir3::Y, w) will make the spaceship’s nose point in the direction of v, while the dorsal fin does its best to point in the direction w.

More precisely, the Transform::rotation produced will be such that:

  • applying it to main_axis results in main_direction
  • applying it to secondary_axis produces a vector that lies in the half-plane generated by main_direction and secondary_direction (with positive contribution by secondary_direction)

Transform::look_to is recovered, for instance, when main_axis is Dir3::NEG_Z (the Transform::forward direction in the default orientation) and secondary_axis is Dir3::Y (the Transform::up direction in the default orientation). (Failure cases may differ somewhat.)

In some cases a rotation cannot be constructed. Another axis will be picked in those cases:

  • if main_axis or main_direction fail converting to Dir3 (e.g are zero), Dir3::X takes their place
  • if secondary_axis or secondary_direction fail converting, Dir3::Y takes their place
  • if main_axis is parallel with secondary_axis or main_direction is parallel with secondary_direction, a rotation is constructed which takes main_axis to main_direction along a great circle, ignoring the secondary counterparts

Example

t1.align(Dir3::X, Dir3::Y, Vec3::new(1., 1., 0.), Dir3::Z);
let main_axis_image = t1.rotation * Dir3::X;
let secondary_axis_image = t1.rotation * Vec3::new(1., 1., 0.);
assert!(main_axis_image.abs_diff_eq(Vec3::Y, 1e-5));
assert!(secondary_axis_image.abs_diff_eq(Vec3::new(0., 1., 1.), 1e-5));

t1.align(Vec3::ZERO, Dir3::Z, Vec3::ZERO, Dir3::X);
t2.align(Dir3::X, Dir3::Z, Dir3::Y, Dir3::X);
assert_eq!(t1.rotation, t2.rotation);

t1.align(Dir3::X, Dir3::Z, Dir3::X, Dir3::Y);
assert_eq!(t1.rotation, Quat::from_rotation_arc(Vec3::X, Vec3::Z));
Source

pub fn mul_transform(&self, transform: Transform) -> Transform

Multiplies self with transform component by component, returning the resulting Transform

Examples found in repository?
examples/stress_tests/many_cubes.rs (line 178)
137fn setup(
138    mut commands: Commands,
139    args: Res<Args>,
140    mesh_assets: ResMut<Assets<Mesh>>,
141    material_assets: ResMut<Assets<StandardMaterial>>,
142    images: ResMut<Assets<Image>>,
143) {
144    warn!(include_str!("warning_string.txt"));
145
146    let args = args.into_inner();
147    let images = images.into_inner();
148    let material_assets = material_assets.into_inner();
149    let mesh_assets = mesh_assets.into_inner();
150
151    let meshes = init_meshes(args, mesh_assets);
152
153    let material_textures = init_textures(args, images);
154    let materials = init_materials(args, &material_textures, material_assets);
155
156    // We're seeding the PRNG here to make this example deterministic for testing purposes.
157    // This isn't strictly required in practical use unless you need your app to be deterministic.
158    let mut material_rng = ChaCha8Rng::seed_from_u64(42);
159    match args.layout {
160        Layout::Sphere => {
161            // NOTE: This pattern is good for testing performance of culling as it provides roughly
162            // the same number of visible meshes regardless of the viewing angle.
163            const N_POINTS: usize = WIDTH * HEIGHT * 4;
164            // NOTE: f64 is used to avoid precision issues that produce visual artifacts in the distribution
165            let radius = WIDTH as f64 * 2.5;
166            let golden_ratio = 0.5f64 * (1.0f64 + 5.0f64.sqrt());
167            for i in 0..N_POINTS {
168                let spherical_polar_theta_phi =
169                    fibonacci_spiral_on_sphere(golden_ratio, i, N_POINTS);
170                let unit_sphere_p = spherical_polar_to_cartesian(spherical_polar_theta_phi);
171                let (mesh, transform) = meshes.choose(&mut material_rng).unwrap();
172                commands
173                    .spawn((
174                        Mesh3d(mesh.clone()),
175                        MeshMaterial3d(materials.choose(&mut material_rng).unwrap().clone()),
176                        Transform::from_translation((radius * unit_sphere_p).as_vec3())
177                            .looking_at(Vec3::ZERO, Vec3::Y)
178                            .mul_transform(*transform),
179                    ))
180                    .insert_if(NoFrustumCulling, || args.no_frustum_culling)
181                    .insert_if(NoAutomaticBatching, || args.no_automatic_batching);
182            }
183
184            // camera
185            let mut camera = commands.spawn(Camera3d::default());
186            if args.no_indirect_drawing {
187                camera.insert(NoIndirectDrawing);
188            }
189            if args.no_cpu_culling {
190                camera.insert(NoCpuCulling);
191            }
192
193            // Inside-out box around the meshes onto which shadows are cast (though you cannot see them...)
194            commands.spawn((
195                Mesh3d(mesh_assets.add(Cuboid::from_size(Vec3::splat(radius as f32 * 2.2)))),
196                MeshMaterial3d(material_assets.add(StandardMaterial::from(Color::WHITE))),
197                Transform::from_scale(-Vec3::ONE),
198                NotShadowCaster,
199            ));
200        }
201        _ => {
202            // NOTE: This pattern is good for demonstrating that frustum culling is working correctly
203            // as the number of visible meshes rises and falls depending on the viewing angle.
204            let scale = 2.5;
205            for x in 0..WIDTH {
206                for y in 0..HEIGHT {
207                    // introduce spaces to break any kind of moiré pattern
208                    if x % 10 == 0 || y % 10 == 0 {
209                        continue;
210                    }
211                    // cube
212                    commands.spawn((
213                        Mesh3d(meshes.choose(&mut material_rng).unwrap().0.clone()),
214                        MeshMaterial3d(materials.choose(&mut material_rng).unwrap().clone()),
215                        Transform::from_xyz((x as f32) * scale, (y as f32) * scale, 0.0),
216                    ));
217                    commands.spawn((
218                        Mesh3d(meshes.choose(&mut material_rng).unwrap().0.clone()),
219                        MeshMaterial3d(materials.choose(&mut material_rng).unwrap().clone()),
220                        Transform::from_xyz(
221                            (x as f32) * scale,
222                            HEIGHT as f32 * scale,
223                            (y as f32) * scale,
224                        ),
225                    ));
226                    commands.spawn((
227                        Mesh3d(meshes.choose(&mut material_rng).unwrap().0.clone()),
228                        MeshMaterial3d(materials.choose(&mut material_rng).unwrap().clone()),
229                        Transform::from_xyz((x as f32) * scale, 0.0, (y as f32) * scale),
230                    ));
231                    commands.spawn((
232                        Mesh3d(meshes.choose(&mut material_rng).unwrap().0.clone()),
233                        MeshMaterial3d(materials.choose(&mut material_rng).unwrap().clone()),
234                        Transform::from_xyz(0.0, (x as f32) * scale, (y as f32) * scale),
235                    ));
236                }
237            }
238            // camera
239            let center = 0.5 * scale * Vec3::new(WIDTH as f32, HEIGHT as f32, WIDTH as f32);
240            commands.spawn((Camera3d::default(), Transform::from_translation(center)));
241            // Inside-out box around the meshes onto which shadows are cast (though you cannot see them...)
242            commands.spawn((
243                Mesh3d(mesh_assets.add(Cuboid::from_size(2.0 * 1.1 * center))),
244                MeshMaterial3d(material_assets.add(StandardMaterial::from(Color::WHITE))),
245                Transform::from_scale(-Vec3::ONE).with_translation(center),
246                NotShadowCaster,
247            ));
248        }
249    }
250
251    commands.spawn((
252        DirectionalLight {
253            shadows_enabled: args.shadows,
254            ..default()
255        },
256        Transform::IDENTITY.looking_at(Vec3::new(0.0, -1.0, -1.0), Vec3::Y),
257    ));
258}
Source

pub fn transform_point(&self, point: Vec3) -> Vec3

Transforms the given point, applying scale, rotation and translation.

If this Transform has an ancestor entity with a Transform component, Transform::transform_point will transform a point in local space into its parent transform’s space.

If this Transform does not have a parent, Transform::transform_point will transform a point in local space into worldspace coordinates.

If you always want to transform a point in local space to worldspace, or if you need the inverse transformations, see GlobalTransform::transform_point().

Source

pub fn is_finite(&self) -> bool

Returns true if, and only if, translation, rotation and scale all are finite. If any of them contains a NaN, positive or negative infinity, this will return false.

Source

pub fn to_isometry(&self) -> Isometry3d

Get the isometry defined by this transform’s rotation and translation, ignoring scale.

Examples found in repository?
examples/math/custom_primitives.rs (line 231)
221fn bounding_shapes_3d(
222    shapes: Query<&Transform, With<Shape3d>>,
223    mut gizmos: Gizmos,
224    bounding_shape: Res<State<BoundingShape>>,
225) {
226    for transform in shapes.iter() {
227        match bounding_shape.get() {
228            BoundingShape::None => (),
229            BoundingShape::BoundingBox => {
230                // Get the AABB of the extrusion with the rotation and translation of the mesh.
231                let aabb = EXTRUSION.aabb_3d(transform.to_isometry());
232
233                gizmos.primitive_3d(
234                    &Cuboid::from_size(Vec3::from(aabb.half_size()) * 2.),
235                    aabb.center(),
236                    WHITE,
237                );
238            }
239            BoundingShape::BoundingSphere => {
240                // Get the bounding sphere of the extrusion with the rotation and translation of the mesh.
241                let bounding_sphere = EXTRUSION.bounding_sphere(transform.to_isometry());
242
243                gizmos.sphere(bounding_sphere.center(), bounding_sphere.radius(), WHITE);
244            }
245        }
246    }
247}

Trait Implementations§

Source§

impl Animatable for Transform

Source§

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

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

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

Blends one or more values together. Read more
Source§

impl Clone for Transform

Source§

fn clone(&self) -> Transform

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 Component for Transform
where Transform: Send + Sync + 'static,

Required Components: GlobalTransform, TransformTreeChanged.

A component’s Required Components are inserted whenever it is inserted. Note that this will also insert the required components of the required components, recursively, in depth-first order.

Source§

const STORAGE_TYPE: StorageType = bevy_ecs::component::StorageType::Table

A constant indicating the storage type used for this component.
Source§

type Mutability = Mutable

A marker type to assist Bevy with determining if this component is mutable, or immutable. Mutable components will have [Component<Mutability = Mutable>], while immutable components will instead have [Component<Mutability = Immutable>]. Read more
Source§

fn register_required_components( requiree: ComponentId, components: &mut ComponentsRegistrator<'_>, required_components: &mut RequiredComponents, inheritance_depth: u16, recursion_check_stack: &mut Vec<ComponentId>, )

Registers required components.
Source§

fn clone_behavior() -> ComponentCloneBehavior

Called when registering this component, allowing to override clone function (or disable cloning altogether) for this component. Read more
Source§

fn register_component_hooks(hooks: &mut ComponentHooks)

👎Deprecated since 0.16.0: Use the individual hook methods instead (e.g., Component::on_add, etc.)
Called when registering this component, allowing mutable access to its ComponentHooks.
Source§

fn on_add() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>

Gets the on_add ComponentHook for this Component if one is defined.
Source§

fn on_insert() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>

Gets the on_insert ComponentHook for this Component if one is defined.
Source§

fn on_replace() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>

Gets the on_replace ComponentHook for this Component if one is defined.
Source§

fn on_remove() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>

Gets the on_remove ComponentHook for this Component if one is defined.
Source§

fn on_despawn() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>

Gets the on_despawn ComponentHook for this Component if one is defined.
Source§

fn map_entities<E>(_this: &mut Self, _mapper: &mut E)
where E: EntityMapper,

Maps the entities on this component using the given EntityMapper. This is used to remap entities in contexts like scenes and entity cloning. When deriving Component, this is populated by annotating fields containing entities with #[entities] Read more
Source§

impl Debug for Transform

Source§

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

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

impl Default for Transform

Source§

fn default() -> Transform

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

impl<'de> Deserialize<'de> for Transform

Source§

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

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

impl From<GlobalTransform> for Transform

The transform is expected to be non-degenerate and without shearing, or the output will be invalid.

Source§

fn from(transform: GlobalTransform) -> Transform

Converts to this type from the input type.
Source§

impl From<Transform> for GlobalTransform

Source§

fn from(transform: Transform) -> GlobalTransform

Converts to this type from the input type.
Source§

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

Source§

type This<'from_arg> = &'from_arg Transform

The type to convert into. Read more
Source§

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

Creates an item from an argument. Read more
Source§

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

Source§

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

The type to convert into. Read more
Source§

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

Creates an item from an argument. Read more
Source§

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

Source§

type This<'from_arg> = Transform

The type to convert into. Read more
Source§

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

Creates an item from an argument. Read more
Source§

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

Source§

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

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 GetOwnership for &Transform
where Transform: Any + Send + Sync, Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

fn ownership() -> Ownership

Returns the ownership of Self.
Source§

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

Source§

fn ownership() -> Ownership

Returns the ownership of Self.
Source§

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

Source§

fn ownership() -> Ownership

Returns the ownership of Self.
Source§

impl GetTypeRegistration for Transform
where Transform: Any + Send + Sync, Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Quat: 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 IntoReturn for &Transform
where Transform: Any + Send + Sync, Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

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

Converts Self into a Return value.
Source§

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

Source§

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

Converts Self into a Return value.
Source§

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

Source§

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

Converts Self into a Return value.
Source§

impl Mul<GlobalTransform> for Transform

Source§

type Output = GlobalTransform

The resulting type after applying the * operator.
Source§

fn mul( self, global_transform: GlobalTransform, ) -> <Transform as Mul<GlobalTransform>>::Output

Performs the * operation. Read more
Source§

impl Mul<Mesh> for Transform

Source§

type Output = Mesh

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: Mesh) -> <Transform as Mul<Mesh>>::Output

Performs the * operation. Read more
Source§

impl Mul<Transform> for GlobalTransform

Source§

type Output = GlobalTransform

The resulting type after applying the * operator.
Source§

fn mul( self, transform: Transform, ) -> <GlobalTransform as Mul<Transform>>::Output

Performs the * operation. Read more
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 for Transform

Source§

type Output = Transform

The resulting type after applying the * operator.
Source§

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

Performs the * operation. Read more
Source§

impl PartialEq for Transform

Source§

fn eq(&self, other: &Transform) -> 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 Transform
where Transform: Any + Send + Sync, Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Quat: 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<Transform>) -> ReflectOwned

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

fn try_into_reflect( self: Box<Transform>, ) -> 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<Transform>) -> 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 Reflect for Transform
where Transform: Any + Send + Sync, Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

fn into_any(self: Box<Transform>) -> 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<Transform>) -> 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 Serialize for Transform

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 Struct for Transform
where Transform: Any + Send + Sync, Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Quat: 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 TransformPoint for Transform

Source§

fn transform_point(&self, point: impl Into<Vec3>) -> Vec3

Transform a point.
Source§

impl TypePath for Transform
where Transform: 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 Transform
where Transform: Any + Send + Sync, Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

fn type_info() -> &'static TypeInfo

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

impl Copy for Transform

Source§

impl StructuralPartialEq for Transform

Auto Trait Implementations§

Blanket Implementations§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T, 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<C> Bundle for C
where C: Component,

Source§

fn component_ids( components: &mut ComponentsRegistrator<'_>, ids: &mut impl FnMut(ComponentId), )

Source§

fn register_required_components( components: &mut ComponentsRegistrator<'_>, required_components: &mut RequiredComponents, )

Registers components that are required by the components in this Bundle.
Source§

fn get_component_ids( components: &Components, ids: &mut impl FnMut(Option<ComponentId>), )

Gets this Bundle’s component ids. This will be None if the component has not been registered.
Source§

impl<C> BundleFromComponents for C
where C: Component,

Source§

unsafe fn from_components<T, F>(ctx: &mut T, func: &mut F) -> C
where F: for<'a> FnMut(&'a mut T) -> OwningPtr<'a>,

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<C> DynamicBundle for C
where C: Component,

Source§

type Effect = ()

An operation on the entity that happens after inserting this bundle.
Source§

fn get_components( self, func: &mut impl FnMut(StorageType, OwningPtr<'_>), ) -> <C as DynamicBundle>::Effect

Source§

impl<T> DynamicTypePath for T
where T: TypePath,

Source§

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

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