Skip to content

Commit 781c20e

Browse files
committed
Changed back to putting SkinnedMeshBounds on Mesh. This assumes that bevyengine#21732 or similar will land, so we don't lose the bounds if the mesh doesn't have RenderAssetUsages::MAIN_WORLD.
1 parent 4bf5041 commit 781c20e

File tree

10 files changed

+134
-184
lines changed

10 files changed

+134
-184
lines changed

crates/bevy_camera/src/visibility/mod.rs

Lines changed: 27 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ use bevy_ecs::entity::{EntityHashMap, EntityHashSet};
77
use bevy_ecs::lifecycle::HookContext;
88
use bevy_ecs::world::DeferredWorld;
99
use bevy_mesh::skinning::{
10-
entity_aabb_from_skinned_mesh_bounds, SkinnedMesh, SkinnedMeshBounds, SkinnedMeshBoundsAsset,
11-
SkinnedMeshInverseBindposes,
10+
entity_aabb_from_skinned_mesh_bounds, SkinnedMesh, SkinnedMeshInverseBindposes,
1211
};
1312
use derive_more::derive::{Deref, DerefMut};
1413
pub use range::*;
@@ -220,6 +219,15 @@ impl ViewVisibility {
220219
#[reflect(Component, Default, Debug)]
221220
pub struct NoFrustumCulling;
222221

222+
/// Use this component to enable dynamic skinned mesh bounds. The [`Aabb`]
223+
/// component of the skinned mesh will be automatically updated each frame based
224+
/// on the current joint transforms.
225+
///
226+
/// XXX TODO: More documentation.
227+
#[derive(Debug, Component, Default, Reflect)]
228+
#[reflect(Component, Default, Debug)]
229+
pub struct DynamicSkinnedMeshBounds;
230+
223231
/// Collection of entities visible from the current view.
224232
///
225233
/// This component contains all entities which are visible from the currently
@@ -411,44 +419,29 @@ pub fn calculate_bounds(
411419
// XXX TODO: Document.
412420
fn update_skinned_mesh_bounds(
413421
inverse_bindposes_assets: Res<Assets<SkinnedMeshInverseBindposes>>,
414-
bounds_assets: Res<Assets<SkinnedMeshBoundsAsset>>,
422+
mesh_assets: Res<Assets<Mesh>>,
415423
mut mesh_entities: Query<
416-
(
417-
&SkinnedMesh,
418-
&SkinnedMeshBounds,
419-
Option<&GlobalTransform>,
420-
&mut Aabb,
421-
),
422-
// XXX TODO: This is debatable - frustum culling is not the only
423-
// system that might want skinned bounds.
424-
Without<NoFrustumCulling>,
424+
(&mut Aabb, &Mesh3d, &SkinnedMesh, Option<&GlobalTransform>),
425+
With<DynamicSkinnedMeshBounds>,
425426
>,
426427
joint_entities: Query<&GlobalTransform>,
427428
) {
428429
mesh_entities
429430
.par_iter_mut()
430-
.for_each(|(mesh, bounds, world_from_entity, mut aabb)| {
431-
let Some(inverse_bindposes_asset) =
432-
inverse_bindposes_assets.get(&mesh.inverse_bindposes)
433-
else {
434-
return;
435-
};
436-
437-
let Some(bounds_asset) = bounds_assets.get(bounds) else {
438-
return;
439-
};
440-
441-
let Some(skinned_aabb) = entity_aabb_from_skinned_mesh_bounds(
442-
&joint_entities,
443-
mesh,
444-
inverse_bindposes_asset,
445-
bounds_asset,
446-
world_from_entity,
447-
) else {
448-
return;
449-
};
450-
451-
*aabb = skinned_aabb.into();
431+
.for_each(|(mut aabb, mesh, skinned_mesh, world_from_entity)| {
432+
if let Some(inverse_bindposes_asset) =
433+
inverse_bindposes_assets.get(&skinned_mesh.inverse_bindposes)
434+
&& let Some(mesh_asset) = mesh_assets.get(mesh)
435+
&& let Some(skinned_aabb) = entity_aabb_from_skinned_mesh_bounds(
436+
&joint_entities,
437+
mesh_asset,
438+
skinned_mesh,
439+
inverse_bindposes_asset,
440+
world_from_entity,
441+
)
442+
{
443+
*aabb = skinned_aabb.into();
444+
}
452445
});
453446
}
454447

crates/bevy_gizmos/src/skinned_mesh_bounds.rs

Lines changed: 43 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@
22
33
use bevy_app::{Plugin, PostUpdate};
44
use bevy_asset::Assets;
5+
use bevy_camera::visibility::DynamicSkinnedMeshBounds;
56
use bevy_color::Color;
67
use bevy_ecs::{
78
component::Component,
8-
query::Without,
9+
query::{With, Without},
910
reflect::ReflectComponent,
1011
schedule::IntoScheduleConfigs,
1112
system::{Query, Res},
1213
};
1314
use bevy_math::Affine3A;
14-
use bevy_mesh::skinning::{
15-
SkinnedMesh, SkinnedMeshBounds, SkinnedMeshBoundsAsset, SkinnedMeshInverseBindposes,
15+
use bevy_mesh::{
16+
skinning::{SkinnedMesh, SkinnedMeshInverseBindposes},
17+
Mesh, Mesh3d,
1618
};
1719
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
1820
use bevy_transform::{components::GlobalTransform, TransformSystems};
@@ -23,7 +25,7 @@ use crate::{
2325
AppGizmoBuilder,
2426
};
2527

26-
/// A [`Plugin`] that provides visualization of [`SkinnedMeshBounds`]s for debugging.
28+
/// A [`Plugin`] that provides visualization of entities with [`DynamicSkinnedMeshBounds`].
2729
pub struct SkinnedMeshBoundsGizmoPlugin;
2830

2931
impl Plugin for SkinnedMeshBoundsGizmoPlugin {
@@ -44,7 +46,7 @@ impl Plugin for SkinnedMeshBoundsGizmoPlugin {
4446
);
4547
}
4648
}
47-
/// The [`GizmoConfigGroup`] used for debug visualizations of [`SkinnedMeshBounds`] components on entities.
49+
/// The [`GizmoConfigGroup`] used for debug visualizations of entities with [`DynamicSkinnedMeshBounds`]
4850
#[derive(Clone, Reflect, GizmoConfigGroup)]
4951
#[reflect(Clone, Default)]
5052
pub struct SkinnedMeshBoundsGizmoConfigGroup {
@@ -68,7 +70,7 @@ impl Default for SkinnedMeshBoundsGizmoConfigGroup {
6870
}
6971
}
7072

71-
/// Add this [`Component`] to an entity to draw its [`SkinnedMeshBounds`] component.
73+
/// Add this [`Component`] to an entity to draw its [`DynamicSkinnedMeshBounds`] component.
7274
#[derive(Component, Reflect, Default, Debug)]
7375
#[reflect(Component, Default, Debug)]
7476
pub struct ShowSkinnedMeshBoundsGizmo {
@@ -80,25 +82,27 @@ pub struct ShowSkinnedMeshBoundsGizmo {
8082

8183
fn draw(
8284
color: Color,
83-
mesh: &SkinnedMesh,
84-
bounds: &SkinnedMeshBounds,
85-
joints: &Query<&GlobalTransform>,
86-
bounds_assets: &Res<Assets<SkinnedMeshBoundsAsset>>,
85+
mesh: &Mesh3d,
86+
mesh_assets: &Res<Assets<Mesh>>,
87+
skinned_mesh: &SkinnedMesh,
88+
joint_entities: &Query<&GlobalTransform>,
8789
inverse_bindposes_assets: &Res<Assets<SkinnedMeshInverseBindposes>>,
8890
gizmos: &mut Gizmos<SkinnedMeshBoundsGizmoConfigGroup>,
8991
) {
90-
if let Some(bounds_asset) = bounds_assets.get(bounds)
91-
&& let Some(inverse_bindposes_asset) = inverse_bindposes_assets.get(&mesh.inverse_bindposes)
92+
if let Some(mesh_asset) = mesh_assets.get(mesh)
93+
&& let Some(bounds) = mesh_asset.skinned_mesh_bounds()
94+
&& let Some(inverse_bindposes_asset) =
95+
inverse_bindposes_assets.get(&skinned_mesh.inverse_bindposes)
9296
{
93-
for (&joint_index, &joint_aabb) in bounds_asset
97+
for (&joint_index, &joint_aabb) in bounds
9498
.aabb_index_to_joint_index
9599
.iter()
96-
.zip(bounds_asset.aabbs.iter())
100+
.zip(bounds.aabbs.iter())
97101
{
98102
let joint_index = joint_index as usize;
99103

100-
if let Some(&joint_entity) = mesh.joints.get(joint_index)
101-
&& let Ok(&world_from_joint) = joints.get(joint_entity)
104+
if let Some(&joint_entity) = skinned_mesh.joints.get(joint_index)
105+
&& let Ok(&world_from_joint) = joint_entities.get(joint_entity)
102106
&& let Some(&joint_from_mesh) = inverse_bindposes_asset.get(joint_index)
103107
{
104108
let world_from_mesh =
@@ -111,45 +115,50 @@ fn draw(
111115
}
112116

113117
fn draw_skinned_mesh_bounds(
114-
meshes: Query<(
115-
&SkinnedMesh,
116-
&SkinnedMeshBounds,
117-
&ShowSkinnedMeshBoundsGizmo,
118-
)>,
119-
joints: Query<&GlobalTransform>,
120-
bounds_assets: Res<Assets<SkinnedMeshBoundsAsset>>,
118+
mesh_entities: Query<
119+
(&Mesh3d, &SkinnedMesh, &ShowSkinnedMeshBoundsGizmo),
120+
With<DynamicSkinnedMeshBounds>,
121+
>,
122+
joint_entities: Query<&GlobalTransform>,
123+
mesh_assets: Res<Assets<Mesh>>,
121124
inverse_bindposes_assets: Res<Assets<SkinnedMeshInverseBindposes>>,
122125
mut gizmos: Gizmos<SkinnedMeshBoundsGizmoConfigGroup>,
123126
) {
124-
for (mesh_bounds, mesh, gizmo) in meshes {
127+
for (mesh, skinned_mesh, gizmo) in mesh_entities {
125128
let color = gizmo.color.unwrap_or(gizmos.config_ext.default_color);
126129

127130
draw(
128131
color,
129-
mesh_bounds,
130132
mesh,
131-
&joints,
132-
&bounds_assets,
133+
&mesh_assets,
134+
skinned_mesh,
135+
&joint_entities,
133136
&inverse_bindposes_assets,
134137
&mut gizmos,
135138
);
136139
}
137140
}
138141

139142
fn draw_all_skinned_mesh_bounds(
140-
meshes: Query<(&SkinnedMesh, &SkinnedMeshBounds), Without<ShowSkinnedMeshBoundsGizmo>>,
141-
joints: Query<&GlobalTransform>,
142-
bounds_assets: Res<Assets<SkinnedMeshBoundsAsset>>,
143+
mesh_entities: Query<
144+
(&Mesh3d, &SkinnedMesh),
145+
(
146+
With<DynamicSkinnedMeshBounds>,
147+
Without<ShowSkinnedMeshBoundsGizmo>,
148+
),
149+
>,
150+
joint_entities: Query<&GlobalTransform>,
151+
mesh_assets: Res<Assets<Mesh>>,
143152
inverse_bindposes_assets: Res<Assets<SkinnedMeshInverseBindposes>>,
144153
mut gizmos: Gizmos<SkinnedMeshBoundsGizmoConfigGroup>,
145154
) {
146-
for (mesh_bounds, mesh) in meshes {
155+
for (mesh, skinned_mesh) in mesh_entities {
147156
draw(
148157
gizmos.config_ext.default_color,
149-
mesh_bounds,
150158
mesh,
151-
&joints,
152-
&bounds_assets,
159+
&mesh_assets,
160+
skinned_mesh,
161+
&joint_entities,
153162
&inverse_bindposes_assets,
154163
&mut gizmos,
155164
);

crates/bevy_gltf/src/assets.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@ use core::ops::Deref;
66
use bevy_animation::AnimationClip;
77
use bevy_asset::{Asset, Handle};
88
use bevy_ecs::{component::Component, reflect::ReflectComponent};
9-
use bevy_mesh::{
10-
skinning::{SkinnedMeshBoundsAsset, SkinnedMeshInverseBindposes},
11-
Mesh,
12-
};
9+
use bevy_mesh::{skinning::SkinnedMeshInverseBindposes, Mesh};
1310
use bevy_pbr::StandardMaterial;
1411
use bevy_platform::collections::HashMap;
1512
use bevy_reflect::{prelude::ReflectDefault, Reflect, TypePath};
@@ -180,8 +177,6 @@ pub struct GltfPrimitive {
180177
pub extras: Option<GltfExtras>,
181178
/// Additional data of the `material`.
182179
pub material_extras: Option<GltfExtras>,
183-
/// Optional skinned mesh bounds of this primitive.
184-
pub skinned_mesh_bounds: Option<Handle<SkinnedMeshBoundsAsset>>,
185180
}
186181

187182
impl GltfPrimitive {
@@ -193,7 +188,6 @@ impl GltfPrimitive {
193188
material: Option<Handle<StandardMaterial>>,
194189
extras: Option<GltfExtras>,
195190
material_extras: Option<GltfExtras>,
196-
skinned_mesh_bounds: Option<Handle<SkinnedMeshBoundsAsset>>,
197191
) -> Self {
198192
GltfPrimitive {
199193
index: gltf_primitive.index(),
@@ -210,7 +204,6 @@ impl GltfPrimitive {
210204
material,
211205
extras,
212206
material_extras,
213-
skinned_mesh_bounds,
214207
}
215208
}
216209

crates/bevy_gltf/src/label.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,6 @@ pub enum GltfAssetLabel {
7272
/// `Skin{}/InverseBindMatrices`: glTF mesh skin matrices as Bevy
7373
/// [`SkinnedMeshInverseBindposes`](bevy_mesh::skinning::SkinnedMeshInverseBindposes)
7474
InverseBindMatrices(usize),
75-
/// `Mesh{}/Primitive{}/SkinnedMeshBounds`: the optional [`SkinnedMeshBoundsAsset`](bevy_mesh::skinning::SkinnedMeshBoundsAsset)
76-
/// created from a primitive.
77-
SkinnedMeshBounds {
78-
/// Index of the mesh for the primitive
79-
mesh: usize,
80-
/// Index of the primitive in its parent mesh
81-
primitive: usize,
82-
},
8375
}
8476

8577
impl core::fmt::Display for GltfAssetLabel {
@@ -112,9 +104,6 @@ impl core::fmt::Display for GltfAssetLabel {
112104
GltfAssetLabel::InverseBindMatrices(index) => {
113105
f.write_str(&format!("Skin{index}/InverseBindMatrices"))
114106
}
115-
GltfAssetLabel::SkinnedMeshBounds { mesh, primitive } => f.write_str(&format!(
116-
"Mesh{mesh}/Primitive{primitive}/SkinnedMeshBounds"
117-
)),
118107
}
119108
}
120109
}

crates/bevy_gltf/src/lib.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,10 @@ pub enum GltfSkinnedMeshBoundsPolicy {
201201
/// Skinned meshes are assigned an `Aabb` component calculated from the bind
202202
/// pose `Mesh`.
203203
BindPose,
204-
/// Skinned meshes are assigned a `SkinnedMeshBounds` component, which will
205-
/// be used by the `bevy_camera` plugin to update the `Aabb` component
206-
/// based on joint positions.
204+
/// Skinned meshes are created with `SkinnedMeshBounds` and assigned
205+
/// a [`DynamicSkinnedMeshBounds`](bevy_camera::visibility::DynamicSkinnedMeshBounds)
206+
/// component. This means the `bevy_camera` plugin will update the `Aabb`
207+
/// component based on joint positions.
207208
Dynamic,
208209
/// Same as `BindPose`, but also assign a `NoFrustumCulling` component. That
209210
/// component tells the `bevy_camera` plugin to avoid frustum culling the

0 commit comments

Comments
 (0)