Skip to content

Commit 9cf96f5

Browse files
mockersfsuperdump
andcommitted
review
Co-Authored-By: Robert Swain <[email protected]>
1 parent 2d3693f commit 9cf96f5

File tree

4 files changed

+46
-23
lines changed

4 files changed

+46
-23
lines changed

CREDITS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,5 @@
2121
* Ground tile from [Kenney's Tower Defense Kit](https://www.kenney.nl/assets/tower-defense-kit) (CC0 1.0 Universal)
2222
* Game icons from [Kenney's Game Icons](https://www.kenney.nl/assets/game-icons) (CC0 1.0 Universal)
2323
* Space ships from [Kenny's Simple Space Kit](https://www.kenney.nl/assets/simple-space) (CC0 1.0 Universal)
24+
* glTF animated triangle from [glTF Sample Models](https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/AnimatedTriangle) (CC0 1.0 Universal)
25+
* glTF box animated from [glTF Sample Models](https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/BoxAnimated) ([CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) - by [Cesium](https://cesium.com))

crates/bevy_gltf/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use bevy_ecs::{prelude::Component, reflect::ReflectComponent};
2-
use bevy_math::{Vec3, Vec4};
2+
use bevy_math::{Quat, Vec3, Vec4};
33
use bevy_utils::HashMap;
44

55
mod loader;
@@ -70,7 +70,7 @@ pub struct GltfPrimitive {
7070
pub material: Option<Handle<StandardMaterial>>,
7171
}
7272

73-
/// Part of a [`GltfNodeAnimation`], interpolation method for an animation.
73+
/// Interpolation method for an animation. Part of a [`GltfNodeAnimation`].
7474
#[derive(Clone, Debug)]
7575
pub enum GltfAnimationInterpolation {
7676
Linear,
@@ -97,7 +97,7 @@ pub struct GltfAnimation {
9797
/// Key frames of an animation.
9898
#[derive(Clone, Debug)]
9999
pub enum GltfNodeAnimationKeyframes {
100-
Rotation(Vec<Vec4>),
100+
Rotation(Vec<Quat>),
101101
Translation(Vec<Vec3>),
102102
Scale(Vec<Vec3>),
103103
}

crates/bevy_gltf/src/loader.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use bevy_asset::{
55
use bevy_core::Name;
66
use bevy_ecs::world::World;
77
use bevy_log::warn;
8-
use bevy_math::{Mat4, Vec3, Vec4};
8+
use bevy_math::{Mat4, Quat, Vec3, Vec4};
99
use bevy_pbr::{
1010
AlphaMode, DirectionalLight, DirectionalLightBundle, PbrBundle, PointLight, PointLightBundle,
1111
StandardMaterial,
@@ -62,6 +62,8 @@ pub enum GltfError {
6262
ImageError(#[from] TextureError),
6363
#[error("failed to load an asset path: {0}")]
6464
AssetIoError(#[from] AssetIoError),
65+
#[error("Missing sampler for animation {0}")]
66+
MissingAnimationSampler(usize),
6567
}
6668

6769
/// Loads glTF files with all of their data as their corresponding bevy representations.
@@ -137,7 +139,8 @@ async fn load_gltf<'a, 'b>(
137139
}
138140
}
139141
} else {
140-
panic!("animations without a sampler input are not supported");
142+
warn!("animations without a sampler input are not supported");
143+
return Err(GltfError::MissingAnimationSampler(animation.index()));
141144
};
142145

143146
let keyframes = if let Some(outputs) = reader.read_outputs() {
@@ -147,7 +150,7 @@ async fn load_gltf<'a, 'b>(
147150
}
148151
gltf::animation::util::ReadOutputs::Rotations(rots) => {
149152
GltfNodeAnimationKeyframes::Rotation(
150-
rots.into_f32().map(Vec4::from).collect(),
153+
rots.into_f32().map(Quat::from_array).collect(),
151154
)
152155
}
153156
gltf::animation::util::ReadOutputs::Scales(scale) => {
@@ -159,7 +162,8 @@ async fn load_gltf<'a, 'b>(
159162
}
160163
}
161164
} else {
162-
panic!("animations without a sampler output are not supported");
165+
warn!("animations without a sampler output are not supported");
166+
return Err(GltfError::MissingAnimationSampler(animation.index()));
163167
};
164168

165169
gltf_animation

examples/3d/load_gltf_animation.rs

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,35 @@ fn main() {
2424
.run();
2525
}
2626

27-
const ANIMATIONS: [(&str, Transform, f32); 3] = [
28-
(
29-
// Model being loaded
27+
struct Example {
28+
model_name: &'static str,
29+
camera_transform: Transform,
30+
speed: f32,
31+
}
32+
impl Example {
33+
const fn new(model_name: &'static str, camera_transform: Transform, speed: f32) -> Self {
34+
Self {
35+
model_name,
36+
camera_transform,
37+
speed,
38+
}
39+
}
40+
}
41+
42+
// const ANIMATIONS: [(&str, Transform, f32); 3] = [
43+
const ANIMATIONS: [Example; 3] = [
44+
// https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/AnimatedTriangle
45+
Example::new(
3046
"models/animated/AnimatedTriangle.gltf",
31-
// Position of the camera
3247
Transform {
3348
translation: const_vec3!([0.0, 0.0, 3.0]),
3449
rotation: const_quat!([0.0, 0.0, 0.0, 1.0]),
3550
scale: const_vec3!([1.0; 3]),
3651
},
37-
// Speed of the animation
3852
0.12,
3953
),
40-
(
54+
// https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/BoxAnimated
55+
Example::new(
4156
"models/animated/BoxAnimated.gltf",
4257
Transform {
4358
translation: const_vec3!([4.0, 2.0, 4.0]),
@@ -46,7 +61,7 @@ const ANIMATIONS: [(&str, Transform, f32); 3] = [
4661
},
4762
0.4,
4863
),
49-
(
64+
Example::new(
5065
"models/animated/animations.gltf",
5166
Transform {
5267
translation: const_vec3!([-10.0, 5.0, -3.0]),
@@ -76,16 +91,17 @@ fn setup(
7691
// Insert a resource with the current scene information
7792
commands.insert_resource(CurrentScene {
7893
// Its instance id, to be able to check that it's loaded
79-
instance_id: scene_spawner.spawn(asset_server.load(&format!("{}#Scene0", ANIMATIONS[0].0))),
94+
instance_id: scene_spawner
95+
.spawn(asset_server.load(&format!("{}#Scene0", ANIMATIONS[0].model_name))),
8096
// The handle to the first animation
81-
animation: asset_server.load(&format!("{}#Animation0", ANIMATIONS[0].0)),
97+
animation: asset_server.load(&format!("{}#Animation0", ANIMATIONS[0].model_name)),
8298
// The animation speed modifier
83-
speed: ANIMATIONS[0].2,
99+
speed: ANIMATIONS[0].speed,
84100
});
85101

86102
// Add a camera
87103
commands.spawn_bundle(PerspectiveCameraBundle {
88-
transform: ANIMATIONS[0].1,
104+
transform: ANIMATIONS[0].camera_transform,
89105
..Default::default()
90106
});
91107

@@ -107,13 +123,14 @@ fn switch_scene(
107123

108124
// Despawn the existing scene, then start loading the next one
109125
commands.entity(scene_root.single()).despawn_recursive();
110-
current_scene.instance_id =
111-
scene_spawner.spawn(asset_server.load(&format!("{}#Scene0", ANIMATIONS[*current].0)));
112-
current_scene.animation = asset_server.load(&format!("{}#Animation0", ANIMATIONS[*current].0));
113-
current_scene.speed = ANIMATIONS[*current].2;
126+
current_scene.instance_id = scene_spawner
127+
.spawn(asset_server.load(&format!("{}#Scene0", ANIMATIONS[*current].model_name)));
128+
current_scene.animation =
129+
asset_server.load(&format!("{}#Animation0", ANIMATIONS[*current].model_name));
130+
current_scene.speed = ANIMATIONS[*current].speed;
114131

115132
// Update the camera position
116-
*camera.single_mut() = ANIMATIONS[*current].1;
133+
*camera.single_mut() = ANIMATIONS[*current].camera_transform;
117134

118135
// Reset the current animation
119136
commands.remove_resource::<CurrentAnimation>();

0 commit comments

Comments
 (0)