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
by systems in the system set
TransformPropagate
.
This system runs during PostUpdate
. If you
update the Transform
of an entity during this set or after, you will notice a 1 frame lag
before the GlobalTransform
is updated.
§Examples
Fields§
§translation: Vec3
Position of the entity. In 2d, the last value of the Vec3
is used for z-ordering.
See the translations
example for usage.
rotation: Quat
Rotation of the entity.
See the 3d_rotation
example for usage.
scale: Vec3
Scale of the entity.
See the scale
example for usage.
Implementations§
Source§impl Transform
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?
204fn spawn_light(commands: &mut Commands) {
205 commands.spawn((
206 DirectionalLight::default(),
207 Transform::from_xyz(4.0, 8.0, 4.0).looking_at(Vec3::ZERO, Vec3::Y),
208 ));
209}
210
211/// Spawns the camera.
212fn spawn_camera(commands: &mut Commands) {
213 commands
214 .spawn(Camera3d::default())
215 .insert(Transform::from_xyz(0.0, 2.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y))
216 // Tag the camera with `Selection::Camera`.
217 .insert(Selection::Camera);
218}
More examples
71fn spawn_curve_sprite<T: CurveColor>(commands: &mut Commands, y: f32, points: [T; 4]) {
72 commands.spawn((
73 Sprite::sized(Vec2::new(75., 75.)),
74 Transform::from_xyz(0., y, 0.),
75 Curve(CubicBezier::new([points]).to_curve().unwrap()),
76 ));
77}
78
79fn spawn_mixed_sprite<T: MixedColor>(commands: &mut Commands, y: f32, colors: [T; 4]) {
80 commands.spawn((
81 Transform::from_xyz(0., y, 0.),
82 Sprite::sized(Vec2::new(75., 75.)),
83 Mixed(colors),
84 ));
85}
- 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/camera/2d_top_down_camera.rs
- examples/2d/pixel_grid_snap.rs
- examples/shader/fallback_image.rs
- examples/shader/custom_phase_item.rs
- examples/3d/3d_viewport_to_world.rs
- examples/shader/shader_material.rs
- examples/shader/shader_material_glsl.rs
- examples/shader/texture_binding_array.rs
- examples/asset/hot_asset_reloading.rs
- examples/asset/multi_asset_sync.rs
- examples/2d/transparency_2d.rs
- examples/transforms/3d_rotation.rs
- examples/3d/rotate_environment_map.rs
- examples/transforms/scale.rs
- examples/shader/custom_vertex_attribute.rs
- tests/window/minimizing.rs
- tests/window/resizing.rs
- examples/3d/color_grading.rs
- examples/3d/atmospheric_fog.rs
- examples/transforms/translation.rs
- examples/3d/load_gltf_extras.rs
- examples/animation/morph_targets.rs
- examples/shader/shader_defs.rs
- examples/3d/post_processing.rs
- examples/3d/clearcoat.rs
- examples/3d/3d_scene.rs
- examples/diagnostics/log_diagnostics.rs
- examples/animation/animated_mesh.rs
- examples/games/loading_screen.rs
- examples/shader/custom_post_processing.rs
- examples/animation/animation_graph.rs
- examples/3d/tonemapping.rs
- examples/shader/shader_material_screenspace_texture.rs
- examples/3d/pcss.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/3d/parenting.rs
- examples/3d/animated_material.rs
- examples/3d/depth_of_field.rs
- examples/window/screenshot.rs
- examples/ecs/entity_disabling.rs
- examples/camera/custom_projection.rs
- examples/3d/skybox.rs
- examples/3d/load_gltf.rs
- examples/3d/two_passes.rs
- examples/3d/lines.rs
- examples/stress_tests/many_materials.rs
- examples/camera/2d_screen_shake.rs
- examples/shader/extended_material_bindless.rs
- examples/3d/update_gltf_scene.rs
- examples/shader/custom_render_phase.rs
- examples/3d/atmosphere.rs
- examples/3d/order_independent_transparency.rs
- examples/shader/storage_buffer.rs
- examples/ecs/hierarchy.rs
- examples/3d/fog_volumes.rs
- examples/3d/generate_custom_mesh.rs
- examples/2d/wireframe_2d.rs
- examples/window/low_power.rs
- examples/audio/spatial_audio_2d.rs
- examples/movement/smooth_follow.rs
- examples/3d/mesh_ray_cast.rs
- examples/3d/vertex_colors.rs
- examples/shader/extended_material.rs
- examples/picking/simple_picking.rs
- examples/shader/custom_shader_instancing.rs
- examples/games/contributors.rs
- examples/3d/orthographic.rs
- examples/testbed/2d.rs
- examples/shader/specialized_mesh_pipeline.rs
- examples/picking/debug_picking.rs
- examples/3d/spherical_area_lights.rs
- examples/2d/2d_shapes.rs
- examples/math/bounding_2d.rs
- examples/transforms/transform.rs
- examples/window/multiple_windows.rs
- examples/gizmos/axes.rs
- examples/3d/motion_blur.rs
- examples/math/custom_primitives.rs
- examples/camera/first_person_view_model.rs
- examples/animation/animated_mesh_events.rs
- examples/asset/alter_sprite.rs
- examples/app/headless_renderer.rs
- examples/animation/eased_motion.rs
- examples/3d/ssao.rs
- examples/3d/wireframe.rs
- examples/stress_tests/transform_hierarchy.rs
- examples/shader/automatic_instancing.rs
- examples/audio/spatial_audio_3d.rs
- examples/ecs/error_handling.rs
- examples/camera/projection_zoom.rs
- examples/3d/fog.rs
- examples/2d/rotation.rs
- examples/3d/visibility_range.rs
- examples/3d/specular_tint.rs
- examples/testbed/3d.rs
- examples/animation/animated_mesh_control.rs
- examples/stress_tests/many_cameras_lights.rs
- examples/3d/volumetric_fog.rs
- examples/3d/texture.rs
- examples/3d/shadow_caster_receiver.rs
- examples/gizmos/3d_gizmos.rs
- examples/async_tasks/async_compute.rs
- examples/3d/bloom_3d.rs
- examples/3d/anti_aliasing.rs
- examples/transforms/align.rs
- examples/3d/decal.rs
- examples/math/random_sampling.rs
- examples/ui/render_ui_to_texture.rs
- examples/picking/sprite_picking.rs
- examples/2d/mesh2d_alpha_mode.rs
- examples/3d/scrolling_fog.rs
- examples/asset/repeated_texture.rs
- examples/ecs/iter_combinations.rs
- examples/asset/alter_mesh.rs
- examples/2d/sprite_slice.rs
- examples/3d/transparency_3d.rs
- examples/asset/asset_settings.rs
- examples/2d/mesh2d_repeated_texture.rs
- examples/3d/3d_shapes.rs
- examples/gizmos/light_gizmos.rs
- examples/3d/render_to_texture.rs
- examples/3d/pbr.rs
- examples/3d/spotlight.rs
- examples/asset/asset_loading.rs
- examples/3d/auto_exposure.rs
- examples/animation/easing_functions.rs
- examples/shader/shader_prepass.rs
- examples/picking/mesh_picking.rs
- examples/3d/shadow_biases.rs
- examples/stress_tests/many_foxes.rs
- examples/games/desk_toy.rs
- examples/math/sampling_primitives.rs
- examples/2d/sprite_scale.rs
- examples/3d/parallax_mapping.rs
- examples/3d/deferred_rendering.rs
- examples/animation/custom_skinned_mesh.rs
- examples/3d/blend_modes.rs
- examples/stress_tests/many_cubes.rs
- examples/3d/lighting.rs
- examples/animation/animated_transform.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
315fn setup_lights(mut commands: Commands) {
316 commands.spawn((
317 PointLight {
318 intensity: 5000.0,
319 ..default()
320 },
321 Transform::from_translation(Vec3::new(-LEFT_RIGHT_OFFSET_3D, 2.0, 0.0))
322 .looking_at(Vec3::new(-LEFT_RIGHT_OFFSET_3D, 0.0, 0.0), Vec3::Y),
323 ));
324}
325
326/// Marker component for header text
327#[derive(Debug, Clone, Component, Default, Reflect)]
328pub struct HeaderText;
329
330/// Marker component for header node
331#[derive(Debug, Clone, Component, Default, Reflect)]
332pub struct HeaderNode;
333
334fn update_active_cameras(
335 state: Res<State<CameraActive>>,
336 camera_2d: Single<(Entity, &mut Camera), With<Camera2d>>,
337 camera_3d: Single<(Entity, &mut Camera), (With<Camera3d>, Without<Camera2d>)>,
338 mut text: Query<&mut UiTargetCamera, With<HeaderNode>>,
339) {
340 let (entity_2d, mut cam_2d) = camera_2d.into_inner();
341 let (entity_3d, mut cam_3d) = camera_3d.into_inner();
342 let is_camera_2d_active = matches!(*state.get(), CameraActive::Dim2);
343
344 cam_2d.is_active = is_camera_2d_active;
345 cam_3d.is_active = !is_camera_2d_active;
346
347 let active_camera = if is_camera_2d_active {
348 entity_2d
349 } else {
350 entity_3d
351 };
352
353 text.iter_mut().for_each(|mut target_camera| {
354 *target_camera = UiTargetCamera(active_camera);
355 });
356}
357
358fn switch_cameras(current: Res<State<CameraActive>>, mut next: ResMut<NextState<CameraActive>>) {
359 let next_state = match current.get() {
360 CameraActive::Dim2 => CameraActive::Dim3,
361 CameraActive::Dim3 => CameraActive::Dim2,
362 };
363 next.set(next_state);
364}
365
366fn setup_text(mut commands: Commands, cameras: Query<(Entity, &Camera)>) {
367 let active_camera = cameras
368 .iter()
369 .find_map(|(entity, camera)| camera.is_active.then_some(entity))
370 .expect("run condition ensures existence");
371 commands.spawn((
372 HeaderNode,
373 Node {
374 justify_self: JustifySelf::Center,
375 top: Val::Px(5.0),
376 ..Default::default()
377 },
378 UiTargetCamera(active_camera),
379 children![(
380 Text::default(),
381 HeaderText,
382 TextLayout::new_with_justify(JustifyText::Center),
383 children![
384 TextSpan::new("Primitive: "),
385 TextSpan(format!("{text}", text = PrimitiveSelected::default())),
386 TextSpan::new("\n\n"),
387 TextSpan::new(
388 "Press 'C' to switch between 2D and 3D mode\n\
389 Press 'Up' or 'Down' to switch to the next/previous primitive",
390 ),
391 TextSpan::new("\n\n"),
392 TextSpan::new("(If nothing is displayed, there's no rendering support yet)",),
393 ]
394 )],
395 ));
396}
397
398fn update_text(
399 primitive_state: Res<State<PrimitiveSelected>>,
400 header: Query<Entity, With<HeaderText>>,
401 mut writer: TextUiWriter,
402) {
403 let new_text = format!("{text}", text = primitive_state.get());
404 header.iter().for_each(|header_text| {
405 if let Some(mut text) = writer.get_text(header_text, 2) {
406 (*text).clone_from(&new_text);
407 };
408 });
409}
410
411fn switch_to_next_primitive(
412 current: Res<State<PrimitiveSelected>>,
413 mut next: ResMut<NextState<PrimitiveSelected>>,
414) {
415 let next_state = current.get().next();
416 next.set(next_state);
417}
418
419fn switch_to_previous_primitive(
420 current: Res<State<PrimitiveSelected>>,
421 mut next: ResMut<NextState<PrimitiveSelected>>,
422) {
423 let next_state = current.get().previous();
424 next.set(next_state);
425}
426
427fn in_mode(active: CameraActive) -> impl Fn(Res<State<CameraActive>>) -> bool {
428 move |state| *state.get() == active
429}
430
431fn draw_gizmos_2d(mut gizmos: Gizmos, state: Res<State<PrimitiveSelected>>, time: Res<Time>) {
432 const POSITION: Vec2 = Vec2::new(-LEFT_RIGHT_OFFSET_2D, 0.0);
433 let angle = time.elapsed_secs();
434 let isometry = Isometry2d::new(POSITION, Rot2::radians(angle));
435 let color = Color::WHITE;
436
437 #[expect(
438 clippy::match_same_arms,
439 reason = "Certain primitives don't have any 2D rendering support yet."
440 )]
441 match state.get() {
442 PrimitiveSelected::RectangleAndCuboid => {
443 gizmos.primitive_2d(&RECTANGLE, isometry, color);
444 }
445 PrimitiveSelected::CircleAndSphere => {
446 gizmos.primitive_2d(&CIRCLE, isometry, color);
447 }
448 PrimitiveSelected::Ellipse => drop(gizmos.primitive_2d(&ELLIPSE, isometry, color)),
449 PrimitiveSelected::Triangle => gizmos.primitive_2d(&TRIANGLE_2D, isometry, color),
450 PrimitiveSelected::Plane => gizmos.primitive_2d(&PLANE_2D, isometry, color),
451 PrimitiveSelected::Line => drop(gizmos.primitive_2d(&LINE2D, isometry, color)),
452 PrimitiveSelected::Segment => {
453 drop(gizmos.primitive_2d(&SEGMENT_2D, isometry, color));
454 }
455 PrimitiveSelected::Polyline => gizmos.primitive_2d(&POLYLINE_2D, isometry, color),
456 PrimitiveSelected::Polygon => gizmos.primitive_2d(&POLYGON_2D, isometry, color),
457 PrimitiveSelected::RegularPolygon => {
458 gizmos.primitive_2d(®ULAR_POLYGON, isometry, color);
459 }
460 PrimitiveSelected::Capsule => gizmos.primitive_2d(&CAPSULE_2D, isometry, color),
461 PrimitiveSelected::Cylinder => {}
462 PrimitiveSelected::Cone => {}
463 PrimitiveSelected::ConicalFrustum => {}
464 PrimitiveSelected::Torus => drop(gizmos.primitive_2d(&ANNULUS, isometry, color)),
465 PrimitiveSelected::Tetrahedron => {}
466 PrimitiveSelected::Arc => gizmos.primitive_2d(&ARC, isometry, color),
467 PrimitiveSelected::CircularSector => {
468 gizmos.primitive_2d(&CIRCULAR_SECTOR, isometry, color);
469 }
470 PrimitiveSelected::CircularSegment => {
471 gizmos.primitive_2d(&CIRCULAR_SEGMENT, isometry, color);
472 }
473 }
474}
475
476/// Marker for primitive meshes to record in which state they should be visible in
477#[derive(Debug, Clone, Component, Default, Reflect)]
478pub struct PrimitiveData {
479 camera_mode: CameraActive,
480 primitive_state: PrimitiveSelected,
481}
482
483/// Marker for meshes of 2D primitives
484#[derive(Debug, Clone, Component, Default)]
485pub struct MeshDim2;
486
487/// Marker for meshes of 3D primitives
488#[derive(Debug, Clone, Component, Default)]
489pub struct MeshDim3;
490
491fn spawn_primitive_2d(
492 mut commands: Commands,
493 mut materials: ResMut<Assets<ColorMaterial>>,
494 mut meshes: ResMut<Assets<Mesh>>,
495) {
496 const POSITION: Vec3 = Vec3::new(LEFT_RIGHT_OFFSET_2D, 0.0, 0.0);
497 let material: Handle<ColorMaterial> = materials.add(Color::WHITE);
498 let camera_mode = CameraActive::Dim2;
499 [
500 Some(RECTANGLE.mesh().build()),
501 Some(CIRCLE.mesh().build()),
502 Some(ELLIPSE.mesh().build()),
503 Some(TRIANGLE_2D.mesh().build()),
504 None, // plane
505 None, // line
506 None, // segment
507 None, // polyline
508 None, // polygon
509 Some(REGULAR_POLYGON.mesh().build()),
510 Some(CAPSULE_2D.mesh().build()),
511 None, // cylinder
512 None, // cone
513 None, // conical frustum
514 Some(ANNULUS.mesh().build()),
515 None, // tetrahedron
516 ]
517 .into_iter()
518 .zip(PrimitiveSelected::ALL)
519 .for_each(|(maybe_mesh, state)| {
520 if let Some(mesh) = maybe_mesh {
521 commands.spawn((
522 MeshDim2,
523 PrimitiveData {
524 camera_mode,
525 primitive_state: state,
526 },
527 Mesh2d(meshes.add(mesh)),
528 MeshMaterial2d(material.clone()),
529 Transform::from_translation(POSITION),
530 ));
531 }
532 });
533}
534
535fn spawn_primitive_3d(
536 mut commands: Commands,
537 mut materials: ResMut<Assets<StandardMaterial>>,
538 mut meshes: ResMut<Assets<Mesh>>,
539) {
540 const POSITION: Vec3 = Vec3::new(-LEFT_RIGHT_OFFSET_3D, 0.0, 0.0);
541 let material: Handle<StandardMaterial> = materials.add(Color::WHITE);
542 let camera_mode = CameraActive::Dim3;
543 [
544 Some(CUBOID.mesh().build()),
545 Some(SPHERE.mesh().build()),
546 None, // ellipse
547 Some(TRIANGLE_3D.mesh().build()),
548 Some(PLANE_3D.mesh().build()),
549 None, // line
550 None, // segment
551 None, // polyline
552 None, // polygon
553 None, // regular polygon
554 Some(CAPSULE_3D.mesh().build()),
555 Some(CYLINDER.mesh().build()),
556 None, // cone
557 None, // conical frustum
558 Some(TORUS.mesh().build()),
559 Some(TETRAHEDRON.mesh().build()),
560 ]
561 .into_iter()
562 .zip(PrimitiveSelected::ALL)
563 .for_each(|(maybe_mesh, state)| {
564 if let Some(mesh) = maybe_mesh {
565 commands.spawn((
566 MeshDim3,
567 PrimitiveData {
568 camera_mode,
569 primitive_state: state,
570 },
571 Mesh3d(meshes.add(mesh)),
572 MeshMaterial3d(material.clone()),
573 Transform::from_translation(POSITION),
574 ));
575 }
576 });
577}
- examples/stress_tests/many_text2d.rs
- 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/asset/multi_asset_sync.rs
- examples/shader/custom_post_processing.rs
- examples/testbed/2d.rs
- examples/3d/anisotropy.rs
- examples/3d/animated_material.rs
- examples/stress_tests/many_materials.rs
- examples/3d/ssr.rs
- examples/2d/mesh2d_vertex_color_texture.rs
- examples/3d/order_independent_transparency.rs
- examples/audio/spatial_audio_2d.rs
- examples/movement/smooth_follow.rs
- examples/3d/mesh_ray_cast.rs
- examples/transforms/transform.rs
- examples/2d/2d_viewport_to_world.rs
- examples/2d/bloom_2d.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/asset/repeated_texture.rs
- examples/math/random_sampling.rs
- examples/stress_tests/transform_hierarchy.rs
- examples/2d/sprite_slice.rs
- examples/2d/mesh2d_repeated_texture.rs
- examples/3d/meshlet.rs
- examples/gizmos/3d_gizmos.rs
- examples/3d/render_to_texture.rs
- examples/3d/spotlight.rs
- examples/3d/auto_exposure.rs
- examples/games/breakout.rs
- examples/stress_tests/many_foxes.rs
- examples/3d/split_screen.rs
- examples/2d/text2d.rs
- examples/math/sampling_primitives.rs
- examples/2d/sprite_scale.rs
- examples/3d/parallax_mapping.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
55fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
56 commands.spawn((
57 Camera3d::default(),
58 Transform::from_xyz(4.0, 4.0, 12.0).looking_at(Vec3::new(0.0, 0.0, 0.5), Vec3::Y),
59 ));
60
61 commands.spawn((
62 Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, 1.0, -PI / 4.)),
63 DirectionalLight::default(),
64 ));
65
66 commands.spawn(SceneRoot(asset_server.load(
67 GltfAssetLabel::Scene(0).from_asset("models/GltfPrimitives/gltf_primitives.glb"),
68 )));
69}
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}
37fn setup(asset_server: Res<AssetServer>, mut commands: Commands) {
38 commands.insert_resource(MorphData {
39 the_wave: asset_server
40 .load(GltfAssetLabel::Animation(2).from_asset("models/animated/MorphStressTest.gltf")),
41 mesh: asset_server.load(
42 GltfAssetLabel::Primitive {
43 mesh: 0,
44 primitive: 0,
45 }
46 .from_asset("models/animated/MorphStressTest.gltf"),
47 ),
48 });
49 commands.spawn(SceneRoot(asset_server.load(
50 GltfAssetLabel::Scene(0).from_asset("models/animated/MorphStressTest.gltf"),
51 )));
52 commands.spawn((
53 DirectionalLight::default(),
54 Transform::from_rotation(Quat::from_rotation_z(PI / 2.0)),
55 ));
56 commands.spawn((
57 Camera3d::default(),
58 Transform::from_xyz(3.0, 2.1, 10.2).looking_at(Vec3::ZERO, Vec3::Y),
59 ));
60}
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/diagnostics/log_diagnostics.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/shader/custom_render_phase.rs
- examples/3d/mesh_ray_cast.rs
- examples/picking/simple_picking.rs
- examples/picking/debug_picking.rs
- examples/animation/animated_mesh_events.rs
- examples/app/headless_renderer.rs
- examples/3d/ssao.rs
- examples/3d/visibility_range.rs
- examples/3d/specular_tint.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/stress_tests/many_foxes.rs
- examples/3d/split_screen.rs
- examples/3d/deferred_rendering.rs
- examples/3d/lighting.rs
- examples/testbed/full_ui.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?
283fn spawn_fox(commands: &mut Commands, assets: &ExampleAssets) {
284 commands.spawn((
285 SceneRoot(assets.fox.clone()),
286 Visibility::Hidden,
287 Transform::from_scale(Vec3::splat(FOX_SCALE)),
288 MainObject,
289 ));
290}
291
292fn spawn_text(commands: &mut Commands, app_status: &AppStatus) {
293 commands.spawn((
294 app_status.create_text(),
295 Node {
296 position_type: PositionType::Absolute,
297 bottom: Val::Px(12.0),
298 left: Val::Px(12.0),
299 ..default()
300 },
301 ));
302}
303
304// A system that updates the help text.
305fn update_text(mut text_query: Query<&mut Text>, app_status: Res<AppStatus>) {
306 for mut text in text_query.iter_mut() {
307 *text = app_status.create_text();
308 }
309}
310
311impl AppStatus {
312 // Constructs the help text at the bottom of the screen based on the
313 // application status.
314 fn create_text(&self) -> Text {
315 let irradiance_volume_help_text = if self.irradiance_volume_present {
316 DISABLE_IRRADIANCE_VOLUME_HELP_TEXT
317 } else {
318 ENABLE_IRRADIANCE_VOLUME_HELP_TEXT
319 };
320
321 let voxels_help_text = if self.voxels_visible {
322 HIDE_VOXELS_HELP_TEXT
323 } else {
324 SHOW_VOXELS_HELP_TEXT
325 };
326
327 let rotation_help_text = if self.rotating {
328 STOP_ROTATION_HELP_TEXT
329 } else {
330 START_ROTATION_HELP_TEXT
331 };
332
333 let switch_mesh_help_text = match self.model {
334 ExampleModel::Sphere => SWITCH_TO_FOX_HELP_TEXT,
335 ExampleModel::Fox => SWITCH_TO_SPHERE_HELP_TEXT,
336 };
337
338 format!(
339 "{CLICK_TO_MOVE_HELP_TEXT}\n\
340 {voxels_help_text}\n\
341 {irradiance_volume_help_text}\n\
342 {rotation_help_text}\n\
343 {switch_mesh_help_text}"
344 )
345 .into()
346 }
347}
348
349// Rotates the camera a bit every frame.
350fn rotate_camera(
351 mut camera_query: Query<&mut Transform, With<Camera3d>>,
352 time: Res<Time>,
353 app_status: Res<AppStatus>,
354) {
355 if !app_status.rotating {
356 return;
357 }
358
359 for mut transform in camera_query.iter_mut() {
360 transform.translation = Vec2::from_angle(ROTATION_SPEED * time.delta_secs())
361 .rotate(transform.translation.xz())
362 .extend(transform.translation.y)
363 .xzy();
364 transform.look_at(Vec3::ZERO, Vec3::Y);
365 }
366}
367
368// Toggles between the unskinned sphere model and the skinned fox model if the
369// user requests it.
370fn change_main_object(
371 keyboard: Res<ButtonInput<KeyCode>>,
372 mut app_status: ResMut<AppStatus>,
373 mut sphere_query: Query<&mut Visibility, (With<MainObject>, With<Mesh3d>, Without<SceneRoot>)>,
374 mut fox_query: Query<&mut Visibility, (With<MainObject>, With<SceneRoot>)>,
375) {
376 if !keyboard.just_pressed(KeyCode::Tab) {
377 return;
378 }
379 let Some(mut sphere_visibility) = sphere_query.iter_mut().next() else {
380 return;
381 };
382 let Some(mut fox_visibility) = fox_query.iter_mut().next() else {
383 return;
384 };
385
386 match app_status.model {
387 ExampleModel::Sphere => {
388 *sphere_visibility = Visibility::Hidden;
389 *fox_visibility = Visibility::Visible;
390 app_status.model = ExampleModel::Fox;
391 }
392 ExampleModel::Fox => {
393 *sphere_visibility = Visibility::Visible;
394 *fox_visibility = Visibility::Hidden;
395 app_status.model = ExampleModel::Sphere;
396 }
397 }
398}
399
400impl Default for AppStatus {
401 fn default() -> Self {
402 Self {
403 irradiance_volume_present: true,
404 rotating: true,
405 model: ExampleModel::Sphere,
406 voxels_visible: false,
407 }
408 }
409}
410
411// Turns on and off the irradiance volume as requested by the user.
412fn toggle_irradiance_volumes(
413 mut commands: Commands,
414 keyboard: Res<ButtonInput<KeyCode>>,
415 light_probe_query: Query<Entity, With<LightProbe>>,
416 mut app_status: ResMut<AppStatus>,
417 assets: Res<ExampleAssets>,
418 mut ambient_light: ResMut<AmbientLight>,
419) {
420 if !keyboard.just_pressed(KeyCode::Space) {
421 return;
422 };
423
424 let Some(light_probe) = light_probe_query.iter().next() else {
425 return;
426 };
427
428 if app_status.irradiance_volume_present {
429 commands.entity(light_probe).remove::<IrradianceVolume>();
430 ambient_light.brightness = AMBIENT_LIGHT_BRIGHTNESS * IRRADIANCE_VOLUME_INTENSITY;
431 app_status.irradiance_volume_present = false;
432 } else {
433 commands.entity(light_probe).insert(IrradianceVolume {
434 voxels: assets.irradiance_volume.clone(),
435 intensity: IRRADIANCE_VOLUME_INTENSITY,
436 ..default()
437 });
438 ambient_light.brightness = 0.0;
439 app_status.irradiance_volume_present = true;
440 }
441}
442
443fn toggle_rotation(keyboard: Res<ButtonInput<KeyCode>>, mut app_status: ResMut<AppStatus>) {
444 if keyboard.just_pressed(KeyCode::Enter) {
445 app_status.rotating = !app_status.rotating;
446 }
447}
448
449// Handles clicks on the plane that reposition the object.
450fn handle_mouse_clicks(
451 buttons: Res<ButtonInput<MouseButton>>,
452 windows: Query<&Window, With<PrimaryWindow>>,
453 cameras: Query<(&Camera, &GlobalTransform)>,
454 mut main_objects: Query<&mut Transform, With<MainObject>>,
455) {
456 if !buttons.pressed(MouseButton::Left) {
457 return;
458 }
459 let Some(mouse_position) = windows.iter().next().and_then(Window::cursor_position) else {
460 return;
461 };
462 let Some((camera, camera_transform)) = cameras.iter().next() else {
463 return;
464 };
465
466 // Figure out where the user clicked on the plane.
467 let Ok(ray) = camera.viewport_to_world(camera_transform, mouse_position) else {
468 return;
469 };
470 let Some(ray_distance) = ray.intersect_plane(Vec3::ZERO, InfinitePlane3d::new(Vec3::Y)) else {
471 return;
472 };
473 let plane_intersection = ray.origin + ray.direction.normalize() * ray_distance;
474
475 // Move all the main objects.
476 for mut transform in main_objects.iter_mut() {
477 transform.translation = vec3(
478 plane_intersection.x,
479 transform.translation.y,
480 plane_intersection.z,
481 );
482 }
483}
484
485impl FromWorld for ExampleAssets {
486 fn from_world(world: &mut World) -> Self {
487 let fox_animation =
488 world.load_asset(GltfAssetLabel::Animation(1).from_asset("models/animated/Fox.glb"));
489 let (fox_animation_graph, fox_animation_node) =
490 AnimationGraph::from_clip(fox_animation.clone());
491
492 ExampleAssets {
493 main_sphere: world.add_asset(Sphere::default().mesh().uv(32, 18)),
494 fox: world.load_asset(GltfAssetLabel::Scene(0).from_asset("models/animated/Fox.glb")),
495 main_sphere_material: world.add_asset(Color::from(SILVER)),
496 main_scene: world.load_asset(
497 GltfAssetLabel::Scene(0)
498 .from_asset("models/IrradianceVolumeExample/IrradianceVolumeExample.glb"),
499 ),
500 irradiance_volume: world.load_asset("irradiance_volumes/Example.vxgi.ktx2"),
501 fox_animation_graph: world.add_asset(fox_animation_graph),
502 fox_animation_node,
503 voxel_cube: world.add_asset(Cuboid::default()),
504 // Just use a specular map for the skybox since it's not too blurry.
505 // In reality you wouldn't do this--you'd use a real skybox texture--but
506 // reusing the textures like this saves space in the Bevy repository.
507 skybox: world.load_asset("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
508 }
509 }
510}
511
512// Plays the animation on the fox.
513fn play_animations(
514 mut commands: Commands,
515 assets: Res<ExampleAssets>,
516 mut players: Query<(Entity, &mut AnimationPlayer), Without<AnimationGraphHandle>>,
517) {
518 for (entity, mut player) in players.iter_mut() {
519 commands
520 .entity(entity)
521 .insert(AnimationGraphHandle(assets.fox_animation_graph.clone()));
522 player.play(assets.fox_animation_node).repeat();
523 }
524}
525
526fn create_cubes(
527 image_assets: Res<Assets<Image>>,
528 mut commands: Commands,
529 irradiance_volumes: Query<(&IrradianceVolume, &GlobalTransform)>,
530 voxel_cube_parents: Query<Entity, With<VoxelCubeParent>>,
531 voxel_cubes: Query<Entity, With<VoxelCube>>,
532 example_assets: Res<ExampleAssets>,
533 mut voxel_visualization_material_assets: ResMut<Assets<VoxelVisualizationMaterial>>,
534) {
535 // If voxel cubes have already been spawned, don't do anything.
536 if !voxel_cubes.is_empty() {
537 return;
538 }
539
540 let Some(voxel_cube_parent) = voxel_cube_parents.iter().next() else {
541 return;
542 };
543
544 for (irradiance_volume, global_transform) in irradiance_volumes.iter() {
545 let Some(image) = image_assets.get(&irradiance_volume.voxels) else {
546 continue;
547 };
548
549 let resolution = image.texture_descriptor.size;
550
551 let voxel_cube_material = voxel_visualization_material_assets.add(ExtendedMaterial {
552 base: StandardMaterial::from(Color::from(RED)),
553 extension: VoxelVisualizationExtension {
554 irradiance_volume_info: VoxelVisualizationIrradianceVolumeInfo {
555 world_from_voxel: VOXEL_FROM_WORLD.inverse(),
556 voxel_from_world: VOXEL_FROM_WORLD,
557 resolution: uvec3(
558 resolution.width,
559 resolution.height,
560 resolution.depth_or_array_layers,
561 ),
562 intensity: IRRADIANCE_VOLUME_INTENSITY,
563 },
564 },
565 });
566
567 let scale = vec3(
568 1.0 / resolution.width as f32,
569 1.0 / resolution.height as f32,
570 1.0 / resolution.depth_or_array_layers as f32,
571 );
572
573 // Spawn a cube for each voxel.
574 for z in 0..resolution.depth_or_array_layers {
575 for y in 0..resolution.height {
576 for x in 0..resolution.width {
577 let uvw = (uvec3(x, y, z).as_vec3() + 0.5) * scale - 0.5;
578 let pos = global_transform.transform_point(uvw);
579 let voxel_cube = commands
580 .spawn((
581 Mesh3d(example_assets.voxel_cube.clone()),
582 MeshMaterial3d(voxel_cube_material.clone()),
583 Transform::from_scale(Vec3::splat(VOXEL_CUBE_SCALE))
584 .with_translation(pos),
585 ))
586 .insert(VoxelCube)
587 .insert(NotShadowCaster)
588 .id();
589
590 commands.entity(voxel_cube_parent).add_child(voxel_cube);
591 }
592 }
593 }
594 }
595}
More examples
162fn spawn_flight_helmet(commands: &mut Commands, asset_server: &AssetServer) {
163 commands.spawn((
164 SceneRoot(
165 asset_server
166 .load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
167 ),
168 Transform::from_scale(Vec3::splat(2.5)),
169 FlightHelmetModel,
170 Visibility::Hidden,
171 ));
172}
173
174// Spawns the water plane.
175fn spawn_water(
176 commands: &mut Commands,
177 asset_server: &AssetServer,
178 meshes: &mut Assets<Mesh>,
179 water_materials: &mut Assets<ExtendedMaterial<StandardMaterial, Water>>,
180) {
181 commands.spawn((
182 Mesh3d(meshes.add(Plane3d::new(Vec3::Y, Vec2::splat(1.0)))),
183 MeshMaterial3d(water_materials.add(ExtendedMaterial {
184 base: StandardMaterial {
185 base_color: BLACK.into(),
186 perceptual_roughness: 0.0,
187 ..default()
188 },
189 extension: Water {
190 normals: asset_server.load_with_settings::<Image, ImageLoaderSettings>(
191 "textures/water_normals.png",
192 |settings| {
193 settings.is_srgb = false;
194 settings.sampler = ImageSampler::Descriptor(ImageSamplerDescriptor {
195 address_mode_u: ImageAddressMode::Repeat,
196 address_mode_v: ImageAddressMode::Repeat,
197 mag_filter: ImageFilterMode::Linear,
198 min_filter: ImageFilterMode::Linear,
199 ..default()
200 });
201 },
202 ),
203 // These water settings are just random values to create some
204 // variety.
205 settings: WaterSettings {
206 octave_vectors: [
207 vec4(0.080, 0.059, 0.073, -0.062),
208 vec4(0.153, 0.138, -0.149, -0.195),
209 ],
210 octave_scales: vec4(1.0, 2.1, 7.9, 14.9) * 5.0,
211 octave_strengths: vec4(0.16, 0.18, 0.093, 0.044),
212 },
213 },
214 })),
215 Transform::from_scale(Vec3::splat(100.0)),
216 ));
217}
132fn spawn_player(mut commands: Commands, asset_server: Res<AssetServer>) {
133 commands.spawn(Camera2d);
134 commands.spawn((
135 Name::new("Player"),
136 Sprite::from_image(asset_server.load("branding/icon.png")),
137 Transform::from_scale(Vec3::splat(0.3)),
138 AccumulatedInput::default(),
139 Velocity::default(),
140 PhysicalTranslation::default(),
141 PreviousPhysicalTranslation::default(),
142 ));
143}
138fn spawn_reflection_probe(commands: &mut Commands, cubemaps: &Cubemaps) {
139 commands.spawn((
140 LightProbe,
141 EnvironmentMapLight {
142 diffuse_map: cubemaps.diffuse.clone(),
143 specular_map: cubemaps.specular_reflection_probe.clone(),
144 intensity: 5000.0,
145 ..default()
146 },
147 // 2.0 because the sphere's radius is 1.0 and we want to fully enclose it.
148 Transform::from_scale(Vec3::splat(2.0)),
149 ));
150}
47fn setup(
48 mut commands: Commands,
49 asset_server: Res<AssetServer>,
50 mut materials: ResMut<Assets<CustomMaterial>>,
51) {
52 // Add a mesh loaded from a glTF file. This mesh has data for `ATTRIBUTE_BARYCENTRIC`.
53 let mesh = asset_server.load(
54 GltfAssetLabel::Primitive {
55 mesh: 0,
56 primitive: 0,
57 }
58 .from_asset("models/barycentric/barycentric.gltf"),
59 );
60 commands.spawn((
61 Mesh2d(mesh),
62 MeshMaterial2d(materials.add(CustomMaterial {})),
63 Transform::from_scale(150.0 * Vec3::ONE),
64 ));
65
66 commands.spawn(Camera2d);
67}
10fn spawn_system(mut commands: Commands, asset_server: Res<AssetServer>) {
11 commands.spawn(Camera2d);
12 let texture = asset_server.load("branding/icon.png");
13
14 // We're seeding the PRNG here to make this example deterministic for testing purposes.
15 // This isn't strictly required in practical use unless you need your app to be deterministic.
16 let mut rng = ChaCha8Rng::seed_from_u64(19878367467713);
17 for z in 0..128 {
18 commands.spawn((
19 Sprite::from_image(texture.clone()),
20 Transform::from_scale(Vec3::splat(0.1))
21 .with_translation(Vec2::splat(0.0).extend(z as f32)),
22 Velocity(20.0 * Vec2::new(rng.r#gen::<f32>() - 0.5, rng.r#gen::<f32>() - 0.5)),
23 ));
24 }
25}
- examples/2d/sprite_sheet.rs
- examples/animation/animation_graph.rs
- examples/shader/compute_shader_game_of_life.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/time/virtual_time.rs
- examples/3d/motion_blur.rs
- examples/stress_tests/many_lights.rs
- examples/3d/decal.rs
- examples/ecs/iter_combinations.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?
204fn spawn_light(commands: &mut Commands) {
205 commands.spawn((
206 DirectionalLight::default(),
207 Transform::from_xyz(4.0, 8.0, 4.0).looking_at(Vec3::ZERO, Vec3::Y),
208 ));
209}
210
211/// Spawns the camera.
212fn spawn_camera(commands: &mut Commands) {
213 commands
214 .spawn(Camera3d::default())
215 .insert(Transform::from_xyz(0.0, 2.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y))
216 // Tag the camera with `Selection::Camera`.
217 .insert(Selection::Camera);
218}
More examples
295fn setup_cameras(mut commands: Commands) {
296 let start_in_2d = true;
297 let make_camera = |is_active| Camera {
298 is_active,
299 ..Default::default()
300 };
301
302 commands.spawn((Camera2d, make_camera(start_in_2d)));
303
304 commands.spawn((
305 Camera3d::default(),
306 make_camera(!start_in_2d),
307 Transform::from_xyz(0.0, 10.0, 0.0).looking_at(Vec3::ZERO, Vec3::Z),
308 ));
309}
310
311fn setup_ambient_light(mut ambient_light: ResMut<AmbientLight>) {
312 ambient_light.brightness = 50.0;
313}
314
315fn setup_lights(mut commands: Commands) {
316 commands.spawn((
317 PointLight {
318 intensity: 5000.0,
319 ..default()
320 },
321 Transform::from_translation(Vec3::new(-LEFT_RIGHT_OFFSET_3D, 2.0, 0.0))
322 .looking_at(Vec3::new(-LEFT_RIGHT_OFFSET_3D, 0.0, 0.0), Vec3::Y),
323 ));
324}
- 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/shader/fallback_image.rs
- examples/shader/custom_phase_item.rs
- examples/3d/3d_viewport_to_world.rs
- examples/shader/shader_material.rs
- examples/shader/shader_material_glsl.rs
- examples/shader/texture_binding_array.rs
- examples/asset/hot_asset_reloading.rs
- examples/asset/multi_asset_sync.rs
- examples/transforms/3d_rotation.rs
- examples/transforms/scale.rs
- examples/shader/custom_vertex_attribute.rs
- tests/window/minimizing.rs
- tests/window/resizing.rs
- examples/3d/color_grading.rs
- examples/3d/atmospheric_fog.rs
- examples/transforms/translation.rs
- examples/3d/load_gltf_extras.rs
- examples/animation/morph_targets.rs
- examples/shader/shader_defs.rs
- examples/3d/post_processing.rs
- examples/3d/3d_scene.rs
- examples/diagnostics/log_diagnostics.rs
- examples/animation/animated_mesh.rs
- examples/games/loading_screen.rs
- examples/shader/custom_post_processing.rs
- examples/animation/animation_graph.rs
- examples/3d/tonemapping.rs
- examples/shader/shader_material_screenspace_texture.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/3d/parenting.rs
- examples/3d/animated_material.rs
- examples/3d/depth_of_field.rs
- examples/window/screenshot.rs
- examples/camera/custom_projection.rs
- examples/3d/skybox.rs
- examples/3d/load_gltf.rs
- examples/3d/two_passes.rs
- examples/3d/lines.rs
- examples/stress_tests/many_materials.rs
- examples/3d/ssr.rs
- examples/shader/extended_material_bindless.rs
- examples/3d/update_gltf_scene.rs
- examples/shader/custom_render_phase.rs
- examples/3d/atmosphere.rs
- examples/3d/order_independent_transparency.rs
- examples/shader/storage_buffer.rs
- examples/3d/fog_volumes.rs
- examples/3d/generate_custom_mesh.rs
- examples/window/low_power.rs
- examples/movement/smooth_follow.rs
- examples/3d/mesh_ray_cast.rs
- examples/3d/vertex_colors.rs
- examples/shader/extended_material.rs
- examples/picking/simple_picking.rs
- examples/shader/custom_shader_instancing.rs
- examples/3d/orthographic.rs
- examples/shader/specialized_mesh_pipeline.rs
- examples/picking/debug_picking.rs
- examples/3d/spherical_area_lights.rs
- examples/transforms/transform.rs
- examples/window/multiple_windows.rs
- examples/gizmos/axes.rs
- examples/animation/animated_mesh_events.rs
- examples/app/headless_renderer.rs
- examples/animation/eased_motion.rs
- examples/3d/ssao.rs
- examples/3d/wireframe.rs
- examples/shader/automatic_instancing.rs
- examples/audio/spatial_audio_3d.rs
- examples/ecs/error_handling.rs
- examples/camera/projection_zoom.rs
- examples/3d/visibility_range.rs
- examples/3d/specular_tint.rs
- examples/testbed/3d.rs
- examples/animation/animated_mesh_control.rs
- examples/stress_tests/many_cameras_lights.rs
- examples/3d/volumetric_fog.rs
- examples/3d/texture.rs
- examples/3d/shadow_caster_receiver.rs
- examples/gizmos/3d_gizmos.rs
- examples/3d/bloom_3d.rs
- examples/3d/anti_aliasing.rs
- examples/transforms/align.rs
- examples/3d/decal.rs
- examples/math/random_sampling.rs
- examples/ui/render_ui_to_texture.rs
- examples/3d/scrolling_fog.rs
- examples/asset/repeated_texture.rs
- examples/ecs/iter_combinations.rs
- examples/asset/alter_mesh.rs
- examples/3d/transparency_3d.rs
- examples/2d/mesh2d_repeated_texture.rs
- examples/3d/3d_shapes.rs
- examples/3d/meshlet.rs
- examples/gizmos/light_gizmos.rs
- examples/3d/render_to_texture.rs
- examples/3d/pbr.rs
- examples/3d/spotlight.rs
- examples/asset/asset_loading.rs
- examples/3d/auto_exposure.rs
- examples/shader/shader_prepass.rs
- examples/picking/mesh_picking.rs
- examples/3d/shadow_biases.rs
- examples/stress_tests/many_foxes.rs
- examples/3d/split_screen.rs
- examples/math/sampling_primitives.rs
- examples/3d/fog.rs
- examples/3d/parallax_mapping.rs
- examples/3d/deferred_rendering.rs
- examples/animation/custom_skinned_mesh.rs
- examples/3d/blend_modes.rs
- examples/stress_tests/many_cubes.rs
- examples/3d/lighting.rs
- examples/animation/animated_transform.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
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.r#gen::<f32>() - 0.5, rng.r#gen::<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}
49fn setup_pyramid_scene(
50 mut commands: Commands,
51 mut meshes: ResMut<Assets<Mesh>>,
52 mut materials: ResMut<Assets<StandardMaterial>>,
53) {
54 let stone = materials.add(StandardMaterial {
55 base_color: Srgba::hex("28221B").unwrap().into(),
56 perceptual_roughness: 1.0,
57 ..default()
58 });
59
60 // pillars
61 for (x, z) in &[(-1.5, -1.5), (1.5, -1.5), (1.5, 1.5), (-1.5, 1.5)] {
62 commands.spawn((
63 Mesh3d(meshes.add(Cuboid::new(1.0, 3.0, 1.0))),
64 MeshMaterial3d(stone.clone()),
65 Transform::from_xyz(*x, 1.5, *z),
66 ));
67 }
68
69 // orb
70 commands.spawn((
71 Mesh3d(meshes.add(Sphere::default())),
72 MeshMaterial3d(materials.add(StandardMaterial {
73 base_color: Srgba::hex("126212CC").unwrap().into(),
74 reflectance: 1.0,
75 perceptual_roughness: 0.0,
76 metallic: 0.5,
77 alpha_mode: AlphaMode::Blend,
78 ..default()
79 })),
80 Transform::from_scale(Vec3::splat(1.75)).with_translation(Vec3::new(0.0, 4.0, 0.0)),
81 NotShadowCaster,
82 NotShadowReceiver,
83 ));
84
85 // steps
86 for i in 0..50 {
87 let half_size = i as f32 / 2.0 + 3.0;
88 let y = -i as f32 / 2.0;
89 commands.spawn((
90 Mesh3d(meshes.add(Cuboid::new(2.0 * half_size, 0.5, 2.0 * half_size))),
91 MeshMaterial3d(stone.clone()),
92 Transform::from_xyz(0.0, y + 0.25, 0.0),
93 ));
94 }
95
96 // sky
97 commands.spawn((
98 Mesh3d(meshes.add(Cuboid::new(2.0, 1.0, 1.0))),
99 MeshMaterial3d(materials.add(StandardMaterial {
100 base_color: Srgba::hex("888888").unwrap().into(),
101 unlit: true,
102 cull_mode: None,
103 ..default()
104 })),
105 Transform::from_scale(Vec3::splat(1_000_000.0)),
106 ));
107
108 // light
109 commands.spawn((
110 PointLight {
111 shadows_enabled: true,
112 ..default()
113 },
114 Transform::from_xyz(0.0, 1.0, 0.0),
115 ));
116}
85fn setup(
86 mut commands: Commands,
87 asset_server: Res<AssetServer>,
88 mut texture_atlas_layouts: ResMut<Assets<TextureAtlasLayout>>,
89) {
90 commands.spawn(Camera2d);
91
92 // Create a minimal UI explaining how to interact with the example
93 commands.spawn((
94 Text::new("Left Arrow: Animate Left Sprite\nRight Arrow: Animate Right Sprite"),
95 Node {
96 position_type: PositionType::Absolute,
97 top: Val::Px(12.0),
98 left: Val::Px(12.0),
99 ..default()
100 },
101 ));
102
103 // Load the sprite sheet using the `AssetServer`
104 let texture = asset_server.load("textures/rpg/chars/gabe/gabe-idle-run.png");
105
106 // The sprite sheet has 7 sprites arranged in a row, and they are all 24px x 24px
107 let layout = TextureAtlasLayout::from_grid(UVec2::splat(24), 7, 1, None, None);
108 let texture_atlas_layout = texture_atlas_layouts.add(layout);
109
110 // The first (left-hand) sprite runs at 10 FPS
111 let animation_config_1 = AnimationConfig::new(1, 6, 10);
112
113 // Create the first (left-hand) sprite
114 commands.spawn((
115 Sprite {
116 image: texture.clone(),
117 texture_atlas: Some(TextureAtlas {
118 layout: texture_atlas_layout.clone(),
119 index: animation_config_1.first_sprite_index,
120 }),
121 ..default()
122 },
123 Transform::from_scale(Vec3::splat(6.0)).with_translation(Vec3::new(-70.0, 0.0, 0.0)),
124 LeftSprite,
125 animation_config_1,
126 ));
127
128 // The second (right-hand) sprite runs at 20 FPS
129 let animation_config_2 = AnimationConfig::new(1, 6, 20);
130
131 // Create the second (right-hand) sprite
132 commands.spawn((
133 Sprite {
134 image: texture.clone(),
135 texture_atlas: Some(TextureAtlas {
136 layout: texture_atlas_layout.clone(),
137 index: animation_config_2.first_sprite_index,
138 }),
139 ..Default::default()
140 },
141 Transform::from_scale(Vec3::splat(6.0)).with_translation(Vec3::new(70.0, 0.0, 0.0)),
142 RightSprite,
143 animation_config_2,
144 ));
145}
526fn create_cubes(
527 image_assets: Res<Assets<Image>>,
528 mut commands: Commands,
529 irradiance_volumes: Query<(&IrradianceVolume, &GlobalTransform)>,
530 voxel_cube_parents: Query<Entity, With<VoxelCubeParent>>,
531 voxel_cubes: Query<Entity, With<VoxelCube>>,
532 example_assets: Res<ExampleAssets>,
533 mut voxel_visualization_material_assets: ResMut<Assets<VoxelVisualizationMaterial>>,
534) {
535 // If voxel cubes have already been spawned, don't do anything.
536 if !voxel_cubes.is_empty() {
537 return;
538 }
539
540 let Some(voxel_cube_parent) = voxel_cube_parents.iter().next() else {
541 return;
542 };
543
544 for (irradiance_volume, global_transform) in irradiance_volumes.iter() {
545 let Some(image) = image_assets.get(&irradiance_volume.voxels) else {
546 continue;
547 };
548
549 let resolution = image.texture_descriptor.size;
550
551 let voxel_cube_material = voxel_visualization_material_assets.add(ExtendedMaterial {
552 base: StandardMaterial::from(Color::from(RED)),
553 extension: VoxelVisualizationExtension {
554 irradiance_volume_info: VoxelVisualizationIrradianceVolumeInfo {
555 world_from_voxel: VOXEL_FROM_WORLD.inverse(),
556 voxel_from_world: VOXEL_FROM_WORLD,
557 resolution: uvec3(
558 resolution.width,
559 resolution.height,
560 resolution.depth_or_array_layers,
561 ),
562 intensity: IRRADIANCE_VOLUME_INTENSITY,
563 },
564 },
565 });
566
567 let scale = vec3(
568 1.0 / resolution.width as f32,
569 1.0 / resolution.height as f32,
570 1.0 / resolution.depth_or_array_layers as f32,
571 );
572
573 // Spawn a cube for each voxel.
574 for z in 0..resolution.depth_or_array_layers {
575 for y in 0..resolution.height {
576 for x in 0..resolution.width {
577 let uvw = (uvec3(x, y, z).as_vec3() + 0.5) * scale - 0.5;
578 let pos = global_transform.transform_point(uvw);
579 let voxel_cube = commands
580 .spawn((
581 Mesh3d(example_assets.voxel_cube.clone()),
582 MeshMaterial3d(voxel_cube_material.clone()),
583 Transform::from_scale(Vec3::splat(VOXEL_CUBE_SCALE))
584 .with_translation(pos),
585 ))
586 .insert(VoxelCube)
587 .insert(NotShadowCaster)
588 .id();
589
590 commands.entity(voxel_cube_parent).add_child(voxel_cube);
591 }
592 }
593 }
594 }
595}
44fn setup(
45 mut commands: Commands,
46 asset_server: Res<AssetServer>,
47 mut standard_materials: ResMut<Assets<StandardMaterial>>,
48 mut debug_materials: ResMut<Assets<MeshletDebugMaterial>>,
49 mut meshes: ResMut<Assets<Mesh>>,
50) {
51 commands.spawn((
52 Camera3d::default(),
53 Transform::from_translation(Vec3::new(1.8, 0.4, -0.1)).looking_at(Vec3::ZERO, Vec3::Y),
54 Msaa::Off,
55 EnvironmentMapLight {
56 diffuse_map: asset_server.load("environment_maps/pisa_diffuse_rgb9e5_zstd.ktx2"),
57 specular_map: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
58 intensity: 150.0,
59 ..default()
60 },
61 CameraController::default(),
62 ));
63
64 commands.spawn((
65 DirectionalLight {
66 illuminance: light_consts::lux::FULL_DAYLIGHT,
67 shadows_enabled: true,
68 ..default()
69 },
70 CascadeShadowConfigBuilder {
71 num_cascades: 1,
72 maximum_distance: 15.0,
73 ..default()
74 }
75 .build(),
76 Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, PI * -0.15, PI * -0.15)),
77 ));
78
79 // A custom file format storing a [`bevy_render::mesh::Mesh`]
80 // that has been converted to a [`bevy_pbr::meshlet::MeshletMesh`]
81 // using [`bevy_pbr::meshlet::MeshletMesh::from_mesh`], which is
82 // a function only available when the `meshlet_processor` cargo feature is enabled.
83 let meshlet_mesh_handle = asset_server.load("external/models/bunny.meshlet_mesh");
84 let debug_material = debug_materials.add(MeshletDebugMaterial::default());
85
86 for x in -2..=2 {
87 commands.spawn((
88 MeshletMesh3d(meshlet_mesh_handle.clone()),
89 MeshMaterial3d(standard_materials.add(StandardMaterial {
90 base_color: match x {
91 -2 => Srgba::hex("#dc2626").unwrap().into(),
92 -1 => Srgba::hex("#ea580c").unwrap().into(),
93 0 => Srgba::hex("#facc15").unwrap().into(),
94 1 => Srgba::hex("#16a34a").unwrap().into(),
95 2 => Srgba::hex("#0284c7").unwrap().into(),
96 _ => unreachable!(),
97 },
98 perceptual_roughness: (x + 2) as f32 / 4.0,
99 ..default()
100 })),
101 Transform::default()
102 .with_scale(Vec3::splat(0.2))
103 .with_translation(Vec3::new(x as f32 / 2.0, 0.0, -0.3)),
104 ));
105 }
106 for x in -2..=2 {
107 commands.spawn((
108 MeshletMesh3d(meshlet_mesh_handle.clone()),
109 MeshMaterial3d(debug_material.clone()),
110 Transform::default()
111 .with_scale(Vec3::splat(0.2))
112 .with_rotation(Quat::from_rotation_y(PI))
113 .with_translation(Vec3::new(x as f32 / 2.0, 0.0, 0.3)),
114 ));
115 }
116
117 commands.spawn((
118 Mesh3d(meshes.add(Plane3d::default().mesh().size(5.0, 5.0))),
119 MeshMaterial3d(standard_materials.add(StandardMaterial {
120 base_color: Color::WHITE,
121 perceptual_roughness: 1.0,
122 ..default()
123 })),
124 ));
125}
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?
91fn spawn_scene(commands: &mut Commands, asset_server: &AssetServer) {
92 // Spawn the main scene.
93 commands.spawn(SceneRoot(asset_server.load(
94 GltfAssetLabel::Scene(0).from_asset("models/TonemappingTest/TonemappingTest.gltf"),
95 )));
96
97 // Spawn the flight helmet.
98 commands.spawn((
99 SceneRoot(
100 asset_server
101 .load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
102 ),
103 Transform::from_xyz(0.5, 0.0, -0.5).with_rotation(Quat::from_rotation_y(-0.15 * PI)),
104 ));
105
106 // Spawn the light.
107 commands.spawn((
108 DirectionalLight {
109 illuminance: 15000.0,
110 shadows_enabled: true,
111 ..default()
112 },
113 Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, PI * -0.15, PI * -0.15)),
114 CascadeShadowConfigBuilder {
115 maximum_distance: 3.0,
116 first_cascade_far_bound: 0.9,
117 ..default()
118 }
119 .build(),
120 ));
121}
More examples
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}
360fn add_basic_scene(commands: &mut Commands, asset_server: &AssetServer) {
361 // Spawn the main scene.
362 commands.spawn(SceneRoot(asset_server.load(
363 GltfAssetLabel::Scene(0).from_asset("models/TonemappingTest/TonemappingTest.gltf"),
364 )));
365
366 // Spawn the flight helmet.
367 commands.spawn((
368 SceneRoot(
369 asset_server
370 .load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
371 ),
372 Transform::from_xyz(0.5, 0.0, -0.5).with_rotation(Quat::from_rotation_y(-0.15 * PI)),
373 ));
374
375 // Spawn the light.
376 commands.spawn((
377 DirectionalLight {
378 illuminance: 15000.0,
379 shadows_enabled: true,
380 ..default()
381 },
382 Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, PI * -0.15, PI * -0.15)),
383 CascadeShadowConfigBuilder {
384 maximum_distance: 3.0,
385 first_cascade_far_bound: 0.9,
386 ..default()
387 }
388 .build(),
389 ));
390}
95fn setup_basic_scene(mut commands: Commands, asset_server: Res<AssetServer>) {
96 // Main scene
97 commands.spawn((
98 SceneRoot(asset_server.load(
99 GltfAssetLabel::Scene(0).from_asset("models/TonemappingTest/TonemappingTest.gltf"),
100 )),
101 SceneNumber(1),
102 ));
103
104 // Flight Helmet
105 commands.spawn((
106 SceneRoot(
107 asset_server
108 .load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
109 ),
110 Transform::from_xyz(0.5, 0.0, -0.5).with_rotation(Quat::from_rotation_y(-0.15 * PI)),
111 SceneNumber(1),
112 ));
113
114 // light
115 commands.spawn((
116 DirectionalLight {
117 illuminance: 15_000.,
118 shadows_enabled: true,
119 ..default()
120 },
121 Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, PI * -0.15, PI * -0.15)),
122 CascadeShadowConfigBuilder {
123 maximum_distance: 3.0,
124 first_cascade_far_bound: 0.9,
125 ..default()
126 }
127 .build(),
128 SceneNumber(1),
129 ));
130}
60fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
61 // directional 'sun' light
62 commands.spawn((
63 DirectionalLight {
64 illuminance: 32000.0,
65 ..default()
66 },
67 Transform::from_xyz(0.0, 2.0, 0.0).with_rotation(Quat::from_rotation_x(-PI / 4.)),
68 ));
69
70 let skybox_handle = asset_server.load(CUBEMAPS[0].0);
71 // camera
72 commands.spawn((
73 Camera3d::default(),
74 Transform::from_xyz(0.0, 0.0, 8.0).looking_at(Vec3::ZERO, Vec3::Y),
75 CameraController::default(),
76 Skybox {
77 image: skybox_handle.clone(),
78 brightness: 1000.0,
79 ..default()
80 },
81 ));
82
83 // ambient light
84 // NOTE: The ambient light is used to scale how bright the environment map is so with a bright
85 // environment map, use an appropriate color and brightness to match
86 commands.insert_resource(AmbientLight {
87 color: Color::srgb_u8(210, 220, 240),
88 brightness: 1.0,
89 ..default()
90 });
91
92 commands.insert_resource(Cubemap {
93 is_loaded: false,
94 index: 0,
95 image_handle: skybox_handle,
96 });
97}
74fn setup(
75 mut commands: Commands,
76 mut meshes: ResMut<Assets<Mesh>>,
77 mut materials: ResMut<Assets<StandardMaterial>>,
78) {
79 // Make a box of planes facing inward so the laser gets trapped inside
80 let plane_mesh = meshes.add(Plane3d::default());
81 let plane_material = materials.add(Color::from(css::GRAY).with_alpha(0.01));
82 let create_plane = move |translation, rotation| {
83 (
84 Transform::from_translation(translation)
85 .with_rotation(Quat::from_scaled_axis(rotation)),
86 Mesh3d(plane_mesh.clone()),
87 MeshMaterial3d(plane_material.clone()),
88 )
89 };
90
91 commands.spawn(create_plane(vec3(0.0, 0.5, 0.0), Vec3::X * PI));
92 commands.spawn(create_plane(vec3(0.0, -0.5, 0.0), Vec3::ZERO));
93 commands.spawn(create_plane(vec3(0.5, 0.0, 0.0), Vec3::Z * FRAC_PI_2));
94 commands.spawn(create_plane(vec3(-0.5, 0.0, 0.0), Vec3::Z * -FRAC_PI_2));
95 commands.spawn(create_plane(vec3(0.0, 0.0, 0.5), Vec3::X * -FRAC_PI_2));
96 commands.spawn(create_plane(vec3(0.0, 0.0, -0.5), Vec3::X * FRAC_PI_2));
97
98 // Light
99 commands.spawn((
100 DirectionalLight::default(),
101 Transform::from_rotation(Quat::from_euler(EulerRot::XYZ, -0.1, 0.2, 0.0)),
102 ));
103
104 // Camera
105 commands.spawn((
106 Camera3d::default(),
107 Camera {
108 hdr: true,
109 ..default()
110 },
111 Transform::from_xyz(1.5, 1.5, 1.5).looking_at(Vec3::ZERO, Vec3::Y),
112 Tonemapping::TonyMcMapface,
113 Bloom::default(),
114 ));
115}
- 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/3d/decal.rs
- examples/ui/render_ui_to_texture.rs
- examples/picking/sprite_picking.rs
- examples/3d/3d_shapes.rs
- examples/3d/meshlet.rs
- examples/3d/render_to_texture.rs
- examples/picking/mesh_picking.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}
72fn setup_mesh(
73 mut commands: Commands,
74 mut meshes: ResMut<Assets<Mesh>>,
75 mut materials: ResMut<Assets<ColorMaterial>>,
76) {
77 commands.spawn((
78 Mesh2d(meshes.add(Capsule2d::default())),
79 MeshMaterial2d(materials.add(Color::BLACK)),
80 Transform::from_xyz(25., 0., 2.).with_scale(Vec3::splat(32.)),
81 Rotate,
82 PIXEL_PERFECT_LAYERS,
83 ));
84}
24fn setup(
25 mut commands: Commands,
26 mut meshes: ResMut<Assets<Mesh>>,
27 mut materials: ResMut<Assets<CustomMaterial>>,
28 asset_server: Res<AssetServer>,
29) {
30 // camera
31 commands.spawn(Camera2d);
32
33 // quad
34 commands.spawn((
35 Mesh2d(meshes.add(Rectangle::default())),
36 MeshMaterial2d(materials.add(CustomMaterial {
37 color: LinearRgba::BLUE,
38 color_texture: Some(asset_server.load("branding/icon.png")),
39 })),
40 Transform::default().with_scale(Vec3::splat(128.)),
41 ));
42}
- examples/3d/rotate_environment_map.rs
- examples/stress_tests/bevymark.rs
- examples/3d/clearcoat.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/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 compute_matrix(&self) -> Mat4
pub fn compute_matrix(&self) -> Mat4
Returns the 3d affine transformation matrix from this transforms 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>,
129 mut windows: Query<&mut Window>,
130 accumulated_mouse_motion: Res<AccumulatedMouseMotion>,
131 accumulated_mouse_scroll: Res<AccumulatedMouseScroll>,
132 mouse_button_input: Res<ButtonInput<MouseButton>>,
133 key_input: Res<ButtonInput<KeyCode>>,
134 mut toggle_cursor_grab: Local<bool>,
135 mut mouse_cursor_grab: Local<bool>,
136 mut query: Query<(&mut Transform, &mut CameraController), With<Camera>>,
137) {
138 let dt = time.delta_secs();
139
140 let Ok((mut transform, mut controller)) = query.single_mut() else {
141 return;
142 };
143
144 if !controller.initialized {
145 let (yaw, pitch, _roll) = transform.rotation.to_euler(EulerRot::YXZ);
146 controller.yaw = yaw;
147 controller.pitch = pitch;
148 controller.initialized = true;
149 info!("{}", *controller);
150 }
151 if !controller.enabled {
152 return;
153 }
154
155 let mut scroll = 0.0;
156
157 let amount = match accumulated_mouse_scroll.unit {
158 MouseScrollUnit::Line => accumulated_mouse_scroll.delta.y,
159 MouseScrollUnit::Pixel => accumulated_mouse_scroll.delta.y / 16.0,
160 };
161 scroll += amount;
162 controller.walk_speed += scroll * controller.scroll_factor * controller.walk_speed;
163 controller.run_speed = controller.walk_speed * 3.0;
164
165 // Handle key input
166 let mut axis_input = Vec3::ZERO;
167 if key_input.pressed(controller.key_forward) {
168 axis_input.z += 1.0;
169 }
170 if key_input.pressed(controller.key_back) {
171 axis_input.z -= 1.0;
172 }
173 if key_input.pressed(controller.key_right) {
174 axis_input.x += 1.0;
175 }
176 if key_input.pressed(controller.key_left) {
177 axis_input.x -= 1.0;
178 }
179 if key_input.pressed(controller.key_up) {
180 axis_input.y += 1.0;
181 }
182 if key_input.pressed(controller.key_down) {
183 axis_input.y -= 1.0;
184 }
185
186 let mut cursor_grab_change = false;
187 if key_input.just_pressed(controller.keyboard_key_toggle_cursor_grab) {
188 *toggle_cursor_grab = !*toggle_cursor_grab;
189 cursor_grab_change = true;
190 }
191 if mouse_button_input.just_pressed(controller.mouse_key_cursor_grab) {
192 *mouse_cursor_grab = true;
193 cursor_grab_change = true;
194 }
195 if mouse_button_input.just_released(controller.mouse_key_cursor_grab) {
196 *mouse_cursor_grab = false;
197 cursor_grab_change = true;
198 }
199 let cursor_grab = *mouse_cursor_grab || *toggle_cursor_grab;
200
201 // Apply movement update
202 if axis_input != Vec3::ZERO {
203 let max_speed = if key_input.pressed(controller.key_run) {
204 controller.run_speed
205 } else {
206 controller.walk_speed
207 };
208 controller.velocity = axis_input.normalize() * max_speed;
209 } else {
210 let friction = controller.friction.clamp(0.0, 1.0);
211 controller.velocity *= 1.0 - friction;
212 if controller.velocity.length_squared() < 1e-6 {
213 controller.velocity = Vec3::ZERO;
214 }
215 }
216 let forward = *transform.forward();
217 let right = *transform.right();
218 transform.translation += controller.velocity.x * dt * right
219 + controller.velocity.y * dt * Vec3::Y
220 + controller.velocity.z * dt * forward;
221
222 // Handle cursor grab
223 if cursor_grab_change {
224 if cursor_grab {
225 for mut window in &mut windows {
226 if !window.focused {
227 continue;
228 }
229
230 window.cursor_options.grab_mode = CursorGrabMode::Locked;
231 window.cursor_options.visible = false;
232 }
233 } else {
234 for mut window in &mut windows {
235 window.cursor_options.grab_mode = CursorGrabMode::None;
236 window.cursor_options.visible = true;
237 }
238 }
239 }
240
241 // Handle mouse input
242 if accumulated_mouse_motion.delta != Vec2::ZERO && cursor_grab {
243 // Apply look update
244 controller.pitch = (controller.pitch
245 - accumulated_mouse_motion.delta.y * RADIANS_PER_DOT * controller.sensitivity)
246 .clamp(-PI / 2., PI / 2.);
247 controller.yaw -=
248 accumulated_mouse_motion.delta.x * RADIANS_PER_DOT * controller.sensitivity;
249 transform.rotation = Quat::from_euler(EulerRot::ZYX, 0.0, controller.yaw, controller.pitch);
250 }
251}
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 a the sphere, with a given turn speed to get a smooth motion.
117 // With higher speed the curvature of the orbit would be smaller.
118 let incremental_turn_weight = cube.turn_speed * timer.delta_secs();
119 let old_rotation = transform.rotation;
120 transform.rotation = old_rotation.lerp(look_at_sphere.rotation, incremental_turn_weight);
121 }
122}
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?
298fn move_camera(
299 keyboard_input: Res<ButtonInput<KeyCode>>,
300 mut mouse_wheel_input: EventReader<MouseWheel>,
301 mut cameras: Query<&mut Transform, With<Camera>>,
302) {
303 let (mut distance_delta, mut theta_delta) = (0.0, 0.0);
304
305 // Handle keyboard events.
306 if keyboard_input.pressed(KeyCode::KeyW) {
307 distance_delta -= CAMERA_KEYBOARD_ZOOM_SPEED;
308 }
309 if keyboard_input.pressed(KeyCode::KeyS) {
310 distance_delta += CAMERA_KEYBOARD_ZOOM_SPEED;
311 }
312 if keyboard_input.pressed(KeyCode::KeyA) {
313 theta_delta += CAMERA_KEYBOARD_ORBIT_SPEED;
314 }
315 if keyboard_input.pressed(KeyCode::KeyD) {
316 theta_delta -= CAMERA_KEYBOARD_ORBIT_SPEED;
317 }
318
319 // Handle mouse events.
320 for mouse_wheel_event in mouse_wheel_input.read() {
321 distance_delta -= mouse_wheel_event.y * CAMERA_MOUSE_WHEEL_ZOOM_SPEED;
322 }
323
324 // Update transforms.
325 for mut camera_transform in cameras.iter_mut() {
326 let local_z = camera_transform.local_z().as_vec3().normalize_or_zero();
327 if distance_delta != 0.0 {
328 camera_transform.translation = (camera_transform.translation.length() + distance_delta)
329 .clamp(CAMERA_ZOOM_RANGE.start, CAMERA_ZOOM_RANGE.end)
330 * local_z;
331 }
332 if theta_delta != 0.0 {
333 camera_transform
334 .translate_around(Vec3::ZERO, Quat::from_axis_angle(Vec3::Y, theta_delta));
335 camera_transform.look_at(Vec3::ZERO, Vec3::Y);
336 }
337 }
338}
Sourcepub fn forward(&self) -> Dir3
pub fn forward(&self) -> Dir3
Equivalent to -local_z()
Examples found in repository?
More examples
132fn setup_color_gradient_scene(
133 mut commands: Commands,
134 mut meshes: ResMut<Assets<Mesh>>,
135 mut materials: ResMut<Assets<ColorGradientMaterial>>,
136 camera_transform: Res<CameraTransform>,
137) {
138 let mut transform = camera_transform.0;
139 transform.translation += *transform.forward();
140
141 commands.spawn((
142 Mesh3d(meshes.add(Rectangle::new(0.7, 0.7))),
143 MeshMaterial3d(materials.add(ColorGradientMaterial {})),
144 transform,
145 Visibility::Hidden,
146 SceneNumber(2),
147 ));
148}
149
150fn setup_image_viewer_scene(
151 mut commands: Commands,
152 mut meshes: ResMut<Assets<Mesh>>,
153 mut materials: ResMut<Assets<StandardMaterial>>,
154 camera_transform: Res<CameraTransform>,
155) {
156 let mut transform = camera_transform.0;
157 transform.translation += *transform.forward();
158
159 // exr/hdr viewer (exr requires enabling bevy feature)
160 commands.spawn((
161 Mesh3d(meshes.add(Rectangle::default())),
162 MeshMaterial3d(materials.add(StandardMaterial {
163 base_color_texture: None,
164 unlit: true,
165 ..default()
166 })),
167 transform,
168 Visibility::Hidden,
169 SceneNumber(3),
170 HDRViewer,
171 ));
172
173 commands.spawn((
174 Text::new("Drag and drop an HDR or EXR file"),
175 TextFont {
176 font_size: 36.0,
177 ..default()
178 },
179 TextColor(Color::BLACK),
180 TextLayout::new_with_justify(JustifyText::Center),
181 Node {
182 align_self: AlignSelf::Center,
183 margin: UiRect::all(Val::Auto),
184 ..default()
185 },
186 SceneNumber(3),
187 Visibility::Hidden,
188 ));
189}
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>,
129 mut windows: Query<&mut Window>,
130 accumulated_mouse_motion: Res<AccumulatedMouseMotion>,
131 accumulated_mouse_scroll: Res<AccumulatedMouseScroll>,
132 mouse_button_input: Res<ButtonInput<MouseButton>>,
133 key_input: Res<ButtonInput<KeyCode>>,
134 mut toggle_cursor_grab: Local<bool>,
135 mut mouse_cursor_grab: Local<bool>,
136 mut query: Query<(&mut Transform, &mut CameraController), With<Camera>>,
137) {
138 let dt = time.delta_secs();
139
140 let Ok((mut transform, mut controller)) = query.single_mut() else {
141 return;
142 };
143
144 if !controller.initialized {
145 let (yaw, pitch, _roll) = transform.rotation.to_euler(EulerRot::YXZ);
146 controller.yaw = yaw;
147 controller.pitch = pitch;
148 controller.initialized = true;
149 info!("{}", *controller);
150 }
151 if !controller.enabled {
152 return;
153 }
154
155 let mut scroll = 0.0;
156
157 let amount = match accumulated_mouse_scroll.unit {
158 MouseScrollUnit::Line => accumulated_mouse_scroll.delta.y,
159 MouseScrollUnit::Pixel => accumulated_mouse_scroll.delta.y / 16.0,
160 };
161 scroll += amount;
162 controller.walk_speed += scroll * controller.scroll_factor * controller.walk_speed;
163 controller.run_speed = controller.walk_speed * 3.0;
164
165 // Handle key input
166 let mut axis_input = Vec3::ZERO;
167 if key_input.pressed(controller.key_forward) {
168 axis_input.z += 1.0;
169 }
170 if key_input.pressed(controller.key_back) {
171 axis_input.z -= 1.0;
172 }
173 if key_input.pressed(controller.key_right) {
174 axis_input.x += 1.0;
175 }
176 if key_input.pressed(controller.key_left) {
177 axis_input.x -= 1.0;
178 }
179 if key_input.pressed(controller.key_up) {
180 axis_input.y += 1.0;
181 }
182 if key_input.pressed(controller.key_down) {
183 axis_input.y -= 1.0;
184 }
185
186 let mut cursor_grab_change = false;
187 if key_input.just_pressed(controller.keyboard_key_toggle_cursor_grab) {
188 *toggle_cursor_grab = !*toggle_cursor_grab;
189 cursor_grab_change = true;
190 }
191 if mouse_button_input.just_pressed(controller.mouse_key_cursor_grab) {
192 *mouse_cursor_grab = true;
193 cursor_grab_change = true;
194 }
195 if mouse_button_input.just_released(controller.mouse_key_cursor_grab) {
196 *mouse_cursor_grab = false;
197 cursor_grab_change = true;
198 }
199 let cursor_grab = *mouse_cursor_grab || *toggle_cursor_grab;
200
201 // Apply movement update
202 if axis_input != Vec3::ZERO {
203 let max_speed = if key_input.pressed(controller.key_run) {
204 controller.run_speed
205 } else {
206 controller.walk_speed
207 };
208 controller.velocity = axis_input.normalize() * max_speed;
209 } else {
210 let friction = controller.friction.clamp(0.0, 1.0);
211 controller.velocity *= 1.0 - friction;
212 if controller.velocity.length_squared() < 1e-6 {
213 controller.velocity = Vec3::ZERO;
214 }
215 }
216 let forward = *transform.forward();
217 let right = *transform.right();
218 transform.translation += controller.velocity.x * dt * right
219 + controller.velocity.y * dt * Vec3::Y
220 + controller.velocity.z * dt * forward;
221
222 // Handle cursor grab
223 if cursor_grab_change {
224 if cursor_grab {
225 for mut window in &mut windows {
226 if !window.focused {
227 continue;
228 }
229
230 window.cursor_options.grab_mode = CursorGrabMode::Locked;
231 window.cursor_options.visible = false;
232 }
233 } else {
234 for mut window in &mut windows {
235 window.cursor_options.grab_mode = CursorGrabMode::None;
236 window.cursor_options.visible = true;
237 }
238 }
239 }
240
241 // Handle mouse input
242 if accumulated_mouse_motion.delta != Vec2::ZERO && cursor_grab {
243 // Apply look update
244 controller.pitch = (controller.pitch
245 - accumulated_mouse_motion.delta.y * RADIANS_PER_DOT * controller.sensitivity)
246 .clamp(-PI / 2., PI / 2.);
247 controller.yaw -=
248 accumulated_mouse_motion.delta.x * RADIANS_PER_DOT * controller.sensitivity;
249 transform.rotation = Quat::from_euler(EulerRot::ZYX, 0.0, controller.yaw, controller.pitch);
250 }
251}
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
75fn update(
76 time: Res<Time>,
77 mut query: Query<(&MeshMaterial3d<CustomMaterial>, &mut Transform)>,
78 mut materials: ResMut<Assets<CustomMaterial>>,
79 keys: Res<ButtonInput<KeyCode>>,
80) {
81 for (material, mut transform) in query.iter_mut() {
82 let material = materials.get_mut(material).unwrap();
83 material.time.x = time.elapsed_secs();
84 if keys.just_pressed(KeyCode::Space) {
85 material.party_mode = !material.party_mode;
86 }
87
88 if material.party_mode {
89 transform.rotate(Quat::from_rotation_y(0.005));
90 }
91 }
92}
600fn flicker_system(
601 mut flame: Single<&mut Transform, (With<Flicker>, With<Mesh3d>)>,
602 light: Single<(&mut PointLight, &mut Transform), (With<Flicker>, Without<Mesh3d>)>,
603 time: Res<Time>,
604) {
605 let s = time.elapsed_secs();
606 let a = ops::cos(s * 6.0) * 0.0125 + ops::cos(s * 4.0) * 0.025;
607 let b = ops::cos(s * 5.0) * 0.0125 + ops::cos(s * 3.0) * 0.025;
608 let c = ops::cos(s * 7.0) * 0.0125 + ops::cos(s * 2.0) * 0.025;
609 let (mut light, mut light_transform) = light.into_inner();
610 light.intensity = 4_000.0 + 3000.0 * (a + b + c);
611 flame.translation = Vec3::new(-1.0, 1.23, 0.0);
612 flame.look_at(Vec3::new(-1.0 - c, 1.7 - b, 0.0 - a), Vec3::X);
613 flame.rotate(Quat::from_euler(EulerRot::XYZ, 0.0, 0.0, PI / 2.0));
614 light_transform.translation = Vec3::new(-1.0 - c, 1.7, 0.0 - a);
615 flame.translation = Vec3::new(-1.0 - c, 1.23, 0.0 - a);
616}
169fn move_directional_light(
170 input: Res<ButtonInput<KeyCode>>,
171 mut directional_lights: Query<&mut Transform, With<DirectionalLight>>,
172) {
173 let mut delta_theta = Vec2::ZERO;
174 if input.pressed(KeyCode::KeyW) || input.pressed(KeyCode::ArrowUp) {
175 delta_theta.y += DIRECTIONAL_LIGHT_MOVEMENT_SPEED;
176 }
177 if input.pressed(KeyCode::KeyS) || input.pressed(KeyCode::ArrowDown) {
178 delta_theta.y -= DIRECTIONAL_LIGHT_MOVEMENT_SPEED;
179 }
180 if input.pressed(KeyCode::KeyA) || input.pressed(KeyCode::ArrowLeft) {
181 delta_theta.x += DIRECTIONAL_LIGHT_MOVEMENT_SPEED;
182 }
183 if input.pressed(KeyCode::KeyD) || input.pressed(KeyCode::ArrowRight) {
184 delta_theta.x -= DIRECTIONAL_LIGHT_MOVEMENT_SPEED;
185 }
186
187 if delta_theta == Vec2::ZERO {
188 return;
189 }
190
191 let delta_quat = Quat::from_euler(EulerRot::XZY, delta_theta.y, 0.0, delta_theta.x);
192 for mut transform in directional_lights.iter_mut() {
193 transform.rotate(delta_quat);
194 }
195}
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?
137fn track_targets(
138 // `Single` ensures the system runs ONLY when exactly one matching entity exists.
139 mut player: Single<(&mut Transform, &Player)>,
140 // `Option<Single>` ensures that the system runs ONLY when zero or one matching entity exists.
141 enemy: Option<Single<&Transform, (With<Enemy>, Without<Player>)>>,
142 time: Res<Time>,
143) {
144 let (player_transform, player) = &mut *player;
145 if let Some(enemy_transform) = enemy {
146 // Enemy found, rotate and move towards it.
147 let delta = enemy_transform.translation - player_transform.translation;
148 let distance = delta.length();
149 let front = delta / distance;
150 let up = Vec3::Z;
151 let side = front.cross(up);
152 player_transform.rotation = Quat::from_mat3(&Mat3::from_cols(side, front, up));
153 let max_step = distance - player.min_follow_radius;
154 if 0.0 < max_step {
155 let velocity = (player.speed * time.delta_secs()).min(max_step);
156 player_transform.translation += front * velocity;
157 }
158 } else {
159 // 0 or multiple enemies found, keep searching.
160 player_transform.rotate_axis(Dir3::Z, player.rotation_speed * time.delta_secs());
161 }
162}
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
124fn rotator_system(time: Res<Time>, mut query: Query<&mut Transform, With<FirstPassCube>>) {
125 for mut transform in &mut query {
126 transform.rotate_x(1.5 * time.delta_secs());
127 transform.rotate_z(1.3 * time.delta_secs());
128 }
129}
130
131/// Rotates the outer cube (main pass)
132fn cube_rotator_system(time: Res<Time>, mut query: Query<&mut Transform, With<MainPassCube>>) {
133 for mut transform in &mut query {
134 transform.rotate_x(1.0 * time.delta_secs());
135 transform.rotate_y(0.7 * time.delta_secs());
136 }
137}
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: Trigger<Pointer<Drag>>, mut transforms: Query<&mut Transform>) {
194 let mut transform = transforms.get_mut(drag.target()).unwrap();
195 transform.rotate_y(drag.delta.x * 0.02);
196 transform.rotate_x(drag.delta.y * 0.02);
197}
- examples/3d/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/games/alien_cake_addict.rs
- examples/stress_tests/many_foxes.rs
- examples/transforms/3d_rotation.rs
- examples/3d/clustered_decals.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)
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?
298fn move_camera(
299 keyboard_input: Res<ButtonInput<KeyCode>>,
300 mut mouse_wheel_input: EventReader<MouseWheel>,
301 mut cameras: Query<&mut Transform, With<Camera>>,
302) {
303 let (mut distance_delta, mut theta_delta) = (0.0, 0.0);
304
305 // Handle keyboard events.
306 if keyboard_input.pressed(KeyCode::KeyW) {
307 distance_delta -= CAMERA_KEYBOARD_ZOOM_SPEED;
308 }
309 if keyboard_input.pressed(KeyCode::KeyS) {
310 distance_delta += CAMERA_KEYBOARD_ZOOM_SPEED;
311 }
312 if keyboard_input.pressed(KeyCode::KeyA) {
313 theta_delta += CAMERA_KEYBOARD_ORBIT_SPEED;
314 }
315 if keyboard_input.pressed(KeyCode::KeyD) {
316 theta_delta -= CAMERA_KEYBOARD_ORBIT_SPEED;
317 }
318
319 // Handle mouse events.
320 for mouse_wheel_event in mouse_wheel_input.read() {
321 distance_delta -= mouse_wheel_event.y * CAMERA_MOUSE_WHEEL_ZOOM_SPEED;
322 }
323
324 // Update transforms.
325 for mut camera_transform in cameras.iter_mut() {
326 let local_z = camera_transform.local_z().as_vec3().normalize_or_zero();
327 if distance_delta != 0.0 {
328 camera_transform.translation = (camera_transform.translation.length() + distance_delta)
329 .clamp(CAMERA_ZOOM_RANGE.start, CAMERA_ZOOM_RANGE.end)
330 * local_z;
331 }
332 if theta_delta != 0.0 {
333 camera_transform
334 .translate_around(Vec3::ZERO, Quat::from_axis_angle(Vec3::Y, theta_delta));
335 camera_transform.look_at(Vec3::ZERO, Vec3::Y);
336 }
337 }
338}
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
191fn rotation(
192 mut transform: Single<&mut Transform, With<Camera>>,
193 input: Res<ButtonInput<KeyCode>>,
194 time: Res<Time>,
195) {
196 let delta = time.delta_secs();
197
198 if input.pressed(KeyCode::ArrowLeft) {
199 transform.rotate_around(Vec3::ZERO, Quat::from_rotation_y(delta));
200 } else if input.pressed(KeyCode::ArrowRight) {
201 transform.rotate_around(Vec3::ZERO, Quat::from_rotation_y(-delta));
202 }
203}
191fn handle_mouse(
192 accumulated_mouse_motion: Res<AccumulatedMouseMotion>,
193 mut button_events: EventReader<MouseButtonInput>,
194 mut camera_transform: Single<&mut Transform, With<Camera>>,
195 mut mouse_pressed: ResMut<MousePressed>,
196) {
197 // Store left-pressed state in the MousePressed resource
198 for button_event in button_events.read() {
199 if button_event.button != MouseButton::Left {
200 continue;
201 }
202 *mouse_pressed = MousePressed(button_event.state.is_pressed());
203 }
204
205 // If the mouse is not pressed, just ignore motion events
206 if !mouse_pressed.0 {
207 return;
208 }
209 if accumulated_mouse_motion.delta != Vec2::ZERO {
210 let displacement = accumulated_mouse_motion.delta.x;
211 camera_transform.rotate_around(Vec3::ZERO, Quat::from_rotation_y(-displacement / 75.));
212 }
213}
221fn handle_mouse(
222 accumulated_mouse_motion: Res<AccumulatedMouseMotion>,
223 mut button_events: EventReader<MouseButtonInput>,
224 mut camera_transform: Single<&mut Transform, With<Camera>>,
225 mut mouse_pressed: ResMut<MousePressed>,
226) {
227 // Store left-pressed state in the MousePressed resource
228 for button_event in button_events.read() {
229 if button_event.button != MouseButton::Left {
230 continue;
231 }
232 *mouse_pressed = MousePressed(button_event.state.is_pressed());
233 }
234
235 // If the mouse is not pressed, just ignore motion events
236 if !mouse_pressed.0 {
237 return;
238 }
239 if accumulated_mouse_motion.delta != Vec2::ZERO {
240 let displacement = accumulated_mouse_motion.delta.x;
241 camera_transform.rotate_around(Vec3::ZERO, Quat::from_rotation_y(-displacement / 150.));
242 }
243}
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
232fn animate_light(
233 mut lights: Query<&mut Transform, Or<(With<PointLight>, With<DirectionalLight>)>>,
234 time: Res<Time>,
235) {
236 let now = time.elapsed_secs();
237 for mut transform in lights.iter_mut() {
238 transform.translation = vec3(
239 ops::sin(now * 1.4),
240 ops::cos(now * 1.0),
241 ops::cos(now * 0.6),
242 ) * vec3(3.0, 4.0, 3.0);
243 transform.look_at(Vec3::ZERO, Vec3::Y);
244 }
245}
296fn rotate_camera(
297 time: Res<Time>,
298 mut camera_query: Query<&mut Transform, With<Camera3d>>,
299 app_status: Res<AppStatus>,
300) {
301 if !app_status.rotating {
302 return;
303 }
304
305 for mut transform in camera_query.iter_mut() {
306 transform.translation = Vec2::from_angle(time.delta_secs() * PI / 5.0)
307 .rotate(transform.translation.xz())
308 .extend(transform.translation.y)
309 .xzy();
310 transform.look_at(Vec3::ZERO, Vec3::Y);
311 }
312}
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?
73fn input_handler(
74 keyboard_input: Res<ButtonInput<KeyCode>>,
75 mesh_query: Query<&Mesh3d, With<CustomUV>>,
76 mut meshes: ResMut<Assets<Mesh>>,
77 mut query: Query<&mut Transform, With<CustomUV>>,
78 time: Res<Time>,
79) {
80 if keyboard_input.just_pressed(KeyCode::Space) {
81 let mesh_handle = mesh_query.single().expect("Query not successful");
82 let mesh = meshes.get_mut(mesh_handle).unwrap();
83 toggle_texture(mesh);
84 }
85 if keyboard_input.pressed(KeyCode::KeyX) {
86 for mut transform in &mut query {
87 transform.rotate_x(time.delta_secs() / 1.2);
88 }
89 }
90 if keyboard_input.pressed(KeyCode::KeyY) {
91 for mut transform in &mut query {
92 transform.rotate_y(time.delta_secs() / 1.2);
93 }
94 }
95 if keyboard_input.pressed(KeyCode::KeyZ) {
96 for mut transform in &mut query {
97 transform.rotate_z(time.delta_secs() / 1.2);
98 }
99 }
100 if keyboard_input.pressed(KeyCode::KeyR) {
101 for mut transform in &mut query {
102 transform.look_to(Vec3::NEG_Z, Vec3::Y);
103 }
104 }
105}
More examples
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?
137fn setup(
138 mut commands: Commands,
139 args: Res<Args>,
140 mesh_assets: ResMut<Assets<Mesh>>,
141 material_assets: ResMut<Assets<StandardMaterial>>,
142 images: ResMut<Assets<Image>>,
143) {
144 warn!(include_str!("warning_string.txt"));
145
146 let args = args.into_inner();
147 let images = images.into_inner();
148 let material_assets = material_assets.into_inner();
149 let mesh_assets = mesh_assets.into_inner();
150
151 let meshes = init_meshes(args, mesh_assets);
152
153 let material_textures = init_textures(args, images);
154 let materials = init_materials(args, &material_textures, material_assets);
155
156 // We're seeding the PRNG here to make this example deterministic for testing purposes.
157 // This isn't strictly required in practical use unless you need your app to be deterministic.
158 let mut material_rng = ChaCha8Rng::seed_from_u64(42);
159 match args.layout {
160 Layout::Sphere => {
161 // NOTE: This pattern is good for testing performance of culling as it provides roughly
162 // the same number of visible meshes regardless of the viewing angle.
163 const N_POINTS: usize = WIDTH * HEIGHT * 4;
164 // NOTE: f64 is used to avoid precision issues that produce visual artifacts in the distribution
165 let radius = WIDTH as f64 * 2.5;
166 let golden_ratio = 0.5f64 * (1.0f64 + 5.0f64.sqrt());
167 for i in 0..N_POINTS {
168 let spherical_polar_theta_phi =
169 fibonacci_spiral_on_sphere(golden_ratio, i, N_POINTS);
170 let unit_sphere_p = spherical_polar_to_cartesian(spherical_polar_theta_phi);
171 let (mesh, transform) = meshes.choose(&mut material_rng).unwrap();
172 commands
173 .spawn((
174 Mesh3d(mesh.clone()),
175 MeshMaterial3d(materials.choose(&mut material_rng).unwrap().clone()),
176 Transform::from_translation((radius * unit_sphere_p).as_vec3())
177 .looking_at(Vec3::ZERO, Vec3::Y)
178 .mul_transform(*transform),
179 ))
180 .insert_if(NoFrustumCulling, || args.no_frustum_culling)
181 .insert_if(NoAutomaticBatching, || args.no_automatic_batching);
182 }
183
184 // camera
185 let mut camera = commands.spawn(Camera3d::default());
186 if args.no_indirect_drawing {
187 camera.insert(NoIndirectDrawing);
188 }
189 if args.no_cpu_culling {
190 camera.insert(NoCpuCulling);
191 }
192
193 // Inside-out box around the meshes onto which shadows are cast (though you cannot see them...)
194 commands.spawn((
195 Mesh3d(mesh_assets.add(Cuboid::from_size(Vec3::splat(radius as f32 * 2.2)))),
196 MeshMaterial3d(material_assets.add(StandardMaterial::from(Color::WHITE))),
197 Transform::from_scale(-Vec3::ONE),
198 NotShadowCaster,
199 ));
200 }
201 _ => {
202 // NOTE: This pattern is good for demonstrating that frustum culling is working correctly
203 // as the number of visible meshes rises and falls depending on the viewing angle.
204 let scale = 2.5;
205 for x in 0..WIDTH {
206 for y in 0..HEIGHT {
207 // introduce spaces to break any kind of moiré pattern
208 if x % 10 == 0 || y % 10 == 0 {
209 continue;
210 }
211 // cube
212 commands.spawn((
213 Mesh3d(meshes.choose(&mut material_rng).unwrap().0.clone()),
214 MeshMaterial3d(materials.choose(&mut material_rng).unwrap().clone()),
215 Transform::from_xyz((x as f32) * scale, (y as f32) * scale, 0.0),
216 ));
217 commands.spawn((
218 Mesh3d(meshes.choose(&mut material_rng).unwrap().0.clone()),
219 MeshMaterial3d(materials.choose(&mut material_rng).unwrap().clone()),
220 Transform::from_xyz(
221 (x as f32) * scale,
222 HEIGHT as f32 * scale,
223 (y as f32) * scale,
224 ),
225 ));
226 commands.spawn((
227 Mesh3d(meshes.choose(&mut material_rng).unwrap().0.clone()),
228 MeshMaterial3d(materials.choose(&mut material_rng).unwrap().clone()),
229 Transform::from_xyz((x as f32) * scale, 0.0, (y as f32) * scale),
230 ));
231 commands.spawn((
232 Mesh3d(meshes.choose(&mut material_rng).unwrap().0.clone()),
233 MeshMaterial3d(materials.choose(&mut material_rng).unwrap().clone()),
234 Transform::from_xyz(0.0, (x as f32) * scale, (y as f32) * scale),
235 ));
236 }
237 }
238 // camera
239 let center = 0.5 * scale * Vec3::new(WIDTH as f32, HEIGHT as f32, WIDTH as f32);
240 commands.spawn((Camera3d::default(), Transform::from_translation(center)));
241 // Inside-out box around the meshes onto which shadows are cast (though you cannot see them...)
242 commands.spawn((
243 Mesh3d(mesh_assets.add(Cuboid::from_size(2.0 * 1.1 * center))),
244 MeshMaterial3d(material_assets.add(StandardMaterial::from(Color::WHITE))),
245 Transform::from_scale(-Vec3::ONE).with_translation(center),
246 NotShadowCaster,
247 ));
248 }
249 }
250
251 commands.spawn((
252 DirectionalLight {
253 shadows_enabled: args.shadows,
254 ..default()
255 },
256 Transform::IDENTITY.looking_at(Vec3::new(0.0, -1.0, -1.0), Vec3::Y),
257 ));
258}
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?
221fn bounding_shapes_3d(
222 shapes: Query<&Transform, With<Shape3d>>,
223 mut gizmos: Gizmos,
224 bounding_shape: Res<State<BoundingShape>>,
225) {
226 for transform in shapes.iter() {
227 match bounding_shape.get() {
228 BoundingShape::None => (),
229 BoundingShape::BoundingBox => {
230 // Get the AABB of the extrusion with the rotation and translation of the mesh.
231 let aabb = EXTRUSION.aabb_3d(transform.to_isometry());
232
233 gizmos.primitive_3d(
234 &Cuboid::from_size(Vec3::from(aabb.half_size()) * 2.),
235 aabb.center(),
236 WHITE,
237 );
238 }
239 BoundingShape::BoundingSphere => {
240 // Get the bounding sphere of the extrusion with the rotation and translation of the mesh.
241 let bounding_sphere = EXTRUSION.bounding_sphere(transform.to_isometry());
242
243 gizmos.sphere(bounding_sphere.center(), bounding_sphere.radius(), WHITE);
244 }
245 }
246 }
247}
Trait Implementations§
Source§impl Animatable for Transform
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,
components: &mut ComponentsRegistrator<'_>,
required_components: &mut RequiredComponents,
inheritance_depth: u16,
recursion_check_stack: &mut Vec<ComponentId>,
)
fn register_required_components( requiree: ComponentId, components: &mut ComponentsRegistrator<'_>, required_components: &mut RequiredComponents, inheritance_depth: u16, recursion_check_stack: &mut Vec<ComponentId>, )
Source§fn clone_behavior() -> ComponentCloneBehavior
fn clone_behavior() -> ComponentCloneBehavior
Source§fn register_component_hooks(hooks: &mut ComponentHooks)
fn register_component_hooks(hooks: &mut ComponentHooks)
Component::on_add
, etc.)ComponentHooks
.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 FromArg for &'static Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
impl FromArg for &'static Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Source§impl FromArg for &'static mut Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
impl FromArg for &'static mut Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Source§impl FromArg for Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
impl FromArg for Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Source§impl FromReflect for Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
impl FromReflect for Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
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 &Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
impl GetOwnership for &Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Source§impl GetOwnership for &mut Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
impl GetOwnership for &mut Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Source§impl GetOwnership for Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
impl GetOwnership for Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Source§impl GetTypeRegistration for Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
impl GetTypeRegistration for Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
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 &Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
impl IntoReturn for &Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Source§impl IntoReturn for &mut Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
impl IntoReturn for &mut Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Source§impl IntoReturn for Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
impl IntoReturn for Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
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 Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
impl PartialReflect for Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
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 clone_value(&self) -> Box<dyn PartialReflect>
fn clone_value(&self) -> Box<dyn PartialReflect>
reflect_clone
. To convert reflected values to dynamic ones, use to_dynamic
.Self
into its dynamic representation. Read moreSource§fn to_dynamic(&self) -> Box<dyn PartialReflect>
fn to_dynamic(&self) -> Box<dyn PartialReflect>
Source§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 Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
impl Reflect for Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
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 Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
impl Struct for Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
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<'_> ⓘ
fn to_dynamic_struct(&self) -> DynamicStruct
Source§fn clone_dynamic(&self) -> DynamicStruct
fn clone_dynamic(&self) -> DynamicStruct
to_dynamic_struct
insteadDynamicStruct
.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>
Source§impl Typed for Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
impl Typed for Transformwhere
Transform: Any + Send + Sync,
Vec3: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
Quat: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
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 register_required_components(
components: &mut ComponentsRegistrator<'_>,
required_components: &mut RequiredComponents,
)
fn register_required_components( components: &mut ComponentsRegistrator<'_>, required_components: &mut RequiredComponents, )
Bundle
.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,
fn get_components( self, func: &mut impl FnMut(StorageType, OwningPtr<'_>), ) -> <C as DynamicBundle>::Effect
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> 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<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<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.