#Avian Physics

1 messages ยท Page 33 of 1

calm sundial
#

They started implementing these extensions approximately in 2023.

vestal minnow
#

yeah I remember aaronfranke was also here asking about opinions on glTF physics and what would work for Bevy back then

#

(starting here #math-and-physics message)

calm sundial
valid fog
#

Hell yeah

#

Yeah rn its really hard to support the current extension for physics ( omi ) just because of how bevy's asset loading works rn with gltf

#

It makes it hard to do it for a 3rd party crate ( like avian ) it would be fine for bevy but bevy doesn't have the physics structs upstreamed and the gltf loader doesn't have a good way for us to hook into it and apply our own transformations

#

If we had some base physics structs upstreamed representing things like colliders, static vs dynamic vs kinematic, etc, that could then be used by both rapier and avian that would be awesome

#

I had a pr for avian at one point that added omi physics support predicated on another pr to bevy that never got merged that made the gltf loading more extendable

calm sundial
#

It seems the extension schema https://github.com/eoineoineoin/glTF_Physics/tree/master/extensions/2.0/Khronos/KHR_physics_rigid_bodies will not have type static, dynamic, kinematic and will instead have bool isKinematic (false meaning dynamic?). See comment https://github.com/eoineoineoin/glTF_Physics/issues/4#issuecomment-1900631052 and one below it. Quesiton.. wIll Avian be able to fully parse this extension without explicit "static" and infer it using isKinematic and remaining fields?

GitHub

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

GitHub

The draft spec README currently has this isKinematic boolean value: Type Description isKinematic boolean Treat the rigid body as having infinite mass. Its velocity will be constant during simulatio...

vestal minnow
#

I guess we would just insert RigidBody::Static for nodes that aren't rigid bodies but have (child) colliders

#

since the spec says that colliders of nodes that don't have motion properties should be treated as static geometry

valid fog
#

bruh the omi extension was way better

#

what is this ****

#

they put a lot of work into the omi extension it was also basically a 1-1 mapping with avian, entirely coquencidentially

#

this sucks fr

calm sundial
#

They are asking for feedback. Leave comments if something is missing ๐Ÿ™‚

valid fog
#

my feedback: upstream omi_physics as is ๐Ÿ˜‚

valid fog
#

it looks like the msft people won ๐Ÿ˜”

#

I need to look closely at both of them so i can remember what's going on, i don't actually remember at this point it's been too long

vestal minnow
#

the choice of no explicit static bodies is definitely interesting... I know Unity and some scene formats are like that, but at least every physics engine I know definitely has static objects as a separate thing and concept

#

i.e. Avian, Rapier, Box2D, Jolt, Bepu...

valid fog
#

As the implementer of the premier physics engine for rust i would def comment maybe you could convince them!

vestal minnow
#

Wait... you can't even have static compound colliders? thonk

valid fog
vestal minnow
#

or no am I reading that wrong

#

I might be

calm sundial
#

How it will look can be tested using blender extension. We can add rigid body (blenders component under physics tab) to object in Blender. Now how to make this object static, dynamic or kinematic using blender physics panel and additional one?

vestal minnow
# vestal minnow Wait... you can't even have static compound colliders? <:thonk:11538514657654907...

I assume they mean that if you have multiple collider nodes as descendants of a node without motion properties (i.e. a static body), it would be treated as a compound collider. However for us it's currently important to distinguish between child colliders (every collider is its own entity) and actual compound colliders (Collider::compound on a single entity) which isn't really covered by the spec afaik

#

same goes for bevy_rapier I think

calm sundial
#

If something is missing we can use gltf custom properties to extend the extension as last option.

royal helm
#

are there any KCC impls for avian yet?

#

or well, move and slide kinds of methods

#

I made my own a while back with some issues

#

I know some others were working on their own versions

calm sundial
#
GitHub

glTF_Physics_Godot_Importer. Contribute to eoineoineoin/glTF_Physics_Godot_Importer development by creating an account on GitHub.

GitHub

Contribute to eoineoineoin/glTF_Physics_Babylon development by creating an account on GitHub.

vestal minnow
#

namely, what it calls a cast mover, collide mover, plane solver, and velocity clipper

vestal minnow
#

I think that might be the final PR for major optimizations this cycle... I'll probably start working more on release prep and minor QoL things now

#

Maybe I'll take a crack at those observable collision events too ๐Ÿค”

#

oh and I was supposed to finish the no_std branch now that my PR landed in Parry

sleek thicket
#

bump @vestal minnow ๐Ÿ˜ญ

vestal minnow
#

I'm not sure if there's a good way to do that ๐Ÿค” I guess you could pause Time<Physics> so that actual physics doesn't run, but manually run FixedPostUpdate, which is where the systems that update physics transforms currently live? Assuming you don't have game logic there that you don't want to run

#

hmmm though that doesn't update collider AABBs since that happens inside the PhysicsSchedule

#

if the goal is to update the colliders such that you can do spatial queries on them then I think that should actually be fine with the current setup

sleek thicket
#

i don't think i have anything running there, but it might become a footgun
and i do the spatial query on them ๐Ÿฅฒ
i was thinking of just disabling window resizing, but i just realized that it might come up again once i start working on VR

vestal minnow
#

Yeah I haven't tried this but it might work?

  1. time.pause() (where time is ResMut<Time<Physics>>)
  2. world.run_schedule(FixedPostUpdate)
  3. spatial_query.update_pipeline() (where spatial_query is SpatialQuery)
#

and then unpause later

#

feels somewhat hacky though

sleek thicket
#

ty, gonna try in a bit
and i'll just comment that it's a placeholder until something better comes up

#

@valid fog there's no way VR won't need pausing that requires physics to run, right? maybe you can figure something out

sleek thicket
vestal minnow
#

@surreal rune So I have no_std Avian compiling, except with thumbv6m-none-eabi, because Parry uses downcast-rs with the sync feature, and synchronization primitives aren't available there :/

#

How important would it be to support targets without synchronization primitives?

#

like is no-atomic support only needed for very low-level embedded stuff or something, or is it also necessary for retro consoles like the GBA?

surreal rune
surreal rune
#

Since DowncastSync requires DowncastSend, which itself requires Downcast, I suspect you could just replace DowncastSync with Downcast and everything would be fine (maybe)

sleek thicket
vestal minnow
#

Also I had to add this thing, or alternatively handle Commands and ParallelCommands separately in half a dozen ugly cases... could be nice to have in Bevy itself, just making ParallelCommands a thin wrapper over Commands in no_std environments

visual sparrow
vestal minnow
#

observable collision events are working :D just need to do some documentation work and I'll probably make a PR

#

It does probably add a small amount of overhead, but it should be pretty minimal, especially since collision events are opt-in and this is only for started/ended collisions. I doubt people would have tens of thousands of collisions starting or ending every frame anyway :P

sleek thicket
runic tinsel
#

I want to have a setup where I have a dynamic RigidBody that starts as a single small cube, and then I want to add cubes onto it dynamically. I'm assuming that I can just add colliders as children of the original cube, and the mass stuff will be figured out automatically, at least that's how I understood it from the docs, however what about something like impulses and forces? If I apply it to a child, will it be applied properly to the entire 'construction'? Also should I add the other cubes to the cube as children, or with joints?

vestal minnow
#

If you want the cubes to be fixed together with perfectly rigid attachments then you want to use child colliders. Joints only try to constrain positions, they are not perfectly rigid and can be prone to instability in more complex scenarios, plus they are likely more expensive

#

And yeah mass should get updated automatically when you add or remove colliders, unless you add the NoAutoMass component to the rigid body

vestal minnow
runic tinsel
surreal rune
visual sparrow
vestal minnow
#

Damn, I really want to land the SolverBody stuff...
Left: Before reworked contact pair management or solver bodies
Right: After both reworked contact pair management and solver bodies

#

Hmm I can probably get it working before the joint rework too, just need to store a bit of extra data that wouldn't be necessary if joints didn't use XPBD

#

lemme see if I can get something like that working

calm sundial
#

I checked upcoming Blender Gltf physics addon.
As mentioned earlier Gltf physics schema is not going to have explicit type: static, dynamic, kinematic and will have bool isKinematic. it's similar situation with Openusd format that has PhysicsRigidBodyAPI:kinematicEnabled https://openusd.org/release/wp_rigid_body_physics.html#kinematic-bodies. Gltf maintainers also mentioned in the road map video that they try to make Gltf compatible with Openusd.

Part of comment from https://github.com/eoineoineoin/glTF_Physics/issues/4 that explains Gltf schema :
"... There's three types; static bodies (colliders who do not have a parent with a rigidBody property), dynamic bodies (nodes with a rigidBody), and kinematic (nodes with a rigidBody whose isKinematic=true) ..."
So it seems Avian will have enough information to parse the type correctly.

But how to export static rigid body from Blender?? In Blender you can only specify collider shape after rigid body is added to an object. And it seems Gltf addon https://github.com/eoineoineoin/glTF_Physics_Blender_Exporter additional physics panel doesn't cover this.

GitHub

The draft spec README currently has this isKinematic boolean value: Type Description isKinematic boolean Treat the rigid body as having infinite mass. Its velocity will be constant during simulatio...

GitHub

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

calm sundial
#

Full compatibility with Openusd/Gltf seems important if Avian is going to be upstreamed. Maybe we should take into account compatibility while Avian is in active development and it's easier to change stuff. There is also one more upcoming Gltf extension "Interactivity" that has some physics related fields (iirc).

sleek thicket
calm sundial
#

"KHR_collision_shapes is deliberately separated from KHR_physics_rigid_bodies to enable the geometries to be used by any number of future extensions, not necessarily limited to the domain of rigid body simulation. For example, node selection or 3D UI components, etc."

#

KHR_implicit_shapes importer can be implemented in Bevy even without physics.

vestal minnow
#

I have to implement it fully now, don't I ferris_sob

#

geez louise this will be such a large PR again

#

And possibly controversial? ๐Ÿค” It does mean that users can't (easily) access up-to-date body data inside the solver, unless they're willing to use SolverBodys and stuff

#

but honestly I don't care too much about that, since having user systems deep in the internals like that is kinda sketchy anyway, and not worth losing a 3x perf boost for

keen light
#

which approach are you guys using right now to generate colliders?

#

Collider::trimesh_from_mesh(mesh) for each loaded mesh or is there something better

visual sparrow
#

In general, convex hulls a bit more well-behaved and faster to compute with, so I prefer ColliderConstructorHierarchy::new(ColliderConstructor::ConvexHullFromMesh)

keen light
#

yup works even better thanks

#

but my fps does tank quite a bit after adding colliders to everything, is this normal?

kind moss
keen light
#

Yeah I was thinking something similar so i also tried with cylinder but again <1 fps

#

Could it be because everything is always colliding with each other? I only have a couple dozen objects

kind moss
#

Yeah, a dozen objects shouldn't be that slow unless maybe they have ridiculously complex colliders.

kind moss
keen light
#

Nope everything default, just loading gltf and adding colliders

kind moss
#

Huh, and it's slow even if you only give each object one simple cylinder collider? That's weird. Can you share the code?

keen light
#

use bevy::{
    dev_tools::fps_overlay::{FpsOverlayConfig, FpsOverlayPlugin},
    prelude::*,
    text::FontSmoothing,
};

use bevy::{prelude::*};
use avian3d::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_plugins( PhysicsPlugins::default())
        .add_plugins(  FpsOverlayPlugin {
            config: FpsOverlayConfig {
                text_config: TextFont {
                    // Here we define size of our overlay
                    font_size: 42.0,
                    // If we want, we can use a custom font
                    font: default(),
                    // We could also disable font smoothing,
                    font_smoothing: FontSmoothing::default(),
                },
                text_color: Default::default(),
                enabled: true,
            },
        },
        )
        .add_systems(Startup, setup)
        .run();
}
#[derive(Component)]
struct ColliderInserted;

/// set up a simple 3D scene
fn setup(
    mut commands: Commands,
    asset_server: Res<AssetServer>
) {
    commands.spawn((
        SceneRoot(asset_server.load(
            GltfAssetLabel::Scene(0).from_asset("glTF-Sample-Models-main/glTF-Sample-Models-main/2.0/ABeautifulGame/glTF/ABeautifulGame.gltf"),
        )),
        ColliderConstructorHierarchy::new(ColliderConstructor::Cylinder{radius: 0.5, height: 1.0}),
    )
    );
    commands.spawn((
        Camera3d::default(),
        Transform::from_xyz(-2.5, 4.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y),
    ));
}

visual sparrow
#

@keen light low hanging fruit: does your Cargo.toml contain the standard Bevy optimization stuff?

keen light
#

Nope, but my fps is going from 140 to <1 after colliders are added, does the optimization help that much?

visual sparrow
vestal minnow
#

running in release mode or with debug optimizations can be like over a 100x perf improvement

visual sparrow
#
[dependencies]
# Compile low-severity logs out of native builds for performance.
log = { version = "0.4", features = [
    "max_level_debug",
    "release_max_level_warn",
] }
# Compile low-severity logs out of web builds for performance.
tracing = { version = "0.1", features = [
    "max_level_debug",
    "release_max_level_warn",
] }

# Enable a small amount of optimization in the dev profile.
[profile.dev]
opt-level = 1

# Enable a large amount of optimization in the dev profile for dependencies.
[profile.dev.package."*"]
opt-level = 3

# Remove expensive debug assertions due to <https://github.com/bevyengine/bevy/issues/14291>
[profile.dev.package.wgpu-types]
debug-assertions = false
#

@keen light add this

visual sparrow
kind moss
keen light
visual sparrow
#

Then you need to add a RigidBody::Static to the SceneRoot entity

keen light
#

i want other objects to not pass through the enviroment

visual sparrow
keen light
#

and that would apply to all child objects of scene?

visual sparrow
#

A rigid body can have any colliders

#

If you have a setup like this:

#
spawn((
  SceneRoot(foo),
  ColliderConstructorHierarchy(...),
  RigidBody::Static
))
#

Then you end up with one rigid body that has n child colliders

#

Does that make sense?

keen light
#

but what would adding the rigidbody component change in this scenario

#

or is it necessary for collisions to work

visual sparrow
keen light
#

ah okay makes sense

visual sparrow
#

Like e.g. an invisible trigger area that tells you "the player is now in here"

#

A rigid body is the piece that dictates how a collision is handled

#

RigidBody::Static -> never move this entity, just make sure other things don't phase through it

#

RigidBody::Dynamic -> move this entity out of other rigid bodies

#

RigidBody::Dynamic is also the one you want to use for physical forces like gravity

keen light
#

well the optimisations took it up to 3 fps

#

i also added rigidbody::static and now its full speed ๐Ÿš€

vestal minnow
#

ah

keen light
#

maybe self-collisions somehow messed it up?

vestal minnow
#

yeah that's probably because when they're colliders that aren't attached to a rigid body, they're computing contacts against each other, but if they're attached to the same body, it filters out self-collisions

vestal minnow
#

Semantically, Collider should be just a shape, and then the RigidBody or Sensor defines how it's used

visual sparrow
#

I think we had chat about this same thing like a year ago

#

Because I was definitely running into confusion about that back then

#

once you know the avian model of rigid bodies and colliders it's fairly simple, but getting there is very unintuitive

kind moss
keen light
#

I dont think I saw examples of physics systems, maybe it could help to have some?

#

or did i miss them

vestal minnow
#

What kind of physics systems? There are some Avian examples for 2D and 3D, though not nearly as many as we should have

keen light
#

I was only looking at the bevy examples

vestal minnow
# visual sparrow once you know the avian model of rigid bodies and colliders it's fairly simple, ...

Yeah agreed, I think the ideal solution would be

  • Collider on its own does nothing, it just emits a warning.
  • Collider attached to a RigidBody (on the entity or as a descendant) is part of the ContactGraph. If it is not a Sensor, it computes ContactPairs for collisions against other rigid bodies.
  • Collider that is a Sensor is also a part of the ContactGraph (or something like an IntersectionGraph if we want to split it) but does not compute ContactPairs, it only detects intersections, sends events, and updates CollidingEntities, if it exists.
#

I think really the only remaining open question I have in terms of UX is whether collision events for rigid bodies and sensors should be separate or not

vestal minnow
#

Some engines like Box2D have separate events like b2ContactBeginTouchEvent and b2SensorBeginTouchEvent, but I'm unsure if that's useful or just prone to causing more confusion

#

I feel like for sensors you might often want special behavior, in which case using observers may be the play, and if you're targeting the sensor entity then it'd make sense to only have one event since you know you're dealing with a sensor anyway

#

Purely in terms of efficiency, it would probably be better to have separate event types to minimize reading unnecessary events, but I'm just worried people might try to read CollisionStarted events for sensors and be confused why it's not working

#

Hmm there are also some weird edge cases there ๐Ÿค” If we had separate events, and you removed the Sensor component while another collider was overlapping it, should that fire an event for the sensor intersection stopping and a contact beginning? If we had just one event type, it probably shouldn't fire an event at all until they actually stop overlapping

sleek thicket
sleek thicket
cinder summit
vestal minnow
#

I feel like it should be possible to have shapes that are only used for spatial queries, not for contacts or sensor scenarios, so that's probably something we should still support

cinder summit
#

Worth considering if we want sensors to get hit by spatial queries, I remember that causing many bugs for rapier users ๐Ÿค”

vestal minnow
# vestal minnow I feel like it should be possible to have shapes that are only used for spatial ...

So the updated approach would be

  1. Collider on its own is just a shape in the world, and participates in spatial queries.
  2. Attaching a Collider to a RigidBody makes it also compute ContactPairs for collisions against other rigid bodies.
  3. Making a Collider a Sensor overrides (2) and makes it simply detect intersections and send events (and still participate in spatial queries unless you filter them out)
cinder summit
#

At least if it's all colliders it makes some sense they'd be in there though, unlike if it's just RigidBody and Sensor

sleek thicket
sleek thicket
vestal minnow
# sleek thicket you can already do that by just using a layer mask/filter collider that doesn't ...

From my POV, a Collider is just a shape optimized for geometric queries. We could even rename it to Shape if we wanted to, like how Box2D has b2Shape. It really only has three purposes:

  1. Physics (detect and compute contacts for rigid bodies)
  2. Sensors (detect when entities overlap a "trigger area")
  3. Spatial queries (ray casts, shape casts, point queries, etc.)

A RigidBody associates a Collider with (1), unless a Sensor associates it with (2). But a lot of games might not need any collision pipelines or physics, and just want (3). Imo you shouldn't need rigid bodies or sensors to perform spatial queries; fundamentally, you're just querying a tree of shapes for geometric information, which shouldn't need any connection to physics

#

Ex: Maybe for efficient picking support you want to use simpler primitive shapes rather than rendering Meshes. You attach Collider/Shape to those meshes. But they shouldn't otherwise have any physics or overlap detection

sleek thicket
#

yeah i'm worried about games that don't need collision pipelines or physics too, but i think making a collision library would be a better solution for them

vestal minnow
#

Yes well ideally we could maybe have colliders and spatial queries in a separate crate that people can use, and then have Avian integrate with that, providing physics on top of it in some way

#

The broad phase and narrow phase are pretty heavily tied to physics if we want to keep it fast, so splitting that out from Avian would be pretty difficult. But I think we could technically split out colliders and some of the core spatial query pipeline stuff, providing a thin wrapper for physics-specific APIs in Avian, assuming that physics is still allowed to drive stuff like when and how the BVH is updated

sleek thicket
vestal minnow
#

We could upstream some collider type, but like, Rapier still uses Parry, so you wouldn't be able to use it there, unless it internally converted it to Parry shapes. Bevy also doesn't have convex polyhedra, non-rendering trimeshes, heightfields, etc.

sleek thicket
#

which ones do oUSD/gltf have though

vestal minnow
#

it was some super limited set of shapes, lemme find it

sleek thicket
#

oUSD: we suggest the support of UsdGeomCapsule, UsdGeomCone, UsdGeomCube, UsdGeomCylinder, UsdGeomSphere and UsdGeomMesh, though the precise set of supported geoms might be implementation specific

vestal minnow
#

I think glTF is just sphere, box, cylinder, capsule, convex hull

sleek thicket
sleek thicket
vestal minnow
#

it's in the rigid body README's geometry section

#

not an implicit shape

vestal minnow
#

It'd basically be a Bevy-native collider and spatial query crate then

sleek thicket
#

yeah i was just about to say that

vestal minnow
#

One part of Peck I've been dreading implementing is convex decomposition, but maybe the rational short-term solution there would be to just directly port Parry's VHACD algorithm to Glam and release that as its own crate ๐Ÿค”

#

rather than spending ages implementing that or CoACD from scratch (though CoACD would be nice eventually)

calm sundial
#

"Exactly one of shape or node should be provided."

6 types?
If there is "shape". Use one of 4 shapes from KHR_implicit_shapes.
If there is "node". Use mesh.
If there is "node" and convexHull = true. Use convex hull.

calm sundial
#

Extension "KHR_Interactivity" with physics related fields:
rigid_body/applyImpulse
rigid_body/applyPointImpulse
rigid_body/rayCast
event/rigid_body_triggerEntered
event/rigid_body_triggerExited

vestal minnow
#

These nodes are used to apply impulses to a dynamic rigid body, useful when the mass or inertia of a motion is not known in advance.
that's not how impulses work, not in real life or in physics engines ferris_sob

#

an impulse is a change in momentum, which considers mass

#

In other news, I have all joints working with the SolverBody stuff, so I technically have an MVP ready... I need to do a ton of clean-up and documentation work and testing though

#

This requires computing and storing initial anchors and other positional data for joints before the substepping loop since the solver only has access to position and rotation deltas now... It's a fairly intrusive change :P

vestal minnow
#

yeah this will be at least a 4k line PR once I'm done with this ๐Ÿ˜‚ current progress, missing a ton of docs and clean-up

#

the branch is here if someone wants to try it for whatever reason... heavily WIP

visual sparrow
#

@vestal minnow off-topic: is there an easy way to get a rigid body's center of mass?

vestal minnow
#

ComputedCenterOfMass

visual sparrow
#

thanks!

vestal minnow
#

I'm also sort of trying my own thing with how I store mass properties for the solver ๐Ÿค” Box2D stores the mass and angular inertia of each body in each constraint, but I feel like that'd result in too much memory usage in our case with 3D and support for locked axes, so I instead store them in a separate Vec with a SolverBodyInertia for each SolverBody. I figured out a way to make it just 16 bytes in 2D and 32 bytes in 3D, which I'm hoping will make it good for memory locality and fast access

#

or right now it's 44 bytes in 3D, but it will be 32 bytes once I implement a custom SymmetricMat3 type ๐Ÿ™ƒ

#

I think I actually have an old branch with that already

visual sparrow
#

@vestal minnow just ran into a maybe weird use-case: is it possible to create a convex hull from an already existing collider?

vestal minnow
visual sparrow
#

Is there a quick way to get a rigid body AABB?

#

I could build a compound shape of the collider AABBs and then compute the AABB of that

vestal minnow
#

I guess you'd iterate over the ColliderAabbs of the attached colliders and use the merged method

visual sparrow
cinder summit
vestal minnow
#

Yeah I mean this touches the whole solver and all constraints, and involves some extra bookkeeping and writeback, so it's pretty big

#

The perf gains are pretty huge, but tbh I might just leave this for Avian 0.4, since I'm not sure if I'd be comfortable merging this so late in the cycle without extensive testing and getting some feedback first (if I even get this "ready" before 0.16 releases)

#

We have so many things halfway done that 0.4 might end up being a crazy release lol

#

0.3 is mostly just improvements to collision detection and related features, it's a bit smaller than average in terms of shipped things

vestal minnow
#

the solver isn't even that big of a bottleneck there, the narrow phase, broad phase and BVH updates start to get kinda costly

#

should get a bit better with the BVH broad phase and other related improvements

#

"Store Impulses" being 1 ms is interesting thonk

vestal minnow
#

Hmm I guess I'm making another modified version of petgraph's undirected graph, this is probably the third version now ๐Ÿ˜‚

#

I basically need a mix of UnGraph and StableUnGraph, where the edge connectivity list keeps stable indices, but edge weights are stored separately and can be swap-removed to get rid of contact pairs

#

StableUnGraph keeps vacant edges around, which means the narrow phase would need to also unnecessarily iterate over non-existent contacts, so I can't use that. And UnGraph doesn't maintain a stable order at all for removal of nodes or edges

#

So I guess I'll split out edge connectivity data and edge weights and maintain a contact ID pool or something ๐Ÿค”

vestal minnow
#

fixes some scuffed handling of contact removal too

vestal minnow
#

nice it actually optimizes things too (left is old, right is new)

vestal minnow
#

hmm right we should also have separate active and sleeping contacts to avoid unnecessarily iterating through contact pairs for sleeping bodies in the narrow phase

#

Box2D has solver sets which also achieves this

#

god there's so much optimization work we can do ๐Ÿ˜‚ I'm addicted to optimizing rn

vestal minnow
earnest iris
#

I need to support dragging tokens using the mouse. My tokens are RigidBody::Dynamic so to collide against walls. I remember from my days using chipmunk that to properly implement dragging a dynamic entity, I had to spawn an adhoc kinematic entity and create a pivot joint with my dynamic entity.
Will the equivalent in Avian be a RevoluteJoint?

vestal minnow
vestal minnow
#

it's using an old Bevy version and bevy_xpbd (the predecessor of Avian), but it should be fairly simple to get it working with a few small changes

earnest iris
earnest iris
earnest iris
#

(My current workaround is to clamp the kinematic target entity distance from the dynamic entity, thus reducing the amount of 'force' applied by the joint)

vestal minnow
#

A partial workaround is to limit the distance like you're doing, or to scale compliance based on distance (might cause other problems?). We could/should also add an option to limit the maximum force directly

vestal minnow
# vestal minnow Not currently, no. That might change when we do the fabled joint rework (move th...

To expand on this: With XPBD, the joints are changing the positions of the constrained bodies directly. With a large enough positional correction, it can make bodies just go through other objects, or at the very least make them overlap. But if we made joints impulse-based like contacts already are, it would instead change the velocity; if we solved joints first and contacts after, the contacts could probably react to that change in velocity, and apply an impulse to counteract it before the body has been moved

#

But that being said, contacts also have some softness to them (which can be configured), so it might not perfectly ensure that joints never break bodies through other objects

vestal minnow
visual sparrow
#

Maybe by iterating over something?

#

(I say that because I see a few iter calls in that PR, but I'm on mobile, so I canโ€™t easily verify the involved types)

earnest iris
cinder summit
#

It was a lot of merge conflicts thonk
I have it compiling after rebasing it though (or at least avian2d, there are some missing trait impls for 3D types I need to sort out)
https://github.com/NiseVoid/avian/commit/ee4e8902ff179ba754f7352741c25c7ff56cccc8
Still need to implement a couple more of the spatial query functions, apply translation/rotations correctly, and then see if this trait is actually implementable as is
Also gonna need to sort out the issue where I use ColliderAabb to fill the BVH, but those are just left in whatever state they were for the broad phase

vestal minnow
# visual sparrow Are you accidentally assuming order in a hashset / map?

Nope it's just using vecs, except for some pair lookups where order doesn't matter... The initial behavior in the determinism_2d example is deterministic when single-threaded, but it's different after resetting the scene (i.e. respawning everything), and not at all deterministic when multi-threaded

#

I'm guessing the graph edges or their IDs are somehow not getting cleared or updated correctly, since edge removal now marks them as vacant (None) rather than actually removing them, and maybe that messes it up somehow? But I don't see why multi-threading would affect anything since it only adds or removes pairs serially, and the order for that should be stable

earnest iris
distant creek
#

hey guys, quick Q, how does one apply physics after a delay to an object. I want to lock axis until the terrain is generated then unlock the player. However, both unlock transform x,y,z and adding the rigid body and other components after the world has spawned to the entity seems to stop physics affecting them entirely

knotty thicket
#

the new observer collision events are quite nice

vestal minnow
#

I was thinking that it might be nice to add the rigid body entity to them too and to use named fields

vestal minnow
#

I'd double-check (maybe by logging values) that when the player should be able to move, it has

  1. RigidBody::Dynamic or RigidBody::Kinematic
  2. If it is dynamic, a non-zero ComputedMass and ComputedAngularInertia
  3. No locked axes
#

(also the general stuff like make sure you actually have PhysicsPlugins and that physics works in the general case where you're not doing anything weird, just spawning a rigid body normally)

distant creek
#

It was me being dumb

#

just an odd camera angle, and no mass

royal bridge
#

I'm trying to use Avian without any of the collision detection stuff, just the spatial queries and dynamics
Right now I only add these plugins and spatial queries appear to work well and the performance is decent:

PhysicsSchedulePlugin::default(),
PhysicsTypeRegistrationPlugin,
PreparePlugin::default(),
MassPropertyPlugin::default(),
ColliderHierarchyPlugin,
IntegratorPlugin::default(),
SpatialQueryPlugin,
SyncPlugin::default(),

But none of the velocity components (for example) appear to work. I'm not sure what I'm missing (probably something obvious ๐Ÿ˜…)

For context, I have tens of thousands of entities and I only really want spatial queries against them (adding the default plugins outright crashes it)
I considered a custom solution using OBVHS but Avian has some nice convenient features and I'm not sure if OBVHS has existing support for non-ray based queries.

Not a big deal if those components won't work. Easy enough to do manually, but thought it work asking.

cinder summit
#

Wrapping things up into a nice and performant API is still a lot of work though, which is exactly why I'm reworking avian rather than building my own SpatialQuery API for my SDF collisions again

royal bridge
#

Oh neat! That sounds great, I look forward to it

clear dew
#

does anyone have on hand their commit revision for running crate examples on rc5?

#

I've gone back two to no avail (which is totally fine :D) but was wondering if there's a revision with working examples atm? nw if not

#

ah! my fault! run in crate root!

valid zenith
#

Just wondering, does avian have any support for hierarchal collisions?

by that i mean, say i want to create mesh accurate collisions but i dont want to incur the cost of a trimesh, could i simply define a series of increasingly small sphere colliders and have avian only emit a collision event for the "smallest" (or deepest) collider hit, or is that the kind of thing you have to implement yourself

#

LUL nvm answered it myself (i shouldve just googled) bounding volumes are supported because of parry pog

valid zenith
#

mightve spoken too soon on that, went back to avian docs and not finding anything for bounding volume stuff monkaHmm
I know bvh is used under the hood for optimisation, so maybe if you just add a bunch of sphere colliders to a mesh for coverage itl "generate" the bounding volumes for you, but i wouldnt want to just assume itl do that

runic tinsel
valid zenith
# runic tinsel I'm pretty sure you can just keep adding children to a rigidbody, and then have ...

yeah if only the child emits then its probably acting like a BVH

with a BVH youd do something like have one big sphere collider for the entire entity, then two smaller colliders for their top and bottom half, then smaller colliders inside those, and keep getting smaller until you have the resolution you want.

So to check if the left pinky on that model got hit you only have to check, 20 colliders, instead of 2000 for that model (to use an extreme example) because most of them got filtered out in the earlier layers of the heirarchy so dont even get checked by the solver

runic tinsel
#

Jondolf is online if you want the expert opinion :)

valid zenith
#

I would ping him but its not THAT serious LUL

runic tinsel
#

I'm pretty sure they don't mind, I see people pinging them quite often

valid zenith
#

but yeah if it is emitting from the "youngest" child with a collider on it, then it is probably acting like a bvh, because it would be a bit silly to have behaviour for relationships like that and not take the free optimisation of just not checking the children of children that didnt collide ykyk

runic tinsel
#

You could always just do a simple test

valid zenith
#

screw it
@vestal minnow you able to confirm on that?

vestal minnow
# valid zenith Just wondering, does avian have any support for hierarchal collisions? by that ...

So first off, every Collider has its own AABB to accelerate broad phase collision detection and spatial queries. Spatial queries indeed use a BVH for this, with each collider as a leaf node. But broad phase collision detection is currently using a different algorithm (sweep and prune), though I do plan on switching it to also use a BVH.

If a potential intersection is found between e.g. just two spheres, that contact is computed directly. But for composite shapes, such as trimeshes or colliders built using convex decomposition, Parry stores a separate BVH just for that shape to accelerate queries against it. So yes this optimization is kind of done automatically for some shapes

#

But there is currently no acceleration like that for actual child colliders in the entity hierarchy; every Collider is treated as its own shape in the BVH

valid zenith
#

Ah gotcha, is there a way to define a structure like that manually?

Or better yet is it even really necessary to do (not sure how fast primitive shape colliders resolve in the solver), like say i want to have a bunch of humanoid entities and i want to do zoned collisions on them, so each entity is lugging around 6+ colliders where realistically only one of them is relevant at any one time, could i instead do 3 layers of bounded volumes, one for the whole entity, one for upper limbs + head, one for lower limbs

vestal minnow
#

There's not really a way to do it that manually, no. With a BVH, if you have a collider for each of those 6+ shapes, it already computes larger bounding boxes around them sort of hierarchically based on what the heuristic thinks is (close to) optimal for traversal speed; that's kinda the point of a BVH

#

And if you did a ton of nested BVHs, that'd probably just have way more overhead since you'd need to update and traverse each of them separately, possibly losing parallelism in the process. Unless of course the "sub-BVHs" or whatever remain static like meshes often do, in which case it's useful since you don't need to rebuild those

#

(by nested BVHs here I mean multiple layers of BVH filtering at different granularities)

valid zenith
#

Ah gotcha so if im understanding right.

if i chucked a bunch of colliders on a model, currently i could check if say a bullet passed through an armpit using a raycast and it would use bvh, because its a spatial query

but for the actual physics solving its not doing that (yet)

#

effectively just looking to get close to the footprint of a trimesh, but without the huge cost of a trimesh ykyk NODDERS few spheres to get coverage on an arm vs all those vertexes

vestal minnow
#

and I intend to try changing it to use the OBVHS crate (I have some WIP prototypes)

#

But like I mentioned, collisions against e.g. meshes do still also use a BVH for filtering individual triangles after sweep and prune has found an intersection with the whole mesh's bounding box

#

since Parry stores that BVH in the trimesh itself and uses it automatically

valid zenith
#

Ah sick sick NODDERS
is there anything id need to do on my end to help the broad pass do its job like compound the colliders or something?

vestal minnow
#

I wouldn't worry too much about that in 99% of cases unless you notice from profiling that you're bottlenecked on it for whatever reason

valid zenith
#

Fair LUL

calm sundial
#

Blender is working on physics geometry nodes https://projects.blender.org/blender/blender/pulls/124093 . Currently the feature can be enabled as experimental feature. Maybe this will help exporting physics to gltf. There is "Collision shape" node (see screen), separated from rigid body.

dusty pagoda
#

hello. given that bevy is an ecs engine i thought it would be appropriate to have an old school rts-style deterministic lockstep netcode library that would scale well with huge numbers of entities. i couldn't find one already built so i started writing my own. i'm pretty new to this but making good progress. the problem i have run into now is that the determinism across clients is proving difficult to achieve when running a physics simulation.

my netcode strategy is this:

  1. client sends commands to server but does not implement gameplay effects yet
  2. server broadcasts new simulation ticks with all commands for that tick. this way everyone executes the same commands every tick.
  3. clients receive all commands for each tick and then implement the commands' gameplay effects locally.
  4. part of this involves stepping the physics sim by the same duration as the server's sim tick. it's not quite the same on the clients due to packet jitter, which is why i step everything manually

to this end, i start with the physics sim paused

.add_systems(
    Startup,
    |mut time: ResMut<Time<Physics>>| {
        time.pause();
    })

i send a command from a client to apply a force to a unit.
all clients receive this command which implements this

unit.apply_force(force_cmd.force);

immediately after this system i step the physics sim

fn step_physics(
    world: &mut World
) {
    world
        .resource_mut::<Time<Physics>>()
        .advance_by(SIM_TICK_INTERVAL);
    world.run_schedule(PhysicsSchedule);
}

unfortunately this is not enough to prevent desyncs across clients. small changes in position after collisions eventually lead to different states across clients. I have enabled the enhanced-determinism feature for avian, but it doesn't appear to make any difference. does anyone have any suggestions for how i can make this deterministic?

cinder summit
#

@vestal minnow I threw your example into the repo, started working on making it work with SpatialQuery stuff, when suddenly OBVHS panics ferris_sob

obvhs-0.2.0/src/bvh2/mod.rs:406:13:
assertion `left == right` failed
  left: 10002
 right: 10000
```<https://github.com/NiseVoid/avian/tree/generic_spatial_query> example `spatial_query` in case @thorn solstice wants to see what's going on (also Griffin might like the awful mess I made in `src/spatial_query/bvh_ext.rs`)
#

Took me a while to get the ambiguity detection to stop crashing the app too, and not just from my changes, but also existing ambiguities when multiple collider type plugins are registered ... Do we have a way to handle those currently? ๐Ÿค”

vestal minnow
#

or maybe preferably ambiguous_with, putting just the relevant conflicting systems in some system set... but I don't think we do that rn

vestal minnow
rocky seal
#

i see that SyncPlugin and PreparePlugin (i'm not sure which is relevant here) run their systems in FixedPostUpdate. is there something else that happens w/ Position and/or Transform in one of the other schedules? i have two different systems that both sometimes manually set the Transform::translation of an entity. the one in FixedUpdate works, but the one in FixedLast doesn't (i.e. the entity's translation doesn't change)

rocky seal
#

i just tested moving the latter into FixedUpdate and it works

#

so maybe there is something between FixedLast and FixedUpdate that overwrites the translation set in FixedLast?

rocky seal
#

setting the Position instead of the translation in FixedLast works as expected

thorn solstice
thorn solstice
cinder summit
vestal minnow
thorn solstice
#

Yeah sounds familiar, maybe in this context there needed to be 1 prim per leaf or something?

vestal minnow
#

that is still currently very WIP and not yet working properly, but I'll let you know how it goes when I have a chance to work on it again (probably next month)

golden shoal
#

@vestal minnow I have a question about the documentation and behavior of CollisionLayers.
The documentation states:

Two colliders A and B can interact if and only if:
1. The memberships of A contain a layer that is also in the filters of B
2. The memberships of B contain a layer that is also in the filters of A

but it doesn't say whether collision happens IFOIF one is true, or IFOIF both conditions are true.

#

this is making things hard to debug because I'm not sure whether or not I should be expecting objects to interact

vestal minnow
#

it's AND behavior, both must be able to interact with each other

golden shoal
#

alright

#

that's a big difference

vestal minnow
#

but yeah agreed, that should be made clearer in the docs

golden shoal
#

is there an easy way to suggest documentation changes, or would I have to pull the source, make a pull request, etc?

vestal minnow
#

Pull request is fastest, or make an issue (or just remind me here if I forget) and I can change it when I have a chance

willow gyro
#

My goal is to identify the selectable object nearest to the player, in order to highlight it and/or know which object to interact with when interaction input happens.

To this end, I setup CollisionLayers on all the relevant colliders and implemented a shape_intersections. That works, which is great, however, when the player is near multiple selectable objects, they will all intersect. The result of shape intersections only returns Vec<Entity> so either I need to then further calculate distance to player of intersecting colliders to figure out which is nearest, or -- and the reason I'm asking here -- is that there's a better way to achieve this.

sweet sundial
willow gyro
sweet sundial
#

that's what the query's for

#

aabbs.iter().filter_map(|&e|highlight_q.get(e)).min(|Transform{position,..}|(player_pos - position).length())

willow gyro
#

Ah yeah, that's what I meant by "calculate distance to player". That's a more succinct way, and probably something like that is what I'll go with if there's not a clearer built-in tool. You mentioned that AABB intersection is more efficient than shape intersection, why is that?

sweet sundial
#

aabbs and bounding spheres are usually the first test when determining collisions, since they're easier to calculate, so it's likely that a shape intersection would have an aabb intersection involved when there's more than one possible other shape

sharp dew
#

hey, dumb question, am i wrong in assuming that the "name" of a mesh you use in ColliderConstructorHierarchy::without_constructor_for_name is the same as the object name in blender when exporting to gltf?

i haven't been able to skip colliders for certain meshes

    commands.spawn((
        SceneRoot(scene),
        ColliderConstructorHierarchy::new(ColliderConstructor::ConvexHullFromMesh)
            .without_constructor_for_name("fakeWall"),
        RigidBody::Static,
    ));
#

inspecting the exported gltf data i can find the mesh name, though i don't know if it's relevant or not

knotty thicket
sharp dew
cinder summit
vestal minnow
#

Also I wonder if the lack of proper 2D support has any meaningful effect on it ๐Ÿค”

cinder summit
vestal minnow
#

Mm at some point I should try how bad it'd be to add 2D support to Bvh2

cinder summit
#

I had 2D support in ploc-bvh, but that was because bounding volumes were entirely a trait

#

I assume @thorn solstice had some reason for not doing that. Building on the bevy_math bounding traits makes extensibility so much easier after all

vestal minnow
#

For Cwbvh I assume the specific AABB representation is very important and can't easily be made generic, but I would think that for Bvh2 you should be able to traitify things more

cinder summit
#

Also I'd imagine if we really want to optimize the BVH stuff for avian, we're probably gonna need to make it use more Vec3A where possible

thorn solstice
# cinder summit I assume <@223685939849986048> had some reason for not doing that. Building on t...

I didn't have any use for 2d so it wasn't even a consideration until talks re Avian started. OBVHS cares mostly about being fast, trying to give a somewhat reasonable rust alternative to some of the functionality in Embree (and in a lot of places Embree is still a lot faster). I've had some cases where traits were non-zero cost due to breaking inlining which had a somewhat surprising perf impact. I'd want to be careful to not regress perf or readability if we move to something more generic.

vestal minnow
#

Yeah, definitely needs proper profiling to make sure it wouldn't regress things

cinder summit
#

Yea, though if it does perform well it could maybe be nice to have the ability to have an OBB BVH ... Last time I tested bounding sphere BVHs are a very bad idea though ๐Ÿ˜‚

#

OBBs actually being worth it at the BVH level is somewhat niche though (and I have no clue how an efficient "merge" would work), but sometimes the intersection tests already treat AABBs as basically OBBs and it could be worth it

thorn solstice
#

The stuff I've seen on OBB seemed to rarely be worth it, but maybe there are cases where it works really well. TLAS/BLAS on the other hand has a lot of benefits, one of which is that the BLAS is in the local space of the object (so OBB like). This is already doable with OBVHS and there are examples.

maiden charm
#

I'm strongly considering tableflipping and switching my studio's project over from Rapier to Avian. Is Avian mature enough that I won't have a bad time?

cinder summit
#

Unless you're doing something relatively obscure it should be

#

I know some joint types are still a bit weird, and the perf at very high entity counts can be less than ideal, though Jondolf has also been working on that a lot recently

vestal minnow
#

Yeah joints are still missing a lot of features, and perf is likely worse than Rapier in heavier cases. Improving those is my main priority for the next release cycle though

vestal minnow
#

Hmm... needs more design work, but I got an interesting idea for component-driven collision layers

#

Collision detection and spatial queries use bitmasks stored in CollisionLayers to filter colliders. This needs to use bitmasks and not e.g. queries for perf reasons.

#

But in an ECS engine, the natural way to tag and filter entities is to use components, and it has always bothered me that we don't take advantage of this. For such a core feature, I feel like bitmasks should ideally be just an implementation detail, and the user-facing API should use a more component-driven approach.

#

Instead of forcing users to explicitly specify the CollisionLayers, what if we had a way to register components as physics layers:

// We could support tuples to make this less verbose.
// Mayyybe we could also do this automatically at runtime?
// Note: There is a limit of 32 layers! (but we could bump it up to 64)
app.register_physics_layer::<Character>();
app.register_physics_layer::<Enemy>();
app.register_physics_layer::<Terrain>();

This would automatically assign a number to each component for the corresponding physics layer.

#

Then, you could add a component like InteractsWith to specify which layers an entity can interact with:

commands.spawn((
    // Belongs to `Character` layer
    Character,
    // Interacts with `Enemy` and `Terrain` layers
    // TODO: How do we support "interact with everything *except* X, Y, Z"?
    InteractsWith::new::<(Enemy, Terrain)>(),
    // ...
));
#

Internally, there would still be a CollisionLayers component with bitmasks, but the component-driven API would automatically toggle the membership bits based on the existence of the layer components and the filter bits based on InteractsWith, using hooks or observers.

#

We get several pretty convincing benefits:

  • The collision filtering API can be fully component-driven. You can query for collision layers, attach observers, respond to layers being added or removed, or do anything else you typically do with components. Even define bundles of layers or insert layers as required components!
  • No need to have separate marker components and layer definitions; the marker is the layer.
  • No need to think about bitmasks, layer numbers, or conflicting layers at all (unless you directly mess with the bitmasks). Collision layers are guaranteed to be non-overlapping at the type-level.
  • External plugins can define their own layers without risking conflict with user-defined layers.
#

I'm not 100% sure yet how InteractsWith would be best implemented, but I'm sure it should be doable in some way

sleek thicket
#

idk if scattering the code like that is a good idea

vestal minnow
#

Scattering how?

#

The ideal workflow for this is (1) just define a marker component, which you typically already have anyway, and (2) use InteractsWith/CollisionMask/whatever to filter which layers an entity can interact with

#

doesn't even need to be a marker component

#

Right another cool idea: You could specify some visibility component as a physics layer, and then you're automatically able to filter collisions based on the visibility of an entity (assuming visibility is controlled by the component's existence)

sleek thicket
# vestal minnow Scattering how?

e.g. right now i have 1 place where i have all layers, filters and masks
i can easily find everything that uses them, and if i add a new functionality that requires updating layers i don't have to search for everything spawned that uses it

vestal minnow
#

You could still do that with this approach if you wanted to, just have all the layer components in that 1 place, maybe define bundles to group and compose them

#

And CollisionLayers would also still exist for people who do want to use it directly, the component approach would be optional (but probably the encouraged API if we implemented it)

sleek thicket
#

something like required components, but for layers ๐Ÿค”

vestal minnow
#

I guess I don't really understand what practical use cases wouldn't work fine/better with this. I would imagine that the vast majority of uses for collision layers is tagging entities based on "what kind of entity is this?", e.g. Character, Terrain, Water, Prop, Interactable, Enemy... In all of these cases, it would make sense to have a marker component on that entity anyway, and especially for dynamic behavior where you might change layers, e.g. a powerup that makes you Invincible, you'd almost definitely need to add/remove components to reflect that change in behavior

cinder summit
vestal minnow
#

Not to mention this would probably work better with Blender/Blenvy, you could just tag meshes with components and then filter collisions or spatial queries based on that

sleek thicket
#

yeah, i'm erring on the side of caution to avoid moves too

vestal minnow
#

or do you do status effects as entities

sleek thicket
vestal minnow
#

ah sry I meant invinsible, as in enemies can't hurt you or touch you

sleek thicket
#

oh, invincible?

vestal minnow
#

right yeah with a c ๐Ÿ˜‚

sleek thicket
#

i have a toggle for that in the damageable component, nothing needs to query for that

cinder summit
sleek thicket
#

but it's a common mechanic in my case, i can see it being useful in ultra-rare cases, but in that case there's no way i'd put it on layers

cinder summit
#

Usually I don't actually modify things like layers though, because not having counters tends to introduce subtle bugs

#

If I did need to I guess I could have a "removed layers counter" component that's just always there

sleek thicket
#

adding a required component if it's missing when layer is toggled on would be really neat though

#

but i also have a tag enum doing the exact same thing so idk

#

the entire thing definitely needs a cleanup, but that proposal sounds like it'd just add more to the mess

vestal minnow
#

I just feel like it's a pretty big missed opportunity to not support efficiently filtering spatial queries or collisions based on components in an ECS engine, but idk maybe in real games directly using bitmasks is better ๐Ÿคทโ€โ™‚๏ธ

sleek thicket
#

in some cases i'm already getting layers in query and checking which layer i actually hit, you could just streamline that instead

vestal minnow
#

that's not filtering by components

maiden epoch
sleek thicket
#

you can exclude entity

maiden epoch
#

I feel like filtering collision events directly will be slower

vestal minnow
sleek thicket
#

ah

#

i didn't touch collisions directly but it's definitely counter-intuitive if they happen between entities that filter each other out

maiden epoch
#

I also have an issue with objects with high angular speed(wheels) getting buried in the ground

#

Collision events looks correct, and increasing amount of solver substeps help a bit

vestal minnow
# vestal minnow not for collisions unless you make a custom collision hook for it

On the main branch you could ignore collisions against specific entities with a collision hook roughly like this:

fn main() {
    App::new()
        .add_plugins((
            DefaultPlugins,
            PhysicsPlugins::default().with_collision_hooks::<PhysicsHooks>(),
        ))
        .run();
}

#[derive(Component)]
#[require(ActiveCollisionHooks::FILTER_PAIRS)]
struct IgnoredCollisions(EntityHashSet);

// Define a `SystemParam` for the collision hooks.
#[derive(SystemParam)]
struct PhysicsHooks<'w, 's> {
    query: Query<'w, 's, &'static IgnoredCollisions>,
}

// Implement the `CollisionHooks`.
impl CollisionHooks for PhysicsHooks<'_, '_> {
    fn filter_pairs(&self, entity1: Entity, entity2: Entity, _commands: &mut Commands) -> bool {
        if let Ok(ignored1) = self.query.get(entity1) {
            if ignored1.contains(entity2) {
                return false;
            }
        }
        if let Ok(ignored2) = self.query.get(entity2) {
            if ignored2.contains(entity1) {
                return false;
            }
        }
        true
    }
}
sleek thicket
#

@vestal minnow do you think it's possible to register components in a similar way to required components, but 2-way with layers?
e.g. register<Damageable>(10);
if i have layers that include layer 10, but component wasn't added = add default
if i have component, but layers don't include 10 = toggle it on

when i look at it from perspective of catching bugs then it makes total sense to do it, but i'm really not sure if that should be the main way to deal with layers

vestal minnow
#

If we make CollisionLayers an immutable component, then we could handle the 2-way synchronization via hooks or observers

#

But I don't want to do full table scans every frame to detect all CollisionLayers components that may or may not have changed

sleek thicket
#

that's why i said from perspective of catching bugs, only call checks when something is spawned instead of changed

#

i can totally see myself being an airhead and forgetting one or the other, then spending an hour hunting down the bug

vestal minnow
#

This would also require all registered layer components to implement Default, unless we really over-engineer this and support custom constructors require-style

sleek thicket
#

i don't see defaults being a problem when it's only 31 components at most

vestal minnow
#

It's mainly a problem if for whatever reason you wanted to register some external component that you don't own, and that doesn't implement Default. But yeah that seems so niche that it shouldn't really be a problem

vestal minnow
sleek thicket
#

registering link between component and layer is basically 1 step towards your proposal, but much smaller and everyone will have more time to test it and decide if that should be the main way to deal with layers

zenith river
#

For my spaceship building game, I'm interested in implementing a localized physics system where entities inside a moving ship behave as if the ship itself isn't moving - essentially creating a self-contained reference frame. Is this approach feasible, and how might I implement it?

calm sundial
#

About collision filtering. Avian should be compatible with open usd/ gltf.
Upcoming gltf specs mentions this :

knotty thicket
# vestal minnow Not to mention this would probably work better with Blender/Blenvy, you could ju...

state of the art for the collisionlayers blender use cases is

  • custom component hook/observer to set CollisionLayers from custom Marker/enum-data Components. afaik "entity tagging" like you mentioned (Terrain, etc) is what I've seen used the most (An enum with a list of tags makes a nice UI), but that's partially motivated by usability.
  • presets (write only)

It seems like InteractsWith would still require a user-written hook/observer since it theoretically requires a new() call? I think the type arguments mean different types in the reflection data (and thus different options in blender) so default impls for them might work depending on what the underlying value looked like

willow gyro
# vestal minnow Then, you could add a component like `InteractsWith` to specify which layers an ...

For context, I just implemented collision layers this week. What you describe about having to use the bit mask and such did feel odd when I went through the docs. FWIW as someone who is still relatively new to Bevy and Avian, I like the look of this direction. It appears more idiomatic. My only comment would be if it still continues to be simple to use layers in spatial queries, but overall looks great.

sleek thicket
vestal minnow
# knotty thicket state of the art for the collisionlayers blender use cases is * custom componen...

It seems like InteractsWith would still require a user-written hook/observer since it theoretically requires a new() call?
So here I purposefully did InteractsWith::new::<Foo>() rather than InteractsWith::<Foo>::new(). My idea here was that maybe we could make InteractsWith fully type-erased, and the methods would turn the given bundle into a set of TypeIds (or ComponentIds? but I think that requires World access) for each component, and then we could store that. Then a hook would run, mapping those types to bits based on the global physics layer registration, and boom, we have a mapping between components and layer filters

#

But I have very non-existent knowledge on reflection stuff so I don't really know for sure if it'd work until I try it

knotty thicket
#

definitely curious to see if you can get it to work

vestal minnow
knotty thicket
#

the blender interface would just be the InteractsWith type then? so basically a marker from Blender's perspective?

#

not sure where Foo would come from

vestal minnow
#

Hmmm yeah the blender interface for that would be tricky

visual sparrow
#

Off-topic: @vestal minnow mind pinging me when you release a 0.16 compatible Avian? So that I can bump avian_pickup ๐Ÿ™‚

sleek thicket
vestal minnow
#

I feel like layers like this in general are just hard to make work nicely with Blender without a designated UI

sleek thicket
#

the only reason i understand them is because there was a good explanation for unity somewhere

visual sparrow
sleek thicket
#

and part of the reason why it was good is that unity's objects can only have 1 layer, which simplified explanation

#

which basically means it was just a bool

vestal minnow
sleek thicket
#

if both membership and filter are true = collide, else dont ๐Ÿคทโ€โ™‚๏ธ
but rapier and avian's multiple membership really complicate everything

visual sparrow
knotty thicket
#

(I'm just using the git commit on main right now ๐Ÿ˜… )

visual sparrow
visual sparrow
vestal minnow
visual sparrow
vestal minnow
#

though I still have one exam after it on the 8th of May but anyway

#

there's a lot of student culture associated with Wappu, especially where I live

visual sparrow
#

The only "event" around summer we get are smaller queues at the cafeteria because more people are on vacation ๐Ÿ˜…

vestal minnow
#

Yeah I don't know if other countries really have the same thing, in Finland may day is fairly big

zenith river
vestal minnow
# zenith river For my spaceship building game, I'm interested in implementing a localized physi...

This seems difficult to do in an actually stable way, but I imagine you'd probably want two fully separate simulation instances, one for outside of the ship and one for its interior. They're not allowed to interact in any way. Like you suggested, all physics positions and velocities in the interior of the ship would be relative to the ship's frame of reference, and you'd then have some custom sync plugin to convert those local physics positions into world-space transforms

#

But this approach would likely require support for multiple physics worlds on Avian's side, which isn't there yet :/ I had a prototype using bushRAT's index queries, but that stalled so I haven't worked on it more yet

vestal minnow
vestal minnow
sleek thicket
sleek thicket
#

you basically just make a portal that shows the interior, and rotate it however you want

zenith river
#

I mean, considering that I use big_space, I could put it extremely far away

sleek thicket
#

and everything on the interior uses a collision layer that doesn't include the collider that collides with exterior

zenith river
#

Seems like a good solution ๐Ÿ˜„

torn fiber
#

Is PBMPM a future plan for Avian?
Considering it as well started from XPBD

sweet sundial
#

for the layers thing: have a resource with an Any/DynHash-to-layer table, so you can mark a component as a collision layer or group of collision layers but still keep the ability to convert (newtype'd) custom ids to collision layers

#

based on my interpretation of the use cases:

  • static, this type of object does/doesn't collide with that type of object (component hook to add CollidesWith, typeid-only layer registration)
  • unique, this object does not collide with these objects (some struct with an entity or other id in it)
  • dynamic, this entity does not collide with the blue team (the team marker struct, maybe struct Team(usize))
trail sparrow
#

I've been away from Bevy/XPBD for about 10 months. Wild how much has changed

vestal minnow
#

And if I was to add some form of MPM support, I'd probably first look into integrating Avian with dimforge's wgsparkl and collaborating there rather than making my own thing from scratch

#

Afaik it uses MLS-MPM with CPIC for two-way rigid body coupling

torn fiber
#

I'll be making my own PBMPM in the meantime, thanks still

vestal minnow
#

Interested to see how your PBMPM implementation progresses. I saw your earlier MPM post in #project-collaboration, looks really cool

torn fiber
#

I'll be sharing an update once it's done, if that could pick any interest who knows!

half ruin
#

Hey guys, who already used Avian with multiplayer (Authoritarian dedicated server and many clients, like MMO)?

Please share you experience, what did you use, lightyear ?

@cinder summit @dreamy viper

cinder summit
spiral nymph
#

It's really declared as a component though

vestal minnow
#

like the error says, you have conflicting Bevy versions

pulsar osprey
#

Hello everyone, I'm testing out Avian but when I uses it in conjunction with bevy_inspector_egui::WorldInspectorPlugin Im getting the above error, and unable to register Collider type due to it not implementing GetTypeRegistration.

I tried a quick search over documentations, but doesn't seem to have an answer bubbles up. Does anyone encounter this situation yet?

spiral nymph
#

Sorry to bother again, but I took your kinematic example code and I would like to prevent the character from jumping when there is penetration in a slope, is there a way to just snap my character to the ground ?

half ruin
#

@vestal minnow am I right by default in Avian there is not any BVH, AABB etc spatial hashing optimizations ?
And I need to implement it by myself ?

cinder summit
#

Avian has a BVH for spatial queries and uses some optimizations for the boardphase, though the broadphase doesn't use a BVH yet

half ruin
pulsar osprey
#

What is the order of the CollidingEntities component? If multiple Entities are within my collider?

#

I'm assuming its the add order of entities? as in the order they enters the collider ?

vestal minnow
#

We might want to change that to just a Vec though ๐Ÿค”

pulsar osprey
#

Ahh I see, in that case, idk, is it going to be a performance concern? Switching to a Vec?
Since the usefulness of ColldingEntities might require futher processing like calculating distance, ranking by health, ... That it doesn't really matter, as long as the collision detection is performant?

vestal minnow
#

Avian itself doesn't use CollidingEntities at all, it exists just to allow users to efficiently query for which entities a collider is touching. Switching to a Vec should make iterating over the entities in user code a bit faster and make the iteration order stable, but make get or contains lookups and removing entities from CollidingEntities slightly slower. Either way the difference there should be pretty minimal

vague pebble
vestal minnow
#

Whoa, we passed 2k stars! ๐ŸŒŸ

vestal minnow
#

it just wouldn't be very useful since you still wouldn't get access to any of the actual shape's data

half ruin
vestal minnow
#

and CI apparently doesn't use the parallel feature so it didn't catch it

#

mm now can I fix this somehow or do I have to revert that PR

#

I think it should be fixable in theory

#

Oh right the fine print for ThreadLocal::iter_mut says "Returns a mutable iterator over the local values of all threads in unspecified order."

#

I guess I need to sort that somehow

vague pebble
#

But I think there is a few videos of it in this server

half ruin
cinder summit
#

bevy_rewind hasn't had an official release yet so that's definitely a big factor ๐Ÿ˜‚

vague pebble
#

But tbh my sincere opinion is lightyear has more features and is newbee friendly. Although it does lack a little on stability and perfomance

cinder summit
#

I think the main thing here is going to be the different networking approaches either way. Lightyear is more FPS-style, while bevy_rewind is inspired by Rocket League

vague pebble
#

There is also the factor that they have different prediction styles

cinder summit
#

The rocket league approach is notably more expensive, but also necessary for doing crazy things with physics (most games don't want this when online though)

half ruin
#

since I dont need that rocket league crazy physics

cinder summit
#

Lightyear approach might work, might also be possible to build some of your own stuff on bevy_replicon ... Your concern will probably be performance for a real MMORPG so it's probably worth looking at it from that angle too

vestal minnow
severe urchin
cinder summit
#

Yes

#

I was already on 0.16.0-rc, so it shouldn't be too hard, but it is slightly behind on replicon updates iirc. And I'll have to retest my approach to replicating avian in specific ๐Ÿค”

formal gorge
#

Just wanted to chime in that cylinders jitter like crazy. using Collider::trimesh_from_mesh(&Cylinder::new(...).into()) instead of Collider::cylinder changed things from a jittery mess no matter how high I increased angular and linear damping, to being completely stable even with entities piled on top of each other with no damping.

vestal minnow
#

I'm getting some "okay" behavior but occasional jittering/jumping with some cylinder stacks

#

What dimensions are your cylinders using?

formal gorge
#

1.0 tall, 0.2 radius

#

they randomly gain significant velocity every half second or so, enough that they basically can't be stood on end

#

doesn't matter what they're on top of

#

even static cuboids

#

like just a single one is completely unstable and will never sleep

#

tried fixed and not fixed schedule, 60fps 120fps, changing density, damping from 0 to like 10 or 20

#

if this is just me, I can share a repo, but from searching old messages, it looks like this is probably a general issue? I'm not doing anything odd I don't think

vestal minnow
#

It feels like more of a Parry issue (the collision detection lib that both Avian and Rapier currently use) if it's a specific shape, in this case a cylinder

#

I wonder if a thin long shape like a cylinder is just kind of a pathological case for GJK ๐Ÿค”

cinder summit
#

Iirc parry always had open issues for cylinders ๐Ÿฅฒ

vestal minnow
#

I vaguely recall cylinders in general being challenging for robust collision detection

formal gorge
#

that makes sense tbh

#

I don't have the energy to investigate further atm, but if this is common, it could be worth adding a note to the Collider::cylinder function? or even just having it use a tri mesh internally? I even noticed issues with cubes on a very wide, very flat cylinder disk

#

like at the time I just thought avian had very jittery physics

#

but now everything is almost surreally stable

vestal minnow
#

(because of Parry)

formal gorge
#

that looks extremely similar to what I was seeing

#

like random little hops every few moments

#

not enough to topple more stable shapes, just enough to keep them from sleeping, but enough to topple something 1.0 tall, 0.4 wide

#

well now I can't seem to replicate the little jumps but instead they're doing this:

#

anyway I'm gonna go back to trimeshes, but yeah, I guess parry's cylinders have some issues

vestal minnow
#

You could also try a convex hull instead of a trimesh, it should be faster and more robust against clipping into things since trimeshes are hollow

vestal minnow
# vestal minnow oh noo it wasn't just this PR that breaks determinism, the constraint generation...

Made a fix for this... Non-deterministic constraint order -> just sort them afterwards lol
https://github.com/Jondolf/avian/pull/712

GitHub

Objective
Multithreaded determinism is currently broken! This is because #699 accidentally resulted in contact constraint order being non-deterministic. CI didn't catch this, because it cur...

#

Not the ideal solution I would've liked, but works well enough for now

formal gorge
clear dew
#

Hey, I read into main's docs...this has probably been asked 10x, but I was wondering if there's some easy way to calculate, for an object, what the next object it is most likely to collide with. Constraints are: no rotation, perfectly elastic collisions, no friction, perfectly linear movement, no gravity

#

I couldn't really find much about this other than the new triggers (which are awesome btw). Pong in other words hahaha

vestal minnow
#

You could do a shape cast from the current position to the next position predicted based on velocity

clear dew
#

Cool, I'll follow the lead. Thanks!

vestal minnow
#

๐Ÿ”ฅ

#

(not equivalent to merged PRs, especially in early bevy_xpbd days I did more commits directly on main)

clear dew
#

been missing out

eternal anvil
#

I've been working on this asteroids shooter prototype lately and decided to port it from rapier to avian, but i'm getting lower performance. Is this to be expected and is there anything that I can do to improve this? I'm already using circle colliders for the fragments so i'm not quite sure how else I can optimize it.

sleek thicket
vestal minnow
#

I'm hoping that 0.4 will be a huge perf upgrade with all of the SolverBody stuff and hopefully many other optimizations (simulation islands please) landing

cinder summit
#

Yes, simulation islands please ๐Ÿ™

vestal minnow
#

I'll have a lot more time to work on it too since I'll have a long break from uni starting mid-May

cinder summit
#

Also Jondolf you accidentally unearthed a major problem with my rollback crate by not re-adding the pointless PartialEq derive on ContactGraph (it was on Collisions) ๐Ÿคฃ

vestal minnow
#

oh lol, yeah I thought it feels dumb to compare two entire contact graphs for equality

cinder summit
#

Yea, I don't actually need to do that, Rust is just trolling me with the lack of negative traits and specialization

#

This trait bound makes no sense, but I have no idea how I can figure out "Is there a function to compare this type" without the trait bound ๐Ÿค”

    fn register_predicted_resource<T: Resource + Clone + Debug + PartialEq>(
        &mut self,
    ) -> &mut Self;
half ruin
cinder summit
#

"Fixed" as in all RigidBody::Static?

half ruin
#

I spawn them by this:

for _ in 0..20_000 {
    let dimensions = [
        rng.random_range(1.0..3.0),
        rng.random_range(1.0..3.0),
        rng.random_range(1.0..3.0),
    ];

    commands.spawn((
        RigidBody::Static,
        Collider::cuboid(dimensions[0], dimensions[1], dimensions[2]),
        Transform::from_xyz(
            rng.random_range(-180.0..180.0),
            0.5,
            rng.random_range(-180.0..180.0),
        ),
    ));
}
vestal minnow
#

Not sure why the difference would be so drastic, other than if a fixed timestep takes longer than 15.6 ms with the default rate of 64 Hz, perf might dip pretty significantly as it then needs to try and run multiple physics ticks per frame to keep up

#

What if you run physics in e.g. PostUpdate? (for a variable timestep)

#

PhysicsPlugins::new(PostUpdate)

half ruin
vestal minnow
#

I think so

half ruin
#

longer than 15.6 ms
hm, makes sense, with 20k colliders its ~14ms

vestal minnow
half ruin
#

nice, with just changing PhysicsPlugins::new(PostUpdate) now I have 45 FPS with 30k colliders

vestal minnow
#

Are you using 0.2 or the main branch?

half ruin
vestal minnow
#

On the main branch there's a PhysicsDiagnosticsUiPlugin (requires diagnostic_ui feature) that shows you how long different parts of the physics step are taking, I was just curious about some profiling info there

#

I can probably roughly reproduce it locally with your setup though

cinder summit
#

Watch it be all BVH build times ๐Ÿ˜”

vestal minnow
cinder summit
#

The broadphase? But we early out on static - static right? thonk

half ruin
#

what is broadphase ?

cinder summit
#

The broadphase is the part where shapes that could overlap are checked based on bounding boxes, it's an optimization to reduce the number of more precise collision checks necessary

cinder summit
half ruin
#

maybe the issue that I spawn static colliders and half of them spawn partly inside other colliders?

cinder summit
#

I don't think we even get to the step of checking the AABBs, because static - static collisions can always be discarded

#

We found that out the hard way when I accidentally made all my colliders spawn at 0, 0, 0 and the FPS went from good to seconds per frame ๐Ÿ˜‚

half ruin
#

I mean this

vestal minnow
cinder summit
#

Oh right ... But that does stop us from just doing if rb1 == RigidBody::Static { continue; } in the outer loop right?

vestal minnow
#

And it tests overlap along y and z before the static-static early out

#

We can't do that in the outer loop since the inner loop could still have active bodies

cinder summit
#

More reasons for a BVH broadphase

vestal minnow
#

and we'd probably get more iteration overall

cinder summit
#

Yea, we'd be trading "everything is static" perf for "everything is dynamic" perf

vestal minnow
#

Build overhead would be zero for the static tree when it doesn't have changes, and if there are no active bodies, we don't need to do any collision tests

cinder summit
#

-# If only there was a branch somewhere that starts using OBVHS in avian already

#

Actually I guess there are 2 branches that use OBVHS out there

vestal minnow
#

I have an old branch somewhere

#

iirc that one old demo with full rebuilds was like 95% functional, but the newer one doing it "correctly" with incremental updates and enlarged AABBs and "moved proxies" etc. is still very WIP and broken

#

(the idea with moved proxies is that the broad phase only needs to traverse the BVH for colliders whose tight bounding box moved past the enlarged bounding box, meaning we can completely skip broad phase tests for dynamic bodies that aren't moving much)

visual sparrow
eternal anvil
abstract tendon
#

is EventReader<Collision> changed for bevy 0.16?

#

because it says cannot find type Collision in the scope

vestal minnow
abstract tendon
#

ah i see, thank you

clear dew
#

Sorry to poke again! Is there any way to get around using the physics calculations on collision, or even like momentum/inertia/rotation in general, but still get access to the SpatialQuery::cast_shape? or are those tightly integrated? Ideally all I would want is to use Colliders for querying...I was reading through the plugin list, but I haven't yet found a working combination

abstract tendon
#

i found a pretty interesting bug. my crosshair have sensor collider, and ball have disabled rigidbody. when player shoots and two colliders touch eachother, game logs out "nice" (you can see on the vscode terminal) and ball gain his rigidbody and starts jumping. for some reason when they touch eachother from left side, no collision event happens

cinder summit
abstract tendon
#

sorry for the minecraft music btw

cinder summit
#

I did actually encounter a couple crashes when not loading the physicsy bits but still loading SpatialQueryPlugin, so it's probably just a bug

half ruin
#

how to add collider to gltf model (like ground) in proper way?

formal gorge
formal gorge
#

if you need it to be based on the mesh in the model, you can extract the mesh and use the collider::from_mesh constructors

visual sparrow
# formal gorge if you need it to be based on the mesh in the model, you can extract the mesh an...

There's ColliderConstructorHierarchy for doing this automatically, FYI ๐Ÿ™‚

formal gorge
#

that's super useful, I was using asset labels and extracting stuff manually

visual sparrow
wary jolt
#

My player just stick to the wall at the first collision

fn move_player(
    input: Res<ButtonInput<KeyCode>>,
    mut query: Query<&mut LinearVelocity, With<Player>>,
) {
    let mut velocity = query.single_mut();
    let mut input_vec = Vec2::ZERO;
    if input.pressed(KeyCode::KeyW) {
        input_vec.y += 1.0;
    }
    if input.pressed(KeyCode::KeyA) {
        input_vec.x -= 1.0;
    }
    if input.pressed(KeyCode::KeyS) {
        input_vec.y -= 1.0;
    }
    if input.pressed(KeyCode::KeyD) {
        input_vec.x += 1.0;
    }
    velocity.0 = input_vec.normalize() * 200.0;
}
commands.spawn_empty()
    .insert(Name::new("Player"))
    .insert(Transform::from_xyz(0.0, 0.0, 0.0).with_scale(Vec3::splat(8.0)))
    .insert(player_image)
    .insert(AnimationTimer::from_fps(4))
    .insert(GameMarker)
    .insert(RigidBody::Dynamic)
    .insert(Collider::rectangle(8.0, 8.0))
    .insert(Player)
    ;

    commands.spawn_empty()
    .insert(GameMarker)
    .insert(RigidBody::Static)
    .insert(Collider::rectangle(1000.0, 8.0))
    .insert(Transform::from_xyz(000.0, -500.0, 0.0))
    ;
.add_systems(PhysicsSchedule, move_player.before(PhysicsStepSet::First).run_if(in_state(GameStates::InGame)))
cinder summit
#

Huh ... I wonder if insert chaining like this would mess with any of avian's logic ๐Ÿค”

#

Any reason you don't do uh ...

commands.spawn((
    Name::new("Player"),
    Transform::from_xyz(0.0, 0.0, 0.0)
        .with_scale(Vec3::splat(8.0)),
    player_image,
    AnimationTimer::from_fps(4),
    GameMarker,
    RigidBody::Dynamic,
    Collider::rectangle(8.0, 8.0),
    Player,
));
wary jolt
#

Not really but changing it doesnt fix the problem

formal gorge
#

try running move_player in Update, just to see if it changes something?

wary jolt
#

doesnt change anything

formal gorge
#

might be an issue with some other part of your code then? what you posted looks pretty similar to stuff I'm doing

wary jolt
#

Tried loging the linear velocity, its like it is getting stuck in the wall and cant move after

formal gorge
#

gravity?

cinder summit
#

Well those NaN values are definitely bad at least ๐Ÿ˜‚

formal gorge
#

nvm not gravity, the velocity is pretty close to 200 until it breaks

#

oh!

#

you need to call normalize_or_zero or whatever it's called

#

(0,0).normalize results in NaN IIRC

#

NaN velocities would cause issues I'd imagine?

cinder summit
wary jolt
#

Yes that was it, thank you ๐Ÿฅณ

formal gorge
#

heck yeah, np, I've almost done the same thing lol

#

theres also a clamp_length function that's useful for gamepad input

sleek thicket
#

clamp_length_max*

formal gorge
#

Lol can you tell I type 'c' 'l' 'tab' to autocomplete

formal gorge
#

Any reason why setting an entities Transform would just not work? I suspect it's something to do with syncing or something like that

#

I remove the RigidBody component and then insert the new transform in a command

#

ok yeah nvm, removing Position and Rotation fixed it

#

I'm a little confused why another part of my code does work even though I don't do that

#

does syncing differ between children of static and dynamic bodies?

formal gorge
#

Ok, so there are still some parts I don't understand, but it seems like some part of avian does something to entities that have e.g. position/rotation and maybe velocity if they have either a RigidBody OR a Collider. The docs mention avian treating entities with RigidBodies as being in a flat hierarchy, but there seems to be at least some behaviors that are predicated on colliders even in the absence of a RigidBody

#

admittedly this is on entities that had a RigidBody and I removed it

coral kite
vestal minnow
#

required for proper sleeping and basic constraint solver parallelism

cinder summit
#

Proper sleeping that doesn't make my prediction cry

vestal minnow
#

I snatched the avian.rs domain now ๐Ÿ˜›

#

might start working on a website for Avian at some point, it'd have the news/announcements + web demos + maybe a getting started guide

green adder
#

Is there any plans on making avian have Fixed-point (instead of floating point) mode for determinism by any chance? I know that it currently relies on other crates like parry and therefore that might not be something that can even be considered now.

cinder summit
#

Unless you need position independence, I don't think fixed point should be necessary

vestal minnow
#

fixed point doesn't really have anything to do with determinism beyond making behavior the same at different positions in the world

#

afaik in general it can be much more expensive than floating point math, and I don't know how well SIMD would work with it

#

so no, fixed point math isn't really in the plans at the moment since I haven't really seen any convincing reasons for it

#

floating point math is fine for cross-platform determinism (provided you use e.g. libm for non-deterministic operations), and for far-from-origin scenarios we'd ideally have support for big_space

wary jolt
#

is there a way to offset a collider without spawning another entity?

vestal minnow
cinder summit
#

Some collider types can also encode an offset, like capsules

vestal minnow
#

I still really like the idea of Translated, Rotated, Scaled, and Transformed wrappers so you can just do shape.translated(my_translation), I started writing up a proper design doc for it a while back

#

It'd remove the need for all the _local versions of methods, and could theoretically get rid of some unnecessary transformations while also making things more generic over the coordinate system

#

I'd also like to try if we could fully support non-uniform scaling with stuff like shearing without making discretized approximations via meshes, I think technically GJK+EPA should work with it?

#

there's a reason I'm making peck, I want to experiment with these sorts of things :P (and get rid of Nalgebra / use bevy_math)

little maple
#

in the process of updating to 0.16 and using latest avian... did something change with the collision events? My EventReader<CollisionStarted> seems to not be reporting anything ๐Ÿค”

#

ah I should have searched

vestal minnow
#

Yup collision events are now opt-in via the CollisionEventsEnabled component

little maple
#

sorry Jondolf lol

vestal minnow
#

np haha

crimson crest
#

I'm once again working on a KCC slowly but surely, keep running into that annoying issue where a combined pass gravity and movement causes nasty ghost collisions but having gravity on a separate pass makes managing gravity properly painful

#

You have any thoughts Jondolf? How does avian internally deal with gravity? Do you join it in the velocity or is it kept separate?

#

The ghost collisions in particular are showing themselves as sort of trapping the player, not quite inside the mesh but they can't overcome gravity to continue moving along the plane.

Having a skin width doesn't really solve this issue, since I think it's a math problem I'm approaching in the wrong way. You're not inside the floor, but you're definitely failing to move because of rejecting gravity along the plane of collision

vestal minnow
#

Gravity is just added during velocity integration in the substepping loop, same as external forces

crimson crest
#

Also wrt using linearvelocity for KCC (something you mentioned wanting a while back), it'd probably mean doing the KCC steps during the integration phase too

#

Since otherwise it's getting applied twice since Avian will still move a kinematic body according to linearvelocity causing you to clip through stuff

visual sparrow
severe urchin
#

where should i get the manifolds/collision normals from with the new CollisionStarted event stuff on main?

vestal minnow
#

The Collisions system parameter

severe urchin
#

thanks

vestal minnow
fallow pike
#

Hrlo everyone

#

Tried someone create car suspense?

#

Any car suspense

sleek thicket
crimson crest
visual sparrow
#

@fallow pike you may also want to look into bevy_tnua

crimson crest
#

Seems 0.125 resolves the issue mostly

#

Discovered it while investigating some other engines KCC impls

little maple
#

to be clear, it is an excellent video

sleek thicket
little maple
# sleek thicket describe your issues in detail then, it might not be a niche problem

one that's getting me right now is that at high speeds it seems like the steering forces cause the car to suddenly spin out and go flying (even without attempting to turn)

I think it's stuff like that though.. as I start pushing some limits, I need to add more logic to handle stuff.. like... something that scales turning at low speeds vs turning at high speeds.

sleek thicket
little maple
#

wheels are ray, and the ground varies but most of the time it's a plane.

fallow pike
#

Soo manu joints

#

What to pick

little maple
#

I didn't use any joints

little maple
sleek thicket
little maple
sleek thicket
#

then that's probably the main culprit ๐Ÿ˜…

#

try box or half-space, i had a bug where instead of slowing down i sped up to mach-10 and it worked fine (on half-space collider)

little maple
sleek thicket
#

convex meshes seem to be problematic in every physics engine

little maple
little maple
sleek thicket
#

if you pay attention to it, you can easily notice convex decomposition in most games

#

modular kits are usually primitives where it's possible

little maple
sleek thicket
fallow pike
#

Why mass not works?

#

I set like 10000 density and same results with 1

#

Mass, or bundles

#

Not working

vestal minnow
#

if you're just shooting at a target

abstract tendon
#

i would use raycast if it was 3d

#

but i didnt think i can raycast for 2d

#

but

#

hm

#

yeah no, i have no idea how to raycast for this situation

vestal minnow
fallow pike
vestal minnow
#

(or CollidingEntities)

vestal minnow
fallow pike
#

Oh sory i also forgot

#

It has collider

#

Rectangle 50 : 30

vestal minnow
#

Make sure you have PhysicsPlugins added, and you might also want the body to have a Transform, though I think that's technically optional

fallow pike
#

Ehen i running its just ignores mass

#

And falls very very slowly

vestal minnow
#

your dynamic body is 30 units tall but gravity is -9.81 by default

#

use .insert_resource(Gravity(Vec2::new(0.0, -98.1))) or whatever feels good

#

probably even higher

fallow pike
#

Like i want more realistic physic

#

Or also why that happends

#

Any mass what i insert gravity eat

vestal minnow
# fallow pike Is it normal?

9.81 m/s^2 is the average magnitude of the gravitational acceleration near Earth's surface. This means that the linear velocity is increasing downwards by 9.81 m/s every second. In your case, the dynamic body is 30 units tall, which is like a 30 meter tall building, so an acceleration of 9.81 m/s^2 looks tiny for it when zoomed out like this.

cinder vapor
#

Are Avian Sphere colliders filled or hollow?

vestal minnow
#

filled

cinder vapor
#

Is there a way to do a hollow sphere?

#

I want to make a gatcha ball with something inside

#

like this

cinder summit
#

Ah yes, the hollow sphere ... The non-trivial thing to implement that is somehow easy with SDF collisions #off-topic message

vestal minnow
# fallow pike Like i want more realistic physic

You can either scale down the shapes so that their sizes are closer to real-world values, e.g. a character might be 1 or 2 meters tall, and then change the scale of the 2D camera's projection to zoom it in a bit. Or if you want to use pixels as units like you're currently doing, you can scale the gravity and any other forces you might apply to match the scale of your objects

#

For "realistic physics" it's generally easier to work in SI units (meters, kilograms, Newtons)

#

In which case you'd scale the camera in 2D (since Bevy's 2D camera defaults to 1 px = 1 unit)

vestal minnow
vestal minnow
#

collision detection algorithms generally don't like concave shapes (excluding Nise's SDF colliders)

cinder vapor
#

I haven't looked into those SDF colliders. Do they integrate with the rest of Avian?

vestal minnow
#

No (or not yet at least :P) it's just something Nise has for their own game

cinder vapor
#

Trimesh it is then ๐Ÿ™‚

cinder summit
#

It does integrate with avian, and this example lives outside of my game, but it is definitely not ready yet ๐Ÿ˜‚

#

For one the new version is largely untested, so I'm pretty sure there are flipped normals and points everywhere ... But then also it's missing impls between types of colliders, and there are currently no spatial queries at all

sleek thicket
cinder vapor
#

That should work for my case

fallow pike
cinder summit
#

They fall at the same rate ... That's how gravity is supposed to work, right? right?????

vestal minnow
#

yes

fallow pike
vestal minnow
cinder vapor
#

It sounds like you want air resistance (aka drag)

visual sparrow
# fallow pike

Between 1589 and 1592, the Italian scientist Galileo Galilei (then professor of mathematics at the University of Pisa) is said to have dropped "unequal weights of the same material" from the Leaning Tower of Pisa to demonstrate that their time of descent was independent of their mass, according to a biography by Galileo's pupil Vincenzo Viviani,...

spiral nymph
# fallow pike

Oh man, OBS exist, you don't need to film with your phone XD

visual sparrow
visual sparrow
fallow pike
#

Bruh

#

Ok i just go sleep

visual sparrow
# fallow pike Bruh

You can have drag however, which is when air stops certain shapes from falling (e.g. a feather)

vestal minnow
# fallow pike But why

If you want a proof, then according to Newton's law of universal gravitation, the gravitational force acting between two objects is

F = G * (m1 * m2) / r^2

where m1 and m2 are masses, r is the distance between the centers of the masses, and G is the gravitational constant.

If m1 is the Earth and m2 is your object, based on Newton's second law we get

m2 * a2 = G * (m1 * m2) / r^2

Now we divide both sides by m2, and we get the acceleration caused by gravity for our object

a2 = G * m1 / r^2

Therefore the acceleration of the object only depends on the mass of the Earth and the distance between the center of mass of the object and the center of mass of the Earth. These are approximately constant for all objects near the surface of the Earth, and the mass of the object itself has no effect.

#

And yes the object also pulls the Earth towards itself, and this force is larger the greater the mass of the object is. But still the acceleration for that object is the same in that point in time, and unless you're doing orbit simulations or something, the force pulling Earth is insignificant enough that you don't need to take it into account

spiral nymph
#

Did you just erase m2 left and m2 / r^2 right ?

vestal minnow
#

both sides have m2 as a factor so we can just cancel those out

spiral nymph
#

Ok I'm dumb, I was thinking like it was addition, so dumb of me

half ruin
vestal minnow
#

that looks like way too much detail for the collider

half ruin
#

probably I dont need to use ColliderConstructorHierarchy for original gltf model and I need to add some simpler layer to it

#

I mean CollisionLayers

vestal minnow
#

you should have a simplified version of the mesh for the collider with waaay less triangles

half ruin
#

btw, even with such level of detail for the collider, its still 120fps w/o debug gismos hehe

sweet sundial
#

what ColliderConstructorHierarchy mode are you using

half ruin
sweet sundial
vestal minnow
#

you could try a convex hull instead of the trimesh unless your meshes in that glTF have a lot of concavity

vestal minnow
sweet sundial
#

solid, fewer polys

visual sparrow
visual sparrow
#

Then only provide a collider for that simple mesh

half ruin
visual sparrow
# half ruin yeah I thought about it, Also I remember you used `bevy_trenchbroom` in Foxtrot ...

The level itself is already just cubes, so those are just convex hulls. For most props, convex hulls are enough as well. The chairs are heavily concave, so I use trimeshes for those.
The chair meshes as still fairly simple detail-wise, so I didnโ€™t bother with creating simpler ones for performance. But if I noticed a dip in performance when placing too many chairs, I would have created those simpler proxies ๐Ÿ™‚

tulip crystal
#

Has anyone seen something like this before? When viewing the rectangular collider on the player models left arm while the playeris running, the collider is lagging behind the arm's mesh (you can barely see the mesh it's like 0.4 alpha base material but that is in the correct position.) I'm wondering if it's just the physics debugger's visualization that's lagging or the actual collider?

Some sample code...

commands.entity(entity_leftarm_with_mesh).insert((
    ColliderConstructor::ConvexHullFromMesh,
    CollisionLayers::NONE,
    Sensor,
));
half ruin
#

this is convex hull for my ground model
Not very good solution)

tulip crystal
#

From what I've been reading I thought you should use a Trimesh from Mesh for something like a static ground/terrain mesh.

#

@half ruin

half ruin
tulip crystal
#

I don't think you need a simpler invisble version when you're working with a static body and trimesh collider. I mean it's still a little bit heavy but it's not a dynamic geometry which means it's a low cost compared to something that is recomputing new geometry on all the vertices every iteration of the engine.

#

I'm sure you would still see a little less load though if you were able to create an invisible version that has simpler geometry but I don't think it's necessary - atleast from how I've been understanding it.

visual sparrow
visual sparrow
#

Though again, depends on your scene

#

For the group itself, trimesh is probably alright, doesnโ€™t look like that many triangles

#

Itโ€™s just that building really that is a problem

half ruin
#

ground with trimesh. I think its ok

vestal minnow
# tulip crystal I don't think you need a simpler invisble version when you're working with a sta...

The problem is mainly with dense geometry. Let's say you had a very detailed area with a hundred triangles under the player's feet; you'd be computing intersections with potentially all of those triangles and getting hundreds of contact points for the solver deal with, when really you only needed a few. A manifold reduction scheme could be used to group triangles with similar normals together and reduce the number of contact points (e.g. Jolt has this), but we don't have that yet.

visual sparrow
tulip crystal
# tulip crystal Has anyone seen something like this before? When viewing the rectangular collide...

@vestal minnow I feel like I'm dealing with something similar here in a way. i created a simplified geometry to add coliders to a players mesh for their arms for specific collision events there. The difference in that case is that the collider is moving around with the parent(/sibling?) every iteration and recomputing the whole whole player mesh as a physics object every iteration is highly expensive and not recommended.

#

There's just a lag issue in my case though it seems to be creating correctly.

vestal minnow
#

That doesn't look like perf lag, more like either the collider itself or the gizmo is lagging behind

#

It's possible there's a one frame delay somewhere

hard helm
half ruin
# half ruin <@545959292281552928> btw, just saw this issue, is it my mistakes in controller ...

what do you think about these repulsions?
Looks like my tnua builtin walk has a bad config?

controller.basis(TnuaBuiltinWalk {
    // The `desired_velocity` determines how the character will move.
    desired_velocity: direction * 1.2,
    desired_forward: Dir3::try_from(direction).ok(),
    // The `float_height` must be greater (even if by little) from the distance between the
    // character's center and the lowest point of its collider.
    float_height: PLAYER_FLOAT_HEIGHT,
    // Restrict the max slope so that the player cannot walk up slightly angled chairs.
    max_slope: TAU / 6.0,
    acceleration: 50.0,
    air_acceleration: 30.0,
    spring_strength: 3000.0,
    spring_dampening: 1.2,
    ..default()
});
#

@visual sparrow

#

hm, I changed spring_strength to 300 and now there is not repulsions issue

vestal minnow
half ruin
#

but now when i step off a low platform the collider very slowly flows down to the floor as if gravity is not 9.8 but 1.0

cinder summit
visual sparrow
tulip crystal
formal gorge
#

What actually triggers ColliderOf to be added?

#

I have an entity that's missing those and I'm trying to figure out why

formal gorge
#

just fyi ColliderOf seems to only update when RigidBodys are added or removed or when children are added or removed, so adding a collider to an existing child entity doesn't trigger adding a ColliderOf to that entity

#

the comments in the hierarchy plugin make me think this is the intended behavior

#

but it was surprising to me

#

e.g.

/// Updates [`ColliderOf`] components for colliders when their ancestors change
/// or when a rigid body is added to the hierarchy.
#

I think it would make more sense to also trigger it when colliders are added to the hierarchy? if not, It would be nice to have a note somewhere in ColliderOf (or if there is a note, make it more prominent, I spent a while trying to figure out what was happening ๐Ÿ˜… )

formal gorge
#

actually, the more I test stuff, the more I think this might be a bug. I think the behavior is inconsistent between whether the components are added in a system or in a hook?

#

Let me know I've just done something incorrectly, or what. I think I'm done with this for the night

vestal minnow
little maple
#

I accidentally posted this in general and meant to post it here.. I'm running into this warning/error on main branch

Encountered an error in command <bevy_ecs::system::commands::entity_command::remove<avian3d::sync::ancestor_marker::AncestorMarker<avian3d::collision::collider::backend::ColliderMarker>>::{{closure}} as bevy_ecs::error::command_handling::CommandWithEntity<core::result::Result<(), bevy_ecs::world::error::EntityMutableFetchError>>>::with_entity::{{closure}}: The entity with ID 727v1 was despawned by forks/bevy/crates/bevy_scene/src/scene.rs:112:46

it seems similar to this...
https://github.com/Jondolf/avian/pull/677

I actually just realized I was looking for the wrong component... this seems to be complaining about .remove<AncestorMarker<ColliderMarker>>

I also have one complaining about .remove<AncestorMarker<RigidBody>>

#

gonna look some more..

#

I'm guessing it's related to remove_ancestor_markers

vestal minnow
#

Yeah that should be using try_remove... It does check if the entity exists there, but EntityCommands is also deferred so it could be despawned by the time it runs ๐Ÿ™ƒ

little maple
#

that fixed it. I suspect it's because it queues a command instantly

#

yeah

#

I can make an issue + pr if it's helpful

I sometimes get a little conflicted with tiny fixes like this.. the amount of overhead of an issue and PR vs just fixing it with another change. But, it might be worth having the error documented as an issue if someone else stumbles on it before it's fixed ๐Ÿค”

vestal minnow
#

PR would be nice, though I can also make one later

#

(not today tho)

little maple
#

I made #714

valid zenith
#

is there a 0.16 compatible 3d build out yet?

vestal minnow
#

Not a release yet, but the GitHub repo's main branch supports 0.16

valid zenith
#

Sick ill switch over to targeting the repo instead of crates.io for now then NODDERS

tulip crystal
#

Hey sup y'all I'm still testing this collider from yesterday a little bit and honestly I wasn't expecting this result. The collider on the arm is triggering before either the arm or gizmo are in contact with the wall ( the black wall is on the left.) Is this due to the predictive algos you were mentioning yesterday @vestal minnow ? the system I used for detecting the collision

.add_systems(Update, debug_collisons)

fn debug_collisons(mut collision_event_reader: EventReader<Collision>, names: Query<&Name>) {
    for Collision(contacts) in collision_event_reader.read() {
        let Ok(entity1) = names.get(contacts.entity1) else { return };
        let Ok(entity2) = names.get(contacts.entity2) else { return; }; 
        if (entity1.to_string() == "wall" || entity1.to_string() == "left-arm") && (entity2.to_string() == "wall" || entity2.to_string() == "left-arm") {
            dbg!("wall and arm are in contact");
        } 
    }
}

I was able to get the debug gizmo to appear correctly when adding:

app ...
.insert_resource(Time::<Fixed>::from_hz(240.0))

But I'm not really sure what other consequences this line has. Does it effect all the systems in the app?

I haven't gotten into configuring Time for my app until I saw this on an official bevy thread https://github.com/bevyengine/bevy/discussions/12005 where the gizmo was also having a 1 frame delay (not using avian) but they were able to add their gizmo system to PostUpdate schedule and that did the trick for them.

Adding the PhysicsDebugPlugin to the PostUpdate Schedule did not work just the Time snippet above was able to fix the display.

@vestal minnow thank you for these plugins and all the work you've put into this as well as the help from the other 65 or so contributors.

tulip crystal
visual sparrow
#

@vestal minnow FYI, I'm porting Foxtrot to 0.16 and use Avian's main branch, and now I get a ton of these when going from the gameplay back to the menu, which despawns most entities

#

This could be my bad or a fault in one of my patched plugins, just letting you know

#

Sec, here is the same with track_location on

#

From just a cursory glance, it seems like a situation where remove should be replaced with try_remove

calm sundial
visual sparrow
willow elbow
#

@vestal minnow I updated my code to 0.16 and avian main and EventReader<CollisionEnded> doesn't work anymore. collision_events.read() doesn't read any events. Is this a known issue?

cinder summit
#

Yea, there is a marker to enable events now

willow elbow
cinder summit
#

See #1124043933886976171 message

crimson crest
#

I just came to a super important realization when it comes to the KCC. Gravity should be processed separately if you're not on a steep slope, but joined with the characters velocity if you're on one

#

Since I always do grounding checks before the collide and slide I have the floor angle already for this purpose

#

It's an obvious thing in hindsight but

#

So depending on floor angle you either have gravity as a move and collide on its own then add that result to the KCC's velocity, or put both in a single pass

paper jasper
crimson crest
#

Actually hm... @vestal minnow couldn't I run my KCC processing during narrow phase and do collision events and such the same way Avian does internally?

little maple
#

I'm using the 0.16 branch and am running into this behavior and am curious if anyone else has seen it. It's like my frame rate just drops for a few frames with these long calls to "avian3d::sync::propagate_transforms_physics" even when I have physics time paused.

#

ah, realized I can't make a thread here so I made one here
#off-topic message

pulsar osprey
#

Is it possible to create a cone/pizza slice shaped collider? Or do I have to apply an angle filter on CollidingEntities?

#

I want to detect collision with defined radius and angle from object's X or Y.

#

Anyone knows good examples on adding custom colliders like doughnut shapes, ...?

sleek thicket
severe urchin
#

Encountered an error in system avian2d::picking::update_hits: Parameter Res<RayMap> failed validation: Resource does not exist

get this when trying to run with MinimalPlugins. i don't have the bevy_picking feature enabled for avian2d, since i'm trying to run headless. do i need to disable picking some otherway in headless mode?

#

on main btw

severe urchin
#

ah for some reason i was manually adding PhysicsPickingPlugin, that explains it..

sweet sundial
crimson crest
#

Oh huh box2d got some KCC related features

#

I might take a look at those

#

Wait hold on

#

This geometric solver (they're calling it) is very similar to the solution I was reaching on my own

#

Wait no this is... exactly what conclusion I reached in my latest impl attempt, just better executed.... hmm....

#

Lets see, CastMover appears to tell you how far you move along your velocity until you hit a collision? Returns the fraction, which I believe is 0->1 of how far you managed to move?

half ruin
#

Omg I spend 5 hours and still cant setup my physics correctly with Avian and Tnua controller

  1. Why a player slides down very slow from low profile box?
    If I set spring_strength to 3000, it slides fast (As I need, because its a normal fall down, not something special)
    But with that 3000 option, there is another issue - the player begins to be pushed away strongly from inclined planes

  2. Why player jumps very high if I jump from inclined planes ?

  3. Why player sinks a little into the ground and then sort of floats back up every time he lands after a jump?

  4. Why player starts shaking if he trips over a corner

all the issues are in the videos

1 video - spring_strength is 3000
https://youtu.be/pD3N8p7I_zE

2 video - 400
https://youtu.be/Ho2w2seSvdk

urban flume
#

it's great for a chaotic/arcadey game

sweet sundial
#

to me that looks like the collider is way too big

golden shoal
#

I'm having a bit of trouble figuring out the best method for implementing RayCasters and child rigidbodies. I'm making a top-down 2D game, and the intent was that characters have independently-rotating child "head" entities that cast rays in the direction they're looking at.
I haven't been able to implement this at all though. If I just have minimal "head" child entities with nothing other than a transform and a raycaster component, it doesn't work. The rays don't rotate with the head.
If I add a Kinematic Rigidbody to the head child, when the main body moves the child just gets left behind.
How can I have a head attached to a body that can rotate with raycasts that spin with it? I really just want a head that can look around.

little maple
#

is there an easy way to visualize shape casts other than trying to construct a gizmo where you think the shape is?

knotty thicket
half ruin
half ruin
#

here is my settings:

collider: Collider::capsule(0.5, 0.7),
sensor_shape: TnuaAvian3dSensorShape(Collider::cylinder(0.49, 0.0)),

and walk basis:

desired_velocity: direction * 1.2,
desired_forward: Dir3::try_from(direction).ok(),
float_height: PLAYER_FLOAT_HEIGHT,
max_slope: TAU / 6.0,
acceleration: 50.0,
air_acceleration: 30.0,
spring_strength: 400.0,
coyote_time: 0.1,
sweet sundial
sweet sundial
# half ruin here is my settings: ```rust collider: Collider::capsule(0.5, 0.7), sensor_shape...

my tnua: Capsule3d::new(0.5, 1.0), controllable::Walking { walk: 10.0, jump: 4.0, height: 1.5,}
and ```rust
fn apply(
intent: Single<&crate::player::Intent, With<Inhabitor>>,
mut habit_query: Query<(&mut TnuaController, &Walking), With<Inhabited>>,
forward: Single<&ForwardFromCamera, With<Inhabitor>>,
) {
let Ok((mut controller, opts)) = habit_query.get_single_mut() else {
return;
};

controller.basis(TnuaBuiltinWalk {
    desired_velocity: intent.direction * opts.walk,
    float_height: opts.height,
    desired_forward: Some(forward.forward()),
    ..Default::default()
});

if intent.jump {
    controller.action(TnuaBuiltinJump {
        height: opts.jump,
        ..Default::default()
    });
}

}```

#

oh and a TnuaAvian3dSensorShape(Collider::cylinder(0.49, 0.0))

sweet sundial
#

there's a little adjustment when stepping on and off of ledges, but it seems natural enough for my purposes

#

i think Rule 1 of tnua is "don't touch the ground directly"

little maple
half ruin
sweet sundial
#

it's an entire system designed to work around how incredibly inconvenient it is to slide a capsule around on the ground

#

so probably just, don't put the capsule on the ground

#

even on slopes

sleek thicket
knotty thicket
vestal minnow
#

I'm guessing they're using SpatialQuery methods, not the component

#

(also I'm probably still busy today but I'll be back soon!)

little maple
golden shoal
vestal minnow
royal helm
#

Ooooo

#

That'll be nice

royal helm
vagrant jolt
#

Are there any plans for an official kinematic character controller for Avian?
I've been trying to write one the last few weeks, and it's been a frustrating experience for a physics noob like me. There are still so many bugs in my implementation that I don't know how to fix, and information on this, to my knowledge, is pretty sparse.

GitHub

An attempt to implement character motion using the Bevy game engine and Avian physics. - LukK-Dev/character_controller

calm sundial
#

It would be nice to have built-in adjustable/extendable character controller(s) with clear docs. It probably should not be included in Avian default plugin and should be added as separate plugin (like avian debug plugin).

vagrant jolt
#

There are a couple of floating character controllers compatible with Avian, like bevy_tnua (which is great), but there a couple of issues with the approach that would be circumvented by using collide and slide, but there aren't any solutions out there for Avian. Having a solid, well-tested (bare-bones) implementation of a kinematic character controller in Avian (which is also great) would be really awesome for prototyping and as a learning resource.

royal helm
#

is that a separate crate or did you implement it yourself? been meaning to make something like that for my own test environment

knotty thicket
royal helm
weary hornet
# vagrant jolt Are there any plans for an official kinematic character controller for Avian? [I...

Hey, so I'm not sure how "official" worthy it is, but I have a pretty rock solid approach that has worked pretty well for me in the past, in other engines too. I did just notice a flaw with my Bevy version right now (moves a bit faster when sliding against walls) but I can fix that by comparing to my Godot version.

I took the idea from Quake 1. Essentially you loop up to 4 times, shape-casting each time. The moment you dont hit anything, you break out of the loop.

The reason you do up to 4 times is, you may hit a wall, slide along it, then penetrate another wall, so you need to check that next wall, and so on.

I've seen this question pop up a few times now and I'd love to build out a proper example. I've done one in the past but it had a bunch of multiplayer stuff in it too, can strip all that out and keep it scoped.

#

@green adder is also working on one, but I don't think he's open sourcing it, but maybe willing to share techniques, especially surrounding stairs.

#

And, this approach is solid for first/third person games, but I don't think you'd want to have thousands of units using it, so it wouldn't be good for an RTS. That's just gut feeling without trying it.

#

This approach is also great for multiplayer, because you can design it in such a way that you can rollback just the character you want, instead of needing to have full rollback. This is important because not every game needs full rollback.

#

What I can do is fix my Bevy implementation, and invite you to the repo (github) if you want

#

Or I just open it up I guess

barren elbow
weary hornet
#

ok actually so I'm looking at your code now, what are some of the problems you're getting? I see you're doing the looping thing too.

The big difference i see is you're using a par_iter. I think that may cause problems, you want it to be sequential

#

oh nvm

#

Ok you have the exact same issue as me, you're using remaining motion instead of remaining time

#

Hmm maybe its worth creating a temporary Discord server to figure this out?

barren elbow
#

Hey, is there a way for kinematic rigid bodies to opt out of automatically moving the entity using the LinearVelocity? I'm making a character controller and the movement is handled by me, I don't want to define my own velocity since then I would need to special case characters in systems. My solution for now is to just not have a RigidBody on my characters but that's biting me in my butt because now I don't get collision events for free anymore.

barren elbow
weary hornet
#

Oh I just mean for the general problem of having a rock solid character controller. I just feel like if we really dive into it, it would pollute this thread

barren elbow
#

oh yeah, I'd definetly join that.

vestal minnow
#

there's like four or more people with KCCs for Avian at this point, could be nice to gather requirements and ideas in some way

#

at least UB, aceeri, BrianH, Philipp, Luk, kinda me as well...

weary hornet
#

Yeah, and part of the problem is once you get into things like how it climbs stairs and ledges, it starts to become a game-feel thing. Phillip for example has some different ideas than I for that

green adder
#

Hey there, yes I will be doing work in this area in the next few days/weeks. I would love to share thoughts etc.
It's been a bit but I did some high level planning for some features a while ago and I'm currently planning again.
A small example of the old work:

weary hornet
vestal minnow
#

@crimson crest fyi ^

snow urchin
#

@vestal minnow Will avian get a physx backend in the future?

visual sparrow
vestal minnow
little maple
clear dew
#

Seems like I might've gotten it twisted. For ShapeCastConfig.target_distance, I assumed that the shape would travel Scalar units before detecting collisions. Am I wrong about this? just want to make sure it's my fault because I'm going a little crazy ๐Ÿ˜…

#

(implying in this picture, that the log distance would be >= 100). The other param settings compute_contact_on_penetration and ignore_origin_penetration appear to have no effect...ig I'll just need to cast the ray after recomputing the direction 200 units ahead haha

vestal minnow
#

The separation distance at which the shapes will be considered as impacting.
Meaning that in your case, when the distance between the cast shape and the other shape is 100.0, they will be considered as impacting and the shape cast will terminate at that distance

#

so if the distance is already less than or equal to 100.0, the distance traveled by the shape is 0.0

clear dew
#

I totally misconstrued that. Makes sense! I interpreted it as minimum distance between cast shape and other shape.

vestal minnow
#

It's not really a determinism bug, since the behavior is consistent across runs. But the PR results in different behavior when restarting a scene without fully clearing the contact graph, because the free/vacant graph edges affect the contact pair insertion order

#

Now should we accept that behavior (if you don't clear the graph) for the perf win or not... I'm pretty sure it shouldn't be a problem for 99% of cases, it's mainly just weird for users that past contacts would affect a "fresh" scene, and it feels like something that people shouldn't need to worry about

cinder summit
#

Similar cases would happen with things like reversible time more immediate rewinds, or even snapshot systems

vestal minnow
#

If you roll back the contact graph too, including its vacant edges, then you should get the same behavior I think

#

But yeah I'm not 100% sure how it'd work for stuff like that

#

For now I think I'll just keep the current/old approach until optimizing this is more relevant

#

Box2D uses a contact ID pool that I believe would have the same problem of past contact pairs affecting the insertion order of new pairs (I tried an ID pool too), but I'd need to run some tests with it to double-check if it has the problem

cinder summit
vestal minnow
#

You can query for the rigid body entity via ColliderOf, but that is still an extra query and more verbose

#

Internally it needs to do a query here anyway to check if the entity has collision events enabled, so this doesn't really add any overhead beyond storing the extra entity

visual sparrow
#

Bit unfortunate that it needs to be behind an Option

cinder summit
visual sparrow
#

So I still have the whole let Ok(rb) = trigger.rigid_body else { return; } song and dance