#Avian Physics

1 messages · Page 31 of 1

past cargo
#

to sides

sleek thicket
#

but why

past cargo
#

why tf i want a dude stand above other?

sleek thicket
#

because it might be fun? D;

past cargo
#

well yes but its a battlegrounds so

#

i have a lot of stuff i want put on it that i did on roblox

#

iam hyped as f

#

like the elemental interactions system i did, so fun

#

otherwise 1 click forward with linear velocity this happens xd

#

infinite slide xd xd

cinder summit
past cargo
#

when there is no floor it will keep moving the character down, checking ofc for a floor on the next translation before set it, if have it will adjust the new y to stand

vague pebble
#

I ran into a interesting issue, I am trying to make a gltf file collidable. Here is my code logic. SOLVED - Forgot to apply apply rotation and scale

pub struct ClientWorldPlugin;

impl Plugin for ClientWorldPlugin {
    fn build(&self, app: &mut App) {
        app.add_plugins(ClientSunPlugin);
        // app.add_plugins(SceneRenderPlugin);
        app.add_observer(map_generate);
    }
}

fn map_generate(
    trigger: Trigger<OnAdd, MapInformer>,
    query: Query<&MapInformer>,
    map_collection: Res<MapCollection>,
    gltfs: Res<Assets<Gltf>>,
    mut commands: Commands,
) {
    let base = trigger.entity();
    let MapInformer(file_path) = query.get(trigger.entity()).unwrap();
    let gltf = map_collection.map.get(file_path.as_str()).unwrap();
    let gltf = gltfs.get(gltf).unwrap();
    let scene = gltf.scenes[0].clone_weak();

    commands
        .entity(base)
        .insert(SceneRoot(scene))
        .observe(make_map_collidable);
}

/// This will replicate only the meshes as from all the entities that we have the only ones who are interesting for client to have are those ones
fn make_map_collidable(
    trigger: Trigger<SceneInstanceReady>,
    children_query: Query<&Children>,
    mesh_3d: Query<&Mesh3d>,
    meshes: Res<Assets<Mesh>>,
    mut commands: Commands,
) {
    let map = trigger.entity();

    for child in children_query.iter_descendants(map) {
        if let Ok(Mesh3d(handle)) = mesh_3d.get(child) {
            let mesh = meshes.get(handle).unwrap();
            // Only make meshes collidable
            if let Some(collider) = Collider::trimesh_from_mesh(mesh) {
                commands.entity(child).insert(collider);
                info!("Collider added to map entity  {}", child);
            } else {
                warn!("Info this entity didnt have a mesh {}", child);
            }
        }
    }
}```
#

The result:

#

As you can see the generate collider meshes are off scale, any dieas on what might be the cause?

past cargo
#

aaa

#

hard than it seens

vestal minnow
#

I think the docs are outdated there though so I need to update those

past cargo
#

@vestal minnow how do you draw the capsule with the PhysicsDebugPlugin?

#

i want draw the shapecast

#

to know where its going

#

i need debug my query.cast_shape_predicate

vestal minnow
# cinder summit BTW <@545959292281552928> review <https://github.com/Jondolf/avian/pull/665> pls...

but a quick Discord review of this is that

  • I don't love the get_ prefix, it doesn't imply anything about being more "contextful" than the normal versions. I just use a _with_context suffix in my implementation.
  • The argument order is a bit weird to me, I think ideally the context versions would be the exact same as the contextless versions, but with an additional argument added for the context (hence the wrappers in my implementation to encapsulate it better)
  • SimpleCollider is pretty nice. I assume the extra params get compiled out if they're not used so it's the same as the old version with no context stuff at all 🤔 (not that a couple extra entities passed as parameters would be meaningful anyway)
vestal minnow
#

(this did not exist when I originally implemented collider debug rendering)

past cargo
#

THANKS Brother

vague pebble
#

Parentless collider act as immovable static objects correct?

past cargo
#
 let shape_hit_data = query.cast_shape_predicate(collider, transform_translation + vec3(0.0,height,0.0), rotation, Dir3::new(Vec3::new(0.0, -height * 1.3, 0.0)).unwrap(), &ShapeCastConfig{
            max_distance: Default::default(),
            target_distance: 0.0,
            compute_contact_on_penetration: true,
            ignore_origin_penetration: true,
        }, &SpatialQueryFilter{
            mask: LayerMask::from(GameMask::Default),
            excluded_entities: ignore_list,
        }, &|entity_found| {
            true
        });
``` so yes i think i did something wrong here, iam trying make it start the cast on top and go down, is the  Dir3 wrong? @vestal minnow idk a lot how your shape cast system works
#

its not detecing the floor

#

nvm, change the max_distance works

vestal minnow
#

your max_distance is Default::default() which is zero for an f32

past cargo
#

yes

vestal minnow
#

so the shape cast won't really go down at all

#

since the distance it's allowed to move is zero

past cargo
#

@sleek thicket to make it float are you using transform.translation.y or linearvelocity?

#

iam using transform.translation.y

cinder summit
# vestal minnow but a quick Discord review of this is that - I don't love the `get_` prefix, it ...
  • Yea I didn't like the get_ either, it was just a minimal rename to get the names back for SimpleCollider. I'll copy the _with_context when I have time
  • The order is definitely a bit weird, I put context in front because it belongs with the collider, but having the Entity scattered everywhere is definitely kinda of a mess, the wrapper seems like a reasonable compromise there
  • I'm pretty sure the Entitys get optimized out since something without context probably won't use them (thought it could in some rare cases be useful for debugging maybe?)
sleek thicket
#

@vestal minnow i realized what was bothering me about joints
they're all just different combinations of constraints for translation and rotation, so it feels like they could've just been components that can combine with each other, using joint component for common data

vestal minnow
# sleek thicket <@545959292281552928> i realized what was bothering me about joints they're all ...

We can and probably will make constraints a bit more composable, but for perf reasons we probably also want to keep joints that directly handle multiple constraints (ex: a revolute joint with both a point-to-point constraint and angular constraint) rather than splitting the constraint solving across multiple different components and having to fetch and prepare things for each of them individually and potentially doing duplicate work. Blindly combining constraints also isn't good for stability in a lot of cases

#

In fact I don't think it even has a spherical joint with limits built in, but you can create it by combining a BallSocket with a SwingLimit (and TwistLimit)

sleek thicket
#

yeah that feels more like ecs

vestal minnow
#

Solving constraints together like this can often give better results in cases where the constraints affect each other

#

plus you can sometimes reuse computations better

#

So I think ideally you can compose lots of small constraints together, but there are also combined constraints like this for the common cases

past cargo
#

cause if set linear velocity up it goes up forever

#

so iam using translation

sleek thicket
unkempt eagle
#

Is there any ragdoll example? I used to use 6dofjoint in Godot to make a ragdoll. Because I wanted to constrain translation and rotation. In bevy with avian, I tried distanceJoint, but I couldn't figure out how to constrain rotaion. Docs say SphericalJoint is for ragdoll. How can I achieve that?

vestal minnow
#

There's no example for this currently, but SphericalJoint attaches two points together, and you can assign a local swing axis and apply limits to constrain the axes of the bodies to be within some relative angle from this axis

#

I'll note that Avian's joints are probably one of its weaker aspects at the moment, as they're not very polished and are missing quite a few features (motors, easy stiffness configuration, etc.)

#

So Rapier has a bit more functionality there. But improvements are planned

unkempt eagle
#

Right, for ragdoll, distanceJoint and SphericalJoint are to be combined.

#

Thanks. I'll check rapier too.

vestal minnow
#

This would be nice semantically, but I think it's important to allow joints to live on their own entities separate from the bodies (this is also needed to allow multiple joints of the same type for a given entity, since duplicate components aren't allowed) and I think with the current relationship system the relationship component has to live on the source entity

#

so it wouldn't work afaik

#

(with one-to-many relationships)

#

If we had many-to-many relationships, we could do JointOf(entity1, entity2)

sleek thicket
#

i guess if it would be multiple of same joints with both entities being same, but i'm not sure how often that happens

#

i was thinking something like entity.Joint(otherentity, JointConstraints)

vestal minnow
#

the joints instead need to live on the web entity or some other external entity (or be child entities or something)

sleek thicket
#

it's not allowed in bevy? from flecs relationship blog it'd be same case as multiple ships being docked to 1 planet

vestal minnow
#

The Bevy equivalent of that would be a DockedTo relationship component on each ship, and a DockedShips component on the planet

#

this is a one-to-many relationship

#

But with the joint example each entity can be constrained to multiple entities

#

which requires many-to-many

#

A character can be jointed to many objects, and many objects can be jointed to it

sleek thicket
#

if the alternative is making each joint into a separate entity, couldn't users just make child entities for each joint instead?

vestal minnow
#

they can yes, but the effect is still the same that each joint is its own entity

#

oh damn we passed 30k messages here today 😛

weary hornet
kind moss
#

I'm having a lot of trouble with penetration and instability in avian2d. Does anyone have any advice on how I can tune things better? In this example the oblong objects is being given periodic impulses towards the mouse and can quite easily burrow into the solid wall. The last couple of seconds of the video are an example of the instability. In that section there are no external impulses being applied but the object still bounces around uncontrollably.

I can increase SubstepCount and that helps but doesn't completely resolve the issue.

When I was using a simple circle collider for the active object things were much more stable but I was still getting a lot of penetration. I'd like to find a way to tune things so I can continue using trimesh colliders though, because they're very convenient.

#

I'm using 1px==1unit scale so my forces are quite large. Is rescaling stuff likely to help? I have the length_unit set so that the oval player object is roughly 1 length_unit long.

weary hornet
kind moss
#

With a single large trimesh collider. So those aren't individual triangle colliders or anything like that.

sleek thicket
weary hornet
#

Yeah -- hmm. The 1px == 1unit does stand out to me as something that could possibly be the problem but I really dont know for sure

sleek thicket
weary hornet
#

Oh ok, maybe dont listen to me then. I havent really done 2D in bevy

sleek thicket
#
.add_plugins((
            DefaultPlugins,
            // A 2D game with 100 pixels per meter
            PhysicsPlugins::default().with_length_unit(100.0),
#

^ just needs this thing

kind moss
kind moss
sleek thicket
#

ok 1006500.0 seems excessive

weary hornet
#

Yeah that's a big number, I wonder if this is a floating point precision issue

kind moss
weary hornet
#

that's one heavy ass egg

sleek thicket
#

i didn't touch external impulses so it might be fine, but it might be an issue with weight/density of collider

weary hornet
#

I've really only been in the kinematic rigid body world so I actually dont know the answer, is there a Mass component?

kind moss
#

Oh... oh, crap. I did set a mass. I'd forgotten about that. And it's pretty high. So maybe that's my issue.

sleek thicket
#

mesh vs mesh collision could also be contributing to it

#

especially if player isn't convex

weary hornet
#

What if you use a capsule instead of an egg mesh, would that give the desired gameplay feel though?

sleek thicket
#

i'd use composite collider

weary hornet
#

oh

sleek thicket
#

2 circles and 2 boxes

weary hornet
#

or even just 3 circles

sleek thicket
#

no idea if it'd be better though

#

but worth having an extra way to test collisions

kind moss
#

Fixing the silly mass I had set gets me 90% of the way there.

#

It still penetrates a little but it's no where near as bad.

weary hornet
#

whats the mass now

#

maybe just put it to zero

kind moss
#

I could go to simpler colliders, and maybe that's my best long term solution. But I kind of want to keep the trimesh just so I can have a simple blender->bevy workflow.

weary hornet
#

Well the world should definitely try and remain a trimesh, I think. But does the player need to be a mesh is the question

sleek thicket
#

primitive/compound for dynamic is usually the best choice in every engine

vestal minnow
#

dynamic bodies definitely shouldn't use a trimesh if you can avoid it, the shape in the video can probably just use a convex hull or some primitive shape

kind moss
# weary hornet maybe just put it to zero

Zero is no good because avian treats that as infinity. Setting it to a low mass, like 0.01 with my dash strength being 1.0-10.0 gives me roughtly the same results as a mass of 1.0. So I think that so long as it's not 1000.0 it's pretty similar.

kind moss
weary hornet
#

ah.

Ok well here's my thoughts:

  • use a primitive or convex hull for the player as suggested
  • absolute worst case you can predict the trajectory and do some shape casts, particularly for the scenario where you're "drilling" into the ground.
kind moss
weary hornet
#

ya absolutely

vestal minnow
#

can also add the SweptCcd component for the sweep-based continuous collision detection

kind moss
weary hornet
#

I'm actually impressed tri-mesh on tri-mesh collision is working at all

#

that sounds hard to do math wise

kind moss
#

It seems fine like 80-90% of the time.

kind moss
#

Switching back to a circle collider and fixing my weird masses seems to have fixed all my problems. Thank y'all.

#

What is the best practice way to set the mass of a body? Mass is ignored if the body has child colliders. I'm currently setting the ColliderDensity of all the children to zero which feels a bit clumsy. It looks like I can modify ComputedMass after it's calculated but it'll be overwritten again if anything about the body changes. It would be nice to have a way to set a canonical mass for cases like mine where I'm trying to get more arcade style physics.

#

Or, I guess Mass isn't ignored but is instead added to the mass of the children? Either way, it doesn't seem to be possible to use it to set the mass to a fixed value.

sweet sundial
#

set Mass to your desired mass minus the total child mass?

kind moss
# sweet sundial set Mass to your desired mass minus the total child mass?

I guess I could have a system that does that after the object is spawned. I was just hoping for a simple way to configure it so that the mass stays the same even if I adjust the player's colliders. So I don't have to retune all the jump strengths and such. Setting the colliders to a density of zero works but it seems like a hack.

dark swift
# weary hornet Hey just curious, did you look at this? Was this getting stuck on walls? Curious...

I wasn’t able to use the Avian examples as is because they all accounted for gravity which I didn’t want for a 2D top-down. I referenced those examples as part of what I did but I found that vidar was a better example, but in 3D. The Avian examples even say they're not complete examples. I’m also having rollbacks with lightyear but I didn’t have them until I started using the main branch. 0.19 seemed to work fine. I’m still not sure if it’s my code or just the changes on main. I've had a really hard time finding some blessed "correct" way, especially for 2D top-down, hence why I shared that code

sleek thicket
kind moss
kind moss
sleek thicket
sweet sundial
#

or something

kind moss
sleek thicket
#

i got confused the first time too tbh, examples should've been in past tense

kind moss
#

Ok, so I guess NoAutoMass is what I'm lookng for.

#

Thanks for that link by the way. That's a super helpful writeup.

weary hornet
dark swift
vestal minnow
weary hornet
#

So it's kiiind of cool but also really annoying 🤣 what could I do to make it slide more instead of trying to roll along the walls? The collider is a sphere.

#

Maybe use a cube instead?

#

nah cube felt worse

#

ok lowering the friction did it

vague pebble
#

Curious, if colliders have global transform why dynamic rigid bodies, dont require them?

slender lotus
#

hi, anyone knows when avian updates the physical world with newly added rigit bodies? i spawn my rbs in PreStartup and want to do a raycast for them in PostStartup but they dont seem to actualy "exist" yet. if i run the system in update all is fine.

#

and by implication does anyone know how i can force this "realisation" step?

kind moss
#

Maybe you could try to run that schedule yourself but I'm not sure there's an easy way to do that. It's almost certainly easier to wait for it to happen naturally. Why do you need to be running your code in PostStartup?

#

In my stuff I have systems that query on Added<RigidBody> which lets me react to physics objects as soon as they are created and ignore them afterwards. That might work for you.

slender lotus
#

thx

#

i need to run it somewhere in startup as what im doing is using the rigit bodies as terrain and want to shape cast agains them to fill a grid with where obstacles are and where not ( to then run my pathfinding on)

slender lotus
#

a bit jank but better than running a seperate app instance to bake this XD

kind moss
slender lotus
#

yes later ill use this

#

but i dont want my code to be dependent on this to make it work

slender lotus
#

so addin it with different scedules is not posible

#

im prety sure this cant be that hard

#

as this probably is nto such a niche thing?

kind moss
#

I think the most common way of doing this kind of thing is to have a marker component like TerrainReady that indicates that the terrain is ready for use and then using things like Added filters on queries to do whatever processing steps are needed over the course of a few ticks and when everything is done you add the TerrainReady component which the rest of the game looks for. That way you don't have to change any schedules or do anything weird to the internals of the physics system.

#

States are the other way I've seen people do it. You put all your terrain generation systems in one state and all you gameplay in a second state and only transition to the second state once generation is complete.

slender lotus
#

how can i tell that the physics system did its thing?

kind moss
#

I would use something like Query<Entity, Added<RigidBody>>. That query will give you a list of entities which have been added in the current tick.

slender lotus
#

i think statest prob would be the right aproach but i need to know when physics did its thing

slender lotus
kind moss
#

Right. Hmm.

#

Maybe it's enough to just wait for a single tick to pass after you add the objects? I don't see an obvious marker component that avian itself uses to indicate it's finished setting up a rigidbody. A bunch of stuff gets added but nothing like RigidBodyReady

slender lotus
#

probably works but thats awfull XD

#

having some update steps be different from others already is bad design but having it not as a logical dependency but a timely one is to much XD

#

but im prety sure there should be some sort of marker

kind moss
#

I don't know for sure but I suspect that it always takes avian exactly one tick to finish so the strategy of waiting isn't that bad. If it takes more time, because there's an async process or something, then I agree it's ugly.

#

But like I said, I don't know. I'm pretty new to avian and haven't looked at the internals much.

slender lotus
#

i thin its a hack wort trying

#

but its still a prety strong hack

slender lotus
#

rn im trying this

#

and it actualy worked

#

somewhat ...

kind moss
#

Nice

slender lotus
#

follow up question. maybe u know that too how do i shapecast exactly in one position? and nto stride in some way?

#

basicaly im trying to cast a rectangle for each cell to see if it intersects with the terrain

kind moss
#

I've not done anything with shapecasts so I'm not sure.

slender lotus
#

shape_intersections worked

slender lotus
kind moss
weary hornet
#

I just want to say congrats to Jondolf. This is a networked dynamic body I'm controlling. I'm purposely bumping into walls at fast speeds to try and desync it. Note I'm just testing it locally but it seems pretty damn deterministic. I've never had this experience with a physics engine before.

slender lotus
#

later we want to put something like pheromones onto the grid to force enemies to not go where they probably die

candid niche
#

Can someone give me a quick and dirty dynamic rigidbody vs Kinematic Body for dummies for me? My current understanding is that Kinematic Bodies don't have any forces applied to them without it being programmed to, and they detect collisions but again won't have force applied unless programmed to. Meaning a Kinematic Body will just move through a static Rigidbody unless programmed otherwise, right?

cinder summit
#

It's uncommon to see them outside of character controllers (tho those can be dynamic too ofc), but there are some examples where you want bodies to move and apply forces to other things, but not be affected by forces. One such example would be moving platforms

candid niche
#

That makes sense. I'm trying to figure out what to make my characters. I'm starting to think they should be dynamic because any wall or box or anything I want them to collide with. The only other things I won't want them to collide with would be other players and one object, which I can just program to manually ignore yeah?

Then things like projectiles that I want going through walls and only collide with players I can make Kinematic...

kind moss
#

You can also use CollisionLayers to control what collides with what.

candid niche
#

That's true. If I had a Kinematic Body projectile and it collided with a dynamic rigidbody, would the dynamic rigidbody be pushed by default?

vestal minnow
#

Yep

sleek thicket
sweet sundial
#

probably not what you meant, but now i'm trying to think of applications for runtime switching between dynamic and kinematic on a single rigidbody

vestal minnow
#

changing a kinematic character to a dynamic ragdoll is pretty common

#

though for a ragdoll you need multiple bodies so it's not necessarily switching a single body

wide oar
#

I have a question about animated physics bodies,

if I have a kinematic rigid body that is being animated by an AnimationPlayer, how do i make sure that collision works properly?
As in it doesn't teleport the object which makes collision not work nicely..

past cargo
#

@vestal minnow does something reduce the linear velocity y even with gravity scale 0?

#

the gravity scale is 0 but when i set linear velocity to a number it suddenly set for 0 after a time

#

@sleek thicket hey bro

#

i calculate how many studs the player need go up from floor

#

like 0.1

#

altought if i do linearvelocity.y = 0.1 it take a big time to go up until 0.1 studs

#

how calculcate the correctly linearvelocitty to reach the amount i need?

#

i tryed multiplie by computed_mass.value()

sleek thicket
past cargo
#

iam trying use externalforce now

#

cause linear velocity is slown as hell

chilly cradle
#

Is there a good way to know if something is inside of another collision meshes geometry?

#

I saw the Sensor example and have implemented a similar setup in 3D, but the problem I'm having is the CollisionEnded events fire while the colliding object is still within the Sensor's geometry

#

It seems the the CollisionStarted and CollisionEnd only care about the external geometry collision, once something is completely inside the mesh it's treated the same as if it's left the mesh entirely

#

Thinking about it this may be due to the TrimeshFromMesh ColliderConstructor I'm using. I'll have to take another look at that and see if there's an internal one too

#

Otherwise I'll have to switch to using something like big_space's grid system for spatial querys

sweet sundial
#

convex decomposition?

kind moss
#

Oh, never mind. That's what you were already saying.

chilly cradle
marble cradle
#

does avian give acceleration data ? like of a character (tnua controller)

sweet sundial
#

there's the ExternalForce/Impulse/Torque components

#

only works if that's how it's applied though

vague pebble
#

Is there any distinc difference between the collisions of a entity with a child collider and one with a collider itself?

kind moss
past cargo
#

is parallel feature enabled by default?

#

@vestal minnow ?

vestal minnow
chilly cradle
#

Did I see correctly that there was a branch/fork that added support for big_space?

sweet sundial
#

found #1124043933886976171 message , but there's also more recent mentions

chilly cradle
#

I saw that one, couldn't see any more recent mentions but I'll take another look

cinder summit
#

I'd imagine auto complete would absolutely hate that function signature tho 😂

cinder summit
little maple
#

is there a simple way to create a dynamic rigidbody that is frozen in place until something hits it?

maybe I just give it zero gravity and then add gravity when it's hit 🤔

sleek thicket
little maple
past cargo
#

static does it

#

its a wall

past cargo
#

i would suggest just make a collider without rigid body and keep checking is something hitted on it with shape cast

#

if hitted turn it into a dynamic body

little maple
#

I suspect sleep + removing gravity might make it behave the way I want

past cargo
#

how do you think collisions are made?

sleek thicket
little maple
little maple
#

but otherwise, that worked perfectly

cunning gust
#

How do I get the velocity at a specific point on an object?

#

I want my character to move with the point they are standing on

#

so if the platform moves or rotates, they move with it

#

wait no

#

now I'm getting confused about how to use this

#

I've just got back to bevy after a break lol

cunning gust
#

Nevermind. I didn't know what worldquery meant

cunning gust
#

orrr not

#

I am in need of some handholding I think

#

how do I get the velocity of a point of a specific entity

kind moss
cunning gust
#

I have an entity id stored in some variable. How do I go from that to running that method

kind moss
#

Oh, you mean how to you get the RigidBody?

cunning gust
#

the RigidBodyQuery

kind moss
#

If you know it's entity then you can use Query<&RigidBody> and just call get(entity) on that.

cunning gust
#

Either way

#

wait

#

oh

#

ohhhhh

cunning gust
#

as in, is it at instantiation or first call

kind moss
#

Normally you would recieve them as the parameter to a system function. It sounds you you aren't using a system? In that case it gets a lot more complicated. You probably should be in a system.

cunning gust
#

I am, I'm wondering because I don't want Query<RigidBodyQuery> to contain every single rigidbody's rigidbodyquery only for me to use one

#

get_floor_velocity is the system I'm working on rn

kind moss
#

You shouldn't need to worry about that. The ECS is very good at fetching only data that's needed.

cunning gust
kind moss
#

I said to add it to LinearVelocity but take that with a grain of salt. I'm not what exactly the docs mean by Computes the velocity at the given point relative to the center of the body. Is it the point that's relative to the center or the velocity? It's probably more likely that the point is in local coordinates and the velocity is in global coordinates, in which case you don't need LinearVelocity at all. But I'm not sure.

cunning gust
#

but uhh

#

problem

#

It doesn't account for rotation since the origin is rotation

#

that's why I wanted it in the first place 🙃

#

so I'm stuck

kind moss
#

So it's returning the velocity in local coordinates?

cunning gust
#

is there any way to move relative to a point on an object that takes into account the object's rotation?

cunning gust
kind moss
#

That should also work with velocity vectors I think?

cunning gust
#

What I mean is like

#

we paint a dot on the object

#

and we're moving relative to that dot

#

and the object can move around and rotate

#

well

#

more accurately I just want to know where the dot is

#

and I want to know it's velocity

#

so I can move something with it

#

what I mean is

#

idk how to explain it better, I'm sleepy

kind moss
#

Can you parent the object to the thing it's supposed to move with? That might just get you all this for free.

cunning gust
#

but it's important that I have the dot's velocity

cunning gust
#

(trying to save myself a headache down the road if I do that for whatever reason)

#

I don't want to modify the "floor" (the entity the dot is on) at all

kind moss
#

Since objects are all rigid in avian you only have a problem if the object has angular velocity, right? If it's not currently rotating then the velocity at every point will just be LinearVelocity.

cunning gust
#

I already have code that does the math to just figure it out using angular velocity and a point but it doesn't work in the event of nested rotating objects and other converted situations

cunning gust
#

I need it to work with rotating objects

#

It already works with ones that don't rotate

kind moss
#

Can rigidbodies even be nested like that? I thought they couldn't.

cunning gust
#

and rigidbody is just a component, so entities with it can be nested like any entity methinks

kind moss
#

Huh, for some reason I thought only the outermost RigidBody actually got simulated. But I guess not. Then can you walk the hierarchy and add up the local velocity_at_point results?

cunning gust
#

It might be a bug

#

if it accounted for AngularVelocity it would be fine

#

but it doesn't

kind moss
#

That sounds like a bug to me, then.

cunning gust
#

also the description makes no sense with that behavior. It should return 0 for non-rotating bodies and account for rotation for rotating ones

#

either way, I want a working velocity_at_point that's in worldspace basically

kind moss
cunning gust
#

since the body origin moves with the rest

kind moss
cunning gust
#

wait

#

ok something is definitely weird one sec

#

I just realized it doesn't return identically I just misinterpreted something in my sleepy state

#

gimmie a sec

#

wait no it is identical

#

hmm

#

It might be because I'm asking about a point that's technically above the model by a smidge

#

since it's the bottom of the player instead of the surface

#

if raycasts let you see where they hit this would be easier lol

#

gimmie a sec to try and ask it about where it got hit

#

yeah no I can't get it to work

#
fn get_floor_velocity(
    mut player_query: Query<&mut PlayerData, With<Player>>,
    ray_query: Query<(&mut RayHits, &RayCaster), (With<PlayerFloorCaster>, Without<Player>)>,
    floor_query: Query<RigidBodyQuery>,
) {
    let mut entity: Option<Entity> = None;
    let mut hit_point: Option<Vec3> = None;
    for (hits, caster) in &ray_query {
        for hit in hits.iter() {
            entity = Some(hit.entity);
            hit_point = Some(caster.origin + caster.direction * hit.distance);
        }
    }
    let mut floor_velocity = Vec3::ZERO;
    if let Some(hit_point) = hit_point {
        if let Some(entity) = entity {
            if let Ok(floor) = floor_query.get(entity) {
                floor_velocity = floor.velocity_at_point(hit_point);
            }
        }
    }
    for mut player_data in &mut player_query {
        player_data.floor_linear_velocity = floor_velocity;
    }
}
kind moss
cunning gust
#

hmm

#

Either way, since this is local anyway and not in world space, it's basically a non-functional version of what I had before

#

and I'd need to recursively do the calculation

#

at this point, I'll probably just do that

kind moss
#

I'm hazy on ray casting but it doesn't look like you're selecting only the nearest hit? Are you sure the floor you end up selecting isn't some distant one?

cunning gust
cunning gust
#

or something extremely small, I forget

kind moss
#

Ok

cunning gust
#

and as a final thing

#

do you know if collisions or air resistance are simulated first in the physics schedule

#

if you don't I'll just check myself

kind moss
#

I don't, sorry.

cunning gust
#

alr

cunning gust
#

Does anybody know when gravity is simulated?

#

As in, in what schedule and step?

#

nevermind

#

I always ask questions just before I find the answer lol

cunning gust
#

@sleek thicket how'd you know lol

vestal minnow
#

If the offset is zero, the point velocity will be the same as the body's linear velocity, since angular velocity won't have an effect at the center of mass; otherwise, the point speed should be larger if angular velocity is non-zero

#

This is the exact same as bevy_rapier's linear_velocity_at_point, except the point is given relative to the center of mass to avoid having to compute it in the method every time. Also similar to GetPointVelocity in Unity.

#

It could be changed to take points in global space, not relative to the center of mass, but this would be useless for Avian internally since we need them to be relative for the contact solver. RigidBodyQuery isn't necessarily intended for users, its main purpose currently is to make internals a bit less annoying

#

The point velocity is also very simple to compute manually, it's just

lin_vel + ang_vel.cross(offset)
#

I've considered combining LinearVelocity and AngularVelocity into just Velocity like in Rapier, which would let us add an at_point/at_offset helper for it directly. I'm not entirely sure if I like it otherwise, but I would be open to trying it if people would prefer that

thin osprey
#

when I checked a while back there was an issue where this crate was using a dependency that couldn't be used for commercial products. I suggested that it was put in a feature flag so we could avoid the issue, just wondering if it's still a thing or can avian now be used for commercial stuff?

vestal minnow
#

But (I am not a lawyer) realistically I think the risk is extremely small. XPBD is quite widely used in a number of open source and commercial projects, the inventors of the method have themselves published XPBD implementations under the MIT license, and when we asked about it, they even responded to us saying that there shouldn't be any restrictions in using it. And looking at the patent, it doesn't seem very enforceable, and I don't think it even applies in the EU where I live (but again, I am not a lawyer).

#

Also, Jolt uses XPBD for soft bodies, and Jolt is officially supported as an option for physics in Godot.

#

That being said, we do still plan on most likely switching away from XPBD for joints, and I have it partially implemented already; it's just a lot of work and takes time

thin osprey
#

alright I might give avian a try then, would be interesting to see how it differs from rapier in terms of an end user perspective

cunning gust
#

I can do more testing later today

past cargo
#

@sleek thicket

pub fn adjust_collider_float(
    mut character_query: Query<(&CharacterController, &Collider, &Transform, &mut ExternalForce, &mut LinearVelocity, &ComputedMass), With<CharacterController>>
){
    for (character_controller, collider, transform, mut external_forces, mut linear_velocity, computed_mass) in character_query.iter_mut(){
        let capsule_collider= if let Some(capsule) = collider.shape().as_capsule() {capsule} else {continue};
        let height: f32 = capsule_collider.height() + (capsule_collider.radius * 2.0);
        let half_height = height / 2.0;
        let current_translation = transform.translation;
        let mass_value = computed_mass.value();

        if let Some(ref shape_hit_data) = character_controller.shape_hit_data{

            let ground_point = shape_hit_data.point1;
            let float_point = (ground_point.y + half_height) + 0.1;
            let stand_difference = current_translation.y - float_point;

            if stand_difference.abs() <= 0.01 {
                if linear_velocity.y != 0.0 {
                    linear_velocity.y = 0.0;
                }

                if external_forces.y != 0.0 {
                    external_forces.y = 0.0;
                }
            }else if stand_difference > 0.0 {
                external_forces.apply_force(Vec3::new(0.0, stand_difference * mass_value, 0.0));
            }else {
                external_forces.apply_force(Vec3::new(0.0, -stand_difference * mass_value, 0.0));
            }
        }
    }
}
#

did

#

and its working

#

floats 0.1 from ground

sleek thicket
past cargo
#

xd

#

but

#

its fine this way?

sleek thicket
#

if you're happy with it then w/e

#

but it would be 2 lines of code if you watched it

past cargo
#

xd

sleek thicket
#

and you'd actually understand what you're doing at the same time

#

applying as force instead of velocity might be really cool for your game though

past cargo
#

iam remaking this game

#

spellbreak

sleek thicket
#

like if you have some gravity ability that increases enemies' weight and they start crouching because of it

sleek thicket
# past cargo spellbreak

ah yeah, they shot themselves in the foot by choosing UE for something so complex, didn't they

past cargo
cinder summit
#

wdym used all their money on one streamer? thonk

past cargo
#

proletariat

grizzled junco
#

marketing?

past cargo
#

all gamee they did were GOOD GAMES

#

but they alwasy fuck up

#

on ads

past cargo
#

seens the worst stuff possible

cinder summit
#

Like they spent their whole promotion budget on getting one streamer to stream the content? 🤔

cinder summit
#

What even ... Most game developers literally don't even pay streamers for promotion

past cargo
#

spellbreak is legit the best game i played so far in 5 years

#

still, it died cause dumb decisions

#

and have a big community rn that plays the open source version

#

that sadly cant keep because copyright

#

so iam remaking it but with unique stuff to avoid copyright

#

making like that i will have a big community already xd

sleek thicket
past cargo
#

fortnite

#

talking about competitive games btw

sleek thicket
#

oh, that explains a lot

past cargo
#

spellbreak was competitive, had tournaments and all

past cargo
sleek thicket
past cargo
#

ik cause i followed the game since start

#

they started get lazy with updates and giving content comunnity didnt want

#

and again, LACK OF ADS

#

like 0 ads bro

sleek thicket
#

i don't think ads could help them in the first place

dreamy viper
#

I wonder if Position should required Transform; i've had many issues where i was missing cases where Position was added on an entity but no Transform

#

so things like position_to_transform sync would not work

past cargo
#

Games that don't come from a well-known company or a big franchise need ads

#

a example is Vaultbreakers, a new game that is on test phase, i found it cause constantly ads on youtube

#

otherwise i would never find it

#

now if resident evil 10 releases for example they BARELY neeed ads

#

since its a big franchise alraedy

sleek thicket
#

because the target audience is the one that's most likely to have adblock installed lmao

past cargo
#

youtube ads, trailers, multiple streamers

#

i never see it on spellbreak

#

they put all the money on one streamer guy

sleek thicket
cinder summit
#

i never saw ads for vaultbreakers

past cargo
cinder summit
#

But also this seems pretty unrelated to physics, might be better to move to #off-topic 👀

past cargo
#

it appeared on my youtube recommendations

#

sorry @cinder summit -senpai

cinder summit
dreamy viper
#

Yeah, it's just annoying because i'm replicating Position and i keep expecting things to work, but most avian systems do the position<>transform syncs only for RigidBodies

cinder summit
#

That said the whole situation with Transforms sucks, and ideally we could just have something that avian could use directly and thus eliminate this whole class of problems

dreamy viper
#

yeah it's a huge annoyance

#

I mean the separation between Position/Transform might be necessary/good though

dreamy viper
#

Transform could be modified for various reasons (visual interpolation, etc.) which doesn't mean that you should send a replication update

#

it's cleaner to have a dedicated component Position for FixedUpdate concerns

#

ah I see

dreamy viper
sweet sundial
#

is there a good way to play sounds on each collision, with scaled volume by either applied force or energy loss? Res<Collisions> seems to only ever give non-zero total_normal_impulse when during_previous_frame is also set

plucky elbow
#

anyone know how to impl avian collisions for bevy_voxel_world?

worldly cove
#

Is it possible to offset a cuboid collider on a gltf model? My buildings are off the ground by 50%. I've searched and it looks like this might be a common issue, but I don't see what the solution is. I tried changing the origin point of the model in Blender (doesn't work), and offsetting all the vertices so half the model is below zero (works, but it's not ideal - I'd have to duplicate/automate models in my project). Here's how I'm spawning the gltf scene:

commands.spawn((
  SceneRoot(
    asset_server
      .load(GltfAssetLabel::Scene(0).from_asset("models/shop.glb")),
  Transform::from_xyz(pos.x, pos.y, pos.z),
  Collider::cuboid(size.x, size.y, size.z),
  RigidBody::Dynamic,
  CollisionLayers::new([Layer::Buildings], [Layer::Terrain]))
));
sleek thicket
#

it seems like the model's origin is at bottom

worldly cove
#

It seems like the model origin has no effect on the collider. If I change the origin from the base to the center, then it doesn't modify where the collider is (the building floats in the air - the same as if the origin is at the bottom)

#

But if I move all of the vertices manually below zero, then it does work. I can do that if I have to, but I was hoping there'd be a way to specify a manual offset. (This is using a hand-rolled cuboid collider, not the generated trismesh collider.)

vestal minnow
#

via Transform

worldly cove
#

Thanks, perfect!

plucky elbow
worldly cove
#

I did apply all transforms... do you think changing the origin should affect the position relative to the collider? I will go with Jondolf's suggesting of offsetting via a child anyway (as I'd like the origin to be the pivot point at the base of the building), but I have no idea what I've messed up if changing the origin /should/ work!

thin hare
#

hey @vestal minnow are there any good papers/videos that you found helpful while building avian? I'm working on building a (much simpler) physics engine in zig but I don't have a formal maths education

past cargo
#

zig?

past cargo
#

just use chat gpt to get the math formulas

#

and examples on how implement on others languages

thin hare
#

Someone in the zig discord mentioned The orange book (real-time collision detection), so I'm going to start there

past cargo
#

you can use parry also

past cargo
#

you could contribuit

plucky elbow
thin hare
#

zig has several, I will likely contribute to some in the future but I'm building this physics engine largely to teach myself more about game physics so that I am less reliant on external engines

past cargo
#

lol

#

much easier

thin hare
#

Whatever floats you're boat, I personally don't like to use LLMs ever

grizzled junco
#

easy but not reliable at all

#

easy for 1 + 1

#

the more complex the problem the more they will hallucinate

grizzled junco
#

also, is there no physics engine built in pure zig?

thin hare
#

Didn't see that channel existed, thanks!

#

There probably are, but I'm trying to build one myself, and I don't believe any of the existing engines will be as mature as avian

grizzled junco
sleek thicket
vestal minnow
thin hare
#

Reading it now, thanks a ton, this is a lot of useful material

white garnet
#

is it possible to create "inverse" colliders? e.g. if I wanted to create a sort of game arena, could I do something like .capsule()..invert() where only the inner part would be accessible and everything outside would be a colission?

sleek thicket
plucky elbow
#

That's how I get inverted meshes at least

vestal minnow
#

(excluding NiseVoid's SDF colliders I guess)

white garnet
sweet sundial
#

just do like ten halfspaces

chilly cradle
vague pebble
#

@vestal minnow Sorry for ping, but do you think it is a good idea to make a component that stores the contact manifolds of an entity? On that frame

#

Similar to colliding entities in this case

vestal minnow
#

the internals wouldn't use the component either way, it'd be way too expensive and make parallelizing the narrow phase much harder / impossible

#

if you want to access contacts for an entity, use the Collisions resource

past cargo
#

Jondolffff

vague pebble
# vestal minnow This would copy all the contact data to multiple places (`Collisions` resource +...

Yes, you are completely right. Could you give me your take on this? Lightyear needs to rewind collisions to the tick rate at server, when a predict rd entity Rollbacks. Right now he can only rollback components sent in the same predicted packet (cant include resources because reasons). My idea - Store collision forces applied to that entity in server tick, on rollback instead of using the new sim forces use server replicated "forces", by overriding the forces in colllisions. This would be a temporary solution, only until resource as entities. Btw lovely documentation, collisions is truly a powerfull struct

cinder summit
vague pebble
#

We could also make, so collisions is converted into some sort of pseudo entity. Seems weird tho and unsafe

vague pebble
#

I wonder how did you handle collisions?

cinder summit
#

In the case of Collisions I just roll it back to what it was on that tick, the mispredictions caused by them being out of sync disappear within a frame anyway

#

Tho disabling warm starting is also an option so it no longer affects determinism 🤔

#

There are also some annoying edgecases with Collisions where my code ends up removing it because it wasn't there in the history and then avian panics 😂

vague pebble
past cargo
#

Interesting

cinder summit
#

I rewind it to whatever it was on the client at the tick I am rolling back to, then leave it alone as I resimulate (same as for predicted-only components, tho unfortunately I have to special case resources so they have more scuffed code)

#

The tick I roll back to in turn is the oldest tick I received data for

past cargo
#

Nise your game looking great

vague pebble
cinder summit
vague pebble
#

Ah I see, I dont think I can do that in lightyear the refactor involved,might get me shot by Periwink. I guess the logic is more rewind precise factors

cinder summit
#

Yea it's really not well suited to lightyear's impl. On the plus side disabling warm starting and upping substeps to compensate is more viable if you don't predict the whole world

vague pebble
#

Increasing precision, might not fix my problem tho. One slight mis prediction and it is goodbye alignment. I guess although it increases packet size, delta compression could easily avoid redundant big chonky collisions packets

cinder summit
#

Yea it's removing the non-determinism, and warm starting causes that if it's not replicated

#

Delta compression definitely could help, but you might also want more locality than the whole resource

vague pebble
dreamy viper
vague pebble
cinder summit
#

I assume the way it works in lightyear is that you'd have to roll it back to the newest confirmed tick for your predicted entities (often just the player), then resimulate from there ... But thay still gives you less ticks to smooth stuff out + collisions with aything interpolated would always cause it to be wrong

dreamy viper
#

Can you explain more why it would work in your case and not mine?
That's correct, I revert Collisions (which is non-networked) to its last client state at the start of the rollback tick (which is usually slightly different from the state of the resource on the server). Then I do a normal rollback on every predicted entity. There are no interpolated entities, everything is predicted. I don't understand if you're doing anything different than this?

dreamy viper
#

I don't understand what this means: "Yes, but if there is state for the next frame I load that, and the mispredictions disappear in no time, since eventually both sides have the same collisions happening on a tick"
You reload state from two consecutive ticks?

cinder summit
#

While if you don't assume you have to resimulate every frame after changed state anyway, you can just start at 3 in this case, or 5 if e1 wasn't there

#

In essence that means my client's simulation will almost always resimulate until it is exactly the same as the server

dreamy viper
#

Hm i still don't get it; in my cases all entities are at tick 10, I receive an update from the server with the state of all entity states at tick 3. I revert Collisions to tick 3, I revert all entities to the server-state of tick 3, and resimulate 3-10.
The issue is that since Collisions is slightly different so I end up getting slightly different values at the end again

#

I need to go to work but i'm interested in discussing further! thanks for sharing this

past cargo
#

and its causing me issues

#

but its defi not two lines of code

#

iam having problems to implemnt it anyway

#

can i see your one?

cinder summit
#

You mean the code for calculating the floating force? 🤔

past cargo
#

rn i did it myself, but for that i made it 0 gravity

#

the proble mis

#

when iam making the character go down after jump

#

its go under the floating point and takes a bit time to start floating again cause the forces

#

let me show the issue to be hoenst

cinder summit
#

I have 3 lines for the floating force code ... Tho I do also disable gravity (using GravityScale)

fn calculate_float_force(ground_distance: f32, velocity: &LinearVelocity, ground_vel: Vec3) -> f32 {
    let relative_vel = velocity.y - ground_vel.y;
    let snap = ground_distance - FLOAT_HEIGHT;

    -(snap * FLOAT_STRENGTH + relative_vel * FLOAT_DAMPING * TICKRATE as f32)
}
sleek thicket
past cargo
sleek thicket
past cargo
#

you disable gravity too?

sleek thicket
#

yeah

past cargo
#

well that is the issue iam having, look

#

wait its loading

sleek thicket
#

if ray doesn't hit ground you're in air, so you just apply gravity there and add to coyote time counter

past cargo
#

what is coyote time counter?

sleek thicket
#

it's a counter for coyote time 👍

past cargo
#

what is coyote xd

sleek thicket
vague pebble
past cargo
cinder summit
#

I wonder how much of a crime my character controller is, I remember it was awful and then I improved it slightly, but then I added features I never tested 🤔
Probably some good nightmare fuel for @sleek thicket at least 🤔

#

Oh and const values for @vague pebble 😂

past cargo
#

well

#
pub fn adjust_collider_float(
    mut character_query: Query<(&CharacterController, &Collider, &Transform, &mut ExternalForce, &mut LinearVelocity, &ComputedMass, &CurrentStates), (With<InteractNetworkAble>,With<CharacterController>)>
){
    for (character_controller, collider, transform, mut external_forces, mut linear_velocity, computed_mass, current_states) in character_query.iter_mut(){
        if current_states.contains_state(&States::Jumping) || current_states.contains_state(&States::Falling) {
            continue;
        }

        let capsule_collider= if let Some(capsule) = collider.shape().as_capsule() {capsule} else {continue};
        let height: f32 = capsule_collider.height() + (capsule_collider.radius * 2.0);
        let half_height = height / 2.0;
        let current_translation = transform.translation;
        let mass_value = computed_mass.value();

        if let Some(ref shape_hit_data) = character_controller.shape_hit_data{
            let ground_point = shape_hit_data.point1;
            let float_point = (ground_point.y + half_height) + FLOAT_DISTANCE;
            let stand_difference = current_translation.y - float_point;

            if stand_difference.abs() <= 0.005 {
                if linear_velocity.y != 0.0 {
                    linear_velocity.y = 0.0;
                }

                if external_forces.y != 0.0 {
                    external_forces.y = 0.0;
                }
            }else if stand_difference > 0.0 {
                external_forces.apply_force(Vec3::new(0.0, stand_difference * mass_value, 0.0));
            }else {
                external_forces.apply_force(Vec3::new(0.0, -stand_difference * mass_value, 0.0));
            }
        }
    }
#

this is how i am doing

cinder summit
#

Wait why do you invert stand_difference in one case? Isn't it supposed to actually go the other way if it becomes negative?

past cargo
#

what

vague pebble
vague pebble
#

I was about to do that

cinder summit
past cargo
#

there is no gravity, if i make it go up than on next frame i need make go down, otherwise it keep going up forever

#

😭

#

and when i make going down that is being the problem

cinder summit
# past cargo wydm

This makes it always only go one way no?

}else if stand_difference > 0.0 {
    external_forces.apply_force(Vec3::new(0.0, stand_difference * mass_value, 0.0));
}else {
    external_forces.apply_force(Vec3::new(0.0, -stand_difference * mass_value, 0.0));
}
```Like if stand_difference is negative you make it positive again 🤔
#

But also why is the force so small and why is there no damping?

sleek thicket
past cargo
#

plus i never did it

past cargo
past cargo
sleek thicket
#

i think it was explained better in the car one

past cargo
sleek thicket
past cargo
#

the problem iam having is when i try make the character go down when there is no floor

#

i keep like

#

wait let me show

#

linear_velocity.y -= gravity_force.abs()

#

every frame

#

aaa i will try play to show what i mean

#

when rust over stop bugs

past cargo
#

@cinder summit

#

see

#

it takes a time to keep floating again

#

when i jump

cinder summit
#

Cause your forces are absolutely tiny and there is no damping to get rid of existing downward velocity

past cargo
#

yes and idk the math for it

#

linear_velocity.y -= gravity_force.abs() + 0.1; iam reducing the velocity like this every frame when there is no floor detecting

#

that is the problem probaly

#

i should get the distance and reduce to go correctly on the floor position

past cargo
#

is this a const you made i suppose? @cinder summit

cinder summit
#

The damping is pretty much arbitrary, this was the lowest that felt right iirc

past cargo
#

the code is a bit messy xd

cinder summit
#

Mine or yours?

past cargo
#

yours, at least for my defaults

#

not saying its bad lol, just saying its not the style i like personally

#

so its bit confusing for me

cinder summit
#

Oh yeah that file is a mess

past cargo
#

yes

vague pebble
#

How does one increase the amount of substeps in avian?

vestal minnow
#

insert the SubstepCount resource

#

default is 6 substeps currently

past cargo
#

okie iam all day trying make it float, gonna leave now

#

still no progess xd

#

see ya guys

vague pebble
cinder summit
vestal minnow
#

Rapier and Box2D default to 4 IIRC

#

Rapier might have some extra stabilization thing though, I don't remember

cinder summit
#

3 kinda works but doesn't feel as stable, 4 is doable, but maybe one day the performance is good enough that running 60 substeps per frame isn't the bottleneck and I can set it back to the default of 6 again

vague pebble
#

A substep count of 12 should worry me about f32 imprecision?

cinder summit
#

Wasn't 12 the default back with XPBD?

vestal minnow
#

uhh I think so

vestal minnow
cinder summit
#

iirc back with xpbd the recommended range was 4 - 60

#

60 already feels excessive 😂

vestal minnow
#

those high counts are only really useful for complex joint setups like chains or cloth

#

for collisions that would typically be very excessive unless you want a very tall perfectly stable stack of boxes or something

#

(very tall, like hundreds of boxes probably)

vestal minnow
#

Avian and Box2D run it once

#

Hmm might be worth trying if that's better or worse than our current default, if we used 4 substeps but 2 relaxation iterations, it'd be the same total number of constraint solves as our current 6 substeps and 1 relaxation iteration

#

(4x solve with bias + 8x relax vs. 6x solve with bias + 6x relax)

cinder summit
#

In case you missed the context btw, here it's upping the substeps to hopefully get a bit more stability despite disabling warm starting

#

I think I did this before with no warm starting and 6 (instead of 4)

#

I don't stack boxes tho thonk

past cargo
vague pebble
past cargo
#

hmm seens working

sleek thicket
sleek thicket
# past cargo

and why are you swapping animations when jump ends, instead of when falling starts

wide oar
#

heyy, wanna ask how does external impulse works? do i need to add the component to the targetted entity? or do i just spawn it into the world? will it be automatically removed after that? or do i need to clean it up myself?

past cargo
sleek thicket
past cargo
#

So increase the float for 0.5? Studs? Its Fine i Just need increase

sleek thicket
#

change the capsule size to fit the torso

cinder summit
past cargo
#

Is your game server + client on same crate?

past cargo
#

Client jump First, than server moves it back

cinder summit
#

Usually mispredictions are caused by scheduling problems in your own code

past cargo
#

You mean add.system?

#

Like FixedPreUpdate

#

ET

#

Etc

#

You saying iam scheduling wrong?

#

Can you take a look at my current code? @cinder summit

#

Very small

cinder summit
# past cargo You mean add.system?

Yes, but the easiest source of issues is systems not having ordering rules within the same schedule, that causes them to run in a random order each restart

past cargo
#

Iam using .chain and before

#

Could you look?

cinder summit
#

Not atm, am at work :(

past cargo
#

Np

vague pebble
#

In avian should I worry about multypling by mass of the rigidbody? If my game deosnt care that much about contact forces

vestal minnow
#

Managed to cut the combined cost of the narrow phase + constraint generation in nearly half (left is old, right is new)

#

The labels are a bit misleading now since "Generate Constraints" no longer exists as its own step for contacts. I basically just moved constraint generation into the parallel contact computation loop, which (1) makes constraint creation parallel, (2) lets us reuse all the computed values like the effective speculative margin, and (3) gets rid of the additional ECS queries for body and collider data

#

I'm not sure if this approach will work once we have SIMD constraints, but for now it seems fine :P

vestal minnow
vague pebble
#

Thanks god to know

cinder summit
vestal minnow
#

it shouldn't, no

cinder summit
#

So you're saying this is basically free performamce? 👀

vestal minnow
#

For some reason it seems to cause a small solver perf regression at least when single-threaded, even though it shouldn't affect that assuming the generated constraints are the same 🤔 I still need to figure out if there's something going wrong there

#

But it should be basically free perf, and is especially faster when multi-threaded

cinder summit
#

Now we just need @bold garnet to make multi-threading worth it below thousands of entities ferris_sob

vestal minnow
#

I will definitely have to get completely rid of PostProcessCollisions to make it work though, but that was kinda the plan with collision hooks anyway

#

(the post-processing schedule was previously run in between the narrow phase update and constraint generation, but if they're done in the same loop, that's not possible)

bold garnet
#

If you want to suggest any

#

Ideally ones that do not depend on bevy itself

safe eagle
#

hi. I created a system that works with this query:

#[derive(QueryData)]
#[query_data(mutable)]
struct HydrodynamicsIntegrationQuery {
    position: &'static Position,
    rotation: &'static Rotation,
    collider: &'static Collider,
    velocity: &'static LinearVelocity,
    impulse: &'static mut ExternalImpulse,
}

fn integrate_hydrodynamics(
    time: Res<Time>,
    mut bodies: Query<HydrodynamicsIntegrationQuery, With<Hydrodynamic>>,
) {

it should be right before or right after integrate_velocities. how can I put it in these places?

#

currently, it just lives in fixedpostupdate:

.add_systems(FixedPostUpdate, integrate_hydrodynamics)
vague pebble
#

hmm why doesnt spatial query raycast have gizmos?

safe eagle
vestal minnow
#

I'm not entirely sure you want fluid sim to be substepped though, it seems like it'd be quite expensive and probably not needed for stability, depending on the implementation

vague pebble
#

Hmm I am doing a shapecast, to detect the slope of the platform I am on top off I should grab the contact points, and check their degree difference right?

vestal minnow
#

like

let too_steep = hit.normal1.angle_between(Vec3::Y).abs() > max_slope;
#

(or something similar)

sleek thicket
#

or dot

vestal minnow
#

yeah dot product works too and is faster

vague pebble
#

Dot product among the point1 and vec::y?

vestal minnow
#

normal and up-direction

vague pebble
#

Okay

vestal minnow
#

meaning something like

// The slope is too steep if the normal
// is pointing "away enough" from the up-direction
let too_steep = hit.normal1.dot(Vec3::Y) < 0.9;
vague pebble
#

Oh my character controller is finally taking shape

vestal minnow
# vestal minnow meaning something like ```rust // The slope is too steep if the normal // is poi...

You can also define a specific maximum angle with this dot product approach. Mathematically (with pseudo-codey syntax), the angle between two vectors can be described as

cos(angle) = dot(a, b) / (length(a) * length(b))

in our case, we have two normalized vectors, so it gets simplified to this

cos(angle) = dot(a, b)

so if we wanted the maximum angle difference from the up-direction to be e.g. 45 degrees, we can say that the maximum dot product between a and b is cos(45 deg) ≈ 0.707107, resulting in this condition

const COS_45_DEG: f32 = 0.707107;

let too_steep = hit.normal1.dot(Vec3::Y) < COS_45_DEG;
safe eagle
#

just a little bit of organic to my game

#

I use configurable ray casting and an optimized aabb projection

#

this is default behaviour, I didn't add any fluid dynamics to them

#
for i in 0..20 {
        for j in 0..20 {
            let x = i as f32 / 19.0 * 5.0 - 2.5;
            let z = j as f32 / 19.0 * 5.0 - 2.5;

            commands.spawn((
                RigidBody::Dynamic,
                Transform::from_xyz(x, 1.0, z),
                Mass(0.1),
                Collider::cuboid(0.2, 0.2, 0.2),
                Mesh3d(meshes.add(Cuboid::new(0.2, 0.2, 0.2))),
                MeshMaterial3d(materials.add(Color::srgba(1.0, 1.0, 1.0, 1.0))),
            ));
        }
    }

and the ground:

commands.spawn((
        RigidBody::Static,
        Transform::from_xyz(0.0, -2.0, 0.0),
        Collider::cylinder(4.0, 0.1),
        Mesh3d(meshes.add(Cylinder::new(4.0, 0.1))),
        MeshMaterial3d(materials.add(Color::WHITE)),
    ));

and a setup:

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

they're alive ig

vestal minnow
#

Could try PhysicsPlugins::default().with_length_unit(0.1) or something? Might not fix it completely though, I think there are currently some stability problems with small objects

#

IIRC it might be a numerical problem with angular inertia

#

so you could also try manually specifying some higher AngularInertia

safe eagle
cinder summit
safe eagle
#

lower numbers just slow down the giggles, maybe i'll try to add some stabilization system

vestal minnow
#

A cuboid floor is fine

safe eagle
#

oh really

vestal minnow
#

Seems like it, just tested both shapes

safe eagle
#

it is, yeah. why's it like that?

vestal minnow
#

Not sure, I wonder if it could be some inaccuracy with contact computation for small shapes using Parry 🤔 (the collision detection library currently used by Avian and Rapier)

#

Using a trimesh collider for the cylinder seems to be perfectly stable

#

with ColliderConstructor::TrimeshFromMesh

#

One annoying thing about Parry is that it has a lot of hard-coded constants for various epsilon values and tolerances, which could potentially lead to some scenarios being misconfigured. Maybe something like that is happening 🤔

#

I'd really like if it'd allow passing some config to geometric queries (where relevant), at least for some length unit / expected world scale

vestal minnow
#

Btw the changelog and migration guide still mention the get_ prefix, should probably be updated to be the _with_context suffix

cinder summit
#

If there is any performance regression, worst case we could try to invert the traits, though that could create the weird situation where you could not specify SimpleCollider but still have a () Context, which isn't great

#

(like have SimpleCollider be it's own trait without Context and the like, then have a impl<C: SimpleCollider> AnyCollider for C)

vague pebble
#

So I have an interesting issue while climbing slopes

#

I guess that in this case scenario I should apply force at a certain point, instead of making it at center mass correct? Or perhaps diminish by the slope factor

safe eagle
#

the direction of the force when walking or running the legs should depend on the direction of the desired movement and the slope of the surface. and if you apply it once in a while to simulate the movement of the legs, you will get a fairly organic walk with a realistic stop when the movement stops

#

this is the idea

#

if a character is descending, then you can not only add horizontal speed to it, but also negative vertical, as if it is not just falling, but stretching its foot down. but for large slopes this trick will not work, the character still has to fall

vague pebble
#

Hmm I guess the way he is climbing is correct

#

The way he goes dow is just a matter as of as said negative vertiical

cinder summit
# vestal minnow reviewed

Review comments should be fixed now, except empty vs fake cause empty really would be a sus name, tho I think that one isn't pub either way

sleek thicket
vague pebble
#

Yes

sleek thicket
#

could've just gone with a non-floating controller then lmao

vague pebble
#

The real problem here is distance, thing is unstable

#

oh i can just clamp it

kind moss
#

I'm trying to make a spring network that is very soft and squishy in response to small disturbances but strongly resists large separations between nodes. What's the best way to achieve that? Right now I'm using DistanceJoints with a fairly high compliance which gives me the effect I want for small motions but let's the nodes separate way too much when there's more force on them.

#

Maybe two separate joints. One with high compliance and no distance limits and one with low compliance and a distance limit set to about the separation I want to tolerate?

#

I'm trying to achieve a soft body blob effect.

kindred hinge
#

Can you just recalculate the parameters of the joint every frame based on the separation?

safe eagle
#

how can I query acceleration?

kind moss
#

Hmm, yeah having even a single joint per edge in the network with low compliance and length limits gives very glitchy behavior. When I apply an impulse to the entire network (ie. set the ExternalImpulse for each node to the same vector) it starts to move and then jerks to a halt in mid air, starts to fall, twitches and jerks to a stop again, falls again, etc. Like the joints are fighting to keep the network together and end up applying large global forces to the composite system.

silk mauve
#

How can I get the position of a hit between 2 entities in a collision event?

kind moss
#

The motion is done by applying the same impulse to each body in the net. All the bodies are identical.

#

So it's not like it's yanking on one body an everything else is flayling around to catch up to it.

kind moss
#

That ended up being a bit more jello and less liquid goop than I initially wanted, but it's pretty stable so I'll take it.

sweet sundial
#

maybe some cosmetic blob particles that come out when stationary and retract when moving

kind moss
#

Yeah, might emphasize the effect. That was actually my first approach but I didn't like how disconnected it seemed from the terrain so this version is an attempt to do it with actual colliders. I might also be able to make the joints more compliant when the body is moving slowly and more rigid when it's moving quickly.

sweet sundial
#

alternative approach, make it more stringy and use a ragdoll

kind moss
# sweet sundial alternative approach, make it more stringy and use a ragdoll

I'm not sure I understand the suggestion. Are you saying to set it up like a mop or a pom-pom or something with strings that connect to the center and can flop around? That's interesting. It would work with the rendering which is already just metaballs so it doesn't really care what the internal structure is.

sweet sundial
#

yeah, basically
more like a mop, how i was imagining it

kind moss
#

That would likely work. I might try it when I circle back around to this.

vestal minnow
#

Next I'll probably work on updating to 0.16-0-rc.1 now that it's released

#

then I'll also be able to try peck in the wild for contacts :P (it has relied on Bevy main so far)

#

I should theoretically have 2D contact manifolds for arbitrary convex polygons working with it

#

3D shouldn't be too bad either, just need to implement feature clipping for it

vestal minnow
surreal rune
vestal minnow
#

Yeah it's really cool how few changes are needed to support it for crates like this

#

(though CI seems to be failing now for unrelated reasons :P)

surreal rune
vestal minnow
#

@surreal rune I also updated bevy_heavy to 0.16.0-rc.1, so your no_std PR should work once the actual feature flags are added. Shall I do that quickly, or do you have it done locally already? (edit: link)

#

ah there's a few failing tests too I think

#

I can update the PR since I'm working on this anyway, should be quick

surreal rune
#

All the features work in no_std (tested on wasm32v1-none). Note that default-features = false will fail to compile though, since you need to have std and/or libm enabled for Glam (but once the new version of Glam releases that'll be resolved)

vestal minnow
#

Awesome, thanks :)

#

I think the tests in the impls modules are still missing a Vec import

surreal rune
#

Technically, bevy_heavy is also one of the few no_alloc Bevy crates too (there's no functionality since you need alloc for 2d and 3d but still :P)

vestal minnow
#

I think that's also only the polygon and polyline types, which could technically be feature-gated 🤔 but idk if it'd actually be useful at all

#

Oh nvm there's a Sum impl that uses a Vec

surreal rune
#

I think it's fine to not bother with no_alloc. It's much harder to write and even harder to test

vestal minnow
#

yeah

uncut raptor
#

With avian2d is there a way to disable all rotation/angular movement and only have linear velocity from collisions?

vestal minnow
#

You can use LockedAxes::ROTATION_LOCKED

uncut raptor
#

Thanks, that was exactly what I needed!

#

Just didn't know what name to look for

vestal minnow
#

Alrighty @cinder summit et al, Avian now has a rough migration to the Bevy 0.16 RC on the bevy-0.16 branch

#

Note that child colliders are currently broken there, but otherwise it seems to work

#

this is just an initial version to get it to compile and run, I'll clean it up later

smoky crane
jovial herald
#

You probably want to create two models. One of the complete vase, and one for the shattered vase (where each piece it it's own object with it's own collider). And then just swap out the model when you break it, giving each piece some outward velocity.

#

You could make the shattering procedural but I wouldn't bother.

#

You could also listen for collisions on the vase and trigger the break when the force is more than X

#

EDIT: actually I'm not sure how to get the size of the impulse from a collision

jovial herald
#

I actually am curious about this now

sweet sundial
#

the Collisions resource has a total_normal_impulse

cinder summit
vestal minnow
#

I think so, yeah

vestal minnow
#

Okay fixed the child collider bug

#

I think it was a thing where I had an OnInsert observer that was also checking if the entity matches a query, but if both components were added at spawn, they didn't exist yet so the query failed

#

Mmmm the unsafe world cell stuff added in the collider context PR is panicking in debug mode because get_resource_mut doesn't allow mutable access through a read-only cell

#

need to figure out how to get around that

#

That's easy actually, just remove the whole AABB computation that uses the world cell 🙈 it doesn't make much sense to have it since the initial positions are likely wrong anyway

cinder summit
vestal minnow
cinder summit
vestal minnow
#

wait I forgot I can also remove the ContextState resource now, lemme do that quickly

#

boom

#

yeah the world cell stuff was pretty ugly lol

little maple
#

how's bevy 0.16?

cinder summit
#

I've been working on main for a while for some networking stuff, it has surprisingly few breaking changes and outside of some messy APIs it seems overall stable

little maple
#

good to know

surreal rune
little maple
cinder summit
# vestal minnow Alrighty <@409485472390316033> et al, Avian now has a rough migration to the Bev...

This should compile right?

avian3d = { git = "https://github.com/Jondolf/avian", branch="bevy-0.16", default-features = false, features = ["3d", "f32"] }
```Cause I'm currently getting this error:

error[E0412]: cannot find type SpatialQuery in this scope
--> /home/nisevoid/.cargo/git/checkouts/avian-5a22c167119f3550/6874027/crates/avian3d/../../src/spatial_query/mod.rs:222:24
|
222 | mut spatial_query: SpatialQuery,
| ^^^^^^^^^^^^ not found in this scope
|

vestal minnow
#

idk when that broke, I don't remember touching that in a long time

cinder summit
#

I mean this is my first time trying to get SDF collisions working again since 0.14, so it had a full cycle to be broken 😂

vestal minnow
#

I'll merge it once CI passes, I want to get to actually doing stuff with 0.16 :P

past cargo
#

@vestal minnow I Hope they fix the Time resource issue on 0.16

vestal minnow
cinder summit
#

@vestal minnow How would you handle cases like 2 perfectly overlapping spheres? What is the normal here? 🤔

vestal minnow
#

If the normal was a zero vector, physics would get zero overlap and do nothing to resolve the contact, which you probably don't want

cinder summit
vestal minnow
#

as long as the fallback normal is the same, it should be

#

this is also an edge case anyway, I imagine the only case where you'd get this is if you're spawning several spheres at the same exact position at the same time

cinder summit
#

Is the entity1 vs entity2 thing deterministic?

#

Cause depending on which is 1 and 2 the normal would effectively be reversed

#

But yea it's definitely an edgecase ... Either spawning them on the same position, having some bug that spawns things inside the player/enemy instead of at a more reasonable position, or having exactly the right amount of tunneling (very unlikely, but in theory possible)

vestal minnow
#

If the entity order wasn't deterministic, then I think you'd get vastly different results anyway regardless of the normal, since the contact points would be in a different order and stuff like the relative velocity would be slightly different

cinder summit
#

Scaling support, in my SDF collisions?!

impl ScalableCollider for SdfCollider {
    fn scale(&self) -> Vec3 {
        Vec3::splat(self.scale)
    }
    fn set_scale(&mut self, scale: Vec3, _: u32) {
        self.scale = scale.min_element();
    }
}
cinder summit
#

@vestal minnow Are the local points for contact points the local coordinates on the already scaled collider?

#

So like if something just barely hits the edge of a sphere with radius 0.5, that was scaled by a factor of 3 ... Is the local point a length of ~0.5 or ~1.5?

vestal minnow
#

I think it's on the scaled collider, so -1.5

spiral nymph
#

Hi,

I tried creating a map with ConstructorColliderHierarchy::TrimeshFromMesh, but when my character walk on a edge, it can't move and after some time fall through the ground.
Am I doing something wrong ? or is TrimeshFromMesh not adapted for that kind of uses ?

sleek thicket
spiral nymph
#

tried just now, same result
I will create collider manually, seem safer

cinder pilot
vestal minnow
#

and in what schedule

cinder pilot
#

I'm using leafwing, e.g.

        app.add_plugins(InputManagerPlugin::<PlayerMovementAction>::default())
            .add_systems(
                FixedUpdate,
                (systems::local_movement).run_if(in_state(GameState::InGame)),
            )
#

pub fn local_movement(
    time: Res<Time>,
    mut action_state: Option<
        Single<(&ActionState<PlayerMovementAction>, &mut LinearVelocity), With<LocalPlayer>>,
    >,
) {
    let Some((action, linvel)) = action_state.as_deref_mut() else {
        return;
    };
    let delta_time = time.delta_secs_f64().adjust_precision();

    let Vec2 { x, y } = action.axis_pair(&PlayerMovementAction::Move);

    let moving = x != 0.0 || y != 0.0;

    let dir = (y).atan2(x);
    let cos = dir.cos();
    let sin = dir.sin();
    if moving {
        linvel.x += cos * PLAYER_MOVE_SPEED * delta_time;
        linvel.y += sin * PLAYER_MOVE_SPEED * delta_time;
    }
}
#

Oh, I also have movement damping. But that's it basically.

sleek thicket
#

don't multiply by delta in fixed updates

vestal minnow
#

Hmm yeah that looks like it should be fine

vestal minnow
cinder pilot
#

the examples do that...

sleek thicket
#

it's only worth it in update

vestal minnow
#

If you don't multiply by delta, behavior will be different if you change the fixed timestep, and units also make less sense

cinder pilot
cinder summit
#

It's the same as making a setting so you can easily change tickrate later

vestal minnow
#

If you want to move at 2 units per second, that's 2.0 * delta_secs regardless of the schedule. 2.0 in FixedUpdate would be... 2 per tick, which is weirder

cinder pilot
#

Yeah so I think this is a red herring, I doubt FixedUpdate is an issue here. Any other ideas why Interpolation/Extrapolation would be different in how fast my character can move?

vestal minnow
sleek thicket
cinder summit
cinder summit
sleek thicket
#

ticks happening slower doesn't increase delta? 🤔

vestal minnow
#

not if you're doing slow-mo

cinder summit
#

FixedUpdate doesn't measure the real delta, it just gives you the delta for the tickrate you configured

cinder pilot
cinder pilot
# cinder summit Is there a reason that code isn't something along the lines of this? ```rust ...

Ok, I adjusted to

pub fn local_movement(
    time: Res<Time>,
    mut action_state: Option<
        Single<(&ActionState<PlayerMovementAction>, &mut LinearVelocity), With<LocalPlayer>>,
    >,
) {
    let Some((action, linvel)) = action_state.as_deref_mut() else {
        return;
    };
    let delta_time = time.delta_secs_f64().adjust_precision();

    let dir = action.axis_pair(&PlayerMovementAction::Move);
    if dir != Vec2::ZERO {
        linvel.x += dir.x * PLAYER_MOVE_SPEED * delta_time;
        linvel.y += dir.y * PLAYER_MOVE_SPEED * delta_time;
    }
}

But it did not solve anything

#

btw, here how I'm initializing the physics:

pub struct SharedPhysicsPlugin {
    pub render_gizmos: bool,
}

impl Plugin for SharedPhysicsPlugin {
    fn build(&self, app: &mut bevy::app::App) {
        app.add_plugins(PhysicsPlugins::default().with_length_unit(50.0))
            .add_plugins(PhysicsDebugPlugin::default())
            .insert_resource(Gravity(Vec2::ZERO))
            .insert_resource(Time::from_duration(PHYSICS_TICK_RATE));

        // Enable or Disable gizmos
        let mut store = app.world_mut().resource_mut::<GizmoConfigStore>();
        let config = store.config_mut::<PhysicsGizmos>().0;
        config.enabled = self.render_gizmos;
    }
}
cinder summit
cinder pilot
vestal minnow
#

Here's a minimal working example of interpolated movement with damping, for reference

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

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

#[derive(Component)]
struct Controllable;

fn setup(
    mut commands: Commands,
    mut materials: ResMut<Assets<ColorMaterial>>,
    mut meshes: ResMut<Assets<Mesh>>,
) {
    commands.spawn(Camera2d);

    // Controllable object
    commands.spawn((
        RigidBody::Dynamic,
        Collider::circle(20.0),
        Mesh2d(meshes.add(Circle::new(20.0))),
        MeshMaterial2d(materials.add(Color::srgb(0.2, 0.7, 0.9))),
        TransformInterpolation,
        Controllable,
        LinearDamping(1.5),
    ));
}

fn movement(
    time: Res<Time>,
    keyboard_input: Res<ButtonInput<KeyCode>>,
    mut query: Query<&mut LinearVelocity, With<Controllable>>,
) {
    let delta_secs = time.delta_secs();

    let up = keyboard_input.any_pressed([KeyCode::KeyW, KeyCode::ArrowUp]);
    let down = keyboard_input.any_pressed([KeyCode::KeyS, KeyCode::ArrowDown]);
    let left = keyboard_input.any_pressed([KeyCode::KeyA, KeyCode::ArrowLeft]);
    let right = keyboard_input.any_pressed([KeyCode::KeyD, KeyCode::ArrowRight]);

    let horizontal = right as i8 - left as i8;
    let vertical = up as i8 - down as i8;
    let direction = Vec2::new(horizontal as f32, vertical as f32).clamp_length_max(1.0);

    for mut linear_velocity in &mut query {
        linear_velocity.0 += 500.0 * delta_secs * direction;
    }
}
#

I would try to reduce your case to something as minimal as possible, and build up from there to locate the problem

cinder pilot
#

@vestal minnow Did you change it to Extrapolation

#

And see it go the same speed?

vestal minnow
#

Yes

cinder pilot
#

... Wait what is Controllable

#

Do I need that?

vestal minnow
#

It's defined in the code snippet

#

just a marker component

cinder pilot
#

Ah, ok. Another interesting observation, you have a LinearDamping component?

vestal minnow
cinder pilot
#

I was doing it with a system....

pub fn apply_movement_damping(
    // TODO: This should only apply to players, With<Player>
    mut query: Query<&mut LinearVelocity, Without<Sleeping>>,
    time: Res<Time<Physics>>,
) {
    if time.is_paused() {
        return;
    }
    let damping_factor = 0.75;
    for mut linear_velocity in &mut query {
        linear_velocity.x *= damping_factor;
        if linear_velocity.x.abs() < 0.01 {
            linear_velocity.x = 0.0;
        }
        linear_velocity.y *= damping_factor;
        if linear_velocity.y.abs() < 0.01 {
            linear_velocity.y = 0.0;
        }
    }
}
#

Maybe this could've been my issue.

#

I'll switch it out

#

Ok I'm more convinced this is an avian issue now

#

I swapped out my damping with LinearDamping and it became better, but then I increased the damping and it became slower

#

It's directly related to LinearDamping

#

Jon, can you add these components to your example?

    RigidBody(|| RigidBody::Dynamic),
    LockedAxes(|| LockedAxes::ROTATION_LOCKED),
    LinearDamping(|| LinearDamping(3.0)),
    TransformInterpolation,
    MaxLinearSpeed(|| MaxLinearSpeed(PLAYER_MOVE_SPEED)),
    Restitution(|| Restitution::new(0.0).with_combine_rule(CoefficientCombine::Min)),
    Collider(||Collider::ellipse(175.0, 50.0)),
vestal minnow
cinder pilot
#

The movement became slower, e.g. Walking around

#

The transform basically

vestal minnow
#

Yeah I mean higher damping values slow down the object more rapidly, so you need a larger movement velocity (or I guess acceleration in this case) if you want to keep walking around at the same rate

cinder pilot
#

But why would LinearDamping only affect TransformInterpolation and not TransformExtrapolation

#

Do you know if LinearDamping happening on Update or FixedUpdate?

vestal minnow
#

it does definitely affect both for me

cinder pilot
#

Are you running on wasm? I'm runnign on wasm

vestal minnow
#

it's applied in FixedPostUpdate where physics runs by default

#

the platform shouldn't matter

cinder pilot
#

and here is Extrapolation: (one sec)

#

Same damping level

#

It just makes no sense why this would be faster, they both have the same damping

#

btw my Time resource is set to Duration::from_millis(50) (20Hz)

vestal minnow
#

I'm 99% sure you're accidentally changing the transform manually somewhere if you're getting that stuttering and speedup with extrapolation

#

I get the same if changing Transform in Update, even just setting it to itself, since it triggers change detection and messes up extrapolation

#

Otherwise I'm not getting that

cinder pilot
#

The stuttering is because it's 20Hz, so it looks like it's 20FPS. It's actually 60FPS

#

I see the same stuttering when I run the interpolation example from avian2d

cinder pilot
vestal minnow
#

Yes that would break it

cinder pilot
#

Fuck. Ok I need a solution then

#

Because I need to adjust the Z

#

The game is 2.5D, meaning the player's Z-index is adjusted every frame to apply a painter's algorithm (like Zelda or Pokemon)

#

One sec, I'll confirm if the Z-index change is the issue though.

#

YEP! That was it

vestal minnow
#

Can you adjust Z in FixedUpdate or some other fixed schedule?

#

That won't have the same problem

cinder pilot
#

Hmm... That's

#

Errgggh

#

Then things may render out of order slightly, because I would only change what order to render items at 20Hz

#

Not terrible though... I could probably make adjustments in my render pipeline instead

vestal minnow
#

I think if we had Transform2d, with Z ordering handled by a separate component like ZIndex, this problem wouldn't exist 🤔 another reason to split 2D/3D transforms I guess

cinder pilot
#

I think there is a ZIndex component in Bevy but its documentation points it towards being used by UI, meaning I probably wouldn't re-use it for my world-space items.

vestal minnow
#

People in #math-dev and elsewhere have been wanting first-party 2D transforms for Bevy for a long time (while keeping the 3D GlobalTransform for rendering)

#

or more generally, support for transform types and customizability other than just the hierarchical 3D Transform

cinder pilot
#

Yeah. I maintain bevy_vello which is how I'm rendering the graphics here; it's vector graphics. I can probably adjust to an architecture that uses an inhouse Transform2d and ZIndex until that lands in bevy. Either way I have the ownership to fix my own issue here.

#

Thanks again for the help, Jondolf! Awesome library.

vestal minnow
#

Happy to help 😄

#

I suppose technically we could also fix this issue on the side of bevy_transform_interpolation by allowing interpolation to be enabled for each of the XYZ components separately

#

So if you disabled interpolation for the Z component of the translation, it'd just leave that untouched

cinder pilot
vestal minnow
#

Physics doesn't really, but bevy_transform_interpolation (which Avian uses for interpolation) doesn't distinguish between 2D and 3D, it only sees a Transform

#

Now if there was a Transform2d...

cinder pilot
#

I agree, this should be a thing.

vestal minnow
#

In general, I think we have reasonable consensus that it should be a thing, it just needs to be implemented, and some details around e.g. efficiently handling transform hierarchies and mixing different types of transforms need to be nailed down

#

@bold garnet had some ideas for this IIRC, but I believe they're focused on the Forte thread pool right now

cinder summit
#

I think Forte was in some way related to transforms too tho ... Everything nth does always seems to be connected

vestal minnow
#

surely ICBINBSN templates are related to transforms too thonk

cinder summit
#

Well .... You never know thonk

cinder pilot
#

Is there a way to translate the collider a bit to the left, so it aligns with the base of my tree?

sleek thicket
cinder pilot
#

Surely Avian lets you change the collider offset... right?