#Avian Physics

1 messages Β· Page 32 of 1

cinder pilot
#

nvm we're good I figured it out

#
            commands
                .entity(entity)
                .insert((RigidBody::Static, NoTransformEasing))
                .with_child((
                    Collider::ellipse(25.0, 25.0),
                    Transform::from_xyz(-50.0, 0.0, 0.0),
                ));
#

(spawn collider as child)

sleek thicket
#

oh yeah derp, i forgot sprites don't have origins

willow elbow
#

Hello, how do I get the global coordinates of an existing Collider's vertices?
This collider.shape_scaled().as_convex_polyhedron().unwrap().points() returns always the same numbers regardless of its position in space.
Thanks

vestal minnow
#

(we convert the transform to an isometry because we don't want to apply scale, since shape_scaled already includes scale)

bold garnet
#

Work stealing will help speed up transform propagation & any highly divide-and-conquer algorithm.

vestal minnow
#

Trying to get no_std Avian running, this is fun

#

Firstly we'll need to copy bevy_math's ops module for f64 (I suggested having this first-party in the original PRs...)

#

Secondly I think we might be blocked on Nalgebra of all things ferris_spooky

cinder summit
vestal minnow
#

Which means we need to either fix this upstream if possible, or implement our own conversions

cinder summit
#

Even more reasons to work on bevy_peck

#

I was going to say "But at least we can no_std with SDF collisions", but that needs bevy_asset which requires std for std::io and std::path ferris_sob

vestal minnow
#

Right now it changes basically everything to f64 but it's only really relevant for specific things

cinder summit
#

With big_space support or alike I'm honestly not even sure what it would be good for anymore

#

I guess maybe insane amounts of substeps, but then avian isn't really made for scientific uses and I'm not sure why games would do that to their FPS πŸ€”

vestal minnow
#

I think large and small masses might be problematic with f32 atm

vestal minnow
#

πŸ‘€

#

need to fix Nalgebra still

vestal minnow
#

Okay it seems like Parry is actually insanely reliant on std right now, for some reason

#

Almost half of the shapes are gated behind std

#

hhh I guess I'll see if I can properly no_stdfy Parry

#

(fyi @surreal rune)

#

Parry is the main blocker right now, otherwise I should have no_std Avian working

sweet sundial
#

what's the second most popular collider crate?

surreal rune
#

But that's still very cool that Avian's own no_std support came so quickly. I reckon a lot of the Bevy ecosystem could be ported (bar assets and rendering of course)

vestal minnow
#

Or my crate Peck #showcase message but the repo is even public yet πŸ˜›

#

There aren't really any other major collision detection crates that I'm aware of, apart from Parry

#

There's NCollide but that's just Parry's predecessor

vestal minnow
#

There's like over 240 occurrences of feature = "std"

surreal rune
vestal minnow
#

What is this in Parry thonk

#[cfg(all(feature = "alloc", not(feature = "alloc")))]
#[cfg_attr(test, macro_use)]
extern crate alloc;
vestal minnow
#

Also it does this πŸ€”

#[cfg(not(feature = "alloc"))]
extern crate core as std;

I can't tell if I like this

surreal rune
#

Yeah I hate that. IMO it was a mistake for Rust to re-export core in std

vestal minnow
#

yeah

surreal rune
#

Problem is they're slowly moving things out of std and into core and they can't break backwards compatibility.

#

But yeah, libraries should just use core there's no harm

sweet sundial
#

there's a clippy lint for it

surreal rune
white garnet
#

when using ExternalImpulse is my understanding correct that the entity that gets this component .inserted to will be "bumped" ?

kind moss
#

Does anyone have any advice on how to reduce compile times when using avian? A modestly complex bevy project without physics takes 1-3 seconds to do incremental debug compilation but my project that uses avian, even if I remove basically every other dependency and strip my own code down to almost noting, is over 1 minute. I know that Jondolf has said that replacing parry may eventually help but is there anything folks are doing currently?

#

Cranelift helps some but not a huge amount.

light vessel
light vessel
#

welp thats all i got sorry

kind moss
#

Thanks. It's a good suggestion but not the specific problem I have unless I've broken it somehow but that doesn't seem to be true.

bold garnet
kind moss
# bold garnet are you using rust analyzer?

I am but I don't believe it's invalidating my build, if that's your suggestion. Only my actual package seems to be building. When I do --timings it only shows my package.

#

I found a dependency that was bringing in a second version of bevy. Thought I'd already removed that. We'll see if that was the issue.

#

Yeah, I think that was my problem. That seems to have brought me back down to 4ish seconds, which is fine.

#

Though why that would add nearly a minute to the compile time is confusing to me. But clearly has nothing to do with avain.

sweet sundial
#

might be that one of them didn't have dylib

kind moss
vestal minnow
#

@surreal rune I think I might've gotten no_std Avian and Parry working! For Avian it's on the no-std branch

surreal rune
vestal minnow
#

Nope, bevy_math uses Glam 0.29

surreal rune
#

Ahh ok. I'm hoping to get that feature backported to 0.29.3 next week!

#

Just to cover us until we can update to 0.30 at least

vestal minnow
#

Cool, that'd be nice

surreal rune
#

I see 0.16 having some teething issues as we work out exactly how to make the experience the best and get dependencies on board, but it is happening...slowly haha

cinder summit
vestal minnow
vague pebble
#

I know this sounds weird but a function similar to look at with rigidbodies, that works via angular velocity. Would be pretty cool

peak marsh
vestal minnow
#

spade is the crate that Parry uses for Delaunay triangulation

peak marsh
vestal minnow
#

It's just a way to conditionally enable std for spade if spade is enabled

#

If you did spade/std, it'd unconditionally enable spade itself too

vague pebble
#

Just a quick question, is this the correct way of calculting an ang_vel. Given a certain yaw? Also anyone knows how to get rid of tab spaces in discord code

 
      if let Some(yaw) = action.axis_data(&PlayerInputs::RotateTo) {
            let new_rotation = Quat::from_rotation_y(yaw.value);
            let delta_rotation = new_rotation * rotation.conjugate();
            let desired_ang_vel = delta_rotation.to_scaled_axis() / time.delta_secs();
            info!(?desired_ang_vel);
            ang_vel.0 = desired_ang_vel;
        }```
chilly cradle
#

This is more of a rust question than an avian question, but I'm implementing it for a Avian-big space plugin so I'll ask it here

#

Is there a nice way to "inherit" the SyncPlugin and only overwrite the bits that I need to get integration with big space working?

#

Or do I need to make a complete duplicate of SyncPlugin into a unique struct/impl and implement both the things that need to be changed to integrate with big space and the bits that don't?

#

Not a massive pain either way, just thought I'd ask first

opaque temple
#

Are LockedAxes something that can be used to keep a player-controlled spaceship stabilized on the horizon whenever pitch/yaw are applied?

sweet sundial
#

dynamically applying them?

spiral nymph
opaque temple
#

I mean, if Avian is performing the rotation (based on angular impulse for example), can it satisfy these requirement during rotation:

  • no gimbal lock
  • full smooth 360Β° rotation along X and Y (no invisible walls or weird instabilities at singularities/poles)
  • no rolling around Z, meaning keep the object level on the horizon (XZ plane)
#

...which is something needed for swimming or flight sims

sleek thicket
#

so basically you're asking if it's local or global lock? i'm assuming it's global, but i never actually tested πŸ€”

bold garnet
#

The last one is, in as far as it’s a constraint. I imagine that should be pretty easy.

vague pebble
#

And from what I saw no problems with collision

opaque temple
bold garnet
opaque temple
sweet sundial
#

how are you making the delta rotation exactly?

opaque temple
# sweet sundial how are you making the delta rotation exactly?
let q_pitch = DQuat::from_axis_angle(DVec3::X, input.pitch * dt);
let q_yaw = DQuat::from_axis_angle(DVec3::Y, input.yaw * dt);
let q_roll = DQuat::from_axis_angle(DVec3::Z, input.roll * dt);
let q_combined = q_pitch * q_yaw * q_roll;
ship_ct.transform.rotation *= q_combined.as_quat();

input.roll is always zero

sweet sundial
#

yaw should be before pitch, i think

#

unless quat multiplication is actually commutative

opaque temple
#

The Z-roll accumulates either way

sweet sundial
#

could also do transform.look_to(Vec3::NEG_Z * transform.rotation * yaw * pitch, <up>)

opaque temple
#

Vec3 cannot be multiplied by a Quat. Did you mean Vec3::NEG_Z.rotate(transform.rotation) ? Or something else

vague pebble
#

Are you trying to make an airplane controller? If so here is my approach on how to rot via yaw, perhaps you can apply the same to your pitch and roll logic.

       if let Some(yaw) = action.axis_data(&PlayerInputs::RotateTo) {
            // Handles rotation
            let new_rotation = Quat::from_rotation_y(yaw.value);
            let delta_rotation = new_rotation * rotation.conjugate();
            let desired_ang_vel = delta_rotation.to_scaled_axis() / time.delta_secs();
            ang_vel.0 = desired_ang_vel;```
sleek thicket
#

you'll probably need to do it to clamp pitch/roll anyway

little maple
#

if I'm doing things correctly, the game shouldn't slow down if the framerate drops, right?

grizzled depot
crimson crest
#

Has anyone made progress on kinematic character controllers beyond just what my draft PR has?

#

I'm likely not going to be active in game related stuff quite a while (irl job + other responsibilities) so I'd rather someone else take over that task

sweet sundial
#

does tnua not work?

smoky crane
#

is it possible / good idea, to rotate the collider here to simulate the fox going down the slope ?

sleek thicket
smoky crane
#

Nice, and I can parent them to the bones I guess

#

But how to make them work in avian? Is there any example showing something similar?

#

Mine is based on the dynamic character example

sleek thicket
smoky crane
#

Tnx, I’ll do some research

sleek thicket
smoky crane
#

Ohh would be amazing 🀩

sleek thicket
spiral nymph
#

Wow really satisfying, must've been a lot of work

little maple
#

even with all the visual bugs I'm like "wow that looks awesome"

rough nebula
#

hello, is anyone else using avian in the candidate branch? ive been having issues trying to despawn entities with physics components

vestal minnow
#

Are you using the latest main? I fixed a despawn panic issue 2 days ago

rough nebula
#

i believe so

vestal minnow
#

What's the error/panic/issue you're seeing?

rough nebula
#

ok just a moment i lost the message now and i am stuck in compile hell :/

kind moss
#

I've been using it but I think the only time my code despawns may be when StateScoped kills things, which is the crash Jondolf fixed.

spiral nymph
#

Is there a half cylinder shape ? I want to shapecast a sword attack

crimson crest
rapid delta
#

Hi and thanks for the great plugin! I have a problem with a 2D static body and its friction. I'm trying to build a sort of a slowly rotating planet that objects react to. So I have a pretty big circle collider that slowly rotates. All fine and good, objects fall to its surface. But as this sprite rotates, the objects stay put, as if there was no friction. I've added the Friction to both the object and the planet.

vestal minnow
rapid delta
#

Wow, thanks for the super fast reply!! Kiitos!

vestal minnow
#

Ei mitÀÀ, happy to help πŸ˜„

#

Oh and btw velocity won't actually work if the circle is a static body (since it's... static) but you can make it a kinematic body in this case

rapid delta
#

Worked like a charm, thanks!

kind moss
#

@vestal minnow I have the changes needed to move to rc.2 if you want them. I'm not going to do a PR because I assume that looking at it will take you longer than making the changes yourself (it's like three trivial things for avian2d) but I can if it's helpful.

tulip plaza
#

The elevator physics components look like:

commands.entity(mesh_entity).insert((
    ColliderConstructor::TrimeshFromMesh,
    avian3d::prelude::RigidBody::Dynamic,
    avian3d::dynamics::ccd::SweptCcd::LINEAR,
));

And the cube:

commands.spawn((
    avian3d::prelude::RigidBody::Dynamic,
    avian3d::prelude::Collider::cuboid(1.0, 1.0, 1.0),
    Mesh3d(meshes.add(Cuboid::default())),
    MeshMaterial3d(materials.add(Color::srgb(0.8, 0.7, 0.6))),
    bevy::prelude::Transform::from_translation(position).with_scale(Vec3::splat(64.0)),
    avian3d::dynamics::ccd::SweptCcd::LINEAR,
));
#

I think one issue is that I'm updating the transform not the velocity? ferris_Hmm

glacial nebula
tulip plaza
sleek thicket
cinder summit
#

@vestal minnow have you looked into a parry/Collider agnostic spatial query pipeline? I'm currently faced with having to rewrite all my spatial query stuff, and it makes me wonder if it would be possible to upstream something πŸ€”

vestal minnow
# cinder summit <@545959292281552928> have you looked into a parry/`Collider` agnostic spatial q...

I've thought about it, but haven't started on a proper design. It'd probably be something like this?

// Convenience alias to keep the current API
#[cfg(any(feature = "parry-f32", feature = "parry-f64"))]
pub type SpatialQuery = SpatialQuerySystemParam<DefaultSpatialQueryPipeline>;

// Generic SystemParam for spatial queries
#[derive(SystemParam)]
pub struct SpatialQuerySystemParam<'w, 's, Pipeline: SpatialQueryPipeline> {
    pipeline: ResMut<'w, Pipeline>
}

// Trait for spatial query pipelines
pub trait SpatialQueryPipeline: Resource {
    // ...all the spatial query methods
}

Updating the pipeline would probably be handled from the outside for each pipeline since it might not generalize properly, not sure

#

(I need to go offline for a few hours now)

tulip plaza
vague pebble
#

Any ideas on how I can dampen up a dynamic rigidbody that constantly rotates and shifts it is linear velocities?

sweet sundial
#

there're angular and linear damping components

junior oar
#

Seems like main currently won't compile for new projects (or the examples) against bevy 0.16.0-rc2?

vestal minnow
#

We really should try making CI faster somehow πŸ˜… the tests take ages to compile

vestal minnow
#

Damn, that was fast

sand smelt
#

haha, I was like "I know how to do that"

vestal minnow
#

I feel like I've tried caching at some point πŸ€” idk where that is though so maybe not

sand smelt
#

It's the only real way to speed up CI except for using custom runners. It can be tweaked quite a bit (e.g. different architectures or RUSTFLAG shouldn't share cache), but I think these are simple enough that it will just work

vestal minnow
sand smelt
#

I can use that one instead

#

Hmm bevy also sometimes has multiple target folders, so they need to tweak it anyway

vestal minnow
#

eh you can keep the rust-cache one too, it seems pretty popular so it should be fine

#

either one is fine for me as long as it works πŸ˜›

sand smelt
#

Then I'll just keep it. But why doesn't main compile for me πŸ€”

vestal minnow
sand smelt
#

oh right, semver

vestal minnow
#

started 27 28 29 30 31 32 33 34 35 36 minutes ago...
edit: god damn how many times do I need to update this

sand smelt
#

Windows is also just ridiculously slow, I thought the "rust compilation is way too slow" was a bit of a meme until I tried it on windows

vestal minnow
#

okay it merged, I updated your CI PR

sand smelt
#

Gonna be just as slow now, but hopefully faster for next PR

vestal minnow
#

yeah

light vessel
#

When using TranslationInterpolation/Extrapolation with Avian, does it work if we only modified LinearVelocity within FixedUpdate? Or should we instead be modifying transform directly? I've seen it discussed that modifying transform directly would cause collisions to stop working because it is essentially teleporting.

vestal minnow
#

Transform interpolation/extrapolation should work with both modifying velocity or the transform directly in FixedUpdate. But interpolation is purely visual, it doesn't affect behavior within FixedUpdate

light vessel
#

Yeah that part makes sense, just cant seem to get rid of screen tearing/jittery movement no matter how I configure it but ill keep tinkering with it, thanks!

vestal minnow
# vestal minnow Transform interpolation/extrapolation should work with both modifying velocity o...

Changing the transform directly can be fine in some cases, but it is like teleporting and therefore isn't considered by physics in the same way. This means that:

  • the whole movement is applied at once instead of over several smaller substeps
  • it can be easier to get more overlap as you're "teleporting" into other objects
  • friction and restitution won't take the movement into account (since there is no new relative velocity)
  • Continuous Collision Detection (CCD) may not consider the movement properly
vestal minnow
light vessel
#

I assume you just mean the Transforms of the RigidBody entities specifically? What about if we mutate it once for say, changing location upon entering a new level?

vestal minnow
light vessel
#

Okay yup that makes sense, thanks again!

kind moss
#

What's the new correct way to do child colliders? They get ColliderOf but should they also be ChildOf the RigidBody?

#

(neither seems to work for me but with different failures so I'm trying to work out what's wrong)

vestal minnow
#

It should be the same as before, children of rigid bodies should automatically get ColliderOf pointing to the parent rigid body. But theoretically it should also be possible to have a non-child collider point to any rigid body too I think

kind moss
#

Oh... hmm. I don't think that's what I'm seeing but I've probably broken it myself.

vestal minnow
#

I need more tests for child colliders though, it's very possible there are bugs

kind moss
#

The thing I'm having trouble with is a rather convoluted tool that adds colliders and rigidbodies to gltf models so it's also likely that I have bugs.

#

Specifically, I'm not necessarily creating the rigidbody component and the collider components in the same tick. Would that could a problem with your systems setting things up?

vestal minnow
#

The examples in the repo like collider_constructors and dynamic_character_3d use child colliders loaded for glTF scenes, and work normally

vestal minnow
#

I should be able to fix that though if that's the case

kind moss
#

Yeah, should always do bodies first and then colliders in the next tick

vestal minnow
#

Hm, seems like that's broken yeah nvm my test scene itself was broken lol

kind moss
#

Or... no. I think there's a case where I can go the other way.

#

Which makes sense, I think. Because it's clearly working sometimes and not others, which would make sense if stuff was just happening out of order for some models.

#

Ok, now I'm pretty sure I'm only making colliders if the body has already been made and I still see problems. Some colliders behave as expected but others seem to end up at a global translation of (0,0). They're in the scene and in the correct offset relative to their parent, if the parent was at (0,0) but it's not. And I don't think they are translating or rotating in sync with the body.

#

Yeah, they are not moving.

#

I have cases where the same body has multiple child colliders and some work but others don't. And... well actually this other case isn't a child collider. The collider is on the same entity as the body but it is also not working, in the same way.

#

Ok, I need to go back and rewrite some of this code. I'm not confident it's doing what I think it is so there's a very high probability that this is all my bug. I have to go do something else now but I'll let you know if it turns out to all be a false alarm.

vestal minnow
#

I think there's definitely something wrong on the Avian side currently, I'm also getting some weird results

kind moss
#

I guess this is what a release candidate is for.

light vessel
#

LOL im so dumb my YSort was modifying Z values every frame on transforms in the Update schedule. I wish bevy had proper 2DTransforms.. One more odd issue: Is it normal for colliders to flicker occasionally and lag-behind when moving their rigid body via LinearVelocity? It is a little hard to see in this video but I figured the collider transform prop would be unnoticeable.

vestal minnow
vestal minnow
#

Are you using child colliders?

light vessel
#

Yes each of the 3 colliders are children (bevy 0.15) , 2 sensors and one for physical collisions

vestal minnow
#

The lagging behind might be because collider positions are only updated before physics, and so after physics, when debug rendering happens, the positions may be outdated

#

But for the actual physics simulation they should be up-to-date

#

I could probably fix this though

light vessel
#

yeah i havent noticed any gameplay ramifications so that would make sense, was mostly a curiosity. Thanks for all the support!

kind moss
vestal minnow
#

still not great of course, but a significant improvement

surreal rune
oak vigil
#

Hey, I'm observing a weird issue in my game:

I have two entities, a sensor and a subject (with a collider). When the subject is a root entity (no parent), my sensor detects it fine (via CollidingEntities). All is ok.

If I attach the subject to the sensor's entity hierarchy, the subject is no longer in CollidingEntities. This is expected since now the collider is part of the same hierarchy as the sensor collider. All is ok.

But then if I detach the subject from the sensor hierarchy (i.e. remove_parent), suddenly my sensor doesn't detect the subject anymore (i.e. CollidingEntities is empty, even though the sensor is clearly colliding with the subject based on debug render). Is this a bug, or am I missing something?

oak vigil
#

Is there something I need to do to update physics hierarchy after detaching an entity...?

oak vigil
#

So I think I found the root cause. My subject doesn't have a RigidBody. But if I add a RigidBody things get strange when I attach the subject to the sensor (since now they're nested Rigid Bodies).
I've managed to solve it so far by manually inserting/removing the Rigid Body when the subject is detached/attached, and that seems to work.
Let me know if there is an easier way! πŸ˜…

cinder summit
# vestal minnow I've thought about it, but haven't started on a proper design. It'd probably be ...

I think as long as we provide the relevant context we can probably make filling the pipeline generalizable ... The bvh just needs to have AABBs, entities and layers for each each "primitive" ... Looking at obvhs I'm not entirely sure if it has everything necessary for efficient traversal, there is ray traversal and aabb traversal so you can probably implement all features but I doubt the traversal order would always be optimal πŸ€”

#

Oh and speaking of context, I realized mass properties don't get context ... I'm not currently sure how I would handle calculating mass properties for SDFs anyway so I'm not too concerned atm, but that's probably something that needs to be addressed (also worth considering that mass properties might just grab processed data from other resources, so it might not need the same Context either)

#

Back on the topic of the spatial query stuff ... It's also worth considering how components like RayCaster and the like handle the different BVHs, especially when it's possible to have multiple collider types in a world

vestal minnow
cinder summit
#

Yea that's kinda what I'm thinking too. I can essentially just estimate it by treating it as voxels + potentially some extra accuracy by moving towards where a surface is, though that has some limitation with bound colliders, though I'm not sure if I can even support those yet

vestal minnow
cinder summit
#

Yea I guess that could work ... I wonder how we would decide which hits to keep though πŸ˜‚

vestal minnow
#

The closest hits within max_hits probably

#

Or yolo, random order each time

cinder summit
#

ShapeCaster should be easier though, it takes a shape so it needs generics anyway

trim barn
#

Hi, is there an event for detecting collisions? I want to detect collision between the player and enemies, and give a special "dizzy" tag to the enemy when it is it by the player.

vestal minnow
#

I sure am happy I don't need to go through the Bevy review processes for these right now πŸ˜‚

#

I'll have the optimizations for contact constraint generation in a follow-up

chilly cradle
#

Also works in 3D (which is where I'm using it)

vestal minnow
cinder summit
#

Sounds like a free speedup to my SDF collisions

vestal minnow
chilly cradle
cinder summit
#

Then I just pass mutable references to that around

vague pebble
#

question how do i get a collision normal? In my character controller if I continously apply a force into a wall, it glues to it. I guess i need to rebacle with a contact normal or something like that

#

Ah just read the docs, friction is a global thing

vestal minnow
#

How would people feel about renaming

  1. Contacts to ContactPair
  2. Collisions to ContactGraph
#

The first one I'm fairly confident about, since the current name Contacts is pretty ambiguous (all contacts? contacts between two entities? contacts in a specific manifold?) and the code and methods already refer to "contact pairs" a lot. Rapier also uses ContactPair

#

Though just Contact could also make sense, and then we just say that a contact consists of one or more ContactManifolds πŸ€” I think Box2D also uses b2Contact

#

Collisions is a bit weird since the new version also stores non-touching contacts, and only AABBs need to overlap. The term "Collision" sounds more like there's an active hit happening. Having "Contact" in the name would make things more consistent and clear imo, so ContactGraph (a graph structure storing contacts) would make sense

#

It is arguably more "intimidating" for users, but I would also consider it to be a more advanced API anyway, so it could be considered a good thing. I'm a bit conflicted there

cinder summit
#

The only interaction I've ever had with that resource is registering it for rollback ... Renaming it to ContactGraph would make that no more or less confusing πŸ€”

sleek thicket
#
  • for #1, no idea about #2
vestal minnow
#

I do like the consistency of "ContactGraph stores ContactPairs, which store ContactManifolds, which store ContactPoints"

#

As opposed to 0.2 and earlier where it's "Collisions stores Contacts (for each pair), which store ContactManifolds, which store ContactData"

sleek thicket
#

contactpair definitely makes sense to reduce confusion for people coming from other engines where contacts are per object

cinder summit
#

Especially when a ContactPair might not even be touching

vestal minnow
#

I almost feel like we want a low-level ContactGraph resource, and some helper system parameter to abstract over the details like the fact that the graph also contains non-touching contact pairs

little maple
vestal minnow
vestal minnow
vestal minnow
little maple
vestal minnow
#

This is that branch

#

but it doesn't have the contact constraint generation optimizations or solver body stuff, I have those on different branches

little maple
#

lol sorry, right

vestal minnow
#

the solver body stuff would give the biggest immediate performance win, but I'm not sure how to make it neatly work with our XPBD joints, so I need to either hack some temporary workaround together or just... finish reworking our joints πŸ™ƒ

cinder summit
#

The latter sounds good

vestal minnow
#

so you wish to delay good performance by another six months /s

cinder summit
#

BTW @vestal minnow, would you be open to a PR to make the spatial query stuff generic over colliders? And if yes, should that be obvhs powered or keep using Qbvh for now? Making that code generic and making an impl for non-parry colliders seems pretty doable ... It's gonna be a big PR though

#

Like damn the spatial query code in avian is big compared to the tiny file I had in my old spatial query stuff πŸ˜‚

vestal minnow
#

I would be open to that yeah, and using OBVHS would be great assuming it can be made to work for all of the different types of queries, and performance is roughly the same or better

#

I will probably need to rework some of it for the broad phase rework though, for that the plan is to have at least two BVHs (one for dynamic and kinematic bodies, one for static and sleeping bodies), and it would be shared between the broad phase and spatial queries

#

Colliders would be added/removed from the BVHs via the insertion/removal stuff Griffin has been implementing, and it'd probably rebuild the dynamic body tree in parallel with the narrow phase or some other part of the simulation (I think that's what Box2D does) to keep the tree quality good

cinder summit
#

Is the broadphase currently per-AnyCollider or universal?

vestal minnow
#

It's the same for all collider types currently, just uses ColliderAabb

#

But the AABBs themselves are updated per-AnyCollider

#

By the ColliderBackendPlugin

#

(brb)

cinder summit
#

Hmmm ... I guess we have two approaches we could take there:

  1. Make the broadphase per-collider, so the BVHs can be per-collider
  2. Make the BVH generic by only putting AABBs in them and a ComponentId or the like of the AnyCollider impl
    Downside of 2 is that 2 collider components on 1 entity doesn't work. Downside of 1 is some extra overhead when multiple collider types are registered
vestal minnow
#

idk when you would be using several different collider backends at the same time anyway

#

maybe if you had both 2D and 3D, but each dimension would probably have its own broad phase

cinder summit
#

Yea dimensions would definitely be split ... But I can imagine there might be people that want say SDF collisions, but also stackable boxes (which would be slow arbitrary SDF-SDF collisions over in SDF land)

#

But yea idk about putting them on the same entity ... Maybe if you have stackable boxes you'd need the player to have both collider types so you can still collide with the boxes ...

#

But child colliders would also be fine in that fairly niche case

#

They might be on different collision layers and whatever anyway

vestal minnow
#

yeah

#

either trade-off is fine for me, whatever works best for the general case

#

having multiple collider backends at once feels like such a niche case that I wouldn't worry too much about it being perfectly supported for now, as long as it's technically possible

vague pebble
#

Okay, simple physics problem that I am stupid too solve. Lets say, I have Vec3 (0,1,0) at a step slope that I always have the information of (normal via shape cast) in this case the slope is 45 degrees, at tick 0. For what factor must I multiply to ensure that when I climb that slope, my y distance doesnt shift meaning in tick 1 I should be at (1,1,0)?

#

Case scenario: As the video shows, I want to avoid this Y axis jiggling from my floating character, when climbing slopes. Caused due to the distance change from the shape cast from tick 0, to tick 1

cinder summit
vestal minnow
#

I have some of it roughly implemented, but it probably won't be ready for 0.16 at least

#

hopefully early-ish in the 0.17 cycle

umbral kelp
#

What is the best way to sync position of a dragged object to mouse position with physics?
I did a workaround setting translation to mouse position and then simulating forcefields around the objects.. which works, but I'm kinda implementing physics from scratch again then? especially when I want to have joints next..

vestal minnow
#

2D or 3D?

umbral kelp
#

2d

vestal minnow
umbral kelp
#

ah so have a joint dragging it to the mouse position.. that's smart

#

I thought about setting the velocity so it would land at mouse pos in the next frame (which is not accurate) and then zeroing velocity.. this seems a lot better :D

vestal minnow
# vague pebble Case scenario: As the video shows, I want to avoid this Y axis jiggling from my ...

I have this in the kinematic character controller examples, something similar might work?

// Points in the normal's direction in the XZ plane.
let normal_direction_xz =
    normal.reject_from_normalized(Vector::Y).normalize_or_zero();

// The movement speed along the direction above.
let linear_velocity_xz = linear_velocity.dot(normal_direction_xz);

// Snap the Y speed based on the speed at which the character is moving
// up or down the slope, and how steep the slope is.
//
// A 2D visualization of the slope, the contact normal, and the velocity components:
//
//             β•±
//     normal β•±
// *         β•±
// β”‚   *    β•±   velocity_x
// β”‚       * - - - - - -
// β”‚           *       | velocity_y
// β”‚               *   |
// *───────────────────*

let max_y_speed = -linear_velocity_xz * slope_angle.tan();
linear_velocity.y = linear_velocity.y.max(max_y_speed);
umbral kelp
#

I guess in my head I just wanted to set the position and then afterwards tell the physics system, hey btw. it had this velocity, please calculate collisions

vestal minnow
#

Updated the contact graph PR to rename Collisions to ContactGraph, but also added a Collisions system parameter as a simple wrapper to only provide touching contacts

#

I'll rename Contacts to ContactPair in a follow-up though

#

this is fine

#

how have I technically been working on this contact graph stuff for 3 months ferris_sob might be one of my bigger PRs in a while

dark swift
#

I have my players represented as 2D circles that are moved by a custom character controller. The inputs for these players are applied on the same tick which causes collision detection problems because the SpatialQueryPipeline doesn't have the latest position from the previous player who moved. Calling the update method for the SpatialQueryPipeline is really difficult to do because of system query conflicts while looping through the movement for each player. I'm using Avian2D just because it was convenient. If I don't need dynamic physics for the player movement, would it make more sense to roll my own collisions for the movement with bevy's built-in AABBs instead? It seems like Parry's API is the real limiting factor here.

umbral kelp
#

@vestal minnow ty, that does work :)!! and with high enough lineardamping everything else doesn't just fly off :p I guess tweaking the parameters is a bit more tricky/needed then the less physics based way. can I just increase the speed of collisions resolution?

prime turret
#

Is there any reason why an entity (a child entity) that has a dynamic rigid body component would not have its LinearVelocity updated? The velocity components are there (I do like required components, and those are required for rigidbody), but the values are all Vec3::ZERO. I feel like I'm missing something fundamental, like, "the velocities are relative to their parent entity" and I need to manually compute vels by checking GlobalTransform and PreviousGlobalTransform, but that seems like I'm just missing something.

#

the parent entity with a dynamic RB has the expected velocities when queried in systems.

vestal minnow
#

Nesting rigid bodies in a hierarchy is also kind of weird and might not behave fully like you'd expect, so I wouldn't recommend it in general

vestal minnow
cinder summit
#

@vestal minnow two questions relating to the spatial query work:

  1. Do you know if there's any overhead to converting between IsometryNd or Position + Rotation to parry's isometries?
  2. What the hell are QueryPipelineAsCompositeShape and friends? πŸ˜‚
vestal minnow
cinder summit
#

2 sounds kinda hacky, but I guess if we're doing obvhs we can just yeet that anyway πŸ€”

vestal minnow
#

yeah feel free to yeet

cinder summit
#

Wait .... OBVHS ... doesn't do 2D? thonk

vestal minnow
cinder summit
#

Ah right that hack exists πŸ˜‚

#

I guess it shouldn't matter much either way unless we implement 2xVec2 SIMD, though I doubt many 2D games would even need that

prime turret
vague pebble
#

Hmm when does external forces get converted into linear velocity?

prime turret
#

I've been building a vehicle controller and was trying to use shapecasts, but doing so resulted in instability where there was a ton of jitter in the actual forces, and the vehicle body was affected. Switching to raycasts fixed the jitter, but I wonder if anyone has experience with this and if there's One Weird Trick. Note that changing the substep count had no real effect on it.

sleek thicket
visual sparrow
#

@vestal minnow heya, long time no see πŸ˜„
I'm updating my plugins right now and I'm wondering whether avian_interpolation still needs to exist. My main issue with your solution was the fact that it used to run after Update, which is no longer the case, right?
The other thing was that bevy_transform_interpolation caches more data as it does not know about Avian's components, but that's a minor difference. One could also easily improve that in your plugin by providing a backend feature or something like that.

GitHub

A general-purpose Transform interpolation plugin for fixed timesteps in Avian Physics for the Bevy engine. - janhohenheim/avian_interpolation

prime turret
#

oh hmm. I was using a sphere as the casted shape, which was projecting onto a cuboid, so I'm not sure if there's issues with trimeshes...

little maple
prime turret
#

Yeah, it's a pretty marginal difference; I know I'm not going to recreate beamng or anything and that's not the point, I'm just trying to make something that's interesting to do and fun to play with πŸ™‚

#

I had started with colliders and joints, so I've been sliding down the fidelity scale and I guess I'm landing at raycasts

vestal minnow
#

#5 indeed changed it to run in RunFixedMainLoopSystem::AfterFixedMainLoop (what a name) instead of after Update, so that shouldn't be an issue anymore

#

I think the biggest issue I've seen people have with bevy_transform_interpolation is that mutably accessing Transform outside of the fixed timestep, such as in Update, disables interpolation for the remainder of that timestep, and causes visible stutter. This is especially a problem in 2D where you might have a Z-sorting algorithm that changes Z coordinates every frame, breaking interpolation completely

#

There's a few ways we could potentially fix this:

  1. Ignore changes to Transform outside the fixed timestep, snapping to the interpolated value. I think avian_interpolation does this? It might break compatibility with some ecosystem crates that expect to modify transforms in Update though, and doesn't really fix e.g. the Z-sorting problem since it wouldn't even allow you to change the visual Z coordinate to begin with.
  2. Continue interpolation even after the Transform is modified in e.g. Update, but change the "end state" of the interpolation to match the new transform. Doing this smoothly might be tricky since the trajectory of the body might change. Sometimes you also don't want movement to be interpolated, for example in big_space when changing transform grid cells.
  3. For the 2D Z-sorting case specifically: Upstream Transform2d to Bevy πŸ˜› or support only interpolating specific translation axes (might be costly)
#

I think something similar to 2 could be interesting to experiment with, alongside some command or something to let you actually teleport entities in cases where that's desirable. Similar to how Godot has reset_physics_interpolation

#

Not 100% sure how I'd best implement it though

#

Hmm maybe this would work for 2

#

Original interpolation is between start1 and end1. Then the desired end transform changes to end2. We want to keep interpolating from the same visual position, so the interpolation is now between start2 and end2

#

might need to do some shenanigans to put the start2 further back, since the interpolation value t wouldn't be 0.0 mid-frame

#

sooo it'd be like this I think πŸ€”

#

where the solid line is the actual path the object would take, and time t is the moment the end transform is changed

sleek thicket
#

start1 is fixed step 1, end1 is fixed step 2, end2 is fixed step 3?

vestal minnow
#

start1 is right before fixed update (the "old position"), end1 is right after fixed update (the "new position"), end2 is if something changes the transform before the start of the next fixed update (like some system in Update)

#

Right now I think the behavior in bevy_transform_interpolatipon is that if Transform changes to end2 inside Update, it will stay there without any interpolation until the next fixed timestep. So if you are in any way accessing Transform mutably outside FixedUpdate, the interpolation breaks, and you get stutter back.

#

This new idea would still keep end2 as the end position to reach by the time of the next fixed timestep, but it would continue interpolation from the current/old visual position to not just suddenly teleport the object

#

I think it should in theory fix the Z-sorting case and other scenarios where you get stutter from modifying transforms outside the fixed timestep

light vessel
#

Do you know what the blockers are on getting Transfrom2D into bevy?

vestal minnow
#

nth is working on a thread pool

#

But no realistically I think we just need to hammer out some details of how we'll handle transform hierarchies and mixing different types of transforms in an efficient and flexible enough way. And someone needs to actually implement it

#

some people also want to rework Transform not to have non-uniform scale since it causes some problems and can't really express some forms of scaling correctly, and to have an optionalDeform component or similar that also supports shear and skew and whatever other transformations you might want

#

(but it'd be purely visual afaik)

light vessel
#

There were also talks of splitting rotation/translation too iirc

#

But yeah I can see how splitting things introduces more questions than answers overall

sleek thicket
vestal minnow
#

But yes in the vast majority of cases you should be using velocity or just changing transforms inside fixed update

#

also remember bevy_transform_interpolation isn't just for Avian and physics, it's for any entity with a transform

sleek thicket
#

ah

#

yeah then that makes sense

visual sparrow
visual sparrow
visual sparrow
#

Have you ever checked the overhead the extra components add to complex scenes?

vestal minnow
visual sparrow
vestal minnow
visual sparrow
vestal minnow
#

I feel like it should pretty easily handle thousands of objects since it's just lerp and slerp in a parallel loop, and the systems for translation and rotation can also run in parallel

visual sparrow
vestal minnow
#

fair

bold garnet
vestal minnow
visual sparrow
vestal minnow
#

Note that with only translation interpolated, I'm getting ~411 Mb

visual sparrow
#

If so, 40 Mb of RAM seems pretty reasonable πŸ˜„

visual sparrow
#

Lovely! I'll retire my plugin then πŸ™‚

visual sparrow
vestal minnow
#

If you make a PR I'll leave an approval there

visual sparrow
#

Cool! I'll add it under "Helpers", I suppose

#

Since "Physics" is explicitly not the only target

#

right?

vestal minnow
#

Yeah I suppose Helpers might be closest of the current categories

#

though looking at the projects there it seems kinda like a dump pile of "uhhh where do I put this" lol

visual sparrow
sweet sundial
#

what's the best way to make a physics jump less fixedrate dependent and more deterministic while keeping the "accelerates continuously if you hold jump while touching a wall" behavior of a stateless Collisions check?

vestal minnow
#

Next I think I will:

  1. Rename Contacts to ContactPair
  2. Try vero's GJK+EPA implementation and compare its performance to the one in Peck/Parry
  3. Optimize contact constraint generation by moving it into the parallel contact update loop
vestal minnow
visual sparrow
#

@vestal minnow I'm updating avian_pickup and am getting these new conflicts:

Error when initializing schedule PhysicsSchedule: Systems with conflicting access have indeterminate run order.
3 pairs of systems with conflicting data access have indeterminate execution order. Consider adding `before`, `after`, or `ambiguous_with` relationships between these:
 -- set_velocities (in sets First, HandleVerb, Hold, SetVelocities) and update_previous_velocity (in set First)
    conflict on: ["avian3d::dynamics::rigid_body::LinearVelocity", "avian3d::dynamics::rigid_body::AngularVelocity"]
 -- update_previous_velocity (in set First) and drop (in sets Drop, First, HandleVerb)
    conflict on: ["avian3d::dynamics::rigid_body::LinearVelocity", "avian3d::dynamics::rigid_body::AngularVelocity"]
 -- update_previous_velocity (in set First) and throw (in sets First, HandleVerb, Throw)
    conflict on: ["avian3d::dynamics::rigid_body::LinearVelocity", "avian3d::dynamics::rigid_body::AngularVelocity"]

Do you have some hints as to what could be going on?
set_velocities is my own system, I assume update_previous_velocity is coming from Avian?

#

I'm running my stuff .in_set(PhysicsStepSet::First). Is that a bad idea?

#

Hold up, PhysicsStepSet::First is empty by default according to the docs, so why is the error telling me that theres an update_previous_velocity in First? hmm

#

(this is avian v0.2.1)

vestal minnow
#

I think that's actually the only system in PhysicsStepSet::First, we should just move it probably

visual sparrow
rocky seal
#

just migrated to the 0.16 RC and i'm getting this panic:

thread 'main' panicked at /home/ty/.cargo/git/checkouts/avian-5a22c167119f3550/2ab588d/crates/avian3d/../../src/data_structures/graph.rs:231:27:
`UnGraph::add_edge`: node indices out of bounds
Encountered a panic in system `avian3d::collision::broad_phase::collect_collision_pairs<()>`!
Encountered a panic in system `avian3d::schedule::run_physics_schedule`!
Encountered a panic in system `bevy_app::main_schedule::FixedMain::run_fixed_main`!
Encountered a panic in system `bevy_time::fixed::run_fixed_main_schedule`!
Encountered a panic in system `bevy_app::main_schedule::Main::run_main`!

reckon this is an avian issue or bevy? full backtrace is too long to paste but can include in gh issue

vestal minnow
rocky seal
#

sure i'll try

#

nah, same result. the only silly thing i can think of that i'm doing that maybe you haven't tested is w/ RigidBodyDisabled and ColliderDisabled and manually setting translations while those components are set

#

so very likely i'm teleporting an object such that it overlaps with another collider and then removing those components

#

i intend to stop doing something as dumb as that eventually

vestal minnow
#

Okay I managed to reproduce this, the only case where I'm getting it is indeed if I first add RigidBodyDisabled/ColliderDisabled and then later remove them

rocky seal
#

well gee whiz

vestal minnow
#

I'll try to figure out what's going wrong there πŸ€”

#

oh god I'll also need to consider entity disabling for 0.16 won't I

cinder summit
vestal minnow
#

there's four different ways to remove an entity from physics πŸ™ƒ despawn, remove physics components, add RigidBodyDisabled/ColliderDisabled, disable entity

#

mm right we have this problem I had also forgotten about πŸ€” the contact graph stores a custom EntityDataIndex structure that maps entity IDs to node indices, but it allocates space for every entity up to the largest stored entity index... this works fine if the IDs are just collider IDs, but we're using Entity IDs directly, so if you had e.g. 999,999 non-physics entities and just one collider entity at the end, it'd allocate a million elements

#

(here there's only one collider, but it's entity 39v1, so it allocates 39-ish elements)

#

we'd need to maintain separate ColliderIds to fix this properly, or rework things to map entities to node IDs in some other way

trim barn
#

is there a way to temporary pause the physics? I'm trying to make a pause screen

true hearth
#

yes there should be a pause method or similar on ResMut<Time<Physics>> @trim barn

trim barn
#

thank you it worked

umbral kelp
#

is there a way to make a distancejoint bouncy?

vestal minnow
umbral kelp
#

ah I changed that to make it comply to the constraints faster or slower..

#

I was imagining slow compliance to the min distance and then bouncing back a bit

#

which would mean two distinct variables

vestal minnow
#

It was just a dumb oversight where it wasn't clearing removed colliders from a structure that maps entities to graph nodes

umbral kelp
#

Other question... more important&confusing
the magenta squares are the aabbs I'm using in a spatial query to find touching colliders. the yellow circle around the red nodes should be the debug rendering of their colliders.. the magenta line between them shows the spatial query is returning one from the other... now I'm just very confused why, as the aabbs obviously don't touch the colliders

sweet sundial
#

the aabbs are touching each other

umbral kelp
#

ah right.. another layer of aabbs

#

I always forget

#

thanks 😭

#

there cannot be enough gizmos to make this clear to my brain

vestal minnow
#

TIL Bevy also has an Identifier that is "for all entity and similar IDs" except it packs an IdKind into the high bits which I don't necessarily want

#

bleh I guess I'll copy Entity for my purposes, it's not that much code

umbral kelp
#

to the actual thing I tried to solve.. is there a way to hackily enable sleeping for jointed RigidBodies? tried to inserting Sleeping manually, but it's ignored/removed when connected to a joint, is what I take from that message?

vestal minnow
#

Yes, sleeping currently doesn't work with joints

umbral kelp
#

can I work around it?

#

detecting when one of the rigidbodies moves to then disable sleeping in the other should work kinda?

umbral kelp
vestal minnow
#

Yeah; we don't have simulation islands just yet (though I do have an implementation in the works), and without them we only have per-body sleeping, which can be problematic for various reasons for objects that are interacting with each other

#

which is why sleeping is currently used only for dynamic bodies that aren't interacting with other dynamic bodies

umbral kelp
#

I don't have a complex physics simulation, I just use it for graph layouting so I guess that's why I'm not too concerned, but I understand that's not the main target for the library.
Looking forward for islands :)
And maybe I can work around it for now.

#

thanks for your help!

willow elbow
#

I have a question on FixedJoint: let's say I have two entities that were spawned independently with different Transforms. I would expect that spawning a FixedJoint like this:
commands.spawn(FixedJoint::new(id1, id2).with_local_anchor_1(Vec3::ZERO).with_local_anchor_2(Vec3::ZERO) would just fix them relatively to each other with anchors located at their centers. But they actually become overlapping each other like the joint overwrote the transform of one or both of them.
Why do I need to know the local position of one with respect to the other at the moment of the joint creation to obtain the desired result?

vestal minnow
# willow elbow I have a question on FixedJoint: let's say I have two entities that were spawned...

The local anchors are the points on each body that the joint attempts to align. If the anchors are just zero, it means that the joint will make the centers of the bodies align.

The joint needs these values in local space, because if they were in world space, they would become invalid as soon as the bodies are moved or rotated. We could have an API however to help initialize the anchors more conveniently in world space

vague pebble
#

If you guys had to make hitboxes that are basically cuboids , which dimensions rely a tad bit of the given mesh information. How would you guys do it?

willow elbow
vestal minnow
vestal minnow
#

or just an EntityHashMap if I want to be really simple

#

too many choices aaaa

vestal minnow
#

Welp, I ended up vendoring my own version of slotmap::SparseSecondaryMap since it had some problems (like not supporting no_std)

#

branch here, a bit WIP though

sharp dew
#

hey, sorry if this question has been answered many times, but discord search is hell

i'm trying to spawn a very minimal scene for testing but i can't get a capsule collider to behave, as it keeps bouncing

    // this is just a cube
    let scene = assets.load("models/level.glb#Scene0");

    commands.spawn((
        SceneRoot(scene),
        ColliderConstructorHierarchy::new(ColliderConstructor::TrimeshFromMesh),
        RigidBody::Static,
        CollisionMargin(0.1),
    ));

    // "player"
    commands.spawn((
        Visibility::default(),
        RigidBody::Dynamic,
        Collider::capsule(0.25, 2.0),
        LockedAxes::ROTATION_LOCKED,
        LinearDamping(0.8),
        Transform::from_xyz(1.0, 15.0, 1.0),
        Player,
    ));
#

(light mode warning, sorry about that)

sharp dew
#

I uh.... I'm so sorry. I "fixed" it and I have no idea how

at first I thought the CollisionMargin component was the problem, but then added it back in and everything still worked

sweet sundial
#

source control rollback and recheck? or somehow a cache/local issue

sharp dew
#

it's a very minimal "hello world" type of thing, no meaningful vcs practices

#

I'm more inclined to blame the export Blender at this point

#

but I'll keep an eye out, sorry again for the spam

visual sparrow
#

I recommend running the prop_playground example, that one's fun to play around with

vestal minnow
vestal minnow
#

A few things that came to mind:

  • I'm not sure I love using EventWriter<AvianPickupInput> for performing actions; in general, I treat events as a way to respond to things that have happened, not as something that makes things happen by itself.
  • Maybe PropThrown and PropDropped should be observable events? This would allow you to observe specific entities, which could be useful for e.g. sound effects or other things that may vary per prop.
  • For 0.16: Avian has a RigidBodyColliders component now, which should simplify the rigid_body_compound_collider stuff.
    Also, I noticed that in play_catch, R doesn't seem to actually reset the prop?
#

Another small thing: There's a solid chance this is intended, but often when I'm grabbing things that are close to each other, it kinda shifts focus between them and ends up launching both towards the player, rather than locking onto one

visual sparrow
#

The "R" thing is weird, I cannot reproduce it. I just googled "Finnish Keyboard" and it says that the R key is on the same physical location as on the QWERTY keyboard, so that's not an issue. hmmm.

visual sparrow
#

Thanks for the review in any case πŸ™‚

vestal minnow
vestal minnow
visual sparrow
visual sparrow
visual sparrow
visual sparrow
#

@vestal minnow are all rigid bodies guaranteed to have a RigidBodyColliders component?

vestal minnow
visual sparrow
#

Update: think I got it

#

Btw, I lost track of the difference of Position + Rotation and Transform while interpolation is active. I remember that with my plugin, I had a strict "Transform is screen stuff, Position + Rotation is the real physical simulation" doctrine. Does Avian's interpolation just handle everything so that Transform is the physical position during PhysicsStepSet::First?

visual sparrow
visual sparrow
vestal minnow
#

So Avian itself doesn't really see transform interpolation in any way, it's all handled by bevy_transform_interpolation and primarily happens outside the fixed update

visual sparrow
#

So, am I understanding it correctly that I can safely change all my references to Position and Rotation to use Transform?

#

(if the object in question has no parents)

#

I don't think you update GlobalTransform, right? So that one would be outdated, I presume

vestal minnow
#

Hmm I believe GlobalTransform is currently updated for physics entities in PhysicsSet::Prepare, right before the PhysicsSchedule

visual sparrow
#

Oh, so I can just use GlobalTransform everywhere?

#

Is there a best practice you would recommend?

vestal minnow
#

Mmm I would say yes, you should be able to use it pretty much everywhere. I don't know if there's anyone using only Position and Rotation without GlobalTransform (and if we even care about supporting that)

visual sparrow
vestal minnow
#

I still personally consider Position and Rotation to be primarily internal physics components, not something the average user should be using. So in general, I would encourage people to use the de facto transform components provided by Bevy (Transform and GlobalTransform) unless there is a clear reason not to

#

of course the transform situation in Bevy isn't ideal either though, 2D transforms sure would be nice...

visual sparrow
kind moss
#

I just update to the latest main and now EventReader<CollisionStarted> doesn't seem to be yielding any events? Collisions are still happening in the simulation but those events don't seem to be going out any more. Did something change?

#

The sensor example prints events, so they are working there. Sigh. Must be something I've done.

vestal minnow
kind moss
vestal minnow
kind moss
#

I actually think I'm going to switch to CollidingEntities which suits my usecase better.

#

Hadn't noticed that before (maybe it's new).

#

And replace all the places I manually query Collisions

vestal minnow
#

Just fixed a pretty major bug in bevy_heavy's AngularInertiaTensor::shifted method (an incorrect sign), which fixes angular inertia computation for child colliders in Avian. I had this bug because I originally used Parry as reference for this, and it's wrong ferris_spooky

#

Kinda wild how Parry/Rapier still has bugs like this and people haven't caught it, it's a major correctness issue and makes behavior weird for compound shapes, including colliders using convex decomposition or convex hulls I believe

#

Here you can see it being broken in bevy_rapier3d. The body with three boxes joined together is using child colliders (Collider::compound is similarly broken) while the other body is just a single cuboid. The mass properties should be the same, but the angular inertia for the compound one is wrong, 4.5 instead of 0.5 for the y axis, which leads to it spinning with much more inertia and overall behaving wonky

#

(the initial velocity and orientation is the same for both, the video is just trimmed a bit from the start)

#

Avian was similarly broken before, but it's now fixed for child colliders, so this three-cube case behaves the same as the single tall cuboid. Collider::compound is still broken because of Parry though, so I'll need to fix that upstream

vestal minnow
#

cc @grizzled depot, this one is pretty important

grizzled depot
vestal minnow
#

Yeah no hurry! That PR is different, that just fixes the unit angular inertia tensor computation for tetrahedra (and therefore trimeshes). My fix is for MassProperties::construct_shifted_inertia_matrix, which is used when summing MassProperties together, which is done for compound shapes and child colliders

visual sparrow
proven ice
#

will avian properly handle spin caused by friction on colliding spheres? e.g., for pool / billiards.

#

there are a lot of pool nerds who know how the game works with real-life physics. im hesitant to make a pool game without looking into physics engines, since i'm sure someone would complain if the physics weren't just right.

#

i'm not a physics programmer, so i don't know if the important factors in cue ball physics are trivial to physics, or something that is usually simplified / glossed over in physics engines.

#

im sure pool snobs are used to inaccuracies in digital versions of the game, though. but getting spin upon ball contact feels like something that should be handled somewhat properly for a pool game.

vestal minnow
#

It should be fairly accurate, but I don't know pool well enough to really say

#

I imagine there might be a lot of very subtle details that are important in pool but might not be perfectly accurate in a game physics simulation

proven ice
#

if a spinning sphere hits a stationary sphere, will the stationary sphere start to spin?

vestal minnow
#

Yes that should work

#

I can make a quick test actually

proven ice
#

i think pool / billiards is such a niche case that it doesnt reallly matter if this particular thing isn't handled correctly in avian. i was just curious if the answer to this is known / presumable by someone smarter than me lol.

proven ice
sweet sundial
#

how do people hook sound into Avian anyway? i tried with collisions' normal total impulse and it didn't work properly with anything but two boxes in a vacuum

proven ice
vestal minnow
#

so yeah we need ColliderId...

proven ice
#

why does it allocate space for every entity ID?

cinder summit
#

I currently hand it entity indices for indices and ofc collider aabbs

vestal minnow
#

I think regardless of the BVH, we need to map BVH proxies to entities and vice versa

vestal minnow
# proven ice why does it allocate space for every entity ID?

I think this is because the AABBs must be stored contiguously for perf reasons, and the indices correspond to the vec indices. To make sparse Entity IDs work without unnecessary allocations, we need a mapping from Entity IDs to these BVH indices

cinder summit
#

@vestal minnow I'm back to working on the SpatialQuery stuff ... Have some partial progress, but I'm now at the point where I need to make some architectural decisions on how this will look ... I'm thinking we can just make SpatialQueryPipeline collider-agnostic, then pass in the collider type from SpatialQuery (which can default to C = Collider if that's enabled) ... Then we could either pass that type + necessary context to the methods, or we just pass a method to SpatialQueryPipeline that returns the necessary data ... The latter sounds cleaner, and lets us remove _predicate vs not-predicate from this layer ... And we would need a QueryCollider trait or whatever which provides raycast impls, shapecast impls, etc

#

Alternative would be to make SpatialQueryPipeline per-collider, which gives us the generics there to do things directly, but we would still need to take a Context there as input

vestal minnow
#

so it'd mainly be just a wrapper around a BVH, with methods for querying it

#

Also damn I'm experimenting with yet another redesign of the contact graph stuff, it sure is going through a lot of iterations... We need collider IDs that are separate from Entity, but we also need to map those to nodes in the contact graph, so I was thinking I could combine these and use a generational arena to store the next_contact edge index for each collider. This way the contact graph node indices would be the collider IDs themselves, and I can minimize mapping stuff

cinder summit
vestal minnow
#

Yeah that sounds fine

vague pebble
#

When it comes, to rigidbodies, the kinematic bodies are affected by the transform component, but not the dynamics bodies those ones you should hard set via position and rotation components?

cinder summit
#

The Transform -> Position/Rotation applies the same to all RigidBodys, but you don't want to be updating positions during a simulation at least, that'll be treated like teleportation after all

vague pebble
#

This is just to set start position

finite blaze
cinder summit
#

This sure is becoming one hell of a type

#[derive(SystemParam)]
pub struct SpatialQuery<'w, 's, C: QueryCollider> {
    pub(crate) colliders: Query<'w, 's, (&'static Position, &'static Rotation, &'static C)>,
    /// The [`SpatialQueryPipeline`].
    pub query_pipeline: ResMut<'w, SpatialQueryPipeline>,
    context: StaticSystemParam<'w, 's, <C as AnyCollider>::Context>,
}
shrewd pulsar
#

What are the swing_axis and twist_axis fields in SphericalJoint?

cinder summit
#

@vestal minnow do you think there would be any value at all in having "get the ray hit distance" and "get the ray hit normal" separated? OBVHS is largely set up to just take a distance and then compute the rest at the end, but we could just combine it too

vestal minnow
#

also why did I name it RayHitData and not just RayHit πŸ€” should probably be renamed

#

or maybe RayCastHit and ShapeCastHit since ShapeHit would be a bit more ambiguous

vestal minnow
# shrewd pulsar What are the `swing_axis` and `twist_axis` fields in `SphericalJoint`?

You can think of spherical joints as having a sort of "limit cone", where the relative orientation of the bodies is limited to remain within a cone shape. twist_axis is the axis passing through the apex of this cone (from the tip to the base or vice versa), and the swing_axis should be any direction parallel to the base of the cone. These axes essentially determine the orientation of the cone.

#

Then, the swing_limit determines how wide the cone is, and twist_limit determines how much the bodies are allowed to rotate relative to each other on the twist_axis

cinder summit
drifting marsh
#

is transform interpolation broken? when I enable it, everything seems to slow down and gets even less smooth

sleek thicket
drifting marsh
#

I am changing the rotation of the transform but not the translation

vestal minnow
prime turret
#

for ExternalForce::apply_force_at_point(), it says that all the arguments (force, point, center-of-mass) should be in world space, but what does that mean for a force?

#

ah, I see, rotated by the parent xform

elder narwhal
#

2d: if I have a row of flush square colliders as part of a same static rigidbody (its a tilemap with a flat surface), a dynamic rigidbody moving on top of them bumps up when it meets each corner. is there something i can do about it? (short of merging these squares into a single polygon or something)

sweet sundial
#

can try changing the physics scale or body's ccd

#

best bet is to make a hull or otherwise compose the colliders, though

elder narwhal
#

for sure i'd do that if it wasnt for ludum dare xD
edit: ccd or scale didn't work

sweet sundial
#

then maybe just do a quick trimesh of two tris per square

elder narwhal
#

like 2 polylines per tile? not sure if that'd be any better
i kind of got it looking ok by playing with the gravity and timestep, good enough for now, can only notice it maybe 10% of tile crossings

shrewd pulsar
#

What's the best way to apply a force as if it were applied from a certain point offset from the center of the rigidbody?

golden python
#

What would be the best way for multiple objects to all contribute an immediate force to a single body ?

I could have a persistent external force on it but that would mean resetting it to 0 every frame.

Guess i'll do that but wondering if there is a more ergonomic way

golden python
#

Seems like resetting it every frame prevents all movement, even though I reset it before the frame. Not sure why

elder narwhal
#

ExternalForce/ExternalImpulse components, I think? They have functions to apply at points

#

There's a setting on the external force component to clear it every frame

golden python
elder narwhal
#

Try using the persistent field set to false

golden python
#

I'm going to make a simple reproduction

golden python
# elder narwhal Try using the persistent field set to false
fn main() {
    App::new()
        .add_plugins((DefaultPlugins, PhysicsPlugins::default()))
        .insert_resource(Gravity::ZERO)
        .add_systems(Startup, setup)
        .add_systems(PreUpdate, reset_forces)
        .add_systems(Update, force)
        .run();
}
use avian2d::prelude::*;
use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins((DefaultPlugins, PhysicsPlugins::default()))
        .insert_resource(Gravity::ZERO)
        .add_systems(Startup, setup)
        .add_systems(PreUpdate, reset_forces)
        .add_systems(Update, (force, gizmos))
        .run();
}

#[derive(Component)]
pub struct Car;

fn setup(mut commands: Commands) {
    commands.spawn(Camera2d);

    commands.spawn((
        Car,
        RigidBody::Dynamic,
        Mass(1.),
        ExternalForce::default().with_persistence(true),
    ));
}

fn reset_forces(mut cars: Query<&mut ExternalForce, With<Car>>) {
    for mut force in cars.iter_mut() {
        force.clear();
    }
}

fn force(mut cars: Query<&mut ExternalForce, With<Car>>) {
    for mut force in cars.iter_mut() {
        force.apply_force(Vec2::Y * 100.);
    }
}

fn gizmos(mut gizmos: Gizmos, cars: Query<&Transform, With<Car>>) {
    for transform in cars.iter() {
        gizmos.circle_2d(transform.translation.xy(), 10., Color::WHITE);
    }
}

Here is the minimal reproduction

#

I also tried this while creating a new External force component every frame but it also doesn't work

vestal minnow
#

you're applying the force in Update (after physics) but clearing it in PreUpdate (before physics)

#

so it never really gets applied

golden python
#

I see, thanks

golden python
#

I ended up using persistence = false which worked just fine.

#

I'm now struggling with angular velocity staying at 0 even though it's saying my external force has torque.

vestal minnow
golden python
#

Hello again, is there a built-in way to get the linear velocity at a point of a rigidbody ?
Something like rapier's linear_velocity_at_point or unity's getPointVelocity ?
Would be really handy for my vehicle physics

vestal minnow
#

There isn't really a convenient helper for velocity directly, but it's just lin_vel + ang_vel.cross(offset), where offset is a point relative to the center of mass

#

Or if you use Query<RigidBodyQuery>, then the returned items also do have a velocity_at_point helper

golden python
#

thanks

golden python
#

They are kind of flipped version of each other

[4.5047007, 9.038669] [-9.071604, 4.513233]
#

This is your formula I adapted for my 2d case

let tire_vel = **velocity + **angular_velocity * local_transform.translation.xy();
vestal minnow
#

for 2D it's lin_vel + ang_vel * offset.perp()

golden python
#

thanks that was it

abstract forge
#

I was looking though the examples for avian2d and cant seems to find anything on creating colliders using something like a polygon. Would anyone happen to have any info on this

kind moss
#

Or maybe polyline if you really just have a single polygon.

abstract forge
#

Thanks trymesh works I just had to meshify my polygon first.

shrewd pulsar
vestal minnow
#

(and how joints will work once we switch them away from XPBD)

visual sparrow
#

@vestal minnow FYI PreSolveRotation and GlobalAngularInertia are not type registered, so a Scene I loaded in avian "0.2.1" that contained those types crashed at runtime. I manually added them, not sure if I should open a PR or whether you fixed it already.

vestal minnow
#

hmm maybe we could have some test for it so that (some) missing registrations would get caught by CI πŸ€” like spawn a rigid body and collider, turn that into a Scene, and try to load it

visual sparrow
vestal minnow
#

wouldn't catch everything (unless we manually add all components :P), but the required components that get auto-inserted

visual sparrow
vestal minnow
#

I never know what labels to use for stuff like this πŸ₯² does this count as C-Bug, or C-Usability, or...

languid lynx
#

would it be possible to implement caching for ColliderConstructor::TrimeshFromMesh so that all entities with the same Handle<Mesh> use the same SharedShape? as it stands, if you try to construct hundreds of colliders with the same trimesh it will duplicate the vertices across each instance for the collider and spike the memory usage

visual sparrow
#

Hmm but then again, Collider is always inserted directly into colliders, there's no Handle<Collider>

#

I suppose one could create a kind of collider that holds an internal RwLock and clone that across all objects with the same Handle<Mesh>?

visual sparrow
languid lynx
#

im looking at it a bit. internally, colliders hold a SharedShape, which is an Arc for the collider mesh data. so the machinery is there to support this, its just a matter of hooking it up

#

currently im trying to add a MeshColliderCache resource that's just a HashMap<AssetId<Mesh>, Weak<dyn Shape>>, both weak pointers so they don't keep references to the mesh/colliders alive unnecessarily

#

i still need to differentiate between convex hull / convex decomposition / trimesh, but baby steps

languid lynx
#

hmm, i thought it would be that simple, but the memory usage is still spiking high....

#

ill try to work on it more tomorrow, i think im just missing something obvious

languid lynx
#

okay from further testing it seems that the majority of allocations come from contacts, NOT from the colliders themselves πŸ˜…

visual sparrow
vestal minnow
#

it's opt-in on main

#

the new contact graph stuff has a small memory usage problem, which this should fix, but I'm not entirely satisfied with the solution there so I'm experimenting with alternatives

#

but contacts still also just inherently require a decent amount of memory

languid lynx
#

yeah, i forgot that collision contacts would induce allocations

visual sparrow
vestal minnow
visual sparrow
vestal minnow
#

they are, I also have an optimization that cuts the combined cost of the narrow phase and constraint generation in almost half again (if multi-threaded)
#1124043933886976171 message

visual sparrow
#

I see, my dream of yeeting 100 boxes at the same time can finally be fulfilled

vestal minnow
#

I also have a SolverBody optimization that makes the solver (our biggest bottleneck) more than twice as fast, but that's kinda blocked on me finally switching joints away from XPBD (or doing ugly hacks)

visual sparrow
#

Love it when one of those gets resolved

vestal minnow
#

I do have impulse-based 2D and 3D revolute joints and spherical joints working, it'll get there eventually...

#

it's not a very motivating thing to work on tho since implementing the math is way more complicated and the immediate result is likely slower than with XPBD

little maple
#

I've been using that branch for my game and it gave me like 20-30+fps improvement, I was like 🀩 when I first switched to it

vestal minnow
little maple
royal helm
#

do AnyCollider impls only work for interactions between those colliders?

sweet sundial
#

seems so, though it's possible IntoCollider can smooth things over a little

golden python
#

I find it really useful when having to tweak enemy masses for example without affecting their speed

golden python
#

Also wondering if there is a way to get the direction of a collision ?

deep cypress
golden python
#

I guess an average or something would get me there

deep cypress
#

I guess I'm not sure what you mean by direction of collision.

#

Do you mean the direction from entity1 to entity2?

#

The ContactManifold.normal1 seems to be that value.

#

Disclaimer, I haven't used that feature, so I could be misunderstanding it.

#

Correction, normal1 isn't the direction from the entity to the other entity, it's the normal shared by all contact points in the manifold.

sweet sundial
#

you probably want the position relative to the center of mass

vestal minnow
livid dew
#

I tried switching my project from rapier2d to avian2d, but encountered a strange issue. When a ball naturally slows down to a stop, changing its CollisionLayers has no effect. I’ve already added SleepingDisabled to the ball and set the global SleepingThreshold to a negative value, but modifying CollisionLayers still doesn’t work. However, when the ball is still moving, changing CollisionLayers works as expected.

zinc talon
#

Does avian support computing mass properties for hierarchies? Like if I have a single dynamic rigid body with two children with mass + moment of inertia + transform offset, will the root entity calculate its mass properties with respect to the whole hierarchy?

light vessel
zinc talon
#

Oh nice

#

ty

undone escarp
#

Hi, I am trying out avianand I believe I've ran into a bug. I am listening to collision events with an EventReader<CollisionStarted> and I modify the collision layers of the colliding entities after the collision has started. However, it seems that sometimes this causes the collision not to resolve correctly and the two colliders end up passing through each other.

#

I think this is a bug because the CollisionStarted event is fired correctly, but I assume because I modify the collision layers the rest of the collision does not play out correctly.

sweet sundial
#

have you tried ordering your listener after physics entirely?

undone escarp
#

Yes, although I'm not 100% sure what would be the correct scheduling here as I'm relatively new to bevy/avian.
Would app.add_systems(Update, handle_collisions.after(PhysicsStepSet::Last)); be correct?

sweet sundial
#

sometimes

#

you want FixedUpdate or Physics

#

specifically: fixed schedules happen during update, but sometimes don't happen or happen multiple times depending on frame time

undone escarp
#

Ah, good catch on Update vs FixedUpdate but it does not make a difference for the issue I mentioned though. Also, I'm a bit confused by what you mean by Physics as that's not a schedule.

sweet sundial
#

maybe it's PhysicsSchedule or something

#

you could try delaying the layer change by a couple ticks

sweet sundial
rocky seal
#

0.16.0-rc.4 removes the bevy_log feature flag in favor of tracing

thorny heart
#

Hi, I ran

git clone https://github.com/Jondolf/avian
cd avian
cargo run --example one_way_platform_2d
vestal minnow
#

It's technically easy to fix, there's just three different ways I could do it

  1. Have a system that just queries for Changed<CollisionLayers> and removes contact pairs whose layers no longer match. Requires full table scans :(
  2. Same as 1, but make CollisionLayers an immutable component, and observe OnInsert events. More efficient for sparse changes, but makes changing layers a bit more annoying :(
  3. Always check if layers are compatible in the narrow phase. Adds a (very) small extra cost for every contact pair :(
cinder summit
#

Definitely not a fan of 1 at least

vestal minnow
#

yeah I'll probably just do 3 for now, and leave a TODO to handle it better if we ever get fine-grained change detection

vestal minnow
#

I think I found an interesting bug in the process thonk I'm setting CollisionLayers::NONE at runtime for all colliders in this test scene, but for some reason it only removes half of the contact pairs at a time, even though it should remove them all at once
edit: figured it out

little maple
#

is there a stable approach for "teleporting" a dynamic rigidbody while keeping its momentum? I've been just changing the entity's Transform but not sure if that's a good idea

cinder summit
little maple
#

I suspect what I'm running into is that the interpolation makes it stutter just slightly... seems like I should be modifying the linear velocity instead? Like... apply a significant force for one frame?

cinder summit
#

Applying a significant force sounds like a recipe for disaster, you'll hit something and it will explode ... I think Jondolf talked about a way to skip interpolation for frames with a teleport before πŸ€”

little maple
#

yeah, I think he had a couple ideas but not sure what he ended up going with

cinder summit
#

I don't think we got a real solution, but you might be able to just modify the thing for interpolation and make it so that the from and to values are the same

little maple
#

I guess, maybe this is an XY problem... what I really want is to put the player in a repeating area for a variable length of time and then when some condition is met have them able to exit the area

#

like uhh mario 64's repeating stairs

#

I can't decide whether it's better to handle that by teleporting or by spawning more area in front of the player forever

cinder summit
#

Spawning more area for ever could end you up in inprecision land which isn't ideal πŸ€”

#

If you need it to be smooth you might need to modify both the start and end of the interpolation so it's the same as if would've been if you hadn't teleported but just started there

little maple
#

I wonder if disabling interpolation during teleportation would work

cinder summit
#

If you disable it you'd notice that the motion isn't continuous anymore

little maple
#

Note that changing Transform manually in any schedule that doesn't use a fixed timestep is also supported, but it is equivalent to teleporting, and disables interpolation for the entity for the remainder of that fixed timestep.

#

hmm, I might not be able to get around that

vestal minnow
vestal minnow
#

We should probably add a command like Teleport to bevy_transform_interpolation that teleports the given entity to the given position, kinda like changing the frame of reference, but allows keeping the smooth interpolation in some way

cinder summit
#

Oh BTW @vestal minnow in case you were wondering ... I'm still working on the SpatialQuery rework ... It is starting to look a bit sus though, like this ext trait:

pub(crate) trait BvhExt {
    fn cast_traverse<...>(...)
    fn cast_traverse_dynamic<...>(...)
    fn dist_traverse<...>(...)
    fn dist_traverse_dynamic<...>(...)
    fn point_traverse<...>(...)
    fn point_traverse_dynamic<...>(...)
}```
vestal minnow
#

that doesn't look too bad

#

what's the difference between the _dynamic and non-dynamic versions?

cinder summit
#

The non-dynamic ones just call dynamic and construct some stuff to not clutter up the calls

vestal minnow
#

right makes sense

cinder summit
#

The dynamic ones allow you to early-exit, while the non-dynamic ones just keep traversing the whole BVH to get the best value

#

Dynamic is also necessary if you want multiple results or like the _callback versions

little maple
#

if I were to alter the transform to teleport... when in the frame would be best?

cinder summit
cinder summit
#

Is there even a good example to test spatial query stuff? πŸ€”

vestal minnow
#

Not a good one, the only one dedicated to spatial queries is probably the ray_caster example and that's very basic

#

some other examples also use shape casts but only as a side thing (like ground detection for character controllers)

#

There might be some other edge cases I'm missing in terms of hierarchies or something πŸ€”

cinder summit
#

Does this work fine for the case where both Disabled and ColliderDisabled get removed at once?

vestal minnow
#

why would you have both ferris_sob I guess the AABB interval thing should be changed to remove duplicates

cinder summit
#

Hmmm, I just realized that AnyCollider isn't actually a valid input for shape casting, since the thing you cast might not be your collider type at all (like with the VoxelCollider example we probably don't want to be casting chunks against chunks)

vestal minnow
#

I had it lying around on a branch with BVH broad phase experiments from a while back, I just updated it now and removed some stuff

#

it's based on one of the Box2D stress tests for dynamic BVHs

#

it uses the CircleCollider from the custom collider example just so that it doesn't use Parry, but that can be changed to something else

vestal minnow
#

Hmm this needs more testing, but I might have a potential fix to the interpolation problem? πŸ€”

#

test without moving the camera (the cyan object gets teleported backwards by just changing its Transform)

#

Basically: If the transform is modified outside the fixed time step (e.g. in Update), compute the difference between the current interpolated transform and new Transform, and add this difference to the start and end states of the interpolation

#

I believe this doesn't truly teleport, i.e. the transform at the end won't necessarily match the target Transform it was set to (since it finishes the old interpolation, just with a different current interpolated transform), but people can turn this into an actual teleport by setting the easing states to None first. For that, we could expose something like a ResetInterpolation command

vestal minnow
#

I'm getting perfectly smooth grid cell transitions rn

earnest iris
#

I'm trying to have a gliding rigid body object on a trimesh static collider floor move smoothly, but I keep getting the object jumping whenever it hits an edge on floor. It seems as if the rigib body capsule is penetrating the floor just by a little, enough to make it jump up when hitting those edges.
Is there any hack to workaround something like this?

vestal minnow
#

This won't help for edges between separate trimeshes though

earnest iris
#

Yes, I tried with:

            TrimeshFlags::DELETE_BAD_TOPOLOGY_TRIANGLES
                | TrimeshFlags::FIX_INTERNAL_EDGES
                | TrimeshFlags::MERGE_DUPLICATE_VERTICES,
        ))
vestal minnow
#

Are you sure the bumps are between edges of triangles that belong to the same mesh, or between separate meshes? Your'e using ColliderConstructorHierarchy which implies that you're maybe spawning a scene with multiple meshes

#

Adding a small CollisionMargin (adds some thickness) around the capsule and/or terrain might help a bit in some cases, though it's not really a proper fix

earnest iris
#

That's the mesh

#

Let me try with CollisionMargin

#

Not really working I'm afraid πŸ˜…

vestal minnow
#

Mm I'm not getting any bumps in my test scene with trimeshes if I'm using TrimeshFlags::FIX_INTERNAL_EDGES

earnest iris
#

What kind of collider are you using for the player?

vestal minnow
#

capsule

earnest iris
vestal minnow
#

thanks, I'll try with that

earnest iris
#

Thanks.

vestal minnow
#

@earnest iris Just moving around and rolling a ball on the ground, I'm not really seeing any bumps πŸ€”

#

(this is the character controller from the dynamic_character_3d example)

earnest iris
#

Would you mind sharing the test code with me? πŸ˜… this looks great!

vestal minnow
earnest iris
#

Amazing! Thanks, a million ❀️‍πŸ”₯

vestal minnow
#

In my testing, it seems like it should fix all the problems with mutably accessing Transform breaking interpolation, when e.g. y-sorting or using big_space

vestal minnow
#

FYI @glacial nebula, this ^ seems to make bevy_transform_interpolation Just Workβ„’ with big_space, assuming my test case isn't faulty

#

(here the grid cells are small just to make it switch between them often)

little maple
thorny heart
#

@vestal minnow i'm so glad this "just works", it's awesome

visual sparrow
#

@vestal minnow any idea what's up with these guys?

#
  • The plates fall through the floor
  • The mugs jitter
  • The books breakdance
#

The prop colliders and the floor are all convex hulls

#

Is there any obvious setting I could tweak?

thorny heart
visual sparrow
#

I guess some of my dependencies activate f32

oak vigil
#

Hey I'm having trouble understanding contact manifolds. I'd appreciate some insight!
My problem is that given two intersecting colliders A and B (not enclosed), I want to find the best position inside collider A to place collider B, such that A fully contains B.
So something like this:

#

I've been researching, and I think I need to get the normals from contact manifolds. It makes sense. But I'm not sure what the contact manifolds are exactly.

#

For example, in the diagram above, do I get 2 manifolds with two different normals...? What about this...?
If so, what about this case?

marble cradle
#

i have a dumb question

#

i have been 'teleporting' my character by settings its Transform

#

but this no longer seems to be reliably working !? since i added TransformInterpolation

#

sooo am i doing something wrong ?

visual sparrow
thorny heart
#

@vestal minnow @gentle cave i'm kind of stuck using both avian and ecs_ldtk together. i have the minimalest possible setup for both you can think of. here's what i've investigated

marble cradle
#

Oh it stopped . Nvm i think i was doing something else incorrect

thorny heart
#

so far this works but it's super hacky

#
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
    commands.spawn((
        Camera2d,
        Projection::Orthographic(OrthographicProjection {
            scale: 0.5,
            ..OrthographicProjection::default_2d()
        }),
        Transform::from_xyz(1280.0 / 4.0, 720.0 / 4.0, 0.0),
    ));

    commands.spawn(LdtkWorldBundle {
        ldtk_handle: asset_server.load("tile-based-game.ldtk").into(),
        ..Default::default()
    });
}

fn init_added_player(
    mut commands: Commands,
    assets: Res<Assets<Image>>,
    player: Single<(Entity, &Sprite, &Transform), Added<Player>>,
) {
    let (player_entity, player_sprite, sprite_transform) = (player.0, player.1, player.2);
    let player_size = Vec2::new(1.0, 1.0);
    //assets.get(&player_sprite.image).unwrap().size_f32() * sprite_transform.scale.truncate();
    commands.entity(player_entity).insert((
        RigidBody::Dynamic,
        LockedAxes::ROTATION_LOCKED,
        Restitution::ZERO.with_combine_rule(CoefficientCombine::Min),
        Transform::from_scale(Vec3::new(0.5, 0.5, 0.5)).with_translation(Vec3::new(
            sprite_transform.translation.x,
            sprite_transform.translation.y,
            10.0,
        )),
        Collider::rectangle(player_size.x, player_size.y),
    ));

    //
    //commands.spawn((
    //    Player,
    //));
}
#

I can also send the revy details which show every component of the entity at each time step

sleek thicket
#

actually nvm it was still xpbd back then, so something might've changed

thorny heart
#

i've figured it out

#

it's hacky

#

but you have to manually set a high z index on the Transform for the player

#

when you setup it as an avian physics object

sleek thicket
#

i had both player and enemies spawned in LDTK itself

thorny heart
#

same

#

but i also need to add avian physics to them lol

sleek thicket
#

i just took the platformer example and adapted it to xpbd and it worked

thorny heart
#

idk what xpbd is

sleek thicket
#

old avian

thorny heart
#

lol

#

not really relevant then πŸ˜…

#

bevy breaks every week

sleek thicket
#

it switched from position to velocity-based solver, i could see new bugs appearing but i don't see how that's relevant here xD

thorny heart
#

lol well you have the results of my investigation

#

make of them what you will

#

i can reproduce everything htere

sleek thicket
#

like what was even the problem, layers being backwards?

thorny heart
#

see screenshots

#

either the sprite disappears or the level becomes gray sometimes

sleek thicket
vestal minnow
#

the green arrow is the outward normal on each object's surface

#

For all convex shapes, there is only one contact manifold at a time, but concave shapes and composite shapes (trimeshes, heightfields, polylines, compound shapes) can have several

vestal minnow
#

In the past I've noticed that contacts between some shapes are much more prone to instability than others at small scales (see #1124043933886976171 message)

chilly cradle
vestal minnow
#

I won't make a new release for 0.15, but I could maybe set up some branch that has it cherry-picked

#

so you could then target that branch until you switch to 0.16

vestal minnow
#

Need to test a bit more to verify that I didn't break anything, but it seems fine :P

cinder summit
#

Oh no, a merge conflict πŸ‘€

vestal minnow
#

I assume your stuff is pretty different anyway though? Since it doesn't even use Parry for the BVH

cinder summit
#
pub struct SpatialQueryPipeline {
    pub(crate) bvh: Bvh2,
    pub(crate) colliders: HashMap<u32, SpatialQueryItem>,
}
``````rust
struct SpatialQueryItem {
    generation: u32,
    layers: CollisionLayers,
    position: Position,
    rotation: Rotation,
    aabb: ColliderAabb,
}
#

I guess I can just adopt this proxies approach though, that might even allow for resorting so I can get rid of the extra indirection, though I'm not sure if that makes sense to do performance wise

#

The array lookup would also be faster than a hashmap lookup, though I guess the lookups don't happen that often if the BVH is culling effectively

vestal minnow
#

Yeah whatever works best in terms of perf is fine, for the current spatial query pipeline the allocations and overhead were insanely large with the old approach lol

#

I'm not sure why I did it like that originally, I must have had some weird reason thonk

cinder summit
#

No both of us just didn't understand BVHs bavy

#

I even remember helping with the generations thing but the implementation makes no sense

#

Also as for that TODO

#

I just changed my impl to get rid of position/rotation

#

It's just Entity, CollisionLayers, Aabb now

#

I need to query some C: QueryCollider anyway πŸ™ƒ

vestal minnow
#

Yeah that's pretty ideal, assuming the cost of ECS queries isn't a problem

cinder summit
#

Shoudln't be an issue considering how much the BVH can skip

vestal minnow
#

Box2D also does a thing where it stores category bits (our CollisionLayers::memberships) in internal BVH nodes, which lets it early-out for incompatible layers earlier. That would probably require changes to OBVHS itself though

#

also I have to say that from a dev POV, the physics diagnostics stuff is probably one of the best features I ever added to Avian πŸ˜‚ it makes it so much easier and more motivating to optimize things and detect bottlenecks

cinder summit
#

It does seem pretty neat yea

chilly cradle
little maple
vestal minnow
#

I'll try to set up a 0.15 branch with that later today

little maple
#

I think I just need to remove the no-std stuff in my fork of bevy_transform_interpolation

#

ah, there's a bit more... I don't know, I probably should be working toward using 0.16 anyway

oak vigil
vestal minnow
umbral kelp
#

what could make 2 rigidbodies move differently, when rigidbody A is moved by a joint and I copy the velocity over to rigidbody B.

vestal minnow
#

Rigid bodies are moved multiple times per timestep in the substepping loop. You'd need to copy the velocity right before position integration within the substepping loop to get similar behavior

umbral kelp
#

similar behavior means, it's not a good way to do it? :P I basically just wanna "group" a bunch of rigidbodies, and mirror the movement of a placeholder to all of them.

vestal minnow
#

If you want the other entities to replicate the movement of one body exactly, do those other bodies need to be (dynamic) rigid bodies, or could they just be normal entities whose transforms you update manually to mirror that one body?

umbral kelp
#

they are part of a simulation, but I set them to kinematic for the time they are moved

#

so I tried setting the transform, but that desyncs, so it would need a more complex approach of removing them completly from sim and then back?

vague pebble
#

Curious how would in avian avoid camera 3d clipping into collidables?

vestal minnow
#

I haven't implemented a camera like that but I think typically you'd do ray casts or shape casts around the camera to see where it can and can't move and how far it is from the environment

umbral kelp
vague pebble
vestal minnow
umbral kelp
vestal minnow
#

Ehhh maybe, I generally wouldn't nest rigid bodies in a hierarchy, the behavior there isn't very well defined or tested atm

umbral kelp
#

so set the translation according to.. what exactly? I'd love there to be delta movement accessible

vague pebble
vestal minnow
#

I think you'd rather do the ray cast before the camera is moved, and limit the movement such that the camera doesn't move past the hit distance returned by the ray. So rather than moving the camera back along the normal, you'd prevent it from intersecting things to begin with

vague pebble
#

I am gonna give it a shot, I think that would be a cool example to add to avian and panorbit camera πŸ™‚

vestal minnow
#

There are likely a lot of edge cases that you might need to handle though, depending on how you want it to feel

vague pebble
vestal minnow
visual sparrow
# vestal minnow The jittering and breakdancing sounds like it could be either an angular inertia...

I tried changing the prop colliders to primitives and keeping the floor a convex hull, but that didn't change. Interestingly, the mass seems to make quite a difference. No matter the shape, if I up the default_density in the ColliderConstructorHierarchy, the problems lessen. At density 1, everything looks as in the video. At density 10, the only artifact is jitter. At density 100, there's just a bit of jitter occasionally.

#

Dunno if that's relevant information, but at least it's a workaround for now

#

I remember there used to be an issue laying around that involved small shapes colliding with big triangles, maybe that's related?

half ruin
visual sparrow
half ruin
visual sparrow
#

see the avian examples of that crate πŸ™‚

vague pebble
half ruin
vague pebble
#

A deterministic implementation, unfortunately tnua went a little too deep on the dyn types. Making serialization and validation quite a nuisance

#

If singleplay he is perfect tho

half ruin
vague pebble
half ruin
vague pebble
#

I use dynamic bodies

#

I have a pseudo ttnua impl

chilly cradle
half ruin
#

LockedAxes::new().lock_rotation_z() ?

#

hm, switched to Dynamic body, it moves not too smooth ) what I need to know about Dynamic body for player model?

vague pebble
#

OR disable floor friction

half ruin
vague pebble
#

Make it floati means make it float, either turning off gravity or making a spring dampener in it is lower bounds

#

Usually the later should be the go to

#

In the end friendorino, a controller is an expression of your game, lots of variables and things you may wanna change

vestal minnow
chilly cradle
#

Yeah correct

vestal minnow
#

Are you using Avian?

chilly cradle
#

Yes, avian3d

vestal minnow
#

Avian itself doesn't support big_space (yet), that branch should just make bevy_transform_interpolation work with it

chilly cradle
#

Oh I've misunderstood then. I thought it was an underlying package of avian

#

That would then enable support when using this branch, my mistake

vestal minnow
#

Yeah Avian does use bevy_transform_interpolation, but that's only for interpolation support, doesn't make it work with big_space

chilly cradle
#

Gotcha!

#

Thanks for clarifying!

jovial herald
#

are collision events sent on the frame where the collision ends?

#

I notice Contacts has is_colliding_current/past_frame

#

but I can't seem to catch the end of the collision with Collision, though CollisionEnded works

vague pebble
#

What is the diff between cast_ray and cast_ray_predicate?

sweet sundial
#

"predicate: A function called on each entity hit by the ray. The ray keeps travelling until the predicate returns true."

vague pebble
little maple
#

I know I'm altering the translation and the rotation and it seems to get stuck spinning there when I'm trying to change the rotation (to make the vehicle point forward/be upright)

gaunt loom
#

I feel like I'm taking crazy pills - I can't get my sensors to detect collisions

#
  commands.spawn((
    Transform::from_xyz(0.0, 0.0, 100.0),
    Sprite { image: asset_server.load("player.png"), ..Default::default() },
    RigidBody::Kinematic,
    KinematicCharacter,
    Collider::circle(12.0),
    DesiredMove::default(),
    ApplyDesiredMove { max_speed: 100.0 },
    Player,
  ));
#
    commands.spawn((
      Transform::from_xyz(200.0, y as f32 * 32.0, 100.0),
      LinearVelocity(Vec2::new(-60.0, 0.0)),
      Sprite::from_image(asset_server.load("fireball.png")),
      Collider::circle(8.0),
      RigidBody::Kinematic,
      Sensor,
      Projectile,
      DeleteProjectileOnCollision,
    ));
#
fn handle_projectile_collisions(
  mut collisions: EventReader<Collision>,
  projectiles: Query<(), With<Projectile>>,
  mut commands: Commands,
) {
  for collision in collisions.read() {
    let is_projectile_1 = projectiles.contains(collision.0.entity1);
    let is_projectile_2 = projectiles.contains(collision.0.entity2);
    dbg!(collision);
    //... some other stuff
  }
}
#

And I definitely have the physics plugin added

little maple
#

well

gaunt loom
#

Yeah but I don't use that fact until after the dbg print

little maple
#

hmm

gaunt loom
#

Like I'm not getting any printing

#

Hence why I'm going crazy haha

#

This is avian2d btw

little maple
#

have you tried turning on the avian debug visuals?

gaunt loom
#

Yup, they seem to show the colliders in the right spot!

#

The fireballs have colliders seemingly

sweet sundial
#

when's the system run?

gaunt loom
#
    .add_systems(
      PhysicsSchedule,
      handle_projectile_collisions.in_set(PhysicsStepSet::Last),
    )
#

Possibly the wrong spot, but even if it was, I would still expect events to be handled for the next frame

#

WAIT WHAT THE HECK

#

This system isn't even running???

#

i am so dumb

#

i didn't add the dang plugin

#

arghhhhhhhh

#

that's what I get for splitting up things into separate crates so early

#

Thank you both! πŸ˜… πŸ˜… πŸ˜…

#

Oh that's a little awkward - I'd like to delete my projectile if it hits something this physics frame, but deleting the object in PhysicsStepSet::Last causes a panic in avian...

#

Oh wait perhaps not, it's just my code again

#

Bleh

willow gyro
#

How can I stop rotation/angular motion (2d) when a dynamic body collides with a static body? I'm using TranslationExtrapolation instead of TransformExtrapoliation, and I even added added NoRotationEasing but it continues to happen. I only want avian to handle the linear translation part of things.

RigidBody::Dynamic,
Collider::circle(16.0),
TranslationExtrapolation,
NoRotationEasing,
LinearDamping(2.75),

edit -- I should also add that I'm only updating LinearVelocity in the movement system function.

willow gyro
#

yessss ROTATION_LOCKED is what I was searching the docs for. Thanks.

jovial herald
#

I am getting weird issues loading assets with blenvy, which result in Position and ColliderParent being wrong

#

Heirarchy is wall (Rigidbody::Static) -> wall_segment (Rigidbody::Static) -> collider (Collider via ColliderConstructor)

#

I am not certain of what order components are added, but it seems like the behavior is probably a bug for avian regardless.

#

Note that position != global transform, and ColliderParent skips over wall_segment and goes to wall

#

wall_segment does indeed have Rigidbody::Static, and if I set it to dynamic and back to static everything corrects.

#

if I change the transform or position of wall_segment everything breaks again

#

it seems in this state position is synced to transform instead of global transform

#

maybe this is the expected behavior?

#

very odd though, since it results in collider to not line up with the object

vestal minnow
#

Do you happen to have negative scaling somewhere?

#

IIRC there might be some transform propagation issues for colliders there

jovial herald
#

I fixed my issue by just not having nested RigidBody's

#

I saw your comment somewhere above that that isn't well tested

vestal minnow
#

cool, yeah for now I'd try to avoid nested rigid bodies where possible

#

for static bodies (or any rigid body really) you can just have one root body and child colliders

jovial herald
#

I am still a little confused on how the syncing of transform <-> position is supposed to work without taking into account parent transforms

#

Though it seems I can change the transform of wall (no longer a RigidBody), and it gets reflected in the Position of wall -> wall_segment -> collider

#

OH

#

When synchronizing changes in Position or Rotation to Transform, the engine treats nested rigid bodies as a flat structure. This means that the bodies move independently of the parents, and moving the parent will not affect the child.

#

I read that backward

#

position -> transform, yeah it makes sense for it to work that way

vestal minnow
#

Yeah right now there's a lot of confusing sync logic to write the physics Position (which must be in global space) into Transform (which is in local space), but we also ideally want people to be able to just change Transform directly, so we have the inverse of that as well. But it's somewhat unclear how Transform changes should work within hierarchies for physics entities, and making it work properly gets pretty cursed

magic tiger
#

hey i have some weird dependency issue i cant get behind, basically im using avian2d with f32, but it imports parry2d and parry2d_f64 for me, so some types come from one crate, some from another

cargo.toml definition:
avian2d = { version = "0.2.1", features = ["serialize", "simd"] }

what can be done here?

true hearth
#

have you double checked your use statements to see if everything is consistent there?

kind moss
prime turret
#

it looks like the rc4 release broke the bevy-0.16 branch; is that something you'd take a PR for?

vestal minnow
#

the main branch supports the latest rc

vestal minnow
vague pebble
#

@vestal minnow Made that little code we talked about was wondering if you would like to give any opinions especially when it comes to handling the precision of the raycast distance, which becomes quite imprecise when anchored entity moves. It works fine I think

/// Check ray direct
fn avoid_wall_collisions(
    mut query: Query<(&mut ThirdPersonCamera, &Transform), With<MarkerPrimaryCamera>>,
    transform: Query<&Transform, Without<MarkerPrimaryCamera>>,
    spatial_query: SpatialQuery,
) {
    let (mut tps_camera, camera_transform) = query.single_mut();

    let entity = tps_camera.anchor;

    if let Ok(transform) = transform.get(entity) {
        let direction = (camera_transform.translation - transform.translation).normalize_or_zero();
        let dir = Dir3::new(direction).unwrap_or(Dir3::Z);
        let opt_ray_data = spatial_query.cast_shape(
            &Collider::sphere(0.4),
            transform.translation,
            Quat::IDENTITY,
            dir,
            &ShapeCastConfig::default().with_max_distance(6.5),
            &SpatialQueryFilter::from_mask(GameLayer::Map),
        );
        let smoothing = 0.1;
        if let Some(ray_data) = opt_ray_data {
            // Means camera is probably colliding with something behind itr
            if ray_data.distance <= tps_camera.radius {
                let safe_distance = (ray_data.distance - 0.2).max(0.1);
                if let Some(prev_pos) = tps_camera.target_radius {
                    tps_camera.target_radius =
                        Some(prev_pos * (1.0 - smoothing) + safe_distance * smoothing);
                } else {
                    tps_camera.target_radius = Some(safe_distance);
                }
            } else {
                tps_camera.target_radius = None;
            }
        } else {
            tps_camera.target_radius = None;
        }
    }
}```
sleek thicket
#

@vestal minnow i'm moving and rescaling transforms with colliders when resizing window, and while the game is paused colliders don't get updated until game is unpaused, what's the right way to update them without unpausing or stepping?

calm sundial
#

Two physics Gltf extinctions are planned this year https://github.com/eoineoineoin/glTF_Physics?tab=readme-ov-file waiting for review/ratification. Blender Gltf physics importer/exporter is also ready https://github.com/eoineoineoin/glTF_Physics_Blender_Exporter and adds additional physics panel (see screen). We can't implement Gltf physics importer in Bevy repo until Bevy has it's own physics, but maybe we can add (hacky) support to Avian when these extensions are ready (or draft in Bevy repo with Avian)?
New Gltf roadmap 2025 https://youtu.be/jeYE23Dn8r8?t=518

GitHub

Proposal for adding rigid body dynamics extension to glTF - eoineoineoin/glTF_Physics

GitHub

Plugin for Blender to enable export of rigid body info when exporting glTF files - eoineoineoin/glTF_Physics_Blender_Exporter

The Khronos Group held "3D on the Web," a special event in San Francisco on March 19th during the week of GDC 2025. The gathering united the brightest minds in glTF, WebGL, WebGPU, and the future of interactive 3D on the web.

https://www.khronos.org/events/3d-on-the-web-2025

β–Ά Play video
vestal minnow
#

(also cc @valid fog)

#

I haven't looked at the spec too closely in a while, but it'd be cool to support it in some way. It could be a separate crate or just in Avian directly, behind some feature flag