#Avian Physics

1 messages Β· Page 36 of 1

balmy delta
#

fwiw I think there are many interested in this specific rabbit hole (AVBD), I at least am following your updates with very great interest so don't consider it wasted πŸ™

#

It's too bad the code they used for benchmarking wasn't published

rocky seal
#

i bet it is because of interpolation

#

see this convo

visual sparrow
#

@vestal minnow there's no Avian API to convert a collider into a trimesh, right? I have to go through the parry shape, I believe

#

Would you be up for a PR that added rasterization to colliders?

#

its implemented for these shapes

#

And I've already implemented it once for compound shapes by unpacking them first

vestal minnow
#

Or a Parry TriMesh

visual sparrow
#

Or similar

#

whether that data is in a TriMesh, Collider or whatnot doesn't matter

#

Which is what that parry method gives me:

fn to_trimesh(&self) -> (Vec<Point<f32>>, Vec<[u32; 3]>)
visual sparrow
vestal minnow
visual sparrow
#

For context, I need this because the navmesh algorithm I'm porting expects regular old meshes

vestal minnow
visual sparrow
#

Maybe ColliderMesh?

#

or RasterizedCollider

#

or something like that

visual sparrow
#

Maybe fn rasterize?

vestal minnow
#

I think for now just the tuple unless we intend to add other functionality to it, I would probably expect Collider::trimesh and Collider::to_trimesh to have the same input/output

visual sparrow
#

alright, can do tuple

visual sparrow
#

@vestal minnow update: some trimesh conversions need a number of subdivisions, and some shapes cannot be rasterized

#
fn to_trimesh(&self, subdivisions: u32) -> Option<(Vec<Vector>, Vec<[u32; 3]>)> 
#

I think the return value now looks quite confusing as a tuple inside an option

vestal minnow
#

yeah all the rounded shapes need subdivisions

#

and something like a half-space definitely doesn't really have a mesh representation :P

visual sparrow
#

yeah same for e.g. polyline

vestal minnow
#

rounded polygons/polyhedrons probably don't have mesh conversions implemented either since that seems tricky

#

and custom shapes are a problem

visual sparrow
#

What's up with this?

    #[cfg(feature = "dim3")]
    #[cfg(feature = "alloc")]
    /// A convex polyhedron.
    ConvexPolyhedron(&'a ConvexPolyhedron),

When do we activate "alloc" on parry?

vestal minnow
#

It's a default feature

visual sparrow
vestal minnow
#

Or it's not necessarily a default feature, but spade is, and that also enables alloc

visual sparrow
#

@vestal minnow I just checked what oxidized_navigation does, and it takes the inner shape for the rounded colliders

#

thoughts on that?

#

It's definitely not quite correct

#

but also maybe better than nothing?

visual sparrow
# visual sparrow

Also, cargo check -p avian3d also tells me that ConvexPolygon is not enabled by default

#

And I'm not sure which Avian feature enables it hmm

vestal minnow
#

polygons are 2D shapes

#

polyhedra are 3D

visual sparrow
#

OOOOOO

#

That makes sense

vestal minnow
#

(and "polytope" is the n-dimensional term)

visual sparrow
visual sparrow
vestal minnow
#

I vaguely recall Parry also using just the inner shape for something that didn't support the rounded version but I can't find it

#

I'm not sure here, for small rounding that'd probably be fine but if you have a large border radius then you just have a totally different shape

#

I imagine for a navmesh it'd still be fine but more generally ehhh

visual sparrow
#

If we think about navmeshes, I would definitely prefer the too-big mesh over nothing

visual sparrow
#

But your call

#

I don't use rounded colliders anyways lol

vestal minnow
# visual sparrow Agreed it's a bit iffy, but I think it's fine considering we have no API at all ...

Mm I'm increasingly not sure if we really we want this API on Collider since

  • It doesn't (and can't) support all shapes
  • You need to provide a subdivision count that only applies to some shapes (and you might want different subdivisions depending on the shape anyway)
  • Rounded colliders would need to use the inner shape, producing inaccurate meshes
    If the primary motivation is to produce navmeshes, then maybe it'd just be better to have it in the navmesh library instead of trying to make a general API, though it is annoying :/
visual sparrow
cerulean zephyr
#

@vestal minnow just bumping an older message, if I clone an entity with rigid body, which components do i need to clone (right now i clone w/e i use to spawn) and which component s do i need to modify to translate the clone? (global transform gets reset by some physics system)

#

my best guess is some Sync logic is resetting my cloned, updated global transform

vestal minnow
#

I'm not sure how entity cloning works πŸ€” does it not consider required components or run hooks?

cerulean zephyr
#

i think the components i don't copy are inserted through required components

#

because things like Position Velocity, etc. exist on the clone

#

and hooks only get custom behavior for relationships

vestal minnow
#

If you use the same as what you spawned the entity with, and use some initial transform, I don't see why it wouldn't work

#

Specifically set the Transform or Position/Rotation, not GlobalTransform

#

GlobalTransform is generally kinda read-only in Bevy since it's driven by Transform

cerulean zephyr
#

i froze the physics using the plugin you have in your examples, then created a clone, this is how the components look like

#

if i run the system in PostUpdate the position is correct for 1 frame (sprite flashes), but then it jumps to 0, 0 even with physics frozen

#

and previous global transform is still 0, 0 even with that

vestal minnow
#

A minimal reproduction of the behavior could be useful

cerulean zephyr
#

i can try

cerulean zephyr
#

@vestal minnow

vestal minnow
#

Thanks!

#

@cerulean zephyr setting Position and Rotation seems to work here, but yeah I'd probably count this as a bug

cerulean zephyr
#

alright

#

thanks :)

vestal minnow
#

oh lol I think I fixed it

#

I'll test a bit more and open a PR

cerulean zephyr
#

cloning may be a neat example, mind if i PR it to avian2d?

#

after the fix

vestal minnow
#

Hmm I'm not sure if it's really related to physics, it feels like something that'd rather be a Bevy example

cerulean zephyr
#

fair, there is just some special treatment needed because of avian

#

like filtering what you clone, certain components crash the app xD

vestal minnow
#

I imagine some stuff with entity references (like ColliderOf nvm that should be fine) or internal indices might be something you don't want to clone

#

or it depends I guess

vestal minnow
cerulean zephyr
#

joints aren't relationships so cloning them doesn't actually work on the clone 🫠

cerulean zephyr
#

odd behavior, revolute joint is trying to simulate collision between parts, but those parts are set to not collider (you can see them intersect on the bottom)

#

@vestal minnow i feel like this is intended to some degree

#

i think it's pretty clear between those 2 frames, static bodies in the first one, split seconds of bodies being dynamic on the second one

vestal minnow
#

Could try it without the joint first to minimize factors and make sure they don't collide like that

#

Joints are completely separate from any collision stuff so that shouldn't have any impact

cerulean zephyr
cerulean zephyr
cerulean zephyr
vestal minnow
#

No

#

Can you check if there's really a collision? With collision events or CollidingEntities or Collisions or w/e

cerulean zephyr
#

Sure, I can do that when Im back at the PC, will you still be up in ~1-1.5h?

vestal minnow
#

I probably will be, I really want to get my AVBD impl working properly lol

#

it's so clooose

shy blaze
#

is there still a character controller working group discord

knotty thicket
spare lily
#

Is there a right way to insert Friction? just adding Friction component for some reason screams that Friction does not implement Bundle

visual sparrow
visual sparrow
cinder summit
#

Or bevy version mismatches

visual sparrow
#

Right, that will also give you the same issues

#

run cargo tree -i bevy and cargo tree -i avian3d

spare lily
visual sparrow
#

tuples of bundles are themselves a single bundle πŸ™‚

visual sparrow
#

But because tuples of bundles are a bundle, in practice, a bundle can be infinitely long πŸ™‚

spare lily
#

Thanks!

supple lily
#

Hi, I am currently making space-sim (very very very early) and for now I am planning on doing ships and their interiors. Ships shouldn't collide with each other, interiors of ships shouldn't collide with each other, characters and objects in interior should collide with each other.

I have encountered 2 issues:

  1. Collide layers are restricted to just 32 . So I am not sure how I would go about each interior having it's own layer. Maybe don't have any layers for now and then use collision hooks to prevent collisions between interiors ? How would you go about it ?
  2. I would like to have interiors as children of ships but this causes issues with walls, which are static, and ships, which are dynamic (Dynamic bodies too). Moving the ship with forces causes the static bodies to remain in place. Do I have to manually move the bodies or is there a better way ?
visual sparrow
visual sparrow
supple lily
visual sparrow
vestal minnow
#

Got AVBD working btw πŸ‘€ #math-and-physics message

#

There's a lot to do though before I have fancy 3D demos to show for it

#

it'd be so cool to replicate their demos of the balls twisting around the ropes and the ball dropping into a chain mail net

#

maybe with Jasmine's work on solari we'll soon have real-time ray tracing too to get the fancy physics demo look right πŸ˜›

runic tinsel
#

What does AVBD stand for? Google keeps correcting me, and refuses to spit out a useful answer lol.

vestal minnow
#

I kinda summarized some of the differences to XPBD here #math-and-physics message

#

We still currently use XPBD for joints, but an impulse-based solver for contacts

#

AVBD is again very different from both :P basically requires rewriting the solver from scratch

supple lily
vestal minnow
#

for indented lists you use two spaces (or I do at least)

- Item 1
  - Sub-item 1
  - Sub-item 2
- Item 2
  - Sub-item 1
  - Sub-item 2
supple lily
#
  • entity
    • dynamic body
    • ship
    • entity
      • static body
      • collider
      • wall

like this ?

vestal minnow
#

using 4 messes up formatting, I've done that a lot when copy-pasting from elsewhere where I use 4 lol

supple lily
#

thanks

visual sparrow
#

Just remove that static body

sweet sundial
#

is it possible to model artificial gravity as two forces such that standing inside a spaceship doesn't accelerate it downwards

supple lily
sweet sundial
#

how's the player controlled

supple lily
sweet sundial
#

need to apply opposite forces to the ship then

#

(i got around this by practically only applying external torque)

#

though if you're okay with it you could just give the ship higher priority

supple lily
silk mauve
#

https://www.youtube.com/watch?v=bwJgifqvd5M when is augmented vertex block descent coming to avian

Chris Giles, Elie Diaz, Cem Yuksel
Augmented Vertex Block Descent
ACM Transactions on Graphics (SIGGRAPH 2025), 44, 4, 2025.

Project Page: https://graphics.cs.utah.edu/research/projects/avbd/
(including a 2D online demo and source code)

Vertex Block Descent is a fast physics-based simulation method that is unconditionally stable, highly parall...

β–Ά Play video
#

1 week? 2?

vestal minnow
#

go through #math-and-physics for my progress on AVBD, starting from #math-and-physics message

#

right now I'm trying to get a very πŸ§ͺ hybrid solver working that combines our existing solver for contacts and AVBD for joints

#

since so far, our contact solver still seems to be more well-behaved than the AVBD version I implemented (might be a skill issue tho), but I suspect AVBD will be much better for joints

silk mauve
#

wtf I was kidding. That's sick though

vestal minnow
#

(I'm moving the box with fixed rotation)

#

it's probably some error in the Hessian...

#

holy shit it works maybe, hold on

#

it just broke gravity lol

cerulean zephyr
#

honestly

#

close to my average experience XD

#

(jk)

visual sparrow
slim ledge
#

For a turn-based game that needs physics, how can I simulate exactly 1 second of physics as fast as possible (ideally within a system)?

sweet sundial
#

#general message and others

#

maybe exclusive system with a loop of incrementing the physics timer and running the physics schedule, but iirc someone listed a more comprehensive method

#

ah here

calm sundial
#
bobajeff

We present a novel contact model, termed Offset Geometric Contact (OGC), for guaranteed penetration-free simulation of codimensional objects with minimal computational overhead. Our method is based on constructing a volumetric shape by offsetting each face along its normal direction, ensuring orthogonal contact forces, thus allows large contact ...

β–Ά Play video
Dropbox

Shared with Dropbox

vestal minnow
#

My πŸ§ͺ experiments appear to be (almost) working properly πŸ‘€
This is using an AVBD point-to-point constraint for the grabbing, while using our existing TGS Soft solver for contacts

#

A special thing here is that unlike our current TGS Soft + XPBD hybrid solver, this AVBD implementation is collision-aware; this means that AVBD runs first and only produces a "prediction velocity" that the TGS Soft solver will then apply over several substeps, but contacts can apply impulses to the velocity before the body is actually moved.

#

In practice this means that joints won't overpower contacts nearly as easily as with our XPBD hybrid approach.

#

Here you can see how our current XPBD approach lets the joint pull objects through walls with barely any resistance, which generally isn't desirable:

vestal minnow
#

I did also try to embed AVBD into the substepping loop somehow, but didn't have great success with that approach

visual sparrow
visual sparrow
# vestal minnow My πŸ§ͺ experiments appear to be (almost) working properly πŸ‘€ This is using an AVB...

Looking at this, I can't help but wonder if I'm underutilizing constraints. I briefly used them to model a lid on a container, but then never touched them again. My pickup stuff is done with velocities, for better or worse, to mirror the HL2 implementation.
Outside of things like chains and other kinds of strings, are there some good everyday gamedev examples of things that one should use constraints for? Ragdolls come to mind.

cerulean zephyr
#

Simulation games use those more

visual sparrow
cerulean zephyr
#

Car suspension

visual sparrow
cerulean zephyr
#

Personally im a fan of physic sims in sandbox games, so everything cool there is joint based

cerulean zephyr
visual sparrow
vestal minnow
cerulean zephyr
#

Thats a very old example but yes

vestal minnow
#

also I need to fix the static attachment being so weak

visual sparrow
cerulean zephyr
#

Take stuff like algodoo, scrap mechanic, main assembly

visual sparrow
visual sparrow
cerulean zephyr
#

Algodoo has been around for half my life xD

#

Prolly more

#

It's pretty old

vestal minnow
visual sparrow
visual sparrow
vestal minnow
#

little big planet

#

my childhood

visual sparrow
#

πŸ˜„

vestal minnow
#

probably why I got interested in physics simulations lol

visual sparrow
#

Like, can you define your own?

#

Or does the level just have interesting ones?

vestal minnow
visual sparrow
#

Oooh I see. So a bit like the physgun in GMod?

vestal minnow
#

no idea what that is

#

but you can joint objects together when creating levels, and set their properties like the strength and motorization etc.

#

and you can create logic circuits to activate motors and stuff

cerulean zephyr
#

Something like spider legs also use joints, but im pretty sure that's a whole different set of solutions

vestal minnow
#

when stepping on a button or pulling a lever for example

visual sparrow
#

Alright, that's a bit more advanced than GMod πŸ˜„

#

Cool, thanks for giving me some insight into what constraints are used for πŸ™‚

vestal minnow
#

You can also make simple cloth and soft bodies, especially if a basic mass-spring-damper model is enough

visual sparrow
vestal minnow
#

yeah, just some squares or circles with distance constraints (and bending constraints if needed)

#

you can also have volume constraints, though we don't properly support it atm

#

either a global volume constraint (computes the volume of e.g. a whole trimesh and tries to maintain that volume) or for better results you can tetrahedralize the object and have tetrahedral volume constraints

#

I did a global volume constraint for that one XPBD demo ages ago

visual sparrow
vestal minnow
#

yeah like this #showcase message

bold garnet
vestal minnow
#

I'm now at the point of debugging this that I forked AVBD's web demo to be exactly the same as my scene visually, replicated the exact scene and setup in both, and am running them side-by-side to compare

#

Like my version is so close overall, but why the heck does it have inconsistent gaps in the chain and sometimes some parts of the chain are kinda dislodged to the side, while their version has a perfectly uniform chain

#

And these gaps are also at weirdly consistent distances from each other at specific spots

vestal minnow
#

i've triple-checked the math for the Hessians and everything

vestal minnow
#

it's always every sixth chain segment even with longer chains, like whyyyy???

cerulean zephyr
#

It seems more like every 6th one is actually correct

#

Could it be an issue with rendering/ interpolation?

#

Like, pure graphical

#

It's too stable for this to be error adding up then cancelling out perfectly

#

That just doesnt happwn

visual sparrow
#

@vestal minnow what happens when you setup something notoriously chaotic like a double or tripple pendulum in both?

visual sparrow
vestal minnow
#

wait what the hell it's based on the number of iterations

#

6 iterations = every 6 segments
3 iterations = every 3 segments
etc.

#

wtf

drifting marsh
#

oh funny I was going to suggest that but I thought it was probably wrong

visual sparrow
vestal minnow
#

it's probably something wrong with how I manage position updates and how it carries over to the next iteration, but I've been looking for an error like that for the past four hours and have not found it

#

I use position deltas instead of actual global positions which does make the logic slightly harder to follow

#

I guess for now I could copy the reference impl exactly and use global positions directly but ehhh it's annoying to change and I won't do that for the final impl anyway

lyric sorrel
#

Sounds almost like some sort of perturbation that's seeded by an impulse at one end each step start/end and propagates up the chain at a rate of 1 link/substep, if you're able to change the substep count at runtime it'd be interesting to see if the period of the error changes along the whole chain instantaneously or propagates one step further with each simulation step

vestal minnow
#

It seems like it's a bug in how I limit the position correction for hard constraints (sec. 3.6) since using a finite stiffness fixes it

#

However I'm not sure where exactly the error is because I'm pretty sure I'm doing it just like the reference impl πŸ€”

little maple
#

maybe your code is correct and this is actually how reality works πŸ€”

hexed veldt
#

Encountered an error like this, what might cause this issue?

thread 'main' panicked at .../.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/avian3d-0.3.1/src/collision/contact_types/contact_graph.rs:401:18:
swapped entity has no entity-to-node mapping
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic when applying buffers for system `bevy_state::state_scoped::clear_state_scoped_entities<game::state::GameState>`!
Encountered a panic in system `bevy_ecs::apply_deferred`!

I'm using Scoped entities and when the game is finished, all entities will be automatically despawned.

timid berry
vestal minnow
#

I also have scenes where I despawn all physics entities, and in Chainboom (our jam game) we also use state scoped entities, and those don't panic

#

so a minimal reproduction could be useful there

slim ledge
#

What are best practices for fast moving and numerous bullets? Is this entirely solved by Swept CCD? Are there examples somewhere?

little maple
vestal minnow
vestal minnow
#

Oh there is actually a clear_scene system too to despawn enemies and decals when you enter the loading screen

vestal minnow
#

oh hell nah

#

naaah

#

so the chain bug is because the query iterates over entities in ascending Entity order, while the reference impl has a linked list that has the exact opposite iteration order

#

if I collect the query into a vec and .reverse() it, it works fine and is like the reference impl

#

so it is quite iteration order-dependent

visual sparrow
#

Heck

bold garnet
#

can't nock it if it works, ig?

vestal minnow
#

for the best behavior we would probably shuffle the iteration order

bold garnet
#

aren't most IK solvers pretty order dependant as well? seems like that would be hard to get rid of with a long chain.

vestal minnow
#

all Gauss-Seidel solvers (like our existing one) are order dependent, I just haven't seen it manifest quite like this :P

#

I think it should be better once I do graph coloring

#

also the paper does say

We have observed that in some difficult cases, such as those involving a series of connections
with high stiffness ratios, randomizing the order with which the
colors are processed can improve convergence. However, we do not
randomize the order for any results presented in this paper.

#

I'm pretty sure graph coloring by itself will also inherently change the order to not be purely the spawn order, which should help even without shuffling the colors

hexed veldt
timber terrace
#

I'm trying to setup a basic collider for a character, i have an issue where the mesh gets a vertical offset when i add a capsule collider, which doesn't happen without. What am i doing wrong ?

#

do i have to make one the child of the other or should this work this way ?

vestal minnow
vestal minnow
#

You can either center the mesh (if it is offset like it looks) or use a child entity to offset the collider or mesh to the correct position

timber terrace
#

i see, i'll offset the collider in a child entity then, the mesh origin is indeed at 0,0,0

#

thanks

visual sparrow
visual sparrow
vestal minnow
vestal minnow
#

iter_many and iter_mut

#

par_iter_many and par_iter_mut

#

yeah that seems right thonk

visual sparrow
vestal minnow
#

Yeah that case wasn't really too representative of an actual scene, since it was a lot of iterations with not so many bodies, so the multi-threading was just adding a ton of overhead for little benefit

#

(interesting that the overhead is that bad tho)

#

In a more "realistic" scenario with just 6 iterations but 50k bodies, it's a lot better

#

Single-threaded

#

Multi-threaded

#

so like, nearly a 5x improvement from parallelism there

#

this is just a very long 2D chain tho

bold garnet
vestal minnow
# bold garnet I would be interested in knowing what is causing that overhead.

Well it's basically just doing this

for _ 0..num_iterations {
    // Primal update
    for color in colors {
        body_query.par_iter_many(&color.bodies).for_each(...);
    }

    // Dual update
    constraint_query.par_iter_mut().for_each(...);
}

In that case num_iterations was 100, and there were only like 100-200 bodies and constraints, so I assume the overhead was just from spinning up small parallel tasks 100 times in a row?

vestal minnow
vestal minnow
#

it would be interesting to try the same with forte though once I can properly use it for this sort of thing

bold garnet
eager meadow
#

I'm working on a top-down 2d game, so gravity isn't a problem. I just want to use colliders to prevent the player from moving the character through the level (walls, etc). Is there a good example of how to use colliderst effectively for that purpose?

maiden epoch
cinder summit
#

@thorn solstice would it be possible to have OBVHS avoid building trees with a depth great enough for it to panic in the validation? I've been running into that particular crash quite often in the spatial query code

thorn solstice
#

I guess another thought it to put an option for it to automatically set the max stack depth in BvhBuildParams, and/or maybe we can estimate it better during building without additional cost.

cinder summit
#

But yea it's definitely strange that it happens, if I shrink the scene it stops happening however πŸ€”

cerulean zephyr
#

this got recommended to me, unprompted, I haven't watched anything physics related in a while πŸ˜…

vestal minnow
#

taking a break from AVBD to try and finish up the force rework and BVH stuff... just finished writing 700 lines of nothing but component type definitions and docs

#

not even done with docs or clean-up yet ferris_sob

#

this will be a rather large PR

summer acorn
#

if i want to generate contact pairs between colliders and a custom collider, what system set do i run in? i presume the narrowphase runs on every substep?

vestal minnow
#

but the narrow phase updates are done in NarrowPhaseSet::Update in the PhysicsSchedule, not on every substep, that would be wayy too expensive

#

you can do collisions between custom colliders easily by just implementing AnyCollider (and ScalableCollider iirc?) for your collider type and adding the relevant plugins with that collider passed as a generic, but collisions between different types of colliders is non-trivial and not supported very well

#

You can also implement custom shapes for the existing Collider, but I think that's currently limited to just single contact points computed via support mapping and GJK+EPA

summer acorn
#

id like to swap out the collision detection backend lmao

#

thanks for the info, i'll see what i can do later today

vestal minnow
#

I still need to test it more to make sure all the APIs actually work correctly, and fix how kinematic bodies are handled

#

Feedback on the general API would be appreciated though πŸ™‚

#

Also I'm not sure what the best name would be for the ForceHelper system param... I also considered RigidBodyForces and PhysicsForces or even just Forces as potential names

thorn solstice
summer acorn
#

@cinder summit how did you approach sdf physics with avian? did you do that at all or nah

cinder summit
#

I implemented AnyCollider, ScalableCollider, and the QueryCollider I'm working on

foggy storm
#

Is it overkill to use Avian if I only want sensors?

sweet sundial
#

not if you cherrypick the plugins

cinder summit
foggy storm
visual sparrow
#

you don't really pay for anything you don't use

#

and the setup is not any more or less complicated either way

#

So I wouldn't bother cherrypicking

thorn solstice
cinder summit
#

Might want to add that to the assert 🀣

thorn solstice
#

lol good point

foggy storm
thorn solstice
#

wonder if they are maybe equal or something

cinder summit
#

result.max_depth (187) must be less than self.max_depth (187)
bavy

sweet sundial
#

<=

summer acorn
#

187 node deep bvh??? what the fuck

cinder summit
summer acorn
#

thats a fuckin useless bvh if its 187 nodes deep

cinder summit
#

Definitely, but it shouldn't crash the whole app the second this happens

thorn solstice
thorn solstice
#

The most common reason for this kind of thing is having a bunch of identical or almost identical geometry in the same spot, which is just generally untenable for physics/ray tracing/rasterization.

vestal minnow
#

on main it should (in theory) initialize Position, Rotation, and ColliderAabb with the correct values on spawn

cinder summit
#

I think I did partially grab those changes, but all AABBs now get expanded so it's hard to avoid invalid AABBs, and my SDF code can have situations with invalid AABBs

little maple
vestal minnow
# little maple will there be a way to use ForceHelper with parallel query iteration? my first t...

Yeah that's kinda the tricky part. Earlier on I was trying to get a QueryData API like this working

fn apply_forces(query: Query<RigidBodyForces, With<Foo>>) {
    for forces in &mut query {
        forces.add_force(force);
    }
}

This would let you use all the query APIs like normal. However it needs to query for some optional components, and later batch-insert them if they're not already present, kinda like a get_mut_or_insert API, which is currently not possible with QueryData.

So I changed it to the ForceHelper system param that handles it for you. However this then requires the manual APIs like entity for actually accessing the APIs. We could probably add helpers like iter, iter_mut, par_iter, etc. that would take in a given query, and allow for a more efficient way to apply forces, it just needs some work

#

Mm or we could probably get the QueryData API working too... The main problem is local forces since they need to be accumulated into a separate component, unless we're willing to ignore the force direction changing between substeps

#

and I don't exactly love storing that extra component on every dynamic body just in case people apply local forces

little maple
vestal minnow
#

for world-space forces too, if we don't accumulate forces and acceleration into their own separate components, it would mean that actually applying forces is a bit more costly since it needs to apply the mass properties to each individual force rather than applying them once at the end to the accumulated forces

little maple
#

implementing and supporting two different APIs to do the same thing just to support parallel in one of the APIs also is kinda ooph

vestal minnow
#

we could also expose an unsafe entity_unchecked method similar to get_unchecked for parallel contexts, but ehh that's not ideal

little maple
#

We could probably add helpers like iter, iter_mut, par_iter, etc. that would take in a given query, and allow for a more efficient way to apply forces, it just needs some work

I like this idea, but I don't know how infeasible it is.

vestal minnow
#

yesss I think I got manifold-level graph coloring working finally
-# excluding an out-of-bounds index panic I get sometimes

#

so if two bodies share many contact constraints, they are all spread out to their own colors to avoid race conditions

#

changing it from pair-level coloring (which was UB for multi-manifold cases) to manifold-level coloring was a painnn but it seems to work now, and not be meaningfully slower

#

I'll hopefully have a PR ready soon-ish, and then we'll be faster than Rapier πŸ”₯ (given enough threads, in scenes with large islands)

#

then I should be able to do wide SIMD contacts πŸ‘€

sweet sundial
#

really fast-forwarding the tech evolution on avian

viral goblet
#

I added PhysicsDebugPlugin::default(), but I don't see my debug renders
Has anybody encountered anything similar lately?

visual sparrow
little maple
vestal minnow
#

make sure you also have PhysicsPlugins and whatever plugin Bevy uses for rendering gizmos (it's in DefaultPlugins)

vestal minnow
#

Lots of juicy benchmarks and other performance stuff there

little maple
vestal minnow
#

I'll try to fix that one in a sec

vestal minnow
#

mm there is also an occasional panic still :/ they're so annoying to track down

vestal minnow
#

@little maple I fixed those bugs so it should hopefully work properly now 🀞

#

got CI passing too

vestal minnow
#

I don't remember what your main bottleneck is, but this should primarily improve solver perf which is commonly the most expensive part of physics

little maple
#

my main bottleneck is ||my own bad code||, but I mostly notice dips when things start colliding aggressively

#

I did redo a few things based off suggestions you made which helped a lot and haven't bothered to remeasure

#

thread 'main' panicked at forks/avian/crates/avian3d/../../src/dynamics/solver/constraint_graph.rs:325:25:
Contact edge not found in graph: ContactId(233)

#

and
thread 'main' panicked at forks/avian/crates/avian3d/../../src/collision/contact_types/contact_graph.rs:576:26:
moved edge should exist

#

actually hold on... this might be unrelated.. I think one of my files got corrupted

vestal minnow
#

Yeah those are the common panics with this branch :/ I've fixed a million of those bugs already but it's very possible there are still some left

#

I would just need to consistently repro it lol, I haven't hit any panics so far after I fixed the sleeping bugs

little maple
#

oh it panics every time for me lol

#

it like... looks like it changed my world mesh

viral goblet
# visual sparrow Did you activate the gizmos?

I'm not sure what you mean. I added this as a component: DebugRender::default().with_collider_color(Color::from(PURPLE)) to something with a rigid body, a collider and collision layers

viral goblet
viral goblet
#

Also a new problem I came upon- how do you guys handle collisions in a tile grid?
My recoil-applying system (I use kinematic bodies) keeps making my player exit the grid (like, fly far far away)

vestal minnow
little maple
#

that's like, the same place in the game

vestal minnow
#

I think I've had that mess up transforms like once or twice for generated colliders but it's sooo random

little maple
#

I will say, it like puts a bunch of stuff inside of other things so that could be contributing to the odds of panicking. It looks like it consistently messes up some stuff but not others so I might be able to pinpoint what causes it at least. I'll dig into that more tonight

little maple
vestal minnow
#

This probably doesn't fix the issues you're having, but fixes another panic I was getting, and should also fix the problem where removing ColliderDisabled sometimes doesn't work
https://github.com/Jondolf/avian/pull/772

GitHub

Objective
Fixes #739.
The broad phase uses RemovedComponents for detecting when Disabled or ColliderDisabled is removed. However, it can miss removals in schedules with fixed time steps. To make it...

vestal minnow
#

I'ma try running Chainboom with the graph coloring branch to see if I can repro any of the bugs :P

little maple
vestal minnow
#

there's a few different instances of that same message

#

I'm guessing it could be from ContactGraph::remove_pair_by_id around line 561 or 576

little maple
#

Encountered a panic in system avian3d::collision::narrow_phase::update_narrow_phase<avian3d::collision::collider::parry::Collider, ()>!

thread 'main' panicked at forks/avian/crates/avian3d/../../src/collision/contact_types/contact_graph.rs:576:26:
moved edge should exist

vestal minnow
#

thanks, that should narrow it down a bit

vestal minnow
#

side note: holy shit we need the broad phase rework and incremental BVH updates badly ferris_spooky

#

I have gotten the bug like a handful of times in the past even with super simple scenes, but it's like a 1 in 100 chance

#

I was thinking that maybe it's something where it takes a longer time for the mesh to be loaded, which messes up some ordering, but it doesn't seem like it

little maple
#

I have a setting in my game that lets me scale the "world" mesh because I hadn't really decided at the time what felt good size-wise for everything. So, it's at 0.8 for this map. The way it works is it loads the scene with a transform with that scale and then I have hooks on things that add colliders and stuff to specific meshes. SO, what it looks like is that everything that has a collider in the world mesh gets set back to 1.0 scale. If you look at the comparison pic again there's that big OUTER 277 sign sticking out. It's at 1.0 scale because it has a collider, but the "bigger" sign behind it is at 0.8

#

so.. that's at least why that was happening to me. I think you're right it's related to that PR you linked

#

but also that uh, I'm doing something unusual

vestal minnow
#

hmm okay that sounds like a different bug than what I've seen, but also good to know

#

the problem I've seen a few times is some meshes just being teleported to the world origin like their global transform was reset

#

though scaling scene transforms does seem to work normally for me πŸ€”

little maple
#

I'll check my world origin, but once I set the scale to 1.0 everything looked right.

vestal minnow
#

OH I managed to repro but... differently? The mesh does get scaled but the collider didn't thonk

#

Or it did get scaled originally, but then snapped to a scale of 1.0

little maple
#

I think for me it's... the scene root is scaled.. and then in blender I have meshes that have their own scales which seems to affect the scale of the colliders underneath?

#

yeah, I'm not sure... honestly there could be a couple contributing factors for my situation like the scaling code I have

vestal minnow
#

or just Transform

vestal minnow
#

I'll look into it more tomorrow

little maple
little maple
acoustic spoke
#

you need bevy_sprite for 2d gizmos and bevy_pbr for 3d

#

@viral goblet

viral goblet
viral goblet
viral goblet
tribal hazel
#

hi trying to get a shapecast to work and need a sanity check

let Some(hit) = space.cast_shape(
    &Collider::cuboid(0.6, 0.5, 0.6),
    trans.translation + Vec3::Y * 0.75 + *forward * 0.3,
    Quat::from_rotation_arc(Vec3::Z, *forward),
    forward,
    &ShapeCastConfig::from_max_distance(0.1),
    &SpatialQueryFilter::default(),
) else {
    continue;
};

I want to cast from the middle of the 1 unit tall character so add Vec3::Y*(0.5+0.25 from cuboid height) and add forward*0.3 from cuboid width and rotate by arc to forward
i believe this is a correct representation in gizmos

gizmo.cuboid(
    Mat4::from_scale_rotation_translation(
        Vec3::new(0.6, 0.5, 0.6),
        Quat::from_rotation_arc(Vec3::Z, *forward),
        trans.translation + Vec3::Y * 0.75 + *forward * 0.3,
    ),
    Srgba::GREEN,
);

however it currently isn't hitting consistently (image isn't meant to be a hit btw) - anything i'm doing wrong?

vestal minnow
little maple
#

checking..

little maple
vestal minnow
little maple
# vestal minnow Neat! I'll merge it in a sec and then try to repro and fix the panic you were ge...

I think the remaining problem I'm seeing is due to my code spawning an entity with a rigid body and collider and then inserting a Transform of where I actually want it with entity_commands afterward... and with that change I think it causes the entity to spawn at the origin and get stuck. But... that seems correct because that would mean the collider/rigidbody is using the transform that's there which is the default Transform. I just need to change my code for that, I think

vestal minnow
#

This simple case ^ works for me at least

little maple
# vestal minnow Something like this? ```rust commands .spawn(( RigidBody::Dynamic, ...

my situation is a bit more complicated, I'm afraid. I use this scene hook which processes the entities as the scene loads so that when it finds the part of the gltf that I want to generate a collider from, that's when it puts the rigidbody/collider on the root. I think it creates this race condition where.. depending on how quickly that happens, the collider gets added while the Transform is default or after the Transform has been updated. Again, I think I just need to change that code

vestal minnow
#

I've tried quite a few different collision scenarios with various shapes and stuff, no crashes so far

#

I'm not sure how it'd even be possible to crash there, I think it'd require there to be duplicate or invalid contact IDs which shouldn't be possible πŸ€” probably missing something though

#

@little maple I added some more info to that crash message on the graph-coloring branch in case you can reproduce it

#

Mainly just the involved contact IDs and pair index

little maple
little maple
vestal minnow
#

Oh interesting that's from a different place now

#

That one is when a collider is despawned or disabled

viral goblet
vestal minnow
#

It's when you despawn a collider that has a contact pair with multiple contact manifolds

little maple
#

ok, I got another one for ya

thread 'main' panicked at forks/avian/crates/avian3d/../../src/collision/contact_types/contact_graph.rs:579:25:
error when removing contact pair ContactId(127) with pair index 49: moved edge ContactId(140) not found in contact graph with 211 edges and 67 active pairs

vestal minnow
#

yeah okay that's the original one, with the more detailed message I added

#

those values don't look too weird so I have no clue what's happening there thonk somehow the edge is removed and the corresponding contact pair isn't, or the ID becomes invalid

#

would be nice if I managed to actually reproduce that panic ferris_sob

little maple
vestal minnow
#

Nah it's super helpful for making sure things aren't broken, your project is clearly good for finding bugs lol

little maple
#

haha yah πŸ˜… ||😭 ||

little maple
vestal minnow
#

I did test that sensors still detect things but didn't try actual physics with other contacts happening simultaneously

#

I'll see if I can figure it out

vestal minnow
#

crash 1 out of 3(?) fixed, the one related to despawning entities

#

lol yeah sensors really fuck up the collisions, though I haven't gotten a crash (edit: reproduced a crash!)

little maple
#

yeah, again I have two big sensors that are inside of each other and it's like when entering a spot that was within both of the sensors.. that triggered a crash a lot

crimson estuary
#

Hi all, I am trying to figure out if I have a performance issue or not, I am on an M4 MacBook Pro (M4 Max) and am playing with bevy and avian3d and I am essentially taking the 3d cube example from the readme and just spawning a lot of those cubes (a lot being 100 in this case) and things get real choppy and I am trying to figure out if I am making a mistake with how I add these cubes or if this is in line with the expected performance for that number of Dynamic RigidBodys on that kind of machine.

There is some shader stuf happening as well but that wasn't choppy when the cubes were not physics objects / when I switch to a StandardMaterial performance doesn't change all that much..

In the video I am restarting the app to show the initial choppiness, it seems to calm down a little once the cubes stop moving / the number of collisions is reduced.

So yea, I am new to bevy as well and as such I wanted to check what the expected performance is to figure out if I am spawning the cubes in an inefficient way or am making some other mistake. But first I wanted to ask what performance I should expect with 100 colliding bodies.

#

Hope this is the right place to ask that :/

crimson estuary
broken hedge
crimson estuary
# broken hedge I suggest check out this page https://bevy.org/learn/quick-start/getting-started...

Thanks,indeed I have not switched on any optimisation ( I guess it's a debug build ... Not sure about the terminology). I guess I (possibly naively) assumed those optimisations will represent constant factor improvements and as such the fundamental relation between number of objects with colliders and the performance might stay the same regardless (e.g. if it is something quadratic in the number of entities or so).

viral goblet
viral goblet
#

I wanted to make a pr with this as an example for Avian2d but said I'd put it here first
Who thinks it's clear and important enough to be submitted as a pr (with subtle changed)?
It's a file from my game that showcases shapecasting for velocity clamping (specifically for walls as of now)

vestal minnow
#

So it slows you down based on distance as you approach walls?

#

It's a cool idea, but maybe a bit too niche to be an example imo

#

For examples I generally want to scope them to one of these three:

  1. Demonstrates a specific feature and how to use it
  2. Demonstrates how to use the engine to implement physics functionality for a common gamey use case (like a character controller or some n-body sim or buoyancy etc.)
  3. A sample or stress test for demonstrating the engine's stability, performance, or accuracy (these could probably have their own folder)
#

Your example would probably fit category 2, but it feels a bit too specific maybe

#

Also it seems like you could just specify a SpatialQueryFilter for the ShapeCaster to handle the layer filtering, instead of manually filtering results in the system

viral goblet
#

Like, if the next physics update would make you pass the wall, it makes you get to the wall instead

#

I think it's useful

viral goblet
vestal minnow
vestal minnow
#

Heyyy @little maple wanna try the graph coloring branch again when you have time? I fixed quite a few problems involving sensors and kinematic bodies and some other stuff :P

#

I couldn't repro one of the crashes you got, but I'm hoping it was related to the sensor bug I fixed, which was otherwise messing up contacts for me

little maple
vestal minnow
#

Yay! I'll merge it later this weekend then, once I've cleaned it up a bit more and written the migration guide

#

I'm pretty hyped to finally get graph coloring done, now I'll be able to do wide SIMD to really make it shine

past escarp
#

In a basic 2d example I was inadvertently running debug on my iphone and it was peaking at 200+%cpu vs ~60% on release. Iirc there is also a mac bug atm that causes higher than needed cpu usage

pulsar lion
#

Hejhej! I've only made some games where I had very simple collision detection etc. via my own naive implementations and it worked ok on my laptop.
Now my question is:
I ran the 3d example from the avian repo and it seems like I only get around 10 fps on my somewhat old laptop. Is this to be expected?
I'm a bit scared, that I will run into performance problems later on.
Should I use avian only if I really need realistic physics and opt for parry if I just need collision detection? (I think bevy recently got their own raycasting system right?)

rustic vine
#

When using EventReader to handle collision events, is there a way to get a specific kind of entity as the first one without checking whether it's the first, swapping the pair, then checking again?
Pretty much like Observers, where trigger.target() is always the entity that has CollisionEventsEnabled. (If both colliding entities have CollisionEventsEnabled, then it calls the observer twice for the same collision.)

silk mauve
# pulsar lion Hejhej! I've only made some games where I had very simple collision detection et...
  1. Make sure your project is setup to compile with performance optimizations as per https://bevy.org/learn/quick-start/getting-started/setup/

I know you said you're on an example, but it could be you imported it into another project or something so I thought I'd mention it.

  1. Try running with cargo run --release
pulsar lion
silk mauve
#

It's almost always the case that specialized solutions will be more performant then general ones so that makes sense. I'm glad you figured it out!

vestal minnow
#

the breakout example basically does O(n^2) collision detection which will scale very poorly

#

on my machine with the recent work, I can easily have 10k dynamic bodies at 60 FPS, at least in 2D (but I do also have a fairly powerful PC)

#

The current broad phase though does scale quite poorly too for tons of colliders, but the BVH broad phase coming SoonTM should fix it

pulsar lion
summer acorn
#

do i have to re-implement all colliders i want?

#

like a custom enum

vestal minnow
#

but you could just do

// pls use better names
pub enum MyCollider {
    Parry(Collider),
    Custom(MyCustomCollider),
}

or something like that, and use the default impl for Collider-Collider collisions and your custom logic for the rest

summer acorn
#

i seeee

#

hmm

#

so its expected that all colliders in a scene are the same type

#

what happens when they arent

vestal minnow
#

you can have more than one collider type in the scene, but each collider will only interact with colliders of the same type

summer acorn
#

i see

vestal minnow
#

doing NarrowPhasePlugin::<MyCollider>::default() essentially just defines a narrow phase instance for collisions between colliders of type MyCollider

summer acorn
#

so, i could just hook in my custom narrowphase implementation here

#

datura

#

makes sense

vestal minnow
#

the narrow phase has quite a lot of complexity, even more-so once I merge the graph coloring PR, so it's not really trivial to fully replace the narrow phase or just "hook in" a custom implementation there

#

the main supported way is just using the AnyCollider approach like in the example in the repo

#

in the case of Peck I just derive AnyCollider for the Shape2d/Shape3d enum and boom I have working colliders

summer acorn
#

cool

vestal minnow
#

for the Parry Collider it instead stores a SharedShape which is an Arc<dyn Shape> so it can store any type that implements the Shape trait from Parry

arctic fulcrum
#

Shouldn't the revolute_joint allow for a different axis on each body to be aligned? E.g. I want a wheel rotating around Z axis to be aligned with the X axis of a car

#

similar to how it has separate local_anchor1: Vec3 and local_anchor2: Vec

#

Or am I misunderstanding how it's meant to be used?

dreamy viper
#

How do i measure the diffs between 2 rotations?

sweet sundial
#

divide the quats?

#

depends what you want the diff as

dreamy viper
sweet sundial
#

huh, weird

dreamy viper
#

I guess there's inverse and product

sweet sundial
#

multiply the conjugate/inverse

dreamy viper
#

ty

#

So (b-a) = b * a.inverse() ?

sweet sundial
#

no, quat addition just isn't meaningful to quat rotations

#

can sphere-average with an add and renormalize, though, so they're still useful

vestal minnow
#

Merged graph coloring!

little maple
#

I haven't actually had a need for this yet, but if a collision occurs how would you determine where in world space the collision is?

past escarp
#

is collidingentities less reliable than collision events? I notice im sometimes missing collisions using the former

wicked garden
#

How much work is it to DIY a character controller?

#

Just the basic 4-directional movement, maybe jump, bit of acceleration on start and go, not flying off on bumps

sweet sundial
sweet sundial
sweet sundial
wicked garden
#

But I want something that stops on its own and doesn't roll or slide down slopes unless idk they're slippery and steep I guess

#

The typical, with nothing fancy

orchid olive
#

You could maybe add some kind of angular anti force on the sphere ?

#

And you set the friction of the material really high

sweet sundial
#

you mean drag?

wicked garden
#

OK it's sounding very hard

sweet sundial
#

i just use tnua

past escarp
wicked garden
#
rapier_context
    .cast_ray_and_get_normal(
        position.extend(300.0),
        Vec3::NEG_Z,
        bevy_rapier3d::prelude::Real::MAX,
        false,
        QueryFilter::only_fixed(),
    )
    .map(|(_, intersection)| intersection.point.z)
```What would be the Avian way to do this? For a specific point in 2D, I get the height (highest point) of some collider
#

in a 3D space

#

So for a given x and y I find the z (the collider is my ground)

#

The only initialisers for ColliderMassProperties are ZERO and one that takes a density?

sweet sundial
#

is that related?

wicked garden
#

Not beyond that it's also me trying to migrate from rapier on the same project

#

ah I see I think I should just be using Mass instead

#

What is the Avian counterpart to rapier's Velocity component?

little maple
#

LinearVelocity?

wicked garden
#

thanks

little maple
wicked garden
#

No

#

Looking into rays, Avian's RayHitData doesn't even say where in world space the hit was

#

only entity, distance and normal

#

Wait, that's not what a normal is, is it

#

normal is going to be a unit vector?

sweet sundial
#

yes

wicked garden
#

I could do the math based on the original ray's starting point, angle and distance, but I'd really rather not

sweet sundial
#

you may be looking for the raycaster component or the spacialquery systemparam

wicked garden
#

Nah because I need it on demand, sometimes multiple times per frame

sweet sundial
wicked garden
#

Well, the one thing I said before is ok once per frame, but there are some related things

wicked garden
#

I am doing 2 things that involve raycasting, one of them may not really need it

#

I am casting a vertical ray down to get the height at any given point, I think multiple things use this but one is the thing that prevents things from going underground

#

the world is a trimesh

#

and I am casting a ray from cursor to the terrain to see what has been clicked or dragged

#

you can paint colours onto the terrain

wicked garden
#

Yeah, but the raycasts on it don't seem to communicate what they hit

#

I mean the point they hit

#

they give entity, normal and distance

halcyon dew
little maple
#

πŸ‘†

wicked garden
#

since I only need z there is space for a micro-optimisation xdd

#

Two colliders A and B can interact if and only if:

The memberships of A contain a layer that is also in the filters of B
The memberships of B contain a layer that is also in the filters of A

is this and or or

vestal minnow
#

and

#

same as rapier by default

wicked garden
#

why are there so damn many different vec3s

#

I get a Dir3 from Bevy, but Avian wants a Dir, which I can .into()

#

but elsewhere I was apparently using a Vec3 and I can't .into() that

#

oh Dir is just an alias for Dir3 derp

#

(presumably only when using avian3d)

sweet sundial
#

Dir3::new, Dir3::get or deref

wicked garden
#

I needed Dir3::NEG_Z, they can pry vertical Z from my cold dead hands

#

I deleted a bunch of components having faith that the new required components thing would insert any that looked boring and defaulty

#

compiling now 🀞

#

deleted their insertions I mean

wicked garden
#

I kinda wanna hardcode the gravity direction less, but to do that I would have to give up extend I guess. and instead do something like + some gravity vector * 300.0

#

maybe that's not too bad

wicked garden
#

Everything is working except my ball falls through the world

little maple
#

have you tried using the debug plugin?

wicked garden
#

not yet

wicked garden
#

I just did the most 1:1 migration I could think of from Rapier to Avian

#

to get it to compile

#

My terrain has ```rs
CollisionLayers {
memberships: GameLayer::Terrain.into(),
..default()
},

#
/// Adds physics simulation property to the avatar.
fn give_avatar_physics(mut commands: Commands, avatar: Query<Entity, With<Avatar>>) {
    let avatar = avatar.single().unwrap();

    commands.entity(avatar).insert((
        Collider::sphere(0.5),
        Mass(1.0),
        RigidBody::Dynamic,
        CollisionLayers {
            memberships: GameLayer::Avatar.into(),
            ..default()
        },
    ));
}
```And here is my avatar
#

it's kind of interesting that I have a separate system just to add physics to the thing, because I have 1 module with all my physics. I don't think that today I would bother to split it up like that

sweet sundial
#

why aren't those required components

wicked garden
#

that didn't exist when I wrote this

#

and I don't think it's worth bothering now, it seems like a very lateral change

#

Is it the new idiom to shove as much as possible into required components?

#

Now what xd

wicked garden
#

I removed all the filters and such in case that was the problem

little maple
#

what is the problem you're facing?

wicked garden
#

After migrating like 1:1 from rapier, there appears to be no collision between the trimesh terrain and the spherical collider "avatar" (the only two colliders I have)

halcyon dew
halcyon dew
wicked garden
#

That's just it being teleported out each time it falls below

#

I guess it does teleport it a bit higher than needed

#

it's my DIY anti-tunneling xd

little maple
#

it's kinda difficult to tell from that screen shot.. it does look like it's floating in the right spot

wicked garden
#

I was just showing that the colliders exist, not sure what else debug can do

#

I got it πŸ™‚ I was missing a RigidBody::Fixed on the terrain

#

I don't really know how that happened, did Rapier have that as a default and Avian doesn't?

little maple
#

do you mean RigidBody::Static?

slate vigil
#

hi i wanted to try out avian2d for my project, but i noticed some bizare behavior idk what to do about it. Adding a RigidBody to an entity disables the Sprite component, resulting in the second image. commenting it out results in the first image, which is the intended behavior except for the missing RigidBody ofc. i have PhysicsDebugPlugin in the project to show colliders, as you can see in the image, removing it doesnt help.

heres the snippet where all the things in my player are:

                entity.insert(Player::default())
                .insert(Sprite::from_image(asset_server.load("main-char.png")))
                .insert(RigidBody::Kinematic)
                .insert(Collider::rectangle(16., 16.))
                .with_children(|commands| {
                    commands.spawn((
                        Camera2d,
                        Camera::default(),
                        Msaa::Off,
                        Transform::from_xyz(0., 0., 0.).with_scale(Vec3::splat(1. / SCALE_FACTOR)),
                    ));
                });```
i couldnt find anything via normal search engines and discord search for threads is terrible so idk if anyone had this issue here either
#

the versions should be up to date

#

AHA same issue with sprite rendering

#

oh uh. huh. what? the sprite moves down to below the game world. i guess its some render ordering thing

little maple
#

huh, wonder if it changes the z-index

slate vigil
#

the player transform is probably at Z zero because im spawning it from an ldtk map

#

so the same map as the tilemap in the background

#

them overlapping can create issues like that

#

moved the sprite here and raised it 10 units now its on top while having a RigidBody

#

while im here can the debug render for colliders and such be toggled at runtime?

little maple
vestal minnow
#

PhysicsGizmos is just a GizmoConfigGroup so you can toggle and configure it like other gizmos in Bevy

wicked garden
wanton sorrel
thorn solstice
#

I think I have a fix for this on obvhs main now (and on the max depth pr). I've reworked the bvh2 leaf_collapser to be a lot more parallel and fixed a possible race condition with the old parallel version (I think the issue you ran into here). I'll probably cut a new point release with the fix sometime in the next couple days.

#

With the new version, single-threaded collapse is around 1.4x as fast, and multi-threaded collapse is around 2.5x as fast. On the medium build preset single-threaded bvh building is around 1.14x as fast, and multi-threaded is around 1.5x as fast averaged across the tray racing scenes (total bvh build time, not just collapse).

thorn solstice
maiden epoch
#

@vestal minnow, Hi!
What do you think about using component hooks on ColliderAabb to push an entity into AabbIntervals immediately when it's spawned?
So that we can guarantee the iteration order even if the entities are at the same X position.
And also get rid of sorting in the broad phase.

vestal minnow
#

We're going to replace it with BVHs soon but it will still be deterministic.

#

Avian is already cross-platform deterministic with the enhanced-determinism feature, you can try the determinism_2d example to verify this. Our CI also has a test for this so that we never break determinism.

#

The only exception is currently if you have a chain of joints, as they currently use query iteration order (this will change later). But I believe even that should be deterministic across runs.

#

"Determinism issues" in Avian in the context of networking are primarily from how (rollback) networking interacts with the contact graph and warm starting.

vestal minnow
vestal minnow
rough nebula
#

hello friends, i want to ask if it is possible to have rigidbodies that are not able to push each other, but still prevent other bodies from passing through them

#

i thought that is what kinematic rbs where but i realized kinematic rbs dont interact with other kinematics at all :/

vestal minnow
#

So you want them to collide normally with some bodies but pass through others?

#

Or do you want that they are immovable when colliding against each other, but still don't allow each other to pass through

vestal minnow
#

Mm that's kind of tricky with built-in contacts because you essentially want both objects to be immovable but to also not overlap, which are somewhat conflicting requirements from the physics engine's POV (since to resolve overlap you kinda need to move the objects)

#

I feel like this should probably be a kinematic body with a collision algorithm like collide-and-slide

#

like most kinematic character controllers

rough nebula
#

yeah i figuered itwould be like that

#

meh i think its too much effort :P
im sure my infallible pathfinding will prevent stuff bumping into each other right

acoustic spoke
#

hey, just checking; does Avian currently have problems with entities that spawn with Disabled (and re-enabled later)? i'm typing this as i try to compile a minimum reproducible example...

vestal minnow
acoustic spoke
#

😦

#

do you have any workarounds i could use for ""delaying"" entity spawning with physics components? or should i just use the main branch

vestal minnow
#

The bug I fixed is with re-enabling sometimes not working

#

But I didn't test starting in a disabled state at spawn iirc

acoustic spoke
#

ah, okay. i'll try switching to main and see if it gets fixed then

#

otherwise i'll post that minimum reproducible example on a new issue report!

#

to be clear, it's toml [patch.crates-io] avian2d = { git = "https://github.com/Jondolf/avian" } and cargo update, right?

thorn solstice
maiden epoch
# vestal minnow Avian is already cross-platform deterministic with the `enhanced-determinism` fe...

Nice, I didn't realised that!
Not related to determinism:
A while ago I wrote here about weird behavior with quickly rolling objects, slowly passing through ground.
Recently I figured out that this happens because TGS caches contact points in the local space of the body.
This heuristics works especially bad with fast rotation.
The deviation increases with each substep, thereby reducing the support force:

vestal minnow
#

same as Box2D and Rapier

#

or hmm

#

Yeah so more specifically, the fixed anchors are used for computing the relative velocity, which makes it so that it won't drill objects into the ground due to an incorrect velocity direction. But it computes updated anchors for the updated separation depth, which may be wrong for rolling objects like this. But I believe it shouldn't matter generally

#

(I think, I'd need to test some things to double-check how it behaves)

maiden epoch
#

As I understand, separation is computed from local contacts:

            let r1 = body1.delta_rotation * point.anchor1;
            let r2 = body2.delta_rotation * point.anchor2;

            let delta_separation = delta_translation + (r2 - r1);
            let separation = delta_separation.dot(self.normal) + point.initial_separation;
#

By locality I mean temporal locality, i.e. relative to the position at the previous substep.

vestal minnow
#

The bigger problem would be using the local contacts for the relative velocity, which is why we use the fixed anchors for that part instead

#

With the current approach of using local contact data for the separation depth and fixed anchors for relative velocity, rolling at a high speed looks like this

#

With local contact data for relative velocity too, there's some weird resistance and you can see the object sink in the ground

#

(ignore the debug rendering lagging behind a bit, it's not interpolated here atm unlike the mesh)

maiden epoch
#

This becomes problematic on a car moving at 100km/h.
I think we need some threshold for rotation speed.
And for fast rotating objects compute local contacts without taking rotation updates into account.

vestal minnow
#

Pretty much all physics engines I'm aware of that use substepping use this same approximation based on local contact points. The alternative is running the narrow phase at each substep, which is not feasible

vestal minnow
#

We do have MaxAngularSpeed already

#

It's just uncapped by default currently

maiden epoch
vestal minnow
maiden epoch
#

But it is no longer a problem for me though, because I no longer use contacts for wheels
I have a custom solver for wheel-ground constraint

#

Avian is really nice for implementing custom constraints

#

I wish there be functions for computing effective mass for common DOFs

vestal minnow
maiden epoch
vestal minnow
#

Right, cool

#

We're most likely switching the joints to be impulse-based soon, so they'll probably have some helpers for computing the effective mass for various constraints

little maple
#

is there a way to get the world space point where two entities collided?

oak vigil
#

Hey, I'm having a strange issue with Colliders. I'm trying to create a minimal repro but it's being difficult.
I have a case when I spawn 2 rigidbodies at the same time with disabled colliders (i.e. ColliderDisabled), and then immediately remove ColliderDisabled.
Somehow, sometimes (not always!) the colliders don't seem to detect collisions with each other. CollidingEntities returns empty.
If I add/remove ColliderDisabled, without changing anything else (no transforms changed), suddenly the colliders start reporting collisions again.
It feels like the engine is somehow not detecting the removal of ColliderDisabled... sometimes?
Is this a known issue? Anyone else notices this? Any clues would be helpful

acoustic spoke
acoustic spoke
#

do kinematic bodies not fire collision events? despite having Sensor and CollisionEvents components?

#

seems like i have to shapecast manually...

acoustic spoke
#

the "hey???" never prints

oak vigil
#

Are you sure they're actually colliding?

#

I'd start by checking CollidingEntities

acoustic spoke
acoustic spoke
#

wait, i have to add it manually?

oak vigil
#

Yes

acoustic spoke
#

or is this unrelated to the collision event/trigger systems

oak vigil
#

You need to add CollidingEntities manually for it to be populated by avian

#

You could probably check collisions too, I just usually find CollidingEntities more ergonomic

acoustic spoke
#

it is empty

oak vigil
#

Yah so you're not colliding

#

I'd say maybe check your collision layers

acoustic spoke
#

i have never once touched collision layers

oak vigil
#

You don't use them at all?

acoustic spoke
#

it's just RigidBody::Kinematic and Colliders

#

yes

#

the kinematic body is probably the problematic part

oak vigil
#

Hm thinkEgg

#

It shouldn't be. I use kinematics only too

#

Although I don't use events. But I do get colliding entities populated

#

Is this 2D or 3D?

#

3D

acoustic spoke
#

Collisions::entities_colliding_with(...).len() also reports 0 lol

oak vigil
#

Oh I thought capsule collider was 3d

acoustic spoke
#

although i wonder if this is the result of the entities being Disabled at first; let's try factoring that out

oak vigil
#

Are your rigid bodies root entities?

#

Oh!

oak vigil
oak vigil
#

!!!

#

We are seeing the same issue I think

acoustic spoke
#

aaAARHHGHHHAHAHAAHAHAHAAAAAA i'm going insane

acoustic spoke
oak vigil
#

Maybe this is a bug

acoustic spoke
#

if only there's a way other than [Collider]Disabled to delay spawning entities rahhh

acoustic spoke
# oak vigil Maybe this is a bug

definitely is-- before switching to main the bug was even worse: after re-enabling the colliders won't even exist, and gizmos don't draw

oak vigil
#

I'm curious, is your issue 100% repro? Cause for me, I only get it sometimes. Mine only shows up in tests cause that's when I spawn both bodies in 1 frame. And it only happens 2/5 times

acoustic spoke
#

it is 100%, yes

oak vigil
#

But that could just be due to race conditions in my own systems

acoustic spoke
#

1 frame
that could be the cause?

#

fixed update and some other things

#

my delay is 2 seconds before i remove the Disabled component

oak vigil
#

From my POV, it just looks like the engine isn't updating the physics state on ColliderDisabled removal when entity just spawns

acoustic spoke
#

ah, so mine's more subtle... it just refuses collisions

oak vigil
#

For me, bodies spawn, they're visually colliding, ColliderDisabled is removed, CollidingEntities reports empty until I add/remove ColliderDisabled

#

Yah so maybe a bit different.

acoustic spoke
#

no doubt it's related to insertion/removal hooks tho

#

so i guess we'll have to find some other way to disable colliders (or even entities) until this gets resolved 😭

#

there's that hey??? i was looking for πŸ™ƒ

#

although actually @oak vigil, i wonder what happens if we re-insert the Colliders?

#

i.e. ```rs
commands.entity(e).queue(|mut e: EntityWorldMut| {
let collider = e.remove::<Collider>().unwrap();
e.insert(collider);
});

oak vigil
#

In theory physics state should update if collider/transform state changes... so yah, i'd expect it to work

#

Although I haven't tried it, cause I thought that exact code you have is too naive

#

Since it happens all in one frame, it might still not "kick" avian

#

I dunno. Try it

acoustic spoke
#

well, if avian relies on Added<> or on_insert/on_add, it should probably do it

#

since it increments the change tick

#

let's see...

#

crap, removeing doesn't actually return the component since it accepts a Bundle

oak vigil
#

I think the function you want is take

acoustic spoke
#

oh damn i didn't know that existed, thanks

#

okay yeah that didn't work.

#

i only considered RigidBody and Collider though, maybe there's something else i should consider?

#

(or, a more cursed idea is to delay removal and insertion by 1 frame)

oak vigil
#

Are your rigid bodies root entities?

acoustic spoke
#

the parents don't have physics components, though, only Transform and Visibility

acoustic spoke
#

i managed to make it work by using... this 🀣

#

cleaned it up a bit

oak vigil
# acoustic spoke uhh, no they are not

This might be your root cause. In my project, I had issues where collider positions of child rigid bodies wouldn't update correctly.
In my case, I have a system which swaps the RigidBody in/out for all child entities, so that all my rigid bodies are root entities

#
fn spatial_attachment(
    attach: Query<(Instance<Spatial>, &RigidBody), With<ChildOf>>,
    detach: Query<(Instance<Spatial>, &AttachedRigidBody), Without<ChildOf>>,
    objects: Objects,
    bodies: Query<Entity, With<RigidBody>>,
    mut commands: Commands,
) {
    for (instance, body) in &attach {
        let this = objects.get(*instance).unwrap();
        let new_body = this.query_ancestors(&bodies).last().unwrap();
        commands
            .entity(*instance)
            .remove::<RigidBody>()
            .insert(ColliderOf { body: new_body })
            .insert(AttachedRigidBody(*body));
    }
    for (instance, AttachedRigidBody(body)) in &detach {
        commands
            .entity(*instance)
            .remove::<AttachedRigidBody>()
            .remove::<ColliderOf>()
            .insert(*body);
    }
}
#

I could probably optimize it with triggers, but it's good enough for now

warm whale
#

is there a component that would allow me to ignore collisions on a specific entity? like, if i insert a component on an entity it will pass through other entities without affecting them

#

I'm trying to implement a ghost like entity (it'a a kinematic body)

#

hm, i just realised I can probably do that just by removing a collider... I still want collision events though πŸ˜„ (If a ghost reaches the player, I want to get a coliision event when that happens)

vestal minnow
#

You can make it a Sensor collider

warm whale
#

Thanks! I think that's exactly what I wanted πŸ™‚

unkempt jewel
#

i've been using the force-rework branch and am really enjoying it. lovely stuff ❀️
only problems i ran into was needing different values between 0.3.1 and force-rework and the transform issues where a plane would shrink which i think was fixed in https://github.com/Jondolf/avian/pull/760
i needed about 100N to throw something with a mass of 0.4, which seems odd compared to the 1N for 0.3.1. i suspect something is off on my end, maybe too much dampening or some such

worst part by far is having to switch back to 0.3.1. i got myself hooked on ForceHelper

vestal minnow
#

And yeah, I still need to verify that all the forces and impulses are actually physically correct and I haven't gotten units mixed up somewhere. It's possible that something is currently wrong there, especially if the values are vastly different from before

little maple
#

I finally figured out what was causing this issue where when my car goes fast it trips over edges in the ground collider. It was ghost collisions and turning off speculative collisions by setting default_speculative_margin to 0.0 totally eliminated the issue. I know tunneling is a concern but so far it's been good πŸ€·β€β™‚οΈ

bleak wadi
#

is it normal that hitboxes can clip a little bit into each other? if not, how do i fix it? and if so, how can i fix collision when walking over different tiles

maiden epoch
#

Try to add CollisionMargin to the ground

lyric loom
#

Hi everyone, I'm starting a game with chunk-based procedural generation. I'm running into a performance issue with avian3d which I don't fully understand

#

Here's my setup: I have a character that runs around. As the character changes position, a dedicated system despawns chunks that the character is no longer close to, and spawns chunks that they become close to

#

For now chunks are just composed of a simple gltf-based static body

#

So in a nutshell, you have a bunch of static bodies all over space, with some spawning and some despawning as time goes

#

Here's my issue: the frame rate is ok at first, and as I move around it goes down and down. I'd understand if it were just going down as the bodies are getting spawned, and it went back to normal after. But no, even if I don't move after that, the frame rate remains very bad

#

Any idea what this might be due to?

visual sparrow
lyric loom
#

I spent hours on that issue, and just as I'm asking my question I realize the chunks that are supposed to despawn might not actually be despawning after all -_-

lyric loom
lyric loom
lyric loom
visual sparrow
past escarp
# little maple is there a way to get the world space point where two entities collided?

I dont know if you ended up figuring this out but i was trying to figure out the same problem and thought to post my solution for posterity.

You'll need the two entities colliding, and these queries:

contacts: Res<ContactGraph>,
pos_rot: Query<(&Position, &Rotation)>,
let (projectile_pos, projectile_rot) = pos_rot.get(projectile_entity)?;
let (object_pos, object_rot) = pos_rot.get(object_entity)?;

let hit_point = contacts
    .get(projectile_entity, object_entity)
    .and_then(|pair| pair.find_deepest_contact())
    .map(|points| {
        (points.global_point1(projectile_pos, projectile_rot)
            + points.global_point2(object_pos, object_rot))
            / 2.0
    });

anyone please let me know if there's a better way to do this :)

#

in my case i assume getting the average is probably really unnecessary since the points are very close together and I don't care about that precision

little maple
bleak wadi
#

hm thats because i have something detecting the angle of the collision, so if it hits the side of the collider instead of the top it doesn't like that

#

weird sometimes thats not even it

modern quartz
visual sparrow
rare shale
#

@vestal minnow did you ever make an issue SpatialQuery Collider component access conflicts? Can't find anything on GH. #1124043933886976171 message

  1. Out of interest, what is the tl;dr of the fix that you meant here?
  2. It looks like the only thing that uses SpatialQuery.added_colliders and SpatialQuery.colliders is SpatialQuery.update_pipeline, and in my cases, I actually never use that function, I just use point_intersections and shape_intersections, so I guess it's interesting that I even reached for the SpatialQuery system param in the first place...seems like a lot of cases people have here should just be reaching for Res<SpatialQueryPipeline>, right?
cinder summit
#

You mean the system param conflicting with queries accessing Collider/Position/Rotation?

#

Cause my SpatialQuery rework just outright removes that issue 🀣

molten bane
vestal minnow
#

Which lets joints kind of "break through" contacts quite easily

#

We're most likely switching the joints to be impulse-based as well, which should fix it

#

Joints will be solved first, and contacts will "see" those impulses before the positions of bodies are changed, giving contacts higher priority in the solver

#

same as how other engines handle it

#

My TGS+AVBD hybrid experiment kind of hacked together a similar effect in that AVBD didn't apply positional updates to bodies directly, but rather computed what the resulting velocity would be, and then contacts are solved afterwards, which kinda makes them joint-aware

#

But yeah I guess to answer your actual question, the main way to give collisions a higher priority is to just solve them last. That way they can react to what the earlier constraints have done.

#

Or you could also scale the contact softness parameters (mainly the frequency) based on some criteria. For example we make contacts against static bodies stiffer than contacts against dynamic bodies to prevent tunneling

rare shale
vestal minnow
#

I don't think it's public or at least finished yet

#

or the branch might be public but there's no PR just yet

vestal minnow
#

I never got around to implementing this though, but I'd accept a PR for it (though Nise's stuff should also fix it)

vestal minnow
#

(details here are TBD)

rare shale
#

FWIW at least from a naming perspective SpatialQuery seemed to be the obvious dependency to use to query, whereas SpatialQueryPipeline actually sounds more complicated.

But anyway, I didn’t know the resource existed until I saw your linked post above and it’s gotten me out of trouble with that error so I’m happy for now.

Sounds like there’s a bit in flux so I won’t bother doing any PR related to your initial thoughts above.

vestal minnow
#

Yeah, SpatialQueryPipeline is definitely intended to be more of an internal thing, so I'd like to keep SpatialQuery as the primary user-facing API (excluding the current conflict problem you're having)

cinder summit
bold forge
#

Is it possible to lock the rotation of a child collider but still have the parent able to freely rotate?

vestal minnow
#

Not really

#

you'd have to hack around transform propagation

bold forge
#

Yeah I think I just need a joint and two separate entities

robust girder
#

How do I set up things to be able to speed up the simulation while retaining determinism?
I tried changing relative_speed of Time<Physics>, but that changes the outcome, which makes sense as my other systems (which interact with the physics) still run as normal.
Is there maybe a schedule I can hook into?

past cargo
#

@vestal minnow hey jondolf, do you use Res<Time> from bevy to get the delta time on your phsics simulation?

hoary turret
#

would it be possible for a component containing the collisions for a physics-abled entity to exist alongside it?

so that instead of:

fn projectile_airborne(p: Single<Entity, With<Projectile>>, c: Collisions) -> bool {
    c.collisions_with(*p).next().is_none()
}

we can do:

fn projectile_airborne(c: Single<Collisions, With<Projectile>>) -> bool {
    c.next().is_none()
}
#

I found it weird that checking collisions breaks the ECS query pattern of bevy

#

I suspect there will be a performance-related reason behind the decision

sweet sundial
#

there's CollidingEntities

vestal minnow
#

There's CollidingEntities but storing the actual collision data on the entities would be bad, it'd mean you're storing the same data in three separate places, i.e. on each of the two entities and in the ContactGraph, and you'd need to keep all of that in sync

vestal minnow
#

With the default scheduling, Time<Physics> is derived from the Time used by the schedule where physics runs, so Time<Fixed> in schedules like FixedUpdate and FixedPostUpdate, or Time<Virtual> in PostUpdate

hoary turret
hoary turret
#

thanks ❀️

vestal minnow
#

For proper determinism and consistent behavior, the delta time used by physics must remain constant. The only way you can really speed up or slow down the simulation in this context is to run physics more or less frequently, but keeping the time step constant.

#

I think you should be able to do this by scaling the relative speed of Time<Virtual>, which would then advance Bevy's virtual time faster or slower, causing schedules like FixedUpdate to also run more or less frequently πŸ€” with this approach you don't have to touch physics scheduling at all

#

Of course the caveat is that this also affects how frequently your own systems run inside FixedUpdate, which may or may not be desirable

#

Alternatively you could set up some custom scheduling that runs physics at its own fixed time step independent of Bevy's fixed updates

#

Note that in slow-mo, the fixed time step will be exaggerated, so you will need transform interpolation to keep movement looking visually smooth

past cargo
vestal minnow
past cargo
vestal minnow
#

Yeah that shouldn't affect Time<Fixed> determinism-wise since the delta time in that is always fixed

#

I believe that issue is primarily just that even if you had well over 60 fps, and had vsync enabled to lock Bevy to the display frame rate, you wouldn't get 0.016666... ms every frame even though you technically should

#

That affects Time<Real> and Time<Virtual>, which in turn also affects how often FixedUpdate runs, but the actual fixed delta time in Time<Fixed> should still be truly fixed

sweet sundial
#

remember, Res<Time<()>> gives the current schedule timer

bleak wadi
#

is there any way to prevent bumps with tiles of colliders?

visual sparrow
#

Sorry for the vague answer, but I never use tiles, so I don't run into this. But I believe that is the term you'll want to search for on Discord πŸ™‚

bleak wadi
#

lmao there was someone right there with the solution to my problem, and i didnt even notice!

#

idk what tunneling is

bleak wadi
#

i can selectively enable speculative collisions right? i can probably just disable them for characters and enable them for projectiles

visual sparrow
#

But again, I don't have any first hand experience with how to deal with ghost collisions in practice 😬

bleak wadi
#

maybe that wasn't the best idea lol

#

it's ok, the bumps aren't really noticeable

#

my main problem was that i wasn't handling angles of -180

#

which is identical to 0 obviously, but my code did not realise that

minor sandal
#

I've been thinking around and wondering why physics engines are always using floating points.

Wouldn't it make sense to scale at compile time and use fixed point so the extra 8 bits of floating point mantissa are use for increased resolution/playground size?

That would lead to over/underflow errors at the boundaries, but wouldn't mean a more powerful physics engine within those boundaries?

past cargo
#

like 1000 mileseconds

#

etc

#

instead seconds

#

it will always take miliseconds for stuff, never less than that

#

so far i remember godot haev a GetMSecs() stuff

#

it return a longint

minor sandal
#

I mean for all the positional computing. I meant all the vectors to be fixed points.

minor sandal
#

Locally deterministic but that is not the point.

I'm talking about the data type for vec2/vec3 being a float32.

I was thinking of why use float32 instead a a fixed point.

vestal minnow
# minor sandal I've been thinking around and wondering why physics engines are always using flo...

The only compelling reason to use fixed point (that I'm aware of) is that you get the same precision regardless of the distance from the origin and can therefore get identical results regardless of where in the world the simulation is run. But this is very rarely needed for game purposes, and f32 is enough for pretty good results even when you're farther than 10 km from the origin. We (and many other engines) use constraint anchors that are relative to body positions, and collision detection also happens in body-space (excluding the broad phase, but accuracy is less important there), so those computations are always pretty accurate. Excluding edge cases like if you had a single collider that's massive, but that's usually a bad idea anyway.

#

The main problem with fixed-point math is that it's just much slower and more tedious to work with. I suspect that effective vectorization via SIMD would also be more difficult, and you'd at least need to develop your own math library from scratch for this. I'm not aware of any vectorized fixed-point math libraries, at least in Rust

#

People often say that you need fixed-point math for cross-platform determinism but that's just straight up not true. Avian, Rapier, Box2D, and some other engines all support cross-platform determinism despite using floating-point math.

minor sandal
#

That makes sense.

I was thinking of that mainly for some sort of space game that had sparce entities over large areas.

#

But yeah 10km from the origin already gives a lot of leeway especially when you can scale it to your needs.

#

I mainly came over to ask the question to people who knew more than I about physics engines.

minor sandal
vestal minnow
#

Yeah, and we do also support f64 if you need it (though we'll probably rework this later to only use f64 for stuff like positions and not literally everything). In the future I do also want to support big_space which would make physics work at ridiculously large scales

minor sandal
minor sandal
vestal minnow
#

This is an improvement by itself, but is also important for the wide SIMD stuff

#

I'll probably update the force rework PR first before doing wide SIMD though, hopefully get it in a mergeable state

visual sparrow
vestal minnow
#

Here's a benchmark against Glam's Mat3

#

Glam also has a Mat3A that is aligned for SIMD at the cost of taking even more data and being more expensive to construct. SymmetricMat3 is still faster than that for most important operations, like inverse and transforming vectors

#

Additionally, this makes SolverBodyInertia 32 bytes instead of 44 in 3D, which is nicer

#

And for wide SIMD scatter/gather stuff we will want the data to be minimal for maximum efficiency

#

Also it's just nice to enforce symmetricity for the inertia tensor at the type-level since an asymmetric inertia tensor would be wrong

#

(more accurately the inertia tensor should be a symmetric positive semidefinite matrix, but enforcing it to be positive semidefinite is more annoying and costly and probably not worthwile)

vestal minnow
#

Hmm... a mildly scuffed way we could support an efficient iteration API with the ForceHelper stuff is to simply expose a public RigidBodyForces query data that has the components used by the force APIs, so you can do something like this:

fn apply_forces(mut query: Query<RigidBodyForces>, mut force_helper: ForceHelper) {
    for rb_forces in &mut query {
       force_helper.get(rb_forces).apply_force(Vec2::new(0.0, 10.0));
    }
}

as an alternative to the usual API:

fn apply_forces(query: Query<Entity>, mut force_helper: ForceHelper) {
    for entity in &query {
       force_helper.entity(entity).apply_force(Vec2::new(0.0, 10.0));
    }
}

This would also trivially work with parallel iteration without any separate APIs on the ForceHelper, which @little maple was asking about earlier

#

But there is a small weirdness factor and you might wonder why you can't use RigidBodyForces directly for applying forces and need to also use the ForceHelper

#

The nicest API would still be this

fn apply_forces(mut query: Query<RigidBodyForces>) {
    for forces in &mut query {
       forces.apply_force(Vec2::new(0.0, 10.0));
    }
}

But it requires either

  1. Somehow storing and applying a command buffer on RigidBodyForces to add missing components (not supported by Bevy yet)
  2. Accepting that we store an additional six or nine vectors on every dynamic body
little maple
past cargo
vestal minnow
#

The tradeoffs are

  • We'd need to store an extra 12 bytes in 2D or 24 bytes in 3D per dynamic body, for local acceleration
  • The force methods would immediately turn forces into acceleration rather than storing forces separately. This means that torque ignores changes in the inertia tensor between substeps (which should be probably acceptable) and also if you apply more than one force to a body at once, you'd pay the cost of applying the mass props for each individual force
past cargo
#

What are the plans for 0.4?

vestal minnow
little maple
#

I'm pretty biased where I care more about the parallel iteration than the amount of byte space.. I haven't really run into memory bottle necks πŸ€”

#

but.. I get that's important for something like this

vestal minnow
#

Yeah definitely, memory isn't really too critical here, in general I just want to try my best to avoid storing potentially unnecessary and unused data on all bodies (or dynamic bodies in this case) if it can be avoided

#

24 bytes is definitely fine tho

vestal minnow
#

Also more progress on the joint rework, but that might be delayed until the next cycle again because there's still more experimentation I want to do to make it good

#

I could probably get the impulse-based joint stuff ready for 0.4 if I dropped everything else, but then there's also the AVBD stuff which would be really interesting to explore more for joints, it just requires a lot more research and work to make it actually usable for our purposes

summer acorn
#

you're a beast

#

i want everything you're making lol

vestal minnow
#

start contributing 😈

#

(and thanks πŸ’š)

cinder summit
#

Wait is the only thing on that list that you aren't doing entirely alone the BVH-related stuff? πŸ€”

vestal minnow
#

uhh yeah lol

#

Jan did caching for collider constructors

silk mauve
#

Medium related to Avian specifically but thanks for making bevy such an exciting engine to work with. Between Unity's various controversies (not to mention the seemingly random creation and abandonment of new crates) and Unreal engines clunkiness/performance regressions it's crazy to work in an engine that just seems to get better and better. Thank you for being such a big part of it getting better!

vestal minnow
#

I need an Alice to manage the issues and other peoples' PRs

#

I'm not exactly doing a great job at responding to issues unless they're particularly interesting or related to something I'm working on bavy

#

At the start of the project I was responding to everything and fixing things regularly but nowadays I've kinda slipped from doing that as much

#

I just want to focus on the shiny big things lol :P

#

maybe I should do something similar to Alice's weekly merge train except it's me going through issues and fixing trivial problems and responding to stuff

silk mauve
#

Every dev needs an Alice

#

Alice probably needs an Alice

cinder summit
#

Alice is the only person that functions without an Alice

silk mauve
#

Makes sense. Can't have infinite regressions

visual sparrow
#

You're pretty good at responding to those IME haha

vestal minnow
#

yeah do ping me here about issues and I will respond :P

#

it's just responding on GitHub that I suck at lol

#

-# and emails, sorry to all the companies and people who have still not heard back from me

foggy storm
#

What collider should I use for a plane in 3D? Looks like Plane3d starts from the origin which is not what I want. Polyline3d<4>?

#

Maybe plane is the wrong word. Not an infinite plane.

vestal minnow
#

That would be a trimesh, a convex hull, or a thin cuboid

#

If you have a plane mesh then you can also use ColliderConstructor::TrimeshFromMesh to auto-generate it

#

If you did want something like an infinite ground plane, you'd probably want Collider::half_space

foggy storm
#

I have two points in X/Z. I'm creating two more points by shooting up a bit in Y. Those are basically the four points I want to create it from.

vestal minnow
#

Yeah I would probably use a trimesh for that

#

I'm not entirely sure what Collider::polyline actually does in 3D πŸ€” Parry supports it but I don't remember what it's like for 3D

foggy storm
#

At what speeds and sizes would I start seeing tunneling? Would a car traveling at 350km/h tunnel?

vestal minnow
#

The main cause of tunneling is small objects being pushed through geometry by other objects due to contact softness

foggy storm
#

Yeah last time I looked at that demo I remember Avian being incredibly good at avoiding tunneling (unlike other engines I've tried). Might be best to opt for a cuboid though. It's an invisible component anyway so it can be a bit thick.

vestal minnow
foggy storm
#

I just wanted to avoid the normal calculation because I'll probably mess it up :p

vestal minnow
#

Graph coloring (which we have on main) has the added benefit that we can leave some colors fully dedicated for contacts with static bodies, so we can actually solve dynamic-dynamic contacts first and dynamic-static contacts last, which gives higher priority to contacts against statics

foggy storm
#

I'd want to avoid CCD anyway because I need the CPU for a bunch of other stuff. I prefer a lightweight solution this time.

#

Btw, CollisionEventsEnabled and RigidBody::Static do they lead to different things?

vestal minnow
#

Wdym? CollisionEventsEnabled just lets you get CollisionStarted and CollisionEnded events for a collider

foggy storm
#

Ah right. Yeah it says so in the name :p. I just saw an example that didn't a rigidbody and just CollisionEventsEnabled. For a sensor do I not need a rigidbody?

vestal minnow
#

You don't, yeah