#Avian Physics

1 messages ยท Page 10 of 1

vestal minnow
#

??? with normal Colliders the render order is different

#

and it also doesn't randomly explode unlike the CircleCollider version

#

I'll fix it tomorrow, need to sleep rn

lunar bluff
#

Hello, I'm trying to use a dynamic RigidBody to simulate the ball's movement in a breakout game. In other words, I want velocity and collisions to be handled by the plugin, and for the ball to maintain a constant velocity, forever. I thought that perfectly elastic restitution would suffice, but every time it bounces off a wall, it loses some velocity. This is contrary to what I unserstood about "perfect elasticity". I have also ensured that the combine rule is "max" so the wall's resitution does not come into play. Here's the code for generating the ball, which starts within a box of static rigid body walls:

    commands.spawn((
        SpriteBundle {
            sprite: Sprite {
                color: Color::rgb_u8(248, 131, 121),
                custom_size: Some(Vec2::new(20., 20.)),
                ..default()
            },
            ..default()
        },
        RigidBody::Dynamic,
        LinearVelocity(Vec2::X * 300.),
        LockedAxes::ROTATION_LOCKED,
        Restitution::PERFECTLY_ELASTIC.with_combine_rule(CoefficientCombine::Max),
        Friction {
            dynamic_coefficient: 0.,
            static_coefficient: 0.,
            combine_rule: CoefficientCombine::Min,
        },
        Collider::cuboid(20., 20.),
    ));
}```
#

I've also set gravity to zero

atomic wigeon
#

It's from wgpu-core-0.17.1.

I see that the default LogPlugin from Bevy filters wgpu, but not wgpu-core?

impl Default for LogPlugin {
    fn default() -> Self {
        Self {
            filter: "wgpu=error,naga=warn".to_string(),
            level: Level::INFO,
        }
    }
}```
atomic wigeon
#

New q: do CollidingEntities include entities that aren't "interactable" for their collision group / mask?

glad abyss
#

so i have a project where i use bevy_ecs_ldtk and bevy_xpbd_2d. i recently upgraded from bevy 0.11 to bevy 0.12 with all the relevant plugins.
in bevy 0.11, performance was fine. after the upgrade, performance is unusably slow (seconds per frame). i did a trace to investigate.
in the trace, i see that each substep is taking a huge amount of time, and pretty much all that time is spent in bevy_xpbd_2d::plugins::sync::propagate_collider_transforms
i look at the source code of that system and i see that it has the following queries

    mut root_query: Query<(Entity, Ref<Transform>, &Children), Without<Parent>>,
    collider_query: Query<
        (
            Ref<Transform>,
            Option<&mut ColliderTransform>,
            Option<&Children>,
        ),
        With<Parent>,
    >,
    parent_query: Query<(Entity, Ref<Transform>, Has<RigidBody>, Ref<Parent>)>,

Note how none of these queries actually restrict themselves to just operate on physics entities (those that have bevy_xpbd components). Option and Has query parameters do not limit the selection of entities that the query matches! so this system is iterating over everything, not just physics stuff.
I tried commenting out all the systems in my game that set up physics entities. Therefore, the expected outcome should be that bevy_xpbd should have nothing to do. But the game still runs just as slowly. I am just loading my LDTK level without setting up any colliders or rigid bodies, which creates many thousands of (non-physics) entities.
I patched bevy_xpbd with some debug prints to see how many entities those queries match:

root_query.iter().len() = 1
collider_query.iter().len() = 60877
parent_query.iter().len() = 60877

So I can indeed confirm that this system seems to be doing huge amounts of work on non-bevy_xpbd entities.

@vestal minnow do you have an idea how we could fix this bug?

cinder summit
#

I think the problem might be that bevy_xpbd doesn't have any strict requirements on what needs to be on entities ... Iirc even entities with just a collider without Sensor or RigidBody behave like a sensor

#

I think this ColliderTransform is also global, and not relative to the top rigid body entity ๐Ÿค”

vestal minnow
#

iirc the main issue here is that I wanted child collider hierarchies to work with any amount of nesting, and it should even work if there are entities that don't have any physics components

#

If we have that as a requirement, then I don't think we can add With filters here

#

And it currently runs this transform propagation on every substep, not just every frame, because the collider positions should be up-to-date for the narrow phase and solver

cinder summit
#

I think a collider hierarchy should probably start with RigidBody or Sensor at least. And ofc only ones that actually have children

vestal minnow
#

Yeah, that's probably a reasonable requirement...

#

It just means that you can't have just colliders and have the transforms work correctly like in other engines

vestal minnow
#

So global in the sense that if you had like 10 levels of nesting for colliders, they'd all use the same rigid body as a reference point

#

But it's not global like GlobalTransform

cinder summit
#

Isn't some propagation also needed to get the position of the top-level of the rigid body?

vestal minnow
#

yes

#

I'm not sure how well it works if the rigid body is already a child

#

I'm pretty sure it should work "normally" atm

cinder summit
#

But yea if it starts from RigidBody/Sensor it should avoid most entities. And I think the propagation the other way already breaks without RigidBody anyway ๐Ÿค”

#

I'm kind of surprised how slow it gets with just 60k entities tho

vestal minnow
#

scales with the number of substeps probably

#

there must be a better way to handle child colliders though, I'm not a fan of the current implementation

cinder summit
vestal minnow
#

yea

#

I think it'd also make normal transform propagation faster?

#

I remember some discussion about how it currently has to iterate over basically everything, and it could be optimized in some way

#

don't remember if relations are related tho

torn hedge
#

Hello! I hope I'm not interrupting anything here.

I'm trying to have 2 raycasts follow one of my entities. so i add those raycasters as a child to that entity.
but they are not following the entity

after some trying, i figured out it seems like they only follow an entity that has a rigidbody component?

without the RigidBody no RayCaster is following. but i don't really want the entity to be a rigidbody.

vestal minnow
torn hedge
#

ah i see, should have checked github issues first. my bad. thanks though!

vestal minnow
#

I've meant to fix this several times now but I keep getting distracted by other things lol

#

I'll try to fix it soon

torn hedge
#

i could have a try

vestal minnow
cinder summit
vestal minnow
#

The issue is that it currently relies on the Position and Rotation of the parent, but those only exist on physics entities. It should probably fall back to GlobalTransform in those cases

#

Yeah, true

#

Hierarchies are pretty heavily used in other game engines even for just organization (and Godot's node workflow), but for an ECS it's a bit different

cinder summit
#

The most common use for hierarchies is just "I need this to despawn with this other thing" ... I've had multiple cases where transform propagation became an unwanted side effect of that behavior

vestal minnow
#

One reason why child colliders and hierarchy support is currently very important is for glTF scenes and async scene colliders

#

glTFs are usually heavily nested

#

could flatten it I guess

cinder summit
#

Yea you could flatten it, tho many of the issues of loading glTFs would still remain unless you convert them to some more sensible format

#

Even if we get relations and have the asset processing to fix some of the issues, I think we're probably going to be stuck with "everything is heavily nested hierarchies" for a while either way ๐Ÿค”

vestal minnow
#

that reminds me that we also need to try the asset preprocessing thing with running convex decomposition in advance

#

for static scenes

cinder summit
#

Yea that would be useful, tho I'm not sure if any work has even be done yet on preprocessing scenes

vestal minnow
#

I have no clue on any asset or scene things so idk lol

#

How would bsn handle constructors ๐Ÿค” like how do you make a collider with Collider::ball

#

or would it need custom structs that get converted to colliders in some build step

#

(primitives ๐Ÿ‘€)

cinder summit
#

Well yes, pretty sure if bevy_gltf reads colliders from a gltf file (idk if that's a part of the spec yet, I remember someone working on it showing up on the bevy discord tho), it would pretty much just have to load it as "oh hey here's some collider primitives"

#

It could then get preprocessed into more specific collider types

vestal minnow
#

I think (basic) glTF extension support also just got merged for Bevy so physics/colliders in glTF files might be more viable, assuming there's progress on the actual extension

#

I haven't followed if they've made progress on it tho

#

all physics stuff seems to be at stage one of five

#

*six, it starts at stage 0

torn hedge
vestal minnow
torn hedge
#

yeah, no stress! Hope the code is good enough. feel free to give feedback and criticize it :)

torn hedge
#

the system that update the positions of the raycasts is in the PhysicsStepSet::SpatialQuery SystemSet.
which runs in its own PhysicsSchedule.

now i never used schedules myself, so it could just be a missing understanding from my side.
but i currently have the problem that the RayCasts lag behind my non rigidbody entity.
why could that be?

do i need to order my system that updates that entitity before the PhysicsStepSet::SpatialQuery?

#

when my camera had jitter i just ordered the system like this:
.after(PhysicsSet::Sync).before(TransformSystem::TransformPropagate) and that worked. but as the update_ray_caster_positions doesnt run in PostUpdate/FixedUpdate, but in PhysicsSchedule, i can't order it like this again

#

also not sure if thats even the same problem at all

lunar bluff
#

does xpbd have any kind of interpolation built-in? Or should I go for bevy_xpbd_2d_interp

#

moving a kinematic body at high speed using velocity is very jittery

vestal minnow
#

no built-in yet

lunar bluff
#

okay, thanks, i'll use bevy_xpbd_2d_interp for now then

vestal minnow
#

are you making the camera follow the body?

lunar bluff
#

no, im making a ball move around for a simple breakout game

#

if it was a camera following, i'd probably use some lerp-based solution anyway

vestal minnow
#

which requires specific system ordering for camera following

lunar bluff
#

ah okay. yes its a different issue, i just want a thing to move smoothly at 160fps

vestal minnow
#

You could probably make physics run at a higher rate too, it'd just be more expensive

#

and not ideal for monitors with a lower refresh rate

lunar bluff
#

its always temping to do that, but then where's the speet spot. in my opinion, the physics rate should reflect the accuracy you desire, not the graphics fidelity

vestal minnow
#

yep

lunar bluff
#

im not after any level of accuracy beyond 60Hz

#

thanks for the rapid response by the way, much appreciated ๐Ÿ‘

cinder summit
vestal minnow
#

that's the main reason it normally uses Position/Rotation; it's the up-to-date physics position

#

fixing it would probably require either running extra syncing for transforms, or reordering scheduling so that spatial query stuff runs after transform propagation

#

Btw @cinder summit I fixed the explosion thing in the custom collider example, I had .length() instead of .length_squared() in the circle collision logic...

#

There's just a clear determinism issue where results vary between runs, even with normal Colliders

#

I'll check if it's also an issue on main

#

otherwise I think everything should be ready so I can finally make the PR

vestal minnow
#

okay the determinism issue doesn't exist on main it seems, so it's a regression... I'll make a draft PR anyway and have it as todo

vestal minnow
#

@cinder summit Sry for ping again, but the generic collider PR should now be ready and working... It's quite a bit bigger than I anticipated, but I think the refactors and additions are quite nice overall
https://github.com/Jondolf/bevy_xpbd/pull/311

GitHub

Objective
An improved and more focused version of #302.
Currently, collider logic is split across several plugins. The PreparePlugin initializes them and manages mass properties and collider parent...

#

Porting the SDF colliders should hopefully be straightforward

#

Currently it does require implementing ScalableCollider, but you could just make it do nothing lol

sleek thicket
#

@vestal minnow SpatialQueryFilter::new() is exact same thing as SpatialQueryFilter::default() and both feel like a pointless extra step, so

can you add something like this?

    pub fn new_from_bits(masks: u32) -> Self {
        Self {
            masks,
            excluded_entities: default(),
        }
    }

    pub fn new_without(entities: impl IntoIterator<Item = Entity>) -> Self {
        Self {
            masks: 0xffff_ffff,
            excluded_entities = HashSet::from_iter(entities),
        }
    }

    pub fn new_from_bits_without(masks: u32, entities: impl IntoIterator<Item = Entity>) -> Self {
        Self {
            masks,
            excluded_entities = HashSet::from_iter(entities),
        }
    }
vestal minnow
#

also I tried making some of the methods const but couldn't find a nice way to make a const HashSet

sleek thicket
#

i never used PhysicsLayer because bitmask seems simpler, and i don't see bits+without there

#

maybe change names for them to "from_bitmask" and "from_layermask"?

#

changing the old functions to "set_" would make it easier to understand too

#

with_masks_from_bits -> with_bitmask
from_mask_bits -> from_bitmask

with_masks -> with_layermask
from_masks -> from_layermask

without_entities -> with_excluded (i really like .without() though)
from_excluded_entities -> from_excluded

torn hedge
cinder summit
cinder summit
vestal minnow
#

And from_excluded doesn't signify what is excluded; Layers? Rigid body types? Sensors? Or specific entities, which is what it actually excludes

#

And yeah set isn't ideal imo if it doesn't take a mutable reference but just returns the mutated version for chaining. I think with is also more common for this pattern in Bevy, e.g. Transform::with_translation

vestal minnow
#

I originally went for Godot's naming, it calls them collision masks iirc

#

I think Rapier calls them interaction groups

topaz yacht
#

For what is worth, I found group and mask pretty obvious names, but I do come from Godot ๐Ÿคทโ€โ™‚๏ธ

cinder summit
#

It's the bits that makes it less obvious ๐Ÿ˜‚

#

Pretty sure if we had better const in rust we wouldn't even need that

topaz yacht
#

with_masks_from_bits -> with_masks_from_bitmask then ?

cinder summit
#

Definitely sounds more reasonable ... Makes the name more clear in two ways ๐Ÿค”

sleek thicket
vestal minnow
#

We will probably add more options though

#

Like flags for rigid body type and whether a collider is a sensor

sleek thicket
#

then it makes sense

vestal minnow
#

And a custom predicate would be nice, although I think there'd be lifetime issues

#

(when used with RayCaster/ShapeCaster)

sleek thicket
#

well, the main issues:
new() is redundant
chaining must be consistent with new
bit and layer counterparts must be consistent

so, these make complete sense to me:
with_masks_from_bits -> with_bitmask
from_mask_bits -> from_bitmask

with_masks -> with_layermask
from_masks -> from_layermask

but is new() even required?
and i have no idea about without_entities being different from_excluded_entities, i really like without but don't like inconsistency

cinder summit
#

If you have no new() how would you start the chain?

vestal minnow
#

default()

#

but lots of Rust APIs have new too, like Vec, HashMap etc.

#

mainly it exists on SpatialQueryFilter for consistency with CollisionLayers, but I guess we could remove both

vestal minnow
sleek thicket
#

yeah but that's basically what unity does

#

you basically just set it up in editor in a dropdown enum/bitmask

vestal minnow
#

it'd probably be with_layer_mask at least since it's two words and not layermask

#

bitmask is one word tho

#

typically

sleek thicket
#

bitmask is always written as 1 word so the same thing makes sense for layermask, yeah

cinder summit
#

Because bitmask is pretty well established as 1 word

vestal minnow
#

yeah layermask isn't very established

sleek thicket
#

roll a die

cinder summit
#

Also I feel like layer_mask wouldn't really make things much better ... It's kind of far fetched for people to just be looking for it as that because CollisionLayers has the word layer in it ๐Ÿค”

vestal minnow
#

yep

cinder summit
#

If mask isn't clear, collision mask or collider mask might make more sense

sleek thicket
#

wait, wouldn't that actually work for without

cinder summit
#

Wasn't there some other mask component too, for the solver?

sleek thicket
#

from_entity_mask
with_entity_mask

cinder summit
#

entity_mask sounds pretty spooky ferris_spooky

sleek thicket
#

๐Ÿค” nvm i still like without more

cinder summit
#

"Please give me all collisions with entities that have bits 3 and 7 set on their generation"

vestal minnow
#

maybe we could make a separate Layer struct, use that for groups and masks in CollisionLayers, and have a method with_masks that takes impl Into<Layer>

#

then you could pass either a u32 or enum-like value

#

maybe

sleek thicket
#

i'd prefer if you didn't make it any more complicated ๐Ÿ˜‚

vestal minnow
#

it'd reduce the number of methods in public API

cinder summit
#

It would be simpler to use ... The weird iterator signature always looks kind of confusing ๐Ÿค”

vestal minnow
#

and make names nicer

cinder summit
#

Also making it with_collision_masks might be more clear ... Especially if we add other masks later

vestal minnow
#

from_masks and with_masks

sleek thicket
#

idk about how it'd work with editor but for me just doing the
pub const somelayer: u32 = 1 << 10;
pub const someotherlayer: u32 = 1 << 20;

and doing bitmask from (somelayer | someotherlayer) works really well for me

cinder summit
#

Can't wait to have CollisionLayers, SolverLayers, ConstraintLayers, etc ๐Ÿ˜‚

vestal minnow
#

I'd like to handle layers via ECS filters ideally

cinder summit
cinder summit
vestal minnow
#

Joints as relations would be nice

#

Even collision data in relations could be kinda nice but probably not efficient, idk

#

Constraint graphs via relations

cinder summit
#

If we take it to the logical conclusion .... Collisions as ๐ŸŒˆ

vestal minnow
#

You could add arbitrary data to collisions by just adding components... would be really nice for queries and modularity

cinder summit
#

Hmmm, there wouldn't happen to be some secret branch of bevy_xpbd with bounding sphere support, right? ๐Ÿค”

vestal minnow
#

bounding spheres/circles instead of AABBs?

#

no

#

sweep and prune also wouldn't be as nice since the min/max would need to be computed every time

cinder summit
#

Guess I'll have to constraint testing that part of the bevy_math changes to BVH-related operations then thonk

vestal minnow
#

Not 100% sure but I think with Layers I might be able to get rid of all the weird iterator stuff and remove like over half of the methods

#

Like for CollisionLayers::add_groups you could do any of these

  • layers.add_groups(my_bitmask)
  • layers.add_groups(MyLayerEnum::Foo)
  • layers.add_groups([MyLayerEnum::Foo, MyLayerEnum::Bar]
#

I think

#

Since it'd just take an impl Into<Layers>. Layers stores a u32 bitmask but has a bunch of Into impls

#

So it can be a bitmask, an enum implementing PhysicsLayer, an array of layers...

#

instead of a separate method for all of these cases for adding layers, removing layers, checking if a layer exists and so on

vestal minnow
#

I'm really liking this API, I think it's pretty ideal in terms of flexibility, ergonomics and reducing API duplication

#

Also more explicit in some ways

sleek thicket
#

you can do both ๐Ÿคทโ€โ™‚๏ธ

vestal minnow
#

wdym both?

sleek thicket
#

old and add_groups

vestal minnow
#

no but the new API does everything the old one does, just with way less methods and with nicer ergonomics

#

kinda like how Bevy deprecated add_system in favor of a single add_systems

sleek thicket
#

it definitely makes sense for new()

#

i just don't understand why overcomplicate it when all you need is a simple u32

#

i'm probably just missing part of perspective because i never thought about future masks and using it with ecs filter

vestal minnow
#

Layers stores a u32, but allows you to create layers in other ways too

#

I don't see how it complicates things

#

Instead of CollisionLayers::from_bits you can now just use CollisionLayers::new for everything

#

also this isn't related to ECS stuff

sleek thicket
#

will it still work with const?

vestal minnow
#

yes

sleek thicket
#

then it's fine

#

actually on that point

#

wouldn't making from_bits for queryfilter allow const queryfilter

vestal minnow
#

You can make const Layers, but not all CollisionLayers methods are const (which was also the case before)

#

new wasn't const before either

sleek thicket
#

in that case i'll be able to move some of the repetitive filters to a single place

vestal minnow
sleek thicket
#

basically replacing
SpatialQueryFilter::new().with_masks_from_bits(layer::damageable).without_entities([*e]);
with
layer::filterDamageable.without_entities([*e]);

#

CollisionLayers was already fine... wait, are you trying to unify them?

vestal minnow
#

No?

sleek thicket
#

ok then i just realized why the layermask was confusing

vestal minnow
#

Hmm, should we also just remove chaining from CollisionLayers and make the methods mutate &mut self instead? There's currently the footgun where collision_layers.add_masks(...) won't do anything unless you use the return value

#

#[must_use] can help avoid the footgun but I feel like the chaining isn't that valuable anyway

#

In most cases you'd probably just use CollisionLayers::new or similar, and with bitwise ops you could add/remove layers anyways if you wanted to

sleek thicket
#

i can imagine that being especially useful if there would be a function to "add layers if there's no intersection" to avoid accidental explosive behaviour

vestal minnow
#

you'd just implement that manually with a system

sleek thicket
#

yeah but it's something that feels like it could be streamlined

vestal minnow
#

it could maybe be done with a system param or possibly a custom command

#

but the component itself shouldn't be aware of any other state like if there's an intersection

sleek thicket
#

yeah i guess if it's for sensors then it's not required, and for colliders it's probably rare enough to not bother
my only use case for flipping layer was the celeste dream block in unity, it's solid unless player is dashing so what i did there is modify layer on player for the duration of dash

#

and i guess i can imagine it being used for those 2d platforms that pop out from background

#

spawning things is really common, so maybe a generic function for checking that would be more useful

#

you already have that intersect test for warning when spawning, is there any other functionality other than warning?

vestal minnow
#

at least with a system param

#

I made a quick algorithm for finding a "safe" spot to spawn a while ago

#

could be improved tho

sleek thicket
#

i have no idea how i'd do it in rust, i was thinking about something like a callback, if successful then call function1, else call function2

#

e.g. you could want function2 to move spawn point to safe place, or wait, or cancel...

vestal minnow
#

You can do intersection tests with SpatialQuery

#

for a given shape and position

#

if there's an intersection, just fall back to something else

sleek thicket
#

but it's not in the same frame as spawn, can't something go wrong there?

vestal minnow
#

if something happens to move there before the spawn command has been applied, then sure

#

but that's probably pretty rare

sleek thicket
#

not at all, consider how many moving entities could be in a game with ECS

#

but yeah that's solving a problem way ahead of time

vestal minnow
#

it's a one frame delay at worst

#

you could add an extra padding to the intersection check

#

to account for some movement of nearby entities

#

you could probably also schedule it in a way where the entity is spawned before physics runs

#

which would avoid the issue completely

#
  1. check for intersection (before physics)
  2. if no intersection, spawn entity
  3. apply_deferred
  4. physics
#

For SpatialQueryFilter, would these constructors be fine?

  • from_collision_masks and with_collision_masks
  • from_excluded_entities and with_excluded_entities
    I'd also probably be fine with removing _collision and/or _entities, so that it'd be e.g. from_masks and with_excluded
#

I agree without_entities is really nice though...

#

consistency is probably more important still

sleek thicket
#

i vote for from_masks and with_masks

#

or from_mask and with_mask

#

or from_layers and with_layers

vestal minnow
#

masks is probably more accurate

#

also what Godot uses for raycasting masks iirc

sleek thicket
#

for filter it's a single bitmask though, for collisionlayers it's 2 masks

vestal minnow
#

yep

#

hmm

vestal minnow
#

(encoded as bitmasks)

#

mask in the context of collision layers just means a layer that something can interact with

#

"interaction group" would be more explicit in that it's more clearly a single layer

#

a mask often just means a bitmask which can define multiple layers...

#

and having mask and groups as the property names wouldn't be ideal imo, kinda inconsistent

sleek thicket
#

that needs to be written down in docs just so people know how much thought was put into naming

vestal minnow
#

bikeshedding is 90% of the work in software development lol

sleek thicket
#

for me it's more like 9%

#

90% is just procrastinating in other ways

vestal minnow
sleek thicket
#

that's just savage

vestal minnow
#

oh PointCompositeShapeProjWithFeatureBestFirstVisitor is better

#

alongside PointCompositeShapeProjWithLocationBestFirstVisitor

sleek thicket
#

i didn't check on progress for a while now, how's replacing parry coming along?

vestal minnow
#

whoa RayCompositeShapeToiAndNormalBestFirstVisitor, haven't seen that one before

vestal minnow
#

I was working on replacing the bounding volumes with Bevy's bounding volumes today

#

trying to replace Parry's shapes with Bevy's primitives

#

I also made a PR for generic colliders in bevy_xpbd, which will make integrating custom collider backends (like Nise's SDF colliders) much easier

#

it'll be useful for a kind of transition period where we can test replacing Parry without fully committing at the start

#

and also if I try to make a fully custom collision detection lib from scratch eventually

sleek thicket
vestal minnow
#

Maybe, but only after it's at a state where I feel confident that it's a good implementation and I understand everything well enough

#

I also would like to make physics tutorial stuff but I still feel like I don't have enough knowledge on some important things

sleek thicket
#

there were also tutorials for breakout and asteroids but they were too focused on 1 thing
it's a really interesting but unapproachable topic, so maybe from scratch it would make more sense to get into it

vestal minnow
#

I agree, there are very few good resources that go in-depth

#

if any

vestal minnow
sleek thicket
#

cocporn was really frustrated at how physics work when i tried to explain the stuff i know, and theoretically anyone should be able to look at the source code and learn how it works but yeah, currently it's a monolith without a good entry point to start learning

#

and i keep referencing catlikecoding because it uses "mistakes" as part of teaching

#

like oops we didn't normalize and now we move diagonally with ~40% more speed, here's how to normalize...
but means controllers won't be able to move slower than max speed, so here's how to clamp magnitude instead...

vestal minnow
cinder summit
vestal minnow
#

I don't think that'd get rid of the .0 if you just want the value

#

also idk if we want all number methods on a layer type

cinder summit
#

At least in this case it's mostly on a struct field ... Missing derefs are very annoying on newtype components tho ... Cause then it's much shorter to just throw a few stars at it ๐Ÿ˜‚

vestal minnow
#

wait whoops, apparently I made Layers a component lol

#

eh, I'll add Deref

fair fractal
#

my physics objects seem to kinda jump around when they fall asleep, which causes them to jolt back awake? It doesn't happen when I add the SleepingDisabled component. has anyone seen this before or are there any fixes?

#

it looks like this might be the same issue? is there an easy fix for to this?

sleek thicket
#

won't converting u32 to Layers then back to u32 have a performance hit?

#

converting to layers would be fine with const but then converting back can't be avoided

#

definitely looks cleaner from user side (at least at first glance), but the whole rework seems bigger than i expected

fluid echo
#

I put my physics in FixedUpdate and it really tanks performance, even with Time::<Fixed>::from_hz(32.) (though much less so). My goal was to make sure physics is stable even in laggy situations, and to make it easier to network in the future. Should I be concerned with the stability of the physics under lag? And is there a better way to make the physics run in fixed updates?

fair fractal
#

also make sure you're configuring the physics timer to run at the proper interval type. It should be TimeStepMode::FixedOnce if it's in fixed update

fluid echo
fair fractal
#

well it sounds like the player look system might depend on the player transform which would be controlled by the physics engine if it's a physics object, are you sure this isn't the issue? It really sounds like it is to me. Also, If it is, you could fix it by implementing interpolation on your rigidbody entities with something like this crate:
https://crates.io/crates/bevy_xpbd_2d_interp

#

there is also a 3d one

fluid echo
#

But it's good to know, thanks

#

The look system sets the transform directly, and is chained before propagate_transforms

#

And when I put a log statement in it, it prints only like 3 times per second

fair fractal
#

well that's definitely problematic, not really sure what the issue could be

#

It works a lot smoother when I have the physics running in fixedupdate for me

fluid echo
#

I'll try to make a minimal repro

vestal minnow
#

It can also be disabled globally by disabling the SleepingPlugin or by making the SleepingThreshold resource negative

vestal minnow
#

Layers is just a wrapper over u32

cinder summit
#

There's a reason we don't have runtime reflection in rust

vestal minnow
#

Afaik there are weird edge cases where newtypes do have extra overhead compared to raw values, due to specialization reasons

#

but that's probably basically negligible in 99% of cases

cinder summit
#

Yea I think newtypes can break some optimizations like Option<NonZeroX>, but converting between u32 and NewType(u32) shouldn't have any cost

vestal minnow
#

yeah

cinder summit
#

It's a different story if the types actually have different representations tho, like Vec3 vs Vec3A

peak marsh
#

What's the difference between the normal values in ContactManifold and ContactData? The docs says they're shared, but if so why are they duplicated?

vestal minnow
#

It can be useful to have them in ContactData so that you have access to them when e.g. iterating over a flat list of contacts

#

I guess we could make two different versions of ContactData, one with normals and one without

#

Then only ContactManifolds would store the normals internally, but we could have some APIs that give the normals with the contact data

peak marsh
#

Makes sense, thanks!

fair fractal
#

I mean even if there were newtype conversion overhead, it seems like the cost would be so small it'd be pretty much negligible anyway

sleek thicket
#

right, i forgot rust was made by wizards

sleek thicket
#

i did find a blog post about how it might be non-zero-cost but his example in last version of rust was exactly the same between the two

vestal minnow
sleek thicket
#

i think LayerMask be a better fit than Layers, easier to understand that it's a bitmask and it's basically same thing unity did

#

in unity Layer is the individual bit, e.g. player, and you can assign only 1 per object, which sucks btw.
and the CollisionLayers is set globally in physics settings, and called Layer Collision Matrix. which also kinda sucks.

vestal minnow
#

yeah I think LayerMask is a better name than Layers, I'll change it

sleek thicket
#

by unity layer logic, in query_filter, line 17:
A query filter that has three collision masks and excludes the object entity
->
A query filter that has three (collision?) layers and excludes the object entity

#

checking if unity refers to layers as collision layers anywhere but i don't think so, they use the same layers for other purposes
how was it in godot?

vestal minnow
sleek thicket
#

collision mask bit...
vs collision layer

#

i think mask bit is more descriptive, but layer just feels more natural because i'm from unity

vestal minnow
#

It's mask because of how CollisionLayers properties are

  • groups describes which layers an entity belongs to
  • masks describes which layers an entity interacts with
    The collision masks in SpatialQueryFilter are basically like masks, i.e. the layers that a raycast/shapecast can detect
sleek thicket
#

found godot counterpart

#

so godot calls it collision_layer, and the collision_mask is made from collision_layers

vestal minnow
#

collision_layer is just our groups

sleek thicket
#

yep, i'm still reading

#

so collision mask is the matrix

#

and layer is mask

#

๐Ÿฅฒ

#

trying to find unreal counterpart

vestal minnow
#

what about renaming masks in CollisionLayers to filters and in SpatialQueryFilter to layer_filters

#

that way you wouldn't confuse collision masks and bitmasks

#

and the meaning might be clearer since it's kinda like Rust's filter (keep only the layers that return true/1)

sleek thicket
#

seems like UE has same thing as unity, but calls layers/bits "object type"

#

and "collision responses" for the matrix.. or is that mask... i can't tell

vestal minnow
#

that's just confusing lol, would you call "Environment" an object type?

#

I kinda like filters

sleek thicket
sleek thicket
vestal minnow
#

I can't visualize it as a matrix but maybe

sleek thicket
#

is it same thing as collisionlayers or am i missing something

#

i guess collisionlayers is way more complicated because of groups, not sure if that means it's no longer a matrix

vestal minnow
#

it's just two bitmasks, groups and filters (currently masks), and if A has a filter that matches a group of B, they can interact

#

my brain isn't a huge fan of the matrix representation but that might just be me

sleek thicket
#

now that i think of it, the difference between unity matrix and collisionlayers might need a good example/documentation

#

ok i'll need to think about it, but i definitely think that 'Layers' would be better off as something that has 'Mask', one way or another

#

using raycast as baseline, godot uses CollisionMask, unity uses LayerMask, can't even find what UE has

#

and ultimately it's just a BitMask

#

on a side note, i really like godot's mask UI

#

so, CollisionLayers is just Collision

#

Groups is Layer

#

just 'Collision' probably wouldn't work here though

vestal minnow
# sleek thicket now that i think of it, the difference between unity matrix and collisionlayers ...

In the matrix picture above, layers 1-3 are set up so that 1 interacts with 1, 2 interacts with 2, and 3 interacts with 3.

With Unity, these seem to be hard-coded in that a single object can only belong to one layer at a time, and that layer can only interact with the layers defined in the global collision matrix.

The CollisionLayers equivalent (with bitmasks) is

  • Entities on layer 1 have CollisionLayers::new(0b0001, 0b0001)
  • Entities on layer 2 have CollisionLayers::new(0b0010, 0b0010)
  • Entities on layer 3 have CollisionLayers::new(0b0100, 0b0100)
    The difference is that each entity can belong to more than one layer, and the filters can be configured at an entity-level
sleek thicket
#

it seems that godot has individual collision checks similar to unity, but xpbd works in a way that there's only a single collision event

#

so i'm currently struggling to understand how matrix even works

#

i watched the godot and it made sense that object can belong to nothing but have an interaction mask checking for environment, therefore collision happening

#

maybe i should just download godot and play around with physics

vestal minnow
# sleek thicket

ooh safety margin seems like a much better name for our weird prediction_distance

sleek thicket
#

yeah i noticed that too but i'm not even sure if it's the same thing, is prediction_distance on every object?

vestal minnow
#

it's the same for every collider currently

sleek thicket
#

well, margin is still a better name

vestal minnow
#

prediction_distance is a valid name but not for what we use it for I think

#

it'd make sense for speculative contacts but I think that's slightly different from what it currently does

sleek thicket
#

it just makes more sense from a user perspective

vestal minnow
sleek thicket
#

and it seems people are struggling with masks in godot too

#
A is on layer 1 and has a mask on 2

B is on layer 2 and has no mask

A will detect a collision with B

B has no mask layer and will not detect anything

how would that work in xpbd?

vestal minnow
#

(with bitmasks, assuming layer 1 is the first layer)
A: CollisionLayers::new(0b01, 0b10)
B: CollisionLayers::new(0b10, 0)

sleek thicket
#

no, i know how to assign them but what's the outcome

#

because godot has same thing as unity where each object is called to do something

#

e.g. if they both have scripts to explode on hit, and both detect each other, then both explode.
if taking that same example, then A will explode but B won't

vestal minnow
#

I think there won't be a collision because B can't collide with A

#

Both need to match

#

Collisions aren't one-sided

sleek thicket
#

yeah, that's exactly my point

vestal minnow
#

Bevy doesn't have signal-like callbacks

#

in the same way at least

sleek thicket
#

the way i have it is just a giant match that gets a "tag" where i pretend it's a class

#

it's just that i've been using this without fully understanding what's going on.

vestal minnow
#

If we stored collisions in components, you could query each entity's collisions separately, but it's not ideal in some other ways

#

But

#

๐ŸŒˆ

#

I think with relations we could have unidirectional collisions, maybe

#

If we made each collision an entity

#

They'd just be graph edges basically

sleek thicket
#

i'll need to test it more to see if it's even needed

#

it feels like both ways have their shortcomings

vestal minnow
#

yeah

sleek thicket
#

i like how with xpbd i don't have to worry about race conditions for bullets

#

except the part where it might hit 2 things at the same time

#

but it's mostly because i have bullets that are damageable

#

in unity the collision between 2 projectiles was a headache, in xpbd you just match (type, type) { projectile, projectile) => { NoHeadache(); } }

#

@vestal minnow does CollisionLayers depend on parry?

vestal minnow
#

No

#

It's custom

#

Originally inspired by the heron crate (wrapper over bevy_rapier)

sleek thicket
#

good, i just thought that rewriting parry might affect it

vestal minnow
#

Very few things in the public API depend on Parry

#

collider shapes are probably the biggest one, but you rarely need to deal with the actual Parry shapes

#

and ColliderAabbs I guess

sleek thicket
#

yeah, then i'll have to try to come up with a bunch of scenarios to make some kind of introduction to layers because it's different from everything

#

although if using just a single layer then it's close enough to unity

#

that's basically what i've been doing so maybe that's why i didn't find any issues

vestal minnow
#

yeah you should be able to use it like Unity, but you can also do more things

sleek thicket
#

yeah, in unity i struggled several times because objects couldn't have multiple layers

#

so i had to resort to using tags

#

using hit.layer and hit.tag ended up covering most of it

cinder summit
sleek thicket
#

@cinder summit got any opinions on the layer/mask naming mess?

cinder summit
#

I like group/mask ... Group is better than layer imo, tho I'm not a huge fan of the word "mask" cause groups are really also a mask thonk

vestal minnow
cinder summit
#

Yea, groups/filters sounds nice ๐Ÿค”

vestal minnow
#

i.e. replace "collision masks" with "collision filters" in CollisionLayers

sleek thicket
#

i think what's inside collisionlayers doesn't matter as much as collisionlayers and layermask themselves

vestal minnow
#

it does matter for the API

#

like add_masks

sleek thicket
#

you could just keep it as unnamed tuple and add to docs that first is the layers it belongs to, and second is layers it's supposed to collide with

cinder summit
#

Godot also has this absolute moronic mess

#

Those checkboxes on Area3D are just duplicate behavior of clearing the masks thonk

sleek thicket
#

maybe that's because of something going on in the background

cinder summit
sleek thicket
#

the way you make new collisionlayers is exact same though

vestal minnow
#

I'd definitely keep the naming explicit

sleek thicket
#

i think it'll still have to be explicit for the editor

cinder summit
sleek thicket
#

yeah

#

no

#

wait

#

what was it after rework xD

vestal minnow
#

That

#

new didn't have breaking changes

#

Other than being more flexible

sleek thicket
#

i think target would work here too

vestal minnow
#

I like filter for being like Rust's filter (although not a callback)

sleek thicket
#

if it works the same for raycast and collisions then it makes sense

vestal minnow
#

for spatial query filters it could just be layer_filter

#

i.e. it filters which layers are included

cinder summit
#

With the naming I feel like some form of "member" makes more sense than groups actually thonk

sleek thicket
#

in my mind i'm only settled on that each individual bit is "layer", and both godot and unity use that
and the actual bitmask type has to have "mask" in it, like godot's CollisionMask and unity's LayerMask

#

i have no idea what i'd do with collisionlayers and the 2 bitmasks it holds

vestal minnow
sleek thicket
#

LayerGroup?

vestal minnow
#

add_member sounds very weird though lol

cinder summit
#

member_of thonk

vestal minnow
#

LayerBundle lmao

cinder summit
vestal minnow
sleek thicket
vestal minnow
#

I'd like layers as marker components but idk how to store query filters

cinder summit
sleek thicket
#

so yeah godot is collision layer for 1 bit, collision mask for the whole bitmask

#

unity is layer for 1 bit, layermask for whole bitmask

cinder summit
#

collision layers aren't called a mask, despite basically being a bitmask

#

We must be the only ones worrying about this naming ๐Ÿ˜‚

sleek thicket
#

i think it's worth worrying because it's really confusing tbh

cinder summit
#

Yea, the terms "layer" and "mask" are especially confusing ... Or group if you call them collision groups

#

When you talk about it you'd probably say "this entity is a member of collision layers A and B"

sleek thicket
#

i'd say "it's on layer A and B"

vestal minnow
#

I'd just go for

struct CollisionLayers {
    groups: LayerMask,
    filters: LayerMask,
}

and maybe change groups to something like memberships/member, but the method names are kind of an issue

#

add_memberships would work I guess

#

a bit long tho

#

Rapier has memberships and filters

#

all roads lead to Rapier

sleek thicket
#

but considering godot/unity, groups would be layers

cinder summit
#

Yea groups and layers are the same thing, that's why that name makes no real sense

sleek thicket
#

and filters would be collision/layer mask

#

if the bitmask will remain called layermask i actually think it'd be funny to make it
layer: LayerMask
mask: LayerMask

cinder summit
#

Maybe interacts_with_colliders_on_at_least_one_matching_layer

sleek thicket
#

collides_if_at_least_one_layer_from_both_group_and_filter_is_a_match

cinder summit
#

But yea memberships and filters seems very clear at least ... And if it matches rapier that makes it easier for people to transition to bevy_xpbd and get access to a vastly superior collision detection library ... sdf_peck ๐Ÿ‘€

vestal minnow
#

I'll probably rename it to memberships and filters then, I agree it's pretty clear at least

sleek thicket
#

when i switched from unity to rapier it was really confusing though

#

if memberships was layers then at least there would be some common ground

vestal minnow
#

I don't think the current groups and masks is much better

#

and filters is a bitmask of layers

#

it's filtering layers

sleek thicket
#

i had an unfair advantage of knowing how bitmasks work so i got extra confused by how complicated it was in source code too

cinder summit
sleek thicket
#

i wonder how people coming from unity would normally react

#

it's probably not an issue for someone learning from scratch though

#

someone learning from scratch in bevy is an issue itself though

vestal minnow
#

I only learned what masks in this context are like a year ago

cinder summit
#

If they're learning from scratch they'll be looking for their puzzle pieces thonk

sleek thicket
#

the introduction to the whole thing using a single layer and raycast is really simple though

vestal minnow
#

masks to me sound almost like the opposite of what they do; irl masks cover things, so it sounds like it's blocking interactions

sleek thicket
#

object A is layer_environment, object B is layer_player
raycast's mask includes layer_environment but not layer_player
object B sends raycast from center of its' collider and doesn't hit itself, and now you have your generic beginner gun

sleek thicket
cinder summit
sleek thicket
#

that's because it's a bitmask

#

which is really cool when you understand the underlying math behind everything

#

In computer science, a mask or bitmask is data that is used for bitwise operations, particularly in a bit field. Using a mask, multiple bits in a byte, nibble, word, etc. can be set either on or off, or inverted from on to off (or vice versa) in a single bitwise operation. An additional use of masking involves predication in vector processing, ...

vestal minnow
#

One issue with the name filters is that the methods add_filters and remove_filters sound confusing

#

If you filter a vec, you're probably removing some items, but here add_filters would add layers to include

cinder summit
#

Just don't make add_filters/remove_filters and let people or/xor/and CollisionLayers.filters ๐Ÿ‘€

vestal minnow
#

We could remove the methods and just let people do collision_layers.filters.add_layers(...) though

#

yep

vestal minnow
#

like or/xor/and

sleek thicket
#

that's actually an interesting idea, teaching people to use bitmasks without abstractions

#

feels like rust somehow

vestal minnow
#

I'd keep the abstractions too though, it'd just be on LayerMask

#

have both as an option

sleek thicket
#

people are lazy and pick the option they don't have to learn though

#

it's a 10 minute topic to learn but everyone usually picks the option that takes no learning at all
and that's probably why JS ecosystem is such a mess

cinder summit
sleek thicket
#

for now*

vestal minnow
sleek thicket
#

i insist on the actual type that is a wrapper for a bitmask to have "mask" in it.

cinder summit
#

Having methods on Layers/LayerMask seems reasonable ... It's just a lot weirder on CollisionLayers

vestal minnow
#

Many people aren't very familiar with working with bitmasks, and forcing them to use them isn't ideal imo

sleek thicket
#

but once you know what it does i think bitwise is simpler

#

you don't have to guess what the abstracted thing does, you just see it directly

ripe cliff
#

Hey there, i just recently started with bevy and am currently trying to match colliders to a "vehicle" i created
While statically, the scaling works, once i start moving the "vehicle" the colliders resize in wonky ways (See image)

any idea where that could be coming from?
i am creating the colliders as follows:
https://github.com/X39/bevy-in-space/blob/master/src/gentity/gltf/pp_collision.rs
Also getting overlap warnings, so is there a way to tell those colliders that they are the "vehicles" "ground"? Or should i make them static and update the position of them myself?
Thanks in advance

cinder summit
vestal minnow
#

yeah true

#

contains_all is much better for that

sleek thicket
vestal minnow
#

If you use the transform scale for the collider's size, the final collider's size will be squared since the collider size (transform scale in your case) is multiplied by transform scale

ripe cliff
#

Will try resetting the transform scale
using it to have an easy way from the blender gltf export to the colliders

trying to change that rn

sleek thicket
#

and child scale is multiplied by parent scale if you use that

ripe cliff
#

No scaling involved anywhere but in those very (blender cube) entities

#

yeah
it was the scaling
Now just having to sync the colliders position with the movement
makes me wonder tho why it did work yesterday without the movement ... as that apparently did no longer work that way today

Anyhow
thanks for the quick help ๐Ÿ™‚

vestal minnow
#

uhh... I think I'll make yet another PR for the layer rework lol

#

it's different enough that the description would change a lot

#

The third PR in this chain now ๐Ÿ˜ค

sleek thicket
#

take your time with it

vestal minnow
#

And this all started from adding a couple of constructors to SpatialQueryFilter ๐Ÿ˜ญ

sleek thicket
#

you can test the actual functionality in between

#

once you're done with it, you probably won't have to touch it ever again

vestal minnow
#

unless we manage to do layers as components eventually

#

but that might not be very viable

sleek thicket
#

it's already kind of a component though

#

the CollisionLayers

#

i think using it in query would be rare enough that it'd be better to just make a tag component

#

although i can definitely see it being useful. it's probably not 0-cost though.

vestal minnow
# sleek thicket it's already kind of a component though

Yes, but I mean having each layer be a marker component and using arbitrary query filters for collision filtering, something like this:

#[derive(Component)]
struct MyLayer;

commands.spawn((
    Collider::ball(0.5),
    MyLayer,
    CollisionFilter::<(MyLayer, Sensor)::new(),
));

The real power here is that you can use any component as a filter, so you could e.g. only detect collisions against sensors. And you probably have lots of marker components in Bevy anyway, so you could reuse those instead of making separate collision layers.

You could also have an arbitrary number of layers instead of "just" 32, and they could be nicely organized in component bundles

#

But the main issues are probably performance and whether or not this is even remotely possible

#

It might require exclusive World access when creating the filters so that you can get component IDs and store those, but even then I'm not sure if it works

#

Maybe some reflect magic but I have no idea how reflection works

sleek thicket
#

yeah, it does make sense but for physics engine performance > utility

#

in unity i was actually doing the reverse of that

#

using layer as a tag component

#

since collider was already there, and accessing layer is easier, cheaper, and safer than trying to get components that might not exist

#

not sure if i should bother replicating it in bevy

vestal minnow
#

For the current layer rework though, the changes I have right now (compared to last time):

  • Renamed groups to memberships and masks to filters
  • Removed all group/mask manipulation methods like add_groups from CollisionLayers
  • Added add, remove and contains_all to LayerMask
    To manipulate layers, you'd now work with the properties directly:
let mut layers = CollisionLayers::new(0b0010, 0b0111);

layers.memberships.add_layers(0b0100); // or
layers.memberships |= 0b0100;

layers.filters.remove_layers(0b0011); // or
layers.filters &= !0b0011;

let has = layers.memberships.contains_all(0b0110); // or
let has = (layers.memberships & 0b0110) == 0;

It's slightly longer than before, but more explicit and maybe more flexible

sleek thicket
#

projectiles have interactions for damageable components and environment, it would make sense to make a match for layer instead of getting tag component... but if i have a tag component anyway then i might as well just use that for everything...

sleek thicket
vestal minnow
#

yeah this seems to be basically identical to rapier's approach

sleek thicket
#

layer+mask are used in godot and unity so they would be more familiar, i'm neutral on this though

#

i'm more concerned about CollisionLayers and LayerMask. and SpatialQueryFilter

vestal minnow
#

can't have layers.layers

sleek thicket
#

why is the first one layers

vestal minnow
#

and CollisionGroups isn't really better

#

since a group is very close to a layer

#

it'd be kinda nice if Bevy had a Layers component or similar, and we'd just have a CollisionFilter or something

sleek thicket
#
let mut collision = CollisionLayers::new(0b0010, 0b0111);

collision.layers.add_layers(0b0100); // or
collision.layers |= 0b0100;

collision.masks.remove_layers(0b0011); // or
collision.masks &= !0b0011;

let has = collision.layers.contains_all(0b0110); // or
let has = (collision.layers & 0b0110) == 0;

copying godot

#

actually

vestal minnow
sleek thicket
#

to have a bitmask marker on objects, similar to name and tag... just like unity...

vestal minnow
#

idk if Bevy would add it as built in

vestal minnow
sleek thicket
#

too much to consider everything in 1 day though

#

is _layers even necessary for bitwise ops, considering it's already inside mask?

vestal minnow
#

no, but if LayerMask has Deref, add clashes with u32::add

#

we could remove Deref too though

sleek thicket
#

i didn't even know ::add is a thing ๐Ÿ˜‚

vestal minnow
#

well Add just has the add method for +

#

operator overloading is cool

sleek thicket
#

you can't overload += and -= for the same reason though, right?

vestal minnow
#

for what reason?

sleek thicket
#

because that's what we use to add and remove

#

just instead of actual add/remove op, it could call bitwise

#

but honestly i think a good reminder of how to use bitwise is still the best

vestal minnow
#

we could overload it, but it might be confusing

#

it would probably break some convention rule Rust has for Add

sleek thicket
#

yeah it just sounds dangerous in general

vestal minnow
#

like mask + mask != 2 * mask

#

(not that adding/multiplying bitmasks like that would make any sense anyway)

peak timber
patent vigil
patent vigil
trail sparrow
#

Please note I've added 'patches' [patch.crates-io]
bevy = { path = "/Users/jpedrick/Development/bevy" }
winit = { path = "/Users/jpedrick/Development/winit-clean" }

vestal minnow
#

Haha, I'm updating it to main right now ๐Ÿ˜…

trail sparrow
#

Ohhh, well, maybe you'll use some of my chanes.

#

You probably noticed WorldQuery is deprecated

vestal minnow
#

ya

#

I have everything working already

#

*almost everything

trail sparrow
#

Nice!

#

I'll just wait then

vestal minnow
#

I'll soon publish a bevy-main branch (and PR), I don't want it on actual main yet

trail sparrow
#

Ok cool, sounds good to me.

vestal minnow
#

One issue was that Glam 0.25 was released, but Nalgbera (used by Parry) doesn't support it yet with its type conversion stuff, so I had to make a PR

trail sparrow
#

FYI, people in #reflection-dev thought you should get glam from bevy. But I don't see anywhere that bevy re-exports glam

#

I saw that

vestal minnow
#

My current bevy-main branch stuff depends on my fork of Nalgebra, and a fork of Parry that depends on that Nalgebra fork...

vestal minnow
#

I can probably remove glam and use bevy_math instead, but I'm not sure how that'd help

#

other than it automatically updating the glam version to match bevy. but there are errors if it doesn't match bevy anyway

cinder summit
vestal minnow
#

yea

cinder summit
trail sparrow
#

I've gotta get going, but I'll try aligning the glam versions in bevy and xpbd and see if that fixes the problem.

vestal minnow
#

I only add glam as a dependency to add features to it, I don't actually import or use it anywhere

#

could do it on bevy_math too

#

*should

trail sparrow
#

Might be nicer to do that

vestal minnow
#

and @cinder summit in case you need main branch Bevy with bevy_xpbd

#

I'll try to implement a bunch of things regarding primitives in separate PRs though, and merge them into that one

#

and later merge it all into main once 0.13 releases

#

I also changed the glam dependency to bevy_math

#

of course CI fails tho

fluid echo
trail sparrow
#

Hi @vestal minnow

This is probably a Rust noob question, but how does this work?

[dependencies]
bevy = { git = "https://github.com/bevyengine/bevy.git", default-features = false }
bevy_math = { git = "https://github.com/bevyengine/bevy.git" }
vestal minnow
#

Getting bevy_math?

trail sparrow
#

Yeah

vestal minnow
#

Cargo looks for a crate called "bevy_math" there

trail sparrow
#

Ok I see

#

Looks like cargo treats git = dependencies differently than path = dependencies

#

Hrmp, the next bevy version is gonna hurt ๐Ÿ˜

#

(Not me, others.)

#

Anyway, I was able to get everything compiled. Thanks @vestal minnow !

surreal kelp
#

I think Colliders currently aren't shared assets between entities, like for example Mesh is. Naively this seems like it could potentially save a good chunk of memory. Is there a reason for not doing this (other than just not having been done)?

vestal minnow
# surreal kelp I think Colliders currently aren't shared assets between entities, like for exam...

Many colliders are significantly smaller memory-wise than meshes, unless using large trimesh colliders, convex hulls or compound colliders. Colliders also currently store the shapes in a SharedShape which stores an Arc<dyn Shape>, so the data itself isn't stored in the component.

I think assets could still be a good fit for colliders though, especially if/when we add collider asset preprocessing for e.g. making colliders out of meshes. So it's probably worth trying out

surreal kelp
#

I'm currently doing a little asset preprocessing after loading a scene but before spawning. Without the asset pipeline, for now, just wanted to have the scene fully ready during the loading state.

vestal minnow
#

Also I'm not sure what the performance impact of having to always get the collider using a handle would be; probably not significant, but I'd expect it to have some extra O(1) cost compared to just having the collider itself as a component

surreal kelp
#

Right. Thanks for the explanation. I love the library so far, having it Bevy native is quite nice.

dull crest
#

hello! Currently I'm trying to use xpbd to be my tetris games' collider, but I've run into a small issue

fn display_events(
    collision_events: Query<(Entity, &CollidingEntities)>,
    mut query: Query<&mut State, With<Block>>,
) {
    for entity in collision_events.iter().flat_map(|x| x.1 .0.iter()) {
        if let Ok(mut p) = query.get_mut(*entity) {
            *p = State::Placed;
        }
    }
}

This code right here stops the blocks from falling as soon as it touching each other(it's flawed I know, but there's a bigger issue)
it suffers from this issue, blocks not falling thru when there's a single point of contact
any ideas on how to solve this?
(here is my block generator)

        commands
            .spawn(TetrisBlockBundle {
                block,
                state: State::Falling,
            })
            .insert(MaterialMesh2dBundle {
                mesh: meshes.add(mesh).into(),
                transform,
                material,
                ..default()
            })
            .insert(collider)
            .insert(Sensor);

(code https://github.com/JustSimplyKyle/tetris-with-bevy)

surreal kelp
vestal minnow
#

not sure what the state of that is

vestal minnow
dull crest
#

hmm how would I make the collision block smaller then?
I believe the transform is coupled together with the tetris block

vestal minnow
#

Why would you need to make the blocks smaller?

#

If you need them to be smaller then you could set the transform scale though

dull crest
vestal minnow
#

Yeah making the collider smaller could work

#

I meant just positioning them in a way where they're slightly apart, but scaling might be easier

#

Could probably use transform.with_scale(Vec3::new(0.99, 1.0, 1.0)), although it feels a bit hacky

cinder summit
#

I think scaling them wouldn't quite work as intended, since it would break the alignment of bigger pieces ๐Ÿค”

vestal minnow
#

yeah, true

vestal minnow
#

If you can, I'd probably position them slightly apart on the X axis

surreal kelp
#

If you just scale the X and controls only allow moving a square at a time, this should work fine, I think.

surreal kelp
#

I donโ€™t know if thereโ€™s a nicer way to handle this with the shape type, though.

vestal minnow
#

Yeah we'd need Parry to use a separate shape type for the shapes in compound colliders

vestal minnow
#

(issue 404, lol)

#

hm

#

It looks like the PR to support self-referential types might make it to 0.13?

#

See latest messages

#

If so, it could maybe be Reflect-able for next release

surreal kelp
#

Itโ€™s unfortunate it uses a self referential type here, as that makes it require boxing, where it could possibly be self-contained otherwise.

cinder summit
vestal minnow
#

Or use bevy_peck where compound shapes aren't a thing yet

#

Neither is proper collision detection, but...

cinder summit
#

Port your whole project to sdf_peck cause it has no self referential types

#

Only to realize it doesn't derive Reflect on any of its types

dull crest
sleek thicket
#

are you trying to make jelly tetris or something

ripe cliff
#

Assuming I wanted to create a 3d spaceship i can walk inside and "drive"
What would the process be to get the colliders working for this?
I currently struggle with the kinetic colliders not moving with the parented spaceship eg. And, additionally, the kinetic colliders report collisions with each other all the time

sleek thicket
dull crest
nova relic
twin granite
#

Hi !
I wanted to know how to get a camera that follows a character (RigidBody::Kinematic), if possible in a Smooth way with linear interpolation.
I tried to synchronize the camera transform with the character transform, which is subject to physics (RigidBody::Kinematic).
I've tried running a synchronization system for these two transforms after PhysicsSet::Sync, but I still seem to have a problem with the GlobalTransform.
I know it's possible to make my camera a child of my character, but I couldn't make the camera smooth it seems, otherwise I'd be happy to hear!

twin granite
vestal minnow
sleek thicket
sleek thicket
vestal minnow
#

an example showing the correct system ordering and explain why it's needed

#

could also be a part of one of the character controller examples, but a more focused and discoverable one might be useful

#

also it is in the docs FAQ already, just not released to docs.rs

sleek thicket
#

examples are awesome in general, they're like both a test and documentation at the same time

#

i think bevy will need something like cinemachine in the long term though

sleek thicket
#

maybe also add a better layers example?
like that spinning raycaster from before, just add 2 types of walls on different layers, only one included in raycaster's mask
plug in the char controller, player has both layers included and can't leave

fiery mortar
#

hi, is there a way to disable a collider?

sleek thicket
fair fractal
#

Or you can add a sensor component

sleek thicket
#

@vestal minnow i just realized the bikeshedding can be mostly solved by adding alias matching unity and godot

#

so memberships alias layers and filter alias masks

vestal minnow
#

yeah doc aliases are good to add here

fair fractal
#

I don't suppose there's a way to have a collider show up in spatial queries without adding a rigid body component to it?

vestal minnow
#

Do they not show up? I think it should work

fair fractal
#

๐Ÿค” don't seem to be

vestal minnow
#

Make sure it has a transform, that might be required

fair fractal
#

interesting. All I'm doing is adding and not adding a rigidbody, and it seems like they only show up when it has a rigidbody

#

I'm using a aabb_intersections_with_aabb query though

#

doesn't seem like it should make a difference

vestal minnow
#

Yeah it probably shouldn't

torn hedge
#

where would be the correct place to do manual translation changes to a physicsobject?

i'm trying to make my player stick to the wall, and that itself works. but as seen in the video it's quite jittery :)

torn hedge
#

The other side? You mean the "inside" of the curve?

#

There its a bit Harder to Tell, but i think so.
Currently not on my PC so i can't check

torn hedge
vestal minnow
#

also

#

For that, you need to use Position instead of Transform because the engine internals use Position

torn hedge
#

exactly what i needed, thanks! looks quite good now :D

sleek thicket
ionic gale
#

Is this blazingly fast?

vestal minnow
# ionic gale Is this *blazingly fast*?

Not necessarily, Rapier is likely to be more performant. The main focus so far has been on "Bevy nativeness" and getting closer to feature parity with more mature engines

#

Optimizations are planned though

ionic gale
vestal minnow
#

bevy_xpbd doesn't have joint motors/actuators just yet, and you might need those?

#

So bevy_rapier might be better for that use case for now

sleek thicket
#

yet.

wraith aspen
#

If a ShapeCaster and a Collider are part of the same entity, will the ShapeCaster detect the Collider?

vestal minnow
#

By default, it should not detect it iirc, but there should be some configuration option like ignore_self on the caster

wraith aspen
#

ah wait i needed a .with_max_time_of_impact(0.2)

fair fractal
# ionic gale I will need that.

on the flipside, from an engineering perspective, xpbd is much cooler than using a traditional position based dynamics physics engine

trail sparrow
#

So, I'd like to 'edge detect' collisions.

would: (contact.during_current_frame || contact.during_current_substep) && !contact.during_previous_frame do the trick?

fair fractal
#

what do you mean by edge detect exactly?

#

that should do the trick if you just want to detect if it was in contact for either the current or previous frame

trail sparrow
#

I want to know if a collision just happened so I can play a sound

fair fractal
#

oh like the first frame a collision happens, right, that makes sense

trail sparrow
#

Yeah exactly

fair fractal
#

I think there is a collision event for when something initially comes into contact, lemme check real quick

#

your approach would also probably work though

trail sparrow
#

Ooof, my logic โ˜๏ธ kinda works, but I have a bunch of small blocks that make up a single "wall" so I get a bunch of events

#

That event is much better than what I'm doing by looping over all the contacts

#

I'm thinking though, I'd kind of need to know the delta-v or force from the collision

fair fractal
#

yeah the collision event doesn't provide much info unfortunately

trail sparrow
#

Maybe the contact manifold?

#

Or is it possible to do a world query to get the force on the entities?

#

Do you think I could compare PreSolveLinearVelocity with LinearVelocity?

fair fractal
#

I'm confused because I could have sworn that the relative velocity was exposed in the Contact

#

but maybe that was with with rapier ๐Ÿค”

trail sparrow
#

Idk, I haven't looked at rapier yet

fair fractal
#

Either way, I don't see it anywhere in the xpbd docs

trail sparrow
#

But, relative velocity would be easy enough to figure out

#

Just v1 - v2, right?

fair fractal
#

yeah, I guess so

#

you might just want to have a system that runs right before PhysicsSet::Prepare, record the velocity, and then have another system run immediately after PhysicsSet::Sync and calculate the impulse from the difference in velocity and/or angular velocity

trail sparrow
#

Right, well, let me see if pre_solve_linear_velocity does that first

fair fractal
#

I imagine it probably will, but it might be the PreSolveVelocity for each substep, so it might get funky if there is multiple contacts within the same step

fair fractal
#

it's cooler!

ionic gale
#

Are you saying that motion is relative?

fair fractal
#

what?

#

extended position based dynamics is just a newer way of simulating physics than traditional physics engines

fair fractal
#

more accurate collisions is the main advantage in my opinion. The simulation is also inherently much more stable

#

but I'm no expert

#

more accurate collision resolution, to be more precise

ionic gale
#

And faster?

fair fractal
ionic gale
fair fractal
#

but motors themselves aren't implemented in this bevy crate, so you will have to do it yourself, which is what jondolf was saying before

#

so there are joints, but not motors.

#

and it is arguably much easier to implement custom joints and behaviors in bevy_xpbd than rapier

fair fractal
# ionic gale And faster?

just to be super clear, I'm talking about extended position based dynmics (xpbd) in general here. Not specifically bevy_xpbd. bevy_xpbd implements xpbd into a realtime physics engine that can be used in games. but over all, it is less feature complete, a bit more buggy, and definitely not as fast (in most cases) as rapier physics

fair fractal
#

is there a way to cast a shape with shape_hits without it sorting the hits by time of impact? or ๐Ÿค” it looks like it uses best first traversal so it's just automatically sorted. Now I've gone and confused myself here. I may be shape casting over very large distances and was wondering if I could mitigate the overhead from the.. sorting? but I'm totally unfamilira with how best first traversal works in a bvh so maybe it's something I just shouldn't be concerned about?

trail sparrow
#

Ok, so... it seems like pre_solve_linear_velocity is indeed not the best thing to compare with.

ionic gale
#

So is xpbd in general very fast?

sleek thicket
#

for what it can do, yes

#

i'd assume that for engineering game it'd be a better choice in the long run

wraith aspen
#

I want to use raycasts to place quads on walls so they look like its on the wall (like decals). How do I use the normal vector of RayHitData to rotate my quad so it looks like its on the wall?

sleek thicket
fiery mortar
#

look_to i mean

wraith aspen
sleek thicket
#

no

#

but yeah it won't work

#

you need to use hit normal + hit point

fiery mortar
wraith aspen
sleek thicket
#

it looks at worldspace position

#

quaternion is better here

wraith aspen
#

yeah why not just set the rotation directly

pulsar bone
#

Quat doesn't have a helper method for this.

sleek thicket
#

it doesn't need one

pulsar bone
#

transform.look_to(hit.normal, Vec3::Y) will do the trick. (Note: look_to, not look_at)

sleek thicket
#

i keep forgetting how quaternions work though, i thought it was just a simple multiplication but quick google basically says this
transform.rotation = Quat::from_rotation_arc(Vec3::Y, normal);

pulsar bone
#

^ Should be Vec3::Z or Vec3::NEG_Z

sleek thicket
#

it should be whatever fits

#

i use Z as up and Y as forward

wraith aspen
#

it makes the quads not appear for some reason

pulsar bone
wraith aspen
#

nvm Quat::from_rotation_arc works

sleek thicket
#

then Z fits ๐Ÿ˜…

#

i really hate the coordinate bullshit

#

i wonder how hard would it be to make them configurable

atomic wigeon
#

Is there a way to make CollidingEntities only include colliders that correctly intersect with CollisionLayers between the two entities?

fair fractal
#

how do collision masks work when there are conflicts? for example:
objectA has a collision layer CollisionLayer::new([LayerA], [LayerA, LayerB]) and objectB has CollisionLayer::new([LayerB], [LayerB]).
do objectA and objectB collide?

vestal minnow
#

Both have to be compatible, i.e. B is in masks of A, and A is in masks of B

fair fractal
#

ah ok, I see

cinder summit
#

Yea the normal thing to do here for entities that don't care about what they're touching is just do:

CollisionLayers::all_masks::<CollisionLayer>()
  .add_group(CollisionLayer::WhateverGroup),
vestal minnow
#

unless I'm misunderstanding what you mean

trail sparrow
#

Suppose I have a Rogue like game and I want to determine if a monster can see the character, or if a lantern the character is holding can illuminate a room. I could cast many rays, but is there another way to do that with a "circle"?

#

Shape casting doesn't seem quite correct

cinder summit
#

You mean you want to see if something is visible in a circle?

trail sparrow
#

Yeah, if it's blocked by a wall

#

I guess I can search for everything in a circle and send a ray to each one

cinder summit
#

The way I do this is first do a shape intersection with a circle, then anything that could be a valid hits gets a raycast to follow up, which filters to only see things that can block it

trail sparrow
#

Right, makes sense

#

Would be cool if XPBD integrated that in SpatialQuery

cinder summit
#

It's not ideal in some cases however, something might be mostly unblocked, except at the place where you do the raycast ... So if you need it to be very accurate you might have to do multiple raycasts if one fails

trail sparrow
#

For my purpose I think it's ok

cinder summit
trail sparrow
#

Easy enough to check the translation of every entity, but maybe some kind of grid buckets

trail sparrow
#

Oh nice

#

Do I actually need to spawn the collider?

vestal minnow
#

no

#

you can pass the collider to the method

trail sparrow
#

Very nice. Thanks

#

BTW, I love bevy xpbd @vestal minnow

#

I was able to solve my problem with collisions by just saving LinearVelocity before the physics phase, (v1-v2).length() ๐Ÿ™Œ๐Ÿป

#

One thing I keep thinking about is "particle charge" or reacting to an electric or magnetic field.

#

IDK if that's of any interest to you to add to XPBD

vestal minnow
#

Probably not as built-in, but could be a good 3rd party crate

trail sparrow
#

To do it accurately it would probably involve doing some FEM grid

#

Idk if accuracy is that important for games, but it does make designing the game easier.

upbeat abyss
#

Can a collider be a child of another collider? I donโ€™t want their physics behaviors to interact, I just want the convenience of transform propagations from the parent/child hierarchy.

#

Specifically, a player in my game has a movement collider with velocity etc. I want a separate hit box collider as a child entity. Any gotchas I should be aware of?

fiery mortar
vestal minnow
#

In 0.3 and above

#

Although 0.3 can have some instability with actual child collider collisions

#

but that should be fixed in 0.4

fiery mortar
#

Child and parent don't collide with each other by default?

vestal minnow
#

No, they shouldn't collide by default, they're treated kinda like a compound collider

#

Same as Rapier I think

#

or Godot

#

almost anything (that I know of) that supports multiple colliders as the children of a rigid body

fair fractal
#

seems slightly redundant that I have to add another component to my query to get the center of mass when it seems like it should be able to be accessed when the impulse is evaluated in the velocity solver

#

Oh I see now, it converts the impulse at point to a linear impulse with torque immediately at the function call

warped elk
#

Is there an example on doing mouse picking in xpbd (2d)?

Tried attaching a raycaster to the mouse and setting the direction to Vec2::ZERO, but its not working

vestal minnow
warped elk
vestal minnow
#

It won't do anything because a direction of zero isn't really a direction

#

It needs to be non-zero

#

Raycasting algorithms need a valid direction

#

Or I could maybe fall back to a point intersection test, but I'm not sure if that would qualify as raycasting anymore

warped elk
#

True, maybe add an assert or something for idiots like me passing in a zero-direction ๐Ÿ˜†

vestal minnow
#

Yeah, that could be good to add ๐Ÿ˜„

cinder summit
#

Why add an assertion when you can just change it in the next bevy_xpbd release to use RayXd or RayCastXd? ๐Ÿค”

#

Or in the worst case just make that one param DirectionXd

vestal minnow
#

My plan is to probably use the ray structs, yeah

#

giving a ray to a shapecast might be a bit weird but it's just a shape travelling along the ray so I guess it'd still make sense

cinder summit
#

This is the function signature I have now in sdf_peck

    pub fn shape_hits<'a>(
        &'a mut self,
        ray: RayCast3d,
        shape: &'a SdfCollider,
        rotation: Quat,
        _ignore_origin_penetration: bool, // TODO
        filter: &'a SpatialQueryFilter,
    ) -> impl Iterator<Item = ShapeHitData> + 'a {

Tho I'm not sure how much sense RayCastXd makes if you're not using a BVH that uses bevy_math's bounding

#

I still want to improve things a bit so it takes a primitive directly instead of SdfCollider tho ๐Ÿค”

vestal minnow
#

yeah you can probably "just" impl From<MyPrimitive> for SdfCollider and pass in an impl Into<SdfCollider>, that's my plan for bevy_xpbd spatial queries

#

except not with SdfCollider ๐Ÿ˜‚

#

...yet

#

although you have a lifetime there

cinder summit
#

That lifetime is just because impl Trait in return position has some cursed issues ๐Ÿ˜‚

cinder summit
vestal minnow
#

yeah, makes sense

#

I could maybe try something similar for bevy_peck

#

or I do already do that kinda

cinder summit
#

At the same time it should also probably be a standalone thing ... For non bevy users ... Heck even for non-rust users ... There's no decently documented SDF collision implementation anywhere ferris_sob

vestal minnow
#

Yeah I do want to try the idea of somehow mixing SDF collisions and GJK/EPA collisions efficiently, but that probably doesn't need peck_sdf to depend on bevy_peck, just the other way around

#

first I just need to get normal collisions working reliably :P

#

there are so many things I want to work on lol, like now I want to implement a soft TGS solver as shown in the Box2D blog (and Rapier basically has that now I think)

#

(and maybe bepu too?)

#

I should also really try moving the narrow phase out of the substepping loop

#

for some reason I've thought that it wouldn't work but it should afaik

vestal minnow
#

On the other hand what is interesting is the idea that we can do sub-stepping without updating the broad-phase or recomputing the contact points. It turns out with a little bit of vector algebra we can update contact points by storing them in local coordinates as this figure shows.

We can track the contact point in both bodies across sub-steps. With that information we can update the separation value and push the bodies apart in response. Maintaining the same contact anchor points across sub-steps is approximate, but it turns out to work well. It would be very expensive to recompute the contact points every sub-step, so contact point updating has made sub-stepping a viable approach. Unfortunately this idea is not mentioned in the small steps paper.

#
cinder summit
#

Huh ... That sounds like magic

#

It would make tunneling as bad as no substepping tho right?

vestal minnow
#

yeah... I think so

#

Box2D has CCD by default I think so it doesn't need to care

#

so we'd probably need CCD too

#

or we could do something where it does run the narrow phase again, but only if there hasn't been a contact in a prior substep yet

#

that would probably address it to some extent at least

dreamy viper
#

Does it make sense to have a 1D collider? x-min = x-max?

vestal minnow
#

Do you mean having e.g. a 1D line as a collider in 2D, or literally collision detection in 1D?

#

I think 1D collisions would just be checking if the extents of two objects overlap along a singular axis

cinder summit
#

With a sign as normal thonk

vestal minnow
#

scalar value as contact point

#

Rotation as... sign? For flipping?

dreamy viper
#

having a 1D line as a collider in 2D

cinder summit
#

As in it collides only based on X or Y positions?

dreamy viper
#

so it's not real physics, but maybe i can use xpbd's contact detection

#

otherwise i'll re-implement it myself using parry (it looks like glam is pretty bare bones)

vestal minnow
#

well, there are segment and polyline colliders

cinder summit
#

Hmmm, having it actually check for it being parallel might be fairly hard ๐Ÿค”

full tundra
#

๐Ÿ‘‹ hey folks, I apologise in advance if this is a daft question but i'm used to unity where in the editor I can see a visualisation of the collider shapes and use this to sanity test what's going on with colliders. I'm struggling to find a way to visualise xpbd colliders and understand how everything fits together.

For reference, my current learning project is a flappy bird clone and the kenny art pack has some lopsided-triangle sprites. I can see that xpbd has a method to create a triangle collider from some vectors, but without having visual feedback to know where everything's at, i'm struggling to think of efficient ways to construct the collider.

Thank you in advance for any help!

full tundra
warped elk
#

Does a linear velocity require a rigid body? E.g. I want to make a projectile which has a collider (just to check for collision in code) and uses the same velocity system, but which isnt a body (e.g. can travel through other rigid bodies)

cinder summit
#

You mean it's a kinematic body?

#

If it's not even that I think you'd have to integrate the velocity on your own (which isn't too unreasonable, projectiles tend to travel fast enough that collision detection is pointless, so you need to shapecast from A to B every tick)

warped elk
#

Kinematic bodies interact with other bodies, no?

cinder summit
#

They can apply forces to dynamic bodies, which I guess is interacting with other bodies yes

vestal minnow
#

You can make it a sensor collider with Sensor though

#

That way it'll still go through other bodies

warped elk
#

Now that I think about it, I dont even need a collider, probably cheaper doing point_intersection each frame

cinder summit
#

Moving your projectiles after doing a ray/shapecast is pretty common in games. It runs a lot better than using CCD-enabled colliders

#

bevy_xpbd also doesn't have CCD so that would be difficult too ๐Ÿ˜‚

warped elk
#

Ok so, kinematic body without any collider would fit my criteria if I have understood this correctly

cinder summit
#

You don't need it to be a kinematic body even. You can just use the existing LinearVelocity component, but use it in your own system

#

Or use a different component if it's more practical (I have a custom one that also holds distance traveled and max distance)

warped elk
#

If I want to see redundant code, I will go to my job ๐Ÿ˜†

cinder summit
#

I don't think position += linearvelocity * delta; is an amount of redudant code you need to worry about ๐Ÿ˜‚

dreamy viper
#

So i'm still not sure; would xpbd be helpful to me in the 'snake' example i linked above?

Here's my current understanding:

  • I would use Colliders but no RigidBodies, and use only the collision detection
  • bevy_xpbd is still helpful compared with raw parry for collision detection because it contains that internal QBVH structure to accelerate spatial queries. But should I rely on xpbd's collisions detection or just run the ray-casts and spatial queries myself? (in which case the collision-detection would be wasted)
  • I might need different CollisionLayers for SnakeHeads vs SnakeTail to distinguish between head collision (perpendical) vs tail friction (parallel)
  • what happens for a 'parallel' contact? (seems like there would be an infinite number of points on the contact manifold, no?)
warped elk
#

Is it possible to conditionally run PhysicsDebugPlugin ? E.g. toggle by pressing key

fair fractal
fair fractal
fair fractal
vestal minnow
#

Currently the broad phase uses sweep and prune instead of a BVH

fair fractal
#

Oh interesting

#

Is that due to some limitation?

vestal minnow
#

I haven't tried a shared BVH, but afaik it's pretty common to have separate ones (e.g. Rapier has one specifically for the query pipeline)

#

The broad phase uses a basic sweep and prune mainly because it's simpler, I intend to use a more optimized solution at some point

#

(Rapier's broad phase is also "Hierarchical SAP", a combination of a multi-layer spatial hash and sweep and prune)

fair fractal
#

So does this mean that I should be worried about making too many spatial queries per frame? Because honestly in my game there a probably much more spatial queries than rigid bodies per frame. One shape cast per projectile

#

It's probably still fine

#

I've only ever used SAP for my own collision optimizations and haven't had too many performance issues in the past lol

vestal minnow
#

so yeah, it should be fine

fair fractal
#

Oh wow, so spatial queries are even more optimized, nice!

vestal minnow
#

it just uses Parry's Qbvh, the core spatial query logic is almost identical to rapier/bevy_rapier

fair fractal
#

Orrr you're saying the SAP only actually happens once per frame, I see

cinder summit
#

With how bevy_xpbd is set up the only real consideration for spatial queries would be "If I don't need any, I don't need to construct a BVH every frame"

#

And ofc you want to be careful with casts against trimeshes or shapecasts with complex colliders, but that's about the same in every physics engine I think ๐Ÿค”

dreamy viper
#

@fair fractal so you're saying i should still use xpbd's collision events?

fair fractal
#

If your entities don't have rigid bodies your only choice is to use spatial queries

#

Although I still haven't gotten spatial queries to work without rigid bodies ๐Ÿค”. But I know they're supposed to

cinder summit
fair fractal
#

Ah, well. Nevermind then

dreamy viper
#

Really? the docs say "Colliders on their own only detect contacts and generate collision events. To make colliders apply contact forces, they have to be attached to rigid bodies:" which suggests that Collision events can be emitted even without rigid bodies

#

ah, didn't see nisevoid's answer

#

so the collision detection internally uses spatial queries + adds some rigid-bodies-related stuff to compute the 'force' of contact?

vestal minnow
#

XPBD also doesn't really use contact forces since it's position-based

#

And other simulation methods typically use impulses

dreamy viper
#

ok thanks, i'll start with spatial queries then

dreamy viper
#

What do i have the spatial queries plugin working?

  • Does it use Position/Rotation under the hood, in which case I need SyncPlugin?
  • do i need anything from PreparePlugin ?
vestal minnow
#

In the next release there might be a ColliderBackendPlugin that handles all setup stuff related to colliders though

#

so you would probably only need that in 0.4

#

(and SpatialQueryPlugin)

dreamy viper
#

I'm creating my own collider from Polyline, and using SpatialQuery for ray-casts.
I don't use Transform at all; so maybe syncplugin is not needed?

vestal minnow
#

Yeah, in that case it might not be necessary

dreamy viper
#

In PreparePlugin, it sounds like I only need ColliderAabb? is that used by SpatialQueries?

vestal minnow
#

I'll check

vestal minnow
dreamy viper
#

it appears a little bit in intersections, but i think i might only need raycasts

#

SG! Let me try with only SpatialQueryPlugin, i'll let you know!

vestal minnow
#

all you need is Position, Rotation, and Collider

#

I think

dreamy viper
#

Hm it does look like I need Position/Rotation... i'm not too sure what position/rotation to give for a Polyline.. Looks like it's used internally to create an Isometry, so maybe I can just add default components