From cf66df1d0d8e8ddc7717f830e946623100412b8a Mon Sep 17 00:00:00 2001 From: Chris Biscardi Date: Wed, 19 Jun 2024 17:58:00 -0700 Subject: [PATCH] Use a ship in Transform::align example (#13935) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Objective The documentation for [`Transform::align`](https://docs.rs/bevy/0.14.0-rc.3/bevy/transform/components/struct.Transform.html#method.align) mentions a hypothetical ship model. Showing this concretely would be a nice improvement over using a cube. > 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. ## Solution This commit makes the ship less hypothetical by using a kenney ship model in the example. The local axes for the ship needed to change to accommodate the gltf, so the hypothetical in the documentation and this example's local axes don't necessarily match. Docs use `align(Dir3::X, v, Dir3::Y, w)` and this example now uses `(Vec3::NEG_Z, *first, Vec3::X, *second)`. I manually modified the `craft_speederD` Node's `translation` to be 0,0,0 in the gltf file, which means it now differs from kenney's original model. Original ship from: https://kenney.nl/assets/space-kit ## Testing ``` cargo run --example align ``` ![screenshot-2024-06-19-at-14 27 05@2x](https://github.com/bevyengine/bevy/assets/551247/ab1afc8f-76b2-42b6-b455-f0d1c77cfed7) ![screenshot-2024-06-19-at-14 27 12@2x](https://github.com/bevyengine/bevy/assets/551247/4a01031c-4ea1-43ab-8078-3656db67efe0) ![screenshot-2024-06-19-at-14 27 20@2x](https://github.com/bevyengine/bevy/assets/551247/06830f38-ba2b-4e3a-a265-2d10f9ea9de9) --- assets/models/ship/craft_speederD.gltf | 288 +++++++++++++++++++++ assets/models/ship/craft_speederD_data.bin | Bin 0 -> 20120 bytes examples/transforms/align.rs | 89 +++---- 3 files changed, 333 insertions(+), 44 deletions(-) create mode 100644 assets/models/ship/craft_speederD.gltf create mode 100644 assets/models/ship/craft_speederD_data.bin diff --git a/assets/models/ship/craft_speederD.gltf b/assets/models/ship/craft_speederD.gltf new file mode 100644 index 0000000000..c20e240592 --- /dev/null +++ b/assets/models/ship/craft_speederD.gltf @@ -0,0 +1,288 @@ +{ + "extensionsUsed": [ + "KHR_materials_unlit" + ], + "asset": { + "generator": "UniGLTF-1.27", + "version": "2.0" + }, + "buffers": [ + { + "uri": "craft_speederD_data.bin", + "byteLength": 20120 + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteOffset": 0, + "byteLength": 6096, + "target": 34962 + }, + { + "buffer": 0, + "byteOffset": 6096, + "byteLength": 6096, + "target": 34962 + }, + { + "buffer": 0, + "byteOffset": 12192, + "byteLength": 4064, + "target": 34962 + }, + { + "buffer": 0, + "byteOffset": 16256, + "byteLength": 732, + "target": 34963 + }, + { + "buffer": 0, + "byteOffset": 16988, + "byteLength": 1368, + "target": 34963 + }, + { + "buffer": 0, + "byteOffset": 18356, + "byteLength": 456, + "target": 34963 + }, + { + "buffer": 0, + "byteOffset": 18812, + "byteLength": 1308, + "target": 34963 + } + ], + "accessors": [ + { + "bufferView": 0, + "byteOffset": 0, + "type": "VEC3", + "componentType": 5126, + "count": 508, + "max": [ + 1.4, + 0.9, + 1.11283529 + ], + "min": [ + -1.4, + 0, + -1.11283529 + ], + "normalized": false + }, + { + "bufferView": 1, + "byteOffset": 0, + "type": "VEC3", + "componentType": 5126, + "count": 508, + "normalized": false + }, + { + "bufferView": 2, + "byteOffset": 0, + "type": "VEC2", + "componentType": 5126, + "count": 508, + "normalized": false + }, + { + "bufferView": 3, + "byteOffset": 0, + "type": "SCALAR", + "componentType": 5125, + "count": 183, + "normalized": false + }, + { + "bufferView": 4, + "byteOffset": 0, + "type": "SCALAR", + "componentType": 5125, + "count": 342, + "normalized": false + }, + { + "bufferView": 5, + "byteOffset": 0, + "type": "SCALAR", + "componentType": 5125, + "count": 114, + "normalized": false + }, + { + "bufferView": 6, + "byteOffset": 0, + "type": "SCALAR", + "componentType": 5125, + "count": 327, + "normalized": false + } + ], + "materials": [ + { + "name": "metal", + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.843137264, + 0.870588243, + 0.9098039, + 1 + ], + "metallicFactor": 1, + "roughnessFactor": 1 + }, + "doubleSided": false, + "alphaMode": "OPAQUE" + }, + { + "name": "metalDark", + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.6750623, + 0.7100219, + 0.7735849, + 1 + ], + "metallicFactor": 1, + "roughnessFactor": 1 + }, + "doubleSided": false, + "alphaMode": "OPAQUE" + }, + { + "name": "dark", + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.274509817, + 0.298039228, + 0.34117648, + 1 + ], + "metallicFactor": 1, + "roughnessFactor": 1 + }, + "doubleSided": false, + "alphaMode": "OPAQUE" + }, + { + "name": "metalRed", + "pbrMetallicRoughness": { + "baseColorFactor": [ + 1, + 0.628524244, + 0.2028302, + 1 + ], + "metallicFactor": 1, + "roughnessFactor": 1 + }, + "doubleSided": false, + "alphaMode": "OPAQUE" + } + ], + "meshes": [ + { + "name": "Mesh craft_speederD", + "primitives": [ + { + "mode": 4, + "indices": 3, + "attributes": { + "POSITION": 0, + "NORMAL": 1, + "TEXCOORD_0": 2 + }, + "material": 0 + }, + { + "mode": 4, + "indices": 4, + "attributes": { + "POSITION": 0, + "NORMAL": 1, + "TEXCOORD_0": 2 + }, + "material": 1 + }, + { + "mode": 4, + "indices": 5, + "attributes": { + "POSITION": 0, + "NORMAL": 1, + "TEXCOORD_0": 2 + }, + "material": 2 + }, + { + "mode": 4, + "indices": 6, + "attributes": { + "POSITION": 0, + "NORMAL": 1, + "TEXCOORD_0": 2 + }, + "material": 3 + } + ] + } + ], + "nodes": [ + { + "children": [ + 1 + ], + "name": "tmpParent", + "translation": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0, + 1 + ], + "scale": [ + 1, + 1, + 1 + ] + }, + { + "name": "craft_speederD", + "translation": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0, + 1 + ], + "scale": [ + 1, + 1, + 1 + ], + "mesh": 0 + } + ], + "scenes": [ + { + "nodes": [ + 1 + ] + } + ], + "scene": 0 +} \ No newline at end of file diff --git a/assets/models/ship/craft_speederD_data.bin b/assets/models/ship/craft_speederD_data.bin new file mode 100644 index 0000000000000000000000000000000000000000..6538b117a5dea10fd92aab8c844bc686471b9b0b GIT binary patch literal 20120 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 TJY)0)!oP)u!oQ5sn}q)X^vnBL literal 0 HcmV?d00001 diff --git a/examples/transforms/align.rs b/examples/transforms/align.rs index a927f72ab5..4b773688c2 100644 --- a/examples/transforms/align.rs +++ b/examples/transforms/align.rs @@ -10,24 +10,24 @@ fn main() { App::new() .add_plugins(DefaultPlugins) .add_systems(Startup, setup) - .add_systems(Update, (draw_cube_axes, draw_random_axes)) - .add_systems(Update, (handle_keypress, handle_mouse, rotate_cube).chain()) + .add_systems(Update, (draw_ship_axes, draw_random_axes)) + .add_systems(Update, (handle_keypress, handle_mouse, rotate_ship).chain()) .run(); } -/// This struct stores metadata for a single rotational move of the cube +/// This struct stores metadata for a single rotational move of the ship #[derive(Component, Default)] -struct Cube { - /// The initial transform of the cube move, the starting point of interpolation +struct Ship { + /// The initial transform of the ship move, the starting point of interpolation initial_transform: Transform, - /// The target transform of the cube move, the endpoint of interpolation + /// The target transform of the ship move, the endpoint of interpolation target_transform: Transform, - /// The progress of the cube move in percentage points + /// The progress of the ship move in percentage points progress: u16, - /// Whether the cube is currently in motion; allows motion to be paused + /// Whether the ship is currently in motion; allows motion to be paused in_motion: bool, } @@ -49,6 +49,7 @@ fn setup( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, + asset_server: Res, ) { // We're seeding the PRNG here to make this example deterministic for testing purposes. // This isn't strictly required in practical use unless you need your app to be deterministic. @@ -83,14 +84,14 @@ fn setup( let second = seeded_rng.gen(); commands.spawn(RandomAxes(first, second)); - // Finally, our cube that is going to rotate + // Finally, our ship that is going to rotate commands.spawn(( - PbrBundle { - mesh: meshes.add(Cuboid::new(1.0, 1.0, 1.0)), - material: materials.add(Color::srgb(0.5, 0.5, 0.5)), + SceneBundle { + scene: asset_server + .load(GltfAssetLabel::Scene(0).from_asset("models/ship/craft_speederD.gltf")), ..default() }, - Cube { + Ship { initial_transform: Transform::IDENTITY, target_transform: random_axes_target_alignment(&RandomAxes(first, second)), ..default() @@ -105,7 +106,7 @@ fn setup( The fainter red axis is the secondary alignment axis, and it is made to\n\ line up with the secondary target direction (gray) as closely as possible.\n\ Press 'R' to generate random target directions.\n\ - Press 'T' to align the cube to those directions.\n\ + Press 'T' to align the ship to those directions.\n\ Click and drag the mouse to rotate the camera.\n\ Press 'H' to hide/show these instructions.", TextStyle::default(), @@ -125,17 +126,17 @@ fn setup( // Update systems -// Draw the main and secondary axes on the rotating cube -fn draw_cube_axes(mut gizmos: Gizmos, query: Query<&Transform, With>) { - let cube_transform = query.single(); +// Draw the main and secondary axes on the rotating ship +fn draw_ship_axes(mut gizmos: Gizmos, query: Query<&Transform, With>) { + let ship_transform = query.single(); - // Local X-axis arrow - let x_ends = arrow_ends(cube_transform, Vec3::X, 1.5); - gizmos.arrow(x_ends.0, x_ends.1, RED); + // Local Z-axis arrow, negative direction + let z_ends = arrow_ends(ship_transform, Vec3::NEG_Z, 1.5); + gizmos.arrow(z_ends.0, z_ends.1, RED); - // local Y-axis arrow - let y_ends = arrow_ends(cube_transform, Vec3::Y, 1.5); - gizmos.arrow(y_ends.0, y_ends.1, Color::srgb(0.65, 0., 0.)); + // local X-axis arrow + let x_ends = arrow_ends(ship_transform, Vec3::X, 1.5); + gizmos.arrow(x_ends.0, x_ends.1, Color::srgb(0.65, 0., 0.)); } // Draw the randomly generated axes @@ -145,38 +146,38 @@ fn draw_random_axes(mut gizmos: Gizmos, query: Query<&RandomAxes>) { gizmos.arrow(Vec3::ZERO, 1.5 * *v2, GRAY); } -// Actually update the cube's transform according to its initial source and target -fn rotate_cube(mut cube: Query<(&mut Cube, &mut Transform)>) { - let (mut cube, mut cube_transform) = cube.single_mut(); +// Actually update the ship's transform according to its initial source and target +fn rotate_ship(mut ship: Query<(&mut Ship, &mut Transform)>) { + let (mut ship, mut ship_transform) = ship.single_mut(); - if !cube.in_motion { + if !ship.in_motion { return; } - let start = cube.initial_transform.rotation; - let end = cube.target_transform.rotation; + let start = ship.initial_transform.rotation; + let end = ship.target_transform.rotation; - let p: f32 = cube.progress.into(); + let p: f32 = ship.progress.into(); let t = p / 100.; - *cube_transform = Transform::from_rotation(start.slerp(end, t)); + *ship_transform = Transform::from_rotation(start.slerp(end, t)); - if cube.progress == 100 { - cube.in_motion = false; + if ship.progress == 100 { + ship.in_motion = false; } else { - cube.progress += 1; + ship.progress += 1; } } // Handle user inputs from the keyboard for dynamically altering the scenario fn handle_keypress( - mut cube: Query<(&mut Cube, &Transform)>, + mut ship: Query<(&mut Ship, &Transform)>, mut random_axes: Query<&mut RandomAxes>, mut instructions: Query<&mut Visibility, With>, keyboard: Res>, mut seeded_rng: ResMut, ) { - let (mut cube, cube_transform) = cube.single_mut(); + let (mut ship, ship_transform) = ship.single_mut(); let mut random_axes = random_axes.single_mut(); if keyboard.just_pressed(KeyCode::KeyR) { @@ -185,15 +186,15 @@ fn handle_keypress( let second = seeded_rng.0.gen(); *random_axes = RandomAxes(first, second); - // Stop the cube and set it up to transform from its present orientation to the new one - cube.in_motion = false; - cube.initial_transform = *cube_transform; - cube.target_transform = random_axes_target_alignment(&random_axes); - cube.progress = 0; + // Stop the ship and set it up to transform from its present orientation to the new one + ship.in_motion = false; + ship.initial_transform = *ship_transform; + ship.target_transform = random_axes_target_alignment(&random_axes); + ship.progress = 0; } if keyboard.just_pressed(KeyCode::KeyT) { - cube.in_motion ^= true; + ship.in_motion ^= true; } if keyboard.just_pressed(KeyCode::KeyH) { @@ -240,8 +241,8 @@ fn arrow_ends(transform: &Transform, axis: Vec3, length: f32) -> (Vec3, Vec3) { } // This is where `Transform::align` is actually used! -// Note that the choice of `Vec3::X` and `Vec3::Y` here matches the use of those in `draw_cube_axes`. +// Note that the choice of `Vec3::X` and `Vec3::Y` here matches the use of those in `draw_ship_axes`. fn random_axes_target_alignment(random_axes: &RandomAxes) -> Transform { let RandomAxes(first, second) = random_axes; - Transform::IDENTITY.aligned_by(Vec3::X, *first, Vec3::Y, *second) + Transform::IDENTITY.aligned_by(Vec3::NEG_Z, *first, Vec3::X, *second) }