#Avian Physics

1 messages · Page 29 of 1

vestal minnow
#

You might even be able to do this actually

ship.0.rotation =
    Quat::from(Rotation::from(ship.0.rotation).nlerp(Rotation::radians(angle), 0.25));
golden python
#

https://cdn.discordapp.com/attachments/1334796607321018420/1335202640610463824/movement_shooter_df8cSjQ55U.mp4?ex=679ff89c&is=679ea71c&hm=2132936df5daca4bca2f8118248d971d30e5b27aa9691904f1d84e53a77b2393&

Hello, I'm having trouble understanding the problem here.
My character has no problem jumping over that box, but when I run into the box and jump I just much lower.
I removed all friction and set the friction to ZERO with CombineCoefficient(Min).

I am using a kinematic body with the default collision code from the kinematic character controller

wispy lance
#

LinearVelocity is good for character controllers right?

#

why does avian use its own vectors and for 2d there is no z?

winged frost
sleek thicket
sleek thicket
winged frost
sleek thicket
winged frost
#

😮 I landed on the same collision epsilon. Thank you!
Mine is in 2D, I had to increase collision_epsilon from (f32::EPSILON * 50) to (0.01) to avoid clipping on sharp edges. Why do sharp corners need extra caution? Is it float precision errors?

vestal minnow
#

The character controller there is not good though, typically you would want a proper collide-and-slide algorithm for kinematic characters

#

Based on basic profiling yesterday, it looked like Query::get_many_mut in the solver is costing us more than the constraint logic itself 😬 get_unchecked was slightly better but still dominates performance

#

I probably need to double-check though, it seemed weirdly bad

#

We will probably move to storing separate SolverBody structs outside the ECS for the critical solver loop anyway though, which should hopefully fix this partially

wispy lance
#

so when using linearvelocity, and 2 objects collide, for some reason they rotate? i dont have any code that does the rotation, it rotates as if there was friction (which there probably is, so how do i disable that)?

vestal minnow
wispy lance
vestal minnow
#

There should be a DefaultFriction resource that you can set to configure default friction globally

wispy lance
#

the constant doesnt exist

vestal minnow
# wispy lance if i was to use a kinematic body how does it not fall through the floor? I wante...

Kinematic bodies are like static bodies in that they have basically infinite mass and therefore don't respond to collisions, joints, etc. but unlike static bodies they can be moved and have velocity. This is the same as in other engines. Typically you'd have something like a collide-and-slide algorithm for kinematic character controllers to move them and handle collisions, there's a few implementations floating around here but no built-in thing yet

vestal minnow
#

should probably add the constant for DefaultFriction directly too though

wispy lance
#

thank you for all the help :)

vestal minnow
#

happy to help 🙂

vague pebble
#

@vestal minnow Mr Jondol, I am making a hitbox for my melee weapon. The hitbox usually follows along the movement of the bone. In this case, question tho. How can I spawn a tri mesh that follows along a scene?

tribal hazel
#

hi just implementing a basic collide and slide (this might be me being dumb)
i have a part where i'm shapecasting down the slide velocity to detect any second walls to stop at but i don't seem to be detecting them.
i've got a blue gizmo to show the character "collider" and the green gizmo is the end of the slide velocity cast.

winged frost
#

I'm using move_and_slide for a top-down 2D controller. To push dynamic objects, I increase their velocity when the player collides with them. However, objects with high linear damping slow down too quickly, causing jitter when the player catches up to them

My plan is to fire an event when an object is pushed, storing its original LinearDamping in a HashMap. While pushed, damping is set to 0.0, and once released, it’s restored. Does this approach make sense, or is there a better way to handle this?

cunning gust
#

Do raycasts ignore the parents of their parent entities by default if they're set to ignore their parent?

tribal hazel
vestal minnow
#

It should pick the closest hit, but for penetrating cases it might be arbitrary 🤔 taking a brief look at the code it doesn't seem like it considers penetration depth to prioritize hits

vestal minnow
tribal hazel
vestal minnow
#

a bit more expensive and complicated but might work?

tribal hazel
#

although it'll still have issues on slopes because it'll return the hit on the slope first so i need to rotate to account for that

weary hornet
#

If I may make a suggestion, one thing that always burns me with Avian is how for ex: Collider::cuboid() takes in full size values, but Bevy's Cuboid takes in half size values.

It would probably make more sense to make it use half size too? It just feels unexpected

#

I understand that would be an annoying change but might be for the better

vestal minnow
#

The collider constructors match the shape constructors, not internal representations

weary hornet
#

wth ok im just crazy

#

ignore me

#

I dont know why I havent been using new... embarassing lol

cunning gust
#

does it then exclude its parent's parents?

vestal minnow
cunning gust
vague pebble
#

@vestal minnow I think I used too much polygons here right? HOHOH

viral goblet
#

I'm not sure how to use num_subdivisions
I looked it up in the server and it seems like nobody ever asked about it?

lime lynx
#

So I have a body that I've assigned a LinearVelocity, and am getting the GlobalTransform of. When I log and plot the components of the LinearVelocity (vx, vy, vz) * a delta_t (from Time<Virtual>) vs. the actual GlobalTransform's global_transform.translation(), everything lines up.

However, when I do something like get the heading from global_transform.rotation(), then doing something like linear_velocity.length() * sin(heading) and linear_velocity.length() * cos(heading), I'd expect that the resulting values are the same as in LinearVelocity vx, ,vz. However, I'm seeing (meaningfully) different values there. This leads to a very different overall position plot that the one from either GlobalTransform directly (as propagated by the physics plug-in) or my integration via LinearVelocity * dt. Is this expected? Am I missing something/doing something dumb?

earnest patrol
#

@vestal minnow forgive me if this is documented somewhere, but have you thought about how avian could fit into a networked physics scenario? I'm thinking about things like rewinding world state and re-running simulation steps with "past" inputs.

EDIT: just found an example using lightyear: https://github.com/cBournhonesque/lightyear/tree/main/examples/avian_physics

GitHub

A networking library to make multiplayer games for the Bevy game engine - cBournhonesque/lightyear

wispy lance
#

does linearvelocity component already multiply everything with delta time?

wispy lance
#

how can there be friction?

mild stump
spiral nymph
vague pebble
#

Besides that if you base your character controller on floating point characters and just use sensors you can circumnavigate that issue

vestal minnow
# viral goblet I'm not sure how to use `num_subdivisions` I looked it up in the server and it s...

I'm not 100% sure how it works since the actual logic is implemented in Parry, and Avian just passes the parameter forward to it. I think for something like a circle though, it just corresponds to how many segments or vertices there are, for example with 6 subdivisions you'd get a hexagonal shape. Similarly, for a cone or cylinder, the base(s) would have 6 vertices. For spheres or capsules it might be more complicated, and it'd presumably control the resolution for both phi and theta (two angles used for constructing the round surface)

wispy lance
vestal minnow
#

If you're asking in the context of Collider::set_scale, note that scale for colliders on entities is set by the Transform scale, so using the method might not do what you expect

true hearth
# wispy lance

I'm not sure I see the friction being applied in the video. What exactly is going wrong in the video?

wispy lance
#

in the image on the left you see its Zero

true hearth
#

Do you mean how the objects push each other around? It looks to me like the bodies are moving into each other, which pushes them independent of whether friction is applied or not

wispy lance
vestal minnow
wispy lance
vestal minnow
#

You don't, no

wispy lance
#

okay

vestal minnow
#

Unless maybe if you're applying acceleration since the SI unit for that is meters per second squared

true hearth
wispy lance
vestal minnow
true hearth
wispy lance
vestal minnow
vestal minnow
#

You can still override it for individual entities by adding LockedAxes for them manually

#

i.e. to allow rotation you could add LockedAxes::new()

wispy lance
#

i dont think the method takes that in

#

oh

#

i forgot the _with

sleek thicket
viral goblet
#

How do usually debug your colliders?
Using a circle gizmo for a circle collider is trivial, but what about capsules?

vestal minnow
true hearth
viral goblet
true hearth
#

think this was added in 0.14

#

(ok no it was 0.13)

lime lynx
vestal minnow
#

I assume the "heading" is meant to be the direction the body is moving but the rotation doesn't necessarily tell you that, unless this is for like character movement or a car where you move in a specified forward direction

lime lynx
# vestal minnow I assume the "heading" is meant to be the direction the body is moving but the r...

Oh, sorry! So basically at the end of a simulation, I'm trying to calculate where the body was at a given point in time using the linear velocity information and heading, then compare that to the simulation's actual position information as a ground truth. I was trying to get the body to move like a car, which I'm doing by applying all the forward movement force being in the body's frame by gt.forward() * force

#

I sort of assume that the "compass" on the body is always correct, but if I was calculating speed via wheel rotations/odometry (linear velocity in the vehicle's direction of travel), can I still do a decent estimation of where the vehicle was compared to the sim's groundtruth?

true hearth
#

this still doesn't seem like the body velocity is necessarily aligned with it's global rotation

#

only the force is, which when integrated over various orientations, will result in a velocity direction that can be different from the cars rotation

lime lynx
#

Hmm, that does make sense. I have some drag that I thought might cancel that out, but maybe the solution is assume really good traction, and do something like lv = lv * gt.rotation() on each timestep so that linear velocity is conserved, but always in the direction that the vehicle is traveling?

true hearth
#

If you want to "simulate" the full motion, you can just integrate the velocity, i.e.

velocity += forces / mass * dt
position += velocity * dt

which requires that you also consider that drag in the forces

#

if you constrain the physics so that drag is really strong such that any motion that is not aligned with the rotation immediately is cancelled, than the simple approach should align closer, yes. Though I think I'm still not sure what you're ultimately trying to accomplish

lime lynx
#

I'm sort of trying to avoid simulating all the physics, because I think that's what Avian already does? Basically using a subset of values to back out overall position

So I'm doing some simple robotics, and I have a compass on the vehicle and a way of measuring/estimating forward velocity (i.e. wheel speed -> n m/s). I'm developing a sim for some of the behavior stuff (like going from point A -> point B), and am using a Bevy sim to try to develop the code responsible for estimating where I am in the world

true hearth
#

Yeah I guess I don't know for what reason you're trying to approximate what avian already does, so it's hard for me to judge what approach would be best for you

#

usually, car games explicitly allow for the velocity not always aligned with the car rotation, so drifting is possible

#

Ah ok, starting to understand

lime lynx
#

So if I can develop some code using the inputs that I have (direction, speed) and some simplifying assumption (linear velocity is basically conserved), then when I take the code out of sim, I can still estimate the vehicle's position. Before I do that, though, I'd like to double-check that the math I'm using is correct, so I'm trying to ground-truth the code I'm using to estimate position based on my inputs to the full Avian-simluated physics one

true hearth
#

In that case, your initial approach does seem to make sense. How accurate it is then depends on how closely your simulation is aligned with just a heading aligned velocity, but there might be an implementation issue somewhere ofc.
In your case I would do things like add debug gizmos to plot all your orientations and velocities, and maybe intermediate position predictions and stuff like that and see if things make sense

#

it's hard to judge without the full code what might be going wrong

lime lynx
#

Gotcha! Do you happen to know if Avian PhysicsDebugPlugin (I forget if that's the right name) has that functionality? Or should I maybe just start ground-up with something like bevy_gizmos?

true hearth
#

I think the Plugin by default shows all colliders and things like avian shapecast components etc.
I would definitely use custom gizmos to debug your own simulation logic though

#

because then you can draw all the custom vectors and positions that you use in the simulation separate from avian

lime lynx
#

Awesome, I really appreciate the advice 🙂

true hearth
#

np, glad to help

#

also, make sure to use the correct delta time. if you use a custom loop then it should be straightforward, but if it's a repeating system you need to make sure that the delta time is the correct one for the schedule. (For Update it should just be Res<Time>::delta_secs though). There is also Res<Time<Fixed>> for FixedUpdate

past cargo
#

iam using a capusler collider and its seens its not centered on the model, its possible to change the collider transform?

#

its floating lmao

#
 commands.spawn((
        SceneRoot(
            asset_server
                .load(GltfAssetLabel::Scene(0).from_asset("Basic.glb")),
        ),
        RigidBody::Dynamic,
        Collider::capsule(1.0, 0.0),
        Player,
        Transform::from_xyz(0.0, 0.5, 0.0),
    ));
vestal minnow
#

Why does the capsule have a height of zero?

#

I think that should technically be equivalent to a sphere since it only has the radius

#

You can transform colliders separately from the mesh though by making the collider (or the mesh) a child entity and adding a Transform to that

past cargo
#

make senses, thanks mate

#

you are goat

sleek thicket
#

@vestal minnow i thought you already changed default layer to 1, why does gltf still spawn as 4294967295

#

and adding layer component still doesn't change anything v_v

vestal minnow
#

is that filters or memberships?

#

filters include all layers

sleek thicket
#

should be mem.. sec

vestal minnow
#

memberships only the first

sleek thicket
#

yeah it's memberships

vestal minnow
#

oh ColliderConstructorHierarchy apparently still defaults to CollisionLayers::ALL thonk

sleek thicket
#

filter is same

vestal minnow
#

are you using that?

sleek thicket
#

yeah

#

what's the other option i have rn

vestal minnow
#

for now you could do .with_default_layers(CollisionLayers::default()) lol (for the collider constructor thing)

#

I'll open a fix for this asap though

sleek thicket
#

yep that works

#

probably going to keep it just so i can change filters later

vestal minnow
light sundial
#

Is like the general Avian thread?

#

I have a weird niche use case I'm working on and I want to get a local copy of avian3d in my project directory so I can experiment with making my own workaround

#

git cloning the avian directory does not seem like what I want but I don't know

#

found cargo-download nevermind

#

😄

light vessel
#

Is it possible to convert a Vec<CollisionLayers> into the LayerMask that "memberships" and "filters" expects? Kinda a rust noob but would I need to implement "From" for Vec<CollisionLayers> somehow, I'm imaging looping and doing bitwise Ors through the Vec in some kind of collector?

#

For reference this is what I'm trying to accomplish and then pipe into the collision layer targets.

pub enum DamageSource {
    Player,
    Enemy,
    Environment,
}
impl DamageSource {
    pub fn to_collision_target(&self) -> Vec<GameCollisionLayer> {
        match *self {
            DamageSource::Player => vec![GameCollisionLayer::Enemy],
            DamageSource::Enemy => vec![GameCollisionLayer::Player],
            DamageSource::Environment => {
                vec![GameCollisionLayer::Enemy, GameCollisionLayer::Player]
            }
        }
    }
}
vestal minnow
#

producing CollisionLayers that has all memberships and filters of the elements in your Vec<CollisionLayers>

light sundial
#

Good old |=

light vessel
#

see this is magic I could have never cooked up ty ty

viral goblet
#

Could it be that I can only use collider_name.set_scale in a specific timing or something? I use it but the default physics plugin overrides it

viral goblet
#

Wait is it automatically connected to Transform.scale

vestal minnow
viral goblet
#

Ohhh
Thanks

#

Is there a way to override that?

#

(I don't need it right now, just curious)

frosty cradle
#

Do child Colliders inherit the CollisionLayer of the ColliderParent, or is it set to the defaults if I omit CollisionLayer on the child collider?

#

Seems like they're not inherited on closer inspection and I got things working.

past cargo
#

@vestal minnow its possible to see the colliders?

#

its ahrd to figure out hwo stuff are working

true hearth
#

so basically you can do app.add_plugins(PhysicsDebugPlugin::default());

past cargo
#

thanks sir

turbid mango
#

Hey 👋 Getting this bug where some dynamic objects (mostly those with FixedJoint or RevoluteJoint constraints) suddenly "disappear" (but it turns out their physics state is getting filled with NaN). I can't reproduce it 100% exactly, but it seems to happen more frequently with objects that are really wide in one axis and really narrow in another, or when multiple objects of very different sizes interacting with each other.

I have a revolving door made out of a few dynamics objects tied together with FixedJoints and RevoluteJoints around a pivot kinematic object that is particularly problematic, and I managed to make the bug happen semi-consistently by cutting up one of the door panels into smaller pieces of odd shapes/angles. (All Colliders are convex hulls)

I've managed to track down what I believe is the first occurence of a NaN to here: https://github.com/Jondolf/avian/blob/c4840ddf4a3adb081bb21c992e524231df83e195/src/dynamics/integrator/semi_implicit_euler.rs#L135

Adding this line below it:

            if !delta_rot.is_finite() {
                panic!("ang_vel = {ang_vel}, scaled_axis = {scaled_axis}, delta_rot = {delta_rot}")
            }

Makes the app panics with the following output:

hread 'main' panicked at contrib/avian/crates/avian3d/../../src/dynamics/integrator/semi_implicit_euler.rs:143:17:
ang_vel = [-8648430700000000000000, 2211794600000000000000, 4786264000000000000000], scaled_axis = [-22521959000000000000, 5759882400000000000, 12464231000000000000], delta_rot = [NaN, NaN, NaN, NaN]

Which seems to indicate that something is making the angular velocity reach incredibly high values (numerical instability?) that then produce the NaN, but I haven't been able to find out where exactly that might be happening.

winged frost
#

Anyone with a physics-based player controller tweaking FixedUpdate timestep?
I used a transform-based player controller for precision since physics felt unresponsive for a bullet hell. I wrote a long but working solution for physics interaction (get close and apply external force), but I just realized that I can increase the timestep and go fully phyiscs for the player controller, why is this a bad idea?

turbid mango
#

Proposed fix for the issue described above/captured in the video

#

Can't really vouch for the “correctness” of the approach, but since MaxLinearSpeed and MaxAngularSpeed are already non-physically realistic, it should hopefully be fine?

worldly cove
#

Is there a way to modify the points of an existing collider? I have some dynamic terrain (a plane) with a collider. When the mesh changes (perhaps every frame) I remove the collider component and re-add one with ColliderConstructor::TrimeshFromMesh.

This feels inefficient, and also seems to have a kind of timing issue where objects will occasionally fall through the ground when the collider is removed and re-added.

kindred hinge
sleek thicket
# winged frost Anyone with a physics-based player controller tweaking FixedUpdate timestep? I u...

update can run anywhere from 1 fps to 10000, so even if you're multiplying by delta you'll start to teleport around at low fps
fixedupdate tries to run at usual intervals even at 1 fps, and since you don't have to multiply by delta the teleports don't happen even if something goes wrong
but tbh nobody's gonna play bullet hell at 1 fps so maybe it's not an issue either way, even if they tunnel through some bullets they'll still bump into another one D;

vestal minnow
#

I would suspect that the problem in your case is probably mostly the joints though, or how they interact with things, Avian's joints aren't particularly stable with the current implementation that is still using XPBD

vestal minnow
#

I think updating vertices would involve several other things like updating the pseudo normals and Qbvh. It would be nice if there were some methods for this though

formal galleon
#

@vestal minnow any plans for a release date for avian 0.3?

turbid mango
turbid mango
#

enforcing the speed limit continuously for all bodies during solving, even with a relatively high limit (e.g 1000) has really helped with the stability

vestal minnow
turbid mango
vestal minnow
#

Depends on the shape pair, for two spheres there's 1, for two cuboids with a face contact there's 4, for things like triangle meshes there can be more

turbid mango
#

I wonder if annotating some of it with unlikely() once that is stable would help the compiler optimize it more?

vestal minnow
#

It's also pretty likely that the constraint solver won't even have access to MaxLinearSpeed and MaxAngularSpeed after some optimizations I have planned

#

the core solver (excluding position and velocity integration) probably wouldn't access the ECS directly, but would have its own more compact SolverBody structs that have only the data required for solving the constraints, like velocity and maybe some mass properties

#

this is similar to what e.g. Rapier and Box2D do, where the solver has its own optimized data types separate from the user-facing body definition

#

which will also be relevant for AoSoA style SIMD

turbid mango
#

Hmm yeah you can then make it a much tighter loop that way, and cache-wise it will probably also help

vestal minnow
#

It should hopefully also help fix the bottleneck where Query::get_many_mut seems to be taking us more time than the actual constraint solving 🙃

vestal minnow
weary hornet
#

Seems reasonable

vestal minnow
#

There isn't that much new stuff merged that'd be in a 0.3 release yet, mainly just collision hooks, PhysicsPickingFilter, and a few fixes

#

For 0.3 I'd ideally like to get in the contact graph, better contact management and contact types, maybe simulation islands, and maybe support for multiple physics worlds (if the indexing PR gets merged)

#

and a bunch of miscallaneous other stuff

#

simulation islands might still require more work on internals so we'll see

#

In general I'm focusing more on the collision detection and solver internals atm since a lot of it is implemented in a pretty naive way in terms of performance

turbid mango
vestal minnow
#

The plan is to migrate to an impulse-based solver for joints, like what contacts already use. It probably wouldn't help much with mass ratios, but might be more stable in other ways, and would make joint motors, predictive limits, and better stiffness tuning (with a frequency and damping ratio) easier to implement

#

For solving entire chains, there are solvers using reduced coordinates like Featherstone's algorithm

#

solvers like that are pretty rare for game physics and more expensive than the standard iterative solver, but Rapier does support it with its multi-body joints, and PhysX also has its articulations which are similar

#

I don't have immediate plans to add multi-body joints / articulations, but they would be cool to have eventually

#

(Box2D, Jolt, Bepu, etc. don't have them either afaik)

turbid mango
#

BTW, in this part of the code, if one of the bodies is static, or has a higher dominance, isn't their part of the impulse "lost"? Would it make sense to have an else that applies the remaining impulse to the other body instead? Effectively treating it as if it had infinite mass/inverse mass of 0?

vestal minnow
turbid mango
vestal minnow
#

or like the impulse is the correct impulse and it is theoretically applied to the static body too, but since it has infinite mass, it does nothing to it

#

the inverse mass returned by effective_inverse_mass is zero for static bodies

#

and kinematic bodies, and bodies with locked axes

#

I'm not sure if dominance is handled correctly though 🤔 might not be

turbid mango
#

oh since it can't know ahead of time what other body it will be interacting with, and can't change the effective inverse mass

vestal minnow
#

one way to handle this could be to store the effective inverse mass and inertia for each body in the constraint itself, initializing them in generate based on which body is static or has higher dominance

#

this would also remove some branching and make it so that it's only computed once per time step, not per substep

#

at the expense of maybe a bit more memory usage

turbid mango
#

but it will still be calculated multiple times per object if it appears in multiple contacts, instead of just once at the computed mass level?

vestal minnow
#

once per constraint between two bodies, but only in ContactConstraint::generate (which is before the substepping loop) and not in warm_start, solve, and apply_restitution (which are inside the substepping loop)

#

no that doesn't make sense nvm

#

we just need to change ContactConstraint::generate to consider dominance for the masses I think

#

the other methods don't really care about the mass of the other body since the effective mass was computed already

oak vigil
#

Hey, I'm using Time<Virtual> to control the simulation speed in my game. I synchronize Time<Physics> with it using this system:

fn update_physics_speed(source: Res<Time<Virtual>>, mut physics: ResMut<Time<Physics>>) {
    physics.set_relative_speed(source.relative_speed());
}

This works, but I'm noticing on higher speeds (like 8x), avian2d starts causing major performance spikes.
I ran a profile and this seems to be because avian2d is running a many substeps during that frame, which makes sense...
But I'm wondering if there is a solution? Is there a more correct way to synchronize physics/virtual times which doesn't cause this issue?

#

Substeps exapnded:

vestal minnow
#

(by "substeps" I mean the substeps taken by the physics solver)

#

You could scale down the fixed time step inversely proportional to your sim speed, so 64 Hz at a speed of 1, 32 Hz at a speed of 2, and so on. But this can make the simulation drastically worse once the frequency is low enough.

cinder summit
vestal minnow
#

Yup

#

For sped up simulation your choices are basically

  1. Run physics more frequently, keeping consistent and stable behavior, at the expense of worse performance
  2. Run physics at the same rate as before, keeping performance roughly the same, at the expense of worse simulation quality and behavior being dependent on the simulation speed
cinder summit
#

There is also the option of not actually speeding up the simulation, and instead having things move and accelerate faster, which has the benefits of being predictable and efficient, but requires a lot of extra engineering work and creates a lot of room for bugs

#

I guess this is one of those cases where there are 3 things you want and only get to choose 2 :')

#

fwiw in my game I just speed up the whole simulation, since it's essentially free and I shouldn't need more than a few % to keep things in-sync, and running ~70 ticks/s instead of 60 ticks/s is nothing when I also run like 14 ticks of rollback each frame 😂

vestal minnow
#
  1. Run the simulation on a generative AI that just predicts what happens ferris_spooky
cinder summit
#

Or without the AI: extrapolate the effect of one tick by multiplying the changes by 8 ... Things definitely won't ghost trough walls all the time 😂

vestal minnow
cinder summit
#

I bet they still lost to bepu 😂

vestal minnow
#

it's more than just physics though

vague pebble
#

Man I swear to god if I import one more godamm parry3d hashmap not wanting too I am gonna shot myself

vestal minnow
#

lmao why does Parry of all things re-export a hash map

#

oh it's for determinism I think 🤔

cinder summit
#

Guess we have a new avian meme now 🤔

vestal minnow
#

what's a good keyboard shortcut for toggling the visibility of the diagnostics UI thing in examples?

#

I'm currently using Alt+P but idk if that's weird

#

just P is for pausing already

cinder summit
#

I don't think there is much of a convention for hiding UI ... I've seen some games do ctrl + H ... Which seems rather arbitrary too 😂

#

Some examples also just throw everything on F1-12

vestal minnow
#

maybe I'll do Ctrl+P (P for profile)

#

though in browsers that's for printing lol

cinder summit
#

Not just in browsers, Ctrl + P is for printing in any app that supports it I'm pretty sure

vestal minnow
#

mm yeah

cinder summit
#

Could just do U for UI thonk

vestal minnow
#

I'll probably do that lol

#

I think I'll have a smol text in some corner to display the keys anyway

cinder summit
vestal minnow
#

it's like this atm

#

(diagnostics UI defaults to hidden)

cinder summit
#

Not a big fan of the quotes but that seems fairly unintrusive 🤔

vestal minnow
cinder summit
#

Might even make sense to flip it, you want to know the key for pause/unpause, not the function of P

vestal minnow
#

hmm Bevy examples tend to have it in this order

#

for example

sleek thicket
#

doesn't look like there's anything new since GDC 4 years ago

sleek thicket
vestal minnow
#

these keybinds are just for the examples so there's no risk of conflict for actual apps, so I'm keeping it simple with just single keys

sleek thicket
#

i guess it's easy to rebind though

vestal minnow
#

I'm writing the PR description rn so it'll be up Soon™

vestal minnow
turbid mango
#

Would something like ExternalLinearAcceleration and ExternalAngularAcceleration make sense? To easily produce these accelerations externally without having to care about mass?

vestal minnow
#

Yeah I've been considering something like that as part of a force API redesign I've been experimenting with

turbid mango
#

It's straighforward enough to implement via a system, but sometimes you just want to set it and forget, kinda like gravity

vestal minnow
# turbid mango It's straighforward enough to implement via a system, but sometimes you just wan...

IIRC my latest design from when I was last playing around with force stuff basically had ConstantForce, ConstantTorque, ConstantLinearAcceleration, and ConstantAngularAcceleration. Additionally, there's a ForceHelper system parameter with methods like

  • add_constant_force
  • add_constant_center_force
  • add_constant_torque
  • add_constant_linear_acceleration
  • add_constant_angular_acceleration
  • apply_force
  • apply_center_force
  • apply_torque
  • apply_linear_impulse
  • apply_linear_center_impulse
  • apply_angular_impulse
  • apply_linear_acceleration
  • apply_angular_acceleration
  • and some more.
    The impulses would modify velocity directly, while the non-constant forces and acceleration would be applied to AccumulatedLinearAcceleration and AccumulatedAngularAcceleration components that are cleared every frame
turbid mango
#

So ConstantForce and ConstantTorque would replace ExternalForce and ExternalTorque, these two new ones would act as the mass-independent versions, and the methods are just so you don't have to care about interacting with them directly? Would persistent go away with the migration to AccumulatedLinearAcceleration?

vestal minnow
#

So "persistent" forces and acceleration would have their own components for efficient querying, while one-off versions are cleared (probably SparseSet components)

turbid mango
#

How is a non-persistent acceleration different from an impulse though? Is it just scaled by delta time?

vestal minnow
# turbid mango So `ConstantForce` and `ConstantTorque` would replace `ExternalForce` and `Exter...

Yeah ConstantForce and ConstantTorque would replace the persistent versions of ExternalForce and ExternalTorque. I don't like how the components are sometimes persistent and sometimes not, or how ExternalForce also stores torque for off-center forces. I especially don't like how impulses also optionally support persistence for some reason, that's not a thing in any other engine.

The two new components for acceleration (if we want them) would be mass-independent. ConstantAcceleration::from_xyz(0.0, -9.81, 0.0) would be equivalent to Gravity applied to a single entity. The ForceHelper on the other hand would be primarily for the non-persistent versions and impulses (so we don't need to store impulses anywhere), but the persistent/constant methods are also available for completeness

vestal minnow
turbid mango
vestal minnow
#

So you could for example apply different gravitational accelerations from nearby planets every frame without manually accumulating and clearing

turbid mango
#

So if you have an acceleration of (384.0, 0.0, 0.0) without persistance, and the default substeps, it would be first divided by 64 (producing (6.0, 0.0, 0.0)) then divided by 6 (producing (1.0, 0.0, 0.0)) then after applied 6 times in the substeps it would be cleared

vestal minnow
#

Yeah that seems correct

turbid mango
#

So I'm just going to make them fall sideways

sleek thicket
winged frost
winged frost
#

no 👀

vestal minnow
#

Merged the physics diagnostics PR! I've been wanting to work on other things so bad lol, just wanted diagnostics first to make profiling some things easier and more reliable

turbid mango
kindred hinge
#

Sorry if I'm missing a whole chunk of code/documentation that's already available, but I think the position is that there's not any simple way to bind together a scene that's been loaded into Bevy (from gltf say, complete with rigging) with Avian, is there? I guess what I'm envisaging is a way to import Avian components and Avian joint entities, and to map them to the gltf entities. (I assume there's no way to define Avian components and joints in gltf, is there?) Does that make sense as a goal? But there's nothing out there that can help with that currently?

To be specific, I'm envisaging importing a rigged car model from blender, importing a compatible but not specific avian model from some other file format, importing a mapping file that binds the two together, and then using some sort of plugin to merge them into a Bevy scene, instances of which are easy to spawn? Feasible but not yet on the roadmap? Or am I missing something?

vestal minnow
# kindred hinge Sorry if I'm missing a whole chunk of code/documentation that's already availabl...

There's ColliderConstructorHierarchy for generating colliders for entire hierarchies (like glTF scenes) at runtime, but nothing for joints. With Blenvy you might be able to set up joints in Blender too, but I haven't tried that

#

You can use most of Avian's components in glTF, that's what me and @janhohenheim did for Crazy Bike for the last Bevy game jam

#

the map and NPCs etc. were defined in Blender with Blenvy

#

One limitation is that you can't use Collider directly in Blenvy since it's not Reflect, but you can use ColliderConstructor for constructing it at runtime

#

eventually when Bevy has an editor, you'd of course be able to add colliders and joints to entities there too, like in Godot and Unity

river perch
#

how many more deps do avian3d need compared to avian2d?

vestal minnow
#

pretty sure it's the same number of deps as 2D unless parry3d has different sub-dependencies than parry2d

#

I think it's probably listed on crates.io somewhere

river perch
#

not sure if im seeing it correctly, but my server build has 580 deps. but its probably me who is introducing alot of stuff in addition to avian3d and lightyear. just wanted to know if there was any large difference between 2d and 3d in regards to deps. but not that it matters alot in runtime

#

thanks, thats actually a useful page for checking deps for a crate

vestal minnow
river perch
#

I see avian3d is bringing in the most of them. but its mostly bevy.

vestal minnow
#

Avian uses Bevy with default-features = false unless you bring in e.g. scenes or gizmos through Avian's features for those

river perch
#

I do actually need scenes, so thats probably the one that rises it up

#

I reduced the number of deps needed to build my project by around 50-60 deps by just enabling features flags so thats sweet. didnt even know that was possible..the minutes building from scratch kept rising as I built. didnt feel good. but thats life of game, physics and networking engines all together.

arctic fulcrum
#

I'm looking at using joints -

  • The docs on the constraint fields are a little unclear - I realized after a few scans that e.g. FixedJoint::force is just internal bookkeeping, and not something that I would configure when creating a joint. It would be helpful to clarify exactly when these "state" fields are set.
  • The local_anchor1/local_anchor2 allow for a custom local translation, but not for a custom rotation. This seems limiting - or is there some way to emulate it for e.g. allowing two entities to have a RevoluteJoint to align entity1.x and entity2.y? Could these be made into Isometry instead of just Vector maybe?
weary ember
#

I'm trying to recreate mujoco ant robot with avian and bevy to train multiagent swarm robots in bevy. The mode is simple: a body and 4 legs, 2 joints each. However I've immediately stumbled upon a roadblock: once I rotate entities the right way, and apply a joint connections, the rotation is either discarded, or resulting body receives a momentum

https://github.com/Jondolf/avian/discussions/650

GitHub

Here's how 2 objects are located relatively to each other before joint is spawned Here's what happens after joint spawn pub fn spawn_stub_model( mut commands: Commands, mut app_state: ResMu...

#

I don't need the most accurate physics like in mujoco, just something that works for a game setting

paper maple
#

RevoluteJoint isn't making sense to me. From my understanding, if body B is rotating then it should have no effect over body A, but in the example, it does.

#

They are supposed to be free to rotate relative to each other

#
    let axle = commands
        .spawn((
            square_sprite.clone(),
            RigidBody::Dynamic,
        ))
        .id();

    let wheel = commands
        .spawn((
            square_sprite,
            Transform::from_xyz(0.0, -100.0, 0.0),
            RigidBody::Dynamic,
            AngularVelocity(1.5),
        ))
        .id();

    commands.spawn(
        RevoluteJoint::new(axle, wheel)
            .with_local_anchor_2(Vector::Y * 100.0)
    );
#

In this example, I'd expect the axle to not rotate at all, while the wheel is free to rotate. That however is not what happens; the axle kind of rotates along with the wheel

#

Also the anchor points seem to be totally meaningless, as modifying them does nothing.

silk mauve
#

So I have this cool effect that lets me make my terrain bounce, but the terrain doesn't "move" according to the physics engine. Instead, the ground is a static mesh that is regenerated. I'm not sure how physics engines actually work, but this seems like the kind of thing that would break any guarantees that avian could make regarding objects passing through one another. Like if 2 dynamic objects run into each other at this speed, they'll just stop or slide past each other or something. But since the collider is being generated inside of the player collider, the player will just fall through it. I'm trying to brainstorm the best ways of handling this. The most foolproof way I can think of is treating the mesh below the terrain as a volumetric collider or maybe applying localized impulses based on the effect. I'd love some insight from the certified brain-genius's in this channel tho

#

I -could- make my character a floating capsule which would help (and I plan to do that) but that still doesn't handle cases where the terrain may be moving very fast. It's a partial fix at best

cinder summit
paper maple
#

Can softness be configured for an individual entity / rigidbody ? It doesn't seem so from what i've seen from reading thru the docs

worldly cove
# silk mauve So I have this cool effect that lets me make my terrain bounce, but the terrain ...

Hey, I saw your post in another thread (it looks so cool!) but I was wondering how you were handling the physics even in that demo: the player seems to be moving correctly over the top. Are you removing the collider every frame and regenerating a new one when you re-make the mesh? (I'm trying to figure out how to do something similar)
[Edit: oh, just watched your version above... yep, that's what I see in mine when I do the "remove and re-add a collider every frame": sometimes there are kind of "concurrency issues" and my object falls through the floor]

#

(I worked around this in my prototype by doing a raycast and if I fell through the floor then I manually placed back above. It works for me because it was very simple object and terrain - so might not be appropriate for you)

grizzled junco
#

when would i need object that has rigid body static over just a collider?

sweet sundial
#

i think colliders without rigidbodies don't actually interact with the physics

silk mauve
# worldly cove Hey, I saw your post in another thread (it looks so cool!) but I was wondering h...

It seems like you basically worked through this conversation on your own. I have a few thoughts though.

  1. Lots of characters controllers use a downward raycast to determine their position. If you start the raycast at (or near) the top of the character instead of starting it at their feet, this would make your character more robust against these types of static-collider-changes

  2. You can pair the above with making the collider volumetric. What does that mean? Think quad vs cube. So if your character falls into the ground, they are in a solid collider that will push them up hopefully.

  3. You could apply impulses to entities on top of the terrain in relation to the terrains movement.

All of the above solutions are best when the only morphing is in the y-axis. For instance the raycasting helps when the floor moves up and down, but not when the wall moves into you. Volumetric colliders may help but I'm not entirely sure

weary ember
#

Has anyone did somthing with joins beyond examples?

mossy brook
#

Is there a way to give a heightfield some thickness on -y only? I'm using it for terrain generation and I don't want to make things hover over the surface by just using CollisionMargin.

sleek thicket
fleet mason
#

do you think no_std support might happen eventually/soon? getting to that point with my playdate game where im about to integrate physics and have to choose between this and bevy_rapier. bevy_rapier doesn't have no_std support yet but rapier does so im sure its possible

sleek thicket
fleet mason
#

I'll probably try both

turbid mango
#

did some Archimedes-ing 🙂

shy blaze
#

if i move some Positions around and then do a spatial query, will it just work with the new positions? or do i need to run some intermediate step to update the physics state

cinder summit
shy blaze
#

hm. i figured. trying to suss out the laziest way to reverse some positions to do lag compensated hit testing. open to suggestions 🥲

cinder summit
#

Copy the BVH every frame and put it into a history that holds however many ticks of lag compensation you allow

shy blaze
cinder summit
#

Yea, if we're gonna be lazy about it, that would be the way to go

shy blaze
#

and, if i wasn't going to be lazy? sounds like you have a clever alternative in mind that's more work

cinder summit
#

Well there is the other approach of rebuilding the BVH by calling the system, then resetting your changes afterwards ... That's more expensive unless it's really rare to run lag compensated hit detection however 🤔

shy blaze
#

well i won’t worry about it until it’s a performance problem, then. should be good for now. thanks!

lime lynx
# turbid mango did some Archimedes-ing 🙂

This is so cool! Any chance that you're thinking about turning this into a full-on lib? I'd love to play around with putting a boat or something on top of a volume like this 🙂

turbid mango
# lime lynx This is so cool! Any chance that you're thinking about turning this into a full-...

Not sure. It's still very hacky/basic (doesn't handle torque from objects hitting the water “sideways” so something irregularly shaped like a boat might decide to float vertically). I'm currently working around that by segmenting the shape into multiple smaller objects joined by fixed joints, but that probably is too brittle for a fully baked library. My math/physics knowledge is somewhat limited, so I'm not sure how to do the more complicated/correct handling either

#

Since on the current form it's a single plugin and relatively simple to drop-in, maybe it's better to keep it as a gist that people can copy/paste from, and adapt to their specific needs

lime lynx
#

That makes sense! Still cool to see someone playing around with it, and I might spend some time doing the same at some point 🙂

vestal minnow
# turbid mango Not sure. It's still very hacky/basic (doesn't handle torque from objects hittin...

this has a simple but reasonably accurate and fast approach
https://youtu.be/-4cphhvxI8g?si=Mgw5EO8CPmn_nL8w

visit https://brilliant.org/b2studios/ for a free 30-day trial and 20% off an annual subscription!

I think the best question to ask is how did someone manage to crash a ship that badly?

Discord: https://discord.gg/KgMgeQ7EMP
Reddit: https://www.reddit.com/r/b2studios/
Twitch: https://www.twitch.tv/b2studios
Patreon: https://www.patreon.com/b2s...

▶ Play video
#

TLDR: Estimate the submerged volume by computing the total volume of the shape, uniformly sampling some number of points inside the shape, and testing which percentage of points is below the water surface. The center of mass to apply the bouyancy force to can also be computed based on these submerged points.

#

There are other likely more efficient and accurate approaches too, but they're a bit more complicated. I know at least Jolt has buoyancy built in

sleek thicket
#

@vestal minnow what do you think #1124043933886976171 message

vestal minnow
#

Last I checked, Parry was technically mostly no_std but there might've been some part that wasn't? Not 100% sure, it might've gotten fixed

#

If Parry and Bevy are sufficiently no_std then I don't see any inherent blockers for Avian

vestal minnow
fleet mason
#

oh weird i wonder where i got that idea

sleek thicket
#

@fleet mason what exactly do you need from physics? maybe you could get away with just the collision lib?

fleet mason
#

just a simple physics-based-ish platformer

#

you're probably right that i could get away with it for the most part but it would limit some ideas that ive had (grapple hook-like mechanic which would require a distance joint or similar)

sleek thicket
#

i'm just assuming that starting with no_std collision lib would be more manageable

#

doesn't mean that you have to stop there

fleet mason
#

true, but at some point it might just be easier to help port avian haha

turbid mango
grizzled depot
vestal minnow
#

Cool, good to know 🙂

sweet sundial
#

is there big_space support of any kind?

glacial nebula
vestal minnow
#

Huh, TIL that Rapier doesn't seem to have even inter-island parallelism? There's a ton of code for parallel islands and even graph coloring but it's all commented out and WIP, so the whole constraint solver is currently single-threaded as far as I can tell

Edit: It does have inter-island parallelism, but not intra-island parallelism. The commented out ParallelIslandSolver is unrelated to inter-island parallelism.

#

I was under the impression that Rapier had at least inter-island parallelism, and SIMD constraints, but it's just SIMD

#

though I'm not entirely sure how that works either, since afaik implementing SIMD constraints properly requires graph coloring, which Rapier doesn't really have

willow elbow
#

is it possible to change the color of a DistanceJoint and/or ShapeCaster debug arrows?

vestal minnow
#

But it affects all joints and shape casters, there currently is no per-entity configuration for this

mossy brook
vestal minnow
#

I think implementing a collision shape for this wouldn't be too bad if you could assume that there are no holes, but heightfields support holes which makes things kind of weird

sleek thicket
#

heightfield with holes can just be renamed to heightfield_with_holes 😅

vestal minnow
#

yeah but it kind of needs to be handled on the Parry side regardless

sleek thicket
#

unless you yeet parry

mossy brook
#

I can definitely assume there are no holes since it's for terrain gen. So I would implement my own collision shape?

sleek thicket
mossy brook
#

I did have a player spawn in a platform and get shot through the floor. I'll have a lot of UGC, so mostly preparing for the inevitable bugs. Players will be able to delete stuff, so I'm not worried about them getting stuck.

#

Also crashing into the side of a mountain at high speed could cause some issues, and possibly complications with replication.

sleek thicket
#

it's probably fine to leave as is and hope that jondolf will add heightfield without holes soon
i want to use heightfield as a sensor, so that's an extra reason for it to exist

mossy brook
#

Yeah I don't need it immediately. Just eventually.

#

Just thought it would be odd to have players float above the surface just so they don't clip underneath.

sleek thicket
#

that's just an early warning of something being wrong with trimeshes though

mossy brook
#

I guess I could offset the mesh?

sleek thicket
#

i'd say don't do bandaid fixes, the root cause might get fixed eventually

vestal minnow
#

and that should be very rare unless the object being pushed is very thin or otherwise small, which the player probably isn't

#

*assuming there aren't bugs

mossy brook
#

Good to know. I assumed speed would be an issue, I haven't seen any though. Yeah it was an overlapping object with the player, and I'm not certain I'll cover all possible cases when that could happen in the future.

vestal minnow
#

Speed can be a problem without Continuous Collision Detection, but speculative collision (one form of CCD) is enabled by default, which should prevent most cases of tunneling

golden python
#

Hello fine people of avian. How would you recommend I approach building colliders for voxel based terrain ? should I go straight from the mesh (which introduces a GPU readback since I build the meshes on the GPU) or is there a better way to go from a 3d grid of cubes to a collider ?

cinder summit
#

If they are boxels like in minecraft, just use cuboids, maybe build copound colliders per chunk made up of the largest cubes you can create

#

If they are smooth voxels you're in for some real trouble unless you have the resources to run convex decomposition for chunks 😅

golden python
south nacelle
#

I'm trying to simulate a cube dropping on a mesh, then resetting the physics components and letting the cube drop again. I'm resetting the transform, position, rotation, linear velocity and angular velocity components but the cube ends up in a different position after each reset. Destroying and respawning the cube works as expected with the cube always falling into the same place. Is there a correct way to reset the physics on an entity? Am I missing some components?

golden python
cinder summit
#

That said I've seen Jondolf use examples with this behavior, so I'd imagine the examples have the right implementation for this

south nacelle
#

Ah true. Couldn't find an example but I'll try to figure out something

vestal minnow
#

The way I've done this in my own examples is by just respawning all the physics entities, this is actually kind of done in the determinism_2d example

#

Resetting values can probably also work, but contact warm starting impulses (used for making the solver converge faster) might carry over from the previous frame, which could affect things

#

@south nacelle You could probably try this to prevent contact impulses from the previous frame from carrying over to the current frame, just to see if that's the problem

app.insert_resource(NarrowPhaseConfig {
    match_contacts: false,
    ..default()
});
#

(also hi :D)

#

I'll try to repro this myself too actually

south nacelle
#

yeah the reason I ended up testing this is that I'm building a multiplayer game where for server reconciliation I need to move the player basically back in time and then simulate some amount of frames manually with the physics schedule to hopefully end up in the same position. Currently it's not working properly and I isolated it to the physics system with this cube test. If there are better ways to solve this for that specific use case that would work as well.

vestal minnow
#

@cinder summit would probably know more about that area

#

but specifically for this warm starting problem you can either disable it entirely with match_contacts: false like above, or I guess technically you could also manually iterate through contact data in the Collisions resource and set all the contact impulses to zero right before you reset the body state. If you're resetting very frequently then the former is better

#

With Lightyear I believe Avian does currently have some issues with rollbacks though. Afaik it's related to the entity order between the server and client not necessarily being the same, which can cause slightly different behavior on the Avian side. Not 100% sure though

south nacelle
#

Thanks I'll try the Collisions resource

cinder summit
#

Hopefully simulation islands will fix that without introducing major new problems 🤔

#

It doesn't really make sense for Sleeping to influence the simulation in the first place I guess, so it's undesirable for more than just rollback

vestal minnow
#

right now I'm working on finishing a solver optimization that cuts total physics step time in half for some collision-heavy cases

#

from 16 ms to 8 ms for my current 2D test scene

#

it also optimizes position and velocity integration

#

after that the narrow phase is actually the bigger bottleneck, but I'm hoping the contact graph stuff will help cut that down a bit

ivory arrow
#

How well does avian handle rollbacks?

plucky elbow
#

am i stupid?
trying to raycast from my camera
but no matter what i do it only returns the same entity or no hit
ive excluded the player
camera is a child of the player/collider

cinder summit
# ivory arrow How well does avian handle rollbacks?

Mentioned it above, as long as you disable SleepingPlugin and roll back Collisions (or disable warm starting) it should work almost flawlessly provided you roll back all relevant components that might change (position, rotation, linear velocity, angular velocity, and any properties your simulation might change) ... If you need to to be perfectly deterministic (for games with deterministic replication) there might be some extra small edgecases here and there however 🤔

cinder summit
cinder summit
#

So there are multiple possible issues here:

  1. The camera has no rotation or only partial rotation, and you're not using GlobalTransform nor adding up both rotations
  2. The player's origin is on the ground, and you always detect the ground
  3. The camera is offset from the player, and because you don't start from the camera's position you thus don't see things in the center of the screen but offset as if the camera was on the player
vestal minnow
#

Basically I'm just maintaining a SolverBodies resource with a SolverBody for each awake dynamic and kinematic body. A SolverBody stores the velocity and delta isometry needed by the solver, which removes the need for querying the ECS in performance-critical parts. Solver bodies are prepared before the substepping loop and written back to rigid body components after it, so I would imagine it's probably not something you need to roll back

#

But the SolverBody entries (not their values) and some indices and whatnot are persisted across time steps

cinder summit
vestal minnow
#

Query::get_unchecked was taking like 2.3 ms in a test of mine while just accessing an array was 0.4-0.6 ms IIRC

cinder summit
# vestal minnow But the `SolverBody` entries (not their values) and some indices and whatnot are...

If the indices have some sort of impact then rolling it back could result in non-deterministic behavior ... The simple case to figure out if rollback would have an impact is: If a wrong series of events happens, for example things spawning in a different order, or some entity missing for a while, and then get fixed later, does that result in a different output from immediately getting the correct series of events?

cinder summit
vestal minnow
#

Also we'll definitely need SolverBody-like stuff for AoSoA SIMD once we do that

cinder summit
#

That data should be cached and thus be fetchable quickly using an archetype id

vestal minnow
#

The SolverBody is also exactly 32 bytes in 2D which I imagine is nice for memory locality

cinder summit
#

If that's after alignment I'm sure the cache would like that yes 😂

vestal minnow
#

and it will fit nicely in 256-bit AVX vectors eventually

#

(I may or may not have stolen the current design I'm using from Box2D)

cinder summit
vestal minnow
#

in terms of its implementation, I kinda like to imagine Avian as striving to be "Box2D, but also 3D, and in Rust, with an ECS"

#

Box2D is so niiicee

cinder summit
#

Set the goal even higher ... Box2D but better 👀

#

Better, and 3D and SDF collisions 😂

vestal minnow
#

Idk if we can beat it in raw performance, but we can of course have more game dev centric features built in (since Avian is for a specific game engine) and the ECS allows for some nice APIs and modularity

cinder summit
#

Is Box2D really that performant? I thought only bepu had unusual performance 🤔

vestal minnow
#

Box2D V3 is somewhat inspired by Bepu's design

#

graph coloring + wide SIMD + very data-oriented

dire cape
#

I just found out about bepu physics from this chat, why is it so fast? I'm curious now

#

any links?

vestal minnow
#

C# crimes

cinder summit
#

It's not really any one thing that makes it fast, but more that the dev seems obsessed with performance

vestal minnow
#

very, very heavily vectorized

cinder summit
#

There are a lot of ways most physics engines could be improved, but doing so takes time and most physics engine devs just don't give a shit

#

"It can simulate 1000 awake entities and have unlimited sleeping entities, good enough"

dire cape
#

the demo video for bepu looks so cool though

vestal minnow
#

(bepu or bevy?)

dire cape
#

oops

cinder summit
#

Meanwhile bepu physics be like: "What if we have many thousands of awake physics bodies and it also runs fine?"

dire cape
cinder summit
#

I mean ... It's a neat tech demo, but I think jondolf's examples look better 😂

dire cape
#

oh for sure, but the scale of the demo is so cool

#

makes me think about what kind of game you could make with fast, large-scale phyics

cinder summit
#

Like the bepu demo scenes honestly look hideous, if they didn't distract you with their scale it would be underwhelming

vestal minnow
#

we just need to get the atmosphere stuff and raytracing in Bevy and we'll have physics demos that look like all those research papers

#

like this is so unnecessarily fancy 😂

#

(from the VBD demo)

#

This is completely unrelated and has sort of been brought up before, but I've been thinking lately that at some point it'd be worth experimenting with a crate like bevy_physics_common that just provides a shared, physics engine agnostic API. We could then add integrations for Rapier, Avian, or even e.g. Box2D, all using the same components and resources wherever possible, and only diverging for heavily engine-dependent features.

#

I feel like something like this could be desirable for an eventual bevy_physics; provide a first-party API and an optional official physics integration, but also allow the use of other physics engines without completely fragmenting the ecosystem

#

I used to be pretty skeptical of this since I felt like engines vary too much, but I feel like it should technically be viable to share like 95% of the API surface 🤔

#

The main problem is probably different collider types, but we could technically have something similar to ColliderConstructor for the shared type if we wanted to, plus plugins can largely be collider-agnostic like we do with the AnyCollider trait already

lunar bluff
#

Im using avian2d, and I've created a triangle collider with a height of about 100 units. I've made it a dynamic rigid body, and with the default settings on the plugins, it falls extremely slowly

#

If I change the length unit to 100.0, it doesn't move at all

#

im thinking i need to define my own mass?

vestal minnow
#

the Gravity resource defaults to -9.81, you can scale that

lunar bluff
#

ah okay

lunar bluff
# vestal minnow the `Gravity` resource defaults to -9.81, you can scale that

And documentation even says I should:

The default is an acceleration of 9.81 m/s^2 pointing down, which is approximate to the gravitational acceleration near Earth's surface. Note that if you are using pixels as length units in 2D, this gravity will be tiny. You should modify the gravity to fit your application.
#

thanks!

#

Shouldn't the length unit being set to 100 also fix the problem though?

vestal minnow
lunar bluff
#

oh so its just for numerical stability

vestal minnow
#

Yeah basically

lunar bluff
#

cheers!

vestal minnow
#

It's essentially an internal scaling factor to make sure that internal thresholds and tolerances match the scale of your world. For example, how fast can penetrating objects be pushed apart, how large contact tolerances should be, what speed is considered fast enough for restitution to be applied, etc.

#

so I suppose it's more for simulation stability than numerical stability

vestal minnow
#

bleh... I think I need to do the joint rework before I can land this SolverBody thing, since the current XPBD setup for joints isn't really compatible with it, at least without more nasty hacks and accumulating tech dept :/

cinder summit
#

Is it finally time to fully yeet XPBD 👀

vestal minnow
#

I guess back to fighting with hinge joints I go

#

I've been stuck with a bug with them for ages, I have some custom matrix types that I'm writing unit tests for just to eliminate any potential errors in the math

#

I've gone over the code like a bajillion times

#

-# If Avian was 2D-only, this would be so much easier ferris_sob 3D joints are a pain

vestal minnow
#

this doesn't even use quats much, it's just a ton of confusing matrix math and dealing with Jacobians

#

I should write some blog post or guide on joints if I ever manage to finish this, there really aren't any good resources for actually implementing them aside from existing implementations and math-heavy academic papers

lunar bluff
vestal minnow
#

oh my god is the problem really just that Glam's any_orthonormal_pair builds the basis slightly differently than the joint implementation I'm using as reference

#

I don't even want to know how much time I've wasted on this ferris_sob

#

welp the hinge seems to work now, though I still need to implement 3D limits and a motor for it 🙃

sleek thicket
plucky elbow
#

I tried GlobalTransform but got type errors on the cast fn

sleek thicket
#

globaltransform.translation() is probably what should be used here

plucky elbow
cinder summit
#

You'd need both the camera's GlobalTransform translation and rotation for the cast I think

#

Tho ideally you'd avoid GlobalTransform because it's kind of clunky unless you really only need things to run after PostUpdate and not change transforms again

plucky elbow
#

OK this seems to work. ungodly

cinder summit
#

Use Vec3::NEG_Z instead of that weird * -1.0 hack 😂

#

Also you can just rotation * vec instead of explicitly calling mul_vec3 I think

plucky elbow
#

Now I'm begging for vec3 to have a Into impl for dir3 so I'm not having to do Dir3::new_unchecked()

cinder summit
#

You can't turn a vec3 into a dir3 blindly because that's a fallible operation

vestal minnow
#

can't you just do camera_transform.forward()?

plucky elbow
#

I gotta go check out some land for sale

plucky elbow
vestal minnow
#

pretty sure there is .try_into()

vestal minnow
#

my current hinge is just a separate point-to-point constraint and angular hinge constraint though, not a combined one since that's uhh... pretty broken still

lunar bluff
#

question: why aren't Colliders Assets?

#

they can be quite complex, and you can potentially have a lot of them, similar in nature to Mesh

vestal minnow
#

Mainly we just haven't tried it yet. It would also add an extra asset lookup to every place that queries for colliders, so we need to profile if it'd just have more overhead

#

Colliders store a SharedShape though which is an Arc<dyn Shape> so it's shared anyway if you clone it

lunar bluff
#

maybe make it an enum for the best of both worlds

#

ah okay

#

thats good to know

vestal minnow
#

Enums have the problem that their size is determined by the largest variant, so even a Collider::Sphere(0.5) would be large in size if some variant stores a TriMesh. But we could instead do something where large shapes have their own asset types, and the enum just stores handles to those, while small primitive shapes are stored in the enum directly

lunar bluff
#

sounds good.

cinder summit
lunar bluff
#

wait, surely the TriMesh variant would have a Vec in it? The enum's size wouldn't be affected.

vestal minnow
#

a TriMesh stores something like at least 14 Vecs internally

lunar bluff
#

oh really

#

fair enough

vestal minnow
#

it has a Qbvh and a bunch of topology data and pseudonormals etc.

lunar bluff
#

understandable, this is way beyond my sphere of knowledge

#

😅

warm sparrow
vestal minnow
#

Not right now, but locally I do have some of Box2D's benchmarks and samples implemented with Avian, like tumbler and large pyramid

#

I'm mainly profiling Avian against itself for now since there are so many large optimizations we need to do still

#

once we do have a lot of the big optimizations done though (solver bodies, simulation islands, better contact management, graph coloring, SIMD contacts, BVH broad phase) it'll be interesting to see where we'll be relative to other engines

golden python
#

Pure curiosity but do you have an general idea of where Avian stands performance wise with other engines ? Mostly curious about mainstreams ones like box2d or whatever is used in the big engines

vestal minnow
#

currently it's definitely slower than Box2D, Jolt, and Bepu, and also slower than Rapier in a lot of cases, but a lot of it depends heavily on the scene

#

some people have said it's faster than bevy_rapier for their projects

#

but for large scenes with lots of contacts and/or joints I would be very surprised if it is

#

most projects also just aren't that intensive on physics, like it's relatively rare to have tens of thousands of dynamic bodies being simulated and colliding at once

#

so physics perf is unlikely to be too big of a concern for a lot of projects

warm sparrow
#

Out of curiosity, how does 3d avian perform compared to 2d avian for the same scenario (for example same number of spheres vs circles)?

vestal minnow
#

Should be pretty comparable if the number of contact points is roughly the same. But there is some inherent extra cost in 3D because of the added dimension, for example rotation uses quaternions instead of just a complex number, and angular inertia is a 3x3 matrix instead of a scalar value. Friction also becomes a bit more expensive since it now needs to consider two tangent directions instead of one

#

Currently 3D also has gyroscopic torque by default, which adds a bit of cost to velocity integration, but we could make it opt-in and otherwise optimize it a bit

#

A fun optimization I discovered in Rapier a couple of days ago is that we could also precompute velocity increments caused by external forces and torques at the start of the time step, and apply them at each substep with just a single addition. For 3D though, the changing orientation of the body should affect the angular inertia and gyroscopic torque, so you'd lose some accuracy there...

sleek thicket
#

@vestal minnow in picking example Shape marker isn't used 🫠

#

and idk what i'm doing wrong but require_markers: true and PhysicsPickable doesn't work

sleek thicket
#

oh, camera needed it too, derp

sharp atlas
#

Hi! Im trying to impl this ytb video using avian.
https://www.youtube.com/watch?v=CdPYlj5uZeI
The experience and result are pretty good!

but it always jittering, and i cant find the reason. pls help me~

A detailed look at how we made our custom raycast-based car physics 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
sharp atlas
sharp atlas
#

Also, when the speed is high, it seems like the ray caster is lagging behind.

#

This happens especially when moving at high speeds or high rotation, and it feels like the ray caster can't keep up with the movement

golden python
# sharp atlas

To me it looks like the kind of thing that would happen if you were applying forces in a frame dependent way, so that variations in FPS would make the car "jitter".

Could be something else though, just a hunch

weary hornet
#

Also I'm assuming you're doing this in FixedUpdate, so there will be some visual jitter. You have to interpolate the visuals.

But I think @vestal minnow has a solution for this with Avian?, I just dont remember what it is

little maple
weary hornet
#

Ah there ya go, thanks!

sharp atlas
sharp atlas
little maple
#

one thing I ran into was using really small, light objects which made things jittery

sharp atlas
#

And the force is constantly and rapidly changing

sharp atlas
#

I've noticed that the jitter occurs very regularly, happening about once every 0.2 seconds. It happens regardless of the speed; it just becomes more noticeable when the speed is faster.

sharp atlas
#

Sh*t! I've figured it out! By placing the camera update function in the FixedUpdate, the jitter is gone!
However, I tried using TransformInterpolation, which not only failed to solve the problem but also increased the jitte, and the pattern remained the same as before.
I suspect that whether RayCaster or PhysicsDebugPlugin has interpolation enabled by default, which might be causing the jitter. However, this still needs to be verified.

sweet sundial
#

everyone talks about jitter and interpolation, but i've never had a problem; is 144hz fixedupdate too high for smaller computers?

sharp atlas
#

i think the default setting is 64hz fixed update.

weary hornet
#

And you probably want to use linear not extrapolate

sharp atlas
#

yes I did, that's exactly what I did.

#

and since Im using mac, the refresh rate is 60hz, and fixed update is 64hz. the interpolation may not needed.

weary hornet
#

Hmm then I don't know sadly. I've never used the interpolation built into Avian yet either to really know for sure. But it sounds like maybe you're seeing more than the jitter I'm thinking about

true hearth
#

afaik the only way to not have jitter without interpolation is to have the fixed update rate be a integer multiple of the refresh rate (or a integer division)

little maple
#

I can't tell from your video what you mean by jitter, but one thing I ran into was when I made my camera smoothly follow, there would be a little bit of jitter and the reason was the camera updated more often than the physics ran and so it would move while the world hadn't changed and then adjust again on the next update

sharp atlas
little maple
sharp atlas
#

the raycaster gizmos, four tire

#

this is what happened when camera in update, and enable interpolation: first the jittering is more obvious, and second, the mesh(faint blue) didn't match the collider gizmos🥲

#

Sorry for taking up so much time in this channel😅 I really appreciate everyone's enthusiasm and help!

sharp atlas
sleek thicket
sharp atlas
sleek thicket
sharp atlas
#

i think in different setting, like 120 hz refreash rate, the jittering may disappear, that would be bad..

vestal minnow
sharp atlas
vestal minnow
#

Hmm yeah that sounds correct

#

Something you could try to exaggerate the problem is to set the fixed timestep to some very low tick rate, e.g. .insert_resource(Time::<Fixed>::from_hz(10.0)). If interpolation is working, it should still look relatively smooth, but if not, then something is most likely going wrong there

sharp atlas
weary hornet
#

it's not just the debug lines that are doing that right? have you confirmed that? It looks like it's everything, but may be tricking the eyes

#

Because the shadow looks smooth to me

sharp atlas
weary hornet
#

I'd honestly try disabling the debug output for a sec

#

because if the body is jittering you'd expect the shadow to be too

sharp atlas
weary hornet
#

ya that makes sense but you want camera in Update otherwise it wouldn't be smooth on a faster monitor

sharp atlas
#

as far as i notice, the camera in fixed update will make sure the movement is smooth. and interpolation will make sure the mesh didnt catch up the gizmos.

weary hornet
#

I just wonder if it's a bug with the gizmos and otherwise the physics are working fine

sharp atlas
#

hmm, i will try disable the gizmos, camera in update, and with ot without interpolation

weary hornet
#

that will be jittery

#

I would try disabling gizmos, camera in update, and then interpolation on

vestal minnow
sharp atlas
weary hornet
#

yeah thats what I figured, the shadow gave it away 😛

sharp atlas
#

that really make sense

#

thank you very much!

#

i cant believe i havent try that before

vestal minnow
#

I guess we could make the debug rendering use interpolated transforms too, but it technically wouldn't match the actual state of physics perfectly 🤔

weary hornet
#

could be an option, both are useful

vestal minnow
#

yeah

grizzled junco
#

something is kind of bothering me. CollisionLayers and CollidingEntities are in the same entity as the collider and not the rigidbody. That is annoying to me but not hard to solve. But the thing is, RigidBodyDisabled doesn't disable the children colliders? (or it is disabled but the colliding entities still updated, i haven't test much yet)

vestal minnow
#

though it'd make queries annoying

sharp atlas
#

i mean the parent gizmos(collider) and raycaster(tire, children of the body) didnt match

vestal minnow
little maple
vestal minnow
#

just for Tnua's purposes though

grizzled junco
grizzled junco
vestal minnow
#

I think it's desirable to support disabling a specific collider, not just all attached colliders. But the latter would also be nice to support, so that you can just disable all collisions for a rigid body without having to deal with children. So some things might change or be expanded

#

I'm definitely open to improvements there

#

It'd be nice if there was some form of first-party "component propagation" in Bevy so that you could add a component for a parent and it'd optionally affect descendants too

#

there's an open PR for something like that already

grizzled junco
#

good to know

#

right now i will change my implementation so i can easily work with avian

sleek thicket
#

otherwise i don't get what you're doing

grizzled junco
#

wait, but then should i insert both RigidBodyDisabled and ColliderDisabled for disabling a body?

grizzled junco
#

i just want to NOT frequently spawn and despawn bullets since my game will have A LOT of bullets

#

or im just doing premature optimization

sleek thicket
#

@cinder summit we caught one

grizzled junco
#

man

#

so spawning a new one is just as costly as insert remove disabled component?

sleek thicket
grizzled junco
#

ECS pattern is very rare in the wild so things like this is hard to know

grizzled junco
#

made me question my life choices

sleek thicket
grizzled junco
#

switched? isn't it just became a package?

sleek thicket
cinder summit
#

I think that's next version that's years away 🤔

sleek thicket
#

it's not too different from what they already had, if you just imagine that script component is a marker component

#

just more of a pain to work with, and less flexible compared to bevy ecs

cinder summit
grizzled junco
#

good to know 😂

grizzled junco
sleek thicket
#

i'd be more concerned about avian's performance than spawning

#

might be better to use plain distance checks

grizzled junco
#

for bullets?

sleek thicket
#

yeah

#

bullets mostly have constant speed so you can store just the direction for them and move transform

#

and check only the player

grizzled junco
#

are you saying there are better physics engine for it like rapier or for general thousands of bullets is not really good with these physics engine?

cinder summit
#

Thousands of bullets as physics engines usually doesn't end too well

#

Tho if Jondolf is to be believed Box2D and bepu would handle it like it's nothing 😂

sleek thicket
#

either way it's like 10 mins work to do the bullet movement + collision check without physics

#

if you have environment to collide with then that's another thing though

vestal minnow
grizzled junco
#

make sense, since my bullet will likely have simple geometric shapes

grizzled junco
cinder summit
sleek thicket
#

for the bullet hell games that i played only player bullets needed physics though, and 99% of bullets weren't from player

grizzled junco
#

it will have interactions with environment, but the shapes are simple to do simple collision check, but my bullet probably won't go past 3000...

cinder summit
#

I wonder how many projectiles my spherecast-powered mess can handle ... Probably not actually as much as just doing projectile collisions using intersection tests against capsules in default avian, then storting the result by distance thonk

vestal minnow
vestal minnow
#

yeah

cinder summit
#

Yea that's the one I was thinking about

#

By all the numbers I got avian should be faster too 👀

vestal minnow
#

I'm trying to find that newer one with a ton of asteroids breaking into pieces and stuff

sharp atlas
#

thats crazy!

grizzled junco
#

then i think it's still fine for me to use the engine for my probably not pass 3000 bullets game 👀

sharp atlas
#

so the bullets can even collide with each other?

vestal minnow
#

(I'm assuming it's using Avian at least)

vestal minnow
sharp atlas
#

im totally shocked

vestal minnow
#

it's not even that good tbh, it should be possible to make it much faster I think

#

collisions are the main thing that is costly for physics, and in these demos there aren't any crazy amounts of active contacts

sharp atlas
#

physics engine is magic to me.....

cinder summit
#

Yea iirc the bottleneck was actually the broadphase, which I guess makes sense considering how uh ... primitive ... it is

sharp atlas
#

rely on a physic engine but not to rebuild the wheel should be the smartest thing for me..

cinder summit
#

Pretty sure it is for most people

#

There's not even really much reason to make a physics engine from scratch now that avian exists either ... Want something fancy? Just build it using avian 😂

vestal minnow
#

meanwhile Nise implementing custom SDF collisions

cinder summit
#

Hey, I didn't rebuild any wheels, no bevy crates ship with SDF collisions okay 😂

#

After I figure out OBVHS for my raymarcher I should probably look at updating the SDF collisions for my updated SDF tree stuff 🤔

sharp atlas
#

after seeing pezzza's verlet engine ytb video, i thought, oh that interesting, i should build one. (but never pass 3k objects)😅

#

i tried everything, it just didnt work

vestal minnow
#

iirc his video on Verlet physics was actually one of the things that originally inspired me to want to try implementing my own physics as well

#

among some other videos and articles I found

#

I was in a Verlet physics rabbit hole at one point and partially found XPBD through it if I'm remembering right

#

(and Johan Helsing's blog post on implementing 2D XPBD for Bevy)

sharp atlas
#

looks a little bit similar to me, actually🤔 both by manipulating position? some kind of ?

cinder summit
vestal minnow
#

same 😂

cinder summit
#

At least I can still remember how I ended up doing SDF collisions 🤔

sharp atlas
#

me, right now👀

vestal minnow
cinder summit
#

Honestly still feels crazy how avian used to be this small obscure library, and now basically half of the bevy ecosystem uses it 😂

sharp atlas
#

i think the github readme explain this very well. I also tried rapier, but avian's doc is much better, and very easy to use.

cinder summit
#

That's basically the goal afaik

#

Legend has it Jondolf actually likes writing docs ... somehow thonk

sleek thicket
#

or was that just me

cinder summit
#

I was keeping an eye on the bevy_xpbd repo before it even had a release iirc 😂

#

rapier just had too many bugs and I wasn't able to understand the code to the point where I felt I stood any chance fixing them

sharp atlas
#

hmm, doesnt rapier "battle tested"? cant remember where i saw that.

sleek thicket
#

it is, just not by games lmao

sharp atlas
#

althought i didnt try rapier deeply, but just have that feeling

cinder summit
#

Yea most problems with rapier are actually kind of gamey problems

vestal minnow
#

Rapier is more mature and has been around longer (its predecessor NPhysics is also nearly ten years old now), and it currently has more physics features and optimizations and stuff

#

also has more and bigger sponsors (like Foresight)

cinder summit
#

Worth noting that half the optimizations are actually commented out tho 😂

vestal minnow
#

yeah lol

#

Rapier (or specifically Dimforge) also seems to focus a bit more on robotics and industrial applications recently, while I'm focusing more on specifically game physics

#

though they're not necessarily exclusive

sharp atlas
#

is it possible that sometime avian will be built into bevy...

#

There's no reason Bevy doesn't have its own physics engine, while avian is an option

vestal minnow
#

It's not a very high priority right now, but Bevy will most likely have some first-party physics eventually

#

this could use Avian, but it's definitely not ready for it yet (and neither is bevy_rapier imo)

#

I imagine the physics engine would also be easily swappable still, so you could opt in to using other engines if you wanted to

sharp atlas
#

bevy philosophy

grizzled junco
#

removing those object pool codes feels sooo good

sharp atlas
#

congrats!

vestal minnow
#

from what I can tell, there's very little solver parallelism (since all of that is commented out), and there's a lot of things that feel kind of sus

#

Also am I misremembering or is Rapier non-deterministic with SIMD enabled? I don't see why it would be, but if it is, that feels bad

#

imo you should keep determinism even with high parallelism and wide SIMD, it's definitely doable with the right architecture

cinder summit
#

For avian it makes sense to care about determinism because people ask you about it quite often, but for engines that are developed almost without any interaction with gamedevs it's not surprising they ignore it for all the problems it brings

sleek thicket
cinder summit
mossy brook
#

Is it possible to make physics debug rendering opt-in per entity? Looking at the source it seems like it's everything with the option to disable specific entities?

Also doesn't seem like there's a way to toggle it at runtime?

grizzled junco
sleek thicket
grizzled junco
#

make sense

vestal minnow
#

Also doesn't seem like there's a way to toggle it at runtime?
You can do this with the GizmoConfig for PhysicsGizmos, same as other gizmo groups

fn toggle_debug_rendering(mut gizmo_configs: ResMut<GizmoConfigStore>) {
    let (mut config, _) = gizmo_configs.config_mut::<PhysicsGizmos>();
    config.enabled = todo!("toggle this");
}
mossy brook
#

Awesome, thanks!

quartz heart
#

@vestal minnow I’m currently looking into continuous rollbacks issues in the lightyear crate when using avian.

Is there still a source of non-determinism you are aware of in avian? (Like Order of contact pairs or similar)?

(Not talking about cross platform determinism, but rather same platform/machine determinism)

cunning gust
#

I want to rotate a point about another point (or the origin, I can transform to and from that if need be) by some number of radians

#

having some trouble figure out how

#

I want to rotate it depending on the contents of something's AngularVelocity

cunning gust
#

nevermind, I do believe I have figured it out

cunning gust
#

nevermind again

#

still very confused

vestal minnow
#

(mostly for collisions)

quartz heart
vestal minnow
#

the entities for the keys of the IndexMap in Collisions are sorted by entity, but that shouldn't affect things unless the sim uses those entities stored in the key somewhere

grizzled depot
vestal minnow
#

need to manually remove the docs folder for avian2d/avian3d every time I rebuild docs (or use cargo clean)

grizzled depot
#

it's rather quick with clean -p but eh, my mental burden 🥲 ; thanks for confirming

quartz heart
# vestal minnow the entities for the *keys* of the `IndexMap` in `Collisions` are sorted by enti...

I wanted to try another approach of filtering out very small differences in position changes/velocities, to see if its a floating point precision issue.

When I access the Collisions (during PostProcessCollisions) all the total_normal_impulse are 0.

But if I filter out the ones which are have 0 impulse, collisions are not working.

At what point in the schedule can I best prune forces which are below a certain threshold?

vestal minnow
#

you can't, since the impulses are computed in the solver, and applied immediately

#

filtering by penetration depth and/or impact velocity would be the next closest thing

#

but I don't see why this would be a floating point issue, std floating point ops used in Avian should be (at least) locally deterministic

#

the entity order problem can be easily reproduced by running the determinism_2d example with the entity columns shuffled with


let mut cols = (0..COLUMNS).collect::<Vec<u32>>();
cols.shuffle(&mut rand::thread_rng());

for col in cols {
    // ...
}
#

without shuffling, it's perfectly cross-platform deterministic

#

in both cases the initial transforms should be identical, just the Entity IDs assigned to the bodies are different and they're spawned in a different order

#

(same problem even without the joints and just collisions)

quartz heart
#

The determinism_2d sample panics for me with:

thread 'main' panicked at crates/avian2d/examples/determinism_2d.rs:253:41:
attempt to add with overflow
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic in system `determinism_2d::update_hash`!
vestal minnow
#

yeah that seems to happen on some runs, not often for me though

quartz heart
vestal minnow
#

I think it's just a problem with how the transform hash is computed

quartz heart
#
fn djb2_hash(mut hash: u32, data: &[u8]) -> u32 {
    for &byte in data {
        hash = (hash << 5).wrapping_add(hash).wrapping_add(byte as u32);
    }
    hash
}
vestal minnow
#

ah

quartz heart
#

this seems to not have it happen up to now?

vestal minnow
#

hmm okay yeah without the joints it is deterministic even with shuffling

#

for the current joints it makes sense that it's entity dependent

#

@quartz heart the lightyear demo doesn't use joints right?

#

seems like it's just rigid bodies and colliders which should be perfectly deterministic, so I'm not sure what's going on if there's still constant rollbacks 🤔

#

one thing to note is that I think collision events and CollidingEntities have the entities sorted by Entity ID currently, so they may be in a different order across clients. But I don't think the lightyear demo is using that

cinder summit
vague pebble
quartz heart
#

Indeed it’s simply a dynamic body (characters controlled by wasd) no joints for the movement

quartz heart
little maple
#

🤔 I feel like my fps starts dropping once I have ~150 of my raycast rigid body cars going (but not colliding)

it'd be cool to get 1000s (or even just 1k) going, but.. I'm guessing applying forces to keep the rigid bodies in the right position is enough to start affecting performance?

grizzled depot
#

omg all your cars are raycast+force simulated ? could you approximate cars far away with a simpler "raycast/shapecast on the ground + lerp rotation to horizontal or normal ?", like a simpler to compute kinematic approach ?

#

I'd assume they don't need the same precision as your player car (if that's still the same game you shared a few times), gamedev is full of cheats like that in my experience heh

little maple
grizzled depot
#

measure and adapt 🤞 and keep us posted :D

little maple
#

yeah... I thought doing something like that would be helpful.. like cars that are far away, I was disabling their rigid bodies and colliders with that disabled component.. I was going to even have background cars that don't have any physics at all...

still... not seeing a significant difference in the framerate 🤔 gonna run a trace

grizzled depot
#

🤔 but you mentionned raycasts ? wouldn't you have to disable those too ?

#

yeah if your bottleneck is on rendering those or whatever it's good to know you're looking at the wrong place at least 🙂

grizzled junco
#

well, the game full release was in 2017..

quartz heart
#

@vestal minnow for me in the determinism_2d sample I get different hashes even without joints:

#

(while with the same order of entities spawning, I get the exact same hash)

quartz heart
vestal minnow
#

also make sure the joints aren't there since they're not deterministic across different entity orders atm

#

I think we'll need to partially move them out of the ECS to fix that properly (we probably want to do that for perf reasons anyway though)

quartz heart
sleek thicket
paper maple
#

I've been trying to sync a Sensor's position with a RigidBody, and it seems to lag behind. I mutate the Sensor's Position in a system after StepSimulation and before Sync. In my mind that should cause them to line up, but the Sensor still lags (according to the Debug Render). Why is that ?

golden python
#

Hello, is there a built-in component to have a collider that generates from a mesh everytime the mesh data is updated or do I have to make it myself ?

golden python
#

I tried using the collider-from-mesh feature with a ColliderConstructor but it doesn't seem to work

cunning gust
#

How does LinearDamping work? The docs don't specify

cunning gust
#

Nevermind, I've figure out a solution to my problem that makes this irrelevant

#

but I have another question

#

How can I tell whether a change in velocity was because of a collision or something else (eg: gravity)?

#

I figured it out sorta

#

but am back at the LinearDamping question

cunning gust
#

basically, I need to use lineardamping manually

#

outside of the physics system

#

I'm making a player controller and it's for that

vestal minnow
cunning gust
#

My controller works within the physics sim by subtracting what it set velocity to last tick (velocity needed to stay on point on floor (rotating + moving floors supported) + player in input) from the velocity to see the impact that the sim had on the velocity

#

and it adds that to the velocity it wants you to move to get what you should be moving at

#

I'm gonna see if this damping equation works to add damping when I apply it to the part the physics sim changed

#

since that part persists across physics updates in a way because it's used to calculate the next velocity

#

then I'll just need collide-and-slide so I don't run into walls, get stopped, and think the sim wants me to move in the opposite direction because the wall set my velocity in a direction to 0 and made the difference the opposite of the intended velocity in that direction

little maple
golden python
#

I would appreciate if anyone could point me in the right direction

vestal minnow
golden python
#

Thanks, i'll do that

vague pebble
echo parcel
#

@vestal minnow Hi. I wanted to know, how much of Avian's physics is deterministic. I want to create rocket simulation, and I would want to set parameters by myself, without worrying that some random values would screw the results. So, if I e.g. add force to the rocket, and observe the results multiple time, I would want to see exactly same results every time, if I didn't change the values

golden python
#

I got the collider updating from mesh working, but it seems that once one of the rigidbodies becomes asleep, it doesn't react to the ground under it disappearing.
This might be expected behavior but idk (i'm running this with the default settings).

sleek thicket
vestal minnow
#

For cross-platform determinism you need the enhanced-determinism feature flag, but even without it Avian should still be locally deterministic

vestal minnow
#

(you'd use the command like commands.queue(WakeUpBody(my_entity)))

golden python
vestal minnow
golden python
#

Thanks a lot

little maple
sleek thicket
little maple
echo parcel
# vestal minnow Collisions, joints, external forces and torques etc. should be cross-platform de...

Great. I have few more questions. The idea behind the project is to launch a rocket, and then via the movement of the engine let it land without crashing. Something like SpaceX demonstrated but on much, much lesser scale. When rocket is close to the ground it is meant to just spread "legs" on which it can land(Can me called by hand, doesn't really matter, info just for the physics context).

Which elements of the required physics for this can Avian Physics provide? I know, that is can provide collisions, and I guess it can also provide thrust force. What also relevant (like e.g. air resistance) can it provide?

sleek thicket
vestal minnow
#

The contact graph and better pair management stuff I'm working on bring some nice perf wins for collision detection, the narrow phase typically seems to be 3x as fast, and the cost of collision reporting (events + CollidingEntities) is now pretty negligible. There are some wins elsewhere too

#

(ignore the image ugliness lol)

#

this is without the SolverBody stuff so the solver is really expensive still

#

there are also more low-hanging fruit to optimize this further, like using Query::get_unchecked more

golden python
#

Hello, I want to raycast from my camera that is inside my player character (as a child).

.with_child((
    IndexedCamera::new(0),
    FpsCamera::new(0.1),
    Transform::from_xyz(0.0, 0.6, 0.0),
    RayCaster::new(Vec3::ZERO, -Dir3::Z).with_solidness(false),
));

But even with solidness as false, it reports the hit on the collider it starts inside (white sphere is the origin).

Is this a known issue or am I just doing something wrong ?

sleek thicket
#

solidness false is like when you're in a room, and you want the room to be a box for some reason
probably could use a better name

golden python
#

makes sense thanks

#

do you know how I would exclude the entity ?

#

with a query filter ?

sleek thicket
#

Query<(Entity, etc)> if it's unique, yeah

#

i ended up storing player entity in a resource because it was required too often to bother with constant clashes

#

jondolf will probably add ignore to raycast soon though, so you might as well just use a spherecast for now

golden python
#

also i'm not sure about the query_filter syntax

sleek thicket
# golden python but why would I use a sphere cast ?

it's basically same as raycast if you use a small radius
filter is just a simple struct, and it can be const for reusable settings

const config: ShapeCastConfig = ShapeCastConfig {
    max_distance: 100.0,
    target_distance: 0.0,
    compute_contact_on_penetration: false,
    ignore_origin_penetration: true // <-- this is what you need 
};
golden python
#

Thanks

#

Got it working with the query filter

sleek thicket
#

@vestal minnow maybe instead of solidness or compute_contact_on_penetration, "invert_collider" would make more sense and be more useful?

golden python
#

Am I doing it wrong or is computing the actual global world position of a Raycaster's hit quite convoluted ?
This doesn't work but it's where i'm at rn:

let pos: Vec3 =
    gt.translation() + raycast.origin + gt.forward() * *raycast.direction * hit.distance;

Where gt is global_transform of the raycaster and hit is one of the rayhits

#

Would be so nice to just have position in hit, but I guess there is a good reason for that

sleek thicket
golden python
#

Yeah I know, that's what I usually do that's why it's so painful to have to do weird math for such a simple thing
I need to do a raycast every frame so it seems dumb to not use Raycaster

sleek thicket
#

does it actually do any optimizations though? i guess i'll have to check source later

paper maple
#

I still have this issue. I even have SyncConfig { position_to_transform: true, transform_to_position: false, ..default() }.

sleek thicket
paper maple
#

In Avian or Bevy ?

#

The system runs before all sync operations. I even disabled transform_to_position so the Entity's Transform should have 0 affect on this. Also, PhysicsDebug uses the Entity avian::Positions iirc, so as long as Transform isn't writing to Position (which it shouldn't be with my SyncConfig), it should align

vestal minnow
#

That matches more what I expected

vestal minnow
# paper maple

Hmm that seems strange 🤔 The debug rendering is currently done in PostUpdate by default, so just to make sure it's an Avian problem you could try syncing the position in e.g. Update (which is after any of Avian's physics systems) to see if the lag persists

paper maple
#

I just have a very simple example that just creates a RigidBody that movies under Gravity, and a Sensor.

app
  .add_systems(
    FixedUpdate, 
    move_sensor.after(PhysicsSet::StepSimulation).before(PhysicsSet::Sync)
  )

The Sensor is updated via :

fn move_sensor(mut q: Query<(&mut Position, Has<Follower>, Has<Leader>)>) {
    if let Some(&target) = q.iter().find_map(|(p, _, l)| if l {Some(p)} else {None}) {
        let mut p = q.iter_mut().find_map(|(p, s, _)| if s {Some(p)} else {None}).unwrap();
        p.0 = target.0;
    };
}
vestal minnow
paper maple
#

o

little maple
#
// TODO: Would batching events be worth it? (from report_contacts)

I'm running into 4-5ms of time spent in report_contacts and am now wondering what I can do to reduce that

#

lol geez sorry, there is send_batch on event writer. I'm gonna try that out

vestal minnow
#

How many contacts do you have? I had a scene with 5k+ contacts and it was ~0.2 ms (but I didn't use CollidingEntities there)

little maple
#

by "feel" i mean "I didn't measure so idk"

vestal minnow
#

Also the cost for contact reporting should be way, way smaller once I make that PR for the contact graph and better contact pair management

#

(it's on this branch, there's just a weird 3D determinism bug I need to track down and some other small things I need to fix)

#

I should split out some more things from that branch into smaller PRs lol, it's pretty massive

#

at least tangent velocity which is completely unrelated

little maple
#

I'm gonna see how many contacts I have

and also maybe check out that branch ||since I don't care about determinism 🫠 ||

vestal minnow
#

also, on the main branch (or that branch) you can add the PhysicsDiagnosticsPlugin and PhysicsDiagnosticsUiPlugin (requires diagnostic_ui feature) to add that fancy overlay I've been using with physics timing information and stuff

little maple
#

ah, got a panic on
debug_assert!(contact_pair.manifolds.is_empty());

#

curious what that's all about but... running it in release is glorious 🤩

vestal minnow
#

nice!

vestal minnow
#

I guess it's good that I added that debug_assert :P

vestal minnow
#

wow with the narrow phase improvements the broad phase is now often more expensive than the narrow phase lol

#

the broad phase cost should go down once we properly rework it to use OBVHS though

#

of course we're most severely bottlenecked on the solver though, it's over 50% of total physics step time in my current test scene

#

that should hopefully be improved quite a lot by the SolverBody stuff and parallel simulation islands in the near-ish future though

#

and later on graph coloring + wide SIMD for contacts

vestal minnow
little maple
vestal minnow
#

we are severely solver-bound

frosty cradle
#

Hey, I've had this assertion fail a few times and I can't really trace what I'm doing wrong.

assertion failed: b.min.cmple(b.max).all()
stack backtrace:
   [...]
   3: avian3d::collision::collider::ColliderAabb::grow
             at [...]/avian3d-0.2.1/src/collision/collider/mod.rs:378:9
   4: avian3d::collision::collider::backend::update_aabb
frosty cradle
#

It would appear that some AnyCollider::aabb or ::swept_aabb generates a malformed AABB

#

Possibly the cylinder shape. I made a cylinder collider into a cuboid instead and it's not failing anymore.

vestal minnow
#

usually that means you have NaN or Infinity somewhere

#

e.g. in the position or rotation, or an invalid shape

frosty cradle
#

I'm using a PrismaticJoint for cylinder and cuboid. I want the free axis to be aligned with the cube, so I added a system that adjusts the axis on FixedUpdate, after which the assertion started failing. Replacing the cylinder with another cuboid and it works again

#

Appears that the global transform of the main cuboid turns NaN at some point.

vestal minnow
#

Yup that'd be the cause

#

the joint probably becomes unstable and blows up for some reason

frosty cradle
#

appears so. Is it "illegal" to alter the free_axis? 😆
I'm assuming it's a global orientation by default, and I'm trying to make it align with the main body in order to emulate a wheel suspension

#

Hah... of course, I'm translating the vector

#

sorry, my math is out of wack

vestal minnow
#

I think free_axis determines which local axis the bodies are aligned to and can translate along. For example a free_axis of Vec3::X means that the axis goes through the local X axis of each body

frosty cradle
#

OH, that makes sense. Ok, no need to adjust it then.

#

Thanks 🙂
The assertion is a bit scary tho. I wouldn't want my game to shut down even if something explodes. I guess the new failing systems in 0.16 could probably let me configure that if the update_aabb system will return errors then?

vestal minnow
#

It's a debug_assert so it won't panic in release builds regardless

frosty cradle
vestal minnow
#

But yeah at least the error message could be improved, it's not immediately clear from the current error what the problem is

#

and yeah we could maybe make this fallible in 0.16 if it doesn't impact perf

frosty cradle
#

Neat! 😄 Thanks again

paper maple
vestal minnow
#

pretty sure it's world space but relative to the centers of the shapes

#

Or no I think it is fully global coordinates

paper maple
#

not from my experience

#

I had to do shape_origin + point2 to get world space position

#

from the result of SpatialQuery::cast_shape

vestal minnow
# paper maple not from my experience

Made this test scene quickly, at least here it definitely is global coordinates

use avian2d::prelude::*;
use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins((DefaultPlugins, PhysicsPlugins::default()))
        .add_systems(Startup, setup)
        .add_systems(Update, render_rays)
        .run();
}

fn setup(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<ColorMaterial>>,
) {
    commands.spawn(Camera2d);
    commands.spawn((
        Collider::circle(20.0),
        Transform::from_xyz(100.0, 0.0, 0.0),
        Mesh2d(meshes.add(Circle::new(20.0))),
        MeshMaterial2d(materials.add(Color::srgb(0.2, 0.7, 0.9))),
    ));
}

fn render_rays(mut gizmos: Gizmos, spatial: SpatialQuery) {
    let origin = Vec2::new(-200.0, 0.0);

    // Render a dot at the origin.
    gizmos.circle_2d(origin, 2.0, Color::srgb(0.9, 0.2, 0.2));

    if let Some(hit) = spatial.cast_shape(
        &Collider::circle(10.0),
        origin,
        0.0,
        Dir2::X,
        &ShapeCastConfig::default(),
        &SpatialQueryFilter::default(),
    ) {
        // Render a line from the origin to the hit point.
        gizmos.line_2d(origin, hit.point1, Color::srgb(0.2, 0.9, 0.2));
    }
}
#

the green line is drawn from the origin of the cast to the hit point, which is global

#

oh wait what

#

hit.point2 is different okay

#

yeah there is something very weird happening there 🤔

shut pulsar
#

can anyone provide any examples for how Sleeping is meant to be implemented?

paper maple
#

What is the reason why SpatialQuery doesn't have a method for getting ContactManifold ?

vestal minnow
#

I guess we could maybe have a built-in spatial query for this too, though I haven't seen any other engine have that

vestal minnow
#

depends on what you mean by "implemented"

#

like do you mean how sleeping is meant to be used and configured, or how Avian implements sleeping?

oak vigil
#

Thank you for the good documentation on this library. It's so nicely laid out ❤️

oak vigil
#

I'm trying to use colliders for an "ai vision" system. I have sensor colliders on the "vision sensors" and regular colliders on "vision targets".
This all works, but I'm trying to define collision layers for this to reduce noise. I have a VISION_LAYER.
Can I set up the layers such that the sensors detect collisions with targets, but not the other way around?
I tried setting the layers to:

let target_layers = CollisionLayers::new(VISION_LAYER, LayerMask::NONE /* filter */);
let sensor_layers = CollisionLayers::new(LayerMask::NONE /* member */, VISION_LAYER);

And this doesn't work... cause as I understand it, both colliders need to match filter/members.
So this works:

let target_layers = CollisionLayers::new(VISION_LAYER, VISION_LAYER);
let sensor_layers = CollisionLayers::new(VISION_LAYER, VISION_LAYER);

But then the target colliders pick up collisions with sensors, which is undesirable

#

Are "asymmetric colliders" not possible?

vestal minnow
#

Collisions are always kind of undirected, it's not "A collides with B" but "A and B have a collision"

#

We should add support for per-entity collision events with observers or one-shot systems eventually, but internally collisions will still be stored as contact pairs like that

oak vigil
#

Ah fair. I could probably just do the filtering on my side

vestal minnow
#

Also kinda unrelated but I'm most likely making collision events opt-in with a CollisionEventsEnabled marker component, very rarely do you actually want collision events for everything

#

Rapier and Box2D have a similar thing

oak vigil
#

I mostly use ContainedEntities. It's my favorite thing lol

#

With Changed<ContainedEntities>, it's great!

#

*CollidingEntities!

vestal minnow
#

Mhmm, I was considering removing it since the new contact graph stuff will allow a similar thing (collisions.entities_colliding_with(entity)), but I'll probably keep it. It's still slightly faster than querying the graph, and the ergonomics of a component for this are nice

vestal minnow
#

this is becoming rather big

#

a lot of things are sooo much nicer and more optimized though

#

Would y'all agree that where applicable, marker components are nicer than bitflags in the API? For example, this:

commands.spawn((
    Collider::capsule(0.5, 1.0),
    ContactPairFiltering,
    ContactModification,
));

is nicer than this?

commands.spawn((
    Collider::capsule(0.5, 1.0),
    ActiveCollisionHooks::FILTER_PAIRS | ActiveCollisionHooks::MODIFY_CONTACTS
));
#

bevy_rapier has a lot of the latter, but I feel like these sorts of bitflags are often exactly what marker components are for in an ECS :P

#

also plays nicer with required components

#

and of course query filters

#

I imagine Rapier's reasoning there is that the internal collider structures use bitflags, and often for e.g. contact pairs you do also want to use bitflags, but using them for the API for body definitions seems very strange to me in an ECS

#

so I think I will go for marker components for enabling collision events and various hooks

cinder summit
#

Or alternatively if they are all literally part of the same thing, like collision layers, or for non-physics stuff, something like file permissions would be an example of that

vestal minnow
#

yeah things like collision layers kinda need to use bitflags

sleek thicket
vestal minnow
#

I guess one minor benefit of bitflags for e.g. these collision hooks is that you can concisely do ActiveCollisionHooks::all(), but for marker components that's just a bundle :p