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.
- To place or move an entity, you should set its
Transform
. - To get the global transform of an entity, you should get its
GlobalTransform
. - To be displayed, an entity must have both a
Transform
and aGlobalTransform
.GlobalTransform
is automatically inserted wheneverTransform
is inserted.
§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
in the TransformSystems::Propagate
system set.
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
impl Transform
Sourcepub const IDENTITY: Transform
pub const IDENTITY: Transform
An identity Transform
with no translation, rotation, and a scale of 1 on all axes.
Sourcepub const fn from_xyz(x: f32, y: f32, z: f32) -> Transform
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?
201fn spawn_light(commands: &mut Commands) {
202 commands.spawn((
203 DirectionalLight::default(),
204 Transform::from_xyz(4.0, 8.0, 4.0).looking_at(Vec3::ZERO, Vec3::Y),
205 ));
206}
207
208/// Spawns the camera.
209fn spawn_camera(commands: &mut Commands) {
210 commands
211 .spawn(Camera3d::default())
212 .insert(Transform::from_xyz(0.0, 2.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y))
213 // Tag the camera with `Selection::Camera`.
214 .insert(Selection::Camera);
215}
More examples
73fn spawn_curve_sprite<T: CurveColor>(commands: &mut Commands, y: f32, points: [T; 4]) {
74 commands.spawn((
75 Sprite::sized(Vec2::new(75., 75.)),
76 Transform::from_xyz(0., y, 0.),
77 Curve(CubicBezier::new([points]).to_curve().unwrap()),
78 ));
79}
80
81fn spawn_mixed_sprite<T: MixedColor>(commands: &mut Commands, y: f32, colors: [T; 4]) {
82 commands.spawn((
83 Transform::from_xyz(0., y, 0.),
84 Sprite::sized(Vec2::new(75., 75.)),
85 Mixed(colors),
86 ));
87}
- examples/3d/irradiance_volumes.rs
- examples/async_tasks/external_source_external_thread.rs
- examples/math/render_primitives.rs
- examples/stress_tests/many_gizmos.rs
- examples/animation/gltf_skinned_mesh.rs
- examples/games/alien_cake_addict.rs
- examples/shader/animate_shader.rs
- examples/3d/query_gltf_primitives.rs
- examples/3d/lightmaps.rs
- examples/shader/shader_material_wesl.rs
- examples/shader/array_texture.rs
- examples/3d/ssr.rs
- examples/3d/light_textures.rs
- examples/camera/2d_top_down_camera.rs
- examples/2d/pixel_grid_snap.rs
- examples/shader/fallback_image.rs
- examples/shader_advanced/custom_phase_item.rs
- examples/shader_advanced/render_depth_to_texture.rs
- examples/3d/3d_viewport_to_world.rs
- examples/shader/shader_material.rs
- examples/shader/shader_material_glsl.rs
- examples/shader_advanced/texture_binding_array.rs
- examples/asset/hot_asset_reloading.rs
- examples/asset/multi_asset_sync.rs
- examples/3d/manual_material.rs
- examples/3d/color_grading.rs
- examples/2d/transparency_2d.rs
- examples/transforms/3d_rotation.rs
- examples/3d/rotate_environment_map.rs
- examples/transforms/scale.rs
- examples/shader_advanced/custom_vertex_attribute.rs
- examples/animation/morph_targets.rs
- examples/3d/post_processing.rs
- tests/window/minimizing.rs
- tests/window/resizing.rs
- examples/3d/atmospheric_fog.rs
- examples/transforms/translation.rs
- examples/3d/load_gltf_extras.rs
- examples/shader/shader_defs.rs
- examples/3d/clearcoat.rs
- examples/3d/3d_scene.rs
- examples/animation/animated_mesh.rs
- examples/games/loading_screen.rs
- examples/shader_advanced/custom_post_processing.rs
- examples/3d/parenting.rs
- examples/animation/animation_graph.rs
- examples/shader/shader_material_screenspace_texture.rs
- examples/3d/pcss.rs
- examples/3d/depth_of_field.rs
- examples/camera/2d_screen_shake.rs
- examples/camera/camera_orbit.rs
- examples/3d/edit_material_on_gltf.rs
- examples/shader/shader_material_bindless.rs
- examples/3d/anisotropy.rs
- examples/remote/server.rs
- examples/animation/animation_masks.rs
- examples/window/screenshot.rs
- examples/3d/animated_material.rs
- examples/ecs/entity_disabling.rs
- examples/camera/custom_projection.rs
- examples/3d/load_gltf.rs
- examples/3d/two_passes.rs
- examples/3d/lines.rs
- examples/stress_tests/many_materials.rs
- examples/diagnostics/log_diagnostics.rs
- examples/shader/extended_material_bindless.rs
- examples/3d/skybox.rs
- examples/3d/order_independent_transparency.rs
- examples/3d/tonemapping.rs
- examples/3d/update_gltf_scene.rs
- examples/shader_advanced/custom_render_phase.rs
- examples/3d/atmosphere.rs
- examples/3d/fog_volumes.rs
- examples/shader/storage_buffer.rs
- examples/window/low_power.rs
- examples/ecs/hierarchy.rs
- examples/3d/generate_custom_mesh.rs
- examples/2d/wireframe_2d.rs
- examples/3d/mesh_ray_cast.rs
- examples/audio/spatial_audio_2d.rs
- examples/picking/simple_picking.rs
- examples/movement/smooth_follow.rs
- examples/shader/extended_material.rs
- examples/3d/vertex_colors.rs
- examples/shader_advanced/custom_shader_instancing.rs
- tests/window/desktop_request_redraw.rs
- examples/3d/orthographic.rs
- examples/games/contributors.rs
- examples/picking/debug_picking.rs
- examples/testbed/2d.rs
- examples/shader_advanced/specialized_mesh_pipeline.rs
- examples/3d/spherical_area_lights.rs
- examples/math/bounding_2d.rs
- examples/transforms/transform.rs
- examples/window/multiple_windows.rs
- examples/camera/first_person_view_model.rs
- examples/gizmos/axes.rs
- examples/3d/motion_blur.rs
- examples/math/custom_primitives.rs
- examples/3d/ssao.rs
- examples/animation/animated_mesh_events.rs
- examples/asset/alter_sprite.rs
- examples/app/headless_renderer.rs
- examples/animation/eased_motion.rs
- examples/3d/wireframe.rs
- examples/2d/2d_shapes.rs
- examples/stress_tests/transform_hierarchy.rs
- examples/audio/spatial_audio_3d.rs
- examples/shader/automatic_instancing.rs
- examples/ecs/error_handling.rs
- examples/camera/projection_zoom.rs
- examples/2d/rotation.rs
- examples/3d/fog.rs
- examples/3d/specular_tint.rs
- examples/ui/viewport_node.rs
- examples/3d/visibility_range.rs
- examples/3d/volumetric_fog.rs
- examples/animation/animated_mesh_control.rs
- examples/testbed/3d.rs
- tests/3d/test_invalid_skinned_mesh.rs
- examples/stress_tests/many_cameras_lights.rs
- examples/3d/texture.rs
- examples/async_tasks/async_compute.rs
- examples/3d/shadow_caster_receiver.rs
- examples/3d/anti_aliasing.rs
- examples/3d/bloom_3d.rs
- examples/gizmos/3d_gizmos.rs
- examples/transforms/align.rs
- examples/math/random_sampling.rs
- examples/picking/sprite_picking.rs
- examples/3d/scrolling_fog.rs
- examples/3d/decal.rs
- examples/2d/mesh2d_alpha_mode.rs
- examples/3d/render_to_texture.rs
- examples/asset/repeated_texture.rs
- examples/ecs/iter_combinations.rs
- examples/2d/sprite_slice.rs
- examples/asset/alter_mesh.rs
- examples/3d/transparency_3d.rs
- examples/asset/asset_settings.rs
- examples/2d/mesh2d_repeated_texture.rs
- examples/gizmos/light_gizmos.rs
- examples/3d/spotlight.rs
- examples/3d/pbr.rs
- examples/3d/3d_shapes.rs
- examples/3d/auto_exposure.rs
- examples/animation/easing_functions.rs
- examples/asset/asset_loading.rs
- examples/shader/shader_prepass.rs
- examples/window/multi_window_text.rs
- examples/3d/shadow_biases.rs
- examples/picking/mesh_picking.rs
- examples/ui/render_ui_to_texture.rs
- examples/stress_tests/many_foxes.rs
- examples/games/desk_toy.rs
- examples/math/sampling_primitives.rs
- examples/3d/parallax_mapping.rs
- examples/2d/sprite_scale.rs
- examples/3d/deferred_rendering.rs
- examples/animation/custom_skinned_mesh.rs
- examples/3d/blend_modes.rs
- examples/stress_tests/many_cubes.rs
- examples/animation/animated_transform.rs
- examples/3d/lighting.rs
- examples/3d/camera_sub_view.rs
- examples/3d/transmission.rs
Sourcepub fn from_matrix(world_from_local: Mat4) -> Transform
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.
Sourcepub const fn from_translation(translation: Vec3) -> Transform
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?
More examples
288fn setup_lights(mut commands: Commands) {
289 commands.spawn((
290 PointLight {
291 intensity: 5000.0,
292 ..default()
293 },
294 Transform::from_translation(Vec3::new(-LEFT_RIGHT_OFFSET_3D, 2.0, 0.0))
295 .looking_at(Vec3::new(-LEFT_RIGHT_OFFSET_3D, 0.0, 0.0), Vec3::Y),
296 ));
297}
298
299/// Marker component for header text
300#[derive(Debug, Clone, Component, Default, Reflect)]
301pub struct HeaderText;
302
303/// Marker component for header node
304#[derive(Debug, Clone, Component, Default, Reflect)]
305pub struct HeaderNode;
306
307fn update_active_cameras(
308 state: Res<State<CameraActive>>,
309 camera_2d: Single<(Entity, &mut Camera), With<Camera2d>>,
310 camera_3d: Single<(Entity, &mut Camera), (With<Camera3d>, Without<Camera2d>)>,
311 mut text: Query<&mut UiTargetCamera, With<HeaderNode>>,
312) {
313 let (entity_2d, mut cam_2d) = camera_2d.into_inner();
314 let (entity_3d, mut cam_3d) = camera_3d.into_inner();
315 let is_camera_2d_active = matches!(*state.get(), CameraActive::Dim2);
316
317 cam_2d.is_active = is_camera_2d_active;
318 cam_3d.is_active = !is_camera_2d_active;
319
320 let active_camera = if is_camera_2d_active {
321 entity_2d
322 } else {
323 entity_3d
324 };
325
326 text.iter_mut().for_each(|mut target_camera| {
327 *target_camera = UiTargetCamera(active_camera);
328 });
329}
330
331fn switch_cameras(current: Res<State<CameraActive>>, mut next: ResMut<NextState<CameraActive>>) {
332 let next_state = match current.get() {
333 CameraActive::Dim2 => CameraActive::Dim3,
334 CameraActive::Dim3 => CameraActive::Dim2,
335 };
336 next.set(next_state);
337}
338
339fn setup_text(mut commands: Commands, cameras: Query<(Entity, &Camera)>) {
340 let active_camera = cameras
341 .iter()
342 .find_map(|(entity, camera)| camera.is_active.then_some(entity))
343 .expect("run condition ensures existence");
344 commands.spawn((
345 HeaderNode,
346 Node {
347 justify_self: JustifySelf::Center,
348 top: px(5),
349 ..Default::default()
350 },
351 UiTargetCamera(active_camera),
352 children![(
353 Text::default(),
354 HeaderText,
355 TextLayout::new_with_justify(Justify::Center),
356 children![
357 TextSpan::new("Primitive: "),
358 TextSpan(format!("{text}", text = PrimitiveSelected::default())),
359 TextSpan::new("\n\n"),
360 TextSpan::new(
361 "Press 'C' to switch between 2D and 3D mode\n\
362 Press 'Up' or 'Down' to switch to the next/previous primitive",
363 ),
364 TextSpan::new("\n\n"),
365 TextSpan::new("(If nothing is displayed, there's no rendering support yet)",),
366 ]
367 )],
368 ));
369}
370
371fn update_text(
372 primitive_state: Res<State<PrimitiveSelected>>,
373 header: Query<Entity, With<HeaderText>>,
374 mut writer: TextUiWriter,
375) {
376 let new_text = format!("{text}", text = primitive_state.get());
377 header.iter().for_each(|header_text| {
378 if let Some(mut text) = writer.get_text(header_text, 2) {
379 (*text).clone_from(&new_text);
380 };
381 });
382}
383
384fn switch_to_next_primitive(
385 current: Res<State<PrimitiveSelected>>,
386 mut next: ResMut<NextState<PrimitiveSelected>>,
387) {
388 let next_state = current.get().next();
389 next.set(next_state);
390}
391
392fn switch_to_previous_primitive(
393 current: Res<State<PrimitiveSelected>>,
394 mut next: ResMut<NextState<PrimitiveSelected>>,
395) {
396 let next_state = current.get().previous();
397 next.set(next_state);
398}
399
400fn in_mode(active: CameraActive) -> impl Fn(Res<State<CameraActive>>) -> bool {
401 move |state| *state.get() == active
402}
403
404fn draw_gizmos_2d(mut gizmos: Gizmos, state: Res<State<PrimitiveSelected>>, time: Res<Time>) {
405 const POSITION: Vec2 = Vec2::new(-LEFT_RIGHT_OFFSET_2D, 0.0);
406 let angle = time.elapsed_secs();
407 let isometry = Isometry2d::new(POSITION, Rot2::radians(angle));
408 let color = Color::WHITE;
409
410 #[expect(
411 clippy::match_same_arms,
412 reason = "Certain primitives don't have any 2D rendering support yet."
413 )]
414 match state.get() {
415 PrimitiveSelected::RectangleAndCuboid => {
416 gizmos.primitive_2d(&RECTANGLE, isometry, color);
417 }
418 PrimitiveSelected::CircleAndSphere => {
419 gizmos.primitive_2d(&CIRCLE, isometry, color);
420 }
421 PrimitiveSelected::Ellipse => drop(gizmos.primitive_2d(&ELLIPSE, isometry, color)),
422 PrimitiveSelected::Triangle => gizmos.primitive_2d(&TRIANGLE_2D, isometry, color),
423 PrimitiveSelected::Plane => gizmos.primitive_2d(&PLANE_2D, isometry, color),
424 PrimitiveSelected::Line => drop(gizmos.primitive_2d(&LINE2D, isometry, color)),
425 PrimitiveSelected::Segment => {
426 drop(gizmos.primitive_2d(&SEGMENT_2D, isometry, color));
427 }
428 PrimitiveSelected::Polyline => gizmos.primitive_2d(
429 &Polyline2d {
430 vertices: vec![
431 Vec2::new(-BIG_2D, -SMALL_2D),
432 Vec2::new(-SMALL_2D, SMALL_2D),
433 Vec2::new(SMALL_2D, -SMALL_2D),
434 Vec2::new(BIG_2D, SMALL_2D),
435 ],
436 },
437 isometry,
438 color,
439 ),
440 PrimitiveSelected::Polygon => gizmos.primitive_2d(
441 &Polygon {
442 vertices: vec![
443 Vec2::new(-BIG_2D, -SMALL_2D),
444 Vec2::new(BIG_2D, -SMALL_2D),
445 Vec2::new(BIG_2D, SMALL_2D),
446 Vec2::new(0.0, 0.0),
447 Vec2::new(-BIG_2D, SMALL_2D),
448 ],
449 },
450 isometry,
451 color,
452 ),
453 PrimitiveSelected::RegularPolygon => {
454 gizmos.primitive_2d(®ULAR_POLYGON, isometry, color);
455 }
456 PrimitiveSelected::Capsule => gizmos.primitive_2d(&CAPSULE_2D, isometry, color),
457 PrimitiveSelected::Cylinder => {}
458 PrimitiveSelected::Cone => {}
459 PrimitiveSelected::ConicalFrustum => {}
460 PrimitiveSelected::Torus => drop(gizmos.primitive_2d(&ANNULUS, isometry, color)),
461 PrimitiveSelected::Tetrahedron => {}
462 PrimitiveSelected::Arc => gizmos.primitive_2d(&ARC, isometry, color),
463 PrimitiveSelected::CircularSector => {
464 gizmos.primitive_2d(&CIRCULAR_SECTOR, isometry, color);
465 }
466 PrimitiveSelected::CircularSegment => {
467 gizmos.primitive_2d(&CIRCULAR_SEGMENT, isometry, color);
468 }
469 }
470}
471
472/// Marker for primitive meshes to record in which state they should be visible in
473#[derive(Debug, Clone, Component, Default, Reflect)]
474pub struct PrimitiveData {
475 camera_mode: CameraActive,
476 primitive_state: PrimitiveSelected,
477}
478
479/// Marker for meshes of 2D primitives
480#[derive(Debug, Clone, Component, Default)]
481pub struct MeshDim2;
482
483/// Marker for meshes of 3D primitives
484#[derive(Debug, Clone, Component, Default)]
485pub struct MeshDim3;
486
487fn spawn_primitive_2d(
488 mut commands: Commands,
489 mut materials: ResMut<Assets<ColorMaterial>>,
490 mut meshes: ResMut<Assets<Mesh>>,
491) {
492 const POSITION: Vec3 = Vec3::new(LEFT_RIGHT_OFFSET_2D, 0.0, 0.0);
493 let material: Handle<ColorMaterial> = materials.add(Color::WHITE);
494 let camera_mode = CameraActive::Dim2;
495 [
496 Some(RECTANGLE.mesh().build()),
497 Some(CIRCLE.mesh().build()),
498 Some(ELLIPSE.mesh().build()),
499 Some(TRIANGLE_2D.mesh().build()),
500 None, // plane
501 None, // line
502 None, // segment
503 None, // polyline
504 None, // polygon
505 Some(REGULAR_POLYGON.mesh().build()),
506 Some(CAPSULE_2D.mesh().build()),
507 None, // cylinder
508 None, // cone
509 None, // conical frustum
510 Some(ANNULUS.mesh().build()),
511 None, // tetrahedron
512 ]
513 .into_iter()
514 .zip(PrimitiveSelected::ALL)
515 .for_each(|(maybe_mesh, state)| {
516 if let Some(mesh) = maybe_mesh {
517 commands.spawn((
518 MeshDim2,
519 PrimitiveData {
520 camera_mode,
521 primitive_state: state,
522 },
523 Mesh2d(meshes.add(mesh)),
524 MeshMaterial2d(material.clone()),
525 Transform::from_translation(POSITION),
526 ));
527 }
528 });
529}
530
531fn spawn_primitive_3d(
532 mut commands: Commands,
533 mut materials: ResMut<Assets<StandardMaterial>>,
534 mut meshes: ResMut<Assets<Mesh>>,
535) {
536 const POSITION: Vec3 = Vec3::new(-LEFT_RIGHT_OFFSET_3D, 0.0, 0.0);
537 let material: Handle<StandardMaterial> = materials.add(Color::WHITE);
538 let camera_mode = CameraActive::Dim3;
539 [
540 Some(CUBOID.mesh().build()),
541 Some(SPHERE.mesh().build()),
542 None, // ellipse
543 Some(TRIANGLE_3D.mesh().build()),
544 Some(PLANE_3D.mesh().build()),
545 None, // line
546 None, // segment
547 None, // polyline
548 None, // polygon
549 None, // regular polygon
550 Some(CAPSULE_3D.mesh().build()),
551 Some(CYLINDER.mesh().build()),
552 None, // cone
553 None, // conical frustum
554 Some(TORUS.mesh().build()),
555 Some(TETRAHEDRON.mesh().build()),
556 ]
557 .into_iter()
558 .zip(PrimitiveSelected::ALL)
559 .for_each(|(maybe_mesh, state)| {
560 if let Some(mesh) = maybe_mesh {
561 commands.spawn((
562 MeshDim3,
563 PrimitiveData {
564 camera_mode,
565 primitive_state: state,
566 },
567 Mesh3d(meshes.add(mesh)),
568 MeshMaterial3d(material.clone()),
569 Transform::from_translation(POSITION),
570 ));
571 }
572 });
573}
- examples/ecs/fallible_params.rs
- examples/3d/3d_viewport_to_world.rs
- examples/transforms/3d_rotation.rs
- examples/stress_tests/bevymark.rs
- examples/transforms/translation.rs
- examples/testbed/2d.rs
- examples/asset/multi_asset_sync.rs
- examples/shader_advanced/custom_post_processing.rs
- examples/testbed/3d.rs
- examples/3d/anisotropy.rs
- examples/3d/animated_material.rs
- examples/3d/ssr.rs
- examples/stress_tests/many_materials.rs
- examples/movement/physics_in_fixed_timestep.rs
- examples/2d/mesh2d_vertex_color_texture.rs
- examples/3d/mesh_ray_cast.rs
- examples/3d/order_independent_transparency.rs
- examples/audio/spatial_audio_2d.rs
- examples/movement/smooth_follow.rs
- examples/2d/2d_viewport_to_world.rs
- examples/transforms/transform.rs
- examples/2d/bloom_2d.rs
- examples/3d/light_textures.rs
- examples/3d/occlusion_culling.rs
- examples/animation/eased_motion.rs
- examples/audio/spatial_audio_3d.rs
- examples/ecs/error_handling.rs
- examples/camera/projection_zoom.rs
- examples/stress_tests/many_lights.rs
- examples/3d/render_to_texture.rs
- examples/asset/repeated_texture.rs
- examples/math/random_sampling.rs
- examples/stress_tests/transform_hierarchy.rs
- examples/2d/sprite_slice.rs
- examples/3d/meshlet.rs
- examples/2d/mesh2d_repeated_texture.rs
- examples/3d/spotlight.rs
- examples/gizmos/3d_gizmos.rs
- examples/3d/auto_exposure.rs
- examples/3d/solari.rs
- examples/3d/split_screen.rs
- examples/games/breakout.rs
- examples/stress_tests/many_foxes.rs
- examples/math/sampling_primitives.rs
- examples/3d/parallax_mapping.rs
- examples/2d/sprite_scale.rs
- examples/2d/text2d.rs
- examples/stress_tests/many_cubes.rs
Sourcepub const fn from_rotation(rotation: Quat) -> Transform
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?
More examples
54fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
55 commands.spawn((
56 Camera3d::default(),
57 Transform::from_xyz(4.0, 4.0, 12.0).looking_at(Vec3::new(0.0, 0.0, 0.5), Vec3::Y),
58 ));
59
60 commands.spawn((
61 Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, 1.0, -PI / 4.)),
62 DirectionalLight::default(),
63 ));
64
65 commands.spawn(SceneRoot(asset_server.load(
66 GltfAssetLabel::Scene(0).from_asset("models/GltfPrimitives/gltf_primitives.glb"),
67 )));
68}
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}
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}
28fn setup(
29 mut commands: Commands,
30 asset_server: Res<AssetServer>,
31 mut graphs: ResMut<Assets<AnimationGraph>>,
32) {
33 let (graph, index) = AnimationGraph::from_clip(
34 asset_server.load(GltfAssetLabel::Animation(2).from_asset(GLTF_PATH)),
35 );
36
37 commands
38 .spawn((
39 AnimationToPlay {
40 graph_handle: graphs.add(graph),
41 index,
42 },
43 SceneRoot(asset_server.load(GltfAssetLabel::Scene(0).from_asset(GLTF_PATH))),
44 ))
45 .observe(play_animation_when_ready);
46
47 commands.spawn((
48 DirectionalLight::default(),
49 Transform::from_rotation(Quat::from_rotation_z(PI / 2.0)),
50 ));
51
52 commands.spawn((
53 Camera3d::default(),
54 Transform::from_xyz(3.0, 2.1, 10.2).looking_at(Vec3::ZERO, Vec3::Y),
55 ));
56}
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/3d_scene.rs
- examples/animation/animated_mesh.rs
- examples/animation/animation_graph.rs
- examples/3d/post_processing.rs
- examples/3d/color_grading.rs
- examples/remote/server.rs
- examples/animation/animation_masks.rs
- examples/3d/tonemapping.rs
- examples/camera/custom_projection.rs
- examples/stress_tests/many_materials.rs
- examples/testbed/3d.rs
- examples/diagnostics/log_diagnostics.rs
- examples/shader_advanced/custom_render_phase.rs
- examples/3d/mesh_ray_cast.rs
- examples/picking/simple_picking.rs
- examples/picking/debug_picking.rs
- examples/3d/ssao.rs
- examples/animation/animated_mesh_events.rs
- examples/app/headless_renderer.rs
- examples/3d/specular_tint.rs
- examples/3d/visibility_range.rs
- examples/animation/animated_mesh_control.rs
- examples/stress_tests/many_cameras_lights.rs
- examples/3d/texture.rs
- examples/3d/shadow_caster_receiver.rs
- examples/3d/anti_aliasing.rs
- examples/3d/decal.rs
- examples/3d/meshlet.rs
- examples/gizmos/light_gizmos.rs
- examples/3d/solari.rs
- examples/3d/split_screen.rs
- examples/stress_tests/many_foxes.rs
- examples/3d/deferred_rendering.rs
- examples/3d/lighting.rs
Sourcepub const fn from_scale(scale: Vec3) -> Transform
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?
282fn spawn_fox(commands: &mut Commands, assets: &ExampleAssets) {
283 commands.spawn((
284 SceneRoot(assets.fox.clone()),
285 Visibility::Hidden,
286 Transform::from_scale(Vec3::splat(FOX_SCALE)),
287 MainObject,
288 ));
289}
290
291fn spawn_text(commands: &mut Commands, app_status: &AppStatus) {
292 commands.spawn((
293 app_status.create_text(),
294 Node {
295 position_type: PositionType::Absolute,
296 bottom: px(12),
297 left: px(12),
298 ..default()
299 },
300 ));
301}
302
303// A system that updates the help text.
304fn update_text(mut text_query: Query<&mut Text>, app_status: Res<AppStatus>) {
305 for mut text in text_query.iter_mut() {
306 *text = app_status.create_text();
307 }
308}
309
310impl AppStatus {
311 // Constructs the help text at the bottom of the screen based on the
312 // application status.
313 fn create_text(&self) -> Text {
314 let irradiance_volume_help_text = if self.irradiance_volume_present {
315 DISABLE_IRRADIANCE_VOLUME_HELP_TEXT
316 } else {
317 ENABLE_IRRADIANCE_VOLUME_HELP_TEXT
318 };
319
320 let voxels_help_text = if self.voxels_visible {
321 HIDE_VOXELS_HELP_TEXT
322 } else {
323 SHOW_VOXELS_HELP_TEXT
324 };
325
326 let rotation_help_text = if self.rotating {
327 STOP_ROTATION_HELP_TEXT
328 } else {
329 START_ROTATION_HELP_TEXT
330 };
331
332 let switch_mesh_help_text = match self.model {
333 ExampleModel::Sphere => SWITCH_TO_FOX_HELP_TEXT,
334 ExampleModel::Fox => SWITCH_TO_SPHERE_HELP_TEXT,
335 };
336
337 format!(
338 "{CLICK_TO_MOVE_HELP_TEXT}\n\
339 {voxels_help_text}\n\
340 {irradiance_volume_help_text}\n\
341 {rotation_help_text}\n\
342 {switch_mesh_help_text}"
343 )
344 .into()
345 }
346}
347
348// Rotates the camera a bit every frame.
349fn rotate_camera(
350 mut camera_query: Query<&mut Transform, With<Camera3d>>,
351 time: Res<Time>,
352 app_status: Res<AppStatus>,
353) {
354 if !app_status.rotating {
355 return;
356 }
357
358 for mut transform in camera_query.iter_mut() {
359 transform.translation = Vec2::from_angle(ROTATION_SPEED * time.delta_secs())
360 .rotate(transform.translation.xz())
361 .extend(transform.translation.y)
362 .xzy();
363 transform.look_at(Vec3::ZERO, Vec3::Y);
364 }
365}
366
367// Toggles between the unskinned sphere model and the skinned fox model if the
368// user requests it.
369fn change_main_object(
370 keyboard: Res<ButtonInput<KeyCode>>,
371 mut app_status: ResMut<AppStatus>,
372 mut sphere_query: Query<&mut Visibility, (With<MainObject>, With<Mesh3d>, Without<SceneRoot>)>,
373 mut fox_query: Query<&mut Visibility, (With<MainObject>, With<SceneRoot>)>,
374) {
375 if !keyboard.just_pressed(KeyCode::Tab) {
376 return;
377 }
378 let Some(mut sphere_visibility) = sphere_query.iter_mut().next() else {
379 return;
380 };
381 let Some(mut fox_visibility) = fox_query.iter_mut().next() else {
382 return;
383 };
384
385 match app_status.model {
386 ExampleModel::Sphere => {
387 *sphere_visibility = Visibility::Hidden;
388 *fox_visibility = Visibility::Visible;
389 app_status.model = ExampleModel::Fox;
390 }
391 ExampleModel::Fox => {
392 *sphere_visibility = Visibility::Visible;
393 *fox_visibility = Visibility::Hidden;
394 app_status.model = ExampleModel::Sphere;
395 }
396 }
397}
398
399impl Default for AppStatus {
400 fn default() -> Self {
401 Self {
402 irradiance_volume_present: true,
403 rotating: true,
404 model: ExampleModel::Sphere,
405 voxels_visible: false,
406 }
407 }
408}
409
410// Turns on and off the irradiance volume as requested by the user.
411fn toggle_irradiance_volumes(
412 mut commands: Commands,
413 keyboard: Res<ButtonInput<KeyCode>>,
414 light_probe_query: Query<Entity, With<LightProbe>>,
415 mut app_status: ResMut<AppStatus>,
416 assets: Res<ExampleAssets>,
417 mut ambient_light: ResMut<AmbientLight>,
418) {
419 if !keyboard.just_pressed(KeyCode::Space) {
420 return;
421 };
422
423 let Some(light_probe) = light_probe_query.iter().next() else {
424 return;
425 };
426
427 if app_status.irradiance_volume_present {
428 commands.entity(light_probe).remove::<IrradianceVolume>();
429 ambient_light.brightness = AMBIENT_LIGHT_BRIGHTNESS * IRRADIANCE_VOLUME_INTENSITY;
430 app_status.irradiance_volume_present = false;
431 } else {
432 commands.entity(light_probe).insert(IrradianceVolume {
433 voxels: assets.irradiance_volume.clone(),
434 intensity: IRRADIANCE_VOLUME_INTENSITY,
435 ..default()
436 });
437 ambient_light.brightness = 0.0;
438 app_status.irradiance_volume_present = true;
439 }
440}
441
442fn toggle_rotation(keyboard: Res<ButtonInput<KeyCode>>, mut app_status: ResMut<AppStatus>) {
443 if keyboard.just_pressed(KeyCode::Enter) {
444 app_status.rotating = !app_status.rotating;
445 }
446}
447
448// Handles clicks on the plane that reposition the object.
449fn handle_mouse_clicks(
450 buttons: Res<ButtonInput<MouseButton>>,
451 windows: Query<&Window, With<PrimaryWindow>>,
452 cameras: Query<(&Camera, &GlobalTransform)>,
453 mut main_objects: Query<&mut Transform, With<MainObject>>,
454) {
455 if !buttons.pressed(MouseButton::Left) {
456 return;
457 }
458 let Some(mouse_position) = windows.iter().next().and_then(Window::cursor_position) else {
459 return;
460 };
461 let Some((camera, camera_transform)) = cameras.iter().next() else {
462 return;
463 };
464
465 // Figure out where the user clicked on the plane.
466 let Ok(ray) = camera.viewport_to_world(camera_transform, mouse_position) else {
467 return;
468 };
469 let Some(ray_distance) = ray.intersect_plane(Vec3::ZERO, InfinitePlane3d::new(Vec3::Y)) else {
470 return;
471 };
472 let plane_intersection = ray.origin + ray.direction.normalize() * ray_distance;
473
474 // Move all the main objects.
475 for mut transform in main_objects.iter_mut() {
476 transform.translation = vec3(
477 plane_intersection.x,
478 transform.translation.y,
479 plane_intersection.z,
480 );
481 }
482}
483
484impl FromWorld for ExampleAssets {
485 fn from_world(world: &mut World) -> Self {
486 let fox_animation =
487 world.load_asset(GltfAssetLabel::Animation(1).from_asset("models/animated/Fox.glb"));
488 let (fox_animation_graph, fox_animation_node) =
489 AnimationGraph::from_clip(fox_animation.clone());
490
491 ExampleAssets {
492 main_sphere: world.add_asset(Sphere::default().mesh().uv(32, 18)),
493 fox: world.load_asset(GltfAssetLabel::Scene(0).from_asset("models/animated/Fox.glb")),
494 main_sphere_material: world.add_asset(Color::from(SILVER)),
495 main_scene: world.load_asset(
496 GltfAssetLabel::Scene(0)
497 .from_asset("models/IrradianceVolumeExample/IrradianceVolumeExample.glb"),
498 ),
499 irradiance_volume: world.load_asset("irradiance_volumes/Example.vxgi.ktx2"),
500 fox_animation_graph: world.add_asset(fox_animation_graph),
501 fox_animation_node,
502 voxel_cube: world.add_asset(Cuboid::default()),
503 // Just use a specular map for the skybox since it's not too blurry.
504 // In reality you wouldn't do this--you'd use a real skybox texture--but
505 // reusing the textures like this saves space in the Bevy repository.
506 skybox: world.load_asset("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
507 }
508 }
509}
510
511// Plays the animation on the fox.
512fn play_animations(
513 mut commands: Commands,
514 assets: Res<ExampleAssets>,
515 mut players: Query<(Entity, &mut AnimationPlayer), Without<AnimationGraphHandle>>,
516) {
517 for (entity, mut player) in players.iter_mut() {
518 commands
519 .entity(entity)
520 .insert(AnimationGraphHandle(assets.fox_animation_graph.clone()));
521 player.play(assets.fox_animation_node).repeat();
522 }
523}
524
525fn create_cubes(
526 image_assets: Res<Assets<Image>>,
527 mut commands: Commands,
528 irradiance_volumes: Query<(&IrradianceVolume, &GlobalTransform)>,
529 voxel_cube_parents: Query<Entity, With<VoxelCubeParent>>,
530 voxel_cubes: Query<Entity, With<VoxelCube>>,
531 example_assets: Res<ExampleAssets>,
532 mut voxel_visualization_material_assets: ResMut<Assets<VoxelVisualizationMaterial>>,
533) {
534 // If voxel cubes have already been spawned, don't do anything.
535 if !voxel_cubes.is_empty() {
536 return;
537 }
538
539 let Some(voxel_cube_parent) = voxel_cube_parents.iter().next() else {
540 return;
541 };
542
543 for (irradiance_volume, global_transform) in irradiance_volumes.iter() {
544 let Some(image) = image_assets.get(&irradiance_volume.voxels) else {
545 continue;
546 };
547
548 let resolution = image.texture_descriptor.size;
549
550 let voxel_cube_material = voxel_visualization_material_assets.add(ExtendedMaterial {
551 base: StandardMaterial::from(Color::from(RED)),
552 extension: VoxelVisualizationExtension {
553 irradiance_volume_info: VoxelVisualizationIrradianceVolumeInfo {
554 world_from_voxel: VOXEL_FROM_WORLD.inverse(),
555 voxel_from_world: VOXEL_FROM_WORLD,
556 resolution: uvec3(
557 resolution.width,
558 resolution.height,
559 resolution.depth_or_array_layers,
560 ),
561 intensity: IRRADIANCE_VOLUME_INTENSITY,
562 },
563 },
564 });
565
566 let scale = vec3(
567 1.0 / resolution.width as f32,
568 1.0 / resolution.height as f32,
569 1.0 / resolution.depth_or_array_layers as f32,
570 );
571
572 // Spawn a cube for each voxel.
573 for z in 0..resolution.depth_or_array_layers {
574 for y in 0..resolution.height {
575 for x in 0..resolution.width {
576 let uvw = (uvec3(x, y, z).as_vec3() + 0.5) * scale - 0.5;
577 let pos = global_transform.transform_point(uvw);
578 let voxel_cube = commands
579 .spawn((
580 Mesh3d(example_assets.voxel_cube.clone()),
581 MeshMaterial3d(voxel_cube_material.clone()),
582 Transform::from_scale(Vec3::splat(VOXEL_CUBE_SCALE))
583 .with_translation(pos),
584 ))
585 .insert(VoxelCube)
586 .insert(NotShadowCaster)
587 .id();
588
589 commands.entity(voxel_cube_parent).add_child(voxel_cube);
590 }
591 }
592 }
593 }
594}
More examples
167fn spawn_flight_helmet(commands: &mut Commands, asset_server: &AssetServer) {
168 commands.spawn((
169 SceneRoot(
170 asset_server
171 .load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
172 ),
173 Transform::from_scale(Vec3::splat(2.5)),
174 FlightHelmetModel,
175 Visibility::Hidden,
176 ));
177}
178
179// Spawns the water plane.
180fn spawn_water(
181 commands: &mut Commands,
182 asset_server: &AssetServer,
183 meshes: &mut Assets<Mesh>,
184 water_materials: &mut Assets<ExtendedMaterial<StandardMaterial, Water>>,
185) {
186 commands.spawn((
187 Mesh3d(meshes.add(Plane3d::new(Vec3::Y, Vec2::splat(1.0)))),
188 MeshMaterial3d(water_materials.add(ExtendedMaterial {
189 base: StandardMaterial {
190 base_color: BLACK.into(),
191 perceptual_roughness: 0.0,
192 ..default()
193 },
194 extension: Water {
195 normals: asset_server.load_with_settings::<Image, ImageLoaderSettings>(
196 "textures/water_normals.png",
197 |settings| {
198 settings.is_srgb = false;
199 settings.sampler = ImageSampler::Descriptor(ImageSamplerDescriptor {
200 address_mode_u: ImageAddressMode::Repeat,
201 address_mode_v: ImageAddressMode::Repeat,
202 mag_filter: ImageFilterMode::Linear,
203 min_filter: ImageFilterMode::Linear,
204 ..default()
205 });
206 },
207 ),
208 // These water settings are just random values to create some
209 // variety.
210 settings: WaterSettings {
211 octave_vectors: [
212 vec4(0.080, 0.059, 0.073, -0.062),
213 vec4(0.153, 0.138, -0.149, -0.195),
214 ],
215 octave_scales: vec4(1.0, 2.1, 7.9, 14.9) * 5.0,
216 octave_strengths: vec4(0.16, 0.18, 0.093, 0.044),
217 },
218 },
219 })),
220 Transform::from_scale(Vec3::splat(100.0)),
221 ));
222}
153fn spawn_reflection_probe(commands: &mut Commands, cubemaps: &Cubemaps) {
154 commands.spawn((
155 LightProbe,
156 EnvironmentMapLight {
157 diffuse_map: cubemaps.diffuse_environment_map.clone(),
158 specular_map: cubemaps.specular_reflection_probe.clone(),
159 intensity: ENV_MAP_INTENSITY,
160 ..default()
161 },
162 // 2.0 because the sphere's radius is 1.0 and we want to fully enclose it.
163 Transform::from_scale(Vec3::splat(2.0)),
164 ));
165}
46fn setup(
47 mut commands: Commands,
48 asset_server: Res<AssetServer>,
49 mut materials: ResMut<Assets<CustomMaterial>>,
50) {
51 // Add a mesh loaded from a glTF file. This mesh has data for `ATTRIBUTE_BARYCENTRIC`.
52 let mesh = asset_server.load(
53 GltfAssetLabel::Primitive {
54 mesh: 0,
55 primitive: 0,
56 }
57 .from_asset("models/barycentric/barycentric.gltf"),
58 );
59 commands.spawn((
60 Mesh2d(mesh),
61 MeshMaterial2d(materials.add(CustomMaterial {})),
62 Transform::from_scale(150.0 * Vec3::ONE),
63 ));
64
65 commands.spawn(Camera2d);
66}
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.random::<f32>() - 0.5, rng.random::<f32>() - 0.5)),
23 ));
24 }
25}
- examples/shader/compute_shader_game_of_life.rs
- examples/2d/sprite_sheet.rs
- examples/animation/animation_graph.rs
- examples/animation/animation_masks.rs
- examples/3d/atmospheric_fog.rs
- examples/ecs/hierarchy.rs
- examples/3d/fog.rs
- examples/2d/sprite_animation.rs
- examples/3d/volumetric_fog.rs
- examples/3d/motion_blur.rs
- examples/time/virtual_time.rs
- examples/stress_tests/many_lights.rs
- examples/3d/decal.rs
- examples/ecs/iter_combinations.rs
- examples/3d/solari.rs
- examples/games/desk_toy.rs
- examples/3d/deferred_rendering.rs
- examples/stress_tests/many_cubes.rs
Sourcepub fn from_isometry(iso: Isometry3d) -> Transform
pub fn from_isometry(iso: Isometry3d) -> Transform
Sourcepub fn looking_at(self, target: Vec3, up: impl TryInto<Dir3>) -> Transform
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 toDir3
(e.g if it isVec3::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?
201fn spawn_light(commands: &mut Commands) {
202 commands.spawn((
203 DirectionalLight::default(),
204 Transform::from_xyz(4.0, 8.0, 4.0).looking_at(Vec3::ZERO, Vec3::Y),
205 ));
206}
207
208/// Spawns the camera.
209fn spawn_camera(commands: &mut Commands) {
210 commands
211 .spawn(Camera3d::default())
212 .insert(Transform::from_xyz(0.0, 2.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y))
213 // Tag the camera with `Selection::Camera`.
214 .insert(Selection::Camera);
215}
More examples
268fn setup_cameras(mut commands: Commands) {
269 let start_in_2d = true;
270 let make_camera = |is_active| Camera {
271 is_active,
272 ..Default::default()
273 };
274
275 commands.spawn((Camera2d, make_camera(start_in_2d)));
276
277 commands.spawn((
278 Camera3d::default(),
279 make_camera(!start_in_2d),
280 Transform::from_xyz(0.0, 10.0, 0.0).looking_at(Vec3::ZERO, Vec3::Z),
281 ));
282}
283
284fn setup_ambient_light(mut ambient_light: ResMut<AmbientLight>) {
285 ambient_light.brightness = 50.0;
286}
287
288fn setup_lights(mut commands: Commands) {
289 commands.spawn((
290 PointLight {
291 intensity: 5000.0,
292 ..default()
293 },
294 Transform::from_translation(Vec3::new(-LEFT_RIGHT_OFFSET_3D, 2.0, 0.0))
295 .looking_at(Vec3::new(-LEFT_RIGHT_OFFSET_3D, 0.0, 0.0), Vec3::Y),
296 ));
297}
- examples/stress_tests/many_gizmos.rs
- examples/animation/gltf_skinned_mesh.rs
- examples/games/alien_cake_addict.rs
- examples/shader/animate_shader.rs
- examples/async_tasks/async_compute.rs
- examples/3d/query_gltf_primitives.rs
- examples/shader/shader_material_wesl.rs
- examples/shader/array_texture.rs
- examples/3d/light_textures.rs
- examples/shader/fallback_image.rs
- examples/shader_advanced/custom_phase_item.rs
- examples/3d/3d_viewport_to_world.rs
- examples/shader/shader_material.rs
- examples/shader/shader_material_glsl.rs
- examples/shader_advanced/texture_binding_array.rs
- examples/asset/hot_asset_reloading.rs
- examples/asset/multi_asset_sync.rs
- examples/3d/manual_material.rs
- examples/3d/color_grading.rs
- examples/transforms/3d_rotation.rs
- examples/transforms/scale.rs
- examples/shader_advanced/custom_vertex_attribute.rs
- examples/animation/morph_targets.rs
- examples/3d/post_processing.rs
- tests/window/minimizing.rs
- tests/window/resizing.rs
- examples/3d/atmospheric_fog.rs
- examples/transforms/translation.rs
- examples/3d/load_gltf_extras.rs
- examples/shader/shader_defs.rs
- examples/3d/3d_scene.rs
- examples/animation/animated_mesh.rs
- examples/games/loading_screen.rs
- examples/shader_advanced/custom_post_processing.rs
- examples/3d/parenting.rs
- examples/animation/animation_graph.rs
- examples/shader/shader_material_screenspace_texture.rs
- examples/3d/depth_of_field.rs
- examples/camera/camera_orbit.rs
- examples/3d/edit_material_on_gltf.rs
- examples/shader/shader_material_bindless.rs
- examples/3d/anisotropy.rs
- examples/remote/server.rs
- examples/animation/animation_masks.rs
- examples/window/screenshot.rs
- examples/3d/animated_material.rs
- examples/camera/custom_projection.rs
- examples/3d/ssr.rs
- examples/3d/load_gltf.rs
- examples/3d/two_passes.rs
- examples/3d/lines.rs
- examples/stress_tests/many_materials.rs
- examples/shader_advanced/render_depth_to_texture.rs
- examples/diagnostics/log_diagnostics.rs
- examples/shader/extended_material_bindless.rs
- examples/3d/skybox.rs
- examples/3d/order_independent_transparency.rs
- examples/3d/tonemapping.rs
- examples/3d/update_gltf_scene.rs
- examples/shader_advanced/custom_render_phase.rs
- examples/3d/atmosphere.rs
- examples/3d/fog_volumes.rs
- examples/shader/storage_buffer.rs
- examples/window/low_power.rs
- examples/3d/generate_custom_mesh.rs
- examples/3d/mesh_ray_cast.rs
- examples/picking/simple_picking.rs
- examples/movement/smooth_follow.rs
- examples/shader/extended_material.rs
- examples/3d/vertex_colors.rs
- examples/shader_advanced/custom_shader_instancing.rs
- tests/window/desktop_request_redraw.rs
- examples/3d/orthographic.rs
- examples/picking/debug_picking.rs
- examples/shader_advanced/specialized_mesh_pipeline.rs
- examples/3d/spherical_area_lights.rs
- examples/transforms/transform.rs
- examples/window/multiple_windows.rs
- examples/gizmos/axes.rs
- examples/3d/ssao.rs
- examples/animation/animated_mesh_events.rs
- examples/app/headless_renderer.rs
- examples/animation/eased_motion.rs
- examples/3d/wireframe.rs
- examples/audio/spatial_audio_3d.rs
- examples/shader/automatic_instancing.rs
- examples/ecs/error_handling.rs
- examples/camera/projection_zoom.rs
- examples/3d/specular_tint.rs
- examples/3d/visibility_range.rs
- examples/3d/volumetric_fog.rs
- examples/animation/animated_mesh_control.rs
- examples/testbed/3d.rs
- tests/3d/test_invalid_skinned_mesh.rs
- examples/stress_tests/many_cameras_lights.rs
- examples/3d/texture.rs
- examples/3d/shadow_caster_receiver.rs
- examples/3d/anti_aliasing.rs
- examples/3d/bloom_3d.rs
- examples/gizmos/3d_gizmos.rs
- examples/transforms/align.rs
- examples/math/random_sampling.rs
- examples/3d/scrolling_fog.rs
- examples/3d/decal.rs
- examples/3d/render_to_texture.rs
- examples/asset/repeated_texture.rs
- examples/ecs/iter_combinations.rs
- examples/asset/alter_mesh.rs
- examples/3d/transparency_3d.rs
- examples/3d/meshlet.rs
- examples/2d/mesh2d_repeated_texture.rs
- examples/gizmos/light_gizmos.rs
- examples/3d/spotlight.rs
- examples/3d/pbr.rs
- examples/3d/3d_shapes.rs
- examples/3d/auto_exposure.rs
- examples/asset/asset_loading.rs
- examples/shader/shader_prepass.rs
- examples/3d/shadow_biases.rs
- examples/3d/split_screen.rs
- examples/picking/mesh_picking.rs
- examples/ui/render_ui_to_texture.rs
- examples/stress_tests/many_foxes.rs
- examples/math/sampling_primitives.rs
- examples/3d/parallax_mapping.rs
- examples/3d/fog.rs
- examples/3d/deferred_rendering.rs
- examples/animation/custom_skinned_mesh.rs
- examples/3d/blend_modes.rs
- examples/stress_tests/many_cubes.rs
- examples/animation/animated_transform.rs
- examples/3d/lighting.rs
- examples/3d/camera_sub_view.rs
- examples/3d/transmission.rs
Sourcepub fn looking_to(
self,
direction: impl TryInto<Dir3>,
up: impl TryInto<Dir3>,
) -> Transform
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 toDir3
(e.g if it isVec3::ZERO
),Dir3::Z
is used instead - if
up
fails converting toDir3
,Dir3::Y
is used instead - if
direction
is parallel withup
, an orthogonal vector is used as the “right” direction
Examples found in repository?
More examples
188fn spawn_environment(
189 mut commands: Commands,
190 mut meshes: ResMut<Assets<Mesh>>,
191 mut materials: ResMut<Assets<StandardMaterial>>,
192) {
193 let sphere_material = materials.add(Color::from(tailwind::SKY_200));
194 let sphere_mesh = meshes.add(Sphere::new(0.3));
195 let spheres_in_x = 6;
196 let spheres_in_y = 4;
197 let spheres_in_z = 10;
198 let distance = 3.0;
199 for x in 0..spheres_in_x {
200 for y in 0..spheres_in_y {
201 for z in 0..spheres_in_z {
202 let translation = Vec3::new(
203 x as f32 * distance - (spheres_in_x as f32 - 1.0) * distance / 2.0,
204 y as f32 * distance - (spheres_in_y as f32 - 1.0) * distance / 2.0,
205 z as f32 * distance - (spheres_in_z as f32 - 1.0) * distance / 2.0,
206 );
207 commands.spawn((
208 Name::new("Sphere"),
209 Transform::from_translation(translation),
210 Mesh3d(sphere_mesh.clone()),
211 MeshMaterial3d(sphere_material.clone()),
212 ));
213 }
214 }
215 }
216
217 commands.spawn((
218 DirectionalLight::default(),
219 Transform::default().looking_to(Vec3::new(-1.0, -3.0, 0.5), Vec3::Y),
220 ));
221}
359 pub fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
360 commands.spawn((
361 Camera3d::default(),
362 Transform::from_xyz(-4.0, 4.0, -5.0).looking_at(Vec3::ZERO, Vec3::Y),
363 DespawnOnExit(CURRENT_SCENE),
364 ));
365
366 commands.spawn((
367 DirectionalLight {
368 color: BLUE.into(),
369 ..default()
370 },
371 Transform::IDENTITY.looking_to(Dir3::Z, Dir3::Y),
372 DespawnOnExit(CURRENT_SCENE),
373 ));
374
375 commands.spawn((
376 DirectionalLight {
377 color: RED.into(),
378 ..default()
379 },
380 Transform::IDENTITY.looking_to(Dir3::X, Dir3::Y),
381 DespawnOnExit(CURRENT_SCENE),
382 ));
383
384 commands.spawn((
385 DirectionalLight {
386 color: GREEN.into(),
387 ..default()
388 },
389 Transform::IDENTITY.looking_to(Dir3::NEG_Y, Dir3::X),
390 DespawnOnExit(CURRENT_SCENE),
391 ));
392
393 commands
394 .spawn((
395 SceneRoot(asset_server.load_with_settings(
396 GltfAssetLabel::Scene(0).from_asset("models/Faces/faces.glb"),
397 |s: &mut GltfLoaderSettings| {
398 s.use_model_forward_direction = Some(true);
399 },
400 )),
401 DespawnOnExit(CURRENT_SCENE),
402 ))
403 .observe(show_aabbs);
404 }
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}
Sourcepub 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
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
ormain_direction
fail converting toDir3
(e.g are zero),Dir3::X
takes their place - if
secondary_axis
orsecondary_direction
fail converting,Dir3::Y
takes their place - if
main_axis
is parallel withsecondary_axis
ormain_direction
is parallel withsecondary_direction
, a rotation is constructed which takesmain_axis
tomain_direction
along a great circle, ignoring the secondary counterparts
See Transform::align
for additional details.
Sourcepub const fn with_translation(self, translation: Vec3) -> Transform
pub const fn with_translation(self, translation: Vec3) -> Transform
Returns this Transform
with a new translation.
Examples found in repository?
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.random::<f32>() - 0.5, rng.random::<f32>() - 0.5)),
23 ));
24 }
25}
More examples
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}
56fn setup_pyramid_scene(
57 mut commands: Commands,
58 mut meshes: ResMut<Assets<Mesh>>,
59 mut materials: ResMut<Assets<StandardMaterial>>,
60) {
61 let stone = materials.add(StandardMaterial {
62 base_color: Srgba::hex("28221B").unwrap().into(),
63 perceptual_roughness: 1.0,
64 ..default()
65 });
66
67 // pillars
68 for (x, z) in &[(-1.5, -1.5), (1.5, -1.5), (1.5, 1.5), (-1.5, 1.5)] {
69 commands.spawn((
70 Mesh3d(meshes.add(Cuboid::new(1.0, 3.0, 1.0))),
71 MeshMaterial3d(stone.clone()),
72 Transform::from_xyz(*x, 1.5, *z),
73 ));
74 }
75
76 // orb
77 commands.spawn((
78 Mesh3d(meshes.add(Sphere::default())),
79 MeshMaterial3d(materials.add(StandardMaterial {
80 base_color: Srgba::hex("126212CC").unwrap().into(),
81 reflectance: 1.0,
82 perceptual_roughness: 0.0,
83 metallic: 0.5,
84 alpha_mode: AlphaMode::Blend,
85 ..default()
86 })),
87 Transform::from_scale(Vec3::splat(1.75)).with_translation(Vec3::new(0.0, 4.0, 0.0)),
88 NotShadowCaster,
89 NotShadowReceiver,
90 ));
91
92 // steps
93 for i in 0..50 {
94 let half_size = i as f32 / 2.0 + 3.0;
95 let y = -i as f32 / 2.0;
96 commands.spawn((
97 Mesh3d(meshes.add(Cuboid::new(2.0 * half_size, 0.5, 2.0 * half_size))),
98 MeshMaterial3d(stone.clone()),
99 Transform::from_xyz(0.0, y + 0.25, 0.0),
100 ));
101 }
102
103 // sky
104 commands.spawn((
105 Mesh3d(meshes.add(Cuboid::new(2.0, 1.0, 1.0))),
106 MeshMaterial3d(materials.add(StandardMaterial {
107 base_color: Srgba::hex("888888").unwrap().into(),
108 unlit: true,
109 cull_mode: None,
110 ..default()
111 })),
112 Transform::from_scale(Vec3::splat(1_000_000.0)),
113 ));
114
115 // light
116 commands.spawn((
117 PointLight {
118 shadows_enabled: true,
119 ..default()
120 },
121 Transform::from_xyz(0.0, 1.0, 0.0),
122 ));
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: px(12),
98 left: px(12),
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}
525fn create_cubes(
526 image_assets: Res<Assets<Image>>,
527 mut commands: Commands,
528 irradiance_volumes: Query<(&IrradianceVolume, &GlobalTransform)>,
529 voxel_cube_parents: Query<Entity, With<VoxelCubeParent>>,
530 voxel_cubes: Query<Entity, With<VoxelCube>>,
531 example_assets: Res<ExampleAssets>,
532 mut voxel_visualization_material_assets: ResMut<Assets<VoxelVisualizationMaterial>>,
533) {
534 // If voxel cubes have already been spawned, don't do anything.
535 if !voxel_cubes.is_empty() {
536 return;
537 }
538
539 let Some(voxel_cube_parent) = voxel_cube_parents.iter().next() else {
540 return;
541 };
542
543 for (irradiance_volume, global_transform) in irradiance_volumes.iter() {
544 let Some(image) = image_assets.get(&irradiance_volume.voxels) else {
545 continue;
546 };
547
548 let resolution = image.texture_descriptor.size;
549
550 let voxel_cube_material = voxel_visualization_material_assets.add(ExtendedMaterial {
551 base: StandardMaterial::from(Color::from(RED)),
552 extension: VoxelVisualizationExtension {
553 irradiance_volume_info: VoxelVisualizationIrradianceVolumeInfo {
554 world_from_voxel: VOXEL_FROM_WORLD.inverse(),
555 voxel_from_world: VOXEL_FROM_WORLD,
556 resolution: uvec3(
557 resolution.width,
558 resolution.height,
559 resolution.depth_or_array_layers,
560 ),
561 intensity: IRRADIANCE_VOLUME_INTENSITY,
562 },
563 },
564 });
565
566 let scale = vec3(
567 1.0 / resolution.width as f32,
568 1.0 / resolution.height as f32,
569 1.0 / resolution.depth_or_array_layers as f32,
570 );
571
572 // Spawn a cube for each voxel.
573 for z in 0..resolution.depth_or_array_layers {
574 for y in 0..resolution.height {
575 for x in 0..resolution.width {
576 let uvw = (uvec3(x, y, z).as_vec3() + 0.5) * scale - 0.5;
577 let pos = global_transform.transform_point(uvw);
578 let voxel_cube = commands
579 .spawn((
580 Mesh3d(example_assets.voxel_cube.clone()),
581 MeshMaterial3d(voxel_cube_material.clone()),
582 Transform::from_scale(Vec3::splat(VOXEL_CUBE_SCALE))
583 .with_translation(pos),
584 ))
585 .insert(VoxelCube)
586 .insert(NotShadowCaster)
587 .id();
588
589 commands.entity(voxel_cube_parent).add_child(voxel_cube);
590 }
591 }
592 }
593 }
594}
35fn setup(
36 mut commands: Commands,
37 asset_server: Res<AssetServer>,
38 mut standard_materials: ResMut<Assets<StandardMaterial>>,
39 mut debug_materials: ResMut<Assets<MeshletDebugMaterial>>,
40 mut meshes: ResMut<Assets<Mesh>>,
41) {
42 commands.spawn((
43 Camera3d::default(),
44 Transform::from_translation(Vec3::new(1.8, 0.4, -0.1)).looking_at(Vec3::ZERO, Vec3::Y),
45 Msaa::Off,
46 EnvironmentMapLight {
47 diffuse_map: asset_server.load("environment_maps/pisa_diffuse_rgb9e5_zstd.ktx2"),
48 specular_map: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
49 intensity: 150.0,
50 ..default()
51 },
52 CameraController::default(),
53 ));
54
55 commands.spawn((
56 DirectionalLight {
57 illuminance: light_consts::lux::FULL_DAYLIGHT,
58 shadows_enabled: true,
59 ..default()
60 },
61 CascadeShadowConfigBuilder {
62 num_cascades: 1,
63 maximum_distance: 15.0,
64 ..default()
65 }
66 .build(),
67 Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, PI * -0.15, PI * -0.15)),
68 ));
69
70 // A custom file format storing a [`bevy_mesh::Mesh`]
71 // that has been converted to a [`bevy_pbr::meshlet::MeshletMesh`]
72 // using [`bevy_pbr::meshlet::MeshletMesh::from_mesh`], which is
73 // a function only available when the `meshlet_processor` cargo feature is enabled.
74 let meshlet_mesh_handle = asset_server.load(ASSET_URL);
75 let debug_material = debug_materials.add(MeshletDebugMaterial::default());
76
77 for x in -2..=2 {
78 commands.spawn((
79 MeshletMesh3d(meshlet_mesh_handle.clone()),
80 MeshMaterial3d(standard_materials.add(StandardMaterial {
81 base_color: match x {
82 -2 => Srgba::hex("#dc2626").unwrap().into(),
83 -1 => Srgba::hex("#ea580c").unwrap().into(),
84 0 => Srgba::hex("#facc15").unwrap().into(),
85 1 => Srgba::hex("#16a34a").unwrap().into(),
86 2 => Srgba::hex("#0284c7").unwrap().into(),
87 _ => unreachable!(),
88 },
89 perceptual_roughness: (x + 2) as f32 / 4.0,
90 ..default()
91 })),
92 Transform::default()
93 .with_scale(Vec3::splat(0.2))
94 .with_translation(Vec3::new(x as f32 / 2.0, 0.0, -0.3)),
95 ));
96 }
97 for x in -2..=2 {
98 commands.spawn((
99 MeshletMesh3d(meshlet_mesh_handle.clone()),
100 MeshMaterial3d(debug_material.clone()),
101 Transform::default()
102 .with_scale(Vec3::splat(0.2))
103 .with_rotation(Quat::from_rotation_y(PI))
104 .with_translation(Vec3::new(x as f32 / 2.0, 0.0, 0.3)),
105 ));
106 }
107
108 commands.spawn((
109 Mesh3d(meshes.add(Plane3d::default().mesh().size(5.0, 5.0))),
110 MeshMaterial3d(standard_materials.add(StandardMaterial {
111 base_color: Color::WHITE,
112 perceptual_roughness: 1.0,
113 ..default()
114 })),
115 ));
116}
Sourcepub const fn with_rotation(self, rotation: Quat) -> Transform
pub const fn with_rotation(self, rotation: Quat) -> Transform
Returns this Transform
with a new rotation.
Examples found in repository?
89fn spawn_scene(commands: &mut Commands, asset_server: &AssetServer) {
90 // Spawn the main scene.
91 commands.spawn(SceneRoot(asset_server.load(
92 GltfAssetLabel::Scene(0).from_asset("models/TonemappingTest/TonemappingTest.gltf"),
93 )));
94
95 // Spawn the flight helmet.
96 commands.spawn((
97 SceneRoot(
98 asset_server
99 .load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
100 ),
101 Transform::from_xyz(0.5, 0.0, -0.5).with_rotation(Quat::from_rotation_y(-0.15 * PI)),
102 ));
103
104 // Spawn the light.
105 commands.spawn((
106 DirectionalLight {
107 illuminance: 15000.0,
108 shadows_enabled: true,
109 ..default()
110 },
111 Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, PI * -0.15, PI * -0.15)),
112 CascadeShadowConfigBuilder {
113 maximum_distance: 3.0,
114 first_cascade_far_bound: 0.9,
115 ..default()
116 }
117 .build(),
118 ));
119}
More examples
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}
344fn add_basic_scene(commands: &mut Commands, asset_server: &AssetServer) {
345 // Spawn the main scene.
346 commands.spawn(SceneRoot(asset_server.load(
347 GltfAssetLabel::Scene(0).from_asset("models/TonemappingTest/TonemappingTest.gltf"),
348 )));
349
350 // Spawn the flight helmet.
351 commands.spawn((
352 SceneRoot(
353 asset_server
354 .load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
355 ),
356 Transform::from_xyz(0.5, 0.0, -0.5).with_rotation(Quat::from_rotation_y(-0.15 * PI)),
357 ));
358
359 // Spawn the light.
360 commands.spawn((
361 DirectionalLight {
362 illuminance: 15000.0,
363 shadows_enabled: true,
364 ..default()
365 },
366 Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, PI * -0.15, PI * -0.15)),
367 CascadeShadowConfigBuilder {
368 maximum_distance: 3.0,
369 first_cascade_far_bound: 0.9,
370 ..default()
371 }
372 .build(),
373 ));
374}
99fn setup_basic_scene(mut commands: Commands, asset_server: Res<AssetServer>) {
100 // Main scene
101 commands.spawn((
102 SceneRoot(asset_server.load(
103 GltfAssetLabel::Scene(0).from_asset("models/TonemappingTest/TonemappingTest.gltf"),
104 )),
105 SceneNumber(1),
106 ));
107
108 // Flight Helmet
109 commands.spawn((
110 SceneRoot(
111 asset_server
112 .load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
113 ),
114 Transform::from_xyz(0.5, 0.0, -0.5).with_rotation(Quat::from_rotation_y(-0.15 * PI)),
115 SceneNumber(1),
116 ));
117
118 // light
119 commands.spawn((
120 DirectionalLight {
121 illuminance: 15_000.,
122 shadows_enabled: true,
123 ..default()
124 },
125 Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, PI * -0.15, PI * -0.15)),
126 CascadeShadowConfigBuilder {
127 maximum_distance: 3.0,
128 first_cascade_far_bound: 0.9,
129 ..default()
130 }
131 .build(),
132 SceneNumber(1),
133 ));
134}
62fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
63 // directional 'sun' light
64 commands.spawn((
65 DirectionalLight {
66 illuminance: 32000.0,
67 ..default()
68 },
69 Transform::from_xyz(0.0, 2.0, 0.0).with_rotation(Quat::from_rotation_x(-PI / 4.)),
70 ));
71
72 let skybox_handle = asset_server.load(CUBEMAPS[0].0);
73 // camera
74 commands.spawn((
75 Camera3d::default(),
76 Msaa::Off,
77 TemporalAntiAliasing::default(),
78 ScreenSpaceAmbientOcclusion::default(),
79 Transform::from_xyz(0.0, 0.0, 8.0).looking_at(Vec3::ZERO, Vec3::Y),
80 CameraController::default(),
81 Skybox {
82 image: skybox_handle.clone(),
83 brightness: 1000.0,
84 ..default()
85 },
86 ));
87
88 // ambient light
89 // NOTE: The ambient light is used to scale how bright the environment map is so with a bright
90 // environment map, use an appropriate color and brightness to match
91 commands.insert_resource(AmbientLight {
92 color: Color::srgb_u8(210, 220, 240),
93 brightness: 1.0,
94 ..default()
95 });
96
97 commands.insert_resource(Cubemap {
98 is_loaded: false,
99 index: 0,
100 image_handle: skybox_handle,
101 });
102}
71fn setup(
72 mut commands: Commands,
73 mut meshes: ResMut<Assets<Mesh>>,
74 mut materials: ResMut<Assets<StandardMaterial>>,
75) {
76 // Make a box of planes facing inward so the laser gets trapped inside
77 let plane_mesh = meshes.add(Plane3d::default());
78 let plane_material = materials.add(Color::from(css::GRAY).with_alpha(0.01));
79 let create_plane = move |translation, rotation| {
80 (
81 Transform::from_translation(translation)
82 .with_rotation(Quat::from_scaled_axis(rotation)),
83 Mesh3d(plane_mesh.clone()),
84 MeshMaterial3d(plane_material.clone()),
85 )
86 };
87
88 commands.spawn(create_plane(vec3(0.0, 0.5, 0.0), Vec3::X * PI));
89 commands.spawn(create_plane(vec3(0.0, -0.5, 0.0), Vec3::ZERO));
90 commands.spawn(create_plane(vec3(0.5, 0.0, 0.0), Vec3::Z * FRAC_PI_2));
91 commands.spawn(create_plane(vec3(-0.5, 0.0, 0.0), Vec3::Z * -FRAC_PI_2));
92 commands.spawn(create_plane(vec3(0.0, 0.0, 0.5), Vec3::X * -FRAC_PI_2));
93 commands.spawn(create_plane(vec3(0.0, 0.0, -0.5), Vec3::X * FRAC_PI_2));
94
95 // Light
96 commands.spawn((
97 DirectionalLight::default(),
98 Transform::from_rotation(Quat::from_euler(EulerRot::XYZ, -0.1, 0.2, 0.0)),
99 ));
100
101 // Camera
102 commands.spawn((
103 Camera3d::default(),
104 Transform::from_xyz(1.5, 1.5, 1.5).looking_at(Vec3::ZERO, Vec3::Y),
105 Tonemapping::TonyMcMapface,
106 Bloom::default(),
107 ));
108}
- examples/testbed/2d.rs
- examples/transforms/transform.rs
- examples/math/custom_primitives.rs
- examples/3d/atmosphere.rs
- examples/3d/texture.rs
- examples/3d/motion_blur.rs
- examples/picking/sprite_picking.rs
- examples/3d/decal.rs
- examples/3d/render_to_texture.rs
- examples/3d/meshlet.rs
- examples/3d/3d_shapes.rs
- examples/3d/solari.rs
- examples/picking/mesh_picking.rs
- examples/ui/render_ui_to_texture.rs
- examples/stress_tests/many_foxes.rs
- examples/3d/transmission.rs
Sourcepub const fn with_scale(self, scale: Vec3) -> Transform
pub const fn with_scale(self, scale: Vec3) -> Transform
Returns this Transform
with a new scale.
Examples found in repository?
More examples
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}
70fn setup_mesh(
71 mut commands: Commands,
72 mut meshes: ResMut<Assets<Mesh>>,
73 mut materials: ResMut<Assets<ColorMaterial>>,
74) {
75 commands.spawn((
76 Mesh2d(meshes.add(Capsule2d::default())),
77 MeshMaterial2d(materials.add(Color::BLACK)),
78 Transform::from_xyz(25., 0., 2.).with_scale(Vec3::splat(32.)),
79 Rotate,
80 PIXEL_PERFECT_LAYERS,
81 ));
82}
25fn setup(
26 mut commands: Commands,
27 mut meshes: ResMut<Assets<Mesh>>,
28 mut materials: ResMut<Assets<CustomMaterial>>,
29 asset_server: Res<AssetServer>,
30) {
31 // camera
32 commands.spawn(Camera2d);
33
34 // quad
35 commands.spawn((
36 Mesh2d(meshes.add(Rectangle::default())),
37 MeshMaterial2d(materials.add(CustomMaterial {
38 color: LinearRgba::BLUE,
39 color_texture: Some(asset_server.load("branding/icon.png")),
40 })),
41 Transform::default().with_scale(Vec3::splat(128.)),
42 ));
43}
196fn spawn_plane(
197 commands: &mut Commands,
198 meshes: &mut Assets<Mesh>,
199 show_depth_texture_materials: &mut Assets<ShowDepthTextureMaterial>,
200 demo_depth_texture: &DemoDepthTexture,
201) {
202 let plane_handle = meshes.add(Plane3d::new(Vec3::Z, Vec2::splat(2.0)));
203 let show_depth_texture_material = show_depth_texture_materials.add(ShowDepthTextureMaterial {
204 depth_texture: Some(demo_depth_texture.0.clone()),
205 });
206 commands.spawn((
207 Mesh3d(plane_handle),
208 MeshMaterial3d(show_depth_texture_material),
209 Transform::from_xyz(10.0, 4.0, 0.0).with_scale(Vec3::splat(2.5)),
210 ));
211}
- examples/3d/rotate_environment_map.rs
- examples/stress_tests/bevymark.rs
- examples/3d/clearcoat.rs
- examples/testbed/3d.rs
- examples/2d/mesh2d_vertex_color_texture.rs
- examples/ecs/hierarchy.rs
- examples/math/sampling_primitives.rs
- examples/testbed/2d.rs
- examples/3d/spherical_area_lights.rs
- examples/3d/motion_blur.rs
- examples/3d/light_textures.rs
- examples/camera/projection_zoom.rs
- examples/3d/atmosphere.rs
- examples/3d/bloom_3d.rs
- examples/picking/sprite_picking.rs
- examples/3d/scrolling_fog.rs
- examples/3d/meshlet.rs
- examples/gizmos/3d_gizmos.rs
- examples/games/breakout.rs
- examples/stress_tests/many_foxes.rs
- examples/games/desk_toy.rs
- examples/3d/transmission.rs
Sourcepub fn to_matrix(&self) -> Mat4
pub fn to_matrix(&self) -> Mat4
Computes the 3d affine transformation matrix from this transform’s translation, rotation, and scale.
Sourcepub fn compute_affine(&self) -> Affine3A
pub fn compute_affine(&self) -> Affine3A
Returns the 3d affine transformation matrix from this transforms translation, rotation, and scale.
Sourcepub fn left(&self) -> Dir3
pub fn left(&self) -> Dir3
Equivalent to -local_x()
Sourcepub fn right(&self) -> Dir3
pub fn right(&self) -> Dir3
Equivalent to local_x()
Examples found in repository?
More examples
127fn run_camera_controller(
128 time: Res<Time<Real>>,
129 mut windows: Query<(&Window, &mut CursorOptions)>,
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 // Update velocity
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
217 // Apply movement update
218 if controller.velocity != Vec3::ZERO {
219 let forward = *transform.forward();
220 let right = *transform.right();
221 transform.translation += controller.velocity.x * dt * right
222 + controller.velocity.y * dt * Vec3::Y
223 + controller.velocity.z * dt * forward;
224 }
225
226 // Handle cursor grab
227 if cursor_grab_change {
228 if cursor_grab {
229 for (window, mut cursor_options) in &mut windows {
230 if !window.focused {
231 continue;
232 }
233
234 cursor_options.grab_mode = CursorGrabMode::Locked;
235 cursor_options.visible = false;
236 }
237 } else {
238 for (_, mut cursor_options) in &mut windows {
239 cursor_options.grab_mode = CursorGrabMode::None;
240 cursor_options.visible = true;
241 }
242 }
243 }
244
245 // Handle mouse input
246 if accumulated_mouse_motion.delta != Vec2::ZERO && cursor_grab {
247 // Apply look update
248 controller.pitch = (controller.pitch
249 - accumulated_mouse_motion.delta.y * RADIANS_PER_DOT * controller.sensitivity)
250 .clamp(-PI / 2., PI / 2.);
251 controller.yaw -=
252 accumulated_mouse_motion.delta.x * RADIANS_PER_DOT * controller.sensitivity;
253 transform.rotation = Quat::from_euler(EulerRot::ZYX, 0.0, controller.yaw, controller.pitch);
254 }
255}
Sourcepub fn local_y(&self) -> Dir3
pub fn local_y(&self) -> Dir3
Get the unit vector in the local Y
direction.
Examples found in repository?
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 ¢er_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 at 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}
Sourcepub fn down(&self) -> Dir3
pub fn down(&self) -> Dir3
Equivalent to -local_y()
Sourcepub fn local_z(&self) -> Dir3
pub fn local_z(&self) -> Dir3
Get the unit vector in the local Z
direction.
Examples found in repository?
300fn move_camera(
301 keyboard_input: Res<ButtonInput<KeyCode>>,
302 mut mouse_wheel_reader: MessageReader<MouseWheel>,
303 mut cameras: Query<&mut Transform, With<Camera>>,
304) {
305 let (mut distance_delta, mut theta_delta) = (0.0, 0.0);
306
307 // Handle keyboard events.
308 if keyboard_input.pressed(KeyCode::KeyW) {
309 distance_delta -= CAMERA_KEYBOARD_ZOOM_SPEED;
310 }
311 if keyboard_input.pressed(KeyCode::KeyS) {
312 distance_delta += CAMERA_KEYBOARD_ZOOM_SPEED;
313 }
314 if keyboard_input.pressed(KeyCode::KeyA) {
315 theta_delta += CAMERA_KEYBOARD_ORBIT_SPEED;
316 }
317 if keyboard_input.pressed(KeyCode::KeyD) {
318 theta_delta -= CAMERA_KEYBOARD_ORBIT_SPEED;
319 }
320
321 // Handle mouse events.
322 for mouse_wheel in mouse_wheel_reader.read() {
323 distance_delta -= mouse_wheel.y * CAMERA_MOUSE_WHEEL_ZOOM_SPEED;
324 }
325
326 // Update transforms.
327 for mut camera_transform in cameras.iter_mut() {
328 let local_z = camera_transform.local_z().as_vec3().normalize_or_zero();
329 if distance_delta != 0.0 {
330 camera_transform.translation = (camera_transform.translation.length() + distance_delta)
331 .clamp(CAMERA_ZOOM_RANGE.start, CAMERA_ZOOM_RANGE.end)
332 * local_z;
333 }
334 if theta_delta != 0.0 {
335 camera_transform
336 .translate_around(Vec3::ZERO, Quat::from_axis_angle(Vec3::Y, theta_delta));
337 camera_transform.look_at(Vec3::ZERO, Vec3::Y);
338 }
339 }
340}
Sourcepub fn forward(&self) -> Dir3
pub fn forward(&self) -> Dir3
Equivalent to -local_z()
Examples found in repository?
More examples
136fn setup_color_gradient_scene(
137 mut commands: Commands,
138 mut meshes: ResMut<Assets<Mesh>>,
139 mut materials: ResMut<Assets<ColorGradientMaterial>>,
140 camera_transform: Res<CameraTransform>,
141) {
142 let mut transform = camera_transform.0;
143 transform.translation += *transform.forward();
144
145 commands.spawn((
146 Mesh3d(meshes.add(Rectangle::new(0.7, 0.7))),
147 MeshMaterial3d(materials.add(ColorGradientMaterial {})),
148 transform,
149 Visibility::Hidden,
150 SceneNumber(2),
151 ));
152}
153
154fn setup_image_viewer_scene(
155 mut commands: Commands,
156 mut meshes: ResMut<Assets<Mesh>>,
157 mut materials: ResMut<Assets<StandardMaterial>>,
158 camera_transform: Res<CameraTransform>,
159) {
160 let mut transform = camera_transform.0;
161 transform.translation += *transform.forward();
162
163 // exr/hdr viewer (exr requires enabling bevy feature)
164 commands.spawn((
165 Mesh3d(meshes.add(Rectangle::default())),
166 MeshMaterial3d(materials.add(StandardMaterial {
167 base_color_texture: None,
168 unlit: true,
169 ..default()
170 })),
171 transform,
172 Visibility::Hidden,
173 SceneNumber(3),
174 HDRViewer,
175 ));
176
177 commands.spawn((
178 Text::new("Drag and drop an HDR or EXR file"),
179 TextFont {
180 font_size: 36.0,
181 ..default()
182 },
183 TextColor(Color::BLACK),
184 TextLayout::new_with_justify(Justify::Center),
185 Node {
186 align_self: AlignSelf::Center,
187 margin: UiRect::all(auto()),
188 ..default()
189 },
190 SceneNumber(3),
191 Visibility::Hidden,
192 ));
193}
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}
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}
127fn run_camera_controller(
128 time: Res<Time<Real>>,
129 mut windows: Query<(&Window, &mut CursorOptions)>,
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 // Update velocity
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
217 // Apply movement update
218 if controller.velocity != Vec3::ZERO {
219 let forward = *transform.forward();
220 let right = *transform.right();
221 transform.translation += controller.velocity.x * dt * right
222 + controller.velocity.y * dt * Vec3::Y
223 + controller.velocity.z * dt * forward;
224 }
225
226 // Handle cursor grab
227 if cursor_grab_change {
228 if cursor_grab {
229 for (window, mut cursor_options) in &mut windows {
230 if !window.focused {
231 continue;
232 }
233
234 cursor_options.grab_mode = CursorGrabMode::Locked;
235 cursor_options.visible = false;
236 }
237 } else {
238 for (_, mut cursor_options) in &mut windows {
239 cursor_options.grab_mode = CursorGrabMode::None;
240 cursor_options.visible = true;
241 }
242 }
243 }
244
245 // Handle mouse input
246 if accumulated_mouse_motion.delta != Vec2::ZERO && cursor_grab {
247 // Apply look update
248 controller.pitch = (controller.pitch
249 - accumulated_mouse_motion.delta.y * RADIANS_PER_DOT * controller.sensitivity)
250 .clamp(-PI / 2., PI / 2.);
251 controller.yaw -=
252 accumulated_mouse_motion.delta.x * RADIANS_PER_DOT * controller.sensitivity;
253 transform.rotation = Quat::from_euler(EulerRot::ZYX, 0.0, controller.yaw, controller.pitch);
254 }
255}
Sourcepub fn back(&self) -> Dir3
pub fn back(&self) -> Dir3
Equivalent to local_z()
Examples found in repository?
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}
Sourcepub fn rotate(&mut self, rotation: Quat)
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?
More examples
73fn update(
74 time: Res<Time>,
75 mut query: Query<(&MeshMaterial3d<CustomMaterial>, &mut Transform)>,
76 mut materials: ResMut<Assets<CustomMaterial>>,
77 keys: Res<ButtonInput<KeyCode>>,
78) {
79 for (material, mut transform) in query.iter_mut() {
80 let material = materials.get_mut(material).unwrap();
81 material.time.x = time.elapsed_secs();
82 if keys.just_pressed(KeyCode::Space) {
83 material.party_mode = !material.party_mode;
84 }
85
86 if material.party_mode {
87 transform.rotate(Quat::from_rotation_y(0.005));
88 }
89 }
90}
589fn flicker_system(
590 mut flame: Single<&mut Transform, (With<Flicker>, With<Mesh3d>)>,
591 light: Single<(&mut PointLight, &mut Transform), (With<Flicker>, Without<Mesh3d>)>,
592 time: Res<Time>,
593) {
594 let s = time.elapsed_secs();
595 let a = ops::cos(s * 6.0) * 0.0125 + ops::cos(s * 4.0) * 0.025;
596 let b = ops::cos(s * 5.0) * 0.0125 + ops::cos(s * 3.0) * 0.025;
597 let c = ops::cos(s * 7.0) * 0.0125 + ops::cos(s * 2.0) * 0.025;
598 let (mut light, mut light_transform) = light.into_inner();
599 light.intensity = 4_000.0 + 3000.0 * (a + b + c);
600 flame.translation = Vec3::new(-1.0, 1.23, 0.0);
601 flame.look_at(Vec3::new(-1.0 - c, 1.7 - b, 0.0 - a), Vec3::X);
602 flame.rotate(Quat::from_euler(EulerRot::XYZ, 0.0, 0.0, PI / 2.0));
603 light_transform.translation = Vec3::new(-1.0 - c, 1.7, 0.0 - a);
604 flame.translation = Vec3::new(-1.0 - c, 1.23, 0.0 - a);
605}
167fn move_directional_light(
168 input: Res<ButtonInput<KeyCode>>,
169 mut directional_lights: Query<&mut Transform, With<DirectionalLight>>,
170) {
171 let mut delta_theta = Vec2::ZERO;
172 if input.pressed(KeyCode::KeyW) || input.pressed(KeyCode::ArrowUp) {
173 delta_theta.y += DIRECTIONAL_LIGHT_MOVEMENT_SPEED;
174 }
175 if input.pressed(KeyCode::KeyS) || input.pressed(KeyCode::ArrowDown) {
176 delta_theta.y -= DIRECTIONAL_LIGHT_MOVEMENT_SPEED;
177 }
178 if input.pressed(KeyCode::KeyA) || input.pressed(KeyCode::ArrowLeft) {
179 delta_theta.x += DIRECTIONAL_LIGHT_MOVEMENT_SPEED;
180 }
181 if input.pressed(KeyCode::KeyD) || input.pressed(KeyCode::ArrowRight) {
182 delta_theta.x -= DIRECTIONAL_LIGHT_MOVEMENT_SPEED;
183 }
184
185 if delta_theta == Vec2::ZERO {
186 return;
187 }
188
189 let delta_quat = Quat::from_euler(EulerRot::XZY, delta_theta.y, 0.0, delta_theta.x);
190 for mut transform in directional_lights.iter_mut() {
191 transform.rotate(delta_quat);
192 }
193}
Sourcepub fn rotate_axis(&mut self, axis: Dir3, angle: f32)
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?
136fn track_targets(
137 // `Single` ensures the system runs ONLY when exactly one matching entity exists.
138 mut player: Single<(&mut Transform, &Player)>,
139 // `Option<Single>` never prevents the system from running, but will be `None` if there is not exactly one matching entity.
140 enemy: Option<Single<&Transform, (With<Enemy>, Without<Player>)>>,
141 time: Res<Time>,
142) {
143 let (player_transform, player) = &mut *player;
144 if let Some(enemy_transform) = enemy {
145 // Enemy found, rotate and move towards it.
146 let delta = enemy_transform.translation - player_transform.translation;
147 let distance = delta.length();
148 let front = delta / distance;
149 let up = Vec3::Z;
150 let side = front.cross(up);
151 player_transform.rotation = Quat::from_mat3(&Mat3::from_cols(side, front, up));
152 let max_step = distance - player.min_follow_radius;
153 if 0.0 < max_step {
154 let velocity = (player.speed * time.delta_secs()).min(max_step);
155 player_transform.translation += front * velocity;
156 }
157 } else {
158 // 0 or multiple enemies found, keep searching.
159 player_transform.rotate_axis(Dir3::Z, player.rotation_speed * time.delta_secs());
160 }
161}
Sourcepub fn rotate_x(&mut self, angle: f32)
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?
More examples
- examples/3d/render_to_texture.rs
- examples/picking/debug_picking.rs
- examples/picking/simple_picking.rs
- examples/ui/render_ui_to_texture.rs
- examples/shader_advanced/render_depth_to_texture.rs
- examples/window/low_power.rs
- examples/ui/viewport_node.rs
- examples/stress_tests/many_cubes.rs
- examples/3d/generate_custom_mesh.rs
- examples/3d/lighting.rs
Sourcepub fn rotate_y(&mut self, angle: f32)
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?
More examples
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: On<Pointer<Drag>>, mut transforms: Query<&mut Transform>) {
194 let mut transform = transforms.get_mut(drag.entity).unwrap();
195 transform.rotate_y(drag.delta.x * 0.02);
196 transform.rotate_x(drag.delta.y * 0.02);
197}
- examples/3d/render_to_texture.rs
- examples/picking/debug_picking.rs
- examples/picking/simple_picking.rs
- examples/ui/render_ui_to_texture.rs
- examples/3d/deferred_rendering.rs
- examples/shader_advanced/render_depth_to_texture.rs
- examples/ui/viewport_node.rs
- examples/games/alien_cake_addict.rs
- examples/stress_tests/many_foxes.rs
- examples/transforms/3d_rotation.rs
- examples/3d/clustered_decals.rs
- examples/3d/light_textures.rs
- examples/3d/generate_custom_mesh.rs
- examples/3d/lighting.rs
Sourcepub fn rotate_z(&mut self, angle: f32)
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?
More examples
Sourcepub fn rotate_local(&mut self, rotation: Quat)
pub fn rotate_local(&mut self, rotation: Quat)
Sourcepub fn rotate_local_axis(&mut self, axis: Dir3, angle: f32)
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.
Sourcepub fn rotate_local_x(&mut self, angle: f32)
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?
More examples
Sourcepub fn rotate_local_y(&mut self, angle: f32)
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?
More examples
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}
Sourcepub fn rotate_local_z(&mut self, angle: f32)
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?
More examples
Sourcepub fn translate_around(&mut self, point: Vec3, rotation: Quat)
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?
300fn move_camera(
301 keyboard_input: Res<ButtonInput<KeyCode>>,
302 mut mouse_wheel_reader: MessageReader<MouseWheel>,
303 mut cameras: Query<&mut Transform, With<Camera>>,
304) {
305 let (mut distance_delta, mut theta_delta) = (0.0, 0.0);
306
307 // Handle keyboard events.
308 if keyboard_input.pressed(KeyCode::KeyW) {
309 distance_delta -= CAMERA_KEYBOARD_ZOOM_SPEED;
310 }
311 if keyboard_input.pressed(KeyCode::KeyS) {
312 distance_delta += CAMERA_KEYBOARD_ZOOM_SPEED;
313 }
314 if keyboard_input.pressed(KeyCode::KeyA) {
315 theta_delta += CAMERA_KEYBOARD_ORBIT_SPEED;
316 }
317 if keyboard_input.pressed(KeyCode::KeyD) {
318 theta_delta -= CAMERA_KEYBOARD_ORBIT_SPEED;
319 }
320
321 // Handle mouse events.
322 for mouse_wheel in mouse_wheel_reader.read() {
323 distance_delta -= mouse_wheel.y * CAMERA_MOUSE_WHEEL_ZOOM_SPEED;
324 }
325
326 // Update transforms.
327 for mut camera_transform in cameras.iter_mut() {
328 let local_z = camera_transform.local_z().as_vec3().normalize_or_zero();
329 if distance_delta != 0.0 {
330 camera_transform.translation = (camera_transform.translation.length() + distance_delta)
331 .clamp(CAMERA_ZOOM_RANGE.start, CAMERA_ZOOM_RANGE.end)
332 * local_z;
333 }
334 if theta_delta != 0.0 {
335 camera_transform
336 .translate_around(Vec3::ZERO, Quat::from_axis_angle(Vec3::Y, theta_delta));
337 camera_transform.look_at(Vec3::ZERO, Vec3::Y);
338 }
339 }
340}
Sourcepub fn rotate_around(&mut self, point: Vec3, rotation: Quat)
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?
More examples
188fn rotation(
189 mut transform: Single<&mut Transform, With<Camera>>,
190 input: Res<ButtonInput<KeyCode>>,
191 time: Res<Time>,
192) {
193 let delta = time.delta_secs();
194
195 if input.pressed(KeyCode::ArrowLeft) {
196 transform.rotate_around(Vec3::ZERO, Quat::from_rotation_y(delta));
197 } else if input.pressed(KeyCode::ArrowRight) {
198 transform.rotate_around(Vec3::ZERO, Quat::from_rotation_y(-delta));
199 }
200}
191fn handle_mouse(
192 accumulated_mouse_motion: Res<AccumulatedMouseMotion>,
193 mut mouse_button_inputs: MessageReader<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 mouse_button_input in mouse_button_inputs.read() {
199 if mouse_button_input.button != MouseButton::Left {
200 continue;
201 }
202 *mouse_pressed = MousePressed(mouse_button_input.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}
221fn handle_mouse(
222 accumulated_mouse_motion: Res<AccumulatedMouseMotion>,
223 mut mouse_button_inputs: MessageReader<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 mouse_button_input in mouse_button_inputs.read() {
229 if mouse_button_input.button != MouseButton::Left {
230 continue;
231 }
232 *mouse_pressed = MousePressed(mouse_button_input.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}
Sourcepub fn look_at(&mut self, target: Vec3, up: impl TryInto<Dir3>)
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 toDir3
(e.g if it isVec3::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?
More examples
230fn animate_light(
231 mut lights: Query<&mut Transform, Or<(With<PointLight>, With<DirectionalLight>)>>,
232 time: Res<Time>,
233) {
234 let now = time.elapsed_secs();
235 for mut transform in lights.iter_mut() {
236 transform.translation = vec3(
237 ops::sin(now * 1.4),
238 ops::cos(now * 1.0),
239 ops::cos(now * 0.6),
240 ) * vec3(3.0, 4.0, 3.0);
241 transform.look_at(Vec3::ZERO, Vec3::Y);
242 }
243}
337fn rotate_camera(
338 time: Res<Time>,
339 mut camera_query: Query<&mut Transform, With<Camera3d>>,
340 app_status: Res<AppStatus>,
341) {
342 if !app_status.rotating {
343 return;
344 }
345
346 for mut transform in camera_query.iter_mut() {
347 transform.translation = Vec2::from_angle(time.delta_secs() * PI / 5.0)
348 .rotate(transform.translation.xz())
349 .extend(transform.translation.y)
350 .xzy();
351 transform.look_at(Vec3::ZERO, Vec3::Y);
352 }
353}
Sourcepub fn look_to(&mut self, direction: impl TryInto<Dir3>, up: impl TryInto<Dir3>)
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 toDir3
(e.g if it isVec3::ZERO
),Dir3::NEG_Z
is used instead - if
up
fails converting toDir3
,Dir3::Y
is used instead - if
direction
is parallel withup
, an orthogonal vector is used as the “right” direction
Examples found in repository?
71fn input_handler(
72 keyboard_input: Res<ButtonInput<KeyCode>>,
73 mesh_query: Query<&Mesh3d, With<CustomUV>>,
74 mut meshes: ResMut<Assets<Mesh>>,
75 mut query: Query<&mut Transform, With<CustomUV>>,
76 time: Res<Time>,
77) {
78 if keyboard_input.just_pressed(KeyCode::Space) {
79 let mesh_handle = mesh_query.single().expect("Query not successful");
80 let mesh = meshes.get_mut(mesh_handle).unwrap();
81 toggle_texture(mesh);
82 }
83 if keyboard_input.pressed(KeyCode::KeyX) {
84 for mut transform in &mut query {
85 transform.rotate_x(time.delta_secs() / 1.2);
86 }
87 }
88 if keyboard_input.pressed(KeyCode::KeyY) {
89 for mut transform in &mut query {
90 transform.rotate_y(time.delta_secs() / 1.2);
91 }
92 }
93 if keyboard_input.pressed(KeyCode::KeyZ) {
94 for mut transform in &mut query {
95 transform.rotate_z(time.delta_secs() / 1.2);
96 }
97 }
98 if keyboard_input.pressed(KeyCode::KeyR) {
99 for mut transform in &mut query {
100 transform.look_to(Vec3::NEG_Z, Vec3::Y);
101 }
102 }
103}
More examples
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}
Sourcepub fn align(
&mut self,
main_axis: impl TryInto<Dir3>,
main_direction: impl TryInto<Dir3>,
secondary_axis: impl TryInto<Dir3>,
secondary_direction: impl TryInto<Dir3>,
)
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 inmain_direction
- applying it to
secondary_axis
produces a vector that lies in the half-plane generated bymain_direction
andsecondary_direction
(with positive contribution bysecondary_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
ormain_direction
fail converting toDir3
(e.g are zero),Dir3::X
takes their place - if
secondary_axis
orsecondary_direction
fail converting,Dir3::Y
takes their place - if
main_axis
is parallel withsecondary_axis
ormain_direction
is parallel withsecondary_direction
, a rotation is constructed which takesmain_axis
tomain_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));
Sourcepub fn mul_transform(&self, transform: Transform) -> Transform
pub fn mul_transform(&self, transform: Transform) -> Transform
Multiplies self
with transform
component by component, returning the
resulting Transform
Examples found in repository?
138fn setup(
139 mut commands: Commands,
140 args: Res<Args>,
141 mesh_assets: ResMut<Assets<Mesh>>,
142 material_assets: ResMut<Assets<StandardMaterial>>,
143 images: ResMut<Assets<Image>>,
144) {
145 warn!(include_str!("warning_string.txt"));
146
147 let args = args.into_inner();
148 let images = images.into_inner();
149 let material_assets = material_assets.into_inner();
150 let mesh_assets = mesh_assets.into_inner();
151
152 let meshes = init_meshes(args, mesh_assets);
153
154 let material_textures = init_textures(args, images);
155 let materials = init_materials(args, &material_textures, material_assets);
156
157 // We're seeding the PRNG here to make this example deterministic for testing purposes.
158 // This isn't strictly required in practical use unless you need your app to be deterministic.
159 let mut material_rng = ChaCha8Rng::seed_from_u64(42);
160 match args.layout {
161 Layout::Sphere => {
162 // NOTE: This pattern is good for testing performance of culling as it provides roughly
163 // the same number of visible meshes regardless of the viewing angle.
164 const N_POINTS: usize = WIDTH * HEIGHT * 4;
165 // NOTE: f64 is used to avoid precision issues that produce visual artifacts in the distribution
166 let radius = WIDTH as f64 * 2.5;
167 let golden_ratio = 0.5f64 * (1.0f64 + 5.0f64.sqrt());
168 for i in 0..N_POINTS {
169 let spherical_polar_theta_phi =
170 fibonacci_spiral_on_sphere(golden_ratio, i, N_POINTS);
171 let unit_sphere_p = spherical_polar_to_cartesian(spherical_polar_theta_phi);
172 let (mesh, transform) = meshes.choose(&mut material_rng).unwrap();
173 commands
174 .spawn((
175 Mesh3d(mesh.clone()),
176 MeshMaterial3d(materials.choose(&mut material_rng).unwrap().clone()),
177 Transform::from_translation((radius * unit_sphere_p).as_vec3())
178 .looking_at(Vec3::ZERO, Vec3::Y)
179 .mul_transform(*transform),
180 ))
181 .insert_if(NoFrustumCulling, || args.no_frustum_culling)
182 .insert_if(NoAutomaticBatching, || args.no_automatic_batching);
183 }
184
185 // camera
186 let mut camera = commands.spawn(Camera3d::default());
187 if args.no_indirect_drawing {
188 camera.insert(NoIndirectDrawing);
189 }
190 if args.no_cpu_culling {
191 camera.insert(NoCpuCulling);
192 }
193
194 // Inside-out box around the meshes onto which shadows are cast (though you cannot see them...)
195 commands.spawn((
196 Mesh3d(mesh_assets.add(Cuboid::from_size(Vec3::splat(radius as f32 * 2.2)))),
197 MeshMaterial3d(material_assets.add(StandardMaterial::from(Color::WHITE))),
198 Transform::from_scale(-Vec3::ONE),
199 NotShadowCaster,
200 ));
201 }
202 _ => {
203 // NOTE: This pattern is good for demonstrating that frustum culling is working correctly
204 // as the number of visible meshes rises and falls depending on the viewing angle.
205 let scale = 2.5;
206 for x in 0..WIDTH {
207 for y in 0..HEIGHT {
208 // introduce spaces to break any kind of moiré pattern
209 if x % 10 == 0 || y % 10 == 0 {
210 continue;
211 }
212 // cube
213 commands.spawn((
214 Mesh3d(meshes.choose(&mut material_rng).unwrap().0.clone()),
215 MeshMaterial3d(materials.choose(&mut material_rng).unwrap().clone()),
216 Transform::from_xyz((x as f32) * scale, (y as f32) * scale, 0.0),
217 ));
218 commands.spawn((
219 Mesh3d(meshes.choose(&mut material_rng).unwrap().0.clone()),
220 MeshMaterial3d(materials.choose(&mut material_rng).unwrap().clone()),
221 Transform::from_xyz(
222 (x as f32) * scale,
223 HEIGHT as f32 * scale,
224 (y as f32) * scale,
225 ),
226 ));
227 commands.spawn((
228 Mesh3d(meshes.choose(&mut material_rng).unwrap().0.clone()),
229 MeshMaterial3d(materials.choose(&mut material_rng).unwrap().clone()),
230 Transform::from_xyz((x as f32) * scale, 0.0, (y as f32) * scale),
231 ));
232 commands.spawn((
233 Mesh3d(meshes.choose(&mut material_rng).unwrap().0.clone()),
234 MeshMaterial3d(materials.choose(&mut material_rng).unwrap().clone()),
235 Transform::from_xyz(0.0, (x as f32) * scale, (y as f32) * scale),
236 ));
237 }
238 }
239 // camera
240 let center = 0.5 * scale * Vec3::new(WIDTH as f32, HEIGHT as f32, WIDTH as f32);
241 commands.spawn((Camera3d::default(), Transform::from_translation(center)));
242 // Inside-out box around the meshes onto which shadows are cast (though you cannot see them...)
243 commands.spawn((
244 Mesh3d(mesh_assets.add(Cuboid::from_size(2.0 * 1.1 * center))),
245 MeshMaterial3d(material_assets.add(StandardMaterial::from(Color::WHITE))),
246 Transform::from_scale(-Vec3::ONE).with_translation(center),
247 NotShadowCaster,
248 ));
249 }
250 }
251
252 commands.spawn((
253 DirectionalLight {
254 shadows_enabled: args.shadows,
255 ..default()
256 },
257 Transform::IDENTITY.looking_at(Vec3::new(0.0, -1.0, -1.0), Vec3::Y),
258 ));
259}
Sourcepub fn transform_point(&self, point: Vec3) -> Vec3
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()
.
Sourcepub fn is_finite(&self) -> bool
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
.
Sourcepub fn to_isometry(&self) -> Isometry3d
pub fn to_isometry(&self) -> Isometry3d
Get the isometry defined by this transform’s rotation and translation, ignoring scale.
Examples found in repository?
219fn bounding_shapes_3d(
220 shapes: Query<&Transform, With<Shape3d>>,
221 mut gizmos: Gizmos,
222 bounding_shape: Res<State<BoundingShape>>,
223) {
224 for transform in shapes.iter() {
225 match bounding_shape.get() {
226 BoundingShape::None => (),
227 BoundingShape::BoundingBox => {
228 // Get the AABB of the extrusion with the rotation and translation of the mesh.
229 let aabb = EXTRUSION.aabb_3d(transform.to_isometry());
230
231 gizmos.primitive_3d(
232 &Cuboid::from_size(Vec3::from(aabb.half_size()) * 2.),
233 aabb.center(),
234 WHITE,
235 );
236 }
237 BoundingShape::BoundingSphere => {
238 // Get the bounding sphere of the extrusion with the rotation and translation of the mesh.
239 let bounding_sphere = EXTRUSION.bounding_sphere(transform.to_isometry());
240
241 gizmos.sphere(bounding_sphere.center(), bounding_sphere.radius(), WHITE);
242 }
243 }
244 }
245}
Trait Implementations§
Source§impl Animatable for Transform
impl Animatable for Transform
Source§impl Component for Transform
Required Components: GlobalTransform
, TransformTreeChanged
.
impl Component for Transform
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
const STORAGE_TYPE: StorageType = bevy_ecs::component::StorageType::Table
Source§type Mutability = Mutable
type Mutability = Mutable
Component<Mutability = Mutable>
,
while immutable components will instead have Component<Mutability = Immutable>
. Read moreSource§fn register_required_components(
_requiree: ComponentId,
required_components: &mut RequiredComponentsRegistrator<'_, '_>,
)
fn register_required_components( _requiree: ComponentId, required_components: &mut RequiredComponentsRegistrator<'_, '_>, )
Source§fn clone_behavior() -> ComponentCloneBehavior
fn clone_behavior() -> ComponentCloneBehavior
Source§fn on_add() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
fn on_add() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
Source§fn on_insert() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
fn on_insert() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
Source§fn on_replace() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
fn on_replace() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
Source§fn on_remove() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
fn on_remove() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
Source§fn on_despawn() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
fn on_despawn() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
Source§fn map_entities<E>(_this: &mut Self, _mapper: &mut E)where
E: EntityMapper,
fn map_entities<E>(_this: &mut Self, _mapper: &mut E)where
E: EntityMapper,
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 moreSource§impl<'de> Deserialize<'de> for Transform
impl<'de> Deserialize<'de> for Transform
Source§fn deserialize<__D>(
__deserializer: __D,
) -> Result<Transform, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(
__deserializer: __D,
) -> Result<Transform, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
Source§impl From<GlobalTransform> for Transform
The transform is expected to be non-degenerate and without shearing, or the output
will be invalid.
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
fn from(transform: GlobalTransform) -> Transform
Source§impl From<Transform> for GlobalTransform
impl From<Transform> for GlobalTransform
Source§fn from(transform: Transform) -> GlobalTransform
fn from(transform: Transform) -> GlobalTransform
Source§impl FromReflect for Transform
impl FromReflect for Transform
Source§fn from_reflect(reflect: &(dyn PartialReflect + 'static)) -> Option<Transform>
fn from_reflect(reflect: &(dyn PartialReflect + 'static)) -> Option<Transform>
Self
from a reflected value.Source§fn take_from_reflect(
reflect: Box<dyn PartialReflect>,
) -> Result<Self, Box<dyn PartialReflect>>
fn take_from_reflect( reflect: Box<dyn PartialReflect>, ) -> Result<Self, Box<dyn PartialReflect>>
Self
using,
constructing the value using from_reflect
if that fails. Read moreSource§impl GetOwnership for Transform
impl GetOwnership for Transform
Source§impl GetTypeRegistration for Transform
impl GetTypeRegistration for Transform
Source§fn get_type_registration() -> TypeRegistration
fn get_type_registration() -> TypeRegistration
TypeRegistration
for this type.Source§fn register_type_dependencies(registry: &mut TypeRegistry)
fn register_type_dependencies(registry: &mut TypeRegistry)
Source§impl IntoReturn for Transform
impl IntoReturn for Transform
Source§impl Mul<GlobalTransform> for Transform
impl Mul<GlobalTransform> for Transform
Source§type Output = GlobalTransform
type Output = GlobalTransform
*
operator.Source§fn mul(
self,
global_transform: GlobalTransform,
) -> <Transform as Mul<GlobalTransform>>::Output
fn mul( self, global_transform: GlobalTransform, ) -> <Transform as Mul<GlobalTransform>>::Output
*
operation. Read moreSource§impl Mul<Transform> for GlobalTransform
impl Mul<Transform> for GlobalTransform
Source§impl PartialReflect for Transform
impl PartialReflect for Transform
Source§fn get_represented_type_info(&self) -> Option<&'static TypeInfo>
fn get_represented_type_info(&self) -> Option<&'static TypeInfo>
Source§fn try_apply(
&mut self,
value: &(dyn PartialReflect + 'static),
) -> Result<(), ApplyError>
fn try_apply( &mut self, value: &(dyn PartialReflect + 'static), ) -> Result<(), ApplyError>
Source§fn reflect_kind(&self) -> ReflectKind
fn reflect_kind(&self) -> ReflectKind
Source§fn reflect_ref(&self) -> ReflectRef<'_>
fn reflect_ref(&self) -> ReflectRef<'_>
Source§fn reflect_mut(&mut self) -> ReflectMut<'_>
fn reflect_mut(&mut self) -> ReflectMut<'_>
Source§fn reflect_owned(self: Box<Transform>) -> ReflectOwned
fn reflect_owned(self: Box<Transform>) -> ReflectOwned
Source§fn try_into_reflect(
self: Box<Transform>,
) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>>
fn try_into_reflect( self: Box<Transform>, ) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>>
Source§fn try_as_reflect(&self) -> Option<&(dyn Reflect + 'static)>
fn try_as_reflect(&self) -> Option<&(dyn Reflect + 'static)>
Source§fn try_as_reflect_mut(&mut self) -> Option<&mut (dyn Reflect + 'static)>
fn try_as_reflect_mut(&mut self) -> Option<&mut (dyn Reflect + 'static)>
Source§fn into_partial_reflect(self: Box<Transform>) -> Box<dyn PartialReflect>
fn into_partial_reflect(self: Box<Transform>) -> Box<dyn PartialReflect>
Source§fn as_partial_reflect(&self) -> &(dyn PartialReflect + 'static)
fn as_partial_reflect(&self) -> &(dyn PartialReflect + 'static)
Source§fn as_partial_reflect_mut(&mut self) -> &mut (dyn PartialReflect + 'static)
fn as_partial_reflect_mut(&mut self) -> &mut (dyn PartialReflect + 'static)
Source§fn reflect_partial_eq(
&self,
value: &(dyn PartialReflect + 'static),
) -> Option<bool>
fn reflect_partial_eq( &self, value: &(dyn PartialReflect + 'static), ) -> Option<bool>
Source§fn debug(&self, f: &mut Formatter<'_>) -> Result<(), Error>
fn debug(&self, f: &mut Formatter<'_>) -> Result<(), Error>
Source§fn reflect_clone(&self) -> Result<Box<dyn Reflect>, ReflectCloneError>
fn reflect_clone(&self) -> Result<Box<dyn Reflect>, ReflectCloneError>
Self
using reflection. Read moreSource§fn apply(&mut self, value: &(dyn PartialReflect + 'static))
fn apply(&mut self, value: &(dyn PartialReflect + 'static))
Source§fn to_dynamic(&self) -> Box<dyn PartialReflect>
fn to_dynamic(&self) -> Box<dyn PartialReflect>
Source§fn reflect_clone_and_take<T>(&self) -> Result<T, ReflectCloneError>
fn reflect_clone_and_take<T>(&self) -> Result<T, ReflectCloneError>
PartialReflect
, combines reflect_clone
and
take
in a useful fashion, automatically constructing an appropriate
ReflectCloneError
if the downcast fails. Read moreSource§fn reflect_hash(&self) -> Option<u64>
fn reflect_hash(&self) -> Option<u64>
Source§fn is_dynamic(&self) -> bool
fn is_dynamic(&self) -> bool
Source§impl Reflect for Transform
impl Reflect for Transform
Source§fn into_any(self: Box<Transform>) -> Box<dyn Any>
fn into_any(self: Box<Transform>) -> Box<dyn Any>
Box<dyn Any>
. Read moreSource§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut dyn Any
. Read moreSource§fn into_reflect(self: Box<Transform>) -> Box<dyn Reflect>
fn into_reflect(self: Box<Transform>) -> Box<dyn Reflect>
Source§fn as_reflect(&self) -> &(dyn Reflect + 'static)
fn as_reflect(&self) -> &(dyn Reflect + 'static)
Source§fn as_reflect_mut(&mut self) -> &mut (dyn Reflect + 'static)
fn as_reflect_mut(&mut self) -> &mut (dyn Reflect + 'static)
Source§impl Serialize for Transform
impl Serialize for Transform
Source§fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
Source§impl Struct for Transform
impl Struct for Transform
Source§fn field(&self, name: &str) -> Option<&(dyn PartialReflect + 'static)>
fn field(&self, name: &str) -> Option<&(dyn PartialReflect + 'static)>
name
as a &dyn PartialReflect
.Source§fn field_mut(
&mut self,
name: &str,
) -> Option<&mut (dyn PartialReflect + 'static)>
fn field_mut( &mut self, name: &str, ) -> Option<&mut (dyn PartialReflect + 'static)>
name
as a
&mut dyn PartialReflect
.Source§fn field_at(&self, index: usize) -> Option<&(dyn PartialReflect + 'static)>
fn field_at(&self, index: usize) -> Option<&(dyn PartialReflect + 'static)>
index
as a
&dyn PartialReflect
.Source§fn field_at_mut(
&mut self,
index: usize,
) -> Option<&mut (dyn PartialReflect + 'static)>
fn field_at_mut( &mut self, index: usize, ) -> Option<&mut (dyn PartialReflect + 'static)>
index
as a &mut dyn PartialReflect
.Source§fn name_at(&self, index: usize) -> Option<&str>
fn name_at(&self, index: usize) -> Option<&str>
index
.Source§fn iter_fields(&self) -> FieldIter<'_> ⓘ
fn iter_fields(&self) -> FieldIter<'_> ⓘ
Source§fn to_dynamic_struct(&self) -> DynamicStruct
fn to_dynamic_struct(&self) -> DynamicStruct
DynamicStruct
from this struct.Source§fn get_represented_struct_info(&self) -> Option<&'static StructInfo>
fn get_represented_struct_info(&self) -> Option<&'static StructInfo>
None
if TypeInfo
is not available.Source§impl TransformPoint for Transform
impl TransformPoint for Transform
Source§impl TypePath for Transform
impl TypePath for Transform
Source§fn type_path() -> &'static str
fn type_path() -> &'static str
Source§fn short_type_path() -> &'static str
fn short_type_path() -> &'static str
Source§fn type_ident() -> Option<&'static str>
fn type_ident() -> Option<&'static str>
Source§fn crate_name() -> Option<&'static str>
fn crate_name() -> Option<&'static str>
impl Copy for Transform
impl StructuralPartialEq for Transform
Auto Trait Implementations§
impl Freeze for Transform
impl RefUnwindSafe for Transform
impl Send for Transform
impl Sync for Transform
impl Unpin for Transform
impl UnwindSafe for Transform
Blanket Implementations§
Source§impl<T, U> AsBindGroupShaderType<U> for T
impl<T, U> AsBindGroupShaderType<U> for T
Source§fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
T
ShaderType
for self
. When used in AsBindGroup
derives, it is safe to assume that all images in self
exist.Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<C> Bundle for Cwhere
C: Component,
impl<C> Bundle for Cwhere
C: Component,
fn component_ids( components: &mut ComponentsRegistrator<'_>, ids: &mut impl FnMut(ComponentId), )
Source§fn get_component_ids(
components: &Components,
ids: &mut impl FnMut(Option<ComponentId>),
)
fn get_component_ids( components: &Components, ids: &mut impl FnMut(Option<ComponentId>), )
Source§impl<C> BundleFromComponents for Cwhere
C: Component,
impl<C> BundleFromComponents for Cwhere
C: Component,
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
, which can then be
downcast
into Box<dyn ConcreteType>
where ConcreteType
implements Trait
.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
, which can then be further
downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
. Box<dyn Any>
can
then be further downcast
into Box<ConcreteType>
where ConcreteType
implements Trait
.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
. Rc<Any>
can then be
further downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<C> DynamicBundle for Cwhere
C: Component,
impl<C> DynamicBundle for Cwhere
C: Component,
Source§unsafe fn get_components(
ptr: MovingPtr<'_, C>,
func: &mut impl FnMut(StorageType, OwningPtr<'_>),
) -> <C as DynamicBundle>::Effect
unsafe fn get_components( ptr: MovingPtr<'_, C>, func: &mut impl FnMut(StorageType, OwningPtr<'_>), ) -> <C as DynamicBundle>::Effect
Source§unsafe fn apply_effect(
_ptr: MovingPtr<'_, MaybeUninit<C>>,
_entity: &mut EntityWorldMut<'_>,
)
unsafe fn apply_effect( _ptr: MovingPtr<'_, MaybeUninit<C>>, _entity: &mut EntityWorldMut<'_>, )
Source§impl<T> DynamicTypePath for Twhere
T: TypePath,
impl<T> DynamicTypePath for Twhere
T: TypePath,
Source§fn reflect_type_path(&self) -> &str
fn reflect_type_path(&self) -> &str
TypePath::type_path
.Source§fn reflect_short_type_path(&self) -> &str
fn reflect_short_type_path(&self) -> &str
Source§fn reflect_type_ident(&self) -> Option<&str>
fn reflect_type_ident(&self) -> Option<&str>
TypePath::type_ident
.Source§fn reflect_crate_name(&self) -> Option<&str>
fn reflect_crate_name(&self) -> Option<&str>
TypePath::crate_name
.Source§fn reflect_module_path(&self) -> Option<&str>
fn reflect_module_path(&self) -> Option<&str>
Source§impl<T> DynamicTyped for Twhere
T: Typed,
impl<T> DynamicTyped for Twhere
T: Typed,
Source§fn reflect_type_info(&self) -> &'static TypeInfo
fn reflect_type_info(&self) -> &'static TypeInfo
Typed::type_info
.Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self
to use its Binary
implementation when Debug
-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self
to use its Display
implementation when
Debug
-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self
to use its LowerExp
implementation when
Debug
-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self
to use its LowerHex
implementation when
Debug
-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self
to use its Octal
implementation when Debug
-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self
to use its Pointer
implementation when
Debug
-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self
to use its UpperExp
implementation when
Debug
-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self
to use its UpperHex
implementation when
Debug
-formatted.Source§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
Source§impl<T> FromWorld for Twhere
T: Default,
impl<T> FromWorld for Twhere
T: Default,
Source§fn from_world(_world: &mut World) -> T
fn from_world(_world: &mut World) -> T
Creates Self
using default()
.
Source§impl<S> GetField for Swhere
S: Struct,
impl<S> GetField for Swhere
S: Struct,
Source§impl<T> GetPath for T
impl<T> GetPath for T
Source§fn reflect_path<'p>(
&self,
path: impl ReflectPath<'p>,
) -> Result<&(dyn PartialReflect + 'static), ReflectPathError<'p>>
fn reflect_path<'p>( &self, path: impl ReflectPath<'p>, ) -> Result<&(dyn PartialReflect + 'static), ReflectPathError<'p>>
path
. Read moreSource§fn reflect_path_mut<'p>(
&mut self,
path: impl ReflectPath<'p>,
) -> Result<&mut (dyn PartialReflect + 'static), ReflectPathError<'p>>
fn reflect_path_mut<'p>( &mut self, path: impl ReflectPath<'p>, ) -> Result<&mut (dyn PartialReflect + 'static), ReflectPathError<'p>>
path
. Read moreSource§fn path<'p, T>(
&self,
path: impl ReflectPath<'p>,
) -> Result<&T, ReflectPathError<'p>>where
T: Reflect,
fn path<'p, T>(
&self,
path: impl ReflectPath<'p>,
) -> Result<&T, ReflectPathError<'p>>where
T: Reflect,
path
. Read moreSource§fn path_mut<'p, T>(
&mut self,
path: impl ReflectPath<'p>,
) -> Result<&mut T, ReflectPathError<'p>>where
T: Reflect,
fn path_mut<'p, T>(
&mut self,
path: impl ReflectPath<'p>,
) -> Result<&mut T, ReflectPathError<'p>>where
T: Reflect,
path
. Read moreSource§impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
Source§impl<T> Identity for Twhere
T: ?Sized,
impl<T> Identity for Twhere
T: ?Sized,
Source§impl<T> InitializeFromFunction<T> for T
impl<T> InitializeFromFunction<T> for T
Source§fn initialize_from_function(f: fn() -> T) -> T
fn initialize_from_function(f: fn() -> T) -> T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoResult<T> for T
impl<T> IntoResult<T> for T
Source§fn into_result(self) -> Result<T, RunSystemError>
fn into_result(self) -> Result<T, RunSystemError>
Source§impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
fn into_sample(self) -> T
Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
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
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
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
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self
, then passes self.deref()
into the pipe function.Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<R, P> ReadPrimitive<R> for P
impl<R, P> ReadPrimitive<R> for P
Source§fn read_from_little_endian(read: &mut R) -> Result<Self, Error>
fn read_from_little_endian(read: &mut R) -> Result<Self, Error>
ReadEndian::read_from_little_endian()
.Source§impl<T> Serialize for T
impl<T> Serialize for T
fn erased_serialize(&self, serializer: &mut dyn Serializer) -> Result<(), Error>
fn do_erased_serialize( &self, serializer: &mut dyn Serializer, ) -> Result<(), ErrorImpl>
Source§impl<Ret> SpawnIfAsync<(), Ret> for Ret
impl<Ret> SpawnIfAsync<(), Ret> for Ret
Source§impl<T, O> SuperFrom<T> for Owhere
O: From<T>,
impl<T, O> SuperFrom<T> for Owhere
O: From<T>,
Source§fn super_from(input: T) -> O
fn super_from(input: T) -> O
Source§impl<T, O, M> SuperInto<O, M> for Twhere
O: SuperFrom<T, M>,
impl<T, O, M> SuperInto<O, M> for Twhere
O: SuperFrom<T, M>,
Source§fn super_into(self) -> O
fn super_into(self) -> O
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B>
of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B>
of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R>
view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R>
view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target
of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target
of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap()
only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut()
only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.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
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.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
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.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
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.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
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref()
only in debug builds, and is erased in release
builds.