#Cloned collider freeze

25 messages · Page 1 of 1 (latest)

balmy vector
#

Hi, I'm trying to understand why a .clone() on an entity with a Collider would cause a game to freeze.

Simple example:

use avian2d::prelude::*; // 0.4.1
use bevy::prelude::*;    // 0.17.2

#[derive(Component, Clone)]
struct NeedDup;

fn main() {
    App::new()
        .add_plugins((DefaultPlugins, PhysicsPlugins::default()))
        .add_systems(Startup, |mut cmds: Commands| {
            cmds.spawn(Camera2d);
        })
        .add_systems(Update, spawn)
        .add_systems(Update, dup)
        .run();
}

fn spawn(mut cmds: Commands, mut mt: ResMut<Assets<ColorMaterial>>, mut ms: ResMut<Assets<Mesh>>) {
    cmds.spawn((
        NeedDup,
        RigidBody::Dynamic,
        Collider::circle(2.0),
        MeshMaterial2d(mt.add(ColorMaterial::from_color(Color::WHITE))),
        Mesh2d(ms.add(Circle::new(2.0))),
    ));
}

fn dup(mut cmds: Commands, entities: Query<Entity, With<NeedDup>>) {
    entities.iter().for_each(|entity| {
        cmds.entity(entity).remove::<NeedDup>().clone_and_spawn();
    });
}

Note that:

  • I've reduced the example as much as possible, the crash happens even without Camera2d, MeshMaterial2d, or Mesh2d, it's left here for visual purpose.
  • clone_and_spawn many entities without Collider works.
  • cmd.spawn(...) many times with Collider works.
  • I've already opened https://github.com/avianphysics/avian/issues/880 as this looks like a bug, but I'm curious for other feedback as well.

Any ideas of what I am doing wrong, or if this is a bug?

GitHub

ECS-driven 2D and 3D physics engine for the Bevy game engine. - avianphysics/avian

#

Cloned collider freeze

balmy vector
#

FWIW, I tried the same using Rapier and didn't get the same issue. It however takes longer to build and I had to drop one version of bevy 🤔

use bevy::prelude::*;          // 0.16.0
use bevy_rapier2d::prelude::*; // 0.31.0

#[derive(Component, Clone)]
struct NeedDup;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_plugins(RapierPhysicsPlugin::<NoUserData>::pixels_per_meter(100.0))
        .add_systems(Startup, |mut cmds: Commands| {
            cmds.spawn(Camera2d);
        })
        .add_systems(Update, spawn)
        .add_systems(Update, dup)
        .run();
}

fn spawn(mut cmds: Commands, mut mt: ResMut<Assets<ColorMaterial>>, mut ms: ResMut<Assets<Mesh>>) {
    cmds.spawn((
        NeedDup,
        RigidBody::Dynamic,
        Collider::ball(2.0),
        MeshMaterial2d(mt.add(ColorMaterial::from_color(Color::WHITE))),
        Mesh2d(ms.add(Circle::new(2.0))),
    ));
}

fn dup(mut cmds: Commands, entities: Query<Entity, With<NeedDup>>) {
    entities.iter().for_each(|entity| {
        cmds.entity(entity).remove::<NeedDup>().clone_and_spawn();
    });
}
pearl geode
#

which is about a million colliders in exactly one place

#

might only work on rapier because it has a dynamic timestep by default

pearl geode
#

looks like with just debug rendering the most colliders i can get is 8192

pearl geode
#

okay i've managed to actually get an unambiguous freeze, but for some reason it seems ordering related

balmy vector
balmy vector
#

I get very different numbers when running with the debug UI:

#

I've done a couple more examples, only changing the dup code each time, and capturing the freeze debug panel.

#
fn dup(mut cmds: Commands, entities: Query<Entity, With<NeedDup>>) {
    entities.iter().for_each(|entity| {
        cmds.entity(entity)
            .remove::<NeedDup>()
            .clone_and_spawn();
    });
}
#
fn dup(mut cmds: Commands, entities: Query<Entity, With<NeedDup>>) {
    entities.iter().for_each(|entity| {
        cmds.entity(entity)
            .remove::<NeedDup>()
            .remove::<RigidBody>()
            .clone_and_spawn()
            .insert(RigidBody::Dynamic);
    });
}
#

interestingly, for this one the simulation never froze, but it got laggy pretty fast, the contact pairs never decreased.

#
fn dup(mut cmds: Commands, entities: Query<Entity, With<NeedDup>>) {
    entities.iter().for_each(|entity| {
        cmds.entity(entity)
            .remove::<NeedDup>()
            .remove::<RigidBody>()
            .remove::<Collider>()
            .clone_and_spawn()
            .insert(RigidBody::Dynamic);
    });
}

For this one, it also didn't freeze but it got really laggy,

#
fn dup(mut cmds: Commands, entities: Query<Entity, With<NeedDup>>) {
    entities.iter().for_each(|entity| {
        cmds.entity(entity)
            .remove::<NeedDup>()
            .remove::<RigidBody>()
            .remove::<Collider>()
            .clone_and_spawn()
            .insert((RigidBody::Dynamic, Collider::default()));
    });
}

This one might be the "best", given that I was able to spawn many colliders and duplicate them.

#

in drastic comparison, if I spawn two entities with spawn_batch (so, mimicking the 'duplicated' nature), there's no freeze, no lag, even for 4k colliders.

fn spawn(mut cmds: Commands, mut mt: ResMut<Assets<ColorMaterial>>, mut ms: ResMut<Assets<Mesh>>) {
    cmds.spawn_batch(vec![
        (
            RigidBody::Dynamic,
            Collider::default(),
            MeshMaterial2d(mt.add(ColorMaterial::from_color(Color::WHITE))),
            Mesh2d(ms.add(Circle::new(2.0))),
        ),
        (
            RigidBody::Dynamic,
            Collider::default(),
            MeshMaterial2d(mt.add(ColorMaterial::from_color(Color::WHITE))),
            Mesh2d(ms.add(Circle::new(2.0))),
        ),
    ]);
}
#

coming back to the dup system, spawning a net-new entity doesn't cause the freez.

fn dup(
    mut cmds: Commands,
    entities: Query<Entity, With<NeedDup>>,
    mut mt: ResMut<Assets<ColorMaterial>>,
    mut ms: ResMut<Assets<Mesh>>,
) {
    entities.iter().for_each(|entity| {
        cmds.entity(entity).remove::<NeedDup>();
        cmds.spawn((
            RigidBody::Dynamic,
            Collider::default(),
            MeshMaterial2d(mt.add(ColorMaterial::from_color(Color::WHITE))),
            Mesh2d(ms.add(Circle::new(2.0))),
        ));
    });
}
pearl geode
#

i was getting some really weird results where it'd only freeze if you ran several frames, but not if they're ordered in this specific way and only with debug visuals

balmy vector
#

Uh, interesting. 🤔
Does the freeze not happen with just the code provided?

pearl geode
#

only after long enough it looks like regular lag, if so

balmy vector
#

mmmh, so maybe there's something up with my setup, rather than with the Avian itself

balmy vector
#

I just tried the original code from the post, on a different computer and I have similar result, it freezes almost immediately.
The two computers I tried on:

  • Linux, AMD 9070X, AMD Zen 5
  • Macbook Pro, 2020, 2.3G Quad core intel i7
balmy vector
#

FWIW, I tested with 2 more computers, and they all froze within seconds, so it's not my setup