#Avian Physics
1 messages ยท Page 10 of 1
and it also doesn't randomly explode unlike the CircleCollider version
I'll fix it tomorrow, need to sleep rn
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
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,
}
}
}```
Looks like this was fixed. The info log is the culprit https://github.com/gfx-rs/wgpu/commit/039660ec8536de91d5e32466bc17953e5c586fed
New q: do CollidingEntities include entities that aren't "interactable" for their collision group / mask?
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?
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 ๐ค
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
I think a collider hierarchy should probably start with RigidBody or Sensor at least. And ofc only ones that actually have children
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
It's relative to the rigid body
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
Isn't some propagation also needed to get the position of the top-level of the rigid body?
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
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
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
The answer is always ๐
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
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.
ah i see, should have checked github issues first. my bad. thanks though!
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
i could have a try
This is the system in question (and same for shapecasters)
https://github.com/Jondolf/bevy_xpbd/blob/0776176b972fdfb388ccd8567a9d0694f68474be/src/plugins/spatial_query/mod.rs#L246
Not sure tbh, but a lot of cases where people use hierarchies now could be removed with relations I think. Hierarchies being much more common than necessary would probably be a big part of the reason it's slow ๐ค
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
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
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
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 ๐ค
that reminds me that we also need to try the asset preprocessing thing with running convex decomposition in advance
for static scenes
Yea that would be useful, tho I'm not sure if any work has even be done yet on preprocessing scenes
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 ๐)
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
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
i created a pull request: https://github.com/Jondolf/bevy_xpbd/pull/310
Thanks! I'll try to give it a review later today
yeah, no stress! Hope the code is good enough. feel free to give feedback and criticize it :)
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
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
no built-in yet
okay, thanks, i'll use bevy_xpbd_2d_interp for now then
are you making the camera follow the body?
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
yeah just wanted to make sure you don't have this issue
https://github.com/Jondolf/bevy_xpbd/issues/211
which requires specific system ordering for camera following
ah okay. yes its a different issue, i just want a thing to move smoothly at 160fps
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
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
yep
im not after any level of accuracy beyond 60Hz
thanks for the rapid response by the way, much appreciated ๐
Even chasing the accuracy isn't always the right call. There's a talk about rocket league where they mention regretting going with 120Hz just to "fix" some inconsistencies at 60Hz
I would guess that this is a side-effect of using GlobalTransform instead of Position/Rotation in the raycaster position update. GlobalTransform is updated later in the schedule, so it might be lagging one frame behind
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
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
@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
Porting the SDF colliders should hopefully be straightforward
Currently it does require implementing ScalableCollider, but you could just make it do nothing lol
@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),
}
}
Sure, does this look fine?
https://github.com/Jondolf/bevy_xpbd/pull/312
also I tried making some of the methods const but couldn't find a nice way to make a const HashSet
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
i don't think the problem is in using GlobalTransform. I added a RigidBody to the ParentEntity, as you can see with the debug view. and as i understand, it should now use Position and Rotation instead of GlobalTransform.
But it still lags behind, even the ridigbody debug overlay. but the entity itself (the little cube) doesnt.
with makes a lot more sense when chaining ... bitmask definitely seems better than mask_bits tho ๐ค
I can test it after I finish my sdf rewrite on bevy_math main (the bvh is already done)
In from_mask_bits the "mask" is intended to mean "collision masks", not just bitmask. It's a bitmask for collision masks
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
We could probably rename collision masks to something else though to avoid confusion with bitmasks (although the representation is a bitmask)
I originally went for Godot's naming, it calls them collision masks iirc
I think Rapier calls them interaction groups
For what is worth, I found group and mask pretty obvious names, but I do come from Godot ๐คทโโ๏ธ
It's the bits that makes it less obvious ๐
Pretty sure if we had better const in rust we wouldn't even need that
with_masks_from_bits -> with_masks_from_bitmask then ?
Definitely sounds more reasonable ... Makes the name more clear in two ways ๐ค
you can see that the only parameter is entities
and once you decide between layer and bit masks, you basically only need to know only 4 functions, so i don't think there's a need to be completely descriptive, especially since doc can explain it further
and chaining when creating new mask feels wrong considering that you only have 3 options
We will probably add more options though
Like flags for rigid body type and whether a collider is a sensor
then it makes sense
And a custom predicate would be nice, although I think there'd be lifetime issues
(when used with RayCaster/ShapeCaster)
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
If you have no new() how would you start the chain?
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
layermask feels a bit weird to me... it's still a bitmask, but it's just abstracted away via PhysicsLayer
yeah but that's basically what unity does
you basically just set it up in editor in a dropdown enum/bitmask
it'd probably be with_layer_mask at least since it's two words and not layermask
bitmask is one word tho
typically
bitmask is always written as 1 word so the same thing makes sense for layermask, yeah
Because bitmask is pretty well established as 1 word
yeah layermask isn't very established
roll a die
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 ๐ค
yep
If mask isn't clear, collision mask or collider mask might make more sense
wait, wouldn't that actually work for without
Wasn't there some other mask component too, for the solver?
from_entity_mask
with_entity_mask
entity_mask sounds pretty spooky 
๐ค nvm i still like without more
"Please give me all collisions with entities that have bits 3 and 7 set on their generation"
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
i'd prefer if you didn't make it any more complicated ๐
it'd reduce the number of methods in public API
It would be simpler to use ... The weird iterator signature always looks kind of confusing ๐ค
and make names nicer
Also making it with_collision_masks might be more clear ... Especially if we add other masks later
from_masks and with_masks
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
Can't wait to have CollisionLayers, SolverLayers, ConstraintLayers, etc ๐
I'd like to handle layers via ECS filters ideally
With the approach Jondolf mentioned that would work by just passing it to with_masks
Make every layer an entity, then use relations 
Joints as relations would be nice
Even collision data in relations could be kinda nice but probably not efficient, idk
Constraint graphs via relations
If we take it to the logical conclusion .... Collisions as ๐
You could add arbitrary data to collisions by just adding components... would be really nice for queries and modularity
Hmmm, there wouldn't happen to be some secret branch of bevy_xpbd with bounding sphere support, right? ๐ค
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
Guess I'll have to constraint testing that part of the bevy_math changes to BVH-related operations then 
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
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
you can do both ๐คทโโ๏ธ
wdym both?
old and add_groups
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
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
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
will it still work with const?
yes
then it's fine
actually on that point
wouldn't making from_bits for queryfilter allow const queryfilter
or I guess new doesn't, but you can construct it manually, or I can keep from_bits too
You can make const Layers, but not all CollisionLayers methods are const (which was also the case before)
new wasn't const before either
in that case i'll be able to move some of the repetitive filters to a single place
The excluded entities HashSet is the issue, I couldn't find a nice way to make const HashSets
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?
No?
ok then i just realized why the layermask was confusing
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
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
you'd just implement that manually with a system
yeah but it's something that feels like it could be streamlined
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
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?
Not yet
Yeah spawning things if there are no intersections should be doable
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
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...
You can do intersection tests with SpatialQuery
for a given shape and position
if there's an intersection, just fall back to something else
but it's not in the same frame as spawn, can't something go wrong there?
if something happens to move there before the spawn command has been applied, then sure
but that's probably pretty rare
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
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
- check for intersection (before physics)
- if no intersection, spawn entity
apply_deferred- physics
For SpatialQueryFilter, would these constructors be fine?
from_collision_masksandwith_collision_masksfrom_excluded_entitiesandwith_excluded_entities
I'd also probably be fine with removing_collisionand/or_entities, so that it'd be e.g.from_masksandwith_excluded
I agree without_entities is really nice though...
consistency is probably more important still
i vote for from_masks and with_masks
or from_mask and with_mask
or from_layers and with_layers
for filter it's a single bitmask though, for collisionlayers it's 2 masks
for CollisionLayers it's 2 bitmasks, but 1 set of collision masks and 1 set of collision groups
(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
that needs to be written down in docs just so people know how much thought was put into naming
bikeshedding is 90% of the work in software development lol
meanwhile Parry could really use some bikeshedding with its NonlinearTOICompositeShapeShapeBestFirstVisitor
that's just savage
oh PointCompositeShapeProjWithFeatureBestFirstVisitor is better
alongside PointCompositeShapeProjWithLocationBestFirstVisitor
i didn't check on progress for a while now, how's replacing parry coming along?
whoa RayCompositeShapeToiAndNormalBestFirstVisitor, haven't seen that one before
decently
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
if you get around to doing that, can you make a tutorial similar to https://catlikecoding.com/unity/tutorials/movement/ ?
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
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
specifically, I need to do proper impulse-based physics, implement simulation islands, do more optimization things, handle CCD...
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...
@sleek thicket https://github.com/Jondolf/bevy_xpbd/pull/313
Change CollisionLayers::groups_bits() and CollisionLayers::masks_bits() to layers.groups.0 and layers.masks.0
Where's the Deref? ๐
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
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 ๐
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?
woops the media was corrupted. this one shoult work.
it looks like this might be the same issue? is there an easy fix for to this?
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
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?
are you sure it's actually tanking performance? if it's in fixed update and your fixed update is only running 32 times per second, the physics engine is only running at 32 steps per second, which means that the physics objects will look like they are moving at 32 frames per second. this doesn't mean it's running slower, it's just running less frequently
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
Yeah, my player look system is in Update and it slows that down too
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
This didn't seem to fix it
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
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
I'll try to make a minimal repro
You can disable sleeping for now, like you're doing
It can also be disabled globally by disabling the SleepingPlugin or by making the SleepingThreshold resource negative
I'm pretty sure newtypes in Rust are a zero-cost abstraction
Layers is just a wrapper over u32
Pretty sure the newtypes don't even actually exist in the binary
There's a reason we don't have runtime reflection in rust
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
Yea I think newtypes can break some optimizations like Option<NonZeroX>, but converting between u32 and NewType(u32) shouldn't have any cost
yeah
It's a different story if the types actually have different representations tho, like Vec3 vs Vec3A
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?
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
Makes sense, thanks!
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
right, i forgot rust was made by wizards
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
yeah that post is probably what I was referring to with this
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.
yeah I think LayerMask is a better name than Layers, I'll change it
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?
this is Godot logic (see collision_mask)
https://docs.godotengine.org/en/3.1/classes/class_raycast.html
collision mask bit...
vs collision layer
i think mask bit is more descriptive, but layer just feels more natural because i'm from unity
It's mask because of how CollisionLayers properties are
groupsdescribes which layers an entity belongs tomasksdescribes which layers an entity interacts with
The collision masks inSpatialQueryFilterare basically likemasks, i.e. the layers that a raycast/shapecast can detect
In game development, you often need to know when two objects in the game intersect or come into contact. This is known as collision detection. When a collision is detected, you typically want something to happen. This...
found godot counterpart
so godot calls it collision_layer, and the collision_mask is made from collision_layers
collision_layer is just our groups
yep, i'm still reading
so collision mask is the matrix
and layer is mask
๐ฅฒ
trying to find unreal counterpart
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)
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
that's just confusing lol, would you call "Environment" an object type?
I kinda like filters
https://docs.unrealengine.com/5.0/en-US/collision-in-unreal-engine---overview/
in example it's "WorldDynamic" so i guess environment is just "WorldStatic"
isn't it technically a matrix though
I can't visualize it as a matrix but maybe
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
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
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
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
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
ooh safety margin seems like a much better name for our weird prediction_distance
yeah i noticed that too but i'm not even sure if it's the same thing, is prediction_distance on every object?
it's the same for every collider currently
well, margin is still a better name
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
it just makes more sense from a user perspective
but yeah I renamed Layers to LayerMask for now
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?
(with bitmasks, assuming layer 1 is the first layer)
A: CollisionLayers::new(0b01, 0b10)
B: CollisionLayers::new(0b10, 0)
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
I think there won't be a collision because B can't collide with A
Both need to match
Collisions aren't one-sided
yeah, that's exactly my point
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.
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
i'll need to test it more to see if it's even needed
it feels like both ways have their shortcomings
yeah
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?
No
It's custom
Originally inspired by the heron crate (wrapper over bevy_rapier)
good, i just thought that rewriting parry might affect it
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
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
yeah you should be able to use it like Unity, but you can also do more things
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
Can confirm, bevy_xpbd works mostly as normal with sdf collisions
@cinder summit got any opinions on the layer/mask naming mess?
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 
what about this? #1124043933886976171 message
Yea, groups/filters sounds nice ๐ค
i.e. replace "collision masks" with "collision filters" in CollisionLayers
i think what's inside collisionlayers doesn't matter as much as collisionlayers and layermask themselves
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
Godot also has this absolute moronic mess
Those checkboxes on Area3D are just duplicate behavior of clearing the masks 
maybe that's because of something going on in the background
That sounds very error prone ... groups/filters makes it clear what you're trying to do
the way you make new collisionlayers is exact same though
I'd definitely keep the naming explicit
i think it'll still have to be explicit for the editor
You mean cause it's ::new(group, filter)?
I like filter for being like Rust's filter (although not a callback)
if it works the same for raycast and collisions then it makes sense
for spatial query filters it could just be layer_filter
i.e. it filters which layers are included
With the naming I feel like some form of "member" makes more sense than groups actually 
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
yeah... a "group" is very similar to a "layer"
LayerGroup?
add_member sounds very weird though lol
member_of 
LayerBundle lmao
At that point it almost sounds like LayerLayer ๐
if only we had layer as components...
I'd like layers as marker components but idk how to store query filters
Layer<const u8> 
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
In godot "mask" is what is detected
collision layers aren't called a mask, despite basically being a bitmask
We must be the only ones worrying about this naming ๐
i think it's worth worrying because it's really confusing tbh
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"
i'd say "it's on layer A and B"
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
but considering godot/unity, groups would be layers
Yea groups and layers are the same thing, that's why that name makes no real sense
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
I wonder what it would be called if it was in parry 
Maybe interacts_with_colliders_on_at_least_one_matching_layer
collides_if_at_least_one_layer_from_both_group_and_filter_is_a_match
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 ๐
I'll probably rename it to memberships and filters then, I agree it's pretty clear at least
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
I don't think the current groups and masks is much better
and filters is a bitmask of layers
it's filtering layers
i had an unfair advantage of knowing how bitmasks work so i got extra confused by how complicated it was in source code too
I think the real issue is that rapier has: Multiple types for this, less documentation, and they're also called groups ... Which is a name not many other engines use afaict
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
I only learned what masks in this context are like a year ago
If they're learning from scratch they'll be looking for their puzzle pieces 
the introduction to the whole thing using a single layer and raycast is really simple though
masks to me sound almost like the opposite of what they do; irl masks cover things, so it sounds like it's blocking interactions
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
in photoshop masks can do both things so it makes sense to me
Sometimes they cover things to selectively apply things tho ... It's just weird how often with collisions they call them masks when their only behavior is "needs some overlap"
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, ...
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
Just don't make add_filters/remove_filters and let people or/xor/and CollisionLayers.filters ๐
We could remove the methods and just let people do collision_layers.filters.add_layers(...) though
yep
or use bitwise ops
like or/xor/and
that's actually an interesting idea, teaching people to use bitmasks without abstractions
feels like rust somehow
I'd keep the abstractions too though, it'd just be on LayerMask
have both as an option
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
It's called LayerMask instead of Layers now? ๐
for now*
it's more readable to do memberships.contains_layers(layers) than to do ยด(memberships & layers) != 0
i insist on the actual type that is a wrapper for a bitmask to have "mask" in it.
Having methods on Layers/LayerMask seems reasonable ... It's just a lot weirder on CollisionLayers
Like I wouldn't immediately know what this bitwise thing does if I didn't know the method currently
Many people aren't very familiar with working with bitmasks, and forcing them to use them isn't ideal imo
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
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
contains_layers is actually a horrible name ... If it was contains_all and contains_any I would at least be able to guess what it does correctly ๐
i've read this several times and i still don't understand anything
maybe something to do with transform/child scale stacking up with collision scale?
It's a bit hard to tell what could be happening, but you seem to add a cuboid collider with the size using the transform scale. Transform scale is automatically taken into account for colliders, so you might not need that
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
Sorry if not clear enough
i just don't know how to phrase myself in a more understandible way ๐
feel free to ask questions tho
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
and child scale is multiplied by parent scale if you use that
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 ๐
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 ๐ค
take your time with it
And this all started from adding a couple of constructors to SpatialQueryFilter ๐ญ
you can test the actual functionality in between
once you're done with it, you probably won't have to touch it ever again
unless we manage to do layers as components eventually
but that might not be very viable
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.
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
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
For the current layer rework though, the changes I have right now (compared to last time):
- Renamed
groupstomembershipsandmaskstofilters - Removed all group/mask manipulation methods like
add_groupsfromCollisionLayers - Added
add,removeandcontains_alltoLayerMask
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
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...
so, you stopped on the rapier way?
yeah this seems to be basically identical to rapier's approach
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
can't have layers.layers
why is the first one layers
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
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
but again, marker components and query filters can often handle layer functionality
this makes a lot more sense
to have a bitmask marker on objects, similar to name and tag... just like unity...
idk if Bevy would add it as built in
calling the variable collision isn't ideal imo, it's not collision data
too much to consider everything in 1 day though
is _layers even necessary for bitwise ops, considering it's already inside mask?
no, but if LayerMask has Deref, add clashes with u32::add
we could remove Deref too though
i didn't even know ::add is a thing ๐
you can't overload += and -= for the same reason though, right?
for what reason?
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
we could overload it, but it might be confusing
it would probably break some convention rule Rust has for Add
yeah it just sounds dangerous in general
like mask + mask != 2 * mask
(not that adding/multiplying bitmasks like that would make any sense anyway)
wen PartialAdd ๐
I also experienced performance absolutely tanking to the point where optimized dev builds were not useable when running physics in fixed timestep. Although it was our own custom fixed timestep but similar to bevys built in one.
same project as this post, maybe fixed timestep and the new 0.12 child collider stuff is interacting somehow and making perf worse?
Hi @vestal minnow I'm trying to update bevy_xpbd to use the latest bevy main and I'm running into some errors relating to reflection:
https://github.com/jpedrick/bevy_xpbd/tree/upgrade-bevy-314
Please note I've added 'patches' [patch.crates-io]
bevy = { path = "/Users/jpedrick/Development/bevy" }
winit = { path = "/Users/jpedrick/Development/winit-clean" }
Haha, I'm updating it to main right now ๐
Ohhh, well, maybe you'll use some of my chanes.
You probably noticed WorldQuery is deprecated
I'll soon publish a bevy-main branch (and PR), I don't want it on actual main yet
https://github.com/Jondolf/bevy_xpbd/issues/314 <- here's the issue I created for the update
Ok cool, sounds good to me.
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
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
My current bevy-main branch stuff depends on my fork of Nalgebra, and a fork of Parry that depends on that Nalgebra fork...
Wait what's the issue? I'm not getting any errors
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
I think a lot of the types are re-exported exported from bevy_math
yea
It's nicer to use bevy_math cause if you use bevy::math::*; you get primitives ๐
Oh, that's probably the issue
I've gotta get going, but I'll try aligning the glam versions in bevy and xpbd and see if that fixes the problem.
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
Might be nicer to do that
@trail sparrow 0.13 migration "done" in that it should compile and work normally now
https://github.com/Jondolf/bevy_xpbd/pull/315
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
Ok I made a very stripped down version of my game as a repro https://github.com/Seldom-SE/testetst/blob/b6ee6031e69cc08ed2b9e3f6b0834fd8dab0c413/src/main.rs
Thank you!
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" }
Getting bevy_math?
Yeah
Bevy has a Cargo workspace where it has all of the crates as members
https://github.com/bevyengine/bevy/blob/2391e44fa05ffdba4d13e585c30d8b94672a3b8e/Cargo.toml#L24
Cargo looks for a crate called "bevy_math" there
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 !
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)?
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
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.
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
Right. Thanks for the explanation. I love the library so far, having it Bevy native is quite nice.
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);
Hmm, scene needs components to be Reflect, so that seems to be a challenge.
Ah, yeah... I believe colliders can't be reflected until "recursive" types are supported, since compound colliders can contain other colliders
not sure what the state of that is
There's this issue where collision events are sometimes sent when not actually in contact; you could try setting the prediction_distance to 0.0 and/or make the tetris blocks have a tiny gap between them on the X axis
hmm how would I make the collision block smaller then?
I believe the transform is coupled together with the tetris block
Why would you need to make the blocks smaller?
If you need them to be smaller then you could set the transform scale though
I meant making the collider smaller
I thought that's what you mean by "a tiny gap between them on the X axis"
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
I think scaling them wouldn't quite work as intended, since it would break the alignment of bigger pieces ๐ค
yeah, true
yeah...
If you can, I'd probably position them slightly apart on the X axis
If you just scale the X and controls only allow moving a square at a time, this should work fine, I think.
Hmm, thatโs a tricky one. I guess it doesnโt really need to be recursive, though, as Compound doesnโt actually need to be nested. One top level Compound should be able to do anything, unless you allow CSG style modifiers, which seems overly complicated.
I donโt know if thereโs a nicer way to handle this with the shape type, though.
Yeah we'd need Parry to use a separate shape type for the shapes in compound colliders
Here's a bevy_rapier issue for this by the way
https://github.com/dimforge/bevy_rapier/issues/404
(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
Itโs unfortunate it uses a self referential type here, as that makes it require boxing, where it could possibly be self-contained otherwise.
Just fix it in barry ... Make a type for primitive colliders, then a layer on top that is either a primitive collider or a compound collider ... No more self referential types, because compound colliders just won't be allowed to contain compound colliders
Or use bevy_peck where compound shapes aren't a thing yet
Neither is proper collision detection, but...
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
this mostly works, but it sometimes fails
are you trying to make jelly tetris or something
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
it's usually faked by splitting exterior from interior to different layers that can't see or interact with each other
Oh no lol, just regular plain Tetris
I'd go further personally, and just make it a totally separate, static world without any sort of moving reference frame. Having physics objects move around is just asking for trouble if you can avoid it.
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!
I've found the solution!
With a little more research in Bevy's doc, I came across the SystemSet TransformSystem (https://docs.rs/bevy/0.12.1/bevy/transform/enum.TransformSystem.html)
I ended up making a camera_follow_player.after(PhysicsSet::Sync).before(TransformSystem::TransformPropagate)
Set enum for the systems relating to transform propagation
Yup, there's an issue and explanation for this here
https://github.com/Jondolf/bevy_xpbd/issues/211#issuecomment-1789342920
It'll be in the documentation FAQ for next release
Thanks ๐
plain tetris doesn't use physics
considering how frequently it happens, maybe just add a correct camera to example?
yeah, that could be a good idea
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
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
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
hi, is there a way to disable a collider?
change layer
commands.entity(ent).remove::<Collider>()
Or you can add a sensor component
@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
yeah doc aliases are good to add here
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?
Do they not show up? I think it should work
๐ค don't seem to be
This example spawns colliders without rigid bodies, and raycasts work
https://github.com/Jondolf/bevy_xpbd/blob/main/crates%2Fbevy_xpbd_2d%2Fexamples%2Fray_caster.rs
Make sure it has a transform, that might be required
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
Yeah it probably shouldn't
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 :)
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
it's less extreme on the inside, but definitely happening.
but i'll try a different approach, maybe that will go smoother
Short version is that you shouldn't change the translation for stuff like this and it's generally better to use e.g. LinearVelocity.
If you do want to change the position directly, the most stable place would probably be in the SubstepSchedule with .before(SubstepSet::Integrate). This should run the system more often and as a part of the simulation loop
also
For that, you need to use Position instead of Transform because the engine internals use Position
oh that is perfect!
exactly what i needed, thanks! looks quite good now :D
the problem i had is ray hitting next face and rotating ended up hitting previous face, it was too obvious when i was standing still so i had to fix it there, but if you're always moving it might not be a problem
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
So I should use Rapier for an engineering game?
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
I will need that.
yet.
If a ShapeCaster and a Collider are part of the same entity, will the ShapeCaster detect the Collider?
By default, it should not detect it iirc, but there should be some configuration option like ignore_self on the caster
ah wait i needed a .with_max_time_of_impact(0.2)
on the flipside, from an engineering perspective, xpbd is much cooler than using a traditional position based dynamics physics engine
So, I'd like to 'edge detect' collisions.
would: (contact.during_current_frame || contact.during_current_substep) && !contact.during_previous_frame do the trick?
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
I want to know if a collision just happened so I can play a sound
oh like the first frame a collision happens, right, that makes sense
Yeah exactly
I think there is a collision event for when something initially comes into contact, lemme check real quick
yeah here you go
https://docs.rs/bevy_xpbd_2d/latest/bevy_xpbd_2d/plugins/collision/contact_reporting/struct.CollisionStarted.html
A collision event that is sent when two entities start colliding.
your approach would also probably work though
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
yeah the collision event doesn't provide much info unfortunately
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?
I'm confused because I could have sworn that the relative velocity was exposed in the Contact
but maybe that was with with rapier ๐ค
Idk, I haven't looked at rapier yet
Either way, I don't see it anywhere in the xpbd docs
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
Right, well, let me see if pre_solve_linear_velocity does that first
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
What does that mean?
it's cooler!
Are you saying that motion is relative?
what?
extended position based dynamics is just a newer way of simulating physics than traditional physics engines
What are the advantages?
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
And faster?
here's a good video that briefly goes over the idea of extended position based dynamics
https://www.youtube.com/watch?v=F0QwAhUnpr4
Will I be able to implement joints easily?
joints, sure. but for motor driven joints like you said you will need, it won't be too hard if you have a solid understanding of classical mechanics
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
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
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?
Ok, so... it seems like pre_solve_linear_velocity is indeed not the best thing to compare with.
But it will get better.
So is xpbd in general very fast?
for what it can do, yes
i'd assume that for engineering game it'd be a better choice in the long run
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?
quaternions don't really have anything to do with physics in this case, you could ask in general
transform.look_to(hit.normal, Vec3::Y) should work
look_to i mean
does this assume that the translation is at 0, 0, 0?
That doesn't matter in this case i thin?
it does
yeah why not just set the rotation directly
Quat doesn't have a helper method for this.
it doesn't need one
transform.look_to(hit.normal, Vec3::Y) will do the trick. (Note: look_to, not look_at)
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);
^ Should be Vec3::Z or Vec3::NEG_Z
it makes the quads not appear for some reason
The default quad points to Z
nvm Quat::from_rotation_arc works
then Z fits ๐
i really hate the coordinate bullshit
i wonder how hard would it be to make them configurable
Is there a way to make CollidingEntities only include colliders that correctly intersect with CollisionLayers between the two entities?
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?
I'm pretty sure they don't collide, because objectB doesn't have the LayerA collision mask
Both have to be compatible, i.e. B is in masks of A, and A is in masks of B
ah ok, I see
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),
It already only contains the entities with compatible collision layers, otherwise they wouldn't be colliding
unless I'm misunderstanding what you mean
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
You mean you want to see if something is visible in a circle?
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
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
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
For my purpose I think it's ok
Yea there's some room for optimization in this approach, so something clever could definitely be designed for it ๐ค
Right... I guess the first thing I'll need to figure out is how to search in a circle
Easy enough to check the translation of every entity, but maybe some kind of grid buckets
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
Probably not as built-in, but could be a good 3rd party crate
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.
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?
Setup their CollisionLayers so that they don't interact with each other
It should Just Workโข
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
Child and parent don't collide with each other by default?
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
for ExternalImpulse.apply_impulse_at_point() why do you need to supply the center of mass as a parameter? Isn't that already calculated and stored on the entity?
https://docs.rs/bevy_xpbd_2d/latest/bevy_xpbd_2d/components/struct.ExternalImpulse.html
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
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
You should probably use the SpatialQuery system parameter, and use either project_point or point_intersections
A system parameter for performing spatial queries.
Ah I see, nice docs btw
Out of curiosity, is direction Vec2::ZERO when raycasting pointing into the screen in 2d?
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
True, maybe add an assert or something for idiots like me passing in a zero-direction ๐
Yeah, that could be good to add ๐
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
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
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 ๐ค
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
That lifetime is just because impl Trait in return position has some cursed issues ๐
I actually want to do it a bit different, by implementing a trait for SDF collisions directly for the primitive types (and any of my custom SDF types), and SdfCollider being an enum-dispatch type for that trait. That way you can pass either a collider, or pass a primitive without needing any Intoing
yeah, makes sense
I could maybe try something similar for bevy_peck
or I do already do that kinda
It sounds more and more like my sdf collisions should just be an extension to bevy_peck ๐ค
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 
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
Huh? How? ๐
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.
I was recently testing the Box2D version 3.0 alpha and found a stability problem. I found a fix for the problem fairly quickly, however the experience left me thinking about the progression of v3.0 and how the engine has been getting more features and more complexity. There are several joint types now. There is island management, multithreading,...
Huh ... That sounds like magic
It would make tunneling as bad as no substepping tho right?
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
Does it make sense to have a 1D collider? x-min = x-max?
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
With a sign as normal 
having a 1D line as a collider in 2D
As in it collides only based on X or Y positions?
for a game like this: https://powerline.io/
i'd like to detect if there are snakes parallel that are close enough to my snake
powerline.io - Massive multiplayer online snake
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)
well, there are segment and polyline colliders
Hmmm, having it actually check for it being parallel might be fairly hard ๐ค
๐ 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!
you can add the PhysicsDebugPlugin to visualize colliders
thank you! i thought it was a daft question and i'm thrilled to be right (and daft) ๐
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)
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)
Kinematic bodies interact with other bodies, no?
They can apply forces to dynamic bodies, which I guess is interacting with other bodies yes
You can make it a sensor collider with Sensor though
That way it'll still go through other bodies
Now that I think about it, I dont even need a collider, probably cheaper doing point_intersection each frame
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 ๐
Ok so, kinematic body without any collider would fit my criteria if I have understood this correctly
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)
If I want to see redundant code, I will go to my job ๐
I don't think position += linearvelocity * delta; is an amount of redudant code you need to worry about ๐
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?)
Is it possible to conditionally run PhysicsDebugPlugin ? E.g. toggle by pressing key
Parallel contacts seem to have only two contact manifolds in bevy xpbd from what I've seen
Spatial queries also benefit from the bounding volume hierarchy broad phase sweep optimizations, so the collision detection would not be entirely wasted
There's a resource you can get that allows you to enable it disable it. I think it's called PhysicsDebugRenderConfig? But I don't have the docs on hand rn
That's separate actually, the broad phase and spatial query acceleration structures aren't shared
Currently the broad phase uses sweep and prune instead of a BVH
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)
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
No, spatial queries still use a BVH (QBVH to be exact), only the broad phase uses SAP
so yeah, it should be fine
Oh wow, so spatial queries are even more optimized, nice!
it just uses Parry's Qbvh, the core spatial query logic is almost identical to rapier/bevy_rapier
Orrr you're saying the SAP only actually happens once per frame, I see
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 ๐ค
@fair fractal so you're saying i should still use xpbd's collision events?
I didn't think collision events will be generated if your objects don't have rigid bodies
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
They will, they work like Sensors iirc
Ah, well. Nevermind then
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?
No, collision detection and spatial queries are considered separate. Spatial queries handle e.g. raycasting, shapecasting, and so on, while collision detection detects and computes contacts (contact points and normals).
If you have rigid bodies, the constraint solver goes through the contacts and performs the corrections necessary to resolve overlap.
XPBD also doesn't really use contact forces since it's position-based
And other simulation methods typically use impulses
ok thanks, i'll start with spatial queries then
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?
Yes to both, you currently need both the SyncPlugin (to handle positions, especially if you use Transform in your own logic) and PreparePlugin (to initialize some components)
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)
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?
Yeah, in that case it might not be necessary
In PreparePlugin, it sounds like I only need ColliderAabb? is that used by SpatialQueries?
I'll check
I'm pretty sure that isn't needed either
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!
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