#Avian Physics

1 messages · Page 30 of 1

sleek thicket
#

and i set up bitmasks as consts, so it's just layer::whatever to me when spawning

#

with components it might actually get worse

vestal minnow
#

With bitflags I really don't like that if component A requires ActiveCollisionHooks::FILTER_PAIRS, and component B requires ActiveCollisionHooks::MODIFY_CONTACTS, only one of them will be applied unless you manually add both

#

with separate components this is not an issue

sleek thicket
vestal minnow
#

enabling collision hooks

#

for filtering broad phase pairs, and for modifying/filtering contacts computed by the narrow phase

#

and possibly more in the future

sleek thicket
#

i tried reading rapier doc about it but i still don't get how it's different from collisionlayers

vestal minnow
#

you cannot query the ECS or do any other custom logic with collision layers, nor can you use them to modify contact data

#

you can use contact modification hooks for one-way platforms, conveyor belts, non-uniform friction and restitution, etc.

#

broad phase pair filtering is a bit more limited, but you can use it for e.g. interaction groups beyond the limit of 32 layers for CollisionLayers, or for stuff like Box2D's collision groups (different from layers)

#

any custom logic before the collisions are handled by the solver

sleek thicket
#

i took a look at PR and the reworked one-way example, and my conclusion is that you really shouldn't worry about how 1 line out of 800 looks nicer 😅

paper maple
#

What is prediction_distance in contact_manifolds

shut pulsar
#

didn't see that message, cheers for the info.
Yeh I meant how it's mean to be used/configured in Bevy as it didn't really click for me (new to rust) couldn't find an example

vestal minnow
paper maple
#

yeah sorry it's clearer in contact

vestal minnow
#

arguably it even makes some things slightly more annoying (as opposed to using PostProcessCollisions)

sleek thicket
#

i'm saying that you already made 2 examples so you probably know which one is better, even if it doesn't look nice

paper maple
#

Would it be a bad idea to have SpatialQuery expose its fields ? I currently have to put Position, Collider and Rotation queries in a ParamSet because SpatialQuery uses them, but doesn't expose them to the user.

past cargo
#

Hey Bro, How do i see this world inspector?

paper maple
cyan flame
#

I have a really silly question

#

How can I make gravity of a collider relative to another collider?

#

I'm trying to use the 3d dynamic example and adapt the character controller to move around a sphere (planet) but gravity is -y... is setting gravity angle(?) supported?

#

Custom collider 2d example is what I'm looking for... but I'm not sure how to turn that into 3d

mild stump
#

So I have a quick question. If I use cross-platform determinism does that mean I will have to sacrifice parallelism or have we found a way to make them work with it?

little maple
cyan flame
#

Should I disable gravity and do position manually?

vestal minnow
#

There isn't that much parallelism yet (mainly narrow phase collision detection is multi-threaded) but there will be more in the future. I intend to keep determinism by default even with multi-threading though

cyan flame
#

Thank you! Will this work if say I added mountains and valley to my planet, i.e. not the simple perfect sphere I currently have?

golden python
#

Hello, I'm still interested if anyone knows of good 3d kinematic collision solutions (except the built-in one)

cinder summit
#

@vestal minnow I think there was some discussion on the potential of a world where big types could be assets instead of part of Collider ... What would that API look like?
Something like this?

enum Collider {
    Sphere(Sphere),
    Capsule(Capsule),
    ... // more small primitives
    TriMesh(Handle<TriMesh>),
    ConvecDecomp(Handle<ConvexDecomp>),
}
#

Trying to plan the improved SDF collider API, and I'm not sure if I should just have everything be a handle to an SDF tree, or make an enum that special-cases the optimized shapes

#

Makes sense to just pick whatever approach avian would go with given the same situation 🤔

past cargo
#

hmm is this normal? if i load the rigid body and collider as components on a bundle it doenst show on PhysicsDebugPlugin

#

wydm

cinder summit
#

That said I don't think bundles should be breaking the debug plugin ... Maybe nested bundles are broken or one of your bundles is actually a Component instead of a Bundle 🤔

past cargo
#

the sad thing is that i cant modify the default values from #[require]

#

how

#

yes

#

and have nothing aobut it

#

or iam blind lol

#

thanks guys

vestal minnow
#

Also I don't love the shape name repetition for the API, like Collider::Sphere(Sphere::new(0.5)), but we already have Collider::from(Sphere::new(0.5)) and even Sphere::new(0.5).collider() which is alright. I'm not entirely sure if we want to keep all of the current constructors like Collider::sphere(0.5) on Collider, or embrace the primitive shape APIs more, probably the latter

#

We also need to handle scaling, which is why the current representation has both the scaled and unscaled version, similar to bevy_rapier

pub struct Collider {
    shape: SharedShape,
    scaled_shape: SharedShape,
    scale: Vector,
}

There's probably a smarter way to do this though. We should probably just store only the scaled version, even if that could technically be lossy when scaling at runtime, and have some optional component to entirely disable automatic scaling with transforms. People who need "lossless" scaling can always cache the unscaled version and manually handle scaling for the rare cases where that does matter

#

(an example of "lossy" scaling would be if you have an animation that scales the collider from a scale of zero to one, but the scale of zero erased all information about the size and proportions of the actual shape)

sleek thicket
#

do you have any plans for how working with colliders will look like in the editor?

#

asking that because in unity i never even had to touch the API

vestal minnow
#

Ideally similar to Unity or Godot, add a Collider component and have a dropdown where you can set the shape and its properties

#

If we have shapes like meshes as assets, you can load or drag and drop that for the shape (handle)

#

You just define the unscaled collider's shape in the editor, and the transform scale is applied to that

#

since the editor edits mostly BSN, that can just store the unscaled shape

#

then at startup (and in the viewport) it applies scale probably

vestal minnow
#

I'm thinking that I might make Friction and Restitution only affect the collider they're on, not child colliders 🤔 I'm pretty sure they're currently our only components whose behavior propagates to child colliders (unless explicitly specified for those entities) which is a bit inconsistent

#

it's also kind of a pain internally to have the "collider -> body -> global default" priority chain for them

#

this is so ugly lol

// Get combined friction and restitution coefficients of the colliders
// or the bodies they are attached to. Fall back to the global defaults.
let friction = collider1
    .friction
    .or(body1.friction)
    .copied()
    .unwrap_or(default_friction.0)
    .combine(
        collider2
            .friction
            .or(body2.friction)
            .copied()
            .unwrap_or(default_friction.0),
);
let restitution = collider1
    .restitution
    .or(body1.restitution)
    .copied()
    .unwrap_or(default_restitution.0)
    .combine(
        collider2
            .restitution
            .or(body2.restitution)
            .copied()
            .unwrap_or(default_restitution.0),
);
#

oh right CollisionMargin is like this too

vestal minnow
#

mhhh I'll keep it the way it is for now, though it's making things more annoying for me rn

sleek thicket
#

you could just make a constructor on parent

#

so users will only need to deal with 1 component that propagates to every child on spawn

vestal minnow
#

wdym by constructor

sleek thicket
#
  1. i still think Mass should be renamed to something like IndependentMass to avoid confusion
  2. i can't understand how easy it would be to propagate to joints instead of children, otherwise the generic propagation seems almost perfect
  3. combining friction+restitution+density into one "material" makes the most sense to me,
    unity and godot basically do this but without density
  4. i still think that it'd make more sense to spawn a group of objects using only the final mass and create a material based on that, and i can't see if anything like it has already been done in mass rework
sleek thicket
#

#3 especially makes sense when you account for gameplay where you can get frozen/petrified

#

not sure if propagation would work there, because you might want to freeze only 1 body part

vestal minnow
#

Combining friction and restitution could be fine, and I would do that if we make physics materials assets. But:

  1. It's not necessarily an ergonomics win.
commands.spawn((
    PhysicsMaterial {
        friction: 0.4,
        friction_combine_rule: CoefficientCombine::Max,
        restitution: 0.2,
        ..default()
    },
    // ...
));

vs.

commands.spawn((
    Friction::new(0.4).with_combine_rule(CoefficientCombine::Max),
    Restitution::new(0.2),
    // ...
));

We could have constructors for PhysicsMaterial, but it'd still be a bit more verbose. Though with materials as assets, you could cleanly reuse the same material handle, which would be nice.

  1. You wouldn't be able to set e.g. a custom friction, while still using the globally configured default restitution, since the material component would override both. Not sure if this is really a big issue though.
sleek thicket
vestal minnow
#

split this out from the contact graph branch

#

After the contact graph + solver bodies, we can handle 13k+ active contacts at 60 fps in 2D on my machine

#

(6 substeps)

#

I should test how this compares to bevy_rapier without SIMD

golden python
#

thanks, i'm trying it out, though it is 0.14, so I have a lil upgrading to do

vestal minnow
#

Avian vs. three steps of Rapier in this large pyramid test, tried to make configuration as comparable as possible

#

there's something wrong with my config though since Rapier is giving a lot of zeros even for stuff like contact counts

golden python
#

Hello, are there migration notes for 0.1 to 0.2 ?
I am specifically looking for what shape_cast's max_time_of_impact became.

vestal minnow
#

It's just max_distance

golden python
#

thanks, that was my suspicion

grizzled depot
golden python
#

Now I'm going to try and port the collision part back into my character controller, it's a mess

vestal minnow
#

I believe I should probably store a bit set for each worker and cache those rather than reallocating every time

#

(if only I knew how to do that ferris_sob)

#

I should really get a lot more familiar with multi-threading beyond par_iter and par_splat_map lmao

#

way faster than current main branch, but inherently much slower than multi-threaded for collision detection

#

lemme try

#

scuffed screenshot setup lol

#

I think we should be able to optimize the single-threaded version of the narrow phase by a fair amount, it's currently kinda using the "parallel approach but single-threaded"

#

could probably have a single-threaded path that doesn't use the bit set stuff at all

lavish orbit
#

@vestal minnow I just noticed that on the github light theme, the avian logo looks a bit weird and pixelated along the edges. just thought I'd let you know.

cinder summit
#
#[require(Predicted, RigidBody(|| RigidBody::Dynamic), Collider(|| Collider::from(Sphere::default())))]

The avian API sure is clunky to use with required components ... Tho I guess it's nice that Collider at least doesn't require any Assets currently 😂

opaque temple
#

Does anyone have thoughts for BigSpace integration? If you tried it, what were the challenges?

vestal minnow
#

I'm on my phone rn but it's not that pixelated for me

lavish orbit
#

Huh, maybe a safari quirk

vestal minnow
#

can also use a function instead of a closure if the same requirement is used for different components

past cargo
#

jondolf the goat

cinder summit
vestal minnow
# opaque temple Does anyone have thoughts for BigSpace integration? If you tried it, what were t...

For a single floating origin it shouldn't be too bad, mainly I think you need a custom version of Avian's SyncPlugin which synchronizes Bevy's transforms with the Position and Rotation components used by physics. Someone made a branch that has this a long time ago.

For proper support, including multiple floating origins, we need the ability to run several instances of the simulation separately. This isn't currently easy to do properly, but I have a prototype for multiple physics worlds using bushrat's indexed query PR for Bevy. I haven't worked on it more yet though since that PR is currently kinda stalled

#

Once we do have support for disjoint simulation instances one way or another, we would probably use big_space's spatial hashing to group physics entities into those instances

vestal minnow
cyan flame
#

Maybe a silly question but won’t this accumulate endlessly?

sweet sundial
#

isn't that closure unnecessary? RigidBody::default() is dynamic

cyan flame
#

I have a followup silly question… what if I always want my dynamic colliders to be grounded? Am I doing this wrong by doing it in a single system? Say I have a system for vehicle movement, I assume I need to apply the gravity acceleration to the vector of the requested movement. Sorry for these really silly questions, are the some resources you can point me to that would help me understand this better and be better able to reason about this?

cyan flame
#

I never want my vehicle colliders to not be in contact with the planet collider. All colliders should always be grounded… is that misguided?

#

Can you point me to some resources about this so I can educate myself on the domain a bit?

#

If you know of any that is

#

Just feel a bit lost and unable to reason about what I need to do

#

I want to have a capsule move along the surface of a planet which for now is just a sphere

#

Jumping or not either way is fine

sweet sundial
#

my initial impression is 'use ExternalForce with persistent:false, and the entity_commands.entry().or_insert().and_modify() pattern'

cyan flame
#

Conceptually I’m having trouble figuring out what to do to accomplish that

#

I started with just trying to get a capsule spawned 50 units away from the surface to land on the surface

#

Oh really? What part of the camera causes problems?

cyan flame
#

Increasing the friction on the capsule collider and the planet collider causes the capsule to wiggle around in the spot it landed

#

I think that code just took the normal times 100.0 from the translation of the position component and set that equal the the entity’s LinearVelocity component’s inner vector

#

Which is a feedback loop so never reaches a steady state

#

Sorry I’ll the actual code when I get home in a few hours

#

Awesome, will do, thanks for your help!

vestal minnow
#

both are using rayon currently

rocky seal
vestal minnow
past cargo
#

Does avian have body position force? Like i can set a position to It move and Lock on this position, Very good to fly cause i can Lock the Y position only, while x and z can be moved

past cargo
#

Thanks bro

#

You are a goat

formal galleon
#

@vestal minnow In your kinematic character controller example, wouldn't it be way more efficient if you would use CollidingEntities for the Collider of the character instead of iterating all Collisions in function kinematic_controller_collisions in https://github.com/Jondolf/avian/blob/main/crates/avian3d/examples/kinematic_character_3d/plugin.rs ?

GitHub

ECS-driven 2D and 3D physics engine for the Bevy game engine. - Jondolf/avian

vestal minnow
#

It would, yeah

formal galleon
#

Ok, just wanted to make sure that I correctly understood how Collisions and CollidingEntities work

vestal minnow
#

You still need to get the contact data from Collisions but you can at least avoid iterating over all collisions

formal galleon
#

ah yes, good point

vestal minnow
#

the KCC in that example is not great though, I would generally recommend more of a collide-and-slide approach using shape casts instead of raw contact data

formal galleon
#

In my hedgehog game, I implemented a hover functionality, to prevent colliding and flickering all the time, but still use the collision resolver from your example as "fallback", because I have to handle high jumps and such.

formal galleon
vestal minnow
#

yep

#

There's also Collisions::collisions_with_entity which avoids having to use CollidingEntities, but that's horribly unoptimized right now since it just iterates through all collisions. It will be much better with the upcoming contact graph stuff though

formal galleon
#

Ok, so CollidingEntities, for now, is the most efficient way to find collisions of exactly one entity of interest

vestal minnow
#

Yeah it should be the fastest currently

formal galleon
#

Nice! I recognized a performance boost already, because I have a lot of collisions and handling scenarios. 1. I have a wind plugin that applies external forces and torques to falling leafs to appear more natural, but disable the wind affection after colliding with the ground. 2. I use a sensor to detect nearby food on the ground to enable interaction. 3. Another sensor to detect the environment to calculate stealth of the hedgehog (if nearby to grass, it's stealthier than on plane ground). And 4. the character collisions. There are a few more cases, but currently, in every case I iterated all collisions

weary hornet
#

Outside of shapecasts I haven't done much with avian yet, so maybe this is more obvious for someone

if I add a RigidBody::Kinematic to an entity, I should be able to query for these below, and get that entity right? And then it's just a matter of manipulating these to move it?

&mut LinearVelocity,
&mut AngularVelocity,
formal galleon
#

@vestal minnow Is there a easy way to find the matching/related rigid body entity for an entity with a collider (because colliders can be inserted to children entities). For me, it often feels bloated to traverse the parents to find the matching rigid body entity. There is a new upcoming feature called Relations. Maybe we could use something like this to easily lookup a rigid body? Don't know how it would work if there are multiple collider chidren. What do you think?
edit: oh, there is a ColliderParent. sorry! 😄

weary hornet
#

Ok another question, I see Kinematic doesn't deal with collisions.

How would I implement a simple collide and slide system? Dont care about grounded state or jumping, or anything like that.

#

I guess I could just use a Dynamic and use external forces

#

trying to do this without shapecasts like I have in the past

opaque temple
#

I thought kinematic meant, conceptually, that the object is deliberately excluded from the automated physics interactions, to be used for scripted movement / cutscenes.

spiral nymph
weary hornet
#

thanks I missed it

spiral nymph
#

Just need to change bundle by require in case you're using bevy .15

valid fog
#

I'm writing a networking library that has the ability to modify avian transforms and sync them between clients. What is the things I should be aware of the, the caviates, about modifying Position, Rotation, LinearVelocity, AngularVelocity ( i assume these are the components i should be modifying perhaps I am incorrect ).
Should I do these modifications in FixedUpdate or in Update? Are there other scheduling concerns or other things i should be aware of?

#

Is there some way I should be taking advantage of interpolation or something in order to tell the objects to move towards a location instead of just teleporting them there?

spiral nymph
#

FixedUpdate or a custom schedule with const frequency I suppose since you don't want it to dependant of frame rate.
But syncing between users mean you'll need a PreFixedUpdate to compute (t-1) Transform of other clients before computing (t) physics, or to chain them in this order

And you should use velocities instead of changing transform directly to avoid teleporting

cinder summit
vestal minnow
#

So I've been optimizing the narrow phase a bit further. The test scene is a 2D pyramid with a base of 60 rectangles, about 4750 contact pairs in total.

By default, rayon's par_iter_mut is often faster on my machine than Bevy's par_chunk_map_mut, however this seems to be because rayon's task pool here has 24 threads (not necessarily all used) while Bevy's ComputeTaskPool has "only" 16 threads.

If I constrain rayon to 16 threads so that it's the same as Bevy, I get:

  • rayon: 0.56-0.58 ms
  • ComputeTaskPool: 0.38-0.40 ms
    So using Bevy's task pool seems faster in this case when constrained to the same number of threads. Maybe when using rayon it's fighting with Bevy's own task pool in some way, or maybe it's not using high performance cores, idk.

Interestingly, in this scene, Rapier's narrow phase is taking 0.57 ms when also constrained to 16 threads, so we're actually about 33% faster. With a larger pyramid it's closer though, and I suspect that Rapier still wins at larger scales at the moment

grizzled junco
#

modifying Position will always be "teleport"? I'm trying to use bevy_tween to directly modify Position but it won't "trigger" the physics until it stopped interpolating

#

if that's the case, i will try to somehow use LinearVelocity instead

grizzled junco
#

now that i think about it

impl Interpolator for MovePos {
    type Item = Position;
    fn interpolate(&self, item: &mut Self::Item, t: f32) {
        item.0 = self.start.lerp(self.end, t);
    }
}

because it's just directly set the position every interpolation step, it will just keep teleporting until t = 1, even if the physics engine doing something between t = 0 -> t = 1.

#

so, i need a way to check if next position is "valid" then set the position. But that won't go well if, for example, t: 0.1 valid, t: 0.2 not valid, t: 1 valid. It will teleport with a huge step.

#

now i need a way to have a state for "this should not interpolate anymore"

#

i feel like i should interpolate LinearVelocity instead for physics object

cinder summit
cinder summit
#

Also speaking of data structures, I've noticed that Collisions is incredibly slow to clone, but it's needed for warm starting ... I wonder if this is another case of nested Vecs

true hearth
#

you can kind of see the result in this video, though if you let avian do the integration you can skip the second half https://www.youtube.com/watch?v=KPoeNZZ6H4s

It's been a while since the last video hasn't it? I've made quite a bit of progress since the last update, and since one of the things I worked on was some procedurally animated characters, I decided to make a video about the subject. In particular, this video highlights the entire process from initial motivation, to the technical design, techni...

▶ Play video
vestal minnow
# cinder summit How did you optimize the narrow phase? Is this defualt collider specific or gene...

General improvements, a lot of them. I'll have details and results in the PR description once I make that, but:

  • Use a contact graph instead of the current IndexMap. This is needed for iterating over all contact pairs associated with a specific entity, which was previously insanely slow and seriously bottle necked some systems. Also needed for simulation islands once we implement them.
  • A contact pair now always exists if two AABBs intersect, even if the shapes themselves are not touching. The broad phase creates new pairs in the contact graph directly rather than collecting all pairs to a vec every time.
  • All pairs are updated by the narrow phase in parallel, without any extra allocations. Previously the narrow phase basically reinserted all touching contacts and allocated a ton of vecs instead of mutating persisted data directly.
  • contact_manifolds now mutates the given vec of manifolds in-place rather than allocating a new vec every time. However, we still need some allocations and annoying conversions there because Parry uses its own contact manifold type that we can't reuse :(
  • Contact status changes (collision started or ended) are collected into thread-local bit vectors during parallel iteration, and combined into a global bit vector. The narrow phase then quickly iterates through set bits using bit scanning intrinsics, and sends collision events and removes contact pairs whose AABBs no longer intersect. This is done serially for determinism.
  • Collision events are opt-in with a CollisionEventsEnabled component. The overhead of collision events is also way smaller since it doesn't require its own separate scan over collision pairs.
  • A lot of things are simpler: we can yeet BroadCollisionsPairs, AabbIntersections, wake_on_collision_ended, all of the awkward during_current_frame/during_previous_frame shenanigans...
  • Probably more, there's so many changes and improvements that I forget
#

In short:

  • Contact pairs are persisted way better. Much fewer allocations and unnecessary work.
  • Pair creation and removal is fast and handled more incrementally rather than creating and yeeting everything all the time.
  • Updating contact data is way faster, using in-place mutation.
  • Collision event overhead is way smaller.
  • Hacky ugly stuff around contact pair management begone!
cinder summit
#

Nice ... Those changes are a lot more broad than what I imagined when hearing "the narrow phase" ... How big is the actual difference? 🤔

vestal minnow
#

Worth noting that collision events are included in the narrow phase timings now, so it's a bit misleading

#

Also the main branch's version didn't include contact removal in the narrow phase section

cinder summit
vestal minnow
#

The broad phase has been only like 10% or less of the solver's time in most of my tests, and that's if the entities are pretty densely packed in a way that makes sorting for sweep and prune more expensive

#

but my test scenes aren't representative of actual projects so idk

cinder summit
#

The one case where optimizing the narrow phase makes a big difference are when the AABBs overlap but the colliders never touch ... That can be incredibly rare, for example if you largely deal with barely rotated cubes, or things with relatively tight AABBs like spheres ... But then there's like trimeshes or convex decomp

#

Or those arc colliders in my game 😂

#

That will get you potentially thousands of things going trough the broad phase, when realistically only a few contacts exist

vestal minnow
#

For cases like that I don't think there's really a way to avoid potentially unnecessary contact computations, beyond splitting the large shapes up into smaller shapes with their own bounding volumes

#

since Parry's trimeshes store BVHs for the triangles, technically we could try having some mid-phase that further filters intersections with meshes before creating contact pairs for the narrow phase

cinder summit
#

If the narrow phase is fast enough and the solver doesn't waste time on things that aren't even touching that shouldn't be a problem no? 🤔

vestal minnow
#

yup

sweet sundial
#

not actually relevant for my projects, but is there a good way to put a hole in a collider? eg, half-space with a hemispherical pit

spiral nymph
sleek thicket
cyan flame
#

My previous colliders were a 100.0 radius sphere and a 0.3 radius 1.0 heigh capsule

sleek thicket
cyan flame
#

I wanted a realistically sized planet anyway so the fact that this appears to fix it works to my benefit

#

Hopefully it actually fixes it not just seems to

vague pebble
#

Issues like tunneling and precision limitation may arise

vestal minnow
#

not really, in general you're just more likely to get precision and stability issues with very large or very small objects

#

Tunneling would be a problem if you had for example some small object moving towards a thin wall very fast, but scaling the whole scene up doesn't inherently fix anything assuming you also scale the velocities. But yeah stuff like just making the wall thicker would help a bit

#

CCD also "fixes" tunneling so it shouldn't be too big of a concern in general

golden python
#

Hello, I can't seem to get kinematics collision working great with my usecase (I have complex procedurally generated colliders from a mesh) as my characters keep falling through the map.

I tried the kinematic character example, but it would fall through very often.
I also tried this one: https://github.com/UndefinedBHVR/vidar, which worked better but still falls through quite often.

I am considering going with a rigidbody based controller as I imagine it would have more robust collision stuff with CCD.
Is that a good call ?

sleek thicket
golden python
sleek thicket
golden python
#

and I don't understand the "once you actually need it"

sleek thicket
golden python
sleek thicket
golden python
kind moss
#

Can someone help me figure out what's wrong with the physics here? An impulse is being applied to the blue ball in the direction the green line is pointing. When it rolls along the surface and over the edge it bounces in to the air. The corner it's rolling across is clean, there's just one vertex there. The collider it's rolling on is a polyline but I see the same behavior with trimesh colliders. I thought it might have something to do with restitution but I see the same behavior when restitution is turned down to 0 on both bodies.

sleek thicket
kind moss
sleek thicket
kind moss
#

Hmm, yeah, setting SpeculativeMargin(0.0) and SweptCcd::default() seems to resolve it in some quick tests. I thought I'd tried that but I guess not.

#

Yeah, if that didn't completely fix it it made it almost unnoticeable. Hard to say if it's completely gone. Thanks!

grizzled junco
grizzled junco
#

it's so fun doing anything other than finishing the game itself

grizzled junco
#

what makes a rigidbody entity implicitly have Position and Rotation?

true hearth
#

though in most cases, the "anticipation" motion from that video is not part of a "damped spring"

#

but basically it's just:

force = spring_strength * (target_position - current_position)
    - damping_strength * velocity
#

but you can use the equations from the video to control this in terms of zeta and f, which is more intuitive to control. Though you will need to incorporate the rigid body mass as well, except if you are able to set it's mass to exactly 1.

true hearth
vague pebble
#

Curious, if there are multiplee collision at the same, is there a chance that the Collisions event might die before I can consume it? If so, how can one ensure he never skips a collision

past cargo
#

.

cinder summit
#

So I know how I would make a rocket league arena with SDF colliders, but what would be the most sensible approach with the default collider? 🤔

vestal minnow
#

the easiest would probably just be a trimesh

#

with fixed internal edges

#

convex decomp could maybe work too, but I'm not sure if it'd produce perfectly consistent or smooth enough results in comparison to a hand-authored thing

cinder summit
#

Yea especially since the arena would be big ... Maybe if I flipped some meshes a couple of times, but at that point just doing rectangles might be easier 😂

dark swift
#

This took me way too long to figure out but I wanted to share here in case it was useful for someone else because I couldn't find very many complete 2D top-down examples. I made an Avian 2D top-down kinematic character controller that doesn't get stuck on corners. Feel free to suggest any changes if you find a bug https://gist.github.com/komodo472/527de60a3d2ee07c4d5ca18c3d14087c
It's based on these two papers

Gist

Bevy Avian 2D Top-Down Kinematic Character Controller - client.rs

weary hornet
#

Hey so I have a weird issue where colliders are not following the entity.

Note that I am using lightyear, and I have a feeling it's probably related to how it handles interpolation. Not sure what to do, I'm thinking maybe its needing to manually set the Position or something.

grizzled junco
grizzled junco
fading zenith
#

I'm trying to write a very basic breakout game and my setup is very simple, but I'm running into issues that I think should be trivial and could use help with. 1) The ball doesn't reflect off the objects at the expected angles. 2) The ball starts speeding up (or slowing down?) and I can't tell why. The paddle is a kinematic body, the ball is a dynamic body, and the walls are static bodies. Restitution for everything is 1.0. Can provide code if needed, but I have a clip

sleek thicket
#

and those walls might be causing ghost collisions, try making them out of just 4 colliders

fading zenith
#

kk will give it a shot

fading zenith
formal galleon
#

I think I found a bug. I have an entity with multiple colliders as children - one "real" collider, and some sensors. As soon as my real collider collides with another collider (which also isn't a sensor), the is_sensor field in Contact is true (https://docs.rs/avian3d/latest/avian3d/collision/struct.Contacts.html#structfield.is_sensor) which isn't correct.

I also validated it with a Query<Has<Sensor>> for both - entity1and entity2 fields in the Contact. The query also returns false for both entities. I can't imagine that this behavior is intentional?

I use the latest release version 0.2.1.

proven ice
#

using avian2d. how could i generate a collision mesh and then use it as a static body's collider?

#

in my particular case, i'm just gonna be generating triangles.

kind moss
# proven ice using avian2d. how could i generate a collision mesh and then use it as a static...

I think this is probably the easiest way if you mean a triangle mesh: https://docs.rs/avian2d/latest/avian2d/collision/collider/enum.ColliderConstructor.html#variant.Trimesh

#

There's another variant for just single triangles too.

proven ice
#

does avian have this problem?

#

the red circles are misaligned lol but i think its a problem people making tile-based games in modern engines will be familiar with

#

im working on a solution / meshing algorithm. finds edges (and their normals), and creates triangles from them. then maybe i could do something where the corners are filled in (only half-way to the inset points, due to an edge case that is hard to explain via text) to prevent weird corner behaviour.

sleek thicket
proven ice
junior flower
# proven ice inspired?

Making inward-pointing triangles to have a single face per edge. I think the idea is neat.

proven ice
#

oh, thanks!

proven ice
#

im going to assume avian corrects for non-CCW triangles internally? since creating a collider from a single triangle does so.

kind moss
vestal minnow
#

and only in 2D

vestal minnow
#

The way to properly fix ghost collisions is to have a shape that uses adjacency information to detect and prevent hits against internal edges. Trimeshes support this with TrimeshFlags::FIX_INTERNAL_EDGES enabled, and it should also be possible to support it for polylines, but I'm not sure if Parry does. Box2D has a chain shape for this

#

Also see Erin Catto's article on ghost collisions
https://box2d.org/posts/2020/06/ghost-collisions/

worldly cove
#

I have a very large object, moving very fast - and it seems to be "jittery". I thought it was the bevy_panorbit_camera not keeping up, but after looking more, it seems that other static objects (like the small trees) are smooth. I'm reeeasonably sure I'm not manually updating the stone anywhere else - any suggestions on what I might check? Thanks!

sweet sundial
#

what's your physics tickrate?

worldly cove
# sweet sundial what's your physics tickrate?

I went to reply "just using whatever is in PhysicsPlugins::default()", which lead me to actual read the docs. Upping the substeps to around 20 fixed the issue I was seeing. Not sure that's the best way - but I'll now read the rest of the docs and make sure I'm not doing anything else stupid. Thanks!
[Edit, well - fixed it with debug on, but still jittery without it... but I'll try more settings and hopefully sort it out]

[Final edit! Reading the docs really pays off... who would have thought? Adding the TransformInterpolation component to my stone as recommended in the very clearly-titled "Why does movement look choppy?" question in the FAQs - makes everything buttery smooth]

viral goblet
#

Are collisions reported twice?
If A intersects with B do I get both an (A,B) event and a (B,A) event?

viral goblet
#

Interesting
Which one is the first then?

sleek thicket
#

either one.

viral goblet
#

Meaning that if I have two different queries I need to check twice each time?

#

What do you mean? Can you send a code example?

sleek thicket
#

one system sorts all collisions, and the subsequent systems know exact order and type

viral goblet
#

I see

sleek thicket
#

there's also no issues with race conditions unlike the usual approach

viral goblet
#

But that means that they're all in the same place
If I wanted them to be more independent I'd have to send another collision-sorted event which would flood the system

kind moss
viral goblet
#

I think I'd just check in each query

vestal minnow
kind moss
sleek thicket
kind moss
# vestal minnow It should fix ghost collisions against the mesh that has it set, but it of cours...

Yes, it seems to still be happening. The terrain mesh here is built with FIX_INTERNAL_EDGES on and the blue ball has the default SpeculativeMargin and SweptCcd off. An impulse is being applied in the direction the green line points and you can see that the ball rolls to the edge and then hops into the air, which I've been blaming on ghost collisions but maybe there's actually some other problem.

#

Sorry, that first example is my old test. Showing the same problem without FIX_INTERNAL_EDGES. The second video is the one with FIX_INTERNAL_EDGES on. The behavior is the same, or maybe slightly better in the second one but the problem is still there.

vestal minnow
#

Hmm so this is 2D, I'm not sure if Parry handles internal edges properly there

kind moss
#

Yes, 2d. Sorry, should have specified that.

vestal minnow
#

I know in 3D Parry uses "normal cones" to fix contact normals using adjacent triangle geometry, but it might not do that in 2D currently

kind moss
#

Ok. I'm actually fine using SweptCcd and the tuned SpeculativeMargin, that fixed the issue for me. I just got excited when I saw you mention FIX_INTERNAL_EDGES.

vestal minnow
#

The problem with observers is that we'd ideally only trigger the event for entities that are actually being targeted by an observer, but with current Bevy that info is not easily accessible. People might also have assumptions about global observers behaving a certain way, like getting all collision events by default, but that wouldn't necessarily be the case here

#

We could also just trigger the collision events for everything by default, but that could be thousands of events per frame in heavier cases, times two (one event for each entity in the collision)

#

A custom API more similar to bevy_eventlistener would make the API more obvious and provide a clear marker of "send collision events for this entity please" since the component lives on the entity directly, but that may also diverge a bit from what many people expect, since observers are the usual first-party thing for targeted entity events

sleek thicket
#

i don't unity/godot's approach because of what happens after that,
you'll still need to look up what the other object is twice, when it could just be sorted out ahead of time

#

i just need to figure out a better way of doing it

vestal minnow
#

In theory we could make an API where e.g. collisions.get(entity) returns the collision such that the given entity is the first entity in the collision data, but that would mean iterating through all of the manifolds and contact points and swapping everything

#

*in the case that it's not already the first entity

kind moss
vestal minnow
#

For entity events using observers / one-shot-systems / whatever, you'd always know which entity is "self" and which entity is "other", but those events only store the entity, you still need to query the Collisions resource to get actual collision data

kind moss
#

Related: Having body_entity on OnCollisionStarted would also be very useful. I don't have a sense for how expensive that is, maybe it's prohibitive.

sleek thicket
#

@viral goblet i just realized you could just hold multiple Option<tag>s inside that component
just skip matching when tags shouldn't interact

you can split the individual sorting systems into events with just 1 tag too

vestal minnow
#

but two extra u64 values per event probably isn't a concern memory-wise :P

kind moss
vestal minnow
#

Yeah, makes sense

kind moss
#

Sometimes I can use Collisions instead, and I do. But the events are nice.

vestal minnow
#

I like how the current tuple struct looks API-wise when destructuring in stuff like loops

for CollisionStarted(entity1, entity2) in event_reader.read() {
    // ...
}

but I guess this pattern wouldn't be too much worse if it was a normal struct with fields either, assuming you're using the field names directly

for CollisionStarted { entity1, entity2, .. } in event_reader.read() {
    // ...
}
kind moss
#

Yeah, I agree the tuple is very clean but the second version also looks fine.

sleek thicket
#

it won't look fine if you change the name though

kind moss
#

Yeah. But entity1:my_entity1 isn't terrible.

#

And the mass of code required to look up the RigidBody from the collider entity is way worse.

sleek thicket
#

for a fair comparison:

for CollisionStarted(E1, E2) in event_reader.read() {
    // ...
}
for CollisionStarted { entity1: E1, entity2: E2, .. } in event_reader.read() {
    // ...
}

i think tuple wins 😄

kind moss
#

If that's all you're doing I agree. But if you need the body, which I always do, you have a whole lot of other ugliness to deal with which an extra field would solve.

#

And that ugliness involves both the system definition, because you probably need an extra Query, as well as the code that processes the event.

#

Also the performance cost of doing the query lookup.

sleek thicket
# kind moss If that's all you're doing I agree. But if you need the body, which I always do,...

you just need 2 bodies, right? in that case wouldn't it just be...

for CollisionStarted(E1, E2, _, _) in event_reader.read() {
    // ...
}
for CollisionStarted { entity1: E1, entity2: E2, .. } in event_reader.read() {
    // ...
}

if you're not using them, and

for CollisionStarted(E1, E2, RB1, RB2) in event_reader.read() {
    // ...
}
for CollisionStarted { entity1: E1, entity2: E2, rigidbody1: RB1, rigidbody2: RB2 } in event_reader.read() {
    // ...
}

if you are?

vestal minnow
#

not exactly the clearest type definition

pub struct CollisionStarted(pub Entity, pub Entity, pub Entity, pub Entity);
kind moss
#

Yeah, I agree.

#

I strongly prefer named fields in this case.

sleek thicket
#

i guess i'm fine with both because i have it all in 1 system

vestal minnow
#

you can also just... not use destructuring there if it ends up ugly, you can just call it ev if you want short names and do ev.entity1 or whatever

cinder summit
sleek thicket
#
for CollisionStarted([E1, E2, RB1, RB2]) in event_reader.read() {
    // ...
}

bavy

#

sometimes you can't make both sides equally happy, but you can always make them equally unhappy

for CollisionStarted((E1, RB1), (E2, RB2)) in event_reader.read() {
    // ...
}
kind moss
#

No see, this is fine:

for CollisionStarted(es) in event_reader.read() {
    for e in es {
        if collider_query.contains(e) {
          // process colliders
        } else if body_query.contains(e) {
          // process bodies
        } else { panic!() }
    }
}

bavy bavy bavy

kind moss
sleek thicket
#

i think it's better when you don't care about either collider or body

#

(_, _, rb1, rb2) or (e1, e2, _, _)

kind moss
# sleek thicket why not (e, e, rb, rb)?

That is a good question. The structure of the nested tuples makes the relationship between the pairs less opaque to me. To be clear, I still think it's a bad design but I think it's less unclear.

kind moss
sleek thicket
#

vs ((_, rb1), (_, rb2)) or ((e1, _), (e2, _))

#

every variant is better than how unity did it though

vestal minnow
#

how does Unity handle it?

sleek thicket
#

collision gets rb by default, and you use .collider to get actual collider

void OnCollisionEnter(Collision collision)
{
    Debug.Log(collision.collider.name);
}
vestal minnow
#

Oh god it has both body and rigidbody and they belong to different game objects

slow tapir
#

How do I prevent colliders from sticking together? I have a trimesh generated from a bevy_voxel_world chunk and a bevy_tnua capsule collider for the player.. I tried a CollisionMargin of 0.15 but it still gets stuck

sleek thicket
viral goblet
# sleek thicket <@1204086077942538304> i just realized you could just hold multiple Option<tag>s...

What I ended up doing (after thinking about it for the entire day) is exctracting this logic into a macro, so it's use looks something like:

            physical_bodies,
            unchangeable_velocity_bodies,
            *first_entity,
            *second_entity
        );
        match maybe_bodies {
            Some((
                (LinearVelocity(velocity), Mass(mass), physical_transform, physical_entity),
                (unchangeable_velocity, unchangeable_transform),
            )) => {
                  ...
                  }
            _ => {}
      }
#

Oh that means I can actually use if let

#

Look how clean this other function is now:

        let maybe_damage_taker_and_causer =
            get_from_both_queries!(damage_takers, damage_causers, *first, *second);
        if let Some(((damage_taker, damage_taker_entity), damage_causer)) =
            maybe_damage_taker_and_causer
        {
            if damage_taker.is_damageable_by(damage_causer) {
                damage_requester.send(DamageCauseRequest {
                    to: damage_taker_entity,
                    damage: damage_causer.damage,
                });
            }
        }
    }```
#

(Let me know if I should share the macro here so other people may use it)

slow tapir
formal galleon
#

Please don't blame me if it's not 😶

sleek thicket
# viral goblet What I ended up doing (after thinking about it for the entire day) is exctractin...

you'll probably need to revert if you run into same problem as me 😄
i needed projectiles that are damageable, but can have special interactions with each other
when it was separate, it'd trigger both the projectile_hit_damageable and projectile_hit_projectile, but i only needed the latter
so i had to query both for everything they might be, and sorting that out ended up just being a more complicated version of tag matching

sleek thicket
valid fog
#

I need to extrapolate out using position += velocity * delta time

#

Where delta time is timestamp when packet was sent - current time

cinder summit
# valid fog I need to extrapolate out using position += velocity * delta time

This also produces weird artifacts, which is why games either accept the fact that other people's positions are in the past (and potentially use lag compensation to make sure gameplay isn't affected by it heavily), or do fully simulate what those clients would've done using rollback, like fighters or in a non-1v1 setting rocket league

past cargo
#

@vestal minnow why when i add serialize as feature it remove all others?

#

aaaaa

sleek thicket
past cargo
#

if i remove serialize its fine

#

otherwise no

sleek thicket
past cargo
#

not working

sleek thicket
#

and why are you showing the compile error tab when it's written in terminal anyway

past cargo
#

guys

#

putting like this fixes the issue

past cargo
#

xd

#

simple test btw linear_velocity.z += 20.0 * delta_time;

#

all i do is put RigidBody::Dynamic and Collider::capsule(0.3,1.0)

gloomy folio
#

I have a problem.. i change LinearVelocity and AngularVelocity but it doesn't move at all. do i need to tell avian that i've changed it or something? i print it to console and numbers move and move from frame to frame

past cargo
#

did you implemented the Pyshics plugin?

#

on add_plugins

sleek thicket
past cargo
#

?

sleek thicket
#

unless you were on ice

past cargo
#

but iam pushing?

#

iam just trying move it

#

like normal walk

#

i shouldnt use linear velocity so?

sleek thicket
#

if you remove friction he'll slide, if that's what you want
if you lock rotation he just won't fall
character controllers are a pain and there are too many ways to deal with it

past cargo
#

okie so i need lock rotation?

sleek thicket
past cargo
#

"you can just disconnect the animations from collider"?

#

wydm

#

the player walking animation?

#

cause the model is a child of the entity that have the collider

gloomy folio
past cargo
gloomy folio
past cargo
#

that was the problem?

past cargo
#

now i just legit just need move it ahaha

cinder summit
kind moss
#

When I add a RevoluteJoint (or any joint, I think) as a component on one of the bodies it joins it seems not to work. If I spawn the exact same RevoluteJoint as it's own entity it does work. Is that Expected or a bug? It seems like it would be tidy to keep the joints close to the entities they apply to.

#

Hmm. If I spawn the joint as a child of the entity it effects, that also works. So maybe it's just that the joint component interferes with other components on the body? I guess having it as a child addresses my tidiness concern.

past cargo
#

how does Shapecast works?

sleek thicket
past cargo
#

BRO

#

IAM talking about the method

#

like have cast_shape_predicate

#

and cast_shape

#

what is the difference?

sleek thicket
past cargo
#

is there a way to debug the ray? @sleek thicket

#

so i can see the direction its going

sleek thicket
#

ray/shapecaster should have it but i don't remember if it's enabled by default

past cargo
#

i mean, iam trying fire a ray down the character to align it with the floor

#
let transform_translation = transform.translation;

        let shape_hit_data = query.cast_shape_predicate(collider, transform_translation, Quat::from_rotation_y(0.0),Dir3::Z,&ShapeCastConfig{
            max_distance: 20.0,
            target_distance: 0.0,
            compute_contact_on_penetration: true,
            ignore_origin_penetration: true,
        },&SpatialQueryFilter::default(),&|entity_found| {
            if entity_found == entity {
                return false
            }
            true
        });

        if let Some(shape_hit_data) = shape_hit_data {
            controller.floor = Some(shape_hit_data.entity);
            controller.floor_normal = Some(shape_hit_data.normal2)
        }else {
            controller.floor = None;
            controller.floor_normal = None;
        }
#

wich seens wrong

sleek thicket
past cargo
#
pub fn rotate_to_ground(
    mut character_query: Query<(Entity, &mut Transform, &CharacterController), (With<CharacterController>)>,
    time: Res<Time>,
){
    for (_,mut transform,controller) in character_query.iter_mut(){
        if controller.floor == None{return;}
        let target_rotation = Quat::from_rotation_arc(Vec3::Y, controller.floor_normal.unwrap());

        let smoothing_factor = 5.0 * time.delta_secs_f64().adjust_precision();;
        transform.rotation = transform.rotation.slerp(target_rotation, smoothing_factor);
    }
}
past cargo
#

even if he is rotated

sleek thicket
past cargo
#

so how do i do it to cat down the player always?

sleek thicket
past cargo
#

its math stuff

#

i just ask small stuff here

sleek thicket
# past cargo its math stuff

predicate wasn't math, just 10 seconds of bothering to take a look at docs

direction down is just basic transform method but i guess if you started game dev with bevy then nothing would explain it to you 🤔

past cargo
#

i am game dev since 5 years but bevy coordinates are totally different from the way i was working

#

like the linear velocity

sleek thicket
#

oh you mean which way is up/forward?

past cargo
#

yes

#

i tryed Quat::from_rotation_Y

#

that should be the expected

#

but no

sleek thicket
#

you can just use whatever coordinate system you want, just keep in mind that for default stuff like methods and camera Y is up and -Z is forward

past cargo
#

for some reason just _Z works

sleek thicket
past cargo
#

okie but how enalbe the raycast debugs?

#

so i can know

past cargo
#

:/

#

thanks btw

#

but the raycast part seens correctly, its getting the floor aways

sleek thicket
#

idk if jondolf made any shorthand for that, it'd actually be useful

past cargo
#

now i just need rotate it

#

the character

#

need a formula math for it

sleek thicket
#

you're making something with anti-gravity?

#

mario galaxy battlegrounds?

past cargo
#

no

#

i just want alight on small angles

#

like when he is walking on a ramp

sleek thicket
#

i don't understand why, you'd just get player to tilt

#

with extra issues around edges

past cargo
#

so i need make it dont keep falling

sleek thicket
#

why did you decide against locking collider rotation?

past cargo
#

with angular velocity

#

rotate axis stops angular velocity to works

sleek thicket
#

you mean like that thing from very very valet tutorial?

past cargo
#

what?

past cargo
#

wydm on this tutorial there is nothing about it

sleek thicket
# past cargo wydm on this tutorial there is nothing about it

A detailed look at how we built our physics-based character controller in Unity for our game Very Very Valet - available for Nintendo Switch, PS5, and Steam
BUY NOW!! https://toyful.games/vvv-buy

~ More from Toyful Games ~

▶ Play video
past cargo
#

does it really need float?

sleek thicket
#

yep, you can just add IK legs and it should be good

past cargo
#

na never did ik iam fine

#

i will keep it not floating

sleek thicket
past cargo
sleek thicket
#

old games got around that issue by avoiding stairs/ramps and making elevation that you can only jump on, or adding stuff like "interact with stairs" that made you lose control

#

or just not allowing you or anyone else to see how characters walk up/down stairs/ramps

#

but these days idk the last time i didn't see IK for legs

deep cypress
#

I'm trying to detect collisions between a half space and a capsule, but it's reporting collisions on every frame no matter where that collider is. Seems to be related to this issue. Anyone know a workaround?
https://github.com/Jondolf/avian/issues/586

GitHub

avian2d (including release v0.1.2 and e23d070) reports collisions between non-intersecting (and in fact, far apart) half-space and rectangle (as well as other) colliders. I believe this is because ...

sweet sundial
#

is there a non-uniform scale on it?

#

is Contacts.during_current_frame handy

deep cypress
deep cypress
#

I just switched to using rectangles instead of half spaces.

past cargo
#

@sleek thicket hey bro iam trying make it float but i cant for some reason, avian does not let it happens?

#

i tryed move the child translation first

#

but just the child moves up, the collider stays on same place

#

i tryied than move the ColliderTransform

#

but nops, collider transform does not move

#

so i need try body Position?

#

nvm avian does not have body position

sleek thicket
#

@past cargo all you need to do is add velocity to collider with rb

#

and avian does have position, but you're not supposed to change it in this case

sleek thicket
#

rigidbody

past cargo
#

but keep adding velocity up isnt a problem?

#

nvm it doesnt work the way i tought

past cargo
#

@vestal minnow where is the body position link you showed me?

#

seens you deleted

chilly cradle
#

Hey @vestal minnow, is this example available anywhere? I'm trying to do something similar and am dumb and can't find anything related to attractors in the Avian GitHub repo

vestal minnow
chilly cradle
#

Sweet, I'll be digging into that now

vague pebble
#

@vestal minnow Mr Jondol, when you a load a scene collider from a mesh, what characteristic is usually necessary for the collider to be shaped correctly? For example, does it need UVs, tangents, normals? Or all it needs is the vertex locations

#

I ask because I am exporting a gltf, which it is sole purpose is to give me colliders

vestal minnow
#

Only vertices and indices are necessary for trimesh colliders since they describe the actual triangles, the rest is mostly useful for rendering

cinder summit
#

Anyone know if my estimation is correct that avian will be a pain to migrate to bevy main? 🤔

vestal minnow
#

not too bad, the biggest non-mechanical thing was probably needing to rework the AncestorMarkerPlugin to use just observers since HierarchyEvent no longer exists

#

but we wanted to do that anyway, it simplifies things and makes it more robust

#

I'll migrate Avian's main branch to Bevy 0.16 as soon as the RC is out, but that commit probably works as a base for now

vague pebble
#

If it doesnt, it seens indices and vertex are not found, reason unknow

past cargo
#

bassicaly the way roblox works is you insert one of those on the character

#

with attachments

#

and applie the force

#

its good becasue

#

you can insert multiplie

#

and have forces being applied on different parts of the body

vestal minnow
#

yeah we'll most likely have a similar thing once we have joint motors

past cargo
#

wait let me shhow you a example to be more clear

#

xd

vestal minnow
past cargo
#

about the BodyPosition, that is AlignPosition now on roblox, the idea is to make the model move for the designed position you set on it, that way we can lock the model movement, like on roblox have a lot of air combat, where you punch the enemy up and both stay on air, it uses body position to lock the Y on air, so they both can get knockbacked to the sides but stay on air on same y axis

#

the idea is be able to select the position you want it to move

#

and the forces values on each axis

#

so if you like set force 0 on y, it wont move the y axis

#

same for x and z

#

its very usefull

#

idk if you get it cause my english is bad

#

but i can show some examples if you want later

sleek thicket
past cargo
#

Wait two pings

#

Who did the other?

sleek thicket
#

i got confused by your LV demo

past cargo
#

O

sleek thicket
#

wiggling with a cursor doesn't communicate well what you're trying to demonstrate 😅

past cargo
#

Btw to rotate the player can I Just transform.translatio? Or i should use Psychic stuff?

sleek thicket
#

why do you need to rotate the player?

past cargo
#

?? Well Its 3D game so she should walk on alll directions lol

#

So I need rotate for the direciont he gonna walk

#

Transform.translation is fone?

#

*fine

sleek thicket
surreal rune
cinder summit
#

I also love that this is now just PR 1 of bevy_heavy

surreal rune
vestal minnow
#

not many external users for a mass property crate 😂

surreal rune
cinder summit
grizzled junco
#

is there example on how to use ExternalTorque? I tried to use it, but it doesn't do anything to the rigidbody.

cinder summit
vestal minnow
cinder summit
#

Whats a good 3D example for collisions? 🤔

vestal minnow
#

cubes I guess

cinder summit
#

Oh ... It really is just the character controllers wtf 😂

vestal minnow
#

for the minimal collision setup

#

Or something with collider hierarchies? Since the example loads a glTF scene

cinder summit
#

That's very possible considering you changed hierarchy code 🤔

vestal minnow
#

yea that's probably the most likely thing to be broken, tho iirc tests were passing

cinder summit
#

I don't need hierarchies to work anyway, so this should be fine 😂

vestal minnow
#

especially if this is 2D and you're using pixels as length units, you might need some very large forces and torques for things to move

past cargo
#

doesl inear velocity doenst accept negative values?

#

i put z= -10 and it goes forward lol

#

same if i put just 10

sleek thicket
#

it does, wtf are you talking about

cinder summit
white garnet
#

is it possible to advance simulation for a specific object only?

grizzled junco
cinder summit
past cargo
#

seens not

#

iam setting it positive and negative and still same direciton

sleek thicket
past cargo
#

first test 1

#

second test now -1

#

@vestal minnow what i fucked up?xd

#

nvm

#

i think i figured out

sleek thicket
#

i facepalmed so hard when i saw it

past cargo
#

i need glasses

sleek thicket
#

you need adhd meds

past cargo
#

xd

#

also i notice that some bugs happens if you set linear velocity fields to 0.0 @vestal minnow

sleek thicket
#

i don't, probably something on your end... by now you can just safely assume that every problem is on your end, tbh

past cargo
sleek thicket
past cargo
#

*capsule

sleek thicket
#

capsule would fall over

#

whatever you're doing to keep it straight might be the reason for the behaviour

past cargo
#

LockedAxes::new().lock_rotation_x().lock_rotation_z()

sleek thicket
#

ok then capsule should be fine too

past cargo
#

want take a look on code?

#

can be lightyear replicating maybe too idk

sleek thicket
past cargo
#

the issue was i need set the linear velocity to 0 when stops the movement @sleek thicket

sleek thicket
past cargo
#

that maybe because lightyear replication system

sleek thicket
#

then you have something broken that does it

#

probably input

past cargo
past cargo
#

what do you mean

past cargo
#

i mean that is not input because i dont set the linear velocity if the unit is not on walking state

#

i also printed to check

#

but i notice that the Y on linear velocity gets crazy when iam moving it

#

let me show ya

#

maybe its because its not floating xd

sleek thicket
past cargo
#
pub fn character_inputs(
    mut commands: Commands,
    mut character_query: Query<(Entity, &ActionState<CombatantActions>, &mut StatesMachine, &NetworkSide, Option<&PlayerCombatant>), (With<CharacterController>)>,
){
    for (entity,action_state,mut states_machine,network_side,player_combatant) in character_query.iter_mut() {
        if player_combatant.is_none() && network_side != &NetworkSide::Server{
            continue;
        }

        let move_dir = action_state.axis_pair(&CombatantActions::Move);

        if move_dir.x != 0.0 || move_dir.y != 0.0 {
            if !states_machine.can_execute(StatesType::Walking) {continue;}

            if !states_machine.current_states.contains_key(&StatesType::Walking) {
                states_machine.execute(&mut commands,entity,network_side,StatesType::Walking,StatesInfos{
                    start: Default::default(),
                    duration: 0.0,
                    source: Default::default(),
                    in_cooldown: false,
                    applied: false,
                    values: Some(StatesValues::Walking(
                        Vec3::new(-move_dir.x,0.0, move_dir.y),
                    )),
                });
            }else {
                states_machine.current_states.get_mut(&StatesType::Walking).unwrap().values = Some(StatesValues::Walking(
                    Vec3::new(-move_dir.x,0.0, move_dir.y),
                ));
            }
        }else {
            if !states_machine.can_execute(StatesType::Idle) {continue;}

            if !states_machine.current_states.contains_key(&StatesType::Idle) {
                states_machine.execute(&mut commands,entity,network_side,StatesType::Idle,StatesInfos{
                    start: Default::default(),
                    duration: 0.0,
                    source: Default::default(),
                    in_cooldown: false,
                    applied: false,
                    values: None,
                });
            }
        }
    }
}
sleek thicket
#

so when you release input, what happens?

past cargo
#

i can even show ya wait a bit

#

now as i said the absurds values on Y when iam moving it

#

may be the reason?xd

sleek thicket
#

when adding input you run system that adds it to velocity and replicates it
when idle, you just don't replicate it
do i get that right?
you're not commenting anything so i have no idea what you're doing

past cargo
#

if you stop press and movement inpu

#

it start the idle state

#

that stops the moving state

#

on idle state the unit doenst move with inputs

past cargo
#

the Y GIANT VALUE LOL

sleek thicket
#

isnt that 0

past cargo
#

no?

#

y is being big f numbers

#

let me show ya xd

#

considering iam not changing y

sleek thicket
#

it's probably just 0 with floating point error

#

ah, i guess walking state is triggered by it so it's still a potential bug

#

didn't rust have a warning on comparing floats

past cargo
#

cause i move the unit here

#

and its not printing when its on idle state

#

so its not it

sleek thicket
#

yep

#

0 FPEs to 0.0000000000000000000000000001
0.0000000000000000000000000001 != 0, so you're walking

past cargo
#

i can also check if you want the linear velocity when its on idle

#

let me see it

sleek thicket
#

basically you need to switch that to move_dir.length <= 0.01

#

or whatever the controller deadzone is

past cargo
# sleek thicket

hmm but you mean the move dir is wrong when iam setting it on walking?cause its not triggering walking state when i stop input

#

because this if seens pretty much working

#

let me test it

#

its not triggering the walking state

#

but aftr i stop walking

#

the linear keeps like ths

#

unless i do linearvelocity = 0

#

maybe the move dir is a very weird value

sleek thicket
#

ah fuck it's been 1 hr already

#

that'll be $30

past cargo
#

okie

#

paypal?

sleek thicket
#

i was just joking but if you're paying then i can actually go read your github

past cargo
#

xd

#

but yes bro, the walking state is not being triggets meaning the if move_dir.x != 0.0 || move_dir.y != 0.0 { is working , i checked with the printt

#

the problem is when it stops moving the linear velocity keeps crazy

#

until i set it 0

#

that can mean:
1-the capsule is not floating so maybe the values are crazy cause it
2-the move dir while waking is giving weird values
3-the y value being weird as hell is influencing the z value

sleek thicket
past cargo
#

i mean i dont do nothing while its not moving

sleek thicket
#

comment everything you're doing, i'll check your github next time if you don't accidentally find the problem yourself

past cargo
#

well still can be the the y weird value cant it?

#

or because the capsule is not floating

#

bro you are a goat fr

past cargo
#

@sleek thicket the problem was the Friction(|| Friction::new(50.0_f32)),

#

if i dont put adefault friction ,it doenst happens

cinder summit
#

Isn't friction supposed to be between 0 and 1?

past cargo
#

xd idk

sleek thicket
#

The friction coefficients should typically be between 0 and 1, where 0 corresponds to no friction at all, and 1 corresponds to high friction. However, any non-negative value is allowed.

past cargo
#

yessssssssssssssssss

#

this was the issue

sleek thicket
#

does friction above 1 just push you in negative direction? lmao

past cargo
sleek thicket
#

either way that doesn't sound right

past cargo
#

bt [] i think my character model seens inverse rotating, any easy way to see the look vector?

#

cause you guys said -z is forward

#

but z is being forward here xd

sleek thicket
#

it doesn't really matter

#

i'm using Y-forward Z-up

past cargo
#

what

sleek thicket
#

to match blender

#

you just have to keep in mind that for camera -Z is forward and Y is up

#

and X is left if i understand it correctly, idk it always makes my brain hurt

past cargo
#

lol

#

also friction zero means it will slide?

sleek thicket
#

yeah, unless you add damping

past cargo
#

and friction 1 = no slide at wall

sleek thicket
#

idk how often it's done but before hovering sphere i had 2 colliders, one with friction for legs and one without friction for body, i was mostly just copying wolfire's procedural animation stuff

past cargo
sleek thicket
past cargo
sleek thicket
#

also i've never seen that before, really cool seeing the actual prototype stuff
https://youtu.be/SAtwQa8t_3g

http://www.wolfire.com/overgrowth

I have been asked many times how the procedural animation worked in the old Lugaru 2 movement demos, so I made this video showing some of the early stages!

Check out the game site at:
wolfire.com/overgrowth

You can follow its progress on the Wolfire games blog:
blog.wolfire.com/

▶ Play video
sleek thicket
past cargo
#

nvm

#

its the high speed as f

sleek thicket
#

oh yeah you can set which one affects it

#

yeah you need environment to see what's actually going on

past cargo
#

and works now

#

slide a bit still, what is dampening as you said?

sleek thicket
#

but in this case i think you just need IK

past cargo
#

i just set the linear velocity to 0 when stop walks

past cargo
#

like to follow terrain, stairs etc

sleek thicket
past cargo
sleek thicket
#

no

past cargo
#

?

#

but the mesh model

#

have nothing

#

its just visual

#

oooooooooooooooooooooooooooooo

#

you mean to show how they are sliding

#

for ppl

sleek thicket
#

???

past cargo
#

i understand what you mean

#

but my bad english kills me

#

iam specialist with combat and spells game xd

#

first time doing on bevy

#

wish me lucky

past cargo
#

i have experience at least xd

sleek thicket
past cargo
#

i work with it

#

but now iam trying make a game on bevy as hobby

past cargo
#

combat + spells

sleek thicket
#

scripting

past cargo
#

yup

paper maple
# past cargo friction 1 still slide a bit lol

Haven't read the whole conversation, but generally rigidbody colliders dont make good character controllers on their own. You need to implement specific collision handling for characters so that they behave more like legs, rather than a rigidbody

past cargo
#

And iam moving it

#

What more should i do?

paper maple
#

Yeah but going up slopes and dealing with un-even terrain won't work out too well (at least I didn't like it)

past cargo
#

I also now iam setting the linear velocity x and y to 0 when it stops now

paper maple
#

because normal forces and sliding, etc.

past cargo
#

What should i do mr frog

paper maple
#

Legs and walking don't behave like rigidbodies at all, so sliding a rigidbody around will always feel wrong

past cargo
#

Frog senpai

paper maple
# past cargo What should i do mr frog

Well, I've been working on a character controller in 2d. I tried Tnua which does a floating body controller, but I found it to be a bit too complicated for me. When trying to implement my own, I started off with just a rigidbody capsule as well, but ran into the numerous issues that occur when going across un-even terrain. That's about when I reaized that pedal movement doesn't really match RigidBody physics

#

I tried doing a circle with infinite friction and rolling that around, and that works okay

#

But it makes other things complicated.

#

So now im working on just having a capsule shape cast (I dont actually use a Shapecaster because the system ordering doesn't work out for what I want to do with it, so I do an explicit shape cast in the system I need it for) and then resolving collisions / overlaps in a way that would feel natural as a walking entity

past cargo
#

How shape cast helps you there?

paper maple
#

Because it doesn't apply any forces or anything. It just tells me where the overlaps are happening, then it's up to me to implement how to resolve it.

past cargo
#

Well you could use kinematic rigid body instead

paper maple
#

Messed around with it and I didn't end up using it. I don't reember what issues it had, but it isn't an automatic solution.

#

I think it was because you still dont get control over how te resolve collisions, it just forces anything that overlaps with it to get pushed out of it.

past cargo
#

So, bassicaly, rigidbodys are no good for character controllers

#

To be honest you could make a rigidbody static at least so others rigidbody would collide with It @paper maple

paper maple
#

U could try the Kinematic bodies and see how that goes

#

but defnitely not Dynamic bodies

sleek thicket
# past cargo So, bassicaly, rigidbodys are no good for character controllers

in robotics doing extremely simple stuff like walking turned out to be the most difficult problem to solve
character controller is robotics where you're allowed to cheat, and everyone's failing even with that

either way i took a look at battlegrounds and i'm not even sure if it's possible without dynamic rb

paper maple
#

Uh huh yeah except the people solving it for themselves haven't spent years studying the topic ? More like 2 weeks intermittently ? I'm not sure why you feel the need to be condescending

#

Condescending and dismissive. @sleek thicket

#

nice

past cargo
sleek thicket
past cargo
past cargo
sleek thicket
#

yeah i know, roblox devs already figured out everything for you

past cargo
#

Yup

#

But yeah you cant make It fly with dynamic rb

sleek thicket
#

please don't state things you don't understand as facts

past cargo
#

Wydm

#

It have gravity that pushs down

#

Not possible lol

sleek thicket
#

do you know what gravity is?

past cargo
#

I tryed set the y to 0.5 every frame

#

I mean i tryed set the linear velocity y to 0.5 every frame

sleek thicket
#

not in game dev, just tell me what gravity is

past cargo
#

A force pushing you down

sleek thicket
#

ok that's good enough, so how do birds fly irl if there's a force pushing you down that makes it impossible to fly

past cargo
#

So you mean the linear velocity y need be the same force as the Gravity?

#

If its higher It Will fly

#

If its lower it wont fly

#

If its equall It Will float

paper maple
sleek thicket
paper maple
#

but that part only matters when they actually collide with things

sleek thicket
#

you can also just disable it altogether and apply it manually like how many games do it to make jumping/falling feel better

past cargo
past cargo
#

@paper maple i think you could Shapecast sphere down the character like 10% bigger than current Sphere, If It find some floor you Already make it up

sleek thicket
past cargo
#

Btw just to make sure again, why It need floats?

#

Also How would i make something fly and stay on a determined y axis? Cause if the Y is much bigger It Will feep flying forever

#

And going up

#

Since there is no body position forces on avian

#

Or i would need make my own gravity for the character?

sleek thicket
past cargo
#

I did my english is bad

#

And I forgot ir

#

It

#

Xd

#

Well iam gonna keep trying

grizzled junco
#

im really curious why one of my game object has (Position, Rotation) without me inserting it, but not the other

#

both have rb

#

and i think rb doesn't have Position and Rotation as its required components

kind moss
grizzled junco
#

it's not really a big concern right now, but it's just annoying when i think about it

#
match (has_rigid_body, new_transform) {
    (true, None) => {
        cmds.try_insert((
            Position(new_position),
            new_rotation,
            PreSolveAccumulatedTranslation::default(),
            *previous_rot.unwrap_or(&PreviousRotation(new_rotation)),
            PreSolveRotation::default(),
        ));
    }
    (true, Some(transform)) => {
        cmds.try_insert((
            transform,
            Position(new_position),
            new_rotation,
            PreSolveAccumulatedTranslation::default(),
            *previous_rot.unwrap_or(&PreviousRotation(new_rotation)),
            PreSolveRotation::default(),
        ));
    }
    (false, None) => {
        cmds.try_insert((Position(new_position), new_rotation));
    }
    (false, Some(transform)) => {
        cmds.try_insert((transform, Position(new_position), new_rotation));
    }
}

https://github.com/Jondolf/avian/blob/0474c721040582caa304dc70ddce4c53faca250a/src/prepare.rs#L312C1-L338C10
also it's using try_insert but im not sure if that's actually matters

vestal minnow
#

worked a bit on Peck yesterday, got rectangle-rectangle contact manifolds with SAT and clipping working I think

#

now I could theoretically plug this in Avian to simulate box collisions without Parry :P

#

I'll test that later tho

vestal minnow
past cargo
#

i see

vestal minnow
#

it was built primarily for Rapier, but can be used independently

past cargo
#

pls bro make body position, will make float so much easier xd

#

rn i need keep controlling character gravity scale to make it float

#
  • linear velocity y
grizzled junco
#

there's Position component though?

past cargo
grizzled junco
#

what do you mean by body position

past cargo
grizzled junco
#

even in that reference it said deprecated

#

also I'm not sure avian should add that kind of feature in the engine

#

not like i know avian long-term goal

past cargo
#

that does the same

#

but you can focus the point it will move

#

with a attachment

past cargo
#

this is essential to make fly for example

past cargo
#

na bro, make it float is dumb, the math is not mathing

#

i will f ignore it for now until jondol make body positio

grizzled junco
past cargo
#

to make fly now its almost impossible with dynamic body

past cargo
grizzled junco
#

seems like i misunderstood the description

#

yeah that sounds useful in more cases than i thought

past cargo
#

yup

sleek thicket
#

BodyPosition is a cursed name for that, AlignPosition is better but still not immediately obvious
if you know what it's called in other engines then link it, might be useful for future bikeshedding

vestal minnow
#

we do have a DistanceJoint which could be used for a kind of similar effect, you'd have a static or kinematic body for the target position and constraint the other body to that via the joint

#

not quite the same as what that thing in Roblox is though

sleek thicket
#

yeah, i think it affects rotation when pulling? idk about roblox though

#

oh nvm if it's not center then it does

past cargo
#

called AlignRotation

sleek thicket
#

not aligning, just affecting

past cargo
vestal minnow
sleek thicket
#

like when you try to pull head to the ground, body bends over

#

instead of just getting stuck

past cargo
#

i mean the issue rn is not able to make character controller with dynamic body lol

#

its just over complicated

#

like

sleek thicket
#

i have a floating dynamic controller with coyote time working with alignment to custom gravity working in 10 lines of code if you don't count the boilerplate and the cursed camera, but i can't send it to you because your netcode would break it

past cargo
#

i wanted see the direction iam shapecasting

sleek thicket
#

i don't understand why you'd need it without custom gravity though, it goes exactly where you tell it to and you're not even changing it

grizzled junco
sleek thicket
#

distancejoint isn't perfect either, assuming it does exactly the same thing

grizzled junco
#

i don't think there's a perfect name, but i just don't like BodyPosition / AlignPosition

vestal minnow
#

or Bepu's DistanceLimit

#

or Jolt's DistanceConstraint :P

sleek thicket
#

@vestal minnow would splitting joints into required components make no sense?
every joint has 2 entities, 2 anchors, lin+ang damping, compliance and force, and position lagrange and exact same docs

and would distancejoint be any different from fixedjoint if making rest_length optional meant that it's same as distance between anchors?

#

and are you planning on turning joints into relationships

vestal minnow
#

FixedJoint aligns both translational and rotational degrees of freedom, some engines call it a weld joint

sleek thicket
#

oh, 🤔

vestal minnow
#

I imagine we'll also want to have a split between the user API for joints and the internal representation, since using the ECS for solver internals isn't great for perf or determinism atm

#

(currently joints can cause determinism issues in some cases because of query iteration order)

past cargo
past cargo
#

since the parameters are very weird compared what ik

sleek thicket
past cargo
#

like this mask stuff

#

its working oposite the way it should? its black list or whitelist?

#

cause i made the floor Default layer

#

and i tryed make floor on this mask

#

but when i do it starts ignored the floor lol

sleek thicket
#

can you read what it says in the tooltip for me

past cargo
#

Specifies which collision layers will be included in the spatial query, wich means for me it will just get stuff inside on this layer

#

that doenst happens

#

the oposite happens lol

#

this make me hella confused

sleek thicket
#

default is 1 so it should work.
as usual, you can safely assume it's something on your end.

past cargo
#

default is 0

#

the floor is on Default layer

sleek thicket
#

you're not using gamemask here though

#

and the default avian layer is 1

past cargo
sleek thicket
#

does .into() work? i don't use physicslayer at all so idk how it's done with it

past cargo
#

i also need get the bottom point of the character collider to calculate the floating distance

sleek thicket
past cargo
#

from works dont worry

#

now i need get the bottom position of the collider

sleek thicket
past cargo
#

to be honest i wanted to know the capsule height size

#

@sleek thicketi but capsule just have a .radius

#

not .height

#

nvm it have

#

now it make all more ez

past cargo
#

@vestal minnow something is wrong here, the floor is on transform 0,0,0, the height is 0.1, means the top of it would be y = 0.05 (that is height / 2), until now fine, but my entity collider is height 1, means to stand on top of the floor the y would need be 1 / 2 + 0.05 = 0.55, but for some reason its 0.85 to stand on top, like wtf?

#

or on bevy the translation is not the center?

vestal minnow
# sleek thicket you mutate everything as you iterate?

joints are currently solved by iterating through all joints serially, but the query iteration order can be different depending on Entity IDs (and probably some other factors) which can cause problems for networking since the IDs may not be stable across clients afaik

#

and different constraint solve order can result in different behavior

vestal minnow
past cargo
vestal minnow
#

the height is the height of the cylindrical part between the hemispheres, add 2x the radius to get the total height

#

so if the capsule has a "height" of 1 and the radius was e.g. 0.25, the actual full height is 1.5

past cargo
#

so the 1 + 0.3 * 2 = 1.6 height, 1.6 / 2 = 0.8 + 0.05 = 0.85

#

now math is mathing

past cargo
#

doenst it seens unecessary?

vestal minnow
# past cargo why this approach btw?

There's a lot of reasons:

  • Bevy's Capsule2d and Capsule3d and their meshes are defined like this
  • You could get impossible configurations if the radius wasn't added. For example, a capsule with a height of 0.5 and radius of 0.3 would be invalid, since the radius would make the height at least 0.6.
  • Mathematically, a capsule is often defined as a cylinder with hemispherical ends, or as a line segment that is expanded by some radius (using the Minkowski sum). With either of these definitions, it's pretty intuitive to represent the capsule with the height or length of the cylinder or line segment, and a radius.
  • The representation is better for many calculations and algorithms
cinder summit
#

Pff, clearly capsules are defined as distance away from a line segment thonk

past cargo
#

it floats 0.1 studs

#

from floor

#

while the character model still correctly on floor standing

#

with dynamic body

vestal minnow
past cargo
#

okie, now i need see how iam raycasting to get the floor correctly

#

my plan is raycast from capsule top and goes down to get the closest floor

#

if the floor normal 1 is to big so its not auto step

#

if its small the diferecence so i auto step

#

well if it follows roblxo shape cast logic

#

it wont detect nothing that is inside the ray when its casted

#

so i wont have this problem

#

its excluded already

#

combatants are on a different layer

#

i dont want get combatants as floor lol

sleek thicket
past cargo
#

they should slide