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
Transformand aGlobalTransform.GlobalTransformis automatically inserted wheneverTransformis inserted.
Transforms compose from right to left: if t1 and t2 are transforms, then t1 * t2
corresponds to applying t2 first, then applying t1.
§Transform and GlobalTransform
Transform is the position of an entity relative to its parent position, or the reference
frame if it doesn’t have a ChildOf component.
GlobalTransform is the position of an entity relative to the reference frame.
GlobalTransform is updated from Transform in the TransformSystems::Propagate
system set.
This system runs during PostUpdate. If you
update the Transform of an entity during this set or after, you will notice a 1 frame lag
before the GlobalTransform is updated.
§Examples
Fields§
§translation: Vec3Position of the entity. In 2d, the last value of the Vec3 is used for z-ordering.
See the translations example for usage.
rotation: QuatRotation of the entity.
See the 3d_rotation example for usage.
scale: Vec3Scale 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?
99const FREE_CAMERA_START_TRANSFORM: Transform = Transform::from_xyz(-20., 10., 22.);
100const FREE_CAMERA_START_TARGET: Vec3 = Vec3::new(7., 1.5, 0.);
101
102fn setup(
103 mut commands: Commands,
104 windows: Query<&Window>,
105 mut config_store: ResMut<GizmoConfigStore>,
106 mut meshes: ResMut<Assets<Mesh>>,
107 mut materials: ResMut<Assets<StandardMaterial>>,
108) -> Result {
109 let window = windows.single()?;
110 // The camera that the user controls to observe the scene.
111 let free_camera = commands
112 .spawn((
113 Camera3d::default(),
114 FREE_CAMERA_START_TRANSFORM.looking_at(FREE_CAMERA_START_TARGET, Vec3::Y),
115 FreeCamera::default(),
116 ))
117 .id();
118
119 // The camera that we want to debug frustum culling for. This will be rendered
120 // as a picture-in-picture in the lower right ninth of the screen.
121 let my_camera = commands
122 .spawn((
123 Camera3d::default(),
124 Transform::from_xyz(0., 1.5, 0.).looking_at(Vec3::new(1.0, 1.5, 0.), Vec3::Y),
125 Camera {
126 order: 1,
127 // The camera-to-debug's view will be in the lower right ninth of the screen.
128 viewport: Some(Viewport {
129 physical_position: window.physical_size() * 2 / 3,
130 physical_size: window.physical_size() / 3,
131 ..default()
132 }),
133 // Do not write the free camera's view rendering back into the P-I-P
134 msaa_writeback: MsaaWriteback::Off,
135 ..default()
136 },
137 MyCamera,
138 ))
139 .id();
140
141 // Instructions placed on top of the free_camera view
142 commands.spawn((
143 UiTargetCamera(free_camera),
144 Node {
145 width: percent(100),
146 height: percent(100),
147 ..default()
148 },
149 children![(
150 Text::new(
151 "This example utilizes free camera controls i.e. move with WASD and mouse grab to change orientation.\n\
152 Press '1' to move the free camera to where MyCamera is, matching its view frustum.\n\
153 Press '2' to move the free camera to its initial position in the example.",
154 ),
155 Node {
156 position_type: PositionType::Absolute,
157 top: px(12),
158 left: px(12),
159 ..default()
160 },
161 )]
162 ));
163 // Label for the picture-in-picture view of MyCamera
164 commands.spawn((
165 UiTargetCamera(my_camera),
166 Node {
167 width: percent(100),
168 height: percent(100),
169 ..default()
170 },
171 children![(
172 Text::new("View of MyCamera"),
173 Node {
174 position_type: PositionType::Absolute,
175 bottom: px(12),
176 right: px(100),
177 ..default()
178 },
179 )],
180 ));
181
182 // Green Floor Plane
183 commands.spawn((
184 Mesh3d(
185 meshes.add(
186 Plane3d::default()
187 .mesh()
188 .size(SHAPE_RING_RADIUS * 4., SHAPE_RING_RADIUS * 4.),
189 ),
190 ),
191 MeshMaterial3d(materials.add(Color::srgb(0.3, 0.5, 0.3))),
192 ));
193 // Blue Wall Plane
194 commands.spawn((
195 Mesh3d(meshes.add(Plane3d::default().mesh().size(5., 5.))),
196 MeshMaterial3d(materials.add(Color::srgb(0.3, 0.3, 0.5))),
197 Transform::from_xyz(20., 2.5, 10.).with_rotation(Quat::from_rotation_z(PI / 2.)),
198 ));
199 // Light
200 commands.spawn((
201 PointLight {
202 shadow_maps_enabled: true,
203 ..default()
204 },
205 Transform::from_xyz(0.0, 10.0, 0.0),
206 ));
207
208 // Configure all AABB's to have a default color of red
209 let (_, aabb_gizmo_config) = config_store.config_mut::<AabbGizmoConfigGroup>();
210 aabb_gizmo_config.default_color = Some(Color::LinearRgba(LinearRgba::RED));
211
212 // Configure the shapes on the ring that will have their AABB's drawn and updated
213 let white_matl = materials.add(Color::WHITE);
214 let shapes = [
215 meshes.add(Cuboid {
216 half_size: Vec3::new(2., 0.5, 1.),
217 }),
218 meshes.add(Tetrahedron {
219 vertices: [
220 Vec3::new(3., 4., 3.),
221 Vec3::new(-0.5, 4., -0.5),
222 Vec3::new(-0.5, -0.5, 3.),
223 Vec3::new(3., -0.5, -0.5),
224 ],
225 }),
226 meshes.add(Cylinder {
227 radius: 0.1,
228 half_height: 1.5,
229 }),
230 meshes.add(Cuboid {
231 half_size: Vec3::new(1., 0.1, 2.),
232 }),
233 meshes.add(Sphere::default().mesh().ico(5).unwrap()),
234 ];
235 let shapes_len = shapes.len() as f32;
236 let mut shape_ring = commands.spawn((Transform::default(), Visibility::default(), ShapeRing));
237 for (i, shape) in shapes.into_iter().enumerate() {
238 // Space the shapes out evenly along the ring
239 let shape_angle = i as f32 * 2. * PI / shapes_len;
240 let (s, c) = ops::sin_cos(shape_angle);
241 let (x, z) = (SHAPE_RING_RADIUS * c, SHAPE_RING_RADIUS * s);
242 shape_ring.with_child((
243 Mesh3d(shape),
244 MeshMaterial3d(white_matl.clone()),
245 Transform::from_xyz(x, 1.5, z).with_rotation(Quat::from_rotation_x(-PI / 4.)),
246 MyShape,
247 ));
248 }
249
250 // Configure the shape that peeks out of the wall plane
251 let wall_shape = meshes.add(Torus::default());
252 commands.spawn((
253 Mesh3d(wall_shape),
254 MeshMaterial3d(white_matl.clone()),
255 Transform::from_xyz(25., 1.5, 12.5).with_rotation(Quat::from_rotation_x(-PI / 4.)),
256 WallShape,
257 ));
258
259 Ok(())
260}More examples
201fn spawn_light(commands: &mut Commands) {
202 commands.spawn((
203 DirectionalLight::default(),
204 Transform::from_xyz(4.0, 8.0, 4.0).looking_at(Vec3::ZERO, Vec3::Y),
205 ));
206}
207
208/// Spawns the camera.
209fn spawn_camera(commands: &mut Commands) {
210 commands
211 .spawn(Camera3d::default())
212 .insert(Transform::from_xyz(0.0, 2.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y))
213 // Tag the camera with `Selection::Camera`.
214 .insert(Selection::Camera);
215}50fn setup(mut commands: Commands) {
51 commands.spawn((
52 Camera3d::default(),
53 Transform::from_xyz(0.0, 7.5, 18.0).looking_at(Vec3::new(0.0, 5.5, 0.0), Vec3::Y),
54 ));
55}
56
57#[derive(Component, Debug, Default)]
58struct PendingScene(Handle<Gltf>);
59
60#[derive(Component, Debug, Default)]
61struct PendingAnimation((Handle<AnimationGraph>, AnimationNodeIndex));
62
63fn load_scene(mut commands: Commands, asset_server: Res<AssetServer>) {
64 commands.spawn((
65 PendingScene(asset_server.load("models/animated/Fox.glb")),
66 Transform::from_xyz(1.3, 4.3, 0.0)
67 .with_scale(Vec3::splat(0.08))
68 .looking_to(-Vec3::X, Vec3::Y),
69 ));
70}
71
72fn spawn_scene(
73 mut commands: Commands,
74 query: Query<(Entity, &PendingScene)>,
75 assets: Res<Assets<Gltf>>,
76 mut graphs: ResMut<Assets<AnimationGraph>>,
77) {
78 for (entity, PendingScene(asset)) in query.iter() {
79 if let Some(gltf) = assets.get(asset)
80 && let Some(scene_handle) = gltf.scenes.first()
81 && let Some(animation_handle) = gltf.named_animations.get("Run")
82 {
83 let (graph, graph_node_index) = AnimationGraph::from_clip(animation_handle.clone());
84
85 commands
86 .entity(entity)
87 .remove::<PendingScene>()
88 .insert((
89 WorldAssetRoot(scene_handle.clone()),
90 PendingAnimation((graphs.add(graph), graph_node_index)),
91 ))
92 .observe(play_animation);
93 }
94 }
95}
96
97fn play_animation(
98 trigger: On<WorldInstanceReady>,
99 mut commands: Commands,
100 children: Query<&Children>,
101 animations: Query<&PendingAnimation>,
102 mut players: Query<&mut AnimationPlayer>,
103) {
104 if let Ok(PendingAnimation((graph_handle, graph_node_index))) = animations.get(trigger.entity) {
105 for child in children.iter_descendants(trigger.entity) {
106 if let Ok(mut player) = players.get_mut(child) {
107 player.play(*graph_node_index).set_speed(0.6).repeat();
108
109 commands
110 .entity(child)
111 .insert(AnimationGraphHandle(graph_handle.clone()));
112 }
113 }
114 }
115
116 commands.entity(trigger.entity).remove::<PendingAnimation>();
117}
118
119type CustomAnimationId = i8;
120
121#[derive(Component)]
122struct CustomAnimation(CustomAnimationId);
123
124fn spawn_custom_meshes(
125 mut commands: Commands,
126 mut mesh_assets: ResMut<Assets<Mesh>>,
127 mut material_assets: ResMut<Assets<StandardMaterial>>,
128 mut inverse_bindposes_assets: ResMut<Assets<SkinnedMeshInverseBindposes>>,
129) {
130 let mesh_handle = mesh_assets.add(
131 Mesh::new(
132 PrimitiveTopology::TriangleStrip,
133 // Test that skinned mesh bounds work even if the mesh is render
134 // world only.
135 RenderAssetUsages::RENDER_WORLD,
136 )
137 .with_inserted_attribute(
138 Mesh::ATTRIBUTE_POSITION,
139 vec![
140 [-0.5, 0.0, 0.0],
141 [0.5, 0.0, 0.0],
142 [-0.5, 0.5, 0.0],
143 [0.5, 0.5, 0.0],
144 [-0.5, 1.0, 0.0],
145 [0.5, 1.0, 0.0],
146 [-0.5, 1.5, 0.0],
147 [0.5, 1.5, 0.0],
148 [-0.5, 2.0, 0.0],
149 [0.5, 2.0, 0.0],
150 ],
151 )
152 .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, vec![[0.0, 0.0, 1.0]; 10])
153 .with_inserted_attribute(
154 Mesh::ATTRIBUTE_JOINT_INDEX,
155 VertexAttributeValues::Uint16x4(vec![
156 [1, 0, 0, 0],
157 [1, 0, 0, 0],
158 [1, 2, 0, 0],
159 [1, 2, 0, 0],
160 [1, 2, 0, 0],
161 [1, 2, 0, 0],
162 [2, 1, 0, 0],
163 [2, 1, 0, 0],
164 [2, 0, 0, 0],
165 [2, 0, 0, 0],
166 ]),
167 )
168 .with_inserted_attribute(
169 Mesh::ATTRIBUTE_JOINT_WEIGHT,
170 vec![
171 [1.00, 0.00, 0.0, 0.0],
172 [1.00, 0.00, 0.0, 0.0],
173 [0.75, 0.25, 0.0, 0.0],
174 [0.75, 0.25, 0.0, 0.0],
175 [0.50, 0.50, 0.0, 0.0],
176 [0.50, 0.50, 0.0, 0.0],
177 [0.75, 0.25, 0.0, 0.0],
178 [0.75, 0.25, 0.0, 0.0],
179 [1.00, 0.00, 0.0, 0.0],
180 [1.00, 0.00, 0.0, 0.0],
181 ],
182 )
183 .with_generated_skinned_mesh_bounds()
184 .unwrap(),
185 );
186
187 let inverse_bindposes_handle = inverse_bindposes_assets.add(vec![
188 Mat4::from_translation(Vec3::new(0.0, 0.0, 0.0)),
189 Mat4::from_translation(Vec3::new(0.0, 0.0, 0.0)),
190 Mat4::from_translation(Vec3::new(0.0, -1.0, 0.0)),
191 ]);
192
193 struct MeshInstance {
194 animations: [CustomAnimationId; 2],
195 }
196
197 let mesh_instances = [
198 // Simple cases. First joint is still, second joint is all rotation/translation/scale variations.
199 MeshInstance { animations: [0, 1] },
200 MeshInstance { animations: [0, 2] },
201 MeshInstance { animations: [0, 3] },
202 MeshInstance { animations: [0, 4] },
203 MeshInstance { animations: [0, 5] },
204 MeshInstance { animations: [0, 6] },
205 MeshInstance { animations: [0, 7] },
206 MeshInstance { animations: [0, 8] },
207 // Skewed cases. First joint is non-uniform scaling, second joint is rotation/translation variations.
208 MeshInstance { animations: [9, 1] },
209 MeshInstance { animations: [9, 2] },
210 MeshInstance { animations: [9, 3] },
211 MeshInstance { animations: [9, 4] },
212 MeshInstance { animations: [9, 5] },
213 ];
214
215 for (i, mesh_instance) in mesh_instances.iter().enumerate() {
216 let x = ((i as f32) * 2.0) - ((mesh_instances.len() - 1) as f32);
217
218 let base_entity = commands
219 .spawn((Transform::from_xyz(x, 0.0, 0.0), Visibility::default()))
220 .id();
221
222 let joints = vec![
223 commands.spawn((Transform::IDENTITY,)).id(),
224 commands
225 .spawn((
226 CustomAnimation(mesh_instance.animations[0]),
227 Transform::IDENTITY,
228 ))
229 .id(),
230 commands
231 .spawn((
232 CustomAnimation(mesh_instance.animations[1]),
233 Transform::IDENTITY,
234 ))
235 .id(),
236 ];
237
238 commands.entity(joints[0]).insert(ChildOf(base_entity));
239
240 commands.entity(joints[1]).insert(ChildOf(joints[0]));
241 commands.entity(joints[2]).insert(ChildOf(joints[1]));
242
243 let mesh_entity = commands
244 .spawn((
245 Transform::IDENTITY,
246 Mesh3d(mesh_handle.clone()),
247 MeshMaterial3d(material_assets.add(StandardMaterial {
248 base_color: Color::WHITE,
249 cull_mode: None,
250 ..default()
251 })),
252 SkinnedMesh {
253 inverse_bindposes: inverse_bindposes_handle.clone(),
254 joints: joints.clone(),
255 },
256 DynamicSkinnedMeshBounds,
257 ))
258 .id();
259
260 commands.entity(mesh_entity).insert(ChildOf(base_entity));
261 }
262}228fn spawn_light(commands: &mut Commands) {
229 commands.spawn((
230 PointLight {
231 intensity: 10_000_000.,
232 range: 100.0,
233 ..default()
234 },
235 Transform::from_xyz(8.0, 16.0, -8.0),
236 ));
237}
238
239/// Spawns a camera.
240fn spawn_camera(commands: &mut Commands) {
241 commands.spawn((
242 Camera3d::default(),
243 Transform::from_xyz(2.0, 0.0, -7.0).looking_at(Vec3::ZERO, Vec3::Y),
244 Hdr,
245 ));
246}94fn spawn_camera(commands: &mut Commands) {
95 commands.spawn((
96 Camera3d::default(),
97 FreeCamera::default(),
98 Transform::from_xyz(0.0, 0.0, 4.0).looking_at(Vec3::new(0.0, -2.5, 0.0), Dir3::Y),
99 Hdr,
100 ));
101}
102
103/// Spawns the inner reflective cube in the scene.
104fn spawn_inner_cube(
105 commands: &mut Commands,
106 meshes: &mut Assets<Mesh>,
107 materials: &mut Assets<StandardMaterial>,
108) {
109 let cube_mesh = meshes.add(
110 Cuboid {
111 half_size: Vec3::new(5.0, 1.0, 2.0),
112 }
113 .mesh()
114 .build()
115 .with_duplicated_vertices()
116 .with_computed_flat_normals(),
117 );
118 let cube_material = materials.add(StandardMaterial {
119 base_color: Color::WHITE,
120 metallic: 1.0,
121 reflectance: 1.0,
122 perceptual_roughness: 0.0,
123 ..default()
124 });
125
126 commands.spawn((
127 Mesh3d(cube_mesh),
128 MeshMaterial3d(cube_material),
129 Transform::from_xyz(0.0, -4.0, -2.5),
130 InnerCube,
131 ));
132}- examples/3d/occlusion_culling.rs
- examples/3d/mirror.rs
- examples/2d/move_sprite.rs
- examples/3d/reflection_probes.rs
- examples/animation/color_animation.rs
- examples/3d/irradiance_volumes.rs
- examples/ecs/delayed_commands.rs
- examples/gizmos/3d_text_gizmos.rs
- examples/async_tasks/external_source_external_thread.rs
- examples/math/render_primitives.rs
- examples/stress_tests/many_gizmos.rs
- examples/scene/world_serialization.rs
- examples/gltf/gltf_skinned_mesh.rs
- examples/showcase/alien_cake_addict.rs
- examples/shader/animate_shader.rs
- examples/gltf/query_gltf_primitives.rs
- examples/3d/lightmaps.rs
- examples/shader/shader_material_wesl.rs
- examples/3d/ssr.rs
- examples/3d/light_textures.rs
- examples/camera/2d_top_down_camera.rs
- examples/2d/pixel_grid_snap.rs
- examples/shader/fallback_image.rs
- examples/shader_advanced/custom_phase_item.rs
- examples/shader_advanced/render_depth_to_texture.rs
- examples/3d/3d_viewport_to_world.rs
- examples/camera/free_camera_controller.rs
- examples/3d/light_probe_blending.rs
- examples/shader/shader_material.rs
- examples/shader/shader_material_glsl.rs
- examples/shader_advanced/texture_binding_array.rs
- examples/async_tasks/async_channel_pattern.rs
- examples/app/externally_driven_headless_renderer.rs
- examples/asset/hot_asset_reloading.rs
- examples/asset/multi_asset_sync.rs
- examples/shader_advanced/manual_material.rs
- examples/3d/color_grading.rs
- examples/2d/transparency_2d.rs
- examples/transforms/3d_rotation.rs
- examples/transforms/scale.rs
- examples/shader_advanced/custom_vertex_attribute.rs
- examples/animation/morph_targets.rs
- examples/3d/3d_scene.rs
- tests/window/minimizing.rs
- tests/window/resizing.rs
- examples/3d/atmospheric_fog.rs
- examples/transforms/translation.rs
- examples/shader/shader_defs.rs
- examples/gltf/load_gltf_extras.rs
- examples/animation/animated_mesh.rs
- examples/showcase/loading_screen.rs
- examples/3d/parenting.rs
- examples/animation/animation_graph.rs
- examples/3d/post_processing.rs
- examples/3d/rotate_environment_map.rs
- examples/shader/shader_material_screenspace_texture.rs
- examples/3d/depth_of_field.rs
- examples/camera/2d_screen_shake.rs
- examples/camera/camera_orbit.rs
- examples/shader/shader_material_bindless.rs
- examples/gltf/edit_material_on_gltf.rs
- examples/remote/server.rs
- examples/animation/animation_masks.rs
- examples/3d/anisotropy.rs
- examples/window/screenshot.rs
- examples/3d/animated_material.rs
- examples/3d/pcss.rs
- examples/shader_advanced/custom_post_processing.rs
- examples/ecs/entity_disabling.rs
- examples/3d/clearcoat.rs
- examples/camera/custom_projection.rs
- examples/picking/custom_hit_data.rs
- examples/gltf/load_gltf.rs
- examples/3d/two_passes.rs
- examples/stress_tests/many_materials.rs
- examples/gltf/gltf_extension_animation_graph.rs
- examples/diagnostics/log_diagnostics.rs
- examples/shader/extended_material_bindless.rs
- examples/3d/tonemapping.rs
- examples/shader_advanced/custom_render_phase.rs
- examples/dev_tools/infinite_grid.rs
- examples/gltf/update_gltf_scene.rs
- examples/3d/skybox.rs
- examples/3d/fog_volumes.rs
- examples/3d/lines.rs
- examples/shader/storage_buffer.rs
- examples/window/low_power.rs
- examples/3d/order_independent_transparency.rs
- examples/shader/array_texture.rs
- examples/ecs/hierarchy.rs
- examples/3d/generate_custom_mesh.rs
- examples/2d/wireframe_2d.rs
- examples/3d/mesh_ray_cast.rs
- examples/audio/spatial_audio_2d.rs
- examples/picking/simple_picking.rs
- examples/movement/smooth_follow.rs
- examples/shader/extended_material.rs
- examples/3d/vertex_colors.rs
- examples/animation/animated_mesh_control.rs
- examples/asset/generated_assets.rs
- examples/shader_advanced/custom_shader_instancing.rs
- tests/window/desktop_request_redraw.rs
- examples/3d/orthographic.rs
- examples/showcase/contributors.rs
- examples/testbed/2d.rs
- examples/picking/debug_picking.rs
- examples/shader_advanced/specialized_mesh_pipeline.rs
- examples/window/multiple_windows.rs
- examples/3d/spherical_area_lights.rs
- examples/math/bounding_2d.rs
- examples/stress_tests/many_morph_targets.rs
- examples/transforms/transform.rs
- examples/camera/first_person_view_model.rs
- examples/gizmos/axes.rs
- examples/3d/motion_blur.rs
- examples/app/headless_renderer.rs
- examples/3d/ssao.rs
- examples/3d/atmosphere.rs
- examples/animation/animated_mesh_events.rs
- examples/app/render_recovery.rs
- examples/animation/eased_motion.rs
- examples/stress_tests/transform_hierarchy.rs
- examples/audio/spatial_audio_3d.rs
- examples/shader/automatic_instancing.rs
- examples/asset/alter_sprite.rs
- examples/ecs/error_handling.rs
- examples/camera/projection_zoom.rs
- examples/2d/rotation.rs
- examples/3d/fog.rs
- examples/3d/rect_light.rs
- examples/3d/specular_tint.rs
- examples/ui/widgets/viewport_node.rs
- examples/3d/visibility_range.rs
- examples/2d/dynamic_mip_generation.rs
- examples/3d/volumetric_fog.rs
- tests/3d/test_invalid_skinned_mesh.rs
- examples/stress_tests/many_cameras_lights.rs
- examples/3d/texture.rs
- examples/async_tasks/async_compute.rs
- examples/3d/shadow_caster_receiver.rs
- examples/3d/wireframe.rs
- examples/3d/bloom_3d.rs
- examples/3d/anti_aliasing.rs
- examples/gizmos/3d_gizmos.rs
- examples/transforms/align.rs
- examples/3d/decal.rs
- examples/math/random_sampling.rs
- examples/testbed/3d.rs
- examples/picking/sprite_picking.rs
- examples/2d/mesh2d_alpha_mode.rs
- examples/3d/scrolling_fog.rs
- examples/ecs/iter_combinations.rs
- examples/shader_advanced/compute_mesh.rs
- examples/3d/render_to_texture.rs
- examples/2d/sprite_slice.rs
- examples/gizmos/transform_gizmo.rs
- examples/3d/transparency_3d.rs
- examples/asset/repeated_texture.rs
- examples/asset/asset_settings.rs
- examples/2d/mesh2d_repeated_texture.rs
- examples/3d/spotlight.rs
- examples/asset/alter_mesh.rs
- examples/3d/pbr.rs
- examples/math/custom_primitives.rs
- examples/3d/auto_exposure.rs
- examples/animation/easing_functions.rs
- examples/asset/asset_loading.rs
- examples/window/multi_window_text.rs
- examples/gizmos/light_gizmos.rs
- examples/stress_tests/bevymark_3d.rs
- examples/shader/shader_prepass.rs
- examples/3d/shadow_biases.rs
- examples/2d/2d_shapes.rs
- examples/picking/mesh_picking.rs
- examples/ui/render_ui_to_texture.rs
- examples/showcase/desk_toy.rs
- examples/3d/parallax_mapping.rs
- examples/2d/sprite_scale.rs
- examples/stress_tests/many_foxes.rs
- examples/3d/deferred_rendering.rs
- examples/3d/contact_shadows.rs
- examples/3d/3d_shapes.rs
- examples/animation/custom_skinned_mesh.rs
- examples/3d/blend_modes.rs
- examples/animation/animated_transform.rs
- examples/3d/lighting.rs
- examples/3d/camera_sub_view.rs
- examples/3d/transmission.rs
- examples/stress_tests/many_cubes.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.
Examples found in repository?
More examples
341fn calculate_mirror_camera_transform_and_projection(
342 main_camera_transform: &Transform,
343 main_camera_projection: &PerspectiveProjection,
344 mirror_transform: &Transform,
345) -> (Transform, PerspectiveProjection) {
346 // Calculate the reflection matrix (a.k.a. Householder matrix) that will
347 // reflect the scene across the mirror plane.
348 //
349 // Note that you must calculate this in *matrix* form and only *afterward*
350 // convert to a `Transform` instead of composing `Transform`s. This is
351 // because the reflection matrix has non-uniform scale, and composing
352 // transforms can't always handle composition of matrices with non-uniform
353 // scales.
354 let mirror_camera_transform = Transform::from_matrix(
355 Mat4::from_mat3a(reflection_matrix(Vec3::NEG_Z)) * main_camera_transform.to_matrix(),
356 );
357
358 // Compute the distance from the camera to the mirror plane. This will be
359 // used to calculate the distance to the near clip plane for the mirror
360 // world.
361 let distance_from_camera_to_mirror = InfinitePlane3d::new(mirror_transform.rotation * Vec3::Y)
362 .signed_distance(
363 Isometry3d::IDENTITY,
364 mirror_transform.translation - main_camera_transform.translation,
365 );
366
367 // Compute the normal of the mirror plane in view space.
368 let view_from_world = main_camera_transform.compute_affine().matrix3.inverse();
369 let mirror_projection_plane_normal =
370 (view_from_world * (mirror_transform.rotation * Vec3::NEG_Y)).normalize();
371
372 // Compute the final projection. It should match the main camera projection,
373 // except that `near` and `near_normal` should be set to the updated near
374 // plane and near normal plane as above.
375 let mirror_camera_projection = PerspectiveProjection {
376 near_clip_plane: mirror_projection_plane_normal.extend(distance_from_camera_to_mirror),
377 ..*main_camera_projection
378 };
379
380 (mirror_camera_transform, mirror_camera_projection)
381}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
314fn setup_lights(mut commands: Commands) {
315 commands.spawn((
316 PointLight {
317 intensity: 5000.0,
318 ..default()
319 },
320 Transform::from_translation(Vec3::new(-LEFT_RIGHT_OFFSET_3D, 2.0, 0.0))
321 .looking_at(Vec3::new(-LEFT_RIGHT_OFFSET_3D, 0.0, 0.0), Vec3::Y),
322 ));
323}
324
325/// Marker component for header text
326#[derive(Debug, Clone, Component, Default, Reflect)]
327pub struct HeaderText;
328
329/// Marker component for header node
330#[derive(Debug, Clone, Component, Default, Reflect)]
331pub struct HeaderNode;
332
333fn update_active_cameras(
334 state: Res<State<CameraActive>>,
335 camera_2d: Single<(Entity, &mut Camera), With<Camera2d>>,
336 camera_3d: Single<(Entity, &mut Camera), (With<Camera3d>, Without<Camera2d>)>,
337 mut text: Query<&mut UiTargetCamera, With<HeaderNode>>,
338) {
339 let (entity_2d, mut cam_2d) = camera_2d.into_inner();
340 let (entity_3d, mut cam_3d) = camera_3d.into_inner();
341 let is_camera_2d_active = matches!(*state.get(), CameraActive::Dim2);
342
343 cam_2d.is_active = is_camera_2d_active;
344 cam_3d.is_active = !is_camera_2d_active;
345
346 let active_camera = if is_camera_2d_active {
347 entity_2d
348 } else {
349 entity_3d
350 };
351
352 text.iter_mut().for_each(|mut target_camera| {
353 *target_camera = UiTargetCamera(active_camera);
354 });
355}
356
357fn switch_cameras(current: Res<State<CameraActive>>, mut next: ResMut<NextState<CameraActive>>) {
358 let next_state = match current.get() {
359 CameraActive::Dim2 => CameraActive::Dim3,
360 CameraActive::Dim3 => CameraActive::Dim2,
361 };
362 next.set(next_state);
363}
364
365fn setup_text(mut commands: Commands, cameras: Query<(Entity, &Camera)>) {
366 let active_camera = cameras
367 .iter()
368 .find_map(|(entity, camera)| camera.is_active.then_some(entity))
369 .expect("run condition ensures existence");
370 commands.spawn((
371 HeaderNode,
372 Node {
373 justify_self: JustifySelf::Center,
374 top: px(5),
375 ..Default::default()
376 },
377 UiTargetCamera(active_camera),
378 children![(
379 Text::default(),
380 HeaderText,
381 TextLayout::justify(Justify::Center),
382 children![
383 TextSpan::new("Primitive: "),
384 TextSpan(format!("{text}", text = PrimitiveSelected::default())),
385 TextSpan::new("\n\n"),
386 TextSpan::new(
387 "Press 'C' to switch between 2D and 3D mode\n\
388 Press 'Up' or 'Down' to switch to the next/previous primitive",
389 ),
390 TextSpan::new("\n\n"),
391 TextSpan::new("(If nothing is displayed, there's no rendering support yet)",),
392 ]
393 )],
394 ));
395}
396
397fn update_text(
398 primitive_state: Res<State<PrimitiveSelected>>,
399 header: Query<Entity, With<HeaderText>>,
400 mut writer: TextUiWriter,
401) {
402 let new_text = format!("{text}", text = primitive_state.get());
403 header.iter().for_each(|header_text| {
404 if let Some(mut text) = writer.get_text(header_text, 2) {
405 (*text).clone_from(&new_text);
406 };
407 });
408}
409
410fn switch_to_next_primitive(
411 current: Res<State<PrimitiveSelected>>,
412 mut next: ResMut<NextState<PrimitiveSelected>>,
413) {
414 let next_state = current.get().next();
415 next.set(next_state);
416}
417
418fn switch_to_previous_primitive(
419 current: Res<State<PrimitiveSelected>>,
420 mut next: ResMut<NextState<PrimitiveSelected>>,
421) {
422 let next_state = current.get().previous();
423 next.set(next_state);
424}
425
426fn in_mode(active: CameraActive) -> impl Fn(Res<State<CameraActive>>) -> bool {
427 move |state| *state.get() == active
428}
429
430fn draw_gizmos_2d(mut gizmos: Gizmos, state: Res<State<PrimitiveSelected>>, time: Res<Time>) {
431 const POSITION: Vec2 = Vec2::new(-LEFT_RIGHT_OFFSET_2D, 0.0);
432 let angle = time.elapsed_secs();
433 let isometry = Isometry2d::new(POSITION, Rot2::radians(angle));
434 let color = Color::WHITE;
435
436 #[expect(
437 clippy::match_same_arms,
438 reason = "Certain primitives don't have any 2D rendering support yet."
439 )]
440 match state.get() {
441 PrimitiveSelected::RectangleAndCuboid => {
442 gizmos.primitive_2d(&RECTANGLE, isometry, color);
443 }
444 PrimitiveSelected::CircleAndSphere => {
445 gizmos.primitive_2d(&CIRCLE, isometry, color);
446 }
447 PrimitiveSelected::Ellipse => drop(gizmos.primitive_2d(&ELLIPSE, isometry, color)),
448 PrimitiveSelected::Triangle => gizmos.primitive_2d(&TRIANGLE_2D, isometry, color),
449 PrimitiveSelected::Plane => gizmos.primitive_2d(&PLANE_2D, isometry, color),
450 PrimitiveSelected::Line => drop(gizmos.primitive_2d(&LINE_2D, isometry, color)),
451 PrimitiveSelected::Segment => {
452 drop(gizmos.primitive_2d(&SEGMENT_2D, isometry, color));
453 }
454 PrimitiveSelected::Polyline => gizmos.primitive_2d(
455 &Polyline2d {
456 vertices: POLYLINE_2D_VERTICES.to_vec(),
457 },
458 isometry,
459 color,
460 ),
461 PrimitiveSelected::ConvexPolygon => gizmos.primitive_2d(
462 &Polygon::from(ConvexPolygon::new(CONVEX_POLYGON_VERTICES).unwrap()),
463 isometry,
464 color,
465 ),
466 PrimitiveSelected::Polygon => gizmos.primitive_2d(
467 &Polygon {
468 vertices: vec![
469 Vec2::new(-BIG_2D, -SMALL_2D),
470 Vec2::new(BIG_2D, -SMALL_2D),
471 Vec2::new(BIG_2D, SMALL_2D),
472 Vec2::new(0.0, 0.0),
473 Vec2::new(-BIG_2D, SMALL_2D),
474 ],
475 },
476 isometry,
477 color,
478 ),
479 PrimitiveSelected::RegularPolygon => {
480 gizmos.primitive_2d(®ULAR_POLYGON, isometry, color);
481 }
482 PrimitiveSelected::Capsule => gizmos.primitive_2d(&CAPSULE_2D, isometry, color),
483 PrimitiveSelected::Cylinder => {}
484 PrimitiveSelected::Cone => {}
485 PrimitiveSelected::ConicalFrustum => {}
486 PrimitiveSelected::Torus => drop(gizmos.primitive_2d(&ANNULUS, isometry, color)),
487 PrimitiveSelected::Tetrahedron => {}
488 PrimitiveSelected::Arc => gizmos.primitive_2d(&ARC, isometry, color),
489 PrimitiveSelected::CircularSector => {
490 gizmos.primitive_2d(&CIRCULAR_SECTOR, isometry, color);
491 }
492 PrimitiveSelected::CircularSegment => {
493 gizmos.primitive_2d(&CIRCULAR_SEGMENT, isometry, color);
494 }
495 }
496}
497
498/// Marker for primitive meshes to record in which state they should be visible in
499#[derive(Debug, Clone, Component, Default, Reflect)]
500pub struct PrimitiveData {
501 camera_mode: CameraActive,
502 primitive_state: PrimitiveSelected,
503}
504
505/// Marker for meshes of 2D primitives
506#[derive(Debug, Clone, Component, Default)]
507pub struct MeshDim2;
508
509/// Marker for meshes of 3D primitives
510#[derive(Debug, Clone, Component, Default)]
511pub struct MeshDim3;
512
513fn spawn_primitive_2d(
514 mut commands: Commands,
515 mut materials: ResMut<Assets<ColorMaterial>>,
516 mut meshes: ResMut<Assets<Mesh>>,
517) {
518 const POSITION: Vec3 = Vec3::new(LEFT_RIGHT_OFFSET_2D, 0.0, 0.0);
519 let material: Handle<ColorMaterial> = materials.add(Color::WHITE);
520 let camera_mode = CameraActive::Dim2;
521 let polyline_2d = Polyline2d {
522 vertices: POLYLINE_2D_VERTICES.to_vec(),
523 };
524 let convex_polygon = ConvexPolygon::new(CONVEX_POLYGON_VERTICES).unwrap();
525 [
526 Some(RECTANGLE.mesh().build()),
527 Some(CIRCLE.mesh().build()),
528 Some(ELLIPSE.mesh().build()),
529 Some(TRIANGLE_2D.mesh().build()),
530 None, // plane
531 None, // line
532 Some(SEGMENT_2D.mesh().build()),
533 Some(polyline_2d.mesh().build()),
534 None, // polygon
535 Some(convex_polygon.mesh().build()),
536 Some(REGULAR_POLYGON.mesh().build()),
537 Some(CAPSULE_2D.mesh().build()),
538 None, // cylinder
539 None, // cone
540 None, // conical frustum
541 Some(ANNULUS.mesh().build()),
542 None, // tetrahedron
543 None, // arc
544 Some(CIRCULAR_SECTOR.mesh().build()),
545 Some(CIRCULAR_SEGMENT.mesh().build()),
546 ]
547 .into_iter()
548 .zip(PrimitiveSelected::ALL)
549 .for_each(|(maybe_mesh, state)| {
550 if let Some(mesh) = maybe_mesh {
551 commands.spawn((
552 MeshDim2,
553 PrimitiveData {
554 camera_mode,
555 primitive_state: state,
556 },
557 Mesh2d(meshes.add(mesh)),
558 MeshMaterial2d(material.clone()),
559 Transform::from_translation(POSITION),
560 ));
561 }
562 });
563}
564
565fn spawn_primitive_3d(
566 mut commands: Commands,
567 mut materials: ResMut<Assets<StandardMaterial>>,
568 mut meshes: ResMut<Assets<Mesh>>,
569) {
570 const POSITION: Vec3 = Vec3::new(-LEFT_RIGHT_OFFSET_3D, 0.0, 0.0);
571 let material: Handle<StandardMaterial> = materials.add(Color::WHITE);
572 let camera_mode = CameraActive::Dim3;
573 let polyline_3d = Polyline3d {
574 vertices: POLYLINE_3D_VERTICES.to_vec(),
575 };
576 [
577 Some(CUBOID.mesh().build()),
578 Some(SPHERE.mesh().build()),
579 None, // ellipse
580 Some(TRIANGLE_3D.mesh().build()),
581 Some(PLANE_3D.mesh().build()),
582 None, // line
583 Some(SEGMENT_3D.mesh().build()),
584 Some(polyline_3d.mesh().build()),
585 None, // polygon
586 None, // convex polygon
587 None, // regular polygon
588 Some(CAPSULE_3D.mesh().build()),
589 Some(CYLINDER.mesh().build()),
590 Some(CONE.mesh().build()),
591 Some(CONICAL_FRUSTUM.mesh().build()),
592 Some(TORUS.mesh().build()),
593 Some(TETRAHEDRON.mesh().build()),
594 None, // arc
595 None, // circular sector
596 None, // circular segment
597 ]
598 .into_iter()
599 .zip(PrimitiveSelected::ALL)
600 .for_each(|(maybe_mesh, state)| {
601 if let Some(mesh) = maybe_mesh {
602 commands.spawn((
603 MeshDim3,
604 PrimitiveData {
605 camera_mode,
606 primitive_state: state,
607 },
608 Mesh3d(meshes.add(mesh)),
609 MeshMaterial3d(material.clone()),
610 Transform::from_translation(POSITION),
611 ));
612 }
613 });
614}- examples/3d/clustered_decals.rs
- examples/stress_tests/many_text2d.rs
- examples/3d/mirror.rs
- examples/ecs/fallible_params.rs
- examples/shader_advanced/fullscreen_material.rs
- examples/3d/3d_viewport_to_world.rs
- examples/transforms/3d_rotation.rs
- examples/stress_tests/bevymark.rs
- examples/transforms/translation.rs
- examples/testbed/2d.rs
- examples/2d/dynamic_mip_generation.rs
- examples/asset/asset_saving_with_subassets.rs
- examples/asset/multi_asset_sync.rs
- examples/3d/anisotropy.rs
- examples/3d/animated_material.rs
- examples/shader_advanced/custom_post_processing.rs
- examples/testbed/3d.rs
- examples/stress_tests/many_materials.rs
- examples/movement/physics_in_fixed_timestep.rs
- examples/dev_tools/infinite_grid.rs
- examples/2d/mesh2d_vertex_color_texture.rs
- examples/3d/ssr.rs
- examples/3d/mesh_ray_cast.rs
- examples/3d/order_independent_transparency.rs
- examples/audio/spatial_audio_2d.rs
- examples/movement/smooth_follow.rs
- examples/2d/2d_viewport_to_world.rs
- examples/transforms/transform.rs
- examples/2d/bloom_2d.rs
- examples/3d/light_probe_blending.rs
- examples/3d/light_textures.rs
- examples/3d/occlusion_culling.rs
- examples/animation/eased_motion.rs
- examples/audio/spatial_audio_3d.rs
- examples/ecs/error_handling.rs
- examples/camera/projection_zoom.rs
- examples/3d/clustered_decal_maps.rs
- examples/stress_tests/many_lights.rs
- examples/picking/dragdrop_picking.rs
- examples/math/random_sampling.rs
- examples/stress_tests/transform_hierarchy.rs
- examples/3d/render_to_texture.rs
- examples/2d/sprite_slice.rs
- examples/asset/repeated_texture.rs
- examples/2d/mesh2d_repeated_texture.rs
- examples/3d/spotlight.rs
- examples/gizmos/3d_gizmos.rs
- examples/3d/meshlet.rs
- examples/3d/auto_exposure.rs
- examples/stress_tests/bevymark_3d.rs
- examples/3d/split_screen.rs
- examples/showcase/breakout.rs
- examples/3d/solari.rs
- examples/3d/parallax_mapping.rs
- examples/2d/sprite_scale.rs
- examples/stress_tests/many_foxes.rs
- examples/2d/text2d.rs
- examples/stress_tests/many_cubes.rs
Sourcepub const fn from_rotation(rotation: Quat) -> Transform
pub const fn from_rotation(rotation: Quat) -> Transform
Creates a new Transform, with rotation. Translation will be 0 and scale 1 on
all axes.
Examples found in repository?
More examples
220fn spawn_ground_plane(
221 commands: &mut Commands,
222 meshes: &mut Assets<Mesh>,
223 standard_materials: &mut Assets<StandardMaterial>,
224) {
225 commands.spawn((
226 Mesh3d(meshes.add(Circle::new(200.0))),
227 MeshMaterial3d(standard_materials.add(Color::from(GREEN))),
228 Transform::from_rotation(Quat::from_rotation_x(-FRAC_PI_2))
229 .with_translation(vec3(-25.0, 0.0, 0.0)),
230 ));
231}54fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
55 commands.spawn((
56 Camera3d::default(),
57 Transform::from_xyz(4.0, 4.0, 12.0).looking_at(Vec3::new(0.0, 0.0, 0.5), Vec3::Y),
58 ));
59
60 commands.spawn((
61 Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, 1.0, -PI / 4.)),
62 DirectionalLight::default(),
63 ));
64
65 commands.spawn(WorldAssetRoot(asset_server.load(
66 GltfAssetLabel::Scene(0).from_asset("models/GltfPrimitives/gltf_primitives.glb"),
67 )));
68}130fn spawn_test_scene(
131 mut commands: Commands,
132 mut meshes: ResMut<Assets<Mesh>>,
133 mut materials: ResMut<Assets<StandardMaterial>>,
134) {
135 commands.spawn((
136 Mesh3d(meshes.add(Circle::new(4.0))),
137 MeshMaterial3d(materials.add(Color::WHITE)),
138 Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)),
139 ));
140 commands.spawn((
141 Mesh3d(meshes.add(Cuboid::new(2.0, 2.0, 2.0))),
142 MeshMaterial3d(materials.add(Color::srgb_u8(124, 144, 255))),
143 Transform::from_xyz(0.0, 1.0, 0.0),
144 ));
145 commands.spawn((
146 PointLight {
147 shadow_maps_enabled: true,
148 ..default()
149 },
150 Transform::from_xyz(4.0, 8.0, 4.0),
151 ));
152}188fn setup_scene(
189 mut commands: Commands,
190 mut meshes: ResMut<Assets<Mesh>>,
191 mut materials: ResMut<Assets<StandardMaterial>>,
192) {
193 // Camera
194 commands.spawn((
195 Camera3d::default(),
196 Transform::from_xyz(10.0, 10.0, 15.0).looking_at(Vec3::new(0.0, 0.0, 0.0), Vec3::Y),
197 ));
198
199 // Light
200 commands.spawn((
201 DirectionalLight {
202 shadow_maps_enabled: true,
203 ..default()
204 },
205 Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, 1.0, -PI / 4.)),
206 ));
207
208 // Plane
209 commands.spawn((
210 Mesh3d(meshes.add(Plane3d::default().mesh().size(50000.0, 50000.0))),
211 MeshMaterial3d(materials.add(Color::srgb(0.7, 0.2, 0.2))),
212 Loading,
213 ));
214}37fn setup(
38 mut commands: Commands,
39 mut meshes: ResMut<Assets<Mesh>>,
40 mut materials: ResMut<Assets<StandardMaterial>>,
41) {
42 // Spawn a cube to scale.
43 commands.spawn((
44 Mesh3d(meshes.add(Cuboid::default())),
45 MeshMaterial3d(materials.add(Color::WHITE)),
46 Transform::from_rotation(Quat::from_rotation_y(PI / 4.0)),
47 Scaling::new(),
48 ));
49
50 // Spawn a camera looking at the entities to show what's happening in this example.
51 commands.spawn((
52 Camera3d::default(),
53 Transform::from_xyz(0.0, 10.0, 20.0).looking_at(Vec3::ZERO, Vec3::Y),
54 ));
55
56 // Add a light source for better 3d visibility.
57 commands.spawn((
58 DirectionalLight::default(),
59 Transform::from_xyz(3.0, 3.0, 3.0).looking_at(Vec3::ZERO, Vec3::Y),
60 ));
61}- examples/async_tasks/async_channel_pattern.rs
- examples/animation/morph_targets.rs
- examples/3d/pcss.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/gltf/gltf_extension_animation_graph.rs
- examples/diagnostics/log_diagnostics.rs
- examples/shader_advanced/custom_render_phase.rs
- examples/3d/mesh_ray_cast.rs
- examples/picking/simple_picking.rs
- examples/animation/animated_mesh_control.rs
- examples/picking/debug_picking.rs
- examples/stress_tests/many_morph_targets.rs
- examples/app/headless_renderer.rs
- examples/3d/ssao.rs
- examples/animation/animated_mesh_events.rs
- examples/app/render_recovery.rs
- examples/3d/order_independent_transparency.rs
- examples/3d/specular_tint.rs
- examples/3d/visibility_range.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/shader_advanced/compute_mesh.rs
- examples/gizmos/transform_gizmo.rs
- examples/3d/meshlet.rs
- examples/gizmos/light_gizmos.rs
- examples/3d/split_screen.rs
- examples/3d/solari.rs
- examples/stress_tests/many_foxes.rs
- examples/3d/deferred_rendering.rs
- examples/3d/contact_shadows.rs
- examples/3d/lighting.rs
Sourcepub const fn from_scale(scale: Vec3) -> Transform
pub const fn from_scale(scale: Vec3) -> Transform
Creates a new Transform, with scale. Translation will be 0 and rotation 0 on
all axes.
Examples found in repository?
282fn spawn_fox(commands: &mut Commands, assets: &ExampleAssets) {
283 commands.spawn((
284 WorldAssetRoot(assets.fox.clone()),
285 Visibility::Hidden,
286 Transform::from_scale(Vec3::splat(FOX_SCALE)),
287 MainObject,
288 ));
289}
290
291fn spawn_text(commands: &mut Commands, app_status: &AppStatus) {
292 commands.spawn((
293 app_status.create_text(),
294 Node {
295 position_type: PositionType::Absolute,
296 bottom: px(12),
297 left: px(12),
298 ..default()
299 },
300 ));
301}
302
303// A system that updates the help text.
304fn update_text(mut text_query: Query<&mut Text>, app_status: Res<AppStatus>) {
305 for mut text in text_query.iter_mut() {
306 *text = app_status.create_text();
307 }
308}
309
310impl AppStatus {
311 // Constructs the help text at the bottom of the screen based on the
312 // application status.
313 fn create_text(&self) -> Text {
314 let irradiance_volume_help_text = if self.irradiance_volume_present {
315 DISABLE_IRRADIANCE_VOLUME_HELP_TEXT
316 } else {
317 ENABLE_IRRADIANCE_VOLUME_HELP_TEXT
318 };
319
320 let voxels_help_text = if self.voxels_visible {
321 HIDE_VOXELS_HELP_TEXT
322 } else {
323 SHOW_VOXELS_HELP_TEXT
324 };
325
326 let rotation_help_text = if self.rotating {
327 STOP_ROTATION_HELP_TEXT
328 } else {
329 START_ROTATION_HELP_TEXT
330 };
331
332 let switch_mesh_help_text = match self.model {
333 ExampleModel::Sphere => SWITCH_TO_FOX_HELP_TEXT,
334 ExampleModel::Fox => SWITCH_TO_SPHERE_HELP_TEXT,
335 };
336
337 format!(
338 "{CLICK_TO_MOVE_HELP_TEXT}\n\
339 {voxels_help_text}\n\
340 {irradiance_volume_help_text}\n\
341 {rotation_help_text}\n\
342 {switch_mesh_help_text}"
343 )
344 .into()
345 }
346}
347
348// Rotates the camera a bit every frame.
349fn rotate_camera(
350 mut camera_query: Query<&mut Transform, With<Camera3d>>,
351 time: Res<Time>,
352 app_status: Res<AppStatus>,
353) {
354 if !app_status.rotating {
355 return;
356 }
357
358 for mut transform in camera_query.iter_mut() {
359 transform.translation = Vec2::from_angle(ROTATION_SPEED * time.delta_secs())
360 .rotate(transform.translation.xz())
361 .extend(transform.translation.y)
362 .xzy();
363 transform.look_at(Vec3::ZERO, Vec3::Y);
364 }
365}
366
367// Toggles between the unskinned sphere model and the skinned fox model if the
368// user requests it.
369fn change_main_object(
370 keyboard: Res<ButtonInput<KeyCode>>,
371 mut app_status: ResMut<AppStatus>,
372 mut sphere_query: Query<
373 &mut Visibility,
374 (With<MainObject>, With<Mesh3d>, Without<WorldAssetRoot>),
375 >,
376 mut fox_query: Query<&mut Visibility, (With<MainObject>, With<WorldAssetRoot>)>,
377) {
378 if !keyboard.just_pressed(KeyCode::Tab) {
379 return;
380 }
381 let Some(mut sphere_visibility) = sphere_query.iter_mut().next() else {
382 return;
383 };
384 let Some(mut fox_visibility) = fox_query.iter_mut().next() else {
385 return;
386 };
387
388 match app_status.model {
389 ExampleModel::Sphere => {
390 *sphere_visibility = Visibility::Hidden;
391 *fox_visibility = Visibility::Visible;
392 app_status.model = ExampleModel::Fox;
393 }
394 ExampleModel::Fox => {
395 *sphere_visibility = Visibility::Visible;
396 *fox_visibility = Visibility::Hidden;
397 app_status.model = ExampleModel::Sphere;
398 }
399 }
400}
401
402impl Default for AppStatus {
403 fn default() -> Self {
404 Self {
405 irradiance_volume_present: true,
406 rotating: true,
407 model: ExampleModel::Sphere,
408 voxels_visible: false,
409 }
410 }
411}
412
413// Turns on and off the irradiance volume as requested by the user.
414fn toggle_irradiance_volumes(
415 mut commands: Commands,
416 keyboard: Res<ButtonInput<KeyCode>>,
417 light_probe_query: Query<Entity, With<LightProbe>>,
418 mut app_status: ResMut<AppStatus>,
419 assets: Res<ExampleAssets>,
420 mut ambient_light: ResMut<GlobalAmbientLight>,
421) {
422 if !keyboard.just_pressed(KeyCode::Space) {
423 return;
424 };
425
426 let Some(light_probe) = light_probe_query.iter().next() else {
427 return;
428 };
429
430 if app_status.irradiance_volume_present {
431 commands.entity(light_probe).remove::<IrradianceVolume>();
432 ambient_light.brightness = AMBIENT_LIGHT_BRIGHTNESS * IRRADIANCE_VOLUME_INTENSITY;
433 app_status.irradiance_volume_present = false;
434 } else {
435 commands.entity(light_probe).insert(IrradianceVolume {
436 voxels: assets.irradiance_volume.clone(),
437 intensity: IRRADIANCE_VOLUME_INTENSITY,
438 ..default()
439 });
440 ambient_light.brightness = 0.0;
441 app_status.irradiance_volume_present = true;
442 }
443}
444
445fn toggle_rotation(keyboard: Res<ButtonInput<KeyCode>>, mut app_status: ResMut<AppStatus>) {
446 if keyboard.just_pressed(KeyCode::Enter) {
447 app_status.rotating = !app_status.rotating;
448 }
449}
450
451// Handles clicks on the plane that reposition the object.
452fn handle_mouse_clicks(
453 buttons: Res<ButtonInput<MouseButton>>,
454 windows: Query<&Window, With<PrimaryWindow>>,
455 cameras: Query<(&Camera, &GlobalTransform)>,
456 mut main_objects: Query<&mut Transform, With<MainObject>>,
457) {
458 if !buttons.pressed(MouseButton::Left) {
459 return;
460 }
461 let Some(mouse_position) = windows.iter().next().and_then(Window::cursor_position) else {
462 return;
463 };
464 let Some((camera, camera_transform)) = cameras.iter().next() else {
465 return;
466 };
467
468 // Figure out where the user clicked on the plane.
469 let Ok(ray) = camera.viewport_to_world(camera_transform, mouse_position) else {
470 return;
471 };
472 let Some(plane_intersection) =
473 ray.plane_intersection_point(Vec3::ZERO, InfinitePlane3d::new(Vec3::Y))
474 else {
475 return;
476 };
477 // Move all the main objects.
478 for mut transform in main_objects.iter_mut() {
479 transform.translation = vec3(
480 plane_intersection.x,
481 transform.translation.y,
482 plane_intersection.z,
483 );
484 }
485}
486
487impl FromWorld for ExampleAssets {
488 fn from_world(world: &mut World) -> Self {
489 let fox_animation =
490 world.load_asset(GltfAssetLabel::Animation(1).from_asset("models/animated/Fox.glb"));
491 let (fox_animation_graph, fox_animation_node) =
492 AnimationGraph::from_clip(fox_animation.clone());
493
494 ExampleAssets {
495 main_sphere: world.add_asset(Sphere::default().mesh().uv(32, 18)),
496 fox: world.load_asset(GltfAssetLabel::Scene(0).from_asset("models/animated/Fox.glb")),
497 main_sphere_material: world.add_asset(Color::from(SILVER)),
498 main_scene: world.load_asset(
499 GltfAssetLabel::Scene(0)
500 .from_asset("models/IrradianceVolumeExample/IrradianceVolumeExample.glb"),
501 ),
502 irradiance_volume: world.load_asset("irradiance_volumes/Example.vxgi.ktx2"),
503 fox_animation_graph: world.add_asset(fox_animation_graph),
504 fox_animation_node,
505 voxel_cube: world.add_asset(Cuboid::default()),
506 // Just use a specular map for the skybox since it's not too blurry.
507 // In reality you wouldn't do this--you'd use a real skybox texture--but
508 // reusing the textures like this saves space in the Bevy repository.
509 skybox: world.load_asset("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
510 }
511 }
512}
513
514// Plays the animation on the fox.
515fn play_animations(
516 mut commands: Commands,
517 assets: Res<ExampleAssets>,
518 mut players: Query<(Entity, &mut AnimationPlayer), Without<AnimationGraphHandle>>,
519) {
520 for (entity, mut player) in players.iter_mut() {
521 commands
522 .entity(entity)
523 .insert(AnimationGraphHandle(assets.fox_animation_graph.clone()));
524 player.play(assets.fox_animation_node).repeat();
525 }
526}
527
528fn create_cubes(
529 image_assets: Res<Assets<Image>>,
530 mut commands: Commands,
531 irradiance_volumes: Query<(&IrradianceVolume, &GlobalTransform)>,
532 voxel_cube_parents: Query<Entity, With<VoxelCubeParent>>,
533 voxel_cubes: Query<Entity, With<VoxelCube>>,
534 example_assets: Res<ExampleAssets>,
535 mut voxel_visualization_material_assets: ResMut<Assets<VoxelVisualizationMaterial>>,
536) {
537 // If voxel cubes have already been spawned, don't do anything.
538 if !voxel_cubes.is_empty() {
539 return;
540 }
541
542 let Some(voxel_cube_parent) = voxel_cube_parents.iter().next() else {
543 return;
544 };
545
546 for (irradiance_volume, global_transform) in irradiance_volumes.iter() {
547 let Some(image) = image_assets.get(&irradiance_volume.voxels) else {
548 continue;
549 };
550
551 let resolution = image.texture_descriptor.size;
552
553 let voxel_cube_material = voxel_visualization_material_assets.add(ExtendedMaterial {
554 base: StandardMaterial::from(Color::from(RED)),
555 extension: VoxelVisualizationExtension {
556 irradiance_volume_info: VoxelVisualizationIrradianceVolumeInfo {
557 world_from_voxel: VOXEL_FROM_WORLD.inverse(),
558 voxel_from_world: VOXEL_FROM_WORLD,
559 resolution: uvec3(
560 resolution.width,
561 resolution.height,
562 resolution.depth_or_array_layers,
563 ),
564 intensity: IRRADIANCE_VOLUME_INTENSITY,
565 },
566 },
567 });
568
569 let scale = vec3(
570 1.0 / resolution.width as f32,
571 1.0 / resolution.height as f32,
572 1.0 / resolution.depth_or_array_layers as f32,
573 );
574
575 // Spawn a cube for each voxel.
576 for z in 0..resolution.depth_or_array_layers {
577 for y in 0..resolution.height {
578 for x in 0..resolution.width {
579 let uvw = (uvec3(x, y, z).as_vec3() + 0.5) * scale - 0.5;
580 let pos = global_transform.transform_point(uvw);
581 let voxel_cube = commands
582 .spawn((
583 Mesh3d(example_assets.voxel_cube.clone()),
584 MeshMaterial3d(voxel_cube_material.clone()),
585 Transform::from_scale(Vec3::splat(VOXEL_CUBE_SCALE))
586 .with_translation(pos),
587 ))
588 .insert(VoxelCube)
589 .insert(NotShadowCaster)
590 .id();
591
592 commands.entity(voxel_cube_parent).add_child(voxel_cube);
593 }
594 }
595 }
596 }
597}More examples
278fn spawn_flight_helmet(commands: &mut Commands, asset_server: &AssetServer) {
279 commands.spawn((
280 WorldAssetRoot(
281 asset_server
282 .load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
283 ),
284 Transform::from_scale(Vec3::splat(2.5)),
285 FlightHelmetModel,
286 Visibility::Hidden,
287 ));
288}
289
290// Spawns the row of capsules.
291fn spawn_capsules(
292 commands: &mut Commands,
293 meshes: &mut Assets<Mesh>,
294 standard_materials: &mut Assets<StandardMaterial>,
295) {
296 let capsule_mesh = meshes.add(Capsule3d::new(0.4, 0.5));
297 let parent = commands
298 .spawn((
299 Transform::from_xyz(0.0, 0.5, 0.0),
300 Visibility::Hidden,
301 CapsulesParent,
302 ))
303 .id();
304
305 for i in 0..5 {
306 let roughness = i as f32 * 0.25;
307 let child = commands
308 .spawn((
309 Mesh3d(capsule_mesh.clone()),
310 MeshMaterial3d(standard_materials.add(StandardMaterial {
311 base_color: Color::BLACK,
312 perceptual_roughness: roughness.max(0.08),
313 ..default()
314 })),
315 Transform::from_xyz(i as f32 * 1.1 - (1.1 * 2.0), 0.5, 0.0),
316 CapsuleModel,
317 ))
318 .id();
319 commands.entity(parent).add_child(child);
320 }
321}
322
323// Spawns the metallic base.
324fn spawn_metallic_base(
325 commands: &mut Commands,
326 meshes: &mut Assets<Mesh>,
327 standard_materials: &mut Assets<StandardMaterial>,
328) {
329 commands.spawn((
330 Mesh3d(meshes.add(Plane3d::new(Vec3::Y, Vec2::splat(1.0)))),
331 MeshMaterial3d(standard_materials.add(StandardMaterial {
332 base_color: Color::from(bevy::color::palettes::css::DARK_GRAY),
333 metallic: 1.0,
334 perceptual_roughness: 0.3,
335 ..default()
336 })),
337 Transform::from_scale(Vec3::splat(100.0)),
338 MetallicBaseModel,
339 Visibility::Hidden,
340 ));
341}
342
343// Spawns the non-metallic base.
344fn spawn_non_metallic_base(
345 commands: &mut Commands,
346 meshes: &mut Assets<Mesh>,
347 standard_materials: &mut Assets<StandardMaterial>,
348) {
349 commands.spawn((
350 Mesh3d(meshes.add(Plane3d::new(Vec3::Y, Vec2::splat(1.0)))),
351 MeshMaterial3d(standard_materials.add(StandardMaterial {
352 base_color: Color::from(bevy::color::palettes::css::RED),
353 metallic: 0.0,
354 perceptual_roughness: 0.2,
355 ..default()
356 })),
357 Transform::from_scale(Vec3::splat(100.0)),
358 RedPlaneBaseModel,
359 Visibility::Hidden,
360 ));
361}
362
363// Spawns the water plane.
364fn spawn_water(
365 commands: &mut Commands,
366 asset_server: &AssetServer,
367 meshes: &mut Assets<Mesh>,
368 water_materials: &mut Assets<ExtendedMaterial<StandardMaterial, Water>>,
369) {
370 commands.spawn((
371 Mesh3d(meshes.add(Plane3d::new(Vec3::Y, Vec2::splat(1.0)))),
372 MeshMaterial3d(
373 water_materials.add(ExtendedMaterial {
374 base: StandardMaterial {
375 base_color: BLACK.into(),
376 perceptual_roughness: 0.09,
377 ..default()
378 },
379 extension: Water {
380 normals: asset_server
381 .load_builder()
382 .with_settings::<ImageLoaderSettings>(|settings| {
383 settings.is_srgb = false;
384 settings.sampler = ImageSampler::Descriptor(ImageSamplerDescriptor {
385 address_mode_u: ImageAddressMode::Repeat,
386 address_mode_v: ImageAddressMode::Repeat,
387 mag_filter: ImageFilterMode::Linear,
388 min_filter: ImageFilterMode::Linear,
389 ..default()
390 });
391 })
392 .load("textures/water_normals.png"),
393 // These water settings are just random values to create some
394 // variety.
395 settings: WaterSettings {
396 octave_vectors: [
397 vec4(0.080, 0.059, 0.073, -0.062),
398 vec4(0.153, 0.138, -0.149, -0.195),
399 ],
400 octave_scales: vec4(1.0, 2.1, 7.9, 14.9) * 5.0,
401 octave_strengths: vec4(0.16, 0.18, 0.093, 0.044),
402 },
403 },
404 }),
405 ),
406 Transform::from_scale(Vec3::splat(100.0)),
407 WaterModel,
408 ));
409}46fn setup(
47 mut commands: Commands,
48 asset_server: Res<AssetServer>,
49 mut materials: ResMut<Assets<CustomMaterial>>,
50) {
51 // Add a mesh loaded from a glTF file. This mesh has data for `ATTRIBUTE_BARYCENTRIC`.
52 let mesh = asset_server.load(
53 GltfAssetLabel::Primitive {
54 mesh: 0,
55 primitive: 0,
56 }
57 .from_asset("models/barycentric/barycentric.gltf"),
58 );
59 commands.spawn((
60 Mesh2d(mesh),
61 MeshMaterial2d(materials.add(CustomMaterial {})),
62 Transform::from_scale(150.0 * Vec3::ONE),
63 ));
64
65 commands.spawn(Camera2d);
66}156fn spawn_reflection_probe(commands: &mut Commands, cubemaps: &Cubemaps) {
157 commands.spawn((
158 LightProbe::default(),
159 EnvironmentMapLight {
160 diffuse_map: cubemaps.diffuse_environment_map.clone(),
161 specular_map: cubemaps.specular_reflection_probe.clone(),
162 intensity: ENV_MAP_INTENSITY,
163 ..default()
164 },
165 // 2.0 because the sphere's radius is 1.0 and we want to fully enclose it.
166 Transform::from_scale(Vec3::splat(2.0)),
167 // Disable parallax correction because the reflected scene is quite
168 // distant.
169 ParallaxCorrection::None,
170 ));
171}- examples/3d/pccm.rs
- examples/ecs/parallel_query.rs
- examples/shader/compute_shader_game_of_life.rs
- examples/2d/sprite_sheet.rs
- examples/animation/animation_graph.rs
- examples/animation/animation_masks.rs
- examples/3d/mirror.rs
- examples/3d/atmospheric_fog.rs
- examples/ecs/hierarchy.rs
- examples/3d/light_probe_blending.rs
- examples/3d/atmosphere.rs
- examples/3d/fog.rs
- examples/2d/sprite_animation.rs
- examples/3d/volumetric_fog.rs
- examples/3d/motion_blur.rs
- examples/time/virtual_time.rs
- examples/stress_tests/many_lights.rs
- examples/3d/decal.rs
- examples/ecs/iter_combinations.rs
- examples/3d/solari.rs
- examples/showcase/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
targetis the same as the transform translation,Vec3::Zis used instead - if
upfails converting toDir3(e.g if it isVec3::ZERO),Dir3::Yis used instead - if the resulting forward direction is parallel with
up, an orthogonal vector is used as the “right” direction
Examples found in repository?
201fn spawn_light(commands: &mut Commands) {
202 commands.spawn((
203 DirectionalLight::default(),
204 Transform::from_xyz(4.0, 8.0, 4.0).looking_at(Vec3::ZERO, Vec3::Y),
205 ));
206}
207
208/// Spawns the camera.
209fn spawn_camera(commands: &mut Commands) {
210 commands
211 .spawn(Camera3d::default())
212 .insert(Transform::from_xyz(0.0, 2.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y))
213 // Tag the camera with `Selection::Camera`.
214 .insert(Selection::Camera);
215}More examples
- examples/3d/reflection_probes.rs
- examples/app/externally_driven_headless_renderer.rs
- examples/3d/irradiance_volumes.rs
- examples/gizmos/3d_text_gizmos.rs
- examples/math/render_primitives.rs
- examples/stress_tests/many_gizmos.rs
- examples/scene/world_serialization.rs
- examples/gltf/gltf_skinned_mesh.rs
- examples/showcase/alien_cake_addict.rs
- examples/3d/mirror.rs
- examples/shader/animate_shader.rs
- examples/async_tasks/async_compute.rs
- examples/gltf/query_gltf_primitives.rs
- examples/shader/shader_material_wesl.rs
- examples/3d/light_textures.rs
- examples/shader/fallback_image.rs
- examples/shader_advanced/custom_phase_item.rs
- examples/shader_advanced/fullscreen_material.rs
- examples/3d/3d_viewport_to_world.rs
- examples/shader/shader_material.rs
- examples/shader/shader_material_glsl.rs
- examples/shader_advanced/texture_binding_array.rs
- examples/asset/hot_asset_reloading.rs
- examples/asset/multi_asset_sync.rs
- examples/shader_advanced/manual_material.rs
- examples/3d/color_grading.rs
- examples/transforms/3d_rotation.rs
- examples/transforms/scale.rs
- examples/async_tasks/async_channel_pattern.rs
- examples/shader_advanced/custom_vertex_attribute.rs
- examples/animation/morph_targets.rs
- examples/3d/3d_scene.rs
- tests/window/minimizing.rs
- tests/window/resizing.rs
- examples/3d/atmospheric_fog.rs
- examples/transforms/translation.rs
- examples/shader/shader_defs.rs
- examples/gltf/load_gltf_extras.rs
- examples/animation/animated_mesh.rs
- examples/showcase/loading_screen.rs
- examples/3d/parenting.rs
- examples/animation/animation_graph.rs
- examples/3d/post_processing.rs
- examples/shader/shader_material_screenspace_texture.rs
- examples/3d/depth_of_field.rs
- examples/camera/camera_orbit.rs
- examples/shader/shader_material_bindless.rs
- examples/gltf/edit_material_on_gltf.rs
- examples/remote/server.rs
- examples/animation/animation_masks.rs
- examples/3d/anisotropy.rs
- examples/window/screenshot.rs
- examples/3d/animated_material.rs
- examples/shader_advanced/custom_post_processing.rs
- examples/camera/custom_projection.rs
- examples/picking/custom_hit_data.rs
- examples/shader_advanced/render_depth_to_texture.rs
- examples/gltf/load_gltf.rs
- examples/3d/two_passes.rs
- examples/stress_tests/many_materials.rs
- examples/gltf/gltf_extension_animation_graph.rs
- examples/diagnostics/log_diagnostics.rs
- examples/shader/extended_material_bindless.rs
- examples/3d/tonemapping.rs
- examples/shader_advanced/custom_render_phase.rs
- examples/dev_tools/infinite_grid.rs
- examples/gltf/update_gltf_scene.rs
- examples/3d/skybox.rs
- examples/3d/fog_volumes.rs
- examples/3d/lines.rs
- examples/shader/storage_buffer.rs
- examples/window/low_power.rs
- examples/3d/order_independent_transparency.rs
- examples/shader/array_texture.rs
- examples/3d/generate_custom_mesh.rs
- examples/3d/ssr.rs
- examples/3d/mesh_ray_cast.rs
- examples/picking/simple_picking.rs
- examples/movement/smooth_follow.rs
- examples/shader/extended_material.rs
- examples/3d/vertex_colors.rs
- examples/animation/animated_mesh_control.rs
- examples/shader_advanced/custom_shader_instancing.rs
- tests/window/desktop_request_redraw.rs
- examples/3d/orthographic.rs
- examples/picking/debug_picking.rs
- examples/shader_advanced/specialized_mesh_pipeline.rs
- examples/window/multiple_windows.rs
- examples/3d/spherical_area_lights.rs
- examples/stress_tests/many_morph_targets.rs
- examples/transforms/transform.rs
- examples/gizmos/axes.rs
- examples/3d/light_probe_blending.rs
- examples/app/headless_renderer.rs
- examples/3d/ssao.rs
- examples/3d/atmosphere.rs
- examples/animation/animated_mesh_events.rs
- examples/app/render_recovery.rs
- examples/animation/eased_motion.rs
- examples/audio/spatial_audio_3d.rs
- examples/shader/automatic_instancing.rs
- examples/ecs/error_handling.rs
- examples/camera/projection_zoom.rs
- examples/3d/rect_light.rs
- examples/3d/specular_tint.rs
- examples/3d/visibility_range.rs
- examples/3d/volumetric_fog.rs
- tests/3d/test_invalid_skinned_mesh.rs
- examples/stress_tests/many_cameras_lights.rs
- examples/3d/texture.rs
- examples/3d/shadow_caster_receiver.rs
- examples/3d/wireframe.rs
- examples/3d/bloom_3d.rs
- examples/3d/anti_aliasing.rs
- examples/gizmos/3d_gizmos.rs
- examples/transforms/align.rs
- examples/3d/decal.rs
- examples/math/random_sampling.rs
- examples/testbed/3d.rs
- examples/3d/scrolling_fog.rs
- examples/ecs/iter_combinations.rs
- examples/shader_advanced/compute_mesh.rs
- examples/3d/render_to_texture.rs
- examples/gizmos/transform_gizmo.rs
- examples/3d/transparency_3d.rs
- examples/asset/repeated_texture.rs
- examples/2d/mesh2d_repeated_texture.rs
- examples/3d/spotlight.rs
- examples/asset/alter_mesh.rs
- examples/3d/meshlet.rs
- examples/3d/pbr.rs
- examples/3d/auto_exposure.rs
- examples/asset/asset_loading.rs
- examples/gizmos/light_gizmos.rs
- examples/stress_tests/bevymark_3d.rs
- examples/shader/shader_prepass.rs
- examples/3d/shadow_biases.rs
- examples/3d/split_screen.rs
- examples/picking/mesh_picking.rs
- examples/ui/render_ui_to_texture.rs
- examples/3d/parallax_mapping.rs
- examples/3d/fog.rs
- examples/stress_tests/many_foxes.rs
- examples/3d/deferred_rendering.rs
- examples/3d/contact_shadows.rs
- examples/3d/3d_shapes.rs
- examples/animation/custom_skinned_mesh.rs
- examples/usage/debug_frustum_culling.rs
- examples/3d/blend_modes.rs
- examples/animation/animated_transform.rs
- examples/3d/lighting.rs
- examples/3d/camera_sub_view.rs
- examples/3d/transmission.rs
- examples/stress_tests/many_cubes.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
directionfails converting toDir3(e.g if it isVec3::ZERO),Dir3::Zis used instead - if
upfails converting toDir3,Dir3::Yis used instead - if
directionis parallel withup, an orthogonal vector is used as the “right” direction
Examples found in repository?
More examples
76fn spawn_camera(mut commands: Commands) {
77 commands.spawn((
78 Camera3d::default(),
79 Transform::from_xyz(0.0, 1.0, 0.0).looking_to(Vec3::X, Vec3::Y),
80 // This component stores all camera settings and state, which is used by the FreeCameraPlugin to
81 // control it. These properties can be changed at runtime, but beware the controller system is
82 // constantly using and modifying those values unless the enabled field is false.
83 FreeCamera {
84 sensitivity: 0.2,
85 friction: 25.0,
86 walk_speed: 3.0,
87 run_speed: 9.0,
88 ..default()
89 },
90 ));
91}188fn spawn_environment(
189 mut commands: Commands,
190 mut meshes: ResMut<Assets<Mesh>>,
191 mut materials: ResMut<Assets<StandardMaterial>>,
192) {
193 let sphere_material = materials.add(Color::from(tailwind::SKY_200));
194 let sphere_mesh = meshes.add(Sphere::new(0.3));
195 let spheres_in_x = 6;
196 let spheres_in_y = 4;
197 let spheres_in_z = 10;
198 let distance = 3.0;
199 for x in 0..spheres_in_x {
200 for y in 0..spheres_in_y {
201 for z in 0..spheres_in_z {
202 let translation = Vec3::new(
203 x as f32 * distance - (spheres_in_x as f32 - 1.0) * distance / 2.0,
204 y as f32 * distance - (spheres_in_y as f32 - 1.0) * distance / 2.0,
205 z as f32 * distance - (spheres_in_z as f32 - 1.0) * distance / 2.0,
206 );
207 commands.spawn((
208 Name::new("Sphere"),
209 Transform::from_translation(translation),
210 Mesh3d(sphere_mesh.clone()),
211 MeshMaterial3d(sphere_material.clone()),
212 ));
213 }
214 }
215 }
216
217 commands.spawn((
218 DirectionalLight::default(),
219 Transform::default().looking_to(Vec3::new(-1.0, -3.0, 0.5), Vec3::Y),
220 ));
221}13fn setup(
14 mut commands: Commands,
15 asset_server: Res<AssetServer>,
16 mut materials: ResMut<Assets<StandardMaterial>>,
17 meshes: Res<Assets<Mesh>>,
18) {
19 commands.spawn((Camera3d::default(), Transform::from_xyz(0.0, 0.0, 5.0)));
20
21 commands.spawn((
22 DirectionalLight::default(),
23 Transform::default().looking_to(Dir3::new(Vec3::new(-1.0, -1.0, -1.0)).unwrap(), Dir3::Y),
24 ));
25
26 // The simplest way to generate an asset is to add it directly to the `Assets`.
27 let material_handle = materials.add(StandardMaterial::default());
28
29 commands.spawn((
30 Transform::from_xyz(-2.0, 0.0, 0.0),
31 MeshMaterial3d(material_handle.clone()),
32 // Alternatively, `add_async` creates a task that runs your async function. Once it
33 // completes, the asset is added to the `Assets`. This is "deferred" meaning that the asset
34 // may take a frame to be added after the task completes.
35 Mesh3d(asset_server.add_async(generate_mesh_async())),
36 ));
37
38 // The last way to generate assets is to reserve a handle, and then use `Assets::insert` to
39 // populate the asset later. In this example, the `generate_mesh_system` system runs to populate
40 // the mesh.
41 let mesh_handle = meshes.reserve_handle();
42 commands.insert_resource(HandleToGenerate(mesh_handle.clone()));
43 commands.spawn((
44 Transform::from_xyz(2.0, 0.0, 0.0)
45 .with_rotation(Quat::from_rotation_x(50.0f32.to_radians())),
46 Mesh3d(mesh_handle),
47 MeshMaterial3d(material_handle),
48 ));
49}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_axisormain_directionfail converting toDir3(e.g are zero),Dir3::Xtakes their place - if
secondary_axisorsecondary_directionfail converting,Dir3::Ytakes their place - if
main_axisis parallel withsecondary_axisormain_directionis parallel withsecondary_direction, a rotation is constructed which takesmain_axistomain_directionalong 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?
220fn spawn_ground_plane(
221 commands: &mut Commands,
222 meshes: &mut Assets<Mesh>,
223 standard_materials: &mut Assets<StandardMaterial>,
224) {
225 commands.spawn((
226 Mesh3d(meshes.add(Circle::new(200.0))),
227 MeshMaterial3d(standard_materials.add(Color::from(GREEN))),
228 Transform::from_rotation(Quat::from_rotation_x(-FRAC_PI_2))
229 .with_translation(vec3(-25.0, 0.0, 0.0)),
230 ));
231}
232
233/// Creates the initial image that the mirror camera will render the mirror
234/// world to.
235fn create_mirror_texture_resource(
236 commands: &mut Commands,
237 windows_query: &Query<&Window>,
238 images: &mut Assets<Image>,
239) -> Handle<Image> {
240 let window = windows_query.iter().next().expect("No window found");
241 let window_size = uvec2(window.physical_width(), window.physical_height());
242 let image = create_mirror_texture_image(images, window_size);
243 commands.insert_resource(MirrorImage(image.clone()));
244 image
245}
246
247/// Spawns the camera that renders the mirror world.
248fn spawn_mirror_camera(
249 commands: &mut Commands,
250 camera_transform: &Transform,
251 camera_projection: &PerspectiveProjection,
252 mirror_transform: &Transform,
253 mirror_render_target: Handle<Image>,
254) {
255 let (mirror_camera_transform, mirror_camera_projection) =
256 calculate_mirror_camera_transform_and_projection(
257 camera_transform,
258 camera_projection,
259 mirror_transform,
260 );
261
262 commands.spawn((
263 Camera3d::default(),
264 Camera {
265 order: -1,
266 // Reflecting the model across the mirror will flip the winding of
267 // all the polygons. Therefore, in order to properly backface cull,
268 // we need to turn on `invert_culling`.
269 invert_culling: true,
270 ..default()
271 },
272 RenderTarget::Image(mirror_render_target.clone().into()),
273 mirror_camera_transform,
274 Projection::Perspective(mirror_camera_projection),
275 MirrorCamera,
276 ));
277}
278
279/// Spawns the animated fox.
280///
281/// Note that this doesn't play the animation; that's handled in
282/// [`play_fox_animation`].
283fn spawn_fox(commands: &mut Commands, asset_server: &AssetServer) {
284 commands.spawn((
285 WorldAssetRoot(asset_server.load(GltfAssetLabel::Scene(0).from_asset(FOX_ASSET_PATH))),
286 Transform::from_xyz(-50.0, 0.0, -100.0),
287 ));
288}
289
290/// Spawns the mirror plane mesh and returns its transform.
291fn spawn_mirror(
292 commands: &mut Commands,
293 meshes: &mut Assets<Mesh>,
294 screen_space_texture_materials: &mut Assets<
295 ExtendedMaterial<StandardMaterial, ScreenSpaceTextureExtension>,
296 >,
297 mirror_render_target: Handle<Image>,
298) -> Transform {
299 let mirror_transform = Transform::from_scale(vec3(300.0, 1.0, 150.0))
300 .with_rotation(Quat::from_rotation_x(MIRROR_ROTATION_ANGLE))
301 .with_translation(MIRROR_POSITION);
302
303 commands.spawn((
304 Mesh3d(meshes.add(Plane3d::default().mesh().size(1.0, 1.0))),
305 MeshMaterial3d(screen_space_texture_materials.add(ExtendedMaterial {
306 base: StandardMaterial {
307 base_color: Color::BLACK,
308 emissive: Color::WHITE.into(),
309 emissive_texture: Some(mirror_render_target),
310 perceptual_roughness: 0.0,
311 metallic: 1.0,
312 ..default()
313 },
314 extension: ScreenSpaceTextureExtension { dummy: 0.0 },
315 })),
316 mirror_transform,
317 Mirror,
318 ));
319
320 mirror_transform
321}More examples
10fn spawn_system(mut commands: Commands, asset_server: Res<AssetServer>) {
11 commands.spawn(Camera2d);
12 let texture = asset_server.load("branding/icon.png");
13
14 // We're seeding the PRNG here to make this example deterministic for testing purposes.
15 // This isn't strictly required in practical use unless you need your app to be deterministic.
16 let mut rng = ChaCha8Rng::seed_from_u64(19878367467713);
17 for z in 0..128 {
18 commands.spawn((
19 Sprite::from_image(texture.clone()),
20 Transform::from_scale(Vec3::splat(0.1))
21 .with_translation(Vec2::splat(0.0).extend(z as f32)),
22 Velocity(20.0 * Vec2::new(rng.random::<f32>() - 0.5, rng.random::<f32>() - 0.5)),
23 ));
24 }
25}187fn spawn_light(commands: &mut Commands, app_status: &AppStatus) {
188 // Because this light can become a directional light, point light, or spot
189 // light depending on the settings, we add the union of the components
190 // necessary for this light to behave as all three of those.
191 commands
192 .spawn((
193 create_directional_light(app_status),
194 Transform::from_rotation(Quat::from_array([
195 0.6539259,
196 -0.34646285,
197 0.36505926,
198 -0.5648683,
199 ]))
200 .with_translation(vec3(57.693, 34.334, -6.422)),
201 ))
202 // These two are needed for point lights.
203 .insert(CubemapVisibleEntities::default())
204 .insert(CubemapFrusta::default())
205 // These two are needed for spot lights.
206 .insert(VisibleMeshEntities::default())
207 .insert(Frustum::default());
208}317fn spawn_light_probes(commands: &mut Commands, asset_server: &AssetServer) {
318 // Spawn the first room's light probe.
319 commands.spawn((
320 LightProbe {
321 falloff: Vec3::splat(LIGHT_PROBE_FALLOFF),
322 },
323 EnvironmentMapLight {
324 diffuse_map: asset_server.load(get_web_asset_url("diffuse_room1.ktx2")),
325 specular_map: asset_server.load(get_web_asset_url("specular_room1.ktx2")),
326 intensity: LIGHT_PROBE_INTENSITY,
327 ..default()
328 },
329 Transform::from_scale(vec3(1.0, -1.0, 1.0) * LIGHT_PROBE_SIDE_LENGTH)
330 .with_rotation(Quat::from_rotation_x(PI)),
331 ParallaxCorrection::Custom(Vec3::splat(LIGHT_PROBE_PARALLAX_CORRECTION_SIDE_LENGTH)),
332 ));
333
334 // Spawn the second room's light probe.
335 commands.spawn((
336 LightProbe {
337 falloff: Vec3::splat(LIGHT_PROBE_FALLOFF),
338 },
339 EnvironmentMapLight {
340 diffuse_map: asset_server.load(get_web_asset_url("diffuse_room2.ktx2")),
341 specular_map: asset_server.load(get_web_asset_url("specular_room2.ktx2")),
342 intensity: LIGHT_PROBE_INTENSITY,
343 ..default()
344 },
345 Transform::from_scale(vec3(1.0, -1.0, 1.0) * LIGHT_PROBE_SIDE_LENGTH)
346 .with_rotation(Quat::from_rotation_x(PI))
347 .with_translation(vec3(0.0, 0.0, -ROOM_SEPARATION)),
348 ParallaxCorrection::Custom(Vec3::splat(LIGHT_PROBE_PARALLAX_CORRECTION_SIDE_LENGTH)),
349 ));
350}212fn setup_terrain_scene(
213 mut commands: Commands,
214 mut meshes: ResMut<Assets<Mesh>>,
215 mut water_materials: ResMut<Assets<ExtendedMaterial<StandardMaterial, Water>>>,
216 asset_server: Res<AssetServer>,
217) {
218 // Sun
219 commands.spawn((
220 DirectionalLight {
221 shadow_maps_enabled: true,
222 // lux::RAW_SUNLIGHT is recommended for use with this feature, since
223 // other values approximate sunlight *post-scattering* in various
224 // conditions. RAW_SUNLIGHT in comparison is the illuminance of the
225 // sun unfiltered by the atmosphere, so it is the proper input for
226 // sunlight to be filtered by the atmosphere.
227 illuminance: lux::RAW_SUNLIGHT,
228 ..default()
229 },
230 Transform::from_xyz(1.0, 0.4, 0.0).looking_at(Vec3::ZERO, Vec3::Y),
231 VolumetricLight,
232 ));
233
234 // spawn the fog volume
235 commands.spawn((
236 FogVolume::default(),
237 Transform::from_scale(Vec3::new(10.0, 1.0, 10.0)).with_translation(Vec3::Y * 0.5),
238 ));
239
240 // Terrain
241 commands.spawn((
242 Terrain,
243 WorldAssetRoot(
244 asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/terrain/terrain.glb")),
245 ),
246 Transform::from_xyz(-1.0, 0.0, -0.5)
247 .with_scale(Vec3::splat(0.5))
248 .with_rotation(Quat::from_rotation_y(PI / 2.0)),
249 ));
250
251 spawn_water(
252 &mut commands,
253 &asset_server,
254 &mut meshes,
255 &mut water_materials,
256 );
257}56fn setup_pyramid_scene(
57 mut commands: Commands,
58 mut meshes: ResMut<Assets<Mesh>>,
59 mut materials: ResMut<Assets<StandardMaterial>>,
60) {
61 let stone = materials.add(StandardMaterial {
62 base_color: Srgba::hex("28221B").unwrap().into(),
63 perceptual_roughness: 1.0,
64 ..default()
65 });
66
67 // pillars
68 for (x, z) in &[(-1.5, -1.5), (1.5, -1.5), (1.5, 1.5), (-1.5, 1.5)] {
69 commands.spawn((
70 Mesh3d(meshes.add(Cuboid::new(1.0, 3.0, 1.0))),
71 MeshMaterial3d(stone.clone()),
72 Transform::from_xyz(*x, 1.5, *z),
73 ));
74 }
75
76 // orb
77 commands.spawn((
78 Mesh3d(meshes.add(Sphere::default())),
79 MeshMaterial3d(materials.add(StandardMaterial {
80 base_color: Srgba::hex("126212CC").unwrap().into(),
81 reflectance: 1.0,
82 perceptual_roughness: 0.0,
83 metallic: 0.5,
84 alpha_mode: AlphaMode::Blend,
85 ..default()
86 })),
87 Transform::from_scale(Vec3::splat(1.75)).with_translation(Vec3::new(0.0, 4.0, 0.0)),
88 NotShadowCaster,
89 NotShadowReceiver,
90 ));
91
92 // steps
93 for i in 0..50 {
94 let half_size = i as f32 / 2.0 + 3.0;
95 let y = -i as f32 / 2.0;
96 commands.spawn((
97 Mesh3d(meshes.add(Cuboid::new(2.0 * half_size, 0.5, 2.0 * half_size))),
98 MeshMaterial3d(stone.clone()),
99 Transform::from_xyz(0.0, y + 0.25, 0.0),
100 ));
101 }
102
103 // sky
104 commands.spawn((
105 Mesh3d(meshes.add(Cuboid::new(2.0, 1.0, 1.0))),
106 MeshMaterial3d(materials.add(StandardMaterial {
107 base_color: Srgba::hex("888888").unwrap().into(),
108 unlit: true,
109 cull_mode: None,
110 ..default()
111 })),
112 Transform::from_scale(Vec3::splat(1_000_000.0)),
113 ));
114
115 // light
116 commands.spawn((
117 PointLight {
118 shadow_maps_enabled: true,
119 ..default()
120 },
121 Transform::from_xyz(0.0, 1.0, 0.0),
122 ));
123}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?
111fn spawn_scene(commands: &mut Commands, asset_server: &AssetServer) {
112 // Spawn the main scene.
113 commands.spawn(WorldAssetRoot(asset_server.load(
114 GltfAssetLabel::Scene(0).from_asset("models/TonemappingTest/TonemappingTest.gltf"),
115 )));
116
117 // Spawn the flight helmet.
118 commands.spawn((
119 WorldAssetRoot(
120 asset_server
121 .load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
122 ),
123 Transform::from_xyz(0.5, 0.0, -0.5).with_rotation(Quat::from_rotation_y(-0.15 * PI)),
124 ));
125
126 // Spawn the light.
127 commands.spawn((
128 DirectionalLight {
129 illuminance: 15000.0,
130 shadow_maps_enabled: true,
131 ..default()
132 },
133 Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, PI * -0.15, PI * -0.15)),
134 CascadeShadowConfigBuilder {
135 maximum_distance: 3.0,
136 first_cascade_far_bound: 0.9,
137 ..default()
138 }
139 .build(),
140 ));
141}More examples
345fn add_basic_scene(commands: &mut Commands, asset_server: &AssetServer) {
346 // Spawn the main scene.
347 commands.spawn(WorldAssetRoot(asset_server.load(
348 GltfAssetLabel::Scene(0).from_asset("models/TonemappingTest/TonemappingTest.gltf"),
349 )));
350
351 // Spawn the flight helmet.
352 commands.spawn((
353 WorldAssetRoot(
354 asset_server
355 .load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
356 ),
357 Transform::from_xyz(0.5, 0.0, -0.5).with_rotation(Quat::from_rotation_y(-0.15 * PI)),
358 ));
359
360 // Spawn the light.
361 commands.spawn((
362 DirectionalLight {
363 illuminance: 15000.0,
364 shadow_maps_enabled: true,
365 ..default()
366 },
367 Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, PI * -0.15, PI * -0.15)),
368 CascadeShadowConfigBuilder {
369 maximum_distance: 3.0,
370 first_cascade_far_bound: 0.9,
371 ..default()
372 }
373 .build(),
374 ));
375}291fn spawn_mirror(
292 commands: &mut Commands,
293 meshes: &mut Assets<Mesh>,
294 screen_space_texture_materials: &mut Assets<
295 ExtendedMaterial<StandardMaterial, ScreenSpaceTextureExtension>,
296 >,
297 mirror_render_target: Handle<Image>,
298) -> Transform {
299 let mirror_transform = Transform::from_scale(vec3(300.0, 1.0, 150.0))
300 .with_rotation(Quat::from_rotation_x(MIRROR_ROTATION_ANGLE))
301 .with_translation(MIRROR_POSITION);
302
303 commands.spawn((
304 Mesh3d(meshes.add(Plane3d::default().mesh().size(1.0, 1.0))),
305 MeshMaterial3d(screen_space_texture_materials.add(ExtendedMaterial {
306 base: StandardMaterial {
307 base_color: Color::BLACK,
308 emissive: Color::WHITE.into(),
309 emissive_texture: Some(mirror_render_target),
310 perceptual_roughness: 0.0,
311 metallic: 1.0,
312 ..default()
313 },
314 extension: ScreenSpaceTextureExtension { dummy: 0.0 },
315 })),
316 mirror_transform,
317 Mirror,
318 ));
319
320 mirror_transform
321}158fn spawn_camera(commands: &mut Commands, asset_server: &AssetServer) {
159 commands
160 .spawn((
161 Camera3d::default(),
162 Transform::from_xyz(-12.912 * 0.7, 4.466 * 0.7, -10.624 * 0.7).with_rotation(
163 Quat::from_euler(EulerRot::YXZ, -134.76 / 180.0 * PI, -0.175, 0.0),
164 ),
165 #[cfg(feature = "free_camera")]
166 FreeCamera::default(),
167 ))
168 .insert(ShadowFilteringMethod::Gaussian)
169 // `TemporalJitter` is needed for TAA. Note that it does nothing without
170 // `TemporalAntiAliasSettings`.
171 .insert(TemporalJitter::default())
172 // We want MSAA off for TAA to work properly.
173 .insert(Msaa::Off)
174 // The depth prepass is needed for TAA.
175 .insert(DepthPrepass)
176 // The motion vector prepass is needed for TAA.
177 .insert(MotionVectorPrepass)
178 // Add a nice skybox.
179 .insert(Skybox {
180 image: Some(asset_server.load("environment_maps/sky_skybox.ktx2")),
181 brightness: 500.0,
182 rotation: Quat::IDENTITY,
183 });
184}100fn setup_basic_scene(mut commands: Commands, asset_server: Res<AssetServer>) {
101 // Main scene
102 commands.spawn((
103 WorldAssetRoot(asset_server.load(
104 GltfAssetLabel::Scene(0).from_asset("models/TonemappingTest/TonemappingTest.gltf"),
105 )),
106 SceneNumber(1),
107 ));
108
109 // Flight Helmet
110 commands.spawn((
111 WorldAssetRoot(
112 asset_server
113 .load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
114 ),
115 Transform::from_xyz(0.5, 0.0, -0.5).with_rotation(Quat::from_rotation_y(-0.15 * PI)),
116 SceneNumber(1),
117 ));
118
119 // light
120 commands.spawn((
121 DirectionalLight {
122 illuminance: 15_000.,
123 shadow_maps_enabled: true,
124 ..default()
125 },
126 Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, PI * -0.15, PI * -0.15)),
127 CascadeShadowConfigBuilder {
128 maximum_distance: 3.0,
129 first_cascade_far_bound: 0.9,
130 ..default()
131 }
132 .build(),
133 SceneNumber(1),
134 ));
135}61fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
62 // directional 'sun' light
63 commands.spawn((
64 DirectionalLight {
65 illuminance: 32000.0,
66 ..default()
67 },
68 Transform::from_xyz(0.0, 2.0, 0.0).with_rotation(Quat::from_rotation_x(-PI / 4.)),
69 ));
70
71 let skybox_handle = asset_server.load(CUBEMAPS[0].0);
72 // camera
73 commands.spawn((
74 Camera3d::default(),
75 Msaa::Off,
76 #[cfg(any(feature = "webgpu", not(target_arch = "wasm32")))]
77 TemporalAntiAliasing::default(),
78 ScreenSpaceAmbientOcclusion::default(),
79 Transform::from_xyz(0.0, 0.0, 8.0).looking_at(Vec3::ZERO, Vec3::Y),
80 FreeCamera::default(),
81 Skybox {
82 image: Some(skybox_handle.clone()),
83 brightness: 1000.0,
84 ..default()
85 },
86 ));
87
88 // ambient light
89 // NOTE: The ambient light is used to scale how bright the environment map is so with a bright
90 // environment map, use an appropriate color and brightness to match
91 commands.insert_resource(GlobalAmbientLight {
92 color: Color::srgb_u8(210, 220, 240),
93 brightness: 1.0,
94 ..default()
95 });
96
97 commands.insert_resource(Cubemap {
98 is_loaded: false,
99 index: 0,
100 image_handle: skybox_handle,
101 });
102}- examples/3d/mesh_ray_cast.rs
- examples/3d/light_probe_blending.rs
- examples/3d/atmosphere.rs
- examples/asset/generated_assets.rs
- examples/testbed/2d.rs
- examples/transforms/transform.rs
- examples/camera/free_camera_controller.rs
- examples/3d/rect_light.rs
- examples/3d/texture.rs
- examples/3d/motion_blur.rs
- examples/3d/decal.rs
- examples/picking/sprite_picking.rs
- examples/3d/render_to_texture.rs
- examples/3d/meshlet.rs
- examples/math/custom_primitives.rs
- examples/picking/mesh_picking.rs
- examples/3d/solari.rs
- examples/ui/render_ui_to_texture.rs
- examples/stress_tests/many_foxes.rs
- examples/3d/3d_shapes.rs
- examples/usage/debug_frustum_culling.rs
- examples/3d/transmission.rs
Sourcepub const fn with_scale(self, scale: Vec3) -> Transform
pub const fn with_scale(self, scale: Vec3) -> Transform
Returns this Transform with a new scale.
Examples found in repository?
More examples
12fn setup(
13 mut commands: Commands,
14 mut meshes: ResMut<Assets<Mesh>>,
15 mut materials: ResMut<Assets<ColorMaterial>>,
16) {
17 commands.spawn(Camera2d);
18
19 commands.spawn((
20 Mesh2d(meshes.add(Rectangle::default())),
21 MeshMaterial2d(materials.add(Color::from(PURPLE))),
22 Transform::default().with_scale(Vec3::splat(128.)),
23 ));
24}70fn setup_mesh(
71 mut commands: Commands,
72 mut meshes: ResMut<Assets<Mesh>>,
73 mut materials: ResMut<Assets<ColorMaterial>>,
74) {
75 commands.spawn((
76 Mesh2d(meshes.add(Capsule2d::default())),
77 MeshMaterial2d(materials.add(Color::BLACK)),
78 Transform::from_xyz(25., 0., 2.).with_scale(Vec3::splat(32.)),
79 Rotate,
80 PIXEL_PERFECT_LAYERS,
81 ));
82}25fn setup(
26 mut commands: Commands,
27 mut meshes: ResMut<Assets<Mesh>>,
28 mut materials: ResMut<Assets<CustomMaterial>>,
29 asset_server: Res<AssetServer>,
30) {
31 // camera
32 commands.spawn(Camera2d);
33
34 // quad
35 commands.spawn((
36 Mesh2d(meshes.add(Rectangle::default())),
37 MeshMaterial2d(materials.add(CustomMaterial {
38 color: LinearRgba::BLUE,
39 color_texture: Some(asset_server.load("branding/icon.png")),
40 })),
41 Transform::default().with_scale(Vec3::splat(128.)),
42 ));
43}- examples/shader_advanced/render_depth_to_texture.rs
- examples/stress_tests/bevymark.rs
- examples/2d/dynamic_mip_generation.rs
- examples/3d/rotate_environment_map.rs
- examples/3d/clearcoat.rs
- examples/testbed/3d.rs
- examples/2d/mesh2d_vertex_color_texture.rs
- examples/ecs/hierarchy.rs
- examples/3d/atmosphere.rs
- examples/testbed/2d.rs
- examples/3d/spherical_area_lights.rs
- examples/3d/motion_blur.rs
- examples/3d/light_textures.rs
- examples/camera/projection_zoom.rs
- examples/3d/clustered_decal_maps.rs
- examples/3d/bloom_3d.rs
- examples/picking/sprite_picking.rs
- examples/3d/scrolling_fog.rs
- examples/gizmos/3d_gizmos.rs
- examples/3d/meshlet.rs
- examples/showcase/breakout.rs
- examples/showcase/desk_toy.rs
- examples/stress_tests/many_foxes.rs
- examples/3d/solari.rs
- examples/3d/transmission.rs
Sourcepub fn to_matrix(&self) -> Mat4
pub fn to_matrix(&self) -> Mat4
Computes the 3d affine transformation matrix from this transform’s translation, rotation, and scale.
Examples found in repository?
341fn calculate_mirror_camera_transform_and_projection(
342 main_camera_transform: &Transform,
343 main_camera_projection: &PerspectiveProjection,
344 mirror_transform: &Transform,
345) -> (Transform, PerspectiveProjection) {
346 // Calculate the reflection matrix (a.k.a. Householder matrix) that will
347 // reflect the scene across the mirror plane.
348 //
349 // Note that you must calculate this in *matrix* form and only *afterward*
350 // convert to a `Transform` instead of composing `Transform`s. This is
351 // because the reflection matrix has non-uniform scale, and composing
352 // transforms can't always handle composition of matrices with non-uniform
353 // scales.
354 let mirror_camera_transform = Transform::from_matrix(
355 Mat4::from_mat3a(reflection_matrix(Vec3::NEG_Z)) * main_camera_transform.to_matrix(),
356 );
357
358 // Compute the distance from the camera to the mirror plane. This will be
359 // used to calculate the distance to the near clip plane for the mirror
360 // world.
361 let distance_from_camera_to_mirror = InfinitePlane3d::new(mirror_transform.rotation * Vec3::Y)
362 .signed_distance(
363 Isometry3d::IDENTITY,
364 mirror_transform.translation - main_camera_transform.translation,
365 );
366
367 // Compute the normal of the mirror plane in view space.
368 let view_from_world = main_camera_transform.compute_affine().matrix3.inverse();
369 let mirror_projection_plane_normal =
370 (view_from_world * (mirror_transform.rotation * Vec3::NEG_Y)).normalize();
371
372 // Compute the final projection. It should match the main camera projection,
373 // except that `near` and `near_normal` should be set to the updated near
374 // plane and near normal plane as above.
375 let mirror_camera_projection = PerspectiveProjection {
376 near_clip_plane: mirror_projection_plane_normal.extend(distance_from_camera_to_mirror),
377 ..*main_camera_projection
378 };
379
380 (mirror_camera_transform, mirror_camera_projection)
381}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.
Examples found in repository?
341fn calculate_mirror_camera_transform_and_projection(
342 main_camera_transform: &Transform,
343 main_camera_projection: &PerspectiveProjection,
344 mirror_transform: &Transform,
345) -> (Transform, PerspectiveProjection) {
346 // Calculate the reflection matrix (a.k.a. Householder matrix) that will
347 // reflect the scene across the mirror plane.
348 //
349 // Note that you must calculate this in *matrix* form and only *afterward*
350 // convert to a `Transform` instead of composing `Transform`s. This is
351 // because the reflection matrix has non-uniform scale, and composing
352 // transforms can't always handle composition of matrices with non-uniform
353 // scales.
354 let mirror_camera_transform = Transform::from_matrix(
355 Mat4::from_mat3a(reflection_matrix(Vec3::NEG_Z)) * main_camera_transform.to_matrix(),
356 );
357
358 // Compute the distance from the camera to the mirror plane. This will be
359 // used to calculate the distance to the near clip plane for the mirror
360 // world.
361 let distance_from_camera_to_mirror = InfinitePlane3d::new(mirror_transform.rotation * Vec3::Y)
362 .signed_distance(
363 Isometry3d::IDENTITY,
364 mirror_transform.translation - main_camera_transform.translation,
365 );
366
367 // Compute the normal of the mirror plane in view space.
368 let view_from_world = main_camera_transform.compute_affine().matrix3.inverse();
369 let mirror_projection_plane_normal =
370 (view_from_world * (mirror_transform.rotation * Vec3::NEG_Y)).normalize();
371
372 // Compute the final projection. It should match the main camera projection,
373 // except that `near` and `near_normal` should be set to the updated near
374 // plane and near normal plane as above.
375 let mirror_camera_projection = PerspectiveProjection {
376 near_clip_plane: mirror_projection_plane_normal.extend(distance_from_camera_to_mirror),
377 ..*main_camera_projection
378 };
379
380 (mirror_camera_transform, mirror_camera_projection)
381}Sourcepub fn left(&self) -> Dir3
pub fn left(&self) -> Dir3
Equivalent to -local_x()
Sourcepub fn local_y(&self) -> Dir3
pub fn local_y(&self) -> Dir3
Get the unit vector in the local Y direction.
Examples found in repository?
101fn rotate_cube(
102 mut cubes: Query<(&mut Transform, &mut CubeState), Without<Center>>,
103 center_spheres: Query<&Transform, With<Center>>,
104 timer: Res<Time>,
105) {
106 // Calculate the point to circle around. (The position of the center_sphere)
107 let mut center: Vec3 = Vec3::ZERO;
108 for sphere in ¢er_spheres {
109 center += sphere.translation;
110 }
111 // Update the rotation of the cube(s).
112 for (mut transform, cube) in &mut cubes {
113 // Calculate the rotation of the cube if it would be looking at the sphere in the center.
114 let look_at_sphere = transform.looking_at(center, *transform.local_y());
115 // Interpolate between the current rotation and the fully turned rotation
116 // when looking at the sphere, with a given turn speed to get a smooth motion.
117 // With higher speed the curvature of the orbit would be smaller.
118 let incremental_turn_weight = cube.turn_speed * timer.delta_secs();
119 let old_rotation = transform.rotation;
120 transform.rotation = old_rotation.lerp(look_at_sphere.rotation, incremental_turn_weight);
121 }
122}Sourcepub fn down(&self) -> Dir3
pub fn down(&self) -> Dir3
Equivalent to -local_y()
Sourcepub fn local_z(&self) -> Dir3
pub fn local_z(&self) -> Dir3
Get the unit vector in the local Z direction.
Examples found in repository?
634fn move_camera(
635 keyboard_input: Res<ButtonInput<KeyCode>>,
636 mut mouse_wheel_reader: MessageReader<MouseWheel>,
637 mut cameras: Query<&mut Transform, With<Camera>>,
638) {
639 let (mut distance_delta, mut theta_delta) = (0.0, 0.0);
640
641 // Handle keyboard events.
642 if keyboard_input.pressed(KeyCode::KeyW) {
643 distance_delta -= CAMERA_KEYBOARD_ZOOM_SPEED;
644 }
645 if keyboard_input.pressed(KeyCode::KeyS) {
646 distance_delta += CAMERA_KEYBOARD_ZOOM_SPEED;
647 }
648 if keyboard_input.pressed(KeyCode::KeyA) {
649 theta_delta += CAMERA_KEYBOARD_ORBIT_SPEED;
650 }
651 if keyboard_input.pressed(KeyCode::KeyD) {
652 theta_delta -= CAMERA_KEYBOARD_ORBIT_SPEED;
653 }
654
655 // Handle mouse events.
656 for mouse_wheel in mouse_wheel_reader.read() {
657 distance_delta -= mouse_wheel.y * CAMERA_MOUSE_WHEEL_ZOOM_SPEED;
658 }
659
660 // Update transforms.
661 for mut camera_transform in cameras.iter_mut() {
662 let local_z = camera_transform.local_z().as_vec3().normalize_or_zero();
663 if distance_delta != 0.0 {
664 camera_transform.translation = (camera_transform.translation.length() + distance_delta)
665 .clamp(CAMERA_ZOOM_RANGE.start, CAMERA_ZOOM_RANGE.end)
666 * local_z;
667 }
668 if theta_delta != 0.0 {
669 camera_transform
670 .translate_around(Vec3::ZERO, Quat::from_axis_angle(Vec3::Y, theta_delta));
671 camera_transform.look_at(Vec3::ZERO, Vec3::Y);
672 }
673 }
674}Sourcepub fn forward(&self) -> Dir3
pub fn forward(&self) -> Dir3
Equivalent to -local_z()
Examples found in repository?
More examples
137fn setup_color_gradient_scene(
138 mut commands: Commands,
139 mut meshes: ResMut<Assets<Mesh>>,
140 mut materials: ResMut<Assets<ColorGradientMaterial>>,
141 camera_transform: Res<CameraTransform>,
142) {
143 let mut transform = camera_transform.0;
144 transform.translation += *transform.forward();
145
146 commands.spawn((
147 Mesh3d(meshes.add(Rectangle::new(0.7, 0.7))),
148 MeshMaterial3d(materials.add(ColorGradientMaterial {})),
149 transform,
150 Visibility::Hidden,
151 SceneNumber(2),
152 ));
153}
154
155fn setup_image_viewer_scene(
156 mut commands: Commands,
157 mut meshes: ResMut<Assets<Mesh>>,
158 mut materials: ResMut<Assets<StandardMaterial>>,
159 camera_transform: Res<CameraTransform>,
160) {
161 let mut transform = camera_transform.0;
162 transform.translation += *transform.forward();
163
164 // exr/hdr viewer (exr requires enabling bevy feature)
165 commands.spawn((
166 Mesh3d(meshes.add(Rectangle::default())),
167 MeshMaterial3d(materials.add(StandardMaterial {
168 base_color_texture: None,
169 unlit: true,
170 ..default()
171 })),
172 transform,
173 Visibility::Hidden,
174 SceneNumber(3),
175 HDRViewer,
176 ));
177
178 commands.spawn((
179 Text::new("Drag and drop an HDR or EXR file"),
180 TextFont {
181 font_size: FontSize::Px(36.0),
182 ..default()
183 },
184 TextColor(Color::BLACK),
185 TextLayout::justify(Justify::Center),
186 Node {
187 align_self: AlignSelf::Center,
188 margin: UiRect::all(auto()),
189 ..default()
190 },
191 SceneNumber(3),
192 Visibility::Hidden,
193 ));
194}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}529fn move_camera_on_mouse_down(
530 mut main_cameras_query: Query<&mut Transform, (With<Camera>, Without<MirrorCamera>)>,
531 interactions_query: Query<&Interaction, With<RadioButton>>,
532 mouse_buttons: Res<ButtonInput<MouseButton>>,
533 mouse_motion: Res<AccumulatedMouseMotion>,
534 app_status: Res<AppStatus>,
535) {
536 // Only process the mouse motion if the left mouse button is pressed, the
537 // mouse action is set to move the fox, and the pointer isn't over a UI
538 // widget.
539 if app_status.drag_action != DragAction::MoveCamera
540 || !mouse_buttons.pressed(MouseButton::Left)
541 || interactions_query
542 .iter()
543 .any(|interaction| *interaction != Interaction::None)
544 {
545 return;
546 }
547
548 let delta = mouse_motion.delta;
549
550 // Mouse motion is one of the few inputs that should not be multiplied by delta time,
551 // as we are already receiving the full movement since the last frame was rendered. Multiplying
552 // by delta time here would make the movement slower that it should be.
553 let delta_pitch = delta.y * CAMERA_PITCH_SPEED;
554 let delta_yaw = delta.x * CAMERA_YAW_SPEED;
555
556 for mut main_camera_transform in &mut main_cameras_query {
557 // Obtain the existing pitch and yaw values from the transform.
558 let (yaw, pitch, _) = main_camera_transform.rotation.to_euler(EulerRot::YXZ);
559
560 // Establish the new yaw and pitch, preventing the pitch value from exceeding our limits.
561 let pitch = (pitch + delta_pitch).clamp(-CAMERA_PITCH_LIMIT, CAMERA_PITCH_LIMIT);
562 let yaw = yaw + delta_yaw;
563 main_camera_transform.rotation = Quat::from_euler(EulerRot::YXZ, yaw, pitch, 0.0);
564
565 // Adjust the translation to maintain the correct orientation toward the orbit target.
566 // In our example it's a static target, but this could easily be customized.
567 let target = Vec3::ZERO;
568 main_camera_transform.translation =
569 target - main_camera_transform.forward() * CAMERA_ORBIT_DISTANCE;
570 }
571}Sourcepub fn back(&self) -> Dir3
pub fn back(&self) -> Dir3
Equivalent to local_z()
Examples found in repository?
330fn move_camera(
331 camera: Single<(&mut Transform, &mut Projection), Without<CameraTracked>>,
332 tracked: Single<&Transform, With<CameraTracked>>,
333 mode: Res<CameraMode>,
334) {
335 let (mut transform, mut projection) = camera.into_inner();
336 match *mode {
337 CameraMode::Track => {
338 transform.look_at(tracked.translation, Vec3::Y);
339 transform.translation = Vec3::new(15.0, -0.5, 0.0);
340 if let Projection::Perspective(perspective) = &mut *projection {
341 perspective.fov = 0.05;
342 }
343 }
344 CameraMode::Chase => {
345 transform.translation =
346 tracked.translation + Vec3::new(0.0, 0.15, 0.0) + tracked.back() * 0.6;
347 transform.look_to(tracked.forward(), Vec3::Y);
348 if let Projection::Perspective(perspective) = &mut *projection {
349 perspective.fov = 1.0;
350 }
351 }
352 }
353}Sourcepub fn rotate(&mut self, rotation: Quat)
pub fn rotate(&mut self, rotation: Quat)
Rotates this Transform by the given rotation.
If this Transform has a parent, the rotation is relative to the rotation of the parent.
§Examples
Examples found in repository?
More examples
73fn update(
74 time: Res<Time>,
75 mut query: Query<(&MeshMaterial3d<CustomMaterial>, &mut Transform)>,
76 mut materials: ResMut<Assets<CustomMaterial>>,
77 keys: Res<ButtonInput<KeyCode>>,
78) {
79 for (material, mut transform) in query.iter_mut() {
80 let mut material = materials.get_mut(material).unwrap();
81 material.time.x = time.elapsed_secs();
82 if keys.just_pressed(KeyCode::Space) {
83 material.party_mode = !material.party_mode;
84 }
85
86 if material.party_mode {
87 transform.rotate(Quat::from_rotation_y(0.005));
88 }
89 }
90}594fn flicker_system(
595 mut flame: Single<&mut Transform, (With<Flicker>, With<Mesh3d>)>,
596 light: Single<(&mut PointLight, &mut Transform), (With<Flicker>, Without<Mesh3d>)>,
597 time: Res<Time>,
598) {
599 let s = time.elapsed_secs();
600 let a = ops::cos(s * 6.0) * 0.0125 + ops::cos(s * 4.0) * 0.025;
601 let b = ops::cos(s * 5.0) * 0.0125 + ops::cos(s * 3.0) * 0.025;
602 let c = ops::cos(s * 7.0) * 0.0125 + ops::cos(s * 2.0) * 0.025;
603 let (mut light, mut light_transform) = light.into_inner();
604 light.intensity = 4_000.0 + 3000.0 * (a + b + c);
605 flame.translation = Vec3::new(-1.0, 1.23, 0.0);
606 flame.look_at(Vec3::new(-1.0 - c, 1.7 - b, 0.0 - a), Vec3::X);
607 flame.rotate(Quat::from_euler(EulerRot::XYZ, 0.0, 0.0, PI / 2.0));
608 light_transform.translation = Vec3::new(-1.0 - c, 1.7, 0.0 - a);
609 flame.translation = Vec3::new(-1.0 - c, 1.23, 0.0 - a);
610}168fn move_directional_light(
169 input: Res<ButtonInput<KeyCode>>,
170 mut directional_lights: Query<&mut Transform, With<DirectionalLight>>,
171) {
172 let mut delta_theta = Vec2::ZERO;
173 if input.pressed(KeyCode::KeyW) || input.pressed(KeyCode::ArrowUp) {
174 delta_theta.y += DIRECTIONAL_LIGHT_MOVEMENT_SPEED;
175 }
176 if input.pressed(KeyCode::KeyS) || input.pressed(KeyCode::ArrowDown) {
177 delta_theta.y -= DIRECTIONAL_LIGHT_MOVEMENT_SPEED;
178 }
179 if input.pressed(KeyCode::KeyA) || input.pressed(KeyCode::ArrowLeft) {
180 delta_theta.x += DIRECTIONAL_LIGHT_MOVEMENT_SPEED;
181 }
182 if input.pressed(KeyCode::KeyD) || input.pressed(KeyCode::ArrowRight) {
183 delta_theta.x -= DIRECTIONAL_LIGHT_MOVEMENT_SPEED;
184 }
185
186 if delta_theta == Vec2::ZERO {
187 return;
188 }
189
190 let delta_quat = Quat::from_euler(EulerRot::XZY, delta_theta.y, 0.0, delta_theta.x);
191 for mut transform in directional_lights.iter_mut() {
192 transform.rotate(delta_quat);
193 }
194}Sourcepub fn rotate_axis(&mut self, axis: Dir3, angle: f32)
pub fn rotate_axis(&mut self, axis: Dir3, angle: f32)
Rotates this Transform around the given axis by angle (in radians).
If this Transform has a parent, the axis is relative to the rotation of the parent.
§Warning
If you pass in an axis based on the current rotation (e.g. obtained via Transform::local_x),
floating point errors can accumulate exponentially when applying rotations repeatedly this way. This will
result in a denormalized rotation. In this case, it is recommended to normalize the Transform::rotation after
each call to this method.
Examples found in repository?
136fn track_targets(
137 // `Single` ensures the system runs ONLY when exactly one matching entity exists.
138 mut player: Single<(&mut Transform, &Player)>,
139 // `Option<Single>` never prevents the system from running, but will be `None` if there is not exactly one matching entity.
140 enemy: Option<Single<&Transform, (With<Enemy>, Without<Player>)>>,
141 time: Res<Time>,
142) {
143 let (player_transform, player) = &mut *player;
144 if let Some(enemy_transform) = enemy {
145 // Enemy found, rotate and move towards it.
146 let delta = enemy_transform.translation - player_transform.translation;
147 let distance = delta.length();
148 let front = delta / distance;
149 let up = Vec3::Z;
150 let side = front.cross(up);
151 player_transform.rotation = Quat::from_mat3(&Mat3::from_cols(side, front, up));
152 let max_step = distance - player.min_follow_radius;
153 if 0.0 < max_step {
154 let velocity = (player.speed * time.delta_secs()).min(max_step);
155 player_transform.translation += front * velocity;
156 }
157 } else {
158 // 0 or multiple enemies found, keep searching.
159 player_transform.rotate_axis(Dir3::Z, player.rotation_speed * time.delta_secs());
160 }
161}Sourcepub fn rotate_x(&mut self, angle: f32)
pub fn rotate_x(&mut self, angle: f32)
Rotates this Transform around the X axis by angle (in radians).
If this Transform has a parent, the axis is relative to the rotation of the parent.
Examples found in repository?
More examples
110fn rotator_system(time: Res<Time>, mut query: Query<&mut Transform, With<FirstPassCube>>) {
111 for mut transform in &mut query {
112 transform.rotate_x(1.5 * time.delta_secs());
113 transform.rotate_z(1.3 * time.delta_secs());
114 }
115}
116
117/// Rotates the outer cube (main pass)
118fn cube_rotator_system(time: Res<Time>, mut query: Query<&mut Transform, With<MainPassCube>>) {
119 for mut transform in &mut query {
120 transform.rotate_x(1.0 * time.delta_secs());
121 transform.rotate_y(0.7 * time.delta_secs());
122 }
123}- examples/picking/debug_picking.rs
- examples/picking/simple_picking.rs
- examples/ui/render_ui_to_texture.rs
- examples/shader_advanced/render_depth_to_texture.rs
- examples/window/low_power.rs
- examples/ui/widgets/viewport_node.rs
- examples/3d/atmosphere.rs
- examples/stress_tests/many_cubes.rs
- examples/3d/generate_custom_mesh.rs
- examples/3d/lighting.rs
Sourcepub fn rotate_y(&mut self, angle: f32)
pub fn rotate_y(&mut self, angle: f32)
Rotates this Transform around the Y axis by angle (in radians).
If this Transform has a parent, the axis is relative to the rotation of the parent.
Examples found in repository?
More examples
186fn rotate(mut query: Query<&mut Transform, With<Shape>>, time: Res<Time>) {
187 for mut transform in &mut query {
188 transform.rotate_y(time.delta_secs() / 2.);
189 }
190}
191
192/// An observer to rotate an entity when it is dragged
193fn rotate_on_drag(drag: On<Pointer<Drag>>, mut transforms: Query<&mut Transform>) {
194 let mut transform = transforms.get_mut(drag.entity).unwrap();
195 transform.rotate_y(drag.delta.x * 0.02);
196 transform.rotate_x(drag.delta.y * 0.02);
197}- examples/stress_tests/many_cubes.rs
- examples/3d/render_to_texture.rs
- examples/picking/debug_picking.rs
- examples/picking/simple_picking.rs
- examples/ui/render_ui_to_texture.rs
- examples/3d/deferred_rendering.rs
- examples/shader_advanced/render_depth_to_texture.rs
- examples/ui/widgets/viewport_node.rs
- examples/showcase/alien_cake_addict.rs
- examples/stress_tests/many_foxes.rs
- examples/transforms/3d_rotation.rs
- examples/3d/clustered_decals.rs
- examples/3d/light_textures.rs
- examples/3d/generate_custom_mesh.rs
- examples/usage/debug_frustum_culling.rs
- examples/3d/contact_shadows.rs
- examples/3d/lighting.rs
Sourcepub fn rotate_z(&mut self, angle: f32)
pub fn rotate_z(&mut self, angle: f32)
Rotates this Transform around the Z axis by angle (in radians).
If this Transform has a parent, the axis is relative to the rotation of the parent.
Examples found in repository?
More examples
- examples/stress_tests/many_sprites.rs
- examples/showcase/contributors.rs
- examples/shader_advanced/render_depth_to_texture.rs
- examples/stress_tests/many_cubes.rs
- examples/stress_tests/many_text2d.rs
- examples/3d/generate_custom_mesh.rs
- examples/ecs/hierarchy.rs
- examples/2d/rotation.rs
- examples/camera/2d_screen_shake.rs
- examples/3d/lighting.rs
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?
634fn move_camera(
635 keyboard_input: Res<ButtonInput<KeyCode>>,
636 mut mouse_wheel_reader: MessageReader<MouseWheel>,
637 mut cameras: Query<&mut Transform, With<Camera>>,
638) {
639 let (mut distance_delta, mut theta_delta) = (0.0, 0.0);
640
641 // Handle keyboard events.
642 if keyboard_input.pressed(KeyCode::KeyW) {
643 distance_delta -= CAMERA_KEYBOARD_ZOOM_SPEED;
644 }
645 if keyboard_input.pressed(KeyCode::KeyS) {
646 distance_delta += CAMERA_KEYBOARD_ZOOM_SPEED;
647 }
648 if keyboard_input.pressed(KeyCode::KeyA) {
649 theta_delta += CAMERA_KEYBOARD_ORBIT_SPEED;
650 }
651 if keyboard_input.pressed(KeyCode::KeyD) {
652 theta_delta -= CAMERA_KEYBOARD_ORBIT_SPEED;
653 }
654
655 // Handle mouse events.
656 for mouse_wheel in mouse_wheel_reader.read() {
657 distance_delta -= mouse_wheel.y * CAMERA_MOUSE_WHEEL_ZOOM_SPEED;
658 }
659
660 // Update transforms.
661 for mut camera_transform in cameras.iter_mut() {
662 let local_z = camera_transform.local_z().as_vec3().normalize_or_zero();
663 if distance_delta != 0.0 {
664 camera_transform.translation = (camera_transform.translation.length() + distance_delta)
665 .clamp(CAMERA_ZOOM_RANGE.start, CAMERA_ZOOM_RANGE.end)
666 * local_z;
667 }
668 if theta_delta != 0.0 {
669 camera_transform
670 .translate_around(Vec3::ZERO, Quat::from_axis_angle(Vec3::Y, theta_delta));
671 camera_transform.look_at(Vec3::ZERO, Vec3::Y);
672 }
673 }
674}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
262fn rotate_light(
263 mut lights: Query<&mut Transform, With<LightContainer>>,
264 app_status: Res<AppStatus>,
265) {
266 if app_status.light_rotation != LightRotation::Rotating {
267 return;
268 }
269
270 for mut transform in lights.iter_mut() {
271 transform.rotate_around(Vec3::ZERO, Quat::from_rotation_y(LIGHT_ROTATION_SPEED));
272 }
273}188fn rotation(
189 mut transform: Single<&mut Transform, With<Camera>>,
190 input: Res<ButtonInput<KeyCode>>,
191 time: Res<Time>,
192) {
193 let delta = time.delta_secs();
194
195 if input.pressed(KeyCode::ArrowLeft) {
196 transform.rotate_around(Vec3::ZERO, Quat::from_rotation_y(delta));
197 } else if input.pressed(KeyCode::ArrowRight) {
198 transform.rotate_around(Vec3::ZERO, Quat::from_rotation_y(-delta));
199 }
200}191fn handle_mouse(
192 accumulated_mouse_motion: Res<AccumulatedMouseMotion>,
193 mut mouse_button_inputs: MessageReader<MouseButtonInput>,
194 mut camera_transform: Single<&mut Transform, With<Camera>>,
195 mut mouse_pressed: ResMut<MousePressed>,
196) {
197 // Store left-pressed state in the MousePressed resource
198 for mouse_button_input in mouse_button_inputs.read() {
199 if mouse_button_input.button != MouseButton::Left {
200 continue;
201 }
202 *mouse_pressed = MousePressed(mouse_button_input.state.is_pressed());
203 }
204
205 // If the mouse is not pressed, just ignore motion events
206 if !mouse_pressed.0 {
207 return;
208 }
209 if accumulated_mouse_motion.delta != Vec2::ZERO {
210 let displacement = accumulated_mouse_motion.delta.x;
211 camera_transform.rotate_around(Vec3::ZERO, Quat::from_rotation_y(-displacement / 75.));
212 }
213}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
targetis the same as the transform translation,Vec3::Zis used instead - if
upfails converting toDir3(e.g if it isVec3::ZERO),Dir3::Yis 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
243fn animate_light(
244 mut lights: Query<&mut Transform, Or<(With<PointLight>, With<DirectionalLight>)>>,
245 time: Res<Time>,
246) {
247 let now = time.elapsed_secs();
248 for mut transform in lights.iter_mut() {
249 transform.translation = vec3(
250 ops::sin(now * 1.4),
251 ops::cos(now * 1.0),
252 ops::cos(now * 0.6),
253 ) * vec3(3.0, 4.0, 3.0);
254 transform.look_at(Vec3::ZERO, Vec3::Y);
255 }
256}343fn rotate_camera(
344 time: Res<Time>,
345 mut camera_query: Query<&mut Transform, With<Camera3d>>,
346 app_status: Res<AppStatus>,
347) {
348 if !app_status.rotating {
349 return;
350 }
351
352 for mut transform in camera_query.iter_mut() {
353 transform.translation = Vec2::from_angle(time.delta_secs() * PI / 5.0)
354 .rotate(transform.translation.xz())
355 .extend(transform.translation.y)
356 .xzy();
357 transform.look_at(Vec3::ZERO, Vec3::Y);
358 }
359}349fn rotate_camera(
350 mut camera_query: Query<&mut Transform, With<Camera3d>>,
351 time: Res<Time>,
352 app_status: Res<AppStatus>,
353) {
354 if !app_status.rotating {
355 return;
356 }
357
358 for mut transform in camera_query.iter_mut() {
359 transform.translation = Vec2::from_angle(ROTATION_SPEED * time.delta_secs())
360 .rotate(transform.translation.xz())
361 .extend(transform.translation.y)
362 .xzy();
363 transform.look_at(Vec3::ZERO, Vec3::Y);
364 }
365}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
directionfails converting toDir3(e.g if it isVec3::ZERO),Dir3::NEG_Zis used instead - if
upfails converting toDir3,Dir3::Yis used instead - if
directionis parallel withup, an orthogonal vector is used as the “right” direction
Examples found in repository?
71fn input_handler(
72 keyboard_input: Res<ButtonInput<KeyCode>>,
73 mesh_query: Query<&Mesh3d, With<CustomUV>>,
74 mut meshes: ResMut<Assets<Mesh>>,
75 mut query: Query<&mut Transform, With<CustomUV>>,
76 time: Res<Time>,
77) {
78 if keyboard_input.just_pressed(KeyCode::Space) {
79 let mesh_handle = mesh_query.single().expect("Query not successful");
80 let mesh = meshes.get_mut(mesh_handle).unwrap();
81 toggle_texture(mesh.into_inner());
82 }
83 if keyboard_input.pressed(KeyCode::KeyX) {
84 for mut transform in &mut query {
85 transform.rotate_x(time.delta_secs() / 1.2);
86 }
87 }
88 if keyboard_input.pressed(KeyCode::KeyY) {
89 for mut transform in &mut query {
90 transform.rotate_y(time.delta_secs() / 1.2);
91 }
92 }
93 if keyboard_input.pressed(KeyCode::KeyZ) {
94 for mut transform in &mut query {
95 transform.rotate_z(time.delta_secs() / 1.2);
96 }
97 }
98 if keyboard_input.pressed(KeyCode::KeyR) {
99 for mut transform in &mut query {
100 transform.look_to(Vec3::NEG_Z, Vec3::Y);
101 }
102 }
103}More examples
300fn move_cars(
301 time: Res<Time>,
302 mut movables: Query<(&mut Transform, &Moves, &Children)>,
303 mut spins: Query<&mut Transform, (Without<Moves>, With<Rotates>)>,
304) {
305 for (mut transform, moves, children) in &mut movables {
306 let time = time.elapsed_secs() * 0.25;
307 let t = time + 0.5 * moves.0;
308 let dx = ops::cos(t);
309 let dz = -ops::sin(3.0 * t);
310 let speed_variation = (dx * dx + dz * dz).sqrt() * 0.15;
311 let t = t + speed_variation;
312 let prev = transform.translation;
313 transform.translation.x = race_track_pos(0.0, t).x;
314 transform.translation.z = race_track_pos(0.0, t).y;
315 transform.translation.y = -0.59;
316 let delta = transform.translation - prev;
317 transform.look_to(delta, Vec3::Y);
318 for child in children.iter() {
319 let Ok(mut wheel) = spins.get_mut(child) else {
320 continue;
321 };
322 let radius = wheel.scale.x;
323 let circumference = 2.0 * std::f32::consts::PI * radius;
324 let angle = delta.length() / circumference * std::f32::consts::PI * 2.0;
325 wheel.rotate_local_y(angle);
326 }
327 }
328}
329
330fn move_camera(
331 camera: Single<(&mut Transform, &mut Projection), Without<CameraTracked>>,
332 tracked: Single<&Transform, With<CameraTracked>>,
333 mode: Res<CameraMode>,
334) {
335 let (mut transform, mut projection) = camera.into_inner();
336 match *mode {
337 CameraMode::Track => {
338 transform.look_at(tracked.translation, Vec3::Y);
339 transform.translation = Vec3::new(15.0, -0.5, 0.0);
340 if let Projection::Perspective(perspective) = &mut *projection {
341 perspective.fov = 0.05;
342 }
343 }
344 CameraMode::Chase => {
345 transform.translation =
346 tracked.translation + Vec3::new(0.0, 0.15, 0.0) + tracked.back() * 0.6;
347 transform.look_to(tracked.forward(), Vec3::Y);
348 if let Projection::Perspective(perspective) = &mut *projection {
349 perspective.fov = 1.0;
350 }
351 }
352 }
353}Sourcepub fn align(
&mut self,
main_axis: impl TryInto<Dir3>,
main_direction: impl TryInto<Dir3>,
secondary_axis: impl TryInto<Dir3>,
secondary_direction: impl TryInto<Dir3>,
)
pub fn align( &mut self, main_axis: impl TryInto<Dir3>, main_direction: impl TryInto<Dir3>, secondary_axis: impl TryInto<Dir3>, secondary_direction: impl TryInto<Dir3>, )
Rotates this Transform so that the main_axis vector, reinterpreted in local coordinates, points
in the given main_direction, while secondary_axis points towards secondary_direction.
For example, if a spaceship model has its nose pointing in the X-direction in its own local coordinates
and its dorsal fin pointing in the Y-direction, then align(Dir3::X, v, Dir3::Y, w) will make the spaceship’s
nose point in the direction of v, while the dorsal fin does its best to point in the direction w.
More precisely, the Transform::rotation produced will be such that:
- applying it to
main_axisresults inmain_direction - applying it to
secondary_axisproduces a vector that lies in the half-plane generated bymain_directionandsecondary_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_axisormain_directionfail converting toDir3(e.g are zero),Dir3::Xtakes their place - if
secondary_axisorsecondary_directionfail converting,Dir3::Ytakes their place - if
main_axisis parallel withsecondary_axisormain_directionis parallel withsecondary_direction, a rotation is constructed which takesmain_axistomain_directionalong 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?
183fn spawn_quads(
184 commands: &mut Commands,
185 meshes: &mut Assets<Mesh>,
186 materials: &mut Assets<StandardMaterial>,
187) {
188 let quad_handle = meshes.add(Rectangle::new(3.0, 3.0).mesh());
189 let render_layers = RenderLayers::layer(1);
190 let xform = |x, y, z| {
191 Transform::from_rotation(Quat::from_rotation_y(0.5))
192 .mul_transform(Transform::from_xyz(x, y, z))
193 };
194 commands.spawn((
195 Mesh3d(quad_handle.clone()),
196 MeshMaterial3d(materials.add(StandardMaterial {
197 base_color: RED.with_alpha(0.5).into(),
198 alpha_mode: AlphaMode::Blend,
199 ..default()
200 })),
201 xform(1.0, -0.1, 0.),
202 render_layers.clone(),
203 ));
204 commands.spawn((
205 Mesh3d(quad_handle.clone()),
206 MeshMaterial3d(materials.add(StandardMaterial {
207 base_color: BLUE.with_alpha(0.8).into(),
208 alpha_mode: AlphaMode::Blend,
209 ..default()
210 })),
211 xform(0.5, 0.2, -0.5),
212 render_layers.clone(),
213 ));
214 commands.spawn((
215 Mesh3d(quad_handle.clone()),
216 MeshMaterial3d(materials.add(StandardMaterial {
217 base_color: GREEN.with_green(1.0).with_alpha(0.5).into(),
218 alpha_mode: AlphaMode::Blend,
219 ..default()
220 })),
221 xform(0.0, 0.4, -1.),
222 render_layers.clone(),
223 ));
224 commands.spawn((
225 Mesh3d(quad_handle.clone()),
226 MeshMaterial3d(materials.add(StandardMaterial {
227 base_color: YELLOW.with_alpha(0.3).into(),
228 alpha_mode: AlphaMode::Blend,
229 ..default()
230 })),
231 xform(-0.5, 0.6, -1.1),
232 render_layers.clone(),
233 ));
234 commands.spawn((
235 Mesh3d(quad_handle.clone()),
236 MeshMaterial3d(materials.add(StandardMaterial {
237 base_color: BLUE.with_alpha(0.2).into(),
238 alpha_mode: AlphaMode::Blend,
239 ..default()
240 })),
241 xform(-0.8, 0.8, -1.2),
242 render_layers.clone(),
243 ));
244}More examples
161fn setup(
162 mut commands: Commands,
163 args: Res<Args>,
164 mesh_assets: ResMut<Assets<Mesh>>,
165 material_assets: ResMut<Assets<StandardMaterial>>,
166 images: ResMut<Assets<Image>>,
167) {
168 warn!(include_str!("warning_string.txt"));
169
170 let args = args.into_inner();
171 let images = images.into_inner();
172 let material_assets = material_assets.into_inner();
173 let mesh_assets = mesh_assets.into_inner();
174
175 let meshes = init_meshes(args, mesh_assets);
176
177 let material_textures = init_textures(args, images);
178 let materials = init_materials(args, &material_textures, material_assets);
179
180 // We're seeding the PRNG here to make this example deterministic for testing purposes.
181 // This isn't strictly required in practical use unless you need your app to be deterministic.
182 let mut material_rng = ChaCha8Rng::seed_from_u64(42);
183 match args.layout {
184 Layout::Sphere => {
185 // NOTE: This pattern is good for testing performance of culling as it provides roughly
186 // the same number of visible meshes regardless of the viewing angle.
187 let n_points: usize = args.instance_count;
188 // NOTE: f64 is used to avoid precision issues that produce visual artifacts in the distribution
189 let radius = WIDTH as f64 * 2.5;
190 let golden_ratio = 0.5f64 * (1.0f64 + 5.0f64.sqrt());
191 for i in 0..n_points {
192 let spherical_polar_theta_phi =
193 fibonacci_spiral_on_sphere(golden_ratio, i, n_points);
194 let unit_sphere_p = spherical_polar_to_cartesian(spherical_polar_theta_phi);
195 let (mesh, transform) = meshes.choose(&mut material_rng).unwrap();
196 commands
197 .spawn((
198 Mesh3d(mesh.clone()),
199 MeshMaterial3d(materials.choose(&mut material_rng).unwrap().clone()),
200 Transform::from_translation((radius * unit_sphere_p).as_vec3())
201 .looking_at(Vec3::ZERO, Vec3::Y)
202 .mul_transform(*transform),
203 ))
204 .insert_if(NoFrustumCulling, || args.no_frustum_culling)
205 .insert_if(NoAutomaticBatching, || args.no_automatic_batching)
206 .insert_if(NoCpuCulling, || args.no_cpu_culling);
207 }
208
209 // camera
210 let mut camera = commands.spawn(Camera3d::default());
211 if args.no_indirect_drawing {
212 camera.insert(NoIndirectDrawing);
213 }
214 if args.no_cpu_culling {
215 camera.insert(NoCpuCulling);
216 }
217 if args.motion_blur {
218 camera.insert((
219 MotionBlur {
220 // Use an unrealistically large shutter angle so that motion blur is clearly visible.
221 shutter_angle: 3.0,
222 ..Default::default()
223 },
224 // MSAA and MotionBlur are not compatible on WebGL.
225 #[cfg(all(
226 feature = "webgl2",
227 target_arch = "wasm32",
228 not(feature = "webgpu")
229 ))]
230 Msaa::Off,
231 ));
232 }
233
234 // Inside-out box around the meshes onto which shadows are cast (though you cannot see them...)
235 commands.spawn((
236 Mesh3d(mesh_assets.add(Cuboid::from_size(Vec3::splat(radius as f32 * 2.2)))),
237 MeshMaterial3d(material_assets.add(StandardMaterial::from(Color::WHITE))),
238 Transform::from_scale(-Vec3::ONE),
239 NotShadowCaster,
240 ));
241 }
242 Layout::Cube => {
243 // NOTE: This pattern is good for demonstrating that frustum culling is working correctly
244 // as the number of visible meshes rises and falls depending on the viewing angle.
245 let scale = 2.5;
246
247 // Scale the width and height by the same factor so that we have the
248 // right number of instances.
249 // Because of the moiré pattern check and the fact that we're
250 // spawning 4 instances per trip around the inner loop below, we're
251 // solving the following equation for the factor variable:
252 //
253 // 4 * (9/10 * factor * width * 9/10 * factor * height) = count
254 //
255 // The solution is the value below.
256 let factor = (5.0 / 9.0) * sqrt(args.instance_count as f32)
257 / (sqrt(HEIGHT as f32) * sqrt(WIDTH as f32));
258 let dimensions = (vec2(WIDTH as f32, HEIGHT as f32) * factor)
259 .ceil()
260 .as_uvec2();
261
262 for x in 0..dimensions.x {
263 for y in 0..dimensions.y {
264 // introduce spaces to break any kind of moiré pattern
265 if x % 10 == 0 || y % 10 == 0 {
266 continue;
267 }
268 // cube
269 commands
270 .spawn((
271 Mesh3d(meshes.choose(&mut material_rng).unwrap().0.clone()),
272 MeshMaterial3d(materials.choose(&mut material_rng).unwrap().clone()),
273 Transform::from_xyz((x as f32) * scale, (y as f32) * scale, 0.0),
274 ))
275 .insert_if(NoCpuCulling, || args.no_cpu_culling);
276 commands
277 .spawn((
278 Mesh3d(meshes.choose(&mut material_rng).unwrap().0.clone()),
279 MeshMaterial3d(materials.choose(&mut material_rng).unwrap().clone()),
280 Transform::from_xyz(
281 (x as f32) * scale,
282 dimensions.y as f32 * scale,
283 (y as f32) * scale,
284 ),
285 ))
286 .insert_if(NoCpuCulling, || args.no_cpu_culling);
287 commands
288 .spawn((
289 Mesh3d(meshes.choose(&mut material_rng).unwrap().0.clone()),
290 MeshMaterial3d(materials.choose(&mut material_rng).unwrap().clone()),
291 Transform::from_xyz((x as f32) * scale, 0.0, (y as f32) * scale),
292 ))
293 .insert_if(NoCpuCulling, || args.no_cpu_culling);
294 commands
295 .spawn((
296 Mesh3d(meshes.choose(&mut material_rng).unwrap().0.clone()),
297 MeshMaterial3d(materials.choose(&mut material_rng).unwrap().clone()),
298 Transform::from_xyz(0.0, (x as f32) * scale, (y as f32) * scale),
299 ))
300 .insert_if(NoCpuCulling, || args.no_cpu_culling);
301 }
302 }
303 // camera
304 let center = 0.5
305 * scale
306 * Vec3::new(
307 dimensions.x as f32,
308 dimensions.y as f32,
309 dimensions.x as f32,
310 );
311 commands.spawn((Camera3d::default(), Transform::from_translation(center)));
312 // Inside-out box around the meshes onto which shadows are cast (though you cannot see them...)
313 commands.spawn((
314 Mesh3d(mesh_assets.add(Cuboid::from_size(2.0 * 1.1 * center))),
315 MeshMaterial3d(material_assets.add(StandardMaterial::from(Color::WHITE))),
316 Transform::from_scale(-Vec3::ONE).with_translation(center),
317 NotShadowCaster,
318 ));
319 }
320 Layout::Dense => {
321 // NOTE: This pattern is good for demonstrating a dense configuration of cubes
322 // overlapping each other, all within the camera frustum.
323 let count = args.instance_count;
324 let size = cbrt(count as f32).round();
325 let gap = 1.25;
326
327 for i in 0..count {
328 let x = i as f32 % size;
329 let y = (i as f32 / size) % size;
330 let z = i as f32 / (size * size);
331 let pos = Vec3::new(x * gap, y * gap, z * gap);
332 commands
333 .spawn((
334 Mesh3d(meshes.choose(&mut material_rng).unwrap().0.clone()),
335 MeshMaterial3d(materials.choose(&mut material_rng).unwrap().clone()),
336 Transform::from_translation(pos),
337 ))
338 .insert_if(NoCpuCulling, || args.no_cpu_culling);
339 }
340
341 // camera
342 commands.spawn((
343 Camera3d::default(),
344 Transform::from_xyz(100.0, 90.0, 100.0)
345 .looking_at(Vec3::new(0.0, -10.0, 0.0), Vec3::Y),
346 ));
347 }
348 }
349
350 commands.spawn((
351 DirectionalLight {
352 shadow_maps_enabled: args.shadows,
353 ..default()
354 },
355 Transform::IDENTITY.looking_at(Vec3::new(0.0, -1.0, -1.0), Vec3::Y),
356 ));
357}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?
322fn bounding_shapes_3d(
323 shapes: Query<&Transform, With<Shape3d>>,
324 mut gizmos: Gizmos,
325 bounding_shape: Res<State<BoundingShape>>,
326) {
327 for transform in shapes.iter() {
328 match bounding_shape.get() {
329 BoundingShape::None => (),
330 BoundingShape::BoundingBox => {
331 // Get the AABB of the extrusion with the rotation and translation of the mesh.
332 let aabb = EXTRUSION.aabb_3d(transform.to_isometry());
333
334 gizmos.primitive_3d(
335 &Cuboid::from_size(Vec3::from(aabb.half_size()) * 2.),
336 aabb.center(),
337 WHITE,
338 );
339 }
340 BoundingShape::BoundingSphere => {
341 // Get the bounding sphere of the extrusion with the rotation and translation of the mesh.
342 let bounding_sphere = EXTRUSION.bounding_sphere(transform.to_isometry());
343
344 gizmos.sphere(bounding_sphere.center(), bounding_sphere.radius(), WHITE);
345 }
346 }
347 }
348}Trait Implementations§
Source§impl Animatable for Transform
impl Animatable for Transform
Source§impl Component for Transform
Required Components: GlobalTransform, TransformTreeChanged.
impl Component for Transform
Required Components: GlobalTransform, TransformTreeChanged.
A component’s Required Components are inserted whenever it is inserted. Note that this will also insert the required components of the required components, recursively, in depth-first order.
Source§const STORAGE_TYPE: StorageType = bevy_ecs::component::StorageType::Table
const STORAGE_TYPE: StorageType = bevy_ecs::component::StorageType::Table
Source§type Mutability = Mutable
type Mutability = Mutable
Component<Mutability = Mutable>,
while immutable components will instead have Component<Mutability = Immutable>. Read moreSource§fn register_required_components(
_requiree: ComponentId,
required_components: &mut RequiredComponentsRegistrator<'_, '_>,
)
fn register_required_components( _requiree: ComponentId, required_components: &mut RequiredComponentsRegistrator<'_, '_>, )
Source§fn clone_behavior() -> ComponentCloneBehavior
fn clone_behavior() -> ComponentCloneBehavior
Source§fn relationship_accessor() -> Option<ComponentRelationshipAccessor<Transform>>
fn relationship_accessor() -> Option<ComponentRelationshipAccessor<Transform>>
ComponentRelationshipAccessor required for working with relationships in dynamic contexts. Read moreSource§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_discard() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
fn on_discard() -> 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 moreimpl Copy for Transform
Source§impl<'de> Deserialize<'de> for Transform
impl<'de> Deserialize<'de> for Transform
Source§fn deserialize<__D>(
__deserializer: __D,
) -> Result<Transform, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(
__deserializer: __D,
) -> Result<Transform, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
Source§impl From<GlobalTransform> for Transform
The transform is expected to be non-degenerate and without shearing, or the output
will be invalid.
impl From<GlobalTransform> for Transform
The transform is expected to be non-degenerate and without shearing, or the output will be invalid.
Source§fn from(transform: GlobalTransform) -> Transform
fn from(transform: GlobalTransform) -> Transform
Source§impl From<Transform> for GlobalTransform
impl From<Transform> for GlobalTransform
Source§fn from(transform: Transform) -> GlobalTransform
fn from(transform: Transform) -> GlobalTransform
Source§impl FromReflect for Transform
impl FromReflect for Transform
Source§fn from_reflect(reflect: &(dyn PartialReflect + 'static)) -> Option<Transform>
fn from_reflect(reflect: &(dyn PartialReflect + 'static)) -> Option<Transform>
Self from a reflected value.Source§fn take_from_reflect(
reflect: Box<dyn PartialReflect>,
) -> Result<Self, Box<dyn PartialReflect>>
fn take_from_reflect( reflect: Box<dyn PartialReflect>, ) -> Result<Self, Box<dyn PartialReflect>>
Self using,
constructing the value using from_reflect if that fails. Read moreSource§impl GetOwnership for Transform
impl GetOwnership for Transform
Source§impl GetTypeRegistration for Transform
impl GetTypeRegistration for Transform
Source§fn get_type_registration() -> TypeRegistration
fn get_type_registration() -> TypeRegistration
TypeRegistration for this type.Source§fn register_type_dependencies(registry: &mut TypeRegistry)
fn register_type_dependencies(registry: &mut TypeRegistry)
Source§impl IntoReturn for Transform
impl IntoReturn for Transform
Source§impl Mul<GlobalTransform> for Transform
impl Mul<GlobalTransform> for Transform
Source§type Output = GlobalTransform
type Output = GlobalTransform
* operator.Source§fn mul(
self,
global_transform: GlobalTransform,
) -> <Transform as Mul<GlobalTransform>>::Output
fn mul( self, global_transform: GlobalTransform, ) -> <Transform as Mul<GlobalTransform>>::Output
* operation. Read moreSource§impl Mul<Transform> for GlobalTransform
impl Mul<Transform> for GlobalTransform
Source§impl PartialReflect for Transform
impl PartialReflect for Transform
Source§fn get_represented_type_info(&self) -> Option<&'static TypeInfo>
fn get_represented_type_info(&self) -> Option<&'static TypeInfo>
Source§fn try_apply(
&mut self,
value: &(dyn PartialReflect + 'static),
) -> Result<(), ApplyError>
fn try_apply( &mut self, value: &(dyn PartialReflect + 'static), ) -> Result<(), ApplyError>
Source§fn reflect_kind(&self) -> ReflectKind
fn reflect_kind(&self) -> ReflectKind
Source§fn reflect_ref(&self) -> ReflectRef<'_>
fn reflect_ref(&self) -> ReflectRef<'_>
Source§fn reflect_mut(&mut self) -> ReflectMut<'_>
fn reflect_mut(&mut self) -> ReflectMut<'_>
Source§fn reflect_owned(self: Box<Transform>) -> ReflectOwned
fn reflect_owned(self: Box<Transform>) -> ReflectOwned
Source§fn try_into_reflect(
self: Box<Transform>,
) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>>
fn try_into_reflect( self: Box<Transform>, ) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>>
Source§fn try_as_reflect(&self) -> Option<&(dyn Reflect + 'static)>
fn try_as_reflect(&self) -> Option<&(dyn Reflect + 'static)>
Source§fn try_as_reflect_mut(&mut self) -> Option<&mut (dyn Reflect + 'static)>
fn try_as_reflect_mut(&mut self) -> Option<&mut (dyn Reflect + 'static)>
Source§fn into_partial_reflect(self: Box<Transform>) -> Box<dyn PartialReflect>
fn into_partial_reflect(self: Box<Transform>) -> Box<dyn PartialReflect>
Source§fn as_partial_reflect(&self) -> &(dyn PartialReflect + 'static)
fn as_partial_reflect(&self) -> &(dyn PartialReflect + 'static)
Source§fn as_partial_reflect_mut(&mut self) -> &mut (dyn PartialReflect + 'static)
fn as_partial_reflect_mut(&mut self) -> &mut (dyn PartialReflect + 'static)
Source§fn reflect_partial_eq(
&self,
value: &(dyn PartialReflect + 'static),
) -> Option<bool>
fn reflect_partial_eq( &self, value: &(dyn PartialReflect + 'static), ) -> Option<bool>
Source§fn reflect_partial_cmp(
&self,
value: &(dyn PartialReflect + 'static),
) -> Option<Ordering>
fn reflect_partial_cmp( &self, value: &(dyn PartialReflect + 'static), ) -> Option<Ordering>
Source§fn debug(&self, f: &mut Formatter<'_>) -> Result<(), Error>
fn debug(&self, f: &mut Formatter<'_>) -> Result<(), Error>
Source§fn reflect_clone(&self) -> Result<Box<dyn Reflect>, ReflectCloneError>
fn reflect_clone(&self) -> Result<Box<dyn Reflect>, ReflectCloneError>
Self using reflection. Read moreSource§fn apply(&mut self, value: &(dyn PartialReflect + 'static))
fn apply(&mut self, value: &(dyn PartialReflect + 'static))
Source§fn to_dynamic(&self) -> Box<dyn PartialReflect>
fn to_dynamic(&self) -> Box<dyn PartialReflect>
Source§fn reflect_clone_and_take<T>(&self) -> Result<T, ReflectCloneError>
fn reflect_clone_and_take<T>(&self) -> Result<T, ReflectCloneError>
PartialReflect, combines reflect_clone and
take in a useful fashion, automatically constructing an appropriate
ReflectCloneError if the downcast fails.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 Transform
impl Reflect for Transform
Source§fn into_any(self: Box<Transform>) -> Box<dyn Any>
fn into_any(self: Box<Transform>) -> Box<dyn Any>
Box<dyn Any>. Read moreSource§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut dyn Any. Read moreSource§fn into_reflect(self: Box<Transform>) -> Box<dyn Reflect>
fn into_reflect(self: Box<Transform>) -> Box<dyn Reflect>
Source§fn as_reflect(&self) -> &(dyn Reflect + 'static)
fn as_reflect(&self) -> &(dyn Reflect + 'static)
Source§fn as_reflect_mut(&mut self) -> &mut (dyn Reflect + 'static)
fn as_reflect_mut(&mut self) -> &mut (dyn Reflect + 'static)
Source§impl Serialize for Transform
impl Serialize for Transform
Source§fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
Source§impl Struct for Transform
impl Struct for Transform
Source§fn field(&self, name: &str) -> Option<&(dyn PartialReflect + 'static)>
fn field(&self, name: &str) -> Option<&(dyn PartialReflect + 'static)>
name as a &dyn PartialReflect.Source§fn field_mut(
&mut self,
name: &str,
) -> Option<&mut (dyn PartialReflect + 'static)>
fn field_mut( &mut self, name: &str, ) -> Option<&mut (dyn PartialReflect + 'static)>
name as a
&mut dyn PartialReflect.Source§fn field_at(&self, index: usize) -> Option<&(dyn PartialReflect + 'static)>
fn field_at(&self, index: usize) -> Option<&(dyn PartialReflect + 'static)>
index as a
&dyn PartialReflect.Source§fn field_at_mut(
&mut self,
index: usize,
) -> Option<&mut (dyn PartialReflect + 'static)>
fn field_at_mut( &mut self, index: usize, ) -> Option<&mut (dyn PartialReflect + 'static)>
index
as a &mut dyn PartialReflect.Source§fn index_of_name(&self, name: &str) -> Option<usize>
fn index_of_name(&self, name: &str) -> Option<usize>
Source§fn iter_fields(&self) -> FieldIter<'_> ⓘ
fn iter_fields(&self) -> FieldIter<'_> ⓘ
Source§fn to_dynamic_struct(&self) -> DynamicStruct
fn to_dynamic_struct(&self) -> DynamicStruct
DynamicStruct from this struct.Source§fn get_represented_struct_info(&self) -> Option<&'static StructInfo>
fn get_represented_struct_info(&self) -> Option<&'static StructInfo>
None if TypeInfo is not available.impl StructuralPartialEq for Transform
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>
Auto Trait Implementations§
impl Freeze for Transform
impl RefUnwindSafe for Transform
impl Send for Transform
impl Sync for Transform
impl Unpin for Transform
impl UnsafeUnpin 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
impl<T> Brush for T
Source§impl<C> Bundle for Cwhere
C: Component,
impl<C> Bundle for Cwhere
C: Component,
fn component_ids( components: &mut ComponentsRegistrator<'_>, ) -> impl Iterator<Item = ComponentId> + use<C>
Source§fn get_component_ids(
components: &Components,
) -> impl Iterator<Item = Option<ComponentId>>
fn get_component_ids( components: &Components, ) -> impl Iterator<Item = Option<ComponentId>>
Source§impl<C> BundleFromComponents for Cwhere
C: Component,
impl<C> BundleFromComponents for Cwhere
C: Component,
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> ConditionalSend for Twhere
T: Send,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
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
impl<S, T> Duplex<S> for Twhere
T: FromSample<S> + ToSample<S>,
Source§impl<C> DynamicBundle for Cwhere
C: Component,
impl<C> DynamicBundle for Cwhere
C: Component,
Source§unsafe fn get_components(
ptr: MovingPtr<'_, C>,
func: &mut impl FnMut(StorageType, OwningPtr<'_>),
) -> <C as DynamicBundle>::Effect
unsafe fn get_components( ptr: MovingPtr<'_, C>, func: &mut impl FnMut(StorageType, OwningPtr<'_>), ) -> <C as DynamicBundle>::Effect
Source§unsafe fn apply_effect(
_ptr: MovingPtr<'_, MaybeUninit<C>>,
_entity: &mut EntityWorldMut<'_>,
)
unsafe fn apply_effect( _ptr: MovingPtr<'_, MaybeUninit<C>>, _entity: &mut EntityWorldMut<'_>, )
Source§impl<T> DynamicTypePath for Twhere
T: TypePath,
impl<T> DynamicTypePath for Twhere
T: TypePath,
Source§fn reflect_type_path(&self) -> &str
fn reflect_type_path(&self) -> &str
TypePath::type_path.Source§fn reflect_short_type_path(&self) -> &str
fn reflect_short_type_path(&self) -> &str
Source§fn reflect_type_ident(&self) -> Option<&str>
fn reflect_type_ident(&self) -> Option<&str>
TypePath::type_ident.Source§fn reflect_crate_name(&self) -> Option<&str>
fn reflect_crate_name(&self) -> Option<&str>
TypePath::crate_name.Source§fn reflect_module_path(&self) -> Option<&str>
fn reflect_module_path(&self) -> Option<&str>
Source§impl<T> DynamicTyped for Twhere
T: Typed,
impl<T> DynamicTyped for Twhere
T: Typed,
Source§fn reflect_type_info(&self) -> &'static TypeInfo
fn reflect_type_info(&self) -> &'static TypeInfo
Typed::type_info.Source§impl<T> ErasedBundleTemplate for T
impl<T> ErasedBundleTemplate for T
Source§unsafe fn apply(
&self,
context: &mut TemplateContext<'_, '_>,
) -> Result<(), BevyError>
unsafe fn apply( &self, context: &mut TemplateContext<'_, '_>, ) -> Result<(), BevyError>
entity. Read moreSource§fn clone_template(&self) -> Box<dyn ErasedBundleTemplate>
fn clone_template(&self) -> Box<dyn ErasedBundleTemplate>
Clone.Source§impl<T> ErasedComponentTemplate for T
impl<T> ErasedComponentTemplate for T
Source§unsafe fn apply(
&self,
context: &mut TemplateContext<'_, '_>,
bundle_writer: &mut BundleWriter<'_>,
) -> Result<(), BevyError>
unsafe fn apply( &self, context: &mut TemplateContext<'_, '_>, bundle_writer: &mut BundleWriter<'_>, ) -> Result<(), BevyError>
entity. Read moreSource§fn clone_template(&self) -> Box<dyn ErasedComponentTemplate>
fn clone_template(&self) -> Box<dyn ErasedComponentTemplate>
Clone.impl<T> ErasedDestructor for Twhere
T: 'static,
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> FromTemplate for T
impl<T> FromTemplate for T
Source§impl<T> FromWorld for Twhere
T: Default,
impl<T> FromWorld for Twhere
T: Default,
Source§fn from_world(_world: &mut World) -> T
fn from_world(_world: &mut World) -> T
Creates Self using default().
Source§impl<S> GetField for Swhere
S: Struct,
impl<S> GetField for Swhere
S: Struct,
Source§impl<T> GetPath for T
impl<T> GetPath for T
Source§fn reflect_path<'p>(
&self,
path: impl ReflectPath<'p>,
) -> Result<&(dyn PartialReflect + 'static), ReflectPathError<'p>>
fn reflect_path<'p>( &self, path: impl ReflectPath<'p>, ) -> Result<&(dyn PartialReflect + 'static), ReflectPathError<'p>>
path. Read moreSource§fn reflect_path_mut<'p>(
&mut self,
path: impl ReflectPath<'p>,
) -> Result<&mut (dyn PartialReflect + 'static), ReflectPathError<'p>>
fn reflect_path_mut<'p>( &mut self, path: impl ReflectPath<'p>, ) -> Result<&mut (dyn PartialReflect + 'static), ReflectPathError<'p>>
path. Read moreSource§fn path<'p, T>(
&self,
path: impl ReflectPath<'p>,
) -> Result<&T, ReflectPathError<'p>>where
T: Reflect,
fn path<'p, T>(
&self,
path: impl ReflectPath<'p>,
) -> Result<&T, ReflectPathError<'p>>where
T: Reflect,
path. Read moreSource§fn path_mut<'p, T>(
&mut self,
path: impl ReflectPath<'p>,
) -> Result<&mut T, ReflectPathError<'p>>where
T: Reflect,
fn path_mut<'p, T>(
&mut self,
path: impl ReflectPath<'p>,
) -> Result<&mut T, ReflectPathError<'p>>where
T: Reflect,
path. Read moreSource§impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
impl<T> HitDataExtra for T
Source§impl<T> Identity for Twhere
T: ?Sized,
impl<T> Identity for Twhere
T: ?Sized,
Source§impl<T> InitializeFromFunction<T> for T
impl<T> InitializeFromFunction<T> for T
Source§fn initialize_from_function(f: fn() -> T) -> T
fn initialize_from_function(f: fn() -> T) -> T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoResult<T> for T
impl<T> IntoResult<T> for T
Source§fn into_result(self) -> Result<T, RunSystemError>
fn into_result(self) -> Result<T, RunSystemError>
Source§impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
fn into_sample(self) -> T
Source§impl<G> PatchFromTemplate for Gwhere
G: FromTemplate,
impl<G> PatchFromTemplate for Gwhere
G: FromTemplate,
Source§fn patch<F>(func: F) -> TemplatePatch<F, <G as PatchFromTemplate>::Template>
fn patch<F>(func: F) -> TemplatePatch<F, <G as PatchFromTemplate>::Template>
func, and turns it into a TemplatePatch.Source§impl<T> PatchTemplate for Twhere
T: Template,
impl<T> PatchTemplate for Twhere
T: Template,
Source§fn patch_template<F>(func: F) -> TemplatePatch<F, T>
fn patch_template<F>(func: F) -> TemplatePatch<F, 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.impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
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().impl<T> Reflectable for T
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>
impl<T> Settings for T
Source§impl<Ret> SpawnIfAsync<(), Ret> for Ret
impl<Ret> SpawnIfAsync<(), Ret> for Ret
Source§impl<T, O> SuperFrom<T> for Owhere
O: From<T>,
impl<T, O> SuperFrom<T> for Owhere
O: From<T>,
Source§fn super_from(input: T) -> O
fn super_from(input: T) -> O
Source§impl<T, O, M> SuperInto<O, M> for Twhere
O: SuperFrom<T, M>,
impl<T, O, M> SuperInto<O, M> for Twhere
O: SuperFrom<T, M>,
Source§fn super_into(self) -> O
fn super_into(self) -> O
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.Source§impl<T> Template for T
impl<T> Template for T
Source§fn build_template(
&self,
_context: &mut TemplateContext<'_, '_>,
) -> Result<<T as Template>::Output, BevyError>
fn build_template( &self, _context: &mut TemplateContext<'_, '_>, ) -> Result<<T as Template>::Output, BevyError>
entity context to produce a Template::Output.Source§fn clone_template(&self) -> T
fn clone_template(&self) -> T
Clone.