#Avian Physics

1 messages ยท Page 26 of 1

severe urchin
#

wasn't sure how to make a collider from a torus

low storm
#

How to create new SharedShape from old SharedShape ? My system receive event include &SharedShape to create Collider, but I could not clone Arc object from it.

low storm
rough nebula
#

Is there any difference between setting physics speed and setting physics time step?

#

Like id assume they do the same thing right?

vestal minnow
#

Running physics more frequently is more expensive but can improve simulation quality

rough nebula
#

Oh right i thought step made the simulation go faster lol

clever quail
#

Instead of using hollow shapes or an approximation I just used joints which did a good enough job, other solution would have have taken too long to load

glossy holly
glacial nebula
#

@vestal minnow do you plan on yoinking the avian picking backend for 0.15? bevy_mod_picking is on track for deprecation.

vestal minnow
#

Docs should probably be clarified though

vestal minnow
fiery mortar
#

I have some general design questions on how to implement a kinematic character controller in avian3d. My plan is to update the linear velocity of my character using shape-casting before the phsics step. Is this the right approach? Won't this mean my character could end up colliding with other moving kinematic rigidbodies at the end of the physics step?

fiery mortar
# fiery mortar I have some general design questions on how to implement a kinematic character c...

Or maybe I'm confused on how avian works. The kinematic character controller example here https://github.com/Jondolf/avian/blob/main/crates/avian3d/examples/kinematic_character_3d/plugin.rs#L295 says "speculative collision". What does this mean, exactly?

GitHub

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

clever quail
#

Is there a bundle for removing all physics stuff, I spawn an object with a bundle containing

    pub rigid_body: RigidBody,
    pub collider: Collider,
    pub collider_density: ColliderDensity,
    pub dominance: Dominance

Is there a bundle of all physics components that may be generated so I can remove them all as I only do physics on gamestart and rather not run it after its done

crimson crest
clever quail
#

the list of removables

physics_stuff.remove::<(
                ColliderParent,
                ColliderMassProperties,
                Mass,
                InverseMass,
                Inertia,
                InverseInertia,
                CenterOfMass,
                ColliderTransform,
                LinearVelocity,
                AngularVelocity,
                ExternalForce,
                ExternalTorque,
                ExternalImpulse,
                ExternalAngularImpulse,
                Restitution,
            )>();
#

rest I cannot remove

lunar bluff
#

is there a cleaner way to get the normal of the contact manifold depending on whether the queried entity is entity 1 or 2?

let normal = if entity == event.0.entity1 {
    event
        .0
        .manifolds
        .iter()
        .next()
        .and_then(|m| Some(m.normal1))
} else if entity == event.0.entity2 {
    event
        .0
        .manifolds
        .iter()
        .next()
        .and_then(|m| Some(m.normal2))
} else {
    None
};
#

it seems that entity is consistently equal to entity1, but I'm not sure if I can depend on this, there seems to be no distinction between 1 and 2 in any documentation, so I have to write code like the above

#

would be good to be able to convert the Collision event into one that is relative to a given entity, so 1 and 2 become "this" and "other" for example. Something like event.relative_to(entity), returning Option<RelativeCollision>, where None is returned if it doesn't match entity1 or entity2

fiery mortar
fiery mortar
obsidian maple
#

Curious why PhysicsLayer requires implementing Default - shouldn't the default just be the empty mask?

#

Btw @vestal minnow, I noticed that the PhysicsDebugPlugin emits a ton of validation errors each frame on main:

        Validation Error: [ SYNC-HAZARD-READ-AFTER-WRITE ] Object 0: handle = 0x555559a1ba80, type = VK_OBJECT_TYPE_QUEUE; | MessageID = 0xe4d96472 | vkQueueSubmit():  Hazard READ_AFTER_WRITE for entry 3, VkCommandBuffer 0x7ffee80ccfa0[main_transparent_pass_2d], Submitted access info (submitted_usage: SYNC_VERTEX_ATTRIBUTE_INPUT_VERTEX_ATTRIBUTE_READ, command: vkCmdDraw, seq_no: 3, reset_no: 37, debug_region: main_transparent_pass_2d). Access info (prior_usage: SYNC_COPY_TRANSFER_WRITE, write_barriers: SYNC_FRAGMENT_SHADER_COLOR_ATTACHMENT_READ|SYNC_FRAGMENT_SHADER_DEPTH_STENCIL_ATTACHMENT_READ|SYNC_FRAGMENT_SHADER_INPUT_ATTACHMENT_READ|SYNC_EARLY_FRAGMENT_TESTS_DEPTH_STENCIL_ATTACHMENT_READ|SYNC_EARLY_FRAGMENT_TESTS_DEPTH_STENCIL_ATTACHMENT_WRITE|SYNC_LATE_FRAGMENT_TESTS_DEPTH_STENCIL_ATTACHMENT_READ|SYNC_LATE_FRAGMENT_TESTS_DEPTH_STENCIL_ATTACHMENT_WRITE|SYNC_COLOR_ATTACHMENT_OUTPUT_COLOR_ATTACHMENT_READ|SYNC_COLOR_ATTACHMENT_OUTPUT_COLOR_ATTACHMENT_WRITE|SYNC_SUBPASS_SHADER_HUAWEI_INPUT_ATTACHMENT_READ, queue: VkQueue 0x555559a1ba80[], submit: 7, batch: 0, batch_tag: 192, command: vkCmdCopyBuffer, command_buffer: VkCommandBuffer 0x555559c53550[(wgpu internal) PendingWrites], seq_no: 8, reset_no: 1).    
2024-10-29T20:59:18.770377Z ERROR wgpu_hal::vulkan::instance:       objects: (type: QUEUE, hndl: 0x555559a1ba80, name: ?)
vestal minnow
#

Long explanation, starting with some background: Collision layers in Avian are specified for colliders with the CollisionLayers component (similar to bevy_rapier's CollisionGroups). Previously, the default was that every collider belongs on every layer, and can interact with every layer, meaning that all bits in the bitmasks are set to 1. I originally just copied this from Rapier.

However, we realized that this is very impractical and doesn't make sense in practice. It means that you can't e.g. perform ray casts targeting a specific layer without overriding everything, since all colliders belong to all layers by default. So, we changed the defaults on the main branch in #476 such that colliders only have one membership and all filters by default. The first bit in the bitmask is reserved for this default layer. This is the same as what the Box2D physics engine does.

To clarify what PhysicsLayer is for: it's a trait you can derive for an enum to use it for CollisionLayers. It's not something you're intended to manually implement for anything. Using it on the main branch looks like this:

#[derive(PhysicsLayer, Default)]
enum GameLayer {
    #[default]
    Default, // Layer 0 - the default layer that objects are assigned to
    Player,  // Layer 1
    Enemy,   // Layer 2
    Ground,  // Layer 3
}

// ...

// Player collides with enemies and the ground, but not with other players.
let layers = CollisionLayers::new(
    GameLayer::Player,
    [GameLayer::Default, GameLayer::Enemy, GameLayer::Ground],
);
#

If you have an enum value that is a PhysicsLayer, it must obviously represent some layer. You can't have an enum value that doesn't represent any of its variants. You can have empty CollisionLayers though, but it wouldn't make sense as a default, since then nothing would collide by default.

Now, finally the reason PhysicsLayer requires Default. Since the first bit is now reserved for the default layer, it means that one of the enum variants (typically the first one) is also the default layer. This is implicit and could be very confusing if you are not aware of this. So, we added the Default restriction in #494 to force users to explicitly specify "this variant represents the default layer", i.e. the first bit.

#

(wow, that became long ๐Ÿ˜…)

obsidian maple
#

got it thanks ๐Ÿ™‚

vague pebble
#

Is there an easy way to see your colliders, like a debug mode in aviann?

vague pebble
#

Or make like a semi visible capsule

vestal minnow
vague pebble
#

oh wee

fiery mortar
#

what does LinearVelocity mean when running the physics simulation in FixedUpdate? is LinearVelocity not units per step?

vestal minnow
#

or no, I mean units per second

#

misread

#

So, for example LinearVelocity(Vec3::new(5.0, 0.0, 0,0)) would move towards positive X at 5 units/s

fiery mortar
#

thanks. Followup question, is there a way to configure the plugin so that it represents velocity per step? Otherwise, what's the most reliable way to convert from velocity per step to velocity per second?

vestal minnow
vague pebble
#

So I was trying to setup my server to be able to handle avian physics. I got this error related to the debug plugin I think.

#
impl Plugin for SharedPhysicsPlugin {
    fn build(&self, app: &mut App) {
        // Leafwing input plugin handles the whole leafwing shenanigans
        app.add_plugins(LeafwingInputPlugin::<CharacterAction>::default());

        // SETUP FOR MAKING OUR PHYSICS WORK
        app.add_plugins(
            PhysicsPlugins::new(FixedUpdate)
                .build()
                .disable::<SyncPlugin>(),
        );
        app.add_plugins(PhysicsDebugPlugin::default());
        // We change SyncPlugin to PostUpdate, because we want the visually
        // interpreted values synced to transform every time, not just when
        // Fixed schedule runs.
        app.add_plugins(SyncPlugin::new(PostUpdate));
        // Position and Rotation are the primary source of truth so no need to
        // sync changes from Transform to Position.
        app.insert_resource(SyncConfig {
            transform_to_position: false,
            position_to_transform: true,
        });
        // Setting timestep to same rate as fixed timestep hz
        app.insert_resource(Time::new_with(Physics::fixed_once_hz(FIXED_TIMESTEP_HZ)));
        // Setting up gravity
        app.insert_resource(Gravity(Vec3::ZERO));

        // Make sure that any physics simulation happens after the input
        // SystemSet (i.e. where we apply user's actions).
        app.configure_sets(
            FixedUpdate,
            (
                (
                    PhysicsSet::Prepare,
                    PhysicsSet::StepSimulation,
                    PhysicsSet::Sync,
                )
                    .in_set(InputPhysicsSet::Physics),
                (InputPhysicsSet::Input, InputPhysicsSet::Physics).chain(),
            ),
        );
    }
}
#

I encountered this panic
Resource requested by bevy_gizmos::update_gizmo_meshesavian3d::debug_render::configuration::PhysicsGizmos does not exist: bevy_asset::assets::Assets<bevy_gizmos::LineGizmo>
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace
Encountered a panic in system bevy_gizmos::update_gizmo_meshes<avian3d::debug_render::configuration::PhysicsGizmos>!
Encountered a panic in system bevy_app::main_schedule::Main::run_main!

#

Any ideas on what type of adjustment i need to do to my physics debug plugin gizmos to avoid this?

vague pebble
#

FIgured it out

#

app.configure_sets( FixedUpdate, ( ( PhysicsSet::Prepare, PhysicsSet::StepSimulation, PhysicsSet::Sync, ) .in_set(InputPhysicsSet::Physics), (InputPhysicsSet::Input, InputPhysicsSet::Physics).chain(), ), ); this is nono

bold garnet
#

there's an avian backend in bevy_mod_picking @vestal minnow

#

are you interested in taking ownership/splitting that out at some point?

vestal minnow
bold garnet
#

Great. Heads up, I'm going to try to do an end-of-life update to the existing avian backend, moving it to 0.15 but still using the legacy bevy_mod_picking version. We'll leave it to you to publish a version for the upstreamed picking version.

vestal minnow
bold garnet
obsidian maple
#

@vestal minnow Is the correct way to "pause" physics to set the timestep to zero in Time<Physics>?

vestal minnow
obsidian maple
#

Oh, maybe I'm to use with_relative_speed now to force the resource to be created

#

Er no, that can't be right

#

oh, I can use default

vestal minnow
obsidian maple
#

if you don't set the resource, what happens?

#

Basically that resource must exist to do pause / unpause

vestal minnow
#

It's initialized by the physics plugins

#

Or you can just .init_resource::<Time<Physics>>() if for some reason you need it before that

#

(or insert_resource)

obsidian maple
#

Does it use the value of the current fixed timestep by default? (btw, it works, I had an unrelated bug)

#

in other words, I'm doing this:

app.insert_resource(Time::<Fixed>::from_seconds(FIXED_TIMESTEP));
#

curious if it'll use that under the hood, or if i need to explicitly set it

vestal minnow
#

In fixed schedules, Time<Fixed>

obsidian maple
#

Awesome thanks ๐Ÿ™‚

vestal minnow
#

Np ๐Ÿ™‚

pseudo prairie
#

Hi! I am using spatial_query.cast_shape(...) and I need the point where the other collider is hit by the shape in local coordinates of said collider. I kind of thought that point1 of ShapeHitData is in local space of the collider but it seems to be in global space. At least that's what I think because when I subtract the Position/Transform of the collider from point1 I get the correct value.

That seems to be counter intuitive because ContactData works different where point1 and point2 are in their respective local coordinates. Is that intended or am I misunderstanding something? ๐Ÿ™‚

vestal minnow
#

Avian's docs are also wrong here atm but I have a PR open that fixes them

#

I might also rename point1 and point2 for contact data to local_point1 and local_point2 to be more explicit

#

I'll probably merge this tomorrow so people can use the main branch for the RC

#

I'll migrate internals to required components and add that picking backend in follow-ups

willow rune
#

I have to wonder why this is like this

vestal minnow
willow rune
#

yeah

vestal minnow
#

Parry represents capsules with two endpoints and a radius rather than just a half-height and radius

#

So the half_height getter is just a helper to compute the distance between those points

#

*half of the distance

willow rune
#

yeah ok it is just a getter cool ty

vestal minnow
#

So I'm now porting things to required components, and I feel like it'd be a good time to rework some of our defaults as well. Any opposition to making these components optional?

For RigidBody:

  • Friction
  • Restitution
  • ExternalForce
  • ExternalTorque
  • ExternalImpulse
  • ExternalAngularImpulse

For Collider:

  • CollidingEntities

I think the force-related components definitely shouldn't be required. They're not used by anything internally, and you rarely need them on too many entities. CollidingEntities also makes sense as something you need to add manually, although people might then have the issue of forgetting to add it, at least at the start. Either way, I don't think any of these should be "required". If people want to insert them automatically anyway, it'll be easy in 0.15 with runtime required components.

Friction and Restitution I'm least sure about, but I think instead of inserting them for every rigid body automatically, we should treat them as extra configuration, and default to globally defined default material properties (see #119). This would let each app specify its own defaults.

#

Later on I'd also like to split the RigidBody enum in some way to only require velocity and mass components for dynamic bodies

regal kindle
#

@vestal minnow Hi, hope you are doing great!
I am making rts game on bevy using Avian 3d. And at the moment I am facing one issue:

I cannot pinpoint a time when I need to run observer or system so that it run after certain collider has been initialised.

I need to run series of raycasts on level collider to determine buildable and not buildable positions, if ray hits level then its buildable, if it doesn't then its not buildable position.

Since its quite compute heavy task I need to run it only once - when the level collider has been fully initialized and ready to be detected by raycasts.

I have difficulty getting system/observer run in this point in time. So far I have tried both observer Trigger<OnAdd, ColliderMarker> and system Query<Entity, Added<ColliderMarker>> , with system I have tried to run it on different schedules like Last, PostProcessCollisions and others.

If you have time I will be very grateful if you could give me advise on how to approach this problem.
Thank you!

vestal minnow
#

Running anywhere after physics should also work, but it might be some issue where physics doesn't happen to run during the frame you added the collider and some values aren't initialized properly

regal kindle
#

It works with PhysicsSchedule .in_set(PhysicsStepSet::Last), thank you so much!!!! โค๏ธ

elder creek
vestal minnow
#

Yes, it'd mean you need to add it manually to query for it

#

That's how it is in bevy_rapier too

#

Adding it to every collider is mainly just unnecessary memory usage for entities you don't need it for, which usually is most of your entities

elder creek
#

Right, I get the motivation now!

elder creek
vestal minnow
#

Yeah. Like, you probably don't need CollidingEntities on all random objects in the environment, but just on specific entities

elder creek
#

Yep that makes sense

gaunt niche
#

#1302253308010037309 message
This is such a strange thing, maybe someone can advise something?
in short, the joints behave strangely when the parent is turned

alpine oak
cinder summit
vestal minnow
alpine oak
vestal minnow
#

IIRC the motivation was that this makes it easier to implement a custom voxel collider, right? Let's you access voxel data

cinder summit
alpine oak
#

however, as i'm typing this out I think that I can just use observers

#

to update data inside collider components

#

or smth

cinder summit
#

There's also that thing where avian probably needs to start using Assets at some point rather than having a big enum with weird Arc types from parry

vestal minnow
#

So you have a shared structure that stores voxel data, and need to access that in the collider methods

alpine oak
#

yea

vestal minnow
#

yeah, makes sense... I think it might require something context-like then

cinder summit
#

I don't think that PR can handle per-component vs world resource data correctly tho can it? ๐Ÿค”

#

Also wonder if there's some rust magic that can be done to remove that context arg entirely when the generics are ()

vestal minnow
#

Probably not, but we could technically have separate _with_context variants of the methods

cinder summit
#

Maybe make impl only for types with empty context that add the non-context version, then make it non-optional

#

Because empty context would probably always be wrong on colliders that need it

vestal minnow
#

Right, that'd probably be fine

alpine oak
#

this was more of a proof of concept

#

to get it working for my use case

#

i'd be happy to clean it up further if it'd be useful

vestal minnow
#

If it works for your use case, and you can't think of nice alternatives that'd work, I think I'd be fine adding something like this

#

I'd preferably like to keep the non-context versions for colliders that have an empty context, and also have the non-optional context versions, like Nise suggested

#

I wonder if something like the Fetchable collider idea from a while back could also work here somehow #1124043933886976171 message

alpine oak
#

probably?

spiral nymph
#

Set gravity scale to 0 and add an external force to entities in a query with filter ?

vague pebble
#

Yeah i could do that

#

I was just thinking how the gravity resource works

#

but it seens he directly affect velocity

#

Not entities with impulse as I expected

pulsar bone
#

Restitution::new(0.).with_combine_rule(CoefficientCombine::Min) Doesn't seem to be having any effect ๐Ÿค”
I'm dropping a rotation locked dynamic cube on a static cube, both with 0 restitution

#

This is caused by friction

#

Setting friction to 0 prevents any bouncing

vestal minnow
#

but not with default friction in this basic test

pulsar bone
#

Interesting, I've left the friction at the default. It does get worse if I raise the friction further

vestal minnow
pulsar bone
#

Let me test without locking the rotation

vestal minnow
#

I'm aware of the 3D friction implementation being a bit wrong (see #489) so I wouldn't be surprised if this is related

pulsar bone
vestal minnow
#

Yeah I get a small corner bounce with that too

fiery mortar
#

I have two questions:

  • what is the order of AngularVelocity?
  • why is AngularVelocity euler angles instead of quaternions?
vestal minnow
#

2D would be equivalent to Vec3::Z * rotation_speed

#

i.e. you're only rotating about the Z axis, the other axes project to zero

#

using a scaled axis makes computations much simpler / more efficient than having to deal with quats everywhere

#

I'm not aware of any engine using quats for angular velocity

#

Glam's Quat is also intended to be normalized

#

So it doesn't make sense to use for angular velocity. It's primarily for representing orientation

fiery mortar
#

Okay, that makes sense. I thought they were eulers cause I missed the comments on the AngularVelocity. ๐Ÿ™‡โ€โ™‚๏ธ

vestal minnow
#

The contact tangent directions for friction seem to be very wrong for the initial contact in a spinning case at least ๐Ÿค” lemme investigate

#

okay there's actually no way ferris_sob this fixes it

- let tangent_velocity =
-     relative_velocity + force_direction * force_direction.dot(relative_velocity);
+ let tangent_velocity =
+     relative_velocity - force_direction * force_direction.dot(relative_velocity);
#

god I love programming

#

I've tried debugging this friction bug on like five separate occasions and of course it ends up being a sign issue

#

FYI @pulsar bone ^ fixed it

#

I'll make a PR

pulsar bone
#

Nice!

vestal minnow
#

I'll run some more examples to test things though, this changes behavior quite a bit

#

since friction is now actually... like friction

pulsar bone
#

Yes, that would affect things ๐Ÿ˜„

vestal minnow
#

(the diff is misleading there because of snapshots, really it's a +2/-2 change)

#

I should really change our determinism tests to just produce a single hash that is compared between platforms instead of using these large snapshots

pulsar bone
#

I noticed something about how the cubes bounce when it lands flat on a side. Its biased to rotate towards the positive axes after it bounces
I.E. Dropping a cube flat with the default gravity makes the top of the cube turn diagonally, towards positive Z and X(Towards the camera and to the right)

#

Same for dropping it in the other gravity directions I've tested(X, -X, and -Z ), it always turns toward the positive axes

vestal minnow
#

Probably some bias in the order that Parry returns contact points for contact manifolds

#

For a cube landing flat, there can be 4 contact points, and they are solved sequentially

#

The order matters there, though more iterations can help make it less apparent

pulsar bone
#

That makes a lot of sense ๐Ÿ‘

vestal minnow
#

It's possible to make a block solver that solves multiple contact point at once without bias, but I've only seen it for two contact points, for more than that it quickly gets very complicated and expensive afaik

ocean monolith
#

Hello,
I am trying to switch away from rapier and made a test implementation
for top down car physics. I removed gravity, calculate the all
acting forces according to current energy. And then set the fixed
external force & torque each frame. No impulses. This works butter smooth
in rapier, but in avian I have these 'impuls' stutters. Besides the gravity, both
plugins run in default config. (1/60 step). Any idea, what could be the cause?

vestal minnow
ocean monolith
#

Its not a camera follow issue. The logic is the same in both test. Your suggested changes did improve the overall follow by a tiny bit. But the stutter still remains.

pulsar bone
#

@vestal minnow Could it be a lack of transform interpolation + the fixed timestep being one frame ahead/behind sometimes? IIRC avian actually does properly run in fixed timestep unlike rapier

cinder summit
#

If the FPS isn't exactly 60, or it only happens sometimes then it would be because of the fixed timestep yes

ocean monolith
#

You are right, that is the cause of the problem. On 60fps the stutter is gone. Demo runs on 164fps (vsync). I have to
look into avians schedule system. Thx alot, I was about to go nuts. ๐Ÿ˜…

vestal minnow
#

I'm adding built-in interpolation for Avian 0.2 though

pulsar bone
#

Thoughts on making collision started/ended events be observable ๐Ÿฅบ

vestal minnow
pulsar bone
#

A performant way to check whether there is an observer present would be nice

#

I'm wondering whether you could observe an observer being created for the collision events and then add a marker component automagically thonk

vestal minnow
#

The tricky thing is that each observer is its own entity, and they don't live on the target entity. But IIRC there is a way to get observers targeting an entity, and I think I managed to get something scuffed like that working a while ago

#

Lemme see if I can find it

pulsar bone
#

Hmm, Observer is type erased now :u

vestal minnow
#

Mm I found old code related to this but it's not doing the thing I was thinking about

#

Right, Bevy has this ObservedBy component but it's private ๐Ÿ™ƒ

#

It sure would be nice

#

Oh and there's still the issue that you need to figure out if there's an observer with the correct event

vestal minnow
#

lemme ask in #ecs-dev

cinder summit
#

Should the next release include something like

if rb1.is_added() || rb2.is_added() {
+    if !contacts
+        .manifolds
+        .iter()
+        .any(|m| m.contacts.iter().any(|c| c.penetration >= 0.01))
+    {
+        continue;
+    }
```or just finally ![yeet](https://cdn.discordapp.com/emojis/941199111422627891.webp?size=128 "yeet") the overlap warnings? ๐Ÿค”
vestal minnow
#

might need to scale by PhysicsLengthUnit?

cinder summit
#

Made a PR for each option, you previously mentioned 0.05 * PhysicsLengthUnit, so that's what the check version does

vestal minnow
#

Ah I see you made a bunch of PRs, thanks

#

I think I'll merge the yeet version, I don't really see a need for the warning anymore and it's easy enough to add on the user's side too if someone really wants it

#

the threshold is also kinda arbitrary

cinder summit
#

Yea, was planning to make just these two options, but then I realized I had some some fixes for {:?} locally too, and I ran into failing doctests and by the time I fixed them I realize they were unrelated to my change ๐Ÿ˜‚

#

At least in 0.15 the {:?} for Entity is a bit less awful, but it still looks a lot worse than {}

vestal minnow
#

Weird how CI is fine with the doc tests

cinder summit
#

Maybe it doesn't run them? ๐Ÿค”

#

If you pass something like --lib to cargo test it won't run doc tests for example

vestal minnow
#

It does look like it's running them

cinder summit
#

Oh ... Yea, that's very strange then ๐Ÿค”

#

Does it pull avian from crates and use that? ๐Ÿ˜‚

vestal minnow
#

I don't think so, it should be using the workspace's crates

#

The command it's using is currently

cargo test --no-default-features --features enhanced-determinism,collider-from-mesh,serialize,debug-plugin,avian2d/2d,avian3d/3d,avian2d/f64,avian3d/f64,default-collider,parry-f64,bevy_scene
#

I've also run it locally and tests pass fine

cinder summit
#

In my case I just ran cargo test -p avian3d -j 2 -- --test-threads=2

#

The -j and --test-threads is so doc tests and examples don't crash everything bavy

#

Might be a rust version thing tho, but I don't thinkg Type::default() should've ever been valid as a reference ๐Ÿค”

rich gazelle
#

Is there a commonly accpeted workaround to not having motor joints at the moment? Even a way to just set a joint angle manually by moving around entities?

#

Alternatively what's in the way of motor joints currently? I've love to contribute so if it's more a matter of getting it done I'd be happy to take a crack at it. But if it's requires changing the entire engine or knowing the deep magic I'd leave it to the main devs.

calm meteor
#

Hi everyone, I need some help ๐Ÿ™‚
Long story short, I made a custom schedule to run Avian on it because I need it to keep looping while the visual frames are rendering, because I need to communicate with an external controller in real time. I run that custom schedule in a loop in a world exclusive system until it gets a signal that rendering is done.

The problem with this approach is that the physics simulation suddenly became insanely fast. I assume this is because every time I run the schedule, Avian will advance the physics clock it uses internally by the delta of the real clock, which would be equivalent to the delta time of the full app loop instead of my internal real time loop.

How should one get around this issue? Should I try to replace the real clock with my own and then restore the original at the end of my system?

vestal minnow
vestal minnow
# rich gazelle Alternatively what's in the way of motor joints currently? I've love to contribu...

So, Avian's joints currently still use Extended Position-Based Dynamics (XPBD). There's an XPBD rigid body simulation paper that describes the "proper" way to handle joint motors with it. For revolute joints (i.e. hinges, see section 3.4.1), you essentially just have a target angle that you update at every substep based on a target velocity, and the joint applies a correction that attempts to match this target angle. I have a very old branch that largely implements this.

The main blocker though is that I'm in the process of overhauling joints to use a completely different impulse-based approach instead of XPBD. I'd be a bit hesitant to spend time or effort adding proper XPBD-based joint motors right now, when it'll likely need to be entirely rewritten for the joint rework. The rework is still pretty WIP, but I hope to have it ready for Avian 0.3 (not the upcoming release coming with Bevy 0.15, but the one after that)

#

For impulse-based joints, motors should be relatively straightforward to implement, but the joints themselves are quite complicated and a lot of work

rich gazelle
#

And the idea is that the release with impulse based joints will include motors or they'll be coming some time after that? If that's the case what the current timeline on that rewrite (days, weeks, months, or years). If it's more than a year away I might just try anyways since it could be nice to have an established interface when doing the rewrite so it wouldn't be completely wasted work.

vestal minnow
#

I intend to include joint motors in that release, yeah, along with some other improvements to joints. Accurate estimates are always hard, but I would hope to have the rework ready in anywhere from 1-3 months. I have revolute joints in 2D and 3D mostly working locally already, and once they're fully done I expect the rest of the joints to be a bit easier

rich gazelle
#

gotcha that's pretty soon so I think I'll leave you to it

#

thanks for your work!

vestal minnow
#

On the main branch you'd probably do what you're describing and replace the clock for the duration of physics, since physics uses the current schedule's active Time clock

vestal minnow
#

Which is a bit confusing, but... It's simpler on the main branch

#

You could also make your own scheduling by pausing the Time<Physics> clock (or rewriting PhysicsSchedulePlgin), and creating a system that manually advances time and runs the PhysicsSchedule

calm meteor
# vestal minnow (I'm assuming you're using 0.1 and not the main branch) You should probably set ...

Ah that's interesting, so basically I could just replace the Time<Physics> resource every time I run my custom schedule with the true delta?

Yes I'm on 0.1.2

What I did now was replacing Time<Real> with a fake version and advance it on each interal cycle with the delta calculated in the system. I guess this has the added benefit that it works for other plugins as well, not just Avian, however it is a lot more complicated then basically setting the physics delta.

I noticed that my dynamic bodies randomly jump around, could that happen if the delta is very close to 0 perhaps?

rich gazelle
#

I'm working on a robot simulator and I'm trying to use Avian but I'm having some difficult behavior. I'm constructing the robot from a URDF and I know I'm assembling it correctly but the moment I try to actually simulate anything it gets hairy fast. There's lots of stuttering and shaking and jumping around and it eventually just folds up. This might be a larger challenge of robotics simulation in general. I really should look into hoe Gazebo handles intersection and joints.

If anyone has the time my code is here: https://github.com/RunnersNum40/bevy_robotics

Things I have tried to fix this:

  1. Ignore collisions between links using collisions.retain
  • This doesn't seem to do much
  1. Turning the dampening on the joints up really high
  • Going from nothing to a lot makes a difference but it doesn't solve it
  1. Setting restitution to zero
  • Might make a difference but it's hard to say
  1. Increasing the substep count
  • This helped a bit but didn't solve it
  1. Removing gravity
  • No change
  1. Slightly scaling down the meshes
  • Bad idea for obvious reasons and it didn't work
  1. Increasing the resolution of the VHACD convex decomposition
  • Not much effect
  1. Locking all the joints be setting the angle limits to a small range or a single value
  • I don't think it did anything
  1. Many combinations of the above

If anyone has some advice I'd greatly appreciate it.

GitHub

Robotics simulation in Rust. Contribute to RunnersNum40/bevy_robotics development by creating an account on GitHub.

#

Okay update. When I remove the colliders entirely and keep the joints everything works fine (except collision detection of course). This is confusing to me because I assumed that 1. Ignoring collisions between links using collisions.retain would have made them a non-factor. Is it possible I'm misinterpreting what the function does?

#

This is the system that's supposed to prevent small intersections from mattering:

fn ignore_collision(mut collisions: ResMut<Collisions>, query: Query<&URDFCollider>) {
    collisions.retain(|contacts| {
        let entity1_is_urdf = query.get(contacts.entity1).is_ok();
        let entity2_is_urdf = query.get(contacts.entity2).is_ok();

        if entity1_is_urdf && entity2_is_urdf {
            collision_below_threshold(contacts, 0.01)
        } else {
            true
        }
    });
}

fn collision_below_threshold(contacts: &mut Contacts, ignore_threshold: f32) -> bool {
    contacts.manifolds.iter().all(|manifold| {
        manifold
            .contacts
            .iter()
            .all(|contact| contact.penetration >= ignore_threshold)
    })
}
#

Okay so one things that I wasn't doing that's made a big difference was having the ignore_collision system on the PostProcessCollisions schedule. I had it on Update so it basically didn't do anything.

#

That's solved a lot of my problem but I'm still a bit confused about how contact penetration works. I'm having a difficult time selecting a value that makes ignoring small intersections work correctly. They seem to vary in the 0.01 +- 0.005 range no matter what's happening. Does anyone have any insight into what the values mean? Should I consider a completely different metric?

calm meteor
#

@rich gazelle I have no answer to your questions, just wanted to say it looks really cool. I'm a robotics engineer and I'm trying to make a drone simulator. I think in case of Gazebo it doesn't actually simulate joints and joint motors, I'm pretty sure it just applies position or velocity updates to the "joints". Basically they can be treated as static bodies. Of course if you want "real" simulation which would allow collisions of the arm with itself or even ragdolling the arm that would be cool but yeah I'm not sure how to avoid this janky behaviour.

rich gazelle
#

So it doesn't actually deal with link intersection it just is based on the joint limits?

calm meteor
#

if I were you I would try to make the collision mesh smaller around the joints so they are clearly not touching. Two links will not move closer to each other anyway since they are rigit bodies rotating around each other over just one axis.

#

But it depends on what your end goal is with this project.

rich gazelle
#

Damn that makes me reconsider some choices here. I really like the idea of doing a proper simulation to get more accurate dynamics but I think it gets farther from real once things start exploding like this

#

My end goal is to be able to not use ROS but still have Gazebo

#

it's be nice to improve on it on the way

calm meteor
#

There are collaborative robots out there which go into a handmanouverable safety mode when they collide with something. That would be hard to do without modelling the dynamics

calm meteor
rich gazelle
#

I tried making the meshes smaller but the naive approach leads to more intersections since you start pulling some of them into each other if they aren't perfectly convex

#

I am making a Gazebo replacement, sorry for any confusing language

#

mostly for personal use but I just want to try doing an entire robotics project in plain Rust

calm meteor
#

Yeah that's funny we're doing very similar things. Alright I feel a bit bad about hijacking this thread ๐Ÿ™‚

rich gazelle
#

nah that's okay I stole yours

vague pebble
#

is there something similar to collision groups in avian?

vague pebble
#

Does avisn intend to make softbodies?

cinder summit
#

Jondolf has posted a soft body showcase in the past usin bevy_xpbd, haven't seen any soft bodies since however ... I think in theory it might be possible to add them manually on top too ๐Ÿค”

vestal minnow
#

There's a third party bevy_silk crate for cloth, but actual deformable solids are not on the near-future roadmap for first party features. Hopefully some day once everything on the rigid body simulation side is good enough

#

It's not too hard to make very basic soft bodies with just a mass-spring-damper model using joints though

dire cape
#

I remember there was some talk about adding a AnyCollider::Context associated type so that you can pass arbitrary world context down to colliders from the world. Previously this was implemented by @alpine oak (#1124043933886976171 message) where the context was a single extra component that may be included in the collider query. I've built on this and turned Context into a full ReadOnlySystemParam which you can access, and also give the AnyCollider access to its own entity ID, so it can read its own components from queries within that param.

Implementation here: https://github.com/oxkitsune/avian/pull/1
@vestal minnow Do you think this approach is suitable to be upstreamed into avian?

#

there's 1 safety comment which I think is actually safe, but I need to confirm with ecs folks

#

I think this resolves your concerns with having non-context versions though, since in that case colliders will just take () as context, which means nothing extra is queried

vague pebble
#

@vestal minnow Imagine the following, I have gravity setted up manually in my game, because it is networked. If my player is on ground, should I keep applying gravity in your opinion or nah? If the whole limitations of messages and such.

cinder summit
#

If you stop applying gravity when on the ground it's trivially easy to stop being on the ground, but not necessarily impossible when an object is stationary

vague pebble
#

well fudge

hexed veldt
#

What might caused the following error/panic?

thread 'main' panicked at ...\.cargo\registry\src\index.crates.io-6f17d22bba15001f\avian3d-0.1.2\src\collision\collider\mod.rs:327:9:
assertion failed: b.min.cmple(b.max).all()
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic in system `avian3d::collision::collider::backend::update_aabb<avian3d::collision::collider::parry::Collider>`!
Encountered a panic in system `avian3d::schedule::run_physics_schedule`!
Encountered a panic in system `bevy_app::main_schedule::Main::run_main`!
hexed veldt
#

I can re-prduce the above panic consistently. Since the setup has many objects/colliders running the same time, I wonder if there is anyway for me to debug which entity is causing the panic?

cinder summit
#

NaN in turn is usually caused by things rotating at very high speeds, denormalizing the rotation and making things quickly spiral out of control

hexed veldt
#

After some debugging, I noticed the object I spawned into the game has the following initial transformation (without angular rotation)

--------- pos Vec3(5.0, 0.0, 0.0) rot Quat(0.0, -0.0, 0.22975293, 0.97324896) s Vec3(0.6, 0.6, 0.6)

in the avian3d system avian3d-0.1.2/src/collision/collider/backend.rs#L495 update_aabb both Position and Rotation for the collider is NaN

Position(Vec3(NaN, NaN, NaN)) rot Rotation(Quat(NaN, NaN, NaN, NaN))

Then I removed the debug_assert! from the grow method and notice the game seems to be running fine, with the object colliding with other objects correctly. I wonder if this NaN only exist for the object after the initial setup, but then gets auto corrected into valid numbers?

#

Ok. Here is my question:

Where is the logic that added the initial Position component for the newly initialized Collider. I can dig into that deeper to understand why it is NaN

hexed veldt
#

I think I found the fix. I have a auto aim system that update the object orientation towards a moving target. The system was executed under Update schedule. When I change that system to use FixedUpdate schedule, now I no longer see the NaN in avian's update_aabb system.

Anyone knows why changing the schedule to FixedUpdate solves the issue?

cinder summit
hexed veldt
#

I don't know. What is the difference and how to configure it? Any best practice here?

cinder summit
#

It's configured based on the schedule passed to PhysicsPlugin, on 0.1.2 it's still PostUpdate, but if you'r on a newer git version it's FixedPostUpdate

#

The best practice is generally to use FixedUpdate so things aren't tied to FPS, but there are still some issues (which the default in 0.1.2 also has because it runs its own loop in PostUpdate, rather than just once per frame at a variable delta) like getting jittery movement when your frames and updates don't align perfectly. Which could be fixed with some interpolation, and there is a plugin for interpolation with avian, it's just not something you have by default iirc

hexed veldt
#

I noticed the objects move slightly slower on my macbook (120FPS) versus my windows (60FPS). The configuration on the objects are the same, with LinearVelocity applied. I'm using FixedPostUpdate schedule to run physics. Suppose Fixed schedule would make the movement the same on different frame rate right?

hexed veldt
#

BTW, I'm using avian 0.12. When I switch to PostUpdate for the Physics schedule, everything seems to work fine now. The movement looks exactly the same between 60 and 120 FPS.

#

The only issue I had with PostUpdate physics update is that when FPS drops lower (like 30FPS) things start moving slower again.

cinder summit
#

By default it currently is set up to run its own loop in PostUpdate, so the physics theirselves should run the same, but your own code might not run in-sync with physics, which can cause the results to be off

hexed veldt
#

Here is what I did, and it seems everything is working well now, for 30/60/120 FPS consistently.

  app.insert_resource(Time::new_with(Physics::fixed_once_hz(60.0)))
     .add_plugins(PhysicsPlugins::new(FixedPostUpdate),...
     ...
     .add_systems(FixedUpdate, keyboard_handle)

I learned bevy's FixedUpdate schedule is running at 64HZ instead of 60. I wonder if the above setup of 60.0 hz for physics would cause any issues? Does it need to match 64HZ?

cinder summit
#

Ideally it would match yes, you can either set FixedUpdate to 60Hz too, or set both to 64Hz

vestal minnow
#

Yeah in this case, if it doesn't match, I think the simulation would be slower/faster than real time

#

like if fixed_once_hz was configured to 10 Hz and Bevy's fixed update uses 64 Hz, it'd run physics whenever the fixed update runs, but advance physics time by the equivalent of 10 Hz every time

#

(which is 1 / 10 Hz = 0.1 s)

#

but yeah on the main branch it's different and simpler, stuff like fixed_once_hz doesn't exist, you'd just configure Time<Fixed>

rich gazelle
#

I'm doing my best to approximate joint motors with external forces and torques. Can anyone suggest the best schedule to run updates on? I've been using FixedUpdate but it would be nice if it could match the substeps so I can increase the accuracy if needed. I tried using avian3d::schedule::SubstepSchedule and avian3d::schedule::PhysicsSchedule but both cause a panic.

rich gazelle
#

Working revolute joint motor

rich gazelle
#

If anyone wants to take a look at a working implementation of motor joints I've made this plugin which allows velocity control of revolute joints

hot osprey
#

Hey, sorry, got a stupid question

I'm doing an rts selection system. Basic click on a unit and highlight it. I'm drawing boxes around units ala Starcraft.

Problem I have is I can't figure out the correct way to do it

The way I'm doing it atm is this

#

I decided to cache the mouse pointer info in a resource for reuse in multiple systems later on. I know events are probably a smarter way to do it but I just want something simple whilst I learn and mess around with things

I then get a point intersection using avian, with a collidable box

The problem I'm having after that is that I don't really know what to do with the entities themselves

#

Entities are set up like this. The idea is, click the entity, flag it as selected or unselected in some buffer somewhere, flip the visibility state of the child

#

Under normal circumstances in a game engine you'd just grab the entity and go to town finding its child. All I can think of is tagging the entity with a tag component of some sort and flipping it next frame

#

Any advice on how to deal with this and other similar problems coming out of SpatialQuery?

vestal minnow
# hot osprey Any advice on how to deal with this and other similar problems coming out of Spa...

If I understood your setup correctly, you should just get the Children of the selected entities, query for the ones that are selection boxes, and toggle their visibility. I think it's something like this

fn flip_selection_box_visibility(
    mouse_info: Res<MouseInfo>,
    mouse_buttons: Res<ButtonInput<MouseButton>>,
    mut q_selection_box: Query<&mut Visibility, With<SelectionBoxTag>>,
    children: Query<&Children>,
    mut commands: Commands,
) {
    if mouse_buttons.just_pressed(MouseButton::Left) {
        for &entity in mouse_info.selectable_entities.iter() {
            // Get child entities.
            let Ok(children) = children.get(entity) else {
                continue;
            };

            // Iterate over children that are selection boxes.
            // We can't use a for loop for `iter_many_mut` (I forget why)
            let mut iter = q_selection_box.iter_many_mut(children);
            while let Some(mut visibility) = iter.next() {
                visibility.toggle_inherited_hidden();
            }
        }
    }
}
vestal minnow
#

So I was looking at defaults for friction and restitution coefficients and combine rules across physics engines

  • Jolt: 0 restitution (max), 0.2 friction (geometric mean)
  • Box2D: 0 restitution (max), 0.6 friction (geometric mean)
  • PhysX: 0 restitution (average), 0 friction (average)
  • Rapier: 0 restitution (average), 0.5 friction (average)
  • Godot: 0 restitution (?), 1.0 friction ("rough" boolean)
  • Unity 2D: 0 restitution (max), 0.4 friction (geometric mean)
  • Unity 3D: 0 restitution (average), 0.6 friction (average)
  • Avian: 0.3 restitution (average), 0.3 friction (average)
#

(gotta love how Unity is inconsistent between 2D and 3D)

#

I think we should at least change the default restitution to zero, making bounciness opt-in

#

I think it might be good to increase the default friction too, maybe to 0.6 or 0.5

glacial nebula
#

probably good for default stability too, I imagine?

rich gazelle
#

In almost everything I do I add in the Restitution::ZERO

vestal minnow
#

Yeah, might help a bit

rich gazelle
#

so I'd like that default

vestal minnow
#

Then for combine rules, I'm not sure; the geometric mean sqrt(a * b) for friction is kinda nice since it means that the mixed friction is zero if either coefficient is zero, so e.g. everything can slide on "ice"

#

but it's still somewhat averaged otherwise

#

you can get that by just using CoefficientCombine::Min on the ice though... so I'm not sure if it's worth it

#

the current arithmetic average (a + b) / 2.0 is easier to reason about and think about in your head, so it might make sense to keep it as the default

#

especially for consistency with restitution, if we keep that the same

#

So I think the only thing left to figure out is what the default coefficient for friction should be, that's a bit more arbitrary

#

The current default of 0.3 feels way too slidey, and 0.6 feels like it's slightly too much

#

0.5 like in Rapier might be the sweet spot...

cinder summit
vestal minnow
#

Yes

cinder summit
#

Yea restitution probably should be 0 then, because having things bounce by default is kind of odd ๐Ÿค”

vestal minnow
#

Yeah I think I'll change default restitution to 0 and default friction to 0.5, but keep the combine rules the same for now

#

and Restitution will be optional (currently it's added automatically)

#

Now I'm not sure if I should make Friction required or not. Conceptually yes, but I'd like to have DefaultRestitution and DefaultFriction resources that let you configure the global defaults

#

Similar to Unity's default physics material

#

(side note, I love how in Unity it's "Physic material" in 3D but "Physics material 2D" in 2D)

#

Technically we could do physics materials as assets, which would let us require a physics material component with the default handle for every rigid body, and you'd be able to modify the default material's asset... But I've felt like it'd be more annoying to work with (without an editor) since you'd need to define assets just to specify friction and restitution for things

#

The other benefit would be that you can just change one material and have that change affect every entity using that material, but you could also just define constants for friction and restitution values atm, so changing it in code is pretty straightforward

cinder summit
#

Physics material as assets does sound nice but yes it does also sound kind of painful ๐Ÿ˜‚

thin hare
#

What is the best way to alter a colliders size at run time? Is it just updating the collider shape or is there a better way I'm not aware of?

vestal minnow
#

If you have other things like a mesh on the entity and you don't want to scale those, you can put the collider on a child entity and only scale that

#

Otherwise, yeah updating the collider shape would be the way

thin hare
#

I'll give that a go, thanks!

proven ice
#

what kind of physics body should i use for players?

cinder summit
#

There's no single correct answer, but at the very least static is probably the wrong choice ๐Ÿ˜‚

#

Kinematic bodies are used for kinematic character controllers, while dynamic bodies are used for physics-based character controllers like the common floating capsule character controllers

proven ice
#

thanks!

proven ice
vestal minnow
rich gazelle
#

What is the correct schedule to run systems that modify the physics on? Things that modify the torques, velocities, or positions.

vestal minnow
#

On the main branch, physics runs in FixedPostUpdate by default, and the intended place to run most logic like that would be before that, in FixedUpdate. Same as running things in _physics_process in Godot or FixedUpdate in Unity

#

In 0.1 physics is in PostUpdate by default, so it's a bit more annoying to run things at the same fixed timestep

#

There you'd run in PhysicsSchedule, with .before(PhysicsStepSet::Prepare) IIRC

#

Or, move physics scheduling to FixedPostUpdate kinda like the main branch

#

You can also run things inside the physics schedules or even the substepping loop if you really need to, but avoiding scheduling conflicts there is more annoying, and scheduling internals are prone to changes

cinder summit
rich gazelle
rich gazelle
#

If anyone's interested I've implemented really really basic motors for revolute joints https://github.com/RunnersNum40/avian_motors. The interface and naming is a bit rough because I've been prototyping a lot and changing things. I might work on cleaning it all up but if actual motors are coming soon I don't want to spend too much time on it.

#

It has PID based position and velocity control for revolute joint angles

#

I'd super appreciate if anyone has any suggestions for improvements

#

I'm also pretty new to rust so I've no clue how to setup the Cargo.toml so it's a usable library.

vague pebble
#

Question how can I acess the physics debug plugins gizmos, I need to insert a little bit of visual interpolation into them in my networked game

cinder summit
vague pebble
#

Once there are corrections and rollbaccks

cinder summit
#

With my rollback it's pretty easy, I just clear all the gizmos before new simulations so I get exactly just one set of gizmos matching the newest tick

vague pebble
#

Mind if I see how you do it, I dont even know how to acess the gizmmo itself

cinder summit
#

Ah it looks like I slightly changed what I do.
I run this system after any resimulation so only events from the real simulations get picked up

fn clear_collision_events(
    mut col_events: ResMut<Events<Collision>>,
    mut start_events: ResMut<Events<CollisionStarted>>,
    mut end_events: ResMut<Events<CollisionEnded>>,
) {
    col_events.clear();
    start_events.clear();
    end_events.clear();
}
#

I'd assume you otherwise access them trough the Gizmos<PhysicsGizmos> system param

bronze bronze
#

What is the/is there a recommended way of changing a collider's size at runtime? I'm trying to use it for collision detection on a basic 2d rts-style unit selection (rectangle that gets bigger with a mouse drag).

#

I tried using the ColliderConstructor, but it seems disappear upon the collider creation and adding a new one doesn't overwrite the previous collider.

sharp dew
#

is it ok to use CollisionLayers along with Sensors? i cant seem to get my player to collide with event triggers, but tile collisions ive set up with CollisionLayers in the same way work just fine

#

for reference, this (save for irrelevant bits) is how im spawning the triggers

commands.spawn((
    RigidBody::Static,
    Collider::rectangle(rect.width(), rect.height()),
    CollisionLayers::new([Layer::Portal], [Layer::Player]),
    Sensor,
    /* trigger components */
));
#

and the player:

commands
    .spawn((
        RigidBody::Dynamic,
        LockedAxes::ROTATION_LOCKED,
        Collider::capsule(4.0, 8.0),
        ShapeCaster::new(caster_shape, Vector::ZERO, 0.0, Dir2::NEG_Y)
            .with_max_time_of_impact(1.0),
        Friction::ZERO.with_combine_rule(CoefficientCombine::Min),
        Restitution::ZERO.with_combine_rule(CoefficientCombine::Min),
        ColliderDensity(2.0),
        GravityScale(2.5),
        CollisionLayers::new([Layer::Player], [Layer::Wall, Layer::Portal]),
    ))
#

I can detect every other collision with EventReader<CollisionStarted> just fine

sleek thicket
sharp dew
sleek thicket
#

@sharp dew how are you checking that it's getting hit? maybe you just forgot to use the system D;

sharp dew
#

hideous but here it is

fn portal_detection(
    mut reader: EventReader<CollisionStarted>,
    player_query: Query<Entity, With<Player>>,
    portal_query: Query<Entity, With<Portal>>,
) {
    for CollisionStarted(e1, e2) in reader.read() {
        for portal in portal_query.iter() {
            if let Ok(player) = player_query.get_single() {
                warn!("collision detected between entities {e1} and {e2}");
                // if one of the entities is the player and the other one a portal
                if (*e1 == player || *e2 == player) && (*e1 == portal || *e2 == portal) {
                    warn!("portal collision detected");
                }
            }
        }
    }
}
#

the first warn! between the player and collision tiles works just fine, but nothing appears when i should be colliding with the triggers

#

just found out about CollidingEntities but that didn't give me any results either

sleek thicket
#

^ this is basically what i have

sleek thicket
# sharp dew hideous but here it is ```rust fn portal_detection( mut reader: EventReader...

i can't see what's wrong, but i cleaned it up a little

fn portal_detection(
    mut reader: EventReader<CollisionStarted>,
    player_query: Query<Entity, With<Player>>,
    portal_query: Query<Entity, With<Portal>>,
) { let Ok(player) = player_query.get_single() else { error!("no player?"); }
    for CollisionStarted(e1, e2) in reader.read() {
        let (player_e, other_e) = if *e1 == player { (*e1, *e2) }
                             else if *e2 == player { (*e2, *e1) }
                                else { continue; }

        for portal in portal_query.iter() {
            if other_e == portal { warn!("success"); }
        }
    }
}
sharp dew
#

oh my god.

i just. forgot to add a transform to the portal spawn. groaaaaan.

#

the examples are still super useful to me, tysm!

sleek thicket
#

doesn't it just spawn at 0 without transform?

sharp dew
#

guess so but i had no way to collide with it with the layout i have

vestal minnow
#

Spent most of today trying to set up a testbed that would allow running all the 2D or 3D examples at once, and also added a way to reset examples. Only implemented it for two examples so far to just get it working

#

The goal is to have a similar thing as Box2D's demos, with a bunch of samples you can run, with UI for lots of configuration options

#

The tricky part is that I still want the examples to be useful for demonstration purposes and showing off APIs too, and you kinda have to set things up in a specific way so the tesbed can also run them

#

Right now I just create a struct for each example that defines the system configurations and the name of the example

pub fn main() {
    App::new()
        .add_plugins((
            DefaultPlugins,
            ExampleCommonPlugin,
            PhysicsPlugins::default(),
            MoveMarblesExample.plugin(),
        ))
        .run();
}

pub struct MoveMarblesExample;

impl PhysicsExample for MoveMarblesExample {
    fn name(&self) -> &str {
        "Move Marbles"
    }

    fn setup(&self) -> SystemConfigs {
        setup.into_configs()
    }

    fn fixed_update(&self) -> SystemConfigs {
        movement.into_configs()
    }
}
#

Ideally you could just use a plugin directly, but the testbed needs to add additional run conditions (or swap/reset worlds and schedules somehow, which I don't think is possible)

#

I think it's probably fine like this, the scheduling is rarely the focus in examples anyway, and in cases where it is, we can just have those be "normal" examples that aren't available in the testbed

vestal minnow
cinder summit
vestal minnow
#

I think technically you could just have the examples in a separate crate that uses both crates... you'll have all the type names duplicated tho

rough nebula
#

Is there a way to exclude an entity from collisions?

cinder summit
#

I think your options would be collision post processing and making the collision layers not match

vestal minnow
#

I'll go over it again tomorrow and probably add a 2D example, it's getting really late here

#

(FYI @glacial nebula @bold garnet ๐Ÿ™‚)

cinder summit
vestal minnow
#

...good point lol

#

lemme change that

cinder summit
#

It's also around for bevy_math for some reason

vestal minnow
#

Doesn't seem like it's exposed for bevy directly

vestal minnow
#

Begone unnecessary huge PR diffs and manual snapshot generation!

#

let's see if CI passes

#

also fixed some pretty nasty and obscure bugs I found

cinder summit
vestal minnow
rich gazelle
#

Is it possible to apply an external torque around a specific point?

glacial nebula
#

if you rely on bevy + features, your plugin can't start building until bevy and all transitive deps have finished building, even if your plugin only uses one tiny part of bevy

cinder summit
fleet field
#

hey all, wondering if anyone has experienced little "hops" with dynamic character controllers in avian3d. basically, whenever my character moves horizontally when standing on flat ground, it gets some upward force. I don't have anything fancy setup, basically just the dynamic character controller example. I thought I'd ask here in case this is a known quick that is easily solved

sleek thicket
fleet field
#

I see. I am just stepping away from using bevy_tnua's floating character controller as it wasn't playing well with lightyear... Is a hovering collider builtin to avian directly which I can use?

fleet field
#

ah okay, thanks. I'll look into that!

sleek thicket
#

and man, those 2 videos overshadow their actual game so hard it's strange that they didn't just convert into a tutorial channel ๐Ÿคฃ

fleet field
#

haha. their tutorials seem very well done

rough nebula
#

What exactly is the heightfield collider?

vestal minnow
#

A grid with a given height for each cell, useful for things like terrain

rough nebula
#

Oh i knew what a heightmap is, didnt know you could just do that

little maple
#

I'm working on optimizing my game a bit. I did a profile and am just wondering as this isn't something I've looked at to deeply before..

assuming I have several dynamic rigid bodies with cuboid colliders that I'm applying impulses to, is there anything I can do in "user code" to optimize this (it's a screenshot of the physics part of one frame) or is this pretty typical?

vestal minnow
#

Reducing the SubstepCount down from 6 can also help, but at some point it'll hurt stability

little maple
vestal minnow
#

It could maybe help slightly, but the broad phase already filters out entities whose AABBs aren't intersecting, so if they're far away they already shouldn't have collision checks

#

Optimizations for the solver are planned, but I keep getting other important (or more fun) things to work on :/

little maple
rough nebula
#

Second stupid question, do physics work for entities in different plugins?

vestal minnow
#

What do you mean by entities in different plugins? Entities don't belong to plugins, they just belong to... the ECS

rough nebula
#

Spawned in a different plugin*
I figuered it wouldnt but i am noticing it wasnt working so maybe i did something wrong

slim ledge
#

I have a stupid question too: can I define the rotation of a fixed joint between 2 dynamic bodies? I changed their Transform rotation but they keep sticking to each other with default rotation

vestal minnow
#

Haven't merged it yet since I need to verify that it works in 3D, and this also kinda overlaps with the joint overhaul I'm working on (among many other things, it should support proper "local frames" for joints, i.e. anchor offset + rotation offset)

#

A simple workaround that could maybe work depending on the use case is to instead use a child entity for the thing you want to rotate, and keep the parent rigid body as is

#

Ideas and feedback welcome!

slim ledge
sleek thicket
rough nebula
#

Ok but wtf, i can see the colliders exist through the debug wireframe, run into them, no collision

#

Although only for trimesh, other shapes seem to work just fine

opal moth
#

Hello, is avian2d have only event but not really collision collider?

rough nebula
#

Genuinely have no idea what could be causing this

blazing sluice
#

Hey guys, glad to see the Avian project is going well. I've just upgraded my codebase from 0.13 to 0.14, and xbpd still works great, so thanks for at least supporting it into 0.14. What's the transition like from xbpd to avian? Any big changes I should be aware of going in?

little maple
vestal minnow
#

The next release (coming after Bevy 0.15) also has a decent amount of changes, there'll be a migration guide and post for those too

rough nebula
opal moth
#

Hello, is avian2d have only event but not really collision collider?

#

I create a bullet for attack detection but it really collision.

vestal minnow
# opal moth Hello, is avian2d have only event but not really collision collider?

I'm not sure if I understood exactly what you mean, but:

  • A Collider on its own currently only detects collisions and sends collision events like CollisionStarted. Objects can go through colliders with no "collision response".
  • To enable "collision response" for a Collider, make it a RigidBody. That way, dynamic rigid bodies can bump into it.
  • If you want a RigidBody that has a Collider but does not have collision response, you can add the Sensor component. This makes it behave like a standalone Collider again, but with the other features of rigid bodies.
opal moth
#

Thanks for reply, Sensor works for me.

#

But i got tons of message

Dynamic rigid body Entity { index: 0, generation: 2 } has no mass or inertia. This can cause NaN values. Consider adding a `MassPropertiesBundle` or a `Collider` with mass.
#

It's really a Collider:

.insert(RigidBody::Dynamic)
.insert(Collider::circle(4.))
.insert(CollisionLayers::from_bits(
    ATTACK_DUMMY_GROUP,
    NORMAL_COLLIDER_GROUP & !ATTACK_DUMMY_GROUP,
))
.insert(Lifetime(5.))
.insert(YSort::default())
.insert(Sensor)
.insert(LinearVelocity(
    fire_direction.truncate().normalize() * bullet_speed,
));
#

What I did wrong?

vestal minnow
# opal moth What I did wrong?

Unlike normal colliders, sensors currently don't get mass automatically since they're not really physical "things", just shapes for detecting intersections in some area. A common use case could be detecting when the player enters some area, or is close to a door, which doesn't need mass.

Dynamic rigid bodies do need mass though. You could add it manually like this:

.insert(MassPropertiesBundle::new_computed(&Collider::circle(4.), 1.0))

which basically computes the collider's mass based on the shape with a density of 1. For colliders that aren't sensors, you don't need this

#

Also FYI, if the bullet is moving very fast, it could be better to use ray casts or shape casts than colliders. Depends on what kind of bullets they are though, and what behavior you need

opal moth
#

Thank you very much, this knowledge will be very helpful for me to develop other kinds of skills.

cinder summit
vestal minnow
cinder summit
#

Oh, so it's like a kinematic body that also doesn't push thing?

vestal minnow
#

not kinematic since it's still controlled by physics, but it just passes through things

#

Sensor just disables the contact solver essentially (and automatic mass computation)

#

and in the future it likely wouldn't compute actual contact data, but just do cheaper intersection tests

hot osprey
hot osprey
#

I didn't even think to try using queries with simple lists of entities

#

Now that I think about it, it's stupid I never even considered how the engine itself would be doing the selection of entities ๐Ÿ™‚

#

Thanks so much

last forge
#

Hey again! things are (almost) working to get my balloon simulation off the ground. I'm having trouble with external forces though.

  1. If I have my systems force.set_force(my_vec3) on the ExternalForce every physics tick, the force accumulates over time.
  2. If I add additional ExternalForce components to the entity, the magnitudes are correct but the object does not move.

It's not exactly clear to me when I should set_force vs apply_force. If I understand it right I'd want to apply_force to make it act in world space, and set_force to change the vector thereafter.

Driving me crazy. Attached a snippet similar to what im working with if you're curious.

#

I put in logs to show that when the new ExternalForce is added it is indeed running the apply_force and then running set_force each physics tick after that. The main ExternalForce component on the plugin is still zero but I thought that additional forces would be summed to the dynamic body

2024-11-14T02:27:53.430373Z  INFO yahs::simulator::forces: applied new buoyant force: Vec3(0.0, 0.0, 0.0)
2024-11-14T02:27:53.430394Z  INFO yahs::simulator::forces: applied new weight force: Vec3(0.0, 0.0, 0.0)
2024-11-14T02:27:53.457624Z  INFO yahs::simulator::forces: updated weight force: Vec3(0.0, -53.10969, 0.0)
2024-11-14T02:27:53.457619Z  INFO yahs::simulator::forces: updated buoyant force: Vec3(0.0, 50.412033, 0.0)
rough nebula
#

Is impulse and force impersistent practically the same thing?

vestal minnow
#

I want to rework how forces and impulses work though. Imo it doesn't make sense to have "persistent impulses", and no other engines have them

#

(I have a rough proposal for a new approach here)

vestal minnow
#

apply_force adds a new force on top of the existing forces, set_force sets the total force to a specific value

#

IIRC the forces are currently persistent by default, so you need to manually clear them, but you can also set persistence to false, and they'll be cleared automatically every frame

vestal minnow
little maple
ocean monolith
#

To me it looks like a interpolation error. The stutter does not feel linear. But that's just a wild guess.

little maple
#

I thought it was related to schedule ordering + fluctuating frame rate

last forge
# vestal minnow Here it looks like you're not updating the actual `ExternalForce` component of t...

Okay, so the only way to move the body is to update the external force component created with the rigid body and other external forces are ignored? I thought avian would sum all external forces attached to a rigid body. I'm coming from an engineering background so I drew the force diagram and added all the force vectors.

Not to hard to add a system to do that myself. Feels like I am doing the Shrek walking through the velvet rope thing though. https://makeagif.com/i/yI54VY

What is the "avian" way to handle summing a bunch of independent forces like this? I guess the answer is to have only one system that sets the net force, not one system for each contributing force.

glacial nebula
#

I guess the answer is to have only one system that sets the net force, not one system for each contributing force.
Forces can be summed, you could reset the external force on your entity at the start of every update, then add forces to it from multiple systems throughout the update.

little maple
little maple
ocean monolith
last forge
#

Awesome thanks all this got me out of my thought spiral! Hopefully I'll have a cool demo to share when I get it working

noble pier
#

Did you every figure out the cause? Noticing the same issue with half-space and non-half-spaces.

vestal minnow
#

FYI that warning has been yeeted on the main branch

vestal minnow
# little maple I was about to ask this exact question and make almost the exact same video is ...

Most likely it's mainly just what Tim and Nise said. Since physics uses a fixed timestep (60 Hz in 0.1, and Bevy's 64 Hz on the main branch), it can sometimes run once per frame, and sometimes skip frames depending on the screen refresh rate. The solution is to use transform interpolation to visually smooth out the movement between fixed timesteps, but this isn't built-in yet. It should be in the next release though, and I also have a bevy_transform_interpolation crate (somewhat experimental)

#

You can also (1) increase the fixed timestep rate to match the refresh rate, or (2) use a variable timestep, but (1) can be more expensive at high refresh rates, and also makes behavior dependent on the frame rate, and (2) is even worse in terms of determinism, and can make behavior wonky if FPS is inconsistent

little maple
#

I may go with 2 after checking out that crate because what in life is determined anyway amirite

vestal minnow
#

after Bevy 0.15 releases

#

or the main branch is already 0.15-compatible

little maple
#

oh so the fix is already in avian main?

vestal minnow
#

No, interpolation isn't on main yet, but main uses the Bevy 0.15 RC so it's "ready" in that sense. I want to add a few more things though before release (like the interpolation)

little maple
#

got it ๐Ÿ‘ cool

vestal minnow
#

I might also make a release just for the 0.15 migration without the other changes to ease migration but I'm not sure yet... It's a bit of a pain to do lol

little maple
vestal minnow
#

PostUpdate is also fine still, as long as it's before transform propagation

cinder summit
#

I tend to use PostUpdate for purely visual stuff, which cameras often are not, since pointing the camera at something usually has some non-simulation impacts like highlighting things or whatever

#

Also lerp in a variable delta context is wrong, but iirc 0.15 should have that thing mweatherley added

vestal minnow
#

yeah stable interpolation with smooth_nudge would be what you actually want

little maple
#

hmm, maybe I should upgrade and then come back to this. Does there happen to be example code of like.. even an opinionated way to avoid the stuttering?

cinder summit
#

The opinionated way is using the interpolation

#

And a pretty popular opinion at that

vestal minnow
#

I've been chewing on the interpolation stuff for a couple of days again, and experimenting with making bevy_transform_interpolation work nicely for it (e.g. support alternative component sources for start and end states, like PreviousRotation and Rotation in our case). For now, I think I won't use it for Avian though; making things properly generic is kinda tricky, and my approach there doesn't work well for transform extrapolation.

#

Instead, I'll probably just add PhysicsInterpolation and maybe PhysicsExtrapolation components to Avian, and tailor it just to physics entities. It's simpler and likely more efficient, and technically we could also take e.g. velocity into account for more accurate interpolation, which requires physics integration anyway

#

Of course people could still use bevy_transform_interpolation for general interpolation too if they wanted, since it works for any entity with a Transform

slim ledge
#

Considering Avian doesn't support motors and supposing I set a joint-based car up (1 chassis, 4 axle joints each with 1 wheel joint), how should I propel my car? Should I just add some ExternalForce (not torque) to each wheel? Or to the chassis? Other approaches? Or should I just drop it all...

grizzled depot
vestal minnow
#

And yeah extrapolation needs velocity so that needs physics integration anyway

#

In practice I would also expect at least 95% of things that really need to move at a fixed timestep to be physics entities, so I'm not sure how useful fully general transform interpolation would be

#

That being said, I've seen interest in adding more general interpolation support to Bevy itself eventually (not just for transforms afaik), and if/when that's a thing, we can consider if we can make use of it too. Though I'd still expect physics to want some of its own logic

sleek thicket
#

even if it's not useful, it just makes sense to have
like if you eventually run into a case where you want something without physics in fixed update and then realize that you have to deal with transform being choppy, just using the usual approach is just nice

void dragon
#

Quick question, because I swear I have seen it somewhere. Can I create a collision mesh from an imported mesh? If so how?

vestal minnow
void dragon
#

Yes that was it! Thank you!

vestal minnow
#

I agree it'd be nice to have in theory though

sleek thicket
#

physics or movement could be done server-side and clients would just receive positions with regular intervals

vestal minnow
#

I feel like you might want something more custom for that, and it's something that the networking library would handle instead of the user (like lightyear iirc), but I know close to nothing about netcode so idk

sleek thicket
#

i guess games without any physics in the first place would also benefit from that a lot

vestal minnow
#

built-in transform interpolation is a physics-only thing in both Godot and Unity fwiw

#

and if you want it otherwise, just manually lerp/slerp where necessary

sleek thicket
#

hmmm... yeah, maybe it's worth adding that question and link to discussion right in the docs

#

but intuitively it just seems like a good idea to have a common way to interpolate transforms with movement systems stuck in fixedupdate for any reason

rocky seal
#

i just dropped TransformationInterpolationPlugin into my app and it works great, thanks @vestal minnow

glacial nebula
vestal minnow
#

So, only transform changes in fixed schedules get interpolated, and only if you don't also change transforms in non-fixed schedules

glacial nebula
#

Wouldn't that mean that when crossing from one cell to the next, the object would jump/not interpolate?

#

i.e. when the object teleports its Transform

vestal minnow
#

Possibly, yeah

#

It's only for the remainder of that one fixed timestep but might still be a bit annoying, hmm

glacial nebula
#

what approach were you planning on taking for integrating with big_space?

#

iirc we had very different approaches in mind

vestal minnow
#

I'd probably try your idea of physics islands

#

I'm not sure how well it'll work with the current architecture in terms of running physics in parallel for different islands, but we'll need to rework things anyway to do that for actual simulation islands

#

Also need to consider how this will work together with simulation islands

#

I guess technically these physics islands would already be a simpler form of simulation islands :p just based on proximity (I think?) and not constraints

#

Hmm you could probably parallelize simulation island building based on these proximity-based Islands

vague pebble
#

@vestal minnow A funny thing is ocurring with my collision layers when inside a collider that you can collide with, and I add a impulse force my character just jumps way higher

#

Here is a sample

vestal minnow
# vague pebble Any ideas on what causes this ๐Ÿ™‚

How do you determine if the character can jump, and apply the jump impulse? It's hard to tell what the problem is, but it kinda looks like the impulse strength is doubled, so intuitively I would guess that maybe it detects both the ground and the other character as entities you can jump on, and then tries to jump on both of them for some reason

#

which would add the jump impulse twice

#

I'm just guessing based on what it looks like though

vague pebble
#

I think I already see the mistake

#
// Handle jumping.
    if action_state.pressed(&CharacterAction::Jump) {
        let ray_cast_origin = character.position.0
            + Vec3::new(
                0.0,
                -CHARACTER_CAPSULE_HEIGHT / 2.0 - CHARACTER_CAPSULE_RADIUS,
                0.0,
            );

        // Only jump if the character is on the ground.
        //
        // Check if we are touching the ground by sending a ray from the bottom
        // of the character downwards.
        if spatial_query
            .cast_ray(
                ray_cast_origin,
                Dir3::NEG_Y,
                0.01,
                true,
                SpatialQueryFilter::from_excluded_entities([character.entity]),
            )
            .is_some()
        {
            character
                .external_impulse
                .apply_impulse(Vec3::new(0.0, 5.0, 0.0));
        }
    }
#

I forgot the spatial query filter

vestal minnow
#

Might also want to use just_pressed to only apply the impulse once? I believe pressed is true for every frame the button is held down

vague pebble
void dragon
#

I am trying to create a kinematic character controller, and for the collide and slide algorithm I need the distance between the projection and hit.

vestal minnow
#

It's most likely getting renamed to just distance soon

void dragon
#

that is much more intuitive. thank you

#

is it 1:1 to vec3 distances? so a distance of 1.0 is the same as vec3(0.0, 0.0, 1.0).length()?

vestal minnow
#

Yep

void dragon
#

May I ask if this is something that you come home from work and do? Did you have another big project in a physics engine before bevy?

vestal minnow
#

I don't currently have a job, but I'm a first-year university student, and yeah I do this mainly as a hobby

void dragon
#

No way. How old are you?

vestal minnow
#

I didn't have prior experience with physics simulations before I started making physics stuff for Bevy, I mostly did web dev, some mobile development, tinkered with several languages and technologies, and occasionally did some stuff in Unity and Godot

vestal minnow
void dragon
#

Man I am 20, you make me feel obsolete. What are you studying in uni?

#

Dont take it the wrong way but I thought you are some 30 year old guy with 2 bachelors in computer science and a master in physics just cuz its fun.

#

(2 bscs of course I am joking)

vestal minnow
#

(I'm from Finland)

void dragon
#

I am from Hungary

vestal minnow
#

I'll take that as a compliment

void dragon
#

This is so crazy. You will have the easiest time finding an internship.

fiery mortar
vestal minnow
gritty estuary
vestal minnow
#

haha thanks ๐Ÿ˜…

gritty estuary
#

I'm the same age as you but I'm very far from making a physics engine ๐Ÿ˜…

vestal minnow
#

Eh, I started by just copying a tutorial, and it took a long time and struggling with papers and math before I actually understood how things generally worked (and I still don't fully understand a lot). It's a ton of incremental learning and researching into what other engines do, and I feel like I'm still in the lower end of the learning curve

#

I've technically been working on this stuff for over two years now, though actively about one and a half years probably

#

the first commit in the repo is from May 29, 2022, although I remember playing around with Verlet integration and watching YT videos on physics simulation stuff before that

gritty estuary
#

It's literally impossible for me to work on my project and study at the same time. I can only work efficiently on my project during the vacations...

gritty estuary
#

learning physics is tough so making an engine sure is

vestal minnow
#

development through the last year of high school with matriculation exams going on was pretty rough ๐Ÿ˜…

void dragon
#

nah the impressive stuff the understanding papers at 19

#

that's a highly appreciated skill

vestal minnow
#

As far as papers go, it's not too crazy, the algorithm is outlined pretty clearly, everything is in pretty self-contained sections, and the formulas are relatively simple (though I didn't understand a lot of them at first)

#

I've definitely seen some papers that are a lot more unreadable with my math knowledge though lol

void dragon
#

at 19 years old.

proven ice
#

is there any way i can toggle physics simulation of entities and then resume them?

#

i'd like to make a system for volumes where physics is allowed; if anything is outside a physics zone, it will pause that entity until physics in that area is permitted.

vestal minnow
proven ice
# vestal minnow For now, you could probably just add/remove the `RigidBody` component, or make t...

alright, i see! i should probably explain why i want this - i'm doing a minecraft clone (bc there aren't enough already) and want to generate a small mesh around physics bodies for collision (from the world geometry / voxel data).

could i just make the system for updating these collision meshes run before physics systems to ensure simulated objects don't go too fast, leave their calculated collision zone, and fall through / clip into the world?

vestal minnow
proven ice
#

can avian efficiently handle collisions with larger collision meshes? does parry spatially partition collision meshes?

vestal minnow
#

Yeah, it uses a Bounding Volume Hierarchy (BVH) for each trimesh to partition the triangles. Not super fast but pretty decent afaik. I think it's mainly slow if you have a ton of small triangles densely packed together, since then you might be intersecting all of them at once and get way more hit tests than normal

proven ice
# vestal minnow Yeah, it uses a Bounding Volume Hierarchy (BVH) for each trimesh to partition th...

oh, okay! thats great, because i can just generate the collision mesh for entire chunks at once.

there's a problem in many physics engines (including avian) where things sliding along touching / flush (but separate) faces will hitch. to solve this, i would probably merge contiguous chunk meshes. but how would i unmerge when the chunk unloads? do i need to store all the chunk meshes and the combined mesh so i can recombine them upon chunk unloads (without having to remesh everything)? i cant think of a way to solve this without doing really hacky stuff with caching and tagging regions of mesh data to specific chunks and then deleting those regions when chunks unload. there's gotta be a better way.

so ig my question is: do you know of a solution to the hitching problem?

(btw im talking about collision meshes here)

little maple
little maple
#

Edit: I think I'm just going crazy over frame rate inconsistency so ignore this

I'm trying to get to the bottom of this stutter in my game. This is a really simplified example where I have a cube spawned with a linear velocity, zero gravity, a camera following it with an offset on after(PhysicsSet::Sync).before(TransformSystem::TransformPropagate). I'm using the bevy_transform_interpolation crate and have time set with Time::from_hz(120.0) and running in release mode.

and to me, I still see these random stutters... do y'all see it too? Is this enough to rule out that it's caused by the physics engine?

fiery mortar
# vestal minnow So are you trying to implement a kinematic position-based character that has `Po...

Basically, yes. I've got this working perfectly fine in an minimal example, but in my actual game the angular velocity is not applied in full.

pub fn log_system(
  physics_time_r: Res<Time<Physics>>,
  mut player_character_q: Query<
    (&Transform, &AngularVelocity, &Rotation),
    With<PhaseTagComponent>,
  >,
) {
  for (transform, angular_velocity, rotation) in player_character_q.iter_mut() {
    debug!(
      "{:?}+{}={}?",
      transform.rotation.to_euler(EulerRot::YXZ).0,
      (angular_velocity.0 * physics_time_r.delta_seconds()).y,
      rotation.0.to_euler(EulerRot::YXZ).0
    );
  }
}

This gives me outputs like -0.7853124+3.1415927=2.2909148? and then 2.2909148+0.06528074=2.3562312? . It seems to simply not being applied in full and takes two steps to apply the velocity.

Which is strange, because I have a minimal app with the same implemetnation and it works just fine.

void dragon
void dragon
#

I do not have an example, because I have never seen anything like this, but I think it could be done.

little maple
void dragon
#

So this is a dynamic controller and not a kinematic?

little maple
void dragon
#

Ah okay I hoped that it is kinematic :D

little maple
void dragon
#

I want to create my own, and I have tried understanding tnua but I just couldn't.

#

I am having some weird behaviour currently. I will probably fix it sooner or later. It would have been faster if I could ask someone.

little maple
void dragon
#

Yeah but it is not what I am looking for.

wide oar
#

hey how do I get rid of these messages if I am juz spawning a bunch of static colliders that is closesly together (they are not overlapping actually)

WARN avian2d::boom::narrow_phase: Entity { index: 451, generation: 1 } and Entity { index: 502, generation: 1 } are overlapping at spawn, which can result in explosive behavior.

sleek thicket
wide oar
sleek thicket
cinder summit
#

Yea, static-static doesn't even get to the plugin that produces that message, there were some bugs that made them show up with kinematics tho, despite the fact that kinematic bodies can't produce explosive behavior because they have no collision responses

#

Idk if the fix for that ever got merged

wide oar
#

I am still in version 0.1 tho, not sure if I should upgrade? but I am using also leafwing 0.14 and bevy 0.14

sleek thicket
#

i'd wait for 0.15 first, it shouldn't be that long now

#

but i don't think version matters

wide oar
#

I see, I will dig into the source code I guess ๐Ÿคฃ

sleek thicket
#

just remove rigidbody from terrain and see if it still shows messages

wide oar
#

alright lemme test

wide oar
#

tho does it still collide

sleek thicket
#

yeah, you only need RB on the thing that moves

wide oar
#

oh yeah I will do that

#

so the colliders doesn't need one?

sleek thicket
#

if they're static, and not sensors, no

wide oar
#

I see, that' s neat

#

ill try it out!

sleek thicket
wide oar
little maple
#

is it possible for avian to skip applying impulses for a frame?

I have an Update system "A" that applies an impulse to an entity
and a PostUpdate after PhysicsSet before TransformPropagate system B that reads the transform

and sometimes I'll get a frame where the transform in those two systems is the same and it's also the same when system A runs on the next frame

Edit: I believe what might be happening is since System A is on Update, if a frame takes longer than the fixed update, the impulses get made too late.

wide oar
hidden girder
# wide oar seems like I still need the `RigidBody::Static` for collision to work ๐Ÿคฃ

Yup, can confirm on 0.1.2. At least when using a trimesh collider for the ground.
Everything just falls through if terrain entity does not have RigidBody::Static.

I also noted a large performance issue for trimesh collision.
When not adding CollisionMargin to the terrain entity, rigid bodies seem to be unable to enter sleep/are woken up by something(maybe speculative collision?).
Fps start to drop very noticably when >1.5k capsules with locked rotation are falling onto the terrain.
Note:
The drop only starts to happen when they start colliding with the terrain.
While all are falling the fps are fine.
Adding the CollisionMargin to the trimesh collider entity reduces the severity of the fps drop but it is not prevented entirely.

hidden girder
#

Does anyone have any idea what can cause this behaviour?

The duck is moving forward by updating its LinearVelocity component.
The update happens in the Update schedule of bevy.

It looks like its position is reset if it starts moving.
Furthermore, it starts to look jumpy/shaky and starts to bounce after a few seconds of moving forwards.
It has a capsule collider component, and the ground is a trimesh collider.

Sidenote: Previously, i have been using rapier and there it was just sliding along the ground without the resetting/bounciness.
I am sure I am doing something wrong/missing something but for now I am not exactly sure what.

little maple
hidden girder
#

When using PhysicsDebugPlugin it looks like this:

little maple
hidden girder
#

like this when its standing still, i guess the lines are overlapping with the mesh so sometimes they are not visible.

Linear Velocity change is just z axis but once it starts moving linear velocity changes on x and y too.

I am just using LockedAxes::ROTATION_LOCKED

#

Restitution is set to Restitution::PERFECTLY_INELASTIC

silk mauve
#

I know the kinematic character controller example isn't really intended for use, so I'm not trying to be critical with this but I thought it was interesting. I'm using the kinematic_controller_collisions from the kinematic character example, and when I walk my character over the edges of the triangles in my custom terrain they seem to bounce like I might expect them to do if the character went over a small ramp:

fleet field
#

It worked for me

silk mauve
#

Thanks!

#

I am curious if this would be fixed with a proper collide-and-slide implementation. I just don't know enough about this

fleet field
#

Perhaps. I quite like the floating collider approach as it can give you slopes and stairs basically for free if you float high enough

silk mauve
#

That's fair

sleek thicket
#

yeah, for 3d the floating collider will be good even if edge ghost collision bug gets fixed

finite blaze
#

HL-2 anniversary doc, and how they used a string comparsion scale for object masses when debugging ("mass of a food can", "racehorse", "space station"): https://youtu.be/YCjNT9qGjh4?t=2138

sleek thicket
#

lmao

finite blaze
#

there's several tricks the comment about, for example increasing the friction of the player when closer to edges

vague pebble
#

I am curious if I want my collider to rotate so he stares at mouse direction should I try applying force or just apply directly into angvel?

wide oar
#

btw is there a concept of physics world in avian? let's say I want to have world 1 and world 2 so that they do not collide/interact with each other, is it possible?

wide oar
#

from my research it seems like it's not supported yet, tho would it help if I use separate bevy Worlds?

hidden girder
hidden girder
wide oar
wide oar
#

the only "easier" solution I came up with is to put them in different locations and simulate them altogether ๐Ÿ˜ญ , for now precision isn't the issue yet...

vague pebble
wide oar
vague pebble
#

nope dynamic

wide oar
#

then maybe consider using some sort of physics, but I really don't think it will matter that much since avian won't just explode if you accidentally clip into another collider due to rotation

#

it really depends on your use case, if you want snappy rotation, then rotate the Rotation component, if you want physics based, then use AngularVelocity or force

wide oar
hidden girder
#

yes, afaik sensors only prevent collision entities from being affected by physics.
Otherwise, they should behave like regular colliders.

sleek thicket
cloud jasper
# vague pebble I dont know what is usually the go tofor character controllers

I think it's not that important for rotation.

It's crucial for linear velocity/acceleration, because even the slight differences between working with the velocity and working with the acceleration can have big effects on where the character ends up. Also, changing the velocity directly makes it possible for the character to slightly phase into solid walls - something that doesn't happen with acceleration (ExternalForce really). On the other hand, using acceleration makes it easier to overshoot - especially if you are not using fixed timestep. With velocity it's much easier to stop exactly when you want to. Because of that, for Tnua's linear movement part I'm using acceleration in general but when the character stops, during the last frame, I switch velocity to guarantee it won't change the direction before stopping completely (especially important if some other system is looking at the direction of the velocity to decide where the character should be facing)

But for rotation? The difference will be quite minor. It will affect how quickly the character turns, but the difference will not be noticeable - and either way the character will end up facing the same direction.

I do suggest though that you use angular velocity, which makes the calculations simpler. Additionally, phasing into walls is not a problem with rotation - but overshooting is.

vestal minnow
# vestal minnow I've been chewing on the interpolation stuff for a couple of days again, and exp...

Okay, I've kept working on this for the past few days, and I might take back what I said; currently, I think I will use bevy_transform_interpolation for Avian as well.

I've reworked the structure a ton and made it more extensible, and in #4 I managed to implement decent transform extrapolation, and also added support for some shiny (optional) Hermite interpolation to produce more accurate motion by taking velocities into account for the interpolation. The velocity components aren't defined in the crate itself, but passed in using generics implementing a VelocitySource trait. For Avian, this means that the interpolation can just use LinearVelocity and AngularVelocity instead of storing duplicates.

As for my concern re: duplicate position components instead of using the physics position directly, I think I'm actually fine with it for now. It means that we don't have to worry about hierarchies (Position and Rotation in Avian are in global space, but the interpolated Transform isn't!), and it might make big_space support more straightforward.

#

I'm still working on this though, so of course I could change my mind for the millionth time ๐Ÿ™ƒ

#

Things I still need to do for bevy_transform_interpolation:

  • Try to integrate it with big_space
  • Test camera following scenarios
  • Maybe move the actual easing from PostUpdate to RunFixedMainLoop, in RunFixedMainLoopSystem::AfterFixedMainLoop? (#2)
  • Rework module structure some more
  • Add a 3D example or two
  • Finally, add a PhysicsInterpolationPlugin or similar to Avian using it
vestal minnow
#

It's a bit tricky to support more than one physics instance since Avian uses the ECS directly, and the ECS doesn't really have proper multi-world support or partitioning. In the future, we will probably do a limited version of "multiple physics worlds" where you can just assign physics entities to worlds/groups using some PhysicsWorldId, and each world has its own acceleration structures and constraints, making them fully separate in terms of physics entities interacting with one another

little maple
#

I think I've narrowed down the source of the stuttering in my game

I have the camera follow in PostUpdate, impulses applied in FixedUpdate and every couple seconds I get a frame where the physics isn't run before PostUpdate runs (which updates the smooth camera)

so everything stays still but the camera moves which makes it stutter.

#

I think I can work around that now that I know it's happening.. I guess it makes sense, just an update that doesn't align with the physics fixed update

vague pebble
cloud jasper
vague pebble
#

No

#

Hahhaa

wide oar
wide oar
wide oar
#

this is juz one way, u cud formulize other ways to do it hahaha

cloud jasper
#

I find it easier to keep a persistent representation of the direction you want your character to face, and use mouse positions to rotate that direction. This is easier than doing it with velocity, because you can just convert mouse movement units into radians with a simple multiplication. Unless your character is a plane/spaceship - keep the spinning and elevation separate to make the updates easier.

Once you have that, calculate the angular velocity required to rotate to that direction in a single frame - and clamp it by the maximum rotation speed you want to allow (you'll probably want to have separate limits for spinning and pitching). That's the angular velocity for that frame.

This does mean that the character will keep turning for a bit after the player stops moving the mouse. But:

  • Unless you use very slow rotation limits, this will hardly be noticeable.
  • If you use a third person camera, you can move the camera separately from the character so that the camera will respond immediately to the mouse motion, even if the character takes a bit more time to get there.
  • If none of these solutions are applicable - you can just have that forward direction slowly "diminish" (using a weighted average) toward the actual direction every frame.
little maple
little maple
#

that crate is good though, it definitely helped smooth everything out

wide oar
wide oar
#

my current solution is to not interpolate it at the start haha, maybe you can remove interpolate when it's not moving?

little maple
void dragon
#

Hi! How do I show the collision shape in Avian in the 3D space for debug reasons?

#

This is actually getting funny. Quick description: I am currently trying to implement a collide and slide algorithm. I am using the cast_shape function to manually check collision. If I press forward or/and left it works as expected, if however I press backward/right it for some what reason makes a collision at a distance of 0.0. I cannot debug it. The blue line - velocity - touches the ground everywhere. Everything shown in the visual is the same as in the cast_shape function.

#

The object is not moving in any direction. It has no LinearVelocity set.

void dragon
#

Could this be a bug?

void dragon
#

(please)

vestal minnow
#

Also FYI there's a few existing collide and slide implementations for Avian floating around, like this one in vidar by UB

#

aceeri also has one, but I can't find it rn with Discord's search

void dragon
#

Oh wow thank you so much!

void dragon
rocky seal
#

@vestal minnow using bevy_transformation_interpolation i experience a regression between HEAD and the previous commit. interpolation works great on the previous, but when i use the latest:

2024-11-21T22:52:18.270855Z  INFO bevy_diagnostic::system_information_diagnostics_plugin::internal: SystemInfo { os: "Linux 21.3 Linux Mint", kernel: "6.8.0-49-generic", cpu: "12th Gen Intel(R) Core(TM) i9-12900K", core_count: "16", memory: "62.6 GiB" }
2024-11-21T22:52:18.371795Z  INFO bevy_render::renderer: AdapterInfo { name: "NVIDIA GeForce RTX 3090", vendor: 4318, device: 8708, device_type: DiscreteGpu, driver: "NVIDIA", driver_info: "535.183.01", backend: Vulkan }
2024-11-21T22:52:18.749330Z  INFO bevy_winit::system: Creating new window "App" (0v1#4294967296)
2024-11-21T22:52:18.749486Z  INFO winit::platform_impl::linux::x11::window: Guessed window scale factor: 1
thread '<unnamed>' panicked at /home/ty/.cargo/git/checkouts/bevy_transform_interpolation-06af9eb63201b40c/1ee1c33/src/lib.rs:321:75:
called `Option::unwrap()` on a `None` value
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic in system `bevy_transform_interpolation::reset_easing_states_on_transform_change`!
Encountered a panic in system `bevy_app::main_schedule::FixedMain::run_fixed_main`!
Encountered a panic in system `bevy_time::fixed::run_fixed_main_schedule`!
Encountered a panic in system `bevy_app::main_schedule::Main::run_main`!
Segmentation fault (core dumped)
error: Recipe `local` failed on line 5 with exit code 139
vestal minnow
rocky seal
golden python
#

Anyone know how mass is handled when not explicitly set ?

rocky seal
hidden girder
wide oar
last forge
#

I got my force systems working with bevy_trait_query! My force components impl the Force trait. Each one gets updated in a system set just before the physics updates. In the prepare phase, a system gathers all components that implement Force sets the external force to the sum. I am approximating drag by using the bounding sphere as the thing making drag. Still working on a system that does differential drag based on the mesh. Some experiments showed it could work if I'm clever.

It's not much but it's there. I think I'm finally getting the hang of Bevy and Avian. Thanks yall for answering my noob questions lately. Next thing is to add force debug vector gizmos and attach a dangly tether to the bottom for fun

vague pebble
vague pebble
wide oar
sleek thicket
#

@vestal minnow did "Block" come up as a name for a collision library before?

vestal minnow
#

I don't think so

sleek thicket
#

i was working on adding block and parry to the game and thought it'd be a good name xD

vestal minnow
#

repel ๐Ÿค”

sleek thicket
#

i mean, you could think of minecraft/building blocks which kinda also relate to collisions a lot better

vestal minnow
#

yeah

#

repel is kinda funny because "avian repellent"

#

i.e. bird repellent

sleek thicket
#

if you wanna pair meme with avian then i'll have to think harder D:

vestal minnow
#

nah I don't actually want that haha

sleek thicket
#

"avian uses ### collision library"

#

fuck, it has to be glass or cage

edgy light
#

"angry". it's a well known fact that angry avians like to collide into stuff

sleek thicket
#

there are so many names that are super effective in that context xD

vestal minnow
#

It's pretty nice how Avian's new default scheduling setup (FixedPostUpdate) and this interpolation stuff simplify the camera ordering shenanigans you used to need for camera following logic

// Before
app.add_systems(
    PostUpdate,
    camera_follow_player
        .after(PhysicsSet::Sync)
        .before(TransformSystem::TransformPropagate),
);

// Now
app.add_systems(Update, camera_follow_player);

of course you could still use PostUpdate too for camera following, but either way you don't need to order things relative to physics

sleek thicket
#

is it 0-lag though

vestal minnow
#

define 0-lag, interpolation can never not be behind true positions

#

Or you mean the camera following? It shouldn't lag behind the rendered transforms of the entities

sleek thicket
vestal minnow
#

If the fixed timestep matches the screen refresh rate then you're just running fixed update every frame, and the interpolation shouldn't have an effect

sleek thicket
#

wasn't it 64 though

vestal minnow
#

yes

#

just means that for some frames, it'll run fixed update twice or zero times, and when it's zero times, it should get interpolated

#

or no it should always run once or twice I think

#

I'm confusing myself, it's late

sleek thicket
#

at 60 fps each frame is 16ms, so i really don't want any delay there ๐Ÿ˜…

#

i was planning on just not using interpolation for now, but if there's no cost then i'll have to try it

vestal minnow
#

it's at least super easy to just try and see if it helps, just add the dep and plugin, and enable it for everything or for specific entities

#

Or for Avian 0.2 I'll add a PhysicsInterpolationPlugin or similar that just uses bevy_transform_interpolation and sets things up nicer for physics

river moat
#

It is really strange, but my game (with default PhysicsPlugins) always crashes after adding mesh colliders. This is my system for adding mesh collider (during Update stage):

pub fn add_mesh_colliders(
    mut commands: Commands,
    query: Query<
        (Entity, &Handle<Mesh>),
        (
            With<RequireMeshCollider>,
            Without<MeshColliderAdded>,
            Without<MeshColliderError>,
        ),
    >,
    meshes: Res<Assets<Mesh>>,
) {
    for (entity, mesh_handle) in query.iter() {
        let Some(mesh) = meshes.get(mesh_handle) else {
            continue;
        };
        let Some(collider) = Collider::convex_decomposition_from_mesh(mesh) else {
            error!("Invalid collider mesh");
            commands.entity(entity).insert(MeshColliderError);
            continue;
        };
        debug!("Adding mesh collider");
        commands
            .entity(entity)
            .insert((collider, RigidBody::Static, MeshColliderAdded));
    }
}

And this is error message:

thread 'Compute Task Pool (7)' panicked at /home/artushak/.cargo/registry/src/index.crates.io-6f17d22bba15001f/glam-0.27.0/src/f32/mat3.rs:458:9:
assertion failed: det != 0.0
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic in system `avian3d::collision::collider::backend::update_collider_mass_properties<avian3d::collision::collider::parry::Collider>`!
river moat
#

Very interesting, adding capsule collider instead of the mesh one causes the same crash

river moat
#

Even when I simply spawn:

let cube_mesh = Capsule3dMeshBuilder::new(0.35, 1.1, 10, 10).build();
let collider = Collider::capsule(0.35, 1.5);
let cube_mesh_handle = meshes.add(cube_mesh);
commands.spawn((
    PbrBundle {
        mesh: cube_mesh_handle,
        transform: Transform::from_xyz(0.0, 2.0, 10.0),
        ..default()
    },
    RigidBody::Static,
    collider,
));

game crashes, but if I spawn

let cube_mesh = Capsule3dMeshBuilder::new(0.35, 1.1, 10, 10).build();
let collider = Collider::capsule(0.35, 1.5);
let cube_mesh_handle = meshes.add(cube_mesh);
commands.spawn((
    PbrBundle {
        mesh: cube_mesh_handle,
        transform: Transform::from_xyz(0.0, 2.0, 10.0),
        ..default()
    },
    collider,
));

it does not

brittle pilot
#

Hi!
Is there a way to find the closest collider to a point?
I'm trying to implement basic obstacle avoidance, but i don't want to just on random raycasts.

north kindle
#

Hi, I am new to avian, is there any way to visually debug collisions et forces applied on rigid bodies ?

river moat
# river moat Even when I simply spawn: ```rust let cube_mesh = Capsule3dMeshBuilder::new(0.3...

Here comes the minimal reproducible exampleโ„ข:

use avian3d::prelude::*;
use bevy::{prelude::*, render::mesh::Capsule3dMeshBuilder};

pub fn test_spawn1(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut local_flag: Local<u8>,
) {
    debug!("Local counter is {}", *local_flag);
    if *local_flag == 128 {
        debug!("Spawning debug capsule collider");
        let cube_mesh = Capsule3dMeshBuilder::new(0.35, 1.1, 10, 10).build();
        let collider = Collider::capsule(0.35, 1.5);
        let cube_mesh_handle = meshes.add(cube_mesh);
        commands.spawn((
            PbrBundle {
                mesh: cube_mesh_handle,
                transform: Transform::from_xyz(0.0, 2.0, 10.0),
                ..default()
            },
            RigidBody::Static,
            collider,
        ));
        *local_flag += 1;
    } else if *local_flag < 128 {
        *local_flag += 1;
    }
}

fn main() {
    let mut app = App::new();
    app.add_plugins(DefaultPlugins);
    app.add_plugins(PhysicsPlugins::default());
    app.add_systems(Startup, move |mut commands: Commands| {
        commands.spawn(Camera3dBundle {
            transform: Transform::from_xyz(0.0, 40.0, 0.0).looking_at(Vec3::ZERO, Vec3::Z),
            ..default()
        });
    });
    app.add_systems(Update, test_spawn1);
    app.run();
}

And, alas, it crashes.

#

Alright, I'll try to remove most of my dependencies and run this example again.

river moat
vestal minnow
#

yeah the issue is most likely glam-assert in that case

#

it can panic for a ton of pretty small things

#

and physics code is quite math-heavy so it's not uncommon to hit those assertions

vestal minnow
# north kindle Hi, I am new to avian, is there any way to visually debug collisions et forces a...

You can add the PhysicsDebugPlugin to enable debug rendering for physics. Collisions won't be visualized by default, but you can configure the PhysicsGizmos like this:

app.insert_gizmo_config(
    PhysicsGizmos::default().with_contact_normal_color(foo_color),
    GizmoConfig::default(),
);

IIRC the contact normal should be scaled by the contact force or impulse by default, and you can also adjust the scale using with_contact_normal_scale

north kindle
#

Thx, I will try this!

wide oar
#

hi, in which schedule shud I be checking for collisions?

grizzled depot
#

https://github.com/Vrixyz/bevy_rapier/pull/28 fyi ; a (wip) proof of concept example to use bevy_transform_interpolation with bevy_rapier ; I'd love to strip interpolation-specific code from bevy_rapier and benefit from shared codebase ๐Ÿคฉ

peak marsh
#

Is it possible to make a capsule collider, but rotated by 90 degrees? I'm making a top-down view game, so my player entity points to the right by default. I could make it so that my character points up instead, but it will make the rotation logic in other systems more annoying.

#

Basically my situation:

#

Oh this works:

Collider::compound(vec![(
    vec2(0.0, 0.0),
    Rotation::degrees(90.0),
    Collider::capsule(12.0, 24.0),
)])
peak marsh
#

Does it make sense to mutate Rotation directly for kinematic bodies? I need it to point to a specific angle, so AngularVelocity won't work for my case.

north kindle
#

Sometimes my RevoluteJoint snap on the other side of the angle limits set by with_angle_limits, how can I prevent that ?

cinder summit
vestal minnow
# grizzled depot https://github.com/Vrixyz/bevy_rapier/pull/28 fyi ; a (wip) proof of concept exa...

Cool! I also just made a PR to add built-in physics interpolation support for Avian, powered by bevy_transform_interpolation

GitHub

Objective
Closes #444.
To produce frame rate independent behavior and deterministic results, Avian runs at a fixed timestep in FixedPostUpdate by default. However, this can often lead to visual stu...

#

(also see #showcase message)

#

Worth noting that I have a PR ready for bevy_transform_interpolation that adds support for extrapolation and Hermite interpolation, renames some types, and reworks a bunch of docs. My PR for Avian uses that branch, but it can't be merged yet since it depends on a fix on Bevy's main branch that isn't in the RC

vestal minnow
cinder summit
#

If correct collision responses are desired, setting angular velocity so that it results in the desired rotation in a known amount of time (say 1 full tick) would be the way to go

peak marsh
vestal minnow
#

Anywhere before physics should be fine I think

cinder summit
#

If it runs after physics that's fine too, it just runs for the next frame ... As long as it doesn't run in the same schedule with no ordering relative to physics, since that would cause inconsistent ordering

peak marsh
#

Ok thanks for the advice!

peak marsh
vestal minnow
peak marsh
#

Oh yeah forgot about that.

vestal minnow
vague pebble
#

@vestal minnow A quick questioneriino is there a problem in changing rotation directly I know it is not supposed to be the go to, but do you think that is gonna cause some weird things to occur with a dynamic body.

vestal minnow
vague pebble
#

Lol

#

So it is nono

vestal minnow
#

It's fine for some things, but for continuous rotation I would generally recommend changing velocity or applying a torque instead

#

you can always try it and see if you get problems for your use case, if not then it's probably fine

vague pebble
#
    
let target_rotation = Quat::from_euler(EulerRot::YXZ, camera_rotation.y, 0.0, 0.0);

    let current_rotation = character.rotation.0;

    let delta_quat = target_rotation * current_rotation.conjugate();

    let (axis, angle) = delta_quat.to_axis_angle();

    let angular_velocity = axis * (angle / time.delta_seconds());

    if angle > 1e-5 {
        // Avoid numerical instability for very small angles
        character.angular_velocity.0 = angular_velocity;
    } else {
        return;
    }``` is this how you would convert the difference between rotations into  angular velocity?
vestal minnow
vague pebble
#

And then went up again

#

Thing is I cant balance out it is angular velocity, when I do via it.

#

It goes cucko

#

It works

#

But it goes cucko I wonder why

vestal minnow
vague pebble
#

It is a vec2 giving me the yaw and pitch from camera rotation

#
fn camera_rotate_to(
    q_transform: Query<&Transform, With<MarkerMainCamera>>,
    mut player_action_state: Query<&mut ActionState<PlayerAction>, With<Predicted>>,
) {
    if let Ok(cam_transform) = q_transform.get_single() {
        let (yaw, pitch, _) = cam_transform.rotation.to_euler(EulerRot::YXZ);
        if let Ok(mut action_state) = player_action_state.get_single_mut() {
            action_state.set_axis_pair(&PlayerAction::RotateToCamera, Vec2::new(pitch, yaw));
        }
    }
}```
#

This guy

vestal minnow
#

right, makes sense

vague pebble
#

Agh I am guessing i would need a pid to ensure he stabilizes

peak marsh
#

Is there a way to turn off overlap warnings for kinematic bodies? I don't have any dynamic bodies in my game, so it's not an issue. It looks like that it still prints a warning even if you have attached a Sensor.

peak marsh
#

Ah, it looks like it was fixed: https://github.com/Jondolf/avian/commit/571dcc668a5fa27537a33c0d1810f42d41a39894, but missed the 0.1.2 window by 5 days ๐Ÿ˜ฉ. Could it be backported, since most people is going to be stuck with 0.14 for a while?
Also, it looks like that this logging system is no longer a thing in main, or at least I can't find it. Was it just removed or replaced by something else?

vestal minnow
# peak marsh Ah, it looks like it was fixed: https://github.com/Jondolf/avian/commit/571dcc66...

It was removed, since it's not nearly as relevant in Avian as it was in bevy_xpbd, and I've only seen people be annoyed by the spam :P It's also pretty straightforward for users to add the warnings manually in app code if they want
https://github.com/Jondolf/avian/pull/547

GitHub

Objective

Overlap warnings are annoying

Solution

Yeet

#

I'm not sure if I want to make a cherry picked patch release this late in the cycle just to remove a warning ๐Ÿค”

#

if people really want it then I could, it's just pretty small and also technically removing existing behavior

peak marsh
paper maple
#

It seems that ConvexHullFromMesh doesn't do any sort of internal caching of a generated collider for a Mesh, meaning that it seems to be recalculating the collider for each copy of that mesh that I add. Is that right ? If so, how can I cache the generated colliders in a nice way ?

vestal minnow
#

If you can generate one Collider in some way, you can just clone that without cloning the actual data, since internally it stores an Arc<dyn Shape> which is cheap to clone.

#

You could create the collider manually with Collider::convex_hull_from_mesh, you just need access to the Mesh for that

formal galleon
#

hey folks, i think i have a silly question, but i don't know how to proceed. in my game there's a Dir3 that keeps getting denormalized over time - it starts with length 1 and keeps increasing until it panics within a few seconds. here are the last log entries. any ideas how to best debug something like this?

Warning: The vector given to `Dir3::new_unchecked` is not normalized. The length is 1.0099094.
   0: bevy_ecs::system::function_system::system
           with name="avian3d::spatial_query::update_ray_caster_positions"
             at /Users/mario/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_ecs-0.15.0-rc.3/src/system/function_system.rs:65
thread 'main' panicked at /Users/mario/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_math-0.15.0-rc.3/src/direction.rs:63:9:
Error: The vector given to `Dir3::new_unchecked` is not normalized. The length is 1.0099764.
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic in system `avian3d::spatial_query::update_ray_caster_positions`!
Encountered a panic in system `avian3d::schedule::run_physics_schedule`!
Encountered a panic in system `bevy_app::main_schedule::FixedMain::run_fixed_main`!
Encountered a panic in system `bevy_time::fixed::run_fixed_main_schedule`!
Encountered a panic in system `bevy_app::main_schedule::Main::run_main`!
#

or should I post it in another channel? ๐Ÿ˜ถ

paper maple
#

That means messing with loading events and stuff

#

Any idea on how to streamline this so it's more convenient for users ?

#

Maybe the component could include a cache_name: Option<String> field that will store it in a Resource CachedColliders(HashMap<String, Collider>), then subsequent calls with the same cache_name can check that resource for a collider if there is one, and use that ?

#

I'm not convinced of my design pattern, but just a basic idea of how something like that could work ?

vestal minnow
# paper maple Any idea on how to streamline this so it's more convenient for users ?

We've had the idea of "colliders as assets" for larger shapes like trimeshes and convex polyhedra, and using asset preprocessing to generate colliders for scenes at build-time to reduce startup times. Then you could just pass those collider asset handles around. Afaik there are still some blockers here though, and Bevy's asset preprocessing functionality is pretty half-baked, so it probably isn't very viable just yet

vestal minnow
vestal minnow
#

Is the RayCaster on a dynamic or kinematic rigid body? Or something else

formal galleon
#

its a kinematic body

vestal minnow
#

It should be normalizing rotation every frame for kinematic bodies too so I'm not sure why it'd become denormalized over time

#

(btw the panic should only happen with debug_assertions enabled, so it shouldn't happen in release mode at least)

formal galleon
#

i cant debug the assertion in new_unchecked, but i could clone the source and insert an if and set a breakpoint ๐Ÿค” i will give it a try

cinder summit
peak marsh
cinder summit
#

I think I've seen other people disable it trough a rule on bevy's LogPlugin

north kindle
#

Hi, I'll ask again with more details. I have been trying to make landing legs for my spaceship, currently the code for them looks like this :

let leg_normal = position.cross(Vec3::Y).normalize();

let leg_entity = parent.spawn((
    PbrBundle {
        transform: Transform {
            translation: position,
            rotation: Quat::from_axis_angle(leg_normal, 0.5),
            ..default()
        },
        mesh: meshes.add(Cylinder::new(0.15, 1.0)),
        material: materials.add(Color::WHITE),
        ..default()
    },
    LandingLeg,
    Collider::cylinder(0.15, 1.0),
    CollisionMargin(0.2),
    RigidBody::Dynamic,
    ExternalTorque::new(-2.0 * leg_normal),
    SweptCcd::default()
)).id();

parent.spawn(RevoluteJoint::new(ship_entity, leg_entity)
    .with_aligned_axis(leg_normal)
    .with_angular_velocity_damping(0.5)
    .with_angle_limits(0.2, 0.6)
    .with_local_anchor_1(position)
    .with_local_anchor_2(Vec3::Y * 0.5)
);

They have a RevoluteJoint that link them to the ship with angle limits and external torque to act like a spring that put them back in position
However, when they hit something, they go off the limits (below 0.2 and above 0.6) as you can see here :

vestal minnow
#

I did find one bug related to joint limits recently, which could maybe be related, not sure. That one should be fixed on the main branch

north kindle
#

I will try to rebuild with the main branch and update you about that

vestal minnow
#

I'm trying to work on finishing the mass rework again, it's such a pain

#

give me back my Jacobians and Lagrange multipliers ferris_sob

#

Current issue is that idk how I would detect if the components were added manually or through required components

#

i.e. in this case

  • RigidBody + Collider + Mass(5.0)
    the manually specified mass should probably override the initial value
#

but if Mass isn't provided, it should be computed from the collider

#

but Mass is required for RigidBody, so it exists in both cases

bold garnet
#

Seems like you should make mass an enum with an Auto variant, and have a system that calculates the value for components set to Auto.

#

Much like Val::Px vs Val::Auto

vestal minnow
#

Yeah I kinda had something like that at one point, I've gone through a billion designs

bold garnet
#

You could even have a private ComputedMass component

vestal minnow
#

I also had that design :P

bold garnet
#

Otherwise I donโ€™t think it should be required

vestal minnow
#

I don't really want a "manual mass vs. computed mass" split, or enums

#

I.e.

  • Mass is established from attached colliders based on their densities by default
  • Adding, removing, and modifying colliders affects the body's mass properties
  • Mass properties can be set manually at runtime
  • Automatic mass computation can be explicitly disabled (with marker components)
    And in our case also
  • If a collider entity has Mass, AngularInertia, or CenterOfMass specified at spawn, they override the initial values
  • A MassHelper system param can be used to do mass computations and updates that require access to hierarchies or several different components
rocky seal
#

would it be easier if you did not use required components and instead used a builder?

#

that way, you would know which components the user has provided and which they want computed

vestal minnow
#

I don't see how a builder would necessarily help, I think the same could be done by not having the mass components be required components and just checking if they were added

#

Just semantically, Mass should 1000% be a required component for dynamic rigid bodies

#

(not necessarily for static or kinematic)

bold garnet
#

there's a proposal to give the custom constructor access to the components that require it

rocky seal
#

fair enough. it just sounded above like you were having trouble checking whether they were added manually

bold garnet
#

so if A requires B, it can give it a constructor fn(A) -> B

vestal minnow
#

I'd like if Ref<Mass> had an .is_explicit_component() method

bold garnet
#

go review that pr i guess

vestal minnow
#

that information is already stored in the bundle info

#

but not exposed for the component

#

I'll look into adding that

vestal minnow
#

Or do you mean this? #general message

#

I think that'd mainly be useful for me if it can return None to skip insertion depending on some predicate

#

which might be contentious

river perch
#

Is it possible to run avian3d on a headless server app? When I add minimal plugins I get complaints that avian collision collider need mesh resource from bevy_render

junior flower
river perch
formal galleon
# formal galleon i cant debug the assertion in new_unchecked, but i could clone the source and in...

@vestal minnow I debugged it. It always happens here: https://github.com/Jondolf/avian/blob/f951ed38ed4e03d00b61d772ae21b8c953dd5ba3/src/spatial_query/mod.rs#L273
The rotation Quaternion keeps getting denormalized over time until it crashes. Any clue why it happens? ๐Ÿค” I don't exactly understand whats going on in this function with the global und parent stuff, right now.

GitHub

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

paper maple
#

Is there a provided method to apply an impulse to the Ancestor of Colliders, and have that propogate sensibly through the Hierarchy ?

paper maple
#

Or just some way of determining the "primary" rigidbody in a hierarchy or something ?

#

Basically it's just really awkward to apply an impulse to an object in my scene :/

paper maple
#

How do I maintain a non-collider Entity's Transform constant relative to another Collider Entity's Transform ?

formal galleon
# formal galleon <@545959292281552928> I debugged it. It always happens here: https://github.com/...

I fixed it. I used to update the rotation in the Update schedule by setting the Transform componenent. I thought they will be in sync after one frame. However, now I also update the Rotation component and it works. I have some strange behavior with my character since updating to the main branch of avian (and bevy 0.15-rc.3). Do we have a changelog or migration guide or something for avian? It would be cool to review the changes for possible incompatibilities with my code.

vestal minnow
#

For the actual release I will write a proper migration guide, and a blog post covering the changes, like I did for 0.1 (see the GitHub release and blog post)

vestal minnow
#

You can apply an impulse to the rigid body entity with the ExternalImpulse component

#

I intend to rework the force and impulse API at some point though, I'm not entirely satisfied with it

vestal minnow
#

You generally shouldn't nest rigid bodies in hierarchies

paper maple
#

I don't know how best to deal with that kind of situation. Maybe I have a marker component. But I'm importing a car from Blender, so it means some modifying of the loaded scene to give it a marker component. idk, i'm just not sure what to do

vestal minnow
#

Do you need them to be separate rigid bodies? Typically if you load a model from Blender like that, you'd have just one rigid body with several child colliders

paper maple
#

Oh I didn't know that

#

So parent car container entity would be a rigid body, then children of it would just be colliders, but not rigid bodies ?

vestal minnow
#

If you want stuff like physically simulated wheels attached to the car with joints, they'd need to be separate rigid bodies since they're simulated separately, but if you want just one physics object with many shapes rigidly attached to it, then yeah they'd just be child collider entities

#

There's also the ColliderConstructorHierarchy component for automatically generating colliders for child entities in a scene, but that of course doesn't have the caching thing either if you had many instances of the same scene

paper maple
#

So the issue I have now is that I'm getting warnings about it having no mass

#

Cus the Entity with the RigidBody doesn't have a collider itself. The children have colliders and mass, but it doesn't seem be getting respected ?

vestal minnow
#

It should have mass, but not before the scene is loaded and the colliders are actually inserted. The warning is just sent before this, though it probably should be changed to wait somehow

paper maple
#

The parent has less mass than one of the child colliders

vestal minnow
#

Hmm, that's strange

paper maple
#

Might be something to do with the order that things are getting added

#

idk

#

Cus maybe im adding things later than expected because I'm caching stuff first, idk

vestal minnow
#

You should probably use ColliderDensity for the collider, and not use MassPropertiesBundle there

paper maple
#

Okay

#

How does that work if MassPropertiesBundle::new_computed(&collider, 5.), needs to be pre-computed ?

vestal minnow
#

I think the way it currently works is that the components in MassPropertiesBundle only work for rigid bodies, and do nothing on a standalone collider entity. Colliders use ColliderMassProperties instead, and that is computed at runtime based on the shape and ColliderDensity. The Mass of the rigid body is the sum of the masses of all attached colliders

#

Afaik you can't really precompute mass properties for colliders currently

paper maple
#

Gotcha

vestal minnow
#

The way mass works currently is confusing and kinda footgunny, which is why I've been working on trying to redesign it

#

With my new designs I think your code would work, i.e. you can set the mass of a collider with MassPropertiesBundle or its individual components

paper maple
#

No problem I don't really mind either way atm - I just couldn't get it to work cus I didn't understand. ColliderDensity worked for me, thanks

paper maple
#

How does Friction behave ? Does friction need to be in Entities with Collider ? Or can I have them in just the parent Entity (with the RigidBody) ?

vestal minnow
urban flume
#

do heightfield colliders always have to be square?

#

when I try to add less rows than columns it doesn't look like I expect

#

this looks right

#

but if I remove a row it looks like it expects the missing row to be there

peak marsh
#

Will collision reporting become triggers one day? I wonder what's the overhead of just running commands.trigger on every collision by default.

void dragon
#

Remember me? It was a bug, for some reason the ignore_origin_penetration did not work, I filtered out the entity at the beginning, now it works fine.

#

More context: I cast_shape to query for hits along the velocity to implement the collide_and_slide. I checked the source code of vidar - awesome thanks again! - and I copied the part that filters out the entity itself, now it does not collide with itself. All the math checks out so it is a bug in Avian itself.

weak gorge
#

Greetings. Thanks for the great crate. I noticed when I clone the repo and run the examples they are locked to 144 hz. However, if I copy and paste the example into a new project it is NOT locked to any framerate. Can you share how you were able to lock the framerate? Cheers.

river perch
#

Actually nvm donโ€™t think thatโ€™s it

#

You can try it

#

Also donโ€™t think avian physics is related to frame rate itself, you can just define how many times physics run per frame. Fixed frame rate is set by the schedulerunner.

Like this:

    App::new()
        .add_plugins(
            DefaultPlugins
                .set(ScheduleRunnerPlugin::run_loop(Duration::from_secs_f64(
                    1.0 / 60.0,
                )))```
vestal minnow
#

It's kinda confusing though, I'm not 100% sure if the inner vectors should represent rows or columns. It's mainly a matter of choice

#

I think Glam's matrices use a column-major order, and input vectors are the columns, even though visually they look like rows when laid out table-like

#

But especially for heightfields, that representation might just be confusing

vestal minnow
#

I've tried the observer route a couple of times, but I'd like the events to be opt-in at the entity-level, and I don't really want the observer events to be sent globally (the buffered events already exist for that) so I haven't been entirely satisfied with that approach

vestal minnow
#

For example I'm currently on a 60 Hz monitor, and the examples are capped to 60 FPS for me

cinder badger
#

What kind of error is this

vestal minnow
#

Bevy version mismatch?

cinder badger
#

0.14

#

yeah its 0.14

vestal minnow
#

If you're using Avian 0.1 and not the main branch, then yeah 0.14

cinder badger
#

so i still have that error

vestal minnow
#

any other dependencies that could be using a different Bevy version?

#

might also want to run cargo update and/or cargo clean just in case if not

cinder badger
#

Also on the bevy screen it just shows all black, are all collider shapes automatically colored black?

vestal minnow
#

colliders aren't rendered unless you have debug rendering for physics enabled

vestal minnow
#

for a game you'd use meshes and/or sprites to render your entities, but if you specifically want physics debug rendering, you can add the PhysicsDebugPlugin

cinder badger
#

gosh the error is bothering me

#

i have no idea why its acting like that

#

it's really frustrating because errors like these pop up, then i'd have to make a whole bug report about it with the chance of being ignored by Jetbrains teams because it's not a severe issue, it would've been nicer for RustRover to not be closed source so it'd be easier to contribute through there to fix stupid errors like these which would be ignored anyway

vestal minnow
#

If the game compiles and runs fine but you still get the error in your editor, you might need to restart Rust Analyzer? (or that looks like RustRover, iirc it has its own thing)

cinder badger
vestal minnow
#

hmm I'm not sure then, I haven't used RustRover so I can't help there unfortunately

vestal minnow
bold garnet
#

I think the public api component / private computed components is going to be an increasingly common pattern.

peak marsh
silk mauve
#

Is there any situation in which changing the translation of an entity won't move it in Avian?

fn threat_collector_follow_system(
    character_query: Query<(&ThreatCollector, &Target, &Transform)>,
    mut threat_collector_query: Query<&mut Transform, Without<ThreatCollector>>,
) {
    for (threat_collector, target, character_transform) in character_query.iter() {
        if let Ok(mut threat_collector_transform) = threat_collector_query.get_mut(threat_collector.0) {

            let direction = (target.0 - character_transform.translation).normalize_or_zero();
    
            println!("pos before: {:?}", threat_collector_transform.translation);
            threat_collector_transform.translation = target.0; //threat_collector_transform.translation + direction * 10.0;
            println!("pos after : {:?}", threat_collector_transform.translation);
            continue;
        }
    }
}

The translation changes, and the ThreatCollector has the correct entity reference.

    let threat_detector = commands.spawn((
        Collider::cylinder(10.0, 10.0),
        Transform::default(),
        ThreatCollectorOwner(player_id),
        Sensor,
        CollisionLayers::new([Layer::Sensor], [Layer::Character]),
        OwnerBundle::new(),
    )).id();

... the threat collector if that helps.

vestal minnow
#

Hmm, I might just make a minimal 0.15 migration release tomorrow, and do the full feature release (0.3 I guess?) in a week or two. I really want to land the mass property rework properly, and need some more time to finish it, clean up and merge a few other open PRs, and do all the release prep

vestal minnow
vestal minnow
#

I'd also like to just call the new release 0.2 and not do a tiny release followed by a huge 0.3

#

I could also just have a bevy-0.15 branch with the minimal migration path and not do a crates.io release before the full release, idk

boreal tendon
vestal minnow
#

RustRover

rocky seal
#

what's the rush? folks that can't wait for the proper release can use main

vague pebble
#

@vestal minnow Mr Jondolf question, besides sleeping is there any other state based logic envolving components?

silk mauve
#

I'm building a boid system in my game that already uses Avian and I'm curious if it's even worth building a specialized spatial partitioning system? I don't know how physics works but I assume there's some sort of spatial partitioning going on to avoid unnecessary collision checks. If that's the case, couldn't I just do a sphere cast for anything on with "Layer::Boid"?

#

I feel like this is the exact problem a physics engine solves but maybe I'm missing something

sleek thicket