#Avian Physics

1 messages ยท Page 25 of 1

sleek thicket
#

that's what i thought manual does in the first place, instead of override

vestal minnow
#

Hmm, yeah that's fair

#

We could have both as variants, but I'm not sure if that's ideal

#

I'll tinker with this for a bit

sleek thicket
#

merging inverse and making read-only can be done without changing the rest of the stuff, right?

vestal minnow
visual sparrow
#

That'd be really great

vestal minnow
# sleek thicket that's what i thought manual does in the first place, instead of override

Okay so I think there's three cases we might care about:

  1. Derive mass automatically from colliders based on the given density (defaults to 1.0)
    • Maybe default to a mass of 1.0 if no colliders exist, to prevent wonky behavior caused by zero mass
  2. Set the mass of the rigid body, and add masses of child colliders on top
  3. Override the mass of a rigid body completely, ignoring colliders

We could handle (2) and (3) with separate variants, say Manual and Override, but we'd need them for all of Mass, AngularInertia, and CenterOfMass, and the distinction between the two could be confusing. And on child collider's, Manual and Override would do the exact same thing, which is kind of redundant.

I'm currently thinking that we should just make the semantics such that Mass::Manual is only the mass of that entity, and then masses of child colliders are added on top. If you don't want child colliders to affect the rigid body's mass, set their mass or density to zero. So basically, just don't handle (3) with any special API, but rather make it something that needs to be done manually.

spiral nymph
#

Can I add gravity and collision to specific entities on a kinematic object ?

vestal minnow
# spiral nymph Can I add gravity and collision to specific entities on a kinematic object ?

Kinematic objects by definition aren't affected by forces or collisions, since they're user controlled. For that, you'd need a Kinematic Character Controller (KCC), which handles movement and collisions. Avian doesn't have a built-in KCC yet, but there's an example that has a basic one here. It's kinda buggy though and not intended to be used as is.

Generally the way you'd handle KCCs is with a collide and slide algorithm (similar to Godot's move_and_slide). There's a few of those for Avian scattered on this Discord, one of them is by UB
#1124043933886976171 message

#

For a dynamic character controller, I'd recommend bevy-tnua

sleek thicket
frail robin
#

Is there a way to set center for a cuboid collider without spawning it as child?

Do I need to manually create it as trimesh?

vestal minnow
# sleek thicket i have no idea how everything works on the background, so what i'm imagining is ...

A few examples of how it'd work API-wise

  • Rigid body: Mass::Density(2.0)

    • Child collider: Mass::Density(3.0)
      Result: Rigid body's computed mass is the mass of its own collider (if one exists) with a density of 2.0 + the mass of its child collider with a density of 3.0.
  • Rigid body: Mass::Manual(100.0)

    • Child collider: Mass::Manual(10.0)
      Result: Rigid body's computed mass is 100.0 + 10.0 == 110.0.
  • Rigid body: Mass::Manual(100.0)

    • Child collider: Mass::Density(0.0)
      Result: Rigid body's computed mass is 100.0 + 0.0 == 100.0.
#

We could also replace Mass::Density with Mass::Auto, and keep ColliderDensity as its own component

sleek thicket
vestal minnow
sleek thicket
#

you could actually name it IndividualMass and it'd all fit together

vestal minnow
frail robin
sleek thicket
#

and since there's no longer distinction between auto and manual, it's no longer manual

#

but mass::mass would be weird

#

mass::new?

vestal minnow
sleek thicket
#

it doesn't have to be same for everything

vestal minnow
#

Special-casing the name for mass seems kinda weird

#

For consistency, I would probably just keep it as a Mass enum with Density and Manual variants, and document it such that it only affects that entity, and child colliders can have their own masses that are added on top for ComputedMass

#

Local isn't the same as it is for transforms here, since child colliders don't have a distinction between the "local" and "global" mass. The root rigid body is the one where the computed mass may be different, which is kind of opposite from transforms

sleek thicket
#

yeah, either way the main footgun is avoided

if you make a generic humanoid character and know his overall weight has to be 100kg...
how do you figure out what the mass of each limb should be?

#

that's just a niche problem, i'm not saying there should be a built-in way of doing that ๐Ÿ˜…

#

it would actually make a really nice example for why density is better than manual in some cases

vestal minnow
#

Or alternatively, just compute the desired density for everything based on the total volume and desired total mass

#

yeah that might be easier

sleek thicket
#

the first one is probably way more accurate though

vestal minnow
#

They should be equivalent here. In both cases you have uniform density computed based on the volume and desired total mass

#

In the first case you just set the mass explicitly, while in the second case you set the density (which should result in the same mass)

#

Of course actual humanoid characters wouldn't have uniform density for different body parts or even different parts of those body parts, but then you'll just have to compute what they should be for everything, there's no easy way out there

#

Or I guess you could have some way of setting the mass contribution factor for each part and then compute the mass based on that and the desired total mass

#

but that's something you could easily do with your own custom components

#

Also with the current proposal, we're handling mass properties in a much more flexible and configurable way than almost any engine ๐Ÿ˜› All Unity has is this, which feels pretty limited to me

#

No way to compute mass from colliders or use a density afaik, and no way to specify mass properties for individual colliders

#

Here the behavior is closer to what our Override variants would've been

#

Like if you have a mass of 1, that's what the mass is, and adding child colliders has no effect on it

#

at least based on what I was reading when looking into it, I didn't properly test Unity's behavior myself yet

sleek thicket
vestal minnow
#

Colliders don't have any field to change mass, it only exists for Rigidbody

#

Same in Godot iirc

#

No, this is all the properties for a collider that is a child of a dynamic rigid body

sleek thicket
#

nvm apparently you're supposed to use joints for what i was thinking about ๐Ÿ˜…

visual sparrow
#

@vestal minnow what was the state on upstreaming the KCC that @crimson crest made?

#

I'm a bit out of the loop

vestal minnow
vestal minnow
#

I imagine I'll change some API things, but I need to experiment with it to see what's possible to decouple and handle differently without breaking things

#

Mainly I've just been busy with way too many unrelated things (mass property rework, reworking bevy_heavy, adding ray casting for Bevy, doing required components migrations for Bevy, implementing impulse-based joints, experimenting with simulation islands and multiple physics worlds, messing with interpolation stuff, university...)

crimson crest
#

In my testing the more you decouple the more boilerplating you need to do

#

The "best" course is to provide the utilities as their own functions and an opt-in default system that does everything for you, most people won't need much more than the default, but for power users maybe all they care about is having collide and slide itself

#

The more you break it apart, the more code the end user would be rewriting every time they want to use it, basically

visual sparrow
#

Did you finally figure out that "variable" business?

#

have you advanced to functions yet?

crimson crest
# crimson crest The "best" course is to provide the utilities as their own functions and an opt-...

My sort of final thoughts for the best way to do a KCC is to operate on the LinearVelocity component (need to figure out the scheduling for the best time to update on it since Avian will also try to automatically move a kinematic body using it I believe. Or ideally some way to opt out), optionally provide a way to do gravity as a separate pass (can make some edge cases simpler, though it doesn't work great for "Mario Galaxy" styled games where the direction of gravity can vary), and depenetrate after the collision detection is done due to since bevy doesn't support f64 transforms

vestal minnow
# crimson crest In my testing the more you decouple the more boilerplating you need to do

Some things I was thinking about are like

  • Can we use LinearVelocity directly? (may require first-party integration)
  • Can we move the collider out of KinematicCharacterController into its own CharacterShape or similar, and if it doesn't exist, default to the Collider on the entity?
  • Can we make KCCGrounded a marker component so that people can just filter by it in queries instead of having to check the grounded property?
  • Can we extract things irrelevant to the user from e.g. KCCFloorDetection into their own components, separating configuration like max_floor_distance or up from internal state like prev_floor_normal or prev_velocity?
    Also for upstreaming, it needs to support both 2D and 3D, and f32 and f64, and probably use PhysicsLengthUnit if there are some internal tolerances and such
#

Stretch goals are like

  • Does everything need to be specific to KCCs? Can we make things more general and make things like floor snapping and ground detection work for dynamic character controllers too?
  • Can we provide system params to run collide and slide on-demand?
#

To be clear, these aren't all things that I necessarily require, just open questions I'd like to experiment with

crimson crest
# vestal minnow Some things I was thinking about are like - Can we use `LinearVelocity` directly...
  1. Yes, (see the block above, I need some way to tell avian not to act on it automatically, but still provide predictions maybe)
  2. Yes, I moved it into the KCC since you may want to have a different collider for prediction than detection if you want some unusual logic
  3. The KCC doesn't currently act on it, but to make floor snapping the best it can be you definitely want to know if we're not grounded this tick but were the last (as in, you shouldn't snap if you've been in the air for two consecutive physics ticks)
  4. Should be able to, a lot of whats in vidar is future proofing (or debugging info) and not currently used
vestal minnow
#

Yup, makes sense

crimson crest
#

In the future I'd love to be able to have something like tnua's movement basis model, but that might be best to leave to a third party crate since its a lot of work to maintain

#

I think the built in KCC should be more of a well integrated example that works for most games, but gives you access to the tools to ditch it entirely and build your own if you need more complex behaviors

#

On the thought of system parameter actually, would it be possible to make it CollideAndSlide<T> where T defines a tuple struct component wrapping a vec that represents velocity?

#

Or maybe implements some kind of velocity trait? So it can be LinearVelocity automatically provided by default but you can define as many system params for different passes as you like

vestal minnow
crimson crest
#

Not sure how valuable it would be outside of the aforementioned some games do movement and gravity in separate passes, would need to think of some other scenarios to justify it

vestal minnow
frail robin
#

But on the latest master it's crazy slow for some reason.

#

To clarify, it's unrelated to the fix, just slow on the latest master

vestal minnow
#

Was this the case in the 0.1.2 release as well? It'd be nice to find what caused it if it's a regression

frail robin
#

Bisecting now.

vestal minnow
#

Do you have a bunch of gizmos?

frail robin
#

I mean I enabled the debug rendered for colliders

vestal minnow
frail robin
frail robin
#

So I have a branch to point

#

Actually, no, it's still slow...

vestal minnow
#

Weird that it'd be meaningfully slower though, maybe Bevy's "contextually clearing gizmos" thing for fixed schedules has a lot of overhead?

frail robin
#

It's strange... If I jump to 4d082a79fd30078e5b536ae23656f690091ae285 from the PR, it's fast. But if I apply it on your PR with the fix - it's slow.

#

Mabye there are multiple causes of the slowdown

#

Because the fix on a bit outdated branch

cinder summit
vestal minnow
#

yeah

cinder summit
#

Meanwhile my fix to make debug gizmos play nicely with FixedUpdate: Clear the event each simulation tick

frail robin
#

Slow even if I disable gizmos

vestal minnow
frail robin
frail robin
vestal minnow
frail robin
#

Will try

vestal minnow
#

The only one that would make any sense to me is the commit right after it, for #480... But I don't immediately see why it'd be meaningfully slower

frail robin
#

Hm... Tried using 1e4d7a7cff1dfaf2ba17f5d14629c72df5089515 with the cherry-pick of the fix from the PR - it's slow, strange.

#

Ah, never mind the branch named patch-1, I probably checked out some wrong stuff ๐Ÿ˜…

#

Hm.. No, I did not.

#

Double-checked everything. Looks like on the PR it's still slow.
Maybe I just messed with the compilation cache previosly.

#

No gizmo involved.

vestal minnow
#

I'm expecting it to be a bit slower with that, since it changes the default fixed timestep from 60 Hz to 64 Hz (because of Bevy) and because Bevy's fixed schedules can properly run multiple times per frame if needed, while the old custom fixed scheduling didn't

#

But I don't think it should be like a significant performance drop

frail robin
#

@vestal minnow will it be okay If I create a branch with the avian update to the latest main and provide you a single instruction in the terminal to run it? You will immediately see the slowdown.

#

Branch for my game*

vestal minnow
#

Yep, that'd be useful

frail robin
#

Working on it!

vestal minnow
#

Thanks!

frail robin
#

Let me know if you have any questions.
Here is what I use physics for:

  1. Picking. I will switch to GPU-based picking when it comes to Bevy.
  2. Collision checking when I place objects/walls.
  3. I build navigation from colliders.
#

The map have a several walls that are trimesh colliders and 4 characters with capsule colliders. So not much.

cinder summit
#

I have personally also seen some slowdowns after I switch to main, but the percentages seemed pretty small so I assumed it wouldn't have been avian related ๐Ÿค”

#

Could it have happened in the hooks PR?

#

I actually switched to main for that determinism commit, but got more than a few unrelated issues, so there definitely might be something wrong

cinder summit
#

What if you run with fixed_once_hz(64) and set it to FixedPostUpdate in the first place? At that point it should be identical

vestal minnow
#

Lemme add an fps counter or something

cinder summit
#

Wait, in what way was it slow anyway?

frail robin
#

Interesting, it's slow sometimes

frail robin
#

I just tried running it a few times, sometimes it's slow, sometimes not

cinder summit
#

FPS based on an FPS counter?

#

Cause if it's only visual it would just look lower FPS because no interpolation

frail robin
#

No, just camera movement, it's choppy

#

No object movement.

#

Let me add a counter and I will provide more info :)

cinder summit
vestal minnow
frail robin
#

But camera and objects are not affected by physics, everything is static...

vestal minnow
#

Hmm okay

#

Either way I'm getting a stable 80 FPS in debug mode

cinder summit
#

There can't not be system ordering issues in avian at least when my server always spams these stupid mass property warnings while the client never send them while using literally the same code to initialize the entities

frail robin
#

And it's Ryzen 9 5950X.

vestal minnow
#

I have 600 FPS in release mode ๐Ÿ˜‚

cinder summit
#

I don't think there's any consumer chips that are 8x faster than a 5950X, so it must be a supercomputer ๐Ÿ˜‚

vestal minnow
#

I'm on a 13th gen Intel i7-13700F

frail robin
#

@vestal minnow I added 2 commits:

  1. The FPS counter I used.
  2. The update to the avian's slowdown commit.
    Could you check again?
#

Just in case

vestal minnow
#

yup

frail robin
#

I have around 25 FPS in debug mode without the slowdown commit and around 10 FPS with the slowdown commit.

#

Rust 1.81.0

vestal minnow
#

Still getting a nice 60 FPS in debug mode with VSync (I'm on a 60 Hz monitor) and 80 FPS uncapped

frail robin
#

Are you running Windows?

vestal minnow
#

Yes

frail robin
#

Guessed by fonts ๐Ÿ˜…

#

I use Archlinux ๐Ÿค” BTW

vestal minnow
frail robin
vestal minnow
#

not that I can see, no

frail robin
#

Okay, you suggested to try to switch to 64hz?

#

to 60*

vestal minnow
#

Yeah Bevy's default is 64 Hz, Avian/bevy_xpbd used to have 60 Hz

#

to change to 60 Hz you'd use app.insert_resource(Time::from_hz(60.0)) on Avian main

#

I doubt changing it would really make a big difference though

frail robin
#

Yes, this doesn't change anything.

#

This is very strange.
On Linux it runs much slower then on Windows, but that I can understand.
But why switching the commit doesn't doesn't affect your machine in any way?.. I even tried jumping between commits multiple times - I can reproduce the slowdown.

frail robin
vestal minnow
#

in debug mode

#

maybe it is slower but my FPS is just high enough that it's not as observable? idk

vestal minnow
#

so like, if you run it 20 times and get it once or twice, it could be a scheduling thing

#

but Avian itself shouldn't have ambiguities, except where explicitly accepted and known (or expected) to be fine

cinder summit
frail robin
cinder summit
#

I don't think any other new ones should've been introduced on main vs 0.1.2 tho

frail robin
cinder summit
#

Scheduling issues can be reliable in some cases too

frail robin
#

Yes, but it's weirdly reliable ๐Ÿ˜…

cinder summit
#

I've had plenty of those between my client and server because the other systems in the schedule are different and thus consisently shift things around

#

And I'd imagine FixedPostUpdate and PostUpdate run different systems

#

But also, your FPS is always low, so switching to FixedPostUpdate should cause a slowdown whenever you're below 64 FPS

#

Not this much tho, that's like 40 to 10 thonk

frail robin
#

Ah, maybe that's the isse

frail robin
cinder summit
#

Try 0.1.2 with fixed_once_hz(64.) and pass FixedPostUpdate to PhysicsPlugin::new()

#

If that gives you the same result it would just be expected changes from switching to FixedUpdate

frail robin
#

Ah, PhysicsSchedulePlugin!

vestal minnow
cinder summit
#

Ah yea, it's with an s, it's a plugin group after all

vestal minnow
#

my game perf super_bevy
my compilation times bavy

frail robin
cinder summit
#

The last step is also just always a bit slower on windows iirc, because it pulls in a bunch of extra crates for windows-specific stuff

#

Which is more stuff to link than what linux has, especially if you only do X11 or only wayland

frail robin
# cinder summit Try 0.1.2 with `fixed_once_hz(64.)` and pass `FixedPostUpdate` to `PhysicsPlugin...

Hm... About the same. Here are my changes:

diff --git a/app/src/main.rs b/app/src/main.rs
index 6f77bd4..0b7486a 100644
--- a/app/src/main.rs
+++ b/app/src/main.rs
@@ -27,6 +27,7 @@ fn main() {
             position_to_transform: false,
             ..Default::default()
         })
+        .insert_resource(Time::new_with(Physics::fixed_once_hz(60.0)))
         .add_plugins((
             DefaultPlugins
                 .set(RenderPlugin {
@@ -50,6 +51,7 @@ fn main() {
             NavmeshUpdaterPlugin::<Collider, Obstacle>::default(),
             PhysicsPlugins::default()
                 .build()
+                .set(PhysicsSchedulePlugin::new(FixedPostUpdate))
                 .disable::<CcdPlugin>()
                 .disable::<SleepingPlugin>(),
             PhysicsDebugPlugin::default(),
cinder summit
#

The same as main or as 0.1.2 without any changes?

frail robin
#

And I tried with and without the changes

vestal minnow
frail robin
#

Ah, thanks!

#

Yes, I can reproduce it with this changes.

#

@cinder summit was right

#

So on commit before the slowdown If I do this changes - it gets slow. If I stash them - it's faster.

vestal minnow
#

Okay well at least it's not necessarily a regression then ๐Ÿ˜› in the case where physics is configured to run in that same schedule

frail robin
#

Yes. Can I also confirm the same behavior on 0.1.2.

#

Thanks for helping me to find the root cause!
I probably should lower the tick rate... I think 30hz for my game is enough.

cinder summit
#

Or make the game run faster

frail robin
#

With 30hz I have the same perf as before without chaning the schedule.
I use physics only for collision detection for now anyway.

cinder summit
frail robin
# vestal minnow I have 600 FPS in release mode ๐Ÿ˜‚

I have only 400 in release ๐Ÿ˜… But it could be a GPU difference or because of the crappy Nvidia drivers for Linux.

Looks like mold in debug really prioritizes speed. Such a big difference between debug and release. But it's probably a good thing, I care only about compilation speed in development.

cinder summit
frail robin
# cinder summit I get the same FPS (40 debug, 400 release) on linux with an AMD GPU (on wayland)...

Interesting... Do you get 40 in debug even without changing the code (swapping the schedule or lowering the tick rate)?
I can't get 40 even if I do so.

Did a few more tests:

  1. With and without mold - the performance is the same.
  2. Setting the tickrate to 30 returns makes it around 30 FPS.
  3. Lowering the tick rate below 30 doesn't have any effect.
  4. Tried on Windows 11 (dual-boot) - 40-50 FPS in debug (no code changes) and 400-500 in release (a bit faster).

In release I think it becomes GPU bound. I have 3060TI, maybe @vestal minnow have just faster GPU, that would explain more FPS.
And on Linux I use X11 due to Wayland issues with Nvidia, this could explain lower FPS compared to @cinder summit and comparing to Windows.

glad eagle
#

But it's a fairly small game

vestal minnow
#

Still playing around with APIs for the mass stuff... While I do think yesterday's proposal of adding the mass of colliders on top of the manual mass defined for a body is useful, I think we do also want to support entirely overriding mass properties without having to set mass for all child colliders to zero.

There's a few reasons:

  • If you had to set mass to zero for all child colliders to override a body's mass, it'd also make their automatic angular inertia zero, since it's scaled by mass.
  • You often don't care about the exact geometry of the body, and want to just tune mass until it feels right. This should be doable without messing with the child colliders' masses, since again, that could affect the total angular inertia and the center of mass of our body, which may not be what we want.
  • I've seen several users specifically ask if it's possible to override a body's mass, not just add to the mass given by the colliders.

In Box2D, mass is derived from attached shapes by default, but you can manually set it if desired. I think what we want is similar, but also with the option of "additional" mass, like what was discussed yesterday.

#

What I'm currently imagining is like this:

#[derive(Component, Default)]
pub enum Mass {
    #[default]
    Auto,
    Override(Scalar),
    Additional(Scalar),
}

#[derive(Component, Default, Deref, DerefMut)]
pub struct ColliderDensity(pub Scalar);

#[cfg(feature = "2d")]
#[derive(Component, Default)]
pub enum AngularInertia {
    Auto,
    Override(Scalar),
    Additional(Scalar),
}

#[derive(Component, Default)]
pub enum CenterOfMass {
    Auto,
    Override(Vector),
    Additional(Vector),
}

Density is separate from Mass, because (1) you might have Mass on a rigid body with no collider, and (2) because you might want to derive mass from a collider's shape while also giving it additional mass.

#

Not sure if this sort of API is overengineering things, but I think it's close to supporting almost all use cases I can think of pretty nicely

#

-# AFK for a bit

cinder summit
#

Actually wouldn't the real mass have to be stored in other components? I wonder if maybe having an Auto is wrong here since this is optional behavior ๐Ÿค”

vestal minnow
# cinder summit Actually wouldn't the real mass have to be stored in other components? I wonder ...

Auto isn't really necessary, although the components would then probably need to be renamed to e.g. ManualMass and so on. But if we're considering the issue about implicit defaults, then it semantically should maybe exist

GitHub

For Bevy 0.15, which will have required components. Objective Currently, Avian has implied defaults for numerous components. This means that when a component doesn't exist on an entity, a defau...

cinder summit
#

In this case Auto isn't an implicit default, it's entirely separate behavior

vestal minnow
#

Auto is what the default behaviour would be if the component didn't exist

#

Like what it is in current Avian

cinder summit
#

Yea, which is why it's weird to init it to Auto when the other is additional new behavior

#

There are also some other odd ones like how ColliderDensity probably shouldn't be required if it can come from any part in the hierarchy

vestal minnow
#

Depends on if we want a ColliderDensity on the rigid body to apply to all attached colliders or only the entity it's on

cinder summit
#

Yea if it doesn't have propagation you'd end up in a situation where every collider would have it

#

Also if it's not just for colliders but the entire rigid body it would probably have to be renamed to not have the word Collider in it thonk

sleek thicket
cinder summit
#

I think it's less about overriding and more about just setting the mass based on the rigid body instead of a hierarchy of colliders, no? ๐Ÿค”

sleek thicket
#

oh, the thing i mentioned before?

#

but i didn't mean that as override

sleek thicket
#

but yeah i guess it's one of the most realistic use cases, knowing how much something should weight in total and expecting the engine to automatically distributing the mass

#

setting the exact weight is second most realistic use case, like this gun should weight 10kg, and letting the physics engine figure out the rest without changing it

vestal minnow
#

yeah in e.g. Unity and Godot you can just set the mass of the object while automatically computing angular inertia and center of mass, and that only works nicely if you can override the rigid body's mass

sleek thicket
#

maybe something like "inherit" as option?

#

like pick a limb and set it to "inherit mass", then the rb will redistribute it

vestal minnow
#

you can kinda do that with auto or Additional on the rigid body

sleek thicket
#

isn't that based on density

vestal minnow
#

it's based on whatever the colliders' masses are, which can be based on density or explicitly specified depending on how the colliders are configured

sleek thicket
#

collider or rigidbody?

vestal minnow
#

Auto on a rigid body is just "Compute mass properties from attached shapes", and each collider's mass can be configured individually (defaulting to auto, which uses density)

#

And Additional is same as auto, but adds the given mass on top

#

Like Rapier's AdditionalMassProperties

cinder summit
#

Density defaults to 1.0 afaik

vestal minnow
cinder summit
#

Colliders without mass aren't something fun

#

Especially considering avian uses inverse values, so you get 1. / 0.

#

No

#

Idk if it still works but you used to be able to just manually set mass and inertia

vestal minnow
#

It doesn't need to do anything special to get the density of anything, that's 1.0 by default and just configurable with ColliderDensity. It computes the mass properties corresponding to each collider using the given density, and then a system later computes the total mass properties for the rigid body, taking into account collider transforms

#

Bodies connected by joints are completely separate physics objects, joints aren't related to mass in any way

#

other than the impulses applied by joints of course taking mass into account

frail robin
# vestal minnow <@243426730851696640> Should be fixed: https://github.com/Jondolf/avian/pull/520

Found another way to cause desync even with the latest main. Opened with a minimal reproducible example:
https://github.com/Jondolf/avian/issues/522

GitHub

The previously discovered desync from #516 has been fixed in #520. However, I found another way to cause a desync on the latest main. Here is a minimal example to reproduce: collider_bug.zip Copy i...

vestal minnow
#
  1. Sure, that's basically what Mass/CustomMass here is, plus the Additional variant. Tbh we could also remove Additional and only have Override, it'd be much simpler and more consistent with most other engines.
  2. The internal representation needed by physics is different, so this doesn't really work. And it would add a lot of extra branching to internals since now there are two possible sources of truth.
  3. I don't understand what "propagating mass" means or how it'd be useful. If you mean just saying that "this rigid body has a mass of 100 kg" and want to have that get split between children based on volume, then sure, we could do that, but functionally it's the exact same as just overriding the rigid body's mass and allowing the angular inertia and the center of mass to be automatically computed for child colliders. The actual mass values of the colliders don't necessarily matter for the behavior of the rigid body. What matters is the mass of the rigid body entity and how large the colliders' masses are relative to each other to produce the correct inertia tensor (which will then be scaled by the true mass) and the correct center of mass. Managing lists and affecting joints adds a ton of complexity and I'm having trouble imagining what it'd even mean.
#

Something we could add for joints is something like PhysX's mass scaling, but that's different

vestal minnow
#
  1. This would make so many cases unnecessarily painful, as you don't have direct control over what the actual mass of the rigid body is, and instead have to think about how it'll be computed from the attached colliders. I don't know any engine that doesn't have a way to override mass, other than maybe bevy_rapier, but I might just be forgetting how to do it there.
  2. I think I'm just not understanding what you meant. Did you mean that mass properties are automatically computed by default, but if you add an OverrideMass marker component, the engine won't update mass automatically and you can instead freely modify it? (like Unity's autoInertiaTensor boolean)
  3. This seems kinda niche and confusing, but if we added this, I'd just add a system param like MassPropertyHelper with a method that takes in a list of entities and the desired mass, and then distributes it to them, overriding their masses.
#

With mass overrides you can technically do anything, and have custom logic for updating things if you want to, but with Additional you can't, or it's at least much more annoying

rustic rock
#

hi, another question... what I must do to avoid bounce on a dynamic body that collides with a static body? I've declared this Restitution::new(0.0).with_combine_rule(CoefficientCombine::Min), over the player entity (dynamic) but still bouncing after a collision.

fleet orbit
#

I couldnโ€™t find a way to fix it on my side, should I open an issue on GitHub about it?

rustic rock
vestal minnow
rigid tinsel
#

Hello

Do I really need Rigidbody::Static if all I want is a collider for some ground and walls, or adding just a Collider works too?

rustic rock
# vestal minnow Tiny bounces are expected because of how contact solving works, but they should ...

thanks for reply @vestal minnow I figured out maybe the problem is in my systems, not in the collisions detection (or bounce effect).

The problem is that the player's entity has LinearVelocity component. This value is updated constantly by the movement system (plugin 1). There is a another system (plugin 2) handling the collisions.

And finally, there is a last system (plugin 3) which is constantly showing the player's LinearVelocity value. So, when a collision happens, the velocity is updated (in parallel?) due to the bounce... What I need is to freeze the LinearVelocity value when the collisions happens.

Now, the value is frozen but 1 or 2 frames after the collision. I must define an specific runtime systems' order with Sets?

glad eagle
proven ice
#

anyway to set the origin of my collider?

#

rn my hierarchy looks like this:

(Player, TransformBundle, InputManagerBundle<Action>)
    (PlayerPhysicsBodyBundle: TransformBundle, RigidBody, Collider, LockedAxis, Restitution)
    (SceneBundle)
    (Camera3dBundle)
#

id like to move the physics stuff into the player parent entity

mossy salmon
#

Is there a way to set the Friction component in a bundle? I was trying to add it to the dynamic_character_2d example but I keep getting a duplicate component error, I assume because Avian automatically adds it along with the RigidBody::Dyanmic component. I can work around it with systems but I'd rather just set it up in the bundle if possible.

lucid cloud
#

I think I have kind of a dumb question: How come Half Life 2 and Banjo-Kazooie run on f***ing potatoes with 60 FPS at least and my little ittie bittie room with 4 walls and three dynamic objects stutters and is not able to run smoothly even on release mode on my 2015 macbook pro? (I'm sorry for the swearing)

#

Sorry, I'm really frustrated ๐Ÿ˜ข

cinder summit
#

Wrong as in trimesh-trimesh collisions

lucid cloud
#

The 3 dynamic objects use convex-hulls generated at runtime

cinder summit
#

My game used to bottleneck on physics (as recently as bevy_xpbd 0.5) because I run multiple ticks of physics per frame, but since upgrading to avian that bottleneck disappear, and most of the frame time now goes to the UI library I use bavy

lucid cloud
#

Thanks, I will try to use a profiler.

vestal minnow
#

Conflicts are also only an issue when you have duplicates in a single insert, separate inserts will just overwrite.

mossy salmon
vestal minnow
#

Hehe no problem ๐Ÿ˜…

vestal minnow
lucid cloud
cinder summit
lucid cloud
rigid tinsel
# glad eagle you need a static rigidbody aswell, without it you just go through them, the poi...

Oh, I see! So, a sensor/trigger/area/volume, essentially

So, this is how it works, correct me if Iโ€™m wrong:

  • if I add only a collider, itโ€™s a no-op. Nothing happens. I go through. And I canโ€™t detect anything because itโ€™s not a sensor
  • if I add collider + sensor, I go through it but I can use it as a sensor
  • if I add collider + static rb, It behaves as a solid and I collide โ€ฆ
  • โ€ฆ unless I add a sensor too, in which case itโ€™s a sensorโ€ฆ with a static collider that is useless / expendable
glad eagle
rigid tinsel
visual sparrow
vestal minnow
#

Yes, that's essentially the current behaviour. Open to changing this to treat colliders without rigid bodies as static bodies at some point though

#

Afaik that's what e.g. Unity does

#

it's just a bit more annoying implementation-wise, we'd at least need one-body constraints

visual sparrow
#

I'll say that once I got used to Avian's model, there is a certain elegance to it

#

The only thing that I find confusing is that Sensor is not required to have sensor behavior ๐Ÿ˜›

vestal minnow
#

I think a decent split would be:

  • RigidBody is a unit struct, and represents a dynamic body by default.
  • Add a Static marker to make the rigid body static (also used by e.g. rendering, see old PR).
  • Add a KinematicCharacter marker to make the rigid body kinematic and controllable via e.g. collide and slide logic.
  • Collider on its own only exists for spatial queries. By default, it can't register collisions without participating in the simulation, attached to a rigid body.
  • Add Sensor to ignore collision response and make the collider trigger CollisionStarted/CollisionEnded events, but maybe not compute actual contact data, and instead just detect intersections, which is more efficient. For example Rapier and Box2D have separate events for sensors.
visual sparrow
vestal minnow
#

But then StaticBody and the hypothetical first-party Static marker would do the same thing here

visual sparrow
vestal minnow
royal helm
#

where was that code we made in here that made those boundary walls for a cylinder

#

hmm

royal helm
#

just remade it and now ive been nerd sniped on calculating the radius of the furthest points of the walls

cinder summit
# vestal minnow I think a decent split would be: - `RigidBody` is a unit struct, and represents ...

This sounds pretty decent. Especially not having Collider do things by itself anymore ... The KinematicCharacter sounds a bit weird considering non-character kinematic bodies do occasionally get used (I remember with gltf physics that moving platforms were used as example for kinematic bodies). We would still be missing the case of Sensors that don't get added to spatial queries (which is often the more desirable behavior, since sensors often only exist to report collisions and not to be detectable)

royal helm
#

because i wanna calculate a width to perfect seam the walls together based on the thickness/radius, i think it requires iteration unless someone much better at math took a shot at it

cinder summit
cinder summit
royal helm
#

no no

#

im making a circle with walls

#

and you see how that black line lines up with the center? I need to get that very tip of the edge that is the outer most point here

#

that'd let me correct that seam in the back

#

i suppose the width at the center stays the same so maybe I dont need iteration

cinder summit
royal helm
#

ya

#

i can sort of solve it here

#

actually wait

#

hmm

#

its an approximation of a circle

#

essentially

cinder summit
#

Oh you're doing the slightly different approach where they aren't literally just chords

royal helm
#

chords?

cinder summit
#

A line on one point of a circle from another

#

I remember struggling with it to figure out the correct placement of these hallways thonk

royal helm
#

ya i think it both cases you end up with the same problem

#

that just comes from the thickness of the walls

#

well ill just do some good ol pythagorous and call it a day

#

i dont think its perfect

#

because whatever

cinder summit
#

I'd probably just place the start/end points on the circle and give them some thickness and extra length so they overlap nicely

#

Or well, that's what I would've done if I didn't have arc colliders thonk

proven ice
#

oops i didnt mean to send that as a reply ๐Ÿ˜ฌ

royal helm
#

@cinder summit I got it lol

#

realized its really a kite

vestal minnow
#

And yeah we could make it so that sensors aren't included in spatial queries by default, but you can opt in to including them

vestal minnow
#

Might also make documentation nicer in some ways since you can document the different types of rigid bodies separately (and probably link to some shared docs)

#

And filtering queries would of course be nicer

sleek thicket
royal helm
#

there's prob ways to simplify it by a lot I was just bored and decided to do the math

#

just fun to mess around with geometry sometimes

#

really the simplest way would be take points, midpoint of them for position, push in by half thickness

vague pebble
#

@vestal minnow you know what would be nice a ragdoll example

#

I am gonna go ahead an do one

vestal minnow
vague pebble
#

thing is u need to make a collider per bone

#

I think

#

in 3d

sleek thicket
#

animation -> ragdoll

#

maybe even with some kind of a mix like wolfire did to make it seem more natural

vague pebble
#

But ragdoll is good for explosions

#

Boom flies away and i like explosions

sleek thicket
#

you can do both though

#

character running around in circle around TNT
click on character to use sniper rifle, or press a button to detonate tnt.
press another button to reset.

dark zinc
#

is there a reason for colliders detaching from sprites when they're loaded from a RON?

gaunt niche
rustic rock
#

Still stuck in same problem, reading more docs about Avian2d I've figured out that maybe I've a misconception about what (and how) I need to obtain.

When my player (dynamic rigid body) collides with a static platform, the player's linear velocity (y axis) is modified due to a bounce effect (even if resitution value is 0).

When the collision happens, the player's linear velocity (y) is set to a zero value. But, how can I preserve the value just before the collisions does?

rustic rock
vestal minnow
dark zinc
#

I found a workaround by adding a custom component which marks the player spawn point and then spawn the player like that, thank you for answering though ๐Ÿ˜Š

dark zinc
#

i'm back :/, not for a good reason though:
My sprite can somehow walk through Colliders from the side, but not from the top. This is obviously a massive issue, and I'd really appreciate any help. Thanks

lucid cloud
#

This is more of a general question: How do big studios/big engines handle colliders in large levels with lots of geometry? Is it all custom colliders or do they just generate trimeshes from everything (I heard that's bad) or what do they do? Having used Avian for a few weeks now, I can't really imagine a concrete workflow for this scenario

cinder summit
lucid cloud
cinder summit
#

Yea LOD is level of detail

#

Convex decomp in the way avian has it (which comes from parry and is thus the same as what rapier has) relies a lot on the resolution yea. It's also quite slow, which means ideally we'd be able to do asset preprocessing for it

lucid cloud
#

Ah, right, I think I read somewhere that Jondolf wanted to wait for assets v2 to do preprocessing on meshes to get colliders. What happened to that project? Or is it just time โ„ข๏ธ ?

cinder summit
#

We have assets v2, but it's really not in a great spot atm. We can't process a gltf file into a scene + mesh + materials, and then add on extra things like colliders

vestal minnow
#

time + some other priorities + I think Bevy's asset preprocessing is still somewhat half-baked, or at least not well documented

#

(and what Nise said yeah)

lucid cloud
#

Thanks for clearifying, folks ๐Ÿ™‚

vestal minnow
dark zinc
#

i'm using colliderconstructors if it makes a difference

rocky seal
#

how do i turn on gravity? i've tried added the Gravity resource and adding a GravityScale component. i set my object to start at y = 100 and expect it to fall but it doesn't move in that direction

#

does it need mass?

junior flower
junior flower
# junior flower We have LD make the game in white box using cubes. Art comes later and builds th...

Mesh-colliders are too โ€œslowโ€ once you get to a certain scale. Itโ€™s very rarely worth it. Even characters with โ€œdetailedโ€ colliders are generally just a bunch of spheres or capsules

Itโ€™s extremely rare to hear people talk about whether or not a collider is more than just a sphere, capsule, or cube, and Iโ€™d expect that convex decomposition isnโ€™t even in the majority of game folksโ€™ dictionaries, let alone something they do regularly.

For clarity, my experience is coming from 50-100 sized studios, maybe 10-15 programmers per game

rocky seal
glad eagle
#

Can we modify transform just for the collider?

#

Without affecting the entire entity

gaunt niche
cinder summit
# glad eagle Can we modify transform just for the collider?

You can make it a child entity of the rigid body, giving you an extra Transform. If physics needs to move it without affecting the parent the entire rigid body could possibly be a rigid body (less sure about this on tho). Alternatively if you just want an offset you can do some stuff with compound colliders or collider types that have built in positions (like capsules with capsule_endpoints)

lucid cloud
royal helm
#

but yeah for anything that moves I'd steer clear of convex hulls/trimeshes

cinder summit
#

I guess that's also a workflow we're seeing more and more now. Having tools in your engine that create landscape and reasonably efficient colliders at the same time

#

It honestly really just depends on your workflow, if you do grayboxing your final level probably ends up keeping a large number of those efficient colliders, if you start with the art you'll go for convex decomp or a convex hull whenever it's not as simple as throwing a shape or two on there, and if you use engine tools you tend to have whatever the engine gives you

#

For my game I kind of do the latter, since I create SDFs that I both render and use for collisions ๐Ÿค”

rocky seal
#

i just have a cone i'm dropping onto a collider made from a Plane3d, but it goes right thru. the page in the docs about CCD suggests making walls thicker than they strictly need to be to avoid this. a plane of course can't be any thicker. what's the best thing to use as a collider for a floor? a long thin Cuboid?

lucid cloud
rocky seal
#

ohh that makes sense

#

thanks!

royal helm
#

from what I remember parry just constructs a trimesh underneath a heightfield

#

also regardless I think convex hulls are fine for static objects

#

convex decomp... not as great but good for creating things faster

#

I just see convex decomp the same way I see nanite, a tool to speed up creation of assets

tacit shore
#

Folks, sorry to bother but I was wondering how to go about creating explosions using avian 3d. I was thinking about an expanding collider, but that would be missing the force. Should I just manually add the forces? Or is there a better way

junior flower
# lucid cloud Thank you for the additional info ๐Ÿ™ That sounds really solid! Could you explain...

Like ใ‡ฃ โŒฃโŒฃ ใ‡ฃ said yes, LD = level designer.

Once you get to a certain scale, "fail fast" and "teams can work independently" become more and more important.

On "Fail Fast":
There's no point in making art for an area if the area's layout is fundamentally broken, so you start with whitebox, playtest, and once the layout is finalized, only then does the art team go in and flesh out everything with meshes. If you have tweaks to the layout later, the art will tweak after that new layout has been finalized again. This leads to art and collision not always matching but the cost of that is less than "we wasted the art team's time on an entire area and threw it all out".

On "Teams can work independently":
Since scenes are usually monolithic, you'll generally see e.g. collision, spawners, art, etc all in separate scenes. Unreal gets around this with their one-file-per-actor thing, but I've seen people avoid it because it's confusing to see 100s of files with diffs when as far as the artist is concerned they only edited a single scene. In Unity, we generally separate as I said above, though it's less of an issue since the yaml that it's stored in is often mergable.

Other places you'll see "teams can work independently" is e.g. not directly placing a particle system inside a model, but instead having some asset that stores e.g. offsets and attachment data. The model instead references that asset. This means that someone can be changing the prefab/blueprint/scene of a character and the VFX team can make adjustments to the location of the VFX without file conflicts, for example.

Smaller/personal projects generally don't prioritize these things (I know mine don't) so I'm sure there's going to be folks with different opinions on how these things should work. I just happen to have experience in larger-scale projects so figured the information would e useful.

#

On heightfields/mesh colliders:
Like NiseVoid says landscape/terrain are generally heightfields. Unreal's definitely is, and since you can't have overlapping sections I assume that Unity's is, too. These are much cheaper than a full-blown mesh collider since the distance becomes a single function.

cinder summit
#

Realistically tho, there's plenty of studios that do the reverse, making art first then kitbashing it together and only needing to do minor touchups at the end (the benefit here is that the time from start to finish is shorter because the art was already made, similar to using assets). Convex decomp can really shine there. And I think ultimately you just kind of bend physics to whatever fits your (team's) workflow

junior flower
#

I have a feeling it's probably related to genre if there are studios that don't actually whitebox.
Not exclusively, but I work on a lot of platformers, so the geometry is obviously core to the gameplay there.

I firmly believe that this is at least part of the reason that a lot of modern games play like crap: the collision is a mess because it wasn't whiteboxed first and is based on what an artist has made -- the collision is based on how it looks, and not how it should be for gameplay.
A couple of games that come to mind for this are early PubG, early Icarus (neither of which I've played recently, so maybe they've improved)

I think you're right about the art being distracting, too.

Even characters btw: we've always started with boxes. Literally a single box for weeks while we iterate on gameplay.

#

and is based on what an artist has made
This isn't a dig at artists, btw. Just that gameplay concerns are different to art concerns.

cinder summit
#

Boxes for characters? No capsules? Blasphemy! ๐Ÿ˜‚

#

Also modern games don't have good collisions and don't have collisions that match art ... Honestly I don't even know what some of these studios are doing ๐Ÿ˜‚

junior flower
#

For a 3D game it's usuall a cylinder rather than a capsule. 2D is boxes. The curves don't play well with corners

junior flower
vestal minnow
tacit shore
#

Awesome!! So do an spatial query, expanding each frame, and applying impulses on entities collided. To calculate the direction it would be the hit entity translation minus the query position, right?

#

If I make a good one, would you like me to add it to the examples?

vestal minnow
#

And yeah, an example could be nice if it ends up working well ๐Ÿ˜„

tacit shore
#

Oh so just one?? Iโ€™ll try that. Yeah Iโ€™ll share an example since it would help me see if itโ€™s correct, and the repo to have one, so itโ€™s a win-win. Thanks!!!

sleek thicket
tacit shore
#

so is a projectile, that explodes when it hits, more or less the logic is:

  • spawn projectile with collider
  • when projectile hits, "explode"
  • damage "enemy"s only once per hit, and push them outwards from the hit location
sleek thicket
#

yea i use intersections for that

cinder summit
tacit shore
#

Wouldn't that be a hitscan? If I need to use different projectile speed, isn't a collider the best idea?

cinder summit
#

No, because the ray/shapecast doesn't need to be infinitely long, you can have it be 1 frame worth of movement, then move it forward by that amount (or to whever it hit if it can't pierce enemies)

sleek thicket
#

i think collider (sensor) is better, no chance to miss a collision

cinder summit
#

Which will naturally be a no-go for any game with many projectiles

sleek thicket
#

i guess if there's no fast movement then it's fine

tacit shore
#

so the idea for this case is you can see projectiles moving, similar to a space invanders (they are faster, but not real-bullet speed). In that case, would you do a raycast from the projectile itself?

sleek thicket
#

do they leave empty space between fixed updates?

#

e.g. if enemy moves from 1,2 to 3,2, and bullet moves from 2,1 to 2,3 that means collision would be missed by raycast

tacit shore
#

yes, that can happen. I think eventually I'll have faster projectiles, which will be hitscan. This exploding projectiles will be fairly slow

#

specially compared to some enemies

cinder summit
sleek thicket
#

you can shoot down a rocket

cinder summit
#

Yea, if you have something like that you kind of need them to be physics objects anyway

#

Otherwise projectiles can't seen projectiles (which is kind of the key to why it scales well with many projectiles)

#

Any game that needs both projectiles that behave that way and ones that don't can of course mix and match these approaches

#

Using Sensor for projectiles would also get better if we can actually exclude them from the BVH ๐Ÿค”

tacit shore
#

The are enemies that can "dash", and also you can hit "enemy projectiles"
Sorry, but what is BVH?

cinder summit
#

A BVH is a spatial acceleration structure. It's used for avian's ray/shapecasting (and iirc jondolf was also working on using a bvh for the broadphase, idk what the state of that is tho)

#

If you add tons of things to it that never need to get hit, things inevitably get slower

tacit shore
#

ohhh makes sense. So I used collider for bullets, because some of them need to have weight to push back, and the attributes can change a lot. I think a sensor/raycast would require adding that logic that already comes from collisions

#

(BTW thanks for all the feedback, I'm new to this, so it helps me learn a lot)

cinder summit
#

Yea it's a lot nicer to just get info on what to consider rather than having to learn things the hard way

#

Back when I first tried to make my game I had to rewrite projectiles like 3 times because it was so easy for it to cause lag (I have a multiplayer game with multiple skills that fire multiple projectiles, so there can be a lot of them in the world at once) ... Tho that was also when I still used godot, which generally hated having many colliders more than avian does

tacit shore
#

So if the hard way, is the better approach, I'm willing to learn. My conflict right now is, if I raycast, and calculate the push, and consdier fast movement, etc. isn't that the same calculation load as using a collider? Specially considering that avian will be more optimized than my stuff

#

BTW what is a lot of colliders?? 100?? 1000? Honestly asking, I don't know how to estimate taht

cinder summit
#

The first version I built (in godot) got to about 900. I think similar approaches in avian got to about 1500. But that is in a world with only projectiles, on a game that's already somewhat heavy, adding just a few hunderd could get you in trouble

#

The version I have now handles tens of thousands no problem, because it only scales O(n), instead of O(n * log n) or O(n^2) that you'd get when every projectile can hit every other projectile

sleek thicket
#

i don't really understand why people make fast-moving projectiles at all, or make slow-moving projectiles that you can only dodge

tacit shore
#

Ohhh makes sense, so is not about colliders, but about how many collision queries, right?? Is it related to layers?

#

sorry @sleek thicket what do you mean?? The concept I'm working with is that you can configure your attacks, some people prefer slow hard hitting, and another fast hitting projectile (AK-47 vs RPG, and the line in between)

sleek thicket
#

i guess for bullet hell it might be fine, and that's basically the only time where you'll really see a rain of projectiles

sleek thicket
cinder summit
sleek thicket
#

yeah, maybe

#

ultrakill also has parry on every projectile including your own and it worked out really well

tacit shore
#

Yes, you can, and enemies can

#

I would say every projectile (except for laser weapons)

sleek thicket
#

but ak bullet is tiny and fast, so why not just use raycast

#

without nise's over-time stuff

cinder summit
# tacit shore Ohhh makes sense, so is not about colliders, but about how many collision querie...

Layers are fairly relevant here, but they aren't the full story. They allow you to skip collisions before having to calculate them, which saves some of the more expensive work, but you still need to iterate trough more things and check more masks to get the collisions. Because of that having say 3 projectiles makes the implementation pretty irrelevant, while with 3000 it could be more than 1000 times slower

tacit shore
#

so the thing in my case is that you have a weapon, and can add modifiers. Most weapons will be on the slower side, that is why I use colliders. Maybe I'll nedd to use threshold for raycasting

#

What other ways are to optimize if not layers?

cinder summit
# sleek thicket but ak bullet is tiny and fast, so why not just use raycast

Yea implementing hitscan weapons with projectiles is definitely a huge mistake ... It kind of works when you try to do the battle field thing with travel time and bullet drop, but you can still just have them be raycasts ... Even if bullets could hit bullets, it not like you would notice it should've happened ๐Ÿ˜‚

sleek thicket
#

yeah that's a fair point

cinder summit
#

The 900 projectiles in godot might've actually been the sensors version tho thonk

#

But the 1500 in avian was definitely rigid bodies ... The projectiles could bounce off of things (but possibly not eachother)

sleek thicket
#

maybe i should copy your homework then, since none of them need real physics anyway

tacit shore
#

It is something interesting, deciding what to use for projectiles, and where the threshold is more a hitscan, where a raycast makes sense. I'm thinking maybe disabling collision if the projectiles are past all enemies, and things like that to optimize the amount of entities

#

is it possible to disable collission but not other physics?? like velocity, etc?

#

Just removing the collider right?? keeping the rigidbody

cinder summit
#

Not sure actually, but worst case you can just make your own system to integrate velocity on Query<(&mut Position, &Velocity), Without<Collider>>

rocky seal
#

i'd like to have an object hover at a constant height. i have tried this:

fn setup(mut query: Query<(&mut ExternalForce, &Mass)>) {
    for (mut force, mass) in &mut query {
        force.apply_force(Vec3::Y * 9.81 * mass.0);
    }
}

which i reckon ought to cancel out the pull of gravity. but the object still falls down (albeit more slowly)

cinder summit
spiral nymph
#

Hey,

I don't understand how you check the components of these entities from there, for example detecing if it collided with a mob or an object

fn print_started_collisions(mut collision_event_reader: EventReader<CollisionStarted>) {
    for CollisionStarted(entity1, entity2) in collision_event_reader.read() {
        println!(
            "Entities {:?} and {:?} started colliding",
            entity1,
            entity2,
        );
    }
}
rocky seal
#

i'm happy to do it just need some direction

vestal minnow
#

Then for mass properties, I have an implementation on a secret branch for my mass property crate bevy_heavy. It's not for Parry, but works as a reference, although I'm not entirely happy with how I implemented the principal angular inertia

#

(I have verified it to be correct by comparing it with angular inertia computed from a point cloud generated with rejection sampling though)

vestal minnow
zinc talon
#

Can custom constraints constrain separation velocity? Like, if I wanted two objects to be moving away from each other at a certain rate?

#

I'm working through the documentation on custom constraints but my brain is fried

#

I kinda want to know whether it's possible before I commit a few days to learning

vestal minnow
#

That sounds like joint motors, and it's something that'd probably be easier with impulse-based joints (which we'll switch to eventually/soon-ish)

#

With position-based constraints though, the general idea for joint motors is that you have some target position/orientation that you change every frame

zinc talon
vestal minnow
vestal minnow
#

I'm not sure yet how custom constraints will work once we have a fully impulse-based solver and implement things like simulation islands

zinc talon
vestal minnow
#

(sry if that's a confusing explanation)

#

this would also be easier with impulse-based constraints

zinc talon
zinc talon
vestal minnow
#

some things like this are more straightforward to do at the velocity level, but actually deriving the math for the constraints and implementing the core logic is often significantly more complicated than it is with position-based constraints, at least in 3D

#

I've been thinking of writing a blog post / article on constraints and how they fundamentally work, with all the nitty gritty details

#

I started a draft some time ago but haven't finished yet

#

For XPBD, you mainly just need the position constraint function, which is typically relatively easy to get with some trigonometry and geometry. For impulse-based joints, you need to also differentiate that with respect to time, find a form that lets you extract the Jacobians, use that to determine the effective mass matrix, bias things based on the position constraint error, take possible softness parameters into account...

#

though I suppose some of that can also apply to XPBD if you have block solvers to constrain multiple DOF at once

zinc talon
#

I got some readin to do

timber cape
#

has anyone made a pong/breakout/similar game using a kinematic body for the ball that they can share?

rare shale
alpine oak
#

hey i'm trying to design some additions to the AnyCollider trait, which would enable it to be a little bit more general.

i'm prototyping the idea I had right now, but I'm not super familiar with the design of avian internals. I would like to know what you think about the following:

  • Add a GAT to AnyCollider which is used to provide extra context to operations like computing manifolds. I've implemented this as a simple type Context: Component in this prototype, but perhaps extending it to support a full Query and use QueryLens would be cool.
#
  • add Option<&Self::Context> to each method in AnyCollider. decided to go for an Option, because there are some cases where a context isn't critical, and might not exist for the entity e.g. when initialising
#

with this in place, we can extend the queries in the broad and narrow phase plugins to optionally query for the context as well, and pass it along when interacting with the colliders

#

an example use for this is the voxel collider i'm using for my game, where the voxel data is stored as a component on my entity using a sparse octree. In order to mutate the voxels safe and efficiently, I implemented deferred updates to this data. Originally my VoxelCollider had an arc rwlock to this raw data, but that was quite error prone because the bevy scheduler didn't take that into account when scheduling other systems. This lead to some fun deadlocks ๐Ÿ™ƒ

using the context i described above allows me to have bevy figure out the access to the voxel data.

visual sparrow
cinder summit
timber cape
#

his multiplayer pong does use rapier unfortunately
his other infinite pong game uses xbpd but uses dynamic rigidbodies instead of kinematic
im avoiding dynamic bodies because they seem to have issues with losing velocity when they collide weirdly even with no friction and perfect restitution (as shown in that video)

timber cape
#

this is what i have so far, it seems like im close but its still very clearly broken and idk how to fix it amirmir
the bounce looks ok on the off chance it actually bounces so i think my math is correct there but i dont really know whats causing them to get stuck

fn handle_ball_brick_collisions(
    mut collision_event_reader: EventReader<Collision>,
    brick_query: Query<Entity, With<Brick>>,
    mut ball_query: Query<(&Ball, &mut LinearVelocity, &mut Position)>,
    mut commands: Commands,
) {
    for Collision(contacts) in collision_event_reader.read() {
        let e1 = contacts.entity1;
        let e2 = contacts.entity2;

        let (ball, mut ball_velocity, mut ball_position, brick, ball_is_first) =
            if let Ok((ball, velocity, position)) = ball_query.get_mut(e1) {
                if let Ok(brick) = brick_query.get(e2) {
                    (ball, velocity, position, brick, true)
                } else {
                    continue;
                }
            } else if let Ok((ball, velocity, position)) = ball_query.get_mut(e2) {
                if let Ok(brick) = brick_query.get(e1) {
                    (ball, velocity, position, brick, false)
                } else {
                    continue;
                }
            } else {
                continue;
            };

        commands.trigger_targets(
            BrickDamaged {
                damage: ball.damage,
            },
            brick,
        );

        let normal = if ball_is_first {
            contacts.manifolds[0].normal1
        } else {
            contacts.manifolds[0].normal2
        };

        ball_velocity.0 = -(2.0 * normal * ball_velocity.0.dot(normal) - ball_velocity.0);
    }
}

any tips on how i could improve this?

sleek thicket
cinder summit
#

If it was bevy_xpbd losing velocity, it's possible that the new solver fixed it at least, if it's lost slowly you could also just reset the length of the velocity vector constantly

reef root
#

I have a question regarding my mesh generation. The chunk generated by my mesh consists of unoptimized geometry, where each face has 4 vertices and 2 triangles that I don't really care about. I'm wondering if it's logical to use a generated collider for the ground, where the player can only walk on it. Also, can I use raycasting to get the grid position?

To give some context, the world is endlessly generated, similar to Minecraft, and I want to add a player that can walk but not pass through walls.

Hereโ€™s the code for the chunk generation if anyone wants to test it: GitHub link

#

So is it possible to do that with Avian can't find anything on generating custom collider

spiral nymph
wide oar
#

Hi I am having this jittering issue when using FixedUpdate in avian2d (this disappears if I uses PostUpdate)

    // Physics
    //
    // we use Position and Rotation as primary source of truth, so no need to sync changes
    // from Transform->Pos, just Pos->Transform.
    app.insert_resource(avian2d::sync::SyncConfig {
        transform_to_position: false,
        position_to_transform: true,
    });
    // 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(
        PhysicsPlugins::new(FixedUpdate)
            .with_length_unit(100.0)
            .build()
            .disable::<SyncPlugin>(),
    )
    .add_plugins(SyncPlugin::new(PostUpdate));

    app.insert_resource(Time::new_with(Physics::fixed_once_hz(FIXED_TIMESTEP_HZ)));

    app.configure_sets(
        FixedUpdate,
        (
            // make sure that any physics simulation happens after the Main SystemSet
            // (where we apply user's actions)
            (
                PhysicsSet::Prepare,
                PhysicsSet::StepSimulation,
                PhysicsSet::Sync,
            )
                .in_set(FixedSet::Physics),
            (FixedSet::Main, FixedSet::Physics).chain(),
        ),
    );

(am using avian2d 0.1.2)

wide oar
#

hmm I fixed it by changing the FIXED_TIMESTEP_HZ to 60.0 instead of 64.0

vestal minnow
#

Yeah, Bevy's default 64 Hz fixed time step is much worse for jitter in my experience

#

Ultimately the "real" fix is to have transform interpolation

cinder summit
#

Once we're done with some of the current set of engine work we should start that interpolation work group, the number of people that suffers because of not having interpolation is getting stupidly high ๐Ÿ™ƒ

vestal minnow
#

yeah transform rework + interpolation would be good for 0.16

#

I'll probably add built-in physics interpolation for the next Avian release too tho

spiral nymph
spiral nymph
#

Sorry for the french XD

sleek thicket
#

it doesn't have to be empty, i used optional values at first but removed them later

spiral nymph
#

Maybe I should do this, because I'm making components IsPlayer, IsEnemy, IsGround

sleek thicket
#

i handle isPlayer by collision layers but it's only for triggers, most of my systems aren't supposed to care about that

#

and ground is either layer or without a tag

#

tags are mutually exclusive, and that means you can't use it for everything

spiral nymph
#

yeah like filtering query in system

#

you can't use With filter with an enum value

sleek thicket
#

i'm still searching for a better way to handle it, but for now it works better than other stuff i've seen

spiral nymph
#

i'm doing it like this since i'm using components

fn bullet_collision_system(
    mut collision_started_event_reader: EventReader<CollisionStarted>,
    bullet_query: Query<Entity, With<IsBullet>>,
    hit_query: Query<Entity, With<stats::Health>>,
    mut bullet_damage_event: EventWriter<BulletDamageEvent>
) {
    for CollisionStarted(entity1, entity2) in collision_started_event_reader.read() {
        for (e1, e2) in [(entity1, entity2), (entity2, entity1)] {
            if bullet_query.contains(*e1) && hit_query.contains(*e2) {
                bullet_damage_event.send(BulletDamageEvent(*e2));
            }
        }
    }
}
sleek thicket
#

yeah that's basically what i switched out of

#

like, think about it this way

spiral nymph
#

hum... but if you need more than entity, like each bullet has its specific damage, then you need entity + bullet damage
and it need query
or you manage it in eventreader

sleek thicket
#

bullets are just "source of damage"
enemies are just "something that can be damaged"
eventually you'll have ground/walls that you want to destroy, which is just an "enemy" that you can step on
and "bullets" that can be killed (by other "bullets")

#

and the tag system just sorts out the entities to know the exact order of what i'm dealing with, and handle everything else in the next event system

edgy estuary
spiral nymph
red shale
#

Speaking of performance, Is avian physics comparable to rapier within an order of magnitude, or is one vastly more performant?

cinder summit
#

Within an order of magnitude most likely yes ... The performance goes a bit both ways depending on circumstances right now, I think rapier is a bit faster for average circumstances and still has a few more features, but avian has better UX and provides some benefits bevy_rapier doesn't (tho you could get them when using rapier directly I think)

#

I would say "avian also gets more active development" but jondolf has been busy with some engine dev stuff lately so that's not entirely true right now

vestal minnow
#

will be back working on Avian stuff in a week or so hopefully

#

or when required components migrations, mesh picking, and primitive ray casting are done

cinder summit
#

Casually mentioning 3 massive features ๐Ÿ˜‚

peak timber
wide oar
#

wanted to ask tho, is there TrimeshFromMesh equivalent collider constructor for avian 2d?

glad eagle
#

how can i multiply forces by delta time? right now if i limit my fps it looks like its in slow motion

cinder summit
#

Forces are already in a unit applied over time, if you want to instead apply some amount of force for one frame, impulses would be the way to go and the input value would need to be for the given time delta

glad eagle
#

how about gravity?

cinder summit
#

Gravity is applied like forces by default by avian, tho you can change the global gravity with a resource and set the gravity scale per entity. If you need custom gravity (like in games like mario galaxy) you'd set the force to match the gravity of the thing applying gravity to you

sleek thicket
#

@glad eagle if you're on main then it's already in fixedupdate so it should be consistent without delta

sleek thicket
#

i think you can change from default schedule to fixed as a placeholder, not entirely sure if it'll be the same

glad eagle
#

i'll check it out tomorrow

thin hare
#

is there a way to do something simmilar to cast_ray_with_predicate and recieve the point of intersection?

vestal minnow
#

you can get the point of intersection as just ray_origin + ray_direction * hit.time_of_impact

thin hare
#

Nice, I should really bone up on my understanding of actual physics to intuit these things haha

formal galleon
#

i had previously posted about trimesh colliders because my character (the hedgehog) keeps falling through the ground from time to time. the suggestion was to avoid using a trimesh collider. however, my game levels include forests and mountains, so i canโ€™t do without uneven terrain. since i didnโ€™t get any solution back then, i assume i canโ€™t resolve this well with avian yet (donโ€™t get me wrong, avian is awesome!). but how is this generally solved, for example, in UE or unity? or, what feature is avian missing to make this possible?

cinder summit
#

If the issue is passing trough objects then the solutions to those problems would be colliders with volumes. To some extent that is kind of an implementation detail, tho it's really hard to make trimeshes behave like they have volume, and often the meshes don't have volume either

#

UE and unity both are really starting to push for things like terrain generation tools in engine which seem to largely be based on height maps, which you could easily implement in a way where they have volume

#

And since they both come with an editor it becomes substantially easier to manually add colliders to scenes to (tho maybe this could become easier with bevy's current workflow too once gltf physics are standardized)

#

With how avian currently is, convex decomposition or convex hulls are the easiest solution, tho they have their own share of problems

#

And since rapier and avian use the same collision library, rapier would at best have the same issues, and at worse have even more issues on top

vestal minnow
#

In general, (static) trimeshes shouldn't have issues where other non-trimesh objects randomly fall through them, unless maybe if there is some wonky geometry involved. Does it happen in specific spots, and in what circumstances? If it happens to be related to the mesh having weird topology issues, then enabling some TrimeshFlags when constructing the collider could maybe help fix them

#

and yeah in an ideal case colliders would have volume, and you'd be able to avoid trimeshes, but static geometry like this is generally a fine use case for trimeshes

#

or maybe preferably heightfields if it works for your specific terrain

cinder summit
#

Having dynamic colliders also be trimeshes is where issues start. trimesh-trimesh is extremely slow and two colliders without volume aren't going to have very useful collision data

vestal minnow
#

yeah, there's a lot of physics engines that just straight up don't let you make trimeshes dynamic at all

#

afaik Parry's implementation should be a bit more robust for that in particular than the average trimesh colliders in engines, but still not perfect

#

e.g. many engines store trimesh colliders as just a list or BVH of triangles, with no pseudonormals or other special handling

#

(if I remember correctly at least)

tacit shore
#

Hello Folks, sorry to bother again, but I have a bit of a question, about "sensing". For enemies to attack they need to be in range. Right now I'm just doing a Vec3::distance to determine that, but I was wondering if a sensor would be more efficient. It would also help me if there are enemies in front. But wasn't sure and wanted to ask for feedback (hope this is not annoying)

royal helm
#

technically the distance could still be faster if you put in more effort and did a bvh there as well

#

but I use sensors generally

#

it's just faster to set up and get what you want from my experience and the performance hit is negligible

tacit shore
#

ohhh awesome!! I'm planning on lots of enemies, but I'll try with sensors and see if I need to adjust. Thanks!!

royal helm
#

if you find the performance a problem then you should be able to use avians bvh manually i believe

#

gl!

royal helm
#

tbh even better would be something like @cinder summit's SDF stuff for sensors I think

#

since you dont really need all the extra complexity, you just need "am i touching it"

tacit shore
#

sorry what are you refering to?

royal helm
#

SDFs would just give you the same thing as colliders but maybe faster

#

im not entirely sure though since the colliders probably use something like an SDF in their "is in area" function

#

but you could do cool stuff like unions and concave shapes lol

vestal minnow
#

(SDF = Signed Distance Field or Signed Distance Function)

tacit shore
#

I think I need something like that, since the calculation can get complex, the logic is more or less (for ranged enemies):

  • If player is not in range, start navigation calculation (this is separate process)
  • if player is too close, move away
  • If player is in range, ray cast to the player
  • if there is an obstacle, use the normal to move to unblock line of sight
  • else start shooting.
    This needs to be done on many enemies (I want to make it work for 100 ranged + 100 melee that have another logic)
    Doing this with sensor would require 2 (one for in range, one for too close). I was thinking of disabling the sensor when the player is in range, and turning them on in intervals just to save some cpu, but I'm sure there is a better way
sleek thicket
tacit shore
#

What do you recommend? Using Vec3::distance? (Again thanks for all the feedback and ideas, I love this community)

sleek thicket
#

yeah, or square distance if you want an insignificant optimization

#

and a really simple system for switching states or writing events

fleet field
#

Hey all, I have little intuition on the efficiency of ray casting. I'm making a simple 2d platformer. For basic enemies that move back and forth on platforms, it is typical to cast rays every frame to check if they reach the edge of the platform and turn around? For this I would want to add a RayCaster component to the entity. What if I also wanted to cast a ray in front to check if they've run into a wall so they could turn around, I can't add a second RayCaster component, should I be adding a child entity with RayCaster for each ray I want to cast? Or just use SpatialQuery?

#

Adding child entities for RayCaster is a bit ugly to me, as I am using bevy_ecs_ldtk to automatically spawn in the enemies from my ldtk level file, so I would need to add an Update system to add those child entities to each enemy the frame after they are spawned in. Is there a more ergonomic approach to this problem?

sleek thicket
fleet field
#

hmm, good point. may as well write it one way, can always optimize later

vestal minnow
#

Okay, so I have yet another idea for the mass property rework:

Just have Mass, AngularInertia, and CenterOfMass. No separate components for additional mass or overrides. But, it'd work like the following:

  • No Mass specified -> compute Mass from colliders, taking into account their densities.
  • Mass specified -> use that for the initial value.
  • By default, if colliders are added after the body's initial creation, their mass is added to the body's mass.
  • By default, if colliders are transformed or their densities are changed after the body's initial creation, the body's mass properties are updated accordingly.
  • Automatic mass property updates can be disabled for individual entities with the NoAutoMass, NoAutoAngularInertia, and NoAutoCenterOfMass components.
  • Automatic mass property updates can be disabled globally by just disabling the MassPropertyPlugin.

Additionally, there would be a MassHelper system parameter (like TransformHelper) that lets you manually recompute mass properties based on attached colliders at any time, or do any other updates you might want.

#

Compared to previous proposals, this would have benefits like:

  • Reduced API surface. There's a single source of truth, no separate "custom mass" and "computed mass" or similar. Also less memory usage.
  • More flexibility. You can choose to opt out of automatic mass computation completely and modify things as much as you want.
  • Sensible defaults. If you do nothing, mass is automatically computed from colliders. If you specify it manually, that value is used. If you add more colliders later, mass takes that into account, unless you choose to opt out.
  • More ECS-friendly. The marker components just act as filters for disabling automatic mass computation. No need to check enum variants or check for optional components.
  • No confusing semantics in terms of what components are required and what components are purely configuration.

This is also quite similar to Box2D, where mass properties are computed automatically when shapes are added, but you can manually set or adjust it at runtime, and use b2Body_ApplyMassFromShapes to revert it to the mass determined by shapes.

#

I think I like this version quite a lot, and it might be the simplest as well. I might start experimenting with this, but it'd be nice to hear what others think

#

lemme cross-post to that discussion actually (edit: here)

cinder summit
#

"if colliders are added after the body's initial creation"
How do we define when this happened?

vestal minnow
#

In practice it'd be after queries no longer match Added<RigidBody> for that entity. Things like ColliderConstructor might require extra care since they can construct colliders in a deferred way

#

Could maybe have a SparseSet marker component that is added when the rigid body is spawned, and removed when all collider constructors present at spawn have been removed

#

But yeah that part is slightly trickier / an open question here

cinder summit
#

One other option would just be to track manual creation vs automatic creation, by adding a marker (or storing it in a field on these types) when the value was calculated rather than user provided

#

If it's user provided, automatic mass changes would never make much sense, because the mass could be say 20, while it has 2 colliders that each have more than 20 mass, so removing either gives you negative mass bavy

vestal minnow
#

yup, that's also a potential issue, but it probably would just need to be documented

#

it'd also probably clamp to zero so you can't get negative mass

cinder summit
#

Zero mass isn't great either ๐Ÿ˜‚

vestal minnow
#

I guess the question is, given this setup:

  • Rigid body with Mass(10.0)
    • Child collider with Mass(20.0)

which of these would you expect?

  1. Rigid body's mass is 10.0 + 20.0 == 30.0
  2. Rigid body's mass is 10.0

Option (1) might make more sense here when the child's mass is explicitly specified, but for the general case of this:

  • Rigid body with Mass(10.0)
    • Child collider, mass computed automatically

you'd probably expect it to be an override imo

cinder summit
#

One option would be to make the user be more in control of when mass gets computed? ๐Ÿค”

#

Like instead of defaulting ColliderDensity to 1, it could be the thing that enables the optional "calculate density" stuff

#

Then always add up collider mass if those properties actually exist, because you either: 1. Enabled calculation; 2. Specified it manually

vestal minnow
#

Most people would probably expect just this to work

commands.spawn((
    RigidBody::Dynamic,
    Collider::circle(5.0),
));

but with that approach it'd have zero mass and break things. Unless we had a "default mass" of 1 or something, which afaik is what Godot and Unity actually have

#

At least angular inertia and center of mass should be automatically computed by default, otherwise you'd get very wonky behavior for a lot of things

#

And not having it work the same for mass would be kinda inconsistent

#

and confusing, especially since we don't have an editor that would explicitly show you "this body has a mass of 1 kg by default"

sleek thicket
#

i think editor is better for doing stuff like that, and in the editor you probably won't need to hide anything

sleek thicket
cinder summit
#

But I do agree it definitely shouldn't just explode or something just because you forgot to specify the mass ๐Ÿ˜‚

vestal minnow
# vestal minnow Okay, so I have *yet another* idea for the [mass property rework](https://github...

The main thing I'm trying to avoid with this ^ proposal is having separate components storing "computed mass" and "user-defined mass", as well as make things more flexible. Having two separate storages makes you unnecessarily duplicate data and makes the semantics more confusing. Which one is the actual source of truth, and are both components required, or just one of them? Component naming is also harder

vestal minnow
sleek thicket
#

yeah, didn't we arrive at the same conclusion the last time?

vestal minnow
#

Maybe? Idk lol

sleek thicket
#

iirc the issue was how to do it, and not what to do D;

#

and i still think density really overcomplicates everything

#

it sounds cool on paper, but would probably better as a helper function than a component

#

if unity can get away with defaulting to 1 mass then why not here too

cinder summit
#

In the old proposal OverrideMass would still have a value iirc

merry gulch
#

Hello. Is there any conditions based on which I should choose to use kinematic or dynamic character controller?

sleek thicket
vestal minnow
#

so I guess the only change to my proposal would be that Mass at spawn doesn't override unless that marker component is present

cinder summit
vestal minnow
#

So,

  • Rigid body with Mass(10.0)
    • Child collider with Mass(20.0)
      produces a mass of 30, but if the rigid body has NoAutoMass, it's 10
cinder summit
#

Still feels a bit footgunny in that specifying mass defaults to being an addition, the thing you are least likely to want ๐Ÿค”

vestal minnow
#

yeah

#

that's why I went with the overriding behavior in my proposal

#

for the initial spawn

merry gulch
sleek thicket
#

meanwhile kinematic needs you to essentially rewrite everything from scratch

merry gulch
#

well... then...

cinder summit
#

Also worth keeping in mind that people probably already wrote decent character controllers, picking based on what's out there can be better than starting from scratch unless you need something very specific

#

Even floating character controllers, which are probably the easiest to write, are annoying to get right ๐Ÿ˜‚

sleek thicket
merry gulch
cinder summit
vestal minnow
sleek thicket
#

don't overthink it too much, you'll probably get an urge to rewrite everything once editor is ready ๐Ÿ˜…

vestal minnow
#

will just need documentation for the "mass properties of child colliders are added on top at spawn unless you have NoAutoMass" thing

#

instead of overriding by default

#

It's actually somewhat similar to what we already have I think, with a few differences

sleek thicket
#

yeah, that part should still be good even with editor

#

might need a better name though

vestal minnow
#

for NoAutoMass?

sleek thicket
#

yeah

vestal minnow
#

yeah probably, I mainly copied the NoWireframe naming Bevy has

#

just ManualMass, ManualMassComputation, or OverrideMass could work too, although they sound a bit less like marker components

#

NoMassFromColliders :P

sleek thicket
#

NoMassGainedFromChildren ๐Ÿคฃ

#

AutoMass just sounds like it changes mass itself, rather than adding them up

#

either way you can take you time with bikeshedding, i can't come up with anything good either

vestal minnow
#

It does change the Mass itself for the rigid body, since the masses of child colliders are added to it

#

with this approach

#

unless we do the ComputedMass thing, which I don't love

sleek thicket
vestal minnow
#

ColliderMassProperties isn't changed, that still has the actual mass of the collider, taking density into account

sleek thicket
#

so e.g. i have an object that alternates its' mass between 2 values, it should be completely fine even if it has parent/child colliders?

vestal minnow
#

You can set the rigid body's Mass at runtime, which will override it. But you could also first recompute the mass properties given by child colliders using MassHelper, and then add whatever additional mass you want on top

#

The semantics are

  • Mass is the single source of truth for the mass of a RigidBody. You can overwrite it at any time if you want.
  • At spawn, Mass is set to whatever value you specify (or zero by default), plus masses of child colliders, unless you have NoAutoMass.
  • Each collider has a ColliderMassProperties component for the mass properties computed based on the shape and density. When this is changed/added/removed, the rigid body's mass properties are updated accordingly, unless the body has NoAutoMass etc.
  • If you manually specify Mass, AngularInertia, or CenterOfMass for a child collider, that will be used instead of the computed value in ColliderMassProperties.
sleek thicket
#

marker components should be good even if you completely change how everything works on the background

vestal minnow
#

Might want to rename ColliderMassProperties to ComputedColliderMassProperties as well to make it clearer it's specifically the mass properties computed for the collider, not necessarily what is actually used (since you could have Mass on a collider too with this proposal) and not something people should modify

#

also make fields private with public getters

sleek thicket
#

NoAutoMass still doesn't sound right
ideally it'd have a word similar to inheritance, but in reverse... i just can't come up with anything that fits perfectly
and yeah, we also need a better word for readonly components D;

#

we need a bikeshedding channel

vestal minnow
#

what should its name be? /s

#

we should have an SME-Bikeshed

#

just ask them and the name they give is final

#

boom, problem solved

#

problems arise when you have more than one SME-Bikeshed

sleek thicket
#

bikeshedding-containment-channel ๐Ÿ˜‚

#

btw what happens if you want to gain mass from some children but not the others? use mass helper?

vestal minnow
#

you could just set the mass of those colliders to zero, although that can also affect the total angular inertia and center of mass for the rigid body since it'd change how mass is distributed

#

which may or may not be desired depending on what you're doing

#

or use mass helper for obscure things, probably

vestal minnow
#

I intend to merge #500 tomorrow, which yeets InverseMass and InverseInertia in favor of just storing them in nicer Mass and AngularInertia components, and caches GlobalAngularInertia. Will probably do a quick test to see if there's any perf difference

GitHub

Objective
Part of the ongoing mass property rework proposed in #499.
Currently, the inverses of Mass and Inertia (poor name, since mass is also inertia) are cached in the InverseMass and InverseIne...

#

and then do the bigger API and behavior changes and refactors

vestal minnow
#

ooh just noticed that AngularInertia in 3D actually shouldn't store the inverse, only the cached GlobalAngularInertia should

#

the inverse of the local AngularInertia isn't used anywhere in 3D, but the actual tensor is used once in a hot loop

#

bleh, I don't think it matters though since you'd need the inversion for GlobalAngularInertia anyway, so you end up with the same number of ops per substep

vestal minnow
#

works towards yeeting PreparePlugin, makes it possible to disable automatic mass computation completely, and adds a nice place for docs and new mass functionality

#

I'm also prepping a PR to refactor SyncPlugin into a PhysicsTransformPlugin and PhysicsHierarchyPlugin, which makes all of that logic more encapsulated, shrinks down PreparePlugin further, and also fixes some duplicate systems and makes scheduling nicer

cinder summit
vestal minnow
#

yea

#

one was run if any entity matched Added<RigidBody>, and the other if any entity matched (Added<Collider>, Without<RigidBody>), so they didn't necessarily overlap at all times, but it's easy to merge them into one anyway

cinder summit
#

Wasn't that only the run condition and not the system itself?

vestal minnow
#

run condition, yeah

#

so sometimes both could run

#

I could maybe also have an observer that propagates transforms only for trees with added physics objects, but it probably wouldn't be faster if you spawn many entities at once, like at startup

cinder summit
#

The "fast" option there would be storing the entities to process in a list and only update what is in the list

#

Until we get buffered observers or archetype-level change detection anyway

crimson crest
#

As a sort of stress test for Avian I've decided my next project will be a modular vehicle building game. Think of say From the Depths or Space Engineers

#

Entirely in space so I can focus entirely on the ship building without worrying about lag coming from anywhere else

#

I suddenly got recommended an ancient video series from Quill18 about modular spaceships which brought about this idea

crimson crest
#

Jondolf, how well do you think Avian could handle 100k-ish cubeoid colliders since that's about worst case scenario since I want each block destructible

sleek thicket
wide oar
#

May I know what is the proper way to mitigate the physics jittering when using FixedUpdate at the moment?

I have inserted Time::<Physics> with the correct value using โ€œfixed_once_hzโ€ but the issue keeps coming back even if I used 60hz ๐Ÿคฃ.

#

I have thought of keeping a separate Update schedule to interpolate the transform from positions. But Iโ€™m not sure how..

wide oar
#

I worked out a solution in case anyone is interested...


fn player_visual(
    mut q_transforms: Query<(&mut Transform, &mut PreviousPosition, &Position)>,
    fixed_time: Res<Time<Fixed>>,
) {
    let overstep_frac = fixed_time.overstep_fraction();
    println!("overstep {:?}", fixed_time.overstep_fraction());

    for (mut transform, mut prev_position, position) in q_transforms.iter_mut() {
        transform.translation.x = FloatExt::lerp(prev_position.x, position.x, overstep_frac);
        transform.translation.y = FloatExt::lerp(prev_position.y, position.y, overstep_frac);

        prev_position.0 = position.0;
    }
}
#

run this in FixedUpdate

vestal minnow
#

the latter only works on Avian's main branch currently, and requires using Position and Rotation for changing positions of physics objects

#

mine is a bit more general and not tied to Avian, and lets you modify Transform directly

wide oar
#

oh wow did not know this hahaha, that's nice to knoww :D

vestal minnow
vestal minnow
#

simulation islands would also be important here, which we don't have yet

thin hare
#

Is there currently a branch using required components?

vestal minnow
#

Nope, not yet

#

I'll probably make the main branch use the 0.15 rc once it's out

thin hare
#

noice, any knowledge on an ETA for the 0.15 rc? I'm itching for it haha

vestal minnow
#

hopefully friday-ish this week I think, there's mainly just the UI required components migration (which has a draft PR) and some rendering fixes blocking the release

#

if not this week, then next week

thin hare
#

Will avian need some PRs to integrate with it? I'd love to try and help

vestal minnow
crimson crest
crimson crest
#

Only really needing Avian for the first pass for determining if the ship's rigidbody intersects something, then I'll probably being my own internal math to determine what voxels were hit and all that sort of stuff

thin hare
#

Are ConvexHull colliders more costly just when they're first instantiated or are they more costly as the app runs as well?

cinder summit
#

Compared to what?

thin hare
#

Compared to building colliders out of primitives like cuboids and spheres

#

I'm working on some physics based platforming and for things like ramps I was wondering if it's a big perf hit to just build a ConvexHull from the mesh itself

cinder summit
#

Convex hulls are decently performant, especially if the number of points is low. Of course compound colliders from primitives could outperform it

#

In comparison convex decomposition is a lot more costly to generate, and a bit slower than a hull (because you can end up with a lot of hulls)
Mesh colliders are the real ones you want to be avoiding tho

vestal minnow
#

Convex hulls are slightly more expensive than most primitives, but cheaper than trimeshes or large compound colliders built with convex decomposition (which just outputs many convex polyhedra)

#

Also convex hulls and convex polyhedra are basically the same thing here; there isn't really a ConvexHull collider, it just constructs a ConvexPolyhedron from the computed convex hull

vestal minnow
crimson crest
#

@vestal minnow What are your thoughts on using SDFs to define the "real" collision data for my objects, bad idea?

cinder summit
#

You mean using SDFs as colliders?

crimson crest
#

There's going to be a rough pass from avian for bounding box checks before I do a custom pass with my own logic for which voxels of the ship are intersected.

#

Oh wait I can probably just pass Parry's voxel type to Avian actually

cinder summit
#

I don't think parry has voxel collisions. But you could define your own collider type, if it's a voxel signed distance field I'm not entirely sure what the performance would look like tho

crimson crest
#

Parry has voxel collisions but apparently I can't manually construct the voxel data type, I have to pass in a mesh

cinder summit
#

In my game I use avian with a custom collider based on signed distance functions, and it works fairly well, but of course using your own collider type means you need to implement even basic things yourself

crimson crest
#

Tbf I basically need to do most things myself regardless

#

Avian would be my broad phase and I'd have a custom narrow phase, basically

cinder summit
#

You most likely don't need a custom narrow phase, only a custom component and implementation for AnyCollder and ScalableCollider

#

And for the latter you can also kind of cheat like I did:

impl ScalableCollider for SdfCollider {
    fn scale(&self) -> avian3d::math::Vector {
        bevy::math::Vec3::ONE
    }
    fn set_scale(&mut self, _: avian3d::math::Vector, _: u32) {}
    fn scale_by(&mut self, _: avian3d::math::Vector, _: u32) {}
}
crimson crest
#

Oh yeah no my volumes definitely won't be scaleable, though I do plan to have two different grid sizes, I'll code that as different collider types lol

cinder summit
#

Anyway if you want to do something with voxelized colliders it might be worth seeing how people normally approach this, there's quite a few fancy mini voxel games with physics after all

crimson crest
#

Again though I'll basically need my own logic since I need to determine which voxels are intersected which is why I'd rather have a fully custom narrow phase where I can generate that data for myself\

cinder summit
#

The AnyCollider trait is the one generating the collision data

#

It might even have a spot to store extra info

crimson crest
#

I guess I could probably mark the voxels hit as contact manifolds?

crimson crest
#

It feels wrong to do that though

lunar bluff
#

is there any way to disable physics temporarily for a particular entity? I don't want to pause the whole physics plugin by stopping time, I just want to pause particular entities.

#

Should I just remove the RigidBody component, then put it back later?

vestal minnow
lunar bluff
#

thanks

vestal minnow
lunar bluff
#

nice one man, thats awesome ๐Ÿ‘

subtle epoch
#

HI ,I want to create a grapple hook skill where the rope shoots out from the players hand slot towards a fixed point and then pulls the player towards the target point (as the rope retracts). What physics implementation would be more suitable for the rope part?๐Ÿค” I saw an example in Avain is chain example, but Im not sure if thereโ€™s a more appropriate choice.Any help would be greatly appreciated.

vestal minnow
#

If it doesn't need to bend in the middle and can just be a single "line" between the player and target point, it could be enough to have a DistanceJoint and decrease the max distance limit over time

#

If it needs to bend and stuff, you'd probably need many smaller segments, but the retraction part will be trickier since you'd probably need to dynamically remove joints as the rope gets smaller... not sure about the best way to handle that

#

Stability might also become an issue if you have a ton of small segments in a long chain. One trick to prevent stretching of the overall chain is to add a joint between the first and last segment, to limit the distance between them

subtle epoch
oak vigil
#

Hey, what's the best way to differentiate entities inside CollidingEntities between entities which are in contact vs. entities that are completely inside the collider?
Do I need to do shape cast...?

#

I can only seem to find the API to detect intersections. Is such a thing even supported?

soft horizon
#

HI, im just starting out with avian.

Is there a way to debug render the shape of colliders so i know the match with my meshes?

vestal minnow
soft horizon
#

Ahh i see, that is fantastic

spiral nymph
#

CollisionStarted work with ColliderFromTrimesh ?
I tried implemented HitDamage and HitObstacle, but it seems like my map collider is not triggered

hexed veldt
#

I'm getting the following error randomly with avian

thread 'main' panicked at ... avian3d-0.1.2\src\collision\collider\mod.rs:327:9:
assertion failed: b.min.cmple(b.max).all()

Anyone has any clue on what might cause the issue?

cinder summit
#

Looking at the code I expect NaN

vestal minnow
#

Most likely the position or rotation becomes NaN for some reason, which messes up the AABB and causes the panic

#

the panic should only happen in debug mode IIRC

cinder summit
#

Yea it's a debug assert

hexed veldt
#

BTW, I'm running the collision check system in FixedUpdate schedule, could that be the reason? I used to run the system in PostUpdate without any issues

vestal minnow
#

I doubt it, FixedUpdate should be fine

#

the main branch defaults to FixedPostUpdate now

hexed veldt
#

Any recommendation on how to debug this? It happens randomly so I can't figure out which part of my code is causing the crash

vestal minnow
#

Hmm, make sure you at least don't have dynamic rigid bodies with zero mass or inertia colliding with things

#

I don't recall really getting that panic in a long time ๐Ÿค”

#

The only way I think it can happen is if you're getting NaN values somewhere, or maybe if you have negative scaling on some shapes, but I don't remember the latter being an issue

#

If there are NaN values then it's most likely a mass issue or some bad instability issue, like a joint chain that explodes, or a collision bug that somehow produces NaN contact impulses

#

but it's hard to say

hexed veldt
#

I don't setup mass or join chain in my code at all. I didn't see this error before. I'm picking up my project from 2 months ago and currently changing some Update based systems to use FixedUpdate instead, and now see this error.

#

Also, all my objects are RigidBody::Kinematic and I'm manually checking collisions and despawn objects on hit

vestal minnow
#

Is it random as in you get the panic on some runs but not others, or you can get it on any run at some random point in time?

#

If you can't get the panic at all sometimes when running the project, it definitely seems like a scheduling order issue

hexed veldt
#

It's the latter case. If I run the code for sometime, it will crash at some point.

vestal minnow
#

hmmm, strange

#

I can't really think of anything on the physics side that would cause that panic for kinematic bodies

hexed veldt
#

Well, I think I noticed something useful. Whenever I switch the game to the background and let it run a while, it will crash; Keeping it in the foreground seems fine

#

Maybe it's related to my change from Update to FixedUpdate

vestal minnow
#

Did you configure Time when switching? In Avian 0.1, when running in fixed timestep schedules, you should use Time::new_with(Physics::fixed_once_hz(60.0)), or whatever timestep Hz you want. In the next release this won't be needed

#

not sure if this is related to the problem, but worth mentioning

hexed veldt
#

No. I didn't setup that. Let me try that

#

What does it do? Curious

vestal minnow
#

So Avian 0.1 had it's own custom fixed timestep loop that ran in PostUpdate by default, and the timestep could be configured with Physics::fixed_hz. But when you're running physics in FixedUpdate, this leads to two different fixed timesteps, which could conflict and cause weird behavior. So, we had a Physics::fixed_once_hz option, which simply advances time by the given timestep every time the schedule is run, instead of managing a custom fixed timestep loop

#

The next release removes a lot of the complexity and custom scheduling, and simply runs physics in the given schedule with the timestep configured for that schedule. So it uses a fixed timestep out-of-the-box in schedules like FixedUpdate, and a variable timestep in schedules like PostUpdate

hexed veldt
#

Adding Time setup doesn't fix the issue. I'll dig more. Thanks for the help @vestal minnow

clever quail
#

Hi is this the place, for clicking and dragging to select say like in age of empires?

#

I am thinking if I spawn a plane that grows as my mouse drags out then use collision detection it would work?

fiery mortar
#

Does continuous collision detection support sensor to sensor collisions?

fiery mortar
#

followup question, do shapecasts hit sensors?

vestal minnow
#

(That's what Box2D and most other engines I know do as well. They don't support CCD for sensors afaik)

vestal minnow
fiery mortar
vestal minnow
#

not 100% sure, I haven't planned sensor optimizations that much yet

#

Basically, what we'll likely do for sensors is to only perform intersection tests for them, and have them send intersection started/ended events, but not compute actual contact data since it's more expensive and often unnecessary since it won't be used by physics at all

#

Speculative collision relies on computing closest points using the contact computation algorithm, so it won't work with sensors if we only do cheap intersection tests

fiery mortar
#

Okay, that makes sense. I think I will store my shapes and use parry3d directly then.

gritty estuary
#

Hi Jondolf, any news on the big_space compatibility? I know it's been a few months since you talked about it, but I don't know if you've tackled it yet.

vestal minnow
gritty estuary
vestal minnow
#

0.15 RC 1 just dropped ๐Ÿ‘€

#

I'll try to update the main branch for it within the next couple of days, hopefully tomorrow

alpine geyser
#

hi there! is there an example of how to make a cart (actually an inverted pendulum in my case, but I'm not fussed either way) with independently rotating wheels that can be spun? (I'm on 0.1.2, but I'm happy to use main or the RC)

I have my body spawned and wheels for it, and I've attached RevoluteJoints to them, but I'm not sure that the wheels are actually rotating independently from the body itself. I'm also attempting to apply ExternalTorques to the wheels, but they don't appear to spin, regardless of which axis I use or whether I apply them in worldspace or modelspace.

here's my existing code: https://gist.github.com/philpax/41b89a0ac19723ddb527554fe2a03f49

it's definitely held together correctly (see image). I found this issue https://github.com/Jondolf/avian/issues/254 but I'm not sure if it's relevant as my wheels are correctly oriented relative to the body ๐Ÿค”

cold frigate
#

I was trying to make a script to build the crate locally (because of the weird crate structure) but failed so I'm just going to remake my merge request for adding Default to ColliderConstructor so I can get this component into space_editor ๐Ÿ™

glacial nebula
alpine geyser
royal helm
gaunt niche
alpine geyser
# royal helm try moving the wheels further from the body and see what happens

apologies for the delay, I was extracting it into a learnbevy playground: https://learnbevy.com/playground?share=930668d992d533d0e1c01537c086ccd716b58b370bf4b9bdf8abf81cf1067d5a

that makes the wheels floppier (i.e. they're free to tilt towards/from the body along the axis from which they've been displaced), but they still aren't spinning as far as I can tell

you can use I/K O/L to speed up/down left/right wheel respectively, U/J/M to set the axis upon which the torque is applied, and Y to control whether the torque is multiplied by the wheel's transform upon application. no combination of settings are producing my desired behaviour (the wheels spin, resulting in the body being lifted off the ground / moving in the direction of the wheelspin)

elder creek
#

Hey guys, what's the recommended way of setting up a scene with avian2d? I'm trying to do this:

    app.add_systems(
        OnEnter(GameState::InGame),
        (
            setup_spaceship,
            setup_planets,
            setup_spots,
            spawn_turrets,
        )
            .chain(),
    );

But my issue is that spawn_turrets uses a SpatialQuery to cast rays relative to rigid bodies spawned in setup_planets and it's unable to get any hits. If I run the system once in the FixedUpdate schedule, the rays hit correctly. I tried replacing spawn_turrets, above with spawn_turrets.after(PhysicsSet::Sync), but it had no effect. I'm not 100% confident yet on how schedules are run in Bevy, so I'd appreciate if someone could help a bit.

alpine geyser
#

I'd suggest using a spawn query in a system running on Update, so that you can react to the spawning of your rigid bodies; you can use additional filters / conditions to ensure that it only runs once

elder creek
#

Time to read the doc

#

Thanks for the suggestion! I was kind of hoping I'd be able to do it with OnEnter(GameState::InGame) as that feels cleaner but oh well

alpine geyser
alpine geyser
#

(there may still be a way to schedule it, mind you, but the reactive approach is probably simpler)

elder creek
elder creek
cold frigate
vestal minnow
# cold frigate https://github.com/Jondolf/avian/pull/539

Having a default for colliders seems a bit strange to me. The choice of a "default shape" is very arbitrary, and there isn't really an obvious default that would make sense. If I had to choose, I'd probably pick a 1x1x1 cuboid for 3D and 1x1 rectangle for 2D, but I'd prefer if the default wasn't necessary at all. I feel like that should rather be an editor-level thing, not a requirement imposed for every component

cold frigate
vestal minnow
#

The "aligned axis" is the axis that the bodies are allowed to rotate about

#

Here's a top-down view, I'll try to explain it better

#

The axle is what the local aligned axis of the bodies should be

#

Cylinder colliders are upright, so you need to rotate it to be sideways like a wheel

#

But you don't want to rotate the body itself, since it'll make the aligned axis not work how you want

#

Ideally we'd have "local frames" or reference rotations for joints so you'd be able to configure how rotations are treated easily, but that's WIP at the moment. I think for now you need to use a child collider for the wheel

alpine geyser
#

hmm, I think that makes sense

#

but if I rotate the collider (through a child collider), won't it be out of sync with the rendered mesh?

vestal minnow
#

you could put the mesh on the child entity too

#

So the "forward" direction of the wheel parent entity will be the forward direction of the cart, in the direction the wheel rolls. But the mesh and collider will be rotated to be oriented correctly

alpine geyser
#

aha

vestal minnow
#

Yep, it should

elder creek
#

Is there any obvious reason why spawning a RigidBody::Dynamic near another would immediately trigger a collision when spawned with a big LinearVelocity vs not triggering the collision when not adding any LinearVelocity? (The velocity isn't pointing toward the second body.)
Could this be because of a lack of precision? I could try to produce a minimal example but it'd take a little bit of time so if there's any obvious step I could try to take before doing that it would be great

vestal minnow
#

sorry wrong ping, meant to reply to your new message

vestal minnow
#

We might be able to fix this in the future, by updating the BVH automatically in lifecycle hooks whenever you spawn colliders. But I haven't tried that yet

elder creek
vestal minnow
#

Sure, do you have a link or something?

elder creek
#

I need to push a commit and make the repo public, will ping you when it's done, thank you! ๐Ÿ™‚

#

So the setup is: there is a terrain that's procedurally generated made with a compound of capsules and I spawn the spaceship (represented by a rectangle) on it. When pressing space, an event is created that triggers the spawning of a projectile here: https://github.com/noomly/lunar-lander/blob/main/src/main.rs#L358. In this configuration, as soon as you press space to spawn the projectile, the latter collides instantly with the terrain. If you remove the LinearVelocity attached to it, you'll see that it only collides with it after falling down. The projectile is despawned as soon as it collides with something, here: https://github.com/noomly/lunar-lander/blob/main/src/main.rs#L1150. The collision points are drawn through a debug system here: https://github.com/noomly/lunar-lander/blob/main/src/main.rs#L200.

elder creek
vestal minnow
#

Thanks, I'll try it

#

need to mess with my toolchains or something though, seems like I need nightly Cargo

elder creek
#

if it doesn't work on your machine you can probably just remove .cargo

vestal minnow
#

yeah it wasn't liking codegen_backends even on nightly :P just removed it for now

#

@elder creek So the issue can be fixed by adding SpeculativeMargin::ZERO to the bullets (to disable speculative collision), but I think it's still a bug. It shouldn't be triggering a collision if there isn't actual overlap and the contact impulse is zero, like in this case

elder creek
#

Not awesome for the bug though

#

Do you need me to try and make a minimal reproduction & open an issue?

vestal minnow
#

An issue would be nice, yeah ๐Ÿ™‚ A minimal repro would of course be ideal if you feel like making one, but that reproduction in your project is probably enough too

rigid tinsel
#

Hello, is there any way to tell Avian that instead of moving the transforms it should apply the positions and rotations to some other alternative components instead?

I have my own custom Physics Position components that I propagate to the transforms at the end of my frame

clever quail
#

Am I safe to hide these messages? WARN avian3d:๐Ÿ’ฅ:narrow_phase: Entity { index: 2781, generation: 1 } and Entity { index: 9662, generation: 1 } are overlapping at spawn, which can result in explosive behavior. I am ok with this behaviour my use case is an asteroid belt and I want to split them apart. I am too lazy to fix spawning

#

If thats still to dodgy I have another idea

#

but my current plan is asteroids have physics then I turn them off as physics for an asteroid belt is quite laggy

cinder summit
clever quail
#

RIP Dinos

clever quail
vestal minnow
#

(I haven't tested this myself, but I think it should work. Avian is intended to technically be usable without Transform)

clever quail
#

I am having so much fun with Avian thank you

vestal minnow
#

Hmm, just got a very ๐Ÿงช and mildly ferris_spooky idea ๐Ÿค”

#

If we supported components and query filters in spatial queries, like SpatialQuery<&Enemy> (which I already got working locally a while ago), we could maybe make each of those systems maintain their own BVHs that only have those entities. This could make building and traversing those BVHs much faster, and also ensure that the system has up-to-date data

#

Of course this could be slower if there are many systems that have overlapping but slightly different filters, such that there end up being many similar BVHs. Would need thorough profiling at least

mossy salmon
#

Sorry if this is out of scope, but is there an easy way to have colliders generated from LDtk files? We're using bevy_ecs_ldtk to load the level, and currently adding a collider to each cell of the intgrid, but having rectangle colliders side-by-side causes issues when the character is moving over the boundaries.

Is there something already in place to create a single collider per cell island, or is this something we would have to implement on our own?

clever quail
#

Sorry I posted and deleted, is there a way to make a torus that is hollow on the inside so some stuff can bounce inside it. Inside the rings, (not the donut hole)
I probably want to do the same for a sphere

sleek thicket
sleek thicket
vestal minnow
#

I'm also not sure how an abstraction based on layers would work, unless you mean updating the BVH every time you actually call e.g. cast_ray. But that could make it more expensive if you call it many times within the same system, and caching might be more difficult

#

Hmm or it might need to work like that anyway, I'm not sure if we can make the system param execute any logic before the system runs, probably not... It could avoid duplicate calls by just tracking system change ticks

sleek thicket
#

yeah i'm not sure how i'd implement it either, with unity's 1 layer per object i'm imagining they create BVH per layer

#

do godot's layers work same as avian?

vestal minnow
#

Yes I believe it's the same nowadays, except they only have one mask/filter by default while we have all

#

both have only one membership by default (layer 1)

#

*on the main branch

sleek thicket
#

put in on a thought board and let it brew, i guess
there's something that feels wrong with layers in every engine, but i'm not the right person to figure out how to make it better ๐Ÿซ 

vestal minnow
sleek thicket
#

like if there's a layer that only interacts with players then by default it's weird that you're checking anything other than player

#

maybe you can figure out how to make layers more ECS-y

vestal minnow
#

That would be marker components

rough nebula
#

What does avian2D use for units of measurement exactly?
As far as i understand its in pixels but like how does it convert that to SI?

vestal minnow
#

There's a PhysicsLengthUnit that you can set to specify a kind of "pixels per meter" conversion ratio, which can help with stability, so that for example with 10 pixels per meter, a speed of 20 px/s would be treated as a more sensible 2 m/s by physics

#

The "ideal" approach from a physics POV would be to scale your camera's projection instead, so that you can specify your objects' sizes in meters, and that is rendered as however many pixels you want

#

But generally it should be fine to use pixels, at least if the length unit is configured appropriately

mossy salmon
somber rampart
#

@vestal minnow if you have any more progress I will rebase my changes against those otherwise I'm happy to PR. Can try to tackle the couple of !unimplemented too

vestal minnow
#

PR for current main would be nice

somber rampart
#

It's not too hectic

#

Mostly unsure about how to refer to the parry, I can publish my fork of that and refer to that or whatever you think is best

vestal minnow
somber rampart
#

I like the name

vestal minnow
#

You can point to my or your own git repo with the Nalgebra update

#

either way is fine

somber rampart
#

It seems as though you have it under control ๐Ÿ™‚

vestal minnow
#

Yeah I can also do the 0.15 update myself now, I did about half of it yesterday

somber rampart
#

What did you do for impl Shape for EllipseWrapper -> scale_dyn?

vestal minnow
#

I didn't migrate those yet but I'll look into it

somber rampart
#

OK if you haven't looked at those I will PR against your barry it will save you some time probably

#

Most are simple like this but a couple a bit more challenging

#

Thank you

severe urchin
mossy salmon
crimson crest
#

Just to update nalgebra or?

vestal minnow
#

The main branch changes Nalgebra to Glam and stuff but that's WIP and I probably don't intend to finish it, I'd rather make my own collision lib (which I'm doing... slowly)

#

but this is just for the Nalgebra update

crimson crest
#

Any particular reason you're making your own?

vestal minnow
#

But

  • We don't want Nalgebra
  • I want to use Bevy's bounding, primitive shapes, and (future) ray casting instead of having duplicates in Parry
  • I'd like to use Griffin's OBVHS instead of Parry's Qbvh
  • Parry has that weird crate structure, I want to see if I can avoid it
  • Parry has a lot of dynamic dispatch, I want to see if enum dispatch is better
  • A lot of Parry's algorithms have room for optimization
  • Maintaining a Parry fork would be difficult without knowing how everything works; implementing things myself helps me learn
  • Parry's code quality and docs are pretty poor in a lot of places, benchmarks are broken, and so on, I'd honestly rather re-implement things than clean it up :P
  • Parry is only Apache-2.0 licensed, not dual-licensed like Bevy and Avian (probably not a huge deal though)
    There's enough fundamental things I want to be different that I don't think just modifying Parry is ideal, and it's not what I personally want to do
crimson crest
#

I've not worked with obvhs

#

Don't adisagree with the comments on Parry's algos and code quality though, when I was trying to dig into it to write my custom voxel physics logic I kinda realized its kinda

#

Not bad but lacking

clever quail
clever quail