Skip to content

Commit 3220ad6

Browse files
authored
do not crash when rendering only one gizmo (#8434)
# Objective - Fixes #8432 ## Solution - Do not even create mesh when one is not needed
1 parent 315f3ca commit 3220ad6

File tree

2 files changed

+61
-42
lines changed

2 files changed

+61
-42
lines changed

crates/bevy_gizmos/src/gizmos.rs

-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ pub(crate) struct GizmoStorage {
2020
pub list_colors: Vec<ColorItem>,
2121
pub strip_positions: Vec<PositionItem>,
2222
pub strip_colors: Vec<ColorItem>,
23-
pub in_use: bool,
2423
}
2524

2625
/// A [`SystemParam`](bevy_ecs::system::SystemParam) for drawing gizmos.

crates/bevy_gizmos/src/lib.rs

+61-41
Original file line numberDiff line numberDiff line change
@@ -126,17 +126,15 @@ impl Default for GizmoConfig {
126126

127127
#[derive(Resource)]
128128
struct MeshHandles {
129-
list: Handle<Mesh>,
130-
strip: Handle<Mesh>,
129+
list: Option<Handle<Mesh>>,
130+
strip: Option<Handle<Mesh>>,
131131
}
132132

133133
impl FromWorld for MeshHandles {
134-
fn from_world(world: &mut World) -> Self {
135-
let mut meshes = world.resource_mut::<Assets<Mesh>>();
136-
134+
fn from_world(_world: &mut World) -> Self {
137135
MeshHandles {
138-
list: meshes.add(Mesh::new(PrimitiveTopology::LineList)),
139-
strip: meshes.add(Mesh::new(PrimitiveTopology::LineStrip)),
136+
list: None,
137+
strip: None,
140138
}
141139
}
142140
}
@@ -146,74 +144,96 @@ struct GizmoMesh;
146144

147145
fn update_gizmo_meshes(
148146
mut meshes: ResMut<Assets<Mesh>>,
149-
handles: Res<MeshHandles>,
147+
mut handles: ResMut<MeshHandles>,
150148
mut storage: ResMut<GizmoStorage>,
151149
) {
152-
let list_mesh = meshes.get_mut(&handles.list).unwrap();
150+
if storage.list_positions.is_empty() {
151+
handles.list = None;
152+
} else if let Some(handle) = handles.list.as_ref() {
153+
let list_mesh = meshes.get_mut(handle).unwrap();
153154

154-
storage.in_use = false;
155+
let positions = mem::take(&mut storage.list_positions);
156+
list_mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, positions);
155157

156-
if !storage.list_positions.is_empty() {
157-
storage.in_use = true;
158+
let colors = mem::take(&mut storage.list_colors);
159+
list_mesh.insert_attribute(Mesh::ATTRIBUTE_COLOR, colors);
160+
} else {
161+
let mut list_mesh = Mesh::new(PrimitiveTopology::LineList);
158162

159163
let positions = mem::take(&mut storage.list_positions);
160164
list_mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, positions);
161165

162166
let colors = mem::take(&mut storage.list_colors);
163167
list_mesh.insert_attribute(Mesh::ATTRIBUTE_COLOR, colors);
168+
169+
handles.list = Some(meshes.add(list_mesh));
164170
}
165171

166-
if !storage.strip_positions.is_empty() {
167-
storage.in_use = true;
172+
if storage.strip_positions.is_empty() {
173+
handles.strip = None;
174+
} else if let Some(handle) = handles.strip.as_ref() {
175+
let strip_mesh = meshes.get_mut(handle).unwrap();
168176

169-
let strip_mesh = meshes.get_mut(&handles.strip).unwrap();
177+
let positions = mem::take(&mut storage.strip_positions);
178+
strip_mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, positions);
179+
180+
let colors = mem::take(&mut storage.strip_colors);
181+
strip_mesh.insert_attribute(Mesh::ATTRIBUTE_COLOR, colors);
182+
} else {
183+
let mut strip_mesh = Mesh::new(PrimitiveTopology::LineStrip);
170184

171185
let positions = mem::take(&mut storage.strip_positions);
172186
strip_mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, positions);
173187

174188
let colors = mem::take(&mut storage.strip_colors);
175189
strip_mesh.insert_attribute(Mesh::ATTRIBUTE_COLOR, colors);
190+
191+
handles.strip = Some(meshes.add(strip_mesh));
176192
}
177193
}
178194

179195
fn extract_gizmo_data(
180196
mut commands: Commands,
181197
handles: Extract<Res<MeshHandles>>,
182198
config: Extract<Res<GizmoConfig>>,
183-
storage: Extract<Res<GizmoStorage>>,
184199
) {
185200
if config.is_changed() {
186201
commands.insert_resource(**config);
187202
}
188203

189-
if !config.enabled || !storage.in_use {
204+
if !config.enabled {
190205
return;
191206
}
192207

193208
let transform = Mat4::IDENTITY;
194209
let inverse_transpose_model = transform.inverse().transpose();
195-
commands.spawn_batch([&handles.list, &handles.strip].map(|handle| {
196-
(
197-
GizmoMesh,
198-
#[cfg(feature = "bevy_pbr")]
199-
(
200-
handle.clone_weak(),
201-
MeshUniform {
202-
flags: 0,
203-
transform,
204-
previous_transform: transform,
205-
inverse_transpose_model,
206-
},
207-
),
208-
#[cfg(feature = "bevy_sprite")]
209-
(
210-
Mesh2dHandle(handle.clone_weak()),
211-
Mesh2dUniform {
212-
flags: 0,
213-
transform,
214-
inverse_transpose_model,
215-
},
216-
),
217-
)
218-
}));
210+
commands.spawn_batch(
211+
[handles.list.clone(), handles.strip.clone()]
212+
.into_iter()
213+
.flatten()
214+
.map(move |handle| {
215+
(
216+
GizmoMesh,
217+
#[cfg(feature = "bevy_pbr")]
218+
(
219+
handle.clone_weak(),
220+
MeshUniform {
221+
flags: 0,
222+
transform,
223+
previous_transform: transform,
224+
inverse_transpose_model,
225+
},
226+
),
227+
#[cfg(feature = "bevy_sprite")]
228+
(
229+
Mesh2dHandle(handle),
230+
Mesh2dUniform {
231+
flags: 0,
232+
transform,
233+
inverse_transpose_model,
234+
},
235+
),
236+
)
237+
}),
238+
);
219239
}

0 commit comments

Comments
 (0)