#Avian Physics
1 messages · Page 20 of 1
Joints are the only thing that uses XPBD anymore, and they might transition away from it in the future as well
Does this happen when dropping an object directly down without velocity along the contact surface?
And what shape is the collider?
yeah
two cuboids without rotation, or a cuboid floor and a spherical object
with xpbd (bevy 0.13), I found something weird, Res<Time<Physics>> seems to be framerate dependent. The following recording starts out with the window not in focus, but in the second half of the video, the bevy app gets focused. You can see that the time ticks faster in the second half. I'm guessing this is probably because the framerate gets limited when the window is not in focus. Note that I am using a high-refresh-rate monitor (144 Hz). I thought it might be because i was using bevy_framepace, but I disabled it and I see the same behaviour. The out-of-focus timescale seems to be correct, but in focus the timescale seems to be sped up (maybe because of framerates > 60 fps?)
Time<Substeps> seems to have a even weirder behaviour, it's much slower than all other timers, but maybe that one is supposed to be special.
Time<()>, Time<Fixed>, and Time<Real> all seem to behave as expected.
I’ve switched our existing code from using sensors to using shape_interestions, the one thing I’d like to know - is there a way to make the area it’s sensing be displayed for debugging? I’ve implemented a hack myself using Gizmos, but I’d like to know if there is a better way I missed.
What collision function for shapes can I use that returns the point that it hit? Idk if shape_cast/shape_hits would be less performant for this case if you don't need to cast at a distance.
I know, but does avian raycast if the distance is 0?
Because using manifolds there was a list of contactdata for every manifold and it was annoying
I wouldn't, that's the point
So you're saying it doesn't?
Because I just want to get the point that a collider hit
Idk how to do collision the way shape cast does
Cause in normal collision
You have to shift through contactdata which is impossible
Not if it's a shape cast
you throw a collider in a direction like a raycast
to see if it collides
Because i'm using colliders
Does that use basic collision?
sounds like it checks if something is at a point
ah, it's shape_intersections
I guess
Well, idk how to get hit data from an entity
How can I disable ColliderHierarchyPlugin? PhysicsPlugins is a PluginGroup, not a PluginGroupBuilder
same as disabling plugins from DefaultPlugins
PhysicsPlugins::default()
.build()
.disable::<ColliderHierarchyPlugin>()
ah didn't realize I had to call build() first, sorry
I now get Resource requested by avian2d::collision::collider::backend::init_collider_constructor_hierarchies does not exist: bevy_scene::scene_spawner::SceneSpawner
do you have the bevy_scene feature enabled?
that's what makes that system require the resource
ah i have to disable the default features
it works now!
thanks
I still get more rollbacks than before, only on collisions. But maybe it could be a mistake on my part
Okay checked with bevy_vr_blocks and t his fixed the random dissapearing and the super high rotation of the collliders!
when i used joints
friction doesn't seem to work well with spheres tho
i'm gonna try it with cubes
nah doesn't work well there either 🤔
Controls how strongly the material of an entity prevents relative tangential movement at contact points.
ah maybe it's just implemented differently to how I'm expecting
So like, i'm trying to grasp a cube by having two fingers on opposite ends push into it ( and because they are attached by fixed joints with compilance to the actual fingers they actually flex outward a little bit )
And then lift my hand up, and have it bring the cube with it
instead the cube is just slipping out, there is 0 upward movement
do you have friction set to a high value?
Friction {
dynamic_coefficient: 0.99,
static_coefficient: 0.99,
combine_rule: Default::default(),
},
Does it need to be a high value on the cubes as well for it to work?
Friction {
dynamic_coefficient: 0.8,
static_coefficient: 0.8,
combine_rule: Default::default(),
},
this is what it is on the cubes
nah that should probably be high enough
set it to like 10.0 just to see what happens lol
ahahah okay
hmm it causes the objects to explode away
lemmme try a smaller but still > 1.0 value
hm okay
so to describe the behavior, i have it set to 1.99 for both dynamic and static
if i try to slowly lift the object nothing on the object happens, but the sphere colliders on my fingers spin very rapidly
if i quickly lift the object then it works
also for some reason the cube doesn't explode when my fingers go to far into it, it just, my fingers just pass right through it, and i'm not sure if that's intended behavior or not 🤔
Like with the fixed joint with a small amount of compliance, my expectation is that the cube should explode out if i approach it from both sides and push my collider to the point it's inside it
this is unrealted to the friction values, except with really high friction the cube explodes away so u don't see it 😂
Any thoughts on either of these?
hmmm not sure why it wouldn't be doing anything
Spinning in that situation also seems strange
WAIT i have an idea, maybe, so like, i am teleporting the fixed joint kinematic, which is connected to the dynamic collider. Should I not be doing that? Maybe that's the source of that issue 🤔
I thought it would be fine because it's the dynamic boi that's doing the actual collisions and beceause it's only connected by a joint it wouldn't have the issue
If the dynamic boi is colliding then it should work (or at least do something)
The 3D friction implementation is one of the parts I'm less confident in the new solver though, it was implemented partially using Rapier's approach and I might've scuffed some implementation details
so I wouldn't be too surprised if it has some issues
I should really add some friction impulse visualization and proper tests, like a friction ramp test (cubes with different friction coefficients sliding down a slope) and something similar to your case where a body should be lifted just through objects pushing the sides
AH I have a very good guess on what's going on
Or like
an educated guess
if friction is only activating when objects are sliding past eachother fast enough
that sounds like the dynamic friction works fine and the static friction is broken
👀

Static friction is broken in the sense that it's not handled separately from dynamic friction, but that's also the case for Box2D, Rapier, etc.
oh okay
(I might try to handle it separately in the future, but had some stability issues when I last tried it)
yeah, well then my educated guess it out of the window, do you want me to build the lifting object pushed through the sides example rq so u can debug the friction, or nah
if not it's fie
fine*
I can't debug it today or tomorrow, but it could be useful when I do have time for it
okie
Jon, could you make a collider collision function that returns ShapeHitData?
There is time_of_impact that returns a similar result, but I'm guessing that's not what you mean
Where exactly would that method be? I'm not sure what you mean by "collider collision function"
shape_cast without the raycasting
you could do a shape cast with a max_time_of_impact of zero
It won't do the calculations of the raycasting if it's 0?
It does do some raycasting logic but I think it should compute contact data if the time of impact is small enough
wdym
If you do a shape cast with a zero time of impact, it seems like Parry first runs the algorithm used for shape casting instead of just directly computing contacts. But it should also compute contacts for all the hits it finds in those cases, if I'm interpreting the code correctly
Parry also has a comment stating
witness points and normals will be calculated even when the time-of-impact is 0
so yeah it should be computing the data even in those cases with the default config
Which is why I think there should be a non cast version of shape_hits and cast_shape
Their use cases shouldn't be for raycasting only
yeah we could probably add that
Until then i'll use shapecast, should the direction be ZERO since it won't move?
You can't make the direction zero since it's a Dir2 or Dir3, you can just use whatever direction
How do I get the collider of a component?
I think cast_shape just clones the given collider for it's own use
That's the main purpose of this, for it to be for collisions so you don't have to give a collider
I guess just a normal collision function group version of it like from Res<Collisions>
Hi !
Unless I missed something there is no way to disable physics for a specific entity ?
Something like a PhysicsDisabled component ? (looking at Avian 's code & type registration I do not think so)
The use case for this is together with Blenvy being able to add colliders etc but keep all physics calculations disabled until the entity is actually finished processing.
Yes, exactly, this is both for spawning levels & for spawning new entities during the game too
enabling the feature "bevy/debug_glam_assert" doesn't work with Avian:
assertion failed: self.is_normalized()```
is that expected?
That seems to be Quat::slerp and I'm pretty sure Avian doesn't use that, but Avian might make rotations slightly denormalized so it if you're using slerp in your own code, it might not be normalized there
but yeah I'm not surprised if it doesn't work with Glam's assertions, they're pretty strict and physics pretty much has to do operations that lead to temporary denormalization
I just enabled PhysicsPlugin::default() and when I add any RigidBody or Collider the panic happens immediately
Don't you have slerp or rotate_towards (which uses slerp) anywhere? I double-checked and Avian doesn't use it
I just added Avian for the first time and was confused why the example code crashed.
I have glam_assert in my debug builds active since forever, it just breaks with Avian.
Oh wait the panic actually seems to point to , which would make sense. I was looking at the repo but the code has changed since the last Glam release so the lines are differentmul_vec3
No it's actually mul_quat 😂
But yeah, it might be a bit tricky to get physics working with those assertions since the engine does so many rotation operations, which could lead to small denormalizations
I can make an issue for it later today though
Thats completly fine if it isnt compatible, I would just suggest a note somewhere so nobody else has to debug that issue in the future again 😄
I can see if my game's rollback runs into any issues on avian 0.1. Afaik my rollback currently has 0 issues (on bevy_xpbd 0.5)
@vestal minnow you sure avian works without the default collider and parry? I'm getting a lot of compile errors 
A lot of them seem to be caused by references to some parry types which don't exist when parry isn't enabled (like PackedFeatureId), which then makes every type built on top break in weird ways (like Vec<ContactData> isn't iterable because the type ContactData isn't a valid type because of PackedFeatureId)
mmmm yeah collider constructors, swept CCD and PackedFeatureId
Welp, at least we know we'll need a 0.1.2 patch :P
That is something I thought about but it is not possible, as the components get inserted as soon as glad extras become available.
A not so great workaround would be :
- creating additional components for each of Avian's
- copy the data from each Avian component to the mock ones
- delete the original avian components
- re- create them after the entity is done being processed
But that seems very clunky to say the least 😁
I think I've heard some mention of adding it. Ideally of course there would be a general solution for this in the form of disabled entities and disabled components, so you don't need to ask every crate dev to add it 😂
😂 yes exactly this, I already had to add it to Blenvy.
Also I am not 💯 sur how disabled entities will Work in Bevy once they land (specifically if they will still be queryable).
afaik they'd be queryable, but only if you specifically query for the disabled ones
but yeah I'd probably be down to add RigidBodyDisabled and ColliderDisabled
Here's an example of the bounce issue
I can make a repo with a minimal reproducible example if you'd like
But it's pretty simple - just two entities that are inelastic but have friction bouncing off each other
I'm new enough to physics that I don't have a good feel for its limitations... I've been working on this for some time but still running into various problems.
Just wondering, is what I'm attempting here a generally difficult problem in physics and should I reconsider what I'm doing?
I don't think there's any reason for it to be that explodey at least ... Is the truck made from trimeshes and do the boxes have very low mass or something? 
I've changed the truck to use convex decomposition from mesh... the boxes do have low mass though. Maybe I need to be more realistic with weights and forces 🤔
How do I pause the engine entirely, i.e. all moving objects are hold in place; After, I can resume the engine and everything will keep moving again?
The clock representing physics time, following Time. Can be configured to use a fixed or variable timestep.
can you try making it out of cuboids? primitives are usually the best choice for anything dynamic if you can get away with it
and yeah, you probably need to add mass either way
how would I know how much mass to use? I've really been just using values like 1 or 2 👀
there's a method for calculating it from density
Usually you'd start by using realistic values, then change it if it doesn't suit the gameplay
It's how you end up with games having numbers for physics values that are 1.5x or 2x the value you'd see irl
I'm guessing that Mass is sorta arbitrary unit-wise but I can just pretend it's kg for everything?
ok, we summoned jondolf so now you're gonna get all the answers
oh geez
kg is not weight, weight is in Newtons because it's the force acting on an object due to gravity. Kilograms are the SI unit for mass
I generally recommend SI units yeah, so kg is good
also my comment on physics units #1260519770395250769 message
is there something for figuring out density from intended mass?
Not as a built-in thing currently, but it's density = mass / volume
I'm pretty sure Parry's shapes don't have volume helpers unlike our primitives
yeah but you might have an object without knowing volume or density, only mass...
and then you want all other objects with same material to have that density
I asked Jondolf for this back in like 0.3 
it's kind of a niche thing so i'm not sure if a method or just example would be better
So just like, setting the mass of a collider explicitly?
or specifically computing the density for an intended mass
because the density isn't very useful on its own
Yes, but still setting the center of mass and other fields correctly
And not like that hack I built where I aliased ColliderDensity to Mass and make my collider calculations just generate some nonsense based on that 😂
Okay would replacing ColliderDensity with bevy_rapier's ColliderMassProperties be good?
Custom mass-properties of a Collider.
I should be able to do something like that
i think in most cases you'd only need it when making the collider for the first time though
The density or mass needs to be stored because the mass properties could get overwritten when the collider is e.g. moved or scaled
An enum for density vs mass could be useful, the properties is probably unnecessary since people can insert the bundle directly if they want, and when they change the collider that should probably change too 🤔
Two separate components would work too ofc
wait, are we supposed to only specify Mass or Density but not both?
But now you have Mass vs Mass 
Currently it kind of expects you to only do density
ColliderDensity and ColliderMass would conflict if both exist at the same time
The actual collider mass props would still be stored separately, this would just control how they're computed, or overwrite in the case of ColliderMassProperties::MassProperties, although that duplication doesn't feel ideal for the overwriting case
Could change it to a Custom variant and make it use whatever you set the actual collider mass props to
If they are separate components, not having either makes avian not calculate it right?
Same goes for if they are an enum and you just don't add it I guess? 🤔
Ah, yea then a Custom variant makes sense
Mass properties are one of the messiest user-facing parts in Avian tbh, and we really need to rework them a lot, but there are also so many subtly different ways to handle them
I've never really been happy with our approach even though I've already done at least one rework to how they work (that was pretty early on though)
so.. if I wanted to set/add Mass.. should I be using Mass component or just increasing the ColliderDensity?
Thanks for the information ! And it would be fantastic to have those components! I could try to do a PR once I am done with the bulk of the release of Blenvy, as I would love to add a few features that are specific to Avian to make things easier / friendlier for users of both tools
the key to less explodey is more density?
As I made an item 2,000kg it started going through my cuboid size 1 static floor until I increased the step count. So your mileage may vary. Step count helped a lot, in making things less bouncy too
my step count is 21 🤔
Depends on the reasons for the explodey behavior. But if you apply a tiny force to an object that's just 1kg it will move 10x more than if it was 10kg
ah yeah, math
Iirc there was also some weirdness with high mass ratios, like a 2000kg object touching a 1kg object, but iirc that was one of the things the new solver was supposed to be better at 🤔
gonna weigh a truck and start over with this whole thing 👍
Was that before the 0.1.1 patch? I fixed one mass related issue like that at least
I will recreate the scenario on Thursday. It was somewhere on main before the patch.
@vestal minnow does Time<Physics> rely on Time<Virtual>? Or they are different times?
I want to pause the entire game, which should be achievable by calling pause on Time<Virtual>. I wonder if that will also pause the Time<Physics>
I can maybe also help out with such a PR. I want to see Blenvy + Avian succeed! Ping me if you become too swamped and want me to take a look.
IIRC it uses Time<Real>, you probably need to pause the physics clock separately
What is the consideration of using Real vs Virtual?
You can't speed up or slow down Real afaik, while Virtual is a mor flexible game time you could speed up or slow down. If Time<Physics> uses Virtual that means slowing the game down also slows physics down, which is nice, but also means you can't run physics faster than the rest of the game
Why are all my colliders wireframes pointing towards (0,0)? https://github.com/Niashi24/bevy_gizmo_jam/blob/e93f35aa97ab1b9bed929f574ee2615901204d80/src/tileset/load.rs#L131-L187
Speaking of Time<Physics>, is this expected behaviour? #1124043933886976171 message
I've been using apply_impulse_at_point with world-space vectors for point and center_of_mass but just noticed it says *local* point. Are they both supposed to be local.. and if I was using world space for both isn't that kinda equivalent?
what's the best way to scale a collider? when I edit the scale of a Transform on an entity that also has Collider and RigidBody::Dynamic I get the given sine and cosine produce an invalid rotation
Looks like the problem was I was setting one of the scale dimensions to 0, which results in an invalid rotation being calculated. Not sure if it's something that should be handled but not an issue for me anymore anyway.
@vestal minnow don't be surprised when looking at all the new open issues on GitHub. I added a bunch of things that I believe were previously only floating around on Discord so that we could track them better 🙂
Thanks, that's very much appreciated 😄 I've been meaning to open a bunch of issues but never got around to doing it yet
Do you happen to know anything that I missed while I'm on it?
that thing about replacing cast with structs
Oooh right
I think you got the biggest ones in terms of things I consider to be fundamental blockers for the grand upstreamening... Of course there's a ton of general quality things, the examples are pretty bad, docs could always be improved, there aren't enough benchmarks and tests etc. but those aren't clear tasks in the same way
not sure if square tilemap collider is worth adding as an issue, but it's something that would be nice to see eventually
What's the issue with the examples? I'm out of the loop since I honestly never really looked at them
Also: are there any things I should add that are not upstreaming-related?
also, figuring out density/mass from a couple days ago
Got a link?
[actually, here you go](#1124043933886976171 message)
This?
ah, thx
Moving to FixedUpdate is probably also required for upstreaming tbh.
Otherwise we'd have two separate fixed update schedules in Bevy
there might be more stuff to clean up but i think all of it first requires dogfooding
They're not "bad", but there is a ton of functionality that doesn't have any examples at all, and they're not very focused on actually teaching people how to use the engine. We also don't have many common physics engine test scenes like the ones is Solver2D or even Rapier's testbed
I've just added random examples over the project's lifespan without focusing on making them good yet
there's also like 6 different joint examples that could be condensed into one
So it's these things:
- Showcase more features
- Condense joint examples
- Add test scene
Ideally transform interpolation too if we do that (which we probably will)
There's an open Bevy issue for that, so worth thinking about how that will interplay
sec
the conversation was a bit bigger than that 😅
I think I'm too out of the loop there to understand what is relevant and what is not, sorry :/ Could you copy-paste the relevant parts?
(and https://github.com/bevyengine/bevy/issues/7836 seems pretty important as well)
What problem does this solve or what need does it fill? The purpose of FixedUpdate and fixed timesteps in general is to improve determinism in systems, but any fixed update system relying on Global...
Yeah, and ideally also some more game dev focused practical examples, like
- Basic character movement
- A more complete character controller example
- Buouancy
- Orbit (just simulating gravity and objects orbiting each other)
- Vehicle (car)
- Etc., I think @sleek thicket has mentioned a ton of ideas in the past
honestly just
Mass properties are one of the messiest user-facing parts, and we really need to rework them a lot
would be good enough for now
i think we might need a whole page similar to https://bevyengine.org/examples/ just for physics examples, and move them out of crate to reduce the bloat
The docs might not be very clear, but I'm pretty sure that they are all in world-space, but point and center_of_mass are still relative to the body's position
Eh, I don't think they need to be outside the crate. Don't see us needing giant assets for this.
all character controllers use a demo scene to show how it interacts with physics in different scenarios, that's probably the first thing to add
But yeah, having them running on a webpage would be great
i'm just judging by unity sample projects, they're always >100mb
if they're small enough then it's fine
yeah I could make an avianphysics.org website
This seems like unexpected behavior yeah, I'll try to look into it at some point
Alright, I think I turned everything you described @vestal minnow into neat little issues 🙂
true fix: switch to FixedUpdate 😛
Do you think this is blocking? https://github.com/bevyengine/bevy/issues/7836
What problem does this solve or what need does it fill? The purpose of FixedUpdate and fixed timesteps in general is to improve determinism in systems, but any fixed update system relying on Global...
I still think we could do interpolation pretty easily by just changing some things in SyncPlugin since we have separate physics positions
you could make tiny games as examples and release them on itch 🥴
Beyblade simulator plz
Oh my god, that is perfect
I think there's already some potential workarounds that could be done for that today, but imo we shouldn't be wanting anything in FixedUpdate to really touch GlobalTransform, since it's a visual component and should be updated during the visual part of the frame
Yeah that's fair 🙂
I'm getting quite a lot of the given sine and cosine produce an invalid rotation I've dug into it a bit and seems like something is getting NaN AngularVelocity values somehow, which is weird because almost all of my physics bodies are rotation locked
I'm wondering if there's a way to automatically recalculate ColliderConstructor::TrimeshFromMesh for a mesh when it's changed and hot-reloaded into a running game using the bevy/file_watcher feature? I would love to be able to quickly iterate on levels by changing meshes in Blender and immediately testing the changes in the running instance of the game, but currently the collider is only calculated at startup.
There was a suggestion of not removing ColliderConstructor so that an editor could fiddle around with it at runtime. If we did that, adding such a change detection would be trivial as well.
Added an issue: https://github.com/Jondolf/avian/issues/455
Also @quartz heart, I think the suggestion I mentioned came from you
Awesome, thanks! Didn't even think of the editor use case but that definitely makes sense as well
Okay so I managed to implement a very basic and WIP version of FixedUpdate-by-default physics together with transform interpolation and alternatively extrapolation. This is just using extrapolation:
Already?!?!
You're fast
That's nice! I like the colors 😛
So, are there any major roadblocks?
With transform extrapolation, we don't necessarily need any new components (since it uses a prediction of the next position), but with transform interpolation we would need to store the previous physics position. Or we could technically reverse-extrapolate back in time with the linear velocity, but that caused jittery behavior in my tests
But no I haven't noticed any real blockers yet
(and extra compute)
In practice we should probably just store the next position for extrapolation in a component as well to avoid recomputing it at every rendering frame
But no I haven't noticed any real blockers yet... I whipped this up in like 30 minutes though so it's not complete yet :P
Yep that would be really nice
That's great 😄 I'll be so happy when one of the Upstreamening issues is resolved. It will feel like progress towards having a physics engine in Bevy 🥲
I was wondering, is there already a feature planned for ignoring other specific entities (instead of just layers)
Should be trivial to implement. I'm a little bit busy ATM, but I could do a PR at some point if no one else does.
This, but I don't love the IgnoredCollisions name (and I believe the implementation itself has some perf issues)
https://github.com/Jondolf/avian/pull/364
Something along those lines would be great. But it should also work for tiggers/sensors etc.
this does work for them too
Ok then a different name would make sense.
Performance wise is the implementation a lot worse than manually modifying the broadphase?
The implementation in that PR is really bad performance-wise since it does all the hash set checks before the much cheaper early terminations, and in a very performance-sensitive part
So currently it's probably worse than if you were to just filter the output of the broad phase
How do you check for collisions the most basic way like if collide()?
actually nevermind, collisions_with_entity does that for you and collisionstarted
Would this be correct?
if collisions.collisions_with_entity(ent).collect::<Vec<_>>().len() != 0 {
}
this would probably be more efficient
if collisions.collisions_with_entity(ent).next().is_none() {
// ...
}
avoids allocating a Vec
I thought collect only moved, but I see
I seem to have forgotten that vectors have to be heap allocated no matter what
well, thanks very much
Not relevant in this case, but constructing an empty Vec does not heap allocate FYI.
Just in case you are ever worried about returning an empty Vec in a hot path 🙂
last time I had a peek at this lib, it was undergoing a large change, and also had some issue with a license whereby you couldn't use it on a commercial project - are these both still the case or?
The rework has already shipped and the licensing stuff should be okay
There is still a part of the code that uses XPBD, which is technically patented by Nvidia. The creator of the algorithm says it's fine to use it in open source and there already exist tons of open source implementations since years without anyone ever caring, so it's probably fine.
(Obligatory I'm not a lawyer)
Sooner or later, that part of the code will probably have to be changed to another solver to be sure (https://github.com/Jondolf/avian/issues/440)
But personally, I would say the library is in a pretty good spot to be used right now.
hmm, I don't plan on making the project open source, I'll have another look and if they have plans to fixrelatively soon I'll probably switch over
Sorry, I mean the creator says it's fine to use it anywhere AFAIK
oh, sweet
Just so you have a better source than "Jan said so", here's @vestal minnow's relevant post: https://github.com/Jondolf/avian/issues/346#issuecomment-2168141785
Relevant quote:
A while ago, we sent an email to NVIDIA asking about the legality of using XPBD to create an open source, MIT-licensed, physics simulation library. We actually got a response from Miles Macklin, one of the inventors of XPBD, who is also listed in the XPBD patent.
… I don't believe there is any restriction here – you can already find many open source and commercial examples of XPBD implementations online. …The wording is a bit vague, but it is encouraging that it seems like using XPBD should be fine. Of course the patent is assigned to NVIDIA itself however, so I believe they technically hold the power (I am not a lawyer).
Either way, I'd like to transition away from XPBD even for reasons unrelated to the patent. The upcoming release still uses it for joints, because changing them to be impulse-based would delay things unreasonably, but the rest of the engine has already transitioned away from XPBD completely. In the future, I might also rework joints so that they don't use XPBD.
Note that "the upcoming release" mentioned already happened 🙂
yeah so joints it seems is it
would be nice if I could just slap a feature flag to not include joints since I won't even be using them
Good point, I'll add it to the issue
Thanks
something that might be neat to add is a friction "palette"
like a
impl Friction {
const SNOW: Friction = Friction {
static_coefficient: 0.31,
dynamic_coefficient: 0.23,
..default()
};
const ASPHALT: Friction = Friction {
static_coefficient: 0.68,
dynamic_coefficient: 0.72,
..default()
};
}
would take a bit of time to compile (not rust compile, but find all the stuff) though
An issue with this is that the coefficients can vary a ton depending on the material combination
I don't think materials necessarily have specific friction coefficients on their own
they don't, but these would be a good like
shorthand
I'm not sure the user even has much say in different combinations like that anyways
we could maybe assume that the coefficients are for collisions between the same material, like steel-steel, but for some material combinations it could produce unintuitive results
i don't see why friction, restitution and density for common materials couldn't be built-in though
If you can find a list of friction and restitution coefficients, then sure, but a single material can have dozens of them depending on what the other material is
The COR is not a material property because it changes with the shape of the material and the specifics of the collision, but it can be predicted from material properties and the velocity of impact when the specifics of the collision are simplified
ok i see why friction is a pain
but you could just add docs for that, there's no real need for perfect accuracy
whatever you do is better than leaving people guessing about wtf they should put in, then all they care about is that it's some kind of rubber or wood or rock
yeah again the predicted coefficients of restitution in that list assume the objects have the same material, and the coefficients of friction also depend on the material pair
Damn, I'm working on moving bevy_xpbd_interp to avian and imroving it so you don't need to seperate into physical and rendered entities, but I guess that won't be needed? Or will this not be released for a while?
It'll probably be some time until I release 0.2, probably around a month or more, not sure yet
I'm not 100% sure on the API yet, but I'm currently thinking I might make a general purpose TransformInterpolation component:
pub struct TransformInterpolation {
pub start: Option<Transform>,
pub end: Option<Transform>,
}
and to actually enable the built-in physics interpolation, you'd add a PhysicsInterpolation component:
pub enum PhysicsInterpolation {
Interpolate,
Extrapolate,
}
it'd automatically insert TransformInterpolation, and the engine would update the start and end transforms automatically
could also have an option to enable it globally for all physics entities
Yeah I'm doing it the same way with a TransformInterpolation (although I separate position and rotation interpolation, which now that I think about it feels unnecessary)
you're the perfect person to review and contribute though :>
Yeah it's just that I'll have very little time to code for a while :(
Looks great! What exactly is the "Real Time" case here?
Just doing movement in Update
Ah, cool
"Variable timestep" would've probably been clearer
Out of curiosity, has anyone built an FPS character controller using avian yet?
I've been working on extending the kinematic character controller example, and have been struggling with figuring out how i should do the camera properly (currently i just have a 3d camera bundle as a child of my character however applying pitchwise rotation to my entire character is not ideal)
I wonder if its possible to lock an axes for a parent but not a child?
scratch that, not sure how that would work
I've implemented a 1st person camera, but it's not parented to my character. I have a CameraAnchor without a parent, and the Camera3Dbundle is a child of that anchor. I update the position and rotation of the CamerAnchor manually
that also makes it possible to selectively apply rotation or not, I have a hybrid currently where some parts of the character rotation is actually applied to the anchor as well, but normally you would probably have the camera rotation mostly independent of your character
I believe https://github.com/idanarye/bevy-tnua/tree/main has one. I used a modified version of it with xpbd and it looks like it's now using avian
Are there any advantages to using kinematic or dynamic?
/ one over the other
LWIM?
Not right now but i have seen it and kept the name in mind
I use a separate entity for the physics object, the view model and the camera. These are all not hierarchically connected. Their relationship is as follows:
- The camera follows the mouse movement for the rotation
- The camera follows the physics object for translation, but is eased
- The physics object follows the yaw of the camera
- The view model follows the camera in translation
- The view model follows the camera in rotation, but is eased
The physics object has its rotation axis fixed so that is can only yaw.
It is moved using Tnua.
^ This is how it looks like in action
I see, this was what i was looking for clarification in (hierarchy)
I had seen some other examples where it was done this way, and was wondering if it was just because it was easier to set up that way in an example, or if that was just the best way to do it in bevy.
It's probably not, but that's what my thought process immediately led to
How does the physics object query for the camera? Once again scratch that, i misunderstood how queries worked
The reason I separate them is because all three objects have very different requirements in how they should move, so parenting them makes you constantly fight against Transform propagation.
Finalizing some stuff for the switch to FixedUpdate... my god the default 64 Hz is jittery
60 Hz has much less jitters, at least on my display
ofc interpolation will fix that for apps that use it, but...
Of course, that makes sense.
I suppose I was just thinking camera was a component of a complete "player" and therefore would usually be represented as a child in other game engines
the increased timestep frequency will also make perf a bit worse (but improve stability a bit), although I guess we could just reduce the substep count by one
or just accept the small-ish loss
The default timestep() is 64 hertz, or 15625 microseconds. This value was chosen because using 60 hertz has the potential for a pathological interaction with the monitor refresh rate where the game alternates between running two fixed timesteps and zero fixed timesteps per frame (for example when running two fixed timesteps takes longer than a frame). Additionally, the value is a power of two which losslessly converts into f32 and f64.
The fixed timestep game clock following virtual time.
Do you have numbers on that?
Because trading a little bit of performance for stability and "default Bevy behavior" sounds pretty reasonable to me
No, it's not like a huge hit or anything
What kind of tradeoff would reducing the substep by one bring? Reduced stability again, right?
yeah
Seeing as historically people have often had issues with simulation stability in Avian, I think I leave the substep count in peace.
we already have two more substeps by default than Box2D though, so it'd probably be fine to reduce by one
but yeah keeping it is probably fine too
oh, that's a really good point considering how similar they work
we have 6, and both Box2D and Rapier have 4
Although Rapier might do some extra stabilization iterations? Not sure
is there anyway to better handle colliders overlapping at spawn? currently in some cases this causes them to have NaN angular velocity and panics
Is this on Avian 0.1.1 or something else? I haven't really noticed any big issues with this after the patch
Also what shapes do the colliders have?
I had kinda similar situation (avian 0.1.1), where for boxes stacked on each other at spawn one teleported sideways. Those were kinematic bodies though, but they behave stable when falling on each other with code heavily inspired by current kinematic controller example. Only after I've reduced size of colliders by a bit, spawn overlap warning was gone and boxes behaved correctly.
Having said that, I've found there is something called CollisionMargin and I'm not sure whether having it does something different than just making collider respectively bigger?
I'm currently trying to understand why my bodies are exploding/time is slowing. There are none spawning in the same place on top of each other, and there are no collision events, but they're connected by prismatic joints and it's completely unstable. There are only six total RBs and four colliders in the whole scene
I tested Avian like... a while back, when it was bevy_xpbd, and found it started massively slowing down when doing a vampire-survivors type workload. However, the underlying engine changes seem like they would have fixed that, and rapier is quite awkward to use. should I give it another go?
"exclude themselves"?
I do still have the branch if that helps: https://github.com/kazagistar/boundry_dynamics/blob/xpbd/src/monster.rs#L44
logic is basically "spawn monsters randomly around every 0.01 seconds (to get to stress test levels fast)", "have them all have colliders", "set their velocity towards the player", and "have them pulse and change size with the beat of the song"
right, I'm not exactly trying to make a survivors game, this logic is oversimplified. I am doing much more, uh, dynamic and physicsy movement
that said, fair enough, I guess I should make their movement smarter so they collide less?
shrug, its a game, you can make most decisions multiple ways
for now, it sounds like I gotta stick with rapier if I want to keep collisions?
I'm not really making a clone, I am making a music game that centers all the enemies reacting to the music that happens to have vampire survivors adjacent mechanics. long story short, I don't really want to do optimizations before I know if the basic idea is even fun or good 😛
but yeah, maybe I dont actually want collision physics, because they are kinda fundamentally nonrhythmic
vampire survivors does have some physics though, right? its just boids style evasion or something?
colliders don't really need to rotate, rescale, or collide with others on the same layers
and i'm not even sure, but probably yeah
Yes it's on 0.1.1. These are all Circle colliders. I will try to put together a minimal example, I can reproduce it consistently now. I wouldn't mind explosive behavior in this scenario, but the panic is an issue for my use case
Isn't bevy multithreaded?
Yes, Bevy can run systems in parallel when they aren't explicitly ordered relative to each other and don't have conflicting query accesses
and you can also iterate queries in parallel within systems of course
Multithreading just has some overhead, so it's generally only worth it if you're actually able to properly take advantage of it and are operating on a large number of entities
In the case of Avian, the physics schedules are using a single-threaded executor since the core simulation steps inherently need to be run serially, and performance with the multithreaded executor was worse when we last tested (that was a while ago though)
of course things like collision detection and eventually the solver can be parallelized tho
Is it explosive without the joints? The joint anchors could maybe be wrong
Hmm, moving to FixedUpdate will have the side effect that no physics systems will be run during the first frame, unlike before 🤔
It looks like the fixed timestep schedules never run on the first frame regardless of how much you advance time
i.e. this doesn't run FixedUpdate
// advance by one second
tick(&mut app, 1.0);
but this does
// advance by *zero* seconds
tick(&mut app, 0.0);
// advance by 1.0 / 60.0 seconds
tick(&mut app, 1.0 / 60.0);
(noticed this because we have a failing test for bodies moving on the first frame)
it doesn't seem like that big of an issue though
usually when you launch games you're stuck in menu for a few seconds before you even need physics
Is that by design?
That's usually the way to go. A lot of survivor games don't even do physics, since you can just pretend like monsters have collision trough some clever boid-like logic. If you do do physics you'd need something fairly specialized to get good performance with how much enemies would bump into eachother (tho being able to model everything as spheres does make things a lot easier)
I would assume so, there's this test at least
i.e. it seems like "frame 0" doesn't count
it does seem kinda weird that you could advance time by 999999 hours, and it still wouldn't run FixedUpdate until the second frame
I'd at least open an issue for that, even if it is intentional
Went back to it, and of course it was my issue. At the time I was setting Mass(2000.0) with default ColliderDensity (so 1 on a 1x2x1 object) and no other attributes so there's a pretty massive difference. Just doing that caused the dynamic cuboid to sink/collide in between a static cuboid. Now I set the all the properties including Inertia when setting an explicit Mass and ColliderDensity to 0 so not facing issues.
Objective
Closes #263 (the removal detection issue should also already be fixed thanks to hooks and observers)
So far, Avian has run in PostUpdate by default, but with a custom fixed timestep solut...
So, I think PreUpdate should now be the recommended place for input handling? Or is some other place better
I'm also wondering if physics should use FixedUpdate or FixedPostUpdate 🤔 At least FixedUpdate would make it really easy to run logic before and after physics with FixedPreUpdate and FixedPostUpdate, but people might also have other gameplay logic in FixedUpdate
At least LWIM uses PreUpdate
A Plugin that collects ButtonInput from disparate sources, producing an ActionState that can be conveniently checked
They should be easily able to order that with PhysicsStepSet::First and PhysicsStepSet::Last
I feel like doing stuff in FixedUpdate is advanced enough that you can expect such users to be aware of that
that's only for systems running in PhysicsSchedule
but yes
Hmm fair enough.
Does this not also change the order relative to Update? Avian currently runs after Update, but this will make it run before
PhysicsSet::Prepare and PhysicsSet::Sync would currently be what you'd use for that ordering... we should really simplify it though, either by adding First and Last to PhysicsSet as well, or by otherwise reworking the system sets
It does change that, yes
I'll mention it more explicitly
If I was a user reading this and didn't know what fixed time was or why I should care, this would read to me as if I had to move all of my current code from Update to either FixedPreUpdate or FixedPostUpdate
Oh, TIL
Hmm, I'll try to make it clearer for the average user
Maybe it should say something like "For most users, no change is necessary. Keep your systems in Update, just like before"
All the examples use Update though
Doesn't LWIM collect all input information in PreUpdate and then you can use that however you want in Update?
Maybe, I haven't used it (yet), so I'm not sure how it works
You should, it's one of the best libraries in existence 😄
I'm mainly wondering what the new recommended way to handle input is, if FixedUpdate runs before Update and FixedUpdate itself has input issues
But yeah, if I understand it correctly, an ActionState's ActionData is filled in PreUpdate and then queried in Update.
Metadata about an Actionlike action
Absolutely, I just haven't made games in Bevy yet despite making Avian 😂 I might participate in the jam though, but not sure how much time I'll have
👏 Bey 👏 Blade 👏 Simulator 👏
Won't that cause a one-frame delay if you respond to input after physics?
update for using input, pre-update for preparing everything needed for that
and i'm not sure why physics in post-fixed would be a good idea
You can also query it in FixedMain, although of course that might not every frame, so idk if that's cool
also, beyblades have joints that disconnect from heavy hits, and avian still uses xpbd joints...
and without breaking apart, it's just a spinning top simulator
I edited the migration guide to hopefully be a bit clearer
Hello (new here!)
I'm playing around with bevy and avian, and was wondering how one would go about making a physics explosion at the cursor which would scatter all objects around radially? I'm currently iterating on the Marbles example. Should I create a query to mutate their LinearVelocity based on their relative position of the cursor?
Yep! The direction would be (object_position - cursor_position).normalize_or_zero(), and you can either mutate the LinearVelocity or apply an ExternalImpulse. ExternalImpulse takes mass into account, but might be a bit more annoying to use
If I make a game, I'd ideally like to use it to dogfood Avian or Peck, and maybe develop something useful like that collide and slide implementation and a basic KCC... but then I'll most likely just spend the week building out that feature and not have time to actually make the game 😂
It'd be interesting to try to go Parryless and use Peck even though it's very WIP still
Should I get the object_position from Transform - converting it to Vec2 somehow?
Yes, transform.translation is the position, and you can turn that to a Vec2 with .xy() or .truncate()
You could also use GlobalTransform, because Transform is the position relative to the parent. But if you don't have entity hierarchies, it shouldn't matter
I have this now:
fn movement(
buttons: Res<ButtonInput<MouseButton>>,
windows: Query<&Window, With<PrimaryWindow>>,
mut query: Query<(&Transform, &mut LinearVelocity), With<Controllable>>,
) {
if buttons.just_pressed(MouseButton::Left) {
if let Some(cursor_position) = windows.single().cursor_position() {
for (transform, mut velocity) in query.iter_mut() {
let object_position = transform.translation.truncate();
let direction = (object_position - cursor_position).normalize_or_zero();
velocity.y += 100.0 * direction.y;
velocity.x += 100.0 * direction.x;
}
}
}
}
However, it doesn't seem to work quite as expected. Do I need to offset something regarding the cursor?
Wherever I click they all seem to move down towards the left bottom corner.
.cursor_position() is in viewport coordinates. You should transform it into world coordinates using the camera, like this:
fn movement(
buttons: Res<ButtonInput<MouseButton>>,
windows: Query<&Window, With<PrimaryWindow>>,
camera: Query<(&Camera, &GlobalTransform)>,
mut query: Query<(&Transform, &mut LinearVelocity), With<Marble>>,
) {
if buttons.just_pressed(MouseButton::Left) {
let window = windows.single();
let (camera, camera_transform) = camera.single();
if let Some(cursor_position) = window
.cursor_position()
.and_then(|cursor| camera.viewport_to_world_2d(camera_transform, cursor))
{
for (transform, mut velocity) in query.iter_mut() {
let object_position = transform.translation.truncate();
let direction = (object_position - cursor_position).normalize_or_zero();
velocity.y += 100.0 * direction.y;
velocity.x += 100.0 * direction.x;
}
}
}
}
Thanks, it works! 🙌
I suspected as much - as I was looking at the code for the chain-example 🙂
By the way, is there a short-hand method for doing operations between Vec3 and Vec2? In other words, so that I wouldn't have to explicitly write .x and .y ?
You can just do velocity.0 += 100.0 * direction if velocity and direction are both Vec2 (and I think here they are)
LinearVelocity is actually just a "newtype component", so it's just
pub struct LinearVelocity(pub Vec2);
to do math on the stored vector, you currently need to access it explicitly with .0
you could also deref with *velocity
I tried that earlier, didn't work :/
You might need a double deref **velocity because the query returns it wrapped in a Mut thing :P
That worked, yeah 😄
Just noticed that there's a small lag-spike when I click, but it doesn't seem to be physics-related. If I change to buttons.pressed.. instead, it continuously applies the impulse, but it doesn't lag besides the initial click. This isn't a problem for me, just an observation! (also in release)
Really nice work with the physics by the way @vestal minnow , it's really performant ❤️🔥 . I used to work with Box2D several years ago when I wrote my masters.
apparently for the translation to actually update after collision I have to spawn a while loop
instead of use one
just for collide and slide
Are you on Linux using X11? If so, I know the issue.
Yes I am.
Might be this then: https://github.com/bevyengine/bevy/issues/14303
Try compiling with the wayland feature
Thanks, that fixed it 🙂
The fps dropped from 120 to 40 though.. I reckon something is up with the drivers.
The fps seems to have a negative correlation to the window scale.
Catch22 😆
Anyways, I'll subscribe to that issue and keep myself posted.
These are all not hierarchically connected
This worked, however seems quite wrong and disjointed in my head, is there no better way to accomplish this while somehow retaining some sort of connection between a camera and a controller (physics object)? What if there's multiple cameras and controllers? (not something i intend to do, but for example if someone was making split screen a feature for their game)
In reality it's probably fine for my use case
just trying to over engineer this
Make them all children of an organizational entity that never moves away from 0, 0, 0
it makes sense once you consider more scenarios
e.g. even fps games have cinematics, consider how many things can bug out if you rely on parent at all, and vice-versa
I'd like to improve our issue labels, currently thinking of something like this 🤔
(whoops forgot C-Code-Quality)
vs. current
Way better
I personally like X-Contentious from Bevy as "This is not controversial, but worth thinking about"
Yeah, I'd probably add that too
Also X-Blessed might be nice as well to say "Whatever this issue or PR says or does, @vestal minnow has already said it's fine somewhere"
We can probably add that when there is a case where it'd make sense to actually use that, I'm not sure if we have that yet
In Bevy the description is "Has a large architectural impact or tradeoffs, but the design has been endorsed by decision makers"
So far most large architectural things have been just done by me so they're auto-blessed in that sense :P
I'll update the labels now though and try to triage all the issues
I noticed that while the documentation of ShapeHitData.point1 says that it's expressed in the local space of the collider shape, when I print the value it seems to be in world space. Is this a mistake in the documentation or am I doing something wrong?
I think you're correct, and others have also reported this many times now. IIRC @true hearth also tested this and verified that they are indeed in world space.
The docs say that the data is in local space because that's what Parry says (the library that is internally used for these spatial/geometric queries) and I haven't updated the docs yet or fixed this in Parry. I also remember it being somewhat inconsistent though, and that for some shapes it is still in local space, but I'm less sure about that 🤔
Added an issue: https://github.com/Jondolf/avian/issues/458
Got it, for my purpose world space is what I want anyways, it just tripped me up the first time I saw the doc
whats the recommended way to disable a distance 2d joint? Making a game with a grappling hook where the other end of the joint doesn't exist until it gets attached. Unless I should be spawning/despawning a joint as it attaches?
I would probably spawn/despawn it currently. You might also be able to set the compliance to f32::MAX or something, but I haven't tested how that behaves
Gotcha. For the latter option not sure what to set the entity to
Ah right... I think you could actually just set the other entity to Entity::PLACEHOLDER or some random entity that isn't a rigid body, I think that should effectively disable the joint 🤔
How am I supposed to use taskpool to handle collide and slide?
Do you need a taskpool for that? I'm not sure if collide and slide is something you'd typically parallelize
Apparently doing a while loop in a function won't update the actualized translation until the function ends
I'm guessing bevy waits for each function to end
But essentially the object will never not be in collision because of that
So collide and slide is hard
That's not really how it works, I'm kind of confused about what exactly you're trying to do or why you'd need to have global positions update immediately for collide and slide
If you change the Transform in a system, that will update immediately (although actual rendering is of course done later in the schedule), but GlobalTransform will not be updated immediately because it would be insanely expensive to do so. All GlobalTransforms are updated in batch in PostUpdate
Secondly, physics uses its own position components that are also updated separately in the physics schedules. So changing Transform won't cause an immediate update for physics positions either
well, that's the issue I guess
while collisions.collisions_with_entity(ent).next().is_some() {
tra.translation.x += vel.x * time.delta_seconds();
}
This freezes the game
on collision
Thirdly, spatial queries use their own acceleration structure that is updated once per frame. If you just move an entity, its position won't immediately be updated for spatial queries unless you trigger a manual update (which would also be insanely expensive to do repeatedly in a loop).
This doesn't really look related to collide-and-slide to me
All collide-and-slide implementations I've seen use shape casts
Typically you cast the player's collider in the movement direction with a max distance determined by the velocity, update the origin of the cast to the time of impact, update the movement direction with a vector rejection against the hit normal, and keep doing this iteratively with the leftover velocity
this doesn't require any collision data shenanigans or immediately updating the state of the world
you just move the character once to where the algorithm ends up
I would probably only be able to understand that in code
I've already linked two implementations of it, and a video
#1124043933886976171 message
Updated the issue labels, changing all the bugfix labels to C-Bug was pretty annoying 😅
Note to self: Don't have separate bug and bugfix labels for future repos
don't have bugs 🧠
Oh we surpassed bevy_rapier in stars today 👀 that's pretty cool
of course Rapier itself has a lot more stars tho
i'm not sure if i'm doing something wrong, but it seems that angular damping doesn't do anything
pasting just the damping code works, component doesn't
oh it was just for dynamic
Yeah it might make sense to allow it for kinematic too, but I think it currently only affects dynamic bodies
yeah, inside forces should affect it, outside shouldn't.
I've also been wondering if we should just make LinearVelocity work without RigidBody... In an OOP engine it wouldn't work since velocity would just be a direct property of the rigid body object, but in an ECS context it might make more sense
Why wouldn't the component be able to work on its own?
if you don't need it to work, you don't add it
damping is completely optional, not influenced by outside forces, so there's absolutely no reason to keep it only on rb
one day
Soon™
LV is supposed to be affected by outside forces though, but if that's optional then it makes sense to let kinematic use it
and AV is already enabled
basically, static is the wall that isn't moving anywhere,
kinematic is the wall that is moving, but can't be moved,
RB is the character between the 2 walls.
Yeah all LinearVelocity and AngularVelocity do is move the entity based on the velocity and timestep, so I think it makes sense that e.g. this would work without any RigidBody
// Moves right at 1 unit/s
commands.spawn((
TransformBundle::default(),
LinearVelocity(Vec2::X),
));
Then if you want it to be affected by gravity etc., just add RigidBody::Dynamic
Honestly having separate kinematic bodies feels pretty pointless in our case
if you want it to be affected by gravity, you add gravity component...
mm of course LinearVelocity and AngularVelocity operate on Position and Rotation though, so those would still need to be inserted
does rigidbody have to be an enum btw?
Not really, I'd like to split it up and have at least a Static marker (there are also plans for this in rendering)
yeah, i suspect you could optimize everything by a lot just by rethinking that
maybe bundles would work as a placeholder
but it's basically just 3 components, right?
physics + can/t move + can/t be moved by outside forces
I really don't want bundles, but yeah I think there's still a lot more we could do to better leverage the ECS and composability
I feel like "can't be moved by outside forces" (kinematic) doesn't necessarily need its own component, and you could just add e.g. velocity or character controller functionality by just adding the related components
i.e. entities are kinematic by default, in a sense
and to make it dynamic, add some component
to make it fully static for optimization, add Static
wouldn't it make it easier for queries though?
I guess, but from a functionality standpoint it feels kind of redundant
for the users the only change with bundles would be replacing Rigidbody::dynamic/kinematic/static to Rigidbody::dynamic()/kinematic()/static()
and you can focus on whatever you need for optimizations
Like what's the functional difference between
commands.spawn((
TransformBundle::default(),
LinearVelocity(Vec2::X),
));
and
commands.spawn((
TransformBundle::default(),
RigidBody::Kinematic,
LinearVelocity(Vec2::X),
));
(other than maybe queryability)
and if you go with the bundles then you can add the mandatory components right away instead of on spawn
We can already do that with component lifecycle hooks or observers (run before any other systems at least) and eventually required components (inserts immediately, like a bundle would)
man, i really don't like the idea of mod D':
you can name them however you want and use https://doc.rust-lang.org/reference/items/modules.html#the-path-attribute
it's avian stuff
you can PR it 😄
@_@
Bevy uses mod.rs almost everywhere I'm pretty sure
at least in the crates I've contributed to
I tend to follow Bevy's conventions for this stuff (and I dislike the non-mod style of having the file next to the folder even more)
ok i tried it, this is neat.
just renamed mod into folder name and now it's almost exactly what i always wanted
Is there a way to detect if a polyline forms a cycle? (and then access the interior of that cycle?)
Or maybe there's a better way than polyline to build a continuous curving line. Something like splines? I'm not very familiar with all that
"cycle" you say, fitting with the jam
but no, I don't think Avian/Parry has anything built in for that
I think you could treat each line segment in the polyline as individual lines and check for line intersections
a more complicated algorithm for getting all line intersections is the "Bentley-Ottmann algorithm" but I think you could also do a naive approach of testing every line segment against every other line segment, assuming your input isn't too large
but there could be a better approach too, I haven't looked into how cycles or self-intersections are typically detected for polylines
Continuous curving lines are typically the domain of Bezier curves, B-splines and NURBS
(Depending on your needs)
I know rapier uses PostUpdate
which I feel like does make things simpler
otherwise a lot of people's gamecode ends up relying on being before the physics sim
I feel the problem there is there is always at least a 1 frame lag between input (FixedUpdate or Update) & visual response (Update)
not sure I understand you here, as long as the physics runs between the player updating their game code/entities and some form of transform propagation, it shouldn't have a frame delay
most of the frame delay issues are going to come from the transform propagation itself being wonky to work around
but if you don't rely on that and instead use position it shouldn't affect it
Omg does this mean if I have a submodule foo which itself has modules bar I can actually have them as foo/foo.rs foo/bar.rs?
I have wanted that for a while
I have simple 2d simulation, circle colliders bouncing around an enclosed square border. Whenever one of the colliders hits a wall, the angle of reflection is perpendicular to the wall, as opposed to being equal to the angle of incidence. This effect it causes is unrealistic I think, is this something related to the physics or the collider I am using?
Using PostUpdate (like we currently do) doesn't really make sense for a "native" solution, since I really doubt Bevy wants to have two different fixed timesteps. So FixedUpdate or FixedPostUpdate makes sense imo
Also I checked, and both Unity and Godot run the fixed physics step before the "regular" update step
Collect input -> physics -> update
in Bevy schedules, PreUpdate -> FixedUpdate -> Update
Ah my bad. I misunderstood where the rendering was actually happening.
*when single threaded in Godot afaik
It's inputs -> physics_process -> physics -> process in godot I think. There's also some settings in godot to solve some annoying issues of fixed update loops by polling them constantly while waiting for vblanks
okay Unity's is here
https://docs.unity3d.com/Manual/ExecutionOrder.html
If you really want to simplify it you'd have to simplify it down to input -> n× simulation -> visual update -> rendering
Physics being part of the simulation (usually running near the end of it)
yeah
that's why I'm kinda wondering if physics should be in FixedPostUpdate since it's "near the end of the simulation" and could make having game logic in FixedUpdate nicer, but just putting it in FixedUpdate would also make sense
input is collected immediately as it happens, outside of both loops, but it still feels awful when lagging
Since we no longer have a way to tell systems to run at the start or end of the schedules like we did with base sets I think FixedPostUpdate would be the sensible default
I think I would agree, yeah
people could still easily run stuff after physics if they need to, either with just .after(PhysicsSet::Sync) (or Last if we add that) or FixedLast
in unity fixedpost is fine because it fires off methods immediately as collisions happen
in bevy i still have to sort it and then do the rest of the logic... actually yeah i guess it might be fine there
is there fixedpreupdate?
yes
Godot doesn't seem to have any way to run stuff after physics at the same fixed timestep :P
https://github.com/godotengine/godot-proposals/issues/6795
intuitively i expected collisions to finish between pre-fixedupdate and fixedupdate, e.g. ground check ray is in fixedupdate because i thought the position is already a new one
what uses fixed/pre/post/update in bevy itself?
nothing
I think putting anything in FixedUpdate when you already have a physics engine doing stuff for you seems kinda niche. Do you have an example of what an Avian user might put there?
Anything related to doing physics stuff on objects, like what you'd do in Unity
Not just physics stuff. Everything that is part of your game simulation belongs in there
Some games aren't very heavy on it because they mostly rely on UI, but other games are almost entirely a simulation
I know, but I'm wondering what kind of "physics stuff" since Avian is already running.
Would you apply ExternalImpulses there?
Or manually set velocities?
Character controllers, game effects that apply impulses/forces, non-visual collision reactions, etc
movement for bodies (character controllers), applying forces when in some area, custom gravity...
In something like an action rpg the entire skill system would also be running there
Alright, that makes sense, thanks 🙂
movement depends on ground ray/collision, and that expects physics to have already happened, no?
Yes, but that's only a problem for the first frame 🤔
(noticing that I still have too much code in Update that should be in FixedUpdate in that case 😄 )
Often that first frame happens while you still see a loading screen too so it's not a big concern
Oh yea you almost certainly do, most people do. FixedUpdate doesn't see nearly as much use as it should because of various factors, but physics engines not encouraging it is probably the major one
The ground ray only really cares about the state at the start of the frame (which should be almost identical to the last fixed update), so it's not really a delay. The data is just missing on the first frame, which is why in many games if you can see the loading happening your character is always falling the first frame even if they are already touching the ground 😂
e.g. you're on a moving platform... ray is sent down and it says you're on ground
simulation advances, the platform moves so you're actually not on the ground, but until the next physics update you think you are
...yeah i guess it doesn't matter that much, but still weird
Ah like that, I guess you could also calculate grounded after physics, just so your visuals are correct immediately 🤔
but grounded is what i use for movement+spring+gravity, i'm not even sure what i'd want to be applied before physics
Would you rather have all movement delayed? Like you jump or have some explosion, but it only activates the next frame because you ran the logic after physics
If you responded to input in Update and handled the physics part in FixedUpdate, but internal physics was run in FixedPreUpdate, you'd even get a delay of two or more frames
i guess the whole argument just needs a page/example to let users decide
with higher refresh rate 1 frame would feel like 2 or 4, so if anything is off then it'll be noticeable... i guess i'll have to set physics to 1/4 speed to see how everything feels
I think all of it should be "applied" before physics so physics can execute it. But checking for grounded could be either after physics or at the start of the next update
Is there any way I can help with migration away from parry ? Do I deduce correctly from the X-Contentious tag that there is no consensus yet if this is the direction the project needs to move in?
I can contribute RFC, logic code, tests, benchmarks, documentation.
I can spare 4-8 hours a week to work on this.
I live in Helsinki and am available for pair coding if anyone is interested.
There is certainly consensus that parry needs to go, sooner or later
Yeah it is something that I really want to move towards, but it is a massive undertaking, and needs a lot of design work. I'm developing my own library called peck for this already, here's a rough list of things that we would need (not entirely up to date, and a few things might be optional)
love the name!
The most important part for now would be implementing all the geometric queries for all of Bevy's primitives
I would like to do this by ideally upstreaming those to Bevy itself, and then most other things would be provided by peck
I have already implemented analytic 2D ray casting for all primitives: #math-dev message
Next up would be 3D implementations
And then other geometric queries, like point queries, closest point computation, minimum distance computation, intersection tests, and shape casts
GJK gives a lot of these "for free", but ideally we would have optimized analytic solutions where possible
Sounds like development of these is parallelizeable. I would like to pick up some mid-difficulty query and see how long it takes me to implement. Does all of this happen in a closed repo?
Yes, peck is currently in a private repo since it's still very WIP and pretty unusable, but I could probably make it public under heavy "under construction" warnings
It also has a somewhat questionable design that relies pretty heavily on generics for internals at the moment, and I'm still experimenting with whether that's the way to go
I'd like to avoid the weird crate split that Parry/Rapier/Avian have where 2D and 3D share the same codebase but with different, incompatible feature flags for the dimension
I think that if the algorithm is written clear enough it should be straightforward to migrate
Yeah migrating to a different approach shouldn't be too bad
I agree, incompatible flags are a pain due to cargo treating them additively
For now I'm also trying to avoid the dynamic dispatch that Parry has by using a Shape2d/Shape3d enum, but it leads to some pretty long match statements and some macro usage
I have one macro which expands to this 😂
It's almost like sdf_peck in that regard 👀
this would also be pretty easy to migrate to Parry's approach later if we wanted to though
But yeah, I'd definitely appreciate help with implementing things for peck. I could try to do a more complete write-up tomorrow about what we would need to be able to replace Parry, how we should go about it, and what things can be worked on in parallel.
I'll also try to get the repo to a state where I could make it public (with warnings etc.)
Some more complicated but important things that don't necessarily need any connection to Bevy or Glam would be 2D and 3D Quickhull, and a convex decomposition algorithm like VHACD or CoACD
or 2D Quickhull is actually pretty easy afaik, but robust 3D Quickhull is quite challenging
adding 2D support and more non-ray traversal options for OBVHS would also be useful and not tied to peck itself
That sounds cool!
I am making a 3D game, so I am more motivated to work on 3D algorithms 🙂
I'll look it up and see if I can comprehend it
Reading the wiki article it seems trivial. I am sure I am underestimating the task though 🙃
I guess the non-trivial part will be optimization for speed
Robustness is generally the main thing
From my experience this is only partially true
oh no...
convex hull algorithms are very prone to numerical issues and require a ton of care to handle all sorts of cases
something like robust predicates may be useful
Pretty much the only Quickhull implementation I've found in pure Rust is chull, but it had some issues when I tested it
Parry of course has its own implementation as well though
But I'm not sure if we can legally copy that if we want to be MIT + Apache 2.0 licensed, since Parry only has Apache 2.0
unless we license that separately
or ask Seb and other people who contributed to it for permission I guess
I'll read more about robust float computations and see if I feel like the quickhull is a task I can take on. If not, maybe at least I can write something up, that will help the next person to pick it up.
How do I create colliders from a separate glb file?
Alright, sounds good; I'll also try to write up a bunch of the work that needs to be done, and maybe we can find something else you'd be interested in if Quickhull doesn't work out (which is totally understandable, I also looked into it at one point and left it for later lol)
I'm thinking that I might just make the peck repo public and open a whole bunch of issues for the various things we need to implement (and how)
and maybe some tracking issues to tie it together
I struggled with this, eventually defined marker components NeedsColliders and CollidersInserted and wrote a system that reads all the entities with the former and without the latter and with loaded gltf asset and iterates the children and adds colliders
I was testing avian physics and I noticed adding
.add_plugins(PhysicsDebugPlugin::default())
causes my test runs for my bevy app to take 3-4 extra seconds to go from black screen to rendering. What is avian doing?
You can load the scene like normal, and use ColliderConstructorHierarchy to generate colliders
A component that will automatically generate Colliders on its descendants at runtime. The type of the generated collider can be specified using ColliderConstructor. This supports computing the shape dynamically from the mesh, in which case only the descendants with a Mesh will have colliders generated.
oh man this is so much simpler
In my case, I have a complex model and I want separate colliders for it in my understanding this only creates colliders for the scene assigned to the entity.
(previously called AsyncSceneCollider in bevy_xpbd)
When you load the scene, Bevy typically creates a hierarchy with all the meshes in the scene as children
- Scene root
- My mesh 1
- My mesh 2
- My child mesh
- My mesh 3
ColliderConstructorHierarchyadds a collider for each mesh that is a descendant of the scene root
Like if you had an entire game level in a glTF scene, it would generate a collider for every entity with a mesh in that scene (by default)
Relevant discussion for how I'm doing colliders in Blenvy right now: #1174712142314876959 message
got my colliders to work, but now I have issues with the dynamic rb shaking, any idea what may be causing this issue?
switched to trimesh from convex hull and now it is better, still shakes a bit shakes a lot after some time
Is there a way to toggle a collider?
Nothing that isn't a workaround: https://github.com/Jondolf/avian/issues/436
And that would also be a workaround ... If only entity and component disabling 
adding Sensor seems to work for my use case but a toggle would be a lot nicer
static component might become useful for other stuff in bevy, like how unity has a dropdown right next to object's name
How can I update a Collider that is a polyline at runtime? I can't figure out how to add new points to the shape
I can maintain a separate Polyline and then do set_shape but then I'm copying the entire polyline all the time
Also, are there ways to detect if a collider collides with itself?
I think currently this is the only way, but it shouldn't be much different from the code that would allow modification
the heaviest part of polyline is probably building the bvh for it
at least, I believe avian still relies on parry? not sure if @vestal minnow changed that yet
bounding volume hierarchy: https://docs.rs/parry3d/latest/src/parry3d/shape/polyline.rs.html#28
can see how it's constructed here
making progress on my kinematic character controller. I fixed the jitter issue when walking into corners like the one in the beginning. I think the other two implementations that were posted here recently probably have that issue.
now I have to make the vertical axis movement work
So i need to have both the polyline and the collider at nce
yeah unfortunately
I wasn't really having any jitter on mine but I didn't test too much
have you tried a corner like that? I looked at your implementation and I'm pretty sure it will have that jitter issue
but is there a way to get back the concrete-shape from a SharedShape?
I'm currently trying to pare it down into something that is either a minimum demonstration, or a solution, but I'll report back regardless 🙂
ah, lemme test it, that was the corner I initially tested my collide and slide on and I didn't really notice much
do you have yours posted anywhere?
The one I posted here isn't really fully up to date with the one I'm currently using I believe
I also need to mess with mine so it stops going up slopes because I want it to stay at the same y level
There is, I'm not sure if there is a mutable version for it but it was TypedShape I believe
speaking of parry colliders I need to check if I can finally make them reflectable
Are there collision groups? I don't want my enemies falling through platforms when my player is.
are you talking about collision layers ? https://docs.rs/avian3d/0.1.1/avian3d/collision/struct.CollisionLayers.html
Defines the collision layers of a collider using memberships and filters.
👍
is there a joint that makes two colliders rotate at the same time
so that both of their "up"s are the same at all times
i thought revolute joint would, but it seems to just be keeping them at a fixed distance
each collider cn still rotate about its own centre
i needed fixed joint 
@vestal minnow it took me about 5 hours to implement ~15% of the happy path of the quickhull algo
https://github.com/Sorseg/trilobit
I estimate it will take me a month or two of the calendar time to do the whole thing (the happy path).
Do you think it makes sense for someone else to pick it up?
So about a month ago I tried making a fork of chull to simplify it and tailor things more for Glam/bevy_math, but I had some robustness and determinism issues so I left it for later. If you understand the general idea behind Quickhull now, one option would be to try to investigate that further and see if you're able to fix some of the issues, instead of implementing everything from scratch
video of it in action #math-dev message
I'll push my fork to GitHub at least
But you can definitely move onto something else too if you want, depending on what you're interested in
This is basically chull, but documented, has a ton more comments, reduced to not be dimension-agnostic, along with reworking some of the simplex initialization logic
The 2D case should be handled with its own separate implementation since it's much simpler, Geo has an implementation of it
This looks very readable! I'll try to figure out how to improve robustness. Probably investigate some fuzzing algos. Have you written down anywhere what kind of robustness issues did you have? float under/overflows?
Some issues with the current implementation:
- It consistently produces convex hulls with some concavity in my test scene, probably due to numerical robustness issues.
- Doesn't have face merging IIRC (not sure if it's necessarily needed and I think e.g. QuickHull doesn't have it, but Gregorius's slides have a lot on it)
- The results don't seem to be deterministic. Given the same input mesh, the result is different almost every time. Might be related to the
BTreeSets and indeterministic hashing, not sure. - Might not be very optimized, and at least the original
chullhad tons of unnecessary allocations. This isn't the most important issue to solve for the initial version though imo
What do you mean by "some concavity"? I am struggling with comprehension here. Gregorius's slides are talking about treating the walls as being 2 epsilons thick. I am assuming that if the hull is then used in a different algorithm that doesn't follow that convention, then it might look concave. If I understand correctly, the robust crate provides an algorithm for all parties to agree to which side of the plane the point is, consecutively if the shape is convex or not.
Nope, I misread the slides. The idea was that if the deviation is within two epsilons, then merge the edges
I just mean that after the core algorithm has run, there's this method that checks whether the convex hull is actually convex:
/// Checks if the convex hull is convex with the given tolerance.
fn is_convex(&self, tolerance: f64) -> bool {
for face in self.faces.values() {
if position_from_face(&self.points, face, 0) > tolerance {
return false;
}
}
true
}
And that often fails, meaning that the output of the algorithm isn't actually convex and there was some round-off error / some other issue
also some other warnings
Right. What is the value of tolerance in this case?
It's
fn tolerance(min: DVec3, max: DVec3) -> f64 {
3.0 * f64::EPSILON * max.abs().max(min.abs()).element_sum()
}
which is also in Gregorius's implementation IIRC
so it depends on the size of the hull extents
Gotcha! Thanks a ton for the explanation, I'll sum it up and see if I can figure it out
OK, it's looking like the problem was an over-eager system that tried to keep the model upright (it's for a motorcycle-style vehicle sim, and the PID parameters were likely too aggressive), causing oscillations that got exacerbated by the attached masses sliding up and down the prismatic free axis as a result. I'm still working on building up the minimized example, right now it's just a capsule collider on its side, I'm about to add the wheels to it.
what do people do for finding and deleting joints
Is there some sort of component that the entities that have joint have when the joint is created
Just trying to find it again
ya i dont really see any jitters, whatd you change to fix yours?
sorry got caught up with life last night
the fix is simple when you understand the source of the jitter. (excuse the poor drawing)
essentially, the ball can bounce back and forth because of the projected velocity
it could be not happening for your implementation because you have the number of bounces set so that it ends up on the same side everytime
oh i don't let it ever bounce back from the original direction
I use the original direction as the "reflection"
but essentially my fix was to break if the projected_velocity.dot(original_velocity) < 0
ya makes sense
ah, I didn't notice that in your implementation, did that change?
possibly ya, I forget when I posted the impl but that was a like super initial draft of it
I'd need to go check
I have the link on hand: <#1124043933886976171 message>
this is how it looks right now
ya it seems like it's there too actually
which part does that?
let slide_direction = original_direction.reject_from_normalized(hit_data.normal1);
yours might be better because its an early return so less processing
but this should do the same
oh interesting, I'll have to think about this because I project the last projected velocity onto the normal
I don't know if there's a difference
you aren't using the projection vector for the distance so I think they would have the same direction
unless there is a case where projecting original vs projecting "last projected" would give opposite direction vectors but I can't think of any
I'm not entirely sure if my alignment_scaling stuff is super necessary, but I did it because I was going to cancel out Y movement for my own game
I guess dotting the velocity would do the same though
actually yours might go further potentially?
here's my impl at the moment:
what even is the macos equivalent of paint
no clue, I don't use macos, does it even have a built-in paint program?
i dont think so rip
something else I kind of want to add is friction, so you stick to walls a bit more
downloading clipartstudio so i can explain this lol
wifi is shit, so I'll try to explain a bit while I wait:
so if you hit a wall your distance gets cut off a bit right, but you'd expect the same amount of cutting off for each steepness
if the last velocity is used I believe that if you've already bounced once and then hit another wall to slide off, then its no longer like the original velocity is hitting that wall, but the previous velocity
hmm
so i think based on that you lose less momentum because the angle of reflection with the wall is smaller
i guess a good way to test thing would be to put some really close walls that end up like a semi circle and then see how far it goes
it also probably doesn't matter that much because we are operating on such small timesteps
rarely going to have more than like 2 or 3 bounces
one other thing I've noticed, is that my collide & slide slips out of corners really really easily
which is probably because it overshoots the corners
ah, I was also thinking about this issue before
I guess if I added more segments/substeps to this that all return to original direction it would work better
Anyone have any idea what might be going on here?
https://learnbevy.com/playground?share=44fc096742f3de762c9fb32aeb7da4de72c3b7abd4a2a66c02584beb95abf36b
Trying to set up a simple one-wheel vehicle and it's going all wonky.
what kinda wonkiness? exploding?
It begins rotating in an unintended axis. I haven't intentionally added any forces or torques.
Also, the two parts of the joints seem to rotate 90 degrees relative to each other once physics is enabled.
one problem might be they aren't in the correct positions when spawned so the correction causes that rotation/movement
although @vestal minnow you added a setting or something for that right?
they are both at 0, 0, 0 and i haven't specified any local anchors
I didn't have time to add much joint stuff for Avian 0.1, so not yet
plus I'll likely rework joints a ton
to move away from XPBD completely and to make them work with simulation islands and stuff
line 62 specifies a rotation for the wheel
but not for the bike
if you add it to the bike too, it doesn't seem to rotate immediately
so this is a minification of a situation where the wheel needs to be rotated 90 degrees relative to the body of the vehicle
if you need the collider to be rotated, you could make it a child of the rigid body and only transform the child
btw, does locking rotation have any benefit for performance?
okay, I see there is some discussion in
https://github.com/Jondolf/avian/issues/254
which is remarkably similar to a discussion in
https://github.com/dimforge/bevy_rapier/issues/457
it does seem to, but they seem difficult to use, and even with the workaround mentioned there, I am seeing bizarre behavior
if you need the collider to be rotated, you could make it a child of the rigid body and only transform the child
Okay, this seems to be working
❤️
Uh, don't suppose you've got motors? 😅
Nope, unless you want to port this old branch to Avian and fix some stuff
https://github.com/Jondolf/avian/tree/joint-motors
I don't think so, at least currently
We could maybe optimize the case where all rotation axes are locked
you can throw that into the same bin as rethinking rigidbody
at least in 2d majority of (dynamic) objects are locked, so it's definitely worth trying
omg, same trick worked for rapier, thank you~
Is there a way I could have different compliances along different axes of a FixedJoint? I think I'm trying to hack it into behaving like a PrismaticJoint with a spring. Or should I write my own constraints instead
Is there a way to get the circle collider to bounce correctly off the wall? In the video, you can see that the angle of reflection decreases until it is bouncing straight across, I would like to have the effect of the ball bouncing at the same angle from the wall. Is there some property I am missing? I have Restitution set to 1.0 for all colliders, no gravity, etc
Have you removed friction?
that worked, thank you!
Sorry to come back to ask about determinism, but what would be the changes between avian and xpbd that would cause a change in determinism for collisions? aren't xpbd/avian basically the same?
Internally Avian and bevy_xpbd are very different, but I'm not sure what would've caused determinism changes. I'm getting deterministic results in my test case with the scheduling changes in this PR though
https://github.com/Jondolf/avian/pull/457
oh very cool
there's no specific reason why determinism should change with this PR though, if I was already using FixedUpdate
I'll try to contribute a simple example, just a ball colliding with a wall should be enough
It was using a custom implementation of a fixed schedule as opposed to Bevy's
yeah but the results should be the same; I was using fixed_once_hz inside of FixedUpdate
We just surpassed the other Avian 
how do I make a collider that doesn't have collisions and is just used for detecting like intersecting hitboxes
Sensors I suppose
A component that marks a Collider as a sensor, also known as a trigger.
and it won't collide?
Sensor colliders send collision events and register intersections, but allow other bodies to pass through them.
oh cool thanks
I don't suppose you can show it working? I'm trying to make a wheel out of a hub and tire (torus) connected with a revolute joint, and then I want to connect the hub to the bike with a fixed or prismatic joint acting as suspension, and I'm having a really rough time!
I'm using bevy_ecs_ldtk to load levels (tiles and entities). After adding a few levels I started to get spawn overlap warning from avian, apparently between entities from different levels. As mentioned crate spawns entities as children to level entities I guess it has to have something to do with separate position representations in bevy and avian. Any tips on how to deal with this?
This is the result of the discussion above: https://learnbevy.com/playground?share=1865f7994d2472e7ef70631d5958d87c3b0477d31b8fcf795241b4e855368b0f
I didn't go any further with avian.
What does expressed in the local space of the collider refer to in
https://docs.rs/avian2d/latest/avian2d/spatial_query/struct.ShapeHitData.html#structfield.point1 ?
I'm shapecasting from a moving ball to see whether it has hit a paddle that revolves around a central point (a parent transform is rotated, the paddle actually doesn't move at all). Based on the phrasing above I'd expect point1 to be in local space of the paddle, but the value seems quite of actually
Left: Vec2(-220.34152, -6.1954384)
Right: Vec2(216.51904, 14.457326)
This doesn't make sense to me, because the capsule/paddle is actually smaller
Collider::capsule(23.0, 130.0)
Data related to a hit during a shapecast.
have you figured this out?
i have wheels attached with revolute joints which work fine, but as soon as i try to add a prismatic joint to give the front wheel some suspension, the wheel stops spinning entirely
For shapecasting it is in worldspace I believe
i attached the joint to the wrong thing
, now the wheel is just not even pretending to be attached
thx, I actually tried using
https://docs.rs/bevy/0.14.0/bevy/transform/components/struct.GlobalTransform.html#method.transform_point
on that value before asking here and was getting weird results 😵💫
Guess I'll give it another shot
Describe the position of an entity relative to the reference frame.
i swear prismatic joint doesnt work at all
is it because of weirdness with compliance?
No, I can't get the tire to be rotated correctly 😦 (it's rotating around the diameter of the tire, not through the axel)
I'm about to just manually construct the mesh, which is what I was doing before when I was using rapier
deleted, user-error.
Yeah, I'm using a fixed joint and everything is extremely floppy. In the image below, the torii on the ground (which look green because they're colliding with the ground and the physics debug renderer is on) are spawned below the purple capsule, with the correct orientation, ie, like they're motorcycle wheels, but as soon as it all hits the ground, they just flop down and sideways:
and the code that spawns the colliders and joints: https://git.kittencollective.com/nebkor/avian3d-sandbox/src/commit/52f8c912321be801d77d7ac59426ea36a921c259/src/bike.rs#L106-L162
the default compliance is 0.0, which should be "infinitely stiff"
(also, I wish there were a way to cache things like he convex decomposition of a mesh into a collider, because it takes more than ten seconds to do that for each tire; I'll try using lazy static to do it only once, but that's still a long startup)
Collider currently stores a SharedShape which internally is an Arc<dyn Shape>, so you should be able to create it once somewhere and cheaply clone it for all the tires
oh nice!
I agree though, and I'd like to experiment with "colliders as assets" and handle convex decomposition in an asset preprocessing step, not at runtime
iirc there are still some blockers for that though
Hard to say from a quick look, but I can maybe try to run it to see what's happening better
that's extremely generous 🙂 you can check out the code at https://git.kittencollective.com/nebkor/avian3d-sandbox.git
@vestal minnow is there a reason for changing to FixedUpdate rather than FixedPostUpdate?
I'm just worried because now a whole lot of gameplay systems will need to be specifically ordered against the physics sets
and if you don't you'll have frame delays randomly
No, we discussed this a few days ago, and we (or at least me and Nise I think) came to the conclusion that it probably should be changed to FixedPostUpdate #1124043933886976171 message
I just haven't updated the PR yet
I think this might be a mass ratio issue, i.e. the mass of the "front hub" is too small relative to the front tire so it doesn't affect the tire as strongly
I think this is actually kinda similar to this situation ^
(copied image here)
Ground is the bike's body, small ball is the small front hub, and large ball on top is the tire
(not the same ofc, but maybe somewhat similar)
Can be improved by making the masses of the bodies closer to each other, and/or by increasing the SubstepCount
ooh! OK, that's good to hear!
also, I made the classic rookie mistake of not having my dev profile set external deps to opt-level = 3; fixing that makes the startup basically instantaneous 🙂
OK, making the hub and tires more dense definitely helped
oh and FYI if you don't need the hole in the tires, you could use Collider::convex_hull_from_mesh, which should be much faster than convex decomposition
ooh! Yeah, I just need something with a round edge, otherwise I'd have used a cylinder
this is very exciting to have this working 🙂
doubling the substep count to 12 also greatly improves the joint performance
(ultimately I'll only have four interacting colliders so I think I have the compute budget to keep that up)
OK, convex_hull_from_mesh + lightening the capsule body collider + CollisionMargin(0.05) on the wheel colliders seems to do the trick adequately. My main motivation for trying Avian out was that I could not get the wheel colliders to not penetrate the ground mesh (which was a displaced trimesh) with Rapier, and I'm feeling pretty confident now that this was the right move 🙂
question: what are the mass units? Like, with the default density, that purple capsule's collider has a mass of less than "2". I was assuming that the length units were meters, and if that volume had a density of 1 gram/cc, its mass would be hundreds of kilos
Updated the PR 
There's not really a specific unit, although I recommend SI units and MKS (meters, kilograms, seconds). See #1260519770395250769 message
But yeah assuming SI units the mass would be in kilograms and density kg/m^3
ooooh! 1 kg/m^3 is much lower than 1 g/cm^3 🙂
the SI units are grams/cc
so idunno if you want to make the default density 1000
1 kg/m^3 = 0,001 g/cm^3
that article claims it's kg/dm^3, which is 1gram/cm^3
🙂 I concede!
I'm running into an issue where if I despawn an entity I'm colliding with (a coin), it doesn't get removed from my ground sensor's CollidingEntities
meaning I can just infinitely jump (and maybe a memory leak?)
damn, the docs for that GlobalTransform fn are wrong too. I hit a double incorrect rust docs rainbow 😅
what was wrong about the GlobalTransform docs?
Setting a high Friction value seems to make structures quite unstable. At 1.0 the 3d cubes example shakes slightly and eventually collapses. At 1.5 the cubes shuffle around randomly, and at 2.0 the whole structure instantly explodes. Any tips achieving high friction? Should I just be using damping for that?
will it ever be possible to use avian without bevy
no, why would u want to do that in the first place
just write ur own physics solver
or use rapier ig
I wouldn't say that it will never be possible, but I don't have plans to prioritize it any time soon, and I would still generally put Bevy's needs first
i mean u could replace bevy types with ur own and make ur own scheduling and so on
but like at that point why not just use bevy
It would use Bevy's math types, but things like the broad phase, narrow phase, and parts of the solver could potentially be abstracted in a way where you could have different kinds of backends for the data, like Bevy's ECS or Rapier-style generational arenas. For the scheduling, you could just call the same methods from ECS systems or Rapier's physics pipelines. A lot of the core physics logic doesn't really care that it's in an ECS and could probably be abstracted in some way.
Not saying we should try to achieve this necessarily, but it would be interesting to experiment with the idea
And ofc I don't know how feasible it'd be in practice
Yea thats essentially what i had in mind. It would be a huge undertaking tho and im still not really sure what kind of benefit this would have anyways
Would prob be counterproductive too since u need to convert things constantly
ive ripped out the broad and part of the narrow phase from xpbd before its probably doable, but pretty much pointless
I mean that's basically like saying Rapier is pointless, it would be useful if Avian could be beneficial for the Rust ecosystem as a whole, not just Bevy
i implemented parts of my game in different crate for organization
where essentially i have box2d and mlua, and i can call a step function to step box2d world and call lua scripts on things in the world
i then integrate this crate into a bevy client, and the crate can then also be used without bevy
i want to eventually make a 3D version of this, and ofc box2d is just for 2D, so i was interested in using avian since iirc the solvers are similar and so it could feel similar to the box2d version for users
the main thing is whether we can do that without hurting the Bevy integration or overall maintainability
and if not, it's probably not worth it
yea but we already have rapier, so why not have a native bevy physics engine uk
More options for the Rust ecosystem, especially the Glam side, and possibly slightly different priorities and feature sets
it's better to focus on just 1 thing and do it really really well though
yeah
I'm looking to move my physics sim systems to FixedUpdate, but I was thinking I'd leave the system that sets the gravity vector in Update since no forces are computed or applied (my thing is on the surface of a sphere, so gravity points from current translation to the origin); should I also put that gravity-vector-updating system into FixedUpdate?
For determinism, I think you might still want to put it in FixedUpdate. On some frames, FixedUpdate could run multiple times if the frame took long enough. If you updated gravity in Update, the direction would only be correct on the first FixedUpdate run, and wrong for the rest
sweet, thank you!
When adding a LinearVelocity to an entity, is the movement direction solely determined by the LinearVelocity Vec3, or it's also impacted by the entity's transform rotation?
that kinda depends how you're adding it but yeah it's disconnected
Is there an easy way to toggle the Debug rendering at run-time?
#1124043933886976171 message
Thank you! I swear I searched first and the only one I found was from February and I couldn't find the thing the answer to it suggested
Is this normal, how do I fix this? The box is a child of the player (that has a kinematic character controller)
A more exact question is, what is the right way to implement picking up an item that has a rigid body. Currently, I remove the rigid body from it and parent it to the player (that has the controller) and then when the item is dropped I unparent it and add back the rigid body component but it just falls through the floor 😱, when I don't set the velocity to 0 before parenting to the "hand", after adding back the rigid body it dances and flies off into the distance. Any guidance would be appreciated.
use a spring joint or something like that
and staying away from parenting is always a good idea, it tends to break stuff when used incorrectly
I used to use Unity before bevy and there I am used to this way, thanks I will try!
Even after joining the cube (dynamic rigid body with a collider) to the camera (which only has a kinematic rigid body on it and is moved, and rotated using the transform), I have the same type of lag. Is it a problem with the camera or physics? Which type of joint am I supposed to be using, I am using fixed? Am I supposed to rotate the camera in some specific schedule? Also if I want the player to collide with using the collider of the thing that is picked up should I copy the collider of the box and add it as a child to the player?
Hey @vestal minnowI have a question about Avian, I'm a part of a team that is in the process of developing a voxel game and we encountered a problem or maybe a design decision that we aren't clear about and would love to hear your input. What is the intended mechanism for adding custom collider types? If it's on the parry level we need to do dispatch chaining so that we can handle collisions between custom parry shapes and the builtin ones or if it's at the Avian level how would that work? is the intended way to wrap everything in a delegate enum?
To be more practical and precise this conversation started in the team after we saw that the contact_manifolds function uses the DefaultQueryDispatcher and we can't change it
https://github.com/Jondolf/avian/blob/fb9912965bba96700d95a4d8ea6dd1f010181492/src/collision/contact_query.rs#L166
Also this crate is amazing, saves us so much time and effort, thank you for continuing to maintain it!
parenting is a bad idea in unity too though
and i'm not entirely sure what you mean there, but yeah stay away from parenting, the only good time to do it is when both child and parent are supposed to be the same thing
btw I also created a help post for my issue https://discord.com/channels/691052431525675048/1266433125332816033
I meant using a fixed joint
the way i did it in unity was to use an empty object, setting it to position of object i'm picking and saving the offset, and recalculating it in fixed update (iirc)
i could try to make it in bevy i guess but PoE league in 3 hrs
using joint was really nice though, it automatically breaks if you're not matching the weight
what do you mean by matching the weight?
if object is heavy and you try to look/walk away from it too fast, the joint breaks (if you set the break force)
I'm seeing this too, where my wheeled vehicle's wheels are just slipping like crazy, but if I set the friction values such that the average is greater than 1.0, it's unstable
is there something new I have to do to fix camera jitters in avian, putting the systems in postupdate before and after doesn't fix it anymore
nvm setting the Physics time to once fixed 64 hz fixed it did not fix it I am going insane
if I have a RevoluteJoint that has a Some(AngleLimit), do I need to call .apply_angular_correction() on it in order to enforce the limit?
Avian Physics
I did this already and it had 0 effect
setting the physics frequency to 64 mitigated it but it's still there
oh, I have no idea....
what about running the camera system in FixedPostUpdate?
(if your physics systems are running in FixedUpdate)
Your camera should be tied to frames, not physics updates, otherwise camera movement won't feel smooth at all
they aren't
and yeah it just made the jitter worse
after setting the physics tickrate the jitter is almost unnoticeable at low speeds but comes back the faster you go
so it wasn't really a fix
It's surprising how many games are even released with this issue tbh
The standard solution is to interpolate objects from their last position to their next one.
It would be super neat if there was a crate that just did that tbh since lots of games will need it, one of the networking crates can do it but I don't think as a general solution
I have physics interpolation (or optionally extrapolation) basically ready on a local branch, it'll most likely be in Avian 0.2
Where's the fix for the compilation errors without parry tho? 
How does Trigger<OnInsert, (Component1, Component2)> work?
does it only trigger when both are inserted?
afaik it's when either of them are inserted, or both
After the jam I guess :p I've been busy trying to do jam stuff but then procrastinating by working on Peck
Well at the very least I'll probably be distracted for like a week starting in ~45 minutes
I want to make the repo public very soon
At the very least if you only have physics updating at the physics rate, and the camera moves every frame it can look fairly smooth as long as things move slowly. But yes it is absolutely wild how many games ship with such awful stuff, tho it's pretty obvious the fault here lies with game engines generally not providing any tooling to do this, which in turn makes very few people aware of it so even custom engines rarely get this right
well you have plenty of games having fixed time physics in just normal frames
I remember seeing an issue about an alternative approach which would be somewhat similar to physics substepping, but applied to the entire simulation, and trying to schedule those somewhat dynamically (picking a length based on the FPS you're getting)
That can get you pretty close without any interpolation/extrapolation at all, but now you have the problem that your simulation delta time can vary, and there's plenty of ways to make your simulation dependant on it
The impact is minimized by working with smaller delta ranges (like say min 3ms, max 4ms) instead of 16ms vs a huge 382ms spike when you get some lag. But do a few delta-based lerps and 3ms vs 4ms will already look substanially different
oo, neat
do games really? I've never seen this until I started using bevy
I do think an (ecosystem or core) crate to do interpolation would be very neat though, because basically every thing that runs in a fixed timestep or touches positions needs to know about it
along with some custom for telling plugins what component the transform you want it to use is stored in
otherwise you just end up with half a dozen plugins doing their own conflicting interpolation
but that's getting off topic now
I might be able to make the interpolation logic into its own crate that could function independently of physics, not sure yet. I'll need to try it out
Transform extrapolation needs velocity though (unless you derive it from the current and previous position, which has some issues), so it generally requires physics integration. But extrapolation is rarer anyways
