#Avian Physics
1 messages ยท Page 25 of 1
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
merging inverse and making read-only can be done without changing the rest of the stuff, right?
Yeah, I have a PR for this 95% done
That'd be really great
Okay so I think there's three cases we might care about:
- Derive mass automatically from colliders based on the given density (defaults to
1.0)- Maybe default to a mass of
1.0if no colliders exist, to prevent wonky behavior caused by zero mass
- Maybe default to a mass of
- Set the mass of the rigid body, and add masses of child colliders on top
- 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.
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
i have no idea how everything works on the background, so what i'm imagining is being able to set that single object's mass with a function for either 1 or 2 without considering children, then something else handling the hierarchy and overrides
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?
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 of2.0+ the mass of its child collider with a density of3.0.
- Child collider:
-
Rigid body:
Mass::Manual(100.0)- Child collider:
Mass::Manual(10.0)
Result: Rigid body's computed mass is100.0 + 10.0 == 110.0.
- Child collider:
-
Rigid body:
Mass::Manual(100.0)- Child collider:
Mass::Density(0.0)
Result: Rigid body's computed mass is100.0 + 0.0 == 100.0.
- Child collider:
We could also replace Mass::Density with Mass::Auto, and keep ColliderDensity as its own component
-
Rigid body:
Mass::Manual(100.0)- Child collider:
Mass::Density(10.0)
Result: Rigid body's computed mass is100.0 + 10.0 == 110.0.
- Child collider:
-
Rigid body:
Mass::Density(100.0)- Child collider:
Mass::Manual(10.0)
Result: Rigid body's computed mass is100.0 + 10.0 == 110.0.
- Child collider:
?
and i'm assuming density for volume of 1?
Options are to use a child collider, or to use a Collider::compound that only has the cuboid shape with some offset (kinda hacky, but works). Or a convex hull or trimesh I guess, a convex hull is more efficient
you could actually name it IndividualMass and it'd all fit together
Yes, if the volumes of the colliders are 1 then this is how it works
Thank you, I will try these options!
I don't use use a child collider because it makes the collision detection not very convenient :)
and since there's no longer distinction between auto and manual, it's no longer manual
but mass::mass would be weird
mass::new?
IndividualAngularInertia::Auto wouldn't make much sense, and it's not a very obvious name I'd search for
it doesn't have to be same for everything
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
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
I think having this built-in would overcomplicate APIs, but one option would be to get the volume of each collider (equivalent to the mass with a density of 1) and sum them together to get the total volume of the rigid body. Then you could compute the desired mass for each collider by multiplying the desired total mass with the fraction of how much the collider is of the full volume
Or alternatively, just compute the desired density for everything based on the total volume and desired total mass
yeah that might be easier
the first one is probably way more accurate though
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
isn't it mass per object? i'm not sure either
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
nvm apparently you're supposed to use joints for what i was thinking about ๐
@vestal minnow what was the state on upstreaming the KCC that @crimson crest made?
I'm a bit out of the loop
I need to test it properly and research KCCs in general more deeply before I upstream anything, especially if it'd get upstreamed into the core library, not just included as an example. Looking at the code in vidar it looks great though!
makes sense ๐
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...)
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
Also university, I hope ๐
Did you finally figure out that "variable" business?
have you advanced to functions yet?
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
Some things I was thinking about are like
- Can we use
LinearVelocitydirectly? (may require first-party integration) - Can we move the collider out of
KinematicCharacterControllerinto its ownCharacterShapeor similar, and if it doesn't exist, default to theCollideron the entity? - Can we make
KCCGroundeda marker component so that people can just filter by it in queries instead of having to check thegroundedproperty? - Can we extract things irrelevant to the user from e.g.
KCCFloorDetectioninto their own components, separating configuration likemax_floor_distanceorupfrom internal state likeprev_floor_normalorprev_velocity?
Also for upstreaming, it needs to support both 2D and 3D, and f32 and f64, and probably usePhysicsLengthUnitif 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
- Yes, (see the block above, I need some way to tell avian not to act on it automatically, but still provide predictions maybe)
- 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
- 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)
- Should be able to, a lot of whats in vidar is future proofing (or debugging info) and not currently used
Yup, makes sense
Collide and slide on demand would be great, that's one of the things I'd definitely expect from first party support. Configuration of the collider would ideally happen there automatically with the ability to do it manually
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
We could probably do that yes, if it's valuable
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
@frail robin Should be fixed:
https://github.com/Jondolf/avian/pull/520
Can confirm that it fixes the issue in my game.
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
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
No, on the latest release it's fast.
Bisecting now.
Do you have a bunch of gizmos?
I was wondering if it's related to this
https://github.com/Jondolf/avian/pull/497
I do...
I mean I enabled the debug rendered for colliders
You could try with this PR to see if it fixes it ^
Yes, it fixes it :)
When you merge this one, could you also rebase #497 on top of the latest master?
So I have a branch to point
Actually, no, it's still slow...
Bisected, definitely caused by https://github.com/Jondolf/avian/commit/4d082a79fd30078e5b536ae23656f690091ae285
I'll just merge that one too, tested it and it seems to work
Weird that it'd be meaningfully slower though, maybe Bevy's "contextually clearing gizmos" thing for fixed schedules has a lot of overhead?
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
I don't think it's particularly useful as a default thing either. Especially since fixed update could run arbitrarily fast, like say 128Hz or even 256Hz 
yeah
Meanwhile my fix to make debug gizmos play nicely with FixedUpdate: Clear the event each simulation tick
Double-checked - cherry-picking https://github.com/Jondolf/avian/pull/497 on the latest main still slow :(
Slow even if I disable gizmos
Sorry, which PR or commit or combination did you mean is fast?
Fast is everything before, but not including https://github.com/Jondolf/avian/commit/4d082a79fd30078e5b536ae23656f690091ae285
Also this branch is fast:
https://github.com/Jondolf/avian/pull/497
But If I cherry pick the fix on the latest main - still slow. Even without gizmo
the latest commit at the time of #497 was 1e4d7a7cff1dfaf2ba17f5d14629c72df5089515, could you try to bissect and see which commit after that caused it to be slow again?
Will try
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
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.
So, this commit causes the issue and there is no known fix: https://github.com/Jondolf/avian/commit/4d082a79fd30078e5b536ae23656f690091ae285
No gizmo involved.
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
@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*
Yep, that'd be useful
Working on it!
@vestal minnow https://github.com/projectharmonia/project_harmonia/pull/331
Thanks!
Let me know if you have any questions.
Here is what I use physics for:
- Picking. I will switch to GPU-based picking when it comes to Bevy.
- Collision checking when I place objects/walls.
- I build navigation from colliders.
The map have a several walls that are trimesh colliders and 4 characters with capsule colliders. So not much.
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
The slowdown happens with https://github.com/Jondolf/avian/commit/4d082a79fd30078e5b536ae23656f690091ae285 which is after hooks.
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
I'm not noticing any slowness just running it with the instructions in the PR
Lemme add an fps counter or something
Wait, in what way was it slow anyway?
Interesting, it's slow sometimes
FPS noticebly drops.
I just tried running it a few times, sometimes it's slow, sometimes not
FPS based on an FPS counter?
Cause if it's only visual it would just look lower FPS because no interpolation
No, just camera movement, it's choppy
No object movement.
Let me add a counter and I will provide more info :)
Actually I'm pretty sure my issues all come from the ordering changes surrounding the hooks
yea I mean if it's just choppy camera movement, it's probably because of Bevy's default timestep of 64 Hz and the lack of transform interpolation
But camera and objects are not affected by physics, everything is static...
Sometimes ... System ordering issues? ๐
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
Are you running a supercomputer? I have up to 10 FPS.
And it's Ryzen 9 5950X.
I have 600 FPS in release mode ๐
I don't think there's any consumer chips that are 8x faster than a 5950X, so it must be a supercomputer ๐
I'm on a 13th gen Intel i7-13700F
@vestal minnow I added 2 commits:
- The FPS counter I used.
- The update to the avian's slowdown commit.
Could you check again?
Just in case
yup
I have around 25 FPS in debug mode without the slowdown commit and around 10 FPS with the slowdown commit.
Rust 1.81.0
Still getting a nice 60 FPS in debug mode with VSync (I'm on a 60 Hz monitor) and 80 FPS uncapped
Are you running Windows?
Yes
(same, if it matters)
So the FPS doesn't change for you when you switch between commits?
not that I can see, no
This is strange, when I jump to https://github.com/projectharmonia/project_harmonia/pull/331/commits/596754ba98087659524a0833fd7b7959adc84c56, it's much slower.
Okay, you suggested to try to switch to 64hz?
to 60*
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
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.
It's reliably reproducible for me, except this one run.
Not sure, I've been swapping between them as well and it's always hovering around 80 FPS uncapped
in debug mode
maybe it is slower but my FPS is just high enough that it's not as observable? idk
If it's inconsistent at all between runs though, 95% of the time it means that there's some scheduling ambiguity
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
iirc there's actually a place where you mark some propagation stuff fine for ambiguity which could then apply to other systems which have ambiguities with that
Sorry for the quality, I forgot to adjust resolution. But it should be visible.
And with the other systems relying on change detection while also changing things it could be possible they create a loop ๐ค
I don't think any other new ones should've been introduced on main vs 0.1.2 tho
Maybe in that one time I just made a mistake and didn't save the file or something.
But right now it's reliably slow after jumping between commits.
Scheduling issues can be reliable in some cases too
Yes, but it's weirdly reliable ๐
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 
Ah, maybe that's the isse
Not, it's actually about 10 fps on average
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
There is no PhysicsPlugin on 0.1.2...
Ah, PhysicsSchedulePlugin!
scuffed recording, but
PhysicsPlugins
Ah yea, it's with an s, it's a plugin group after all
also how the heck is your compilation so fast 
my game perf 
my compilation times 
It's crashes on Windows, when you exit, strange.
I use mold as a linker.
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
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(),
The same as main or as 0.1.2 without any changes?
On main, but before the slowdown commit that changes the schedule.
And I tried with and without the changes
You want to pass the schedule to PhysicsPlugins::new since it forwards it to the other physics plugins too. Passing it only to PhysicsSchedulePlugin means that it will configure the physics schedules to use FixedPostUpdate, but it doesn't necessarily make all the relevant systems in other plugins run there (it's impossible for it to do so)
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.
Okay well at least it's not necessarily a regression then ๐ in the case where physics is configured to run in that same schedule
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.
Or make the game run faster
With 30hz I have the same perf as before without chaning the schedule.
I use physics only for collision detection for now anyway.
It's good that it's not that commit before the change then ... It already has some issues but the mass changes might fix those, but if it was causing infinite change loops that would be really bad 
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.
I get the same FPS (40 debug, 400 release) on linux with an AMD GPU (on wayland) and a 5900X instead of a 5950X
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:
- With and without mold - the performance is the same.
- Setting the tickrate to 30 returns makes it around 30 FPS.
- Lowering the tick rate below 30 doesn't have any effect.
- 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.
I get 400fps on debug and ~700-800 on release on windows w i5 12400f and GTX 1080ti
But it's a fairly small game
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
Would all of these default to Auto in the required components?
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 ๐ค
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
In this case Auto isn't an implicit default, it's entirely separate behavior
Auto is what the default behaviour would be if the component didn't exist
Like what it is in current Avian
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
Depends on if we want a ColliderDensity on the rigid body to apply to all attached colliders or only the entity it's on
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 
did those users explain why they need to override it?
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? ๐ค
and jondolf took it personally
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
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
maybe something like "inherit" as option?
like pick a limb and set it to "inherit mass", then the rb will redistribute it
you can kinda do that with auto or Additional on the rigid body
isn't that based on density
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
collider or rigidbody?
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
Mass-properties of a RigidBody, added to the contributions of its attached colliders.
You don't "Let the engine figure out the rest", you just only overwrite the mass
Density defaults to 1.0 afaik
Btw yeah I think it might make sense to remove Auto again and treat it as no component == auto. It's redundant to have the extra memory usage for every dynamic rigid body and possibly every collider, for 3D AngularInertia it'd be the size of a whole extra (nvm, a Mat3Vec3 and Quat). We'd just rename the components to my original proposal's names like CustomMass again
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
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
Found another way to cause desync even with the latest main. Opened with a minimal reproducible example:
https://github.com/Jondolf/avian/issues/522
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...
- Sure, that's basically what
Mass/CustomMasshere is, plus theAdditionalvariant. Tbh we could also removeAdditionaland only haveOverride, it'd be much simpler and more consistent with most other engines. - 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.
- 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
- 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.
- 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
OverrideMassmarker component, the engine won't update mass automatically and you can instead freely modify it? (like Unity'sautoInertiaTensorboolean) - This seems kinda niche and confusing, but if we added this, I'd just add a system param like
MassPropertyHelperwith 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
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.
I couldnโt find a way to fix it on my side, should I open an issue on GitHub about it?
I'd say so, yeah
any hint? or isn't the good channel to make this kind of questions, better to ask in help channel?
Tiny bounces are expected because of how contact solving works, but they should be pretty minor. What shape is your collider and what kind of bounces are you seeing? Like, are you dropping a ball on the ground and seeing it bounce up, or do you have e.g. a box that sometimes tips over when it lands on the ground?
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?
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?
you need a static rigidbody aswell, without it you just go through them, the point of a collider without a rigidbody is to be able to walk to some areas and detect it
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
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.
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 ๐ข
Hard to say without knowing what is in your game. If it's physics causing this then there would have to be something very wrong with those dynamic objects before avian causes lag with just 3 of them ๐ค
Wrong as in trimesh-trimesh collisions
Right, you obv can't see my code ๐ would you mind taking a look? It should be very straight forward. It's just a first-person game with bevy-tnua as a KCC. I dumbed down the colliders as much as I could and it still studders. Maybe it's the lighting or the meshes in the frame?
The 3 dynamic objects use convex-hulls generated at runtime
Convex hulls shouldn't be too bad. Usually using a profiler can give you an idea of what is causing it https://github.com/bevyengine/bevy/blob/main/docs/profiling.md
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 
Thanks, I will try to use a profiler.
Where are you trying to add the component? The example just adds it directly when spawning the player entity. You can't have duplicates of the same component in a single spawn call.
https://github.com/Jondolf/avian/blob/39a7480cd1915bc5266aa8ebd3c3436d4d0568b0/crates/avian2d/examples/dynamic_character_2d/main.rs#L59
Conflicts are also only an issue when you have duplicates in a single insert, separate inserts will just overwrite.
๐คฆโโ๏ธ I was just looking at the plugin, didn't even think that it might have been in Main. Apologies
Hehe no problem ๐
You can make the collider a child of the rigid body and offset it with a transform
thanks!
Sorry to bother you again but.. I don't know how to read the trace ๐ I have the tracy file, would you mind taking a look?
I usually use the chrome tracing format mentioned in that page, which can easily be opened in your browser (tho you are fairly limited to how big profiles can get because of wasm restrictions). Getting tracy to work is a bit annoying because it usually requires compiling a very specific version that matches the tracing crate.
Okay, I'm so sorry, I figured it out. You were correct in assuming that this has nothing to do with Avian ๐คฆโโ๏ธ it was rendering. Basically the point lights were causing long render frames.
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
i guess so, haven't used sensors yet, im new to avian, but coming from unity i assumed thats how it would be
Same, hehe. I will experiment. Thanks!
np ferrisJoy
Nearly correct. AFAIK the first case is actually detectable (or at least used to be in an earlier version of Avian). Sensor can be thought of as DisablePhysicsSolverWhenThisCollidesWithADynamicRigidBody more specifically.
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
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 ๐
I think a decent split would be:
RigidBodyis a unit struct, and represents a dynamic body by default.- Add a
Staticmarker to make the rigid body static (also used by e.g. rendering, see old PR). - Add a
KinematicCharactermarker to make the rigid body kinematic and controllable via e.g. collide and slide logic. Collideron 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
Sensorto ignore collision response and make the collider triggerCollisionStarted/CollisionEndedevents, 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.
Very much agreed on the last part. All of my sensors so far have only needed collision started / ended ๐
RigidBody being an enum is pretty nice for UX when spawning entities, but annoying for queries. Alternatively, we could have DynamicBody, KinematicBody, and StaticBody, which require a shared RigidBodyMarker
But then StaticBody and the hypothetical first-party Static marker would do the same thing here
Agreed on the queries as well. avian_pickup has a ton of stuff start with if !rb.is_dynamic() { return; } 
Eh I guess that's fine, it'd just require both RigidBodyMarker and Static, basically act as a shortcut (or bundle)
where was that code we made in here that made those boundary walls for a cylinder
hmm
just remade it and now ive been nerd sniped on calculating the radius of the furthest points of the walls
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)
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
This approach does have the benefit of not needing that weird conditional requires thing ... You can just only give certain requires to dynamic or kinematic bodies, but not the ones that don't need it (static bodies need only about half the things dynamic bodies do for example)
Iteration for something related to cylinders? That sounds unnecessary ๐ค
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
So a circle of cuboids? ๐ค
ya
i can sort of solve it here
actually wait
hmm
its an approximation of a circle
essentially
Oh you're doing the slightly different approach where they aren't literally just chords
chords?
A line on one point of a circle from another
The relevant topic would be this: https://en.wikipedia.org/wiki/Circular_segment
I remember struggling with it to figure out the correct placement of these hallways 
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
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 
is linearvelocity in local or global coordinate space
oops i didnt mean to send that as a reply ๐ฌ
Global
Yeah kinematic bodies probably shouldn't be specific to characters, I guess it could just be Kinematic and then there could be a separate component for enabling a character controller / collide and slide for it
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
Yep, that's one of the benefits I was thinking of as well
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
shouldn't the line code be similar?
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
@vestal minnow you know what would be nice a ragdoll example
I am gonna go ahead an do one
I have this 2D one from a while ago, although I don't think I released the code for it anywhere. I probably have it stashed away locally somewhere
#showcase message
animation -> ragdoll
maybe even with some kind of a mix like wolfire did to make it seem more natural
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.
is there a reason for colliders detaching from sprites when they're loaded from a RON?
Who knows how to get electrical energy using Avian3D?))))
https://youtu.be/2x79KSZ7oTM
Using the capabilities of the physics engine Avian3D I tried to make a semblance of a waterfall that spins a turbine and generates electricity, just for fun.
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?
ok, now I got it, what I need is only to add a Sensor component to my platform! issue solved
Not sure what you mean by detaching. Do you mean that it doesn't follow the sprite as it moves? If the collider is parented to the sprite, make sure both entities have a Transform and GlobalTransform
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 ๐
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
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
Really depends on the game, but it's very common to just convex decomp a simplified version of the level (sometimes they exist as LODs, other times it just means skipping certain parts of the terrain)
Ah, okay, my tests with convex decomp was really weird geometry on a simple room. Do I have to up the resolution then? Also, I'm fairly new to the lingo here, LOD is Level Of Detail, right?
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
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 โข๏ธ ?
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
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)
Thanks for clearifying, folks ๐
Do the colliders look correct when debug rendering is enabled? Not sure why else it'd only collide from specific sides ๐ค
I mean they show up as rectangles
i'm using colliderconstructors if it makes a difference
this is cool!
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?
We have LD make the game in white box using cubes. Art comes later and builds the world based on this collision in an entirely separate scene.
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
figured it out: yes it needs mass
Thank you ))
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)
Thank you for the additional info ๐ That sounds really solid! Could you explain to me what LD means? ๐
level designer
I mean heightfields are basically mesh colliders
but yeah for anything that moves I'd steer clear of convex hulls/trimeshes
Except heightfields have ways to exclude more efficiently, allowing it to perform less poorly
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 ๐ค
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?
I usually use a halfspace but that means, you can't have anything under it.
thanks
hmm, do we even do that currently though?
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
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
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.
Yea if you have levels with big gameplay implications (so pretty much most games where the level isn't 90% story) you really save a lot of time by doing white/gray/whatevercolor box level design. There's also the not insignificant factor of gameplay just becoming more fun with visuals, so having fancy art can distract you from the fact that your level kind of sucks
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
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.
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 ๐
For a 3D game it's usuall a cylinder rather than a capsule. 2D is boxes. The curves don't play well with corners
Honestly I don't even know what some of these studios are doing
Yeah this is basically my take too heh
"How can you get this so wrong" crosses my mind so often ๐ฆ
A system parameter for performing spatial queries.
You should apply impulses to the bodies inside the explosion range. A more sophisticated explosion would also take projected area and closest points into account (this is what Box2D's new explosion features do)
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?
Yup! Explosions are generally so quick though that you can probably do just one spatial query and apply a single impulse to each entity, instead of having an explosion "expand" over multiple frames. Depends on what effect you're going for of course
And yeah, an example could be nice if it ends up working well ๐
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!!!
do you need plain physics explosion, or also attach some kind of damage logic, or have an actually expanding AoE?
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
yea i use intersections for that
Yea, tho using a collider isn't always desired for projectiles. Depends a lot on their behavior and how many there are. Sometimes ray/shapecasts are the better solution for projectiles
Wouldn't that be a hitscan? If I need to use different projectile speed, isn't a collider the best idea?
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)
i think collider (sensor) is better, no chance to miss a collision
This assumes being able to afford the expensive non-linear CCD, otherwise you'll be missing more collisions than ray/shapecasts
Which will naturally be a no-go for any game with many projectiles
i guess if there's no fast movement then it's fine
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?
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
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
Why do your enemies move so fast in a single update tho ... Normally it's projectiles that move fast ๐
my projectiles are also enemies :>
you can shoot down a rocket
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 ๐ค
The are enemies that can "dash", and also you can hit "enemy projectiles"
Sorry, but what is BVH?
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
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)
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
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
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
i don't really understand why people make fast-moving projectiles at all, or make slow-moving projectiles that you can only dodge
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)
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
do you think RPG missile should be possible to shoot down?
Honestly depends on the game tho
yeah, maybe
ultrakill also has parry on every projectile including your own and it worked out really well
Yes, you can, and enemies can
I would say every projectile (except for laser weapons)
but ak bullet is tiny and fast, so why not just use raycast
without nise's over-time stuff
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
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?
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 ๐
yeah that's a fair point
Iirc my progression in godot was essentially: rigid bodies -> sensors -> raycasts. I don't think avian quite gets the full optimization from using sensors over rigid bodies, but in theory that could be fixed in the near future ๐ค
The 900 projectiles in godot might've actually been the sensors version tho 
But the 1500 in avian was definitely rigid bodies ... The projectiles could bounce off of things (but possibly not eachother)
maybe i should copy your homework then, since none of them need real physics anyway
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
Not sure actually, but worst case you can just make your own system to integrate velocity on Query<(&mut Position, &Velocity), Without<Collider>>
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)
it was the ColliderMass
Alternatively set gravity scale to 0
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,
);
}
}
#1124043933886976171 message
are there any prereqs before the ConicalFrustum collider can be implemented?
https://github.com/Jondolf/avian/blob/main/src/collision/collider/parry/primitives3d.rs#L92
i'm happy to do it just need some direction
I think ideally it'd have both a SupportMap and PolygonalFeatureMap implemented. The former should be relatively straightforward, but the latter might be a bit weirder. It'd probably be pretty similar to the cylinder's implementation though.
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)
The state is #1214134557456990238 message
ok i'll have a look, thanks!
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
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
And contact constraints already use impulse-based constraints right? But there's no API for custom impulse-based constraints
In this case the target relative distance would increase at some desired rate, and the constraint would try to follow the target distances (probably with some logic to prevent moving backwards or causing too sudden accelerations/decelerations)
Yep
I'm not sure yet how custom constraints will work once we have a fully impulse-based solver and implement things like simulation islands
This would probably work... could I limit the amount of force used?
Yeah probably, there's a cursed way I found where you first compute the Lagrange multiplier delta for a compliance of zero, computing the force that would cause, and then using that to solve the compliance required to get the desired force, and recomputing the Lagrange multiplier with that new compliance
(sry if that's a confusing explanation)
this would also be easier with impulse-based constraints
Haha it always sounds confusing at first. It'll make more sense when I'm done reading docs
In that case I might just wait on this
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
This paper has some useful derivations though, you can see how it's pretty math-heavy for impulse-based joints :P
https://danielchappuis.ch/download/ConstraintsDerivationRigidBody3D.pdf
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
I got some readin to do
has anyone made a pong/breakout/similar game using a kinematic body for the ball that they can share?
@visual sparrow as promised (if not delayed) my weird and fun avian3d rotation bug. This is one way to make solar systems.
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
AnyColliderwhich is used to provide extra context to operations like computing manifolds. I've implemented this as a simpletype Context: Componentin this prototype, but perhaps extending it to support a fullQueryand useQueryLenswould be cool.
- add
Option<&Self::Context>to each method inAnyCollider. decided to go for anOption, 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.
I've had that before! It has something to do with bugs in hierarchies with scales
I've seen surprisingly few cases of people using physics to make these games ... I think chris biscardi did make multiplayer pong with a physics library (but it's either rapier or an old bevy_xpbd version)
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)
this is what i have so far, it seems like im close but its still very clearly broken and idk how to fix it 
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?
i think dynamic would be a better choice, do you still have the code for dynamic? it's worth trying to figure out what's going on
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
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
isn't 'ColliderConstructorHierarchy' what you're looking for ?
// Map
commands.spawn((
SceneBundle {
scene: map_gltf_handle.clone(),
..default()
},
IsGround,
RigidBody::Static,
ColliderConstructorHierarchy::new(ColliderConstructor::TrimeshFromMesh), // that line
));
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)
hmm I fixed it by changing the FIXED_TIMESTEP_HZ to 60.0 instead of 64.0
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
This is by design, that number was picked because: 1. You can't accidentally not fix it; 2. you get a well behaved float for the timestep value
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 ๐
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
what is tag ? a custom enum equivalent to marker struct empty ?
Sorry for the french XD
it doesn't have to be empty, i used optional values at first but removed them later
Maybe I should do this, because I'm making components IsPlayer, IsEnemy, IsGround
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
i'm still searching for a better way to handle it, but for now it works better than other stuff i've seen
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));
}
}
}
}
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
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
Anyone else have this problem with avian_pickup? https://discord.com/channels/691052431525675048/1291344666364608542
I'm convinced, performance wise your solution is better
Speaking of performance, Is avian physics comparable to rapier within an order of magnitude, or is one vastly more performant?
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
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
Casually mentioning 3 massive features ๐
dw I'll help out when world hunger is solved, cancer is cured, and we land on mars
I see
wanted to ask tho, is there TrimeshFromMesh equivalent collider constructor for avian 2d?
how can i multiply forces by delta time? right now if i limit my fps it looks like its in slow motion
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
how about gravity?
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
@glad eagle if you're on main then it's already in fixedupdate so it should be consistent without delta
i'm on 0.1
i think you can change from default schedule to fixed as a placeholder, not entirely sure if it'll be the same
i'll check it out tomorrow
is there a way to do something simmilar to cast_ray_with_predicate and recieve the point of intersection?
you can get the point of intersection as just ray_origin + ray_direction * hit.time_of_impact
Nice, I should really bone up on my understanding of actual physics to intuit these things haha
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?
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
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
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
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)
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)
Depends on what you want and how many enemies you have
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
ohhh awesome!! I'm planning on lots of enemies, but I'll try with sensors and see if I need to adjust. Thanks!!
if you find the performance a problem then you should be able to use avians bvh manually i believe
gl!
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"
sorry what are you refering to?
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
(SDF = Signed Distance Field or Signed Distance Function)
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
if it's just player then it's probably better to just skip sensors
What do you recommend? Using Vec3::distance? (Again thanks for all the feedback and ideas, I love this community)
yeah, or square distance if you want an insignificant optimization
and a really simple system for switching states or writing events
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?
shouldn't be too much of a problem either way, but you can just write your systems assuming that you'll rewrite it later, ecs is kinda good for stuff like that
hmm, good point. may as well write it one way, can always optimize later
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
Massspecified -> computeMassfrom colliders, taking into account their densities. Massspecified -> 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, andNoAutoCenterOfMasscomponents. - 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)
"if colliders are added after the body's initial creation"
How do we define when this happened?
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
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 
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
Zero mass isn't great either ๐
It does make sense for some of the cases @sleek thicket mentioned some time ago, like if you explicitly set a character's mass, and then later add some weight as its child, you'd expect it to gain that mass... but of course at spawn time it wouldn't work here, since the child's mass wouldn't be added in that case ๐ค
I guess the question is, given this setup:
- Rigid body with
Mass(10.0)- Child collider with
Mass(20.0)
- Child collider with
which of these would you expect?
- Rigid body's mass is
10.0 + 20.0 == 30.0 - 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
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
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"
i think editor is better for doing stuff like that, and in the editor you probably won't need to hide anything
if you want it to make sense in terms of real life, then 30
the other one could be a hack needed for some game mechanics though
There's only so much you can get with that, both "default mass" of 1 and default density of 1 are usually not what people would expect
But I do agree it definitely shouldn't just explode or something just because you forgot to specify the mass ๐
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
I guess one option could be to make default behavior for Mass the first one, but then also have those optional OverrideMass components for the second case
yeah, didn't we arrive at the same conclusion the last time?
Maybe? Idk lol
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
Wouldn't the OverrideMass in this new approach be NoAutoMass?
In the old proposal OverrideMass would still have a value iirc
Hello. Is there any conditions based on which I should choose to use kinematic or dynamic character controller?
yeah
look at tnua to see what you can get out of dynamic
so I guess the only change to my proposal would be that Mass at spawn doesn't override unless that marker component is present
Kinematic bodies don't respond to collisions, so things like "being pushed around" are difficult to get. But in plenty of cases "being pushed around" is entirely undesirable ... It really depends on how "realistic" you want the movement to be, should it be affected by all physics forces, or just do exactly what the player input?
So,
- Rigid body with
Mass(10.0)- Child collider with
Mass(20.0)
produces a mass of 30, but if the rigid body hasNoAutoMass, it's 10
- Child collider with
Still feels a bit footgunny in that specifying mass defaults to being an addition, the thing you are least likely to want ๐ค
yeah
that's why I went with the overriding behavior in my proposal
for the initial spawn
I don't really need the player to be "pushed around" so I guess I will use the kinematic one although seems like it requires more code
you can just make dynamic with infinite mass
meanwhile kinematic needs you to essentially rewrite everything from scratch
well... then...
Wouldn't infinite mass cause explosions in certain cases? Infinite mass is infinite energy, walking into anything should make it explode 
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 ๐
well, yeah. in unity i just made player really heavy and it worked
I wanted to copy the one from the examples folder
I think at the very least the more correct solution would be using Dominance, that way if something ends up needing to push the player later anyway it at least still can
I think I'll probably go with this + the other stuff I had in my proposal (like MassHelper)
don't overthink it too much, you'll probably get an urge to rewrite everything once editor is ready ๐
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
yeah, that part should still be good even with editor
might need a better name though
for NoAutoMass?
yeah
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
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
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
without leaving original collider mass component?
ColliderMassProperties isn't changed, that still has the actual mass of the collider, taking density into account
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?
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
Massis the single source of truth for the mass of aRigidBody. You can overwrite it at any time if you want.- At spawn,
Massis set to whatever value you specify (or zero by default), plus masses of child colliders, unless you haveNoAutoMass. - Each collider has a
ColliderMassPropertiescomponent 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 hasNoAutoMassetc. - If you manually specify
Mass,AngularInertia, orCenterOfMassfor a child collider, that will be used instead of the computed value inColliderMassProperties.
marker components should be good even if you completely change how everything works on the background
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
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
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
bikeshedding-containment-channel ๐
btw what happens if you want to gain mass from some children but not the others? use mass helper?
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
I intend to merge #500 tomorrow, which
s 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
and then do the bigger API and behavior changes and refactors
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
PR to refactor mass property logic into a MassPropertyPlugin
https://github.com/Jondolf/avian/pull/532
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
Duplicate systems? Those two sync plugin ones that escaped to the collider backend plugin and prepare plugin? 
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
Wasn't that only the run condition and not the system itself?
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
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
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
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
i don't think avian is at the stage where it needs a stress test though D;
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..
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
I also have a bevy_transform_interpolation crate and Jan has avian_interpolation, though neither of them is on crates.io yet
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
oh wow did not know this hahaha, that's nice to knoww :D
The (unofficial) Bevy cheatbook also has a section on transform interpolation and extrapolation if you're interested
https://bevy-cheatbook.github.io/cookbook/smooth-movement.html
Probably not very well, 100k is a lot. If a lot of them are sleeping and they're not all colliding at once, then maybe
simulation islands would also be important here, which we don't have yet
Is there currently a branch using required components?
noice, any knowledge on an ETA for the 0.15 rc? I'm itching for it haha
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
Will avian need some PRs to integrate with it? I'd love to try and help
I'd like to migrate Avian's "required components at home" approach to use actual required components myself, since I think there's a few things that might not be that simple; but PRs for things like migrating examples to use required components instead of bundles could be helpful
It is a worst case scenario fwiw, but yeah they'd likely spend a lot of time asleep
The more I think on this the more I realize I probably am going to be just writing my own logic for the most part lol
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
Are ConvexHull colliders more costly just when they're first instantiated or are they more costly as the app runs as well?
Compared to what?
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
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
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
But yeah it should definitely be fine for things like ramps
@vestal minnow What are your thoughts on using SDFs to define the "real" collision data for my objects, bad idea?
You mean using SDFs as colliders?
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
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
Parry has voxel collisions but apparently I can't manually construct the voxel data type, I have to pass in a mesh
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
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
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) {}
}
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
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
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\
The AnyCollider trait is the one generating the collision data
It might even have a spot to store extra info
I guess I could probably mark the voxels hit as contact manifolds?
It feels wrong to do that though
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?
I'd probably remove RigidBody for now. Another more annoying way could be to remove all collision layers and make the rigid body static (or lock its axes). But there isn't a RigidBodyDisabled component yet, though we could add it
thanks
Made a PR for this finally, it has been a somewhat common request
https://github.com/Jondolf/avian/pull/536
Objective
Fixes part of #436.
A pretty common user request is to be able to temporarily disable rigid bodies without removing them from the world. This can be done by removing RigidBody, but this l...
nice one man, thats awesome ๐
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.
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
Ok,Thanks a lot , i'll have a try๐
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?
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?
Yup! You can add the PhysicsDebugPlugin
A plugin that renders physics objects and properties for debugging purposes. It is not enabled by default and must be added manually.
Ahh i see, that is fantastic
CollisionStarted work with ColliderFromTrimesh ?
I tried implemented HitDamage and HitObstacle, but it seems like my map collider is not triggered
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?
Looking at the code I expect NaN
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
Yea it's a debug assert
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
I doubt it, FixedUpdate should be fine
the main branch defaults to FixedPostUpdate now
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
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
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
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
It's the latter case. If I run the code for sometime, it will crash at some point.
hmmm, strange
I can't really think of anything on the physics side that would cause that panic for kinematic bodies
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
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
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
Adding Time setup doesn't fix the issue. I'll dig more. Thanks for the help @vestal minnow
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?
Does continuous collision detection support sensor to sensor collisions?
followup question, do shapecasts hit sensors?
Currently, yes, but it might be removed at some point in the future for optimization reasons. I generally wouldn't recommend relying on it; if you have fast-moving sensors, using shape casts might be a better fit.
(That's what Box2D and most other engines I know do as well. They don't support CCD for sensors afaik)
Currently they do. I'll probably make this opt-in at some point
Would it be possible to opt into this as well?
I think we could probably keep support for sweep-based CCD with the SweptCcd component, but speculative collision likely wouldn't be a thing for sensors
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
Okay, that makes sense. I think I will store my shapes and use parry3d directly then.
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.
Haven't tackled it yet sadly, I've been prioritizing some other things. My understanding is that the spatial hashing PR in big_space would also be important for a proper physics integration, but that hasn't been merged yet
Okay, no problem. Yes, this pull request seems essential for a proper integration.
0.15 RC 1 just dropped ๐
I'll try to update the main branch for it within the next couple of days, hopefully tomorrow
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 ๐ค
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 ๐
Not strictly needed, but it is for the approach I want to (eventually) take.
does anyone have any ideas/suggestions for this? I explored the GitHub and this thread, but couldn't find a working 3D example with code :(
try moving the wheels further from the body and see what happens
Does anyone have time to take a look? https://discord.com/channels/691052431525675048/1298977419293888605
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)
Experiment with Bevy apps in your browser
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.
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
Right, I think I remember there are query filters that get true only once an entity with a specific component spawned?
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
yup, Added, very handy for augmenting your world/entities upon creation / addition of components
np, I agree that it's cleaner but multi-frame initialisation often has this kind of problem and it's usually easiest to have your code react to what's happened as opposed to trying to schedule it ahead of time
(there may still be a way to schedule it, mind you, but the reactive approach is probably simpler)
I see, that sounds like a reasonable pattern
I admit I like the declarative feeling of scheduling systems
I have gotten around this for now but it would still be nice to have.
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
I think thatโs fair I think I was getting caught up in wanting things to โwork the right wayโ instead of taking the simple, itโs bad but itโs what weโve got approach of making a new component for my needs
Hmm I think you want to make the wheel colliders child colliders so that you can rotate the cylinders to be more like wheels without affecting the rotation of the wheel rigid body itself. And you want the "aligned axis" to be the "axle" of the cart, so along the width of the cart
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
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?
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
aha
would https://github.com/Jondolf/avian/issues/254 resolve this in future?
Yep, it should
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
If the velocity is not pointing towards the other body then I don't see why it would trigger a collision, especially if they're at least slightly separated
sorry wrong ping, meant to reply to your new message
But to respond to this as well; the issue here is that spatial queries internally use a BVH acceleration structures to speed up queries, but it's only updated during the physics schedules, so your colliders won't be found immediately after spawning them. In your case, the spatial queries need to be done after physics or during the next frame to make sure they exist in the BVH.
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
Would you mind taking a quick look at my project to see if you can spot something? I've configured a situation where the issue is triggered by pressing a key. There's a bit of garbage but the code related to the issue I'm describing is pretty short
I see, thanks!
Sure, do you have a link or something?
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.
it's full of crappy debugging code, it's my first project with Bevy & avian2d
If it's too cumbersome, which I'd understand, I'll try to make a minimal repro tomorrow
Thanks, I'll try it
need to mess with my toolchains or something though, seems like I need nightly Cargo
ah yes I've done all the configuration suggested in bevy's doc to speed up compilation, which requires nightly
if it doesn't work on your machine you can probably just remove .cargo
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
Ah awesome, thank you for the fix!
Not awesome for the bug though
Do you need me to try and make a minimal reproduction & open an issue?
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
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
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
Since the switch in solvers the explosive behavior should be mostly gone so hiding the message isn't a big issue ... They can still be useful if the overlap is not desired of course, but then the messages would need to actually be accurate and afaik they aren't
RIP Dinos
I think I can just put in a span called ignore that will set logging to none
With some custom logic that should be possible, yeah. You mainly need to disable SyncPlugin and set up your own logic to use Avian's physics Position and Rotation components to update your own components after physics
(I haven't tested this myself, but I think it should work. Avian is intended to technically be usable without Transform)
I am having so much fun with Avian thank you
Hmm, just got a very ๐งช and mildly
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
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?
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
rather than queries, wouldn't it be better to do that with layers?
i think there was a merging function in one of the examples but yeah, having a built-in grid collider would be nice
Using layers would remove the benefits of using an ECS and having powerful queries. You'd need to iterate through all colliders every time and manually filter them. With queries, you only need to iterate through the entities that match the query
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
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?
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
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 ๐ซ
Maybe with a triangle mesh collider or by manually approximating the shape's exterior with many separate colliders. Collisions inside hollow shapes are very difficult / almost impossible for traditional collision detection algorithms to deal with since those algorithms are largely based on convexity
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
That would be marker components
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?
It's 1 px = 1 unit, there isn't necessarily an actual unit. But I generally recommend treating it as SI units.
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
A units-per-meter scaling factor that adjusts the engineโs internal properties to the scale of the world.
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
Box2D's docs also apply here, their setup is basically the same
https://box2d.org/documentation/md_loose__ends.html#autotoc_md119
Would you mind telling me which example it is? I looked at all the 2D examples but can't figure out which one performs combination.
@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
PR for current main would be nice
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
I also have my own fork that I made yesterday
https://github.com/Jondolf/barry/tree/update_nalgebra
I like the name
You can point to my or your own git repo with the Nalgebra update
either way is fine
It seems as though you have it under control ๐
Yeah I can also do the 0.15 update myself now, I did about half of it yesterday
What did you do for impl Shape for EllipseWrapper -> scale_dyn?
I didn't migrate those yet but I'll look into it
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
Okay thank u
here's my solution: make a bunch of rectangles #1124043933886976171 message
in ldtk?
Thanks, I'll look into it!
You forked Parry?
Just to update nalgebra or?
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
Any particular reason you're making your own?
Here's an old but still largely accurate comment #1213210101574271026 message
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
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
Thank you glad to know I am not missing anything
I will be using a torus and two plates too approximate a sphere.
I wonder why you didnโt use a torus is that not possible in 2d or am I missing something?